]> OCCT Git - occt-copy.git/commitdiff
27117: BRepClass3d_SolidClassifier doesn't take into account vertex/edge/face tolerances
authorisn <isn@opencascade.com>
Tue, 15 Mar 2016 13:38:11 +0000 (16:38 +0300)
committernbv <nbv@opencascade.com>
Fri, 16 Sep 2016 13:14:30 +0000 (16:14 +0300)
3D-claasifier now takes into the account the vertex/edges tolerances. If the given point lays inside the tolerance area of vertex or edge of the solid it's classified as TopAbs_ON.
The behavior of IntCurvesFace_Intersector::Perform was changed. Now it may use optional null-tolerance to classify 2d-point relatively to the given face.
UBTreeFiller is used to speedup intersection process between edges/vertices and the point.
The test case 'boolean gdml_private ZH2' extensively uses the SolidClassifier. After this fix it returns the correct classification statuses, which leads to incorrect result shape (reported by checkshape). Yet the result shape without this fix also seems to be incorrect (one of the isolines goes out of boundary of the face). Thats why it's marked with 'TODO'.

Various improvements in point-solid classifier:

1) Refactoring.
2) BndBoxTree is extracted into separate class.
3) UB-tree calculation is cashed to improve point-solid classification speed.
4) Ray / curve intersection improved by trimmed parameters and correct order.
5) Fixes in logic.
6) Calculation caching at the classifier level.

(cherry picked from commit ccba18e5bd7c21351acd9c29fcb43dc537fd5028)

Task GEOM-03-025: Point classification issue

12 files changed:
src/BRepClass3d/BRepClass3d.cdl
src/BRepClass3d/BRepClass3d_BndBoxTree.cxx [new file with mode: 0644]
src/BRepClass3d/BRepClass3d_BndBoxTree.hxx [new file with mode: 0644]
src/BRepClass3d/BRepClass3d_SClassifier.cxx
src/BRepClass3d/BRepClass3d_SolidExplorer.cdl
src/BRepClass3d/BRepClass3d_SolidExplorer.cxx
src/BRepClass3d/FILES [new file with mode: 0644]
src/IntCurvesFace/IntCurvesFace_Intersector.cdl
src/IntCurvesFace/IntCurvesFace_Intersector.cxx
src/TopOpeBRepTool/FILES
src/TopOpeBRepTool/TopOpeBRepTool.cdl
src/TopOpeBRepTool/TopOpeBRepTool_IndexedDataMapOfSolidClassifier.hxx [new file with mode: 0644]

index 73f9f7b74f7c24c807f21db5ee4d408e4e94de0e..a01f3f2955a70d3aa2d085efbbbdc36cbea7b97b 100644 (file)
@@ -33,22 +33,24 @@ uses
 
 
 is
-
+    
+    imported BndBoxTree;
     class Intersector3d;
+    class SolidExplorer;
+    class SClassifier;
+    class SolidClassifier;
 
     class MapOfInter instantiates  
        DataMap from TCollection(Shape          from TopoDS,
                                Address        from Standard,
                                 ShapeMapHasher from TopTools);
 
-    class SolidExplorer;
+    
         
     class SolidPassiveClassifier instantiates  
        Classifier3d from TopClass  (Intersector3d  from BRepClass3d);
 
-    class SClassifier;       
 
-    class SolidClassifier;
        
     OuterShell(S : Solid from TopoDS)  
            returns Shell from TopoDS;
diff --git a/src/BRepClass3d/BRepClass3d_BndBoxTree.cxx b/src/BRepClass3d/BRepClass3d_BndBoxTree.cxx
new file mode 100644 (file)
index 0000000..a573225
--- /dev/null
@@ -0,0 +1,139 @@
+// Copyright (c) 1994-1999 Matra Datavision
+// Copyright (c) 1999-2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepClass3d_BndBoxTree.hxx>
+
+#include <TopoDS.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <Extrema_ExtPC.hxx>
+#include <Extrema_ExtCC.hxx>
+
+
+//=======================================================================
+//function : Accept
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepClass3d_BndBoxTreeSelectorPoint::Accept (const Standard_Integer& theObj)
+{
+  // Box-point collision.
+  if (theObj > myMapOfShape.Extent())
+    return Standard_False;
+  const TopoDS_Shape& shp = myMapOfShape(theObj);
+  TopAbs_ShapeEnum sht = shp.ShapeType();
+  if (sht == TopAbs_EDGE)
+  {
+    const TopoDS_Edge& E = TopoDS::Edge(shp);
+    Standard_Real EdgeTSq  = BRep_Tool::Tolerance(E);
+    EdgeTSq *= EdgeTSq;
+    Standard_Real f, l;
+    BRepAdaptor_Curve C(E);
+    BRep_Tool::Range(E,f,l);
+
+    // Edge-Point interference.
+    Extrema_ExtPC ExtPC(myP, C, f, l );
+    if (ExtPC.IsDone() && ExtPC.NbExt() > 0)
+    { 
+      for (Standard_Integer i = 1; i <= ExtPC.NbExt(); i++)
+        if (ExtPC.SquareDistance(i) < EdgeTSq)
+        {
+          myStop = 1; //exit from selector
+          return Standard_True;
+        }
+    }        
+  }
+  else if (sht == TopAbs_VERTEX)
+  {
+    const TopoDS_Vertex &V = TopoDS::Vertex(shp);
+    gp_Pnt VPnt = BRep_Tool::Pnt(V);
+    Standard_Real VertTSq = BRep_Tool::Tolerance(V);
+    VertTSq *= VertTSq; 
+    // Vertex-Point interference.
+    if (VPnt.SquareDistance(myP) < VertTSq)
+    {
+      myStop = 1;
+      return Standard_True;
+    }
+  }
+  return Standard_False;
+}
+
+//=======================================================================
+//function : Accept
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepClass3d_BndBoxTreeSelectorLine::Accept (const Standard_Integer& theObj)
+{
+  //box-line collision
+  if (theObj > myMapOfShape.Extent())
+    return Standard_False;
+  const TopoDS_Shape& shp = myMapOfShape(theObj);
+  TopAbs_ShapeEnum sht = shp.ShapeType();
+  if (sht == TopAbs_EDGE)
+  {
+    const TopoDS_Edge& E = TopoDS::Edge(shp);
+    Standard_Real EdgeTSq  = BRep_Tool::Tolerance(E);
+    EdgeTSq *= EdgeTSq;
+    Standard_Real f, l;
+    BRepAdaptor_Curve C(E);
+    BRep_Tool::Range(E,f,l);
+
+    // Edge-Line interference.
+    Extrema_ExtCC ExtCC(C, myLC, f, l, myLC.FirstParameter(), myLC.LastParameter());
+    if (ExtCC.IsDone() && ExtCC.NbExt() > 0)
+    { 
+      Standard_Boolean IsInside = Standard_False;
+      for (Standard_Integer i = 1; i <= ExtCC.NbExt(); i++)
+      {
+        if (ExtCC.SquareDistance(i) < EdgeTSq)
+        {
+          Extrema_POnCurv P1, P2;
+          ExtCC.Points(i,P1, P2);
+
+          EdgeParam EP;
+          EP.myE = E;
+          EP.myParam = P1.Parameter(); // Original curve is the first parameter.
+          EP.myLParam = P2.Parameter(); // Linear curve is the second parameter.
+
+          myEP.Append(EP);
+          IsInside = Standard_True;
+        }
+      }
+      if (IsInside)
+        return Standard_True;
+    }
+  }
+  else if (sht == TopAbs_VERTEX)
+  {
+    const TopoDS_Vertex &V = TopoDS::Vertex(shp);
+    Standard_Real VertTSq = BRep_Tool::Tolerance(V);
+    VertTSq *= VertTSq;
+    // Vertex-Line interference.
+    Extrema_ExtPElC ExtPL(BRep_Tool::Pnt(V), myL, Precision::Confusion(), -Precision::Infinite(), Precision::Infinite());
+    if (ExtPL.IsDone() && ExtPL.NbExt() > 0)
+      if (ExtPL.SquareDistance(1) < VertTSq)
+      {
+        Extrema_POnCurv PP;
+        Standard_Real paramL;
+        PP = ExtPL.Point(1);
+        paramL = PP.Parameter();
+        VertParam VP;
+        VP.myV = V;
+        VP.myLParam = paramL;
+        myVP.Append(VP);
+        return Standard_True;
+      }
+  }
+  return Standard_False;
+}
\ No newline at end of file
diff --git a/src/BRepClass3d/BRepClass3d_BndBoxTree.hxx b/src/BRepClass3d/BRepClass3d_BndBoxTree.hxx
new file mode 100644 (file)
index 0000000..8f6174d
--- /dev/null
@@ -0,0 +1,152 @@
+// Copyright (c) 1994-1999 Matra Datavision
+// Copyright (c) 1999-2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepClass3d_BndBoxTree_HeaderFile
+#define _BRepClass3d_BndBoxTree_HeaderFile
+
+
+#include <NCollection_Sequence.hxx>
+#include <NCollection_UBTreeFiller.hxx>
+#include <NCollection_UBTree.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <BRepBndLib.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <Geom_Line.hxx>
+#include <Bnd_Box.hxx>
+#include <gp_Lin.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <Precision.hxx>
+
+// Typedef to reduce code complexity.
+typedef NCollection_UBTree <Standard_Integer, Bnd_Box> BRepClass3d_BndBoxTree;
+
+// Class representing tree selector for point object.
+class BRepClass3d_BndBoxTreeSelectorPoint : public BRepClass3d_BndBoxTree::Selector
+{
+public:
+  BRepClass3d_BndBoxTreeSelectorPoint(const TopTools_IndexedMapOfShape& theMapOfShape)
+    : BRepClass3d_BndBoxTreeSelectorPoint::Selector(), myMapOfShape (theMapOfShape)
+  {}
+
+  Standard_Boolean Reject (const Bnd_Box& theBox) const
+  {
+    return (theBox.IsOut (myP));
+  }
+
+  Standard_Boolean Accept (const Standard_Integer& theObj);
+
+  // Sets current point for boxes-point collisions.
+  void SetCurrentPoint (const gp_Pnt& theP) 
+  { 
+    myP = theP;
+  }
+
+private:
+  BRepClass3d_BndBoxTreeSelectorPoint(const BRepClass3d_BndBoxTreeSelectorPoint& );
+  BRepClass3d_BndBoxTreeSelectorPoint& operator=(const BRepClass3d_BndBoxTreeSelectorPoint& );
+
+private:
+  const TopTools_IndexedMapOfShape& myMapOfShape; //shapes (vertices + edges)
+  gp_Pnt myP;
+};
+
+// Class representing tree selector for line object.
+class BRepClass3d_BndBoxTreeSelectorLine : public BRepClass3d_BndBoxTree::Selector
+{
+public:
+
+  struct EdgeParam
+  {
+    TopoDS_Edge myE;
+    Standard_Real myParam; //par on myE
+    Standard_Real myLParam; //par on line
+  };
+
+  struct VertParam
+  {
+    TopoDS_Vertex myV;
+    Standard_Real myLParam; //par on line
+  };
+
+
+public:
+  BRepClass3d_BndBoxTreeSelectorLine(const TopTools_IndexedMapOfShape& theMapOfShape) 
+    : BRepClass3d_BndBoxTreeSelectorLine::Selector(), myMapOfShape (theMapOfShape)
+  {}
+
+  Standard_Boolean Reject (const Bnd_Box& theBox) const
+  {
+    return (theBox.IsOut (myL));
+  }
+
+  Standard_Boolean Accept (const Standard_Integer& theObj);
+
+  //Sets current line for boxes-line collisions
+  void SetCurrentLine (const gp_Lin& theL,
+                       const Standard_Real theMaxParam) 
+  {
+    myL = theL;
+    myLC.Load(new Geom_Line(theL), -Precision::PConfusion(), theMaxParam);
+  }
+  
+  void GetEdgeParam(const Standard_Integer i,
+                    TopoDS_Edge& theOutE,
+                    Standard_Real &theOutParam,
+                    Standard_Real &outLParam ) const
+  {
+    const EdgeParam& EP = myEP.Value(i);
+    theOutE = EP.myE;
+    theOutParam = EP.myParam;
+    outLParam = EP.myLParam;
+  }
+
+  void GetVertParam(const Standard_Integer i,
+                    TopoDS_Vertex& theOutV,
+                    Standard_Real &outLParam ) const
+  {
+    const VertParam& VP = myVP.Value(i);
+    theOutV = VP.myV;
+    outLParam = VP.myLParam;
+  }
+
+  Standard_Integer GetNbEdgeParam() const
+  {
+    return myEP.Length();
+  }
+
+  Standard_Integer GetNbVertParam() const
+  {
+    return myVP.Length();
+  }
+
+  void ClearResults()
+  {
+    myEP.Clear();
+    myVP.Clear();
+  }
+
+private:
+  BRepClass3d_BndBoxTreeSelectorLine(const BRepClass3d_BndBoxTreeSelectorLine& );
+  BRepClass3d_BndBoxTreeSelectorLine& operator=(const BRepClass3d_BndBoxTreeSelectorLine& );
+
+private:
+  const TopTools_IndexedMapOfShape& myMapOfShape; //shapes (vertices + edges)
+  gp_Lin myL;
+  NCollection_Sequence<EdgeParam> myEP; //output result (edge vs line)
+  NCollection_Sequence<VertParam> myVP; //output result (vertex vs line)
+  GeomAdaptor_Curve myLC;
+};
+
+#endif
index 8334fb2b5d6d104c461d410d65388787ea824bb0..ba397f74c7dddbfe8ccf5446ab7e608b6747a576 100644 (file)
 
 #include <IntCurvesFace_Intersector.hxx>
 // modified by NIZHNY-MKK  Mon Jun 21 15:13:40 2004
-#include <Precision.hxx>
-#include <ElCLib.hxx>
-#include <Geom_Surface.hxx>
-#include <BRep_Tool.hxx>
+#include <Standard_DomainError.hxx>
+#include <TopoDS.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopExp.hxx>
 #include <math_RealRandom.hxx>
-#include <BRepTopAdaptor_FClass2d.hxx>
+#include <BRep_Tool.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom2d_Curve.hxx>
+#include <ElCLib.hxx>
 
 #include <vector>
 
+// modified by NIZHNY-MKK  Mon Jun 21 15:13:40 2004
 static
   Standard_Boolean FaceNormal (const TopoDS_Face& aF,
                                const Standard_Real U,
@@ -44,7 +50,14 @@ static
 static 
   Standard_Real GetAddToParam(const gp_Lin& L,const Standard_Real P,const Bnd_Box& B);
 
+//gets transition of line <L> passing through/near the edge <e> of faces <f1>, <f2>. <param> is
+// a parameter on the edge where the minimum distance between <l> and <e> was found 
+static Standard_Integer GetTransi(const TopoDS_Face& f1, const TopoDS_Face& f2, const TopoDS_Edge e, 
+                     Standard_Real param, const Geom_Line& L, IntCurveSurface_TransitionOnCurve& trans);
+
+static Standard_Boolean GetNormalOnFaceBound(const TopoDS_Edge& E, const TopoDS_Face& F, Standard_Real param, gp_Dir& OutDir);
 
+static void Trans(Standard_Real parmin, IntCurveSurface_TransitionOnCurve& tran, int& state);
 
 //=======================================================================
 //function : BRepClass3d_SClassifier
@@ -100,80 +113,76 @@ void BRepClass3d_SClassifier::PerformInfinitePoint(BRepClass3d_SolidExplorer& aS
   gp_Pnt aPoint;
   gp_Dir aDN;
 
-  math_RealRandom aRandomGenerator(0.1, 0.9);
+  math_RealRandom RandomGenerator(0.1, 0.9);
   myFace.Nullify();
   myState=2;
 
-  // Collect faces in sequence to iterate
-  std::vector<TopoDS_Face> aFaces;
-  for (aSE.InitShell(); aSE.MoreShell(); aSE.NextShell())
+  aSE.InitShell();
+  if (aSE.MoreShell())
   {
-    for (aSE.InitFace(); aSE.MoreFace(); aSE.NextFace())
+    aSE.InitFace();
+    if (aSE.MoreFace())
     {
-      aFaces.push_back (aSE.CurrentFace());
-    }
-  }
-
-  // iteratively try up to 10 probing points from each face
-  const int NB_MAX_POINTS_PER_FACE = 10;
-  for (int itry = 0; itry < NB_MAX_POINTS_PER_FACE; itry++)
-  {
-    for (std::vector<TopoDS_Face>::iterator iFace = aFaces.begin(); iFace != aFaces.end(); ++iFace)
-    {
-      TopoDS_Face aF = *iFace;
-
+      TopoDS_Face aF = aSE.CurrentFace();
       TopAbs_State aState = TopAbs_OUT;
       IntCurveSurface_TransitionOnCurve aTransition = IntCurveSurface_Tangent;
-
-      aParam = 0.1 + 0.8 * aRandomGenerator.Next(); // random number in range [0.1, 0.9]
-      bFound = aSE.FindAPointInTheFace(aF, aPoint, aU, aV, aParam);
-      if (!bFound || !FaceNormal(aF, aU, aV, aDN))
-        continue;
-
-      gp_Lin aLin(aPoint, -aDN);
-      Standard_Real parmin = RealLast();
-      for (aSE.InitShell();aSE.MoreShell();aSE.NextShell()) { 
-        if (aSE.RejectShell(aLin) == Standard_False) { 
-          for (aSE.InitFace();aSE.MoreFace(); aSE.NextFace()) {
-            if (aSE.RejectFace(aLin) == Standard_False) { 
-              TopoDS_Shape aLocalShape = aSE.CurrentFace();
-              TopoDS_Face CurFace = TopoDS::Face(aLocalShape);
-              IntCurvesFace_Intersector& Intersector3d = aSE.Intersector(CurFace);
-              Intersector3d.Perform(aLin,-RealLast(),parmin); 
-
-              if(Intersector3d.IsDone()) {
-                if(Intersector3d.NbPnt()) { 
-                  Standard_Integer imin = 1;
-                  for (Standard_Integer i = 2; i <= Intersector3d.NbPnt(); i++)
-                    if (Intersector3d.WParameter(i) < Intersector3d.WParameter(imin))
-                      imin = i;
-                  parmin = Intersector3d.WParameter(imin);
-                  aState = Intersector3d.State(imin);
-                  aTransition = Intersector3d.Transition(imin);
+      TopoDS_Face MinFace = aF;
+      for (;;)
+      {
+        aParam = RandomGenerator.Next();
+       bFound = aSE.FindAPointInTheFace(aF, aPoint, aU, aV, aParam);
+       if (!bFound)
+         return;
+
+        if (!FaceNormal(aF, aU, aV, aDN))
+          continue;
+        gp_Lin aLin(aPoint, -aDN);
+        Standard_Real parmin = RealLast();
+        for (aSE.InitShell();aSE.MoreShell();aSE.NextShell()) { 
+          if (aSE.RejectShell(aLin) == Standard_False) { 
+            for (aSE.InitFace();aSE.MoreFace(); aSE.NextFace()) {
+              if (aSE.RejectFace(aLin) == Standard_False) { 
+                TopoDS_Shape aLocalShape = aSE.CurrentFace();
+                TopoDS_Face CurFace = TopoDS::Face(aLocalShape);
+                IntCurvesFace_Intersector& Intersector3d = aSE.Intersector(CurFace);
+                Intersector3d.Perform(aLin,-RealLast(),parmin); 
+                
+                if(Intersector3d.IsDone()) {
+                  if(Intersector3d.NbPnt()) { 
+                    Standard_Integer imin = 1;
+                    for (Standard_Integer i = 2; i <= Intersector3d.NbPnt(); i++)
+                      if (Intersector3d.WParameter(i) < Intersector3d.WParameter(imin))
+                        imin = i;
+                    parmin = Intersector3d.WParameter(imin);
+                    aState = Intersector3d.State(imin);
+                    aTransition = Intersector3d.Transition(imin);
+                    MinFace = CurFace;
+                  }
                 }
               }
             }
           }
-        }
-        else
-          myState = 1;
-      } //end of loop on the whole solid
+          else
+            myState = 1;
+        } //end of loop on the whole solid
         
-      if (aState == TopAbs_IN)
-      {
-        if (aTransition == IntCurveSurface_Out) { 
-          //-- The line is going from inside the solid to outside 
-          //-- the solid.
-          myState = 3; //-- IN --
-          return;
-        }
-        else if (aTransition == IntCurveSurface_In) { 
-          myState = 4; //-- OUT --
-          return;
+        if (aState == TopAbs_IN)
+        {
+          if (aTransition == IntCurveSurface_Out) { 
+            //-- The line is going from inside the solid to outside 
+            //-- the solid.
+            myState = 3; //-- IN --
+            return;
+          }
+          else if (aTransition == IntCurveSurface_In) { 
+            myState = 4; //-- OUT --
+            return;
+          }
         }
+        aF = MinFace;
       }
-    } // iteration by faces
-  } // iteration by points
+    } //if (aSE.MoreFace())
+  } //if (aSE.MoreShell())
 }
 
 //=======================================================================
@@ -181,230 +190,263 @@ void BRepClass3d_SClassifier::PerformInfinitePoint(BRepClass3d_SolidExplorer& aS
 //purpose  : 
 //=======================================================================
 void BRepClass3d_SClassifier::Perform(BRepClass3d_SolidExplorer& SolidExplorer,
-                                     const gp_Pnt&  P,
-                                     const Standard_Real Tol) 
+                                      const gp_Pnt&  P,
+                                      const Standard_Real Tol)
 { 
+  if(SolidExplorer.Reject(P))
+  {
+    // Solid without faces => the whole space. Always in.
+    myState = 3; // IN
+    return;
+  }
 
+  const BRepClass3d_BndBoxTree & aTree = SolidExplorer.GetTree();
+  const TopTools_IndexedMapOfShape & aMapEV = SolidExplorer.GetMapEV();
 
-  if(SolidExplorer.Reject(P)) { 
-    myState=3; //-- in ds solid case without face 
+  // Vertices/Edges vs Point.
+  BRepClass3d_BndBoxTreeSelectorPoint aSelectorPoint(aMapEV);
+  aSelectorPoint.SetCurrentPoint(P);
+
+  Standard_Integer SelsVE = 0;
+  SelsVE = aTree.Select(aSelectorPoint); 
+
+  if (SelsVE > 0)
+  {
+    // The point P lays inside the tolerance area of vertices/edges => return ON state.
+    myState = 2; // ON.
     return;
   }
 
+  TopTools_IndexedDataMapOfShapeListOfShape mapEF;
+  TopExp::MapShapesAndAncestors(SolidExplorer.GetShape(), TopAbs_EDGE, TopAbs_FACE, mapEF);
+  
+  BRepClass3d_BndBoxTreeSelectorLine aSelectorLine(aMapEV);
 
   myFace.Nullify();
   myState = 0;
-  if(SolidExplorer.Reject(P) == Standard_False) { 
-    gp_Lin L;
-    Standard_Real Par;
-    //-- We compute the intersection betwwen the line builded in the Solid Explorer
-    //-- and the shape.
-
-    //-- --------------------------------------------------------------------------------
-    //-- Calculate intersection with the face closest to the direction of bounding boxes 
-    //-- by priority so that to have the smallest possible parmin. 
-    //-- optimization to produce as much as possible rejections with other faces. 
-    Standard_Integer iFlag;
-    //
-
-    //  Modified by skv - Thu Sep  4 11:22:05 2003 OCC578 Begin
-    //  If found line passes through a bound of any face, it means that the line
-    //  is not found properly and it is necessary to repeat whole procedure.
-    //  That's why the main loop while is added.
-    Standard_Boolean isFaultyLine = Standard_True;
-    Standard_Integer anIndFace    = 0;
-    Standard_Real    parmin = 0.;
-
-    while (isFaultyLine) {
-      if (anIndFace == 0) {
-       iFlag = SolidExplorer.Segment(P,L,Par);
-      } else {
-       iFlag = SolidExplorer.OtherSegment(P,L,Par);
-      }
 
-      Standard_Integer aCurInd = SolidExplorer.GetFaceSegmentIndex();
+  gp_Lin L;
+  Standard_Real Par;
+
+  // We compute the intersection between the line built in the Solid Explorer and the shape.
+  //-- --------------------------------------------------------------------------------
+  // Calculate intersection with the face closest to the direction of bounding boxes 
+  // by priority so that to have the smallest possible parmin.
+  // Optimization to produce as much as possible rejections with other faces.
+  Standard_Integer iFlag;
+
+  // If found line passes through a bound of any face, it means that the line
+  // is not found properly and it is necessary to repeat whole procedure.
+  // That's why the main loop while is added.
+  Standard_Boolean isFaultyLine = Standard_True;
+  Standard_Integer anIndFace    = 0;
+  Standard_Real    parmin = 0.0;
+  while (isFaultyLine)
+  {
+    if (anIndFace == 0)
+      iFlag = SolidExplorer.Segment(P,L,Par);
+    else
+      iFlag = SolidExplorer.OtherSegment(P,L,Par);
 
-      if (aCurInd > anIndFace) {
-       anIndFace = aCurInd;
-      } else {
-       myState = 1;
+    Standard_Integer aCurInd = SolidExplorer.GetFaceSegmentIndex();
 
-       return;
-      }
-      //  Modified by skv - Thu Sep  4 11:22:10 2003 OCC578 End
+    if (aCurInd > anIndFace)
+      anIndFace = aCurInd;
+    else
+    {
+      myState = 1; // Faulty.
+      return;
+    }
 
-      if (iFlag==1) {
-       // IsOnFace
-       // iFlag==1 i.e face is Infinite
-       myState=2; 
+    if (iFlag==1)
+    {
+      // IsOnFace iFlag==1 i.e face is Infinite
+      myState = 2; // ON.
+      return;
+    }
+    if (iFlag == 2) 
+    {
+      myState = 4; // OUT.
+      return;
+    }
 
-       return;
+    // Check if the point is ON surface but OUT of the face.
+    // Just skip this face because it is bad for classification.
+    if (iFlag == 3)
+      continue;
+
+    isFaultyLine = Standard_False;
+    parmin = RealLast();
+
+    Standard_Real NearFaultPar = RealLast(); // Parameter on line.
+    aSelectorLine.ClearResults();
+    aSelectorLine.SetCurrentLine(L, Par);
+    Standard_Integer SelsEVL = 0;
+    SelsEVL = aTree.Select(aSelectorLine); //SelsEE > 0 => Line/Edges & Line/Vertex intersection
+    if (SelsEVL > 0 )
+    {    
+      // Line and edges / vertices interference.
+      Standard_Integer VLInterNb = aSelectorLine.GetNbVertParam();
+      TopoDS_Vertex NearIntVert;
+      TopTools_MapOfShape LVInts;
+      for (Standard_Integer i = 1; i <= VLInterNb; i++)
+      {
+        // Line and vertex.
+        Standard_Real LP = 0;
+        TopoDS_Vertex V;
+        aSelectorLine.GetVertParam(i, V, LP);
+
+        LVInts.Add(V);
+        if (Abs(LP) < Abs(NearFaultPar))
+          NearFaultPar = LP;
       }
-      //SolidExplorer.Segment(P,L,Par);
-      //
-      //process results from uncorrected shells
-      //
-      //if(Par > 1.e+100 && L.Direction().IsParallel(gp_Dir(0.,0.,1.),1.e-8)) {
-      if (iFlag==2) {
-       myState = 4;
-       return;
+
+      Standard_Real param = 0.0;
+      TopoDS_Edge EE;
+      Standard_Real Lpar = RealLast();
+      for (Standard_Integer i = 1; i <= aSelectorLine.GetNbEdgeParam(); i++)
+      {
+        // Line and edge.
+        aSelectorLine.GetEdgeParam(i, EE, param, Lpar);
+        const TopTools_ListOfShape& ffs = mapEF.FindFromKey(EE); //ffs size == 2
+        if (ffs.Extent() != 2)
+          continue;
+        TopoDS_Face f1 = TopoDS::Face(ffs.First());
+        TopoDS_Face f2 = TopoDS::Face(ffs.Last());
+        IntCurveSurface_TransitionOnCurve tran;
+        TopoDS_Vertex V1, V2;
+        TopExp::Vertices(EE, V1, V2);
+        if (LVInts.Contains(V1) || LVInts.Contains(V2))
+          continue;
+        Standard_Integer Tst = GetTransi(f1, f2, EE, param, L, tran);
+        if (Tst == 1 && Abs(Lpar) < Abs(parmin))
+        {
+          parmin = Lpar;
+          Trans(parmin, tran, myState);
+        }
+        else if (Abs(Lpar) < Abs(NearFaultPar))
+          NearFaultPar = Lpar;
       }
-      //-- BRepClass3d_Intersector3d Intersector3d;
-    
-      //  Modified by skv - Thu Sep  4 13:48:27 2003 OCC578 Begin
-      // Check if the point is ON surface but OUT of the face. 
-      // Just skip this face because it is bad for classification.
-      if (iFlag == 3)
-       continue;
-
-      isFaultyLine = Standard_False;
-//       Standard_Real parmin = RealLast();
-
-//       for(SolidExplorer.InitShell();
-//       SolidExplorer.MoreShell();
-//       SolidExplorer.NextShell()) { 
-      parmin = RealLast();
-
-      for(SolidExplorer.InitShell();
-         SolidExplorer.MoreShell() && !isFaultyLine;
-         SolidExplorer.NextShell()) { 
-//  Modified by skv - Thu Sep  4 13:48:27 2003 OCC578 End
-
-       if(SolidExplorer.RejectShell(L) == Standard_False) { 
-
-//  Modified by skv - Thu Sep  4 13:48:27 2003 OCC578 Begin
-//       for(SolidExplorer.InitFace(); 
-//           SolidExplorer.MoreFace(); 
-//           SolidExplorer.NextFace()) {
-         for(SolidExplorer.InitFace(); 
-             SolidExplorer.MoreFace() && !isFaultyLine; 
-             SolidExplorer.NextFace()) {
-//  Modified by skv - Thu Sep  4 13:48:27 2003 OCC578 End
-         
-           if(SolidExplorer.RejectFace(L) == Standard_False) { 
-           
-             //-- Intersector3d.Perform(L,Par,Tol,SolidExplorer.CurrentFace());
-             TopoDS_Shape aLocalShape = SolidExplorer.CurrentFace();
-             TopoDS_Face f = TopoDS::Face(aLocalShape);
-             //            TopoDS_Face f = TopoDS::Face(SolidExplorer.CurrentFace());
-             IntCurvesFace_Intersector& Intersector3d = SolidExplorer.Intersector(f);
-
-             // MSV Oct 25, 2001: prolong segment, since there are cases when
-             // the intersector does not find intersection points with the original
-             // segment due to rough triangulation of a parametrized surface
-             Standard_Real addW = Max(10*Tol, 0.01*Par);
-              Standard_Real AddW = addW;
-
-             Bnd_Box aBoxF = Intersector3d.Bounding();
-
-              // MSV 23.09.2004: the box must be finite in order to
-              // correctly prolong the segment to its bounds
-              if (!aBoxF.IsVoid() && !aBoxF.IsWhole()) {
-                Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
-                aBoxF.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
-
-                Standard_Real boxaddW = GetAddToParam(L,Par,aBoxF);
-                addW = Max(addW,boxaddW);
+    }
+
+    for(SolidExplorer.InitShell();
+        SolidExplorer.MoreShell() && !isFaultyLine;
+        SolidExplorer.NextShell())
+    {
+        if(SolidExplorer.RejectShell(L) == Standard_False)
+        {
+          for(SolidExplorer.InitFace(); 
+              SolidExplorer.MoreFace() && !isFaultyLine; 
+              SolidExplorer.NextFace())
+          {
+              if(SolidExplorer.RejectFace(L) == Standard_False)
+              {
+                TopoDS_Shape aLocalShape = SolidExplorer.CurrentFace();
+                TopoDS_Face f = TopoDS::Face(aLocalShape);
+                IntCurvesFace_Intersector& Intersector3d = SolidExplorer.Intersector(f);
+
+                // Prolong segment, since there are cases when
+                // the intersector does not find intersection points with the original
+                // segment due to rough triangulation of a parameterized surface.
+                Standard_Real addW = Max(10*Tol, 0.01*Par);
+                Standard_Real AddW = addW;
+
+                Bnd_Box aBoxF = Intersector3d.Bounding();
+
+                // The box must be finite in order to correctly prolong the segment to its bounds.
+                if (!aBoxF.IsVoid() && !aBoxF.IsWhole())
+                {
+                  Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
+                  aBoxF.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
+
+                  Standard_Real boxaddW = GetAddToParam(L,Par,aBoxF);
+                  addW = Max(addW,boxaddW);
+                }
+
+                Standard_Real minW = -AddW;
+                Standard_Real maxW = Min(Par*10,Par+addW);
+                Intersector3d.Perform(L,minW,maxW);
+                if(Intersector3d.IsDone())
+                {
+                  for (Standard_Integer i = 1; i <= Intersector3d.NbPnt(); i++)
+                  {
+                    if(Abs(Intersector3d.WParameter(i)) < Abs(parmin) - Precision::PConfusion())
+                    {
+                      parmin = Intersector3d.WParameter(i);
+                      TopAbs_State aState = Intersector3d.State(i);
+                      if(Abs(parmin)<=Tol) 
+                      { 
+                        myState = 2;
+                        myFace  = f;
+                      }
+                      //  Treatment of case TopAbs_ON separately.
+                      else if(aState==TopAbs_IN)
+                      {
+                        //-- The intersection point between the line and a face F 
+                        // -- of the solid is in the face F 
+
+                        IntCurveSurface_TransitionOnCurve tran = Intersector3d.Transition(i);
+                        if (tran == IntCurveSurface_Tangent)
+                        {
+                          #ifdef OCCT_DEBUG
+                            cout<<"*Problem ds BRepClass3d_SClassifier.cxx"<<endl;
+                          #endif
+                          continue; // ignore this point
+                        }
+
+                        Trans(parmin, tran, myState);
+                        myFace  = f;
+                      }
+                      // If the state is TopAbs_ON, it is necessary to chose
+                      // another line and to repeat the whole procedure.
+                      else if(aState==TopAbs_ON)
+                      {
+                        isFaultyLine = Standard_True;
+                        break;
+                      }
+                    }
+                    else
+                    {
+                      //-- No point has been found by the Intersector3d.
+                      //-- Or a Point has been found with a greater parameter.
+                    }
+                  } //-- loop by intersection points
+                } //-- Face has not been rejected
+                else
+                  myState = 1;
               }
+          } //-- Exploration of the faces
+        } //-- Shell has not been rejected
+        else
+          myState = 1;
+    } //-- Exploration of the shells
 
-             Standard_Real minW = -AddW;//-addW;
-             Standard_Real maxW = Min(Par*10,Par+addW);//Par+addW;
-              //cout << "range [" << minW << "," << maxW << "]" << endl << endl;
-             Intersector3d.Perform(L,minW,maxW);
-             //Intersector3d.Perform(L,-Tol,Par+10.0*Tol);
-             if(Intersector3d.IsDone()) { 
-               Standard_Integer i;
-               for (i=1; i <= Intersector3d.NbPnt(); i++) { 
-                 if(Abs(Intersector3d.WParameter(i)) < Abs(parmin)) {
-                   parmin = Intersector3d.WParameter(i);
-                   //  Modified by skv - Thu Sep  4 12:46:32 2003 OCC578 Begin
-                   TopAbs_State aState = Intersector3d.State(i);
-                   //  Modified by skv - Thu Sep  4 12:46:33 2003 OCC578 End
-                   if(Abs(parmin)<=Tol) { 
-                     myState = 2;
-                     myFace  = f;
-                   }
-                   //  Modified by skv - Thu Sep  4 12:46:32 2003 OCC578 Begin
-                   //  Treatment of case TopAbs_ON separately.
-
-                   else if(aState==TopAbs_IN) { 
-                   //  Modified by skv - Thu Sep  4 12:46:32 2003 OCC578 End
-
-                     //-- The intersection point between the line and a face F 
-                     // -- of the solid is in the face F 
-
-                     IntCurveSurface_TransitionOnCurve tran = Intersector3d.Transition(i);
-                     if (tran == IntCurveSurface_Tangent) {
-#ifdef DEB
-                       cout<<"*Problem ds BRepClass3d_SClassifier.cxx"<<endl;
-#endif
-                       continue; // ignore this point
-                     }
-                     // if parmin is negative we should reverse transition
-                     if (parmin < 0)
-                       tran = (tran == IntCurveSurface_Out 
-                               ? IntCurveSurface_In : IntCurveSurface_Out);
-                     if(tran == IntCurveSurface_Out) { 
-                       //-- The line is going from inside the solid to outside 
-                       //-- the solid.
-                       myState = 3; //-- IN --
-                     }
-                     else /* if(tran == IntCurveSurface_In) */ { 
-                       myState = 4; //-- OUT --
-                     }
-                     myFace  = f;
-                   }
-                   //  Modified by skv - Thu Sep  4 12:48:50 2003 OCC578 Begin
-                   // If the state is TopAbs_ON, it is necessary to chose
-                   // another line and to repeat the whole procedure.
-                   else if(aState==TopAbs_ON) {
-                     isFaultyLine = Standard_True;
-
-                     break;
-                   }
-                   //  Modified by skv - Thu Sep  4 12:48:50 2003 OCC578 End
-                 }
-                 else { 
-                   //-- No point has been found by the Intersector3d.
-                   //-- Or a Point has been found with a greater parameter.
-                 }
-               } //-- loop by intersection points
-             } //-- Face has not been rejected
-             else { 
-               myState = 1;
-             }
-           }
-         } //-- Exploration of the faces
-       } //-- Shell has not been rejected
-       else { 
-         myState=1; 
-       }
-      } //-- Exploration of the shells
-
-      //  Modified by skv - Thu Sep  4 11:42:03 2003 OCC578 Begin
-      // The end of main loop.
+    if (NearFaultPar != RealLast() &&
+        Abs(parmin) >= Abs(NearFaultPar) - Precision::PConfusion())
+    {
+      isFaultyLine = Standard_True;
     }
-    //  Modified by skv - Thu Sep  4 11:42:03 2003 OCC578 End
+  }
 
 #ifdef DEB
-    //#################################################
-    SolidExplorer.DumpSegment(P,L,parmin,State());
-    //#################################################
+  //#################################################
+  SolidExplorer.DumpSegment(P,L,parmin,State());
+  //#################################################
 #endif
-
-  } //-- Solid has not been rejected
-  else { 
-    myState = 1;
-  }
 }
 
 
-TopAbs_State BRepClass3d_SClassifier::State() const { 
-  if(myState==2)  return(TopAbs_ON);
-  if(myState==4)        return(TopAbs_OUT);          //--
-  else if(myState==3)   return(TopAbs_IN);           //-- 
-  return(TopAbs_OUT);             
+TopAbs_State BRepClass3d_SClassifier::State() const
+{
+  if(myState == 2)
+    return(TopAbs_ON);
+  else if(myState == 3)
+    return(TopAbs_IN);
+  else if(myState == 4)
+    return(TopAbs_OUT);
+
+  // return OUT state when there is an error during execution.
+  return(TopAbs_OUT);
 }
 
 TopoDS_Face BRepClass3d_SClassifier::Face() const {  
@@ -483,3 +525,103 @@ Standard_Boolean FaceNormal (const TopoDS_Face& aF,
   }
   return Standard_True;
 }
+
+//=======================================================================
+//function : GetNormalOnFaceBound
+//purpose  : 
+//=======================================================================
+static Standard_Boolean GetNormalOnFaceBound(const TopoDS_Edge& E,
+                                             const TopoDS_Face& F,
+                                             const Standard_Real param,
+                                             gp_Dir& OutDir)
+{ 
+  Standard_Real f = 0, l = 0;
+
+  gp_Pnt2d P2d;
+  Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+  if (c2d.IsNull())
+    return Standard_False;
+  if (param < f || param > l)
+    return Standard_False;
+  c2d->D0(param, P2d);
+  if (!FaceNormal(F, P2d.X(), P2d.Y(), OutDir))
+    return Standard_False;
+  return Standard_True;
+}
+
+//=======================================================================
+//function : GetTransi
+//purpose  : 
+//=======================================================================
+static Standard_Integer GetTransi(const TopoDS_Face& f1,
+                                  const TopoDS_Face& f2,
+                                  const TopoDS_Edge e,
+                                  const Standard_Real param,
+                                  const Geom_Line& L,
+                                  IntCurveSurface_TransitionOnCurve& trans)
+{
+  //return statuses:
+  //1 => OK
+  //0 => skip
+  //-1 => probably a faulty line
+  gp_Dir nf1, nf2;
+  if (!GetNormalOnFaceBound(e, f1, param, nf1))
+    return -1;
+  if (!GetNormalOnFaceBound(e, f2, param, nf2))
+    return -1;
+
+  const gp_Dir& LDir = L.Lin().Direction();
+
+  if(Abs(LDir.Dot(nf1)) < Precision::Angular() || Abs(LDir.Dot(nf2)) < Precision::Angular())
+  {
+    //line is orthogonal to normal(s)
+    //trans = IntCurveSurface_Tangent;
+    return -1;
+  }
+
+  if (nf1.IsEqual(nf2, Precision::Angular()))
+  {
+    Standard_Real angD = nf1.Dot(LDir);
+    if (Abs(angD) < Precision::Angular())
+      return -1;
+    else if (angD > 0)
+      trans = IntCurveSurface_Out;
+    else //angD < -Precision::Angular())
+      trans = IntCurveSurface_In;
+    return 1;
+  }
+
+  gp_Vec N = nf1^nf2;
+  gp_Dir ProjL = N.XYZ() ^ LDir.XYZ() ^ N.XYZ(); //proj LDir on the plane defined by nf1/nf2 directions
+
+  Standard_Real fAD = nf1.Dot(ProjL); 
+  Standard_Real sAD = nf2.Dot(ProjL);  
+
+  if (fAD < -Precision::Angular() && sAD < -Precision::Angular())
+    trans = IntCurveSurface_In;
+  else if (fAD > Precision::Angular() && sAD > Precision::Angular())
+    trans = IntCurveSurface_Out;
+  else
+    return 0;
+  return 1;
+}
+
+//=======================================================================
+//function : Trans
+//purpose  : 
+//=======================================================================
+static void Trans(const Standard_Real parmin, 
+                  IntCurveSurface_TransitionOnCurve& tran,
+                  int& state)
+{
+  // if parmin is negative we should reverse transition
+  if (parmin < 0)
+    tran = (tran == IntCurveSurface_Out ? IntCurveSurface_In : IntCurveSurface_Out);
+
+  if(tran == IntCurveSurface_Out)
+    //-- The line is going from inside the solid to outside 
+    //-- the solid.
+    state = 3; // IN
+  else
+    state = 4; // OUT
+}
\ No newline at end of file
index 0fa51eedc1f7cdb96fa3cb44f2d07457529a1274..3d11c1a463bb1796868717f0a2d3de231bc96480 100644 (file)
@@ -38,7 +38,9 @@ uses
     State        from TopAbs,
     Intersector  from IntCurvesFace,
     MapOfInter   from BRepClass3d,
-    HSurface     from BRepAdaptor
+    HSurface     from BRepAdaptor,
+    BndBoxTree   from BRepClass3d,
+    IndexedMapOfShape from TopTools
 is
 
     Create returns SolidExplorer from BRepClass3d;
@@ -122,7 +124,22 @@ is
     --          point index of succeseful search
 
 
+    GetShape(me)
+    ---C++: return  const &
+    returns Shape from TopoDS is static;
+    
+    
+    GetTree(me)
+    ---C++: return  const &
+    ---Purpose: Return UB-tree instance which is used for edge / vertex checks.  
+    returns BndBoxTree from BRepClass3d is static;
+    
+    GetMapEV(me)
+    ---C++: return  const &
+    ---Purpose: Return edge/vertices map for current shape.
+    returns IndexedMapOfShape from TopTools is static;
 
+    ---Purpose: Starts an exploration of the shells.
     InitShell(me: in out) is static ;
     ---Purpose: Starts an exploration of the shells.
     MoreShell(me) returns Boolean from Standard is static ;
@@ -213,7 +230,8 @@ fields
     myParamOnEdge   : Real     from Standard;
     myShellExplorer : Explorer from TopExp;
     myFaceExplorer  : Explorer from TopExp;
-
+    myMapEV         : IndexedMapOfShape from TopTools;
+    myTree          : BndBoxTree from BRepClass3d;
     myMapOfInter    : MapOfInter from BRepClass3d;
 
 end SolidExplorer;
index ba7655b6c6d483fcfca6eca2e461655f3b5b998c..cf99c6ef87579948cb2a3a30270f901da5de7591 100644 (file)
@@ -39,6 +39,7 @@
 #include <TopAbs_Orientation.hxx>
 #include <TopExp_Explorer.hxx>
 #include <BRepClass_Edge.hxx>
+#include <TopExp.hxx>
 
 #include <Bnd_Box.hxx>
 #include <BRepBndLib.hxx>
@@ -751,6 +752,9 @@ void BRepClass3d_SolidExplorer::Destroy() {
 
 void BRepClass3d_SolidExplorer::InitShape(const TopoDS_Shape& S)
 {
+  myMapEV.Clear();
+  myTree.Clear();
+
   myShape = S;
   myFirstFace = 0;
   myParamOnEdge = 0.512345;
@@ -775,7 +779,7 @@ void BRepClass3d_SolidExplorer::InitShape(const TopoDS_Shape& S)
       Expl.More();
       Expl.Next()) { 
     const TopoDS_Face Face = TopoDS::Face(Expl.Current());
-    void *ptr = (void *)(new IntCurvesFace_Intersector(Face,Precision::Confusion()));
+    void *ptr = (void *)(new IntCurvesFace_Intersector(Face,Precision::Confusion(), Standard_False));
     myMapOfInter.Bind(Face,ptr);
     myReject=Standard_False;  //-- at least one face in the solid 
   }
@@ -784,11 +788,31 @@ void BRepClass3d_SolidExplorer::InitShape(const TopoDS_Shape& S)
   if(myReject) { 
     cout<<"\nWARNING : BRepClass3d_SolidExplorer.cxx  (Solid without face)"<<endl;
   }
-#endif      
+#endif
 
 #if REJECTION
   BRepBndLib::Add(myShape,myBox);
 #endif
+
+  // Fill mapEV with vertices and edges from shape.
+  TopExp::MapShapes(myShape, TopAbs_EDGE, myMapEV);
+  TopExp::MapShapes(myShape, TopAbs_VERTEX, myMapEV);  
+
+  NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller (myTree);
+
+  for (Standard_Integer i = 1; i <= myMapEV.Extent(); i++)
+  {
+    Bnd_Box B;
+    const TopoDS_Shape& Sh = myMapEV(i);
+    TopAbs_Orientation ori = Sh.Orientation();
+    if (ori == TopAbs_EXTERNAL || ori == TopAbs_INTERNAL)
+      continue;
+    if (Sh.ShapeType() == TopAbs_EDGE && BRep_Tool::Degenerated(TopoDS::Edge(Sh)))
+      continue;
+    BRepBndLib::Add(Sh,B);
+    aTreeFiller.Add(i, B);
+  }
+  aTreeFiller.Fill();
 }
 
 //=======================================================================
@@ -956,3 +980,30 @@ void BRepClass3d_SolidExplorer::DumpSegment(const gp_Pnt&,
  
 #endif
 }
+
+//=======================================================================
+//function : GetShape
+//purpose  : 
+//=======================================================================
+const TopoDS_Shape& BRepClass3d_SolidExplorer::GetShape() const 
+{ 
+  return myShape;
+}
+
+//=======================================================================
+//function : GetTree
+//purpose  : 
+//=======================================================================
+const BRepClass3d_BndBoxTree& BRepClass3d_SolidExplorer::GetTree() const 
+{ 
+  return myTree;
+}
+
+//=======================================================================
+//function : GetMapEV
+//purpose  : 
+//=======================================================================
+const  TopTools_IndexedMapOfShape& BRepClass3d_SolidExplorer::GetMapEV() const 
+{ 
+  return myMapEV;
+}
diff --git a/src/BRepClass3d/FILES b/src/BRepClass3d/FILES
new file mode 100644 (file)
index 0000000..d8135a7
--- /dev/null
@@ -0,0 +1,2 @@
+BRepClass3d_BndBoxTree.hxx
+BRepClass3d_BndBoxTree.cxx
\ No newline at end of file
index 404982e6c8b2e8eee21a3acecb23991038d30b7a..80e12de167819f003e8eb1b9f05644adcc53aa79 100644 (file)
@@ -46,7 +46,8 @@ uses
 is
 
     Create(F    : Face from TopoDS;
-          aTol : Real    from Standard)
+           aTol : Real    from Standard;
+           UseBToler : Boolean from Standard = Standard_True)
           
        ---Purpose: Load a Face.     
        --          
@@ -93,6 +94,18 @@ is
     returns Boolean from Standard
     is static;
     
+    GetUseBoundToler(me)  
+       ---Purpose: Returns the boundary tolerance flag.
+       ---C++: inline
+    returns Boolean from Standard
+    is static;
+    
+    SetUseBoundToler(me: in out;
+                         UseBToler: Boolean from Standard)  
+       ---Purpose: Sets the boundary tolerance flag.
+       ---C++: inline
+    is static;
+    
     
     NbPnt(me) 
        ---C++: inline
@@ -196,6 +209,7 @@ fields
     face               :  Face                from TopoDS;
     PtrOnPolyhedron    :  Address             from Standard;
     PtrOnBndBounding   :  Address             from Standard;
+    myUseBoundTol      :  Boolean from Standard;
 
 
 end Intersector from IntCurvesFace;
index 91cf0e1ee8701481e2daac69065fc682092b3647..5bca21e898a7df90a38df27bfda2b541fab92d33 100644 (file)
@@ -57,13 +57,15 @@ GeomAbs_SurfaceType IntCurvesFace_Intersector::SurfaceType() const
 //purpose  : 
 //=======================================================================
 IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
-                                                     const Standard_Real aTol)
+                                                     const Standard_Real aTol,
+                                                     const Standard_Boolean UseBToler)
 : 
   Tol(aTol),
   done(Standard_False),
   nbpnt(0),
   PtrOnPolyhedron(NULL),
-  PtrOnBndBounding(NULL)
+  PtrOnBndBounding(NULL),
+  myUseBoundTol (UseBToler)
 { 
   BRepAdaptor_Surface surface;
   const Standard_Boolean aRestr = Standard_True;
@@ -146,8 +148,8 @@ void IntCurvesFace_Intersector::InternalCall(const IntCurveSurface_HInter &HICS,
       gp_Pnt2d Puv(HICSPointindex.U(),HICSPointindex.V());
 
       //TopAbs_State currentstate = myTopolTool->Classify(Puv,Tol);
-      TopAbs_State currentstate = myTopolTool->Classify(Puv, mintol2d);
-      if(currentstate == TopAbs_OUT && maxtol2d > mintol2d) {
+      TopAbs_State currentstate = myTopolTool->Classify(Puv, !myUseBoundTol ? 0 : mintol2d);
+      if(myUseBoundTol && currentstate == TopAbs_OUT && maxtol2d > mintol2d) {
         if(anAdditionalTool.IsNull())
         {
           anAdditionalTool = new BRepTopAdaptor_TopolTool(Hsurface);
@@ -408,5 +410,13 @@ void IntCurvesFace_Intersector::Destroy() {
   }
 }
 
+ void IntCurvesFace_Intersector::SetUseBoundToler(Standard_Boolean UseBToler)
+ {
+   myUseBoundTol = UseBToler;
+ }
 
+ Standard_Boolean IntCurvesFace_Intersector::GetUseBoundToler() const
+ {
+   return myUseBoundTol;
+ }
 
index 741e5e2c7880b8dfd7637e8272d8bb2142310d5e..73db3857fc9fb2bbcc1343392e74320e2fffafa2 100755 (executable)
@@ -30,3 +30,4 @@ TopOpeBRepTool_define.hxx
 TopOpeBRepTool_defineG.hxx
 TopOpeBRepTool_tol.hxx
 TopOpeBRepTool_tol.cxx
+TopOpeBRepTool_IndexedDataMapOfSolidClassifier.hxx
index 18a8d51e1a66ddeb9fa0ba3efd38955695068673..50d72790441d300cef7da86fa1888b8475a3aabd 100644 (file)
@@ -70,12 +70,8 @@ is
         ListOfC2DF from TopOpeBRepTool,
         ShapeMapHasher from TopTools);
     
-    class IndexedDataMapOfSolidClassifier 
-    instantiates IndexedDataMap from TCollection 
-       (Shape from TopoDS,
-        SolidClassifier from BRepClass3d,
-        ShapeMapHasher from TopTools);
-        
+    imported IndexedDataMapOfSolidClassifier;
+
     pointer Plos to ListOfShape from TopTools;
     class SolidClassifier;
     
diff --git a/src/TopOpeBRepTool/TopOpeBRepTool_IndexedDataMapOfSolidClassifier.hxx b/src/TopOpeBRepTool/TopOpeBRepTool_IndexedDataMapOfSolidClassifier.hxx
new file mode 100644 (file)
index 0000000..e98c775
--- /dev/null
@@ -0,0 +1,28 @@
+// Created on: 1993-06-17
+// Created by: Jean Yves LEBEY
+// Copyright (c) 1993-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef TopOpeBRepTool_IndexedDataMapOfSolidClassifier_HeaderFile
+#define TopOpeBRepTool_IndexedDataMapOfSolidClassifier_HeaderFile
+
+#include <TopoDS_Shape.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
+#include <TopTools_ShapeMapHasher.hxx>
+#include <NCollection_IndexedDataMap.hxx>
+
+typedef NCollection_IndexedDataMap<TopoDS_Shape,BRepClass3d_SolidClassifier,TopTools_ShapeMapHasher> TopOpeBRepTool_IndexedDataMapOfSolidClassifier;
+
+
+#endif