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

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;
}