COMPASSi/trunk/code/inc/OCC/OCCLib/SplitAllInsectionCurves.h

441 lines
17 KiB
C
Raw Normal View History

2025-06-25 15:06:42 +08:00
#pragma once
#include "Geometry.h"
// ADDED BY XUEFENG 201808
// FOR CODES COMBINE
// ADDED BY XUEFENG 2018.04
typedef std::pair<int, int> Point_Arc_Pair;
typedef std::pair<int, int> Point_Point_Pair;
// End Added
// END ADDED
class TopoDS_Wire;
class CInsectionInfo
{
public:
CInsectionInfo(void);
~CInsectionInfo(void);
public:
//点所属边
std::vector<int> m_vctBelongWireIDs;
//点坐标
gp_Pnt m_PtCoor;
//点id
int m_Id;
//std::map<int,Standard_Real> m_mapdis2start;
};
class CHalfEdgeKey
{
public:
//起始点id
int m_iStartPointID;
//结束点id
int m_iEndPointID;
//线段id
int m_iIntersectionInfoID;
CHalfEdgeKey()
{
m_iStartPointID = 0 ;
m_iEndPointID = 0 ;
m_iIntersectionInfoID = 0 ;
//ElemKey = 0 ;
}
bool operator < ( const CHalfEdgeKey rhs) const
{
if(m_iIntersectionInfoID < rhs.m_iIntersectionInfoID)
{
return true;
}
else if(m_iIntersectionInfoID == rhs.m_iIntersectionInfoID)
{
// if(ElemKey < rhs.ElemKey)
// {
// return true;
// }
// if(ElemKey == rhs.ElemKey)
// {
if(m_iStartPointID < rhs.m_iStartPointID)
{
return true;
}
else if(m_iStartPointID == rhs.m_iStartPointID)
{
if(m_iEndPointID < rhs.m_iEndPointID)
{
return true;
}
}
//}
}
return false;
}
};
class CInsectionSectionInfo
{
public:
CInsectionSectionInfo(void){};
~CInsectionSectionInfo(void){};
public:
Standard_Real GetDistance2Start();
public:
// CInsectionInfo m_startInsection;
// CInsectionInfo m_endInsection;
//起始点id
int m_startInsection;
//结束点id
int m_endInsection;
//线段id
int m_Id;
//所属原边id
int m_BelongWireID;
};
class CResultData
{
public:
//原线id
int m_iWireID;
//起始位置
double m_dStartRatio;
//终止位置
double m_dEndRatio;
//与原线方向是否相反
int m_iFlag; // 1 -1
protected:
private:
};
class CSplitAllInsectionCurves
{
public:
CSplitAllInsectionCurves(void);
//*********** flag ********************************* 交点约束
CSplitAllInsectionCurves(std::map<int,Curve>& m_Curves, std::map<int,Point3D>& m_Points);
//*********************************************************
~CSplitAllInsectionCurves(void);
public:
//初始化线数据
void Init(const std::vector<TopoDS_Edge>& wires,const std::vector<std::string>& seqNo);
//初始化线数据,包含边界
void Init(const std::vector<TopoDS_Edge>& wires,const std::vector<std::string>& strNames,std::vector<int>& borderWireID);
//初始化线数据,包含基础面(用于拆分多边形)
void Init(const std::vector<TopoDS_Edge>& wires, TopoDS_Face baseFace);
//初始化线数据
void Init(const std::vector<TopoDS_Edge>& wires);
//初始化线数据
void Init(std::map<int,TopoDS_Edge>& wires, std::vector<int> ids);
//执行网格面算法
bool Build(bool bsolid=false);//srq 2011-6-3
//获取所有闭合的网格
bool GetAllWires(bool bsolid);
//将多边形进行拆分,获取最终用于生成面的网格
bool GetAllFaces(bool bsolid);
//显示线端点信息
void ShowBSplineStartEndPoint(const Handle(Geom_BSplineCurve) BSplineCurve);
//
void GetClosedShapes(std::map<int,TopoDS_Shape>& shapes);
//
void GetClosedCurves(std::map<int,vector<Handle(Geom_BSplineCurve)>>& ClosedBSplineCurves);
//
void GetIntersectionPoints(std::map<int,CInsectionInfo>& mapAllInsectionPoints){mapAllInsectionPoints =m_mapAllInsectionPoints; }
//
std::map<int,vector<int>> GetClosedZoomPointID(){return m_mapClosedZooms;};
//
std::map<int,bool> GetErrorClosedZoomID();
//
std::vector<pair<pair<int,int>,int>> GetIntersectionTimeSearchs();
//获取闭合线框集合
std::map<int,vector<CResultData>> GetClosedResultDatas(){return m_ClosedResults;};
//获取原线名称
std::string GetWireName(int iID);
//获取最终网格结果
map<int, vector<TopoDS_Edge>> GetResult();
//获取原始边
TopoDS_Edge GetIWireByID(int id);
private:
//*********** flag ********************************* 交点约束
std::map<int,Point3D> m_mapPoints;
std::map<int,Curve> m_mapCurves;
//*********************************************************
//所有原始边集合
std::map<int,TopoDS_Edge> m_mapAllWires;
//所有交点集合
std::map<int,CInsectionInfo> m_mapAllInsectionPoints;
//所原始边被交点拆分后,线段集合
std::map<int,CInsectionSectionInfo> m_mapAllInsectionSectionInfo;
//主从周边点集合
std::map<int,vector<int>> m_mapInsectionAround;
//记录周边点号
std::map<int,vector<int>> m_mapClosedZooms;
//闭合线框id
int m_ClosedZoomID;
//记录周边线号
std::map<int,vector<int>> m_mapClosedWires;
//
std::map<int,TopoDS_Shape> m_mapClosedShape;
//闭合的b样条线框集合
std::map<int,vector<Handle(Geom_BSplineCurve)>> m_mapClosedBSplineCurves;
//
std::map<int,bool> m_mapSuccessGenFaces;
//采用半边边界方法取封闭区域
//半边是否被使用
std::map<CHalfEdgeKey,int> m_mapHalfEdgesUsed;
//线段被使用的次数
std::map<int,int> m_mapIntersectinInfoTimeSearchs;
//闭合线框边集合
std::map<int,vector<CResultData>> m_ClosedResults;
//原始边名称
std::map<int,std::string> m_mapWireID2Name;
//允许误差
double m_precision;
//yc 20131031
//原始边的包围盒
std::map<int, Bnd_Box> m_mapWireBox;
//yc 201307424
//边界,搜索到的闭合线框的边不能都在边界中
std::vector<int> border;
//
TopoDS_Face baseFace;
//闭合线框结果集合
map<int, vector<TopoDS_Edge>> mapResultWires;
private:
//yc 20131031
//创建原始线框的包围盒
void CreateWireBox();
//判断两条边是否已经求交
bool haveInsect(std::vector<pair<int,int>>& haveInsects,int id1,int id2,bool autosave = true);
//检查交点
void CalcInsectionSections();
//*********** flag ********************************* 交点约束
void CalcInsectionPoints();
//**********************************************************
//获取线的端点
void GetWireStartEndPoint(const TopoDS_Wire& wire,gp_Pnt& sp,gp_Pnt& ep);
//获取线的端点
void GetEdgeStartEndPoint(const TopoDS_Edge& edge,gp_Pnt& sp,gp_Pnt& ep);
//
bool GetWireIDbyIntersectionPointID(int InsectionPoint1,int InsectionPoint2,int& wireId);
//
bool GetWireIDbyIntersectionInfoID(int InsectionSectionInfoid,int& wireId);
//获取线段上所有交点
void FindWirePoints(int iWireID,std::vector<int>& ptids);
//将线上交点进行排序
void SortByWire(int iWireID,std::vector<int>& ptids);
//将线上交点进行排序
void SortByWire(int iWireID,std::vector<gp_Pnt>& pts);
//获取线上点到线起始点的长度
Standard_Real GetPoint2StartByWire(const TopoDS_Edge& wire,const gp_Pnt& pt);
//获取线段长度
Standard_Real GetEdgeLength(const TopoDS_Edge& aE );
//
bool isOnPlan(vector<Handle(Geom_BSplineCurve)> vctBSplineCurves, gp_Pln& pln);
//获取交点id
bool haveInsectPoint(gp_Pnt pt,int& iBelongid);
//
bool GetNextPointCollect(int iMasterID,vector<int>& slaveids);
//iStep 取值从2-4
//
bool GetClosedPoints(int iMasterID,int iStep);
//
bool IsExistClosedZoom(const vector<int>& slaveids);
//将vector转化为set
std::set<int> convertvct2set(const vector<int>& slaveids);
//
bool IsIncludeClosedZoom(const vector<int>& srcids,const vector<int>& slaveids);
//将id集合转化为字符串
std::string Set2String(const std::set<int>& setids);
//两点截取线段
bool TrimWireBy2Points(const gp_Pnt& pt1,const gp_Pnt& pt2,const TopoDS_Wire& srcwire,TopoDS_Edge& newwire,TopoDS_Edge& basicedge);
//判断点是否在线上
bool IsPointOnEdge(const TopoDS_Edge& edge,const gp_Pnt& pt1);
//判断点是否在线上
bool IsPointOnWire(const TopoDS_Wire& wire,const gp_Pnt& pt1);
//两点截取线段
bool TrimEdgeBy2Points(const TopoDS_Edge& edge,const gp_Pnt& pt1,const gp_Pnt& pt2,TopoDS_Edge& newEdge);
//
bool GetInsectionSectionInfoId(int InsectionPoint1,int InsectionPoint2,int& InsectionSectionInfoId);
//将topo转化为B样条曲线
Handle(Geom_BSplineCurve) GetBSplineCurve(const TopoDS_Shape& aS);
//将topo转化为B样条曲线
Handle(Geom_BSplineCurve) ConvertEdge2BSplineCurve(const TopoDS_Edge& edge);
//两点截取线段
Handle(Geom_BSplineCurve) TrimWire2BSplineCurve(const TopoDS_Edge& basicWire,const gp_Pnt& pt1,const gp_Pnt& pt2,Standard_Real& dF,Standard_Real& dL);
//两点截取线段
Handle(Geom_BSplineCurve) TrimWire2BSplineCurve(const TopoDS_Edge& basicWire,const Standard_Real& dF,const Standard_Real& dL);
//搜索闭合线框
bool GetClosedZooms();
//
bool ModifyHalfEdgeUse(int ptid1,int ptid2);
//
int GetHalfEdgeUseStep(int ptid1,int ptid2);
//
void AddHalfEdgeUse(const std::vector<int>& ids);
//
Handle(Geom_BSplineCurve) MergeSubBSpline(const vector<int>& subarcids,int iWireid,Standard_Real& dF,Standard_Real& dL);
//
Handle(Geom_BSplineCurve) FindSrcBSpline(const vector<Handle(Geom_BSplineCurve)>& vctBSplineCurves,const vector<CResultData>& resultdatas, const vector<pair<int,int>>& wiresectids,int isectioninfoid,CResultData& data);
//如果封闭区域中有存在外轮廓,则去掉
void ClearMaxEdgeBoundingBox();
//多边形拟合成4边行
bool GetPolygonBSplineSurfaceByMorethan4Sides(const vector<Handle(Geom_BSplineCurve)>& vctBSplineCurves,vector<Handle(Geom_BSplineCurve)>& newvctBSplineCurves);
//
void SortClosedSidesByClock(const vector<int>& slaveids,vector<Handle(Geom_BSplineCurve)>& newvctBSplineCurves,vector<CResultData>& newvctResultDatas);
//
bool IsCloseBSplines( vector<Handle(Geom_BSplineCurve)>& vctBSplineCurves,vector<CResultData>& newvctResultDatas);
//
bool IsExsitNextEdge(const vector<pair<gp_Pnt,gp_Pnt>>& pairPoints,int iCurrentIndex);
// 返回多边形面 TopoDS_Shell
TopoDS_Shape GetPolygonBSplineSurfaceByMorethan4Sides(vector<Handle(Geom_BSplineCurve)>& vctCurve);
// 拆分多边形成多个三角形 每个三角形生成一个TopoDS_Face
void PolygonSplit(vector<Handle(Geom_BSplineCurve)>& vctCurve, vector<TopoDS_Face> &vctTopoFace);
// 返回相邻边的连接点
gp_Pnt GetConnectionPoint(Handle(Geom_BSplineCurve)& curve1, Handle(Geom_BSplineCurve)& curve2);
//返回相邻边的连接点
gp_Pnt GetConnectionPoint(TopoDS_Edge egde1, TopoDS_Edge edge2);
//
void TriangleEdge(vector<Handle(Geom_BSplineCurve)>& edgeSet);
//通过判断角度 拟合多边形
void CheckPolygonBSpline(const vector<Handle(Geom_BSplineCurve)>& vctBSplineCurves,vector<Handle(Geom_BSplineCurve)>& newvctBSplineCurves);
//通过判断端点角度和法向夹角,拟合多边形
void CheckPolygonBSpline1(const vector<Handle(Geom_BSplineCurve)>& vctBSplineCurves,vector<Handle(Geom_BSplineCurve)>& newvctBSplineCurves);
//
void CheckPolygonBSpline2(const vector<Handle(Geom_BSplineCurve)>& vctBSplineCurves,vector<Handle(Geom_BSplineCurve)>& newvctBSplineCurves);
//通过判断边夹角,进行拟合
void 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);
//拟合指定两条边
void 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 MaxAngleIndex( map<int, double>& edgeAngle);
//判断两条边是否平行
bool IsParallel(const TopoDS_Edge& e1, const TopoDS_Edge& e2);
//边边求交点
double DistanceEE(TopoDS_Edge& e1, TopoDS_Edge& e2, gp_Pnt& p);
//边边求交点
double SectionPoints( TopoDS_Edge& e1, TopoDS_Edge& e2, double tol, vector<gp_Pnt>& pSet );
double SectionPoints( std::map<int,TopoDS_Edge>::const_iterator& e1, std::map<int,TopoDS_Edge>::const_iterator& e2, double tol, vector<gp_Pnt>& pSet ); //20180101 added by czb错误时输出边的序号
//计算相邻三点之间的夹角如果夹角大于178度则删除中间点
void ClearPoints(vector<gp_Pnt> &pointSet,vector<int> indexSet);
// 拆分多边形 yc 20140804 start
map<int, vector<TopoDS_Edge>> SplitPolygon(vector<Handle(Geom_BSplineCurve)> vctBSplineCurves);
//拆分多边形,基于基面,获取拆分交线
map<int, vector<TopoDS_Edge>> SplitPolygon(vector<TopoDS_Edge> edgeSet, TopoDS_Face baseFace);
//生成面
TopoDS_Face MakeFace(vector<TopoDS_Edge> edgeSet);
//生成面
TopoDS_Face MakeFace(vector<Handle(Geom_BSplineCurve)> vctBSplineCurves);
//通过判断边夹角,拆分多边形
map<int, vector<TopoDS_Edge>> SplitPolygonByAngle(vector<TopoDS_Edge> edgeSet,vector<gp_Pnt> pointSet, vector<double> angleSet1, vector<double> angleSet2, TopoDS_Face baseFace);
//获取满足条件的夹角id
int FindAngleIndex( vector<double> angleSet1, vector<double> angleSet2, double val1, double val2);
//计算边夹角,返回端点夹角与临近点夹角的最大值
double ComputeAngle(TopoDS_Edge e1 ,TopoDS_Edge e2);
//平面法向角度
double ComputeAngle3(TopoDS_Edge e1 ,TopoDS_Edge e2);
//临近点角度
double ComputeAngle2(TopoDS_Edge e1 ,TopoDS_Edge e2);
//端点角度
double ComputeAngle1(TopoDS_Edge e1 ,TopoDS_Edge e2);
//获取夹角最大的点id
int GetPointByAngle(int index, vector<gp_Pnt> pointSet);
//拟合面求交线
vector<TopoDS_Edge> CreateNewEdge(int startId, int endId, vector<gp_Pnt> pointSet, TopoDS_Face baseFace);
//放样方式 求平均
vector<TopoDS_Edge> CreateNewEdge(int startId, int endId, vector<gp_Pnt> pointSet, vector<TopoDS_Edge> edgeSet);
public:
// 通过差值重构边 yc 20140804 end
TopoDS_Edge RebuildEdge(TopoDS_Edge edge, gp_Pnt p1, gp_Pnt p2, bool isReverse);
//获取原始闭合线框,即未经拆分
map<int, vector<TopoDS_Edge>> GetOldResult();
// ADDED BY XUEFENG 20180731
// FOR CODES COMBINE
// ADDED BY XUEFENG 2018.04
public:
// typedef std::pair<int pointId, int ArcId> Point_Arc_Pair;
std::vector< std::vector<Point_Arc_Pair> > SuccessfulGridVector; // 每次循环得到的封闭回路,可以有多个
std::vector<int> SuccessfulGridWireNumVector;
std::vector< std::vector<Point_Arc_Pair> > finalFoundGridFaceVector; // 最终得到的所有封闭回路的结果
// Grid NEW Algorithm
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> >
std::map< int, Point_Point_Pair > m_mapArc_point1_point2; // std::vector< arcId, <int pointId1, int pointId2>,...,<int pointId1, int pointId2>>
std::map< int, int > m_mapArc_CanBeUsedNum;
void GridAlgorithm_Recursion(int firstPointId, int prePointId, int preArcId, int realStep, bool strictStep, std::vector<Point_Arc_Pair> existPointArcs);
bool GridAlgorithm_FindExistOrNot(int newPoint, std::vector<Point_Arc_Pair> existPointsArcs); // 对比递归调用中新发现的点是否已经走过
std::vector<Point_Arc_Pair> GridAlgorithm_Copy_PointArc_Vector(std::vector<Point_Arc_Pair> existPointsArcs);
bool GridAlgorithm_JudgeTheSameWire(int arcId1, int arcId2);
bool GridAlgorithm_JudgeInTheSameWire(int arcId1, std::vector<Point_Arc_Pair> existPointArcs);
void GridAlgorithm_ConstructGrid( );
void GridAlgorithm_DoPrepairData();
std::vector<Point_Arc_Pair> GridAlgorithm_FindSmallestAndNewOne(); // 每次循环找到wire边数最小的封闭回路
std::vector<Point_Arc_Pair> GridAlgorithm_FindSmallestArcAndNewOne();// 每次循环找到arc数最小的封闭回路 ADDED BY XUEFENG
void GridAlgorithm_DoCleanAffairs();
void GridAlgorithm_DoRemoveArcActions(); // 移除已经确定不会再被用的边点
void GridAlgorithm_DoRemoveArcActionsOnlyArcs();// 仅仅移除绝对不会再被用的边
bool GridAlgorithm_CompareExistFinalVector(std::vector<Point_Arc_Pair> inputPA); // 对比新发现的封闭回路与已经存在的封闭回路是否相同
bool GridAlgorithm_FindOverlapWithFinalVector(std::vector<Point_Arc_Pair> inputPA);// ADDED BY XUEFENG 20190902
bool GridAlgorithm_BigVecIncludeSmallVec(std::vector<Point_Arc_Pair> existVector, std::vector<Point_Arc_Pair> newVector);
std::vector<int> GridAlgorithm_DoSortArcVector(std::vector<Point_Arc_Pair> inputPA);
void GridAlgorithm_FinalVectorToResult(); // 将最后生成的封闭回路的数据转化为m_ClosedResults数据类型
bool GridAlgorithm_JudgeCurvesClosed(std::vector<Handle(Geom_BSplineCurve)> closeCurves);
public:
// XUEFENG ADDED 201805 初始化线数据,加约束曲线
void ExpInit(const std::vector<TopoDS_Edge>& wires,const std::vector<std::string>& seqNo, const std::vector<int>& expSeqNo);
private:
// ADDED BY XUEFENG 201805
std::vector<int> m_expWireSeqNo;
//所有约束边集合
std::map<int,TopoDS_Edge> m_mapAllExpWires;
//约束边名称
std::map<int,std::string> m_mapExpWireID2Name;
// END ADDED
// END ADDED
};