Salome HOME
Merge commit '4823245056426a9ccf9c7965daecf11459f58af5' into V9_11_BR
[modules/geom.git] / src / ShHealOper / ShHealOper_EdgeDivide.cxx
index 3a910c55d01925fe395098b572921eb0610be7ab..a06cf91a657d1b3043eb3a23c0ae99116de9b5a3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2022  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 // Created:   30.04.04 16:44:47
 // Author:    Galina KULIKOVA
 //
+#include <BRep_Tool.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
+#include <Geom2d_Curve.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <Geom_Curve.hxx>
+#include <Precision.hxx>
 #include <ShHealOper_EdgeDivide.hxx>
-#include <ShapeUpgrade_WireDivide.hxx>
-#include <ShHealOper_SplitCurve3d.hxx>
 #include <ShHealOper_SplitCurve2d.hxx>
-#include <TopTools_ListOfShape.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <BRep_Tool.hxx>
-#include <ShapeFix_Edge.hxx>
+#include <ShHealOper_SplitCurve3d.hxx>
 #include <ShapeAnalysis_Edge.hxx>
-#include <GeomAdaptor_Curve.hxx>
-#include <Geom2dAdaptor_Curve.hxx>
+#include <ShapeFix_Edge.hxx>
+#include <ShapeUpgrade_WireDivide.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
 #include <TopoDS.hxx>
-#include <Geom_Curve.hxx>
 #include <TopoDS_Face.hxx>
-#include <Geom2d_Curve.hxx>
-#include <GCPnts_AbscissaPoint.hxx>
-#include <TopExp.hxx>
-#include <Precision.hxx>
+
 //#include <.hxx>
 //#include <.hxx>
 //=======================================================================
@@ -113,10 +117,67 @@ Standard_Boolean ShHealOper_EdgeDivide::Perform(const TopoDS_Shape& theEdge,
   return myDone;
 }
 //=======================================================================
-//function : build
+//function : Perform
 //purpose  : 
 //=======================================================================
 
+Standard_Boolean ShHealOper_EdgeDivide::Perform(const TopoDS_Shape& theEdge, 
+                                                const TopoDS_Shape& thePoints)
+{
+  myDone = Standard_False;
+  myErrorStatus = ShHealOper_NotError;
+  if(theEdge.ShapeType() != TopAbs_EDGE) {
+    myErrorStatus = ShHealOper_InvalidParameters;
+    return myDone;
+  }
+  myDivideParamMode = true;
+  myEdge = TopoDS::Edge(theEdge);
+  Handle(TColStd_HSequenceOfReal) aSeqValues = new TColStd_HSequenceOfReal;
+
+  double aFirst,aLast;
+  Handle(Geom_Curve) aCurve = BRep_Tool::Curve(myEdge,aFirst,aLast);
+  if ( aCurve.IsNull() ) return false;
+  GeomAPI_ProjectPointOnCurve aProjector;
+  aProjector.Init( aCurve, aFirst, aLast );
+
+  TopTools_MapOfShape vMap;
+  TopExp_Explorer vertex( thePoints, TopAbs_VERTEX );
+  std::set< double > params; // to exclude equal params
+  for ( ; vertex.More(); vertex.Next() )
+  {
+    if ( !vMap.Add( vertex.Current() )) continue;
+    gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( vertex.Current() ));
+    aProjector.Perform( p );
+    if ( aProjector.NbPoints() > 0 )
+    {
+      double     u = double( aProjector.LowerDistanceParameter() );
+      double param = ( u - aFirst ) / ( aLast - aFirst );
+      params.insert( param );
+    }
+  }
+  // remove too close params
+  params.insert( 0 );
+  params.insert( 1 );
+  std::set< double >::iterator p2 = params.begin(), p1 = p2++;
+  while ( p2 != params.end() )
+  {
+    if ( Abs( *p2 - *p1 ) < 1e-3 ) // compare normalized params 
+      params.erase( p1 );
+    p1 = p2++;
+  }
+  p1 = params.begin(); ++p1; // skip aFirst
+  p2 = params.end();   --p2; // skip aLast
+  for ( ; p1 != p2; ++p1 )
+    aSeqValues->Append( *p1 );
+
+  myDone = build(aSeqValues);
+  return myDone;
+}
+//=======================================================================
+//function : build
+//purpose  :
+//=======================================================================
+
 Standard_Boolean ShHealOper_EdgeDivide::build(const Handle(TColStd_HSequenceOfReal)& theValues)
 {
   if(myEdge.IsNull() || !theValues->Length()) {
@@ -124,16 +185,16 @@ Standard_Boolean ShHealOper_EdgeDivide::build(const Handle(TColStd_HSequenceOfRe
     return Standard_False;
   }
 
-  Standard_Boolean has3d = Standard_False, 
-  has2d = Standard_False, 
-  hasPCurves = Standard_False;
-  
-  //computation of the split values in dependance from specified mode and values.
+  Standard_Boolean has3d = Standard_False,
+    has2d = Standard_False,
+    hasPCurves = Standard_False;
+
+  //computation of the split values in dependence from specified mode and values.
   if(!computeValues(theValues, has3d,has2d,hasPCurves)) {
     myErrorStatus = ShHealOper_InvalidParameters;
     return Standard_False;
   }
-  
+
   //setting split values in the splitting curve tools.
   Handle(ShapeUpgrade_WireDivide) aSplitTool = new ShapeUpgrade_WireDivide;
   aSplitTool->Load(myEdge);
@@ -152,8 +213,8 @@ Standard_Boolean ShHealOper_EdgeDivide::build(const Handle(TColStd_HSequenceOfRe
     myErrorStatus = ShHealOper_InvalidParameters;
     return Standard_False;
   }
-  
-  //split 3d curve and pcurve for each face reffering to edge.
+
+  //split 3d curve and pcurve for each face referring to edge.
   Standard_Boolean isDone = Standard_True;
   if(hasPCurves) {
     const TopTools_ListOfShape& lfaces  = myMapEdgesFace.FindFromKey(myEdge);
@@ -174,7 +235,10 @@ Standard_Boolean ShHealOper_EdgeDivide::build(const Handle(TColStd_HSequenceOfRe
         myErrorStatus = ShHealOper_ErrorExecution;
   }
   if(isDone)
+  {
     myResultShape = myContext->Apply(myInitShape);
+    myStatistics.AddModif("Vertex added on edge", theValues->Length() );
+  }
   return isDone;
   
 }
@@ -197,7 +261,7 @@ Standard_Boolean ShHealOper_EdgeDivide::computeValues(const Handle(TColStd_HSequ
   
   Standard_Real aFirst =0.,aLast=0.;
 
-  //computation of the split values if edge should be splitted by parameter.
+  //computation of the split values if edge should be split by parameter.
   if(myDivideParamMode) {
     BRep_Tool::Range(myEdge,aFirst,aLast);
     Handle(Geom_Curve) aCurve = BRep_Tool::Curve(myEdge,aFirst,aLast);
@@ -211,7 +275,7 @@ Standard_Boolean ShHealOper_EdgeDivide::computeValues(const Handle(TColStd_HSequ
     }
   }
   else {
-     //computation of the split values if edge should be splitted by length.
+     //computation of the split values if edge should be split by length.
     ShapeAnalysis_Edge sae;
     Handle(Geom_Curve) aCurve;
     Standard_Real aCurLen =0.;