3283 lines
69 KiB
C++
3283 lines
69 KiB
C++
#include "Stdafx.h"
|
|
#include "BaseAlgo.h"
|
|
#include "GeomProjLib.hxx"
|
|
#include "Geom2d_Curve.hxx"
|
|
#include "GeomAPI_ProjectPointOnCurve.hxx"
|
|
#include "TopExp_Explorer.hxx"
|
|
//#include <Windows.h>
|
|
#include "BRepTools_ShapeSet.hxx"
|
|
#include "BRepClass3d_SolidClassifier.hxx"
|
|
#include <iosfwd>
|
|
#include <algorithm>
|
|
|
|
|
|
BaseAlgo::BaseAlgo(void)
|
|
{
|
|
this->flag = 0;
|
|
}
|
|
|
|
|
|
BaseAlgo::~BaseAlgo(void)
|
|
{
|
|
}
|
|
|
|
void BaseAlgo::GetEdgeStartEndPoint( const TopoDS_Edge& edge, gp_Pnt& sp, gp_Pnt& ep )
|
|
{
|
|
TopoDS_Vertex sv,ev;
|
|
TopExp::Vertices(edge,sv,ev);
|
|
sp = BRep_Tool::Pnt(sv);
|
|
ep = BRep_Tool::Pnt(ev);
|
|
}
|
|
|
|
bool BaseAlgo::isOnEdge( TopoDS_Edge& edge1, TopoDS_Edge& edge2 )
|
|
{
|
|
gp_Pnt p1,p2;
|
|
GetEdgeStartEndPoint(edge1, p1, p2);
|
|
vector<gp_Pnt> pSet;
|
|
pSet.push_back(p1);
|
|
pSet.push_back(p2);
|
|
|
|
double col = Precision::Confusion() * 1000;
|
|
|
|
//采样点
|
|
Standard_Real dF,dL;
|
|
|
|
Handle(Geom_Curve) cv = BRep_Tool::Curve(edge1,dF,dL);
|
|
if(dF > dL)
|
|
{
|
|
int k = dF;
|
|
dF = dL;
|
|
dL = k;
|
|
}
|
|
double step = (dL-dF) / 10;
|
|
while (dF < dL)
|
|
{
|
|
gp_Pnt p = cv->Value(dF);
|
|
pSet.push_back(p);
|
|
dF += step;
|
|
}
|
|
|
|
for(vector<gp_Pnt>::iterator iter = pSet.begin(); iter != pSet.end(); iter++)
|
|
{
|
|
TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(*iter).Vertex();
|
|
BRepExtrema_DistShapeShape inter(v,edge2);
|
|
//inter.Perform();
|
|
if(inter.Value() > col)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool BaseAlgo::hasCommenPart( TopoDS_Edge& edge1, TopoDS_Edge& edge2 )
|
|
{
|
|
if(isOnEdge(edge1,edge2))
|
|
{
|
|
return true;
|
|
}
|
|
//BRepExtrema_DistShapeShape inter(edge1,edge2);
|
|
//if(inter.Value() < Precision::Confusion() * 1000 && inter.NbSolution() > 3)
|
|
//{
|
|
// return true;
|
|
//}
|
|
vector<gp_Pnt> pSet;
|
|
int count = 0;
|
|
double col = Precision::Confusion() * 1000;
|
|
Standard_Real dF,dL;
|
|
Handle(Geom_Curve) cv1 = BRep_Tool::Curve(edge1,dF,dL);
|
|
if(dF > dL)
|
|
{
|
|
int k = dF;
|
|
dF = dL;
|
|
dL = k;
|
|
}
|
|
double step = (dL-dF) / 10;
|
|
step = step < col ? col * 1.1 : step;
|
|
for (int i = 0; i < 5 && i * step * 2 > dL - dF; i++)
|
|
{
|
|
gp_Pnt p = cv1->Value(dF + i * step);
|
|
pSet.push_back(p);
|
|
p = cv1->Value(dL - i * step);
|
|
pSet.push_back(p);
|
|
}
|
|
|
|
for(vector<gp_Pnt>::iterator iter = pSet.begin(); iter != pSet.end(); iter++)
|
|
{
|
|
TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(*iter).Vertex();
|
|
BRepExtrema_DistShapeShape inter(v,edge2);
|
|
//inter.Perform();
|
|
if(inter.Value() < col)
|
|
{
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if(count > 3)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
pSet.clear();
|
|
count = 0;
|
|
Handle(Geom_Curve) cv2 = BRep_Tool::Curve(edge2,dF,dL);
|
|
if(dF > dL)
|
|
{
|
|
int k = dF;
|
|
dF = dL;
|
|
dL = k;
|
|
}
|
|
step = (dL-dF) / 10;
|
|
step = step < col ? col * 1.1 : step;
|
|
for (int i = 0; i < 5 && i * step * 2 > dL - dF; i++)
|
|
{
|
|
gp_Pnt p = cv2->Value(dF + i * step);
|
|
pSet.push_back(p);
|
|
p = cv2->Value(dL - i * step);
|
|
pSet.push_back(p);
|
|
}
|
|
|
|
for(vector<gp_Pnt>::iterator iter = pSet.begin(); iter != pSet.end(); iter++)
|
|
{
|
|
TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(*iter).Vertex();
|
|
BRepExtrema_DistShapeShape inter(v,edge1);
|
|
//inter.Perform();
|
|
if(inter.Value() < col)
|
|
{
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if(count > 3)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
Bnd_Box BaseAlgo::getFaceBox( TopoDS_Face face )
|
|
{
|
|
Bnd_Box box;
|
|
|
|
for(TopExp_Explorer ex(face, TopAbs_VERTEX); ex.More(); ex.Next())
|
|
{
|
|
TopoDS_Vertex v = TopoDS::Vertex(ex.Current());
|
|
|
|
gp_Pnt p = BRep_Tool::Pnt(v);
|
|
box.Add(p);
|
|
}
|
|
return box;
|
|
}
|
|
|
|
void BaseAlgo::GetWireSingleEdges1( map<int, TopoDS_Edge>& mapEdge,vector<vector<int>>& edgeIndex )
|
|
{
|
|
map<int, bool> mapIsUse;
|
|
int MaxLengthID = -1;
|
|
double maxLength = -1;
|
|
gp_Pnt fp,ep;
|
|
|
|
double tol1 = Precision::Confusion() * 10;
|
|
double tol2 = Precision::Confusion() * 100;
|
|
|
|
|
|
list<int> listEdge;
|
|
edgeIndex.clear();
|
|
|
|
if(mapEdge.size() == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for(map<int, TopoDS_Edge>::iterator iter = mapEdge.begin(); iter != mapEdge.end(); iter++)
|
|
{
|
|
mapIsUse.insert(make_pair(iter->first,false));
|
|
|
|
double df,dl;
|
|
Handle(Geom_Curve) cv = BRep_Tool::Curve(iter->second, df,dl);
|
|
double len = dl -df;
|
|
|
|
if(len > maxLength)
|
|
{
|
|
maxLength = len;
|
|
MaxLengthID = iter->first;
|
|
GetEdgeStartEndPoint(iter->second, fp,ep);
|
|
}
|
|
}
|
|
|
|
|
|
BRep_Builder builder;
|
|
TopoDS_Compound comp;
|
|
builder.MakeCompound(comp);
|
|
|
|
//以最长边为根
|
|
mapIsUse[MaxLengthID] = true;
|
|
builder.Add(comp, mapEdge[MaxLengthID]);
|
|
listEdge.push_back(MaxLengthID);
|
|
mapEdge[MaxLengthID].Orientation(TopAbs_FORWARD);
|
|
|
|
int numUnuse = mapIsUse.size() - 1;
|
|
|
|
while(numUnuse !=0)
|
|
{
|
|
int temp = numUnuse;
|
|
for(map<int, TopoDS_Edge>::iterator iter = mapEdge.begin(); iter != mapEdge.end(); iter++)
|
|
{
|
|
if(mapIsUse[iter->first])
|
|
{
|
|
continue;
|
|
}
|
|
double df,dl;
|
|
gp_Pnt p1,p2;
|
|
TopoDS_Vertex v1,v2;
|
|
GetEdgeStartEndPoint(iter->second, p1,p2);
|
|
|
|
if(p1.Distance(fp) < tol1)
|
|
{
|
|
if(p2.Distance(ep) < tol2)//闭合
|
|
{
|
|
builder.Add(comp, iter->second);
|
|
fp = p2;
|
|
listEdge.push_front(iter->first);
|
|
mapEdge[iter->first].Orientation(TopAbs_REVERSED);
|
|
}
|
|
else
|
|
{
|
|
TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(p2).Vertex();
|
|
BRepExtrema_DistShapeShape inter(v,comp);
|
|
if(inter.IsDone())
|
|
{
|
|
if( inter.Value() > tol2)
|
|
{
|
|
builder.Add(comp, iter->second);
|
|
fp = p2;
|
|
listEdge.push_front(iter->first);
|
|
mapEdge[iter->first].Orientation(TopAbs_REVERSED);
|
|
}
|
|
}
|
|
}
|
|
mapIsUse[iter->first] = true;
|
|
}
|
|
else if(p2.Distance(fp) < tol1)
|
|
{
|
|
if(p1.Distance(ep) < tol2)//闭合
|
|
{
|
|
builder.Add(comp, iter->second);
|
|
fp = p1;
|
|
listEdge.push_front(iter->first);
|
|
mapEdge[iter->first].Orientation(TopAbs_FORWARD);
|
|
}
|
|
else
|
|
{
|
|
TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(p1).Vertex();
|
|
BRepExtrema_DistShapeShape inter(v,comp);
|
|
if(inter.IsDone())
|
|
{
|
|
if( inter.Value() > tol2)
|
|
{
|
|
builder.Add(comp, iter->second);
|
|
fp = p1;
|
|
listEdge.push_front(iter->first);
|
|
mapEdge[iter->first].Orientation(TopAbs_FORWARD);
|
|
}
|
|
}
|
|
}
|
|
mapIsUse[iter->first] = true;
|
|
}
|
|
else if(p1.Distance(ep) < tol1)
|
|
{
|
|
if(p2.Distance(fp) < tol2)//闭合
|
|
{
|
|
builder.Add(comp, iter->second);
|
|
ep = p2;
|
|
listEdge.push_back(iter->first);
|
|
mapEdge[iter->first].Orientation(TopAbs_FORWARD);
|
|
}
|
|
else
|
|
{
|
|
TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(p2).Vertex();
|
|
BRepExtrema_DistShapeShape inter(v,comp);
|
|
if(inter.IsDone())
|
|
{
|
|
if( inter.Value() > tol2)
|
|
{
|
|
builder.Add(comp, iter->second);
|
|
ep = p2;
|
|
listEdge.push_back(iter->first);
|
|
mapEdge[iter->first].Orientation(TopAbs_FORWARD);
|
|
}
|
|
}
|
|
}
|
|
mapIsUse[iter->first] = true;
|
|
}
|
|
else if(p2.Distance(ep) < tol1)
|
|
{
|
|
if(p1.Distance(fp) < tol2)//闭合
|
|
{
|
|
builder.Add(comp, iter->second);
|
|
ep = p1;
|
|
listEdge.push_back(iter->first);
|
|
mapEdge[iter->first].Reverse();
|
|
mapEdge[iter->first].Orientation(TopAbs_REVERSED);
|
|
}
|
|
else
|
|
{
|
|
TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(p1).Vertex();
|
|
BRepExtrema_DistShapeShape inter(v,comp);
|
|
if(inter.IsDone())
|
|
{
|
|
if( inter.Value() > tol2)
|
|
{
|
|
builder.Add(comp, iter->second);
|
|
ep = p1;
|
|
listEdge.push_back(iter->first);
|
|
mapEdge[iter->first].Reverse();
|
|
mapEdge[iter->first].Orientation(TopAbs_REVERSED);
|
|
}
|
|
}
|
|
}
|
|
mapIsUse[iter->first] = true;
|
|
}
|
|
|
|
if(mapIsUse[iter->first])
|
|
{
|
|
MaxLengthID = iter->first;
|
|
numUnuse--;
|
|
}
|
|
}
|
|
|
|
if(numUnuse == temp || numUnuse == 0)
|
|
{
|
|
vector<int> edges;
|
|
while(listEdge.size() > 0)
|
|
{
|
|
edges.push_back(listEdge.front());
|
|
listEdge.pop_front();
|
|
}
|
|
|
|
if(edges.size() > 0)
|
|
{
|
|
edgeIndex.push_back(edges);
|
|
}
|
|
|
|
//排除小短边
|
|
|
|
for(map<int, TopoDS_Edge>::iterator iter = mapEdge.begin(); iter != mapEdge.end(); iter++)
|
|
{
|
|
if(mapIsUse[iter->first])
|
|
{
|
|
continue;
|
|
}
|
|
|
|
double df,dl;
|
|
Handle(Geom_Curve) cv = BRep_Tool::Curve(iter->second, df,dl);
|
|
double len = dl -df;
|
|
|
|
gp_Pnt p1,p2;
|
|
GetEdgeStartEndPoint(iter->second, p1,p2);
|
|
TopoDS_Vertex v1,v2;
|
|
TopExp::Vertices(iter->second, v1,v2);
|
|
|
|
bool isP1On = false;
|
|
bool isP2On = false;
|
|
|
|
|
|
for(int k = 0; k < edges.size(); k++)
|
|
{
|
|
int index = edges[k];
|
|
TopoDS_Edge edge = mapEdge[index];
|
|
|
|
if(!isP1On)
|
|
{
|
|
BRepExtrema_DistShapeShape inter1(v1,edge);
|
|
inter1.Perform();
|
|
if(inter1.Value() < tol1)
|
|
{
|
|
isP1On = true;
|
|
}
|
|
}
|
|
|
|
if(!isP2On)
|
|
{
|
|
BRepExtrema_DistShapeShape inter2(v2,edge);
|
|
inter2.Perform();
|
|
if(inter2.Value() < tol1)
|
|
{
|
|
isP2On = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(isP2On && isP1On)
|
|
{
|
|
mapIsUse[iter->first] = true;
|
|
numUnuse--;
|
|
}
|
|
}
|
|
|
|
//重新初始
|
|
maxLength = -1;
|
|
for(map<int, TopoDS_Edge>::iterator iter = mapEdge.begin(); iter != mapEdge.end(); iter++)
|
|
{
|
|
if(mapIsUse[iter->first])
|
|
{
|
|
continue;
|
|
}
|
|
|
|
double df,dl;
|
|
Handle(Geom_Curve) cv = BRep_Tool::Curve(iter->second, df,dl);
|
|
double len = dl -df;
|
|
|
|
if(len > maxLength)
|
|
{
|
|
maxLength = len;
|
|
TopExp_Explorer ex(iter->second, TopAbs_VERTEX);
|
|
MaxLengthID = iter->first;
|
|
GetEdgeStartEndPoint(iter->second, fp,ep);
|
|
}
|
|
}
|
|
|
|
if(maxLength > -1)
|
|
{
|
|
mapIsUse[MaxLengthID] = true;
|
|
builder.Add(comp, mapEdge[MaxLengthID]);
|
|
listEdge.push_back(MaxLengthID);
|
|
mapEdge[MaxLengthID].Orientation(TopAbs_FORWARD);
|
|
numUnuse--;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(listEdge.size() > 0)
|
|
{
|
|
vector<int> edges;
|
|
while(listEdge.size() > 0)
|
|
{
|
|
edges.push_back(listEdge.front());
|
|
listEdge.pop_front();
|
|
}
|
|
|
|
if(edges.size() > 0)
|
|
{
|
|
edgeIndex.push_back(edges);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void BaseAlgo::GetWireSingleEdges( map<int, TopoDS_Edge>& mapEdge,vector<vector<int>>& edgeIndex )
|
|
{
|
|
map<int, bool> mapIsUse;
|
|
int MaxLengthID = -1;
|
|
double maxLength = -1;
|
|
gp_Pnt fp,ep;
|
|
|
|
double tol1 = Precision::Confusion() * 100;
|
|
double tol2 = Precision::Confusion() * 100;
|
|
|
|
|
|
list<int> listEdge;
|
|
list<gp_Pnt> pSet;
|
|
edgeIndex.clear();
|
|
|
|
if(mapEdge.size() == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//最长边
|
|
for(map<int, TopoDS_Edge>::iterator iter = mapEdge.begin(); iter != mapEdge.end(); iter++)
|
|
{
|
|
mapIsUse.insert(make_pair(iter->first,false));
|
|
|
|
double df,dl;
|
|
Handle(Geom_Curve) cv = BRep_Tool::Curve(iter->second, df,dl);
|
|
double len = dl -df;
|
|
gp_Pnt p1,p2;
|
|
GetEdgeStartEndPoint(iter->second, p1,p2);
|
|
len = p1.Distance(p2);
|
|
if(len > maxLength)
|
|
{
|
|
maxLength = len;
|
|
MaxLengthID = iter->first;
|
|
GetEdgeStartEndPoint(iter->second, fp,ep);
|
|
}
|
|
}
|
|
|
|
|
|
BRep_Builder builder;
|
|
TopoDS_Compound comp;
|
|
builder.MakeCompound(comp);
|
|
|
|
//以最长边为根
|
|
mapIsUse[MaxLengthID] = true;
|
|
builder.Add(comp, mapEdge[MaxLengthID]);
|
|
listEdge.push_back(MaxLengthID);
|
|
mapEdge[MaxLengthID].Orientation(TopAbs_FORWARD);
|
|
pSet.push_back(fp);
|
|
pSet.push_back(ep);
|
|
|
|
|
|
int numUnuse = mapIsUse.size() - 1;
|
|
|
|
while(numUnuse !=0)
|
|
{
|
|
int temp = numUnuse;
|
|
bool isClosed = false;
|
|
//单边闭合
|
|
if(ep.Distance(fp)<Precision::Confusion() * 100)
|
|
{
|
|
isClosed = true;
|
|
}
|
|
|
|
for(map<int, TopoDS_Edge>::iterator iter = mapEdge.begin(); iter != mapEdge.end() && !isClosed; iter++)
|
|
{
|
|
if(mapIsUse[iter->first])
|
|
{
|
|
continue;
|
|
}
|
|
double df,dl;
|
|
gp_Pnt p1,p2;
|
|
TopoDS_Vertex v1,v2;
|
|
GetEdgeStartEndPoint(iter->second, p1,p2);
|
|
|
|
if(p1.Distance(fp) < tol1)
|
|
{
|
|
int count = 0;
|
|
for(list<gp_Pnt>::iterator it = pSet.begin(); it != pSet.end(); it++,count++)
|
|
{
|
|
gp_Pnt p = *it;
|
|
if(p2.Distance(p) < tol2)
|
|
{
|
|
isClosed = true;
|
|
break;
|
|
}
|
|
}
|
|
if(isClosed)//闭合
|
|
{
|
|
//重复边
|
|
vector<int> edgeId;
|
|
while(listEdge.size() > 0)
|
|
{
|
|
edgeId.push_back(listEdge.front());
|
|
listEdge.pop_front();
|
|
}
|
|
|
|
for(int i = 0; i < edgeId.size(); i++)
|
|
{
|
|
listEdge.push_back(edgeId[i]);
|
|
}
|
|
|
|
for(int i = 0; i < edgeId.size(); i++)
|
|
{
|
|
if(CheckTwoEdgeOverlapByLinePointProject(mapEdge[edgeId[i]], iter->second))
|
|
{
|
|
mapIsUse[iter->first] = true;
|
|
numUnuse--;
|
|
isClosed = false;
|
|
break;
|
|
}
|
|
}
|
|
if(!isClosed)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
builder.Add(comp, iter->second);
|
|
fp = p2;
|
|
listEdge.push_front(iter->first);
|
|
pSet.push_front(fp);
|
|
mapEdge[iter->first].Orientation(TopAbs_REVERSED);
|
|
mapIsUse[iter->first] = true;
|
|
numUnuse--;
|
|
|
|
list<int> tmpListEdge;
|
|
for(int i = 0; i <= count; i++)
|
|
{
|
|
tmpListEdge.push_back(listEdge.front());
|
|
listEdge.pop_front();
|
|
}
|
|
|
|
//修改闭合外的标记
|
|
while(listEdge.size() > 0)
|
|
{
|
|
int id = listEdge.front();
|
|
listEdge.pop_front();
|
|
mapIsUse[id] = false;
|
|
numUnuse++;
|
|
}
|
|
|
|
while(tmpListEdge.size() > 0)
|
|
{
|
|
listEdge.push_back(tmpListEdge.front());
|
|
tmpListEdge.pop_front();
|
|
}
|
|
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(p2).Vertex();
|
|
BRepExtrema_DistShapeShape inter(v,comp);
|
|
if(inter.IsDone())
|
|
{
|
|
if( inter.Value() > tol2)
|
|
{
|
|
builder.Add(comp, iter->second);
|
|
fp = p2;
|
|
listEdge.push_front(iter->first);
|
|
pSet.push_front(fp);
|
|
mapEdge[iter->first].Orientation(TopAbs_REVERSED);
|
|
mapIsUse[iter->first] = true;
|
|
numUnuse--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if(p2.Distance(fp) < tol1)
|
|
{
|
|
int count = 0;
|
|
for(list<gp_Pnt>::iterator it = pSet.begin(); it != pSet.end(); it++,count++)
|
|
{
|
|
gp_Pnt p = *it;
|
|
if(p1.Distance(p) < tol2)
|
|
{
|
|
isClosed = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(isClosed)//闭合
|
|
{
|
|
//重复边
|
|
vector<int> edgeId;
|
|
while(listEdge.size() > 0)
|
|
{
|
|
edgeId.push_back(listEdge.front());
|
|
listEdge.pop_front();
|
|
}
|
|
|
|
for(int i = 0; i < edgeId.size(); i++)
|
|
{
|
|
listEdge.push_back(edgeId[i]);
|
|
}
|
|
|
|
for(int i = 0; i < edgeId.size(); i++)
|
|
{
|
|
if(CheckTwoEdgeOverlapByLinePointProject(mapEdge[edgeId[i]], iter->second))
|
|
{
|
|
mapIsUse[iter->first] = true;
|
|
numUnuse--;
|
|
isClosed = false;
|
|
break;
|
|
}
|
|
}
|
|
if(!isClosed)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
builder.Add(comp, iter->second);
|
|
fp = p1;
|
|
listEdge.push_front(iter->first);
|
|
pSet.push_front(fp);
|
|
mapEdge[iter->first].Orientation(TopAbs_FORWARD);
|
|
mapIsUse[iter->first] = true;
|
|
numUnuse--;
|
|
|
|
list<int> tmpListEdge;
|
|
for(int i = 0; i <= count; i++)
|
|
{
|
|
tmpListEdge.push_back(listEdge.front());
|
|
listEdge.pop_front();
|
|
}
|
|
|
|
//修改闭合外的标记
|
|
while(listEdge.size() > 0)
|
|
{
|
|
int id = listEdge.front();
|
|
listEdge.pop_front();
|
|
mapIsUse[id] = false;
|
|
numUnuse++;
|
|
}
|
|
|
|
while(tmpListEdge.size() > 0)
|
|
{
|
|
listEdge.push_back(tmpListEdge.front());
|
|
tmpListEdge.pop_front();
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(p1).Vertex();
|
|
BRepExtrema_DistShapeShape inter(v,comp);
|
|
if(inter.IsDone())
|
|
{
|
|
if( inter.Value() > tol2)
|
|
{
|
|
builder.Add(comp, iter->second);
|
|
fp = p1;
|
|
listEdge.push_front(iter->first);
|
|
pSet.push_front(fp);
|
|
mapEdge[iter->first].Orientation(TopAbs_FORWARD);
|
|
mapIsUse[iter->first] = true;
|
|
numUnuse--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if(p1.Distance(ep) < tol1)
|
|
{
|
|
int count = 0;
|
|
for(list<gp_Pnt>::reverse_iterator it = pSet.rbegin(); it != pSet.rend(); it++,count++)
|
|
{
|
|
gp_Pnt p = *it;
|
|
if(p2.Distance(p) < tol2)
|
|
{
|
|
isClosed = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(isClosed)//闭合
|
|
{
|
|
//重复边
|
|
vector<int> edgeId;
|
|
while(listEdge.size() > 0)
|
|
{
|
|
edgeId.push_back(listEdge.front());
|
|
listEdge.pop_front();
|
|
}
|
|
|
|
for(int i = 0; i < edgeId.size(); i++)
|
|
{
|
|
listEdge.push_back(edgeId[i]);
|
|
}
|
|
|
|
for(int i = 0; i < edgeId.size(); i++)
|
|
{
|
|
if(CheckTwoEdgeOverlapByLinePointProject(mapEdge[edgeId[i]], iter->second))
|
|
{
|
|
mapIsUse[iter->first] = true;
|
|
numUnuse--;
|
|
isClosed = false;
|
|
break;
|
|
}
|
|
}
|
|
if(!isClosed)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
builder.Add(comp, iter->second);
|
|
ep = p2;
|
|
listEdge.push_back(iter->first);
|
|
pSet.push_back(ep);
|
|
mapEdge[iter->first].Orientation(TopAbs_FORWARD);
|
|
mapIsUse[iter->first] = true;
|
|
numUnuse--;
|
|
|
|
list<int> tmpListEdge;
|
|
for(int i = 0; i <= count; i++)
|
|
{
|
|
tmpListEdge.push_front(listEdge.back());
|
|
listEdge.pop_back();
|
|
}
|
|
|
|
//修改闭合外的标记
|
|
while(listEdge.size() > 0)
|
|
{
|
|
int id = listEdge.front();
|
|
listEdge.pop_front();
|
|
mapIsUse[id] = false;
|
|
numUnuse++;
|
|
}
|
|
|
|
while(tmpListEdge.size() > 0)
|
|
{
|
|
listEdge.push_back(tmpListEdge.front());
|
|
tmpListEdge.pop_front();
|
|
}
|
|
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(p2).Vertex();
|
|
BRepExtrema_DistShapeShape inter(v,comp);
|
|
if(inter.IsDone())
|
|
{
|
|
if( inter.Value() > tol2)
|
|
{
|
|
builder.Add(comp, iter->second);
|
|
ep = p2;
|
|
listEdge.push_back(iter->first);
|
|
pSet.push_back(ep);
|
|
mapEdge[iter->first].Orientation(TopAbs_FORWARD);
|
|
mapIsUse[iter->first] = true;
|
|
numUnuse--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if(p2.Distance(ep) < tol1)
|
|
{
|
|
int count = 0;
|
|
for(list<gp_Pnt>::reverse_iterator it = pSet.rbegin(); it != pSet.rend(); it++,count++)
|
|
{
|
|
gp_Pnt p = *it;
|
|
if(p1.Distance(p) < tol2)
|
|
{
|
|
isClosed = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(isClosed)//闭合
|
|
{
|
|
//重复边
|
|
vector<int> edgeId;
|
|
while(listEdge.size() > 0)
|
|
{
|
|
edgeId.push_back(listEdge.front());
|
|
listEdge.pop_front();
|
|
}
|
|
|
|
for(int i = 0; i < edgeId.size(); i++)
|
|
{
|
|
listEdge.push_back(edgeId[i]);
|
|
}
|
|
|
|
for(int i = 0; i < edgeId.size(); i++)
|
|
{
|
|
if(CheckTwoEdgeOverlapByLinePointProject(mapEdge[edgeId[i]], iter->second))
|
|
{
|
|
mapIsUse[iter->first] = true;
|
|
numUnuse--;
|
|
isClosed = false;
|
|
break;
|
|
}
|
|
}
|
|
if(!isClosed)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
builder.Add(comp, iter->second);
|
|
ep = p1;
|
|
listEdge.push_back(iter->first);
|
|
pSet.push_back(ep);
|
|
mapEdge[iter->first].Reverse();
|
|
mapEdge[iter->first].Orientation(TopAbs_REVERSED);
|
|
mapIsUse[iter->first] = true;
|
|
numUnuse--;
|
|
|
|
list<int> tmpListEdge;
|
|
for(int i = 0; i <= count; i++)
|
|
{
|
|
tmpListEdge.push_front(listEdge.back());
|
|
listEdge.pop_back();
|
|
}
|
|
|
|
//修改闭合外的标记
|
|
while(listEdge.size() > 0)
|
|
{
|
|
int id = listEdge.front();
|
|
listEdge.pop_front();
|
|
mapIsUse[id] = false;
|
|
numUnuse++;
|
|
}
|
|
|
|
while(tmpListEdge.size() > 0)
|
|
{
|
|
listEdge.push_back(tmpListEdge.front());
|
|
tmpListEdge.pop_front();
|
|
}
|
|
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(p1).Vertex();
|
|
BRepExtrema_DistShapeShape inter(v,comp);
|
|
if(inter.IsDone())
|
|
{
|
|
if( inter.Value() > tol2)
|
|
{
|
|
builder.Add(comp, iter->second);
|
|
ep = p1;
|
|
listEdge.push_back(iter->first);
|
|
pSet.push_back(ep);
|
|
mapEdge[iter->first].Reverse();
|
|
mapEdge[iter->first].Orientation(TopAbs_REVERSED);
|
|
mapIsUse[iter->first] = true;
|
|
numUnuse--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//if(mapIsUse[iter->first])
|
|
//{
|
|
// MaxLengthID = iter->first;
|
|
// numUnuse--;
|
|
//}
|
|
}// for(map<int, TopoDS_Edge>::iterator iter = mapEdge.begin(); iter != mapEdge.end(); iter++)
|
|
|
|
if(isClosed ||numUnuse == temp || numUnuse == 0)
|
|
{
|
|
vector<int> edges;
|
|
while(listEdge.size() > 0)
|
|
{
|
|
edges.push_back(listEdge.front());
|
|
listEdge.pop_front();
|
|
}
|
|
|
|
if(edges.size() > 0)
|
|
{
|
|
edgeIndex.push_back(edges);
|
|
}
|
|
|
|
//排除小短边和重复边
|
|
|
|
for(map<int, TopoDS_Edge>::iterator iter = mapEdge.begin(); iter != mapEdge.end(); iter++)
|
|
{
|
|
if(mapIsUse[iter->first])
|
|
{
|
|
continue;
|
|
}
|
|
|
|
double df,dl;
|
|
Handle(Geom_Curve) cv = BRep_Tool::Curve(iter->second, df,dl);
|
|
double len = dl -df;
|
|
|
|
gp_Pnt p1,p2,pMid;
|
|
GetEdgeStartEndPoint(iter->second, p1,p2);
|
|
TopoDS_Vertex v1,v2,vMid;
|
|
TopExp::Vertices(iter->second, v1,v2);
|
|
|
|
pMid = cv->Value((dl+df)/2);
|
|
vMid = BRepBuilderAPI_MakeVertex(pMid);
|
|
|
|
bool isP1On = false;
|
|
bool isP2On = false;
|
|
bool isPMidOn = false;
|
|
|
|
for(int k = 0; k < edges.size(); k++)
|
|
{
|
|
int index = edges[k];
|
|
TopoDS_Edge edge = mapEdge[index];
|
|
|
|
if(!isP1On)
|
|
{
|
|
BRepExtrema_DistShapeShape inter1(v1,edge);
|
|
inter1.Perform();
|
|
if(inter1.Value() < tol1)
|
|
{
|
|
isP1On = true;
|
|
}
|
|
}
|
|
|
|
if(!isP2On)
|
|
{
|
|
BRepExtrema_DistShapeShape inter2(v2,edge);
|
|
inter2.Perform();
|
|
if(inter2.Value() < tol1)
|
|
{
|
|
isP2On = true;
|
|
}
|
|
}
|
|
|
|
if(!isPMidOn)
|
|
{
|
|
BRepExtrema_DistShapeShape inter3(vMid,edge);
|
|
inter3.Perform();
|
|
if(inter3.Value() < tol1)
|
|
{
|
|
isPMidOn = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(isP2On && isP1On && isPMidOn)
|
|
{
|
|
mapIsUse[iter->first] = true;
|
|
numUnuse--;
|
|
}
|
|
}
|
|
|
|
//重新初始
|
|
maxLength = -1;
|
|
pSet.clear();
|
|
for(map<int, TopoDS_Edge>::iterator iter = mapEdge.begin(); iter != mapEdge.end(); iter++)
|
|
{
|
|
if(mapIsUse[iter->first])
|
|
{
|
|
continue;
|
|
}
|
|
|
|
double df,dl;
|
|
Handle(Geom_Curve) cv = BRep_Tool::Curve(iter->second, df,dl);
|
|
double len = dl -df;
|
|
gp_Pnt p1,p2;
|
|
GetEdgeStartEndPoint(iter->second, p1,p2);
|
|
len = p1.Distance(p2);
|
|
if(len > maxLength)
|
|
{
|
|
maxLength = len;
|
|
TopExp_Explorer ex(iter->second, TopAbs_VERTEX);
|
|
MaxLengthID = iter->first;
|
|
GetEdgeStartEndPoint(iter->second, fp,ep);
|
|
}
|
|
}
|
|
|
|
if(maxLength > -1)
|
|
{
|
|
mapIsUse[MaxLengthID] = true;
|
|
TopoDS_Compound c;
|
|
comp = c;
|
|
builder.MakeCompound(comp);
|
|
builder.Add(comp, mapEdge[MaxLengthID]);
|
|
listEdge.push_back(MaxLengthID);
|
|
pSet.push_back(fp);
|
|
pSet.push_back(ep);
|
|
mapEdge[MaxLengthID].Orientation(TopAbs_FORWARD);
|
|
numUnuse--;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(listEdge.size() > 0)
|
|
{
|
|
vector<int> edges;
|
|
while(listEdge.size() > 0)
|
|
{
|
|
edges.push_back(listEdge.front());
|
|
listEdge.pop_front();
|
|
}
|
|
|
|
if(edges.size() > 0)
|
|
{
|
|
edgeIndex.push_back(edges);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
bool BaseAlgo::CheckTwoEdgeOverlapByLinePointProject(TopoDS_Edge& tedgeA,TopoDS_Edge& tedgeB)
|
|
{
|
|
//The function compares if the bounding boxes of edgeA and edgeB are touching or intersecting
|
|
//each other 交点法判断线线重叠(包含部分重叠)
|
|
Standard_Real dF,dL,dF2,dL2;
|
|
|
|
if(tedgeA.IsNull() || tedgeB.IsNull())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Handle(Geom_Curve) cvA = BRep_Tool::Curve(tedgeA,dF,dL);
|
|
Handle(Geom_Curve) cvB = BRep_Tool::Curve(tedgeB,dF2,dL2);
|
|
|
|
Standard_Real tol = Precision::Confusion() * 1000;
|
|
|
|
gp_Pnt sp1 = cvA->Value(dF);
|
|
gp_Pnt ep1 = cvA->Value(dL);
|
|
gp_Pnt sp2 = cvB->Value(dF2);
|
|
gp_Pnt ep2 = cvB->Value(dL2);
|
|
|
|
GetEdgeStartEndPoint(tedgeA, sp1, ep1);
|
|
GetEdgeStartEndPoint(tedgeB, sp2, ep2);
|
|
|
|
vector<gp_Pnt> pointOnEdgeA;
|
|
vector<gp_Pnt> pointOnEdgeB;
|
|
|
|
//#pragma region 边的投影点
|
|
BRepExtrema_DistShapeShape inter1(BRepBuilderAPI_MakeVertex(sp1),tedgeB);
|
|
inter1.Perform();
|
|
if(inter1.Value() < tol)
|
|
{
|
|
gp_Pnt p = inter1.PointOnShape2(1);
|
|
if(p.Distance(sp2) < tol)
|
|
{
|
|
pointOnEdgeB.push_back(sp2);
|
|
}
|
|
else if(p.Distance(ep2) < tol)
|
|
{
|
|
pointOnEdgeB.push_back(ep2);
|
|
}
|
|
else
|
|
{
|
|
pointOnEdgeB.push_back(p);
|
|
}
|
|
pointOnEdgeA.push_back(sp1);
|
|
}
|
|
|
|
BRepExtrema_DistShapeShape inter2(BRepBuilderAPI_MakeVertex(ep1),tedgeB);
|
|
inter2.Perform();
|
|
if(inter2.Value() < tol)
|
|
{
|
|
gp_Pnt p = inter2.PointOnShape2(1);
|
|
if(p.Distance(sp2) < tol)
|
|
{
|
|
pointOnEdgeB.push_back(sp2);
|
|
}
|
|
else if(p.Distance(ep2) < tol)
|
|
{
|
|
pointOnEdgeB.push_back(ep2);
|
|
}
|
|
else
|
|
{
|
|
pointOnEdgeB.push_back(p);
|
|
}
|
|
pointOnEdgeA.push_back(ep1);
|
|
}
|
|
|
|
BRepExtrema_DistShapeShape inter3(BRepBuilderAPI_MakeVertex(sp2),tedgeA);
|
|
inter3.Perform();
|
|
if(inter3.Value() < tol)
|
|
{
|
|
gp_Pnt p = inter3.PointOnShape2(1);
|
|
if(p.Distance(sp1) < tol)
|
|
{
|
|
pointOnEdgeA.push_back(sp1);
|
|
}
|
|
else if(p.Distance(ep1) < tol)
|
|
{
|
|
pointOnEdgeA.push_back(ep1);
|
|
}
|
|
else
|
|
{
|
|
pointOnEdgeA.push_back(p);
|
|
}
|
|
pointOnEdgeB.push_back(sp2);
|
|
}
|
|
|
|
BRepExtrema_DistShapeShape inter4(BRepBuilderAPI_MakeVertex(ep2),tedgeA);
|
|
inter4.Perform();
|
|
if(inter4.Value() < tol)
|
|
{
|
|
gp_Pnt p = inter4.PointOnShape2(1);
|
|
if(p.Distance(sp1) < tol)
|
|
{
|
|
pointOnEdgeA.push_back(sp1);
|
|
}
|
|
else if(p.Distance(ep1) < tol)
|
|
{
|
|
pointOnEdgeA.push_back(ep1);
|
|
}
|
|
else
|
|
{
|
|
pointOnEdgeA.push_back(p);
|
|
}
|
|
pointOnEdgeB.push_back(ep2);
|
|
}
|
|
//#pragma endregion
|
|
|
|
TopoDS_Edge edgeA, edgeB;
|
|
|
|
DeleteSamePoint(pointOnEdgeA, tol);
|
|
DeleteSamePoint(pointOnEdgeB, tol);
|
|
|
|
if(pointOnEdgeA.size() != 2 || pointOnEdgeB.size() != 2)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
gp_Pnt p1, p2;
|
|
Standard_Real para1, para2;
|
|
//截取A边可能到公共部分
|
|
p1 = pointOnEdgeA[0];
|
|
p2 = pointOnEdgeA[1];
|
|
if(p1.Distance(p2) < tol)
|
|
{
|
|
return false;
|
|
}
|
|
//GeomAPI_ProjectPointOnCurve Projector1 (p1, cvA); //gp_Pnt Bpnt
|
|
//GeomAPI_ProjectPointOnCurve Projector2 (p2, cvA); //gp_Pnt Bpnt
|
|
//para1 = Projector1.LowerDistanceParameter();
|
|
//para2 = Projector2.LowerDistanceParameter();
|
|
para1 = ProjectPointOnCurvePara(tedgeA, p1);
|
|
para2 = ProjectPointOnCurvePara(tedgeA, p2);
|
|
|
|
if(para1 > para2)
|
|
{
|
|
Standard_Real tmp = para2;
|
|
para2 = para1;
|
|
para1 = tmp;
|
|
}
|
|
Handle(Geom_TrimmedCurve) myTrimmed1 = new Geom_TrimmedCurve(cvA, para1, para2);
|
|
edgeA = BRepBuilderAPI_MakeEdge(myTrimmed1);
|
|
//截取B边可能的公共部分
|
|
p1 = pointOnEdgeB[0];
|
|
p2 = pointOnEdgeB[1];
|
|
if(p1.Distance(p2) < tol)
|
|
{
|
|
return false;
|
|
}
|
|
//GeomAPI_ProjectPointOnCurve Projector3 (p1, cvB); //gp_Pnt Bpnt
|
|
//GeomAPI_ProjectPointOnCurve Projector4 (p2, cvB); //gp_Pnt Bpnt
|
|
//para1 = Projector3.LowerDistanceParameter();
|
|
//para2 = Projector4.LowerDistanceParameter();
|
|
|
|
para1 = ProjectPointOnCurvePara(tedgeB, p1);
|
|
para2 = ProjectPointOnCurvePara(tedgeB, p2);
|
|
|
|
if(para1 > para2)
|
|
{
|
|
Standard_Real tmp = para2;
|
|
para2 = para1;
|
|
para1 = tmp;
|
|
}
|
|
Handle(Geom_TrimmedCurve) myTrimmed2 = new Geom_TrimmedCurve(cvB, para1, para2);
|
|
edgeB = BRepBuilderAPI_MakeEdge(myTrimmed2);
|
|
//采样法 采样点都在另一条边上 返回true
|
|
double step = (para2 - para1) / 100;
|
|
while (para1 < para2)
|
|
{
|
|
gp_Pnt p = cvB->Value(para1);
|
|
TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(p).Vertex();
|
|
BRepExtrema_DistShapeShape inter(v,edgeA);
|
|
inter.Perform();
|
|
if(inter.Value() > tol)
|
|
{
|
|
return false;
|
|
}
|
|
para1 += step;
|
|
}
|
|
return true;
|
|
|
|
}
|
|
|
|
void BaseAlgo::DeleteSamePoint(vector<gp_Pnt>& pSet, double tol)
|
|
{
|
|
vector<gp_Pnt> pSetTmp;
|
|
|
|
if(pSet.size() == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for(int i = 0; i < pSet.size(); i++)
|
|
{
|
|
pSetTmp.push_back(pSet[i]);
|
|
}
|
|
pSet.clear();
|
|
for(int i = 0; i < pSetTmp.size(); i++)
|
|
{
|
|
bool isFind = false;
|
|
for(int j = i +1; j < pSetTmp.size(); j++)
|
|
{
|
|
if(pSetTmp[i].Distance(pSetTmp[j]) < tol)
|
|
{
|
|
isFind = true;
|
|
break;
|
|
}
|
|
}
|
|
if(isFind)
|
|
{
|
|
continue;
|
|
}
|
|
pSet.push_back(pSetTmp[i]);
|
|
}
|
|
}
|
|
|
|
bool BaseAlgo::GetConnectEdge(std::map<int, TopoDS_Edge>& mapEdge,std::vector<int> edgeIndex, TopoDS_Face &face, TopoDS_Edge& edge1, TopoDS_Edge& edge2, bool& isEdge1, bool& isEdge2)
|
|
{
|
|
if(edgeIndex.size() == 0)
|
|
{
|
|
return false;
|
|
}
|
|
gp_Pnt sp, ep;
|
|
TopoDS_Vertex sv;
|
|
TopoDS_Vertex ev;
|
|
TopoDS_Vertex sv1;
|
|
TopoDS_Vertex ev1;
|
|
|
|
TopoDS_Vertex sv2;
|
|
TopoDS_Vertex ev2;
|
|
|
|
TopoDS_Vertex sv3;
|
|
TopoDS_Vertex ev3;
|
|
|
|
TopoDS_Vertex sv4;
|
|
TopoDS_Vertex ev4;
|
|
|
|
if(edgeIndex.size() == 1)
|
|
{
|
|
TopExp::Vertices(mapEdge[edgeIndex[0]],sv,ev);
|
|
GetEdgeStartEndPoint(mapEdge[edgeIndex[0]], sp,ep);
|
|
sv1 = sv;
|
|
sv3 = sv;
|
|
ev1 = ev;
|
|
ev3 = ev;
|
|
}
|
|
else if(edgeIndex.size() == 2)
|
|
{
|
|
gp_Pnt sp1, ep1;
|
|
gp_Pnt sp2, ep2;
|
|
|
|
TopExp::Vertices(mapEdge[edgeIndex[0]],sv1,ev1);
|
|
TopExp::Vertices(mapEdge[edgeIndex[1]],sv2,ev2);
|
|
GetEdgeStartEndPoint(mapEdge[edgeIndex[0]], sp1,ep1);
|
|
GetEdgeStartEndPoint(mapEdge[edgeIndex[1]], sp2,ep2);
|
|
|
|
if(sp1.Distance(sp2) < Precision::Confusion() * 100)
|
|
{
|
|
sp = ep1;
|
|
sv = ev1;
|
|
ep = ep2;
|
|
ev = ev2;
|
|
}
|
|
else if(sp1.Distance(ep2) < Precision::Confusion() * 100)
|
|
{
|
|
sp = ep1;
|
|
sv = ev1;
|
|
ep = sp2;
|
|
ev = sv2;
|
|
}
|
|
else if(ep1.Distance(sp2) < Precision::Confusion() * 100)
|
|
{
|
|
sp = sp1;
|
|
sv = sv1;
|
|
ep = ep2;
|
|
ev = ev2;
|
|
}
|
|
else if(ep1.Distance(ep2) < Precision::Confusion() * 100)
|
|
{
|
|
sp = sp1;
|
|
sv = sv1;
|
|
ep = sp2;
|
|
ev = sv2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
gp_Pnt sp1, ep1;
|
|
gp_Pnt sp2, ep2;
|
|
|
|
TopExp::Vertices(mapEdge[edgeIndex[0]],sv1,ev1);
|
|
TopExp::Vertices(mapEdge[edgeIndex[1]],sv2,ev2);
|
|
GetEdgeStartEndPoint(mapEdge[edgeIndex[0]], sp1,ep1);
|
|
GetEdgeStartEndPoint(mapEdge[edgeIndex[1]], sp2,ep2);
|
|
|
|
if(sp1.Distance(sp2) < Precision::Confusion() * 100 || sp1.Distance(ep2) < Precision::Confusion() * 100)
|
|
{
|
|
sp = ep1;
|
|
sv = ev1;
|
|
}
|
|
else
|
|
{
|
|
sp = sp1;
|
|
sv = sv1;
|
|
}
|
|
|
|
|
|
TopExp::Vertices(mapEdge[edgeIndex[edgeIndex.size() - 1]],sv3,ev3);
|
|
TopExp::Vertices(mapEdge[edgeIndex[edgeIndex.size() - 2]],sv4,ev4);
|
|
GetEdgeStartEndPoint(mapEdge[edgeIndex[edgeIndex.size() - 1]], sp1,ep1);
|
|
GetEdgeStartEndPoint(mapEdge[edgeIndex[edgeIndex.size() - 2 ]], sp2,ep2);
|
|
|
|
if(sp1.Distance(sp2) < Precision::Confusion() * 100 || sp1.Distance(ep2) < Precision::Confusion() * 100)
|
|
{
|
|
ep = ep1;
|
|
ev = ev3;
|
|
}
|
|
else
|
|
{
|
|
ep = sp1;
|
|
ev = sv3;
|
|
}
|
|
}
|
|
double dis = ep.Distance(sp) ;
|
|
//闭合曲线 不加边
|
|
if(ep.Distance(sp) < Precision::Confusion() * 10000)
|
|
{
|
|
return true;
|
|
}
|
|
else if(ep.Distance(sp) < Precision::Confusion())
|
|
{
|
|
|
|
}
|
|
|
|
Standard_Real dmin = 10000;
|
|
gp_Pnt p;
|
|
|
|
for(TopExp_Explorer ex(face, TopAbs_EDGE); ex.More(); ex.Next())
|
|
{
|
|
gp_Pnt tmp;
|
|
TopoDS_Edge edge = TopoDS::Edge(ex.Current());
|
|
gp_Pnt p1,p2;
|
|
GetEdgeStartEndPoint(edge, p1,p2);
|
|
if(p1.Distance(p2) < Precision::Confusion())
|
|
{
|
|
continue;
|
|
}
|
|
Standard_Real dis = Project(sv, edge, tmp);
|
|
if(dis < dmin)
|
|
{
|
|
p = tmp;
|
|
dmin = dis;
|
|
}
|
|
}
|
|
|
|
if(dmin > Precision::Confusion() *10000)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if(dmin > Precision::Confusion() * 10)
|
|
{
|
|
|
|
TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(p).Vertex();
|
|
Standard_Real tol = BRep_Tool::Tolerance(sv);
|
|
BRep_Builder b;
|
|
b.UpdateVertex(v, tol);
|
|
gp_Pnt tmp;
|
|
|
|
TopoDS_Vertex vv;
|
|
if(sv.IsSame(ev1))
|
|
{
|
|
Standard_Real para1 = BRep_Tool::Parameter(sv1,mapEdge[edgeIndex[0]]);
|
|
Standard_Real para2 = BRep_Tool::Parameter(ev1,mapEdge[edgeIndex[0]]);
|
|
Standard_Real paratemp ;
|
|
double df,dl;
|
|
Handle(Geom_Curve) C;
|
|
C = BRep_Tool::Curve(mapEdge[edgeIndex[0]],df,dl);
|
|
|
|
paratemp = para2;
|
|
|
|
gp_Pnt p1 =C->Value(paratemp);
|
|
|
|
Standard_Real dis = Project(v, mapEdge[edgeIndex[0]], tmp);
|
|
if(tmp.Distance(p1) > Precision::Confusion())
|
|
{
|
|
p1 = tmp;
|
|
}
|
|
|
|
while(p1.Distance(p) < 1E-5)
|
|
{
|
|
paratemp = paratemp - 1E-5;
|
|
p1 = C->Value(paratemp);
|
|
|
|
vv = BRepBuilderAPI_MakeVertex(p1);
|
|
b.UpdateVertex(vv,paratemp, mapEdge[edgeIndex[0]], BRep_Tool::Tolerance(mapEdge[edgeIndex[0]]));
|
|
TopoDS_Edge E = BRepBuilderAPI_MakeEdge(C,sv1,vv,df,paratemp);
|
|
PutPCurve(E, face);
|
|
mapEdge[edgeIndex[0]] = E;
|
|
}
|
|
|
|
gp_Pnt pp =C->Value(paratemp);
|
|
vv = BRepBuilderAPI_MakeVertex(pp);
|
|
b.UpdateVertex(vv,paratemp, mapEdge[edgeIndex[0]], BRep_Tool::Tolerance(mapEdge[edgeIndex[0]]));
|
|
}
|
|
else
|
|
{
|
|
Standard_Real para1 = BRep_Tool::Parameter(sv1,mapEdge[edgeIndex[0]]);
|
|
Standard_Real para2 = BRep_Tool::Parameter(ev1,mapEdge[edgeIndex[0]]);
|
|
Standard_Real paratemp ;
|
|
double df,dl;
|
|
Handle(Geom_Curve) C;
|
|
C = BRep_Tool::Curve(mapEdge[edgeIndex[0]],df,dl);
|
|
|
|
paratemp = para1;
|
|
|
|
gp_Pnt p1 =C->Value(paratemp);
|
|
|
|
Standard_Real dis = Project(v, mapEdge[edgeIndex[0]], tmp);
|
|
if(tmp.Distance(p1) > Precision::Confusion())
|
|
{
|
|
p1 = tmp;
|
|
}
|
|
|
|
while(p1.Distance(p) < 1E-5)
|
|
{
|
|
paratemp = paratemp + 1E-5;
|
|
p1 = C->Value(paratemp);
|
|
|
|
vv = BRepBuilderAPI_MakeVertex(p1);
|
|
b.UpdateVertex(vv,paratemp, mapEdge[edgeIndex[0]], BRep_Tool::Tolerance(mapEdge[edgeIndex[0]]));
|
|
TopoDS_Edge E = BRepBuilderAPI_MakeEdge(C,vv,ev1,paratemp,dl);
|
|
PutPCurve(E, face);
|
|
mapEdge[edgeIndex[0]] = E;
|
|
}
|
|
|
|
gp_Pnt pp =C->Value(paratemp);
|
|
vv = BRepBuilderAPI_MakeVertex(pp);
|
|
b.UpdateVertex(vv,paratemp, mapEdge[edgeIndex[0]], BRep_Tool::Tolerance(mapEdge[edgeIndex[0]]));
|
|
}
|
|
edge1 = BRepBuilderAPI_MakeEdge(v, vv);
|
|
PutPCurve(edge1, face);
|
|
//TopoDS_Vertex Vfirst,Vlast;
|
|
//TopExp::Vertices(edge1,Vfirst,Vlast);
|
|
//tol = BRep_Tool::Tolerance(Vfirst);
|
|
//tol = BRep_Tool::Tolerance(Vlast);
|
|
//BRepTools::Write(edge1, "c:\\b.brep");
|
|
//BRepTools::Write(mapEdge[edgeIndex[0]], "c:\\c.brep");
|
|
isEdge1 = true;
|
|
}
|
|
|
|
|
|
dmin = 10000;
|
|
for(TopExp_Explorer ex(face, TopAbs_EDGE); ex.More(); ex.Next())
|
|
{
|
|
gp_Pnt tmp;
|
|
TopoDS_Edge edge = TopoDS::Edge(ex.Current());
|
|
gp_Pnt p1,p2;
|
|
GetEdgeStartEndPoint(edge, p1,p2);
|
|
if(p1.Distance(p2) < Precision::Confusion())
|
|
{
|
|
continue;
|
|
}
|
|
Standard_Real dis = Project(ev, edge, tmp);
|
|
if(dis < dmin)
|
|
{
|
|
p = tmp;
|
|
dmin = dis;
|
|
}
|
|
}
|
|
|
|
if(dmin > Precision::Confusion() *10000)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if(dmin > Precision::Confusion() * 10)
|
|
{
|
|
TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(p).Vertex();
|
|
Standard_Real tol = BRep_Tool::Tolerance(sv);
|
|
gp_Pnt tmp;
|
|
BRep_Builder b;
|
|
b.UpdateVertex(v, tol);
|
|
|
|
TopoDS_Vertex vv;
|
|
if(ev.IsSame(ev3))
|
|
{
|
|
Standard_Real para1 = BRep_Tool::Parameter(sv3,mapEdge[edgeIndex[edgeIndex.size() - 1]]);
|
|
Standard_Real para2 = BRep_Tool::Parameter(ev3,mapEdge[edgeIndex[edgeIndex.size() - 1]]);
|
|
Standard_Real paratemp ;
|
|
double df,dl;
|
|
Handle(Geom_Curve) C;
|
|
C = BRep_Tool::Curve(mapEdge[edgeIndex[edgeIndex.size() - 1]],df,dl);
|
|
|
|
paratemp = para2;
|
|
|
|
gp_Pnt p1 =C->Value(paratemp);
|
|
|
|
Standard_Real dis = Project(v, mapEdge[edgeIndex[edgeIndex.size() - 1]], tmp);
|
|
if(tmp.Distance(p1) > Precision::Confusion())
|
|
{
|
|
p1 = tmp;
|
|
}
|
|
|
|
while(p1.Distance(p) < 1E-5)
|
|
{
|
|
paratemp = paratemp - 1E-5;
|
|
p1 = C->Value(paratemp);
|
|
|
|
vv = BRepBuilderAPI_MakeVertex(p1);
|
|
b.UpdateVertex(vv,paratemp, mapEdge[edgeIndex[edgeIndex.size() - 1]], BRep_Tool::Tolerance(mapEdge[edgeIndex[edgeIndex.size() - 1]]));
|
|
TopoDS_Edge E = BRepBuilderAPI_MakeEdge(C,sv3,vv,df,paratemp);
|
|
PutPCurve(E, face);
|
|
mapEdge[edgeIndex[edgeIndex.size() - 1]] = E;
|
|
}
|
|
|
|
gp_Pnt pp =C->Value(paratemp);
|
|
vv = BRepBuilderAPI_MakeVertex(pp);
|
|
b.UpdateVertex(vv,paratemp, mapEdge[edgeIndex[edgeIndex.size() - 1]], BRep_Tool::Tolerance(mapEdge[edgeIndex[edgeIndex.size() - 1]]));
|
|
}
|
|
else
|
|
{
|
|
Standard_Real para1 = BRep_Tool::Parameter(sv3,mapEdge[edgeIndex[edgeIndex.size() - 1]]);
|
|
Standard_Real para2 = BRep_Tool::Parameter(ev3,mapEdge[edgeIndex[edgeIndex.size() - 1]]);
|
|
Standard_Real paratemp ;
|
|
double df,dl;
|
|
Handle(Geom_Curve) C;
|
|
C = BRep_Tool::Curve(mapEdge[edgeIndex[edgeIndex.size() - 1]],df,dl);
|
|
|
|
paratemp = para1;
|
|
|
|
gp_Pnt p1 =C->Value(paratemp);
|
|
Standard_Real dis = Project(v, mapEdge[edgeIndex[edgeIndex.size() - 1]], tmp);
|
|
if(tmp.Distance(p1) > Precision::Confusion())
|
|
{
|
|
p1 = tmp;
|
|
}
|
|
|
|
while(p1.Distance(p) < 1E-5)
|
|
{
|
|
paratemp = paratemp + 1E-5;
|
|
p1 = C->Value(paratemp);
|
|
|
|
vv = BRepBuilderAPI_MakeVertex(p1);
|
|
b.UpdateVertex(vv,paratemp, mapEdge[edgeIndex[edgeIndex.size() - 1]], BRep_Tool::Tolerance(mapEdge[edgeIndex[edgeIndex.size() - 1]]));
|
|
TopoDS_Edge E = BRepBuilderAPI_MakeEdge(C,vv,ev3,paratemp,dl);
|
|
PutPCurve(E, face);
|
|
mapEdge[edgeIndex[edgeIndex.size() - 1]] = E;
|
|
}
|
|
|
|
gp_Pnt pp =C->Value(paratemp);
|
|
vv = BRepBuilderAPI_MakeVertex(pp);
|
|
b.UpdateVertex(vv,paratemp, mapEdge[edgeIndex[edgeIndex.size() - 1]], BRep_Tool::Tolerance(mapEdge[edgeIndex[edgeIndex.size() - 1]]));
|
|
}
|
|
|
|
|
|
edge2= BRepBuilderAPI_MakeEdge(vv, v);
|
|
isEdge2 = true;
|
|
PutPCurve(edge2, face);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
Standard_Real BaseAlgo::Project(const TopoDS_Vertex& V, const TopoDS_Edge& theEdge, gp_Pnt& p)
|
|
{
|
|
Handle(Geom_Curve) C;
|
|
TopLoc_Location Loc;
|
|
Standard_Real f,l;
|
|
|
|
gp_Pnt toproj(BRep_Tool::Pnt(V));
|
|
GeomAPI_ProjectPointOnCurve proj;
|
|
|
|
C = BRep_Tool::Curve(theEdge,Loc,f,l);
|
|
if (!Loc.IsIdentity()) {
|
|
Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
|
|
C = *((Handle(Geom_Curve)*)&GG);
|
|
}
|
|
proj.Init(toproj,C,f,l);
|
|
|
|
if(proj.NbPoints() > 0)
|
|
{
|
|
p = proj.NearestPoint();
|
|
return proj.LowerDistance();
|
|
}
|
|
return 100000;
|
|
}
|
|
|
|
void BaseAlgo::PutPCurve(const TopoDS_Edge& Edg, const TopoDS_Face& Fac)
|
|
{
|
|
BRep_Builder B;
|
|
TopLoc_Location LocFac;
|
|
|
|
Handle(Geom_Surface) S = BRep_Tool::Surface(Fac, LocFac);
|
|
Handle(Standard_Type) styp = S->DynamicType();
|
|
|
|
//if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
|
|
// S = (*((Handle(Geom_RectangularTrimmedSurface)*)&(S)))->BasisSurface();
|
|
// styp = S->DynamicType();
|
|
//}
|
|
|
|
//if (styp == STANDARD_TYPE(Geom_Plane)) {
|
|
// return;
|
|
//}
|
|
|
|
Standard_Real Umin,Umax,Vmin,Vmax;
|
|
BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
|
|
|
|
Standard_Real f,l;
|
|
if (!BRep_Tool::CurveOnSurface(Edg,Fac,f,l).IsNull()) {
|
|
return;
|
|
}
|
|
|
|
TopLoc_Location Loc;
|
|
Handle(Geom_Curve) C = BRep_Tool::Curve(Edg,Loc,f,l);
|
|
if (!Loc.IsIdentity()) {
|
|
Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
|
|
C = *((Handle(Geom_Curve)*)&GG);
|
|
}
|
|
|
|
if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
|
|
C = new Geom_TrimmedCurve(C,f,l);
|
|
}
|
|
|
|
S = BRep_Tool::Surface(Fac);
|
|
|
|
// Compute the tol2d
|
|
Standard_Real tol3d = Max(BRep_Tool::Tolerance(Edg),
|
|
BRep_Tool::Tolerance(Fac));
|
|
GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
|
|
Standard_Real TolU = Gas.UResolution(tol3d);
|
|
Standard_Real TolV = Gas.VResolution(tol3d);
|
|
Standard_Real tol2d = Max(TolU,TolV);
|
|
|
|
Handle(Geom2d_Curve) C2d =
|
|
GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
|
|
Standard_Real l1,f1;
|
|
gp_Pnt pp ;
|
|
for(TopExp_Explorer ex(Edg, TopAbs_VERTEX); ex.More(); ex.Next())
|
|
{
|
|
pp = BRep_Tool::Pnt(TopoDS::Vertex(ex.Current()));
|
|
}
|
|
Handle(Geom_Curve) Cd = BRep_Tool::Curve(Edg, f1,l1);
|
|
gp_Pnt pf1(Cd->Value(f1));
|
|
gp_Pnt pl1(Cd->Value(l1));
|
|
gp_Pnt2d pf(C2d->Value(f));
|
|
gp_Pnt2d pl(C2d->Value(l));
|
|
|
|
if (S->IsUPeriodic()) {
|
|
Standard_Real up = S->UPeriod();
|
|
Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
|
|
Standard_Integer nbtra = 0;
|
|
Standard_Real theUmin = Min(pf.X(),pl.X());
|
|
Standard_Real theUmax = Max(pf.X(),pl.X());
|
|
|
|
if (theUmin < Umin-tolu) {
|
|
while (theUmin < Umin-tolu) {
|
|
theUmin += up;
|
|
nbtra++;
|
|
}
|
|
}
|
|
else if (theUmax > Umax+tolu) {
|
|
while (theUmax > Umax+tolu) {
|
|
theUmax -= up;
|
|
nbtra--;
|
|
}
|
|
}
|
|
|
|
/*
|
|
if (theUmin > Umax-tolu) {
|
|
while (theUmin > Umax-tolu) {
|
|
theUmin -= up;
|
|
nbtra--;
|
|
}
|
|
}
|
|
else if (theUmax < Umin+tolu) {
|
|
while (theUmax < Umin+tolu) {
|
|
theUmax += up;
|
|
nbtra++;
|
|
}
|
|
}
|
|
*/
|
|
if (nbtra !=0) {
|
|
C2d->Translate(gp_Vec2d(nbtra*up,0.));
|
|
}
|
|
}
|
|
|
|
if (S->IsVPeriodic()) {
|
|
Standard_Real vp = S->VPeriod();
|
|
Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
|
|
Standard_Integer nbtra = 0;
|
|
Standard_Real theVmin = Min(pf.Y(),pl.Y());
|
|
Standard_Real theVmax = Max(pf.Y(),pl.Y());
|
|
|
|
if (theVmin < Vmin-tolv) {
|
|
while (theVmin < Vmin-tolv) {
|
|
theVmin += vp; theVmax += vp;
|
|
nbtra++;
|
|
}
|
|
}
|
|
else if (theVmax > Vmax+tolv) {
|
|
while (theVmax > Vmax+tolv) {
|
|
theVmax -= vp; theVmin -= vp;
|
|
nbtra--;
|
|
}
|
|
}
|
|
/*
|
|
if (theVmin > Vmax-tolv) {
|
|
while (theVmin > Vmax-tolv) {
|
|
theVmin -= vp;
|
|
nbtra--;
|
|
}
|
|
}
|
|
else if (theVmax < Vmin+tolv) {
|
|
while (theVmax < Vmin+tolv) {
|
|
theVmax += vp;
|
|
nbtra++;
|
|
}
|
|
}
|
|
*/
|
|
if (nbtra !=0) {
|
|
C2d->Translate(gp_Vec2d(0.,nbtra*vp));
|
|
}
|
|
}
|
|
B.UpdateEdge(Edg,C2d,Fac,BRep_Tool::Tolerance(Edg));
|
|
}
|
|
|
|
bool BaseAlgo::GetConnectEdge(TopoDS_Face& face, TopoDS_Edge& edge1, TopoDS_Edge& edge2, TopoDS_Edge& newEdge1, TopoDS_Edge& newEdge2, bool& hasNewEdge1, bool& hasNewEdge2)
|
|
{
|
|
hasNewEdge1 = hasNewEdge2 = false;
|
|
double tol = Precision::Confusion() * 10;
|
|
double df,dl;
|
|
|
|
gp_Pnt sp1, ep1;
|
|
gp_Pnt sp2, ep2;
|
|
|
|
|
|
TopoDS_Vertex sv1;
|
|
TopoDS_Vertex ev1;
|
|
|
|
TopoDS_Vertex sv2;
|
|
TopoDS_Vertex ev2;
|
|
BRep_Builder b;
|
|
|
|
|
|
TopExp::Vertices(edge1,sv1,ev1);
|
|
TopExp::Vertices(edge2,sv2,ev2);
|
|
GetEdgeStartEndPoint(edge1, sp1,ep1);
|
|
GetEdgeStartEndPoint(edge2, sp2,ep2);
|
|
|
|
|
|
if(sp1.Distance(sp2) < Precision::Confusion() * 100)
|
|
{
|
|
TopoDS_Vertex& sv = sv1;
|
|
TopoDS_Vertex& ev = sv2;
|
|
if(sp1.Distance(sp2) > tol)
|
|
{
|
|
if(IsInCurve(edge1, ev) && IsInCurve(edge2, sv))
|
|
{
|
|
sv= sv;
|
|
}
|
|
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(sv, ev);
|
|
PutPCurve(edge, face);
|
|
if(!hasNewEdge1)
|
|
{
|
|
newEdge1 = edge;
|
|
hasNewEdge1 = true;
|
|
}
|
|
else if(!hasNewEdge2)
|
|
{
|
|
newEdge2 = TopoDS::Edge(edge.Reversed());
|
|
hasNewEdge2 = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(!ev.IsSame(sv))
|
|
{
|
|
Standard_Real para1 = BRep_Tool::Parameter(sv1,edge1);
|
|
Standard_Real para2 = BRep_Tool::Parameter(ev1,edge1);
|
|
Standard_Real paratemp ;
|
|
double f,l;
|
|
|
|
Handle(Geom_Curve) C;
|
|
C = BRep_Tool::Curve(edge1,df,dl);
|
|
|
|
paratemp = para1;
|
|
f = paratemp;
|
|
l = para2;
|
|
|
|
gp_Pnt p1 =C->Value(paratemp);
|
|
gp_Pnt p2 =C->Value(para1);
|
|
|
|
while(p1.Distance(p2) < 1E-5)
|
|
{
|
|
paratemp = paratemp + 1E-5;
|
|
f = paratemp;
|
|
l = para2;
|
|
p1 = C->Value(paratemp);
|
|
}
|
|
|
|
gp_Pnt pp =C->Value(paratemp);
|
|
TopoDS_Vertex vv = BRepBuilderAPI_MakeVertex(pp);
|
|
b.UpdateVertex(vv,paratemp, edge1, BRep_Tool::Tolerance(edge1));
|
|
|
|
TopoDS_Edge E = BRepBuilderAPI_MakeEdge(C,vv, ev1,f,l);
|
|
E = TopoDS::Edge(E.Oriented(edge1.Orientation()));
|
|
edge1 = E;
|
|
//PutPCurve(edge1, face);
|
|
|
|
TopoDS_Vertex sv5;
|
|
TopoDS_Vertex ev5;
|
|
TopExp::Vertices(edge1,sv5,ev5);
|
|
pp = BRep_Tool::Pnt(sv5);
|
|
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(ev, sv5);
|
|
edge = TopoDS::Edge(edge.Oriented(edge1.Orientation()));
|
|
PutPCurve(edge, face);
|
|
|
|
if(!hasNewEdge1)
|
|
{
|
|
newEdge1 = edge;
|
|
hasNewEdge1 = true;
|
|
}
|
|
else if(!hasNewEdge2)
|
|
{
|
|
newEdge2 = TopoDS::Edge(edge.Reversed());
|
|
hasNewEdge2 = true;
|
|
}
|
|
|
|
if(ev5.IsSame(ev1))
|
|
{
|
|
ev1 = ev1;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if(sp1.Distance(ep2) < Precision::Confusion() * 100)
|
|
{
|
|
TopoDS_Vertex& sv = sv1;
|
|
TopoDS_Vertex& ev = ev2;
|
|
if(sp1.Distance(ep2) > tol)
|
|
{
|
|
if(IsInCurve(edge1, ev) && IsInCurve(edge2, sv))
|
|
{
|
|
sv= sv;
|
|
}
|
|
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(sv, ev);
|
|
PutPCurve(edge, face);
|
|
if(!hasNewEdge1)
|
|
{
|
|
newEdge1 = edge;
|
|
hasNewEdge1 = true;
|
|
}
|
|
else if(!hasNewEdge2)
|
|
{
|
|
newEdge2 = TopoDS::Edge(edge.Reversed());
|
|
hasNewEdge2 = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(!ev.IsSame(sv))
|
|
{
|
|
Standard_Real para1 = BRep_Tool::Parameter(sv1,edge1);
|
|
Standard_Real para2 = BRep_Tool::Parameter(ev1,edge1);
|
|
Standard_Real paratemp ;
|
|
double f,l;
|
|
|
|
|
|
|
|
Handle(Geom_Curve) C;
|
|
C = BRep_Tool::Curve(edge1,df,dl);
|
|
|
|
paratemp = para1;
|
|
f = paratemp;
|
|
l = para2;
|
|
|
|
gp_Pnt p1 =C->Value(paratemp);
|
|
gp_Pnt p2 =C->Value(para1);
|
|
|
|
while(p1.Distance(p2) < 1E-5)
|
|
{
|
|
paratemp = paratemp + 1E-5;
|
|
f = paratemp;
|
|
l = para2;
|
|
p1 = C->Value(paratemp);
|
|
}
|
|
|
|
|
|
gp_Pnt pp =C->Value(paratemp);
|
|
TopoDS_Vertex vv = BRepBuilderAPI_MakeVertex(pp);
|
|
b.UpdateVertex(vv,paratemp, edge1, BRep_Tool::Tolerance(edge1));
|
|
TopoDS_Edge E = BRepBuilderAPI_MakeEdge(C,vv,ev1,f,l);
|
|
E = TopoDS::Edge(E.Oriented(edge1.Orientation()));
|
|
edge1 = E;
|
|
//PutPCurve(edge1, face);
|
|
|
|
TopoDS_Vertex sv5;
|
|
TopoDS_Vertex ev5;
|
|
TopExp::Vertices(edge1,sv5,ev5);
|
|
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(ev,sv5 );
|
|
edge = TopoDS::Edge(edge.Oriented(edge1.Orientation()));
|
|
PutPCurve(edge, face);
|
|
|
|
if(!hasNewEdge1)
|
|
{
|
|
newEdge1 = edge;
|
|
hasNewEdge1 = true;
|
|
}
|
|
else if(!hasNewEdge2)
|
|
{
|
|
newEdge2 = TopoDS::Edge(edge.Reversed());
|
|
hasNewEdge2 = true;
|
|
}
|
|
|
|
if(ev5.IsSame(ev1))
|
|
{
|
|
ev1 = ev1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(ep1.Distance(sp2) < Precision::Confusion() * 100)
|
|
{
|
|
TopoDS_Vertex& sv = ev1;
|
|
TopoDS_Vertex& ev = sv2;
|
|
if(ep1.Distance(sp2) > tol)
|
|
{
|
|
if(IsInCurve(edge1, ev) && IsInCurve(edge2, sv))
|
|
{
|
|
sv= sv;
|
|
}
|
|
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(sv, ev);
|
|
PutPCurve(edge, face);
|
|
if(!hasNewEdge1)
|
|
{
|
|
newEdge1 = edge;
|
|
hasNewEdge1 = true;
|
|
}
|
|
else if(!hasNewEdge2)
|
|
{
|
|
newEdge2 = TopoDS::Edge(edge.Reversed());
|
|
hasNewEdge2 = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(!ev.IsSame(sv))
|
|
{
|
|
Standard_Real para1 = BRep_Tool::Parameter(sv1,edge1);
|
|
Standard_Real para2 = BRep_Tool::Parameter(ev1,edge1);
|
|
Standard_Real paratemp ;
|
|
double f,l;
|
|
|
|
|
|
Handle(Geom_Curve) C;
|
|
C = BRep_Tool::Curve(edge1,df,dl);
|
|
|
|
paratemp = para2;
|
|
f = para1;
|
|
l = paratemp;
|
|
|
|
gp_Pnt p1 =C->Value(paratemp);
|
|
gp_Pnt p2 =C->Value(para2);
|
|
|
|
while(p1.Distance(p2) < 1E-5)
|
|
{
|
|
paratemp = paratemp - 1E-5;
|
|
f = para1;
|
|
l = paratemp;
|
|
p1 = C->Value(paratemp);
|
|
}
|
|
|
|
|
|
gp_Pnt pp =C->Value(paratemp);
|
|
TopoDS_Vertex vv = BRepBuilderAPI_MakeVertex(pp);
|
|
b.UpdateVertex(vv,paratemp, edge1, BRep_Tool::Tolerance(edge1));
|
|
TopoDS_Edge E = BRepBuilderAPI_MakeEdge(C,sv1,vv,f,l);
|
|
E = TopoDS::Edge(E.Oriented(edge1.Orientation()));
|
|
edge1 = E;
|
|
//PutPCurve(edge1, face);
|
|
C = BRep_Tool::Curve(edge1,df,dl);
|
|
TopoDS_Vertex sv5;
|
|
TopoDS_Vertex ev5;
|
|
TopExp::Vertices(edge1,sv5,ev5);
|
|
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(ev5, ev);
|
|
edge = TopoDS::Edge(edge.Oriented(edge1.Orientation()));
|
|
PutPCurve(edge, face);
|
|
|
|
if(!hasNewEdge1)
|
|
{
|
|
newEdge1 = edge;
|
|
hasNewEdge1 = true;
|
|
}
|
|
else if(!hasNewEdge2)
|
|
{
|
|
newEdge2 = TopoDS::Edge(edge.Reversed());
|
|
hasNewEdge2 = true;
|
|
}
|
|
if(sv5.IsSame(sv1))
|
|
{
|
|
sv1 = sv1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(ep1.Distance(ep2) < Precision::Confusion() * 100)
|
|
{
|
|
TopoDS_Vertex& sv = ev1;
|
|
TopoDS_Vertex& ev = ev2;
|
|
if(ep1.Distance(ep2) > tol)
|
|
{
|
|
if(IsInCurve(edge1, ev) && IsInCurve(edge2, sv))
|
|
{
|
|
Standard_Real para1 = BRep_Tool::Parameter(sv,edge1);
|
|
Standard_Real para2 = BRep_Tool::Parameter(ev,edge2);
|
|
|
|
|
|
}
|
|
|
|
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(sv, ev);
|
|
//BRepTools::Write(edge, "C:\\edge.brep");
|
|
//BRepTools::Write(face, "C:\\face.brep");
|
|
PutPCurve(edge, face);
|
|
if(!hasNewEdge1)
|
|
{
|
|
newEdge1 = edge;
|
|
hasNewEdge1 = true;
|
|
}
|
|
else if(!hasNewEdge2)
|
|
{
|
|
newEdge2 = TopoDS::Edge(edge.Reversed());
|
|
hasNewEdge2 = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(!ev.IsSame(sv))
|
|
{
|
|
Standard_Real para1 = BRep_Tool::Parameter(sv1,edge1);
|
|
Standard_Real para2 = BRep_Tool::Parameter(ev1,edge1);
|
|
Standard_Real paratemp ;
|
|
double f,l;
|
|
|
|
|
|
Handle(Geom_Curve) C;
|
|
C = BRep_Tool::Curve(edge1,df,dl);
|
|
|
|
paratemp = para2;
|
|
f = para1;
|
|
l = paratemp;
|
|
|
|
gp_Pnt p1 =C->Value(paratemp);
|
|
gp_Pnt p2 =C->Value(para2);
|
|
|
|
while(p1.Distance(p2) < 1E-5)
|
|
{
|
|
paratemp = paratemp - 1E-5;
|
|
f = para1;
|
|
l = paratemp;
|
|
p1 = C->Value(paratemp);
|
|
}
|
|
|
|
gp_Pnt pp =C->Value(paratemp);
|
|
TopoDS_Vertex vv = BRepBuilderAPI_MakeVertex(pp);
|
|
b.UpdateVertex(vv,paratemp, edge1, BRep_Tool::Tolerance(edge1));
|
|
TopoDS_Edge E = BRepBuilderAPI_MakeEdge(C,sv1,vv,f,l);
|
|
E = TopoDS::Edge(E.Oriented(edge1.Orientation()));
|
|
edge1 = E;
|
|
//PutPCurve(edge1, face);
|
|
|
|
TopoDS_Vertex sv5;
|
|
TopoDS_Vertex ev5;
|
|
TopExp::Vertices(edge1,sv5,ev5);
|
|
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(ev5, ev);
|
|
edge = TopoDS::Edge(edge.Oriented(edge1.Orientation()));
|
|
PutPCurve(edge, face);
|
|
|
|
if(!hasNewEdge1)
|
|
{
|
|
newEdge1 = edge;
|
|
hasNewEdge1 = true;
|
|
}
|
|
else if(!hasNewEdge2)
|
|
{
|
|
newEdge2 = TopoDS::Edge(edge.Reversed());
|
|
hasNewEdge2 = true;
|
|
}
|
|
|
|
if(sv5.IsSame(sv1))
|
|
{
|
|
sv1 = sv1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void BaseAlgo::RebuildConnectLines(TopoDS_Face& face, std::map<int, TopoDS_Edge> mapEdge,std::vector<int> edgeIndex, std::vector<TopoDS_Edge>& newEdges)
|
|
{
|
|
if(edgeIndex.size() == 0)
|
|
{
|
|
return;
|
|
}
|
|
TopoDS_Edge edge1, edge2;
|
|
bool isEdge1 = false, isEdge2 = false;
|
|
if(!GetConnectEdge(mapEdge,edgeIndex, face, edge1, edge2, isEdge1, isEdge2))
|
|
{
|
|
return;
|
|
}
|
|
if(isEdge1)
|
|
{
|
|
newEdges.push_back(edge1);
|
|
}
|
|
|
|
if(edgeIndex.size() == 1)
|
|
{
|
|
newEdges.push_back(mapEdge[edgeIndex[0]]);
|
|
}
|
|
else
|
|
{
|
|
for(int i = 0; i < edgeIndex.size(); i++)
|
|
{
|
|
if(edgeIndex.size() == 2 && i == 1)
|
|
{
|
|
newEdges.push_back(mapEdge[edgeIndex[i]]);
|
|
break;
|
|
}
|
|
int j = (i + 1) % edgeIndex.size();
|
|
TopoDS_Edge e1 = mapEdge[edgeIndex[i]];
|
|
TopoDS_Edge e2 = mapEdge[edgeIndex[j]];
|
|
|
|
TopoDS_Edge nEdge1, nEdge2;
|
|
bool isnEdge1 = false, isnEdge2 = false;
|
|
|
|
GetConnectEdge(face, e1, e2, nEdge1, nEdge2, isnEdge1, isnEdge2);
|
|
|
|
if(!isnEdge1 && !isnEdge2)
|
|
{
|
|
|
|
}
|
|
|
|
newEdges.push_back(e1);
|
|
|
|
if(isnEdge1)
|
|
{
|
|
newEdges.push_back(nEdge1);
|
|
}
|
|
|
|
if(isnEdge2)
|
|
{
|
|
newEdges.push_back(mapEdge[edgeIndex[j]]);
|
|
newEdges.push_back(nEdge2);\
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(isEdge2)
|
|
{
|
|
newEdges.push_back(edge2);
|
|
}
|
|
}
|
|
|
|
TopoDS_Shape BaseAlgo::GetCutResult(map<int, TopoDS_Face>& mapFace,TopoDS_Shape& InterSecLine)
|
|
{
|
|
TopoDS_Shape TopoShape;
|
|
map<int,bool> mapFaceSign;//false 未使用
|
|
map<int,vector<int>> mapConnectFace; //面的连接关系
|
|
map<int,vector<TopoDS_Vertex>> mapFacePoint;
|
|
map<int,Bnd_Box> mapBox;//
|
|
Bnd_Box boxLine;
|
|
int count = 0; //已使用面的数量
|
|
|
|
double tol = 1e-4;
|
|
double tol_face = tol;
|
|
|
|
|
|
|
|
for(TopExp_Explorer ex(InterSecLine,TopAbs_EDGE); ex.More();ex.Next())
|
|
{
|
|
Standard_Real df,dl;
|
|
Handle(Geom_Curve) curve = BRep_Tool::Curve(TopoDS::Edge(ex.Current()),df,dl);
|
|
gp_Pnt p1,p2;
|
|
GetEdgeStartEndPoint(TopoDS::Edge(ex.Current()),p1,p2);
|
|
//gp_Pnt p1 = curve->Value(df);
|
|
//gp_Pnt p2 = curve->Value(dl);
|
|
if(p1.Distance(p2) > Precision::Confusion())
|
|
{
|
|
boxLine.Add(curve->Value((df+dl) / 2));
|
|
}
|
|
boxLine.Add(p1);
|
|
boxLine.Add(p2);
|
|
boxLine.SetGap(tol);
|
|
}
|
|
|
|
if(boxLine.IsVoid())//无交线
|
|
{
|
|
BRepOffsetAPI_Sewing sew;
|
|
TopoDS_Compound comp;
|
|
BRep_Builder builder;
|
|
builder.MakeCompound(comp);
|
|
for(map<int,TopoDS_Face>::iterator iter = mapFace.begin(); iter!= mapFace.end(); iter++)
|
|
{
|
|
sew.Add(iter->second);
|
|
}
|
|
sew.Perform();
|
|
TopoDS_Shape shell = sew.SewedShape();
|
|
builder.Add(comp, shell);
|
|
|
|
TopoShape = comp;
|
|
|
|
return TopoShape;
|
|
|
|
}
|
|
|
|
for(map<int,TopoDS_Face>::iterator iter = mapFace.begin(); iter!= mapFace.end(); iter++)
|
|
{
|
|
mapFaceSign.insert(make_pair(iter->first,false));
|
|
vector<int> faceSet;
|
|
mapConnectFace.insert(make_pair(iter->first,faceSet));
|
|
|
|
Bnd_Box box;
|
|
box.SetGap(tol_face);
|
|
|
|
vector<TopoDS_Vertex> pointSet;
|
|
|
|
|
|
for(TopExp_Explorer ex(TopoDS::Face(iter->second),TopAbs_EDGE);ex.More();ex.Next())
|
|
{
|
|
TopoDS_Edge edge = TopoDS::Edge(ex.Current());
|
|
double df,dl;
|
|
Handle(Geom_Curve) cv = BRep_Tool::Curve(edge, df, dl);
|
|
TopExp_Explorer ee(edge, TopAbs_VERTEX);
|
|
|
|
vector<gp_Pnt> ps;
|
|
|
|
gp_Pnt p1,p2;
|
|
GetEdgeStartEndPoint(edge,p1,p2);
|
|
if(p1.Distance(p2) < Precision::Confusion())
|
|
{
|
|
continue;
|
|
}
|
|
//gp_Pnt p1 = cv->Value(df);
|
|
//gp_Pnt p2 = cv->Value(dl);
|
|
ps.push_back(p1);
|
|
ps.push_back(p2);
|
|
|
|
//加入一个中点
|
|
if(p1.Distance(p2) > Precision::Confusion())
|
|
{
|
|
ps.push_back(cv->Value((df+dl) / 2));
|
|
}
|
|
|
|
|
|
|
|
for(int i = 0; i < ps.size(); i++)
|
|
{
|
|
bool isfind = false;
|
|
gp_Pnt p = ps[i];
|
|
for(vector<TopoDS_Vertex>::iterator it = pointSet.begin(); it != pointSet.end(); it++)
|
|
{
|
|
gp_Pnt pp = BRep_Tool::Pnt(*it);
|
|
if(p.Distance(pp) < Precision::Confusion())
|
|
{
|
|
isfind = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!isfind)
|
|
{
|
|
pointSet.push_back(BRepBuilderAPI_MakeVertex(p).Vertex());
|
|
box.Add(p);
|
|
}
|
|
}
|
|
}
|
|
|
|
mapFacePoint.insert(make_pair(iter->first, pointSet));
|
|
mapBox.insert(make_pair(iter->first,box));
|
|
|
|
//AddShape(mapFace[iter->first]);
|
|
}
|
|
//return TopoShape;
|
|
|
|
// /* 建立面的连接关系*/
|
|
|
|
for(map<int,TopoDS_Face>::iterator iter = mapFace.begin(); iter!= mapFace.end(); iter++)
|
|
{
|
|
TopoDS_Face face = iter->second;
|
|
int idFace = iter->first;
|
|
vector<TopoDS_Vertex> facePoint = mapFacePoint[idFace];
|
|
vector<TopoDS_Vertex> pointSet;
|
|
|
|
int idF;
|
|
try
|
|
{
|
|
|
|
for(vector<TopoDS_Vertex>::iterator it = facePoint.begin(); it != facePoint.end(); it++)
|
|
{
|
|
TopoDS_Vertex v = *it;
|
|
Bnd_Box boxPoint;
|
|
boxPoint.SetGap(tol);
|
|
boxPoint.Add(BRep_Tool::Pnt(v));
|
|
if(boxPoint.IsOut(boxLine))
|
|
{
|
|
pointSet.push_back(v);
|
|
continue;
|
|
}
|
|
BRepExtrema_DistShapeShape inter_L_P(v,InterSecLine);
|
|
if(inter_L_P.IsDone() && inter_L_P. Value()> tol)
|
|
{
|
|
pointSet.push_back(v);
|
|
}
|
|
}
|
|
|
|
//cout<<"face "<<idF<<endl;
|
|
//for(vector<TopoDS_Vertex>::iterator it = facePoint.begin(); it != facePoint.end(); it++)
|
|
//{
|
|
// TopoDS_Vertex v = *it;
|
|
// gp_Pnt pp = BRep_Tool::Pnt(v);
|
|
// cout<<pp.X()<<" "<<pp.Y()<<" "<<pp.Z()<<endl;
|
|
//}
|
|
|
|
|
|
for(map<int,TopoDS_Face>::iterator it = mapFace.begin(); it != mapFace.end(); it++)
|
|
{
|
|
bool isNeighbour = false;
|
|
|
|
TopoDS_Face F = it->second;
|
|
idF = it->first;
|
|
if(idF == idFace)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
if(mapBox[idF].IsOut(mapBox[idFace]))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//判断是否已相邻
|
|
for(int j = 0; j < (int)mapConnectFace[idF].size(); j++)
|
|
{
|
|
if(mapConnectFace[idF][j] == idFace)
|
|
{
|
|
isNeighbour = true;
|
|
break;
|
|
}
|
|
}
|
|
if(isNeighbour)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
|
|
int pointCount = 0;
|
|
for(int i = 0; i < (int)pointSet.size(); i++)
|
|
{
|
|
TopoDS_Vertex v = pointSet[i];
|
|
|
|
Bnd_Box boxPoint;
|
|
boxPoint.SetGap(tol);
|
|
boxPoint.Add(BRep_Tool::Pnt(v));
|
|
if(boxPoint.IsOut(mapBox[idFace]))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
gp_Pnt pp = BRep_Tool::Pnt(v);
|
|
if(abs(-49.5 - pp.X()) <Precision::Confusion() )
|
|
{
|
|
pp = pp;
|
|
}
|
|
BRepExtrema_DistShapeShape inter(v,F);
|
|
|
|
// /*点在面上*/
|
|
if(inter.Value() < tol_face)
|
|
{
|
|
isNeighbour = true;
|
|
pointCount++;
|
|
//if(pointCount < 2)
|
|
//{
|
|
// continue;
|
|
//}
|
|
mapConnectFace[idFace].push_back(idF);
|
|
mapConnectFace[idF].push_back(idFace);
|
|
|
|
break;
|
|
}
|
|
} // end for pointSet
|
|
|
|
if(isNeighbour)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
} // end for mapFace
|
|
}
|
|
catch(Standard_Failure)
|
|
{
|
|
idF = idF;
|
|
idFace = idFace;
|
|
}
|
|
|
|
}// end end for mapFace
|
|
|
|
TopoDS_Compound comp;
|
|
BRep_Builder builder;
|
|
builder.MakeCompound(comp);
|
|
|
|
//while(mapFace.size() > count)
|
|
//{
|
|
for(map<int,TopoDS_Face>::iterator iter = mapFace.begin(); iter!= mapFace.end(); iter++)
|
|
{
|
|
int idFace = iter->first;
|
|
vector<int> resultSet;
|
|
vector<int> tempFaceSet;
|
|
|
|
|
|
if(mapFaceSign[idFace])
|
|
{
|
|
continue;
|
|
}
|
|
tempFaceSet.push_back(idFace);
|
|
|
|
GetFaceSet(resultSet, mapFaceSign, mapConnectFace, tempFaceSet);
|
|
count += resultSet.size();
|
|
|
|
TopoDS_Shell shell;
|
|
BRep_Builder builder_shell;
|
|
builder_shell.MakeShell(shell);
|
|
|
|
for(int i = 0; i < (int)resultSet.size(); i++)
|
|
{
|
|
int id = resultSet[i];
|
|
builder_shell.Add(shell,mapFace[id]);
|
|
}
|
|
|
|
builder.Add(comp,shell);
|
|
|
|
}
|
|
//}
|
|
TopoShape = comp;
|
|
|
|
return TopoShape;
|
|
}
|
|
|
|
bool BaseAlgo::IsInCurve(TopoDS_Edge edge, TopoDS_Vertex vertex)
|
|
{
|
|
Standard_Real tol = Precision::Confusion() *100;
|
|
TopoDS_Vertex sv,ev;
|
|
TopExp::Vertices(edge,sv,ev);
|
|
|
|
BRepExtrema_DistShapeShape inter(vertex,edge);
|
|
|
|
if(!inter.IsDone())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Standard_Real dis = inter.Value();
|
|
|
|
gp_Pnt sp = BRep_Tool::Pnt(sv);
|
|
gp_Pnt ep = BRep_Tool::Pnt(ev);
|
|
gp_Pnt p = BRep_Tool::Pnt(vertex);
|
|
|
|
Standard_Real dis_s = sp.Distance(p);
|
|
Standard_Real dis_e = ep.Distance(p);
|
|
|
|
if(dis > tol)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if(dis_s > tol && dis_e > tol)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void BaseAlgo::GetFaceSet( vector<int> &resultSet, map<int,bool>& mapFaceSign, map<int,vector<int>>& mapConnectFace, vector<int>& tempFaceSet)
|
|
{
|
|
if(tempFaceSet.size() == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int idFace = tempFaceSet[tempFaceSet.size() - 1];
|
|
tempFaceSet.pop_back();
|
|
if(mapFaceSign[idFace])
|
|
{
|
|
GetFaceSet(resultSet, mapFaceSign, mapConnectFace, tempFaceSet);
|
|
return;
|
|
}
|
|
mapFaceSign[idFace] = true;
|
|
resultSet.push_back(idFace);
|
|
|
|
|
|
vector<int> connectFaceSet = mapConnectFace[idFace];
|
|
|
|
for(int i = 0; i < (int)connectFaceSet.size(); i++)
|
|
{
|
|
int id = connectFaceSet[i];
|
|
if(mapFaceSign[id])
|
|
{
|
|
continue;
|
|
}
|
|
tempFaceSet.push_back(id);
|
|
}
|
|
GetFaceSet(resultSet, mapFaceSign, mapConnectFace, tempFaceSet);
|
|
}
|
|
|
|
Handle(Geom_BSplineCurve) BaseAlgo::GetBSplineCurve(const TopoDS_Shape& aS)
|
|
{
|
|
if(aS.ShapeType() != TopAbs_EDGE)
|
|
//return FALSE;
|
|
return 0; //pj
|
|
|
|
//
|
|
double dF,dL;
|
|
Handle(Geom_Curve) aCur = BRep_Tool::Curve(TopoDS::Edge(aS),dF,dL);
|
|
if(aCur.IsNull())
|
|
return NULL;
|
|
|
|
GeomAdaptor_Curve adaptor(aCur);
|
|
gp_Pnt pt1 = adaptor.Value(0);
|
|
gp_Pnt pt2 = adaptor.Value(0.5);
|
|
gp_Pnt pt3 = adaptor.Value(1);
|
|
|
|
|
|
Handle(Geom_BSplineCurve) m_bsplCur;
|
|
|
|
|
|
if(aCur->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
|
|
{
|
|
m_bsplCur = Handle(Geom_BSplineCurve)::DownCast(aCur->Copy());//记录备份,防止改变原来的曲线。
|
|
|
|
}
|
|
else if(aCur->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
|
|
{
|
|
Handle(Geom_TrimmedCurve) aTC = Handle(Geom_TrimmedCurve)::DownCast(aCur);
|
|
Handle(Geom_Curve) aBC = aTC->BasisCurve();
|
|
if(aBC->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
|
|
{
|
|
m_bsplCur = Handle(Geom_BSplineCurve)::DownCast(aCur->Copy());//记录备份,防止改变原来的曲线。
|
|
m_bsplCur->Segment(dF,dL);//切断,取一部分
|
|
|
|
}
|
|
}
|
|
|
|
return m_bsplCur;
|
|
}
|
|
|
|
vector<TopoDS_Shell> BaseAlgo::SplitShapeToShell(TopoDS_Shape S)
|
|
{
|
|
vector<TopoDS_Shell> shellSet;
|
|
|
|
if(S.ShapeType() == TopAbs_FACE)
|
|
{
|
|
BRep_Builder b;
|
|
TopoDS_Shell shell;
|
|
b.MakeShell(shell);
|
|
b.Add(shell, S);
|
|
shellSet.push_back(shell);
|
|
return shellSet;
|
|
}
|
|
|
|
vector<TopoDS_Face> faceSet;
|
|
vector<bool> isUsed;
|
|
vector<vector<TopoDS_Edge>> edgeSet;
|
|
vector<vector<TopoDS_Vertex>> pointSet;
|
|
for(TopExp_Explorer ex(S,TopAbs_FACE);ex.More();ex.Next())
|
|
{
|
|
TopoDS_Face face = TopoDS::Face(ex.Current());
|
|
faceSet.push_back(face);
|
|
isUsed.push_back(false);
|
|
|
|
vector<TopoDS_Edge> edges;
|
|
for(TopExp_Explorer ex1(face,TopAbs_EDGE);ex1.More();ex1.Next())
|
|
{
|
|
TopoDS_Edge edge = TopoDS::Edge(ex1.Current());
|
|
edges.push_back(edge);
|
|
}
|
|
edgeSet.push_back(edges);
|
|
|
|
vector<TopoDS_Vertex> vertexs;
|
|
for(TopExp_Explorer ex1(face,TopAbs_VERTEX);ex1.More();ex1.Next())
|
|
{
|
|
TopoDS_Vertex v = TopoDS::Vertex(ex1.Current());
|
|
vertexs.push_back(v);
|
|
}
|
|
pointSet.push_back(vertexs);
|
|
}
|
|
|
|
int count = 0;
|
|
|
|
vector<int> faceIds;
|
|
TopoDS_Compound c;
|
|
BRep_Builder b;
|
|
b.MakeCompound(c);
|
|
while(count != faceSet.size())
|
|
{
|
|
int faceIdsSize = faceIds.size();
|
|
for(int i = 0; i < faceSet.size(); i++)
|
|
{
|
|
if(isUsed[i])
|
|
{
|
|
continue;
|
|
}
|
|
if(faceIds.size() == 0)
|
|
{
|
|
faceIds.push_back(i);
|
|
isUsed[i] = true;
|
|
for(int j = 0; j < edgeSet[i].size(); j++)
|
|
{
|
|
b.Add(c,edgeSet[i][j]);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
vector<TopoDS_Vertex> vs = pointSet[i];
|
|
for(int k = 0; k < vs.size(); k++)
|
|
{
|
|
BRepExtrema_DistShapeShape inter(vs[k],c);
|
|
double dis = inter.Value();
|
|
if(dis < Precision::Confusion() * 100)
|
|
{
|
|
faceIds.push_back(i);
|
|
isUsed[i] = true;
|
|
for(int j = 0; j < edgeSet[i].size(); j++)
|
|
{
|
|
b.Add(c,edgeSet[i][j]);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
count += faceIds.size() - faceIdsSize;
|
|
//无新增
|
|
if(faceIds.size() - faceIdsSize == 0 || count == faceSet.size())
|
|
{
|
|
TopoDS_Shell shell;
|
|
BRep_Builder b_shell;
|
|
b_shell.MakeShell(shell);
|
|
for(int i = 0; i < faceIds.size(); i++)
|
|
{
|
|
b_shell.Add(shell, faceSet[faceIds[i]]);
|
|
}
|
|
shellSet.push_back(shell);
|
|
|
|
faceIds.clear();
|
|
TopoDS_Compound newC;
|
|
c = newC;
|
|
b.MakeCompound(c);
|
|
}
|
|
}
|
|
|
|
return shellSet;
|
|
}
|
|
|
|
bool BaseAlgo::IsConnect(TopoDS_Shape s1, TopoDS_Shape s2)
|
|
{
|
|
BRep_Builder b;
|
|
TopoDS_Compound vc1;
|
|
b.MakeCompound(vc1);
|
|
for(TopExp_Explorer ex(s1, TopAbs_VERTEX); ex.More(); ex.Next())
|
|
{
|
|
b.Add(vc1, TopoDS::Vertex(ex.Current()));
|
|
}
|
|
|
|
TopoDS_Compound ec1;
|
|
b.MakeCompound(ec1);
|
|
for(TopExp_Explorer ex(s1, TopAbs_EDGE); ex.More(); ex.Next())
|
|
{
|
|
b.Add(ec1, TopoDS::Edge(ex.Current()));
|
|
}
|
|
|
|
TopoDS_Compound vc2;
|
|
b.MakeCompound(vc2);
|
|
for(TopExp_Explorer ex(s2, TopAbs_VERTEX); ex.More(); ex.Next())
|
|
{
|
|
b.Add(vc2, TopoDS::Vertex(ex.Current()));
|
|
}
|
|
|
|
TopoDS_Compound ec2;
|
|
b.MakeCompound(ec2);
|
|
for(TopExp_Explorer ex(s2, TopAbs_EDGE); ex.More(); ex.Next())
|
|
{
|
|
b.Add(ec2, TopoDS::Edge(ex.Current()));
|
|
}
|
|
|
|
BRepExtrema_DistShapeShape inter1(vc1,ec2);
|
|
double dis = inter1.Value();
|
|
if(dis < Precision::Confusion() * 100)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
BRepExtrema_DistShapeShape inter2(vc2,ec1);
|
|
dis = inter2.Value();
|
|
if(dis < Precision::Confusion() * 100)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
TopoDS_Shell BaseAlgo::SewShell(vector<TopoDS_Shape> shapeSet, double tol)
|
|
{
|
|
TopoDS_Shell shell,shell1;
|
|
|
|
if(shapeSet.size() == 0)
|
|
{
|
|
return shell;
|
|
}
|
|
BRep_Builder b;
|
|
b.MakeShell(shell);
|
|
|
|
// BRepOffsetAPI_Sewing sew(tol);
|
|
BRepBuilderAPI_Sewing sew(tol);
|
|
|
|
vector<TopoDS_Face> faceSet;
|
|
|
|
for(int i = 0; i < shapeSet.size(); i++)
|
|
{
|
|
TopoDS_Shape shape = shapeSet[i];
|
|
|
|
if(shape.ShapeType() == TopAbs_FACE)
|
|
{
|
|
faceSet.push_back(TopoDS::Face(shape));
|
|
continue;
|
|
}
|
|
|
|
for(TopExp_Explorer ex(shape, TopAbs_FACE); ex.More();ex.Next())
|
|
{
|
|
faceSet.push_back(TopoDS::Face(ex.Current()));
|
|
}
|
|
}
|
|
|
|
if(faceSet.size() == 0)
|
|
{
|
|
return shell;
|
|
}
|
|
|
|
if(faceSet.size() == 1) //20170601 by czb
|
|
{
|
|
b.Add(shell, faceSet[0]);
|
|
//BRepTools::Write(shell, "C:\\shell.brep");
|
|
return shell;
|
|
}
|
|
|
|
for(int i = 0; i < faceSet.size(); i++)
|
|
{
|
|
//sew.Add(faceSet[i]);
|
|
b.Add(shell, faceSet[i]);
|
|
}
|
|
//sew.Perform(); //20170601 by czb
|
|
//shell = TopoDS::Shell(sew.SewedShape());
|
|
//return shell;
|
|
|
|
//return shell;
|
|
//BRepTools::Write(shell, "C:\\shell.brep");
|
|
try
|
|
{
|
|
BRep_Builder B;
|
|
TopoDS_Shape theShape;
|
|
int r= rand()%10000;
|
|
string str;
|
|
stringstream sstream;
|
|
sstream<<r;
|
|
sstream>>str;
|
|
str = str + ".brep";
|
|
BRepTools::Write(shell, str.c_str());
|
|
BRepTools::Read(theShape,str.c_str(),B);
|
|
remove(str.c_str());
|
|
//const char* fname = "c:\\sew.brep";
|
|
//const char* name = "t";
|
|
|
|
//filebuf fic;
|
|
//istream in(&fic);
|
|
//
|
|
|
|
//char typ[255];
|
|
//in >> typ;
|
|
//
|
|
//BRepTools_ShapeSet S(B);
|
|
|
|
//S.Read(in);
|
|
|
|
|
|
//
|
|
//S.Read(theShape,in );
|
|
TopExp_Explorer ex ;
|
|
for (ex.Init(theShape, TopAbs_FACE, TopAbs_SHAPE); ex.More(); ex.Next())
|
|
{
|
|
sew.Add(TopoDS::Face(ex.Current()));
|
|
}
|
|
|
|
sew.Perform();
|
|
TopoDS_Shape ss = sew.SewedShape();
|
|
TopAbs_ShapeEnum type = ss.ShapeType();
|
|
shell = TopoDS::Shell(sew.SewedShape());
|
|
}
|
|
catch(Standard_Failure)
|
|
{
|
|
return shell;
|
|
}
|
|
return shell;
|
|
}
|
|
|
|
TopoDS_Solid BaseAlgo::RebuildSolid(TopoDS_Solid solid, double tol)
|
|
{
|
|
TopoDS_Solid result;
|
|
|
|
vector<TopoDS_Shape> faceSet;
|
|
|
|
for(TopExp_Explorer ex(solid, TopAbs_FACE); ex.More();ex.Next())
|
|
{
|
|
faceSet.push_back(TopoDS::Face(ex.Current()));
|
|
}
|
|
|
|
TopoDS_Shell shell = SewShell(faceSet, tol);
|
|
|
|
result = BRepBuilderAPI_MakeSolid(shell).Solid();
|
|
|
|
return result;
|
|
}
|
|
|
|
vector<TopoDS_Shape> BaseAlgo::SolidSurfaceClear(vector<TopoDS_Shape> shapeSet, vector<int> onID)
|
|
{
|
|
vector<TopoDS_Shape> result;
|
|
int num = onID.size();
|
|
vector<bool> isUsed;
|
|
for(int i = 0; i < num; i++)
|
|
{
|
|
isUsed.push_back(false);
|
|
}
|
|
|
|
for(int i = 0; i < shapeSet.size(); i++)
|
|
{
|
|
bool isfind = false;
|
|
for(int j = 0; j < onID.size(); j++)
|
|
{
|
|
if(i == onID[j])
|
|
{
|
|
isfind = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(isfind)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
result.push_back(shapeSet[i]);
|
|
}
|
|
|
|
int count = 0;
|
|
while(num != count)
|
|
{
|
|
count = num;
|
|
|
|
for(int i = 0; i < onID.size(); i++)
|
|
{
|
|
if(isUsed[i])
|
|
{
|
|
continue;
|
|
}
|
|
|
|
TopoDS_Shape shape = shapeSet[onID[i]];
|
|
|
|
bool isOut = false;
|
|
for(TopExp_Explorer ex(shape, TopAbs_VERTEX); ex.More(); ex.Next())
|
|
{
|
|
TopoDS_Vertex v = TopoDS::Vertex(ex.Current());
|
|
|
|
bool isOn = false;
|
|
for(int j = 0; j < shapeSet.size(); j++)
|
|
{
|
|
|
|
if(onID[i] == j)
|
|
{
|
|
continue;
|
|
}
|
|
//已经排除的面 不计算
|
|
bool isOnOut = false;
|
|
for(int k = 0; k < onID.size(); k++)
|
|
{
|
|
if(onID[k] == j)
|
|
{
|
|
isOnOut = isUsed[k];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(isOnOut)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
BRepExtrema_DistShapeShape dis(v, shapeSet[j]);
|
|
dis.Perform();
|
|
if(dis.Value() < Precision::Confusion() * 100)
|
|
{
|
|
isOn = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(isOn)
|
|
{
|
|
continue;
|
|
}
|
|
isOut = true;
|
|
break;
|
|
}
|
|
|
|
if(isOut)
|
|
{
|
|
isUsed[i] = false;
|
|
num--;
|
|
}
|
|
}
|
|
}
|
|
|
|
for(int i = 0; i < onID.size(); i++)
|
|
{
|
|
if(isUsed[i])
|
|
{
|
|
continue;
|
|
}
|
|
result.push_back(shapeSet[onID[i]]);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
bool BaseAlgo::IsParallel( TopoDS_Edge e1, TopoDS_Edge e2)
|
|
{
|
|
double df,dl;
|
|
Handle(Geom_Curve) cv1 = BRep_Tool::Curve(e1,df,dl);
|
|
gp_Pnt p11 = cv1->Value(df);
|
|
gp_Pnt p12 = cv1->Value(dl);
|
|
|
|
Handle(Geom_Curve) cv2 = BRep_Tool::Curve(e2,df,dl);
|
|
gp_Pnt p21 = cv2->Value(df);
|
|
gp_Pnt p22 = cv2->Value(dl);
|
|
|
|
if(p11.Distance(p21) < Precision::Confusion())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if(p11.Distance(p22) < Precision::Confusion())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if(p12.Distance(p21) < Precision::Confusion())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if(p12.Distance(p22) < Precision::Confusion())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
gp_Dir d1(p11.X() - p12.X(), p11.Y() - p12.Y(), p11.Z() - p12.Z());
|
|
gp_Dir d2(p21.X() - p22.X(), p21.Y() - p22.Y(), p21.Z() - p22.Z());
|
|
|
|
double angle = d1.Angle(d2);
|
|
if(angle < Standard_PI * 0.001 || angle > Standard_PI * 0.999)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool BaseAlgo::IsReversed(TopoDS_Shape solid, gp_Pnt p)
|
|
{
|
|
BRepClass3d_SolidClassifier solidClassifier(solid);
|
|
solidClassifier.Perform(p, 1E-5) ;
|
|
TopAbs_State state = solidClassifier.State() ;
|
|
if(state == TopAbs_IN)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool BaseAlgo::IsPointOnEdge( const TopoDS_Edge& edge,const gp_Pnt& pt1)
|
|
{
|
|
//double df,dl;
|
|
//Handle(Geom_Curve) aCur = BRep_Tool::Curve(edge,df,dl);
|
|
|
|
//GeomAPI_ProjectPointOnCurve Projector1 (pt1, aCur); //gp_Pnt Bpnt
|
|
//gp_Pnt Bpnt_P1 = Projector1.NearestPoint();
|
|
////Standard_Real r = Projector1.LowerDistanceParameter();
|
|
//Standard_Real p1_Bpnt_distance=Bpnt_P1.Distance (pt1) ;
|
|
////if(fabs(p1_Bpnt_distance) < Precision::Confusion())//srq 2012-5-31
|
|
//if(fabs(p1_Bpnt_distance)<m_precision)//srq 2012-5-31
|
|
// return true;
|
|
//return false;
|
|
|
|
// yc 20130725
|
|
BRepExtrema_DistShapeShape dis(edge, BRepBuilderAPI_MakeVertex(pt1).Shape());
|
|
dis.Perform();
|
|
//return dis.Value() < Precision::Confusion();
|
|
double disVal = dis.Value();
|
|
bool flag = (disVal < Precision::Confusion());
|
|
return flag;
|
|
|
|
}
|
|
|
|
bool BaseAlgo::TrimEdgeBy2Points( const TopoDS_Edge& edge,const gp_Pnt& pt1,const gp_Pnt& pt2,TopoDS_Edge& newEdge )
|
|
{
|
|
try
|
|
{
|
|
double df,dl;
|
|
Handle(Geom_Curve) aCur = BRep_Tool::Curve(edge,df,dl);
|
|
|
|
if(IsPointOnEdge(edge,pt1) && IsPointOnEdge(edge,pt2))
|
|
{
|
|
|
|
//GeomAPI_ProjectPointOnCurve Projector1 (pt1, aCur); //gp_Pnt Bpnt
|
|
//GeomAPI_ProjectPointOnCurve Projector2 (pt2, aCur); //gp_Pnt Bpnt
|
|
|
|
//Standard_Real st1 = Projector1.LowerDistanceParameter();
|
|
//Standard_Real st2 = Projector2.LowerDistanceParameter();
|
|
|
|
Standard_Real st1 = ProjectPointOnCurvePara(edge, pt1);
|
|
Standard_Real st2 = ProjectPointOnCurvePara(edge, pt2);
|
|
|
|
Handle(Geom_TrimmedCurve) myTrimmed = new Geom_TrimmedCurve(aCur, st1, st2);
|
|
|
|
newEdge = BRepBuilderAPI_MakeEdge(myTrimmed);
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
catch (Standard_ConstructionError e)
|
|
{
|
|
Standard_CString str = e.GetMessageString();
|
|
return false;
|
|
}
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
vector<gp_Pnt> BaseAlgo::GetPointSet(vector<TopoDS_Edge> edgeSet)
|
|
{
|
|
vector<gp_Pnt> pointSet;
|
|
|
|
for(int i = 0; i < edgeSet.size(); i++)
|
|
{
|
|
TopoDS_Edge edge = edgeSet[i];
|
|
gp_Pnt p1 ,p2;
|
|
GetEdgeStartEndPoint(edge, p1,p2);
|
|
|
|
if(i > 0)
|
|
{
|
|
gp_Pnt ep = pointSet[pointSet.size() - 1];
|
|
|
|
if(ep.Distance(p1) < Precision::Confusion() * 10)
|
|
{
|
|
pointSet.push_back(p2);
|
|
}
|
|
else
|
|
{
|
|
pointSet.push_back(p1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(edgeSet.size() == 1)
|
|
{
|
|
pointSet.push_back(p1);
|
|
pointSet.push_back(p2);
|
|
continue;
|
|
}
|
|
TopoDS_Edge edge1 = edgeSet[edgeSet.size() - 1];
|
|
gp_Pnt p3 ,p4;
|
|
GetEdgeStartEndPoint(edge1, p3,p4);
|
|
if(p1.Distance(p3) < Precision::Confusion() * 10 || p1.Distance(p4) < Precision::Confusion() * 10)
|
|
{
|
|
pointSet.push_back(p2);
|
|
pointSet.push_back(p1);
|
|
}
|
|
else
|
|
{
|
|
pointSet.push_back(p1);
|
|
pointSet.push_back(p2);
|
|
}
|
|
}
|
|
}
|
|
|
|
return pointSet;
|
|
}
|
|
|
|
gp_Pnt BaseAlgo::ProjectPointOnCurvePoint( TopoDS_Edge edge, gp_Pnt p )
|
|
{
|
|
double df,dl;
|
|
gp_Pnt p1,p2;
|
|
double minDis = 10000;
|
|
double dis;
|
|
gp_Pnt pnt;
|
|
Handle(Geom_Curve) cv = BRep_Tool::Curve(edge, df, dl);
|
|
GetEdgeStartEndPoint(edge,p1,p2);
|
|
dis = p1.Distance(p);
|
|
if(minDis > dis)
|
|
{
|
|
minDis = dis;
|
|
pnt = p1;
|
|
}
|
|
dis = p2.Distance(p);
|
|
if(minDis > dis)
|
|
{
|
|
minDis = dis;
|
|
pnt = p2;
|
|
}
|
|
if(minDis<Precision::Confusion())
|
|
{
|
|
return pnt;
|
|
}
|
|
GeomAPI_ProjectPointOnCurve project(p,cv);
|
|
dis = project.LowerDistance();
|
|
if(minDis >dis)
|
|
{
|
|
pnt = project.NearestPoint();
|
|
}
|
|
|
|
return pnt;
|
|
}
|
|
|
|
double BaseAlgo::ProjectPointOnCurvePara( TopoDS_Edge edge, gp_Pnt p )
|
|
{
|
|
double df,dl;
|
|
gp_Pnt p1,p2;
|
|
double minDis = 10000;
|
|
double dis;
|
|
double para;
|
|
Handle(Geom_Curve) cv = BRep_Tool::Curve(edge, df, dl);
|
|
GetEdgeStartEndPoint(edge,p1,p2);
|
|
dis = p1.Distance(p);
|
|
if(minDis > dis)
|
|
{
|
|
minDis = dis;
|
|
para = df;
|
|
}
|
|
dis = p2.Distance(p);
|
|
if(minDis > dis)
|
|
{
|
|
minDis = dis;
|
|
para = dl;
|
|
}
|
|
if(minDis<Precision::Confusion()*50)
|
|
{
|
|
return para;
|
|
}
|
|
|
|
GeomAPI_ProjectPointOnCurve project(p, cv);
|
|
dis = project.LowerDistance();
|
|
if(minDis > dis)
|
|
{
|
|
gp_Pnt pp = project.NearestPoint();
|
|
para = project.LowerDistanceParameter();
|
|
}
|
|
return para;
|
|
}
|
|
|
|
double BaseAlgo::ProjectPointOnCurveDis( TopoDS_Edge edge, gp_Pnt p )
|
|
{
|
|
double df,dl;
|
|
gp_Pnt p1,p2;
|
|
double minDis = 10000;
|
|
double dis;
|
|
Handle(Geom_Curve) cv = BRep_Tool::Curve(edge, df, dl);
|
|
GetEdgeStartEndPoint(edge,p1,p2);
|
|
dis = p1.Distance(p);
|
|
if(minDis > dis)
|
|
{
|
|
minDis = dis;
|
|
}
|
|
dis = p2.Distance(p);
|
|
if(minDis > dis)
|
|
{
|
|
minDis = dis;
|
|
}
|
|
if(minDis<Precision::Confusion())
|
|
{
|
|
return minDis;
|
|
}
|
|
GeomAPI_ProjectPointOnCurve project(p, cv);
|
|
dis = project.LowerDistance();
|
|
if(minDis > dis)
|
|
{
|
|
minDis = dis;
|
|
}
|
|
|
|
return minDis;
|
|
}
|