0025969: Wrong result obtained by 2d classifier algorithm.
authorpkv <pkv@opencascade.com>
Thu, 26 Mar 2015 12:41:00 +0000 (15:41 +0300)
committerapn <apn@opencascade.com>
Thu, 26 Mar 2015 15:10:23 +0000 (18:10 +0300)
Class IntTools_FClass2d
method:void IntTools_FClass2d::Init(const TopoDS_Face& aFace,const Standard_Real TolUV)
has been changed.
The cases where derivattive angles that are near to PI are considered as a sign to avoid express treatment for that wire

Test case for CR25969

src/BOPTest/BOPTest_LowCommands.cxx
src/IntTools/IntTools_FClass2d.cxx
tests/bugs/modalg_5/bug25969 [new file with mode: 0644]

index dd6eb64..205fe05 100644 (file)
@@ -40,6 +40,7 @@
 #include <DrawTrSurf.hxx>
 
 #include <BOPTools_AlgoTools2D.hxx>
+#include <IntTools_FClass2d.hxx>
 
 static
   void PrintState (Draw_Interpretor& aDI,
@@ -58,6 +59,7 @@ static
 
 static  Standard_Integer bclassify   (Draw_Interpretor& , Standard_Integer , const char** );
 static  Standard_Integer b2dclassify (Draw_Interpretor& , Standard_Integer , const char** );
+static  Standard_Integer b2dclassifx (Draw_Interpretor& , Standard_Integer , const char** );
 static  Standard_Integer bhaspc      (Draw_Interpretor& , Standard_Integer , const char** );
 
 //=======================================================================
@@ -73,44 +75,50 @@ static  Standard_Integer bhaspc      (Draw_Interpretor& , Standard_Integer , con
   const char* g = "BOPTest commands";
   theCommands.Add("bclassify"    , "use bclassify Solid Point [Tolerance=1.e-7]",
                   __FILE__, bclassify   , g);
-  theCommands.Add("b2dclassify"  , "use bclassify Face Point2d [Tol2D=Tol(Face)] ",
+  theCommands.Add("b2dclassify"  , "use b2dclassify Face Point2d [Tol] ",
                   __FILE__, b2dclassify , g);
+  theCommands.Add("b2dclassifx"  , "use b2dclassifx Face Point2d [Tol] ",
+                  __FILE__, b2dclassifx , g);
   theCommands.Add("bhaspc"       , "use bhaspc Edge Face [do]",
                   __FILE__, bhaspc      , g);
 }
 
+
+//
 //=======================================================================
-//function : bclassify
+//function : b2dclassifx
 //purpose  : 
 //=======================================================================
-Standard_Integer bclassify (Draw_Interpretor& theDI,
-                            Standard_Integer  theArgNb,
-                            const char**      theArgVec)
+Standard_Integer b2dclassifx (Draw_Interpretor& theDI,
+                              Standard_Integer  theArgNb,
+                              const char**      theArgVec)
 {
   if (theArgNb < 3)  {
-    theDI << " use bclassify Solid Point [Tolerance=1.e-7]\n";
+    theDI << " use b2dclassifx Face Point2d [Tol]\n";
     return 1;
   }
 
   TopoDS_Shape aS = DBRep::Get (theArgVec[1]);
   if (aS.IsNull())  {
-    theDI << " Null Shape is not allowed\n";
+    theDI << " Null Shape is not allowed here\n";
     return 1;
   }
-  else if (aS.ShapeType() != TopAbs_SOLID)  {
-    theDI << " Shape type must be SOLID\n";
+  else if (aS.ShapeType() != TopAbs_FACE)  {
+    theDI << " Shape type must be FACE\n";
     return 1;
   }
-
-  gp_Pnt aP (8., 9., 10.);
-  DrawTrSurf::GetPoint (theArgVec[2], aP);
+  TopAbs_State aState;
+  gp_Pnt2d aP (8., 9.);
+  //
+  DrawTrSurf::GetPoint2d (theArgVec[2], aP);
+  const TopoDS_Face&  aF   = TopoDS::Face(aS);
   const Standard_Real aTol = (theArgNb == 4) ? 
-    Draw::Atof (theArgVec[3]) : 1.e-7;
-
-  BRepClass3d_SolidClassifier aSC (aS);
-  aSC.Perform (aP,aTol);
-
-  PrintState (theDI, aSC.State());
+    Draw::Atof (theArgVec[3]) : BRep_Tool::Tolerance (aF);
+  //
+  IntTools_FClass2d aClassifier(aF, aTol);
+  aState=aClassifier.Perform(aP);
+  PrintState (theDI, aState);
+  //
   return 0;
 }
 //
@@ -123,7 +131,7 @@ Standard_Integer b2dclassify (Draw_Interpretor& theDI,
                               const char**      theArgVec)
 {
   if (theArgNb < 3)  {
-    theDI << " use bclassify Face Point2d [Tol2D=Tol(Face)]\n";
+    theDI << " use b2dclassify Face Point2d [Tol]\n";
     return 1;
   }
 
@@ -136,17 +144,53 @@ Standard_Integer b2dclassify (Draw_Interpretor& theDI,
     theDI << " Shape type must be FACE\n";
     return 1;
   }
-
+  //
   gp_Pnt2d aP (8., 9.);
+  //
   DrawTrSurf::GetPoint2d (theArgVec[2], aP);
   const TopoDS_Face&  aF   = TopoDS::Face(aS);
   const Standard_Real aTol = (theArgNb == 4) ? 
     Draw::Atof (theArgVec[3]) : BRep_Tool::Tolerance (aF);
-
+  
   BRepClass_FaceClassifier aClassifier;
   aClassifier.Perform(aF, aP, aTol);
-
   PrintState (theDI, aClassifier.State());
+  //
+  return 0;
+}
+
+//=======================================================================
+//function : bclassify
+//purpose  : 
+//=======================================================================
+Standard_Integer bclassify (Draw_Interpretor& theDI,
+                            Standard_Integer  theArgNb,
+                            const char**      theArgVec)
+{
+  if (theArgNb < 3)  {
+    theDI << " use bclassify Solid Point [Tolerance=1.e-7]\n";
+    return 1;
+  }
+
+  TopoDS_Shape aS = DBRep::Get (theArgVec[1]);
+  if (aS.IsNull())  {
+    theDI << " Null Shape is not allowed\n";
+    return 1;
+  }
+  else if (aS.ShapeType() != TopAbs_SOLID)  {
+    theDI << " Shape type must be SOLID\n";
+    return 1;
+  }
+
+  gp_Pnt aP (8., 9., 10.);
+  DrawTrSurf::GetPoint (theArgVec[2], aP);
+  const Standard_Real aTol = (theArgNb == 4) ? 
+    Draw::Atof (theArgVec[3]) : 1.e-7;
+
+  BRepClass3d_SolidClassifier aSC (aS);
+  aSC.Perform (aP,aTol);
+
+  PrintState (theDI, aSC.State());
   return 0;
 }
 
index a08e077..fbeff09 100644 (file)
@@ -58,8 +58,8 @@ IntTools_FClass2d::IntTools_FClass2d()
 //function : IntTools_FClass2d::IntTools_FClass2d
 //purpose  : 
 //=======================================================================
-  IntTools_FClass2d::IntTools_FClass2d(const TopoDS_Face& aFace,
-                                       const Standard_Real TolUV) 
+IntTools_FClass2d::IntTools_FClass2d(const TopoDS_Face& aFace,
+                                    const Standard_Real TolUV) 
 : Toluv(TolUV), Face(aFace)  
 {
   Init(Face, Toluv);
@@ -68,7 +68,7 @@ IntTools_FClass2d::IntTools_FClass2d()
 //function : IsHole
 //purpose  : 
 //=======================================================================
-  Standard_Boolean IntTools_FClass2d::IsHole() const
+Standard_Boolean IntTools_FClass2d::IsHole() const
 {
   return myIsHole;
 } 
@@ -76,8 +76,8 @@ IntTools_FClass2d::IntTools_FClass2d()
 //function : Init
 //purpose  : 
 //=======================================================================
-  void IntTools_FClass2d::Init(const TopoDS_Face& aFace,
-                               const Standard_Real TolUV) 
+void IntTools_FClass2d::Init(const TopoDS_Face& aFace,
+                            const Standard_Real TolUV) 
 {
   Standard_Boolean WireIsNotEmpty, Ancienpnt3dinitialise, degenerated;
   Standard_Integer nbpnts, firstpoint, NbEdges;
@@ -372,7 +372,10 @@ IntTools_FClass2d::IntTools_FClass2d()
       gp_Pnt2d anInitPnt(0., 0.);
       //
       PClass.Init(anInitPnt);
-      TabClass.Append((void *)new CSLib_Class2d(PClass,FlecheU,FlecheV,Umin,Vmin,Umax,Vmax));
+      TabClass.Append((void *)new CSLib_Class2d(PClass,
+                                               FlecheU,
+                                               FlecheV,
+                                               Umin,Vmin,Umax,Vmax));
       BadWire=1;
       TabOrien.Append(-1);
     }
@@ -392,8 +395,8 @@ IntTools_FClass2d::IntTools_FClass2d()
         //
         aS=0.;
         //
-
         Standard_Integer iFlag=1;
+       //
         PClass(im2)=SeqPnt2d.Value(im2);
         PClass(im1)=SeqPnt2d.Value(im1);
         PClass(nbpnts)=SeqPnt2d.Value(nbpnts);
@@ -423,13 +426,26 @@ IntTools_FClass2d::IntTools_FClass2d()
 
               Standard_Real aN = aVPrev.Magnitude() * aVNext.Magnitude();
               if(aN > 1e-16) { 
-                Standard_Real aDerivAngle = aVPrev.Angle(aVNext);
+                Standard_Real aDerivAngle, aAbsDA, aProduct, aPA;
                 //ifv 23.08.06
-                if(Abs(aDerivAngle) <= Precision::Angular()) aDerivAngle = 0.; 
+               aPA=Precision::Angular();
+               aDerivAngle = aVPrev.Angle(aVNext);
+               aAbsDA=Abs(aDerivAngle);
+                if(aAbsDA <= aPA) {
+                 aDerivAngle = 0.; 
+               }
+               //
+               aProduct=aDerivAngle * a;
+               //
+               if(Abs(aAbsDA - M_PI) <= aPA) {
+                 if (aProduct > 0.) {
+                   aProduct=-aProduct; 
+                 }
+               }
                 //ifv 23.08.06 : if edges continuity > G1, |aDerivAngle| ~0,
                 //but can has wrong sign and causes condition aDerivAngle * a < 0.
                 //that is wrong in such situation
-                if (iFlag && aDerivAngle * a < 0.) {
+                if (iFlag && aProduct < 0.) {
                   iFlag=0;
                   // Bad case.
                   angle = 0.;
@@ -452,7 +468,10 @@ IntTools_FClass2d::IntTools_FClass2d()
         if(FlecheV<Toluv)
           FlecheV = Toluv;
 
-        TabClass.Append((void *)new CSLib_Class2d(PClass,FlecheU,FlecheV,Umin,Vmin,Umax,Vmax));
+        TabClass.Append((void *)new CSLib_Class2d(PClass,
+                                                 FlecheU,
+                                                 FlecheV,
+                                                 Umin,Vmin,Umax,Vmax));
         //
         if((angle<2 && angle>-2)||(angle>10)||(angle<-10)) { 
           BadWire=1;
@@ -467,7 +486,10 @@ IntTools_FClass2d::IntTools_FClass2d()
         TabOrien.Append(-1);
         TColgp_Array1OfPnt2d PPClass(1,2);
         PPClass.Init(anInitPnt);
-        TabClass.Append((void *)new CSLib_Class2d(PPClass,FlecheU,FlecheV,Umin,Vmin,Umax,Vmax));
+        TabClass.Append((void *)new CSLib_Class2d(PPClass,
+                                                 FlecheU,
+                                                 FlecheV,
+                                                 Umin,Vmin,Umax,Vmax));
       }
     }// else if(WireIsNotEmpty)
   } // for(; aExpF.More();  aExpF.Next()) {
@@ -510,9 +532,10 @@ IntTools_FClass2d::IntTools_FClass2d()
 //function : PerformInfinitePoint
 //purpose  : 
 //=======================================================================
-  TopAbs_State IntTools_FClass2d::PerformInfinitePoint() const 
+TopAbs_State IntTools_FClass2d::PerformInfinitePoint() const 
 { 
-  if(Umax==-RealLast() || Vmax==-RealLast() || Umin==RealLast() || Vmin==RealLast()) { 
+  if(Umax==-RealLast() || Vmax==-RealLast() || 
+     Umin==RealLast() || Vmin==RealLast()) { 
     return(TopAbs_IN);
   }
   gp_Pnt2d P(Umin-(Umax-Umin),Vmin-(Vmax-Vmin));
@@ -522,8 +545,9 @@ IntTools_FClass2d::IntTools_FClass2d()
 //function : Perform
 //purpose  : 
 //=======================================================================
-  TopAbs_State IntTools_FClass2d::Perform(const gp_Pnt2d& _Puv,
-                                          const Standard_Boolean RecadreOnPeriodic) const
+TopAbs_State IntTools_FClass2d::Perform
+  (const gp_Pnt2d& _Puv,
+   const Standard_Boolean RecadreOnPeriodic) const
 { 
   Standard_Integer nbtabclass = TabClass.Length();
   if (nbtabclass == 0)
@@ -658,9 +682,10 @@ IntTools_FClass2d::IntTools_FClass2d()
 //function : TestOnRestriction
 //purpose  : 
 //=======================================================================
-  TopAbs_State IntTools_FClass2d::TestOnRestriction(const gp_Pnt2d& _Puv,
-                                                    const Standard_Real Tol,
-                                                    const Standard_Boolean RecadreOnPeriodic) const
+TopAbs_State IntTools_FClass2d::TestOnRestriction
+  (const gp_Pnt2d& _Puv,
+   const Standard_Real Tol,
+   const Standard_Boolean RecadreOnPeriodic) const
 { 
   Standard_Integer nbtabclass = TabClass.Length();
   if (nbtabclass == 0)
@@ -765,12 +790,11 @@ IntTools_FClass2d::IntTools_FClass2d()
       }
   } //for (;;)
 }
-
 //=======================================================================
 //function : Destroy
 //purpose  : 
 //=======================================================================
-  void IntTools_FClass2d::Destroy() 
+void IntTools_FClass2d::Destroy() 
 { 
   Standard_Integer nbtabclass = TabClass.Length(); 
   for(Standard_Integer d=1; d<=nbtabclass;d++) {
diff --git a/tests/bugs/modalg_5/bug25969 b/tests/bugs/modalg_5/bug25969
new file mode 100644 (file)
index 0000000..a672786
--- /dev/null
@@ -0,0 +1,37 @@
+puts "================"
+puts "CR25969"
+puts "================"
+puts ""
+###############################################
+## Wrong result obtained by 2d classifier algorithm.
+###############################################
+
+pload DCAF
+
+Open [locate_data_file bug25969_pal22851.sgd] D
+
+GetShape D 0:1:15:1:1:2 b1
+GetShape D 0:1:29:1:1:2 b2
+explode b1
+explode b2
+bop b1_2 b2_1
+bopcut r
+
+explode r f
+copy r_4 f
+pcurve f
+point p 12.658283198213592 21.045164979270297 
+set cls1 [b2dclassifx f p]
+if { [regexp {OUT} $cls1] } {
+    puts "Error : Wrong result of 2d classifier algorithm"
+} else {
+    puts "OK : Good result of 2d classifier algorithm"
+}
+
+smallview
+fit
+set only_screen_axo 1