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

6113 lines
151 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "Stdafx.h"
#include "SplitAllInsectionCurves.h"
#include "ScBRepLib.h"
#include <BRepExtrema_DistShapeShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TColGeom_Array1OfBSplineCurve.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <BRepExtrema_ExtCC.hxx>
#include <GProp_GProps.hxx>
#include <BRepGProp.hxx>
#include <Geom_Hyperbola.hxx>
#include <Geom_Parabola.hxx>
#include "GProp_PEquation.hxx"
#include <GeomAPI_Interpolate.hxx>
#include <TColgp_HArray1OfPnt.hxx>
#include <GCPnts_AbscissaPoint.hxx>
#include "ClosedFinder.h"
#include "IntTools_EdgeEdge.hxx"
//#include "BOPTools_Tools.hxx" //XUEFENG DELETE 202009
#include "IntTools_CommonPrt.hxx"
#include "IntTools_Range.hxx"
#include "BRepBndLib.hxx"
#include "SectionAlgo.h"
#include "BaseAlgo.h"
#include "GeomAPI_ExtremaCurveCurve.hxx"
#include "TColStd_Array1OfInteger.hxx"
#include "Geom_BezierCurve.hxx" // XUEFENG ADDED 202009
#include "Geom_Surface.hxx" // XUEFENG ADDED 202009
#include "Geom_BSplineSurface.hxx" // XUEFENG ADDED 202009
#include <QString>
#include <QDebug>
#include <sstream>
CSplitAllInsectionCurves::CSplitAllInsectionCurves(void)
{
m_ClosedZoomID = 1;
m_precision=10e-7;
}
//********************* flag **************************************** 交点约束
CSplitAllInsectionCurves::CSplitAllInsectionCurves(std::map<int,Curve>& m_Curves, std::map<int,Point3D>& m_Points):m_mapCurves(m_Curves),m_mapPoints(m_Points)
{
m_ClosedZoomID = 1;
}
CSplitAllInsectionCurves::~CSplitAllInsectionCurves(void)
{
}
// ADDED BY XUEFENG 20180731
// FOR CODES COMBINE
// ADDED BY XUEFENG 201805
// 加约束曲线
void CSplitAllInsectionCurves::ExpInit( const std::vector<TopoDS_Edge>& wires ,const std::vector<std::string>& seqNo,
const std::vector<int>& expSeqNo )
{
if(wires.size() != seqNo.size())
return;
//自动编号
for (int i=0;i < wires.size();i++)
{
m_mapAllWires.insert(make_pair(i+1,wires.at(i)));
m_mapWireID2Name.insert(make_pair(i+1,seqNo.at(i)));
}
this->m_expWireSeqNo = expSeqNo;
m_mapAllInsectionPoints.clear();
m_mapAllInsectionSectionInfo.clear();
m_mapInsectionAround.clear(); //主从周边点集合
m_mapClosedZooms.clear(); //记录周边点号
m_ClosedZoomID = 1;
m_mapClosedWires.clear(); //记录周边线号
m_mapClosedShape.clear();
m_mapClosedBSplineCurves.clear();
m_mapSuccessGenFaces.clear();
m_mapIntersectinInfoTimeSearchs.clear();
CreateWireBox();
}
// END ADDED
// END ADDED
void CSplitAllInsectionCurves::Init( const std::vector<TopoDS_Edge>& wires ,const std::vector<std::string>& seqNo) //20180101 modified by czbNames修改为序号
{
if(wires.size() != seqNo.size())
return;
//自动编号
for (int i=0;i < wires.size();i++)
{
m_mapAllWires.insert(make_pair(i+1,wires.at(i)));
m_mapWireID2Name.insert(make_pair(i+1,seqNo.at(i)));
}
m_mapAllInsectionPoints.clear();
m_mapAllInsectionSectionInfo.clear();
m_mapInsectionAround.clear(); //主从周边点集合
m_mapClosedZooms.clear(); //记录周边点号
m_ClosedZoomID = 1;
m_mapClosedWires.clear(); //记录周边线号
m_mapClosedShape.clear();
m_mapClosedBSplineCurves.clear();
m_mapSuccessGenFaces.clear();
m_mapIntersectinInfoTimeSearchs.clear();
CreateWireBox();
}
// yc 20130724
void CSplitAllInsectionCurves::Init( const std::vector<TopoDS_Edge>& wires ,const std::vector<std::string>& strNames, vector<int>& borderWireID)
{
if(wires.size() != strNames.size())
return;
//自动编号
for (int i=0;i < wires.size();i++)
{
m_mapAllWires.insert(make_pair(i+1,wires.at(i)));
m_mapWireID2Name.insert(make_pair(i+1,strNames.at(i)));
}
this->border = borderWireID;
m_mapAllInsectionPoints.clear();
m_mapAllInsectionSectionInfo.clear();
m_mapInsectionAround.clear(); //主从周边点集合
m_mapClosedZooms.clear(); //记录周边点号
m_ClosedZoomID = 1;
m_mapClosedWires.clear(); //记录周边线号
m_mapClosedShape.clear();
m_mapClosedBSplineCurves.clear();
m_mapSuccessGenFaces.clear();
m_mapIntersectinInfoTimeSearchs.clear();
CreateWireBox();
}
void CSplitAllInsectionCurves::Init(const std::vector<TopoDS_Edge>& wires)
{
//自动编号
for (int i=0;i < wires.size();i++)
{
m_mapAllWires.insert(make_pair(i+1,wires.at(i)));
std::string s;
s = std::to_string(i+1);
m_mapWireID2Name.insert(make_pair(i+1,s));
}
m_mapAllInsectionPoints.clear();
m_mapAllInsectionSectionInfo.clear();
m_mapInsectionAround.clear(); //主从周边点集合
m_mapClosedZooms.clear(); //记录周边点号
m_ClosedZoomID = 1;
m_mapClosedWires.clear(); //记录周边线号
m_mapClosedShape.clear();
m_mapClosedBSplineCurves.clear();
m_mapSuccessGenFaces.clear();
m_mapIntersectinInfoTimeSearchs.clear();
CreateWireBox();
}
void CSplitAllInsectionCurves::Init(std::map<int,TopoDS_Edge>& wires, std::vector<int> ids)
{
//自动编号
for(int i = 0; i < ids.size(); i++)
{
m_mapAllWires.insert(make_pair(ids[i],wires[ids[i]]));
std::string s;
s = std::to_string(ids[i]);
m_mapWireID2Name.insert(make_pair(ids[i],s));
}
m_mapAllInsectionPoints.clear();
m_mapAllInsectionSectionInfo.clear();
m_mapInsectionAround.clear(); //主从周边点集合
m_mapClosedZooms.clear(); //记录周边点号
m_ClosedZoomID = 1;
m_mapClosedWires.clear(); //记录周边线号
m_mapClosedShape.clear();
m_mapClosedBSplineCurves.clear();
m_mapSuccessGenFaces.clear();
m_mapIntersectinInfoTimeSearchs.clear();
CreateWireBox();
}
void CSplitAllInsectionCurves::Init(const std::vector<TopoDS_Edge>& wires, TopoDS_Face baseFace)
{
Init(wires);
this->baseFace = baseFace;
}
bool CSplitAllInsectionCurves::Build(bool bsolid)
{
if(!GetAllWires(bsolid))
{
return false;
}
if(!GetAllFaces(bsolid))
{
return false;
}
return true;
}
bool CSplitAllInsectionCurves::GetAllWires(bool bsolid)
{
//*************** flag ******************************
bool flag = false;
vector<gp_Pnt> vcinsec2sidepnts;
gp_Pnt pnttemp;
if(bsolid) //srq2012-6-3
{
m_precision=0.0005;
}
else
{
m_precision=Precision::Confusion() *100;
}
if(flag)
{
CalcInsectionPoints();
}
else
{///flag 交点约束
std::vector<pair<int,int>> haveInsects;
int autoID = 1;
for (std::map<int,TopoDS_Edge>::const_iterator it1 = m_mapAllWires.begin();it1!=m_mapAllWires.end();++it1 )
{
Bnd_Box box1 = m_mapWireBox[it1->first];
box1.SetGap(0.0001);
//for (std::map<int,TopoDS_Edge>::const_iterator it2 = m_mapAllWires.begin();it2!=m_mapAllWires.end();++it2 )
std::map<int,TopoDS_Edge>::const_iterator it2 = it1;
for (it2++;it2!=m_mapAllWires.end();++it2 ) //20170801 修改 by czb
{
int id1=it1->first;
int id2=it2->first;
//if(id1 == 57 && id2 == 58)
//{
// id1 = id1;
//}
if(it1->first == it2->first)
continue;
Bnd_Box box2 = m_mapWireBox[it2->first];
box2.SetGap(0.0001);
if(!haveInsect(haveInsects,it1->first , it2->first))
{
//先判断是否平行 yc 20130731
if(IsParallel(it1->second, it2->second))
{
continue;
}
if(box1.IsOut(box2))
{
continue;
}
TopoDS_Edge e1 = it1->second;
TopoDS_Edge e2 = it2->second;
gp_Pnt ptInterLeft;
////BRepExtrema_DistShapeShape inter1(it1->second,it2->second);
////int nPnt1= inter1.NbSolution();
//double dis = DistanceEE(e1, e2, ptInterLeft);
////for(int ix = 1;ix <= nPnt1;ix ++)
//if(dis < m_precision)
//{
// //gp_Pnt p1 = inter1.PointOnShape1(ix);
// //gp_Pnt p2 = inter1.PointOnShape2(ix);
// gp_Pnt p1,p2;
// p1 = ptInterLeft;
// p2 = ptInterLeft;
// //if(p1.Distance(p2) < Precision::Confusion())//srq 2012-5-31
// if(p1.Distance(p2) <m_precision)//srq 2012-5-31
// {
// //得到交点
// ptInterLeft = p1;
// int iBelongid = 0 ;
// if(!haveInsectPoint(ptInterLeft,iBelongid))
// {
// CInsectionInfo aInfo;
// aInfo.m_Id = autoID;
// autoID++;
// if(vcinsec2sidepnts.size()>0)
// {
// bool bfind=false;
// for(int mm=0;mm<vcinsec2sidepnts.size();mm++)
// {
// if(abs(ptInterLeft.Distance(vcinsec2sidepnts[mm]))<m_precision)
// {
// ptInterLeft=vcinsec2sidepnts[mm];
// bfind=true;
// break;
// }
// }
// if(bfind)
// {
// }
// else
// {
// vcinsec2sidepnts.push_back(ptInterLeft);
// }
// }
// else
// vcinsec2sidepnts.push_back(ptInterLeft);
// aInfo.m_PtCoor = ptInterLeft;
// aInfo.m_vctBelongWireIDs.push_back(it1->first);
// aInfo.m_vctBelongWireIDs.push_back(it2->first);
// m_mapAllInsectionPoints.insert(make_pair(aInfo.m_Id,aInfo));
// }
// else
// {
// std::vector<int>& vctBelongWireIDs= m_mapAllInsectionPoints[iBelongid].m_vctBelongWireIDs;
// //std::vector<int>::iterator it1find = find(vctBelongWireIDs.begin(),vctBelongWireIDs.end(),it1->first);
// //std::vector<int>::iterator it2find = find(vctBelongWireIDs.begin(),vctBelongWireIDs.end(),it2->first);
// //if(it1find == vctBelongWireIDs.end())
// //{
// // vctBelongWireIDs.push_back(it1->first);
// //}
// //if(it2find == vctBelongWireIDs.end())
// //{
// // vctBelongWireIDs.push_back(it2->first);
// //}
// bool isfind1 = false, isfind2 = false;
// for(std::vector<int>::iterator itfind = vctBelongWireIDs.begin(); itfind != vctBelongWireIDs.end(); itfind++)
// {
// if(it1->first == *itfind)
// {
// isfind1 = true;
// }
// if(it2->first == *itfind)
// {
// isfind2 = true;
// }
// }
// if(!isfind1)
// {
// vctBelongWireIDs.push_back(it1->first);
// }
// if(!isfind2)
// {
// vctBelongWireIDs.push_back(it2->first);
// }
// }
// }
//}
// 多个交点的情况 yc 20140808
vector<gp_Pnt> pSet;
try
{
//SectionPoints(e1, e2, m_precision, pSet);
SectionPoints(it1, it2, m_precision, pSet); //20180101 modified by czb
}
catch(Standard_Failure e)
{
string s = e.GetMessageString();
if (s == "RepeatExist")
{
/* CString strT= _T("曲线") +m_mapWireID2Name[id1]+_T("与") + m_mapWireID2Name[id2] + _T("重合"); // pj change PJTODO: 未来改成UTF8编码再解开注释
throw Standard_Failure(strT); */
}
else
throw e;
}
for(int kk = 0; kk < pSet.size(); kk++)
{
ptInterLeft = pSet[kk];
int iBelongid = 0 ;
if(!haveInsectPoint(ptInterLeft,iBelongid))
{
CInsectionInfo aInfo;
aInfo.m_Id = autoID;
autoID++;
if(vcinsec2sidepnts.size()>0)
{
bool bfind=false;
for(int mm=0;mm<vcinsec2sidepnts.size();mm++)
{
if(abs(ptInterLeft.Distance(vcinsec2sidepnts[mm]))<m_precision)
{
ptInterLeft=vcinsec2sidepnts[mm];
bfind=true;
break;
}
}
if(bfind)
{
}
else
{
vcinsec2sidepnts.push_back(ptInterLeft);
}
}
else
vcinsec2sidepnts.push_back(ptInterLeft);
aInfo.m_PtCoor = ptInterLeft;
aInfo.m_vctBelongWireIDs.push_back(it1->first);
aInfo.m_vctBelongWireIDs.push_back(it2->first);
m_mapAllInsectionPoints.insert(make_pair(aInfo.m_Id,aInfo));
}
else
{
std::vector<int>& vctBelongWireIDs= m_mapAllInsectionPoints[iBelongid].m_vctBelongWireIDs;
//std::vector<int>::iterator it1find = find(vctBelongWireIDs.begin(),vctBelongWireIDs.end(),it1->first);
//std::vector<int>::iterator it2find = find(vctBelongWireIDs.begin(),vctBelongWireIDs.end(),it2->first);
//if(it1find == vctBelongWireIDs.end())
//{
// vctBelongWireIDs.push_back(it1->first);
//}
//if(it2find == vctBelongWireIDs.end())
//{
// vctBelongWireIDs.push_back(it2->first);
//}
bool isfind1 = false, isfind2 = false;
for(std::vector<int>::iterator itfind = vctBelongWireIDs.begin(); itfind != vctBelongWireIDs.end(); itfind++)
{
if(it1->first == *itfind)
{
isfind1 = true;
}
if(it2->first == *itfind)
{
isfind2 = true;
}
}
if(!isfind1)
{
vctBelongWireIDs.push_back(it1->first);
}
if(!isfind2)
{
vctBelongWireIDs.push_back(it2->first);
}
}
}//end for(int kk = 0; kk < pSet.size(); kk++)
}
}
}
}
//2012-5-21 srq 针对bug 网格线,当输入的数据不能创建面时,系统总非法退出,建议给提示信息。 注交点少于2个是不可能成面的
if(m_mapAllInsectionPoints.size()<2)
return false;
//检查交点
CalcInsectionSections();
if(!GetClosedZooms())
{
//2012-5-21 srq 针对bug 网格线,当输入的数据不能创建面时,系统总非法退出,建议给提示信息。 注交点少于2个是不可能成面的
//_ASSERTE(0);
return false;
}
return true;
}
bool CSplitAllInsectionCurves::GetAllFaces(bool bsolid)
{
//////////////////////////////////////////////////////////////////////////
//////////////////////以下的代码是按照xml格式写的可以参考一下/////////////////////////
//////////////////////////////////////////////////////////////////////////
vector<Handle(Geom_BSplineCurve)> vctBSplineCurves;
vector<CResultData> vctResultDatas;
map<int,gp_Pnt> m_map2sidePnts;
map<int,gp_Pnt>::iterator pntit;
int pntscount=0;
BRep_Builder b;
TopoDS_Compound c;
b.MakeCompound(c);
//std::map<int,vector<Handle(Geom_BSplineCurve)>> m_mapClosedBSplineCurves;
for(std::map<int,vector<CResultData>>::iterator pit = m_ClosedResults.begin();pit != m_ClosedResults.end();++pit)
{
vctBSplineCurves.clear();
vctResultDatas = pit->second;
int id = pit->first;
BRep_Builder b1;
TopoDS_Compound c1;
b.MakeCompound(c1);
try
{
//foreach(CResultData data in vctResultDatas)
for (const CResultData& data : vctResultDatas)
{
TopoDS_Edge wire = m_mapAllWires[data.m_iWireID];
b1.Add(c1, wire);
Handle(Geom_BSplineCurve) curve = TrimWire2BSplineCurve(wire,data.m_dStartRatio,data.m_dEndRatio);
if(bsolid)//begin srq 2012-6-3
{
gp_Pnt beginp=curve->StartPoint();
gp_Pnt endp=curve->EndPoint();
gp_Pnt tempp;
double dF,dL;
bool bchangebegin=false;
bool bchangeend=false;
double step=0.1;
vector<gp_Pnt> vcpnts;
int k;
dF=curve->FirstParameter();
dL=curve->LastParameter();
if(m_map2sidePnts.size()>0)
{
for(pntit=m_map2sidePnts.begin();pntit!=m_map2sidePnts.end();pntit++)
{
double dis1=beginp.Distance(pntit->second);
if(abs(beginp.Distance(pntit->second))<m_precision)//srq 2012-5-31
{
bchangebegin=true;
beginp=pntit->second;
}
double dis2=endp.Distance(pntit->second);
if(abs(endp.Distance(pntit->second))<m_precision)//srq 2012-5-31
{
bchangeend=true;
endp=pntit->second;
}
}
if(bchangebegin==false)
{
m_map2sidePnts.insert(make_pair(pntscount,beginp));
pntscount++;
}
if(bchangeend==false)
{
m_map2sidePnts.insert(make_pair(pntscount,endp));
pntscount++;
}
if(bchangebegin ||bchangeend)
{
vcpnts.push_back(beginp);
k=((dL-dF)/step);
for(int i=1;i<k;i++)
{
tempp=curve->Value(dF+i*step);
vcpnts.push_back(tempp);
}
vcpnts.push_back(endp);
Handle(TColgp_HArray1OfPnt) harray =new TColgp_HArray1OfPnt (1,vcpnts.size()); // sizing harray
for (int j=1;j<=vcpnts.size();j++)
{
harray->SetValue(j,vcpnts.at(j-1)) ;
}
GeomAPI_Interpolate anInterpolation(harray,Standard_False,Precision::Confusion());
anInterpolation.Perform();
Handle(Geom_BSplineCurve) SPL2;
if (anInterpolation.IsDone())
{
vctBSplineCurves.push_back(anInterpolation.Curve());
}
}//end srq 2012-6-3
else
{
vctBSplineCurves.push_back(curve);
}
}
else
{
m_map2sidePnts.insert(make_pair(pntscount,beginp));
pntscount++;
m_map2sidePnts.insert(make_pair(pntscount,endp));
pntscount++;
vctBSplineCurves.push_back(curve);
}
} //if solid
else
{
vctBSplineCurves.push_back(curve);
}
}
}
catch(Standard_Failure)
{
continue;
throw c1;
}
for (int i=0;i<vctResultDatas.size();i++)
{
if(vctResultDatas.at(i).m_iFlag == -1)
{
vctBSplineCurves.at(i)->Reverse();
}
}
////多边形拆分 yc 20140804
map<int, vector<TopoDS_Edge>> wireSet;
try
{
wireSet = SplitPolygon(vctBSplineCurves);
}
catch(Standard_Failure)
{
}
catch(TopoDS_Shape)
{
}
//static int yyy = 0;
//cout<<"yyy"<<yyy<<endl;
if(wireSet.size() == 0)
{
BRep_Builder b;
TopoDS_Compound c;
b.MakeCompound(c);
for(int k = 0; k < vctBSplineCurves.size(); k++)
{
b.Add(c, BRepBuilderAPI_MakeEdge(vctBSplineCurves[k]));
}
continue;
throw c;
}
for(map<int, vector<TopoDS_Edge>>::iterator iter_w = wireSet.begin(); iter_w != wireSet.end(); iter_w ++)
{
mapResultWires.insert(make_pair(mapResultWires.size(), iter_w->second));
}
}
return true;
}
bool CSplitAllInsectionCurves::isOnPlan(vector<Handle(Geom_BSplineCurve)> vctBSplineCurves, gp_Pln& pln)
{
int size = 10;
TColgp_Array1OfPnt anArrayofPnt (1,vctBSplineCurves.size() * size); // sizing array
int index = 1;
for(int i = 0; i < vctBSplineCurves.size(); i++)
{
//Handle(Geom_Curve) aCur = vctBSplineCurves[i];
//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();
//Handle(Geom_TrimmedCurve) myTrimmed = new Geom_TrimmedCurve(aCur, st1, st2);
double df,dl;
Handle(Geom_Curve) aCur = BRep_Tool::Curve(BRepBuilderAPI_MakeEdge(vctBSplineCurves[i]),df,dl);
//sp = aCur->Value(df);
//ep = aCur->Value(dl);
for(int j = 0; j < size; j++)
{
double val = j / (size - 1.0) * (dl - df) + df;
anArrayofPnt.SetValue(index++, vctBSplineCurves[i]->Value(val));
}
}
GProp_PEquation PE (anArrayofPnt,0.01);
if(PE.IsPlanar())
{
pln = PE.Plane();
return true;
}
return false;
}
Handle(Geom_BSplineCurve) CSplitAllInsectionCurves::GetBSplineCurve(const TopoDS_Shape& aS)
{
if(aS.ShapeType() != TopAbs_EDGE)
return FALSE;
//
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();
Handle(Geom_BSplineCurve) aBC = GeomConvert::CurveToBSplineCurve(aTC);
if(aBC->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
{
m_bsplCur = Handle(Geom_BSplineCurve)::DownCast(aCur->Copy());//记录备份,防止改变原来的曲线。
m_bsplCur->Segment(dF,dL);//切断,取一部分
}
}
return m_bsplCur;
}
bool CSplitAllInsectionCurves::haveInsect( std::vector<pair<int,int>>& haveInsects ,int id1,int id2,bool autosave /*= true*/)
{
for (std::vector<pair<int,int>>::const_iterator it2 = haveInsects.begin();it2!=haveInsects.end();++it2 )
{
if((it2->first ==id1 && it2->second == id2) || (it2->first ==id2 && it2->second == id1))
return true;
}
if(autosave)
{
haveInsects.push_back(make_pair(id1,id2));
}
return false;
}
void CSplitAllInsectionCurves::CalcInsectionSections()
{
int iSectInfoID = 1;
for (std::map<int,TopoDS_Edge>::const_iterator it1 = m_mapAllWires.begin();it1!=m_mapAllWires.end();++it1 )
{
std::vector<int> ptids;
FindWirePoints(it1->first,ptids);
SortByWire(it1->first,ptids); //得到一条按照顺序排列的点
if(ptids.size() > 2)
{
for (int i=1;i<ptids.size();i++)
{
CInsectionSectionInfo sectinfo;
sectinfo.m_BelongWireID = it1->first;
sectinfo.m_startInsection = ptids.at(i-1);
sectinfo.m_endInsection = ptids.at(i);
sectinfo.m_Id = iSectInfoID;
iSectInfoID++;
m_mapAllInsectionSectionInfo.insert(make_pair(sectinfo.m_Id,sectinfo));
}
}
else if(ptids.size() == 2)
{
CInsectionSectionInfo sectinfo;
sectinfo.m_BelongWireID = it1->first;
sectinfo.m_startInsection = ptids.front();
sectinfo.m_endInsection = ptids.back();
sectinfo.m_Id = iSectInfoID;
iSectInfoID++;
m_mapAllInsectionSectionInfo.insert(make_pair(sectinfo.m_Id,sectinfo));
}
// m_mapAllWirePointids.insert(make_pair(it1->first,ptids));
}
}
//*********** flag ************************************** 交点约束
void CSplitAllInsectionCurves::CalcInsectionPoints()
{
std::vector<pair<int,int>> haveInsects;
std::map<int,Point3D>::const_iterator iter_point;
std::map<int,Curve>::const_iterator iter_curve;
int autoID = 1;
for (std::map<int,TopoDS_Edge>::const_iterator it1 = m_mapAllWires.begin();it1!=m_mapAllWires.end();++it1 )
{
iter_curve = m_mapCurves.find(it1->first);
Curve curve = iter_curve->second;
if(curve.Type != 0)
{
continue;
}
for(int i = 0; i < MAX_ARRAY_SIZE_L; i++)
{
int pointID = curve.Src[i];
if(pointID == 0)
{
break;
}
iter_point = m_mapPoints.find(pointID);
Point3D point = iter_point->second;
if(point.Type != 1)
{
continue;
}
gp_Pnt pointInter(point.X, point.Y, point.Z);
int iBelongid = 0 ;
if(!haveInsectPoint(pointInter,iBelongid))
{
CInsectionInfo aInfo;
aInfo.m_Id = autoID;
autoID++;
aInfo.m_PtCoor = pointInter;
aInfo.m_vctBelongWireIDs.push_back(iter_curve->first);
aInfo.m_vctBelongWireIDs.push_back(point.Src[0]);
m_mapAllInsectionPoints.insert(make_pair(aInfo.m_Id,aInfo));
}
else
{
std::vector<int>& vctBelongWireIDs= m_mapAllInsectionPoints[iBelongid].m_vctBelongWireIDs;
std::vector<int>::iterator it1find = find(vctBelongWireIDs.begin(),vctBelongWireIDs.end(),iter_curve->first);
std::vector<int>::iterator it2find = find(vctBelongWireIDs.begin(),vctBelongWireIDs.end(),point.Src[0]);
if(it1find == vctBelongWireIDs.end())
{
vctBelongWireIDs.push_back(iter_curve->first);
}
if(it2find == vctBelongWireIDs.end())
{
vctBelongWireIDs.push_back(point.Src[0]);
}
}
}
}
}
//**************************************************************************
void CSplitAllInsectionCurves::FindWirePoints(int iWireID,std::vector<int>& ptids)
{
ptids.clear();
for(std::map<int,CInsectionInfo>::iterator pit = m_mapAllInsectionPoints.begin();pit!=m_mapAllInsectionPoints.end();++pit)
{
std::vector<int>::iterator pItFind = find(pit->second.m_vctBelongWireIDs.begin(),pit->second.m_vctBelongWireIDs.end(),iWireID);
if(pItFind != pit->second.m_vctBelongWireIDs.end())
ptids.push_back(pit->first);
}
}
void CSplitAllInsectionCurves::GetWireStartEndPoint( const TopoDS_Wire& wire,gp_Pnt& sp,gp_Pnt& ep )
{
TopExp_Explorer ex;
int iIndex = 0 ;
for(ex.Init(wire,TopAbs_VERTEX);ex.More();ex.Next(),iIndex++)
{
TopoDS_Vertex aE = TopoDS::Vertex(ex.Current());
if(aE.IsNull())
continue;
if(iIndex == 0)
{
sp = BRep_Tool::Pnt(aE);
}
else
{
ep = BRep_Tool::Pnt(aE);
}
}
}
void CSplitAllInsectionCurves::SortByWire( int iWireID,std::vector<int>& ptids )
{
std::map<Standard_Real,int> ptCoors;
for (std::vector<int>::iterator pit = ptids.begin();pit != ptids.end();++pit)
{
if(m_mapAllInsectionPoints.find(*pit) != m_mapAllInsectionPoints.end())
{
if(m_mapAllWires.find(iWireID) != m_mapAllWires.end())
{
ptCoors.insert(make_pair(GetPoint2StartByWire(m_mapAllWires[iWireID],m_mapAllInsectionPoints[*pit].m_PtCoor),*pit)) ;
}
}
}
ptids.clear();
for ( std::map<Standard_Real,int>::iterator pit = ptCoors.begin();pit!=ptCoors.end();++pit)
{
ptids.push_back(pit->second);
}
}
void CSplitAllInsectionCurves::SortByWire( int iWireID,std::vector<gp_Pnt>& pts )
{
vector<int> ptids;
map<int,gp_Pnt> mappts;
}
Standard_Real CSplitAllInsectionCurves::GetPoint2StartByWire( const TopoDS_Edge& wire,const gp_Pnt& pt )
{
//构造一条分割线
Standard_Real length = 0.0;
if(wire.IsNull())
return length;
gp_Pnt sp,ep;
GetEdgeStartEndPoint(wire,sp,ep);
if(pt.IsEqual(sp,m_precision))
//if(pt.IsEqual(sp,Precision::Confusion()))
{
length = 0;
}
//else if(pt.IsEqual(ep,Precision::Confusion()))
else if(pt.IsEqual(ep,m_precision))
{
length = GetEdgeLength(wire);
}
else if(!IsPointOnEdge(wire,pt))
{
length = 0.0;
}
else
{
TopoDS_Edge newEdge;
TrimEdgeBy2Points(wire,sp,pt,newEdge);
length = GetEdgeLength(newEdge);
}
return length;
}
bool CSplitAllInsectionCurves::haveInsectPoint( gp_Pnt pt ,int& iBelongid)
{
for(std::map<int,CInsectionInfo>::iterator pit = m_mapAllInsectionPoints.begin();pit!=m_mapAllInsectionPoints.end();++pit)
{
//if(pt.IsEqual(pit->second.m_PtCoor,Precision::Confusion())) //srq 2012-5-31
if(pt.IsEqual(pit->second.m_PtCoor,m_precision))//srq 2012-5-31
{
iBelongid = pit->first;
return true;
}
}
return false;
}
bool CSplitAllInsectionCurves::GetNextPointCollect( int iMasterID,vector<int>& slaveids )
{
slaveids.clear();
if(m_mapInsectionAround.find(iMasterID) != m_mapInsectionAround.end())
{
slaveids = m_mapInsectionAround[iMasterID];
std::sort(slaveids.begin(),slaveids.end());
std::vector<int> ::iterator pit = std::unique(slaveids.begin(),slaveids.end());
slaveids.erase(pit,slaveids.end());
}
else
return false;
return true;
}
bool CSplitAllInsectionCurves::GetClosedPoints( int iMasterID,int iStep)
{
vector<int> slaveids;
if(iStep == 3)
{
vector<int> innerslaveids1;
GetNextPointCollect(iMasterID,innerslaveids1);
for ( vector<int>::iterator pit1 =innerslaveids1.begin();pit1!=innerslaveids1.end();++pit1 )
{
if(*pit1 == iMasterID)
continue;
vector<int> innerslaveids2;
GetNextPointCollect(*pit1,innerslaveids2);
for ( vector<int>::iterator pit2 =innerslaveids2.begin();pit2!=innerslaveids2.end();++pit2 )
{
if(*pit2 == iMasterID|| *pit2 == *pit1)
continue;
vector<int> innerslaveids3;
GetNextPointCollect(*pit2,innerslaveids3);
for ( vector<int>::iterator pit3 =innerslaveids3.begin();pit3!=innerslaveids3.end();++pit3 )
{
if(*pit3 == *pit1 || *pit3 == *pit2)
continue;
if(*pit3 == iMasterID)
{
slaveids.clear();
slaveids.push_back(*pit3);
slaveids.push_back(*pit2);
slaveids.push_back(*pit1);
if(IsExistClosedZoom(slaveids))
continue;
else
{
m_mapClosedZooms.insert(make_pair(m_ClosedZoomID,slaveids));
AddHalfEdgeUse(slaveids);
m_ClosedZoomID++;
}
}
}
}
}
}
else if(iStep == 4)
{
vector<int> innerslaveids1;
GetNextPointCollect(iMasterID,innerslaveids1);
for ( vector<int>::iterator pit1 =innerslaveids1.begin();pit1!=innerslaveids1.end();++pit1 )
{
if(*pit1 == iMasterID)
continue;
vector<int> innerslaveids2;
GetNextPointCollect(*pit1,innerslaveids2);
for ( vector<int>::iterator pit2 =innerslaveids2.begin();pit2!=innerslaveids2.end();++pit2 )
{
if(*pit2 == iMasterID || *pit2 == *pit1)
continue;
vector<int> innerslaveids3;
GetNextPointCollect(*pit2,innerslaveids3);
for ( vector<int>::iterator pit3 =innerslaveids3.begin();pit3!=innerslaveids3.end();++pit3 )
{
if(*pit3 == iMasterID || *pit3 == *pit2 || *pit3 == *pit1)
continue;
vector<int> innerslaveids4;
GetNextPointCollect(*pit3,innerslaveids4);
for ( vector<int>::iterator pit4 =innerslaveids4.begin();pit4!=innerslaveids4.end();++pit4 )
{
if(*pit4 == *pit3 || *pit4 == *pit2 || *pit4 == *pit1)
continue;
if(*pit4 == iMasterID)
{
slaveids.clear();
slaveids.push_back(*pit4);
slaveids.push_back(*pit3);
slaveids.push_back(*pit2);
slaveids.push_back(*pit1);
if(IsExistClosedZoom(slaveids))
continue;
else
{
m_mapClosedZooms.insert(make_pair(m_ClosedZoomID,slaveids));
AddHalfEdgeUse(slaveids);
m_ClosedZoomID++;
}
}
}
}
}
}
}
return true;
}
// ADDED BY XUEFENG 20180731
// FOR CODES COMBINE
// ADDED BY XUEFENG
//
// 递归函数
// 通过起始点ID前一个点ID前一个线段ID步数已走过的点和线段队列
// 进行迭代直到回到起始点。
void CSplitAllInsectionCurves::GridAlgorithm_Recursion(int firstPointId, int prePointId, int preArcId, int realStep,
bool strictStep, std::vector<Point_Arc_Pair> existPointArcs)
{
std::map<int, std::map<int,int>>::iterator PointToArc_EndPointIt = this->m_mapFromPointStartToEndArc.find(prePointId);
if(PointToArc_EndPointIt!=this->m_mapFromPointStartToEndArc.end())
{
std::map<int,int> newWays = PointToArc_EndPointIt->second;
for(std::map<int,int>::iterator pit=newWays.begin(); pit!=newWays.end(); ++pit)
{
int newArcId = pit->first;
int newEndPointId = pit->second;
if( newArcId==preArcId )
continue;
//判断前后线段是否是同一个几何曲线
//bool isTheSameWire = this->GridAlgorithm_JudgeTheSameWire( newArcId,preArcId );
//判断新线段是否和之前的线段同一个几何曲线
bool isTheSameWire = this->GridAlgorithm_JudgeInTheSameWire( newArcId, existPointArcs );
if(strictStep==true && isTheSameWire==true )
continue;
// 实际步数不能大于5
int newStep = isTheSameWire?realStep:(realStep+1);
//if( newStep>=6 ) // DELETE BY XUEFENG 20190622
if( newStep>=5 ) // ADDED BY XUEFENG 20190622
continue;
// Back to the start point.
// 回到起始点
if( newEndPointId==firstPointId )
{
std::vector<Point_Arc_Pair> newPointArc = this->GridAlgorithm_Copy_PointArc_Vector(existPointArcs);
newPointArc.push_back( make_pair(prePointId,newArcId) );
this->SuccessfulGridVector.push_back(newPointArc);
this->SuccessfulGridWireNumVector.push_back(newStep);
return; // ADDED BY XUEFENG 20190902
}
// 判断新的点是否已经出现在回路上
bool alreadyExist = this->GridAlgorithm_FindExistOrNot(newEndPointId, existPointArcs);
if(alreadyExist==true)
continue;
{
// 进行下一步迭代
int newPrePointId = newEndPointId;
int newPreArcId = newArcId;
std::vector<Point_Arc_Pair> newPointsArcs = this->GridAlgorithm_Copy_PointArc_Vector(existPointArcs);
newPointsArcs.push_back(make_pair(prePointId,newArcId));
GridAlgorithm_Recursion(firstPointId, newPrePointId, newPreArcId, newStep, strictStep, newPointsArcs);
}
}
}
}
// new Algrothm to construct grid
// 查找封闭回路的算法
void CSplitAllInsectionCurves::GridAlgorithm_ConstructGrid()
{
//
this->GridAlgorithm_DoPrepairData();
for(std::map< int, std::map<int, int> >::iterator pit = this->m_mapFromPointStartToEndArc.begin();pit!=this->m_mapFromPointStartToEndArc.end();++pit)
{
int startPointId = pit->first;
int prePointId = startPointId;
int preArcId = -1;
int realStep = 0;
std::vector<Point_Arc_Pair> existPointArcs;
// 严格的查找封闭回路,不允许两条边在一条几何曲线上
this->GridAlgorithm_Recursion(startPointId, prePointId, preArcId, realStep, true, existPointArcs); // Be strict to find grid circles.
if(this->SuccessfulGridVector.size()!=0)
{
// 每次只记录最小的封闭回路
std::vector<Point_Arc_Pair> foundPointArcVector = this->GridAlgorithm_FindSmallestAndNewOne();
//this->XF_DoRemoveArcActions();
this->GridAlgorithm_DoCleanAffairs(); // m_mapArc_CanBeUsedNum -1, and remove some arcs(just one point only has two arcs,and these two arcs are be used.).
}
}
// 移除不会再被使用的边和点
// 可能会有问题!!!
this->GridAlgorithm_DoRemoveArcActionsOnlyArcs();
this->GridAlgorithm_DoRemoveArcActions();
for(std::map< int, std::map<int, int> >::iterator pit = this->m_mapFromPointStartToEndArc.begin();
pit!=this->m_mapFromPointStartToEndArc.end();++pit)
{
int startPointId = pit->first;
int prePointId = startPointId;
int preArcId = -1;
int realStep = 0;
std::vector<Point_Arc_Pair> existPointArcs;
// 松弛的查找封闭回路,允许两条边在一条几何曲线上
this->GridAlgorithm_Recursion(startPointId, prePointId, preArcId, realStep, false, existPointArcs);
if(this->SuccessfulGridVector.size()!=0)
{
continue;// ADDED BY XUEFENG 20190902
// DELETE BY XUEFENG 20190823
/*
std::vector<Point_Arc_Pair> foundPointArcVector = this->GridAlgorithm_FindSmallestAndNewOne();
this->GridAlgorithm_DoCleanAffairs();
this->GridAlgorithm_DoRemoveArcActions();
*/
// END DELETE
}
}
// ADDED BY XUEFENG
// 20190823
this->GridAlgorithm_FindSmallestArcAndNewOne();
this->GridAlgorithm_FinalVectorToResult();
}
// 根据 m_mapAllInsectionPoints和m_mapAllInsectionSectionInfo数据结构
// 构建 m_mapFromPointStartToEndArc数据结构
// m_mapFromPointStartToEndArc数据结构存储每一个点的ID和到其他点的ID以及经过弧段的ID
void CSplitAllInsectionCurves::GridAlgorithm_DoPrepairData()
{
for(std::map<int,CInsectionInfo>::iterator pit = this->m_mapAllInsectionPoints.begin();pit!=this->m_mapAllInsectionPoints.end();++pit)
{
int startPointId = pit->first;
std::map<int, int> ArcId_EndPointId;
int finalArtId = -1;
int finalEndPointId = -1;
for(std::map<int,CInsectionSectionInfo>::iterator pit2 = this->m_mapAllInsectionSectionInfo.begin();pit2!=this->m_mapAllInsectionSectionInfo.end();++pit2)
{
int tmpArcId = pit2->first;
this->m_mapArcIdOrigWiredId.insert( make_pair(tmpArcId, pit2->second.m_BelongWireID) );
this->m_mapArc_CanBeUsedNum.insert(make_pair(tmpArcId, 2));
int tmpEndPointId=-1;
if(pit2->second.m_startInsection==startPointId)
{
tmpEndPointId = pit2->second.m_endInsection;
}
else if(pit2->second.m_endInsection==startPointId)
{
tmpEndPointId = pit2->second.m_startInsection;
}
if( tmpEndPointId!=-1 )
{
ArcId_EndPointId.insert( make_pair(tmpArcId, tmpEndPointId) );
Point_Point_Pair PP = make_pair(startPointId, tmpEndPointId);
this->m_mapArc_point1_point2.insert( make_pair(tmpArcId, PP) );
}
}
this->m_mapFromPointStartToEndArc.insert( make_pair(startPointId, ArcId_EndPointId ) );
}
// Finished init
// std::map< int, int > m_mapArcIdOrigWiredId; // std::map<int ArcId, int WireId>
// std::map< int, std::map<int, int> > m_mapFromPointStartToEndArc; // std::map< int pointId, <int arcId, int endPointId>, ... ,<int arcId, int endPointId> >
}
// 根据递归函数搜索到的网格,选取其中最小的且不与已经找到的网格重复的网格
// 需要用到GridAlgorithm_CompareExistFinalVector函数判断是否已经存在
//
std::vector<Point_Arc_Pair> CSplitAllInsectionCurves::GridAlgorithm_FindSmallestAndNewOne()
{
std::vector<Point_Arc_Pair> returnVector;
for(int i=0;i<SuccessfulGridVector.size();i++)
{
int smallestNum = SuccessfulGridWireNumVector[i];
for(int j=i;j<SuccessfulGridWireNumVector.size();j++)
{
if(smallestNum>SuccessfulGridWireNumVector[j])
{
smallestNum = SuccessfulGridWireNumVector[j];
SuccessfulGridWireNumVector[j] = SuccessfulGridWireNumVector[i];
SuccessfulGridWireNumVector[i] = smallestNum;
std::vector<Point_Arc_Pair> tmpVector = SuccessfulGridVector[j];
SuccessfulGridVector[j] = SuccessfulGridVector[i];
SuccessfulGridVector[i] = tmpVector;
}
}
}
for(int i=0;i<SuccessfulGridVector.size();i++)
{
std::vector<Point_Arc_Pair> tmpPA = SuccessfulGridVector[i];
bool canBeInsert = this->GridAlgorithm_CompareExistFinalVector(tmpPA);
if(canBeInsert==true)
{
this->finalFoundGridFaceVector.push_back(tmpPA);
returnVector = tmpPA;
return returnVector;
}
}
return returnVector;
}
// XUEFENG ADDED 20190824
// 在松弛的查找后得到从一点出发的若干个环的vector
// 从该vector中选取弧段最少的可行的环加入finalFoundGridFaceVector
std::vector<Point_Arc_Pair> CSplitAllInsectionCurves::GridAlgorithm_FindSmallestArcAndNewOne()
{
std::vector<Point_Arc_Pair> returnVector;
// Sort the found vector by arc number.
for(int i=0;i<SuccessfulGridVector.size();i++)
{
int smallestNum = SuccessfulGridVector[i].size();
for(int j=i;j<SuccessfulGridVector.size();j++)
{
if(smallestNum>SuccessfulGridVector[j].size())
{
smallestNum = SuccessfulGridVector[j].size();
//SuccessfulGridWireNumVector[j] = SuccessfulGridWireNumVector[i];
//SuccessfulGridWireNumVector[i] = smallestNum;
std::vector<Point_Arc_Pair> tmpVector = SuccessfulGridVector[j];
SuccessfulGridVector[j] = SuccessfulGridVector[i];
SuccessfulGridVector[i] = tmpVector;
}
}
}
// Can insert more than one circle.
for(int i=0;i<SuccessfulGridVector.size();i++)
{
std::vector<Point_Arc_Pair> tmpPA = SuccessfulGridVector[i];
bool canBeInsert = this->GridAlgorithm_CompareExistFinalVector(tmpPA);
// ADDED BY XUEFENG 20190824
bool NoOverlap = this->GridAlgorithm_FindOverlapWithFinalVector(tmpPA);
if(canBeInsert==true&&NoOverlap==true)
{
this->finalFoundGridFaceVector.push_back(tmpPA);
returnVector = tmpPA;
//this->GridAlgorithm_DoCleanAffairs();
this->GridAlgorithm_DoRemoveArcActionsOnlyArcs();
this->GridAlgorithm_DoRemoveArcActions();
//return returnVector;
}
}
return returnVector;
}
// END ADDED
// ADDED BY XUEFENG 20190824
// THIS FUNCTION
// 判断std::vector<Point_Arc_Pair> inputPA的边是否和已有的封闭回路中边重叠超过2
// 松弛查找的专用
bool CSplitAllInsectionCurves::GridAlgorithm_FindOverlapWithFinalVector(std::vector<Point_Arc_Pair> inputPA)
{
std::vector<int> sortArc = this->GridAlgorithm_DoSortArcVector(inputPA);
bool result = true;
for(int i=0;i<sortArc.size();i++)
{
int num=0;
int newArcId = sortArc[i];
for(int j=0;j<this->finalFoundGridFaceVector.size();j++)
{
std::vector<Point_Arc_Pair> existVector = this->finalFoundGridFaceVector[j];
for(int k=0;k<existVector.size();k++)
{
int oldArcId = existVector[k].second;
if(newArcId==oldArcId)
num++;
}
}
if(num==2)
{
result = false;
break;
}
}
return result;
}
// END ADDED
// 判断std::vector<Point_Arc_Pair> inputPA是否已经存在在已有的封闭回路中
// 使用GridAlgorithm_BigVecIncludeSmallVec函数判断inputPA回路是否包含已有的回路
bool CSplitAllInsectionCurves::GridAlgorithm_CompareExistFinalVector(std::vector<Point_Arc_Pair> inputPA)
{
std::vector<int> sortArc = this->GridAlgorithm_DoSortArcVector(inputPA);
for(int i=0;i<this->finalFoundGridFaceVector.size();i++)
{
std::vector<Point_Arc_Pair> existVector = this->finalFoundGridFaceVector[i];
std::vector<int> sortExistArc = this->GridAlgorithm_DoSortArcVector(existVector);
if(sortExistArc.size()!=sortArc.size())
{
// Judge Include or Not
bool newVecIncludeOldOne = this->GridAlgorithm_BigVecIncludeSmallVec(existVector, inputPA);
// 如果新的回路包含了任意一个已有的回路,这这个新回路不可用
if(newVecIncludeOldOne==true)
return false;
continue;
}
else
{
bool completeEqual = true;
for(int j=0;j<sortExistArc.size();j++)
{
if(sortArc[j]!=sortExistArc[j])
{
completeEqual = false;
break;
}
}
if(completeEqual==true)
return false;
}
}
return true;
}
// 判断 newVector 形成的回路是否包含 existVector 形成的回路
bool CSplitAllInsectionCurves::GridAlgorithm_BigVecIncludeSmallVec(std::vector<Point_Arc_Pair> existVector, std::vector<Point_Arc_Pair> newVector)
{
if(existVector.size()>newVector.size())
return false;
else
{
for(int i=0;i<existVector.size();i++)
{
int existPointId = existVector[i].first;
bool findTheSame = false;
for(int j=0;j<newVector.size();j++)
{
int newPointId = newVector[j].first;
if(newPointId==existPointId)
{
findTheSame = true;
break;
}
}
if(findTheSame==false)
return false;
}
}
return true;
}
// 对inputPA按弧段的ID进行排序
std::vector<int> CSplitAllInsectionCurves::GridAlgorithm_DoSortArcVector(std::vector<Point_Arc_Pair> inputPA)
{
std::vector<int> sortArc;
for(int i=0;i<inputPA.size();i++)
{
int smallestArc = inputPA[i].second;
for(int j=i;j<inputPA.size();j++)
if(inputPA[j].second<smallestArc)
{
smallestArc = inputPA[j].second;
Point_Arc_Pair tmpSmall = inputPA[j];
inputPA[j] = inputPA[i];
inputPA[i] = tmpSmall;
}
sortArc.push_back(smallestArc);
}
return sortArc;
}
// 每次递归调用后,都要对临时存储的回路数据进行清理
void CSplitAllInsectionCurves::GridAlgorithm_DoCleanAffairs()
{
this->SuccessfulGridVector.clear();
this->SuccessfulGridWireNumVector.clear();
}
// 将已经不可以用的点和弧段从m_mapFromPointStartToEndArc数据结构中清除
// 算法思想 1 是一个点只有两个弧段,而且这两个弧段都被使用过,这个点和两个弧段必然不再可用
// 2 另外,当一个弧段被使用了两次后,该弧段也不可用了
//GridAlgorithm_DoRemoveArcActionsOnlyArcs 实现上面提到的算法思想2
void CSplitAllInsectionCurves::GridAlgorithm_DoRemoveArcActionsOnlyArcs()
{
// 去弧段
// 首先,弧段计数
std::map<int,int> tmpArc_UseNum;
std::vector<int> removeArc;
for(int i=0;i<this->finalFoundGridFaceVector.size();i++)
{
std::vector<Point_Arc_Pair> circlePA = this->finalFoundGridFaceVector[i];
for(int j=0;j<circlePA.size();j++)
{
int tmpArcID = circlePA[j].second;
std::map<int,int>::iterator it = tmpArc_UseNum.find(tmpArcID);
if(it==tmpArc_UseNum.end())
tmpArc_UseNum.insert(pair<int,int>(tmpArcID, 1));
else
{
int nowNum = it->second;
if(nowNum==1)
{
it->second = 2;
removeArc.push_back(tmpArcID);
}
else
printf("Something error in arc count!\n");
}
}
}
for(int i=0;i<removeArc.size();i++)
{
int rmArcID = removeArc[i];
for(std::map< int, std::map<int, int> >::iterator pit = this->m_mapFromPointStartToEndArc.begin();
pit!=this->m_mapFromPointStartToEndArc.end();++pit)
{
int startPointId = pit->first;
std::map<int,int> tmpArcToEndPoint = pit->second;
for(std::map<int,int>::iterator pit2=tmpArcToEndPoint.begin(); pit2!=tmpArcToEndPoint.end();++pit2)
{
int nowArcID = pit2->first;
if(rmArcID==nowArcID) // Remove the arc
{
pit->second.erase(nowArcID);
}
}
}
}
}
//实现上面提到的算法思想1
void CSplitAllInsectionCurves::GridAlgorithm_DoRemoveArcActions()
{
// 去点
bool rmArcs = true;
while(rmArcs)
{
rmArcs = false;
for(std::map< int, std::map<int, int> >::iterator pit = this->m_mapFromPointStartToEndArc.begin();
pit!=this->m_mapFromPointStartToEndArc.end();++pit)
{
int startPointId = pit->first;
std::map<int,int> tmpArcToEndPoint = pit->second;
if(tmpArcToEndPoint.size()==2)
{
int arcId[2];
int arcCount=0;
for(std::map<int,int>::iterator pit2=tmpArcToEndPoint.begin(); pit2!=tmpArcToEndPoint.end();++pit2)
{
arcId[arcCount] = pit2->first;
arcCount++;
}
for(int i=0;i<this->finalFoundGridFaceVector.size();i++)
{
bool bothUsed[2] = { false, false };
std::vector<Point_Arc_Pair> circlePA = this->finalFoundGridFaceVector[i];
for(int j=0;j<circlePA.size();j++)
{
if(circlePA[j].second==arcId[0])
bothUsed[0] = true;
if(circlePA[j].second==arcId[1])
bothUsed[1] = true;
}
if(bothUsed[0]==true&&bothUsed[1]==true)
{
for(std::map<int,int>::iterator pit2=tmpArcToEndPoint.begin();
pit2!=tmpArcToEndPoint.end();++pit2)
{
int arcId=pit2->first;
int endPointId = pit2->second;
std::map<int, std::map<int, int> >::iterator findOtherPointMapIt = this->m_mapFromPointStartToEndArc.find(endPointId);
if(findOtherPointMapIt!=this->m_mapFromPointStartToEndArc.end())
findOtherPointMapIt->second.erase(arcId);
}
pit->second.clear();
rmArcs = true;
}
}
}
} // End for
} //End while
}
// 在递归函数中使用
// 判断新找到的点是否已经存在于走过的路径点中?
// 不是起点的路径点
bool CSplitAllInsectionCurves::GridAlgorithm_FindExistOrNot(int newPoint, std::vector<Point_Arc_Pair> existPointsArcs)
{
for(int i=0;i<existPointsArcs.size();i++)
{
if(existPointsArcs[i].first==newPoint)
return true;
}
return false;
}
// 在递归函数中使用
// 创建一个新的点-弧段的容器vector以便下一次迭代
std::vector<Point_Arc_Pair> CSplitAllInsectionCurves::GridAlgorithm_Copy_PointArc_Vector(std::vector<Point_Arc_Pair> existPointsArcs)
{
std::vector<Point_Arc_Pair> newPointsArcs;
for(int i=0;i<existPointsArcs.size();i++)
{
Point_Arc_Pair newPair = make_pair( existPointsArcs[i].first, existPointsArcs[i].second );
newPointsArcs.push_back(newPair);
}
return newPointsArcs;
}
// 在递归函数中使用
// 判断新线和之前已有的线段是否同一个几何曲线
bool CSplitAllInsectionCurves::GridAlgorithm_JudgeInTheSameWire(int arcId1, std::vector<Point_Arc_Pair> existPointArcs)
{
int wireId1 = -1;
int wireId2 = -1;
std::map<int, int>::iterator it1 = this->m_mapArcIdOrigWiredId.find(arcId1);
if(it1!=this->m_mapArcIdOrigWiredId.end())
wireId1 = it1->second;
for(int i=0;i<existPointArcs.size();i++)
{
int arcId2 = existPointArcs[i].second;
std::map<int, int>::iterator it2 = this->m_mapArcIdOrigWiredId.find(arcId2);
if(it2!=this->m_mapArcIdOrigWiredId.end())
wireId2 = it2->second;
if( wireId1==wireId2 && wireId1!=-1)
return true;
}
return false;
}
// 在递归函数中使用
// 判断是否是同一个几何曲线
bool CSplitAllInsectionCurves::GridAlgorithm_JudgeTheSameWire(int arcId1, int arcId2)
{
int wireId1 = -1;
int wireId2 = -1;
std::map<int, int>::iterator it1 = this->m_mapArcIdOrigWiredId.find(arcId1);
if(it1!=this->m_mapArcIdOrigWiredId.end())
wireId1 = it1->second;
std::map<int, int>::iterator it2 = this->m_mapArcIdOrigWiredId.find(arcId2);
if(it2!=this->m_mapArcIdOrigWiredId.end())
wireId2 = it2->second;
if( wireId1==wireId2 && wireId1!=-1)
return true;
return false;
}
// 将最终形成的环加入到 m_ClosedResults 变量中
// 后面的处理将利用 m_ClosedResults 生成相应的边和曲面
// 需要判断形成的环是否合法,主要要判断是否封闭,在误差范围之内
void CSplitAllInsectionCurves::GridAlgorithm_FinalVectorToResult()
{
this->m_ClosedResults.clear();
int finalFaceCount = 1;
for(int i=0;i<this->finalFoundGridFaceVector.size();i++)
{
std::vector<Point_Arc_Pair> tmpPA = this->finalFoundGridFaceVector[i];
// Construct a new tmp point_wire vector.
std::vector<Point_Arc_Pair> tmpPWire;
for(int j=0;j<tmpPA.size();j++)
{
int pointId = tmpPA[j].first;
int arcId = tmpPA[j].second;
std::map<int, int>::iterator ArcWireIt = this->m_mapArcIdOrigWiredId.find(arcId);
if(ArcWireIt!=this->m_mapArcIdOrigWiredId.end())
{
int wireId = ArcWireIt->second;
tmpPWire.push_back(make_pair(pointId, wireId));
}
}
// ADDED BY XUEFENG 201805
// DELETE EXP WIREs
bool allInExp = true;
for(int wireSeq=0;wireSeq<tmpPWire.size();wireSeq++)
{
int wireId = tmpPWire[wireSeq].second;
int expWireSize = this->m_expWireSeqNo.size();
// 遍历一遍所有的约束边
bool findTheSame = false;
for(int exp=0;exp<expWireSize;exp++)
{
if(wireId==this->m_expWireSeqNo[exp])
{
findTheSame = true;
break;
}
}
// 如果有一个边不再约束边中,则这个面可以生成
if(findTheSame==false)
{
allInExp = false;
break;
}
}
// 如果所有的边都是约束边就不生成面调到下一个i+1进行循环
if(allInExp==true)
continue;
// END ADDED 201805
vector<CResultData> resultdatas;
vector<Handle(Geom_BSplineCurve)> closeCurves;
for(int j=0;j<tmpPA.size();j++)
{
int arcId = tmpPA[j].second;
int wireId = tmpPWire[j].second;
if(arcId!=-1)
{
int startPointId = tmpPA[j].first;
int endPointId;
for(int next=j;;) // Direction ++
{
next=(next==(tmpPA.size()-1))?0:(next+1);
if(tmpPWire[next].second==wireId)
{
tmpPA[next].second = -1;
continue;
}
else
{
endPointId = tmpPA[next].first;
break;
}
}
for(int before=j;;) // Direction --
{
before=(before==0)?(tmpPA.size()-1):(before-1);
if(tmpPWire[before].second==wireId)
{
tmpPA[before].second = -1;
startPointId = tmpPA[before].first;
}
else
break;
}
gp_Pnt StartPointPnt, EndPointPnt;
std::map<int,CInsectionInfo>::iterator startPointIt = this->m_mapAllInsectionPoints.find(startPointId);
if(startPointIt!=this->m_mapAllInsectionPoints.end())
StartPointPnt = startPointIt->second.m_PtCoor;
std::map<int,CInsectionInfo>::iterator endPointIt = this->m_mapAllInsectionPoints.find(endPointId);
if(endPointIt!=this->m_mapAllInsectionPoints.end())
EndPointPnt = endPointIt->second.m_PtCoor;
// OLD CODES
// 确定原始曲线,用生成的起点和终点去截原始曲线
CResultData data;
data.m_iWireID = wireId;
data.m_iFlag = 1;
Standard_Real dF,dL;
Handle(Geom_BSplineCurve) aCur = TrimWire2BSplineCurve(m_mapAllWires[data.m_iWireID],StartPointPnt, EndPointPnt,dF,dL);
if(aCur.IsNull()) // pj change aCur == NULL->aCur.IsNull()
continue;
if(dF < dL)
{
data.m_dStartRatio = dF;
data.m_dEndRatio = dL;
}
else
{
data.m_dStartRatio = dL;
data.m_dEndRatio = dF;
}
gp_Pnt tempp1,tempp2;
GetEdgeStartEndPoint(m_mapAllWires[data.m_iWireID],tempp1,tempp2);
if(!tempp1.IsEqual(StartPointPnt,m_precision))//srq 2012-5-31
{
data.m_iFlag *= -1;
}
resultdatas.push_back(data);
closeCurves.push_back(aCur);
}
}
// 判断曲线是否封闭
bool theCurvesAreClosed = this->GridAlgorithm_JudgeCurvesClosed(closeCurves);
if(theCurvesAreClosed==true)
{
// 封闭曲线加入到最后的结果中
this->m_ClosedResults.insert(make_pair(finalFaceCount,resultdatas));
finalFaceCount++;
}
}
}
// 验证传入的 BSpline 曲线是否封闭
// 判断每个点和其他任意一个点是否误差在允许范围之内
bool CSplitAllInsectionCurves::GridAlgorithm_JudgeCurvesClosed(std::vector<Handle(Geom_BSplineCurve)> closeCurves)
{
//double myTol = Precision::Confusion()*100;
double myTol = 0.005; // cqr-20190925 按xuefeng意见修改
for(int i=0;i<closeCurves.size();i++)
{
gp_Pnt startPoint = closeCurves[i]->StartPoint();
gp_Pnt endPoint = closeCurves[i]->EndPoint();
bool startPointConnection = false;
bool endPointConnection = false;
for(int j=0;j<closeCurves.size();j++)
{
if(i!=j)
{
gp_Pnt anotherStartPoint = closeCurves[j]->StartPoint();
gp_Pnt anotherEndPoint = closeCurves[j]->EndPoint();
if(startPoint.Distance(anotherStartPoint)<myTol
||startPoint.Distance(anotherEndPoint)<myTol)
startPointConnection = true;
if(endPoint.Distance(anotherStartPoint)<myTol
||endPoint.Distance(anotherEndPoint)<myTol)
endPointConnection = true;
}
}
// 如果起点或终点没有找到可以连接的点就返回false
if(startPointConnection==false
|| endPointConnection==false)
return false;
}
return true;
}
// 以上以 "GridAlgorithm_*"开头的函数都是为网格化曲面生成添加的
// 入口函数是GridAlgorithm_ConstructGrid
// 在下面bool CSplitAllInsectionCurves::GetClosedZooms()函数中调用
// END ADDED
bool CSplitAllInsectionCurves::GetClosedZooms()
{
// ADDED BY XUEFENG 20180731
// FOR CODES COMBINE
// ADDED BY XUEFENG
// Old Algorithm is SO SO SO BAD!
// Rewrite it.
GridAlgorithm_ConstructGrid();
return true;
// END ADDED
//得到分段集合,查找周边点
for(std::map<int,CInsectionInfo>::iterator pit = m_mapAllInsectionPoints.begin();pit!=m_mapAllInsectionPoints.end();++pit)
{
vector<int> slavePointids;
for(std::map<int,CInsectionSectionInfo>::iterator pit2 = m_mapAllInsectionSectionInfo.begin();pit2!=m_mapAllInsectionSectionInfo.end();++pit2)
{
if(pit2->second.m_startInsection == pit->first)
{
slavePointids.push_back(pit2->second.m_endInsection);
}
else if(pit2->second.m_endInsection == pit->first)
{
slavePointids.push_back(pit2->second.m_startInsection);
}
}
m_mapInsectionAround.insert(make_pair(pit->first,slavePointids));
}
//half edge
for(std::map<int,CInsectionSectionInfo>::iterator pit2 = m_mapAllInsectionSectionInfo.begin();pit2!=m_mapAllInsectionSectionInfo.end();++pit2)
{
pair<int,int> halfedge = make_pair(pit2->second.m_startInsection,pit2->second.m_endInsection);
pair<int,int> opphalfedge = make_pair(pit2->second.m_endInsection,pit2->second.m_startInsection);
CHalfEdgeKey key1;
key1.m_iIntersectionInfoID = pit2->first;
key1.m_iStartPointID = min(halfedge.first,halfedge.second);
key1.m_iEndPointID = max(halfedge.first,halfedge.second);
m_mapHalfEdgesUsed.insert(make_pair(key1,0));
}
if(0)
{
for(std::map<int,CInsectionInfo>::iterator pit = m_mapAllInsectionPoints.begin();pit!=m_mapAllInsectionPoints.end();++pit)
{
bool bFind = false;
for (int i=2;i<=4;i++)
{
if(m_mapAllInsectionPoints.size() < i)
break;
GetClosedPoints(pit->first,i) ;
}
}
}
else
{
ClosedFinder find;
find.border = border;
for(std::map<int,CInsectionInfo>::iterator pit = m_mapAllInsectionPoints.begin();pit!=m_mapAllInsectionPoints.end();++pit)
{
sPoint* pt = new sPoint(); pt->m_Id = pit->first;
pt->m_PtCoor = pit->second.m_PtCoor;
find.addPoint(pt->m_Id, pt);
}
std::map<Point_Key, sPoint*>& mPointsSrc = find.getPoints();
for(std::map<int,CInsectionSectionInfo>::iterator pit2 = m_mapAllInsectionSectionInfo.begin();pit2!=m_mapAllInsectionSectionInfo.end();++pit2)
{
sArc * ptArc = new sArc(); ptArc->m_Id = pit2->first;
ptArc->mPoints.push_back(mPointsSrc[pit2->second.m_startInsection]);
ptArc->mPoints.push_back(mPointsSrc[pit2->second.m_endInsection]);
ptArc->m_IdSrc = pit2->second.m_BelongWireID;
//
find.addArc(ptArc->m_Id, ptArc);
}
//2012-5-21 srq 针对bug 网格线,当输入的数据不能创建面时,系统总非法退出,建议给提示信息。 注交点少于2个是不可能成面的
if(find.GeneralPolygon()<1)
return false;
//if(false)
{
const std::map<Arc_Key , sArc* >& maparcs = find.getArcs();
for (std::map<Arc_Key , sArc* >::const_iterator pit = maparcs.begin();pit!=maparcs.end();++pit)
{
m_mapIntersectinInfoTimeSearchs.insert(make_pair(pit->first,pit->second->mTimeofSearch));
}
const std::map<Polygon_Key, std::list<std::pair<Arc_Key, std::list<sArcHalfEdge> > > >& closepolygons = find.getPolygonsCombin();
std::map<Polygon_Key, std::list<std::pair<Arc_Key, std::list<sArcHalfEdge> > > >::const_reverse_iterator pit = closepolygons.rbegin();
// if(closepolygons.size() >= 2)
// pit ++; //去掉最后一个
for (;pit!=closepolygons.rend();++pit)
{
const std::list<std::pair<Arc_Key, std::list<sArcHalfEdge> > > & poly = pit->second;
int id = pit->first;
if(id == 155)
{
id = id;
}
//const std::vector<sArcHalfEdge>& halfedges= poly.mArcHalfEdge;
vector<int> slaveids;
vector<CResultData> resultdatas;
vector<Handle(Geom_BSplineCurve)> closeCurves;
for (std::list<std::pair<Arc_Key, std::list<sArcHalfEdge> > >::const_iterator pithe = poly.begin();
pithe != poly.end();++pithe)
{
const std::pair<Arc_Key, std::list<sArcHalfEdge> >& halfedge = *pithe ;
// if(halfedge.second.size() >=3)
// {
// _ASSERTE(0);
// }
const sPoint* spt = 0;
const sPoint* ept = 0;
ClosedFinder::getArcHalfEdgeBeginEnd(halfedge.second,spt,ept);
// if (i++ <4) //TODO : Test
{
slaveids.push_back(spt->m_Id);
}
//
CResultData data;
data.m_iWireID = halfedge.first;
data.m_iFlag = 1/*halfedge.mDirection == EAD_Begin2End ? 1 : -1*/;
Standard_Real dF,dL;
Handle(Geom_BSplineCurve) aCur = TrimWire2BSplineCurve(m_mapAllWires[data.m_iWireID],spt->m_PtCoor,ept->m_PtCoor,dF,dL);
if(aCur.IsNull()) // pj change aCur == NULL->aCur.IsNull()
continue;
if(dF < dL)
{
data.m_dStartRatio = dF;
data.m_dEndRatio = dL;
}
else
{
data.m_dStartRatio = dL;
data.m_dEndRatio = dF;
}
gp_Pnt tempp1,tempp2;
GetEdgeStartEndPoint(m_mapAllWires[data.m_iWireID],tempp1,tempp2);
if(!tempp1.IsEqual(spt->m_PtCoor,m_precision))//srq 2012-5-31
{
data.m_iFlag *= -1;
}
//if(aCur != NULL)
//{
// ShowBSplineStartEndPoint(aCur);
// Handle(Geom_BSplineCurve) aCur2 = TrimWire2BSplineCurve(m_mapAllWires[data.m_iWireID],dF,dL);
// ShowBSplineStartEndPoint(aCur2);
//}
resultdatas.push_back(data);
closeCurves.push_back(aCur);
}
m_ClosedResults.insert(make_pair(pit->first,resultdatas));
m_mapClosedZooms.insert(make_pair(pit->first,slaveids));
m_mapClosedBSplineCurves.insert(make_pair(pit->first,closeCurves));
}
}
//ClearMaxEdgeBoundingBox();
}
return true;
}
bool CSplitAllInsectionCurves::IsExistClosedZoom( const vector<int>& slaveids )
{
std::set<int> setids = convertvct2set(slaveids);
for (std::map<int,vector<int>>::iterator pit = m_mapClosedZooms.begin();pit!=m_mapClosedZooms.end();++pit)
{
if(IsIncludeClosedZoom(pit->second,slaveids))
return true;
}
return false;
}
std::set<int> CSplitAllInsectionCurves::convertvct2set( const vector<int>& slaveids )
{
std::set<int> setids;
for (vector<int>::const_iterator pit=slaveids.begin();pit!=slaveids.end();++pit)
{
setids.insert(*pit);
}
return setids;
}
//前面是3个点后面是4个点
bool CSplitAllInsectionCurves::IsIncludeClosedZoom(const vector<int>& srcids,const vector<int>& slaveids)
{
//std::set<int> setsrcids = convertvct2set(srcids);
std::set<int> setdeoids = convertvct2set(slaveids);
//CString srcstring = Set2String(setsrcids);
std::string deostring = Set2String(setdeoids);
int iCounts = 0 ;
for (vector<int>::const_iterator pit= srcids.begin();pit!=srcids.end();++pit)
{
std::string str = "";
//str.Format(_T("[%d]"),*pit);
str = "[]" + std::to_string(*pit) + "]";
//if(deostring.Find(str) != -1)
if(deostring.find(str) != std::string::npos)
{
iCounts++;
}
}
if(iCounts >= 3)
return true;
return false;
}
std::string CSplitAllInsectionCurves::Set2String( const std::set<int>& setids )
{
std::string strset = "";
for (std::set<int>::const_iterator pit = setids.begin();pit!=setids.end();++pit)
{
std::string str = "";
//str.Format(_T("[%d]"),*pit);
str = "[]" + std::to_string(*pit) + "]";
strset += str;
}
return strset;
}
bool CSplitAllInsectionCurves::TrimWireBy2Points( const gp_Pnt& pt1,const gp_Pnt& pt2,const TopoDS_Wire& srcwire,TopoDS_Edge& newwire,TopoDS_Edge& basicedge )
{
TopExp_Explorer ex;
for(ex.Init(srcwire,TopAbs_EDGE);ex.More();ex.Next())
{
TopoDS_Edge aE = TopoDS::Edge(ex.Current());
if(aE.IsNull())
continue;
if(TrimEdgeBy2Points(aE,pt1,pt2,newwire))
{
basicedge = aE;
break;
}
}
return true;
}
void CSplitAllInsectionCurves::GetEdgeStartEndPoint( const TopoDS_Edge& edge,gp_Pnt& sp,gp_Pnt& ep )
{
// TopExp_Explorer ex;
//
// int iIndex = 0 ;
// for(ex.Init(edge,TopAbs_VERTEX);ex.More();ex.Next(),iIndex++)
// {
// TopoDS_Vertex aE = TopoDS::Vertex(ex.Current());
// if(aE.IsNull())
// continue;
//
// if(iIndex == 0)
// {
// sp = BRep_Tool::Pnt(aE);
// }
// else
// {
// ep = BRep_Tool::Pnt(aE);
// }
// }
//double df,dl;
//Handle(Geom_Curve) aCur = BRep_Tool::Curve(edge,df,dl);
//sp = aCur->Value(df);
//ep = aCur->Value(dl);
//TopoDS_Vertex sv,ev;
//TopExp::Vertices(edge,sv,ev);
//sp = BRep_Tool::Pnt(sv);
//ep = BRep_Tool::Pnt(ev);
double df,dl;
BRep_Tool::Curve(edge,df,dl);
Handle(Geom_BSplineCurve) newCurve = TrimWire2BSplineCurve(edge,df,dl);
sp = newCurve->StartPoint();
ep = newCurve->EndPoint();
}
bool CSplitAllInsectionCurves::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 < m_precision);
return flag;
}
bool CSplitAllInsectionCurves::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();
BaseAlgo algo;
Standard_Real st1 = algo.ProjectPointOnCurvePara(edge, pt1);
Standard_Real st2 = algo.ProjectPointOnCurvePara(edge, pt2);
Handle(Geom_TrimmedCurve) myTrimmed = new Geom_TrimmedCurve(aCur, st1, st2);
newEdge = BRepBuilderAPI_MakeEdge(myTrimmed);
gp_Pnt p1, p2;
GetEdgeStartEndPoint(newEdge, p1, p2);
// BRepBuilderAPI_MakeEdge makeedge;
// makeedge.Init(aCur,pt1,pt2);
// if(makeedge.IsDone())
// {
// newEdge = makeedge.Edge();
// }
// else
// {
// BRepBuilderAPI_EdgeError errorly= makeedge.Error();
// return false;
// }
//newEdge = BRepBuilderAPI_MakeEdge();
//Handle(Geom_Curve) aCur = BRep_Tool::Curve(newEdge,df,dl);
}
else
{
return false;
}
}
catch (Standard_ConstructionError e)
{
Standard_CString str = e.GetMessageString();
return false;
}
return true;
}
bool CSplitAllInsectionCurves::GetInsectionSectionInfoId( int InsectionPoint1,int InsectionPoint2,int& InsectionSectionInfoId )
{
for(std::map<int,CInsectionSectionInfo>::iterator pit2 = m_mapAllInsectionSectionInfo.begin();pit2!=m_mapAllInsectionSectionInfo.end();++pit2)
{
if((pit2->second.m_startInsection == InsectionPoint1 && pit2->second.m_endInsection == InsectionPoint2)
||(pit2->second.m_startInsection == InsectionPoint2 && pit2->second.m_endInsection == InsectionPoint1))
{
InsectionSectionInfoId = pit2->first;
return true;
}
}
return false;
}
void CSplitAllInsectionCurves::GetClosedShapes( std::map<int,TopoDS_Shape>& shapes )
{
shapes = m_mapClosedShape;
}
Handle(Geom_BSplineCurve) CSplitAllInsectionCurves::ConvertEdge2BSplineCurve( const TopoDS_Edge& edge )
{
double df,dl;
Handle(Geom_Curve) aCur = BRep_Tool::Curve(edge,df,dl);
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) BSplineCurve = NULL;
if(aCur.IsNull()) return NULL;
if (aCur->IsKind(STANDARD_TYPE(Geom_BoundedCurve)))
{
if (aCur->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
{
BSplineCurve = Handle(Geom_BSplineCurve)::DownCast(aCur->Copy()) ;
}
else if (aCur->IsKind(STANDARD_TYPE(Geom_BezierCurve)))
{
}
else if ( aCur->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
{
}
}
else if (aCur->IsKind(STANDARD_TYPE(Geom_Conic)))
{
if (aCur->IsKind(STANDARD_TYPE(Geom_Circle)))
{
}
else if (aCur->IsKind(STANDARD_TYPE(Geom_Ellipse)))
{
}
else if ( aCur->IsKind(STANDARD_TYPE(Geom_Hyperbola)))
{
}
else if ( aCur->IsKind(STANDARD_TYPE(Geom_Parabola)))
{
}
}
else if ( aCur->IsKind(STANDARD_TYPE(Geom_Line)))
{
gp_Pnt nsp, nep ;
GetEdgeStartEndPoint(edge,nsp,nep);
TColgp_Array1OfPnt Pnts1(1,2);
Pnts1(1) = nsp;
Pnts1(2) = nep;
GeomAPI_PointsToBSpline PTBS1(Pnts1);
BSplineCurve = PTBS1.Curve();
}
return BSplineCurve;
}
bool CSplitAllInsectionCurves::GetWireIDbyIntersectionPointID( int InsectionPoint1,int InsectionPoint2,int& wireId )
{
int iSectioniD = 0;
if(GetInsectionSectionInfoId(InsectionPoint1,InsectionPoint2,iSectioniD) && GetWireIDbyIntersectionInfoID(iSectioniD,wireId))
{
return true;
}
return false;
}
bool CSplitAllInsectionCurves::GetWireIDbyIntersectionInfoID( int InsectionSectionInfoid,int& wireId )
{
std::map<int,CInsectionSectionInfo>::iterator pfind = m_mapAllInsectionSectionInfo.find(InsectionSectionInfoid);
if(pfind != m_mapAllInsectionSectionInfo.end())
{
wireId = pfind->second.m_BelongWireID;
}
else
return false;
return true;
}
bool CSplitAllInsectionCurves::ModifyHalfEdgeUse( int ptid1,int ptid2 )
{
if(ptid1 > ptid2)
swap(ptid1,ptid2);
for (std::map<CHalfEdgeKey,int>::iterator pit = m_mapHalfEdgesUsed.begin();pit!=m_mapHalfEdgesUsed.end();++pit)
{
if(pit->first.m_iStartPointID == ptid1 && pit->first.m_iEndPointID == ptid2)
{
if(pit->second <=1)
{
pit->second = pit->second + 1;
}
return true;
//break;
}
}
return false;
}
int CSplitAllInsectionCurves::GetHalfEdgeUseStep( int ptid1,int ptid2 )
{
if(ptid1 > ptid2)
swap(ptid1,ptid2);
for (std::map<CHalfEdgeKey,int>::iterator pit = m_mapHalfEdgesUsed.begin();pit!=m_mapHalfEdgesUsed.end();++pit)
{
if(pit->first.m_iStartPointID == ptid1 && pit->first.m_iEndPointID == ptid2)
{
return pit->second;
//break;
}
}
return -1;
}
void CSplitAllInsectionCurves::AddHalfEdgeUse( const std::vector<int>& ids )
{
if(ids.size() >= 2)
{
for (int i=1;i<= ids.size();i++)
{
CHalfEdgeKey key;
if(i==ids.size())
{
key.m_iStartPointID = min(ids.back(),ids.front());
key.m_iEndPointID = max(ids.back(),ids.front());
}
else
{
key.m_iStartPointID = min(ids.at(i-1),ids.at(i));
key.m_iEndPointID = max(ids.at(i-1),ids.at(i));
}
if(-1 == GetHalfEdgeUseStep(key.m_iStartPointID,key.m_iEndPointID))
{
m_mapHalfEdgesUsed.insert(make_pair(key,0));
}
else
{
ModifyHalfEdgeUse(key.m_iStartPointID,key.m_iEndPointID);
}
}
}
}
Standard_Real CSplitAllInsectionCurves::GetEdgeLength(const TopoDS_Edge& aE )
{
GProp_GProps gsystem;
BRepGProp::LinearProperties(aE,gsystem);
return gsystem.Mass();
}
void CSplitAllInsectionCurves::GetClosedCurves( std::map<int,vector<Handle(Geom_BSplineCurve)>>& ClosedBSplineCurves )
{
ClosedBSplineCurves = m_mapClosedBSplineCurves;
}
bool CSplitAllInsectionCurves::IsPointOnWire( const TopoDS_Wire& wire,const gp_Pnt& pt1 )
{
TopExp_Explorer ex;
for(ex.Init(wire,TopAbs_EDGE);ex.More();ex.Next())
{
TopoDS_Edge aE = TopoDS::Edge(ex.Current());
if(aE.IsNull())
continue;
if(IsPointOnEdge(aE,pt1))
return true;
}
return false;
}
Handle(Geom_BSplineCurve) CSplitAllInsectionCurves::TrimWire2BSplineCurve( const TopoDS_Edge& basicWire,const gp_Pnt& pt1,const gp_Pnt& pt2 ,Standard_Real& dF,Standard_Real& dL)
{
Handle(Geom_BSplineCurve) BSplineCurve = NULL;
try
{
TopoDS_Edge newEdge;
double df__,dl__;
Handle(Geom_Curve) aCur = BRep_Tool::Curve(basicWire,df__,dl__);
aCur = new Geom_TrimmedCurve(aCur, df__, dl__);
aCur = GeomConvert::CurveToBSplineCurve(aCur);
//TopoDS_Edge e = BRepBuilderAPI_MakeEdge(aCur);
//BRepTools::Write(e, "C:\\edge.brep");
gp_Pnt p1,p2;
GetEdgeStartEndPoint(basicWire, p1,p2);
if(IsPointOnEdge(basicWire,pt1) && IsPointOnEdge(basicWire,pt2))
{
try
{
// GeomAPI_ProjectPointOnCurve Projector1 (pt1, aCur); //gp_Pnt Bpnt
// GeomAPI_ProjectPointOnCurve Projector2 (pt2, aCur); //gp_Pnt Bpnt
// dF = Projector1.LowerDistanceParameter();
// dL = Projector2.LowerDistanceParameter();
BaseAlgo algo;
dF = algo.ProjectPointOnCurvePara(basicWire, pt1);
dL = algo.ProjectPointOnCurvePara(basicWire, pt2);
}
catch(Standard_Failure)
{
dF = df__;
dL = dl__;
}
Handle(Geom_TrimmedCurve) myTrimmed = new Geom_TrimmedCurve(aCur, dF, dL);
BSplineCurve = GeomConvert::CurveToBSplineCurve(myTrimmed);
}
}
catch (Standard_ConstructionError e)
{
Standard_CString str = e.GetMessageString();
return 0;
}
return BSplineCurve;
}
Handle(Geom_BSplineCurve) CSplitAllInsectionCurves::TrimWire2BSplineCurve( const TopoDS_Edge& basicWire,const Standard_Real& dF,const Standard_Real& dL )
{
Standard_Real First,Last;
Handle(Geom_Curve) myCurve = BRep_Tool::Curve(basicWire, First, Last);
Handle(Geom_TrimmedCurve) myTrimmed = new Geom_TrimmedCurve(myCurve, dF, dL);
Handle(Geom_BSplineCurve) BSplineCurve = GeomConvert::CurveToBSplineCurve(myTrimmed);
return BSplineCurve;
}
Handle(Geom_BSplineCurve) CSplitAllInsectionCurves::MergeSubBSpline(const vector<int>& subarcids,int iWireid,Standard_Real& dF,Standard_Real& dL)
{
int iStartPointid = 0 ;
int iEndPointid = 0 ;
gp_Pnt gpStartPt ;
gp_Pnt gpEndPt ;
if(subarcids.size() >=2 )
{
set<int> pts;
vector<int> filterpts;
for (vector<int>::const_iterator pit = subarcids.begin();pit!=subarcids.end();++pit)
{
CInsectionSectionInfo info = m_mapAllInsectionSectionInfo[*pit];
iStartPointid = info.m_startInsection;
iEndPointid = info.m_endInsection;
pts.insert(iStartPointid);
pts.insert(iEndPointid);
}
for (set<int>::const_iterator pit = pts.begin();pit != pts.end();++pit)
{
filterpts.push_back(*pit);
}
SortByWire(iWireid,filterpts);
gpStartPt = m_mapAllInsectionPoints[filterpts.front()].m_PtCoor;
gpEndPt = m_mapAllInsectionPoints[filterpts.back()].m_PtCoor;
TopoDS_Edge wire = m_mapAllWires[iWireid];
return TrimWire2BSplineCurve(wire,gpStartPt,gpEndPt,dF,dL);
}
return NULL;
}
Handle(Geom_BSplineCurve) CSplitAllInsectionCurves::FindSrcBSpline(const vector<Handle(Geom_BSplineCurve)>& vctBSplineCurves,const vector<CResultData>& resultdatas,const vector<pair<int,int>>& wiresectids,int isectioninfoid,CResultData& data)
{
if(vctBSplineCurves.size() != wiresectids.size())
return NULL;
for (int i=0;i<wiresectids.size();i++)
{
if(wiresectids[i].first == isectioninfoid)
{
data = resultdatas.at(i);
return vctBSplineCurves[i];
}
}
return NULL;
}
void CSplitAllInsectionCurves::ClearMaxEdgeBoundingBox()
{
if(m_mapClosedZooms.empty())
return;
std::map<int,vector<int>>::reverse_iterator prit = m_mapClosedZooms.rbegin();
int ikey = prit->first;
vector<int>& lastclosed = prit->second;
prit++;
for (;prit!=m_mapClosedZooms.rend();++prit)
{
if(IsIncludeClosedZoom(lastclosed,prit->second))
{
m_mapClosedZooms.erase(ikey);
m_ClosedResults.erase(ikey);
m_mapClosedBSplineCurves.erase(ikey);
break;
}
}
}
bool CSplitAllInsectionCurves::GetPolygonBSplineSurfaceByMorethan4Sides( const vector<Handle(Geom_BSplineCurve)>& vctBSplineCurves,vector<Handle(Geom_BSplineCurve)>& newvctBSplineCurves )
{
int iSideSize = vctBSplineCurves.size();
if(iSideSize <= 4)
{
newvctBSplineCurves = vctBSplineCurves;
return true;
}
int iMaxlengthStartId = 0;
double dlength = 0.0;
double dMaxLenhth =0.0;
for (int i=0;i<iSideSize;i++)
{
dlength = 0.0;
const Handle(Geom_BSplineCurve)& c1_of= vctBSplineCurves.at(i>=iSideSize ? i-iSideSize:i);
const Handle(Geom_BSplineCurve)& c2_of = vctBSplineCurves.at((i+1)>=iSideSize ? (i+1)-iSideSize:i+1);
const Handle(Geom_BSplineCurve)& c3_of = vctBSplineCurves.at((i+2)>=iSideSize ? (i+2)-iSideSize:i+2);
dlength = GetEdgeLength(BRepBuilderAPI_MakeEdge(c1_of));
dlength += GetEdgeLength(BRepBuilderAPI_MakeEdge(c2_of));
dlength += GetEdgeLength(BRepBuilderAPI_MakeEdge(c3_of));
if(dlength > dMaxLenhth)
{
dMaxLenhth = dlength;
iMaxlengthStartId = i;
}
}
for (int i = iMaxlengthStartId; i<iMaxlengthStartId+3;i++)
{
const Handle(Geom_BSplineCurve)& c1_of= vctBSplineCurves.at(i>=iSideSize ? i-iSideSize:i);
gp_Pnt sp = c1_of->StartPoint();
gp_Pnt ep = c1_of->EndPoint();
newvctBSplineCurves.push_back(c1_of);
}
vector<gp_Pnt> avgPts;
// TColGeom_Array1OfBSplineCurve ArrayOfCurves(1,iSideSize-3);
// TColStd_Array1OfReal ArrayOfToler(1,iSideSize-3);
// Handle(TColGeom_HArray1OfBSplineCurve) ArrayOfConcatenated;
//
// for (int i=0;i<iSideSize-3;i++)
// {
// int newIndex = i + iMaxlengthStartId + 3;
// newIndex = (newIndex>=iSideSize) ? newIndex-iSideSize:newIndex;
// const Handle(Geom_BSplineCurve)& c1_of= vctBSplineCurves.at(newIndex);
// ArrayOfCurves.SetValue(i+1,c1_of);
// ArrayOfToler.SetValue(i+1,Precision::Confusion());
// }
for (int i=0;i<iSideSize-3;i++)
{
int newIndex = i + iMaxlengthStartId + 3;
newIndex = (newIndex>=iSideSize) ? newIndex-iSideSize:newIndex;
const Handle(Geom_BSplineCurve)& c1_of= vctBSplineCurves.at(newIndex);
gp_Pnt sp = c1_of->StartPoint();
gp_Pnt ep = c1_of->EndPoint();
double splinelength = GetEdgeLength(BRepBuilderAPI_MakeEdge(c1_of));
double dF,dL;
Handle(Geom_Curve) aCurbs = BRep_Tool::Curve(BRepBuilderAPI_MakeEdge(c1_of),dF,dL);
double dratio = (dL-dF)/100.0;
double dtotalratio = dF;
//if(i == 0) //modify srq 2012-4-13 注释掉 替换为以下内容
//{
// dtotalratio -= dratio;
//}
////------------modified by ZUOMIN
//while(dtotalratio < dL) //while(dtotalratio <= dL)
//{
// dtotalratio += dratio;
// avgPts.push_back(c1_of->Value(dtotalratio));
//}
gp_Pnt tempP;//modify srq 2012-4-13 替换上面注视内容
if(i == 0)
{
avgPts.push_back(c1_of->Value(dF));
}
while((dtotalratio -(dL-dratio))<10e-6)
{
dtotalratio += dratio;
tempP=c1_of->Value(dtotalratio);
if(abs(tempP.Distance(avgPts.at(avgPts.size()-1)))<10e-6)
{
continue;
}
else
{
avgPts.push_back(c1_of->Value(dtotalratio));
}
}
tempP=c1_of->Value(dL);
if(abs(tempP.Distance(avgPts.at(avgPts.size()-1)))<10e-6)
{
}
else
{
avgPts.push_back(c1_of->Value(dL));
}
}
//------------modified by ZUOMIN
//avgPts.pop_back();
if(avgPts.size() > 2)
{
Handle(TColgp_HArray1OfPnt) harray =
new TColgp_HArray1OfPnt (1,avgPts.size()); // sizing harray
for (int j=1;j<=avgPts.size();j++)
{
harray->SetValue(j,avgPts.at(j-1)) ;
}
GeomAPI_Interpolate anInterpolation(harray,Standard_False,Precision::Confusion());
anInterpolation.Perform();
Handle(Geom_BSplineCurve) SPL2;
if (anInterpolation.IsDone())
{
SPL2 = anInterpolation.Curve();
newvctBSplineCurves.push_back(SPL2);
}
}
return true;
}
void CSplitAllInsectionCurves::SortClosedSidesByClock(const vector<int>& slaveids, vector<Handle(Geom_BSplineCurve)>& newvctBSplineCurves ,vector<CResultData>& newvctResultDatas)
{
if(slaveids.empty())
return;
if(slaveids.size() != newvctBSplineCurves.size())
return;
if(newvctResultDatas.size() != newvctBSplineCurves.size())
return;
vector<int> allslaveids = slaveids;
allslaveids.push_back(slaveids.front());
int iIndex = 0 ;
for (vector<Handle(Geom_BSplineCurve)>::iterator pit = newvctBSplineCurves.begin();pit!=newvctBSplineCurves.end();++pit,iIndex++)
{
Handle(Geom_BSplineCurve)& curvely = *pit;
ShowBSplineStartEndPoint(curvely);
gp_Pnt startPt = curvely->StartPoint();
gp_Pnt endPt = curvely->EndPoint();
gp_Pnt kStartPt = m_mapAllInsectionPoints[allslaveids.at(iIndex)].m_PtCoor;
gp_Pnt kEndPt = m_mapAllInsectionPoints[allslaveids.at(iIndex+1)].m_PtCoor;
if(!startPt.IsEqual(kStartPt,Precision::Confusion()) || !endPt.IsEqual(kEndPt,Precision::Confusion()))
{
curvely->Reverse();
newvctResultDatas[iIndex].m_iFlag *= -1;
}
}
}
void CSplitAllInsectionCurves::ShowBSplineStartEndPoint(const Handle(Geom_BSplineCurve) BSplineCurve)
{
gp_Pnt ps = BSplineCurve->StartPoint();
gp_Pnt pe = BSplineCurve->EndPoint();
std::string strbe = "";
//strbe.Format(_T("\n(%0.5f,%0.5f,%0.5f),(%0.5f,%0.5f,%0.5f)"),ps.X(),ps.Y(),ps.Z(),pe.X(),pe.Y(),pe.Z());
std::ostringstream oss;
oss.precision(5); // 设置精度为 5 位小数
oss << std::fixed; // 使用固定小数位数输出
oss << "\n(" << ps.X() << "," << ps.Y() << "," << ps.Z() << "),(" << pe.X() << "," << pe.Y() << "," << pe.Z() << ")";
strbe = oss.str();
//OutputDebugString(strbe.c_str()); //注意字符编码
}
bool CSplitAllInsectionCurves::IsCloseBSplines( vector<Handle(Geom_BSplineCurve)>& vctBSplineCurves ,vector<CResultData>& newvctResultDatas)
{
vector<pair<gp_Pnt,gp_Pnt>> pairPoints;
if(vctBSplineCurves.size() < 2)
return false;
vector<bool> vctflags;
for(Handle(Geom_BSplineCurve) BSplineCurve : vctBSplineCurves)
{
gp_Pnt ps = BSplineCurve->StartPoint();
gp_Pnt pe = BSplineCurve->EndPoint();
pairPoints.push_back(make_pair(ps,pe));
vctflags.push_back(true);
}
//检查第一条边
if(!pairPoints.at(0).second.IsEqual(pairPoints.at(1).first,Precision::Confusion()))
{
gp_Pnt& ps = pairPoints.at(0).first;
gp_Pnt& pe = pairPoints.at(0).second;
swap(ps,pe);
vctflags[0] = false;
}
for (int i=1;i<pairPoints.size()-1;i++)
{
if(!pairPoints.at(i).second.IsEqual(pairPoints.at(i+1).first,Precision::Confusion()))
{
gp_Pnt& ps = pairPoints.at(i).first;
gp_Pnt& pe = pairPoints.at(i).second;
swap(ps,pe);
vctflags[i+1] = false;
}
}
for (int i=0;i<vctflags.size();i++)
{
if(!vctflags.at(i))
{
Handle(Geom_BSplineCurve)& aCurve = vctBSplineCurves.at(i);
aCurve->Reverse();
newvctResultDatas.at(i).m_iFlag *= -1;
ShowBSplineStartEndPoint(aCurve);
}
}
return true;
}
bool CSplitAllInsectionCurves::IsExsitNextEdge( const vector<pair<gp_Pnt,gp_Pnt>>& pairPoints,int iCurrentIndex )
{
// gp_Pnt endPt = pairPoints.at(iCurrentIndex).second;
// for (int i=0;i<pairPoints.size();i++)
// {
// if(i)
// }
return false;
}
std::map<int,bool> CSplitAllInsectionCurves::GetErrorClosedZoomID()
{
std::map<int,bool> maperrors;
for(std::map<int,bool>::iterator pit = m_mapSuccessGenFaces.begin();pit!=m_mapSuccessGenFaces.end();++pit)
{
if(!pit->second)
{
maperrors.insert(make_pair(pit->first,pit->second));
}
}
return maperrors;
}
std::vector<pair<pair<int,int>,int>> CSplitAllInsectionCurves::GetIntersectionTimeSearchs()
{
std::vector<pair<pair<int,int>,int>> values;
for(std::map<int,int>::iterator pit = m_mapIntersectinInfoTimeSearchs.begin();pit != m_mapIntersectinInfoTimeSearchs.end();++pit)
{
pair<int,int> ptids= make_pair(m_mapAllInsectionSectionInfo[pit->first].m_startInsection,m_mapAllInsectionSectionInfo[pit->first].m_endInsection);
values.push_back(make_pair(ptids,pit->second));
}
return values;
}
std::string CSplitAllInsectionCurves::GetWireName( int iID )
{
std::map<int,std::string>::iterator pit = m_mapWireID2Name.find(iID);
if(pit != m_mapWireID2Name.end())
return pit->second;
return "";
}
// /* start 5边改3边 yc 2013.07.11*/
TopoDS_Shape CSplitAllInsectionCurves::GetPolygonBSplineSurfaceByMorethan4Sides( vector<Handle(Geom_BSplineCurve)>& vctCurve )
{
vector<TopoDS_Face> vctTopoFace;
TopoDS_Shell shell;
BRep_Builder builder;
//// /*拆分*/
//PolygonSplit(vctCurve,vctTopoFace);
//builder.MakeShell(shell);
//for(vector<TopoDS_Face>::iterator iter = vctTopoFace.begin(); iter != vctTopoFace.end(); iter++)
//{
// builder.Add(shell,*iter);
//}
return shell;
}
void CSplitAllInsectionCurves::PolygonSplit( vector<Handle(Geom_BSplineCurve)>& vctCurve, vector<TopoDS_Face> &vctTopoFace )
{
vector<Handle(Geom_BSplineCurve)> vctCurve1;
vector<Handle(Geom_BSplineCurve)> vctCurve2;
//三角形则生成面
if(vctCurve.size() == 3)
{
TriangleEdge(vctCurve);
GeomFill_BSplineCurves fill;
fill=GeomFill_BSplineCurves(vctCurve.at(0),vctCurve.at(1),vctCurve.at(2),GeomFill_StretchStyle);
Handle(Geom_BSplineSurface) BSS = fill.Surface();
//TopoDS_Face S = BRepBuilderAPI_MakeFace(BSS).Face();// XUEFENG DELETE 202101
TopoDS_Face S = BRepBuilderAPI_MakeFace(BSS, Precision::Confusion()).Face(); // XUEFENG ADDED 202101
vctTopoFace.push_back(S);
return;
}
if(vctCurve.size() == 4)
{
GeomFill_BSplineCurves fill;
fill=GeomFill_BSplineCurves(vctCurve.at(0),vctCurve.at(1),vctCurve.at(2),vctCurve.at(3),GeomFill_StretchStyle);
Handle(Geom_BSplineSurface) BSS = fill.Surface();
//TopoDS_Face S = BRepBuilderAPI_MakeFace(BSS).Face(); // XUEFENG DELETE 202101
TopoDS_Face S = BRepBuilderAPI_MakeFace(BSS, Precision::Confusion()).Face(); // XUEFENG ADDED 202101
vctTopoFace.push_back(S);
return;
}
//// ////////拆分 策略是对半分
//gp_Pnt sp,ep;
//sp = GetConnectionPoint(vctCurve.at(0),vctCurve.at(vctCurve.size() - 1));
//int index = (vctCurve.size()-1) / 2;
//ep = GetConnectionPoint(vctCurve.at(index),vctCurve.at(index + 1));
//TopoDS_Edge newEdge = BRepBuilderAPI_MakeEdge(sp,ep);
////新边
//double df,dl;
//BRep_Tool::Curve(newEdge,df,dl);
//Handle(Geom_BSplineCurve) newCurve = TrimWire2BSplineCurve(newEdge,df,dl);
//for(int i = 0; i < index + 1; i++)
//{
// vctCurve1.push_back(vctCurve.at(i));
//}
//vctCurve1.push_back(newCurve);
//PolygonSplit(vctCurve1,vctTopoFace);
//for(int i = index + 1; i < vctCurve.size(); i++)
//{
// vctCurve2.push_back(vctCurve.at(i));
//}
//vctCurve2.push_back(newCurve);
//PolygonSplit(vctCurve2,vctTopoFace);
//// ////////拆分 策略是连接最近的点
map<int, gp_Pnt> mapPoint;
map<int, vector<int>> mapPointEdge;
for(int i = 0; i < vctCurve.size(); i++)
{
int start = i;
int end = (i+1)%vctCurve.size();
vector<int> edgeSet;
edgeSet.push_back(start);
edgeSet.push_back(end);
mapPointEdge.insert(make_pair(i,edgeSet));
mapPoint.insert(make_pair(i,GetConnectionPoint(vctCurve.at(start),vctCurve.at(end))));
}
int spID, epID;
double dis = 1e7;
for(int i = 0; i < vctCurve.size() ; i++)
{
gp_Pnt p1 = mapPoint[i];
for(int j = i + 2; j < vctCurve.size() ; j++)
{
if(i == 0 && j == vctCurve.size() - 1)
{
continue;
}
gp_Pnt p2 = mapPoint[j];
double d = p1.Distance(p2);
if(dis > d)
{
dis = d;
spID = i;
epID = j;
}
}
}
//新边
gp_Pnt sp,ep;
sp = mapPoint[spID];
ep = mapPoint[epID];
TopoDS_Edge newEdge = BRepBuilderAPI_MakeEdge(sp,ep);
double df,dl;
BRep_Tool::Curve(newEdge,df,dl);
Handle(Geom_BSplineCurve) newCurve = TrimWire2BSplineCurve(newEdge,df,dl);
int index;
for(int i =spID; i < epID; i++)
{
index = mapPointEdge[i][1];
vctCurve1.push_back(vctCurve.at(index));
}
vctCurve1.push_back(newCurve);
PolygonSplit(vctCurve1,vctTopoFace);
for(int i = epID; i < spID + vctCurve.size(); i++)
{
index = mapPointEdge[i%vctCurve.size()][1];
vctCurve2.push_back(vctCurve.at(index));
}
vctCurve2.push_back(newCurve);
PolygonSplit(vctCurve2,vctTopoFace);
}
gp_Pnt CSplitAllInsectionCurves::GetConnectionPoint( Handle(Geom_BSplineCurve)& curve1, Handle(Geom_BSplineCurve)& curve2 )
{
return GetConnectionPoint( BRepBuilderAPI_MakeEdge(curve1).Edge(), BRepBuilderAPI_MakeEdge(curve2).Edge());
}
gp_Pnt CSplitAllInsectionCurves::GetConnectionPoint( TopoDS_Edge edge1, TopoDS_Edge edge2 )
{
gp_Pnt pnt;
double df,dl;
double tol = 1e-4;
Handle(Geom_Curve) aCur = BRep_Tool::Curve(edge1,df,dl);
gp_Pnt p1 = aCur->Value(df);
gp_Pnt p2 = aCur->Value(dl);
aCur = BRep_Tool::Curve(edge2,df,dl);
gp_Pnt p3 = aCur->Value(df);
gp_Pnt p4 = aCur->Value(dl);
if(p1.Distance(p3) < tol)
{
return p1;
}
if(p1.Distance(p4) < tol)
{
return p1;
}
if(p2.Distance(p3) < tol)
{
return p2;
}
if(p2.Distance(p4) < tol)
{
return p2;
}
return pnt;
}
// /* end 5边改3边 yc 2013.07.11*/
// /* start 多边形拟合 yc 20130730*/
void CSplitAllInsectionCurves::CheckPolygonBSpline(const vector<Handle(Geom_BSplineCurve)>& vctBSplineCurves,vector<Handle(Geom_BSplineCurve)>& newvctBSplineCurves)
{
//两边 直接返回
if(vctBSplineCurves.size() == 2)
{
newvctBSplineCurves = vctBSplineCurves;
return;
}
map<int,vector<int>> newEdge;
map<int, vector<gp_Pnt>> newEdgePoint;
map<int, double> newEdgeAngle;
map<int, int> newNextEdge;
map<int, gp_Dir> newEdgeDir;
for(int i = 0; i < vctBSplineCurves.size(); i++)
{
gp_Pnt p1 = vctBSplineCurves[i]->StartPoint();
gp_Pnt p2 = vctBSplineCurves[i]->EndPoint();
vector<gp_Pnt> pSet;
vector<int> eSet;
eSet.push_back(i);
if(i > 0)
{
gp_Pnt ep = newEdgePoint[i - 1][1];
if(ep.Distance(p1) < Precision::Confusion() * 10)
{
pSet.push_back(p1);
pSet.push_back(p2);
}
else
{
pSet.push_back(p2);
pSet.push_back(p1);
}
}
else
{
pSet.push_back(p1);
pSet.push_back(p2);
}
gp_Dir dir(pSet[0].X() - pSet[1].X(), pSet[0].Y() - pSet[1].Y(), pSet[0].Z() - pSet[1].Z());
newEdge.insert(make_pair(i,eSet));
newEdgePoint.insert(make_pair(i,pSet));
newNextEdge.insert(make_pair(i,(i+1)%vctBSplineCurves.size()));
newEdgeDir.insert(make_pair(i, dir));
}
// 计算夹角
for(map<int, vector<int>>::iterator iter = newEdge.begin(); iter != newEdge.end(); iter++)
{
int id = iter->first;
int nextId = newNextEdge[id];
gp_Dir d1 = newEdgeDir[id];
gp_Dir d2 = newEdgeDir[nextId];
newEdgeAngle.insert(make_pair(id, PI - d1.Angle(d2)));
}
MergeEdge(newEdge,newEdgePoint,newNextEdge,newEdgeAngle,newEdgeDir);
// 合并
for(map<int, vector<int>>::iterator iter = newEdge.begin(); iter != newEdge.end(); iter++)
{
vector<int> edges = iter->second;
if(edges.size() == 1)
{
newvctBSplineCurves.push_back(vctBSplineCurves.at(edges[0]));
continue;
}
vector<gp_Pnt> avgPts;
vector<int> index;//连接点位置
for (int i=0;i<edges.size();i++)
{
int newIndex = edges[i];
const Handle(Geom_BSplineCurve)& c1_of= vctBSplineCurves.at(newIndex);
gp_Pnt sp = c1_of->StartPoint();
gp_Pnt ep = c1_of->EndPoint();
double splinelength = GetEdgeLength(BRepBuilderAPI_MakeEdge(c1_of));
double dF,dL;
Handle(Geom_Curve) aCurbs = BRep_Tool::Curve(BRepBuilderAPI_MakeEdge(c1_of),dF,dL);
double dratio = (dL-dF)/100.0;
double dtotalratio = dF;
gp_Pnt tempP;
if(i == 0)
{
avgPts.push_back(c1_of->Value(dF));
index.push_back(avgPts.size() - 1);
}
while((dtotalratio -(dL-dratio))<10e-6)
{
dtotalratio += dratio;
tempP=c1_of->Value(dtotalratio);
if(abs(tempP.Distance(avgPts.at(avgPts.size()-1)))<10e-6)
{
continue;
}
else
{
avgPts.push_back(c1_of->Value(dtotalratio));
}
}
tempP=c1_of->Value(dL);
if(abs(tempP.Distance(avgPts.at(avgPts.size()-1)))<10e-6)
{
avgPts[avgPts.size()-1] = tempP;
}
else
{
avgPts.push_back(c1_of->Value(dL));
}
index.push_back(avgPts.size() - 1);
}
//yc 20140723 删除多余点
ClearPoints(avgPts,index);
if(avgPts.size() > 2)
{
Handle(TColgp_HArray1OfPnt) harray =
new TColgp_HArray1OfPnt (1,avgPts.size()); // sizing harray
for (int j=1;j<=avgPts.size();j++)
{
harray->SetValue(j,avgPts.at(j-1)) ;
}
GeomAPI_Interpolate anInterpolation(harray,Standard_False,Precision::Confusion());
anInterpolation.Perform();
Handle(Geom_BSplineCurve) SPL2;
if (anInterpolation.IsDone())
{
SPL2 = anInterpolation.Curve();
newvctBSplineCurves.push_back(SPL2);
}
}
}
//
// 20170601 by czb大于4条边
if(newvctBSplineCurves.size() > 4)
{
vector<Handle(Geom_BSplineCurve)> tempvctBSplineCurves;
for(int i = 0; i < newvctBSplineCurves.size(); i++)
{
tempvctBSplineCurves.push_back(newvctBSplineCurves[i]);
}
newvctBSplineCurves.clear();
GetPolygonBSplineSurfaceByMorethan4Sides(tempvctBSplineCurves,newvctBSplineCurves);
}
}
void CSplitAllInsectionCurves:: MergeEdge(map<int, vector<int>>& edgeSet, map<int, vector<gp_Pnt>>& edgePoint, map<int, int>& nextEdge, map<int, double>& nextEdgeAngle, map<int, gp_Dir>& edgeDir)
{
if(edgeSet.size() < 3)
{
return;
}
//if(edgeSet.size() == 3)
//{
// double len1= 0, len2 = 0, len0 = 0;
// int index1,index2, index0;
// map<int, vector<gp_Pnt>>::iterator iter = edgePoint.begin();
// vector<gp_Pnt> ps0 = iter->second;
// index0 = iter->first;
// iter++;
// vector<gp_Pnt> ps1 = iter->second;
// index1 = iter->first;
// iter++;
// vector<gp_Pnt> ps2 = iter->second;
// index2 = iter->first;
// for(int i= 0; i < ps0.size() -1; i++)
// {
// gp_Pnt p1 = ps0[i];
// gp_Pnt p2 = ps0[i+1];
// len0 += p1.Distance(p2);
// }
// for(int i= 0; i < ps1.size() -1; i++)
// {
// gp_Pnt p1 = ps1[i];
// gp_Pnt p2 = ps1[i+1];
// len1 += p1.Distance(p2);
// }
// for(int i= 0; i < ps2.size() -1; i++)
// {
// gp_Pnt p1 = ps2[i];
// gp_Pnt p2 = ps2[i+1];
// len2 += p1.Distance(p2);
// }
// int index = 0;
// double min = 10000;
// if(abs(len0 + len1 - len2) < min)
// {
// min = abs(len0 + len1 - len2);
// index = index1;
// }
// if(abs(len0 - len1 + len2) < min)
// {
// min = abs(len0 - len1 + len2);
// index = index0;
// }
// if(abs(len2 + len1 - len0) < min)
// {
// min = abs(len2 + len1 - len0);
// index = index2;
// }
// Merge(index, edgeSet, edgePoint, nextEdge, nextEdgeAngle, edgeDir);
//}
//else
//{
// int index = MaxAngleIndex(nextEdgeAngle);
// double angle;
// if(edgeSet.find(index) != edgeSet.end())
// {
// angle = nextEdgeAngle[index];
// }
// Merge(index, edgeSet, edgePoint, nextEdge, nextEdgeAngle, edgeDir);
//}
//MergeEdge(edgeSet, edgePoint, nextEdge, nextEdgeAngle, edgeDir);
int index = MaxAngleIndex(nextEdgeAngle);
double angle;
if(edgeSet.find(index) != edgeSet.end())
{
angle = nextEdgeAngle[index];
}
bool isMerg = false;
switch (edgeSet.size())
{
////三边 如果存在角度大于150 合并成两边
case 3:
//if(angle > PI * 5 / 6)
//{
// Merge(index, edgeSet, edgePoint, nextEdge, nextEdgeAngle, edgeDir);
// isMerg = true;
//}
break;
//四边 如果存在角度大于135 合并成三边
case 4:
//if(angle > PI * 3 / 4)
//{
// Merge(index, edgeSet, edgePoint, nextEdge, nextEdgeAngle, edgeDir);
// isMerg = true;
//}
break;
////大于四边 合并大于108的角
default:
if(angle > PI * 2/ 3)
{
Merge(index, edgeSet, edgePoint, nextEdge, nextEdgeAngle, edgeDir);
isMerg = true;
}
break;
}
if(isMerg)
{
MergeEdge(edgeSet, edgePoint, nextEdge, nextEdgeAngle, edgeDir);
}
return;
}
void CSplitAllInsectionCurves::Merge(int index, map<int, vector<int>>& edgeSet, map<int, vector<gp_Pnt>>& edgePoint, map<int, int>& nextEdge, map<int, double>& nextEdgeAngle, map<int, gp_Dir>& edgeDir)
{
int nextID = nextEdge[index];
//更新端点edgePoint
edgePoint[index].pop_back();
edgePoint[index].push_back(edgePoint[nextID][1]);
//更新边方向edgeDir
gp_Pnt p0 = edgePoint[index][0];
gp_Pnt p1 = edgePoint[index][1];
gp_Dir newDir(p0.X() - p1.X(), p0.Y() - p1.Y(), p0.Z() - p1.Z());
edgeDir[index] = newDir;
//更新nextEdge
nextEdge[index] = nextEdge[nextID];
//更新夹角 nextEdgeAngle
nextEdgeAngle[index] = PI - edgeDir[index].Angle(edgeDir[nextEdge[index]]);
//更新edgeSet
vector<int> edges = edgeSet[nextID];
for(vector<int>::iterator iter = edges.begin(); iter != edges.end(); iter++)
{
edgeSet[index].push_back(*iter);
}
edgePoint.erase(edgePoint.find(nextID));
edgeDir.erase(edgeDir.find(nextID));
nextEdge.erase(nextEdge.find(nextID));
nextEdgeAngle.erase(nextEdgeAngle.find(nextID));
edgeSet.erase(edgeSet.find(nextID));
return;
}
int CSplitAllInsectionCurves::MaxAngleIndex(map<int, double>& edgeAngle)
{
double maxAngle = -1;
int index = -1;
for(map<int, double>::iterator iter = edgeAngle.begin(); iter != edgeAngle.end(); iter++)
{
if(maxAngle > iter->second)
{
continue;
}
maxAngle = iter->second;
index = iter->first;
}
return index;
}
void CSplitAllInsectionCurves::CheckPolygonBSpline1(const vector<Handle(Geom_BSplineCurve)>& vctBSplineCurves,vector<Handle(Geom_BSplineCurve)>& newvctBSplineCurves)
{
//20170601 by czb大于4条边不自动拟合插入新的曲线
newvctBSplineCurves.clear();
for(int i = 0; i < vctBSplineCurves.size(); i++)
{
newvctBSplineCurves.push_back(vctBSplineCurves[i]);
}
return;
vector<TopoDS_Edge> edgeSet;
for(int i = 0; i < vctBSplineCurves.size(); i++)
{
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(vctBSplineCurves.at(i));
edgeSet.push_back(edge);
}
double val1 = PI, val2 = 0;
switch (edgeSet.size())
{
case 2:
val1 = PI;
val2 = 0;
break;
case 3://三边 如果存在角度大于150 合并成两边
val1 = PI;
val2 = 0;
break;
case 4://四边 如果存在角度大于135 合并成三边
val1 = PI * 5 / 6;
val2 = PI / 6;
break;
default:// 大于四边 合并大于108的角
val1 = PI * 2 / 3;
val2 = PI / 6;
break;
}
while(true)
{
bool isFind = false;
vector<TopoDS_Edge> edgeSetTmp;
if(edgeSet.size() == 2)
{
break;
}
switch (edgeSet.size())
{
case 2:
val1 = PI;
val2 = 0;
break;
case 3://三边 如果存在角度大于150 合并成两边
val1 = PI;
val2 = 0;
break;
case 4://四边 如果存在角度大于135 合并成三边
val1 = PI * 5 / 6;
val2 = PI / 6;
break;
default:// 大于四边 合并大于108的角
val1 = PI * 2 / 3;
val2 = PI / 6;
break;
}
for(int i = 0; i < edgeSet.size(); i++)
{
if(isFind)
{
edgeSetTmp.push_back(edgeSet[i]);
continue;
}
TopoDS_Edge edge1 = edgeSet[i];
TopoDS_Edge edge2 = edgeSet[(i+1) % edgeSet.size()];
double angle1 = ComputeAngle(edge1, edge2);
double angle2 = ComputeAngle3(edge1, edge2);
if(val1 < angle1 && val2 > angle2)
{
vector<gp_Pnt> avgPts;
vector<int> index;//连接点位置
vector<TopoDS_Edge> edges;
edges.push_back(edge1);
edges.push_back(edge2);
for (int j=0;j<edges.size();j++)
{
Handle(Geom_BSplineCurve) bc = this->GetBSplineCurve(edges[j]);
gp_Pnt sp = bc->StartPoint();
gp_Pnt ep = bc->EndPoint();
double splinelength = GetEdgeLength(edges[j]);
double dF,dL;
Handle(Geom_Curve) aCurbs = BRep_Tool::Curve(edges[j],dF,dL);
//逆序
if(avgPts.size() > 0)
{
if(sp.Distance(avgPts[0]) < Precision::Confusion() || ep.Distance(avgPts[0]) < Precision::Confusion())
{
vector<gp_Pnt> tmp;
for(int k = 0; k < avgPts.size(); k++)
{
tmp.push_back(avgPts[k]);
}
avgPts.clear();
for(int k = tmp.size() - 1; k > -1; k--)
{
avgPts.push_back(tmp[k]);
}
}
if (ep.Distance(avgPts[avgPts.size() - 1]) < Precision::Confusion())
{
double tmp = dF;
dF = dL;
dL = tmp;
}
}
double dratio = (dL-dF)/100.0;
double dtotalratio = dF;
gp_Pnt tempP;
if(j == 0)
{
avgPts.push_back(aCurbs->Value(dF));
index.push_back(avgPts.size() - 1);
}
while((dtotalratio -(dL-dratio))<10e-6)
{
dtotalratio += dratio;
tempP=aCurbs->Value(dtotalratio);
if(abs(tempP.Distance(avgPts.at(avgPts.size()-1)))<10e-6)
{
continue;
}
else
{
avgPts.push_back(aCurbs->Value(dtotalratio));
}
}
tempP=aCurbs->Value(dL);
if(abs(tempP.Distance(avgPts.at(avgPts.size()-1)))<10e-6)
{
avgPts[avgPts.size()-1] = tempP;
}
else
{
avgPts.push_back(aCurbs->Value(dL));
}
index.push_back(avgPts.size() - 1);
}
//yc 20140723 删除多余点
ClearPoints(avgPts,index);
if(avgPts.size() > 2)
{
Handle(TColgp_HArray1OfPnt) harray =
new TColgp_HArray1OfPnt (1,avgPts.size()); // sizing harray
for (int j=1;j<=avgPts.size();j++)
{
harray->SetValue(j,avgPts.at(j-1)) ;
}
GeomAPI_Interpolate anInterpolation(harray,Standard_False,Precision::Confusion());
anInterpolation.Perform();
Handle(Geom_BSplineCurve) SPL2;
if (anInterpolation.IsDone())
{
SPL2 = anInterpolation.Curve();
edgeSetTmp.push_back(BRepBuilderAPI_MakeEdge(SPL2));
}
}
isFind = true;
i++;
if(i == edgeSet.size())
{
for(int j = 0; j < edgeSetTmp.size() - 1; j++)
{
edgeSetTmp[j] = edgeSetTmp[j + 1];
}
edgeSetTmp.pop_back();
}
}
else
{
edgeSetTmp.push_back(edge1);
}
}
if(!isFind)
{
break;
}
edgeSet.clear();
for(int i = 0; i < edgeSetTmp.size(); i++)
{
edgeSet.push_back(edgeSetTmp[i]);
}
}
if(edgeSet.size() > 4)
{
CheckPolygonBSpline(vctBSplineCurves, newvctBSplineCurves);
return ;
}
else
{
for(int i = 0; i < edgeSet.size(); i++)
{
newvctBSplineCurves.push_back(GetBSplineCurve(edgeSet[i]));
}
}
}
void CSplitAllInsectionCurves::CheckPolygonBSpline2(const vector<Handle(Geom_BSplineCurve)>& vctBSplineCurves,vector<Handle(Geom_BSplineCurve)>& newvctBSplineCurves)
{
//两边 直接返回
if(vctBSplineCurves.size() < 5)
{
newvctBSplineCurves = vctBSplineCurves;
return;
}
//if(vctBSplineCurves.size() == 2)
//{
// newvctBSplineCurves = vctBSplineCurves;
// return;
//}
map<int,vector<int>> newEdge;
map<int, vector<gp_Pnt>> newEdgePoint;
map<int, double> newEdgeAngle;
map<int, int> newNextEdge;
map<int, gp_Dir> newEdgeDir;
for(int i = 0; i < vctBSplineCurves.size(); i++)
{
gp_Pnt p1 = vctBSplineCurves[i]->StartPoint();
gp_Pnt p2 = vctBSplineCurves[i]->EndPoint();
vector<gp_Pnt> pSet;
vector<int> eSet;
eSet.push_back(i);
if(i > 0)
{
gp_Pnt ep = newEdgePoint[i - 1][1];
if(ep.Distance(p1) < Precision::Confusion() * 10)
{
pSet.push_back(p1);
pSet.push_back(p2);
}
else
{
pSet.push_back(p2);
pSet.push_back(p1);
}
}
else
{
pSet.push_back(p1);
pSet.push_back(p2);
}
gp_Dir dir(pSet[0].X() - pSet[1].X(), pSet[0].Y() - pSet[1].Y(), pSet[0].Z() - pSet[1].Z());
newEdge.insert(make_pair(i,eSet));
newEdgePoint.insert(make_pair(i,pSet));
newNextEdge.insert(make_pair(i,(i+1)%vctBSplineCurves.size()));
newEdgeDir.insert(make_pair(i, dir));
}
// 计算夹角
for(map<int, vector<int>>::iterator iter = newEdge.begin(); iter != newEdge.end(); iter++)
{
int id = iter->first;
int nextId = newNextEdge[id];
gp_Dir d1 = newEdgeDir[id];
gp_Dir d2 = newEdgeDir[nextId];
newEdgeAngle.insert(make_pair(id, PI - d1.Angle(d2)));
}
MergeEdge(newEdge,newEdgePoint,newNextEdge,newEdgeAngle,newEdgeDir);
// 合并
for(map<int, vector<int>>::iterator iter = newEdge.begin(); iter != newEdge.end(); iter++)
{
vector<int> edges = iter->second;
if(edges.size() == 1)
{
newvctBSplineCurves.push_back(vctBSplineCurves.at(edges[0]));
continue;
}
vector<gp_Pnt> avgPts;
vector<int> index;//连接点位置
for (int i=0;i<edges.size();i++)
{
int newIndex = edges[i];
const Handle(Geom_BSplineCurve)& c1_of= vctBSplineCurves.at(newIndex);
gp_Pnt sp = c1_of->StartPoint();
gp_Pnt ep = c1_of->EndPoint();
double splinelength = GetEdgeLength(BRepBuilderAPI_MakeEdge(c1_of));
double dF,dL;
Handle(Geom_Curve) aCurbs = BRep_Tool::Curve(BRepBuilderAPI_MakeEdge(c1_of),dF,dL);
double dratio = (dL-dF)/100.0;
double dtotalratio = dF;
gp_Pnt tempP;
if(i == 0)
{
avgPts.push_back(c1_of->Value(dF));
index.push_back(avgPts.size() - 1);
}
while((dtotalratio -(dL-dratio))<10e-6)
{
dtotalratio += dratio;
tempP=c1_of->Value(dtotalratio);
if(abs(tempP.Distance(avgPts.at(avgPts.size()-1)))<10e-6)
{
continue;
}
else
{
avgPts.push_back(c1_of->Value(dtotalratio));
}
}
tempP=c1_of->Value(dL);
if(abs(tempP.Distance(avgPts.at(avgPts.size()-1)))<10e-6)
{
avgPts[avgPts.size()-1] = tempP;
}
else
{
avgPts.push_back(c1_of->Value(dL));
}
index.push_back(avgPts.size() - 1);
}
//yc 20140723 删除多余点
ClearPoints(avgPts,index);
if(avgPts.size() > 2)
{
Handle(TColgp_HArray1OfPnt) harray =
new TColgp_HArray1OfPnt (1,avgPts.size()); // sizing harray
for (int j=1;j<=avgPts.size();j++)
{
harray->SetValue(j,avgPts.at(j-1)) ;
}
GeomAPI_Interpolate anInterpolation(harray,Standard_False,Precision::Confusion());
anInterpolation.Perform();
Handle(Geom_BSplineCurve) SPL2;
if (anInterpolation.IsDone())
{
SPL2 = anInterpolation.Curve();
newvctBSplineCurves.push_back(SPL2);
}
}
}
//
// 20170601 by czb大于4条边
if(newvctBSplineCurves.size() > 4)
{
vector<Handle(Geom_BSplineCurve)> tempvctBSplineCurves;
for(int i = 0; i < newvctBSplineCurves.size(); i++)
{
tempvctBSplineCurves.push_back(newvctBSplineCurves[i]);
}
newvctBSplineCurves.clear();
GetPolygonBSplineSurfaceByMorethan4Sides(tempvctBSplineCurves,newvctBSplineCurves);
}
}
// /*end 多边形拟合 yc 20130730*/
void CSplitAllInsectionCurves::TriangleEdge(vector<Handle(Geom_BSplineCurve)>& edgeSet)
{
Standard_Real L1,L2,L3;
GeomAdaptor_Curve GAC;
Handle(Geom_Curve) myCurve1 = edgeSet.at(0);
Handle(Geom_BSplineCurve) mmyCurve1 = edgeSet.at(0);
GAC.Load(myCurve1);
L1 = GCPnts_AbscissaPoint::Length(GAC);
Handle(Geom_Curve) myCurve2 = edgeSet.at(1);
Handle(Geom_BSplineCurve) mmyCurve2 = edgeSet.at(1);
GAC.Load(myCurve2);
L2 = GCPnts_AbscissaPoint::Length(GAC);
Handle(Geom_Curve) myCurve3 = edgeSet.at(2);
Handle(Geom_BSplineCurve) mmyCurve3 = edgeSet.at(2);
GAC.Load(myCurve3);
L3 = GCPnts_AbscissaPoint::Length(GAC);
edgeSet.clear();
if ((L1 > L2) && (L1 > L3))
{
//tempBSplineCurves.push_back(mmyCurve1);
if (L2> L3)
{
mmyCurve1->Reverse();
mmyCurve3->Reverse();
mmyCurve2->Reverse();
edgeSet.push_back(mmyCurve1);
edgeSet.push_back(mmyCurve3);
edgeSet.push_back(mmyCurve2);
}
else
{
edgeSet.push_back(mmyCurve1);
edgeSet.push_back(mmyCurve2);
edgeSet.push_back(mmyCurve3);
}
}
else
{
if ((L2> L1) && (L2>L3))
{
if (L1 < L3)
{
mmyCurve1->Reverse();
mmyCurve3->Reverse();
mmyCurve2->Reverse();
edgeSet.push_back(mmyCurve2);
edgeSet.push_back(mmyCurve1);
edgeSet.push_back(mmyCurve3);
}
else
{
edgeSet.push_back(mmyCurve2);
edgeSet.push_back(mmyCurve3);
edgeSet.push_back(mmyCurve1);
}
}
else
{
if (L1 > L2)
{
mmyCurve1->Reverse();
mmyCurve3->Reverse();
mmyCurve2->Reverse();
edgeSet.push_back(mmyCurve3);
edgeSet.push_back(mmyCurve2);
edgeSet.push_back(mmyCurve1);
}else{
edgeSet.push_back(mmyCurve3);
edgeSet.push_back(mmyCurve1);
edgeSet.push_back(mmyCurve2);
}
}
}
}
bool CSplitAllInsectionCurves::IsParallel(const TopoDS_Edge& e1, const 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);
Bnd_Box box1,box2;
BRepBndLib::Add(e1,box1);
BRepBndLib::Add(e2,box2);
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;
}
void CSplitAllInsectionCurves::CreateWireBox()
{
m_mapWireBox.clear();
for(map<int, TopoDS_Edge>:: iterator iter = m_mapAllWires.begin(); iter != m_mapAllWires.end(); iter++)
{
int id = iter->first;
TopoDS_Edge edge = iter->second;
Bnd_Box box;
BRepBndLib::Add(edge, box);
box.SetGap(m_precision);
m_mapWireBox.insert(make_pair(id, box));
}
}
double CSplitAllInsectionCurves::DistanceEE( TopoDS_Edge& e1, TopoDS_Edge& e2, gp_Pnt& p )
{
double disV = 1e10;
gp_Pnt p1, p2;
map<int, TopoDS_Edge> edgeSet1;
map<int, TopoDS_Edge> edgeSet2;
map<int, Bnd_Box> boxSet1;
map<int, Bnd_Box> boxSet2;
double df1,dl1,df2,dl2;
Handle(Geom_Curve) cv1 = BRep_Tool::Curve(e1, df1,dl1);
double step1 = (dl1- df1)/100;
double start1 = df1, end1 = df1+step1;
while(abs(end1 - dl1 - step1) > Precision::PConfusion())
{
Handle(Geom_TrimmedCurve) myTrimmed1 = new Geom_TrimmedCurve(cv1, start1, end1);
TopoDS_Edge newEdge1 = BRepBuilderAPI_MakeEdge(myTrimmed1);
start1 = end1;
end1 += step1;
if(abs(end1 - dl1) < Precision::PConfusion())
{
end1 = dl1;
}
Bnd_Box box1;
BRepBndLib::Add(newEdge1, box1);
box1.SetGap(Precision::Confusion());
int count = edgeSet1.size() + 1;
edgeSet1.insert(make_pair(count, newEdge1));
boxSet1.insert(make_pair(count, box1));
}
Handle(Geom_Curve) cv2 = BRep_Tool::Curve(e2, df2,dl2);
double step2 = (dl2- df2)/100;
double start2 = df2, end2 = df2+step2;
while(abs(end2 - dl2 - step2) > Precision::PConfusion())
{
Handle(Geom_TrimmedCurve) myTrimmed2 = new Geom_TrimmedCurve(cv2, start2, end2);
TopoDS_Edge newEdge2 = BRepBuilderAPI_MakeEdge(myTrimmed2);
start2 = end2;
end2 += step2;
if(abs(end2 - dl2) < Precision::PConfusion())
{
end2 = dl2;
}
Bnd_Box box2;
BRepBndLib::Add(newEdge2, box2);
box2.SetGap(Precision::Confusion());
int count = edgeSet2.size() + 1;
edgeSet2.insert(make_pair(count, newEdge2));
boxSet2.insert(make_pair(count, box2));
}
for(map<int, TopoDS_Edge>::iterator iter1 = edgeSet1.begin(); iter1 != edgeSet1.end(); iter1++)
{
int edgeId1 = iter1->first;
TopoDS_Edge edge1 = iter1->second;
Bnd_Box box1 = boxSet1[edgeId1];
for(map<int, TopoDS_Edge>::iterator iter2 = edgeSet2.begin(); iter2 != edgeSet2.end(); iter2++)
{
int edgeId2 = iter2->first;
TopoDS_Edge edge2 = iter2->second;
Bnd_Box box2 = boxSet2[edgeId2];
if(box1.IsOut(box2))
{
continue;
}
if(IsParallel(edge2, edge2))
{
continue;
}
BRepExtrema_DistShapeShape dst(edge1 ,edge2 );
if(dst.NbSolution() > 0)
{
if(disV > dst.Value())
{
disV = dst.Value();
p1 = dst.PointOnShape1(1);
p2 = dst.PointOnShape2(1);
}
}
}
}
p = p1;
return disV;
}
double CSplitAllInsectionCurves::SectionPoints( std::map<int,TopoDS_Edge>::const_iterator& e1It, std::map<int,TopoDS_Edge>::const_iterator& e2It, double tol, vector<gp_Pnt>& pSet ) //20180101 added by czb错误时输出边的序号
{
const TopoDS_Edge& e1 = e1It->second;
const TopoDS_Edge& e2 = e2It->second;
double disV = 1e10;
gp_Pnt p1, p2, p3,p4;
BaseAlgo algo;
map<int, TopoDS_Edge> edgeSet1;
map<int, TopoDS_Edge> edgeSet2;
map<int, Bnd_Box> boxSet1;
map<int, Bnd_Box> boxSet2;
GetEdgeStartEndPoint(e1,p1,p2);
GetEdgeStartEndPoint(e2,p3,p4);
double df1,dl1,df2,dl2;
Handle(Geom_Curve) cv1 = BRep_Tool::Curve(e1, df1,dl1);
double step1 = (dl1- df1)/10;
double start1 = df1, end1 = df1;
while(abs(dl1 - end1) > Precision::Confusion())
{
start1 = end1;
end1 += step1;
if(abs(end1 - dl1) < step1 * 0.5)
{
end1 = dl1;
}
Handle(Geom_TrimmedCurve) myTrimmed1 = new Geom_TrimmedCurve(cv1, start1, end1);
TopoDS_Edge newEdge1 = BRepBuilderAPI_MakeEdge(myTrimmed1);
Bnd_Box box1;
BRepBndLib::Add(newEdge1, box1);
box1.SetGap(Precision::Confusion());
int count = edgeSet1.size() + 1;
edgeSet1.insert(make_pair(count, newEdge1));
boxSet1.insert(make_pair(count, box1));
}
Handle(Geom_Curve) cv2 = BRep_Tool::Curve(e2, df2,dl2);
double step2 = (dl2- df2)/10;
double start2 = df2, end2 = df2;
while(abs(dl2 - end2) > Precision::Confusion())
{
start2 = end2;
end2 += step2;
if(abs(end2 - dl2) < step2 * 0.5)
{
end2 = dl2;
}
Handle(Geom_TrimmedCurve) myTrimmed2 = new Geom_TrimmedCurve(cv2, start2, end2);
TopoDS_Edge newEdge2 = BRepBuilderAPI_MakeEdge(myTrimmed2);
Bnd_Box box2;
BRepBndLib::Add(newEdge2, box2);
box2.SetGap(Precision::Confusion());
int count = edgeSet2.size() + 1;
edgeSet2.insert(make_pair(count, newEdge2));
boxSet2.insert(make_pair(count, box2));
}
for(map<int, TopoDS_Edge>::iterator iter1 = edgeSet1.begin(); iter1 != edgeSet1.end(); iter1++)
{
int edgeId1 = iter1->first;
TopoDS_Edge edge1 = iter1->second;
Bnd_Box box1 = boxSet1[edgeId1];
for(map<int, TopoDS_Edge>::iterator iter2 = edgeSet2.begin(); iter2 != edgeSet2.end(); iter2++)
{
int edgeId2 = iter2->first;
TopoDS_Edge edge2 = iter2->second;
Bnd_Box box2 = boxSet2[edgeId2];
if(box1.IsOut(box2))
{
continue;
}
//if(IsParallel(edge1, edge2))
//{
// continue;
//}
if(algo.CheckTwoEdgeOverlapByLinePointProject(edge1, edge2))
{
//continue;
//Handle_Standard_Failure e = new Standard_Failure();
//e->SetMessageString("RepeatExist");
//throw Standard_Failure("RepeatExist");
//throw "存在重合线"; //20180101 modified by czb输出重合线的序号
//CString str1;
//str1.Format(_T("%d和%d存在重合"), e1It->first+1, e2It->first+1);
//throw Standard_Failure(str1);
throw Standard_Failure("RepeatExist");
//char c[8];
//string s = itoa(e1It->first+1,c,10);
//s += _T("和");
//s += itoa(e2It->first+1,c,10);
//s += _T("重合");
//throw s;
}
Handle(Geom_Curve) c1 = BRep_Tool::Curve(edge1, df1,dl1);
Handle(Geom_Curve) c2 = BRep_Tool::Curve(edge2, df2,dl2);
c1 = new Geom_TrimmedCurve(c1,df1,dl1);
c2 = new Geom_TrimmedCurve(c2,df2,dl2);
GetEdgeStartEndPoint(e1,p1,p2);
GetEdgeStartEndPoint(e2,p3,p4);
if(p1.Distance(p3) <Precision::Confusion() || p1.Distance(p4)<Precision::Confusion())
{
bool isSame = false;
for(int t = 0; t < pSet.size(); t++)
{
if(p1.Distance(pSet[t]) < Precision::Confusion())
{
isSame = true;
break;
}
}
if(!isSame)
{
pSet.push_back(p1);
}
}
if(p2.Distance(p3) <Precision::Confusion() || p2.Distance(p4)<Precision::Confusion())
{
bool isSame = false;
for(int t = 0; t < pSet.size(); t++)
{
if(p2.Distance(pSet[t]) < Precision::Confusion())
{
isSame = true;
break;
}
}
if(!isSame)
{
pSet.push_back(p2);
}
}
GeomAPI_ExtremaCurveCurve intcc(c1, c2);
int nPnt = intcc.NbExtrema();
for(int i=1;i<=nPnt;i++)
{
gp_Pnt pp1,pp2;
intcc.NearestPoints(pp1, pp2);
double dis = pp1.Distance(pp2);
if(disV > dis)
{
disV = dis;
}
if(dis<tol)
{
bool isSame = false;
for(int t = 0; t < pSet.size(); t++)
{
if(pp1.Distance(pSet[t]) < Precision::Confusion())
{
isSame = true;
break;
}
}
if(!isSame)
{
pSet.push_back(pp1);
}
}
}
TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(p1);
BRepExtrema_DistShapeShape dst(v ,edge2 );
dst.Perform();
if(dst.Value() < tol)
{
bool isSame = false;
gp_Pnt pp1 = BRep_Tool::Pnt(v);
for(int t = 0; t < pSet.size(); t++)
{
if(pp1.Distance(pSet[t]) < Precision::Confusion())
{
isSame = true;
break;
}
}
if(!isSame)
{
pSet.push_back(pp1);
}
}
v = BRepBuilderAPI_MakeVertex(p2);
dst.LoadS1(v);
dst.LoadS2(edge2);
dst.Perform();
if(dst.Value() < tol)
{
bool isSame = false;
gp_Pnt pp1 = BRep_Tool::Pnt(v);
for(int t = 0; t < pSet.size(); t++)
{
if(pp1.Distance(pSet[t]) < Precision::Confusion())
{
isSame = true;
break;
}
}
if(!isSame)
{
pSet.push_back(pp1);
}
}
v = BRepBuilderAPI_MakeVertex(p3);
dst.LoadS1(v);
dst.LoadS2(edge1);
dst.Perform();
if(dst.Value() < tol)
{
bool isSame = false;
gp_Pnt pp1 = BRep_Tool::Pnt(v);
for(int t = 0; t < pSet.size(); t++)
{
if(pp1.Distance(pSet[t]) < Precision::Confusion())
{
isSame = true;
break;
}
}
if(!isSame)
{
pSet.push_back(pp1);
}
}
v = BRepBuilderAPI_MakeVertex(p4);
dst.LoadS1(v);
dst.LoadS2(edge1);
dst.Perform();
if(dst.Value() < tol)
{
bool isSame = false;
gp_Pnt pp1 = BRep_Tool::Pnt(v);
for(int t = 0; t < pSet.size(); t++)
{
if(pp1.Distance(pSet[t]) < Precision::Confusion())
{
isSame = true;
break;
}
}
if(!isSame)
{
pSet.push_back(pp1);
}
}
}
}
if(disV > 1E9)
{
return disV;
}
return disV;
}
double CSplitAllInsectionCurves::SectionPoints( TopoDS_Edge& e1, TopoDS_Edge& e2, double tol, vector<gp_Pnt>& pSet )
{
double disV = 1e10;
gp_Pnt p1, p2, p3,p4;
BaseAlgo algo;
map<int, TopoDS_Edge> edgeSet1;
map<int, TopoDS_Edge> edgeSet2;
map<int, Bnd_Box> boxSet1;
map<int, Bnd_Box> boxSet2;
GetEdgeStartEndPoint(e1,p1,p2);
GetEdgeStartEndPoint(e2,p3,p4);
double df1,dl1,df2,dl2;
Handle(Geom_Curve) cv1 = BRep_Tool::Curve(e1, df1,dl1);
double step1 = (dl1- df1)/10;
double start1 = df1, end1 = df1;
while(abs(dl1 - end1) > Precision::Confusion())
{
start1 = end1;
end1 += step1;
if(abs(end1 - dl1) < step1 * 0.5)
{
end1 = dl1;
}
Handle(Geom_TrimmedCurve) myTrimmed1 = new Geom_TrimmedCurve(cv1, start1, end1);
TopoDS_Edge newEdge1 = BRepBuilderAPI_MakeEdge(myTrimmed1);
Bnd_Box box1;
BRepBndLib::Add(newEdge1, box1);
box1.SetGap(Precision::Confusion());
int count = edgeSet1.size() + 1;
edgeSet1.insert(make_pair(count, newEdge1));
boxSet1.insert(make_pair(count, box1));
}
Handle(Geom_Curve) cv2 = BRep_Tool::Curve(e2, df2,dl2);
double step2 = (dl2- df2)/10;
double start2 = df2, end2 = df2;
while(abs(dl2 - end2) > Precision::Confusion())
{
start2 = end2;
end2 += step2;
if(abs(end2 - dl2) < step2 * 0.5)
{
end2 = dl2;
}
Handle(Geom_TrimmedCurve) myTrimmed2 = new Geom_TrimmedCurve(cv2, start2, end2);
TopoDS_Edge newEdge2 = BRepBuilderAPI_MakeEdge(myTrimmed2);
Bnd_Box box2;
BRepBndLib::Add(newEdge2, box2);
box2.SetGap(Precision::Confusion());
int count = edgeSet2.size() + 1;
edgeSet2.insert(make_pair(count, newEdge2));
boxSet2.insert(make_pair(count, box2));
}
for(map<int, TopoDS_Edge>::iterator iter1 = edgeSet1.begin(); iter1 != edgeSet1.end(); iter1++)
{
int edgeId1 = iter1->first;
TopoDS_Edge edge1 = iter1->second;
Bnd_Box box1 = boxSet1[edgeId1];
for(map<int, TopoDS_Edge>::iterator iter2 = edgeSet2.begin(); iter2 != edgeSet2.end(); iter2++)
{
int edgeId2 = iter2->first;
TopoDS_Edge edge2 = iter2->second;
Bnd_Box box2 = boxSet2[edgeId2];
if(box1.IsOut(box2))
{
continue;
}
//if(IsParallel(edge1, edge2))
//{
// continue;
//}
if(algo.CheckTwoEdgeOverlapByLinePointProject(edge1, edge2))
{
//throw "存在重合线"; //PJTODO:未来改成UTF8再解开注释
}
Handle(Geom_Curve) c1 = BRep_Tool::Curve(edge1, df1,dl1);
Handle(Geom_Curve) c2 = BRep_Tool::Curve(edge2, df2,dl2);
c1 = new Geom_TrimmedCurve(c1,df1,dl1);
c2 = new Geom_TrimmedCurve(c2,df2,dl2);
GetEdgeStartEndPoint(e1,p1,p2);
GetEdgeStartEndPoint(e2,p3,p4);
if(p1.Distance(p3) <Precision::Confusion() || p1.Distance(p4)<Precision::Confusion())
{
bool isSame = false;
for(int t = 0; t < pSet.size(); t++)
{
if(p1.Distance(pSet[t]) < Precision::Confusion())
{
isSame = true;
break;
}
}
if(!isSame)
{
pSet.push_back(p1);
}
}
if(p2.Distance(p3) <Precision::Confusion() || p2.Distance(p4)<Precision::Confusion())
{
bool isSame = false;
for(int t = 0; t < pSet.size(); t++)
{
if(p2.Distance(pSet[t]) < Precision::Confusion())
{
isSame = true;
break;
}
}
if(!isSame)
{
pSet.push_back(p2);
}
}
GeomAPI_ExtremaCurveCurve intcc(c1, c2);
int nPnt = intcc.NbExtrema();
for(int i=1;i<=nPnt;i++)
{
gp_Pnt pp1,pp2;
intcc.NearestPoints(pp1, pp2);
double dis = pp1.Distance(pp2);
if(disV > dis)
{
disV = dis;
}
if(dis<tol)
{
bool isSame = false;
for(int t = 0; t < pSet.size(); t++)
{
if(pp1.Distance(pSet[t]) < Precision::Confusion())
{
isSame = true;
break;
}
}
if(!isSame)
{
pSet.push_back(pp1);
}
}
}
TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(p1);
BRepExtrema_DistShapeShape dst(v ,edge2 );
dst.Perform();
if(dst.Value() < tol)
{
bool isSame = false;
gp_Pnt pp1 = BRep_Tool::Pnt(v);
for(int t = 0; t < pSet.size(); t++)
{
if(pp1.Distance(pSet[t]) < Precision::Confusion())
{
isSame = true;
break;
}
}
if(!isSame)
{
pSet.push_back(pp1);
}
}
v = BRepBuilderAPI_MakeVertex(p2);
dst.LoadS1(v);
dst.LoadS2(edge2);
dst.Perform();
if(dst.Value() < tol)
{
bool isSame = false;
gp_Pnt pp1 = BRep_Tool::Pnt(v);
for(int t = 0; t < pSet.size(); t++)
{
if(pp1.Distance(pSet[t]) < Precision::Confusion())
{
isSame = true;
break;
}
}
if(!isSame)
{
pSet.push_back(pp1);
}
}
v = BRepBuilderAPI_MakeVertex(p3);
dst.LoadS1(v);
dst.LoadS2(edge1);
dst.Perform();
if(dst.Value() < tol)
{
bool isSame = false;
gp_Pnt pp1 = BRep_Tool::Pnt(v);
for(int t = 0; t < pSet.size(); t++)
{
if(pp1.Distance(pSet[t]) < Precision::Confusion())
{
isSame = true;
break;
}
}
if(!isSame)
{
pSet.push_back(pp1);
}
}
v = BRepBuilderAPI_MakeVertex(p4);
dst.LoadS1(v);
dst.LoadS2(edge1);
dst.Perform();
if(dst.Value() < tol)
{
bool isSame = false;
gp_Pnt pp1 = BRep_Tool::Pnt(v);
for(int t = 0; t < pSet.size(); t++)
{
if(pp1.Distance(pSet[t]) < Precision::Confusion())
{
isSame = true;
break;
}
}
if(!isSame)
{
pSet.push_back(pp1);
}
}
}
}
if(disV > 1E9)
{
return disV;
}
//try
//{
// Handle(Geom_Curve) curve1 = GetBSplineCurve(e1);
// Handle(Geom_Curve) curve2 = GetBSplineCurve(e2);
// GeomAPI_ExtremaCurveCurve intcc(curve1, curve2);
// int nPnt = intcc.NbExtrema();
// disV = intcc.LowerDistance();
// for(int k = 0; k < nPnt; k++)
// {
// intcc.Points(k +1, p1,p2);
// pSet.push_back(gp_Pnt((p1.X() + p2.X()) / 2, (p1.Y() + p2.Y()) / 2, (p1.Z() + p2.Z()) / 2));
// }
//}
//catch (Standard_Failure)
//{
// TopoDS_Compound c;
// BRep_Builder b;
// b.MakeCompound(c);
// GetEdgeStartEndPoint(e1,p1,p2);
// GetEdgeStartEndPoint(e2,p2,p2);
// b.Add(c,e1);
// b.Add(c,e2);
// BRepTools::Write(c, "C:\\123.brep");
// throw c;
// return disV;
//}
//if(pSet.size() == 0)
//{
// pSet.push_back(p1);
//}
return disV;
}
//计算相邻三点之间的夹角如果夹角大于178度则删除中间点
void CSplitAllInsectionCurves::ClearPoints(vector<gp_Pnt> &pointSet, vector<int> indexSet)
{
if(indexSet.size() == 2)
{
return;
}
vector<gp_Pnt> pSet;
vector<bool> isSaved;
vector<bool> isUsed;
for(int i = 0; i < pointSet.size(); i++)
{
pSet.push_back(pointSet[i]);
isSaved.push_back(false);
isUsed.push_back(false);
}
//连接点前后分别保留12个点
for(int i = 1; i < indexSet.size() - 1; i++)
{
for(int k = 0; k < 6; k++)
{
if(indexSet[i] + k < indexSet[i+1])
{
isSaved[indexSet[i]+k] = true;
}
if(indexSet[i] - k > indexSet[i-1])
{
isSaved[indexSet[i]-k] = true;
}
}
}
//
for(int i = 1; i < indexSet.size(); i++)
{
for(int k = 1; k < indexSet[i] - indexSet[i-1]; k++)
{
if(k % 10 == 0)
{
isSaved[indexSet[i-1]+k] = true;
}
}
}
//
while(true)
{
double angleM = 0;
int startM,midM, endM;
for(int i = 0; i < pSet.size(); i++)
{
if(isUsed[i])
{
continue;
}
//获取起始点
int start = i;
int mid = i;
int end = i;
//获取中间点
for(int j = start + 1; j < pSet.size(); j++)
{
if(isUsed[j])
{
continue;
}
if(isSaved[j])
{
break;
}
mid = j;
break;
}
if(start == mid)
{
continue;
}
end = mid;
//获取结束点
for(int j = mid + 1; j < pSet.size(); j++)
{
if(isUsed[j])
{
continue;
}
end = j;
break;
}
if(end == mid)
{
continue;
}
//计算夹角
gp_Dir newDir1(pSet[start].X() - pSet[mid].X(), pSet[start].Y() - pSet[mid].Y(), pSet[start].Z() - pSet[mid].Z());
gp_Dir newDir2(pSet[mid].X() - pSet[end].X(), pSet[mid].Y() - pSet[end].Y(), pSet[mid].Z() - pSet[end].Z());
double angle = PI - newDir1.Angle(newDir2);
if(angleM < angle)
{
angleM = angle;
startM = start;
midM = mid;
endM = end;
}
}
if(angleM < PI * 178 / 180)
{
break;
}
isUsed[midM] = true;
}
pointSet.clear();
for(int i = 0; i < pSet.size(); i++)
{
if(isUsed[i])
{
continue;
}
pointSet.push_back(pSet[i]);
}
}
//拆分多边形 yc 20140804
map<int, vector<TopoDS_Edge>> CSplitAllInsectionCurves::SplitPolygon(vector<TopoDS_Edge> edgeSet, TopoDS_Face baseFace)
{
map<int, vector<TopoDS_Edge>> mapWires;
vector<gp_Pnt> pointSet;
vector<double> angleSet1;
vector<double> angleSet2;
for(int i = 0; i < edgeSet.size()-1; 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
{
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(p1);
pointSet.push_back(p2);
}
else
{
pointSet.push_back(p2);
pointSet.push_back(p1);
}
}
}
// 计算夹角
for(int i = 0; i < edgeSet.size(); i++)
{
TopoDS_Edge e1 = edgeSet[i];
TopoDS_Edge e2 = edgeSet[(i-1 + edgeSet.size())%edgeSet.size()];
angleSet1.push_back(ComputeAngle(e2,e1));
angleSet2.push_back(ComputeAngle3(e2,e1));
}
//for(int i = 0; i < pointSet.size(); i++)
//{
// gp_Pnt sPoint = pointSet[(i-1 + pointSet.size())%pointSet.size()];
// gp_Pnt mPoint = pointSet[i];
// gp_Pnt ePoint = pointSet[(i +1 + pointSet.size())%pointSet.size()];
// gp_Dir d1(sPoint.X() - mPoint.X(), sPoint.Y() - mPoint.Y(), sPoint.Z() - mPoint.Z());
// gp_Dir d2(mPoint.X() - ePoint.X(), mPoint.Y() - ePoint.Y(), mPoint.Z() - ePoint.Z());
// angleSet.push_back(PI - d1.Angle(d2));
//}
mapWires = SplitPolygonByAngle(edgeSet, pointSet, angleSet1, angleSet2, baseFace);
return mapWires;
}
map<int, vector<TopoDS_Edge>> CSplitAllInsectionCurves::SplitPolygon(vector<Handle(Geom_BSplineCurve)> vctBSplineCurves)
{
map<int, vector<TopoDS_Edge>> mapWires;
vector<TopoDS_Edge> edgeSet;
TopoDS_Face BFace;
for(int i = 0; i < vctBSplineCurves.size(); i++)
{
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(vctBSplineCurves[i]);
edgeSet.push_back(edge);
}
// /*多边变四边 拟合*/
vector<Handle(Geom_BSplineCurve)> vctMergeBSplineCurves;
CheckPolygonBSpline1(vctBSplineCurves,vctMergeBSplineCurves);//yc 2013730
//没有发生拟合
if(vctMergeBSplineCurves.size() == vctBSplineCurves.size())
{
mapWires.insert(make_pair(mapWires.size(), edgeSet));
return mapWires;
}
if(baseFace.IsNull())
{
//BRepBuilderAPI_MakeWire wire1 ;
//wire1.Add(BRepBuilderAPI_MakeEdge(vctMergeBSplineCurves[0]));
//BRepBuilderAPI_MakeWire wire2 ;
//wire2.Add(BRepBuilderAPI_MakeEdge(vctMergeBSplineCurves[1]));
//BRepOffsetAPI_ThruSections generator1(Standard_False,Standard_False);//第二个参数==TRUE直线方式;==FALSE曲线方式
//generator1.AddWire(wire1.Wire());
//generator1.AddWire(wire2.Wire());
//generator1.Build();
//TopoDS_Shape shape1 =generator1.Shape();
//TopoDS_Face face1;
//for(TopExp_Explorer ex(shape1, TopAbs_FACE);ex.More(); ex.Next())
//{
// face1 = TopoDS::Face(ex.Current());
// break;
//}
//BFace = face1;
//BFace = MakeFace(vctMergeBSplineCurves);
////throw BFace;
////vector<TopoDS_Edge> edges;
////for(int i = 0; i < vctMergeBSplineCurves.size(); i++)
////{
//// edges.push_back(BRepBuilderAPI_MakeEdge(vctMergeBSplineCurves[i]));
////}
////mapWires.insert(make_pair(mapWires.size(), edges));
////return mapWires;
}
else
{
BFace = baseFace;
}
if(BFace.IsNull())
{
//return mapWires;
}
////if(vctMergeBSplineCurves.size() == 4)
////{
//// throw BFace;
//// //BRep_Builder b;
//// //TopoDS_Compound c;
//// //b.MakeCompound(c);
//// //for(int i = 0; i < edgeSet.size(); i++)
//// //{
//// // b.Add(c,edgeSet[i]);
//// //}
//// //throw c;
////}
mapWires = SplitPolygon(edgeSet, BFace);
return mapWires;
}
TopoDS_Face CSplitAllInsectionCurves::MakeFace(vector<TopoDS_Edge> edgeSet)
{
vector<Handle(Geom_BSplineCurve)> vctBSplineCurves;
vector<gp_Pnt> ps;
for(int i = 0; i < edgeSet.size(); i++)
{
gp_Pnt p1,p2;
GetEdgeStartEndPoint(edgeSet[i], p1,p2);
Handle(Geom_BSplineCurve) curve = GetBSplineCurve(edgeSet[i]);
vctBSplineCurves.push_back(curve);
ps.push_back(p1);
ps.push_back(p2);
}
TopoDS_Face face ;
try
{
face = MakeFace(vctBSplineCurves);
}
catch (Standard_Failure)
{
throw 0;
}
return face;
}
TopoDS_Face CSplitAllInsectionCurves::MakeFace(vector<Handle(Geom_BSplineCurve)> vctBSplineCurves)
{
TopoDS_Face face;
GeomFill_BSplineCurves fill;
bool isFill = false;
vector<gp_Pnt> pSet;
TopoDS_Compound c;
BRep_Builder b;
b.MakeCompound(c);
for(int i = 0; i < vctBSplineCurves.size(); i++)
{
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(vctBSplineCurves[i]);
b.Add(c,edge);
gp_Pnt pp1,pp2;
GetEdgeStartEndPoint(edge,pp1,pp2);
bool isExist = false;
for(int j = 0; j < pSet.size(); j++)
{
if(pp1.Distance(pSet[j]) < Precision::Confusion())
{
isExist = true;
break;
}
}
if(!isExist)
{
pSet.push_back(pp1);
}
isExist = false;
for(int j = 0; j < pSet.size(); j++)
{
if(pp2.Distance(pSet[j]) < Precision::Confusion())
{
isExist = true;
break;
}
}
if(!isExist)
{
pSet.push_back(pp2);
}
}
if(pSet.size() != vctBSplineCurves.size())
{
throw c;
}
static int ii = 0;
try
{
if(vctBSplineCurves.size() == 2)
{
fill=GeomFill_BSplineCurves(vctBSplineCurves[0],vctBSplineCurves[1],GeomFill_StretchStyle);
isFill = true;
}
else if(vctBSplineCurves.size() == 3)
{
//TriangleEdge(vctBSplineCurves);
fill=GeomFill_BSplineCurves(vctBSplineCurves[0],vctBSplineCurves[1],vctBSplineCurves[2],GeomFill_StretchStyle);
isFill = true;
}
else if(vctBSplineCurves.size() == 4)
{
fill=GeomFill_BSplineCurves(vctBSplineCurves[0],vctBSplineCurves[1],vctBSplineCurves[2],vctBSplineCurves[3],GeomFill_StretchStyle);
isFill = true;
}
if(isFill)
{
Handle(Geom_BSplineSurface) BSS = fill.Surface();
//face = BRepBuilderAPI_MakeFace(BSS); // XUEFENG DELETE 202101
face = BRepBuilderAPI_MakeFace(BSS, Precision::Confusion()); // XUEFENG ADDED 202101
ii++;
}
}
catch(Standard_Failure)
{
throw c;
}
if(face.IsNull())
{
face = face;
}
return face;
}
map<int, vector<TopoDS_Edge>> CSplitAllInsectionCurves::SplitPolygonByAngle(vector<TopoDS_Edge> edgeSet,vector<gp_Pnt> pointSet, vector<double> angleSet1, vector<double> angleSet2, TopoDS_Face baseFace)
{
map<int, vector<TopoDS_Edge>>mapWires;
bool isMerg = false;
int index = -1;
switch (edgeSet.size())
{
case 2:
break;
//三边 如果存在角度大于150 合并成两边
case 3:
//if(angle > PI * 5 / 6)
//{
// isMerg = true;
//}
break;
//四边 如果存在角度大于135 合并成三边
case 4:
//index = FindAngleIndex(angleSet1, angleSet2, PI * 8 / 9, PI / 5);
//if(index < 0)
//{
// //return mapWires;
// break;
//}
//isMerg = true;
//if(angle > PI * 8 / 9)
//{
// isMerg = true;
//}
break;
// 大于四边 合并大于108的角
default:
index = FindAngleIndex(angleSet1, angleSet2, PI * 3 / 5, PI / 5);
if(index < 0)//没有满足的角度
{
if(edgeSet.size() > 4)//大于4边必须拟合
{
index = 0;
}
else
{
return mapWires;
}
}
isMerg = true;
break;
}
if(isMerg)
{
int index2 = GetPointByAngle(index, pointSet);
vector<TopoDS_Edge> newEdges;
//求交得到一条新边
//newEdges = CreateNewEdge(index, index2, pointSet, baseFace);
//放样
//newEdges = CreateNewEdge(index, index2, pointSet, edgeSet);
//直线
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(pointSet[index], pointSet[index2]);
newEdges.push_back(edge);
if(newEdges.size() == 0)
{
//拟合
newEdges = CreateNewEdge(index, index2, pointSet, baseFace);
}
if(newEdges.size() == 0)
{
//直线
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(pointSet[index], pointSet[index2]);
newEdges.push_back(edge);
}
//清理边界重合边
vector<TopoDS_Edge> tmpNewEdges = newEdges;
newEdges.clear();
BaseAlgo baseAlgo;
for(int i = 0 ; i < tmpNewEdges.size(); i++)
{
bool isCoincide = false;
for(int j = 0; j < edgeSet.size(); j++)
{
if(baseAlgo.CheckTwoEdgeOverlapByLinePointProject(tmpNewEdges[i], edgeSet[j]))
{
isCoincide = true;
break;
}
}
if(isCoincide)
{
continue;
}
newEdges.push_back(tmpNewEdges[i]);
//throw tmpNewEdges[i];
}
if(newEdges.size() == 0)
{
TopoDS_Compound c;
BRep_Builder b;
b.MakeCompound(c);
for(int j = 0; j < edgeSet.size(); j++)
{
b.Add(c, edgeSet[j]);
}
//return mapWires;
throw c;
}
for(int i = 0; i < edgeSet.size(); i++)
{
newEdges.push_back(edgeSet[i]);
}
try
{
CSplitAllInsectionCurves m_tool;
m_tool.Init(newEdges, baseFace);
for(int k = 0; k < newEdges.size(); k++)
{
gp_Pnt p1, p2;
GetEdgeStartEndPoint(newEdges[k],p1,p2);
//cout<<"edge"<<k<<endl;
//cout<<p1.X()<<", "<<p1.Y()<<", "<<p1.Z()<<endl;
//cout<<p2.X()<<", "<<p2.Y()<<", "<<p2.Z()<<endl;
}
m_tool.Build(false);
mapWires = m_tool.GetResult();
}
catch(Standard_Failure)
{
TopoDS_Compound c;
BRep_Builder b;
b.MakeCompound(c);
for(int j = 0; j < newEdges.size(); j++)
{
b.Add(c, newEdges[j]);
}
throw c;
}
}
else
{
mapWires.insert(make_pair(mapWires.size(), edgeSet));
}
return mapWires;
}
int CSplitAllInsectionCurves::FindAngleIndex(vector<double> angleSet1, vector<double> angleSet2 , double val1, double val2)
{
for(int i = 0; i < angleSet1.size(); i++)
{
if(val1 < angleSet1[i] && val2 >angleSet2[i])
{
return i;
}
}
return -1;
}
double CSplitAllInsectionCurves::ComputeAngle(TopoDS_Edge edge1 ,TopoDS_Edge edge2)
{
double angle1 = ComputeAngle1(edge1, edge2);
double angle2 = ComputeAngle2(edge1, edge2);
return angle1 > angle2 ? angle1 : angle2;
}
double CSplitAllInsectionCurves::ComputeAngle1(TopoDS_Edge edge1 ,TopoDS_Edge edge2)
{
double angle = 0;
gp_Pnt p1 ,p2;
GetEdgeStartEndPoint(edge1, p1,p2);
gp_Pnt p3 ,p4;
GetEdgeStartEndPoint(edge2, p3,p4);
gp_Pnt pf, pm,pe;
if(p1.Distance(p3) < Precision::Confusion() * 50)
{
pf = p2;
pm = p1;
pe = p4;
}
else if(p2.Distance(p3) < Precision::Confusion() * 50)
{
pf = p1;
pm = p2;
pe = p4;
}
else if(p1.Distance(p4) < Precision::Confusion() * 50)
{
pf = p2;
pm = p1;
pe = p3;
}
else if(p2.Distance(p4) < Precision::Confusion() * 50)
{
pf = p1;
pm = p2;
pe = p3;
}
//端点角度
gp_Dir d1(pf.X() - pm.X(), pf.Y() - pm.Y(), pf.Z() - pm.Z());
gp_Dir d2(pm.X() - pe.X(), pm.Y() - pe.Y(), pm.Z() - pe.Z());
angle= PI - d1.Angle(d2);
return angle;
}
double CSplitAllInsectionCurves::ComputeAngle2(TopoDS_Edge edge1 ,TopoDS_Edge edge2)
{
double angle = 0;
double df1, dl1;
double df2, dl2;
gp_Pnt p1 ,p2;
gp_Pnt p3 ,p4;
Handle(Geom_Curve) curve1 = BRep_Tool::Curve(edge1, df1,dl1);
p1 = curve1->Value(df1);
p2 = curve1->Value(dl1);
Handle(Geom_Curve) curve2 = BRep_Tool::Curve(edge2, df2,dl2);
p3 = curve2->Value(df2);
p4 = curve2->Value(dl2);
gp_Pnt pf, pm,pe;
if(p1.Distance(p3) < Precision::Confusion() * 50)
{
pf = curve1->Value(df1 + (dl1- df1) / 100 );
pm = p1;
pe =curve2->Value(df2 + (dl2- df2) / 100 );
}
else if(p2.Distance(p3) < Precision::Confusion() * 50)
{
pf = curve1->Value(dl1 - (dl1- df1) / 100 );
pm = p2;
pe = curve2->Value(df2 + (dl2- df2) / 100 );
}
else if(p1.Distance(p4) < Precision::Confusion() * 50)
{
pf = curve1->Value(df1 + (dl1- df1) / 100 );
pm = p1;
pe = curve2->Value(dl2 - (dl2- df2) / 100 );
}
else if(p2.Distance(p4) < Precision::Confusion() * 50)
{
pf = curve1->Value(dl1 - (dl1- df1) / 100 );
pm = p2;
pe = curve2->Value(dl2 - (dl2- df2) / 100 );
}
//端点角度
gp_Dir d1(pf.X() - pm.X(), pf.Y() - pm.Y(), pf.Z() - pm.Z());
gp_Dir d2(pm.X() - pe.X(), pm.Y() - pe.Y(), pm.Z() - pe.Z());
angle= PI - d1.Angle(d2);
return angle;
}
double CSplitAllInsectionCurves::ComputeAngle3(TopoDS_Edge edge1 ,TopoDS_Edge edge2)
{
double angle = 0;
double df1, dl1;
double df2, dl2;
gp_Pnt p1 ,p2;
gp_Pnt p3 ,p4;
Handle(Geom_Curve) curve1 = BRep_Tool::Curve(edge1, df1,dl1);
Handle(Geom_Curve) curve2 = BRep_Tool::Curve(edge2, df2,dl2);
GetEdgeStartEndPoint(edge1, p1,p2);
GetEdgeStartEndPoint(edge2, p3,p4);
gp_Pnt pf, pm,pe;
if(p1.Distance(p3) < Precision::Confusion() * 100)
{
pf = curve1->Value(df1 + (dl1- df1) / 2 );
pm = p1;
pe =curve2->Value(df2 + (dl2- df2) / 2 );
}
else if(p2.Distance(p3) < Precision::Confusion() * 100)
{
pf = curve1->Value(dl1 - (dl1- df1) / 2 );
pm = p2;
pe = curve2->Value(df2 + (dl2- df2) / 2 );
}
else if(p1.Distance(p4) < Precision::Confusion() * 100)
{
pf = curve1->Value(df1 + (dl1- df1) / 2 );
pm = p1;
pe = curve2->Value(dl2 - (dl2- df2) / 2 );
}
else if(p2.Distance(p4) < Precision::Confusion() * 100)
{
pf = curve1->Value(dl1 - (dl1- df1) / 2 );
pm = p2;
pe = curve2->Value(dl2 - (dl2- df2) / 2 );
}
//临近点点平面法向
gp_Dir d1(pf.X() - pm.X(), pf.Y() - pm.Y(), pf.Z() - pm.Z());
gp_Dir d2(pe.X() - pm.X(), pe.Y() - pm.Y(), pe.Z() - pm.Z());
gp_Dir d3(pe.X() - pf.X(), pe.Y() - pf.Y(), pe.Z() - pf.Z());
double t = d1.Angle(d2);
if(abs(t) < Precision::Confusion() || abs(abs(t) - PI) < Precision::Confusion()*1000)
{
return 0;
}
gp_Dir d = d1.Crossed(d2);
//d = d.Crossed(d3);
GetEdgeStartEndPoint(edge1, p1,p2);
GetEdgeStartEndPoint(edge2, p3,p4);
if(p1.Distance(p3) < Precision::Confusion() * 100)
{
pf = p2;
pm = p1;
pe = p4;
}
else if(p2.Distance(p3) < Precision::Confusion() * 100)
{
pf = p1;
pm = p2;
pe = p4;
}
else if(p1.Distance(p4) < Precision::Confusion() * 100)
{
pf = p2;
pm = p1;
pe = p3;
}
else if(p2.Distance(p4) < Precision::Confusion() * 100)
{
pf = p1;
pm = p2;
pe = p3;
}
//端点平面法向
gp_Dir dd1(pf.X() - pm.X(), pf.Y() - pm.Y(), pf.Z() - pm.Z());
gp_Dir dd2(pe.X() - pm.X(), pe.Y() - pm.Y(), pe.Z() - pm.Z());
gp_Dir dd3(pe.X() - pf.X(), pe.Y() - pf.Y(), pe.Z() - pf.Z());
double tt = dd1.Angle(dd2);
if(abs(tt) < Precision::Confusion() || abs(abs(tt) - PI) < Precision::Confusion()*1000)
{
return 0;
}
gp_Dir dd = dd1.Crossed(dd2);
//dd = dd.Crossed(dd3);
angle= (PI - dd.Angle(d) > dd.Angle(d)) ? dd.Angle(d) : PI - dd.Angle(d) ;
return angle;
}
int CSplitAllInsectionCurves::GetPointByAngle(int index, vector<gp_Pnt> pointSet)
{
double minAngle = 10;
int result = -1;
int iSP = (index + pointSet.size() - 1) % pointSet.size();
int iMP = index;
int iEP = (index + pointSet.size() + 1) % pointSet.size();
gp_Dir d1(pointSet[iMP].X() - pointSet[iSP].X(), pointSet[iMP].Y() - pointSet[iSP].Y(), pointSet[iMP].Z() - pointSet[iSP].Z());
gp_Dir d2(pointSet[iMP].X() - pointSet[iEP].X(), pointSet[iMP].Y() - pointSet[iEP].Y(), pointSet[iMP].Z() - pointSet[iEP].Z());
for(int i = 0; i < pointSet.size(); i++)
{
if(i == iSP || i == iMP || i == iEP)
{
continue;
}
gp_Dir d(pointSet[iMP].X() - pointSet[i].X(), pointSet[iMP].Y() - pointSet[i].Y(), pointSet[iMP].Z() - pointSet[i].Z());
double angle1 = d1.Angle(d);
double angle2 = d2.Angle(d);
double dis = abs(angle1 - angle2);
if(minAngle > dis)
{
minAngle = dis;
result = i;
}
}
return result;
}
//拟合面求交线
vector<TopoDS_Edge> CSplitAllInsectionCurves::CreateNewEdge(int startId, int endId, vector<gp_Pnt> pointSet, TopoDS_Face baseFace)
{
TopoDS_Face face;
int index = (startId + 1) % pointSet.size();
gp_Dir d1(pointSet[startId].X()-pointSet[index].X(), pointSet[startId].Y()-pointSet[index].Y(),pointSet[startId].Z()-pointSet[index].Z());
gp_Dir d2(pointSet[endId].X()-pointSet[index].X(), pointSet[endId].Y()- pointSet[index].Y(),pointSet[endId].Z()- pointSet[index].Z());
gp_Dir d3(pointSet[endId].X()-pointSet[startId].X(), pointSet[endId].Y()- pointSet[startId].Y(),pointSet[endId].Z()- pointSet[startId].Z());
gp_Dir d = d1.Crossed(d2);
d = d.Crossed(d3);
gp_Pln pln(pointSet[startId], d);
face = BRepBuilderAPI_MakeFace(pln);
SectionAlgo sectionAlgo;
TopoDS_Shape shape = sectionAlgo.SectionFF(face,baseFace);
vector<TopoDS_Edge> edges;
for(TopExp_Explorer ex(shape, TopAbs_EDGE); ex.More(); ex.Next())
{
gp_Pnt pStart = pointSet[startId];
gp_Pnt pEnd = pointSet[endId];
TopoDS_Edge ed = TopoDS::Edge(ex.Current());
TopoDS_Edge ed1 = RebuildEdge(TopoDS::Edge(ex.Current()), pStart,pEnd,false);
edges.push_back(ed1);
}
if(edges.size() == 0)
{
BRep_Builder b;
TopoDS_Compound cc;
b.MakeCompound(cc);
//b.Add(cc,baseFace);
b.Add(cc,face);
//throw cc;
}
return edges;
}
//放样方式 求平均
vector<TopoDS_Edge> CSplitAllInsectionCurves::CreateNewEdge(int startId, int endId, vector<gp_Pnt> pointSet, vector<TopoDS_Edge> edgeSet)
{
vector<TopoDS_Edge> edges;
gp_Pnt ps = pointSet[startId];
gp_Pnt pe = pointSet[endId];
TopoDS_Edge edge1 = edgeSet[startId];
TopoDS_Edge edge2 = edgeSet[(endId - 1+ edgeSet.size()) % edgeSet.size()];
//gp_Pnt p1,p2,p3,p4;
//double df,dl;
//Handle(Geom_Curve) c1 = BRep_Tool::Curve(edge1, df,dl);
//p1 = c1->Value(df);
//p2 = c1->Value(dl);
//if(p1.Distance(ps) < Precision::Confusion())
//{
// TopoDS_Edge edge = RebuildEdge(edge1, p1, p2, false);
// gp_Pnt p = c1->Value((df + dl) / 2);
// TrimEdgeBy2Points(edge, p1, p, edge1);
//}
//else if(p2.Distance(ps) < Precision::Confusion())
//{
// TopoDS_Edge edge = RebuildEdge(edge1, p1, p2, true);
// gp_Pnt p = c1->Value((df + dl) / 2);
// TrimEdgeBy2Points(edge, p2, p, edge1);
//}
//Handle(Geom_Curve) c2 = BRep_Tool::Curve(edge2, df,dl);
//p3 = c2->Value(df);
//p4 = c2->Value(dl);
//if(p3.Distance(pe) < Precision::Confusion())
//{
// TopoDS_Edge edge = RebuildEdge(edge2, p3, p4, true);;
// gp_Pnt p = c2->Value((df + dl) / 2);
// TrimEdgeBy2Points(edge, p3, p, edge2);
//}
//else if(p4.Distance(pe) < Precision::Confusion())
//{
// TopoDS_Edge edge = RebuildEdge(edge2, p3, p4, false);
// gp_Pnt p = c2->Value((df + dl) / 2);
// TrimEdgeBy2Points(edge, p4, p, edge2);
// p3 = p4;
//}
BRepBuilderAPI_MakeWire wire1 ;
wire1.Add(edge1);
BRepBuilderAPI_MakeWire wire2 ;
wire2.Add(edge2);
BRepOffsetAPI_ThruSections generator1(Standard_False,Standard_False);//第二个参数==TRUE直线方式;==FALSE曲线方式
//generator1.AddVertex(BRepBuilderAPI_MakeVertex(p3));
generator1.AddWire(wire1.Wire());
generator1.AddWire(wire2.Wire());
//generator1.AddVertex(BRepBuilderAPI_MakeVertex(p3));
generator1.Build();
TopoDS_Shape shape1 =generator1.Shape();
TopoDS_Face face1;
for(TopExp_Explorer ex(shape1, TopAbs_FACE);ex.More(); ex.Next())
{
face1 = TopoDS::Face(ex.Current());
break;
}
if(face1.IsNull())
{
return edges;
}
TopoDS_Edge edge3 = edgeSet[(startId - 1+ edgeSet.size()) % edgeSet.size()];
TopoDS_Edge edge4 = edgeSet[endId];
//Handle(Geom_Curve) c3 = BRep_Tool::Curve(edge3, df,dl);
//p1 = c3->Value(df);
//p2 = c3->Value(dl);
//if(p1.Distance(ps) < Precision::Confusion())
//{
// TopoDS_Edge edge = RebuildEdge(edge3, p1, p2, false);
// gp_Pnt p = c3->Value((df + dl) / 2);
// TrimEdgeBy2Points(edge, p1, p, edge3);
//}
//else if(p2.Distance(ps) < Precision::Confusion())
//{
// TopoDS_Edge edge = RebuildEdge(edge3, p1, p2, true);
// gp_Pnt p = c3->Value((df + dl) / 2);
// TrimEdgeBy2Points(edge, p2, p, edge3);
//}
//Handle(Geom_Curve) c4 = BRep_Tool::Curve(edge4, df,dl);
//p3 = c4->Value(df);
//p4 = c4->Value(dl);
//if(p3.Distance(pe) < Precision::Confusion())
//{
// TopoDS_Edge edge = RebuildEdge(edge4, p3, p4, false);
// gp_Pnt p = c4->Value((df + dl) / 2);
// TrimEdgeBy2Points(edge, p3, p, edge4);
//}
//else if(p4.Distance(pe) < Precision::Confusion())
//{
// TopoDS_Edge edge = RebuildEdge(edge4, p3, p4, true);
// gp_Pnt p = c4->Value((df + dl) / 2);
// TrimEdgeBy2Points(edge, p4, p, edge4);
// p3 = p4;
//}
BRepBuilderAPI_MakeWire wire3 ;
wire3.Add(edge3);
BRepBuilderAPI_MakeWire wire4 ;
wire4.Add(edge4);
BRepOffsetAPI_ThruSections generator2(Standard_False,Standard_False);//第二个参数==TRUE直线方式;==FALSE曲线方式
//generator2.AddVertex(BRepBuilderAPI_MakeVertex(p3));
generator2.AddWire(wire3.Wire());
generator2.AddWire(wire4.Wire());
//generator2.AddVertex(BRepBuilderAPI_MakeVertex(p3));
generator2.Build();
TopoDS_Shape shape2 = generator2.Shape();
TopoDS_Face face2;
for(TopExp_Explorer ex(shape2, TopAbs_FACE);ex.More(); ex.Next())
{
face2 = TopoDS::Face(ex.Current());
break;
}
if(face2.IsNull())
{
return edges;
}
vector<gp_Pnt> pSet1, pSet2;
for(TopExp_Explorer ex(face1, TopAbs_EDGE);ex.More(); ex.Next())
{
TopoDS_Edge e = TopoDS::Edge(ex.Current());
gp_Pnt p1,p2;
GetEdgeStartEndPoint(e, p1, p2);
if(p1.Distance(ps) < Precision::Confusion() && p2.Distance(pe) < Precision::Confusion())
{
Handle(Geom_BSplineCurve) bc = this->GetBSplineCurve(e);
gp_Pnt sp = bc->StartPoint();
gp_Pnt ep = bc->EndPoint();
double splinelength = GetEdgeLength(e);
double dF,dL;
Handle(Geom_Curve) aCurbs = BRep_Tool::Curve(e,dF,dL);
double dratio = (dL-dF)/100.0;
double dtotalratio = dF;
pSet1.push_back(p1);
for(int i = 1; i < 100; i++)
{
dtotalratio = dF + dratio * i;
pSet1.push_back(aCurbs->Value(dtotalratio));
}
pSet1.push_back(p2);
break;
}
else if(p2.Distance(ps) < Precision::Confusion() && p1.Distance(pe) < Precision::Confusion())
{
Handle(Geom_BSplineCurve) bc = this->GetBSplineCurve(e);
gp_Pnt sp = bc->StartPoint();
gp_Pnt ep = bc->EndPoint();
double splinelength = GetEdgeLength(e);
double dF,dL;
Handle(Geom_Curve) aCurbs = BRep_Tool::Curve(e,dF,dL);
double dratio = (dL-dF)/100.0;
double dtotalratio = dL;
pSet1.push_back(p2);
for(int i = 1; i < 100; i++)
{
dtotalratio = dL - dratio* i;
pSet1.push_back(aCurbs->Value(dtotalratio));
}
pSet1.push_back(p1);
break;
}
}
for(TopExp_Explorer ex(face2, TopAbs_EDGE);ex.More(); ex.Next())
{
TopoDS_Edge e = TopoDS::Edge(ex.Current());
gp_Pnt p1,p2;
GetEdgeStartEndPoint(e, p1, p2);
if(p1.Distance(ps) < Precision::Confusion() && p2.Distance(pe) < Precision::Confusion())
{
Handle(Geom_BSplineCurve) bc = this->GetBSplineCurve(e);
gp_Pnt sp = bc->StartPoint();
gp_Pnt ep = bc->EndPoint();
double splinelength = GetEdgeLength(e);
double dF,dL;
Handle(Geom_Curve) aCurbs = BRep_Tool::Curve(e,dF,dL);
double dratio = (dL-dF)/100.0;
double dtotalratio = dF;
pSet2.push_back(p1);
for(int i = 1; i < 100; i++)
{
dtotalratio = dF + dratio * i;
pSet2.push_back(aCurbs->Value(dtotalratio));
}
pSet2.push_back(p2);
break;
}
else if(p2.Distance(ps) < Precision::Confusion() && p1.Distance(pe) < Precision::Confusion())
{
Handle(Geom_BSplineCurve) bc = this->GetBSplineCurve(e);
gp_Pnt sp = bc->StartPoint();
gp_Pnt ep = bc->EndPoint();
double splinelength = GetEdgeLength(e);
double dF,dL;
Handle(Geom_Curve) aCurbs = BRep_Tool::Curve(e,dF,dL);
double dratio = (dL-dF)/100.0;
double dtotalratio = dL;
pSet2.push_back(p2);
for(int i = 1; i < 100; i++)
{
dtotalratio = dL - dratio * i;
pSet2.push_back(aCurbs->Value(dtotalratio));
}
pSet2.push_back(p1);
break;
}
}
vector<gp_Pnt> pSet, pSetTmp;
int count = 0;
if(pSet1.size() > 0)
{
count++;
}
if(pSet2.size() > 0)
{
count++;
}
if(count == 0)
{
return edges;
}
for(int i = 0; i < pSet1.size(); i++)
{
if(pSetTmp.size() == i)
{
pSetTmp.push_back(gp_Pnt(0,0,0));
}
gp_Pnt p((pSet1[i].X() + pSetTmp[i].X()),(pSet1[i].Y() + pSetTmp[i].Y()),(pSet1[i].Z() + pSetTmp[i].Z()));
//pSetTmp.push_back(p);
gp_Pnt &pp = pSetTmp[i];
pp.SetX(p.X());
pp.SetY(p.Y());
pp.SetZ(p.Z());
}
for(int i = 0; i < pSet2.size(); i++)
{
if(pSetTmp.size() == i)
{
pSetTmp.push_back(gp_Pnt(0,0,0));
}
gp_Pnt p((pSet2[i].X() + pSetTmp[i].X()),(pSet2[i].Y() + pSetTmp[i].Y()),(pSet2[i].Z() + pSetTmp[i].Z()));
//pSetTmp.push_back(p);
gp_Pnt &pp = pSetTmp[i];
pp.SetX(p.X());
pp.SetY(p.Y());
pp.SetZ(p.Z());
}
double len = pSetTmp[0].Distance(pSetTmp[pSetTmp.size() - 1]);
for(int i = 0; i < pSetTmp.size(); i++)
{
gp_Pnt p(pSetTmp[i].X() / count,pSetTmp[i].Y() / count,pSetTmp[i].Z() / count);
if(pSet.size() == 0)
{
pSet.push_back(p);
continue;
}
gp_Pnt ppp = pSet[pSet.size() - 1];
if(ppp.Distance(p) < len / 21)
{
if(i == pSet1.size() - 1)
{
pSet.pop_back();
pSet.push_back(p);
}
continue;
}
pSet.push_back(p);
}
if(pSet.size() > 2)
{
Handle(TColgp_HArray1OfPnt) harray =
new TColgp_HArray1OfPnt (1,pSet.size()); // sizing harray
for (int j=1;j<=pSet.size();j++)
{
harray->SetValue(j,pSet.at(j-1)) ;
}
GeomAPI_Interpolate anInterpolation(harray,Standard_False,Precision::Confusion());
anInterpolation.Perform();
Handle(Geom_BSplineCurve) SPL2;
if (anInterpolation.IsDone())
{
SPL2 = anInterpolation.Curve();
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(SPL2);
edge = RebuildEdge(edge, pSet[0], pSet[pSet.size() - 1], false);
edges.push_back(edge);
}
}
TopoDS_Compound c;
BRep_Builder b;
b.MakeCompound(c);
b.Add(c,shape1);
b.Add(c,shape2);
//for(int i = 0; i < edges.size(); i++ )
//{
// b.Add(c, edges[i]);
//}
//throw c;
return edges;
}
//vector<TopoDS_Edge> CSplitAllInsectionCurves::CreateNewEdge(int startId, int endId, vector<gp_Pnt> pointSet, vector<TopoDS_Edge> edgeSet)
//{
// vector<TopoDS_Edge> edges;
//
// gp_Pnt ps = pointSet[startId];
// gp_Pnt pe = pointSet[endId];
//
// TopoDS_Edge edge1 = edgeSet[startId];
// TopoDS_Edge edge2 = edgeSet[(endId - 1+ edgeSet.size()) % edgeSet.size()];
//
//
//
// BRepBuilderAPI_MakeWire wire1 ;
// for(int i = startId; i%edgeSet.size() != endId; i++)
// {
// wire1.Add(edgeSet[i%edgeSet.size()]);
// }
// BRepBuilderAPI_MakeWire wire2 ;
// for(int i = endId; i%edgeSet.size() != startId; i++)
// {
// wire2.Add(edgeSet[i%edgeSet.size()]);
// }
// BRepOffsetAPI_ThruSections generator1(Standard_False,Standard_False);//第二个参数==TRUE直线方式;==FALSE曲线方式
// generator1.AddWire(wire1.Wire());
// generator1.AddWire(wire2.Wire());
// generator1.Build();
// TopoDS_Shape shape1 =generator1.Shape();
// TopoDS_Face face1;
// for(TopExp_Explorer ex(shape1, TopAbs_FACE);ex.More(); ex.Next())
// {
// face1 = TopoDS::Face(ex.Current());
// break;
// }
// if(face1.IsNull())
// {
// return edges;
// }
//
//
//
// TopoDS_Compound c;
// BRep_Builder b;
// b.MakeCompound(c);
// b.Add(c,shape1);
// //b.Add(c,shape2);
// //for(int i = 0; i < edges.size(); i++ )
// //{
// // b.Add(c, edges[i]);
// //}
// //throw c;
// return edges;
//}
map<int, vector<TopoDS_Edge>> CSplitAllInsectionCurves::GetResult()
{
return this->mapResultWires;
}
map<int, vector<TopoDS_Edge>> CSplitAllInsectionCurves::GetOldResult()
{
map<int, vector<TopoDS_Edge>> result;
vector<CResultData> vctResultDatas;
for(std::map<int,vector<CResultData>>::iterator pit = m_ClosedResults.begin();pit != m_ClosedResults.end();++pit)
{
try
{
vctResultDatas = pit->second;
vector<TopoDS_Edge> edgeSet;
for(CResultData data :vctResultDatas)
//for each(CResultData data in vctResultDatas)
{
TopoDS_Edge wire = m_mapAllWires[data.m_iWireID];
Handle(Geom_BSplineCurve) curve = TrimWire2BSplineCurve(wire,data.m_dStartRatio,data.m_dEndRatio);
edgeSet.push_back(BRepBuilderAPI_MakeEdge(curve));
}
//result.insert(make_pair(result.size(), edgeSet));
}
catch(Standard_Failure)
{
continue;
}
}
return result;
}
TopoDS_Edge CSplitAllInsectionCurves::RebuildEdge(TopoDS_Edge edge, gp_Pnt startP, gp_Pnt endP, bool isReverse)
{
TopoDS_Edge result;
double df, dl;
gp_Pnt p1, p2;
Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, df, dl);
int size = 20;
double kk = (dl - df) / size;
double tol = 0.001;
vector<gp_Pnt> pSet;
if(isReverse)
{
p1 = curve->Value(dl);
if(p1.Distance(endP) < tol)
{
pSet.push_back(endP);
}
else if(p1.Distance(startP) < tol)
{
pSet.push_back(startP);
}
else
{
pSet.push_back(p1);
}
for(int i = 0; i < size; i++)
{
p1 = pSet[pSet.size() - 1];
p2 = curve->Value(dl - kk * i);
if(p1.Distance(p2) < Precision::Confusion() * 10)
{
continue;
}
pSet.push_back(p2);
}
p1 = pSet[pSet.size() - 1];
p2 = curve->Value(df);
if(p1.Distance(p2) < Precision::Confusion() * 10)
{
pSet.pop_back();
}
if(p2.Distance(startP) < tol)
{
pSet.push_back(startP);
}
else if(p2.Distance(endP) < tol)
{
pSet.push_back(endP);
}
else
{
pSet.push_back(p2);
}
}
else
{
p1 = curve->Value(df);
if(p1.Distance(startP) < tol)
{
pSet.push_back(startP);
}
else if(p1.Distance(endP) < tol)
{
pSet.push_back(endP);
}
else
{
pSet.push_back(p1);
}
for(int i = 0; i < size; i++)
{
p1 = pSet[pSet.size() - 1];
p2 = curve->Value(df + kk * i);
if(p1.Distance(p2) < Precision::Confusion() * 10)
{
continue;
}
pSet.push_back(p2);
}
p1 = pSet[pSet.size() - 1];
p2 = curve->Value(dl);
if(p1.Distance(p2) < Precision::Confusion() * 10)
{
pSet.pop_back();
}
if(p2.Distance(startP) < tol)
{
pSet.push_back(startP);
}
else if(p2.Distance(endP) < tol)
{
pSet.push_back(endP);
}
else
{
pSet.push_back(p2);
}
}
if(pSet.size() > 2)
{
Handle(TColgp_HArray1OfPnt) harray =
new TColgp_HArray1OfPnt (1,pSet.size()); // sizing harray
for (int j=1;j<=pSet.size();j++)
{
harray->SetValue(j,pSet.at(j-1)) ;
}
GeomAPI_Interpolate anInterpolation(harray,Standard_False,Precision::Confusion());
anInterpolation.Perform();
Handle(Geom_BSplineCurve) SPL2;
if (anInterpolation.IsDone())
{
SPL2 = anInterpolation.Curve();
result = BRepBuilderAPI_MakeEdge(SPL2);
}
else
{
result = edge;
}
}
else
{
result = edge;
}
return result;
}
TopoDS_Edge CSplitAllInsectionCurves::GetIWireByID(int id)
{
TopoDS_Edge edge;
if(m_mapAllWires.find(id) != m_mapAllWires.end())
{
edge = m_mapAllWires[id];
}
return edge;
}
CInsectionInfo::CInsectionInfo( void )
{
}
CInsectionInfo::~CInsectionInfo( void )
{
}
/*
GeomAPI_ProjectPointOnCurve Projector1 (Bpnt, C); //gp_Pnt Bpnt
gp_Pnt Bpnt_P1 = Projector1.NearestPoint();
Standard_Real p1_Bpnt_distance=Bpnt_P1.Distance (Bpnt) ;
if( Abs (p1_Bpnt_distance)<1)
AfxMessageBox(_T("tang"));
GeomAPI_ProjectPointOnCurve Projector2 (Epnt, C); //gp_Pnt Epnt
gp_Pnt Epnt_P2 = Projector2.NearestPoint();
Standard_Real p2_Bpnt_distance=Epnt_P2.Distance (Epnt) ;
if( Abs (p2_Bpnt_distance)<1)
AfxMessageBox(_T("xiao"));
if(Abs (p2_Bpnt_distance)<1 && Abs (p1_Bpnt_distance)<1)
{
TopoDS_Edge E_edge=BRepBuilderAPI_MakeEdge( C,Bpnt_P1,Epnt_P2);
..................................
................................
}
*/