diff -Nru opencascade-7.5.1+dfsg1/debian/changelog opencascade-7.5.2+dfsg1/debian/changelog --- opencascade-7.5.1+dfsg1/debian/changelog 2021-02-25 20:56:23.000000000 +0000 +++ opencascade-7.5.2+dfsg1/debian/changelog 2021-07-02 02:06:14.000000000 +0000 @@ -1,8 +1,15 @@ -opencascade (1:7.5.1+dfsg1-0~202102252047~ubuntu20.04.1) focal; urgency=low +opencascade (1:7.5.2+dfsg1-0~202107020155~ubuntu20.04.1) focal; urgency=low * Auto build. - -- Kurt Kremitzki Thu, 25 Feb 2021 20:56:23 +0000 + -- Kurt Kremitzki Fri, 02 Jul 2021 02:06:14 +0000 + +opencascade (1:7.5.2+dfsg1-1) unstable; urgency=medium + + * [a006615] New upstream version 7.5.2+dfsg1 + * [b52e7f3] Update hardcoded versions to 7.5.2 + + -- Kurt Kremitzki Thu, 01 Jul 2021 12:40:29 -0500 opencascade (1:7.5.1+dfsg1-1) unstable; urgency=medium diff -Nru opencascade-7.5.1+dfsg1/debian/git-build-recipe.manifest opencascade-7.5.2+dfsg1/debian/git-build-recipe.manifest --- opencascade-7.5.1+dfsg1/debian/git-build-recipe.manifest 2021-02-25 20:56:23.000000000 +0000 +++ opencascade-7.5.2+dfsg1/debian/git-build-recipe.manifest 2021-07-02 02:06:14.000000000 +0000 @@ -1,2 +1,2 @@ -# git-build-recipe format 0.4 deb-version 1:{debupstream}-0~202102252047 -lp:~freecad-maintainers/opencascade/+git/main git-commit:ae9450ef2c4872a9845aebd46ea4db5e5b868080 +# git-build-recipe format 0.4 deb-version 1:{debupstream}-0~202107020155 +lp:~freecad-maintainers/opencascade/+git/main git-commit:140f69ef4c6871d647aa5bd7389feec190873bdb diff -Nru opencascade-7.5.1+dfsg1/debian/occt-draw.1 opencascade-7.5.2+dfsg1/debian/occt-draw.1 --- opencascade-7.5.1+dfsg1/debian/occt-draw.1 2021-02-25 20:56:17.000000000 +0000 +++ opencascade-7.5.2+dfsg1/debian/occt-draw.1 2021-07-02 02:06:10.000000000 +0000 @@ -6,6 +6,6 @@ .SH DESCRIPTION This program provides a kind of scripting interface to the OpenCASCADE libraries. You can perform a simple test by starting it and entering at the -command line: "pload ALL" then "source /usr/share/occt/7.5.1/src/DrawResources/VisualizationDemo.tcl". +command line: "pload ALL" then "source /usr/share/occt/7.5.2/src/DrawResources/VisualizationDemo.tcl". .SH AUTHOR Adam Powell diff -Nru opencascade-7.5.1+dfsg1/debian/occt-draw-7.5.1 opencascade-7.5.2+dfsg1/debian/occt-draw-7.5.1 --- opencascade-7.5.1+dfsg1/debian/occt-draw-7.5.1 2021-02-25 20:56:17.000000000 +0000 +++ opencascade-7.5.2+dfsg1/debian/occt-draw-7.5.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -.TH occt-draw 1 "OpenCASCADE command interpreter and graphical test system" "DEBIAN" \" -*- nroff -*- -.SH NAME -occt-draw \- OpenCASCADE command interpreter and graphical test system -.SH SYNOPSIS -\fBocct-draw\fP -.SH DESCRIPTION -This program provides a kind of scripting interface to the OpenCASCADE -libraries. You can perform a simple test by starting it and entering at the -command line: "pload ALL" then "source /usr/share/occt/7.5.1/src/DrawResources/VisualizationDemo.tcl". -.SH AUTHOR -Adam Powell diff -Nru opencascade-7.5.1+dfsg1/debian/occt-draw-7.5.2 opencascade-7.5.2+dfsg1/debian/occt-draw-7.5.2 --- opencascade-7.5.1+dfsg1/debian/occt-draw-7.5.2 1970-01-01 00:00:00.000000000 +0000 +++ opencascade-7.5.2+dfsg1/debian/occt-draw-7.5.2 2021-07-02 02:06:10.000000000 +0000 @@ -0,0 +1,11 @@ +.TH occt-draw 1 "OpenCASCADE command interpreter and graphical test system" "DEBIAN" \" -*- nroff -*- +.SH NAME +occt-draw \- OpenCASCADE command interpreter and graphical test system +.SH SYNOPSIS +\fBocct-draw\fP +.SH DESCRIPTION +This program provides a kind of scripting interface to the OpenCASCADE +libraries. You can perform a simple test by starting it and entering at the +command line: "pload ALL" then "source /usr/share/occt/7.5.2/src/DrawResources/VisualizationDemo.tcl". +.SH AUTHOR +Adam Powell diff -Nru opencascade-7.5.1+dfsg1/debian/occt-draw.install opencascade-7.5.2+dfsg1/debian/occt-draw.install --- opencascade-7.5.1+dfsg1/debian/occt-draw.install 2021-02-25 20:56:17.000000000 +0000 +++ opencascade-7.5.2+dfsg1/debian/occt-draw.install 2021-07-02 02:06:10.000000000 +0000 @@ -1,7 +1,7 @@ #!/usr/bin/dh-exec ../occ-icon-48.xpm usr/share/icons/hicolor/64x64/apps ../occt-draw*.desktop usr/share/applications -usr/bin/DRAWEXE-7.5.1 => usr/bin/occt-draw-7.5 +usr/bin/DRAWEXE-7.5.2 => usr/bin/occt-draw-7.5 usr/bin/custom_gcc_${DEB_HOST_ARCH_BITS}.sh => usr/share/opencascade/bin/custom_gcc_${DEB_HOST_ARCH_BITS}.sh usr/bin/custom.sh => usr/share/opencascade/bin/custom.sh usr/bin/draw.sh => usr/share/opencascade/bin/draw.sh diff -Nru opencascade-7.5.1+dfsg1/debian/occt-draw.manpages opencascade-7.5.2+dfsg1/debian/occt-draw.manpages --- opencascade-7.5.1+dfsg1/debian/occt-draw.manpages 2021-02-25 20:56:17.000000000 +0000 +++ opencascade-7.5.2+dfsg1/debian/occt-draw.manpages 2021-07-02 02:06:10.000000000 +0000 @@ -1,2 +1,2 @@ -debian/occt-draw-7.5.1 +debian/occt-draw-7.5.2 debian/occt-draw.1 diff -Nru opencascade-7.5.1+dfsg1/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx opencascade-7.5.2+dfsg1/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx --- opencascade-7.5.1+dfsg1/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx 2021-02-02 08:51:56.000000000 +0000 +++ opencascade-7.5.2+dfsg1/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx 2021-04-20 07:07:58.000000000 +0000 @@ -648,8 +648,8 @@ // check if the pave block has a valid range Standard_Real aFirst, aLast; if (!BRepLib::FindValidRange(GeomAdaptor_Curve(aIC.Curve()), aTolR3D, - aT1, BRep_Tool::Pnt(aV1), BRep_Tool::Tolerance(aV1), - aT2, BRep_Tool::Pnt(aV2), BRep_Tool::Tolerance(aV2), + aT1, BRep_Tool::Pnt(aV1), Max (aTolR3D, BRep_Tool::Tolerance(aV1)), + aT2, BRep_Tool::Pnt(aV2), Max (aTolR3D, BRep_Tool::Tolerance(aV2)), aFirst, aLast)) { // If the pave block does not have valid range, i.e. it is completely @@ -3035,28 +3035,29 @@ return; } - if (aDistVP > aTolV) - { - Standard_Integer nVn = UpdateVertex(nV, aDistVP + BOPTools_AlgoTools::DTolerance()); - if (nVn != nV) - { - aPave.SetIndex(nVn); - nV = nVn; - } - aTolV = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV))); - } - // Check if there will be valid range on the curve Standard_Real aFirst, aLast; + Standard_Real aNewTolV = Max(aTolV, aDistVP + BOPTools_AlgoTools::DTolerance()); if (!BRepLib::FindValidRange(GeomAdaptor_Curve(aIC.Curve()), aIC.Tolerance(), - aT[0], aP[0], aTolV, - aT[1], aP[1], aTolV, + aT[0], aP[0], aNewTolV, + aT[1], aP[1], aNewTolV, aFirst, aLast)) { // No valid range return; } + if (aNewTolV > aTolV) + { + Standard_Integer nVn = UpdateVertex(nV, aNewTolV); + if (nVn != nV) + { + aPave.SetIndex(nVn); + nV = nVn; + } + aTolV = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV))); + } + // Add closing pave to the curve BOPDS_Pave aNewPave; aNewPave.SetIndex(nV); diff -Nru opencascade-7.5.1+dfsg1/src/BRepFill/BRepFill_Sweep.cxx opencascade-7.5.2+dfsg1/src/BRepFill/BRepFill_Sweep.cxx --- opencascade-7.5.1+dfsg1/src/BRepFill/BRepFill_Sweep.cxx 2021-02-02 08:51:56.000000000 +0000 +++ opencascade-7.5.2+dfsg1/src/BRepFill/BRepFill_Sweep.cxx 2021-04-20 07:07:58.000000000 +0000 @@ -2969,13 +2969,25 @@ // Construction of the shell TopoDS_Shell shell; B.MakeShell(shell); + Standard_Integer aNbFaces = 0; for (ipath=1; ipath<=NbPath; ipath++) - for (isec=1; isec <=NbLaw; isec++) { - const TopoDS_Shape& face = myFaces->Value(isec, ipath); + for (isec=1; isec <=NbLaw; isec++) + { + const TopoDS_Shape& face = myFaces->Value(isec, ipath); if (!face.IsNull() && - (face.ShapeType() == TopAbs_FACE) ) B.Add(shell, face); + (face.ShapeType() == TopAbs_FACE) ) + { + B.Add(shell, face); + aNbFaces++; + } } + if (aNbFaces == 0) + { + isDone = Standard_False; + return; + } + TopTools_ListIteratorOfListOfShape It(myAuxShape); for (; It.More(); It.Next()) { const TopoDS_Shape& face = It.Value(); diff -Nru opencascade-7.5.1+dfsg1/src/Extrema/Extrema_FuncExtCS.hxx opencascade-7.5.2+dfsg1/src/Extrema/Extrema_FuncExtCS.hxx --- opencascade-7.5.1+dfsg1/src/Extrema/Extrema_FuncExtCS.hxx 2021-02-02 08:51:56.000000000 +0000 +++ opencascade-7.5.2+dfsg1/src/Extrema/Extrema_FuncExtCS.hxx 2021-04-20 07:07:58.000000000 +0000 @@ -84,14 +84,21 @@ //! Return the Nth extremum on S. Standard_EXPORT const Extrema_POnSurf& PointOnSurface (const Standard_Integer N) const; - - - -protected: - - - - + //! Change Sequence of SquareDistance + TColStd_SequenceOfReal& SquareDistances() + { + return mySqDist; + } + //! Change Sequence of PointOnCurv + Extrema_SequenceOfPOnCurv& PointsOnCurve() + { + return myPoint1; + } + //! Change Sequence of PointOnSurf + Extrema_SequenceOfPOnSurf& PointsOnSurf() + { + return myPoint2; + } private: diff -Nru opencascade-7.5.1+dfsg1/src/Extrema/Extrema_GenExtCS.cxx opencascade-7.5.2+dfsg1/src/Extrema/Extrema_GenExtCS.cxx --- opencascade-7.5.1+dfsg1/src/Extrema/Extrema_GenExtCS.cxx 2021-02-02 08:51:56.000000000 +0000 +++ opencascade-7.5.2+dfsg1/src/Extrema/Extrema_GenExtCS.cxx 2021-04-20 07:07:58.000000000 +0000 @@ -306,33 +306,83 @@ Tol(2) = mytol2; Tol(3) = mytol2; // - TUVinf(1) = mytmin; - TUVinf(2) = trimumin; - TUVinf(3) = trimvmin; - // - TUVsup(1) = mytsup; - TUVsup(2) = trimusup; - TUVsup(3) = trimvsup; - // // Number of particles used in PSO algorithm (particle swarm optimization). const Standard_Integer aNbParticles = 48; - // - if (aNbVar == 3) + + Standard_Integer aNbIntC = 1; + if (C.IsClosed() || C.IsPeriodic()) { - GlobMinGenCS(C, aNbParticles, TUVinf, TUVsup, TUV); + Standard_Real aPeriod = C.Period(); + if (C.LastParameter() - C.FirstParameter() > 2. * aPeriod / 3.) + { + aNbIntC = 2; + } } - else if (aNbVar == 2) + + Standard_Integer anInt; + Standard_Real dT = (mytsup - mytmin) / aNbIntC; + for (anInt = 1; anInt <= aNbIntC; anInt++) { - GlobMinConicS(C, aNbParticles, TUVinf, TUVsup, TUV); + TUVinf(1) = mytmin + (anInt - 1) * dT; + TUVinf(2) = trimumin; + TUVinf(3) = trimvmin; + // + TUVsup(1) = TUVinf(1) + dT; // mytsup; + TUVsup(2) = trimusup; + TUVsup(3) = trimvsup; + // + if (aNbVar == 3) + { + GlobMinGenCS(C, aNbParticles, TUVinf, TUVsup, TUV); + } + else if (aNbVar == 2) + { + GlobMinConicS(C, aNbParticles, TUVinf, TUVsup, TUV); + } + else + { + GlobMinCQuadric(C, aNbParticles, TUVinf, TUVsup, TUV); + } + + // Find min approximation + math_FunctionSetRoot anA(myF, Tol); + anA.Perform(myF, TUV, TUVinf, TUVsup); } - else + if (aNbIntC > 1 && myF.NbExt() > 1) { - GlobMinCQuadric(C, aNbParticles, TUVinf, TUVsup, TUV); - } + //Try to remove "false" extrema caused by dividing curve interval + TColStd_SequenceOfReal& aSqDists = myF.SquareDistances(); + Extrema_SequenceOfPOnCurv& aPntsOnCrv = myF.PointsOnCurve(); + Extrema_SequenceOfPOnSurf& aPntsOnSurf = myF.PointsOnSurf(); + TColStd_SequenceOfReal aSqDists1(aSqDists); + Extrema_SequenceOfPOnCurv aPntsOnCrv1(aPntsOnCrv); + Extrema_SequenceOfPOnSurf aPntsOnSurf1(aPntsOnSurf); - // Find min approximation - math_FunctionSetRoot anA(myF, Tol); - anA.Perform(myF, TUV, TUVinf, TUVsup); + Standard_Real aMinDist = aSqDists(1); + Standard_Integer i; + for (i = 2; i <= aSqDists.Length(); ++i) + { + Standard_Real aDist = aSqDists(i); + if (aDist < aMinDist) + { + aMinDist = aDist; + } + } + aSqDists.Clear(); + aPntsOnCrv.Clear(); + aPntsOnSurf.Clear(); + Standard_Real aTol = Precision::SquareConfusion(); + for (i = 1; i <= aSqDists1.Length(); ++i) + { + Standard_Real aDist = aSqDists1(i); + if (Abs(aDist - aMinDist) <= aTol) + { + aSqDists.Append(aDist); + aPntsOnCrv.Append(aPntsOnCrv1(i)); + aPntsOnSurf.Append(aPntsOnSurf1(i)); + } + } + } myDone = Standard_True; } diff -Nru opencascade-7.5.1+dfsg1/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx opencascade-7.5.2+dfsg1/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx --- opencascade-7.5.1+dfsg1/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx 2021-02-02 08:51:56.000000000 +0000 +++ opencascade-7.5.2+dfsg1/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx 2021-04-20 07:07:58.000000000 +0000 @@ -29,6 +29,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -67,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -96,11 +100,10 @@ IMPLEMENT_STANDARD_RTTIEXT(ShapeUpgrade_UnifySameDomain,Standard_Transient) -struct SubSequenceOfEdges -{ - TopTools_SequenceOfShape SeqsEdges; - TopoDS_Edge UnionEdges; -}; +static void SplitWire (const TopoDS_Wire& theWire, + const TopoDS_Face& theFace, + const TopTools_IndexedMapOfShape& theVmap, + TopTools_SequenceOfShape& theWireSeq); static Standard_Real TrueValueOfOffset(const Standard_Real theValue, const Standard_Real thePeriod) @@ -135,6 +138,40 @@ } } +static Standard_Boolean TryMakeLine(const Handle(Geom2d_Curve)& thePCurve, + const Standard_Real theFirst, + const Standard_Real theLast, + Handle(Geom2d_Line)& theLine) +{ + gp_Pnt2d aFirstPnt = thePCurve->Value (theFirst); + gp_Pnt2d aLastPnt = thePCurve->Value (theLast); + gp_Vec2d aVec (aFirstPnt, aLastPnt); + Standard_Real aSqLen = aVec.SquareMagnitude(); + Standard_Real aSqParamLen = (theLast - theFirst)*(theLast - theFirst); + if (Abs(aSqLen - aSqParamLen) > Precision::Confusion()) + return Standard_False; + + gp_Dir2d aDir = aVec; + gp_Vec2d anOffset = -aDir; + anOffset *= theFirst; + gp_Pnt2d anOrigin = aFirstPnt.Translated(anOffset); + gp_Lin2d aLin (anOrigin, aDir); + + const Standard_Integer NbSamples = 10; + Standard_Real aDelta = (theLast - theFirst)/NbSamples; + for (Standard_Integer i = 1; i < NbSamples; i++) + { + Standard_Real aParam = theFirst + i*aDelta; + gp_Pnt2d aPnt = thePCurve->Value(aParam); + Standard_Real aDist = aLin.Distance (aPnt); + if (aDist > Precision::Confusion()) + return Standard_False; + } + + theLine = new Geom2d_Line (aLin); + return Standard_True; +} + static void RemoveEdgeFromMap(const TopoDS_Edge& theEdge, TopTools_IndexedDataMapOfShapeListOfShape& theVEmap) { @@ -1445,17 +1482,329 @@ } //======================================================================= +//function : UnionPCurves +//purpose : +//======================================================================= + +void ShapeUpgrade_UnifySameDomain::UnionPCurves(const TopTools_SequenceOfShape& theChain, + TopoDS_Edge& theEdge) +{ + TopTools_SequenceOfShape aFaceSeq; + + const TopoDS_Edge& aFirstEdge = TopoDS::Edge(theChain.Value(1)); + const TopTools_ListOfShape& aFaceList = myEFmap.FindFromKey (aFirstEdge); + TopTools_ListIteratorOfListOfShape anItl (aFaceList); + for (; anItl.More(); anItl.Next()) + { + TopoDS_Face aFace = TopoDS::Face (anItl.Value()); + if (myFacePlaneMap.IsBound(aFace)) + continue; + + if (myFaceNewFace.IsBound(aFace)) + aFace = TopoDS::Face (myFaceNewFace(aFace)); + + BRepAdaptor_Surface aBAsurf (aFace, Standard_False); + if (aBAsurf.GetType() == GeomAbs_Plane) + continue; + + TopLoc_Location aLoc; + Handle(Geom_Surface) aSurf = BRep_Tool::Surface (aFace, aLoc); + Standard_Boolean isFound = Standard_False; + for (Standard_Integer ii = 1; ii <= aFaceSeq.Length(); ii++) + { + TopLoc_Location aPrevLoc; + Handle(Geom_Surface) aPrevSurf = BRep_Tool::Surface (TopoDS::Face(aFaceSeq(ii)), aPrevLoc); + if (aPrevSurf == aSurf && aPrevLoc == aLoc) + { + isFound = Standard_True; + break; + } + } + if (isFound) + continue; + + Standard_Real aFirst, aLast; + Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface (aFirstEdge, aFace, aFirst, aLast); + + aFaceSeq.Append (aFace); + } + + TColGeom2d_SequenceOfCurve ResPCurves; + TColStd_SequenceOfReal ResFirsts; + TColStd_SequenceOfReal ResLasts; + TColStd_SequenceOfReal aTolVerSeq; + TopoDS_Edge aPrevEdge; + + for (Standard_Integer j = 1; j <= aFaceSeq.Length(); j++) + { + TColGeom2d_SequenceOfCurve aPCurveSeq; + TColStd_SequenceOfReal aFirstsSeq; + TColStd_SequenceOfReal aLastsSeq; + TColStd_SequenceOfBoolean aForwardsSeq; + GeomAbs_CurveType aCurrentType = GeomAbs_OtherCurve; + + Standard_Real aFirst, aLast; + for (Standard_Integer i = 1; i <= theChain.Length(); i++) + { + TopoDS_Edge anEdge = TopoDS::Edge(theChain.Value(i)); + Standard_Boolean isForward = (anEdge.Orientation() != TopAbs_REVERSED); + + Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(anEdge, TopoDS::Face(aFaceSeq(j)), + aFirst, aLast); + if (aPCurve.IsNull()) + continue; + + Geom2dAdaptor_Curve anAdaptor(aPCurve); + GeomAbs_CurveType aType = anAdaptor.GetType(); + + Handle(Geom2d_Line) aLine; + if (aType == GeomAbs_BSplineCurve || + aType == GeomAbs_BezierCurve) + TryMakeLine (aPCurve, aFirst, aLast, aLine); + if (!aLine.IsNull()) + { + aPCurve = aLine; + anAdaptor.Load (aPCurve); + aType = GeomAbs_Line; + } + + if (aPCurveSeq.IsEmpty()) { + Handle(Geom2d_Curve) aCopyPCurve = Handle(Geom2d_Curve)::DownCast(aPCurve->Copy()); + aPCurveSeq.Append(aCopyPCurve); + aFirstsSeq.Append(aFirst); + aLastsSeq.Append(aLast); + aForwardsSeq.Append(isForward); + aCurrentType = aType; + aPrevEdge = anEdge; + continue; + } + + Standard_Boolean isSameCurve = Standard_False; + Standard_Real aNewF = aFirst; + Standard_Real aNewL = aLast; + if (aPCurve == aPCurveSeq.Last()) + { + isSameCurve = Standard_True; + } + else if (aType == aCurrentType) + { + Geom2dAdaptor_Curve aPrevAdaptor(aPCurveSeq.Last()); + switch (aType) { + case GeomAbs_Line: { + gp_Lin2d aPrevLin = aPrevAdaptor.Line(); + gp_Pnt2d aFirstP2d = aPCurve->Value (aFirst); + gp_Pnt2d aLastP2d = aPCurve->Value (aLast); + if (aPrevLin.Contains (aFirstP2d, Precision::Confusion()) && + aPrevLin.Contains (aLastP2d, Precision::Confusion())) + { + isSameCurve = Standard_True; + gp_Pnt2d p1 = anAdaptor.Value(aFirst); + gp_Pnt2d p2 = anAdaptor.Value(aLast); + aNewF = ElCLib::Parameter(aPrevLin, p1); + aNewL = ElCLib::Parameter(aPrevLin, p2); + if (aNewF > aNewL) + { + Standard_Real aTmp = aNewF; + aNewF = aNewL; + aNewL = aTmp; + } + } + break; + } + case GeomAbs_Circle: { + gp_Circ2d aCirc = anAdaptor.Circle(); + gp_Circ2d aPrevCirc = aPrevAdaptor.Circle(); + if (aCirc.Location().Distance(aPrevCirc.Location()) <= Precision::Confusion() && + Abs(aCirc.Radius() - aPrevCirc.Radius()) <= Precision::Confusion()) + { + isSameCurve = Standard_True; + gp_Pnt2d p1 = anAdaptor.Value(aFirst); + gp_Pnt2d p2 = anAdaptor.Value(aLast); + aNewF = ElCLib::Parameter(aPrevCirc, p1); + aNewL = ElCLib::Parameter(aPrevCirc, p2); + if (aNewF > aNewL) + { + Standard_Real aTmp = aNewF; + aNewF = aNewL; + aNewL = aTmp; + } + } + break; + } + default: + break; + } + } + if (isSameCurve) { + if (aForwardsSeq.Last() == Standard_True) + aLastsSeq.ChangeLast() = aNewL; + else + aFirstsSeq.ChangeLast() = aNewF; + } + else + { + Handle(Geom2d_Curve) aCopyPCurve = Handle(Geom2d_Curve)::DownCast(aPCurve->Copy()); + aPCurveSeq.Append(aCopyPCurve); + aFirstsSeq.Append(aFirst); + aLastsSeq.Append(aLast); + aForwardsSeq.Append(isForward); + aCurrentType = aType; + TopoDS_Vertex aV; + TopExp::CommonVertex(aPrevEdge, anEdge, aV); + Standard_Real aTol = BRep_Tool::Tolerance(aV); + aTolVerSeq.Append (aTol); + } + aPrevEdge = anEdge; + } + + Handle(Geom2d_Curve) aResPCurve; + Standard_Real aResFirst, aResLast; + if (aPCurveSeq.Length() == 1) { + aResPCurve = aPCurveSeq.Last(); + aResFirst = aFirstsSeq.Last(); + aResLast = aLastsSeq.Last(); + if (aForwardsSeq.Last() == Standard_False) + { + Standard_Real aNewLast = aResPCurve->ReversedParameter (aResFirst); + Standard_Real aNewFirst = aResPCurve->ReversedParameter (aResLast); + aResPCurve->Reverse(); + aResFirst = aNewFirst; + aResLast = aNewLast; + } + } + else { + //C1 concatenation for PCurveSeq + TColGeom2d_Array1OfBSplineCurve tab_c2d(0, aPCurveSeq.Length() - 1); + for (Standard_Integer i = 1; i <= aPCurveSeq.Length(); i++) { + Handle(Geom2d_TrimmedCurve) aTrPCurve = new Geom2d_TrimmedCurve(aPCurveSeq(i), aFirstsSeq(i), aLastsSeq(i)); + if (aForwardsSeq(i) == Standard_False) + { + aTrPCurve->Reverse(); + } + tab_c2d(i - 1) = Geom2dConvert::CurveToBSplineCurve(aTrPCurve); + Geom2dConvert::C0BSplineToC1BSplineCurve(tab_c2d(i - 1), Precision::Confusion()); + } + + TColStd_Array1OfReal tabtolvertex(0, aTolVerSeq.Length() - 1); + Standard_Real aMaxTol = 0.0; + for (Standard_Integer i = 1; i <= aTolVerSeq.Length(); i++) + { + Standard_Real aTol = aTolVerSeq(i); + tabtolvertex(i - 1) = aTol; + if (aTol > aMaxTol) + aMaxTol = aTol; + } + + Handle(TColGeom2d_HArray1OfBSplineCurve) concatc2d; //array of the concatenated curves + Handle(TColStd_HArray1OfInteger) ArrayOfInd2d; //array of the remining Vertex + Standard_Boolean aClosedFlag = Standard_False; + Geom2dConvert::ConcatC1(tab_c2d, + tabtolvertex, + ArrayOfInd2d, + concatc2d, + aClosedFlag, + Precision::Confusion()); //C1 concatenation + + if (concatc2d->Length() > 1) + { + Geom2dConvert_CompCurveToBSplineCurve Concat2d(concatc2d->Value(concatc2d->Lower())); + + for (Standard_Integer i = concatc2d->Lower() + 1; i <= concatc2d->Upper(); i++) + Concat2d.Add(concatc2d->Value(i), aMaxTol, Standard_True); + + concatc2d->SetValue(concatc2d->Lower(), Concat2d.BSplineCurve()); + } + Handle(Geom2d_BSplineCurve) aBSplineCurve = concatc2d->Value(concatc2d->Lower()); + aResPCurve = aBSplineCurve; + aResFirst = aBSplineCurve->FirstParameter(); + aResLast = aBSplineCurve->LastParameter(); + } + ResPCurves.Append(aResPCurve); + ResFirsts.Append(aResFirst); + ResLasts.Append(aResLast); + } + + BRep_Builder aBuilder; + Standard_Real aTol = BRep_Tool::Tolerance(theEdge); + + //Reparametrize pcurves if needed + for (Standard_Integer ii = 2; ii <= ResPCurves.Length(); ii++) + { + if (Abs (ResFirsts(1) - ResFirsts(ii)) > Precision::Confusion() || + Abs (ResLasts(1) - ResLasts(ii)) > Precision::Confusion()) + { + Handle(Geom2d_TrimmedCurve) aTrPCurve = + new Geom2d_TrimmedCurve (ResPCurves(ii), ResFirsts(ii), ResLasts(ii)); + Handle(Geom2d_BSplineCurve) aBSplinePCurve = Geom2dConvert::CurveToBSplineCurve(aTrPCurve); + TColStd_Array1OfReal aKnots (1, aBSplinePCurve->NbKnots()); + aBSplinePCurve->Knots (aKnots); + BSplCLib::Reparametrize (ResFirsts(1), ResLasts(1), aKnots); + aBSplinePCurve->SetKnots (aKnots); + ResPCurves(ii) = aBSplinePCurve; + } + } + + //Reparametrize 3d curve if needed + if (!ResPCurves.IsEmpty()) + { + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve (theEdge, aFirst, aLast); + if (Abs (aFirst - ResFirsts(1)) > Precision::Confusion() || + Abs (aLast - ResLasts(1)) > Precision::Confusion()) + { + GeomAdaptor_Curve aGAcurve (aCurve); + GeomAbs_CurveType aType = aGAcurve.GetType(); + if (aType == GeomAbs_Line) + { + gp_Lin aLin = aGAcurve.Line(); + gp_Dir aDir = aLin.Direction(); + gp_Pnt aPnt = aGAcurve.Value (aFirst); + gp_Vec anOffset = -aDir; + anOffset *= ResFirsts(1); + aPnt.Translate (anOffset); + Handle(Geom_Line) aLine = new Geom_Line (aPnt, aDir); + aBuilder.UpdateEdge (theEdge, aLine, aTol); + } + else if (aType == GeomAbs_Circle) + { + gp_Circ aCirc = aGAcurve.Circle(); + Standard_Real aRadius = aCirc.Radius(); + gp_Ax2 aPosition = aCirc.Position(); + gp_Ax1 anAxis = aPosition.Axis(); + Standard_Real anOffset = aFirst - ResFirsts(1); + aPosition.Rotate (anAxis, anOffset); + Handle(Geom_Circle) aCircle = new Geom_Circle (aPosition, aRadius); + aBuilder.UpdateEdge (theEdge, aCircle, aTol); + } + else //general case + { + Handle(Geom_TrimmedCurve) aTrCurve = + new Geom_TrimmedCurve (aCurve, aFirst, aLast); + Handle(Geom_BSplineCurve) aBSplineCurve = GeomConvert::CurveToBSplineCurve(aTrCurve); + TColStd_Array1OfReal aKnots (1, aBSplineCurve->NbKnots()); + aBSplineCurve->Knots (aKnots); + BSplCLib::Reparametrize (ResFirsts(1), ResLasts(1), aKnots); + aBSplineCurve->SetKnots (aKnots); + aBuilder.UpdateEdge (theEdge, aBSplineCurve, aTol); + } + } + aBuilder.Range(theEdge, ResFirsts(1), ResLasts(1)); + } + + for (Standard_Integer j = 1; j <= ResPCurves.Length(); j++) + { + aBuilder.UpdateEdge(theEdge, ResPCurves(j), TopoDS::Face(aFaceSeq(j)), aTol); + } +} + +//======================================================================= //function : MergeSubSeq //purpose : Merges a sequence of edges into one edge if possible //======================================================================= -static Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& theChain, - const TopTools_IndexedDataMapOfShapeListOfShape& theVFmap, - TopoDS_Edge& OutEdge, - double theAngTol, - Standard_Boolean ConcatBSplines, - Standard_Boolean isSafeInputMode, - Handle(ShapeBuild_ReShape)& theContext) +Standard_Boolean ShapeUpgrade_UnifySameDomain::MergeSubSeq(const TopTools_SequenceOfShape& theChain, + const TopTools_IndexedDataMapOfShapeListOfShape& theVFmap, + TopoDS_Edge& OutEdge) { ShapeAnalysis_Edge sae; BRep_Builder B; @@ -1521,12 +1870,12 @@ if(c3d1.IsNull() || c3d2.IsNull()) return Standard_False; - while(c3d1->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { + if (c3d1->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(c3d1); c3d1 = tc->BasisCurve(); } - while(c3d2->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { + if (c3d2->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(c3d2); c3d2 = tc->BasisCurve(); @@ -1536,7 +1885,7 @@ Handle(Geom_Line) L2 = Handle(Geom_Line)::DownCast(c3d2); gp_Dir Dir1 = L1->Position().Direction(); gp_Dir Dir2 = L2->Position().Direction(); - if(!Dir1.IsParallel(Dir2,theAngTol)) + if (!Dir1.IsParallel (Dir2, myAngTol)) IsUnionOfLinesPossible = Standard_False; } else @@ -1564,15 +1913,15 @@ V[1] = sae.LastVertex(TopoDS::Edge(theChain.Last())); gp_Pnt PV2 = BRep_Tool::Pnt(V[1]); gp_Vec Vec(PV1, PV2); - if (isSafeInputMode) { + if (mySafeInputMode) { for (int k = 0; k < 2; k++) { - if (!theContext->IsRecorded(V[k])) { + if (!myContext->IsRecorded(V[k])) { TopoDS_Vertex Vcopy = TopoDS::Vertex(V[k].EmptyCopied()); - theContext->Replace(V[k], Vcopy); + myContext->Replace(V[k], Vcopy); V[k] = Vcopy; } else - V[k] = TopoDS::Vertex(theContext->Apply(V[k])); + V[k] = TopoDS::Vertex (myContext->Apply(V[k])); } } Handle(Geom_Line) L = new Geom_Line(gp_Ax1(PV1,Vec)); @@ -1583,6 +1932,7 @@ B.Add (E,V[0]); B.Add (E,V[1]); B.UpdateVertex(V[0], 0., E, 0.); B.UpdateVertex(V[1], dist, E, 0.); + UnionPCurves(theChain, E); OutEdge = E; return Standard_True; } @@ -1593,7 +1943,7 @@ TopoDS_Edge FE = TopoDS::Edge(theChain.First()); Handle(Geom_Curve) c3d = BRep_Tool::Curve(FE,f,l); - while(c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { + if (c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(c3d); c3d = tc->BasisCurve(); @@ -1638,55 +1988,53 @@ B.Add(E,V[1]); } } - else { - if (isSafeInputMode) { + else //open chain + { + Standard_Real ParamFirst = BRep_Tool::Parameter(V[0], FE); + TopoDS_Vertex VertexLastOnFE = sae.LastVertex(FE); + Standard_Real ParamLast = BRep_Tool::Parameter(VertexLastOnFE, FE); + + if (mySafeInputMode) { for (int k = 0; k < 2; k++) { - if (!theContext->IsRecorded(V[k])) { + if (!myContext->IsRecorded(V[k])) { TopoDS_Vertex Vcopy = TopoDS::Vertex(V[k].EmptyCopied()); - theContext->Replace(V[k], Vcopy); + myContext->Replace(V[k], Vcopy); V[k] = Vcopy; } else - V[k] = TopoDS::Vertex(theContext->Apply(V[k])); + V[k] = TopoDS::Vertex (myContext->Apply(V[k])); } } - gp_Pnt PV1 = BRep_Tool::Pnt(V[0]); - gp_Pnt PV2 = BRep_Tool::Pnt(V[1]); - TopoDS_Vertex VM = sae.LastVertex(FE); - gp_Pnt PVM = BRep_Tool::Pnt(VM); - GC_MakeCircle MC (PV1,PVM,PV2); - Handle(Geom_Circle) C = MC.Value(); - gp_Pnt P0 = C->Location(); - gp_Dir D1(gp_Vec(P0,PV1)); - gp_Dir D2(gp_Vec(P0,PV2)); - Standard_Real fpar = C->XAxis().Direction().Angle(D1); - if(fabs(fpar)>Precision::Confusion()) { - // check orientation - gp_Dir ND = C->XAxis().Direction().Crossed(D1); - if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) { - fpar = -fpar; - } - } - Standard_Real lpar = C->XAxis().Direction().Angle(D2); - if(fabs(lpar)>Precision::Confusion()) { - // check orientation - gp_Dir ND = C->XAxis().Direction().Crossed(D2); - if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) { - lpar = -lpar; - } - } - if (lpar < fpar) lpar += 2*M_PI; - Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(C,fpar,lpar); + + gp_Pnt PointFirst = BRep_Tool::Pnt(V[0]); + while (Abs(ParamLast - ParamFirst) > 7*M_PI/8) + ParamLast = (ParamFirst + ParamLast)/2; + BRepAdaptor_Curve BAcurveFE(FE); + gp_Pnt PointLast = BAcurveFE.Value(ParamLast); + gp_Pnt Origin = Cir->Circ().Location(); + gp_Dir Dir1 = gp_Vec(Origin, PointFirst); + gp_Dir Dir2 = gp_Vec(Origin, PointLast); + gp_Dir Vdir = Dir1 ^ Dir2; + gp_Ax2 anAx2(Origin, Vdir, Dir1); + Handle(Geom_Circle) aNewCircle = new Geom_Circle(anAx2, Cir->Radius()); + gp_Pnt PointLastInChain = BRep_Tool::Pnt(V[1]); + gp_Dir DirLastInChain = gp_Vec(Origin, PointLastInChain); + Standard_Real lpar = Dir1.AngleWithRef(DirLastInChain, Vdir); + if (lpar < 0.) + lpar += 2*M_PI; + + Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(aNewCircle,0.,lpar); B.MakeEdge (E,tc,Precision::Confusion()); B.Add(E,V[0]); B.Add(E,V[1]); - B.UpdateVertex(V[0], fpar, E, 0.); + B.UpdateVertex(V[0], 0., E, 0.); B.UpdateVertex(V[1], lpar, E, 0.); } + UnionPCurves(theChain, E); OutEdge = E; return Standard_True; } - if (theChain.Length() > 1 && ConcatBSplines) { + if (theChain.Length() > 1 && myConcatBSplines) { // second step: union edges with various curves // skl for bug 0020052 from Mantis: perform such unions // only if curves are bspline or bezier @@ -1699,7 +2047,7 @@ TopLoc_Location Loc; Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge,Loc,fp1,lp1); if(c3d.IsNull()) continue; - while(c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { + if (c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(c3d); c3d = tc->BasisCurve(); @@ -1912,15 +2260,10 @@ //function : MergeEdges //purpose : auxilary //======================================================================= -static Standard_Boolean MergeEdges(TopTools_SequenceOfShape& SeqEdges, - const TopTools_IndexedDataMapOfShapeListOfShape& theVFmap, - const Standard_Real theAngTol, - const Standard_Real theLinTol, - const Standard_Boolean ConcatBSplines, - const Standard_Boolean isSafeInputMode, - Handle(ShapeBuild_ReShape)& theContext, - NCollection_Sequence& SeqOfSubSeqOfEdges, - const TopTools_MapOfShape& NonMergVrt) +Standard_Boolean ShapeUpgrade_UnifySameDomain::MergeEdges(TopTools_SequenceOfShape& SeqEdges, + const TopTools_IndexedDataMapOfShapeListOfShape& theVFmap, + NCollection_Sequence& SeqOfSubSeqOfEdges, + const TopTools_MapOfShape& NonMergVrt) { TopTools_IndexedDataMapOfShapeListOfShape aMapVE; Standard_Integer j; @@ -2001,7 +2344,7 @@ // split chain by vertices at which merging is not possible NCollection_Sequence aOneSeq; - GenerateSubSeq(aChain, aOneSeq, IsClosed, theAngTol, theLinTol, VerticesToAvoid, theVFmap); + GenerateSubSeq(aChain, aOneSeq, IsClosed, myAngTol, myLinTol, VerticesToAvoid, theVFmap); // put sub-chains in the result SeqOfSubSeqOfEdges.Append(aOneSeq); @@ -2012,9 +2355,7 @@ TopoDS_Edge UE; if (SeqOfSubSeqOfEdges(i).SeqsEdges.Length() < 2) continue; - if (MergeSubSeq(SeqOfSubSeqOfEdges(i).SeqsEdges, theVFmap, - UE, theAngTol, - ConcatBSplines, isSafeInputMode, theContext)) + if (MergeSubSeq(SeqOfSubSeqOfEdges(i).SeqsEdges, theVFmap, UE)) SeqOfSubSeqOfEdges(i).UnionEdges = UE; } return Standard_True; @@ -2025,25 +2366,19 @@ //purpose : Tries to unify the sequence of edges with the set of // another edges which lies on the same geometry //======================================================================= -static Standard_Boolean MergeSeq (TopTools_SequenceOfShape& SeqEdges, - const TopTools_IndexedDataMapOfShapeListOfShape& theVFmap, - const Standard_Real theAngTol, - const Standard_Real theLinTol, - const Standard_Boolean ConcatBSplines, - const Standard_Boolean isSafeInputMode, - Handle(ShapeBuild_ReShape)& theContext, - const TopTools_MapOfShape& nonMergVert) +Standard_Boolean ShapeUpgrade_UnifySameDomain::MergeSeq (TopTools_SequenceOfShape& SeqEdges, + const TopTools_IndexedDataMapOfShapeListOfShape& theVFmap, + const TopTools_MapOfShape& nonMergVert) { NCollection_Sequence SeqOfSubsSeqOfEdges; - if (MergeEdges(SeqEdges, theVFmap, theAngTol, theLinTol, ConcatBSplines, isSafeInputMode, - theContext, SeqOfSubsSeqOfEdges, nonMergVert)) + if (MergeEdges(SeqEdges, theVFmap, SeqOfSubsSeqOfEdges, nonMergVert)) { for (Standard_Integer i = 1; i <= SeqOfSubsSeqOfEdges.Length(); i++ ) { if (SeqOfSubsSeqOfEdges(i).UnionEdges.IsNull()) continue; - theContext->Merge(SeqOfSubsSeqOfEdges(i).SeqsEdges, + myContext->Merge(SeqOfSubsSeqOfEdges(i).SeqsEdges, SeqOfSubsSeqOfEdges(i).UnionEdges); } return Standard_True; @@ -2143,6 +2478,8 @@ myContext->Clear(); myKeepShapes.Clear(); myFacePlaneMap.Clear(); + myEFmap.Clear(); + myFaceNewFace.Clear(); myHistory->Clear(); } @@ -2680,6 +3017,7 @@ BB.MakeWire(aNewWire); BB.Add(aNewWire, StartEdge); RemoveEdgeFromMap(StartEdge, VEmap); + TopTools_IndexedMapOfShape SplittingVertices; Standard_Real fpar, lpar; Handle(Geom2d_Curve) StartPCurve = BRep_Tool::CurveOnSurface(StartEdge, F_RefFace, fpar, lpar); @@ -2761,6 +3099,7 @@ else { //we must choose the closest direction - the biggest angle + SplittingVertices.Add (CurVertex); Standard_Real MaxAngle = RealFirst(); TopoDS_Edge TrueEdge; Handle(Geom2d_Curve) CurPCurve = BRep_Tool::CurveOnSurface(CurEdge, F_RefFace, fpar, lpar); @@ -2910,7 +3249,11 @@ } else //may be this wire is a hole { - NewWires.Append(aNewWire); + //split this wire if needed + if (!SplittingVertices.IsEmpty()) + SplitWire (aNewWire, F_RefFace, SplittingVertices, NewWires); + else + NewWires.Append(aNewWire); } } //while (!edges.IsEmpty()) @@ -2974,6 +3317,9 @@ BB.Add(aResult, InternalWires(ii)); aResult.Orientation(RefFaceOrientation); myContext->Merge(faces, aResult); + //Update the map Face-NewFace + for (Standard_Integer jj = 1; jj <= faces.Length(); jj++) + myFaceNewFace.Bind (faces(jj), aResult); } else if (NewFaces.Length() == 1) { @@ -2983,6 +3329,9 @@ for (Standard_Integer ii = 1; ii <= InternalWires.Length(); ii++) BB.Add(aNewFace, InternalWires(ii)); myContext->Merge(faces, NewFaces(1)); + //Update the map Face-NewFace + for (Standard_Integer jj = 1; jj <= faces.Length(); jj++) + myFaceNewFace.Bind (faces(jj), NewFaces(1)); } else { @@ -3016,6 +3365,9 @@ facesForThisFace.Append(faces(jj)); } myContext->Merge(facesForThisFace, NewFaces(ii)); + //Update the map Face-NewFace + for (Standard_Integer jj = 1; jj <= facesForThisFace.Length(); jj++) + myFaceNewFace.Bind (facesForThisFace(jj), NewFaces(ii)); } } } //if (faces.Length() > 1) @@ -3052,8 +3404,7 @@ TopTools_MapOfShape aSharedVert; CheckSharedVertices(aSeqEdges, aMapEdgesVertex, myKeepShapes, aSharedVert); // Merge the edges avoiding removal of the shared vertices - Standard_Boolean isMerged = MergeSeq(aSeqEdges, aVFmap, myAngTol, myLinTol, myConcatBSplines, - mySafeInputMode, myContext, aSharedVert); + Standard_Boolean isMerged = MergeSeq(aSeqEdges, aVFmap, aSharedVert); // Collect faces to rebuild TopTools_IndexedMapOfShape aChangedFaces; if (isMerged) @@ -3140,6 +3491,8 @@ //======================================================================= void ShapeUpgrade_UnifySameDomain::Build() { + TopExp::MapShapesAndAncestors(myInitShape, TopAbs_EDGE, TopAbs_FACE, myEFmap); + if (myUnifyFaces) UnifyFaces(); if (myUnifyEdges) @@ -3233,3 +3586,112 @@ // Merge the history of the operation into global history myHistory->Merge(aUSDHistory); } + +void SplitWire (const TopoDS_Wire& theWire, + const TopoDS_Face& theFace, + const TopTools_IndexedMapOfShape& theVmap, + TopTools_SequenceOfShape& theWireSeq) +{ + TopTools_DataMapOfShapeListOfShape aVEmap; + + TopTools_MapOfShape aEmap; + TopoDS_Iterator itw (theWire); + for (; itw.More(); itw.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge (itw.Value()); + if (!aEmap.Add (anEdge)) + continue; + if (anEdge.Orientation() != TopAbs_FORWARD && + anEdge.Orientation() != TopAbs_REVERSED) + continue; + + const TopoDS_Vertex& aVertex = TopExp::FirstVertex (anEdge, Standard_True); //with orientation + if (aVEmap.IsBound (aVertex)) + aVEmap(aVertex).Append (anEdge); + else + { + TopTools_ListOfShape aElist; + aElist.Append (anEdge); + aVEmap.Bind (aVertex, aElist); + } + } + + BRep_Builder aBB; + for (Standard_Integer ii = 1; ii <= theVmap.Extent(); ii++) + { + const TopoDS_Vertex& anOrigin = TopoDS::Vertex (theVmap(ii)); + TopTools_ListOfShape& aBranches = aVEmap (anOrigin); + TopTools_ListIteratorOfListOfShape anItl (aBranches); + while (anItl.More()) + { + TopoDS_Edge CurEdge = TopoDS::Edge (anItl.Value()); + aBranches.Remove (anItl); + + TopoDS_Wire aNewWire; + aBB.MakeWire (aNewWire); + for (;;) + { + aBB.Add (aNewWire, CurEdge); + + const TopoDS_Vertex& aVertex = TopExp::LastVertex (CurEdge, Standard_True); //with orientation + if (aVertex.IsSame(anOrigin)) + break; + + if (!aVEmap.IsBound (aVertex)) + break; + + TopTools_ListOfShape& aElist = aVEmap (aVertex); + if (aElist.Extent() == 0) + break; + + if (aElist.Extent() == 1) + { + CurEdge = TopoDS::Edge (aElist.First()); + aElist.Clear(); + } + else + { + Standard_Real fpar, lpar; + Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(CurEdge, theFace, fpar, lpar); + Standard_Real aParam = (CurEdge.Orientation() == TopAbs_FORWARD)? lpar : fpar; + gp_Pnt2d aPoint; + gp_Vec2d CurDir; + aPCurve->D1(aParam, aPoint, CurDir); + CurDir.Normalize(); + if (CurEdge.Orientation() == TopAbs_REVERSED) + CurDir.Reverse(); + //choose the rightest direction - the smallest angle + Standard_Real MinAngle = RealLast(); + TopoDS_Edge NextEdge; + TopTools_ListIteratorOfListOfShape aLocalIter (aElist); + for (; aLocalIter.More(); aLocalIter.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge(aLocalIter.Value()); + aPCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, fpar, lpar); + aParam = (anEdge.Orientation() == TopAbs_FORWARD)? fpar : lpar; + gp_Vec2d aDir; + aPCurve->D1(aParam, aPoint, aDir); + aDir.Normalize(); + if (anEdge.Orientation() == TopAbs_REVERSED) + aDir.Reverse(); + Standard_Real anAngle = CurDir.Angle(aDir); + if (anAngle < MinAngle) + { + MinAngle = anAngle; + NextEdge = anEdge; + } + } + CurEdge = NextEdge; + //Remove from list + for (aLocalIter.Initialize(aElist); aLocalIter.More(); aLocalIter.Next()) + if (CurEdge.IsSame (aLocalIter.Value())) + { + aElist.Remove (aLocalIter); + break; + } + } //else (more than one edge) + } //for (;;) + theWireSeq.Append (aNewWire); + } //while (anItl.More()) + } +} diff -Nru opencascade-7.5.1+dfsg1/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.hxx opencascade-7.5.2+dfsg1/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.hxx --- opencascade-7.5.1+dfsg1/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.hxx 2021-02-02 08:51:56.000000000 +0000 +++ opencascade-7.5.2+dfsg1/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.hxx 2021-04-20 07:07:58.000000000 +0000 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include class ShapeBuild_ReShape; @@ -64,6 +65,13 @@ //! The algorithm provides a place holder for the history and collects the //! history by default. //! To avoid collecting of the history the place holder should be set to null handle. + +struct SubSequenceOfEdges +{ + TopTools_SequenceOfShape SeqsEdges; + TopoDS_Edge UnionEdges; +}; + class ShapeUpgrade_UnifySameDomain : public Standard_Transient { @@ -166,6 +174,27 @@ void IntUnifyFaces(const TopoDS_Shape& theInpShape, TopTools_IndexedDataMapOfShapeListOfShape& theGMapEdgeFaces); + //! Splits the sequence of edges into the sequence of chains + Standard_Boolean MergeEdges(TopTools_SequenceOfShape& SeqEdges, + const TopTools_IndexedDataMapOfShapeListOfShape& theVFmap, + NCollection_Sequence& SeqOfSubSeqOfEdges, + const TopTools_MapOfShape& NonMergVrt); + + //! Tries to unify the sequence of edges with the set of + //! another edges which lies on the same geometry + Standard_Boolean MergeSeq(TopTools_SequenceOfShape& SeqEdges, + const TopTools_IndexedDataMapOfShapeListOfShape& theVFmap, + const TopTools_MapOfShape& nonMergVert); + + //! Merges a sequence of edges into one edge if possible + Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& theChain, + const TopTools_IndexedDataMapOfShapeListOfShape& theVFmap, + TopoDS_Edge& OutEdge); + + //! Unifies the pcurve of the chain into one pcurve of the edge + void UnionPCurves(const TopTools_SequenceOfShape& theChain, + TopoDS_Edge& theEdge); + //! Fills the history of the modifications during the operation. Standard_EXPORT void FillHistory(); @@ -183,6 +212,8 @@ Handle(ShapeBuild_ReShape) myContext; TopTools_MapOfShape myKeepShapes; DataMapOfFacePlane myFacePlaneMap; + TopTools_IndexedDataMapOfShapeListOfShape myEFmap; + TopTools_DataMapOfShapeShape myFaceNewFace; Handle(BRepTools_History) myHistory; //!< The history. }; diff -Nru opencascade-7.5.1+dfsg1/src/Standard/Standard_Version.hxx opencascade-7.5.2+dfsg1/src/Standard/Standard_Version.hxx --- opencascade-7.5.1+dfsg1/src/Standard/Standard_Version.hxx 2021-02-02 08:51:56.000000000 +0000 +++ opencascade-7.5.2+dfsg1/src/Standard/Standard_Version.hxx 2021-04-20 07:07:58.000000000 +0000 @@ -35,7 +35,7 @@ // Primary definitions #define OCC_VERSION_MAJOR 7 #define OCC_VERSION_MINOR 5 -#define OCC_VERSION_MAINTENANCE 1 +#define OCC_VERSION_MAINTENANCE 2 //! This macro must be commented in official release, and set to non-empty //! string in other situations, to identify specifics of the version, e.g.: @@ -47,7 +47,7 @@ // Derived (manually): version as real and string (major.minor) #define OCC_VERSION 7.5 #define OCC_VERSION_STRING "7.5" -#define OCC_VERSION_COMPLETE "7.5.1" +#define OCC_VERSION_COMPLETE "7.5.2" //! Derived: extended version as string ("major.minor.maintenance.dev") #ifdef OCC_VERSION_DEVELOPMENT diff -Nru opencascade-7.5.1+dfsg1/src/TopoDSToStep/TopoDSToStep_MakeStepEdge.cxx opencascade-7.5.2+dfsg1/src/TopoDSToStep/TopoDSToStep_MakeStepEdge.cxx --- opencascade-7.5.1+dfsg1/src/TopoDSToStep/TopoDSToStep_MakeStepEdge.cxx 2021-02-02 08:51:56.000000000 +0000 +++ opencascade-7.5.2+dfsg1/src/TopoDSToStep/TopoDSToStep_MakeStepEdge.cxx 2021-04-20 07:07:58.000000000 +0000 @@ -186,9 +186,11 @@ Handle(StepGeom_Curve) Gpms; Handle(Geom_Curve) C = CA.Curve().Curve(); + if (!C.IsNull()) { C = Handle(Geom_Curve)::DownCast(C->Copy()); - + gp_Trsf Tr1 = CA.Trsf(); + C->Transform(Tr1); // Special treatment is needed for very short edges based on periodic curves. // Since edge in STEP does not store its parametric range, parameters are computed // on import by projecting vertices on a curve, and for periodic curve this may @@ -246,8 +248,7 @@ } } - gp_Trsf Tr1 = CA.Trsf(); - C->Transform(Tr1); + GeomToStep_MakeCurve MkCurve(C); Gpms = MkCurve.Value(); } diff -Nru opencascade-7.5.1+dfsg1/tests/boolean/removefeatures/A1 opencascade-7.5.2+dfsg1/tests/boolean/removefeatures/A1 --- opencascade-7.5.1+dfsg1/tests/boolean/removefeatures/A1 2021-02-02 08:51:56.000000000 +0000 +++ opencascade-7.5.2+dfsg1/tests/boolean/removefeatures/A1 2021-04-20 07:07:58.000000000 +0000 @@ -32,7 +32,7 @@ removefeatures res5 s feature4 checkshape res5 -checkprops res5 -s 2387.67 -v 1060.67 -deps 1.e-7 +checkprops res5 -s 2387.67 -v 1060.68 -deps 1.e-7 checknbshapes res5 -vertex 67 -edge 100 -wire 35 -face 35 -shell 1 -solid 1 -t CheckIsFeatureRemoved feature4 {v e f} diff -Nru opencascade-7.5.1+dfsg1/tests/boolean/removefeatures/A8 opencascade-7.5.2+dfsg1/tests/boolean/removefeatures/A8 --- opencascade-7.5.1+dfsg1/tests/boolean/removefeatures/A8 2021-02-02 08:51:56.000000000 +0000 +++ opencascade-7.5.2+dfsg1/tests/boolean/removefeatures/A8 2021-04-20 07:07:58.000000000 +0000 @@ -10,6 +10,6 @@ removefeatures result s feature checkshape result -checkprops result -s 2392.41 -v 1063.75 -deps 1.e-7 +checkprops result -s 2392.42 -v 1063.76 -deps 1.e-7 checknbshapes result -vertex 61 -edge 91 -wire 34 -face 33 -shell 1 -solid 1 CheckIsFeatureRemoved feature {e f} diff -Nru opencascade-7.5.1+dfsg1/tests/bugs/heal/bug31524 opencascade-7.5.2+dfsg1/tests/bugs/heal/bug31524 --- opencascade-7.5.1+dfsg1/tests/bugs/heal/bug31524 1970-01-01 00:00:00.000000000 +0000 +++ opencascade-7.5.2+dfsg1/tests/bugs/heal/bug31524 2021-04-20 07:07:58.000000000 +0000 @@ -0,0 +1,12 @@ +puts "TODO OCC31524 ALL: Faulty shapes in variables faulty_1" + +puts "===============================================================================================" +puts "0031524: Modeling Algorithms - Unify same domain corrupts shape representing a cylindrical tube" +puts "===============================================================================================" +puts "" + +restore [locate_data_file bug31524.brep] shape + +unifysamedom res shape +checkshape shape + \ No newline at end of file diff -Nru opencascade-7.5.1+dfsg1/tests/bugs/heal/bug31778 opencascade-7.5.2+dfsg1/tests/bugs/heal/bug31778 --- opencascade-7.5.1+dfsg1/tests/bugs/heal/bug31778 1970-01-01 00:00:00.000000000 +0000 +++ opencascade-7.5.2+dfsg1/tests/bugs/heal/bug31778 2021-04-20 07:07:58.000000000 +0000 @@ -0,0 +1,28 @@ +puts "=============================================" +puts "OCC31778: UnifySameDomain fails in Debug mode" +puts "=============================================" +puts "" + +brestore [locate_data_file bug31778.brep] s +explode s +bclearobjects +bcleartools +baddobjects s_1 +baddtools s_2 s_3 +bfillds +bbop q 1 +explode q + +unifysamedom result q_1 + +checkshape result + +checknbshapes result -solid 1 -shell 1 -face 19 -wire 21 -edge 51 -vertex 34 + +set tolres [checkmaxtol result] + +if { ${tolres} > 5.e-5} { + puts "Error: bad tolerance of result" +} + +checkprops result -v 15173.9 diff -Nru opencascade-7.5.1+dfsg1/tests/bugs/heal/bug32140 opencascade-7.5.2+dfsg1/tests/bugs/heal/bug32140 --- opencascade-7.5.1+dfsg1/tests/bugs/heal/bug32140 1970-01-01 00:00:00.000000000 +0000 +++ opencascade-7.5.2+dfsg1/tests/bugs/heal/bug32140 2021-04-20 07:07:58.000000000 +0000 @@ -0,0 +1,18 @@ +puts "==============================================================" +puts "OCC32140: unify same domain calls crossed for opposite vectors" +puts "==============================================================" +puts "" + +restore [locate_data_file bug32140.brep] a + +unifysamedom result a + +checkshape result + +checknbshapes result -solid 1 -shell 1 -face 26 -wire 32 -edge 69 -vertex 41 + +set tolres [checkmaxtol result] + +if { ${tolres} > 6.e-6} { + puts "Error: bad tolerance of result" +} diff -Nru opencascade-7.5.1+dfsg1/tests/bugs/heal/bug32213 opencascade-7.5.2+dfsg1/tests/bugs/heal/bug32213 --- opencascade-7.5.1+dfsg1/tests/bugs/heal/bug32213 1970-01-01 00:00:00.000000000 +0000 +++ opencascade-7.5.2+dfsg1/tests/bugs/heal/bug32213 2021-04-20 07:07:58.000000000 +0000 @@ -0,0 +1,20 @@ +puts "===========================================" +puts "OCC32213: Invalid result of UnifySameDomain" +puts "===========================================" +puts "" + +restore [locate_data_file bug32213.brep] a + +unifysamedom result a + +checkshape result + +checknbshapes result -solid 1 -shell 1 -face 21 -wire 22 -edge 58 -vertex 38 + +set tolres [checkmaxtol result] + +if { ${tolres} > 6.e-6} { + puts "Error: bad tolerance of result" +} + +checkprops result -s 81.9221 \ No newline at end of file diff -Nru opencascade-7.5.1+dfsg1/tests/bugs/modalg_7/bug31984 opencascade-7.5.2+dfsg1/tests/bugs/modalg_7/bug31984 --- opencascade-7.5.1+dfsg1/tests/bugs/modalg_7/bug31984 1970-01-01 00:00:00.000000000 +0000 +++ opencascade-7.5.2+dfsg1/tests/bugs/modalg_7/bug31984 2021-04-20 07:07:58.000000000 +0000 @@ -0,0 +1,12 @@ +puts "==============================================" +puts " 0031984: Sweep crashes if Bi-normal is given" +puts "==============================================" +puts "" + +restore [locate_data_file bug31984.brep] a +explode a + +mksweep a_1 +addsweep a_2 +setsweep -CN 0 0 1 +buildsweep result diff -Nru opencascade-7.5.1+dfsg1/tests/bugs/modalg_7/bug32136 opencascade-7.5.2+dfsg1/tests/bugs/modalg_7/bug32136 --- opencascade-7.5.1+dfsg1/tests/bugs/modalg_7/bug32136 1970-01-01 00:00:00.000000000 +0000 +++ opencascade-7.5.2+dfsg1/tests/bugs/modalg_7/bug32136 2021-04-20 07:07:58.000000000 +0000 @@ -0,0 +1,54 @@ +puts "=============================================================================================" +puts "0032136: Modeling Algorithms - Boolean fuse fails and corrupts the argument-shape" +puts "=============================================================================================" +puts "" + +restore [locate_data_file bug32136_obj.brep] s +restore [locate_data_file bug32136_tools.brep] t + +bclearobjects +bcleartools +baddobjects s +eval baddtools [explode t] +bfillds +bbop result 1 + +checkshape result +checknbshapes result -face 731 -shell 1 -solid 1 -t +checkprops result -s 0.051066 -v 8.9084e-06 + +foreach sh {result s} { + if {![regexp "This shape seems to be OK" [bopcheck $sh]]} { + puts "Error: the $sh shape is self-interfered" + } + checkmaxtol $sh -ref 5.e-6 +} + +foreach sh [explode t] { + if {![regexp "This shape seems to be OK" [bopcheck $sh]]} { + puts "Error: the $sh shape is self-interfered" + } + checkmaxtol $sh -ref 5.e-6 +} + +checkview -display result -2d -path ${imagedir}/${test_image}_fuse.png + +# subsequent cut operation +box box 0.06335 0.06335 0.05 +bclearobjects +bcleartools +baddobjects box +baddtools result +bfillds +bbop result_cut 2 + +checkshape result_cut +checknbshapes result_cut -face 756 -shell 1 -solid 1 -t +checkprops result_cut -s 0.0545148 -v 0.000191753 + +if {![regexp "This shape seems to be OK" [bopcheck result_cut]]} { + puts "Error: the result_cut shape is self-interfered" +} +checkmaxtol result_cut -ref 5.e-6 + +checkview -display result_cut -2d -path ${imagedir}/${test_image}_cut.png diff -Nru opencascade-7.5.1+dfsg1/tests/bugs/modalg_7/bug32189 opencascade-7.5.2+dfsg1/tests/bugs/modalg_7/bug32189 --- opencascade-7.5.1+dfsg1/tests/bugs/modalg_7/bug32189 1970-01-01 00:00:00.000000000 +0000 +++ opencascade-7.5.2+dfsg1/tests/bugs/modalg_7/bug32189 2021-04-20 07:07:58.000000000 +0000 @@ -0,0 +1,15 @@ +puts "=============================" +puts " 0032189: BOP Cut regression" +puts "=============================" +puts "" + +restore [locate_data_file bug32189_a.brep] a +restore [locate_data_file bug32189_b.brep] b + +bcut result a b + +checkshape result +checknbshapes result -vertex 5 -edge 6 -wire 3 -face 3 -shell 1 -solid 1 +checkprops result -s 0.000687454 -v 8.86946e-07 + +checkview -display result -2d -path ${imagedir}/${test_image}.png \ No newline at end of file diff -Nru opencascade-7.5.1+dfsg1/tests/bugs/step/bug32264 opencascade-7.5.2+dfsg1/tests/bugs/step/bug32264 --- opencascade-7.5.1+dfsg1/tests/bugs/step/bug32264 1970-01-01 00:00:00.000000000 +0000 +++ opencascade-7.5.2+dfsg1/tests/bugs/step/bug32264 2021-04-20 07:07:58.000000000 +0000 @@ -0,0 +1,8 @@ +restore [locate_data_file bug32264.brep] s +set aTmpFile "$imagedir/${casename}.brep" +testwritestep "$aTmpFile" s +testreadstep "$aTmpFile" s1 +file delete "$aTmpFile" +checkshape s1 f +checkmaxtol s1 -ref 1.e-7 +checkprops s1 -v 16.1759 -deps 0.01 diff -Nru opencascade-7.5.1+dfsg1/tests/evolved/voluved/HMC010 opencascade-7.5.2+dfsg1/tests/evolved/voluved/HMC010 --- opencascade-7.5.1+dfsg1/tests/evolved/voluved/HMC010 2021-02-02 08:51:56.000000000 +0000 +++ opencascade-7.5.2+dfsg1/tests/evolved/voluved/HMC010 2021-04-20 07:07:58.000000000 +0000 @@ -18,7 +18,7 @@ puts "Error: bopargcheck has found some faulties in res2" } -checkmaxtol result -ref 0.031968491076118669 +checkmaxtol result -ref 5.e-6 smallview don result sw tw diff -Nru opencascade-7.5.1+dfsg1/tests/lowalgos/extcs/bug32225 opencascade-7.5.2+dfsg1/tests/lowalgos/extcs/bug32225 --- opencascade-7.5.1+dfsg1/tests/lowalgos/extcs/bug32225 1970-01-01 00:00:00.000000000 +0000 +++ opencascade-7.5.2+dfsg1/tests/lowalgos/extcs/bug32225 2021-04-20 07:07:58.000000000 +0000 @@ -0,0 +1,28 @@ +puts "========" +puts "OCC32225: Modeling Data - Wrong result of extrema curve-surface" +puts "========" +puts "" + +restore [locate_data_file bug32225_curve.draw] c +restore [locate_data_file bug32225_surf.draw] s + +extrema c s + +if {[isdraw ext_1]} { + set ext_dist [lindex [length ext_1] end] + checkreal "Ext_1 min distance" $ext_dist 0. 1.e-10 1.e-10 +} else { + puts "Error: invalid result" +} + +if {[isdraw ext_2]} { + set ext_dist [lindex [length ext_2] end] + checkreal "Ext_2 min distance" $ext_dist 0. 1.e-10 1.e-10 +} else { + puts "Error: invalid result" +} +smallview +donly c ext_1 ext_2 +fit +disp s +checkview -screenshot -2d -path ${imagedir}/${test_image}.png \ No newline at end of file