X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FBlockFix%2FBlockFix_UnionEdges.cxx;h=7af310d0eaa8bf0dcbedb39b26ef7f028125299d;hb=5a3993c7b06b1f7b0d79e66af3411d9982cf2b62;hp=09c2caf0d398e37180a1237b26299645f02b43a6;hpb=6e2763b42437045fd4b18aa3a6197865020de84b;p=modules%2Fgeom.git diff --git a/src/BlockFix/BlockFix_UnionEdges.cxx b/src/BlockFix/BlockFix_UnionEdges.cxx index 09c2caf0d..7af310d0e 100644 --- a/src/BlockFix/BlockFix_UnionEdges.cxx +++ b/src/BlockFix/BlockFix_UnionEdges.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -88,6 +88,37 @@ #include "utilities.h" +//======================================================================= +//function : IsToMerge +//purpose : This method return Standard_True if two edges have common +// vertex. This vertex is returned by output parameter. The +// difference with the method TopExp::CommonVertex is only in +// the case if there are two common vertices. In this case +// this method returns the last vertex of theEdge1, not the first +// one that TopExp::CommonVertex does. +//======================================================================= +static Standard_Boolean GetCommonVertex(const TopoDS_Edge &theEdge1, + const TopoDS_Edge &theEdge2, + TopoDS_Vertex &theCommon) +{ + Standard_Boolean isFound = Standard_True; + ShapeAnalysis_Edge aSae; + TopoDS_Vertex aVF1 = aSae.FirstVertex(theEdge1); + TopoDS_Vertex aVL1 = aSae.LastVertex(theEdge1); + TopoDS_Vertex aVF2 = aSae.FirstVertex(theEdge2); + TopoDS_Vertex aVL2 = aSae.LastVertex(theEdge2); + + if (aVL1.IsSame(aVF2) || aVL1.IsSame(aVL2)) { + theCommon = aVL1; + } else if (aVF1.IsSame(aVL2) || aVF1.IsSame(aVF2)) { + theCommon = aVF1; + } else { + theCommon.Nullify(); + isFound = Standard_False; + } + + return isFound; +} //======================================================================= //function : IsToMerge @@ -95,9 +126,11 @@ // be merged. The edges can be merged if: // 1. They belong to same faces. // 2. They either both seam or both not seam on each face. -// 3. They are based on coincident lines, or: -// 4. They are based on coincident circles, or: -// 5. They are based on either Bezier of BSplines. +// 3. There are no another edges (e.g. seam) on each common face +// that are connected to the common vertex of two edges. +// 4. They are based on coincident lines, or: +// 5. They are based on coincident circles, or: +// 6. They are based on either Bezier of BSplines. //======================================================================= static Standard_Boolean IsToMerge (const TopoDS_Edge &theEdge1, @@ -108,7 +141,6 @@ static Standard_Boolean IsToMerge Standard_Boolean aResult = Standard_False; Standard_Boolean isDegen1 = BRep_Tool::Degenerated(theEdge1); Standard_Boolean isDegen2 = BRep_Tool::Degenerated(theEdge2); - Standard_Boolean isCompareGeom = Standard_False; if (isDegen1 && isDegen2) { // Both of edges are degenerated. @@ -118,7 +150,7 @@ static Standard_Boolean IsToMerge // Check if they belong to the same faces. Standard_Boolean isSame = Standard_False; Standard_Boolean has1 = theMapEdgeFaces.Contains(theEdge1); - Standard_Boolean has2 = theMapEdgeFaces.Contains(theEdge1); + Standard_Boolean has2 = theMapEdgeFaces.Contains(theEdge2); if (has1 && has2) { const TopTools_ListOfShape &aLst1 = theMapEdgeFaces.FindFromKey(theEdge1); @@ -129,7 +161,7 @@ static Standard_Boolean IsToMerge isSame = Standard_True; - for (; anIter1.More(); anIter1.Next()) { + for (; anIter1.More() && isSame; anIter1.Next()) { TopoDS_Face aFace1 = TopoDS::Face(anIter1.Value()); TopTools_ListIteratorOfListOfShape anIter2(aLst2); @@ -141,6 +173,44 @@ static Standard_Boolean IsToMerge Standard_Boolean isSeam2 = BRep_Tool::IsClosed(theEdge2, aFace1); isSame = (isSeam1 && isSeam2) || (isSeam1 == isSeam2); + + if (isSame) { + // Check if there are no other edges (e.g. seam) on this face + // that are connected to the common vertex. + TopoDS_Vertex aVCommon; + + if (GetCommonVertex(theEdge1, theEdge2, aVCommon)) { + TopTools_IndexedDataMapOfShapeListOfShape aMapVE; + + TopExp::MapShapesAndAncestors + (aFace1, TopAbs_VERTEX, TopAbs_EDGE, aMapVE); + + if (aMapVE.Contains(aVCommon)) { + TopTools_ListIteratorOfListOfShape + anItE(aMapVE.FindFromKey(aVCommon)); + + for (; anItE.More(); anItE.Next()) { + const TopoDS_Shape &anEdge = anItE.Value(); + + if (!theEdge1.IsSame(anEdge) && + !theEdge2.IsSame(anEdge)) { + // There is another edge that shares the common vertex. + // Nothing to merge. + isSame = Standard_False; + break; + } + } + } else { + // Common vertex doesn't belong to the face. + // Nothing to merge. NEVERREACHED. + isSame = Standard_False; + } + } else { + // No common vertex. Nothing to merge. NEVERREACHED. + isSame = Standard_False; + } + } + break; } } @@ -289,7 +359,7 @@ static TopoDS_Edge GlueEdgesWithPCurves(const TopTools_SequenceOfShape& aChain, if (i > 1) { - TopExp::CommonVertex(PrevEdge, anEdge, CV); + GetCommonVertex(PrevEdge, anEdge, CV); Standard_Real Tol = BRep_Tool::Tolerance(CV); tabtolvertex(i-2) = Tol; } @@ -305,11 +375,12 @@ static TopoDS_Edge GlueEdgesWithPCurves(const TopTools_SequenceOfShape& aChain, } Handle(TColGeom_HArray1OfBSplineCurve) concatcurve; //array of the concatenated curves Handle(TColStd_HArray1OfInteger) ArrayOfIndices; //array of the remining Vertex + Standard_Boolean ClosedFlag = Standard_False; GeomConvert::ConcatC1(tab_c3d, tabtolvertex, ArrayOfIndices, concatcurve, - Standard_False, + ClosedFlag, Precision::Confusion()); //C1 concatenation if (concatcurve->Length() > 1) @@ -355,11 +426,12 @@ static TopoDS_Edge GlueEdgesWithPCurves(const TopTools_SequenceOfShape& aChain, } Handle(TColGeom2d_HArray1OfBSplineCurve) concatc2d; //array of the concatenated curves Handle(TColStd_HArray1OfInteger) ArrayOfInd2d; //array of the remining Vertex + Standard_Boolean ClosedFlag = Standard_False; Geom2dConvert::ConcatC1(tab_c2d, tabtolvertex, ArrayOfInd2d, concatc2d, - Standard_False, + ClosedFlag, Precision::Confusion()); //C1 concatenation if (concatc2d->Length() > 1) @@ -393,7 +465,7 @@ static TopoDS_Edge GlueEdgesWithPCurves(const TopTools_SequenceOfShape& aChain, //======================================================================= //function : MergeEdges -//purpose : auxilary +//purpose : auxiliary //======================================================================= static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges, const Standard_Real Tol, @@ -511,16 +583,24 @@ static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges, if (C.IsNull()) { // jfa for Mantis issue 0020228 if (PV1.Distance(PV2) > Precision::Confusion()) continue; - // closed chain - if (edge1.Orientation() == TopAbs_FORWARD) { - C = C1; - } else { - C = Handle(Geom_Circle)::DownCast(C1->Reversed()); + // closed chain. Make a closed circular edge starting from V1. + gp_Ax1 anAxis = C1->Axis(); + + if (edge1.Orientation() == TopAbs_REVERSED) { + anAxis.Reverse(); } + const gp_Pnt &aP0 = anAxis.Location(); + gp_Dir aDX(PV1.XYZ().Subtracted(aP0.XYZ())); + gp_Ax2 aNewAxis(aP0, anAxis.Direction(), aDX); + + C = new Geom_Circle(aNewAxis, C1->Radius()); + B.MakeEdge (E,C,Precision::Confusion()); B.Add(E,V1); B.Add(E,V2); + B.UpdateVertex(V1, 0., E, 0.); + B.UpdateVertex(V2, 2.*M_PI, E, 0.); } else { gp_Pnt P0 = C->Location(); @@ -579,7 +659,7 @@ static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges, break; } if(NeedUnion) { - MESSAGE ("can not make analitical union => make approximation"); + MESSAGE ("can not make analytical union => make approximation"); TopoDS_Edge E = GlueEdgesWithPCurves(aChain, VF, VL); aChain.SetValue(1,E); }