NCollection_List< std::pair<TopoDS_Vertex, TopoDS_Vertex> > aVerticesForLackingEdgesBuilding;
typedef NCollection_DataMap<TopoDS_Face, Standard_Integer> FaceDataMap;
- // search vertices with tolerance greater than specified threshold (theMaxTol)
+ // search for vertices with tolerance greater than specified threshold (theMaxTol)
TopTools_IndexedMapOfShape aShapeVertexMap;
TopExp::MapShapes(myRecoveredShape, TopAbs_VERTEX, aShapeVertexMap);
Standard_Boolean anIsVertexReplaced = Standard_False;
gp_Pnt aFirstNewPnt, aSecondNewPnt; // these points will replace vertex with big tolerance
+ TopTools_MapOfShape anUniqueSharingWiresOfCurVertex;
TopTools_ListIteratorOfListOfShape anWireIter(aSharingWiresOfCurVertex);
for (;anWireIter.More() && !anIsVertexReplaced; anWireIter.Next())
{
const TopoDS_Wire& aCurWire = TopoDS::Wire(anWireIter.Value());
+ if (!anUniqueSharingWiresOfCurVertex.Contains(aCurWire))
+ anUniqueSharingWiresOfCurVertex.Add(aCurWire);
+ else
+ continue;
+
const TopTools_ListOfShape& aSharingFacesOfCurWire =
aWireFacesMap.FindFromKey (anWireIter.Value());
// in parametric space on the vector that was described previously
Standard_Integer aPntNbPerEdgeForProj = 10;
- // the analogues of the first and second points in parametric space of the face
- gp_Pnt2d aPFirst2D, aPSecond2D;
-
- // the wire is explored by BRepTools_WireExplorer and it is
- // guaranteed that edges will be SEQUENCIALLY connected
- Standard_Boolean isNOTExpByBRepTools_WireExplorer = Standard_False;
- Handle(ShapeExtend_WireData) anEdgeExp =
- new ShapeExtend_WireData(theWire, isNOTExpByBRepTools_WireExplorer);
+ // edges sharing the vertex
+ TopTools_ListOfShape aSharingEdges;
+ TopExp_Explorer aWireExp(theWire, TopAbs_EDGE);
+ for (; aWireExp.More(); aWireExp.Next())
+ {
+ const TopoDS_Edge& aCurEdge = TopoDS::Edge(aWireExp.Current());
+ if (!aCurEdge.IsNull())
+ {
+ TopExp_Explorer anEdgeExp(aCurEdge, TopAbs_VERTEX);
+ for (; anEdgeExp.More(); anEdgeExp.Next())
+ {
+ if (theVertex.IsSame(TopoDS::Vertex(anEdgeExp.Current())))
+ aSharingEdges.Append(aCurEdge);
+ }
+ }
+ }
+
+ if (aSharingEdges.IsEmpty())
+ return Standard_False;
- Standard_Integer aStartIndex = 1; // start index of ShapeExtend_WireData
- Standard_Integer anEndIndex = anEdgeExp->NbEdges();
+ NCollection_List<gp_Pnt2d> aPnt2DList;
+ gp_Pnt2d aPnt2D;
- if (anEndIndex == 0) // the WIRE IS EMPTY
- return Standard_False;
+ TopoDS_Vertex aFirstVertex,aLastVertex;
+ Standard_Real aFirstParam, aLastParam;
- // run through all edges and seek couple of edges which share the vertex
- Standard_Integer anEdgeIndex, anEdgeIndex_Prev, anEdgeIndex_Next;
- for (anEdgeIndex = aStartIndex; anEdgeIndex <= anEndIndex; anEdgeIndex++)
+ TopTools_ListIteratorOfListOfShape aSEdgeIter(aSharingEdges);
+ for (; aSEdgeIter.More(); aSEdgeIter.Next())
{
- // index of previous edge
- if (anEdgeIndex == aStartIndex) anEdgeIndex_Prev = anEndIndex;
- else anEdgeIndex_Prev = anEdgeIndex-1;
+ const TopoDS_Edge& anEdge = TopoDS::Edge(aSEdgeIter.Value());
+ TopExp::Vertices(anEdge, aFirstVertex, aLastVertex, Standard_False);
- // index of next element
- if (anEdgeIndex == anEndIndex) anEdgeIndex_Next = aStartIndex;
- else anEdgeIndex_Next = anEdgeIndex+1;
+ Handle(Geom2d_Curve) aPCurve =
+ BRep_Tool::CurveOnSurface (anEdge, theFace, aFirstParam, aLastParam);
- const TopoDS_Edge& aCurEdge = anEdgeExp->Edge(anEdgeIndex);
+ if (theVertex.IsSame(aFirstVertex))
+ {
+ aPCurve->D0(aFirstParam, aPnt2D);
+ aPnt2DList.Append(aPnt2D);
+ }
- TopoDS_Vertex aCurFirstVertex = TopExp::FirstVertex(aCurEdge);
- TopoDS_Vertex aCurLastVertex = TopExp::LastVertex(aCurEdge);
+ if (theVertex.IsSame(aLastVertex))
+ {
+ aPCurve->D0(aLastParam, aPnt2D);
+ aPnt2DList.Append(aPnt2D);
+ }
+ }
- Standard_Boolean anIsFirstBelong = theVertex.IsSame(aCurFirstVertex);
- Standard_Boolean anIsLastBelong = theVertex.IsSame(aCurLastVertex);
+ if (aPnt2DList.Extent() < 2)
+ return Standard_False;
- if (!anIsFirstBelong && !anIsLastBelong)
- continue;
+ gp_Pnt2d aFirstPnt2D, aSecondPnt2D;
- //int todo_investigate_degenerated_edge;
+ NCollection_List<gp_Pnt2d>::Iterator aPnt2DIter(aPnt2DList);
- Standard_Real aPFirstParamOfCurEdge, aPLastParamOfCurEdge;
- Handle(Geom2d_Curve) aPCurveOfCurEdge =
- BRep_Tool::CurveOnSurface (aCurEdge, theFace, aPFirstParamOfCurEdge, aPLastParamOfCurEdge);
+ // first param point
+ aFirstPnt2D = aPnt2DIter.Value();
+
+ // second param point
+ aPnt2DIter.Next();
+ aSecondPnt2D = aPnt2DIter.Value();
- if (anIsFirstBelong && anIsLastBelong) // both ends of current edge belong to the vertex
- {
- aPCurveOfCurEdge->D0(aPFirstParamOfCurEdge, aPFirst2D);
- aPCurveOfCurEdge->D0(aPLastParamOfCurEdge, aPSecond2D);
- }
- else
- {
- if (anIsFirstBelong) // first end of current edge
- aPCurveOfCurEdge->D0(aPFirstParamOfCurEdge, aPFirst2D);
- else if (anIsLastBelong) // last end of current edge
- aPCurveOfCurEdge->D0(aPLastParamOfCurEdge, aPFirst2D);
-
- // is second edge nether next edge in the sequence or previous?
- TopAbs_Orientation aCurEdgeOrient = aCurEdge.Orientation();
- Standard_Boolean anIsSecondANextEdge =
- (aCurEdgeOrient == TopAbs_FORWARD && anIsLastBelong) ||
- (aCurEdgeOrient == TopAbs_REVERSED && anIsFirstBelong);
-
- Standard_Integer anIndexOfEdgeWithSecondPnt =
- (anIsSecondANextEdge ? anEdgeIndex_Next : anEdgeIndex_Prev);
-
- //
- const TopoDS_Edge& anEdgeWithSecondPnt = anEdgeExp->Edge(anIndexOfEdgeWithSecondPnt);
- TopAbs_Orientation anOrientOfEdgeWithSecondPnt = anEdgeWithSecondPnt.Orientation();
-
- Standard_Boolean isFirstVertexOfEdgeWithSecondPnt = Standard_True;
- if (anIsSecondANextEdge) // next edge in the edge sequence
- {
- if (anOrientOfEdgeWithSecondPnt == TopAbs_FORWARD)
- isFirstVertexOfEdgeWithSecondPnt = Standard_True;
- else
- isFirstVertexOfEdgeWithSecondPnt = Standard_False;
- }
- else // previous edge in sequence in the edge sequence
- {
- if (anOrientOfEdgeWithSecondPnt == TopAbs_FORWARD)
- isFirstVertexOfEdgeWithSecondPnt = Standard_False;
- else
- isFirstVertexOfEdgeWithSecondPnt = Standard_True;
- }
+ // todo: process other points if they exist
- Standard_Real aFirstParamOfEdgeWithSecondPnt, aLastParamOfEdgeWithSecondPnt;
- Handle(Geom2d_Curve) aPCurveOfEdgeWithSecondPnt =
- BRep_Tool::CurveOnSurface (anEdgeWithSecondPnt, theFace,
- aFirstParamOfEdgeWithSecondPnt,
- aLastParamOfEdgeWithSecondPnt);
+ if (aFirstPnt2D.Distance(aSecondPnt2D) <= Precision::PConfusion())
+ return Standard_False;
- if (isFirstVertexOfEdgeWithSecondPnt)
- aPCurveOfEdgeWithSecondPnt->D0(aFirstParamOfEdgeWithSecondPnt, aPSecond2D);
- else
- aPCurveOfEdgeWithSecondPnt->D0(aLastParamOfEdgeWithSecondPnt, aPSecond2D);
- }
+ // project points of edges on aPVec2D
+ Standard_Real aProjLength = ProjectTo2DVector(theWire, theFace, aPntNbPerEdgeForProj, aFirstPnt2D, aSecondPnt2D);
- if (aPFirst2D.Distance(aPSecond2D) <= Precision::Confusion())
- continue;
+ gp_Vec2d aVec2D(aFirstPnt2D, aSecondPnt2D);
- // project points of edges on aPVec2D
- Standard_Real aProjLength = ProjectTo2DVector(anEdgeExp, theFace, aPntNbPerEdgeForProj, aPFirst2D, aPSecond2D);
-
- gp_Vec2d aPVec2D(aPFirst2D, aPSecond2D);
- if (aProjLength <= aStripRatio*aPVec2D.Magnitude())
- {
- TopLoc_Location aLocation;
- Handle(Geom_Surface) aSurf = BRep_Tool::Surface (theFace, aLocation);
+ if (aProjLength > aStripRatio*aVec2D.Magnitude())
+ return Standard_False;
- aSurf->D0(aPFirst2D.X() , aPFirst2D.Y(), theFirstPnt);
- aSurf->D0(aPSecond2D.X(), aPSecond2D.Y(), theSecondPnt);
+ TopLoc_Location aLocation;
+ Handle(Geom_Surface) aSurf = BRep_Tool::Surface (theFace, aLocation);
- return Standard_True;
- }
- }
+ aSurf->D0(aFirstPnt2D.X() , aFirstPnt2D.Y(), theFirstPnt);
+ aSurf->D0(aSecondPnt2D.X(), aSecondPnt2D.Y(), theSecondPnt);
- return Standard_False;
+ return Standard_True;
}
//=======================================================================
//function : ProjectTo2DVector
//purpose :
//=======================================================================
-Standard_Real ShapeFix_LackingEdgeRecover::ProjectTo2DVector(const Handle(ShapeExtend_WireData)& theWireData,
+Standard_Real ShapeFix_LackingEdgeRecover::ProjectTo2DVector(const TopoDS_Wire& theWire,
const TopoDS_Face& theFace,
const Standard_Real thePntNbPerEdgeForProj,
const gp_Pnt2d& thePFirst2D,
{
gp_Vec2d aPVec2D(thePFirst2D, thePSecond2D);
+ // the wire is explored by BRepTools_WireExplorer and it is
+ // guaranteed that edges will be SEQUENCIALLY connected
+ Standard_Boolean isNOTExpByBRepTools_WireExplorer = Standard_False;
+ Handle(ShapeExtend_WireData) aWireData =
+ new ShapeExtend_WireData(theWire, isNOTExpByBRepTools_WireExplorer);
+
Standard_Integer aStartIndex = 1; // start index of ShapeExtend_WireData
- Standard_Integer anEndIndex = theWireData->NbEdges();
+ Standard_Integer anEndIndex = aWireData->NbEdges();
// project points of edges on aPVec2D
Standard_Real aMaxWireValue = -Precision::Infinite();
{
Standard_Real aPFirstParamOfIntCurEdge, aPLastParamOfIntCurEdge;
Handle(Geom2d_Curve) aPCurveOfIntCurEdge =
- BRep_Tool::CurveOnSurface (theWireData->Edge(aCurEdgeIndex), theFace,
+ BRep_Tool::CurveOnSurface (aWireData->Edge(aCurEdgeIndex), theFace,
aPFirstParamOfIntCurEdge, aPLastParamOfIntCurEdge);
// split the curve of the current edge on aPntNbPerEdgeForProj parts