COMPASSi/trunk/code/projects/OCC/OCCLib/OCCLib.cpp

477 lines
12 KiB
C++
Raw Permalink Normal View History

2025-06-25 15:06:42 +08:00
// 这是主 DLL 文件。
#include "Stdafx.h"
#include "OCCLib.h"
#include "CutSolidAlgo.h"
#include "BRepBuilderAPI_Transform.hxx"
#include "CutSurfaceAlgo.h"
#include "GridFaces.h"
#include "BRepExtrema_DistShapeShape.hxx"
#include "Bnd_Box.hxx"
#include "SectionAlgo.h"
#include "SolidBool.h"
#include "BRepPrimAPI_MakeHalfSpace.hxx"
OCCLib::OCCLib()
{
}
OCCLib::~OCCLib()
{
}
TopoDS_Face OCCLib::CreateFaceByPoints(gp_Pnt p1, gp_Pnt p2, gp_Pnt p3, gp_Pnt p4)
{
TopoDS_Face face;
try
{
vector<TopoDS_Edge> allWires;
vector<gp_Pnt> pnts;
Standard_Real tol = Precision::Confusion();
pnts.push_back(p1);
if (p2.Distance(pnts.back()) >= tol)
pnts.push_back(p2);
if (p3.Distance(pnts.back()) >= tol)
pnts.push_back(p3);
if (p4.Distance(pnts.back()) >= tol)
pnts.push_back(p4);
if (p1.Distance(pnts.back()) >= tol)
pnts.push_back(p1);
for (int i=0; i<pnts.size()-1; i++)
{
Handle_TColgp_HArray1OfPnt harry1=new TColgp_HArray1OfPnt(1, 2);
harry1->SetValue(1, pnts[i]);
harry1->SetValue(2, pnts[i+1]);
GeomAPI_Interpolate PtB1(harry1,Standard_False, Precision::Confusion());
PtB1.Perform();
allWires.push_back(BRepBuilderAPI_MakeEdge(PtB1.Curve()).Edge());
}
GridFaces gridFace(allWires);
gridFace.Build();
TopoDS_Shape s = gridFace.GetResult();
for(TopExp_Explorer ex(s, TopAbs_FACE);ex.More();ex.Next())
{
face = TopoDS::Face(ex.Current());
break;
}
}
catch(Standard_Failure)
{
throw "OCCLib::CreateFaceByPoints";
}
//GeomFill_BSplineCurves fill=GeomFill_BSplineCurves(PtB1.Curve(),PtB2.Curve(),PtB3.Curve(),PtB4.Curve(),GeomFill_StretchStyle);
//face = BRepBuilderAPI_MakeFace(fill.Surface());
//face.Orientation(TopAbs_FORWARD);
return face;
}
TopoDS_Face OCCLib::CreatePlaneByPoints(const vector<gp_Pnt>& pSet,Standard_Boolean reverse) //20170601 by czb
{
TopoDS_Face face;
if (pSet.size() < 3) return face;
vector<gp_Pnt> orgPnts;
orgPnts.push_back(pSet[0]);
for (int i=1; i<pSet.size(); i++)
{
if (pSet[i].Distance(orgPnts.back()) < Precision::Confusion()) continue;
orgPnts.push_back(pSet[i]);
}
if (orgPnts.size() < 3) return face;
vector<gp_Pnt> pnts;
if (reverse)
{
for (int i=0; i<orgPnts.size(); i++)
{
pnts.push_back(orgPnts[i]);
}
}
else
{
for (int i=orgPnts.size()-1; i>-1; i--)
{
pnts.push_back(orgPnts[i]);
}
}
TopoDS_Wire wire;
BRep_Builder builder;
builder.MakeWire(wire);
for (int i=0; i<pnts.size()-1; i++)
{
int j = (i+1) % pnts.size();
Handle_TColgp_HArray1OfPnt harry1=new TColgp_HArray1OfPnt(1, 2);
harry1->SetValue(1, pnts[i]);
harry1->SetValue(2, pnts[j]);
GeomAPI_Interpolate PtB1(harry1,Standard_False, Precision::Confusion());
PtB1.Perform();
builder.Add(wire, BRepBuilderAPI_MakeEdge(PtB1.Curve()).Edge());
}
BRepBuilderAPI_MakeFace mface(wire);
if (mface.IsDone())
{
face = mface.Face();
}
//GeomFill_BSplineCurves fill=GeomFill_BSplineCurves(PtB1.Curve(),PtB2.Curve(),PtB3.Curve(),PtB4.Curve(),GeomFill_StretchStyle);
//face = BRepBuilderAPI_MakeFace(fill.Surface());
//face.Orientation(TopAbs_FORWARD);
return face;
}
TopoDS_Face OCCLib::CreateXYPlane(gp_Pnt p, Standard_Real l, Standard_Real w)
{
TopoDS_Face result;
gp_Pnt p1(p.X() + l /2, p.Y() + w / 2, p.Z());
gp_Pnt p2(p.X() + l /2, p.Y() - w / 2, p.Z());
gp_Pnt p3(p.X() - l /2, p.Y() - w / 2, p.Z());
gp_Pnt p4(p.X() - l /2, p.Y() + w / 2, p.Z());
return CreateFaceByPoints(p1, p2, p3, p4);
}
TopoDS_Face OCCLib::CreateXZPlane(gp_Pnt p, Standard_Real l, Standard_Real w)
{
TopoDS_Face result;
gp_Pnt p1(p.X() + l /2, p.Y(), p.Z() + w / 2);
gp_Pnt p2(p.X() + l /2, p.Y(), p.Z() - w / 2);
gp_Pnt p3(p.X() - l /2, p.Y(), p.Z() - w / 2);
gp_Pnt p4(p.X() - l /2, p.Y(), p.Z() + w / 2);
return CreateFaceByPoints(p1, p2, p3, p4);
}
TopoDS_Face OCCLib::CreateYZPlane(gp_Pnt p, Standard_Real l, Standard_Real w)
{
TopoDS_Face result;
gp_Pnt p1(p.X(), p.Y() + l / 2, p.Z() + w / 2);
gp_Pnt p2(p.X(), p.Y() + l / 2, p.Z() - w / 2);
gp_Pnt p3(p.X(), p.Y() - l / 2, p.Z() - w / 2);
gp_Pnt p4(p.X(), p.Y() - l / 2, p.Z() + w / 2);
return CreateFaceByPoints(p1, p2, p3, p4);
}
TopoDS_Face OCCLib::CreatePlane(Standard_Real d, XYZ sign, Standard_Real l, Standard_Real w)
{
TopoDS_Face result;
switch(sign)
{
case PlaneZ:
result = CreateXYPlane(gp_Pnt(0,0,d), l, w);
break;
case PlaneY:
result =CreateXZPlane(gp_Pnt(0,d,0), l, w);
break;
case PlaneX:
result =CreateYZPlane(gp_Pnt(d,0,0), l, w);
break;
default:
break;
}
return result;
}
TopoDS_Face OCCLib::CreateRectangle(gp_Pnt p, gp_Dir dir, Standard_Real l, Standard_Real w)
{
TopoDS_Face result;
TopoDS_Face xyPln = CreateXYPlane(p, l, w);
if(dir.Angle(gp_Dir(0,0,1))< Precision::Confusion())
{
return xyPln;
}
gp_Dir Dir = dir.Crossed(gp_Dir(0,0,1));
Standard_Real f = dir.Angle(gp_Dir(0,0,1));
result = SurfaceRotate(xyPln, p, Dir, f);
return result;
}
vector<TopoDS_Face> OCCLib::CutSurfaceBySolid(TopoDS_Face face, TopoDS_Solid solid)
{
vector<TopoDS_Face> result;
//CutSolidAlgo cutSolidAlgo(solid, face);
//TopoDS_Shape shape = cutSolidAlgo.CutSurfaceBySolid(face, solid);
//for(TopExp_Explorer ex(shape, TopAbs_FACE); ex.More(); ex.Next())
//{
// result.push_back(TopoDS::Face(ex.Current()));
//}
BaseAlgo algo;
if(algo.IsReversed(solid))
{
solid.Reverse();
}
BRepAlgoAPI_Common common(face, solid);
TopoDS_Shape shape = common.Shape();
//throw shape;
for(TopExp_Explorer ex(shape, TopAbs_FACE); ex.More();ex.Next())
{
result.push_back(TopoDS::Face(ex.Current()));
}
return result;
}
vector<TopoDS_Solid> OCCLib::CutSolidBySurface(TopoDS_Solid solid, TopoDS_Face face, gp_Pnt cutPoint)
{
vector<TopoDS_Solid> result;
//CutSolidAlgo cutSolidAlgo(solid, face);
//cutSolidAlgo.SetCutPoint(cutPoint);
//cutSolidAlgo.flag = 1;
//cutSolidAlgo.Perform();
//TopoDS_Shape shape = cutSolidAlgo.GetResult();
//for(TopExp_Explorer ex(shape, TopAbs_SOLID); ex.More(); ex.Next())
//{
// result.push_back(TopoDS::Solid(ex.Current()));
//}
BaseAlgo algo;
if(algo.IsReversed(solid))
{
solid.Reverse();
}
BRepPrimAPI_MakeHalfSpace MHS(face, cutPoint);
TopoDS_Solid solid1 = TopoDS::Solid(MHS.Solid());
BRepAlgoAPI_Common common(solid ,solid1);
TopoDS_Shape shape = common.Shape();
//throw shape;
for(TopExp_Explorer ex(shape, TopAbs_SOLID); ex.More();ex.Next())
{
result.push_back(TopoDS::Solid(ex.Current()));
}
return result;
}
Standard_Real OCCLib::GetSurfaceArea(TopoDS_Shape face)
{
Standard_Real result;
GProp_GProps System;
BRepGProp::SurfaceProperties(face,System);
result = abs(System.Mass());
return result;
}
Standard_Real OCCLib::GetSurfaceRound(TopoDS_Shape face)
{
Standard_Real result;
GProp_GProps System;
BRepGProp::LinearProperties(face,System);
result = abs(System.Mass());
return result;
}
gp_Pnt OCCLib::GetSurfaceCenter(TopoDS_Shape face)
{
gp_Pnt result;
GProp_GProps System;
BRepGProp::SurfaceProperties(face,System);
result = System.CentreOfMass ();
return result;
}
Standard_Real OCCLib::GetSurfaceMomentOfInertia(TopoDS_Shape face, gp_Ax1 ax)
{
Standard_Real result;
GProp_GProps System;
BRepGProp::SurfaceProperties(face,System);
result = System.MomentOfInertia(ax);
return result;
}
void OCCLib::GetSurfaceStaticMoments(TopoDS_Shape face, Standard_Real& x, Standard_Real& y, Standard_Real&z)
{
GProp_GProps System;
BRepGProp::SurfaceProperties(face,System);
System.StaticMoments(x,y,z);
}
gp_Pnt OCCLib::GetSolidCenter(TopoDS_Solid solid)
{
BaseAlgo algo;
//TopoDS_Solid tmp = algo.RebuildSolid(solid, 1e-1);
TopoDS_Solid tmp = solid;
gp_Pnt result;
GProp_GProps System;
BRepGProp::VolumeProperties(tmp,System);
result = System.CentreOfMass();
return result;
}
Standard_Real OCCLib::GetSolidArea(TopoDS_Solid solid)
{
BaseAlgo algo;
//TopoDS_Solid tmp = algo.RebuildSolid(solid, 1e-1);
TopoDS_Solid tmp = solid;
Standard_Real result;
GProp_GProps System;
BRepGProp::SurfaceProperties(tmp,System);
result = abs(System.Mass());
return result;;
}
Standard_Real OCCLib::GetSolidMomentOfInertia(TopoDS_Solid solid, gp_Ax1 ax)
{
BaseAlgo algo;
//TopoDS_Solid tmp = algo.RebuildSolid(solid, 1e-1);
TopoDS_Solid tmp = solid;
Standard_Real result;
GProp_GProps System;
BRepGProp::VolumeProperties(tmp, System);
result = System.MomentOfInertia(ax);
return result;
}
TopoDS_Face OCCLib::SurfaceRotate(TopoDS_Face face, gp_Pnt p, gp_Dir dir, Standard_Real f)
{
TopoDS_Face result;
gp_Trsf theTransformation;
gp_Ax1 axe = gp_Ax1(p,dir);
f = (f / 180) * PI;
theTransformation.SetRotation(axe,f);
BRepBuilderAPI_Transform myBRepTransformation(face,theTransformation);
result = TopoDS::Face(myBRepTransformation.Shape());
return result;
}
vector<TopoDS_Face> OCCLib::CutSurfaceBySurface(TopoDS_Face f1, TopoDS_Face f2, gp_Pnt cutPoint)
{
vector<TopoDS_Face> faceSet;
CutSurfaceAlgo cutSurfaceAlgo(f1, f2);
cutSurfaceAlgo.SetCutPoint(cutPoint);
cutSurfaceAlgo.Perform();
TopoDS_Shape result = cutSurfaceAlgo.GetResult();
for(TopExp_Explorer ex(result, TopAbs_FACE); ex.More(); ex.Next())
{
faceSet.push_back(TopoDS::Face(ex.Current()));
}
return faceSet;
}
Standard_Real OCCLib::GetSolidVolume(TopoDS_Solid solid)
{
BaseAlgo algo;
//TopoDS_Solid tmp = algo.RebuildSolid(solid, 1e-1);
TopoDS_Solid tmp = solid;
Standard_Real result;
GProp_GProps System;
BRepGProp::VolumeProperties(tmp,System);
result = abs(System.Mass());
return result;
}
double OCCLib::GetXLength(TopoDS_Shape shape, TopoDS_Face face)
{
double len = 0;
BRepExtrema_DistShapeShape inter(shape,face);
double dis = inter.Value();
if(dis > Precision::Confusion() * 100)
{
return 0;
}
int count = inter.NbSolution();
Bnd_Box box;
for(int i = 1; i <= count; i++)
{
gp_Pnt p = inter.PointOnShape2(i);
box.Add(p);
}
double xmax, xmin, ymax,ymin,zmax,zmin;
box .Get(xmin, ymin, zmin, xmax, ymax, zmax);
len = xmax - xmin;
return len;
}
double OCCLib::GetYLength(TopoDS_Shape shape, TopoDS_Face face)
{
double len = 0;
BRepExtrema_DistShapeShape inter(shape,face);
double dis = inter.Value();
if(dis > Precision::Confusion() * 100)
{
return 0;
}
int count = inter.NbSolution();
Bnd_Box box;
for(int i = 1; i <= count; i++)
{
gp_Pnt p = inter.PointOnShape2(i);
box.Add(p);
}
double xmax, xmin, ymax,ymin,zmax,zmin;
box .Get(xmin, ymin, zmin, xmax, ymax, zmax);
len = ymax - ymin;
return len;
}
TopoDS_Shape OCCLib::Section(TopoDS_Shape shape1,TopoDS_Shape shape2)
{
SectionAlgo sectionAlgo(shape1, shape2);
sectionAlgo.Perform();
return sectionAlgo.result;
}
TopoDS_Shell OCCLib::SewShell( vector<TopoDS_Shape> shapeSet )
{
BaseAlgo algo;
return algo.SewShell(shapeSet);
}
TopoDS_Solid OCCLib::CreateSolid(gp_Pnt p, double dx, double dy, double dz)
{
TopoDS_Solid solid;
TopoDS_Face f1 = CreateFaceByPoints(gp_Pnt(p.X(), p.Y(), p.Z()),
gp_Pnt(p.X(), p.Y() + dy, p.Z()),
gp_Pnt(p.X(), p.Y() + dy, p.Z() + dz),
gp_Pnt(p.X(), p.Y(), p.Z() + dz));
TopoDS_Face f2 = CreateFaceByPoints(gp_Pnt(p.X() + dx, p.Y(), p.Z()),
gp_Pnt(p.X() + dx, p.Y() + dy, p.Z()),
gp_Pnt(p.X() + dx, p.Y() + dy, p.Z() + dz),
gp_Pnt(p.X() + dx, p.Y(), p.Z() + dz));
TopoDS_Face f3 = CreateFaceByPoints(gp_Pnt(p.X(), p.Y(), p.Z()),
gp_Pnt(p.X() + dx, p.Y(), p.Z()),
gp_Pnt(p.X() + dx, p.Y() + dy, p.Z()),
gp_Pnt(p.X(), p.Y() + dy, p.Z()));
TopoDS_Face f4 = CreateFaceByPoints(gp_Pnt(p.X(), p.Y(), p.Z() + dz),
gp_Pnt(p.X() + dx, p.Y(), p.Z() + dz),
gp_Pnt(p.X() + dx, p.Y() + dy, p.Z() + dz),
gp_Pnt(p.X(), p.Y() + dy, p.Z() + dz));
TopoDS_Face f5 = CreateFaceByPoints(gp_Pnt(p.X(), p.Y(), p.Z()),
gp_Pnt(p.X() + dx, p.Y(), p.Z()),
gp_Pnt(p.X() + dx, p.Y(), p.Z() + dz),
gp_Pnt(p.X(), p.Y(), p.Z() + dz));
TopoDS_Face f6 = CreateFaceByPoints(gp_Pnt(p.X(), p.Y() + dy, p.Z()),
gp_Pnt(p.X() + dx, p.Y() + dy, p.Z()),
gp_Pnt(p.X() + dx, p.Y() + dy, p.Z() + dz),
gp_Pnt(p.X(), p.Y() + dy, p.Z() + dz));
vector<TopoDS_Shape> shapeSet;
shapeSet.push_back(f1);
shapeSet.push_back(f2);
shapeSet.push_back(f3);
shapeSet.push_back(f4);
shapeSet.push_back(f5);
shapeSet.push_back(f6);
TopoDS_Shell shell = SewShell(shapeSet);
solid = BRepBuilderAPI_MakeSolid(shell);
BaseAlgo algo;
if(algo.IsReversed(solid))
{
solid.Reverse();
}
return solid;
}