1165 lines
24 KiB
C++
1165 lines
24 KiB
C++
|
#include "Stdafx.h"
|
||
|
#include "CutSurfaceAlgo.h"
|
||
|
#include "SplitAllInsectionCurves.h"
|
||
|
#include "TopExp_Explorer.hxx"
|
||
|
#include "GProp_GProps.hxx"
|
||
|
#include "TopoDS_Face.hxx"
|
||
|
#include "BRepGProp.hxx"
|
||
|
#include "BRepAlgoAPI_Section.hxx"
|
||
|
#include "list"
|
||
|
|
||
|
//#include "BOPTools_Tools2D.hxx" //XUEFENG DELETE 202009
|
||
|
|
||
|
#include "Bnd_Box.hxx"
|
||
|
|
||
|
|
||
|
using namespace std;
|
||
|
|
||
|
CutSurfaceAlgo::CutSurfaceAlgo(void)
|
||
|
{
|
||
|
isDone = false;
|
||
|
}
|
||
|
|
||
|
CutSurfaceAlgo::CutSurfaceAlgo( TopoDS_Shape s1, TopoDS_Shape s2)
|
||
|
{
|
||
|
shell1 = s1;
|
||
|
shell2 = s2;
|
||
|
isDone = false;
|
||
|
this->cutPoint = gp_Pnt(0,0,0);
|
||
|
}
|
||
|
|
||
|
bool CutSurfaceAlgo::IsDone()
|
||
|
{
|
||
|
return isDone;
|
||
|
}
|
||
|
|
||
|
TopoDS_Shape CutSurfaceAlgo::GetResult()
|
||
|
{
|
||
|
TopoDS_Shape shape;
|
||
|
if(isDone)
|
||
|
{
|
||
|
shape = this->result;
|
||
|
}
|
||
|
return shape;
|
||
|
}
|
||
|
|
||
|
void CutSurfaceAlgo::Perform()
|
||
|
{
|
||
|
vector<TopoDS_Shell> shellSet;
|
||
|
TrimSurfaceTranslateInsec(shellSet);
|
||
|
//result = sectionWire;
|
||
|
//return ;
|
||
|
//形心法判断去留,失败
|
||
|
//double distanceMax= -1;
|
||
|
//int index = -1;
|
||
|
//
|
||
|
//for(int i = 0; i < (int)shellSet.size(); i++)
|
||
|
//{
|
||
|
// TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(cutPoint).Vertex();
|
||
|
// BRepExtrema_DistShapeShape dis(v, shellSet[i]);
|
||
|
// double distance = dis.Value();
|
||
|
// if(distance > distanceMax)
|
||
|
// {
|
||
|
// index = i;
|
||
|
// distanceMax = distance;
|
||
|
// }
|
||
|
//}
|
||
|
//if(index > -1)
|
||
|
//{
|
||
|
// this->result = shellSet[index];
|
||
|
// isDone = true;
|
||
|
//}
|
||
|
////static int ii = 0;
|
||
|
////this->result = shellSet[ii++];
|
||
|
|
||
|
double distanceMin= 1000000;
|
||
|
int index = -1;
|
||
|
vector<TopoDS_Shell> shells;
|
||
|
for(int i = 0; i < (int)shellSet.size(); i++)
|
||
|
{
|
||
|
bool isSave = true;
|
||
|
GProp_GProps System;
|
||
|
gp_Pnt G1;
|
||
|
BRepGProp::SurfaceProperties(shellSet[i],System);
|
||
|
G1 = System.CentreOfMass ();
|
||
|
|
||
|
BRepExtrema_DistShapeShape dis(BRepBuilderAPI_MakeVertex(this->cutPoint), shellSet[i]);
|
||
|
dis.Perform();
|
||
|
double distance = dis.Value();
|
||
|
if(distance < distanceMin)
|
||
|
{
|
||
|
index = i;
|
||
|
distanceMin = distance;
|
||
|
}
|
||
|
|
||
|
if(distance < Precision::Confusion())
|
||
|
{
|
||
|
shells.push_back(shellSet[i]);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
////获取判断点集合,体中心和边的顶点
|
||
|
//vector<gp_Pnt> pSet;
|
||
|
//pSet.push_back(G1);
|
||
|
|
||
|
//for(TopExp_Explorer ex(shellSet[i], TopAbs_EDGE); ex.More();ex.Next())
|
||
|
//{
|
||
|
// TopoDS_Edge edge = TopoDS::Edge(ex.Current());
|
||
|
// gp_Pnt p1, p2;
|
||
|
// GetEdgeStartEndPoint(edge, p1,p2);
|
||
|
// pSet.push_back(p1);
|
||
|
// pSet.push_back(p2);
|
||
|
//}
|
||
|
|
||
|
|
||
|
//for(int j = 0; j < pSet.size(); j++)
|
||
|
//{
|
||
|
// TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(this->cutPoint, pSet[j]);
|
||
|
// BRepExtrema_DistShapeShape inter(edge,this->shell2);
|
||
|
// inter.Perform();
|
||
|
// //有交点
|
||
|
// if(inter.Value() < Precision::Confusion() * 100)
|
||
|
// {
|
||
|
// gp_Pnt p = inter.PointOnShape1(1);
|
||
|
// //交点是线的端点,正常线
|
||
|
// if(p.Distance(pSet[j]) < Precision::Confusion() * 100)
|
||
|
// {
|
||
|
// continue;
|
||
|
// }
|
||
|
// isSave = false;
|
||
|
// break;
|
||
|
// }
|
||
|
//}
|
||
|
|
||
|
//if(isSave)
|
||
|
//{
|
||
|
// shells.push_back(shellSet[i]);
|
||
|
//}
|
||
|
}//形心法判断去留,失败
|
||
|
|
||
|
if(shells.size() == 0)
|
||
|
{
|
||
|
if(index > -1)
|
||
|
{
|
||
|
shells.push_back(shellSet[index]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
TopoDS_Compound c;
|
||
|
BRep_Builder b;
|
||
|
b.MakeCompound(c);
|
||
|
for(int i = 0; i < shells.size(); i++)
|
||
|
{
|
||
|
b.Add(c, shells[i]);
|
||
|
}
|
||
|
this->result = c;
|
||
|
isDone = true;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
void CutSurfaceAlgo::SetCutPoint(gp_Pnt p)
|
||
|
{
|
||
|
this->cutPoint = p;
|
||
|
}
|
||
|
|
||
|
void CutSurfaceAlgo::TrimSurfaceTranslateInsec(vector<TopoDS_Shell>& shellSet)
|
||
|
{
|
||
|
TrimSurfaceTranslateInsec(shell1, shell2, shellSet);
|
||
|
}
|
||
|
|
||
|
void CutSurfaceAlgo::TrimSurfaceTranslateInsec(TopoDS_Shape TopoSrf,TopoDS_Shape TopoTemp, vector<TopoDS_Shell>& shellSet)
|
||
|
{
|
||
|
TopoDS_Shape TopoShape;
|
||
|
|
||
|
std::map<int, TopoDS_Face> faceSet;
|
||
|
TopoDS_Compound compLine;
|
||
|
|
||
|
BRep_Builder builder,builder1;
|
||
|
builder.MakeCompound(compLine);
|
||
|
|
||
|
int faceCount = 0;
|
||
|
int faceIndex = 0;
|
||
|
|
||
|
vector<TopoDS_Face> faces;
|
||
|
|
||
|
if(TopoSrf.ShapeType() == TopAbs_FACE)
|
||
|
{
|
||
|
faces.push_back(TopoDS::Face(TopoSrf));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for(TopExp_Explorer ex(TopoSrf,TopAbs_FACE); ex.More(); ex.Next())
|
||
|
{
|
||
|
faces.push_back(TopoDS::Face(ex.Current()));
|
||
|
}
|
||
|
}
|
||
|
for(int m = 0; m < faces.size(); m++)
|
||
|
{
|
||
|
faceIndex++;
|
||
|
//if(m!=194)
|
||
|
//{
|
||
|
// continue;
|
||
|
//}
|
||
|
TopoDS_Face Face = faces[m];
|
||
|
|
||
|
list<TopoDS_Face> listFaces;
|
||
|
listFaces.push_back(Face);
|
||
|
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
TopoDS_Shape splitResult;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
BRepAlgoAPI_Section asect(Face,TopoTemp,Standard_False);
|
||
|
asect.ComputePCurveOn1(Standard_True);
|
||
|
//asect.ComputePCurveOn2(Standard_True);
|
||
|
asect.Approximation(Standard_True);
|
||
|
asect.Build();
|
||
|
|
||
|
if(!asect.IsDone())
|
||
|
{
|
||
|
//faceSet.insert(make_pair(faceSet.size(), face));
|
||
|
//continue;
|
||
|
throw Face;
|
||
|
}
|
||
|
splitResult = asect.Shape();
|
||
|
//throw splitResult;
|
||
|
}
|
||
|
catch (Standard_Failure)
|
||
|
{
|
||
|
TopoDS_Compound c;
|
||
|
TopoDS_Shell s1, s2;
|
||
|
BRep_Builder b;
|
||
|
|
||
|
b.MakeShell(s1);
|
||
|
b.Add(s1, Face);
|
||
|
|
||
|
if(TopoTemp.ShapeType() == TopAbs_FACE)
|
||
|
{
|
||
|
b.MakeShell(s2);
|
||
|
b.Add(s2, TopoTemp);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
s2 = TopoDS::Shell(TopoTemp);
|
||
|
}
|
||
|
|
||
|
b.MakeCompound(c);
|
||
|
b.Add(c, s1);
|
||
|
b.Add(c, s2);
|
||
|
|
||
|
BRepTools::Write(c, "C:\\tt1.brep");
|
||
|
|
||
|
|
||
|
try
|
||
|
{
|
||
|
TopoDS_Shape shape = CheckSectionShape(Face, TopoTemp);
|
||
|
BRepAlgoAPI_Section asect(Face,shape,Standard_False);
|
||
|
asect.ComputePCurveOn1(Standard_True);
|
||
|
//asect.ComputePCurveOn2(Standard_True);
|
||
|
asect.Approximation(Standard_True);
|
||
|
asect.Build();
|
||
|
|
||
|
if(!asect.IsDone())
|
||
|
{
|
||
|
//faceSet.insert(make_pair(faceSet.size(), face));
|
||
|
//continue;
|
||
|
throw Face;
|
||
|
}
|
||
|
splitResult = asect.Shape();
|
||
|
//throw splitResult;
|
||
|
}
|
||
|
catch (Standard_Failure)
|
||
|
{
|
||
|
throw Face;
|
||
|
}
|
||
|
}
|
||
|
if(splitResult.IsNull())
|
||
|
throw splitResult;
|
||
|
|
||
|
builder.Add(compLine, splitResult);
|
||
|
|
||
|
// OCC剪切
|
||
|
|
||
|
int count = 0;
|
||
|
|
||
|
map<int, TopoDS_Edge> mapEdge;
|
||
|
|
||
|
|
||
|
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);
|
||
|
|
||
|
//double df,dl;
|
||
|
//Handle(Geom_Curve) cv = BRep_Tool::Curve(anEdge,df,dl);
|
||
|
//gp_Pnt p1 = cv->Value(df);
|
||
|
//gp_Pnt p2 = cv->Value(dl);
|
||
|
|
||
|
|
||
|
bool isCoincide = false;
|
||
|
for(int i = 0; i < faceBorder.size(); i++)
|
||
|
{
|
||
|
if(CheckTwoEdgeOverlapByLinePointProject(anEdge,faceBorder[i]))
|
||
|
{
|
||
|
isCoincide = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(isCoincide)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
mapEdge.insert(make_pair(count, anEdge));
|
||
|
count++;
|
||
|
}
|
||
|
|
||
|
////交线与边界完全重合 或者没交线
|
||
|
if(count == 0)
|
||
|
{
|
||
|
faceSet.insert(make_pair(faceSet.size(), Face));
|
||
|
continue;
|
||
|
}
|
||
|
//cout<<"num = "<<m<<endl;
|
||
|
// yc 20130731
|
||
|
if(mapEdge.size() > 200)
|
||
|
{
|
||
|
throw Face;
|
||
|
}
|
||
|
|
||
|
vector<vector<int>> edgeIndex;
|
||
|
GetWireSingleEdges(mapEdge,edgeIndex);
|
||
|
|
||
|
|
||
|
//static int yyy = 0;
|
||
|
//yyy++;
|
||
|
|
||
|
|
||
|
//TopoDS_Compound c;
|
||
|
//BRep_Builder b;
|
||
|
//b.MakeCompound(c);
|
||
|
////for(int ii = 0; ii < newEdges.size(); ii++)
|
||
|
////{
|
||
|
//// b.Add(c, newEdges[ii]);
|
||
|
|
||
|
////}
|
||
|
////throw c;
|
||
|
//for(int jj = 0; jj < edgeIndex[yyy-1].size();jj++)
|
||
|
//{
|
||
|
// b.Add(c, mapEdge[edgeIndex[yyy-1][jj]]);
|
||
|
// //gp_Pnt p1,p2;
|
||
|
// //GetEdgeStartEndPoint(mapEdge[edgeIndex[yyy-1][jj]], p1, p2);
|
||
|
// //// string s2 = Format("%.5f\t%.5f\t%.5f\n", p2.X(), p2.Y(), p2.Z());
|
||
|
// //// string s1 = Format("%.5f\t%.5f\t%.5f\n", p1.X(), p1.Y(), p1.Z());
|
||
|
// ////cout<< s1<<endl;
|
||
|
// ////cout<< s2<<endl;
|
||
|
// //cout<<"edge"<<jj<<":"<<endl;
|
||
|
// //cout<<p1.X()<<","<<p1.Y()<<","<<p1.Z()<<endl;
|
||
|
// //cout<<p2.X()<<","<<p2.Y()<<","<<p2.Z()<<endl;
|
||
|
//}
|
||
|
// throw c;
|
||
|
|
||
|
vector<bool> isUsed;
|
||
|
for(int i = 0; i < edgeIndex.size(); i++)
|
||
|
{
|
||
|
isUsed.push_back(false);
|
||
|
}
|
||
|
int wireSize = edgeIndex.size();
|
||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
while(!listFaces.empty())
|
||
|
{
|
||
|
TopoDS_Face face = listFaces.front();
|
||
|
listFaces.pop_front();
|
||
|
TopoShape = face;
|
||
|
TopoDS_Wire w;
|
||
|
|
||
|
if(wireSize == 0)
|
||
|
{
|
||
|
faceSet.insert(make_pair(faceSet.size(), face));
|
||
|
continue;
|
||
|
}
|
||
|
builder1.MakeWire(w);
|
||
|
try
|
||
|
{
|
||
|
TopoDS_Face tempFace = face;
|
||
|
BRepFeat_SplitShape asplit1(face);
|
||
|
BRepFeat_SplitShape asplit2(face);
|
||
|
int index = -1;
|
||
|
for(int i = 0; i < isUsed.size(); i++)
|
||
|
{
|
||
|
if(isUsed[i])
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
//交线不在面上
|
||
|
bool isOnFace = true;
|
||
|
vector<int> edgestmp = edgeIndex[i];
|
||
|
for(int j = 0; j < edgestmp.size(); j++)
|
||
|
{
|
||
|
int ind = edgestmp[j];
|
||
|
TopoDS_Edge edge = mapEdge[ind];
|
||
|
gp_Pnt p1, p2;
|
||
|
GetEdgeStartEndPoint(edge, p1, p2);
|
||
|
|
||
|
TopoDS_Vertex v1 = BRepBuilderAPI_MakeVertex(p1);
|
||
|
TopoDS_Vertex v2 = BRepBuilderAPI_MakeVertex(p2);
|
||
|
|
||
|
BRepExtrema_DistShapeShape inter1(v1,face);
|
||
|
inter1.Perform();
|
||
|
if(inter1.Value() > Precision::Confusion() * 100)
|
||
|
{
|
||
|
isOnFace = false;
|
||
|
break;
|
||
|
}
|
||
|
BRepExtrema_DistShapeShape inter2(v2,face);
|
||
|
inter2.Perform();
|
||
|
if(inter2.Value() > Precision::Confusion() * 100)
|
||
|
{
|
||
|
isOnFace = false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if(!isOnFace)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
index = i;
|
||
|
isUsed[i] = true;
|
||
|
wireSize--;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(index < 0)
|
||
|
{
|
||
|
faceSet.insert(make_pair(faceSet.size(), face));
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
vector<int> edges = edgeIndex[index];
|
||
|
|
||
|
vector<TopoDS_Edge> newEdges;
|
||
|
RebuildConnectLines(face, mapEdge, edges, newEdges);
|
||
|
|
||
|
//TopoDS_Compound c;
|
||
|
//BRep_Builder b;
|
||
|
//b.MakeCompound(c);
|
||
|
//for(int ii = 0; ii < newEdges.size(); ii++)
|
||
|
//{
|
||
|
// b.Add(c, newEdges[ii]);
|
||
|
|
||
|
//}
|
||
|
//throw c;
|
||
|
|
||
|
|
||
|
if(newEdges.size() == 0)
|
||
|
{
|
||
|
listFaces.push_back(face);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
|
||
|
for(int i = 0; i < newEdges.size(); i++)
|
||
|
{
|
||
|
TopoDS_Edge E = newEdges[i];
|
||
|
PutPCurve(E, face);
|
||
|
asplit1.Add(E,face);
|
||
|
E.Reverse();
|
||
|
asplit2.Add(E,face);
|
||
|
builder1.Add(w, E);
|
||
|
|
||
|
gp_Pnt p1,p2;
|
||
|
GetEdgeStartEndPoint(E, p1, p2);
|
||
|
|
||
|
cout<<"edge"<<i<<":"<<endl;
|
||
|
//cout<<p1.X()<<","<<p1.Y()<<","<<p1.Z()<<endl;
|
||
|
//cout<<p2.X()<<","<<p2.Y()<<","<<p2.Z()<<endl;
|
||
|
}
|
||
|
|
||
|
TopTools_ListIteratorOfListOfShape theList1,theList2;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
asplit1.Build();
|
||
|
}
|
||
|
catch (Standard_Failure e)
|
||
|
{
|
||
|
throw face;
|
||
|
}
|
||
|
theList1 = asplit1.Left();
|
||
|
|
||
|
for (;theList1.More();theList1.Next())
|
||
|
{
|
||
|
TopoDS_Face facetmp = TopoDS::Face(theList1.Value());
|
||
|
|
||
|
if(wireSize > 0)
|
||
|
{
|
||
|
int edgeCount = 0;
|
||
|
for(TopExp_Explorer e(facetmp, TopAbs_EDGE); e.More(); e.Next())
|
||
|
{
|
||
|
edgeCount++;
|
||
|
}
|
||
|
|
||
|
if(edgeCount == newEdges.size())
|
||
|
{
|
||
|
faceSet.insert(make_pair(faceSet.size(), facetmp));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
listFaces.push_back(facetmp);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
faceSet.insert(make_pair(faceSet.size(), facetmp));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
try
|
||
|
{
|
||
|
asplit2.Build();
|
||
|
}
|
||
|
catch (Standard_Failure e)
|
||
|
{
|
||
|
throw w;
|
||
|
}
|
||
|
theList2=asplit2.Left();
|
||
|
for (;theList2.More();theList2.Next())
|
||
|
{
|
||
|
TopoDS_Face facetmp = TopoDS::Face(theList2.Value());
|
||
|
if(wireSize > 0)
|
||
|
{
|
||
|
int edgeCount = 0;
|
||
|
for(TopExp_Explorer e(facetmp, TopAbs_EDGE); e.More(); e.Next())
|
||
|
{
|
||
|
edgeCount++;
|
||
|
}
|
||
|
|
||
|
if(edgeCount == newEdges.size())
|
||
|
{
|
||
|
faceSet.insert(make_pair(faceSet.size(), facetmp));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
listFaces.push_back(facetmp);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
faceSet.insert(make_pair(faceSet.size(), facetmp));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
catch(Standard_Failure)
|
||
|
{
|
||
|
throw compLine ;
|
||
|
}
|
||
|
catch(TopoDS_Shape s)
|
||
|
{
|
||
|
throw s;
|
||
|
}
|
||
|
}// while(!listFaces.empty())
|
||
|
}
|
||
|
//if(this->flag == 1)
|
||
|
// throw compLine;
|
||
|
//throw faceSet[0];
|
||
|
int size = faceSet.size();
|
||
|
TopoDS_Shape resultSet = GetCutResult(faceSet,compLine);
|
||
|
for(TopExp_Explorer ex(resultSet,TopAbs_SHELL); ex.More();ex.Next())
|
||
|
{
|
||
|
shellSet.push_back(TopoDS::Shell(ex.Current()));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
TopoDS_Shape CutSurfaceAlgo::CheckSectionShape(TopoDS_Shape s1, TopoDS_Shape s2)
|
||
|
{
|
||
|
TopoDS_Compound c;
|
||
|
BRep_Builder b;
|
||
|
b.MakeCompound(c);
|
||
|
for(TopExp_Explorer ex(s2, TopAbs_FACE); ex.More(); ex.Next())
|
||
|
{
|
||
|
TopoDS_Face face = TopoDS::Face(ex.Current());
|
||
|
try
|
||
|
{
|
||
|
BRepAlgoAPI_Section asect(s1,face,Standard_False);
|
||
|
asect.ComputePCurveOn1(Standard_True);
|
||
|
//asect.ComputePCurveOn2(Standard_True);
|
||
|
asect.Approximation(Standard_True);
|
||
|
asect.Build();
|
||
|
|
||
|
if(!asect.IsDone())
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
TopoDS_Shape splitResult = asect.Shape();
|
||
|
|
||
|
for(TopExp_Explorer e(splitResult, TopAbs_EDGE);e.More();e.Next())
|
||
|
{
|
||
|
b.Add(c,face);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
catch(Standard_Failure)
|
||
|
{
|
||
|
TopoDS_Compound c1;
|
||
|
BRep_Builder b1;
|
||
|
b1.MakeCompound(c1);
|
||
|
b1.Add(c1, face);
|
||
|
b1.Add(c1, s1);
|
||
|
|
||
|
//BRepTools::Write(c1, "C:\\tt2.brep");
|
||
|
throw face;
|
||
|
}
|
||
|
}
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
void CutSurfaceAlgo::TrimSurfaceTranslateInsec(TopoDS_Shape TopoSrf,TopoDS_Shape TopoTemp, vector<TopoDS_Shell>& shellSet , bool isLeft)
|
||
|
{
|
||
|
TopoDS_Shape TopoShape;
|
||
|
|
||
|
std::map<int, TopoDS_Face> faceSet;
|
||
|
TopoDS_Compound compLine;
|
||
|
vector<TopoDS_Face> leftFace;
|
||
|
|
||
|
BRep_Builder builder,builder1;
|
||
|
builder.MakeCompound(compLine);
|
||
|
|
||
|
int faceCount = 0;
|
||
|
int faceIndex = 0;
|
||
|
|
||
|
vector<TopoDS_Face> faces;
|
||
|
|
||
|
if(TopoSrf.ShapeType() == TopAbs_FACE)
|
||
|
{
|
||
|
faces.push_back(TopoDS::Face(TopoSrf));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for(TopExp_Explorer ex(TopoSrf,TopAbs_FACE); ex.More(); ex.Next())
|
||
|
{
|
||
|
faces.push_back(TopoDS::Face(ex.Current()));
|
||
|
}
|
||
|
}
|
||
|
for(int m = 0; m < faces.size(); m++)
|
||
|
{
|
||
|
faceIndex++;
|
||
|
TopoDS_Face Face = faces[m];
|
||
|
|
||
|
list<TopoDS_Face> listFaces;
|
||
|
listFaces.push_back(Face);
|
||
|
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
TopoDS_Shape splitResult;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
BRepAlgoAPI_Section asect(Face,TopoTemp,Standard_False);
|
||
|
asect.ComputePCurveOn1(Standard_True);
|
||
|
asect.Approximation(Standard_True);
|
||
|
asect.Build();
|
||
|
|
||
|
if(!asect.IsDone())
|
||
|
{
|
||
|
//faceSet.insert(make_pair(faceSet.size(), face));
|
||
|
//continue;
|
||
|
throw Face;
|
||
|
}
|
||
|
splitResult = asect.Shape();
|
||
|
//throw splitResult;
|
||
|
}
|
||
|
catch (Standard_Failure)
|
||
|
{
|
||
|
TopoDS_Compound c;
|
||
|
TopoDS_Shell s1, s2;
|
||
|
BRep_Builder b;
|
||
|
|
||
|
b.MakeShell(s1);
|
||
|
b.Add(s1, Face);
|
||
|
|
||
|
if(TopoTemp.ShapeType() == TopAbs_FACE)
|
||
|
{
|
||
|
b.MakeShell(s2);
|
||
|
b.Add(s2, TopoTemp);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
s2 = TopoDS::Shell(TopoTemp);
|
||
|
}
|
||
|
|
||
|
b.MakeCompound(c);
|
||
|
b.Add(c, s1);
|
||
|
b.Add(c, s2);
|
||
|
|
||
|
//BRepTools::Write(c, "C:\\tt1.brep");
|
||
|
|
||
|
|
||
|
try
|
||
|
{
|
||
|
TopoDS_Shape shape = CheckSectionShape(Face, TopoTemp);
|
||
|
BRepAlgoAPI_Section asect(Face,shape,Standard_False);
|
||
|
asect.ComputePCurveOn1(Standard_True);
|
||
|
//asect.ComputePCurveOn2(Standard_True);
|
||
|
asect.Approximation(Standard_True);
|
||
|
asect.Build();
|
||
|
|
||
|
if(!asect.IsDone())
|
||
|
{
|
||
|
//faceSet.insert(make_pair(faceSet.size(), face));
|
||
|
//continue;
|
||
|
throw Face;
|
||
|
}
|
||
|
splitResult = asect.Shape();
|
||
|
//throw splitResult;
|
||
|
}
|
||
|
catch (Standard_Failure)
|
||
|
{
|
||
|
throw Face;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
builder.Add(compLine, splitResult);
|
||
|
|
||
|
// OCC剪切
|
||
|
|
||
|
int count = 0;
|
||
|
|
||
|
map<int, TopoDS_Edge> mapEdge;
|
||
|
|
||
|
|
||
|
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);
|
||
|
//TopoDS_Face aFace1,aFace2;
|
||
|
//if (asect.HasAncestorFaceOn1(anEdge,aFace1) && asect.HasAncestorFaceOn2(anEdge,aFace2))
|
||
|
//{
|
||
|
// TopoDS_Face F = TopoDS::Face(aFace1);
|
||
|
// TopoDS_Face F2 = TopoDS::Face(aFace2);
|
||
|
// bool isface1clock=(F.Orientation() == TopAbs_REVERSED);
|
||
|
// bool isface2clock=(F2.Orientation() == TopAbs_REVERSED);
|
||
|
// if((isface1clock && isface2clock) || (!isface1clock && !isface2clock))
|
||
|
// {
|
||
|
// anEdge.Reverse();
|
||
|
// }
|
||
|
//}
|
||
|
|
||
|
|
||
|
//double df,dl;
|
||
|
//Handle(Geom_Curve) cv = BRep_Tool::Curve(anEdge,df,dl);
|
||
|
//gp_Pnt p1 = cv->Value(df);
|
||
|
//gp_Pnt p2 = cv->Value(dl);
|
||
|
|
||
|
|
||
|
bool isCoincide = false;
|
||
|
for(int i = 0; i < faceBorder.size(); i++)
|
||
|
{
|
||
|
if(CheckTwoEdgeOverlapByLinePointProject(anEdge,faceBorder[i]))
|
||
|
{
|
||
|
isCoincide = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(isCoincide)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
mapEdge.insert(make_pair(count, anEdge));
|
||
|
count++;
|
||
|
}
|
||
|
|
||
|
////交线与边界完全重合 或者没交线
|
||
|
if(count == 0)
|
||
|
{
|
||
|
faceSet.insert(make_pair(faceSet.size(), Face));
|
||
|
continue;
|
||
|
}
|
||
|
//cout<<"num = "<<m<<endl;
|
||
|
// yc 20130731
|
||
|
if(mapEdge.size() > 200)
|
||
|
{
|
||
|
throw Face;
|
||
|
}
|
||
|
|
||
|
vector<vector<int>> edgeIndex;
|
||
|
GetWireSingleEdges(mapEdge,edgeIndex);
|
||
|
|
||
|
|
||
|
//static int yyy = 0;
|
||
|
//yyy++;
|
||
|
|
||
|
|
||
|
//TopoDS_Compound c;
|
||
|
//BRep_Builder b;
|
||
|
//b.MakeCompound(c);
|
||
|
////for(int ii = 0; ii < newEdges.size(); ii++)
|
||
|
////{
|
||
|
//// b.Add(c, newEdges[ii]);
|
||
|
|
||
|
////}
|
||
|
////throw c;
|
||
|
//for(int jj = 0; jj < edgeIndex[yyy-1].size();jj++)
|
||
|
//{
|
||
|
// b.Add(c, mapEdge[edgeIndex[yyy-1][jj]]);
|
||
|
// //gp_Pnt p1,p2;
|
||
|
// //GetEdgeStartEndPoint(mapEdge[edgeIndex[yyy-1][jj]], p1, p2);
|
||
|
// //// string s2 = Format("%.5f\t%.5f\t%.5f\n", p2.X(), p2.Y(), p2.Z());
|
||
|
// //// string s1 = Format("%.5f\t%.5f\t%.5f\n", p1.X(), p1.Y(), p1.Z());
|
||
|
// ////cout<< s1<<endl;
|
||
|
// ////cout<< s2<<endl;
|
||
|
// //cout<<"edge"<<jj<<":"<<endl;
|
||
|
// //cout<<p1.X()<<","<<p1.Y()<<","<<p1.Z()<<endl;
|
||
|
// //cout<<p2.X()<<","<<p2.Y()<<","<<p2.Z()<<endl;
|
||
|
//}
|
||
|
// throw c;
|
||
|
|
||
|
vector<bool> isUsed;
|
||
|
for(int i = 0; i < edgeIndex.size(); i++)
|
||
|
{
|
||
|
isUsed.push_back(false);
|
||
|
}
|
||
|
int wireSize = edgeIndex.size();
|
||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
BRepFeat_SplitShape asplit(listFaces.front());
|
||
|
for(int i = 0; i < edgeIndex.size(); i++)
|
||
|
{
|
||
|
for(int j = 0; j < edgeIndex[i].size(); j++)
|
||
|
{
|
||
|
TopoDS_Edge edge = mapEdge[edgeIndex[i][j]];
|
||
|
if((!isLeft && listFaces.front().Orientation() == TopAbs_REVERSED)
|
||
|
|| (isLeft && listFaces.front().Orientation() == TopAbs_FORWARD))
|
||
|
{
|
||
|
edge.Reverse();
|
||
|
}
|
||
|
asplit.Add(edge,listFaces.front());
|
||
|
}
|
||
|
}
|
||
|
asplit.Build();
|
||
|
TopTools_ListIteratorOfListOfShape theList = asplit.Left();
|
||
|
|
||
|
for (;theList.More();theList.Next())
|
||
|
{
|
||
|
TopoDS_Face facetmp = TopoDS::Face(theList.Value());
|
||
|
leftFace.push_back(facetmp);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
while(!listFaces.empty())
|
||
|
{
|
||
|
TopoDS_Face face = listFaces.front();
|
||
|
listFaces.pop_front();
|
||
|
TopoShape = face;
|
||
|
TopoDS_Wire w;
|
||
|
|
||
|
if(wireSize == 0)
|
||
|
{
|
||
|
faceSet.insert(make_pair(faceSet.size(), face));
|
||
|
continue;
|
||
|
}
|
||
|
builder1.MakeWire(w);
|
||
|
try
|
||
|
{
|
||
|
TopoDS_Face tempFace = face;
|
||
|
BRepFeat_SplitShape asplit1(face);
|
||
|
BRepFeat_SplitShape asplit2(face);
|
||
|
int index = -1;
|
||
|
for(int i = 0; i < isUsed.size(); i++)
|
||
|
{
|
||
|
if(isUsed[i])
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
//交线不在面上
|
||
|
bool isOnFace = true;
|
||
|
vector<int> edgestmp = edgeIndex[i];
|
||
|
for(int j = 0; j < edgestmp.size(); j++)
|
||
|
{
|
||
|
int ind = edgestmp[j];
|
||
|
TopoDS_Edge edge = mapEdge[ind];
|
||
|
gp_Pnt p1, p2;
|
||
|
GetEdgeStartEndPoint(edge, p1, p2);
|
||
|
|
||
|
TopoDS_Vertex v1 = BRepBuilderAPI_MakeVertex(p1);
|
||
|
TopoDS_Vertex v2 = BRepBuilderAPI_MakeVertex(p2);
|
||
|
|
||
|
BRepExtrema_DistShapeShape inter1(v1,face);
|
||
|
inter1.Perform();
|
||
|
if(inter1.Value() > Precision::Confusion() * 100)
|
||
|
{
|
||
|
isOnFace = false;
|
||
|
break;
|
||
|
}
|
||
|
BRepExtrema_DistShapeShape inter2(v2,face);
|
||
|
inter2.Perform();
|
||
|
if(inter2.Value() > Precision::Confusion() * 100)
|
||
|
{
|
||
|
isOnFace = false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if(!isOnFace)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
index = i;
|
||
|
isUsed[i] = true;
|
||
|
wireSize--;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(index < 0)
|
||
|
{
|
||
|
faceSet.insert(make_pair(faceSet.size(), face));
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
vector<int> edges = edgeIndex[index];
|
||
|
|
||
|
vector<TopoDS_Edge> newEdges;
|
||
|
RebuildConnectLines(face, mapEdge, edges, newEdges);
|
||
|
|
||
|
//TopoDS_Compound c;
|
||
|
//BRep_Builder b;
|
||
|
//b.MakeCompound(c);
|
||
|
//for(int ii = 0; ii < newEdges.size(); ii++)
|
||
|
//{
|
||
|
// b.Add(c, newEdges[ii]);
|
||
|
|
||
|
//}
|
||
|
//throw c;
|
||
|
|
||
|
|
||
|
if(newEdges.size() == 0)
|
||
|
{
|
||
|
listFaces.push_back(face);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
|
||
|
for(int i = 0; i < newEdges.size(); i++)
|
||
|
{
|
||
|
TopoDS_Edge E = newEdges[i];
|
||
|
PutPCurve(E, face);
|
||
|
asplit1.Add(E,face);
|
||
|
E.Reverse();
|
||
|
asplit2.Add(E,face);
|
||
|
builder1.Add(w, E);
|
||
|
|
||
|
|
||
|
gp_Pnt p1,p2;
|
||
|
GetEdgeStartEndPoint(E, p1, p2);
|
||
|
//cout<<"edge"<<i<<":"<<endl;
|
||
|
//cout<<p1.X()<<","<<p1.Y()<<","<<p1.Z()<<endl;
|
||
|
//cout<<p2.X()<<","<<p2.Y()<<","<<p2.Z()<<endl;
|
||
|
}
|
||
|
|
||
|
TopTools_ListIteratorOfListOfShape theList1,theList2;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
asplit1.Build();
|
||
|
}
|
||
|
catch (Standard_Failure e)
|
||
|
{
|
||
|
throw face;
|
||
|
}
|
||
|
theList1 = asplit1.Left();
|
||
|
|
||
|
for (;theList1.More();theList1.Next())
|
||
|
{
|
||
|
TopoDS_Face facetmp = TopoDS::Face(theList1.Value());
|
||
|
|
||
|
if(wireSize > 0)
|
||
|
{
|
||
|
int edgeCount = 0;
|
||
|
for(TopExp_Explorer e(facetmp, TopAbs_EDGE); e.More(); e.Next())
|
||
|
{
|
||
|
edgeCount++;
|
||
|
}
|
||
|
|
||
|
if(edgeCount == newEdges.size())
|
||
|
{
|
||
|
faceSet.insert(make_pair(faceSet.size(), facetmp));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
listFaces.push_back(facetmp);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
faceSet.insert(make_pair(faceSet.size(), facetmp));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
try
|
||
|
{
|
||
|
asplit2.Build();
|
||
|
}
|
||
|
catch (Standard_Failure e)
|
||
|
{
|
||
|
throw w;
|
||
|
}
|
||
|
theList2=asplit2.Left();
|
||
|
for (;theList2.More();theList2.Next())
|
||
|
{
|
||
|
TopoDS_Face facetmp = TopoDS::Face(theList2.Value());
|
||
|
if(wireSize > 0)
|
||
|
{
|
||
|
int edgeCount = 0;
|
||
|
for(TopExp_Explorer e(facetmp, TopAbs_EDGE); e.More(); e.Next())
|
||
|
{
|
||
|
edgeCount++;
|
||
|
}
|
||
|
|
||
|
if(edgeCount == newEdges.size())
|
||
|
{
|
||
|
faceSet.insert(make_pair(faceSet.size(), facetmp));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
listFaces.push_back(facetmp);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
faceSet.insert(make_pair(faceSet.size(), facetmp));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
catch(Standard_Failure)
|
||
|
{
|
||
|
throw compLine ;
|
||
|
}
|
||
|
catch(TopoDS_Shape s)
|
||
|
{
|
||
|
throw s;
|
||
|
}
|
||
|
}// while(!listFaces.empty())
|
||
|
}
|
||
|
//if(this->flag == 1)
|
||
|
// throw compLine;
|
||
|
//throw faceSet[0];
|
||
|
int size = faceSet.size();
|
||
|
TopoDS_Shape resultSet = GetCutResult(faceSet,compLine);
|
||
|
vector<TopoDS_Shell> shellTmp;
|
||
|
|
||
|
|
||
|
for(TopExp_Explorer ex(resultSet,TopAbs_SHELL); ex.More();ex.Next())
|
||
|
{
|
||
|
TopoDS_Shell shell = TopoDS::Shell(ex.Current());
|
||
|
bool isfind = false;
|
||
|
for(TopExp_Explorer e(shell, TopAbs_FACE); e.More();e.Next())
|
||
|
{
|
||
|
TopoDS_Face face = TopoDS::Face(e.Current());
|
||
|
vector<TopoDS_Edge> edgeSet;
|
||
|
for(TopExp_Explorer es(face, TopAbs_EDGE); es.More(); es.Next())
|
||
|
{
|
||
|
edgeSet.push_back(TopoDS::Edge(es.Current()));
|
||
|
}
|
||
|
for(int i = 0; i < leftFace.size(); i++)
|
||
|
{
|
||
|
//if(leftFace[i].IsEqual(face))
|
||
|
//{
|
||
|
// isfind = true;
|
||
|
// break;
|
||
|
//}
|
||
|
vector<TopoDS_Edge> edgeSet1;
|
||
|
for(TopExp_Explorer es1(leftFace[i], TopAbs_EDGE); es1.More(); es1.Next())
|
||
|
{
|
||
|
edgeSet1.push_back(TopoDS::Edge(es1.Current()));
|
||
|
}
|
||
|
|
||
|
if(edgeSet1.size() != edgeSet.size())
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
int m = 0;
|
||
|
for(m = 0; m < edgeSet.size(); m++)
|
||
|
{
|
||
|
gp_Pnt p1,p2;
|
||
|
GetEdgeStartEndPoint(edgeSet[m], p1,p2);
|
||
|
bool IsEqual = false;
|
||
|
for(int n = 0; n < edgeSet1.size(); n++)
|
||
|
{
|
||
|
gp_Pnt p3,p4;
|
||
|
GetEdgeStartEndPoint(edgeSet1[n], p3,p4);
|
||
|
|
||
|
if((p1.Distance(p3) < Precision::Confusion() && p2.Distance(p4) < Precision::Confusion())
|
||
|
|| (p1.Distance(p4) < Precision::Confusion() && p2.Distance(p3) < Precision::Confusion()))
|
||
|
{
|
||
|
IsEqual = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if(!IsEqual)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(m == edgeSet.size())
|
||
|
{
|
||
|
isfind = true;
|
||
|
}
|
||
|
}
|
||
|
if(isfind)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if(isfind)
|
||
|
{
|
||
|
shellTmp.push_back(TopoDS::Shell(ex.Current()));
|
||
|
//b.Add(ss, shell);
|
||
|
}
|
||
|
}
|
||
|
if(shellTmp.size() >0)
|
||
|
{
|
||
|
TopoDS_Shell ss;
|
||
|
BRep_Builder b;
|
||
|
b.MakeShell(ss);
|
||
|
for(int i = 0; i < shellTmp.size(); i++)
|
||
|
{
|
||
|
for(TopExp_Explorer ex(shellTmp[i], TopAbs_FACE); ex.More(); ex.Next())
|
||
|
{
|
||
|
b.Add(ss, TopoDS::Face(ex.Current()));
|
||
|
}
|
||
|
}
|
||
|
shellSet.push_back(ss);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|