]> OCCT Git - occt-copy.git/commitdiff
0028991: HLR: Building of the set faces on the base of HLR contours
authorisn <isn@opencascade.com>
Tue, 25 Jul 2017 11:17:14 +0000 (14:17 +0300)
committerasl <asl@opencascade.com>
Thu, 6 Dec 2018 14:17:52 +0000 (17:17 +0300)
1) Draft implementation of face builder on the base of HLR contours has been added
2) new method in bnd_box2d class: distance from 2d point to box
3) small re factoring of  some HLR classes
4) new QA command (OCC28991) for testing of new functionality

12 files changed:
src/Bnd/Bnd_Box2d.cxx
src/Bnd/Bnd_Box2d.hxx
src/Contap/Contap_Contour.cxx
src/HLRAppli/HLRAppli_ReflectLines.cxx
src/HLRAppli/HLRAppli_ReflectLines.hxx
src/HLRBRep/HLRBRep_Data.cxx
src/HLRBRep/HLRBRep_HLRToShape.cxx
src/HLRBRep/HLRBRep_HLRToShape.hxx
src/HLRBRep/HLRBRep_ShapeToHLR.cxx
src/HLRTopoBRep/HLRTopoBRep_DSFiller.cxx
src/QABugs/QABugs_20.cxx
src/TKHLR/EXTERNLIB

index 02263e99ef5ee4e332fce9e69befe24df30544d7..83cdae988edfef30c2404f85fe65f94cfc50483f 100644 (file)
@@ -300,3 +300,23 @@ void Bnd_Box2d::Dump () const
   cout << "\n Gap : " << Gap;
   cout << "\n";
 }
+
+ Standard_Real Bnd_Box2d::SquareDistance (const gp_Pnt2d& thePnt2d) const
+ {
+   Standard_Real Xmin, Xmax, Ymin, Ymax;
+   Standard_Real X = thePnt2d.X(), Y = thePnt2d.Y();
+   Standard_Real dd = 0;
+   Get(Xmin, Ymin, Xmax, Ymax);
+
+   if (X < Xmin)
+     dd += (Xmin - X)*(Xmin - X);
+   else if (X > Xmax)
+     dd += (Xmax - X)*(Xmax - X);
+
+   if (Y < Ymin)
+     dd += (Ymin - Y)*(Ymin - Y);
+   else if (Y > Ymax)
+     dd += (Ymax - Y)*(Ymax - Y);
+
+   return dd;
+ }
\ No newline at end of file
index ac8af037c3abb7edc59837d3128865bee8323156..15df6cb5d43eade2252e32815bcdaddcecfd7b48 100644 (file)
@@ -182,6 +182,10 @@ public:
   
   //! Returns True if the 2d pnt <P> is out <me>.
   Standard_EXPORT Standard_Boolean IsOut (const gp_Pnt2d& P) const;
+
+  //! Returns distance from point <thePnt2d> to <me>
+  //! distance will be 0 if point is inside of <me>
+   Standard_EXPORT Standard_Real SquareDistance (const gp_Pnt2d& thePnt2d) const;
   
   //! Returns True if <Box2d> is out <me>.
   Standard_EXPORT Standard_Boolean IsOut (const Bnd_Box2d& Other) const;
index ba077c5a751bbcce5b40a4ffc8ca90eb958d1f65..07d4bf229ff13d60a7fa7a869af34561761dd7f0 100644 (file)
@@ -1271,7 +1271,6 @@ void ComputeInternalPoints
               else {
                 vtestb = gp_Vec(0.,0.,0.);
               }
-              double vmagn = vtestb.Magnitude();
               count++;
               if (count > 10)
               {
index b63708e2d4149d0af77175354698da6206ecef87..eb10157ef0aad4e2a4e5a5ab1661c1b5f228bcbe 100644 (file)
@@ -112,3 +112,13 @@ TopoDS_Shape HLRAppli_ReflectLines::GetResult() const
 {
   return GetCompoundOf3dEdges(HLRBRep_OutLine, Standard_True, Standard_True);
 }
+//=======================================================================
+//function : GetCompoundOfFaces
+//purpose  :
+//=======================================================================
+TopoDS_Shape HLRAppli_ReflectLines::GetCompoundOfFaces(bool theMode,
+  TopTools_DataMapOfShapeShape& OrigFaceToProjFace ) const
+{
+  HLRBRep_HLRToShape aHLRToShape( myHLRAlgo );
+  return aHLRToShape.CompoundOfFaces(theMode, OrigFaceToProjFace);
+}
index 0ae15dc548989815c4b739d02d072d022d7897d1..d1c92664579e55c64e635cc19cc78525c2703f36 100644 (file)
@@ -26,6 +26,7 @@
 #include <HLRBRep_TypeOfResultingEdge.hxx>
 #include <TopoDS_Shape.hxx>
 #include <Standard_Real.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
 class TopoDS_Shape;
 
 
@@ -60,6 +61,9 @@ public:
                                                     const Standard_Boolean            visible,
                                                     const Standard_Boolean            In3d) const;
 
+  Standard_EXPORT TopoDS_Shape GetCompoundOfFaces(bool theMode,
+                                                  TopTools_DataMapOfShapeShape& OrigFaceToProjFace) const;
+
 
 
 protected:
@@ -70,8 +74,6 @@ protected:
 
 private:
 
-
-
   HLRAlgo_Projector myProjector;
   Handle(HLRBRep_Algo) myHLRAlgo;
   TopoDS_Shape myShape;
index 5cfa9a8a9428e78993a3affbc6830781a93535f1..981cf76a3dc450d2259c8f6fdd793c552e2a899d 100644 (file)
@@ -972,6 +972,8 @@ void HLRBRep_Data::GetNextEdge()
   myLEInternal = Standard_False;
   myLEDouble   = Standard_False;
   myLEIsoLine  = Standard_False;
+  myLEGeom = &myLEData->ChangeGeometry();
+  myLETol = myLEData->Tolerance();
   myLEType     = myLEGeom->GetType();
 }
 
@@ -1009,43 +1011,6 @@ void HLRBRep_Data::NextEdge (const Standard_Boolean skip)
     ((HLRBRep_EdgeData*)myLEData)->HideCount() == myHideCount-1))
     NextEdge();
   ((HLRBRep_EdgeData*)myLEData)->HideCount(myHideCount-1);
-  return;
-
-  /*if (((HLRBRep_EdgeData*)myLEData)->Vertical()) {
-    NextEdge();
-    return;
-  }
-  if (((HLRBRep_EdgeData*)myLEData)->HideCount() > myHideCount-2) {
-    NextEdge();
-    return;
-  }
-  if (((HLRBRep_EdgeData*)myLEData)->Status().AllHidden()) {
-    NextEdge();
-    return;
-  }
-  if (((iFaceMinMax->Max[0] - myLEMinMax->Min[0]) & 0x80008000) != 0 ||
-      ((myLEMinMax->Max[0] - iFaceMinMax->Min[0]) & 0x80008000) != 0 ||
-      ((iFaceMinMax->Max[1] - myLEMinMax->Min[1]) & 0x80008000) != 0 ||
-      ((myLEMinMax->Max[1] - iFaceMinMax->Min[1]) & 0x80008000) != 0 ||
-      ((iFaceMinMax->Max[2] - myLEMinMax->Min[2]) & 0x80008000) != 0 ||
-      ((myLEMinMax->Max[2] - iFaceMinMax->Min[2]) & 0x80008000) != 0 ||
-      ((iFaceMinMax->Max[3] - myLEMinMax->Min[3]) & 0x80008000) != 0 ||
-      ((myLEMinMax->Max[3] - iFaceMinMax->Min[3]) & 0x80008000) != 0 ||
-      ((iFaceMinMax->Max[4] - myLEMinMax->Min[4]) & 0x80008000) != 0 ||
-      ((myLEMinMax->Max[4] - iFaceMinMax->Min[4]) & 0x80008000) != 0 ||
-      ((iFaceMinMax->Max[5] - myLEMinMax->Min[5]) & 0x80008000) != 0 ||
-      ((myLEMinMax->Max[5] - iFaceMinMax->Min[5]) & 0x80008000) != 0 ||
-      ((iFaceMinMax->Max[6] - myLEMinMax->Min[6]) & 0x80008000) != 0 ||
-      ((myLEMinMax->Max[6] - iFaceMinMax->Min[6]) & 0x80008000) != 0 ||
-      ((iFaceMinMax->Max[7] - myLEMinMax->Min[7]) & 0x80008000) != 0) { //-- rejection en z 
-    NextEdge();
-    return;
-  }
-  if (((HLRBRep_Surface*)iFaceGeom)->IsAbove
-      (iFaceBack,myLEGeom,(Standard_Real)myLETol)) {
-    NextEdge();
-    return;
-  }*/
   return;               // edge is OK
 }
 
index b9cd3e1ed9a99f7db913241d9125367f5742aa2d..808ad84e25a513f3a46c0e61bdee0ec623451c8a 100644 (file)
 #include <TopoDS_Shape.hxx>
 #include <TopTools_IndexedMapOfShape.hxx>
 
+#include <BRepLib.hxx>
+#include <BRepLib_MakeVertex.hxx>
+#include <BRepTools.hxx>
+#include <TopExp.hxx>
+#include <IntTools_FClass2d.hxx>
+#include <BRepTools_ReShape.hxx>
+#include <Poly_MakeLoops.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
+#include <NCollection_UBTreeFiller.hxx>
+#include <BndLib_Add2dCurve.hxx>
+#include <Bnd_Box2d.hxx>
+#include <BRepAdaptor_Curve2d.hxx>
+#include <BRepGProp.hxx>
+#include <GProp_GProps.hxx>
+#include <NCollection_Handle.hxx>
+#include <BRepBndLib.hxx>
+#include <BOPTools_AlgoTools3D.hxx>
+#include <IntTools_Context.hxx>
+#include <BRepAlgoAPI_BuilderAlgo.hxx>
+#include <NCollection_UBTree.hxx>
+#include <Extrema_POnCurv2d.hxx>
+#include <IntCurvesFace_ShapeIntersector.hxx>
+#include <Extrema_ExtPC2d.hxx>
+#include <HLRTopoBRep_OutLiner.hxx>
+#include <Geom_Plane.hxx>
+#include <BRepBndLib.hxx>
+#include <TopTools_DataMapOfShapeReal.hxx>
+#include <algorithm>
 //=======================================================================
 //function : HLRBRep_HLRToShape
 //purpose  : 
@@ -250,3 +278,932 @@ HLRBRep_HLRToShape::DrawEdge (const Standard_Boolean visible,
     }
   }
 }
+
+//UBTree edge-point 
+typedef NCollection_UBTree <Standard_Integer, Bnd_Box2d> HLRVV_BndBoxTree;
+
+class HLRVV_BndBoxTreeSelector : public HLRVV_BndBoxTree::Selector
+{
+public:
+  HLRVV_BndBoxTreeSelector( const TopTools_IndexedMapOfShape& theInpShapes,
+    double theMinDDist) 
+    : myInpShapes(theInpShapes), 
+    myMinDDist(theMinDDist),
+    myResId (-1),
+    myCId (-1)
+  {}
+
+  Standard_Boolean Reject (const Bnd_Box2d& theBox) const
+  {
+    double aCurDDist = theBox.SquareDistance(myCPnt);
+    if (aCurDDist > myMinDDist)
+      return true;
+    else
+      return false;
+  }
+
+  Standard_Boolean Accept (const Standard_Integer& theObj)
+  {
+    //extrema pnt <-> vertex
+    const TopoDS_Shape& aSh = myInpShapes(theObj);
+    if (theObj == myCId)
+      return Standard_False;
+    gp_Pnt aCVP = BRep_Tool::Pnt(TopoDS::Vertex(aSh));
+    gp_Pnt2d aCVP2d(aCVP.X(), aCVP.Y());
+    double aDD = aCVP2d.SquareDistance(myCPnt);
+    if (aDD < myMinDDist)
+    {
+      myMinDDist = aDD;
+      myResId = theObj;
+    }
+
+    return Standard_True;
+  }
+
+  void Reset(double theMinDDist)
+  {
+    myMinDDist = theMinDDist;
+    myResId = -1;
+    myCId = -1; 
+  }
+
+  void SetCurrentPoint( int id ) 
+  {
+    gp_Pnt CP = BRep_Tool::Pnt(TopoDS::Vertex(myInpShapes(id)));
+    myCPnt.SetX(CP.X());
+    myCPnt.SetY(CP.Y());
+    myCId = id;
+  }
+
+  double GetMinDDist() const
+  {
+    return myMinDDist;
+  }
+
+  int GetResVId() const
+  {
+    return myResId;
+  }
+
+private:
+  HLRVV_BndBoxTreeSelector(const HLRVV_BndBoxTreeSelector& );
+  HLRVV_BndBoxTreeSelector& operator=(const HLRVV_BndBoxTreeSelector& );
+
+private:
+  const TopTools_IndexedMapOfShape& myInpShapes;
+  gp_Pnt2d myCPnt;
+  double myMinDDist;
+  int myResId;
+  int myCId;
+};
+
+///
+
+//UBTree edge-point 
+typedef NCollection_UBTree <Standard_Integer, Bnd_Box2d> HLRVE_BndBoxTree;
+
+class HLRVE_BndBoxTreeSelector : public HLRVE_BndBoxTree::Selector
+{
+public:
+  HLRVE_BndBoxTreeSelector( 
+    const NCollection_IndexedDataMap<TopoDS_Edge, BRepAdaptor_Curve2d, TopTools_ShapeMapHasher>& theEdgeAdapt,
+    double theMinDDist) 
+    : myEdgeAdapt (theEdgeAdapt), 
+    myMinDDist(theMinDDist)
+  {}
+
+  Standard_Boolean Reject (const Bnd_Box2d& theBox) const
+  {
+    double aCurDDist = theBox.SquareDistance(myCPnt);
+    if (aCurDDist > myMinDDist)
+      return true;
+    else
+      return false;
+  }
+
+  Standard_Boolean Accept (const Standard_Integer& theObj)
+  {
+    const BRepAdaptor_Curve2d& adapt = myEdgeAdapt(theObj);
+    Extrema_ExtPC2d aExtPC(myCPnt, adapt, adapt.FirstParameter(), adapt.LastParameter());
+    if (aExtPC.IsDone() && aExtPC.NbExt() > 0 )
+    {
+      NCollection_Handle<Extrema_POnCurv2d> aPSol;// = aExtPC.Point(1);
+      double aMinDD = Precision::Infinite(); 
+      double aFp = adapt.FirstParameter();
+      double aLp = adapt.LastParameter();
+      for ( Standard_Integer i = 1; i <= aExtPC.NbExt(); i++) 
+      {
+        double aCDD = aExtPC.SquareDistance(i);
+        Extrema_POnCurv2d aCurSol = aExtPC.Point(i);
+        if (Abs(aCurSol.Parameter() - aFp) < Precision::Confusion() || 
+          Abs(aCurSol.Parameter() - aLp) < Precision::Confusion()) //TODO it's better to use tolerance of vertex here
+          continue;
+        if ( aCDD < aMinDD) 
+        {
+          aMinDD = aCDD;
+          aPSol = new Extrema_POnCurv2d(aExtPC.Point(i));
+        }
+      }
+      if (aMinDD < myMinDDist)
+      {
+        myMinDDist = aMinDD;
+        myEARes = adapt;
+        if (!myPSolRes)
+          myPSolRes = new Extrema_POnCurv2d( *aPSol );
+        else
+          myPSolRes->SetValues(aPSol->Parameter(), aPSol->Value());
+      }
+    }
+
+    return Standard_True;
+  }
+
+  void Reset(double theMinDDist)
+  {
+    myMinDDist = theMinDDist;
+    myPSolRes.Nullify();
+  }
+
+  void SetCurrentPoint( const gp_Pnt& thePnt ) 
+  {
+    myCPnt.SetX(thePnt.X());
+    myCPnt.SetY(thePnt.Y());
+  }
+
+  bool GetPResult(Extrema_POnCurv2d& thePSolRes, BRepAdaptor_Curve2d& theERes) const
+  {
+    if (!myPSolRes.IsNull())
+    {
+      thePSolRes = *myPSolRes;
+      theERes = myEARes;
+      return true;
+    }
+    else
+      return false;
+  }
+
+private:
+  HLRVE_BndBoxTreeSelector(const HLRVE_BndBoxTreeSelector& );
+  HLRVE_BndBoxTreeSelector& operator=(const HLRVE_BndBoxTreeSelector& );
+
+private:
+  const NCollection_IndexedDataMap<TopoDS_Edge, BRepAdaptor_Curve2d, TopTools_ShapeMapHasher>& myEdgeAdapt;
+  gp_Pnt2d myCPnt;
+  double myMinDDist;
+  NCollection_Handle<Extrema_POnCurv2d> myPSolRes;
+  BRepAdaptor_Curve2d myEARes;
+};
+
+
+//! deriatives of the edges on both ends
+struct BRepFill_TangentLinkInfo
+{
+  gp_Dir2d myD1L;
+  gp_Dir2d myD1F;
+};
+
+class BRepFill_PolyHelper : public Poly_MakeLoops2D::Helper
+{
+public:
+  BRepFill_PolyHelper( const NCollection_DataMap<Poly_MakeLoops2D::Link, BRepFill_TangentLinkInfo>& mL2TI,
+    const NCollection_DataMap<Standard_Integer, Poly_MakeLoops2D::ListOfLink>& themNode2ListOfLinks) : 
+  myL2TI (mL2TI),
+    mymNode2ListOfLinks (themNode2ListOfLinks)
+  {
+
+  };
+
+  virtual const Poly_MakeLoops2D::ListOfLink& GetAdjacentLinks (Standard_Integer theNode) const
+  {
+    return mymNode2ListOfLinks(theNode);
+  }
+
+  virtual Standard_Boolean GetFirstTangent(const Poly_MakeLoops2D::Link& theLink, gp_Dir2d& theDir) const
+  {
+    if (theLink.flags & Poly_MakeLoops2D::LF_Reversed)
+      theDir = -myL2TI(theLink).myD1L;
+    else
+      theDir = myL2TI(theLink).myD1F;
+    return Standard_True;
+  }
+
+  virtual Standard_Boolean GetLastTangent(const Poly_MakeLoops2D::Link& theLink, gp_Dir2d& theDir) const
+  {    
+    if (theLink.flags & Poly_MakeLoops2D::LF_Reversed)
+      theDir = -myL2TI(theLink).myD1F;
+    else
+      theDir = myL2TI(theLink).myD1L;
+    return Standard_True;
+  }
+private:
+
+  BRepFill_PolyHelper& operator= (const BRepFill_PolyHelper &theOther);
+
+private:
+  const NCollection_DataMap<Poly_MakeLoops2D::Link, BRepFill_TangentLinkInfo>& myL2TI;
+  const NCollection_DataMap<Standard_Integer, Poly_MakeLoops2D::ListOfLink>& mymNode2ListOfLinks;
+
+};
+
+typedef NCollection_UBTree <Standard_Integer, Bnd_Box> HLRFL_BndBoxTree;
+
+class HLRFL_BndBoxTreeSelector : public HLRFL_BndBoxTree::Selector
+{
+public:
+
+  struct FaceParam
+  {
+    TopoDS_Face myF;
+    double LPar;
+  };
+
+  HLRFL_BndBoxTreeSelector(const TopTools_IndexedMapOfShape& theFMap, bool theMode) 
+    : HLRFL_BndBoxTreeSelector::Selector(), 
+    myFMap (theFMap),
+    myIntersectors(1, theFMap.Size()),
+    myMode (theMode)
+  {
+    for (int i =1; i <= myIntersectors.Size(); i++)
+      myIntersectors(i) = NULL;
+  }
+
+  ~HLRFL_BndBoxTreeSelector()
+  {
+    for (int i =1; i <= myIntersectors.Size(); i++)
+    {
+      IntCurvesFace_ShapeIntersector* an_inter = myIntersectors(i);
+      if (an_inter)
+        delete an_inter;
+    }
+  }
+
+
+  Standard_Boolean Reject (const Bnd_Box& theBox) const
+  {
+    return theBox.IsOut (myLine);
+  }
+
+  Standard_Boolean Accept (const Standard_Integer& theObj)
+  {
+    if (theObj > myFMap.Extent())
+      return Standard_False;
+    const TopoDS_Face& F = TopoDS::Face(myFMap(theObj));
+    IntCurvesFace_ShapeIntersector* an_inter = myIntersectors(theObj);
+    if (!an_inter)
+    {
+      an_inter = new IntCurvesFace_ShapeIntersector();
+      an_inter->Load(F, Precision::Confusion());
+    }
+
+    an_inter->Perform(myLine, -Precision::Infinite(), Precision::Infinite()); //TODO trim the line according to bnd box of face 
+    if (an_inter->IsDone() && an_inter->NbPnt())
+    {
+      for (int i=1; i <= an_inter->NbPnt(); i++)
+      {
+        FaceParam fp;
+        fp.LPar = an_inter->WParameter(i);
+        fp.myF = an_inter->Face(i);
+        myRParams.push_back(fp);
+      }
+      if (!myMode)
+        myStop = 1;
+    }
+    return Standard_True;
+    //int nbpnt = an_inter->.NbPnt();
+  }
+   
+  void SetLine (const gp_Lin& theLine) 
+  {
+    myLine = theLine;
+  }
+
+  const std::vector<FaceParam>& GetRParams () const
+  {
+    return myRParams;
+  }
+  void ResetResult()
+  {
+    myRParams.clear();
+  }
+
+private:
+  HLRFL_BndBoxTreeSelector(const HLRFL_BndBoxTreeSelector& );
+  HLRFL_BndBoxTreeSelector& operator=(const HLRFL_BndBoxTreeSelector& );
+
+private:
+  const TopTools_IndexedMapOfShape& myFMap;
+  gp_Lin myLine;
+  NCollection_Array1<IntCurvesFace_ShapeIntersector*> myIntersectors;
+  std::vector<FaceParam> myRParams;
+  bool myMode; //if true => find all line-face intersections; otherwise - find any and stop the search 
+};
+
+
+static bool FuseVE(TopoDS_Shape& theRes)
+{
+  TopTools_IndexedMapOfShape allE;
+  TopExp::MapShapes(theRes, TopAbs_EDGE, allE);
+  TopTools_ListOfShape aLSE;
+  for (int i = 1; i <= allE.Extent(); i++ )
+    aLSE.Append(allE(i));
+
+  Standard_Real aFV = 0;
+  BRepAlgoAPI_BuilderAlgo aBlr;
+  aBlr.SetArguments(aLSE);
+  aBlr.SetRunParallel(Standard_True);
+  aBlr.SetFuzzyValue(aFV);
+  aBlr.Build(); 
+  if (aBlr.HasErrors()) 
+  {
+    aBlr.DumpErrors(cout);
+    return false;
+  }
+  theRes = aBlr.Shape();
+  return true;
+}
+
+static void ProcessHVertices(TopoDS_Shape& theRes,
+  NCollection_IndexedDataMap<TopoDS_Edge, BRepAdaptor_Curve2d, TopTools_ShapeMapHasher>& theEdAd,
+  NCollection_DataMap<TopoDS_Edge, Bnd_Box2d, TopTools_ShapeMapHasher>& theEdBnd2d )
+{
+  BRepTools_ReShape reshaper;  
+  ///hanging vertices => find closely located point on some edge or vertex
+  TopoDS_Face aDraftPrFace;
+  BRep_Builder().MakeFace(aDraftPrFace, BRepLib::Plane(), Precision::Confusion());
+  TopTools_IndexedDataMapOfShapeListOfShape M;
+  TopExp::MapShapesAndAncestors(theRes, TopAbs_VERTEX, TopAbs_EDGE, M);
+  TopTools_IndexedMapOfShape HV; 
+  for (int i = 1; i <= M.Extent(); i++)
+    if (M(i).Extent() == 1)
+      HV.Add(M.FindKey(i));
+  //
+  TopTools_IndexedMapOfShape VV, EE;
+  TopExp::MapShapes(theRes, TopAbs_VERTEX, VV);
+  TopExp::MapShapes(theRes, TopAbs_EDGE, EE);
+  //
+  //vertex-vertex extrema
+  NCollection_UBTree <Standard_Integer, Bnd_Box2d> aTreeVV;
+  NCollection_UBTreeFiller <Standard_Integer, Bnd_Box2d> aTreeFillerVV (aTreeVV);
+  for (Standard_Integer i = 1; i <= VV.Extent(); i++)
+  { 
+    const TopoDS_Vertex& aV = TopoDS::Vertex(VV(i));
+    Bnd_Box2d aBB;
+    gp_Pnt aPV = BRep_Tool::Pnt(aV);
+    aBB.Add(gp_Pnt2d(aPV.X(), aPV.Y()));
+    aBB.Enlarge(BRep_Tool::Tolerance(aV));
+    aTreeFillerVV.Add(i, aBB);
+  }
+
+  aTreeFillerVV.Fill();
+  HLRVV_BndBoxTreeSelector aSelectorVV(VV, Precision::Infinite());  
+
+  //vertex-edge extrema
+  NCollection_UBTree <Standard_Integer, Bnd_Box2d> aTreeVE;
+  NCollection_UBTreeFiller <Standard_Integer, Bnd_Box2d> aTreeFillerVE (aTreeVE);
+  int nbEE = EE.Extent();
+  //NCollection_Array1<BRepAdaptor_Curve2d> anEdgeAdapters(1, nbEE);
+  for (Standard_Integer i = 1; i <= nbEE; i++)
+  { 
+    const TopoDS_Edge& anE = TopoDS::Edge(EE(i));
+    Bnd_Box2d aBB;
+    theEdAd.Add(anE, BRepAdaptor_Curve2d(anE, aDraftPrFace));
+    BndLib_Add2dCurve::Add(*theEdAd.Seek(anE), 0, aBB);
+    theEdBnd2d.Bind(anE, aBB);
+    aTreeFillerVE.Add(i, aBB);
+  }
+
+  aTreeFillerVE.Fill();
+  HLRVE_BndBoxTreeSelector aSelectorVE(theEdAd, Precision::Infinite());      //min dist doesn't matter here   
+  //
+
+  TopTools_IndexedMapOfShape toadd, torem;//temp
+  for (int i = 1; i <= HV.Extent(); i++ )
+  {
+    const TopoDS_Vertex& CHV = TopoDS::Vertex(HV(i));
+    gp_Pnt CHVPnt =  BRep_Tool::Pnt(CHV);
+    //
+    int id = VV.FindIndex(CHV);
+    aSelectorVV.Reset(Precision::Infinite());
+    aSelectorVV.SetCurrentPoint( id );
+    /*int resVV =*/ aTreeVV.Select(aSelectorVV);
+    double aMinDDistReached = aSelectorVV.GetMinDDist();
+    TopoDS_Vertex aResV = TopoDS::Vertex(VV(aSelectorVV.GetResVId()));
+    //          
+    aSelectorVE.Reset(aMinDDistReached);
+    aSelectorVE.SetCurrentPoint( CHVPnt );
+    /*int resVE = */aTreeVE.Select(aSelectorVE);
+
+    Extrema_POnCurv2d aPSolRes;
+    BRepAdaptor_Curve2d aResEA;
+    bool VEFound = aSelectorVE.GetPResult(aPSolRes, aResEA);
+    if (VEFound)
+    {
+      ///if (BRep_Tool::Degenerated(E)) //can be degenerted??
+      double aPar = aPSolRes.Parameter();
+      const TopoDS_Edge& aResE = aResEA.Edge();
+      TopoDS_Edge aDE1 = TopoDS::Edge(aResE.EmptyCopied().Oriented(TopAbs_FORWARD));
+      TopoDS_Edge aDE2 = TopoDS::Edge(aResE.EmptyCopied().Oriented(TopAbs_FORWARD));
+
+      TopoDS_Vertex aFV, aLV;
+      TopExp::Vertices(aResE, aFV, aLV);
+      double aFP = aResEA.FirstParameter();
+      double aLP = aResEA.LastParameter();
+      gp_Pnt2d aResP2d = aResEA.Value(aPar);
+      gp_Pnt aResP3d(aResP2d.X(), aResP2d.Y(), 0.0);
+      TopoDS_Vertex aDummyV = BRepLib_MakeVertex(aResP3d).Vertex();
+      //
+      NCollection_List<TopoDS_Shape> nls;
+      nls.Append(aDummyV); 
+      nls.Append(CHV); 
+      gp_Pnt aNC;
+      double aNTol;
+      BRepLib::BoundingVertex(nls, aNC, aNTol);
+
+      gp_Pnt aFVP = BRep_Tool::Pnt(aFV);
+      gp_Pnt aLVP = BRep_Tool::Pnt(aLV);
+      if (aFVP.Distance(aNC) < aNTol*1e10 ||
+        aLVP.Distance(aNC) < aNTol*1e10)
+      {
+        nls.RemoveFirst();
+        nls.Append(aResV); 
+        BRepLib::BoundingVertex(nls, aNC, aNTol);
+        BRep_Builder().UpdateVertex(aResV, aNC, aNTol);
+        reshaper.Replace(CHV, aResV.Oriented(CHV.Orientation()));
+        if (HV.Contains(aResV)) //if the closest vertex lays on edge => never contains in HV
+          HV.RemoveKey(aResV);
+      }
+      else
+      {
+        BRep_Builder().UpdateVertex(CHV, aNC, aNTol);
+        BRep_Builder().Range(aDE1, aFP, aPar);
+        BRep_Builder().Add(aDE1, aFV.Oriented(TopAbs_FORWARD));
+        BRep_Builder().Add(aDE1, CHV.Oriented(TopAbs_REVERSED));
+        //
+        BRep_Builder().Range(aDE2, aPar, aLP );
+        BRep_Builder().Add(aDE2, CHV.Oriented(TopAbs_FORWARD));
+        BRep_Builder().Add(aDE2, aLV.Oriented(TopAbs_REVERSED));
+        //
+
+        ///TODO temp
+        torem.Add(aResE);
+        toadd.Add(aDE1);
+        toadd.Add(aDE2);
+        //TopoDS_Compound aResCmp;
+        //BRep_Builder().MakeCompound(aResCmp);
+        //BRep_Builder().Add(aResCmp, aDE1);
+        //BRep_Builder().Add(aResCmp, aDE2);
+        //
+        //TopoDS_Wire aResW;
+        //BRep_Builder().MakeWire(aResW);
+        //BRep_Builder().Add(aResW, aDE1);
+        //BRep_Builder().Add(aResW, aDE2);
+        //TopoDS_Wire aResW = BRepBuilderAPI_MakeWire(aDE1, aDE2).Wire(); //this will control proper sharing and tolerance matching between vertices
+        /*{ //DEB
+        TopTools_IndexedMapOfShape VVVV;
+        TopExp::MapShapes(aResW, TopAbs_VERTEX, VVVV);
+        //cout << VVVV.Extent() << endl;
+        }*/
+        //aResW.Orientation(aResE.Orientation());
+        //reshape.Replace(aResE, aResCmp);
+      }
+    }
+    else
+    {
+      NCollection_List<TopoDS_Shape> nls; //TODO move to ext func
+      nls.Append(CHV); 
+      nls.Append(aResV); 
+      gp_Pnt aNC;
+      double aNTol;
+      BRepLib::BoundingVertex(nls, aNC, aNTol);
+      BRep_Builder().UpdateVertex(aResV, aNC, aNTol);
+      reshaper.Replace(CHV, aResV.Oriented(CHV.Orientation()));
+      if (HV.Contains(aResV)) //if the closest vertex lays on edge => never contains in HV
+        HV.RemoveKey(aResV);
+    }
+  }
+  //DEB
+  for (int i =1; i<= torem.Extent() ;i++)
+    BRep_Builder().Remove(theRes, torem(i));
+  //DEB
+  for (int i =1; i<= toadd.Extent() ;i++)
+    BRep_Builder().Add(theRes, toadd(i));
+  //
+  theRes = reshaper.Apply(theRes); //replace only vertices
+}
+
+static void FillNode2LLMap(Standard_Integer NewNode, const Poly_MakeLoops2D::Link& NewLink, 
+  NCollection_DataMap<Standard_Integer, Poly_MakeLoops2D::ListOfLink>& mNode2ListOfLinks)
+{
+  if (!mNode2ListOfLinks.IsBound(NewNode))
+    mNode2ListOfLinks.Bound(NewNode, Poly_MakeLoops2D::ListOfLink())->Append(NewLink);
+  else
+    mNode2ListOfLinks(NewNode).Append(NewLink);
+}
+
+static TopAbs_State GetStateOfSamplePoint(const TopoDS_Face& ff2, 
+  const IntTools_FClass2d& fclass,
+  const Bnd_Box2d& fbnd)
+{     
+  TopExp_Explorer exp(ff2, TopAbs_EDGE); //should contains at least one edge
+  TopoDS_Edge fe2 = TopoDS::Edge(exp.Current());
+  BRepAdaptor_Curve2d afe2(fe2, ff2);
+  gp_Pnt2d middlepoint = afe2.Value((afe2.LastParameter() + afe2.FirstParameter()) / 2.0);
+  Bnd_Box bb3d;
+  BRepBndLib::Add(ff2, bb3d);
+  Bnd_Box2d bb2d;
+  bb2d.Set(gp_Pnt2d(bb3d.CornerMin().X(), bb3d.CornerMin().Y())); 
+  bb2d.Add(gp_Pnt2d(bb3d.CornerMax().X(), bb3d.CornerMax().Y())); 
+  if (bb2d.IsOut(middlepoint))
+    return TopAbs_OUT;
+  else
+    return fclass.Perform(middlepoint);
+}
+
+bool HLRBRep_ParComp(const HLRFL_BndBoxTreeSelector::FaceParam& a, 
+  const HLRFL_BndBoxTreeSelector::FaceParam& b)
+{
+  return a.LPar < b.LPar;
+}
+
+static TopoDS_Shape ProcessLoops(const TopoDS_Shape& theRes,
+  NCollection_IndexedDataMap<TopoDS_Edge, BRepAdaptor_Curve2d, TopTools_ShapeMapHasher>& anEdAd,
+  NCollection_DataMap<TopoDS_Edge, Bnd_Box2d, TopTools_ShapeMapHasher> theEdBnd2d,
+  HLRAlgo_Projector& projector,
+  const TopTools_ListOfShape& anOrigShapes,
+  bool theMode, 
+  TopTools_DataMapOfShapeShape& OrigFaceToProjFace )
+{  
+  NCollection_List<TopoDS_Wire> theLoops;
+  NCollection_List<TopoDS_Wire> SelfLoops;
+  NCollection_DataMap<TopoDS_Shape, Bnd_Box2d, TopTools_ShapeMapHasher> aShToBnd2d;
+  TopoDS_Face aDraftPrFace;
+  BRep_Builder().MakeFace(aDraftPrFace, BRepLib::Plane(), Precision::Confusion());
+  TopTools_IndexedMapOfShape mN2V;
+  TopExp::MapShapes(theRes, TopAbs_VERTEX, mN2V);
+  NCollection_DataMap<Standard_Integer, Poly_MakeLoops2D::ListOfLink> mNode2ListOfLinks;
+  NCollection_DataMap<Poly_MakeLoops2D::Link, BRepFill_TangentLinkInfo> mL2TI;
+  //Create links for Poly_MakeLoops algo and bind them to the existing edges
+  NCollection_DataMap<Poly_MakeLoops2D::Link, TopoDS_Edge> mL2E;
+  Standard_Integer LastIndV = mN2V.Extent();
+  TopExp_Explorer ExpE;
+  ExpE.Init(theRes, TopAbs_EDGE);
+  for (; ExpE.More(); ExpE.Next())
+  {
+    const TopoDS_Edge& E = TopoDS::Edge(ExpE.Current());
+    // If edge contains only one vertex => self loop (should be non degenerated)
+    TopoDS_Vertex FV, LV;
+    FV = TopExp::FirstVertex(E, Standard_True); 
+    LV = TopExp::LastVertex(E, Standard_True); 
+    if (FV.IsSame(LV))
+    {
+      if (!BRep_Tool::Degenerated(E))
+      {
+        const TopoDS_Wire& aW = BRepLib_MakeWire(E).Wire();
+        SelfLoops.Append(aW);
+        Bnd_Box2d aBB;        
+        BndLib_Add2dCurve::Add(BRepAdaptor_Curve2d(E, aDraftPrFace), 0, aBB);
+        aShToBnd2d.Bind(aW, aBB);
+      }
+      continue;
+    }
+
+    const BRepAdaptor_Curve2d* anAd = anEdAd.Seek(E);
+    if (!anAd)
+    {
+      anEdAd.Add(E, BRepAdaptor_Curve2d(E, aDraftPrFace));
+      anAd = anEdAd.Seek(E);
+      Bnd_Box2d aBB;
+      BndLib_Add2dCurve::Add(*anEdAd.Seek(E), 0, aBB);
+      theEdBnd2d.Bind(E, aBB);
+    }
+    //NCollection_Handle<BRepAdaptor_Curve2d> adapt = new BRepAdaptor_Curve2d(E, aDraftPrFace);
+
+    gp_Pnt2d Pnt;
+    gp_Vec2d Vec;
+    gp_Dir2d D1F, D1L;
+    if (anAd->Curve().IsNull())
+      continue;
+    TopAbs_Orientation EOri = E.Orientation();
+    if (EOri == TopAbs_FORWARD)
+    {
+      anAd->D1(anAd->FirstParameter(), Pnt, Vec);
+      if (Vec.SquareMagnitude() <= gp::Resolution())
+        anAd->D1(anAd->FirstParameter() + Precision::Confusion(), Pnt, Vec);
+      D1F.SetCoord(Vec.X(), Vec.Y());
+      anAd->D1(anAd->LastParameter(), Pnt, Vec);
+      if (Vec.SquareMagnitude() <= gp::Resolution())
+        anAd->D1(anAd->LastParameter() - Precision::Confusion(), Pnt, Vec);
+      D1L.SetCoord(Vec.X(), Vec.Y());
+    }
+    else if (EOri == TopAbs_REVERSED)
+    {
+      anAd->D1(anAd->LastParameter(), Pnt, Vec);
+      if (Vec.SquareMagnitude() <= gp::Resolution())
+        anAd->D1(anAd->LastParameter() - Precision::Confusion(), Pnt, Vec);
+      D1F.SetCoord(-Vec.X(), -Vec.Y());
+      anAd->D1(anAd->FirstParameter(), Pnt, Vec);
+      if (Vec.SquareMagnitude() <= gp::Resolution())
+        anAd->D1(anAd->FirstParameter() + Precision::Confusion(), Pnt, Vec);
+      D1L.SetCoord(-Vec.X(), -Vec.Y());
+    }
+    else
+      continue;
+
+    Standard_Integer Node1 = mN2V.FindIndex(FV);
+    Standard_Integer Node2 = mN2V.FindIndex(LV);
+
+    Poly_MakeLoops2D::Link aLink(Node1, Node2);
+    aLink.flags = Poly_MakeLoops2D::LF_Both;
+    if (!mL2E.IsBound(aLink))
+    {
+      mL2E.Bind(aLink, E);
+      FillNode2LLMap(Node1, aLink, mNode2ListOfLinks);
+      FillNode2LLMap(Node2, aLink, mNode2ListOfLinks);
+      BRepFill_TangentLinkInfo* Info = mL2TI.Bound(aLink, BRepFill_TangentLinkInfo());
+      Info->myD1F = D1F;
+      Info->myD1L = D1L;
+    }
+    else
+    {
+      //link have been met twise. This may indicate that it is has 
+      //opposite direction now. Try to divide it (node1, node2) => (node1, ind) + (ind, node2)
+      //so it can be passed to loop maker
+      LastIndV++;
+      Poly_MakeLoops2D::Link aLink1(Node1, LastIndV);
+      aLink1.flags = Poly_MakeLoops2D::LF_Both;
+      Poly_MakeLoops2D::Link aLink2(LastIndV, Node2);
+      aLink2.flags = Poly_MakeLoops2D::LF_Both;
+      mL2E.Bind(aLink1, E);
+      mL2E.Bind(aLink2, TopoDS_Edge()); //indicates that one edge represented as two links
+
+      FillNode2LLMap(Node1, aLink1, mNode2ListOfLinks);
+      FillNode2LLMap(Node2, aLink2, mNode2ListOfLinks);
+      FillNode2LLMap(LastIndV, aLink1, mNode2ListOfLinks);
+      FillNode2LLMap(LastIndV, aLink2, mNode2ListOfLinks);
+
+      BRepFill_TangentLinkInfo* Info1 = mL2TI.Bound(aLink1, BRepFill_TangentLinkInfo());
+      Info1->myD1F = D1F;
+      Info1->myD1L = gp_Dir2d(1., 1.);
+      BRepFill_TangentLinkInfo* Info2 = mL2TI.Bound(aLink2, BRepFill_TangentLinkInfo());
+      Info2->myD1F = gp_Dir2d(1., 1.);
+      Info2->myD1L = D1L;
+    }
+  }
+
+  //DEBUG: print D1F
+  /*{
+  NCollection_DataMap<Standard_Integer, Poly_MakeLoops2D::ListOfLink>::Iterator it(mNode2ListOfLinks);
+  for (;it.More();it.Next())
+  {
+  int nK = it.Key();
+  Poly_MakeLoops2D::ListOfLink links = it.Value();
+  Poly_MakeLoops2D::ListOfLink::Iterator itl(links);
+  cout << "next:" << endl;
+  for (;itl.More();itl.Next())
+  {
+  BRepFill_TangentLinkInfo linfo = mL2TI(itl.Value());
+  cout << linfo.myD1F.X() <<  "  " << linfo.myD1F.Y() << endl;
+  TopoDS_Edge eee = mL2E(itl.Value());
+  }
+  }
+  */
+  //
+  BRepFill_PolyHelper helper(mL2TI, mNode2ListOfLinks);
+  Poly_MakeLoops2D aLoopMaker(1, &helper, NCollection_BaseAllocator::CommonBaseAllocator() );
+  for (NCollection_DataMap<Poly_MakeLoops2D::Link, TopoDS_Edge>::Iterator aMapIt (mL2E); aMapIt.More(); aMapIt.Next())
+    aLoopMaker.AddLink(aMapIt.Key());
+
+  aLoopMaker.Perform();   //try to find loops
+  Standard_Integer NbLoops = aLoopMaker.GetNbLoops();
+  Standard_Integer NbHangs = aLoopMaker.GetNbHanging();
+
+  cout << "NbLoops=" << NbLoops << endl;
+  cout << "NbHangs=" << NbHangs << endl;
+
+  // if (NbLoops == 0 || NbHangs != 0 )
+  //   return Standard_False;
+  
+  theLoops.Append(SelfLoops);
+  for (Standard_Integer i = 1; i <= NbLoops; i++)  //loops to wires
+  {
+    Poly_MakeLoops2D::Loop aLoop = aLoopMaker.GetLoop(i);
+    Poly_MakeLoops2D::Loop::Iterator it(aLoop);
+    BRepBuilderAPI_MakeWire aWM;
+    Bnd_Box2d aWBox2d;
+    TopoDS_Edge E;
+    for (;it.More(); it.Next())
+    {
+      const Poly_MakeLoops2D::Link& Link = it.Value();
+      E = mL2E(Link);
+      if (Link.flags & Poly_MakeLoops2D::LF_Reversed)
+        E.Reverse();
+      //if null => probably this edge was passed as two links (based on the same edge); so skip this edge
+      if (!E.IsNull()) 
+      {
+        aWM.Add(E);
+        aWBox2d.Add(theEdBnd2d(E));
+      }
+    }
+    if (aWM.IsDone())
+    {
+      TopoDS_Wire W = aWM.Wire();
+      if (W.Closed())    
+      {
+        theLoops.Append(W);
+        aShToBnd2d.Bind(W, aWBox2d);
+      }
+    }
+  }
+
+  //DEBUG
+ /* Poly_MakeLoops2D::ListOfLink theHLinks;
+  aLoopMaker.GetHangingLinks(theHLinks);
+  Poly_MakeLoops2D::ListOfLink::Iterator itt(theHLinks);
+
+  TopoDS_Compound cmpH;BRep_Builder().MakeCompound(cmpH);
+  for (; itt.More();itt.Next())
+  {
+    Poly_MakeLoops2D::Link alink = itt.Value();
+    const Poly_MakeLoops2D::Link& Link = itt.Value();
+    TopoDS_Edge E = mL2E(Link);
+    if (Link.flags & Poly_MakeLoops2D::LF_Reversed)
+      E.Reverse();
+    //if null => probably this edge was passed as two links (based on the same edge); so skip this edge
+    if (!E.IsNull()) 
+      BRep_Builder().Add(cmpH, E);
+  }*/
+  //
+
+  IntTools_Context context1;// = new IntTools_Context();
+  NCollection_List<TopoDS_Wire>::Iterator itL(theLoops);
+  NCollection_IndexedDataMap<TopoDS_Shape, double> lf1, lf2;
+  for (; itL.More(); itL.Next())
+  {
+    const TopoDS_Wire& aW = itL.Value();
+    if (aW.IsNull())
+      continue;
+    TopoDS_Face ff;
+    BRep_Builder().MakeFace(ff, BRepLib::Plane(), Precision::Confusion()); 
+    //plane is static; pcurves of edges are already based on this plane
+    BRep_Builder().Add(ff, aW);
+    aShToBnd2d(aW).Enlarge(0.001);
+    aShToBnd2d.Bind(ff, aShToBnd2d(aW)); //bndbox still the same
+    GProp_GProps pr;
+    BRepGProp::SurfaceProperties(ff, pr);
+    Standard_Real CurMass = pr.Mass();
+    if (Abs(CurMass) < 1e-10) //?? TODO 
+      continue;
+    if (CurMass >= 0)
+      lf1.Add(ff, CurMass);
+    else
+      lf2.Add(ff, CurMass);
+  }
+  NCollection_IndexedDataMap<TopoDS_Face, NCollection_List<TopoDS_Face>> FaceToIntWires;
+  for (int i = 1; i <= lf1.Size() && !lf2.IsEmpty(); i++)
+  {
+    //NCollection_Handle<BRepTopAdaptor_FClass2d> fclass;
+    NCollection_Sequence<TopoDS_Face> intf;
+    const TopoDS_Face& ff1 = TopoDS::Face(lf1.FindKey(i));
+    for (int j=1;j<= lf2.Size();j++)
+    {
+      double pm = lf1.FindFromIndex(i);
+      double nm = lf2.FindFromIndex(j);
+      if (pm < -nm)
+        continue;        
+      const TopoDS_Face& ff2 = TopoDS::Face(lf2.FindKey(j));
+      //if (!fclass)
+      //  fclass = new BRepTopAdaptor_FClass2d(ff1, Precision::Confusion());
+      IntTools_FClass2d& fclass = context1.FClass2d(ff1);
+      Bnd_Box2d fbnd = aShToBnd2d(ff1);
+      TopAbs_State st = GetStateOfSamplePoint(ff2, fclass, fbnd);
+      if (st == TopAbs_IN)
+        intf.Append(ff2);
+    }
+    NCollection_Map<int> intfInd;      
+    for (int i = 1; i<= intf.Size();i++)
+    {
+      if (intfInd.Contains(i))
+        continue;
+      //BRepTopAdaptor_FClass2d fclassInt(intf(i), Precision::Confusion());
+      IntTools_FClass2d& fclassInt = context1.FClass2d(intf(i));
+      Bnd_Box2d fbndi = aShToBnd2d(intf(i)); 
+      for (int j=1; j<= intf.Size();j++)
+      {
+        if (i==j)
+          continue;
+        if (intfInd.Contains(j))
+          continue;
+        TopAbs_State st = GetStateOfSamplePoint(intf(j), fclassInt, fbndi);
+        if (st == TopAbs_OUT) //note that intf-faces are holes
+          intfInd.Add(j);
+      }
+    }
+    FaceToIntWires.Add(ff1, NCollection_List<TopoDS_Face>());
+    NCollection_List<TopoDS_Face>& nl = FaceToIntWires.ChangeFromKey(ff1);
+
+    for (int i = 1; i<= intf.Size();i++)
+    {
+      if (intfInd.Contains(i))
+        continue;
+      nl.Append(intf(i));
+    }
+  }
+
+  TopoDS_Compound aResCmp;
+  BRep_Builder().MakeCompound(aResCmp);
+
+  TopTools_ListIteratorOfListOfShape itOrS(anOrigShapes);
+  TopTools_IndexedMapOfShape anOrigFaces;  
+  for (;itOrS.More();itOrS.Next())
+    TopExp::MapShapes(itOrS.Value(), TopAbs_FACE, anOrigFaces);
+
+  NCollection_UBTree <Standard_Integer, Bnd_Box> aTreeFL;
+  NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFillerFL (aTreeFL);
+  for (Standard_Integer i = 1; i <= anOrigFaces.Extent(); i++)
+  { 
+    const TopoDS_Face& aF = TopoDS::Face(anOrigFaces(i));
+    Bnd_Box aBB;
+    BRepBndLib::Add(aF, aBB);
+    aTreeFillerFL.Add(i, aBB);
+  }
+
+  aTreeFillerFL.Fill();
+  HLRFL_BndBoxTreeSelector aSelFL(anOrigFaces, theMode);
+
+  for (int i = 1; i <= FaceToIntWires.Extent(); i++)
+  {
+    TopoDS_Face cf = FaceToIntWires.FindKey(i); 
+    NCollection_List<TopoDS_Face>::Iterator it(FaceToIntWires.FindFromIndex(i));
+    for (;it.More();it.Next())
+    {
+      TopoDS_Face ff = it.Value();
+      TopoDS_Iterator it(ff);
+      TopoDS_Shape int_wire = it.Value();
+      BRep_Builder().Add(cf, int_wire);
+    }
+    gp_Pnt2d p2d;
+    gp_Pnt p3d;
+    TopExp_Explorer exp(cf, TopAbs_EDGE);
+    Handle(IntTools_Context) context = new IntTools_Context();
+    BOPTools_AlgoTools3D::PointNearEdge( TopoDS::Edge(exp.Current()), cf, p2d, p3d, context);
+    gp_Lin shot_line = projector.Shoot(p2d.X(), p2d.Y());
+
+    aSelFL.ResetResult();
+    aSelFL.SetLine( shot_line );
+    aTreeFL.Select(aSelFL);
+
+    std::vector<HLRFL_BndBoxTreeSelector::FaceParam> fp = aSelFL.GetRParams();
+    if (!fp.empty())
+    {
+      BRep_Builder().Add(aResCmp, cf);
+      if (theMode)
+      {
+        std::sort(fp.begin(), fp.end(), HLRBRep_ParComp);
+        OrigFaceToProjFace.Bind(cf, fp.front().myF);
+      }
+    }
+  }
+  //
+  return aResCmp;
+}
+
+TopoDS_Shape HLRBRep_HLRToShape::CompoundOfFaces(bool theMode,
+  TopTools_DataMapOfShapeShape& OrigFaceToProjFace)
+{
+  //
+  TopTools_ListOfShape anOrigShapes;
+  const HLRBRep_SeqOfShapeBounds& aSeqOfShBnds = myAlgo->SeqOfShapeBounds();
+  for (int i=1; i<= aSeqOfShBnds.Size(); i++)
+    anOrigShapes.Append(aSeqOfShBnds(i).Shape()->OriginalShape());
+  //
+  TopoDS_Compound aTotalOSh;
+  BRep_Builder BB;
+  BB.MakeCompound(aTotalOSh);
+
+  TopoDS_Shape aSharpSh = InternalCompound(HLRBRep_Sharp, Standard_True, TopoDS_Shape(), Standard_False); //TODO check
+  if (!aSharpSh.IsNull())
+    BB.Add(aTotalOSh, aSharpSh);
+  TopoDS_Shape anOutLSh = InternalCompound(HLRBRep_OutLine, Standard_True, TopoDS_Shape(), Standard_False);
+  if (!anOutLSh.IsNull())
+    BB.Add(aTotalOSh, anOutLSh);
+  TopoDS_Shape aRg1Sh = InternalCompound(HLRBRep_Rg1Line, Standard_True, TopoDS_Shape(), Standard_False);
+  if (!aRg1Sh.IsNull())
+    BB.Add(aTotalOSh, aRg1Sh);
+
+  //
+  BRepLib::BuildCurves3d(aTotalOSh);
+  BRepLib::SameParameter(aTotalOSh, Precision::PConfusion(),Standard_False);
+  //
+  if( !FuseVE (aTotalOSh))
+    return TopoDS_Shape();
+  //
+  NCollection_DataMap<TopoDS_Edge, Bnd_Box2d, TopTools_ShapeMapHasher> theEdBnd2d;
+  NCollection_IndexedDataMap<TopoDS_Edge, BRepAdaptor_Curve2d, TopTools_ShapeMapHasher> anEdAd; 
+  ProcessHVertices(aTotalOSh, anEdAd, theEdBnd2d);
+  //
+  TopoDS_Shape aRes = ProcessLoops(aTotalOSh, anEdAd, theEdBnd2d, 
+    myAlgo->Projector(), anOrigShapes, theMode, OrigFaceToProjFace);
+  //
+  return aRes;
+}
+
index d88d2ab0a82a204f04a8aa79b0e2a4e1021c7f75..d5054b282eb294cadd3ba0470ab1900014c5301a 100644 (file)
@@ -25,6 +25,7 @@
 #include <Standard_Integer.hxx>
 #include <Standard_Boolean.hxx>
 #include <HLRBRep_TypeOfResultingEdge.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
 class HLRBRep_Algo;
 class TopoDS_Shape;
 class HLRBRep_Data;
@@ -131,6 +132,8 @@ public:
                                  const Standard_Boolean            visible,
                                  const Standard_Boolean            In3d);
 
+    TopoDS_Shape CompoundOfFaces (bool theMode,
+                                  TopTools_DataMapOfShapeShape& OrigFaceToProjFace);
 
 
 protected:
index 465f1a51b47e4011037967a65d0f6287195c58cb..4624aa84e8353b0430bc7cd0d42e7189b27fc7f6 100644 (file)
@@ -271,8 +271,8 @@ HLRBRep_ShapeToHLR::ExploreShape (const Handle(HLRTopoBRep_OutLiner)& S,
   TopExp_Explorer exshell, exface, exedge;
   Standard_Integer i = 1;
 
-  ParallelSurfInitFunctor aFunctor2(DS->FDataArray(), FM);
-  OSD_Parallel::For(1, FM.Extent() + 1, aFunctor2, false);
+  ParallelSurfInitFunctor aSurfFunctor(DS->FDataArray(), FM);
+  OSD_Parallel::For(1, FM.Extent() + 1, aSurfFunctor, Standard_False);
 
   i = 0;
 
index 30822a1ccb763f6d0d12ec9e93badd4b5e5e5a66..e098674a05f86b2d6f51344572bc95c10d48bc87 100644 (file)
@@ -222,9 +222,8 @@ void  HLRTopoBRep_DSFiller::Insert (const TopoDS_Shape& S,
   for (;itBRTIt.More();itBRTIt.Next(), f++)
     nonInitBRTArr(f) = itBRTIt.Value();
 
-  ParallelBRTInitFunctor aFunctor1(nonInitBRTArr);
-  OSD_Parallel::For(nonInitBRTArr.Lower(), nonInitBRTArr.Upper() + 1, aFunctor1, false);
-  //
+  ParallelBRTInitFunctor aBRTFunctor(nonInitBRTArr);
+  OSD_Parallel::For(nonInitBRTArr.Lower(), nonInitBRTArr.Upper() + 1, aBRTFunctor, Standard_False);
 
   //
   NCollection_List<ContourSurfInfo>::Iterator itCS(ContourSurfInfoList);
@@ -235,8 +234,8 @@ void  HLRTopoBRep_DSFiller::Insert (const TopoDS_Shape& S,
     aContourSurfInfoArray(f) = itCS.Value();
 
   //
-  ParallelContourFunctor aFunctor(aContourSurfInfoArray);
-  OSD_Parallel::For(aContourSurfInfoArray.Lower(), aContourSurfInfoArray.Upper() + 1, aFunctor, false);
+  ParallelContourFunctor aContourFunctor(aContourSurfInfoArray);
+  OSD_Parallel::For(aContourSurfInfoArray.Lower(), aContourSurfInfoArray.Upper() + 1, aContourFunctor, Standard_False);
   //
 
   for (f = aContourSurfInfoArray.Lower(); f <= aContourSurfInfoArray.Upper(); f++)
index 33a58bf43f2d1a0586bf8d0e74cb9f4e98fb3cb9..7e61c5ff5b87bcf67132f784bde05775112e2384 100644 (file)
@@ -1593,6 +1593,7 @@ static Standard_Integer OCC26930(Draw_Interpretor& theDI,
 //function : OCC27341
 //purpose : check exact HLR algorighm's work
 //=======================================================================
+#include <OSD_Timer.hxx>
 static Standard_Integer OCC27341 (Draw_Interpretor& , Standard_Integer n, const char** a)
 {
   if (n != 4)
@@ -1652,7 +1653,11 @@ static Standard_Integer OCC27341 (Draw_Interpretor& , Standard_Integer n, const
                     anOrigin.X(), anOrigin.Y(), anOrigin.Z(),
                     aDX.X(), aDX.Y(), aDX.Z());
 
+  OSD_Timer aTimer;
+  aTimer.Start();
   Reflector.Perform();
+  aTimer.Stop();
+  aTimer.Show();
 
   TopoDS_Compound Result;
   BRep_Builder BB;
@@ -1667,12 +1672,86 @@ static Standard_Integer OCC27341 (Draw_Interpretor& , Standard_Integer n, const
   TopoDS_Shape SmoothEdges = Reflector.GetCompoundOf3dEdges(HLRBRep_Rg1Line, Standard_True, Standard_False);
   if (!SmoothEdges.IsNull())
     BB.Add(Result, SmoothEdges);
-  
+
   DBRep::Set(a[1], Result);
 
   return 0;
 }
 
+//=======================================================================
+//function : OCC28991
+//purpose : 
+//=======================================================================
+static Standard_Integer OCC28991 (Draw_Interpretor& , Standard_Integer n, const char** a)
+{
+  if (n != 4)
+  {
+    cout << "Use: OCC28991 res shape axo/top/bottom/front/back/left/right" << endl;
+    return 1;
+  }
+
+  TopoDS_Shape aShape =  DBRep::Get(a[2]);
+  if (aShape.IsNull())
+    return 1;
+
+  gp_Pnt anOrigin(0.,0.,0.);
+  gp_Dir aNormal(0.57735026918962573, -0.57735026918962573, 0.57735026918962573);
+  gp_Ax2 anAxes(anOrigin, aNormal);
+  gp_Dir aDX = anAxes.XDirection();
+  
+  HLRAppli_ReflectLines Reflector(aShape);
+
+  if (strcmp(a[3],"axo") == 0)
+  {
+    aNormal.SetCoord(0.57735026918962573, -0.57735026918962573, 0.57735026918962573);
+    aDX.SetCoord(-0.40824829046386307, 0.40824829046386307, 0.81649658092772615);
+  }
+  else if (strcmp(a[3],"top") == 0)
+  {
+    aNormal.SetCoord(0,0,1);
+    aDX.SetCoord(0,1,0);
+  }
+  else if (strcmp(a[3],"bottom") == 0)
+  {
+    aNormal.SetCoord(0,0,-1);
+    aDX.SetCoord(0,-1,0);
+  }
+  else if (strcmp(a[3],"front") == 0)
+  {
+    aNormal.SetCoord(0,-1,0);
+    aDX.SetCoord(0,0,1);
+  }
+  else if (strcmp(a[3],"back") == 0)
+  {
+    aNormal.SetCoord(0,1,0);
+    aDX.SetCoord(0,0,1);
+  }
+  else if (strcmp(a[3],"left") == 0)
+  {
+    aNormal.SetCoord(-1,0,0);
+    aDX.SetCoord(0,0,1);
+  }
+  else if (strcmp(a[3],"right") == 0)
+  {
+    aNormal.SetCoord(1,0,0);
+    aDX.SetCoord(0,0,1);
+  }
+    
+  Reflector.SetAxes(aNormal.X(), aNormal.Y(), aNormal.Z(),
+                    anOrigin.X(), anOrigin.Y(), anOrigin.Z(),
+                    aDX.X(), aDX.Y(), aDX.Z());
+
+  Reflector.Perform();
+
+  TopTools_DataMapOfShapeShape aDummy;
+  TopoDS_Shape aFaces = Reflector.GetCompoundOfFaces(true, aDummy);
+
+  DBRep::Set(a[1], aFaces);
+
+  return 0;
+}
+
+
 //=======================================================================
 //function : OCC27466
 //purpose :
@@ -3036,6 +3115,9 @@ void QABugs::Commands_20(Draw_Interpretor& theCommands) {
   theCommands.Add("OCC27341",
                   "OCC27341 res shape axo/top/bottom/front/back/left/right",
                   __FILE__, OCC27341, group);
+  theCommands.Add("OCC28991",
+                  "OCC289911 res shape axo/top/bottom/front/back/left/right",
+                  __FILE__, OCC28991, group);
   theCommands.Add ("OCC26747_1", "OCC26747_1 result", __FILE__, OCC26747_1, group);
   theCommands.Add ("OCC26747_2", "OCC26747_2 result", __FILE__, OCC26747_2, group);
   theCommands.Add ("OCC26747_3", "OCC26747_3 result", __FILE__, OCC26747_3, group);
index 6a88cac43dacaf27a818d672207d0d8c49e9e029..c8d1c640fedaec909e075ef55c3bf3317f4538f0 100755 (executable)
@@ -6,3 +6,4 @@ TKG2d
 TKG3d
 TKGeomAlgo
 TKTopAlgo
+TKBO
\ No newline at end of file