]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
22757: [EDF] Vertex on Edge
authoreap <eap@opencascade.com>
Tue, 21 Oct 2014 16:06:51 +0000 (20:06 +0400)
committereap <eap@opencascade.com>
Tue, 21 Oct 2014 16:06:51 +0000 (20:06 +0400)
21 files changed:
doc/salome/examples/repairing_operations_ex10.py
doc/salome/gui/GEOM/images/divedgebypoint.png [new file with mode: 0644]
doc/salome/gui/GEOM/images/repair8.png [changed mode: 0755->0644]
doc/salome/gui/GEOM/input/add_point_on_edge_operation.doc
idl/GEOM_Gen.idl
resources/CMakeLists.txt
resources/pointonedgebypoint.png [new file with mode: 0644]
src/GEOMGUI/GEOM_images.ts
src/GEOMGUI/GEOM_msg_en.ts
src/GEOMImpl/GEOMImpl_HealingDriver.cxx
src/GEOMImpl/GEOMImpl_IHealingOperations.cxx
src/GEOMImpl/GEOMImpl_IHealingOperations.hxx
src/GEOMImpl/GEOMImpl_Types.hxx
src/GEOM_I/GEOM_IHealingOperations_i.cc
src/GEOM_I/GEOM_IHealingOperations_i.hh
src/GEOM_SWIG/GEOM_TestHealing.py
src/GEOM_SWIG/geomBuilder.py
src/RepairGUI/RepairGUI_DivideEdgeDlg.cxx
src/RepairGUI/RepairGUI_DivideEdgeDlg.h
src/ShHealOper/ShHealOper_EdgeDivide.cxx
src/ShHealOper/ShHealOper_EdgeDivide.hxx

index 898991b4e80931ef5f90ac36ef9a8d12997dab49..c2dbc160f0b13cedfcf5b40e987210ba4c03e3a2 100644 (file)
@@ -6,6 +6,8 @@ import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New(salome.myStudy)
 
+# Variant 1: using DivideEdge()
+
 # create vertices
 p1 = geompy.MakeVertex(0,0,50)
 p2 = geompy.MakeVertex(60,0,50)
@@ -27,4 +29,14 @@ edge_points = geompy.SubShapeAllSortedCentres(divide, geompy.ShapeType["VERTEX"]
 for point in edge_points:
     geompy.addToStudyInFather(divide, point, "Edge's point after divide")
 
+
+# Variant 2: using DivideEdgeByPoint()
+box  = geompy.MakeBox(0,0,0, 10,10,10, theName="box")
+p    = geompy.MakeVertex( 3, -2, 1, theName="point to project" )
+edge = geompy.GetEdgeNearPoint( box, p, theName="edge to split")
+
+div  = geompy.DivideEdgeByPoint( box, edge, p, theName="box (edge divided)")
+
+
 salome.sg.updateObjBrowser(1) 
diff --git a/doc/salome/gui/GEOM/images/divedgebypoint.png b/doc/salome/gui/GEOM/images/divedgebypoint.png
new file mode 100644 (file)
index 0000000..cb80833
Binary files /dev/null and b/doc/salome/gui/GEOM/images/divedgebypoint.png differ
old mode 100755 (executable)
new mode 100644 (file)
index d765446..5c30a97
Binary files a/doc/salome/gui/GEOM/images/repair8.png and b/doc/salome/gui/GEOM/images/repair8.png differ
index 4a58ee64a66a01126f96464bef71a824b85ab7af..587f1b9681460fc831624ff12ad2ab546a74e026 100644 (file)
@@ -5,44 +5,66 @@
 \n To <b>Add Point on Edge</b> in the <b>Main Menu</b> select
 <b>Repair - > Add Point on Edge</b>.
 
-\n This operation splits an edge in two new edges in accordance with the
-specified mode (by length or by parameter) and a value specifying the
-position of the point on edge (for example val =0.5; mode =
-by length). This operation is available in <b>OCC Viewer</b> only.
-
-\n The \b Result will be a \b GEOM_Object.
-
-\n <b>TUI Command:</b> <em>geompy.DivideEdge(Shape, EdgeID, Value,
-IsByParameter)</em>
-- \em Shape is a shape which contains an edge to be divided
-- \em EdgeID is the ID of the edge to be divided, if it is = -1, 
-then \em Shape should be an edge itself
-- \em Value is a value of parameter on edge or length parameter,
-depending on \em IsByParameter.
-- \em IsByParameter is a boolean flag, specifying operation mode:
-  - \c True: \em Value is treated as a curve parameter [0..1]
-  - \c False: \em Value is treated as a length parameter [0..1] 
-
-<b>Arguments:</b> Name + 1 Edge + 1 Value setting the position of
-the point according to one of the selected modes.
-
-The difference between "by parameter" and "by length" modes becomes
-apparent on the edges with irregular parametrization (for example,
-b-splines which usually have irregular density by the length).
-For example, value 0.5 "by length" on such edge will produce the point
-in the middle of this edge (equidistant from both its ends); the same
-0.5 value "by parameter" will result in the point situated closer to
-one of the ends (depending on the actual parametrization).
-
-\image html repair8.png
+This operation splits an edge in two new edges.
+This operation is available in <b>OCC Viewer</b> only.
+
+The \b Result will be a \b GEOM_Object.
+
+\n Location of a new vertex on a selected edge can be defined two ways:
+<ol>
+  <li> We can specify a position (ranging from 0.0 to 1.0) of the
+    vertex on the selected edge either by length or by parameter.
+    <p>
+    <b>TUI Command:</b> <em>geompy.DivideEdge(Shape, EdgeID, Value,
+      IsByParameter)</em>
+    <ul>
+      <li> \em Shape is a shape which contains an edge to be divided</li>
+      <li>\em EdgeID is the ID of the edge to be divided, if it is = -1,
+        then \em Shape should be an edge itself.</li>
+      <li> \em Value is a value of parameter on edge or length parameter,
+        depending on \em IsByParameter. </li>
+      <li> \em IsByParameter is a boolean flag, specifying operation mode:
+        - \c True: \em Value is treated as a curve parameter [0..1]
+        - \c False: \em Value is treated as a length parameter [0..1] </li>
+    </ul>
+    \b Arguments: Name + 1 Edge + 1 Value setting the position of
+    the point according to one of the selected modes.
+
+    The difference between "by parameter" and "by length" modes becomes
+    apparent on the edges with irregular parametrization (for example,
+    b-splines which usually have irregular density by the length).
+    For example, value 0.5 "by length" on such edge will produce the point
+    in the middle of this edge (equidistant from both its ends); the same
+    0.5 value "by parameter" will result in the point situated closer to
+    one of the ends (depending on the actual parametrization).
+
+    \image html repair8.png
+    \n\n
+  </li>
+  <li>We can select a point that will be projected to the selected
+    edge to find the location of the new vertex.
+    <p>
+    <b>TUI Command:</b> <em>geompy.DivideEdgeByPoint(Shape, Edge, Point)</em>
+    <ul>
+      <li> \em Shape is a shape which contains an edge to be divided</li>
+      <li>\em Edge is an edge to be divided (or it's ID, if it is = -1,
+        then \em Shape should be an edge itself).</li>
+      <li> \em Point is a point to project to \a Edge. </li>
+    </ul>
+    \b Arguments: Name + 1 Edge + 1 Point.
+
+    \image html divedgebypoint.png
+
+  </li>
+</ol>
 
 \n <b>Example:</b>
 
 \image html image167.png "The initial edge"
 
-\image html image168.png "The edge split in two segments" 
+\image html image168.png "The edge split in two segments"
 
-Our <b>TUI Scripts</b> provide you with useful examples of the use of 
+Our <b>TUI Scripts</b> provide you with useful examples of the use of
 \ref tui_add_point_on_edge "Repairing Operations".
 
 */
index 84d4410159ddf31a1ee314cc8841074b3c212947..0d65fd8f866769509f4d977dbf3b6829421cdb5e 100644 (file)
@@ -3654,7 +3654,7 @@ module GEOM
     GEOM_Object RemoveInternalFaces (in ListOfGO theSolids);
 
     /*!
-     *  \brief Addition of a point to a given edge object.
+     *  \brief Addition of a point to a given edge of \a theObject.
      *  \param theObject Shape to be processed.
      *  \param theEdgeIndex Index of edge to be divided within theObject's shape,
      *                      if -1, then theObject itself is the edge.
@@ -3662,11 +3662,24 @@ module GEOM
      *                  depending on \a isByParameter.
      *  \param isByParameter If TRUE : \a theValue is treated as a curve parameter [0..1],
      *                       if FALSE : \a theValue is treated as a length parameter [0..1]
-     *  \return New GEOM_Object, containing processed shape.
+     *  \return New GEOM_Object, containing the processed shape.
      */
     GEOM_Object DivideEdge (in GEOM_Object theObject, in short theEdgeIndex,
                             in double theValue, in boolean isByParameter);
 
+    /*!
+     *  \brief Addition of a point to a given edge of \a theObject by projecting
+     *         another point to the given edge.
+     *  \param theObject Shape to be processed.
+     *  \param theEdgeIndex Index of edge to be divided within theObject's shape,
+     *                      if -1, then theObject itself is the edge.
+     *  \param thePoint Point to project to theEdgeIndex-th edge.
+     *  \return New GEOM_Object, containing the processed shape.
+     */
+    GEOM_Object DivideEdgeByPoint (in GEOM_Object theObject,
+                                   in short       theEdgeIndex,
+                                   in GEOM_Object thePoint);
+
     /*!
      *  \brief Suppress the vertices in the wire in case if adjacent edges are C1 continuous.
      *  \param theWire Wire to minimize the number of C1 continuous edges in.
index e3afdf6cb91e8a0c9629e92d01f88ad45d30a6e3..1dd29615580ca4af7501ce85ab3dc4b89692a9c4 100755 (executable)
@@ -145,6 +145,7 @@ SET( _res_files
   planeworkingorigin.png
   point2.png
   pointonedge.png
+  pointonedgebypoint.png
   pointonface.png
   point_line_intersection.png
   polyline.png
diff --git a/resources/pointonedgebypoint.png b/resources/pointonedgebypoint.png
new file mode 100644 (file)
index 0000000..2068517
Binary files /dev/null and b/resources/pointonedgebypoint.png differ
index 900d965ad3e423b1aef6388b31e2b4356716c7ea..db8b15dd1d04e91302b036b00817046836e1d699 100644 (file)
             <source>ICON_DLG_DIVIDE_EDGE</source>
             <translation>pointonedge.png</translation>
         </message>
+        <message>
+            <source>ICON_DLG_DIVIDE_EDGE_BY_PNT</source>
+            <translation>pointonedgebypoint.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_ELLIPSE_PV</source>
             <translation>ellipsepointvector.png</translation>
index 3a13360699d0a2f33571d544ead15f9034f85253..1dcc33e191f4c2385aeeb4b606db58d2c1747937 100644 (file)
@@ -38,6 +38,14 @@ Do you still want to delete these objects?</translation>
         <source>DEVIDE_EDGE_NEW_OBJECT_NAME</source>
         <translation>NewObject</translation>
     </message>
+    <message>
+        <source>DEVIDE_EDGE_BAD_PROJ_MSG</source>
+        <translation>Projection outside the edge</translation>
+    </message>
+    <message>
+        <source>DEVIDE_EDGE_BY_PROJ_POINT</source>
+        <translation>Point to project</translation>
+    </message>
     <message>
         <source>ERROR_SHAPE_TYPE</source>
         <translation>Object of incorrect type selected!
index 5cb3b922c1f159560de7e2a54820a1b06851718f..48bca409576ade6ac9c8d0992a10136492605214 100644 (file)
@@ -145,6 +145,7 @@ Standard_Integer GEOMImpl_HealingDriver::Execute(TFunction_Logbook& log) const
     RemoveInternalFaces(&HI, anOriginalShape, aShape);
     break;
   case DIVIDE_EDGE:
+  case DIVIDE_EDGE_BY_POINT:
     AddPointOnEdge(&HI, anOriginalShape, aShape);
     break;
   case CHANGE_ORIENTATION:
@@ -533,26 +534,44 @@ GEOMImpl_HealingDriver::RemoveInternalFaces (GEOMImpl_IHealing*  theHI,
 //function :  AddPointOnEdge
 //purpose  :
 //=======================================================================
-Standard_Boolean GEOMImpl_HealingDriver::AddPointOnEdge (GEOMImpl_IHealing* theHI,
+Standard_Boolean GEOMImpl_HealingDriver::AddPointOnEdge (GEOMImpl_IHealing*  theHI,
                                                          const TopoDS_Shape& theOriginalShape,
-                                                         TopoDS_Shape& theOutShape) const
+                                                         TopoDS_Shape&       theOutShape) const
 {
   Standard_Boolean isByParameter = theHI->GetIsByParameter();
-  Standard_Integer anIndex = theHI->GetIndex();
-  Standard_Real aValue = theHI->GetDevideEdgeValue();
+  Standard_Integer       anIndex = theHI->GetIndex();
+  Standard_Real           aValue = theHI->GetDevideEdgeValue();
 
+  TopoDS_Shape pointToProject;
+  {
+    Handle(TColStd_HSequenceOfTransient) funs = theHI->GetShapes();
+    if ( !funs.IsNull() && funs->Length() > 0 ) {
+      Handle(GEOM_Function) fun = Handle(GEOM_Function)::DownCast( funs->Value(1) );
+      if ( !fun.IsNull() )
+        pointToProject = fun->GetValue();
+    }
+  }
+  
   ShHealOper_EdgeDivide aHealer (theOriginalShape);
 
   Standard_Boolean aResult = Standard_False;
-  if (anIndex == -1) { // apply algorythm for the whole shape which is EDGE
-    if (theOriginalShape.ShapeType() == TopAbs_EDGE)
-      aResult = aHealer.Perform(TopoDS::Edge(theOriginalShape), aValue, isByParameter);
+  if (anIndex == -1) { // apply algorithm for the whole shape which is EDGE
+    if (theOriginalShape.ShapeType() == TopAbs_EDGE) {
+      if ( pointToProject.IsNull() )
+        aResult = aHealer.Perform(TopoDS::Edge(theOriginalShape), aValue, isByParameter);
+      else
+        aResult = aHealer.Perform(TopoDS::Edge(theOriginalShape), pointToProject);
+    }
   } else {
     TopTools_IndexedMapOfShape aShapes;
     TopExp::MapShapes(theOriginalShape, aShapes);
     TopoDS_Shape aEdgeShape = aShapes.FindKey(anIndex);
-    if (aEdgeShape.ShapeType() == TopAbs_EDGE)
-      aResult = aHealer.Perform(TopoDS::Edge(aEdgeShape), aValue, isByParameter);
+    if (aEdgeShape.ShapeType() == TopAbs_EDGE) {
+      if ( pointToProject.IsNull() )
+        aResult = aHealer.Perform(TopoDS::Edge(aEdgeShape), aValue, isByParameter);
+      else
+        aResult = aHealer.Perform(TopoDS::Edge(aEdgeShape), pointToProject);
+    }
   }
 
   if (aResult)
@@ -946,6 +965,14 @@ GetCreationInformation(std::string&             theOperationName,
     AddParam( theParams, "By parameter", aCI.GetIsByParameter() );
     AddParam( theParams, "Value", aCI.GetDevideEdgeValue() );
     break;
+  case DIVIDE_EDGE_BY_POINT:
+    theOperationName = "POINT_ON_EDGE";
+    if ( aCI.GetIndex() > 0 )
+      AddParam( theParams, "Edge", "#" ) << aCI.GetIndex() << " of " << aCI.GetOriginal();
+    else
+      AddParam( theParams, "Edge", aCI.GetOriginal() );
+    AddParam( theParams, "Point", aCI.GetShapes() );
+    break;
   case CHANGE_ORIENTATION:
     theOperationName = "CHANGE_ORIENTATION";
     AddParam( theParams, "Selected shape", aCI.GetOriginal() );
index ab4975aa2055a84eaba5c26589134d95c85290b0..3a2b133052d3b55f86d381d145efd9f3bfb9eab2 100644 (file)
@@ -764,6 +764,70 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::DivideEdge (Handle(GEOM_Object)
   return aNewObject;
 }
 
+//=============================================================================
+/*!
+ *  DivideEdgeByPoint
+ */
+//=============================================================================
+Handle(GEOM_Object)
+GEOMImpl_IHealingOperations::DivideEdgeByPoint (Handle(GEOM_Object) theObject,
+                                                int theIndex,
+                                                Handle(GEOM_Object) thePoint)
+{
+  // set error code, check parameters
+  SetErrorCode(KO);
+
+  if (theObject.IsNull() || thePoint.IsNull())
+    return NULL;
+
+  Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
+  Handle(GEOM_Function) aPointFunc = thePoint->GetLastFunction();
+  if (aLastFunction.IsNull() || aPointFunc.IsNull())
+    return NULL; //There is no function which creates an object to be processed
+
+  // Add a new object
+  Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
+
+  //Add the function
+  aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), DIVIDE_EDGE_BY_POINT);
+
+  if (aFunction.IsNull()) return NULL;
+
+  //Check if the function is set correctly
+  if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
+
+  // prepare "data container" class IHealing
+  GEOMImpl_IHealing HI(aFunction);
+  HI.SetIndex( theIndex );
+  HI.SetOriginal( aLastFunction );
+
+  Handle(TColStd_HSequenceOfTransient) funSeq = new TColStd_HSequenceOfTransient;
+  funSeq->Append( aPointFunc );
+  HI.SetShapes( funSeq );
+
+  //Compute the translation
+  try {
+    OCC_CATCH_SIGNALS;
+    if (!GetSolver()->ComputeFunction(aFunction)) {
+      SetErrorCode("Healing driver failed");
+      return NULL;
+    }
+  }
+  catch (Standard_Failure) {
+    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+    SetErrorCode(aFail->GetMessageString());
+    return NULL;
+  }
+
+  //Make a Python command
+  GEOM::TPythonDump(aFunction)
+    << aNewObject << " = geompy.DivideEdgeByPoint(" << theObject
+    << ", " << theIndex << ", " << thePoint << ")";
+
+  SetErrorCode(OK);
+  return aNewObject;
+}
+
 //=============================================================================
 /*!
  *  FuseCollinearEdgesWithinWire
index f8b17b37120452a3f23e3a0ce3264bfd4a9687ee..e2af51e10cae0e8e38bdb29a8f4deb2fc25223d2 100644 (file)
@@ -77,9 +77,13 @@ class GEOMImpl_IHealingOperations : public GEOM_IOperations {
   Standard_EXPORT Handle(GEOM_Object) RemoveInternalFaces (std::list< Handle(GEOM_Object)> & theSolids);
 
   Standard_EXPORT Handle(GEOM_Object) DivideEdge( Handle(GEOM_Object) theObject,
-                                                  int theIndex,
-                                                  double theValue,
-                                                  bool isByParameter );
+                                                  int                 theIndex,
+                                                  double              theValue,
+                                                  bool                isByParameter );
+
+  Standard_EXPORT Handle(GEOM_Object) DivideEdgeByPoint( Handle(GEOM_Object) theObject,
+                                                         int                 theIndex,
+                                                         Handle(GEOM_Object) thePoint );
 
   Standard_EXPORT Handle(GEOM_Object) FuseCollinearEdgesWithinWire
                                      (Handle(GEOM_Object) theWire,
index 419e1016001a837d40fd13a3922ce4d459d658df..720ce5e6efaa99d45aba02582ce65a35f93cb0c4 100644 (file)
 #define DISK_THREE_PNT    2
 #define DISK_R            3
 
-#define CYLINDER_R_H           1
-#define CYLINDER_PNT_VEC_R_H   2
-#define CYLINDER_R_H_A         3
-#define CYLINDER_PNT_VEC_R_H_A         4
+#define CYLINDER_R_H            1
+#define CYLINDER_PNT_VEC_R_H    2
+#define CYLINDER_R_H_A          3
+#define CYLINDER_PNT_VEC_R_H_A  4
 
 #define CONE_R1_R2_H         1
 #define CONE_PNT_VEC_R1_R2_H 2
 #define FUSE_COLLINEAR_EDGES  10
 #define SEWING_NON_MANIFOLD   11
 #define REMOVE_INTERNAL_FACES 12
+#define DIVIDE_EDGE_BY_POINT  13
 
 #define BASIC_FILLING 1
 
index d286fcf36522109b4529f2c6f635e7d682c44c35..e951e55c984add24618b476e66103d57c880c9d0 100644 (file)
@@ -449,6 +449,40 @@ GEOM::GEOM_Object_ptr GEOM_IHealingOperations_i::DivideEdge (GEOM::GEOM_Object_p
   return GetObject(aNewObject);
 }
 
+//=============================================================================
+/*!
+ *  DivideEdgeByPoint
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr
+GEOM_IHealingOperations_i::DivideEdgeByPoint (GEOM::GEOM_Object_ptr theObject,
+                                              CORBA::Short          theIndex,
+                                              GEOM::GEOM_Object_ptr thePoint)
+{
+  GEOM::GEOM_Object_var aGEOMObject;
+
+  // Set a not done flag
+  GetOperations()->SetNotDone();
+
+  // Get the object itself
+  Handle(GEOM_Object) anObject = GetObjectImpl(theObject);
+  if (anObject.IsNull())
+    return aGEOMObject._retn();
+
+  // Get the point
+  Handle(GEOM_Object) aPoint = GetObjectImpl(thePoint);
+  if (aPoint.IsNull())
+    return aGEOMObject._retn();
+
+  // Perform
+  Handle(GEOM_Object) aNewObject =
+    GetOperations()->DivideEdgeByPoint( anObject, theIndex, aPoint );
+  if (!GetOperations()->IsDone() || aNewObject.IsNull())
+    return aGEOMObject._retn();
+
+  return GetObject(aNewObject);
+}
+
 //=============================================================================
 /*!
  *  FuseCollinearEdgesWithinWire
index 8531871394f8834c1b5191b21541460f7dd96103..8ca4b277c213c771e2fea57eb459c1d2bd16f508 100644 (file)
@@ -81,9 +81,13 @@ class GEOM_I_EXPORT GEOM_IHealingOperations_i :
    GEOM::GEOM_Object_ptr RemoveInternalFaces (const GEOM::ListOfGO& theSolids);
 
    GEOM::GEOM_Object_ptr DivideEdge (GEOM::GEOM_Object_ptr theObject,
-                                     CORBA::Short theIndex,
-                                     CORBA::Double theValue,
-                                     CORBA::Boolean isByParameter);
+                                     CORBA::Short          theIndex,
+                                     CORBA::Double         theValue,
+                                     CORBA::Boolean        isByParameter);
+
+   GEOM::GEOM_Object_ptr DivideEdgeByPoint (GEOM::GEOM_Object_ptr theObject,
+                                            CORBA::Short          theIndex,
+                                            GEOM::GEOM_Object_ptr thePoint);
 
    GEOM::GEOM_Object_ptr FuseCollinearEdgesWithinWire (GEOM::GEOM_Object_ptr theWire,
                                                        const GEOM::ListOfGO& theVertices);
index 7d399a252f4b215ad27165b23ebe37782c5e9b03..1df42aeefc48d9987a07ec09ce81d1d3be3e814b 100644 (file)
@@ -323,6 +323,12 @@ def TestDivideEdge (geompy):
   Id_Box    = geompy.addToStudy(Box, "Box")
   Id_Divide = geompy.addToStudy(Divide, "Box with Divided Edge")
 
+  # using geompy.DivideEdgeByPoint()
+  p    = geompy.MakeVertex( 30, -5, 10, theName="Point to project" )
+  edge = geompy.GetEdgeNearPoint( Box, p, theName="Edge to split")
+  div  = geompy.DivideEdgeByPoint( Box, edge, p, theName="Box (edge divided)")
+  assert geompy.NumberOfEdges( Box ) == geompy.NumberOfEdges( div ) - 1
+
 def TestFuseEdges (geompy):
 
   # create vertices
index a0926791c6898463d8bd91ab70b986b11ace4686..5a0aa557d983d74348ca2b0e365b3cd4b5adf173 100644 (file)
@@ -6590,6 +6590,45 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
             self._autoPublish(anObj, theName, "divideEdge")
             return anObj
 
+        ## Addition of a point to a given edge of \a theObject by projecting
+        #  another point to the given edge.
+        #  @param theObject Shape to be processed.
+        #  @param theEdgeIndex Index of edge to be divided within theObject's shape,
+        #                      if -1, then theObject itself is the edge.
+        #  @param thePoint Point to project to theEdgeIndex-th edge.
+        #  @param theName Object name; when specified, this parameter is used
+        #         for result publication in the study. Otherwise, if automatic
+        #         publication is switched on, default value is used for result name.
+        #
+        #  @return New GEOM.GEOM_Object, containing processed shape.
+        #
+        #  @ref tui_add_point_on_edge "Example"
+        @ManageTransactions("HealOp")
+        def DivideEdgeByPoint(self, theObject, theEdgeIndex, thePoint, theName=None):
+            """
+            Addition of a point to a given edge of \a theObject by projecting
+            another point to the given edge.
+
+            Parameters:
+                theObject Shape to be processed.
+                theEdgeIndex The edge or its index to be divided within theObject's shape,
+                             if -1, then theObject itself is the edge.
+                thePoint Point to project to theEdgeIndex-th edge.
+                theName Object name; when specified, this parameter is used
+                        for result publication in the study. Otherwise, if automatic
+                        publication is switched on, default value is used for result name.
+
+            Returns:
+                New GEOM.GEOM_Object, containing processed shape.
+            """
+            # Example: see GEOM_TestHealing.py
+            if isinstance( theEdgeIndex, GEOM._objref_GEOM_Object ):
+                theEdgeIndex = self.GetSubShapeID( theObject, theEdgeIndex )
+            anObj = self.HealOp.DivideEdgeByPoint(theObject, theEdgeIndex, thePoint)
+            RaiseIfFailed("DivideEdgeByPoint", self.HealOp)
+            self._autoPublish(anObj, theName, "divideEdge")
+            return anObj
+
         ## Suppress the vertices in the wire in case if adjacent edges are C1 continuous.
         #  @param theWire Wire to minimize the number of C1 continuous edges in.
         #  @param theVertices A list of vertices to suppress. If the list
@@ -9688,7 +9727,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
         ## Perform an Archimde operation on the given shape with given parameters.
         #  The object presenting the resulting face is returned.
         #  @param theShape Shape to be put in water.
-        #  @param theWeight Weight og the shape.
+        #  @param theWeight Weight of the shape.
         #  @param theWaterDensity Density of the water.
         #  @param theMeshDeflection Deflection of the mesh, using to compute the section.
         #  @param theName Object name; when specified, this parameter is used
@@ -9707,7 +9746,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
 
             Parameters:
                 theShape Shape to be put in water.
-                theWeight Weight og the shape.
+                theWeight Weight of the shape.
                 theWaterDensity Density of the water.
                 theMeshDeflection Deflection of the mesh, using to compute the section.
                 theName Object name; when specified, this parameter is used
index 19e10b070aceaa37075f4e1975e7a56d6c61a49a..62715108b23ab7b6095650ecb0b2441a8ce599a3 100644 (file)
 
 #include <GEOMImpl_Types.hxx>
 
-#include <TopAbs.hxx>
+#include <BRepBuilderAPI_MakeVertex.hxx>
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
 #include <Geom_Curve.hxx>
-#include <gp_Pnt.hxx>
-#include <TopoDS.hxx>
+#include <TColStd_IndexedMapOfInteger.hxx>
+#include <TopAbs.hxx>
 #include <TopExp.hxx>
-#include <TopoDS_Edge.hxx>
-#include <BRep_Tool.hxx>
+#include <TopExp_Explorer.hxx>
 #include <TopTools_IndexedMapOfShape.hxx>
-#include <BRepBuilderAPI_MakeVertex.hxx>
-#include <TColStd_IndexedMapOfInteger.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Edge.hxx>
+#include <gp_Pnt.hxx>
+
+enum { BY_PARAM, BY_POINT_PROJ };
 
 //=================================================================================
 // class    : RepairGUI_DivideEdgeDlg()
@@ -61,6 +68,7 @@ RepairGUI_DivideEdgeDlg::RepairGUI_DivideEdgeDlg( GeometryGUI* theGeometryGUI, Q
   : GEOMBase_Skeleton( theGeometryGUI, parent, modal )
 {
   QPixmap image0( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_DIVIDE_EDGE" ) ) );
+  QPixmap image2( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_DIVIDE_EDGE_BY_PNT" ) ) );
   QPixmap image1( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) );
 
   setWindowTitle( tr( "GEOM_DIVIDE_EDGE_TITLE" ) );
@@ -68,16 +76,18 @@ RepairGUI_DivideEdgeDlg::RepairGUI_DivideEdgeDlg( GeometryGUI* theGeometryGUI, Q
   /***************************************************************/
   mainFrame()->GroupConstructors->setTitle(tr("GEOM_DIVIDE_EDGE_TITLE"));
   mainFrame()->RadioButton1->setIcon( image0 );
-  mainFrame()->RadioButton2->setAttribute( Qt::WA_DeleteOnClose );
-  mainFrame()->RadioButton2->close();
+  mainFrame()->RadioButton2->setIcon( image2 );
   mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose );
   mainFrame()->RadioButton3->close();
 
-  GroupPoints = new DlgRef_1SelExt( centralWidget() );
+  GroupPoints = new DlgRef_2SelExt( centralWidget() );
   GroupPoints->GroupBox1->setTitle( tr( "GEOM_ADD_POINT" ) );
   GroupPoints->TextLabel1->setText( tr( "GEOM_EDGE" ) );
   GroupPoints->PushButton1->setIcon( image1 );
   GroupPoints->LineEdit1->setReadOnly( true );
+  GroupPoints->TextLabel2->setText( tr( "DEVIDE_EDGE_BY_PROJ_POINT" ) );
+  GroupPoints->PushButton2->setIcon( image1 );
+  GroupPoints->LineEdit2->setReadOnly( true );
 
   QRadioButton* rb1 = new QRadioButton( tr( "GEOM_BY_PARAMETER" ), GroupPoints->Box );
   QRadioButton* rb2 = new QRadioButton( tr( "GEOM_BY_LENGTH" ),    GroupPoints->Box );
@@ -90,13 +100,13 @@ RepairGUI_DivideEdgeDlg::RepairGUI_DivideEdgeDlg( GeometryGUI* theGeometryGUI, Q
   myValEdt = new SalomeApp_DoubleSpinBox( GroupPoints->Box );
   initSpinBox( myValEdt, 0., 1., 0.1, "parametric_precision" );
   myValEdt->setValue( 0.5 );
-  QLabel* aLbl1 = new QLabel( tr( "GEOM_VALUE" ), GroupPoints->Box );
+  myValLbl = new QLabel( tr( "GEOM_VALUE" ), GroupPoints->Box );
 
   QGridLayout* l = new QGridLayout( GroupPoints->Box );
   l->setMargin( 0 ); l->setSpacing( 6 );
   l->addWidget( rb1, 0, 0, 1, 2 );
   l->addWidget( rb2, 1, 0, 1, 2 );
-  l->addWidget( aLbl1, 2, 0 );
+  l->addWidget( myValLbl, 2, 0 );
   l->addWidget( myValEdt, 2, 1 );
 
   QVBoxLayout* layout = new QVBoxLayout( centralWidget() );
@@ -110,6 +120,29 @@ RepairGUI_DivideEdgeDlg::RepairGUI_DivideEdgeDlg( GeometryGUI* theGeometryGUI, Q
   Init();
 }
 
+//=======================================================================
+//function : ConstructorsClicked
+//purpose  : hide/show widgets depending on a selected constructor
+//=======================================================================
+void RepairGUI_DivideEdgeDlg::ConstructorsClicked( int constructorId )
+{
+  myIsParameterGr->button( 0 )->setShown( constructorId == BY_PARAM );
+  myIsParameterGr->button( 1 )->setShown( constructorId == BY_PARAM );
+  myValEdt                    ->setShown( constructorId == BY_PARAM );
+  myValLbl                    ->setShown( constructorId == BY_PARAM );
+  GroupPoints->TextLabel2     ->setShown( constructorId == BY_POINT_PROJ );
+  GroupPoints->PushButton2    ->setShown( constructorId == BY_POINT_PROJ );
+  GroupPoints->LineEdit2      ->setShown( constructorId == BY_POINT_PROJ );
+
+  initSelection();
+
+  if ( constructorId == BY_PARAM &&
+       !GroupPoints->PushButton1->isDown() )
+    GroupPoints->PushButton1->click();
+
+  displayPreview();
+}
+
 //=================================================================================
 // function : ~RepairGUI_DivideEdgeDlg()
 // purpose  : Destroys the object and frees any allocated resources
@@ -128,25 +161,31 @@ void RepairGUI_DivideEdgeDlg::Init()
   myEditCurrentArgument = GroupPoints->LineEdit1;
 
   myObject = GEOM::GEOM_Object::_nil();
-  myIndex = -1;
+  myPoint.nullify();
+  myIndex  = -1;
+  myProjectionOK = false;
 
   //myGeomGUI->SetState( 0 );
-  initSelection();
 
   /* signals and slots connections */
   connect( buttonOk(),    SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
   connect( buttonApply(), SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
 
+  connect(this,           SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int)));
+
   connect( myValEdt,   SIGNAL( valueChanged( double ) ), this, SLOT( ValueChangedInSpinBox() ) );
 
   connect( GroupPoints->PushButton1, SIGNAL( clicked() ),       this, SLOT( SetEditCurrentArgument() ) );
   connect( GroupPoints->LineEdit1,   SIGNAL( returnPressed() ), this, SLOT( LineEditReturnPressed() ) );
+  connect( GroupPoints->PushButton2, SIGNAL( clicked() ),       this, SLOT( SetEditCurrentArgument() ) );
+  connect( GroupPoints->LineEdit2,   SIGNAL( returnPressed() ), this, SLOT( LineEditReturnPressed() ) );
 
   connect( ( (SalomeApp_Application*)( SUIT_Session::session()->activeApplication() ) )->selectionMgr(),
            SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
 
   initName( tr( "DEVIDE_EDGE_NEW_OBJECT_NAME" ) );
   resize(100,100);
+  ConstructorsClicked( BY_PARAM );
   SelectionIntoArgument();
 }
 
@@ -165,6 +204,7 @@ void RepairGUI_DivideEdgeDlg::ValueChangedInSpinBox()
 //=================================================================================
 void RepairGUI_DivideEdgeDlg::displayPreview()
 {
+  myProjectionOK = false;
   erasePreview();
   if ( myObject->_is_nil() )
     return;
@@ -173,7 +213,7 @@ void RepairGUI_DivideEdgeDlg::displayPreview()
   gp_Pnt aPnt;
   GEOMBase::GetShape( myObject, aShape, TopAbs_SHAPE );
 
-  if ( myIndex != -1) {
+  if ( myIndex != -1 ) {
     TopTools_IndexedMapOfShape aShapes;
     TopExp::MapShapes(aShape, aShapes);
     aShape = aShapes.FindKey(myIndex);
@@ -182,15 +222,55 @@ void RepairGUI_DivideEdgeDlg::displayPreview()
   if (aShape.ShapeType() == TopAbs_EDGE) {
     Standard_Real aFP, aLP, aP;
     Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(aShape), aFP, aLP);
-    aP = aFP + (aLP - aFP) * myValEdt->value();
-    aPnt = aCurve->Value(aP);
-    BRepBuilderAPI_MakeVertex mkVertex (aPnt);
-    aShape = mkVertex.Shape();
+    if ( aCurve.IsNull() ) return;
+
+    if ( getConstructorId() == BY_PARAM )
+    {
+      aP = aFP + (aLP - aFP) * myValEdt->value();
+      aPnt = aCurve->Value(aP);
+      BRepBuilderAPI_MakeVertex mkVertex (aPnt);
+      aShape = mkVertex.Shape();
+    }
+    else if ( getConstructorId() == BY_POINT_PROJ && myPoint )
+    {
+      TopoDS_Shape aPoints;
+      GEOMBase::GetShape( myPoint.get(), aPoints, TopAbs_SHAPE );
+
+      BRep_Builder builder;
+      TopoDS_Compound compoundOfVV;
+      builder.MakeCompound(compoundOfVV);
+      aShape = compoundOfVV;
+
+      GeomAPI_ProjectPointOnCurve aProjector;
+      aProjector.Init( aCurve, aFP, aLP );
+
+      TopTools_MapOfShape vMap;
+      TopExp_Explorer vertex( aPoints, TopAbs_VERTEX );
+      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 = aProjector.LowerDistanceParameter();
+          if ( Min( u - aFP, aLP - u ) > Precision::Confusion() )
+          {
+            builder.Add( compoundOfVV, BRepBuilderAPI_MakeVertex( aProjector.NearestPoint()));
+            myProjectionOK = true;
+          }
+        }
+      }
+    }
+    else
+    {
+      return;
+    }
     // Build prs
     SALOME_Prs* aPrs = getDisplayer()->BuildPrs( aShape );
     if ( aPrs != 0 && !aPrs->IsNull() )
       GEOMBase_Helper::displayPreview( aPrs, false, true );
-  } 
+  }
 }
 
 //=================================================================================
@@ -218,9 +298,11 @@ bool RepairGUI_DivideEdgeDlg::ClickOnApply()
 
   myEditCurrentArgument->setText( "" );
   myObject = GEOM::GEOM_Object::_nil();
+  myPoint.nullify();
   myIndex = -1;
+  myProjectionOK = false;
 
-  initSelection();
+  ConstructorsClicked(getConstructorId());
 
   return true;
 }
@@ -235,8 +317,17 @@ void RepairGUI_DivideEdgeDlg::SelectionIntoArgument()
 {
   myEditCurrentArgument->setText( "" );
 
-  myObject = GEOM::GEOM_Object::_nil();
-  myIndex = -1;
+  const bool toSelectObject = ( myEditCurrentArgument == GroupPoints->LineEdit1 );
+  if ( toSelectObject )
+  {
+    myObject = GEOM::GEOM_Object::_nil();
+    myIndex = -1;
+  }
+  else //if ( myEditCurrentArgument == GroupPoints->LineEdit2 )
+  {
+    myPoint.nullify();
+    myProjectionOK = false;
+  }
 
   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
   SALOME_ListIO aSelList;
@@ -252,7 +343,7 @@ void RepairGUI_DivideEdgeDlg::SelectionIntoArgument()
       if ( GEOMBase::GetShape( aSelectedObj, aShape, TopAbs_SHAPE ) )
       {
         const int aType = aShape.ShapeType();
-        if ( aType <= TopAbs_EDGE ) // edge, wire, face, shell, solid, compound
+        if ( aType <= TopAbs_EDGE || !toSelectObject ) // edge, wire, face, shell, solid, compound
         {
           GEOM::short_array anIndexes;
 
@@ -263,20 +354,29 @@ void RepairGUI_DivideEdgeDlg::SelectionIntoArgument()
 
           if ( !aMap.IsEmpty() ) // sub-shape selection
           {
-            myIndex = aMap( 1 );
-            myObject = aSelectedObj;
-            myEditCurrentArgument->setText( aName += QString( ":edge_%1" ).arg( myIndex ) );
+            if ( toSelectObject ) {
+              myIndex = aMap( 1 );
+              myObject = aSelectedObj;
+              myEditCurrentArgument->setText( aName += QString( ":edge_%1" ).arg( myIndex ) );
+            }
+            else if (( myPoint = getSelected( TopAbs_VERTEX )))
+            {
+              myEditCurrentArgument->setText( aName += QString( ":vertex_%1" ).arg( aMap( 1 )));
+            }
           }
-          else if ( aType == TopAbs_EDGE ) // single shape selection
+          else if ( aType == TopAbs_EDGE && toSelectObject ) // single shape selection
           {
             myIndex = -1;
             myObject = aSelectedObj;
-            myEditCurrentArgument->setText( GEOMBase::GetName( myObject ) );
+            myEditCurrentArgument->setText( aName );
+          }
+          else if ( aType == TopAbs_VERTEX && !toSelectObject ) // single shape selection
+          {
+            myPoint = aSelectedObj;
+            myEditCurrentArgument->setText( aName );
           }
           else // face, shell, solid or compound was selected, and NOT its sub-shape.
           {
-            myIndex = -1;
-            myObject = GEOM::GEOM_Object::_nil();
           }
         }
       }
@@ -292,10 +392,29 @@ void RepairGUI_DivideEdgeDlg::SelectionIntoArgument()
 //=================================================================================
 void RepairGUI_DivideEdgeDlg::SetEditCurrentArgument()
 {
-  if ( sender() == GroupPoints->PushButton1 ) {
+  QPushButton* send = (QPushButton*)sender();
+
+  if ( send == GroupPoints->PushButton1 ) {
     GroupPoints->LineEdit1->setFocus();
     myEditCurrentArgument = GroupPoints->LineEdit1;
+
+    GroupPoints->PushButton2->setDown(false);
+    GroupPoints->LineEdit2->setEnabled(false);
   }
+  if ( send == GroupPoints->PushButton2 ) {
+    GroupPoints->LineEdit2->setFocus();
+    myEditCurrentArgument = GroupPoints->LineEdit2;
+
+    GroupPoints->PushButton1->setDown(false);
+    GroupPoints->LineEdit1->setEnabled(false);
+  }
+  // enable line edit
+  myEditCurrentArgument->setEnabled(true);
+  myEditCurrentArgument->setFocus();
+  // after setFocus(), because it will be setDown(false) when loses focus
+  send->setDown(true);
+
+  initSelection();
   SelectionIntoArgument();
 }
 
@@ -310,6 +429,11 @@ void RepairGUI_DivideEdgeDlg::LineEditReturnPressed()
     myEditCurrentArgument = GroupPoints->LineEdit1;
     GEOMBase_Skeleton::LineEditReturnPressed();
   }
+  if ( sender() == GroupPoints->LineEdit2 &&
+       !GroupPoints->LineEdit2->isHidden() ) {
+    myEditCurrentArgument = GroupPoints->LineEdit2;
+    GEOMBase_Skeleton::LineEditReturnPressed();
+  }
 }
 
 
@@ -327,7 +451,7 @@ void RepairGUI_DivideEdgeDlg::ActivateThisDialog()
   myIndex = -1;
 
   //myGeomGUI->SetState( 0 );
-  initSelection();
+  ConstructorsClicked(getConstructorId());
 }
 
 //=================================================================================
@@ -356,7 +480,16 @@ GEOM::GEOM_IOperations_ptr RepairGUI_DivideEdgeDlg::createOperation()
 //=================================================================================
 bool RepairGUI_DivideEdgeDlg::isValid( QString& msg )
 {
-  bool ok = myValEdt->isValid( msg, !IsPreview() );
+  bool ok = false;
+  if ( getConstructorId() == BY_PARAM )
+  {
+    ok = myValEdt->isValid( msg, !IsPreview() );
+  }
+  else if ( getConstructorId() == BY_POINT_PROJ )
+  {
+    if (( ok = myPoint ) && !( ok = myProjectionOK ))
+      msg = tr("DEVIDE_EDGE_BAD_PROJ_MSG");
+  }
   return !myObject->_is_nil() && ok;
 }
 
@@ -367,11 +500,16 @@ bool RepairGUI_DivideEdgeDlg::isValid( QString& msg )
 bool RepairGUI_DivideEdgeDlg::execute( ObjectList& objects )
 {
   GEOM::GEOM_IHealingOperations_var anOper = GEOM::GEOM_IHealingOperations::_narrow( getOperation() );
-  GEOM::GEOM_Object_var anObj = anOper->DivideEdge( myObject, myIndex, myValEdt->value(), getIsByParameter() );
+  GEOM::GEOM_Object_var anObj;
+  if ( getConstructorId() == BY_PARAM )
+    anObj = anOper->DivideEdge( myObject, myIndex, myValEdt->value(), getIsByParameter() );
+  else
+    anObj = anOper->DivideEdgeByPoint( myObject, myIndex, myPoint.get() );
+
   bool aResult = !anObj->_is_nil();
   if ( aResult )
   {
-    if ( !IsPreview() )
+    if ( !IsPreview() && ( getConstructorId() == BY_PARAM ))
     {
       QStringList aParameters;
       aParameters << "";
@@ -400,6 +538,19 @@ bool RepairGUI_DivideEdgeDlg::getIsByParameter() const
 //=================================================================================
 void RepairGUI_DivideEdgeDlg::initSelection()
 {
-  GEOM::GEOM_Object_var aNullGeomObject;
-  localSelection( aNullGeomObject, TopAbs_EDGE ); // load local selection on ALL objects
+  TopAbs_ShapeEnum type = TopAbs_EDGE;
+  if ( myEditCurrentArgument == GroupPoints->LineEdit2 )
+    type = TopAbs_VERTEX;
+
+  globalSelection(); // close local contexts, if any
+  localSelection( GEOM::GEOM_Object::_nil(), type ); // load local selection on ALL objects
+}
+
+//=================================================================================
+// function : addSubshapeToStudy
+// purpose  : virtual method to add new SubObjects if local selection
+//=================================================================================
+void RepairGUI_DivideEdgeDlg::addSubshapesToStudy()
+{
+  GEOMBase::PublishSubObject( myPoint.get() );
 }
index 4b1adc3c9df6b8dce7365bb9dca123820d684241..129c9895cea175c1fd69e973378514f8484d58f2 100644 (file)
@@ -29,7 +29,7 @@
 
 #include <GEOMBase_Skeleton.h>
 
-class DlgRef_1SelExt;
+class DlgRef_2SelExt;
 class SalomeApp_DoubleSpinBox;
 class QButtonGroup;
 
@@ -50,7 +50,8 @@ protected:
   virtual GEOM::GEOM_IOperations_ptr createOperation();
   virtual bool                       isValid( QString& );
   virtual bool                       execute( ObjectList& );
-  
+  virtual void                       addSubshapesToStudy();
+
 private:
   void                               Init();
   void                               enterEvent( QEvent* );
@@ -58,13 +59,16 @@ private:
   
   bool                               getIsByParameter() const;
   int                                myIndex;
-  
+
 private:
   GEOM::GEOM_Object_var              myObject;
-  
-  DlgRef_1SelExt*                    GroupPoints;
+  GEOM::GeomObjPtr                   myPoint;
+  bool                               myProjectionOK;
+
+  DlgRef_2SelExt*                    GroupPoints;
   QButtonGroup*                      myIsParameterGr;
   SalomeApp_DoubleSpinBox*           myValEdt;
+  QLabel*                            myValLbl;
 
 protected slots:
   void                               ClickOnOk();
@@ -76,6 +80,7 @@ protected slots:
   void                               LineEditReturnPressed();
   void                               SelectionIntoArgument();
   void                               SetEditCurrentArgument();
+  void                               ConstructorsClicked( int );
 };
 
 #endif // REPAIRGUI_DIVIDEEDGEDLG_H
index 3a910c55d01925fe395098b572921eb0610be7ab..99de5efe557110b9eef53d1e4254ceb52f094429 100644 (file)
 // 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,51 @@ 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 );
+  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 );
+      aSeqValues->Append( param );
+    }
+  }
+  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 +169,16 @@ Standard_Boolean ShHealOper_EdgeDivide::build(const Handle(TColStd_HSequenceOfRe
     return Standard_False;
   }
 
-  Standard_Boolean has3d = Standard_False, 
-  has2d = Standard_False, 
-  hasPCurves = 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.
   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,7 +197,7 @@ 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.
   Standard_Boolean isDone = Standard_True;
   if(hasPCurves) {
index 4fd3ef0d62daea0531fad79204fde3f2a0f3ccd5..d552149c8b9236089d1e542d558167e26c600cde 100644 (file)
 #ifndef ShHealOper_EdgeDivide_HeaderFile
 #define ShHealOper_EdgeDivide_HeaderFile
 
+#include <ShHealOper_Tool.hxx>
 #include <TColStd_HSequenceOfReal.hxx>
+#include <TColStd_SequenceOfReal.hxx>
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
 #include <TopoDS_Edge.hxx>
-#include <TopoDS_Shape.hxx>
-#include <ShHealOper_Tool.hxx>
-#include <TColStd_SequenceOfReal.hxx>
 
 ///  Class ShHealOper_EdgeDivide
 //Intended for spitting edge in accordance to the specified mode and value.
@@ -59,7 +58,7 @@ class ShHealOper_EdgeDivide : public ShHealOper_Tool
   //specified mode and value.
   //If theDivideParamMode is equal to true edge will be splitted by parameter.
   //Else edge will be spliited by length (default true).
-  //theValue is koefficient for splitting from 0 to 1.
+  //theValue is coefficient for splitting from 0 to 1.
 
   Standard_EXPORT Standard_Boolean Perform(const TopoDS_Shape& theEdge, 
                                            const TColStd_SequenceOfReal& theValues,
@@ -67,7 +66,11 @@ class ShHealOper_EdgeDivide : public ShHealOper_Tool
   //Performs spitting of the specified edge in the accoradnce to
   //specified mode and sequence of values the same way as previous.
 
- protected:
+  Standard_EXPORT Standard_Boolean Perform(const TopoDS_Shape& theEdge, 
+                                           const TopoDS_Shape& thePoint);
+  //Performs spitting of the specified edge by projecting a point to it.
+
+protected:
   // ---------- PROTECTED METHODS ----------