0023587: Operation "2dintersect "in TestHarness can not find intersection point of...
authorgka <gka@opencascade.com>
Fri, 14 Dec 2012 12:38:05 +0000 (16:38 +0400)
committergka <gka@opencascade.com>
Fri, 14 Dec 2012 12:40:05 +0000 (16:40 +0400)
Modified DRAW command "2dintersect" added optional parameter "tolerance for intersection".
Test case for bug 0023587 : Check intersections of four 2d curves
Adding test cases for this fix
Deleting temporary test case

src/GeomliteTest/GeomliteTest_API2dCommands.cxx
src/IntCurve/IntCurve_IntPolyPolyGen.cdl
src/IntCurve/IntCurve_IntPolyPolyGen.gxx
tests/bugs/moddata/bug23587 [new file with mode: 0755]

index 391f6c238ea63c51bf5886497095a7bd2e9f4514..44ad2eda1333821b379138f54bf01d019fa8d058 100755 (executable)
@@ -278,12 +278,15 @@ static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const
 //purpose  : 
 //=======================================================================
 
-static Standard_Integer intersect(Draw_Interpretor& /*di*/, Standard_Integer n, const char** a)
+static Standard_Integer intersect(Draw_Interpretor& di, Standard_Integer n, const char** a)
 {
   if( n < 2) 
+  {
+    cout<< "2dintersect curve curve [Tol]"<<endl;
     return 1;
-
-  Handle(Geom2d_Curve) C1 = DrawTrSurf::GetCurve2d(a[1]);
+  }
+  Standard_Integer k = 1;
+  Handle(Geom2d_Curve) C1 = DrawTrSurf::GetCurve2d(a[k++]);
   if ( C1.IsNull()) 
     return 1;
 
@@ -291,10 +294,16 @@ static Standard_Integer intersect(Draw_Interpretor& /*di*/, Standard_Integer n,
   Geom2dAPI_InterCurveCurve Intersector;
 
   Handle(Geom2d_Curve) C2;
-  if ( n == 3) {
-    C2 = DrawTrSurf::GetCurve2d(a[2]);
+  if ( k < n ) {
+    C2 = DrawTrSurf::GetCurve2d(a[k++]);
     if ( C2.IsNull())
       return 1;
+  }
+  if(k < n)
+    Tol = atof(a[k]);
+
+  if(!C2.IsNull())
+  {
     Intersector.Init(C1,C2,Tol);
   }
   else {
@@ -305,6 +314,7 @@ static Standard_Integer intersect(Draw_Interpretor& /*di*/, Standard_Integer n,
 
   for ( i = 1; i <= Intersector.NbPoints(); i++) {
     gp_Pnt2d P = Intersector.Point(i);
+    di<<"Intersection point "<<i<<" : "<<P.X()<<" "<<P.Y()<<"\n";
     Handle(Draw_Marker2D) mark = new Draw_Marker2D( P, Draw_X, Draw_vert); 
     dout << mark;
   }
@@ -312,15 +322,14 @@ static Standard_Integer intersect(Draw_Interpretor& /*di*/, Standard_Integer n,
 
   Handle(Geom2d_Curve) S1,S2;
   Handle(DrawTrSurf_Curve2d) CD;
-  if ( n == 3) {
-    for ( i = 1; i <= Intersector.NbSegments(); i++) {
-      Intersector.Segment(i,S1,S2);
-      CD = new DrawTrSurf_Curve2d(S1, Draw_bleu, 30);
-      dout << CD;
-      CD = new DrawTrSurf_Curve2d(S2, Draw_violet, 30);
-      dout << CD;
-    }
+  for ( i = 1; i <= Intersector.NbSegments(); i++) {
+    Intersector.Segment(i,S1,S2);
+    CD = new DrawTrSurf_Curve2d(S1, Draw_bleu, 30);
+    dout << CD;
+    CD = new DrawTrSurf_Curve2d(S2, Draw_violet, 30);
+    dout << CD;
   }
+  
   dout.Flush();
 
   return 0;
@@ -353,6 +362,6 @@ void GeomliteTest::API2dCommands(Draw_Interpretor& theCommands)
 
   g = "GEOMETRY intersections";
 
-  theCommands.Add("2dintersect", "intersect curve curve",__FILE__,
+  theCommands.Add("2dintersect", "intersect curve curve [Tol]",__FILE__,
                  intersect,g);
 }
index f6c5fc72162ed70490c542ef18861e2214915e73..04f303f1b6e0f9dad9c3957e2cc5eae0b58f91c5 100755 (executable)
@@ -144,7 +144,27 @@ is
            DeltaU :    Real        from Standard;
            DeltaV :    Real        from Standard)
           
-           is static protected;    
+           is static protected; 
+           
+       findIntersect( me: in out ;
+           Curve1 :    TheCurve;
+           Domain1:    Domain      from IntRes2d;
+           Curve2 :    TheCurve;
+           Domain2:    Domain      from IntRes2d;
+                  TolConf:    Real        from Standard;
+              Tol    :    Real        from Standard;
+           NbIter :    Integer     from Standard;
+           DeltaU :    Real        from Standard;
+           DeltaV :    Real        from Standard;
+         thePoly1 :  ThePolygon2d  from  IntCurve; 
+             thePoly2 :  ThePolygon2d  from  IntCurve;
+             isFullRepresentation : Boolean from Standard)
+             returns Boolean is private;  
+             ---Purpose : Method to find intersection between two curves
+             --         :  returns false for case when some points of polygon
+             --         : were replaced on line and exact point of intersection was not found
+             --         : for case when point of intersection was found
+             --         : during prelimanary search for line (case of bad paramerization of Bspline for example). 
     
 fields    
 
index 7019fad8073db01a15c7bd5c852f4d088251b3f4..0fb97a7db8e58ae03e06bbabbe82478d73c61bbe 100755 (executable)
@@ -49,6 +49,7 @@
 #include <math_Vector.hxx>
 #include <math_FunctionSetRoot.hxx>
 #include <math_NewtonFunctionSetRoot.hxx>
+#include <NCollection_Handle.hxx>
 
 //======================================================================
 
@@ -731,11 +732,8 @@ void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
                                      ,const Standard_Real DeltaU
                                      ,const Standard_Real DeltaV) {
 
-  gp_Vec2d Tan1,Tan2,Norm1,Norm2;
-  gp_Pnt2d P1,P2;
   Standard_Integer nbsamplesOnC1,nbsamplesOnC2;
   done = Standard_False;
-  Standard_Boolean AnErrorOccurred = Standard_False;
 
   if(NbIter>NBITER_MAX_POLYGON) return;
 
@@ -767,29 +765,30 @@ void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
     }
   /////////////////////////////////////////////
 
-  IntCurve_ThePolygon2d *PtrPoly1,*PtrPoly2;
+  
+  NCollection_Handle<IntCurve_ThePolygon2d> aPoly1 ,aPoly2;
   if(nbsamplesOnC2 > nbsamplesOnC1) { 
-    PtrPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol);  
-    if(PtrPoly1->DeflectionOverEstimation() < TolConf) { 
-      PtrPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol);
+    aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol);  
+    if(aPoly1->DeflectionOverEstimation() < TolConf) { 
+      aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol);
     }
     else { 
-      PtrPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol,PtrPoly1->Bounding());
-      PtrPoly1->SetDeflectionOverEstimation( PtrPoly2->DeflectionOverEstimation()
-                                           +PtrPoly1->DeflectionOverEstimation());
-      PtrPoly1->ComputeWithBox(C1,PtrPoly2->Bounding());
+      aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol,aPoly1->Bounding());
+      aPoly1->SetDeflectionOverEstimation( aPoly2->DeflectionOverEstimation()
+                                           + aPoly1->DeflectionOverEstimation());
+      aPoly1->ComputeWithBox(C1,aPoly2->Bounding());
     }
   }
   else { 
-    PtrPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol);  
-    if(PtrPoly2->DeflectionOverEstimation() < TolConf) {
-      PtrPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol);
+    aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol);  
+    if(aPoly2->DeflectionOverEstimation() < TolConf) {
+      aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol);
     }
     else { 
-      PtrPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol,PtrPoly2->Bounding());
-      PtrPoly2->SetDeflectionOverEstimation( PtrPoly2->DeflectionOverEstimation()
-                                           +PtrPoly1->DeflectionOverEstimation());
-      PtrPoly2->ComputeWithBox(C2,PtrPoly1->Bounding());
+      aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol,aPoly2->Bounding());
+      aPoly2->SetDeflectionOverEstimation( aPoly2->DeflectionOverEstimation()
+                                           + aPoly1->DeflectionOverEstimation());
+      aPoly2->ComputeWithBox(C2,aPoly1->Bounding());
     }
   }
   //----------------------------------------------------------------------
@@ -798,13 +797,64 @@ void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
   //-- (Detection des Zones de Tangence)
   //----------------------------------------------------------------------
 
-  if(PtrPoly1->DeflectionOverEstimation() < TolConf) { 
-    PtrPoly1->SetDeflectionOverEstimation(TolConf);
+  if(aPoly1->DeflectionOverEstimation() < TolConf) { 
+    aPoly1->SetDeflectionOverEstimation(TolConf);
   }
-  if(PtrPoly2->DeflectionOverEstimation() < TolConf) { 
-    PtrPoly2->SetDeflectionOverEstimation(TolConf);
+  if(aPoly2->DeflectionOverEstimation() < TolConf) { 
+    aPoly2->SetDeflectionOverEstimation(TolConf);
+  }
+  //for case when a few polygon points were replaced by line
+  //if exact solution was not found 
+  //then search of precise solution will be repeat 
+  //for polygon conatins all initial points
+  //secondary search will be performed only for case when initial points
+  //were dropped
+  Standard_Boolean isFullRepresentation = ( aPoly1->NbSegments() == nbsamplesOnC1 && 
+           aPoly2->NbSegments() == nbsamplesOnC2 );
+  
+  if( !findIntersect( C1, D1, C2, D2, TolConf, Tol, NbIter,
+         DeltaU, DeltaV, *aPoly1, *aPoly2, isFullRepresentation ) && !isFullRepresentation ) 
+  {
+       if(aPoly1->NbSegments() < nbsamplesOnC1)
+       {
+         aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol);
+       }
+       if(aPoly2->NbSegments() < nbsamplesOnC2)
+       {
+         aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol);
+       }
+       
+       findIntersect( C1, D1, C2, D2, TolConf, Tol, NbIter,
+         DeltaU, DeltaV, *aPoly1, *aPoly2, 
+         Standard_True);       
+       
   }
-  Intf_InterferencePolygon2d InterPP(*PtrPoly1,*PtrPoly2);  
+  done = Standard_True;
+}
+
+//======================================================================
+// Purpose :
+//======================================================================
+
+Standard_Boolean IntCurve_IntPolyPolyGen::findIntersect( 
+    const TheCurve& C1,
+       const IntRes2d_Domain& D1,
+       const TheCurve& C2,
+       const IntRes2d_Domain& D2,
+       const Standard_Real TolConf,
+       const Standard_Real Tol,
+       const Standard_Integer NbIter,
+       const Standard_Real DeltaU,
+       const Standard_Real DeltaV,
+       const IntCurve_ThePolygon2d& thePoly1,
+       const IntCurve_ThePolygon2d& thePoly2,
+       Standard_Boolean isFullPolygon )
+{
+
+  gp_Vec2d Tan1,Tan2,Norm1,Norm2;
+  gp_Pnt2d P1,P2;
+  Intf_InterferencePolygon2d InterPP(thePoly1,thePoly2);  
   IntCurve_ExactIntersectionPoint  EIP(C1,C2,TolConf);
   Standard_Real U,V;
   
@@ -812,19 +862,21 @@ void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
   //-- Traitement des SectionPoint 
   //----------------------------------------------------------------------
   Standard_Integer Nbsp = InterPP.NbSectionPoints();
-
-  if(Nbsp>=1) {
-    for(Standard_Integer sp=1; sp <= Nbsp; sp++) {
-      const Intf_SectionPoint& SPnt = InterPP.PntValue(sp);
-      Standard_Integer SegIndex1,SegIndex2;
-      Standard_Real    ParamOn1,ParamOn2;
-      Intf_PIType      Type;
-
-      SPnt.InfoFirst(Type,SegIndex1,ParamOn1);
-      SPnt.InfoSecond(Type,SegIndex2,ParamOn2);
-      EIP.Perform(*PtrPoly1,*PtrPoly2,SegIndex1,SegIndex2,ParamOn1,ParamOn2);
-      AnErrorOccurred = EIP.AnErrorOccurred();
-      if(EIP.NbRoots()>=1) { 
+    
+  for(Standard_Integer sp=1; sp <= Nbsp; sp++) {
+       const Intf_SectionPoint& SPnt = InterPP.PntValue(sp);
+    Standard_Integer SegIndex1,SegIndex2;
+    Standard_Real    ParamOn1,ParamOn2;
+    Intf_PIType      Type;
+
+    SPnt.InfoFirst(Type,SegIndex1,ParamOn1);
+    SPnt.InfoSecond(Type,SegIndex2,ParamOn2);
+    EIP.Perform(thePoly1,thePoly2,SegIndex1,SegIndex2,ParamOn1,ParamOn2);
+    //AnErrorOccurred = EIP.AnErrorOccurred();
+    if( !EIP.NbRoots() && !isFullPolygon)
+      return Standard_False;
+      
+     
        //--------------------------------------------------------------------
        //-- On verifie que le point trouve est bien une racine
        //--------------------------------------------------------------------
@@ -881,11 +933,8 @@ void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
          IntRes2d_IntersectionPoint IP(P1,U,V,Trans1,Trans2,Standard_False);
          Insert(IP);
        }
-      } //-- if(EIP.NbRoots()>=1)
-    }
   }
   
-
   //----------------------------------------------------------------------
   //-- Traitement des TangentZone
   //----------------------------------------------------------------------
@@ -918,14 +967,14 @@ void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
       Standard_Real _PolyUInf,_PolyVInf;
 
       SPnt1.InfoFirst(Type,SegIndex1onP1,ParamOnLine);
-      if(SegIndex1onP1 >= PtrPoly1->NbSegments()) { SegIndex1onP1--; ParamOnLine = 1.0; }
+      if(SegIndex1onP1 >= thePoly1.NbSegments()) { SegIndex1onP1--; ParamOnLine = 1.0; }
       if(SegIndex1onP1 <= 0) { SegIndex1onP1=1; ParamOnLine = 0.0; }
-      _PolyUInf = PtrPoly1->ApproxParamOnCurve(SegIndex1onP1,ParamOnLine);
+      _PolyUInf = thePoly1.ApproxParamOnCurve(SegIndex1onP1,ParamOnLine);
       
       SPnt1.InfoSecond(Type,SegIndex1onP2,ParamOnLine);
-      if(SegIndex1onP2 >= PtrPoly2->NbSegments()) { SegIndex1onP2--; ParamOnLine = 1.0; }
+      if(SegIndex1onP2 >= thePoly2.NbSegments()) { SegIndex1onP2--; ParamOnLine = 1.0; }
       if(SegIndex1onP2 <= 0) { SegIndex1onP2=1; ParamOnLine = 0.0; }
-      _PolyVInf = PtrPoly2->ApproxParamOnCurve(SegIndex1onP2,ParamOnLine);
+      _PolyVInf = thePoly2.ApproxParamOnCurve(SegIndex1onP2,ParamOnLine);
       
       //----------------------------------------------------------------------
 
@@ -953,8 +1002,8 @@ void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
 
     
 
-    if(  (  (PtrPoly1->DeflectionOverEstimation() > TolConf)
-           ||(PtrPoly2->DeflectionOverEstimation() > TolConf))
+    if(  (  (thePoly1.DeflectionOverEstimation() > TolConf)
+           ||(thePoly2.DeflectionOverEstimation() > TolConf))
         &&(NbIter<NBITER_MAX_POLYGON)) {
       
       IntRes2d_Domain RecursD1( TheCurveTool::Value(C1,ParamInfOnCurve1)
@@ -965,7 +1014,7 @@ void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
                               ,ParamInfOnCurve2,TolConf
                               ,TheCurveTool::Value(C2,ParamSupOnCurve2)
                               ,ParamSupOnCurve2,TolConf);
-      //-- On ne delete pas PtrPoly1(2) ,
+      //-- On ne delete pas thePoly1(2) ,
       //-- ils sont detruits enfin de fct. 
       //-- !! Pas de return intempestif !!
       Perform(C1,RecursD1,C2,RecursD2,Tol,TolConf,NbIter+1,DeltaU,DeltaV);
@@ -1081,9 +1130,6 @@ void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
       }
     }
   }
-  //----------------------------------------------------------------------
-  delete PtrPoly1;
-  delete PtrPoly2;
-  done = Standard_True;
+ return Standard_True;
 }
 
diff --git a/tests/bugs/moddata/bug23587 b/tests/bugs/moddata/bug23587
new file mode 100755 (executable)
index 0000000..2e08383
--- /dev/null
@@ -0,0 +1,36 @@
+puts "============"
+puts "CR23587"
+puts "==========="
+puts ""
+###############################################################################
+# Operation "2dintersect "in TestHarness can not find intersection point of two intersecting 2d curves.
+###############################################################################
+
+restore [locate_data_file bug23587_IntEdges.brep] a
+
+explode a 
+
+plane pl1 0 0 0 0 0 1
+trim trpl1 pl1 -1000 1000 -1000 1000
+mkface f1 trpl1
+pcurve c1 a_1 f1
+pcurve c2 a_2 f1
+pcurve c3 a_3 f1
+pcurve c4 a_4 f1
+set inter1 [2dintersect c1 c2 1.e-6]
+set inter2 [2dintersect c3 c2 1.e-6]
+set inter3 [2dintersect c1 c4 1.e-6]
+set inter4 [2dintersect c3 c4 1.e-6]
+set int1 [regexp {Intersection point 1} $inter1]
+set int2 [regexp {Intersection point 1} $inter2]
+set int3 [regexp {Intersection point 1} $inter3]
+set int4 [regexp {Intersection point 1} $inter4]
+
+if { $int1 == 0 || $int2 == 0 || $int3 == 0 || $int4 ==0 } {
+    puts "Error : Intersection is not found"
+} 
+
+av2d
+2dfit
+
+xwd ${imagedir}/${test_image}.png