2357 lines
56 KiB
C++
2357 lines
56 KiB
C++
|
#include "Stdafx.h"
|
|||
|
#include "OCCCabin_Bool.h"
|
|||
|
#include "OCCLib.h"
|
|||
|
#include "SolidBool.h"
|
|||
|
#include "BRepAlgoAPI_Section.hxx"
|
|||
|
#include "BRepAlgoAPI_Common.hxx"
|
|||
|
#include "BRepBuilderAPI_Copy.hxx"
|
|||
|
#include "BRepBndLib.hxx"
|
|||
|
#include "OCCCabin.h"
|
|||
|
// Added BY XUEFENG
|
|||
|
// 用于计算边对应该边所在面的PCurve
|
|||
|
#include "ShapeConstruct_ProjectCurveOnSurface.hxx"
|
|||
|
|
|||
|
#include "GeomConvert.hxx" // XUEFENG ADDED 202009
|
|||
|
#include "Geom_Surface.hxx" // XUEFENG ADDED 202009
|
|||
|
#include "Geom_BSplineSurface.hxx" // XUEFENG ADDED 202009
|
|||
|
#include "TopoDS_Shape.hxx"
|
|||
|
|
|||
|
#include <string> // ADDED BY XUEFENG 202012
|
|||
|
using namespace std; // ADDED BY XUEFENG 202012
|
|||
|
|
|||
|
OCCCabin_Bool::OCCCabin_Bool(TopoDS_Shape solid)
|
|||
|
{
|
|||
|
this->solid = solid;
|
|||
|
SetWidth(40);
|
|||
|
SetHeight(40);
|
|||
|
SetDir(DIR_X);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
OCCCabin_Bool::~OCCCabin_Bool(void)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void OCCCabin_Bool::SetWidth( double width )
|
|||
|
{
|
|||
|
this->width = width;
|
|||
|
}
|
|||
|
|
|||
|
void OCCCabin_Bool::SetHeight( double height )
|
|||
|
{
|
|||
|
this->height = height;
|
|||
|
}
|
|||
|
|
|||
|
void OCCCabin_Bool::SetDir( DIR d )
|
|||
|
{
|
|||
|
this->dir = d;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void OCCCabin_Bool::Perform(Space space)
|
|||
|
{
|
|||
|
OCCLib occLib;
|
|||
|
|
|||
|
clock_t start,finish; //typedef long clock_t;
|
|||
|
double totaltime;
|
|||
|
start=clock(); //clock():确定处理器当前时间
|
|||
|
|
|||
|
// XUEFENG ADDED 202012
|
|||
|
if(space.numSections>=1)
|
|||
|
{
|
|||
|
//this->MultiSectionSurface()
|
|||
|
|
|||
|
int realSections = space.numSections-1;
|
|||
|
int numPoints = 0;
|
|||
|
int count = 0;
|
|||
|
while(space.FCharacterPoints[count]<999.9)
|
|||
|
{
|
|||
|
count++;
|
|||
|
}
|
|||
|
|
|||
|
if(count%2!=0)
|
|||
|
return;
|
|||
|
|
|||
|
int coupleNum = count/2;
|
|||
|
if(coupleNum%space.numSections!=0)
|
|||
|
return;
|
|||
|
int sectionPointsNum = coupleNum/space.numSections;
|
|||
|
|
|||
|
TopoDS_Shape wholeShape;
|
|||
|
for(int i=0;i<space.numSections-1;i++)
|
|||
|
{
|
|||
|
double frontPoints[MAX_ARRAY_SIZE_L];
|
|||
|
double backpoints[MAX_ARRAY_SIZE_L];
|
|||
|
memset(frontPoints, 0, MAX_ARRAY_SIZE_L);
|
|||
|
memset(backpoints, 0, MAX_ARRAY_SIZE_L);
|
|||
|
|
|||
|
/*
|
|||
|
for(int j=0; j<2*sectionPointsNum+2; j++)
|
|||
|
{
|
|||
|
frontPoints[j] = space.FCharacterPoints[i*2*sectionPointsNum + j];
|
|||
|
backpoints[j] = space.FCharacterPoints[(i+1)*2*sectionPointsNum + j];
|
|||
|
}
|
|||
|
frontPoints[2*sectionPointsNum]= space.FCharacterPoints[i*2*sectionPointsNum + 0];
|
|||
|
backpoints[2*sectionPointsNum] = space.FCharacterPoints[(i+1)*2*sectionPointsNum + 0];
|
|||
|
frontPoints[2*sectionPointsNum+1]= space.FCharacterPoints[i*2*sectionPointsNum + 1];
|
|||
|
backpoints[2*sectionPointsNum+1] = space.FCharacterPoints[(i+1)*2*sectionPointsNum + 1];
|
|||
|
|
|||
|
frontPoints[2*sectionPointsNum+2]=1000;
|
|||
|
backpoints[2*sectionPointsNum+2]=1000;
|
|||
|
|
|||
|
vector<gp_Pnt2d> p2dSetFront = ConvertPoint2dSet(frontPoints, width, height);
|
|||
|
vector<gp_Pnt2d> p2dSetBack = ConvertPoint2dSet(backpoints, width, height);
|
|||
|
|
|||
|
if(p2dSetBack.size() == 0 || p2dSetFront.size() == 0)
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
vector<gp_Pnt> pSetFront = CreatePointSet(p2dSetFront, space.LCharacterPoints[i]);
|
|||
|
vector<gp_Pnt> pSetBack = CreatePointSet(p2dSetBack, space.LCharacterPoints[i+1]);
|
|||
|
*/
|
|||
|
|
|||
|
// XUEFENG MODIFIED 20210623
|
|||
|
vector<gp_Pnt> pSetFront;
|
|||
|
vector<gp_Pnt> pSetBack;
|
|||
|
if(sectionPointsNum>2)
|
|||
|
{
|
|||
|
for(int j=0; j<2*sectionPointsNum; j++)
|
|||
|
{
|
|||
|
frontPoints[j] = space.FCharacterPoints[i*2*sectionPointsNum + j];
|
|||
|
backpoints[j] = space.FCharacterPoints[(i+1)*2*sectionPointsNum + j];
|
|||
|
}
|
|||
|
|
|||
|
/* // XUEFENG DELETED 20210623
|
|||
|
frontPoints[2*sectionPointsNum]= space.FCharacterPoints[i*2*sectionPointsNum + 0];
|
|||
|
backpoints[2*sectionPointsNum] = space.FCharacterPoints[(i+1)*2*sectionPointsNum + 0];
|
|||
|
frontPoints[2*sectionPointsNum+1]= space.FCharacterPoints[i*2*sectionPointsNum + 1];
|
|||
|
backpoints[2*sectionPointsNum+1] = space.FCharacterPoints[(i+1)*2*sectionPointsNum + 1];
|
|||
|
*/
|
|||
|
|
|||
|
frontPoints[2*sectionPointsNum]=1000;
|
|||
|
backpoints[2*sectionPointsNum]=1000;
|
|||
|
|
|||
|
vector<gp_Pnt2d> p2dSetFront = ConvertPoint2dSet(frontPoints, width, height);
|
|||
|
vector<gp_Pnt2d> p2dSetBack = ConvertPoint2dSet(backpoints, width, height);
|
|||
|
|
|||
|
if(p2dSetBack.size() == 0 || p2dSetFront.size() == 0)
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//vector<gp_Pnt> pSetFront = CreatePointSet(p2dSetFront, space.LCharacterPoints[i]);
|
|||
|
//vector<gp_Pnt> pSetBack = CreatePointSet(p2dSetBack, space.LCharacterPoints[i+1]);
|
|||
|
pSetFront = CreatePointSet(p2dSetFront, space.LCharacterPoints[i]);
|
|||
|
pSetBack = CreatePointSet(p2dSetBack, space.LCharacterPoints[i+1]);
|
|||
|
|
|||
|
// XUEFENG ADDED 20211020
|
|||
|
gp_Pnt tmpCycleFPoint = pSetFront[0];
|
|||
|
gp_Pnt tmpCycleBPoint = pSetBack[0];
|
|||
|
pSetFront.push_back(tmpCycleFPoint);
|
|||
|
pSetBack.push_back(tmpCycleBPoint);
|
|||
|
// END ADDED
|
|||
|
}
|
|||
|
else if(sectionPointsNum==2)
|
|||
|
{
|
|||
|
for(int j=0; j<2*sectionPointsNum; j++)
|
|||
|
{
|
|||
|
frontPoints[j] = space.FCharacterPoints[i*2*sectionPointsNum + j];
|
|||
|
backpoints[j] = space.FCharacterPoints[(i+1)*2*sectionPointsNum + j];
|
|||
|
}
|
|||
|
|
|||
|
frontPoints[2*sectionPointsNum]=1000;
|
|||
|
backpoints[2*sectionPointsNum]=1000;
|
|||
|
|
|||
|
vector<gp_Pnt2d> p2dSetFront = ConvertPoint2dSet(frontPoints, width, height);
|
|||
|
vector<gp_Pnt2d> p2dSetBack = ConvertPoint2dSet(backpoints, width, height);
|
|||
|
|
|||
|
if(p2dSetBack.size() == 0 || p2dSetFront.size() == 0)
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
pSetFront = CreatePointSet(p2dSetFront, space.LCharacterPoints[i]);
|
|||
|
pSetBack = CreatePointSet(p2dSetBack, space.LCharacterPoints[i+1]);
|
|||
|
}
|
|||
|
else
|
|||
|
return;
|
|||
|
// END MODIFIED
|
|||
|
|
|||
|
|
|||
|
TopoDS_Shape sectionShape = this->ConstructComplexBSplineShape(pSetFront, pSetBack);
|
|||
|
|
|||
|
|
|||
|
{
|
|||
|
GProp_GProps massProps;
|
|||
|
BRepGProp::VolumeProperties(sectionShape, massProps);
|
|||
|
Standard_Real myVolume = massProps.Mass();
|
|||
|
if(myVolume<0)
|
|||
|
sectionShape.Reverse();
|
|||
|
}
|
|||
|
|
|||
|
if(wholeShape.IsNull()==true)
|
|||
|
wholeShape = sectionShape;
|
|||
|
else
|
|||
|
{
|
|||
|
BRepAlgoAPI_Fuse boolOper(wholeShape,sectionShape);
|
|||
|
if(boolOper.IsDone())
|
|||
|
{
|
|||
|
wholeShape = boolOper.Shape();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// XUEFENG ADDED 20230509
|
|||
|
// FOR DEBUG
|
|||
|
{
|
|||
|
GProp_GProps massProps;
|
|||
|
BRepGProp::VolumeProperties(wholeShape, massProps);
|
|||
|
Standard_Real myVolume = massProps.Mass();
|
|||
|
if(myVolume<0)
|
|||
|
wholeShape.Reverse();
|
|||
|
}
|
|||
|
result = wholeShape;
|
|||
|
|
|||
|
if(space.HullID==-99999) // FROM 0
|
|||
|
{
|
|||
|
result = wholeShape;
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//船体
|
|||
|
TopoDS_Shape solidHULL = this->solid; //XUEFENG ADDED 20210623
|
|||
|
{
|
|||
|
GProp_GProps massProps;
|
|||
|
BRepGProp::VolumeProperties(solidHULL, massProps);
|
|||
|
Standard_Real myVolume = massProps.Mass();
|
|||
|
if(myVolume<0)
|
|||
|
solidHULL.Reverse();
|
|||
|
}
|
|||
|
|
|||
|
TopoDS_Shape S;
|
|||
|
BRepAlgoAPI_Common boolOper(solidHULL,wholeShape);
|
|||
|
|
|||
|
if(boolOper.IsDone())
|
|||
|
{
|
|||
|
S = boolOper.Shape();
|
|||
|
result = S;
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
// END ADDED
|
|||
|
|
|||
|
if(space.X1 > space.X2) //尾端面应小于首端面
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
//体
|
|||
|
TopoDS_Shape solid1 = this->solid;
|
|||
|
//BRepTools::Write(solid1, "C:\\CCS\\doc\\CabinError\\ComplexHull.brep");
|
|||
|
//前后位置面
|
|||
|
TopoDS_Face faceFront,faceBack;
|
|||
|
vector<gp_Pnt> borderFront,borderBack;
|
|||
|
|
|||
|
switch(dir)
|
|||
|
{
|
|||
|
case DIR_X:
|
|||
|
faceFront = occLib.CreatePlane(space.X1, PlaneX, width, height);
|
|||
|
faceBack = occLib.CreatePlane(space.X2, PlaneX, width, height);
|
|||
|
|
|||
|
borderFront.push_back(gp_Pnt(space.X1, width / 2, height / 2));
|
|||
|
borderFront.push_back(gp_Pnt(space.X1, -1 * width / 2, height / 2));
|
|||
|
borderFront.push_back(gp_Pnt(space.X1, -1 * width / 2, -1 * height / 2));
|
|||
|
borderFront.push_back(gp_Pnt(space.X1, width / 2, -1 * height / 2));
|
|||
|
borderFront.push_back(gp_Pnt(space.X1, width / 2, height / 2));
|
|||
|
|
|||
|
borderBack.push_back(gp_Pnt(space.X2, width / 2, height / 2));
|
|||
|
borderBack.push_back(gp_Pnt(space.X2, -1 * width / 2, height / 2));
|
|||
|
borderBack.push_back(gp_Pnt(space.X2, -1 * width / 2, -1 * height / 2));
|
|||
|
borderBack.push_back(gp_Pnt(space.X2, width / 2, -1 * height / 2));
|
|||
|
borderBack.push_back(gp_Pnt(space.X2, width / 2, height / 2));
|
|||
|
break;
|
|||
|
case DIR_Y:
|
|||
|
faceFront = occLib.CreatePlane(space.X1, PlaneY, width, height);
|
|||
|
faceBack = occLib.CreatePlane(space.X2, PlaneY, width, height);
|
|||
|
|
|||
|
borderFront.push_back(gp_Pnt( width / 2, space.X1, height / 2));
|
|||
|
borderFront.push_back(gp_Pnt(-1 * width / 2, space.X1, height / 2));
|
|||
|
borderFront.push_back(gp_Pnt( -1 * width / 2, space.X1, -1 * height / 2));
|
|||
|
borderFront.push_back(gp_Pnt( width / 2, space.X1, -1 * height / 2));
|
|||
|
borderFront.push_back(gp_Pnt(width / 2, space.X1, height / 2));
|
|||
|
|
|||
|
borderBack.push_back(gp_Pnt(width / 2, space.X2, height / 2));
|
|||
|
borderBack.push_back(gp_Pnt( -1 * width / 2, space.X2, height / 2));
|
|||
|
borderBack.push_back(gp_Pnt(-1 * width / 2, space.X2, -1 * height / 2));
|
|||
|
borderBack.push_back(gp_Pnt( width / 2, space.X2, -1 * height / 2));
|
|||
|
borderBack.push_back(gp_Pnt( width / 2, space.X2, height / 2));
|
|||
|
break;
|
|||
|
case DIR_Z:
|
|||
|
faceFront = occLib.CreatePlane(space.X1, PlaneZ, width, height);
|
|||
|
faceBack = occLib.CreatePlane(space.X2, PlaneZ, width, height);
|
|||
|
|
|||
|
borderFront.push_back(gp_Pnt(width / 2, height / 2, space.X1));
|
|||
|
borderFront.push_back(gp_Pnt(-1 * width / 2, height / 2, space.X1));
|
|||
|
borderFront.push_back(gp_Pnt( -1 * width / 2, -1 * height / 2, space.X1));
|
|||
|
borderFront.push_back(gp_Pnt( width / 2, -1 * height / 2, space.X1));
|
|||
|
borderFront.push_back(gp_Pnt( width / 2, height / 2, space.X1));
|
|||
|
|
|||
|
borderBack.push_back(gp_Pnt(width / 2, height / 2, space.X2));
|
|||
|
borderBack.push_back(gp_Pnt( -1 * width / 2, height / 2, space.X2));
|
|||
|
borderBack.push_back(gp_Pnt(-1 * width / 2, -1 * height / 2, space.X2));
|
|||
|
borderBack.push_back(gp_Pnt( width / 2, -1 * height / 2, space.X2));
|
|||
|
borderBack.push_back(gp_Pnt(width / 2, height / 2, space.X2));
|
|||
|
break;
|
|||
|
default:
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//剪切面
|
|||
|
TopoDS_Shell splitShell;
|
|||
|
vector<gp_Pnt2d> p2dSetFront = ConvertPoint2dSet(space.FCharacterPoints, width, height);
|
|||
|
vector<gp_Pnt2d> p2dSetBack = ConvertPoint2dSet(space.LCharacterPoints, width, height);
|
|||
|
|
|||
|
if(p2dSetBack.size() == 0 || p2dSetFront.size() == 0)
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
vector<gp_Pnt> pSetFront = CreatePointSet(p2dSetFront, space.X1);
|
|||
|
vector<gp_Pnt> pSetBack = CreatePointSet(p2dSetBack, space.X2);
|
|||
|
|
|||
|
// Added BY XUEFENG 2018.03
|
|||
|
// 根据前后断面的特征点,按OCC的拓扑结构要求,构造一个立方体,用该立方体和原船体进行布尔操作
|
|||
|
// 根据特征点构造的立方体的前后断面为平面,侧面按B样条曲面进行构造。
|
|||
|
|
|||
|
TopoDS_Shape trunctShape = this->ConstructComplexBSplineShape(pSetFront, pSetBack);
|
|||
|
|
|||
|
// ADDED BY XUEFENG 202012
|
|||
|
if(space.HullID==-99999) // FROM 0
|
|||
|
{
|
|||
|
result = trunctShape;
|
|||
|
return;
|
|||
|
}
|
|||
|
// END ADDED
|
|||
|
|
|||
|
// 求体积
|
|||
|
// 体积为负一般意味着体的方向错了,需要进行反向
|
|||
|
// Added BY XUEFENG 2018.03
|
|||
|
{
|
|||
|
GProp_GProps massProps;
|
|||
|
BRepGProp::VolumeProperties(solid1, massProps);
|
|||
|
Standard_Real myVolume = massProps.Mass();
|
|||
|
if(myVolume<0)
|
|||
|
solid1.Reverse();
|
|||
|
}
|
|||
|
// End Added
|
|||
|
|
|||
|
TopoDS_Shape S;
|
|||
|
BRepAlgoAPI_Common boolOper(solid1,trunctShape);
|
|||
|
if(boolOper.IsDone())
|
|||
|
{
|
|||
|
S = boolOper.Shape();
|
|||
|
result = S;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// End ADDED
|
|||
|
|
|||
|
int countBorderF = 0, countBorderB = 0;
|
|||
|
|
|||
|
for(int j = 0; j < pSetFront.size(); j++)
|
|||
|
{
|
|||
|
gp_Pnt p = pSetFront[j];
|
|||
|
bool isborderF = false;
|
|||
|
for(int i = 0; i < borderFront.size() - 1; i++)
|
|||
|
{
|
|||
|
if(p.Distance(borderFront[i]) < Precision::Confusion())
|
|||
|
{
|
|||
|
isborderF = true;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
if(isborderF)
|
|||
|
{
|
|||
|
countBorderF++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
for(int j = 0; j < pSetBack.size(); j++)
|
|||
|
{
|
|||
|
gp_Pnt p = pSetBack[j];
|
|||
|
bool isborderB = false;
|
|||
|
for(int i = 0; i < borderBack.size() - 1; i++)
|
|||
|
{
|
|||
|
if(p.Distance(borderBack[i]) < Precision::Confusion())
|
|||
|
{
|
|||
|
isborderB = true;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
if(isborderB)
|
|||
|
{
|
|||
|
countBorderB++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
splitShell = CreateSplitShell(pSetFront, pSetBack);
|
|||
|
|
|||
|
//throw splitShell;
|
|||
|
|
|||
|
//剪切端面
|
|||
|
//TopoDS_Face frontFace = CreateEndFace( pSetFront , width, height, space.X1);
|
|||
|
//TopoDS_Face backFace = CreateEndFace( pSetBack, width, height, space.X2);
|
|||
|
|
|||
|
TopoDS_Face frontFace = CutEndFace(faceFront, splitShell, pSetFront, false);// 生成面的时候 边的方向与输入方向是反的
|
|||
|
TopoDS_Face backFace = CutEndFace(faceBack, splitShell, pSetBack, false);
|
|||
|
//result = backFace;
|
|||
|
//return;
|
|||
|
//创建体
|
|||
|
vector<TopoDS_Shape> shapeSet;
|
|||
|
shapeSet.push_back(splitShell);
|
|||
|
shapeSet.push_back(frontFace);
|
|||
|
shapeSet.push_back(backFace);
|
|||
|
//TopoDS_Compound c;
|
|||
|
//BRep_Builder b;
|
|||
|
//b.MakeCompound(c);
|
|||
|
//b.Add(c,splitShell);
|
|||
|
//b.Add(c,frontFace);
|
|||
|
//b.Add(c,backFace);
|
|||
|
//throw c;
|
|||
|
|
|||
|
int count = 0;
|
|||
|
for(int i = 0; i < borderFront.size() - 1; i++)
|
|||
|
{
|
|||
|
BRepExtrema_DistShapeShape dis(BRepBuilderAPI_MakeVertex(borderFront[i]), frontFace);
|
|||
|
dis.Perform();
|
|||
|
if(dis.Value() < Precision::Confusion())
|
|||
|
{
|
|||
|
count++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if(count == 4 && !(countBorderB == pSetBack.size() && countBorderF == pSetFront.size()))
|
|||
|
{
|
|||
|
TopoDS_Shell borderShell = CreateSplitShell(borderFront, borderBack);
|
|||
|
shapeSet.push_back(borderShell);
|
|||
|
}
|
|||
|
|
|||
|
TopoDS_Shell shell = occLib.SewShell(shapeSet);
|
|||
|
TopoDS_Solid solid2 = BRepBuilderAPI_MakeSolid(shell).Solid();
|
|||
|
|
|||
|
if(IsReversed(solid2))
|
|||
|
{
|
|||
|
solid2.Reverse();
|
|||
|
}
|
|||
|
if(IsReversed(solid1))
|
|||
|
{
|
|||
|
solid1.Reverse();
|
|||
|
}
|
|||
|
//throw solid2;
|
|||
|
//BRepAlgoAPI_Common common(solid1 ,shell);
|
|||
|
//throw common.Shape();
|
|||
|
|
|||
|
//BRepAlgoAPI_Section asect(solid1,shell,Standard_False);
|
|||
|
//asect.ComputePCurveOn1(Standard_True);
|
|||
|
////asect.ComputePCurveOn2(Standard_True);
|
|||
|
//asect.Approximation(Standard_True);
|
|||
|
//asect.Build();
|
|||
|
//throw asect.Shape();
|
|||
|
|
|||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
//finish=clock();
|
|||
|
//totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
|
|||
|
//cout << "+++++++++++++++++++++++++++++++准备工作:"<<totaltime<<"s"<<endl;
|
|||
|
|
|||
|
//SolidBool solidBool(solid1, solid2, BOOL_COMMON);
|
|||
|
//solidBool.Perform();
|
|||
|
//result = solidBool.GetResult();
|
|||
|
////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
|||
|
//throw solid2;
|
|||
|
TopoDS_Shell borderShell = CreateSplitShell(borderFront, borderBack);
|
|||
|
shapeSet.clear();
|
|||
|
shapeSet.push_back(borderShell);
|
|||
|
shapeSet.push_back(faceFront);
|
|||
|
shapeSet.push_back(faceBack);
|
|||
|
TopoDS_Shell shell3 = occLib.SewShell(shapeSet);
|
|||
|
TopoDS_Solid solid3 = BRepBuilderAPI_MakeSolid(shell3);
|
|||
|
//result = solid2;
|
|||
|
//return;
|
|||
|
|
|||
|
//BRepTools::Write(solid, "C:\\solid1.brep");
|
|||
|
//BRepTools::Write(solid2, "C:\\solid2.brep");
|
|||
|
|
|||
|
OCCCabin occCabin(solid, faceFront, faceBack, splitShell, gp_Pnt(0,0,0));
|
|||
|
occCabin.SetSecondSolid(solid2);
|
|||
|
occCabin.SetThirdSolid(solid3);
|
|||
|
|
|||
|
occCabin.Build();
|
|||
|
result = occCabin.GetResult();
|
|||
|
|
|||
|
//TopoDS_Compound c;
|
|||
|
//BRep_Builder b;
|
|||
|
//b.MakeCompound(c);
|
|||
|
//b.Add(c, solid);
|
|||
|
//b.Add(c, solid2);
|
|||
|
//BRepTools::Write(c, "C:\\ttt.brep");
|
|||
|
//result = solid2;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
TopoDS_Shape OCCCabin_Bool::ConstructComplexBSplineShape(std::vector<gp_Pnt> pSetFront,std::vector<gp_Pnt> pSetBack)
|
|||
|
{
|
|||
|
// XUEFENG MODIFIED MANY MANY 202012
|
|||
|
// This method only choose which way to use
|
|||
|
// Triangle face use 7.1.0, normal use 6.3.0
|
|||
|
|
|||
|
bool triangleFace=false;
|
|||
|
Standard_Real myTol = Precision::Confusion();
|
|||
|
|
|||
|
int pointNum = pSetFront.size();
|
|||
|
for(int i=0;i<pointNum-2;i++)
|
|||
|
{
|
|||
|
if( pSetFront[i].SquareDistance( pSetFront[i+1]) <= myTol)
|
|||
|
triangleFace = true;
|
|||
|
|
|||
|
if( pSetBack[i].SquareDistance( pSetBack[i+1]) <= myTol)
|
|||
|
triangleFace = true;
|
|||
|
}
|
|||
|
|
|||
|
if(triangleFace)
|
|||
|
return ConstructComplexBSplineShape710(pSetFront, pSetBack);
|
|||
|
else
|
|||
|
return ConstructComplexBSplineShape630Original(pSetFront, pSetBack);
|
|||
|
}
|
|||
|
|
|||
|
// 下面开始实现
|
|||
|
// Handle(Geom2d_Curve) getPCurve(Handle(Geom_Surface) surfaceIn, Handle(Geom_Curve) curve3dIn)
|
|||
|
// TopoDS_Shape ConstructComplexBSplineShape(std::vector<gp_Pnt> pSetFront,std::vector<gp_Pnt> pSetBack)
|
|||
|
// Handle(Geom_BSplineCurve) getBSplineCurveMultiPoints(gp_Pnt points[], int len)
|
|||
|
// 3个函数
|
|||
|
/*
|
|||
|
* 根据前后断面特征点构造立方体
|
|||
|
*/
|
|||
|
// XUEFENG ADDED 202102
|
|||
|
// FOR CONSTRUCT SOLID in OCC 6.3.0 and 7.1.0 WAY
|
|||
|
|
|||
|
// This is a 7.1.0 way!
|
|||
|
TopoDS_Shape OCCCabin_Bool::ConstructComplexBSplineShape710(std::vector<gp_Pnt> pSetFront,std::vector<gp_Pnt> pSetBack)
|
|||
|
{
|
|||
|
// XUEFENG MODIFIED MANY MANY 202012
|
|||
|
|
|||
|
TopoDS_Solid mySolid;
|
|||
|
TopoDS_Shell myShell;
|
|||
|
BRep_Builder myBrepBuilder;
|
|||
|
Standard_Real myTol = Precision::Confusion();
|
|||
|
|
|||
|
myBrepBuilder.MakeShell(myShell);
|
|||
|
myBrepBuilder.MakeSolid(mySolid);
|
|||
|
|
|||
|
std::vector<TopoDS_Vertex> frontVertex, backVertex;
|
|||
|
std::vector<Handle(Geom_BSplineCurve)> frontBSplineLine, backBSplineLine, sideBSplineLine;
|
|||
|
std::vector<TopoDS_Edge> frontBSplineEdge, backBSplineEdge, sideBSplineEdge;
|
|||
|
|
|||
|
int pointNum = pSetFront.size();
|
|||
|
for(int i=0;i<pointNum-1;i++)
|
|||
|
{
|
|||
|
TopoDS_Vertex fV,bV;
|
|||
|
myBrepBuilder.MakeVertex(fV, pSetFront[i], myTol);
|
|||
|
myBrepBuilder.MakeVertex(bV, pSetBack[i], myTol);
|
|||
|
|
|||
|
frontVertex.push_back(fV);
|
|||
|
backVertex.push_back(bV);
|
|||
|
}
|
|||
|
|
|||
|
// Init Geom_Curve3ds
|
|||
|
// 构建前、后、侧面的 几何几何几何 边
|
|||
|
for(int i=0;i<pointNum-1;i++)
|
|||
|
{
|
|||
|
int next = (i==(pointNum-2))? 0:(i+1);
|
|||
|
{
|
|||
|
gp_Pnt pointsArray[2] = { pSetFront[i], pSetFront[next] };
|
|||
|
|
|||
|
Handle(Geom_BSplineCurve) frontBSPL = NULL;
|
|||
|
if( pSetFront[i].SquareDistance( pSetFront[next]) > myTol)
|
|||
|
frontBSPL = getBSplineCurveMultiPoints(pointsArray, 2);
|
|||
|
|
|||
|
frontBSplineLine.push_back(frontBSPL);
|
|||
|
}
|
|||
|
|
|||
|
{
|
|||
|
gp_Pnt pointsArray[2] = { pSetBack[i], pSetBack[next] };
|
|||
|
Handle(Geom_BSplineCurve) backBSPL = NULL;
|
|||
|
if( pSetBack[i].SquareDistance( pSetBack[next]) > myTol)
|
|||
|
backBSPL = getBSplineCurveMultiPoints(pointsArray, 2);
|
|||
|
|
|||
|
backBSplineLine.push_back(backBSPL);
|
|||
|
}
|
|||
|
|
|||
|
{
|
|||
|
gp_Pnt pointsArray[2] = { pSetFront[i], pSetBack[i] };
|
|||
|
Handle(Geom_BSplineCurve) sideBSPL = getBSplineCurveMultiPoints(pointsArray, 2);
|
|||
|
sideBSplineLine.push_back(sideBSPL);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Init edges
|
|||
|
// 构建前、后、侧面的 拓扑拓扑拓扑 边
|
|||
|
for(int i=0;i<pointNum-1;i++)
|
|||
|
{
|
|||
|
int next = (i==(pointNum-2))? 0:(i+1);
|
|||
|
|
|||
|
// Front BSpline Edge
|
|||
|
TopoDS_Edge fBSplineEdge;
|
|||
|
Handle(Geom_Curve) frontCurve = frontBSplineLine[i];
|
|||
|
if(!frontCurve.IsNull()) //pj change !=NULL->!.IsNull()
|
|||
|
{
|
|||
|
myBrepBuilder.MakeEdge(fBSplineEdge, frontCurve, Precision::Confusion());
|
|||
|
{
|
|||
|
TopoDS_Vertex bV = frontVertex[i];
|
|||
|
TopoDS_Vertex eV = frontVertex[next];
|
|||
|
bV.Orientation(TopAbs_FORWARD);
|
|||
|
eV.Orientation(TopAbs_REVERSED);
|
|||
|
myBrepBuilder.Add(fBSplineEdge, bV);
|
|||
|
myBrepBuilder.Add(fBSplineEdge, eV);
|
|||
|
|
|||
|
BRepTools::Update(fBSplineEdge);
|
|||
|
}
|
|||
|
}
|
|||
|
if(fBSplineEdge.IsNull())
|
|||
|
int stop = 10;
|
|||
|
frontBSplineEdge.push_back(fBSplineEdge);
|
|||
|
|
|||
|
// Back BSpline Edge
|
|||
|
TopoDS_Edge bBSplineEdge;
|
|||
|
Handle(Geom_Curve) backCurve = backBSplineLine[i];
|
|||
|
if(!backCurve.IsNull()) //pj change !=NULL->!.IsNull()
|
|||
|
{
|
|||
|
myBrepBuilder.MakeEdge(bBSplineEdge, backCurve, Precision::Confusion());
|
|||
|
{
|
|||
|
TopoDS_Vertex bV = backVertex[i];
|
|||
|
TopoDS_Vertex eV = backVertex[next];
|
|||
|
bV.Orientation(TopAbs_FORWARD);
|
|||
|
eV.Orientation(TopAbs_REVERSED);
|
|||
|
myBrepBuilder.Add(bBSplineEdge, bV);
|
|||
|
myBrepBuilder.Add(bBSplineEdge, eV);
|
|||
|
|
|||
|
BRepTools::Update(bBSplineEdge);
|
|||
|
}
|
|||
|
}
|
|||
|
if(bBSplineEdge.IsNull())
|
|||
|
int stop = 10;
|
|||
|
backBSplineEdge.push_back(bBSplineEdge);
|
|||
|
|
|||
|
TopoDS_Edge sBSplineEdge;
|
|||
|
Handle(Geom_Curve) sideCurve = sideBSplineLine[i];
|
|||
|
myBrepBuilder.MakeEdge(sBSplineEdge, sideCurve, Precision::Confusion());
|
|||
|
{
|
|||
|
TopoDS_Vertex bV = frontVertex[i];
|
|||
|
TopoDS_Vertex eV = backVertex[i];
|
|||
|
bV.Orientation(TopAbs_FORWARD);
|
|||
|
eV.Orientation(TopAbs_REVERSED);
|
|||
|
myBrepBuilder.Add(sBSplineEdge, bV);
|
|||
|
myBrepBuilder.Add(sBSplineEdge, eV);
|
|||
|
|
|||
|
BRepTools::Update(sBSplineEdge);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
sideBSplineEdge.push_back(sBSplineEdge);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// XUEFENG ADDED 20201208
|
|||
|
// OCC 7.1.0. Simple Way
|
|||
|
TopoDS_Face frontFace,backFace;
|
|||
|
std::vector<TopoDS_Face> sideFaces;
|
|||
|
BRepBuilderAPI_Sewing mySewObj(Precision::Confusion());
|
|||
|
{
|
|||
|
// Front and Back face
|
|||
|
TopoDS_Wire fWire,bWire;
|
|||
|
myBrepBuilder.MakeWire(fWire);
|
|||
|
myBrepBuilder.MakeWire(bWire);
|
|||
|
for(int i=0;i<pointNum-1;i++)
|
|||
|
{
|
|||
|
if(!frontBSplineEdge[i].IsNull())
|
|||
|
myBrepBuilder.Add(fWire, frontBSplineEdge[i]);
|
|||
|
|
|||
|
if(!backBSplineEdge[i].IsNull())
|
|||
|
myBrepBuilder.Add(bWire, backBSplineEdge[i]);
|
|||
|
}
|
|||
|
|
|||
|
BRepTools::Update(fWire);
|
|||
|
BRepTools::Update(bWire);
|
|||
|
|
|||
|
Standard_Boolean retfW = fWire.Closed();
|
|||
|
Standard_Boolean retbW = bWire.Closed();
|
|||
|
|
|||
|
//bWire.Reverse();
|
|||
|
frontFace = BRepBuilderAPI_MakeFace(fWire, true);
|
|||
|
backFace = BRepBuilderAPI_MakeFace(bWire, true);
|
|||
|
}
|
|||
|
mySewObj.Add(frontFace);
|
|||
|
mySewObj.Add(backFace);
|
|||
|
|
|||
|
myBrepBuilder.Add(myShell,frontFace);
|
|||
|
myBrepBuilder.Add(myShell,backFace);
|
|||
|
//return myShell;
|
|||
|
|
|||
|
// 构建几何体的侧面
|
|||
|
{
|
|||
|
std::vector<TopoDS_Wire> sideWires;
|
|||
|
for(int i=0;i<pointNum-1;i++)
|
|||
|
{
|
|||
|
int next = (i==(pointNum-2))? 0:(i+1);
|
|||
|
|
|||
|
TopoDS_Wire sWire;
|
|||
|
/*
|
|||
|
myBrepBuilder.MakeWire(sWire);
|
|||
|
|
|||
|
myBrepBuilder.Add(sWire, frontBSplineEdge[i]);
|
|||
|
myBrepBuilder.Add(sWire, sideBSplineEdge[next]);
|
|||
|
backBSplineEdge[i].Reverse();
|
|||
|
sideBSplineEdge[i].Reverse();
|
|||
|
myBrepBuilder.Add(sWire, backBSplineEdge[i]);
|
|||
|
myBrepBuilder.Add(sWire, sideBSplineEdge[i]);
|
|||
|
|
|||
|
BRepTools::Update(sWire);
|
|||
|
*/
|
|||
|
{
|
|||
|
GeomFill_FillingStyle fillType = GeomFill_StretchStyle;
|
|||
|
|
|||
|
Handle(Geom_BSplineCurve) GL1 = frontBSplineLine[i];
|
|||
|
Handle(Geom_BSplineCurve) GL2 = sideBSplineLine[next];
|
|||
|
Handle(Geom_BSplineCurve) GL3 = backBSplineLine[i];
|
|||
|
Handle(Geom_BSplineCurve) GL4 = sideBSplineLine[i];
|
|||
|
|
|||
|
GeomFill_BSplineCurves aGeomFill;
|
|||
|
/* if(GL1==NULL && GL2!=NULL && GL3!=NULL && GL4!=NULL) //pj change
|
|||
|
aGeomFill.Init( GL2, GL3, GL4, fillType); // XUEFENG MODIFIED 202102 //pj change
|
|||
|
else if(GL1!=NULL && GL2!=NULL && GL3==NULL && GL4!=NULL) //pj change
|
|||
|
aGeomFill.Init(GL1, GL2, GL4, fillType);
|
|||
|
else if(GL1==NULL && GL3==NULL) // XUEFENG MODIFIED 202102 NO face //pj change
|
|||
|
continue; // XUEFENG MODIFIED 202102
|
|||
|
else
|
|||
|
aGeomFill.Init(GL1, GL2, GL3, GL4, fillType); */
|
|||
|
|
|||
|
if(GL1.IsNull() && !GL2.IsNull() && !GL3.IsNull() && !GL4.IsNull()) //pj change !=NULL->!.IsNull() ==NULL->.IsNull()
|
|||
|
aGeomFill.Init( GL2, GL3, GL4, fillType); // XUEFENG MODIFIED 202102 //pj change
|
|||
|
else if(!GL1.IsNull() && !GL2.IsNull() && GL3.IsNull() && !GL4.IsNull()) //pj change
|
|||
|
aGeomFill.Init(GL1, GL2, GL4, fillType);
|
|||
|
else if(GL1.IsNull() && GL3.IsNull()) // XUEFENG MODIFIED 202102 NO face //pj change
|
|||
|
continue; // XUEFENG MODIFIED 202102
|
|||
|
else
|
|||
|
aGeomFill.Init(GL1, GL2, GL3, GL4, fillType);
|
|||
|
|
|||
|
Handle(Geom_BSplineSurface) aSurf = aGeomFill.Surface(); // XUEFENG ADDED 202009 OCC 7.1.0
|
|||
|
|
|||
|
TopoDS_Face sBSplineFace = BRepBuilderAPI_MakeFace(aSurf, Precision::Confusion()); // XUEFENG ADDED 202009
|
|||
|
|
|||
|
//backBSplineEdge[i].Reverse();
|
|||
|
//sideBSplineEdge[i].Reverse();
|
|||
|
|
|||
|
//sideWires.push_back(sWire);
|
|||
|
sideFaces.push_back(sBSplineFace);
|
|||
|
|
|||
|
mySewObj.Add(sBSplineFace);
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
mySewObj.Perform();
|
|||
|
TopoDS_Shell mySewShell = TopoDS::Shell(mySewObj.SewedShape());
|
|||
|
TopoDS_Solid mySewSolid = BRepBuilderAPI_MakeSolid(mySewShell);
|
|||
|
|
|||
|
// 求体积
|
|||
|
// 体积为负一般意味着体的方向错了,需要进行反向
|
|||
|
// Added BY XUEFENG 2018.03
|
|||
|
{
|
|||
|
GProp_GProps massProps;
|
|||
|
BRepGProp::VolumeProperties(mySewSolid, massProps);
|
|||
|
Standard_Real myVolume = massProps.Mass();
|
|||
|
if(myVolume<0)
|
|||
|
mySewSolid.Reverse();
|
|||
|
}
|
|||
|
// End Added
|
|||
|
|
|||
|
// END ADDED
|
|||
|
|
|||
|
|
|||
|
return mySewSolid;
|
|||
|
}
|
|||
|
|
|||
|
// This is a 6.3.0 Way!
|
|||
|
TopoDS_Shape OCCCabin_Bool::ConstructComplexBSplineShape630Original(std::vector<gp_Pnt> pSetFront,std::vector<gp_Pnt> pSetBack)
|
|||
|
{
|
|||
|
TopoDS_Solid mySolid;
|
|||
|
TopoDS_Shell myShell;
|
|||
|
BRep_Builder myBrepBuilder;
|
|||
|
Standard_Real myTol = Precision::Confusion();
|
|||
|
|
|||
|
myBrepBuilder.MakeShell(myShell);
|
|||
|
myBrepBuilder.MakeSolid(mySolid);
|
|||
|
|
|||
|
std::vector<TopoDS_Vertex> frontVertex, backVertex;
|
|||
|
std::vector<Handle(Geom_BSplineCurve)> frontBSplineLine, backBSplineLine, sideBSplineLine;
|
|||
|
std::vector<TopoDS_Edge> frontBSplineEdge, backBSplineEdge, sideBSplineEdge;
|
|||
|
|
|||
|
// XUEFENG ADDED 20211020
|
|||
|
/*
|
|||
|
gp_Pnt tmpCycleFPoint = pSetFront[0];
|
|||
|
gp_Pnt tmpCycleBPoint = pSetBack[0];
|
|||
|
pSetFront.push_back(tmpCycleFPoint);
|
|||
|
pSetBack.push_back(tmpCycleBPoint);
|
|||
|
*/
|
|||
|
// END ADDED
|
|||
|
|
|||
|
int pointNum = pSetFront.size();
|
|||
|
for(int i=0;i<pointNum-1;i++)
|
|||
|
{
|
|||
|
TopoDS_Vertex fV,bV;
|
|||
|
myBrepBuilder.MakeVertex(fV, pSetFront[i], myTol);
|
|||
|
myBrepBuilder.MakeVertex(bV, pSetBack[i], myTol);
|
|||
|
|
|||
|
frontVertex.push_back(fV);
|
|||
|
backVertex.push_back(bV);
|
|||
|
}
|
|||
|
|
|||
|
// Init Geom_Curve3ds
|
|||
|
// 构建前、后、侧面的 几何几何几何 边
|
|||
|
for(int i=0;i<pointNum-1;i++)
|
|||
|
{
|
|||
|
int next = (i==(pointNum-2))? 0:(i+1);
|
|||
|
{
|
|||
|
gp_Pnt pointsArray[2] = { pSetFront[i], pSetFront[next] };
|
|||
|
Handle(Geom_BSplineCurve) frontBSPL = getBSplineCurveMultiPoints(pointsArray, 2);
|
|||
|
frontBSplineLine.push_back(frontBSPL);
|
|||
|
}
|
|||
|
|
|||
|
{
|
|||
|
gp_Pnt pointsArray[2] = { pSetBack[i], pSetBack[next] };
|
|||
|
Handle(Geom_BSplineCurve) backBSPL = getBSplineCurveMultiPoints(pointsArray, 2);
|
|||
|
backBSplineLine.push_back(backBSPL);
|
|||
|
}
|
|||
|
|
|||
|
{
|
|||
|
gp_Pnt pointsArray[2] = { pSetFront[i], pSetBack[i] };
|
|||
|
Handle(Geom_BSplineCurve) sideBSPL = getBSplineCurveMultiPoints(pointsArray, 2);
|
|||
|
sideBSplineLine.push_back(sideBSPL);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Init edges
|
|||
|
// 构建前、后、侧面的 拓扑拓扑拓扑 边
|
|||
|
for(int i=0;i<pointNum-1;i++)
|
|||
|
{
|
|||
|
int next = (i==(pointNum-2))? 0:(i+1);
|
|||
|
|
|||
|
// Front BSpline Edge
|
|||
|
TopoDS_Edge fBSplineEdge;
|
|||
|
Handle(Geom_Curve) frontCurve = frontBSplineLine[i];
|
|||
|
myBrepBuilder.MakeEdge(fBSplineEdge, frontCurve, Precision::Confusion());
|
|||
|
{
|
|||
|
TopoDS_Vertex bV = frontVertex[i];
|
|||
|
TopoDS_Vertex eV = frontVertex[next];
|
|||
|
bV.Orientation(TopAbs_FORWARD);
|
|||
|
eV.Orientation(TopAbs_REVERSED);
|
|||
|
myBrepBuilder.Add(fBSplineEdge, bV);
|
|||
|
myBrepBuilder.Add(fBSplineEdge, eV);
|
|||
|
|
|||
|
BRepTools::Update(fBSplineEdge);
|
|||
|
}
|
|||
|
frontBSplineEdge.push_back(fBSplineEdge);
|
|||
|
|
|||
|
// Back BSpline Edge
|
|||
|
TopoDS_Edge bBSplineEdge;
|
|||
|
Handle(Geom_Curve) backCurve = backBSplineLine[i];
|
|||
|
myBrepBuilder.MakeEdge(bBSplineEdge, backCurve, Precision::Confusion());
|
|||
|
{
|
|||
|
TopoDS_Vertex bV = backVertex[i];
|
|||
|
TopoDS_Vertex eV = backVertex[next];
|
|||
|
bV.Orientation(TopAbs_FORWARD);
|
|||
|
eV.Orientation(TopAbs_REVERSED);
|
|||
|
myBrepBuilder.Add(bBSplineEdge, bV);
|
|||
|
myBrepBuilder.Add(bBSplineEdge, eV);
|
|||
|
|
|||
|
BRepTools::Update(bBSplineEdge);
|
|||
|
}
|
|||
|
|
|||
|
backBSplineEdge.push_back(bBSplineEdge);
|
|||
|
|
|||
|
TopoDS_Edge sBSplineEdge;
|
|||
|
Handle(Geom_Curve) sideCurve = sideBSplineLine[i];
|
|||
|
myBrepBuilder.MakeEdge(sBSplineEdge, sideCurve, Precision::Confusion());
|
|||
|
{
|
|||
|
TopoDS_Vertex bV = frontVertex[i];
|
|||
|
TopoDS_Vertex eV = backVertex[i];
|
|||
|
bV.Orientation(TopAbs_FORWARD);
|
|||
|
eV.Orientation(TopAbs_REVERSED);
|
|||
|
myBrepBuilder.Add(sBSplineEdge, bV);
|
|||
|
myBrepBuilder.Add(sBSplineEdge, eV);
|
|||
|
|
|||
|
BRepTools::Update(sBSplineEdge);
|
|||
|
}
|
|||
|
|
|||
|
sideBSplineEdge.push_back(sBSplineEdge);
|
|||
|
}
|
|||
|
|
|||
|
{
|
|||
|
// Front and Back face
|
|||
|
TopoDS_Wire fWire,bWire;
|
|||
|
myBrepBuilder.MakeWire(fWire);
|
|||
|
myBrepBuilder.MakeWire(bWire);
|
|||
|
for(int i=0;i<pointNum-1;i++)
|
|||
|
{
|
|||
|
myBrepBuilder.Add(fWire, frontBSplineEdge[i]);
|
|||
|
myBrepBuilder.Add(bWire, backBSplineEdge[i]);
|
|||
|
}
|
|||
|
|
|||
|
BRepTools::Update(fWire);
|
|||
|
BRepTools::Update(bWire);
|
|||
|
|
|||
|
Standard_Boolean retfW = fWire.Closed();
|
|||
|
Standard_Boolean retbW = bWire.Closed();
|
|||
|
// Construct face
|
|||
|
{
|
|||
|
TopoDS_Face frontFace,backFace;
|
|||
|
|
|||
|
/*
|
|||
|
gp_Dir dirF1(pSetFront[0].X()-pSetFront[1].X(),
|
|||
|
pSetFront[0].Y()-pSetFront[1].Y(),
|
|||
|
pSetFront[0].Z()-pSetFront[1].Z());
|
|||
|
gp_Dir dirF2(pSetFront[1].X()-pSetFront[2].X(),
|
|||
|
pSetFront[1].Y()-pSetFront[2].Y(),
|
|||
|
pSetFront[1].Z()-pSetFront[2].Z());
|
|||
|
gp_Dir dirCrossF = dirF2.Crossed(dirF1);
|
|||
|
gp_Pln fPlane(pSetFront[1],dirCrossF);
|
|||
|
*/
|
|||
|
gp_Pln fPlane(pSetFront[1],gp_Dir(1,0,0)); // 平面法向顺 X 轴方向,前断面后面要反向
|
|||
|
|
|||
|
myBrepBuilder.MakeFace(frontFace,new Geom_Plane(fPlane),Precision::Confusion());
|
|||
|
|
|||
|
/*
|
|||
|
gp_Dir dirB1(pSetBack[1].X()-pSetBack[0].X(),
|
|||
|
pSetBack[1].Y()-pSetBack[0].Y(),
|
|||
|
pSetBack[1].Z()-pSetBack[0].Z());
|
|||
|
gp_Dir dirB2(pSetBack[2].X()-pSetBack[1].X(),
|
|||
|
pSetBack[2].Y()-pSetBack[1].Y(),
|
|||
|
pSetBack[2].Z()-pSetBack[1].Z());
|
|||
|
gp_Dir dirCrossB = dirB2.Crossed(dirB1);
|
|||
|
gp_Pln bPlane(pSetBack[1],dirCrossB);
|
|||
|
*/
|
|||
|
gp_Pln bPlane(pSetBack[1],gp_Dir(1,0,0)); // 平面法向顺 X 轴方向,后断面保持
|
|||
|
|
|||
|
myBrepBuilder.MakeFace(backFace,new Geom_Plane(bPlane),Precision::Confusion());
|
|||
|
|
|||
|
myBrepBuilder.Add(frontFace, fWire);
|
|||
|
myBrepBuilder.Add(backFace, bWire);
|
|||
|
|
|||
|
frontFace.Reverse(); // 这个面的朝向要反向,否则构建的体的这个面的朝向将不对,会导致布尔失败
|
|||
|
myBrepBuilder.Add(myShell, frontFace);
|
|||
|
myBrepBuilder.Add(myShell, backFace);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 构建几何体的侧面
|
|||
|
{
|
|||
|
// Side faces
|
|||
|
std::vector<TopoDS_Wire> sideWires;
|
|||
|
std::vector<TopoDS_Face> sideFaces;
|
|||
|
for(int i=0;i<pointNum-1;i++)
|
|||
|
{
|
|||
|
int next = (i==(pointNum-2))? 0:(i+1);
|
|||
|
|
|||
|
TopoDS_Wire sWire;
|
|||
|
myBrepBuilder.MakeWire(sWire);
|
|||
|
|
|||
|
myBrepBuilder.Add(sWire, frontBSplineEdge[i]);
|
|||
|
myBrepBuilder.Add(sWire, sideBSplineEdge[next]);
|
|||
|
backBSplineEdge[i].Reverse();
|
|||
|
sideBSplineEdge[i].Reverse();
|
|||
|
myBrepBuilder.Add(sWire, backBSplineEdge[i]);
|
|||
|
myBrepBuilder.Add(sWire, sideBSplineEdge[i]);
|
|||
|
|
|||
|
BRepTools::Update(sWire);
|
|||
|
|
|||
|
{
|
|||
|
GeomFill_FillingStyle fillType = GeomFill_StretchStyle;
|
|||
|
|
|||
|
Handle(Geom_BSplineCurve) GL1 = frontBSplineLine[i];
|
|||
|
Handle(Geom_BSplineCurve) GL2 = sideBSplineLine[next];
|
|||
|
Handle(Geom_BSplineCurve) GL3 = backBSplineLine[i];
|
|||
|
Handle(Geom_BSplineCurve) GL4 = sideBSplineLine[i];
|
|||
|
|
|||
|
GeomFill_BSplineCurves aGeomFill(GL1, GL2, GL3, GL4, fillType);
|
|||
|
Handle(Geom_BSplineSurface) aBSplineSurface = aGeomFill.Surface();
|
|||
|
Handle(Geom_Surface) aSurf = aBSplineSurface;
|
|||
|
|
|||
|
TopoDS_Face sBSplineFace;
|
|||
|
BRepBuilderAPI_MakeFace MF;
|
|||
|
MF.Init(aSurf, false, myTol); // OCC 7.1.0
|
|||
|
//MF.Init(aSurf, false);
|
|||
|
MF.Add(sWire);
|
|||
|
sBSplineFace = MF.Face();
|
|||
|
|
|||
|
// 关键关键
|
|||
|
// 添加边和面的投影关系信息
|
|||
|
{
|
|||
|
myBrepBuilder.UpdateEdge(frontBSplineEdge[i], this->getPCurve(aSurf, GL1), sBSplineFace, Precision::Confusion());
|
|||
|
myBrepBuilder.UpdateEdge(sideBSplineEdge[next], this->getPCurve(aSurf, GL2), sBSplineFace, Precision::Confusion());
|
|||
|
myBrepBuilder.UpdateEdge(backBSplineEdge[i], this->getPCurve(aSurf, GL3), sBSplineFace, Precision::Confusion());
|
|||
|
myBrepBuilder.UpdateEdge(sideBSplineEdge[i], this->getPCurve(aSurf, GL4), sBSplineFace, Precision::Confusion());
|
|||
|
|
|||
|
BRepTools::Update(sBSplineFace);
|
|||
|
}
|
|||
|
|
|||
|
backBSplineEdge[i].Reverse();
|
|||
|
sideBSplineEdge[i].Reverse();
|
|||
|
|
|||
|
sideWires.push_back(sWire);
|
|||
|
sideFaces.push_back(sBSplineFace);
|
|||
|
|
|||
|
myBrepBuilder.Add(myShell,sBSplineFace);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
myBrepBuilder.Add(mySolid, myShell);
|
|||
|
|
|||
|
return mySolid;
|
|||
|
}
|
|||
|
// END ADDED
|
|||
|
|
|||
|
/*
|
|||
|
* 采用插值方式通过几个点连成线
|
|||
|
* GeomAPI_PointsToBSpline 是拟合方式,误差较大
|
|||
|
*/
|
|||
|
Handle(Geom_BSplineCurve) OCCCabin_Bool::getBSplineCurveMultiPoints(gp_Pnt points[], int len)
|
|||
|
{
|
|||
|
/*
|
|||
|
TColgp_Array1OfPnt SPLPoints(1,len);
|
|||
|
for(int i=1;i<=len;i++)
|
|||
|
SPLPoints(i)=points[i-1];
|
|||
|
|
|||
|
GeomAPI_PointsToBSpline aPointToSPL(SPLPoints);
|
|||
|
Handle(Geom_BSplineCurve) SPL = aPointToSPL.Curve();
|
|||
|
*/
|
|||
|
|
|||
|
|
|||
|
Handle(TColgp_HArray1OfPnt) SPLPoints = new TColgp_HArray1OfPnt(1,len);
|
|||
|
for(int i=1;i<=len;i++)
|
|||
|
SPLPoints->SetValue(i, points[i-1]);
|
|||
|
|
|||
|
GeomAPI_Interpolate PtB(SPLPoints, Standard_False, 0.0);
|
|||
|
PtB.Perform();
|
|||
|
Handle(Geom_BSplineCurve) SPL;
|
|||
|
if(PtB.IsDone())
|
|||
|
SPL=PtB.Curve();
|
|||
|
|
|||
|
return SPL;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Get the pcurve from a curve on a surface
|
|||
|
* 得到一个几何曲线相对于其所在的几何面的参数曲线
|
|||
|
*/
|
|||
|
Handle(Geom2d_Curve) OCCCabin_Bool::getPCurve(Handle(Geom_Surface) surfaceIn, Handle(Geom_Curve) curve3dIn)
|
|||
|
{
|
|||
|
Handle(Geom2d_Curve) pcurve = NULL;
|
|||
|
|
|||
|
//try{
|
|||
|
// ShapeConstruct_ProjectCurveOnSurface pCurveProjector;
|
|||
|
// pCurveProjector.Init(surfaceIn, 0.0);
|
|||
|
|
|||
|
// Standard_Boolean success = pCurveProjector.PerformAdvanced(curve3dIn,
|
|||
|
// curve3dIn->FirstParameter(),
|
|||
|
// curve3dIn->LastParameter(),
|
|||
|
// pcurve);
|
|||
|
//}catch(...){
|
|||
|
// Something error.
|
|||
|
//}
|
|||
|
|
|||
|
return pcurve;
|
|||
|
}
|
|||
|
|
|||
|
// 添加的3个函数实现部分结束
|
|||
|
// BY XUEFENG 2018.03.10
|
|||
|
|
|||
|
//布尔运算 20170601 by czb,type: 0-并,1-差,2-交
|
|||
|
TopoDS_Shape TopoSolidBrepAlgo(int type,TopoDS_Shape& solid1,TopoDS_Shape& solid2)
|
|||
|
{
|
|||
|
TopoDS_Shape toposhape;
|
|||
|
if (solid1.IsNull() || solid2.IsNull()) return toposhape;
|
|||
|
|
|||
|
BaseAlgo algo;
|
|||
|
if(algo.IsReversed((solid1)))
|
|||
|
{
|
|||
|
solid1.Reverse();
|
|||
|
}
|
|||
|
if(algo.IsReversed((solid2)))
|
|||
|
{
|
|||
|
solid2.Reverse();
|
|||
|
}
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
if(type==0)//并
|
|||
|
{
|
|||
|
BRepAlgoAPI_Fuse newfuse(solid1 ,solid2);
|
|||
|
if (!newfuse.IsDone())
|
|||
|
{
|
|||
|
return toposhape;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
toposhape=newfuse.Shape();
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
else if(type==1)//差
|
|||
|
{
|
|||
|
BRepAlgoAPI_Cut cut(solid1, solid2);
|
|||
|
if(!cut.IsDone())
|
|||
|
{
|
|||
|
return toposhape;
|
|||
|
}
|
|||
|
toposhape = cut.Shape();
|
|||
|
}
|
|||
|
else if(type==2)//交
|
|||
|
{
|
|||
|
BRepAlgoAPI_Common comm(solid1, solid2);
|
|||
|
if(!comm.IsDone())
|
|||
|
{
|
|||
|
return toposhape;
|
|||
|
}
|
|||
|
toposhape = comm.Shape();
|
|||
|
}
|
|||
|
}
|
|||
|
catch(...) //20170601 by czb,防止出错后闪退
|
|||
|
{
|
|||
|
toposhape.Nullify();
|
|||
|
return toposhape;
|
|||
|
}
|
|||
|
|
|||
|
return toposhape;
|
|||
|
}
|
|||
|
|
|||
|
void OCCCabin_Bool::Perform2(Space space) //20170601 by czb
|
|||
|
{
|
|||
|
OCCLib occLib;
|
|||
|
|
|||
|
clock_t start,finish; //typedef long clock_t;
|
|||
|
double totaltime;
|
|||
|
start=clock(); //clock():确定处理器当前时间
|
|||
|
|
|||
|
if(space.X1 > space.X2) //尾端面应小于首端面
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//船体
|
|||
|
BRepBuilderAPI_Copy cp(this->solid);
|
|||
|
TopoDS_Shape solid1 = cp.Shape();
|
|||
|
//计算并设定船体坐标范围
|
|||
|
Bnd_Box B;
|
|||
|
BRepBndLib::Add(solid1,B);
|
|||
|
Standard_Real axmin,aymin,azmin,axmax,aymax,azmax;
|
|||
|
B.Get(axmin,aymin,azmin,axmax,aymax,azmax);
|
|||
|
hullMinX = axmin - 0.001;
|
|||
|
hullMaxX = axmax + 0.001;
|
|||
|
hullMinY = aymin - 0.001;
|
|||
|
hullMaxY = aymax + 0.001;
|
|||
|
hullMinZ = azmin - 0.001;
|
|||
|
hullMaxZ = azmax + 0.001;
|
|||
|
|
|||
|
//前后位置面特征点
|
|||
|
vector<gp_Pnt2d> p2dSetFront = ConvertPoint2dSet2(space.FCharacterPoints, width, height);
|
|||
|
vector<gp_Pnt2d> p2dSetBack = ConvertPoint2dSet2(space.LCharacterPoints, width, height);
|
|||
|
|
|||
|
if(p2dSetBack.size() == 0 || p2dSetFront.size() == 0)
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
vector<gp_Pnt> pSetFront = CreatePointSet(p2dSetFront, max(space.X1,this->hullMinX)); //space.X1);
|
|||
|
vector<gp_Pnt> pSetBack = CreatePointSet(p2dSetBack, min(space.X2,this->hullMaxX));//space.X2);
|
|||
|
|
|||
|
|
|||
|
//参数体
|
|||
|
TopoDS_Shell shell;
|
|||
|
shell = CreateShell(pSetFront, pSetBack);
|
|||
|
TopoDS_Solid solid2 = BRepBuilderAPI_MakeSolid(shell).Solid();
|
|||
|
|
|||
|
this->result = solid2;
|
|||
|
return;
|
|||
|
|
|||
|
//this->result = TopoSolidBrepAlgo(2,solid1,solid2);
|
|||
|
|
|||
|
/*if(IsReversed(solid2))
|
|||
|
{
|
|||
|
solid2.Reverse();
|
|||
|
}
|
|||
|
if(IsReversed(solid1))
|
|||
|
{
|
|||
|
solid1.Reverse();
|
|||
|
}*/
|
|||
|
|
|||
|
|
|||
|
BRepAlgoAPI_Common com(solid2, solid1);
|
|||
|
if(com.IsDone())
|
|||
|
{
|
|||
|
this->result = com.Shape();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
TopoDS_Compound c;
|
|||
|
BRep_Builder b;
|
|||
|
b.MakeCompound(c);
|
|||
|
b.Add(c,solid1);
|
|||
|
b.Add(c,solid2);
|
|||
|
this->result = c;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
vector<gp_Pnt2d> OCCCabin_Bool::ConvertPoint2dSet(double* values, double width, double height)
|
|||
|
{
|
|||
|
vector<gp_Pnt2d> pSet, result;
|
|||
|
|
|||
|
|
|||
|
double lw = -1 * width / 2;
|
|||
|
double rw = width / 2;
|
|||
|
double th = height / 2;
|
|||
|
double bh = -1 * height / 2+10; //20161107 by yangchen
|
|||
|
double len = (width + height) / 2;
|
|||
|
|
|||
|
int count = 0;
|
|||
|
vector<int> indexs;
|
|||
|
vector<int> boundIndex;
|
|||
|
vector<TopoDS_Edge> edgeSet;
|
|||
|
for(double* val = values; *val < 999.9; val++,count++)
|
|||
|
{
|
|||
|
double dy = (*val);
|
|||
|
double dz = (*(++val));
|
|||
|
|
|||
|
int y = (int)dy;
|
|||
|
int z = (int)dz;
|
|||
|
bool isBound = false;
|
|||
|
if(y == 777) // Y+,见Statics.convertSpecToDigital
|
|||
|
{
|
|||
|
dy = rw;
|
|||
|
isBound = true;
|
|||
|
|
|||
|
}
|
|||
|
else if(y == -777) // Y-
|
|||
|
{
|
|||
|
dy = lw;
|
|||
|
isBound = true;
|
|||
|
}
|
|||
|
|
|||
|
if(z == 888) // Z+
|
|||
|
{
|
|||
|
dz = th;
|
|||
|
isBound = true;
|
|||
|
}
|
|||
|
else if(z == -888) //Z-
|
|||
|
{
|
|||
|
dz = bh;
|
|||
|
isBound = true;
|
|||
|
}
|
|||
|
|
|||
|
if(abs(y) == 999) // P+ P-
|
|||
|
{
|
|||
|
indexs.push_back(count);
|
|||
|
isBound = true;
|
|||
|
}
|
|||
|
pSet.push_back(gp_Pnt2d(dy, dz));
|
|||
|
|
|||
|
if(isBound)
|
|||
|
{
|
|||
|
boundIndex.push_back(count);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
for(int i = 0; i < indexs.size(); i++)
|
|||
|
{
|
|||
|
int index = indexs[i];
|
|||
|
|
|||
|
gp_Pnt2d& p = pSet[index];
|
|||
|
gp_Pnt2d temp;
|
|||
|
|
|||
|
if(p.X() > 0)
|
|||
|
{
|
|||
|
temp = pSet[(index + 1) % count];
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
temp = pSet[(index - 1+ count) % count];
|
|||
|
}
|
|||
|
|
|||
|
double angle = (p.Y() / 360.0) * 2 * PI;
|
|||
|
|
|||
|
double y = cos(angle) * len + temp.X();
|
|||
|
double z = sin(angle) * len + temp.Y();
|
|||
|
|
|||
|
if(y > rw)
|
|||
|
{
|
|||
|
y = rw;
|
|||
|
z = tan(angle) * (y - temp.X()) + temp.Y();
|
|||
|
if(z > th)
|
|||
|
{
|
|||
|
z = th;
|
|||
|
y = 1 / tan(angle) * (z - temp.Y()) + temp.X();
|
|||
|
}
|
|||
|
else if(z < bh)
|
|||
|
{
|
|||
|
z = bh;
|
|||
|
y = 1 / tan(angle) * (z - temp.Y()) + temp.X();
|
|||
|
}
|
|||
|
}
|
|||
|
else if(y < lw)
|
|||
|
{
|
|||
|
y = lw;
|
|||
|
z = tan(angle) * (y - temp.X()) + temp.Y();
|
|||
|
if(z > th)
|
|||
|
{
|
|||
|
z = th;
|
|||
|
y = 1 / tan(angle) * (z - temp.Y()) + temp.X();
|
|||
|
}
|
|||
|
else if(z < bh)
|
|||
|
{
|
|||
|
z = bh;
|
|||
|
y = 1 / tan(angle) * (z - temp.Y()) + temp.X();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if(z > th)
|
|||
|
{
|
|||
|
z = th;
|
|||
|
y = 1/ tan(angle) * (z - temp.Y()) + temp.X();
|
|||
|
if(y > rw)
|
|||
|
{
|
|||
|
y = rw;
|
|||
|
z = tan(angle) * (y - temp.X()) + temp.Y();
|
|||
|
}
|
|||
|
else if(y < lw)
|
|||
|
{
|
|||
|
y = lw;
|
|||
|
z = tan(angle) * (y - temp.X()) + temp.Y();
|
|||
|
}
|
|||
|
}
|
|||
|
else if(z < bh)
|
|||
|
{
|
|||
|
z = bh;
|
|||
|
y = 1/ tan(angle) * (z - temp.Y()) + temp.X();
|
|||
|
if(y > rw)
|
|||
|
{
|
|||
|
y = rw;
|
|||
|
z = tan(angle) * (y - temp.X()) + temp.Y();
|
|||
|
}
|
|||
|
else if(y < lw)
|
|||
|
{
|
|||
|
y = lw;
|
|||
|
z = tan(angle) * (y - temp.X()) + temp.Y();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
p.SetX(y);
|
|||
|
p.SetY(z);
|
|||
|
}
|
|||
|
|
|||
|
//所有点必须在框内
|
|||
|
for(int i = 0; i < pSet.size(); i++)
|
|||
|
{
|
|||
|
if(abs(pSet[i].X())>rw || abs(pSet[i].Y()) > th)
|
|||
|
{
|
|||
|
return result;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//调整顺序 保证特殊点在首尾
|
|||
|
pSet = Reorder(pSet, boundIndex);
|
|||
|
if(boundIndex.size() == 2)
|
|||
|
{
|
|||
|
boundIndex.clear();
|
|||
|
boundIndex.push_back(0);
|
|||
|
boundIndex.push_back(pSet.size() - 1);
|
|||
|
}
|
|||
|
//调整顺序
|
|||
|
if(boundIndex.size() < 2 || pSet.size() == 2)
|
|||
|
{
|
|||
|
result = pSet;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//判断是否相交
|
|||
|
TopoDS_Edge edge1, edge2;
|
|||
|
int index,nextInd;
|
|||
|
|
|||
|
if(boundIndex[0] == 0 || (boundIndex[0] + pSet.size() - 1) % pSet.size() == boundIndex[1])
|
|||
|
{
|
|||
|
index = (boundIndex[0] + 1) % pSet.size();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
index = (boundIndex[0] + pSet.size() - 1) % pSet.size();
|
|||
|
}
|
|||
|
edge1 = BRepBuilderAPI_MakeEdge(gp_Pnt(0, pSet[boundIndex[0]].X(),pSet[boundIndex[0]].Y()),gp_Pnt(0,pSet[index].X(),pSet[index].Y()));
|
|||
|
|
|||
|
if(boundIndex[1] == 0 || (boundIndex[1] + pSet.size() - 1) % pSet.size() == boundIndex[0])
|
|||
|
{
|
|||
|
index = (boundIndex[1] + 1) % pSet.size();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
index = (boundIndex[1] + pSet.size() - 1) % pSet.size();
|
|||
|
}
|
|||
|
edge2 = BRepBuilderAPI_MakeEdge(gp_Pnt(0, pSet[boundIndex[1]].X(),pSet[boundIndex[1]].Y()),gp_Pnt(0,pSet[index].X(),pSet[index].Y()));
|
|||
|
|
|||
|
BaseAlgo algo;
|
|||
|
if(!algo.IsParallel(edge1, edge2) && pSet.size() > 3/*三个点时 会出现交点特征点的情况*/)
|
|||
|
{
|
|||
|
BRepExtrema_DistShapeShape dis(edge1, edge2);
|
|||
|
dis.Perform();
|
|||
|
if(dis.Value() < Precision::Confusion())
|
|||
|
{
|
|||
|
gp_Pnt p = dis.PointOnShape1(1);
|
|||
|
|
|||
|
gp_Pnt2d p2d(p.Y(), p.Z());
|
|||
|
|
|||
|
result.push_back(p2d);
|
|||
|
for(int i = (boundIndex[0] + 1) % pSet.size(); i != boundIndex[1]; i = (i + 1) % pSet.size())
|
|||
|
{
|
|||
|
result.push_back(pSet[i]);
|
|||
|
}
|
|||
|
result.push_back(p2d);
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
}
|
|||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
|||
|
|
|||
|
vector<gp_Pnt2d> boundPoints;
|
|||
|
gp_Pnt2d p1 = pSet[boundIndex[0]];
|
|||
|
gp_Pnt2d p2 = pSet[boundIndex[1]];
|
|||
|
gp_Pnt2d pp1 = gp_Pnt2d(rw, th);
|
|||
|
gp_Pnt2d pp2 = gp_Pnt2d(lw, th);
|
|||
|
gp_Pnt2d pp3 = gp_Pnt2d(lw, bh);
|
|||
|
gp_Pnt2d pp4 = gp_Pnt2d(rw, bh);
|
|||
|
|
|||
|
boundPoints.push_back(gp_Pnt2d(rw, th));
|
|||
|
if(abs(p1.Y() - boundPoints.back().Y()) < Precision::Confusion())
|
|||
|
{
|
|||
|
gp_Pnt2d p = boundPoints.back();
|
|||
|
|
|||
|
if(p.Distance(p1) > Precision::Confusion() && pp2.Distance(p1) > Precision::Confusion())
|
|||
|
{
|
|||
|
if(p1.X() < p.X())
|
|||
|
{
|
|||
|
boundPoints.push_back(p1);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
boundPoints.pop_back();
|
|||
|
boundPoints.push_back(p1);
|
|||
|
boundPoints.push_back(p);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if(abs(p2.Y() - boundPoints.back().Y()) < Precision::Confusion())
|
|||
|
{
|
|||
|
gp_Pnt2d p = boundPoints.back();
|
|||
|
|
|||
|
if(p.Distance(p2) > Precision::Confusion() && pp2.Distance(p2) > Precision::Confusion())
|
|||
|
{
|
|||
|
if(p2.X() < p.X())
|
|||
|
{
|
|||
|
boundPoints.push_back(p2);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
boundPoints.pop_back();
|
|||
|
boundPoints.push_back(p2);
|
|||
|
boundPoints.push_back(p);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
boundPoints.push_back(gp_Pnt2d(lw, th));
|
|||
|
if(abs(p1.X() - boundPoints.back().X()) < Precision::Confusion())
|
|||
|
{
|
|||
|
gp_Pnt2d p = boundPoints.back();
|
|||
|
|
|||
|
if(p.Distance(p1) > Precision::Confusion() && pp3.Distance(p1) > Precision::Confusion())
|
|||
|
{
|
|||
|
if(p1.Y() < p.Y())
|
|||
|
{
|
|||
|
boundPoints.push_back(p1);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
boundPoints.pop_back();
|
|||
|
boundPoints.push_back(p1);
|
|||
|
boundPoints.push_back(p);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if(abs(p2.X() - boundPoints.back().X()) < Precision::Confusion())
|
|||
|
{
|
|||
|
gp_Pnt2d p = boundPoints.back();
|
|||
|
|
|||
|
if(p.Distance(p2) > Precision::Confusion() && pp3.Distance(p2) > Precision::Confusion())
|
|||
|
{
|
|||
|
if(p2.Y() < p.Y())
|
|||
|
{
|
|||
|
boundPoints.push_back(p2);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
boundPoints.pop_back();
|
|||
|
boundPoints.push_back(p2);
|
|||
|
boundPoints.push_back(p);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
boundPoints.push_back(gp_Pnt2d(lw, bh));
|
|||
|
if(abs(p1.Y() - boundPoints.back().Y()) < Precision::Confusion())
|
|||
|
{
|
|||
|
gp_Pnt2d p = boundPoints.back();
|
|||
|
|
|||
|
if(p.Distance(p1) > Precision::Confusion() && pp4.Distance(p1) > Precision::Confusion())
|
|||
|
{
|
|||
|
if(p1.X() > p.X())
|
|||
|
{
|
|||
|
boundPoints.push_back(p1);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
boundPoints.pop_back();
|
|||
|
boundPoints.push_back(p1);
|
|||
|
boundPoints.push_back(p);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if(abs(p2.Y() - boundPoints.back().Y()) < Precision::Confusion())
|
|||
|
{
|
|||
|
gp_Pnt2d p = boundPoints.back();
|
|||
|
|
|||
|
if(p.Distance(p2) > Precision::Confusion() && pp4.Distance(p2) > Precision::Confusion())
|
|||
|
{
|
|||
|
if(p2.X() > p.X())
|
|||
|
{
|
|||
|
boundPoints.push_back(p2);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
boundPoints.pop_back();
|
|||
|
boundPoints.push_back(p2);
|
|||
|
boundPoints.push_back(p);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
boundPoints.push_back(gp_Pnt2d(rw, bh));
|
|||
|
if(abs(p1.X() - boundPoints.back().X()) < Precision::Confusion())
|
|||
|
{
|
|||
|
gp_Pnt2d p = boundPoints.back();
|
|||
|
|
|||
|
if(p.Distance(p1) > Precision::Confusion() && pp1.Distance(p1) > Precision::Confusion())
|
|||
|
{
|
|||
|
if(p1.Y() > p.Y())
|
|||
|
{
|
|||
|
boundPoints.push_back(p1);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
boundPoints.pop_back();
|
|||
|
boundPoints.push_back(p1);
|
|||
|
boundPoints.push_back(p);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if(abs(p2.X() - boundPoints.back().X()) < Precision::Confusion())
|
|||
|
{
|
|||
|
gp_Pnt2d p = boundPoints.back();
|
|||
|
|
|||
|
if(p.Distance(p2) > Precision::Confusion() && pp1.Distance(p2) > Precision::Confusion())
|
|||
|
{
|
|||
|
if(p2.Y() > p.Y())
|
|||
|
{
|
|||
|
boundPoints.push_back(p2);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
boundPoints.pop_back();
|
|||
|
boundPoints.push_back(p2);
|
|||
|
boundPoints.push_back(p);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
int index1,index2;
|
|||
|
for(int i = 0; i < boundPoints.size(); i++)
|
|||
|
{
|
|||
|
if(boundPoints[i].Distance(p1) < Precision::Confusion())
|
|||
|
{
|
|||
|
index1 = i;
|
|||
|
}
|
|||
|
if(boundPoints[i].Distance(p2) < Precision::Confusion())
|
|||
|
{
|
|||
|
index2 = i;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
for(int i = boundIndex[0]; i != boundIndex[1]; i = (i + 1) % pSet.size())
|
|||
|
{
|
|||
|
result.push_back(pSet[i]);
|
|||
|
}
|
|||
|
|
|||
|
for(int i = index2; i != index1; i = (i + 1) % boundPoints.size())
|
|||
|
{
|
|||
|
result.push_back(boundPoints[i]);
|
|||
|
}
|
|||
|
|
|||
|
result.push_back(p1);
|
|||
|
//
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
vector<gp_Pnt2d> OCCCabin_Bool::ConvertPoint2dSet2(double* values, double width, double height) //20170601 by czb
|
|||
|
{
|
|||
|
vector<gp_Pnt2d> pSet, result;
|
|||
|
|
|||
|
|
|||
|
double lw = this->hullMinY;
|
|||
|
double rw = this->hullMaxY;
|
|||
|
double th = this->hullMaxZ;
|
|||
|
double bh = this->hullMinZ;
|
|||
|
double len = (rw-lw + th-bh);
|
|||
|
|
|||
|
int count = 0;
|
|||
|
vector<int> indexs;
|
|||
|
vector<int> boundIndex;
|
|||
|
vector<TopoDS_Edge> edgeSet;
|
|||
|
for(double* val = values; *val < 999.9; val++,count++)
|
|||
|
{
|
|||
|
double dy = (*val);
|
|||
|
double dz = (*(++val));
|
|||
|
|
|||
|
int y = (int)dy;
|
|||
|
int z = (int)dz;
|
|||
|
bool isBound = false;
|
|||
|
if(y == 777) // Y+,见Statics.convertSpecToDigital
|
|||
|
{
|
|||
|
dy = rw;
|
|||
|
isBound = true;
|
|||
|
|
|||
|
}
|
|||
|
else if(y == -777) // Y-
|
|||
|
{
|
|||
|
dy = lw;
|
|||
|
isBound = true;
|
|||
|
}
|
|||
|
|
|||
|
if(z == 888) // Z+
|
|||
|
{
|
|||
|
dz = th;
|
|||
|
isBound = true;
|
|||
|
}
|
|||
|
else if(z == -888) //Z-
|
|||
|
{
|
|||
|
dz = bh;
|
|||
|
isBound = true;
|
|||
|
}
|
|||
|
|
|||
|
if(abs(y) == 999) // P+ P-
|
|||
|
{
|
|||
|
indexs.push_back(count);
|
|||
|
isBound = true;
|
|||
|
}
|
|||
|
pSet.push_back(gp_Pnt2d(dy, dz));
|
|||
|
|
|||
|
if(isBound)
|
|||
|
{
|
|||
|
boundIndex.push_back(count);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//角度点处理 P
|
|||
|
for(int i = 0; i < indexs.size(); i++)
|
|||
|
{
|
|||
|
int index = indexs[i];
|
|||
|
|
|||
|
gp_Pnt2d& p = pSet[index];
|
|||
|
gp_Pnt2d temp;
|
|||
|
|
|||
|
if(p.X() > 0)
|
|||
|
{
|
|||
|
temp = pSet[(index + 1) % count];
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
temp = pSet[(index - 1+ count) % count];
|
|||
|
}
|
|||
|
|
|||
|
double angle = (p.Y() / 360.0) * 2 * PI;
|
|||
|
|
|||
|
double y = cos(angle) * len + temp.X();
|
|||
|
double z = sin(angle) * len + temp.Y();
|
|||
|
|
|||
|
if(y > rw)
|
|||
|
{
|
|||
|
y = rw;
|
|||
|
z = tan(angle) * (y - temp.X()) + temp.Y();
|
|||
|
if(z > th)
|
|||
|
{
|
|||
|
z = th;
|
|||
|
y = 1 / tan(angle) * (z - temp.Y()) + temp.X();
|
|||
|
}
|
|||
|
else if(z < bh)
|
|||
|
{
|
|||
|
z = bh;
|
|||
|
y = 1 / tan(angle) * (z - temp.Y()) + temp.X();
|
|||
|
}
|
|||
|
}
|
|||
|
else if(y < lw)
|
|||
|
{
|
|||
|
y = lw;
|
|||
|
z = tan(angle) * (y - temp.X()) + temp.Y();
|
|||
|
if(z > th)
|
|||
|
{
|
|||
|
z = th;
|
|||
|
y = 1 / tan(angle) * (z - temp.Y()) + temp.X();
|
|||
|
}
|
|||
|
else if(z < bh)
|
|||
|
{
|
|||
|
z = bh;
|
|||
|
y = 1 / tan(angle) * (z - temp.Y()) + temp.X();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if(z > th)
|
|||
|
{
|
|||
|
z = th;
|
|||
|
y = 1/ tan(angle) * (z - temp.Y()) + temp.X();
|
|||
|
if(y > rw)
|
|||
|
{
|
|||
|
y = rw;
|
|||
|
z = tan(angle) * (y - temp.X()) + temp.Y();
|
|||
|
}
|
|||
|
else if(y < lw)
|
|||
|
{
|
|||
|
y = lw;
|
|||
|
z = tan(angle) * (y - temp.X()) + temp.Y();
|
|||
|
}
|
|||
|
}
|
|||
|
else if(z < bh)
|
|||
|
{
|
|||
|
z = bh;
|
|||
|
y = 1/ tan(angle) * (z - temp.Y()) + temp.X();
|
|||
|
if(y > rw)
|
|||
|
{
|
|||
|
y = rw;
|
|||
|
z = tan(angle) * (y - temp.X()) + temp.Y();
|
|||
|
}
|
|||
|
else if(y < lw)
|
|||
|
{
|
|||
|
y = lw;
|
|||
|
z = tan(angle) * (y - temp.X()) + temp.Y();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
p.SetX(y);
|
|||
|
p.SetY(z);
|
|||
|
}
|
|||
|
|
|||
|
return pSet;
|
|||
|
|
|||
|
/*
|
|||
|
//所有点必须在框内
|
|||
|
for(int i = 0; i < pSet.size(); i++)
|
|||
|
{
|
|||
|
if(abs(pSet[i].X())>rw || abs(pSet[i].Y()) > th)
|
|||
|
{
|
|||
|
return result;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//调整顺序 保证特殊点在首尾
|
|||
|
pSet = Reorder(pSet, boundIndex);
|
|||
|
if(boundIndex.size() == 2)
|
|||
|
{
|
|||
|
boundIndex.clear();
|
|||
|
boundIndex.push_back(0);
|
|||
|
boundIndex.push_back(pSet.size() - 1);
|
|||
|
}
|
|||
|
//调整顺序
|
|||
|
if(boundIndex.size() < 2 || pSet.size() == 2)
|
|||
|
{
|
|||
|
result = pSet;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//判断是否相交
|
|||
|
TopoDS_Edge edge1, edge2;
|
|||
|
int index,nextInd;
|
|||
|
|
|||
|
if(boundIndex[0] == 0 || (boundIndex[0] + pSet.size() - 1) % pSet.size() == boundIndex[1])
|
|||
|
{
|
|||
|
index = (boundIndex[0] + 1) % pSet.size();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
index = (boundIndex[0] + pSet.size() - 1) % pSet.size();
|
|||
|
}
|
|||
|
edge1 = BRepBuilderAPI_MakeEdge(gp_Pnt(0, pSet[boundIndex[0]].X(),pSet[boundIndex[0]].Y()),gp_Pnt(0,pSet[index].X(),pSet[index].Y()));
|
|||
|
|
|||
|
if(boundIndex[1] == 0 || (boundIndex[1] + pSet.size() - 1) % pSet.size() == boundIndex[0])
|
|||
|
{
|
|||
|
index = (boundIndex[1] + 1) % pSet.size();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
index = (boundIndex[1] + pSet.size() - 1) % pSet.size();
|
|||
|
}
|
|||
|
edge2 = BRepBuilderAPI_MakeEdge(gp_Pnt(0, pSet[boundIndex[1]].X(),pSet[boundIndex[1]].Y()),gp_Pnt(0,pSet[index].X(),pSet[index].Y()));
|
|||
|
|
|||
|
BaseAlgo algo;
|
|||
|
if(!algo.IsParallel(edge1, edge2) && pSet.size() > 3) //三个点时 会出现交点特征点的情况
|
|||
|
{
|
|||
|
BRepExtrema_DistShapeShape dis(edge1, edge2);
|
|||
|
dis.Perform();
|
|||
|
if(dis.Value() < Precision::Confusion())
|
|||
|
{
|
|||
|
gp_Pnt p = dis.PointOnShape1(1);
|
|||
|
|
|||
|
gp_Pnt2d p2d(p.Y(), p.Z());
|
|||
|
|
|||
|
result.push_back(p2d);
|
|||
|
for(int i = (boundIndex[0] + 1) % pSet.size(); i != boundIndex[1]; i = (i + 1) % pSet.size())
|
|||
|
{
|
|||
|
result.push_back(pSet[i]);
|
|||
|
}
|
|||
|
result.push_back(p2d);
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
}
|
|||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
|||
|
|
|||
|
vector<gp_Pnt2d> boundPoints;
|
|||
|
gp_Pnt2d p1 = pSet[boundIndex[0]];
|
|||
|
gp_Pnt2d p2 = pSet[boundIndex[1]];
|
|||
|
gp_Pnt2d pp1 = gp_Pnt2d(rw, th);
|
|||
|
gp_Pnt2d pp2 = gp_Pnt2d(lw, th);
|
|||
|
gp_Pnt2d pp3 = gp_Pnt2d(lw, bh);
|
|||
|
gp_Pnt2d pp4 = gp_Pnt2d(rw, bh);
|
|||
|
|
|||
|
boundPoints.push_back(gp_Pnt2d(rw, th));
|
|||
|
if(abs(p1.Y() - boundPoints.back().Y()) < Precision::Confusion())
|
|||
|
{
|
|||
|
gp_Pnt2d p = boundPoints.back();
|
|||
|
|
|||
|
if(p.Distance(p1) > Precision::Confusion() && pp2.Distance(p1) > Precision::Confusion())
|
|||
|
{
|
|||
|
if(p1.X() < p.X())
|
|||
|
{
|
|||
|
boundPoints.push_back(p1);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
boundPoints.pop_back();
|
|||
|
boundPoints.push_back(p1);
|
|||
|
boundPoints.push_back(p);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if(abs(p2.Y() - boundPoints.back().Y()) < Precision::Confusion())
|
|||
|
{
|
|||
|
gp_Pnt2d p = boundPoints.back();
|
|||
|
|
|||
|
if(p.Distance(p2) > Precision::Confusion() && pp2.Distance(p2) > Precision::Confusion())
|
|||
|
{
|
|||
|
if(p2.X() < p.X())
|
|||
|
{
|
|||
|
boundPoints.push_back(p2);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
boundPoints.pop_back();
|
|||
|
boundPoints.push_back(p2);
|
|||
|
boundPoints.push_back(p);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
boundPoints.push_back(gp_Pnt2d(lw, th));
|
|||
|
if(abs(p1.X() - boundPoints.back().X()) < Precision::Confusion())
|
|||
|
{
|
|||
|
gp_Pnt2d p = boundPoints.back();
|
|||
|
|
|||
|
if(p.Distance(p1) > Precision::Confusion() && pp3.Distance(p1) > Precision::Confusion())
|
|||
|
{
|
|||
|
if(p1.Y() < p.Y())
|
|||
|
{
|
|||
|
boundPoints.push_back(p1);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
boundPoints.pop_back();
|
|||
|
boundPoints.push_back(p1);
|
|||
|
boundPoints.push_back(p);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if(abs(p2.X() - boundPoints.back().X()) < Precision::Confusion())
|
|||
|
{
|
|||
|
gp_Pnt2d p = boundPoints.back();
|
|||
|
|
|||
|
if(p.Distance(p2) > Precision::Confusion() && pp3.Distance(p2) > Precision::Confusion())
|
|||
|
{
|
|||
|
if(p2.Y() < p.Y())
|
|||
|
{
|
|||
|
boundPoints.push_back(p2);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
boundPoints.pop_back();
|
|||
|
boundPoints.push_back(p2);
|
|||
|
boundPoints.push_back(p);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
boundPoints.push_back(gp_Pnt2d(lw, bh));
|
|||
|
if(abs(p1.Y() - boundPoints.back().Y()) < Precision::Confusion())
|
|||
|
{
|
|||
|
gp_Pnt2d p = boundPoints.back();
|
|||
|
|
|||
|
if(p.Distance(p1) > Precision::Confusion() && pp4.Distance(p1) > Precision::Confusion())
|
|||
|
{
|
|||
|
if(p1.X() > p.X())
|
|||
|
{
|
|||
|
boundPoints.push_back(p1);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
boundPoints.pop_back();
|
|||
|
boundPoints.push_back(p1);
|
|||
|
boundPoints.push_back(p);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if(abs(p2.Y() - boundPoints.back().Y()) < Precision::Confusion())
|
|||
|
{
|
|||
|
gp_Pnt2d p = boundPoints.back();
|
|||
|
|
|||
|
if(p.Distance(p2) > Precision::Confusion() && pp4.Distance(p2) > Precision::Confusion())
|
|||
|
{
|
|||
|
if(p2.X() > p.X())
|
|||
|
{
|
|||
|
boundPoints.push_back(p2);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
boundPoints.pop_back();
|
|||
|
boundPoints.push_back(p2);
|
|||
|
boundPoints.push_back(p);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
boundPoints.push_back(gp_Pnt2d(rw, bh));
|
|||
|
if(abs(p1.X() - boundPoints.back().X()) < Precision::Confusion())
|
|||
|
{
|
|||
|
gp_Pnt2d p = boundPoints.back();
|
|||
|
|
|||
|
if(p.Distance(p1) > Precision::Confusion() && pp1.Distance(p1) > Precision::Confusion())
|
|||
|
{
|
|||
|
if(p1.Y() > p.Y())
|
|||
|
{
|
|||
|
boundPoints.push_back(p1);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
boundPoints.pop_back();
|
|||
|
boundPoints.push_back(p1);
|
|||
|
boundPoints.push_back(p);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if(abs(p2.X() - boundPoints.back().X()) < Precision::Confusion())
|
|||
|
{
|
|||
|
gp_Pnt2d p = boundPoints.back();
|
|||
|
|
|||
|
if(p.Distance(p2) > Precision::Confusion() && pp1.Distance(p2) > Precision::Confusion())
|
|||
|
{
|
|||
|
if(p2.Y() > p.Y())
|
|||
|
{
|
|||
|
boundPoints.push_back(p2);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
boundPoints.pop_back();
|
|||
|
boundPoints.push_back(p2);
|
|||
|
boundPoints.push_back(p);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
int index1,index2;
|
|||
|
for(int i = 0; i < boundPoints.size(); i++)
|
|||
|
{
|
|||
|
if(boundPoints[i].Distance(p1) < Precision::Confusion())
|
|||
|
{
|
|||
|
index1 = i;
|
|||
|
}
|
|||
|
if(boundPoints[i].Distance(p2) < Precision::Confusion())
|
|||
|
{
|
|||
|
index2 = i;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
for(int i = boundIndex[0]; i != boundIndex[1]; i = (i + 1) % pSet.size())
|
|||
|
{
|
|||
|
result.push_back(pSet[i]);
|
|||
|
}
|
|||
|
|
|||
|
for(int i = index2; i != index1; i = (i + 1) % boundPoints.size())
|
|||
|
{
|
|||
|
result.push_back(boundPoints[i]);
|
|||
|
}
|
|||
|
|
|||
|
result.push_back(p1);
|
|||
|
//
|
|||
|
|
|||
|
return result;*/
|
|||
|
}
|
|||
|
|
|||
|
TopoDS_Shell OCCCabin_Bool::CreateSplitShell(vector<gp_Pnt> pSet1, vector<gp_Pnt> pSet2)
|
|||
|
{
|
|||
|
TopoDS_Shell shell;
|
|||
|
OCCLib occLib;
|
|||
|
vector<TopoDS_Shape> shapeSet;
|
|||
|
BRepOffsetAPI_Sewing sew;
|
|||
|
|
|||
|
if(pSet2.size() != pSet1.size() || pSet1.size() == 0)
|
|||
|
{
|
|||
|
return shell;
|
|||
|
}
|
|||
|
|
|||
|
for(int i = 0; i < pSet1.size() - 1; i++)
|
|||
|
{
|
|||
|
int j = (i+1) % pSet1.size();
|
|||
|
TopoDS_Face face = occLib.CreateFaceByPoints(pSet1[i], pSet1[j], pSet2[j], pSet2[i]);
|
|||
|
shapeSet.push_back(face);
|
|||
|
//sew.Add(face);
|
|||
|
}
|
|||
|
//sew.Perform();
|
|||
|
//shell = TopoDS::Shell(sew.SewedShape());
|
|||
|
shell = occLib.SewShell(shapeSet);
|
|||
|
//throw shell;
|
|||
|
return shell;
|
|||
|
}
|
|||
|
|
|||
|
TopoDS_Shell OCCCabin_Bool::CreateShell(vector<gp_Pnt> pSet1, vector<gp_Pnt> pSet2)
|
|||
|
{
|
|||
|
TopoDS_Shell shell;
|
|||
|
OCCLib occLib;
|
|||
|
vector<TopoDS_Shape> shapeSet;
|
|||
|
BRepOffsetAPI_Sewing sew;
|
|||
|
|
|||
|
if(pSet2.size() != pSet1.size() || pSet1.size() == 0)
|
|||
|
{
|
|||
|
return shell;
|
|||
|
}
|
|||
|
|
|||
|
TopoDS_Face face;
|
|||
|
face = occLib.CreatePlaneByPoints(pSet1,Standard_True);//首端面方向反向
|
|||
|
shapeSet.push_back(face);
|
|||
|
face = occLib.CreatePlaneByPoints(pSet2);
|
|||
|
shapeSet.push_back(face);
|
|||
|
|
|||
|
for(int i = 0; i < pSet1.size() - 1; i++)
|
|||
|
{
|
|||
|
int j = (i+1) % pSet1.size();
|
|||
|
face = occLib.CreateFaceByPoints(pSet1[i], pSet1[j], pSet2[j], pSet2[i]);
|
|||
|
shapeSet.push_back(face);
|
|||
|
//sew.Add(face);
|
|||
|
}
|
|||
|
//sew.Perform();
|
|||
|
//shell = TopoDS::Shell(sew.SewedShape());
|
|||
|
shell = occLib.SewShell(shapeSet);
|
|||
|
//throw shell;
|
|||
|
return shell;
|
|||
|
}
|
|||
|
|
|||
|
vector<gp_Pnt> OCCCabin_Bool::CreatePointSet(vector<gp_Pnt2d> p2dSet, double d)
|
|||
|
{
|
|||
|
vector<gp_Pnt> pSet;
|
|||
|
if(p2dSet.size() == 2)
|
|||
|
{
|
|||
|
//pSet.push_back(gp_Pnt(d, p2dSet[0].X(), p2dSet[0].Y()));
|
|||
|
//pSet.push_back(gp_Pnt(d, p2dSet[0].X(), p2dSet[1].Y()));
|
|||
|
//pSet.push_back(gp_Pnt(d, p2dSet[1].X(), p2dSet[1].Y()));
|
|||
|
//pSet.push_back(gp_Pnt(d, p2dSet[1].X(), p2dSet[0].Y()));
|
|||
|
//pSet.push_back(gp_Pnt(d, p2dSet[0].X(), p2dSet[0].Y()));
|
|||
|
|
|||
|
double xmin = p2dSet[0].X() > p2dSet[1].X() ? p2dSet[1].X() : p2dSet[0].X();
|
|||
|
double xmax = p2dSet[0].X() > p2dSet[1].X() ? p2dSet[0].X() : p2dSet[1].X();
|
|||
|
double ymin = p2dSet[0].Y() > p2dSet[1].Y() ? p2dSet[1].Y() : p2dSet[0].Y();
|
|||
|
double ymax = p2dSet[0].Y() > p2dSet[1].Y() ? p2dSet[0].Y() : p2dSet[1].Y();
|
|||
|
|
|||
|
switch(dir)
|
|||
|
{
|
|||
|
case DIR_X:
|
|||
|
pSet.push_back(gp_Pnt(d, xmax, ymax));
|
|||
|
pSet.push_back(gp_Pnt(d, xmin, ymax));
|
|||
|
pSet.push_back(gp_Pnt(d, xmin, ymin));
|
|||
|
pSet.push_back(gp_Pnt(d, xmax, ymin));
|
|||
|
pSet.push_back(gp_Pnt(d, xmax, ymax));
|
|||
|
break;
|
|||
|
case DIR_Y:
|
|||
|
pSet.push_back(gp_Pnt(xmax, d, ymax));
|
|||
|
pSet.push_back(gp_Pnt(xmin, d, ymax));
|
|||
|
pSet.push_back(gp_Pnt(xmin, d, ymin));
|
|||
|
pSet.push_back(gp_Pnt(xmax, d, ymin));
|
|||
|
pSet.push_back(gp_Pnt(xmax, d, ymax));
|
|||
|
break;
|
|||
|
case DIR_Z:
|
|||
|
pSet.push_back(gp_Pnt(xmax, ymax, d));
|
|||
|
pSet.push_back(gp_Pnt(xmin, ymax, d));
|
|||
|
pSet.push_back(gp_Pnt(xmin, ymin, d));
|
|||
|
pSet.push_back(gp_Pnt(xmax, ymin, d));
|
|||
|
pSet.push_back(gp_Pnt(xmax, ymax, d));
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
for(int i = 0; i < p2dSet.size(); i++)
|
|||
|
{
|
|||
|
switch(dir)
|
|||
|
{
|
|||
|
case DIR_X:
|
|||
|
pSet.push_back(gp_Pnt(d, p2dSet[i].X(), p2dSet[i].Y()));
|
|||
|
break;
|
|||
|
case DIR_Y:
|
|||
|
pSet.push_back(gp_Pnt(p2dSet[i].X(), d, p2dSet[i].Y()));
|
|||
|
break;
|
|||
|
case DIR_Z:
|
|||
|
pSet.push_back(gp_Pnt(p2dSet[i].X(), p2dSet[i].Y(), d));
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return pSet;
|
|||
|
}
|
|||
|
|
|||
|
TopoDS_Face OCCCabin_Bool::CutEndFace(TopoDS_Face face, TopoDS_Shape shell, vector<gp_Pnt> pSet, bool isLeft)
|
|||
|
{
|
|||
|
TopoDS_Face TopoShape;
|
|||
|
|
|||
|
std::vector<TopoDS_Edge> faceBorder; // 面的边界
|
|||
|
for(TopExp_Explorer ex_face(face, TopAbs_EDGE);ex_face.More();ex_face.Next())
|
|||
|
{
|
|||
|
TopoDS_Edge edge = TopoDS::Edge(ex_face.Current());
|
|||
|
gp_Pnt p1,p2;
|
|||
|
GetEdgeStartEndPoint(edge,p1,p2);
|
|||
|
if(p1.Distance(p2) < Precision::Confusion())
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
faceBorder.push_back(edge);
|
|||
|
}
|
|||
|
|
|||
|
BRepAlgoAPI_Section asect(face,shell,Standard_False);
|
|||
|
asect.ComputePCurveOn1(Standard_True);
|
|||
|
asect.Approximation(Standard_True);
|
|||
|
asect.Build();
|
|||
|
|
|||
|
if(!asect.IsDone())
|
|||
|
{
|
|||
|
throw face;
|
|||
|
}
|
|||
|
TopoDS_Shape splitResult = asect.Shape();
|
|||
|
|
|||
|
BRepFeat_SplitShape asplit(face);
|
|||
|
|
|||
|
int count = 0;
|
|||
|
for (TopExp_Explorer Ex(splitResult,TopAbs_EDGE); Ex.More(); Ex.Next())
|
|||
|
{
|
|||
|
TopoDS_Edge anEdge =TopoDS::Edge(Ex.Current());
|
|||
|
gp_Pnt p1,p2;
|
|||
|
GetEdgeStartEndPoint(anEdge, p1,p2);
|
|||
|
|
|||
|
|
|||
|
bool isCoincide = false;
|
|||
|
for(int i = 0; i < faceBorder.size(); i++)
|
|||
|
{
|
|||
|
if(CheckTwoEdgeOverlapByLinePointProject(anEdge,faceBorder[i]))
|
|||
|
{
|
|||
|
isCoincide = true;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if(isCoincide)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
//bool isReverse = true;
|
|||
|
//for(int j = 0; j < pSet.size(); j++)
|
|||
|
//{
|
|||
|
// if(pSet[j].Distance(p1) < Precision::Confusion())
|
|||
|
// {
|
|||
|
// if(pSet[( j + 1) % pSet.size()].Distance(p2) < Precision::Confusion())
|
|||
|
// {
|
|||
|
// isReverse = false;
|
|||
|
// break;
|
|||
|
// }
|
|||
|
// }
|
|||
|
//}
|
|||
|
|
|||
|
//BaseAlgo algo;
|
|||
|
//algo.PutPCurve(anEdge, face);
|
|||
|
//if(isReverse ^ isLeft)
|
|||
|
//{
|
|||
|
// anEdge.Reverse();
|
|||
|
//}
|
|||
|
|
|||
|
|
|||
|
BaseAlgo algo;
|
|||
|
algo.PutPCurve(anEdge, face);
|
|||
|
if(!isLeft)
|
|||
|
{
|
|||
|
anEdge.Orientation(TopAbs_REVERSED);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
anEdge.Orientation(TopAbs_FORWARD);
|
|||
|
}
|
|||
|
|
|||
|
asplit.Add(anEdge, face);
|
|||
|
count++;
|
|||
|
}
|
|||
|
if(count == 0)
|
|||
|
{
|
|||
|
return face;
|
|||
|
}
|
|||
|
TopTools_ListIteratorOfListOfShape theList;
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
asplit.Build();
|
|||
|
}
|
|||
|
catch (Standard_Failure e)
|
|||
|
{
|
|||
|
throw face;
|
|||
|
}
|
|||
|
theList = asplit.Left();
|
|||
|
|
|||
|
for (;theList.More();theList.Next())
|
|||
|
{
|
|||
|
TopoShape = TopoDS::Face(theList.Value());
|
|||
|
}
|
|||
|
|
|||
|
return TopoShape;
|
|||
|
}
|
|||
|
|
|||
|
TopoDS_Shape OCCCabin_Bool::GetResult()
|
|||
|
{
|
|||
|
return this->result;
|
|||
|
}
|
|||
|
|
|||
|
vector<gp_Pnt2d> OCCCabin_Bool::Reorder( vector<gp_Pnt2d> pSet, vector<int> index )
|
|||
|
{
|
|||
|
if(index.size() == 0 )
|
|||
|
{
|
|||
|
return pSet;
|
|||
|
}
|
|||
|
|
|||
|
if(index.size() == 1) //不保存这种情况
|
|||
|
{
|
|||
|
return pSet;
|
|||
|
}
|
|||
|
|
|||
|
if(index.size() > 2) //不保存这种情况
|
|||
|
{
|
|||
|
return pSet;
|
|||
|
}
|
|||
|
|
|||
|
int index1 = index[0];
|
|||
|
int index2 = index[1];
|
|||
|
|
|||
|
if(index1 == 0 && index2 == pSet.size() - 1)
|
|||
|
{
|
|||
|
return pSet;
|
|||
|
}
|
|||
|
|
|||
|
if(index2 != (index1+1)%pSet.size()) //不相邻 不保存这种情况
|
|||
|
{
|
|||
|
return pSet;
|
|||
|
}
|
|||
|
|
|||
|
vector<gp_Pnt2d> result;
|
|||
|
for(int i = 0; i < pSet.size(); i++)
|
|||
|
{
|
|||
|
result.push_back(pSet[(i + index2)%pSet.size()]);
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|