]> OCCT Git - occt-copy.git/commitdiff
0027651: Add projection support in sewing pcurves handling
authorifv <ifv@opencascade.com>
Fri, 25 May 2018 12:21:04 +0000 (15:21 +0300)
committerifv <ifv@opencascade.com>
Mon, 20 Jan 2020 11:43:42 +0000 (14:43 +0300)
1. BRepLib.hxx, BRepLib_1.cxx - implementation of method SetPCurve(...), which can build new pcurve by projection, if pcurve to be set is not  satisfied by tolerance criterium.

2. BRepBuilderAPI_Sewing.cxx - modification of method SameParameterEdge(...) using new method SetPCurve(...)

3. BRepTest/BRepTest_BasicCommands.cxx - implementation Draw command SetPCurve

4. Approx_ComputeCLine.gxx, BRepOffsetAPI_DraftAngle.cxx, ProjLib_ProjectedCurve.cxx - small modification to fix regression.

5. Modification of tests according to current behavior of sewing algorithm.

6. Test case added
 bugs/modalg_6/bug27651

7. dox/user_guides/draw_test_harness/draw_test_harness.md
Documentation update.

21 files changed:
dox/user_guides/draw_test_harness/draw_test_harness.md
src/Approx/Approx_ComputeCLine.gxx
src/BRepBuilderAPI/BRepBuilderAPI_Sewing.cxx
src/BRepLib/BRepLib.hxx
src/BRepLib/BRepLib_1.cxx
src/BRepOffsetAPI/BRepOffsetAPI_DraftAngle.cxx
src/BRepTest/BRepTest_BasicCommands.cxx
src/ProjLib/ProjLib_ProjectedCurve.cxx
tests/bugs/modalg_2/bug22770_13
tests/bugs/modalg_2/bug22770_15
tests/bugs/modalg_2/bug22804
tests/bugs/modalg_4/bug714
tests/bugs/modalg_5/bug25175
tests/bugs/modalg_6/bug27651 [new file with mode: 0644]
tests/bugs/xde/bug547_2
tests/lowalgos/intss/bug26684_1
tests/lowalgos/intss/bug27263
tests/sewing/tol_100/D3
tests/sewing/tol_100/I5
tests/sewing/tol_100/J1
tests/sewing/tol_100/J2

index b5ae421a0167316e3a7bb340945dfac5dca61d9b..230bcc053f4b3f407153acb844fc4e37be819e3a 100644 (file)
@@ -6093,6 +6093,7 @@ This group of commands is used to create topology from shapes and to extract sha
   * To create faces, use the **mkplane**, **mkface** commands.
   * To extract the geometry from edges or faces, use the **mkcurve** and **mkface** commands.
   * To extract the 2d curves from edges or faces, use the **pcurve** command.
+  * To add/set the 2d curves to edges of face, use the **addpcurve** or **setpcurve** command.
 
 
 @subsubsection occt_draw_7_2_1  vertex
@@ -6415,14 +6416,16 @@ vertex v2 10 0 0
 edge e v1 v2 
 ~~~~~
 
-@subsubsection occt_draw_7_2_9  pcurve
+@subsubsection occt_draw_7_2_9  pcurve, addpcurve, setpcurve
 
 Syntax:      
 
 ~~~~~
 pcurve [name edgename] facename 
+addpcurve edge 2dcurve face [tol (default 1.e-7)]
+setpcurve edge 2dcurve face [tol (default 1.e-4)]
 ~~~~~
-
+**pcurve**
 Extracts the 2d curve of an edge on a face. If only the face is specified, the command extracts all the curves and colors them according to their orientation. This is useful in checking to see if the edges in a face are correctly oriented, i.e. they turn counter-clockwise. To make curves visible, use a fitted 2d view. 
 
 **Example:** 
@@ -6436,6 +6439,14 @@ pcurve p
 2dfit 
 ~~~~~
 
+**addpcurve**, 
+Add given pcurve to edge of face, update edge tolerance.
+
+**setpcurve**
+Add given pcurve to edge, if pcurve cannot be set with tolerance less then tol,
+algorithm builds new pcurve by projecting edge on face and sets it.
+
+
 @subsubsection occt_draw_7_2_10  chfi2d
 
 Syntax:      
index c9e7ed838d8b5ebc3d62def7c42210174316cfbd..f35eed4debc3a37f786c2f747a27f6051463bed5 100644 (file)
@@ -178,10 +178,12 @@ void Approx_ComputeCLine::Perform(const MultiLine& Line)
       Standard_Boolean aStopCutting = Standard_False;
       if (aNbCut >= aNbComp)
       {
-        if (aNbCut > aNbImp)
+        if (aNbCut > aNbImp + 1)
         {
           aStopCutting = Standard_True;
         }
+        aNbCut = 0;
+        aNbImp = 0;
       }
       // is new decision better?
       if (!Ok && (Abs(myfirstU - mylastU) <= TolU || aMaxSegments >= aMaxSegments1 || aStopCutting ))
index aa9fb08a1fcf344b96e554643745e7677b9e4bd0..07639cec0b1d48c58072a77ab45879c39da0a104 100644 (file)
@@ -587,6 +587,7 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
 
   // Sort input edges
   TopoDS_Edge edge1, edge2;
+  Standard_Real aTolMax = Precision::Infinite();
   if (firstCall) {
     // Take the longest edge as first
     Standard_Real f, l;
@@ -600,11 +601,13 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
       edge1 = edgeLast;
       edge2 = edgeFirst;
       whichSec = 2;
+      aTolMax = len2 / 2.;
     }
     else {
       edge1 = edgeFirst;
       edge2 = edgeLast;
       whichSec = 1;
+      aTolMax = len1 / 2.;
     }
   }
   else {
@@ -747,7 +750,7 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
   TopLoc_Location loc2;
   Handle(Geom_Surface) surf2;
   
-  //Handle(Geom2d_Curve) c2d2, c2d21;
+  Handle(Geom2d_Curve) c2d2edge;
   //  Standard_Real firstOld, lastOld;
 
   TopTools_ListIteratorOfListOfShape itf2;
@@ -755,6 +758,7 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
   else               itf2.Initialize(listFacesFirst);
   Standard_Boolean isResEdge = Standard_False;
   TopoDS_Face fac2;
+  Standard_Boolean isSeam2edge = Standard_False;
   for (; itf2.More(); itf2.Next()) {
     Handle(Geom2d_Curve) c2d2, c2d21;
     Standard_Real firstOld, lastOld;
@@ -763,6 +767,7 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
     surf2 = BRep_Tool::Surface(fac2, loc2);
     Standard_Boolean isSeam2 = ((IsUClosedSurface(surf2,edge2,loc2) || IsVClosedSurface(surf2,edge2,loc2)) &&
       BRep_Tool::IsClosed(TopoDS::Edge(edge2),fac2));
+    isSeam2edge = isSeam2;
     if (isSeam2) {
       if (!myNonmanifold) return TopoDS_Edge();
       TopoDS_Shape aTmpShape = edge2.Reversed(); //for porting
@@ -770,7 +775,6 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
     }
     c2d2 = BRep_Tool::CurveOnSurface(edge2, fac2, firstOld, lastOld);
     if (c2d2.IsNull() && c2d21.IsNull()) continue;
-
     if (!c2d21.IsNull()) {
       c2d21 = Handle(Geom2d_Curve)::DownCast(c2d21->Copy());
       if (!secForward) {
@@ -800,7 +804,9 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
 
     c2d2 = SameRange(c2d2,firstOld,lastOld,first,last);
     if (c2d2.IsNull()) continue;
-
+    //
+    c2d2edge = c2d2;
+    //
     // Add second PCurve
     Standard_Boolean isSeam = Standard_False;
     TopAbs_Orientation Ori = TopAbs_FORWARD;
@@ -890,6 +896,20 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
   }
   Standard_Real tolReached = Precision::Infinite();
   Standard_Boolean isSamePar = Standard_False; 
+  // Save initial tolerances of edge before SameParameter
+  Standard_Real aToledge = BRep_Tool::Tolerance(edge);
+  TopoDS_Vertex aV1edge, aV2edge;
+  TopExp::Vertices(edge, aV1edge, aV2edge);
+  Standard_Real aTolV1 = Precision::Confusion(), aTolV2 = Precision::Confusion();
+  //
+  if (!aV1edge.IsNull())
+  {
+    aTolV1 = BRep_Tool::Tolerance(aV1edge);
+  }
+  if (!aV2edge.IsNull())
+  {
+    aTolV2 = BRep_Tool::Tolerance(aV2edge);
+  }
   try
   {
     if( isResEdge)
@@ -903,23 +923,23 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
     }
   }
   
-  catch(Standard_Failure const&)
+  catch(Standard_Failure)
   {
     isSamePar = Standard_False;
   }
  
  
-  if (firstCall && ( !isResEdge || !isSamePar || tolReached > myTolerance)) {
+  if (firstCall && (!isResEdge || !isSamePar || tolReached > myTolerance)) {
     Standard_Integer whichSecn = whichSec;
     // Try to merge on the second section
     Standard_Boolean second_ok = Standard_False;
-    TopoDS_Edge s_edge = SameParameterEdge(edgeFirst,edgeLast,listFacesFirst,listFacesLast,
-      secForward,whichSecn,Standard_False);
-    if!s_edge.IsNull())
+    TopoDS_Edge s_edge = SameParameterEdge(edgeFirst, edgeLast, listFacesFirst, listFacesLast,
+      secForward, whichSecn, Standard_False);
+    if (!s_edge.IsNull())
     {
-      Standard_Real tolReached_2  = BRep_Tool::Tolerance(s_edge);
-      second_ok = ( BRep_Tool::SameParameter(s_edge) && tolReached_2 < tolReached );
-      ifsecond_ok)
+      Standard_Real tolReached_2 = BRep_Tool::Tolerance(s_edge);
+      second_ok = (BRep_Tool::SameParameter(s_edge) && tolReached_2 < tolReached);
+      if (second_ok)
       {
         edge = s_edge;
         whichSec = whichSecn;
@@ -929,56 +949,73 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
 
     if (!second_ok && !edge.IsNull()) {
 
-      GeomAdaptor_Curve c3dAdapt(c3d);
-
-      // Discretize edge curve
-      Standard_Integer i, j, nbp = 23;
-      Standard_Real deltaT = (last3d - first3d) / (nbp -1);
-      TColgp_Array1OfPnt c3dpnt(1,nbp);
-      for (i = 1; i <= nbp; i++) 
-        c3dpnt(i) = c3dAdapt.Value(first3d + (i-1)*deltaT);
-
-      Standard_Real dist = 0., maxTol = -1.0;
-      Standard_Boolean more = Standard_True;
-
-      for (j = 1; more; j++) {
-        Handle(Geom2d_Curve) c2d2;
-        BRep_Tool::CurveOnSurface(edge, c2d2, surf2, loc2, first, last, j);
-            
-        more = !c2d2.IsNull();
-        if (more) {
-          Handle(Geom_Surface) aS = surf2;
-          if(!loc2.IsIdentity())
-            aS = Handle(Geom_Surface)::DownCast(surf2->Transformed ( loc2 ));
-
-          Standard_Real dist2 = 0.;
-          deltaT = (last - first) / (nbp - 1);
-          for (i = 1; i <= nbp; i++) {
-            gp_Pnt2d aP2d =  c2d2->Value(first + (i -1)*deltaT);
-            gp_Pnt aP2(0.,0.,0.);
-            aS->D0(aP2d.X(),aP2d.Y(), aP2);
-            gp_Pnt aP1 = c3dpnt(i);
-            dist = aP2.SquareDistance(aP1);
-            if (dist > dist2) 
-              dist2 = dist;
-          }
-          maxTol = Max(sqrt(dist2) * (1. + 1e-7), Precision::Confusion());
-        }
+      Handle(Geom2d_Curve) aProjCurve;
+      Standard_Real aTolReached_3 = RealLast();
+      if (!isSeam2edge && myTolerance < aTolMax)
+      {
+        static_cast<BRep_TEdge*>(edge.TShape().get())->Tolerance(aToledge);
+        static_cast<BRep_TVertex*>(aV1edge.TShape().get())->Tolerance(aTolV1);
+        static_cast<BRep_TVertex*>(aV2edge.TShape().get())->Tolerance(aTolV2);
+
+        BRepLib::SetPCurve(edge, c2d2edge, fac2, myTolerance,
+                                  aTolReached_3, aProjCurve);
       }
-      if (maxTol >= 0. && maxTol < tolReached)
+      else
       {
-        if (tolReached > MaxTolerance())
-        {
-          // Set tolerance directly to overwrite too large tolerance
-          static_cast<BRep_TEdge*>(edge.TShape().get())->Tolerance(maxTol);
+        //
+        GeomAdaptor_Curve c3dAdapt(c3d);
+
+        // Discretize edge curve
+        Standard_Integer i, j, nbp = 23;
+        Standard_Real deltaT = (last3d - first3d) / (nbp - 1);
+        TColgp_Array1OfPnt c3dpnt(1, nbp);
+        for (i = 1; i <= nbp; i++)
+          c3dpnt(i) = c3dAdapt.Value(first3d + (i - 1)*deltaT);
+
+        Standard_Real dist = 0., maxTol = -1.0;
+        Standard_Boolean more = Standard_True;
+
+        for (j = 1; more; j++) {
+          Handle(Geom2d_Curve) c2d2;
+          BRep_Tool::CurveOnSurface(edge, c2d2, surf2, loc2, first, last, j);
+
+          more = !c2d2.IsNull();
+          if (more) {
+            Handle(Geom_Surface) aS = surf2;
+            if (!loc2.IsIdentity())
+              aS = Handle(Geom_Surface)::DownCast(surf2->Transformed(loc2));
+
+            Standard_Real dist2 = 0.;
+            deltaT = (last - first) / (nbp - 1);
+            for (i = 1; i <= nbp; i++) {
+              gp_Pnt2d aP2d = c2d2->Value(first + (i - 1)*deltaT);
+              gp_Pnt aP2(0., 0., 0.);
+              aS->D0(aP2d.X(), aP2d.Y(), aP2);
+              gp_Pnt aP1 = c3dpnt(i);
+              dist = aP2.SquareDistance(aP1);
+              if (dist > dist2)
+                dist2 = dist;
+            }
+            maxTol = Max(sqrt(dist2) * (1. + 1e-7), Precision::Confusion());
+          }
         }
-        else
+        if (maxTol >= 0. && maxTol < tolReached)
         {
-          // just update tolerance with computed distance
-          aBuilder.UpdateEdge(edge, maxTol);
+          if (tolReached > MaxTolerance())
+          {
+            // Set tolerance directly to overwrite too large tolerance
+            static_cast<BRep_TEdge*>(edge.TShape().get())->Tolerance(maxTol);
+          }
+          else
+          {
+            // just update tolerance with computed distance
+            aBuilder.UpdateEdge(edge, maxTol);
+            aBuilder.UpdateVertex(aV1edge, maxTol);
+            aBuilder.UpdateVertex(aV2edge, maxTol);
+          }
         }
+        aBuilder.SameParameter(edge, Standard_True);
       }
-      aBuilder.SameParameter(edge,Standard_True);
     }
   }
 
@@ -4744,7 +4781,7 @@ void BRepBuilderAPI_Sewing::SameParameterShape()
 
       BRepLib::SameParameter(sec, BRep_Tool::Tolerance(sec));
     }
-    catch (Standard_Failure const&) {
+    catch (Standard_Failure) {
 #ifdef OCCT_DEBUG
       std::cout << "Fail: BRepBuilderAPI_Sewing::SameParameterShape exception in BRepLib::SameParameter" << std::endl;
 #endif
index 5bd88230827323d322dbe907457514e9d49d754f..b8039cf702f5d21c643b536f09a9a83308fdbcb1 100644 (file)
@@ -114,6 +114,34 @@ public:
   //! return False if one of the computation failed.
   Standard_EXPORT static Standard_Boolean BuildCurves3d (const TopoDS_Shape& S);
 
+  //! Sets a pcurve theC for the edge theE on the face theF.
+  //! Setting pcurve can include calling sameparameter algorithm.
+  //! theMaxTol is the maximal tolerance allowed for pcurve.
+  //! If given pcurve cannot be set with tolerance less then theMaxtol,
+  //! algorithm builds new pcurve by projecting edge on face and sets curve,
+  //! which provides minimal tolerance. If projecting was done, algorithm sets
+  //! result of projecting in theProjCurve
+  //! Algorithm sets in theTolReached tolerance of edge after setting pcurve.
+  Standard_EXPORT static void SetPCurve(const TopoDS_Edge& theE, 
+    const Handle(Geom2d_Curve)& theC, 
+    const TopoDS_Face& theF, const Standard_Real theMaxTol, 
+    Standard_Real& theTolReached, Handle(Geom2d_Curve)& theProjCurve);
+
+  //! Sets the pcurve theC1, theC2 for the edge theE on the closed face theF.
+  //! Setting pcurve can include calling sameparameter algorithm.
+  //! theMaxTol is the maximal tolerance allowed for pcurve.
+  //! If given pcurve cannot be set with tolerance less then theMaxtol,
+  //! algorithm builds new pcurves by projecting edge on face and sets curves,
+  //! which provides minimal tolerance. If projecting was done, algorithm sets
+  //! result of projecting in theProjCurve1 and theProjCurve2.
+  //! Algorithm sets in theTolReached tolerance of edge after setting pcurve.
+  Standard_EXPORT static void SetPCurve(const TopoDS_Edge& theE,
+    const Handle(Geom2d_Curve)& theC1, const Handle(Geom2d_Curve)& theC2,
+    const TopoDS_Face& theF, const Standard_Real theMaxTol,
+    Standard_Real& theTolReached, 
+    Handle(Geom2d_Curve)& theProjCurve1, 
+    Handle(Geom2d_Curve)& theProjCurve2);
+
   //! Builds pcurve of edge on face if the surface is plane, and updates the edge.
   Standard_EXPORT static void BuildPCurveForEdgeOnPlane(const TopoDS_Edge& theE, const TopoDS_Face& theF);
 
index 5fe6d8c177195a0fbd03600047df70f7eef329f5..af3ebc36caabf32ba7e179145c0a953ac9d03e1e 100644 (file)
 #include <Precision.hxx>
 #include <TopExp.hxx>
 #include <TopoDS_Vertex.hxx>
-
+#include <BRepCheck_Edge.hxx>
+#include <BRepAdaptor_HSurface.hxx>
+#include <GeomAdaptor_HSurface.hxx>
+#include <BRepAdaptor_HCurve.hxx>
+#include <GeomAdaptor_HCurve.hxx>
+#include <ProjLib_ProjectedCurve.hxx>
+#include <AppParCurves_Constraint.hxx>
+#include <ProjLib.hxx>
+#include <GeomLib_CheckCurveOnSurface.hxx>
+#include <GeomAdaptor.hxx>
+#include <Adaptor3d_CurveOnSurface.hxx>
+#include <Geom2dAdaptor_HCurve.hxx>
+#include <GeomLib.hxx>
+#include <BRep_TEdge.hxx>
 //=======================================================================
 // function: findNearestValidPoint
 // purpose : Starting from the appointed end of the curve, find the nearest
@@ -282,3 +295,379 @@ void BRepLib::BuildPCurveForEdgeOnPlane(const TopoDS_Edge& aE,
   aC2D = BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2, &isStored);
   bToUpdate = !isStored && !aC2D.IsNull();
 }
+//=======================================================================
+//function : CompTol
+//purpose  : 
+//=======================================================================
+static Standard_Real CompTol(const Handle(Geom_Curve)& theC3D, 
+                             const Handle(Geom2d_Curve)& theC2D,
+                             const Handle(Geom_Surface)& theS,
+                             const Standard_Real theFirstPar,
+                             const Standard_Real theLastPar)
+{
+  Standard_Real aTolRange = Max(Precision::PConfusion(),
+    0.001 * (theLastPar - theFirstPar));
+  GeomLib_CheckCurveOnSurface aCheckDist(theC3D, theS, theFirstPar, theLastPar, aTolRange);
+  aCheckDist.Perform(theC2D);
+  Standard_Real aTolR = 0.;
+  if (aCheckDist.IsDone())
+  {
+    aTolR = aCheckDist.MaxDistance();
+  }
+  else
+  {
+    const Standard_Integer aNbPnts = 23;
+    TColStd_Array1OfReal aPars(1, aNbPnts);
+    Standard_Integer i;
+    Standard_Real t, dt = (theLastPar - theFirstPar) / (aNbPnts - 1);
+    aPars(1) = theFirstPar;
+    aPars(aNbPnts) = theLastPar;
+    for (i = 2, t = theFirstPar + dt; i < aNbPnts; ++i, t += dt)
+    {
+      aPars(i) = t;
+    }
+    Handle(Geom2dAdaptor_HCurve) aG2dAHC = new Geom2dAdaptor_HCurve(theC2D);
+    GeomAdaptor_Curve aGAC(theC3D);
+    Handle(GeomAdaptor_HSurface) aGAHS = new GeomAdaptor_HSurface(theS);
+    Adaptor3d_CurveOnSurface aConS(aG2dAHC, aGAHS);
+    GeomLib::EvalMaxParametricDistance(aConS, aGAC, 1., aPars, aTolR);
+    aTolR *= 1.5; //possible deflection
+  }
+
+  return aTolR;
+}
+//=======================================================================
+//function : UpdateTol
+//purpose  : 
+//=======================================================================
+static void UpdateTol(const TopoDS_Edge& theE, const Standard_Real theTol)
+{
+  BRep_Builder aBB;
+  TopoDS_Vertex aV1, aV2;
+  TopExp::Vertices(theE, aV1, aV2);
+  if (!aV1.IsNull())
+  {
+    aBB.UpdateVertex(aV1, theTol);
+  }
+  if (!aV2.IsNull())
+  {
+    aBB.UpdateVertex(aV2, theTol);
+  }
+  aBB.UpdateEdge(theE, theTol);
+}
+
+//=======================================================================
+//function : SetPCurve
+//purpose  : 
+//=======================================================================
+void BRepLib::SetPCurve(const TopoDS_Edge& theE,
+                        const Handle(Geom2d_Curve)& theC,
+                        const TopoDS_Face& theF, 
+                        const Standard_Real theMaxTol,
+                        Standard_Real& theTolReached, Handle(Geom2d_Curve)& theProjCurve)
+{
+  Standard_Real aSMTol = Precision::PConfusion();
+  Standard_Real aTol = BRep_Tool::Tolerance(theE);
+  BRep_Builder aBB;
+  Standard_Real fr, lr, f, l;
+  BRep_Tool::Range(theE, fr, lr);
+  Handle(Geom2d_Curve) aC = theC;
+  f = theC->FirstParameter();
+  l = theC->LastParameter();
+  if (!(Precision::IsInfinite(f) || Precision::IsInfinite(l)))
+  {
+    GeomLib::SameRange(aSMTol, theC, f, l, fr, lr, aC);
+  }
+  aBB.UpdateEdge(theE, aC, theF, aTol);
+  Handle(Geom_Surface) anS = BRep_Tool::Surface(theF);
+  Handle(Geom_Curve) aC3D = BRep_Tool::Curve(theE, f, l);
+  Standard_Real aTol1 = CompTol(aC3D, aC, anS, fr, lr);
+  if (aTol1 <= aTol)
+  {
+    theTolReached = aTol1;
+    aBB.SameParameter(theE, Standard_True);
+    return;
+  }
+  else if (theMaxTol < aTol && aTol1 < 2.*aTol)
+  {
+    theTolReached = aTol1;
+    UpdateTol(theE, theTolReached);
+    return;
+  }
+  aBB.SameParameter(theE, Standard_False);
+  Standard_Real aNewTol = -1;
+  BRepLib::SameParameter(theE, aTol, aNewTol, Standard_True);
+  if (aNewTol > 0)
+  {
+    //Set old tolerance for edge, which has been changed by sameparameter
+    static_cast<BRep_TEdge*>(theE.TShape().get())->Tolerance(aTol);
+  }
+  if (aNewTol > 0.)
+  {
+    aC = BRep_Tool::CurveOnSurface(theE, theF, f, l);
+    aNewTol = CompTol(aC3D, aC, anS, fr, lr);
+    if (aNewTol < theMaxTol)
+    {
+      aBB.SameParameter(theE, Standard_True);
+      theTolReached = aNewTol;
+      UpdateTol(theE, theTolReached);
+      return ;
+    }
+  }
+  //Projection
+  Handle(BRepAdaptor_HSurface) aBAHS = 
+    new BRepAdaptor_HSurface(BRepAdaptor_Surface(theF, Standard_False));
+  Handle(BRepAdaptor_HCurve) aBAHC = new BRepAdaptor_HCurve(theE);
+  ProjLib_ProjectedCurve aProjCurv(aBAHS);
+  Standard_Integer aDegMin = -1, aDegMax = -1, aMaxSegments = -1;
+  Standard_Real aMaxDist = Max(1.e3 * theMaxTol, aNewTol);
+  Standard_Real aTR = Precision::Confusion();
+  Standard_Real aMaxTol = 1.e3 * aTR; //0.0001
+  Standard_Boolean isAnaSurf = ProjLib::IsAnaSurf(aBAHS);
+  AppParCurves_Constraint aBndPnt = AppParCurves_TangencyPoint;
+  if (theMaxTol >= aMaxTol || aNewTol > 10. * theMaxTol)
+  {
+    aTR = aMaxTol;
+    if (aNewTol >= 1.)
+    {
+      aTR = Min(10. * aTR, theMaxTol);
+    }
+    if (!isAnaSurf )
+    {
+      aBndPnt = AppParCurves_PassPoint;
+    }
+  }
+  //
+  theTolReached = RealLast();
+  aProjCurv.Load(aTR);
+  aProjCurv.SetDegree(aDegMin, aDegMax);
+  aProjCurv.SetMaxSegments(aMaxSegments);
+  aProjCurv.SetBndPnt(aBndPnt);
+  aProjCurv.SetMaxDist(aMaxDist);
+  aProjCurv.Perform(aBAHC);
+  ProjLib::MakePCurveOfType(aProjCurv, theProjCurve);
+  if (!theProjCurve.IsNull())
+  {
+    Standard_Real pf = theProjCurve->FirstParameter(), 
+                  pl = theProjCurve->LastParameter();
+    if (!(Precision::IsInfinite(pf) || Precision::IsInfinite(pl)))
+    {
+      if (Abs(pf - fr) > aSMTol || Abs(pl - lr) > aSMTol)
+      {
+        aC.Nullify();
+        GeomLib::SameRange(aSMTol, theProjCurve, pf, pl, fr, lr, aC);
+        if (!aC.IsNull() && theProjCurve != aC)
+        {
+          theProjCurve = aC;
+        }
+      }
+    }
+    Standard_Real aTolR = CompTol(aC3D, theProjCurve, anS, fr, lr);
+    //
+    if ((aNewTol > 0. && aTolR < aNewTol) || aNewTol < 0.) 
+    {
+      theTolReached = aTolR;
+      //
+      //Set new pcurve
+      aBB.UpdateEdge(theE, theProjCurve, theF, theTolReached);
+      UpdateTol(theE, theTolReached);
+      aBB.SameParameter(theE, Standard_True);
+    }
+    else
+    {
+      if (aNewTol > 0.)
+      {
+        theTolReached = aNewTol;
+      }
+      else
+      {
+        theTolReached = aTol1;
+      }
+      UpdateTol(theE, theTolReached);
+      aBB.SameParameter(theE, Standard_True);
+    }
+  }
+  else
+  {
+    if (aNewTol > 0.)
+    {
+      theTolReached = aNewTol;
+    }
+    else
+    {
+      theTolReached = aTol1;
+    }
+    UpdateTol(theE, theTolReached);
+    aBB.SameParameter(theE, Standard_True);
+  }
+}
+//=======================================================================
+//function : SetPCurve
+//purpose  : 
+//=======================================================================
+void BRepLib::SetPCurve(const TopoDS_Edge& theE,
+  const Handle(Geom2d_Curve)& theC1, const Handle(Geom2d_Curve)& theC2,
+  const TopoDS_Face& theF,
+  const Standard_Real theMaxTol,
+  Standard_Real& theTolReached, 
+  Handle(Geom2d_Curve)& theProjCurve1,
+  Handle(Geom2d_Curve)& theProjCurve2)
+{
+  Standard_Real aSMTol = Precision::PConfusion();
+  Standard_Real aTol = BRep_Tool::Tolerance(theE);
+  BRep_Builder aBB;
+  Standard_Real fr, lr, f, l;
+  BRep_Tool::Range(theE, fr, lr);
+  Handle(Geom2d_Curve) aC1 = theC1, aC2 = theC2;
+  f = theC1->FirstParameter();
+  l = theC1->LastParameter();
+  if (!(Precision::IsInfinite(f) || Precision::IsInfinite(l)))
+  {
+    GeomLib::SameRange(aSMTol, theC1, f, l, fr, lr, aC1);
+  }
+  f = theC2->FirstParameter();
+  l = theC2->LastParameter();
+  if (!(Precision::IsInfinite(f) || Precision::IsInfinite(l)))
+  {
+    GeomLib::SameRange(aSMTol, theC2, f, l, fr, lr, aC2);
+  }
+  aBB.UpdateEdge(theE, aC1, aC2, theF, aTol);
+  Handle(Geom_Surface) anS = BRep_Tool::Surface(theF);
+  Handle(Geom_Curve) aC3D = BRep_Tool::Curve(theE, f, l);
+  Standard_Real aTol1 = CompTol(aC3D, aC1, anS, fr, lr);
+  aTol1 = Max(aTol1, CompTol(aC3D, aC2, anS, fr, lr));
+  if (aTol1 <= aTol)
+  {
+    theTolReached = aTol1;
+    aBB.SameParameter(theE, Standard_True);
+    return;
+  }
+  aBB.SameParameter(theE, Standard_False);
+  Standard_Real aNewTol = -1;
+  BRepLib::SameParameter(theE, aTol, aNewTol, Standard_False);
+  if (aNewTol > 0)
+  {
+    //Set old tolerance for edge, which has been changed by sameparameter
+    static_cast<BRep_TEdge*>(theE.TShape().get())->Tolerance(aTol);
+  }
+  if (aNewTol > 0. && aNewTol < theMaxTol)
+  {
+    TopoDS_Vertex aV1, aV2;
+    TopExp::Vertices(theE, aV1, aV2);
+    if (!aV1.IsNull())
+    {
+      aBB.UpdateVertex(aV1, aNewTol);
+    }
+    if (!aV2.IsNull())
+    {
+      aBB.UpdateVertex(aV2, aNewTol);
+    }
+    theTolReached = aNewTol;
+    return;
+  }
+  //Projection
+  Handle(BRepAdaptor_HSurface) aBAHS = new BRepAdaptor_HSurface(theF);
+  Handle(BRepAdaptor_HCurve) aBAHC = new BRepAdaptor_HCurve(theE);
+  ProjLib_ProjectedCurve aProjCurv(aBAHS);
+  Standard_Integer aDegMin = -1, aDegMax = -1, aMaxSegments = -1;
+  Standard_Real aMaxDist = Max(1.e3 * theMaxTol, aNewTol);
+  Standard_Real aTR = Precision::Confusion();
+  Standard_Real aMaxTol = 1.e3 * aTR; //0.0001
+  Standard_Boolean isAnaSurf = ProjLib::IsAnaSurf(aBAHS);
+  AppParCurves_Constraint aBndPnt = AppParCurves_TangencyPoint;
+  if (theMaxTol >= aMaxTol || aNewTol > 10. * theMaxTol)
+  {
+    aTR = aMaxTol;
+    if (aNewTol >= 1.)
+    {
+      aTR = Min(10. * aTR, theMaxTol);
+    }
+    if (!isAnaSurf)
+    {
+      aBndPnt = AppParCurves_PassPoint;
+    }
+  }
+  //
+  theTolReached = RealLast();
+  aProjCurv.Load(aTR);
+  aProjCurv.SetDegree(aDegMin, aDegMax);
+  aProjCurv.SetMaxSegments(aMaxSegments);
+  aProjCurv.SetBndPnt(aBndPnt);
+  aProjCurv.SetMaxDist(aMaxDist);
+  aProjCurv.Perform(aBAHC);
+  Handle(Geom2d_Curve) aCProj;
+  ProjLib::MakePCurveOfType(aProjCurv, aCProj);
+  if (!aCProj.IsNull())
+  {
+    Standard_Real pf = aCProj->FirstParameter(),
+      pl = aCProj->LastParameter();
+    if (!(Precision::IsInfinite(pf) || Precision::IsInfinite(pl)))
+    {
+      if (Abs(pf - fr) > aSMTol || Abs(pl - lr) > aSMTol)
+      {
+        aC1.Nullify();
+        GeomLib::SameRange(aSMTol, aCProj, pf, pl, fr, lr, aC1);
+        if (!aC1.IsNull() && aCProj != aC1)
+        {
+          aCProj = aC1;
+        }
+      }
+    }
+    Standard_Real aTolR = CompTol(aC3D, aCProj, anS, fr, lr);
+    //
+    if ((aNewTol > 0. && aTolR < aNewTol) || aNewTol < 0.)
+    {
+      theTolReached = aTolR;
+      //
+      gp_Pnt2d aP1, aP2, aPProj;
+      Handle(Geom2d_Curve) aPC = BRep_Tool::CurveOnSurface(theE, theF, f, l);
+      aP1 = aPC->Value(f);
+      aPC = BRep_Tool::CurveOnSurface(TopoDS::Edge(theE.Reversed()), theF, f, l);
+      aP2 = aPC->Value(f);
+      aPProj = aCProj->Value(f);
+      Standard_Real Dist1, Dist2;
+      Dist1 = aPProj.Distance(aP1);
+      Dist2 = aPProj.Distance(aP2);
+      if (Dist1 < Dist2)  {
+        theProjCurve1 = aCProj;
+        Handle(Geom2d_Geometry) GG = aCProj->Translated(aP1, aP2);
+        theProjCurve2 = Handle(Geom2d_Curve)::DownCast(GG);
+      }
+      else {
+        theProjCurve2 = aCProj;
+        Handle(Geom2d_Geometry) GG = aCProj->Translated(aP2, aP1);
+        theProjCurve1 = Handle(Geom2d_BSplineCurve)::DownCast(GG);
+      }
+      //Set new pcurves
+      aBB.UpdateEdge(theE, theProjCurve1, theProjCurve2, theF, aTolR);
+      UpdateTol(theE, theTolReached);
+      aBB.SameParameter(theE, Standard_True);
+    }
+    else
+    {
+      if (aNewTol > 0.)
+      {
+        theTolReached = aNewTol;
+      }
+      else
+      {
+        theTolReached = aTol1;
+      }
+      UpdateTol(theE, theTolReached);
+      aBB.SameParameter(theE, Standard_True);
+    }
+  }
+  else
+  {
+    if (aNewTol > 0.)
+    {
+      theTolReached = aNewTol;
+    }
+    else
+    {
+      theTolReached = aTol1;
+    }
+    UpdateTol(theE, theTolReached);
+    aBB.SameParameter(theE, Standard_True);
+  }
+}
\ No newline at end of file
index 50eadac75bf506e02cde44953fad5b1c5370f236..149729d2ae28141d69f63da38483f13dc22ac289 100644 (file)
@@ -960,7 +960,7 @@ void BRepOffsetAPI_DraftAngle::CorrectVertexTol()
   anExp.Init(myShape, TopAbs_EDGE);
   for(; anExp.More(); anExp.Next())
   {
-    const TopoDS_Shape& anE = anExp.Current();
+    const TopoDS_Edge& anE = TopoDS::Edge(anExp.Current());
     //Skip old (not modified) edges
     if(anInitEdges.Contains(anE))
       continue;
@@ -971,7 +971,7 @@ void BRepOffsetAPI_DraftAngle::CorrectVertexTol()
     //
     aNewEdges.Add(anE);
     //
-    Standard_Real anETol = BRep_Tool::Tolerance(TopoDS::Edge(anE));
+    Standard_Real anETol = BRep_Tool::Tolerance(anE);
     TopoDS_Iterator anIter(anE);
     for(; anIter.More(); anIter.Next())
     {
@@ -997,6 +997,18 @@ void BRepOffsetAPI_DraftAngle::CorrectVertexTol()
       }
       else
       {
+        gp_Pnt aVPnt = BRep_Tool::Pnt(aVtx);
+        Standard_Real f, l;
+        TopLoc_Location anL;
+        const Handle(Geom_Curve)& aECrv = BRep_Tool::Curve(TopoDS::Edge(anE), anL, f, l);
+        Standard_Real aVPar = BRep_Tool::Parameter(aVtx, anE);
+        gp_Pnt aCP = aECrv->Value(aVPar);
+        if (!anL.IsIdentity())
+        {
+          aCP.Transform(anL.Transformation());
+        }
+        Standard_Real aD = aVPnt.Distance(aCP);
+        aBB.UpdateVertex(aVtx, aD);
         aBB.UpdateVertex(aVtx, anETol + Epsilon(anETol));
       }
     }
index 3e104a3333be9bee333d9bd6979b3d3209e889d4..f07940b722c71067ba54e573d7d67d96a4f94f94 100644 (file)
@@ -110,6 +110,30 @@ static Standard_Integer addpcurve(Draw_Interpretor& , Standard_Integer n, const
   return 0;
 }
 
+//=======================================================================
+// setpcurve
+//=======================================================================
+
+static Standard_Integer setpcurve(Draw_Interpretor&, Standard_Integer n, const char** a)
+{
+  if (n < 4) return 1;
+  TopoDS_Shape E = DBRep::Get(a[1]);
+  if (E.IsNull()) return 1;
+  Handle(Geom2d_Curve) PC = DrawTrSurf::GetCurve2d(a[2]);
+  TopoDS_Shape F = DBRep::Get(a[3]);
+  Standard_Real tol = 1.e-4;
+  if (n > 4) {
+    tol = Draw::Atof(a[4]);
+  }
+  //BRep_Builder BB;
+  //BB.UpdateEdge(TopoDS::Edge(E), PC, TopoDS::Face(F), tol);
+  Standard_Real tolreached;
+  Handle(Geom2d_Curve) ProjC;
+  BRepLib::SetPCurve(TopoDS::Edge(E), PC, TopoDS::Face(F), tol,
+    tolreached, ProjC);
+  DBRep::Set(a[1], E);
+  return 0;
+}
 
 //=======================================================================
 // transform
@@ -1402,6 +1426,10 @@ void  BRepTest::BasicCommands(Draw_Interpretor& theCommands)
                  "addpcurve edge 2dcurve face [tol (default 1.e-7)]",
                  __FILE__,
                  addpcurve,g);
+  theCommands.Add("setpcurve",
+                  "addpcurve edge 2dcurve face [tol (default 1.e-4)]",
+                  __FILE__,
+                  setpcurve, g);
 
   theCommands.Add("reset",
                  "reset name1 name2 ..., remove location",
index 2d5b2a869cc9ab6b5c6dbcc8f44e875f67a543b2..c5135f1c31ff284e5ad3b20abf080508af6364d2 100644 (file)
@@ -237,7 +237,7 @@ static void ExtendC2d (Handle(Geom2d_BSplineCurve)& aRes,
   }
   gp_Lin2d BoundLin(thePole, theBoundDir); //one of the bounds of rectangle
   Standard_Real ParOnLin = 0.;
-  if (theBoundDir.IsParallel(aDBnd, 100.*Precision::Angular()))
+  if (theBoundDir.IsParallel(aDBnd, Precision::PConfusion()))
   {
     ParOnLin = ElCLib::Parameter(aLin, thePole);
   }
index 92e62371609a35100cb02657e1cdace84c99693e..fbe4ce43e45389dbca4d2189f7f2979a37afd278 100755 (executable)
@@ -32,7 +32,7 @@ checkprops result -s 1.8847e+07
 checkshape result
 
 checknbshapes result -vertex 964 -edge 1222 -wire 273 -face 259 -shell 18 -solid 0 -compsolid 0 -compound 1 -shape 2737
-checkmaxtol result -ref 0.046734236640099257
+checkmaxtol result -ref 0.0451323239933289
 checknbshapes result -shell 18
 checkfreebounds result 926
 checkview -display result -3d -path ${imagedir}/${test_image}.png
index 22c4fb2242a7b5431cbf47687e8c1009201585f7..47dab4893bc10a72b6aa9fe547042b43ef301adc 100755 (executable)
@@ -32,7 +32,7 @@ checkprops result -s 1.8847e+07
 checkshape result
 
 checknbshapes result -vertex 964 -edge 1222 -wire 273 -face 259 -shell 18 -solid 0 -compsolid 0 -compound 1 -shape 2737
-checkmaxtol result -ref 0.046734236640099257
+checkmaxtol result -ref 0.0451323239933289
 checknbshapes result -shell 18
 checkfreebounds result 926
 checkview -display result -3d -path ${imagedir}/${test_image}.png
index 8b794093dc48973e5f2e8301c3aa0850e1fdca05..f04776407b142a958bd10d53347e9d177ba092be 100755 (executable)
@@ -28,7 +28,7 @@ if { ${minTolerance}  > ${VertexTolerance} } {
 
 
 checkreal "Min tolerance" ${minTolerance} ${oTolerance} 0 0.001
-checkmaxtol result -ref 2352.4465999220711
+checkmaxtol result -ref 291.20622363265852
 checknbshapes result -shell 1
 checkfreebounds result 5
 
index 3c3d2265e3b36416ba7391c2fb715aff2d446d2c..23c27621ea2d1c89d7e9e12d9d1e09d067e151d4 100755 (executable)
@@ -29,7 +29,7 @@ if { $ve1 != $ve2 || $ed1 != $ed2 || $we1 != $we2} {
     puts "OK OCC714: SEWING operation was made PROPERLY"
 }
 
-checkmaxtol result -ref 0.25619311354638169
+checkmaxtol result -ref 0.17654971008905099
 checknbshapes result -shell 1
 checkfreebounds result 0
 
index 0912b2591e27ee50ac1959682bee8a3a79f1099a..ee7c73ee8286e1c0330058f61fe5c0375f4f18f8 100644 (file)
@@ -12,7 +12,7 @@ igesread [locate_data_file bug25175_3.igs] a *
 
 sewing result 0.1 a
 
-checkmaxtol result -ref 0.40493352048584974 
+checkmaxtol result -ref 0.21794517334615857 
 checknbshapes result -shell 1
 checkfreebounds result 0
 
diff --git a/tests/bugs/modalg_6/bug27651 b/tests/bugs/modalg_6/bug27651
new file mode 100644 (file)
index 0000000..64f47f3
--- /dev/null
@@ -0,0 +1,32 @@
+puts "========"
+puts "0027651: Modeling Algorithms - Add projection support in sewing pcurves handling"
+puts "========"
+puts ""
+
+
+restore [locate_data_file bug27531.brep] aS
+sewing result 0.2 aS
+
+# check result shape for validity.
+checkshape result
+
+# Check distances
+set MAX_DIST 3.0
+explode result E
+explode result F
+
+set log [xdistef result_3 result_1]
+regexp {Max Distance = +([-0-9.+eE]+); Parameter} ${log} full aDist
+if { $aDist > $MAX_DIST} {
+  puts "Error: First pcurve is too far from 3d curve"
+} else {
+  puts "OK: First pcurve is OK."
+}
+
+set log [xdistef result_3 result_2]
+regexp {Max Distance = +([-0-9.+eE]+); Parameter} ${log} full aDist
+if { $aDist > $MAX_DIST} {
+  puts "Error: Second pcurve is too far from 3d curve"
+} else {
+  puts "OK: Second pcurve is OK."
+}
index 59d1d4fd3c16d949eec0a4a4e5e4dcd184b545af..7e9311dd7a339047180c8b43c5f56c891258036c 100755 (executable)
@@ -29,7 +29,7 @@ if { ${face2} > ${face1} || ${edge2} > ${edge1} || ${vert2} > ${vert1} } {
     puts "Tolerance valed. Function FixShape works CORRECTLY"
 }
 
-checkmaxtol result -ref 1.59071e+000
+checkmaxtol result -ref 0.17775413987830679
 checknbshapes result -shell 1
 checkfreebounds result 227
 
index 3479f5ff904fa01b5def844ec4d964a474aa9cfd..7c3e6c3a44175bc8be49b7ab6781310934672ea5 100644 (file)
@@ -20,7 +20,7 @@ fit
 set bop_info [bopcurves f1 f2]
 regexp {Tolerance Reached=([-0-9.+eE]+)} $bop_info full Tolerance
 
-checkreal "Reached tolerance" ${Tolerance} 5.8654166482879483e-009 1.e-7 0
+checkreal "Reached tolerance" ${Tolerance} 5.8654392197230118e-09 1.e-7 0
 
 # 2 case
 set bop_info_2d [bopcurves f1 f2 -2d]
index 9471b1eb4db28f6a55bb4ad13ab6af1784dd236c..e117068d54865d562d7501678b7cc015cc10c5e9 100644 (file)
@@ -30,6 +30,6 @@ if {${NbCurv} != ${GoodNbCurv}} {
 }
 
 checklength c_1 -l 2.9620641619623407
-checklength c_2 -l 3.1050603628884668
+checklength c_2 -l 3.105060362884668
 
 checkview -screenshot -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
index aee1cbeca611f1313d9a03d1b08d2d35909f735b..1837b3275d37b75372c5383cbf3e5e7e0b17bd20 100644 (file)
@@ -1,4 +1,4 @@
-puts "TODO OCC23674 ALL: Error : Number of faults is"
+##puts "TODO OCC23674 ALL: Error : Number of faults is"
 
 restore [locate_data_file CFI_pro15441.rle] a
 
index 0268d88562f7eb7e6e2d929335332d938602246d..8f5045077fbf58529364d4f9623e5fd084c3e343 100755 (executable)
@@ -4,7 +4,7 @@ restore [locate_data_file CIN901_intcqhmi.rle] a
 
 sewing result $tol a
 
-checkmaxtol result -ref 1.91680e+001
+checkmaxtol result -ref 26.246606802805864
 checknbshapes result -shell 1
-checkfreebounds result 3
+checkfreebounds result 0
 checkfaults result a 6
index aa7901677a1b6bd24fa4acdeffac633b00086fbf..89e2b677015266045f200dd235a4af912f3706b6 100644 (file)
@@ -4,7 +4,7 @@ restore [locate_data_file CIN902_intcqhmn.rle] a
 
 sewing result $tol a
 
-checkmaxtol result -ref 31.117378506550729
+checkmaxtol result -ref 33.208410811730566
 checknbshapes result -shell 1
 checkfreebounds result 47
 checkfaults result a 7
index b6d95b07f17fb0d7822de99856df5fcadb770cbe..fc862d800c68e4b1dcfad2fdda3bd7b4cc1ea527 100644 (file)
@@ -4,7 +4,7 @@ restore [locate_data_file CIN902_intcqhmo.rle] a
 
 sewing result $tol a
 
-checkmaxtol result -ref 31.117378506550729
+checkmaxtol result -ref 33.208410811730566
 checknbshapes result -shell 1
 checkfreebounds result 47
 checkfaults result a 7