477 lines
12 KiB
C++
477 lines
12 KiB
C++
|
// 这是主 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;
|
||
|
}
|
||
|
|