]> OCCT Git - occt.git/commitdiff
0032715: Modelling Algorithms - UnifySameDomain does incomplete union
authorjgv <jgv@opencascade.com>
Mon, 14 Feb 2022 13:36:39 +0000 (16:36 +0300)
committersmoskvin <smoskvin@opencascade.com>
Thu, 17 Feb 2022 18:45:44 +0000 (21:45 +0300)
    Add the case of closed, smooth but not periodic surface (unification of faces lying on it if the flag "myConcatBSplines" is true - modify the underlying surface to make it periodic).

src/BRepLib/BRepLib.cxx
src/BRepLib/BRepLib.hxx
src/ChFi3d/ChFi3d.cxx
src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx
tests/bugs/heal/bug29382 [deleted file]
tests/bugs/heal/bug29382_1 [new file with mode: 0644]
tests/bugs/heal/bug29382_2 [new file with mode: 0644]
tests/bugs/heal/bug29382_3 [new file with mode: 0644]

index b956633f1c7c585083b00dffd4f3e2e715218125..a381c6c48c47364f6189519cc1cdc7a3af34c284 100644 (file)
@@ -1960,6 +1960,12 @@ public:
     return aDeriv.Transformed(mySurfaceTrsf);
   }
 
+  gp_Dir Normal()
+  {
+    gp_Dir aNormal = mySurfaceProps.Normal();
+    return aNormal.Transformed(mySurfaceTrsf);
+  }
+
   // Calculate principal curvatures, which consist of minimal and maximal normal curvatures and
   // the directions on the tangent plane (principal direction) where the extremums are reached
   void Curvature(gp_Dir& thePrincipalDir1, Standard_Real& theCurvature1,
@@ -1998,32 +2004,63 @@ private:
 //purpose  : check the angle at the border between two squares.
 //           Two shares should have a shared front edge.
 //=======================================================================
-static GeomAbs_Shape tgtfaces(const TopoDS_Edge& Ed,
-                              const TopoDS_Face& F1,
-                              const TopoDS_Face& F2,
-                              const Standard_Real theAngleTol)
+GeomAbs_Shape BRepLib::ContinuityOfFaces(const TopoDS_Edge&  theEdge,
+                                         const TopoDS_Face&  theFace1,
+                                         const TopoDS_Face&  theFace2,
+                                         const Standard_Real theAngleTol)
 {
-  Standard_Boolean isSeam = F1.IsEqual(F2);
-
-  TopoDS_Edge E = Ed;
+  Standard_Boolean isSeam = theFace1.IsEqual(theFace2);
 
-  // Check if pcurves exist on both faces of edge
-  Standard_Real aFirst,aLast;
-  E.Orientation(TopAbs_FORWARD);
-  Handle(Geom2d_Curve) aCurve1 = BRep_Tool::CurveOnSurface(E, F1, aFirst, aLast);
-  if(aCurve1.IsNull())
-    return GeomAbs_C0;
+  TopoDS_Edge anEdgeInFace1, anEdgeInFace2;
+  Handle(Geom2d_Curve) aCurve1, aCurve2;
+  
+  Standard_Real aFirst, aLast;
+  
+  if (!theFace1.IsSame (theFace2) &&
+      BRep_Tool::IsClosed (theEdge, theFace1) &&
+      BRep_Tool::IsClosed (theEdge, theFace2))
+  {
+    //Find the edge in the face 1: this edge will have correct orientation
+    TopoDS_Face aFace1 = theFace1;
+    aFace1.Orientation (TopAbs_FORWARD);
+    TopExp_Explorer anExplo (aFace1, TopAbs_EDGE);
+    for (; anExplo.More(); anExplo.Next())
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
+      if (anEdge.IsSame (theEdge))
+      {
+        anEdgeInFace1 = anEdge;
+        break;
+      }
+    }
+    if (anEdgeInFace1.IsNull())
+      return GeomAbs_C0;
+    
+    aCurve1 = BRep_Tool::CurveOnSurface (anEdgeInFace1, aFace1, aFirst, aLast);
+    TopoDS_Face aFace2 = theFace2;
+    aFace2.Orientation (TopAbs_FORWARD);
+    anEdgeInFace2 = anEdgeInFace1;
+    anEdgeInFace2.Reverse();
+    aCurve2 = BRep_Tool::CurveOnSurface (anEdgeInFace2, aFace2, aFirst, aLast);
+  }
+  else
+  {
+    // Obtaining of pcurves of edge on two faces.
+    anEdgeInFace1 = anEdgeInFace2 = theEdge;
+    aCurve1 = BRep_Tool::CurveOnSurface (anEdgeInFace1, theFace1, aFirst, aLast);
+    //For the case of seam edge
+    if (theFace1.IsSame(theFace2))
+      anEdgeInFace2.Reverse();
+    aCurve2 = BRep_Tool::CurveOnSurface (anEdgeInFace2, theFace2, aFirst, aLast);
+  }
 
-  if (isSeam)
-    E.Orientation(TopAbs_REVERSED);
-  Handle(Geom2d_Curve) aCurve2 = BRep_Tool::CurveOnSurface(E, F2, aFirst, aLast);
-  if(aCurve2.IsNull())
+  if (aCurve1.IsNull() || aCurve2.IsNull())
     return GeomAbs_C0;
 
   TopLoc_Location aLoc1, aLoc2;
-  Handle(Geom_Surface) aSurface1 = BRep_Tool::Surface(F1, aLoc1);
+  Handle(Geom_Surface) aSurface1 = BRep_Tool::Surface (theFace1, aLoc1);
   const gp_Trsf& aSurf1Trsf = aLoc1.Transformation();
-  Handle(Geom_Surface) aSurface2 = BRep_Tool::Surface(F2, aLoc2);
+  Handle(Geom_Surface) aSurface2 = BRep_Tool::Surface (theFace2, aLoc2);
   const gp_Trsf& aSurf2Trsf = aLoc2.Transformation();
 
   if (aSurface1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
@@ -2040,11 +2077,11 @@ static GeomAbs_Shape tgtfaces(const TopoDS_Edge& Ed,
     return GeomAbs_CN;
   }
 
-  SurfaceProperties aSP1(aSurface1, aSurf1Trsf, aCurve1, F1.Orientation() == TopAbs_REVERSED);
-  SurfaceProperties aSP2(aSurface2, aSurf2Trsf, aCurve2, F2.Orientation() == TopAbs_REVERSED);
+  SurfaceProperties aSP1(aSurface1, aSurf1Trsf, aCurve1, theFace1.Orientation() == TopAbs_REVERSED);
+  SurfaceProperties aSP2(aSurface2, aSurf2Trsf, aCurve2, theFace2.Orientation() == TopAbs_REVERSED);
 
   Standard_Real f, l, eps;
-  BRep_Tool::Range(E,f,l);
+  BRep_Tool::Range (theEdge,f,l);
   Extrema_LocateExtPC ext;
   Handle(BRepAdaptor_Curve) aHC2;
 
@@ -2055,7 +2092,6 @@ static GeomAbs_Shape tgtfaces(const TopoDS_Edge& Ed,
   const Standard_Real anAngleTol2 = theAngleTol * theAngleTol;
 
   gp_Vec aDer1, aDer2;
-  gp_Vec aNorm1;
   Standard_Real aSqLen1, aSqLen2;
   gp_Dir aCrvDir1[2], aCrvDir2[2];
   Standard_Real aCrvLen1[2], aCrvLen2[2];
@@ -2083,13 +2119,26 @@ static GeomAbs_Shape tgtfaces(const TopoDS_Edge& Ed,
     aDer2 = aSP2.Derivative();
     aSqLen2 = aDer2.SquareMagnitude();
     Standard_Boolean isSmoothSuspect = (aDer1.CrossSquareMagnitude(aDer2) <= anAngleTol2 * aSqLen1 * aSqLen2);
+    if (isSmoothSuspect)
+    {
+      gp_Dir aNormal1 = aSP1.Normal();
+      if (theFace1.Orientation() == TopAbs_REVERSED)
+        aNormal1.Reverse();
+      gp_Dir aNormal2 = aSP2.Normal();
+      if (theFace2.Orientation() == TopAbs_REVERSED)
+        aNormal2.Reverse();
+      
+      if (aNormal1 * aNormal2 < 0.)
+        return GeomAbs_C0;
+    }
+    
     if (!isSmoothSuspect)
     {
       // Refine by projection
       if (aHC2.IsNull())
       {
         // adaptor for pcurve on the second surface
-        aHC2 = new BRepAdaptor_Curve (E, F2);
+        aHC2 = new BRepAdaptor_Curve (anEdgeInFace2, theFace2);
         ext.Initialize(*aHC2, f, l, Precision::PConfusion());
       }
       ext.Perform(aSP1.Value(), u);
@@ -2285,9 +2334,8 @@ void BRepLib::EncodeRegularity(TopoDS_Edge& E,
   BRep_Builder B;
   if(BRep_Tool::Continuity(E,F1,F2)<=GeomAbs_C0){
     try {
-      GeomAbs_Shape aCont = tgtfaces(E, F1, F2, TolAng);
+      GeomAbs_Shape aCont = ContinuityOfFaces(E, F1, F2, TolAng);
       B.Continuity(E,F1,F2,aCont);
-      
     }
     catch(Standard_Failure const&)
     {
index 85d8c6d267a8b8e6de7a627078bd576b1ab09a40..1acb765bfc9bc48e0376b610715ef71b5f020a97 100644 (file)
@@ -202,7 +202,14 @@ public:
   //! orientation to have  matter in the solid. Returns
   //! False if the solid is unOrientable (open or incoherent)
   Standard_EXPORT static Standard_Boolean OrientClosedSolid (TopoDS_Solid& solid);
-  
+
+  //! Returns the order of continuity between two faces
+  //! connected by an edge
+  Standard_EXPORT static GeomAbs_Shape ContinuityOfFaces(const TopoDS_Edge&  theEdge,
+                                                         const TopoDS_Face&  theFace1,
+                                                         const TopoDS_Face&  theFace2,
+                                                         const Standard_Real theAngleTol);
+
   //! Encodes the Regularity of edges on a Shape.
   //! Warning: <TolAng> is an angular tolerance, expressed in Rad.
   //! Warning: If the edges's regularity are coded before, nothing
index d9c03e4d9f18cfbc6484190ef453664b98ca1149..82d87ebd62935409cb3524729d286991056eaa1d 100644 (file)
@@ -134,12 +134,12 @@ ChFiDS_TypeOfConcavity ChFi3d::DefineConnectType(const TopoDS_Edge&     E,
 //function : IsTangentFaces
 //purpose  : 
 //=======================================================================
-Standard_Boolean ChFi3d::IsTangentFaces(const TopoDS_Edge& theEdge,
-                                        const TopoDS_Face& theFace1,
-                                        const TopoDS_Face& theFace2,
-                                        const GeomAbs_Shape Order)
+Standard_Boolean ChFi3d::IsTangentFaces(const TopoDS_Edge&  theEdge,
+                                        const TopoDS_Face&  theFace1,
+                                        const TopoDS_Face&  theFace2,
+                                        const GeomAbs_Shape theOrder)
 {
-  if (Order == GeomAbs_G1 && BRep_Tool::Continuity(theEdge, theFace1, theFace2) != GeomAbs_C0)
+  if (theOrder == GeomAbs_G1 && BRep_Tool::Continuity(theEdge, theFace1, theFace2) != GeomAbs_C0)
     return Standard_True;
 
   Standard_Real TolC0 = Max(0.001, 1.5*BRep_Tool::Tolerance(theEdge));
@@ -147,15 +147,46 @@ Standard_Boolean ChFi3d::IsTangentFaces(const TopoDS_Edge& theEdge,
   Standard_Real aFirst;
   Standard_Real aLast;
 
-  // Obtaining of pcurves of edge on two faces.
-  const Handle(Geom2d_Curve) aC2d1 = BRep_Tool::CurveOnSurface
-    (theEdge, theFace1, aFirst, aLast);
-  //For the case of seam edge
-  TopoDS_Edge EE = theEdge;
-  if (theFace1.IsSame(theFace2))
-    EE.Reverse();
-  const Handle(Geom2d_Curve) aC2d2 = BRep_Tool::CurveOnSurface
-    (EE, theFace2, aFirst, aLast);
+  Handle(Geom2d_Curve) aC2d1, aC2d2;
+  
+  if (!theFace1.IsSame (theFace2) &&
+      BRep_Tool::IsClosed (theEdge, theFace1) &&
+      BRep_Tool::IsClosed (theEdge, theFace2))
+  {
+    //Find the edge in the face 1: this edge will have correct orientation
+    TopoDS_Edge anEdgeInFace1;
+    TopoDS_Face aFace1 = theFace1;
+    aFace1.Orientation (TopAbs_FORWARD);
+    TopExp_Explorer anExplo (aFace1, TopAbs_EDGE);
+    for (; anExplo.More(); anExplo.Next())
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
+      if (anEdge.IsSame (theEdge))
+      {
+        anEdgeInFace1 = anEdge;
+        break;
+      }
+    }
+    if (anEdgeInFace1.IsNull())
+      return Standard_False;
+    
+    aC2d1 = BRep_Tool::CurveOnSurface (anEdgeInFace1, aFace1, aFirst, aLast);
+    TopoDS_Face aFace2 = theFace2;
+    aFace2.Orientation (TopAbs_FORWARD);
+    anEdgeInFace1.Reverse();
+    aC2d2 = BRep_Tool::CurveOnSurface (anEdgeInFace1, aFace2, aFirst, aLast);
+  }
+  else
+  {
+    // Obtaining of pcurves of edge on two faces.
+    aC2d1 = BRep_Tool::CurveOnSurface (theEdge, theFace1, aFirst, aLast);
+    //For the case of seam edge
+    TopoDS_Edge EE = theEdge;
+    if (theFace1.IsSame(theFace2))
+      EE.Reverse();
+    aC2d2 = BRep_Tool::CurveOnSurface (EE, theFace2, aFirst, aLast);
+  }
+  
   if (aC2d1.IsNull() || aC2d2.IsNull())
     return Standard_False;
 
@@ -186,15 +217,19 @@ Standard_Boolean ChFi3d::IsTangentFaces(const TopoDS_Edge& theEdge,
     if (i == aNbSamples) aPar = aLast;
 
     LocalAnalysis_SurfaceContinuity aCont(aC2d1, aC2d2, aPar,
-      aSurf1, aSurf2, Order,
+      aSurf1, aSurf2, theOrder,
       0.001, TolC0, 0.1, 0.1, 0.1);
     if (!aCont.IsDone())
     {
+      if (theOrder == GeomAbs_C2 &&
+          aCont.StatusError() == LocalAnalysis_NullSecondDerivative)
+        continue;
+      
       nbNotDone++;
       continue;
     }
 
-    if (Order == GeomAbs_G1)
+    if (theOrder == GeomAbs_G1)
     {
       if (!aCont.IsG1())
         return Standard_False;
index f9185088b202e25ea005f29fd26868a259efe934..bd314351b581d5f74732fc552471801382142011 100644 (file)
@@ -46,6 +46,7 @@
 #include <Geom_TrimmedCurve.hxx>
 #include <GeomAdaptor_Surface.hxx>
 #include <GeomConvert.hxx>
+#include <GeomConvert_ApproxSurface.hxx>
 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
 #include <GeomLib_IsPlanarSurface.hxx>
 #include <gp_Cylinder.hxx>
@@ -1212,7 +1213,31 @@ static Standard_Boolean GetNormalToSurface(const TopoDS_Face& theFace,
 {
   Standard_Real f, l;
   // get 2d curve to get point in 2d
-  const Handle(Geom2d_Curve)& aC2d = BRep_Tool::CurveOnSurface(theEdge, theFace, f, l);
+  Handle(Geom2d_Curve) aC2d;
+  if (BRep_Tool::IsClosed(theEdge, theFace))
+  {
+    //Find the edge in the face: it will have correct orientation
+    TopoDS_Edge anEdgeInFace;
+    TopoDS_Face aFace = theFace;
+    aFace.Orientation (TopAbs_FORWARD);
+    TopExp_Explorer anExplo (aFace, TopAbs_EDGE);
+    for (; anExplo.More(); anExplo.Next())
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
+      if (anEdge.IsSame (theEdge))
+      {
+        anEdgeInFace = anEdge;
+        break;
+      }
+    }
+    if (anEdgeInFace.IsNull())
+      return Standard_False;
+
+    aC2d = BRep_Tool::CurveOnSurface (anEdgeInFace, aFace, f, l);
+  }
+  else
+    aC2d = BRep_Tool::CurveOnSurface(theEdge, theFace, f, l);
+  
   if (aC2d.IsNull()) {
     return Standard_False;
   }
@@ -2965,29 +2990,107 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
       TopTools_IndexedDataMapOfShapeListOfShape VEmap;
       for (Standard_Integer ind = 1; ind <= edges.Length(); ind++)
         TopExp::MapShapesAndUniqueAncestors(edges(ind), TopAbs_VERTEX, TopAbs_EDGE, VEmap);
-      
-      //Perform relocating to new U-origin
-      //Define boundaries in 2d space of RefFace
-      if (Uperiod != 0.)
+
+      //Try to find seam edge and an edge that is not seam but has 2 pcurves on the surface
+      Standard_Boolean SeamFound = Standard_False;
+      TopoDS_Edge EdgeWith2pcurves;
+      for (Standard_Integer ii = 1; ii <= faces.Length(); ii++)
       {
-        //try to find a real seam edge - if it exists, do nothing
-        Standard_Boolean SeamFound = Standard_False;
-        for (Standard_Integer ii = 1; ii <= faces.Length(); ii++)
+        const TopoDS_Face& face_ii = TopoDS::Face(faces(ii));
+        TopoDS_Wire anOuterWire = BRepTools::OuterWire(face_ii);
+        TopoDS_Iterator itw(anOuterWire);
+        for (; itw.More(); itw.Next())
         {
-          const TopoDS_Face& face_ii = TopoDS::Face(faces(ii));
-          TopoDS_Wire anOuterWire = BRepTools::OuterWire(face_ii);
-          TopoDS_Iterator itw(anOuterWire);
-          for (; itw.More(); itw.Next())
+          const TopoDS_Edge& anEdge = TopoDS::Edge(itw.Value());
+          if (BRep_Tool::IsClosed (anEdge, face_ii))
           {
-            const TopoDS_Edge& anEdge = TopoDS::Edge(itw.Value());
             if (BRepTools::IsReallyClosed(anEdge, face_ii))
-            {
               SeamFound = Standard_True;
-              break;
+            else
+              EdgeWith2pcurves = anEdge;
+          }
+        }
+      }
+
+      Standard_Boolean aIsEdgeWith2pcurvesSmooth = Standard_False;
+      if (myConcatBSplines && !EdgeWith2pcurves.IsNull() && !SeamFound)
+      {
+        const TopTools_ListOfShape& aFaceList = theGMapEdgeFaces.FindFromKey (EdgeWith2pcurves);
+        const TopoDS_Face& aFace1 = TopoDS::Face (aFaceList.First());
+        const TopoDS_Face& aFace2 = TopoDS::Face (aFaceList.Last());
+        GeomAbs_Shape anOrderOfCont = BRepLib::ContinuityOfFaces (EdgeWith2pcurves,
+                                                                  aFace1, aFace2,
+                                                                  myAngTol);
+        aIsEdgeWith2pcurvesSmooth = (anOrderOfCont >= GeomAbs_G1);
+      }
+
+      if (aIsEdgeWith2pcurvesSmooth)
+      {
+        Handle(Geom2d_Curve) aPC1, aPC2;
+        Standard_Real aFirst, aLast;
+        aPC1 = BRep_Tool::CurveOnSurface (EdgeWith2pcurves, F_RefFace, aFirst, aLast);
+        EdgeWith2pcurves.Reverse();
+        aPC2 = BRep_Tool::CurveOnSurface (EdgeWith2pcurves, F_RefFace, aFirst, aLast);
+        gp_Pnt2d aPnt1 = aPC1->Value (aFirst);
+        gp_Pnt2d aPnt2 = aPC2->Value (aFirst);
+        Standard_Boolean anIsUclosed = (Abs(aPnt1.X() - aPnt2.X()) > Abs(aPnt1.Y() - aPnt2.Y()));
+        Standard_Boolean aToMakeUPeriodic = Standard_False, aToMakeVPeriodic = Standard_False;
+        if (anIsUclosed && Uperiod == 0.)
+          aToMakeUPeriodic = Standard_True;
+        if (!anIsUclosed && Vperiod == 0.)
+          aToMakeVPeriodic = Standard_True;
+
+        if (aToMakeUPeriodic || aToMakeVPeriodic)
+        {
+          Handle(Geom_BSplineSurface) aBSplineSurface = Handle(Geom_BSplineSurface)::DownCast(aBaseSurface);
+          if (aBSplineSurface.IsNull())
+          {
+            Standard_Real aTol = 1.e-4;
+            GeomAbs_Shape aUCont = GeomAbs_C1, aVCont = GeomAbs_C1;
+            Standard_Integer degU = 14, degV = 14;
+            Standard_Integer nmax = 16;
+            Standard_Integer aPrec = 1;  
+            GeomConvert_ApproxSurface Approximator(aBaseSurface,aTol,aUCont,aVCont,degU,degV,nmax,aPrec);
+            aBSplineSurface = Approximator.Surface();
+          }
+          
+          if (aToMakeUPeriodic)
+          {
+            aBSplineSurface->SetUPeriodic();
+            Uperiod = aBSplineSurface->UPeriod();
+          }
+          if (aToMakeVPeriodic)
+          {
+            aBSplineSurface->SetVPeriodic();
+            Vperiod = aBSplineSurface->VPeriod();
+          }
+
+          //Update ref face and pcurves if the surface changed
+          if (aBSplineSurface != aBaseSurface)
+          {
+            TopoDS_Face OldRefFace = RefFace;
+            Handle(Geom2d_Curve) NullPCurve;
+            RefFace.Nullify();
+            BB.MakeFace(RefFace, aBSplineSurface, aBaseLocation, 0.);
+            for (Standard_Integer ii = 1; ii <= edges.Length(); ii++)
+            {
+              TopoDS_Edge anEdge = TopoDS::Edge(edges(ii));
+              Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface (anEdge, OldRefFace, aFirst, aLast);
+              if (MapEdgesWithTemporaryPCurves.Contains(anEdge))
+                BB.UpdateEdge(anEdge, NullPCurve, OldRefFace, 0.);
+              BB.UpdateEdge(anEdge, aPCurve, RefFace, 0.);
             }
+            F_RefFace = RefFace;
+            F_RefFace.Orientation(TopAbs_FORWARD);
           }
         }
-        
+      } //if (myConcatBSplines && !EdgeWith2pcurves.IsNull() && !SeamFound)
+      
+      //Perform relocating to new U-origin
+      //Define boundaries in 2d space of RefFace
+      if (Uperiod != 0.)
+      {
+        //if seam edge exists, do nothing
         if (!SeamFound)
         {
           //try to find the origin of U in 2d space
diff --git a/tests/bugs/heal/bug29382 b/tests/bugs/heal/bug29382
deleted file mode 100644 (file)
index a380585..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-puts "================================================================================"
-puts "OCC29382: ShapeUpgrade_UnifySameDomain algorithm incorrectly processes the shape"
-puts "================================================================================"
-puts ""
-
-restore [locate_data_file bug29382_Group_3.brep] a
-
-unifysamedom result a
-
-checkshape result
-checkshape a
-
-checknbshapes result -solid 3 -shell 3 -face 18 -wire 18 -edge 36 -vertex 22
-
-set tolres [checkmaxtol result]
-
-if { ${tolres} > 1.8066863810061599e-05} {
-   puts "Error: bad tolerance of result"
-}
-
-explode result
-checkprops result_1 -v 4.41996e-06
-checkprops result_2 -v 1.30453e-06
-checkprops result_3 -v 1.16532e-06
diff --git a/tests/bugs/heal/bug29382_1 b/tests/bugs/heal/bug29382_1
new file mode 100644 (file)
index 0000000..a380585
--- /dev/null
@@ -0,0 +1,24 @@
+puts "================================================================================"
+puts "OCC29382: ShapeUpgrade_UnifySameDomain algorithm incorrectly processes the shape"
+puts "================================================================================"
+puts ""
+
+restore [locate_data_file bug29382_Group_3.brep] a
+
+unifysamedom result a
+
+checkshape result
+checkshape a
+
+checknbshapes result -solid 3 -shell 3 -face 18 -wire 18 -edge 36 -vertex 22
+
+set tolres [checkmaxtol result]
+
+if { ${tolres} > 1.8066863810061599e-05} {
+   puts "Error: bad tolerance of result"
+}
+
+explode result
+checkprops result_1 -v 4.41996e-06
+checkprops result_2 -v 1.30453e-06
+checkprops result_3 -v 1.16532e-06
diff --git a/tests/bugs/heal/bug29382_2 b/tests/bugs/heal/bug29382_2
new file mode 100644 (file)
index 0000000..e9a6d47
--- /dev/null
@@ -0,0 +1,24 @@
+puts "================================================================================"
+puts "OCC29382: ShapeUpgrade_UnifySameDomain algorithm incorrectly processes the shape"
+puts "================================================================================"
+puts ""
+
+restore [locate_data_file bug29382_Group_3.brep] a
+
+unifysamedom result a +b
+
+checkshape result
+checkshape a
+
+checknbshapes result -solid 3 -shell 3 -face 16 -wire 16 -edge 30 -vertex 18
+
+set tolres [checkmaxtol result]
+
+if { ${tolres} > 1.8066863810061599e-05} {
+   puts "Error: bad tolerance of result"
+}
+
+explode result
+checkprops result_1 -v 4.41996e-06
+checkprops result_2 -v 1.30453e-06
+checkprops result_3 -v 1.16532e-06
diff --git a/tests/bugs/heal/bug29382_3 b/tests/bugs/heal/bug29382_3
new file mode 100644 (file)
index 0000000..6fcd5a6
--- /dev/null
@@ -0,0 +1,24 @@
+puts "================================================================================"
+puts "OCC29382: ShapeUpgrade_UnifySameDomain algorithm incorrectly processes the shape"
+puts "================================================================================"
+puts ""
+
+beziercurve a 5  0 0 0  1 0 0  2 2 0  0 0.5 0  0 0 0
+mkedge a a
+wire a a
+mkplane a a
+prism a a 0 0 1
+box b -0.3 -0.2 0  1 0.4 1
+bcommon shape a b
+
+unifysamedom result shape +b
+
+checkshape result
+
+checknbshapes result -solid 1 -shell 1 -face 5 -wire 5 -edge 9 -vertex 5
+
+set tolres [checkmaxtol result]
+
+if { ${tolres} > 6.e-6} {
+   puts "Error: bad tolerance of result"
+}