]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
0022869: EDF 7482 GEOM: Automatically create groups with the generation operations
authorskv <skv@opencascade.com>
Mon, 23 Mar 2015 10:02:48 +0000 (13:02 +0300)
committervsr <vsr@opencascade.com>
Wed, 8 Apr 2015 13:42:03 +0000 (16:42 +0300)
32 files changed:
doc/salome/gui/GEOM/images/gen_group_disabled.png [new file with mode: 0644]
doc/salome/gui/GEOM/images/gen_group_dlg.png [new file with mode: 0644]
doc/salome/gui/GEOM/images/gen_group_other.png [new file with mode: 0644]
doc/salome/gui/GEOM/images/gen_group_sides.png [new file with mode: 0644]
doc/salome/gui/GEOM/images/gen_group_tree.png [new file with mode: 0644]
doc/salome/gui/GEOM/images/pipe.png [changed mode: 0755->0644]
doc/salome/gui/GEOM/images/pipe2.png [changed mode: 0755->0644]
doc/salome/gui/GEOM/images/pipe3.png
doc/salome/gui/GEOM/input/creating_complex_obj.doc
doc/salome/gui/GEOM/input/creating_extrusion_alongpath.doc
doc/salome/gui/GEOM/input/creating_groups.doc [new file with mode: 0644]
idl/GEOM_Gen.idl
src/GEOMGUI/GEOM_msg_en.ts
src/GEOMImpl/GEOMImpl_GlueDriver.cxx
src/GEOMImpl/GEOMImpl_GlueDriver.hxx
src/GEOMImpl/GEOMImpl_I3DPrimOperations.cxx
src/GEOMImpl/GEOMImpl_I3DPrimOperations.hxx
src/GEOMImpl/GEOMImpl_IPipe.hxx
src/GEOMImpl/GEOMImpl_IPipeBiNormal.hxx
src/GEOMImpl/GEOMImpl_IPipeDiffSect.hxx
src/GEOMImpl/GEOMImpl_IPipeShellSect.hxx
src/GEOMImpl/GEOMImpl_PipeDriver.cxx
src/GEOMImpl/GEOMImpl_PipeDriver.hxx
src/GEOMUtils/GEOMUtils.cxx
src/GEOMUtils/GEOMUtils.hxx
src/GEOM_I/GEOM_I3DPrimOperations_i.cc
src/GEOM_I/GEOM_I3DPrimOperations_i.hh
src/GEOM_I_Superv/GEOM_Superv_i.cc
src/GEOM_SWIG/geomBuilder.py
src/GenerationGUI/CMakeLists.txt
src/GenerationGUI/GenerationGUI_PipeDlg.cxx
src/GenerationGUI/GenerationGUI_PipeDlg.h

diff --git a/doc/salome/gui/GEOM/images/gen_group_disabled.png b/doc/salome/gui/GEOM/images/gen_group_disabled.png
new file mode 100644 (file)
index 0000000..7c97c85
Binary files /dev/null and b/doc/salome/gui/GEOM/images/gen_group_disabled.png differ
diff --git a/doc/salome/gui/GEOM/images/gen_group_dlg.png b/doc/salome/gui/GEOM/images/gen_group_dlg.png
new file mode 100644 (file)
index 0000000..e70e6e2
Binary files /dev/null and b/doc/salome/gui/GEOM/images/gen_group_dlg.png differ
diff --git a/doc/salome/gui/GEOM/images/gen_group_other.png b/doc/salome/gui/GEOM/images/gen_group_other.png
new file mode 100644 (file)
index 0000000..7761066
Binary files /dev/null and b/doc/salome/gui/GEOM/images/gen_group_other.png differ
diff --git a/doc/salome/gui/GEOM/images/gen_group_sides.png b/doc/salome/gui/GEOM/images/gen_group_sides.png
new file mode 100644 (file)
index 0000000..cdf0207
Binary files /dev/null and b/doc/salome/gui/GEOM/images/gen_group_sides.png differ
diff --git a/doc/salome/gui/GEOM/images/gen_group_tree.png b/doc/salome/gui/GEOM/images/gen_group_tree.png
new file mode 100644 (file)
index 0000000..71e7e93
Binary files /dev/null and b/doc/salome/gui/GEOM/images/gen_group_tree.png differ
old mode 100755 (executable)
new mode 100644 (file)
index c1b77a9..a02cc34
Binary files a/doc/salome/gui/GEOM/images/pipe.png and b/doc/salome/gui/GEOM/images/pipe.png differ
old mode 100755 (executable)
new mode 100644 (file)
index a94f293..d66407f
Binary files a/doc/salome/gui/GEOM/images/pipe2.png and b/doc/salome/gui/GEOM/images/pipe2.png differ
index c531ad752d06fd7bc6517e2231f0712406d65da2..d1b7f403112e899f565dd7a357a33e951efaa125 100644 (file)
Binary files a/doc/salome/gui/GEOM/images/pipe3.png and b/doc/salome/gui/GEOM/images/pipe3.png differ
index 6630dfa72193a1689db8859e8bbb3d9b916fa001..1fbb1d6a266be6b6242b76cb2258f8b3228a09c6 100644 (file)
@@ -3,23 +3,26 @@
 \page create_complex_obj_page Creating Complex Objects
 
 <b>New entity -> Generation</b> sub-menu allows creating new geometric
-objects by modification and multiplication of the existing objects: 
+objects by modification and multiplication of the existing objects:
 
 
 <ul>
 <li>\subpage create_extrusion_page "Extrude" a 2D object by vector,
-creating a 3D object. </li> 
+creating a 3D object. </li>
 <li>\subpage create_revolution_page "Revolve" an object around an
 axis, creating a body of revolution.</li>
 <li>\subpage create_filling_page  "Create a surface" from a set of edges.</li>
-<li>\subpage create_extrusion_alongpath_page "Extrude an object along a path", 
+<li>\subpage create_extrusion_alongpath_page "Extrude an object along a path",
 creating a more complex trajectory object.</li>
 <li>\subpage create_pipe_path_page "Restore Path" of a pipe-like shape.</li>
 <li>\subpage create_thickness_page "Thickness" operation that allows to add a thickness to objects.</li>
+
+<li>\subpage create_groups_page "Generate Groups".
+This cross-operation functionality allows creation of groups for certain generation operations.</li>
 </ul>
 
 <b> New entity -> Advanced </b> sub-menu allows creating new geometric
-objects using advanced algorithms: 
+objects using advanced algorithms:
 
 <ul>
 <li>\subpage create_smoothingsurface_page "Smoothing surface" from a
index 8c543023267310530f903366ac20b68c9d97c0d7..07808936287ba6ee8e1b666213f0cec263aa5fd1 100644 (file)
@@ -14,13 +14,17 @@ is created so that the <b>angle between the normal vector</b> to
 the base shape <b>and the tangent to the path</b> wire remains constant at any point of the
 given path.
 \n <b>Select unpublished edges</b> checkbox - if checked, allows to select an edge of any other shape as the path object. 
+\n <b>Generate groups</b> checkbox - if checked allows to create groups of
+sub-shapes. For more details on groups creation please refer to
+\ref create_groups_page "this description".
 \n The \b Result of the operation will be a GEOM_Object (edge, face, shell,
 solid or compsolid).
 
-\n <b>TUI Command:</b> <em>geompy.MakePipe(baseShape, pathShape)</em>
+\n <b>TUI Command:</b> <em>geompy.MakePipe(baseShape, pathShape,
+ IsGenerateGroups=False)</em>
 \n <b>Arguments:</b> Name + 1 shape (vertex, edge, planar wire, face or
 shell) serving as base object + 1 shape (edge or wire) for
-definition of the path.
+definition of the path + 1 boolean parameter (IsGenerateGroups).
 \n <b>Advanced options</b> \ref preview_anchor "Preview"
 
 \image html pipe.png
@@ -39,14 +43,19 @@ wire).
 to preserve the constant <b>angle between the normal vector</b> to the base
 shape <b>and the BiNormal vector</b> given as the third argument.
 \n <b>Select unpublished edges</b> checkbox - if checked, allows to select an edge of any other shape as the path object. 
+\n <b>Generate groups</b> checkbox - if checked allows to create groups of
+sub-shapes. For more details on groups creation please refer to
+\ref create_groups_page "this description".
 \n The \b Result of the operation will be a GEOM_Object (edge, face, shell,
 solid or compsolid).
 
-\n <b>TUI Command:</b> <em>geompy.MakePipeBiNormalAlongVector(baseShape, pathShape, binormalShape)</em>
+\n <b>TUI Command:</b> <em>geompy.MakePipeBiNormalAlongVector(baseShape, pathShape, binormalShape,
+ IsGenerateGroups=False)</em>
 \n <b>Arguments:</b> Name + 1 shape (edge, planar wire or face) 
 serving as base object + 1 shape (edge or wire) for
 definition of the path + 1 shape (edge or wire) to set a fixed 
-BiNormal direction to perform the extrusion.
+BiNormal direction to perform the extrusion + 1 boolean parameter
+(IsGenerateGroups).
 
 \image html pipe2.png
 
@@ -64,13 +73,17 @@ Additional controls:
 - If <b>With correction</b> is checked, the section is rotated to be orthogonal to the spine
 tangent in the corresponding point.
 
+<b>Generate groups</b> checkbox - if checked allows to create groups of
+sub-shapes. For more details on groups creation please refer to
+\ref create_groups_page "this description".
 \n The \b Result of the operation will be a shell or a solid.
 
-\n <b>TUI Command:</b> <em>geompy.MakePipeWithDifferentSections(baseShape, locations, pathShape, withContact, withCorrection)</em>
+\n <b>TUI Command:</b> <em>geompy.MakePipeWithDifferentSections(baseShape, locations, pathShape, withContact, withCorrection,
+ IsGenerateGroups=False)</em>
 \n <b>Arguments:</b> Name + list of shapes (edges, planar wires, faces or shells) serving as base object + 
 list of locations (vertices) on the path corresponding specified list of the shapes + 
 1 shape (edge or wire) for definition of the path + 
-2 Boolean parameters (withContact, withCorrection).
+3 Boolean parameters (withContact, withCorrection, IsGenerateGroups).
 \n <b>Advanced options</b> \ref preview_anchor "Preview"
 
 \image html pipe3.png
diff --git a/doc/salome/gui/GEOM/input/creating_groups.doc b/doc/salome/gui/GEOM/input/creating_groups.doc
new file mode 100644 (file)
index 0000000..c86b804
--- /dev/null
@@ -0,0 +1,76 @@
+/*!
+
+\page create_groups_page Generation of Groups
+
+This option is available in some dialogs. To activate it please check
+<b>Generate Groups</b> check box. When it is checked, it is possible to define
+the prefix for generated groups names using <b>Group Names Prefix</b> input
+field.
+
+\image html gen_group_dlg.png "Generate groups option in a dialog"
+
+The groups are created along with the result of the operation when
+\b Apply or <b>Apply and Close</b> button is clicked. Each generated group
+represents a set of sub-shapes of the result that satisfies certain conditions.
+The groups of the following types can be generated:
+ - \b Down - sub-shapes starting the result, e.g. bottom lid
+for the pipe creation operation.
+ - \b Up - sub-shapes ending the result, e.g. top lid
+for the pipe creation operation.
+ - \b Side1, \b Side2 - sub-shapes corresponding to each side
+of the result.
+ - \b Other - faces generated from the bounding edges of
+\b Down group.
+
+The groups are named according to the following naming rule:
+If <b>Group Names Prefix</b> is set <b><Prefix>_<Type></b>, otherwise
+the name is \b <Type>. The following figure shows group names created with
+the prefix \b Group:
+
+\image html gen_group_tree.png "Group_Down, Group_Up, Group_Side1 and Group_Side2 are generated"
+
+
+The general behavior of this functionality is the following:
+<ul>
+<li>If <b>Generate Groups</b> option is not set, the groups are not generated.</li>
+<li>If starting and ending sub-shapes of the result are the same, e.g. if there is
+a closed path for pipe construction, <b>Generate Groups</b> option is disabled
+in the dialog box:</li>
+
+\image html gen_group_disabled.png "Disabled option in the Pipe Construction dialog if the path is closed"
+\n
+<li>Otherwise If the path is not closed edge/wire, the groups are created depending
+on the profile:</li>
+<ul>
+<li>Profile is unclosed edge or wire: \b Down, \b Up, \b Side1, \b Side2:</li>
+
+\image html gen_group_sides.png "Pipe with created groups Down(Red), Up(Green), Side1(Blue) and Side2(Yellow)"
+\n
+<li>Profile is closed edge or wire, face or shell: \b Down, \b Up, \b Other:</li>
+
+\image html gen_group_other.png "Created groups Down(Red), Up(Green) and Other(Yellow)"
+</ul>
+</ul>
+
+\b Down and \b Up groups contain:
+- Edges if the profile is edge or wire;
+- Faces if the profile is face or shell.
+
+\b Side1 and \b Side2 groups contain edges generated from the first and
+last vertices of the profile edge or wire correspondingly. The first and
+last vertices are determined taking into account edge/wire orientation.
+
+\b Other group represents faces generated from the bounding edges of profile.
+
+The behavior in TUI is the following:
+- Each Python function that supports groups generation has a flag
+\b IsGenerateGroups which is equal to \b False by default.
+- If \b IsGenerateGroups is not set the groups are not created; the returned
+value is GEOM_Object that represents a result of the operation.
+- If \b IsGenerateGroups is set the operation returns a list of GEOM_Object.
+Its first element is a result, the remaining ones are the groups in the order:
+\b Down, \b Up, \b Side1, \b Side2 for opened profile or \b Down, \b Up,
+\b Other for closed profile.
+- If \b IsGenerateGroups is set and the path is closed an error occurs.
+
+*/
index 42d188d5492f7a0eaa2d03bf7b9ea82645a3febc..f63819e9755ff990d5514fa18c1c22f7830102e0 100644 (file)
@@ -1726,9 +1726,16 @@ module GEOM
      *  the path shape. The path shape can be a wire or an edge.
      *  \param theBase Base shape to be extruded.
      *  \param thePath Path shape to extrude the base shape along it.
-     *  \return New GEOM_Object, containing the created pipe.
+     *  \param IsGenerateGroups flag that tells if it is necessary to
+     *         return groups (true) or not (false).
+     *  \return The list of objects. The first one is a result pipe,
+     *          the other ones are the created groups. If \a IsGenerateGroups
+     *          is not set the returned list contains a single object, which
+     *          is the operation result.
      */
-    GEOM_Object MakePipe (in GEOM_Object theBase, in GEOM_Object thePath);
+    ListOfGO MakePipe (in GEOM_Object theBase,
+                       in GEOM_Object thePath,
+                       in boolean     IsGenerateGroups);
 
     /*!
      *  \brief Create a shape by revolution of the base shape around the axis
@@ -1796,13 +1803,19 @@ module GEOM
      *                          contact with the spine.
      *  \param theWithCorrection - defining that the section is rotated to be
      *                                 orthogonal to the spine tangent in the correspondent point
-     *  \return New GEOM_Object, containing the created pipe.
+     *  \param IsGenerateGroups flag that tells if it is necessary to
+     *         return groups (true) or not (false).
+     *  \return The list of objects. The first one is a result pipe,
+     *          the other ones are the created groups. If \a IsGenerateGroups
+     *          is not set the returned list contains a single object, which
+     *          is the operation result.
      */
-    GEOM_Object MakePipeWithDifferentSections (in ListOfGO theSeqBases,
-                                               in ListOfGO theLocations,
-                                               in GEOM_Object thePath,
-                                               in boolean theWithContact ,
-                                               in boolean theWithCorrection );
+    ListOfGO MakePipeWithDifferentSections (in ListOfGO theSeqBases,
+                                            in ListOfGO theLocations,
+                                            in GEOM_Object thePath,
+                                            in boolean theWithContact ,
+                                            in boolean theWithCorrection,
+                                            in boolean IsGenerateGroups);
 
     /*!
      *  \brief Create a shape by extrusion of the profile shape along
@@ -1820,23 +1833,35 @@ module GEOM
      *                          contact with the spine.
      *  \param theWithCorrection - defining that the section is rotated to be
      *                                 orthogonal to the spine tangent in the correspondent point
-     *  \return New GEOM_Object, containing the created pipe.
-     */
-    GEOM_Object MakePipeWithShellSections (in ListOfGO theSeqBases,
-                                           in ListOfGO theSeqSubBases,
-                                           in ListOfGO theLocations,
-                                           in GEOM_Object thePath,
-                                           in boolean theWithContact ,
-                                           in boolean theWithCorrection );
+     *  \param IsGenerateGroups flag that tells if it is necessary to
+     *         return groups (true) or not (false).
+     *  \return The list of objects. The first one is a result pipe,
+     *          the other ones are the created groups. If \a IsGenerateGroups
+     *          is not set the returned list contains a single object, which
+     *          is the operation result.
+     */
+    ListOfGO MakePipeWithShellSections (in ListOfGO theSeqBases,
+                                        in ListOfGO theSeqSubBases,
+                                        in ListOfGO theLocations,
+                                        in GEOM_Object thePath,
+                                        in boolean theWithContact,
+                                        in boolean theWithCorrection,
+                                        in boolean IsGenerateGroups);
 
     /*!
      *  \brief Create solids between given sections
      *  \param theSeqBases - list of sections (shell or face).
      *  \param theLocations - list of corresponding vertexes
-     *  \return New GEOM_Object, containing the created solids.
+     *  \param IsGenerateGroups flag that tells if it is necessary to
+     *         return groups (true) or not (false).
+     *  \return The list of objects. The first one is a result pipe,
+     *          the other ones are the created groups. If \a IsGenerateGroups
+     *          is not set the returned list contains a single object, which
+     *          is the operation result.
      */
-    GEOM_Object MakePipeShellsWithoutPath (in ListOfGO theSeqBases,
-                                           in ListOfGO theLocations);
+    ListOfGO MakePipeShellsWithoutPath (in ListOfGO theSeqBases,
+                                        in ListOfGO theLocations,
+                                        in boolean  IsGenerateGroups);
 
     /*!
      *  \brief Create a shape by extrusion of the base shape along
@@ -1848,11 +1873,17 @@ module GEOM
      *  \param theVec Vector defines a constant binormal direction to keep the
      *                same angle beetween the Direction and the sections
      *                along the sweep surface.
-     *  \return New GEOM_Object, containing the created pipe.
-     */
-    GEOM_Object MakePipeBiNormalAlongVector (in GEOM_Object theBase,
-                                             in GEOM_Object thePath,
-                                             in GEOM_Object theVec);
+     *  \param IsGenerateGroups flag that tells if it is necessary to
+     *         return groups (true) or not (false).
+     *  \return The list of objects. The first one is a result pipe,
+     *          the other ones are the created groups. If \a IsGenerateGroups
+     *          is not set the returned list contains a single object, which
+     *          is the operation result.
+     */
+    ListOfGO MakePipeBiNormalAlongVector (in GEOM_Object theBase,
+                                          in GEOM_Object thePath,
+                                          in GEOM_Object theVec,
+                                          in boolean     IsGenerateGroups);
 
 
      /*!
index 5142eb36519d5a5f76a8b465fdc208cc2f622ec7..c1e7addb1a81172f90750fb6e6f0dee423a93ca4 100644 (file)
@@ -1412,6 +1412,14 @@ Please, select face, shell or solid and try again</translation>
         <source>GEOM_SELECT_UNPUBLISHED_EDGES</source>
         <translation>Select unpublished edges</translation>
     </message>
+    <message>
+        <source>GEOM_GENERATE_GROUPS</source>
+        <translation>Generate Groups</translation>
+    </message>
+    <message>
+        <source>GEOM_GROUP_NAME_PREFIX</source>
+        <translation>Group Names Prefix</translation>
+    </message>
     <message>
         <source>GEOM_PLANE</source>
         <translation>Plane</translation>
@@ -2420,6 +2428,26 @@ Please, select face, shell or solid and try again</translation>
         <source>WRN_NULL_OBJECT_OR_SHAPE</source>
         <translation>Shape %1 for solid creation is null</translation>
     </message>
+    <message>
+        <source>GROUP_DOWN</source>
+        <translation>Down</translation>
+    </message>
+    <message>
+        <source>GROUP_UP</source>
+        <translation>Up</translation>
+    </message>
+    <message>
+        <source>GROUP_SIDE1</source>
+        <translation>Side1</translation>
+    </message>
+    <message>
+        <source>GROUP_SIDE2</source>
+        <translation>Side2</translation>
+    </message>
+    <message>
+        <source>GROUP_OTHER</source>
+        <translation>Other</translation>
+    </message>
     <message>
         <source>GEOM_X</source>
         <translation>X :</translation>
index 3e5ed2b8378a9018425647d6d3c8b3a03a9da331..42c064f741b2065d78757a99fc26f9f2c61e9e19 100644 (file)
@@ -323,9 +323,11 @@ TopoDS_Shape GEOMImpl_GlueDriver::GlueFacesByList (const TopoDS_Shape& theShape,
 //function : GlueFaces
 //purpose  :
 //=======================================================================
-TopoDS_Shape GEOMImpl_GlueDriver::GlueFaces (const TopoDS_Shape& theShape,
-                                             const Standard_Real theTolerance,
-                                             const Standard_Boolean doKeepNonSolids)
+TopoDS_Shape GEOMImpl_GlueDriver::GlueFaces
+          (const TopoDS_Shape                       &theShape,
+           const Standard_Real                       theTolerance,
+           const Standard_Boolean                    doKeepNonSolids,
+                 TopTools_DataMapOfShapeListOfShape *pMapModif)
 {
   TopoDS_Shape aRes;
 
@@ -409,6 +411,26 @@ TopoDS_Shape GEOMImpl_GlueDriver::GlueFaces (const TopoDS_Shape& theShape,
   // 5. Result
   aRes = aGA.Shape();
 
+  if (pMapModif) {
+    // Fill the map of modified shapes.
+    TopTools_IndexedMapOfShape aMapSubShapes;
+
+    TopExp::MapShapes(theShape, aMapSubShapes);
+    pMapModif->Clear();
+
+    const Standard_Integer aNbShapes = aMapSubShapes.Extent();
+    Standard_Integer       i;
+
+    for (i = 1; i <= aNbShapes; ++i) {
+      const TopoDS_Shape         &aSubShape = aMapSubShapes.FindKey(i);
+      const TopTools_ListOfShape &aModif    = aGA.Modified(aSubShape);
+
+      if (!aModif.IsEmpty()) {
+        pMapModif->Bind(aSubShape, aModif);
+      }
+    }
+  }
+
   return aRes;
 }
 
index 2339100b0e723aade12f9159a36041585da4cc86..7ebcbad8e47889682bd727100b2012048dd96b15 100644 (file)
@@ -63,6 +63,7 @@
 #include <TCollection_AsciiString.hxx>
 
 class TColStd_SequenceOfExtendedString;
+class TopTools_DataMapOfShapeListOfShape;
 
 
 #include "GEOM_BaseDriver.hxx"
@@ -86,9 +87,11 @@ Standard_EXPORT ~GEOMImpl_GlueDriver() {};
   bool GetCreationInformation(std::string&             theOperationName,
                               std::vector<GEOM_Param>& params);
 
-Standard_EXPORT static TopoDS_Shape GlueFaces (const TopoDS_Shape& theShape,
-                                               const Standard_Real theTolerance,
-                                               const Standard_Boolean doKeepNonSolids = Standard_True);
+Standard_EXPORT static TopoDS_Shape GlueFaces
+   (const TopoDS_Shape                       &theShape,
+    const Standard_Real                       theTolerance,
+    const Standard_Boolean                    doKeepNonSolids = Standard_True,
+          TopTools_DataMapOfShapeListOfShape *pMapModif       = NULL);
   /*
 Standard_EXPORT TopoDS_Shape GlueFacesWithWarnings (const TopoDS_Shape& theShape,
                                                     const Standard_Real theTolerance,
index eb9eb15aa94cdd000f0ab918bd29a71653de23c0..0174470713c4a57ffbb447e6702b9c16b4d836df 100644 (file)
@@ -61,6 +61,7 @@
 #include <GEOMImpl_IDisk.hxx>
 #include <GEOMImpl_ICylinder.hxx>
 #include <GEOMImpl_ICone.hxx>
+#include <GEOMImpl_IGroupOperations.hxx>
 #include <GEOMImpl_ISphere.hxx>
 #include <GEOMImpl_ITorus.hxx>
 #include <GEOMImpl_IPrism.hxx>
@@ -75,6 +76,8 @@
 #include <GEOMImpl_IPipePath.hxx>
 
 #include <Precision.hxx>
+#include <TopExp.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
 
 #include <Standard_Failure.hxx>
 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
@@ -88,6 +91,7 @@ GEOMImpl_I3DPrimOperations::GEOMImpl_I3DPrimOperations (GEOM_Engine* theEngine,
 : GEOM_IOperations(theEngine, theDocID)
 {
   MESSAGE("GEOMImpl_I3DPrimOperations::GEOMImpl_I3DPrimOperations");
+  myGroupOperations = new GEOMImpl_IGroupOperations(GetEngine(), GetDocID());
 }
 
 //=============================================================================
@@ -98,6 +102,7 @@ GEOMImpl_I3DPrimOperations::GEOMImpl_I3DPrimOperations (GEOM_Engine* theEngine,
 GEOMImpl_I3DPrimOperations::~GEOMImpl_I3DPrimOperations()
 {
   MESSAGE("GEOMImpl_I3DPrimOperations::~GEOMImpl_I3DPrimOperations");
+  delete myGroupOperations;
 }
 
 
@@ -1451,8 +1456,10 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeDraftPrism
  *  MakePipe
  */
 //=============================================================================
-Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipe (Handle(GEOM_Object) theBase,
-                                                          Handle(GEOM_Object) thePath)
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_I3DPrimOperations::MakePipe
+                            (const Handle(GEOM_Object) &theBase,
+                             const Handle(GEOM_Object) &thePath,
+                             const bool                 IsGenerateGroups)
 {
   SetErrorCode(KO);
 
@@ -1478,6 +1485,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipe (Handle(GEOM_Object) th
 
   aCI.SetBase(aRefBase);
   aCI.SetPath(aRefPath);
+  aCI.SetGenerateGroups(IsGenerateGroups);
 
   //Compute the Pipe value
   try {
@@ -1493,12 +1501,31 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipe (Handle(GEOM_Object) th
     return NULL;
   }
 
+  // Create the sequence of objects.
+  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+
+  aSeq->Append(aPipe);
+  createGroups(aPipe, &aCI, aSeq);
+
   //Make a Python command
-  GEOM::TPythonDump(aFunction) << aPipe << " = geompy.MakePipe("
-    << theBase << ", " << thePath << ")";
+  GEOM::TPythonDump pyDump(aFunction);
+
+  if (IsGenerateGroups) {
+    pyDump << aSeq;
+  } else {
+    pyDump << aPipe;
+  }
+
+  pyDump << " = geompy.MakePipe(" << theBase << ", " << thePath;
+
+  if (IsGenerateGroups) {
+    pyDump << ", True";
+  }
+
+  pyDump << ")";
 
   SetErrorCode(OK);
-  return aPipe;
+  return aSeq;
 }
 
 
@@ -1794,22 +1821,23 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeThruSections(
  *  MakePipeWithDifferentSections
  */
 //=============================================================================
-Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithDifferentSections(
-                const Handle(TColStd_HSequenceOfTransient)& theBases,
-                const Handle(TColStd_HSequenceOfTransient)& theLocations,
-                const Handle(GEOM_Object)& thePath,
-                bool theWithContact,
-                bool theWithCorrections)
+Handle(TColStd_HSequenceOfTransient)
+  GEOMImpl_I3DPrimOperations::MakePipeWithDifferentSections
+              (const Handle(TColStd_HSequenceOfTransient) &theBases,
+               const Handle(TColStd_HSequenceOfTransient) &theLocations,
+               const Handle(GEOM_Object)                  &thePath,
+               const bool                                  theWithContact,
+               const bool                                  theWithCorrections,
+               const bool                                  IsGenerateGroups)
 {
-  Handle(GEOM_Object) anObj;
   SetErrorCode(KO);
   if(theBases.IsNull())
-    return anObj;
+    return NULL;
 
   Standard_Integer nbBases = theBases->Length();
 
   if (!nbBases)
-    return anObj;
+    return NULL;
 
   Standard_Integer nbLocs =  (theLocations.IsNull() ? 0 :theLocations->Length());
   //Add a new Pipe object
@@ -1819,16 +1847,16 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithDifferentSections(
 
   Handle(GEOM_Function) aFunction =
     aPipeDS->AddFunction(GEOMImpl_PipeDriver::GetID(), PIPE_DIFFERENT_SECTIONS);
-  if (aFunction.IsNull()) return anObj;
+  if (aFunction.IsNull()) return NULL;
 
   //Check if the function is set correctly
-  if (aFunction->GetDriverGUID() != GEOMImpl_PipeDriver::GetID()) return anObj;
+  if (aFunction->GetDriverGUID() != GEOMImpl_PipeDriver::GetID()) return NULL;
 
   GEOMImpl_IPipeDiffSect aCI (aFunction);
 
   Handle(GEOM_Function) aRefPath = thePath->GetLastFunction();
   if(aRefPath.IsNull())
-    return anObj;
+    return NULL;
 
   Handle(TColStd_HSequenceOfTransient) aSeqBases = new TColStd_HSequenceOfTransient;
   Handle(TColStd_HSequenceOfTransient) aSeqLocs = new TColStd_HSequenceOfTransient;
@@ -1864,31 +1892,45 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithDifferentSections(
   }
 
   if(!aSeqBases->Length())
-    return anObj;
+    return NULL;
 
   aCI.SetBases(aSeqBases);
   aCI.SetLocations(aSeqLocs);
   aCI.SetPath(aRefPath);
   aCI.SetWithContactMode(theWithContact);
   aCI.SetWithCorrectionMode(theWithCorrections);
+  aCI.SetGenerateGroups(IsGenerateGroups);
 
   //Compute the Pipe value
   try {
     OCC_CATCH_SIGNALS;
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Pipe with defferent section driver failed");
-      return anObj;
+      return NULL;
     }
   }
   catch (Standard_Failure) {
     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
     SetErrorCode(aFail->GetMessageString());
-    return anObj;
+    return NULL;
   }
 
+  // Create the sequence of objects.
+  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+
+  aSeq->Append(aPipeDS);
+  createGroups(aPipeDS, &aCI, aSeq);
+
   //Make a Python command
   GEOM::TPythonDump pyDump(aFunction);
-  pyDump << aPipeDS << " = geompy.MakePipeWithDifferentSections([";
+
+  if (IsGenerateGroups) {
+    pyDump << aSeq;
+  } else {
+    pyDump << aPipeDS;
+  }
+
+  pyDump << " = geompy.MakePipeWithDifferentSections([";
 
   for(i =1 ; i <= nbBases; i++) {
 
@@ -1920,10 +1962,16 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithDifferentSections(
     }
   }
 
-  pyDump<< "], "<<thePath<<","<<theWithContact << "," << theWithCorrections<<")";
+  pyDump<< "], "<<thePath<<","<<theWithContact << "," << theWithCorrections;
+
+  if (IsGenerateGroups) {
+    pyDump << ", True";
+  }
+
+  pyDump << ")";
 
   SetErrorCode(OK);
-  return aPipeDS;
+  return aSeq;
 }
 
 
@@ -1932,23 +1980,24 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithDifferentSections(
  *  MakePipeWithShellSections
  */
 //=============================================================================
-Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithShellSections(
-                const Handle(TColStd_HSequenceOfTransient)& theBases,
-                const Handle(TColStd_HSequenceOfTransient)& theSubBases,
-                const Handle(TColStd_HSequenceOfTransient)& theLocations,
-                const Handle(GEOM_Object)& thePath,
-                bool theWithContact,
-                bool theWithCorrections)
+Handle(TColStd_HSequenceOfTransient)
+      GEOMImpl_I3DPrimOperations::MakePipeWithShellSections
+              (const Handle(TColStd_HSequenceOfTransient) &theBases,
+               const Handle(TColStd_HSequenceOfTransient) &theSubBases,
+               const Handle(TColStd_HSequenceOfTransient) &theLocations,
+               const Handle(GEOM_Object)                  &thePath,
+               const bool                                  theWithContact,
+               const bool                                  theWithCorrections,
+               const bool                                  IsGenerateGroups)
 {
-  Handle(GEOM_Object) anObj;
   SetErrorCode(KO);
   if(theBases.IsNull())
-    return anObj;
+    return NULL;
 
   Standard_Integer nbBases = theBases->Length();
 
   if (!nbBases)
-    return anObj;
+    return NULL;
 
   Standard_Integer nbSubBases =  (theSubBases.IsNull() ? 0 :theSubBases->Length());
 
@@ -1961,17 +2010,17 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithShellSections(
 
   Handle(GEOM_Function) aFunction =
     aPipeDS->AddFunction(GEOMImpl_PipeDriver::GetID(), PIPE_SHELL_SECTIONS);
-  if (aFunction.IsNull()) return anObj;
+  if (aFunction.IsNull()) return NULL;
 
   //Check if the function is set correctly
-  if (aFunction->GetDriverGUID() != GEOMImpl_PipeDriver::GetID()) return anObj;
+  if (aFunction->GetDriverGUID() != GEOMImpl_PipeDriver::GetID()) return NULL;
 
   //GEOMImpl_IPipeDiffSect aCI (aFunction);
   GEOMImpl_IPipeShellSect aCI (aFunction);
 
   Handle(GEOM_Function) aRefPath = thePath->GetLastFunction();
   if(aRefPath.IsNull())
-    return anObj;
+    return NULL;
 
   Handle(TColStd_HSequenceOfTransient) aSeqBases = new TColStd_HSequenceOfTransient;
   Handle(TColStd_HSequenceOfTransient) aSeqSubBases = new TColStd_HSequenceOfTransient;
@@ -2020,7 +2069,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithShellSections(
   }
 
   if(!aSeqBases->Length())
-    return anObj;
+    return NULL;
 
   aCI.SetBases(aSeqBases);
   aCI.SetSubBases(aSeqSubBases);
@@ -2028,24 +2077,38 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithShellSections(
   aCI.SetPath(aRefPath);
   aCI.SetWithContactMode(theWithContact);
   aCI.SetWithCorrectionMode(theWithCorrections);
+  aCI.SetGenerateGroups(IsGenerateGroups);
 
   //Compute the Pipe value
   try {
     OCC_CATCH_SIGNALS;
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Pipe with shell sections driver failed");
-      return anObj;
+      return NULL;
     }
   }
   catch (Standard_Failure) {
     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
     SetErrorCode(aFail->GetMessageString());
-    return anObj;
+    return NULL;
   }
 
+  // Create the sequence of objects.
+  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+
+  aSeq->Append(aPipeDS);
+  createGroups(aPipeDS, &aCI, aSeq);
+
   //Make a Python command
   GEOM::TPythonDump pyDump(aFunction);
-  pyDump << aPipeDS << " = geompy.MakePipeWithShellSections([";
+
+  if (IsGenerateGroups) {
+    pyDump << aSeq;
+  } else {
+    pyDump << aPipeDS;
+  }
+
+  pyDump << " = geompy.MakePipeWithShellSections([";
 
   for(i =1 ; i <= nbBases; i++) {
 
@@ -2093,10 +2156,16 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithShellSections(
     }
   }
 
-  pyDump<< "], "<<thePath<<","<<theWithContact << "," << theWithCorrections<<")";
+  pyDump<< "], "<<thePath<<","<<theWithContact << "," << theWithCorrections;
+
+  if (IsGenerateGroups) {
+    pyDump << ", True";
+  }
+
+  pyDump << ")";
 
   SetErrorCode(OK);
-  return aPipeDS;
+  return aSeq;
 
 }
 
@@ -2106,19 +2175,20 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithShellSections(
  *  MakePipeShellsWithoutPath
  */
 //=============================================================================
-Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeShellsWithoutPath(
-                const Handle(TColStd_HSequenceOfTransient)& theBases,
-                const Handle(TColStd_HSequenceOfTransient)& theLocations)
+Handle(TColStd_HSequenceOfTransient)
+      GEOMImpl_I3DPrimOperations::MakePipeShellsWithoutPath
+              (const Handle(TColStd_HSequenceOfTransient) &theBases,
+               const Handle(TColStd_HSequenceOfTransient) &theLocations,
+               const bool                                  IsGenerateGroups)
 {
-  Handle(GEOM_Object) anObj;
   SetErrorCode(KO);
   if(theBases.IsNull())
-    return anObj;
+    return NULL;
 
   Standard_Integer nbBases = theBases->Length();
 
   if (!nbBases)
-    return anObj;
+    return NULL;
 
   Standard_Integer nbLocs =  (theLocations.IsNull() ? 0 :theLocations->Length());
 
@@ -2129,10 +2199,10 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeShellsWithoutPath(
 
   Handle(GEOM_Function) aFunction =
     aPipeDS->AddFunction(GEOMImpl_PipeDriver::GetID(), PIPE_SHELLS_WITHOUT_PATH);
-  if (aFunction.IsNull()) return anObj;
+  if (aFunction.IsNull()) return NULL;
 
   //Check if the function is set correctly
-  if (aFunction->GetDriverGUID() != GEOMImpl_PipeDriver::GetID()) return anObj;
+  if (aFunction->GetDriverGUID() != GEOMImpl_PipeDriver::GetID()) return NULL;
 
   GEOMImpl_IPipeShellSect aCI (aFunction);
 
@@ -2169,28 +2239,42 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeShellsWithoutPath(
   }
 
   if(!aSeqBases->Length())
-    return anObj;
+    return NULL;
 
   aCI.SetBases(aSeqBases);
   aCI.SetLocations(aSeqLocs);
+  aCI.SetGenerateGroups(IsGenerateGroups);
 
   //Compute the Pipe value
   try {
     OCC_CATCH_SIGNALS;
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Pipe with shell sections without path driver failed");
-      return anObj;
+      return NULL;
     }
   }
   catch (Standard_Failure) {
     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
     SetErrorCode(aFail->GetMessageString());
-    return anObj;
+    return NULL;
   }
 
+  // Create the sequence of objects.
+  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+
+  aSeq->Append(aPipeDS);
+  createGroups(aPipeDS, &aCI, aSeq);
+
   //Make a Python command
   GEOM::TPythonDump pyDump(aFunction);
-  pyDump << aPipeDS << " = geompy.MakePipeShellsWithoutPath([";
+
+  if (IsGenerateGroups) {
+    pyDump << aSeq;
+  } else {
+    pyDump << aPipeDS;
+  }
+
+  pyDump << " = geompy.MakePipeShellsWithoutPath([";
 
   for(i =1 ; i <= nbBases; i++) {
 
@@ -2222,10 +2306,16 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeShellsWithoutPath(
     }
   }
 
-  pyDump<< "])";
+  pyDump<< "]";
+
+  if (IsGenerateGroups) {
+    pyDump << ", True";
+  }
+
+  pyDump << ")";
 
   SetErrorCode(OK);
-  return aPipeDS;
+  return aSeq;
 
 }
 
@@ -2234,9 +2324,12 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeShellsWithoutPath(
  *  MakePipeBiNormalAlongVector
  */
 //=============================================================================
-Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeBiNormalAlongVector (Handle(GEOM_Object) theBase,
-                                                                             Handle(GEOM_Object) thePath,
-                                                                             Handle(GEOM_Object) theVec)
+Handle(TColStd_HSequenceOfTransient)
+  GEOMImpl_I3DPrimOperations::MakePipeBiNormalAlongVector
+                (const Handle(GEOM_Object) &theBase,
+                 const Handle(GEOM_Object) &thePath,
+                 const Handle(GEOM_Object) &theVec,
+                 const bool                 IsGenerateGroups)
 {
   SetErrorCode(KO);
 
@@ -2264,6 +2357,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeBiNormalAlongVector (Han
   aCI.SetBase(aRefBase);
   aCI.SetPath(aRefPath);
   aCI.SetVector(aRefVec);
+  aCI.SetGenerateGroups(IsGenerateGroups);
 
   //Compute the Pipe value
   try {
@@ -2279,12 +2373,32 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeBiNormalAlongVector (Han
     return NULL;
   }
 
+  // Create the sequence of objects.
+  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+
+  aSeq->Append(aPipe);
+  createGroups(aPipe, &aCI, aSeq);
+
   //Make a Python command
-  GEOM::TPythonDump(aFunction) << aPipe << " = geompy.MakePipeBiNormalAlongVector("
-    << theBase << ", " << thePath << ", " << theVec << ")";
+  GEOM::TPythonDump pyDump(aFunction);
+
+  if (IsGenerateGroups) {
+    pyDump << aSeq;
+  } else {
+    pyDump << aPipe;
+  }
+
+  pyDump << " = geompy.MakePipeBiNormalAlongVector("
+         << theBase << ", " << thePath << ", " << theVec;
+
+  if (IsGenerateGroups) {
+    pyDump << ", True";
+  }
+
+  pyDump << ")";
 
   SetErrorCode(OK);
-  return aPipe;
+  return aSeq;
 }
 
 //=============================================================================
@@ -2546,3 +2660,122 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::RestorePath
   SetErrorCode(OK);
   return aPath;
 }
+
+//=============================================================================
+/*!
+ *  createGroup
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::createGroup
+                  (const Handle(GEOM_Object)              &theBaseObject,
+                   const Handle(TColStd_HArray1OfInteger) &theGroupIDs,
+                   const TCollection_AsciiString          &theName,
+                   const TopTools_IndexedMapOfShape       &theIndices)
+{
+  if (theBaseObject.IsNull() || theGroupIDs.IsNull()) {
+    return NULL;
+  }
+
+  // Get the Shape type.
+  const Standard_Integer anID      = theGroupIDs->Value(theGroupIDs->Lower());
+  const Standard_Integer aNbShapes = theIndices.Extent();
+
+  if (anID < 1 || anID > aNbShapes) {
+    return NULL;
+  }
+
+  const TopoDS_Shape aSubShape = theIndices.FindKey(anID);
+
+  if (aSubShape.IsNull()) {
+    return NULL;
+  }
+
+  // Create a group.
+  const TopAbs_ShapeEnum aGroupType = aSubShape.ShapeType();
+  Handle(GEOM_Object)    aGroup     =
+    myGroupOperations->CreateGroup(theBaseObject, aGroupType);
+
+  if (aGroup.IsNull() == Standard_False) {
+    aGroup->GetLastFunction()->SetDescription("");
+    aGroup->SetName(theName.ToCString());
+
+    Handle(TColStd_HSequenceOfInteger) aSeqIDs = new TColStd_HSequenceOfInteger;
+    Standard_Integer                   i;
+
+    for (i = theGroupIDs->Lower(); i <= theGroupIDs->Upper(); ++i) {
+      // Get and check the index.
+      const Standard_Integer anIndex = theGroupIDs->Value(i);
+
+      if (anIndex < 1 || anIndex > aNbShapes) {
+        return NULL;
+      }
+
+      // Get and check the sub-shape.
+      const TopoDS_Shape aSubShape = theIndices.FindKey(anIndex);
+
+      if (aSubShape.IsNull()) {
+        return NULL;
+      }
+
+      // Check the shape type.
+      if (aSubShape.ShapeType() != aGroupType) {
+        return NULL;
+      }
+
+      aSeqIDs->Append(anIndex);
+    }
+
+    myGroupOperations->UnionIDs(aGroup, aSeqIDs);
+    aGroup->GetLastFunction()->SetDescription("");
+  }
+
+  return aGroup;
+}
+
+//=============================================================================
+/*!
+ *  createGroups
+ */
+//=============================================================================
+void GEOMImpl_I3DPrimOperations::createGroups
+                   (const Handle(GEOM_Object)                  &theBaseObject,
+                          GEOMImpl_IPipe                       *thePipe,
+                          Handle(TColStd_HSequenceOfTransient) &theSequence)
+{
+  if (theBaseObject.IsNull() || thePipe == NULL || theSequence.IsNull()) {
+    return;
+  }
+
+  TopoDS_Shape aShape = theBaseObject->GetValue();
+
+  if (aShape.IsNull()) {
+    return;
+  }
+
+  TopTools_IndexedMapOfShape       anIndices;
+  Handle(TColStd_HArray1OfInteger) aGroupIDs;
+  TopoDS_Shape                     aShapeType;
+  const Standard_Integer           aNbGroups = 5;
+  Handle(GEOM_Object)              aGrps[aNbGroups];
+  Standard_Integer                 i;
+
+  TopExp::MapShapes(aShape, anIndices);
+
+  // Create groups.
+  aGroupIDs = thePipe->GetGroupDown();
+  aGrps[0]  = createGroup(theBaseObject, aGroupIDs, "GROUP_DOWN", anIndices);
+  aGroupIDs = thePipe->GetGroupUp();
+  aGrps[1]  = createGroup(theBaseObject, aGroupIDs, "GROUP_UP", anIndices);
+  aGroupIDs = thePipe->GetGroupSide1();
+  aGrps[2]  = createGroup(theBaseObject, aGroupIDs, "GROUP_SIDE1", anIndices);
+  aGroupIDs = thePipe->GetGroupSide2();
+  aGrps[3]  = createGroup(theBaseObject, aGroupIDs, "GROUP_SIDE2", anIndices);
+  aGroupIDs = thePipe->GetGroupOther();
+  aGrps[4]  = createGroup(theBaseObject, aGroupIDs, "GROUP_OTHER", anIndices);
+
+  for (i = 0; i < aNbGroups; ++i) {
+    if (aGrps[i].IsNull() == Standard_False) {
+      theSequence->Append(aGrps[i]);
+    }
+  }
+}
index 80c8ff4f8181d46f36ed26eb4efb3337d002f02a..a0ae56e3790b0d0e3475ba0e69e55555850fadad 100644 (file)
 #include <TDocStd_Document.hxx>
 #include <TColStd_HSequenceOfTransient.hxx>
 
+class GEOMImpl_IGroupOperations;
+class GEOMImpl_IPipe;
+class TopTools_IndexedMapOfShape;
+
+
 class GEOMImpl_I3DPrimOperations : public GEOM_IOperations {
  public:
   Standard_EXPORT GEOMImpl_I3DPrimOperations(GEOM_Engine* theEngine, int theDocID);
@@ -98,8 +103,10 @@ class GEOMImpl_I3DPrimOperations : public GEOM_IOperations {
   Standard_EXPORT Handle(GEOM_Object) MakeDraftPrism  (Handle(GEOM_Object) theInitShape, Handle(GEOM_Object) theBase,
                                                        double theHeight, double theAngle, bool theFuse, bool theInvert = false );
   
-  Standard_EXPORT Handle(GEOM_Object) MakePipe (Handle(GEOM_Object) theBase,
-                                                Handle(GEOM_Object) thePath);
+  Standard_EXPORT Handle(TColStd_HSequenceOfTransient) MakePipe
+                            (const Handle(GEOM_Object) &theBase,
+                             const Handle(GEOM_Object) &thePath,
+                             const bool                 IsGenerateGroups);
 
   Standard_EXPORT Handle(GEOM_Object) MakeRevolutionAxisAngle (Handle(GEOM_Object) theBase,
                                                                Handle(GEOM_Object) theAxis,
@@ -121,28 +128,34 @@ class GEOMImpl_I3DPrimOperations : public GEOM_IOperations {
                                        double thePreci,
                                        bool theRuled);
 
-  Standard_EXPORT Handle(GEOM_Object) MakePipeWithDifferentSections(
-                const Handle(TColStd_HSequenceOfTransient)& theBases,
-                const Handle(TColStd_HSequenceOfTransient)& theLocations,
-                const Handle(GEOM_Object)& thePath,
-                bool theWithContact,
-                bool theWithCorrections);
-
-  Standard_EXPORT Handle(GEOM_Object) MakePipeWithShellSections(
-                const Handle(TColStd_HSequenceOfTransient)& theBases,
-                const Handle(TColStd_HSequenceOfTransient)& theSubBases,
-                const Handle(TColStd_HSequenceOfTransient)& theLocations,
-                const Handle(GEOM_Object)& thePath,
-                bool theWithContact,
-                bool theWithCorrections);
-
-  Standard_EXPORT Handle(GEOM_Object) MakePipeShellsWithoutPath
-                (const Handle(TColStd_HSequenceOfTransient)& theBases,
-                 const Handle(TColStd_HSequenceOfTransient)& theLocations);
-
-  Standard_EXPORT Handle(GEOM_Object) MakePipeBiNormalAlongVector (Handle(GEOM_Object) theBase,
-                                                                   Handle(GEOM_Object) thePath,
-                                                                   Handle(GEOM_Object) theVec);
+  Standard_EXPORT Handle(TColStd_HSequenceOfTransient)
+      MakePipeWithDifferentSections
+              (const Handle(TColStd_HSequenceOfTransient) &theBases,
+               const Handle(TColStd_HSequenceOfTransient) &theLocations,
+               const Handle(GEOM_Object)                  &thePath,
+               const bool                                  theWithContact,
+               const bool                                  theWithCorrections,
+               const bool                                  IsGenerateGroups);
+
+  Standard_EXPORT Handle(TColStd_HSequenceOfTransient) MakePipeWithShellSections
+              (const Handle(TColStd_HSequenceOfTransient) &theBases,
+               const Handle(TColStd_HSequenceOfTransient) &theSubBases,
+               const Handle(TColStd_HSequenceOfTransient) &theLocations,
+               const Handle(GEOM_Object)                  &thePath,
+               const bool                                  theWithContact,
+               const bool                                  theWithCorrections,
+               const bool                                  IsGenerateGroups);
+
+  Standard_EXPORT Handle(TColStd_HSequenceOfTransient) MakePipeShellsWithoutPath
+              (const Handle(TColStd_HSequenceOfTransient) &theBases,
+               const Handle(TColStd_HSequenceOfTransient) &theLocations,
+               const bool                                  IsGenerateGroups);
+
+  Standard_EXPORT Handle(TColStd_HSequenceOfTransient) MakePipeBiNormalAlongVector
+                (const Handle(GEOM_Object) &theBase,
+                 const Handle(GEOM_Object) &thePath,
+                 const Handle(GEOM_Object) &theVec,
+                 const bool                 IsGenerateGroups);
   
   Standard_EXPORT Handle(GEOM_Object) MakeThickening
                 (Handle(GEOM_Object)                     theObject,
@@ -158,6 +171,23 @@ class GEOMImpl_I3DPrimOperations : public GEOM_IOperations {
   Standard_EXPORT Handle(GEOM_Object) RestorePath (Handle(GEOM_Object) theShape,
                                                    const Handle(TColStd_HSequenceOfTransient)& theBase1,
                                                    const Handle(TColStd_HSequenceOfTransient)& theBase2);
+
+private:
+
+  Handle(GEOM_Object) createGroup
+                  (const Handle(GEOM_Object)              &theBaseObject,
+                   const Handle(TColStd_HArray1OfInteger) &theGroupIDs,
+                   const TCollection_AsciiString          &theName,
+                   const TopTools_IndexedMapOfShape       &theIndices);
+
+  void createGroups(const Handle(GEOM_Object)                  &theBaseObject,
+                          GEOMImpl_IPipe                       *thePipe,
+                          Handle(TColStd_HSequenceOfTransient) &theSequence);
+
+private:
+
+  GEOMImpl_IGroupOperations *myGroupOperations;
+
 };
 
 #endif
index 22ace08b3084ddd7aece1300b17c877c5acca3db..fc346c5f13d8359c1ccd921fec2634d133937f4d 100644 (file)
 
 #include "GEOM_Function.hxx"
 
-#define PIPE_ARG_BASE 1
-#define PIPE_ARG_PATH 2
+#include <TColStd_HArray1OfInteger.hxx>
+
+// ---- GEOMImpl_IPipe
+#define PIPE_ARG_BASE          1
+#define PIPE_ARG_PATH          2
+
+// ---- GEOMImpl_IPipeBiNormal
+#define PIPE_ARG_VEC           3
+
+// ---- GEOMImpl_IPipeDiffSect
+#define PIPEDS_LIST_BASES      1
+//#define PIPEDS_ARG_PATH      2
+#define PIPEDS_LIST_LOCATIONS  3
+#define PIPEDS_ARG_WITHCONTACT 4
+#define PIPEDS_ARG_WITHCORRECT 5
+
+// ---- GEOMImpl_IPipeShellSect
+#define PIPEDS_LIST_SUBBASES   6
+
+// ---- Generate groups block (common)
+#define PIPE_GENERATE_GROUPS   7
+#define PIPE_GROUP_DOWN        8
+#define PIPE_GROUP_UP          9
+#define PIPE_GROUP_SIDE1       10
+#define PIPE_GROUP_SIDE2       11
+#define PIPE_GROUP_OTHER       12
+
 
 class GEOMImpl_IPipe
 {
  public:
 
   GEOMImpl_IPipe(Handle(GEOM_Function) theFunction): _func(theFunction) {}
+  virtual ~GEOMImpl_IPipe() {}
 
   void SetBase (Handle(GEOM_Function) theBase) { _func->SetReference(PIPE_ARG_BASE, theBase); }
   void SetPath (Handle(GEOM_Function) thePath) { _func->SetReference(PIPE_ARG_PATH, thePath); }
+  void SetGenerateGroups (int theGenerateGroups)
+  { _func->SetInteger(PIPE_GENERATE_GROUPS, theGenerateGroups); }
+  void SetGroupDown (const Handle(TColStd_HArray1OfInteger) &theGroup)
+  { _func->SetIntegerArray(PIPE_GROUP_DOWN, theGroup); }
+  void SetGroupUp (const Handle(TColStd_HArray1OfInteger) &theGroup)
+  { _func->SetIntegerArray(PIPE_GROUP_UP, theGroup); }
+  void SetGroupSide1 (const Handle(TColStd_HArray1OfInteger) &theGroup)
+  { _func->SetIntegerArray(PIPE_GROUP_SIDE1, theGroup); }
+  void SetGroupSide2 (const Handle(TColStd_HArray1OfInteger) &theGroup)
+  { _func->SetIntegerArray(PIPE_GROUP_SIDE2, theGroup); }
+  void SetGroupOther (const Handle(TColStd_HArray1OfInteger) &theGroup)
+  { _func->SetIntegerArray(PIPE_GROUP_OTHER, theGroup); }
 
   Handle(GEOM_Function) GetBase() { return _func->GetReference(PIPE_ARG_BASE); }
   Handle(GEOM_Function) GetPath() { return _func->GetReference(PIPE_ARG_PATH); }
+  int GetGenerateGroups () { return _func->GetInteger(PIPE_GENERATE_GROUPS); }
+  Handle(TColStd_HArray1OfInteger) GetGroupDown ()
+  { return _func->GetIntegerArray(PIPE_GROUP_DOWN); }
+  Handle(TColStd_HArray1OfInteger) GetGroupUp ()
+  { return _func->GetIntegerArray(PIPE_GROUP_UP); }
+  Handle(TColStd_HArray1OfInteger) GetGroupSide1 ()
+  { return _func->GetIntegerArray(PIPE_GROUP_SIDE1); }
+  Handle(TColStd_HArray1OfInteger) GetGroupSide2 ()
+  { return _func->GetIntegerArray(PIPE_GROUP_SIDE2); }
+  Handle(TColStd_HArray1OfInteger) GetGroupOther ()
+  { return _func->GetIntegerArray(PIPE_GROUP_OTHER); }
 
  protected:
 
index 8d3780f1a368d2ba1cd2b30d428e44036357f2a9..e6b154c164cf99a4c7c9a4082d4b5f883dfbcf58 100644 (file)
 #ifndef _GEOMImpl_IPIPEBINORMAL_HXX_
 #define _GEOMImpl_IPIPEBINORMAL_HXX_
 
-#include "GEOM_Function.hxx"
 
-#ifndef _GEOMImpl_IPIPE_HXX_
 #include "GEOMImpl_IPipe.hxx"
-#endif
 
-#define PIPE_ARG_BASE 1
-#define PIPE_ARG_PATH 2
-#define PIPE_ARG_VEC  3
+// Position definitions are declared in the base class.
 
 class GEOMImpl_IPipeBiNormal : public GEOMImpl_IPipe
 {
index 563d326333f6b5bdd1aebbe138110105ed823462..902f0cf4d436aeb0ba1eafb50d23e5baac61e017 100644 (file)
 #ifndef _GEOMImpl_IPIPEDIFFSECT_HXX_
 #define _GEOMImpl_IPIPEDIFFSECT_HXX_
 
-#include "GEOM_Function.hxx"
 
-#include <TColStd_HSequenceOfTransient.hxx>
-
-#ifndef _GEOMImpl_IPIPE_HXX_
 #include "GEOMImpl_IPipe.hxx"
-#endif
-
-#define PIPEDS_LIST_BASES 1
-#define PIPEDS_LIST_LOCATIONS 3
-//#define PIPEDS_ARG_PATH 2
-#define PIPEDS_ARG_WITHCONTACT 4
-#define PIPEDS_ARG_WITHCORRECT 5
+#include <TColStd_HSequenceOfTransient.hxx>
 
+// Position definitions are declared in the base class.
 
 class GEOMImpl_IPipeDiffSect : public GEOMImpl_IPipe
 {
index e65a60b1f600c817d7160fd44f9190fc5e1823bc..f162a0b97d4be8d0d253dc2f4952f88186da628b 100644 (file)
 #ifndef _GEOMImpl_IPIPESHELLSECT_HXX_
 #define _GEOMImpl_IPIPESHELLSECT_HXX_
 
-#include "GEOM_Function.hxx"
 
-#ifndef _GEOMImpl_IPIPEDIFFSECT_HXX_
 #include "GEOMImpl_IPipeDiffSect.hxx"
-#endif
-
+#include "GEOM_Function.hxx"
 #include <TColStd_HSequenceOfTransient.hxx>
 
-#define PIPEDS_LIST_SUBBASES 6
-
+// Position definitions are declared in the base class GEOMImpl_IPipe.
 
 class GEOMImpl_IPipeShellSect : public GEOMImpl_IPipeDiffSect
 {
index 029595cbf609971a3ee76a6b2b36984798bddb95..4768d35f11720613e68e82d826d7692f15b35db7 100644 (file)
 #include <TopoDS_Shell.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Compound.hxx>
+#include <TopTools_DataMapOfShapeSequenceOfShape.hxx>
 #include <TopTools_SequenceOfShape.hxx>
 #include <TopTools_HSequenceOfShape.hxx>
 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_MapIteratorOfMapOfShape.hxx>
 
 #include <GProp_GProps.hxx>
 
 
 #include "utilities.h"
 
+#define GROUP_DOWN  0
+#define GROUP_UP    1
+#define GROUP_SIDE1 2
+#define GROUP_SIDE2 3
+#define GROUP_OTHER 4
+
+static bool FillGroups(const TopTools_SequenceOfShape         *theGroups,
+                       const TopTools_IndexedMapOfShape       &theIndices,
+                             Handle(TColStd_HArray1OfInteger) *theGroupIds);
+
+static void StoreGroups(GEOMImpl_IPipe                   *theCI,
+                        Handle(TColStd_HArray1OfInteger) *theGroups);
+
+static bool DoGroups(BRepOffsetAPI_MakePipeShell &theSweep,
+                     TopTools_SequenceOfShape    *theGroups);
+
+static bool CreateGroups(BRepOffsetAPI_MakePipeShell &theSweep,
+                         GEOMImpl_IPipe              *theCI);
 
 //=======================================================================
 //function : GetID
@@ -277,15 +297,6 @@ static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
   BuildPipeShell(aBuilder);
 
   TopoDS_Shape aShape = aBuilder.Shape();
-  /*
-  TopoDS_Compound C;
-  BRep_Builder B;
-  B.MakeCompound(C);
-  B.Add(C,aShape);
-  B.Add(C,FS1);
-  B.Add(C,FS2);
-  BRepTools::Write(C,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
-  */
   ShapeAnalysis_Edge sae;
   double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
                     BRep_Tool::Tolerance(TopoDS::Face(FS2)));
@@ -680,11 +691,12 @@ static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
 //purpose  :
 //=======================================================================
 TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
-                                  (const TopoDS_Wire& theWirePath,
-                                   const Handle(TopTools_HSequenceOfShape) theHSeqBases,
-                                   const Handle(TopTools_HSequenceOfShape) theHSeqLocs,
-                                   const Standard_Boolean theWithContact,
-                                   const Standard_Boolean theWithCorrect)
+                  (const TopoDS_Wire                       &theWirePath,
+                   const Handle(TopTools_HSequenceOfShape)  theHSeqBases,
+                   const Handle(TopTools_HSequenceOfShape)  theHSeqLocs,
+                   const Standard_Boolean                   theWithContact,
+                   const Standard_Boolean                   theWithCorrect,
+                         Handle(TColStd_HArray1OfInteger)  *theGroups)
 {
   TopoDS_Shape aShape;
 
@@ -916,8 +928,12 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
       P1 = P2;
   }
 
+  bool isCreateGroups = (theGroups != NULL);
+
   if (SplitLocNums.Length()==SplitEdgeNums.Length() && SplitEdgeNums.Length()>0) {
-      TopTools_SequenceOfShape aSeqRes;
+      TopTools_SequenceOfShape               aSeqRes;
+      TopTools_DataMapOfShapeSequenceOfShape aMapResGroups[5];
+      Standard_Integer                       iGrp;
       int nn, num1 = 1, num2 = 1;
       for (nn=1; nn<=SplitEdgeNums.Length(); nn++) {
         // create wirepath and sequences of shapes
@@ -954,6 +970,21 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
 
         TopoDS_Shape resShape = aBuilder.Shape();
         aSeqRes.Append(resShape);
+
+        // Create groups.
+        if (isCreateGroups) {
+          // Make groups.
+          TopTools_SequenceOfShape aGroups[5];
+
+          if (!DoGroups(aBuilder, aGroups)) {
+            Standard_ConstructionError::Raise("Generate groups failure");
+          }
+
+          // Get shapes from all groups.
+          for (iGrp = 0; iGrp < 5; ++iGrp) {
+            aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
+          }
+        }
       }
       // create wirepath and sequences of shapes for last part
       BRep_Builder B;
@@ -987,6 +1018,22 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
 
       TopoDS_Shape resShape = aBuilder.Shape();
       aSeqRes.Append(resShape);
+
+      // Create groups.
+      if (isCreateGroups) {
+        // Make groups.
+        TopTools_SequenceOfShape aGroups[5];
+
+        if (!DoGroups(aBuilder, aGroups)) {
+          Standard_ConstructionError::Raise("Generate groups failure");
+        }
+
+        // Get shapes from all groups.
+        for (iGrp = 0; iGrp < 5; ++iGrp) {
+          aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
+        }
+      }
+
       // make sewing for result
       Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
       aSewing->SetTolerance(Precision::Confusion());
@@ -998,6 +1045,56 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
       }
       aSewing->Perform();
       aShape = aSewing->SewedShape();
+
+      if (isCreateGroups) {
+        // Replase Group shapes by modified ones.
+        TopTools_SequenceOfShape aSeqGroups[5];
+
+        // For each group.
+        for (iGrp = 0; iGrp < 5; ++iGrp) {
+          // For each pipe
+          for (i = 1; i <= aSeqRes.Length(); ++i) {
+            if (iGrp == GROUP_DOWN && i > 1) {
+              // For DOWN group we use only the first pipe.
+              continue;
+            }
+
+            if (iGrp == GROUP_UP && i < aSeqRes.Length()) {
+              // For UP group we use only the last pipe.
+              continue;
+            }
+
+            const TopTools_SequenceOfShape &aShapes =
+              aMapResGroups[iGrp].Find(aSeqRes.Value(i));
+            Standard_Integer                j;
+
+            // For each sub-shape of pipe
+            for (j = 1; j <= aShapes.Length(); ++j) {
+              const TopoDS_Shape &aGrpShape = aShapes.Value(j);
+
+              if (aSewing->IsModifiedSubShape(aGrpShape)) {
+                // Use the shape modified by sewing.
+                const TopoDS_Shape &aModifGrpShape =
+                  aSewing->ModifiedSubShape(aGrpShape);
+
+                aSeqGroups[iGrp].Append(aModifGrpShape);
+              } else {
+                // Use the shape as it is.
+                aSeqGroups[iGrp].Append(aGrpShape);
+              }
+            }
+          }
+        }
+
+        // Fill groups
+        TopTools_IndexedMapOfShape anIndices;
+
+        TopExp::MapShapes(aShape, anIndices);
+
+        if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
+          Standard_ConstructionError::Raise("Generate groups failure");
+        }
+      }
   }
   else {
       // old implementation without splitting
@@ -1047,6 +1144,26 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
           Standard_ConstructionError::Raise("Pipe construction failure");
         }
         aShape = aBuilder.Shape();
+
+        if (isCreateGroups) {
+          // Make groups.
+          TopTools_SequenceOfShape aSeqGroups[5];
+
+          if (!DoGroups(aBuilder, aSeqGroups)) {
+            Standard_ConstructionError::Raise("Generate groups failure");
+          }
+
+          // Fill the groups.
+          Handle(TColStd_HArray1OfInteger) aGroupIds[5];
+          TopTools_IndexedMapOfShape       anIndices;
+          const TopoDS_Shape               aResult = aBuilder.Shape();
+
+          TopExp::MapShapes(aResult, anIndices);
+
+          if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
+            Standard_ConstructionError::Raise("Generate groups failure");
+          }
+        }
         aSeqFaces.Append(aShape);
         for (j = 1; j <=usedBases.Length(); j++)
           aBuilder.Delete(usedBases.Value(j));
@@ -1063,8 +1180,6 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
 static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
                                                GEOMImpl_IPipe* aCI)
 {
-  //cout<<"CreatePipeForShellSections"<<endl;
-  //TopoDS_Shape res;
   int i,j;
   BRep_Builder B;
 
@@ -1074,6 +1189,7 @@ static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
   Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations();
   Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
   Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
+  Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
 
   Standard_Integer nbBases = aBasesObjs->Length(),
     nbSubBases = (aSubBasesObjs.IsNull() ? 0 :aSubBasesObjs->Length()),
@@ -1088,8 +1204,6 @@ static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
     Standard_ConstructionError::Raise("Number of sections is not equal to number of subsections ");
   }
 
-  //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
-
   TopTools_SequenceOfShape VLocs;
   for (i=1; i<=nbBases; i++) {
     Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
@@ -1261,7 +1375,6 @@ static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
     for (; i<=Edges.Length(); i++)
       B.Add(W,Edges.Value(i));
     Wires.Append(W);
-    //cout<<"Wires.Length()="<<Wires.Length()<<endl;
   }
 
   if (Wires.Length() != nbLocs-1) {
@@ -1270,10 +1383,8 @@ static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
       ("One of location shapes is not lied on the path");
   }
 
-  //TopTools_SequenceOfShape aSeqBases;
-  //TopTools_SequenceOfShape aSeqSubBases;
-  //TopTools_SequenceOfShape aSeqFaces;
-  TopoDS_Compound aComp;
+  TopTools_SequenceOfShape aGroups[5];
+  TopoDS_Compound          aComp;
   B.MakeCompound(aComp);
   for (i = 1; i < nbBases; i++) {
     TopoDS_Wire WPath = TopoDS::Wire(Wires.Value(i));
@@ -1300,8 +1411,6 @@ static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
       continue;
     TopAbs_ShapeEnum aType2 = aShBase2.ShapeType();
 
-    //BRepTools::Write(aShBase1,"/dn02/users_Linux/skl/work/Bugs/14857/base1.brep");
-
     bool OkSec = (aType1==TopAbs_SHELL || aType1==TopAbs_FACE) &&
                  (aType2==TopAbs_SHELL || aType2==TopAbs_FACE);
     if (!OkSec) {
@@ -1324,153 +1433,6 @@ static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
       CreateFewSolids = true;
     }
 
-    /*
-    // check orientation of sections
-    bool NeedReverse = false;
-    {
-      // first section
-      anExp.Init(aShBase1, TopAbs_FACE);
-      TopoDS_Shape aFace = anExp.Current();
-      TColgp_SequenceOfPnt aPnts;
-      double xc=0, yc=0, zc=0;
-      for (anExp.Init(aFace, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
-        TopoDS_Vertex V = TopoDS::Vertex(anExp.Current());
-        aPnts.Append(BRep_Tool::Pnt(V));
-        xc += aPnts.Last().X();
-        yc += aPnts.Last().Y();
-        zc += aPnts.Last().Z();
-      }
-      gp_Pnt PC(xc/aPnts.Length(), yc/aPnts.Length(), zc/aPnts.Length());
-      gp_Vec V1(PC,aPnts.Value(1));
-      gp_Vec V2(PC,aPnts.Value(2));
-      gp_Vec VN = V1.Crossed(V2);
-      for (int ip=2; ip<aPnts.Length(); ip++) {
-        V1 = gp_Vec(PC,aPnts.Value(ip));
-        V2 = gp_Vec(PC,aPnts.Value(ip+1));
-        VN.Add(V1.Crossed(V2));
-      }
-      gp_Vec PathNorm;
-      gp_Pnt PLoc = BRep_Tool::Pnt(TopoDS::Vertex(VLocs(i)));
-      TopExp_Explorer WE;
-      for (WE.Init(WPath, TopAbs_EDGE); WE.More(); WE.Next()) {
-        TopoDS_Edge edge = TopoDS::Edge(WE.Current());
-        double tol = BRep_Tool::Tolerance(edge);
-        TopoDS_Vertex VF = sae.FirstVertex(edge);
-        gp_Pnt PF = BRep_Tool::Pnt(VF);
-        if (PF.Distance(PLoc) < tol) {
-          double fp,lp;
-          Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
-          gp_Pnt P1,P2;
-          C->D0(fp,P1);
-          if (P1.Distance(PLoc) < tol) {
-            C->D0(fp+(lp-fp)/100,P2);
-          }
-          else {
-            C->D0(lp,P1);
-            C->D0(lp+(fp-lp)/100,P2);
-          }
-          PathNorm = gp_Vec(P1,P2);
-          break;
-        }
-        else {
-          TopoDS_Vertex VL = sae.LastVertex(edge);
-          gp_Pnt PL = BRep_Tool::Pnt(VL);
-          if (PL.Distance(PLoc) < tol) {
-            double fp,lp;
-            Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
-            gp_Pnt P1,P2;
-            C->D0(fp,P1);
-            if (P1.Distance(PLoc) < tol) {
-              C->D0(fp+(lp-fp)/100,P2);
-            }
-            else {
-              C->D0(lp,P1);
-              C->D0(lp+(fp-lp)/100,P2);
-            }
-            PathNorm = gp_Vec(P2,P1);
-            break;
-          }
-        }
-      }
-      cout<<"VN("<<VN.X()<<","<<VN.Y()<<","<<VN.Z()<<")"<<endl;
-      cout<<"PathNorm("<<PathNorm.X()<<","<<PathNorm.Y()<<","<<PathNorm.Z()<<")"<<endl;
-      if (fabs(VN.Angle(PathNorm))>PI/2.) {
-        NeedReverse = true;
-        aShBase1.Reverse();
-      }
-    }
-    {
-      // second section
-      anExp.Init(aShBase2, TopAbs_FACE);
-      TopoDS_Shape aFace = anExp.Current();
-      TColgp_SequenceOfPnt aPnts;
-      double xc=0, yc=0, zc=0;
-      for (anExp.Init(aFace, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
-        TopoDS_Vertex V = TopoDS::Vertex(anExp.Current());
-        aPnts.Append(BRep_Tool::Pnt(V));
-        xc += aPnts.Last().X();
-        yc += aPnts.Last().Y();
-        zc += aPnts.Last().Z();
-      }
-      gp_Pnt PC(xc/aPnts.Length(), yc/aPnts.Length(), zc/aPnts.Length());
-      gp_Vec V1(PC,aPnts.Value(1));
-      gp_Vec V2(PC,aPnts.Value(2));
-      gp_Vec VN = V1.Crossed(V2);
-      for (int ip=2; ip<aPnts.Length(); ip++) {
-        V1 = gp_Vec(PC,aPnts.Value(ip));
-        V2 = gp_Vec(PC,aPnts.Value(ip+1));
-        VN.Add(V1.Crossed(V2));
-      }
-      gp_Vec PathNorm;
-      gp_Pnt PLoc = BRep_Tool::Pnt(TopoDS::Vertex(VLocs(i+1)));
-      TopExp_Explorer WE;
-      for (WE.Init(WPath, TopAbs_EDGE); WE.More(); WE.Next()) {
-        TopoDS_Edge edge = TopoDS::Edge(WE.Current());
-        double tol = BRep_Tool::Tolerance(edge);
-        TopoDS_Vertex VF = sae.FirstVertex(edge);
-        gp_Pnt PF = BRep_Tool::Pnt(VF);
-        if (PF.Distance(PLoc) < tol) {
-          double fp,lp;
-          Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
-          gp_Pnt P1,P2;
-          C->D0(fp,P1);
-          if (P1.Distance(PLoc) < tol) {
-            C->D0(fp+(lp-fp)/100,P2);
-          }
-          else {
-            C->D0(lp,P1);
-            C->D0(lp+(fp-lp)/100,P2);
-          }
-          PathNorm = gp_Vec(P2,P1);
-          break;
-        }
-        else {
-          TopoDS_Vertex VL = sae.LastVertex(edge);
-          gp_Pnt PL = BRep_Tool::Pnt(VL);
-          if (PL.Distance(PLoc) < tol) {
-            double fp,lp;
-            Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
-            gp_Pnt P1,P2;
-            C->D0(fp,P1);
-            if (P1.Distance(PLoc) < tol) {
-              C->D0(fp+(lp-fp)/100,P2);
-            }
-            else {
-              C->D0(lp,P1);
-              C->D0(lp+(fp-lp)/100,P2);
-            }
-            PathNorm = gp_Vec(P2,P1);
-            break;
-          }
-        }
-      }
-      //cout<<"VN("<<VN.X()<<","<<VN.Y()<<","<<VN.Z()<<")"<<endl;
-      //cout<<"PathNorm("<<PathNorm.X()<<","<<PathNorm.Y()<<","<<PathNorm.Z()<<")"<<endl;
-      if (fabs(VN.Angle(PathNorm))>PI/2.)
-        aShBase2.Reverse();
-    }
-    */
-
     if (!CreateFewSolids) {
       // we can create only one solid
       TopoDS_Shape aWire1, aWire2;
@@ -1536,7 +1498,22 @@ static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
 
         BuildPipeShell(aBuilder);
 
-        TopoDS_Shape aShape = aBuilder.Shape();
+        TopoDS_Shape             aShape = aBuilder.Shape();
+        TopTools_SequenceOfShape aLocalGroups[5];
+
+        // Create groups.
+        if (isGenerateGroups) {
+          // Make groups.
+          if (!DoGroups(aBuilder, aLocalGroups)) {
+            if (aCI) delete aCI;
+            Standard_ConstructionError::Raise("Generate groups failure");
+          }
+
+          // Clear the groups Down and Up.
+          aLocalGroups[GROUP_DOWN].Clear();
+          aLocalGroups[GROUP_UP].Clear();
+        }
+
         TopoDS_Shell aShell;
         B.MakeShell(aShell);
         for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
@@ -1544,9 +1521,17 @@ static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
         }
         for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
           B.Add(aShell,anExp.Current());
+
+          if (isGenerateGroups && i == 1) {
+            aLocalGroups[GROUP_DOWN].Append(anExp.Current());
+          }
         }
         for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
           B.Add(aShell,anExp.Current());
+
+          if (isGenerateGroups && i == nbBases - 1) {
+            aLocalGroups[GROUP_UP].Append(anExp.Current());
+          }
         }
         // make sewing for this shell
         Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
@@ -1579,6 +1564,30 @@ static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
         else {
           B.Add(aComp,aShell);
         }
+
+        if (isGenerateGroups) {
+          Standard_Integer iGrp;
+
+          for (iGrp = 0; iGrp < 5; ++iGrp) {
+            Standard_Integer j;
+
+            // For each sub-shape of pipe
+            for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
+              const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
+
+              if (aSewing->IsModifiedSubShape(aGrpShape)) {
+                // Use the shape modified by sewing.
+                const TopoDS_Shape &aModifGrpShape =
+                  aSewing->ModifiedSubShape(aGrpShape);
+
+                aGroups[iGrp].Append(aModifGrpShape);
+              } else {
+                // Use the shape as it is.
+                aGroups[iGrp].Append(aGrpShape);
+              }
+            }
+          }
+        }
       }
     }
     else {
@@ -1776,7 +1785,30 @@ static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
 
           BuildPipeShell(aBuilder);
 
-          TopoDS_Shape aShape = aBuilder.Shape();
+          TopoDS_Shape             aShape = aBuilder.Shape();
+          TopTools_SequenceOfShape aLocalGroups[5];
+
+          // Create groups.
+          if (isGenerateGroups) {
+            // Make groups.
+            if (!DoGroups(aBuilder, aLocalGroups)) {
+              if (aCI) delete aCI;
+              Standard_ConstructionError::Raise("Generate groups failure");
+            }
+
+            // Clear the groups Down and Up.
+            aLocalGroups[GROUP_DOWN].Clear();
+            aLocalGroups[GROUP_UP].Clear();
+
+            if (i == 1) {
+              aLocalGroups[GROUP_DOWN].Append(F1);
+            }
+
+            if (i == nbBases - 1) {
+              aLocalGroups[GROUP_UP].Append(F2);
+            }
+          }
+
           TopoDS_Shell aShell;
           B.MakeShell(aShell);
           for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
@@ -1817,13 +1849,52 @@ static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
           else {
             B.Add(aComp,aShell);
           }
+
+          if (isGenerateGroups) {
+            // Replase Group shapes by modified ones.
+            Standard_Integer iGrp;
+
+            // For each group.
+            for (iGrp = 0; iGrp < 5; ++iGrp) {
+              Standard_Integer j;
+
+              // For each sub-shape of pipe
+              for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
+                const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
+
+                if (aSewing->IsModifiedSubShape(aGrpShape)) {
+                  // Use the shape modified by sewing.
+                  const TopoDS_Shape &aModifGrpShape =
+                    aSewing->ModifiedSubShape(aGrpShape);
+
+                  aGroups[iGrp].Append(aModifGrpShape);
+                } else {
+                  // Use the shape as it is.
+                  aGroups[iGrp].Append(aGrpShape);
+                }
+              }
+            }
+          }
         }
       }
+    }
+  }
+
+  if (isGenerateGroups) {
+    // Fill the groups.
+    Handle(TColStd_HArray1OfInteger) aGroupIds[5];
+    TopTools_IndexedMapOfShape       anIndices;
+
+    TopExp::MapShapes(aComp, anIndices);
 
+    if (!FillGroups(aGroups, anIndices, aGroupIds)) {
+      if (aCI) delete aCI;
+      Standard_ConstructionError::Raise("Generate groups failure");
     }
+
+    StoreGroups(aCI, aGroupIds);
   }
 
-  //BRepTools::Write(aComp,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
   return aComp;
 }
 
@@ -1842,6 +1913,7 @@ static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
   Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
   // vertex for recognition
   Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations();
+  Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
 
   Standard_Integer nbBases = aBasesObjs->Length(),
     nbv = (VObjs.IsNull() ? 0 :VObjs->Length());
@@ -1851,6 +1923,7 @@ static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
     Standard_ConstructionError::Raise("Number of shapes for recognition is invalid");
   }
 
+  TopTools_SequenceOfShape aGroups[5];
   TopTools_SequenceOfShape SecVs,Bases;
   for (i=1; i<=nbBases; i++) {
     // vertex
@@ -1902,8 +1975,23 @@ static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
     }
 
     TopTools_MapOfShape aFaces1,aFaces2;
+    TopTools_MapOfShape aBndEdges1;
+
     for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
-      aFaces1.Add(anExp.Current());
+      const TopoDS_Shape &aBaseFace1 = anExp.Current();
+
+      if (aFaces1.Add(aBaseFace1)) {
+        // Get boundary edges.
+        TopExp_Explorer anExpE(aBaseFace1, TopAbs_EDGE);
+
+        for (; anExpE.More(); anExpE.Next()) {
+          const TopoDS_Shape &aBaseEdge1 = anExpE.Current();
+
+          if (!aBndEdges1.Add(aBaseEdge1)) {
+            aBndEdges1.Remove(aBaseEdge1);
+          }
+        }
+      }
     }
     for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
       aFaces2.Add(anExp.Current());
@@ -1991,6 +2079,8 @@ static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
 
       TopExp_Explorer anExpE(F1,TopAbs_EDGE);
       TopTools_SequenceOfShape aNewFs;
+      TopTools_SequenceOfShape aLocalGroups[5];
+
       //int nbee=0;
       for (; anExpE.More(); anExpE.Next()) {
         TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current());
@@ -2071,8 +2161,6 @@ static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
         B.Add(W,E2);
         B.Add(W,E3);
         B.Add(W,E4.Reversed());
-        //cout<<"      wire for edge "<<nbee<<" is created"<<endl;
-        //BRepTools::Write(W,"/dn02/users_Linux/skl/work/Bugs/14857/w.brep");
 
         // make surface
 
@@ -2114,13 +2202,6 @@ static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
           GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1);
         if (CE4->Degree()<3)
           CE4->IncreaseDegree(3);
-        //cout<<"CE1->Degree()="<<CE1->Degree()<<" CE2->Degree()="<<CE2->Degree()
-        //    <<" CE3->Degree()="<<CE3->Degree()<<" CE4->Degree()="<<CE4->Degree()<<endl;
-        //if (fic.open("/dn02/users_Linux/skl/work/Bugs/14857/ce1.brep",ios::out)) {
-        //  os<<"DrawTrSurf_BSplineCurve"<<endl;
-        //  GeomTools::Write(CE1,os);
-        //  fic.close();
-        //}
 
         Handle(Geom_Surface) BS;
         try {
@@ -2218,8 +2299,13 @@ static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
         TopoDS_Face FixedFace = sff->Face();
         aNewFs.Append(FixedFace);
         VPE.Add(E1,FixedFace);
-        //cout<<"      face for edge "<<nbee<<" is created"<<endl;
-        //BRepTools::Write(FixedFace,"/dn02/users_Linux/skl/work/Bugs/14857/f.brep");
+
+        if (isGenerateGroups) {
+          if (aBndEdges1.Contains(E1)) {
+            // This is a boundary face.
+            aLocalGroups[GROUP_OTHER].Append(FixedFace);
+          }
+        }
       }
       // make shell
       TopoDS_Shell aShell;
@@ -2230,6 +2316,15 @@ static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
       B.Add(aShell,F1);
       B.Add(aShell,F2);
 
+      // Create groups.
+      if (isGenerateGroups && i == 1) {
+        aLocalGroups[GROUP_DOWN].Append(F1);
+      }
+
+      if (isGenerateGroups && i == nbBases - 1) {
+        aLocalGroups[GROUP_UP].Append(F2);
+      }
+
       // make sewing for this shell
       Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
       aSewing->SetTolerance(Precision::Confusion());
@@ -2242,7 +2337,6 @@ static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
       aSewing->Perform();
       MESSAGE ("    shell for face "<<nbff<<" is created");
       const TopoDS_Shape aSewShape = aSewing->SewedShape();
-      //BRepTools::Write(aSewShape,"/dn02/users_Linux/skl/work/Bugs/14857/sew.brep");
       if (aSewShape.ShapeType() == TopAbs_SHELL) {
         aShell = TopoDS::Shell(aSewShape);
         GProp_GProps aSystem;
@@ -2267,32 +2361,48 @@ static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
         B.Add(aComp,aShell);
         MESSAGE ("    solid for face "<<nbff<<" is not created");
       }
-      //cout<<"    solid for face "<<nbff<<" is created"<<endl;
 
-      //Handle(ShapeFix_Shell) sfs = new ShapeFix_Shell(aShell);
-      //sfs->Perform();
-      //TopoDS_Shell FixedShell = sfs->Shell();
-      /*
-      GProp_GProps aSystem;
-      BRepGProp::VolumeProperties(FixedShell, aSystem);
-      if (aSystem.Mass()<0) {
-        //cout<<"aSewShape is reversed"<<endl;
-        FixedShell.Reverse();
-      }
-      if (BRep_Tool::IsClosed(FixedShell)) {
-        TopoDS_Solid aSolid;
-        B.MakeSolid(aSolid);
-        B.Add(aSolid,aShell);
-        B.Add(aComp,aSolid);
-      }
-      else {
-        B.Add(aComp,FixedShell);
+      if (isGenerateGroups) {
+        Standard_Integer iGrp;
+
+        for (iGrp = 0; iGrp < 5; ++iGrp) {
+          Standard_Integer j;
+
+          // For each sub-shape of pipe
+          for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
+            const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
+
+            if (aSewing->IsModifiedSubShape(aGrpShape)) {
+              // Use the shape modified by sewing.
+              const TopoDS_Shape &aModifGrpShape =
+                aSewing->ModifiedSubShape(aGrpShape);
+
+              aGroups[iGrp].Append(aModifGrpShape);
+            } else {
+              // Use the shape as it is.
+              aGroups[iGrp].Append(aGrpShape);
+            }
+          }
+        }
       }
-      */
     }
   }
 
-  //BRepTools::Write(aComp,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
+  if (isGenerateGroups) {
+    // Fill the groups.
+    Handle(TColStd_HArray1OfInteger) aGroupIds[5];
+    TopTools_IndexedMapOfShape       anIndices;
+
+    TopExp::MapShapes(aComp, anIndices);
+
+    if (!FillGroups(aGroups, anIndices, aGroupIds)) {
+      if (aCI) delete aCI;
+      Standard_ConstructionError::Raise("Generate groups failure");
+    }
+
+    StoreGroups(aCI, aGroupIds);
+  }
+
   return aComp;
 }
 
@@ -2365,9 +2475,397 @@ static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
       PipeBuilder.MakeSolid();
   }
 
+  if (!CreateGroups(PipeBuilder, aCIBN)) {
+    if (aCIBN) delete aCIBN;
+    Standard_ConstructionError::Raise("Generate groups failure");
+  }
+
   return PipeBuilder.Shape();
 }
 
+//=======================================================================
+//function : FillGroups
+//purpose  : auxilary for DoGroups()
+//=======================================================================
+bool FillGroups(const TopTools_SequenceOfShape         *theGroups,
+                const TopTools_IndexedMapOfShape       &theIndices,
+                      Handle(TColStd_HArray1OfInteger) *theGroupIds)
+{
+  Standard_Integer i;
+
+  for (i = 0; i < 5; ++i) {
+    if (!theGroups[i].IsEmpty()) {
+      const Standard_Integer aNbShapes = theGroups[i].Length();
+      Standard_Integer       j;
+
+      theGroupIds[i] = new TColStd_HArray1OfInteger(1, aNbShapes);
+
+      for (j = 1; j <= aNbShapes; ++j) {
+        const TopoDS_Shape     &aShape  = theGroups[i].Value(j);
+        const Standard_Integer  anIndex = theIndices.FindIndex(aShape);
+
+        if (anIndex == 0) {
+          return false;
+        }
+
+        theGroupIds[i]->SetValue(j, anIndex);
+      }
+    }
+  }
+
+  return true;
+}
+
+//=======================================================================
+//function : StoreGroups
+//purpose  : auxilary for CreateGroups()
+//=======================================================================
+void StoreGroups(GEOMImpl_IPipe                   *theCI,
+                 Handle(TColStd_HArray1OfInteger) *theGroups)
+{
+  if (theGroups[GROUP_DOWN].IsNull() == Standard_False) {
+    theCI->SetGroupDown(theGroups[GROUP_DOWN]);
+  }
+
+  if (theGroups[GROUP_UP].IsNull() == Standard_False) {
+    theCI->SetGroupUp(theGroups[GROUP_UP]);
+  }
+
+  if (theGroups[GROUP_SIDE1].IsNull() == Standard_False) {
+    theCI->SetGroupSide1(theGroups[GROUP_SIDE1]);
+  }
+
+  if (theGroups[GROUP_SIDE2].IsNull() == Standard_False) {
+    theCI->SetGroupSide2(theGroups[GROUP_SIDE2]);
+  }
+
+  if (theGroups[GROUP_OTHER].IsNull() == Standard_False) {
+    theCI->SetGroupOther(theGroups[GROUP_OTHER]);
+  }
+}
+
+//=======================================================================
+//function : CreateDownUpGroups
+//purpose  : auxilary for DoGroups()
+//=======================================================================
+static bool CreateDownUpGroups(BRepPrimAPI_MakeSweep    *theSweep,
+                               TopTools_SequenceOfShape *theGroups,
+                               Standard_Boolean         &IsDoSides)
+{
+  const TopoDS_Shape     aDownShape   = theSweep->FirstShape();
+  const TopAbs_ShapeEnum aType        = aDownShape.ShapeType();
+  TopAbs_ShapeEnum       anUpDownType = TopAbs_SHAPE;
+
+  IsDoSides  = Standard_False;
+
+  switch (aType) {
+    case TopAbs_EDGE:
+    case TopAbs_WIRE:
+      anUpDownType = TopAbs_EDGE;
+
+      if (GEOMUtils::IsOpenPath(aDownShape)) {
+        IsDoSides = Standard_True;
+      }
+      break;
+    case TopAbs_FACE:
+    case TopAbs_SHELL:
+      anUpDownType = TopAbs_FACE;
+      break;
+    default:
+      break;
+  }
+
+  if (anUpDownType == TopAbs_SHAPE) {
+    // Invalid Up and Down group type.
+    return false;
+  }
+
+  TopExp_Explorer     anExp(aDownShape, anUpDownType);
+  TopTools_MapOfShape aMapFence;
+
+  // Create Down group.
+  for (; anExp.More(); anExp.Next()) {
+    const TopoDS_Shape &aShape = anExp.Current();
+
+    if (aMapFence.Add(aShape)) {
+      theGroups[GROUP_DOWN].Append(aShape);
+    }
+  }
+
+  // Create Up group
+  const TopoDS_Shape anUpShape = theSweep->LastShape();
+
+  aMapFence.Clear();
+  anExp.Init(anUpShape, anUpDownType);
+
+  for (; anExp.More(); anExp.Next()) {
+    const TopoDS_Shape &aShape = anExp.Current();
+
+    if (aMapFence.Add(aShape)) {
+      theGroups[GROUP_UP].Append(aShape);
+    }
+  }
+
+  return true;
+}
+
+//=======================================================================
+//function : DoGroups
+//purpose  : auxilary for CreateGroups()
+//=======================================================================
+bool DoGroups(BRepOffsetAPI_MakePipeShell &theSweep,
+              TopTools_SequenceOfShape    *theGroups)
+{
+  Standard_Boolean isDoSides = Standard_False;
+
+  if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
+    // Up and Down groups creation failure
+    return false;
+  }
+
+  const TopoDS_Shape aDownShape = theSweep.FirstShape();
+
+  if (isDoSides) {
+    // Create Side1 and Side2 groups.
+    const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
+    TopoDS_Vertex          aV[2];
+    Standard_Integer       i;
+
+    if (aType == TopAbs_EDGE) {
+      TopExp::Vertices(TopoDS::Edge(aDownShape), aV[0], aV[1], Standard_True);
+    } else { // aType == TopAbs_WIRE
+      TopExp::Vertices(TopoDS::Wire(aDownShape), aV[0], aV[1]);
+    }
+
+    for (i = 0; i < 2; ++i) {
+      if (aV[i].IsNull() == Standard_False) {
+        const TopTools_ListOfShape &aLstSide = theSweep.Generated(aV[i]);
+
+        if (!aLstSide.IsEmpty()) {
+          TopTools_ListIteratorOfListOfShape aSideIt(aLstSide);
+          TopTools_MapOfShape                aMapFence;
+          const Standard_Integer             anIdSide =
+                      (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
+
+          for (; aSideIt.More(); aSideIt.Next()) {
+            const TopoDS_Shape &aSideShape = aSideIt.Value();
+
+            if (aSideShape.ShapeType() == TopAbs_EDGE) {
+              if (aMapFence.Add(aSideShape)) {
+                theGroups[anIdSide].Append(aSideShape);
+              }
+            } else {
+              // Only edges can be is Side1 and Side2 groups.
+              return false;
+            }
+          }
+        }
+      }
+    }
+  } else {
+    // Create Other group. Get boudnary edges of the profile.
+    TopTools_MapOfShape aMapBndEdges;
+    TopExp_Explorer     anExp(aDownShape, TopAbs_EDGE);
+
+    for (; anExp.More(); anExp.Next()) {
+      const TopoDS_Shape &anEdge = anExp.Current();
+
+      if (!aMapBndEdges.Add(anEdge)) {
+        aMapBndEdges.Remove(anEdge);
+      }
+    }
+
+    // Fill the map of faces generated from profile's boundary edges.
+    TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
+    TopTools_MapOfShape              aMapFence;
+
+    for (; anIter.More(); anIter.Next()) {
+      const TopTools_ListOfShape &aLstOther = theSweep.Generated(anIter.Key());
+
+      if (!aLstOther.IsEmpty()) {
+        TopTools_ListIteratorOfListOfShape anOtherIt(aLstOther);
+
+        for (; anOtherIt.More(); anOtherIt.Next()) {
+          const TopoDS_Shape &anOtherShape = anOtherIt.Value();
+
+          if (anOtherShape.ShapeType() == TopAbs_FACE) {
+            if (aMapFence.Add(anOtherShape)) {
+              theGroups[GROUP_OTHER].Append(anOtherShape);
+            }
+          } else {
+            // Only faces can be in Other group.
+            return false;
+          }
+        }
+      }
+    }
+  }
+
+  return true;
+}
+
+//=======================================================================
+//function : CreateGroups
+//purpose  : auxilary for Execute()
+//=======================================================================
+bool CreateGroups(BRepOffsetAPI_MakePipeShell &theSweep,
+                  GEOMImpl_IPipe              *theCI)
+{
+  if (!theCI->GetGenerateGroups()) {
+    // Nothing to do.
+    return true;
+  }
+
+  // Make groups.
+  TopTools_SequenceOfShape aGroups[5];
+
+  if (!DoGroups(theSweep, aGroups)) {
+    return false;
+  }
+
+  // Fill the groups.
+  Handle(TColStd_HArray1OfInteger) aGroupIds[5];
+  TopTools_IndexedMapOfShape       anIndices;
+  const TopoDS_Shape               aResult = theSweep.Shape();
+
+  TopExp::MapShapes(aResult, anIndices);
+
+  if (!FillGroups(aGroups, anIndices, aGroupIds)) {
+    return false;
+  }
+
+  // Store groups.
+  StoreGroups(theCI, aGroupIds);
+
+  return true;
+}
+
+//=======================================================================
+//function : DoGroups
+//purpose  : auxilary for CreateGroups()
+//=======================================================================
+static bool DoGroups(const TopoDS_Shape             &theProfile,
+                     const TopoDS_Shape             &thePath,
+                           BRepOffsetAPI_MakePipe   &theSweep,
+                           TopTools_SequenceOfShape *theGroups)
+{
+  Standard_Boolean isDoSides = Standard_False;
+
+  if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
+    // Up and Down groups creation failure
+    return false;
+  }
+
+  if (isDoSides) {
+    // Create Side1 and Side2 groups.
+    const TopAbs_ShapeEnum aType = theProfile.ShapeType();
+    TopoDS_Vertex          aV[2];
+    Standard_Integer       i;
+
+    if (aType == TopAbs_EDGE) {
+      TopExp::Vertices(TopoDS::Edge(theProfile), aV[0], aV[1], Standard_True);
+    } else { // aType == TopAbs_WIRE
+      TopExp::Vertices(TopoDS::Wire(theProfile), aV[0], aV[1]);
+    }
+
+    for (i = 0; i < 2; ++i) {
+      if (aV[i].IsNull() == Standard_False) {
+        TopExp_Explorer        anExpP(thePath, TopAbs_EDGE);
+        TopTools_MapOfShape    aMapFence;
+        const Standard_Integer anIdSide =
+                      (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
+
+        for (; anExpP.More(); anExpP.Next()) {
+          const TopoDS_Shape aSideShape =
+            theSweep.Generated(anExpP.Current(), aV[i]);
+
+          if (aSideShape.ShapeType() == TopAbs_EDGE) {
+            if (aMapFence.Add(aSideShape)) {
+              theGroups[anIdSide].Append(aSideShape);
+            }
+          } else {
+            // Only edges can be is Side1 and Side2 groups.
+            return false;
+          }
+        }
+      }
+    }
+  } else {
+    // Create Other group. Get boudnary edges of the profile.
+    TopTools_MapOfShape aMapBndEdges;
+    TopExp_Explorer     anExp(theProfile, TopAbs_EDGE);
+
+    for (; anExp.More(); anExp.Next()) {
+      const TopoDS_Shape &anEdge = anExp.Current();
+
+      if (!aMapBndEdges.Add(anEdge)) {
+        aMapBndEdges.Remove(anEdge);
+      }
+    }
+
+    TopExp_Explorer        anExpP(thePath, TopAbs_EDGE);
+    TopTools_MapOfShape    aMapFence;
+
+    for (; anExpP.More(); anExpP.Next()) {
+      TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
+
+      for (; anIter.More(); anIter.Next()) {
+        const TopoDS_Shape anOtherShape =
+          theSweep.Generated(anExpP.Current(), anIter.Key());
+
+        if (anOtherShape.ShapeType() == TopAbs_FACE) {
+          if (aMapFence.Add(anOtherShape)) {
+            theGroups[GROUP_OTHER].Append(anOtherShape);
+          }
+        } else {
+          // Only faces can be in Other group.
+          return false;
+        }
+      }
+    }
+  }
+
+  return true;
+}
+
+//=======================================================================
+//function : CreateGroups
+//purpose  : auxilary for Execute()
+//=======================================================================
+static bool CreateGroups(const TopoDS_Shape     &theProfile,
+                         const TopoDS_Shape     &thePath,
+                         BRepOffsetAPI_MakePipe &theSweep,
+                         GEOMImpl_IPipe         *theCI)
+{
+  if (!theCI->GetGenerateGroups()) {
+    // Nothing to do.
+    return true;
+  }
+
+  // Make groups.
+  TopTools_SequenceOfShape aGroups[5];
+
+  if (!DoGroups(theProfile, thePath, theSweep, aGroups)) {
+    return false;
+  }
+
+  // Fill the groups.
+  Handle(TColStd_HArray1OfInteger) aGroupIds[5];
+  TopTools_IndexedMapOfShape       anIndices;
+  const TopoDS_Shape               aResult = theSweep.Shape();
+
+  TopExp::MapShapes(aResult, anIndices);
+
+  if (!FillGroups(aGroups, anIndices, aGroupIds)) {
+    return false;
+  }
+
+  // Store groups.
+  StoreGroups(theCI, aGroupIds);
+
+  return true;
+}
+
 //=======================================================================
 //function : Execute
 //purpose  :
@@ -2434,6 +2932,16 @@ Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
       if (aCI) delete aCI;
       Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
     }
+
+    // Check if it is possible to create groups.
+    if (aCI->GetGenerateGroups() && !GEOMUtils::IsOpenPath(aWirePath)) {
+      if (aCI) {
+        delete aCI;
+      }
+
+      Standard_ConstructionError::Raise
+        ("Can't create groups if the path is closed");
+    }
   }
 
   TopoDS_Shape aShape;
@@ -2481,7 +2989,11 @@ Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
       }
       else
         aShape = Sweep.Shape(); //result is good
-      
+
+      if (!CreateGroups(Sweep, aCI)) {
+        if (aCI) delete aCI;
+        Standard_ConstructionError::Raise("Generate groups failure");
+      }
     }
     else
     {
@@ -2490,6 +3002,11 @@ Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
 
       if (aMkPipe.IsDone()) {
         aShape = aMkPipe.Shape();
+
+        if (!CreateGroups(aShapeBase, aWirePath, aMkPipe, aCI)) {
+          if (aCI) delete aCI;
+          Standard_ConstructionError::Raise("Generate groups failure");
+        }
       } else if (theBestMode != GeomFill_IsDiscreteTrihedron) {
         // Try to use Descrete Trihedron mode.
         BRepOffsetAPI_MakePipe aMkPipeDescrete
@@ -2497,6 +3014,11 @@ Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
 
         if (aMkPipeDescrete.IsDone()) {
           aShape = aMkPipeDescrete.Shape();
+
+          if (!CreateGroups(aShapeBase, aWirePath, aMkPipeDescrete, aCI)) {
+            if (aCI) delete aCI;
+            Standard_ConstructionError::Raise("Generate groups failure");
+          }
         }
       }
     }
@@ -2509,6 +3031,8 @@ Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
     Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations ();
     Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
     Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
+    Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
+
     if (aCI) {
       delete aCI;
       aCI = 0;
@@ -2545,7 +3069,24 @@ Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
       aHSeqLocs->Append(aShapeLoc);
     }
 
-    aShape = CreatePipeWithDifferentSections(aWirePath, aHSeqBases, aHSeqLocs, aWithContact, aWithCorrect);
+
+    Handle(TColStd_HArray1OfInteger) *pGroups = NULL;
+    Handle(TColStd_HArray1OfInteger)  aGroups[5];
+
+    if (isGenerateGroups) {
+      pGroups = aGroups;
+    }
+
+    aShape = CreatePipeWithDifferentSections
+              (aWirePath, aHSeqBases, aHSeqLocs,
+               aWithContact, aWithCorrect, pGroups);
+
+    if (isGenerateGroups) {
+      // Store created groups.
+      GEOMImpl_IPipeDiffSect aPipeDS(aFunction);
+
+      StoreGroups(&aPipeDS, aGroups);
+    }
   }
 
   //building pipe with shell sections
@@ -2563,6 +3104,8 @@ Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
     aShape = CreatePipeBiNormalAlongVector(aWirePath, aCI);
   }
 
+  const Standard_Boolean isGenerateGroups = aCI->GetGenerateGroups();
+
   if (aCI) {
     delete aCI;
     aCI = 0;
@@ -2585,11 +3128,99 @@ Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
           aVertMaxTol = aTol;
       }
       aVertMaxTol += Precision::Confusion();
-      aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, aVertMaxTol, Standard_True);
-      //aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, Precision::Confusion(), Standard_True);
+
+      TopTools_DataMapOfShapeListOfShape  aMapModif;
+      TopTools_DataMapOfShapeListOfShape *pMapModif = NULL;
+
+      if (isGenerateGroups) {
+        pMapModif = &aMapModif;
+      }
+
+      TopoDS_Shape aNewShape = GEOMImpl_GlueDriver::GlueFaces
+        (aShape, aVertMaxTol, Standard_True, pMapModif);
+
+      if (isGenerateGroups && !aMapModif.IsEmpty()) {
+        // Update groups.
+        GEOMImpl_IPipe                   aCI(aFunction);
+        Handle(TColStd_HArray1OfInteger) aGroupIDs[5] =
+          { aCI.GetGroupDown(), aCI.GetGroupUp(), aCI.GetGroupSide1(),
+            aCI.GetGroupSide2(), aCI.GetGroupOther() };
+        TopTools_IndexedMapOfShape       anIndices;
+        TopTools_IndexedMapOfShape       aNewIndices;
+        TopTools_SequenceOfShape         aNewShapes[5];
+        TopTools_MapOfShape              aMapReplaced;
+        TopTools_MapOfShape              aMapGlued;
+        Standard_Integer                 iGrp;
+        Standard_Integer                 i;
+
+        TopExp::MapShapes(aShape,    anIndices);
+        TopExp::MapShapes(aNewShape, aNewIndices);
+
+        for (iGrp = 0; iGrp < 5; ++iGrp) {
+          if (aGroupIDs[iGrp].IsNull() == Standard_False) {
+            const Standard_Integer aLower  = aGroupIDs[iGrp]->Lower();
+            const Standard_Integer anUpper = aGroupIDs[iGrp]->Upper();
+
+            for (i = aLower; i <= anUpper; ++i) {
+              const Standard_Integer  anIndex   = aGroupIDs[iGrp]->Value(i);
+              const TopoDS_Shape     &aSubShape = anIndices.FindKey(anIndex);
+
+              if (aMapModif.IsBound(aSubShape)) {
+                const TopTools_ListOfShape         &aListModif =
+                  aMapModif.Find(aSubShape);
+                TopTools_ListIteratorOfListOfShape  anIter(aListModif);
+
+                for (; anIter.More(); anIter.Next()) {
+                  const TopoDS_Shape &aNewShape = anIter.Value();
+
+                  if (aMapReplaced.Add(aNewShape)) {
+                    aNewShapes[iGrp].Append(aNewShape);
+                  } else {
+                    // This is a glued shape. It means that it is internal
+                    // one and should be removed from groups later.
+                    aMapGlued.Add(aNewShape);
+                  }
+                }
+              } else {
+                // Shape is not modified.
+                aNewShapes[iGrp].Append(aSubShape);
+              }
+            }
+          }
+        }
+
+        if (!aMapGlued.IsEmpty()) {
+          // Remove glued (internal) shapes from groups.
+          for (iGrp = 0; iGrp < 5; ++iGrp) {
+            Standard_Integer aNbShapes = aNewShapes[iGrp].Length();
+
+            for (i = 1; i < aNbShapes; ++i) {
+              const TopoDS_Shape &aNewShape = aNewShapes[iGrp].Value(i);
+
+              if (aMapGlued.Contains(aNewShape)) {
+                aNewShapes[iGrp].Remove(i);
+                --i;
+                --aNbShapes;
+              }
+            }
+          }
+        }
+
+        // Store modified groups.
+        Handle(TColStd_HArray1OfInteger) aNewGroupIDs[5];
+
+        if (!FillGroups(aNewShapes, aNewIndices, aNewGroupIDs)) {
+          Standard_ConstructionError::Raise("Generate groups failure");
+        }
+
+        StoreGroups(&aCI, aNewGroupIDs);
+      }
+
+      aShape = aNewShape;
     }
   }
 
+  // Note: group indices should not be changed after the next call.
   TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape);
   aFunction->SetValue(aRes);
 
index ef69fd7ba3b7dfb7de5a7743fb0cfe7dc3adda1d..3a4deca6feed0c44274f19ca92fc2dc5a34a5a3f 100644 (file)
@@ -83,11 +83,12 @@ public:
   Standard_EXPORT ~GEOMImpl_PipeDriver() {};
 
   Standard_EXPORT static TopoDS_Shape CreatePipeWithDifferentSections
-                                     (const TopoDS_Wire& theWirePath,
-                                      const Handle(TopTools_HSequenceOfShape) theBases,
-                                      const Handle(TopTools_HSequenceOfShape) theLocs,
-                                      const Standard_Boolean theWithContact,
-                                      const Standard_Boolean theWithCorrect);
+                  (const TopoDS_Wire                       &theWirePath,
+                   const Handle(TopTools_HSequenceOfShape)  theBases,
+                   const Handle(TopTools_HSequenceOfShape)  theLocs,
+                   const Standard_Boolean                   theWithContact,
+                   const Standard_Boolean                   theWithCorrect,
+                         Handle(TColStd_HArray1OfInteger)  *theGroups = NULL);
 
   Standard_EXPORT virtual
   bool GetCreationInformation(std::string&             theOperationName,
index 9b7ca2d970de5f23e4ee4db05819d217ab8de3ed..3e0b18977de279e5b07a1e1e15efad56bcf371f2 100644 (file)
@@ -1236,3 +1236,54 @@ double GEOMUtils::DefaultDeflection()
 {
   return 0.001;
 }
+
+//=======================================================================
+//function : IsOpenPath
+//purpose  : 
+//=======================================================================
+bool GEOMUtils::IsOpenPath(const TopoDS_Shape &theShape)
+{
+  bool isOpen = true;
+
+  if (theShape.IsNull() == Standard_False) {
+    if (theShape.Closed()) {
+      // The shape is closed
+      isOpen = false;
+    } else {
+      const TopAbs_ShapeEnum aType = theShape.ShapeType();
+
+      if (aType == TopAbs_EDGE || aType == TopAbs_WIRE) {
+        // Check if path ends are coinsident.
+        TopoDS_Vertex aV[2];
+
+        if (aType == TopAbs_EDGE) {
+          // Edge
+          TopExp::Vertices(TopoDS::Edge(theShape), aV[0], aV[1]);
+        } else {
+          // Wire
+          TopExp::Vertices(TopoDS::Wire(theShape), aV[0], aV[1]);
+        }
+
+        if (aV[0].IsNull() == Standard_False &&
+            aV[1].IsNull() == Standard_False) {
+          if (aV[0].IsSame(aV[1])) {
+            // The shape is closed
+            isOpen = false;
+          } else {
+            const Standard_Real aTol1 = BRep_Tool::Tolerance(aV[0]);
+            const Standard_Real aTol2 = BRep_Tool::Tolerance(aV[1]);
+            const gp_Pnt        aPnt1 = BRep_Tool::Pnt(aV[0]);
+            const gp_Pnt        aPnt2 = BRep_Tool::Pnt(aV[1]);
+
+            if (aPnt1.Distance(aPnt2) <= aTol1 + aTol2) {
+              // The shape is closed
+              isOpen = false;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  return isOpen;
+}
index d8a8399407cfa7946ea475c79f2374ed51d21923..8ffa25be2e10bb75ad3e2e2b9ed592c14d4b542d 100644 (file)
@@ -328,6 +328,19 @@ namespace GEOMUtils
    * \return default deflection value
    */
   Standard_EXPORT double DefaultDeflection();
+
+  /**
+   * \brief Check if the shape is not a closed wire or edge.
+   *
+   * This function is used for pipe creation algorithm to test if
+   * the pipe path is not closed. It returns false if theShape is a wire or
+   * an edge with coincident end vertices. Otherwise it returns true.
+   *
+   * \param theShape the shape to be tested.
+   * \return true if theShape is not a closed wire or edge.
+   */
+  Standard_EXPORT bool IsOpenPath(const TopoDS_Shape &theShape);
+
 };
 
 #endif
index 66e4b809f75920b2a279b972350ff5fb160fe5f6..3d5969f71571ec7c954cdfb0fc6ce5204e2cb123 100644 (file)
@@ -794,10 +794,12 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakeDraftPrism
  *  MakePipe
  */
 //=============================================================================
-GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipe
-                 (GEOM::GEOM_Object_ptr theBase, GEOM::GEOM_Object_ptr thePath)
+GEOM::ListOfGO *GEOM_I3DPrimOperations_i::MakePipe
+                           (GEOM::GEOM_Object_ptr theBase,
+                            GEOM::GEOM_Object_ptr thePath,
+                            CORBA::Boolean        IsGenerateGroups)
 {
-  GEOM::GEOM_Object_var aGEOMObject;
+  GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
 
   //Set a not done flag
   GetOperations()->SetNotDone();
@@ -806,15 +808,20 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipe
   Handle(GEOM_Object) aBase = GetObjectImpl(theBase);
   Handle(GEOM_Object) aPath = GetObjectImpl(thePath);
 
-  if (aBase.IsNull() || aPath.IsNull()) return aGEOMObject._retn();
+  if (aBase.IsNull() || aPath.IsNull()) return aSeq._retn();
 
   //Create the Pipe
-  Handle(GEOM_Object) anObject =
-    GetOperations()->MakePipe(aBase, aPath);
-  if (!GetOperations()->IsDone() || anObject.IsNull())
-    return aGEOMObject._retn();
+  Handle(TColStd_HSequenceOfTransient) aHSeq =
+    GetOperations()->MakePipe(aBase, aPath, IsGenerateGroups);
+  if (!GetOperations()->IsDone() || aHSeq.IsNull())
+    return aSeq._retn();
 
-  return GetObject(anObject);
+  Standard_Integer aLength = aHSeq->Length();
+  aSeq->length(aLength);
+  for (Standard_Integer i = 1; i <= aLength; i++)
+    aSeq[i-1] = GetObject(Handle(GEOM_Object)::DownCast(aHSeq->Value(i)));
+
+  return aSeq._retn();
 }
 
 //=============================================================================
@@ -974,14 +981,15 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakeThruSections(const GEOM::Lis
  *  MakePipeWithDifferentSections
  */
 //=============================================================================
-GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeWithDifferentSections
-                      (const GEOM::ListOfGO& theBases,
-                       const GEOM::ListOfGO& theLocations,
-                       GEOM::GEOM_Object_ptr thePath,
-                       CORBA::Boolean theWithContact,
-                       CORBA::Boolean theWithCorrections)
+GEOM::ListOfGO *GEOM_I3DPrimOperations_i::MakePipeWithDifferentSections
+                           (const GEOM::ListOfGO        &theBases,
+                            const GEOM::ListOfGO        &theLocations,
+                                  GEOM::GEOM_Object_ptr  thePath,
+                                  CORBA::Boolean         theWithContact,
+                                  CORBA::Boolean         theWithCorrections,
+                                  CORBA::Boolean         IsGenerateGroups)
 {
-  GEOM::GEOM_Object_var aGEOMObject;
+  GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
 
   //Set a not done flag
   GetOperations()->SetNotDone();
@@ -994,11 +1002,11 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeWithDifferentSections
   aNbLocs = theLocations.length();
 
   if (aNbLocs && aNbBases != aNbLocs)
-    return aGEOMObject._retn();
+    return aSeq._retn();
 
   Handle(GEOM_Object) aPath = GetObjectImpl(thePath);
   if (aPath.IsNull())
-    return aGEOMObject._retn();
+    return aSeq._retn();
 
   for (ind = 0; ind < aNbBases; ind++) {
     Handle(GEOM_Object) aBase = GetObjectImpl(theBases[ind]);
@@ -1014,16 +1022,23 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeWithDifferentSections
     aSeqBases->Append(aBase);
   }
   if (!aSeqBases->Length())
-    return aGEOMObject._retn();
+    return aSeq._retn();
 
   // Make pipe
-  Handle(GEOM_Object) anObject =
-    GetOperations()->MakePipeWithDifferentSections(aSeqBases,aSeqLocations ,aPath,
-                                                   theWithContact,theWithCorrections);
-  if (!GetOperations()->IsDone() || anObject.IsNull())
-    return aGEOMObject._retn();
-
-  return GetObject(anObject);
+  Handle(TColStd_HSequenceOfTransient) aHSeq =
+    GetOperations()->MakePipeWithDifferentSections
+              (aSeqBases, aSeqLocations,
+               aPath, theWithContact,
+               theWithCorrections, IsGenerateGroups);
+  if (!GetOperations()->IsDone() || aHSeq.IsNull())
+    return aSeq._retn();
+
+  Standard_Integer aLength = aHSeq->Length();
+  aSeq->length(aLength);
+  for (Standard_Integer i = 1; i <= aLength; i++)
+    aSeq[i-1] = GetObject(Handle(GEOM_Object)::DownCast(aHSeq->Value(i)));
+
+  return aSeq._retn();
 }
 
 
@@ -1032,15 +1047,16 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeWithDifferentSections
  *  MakePipeWithShellSections
  */
 //=============================================================================
-GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeWithShellSections
-                 (const GEOM::ListOfGO& theBases,
-                  const GEOM::ListOfGO& theSubBases,
-                  const GEOM::ListOfGO& theLocations,
-                  GEOM::GEOM_Object_ptr thePath,
-                  CORBA::Boolean theWithContact,
-                  CORBA::Boolean theWithCorrections)
+GEOM::ListOfGO *GEOM_I3DPrimOperations_i::MakePipeWithShellSections
+                           (const GEOM::ListOfGO        &theBases,
+                            const GEOM::ListOfGO        &theSubBases,
+                            const GEOM::ListOfGO        &theLocations,
+                                  GEOM::GEOM_Object_ptr  thePath,
+                                  CORBA::Boolean         theWithContact,
+                                  CORBA::Boolean         theWithCorrections,
+                                  CORBA::Boolean         IsGenerateGroups)
 {
-  GEOM::GEOM_Object_var aGEOMObject;
+  GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
 
   //Set a not done flag
   GetOperations()->SetNotDone();
@@ -1055,11 +1071,11 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeWithShellSections
   aNbLocs = theLocations.length();
 
   if (aNbLocs && aNbBases != aNbLocs)
-    return aGEOMObject._retn();
+    return aSeq._retn();
 
   Handle(GEOM_Object) aPath = GetObjectImpl(thePath);
   if (aPath.IsNull())
-    return aGEOMObject._retn();
+    return aSeq._retn();
 
   for (ind = 0; ind < aNbBases; ind++) {
     Handle(GEOM_Object) aBase = GetObjectImpl(theBases[ind]);
@@ -1084,17 +1100,23 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeWithShellSections
     }
   }
   if (!aSeqBases->Length())
-    return aGEOMObject._retn();
+    return aSeq._retn();
 
   // Make pipe
-  Handle(GEOM_Object) anObject =
-    GetOperations()->MakePipeWithShellSections(aSeqBases, aSeqSubBases,
-                                               aSeqLocations, aPath,
-                                               theWithContact, theWithCorrections);
-  if (!GetOperations()->IsDone() || anObject.IsNull())
-    return aGEOMObject._retn();
-
-  return GetObject(anObject);
+  Handle(TColStd_HSequenceOfTransient) aHSeq =
+    GetOperations()->MakePipeWithShellSections
+                  (aSeqBases, aSeqSubBases,
+                   aSeqLocations, aPath,
+                   theWithContact, theWithCorrections, IsGenerateGroups);
+  if (!GetOperations()->IsDone() || aHSeq.IsNull())
+    return aSeq._retn();
+
+  Standard_Integer aLength = aHSeq->Length();
+  aSeq->length(aLength);
+  for (Standard_Integer i = 1; i <= aLength; i++)
+    aSeq[i-1] = GetObject(Handle(GEOM_Object)::DownCast(aHSeq->Value(i)));
+
+  return aSeq._retn();
 }
 
 
@@ -1103,11 +1125,12 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeWithShellSections
  *  MakePipeShellsWithoutPath
  */
 //=============================================================================
-GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeShellsWithoutPath
-                 (const GEOM::ListOfGO& theBases,
-                  const GEOM::ListOfGO& theLocations)
+GEOM::ListOfGO *GEOM_I3DPrimOperations_i::MakePipeShellsWithoutPath
+                           (const GEOM::ListOfGO &theBases,
+                            const GEOM::ListOfGO &theLocations,
+                                  CORBA::Boolean  IsGenerateGroups)
 {
-  GEOM::GEOM_Object_var aGEOMObject;
+  GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
 
   //Set a not done flag
   GetOperations()->SetNotDone();
@@ -1120,7 +1143,7 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeShellsWithoutPath
   aNbLocs = theLocations.length();
 
   if (aNbLocs && aNbBases != aNbLocs)
-    return aGEOMObject._retn();
+    return aSeq._retn();
 
   for (ind = 0; ind < aNbBases; ind++) {
     Handle(GEOM_Object) aBase = GetObjectImpl(theBases[ind]);
@@ -1136,16 +1159,22 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeShellsWithoutPath
   }
 
   if (!aSeqBases->Length())
-    return aGEOMObject._retn();
+    return aSeq._retn();
 
   // Make pipe
-  Handle(GEOM_Object) anObject =
-    GetOperations()->MakePipeShellsWithoutPath(aSeqBases,aSeqLocations);
+  Handle(TColStd_HSequenceOfTransient) aHSeq =
+    GetOperations()->MakePipeShellsWithoutPath
+          (aSeqBases, aSeqLocations, IsGenerateGroups);
 
-  if (!GetOperations()->IsDone() || anObject.IsNull())
-    return aGEOMObject._retn();
+  if (!GetOperations()->IsDone() || aHSeq.IsNull())
+    return aSeq._retn();
 
-  return GetObject(anObject);
+  Standard_Integer aLength = aHSeq->Length();
+  aSeq->length(aLength);
+  for (Standard_Integer i = 1; i <= aLength; i++)
+    aSeq[i-1] = GetObject(Handle(GEOM_Object)::DownCast(aHSeq->Value(i)));
+
+  return aSeq._retn();
 }
 
 //=============================================================================
@@ -1153,12 +1182,13 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeShellsWithoutPath
  *  MakePipeBiNormalAlongVector
  */
 //=============================================================================
-GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeBiNormalAlongVector
-                 (GEOM::GEOM_Object_ptr theBase,
-                  GEOM::GEOM_Object_ptr thePath,
-                  GEOM::GEOM_Object_ptr theVec)
+GEOM::ListOfGO *GEOM_I3DPrimOperations_i::MakePipeBiNormalAlongVector
+                           (GEOM::GEOM_Object_ptr theBase,
+                            GEOM::GEOM_Object_ptr thePath,
+                            GEOM::GEOM_Object_ptr theVec,
+                            CORBA::Boolean        IsGenerateGroups)
 {
-  GEOM::GEOM_Object_var aGEOMObject;
+  GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
 
   //Set a not done flag
   GetOperations()->SetNotDone();
@@ -1168,15 +1198,21 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeBiNormalAlongVector
   Handle(GEOM_Object) aPath = GetObjectImpl(thePath);
   Handle(GEOM_Object) aVec = GetObjectImpl(theVec);
 
-  if (aBase.IsNull() || aPath.IsNull() || aVec.IsNull()) return aGEOMObject._retn();
+  if (aBase.IsNull() || aPath.IsNull() || aVec.IsNull()) return aSeq._retn();
 
   //Create the Pipe
-  Handle(GEOM_Object) anObject =
-    GetOperations()->MakePipeBiNormalAlongVector(aBase, aPath, aVec);
-  if (!GetOperations()->IsDone() || anObject.IsNull())
-    return aGEOMObject._retn();
-
-  return GetObject(anObject);
+  Handle(TColStd_HSequenceOfTransient) aHSeq =
+    GetOperations()->MakePipeBiNormalAlongVector
+          (aBase, aPath, aVec, IsGenerateGroups);
+  if (!GetOperations()->IsDone() || aHSeq.IsNull())
+    return aSeq._retn();
+
+  Standard_Integer aLength = aHSeq->Length();
+  aSeq->length(aLength);
+  for (Standard_Integer i = 1; i <= aLength; i++)
+    aSeq[i-1] = GetObject(Handle(GEOM_Object)::DownCast(aHSeq->Value(i)));
+
+  return aSeq._retn();
 }
 
 //=============================================================================
index 733e62833bd7a2c4cfa87950843f0d9d32136492..d5d8ea84793a7c247cc8304019dc9398b880c9ed 100644 (file)
@@ -155,9 +155,10 @@ class GEOM_I_EXPORT GEOM_I3DPrimOperations_i :
                                         CORBA::Double         theAngle,
                                         CORBA::Boolean        theFuse,
                                         CORBA::Boolean        theInvert);
-                            
-  GEOM::GEOM_Object_ptr MakePipe (GEOM::GEOM_Object_ptr theBase,
-                                 GEOM::GEOM_Object_ptr thePath);
+
+  GEOM::ListOfGO* MakePipe (GEOM::GEOM_Object_ptr theBase,
+                            GEOM::GEOM_Object_ptr thePath,
+                            CORBA::Boolean        IsGenerateGroups);
 
   GEOM::GEOM_Object_ptr MakeRevolutionAxisAngle (GEOM::GEOM_Object_ptr theBase,
                                                 GEOM::GEOM_Object_ptr theAxis,
@@ -178,27 +179,35 @@ class GEOM_I_EXPORT GEOM_I3DPrimOperations_i :
                                         CORBA::Boolean theModeSolid,
                                         CORBA::Double thePreci,
                                         CORBA::Boolean theRuled);
-  
-  GEOM::GEOM_Object_ptr MakePipeWithDifferentSections(const GEOM::ListOfGO& theBases,
-                                                     const GEOM::ListOfGO& theLocations,
-                                                     GEOM::GEOM_Object_ptr thePath,
-                                                     CORBA::Boolean theWithContact,
-                                                     CORBA::Boolean theWithCorrections);
-
-  GEOM::GEOM_Object_ptr MakePipeWithShellSections(const GEOM::ListOfGO& theBases,
-                                                 const GEOM::ListOfGO& theSubBases,
-                                                 const GEOM::ListOfGO& theLocations,
-                                                 GEOM::GEOM_Object_ptr thePath,
-                                                 CORBA::Boolean theWithContact,
-                                                 CORBA::Boolean theWithCorrections);
-
-  GEOM::GEOM_Object_ptr MakePipeShellsWithoutPath(const GEOM::ListOfGO& theBases,
-                                                 const GEOM::ListOfGO& theLocations);
-
-  GEOM::GEOM_Object_ptr MakePipeBiNormalAlongVector (GEOM::GEOM_Object_ptr theBase,
-                                                    GEOM::GEOM_Object_ptr thePath,
-                                                    GEOM::GEOM_Object_ptr theVec);
-  
+
+  GEOM::ListOfGO* MakePipeWithDifferentSections
+                           (const GEOM::ListOfGO        &theBases,
+                            const GEOM::ListOfGO        &theLocations,
+                                  GEOM::GEOM_Object_ptr  thePath,
+                                  CORBA::Boolean         theWithContact,
+                                  CORBA::Boolean         theWithCorrections,
+                                  CORBA::Boolean         IsGenerateGroups);
+
+  GEOM::ListOfGO* MakePipeWithShellSections
+                           (const GEOM::ListOfGO        &theBases,
+                            const GEOM::ListOfGO        &theSubBases,
+                            const GEOM::ListOfGO        &theLocations,
+                                  GEOM::GEOM_Object_ptr  thePath,
+                                  CORBA::Boolean         theWithContact,
+                                  CORBA::Boolean         theWithCorrections,
+                                  CORBA::Boolean         IsGenerateGroups);
+
+  GEOM::ListOfGO* MakePipeShellsWithoutPath
+                           (const GEOM::ListOfGO &theBases,
+                            const GEOM::ListOfGO &theLocations,
+                                  CORBA::Boolean  IsGenerateGroups);
+
+  GEOM::ListOfGO* MakePipeBiNormalAlongVector
+                           (GEOM::GEOM_Object_ptr theBase,
+                            GEOM::GEOM_Object_ptr thePath,
+                            GEOM::GEOM_Object_ptr theVec,
+                            CORBA::Boolean        IsGenerateGroups);
+
   GEOM::GEOM_Object_ptr MakeThickening (GEOM::GEOM_Object_ptr   theObject,
                                         const GEOM::ListOfLong &theFacesIDs,
                                         CORBA::Double           theOffset,
index 2108c89b8f0921c662a3a2dd7222c6145f69bb75..8501474d80e79a0d858b3e47d9717ea648e2be75 100644 (file)
@@ -1403,9 +1403,9 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::MakePipe (GEOM::GEOM_Object_ptr theBase,
   beginService( " GEOM_Superv_i::MakePipe" );
   MESSAGE("GEOM_Superv_i::MakePipe");
   get3DPrimOp();
-  GEOM::GEOM_Object_ptr anObj = my3DPrimOp->MakePipe(theBase, thePath);
+  GEOM::ListOfGO_var aList = my3DPrimOp->MakePipe(theBase, thePath, false);
   endService( " GEOM_Superv_i::MakePipe" );
-  return anObj;
+  return aList[0];
 }
 
 //=============================================================================
@@ -1512,9 +1512,9 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::MakePipeWithDifferentSections
   beginService( " GEOM_Superv_i::MakePipeWithDifferentSections" );
   MESSAGE("GEOM_Superv_i::MakePipeWithDifferentSections");
   get3DPrimOp();
-  GEOM::GEOM_Object_ptr anObj = my3DPrimOp->MakePipeWithDifferentSections(theBases,theLocations, thePath,theWithContact,theWithCorrections);
+  GEOM::ListOfGO_var aList = my3DPrimOp->MakePipeWithDifferentSections(theBases,theLocations, thePath,theWithContact,theWithCorrections, false);
   endService( " GEOM_Superv_i::MakePipeWithDifferentSections" );
-  return anObj;
+  return aList[0];
 }
 
 
@@ -1532,12 +1532,13 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::MakePipeWithShellSections
   beginService( " GEOM_Superv_i::MakePipeWithShellSections" );
   MESSAGE("GEOM_Superv_i::MakePipeWithShellSections");
   get3DPrimOp();
-  GEOM::GEOM_Object_ptr anObj =
+  GEOM::ListOfGO_var aList =
     my3DPrimOp->MakePipeWithShellSections(theBases, theSubBases,
                                           theLocations, thePath,
-                                          theWithContact, theWithCorrections);
+                                          theWithContact, theWithCorrections,
+                                          false);
   endService( " GEOM_Superv_i::MakePipeWithShellSections" );
-  return anObj;
+  return aList[0];
 }
 
 
@@ -1551,10 +1552,10 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::MakePipeShellsWithoutPath
   beginService( " GEOM_Superv_i::MakePipeShellsWithoutPath" );
   MESSAGE("GEOM_Superv_i::MakePipeShellsWithoutPath");
   get3DPrimOp();
-  GEOM::GEOM_Object_ptr anObj =
-    my3DPrimOp->MakePipeShellsWithoutPath(theBases,theLocations);
+  GEOM::ListOfGO_var aList =
+    my3DPrimOp->MakePipeShellsWithoutPath(theBases,theLocations, false);
   endService( " GEOM_Superv_i::MakePipeShellsWithoutPath" );
-  return anObj;
+  return aList[0];
 }
 
 
@@ -1569,10 +1570,10 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::MakePipeBiNormalAlongVector
   beginService( " GEOM_Superv_i::MakePipeBiNormalAlongVector" );
   MESSAGE("GEOM_Superv_i::MakePipeBiNormalAlongVector");
   get3DPrimOp();
-  GEOM::GEOM_Object_ptr anObj =
-    my3DPrimOp->MakePipeBiNormalAlongVector(theBase, thePath, theVec);
+  GEOM::ListOfGO_var aList =
+    my3DPrimOp->MakePipeBiNormalAlongVector(theBase, thePath, theVec, false);
   endService( " GEOM_Superv_i::MakePipeBiNormalAlongVector" );
-  return anObj;
+  return aList[0];
 }
 
 
index fabb95341a9d00540ae4da746c91fd3ac2232fd6..e2bf0b10bd64ea33019a383e1c9d41a166f6aa13 100644 (file)
@@ -3869,41 +3869,97 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
             return anObj
 
         ## Create a shape by extrusion of the base shape along
-        #  the path shape. The path shape can be a wire or an edge.
+        #  the path shape. The path shape can be a wire or an edge. It is
+        #  possible to generate groups along with the result by means of
+        #  setting the flag \a IsGenerateGroups.<BR>
+        #  If \a thePath is a closed edge or wire and \a IsGenerateGroups is
+        #  set, an error is occured. If \a thePath is not closed edge/wire,
+        #  the following groups are returned:
+        #  - If \a theBase is unclosed edge or wire: "Down", "Up", "Side1",
+        #    "Side2";
+        #  - If \a theBase is closed edge or wire, face or shell: "Down", "Up",
+        #    "Other".
+        #  .
+        #  "Down" and "Up" groups contain:
+        #  - Edges if \a theBase is edge or wire;
+        #  - Faces if \a theBase is face or shell.<BR>
+        #  .
+        #  "Side1" and "Side2" groups contain edges generated from the first
+        #  and last vertices of \a theBase. The first and last vertices are
+        #  determined taking into account edge/wire orientation.<BR>
+        #  "Other" group represents faces generated from the bounding edges of
+        #  \a theBase.
+        #
         #  @param theBase Base shape to be extruded.
         #  @param thePath Path shape to extrude the base shape along it.
+        #  @param IsGenerateGroups flag that tells if it is necessary to
+        #         create groups. It is equal to False by default.
         #  @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 the created pipe.
+        #  @return New GEOM.GEOM_Object, containing the created pipe if 
+        #          \a IsGenerateGroups is not set. Otherwise it returns new
+        #          GEOM.ListOfGO. Its first element is the created pipe, the
+        #          remaining ones are created groups.
         #
         #  @ref tui_creation_pipe "Example"
         @ManageTransactions("PrimOp")
-        def MakePipe(self, theBase, thePath, theName=None):
+        def MakePipe(self, theBase, thePath,
+                     IsGenerateGroups=False, theName=None):
             """
             Create a shape by extrusion of the base shape along
-            the path shape. The path shape can be a wire or an edge.
+            the path shape. The path shape can be a wire or an edge. It is
+            possible to generate groups along with the result by means of
+            setting the flag IsGenerateGroups.
+            If thePath is a closed edge or wire and IsGenerateGroups is
+            set, an error is occured. If thePath is not closed edge/wire,
+            the following groups are returned:
+            - If theBase is unclosed edge or wire: "Down", "Up", "Side1",
+              "Side2";
+            - If theBase is closed edge or wire, face or shell: "Down", "Up",
+              "Other".
+            "Down" and "Up" groups contain:
+            - Edges if theBase is edge or wire;
+            - Faces if theBase is face or shell.
+            "Side1" and "Side2" groups contain edges generated from the first
+            and last vertices of theBase. The first and last vertices are
+            determined taking into account edge/wire orientation.
+            "Other" group represents faces generated from the bounding edges of
+            theBase.
 
             Parameters:
                 theBase Base shape to be extruded.
                 thePath Path shape to extrude the base shape along it.
+                IsGenerateGroups flag that tells if it is necessary to
+                        create groups. It is equal to False by default.
                 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 the created pipe.
+                New GEOM.GEOM_Object, containing the created pipe if 
+                IsGenerateGroups is not set. Otherwise it returns new
+                GEOM.ListOfGO. Its first element is the created pipe, the
+                remaining ones are created groups.
             """
             # Example: see GEOM_TestAll.py
-            anObj = self.PrimOp.MakePipe(theBase, thePath)
+            aList = self.PrimOp.MakePipe(theBase, thePath, IsGenerateGroups)
             RaiseIfFailed("MakePipe", self.PrimOp)
-            self._autoPublish(anObj, theName, "pipe")
-            return anObj
+
+            if IsGenerateGroups:
+              self._autoPublish(aList, theName, "pipe")
+              return aList
+
+            self._autoPublish(aList[0], theName, "pipe")
+            return aList[0]
 
         ## Create a shape by extrusion of the profile shape along
         #  the path shape. The path shape can be a wire or an edge.
         #  the several profiles can be specified in the several locations of path.
+        #  It is possible to generate groups along with the result by means of
+        #  setting the flag \a IsGenerateGroups. For detailed information on
+        #  groups that can be created please see the method MakePipe().
         #  @param theSeqBases - list of  Bases shape to be extruded.
         #  @param theLocations - list of locations on the path corresponding
         #                        specified list of the Bases shapes. Number of locations
@@ -3913,21 +3969,30 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
         #                          contact with the spine.
         #  @param theWithCorrection - defining that the section is rotated to be
         #                             orthogonal to the spine tangent in the correspondent point
+        #  @param IsGenerateGroups - flag that tells if it is necessary to
+        #                          create groups. It is equal to False by default.
         #  @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 the created pipe.
+        #  @return New GEOM.GEOM_Object, containing the created pipe if 
+        #          \a IsGenerateGroups is not set. Otherwise it returns new
+        #          GEOM.ListOfGO. Its first element is the created pipe, the
+        #          remaining ones are created groups.
         #
         #  @ref tui_creation_pipe_with_diff_sec "Example"
         @ManageTransactions("PrimOp")
         def MakePipeWithDifferentSections(self, theSeqBases,
                                           theLocations, thePath,
-                                          theWithContact, theWithCorrection, theName=None):
+                                          theWithContact, theWithCorrection,
+                                          IsGenerateGroups=False, theName=None):
             """
             Create a shape by extrusion of the profile shape along
             the path shape. The path shape can be a wire or an edge.
             the several profiles can be specified in the several locations of path.
+            It is possible to generate groups along with the result by means of
+            setting the flag IsGenerateGroups. For detailed information on
+            groups that can be created please see the method geompy.MakePipe().
 
             Parameters:
                 theSeqBases - list of  Bases shape to be extruded.
@@ -3939,23 +4004,37 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
                                  contact with the spine(0/1)
                 theWithCorrection - defining that the section is rotated to be
                                     orthogonal to the spine tangent in the correspondent point (0/1)
+                IsGenerateGroups - flag that tells if it is necessary to
+                                 create groups. It is equal to False by default.
                 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 the created pipe.
+                New GEOM.GEOM_Object, containing the created pipe if 
+                IsGenerateGroups is not set. Otherwise it returns new
+                GEOM.ListOfGO. Its first element is the created pipe, the
+                remaining ones are created groups.
             """
-            anObj = self.PrimOp.MakePipeWithDifferentSections(theSeqBases,
+            aList = self.PrimOp.MakePipeWithDifferentSections(theSeqBases,
                                                               theLocations, thePath,
-                                                              theWithContact, theWithCorrection)
+                                                              theWithContact, theWithCorrection,
+                                                              IsGenerateGroups)
             RaiseIfFailed("MakePipeWithDifferentSections", self.PrimOp)
-            self._autoPublish(anObj, theName, "pipe")
-            return anObj
+
+            if IsGenerateGroups:
+              self._autoPublish(aList, theName, "pipe")
+              return aList
+
+            self._autoPublish(aList[0], theName, "pipe")
+            return aList[0]
 
         ## Create a shape by extrusion of the profile shape along
-        #  the path shape. The path shape can be a wire or a edge.
+        #  the path shape. The path shape can be a wire or an edge.
         #  the several profiles can be specified in the several locations of path.
+        #  It is possible to generate groups along with the result by means of
+        #  setting the flag \a IsGenerateGroups. For detailed information on
+        #  groups that can be created please see the method MakePipe().
         #  @param theSeqBases - list of  Bases shape to be extruded. Base shape must be
         #                       shell or face. If number of faces in neighbour sections
         #                       aren't coincided result solid between such sections will
@@ -3974,21 +4053,30 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
         #                          contact with the spine.
         #  @param theWithCorrection - defining that the section is rotated to be
         #                             orthogonal to the spine tangent in the correspondent point
+        #  @param IsGenerateGroups - flag that tells if it is necessary to
+        #                          create groups. It is equal to False by default.
         #  @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 the created solids.
+        #  @return New GEOM.GEOM_Object, containing the created solids if 
+        #          \a IsGenerateGroups is not set. Otherwise it returns new
+        #          GEOM.ListOfGO. Its first element is the created solids, the
+        #          remaining ones are created groups.
         #
         #  @ref tui_creation_pipe_with_shell_sec "Example"
         @ManageTransactions("PrimOp")
         def MakePipeWithShellSections(self, theSeqBases, theSeqSubBases,
                                       theLocations, thePath,
-                                      theWithContact, theWithCorrection, theName=None):
+                                      theWithContact, theWithCorrection,
+                                      IsGenerateGroups=False, theName=None):
             """
             Create a shape by extrusion of the profile shape along
-            the path shape. The path shape can be a wire or a edge.
+            the path shape. The path shape can be a wire or an edge.
             the several profiles can be specified in the several locations of path.
+            It is possible to generate groups along with the result by means of
+            setting the flag IsGenerateGroups. For detailed information on
+            groups that can be created please see the method geompy.MakePipe().
 
             Parameters:
                 theSeqBases - list of  Bases shape to be extruded. Base shape must be
@@ -4009,19 +4097,30 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
                                  contact with the spine (0/1)
                 theWithCorrection - defining that the section is rotated to be
                                     orthogonal to the spine tangent in the correspondent point (0/1)
+                IsGenerateGroups - flag that tells if it is necessary to
+                                 create groups. It is equal to False by default.
                 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 the created solids.
+                New GEOM.GEOM_Object, containing the created solids if 
+                IsGenerateGroups is not set. Otherwise it returns new
+                GEOM.ListOfGO. Its first element is the created solids, the
+                remaining ones are created groups.
             """
-            anObj = self.PrimOp.MakePipeWithShellSections(theSeqBases, theSeqSubBases,
+            aList = self.PrimOp.MakePipeWithShellSections(theSeqBases, theSeqSubBases,
                                                           theLocations, thePath,
-                                                          theWithContact, theWithCorrection)
+                                                          theWithContact, theWithCorrection,
+                                                          IsGenerateGroups)
             RaiseIfFailed("MakePipeWithShellSections", self.PrimOp)
-            self._autoPublish(anObj, theName, "pipe")
-            return anObj
+
+            if IsGenerateGroups:
+              self._autoPublish(aList, theName, "pipe")
+              return aList
+
+            self._autoPublish(aList[0], theName, "pipe")
+            return aList[0]
 
         ## Create a shape by extrusion of the profile shape along
         #  the path shape. This function is used only for debug pipe
@@ -4031,7 +4130,8 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
         @ManageTransactions("PrimOp")
         def MakePipeWithShellSectionsBySteps(self, theSeqBases, theSeqSubBases,
                                              theLocations, thePath,
-                                             theWithContact, theWithCorrection, theName=None):
+                                             theWithContact, theWithCorrection,
+                                             IsGenerateGroups=False, theName=None):
             """
             Create a shape by extrusion of the profile shape along
             the path shape. This function is used only for debug pipe
@@ -4050,16 +4150,17 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
                 tmpLocations = [ theLocations[i-1], theLocations[i] ]
                 tmpSeqSubBases = []
                 if nbsubsect>0: tmpSeqSubBases = [ theSeqSubBases[i-1], theSeqSubBases[i] ]
-                anObj = self.PrimOp.MakePipeWithShellSections(tmpSeqBases, tmpSeqSubBases,
+                aList = self.PrimOp.MakePipeWithShellSections(tmpSeqBases, tmpSeqSubBases,
                                                               tmpLocations, thePath,
-                                                              theWithContact, theWithCorrection)
+                                                              theWithContact, theWithCorrection,
+                                                              IsGenerateGroups)
                 if self.PrimOp.IsDone() == 0:
                     print "Problems with pipe creation between ",i," and ",i+1," sections"
                     RaiseIfFailed("MakePipeWithShellSections", self.PrimOp)
                     break
                 else:
                     print "Pipe between ",i," and ",i+1," sections is OK"
-                    res.append(anObj)
+                    res.append(aList[0])
                     pass
                 pass
 
@@ -4069,57 +4170,92 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
             self._autoPublish(resc, theName, "pipe")
             return resc
 
-        ## Create solids between given sections
+        ## Create solids between given sections.
+        #  It is possible to generate groups along with the result by means of
+        #  setting the flag \a IsGenerateGroups. For detailed information on
+        #  groups that can be created please see the method MakePipe().
         #  @param theSeqBases - list of sections (shell or face).
         #  @param theLocations - list of corresponding vertexes
+        #  @param IsGenerateGroups - flag that tells if it is necessary to
+        #         create groups. It is equal to False by default.
         #  @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 the created solids.
+        #  @return New GEOM.GEOM_Object, containing the created solids if 
+        #          \a IsGenerateGroups is not set. Otherwise it returns new
+        #          GEOM.ListOfGO. Its first element is the created solids, the
+        #          remaining ones are created groups.
         #
         #  @ref tui_creation_pipe_without_path "Example"
         @ManageTransactions("PrimOp")
-        def MakePipeShellsWithoutPath(self, theSeqBases, theLocations, theName=None):
+        def MakePipeShellsWithoutPath(self, theSeqBases, theLocations,
+                                      IsGenerateGroups=False, theName=None):
             """
-            Create solids between given sections
+            Create solids between given sections.
+            It is possible to generate groups along with the result by means of
+            setting the flag IsGenerateGroups. For detailed information on
+            groups that can be created please see the method geompy.MakePipe().
 
             Parameters:
                 theSeqBases - list of sections (shell or face).
                 theLocations - list of corresponding vertexes
+                IsGenerateGroups - flag that tells if it is necessary to
+                                 create groups. It is equal to False by default.
                 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 the created solids.
+                New GEOM.GEOM_Object, containing the created solids if 
+                IsGenerateGroups is not set. Otherwise it returns new
+                GEOM.ListOfGO. Its first element is the created solids, the
+                remaining ones are created groups.
             """
-            anObj = self.PrimOp.MakePipeShellsWithoutPath(theSeqBases, theLocations)
+            aList = self.PrimOp.MakePipeShellsWithoutPath(theSeqBases, theLocations,
+                                                          IsGenerateGroups)
             RaiseIfFailed("MakePipeShellsWithoutPath", self.PrimOp)
-            self._autoPublish(anObj, theName, "pipe")
-            return anObj
+
+            if IsGenerateGroups:
+              self._autoPublish(aList, theName, "pipe")
+              return aList
+
+            self._autoPublish(aList[0], theName, "pipe")
+            return aList[0]
 
         ## Create a shape by extrusion of the base shape along
         #  the path shape with constant bi-normal direction along the given vector.
         #  The path shape can be a wire or an edge.
+        #  It is possible to generate groups along with the result by means of
+        #  setting the flag \a IsGenerateGroups. For detailed information on
+        #  groups that can be created please see the method MakePipe().
         #  @param theBase Base shape to be extruded.
         #  @param thePath Path shape to extrude the base shape along it.
         #  @param theVec Vector defines a constant binormal direction to keep the
         #                same angle beetween the direction and the sections
         #                along the sweep surface.
+        #  @param IsGenerateGroups flag that tells if it is necessary to
+        #         create groups. It is equal to False by default.
         #  @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 the created pipe.
+        #  @return New GEOM.GEOM_Object, containing the created pipe if 
+        #          \a IsGenerateGroups is not set. Otherwise it returns new
+        #          GEOM.ListOfGO. Its first element is the created pipe, the
+        #          remaining ones are created groups.
         #
         #  @ref tui_creation_pipe "Example"
         @ManageTransactions("PrimOp")
-        def MakePipeBiNormalAlongVector(self, theBase, thePath, theVec, theName=None):
+        def MakePipeBiNormalAlongVector(self, theBase, thePath, theVec,
+                                        IsGenerateGroups=False, theName=None):
             """
             Create a shape by extrusion of the base shape along
             the path shape with constant bi-normal direction along the given vector.
             The path shape can be a wire or an edge.
+            It is possible to generate groups along with the result by means of
+            setting the flag IsGenerateGroups. For detailed information on
+            groups that can be created please see the method geompy.MakePipe().
 
             Parameters:
                 theBase Base shape to be extruded.
@@ -4127,18 +4263,29 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
                 theVec Vector defines a constant binormal direction to keep the
                        same angle beetween the direction and the sections
                        along the sweep surface.
+                IsGenerateGroups flag that tells if it is necessary to
+                                 create groups. It is equal to False by default.
                 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 the created pipe.
+                New GEOM.GEOM_Object, containing the created pipe if 
+                IsGenerateGroups is not set. Otherwise it returns new
+                GEOM.ListOfGO. Its first element is the created pipe, the
+                remaining ones are created groups.
             """
             # Example: see GEOM_TestAll.py
-            anObj = self.PrimOp.MakePipeBiNormalAlongVector(theBase, thePath, theVec)
+            aList = self.PrimOp.MakePipeBiNormalAlongVector(theBase, thePath,
+                          theVec, IsGenerateGroups)
             RaiseIfFailed("MakePipeBiNormalAlongVector", self.PrimOp)
-            self._autoPublish(anObj, theName, "pipe")
-            return anObj
+
+            if IsGenerateGroups:
+              self._autoPublish(aList, theName, "pipe")
+              return aList
+
+            self._autoPublish(aList[0], theName, "pipe")
+            return aList[0]
 
         ## Makes a thick solid from a shape. If the input is a surface shape
         #  (face or shell) the result is a thick solid. If an input shape is
index 181522a3c9d79007c8a15782ace2cfeeca4d2081..5f7afb3a1b54cb600e3bb14c571baa0a4dfb0205 100755 (executable)
@@ -37,6 +37,7 @@ INCLUDE_DIRECTORIES(
   ${PROJECT_SOURCE_DIR}/src/GEOMImpl
   ${PROJECT_SOURCE_DIR}/src/GEOMGUI
   ${PROJECT_SOURCE_DIR}/src/GEOMBase
+  ${PROJECT_SOURCE_DIR}/src/GEOMUtils
   ${PROJECT_SOURCE_DIR}/src/DlgRef
   ${PROJECT_BINARY_DIR}/src/DlgRef
   ${CMAKE_CURRENT_SOURCE_DIR}
@@ -55,6 +56,7 @@ SET(_link_LIBRARIES
   GEOMClient
   GEOMImpl
   GEOMBase
+  GEOMUtils
   GEOM
   DlgRef
   )
index fe972a26c219d983e5ec063d06171fad2989cf93..33b43b09fb49b85ad2c4f82c940f233460f6abd5 100644 (file)
@@ -29,6 +29,7 @@
 #include <DlgRef.h>
 #include <GeometryGUI.h>
 #include <GEOMBase.h>
+#include <GEOMUtils.hxx>
 
 #include <SUIT_Session.h>
 #include <SUIT_ResourceMgr.h>
 #include <LightApp_SelectionMgr.h>
 
 #include <TopoDS_Shape.hxx>
-#include <TopoDS.hxx>
-#include <TopExp.hxx>
-#include <TopTools_IndexedMapOfShape.hxx>
-#include <TColStd_IndexedMapOfInteger.hxx>
 #include <TColStd_MapOfInteger.hxx>
 
 #include <GEOMImpl_Types.hxx>
 //=================================================================================
 GenerationGUI_PipeDlg::GenerationGUI_PipeDlg (GeometryGUI* theGeometryGUI, QWidget* parent,
                                               bool modal, Qt::WindowFlags fl)
-  : GEOMBase_Skeleton(theGeometryGUI, parent, modal, fl)
+  : GEOMBase_Skeleton  (theGeometryGUI, parent, modal, fl),
+    myGenGroupCheckGP  (0),
+    myPrefixLblGP      (0),
+    myPrefixEditGP     (0),
+    myGenGroupCheckGMP (0),
+    myPrefixLblGMP     (0),
+    myPrefixEditGMP    (0)
 {
   QPixmap image0 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_PIPE")));
   QPixmap image1 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
@@ -81,6 +84,19 @@ GenerationGUI_PipeDlg::GenerationGUI_PipeDlg (GeometryGUI* theGeometryGUI, QWidg
   GroupPoints->PushButton3->setIcon(image1);
   GroupPoints->CheckButton1->setText(tr("GEOM_SELECT_UNPUBLISHED_EDGES"));
 
+  // Add widgets for group generation
+  QGridLayout *aLayoutGP = (QGridLayout *)GroupPoints->GroupBox1->layout();
+
+  myGenGroupCheckGP =
+    new QCheckBox(tr("GEOM_GENERATE_GROUPS"), GroupPoints->GroupBox1);
+  myPrefixLblGP     =
+    new QLabel (tr("GEOM_GROUP_NAME_PREFIX"), GroupPoints->GroupBox1);
+  myPrefixEditGP    = new QLineEdit(GroupPoints->GroupBox1);
+
+  aLayoutGP->addWidget(myGenGroupCheckGP, 4, 0, 1, 3);
+  aLayoutGP->addWidget(myPrefixLblGP,     5, 0, 1, 2);
+  aLayoutGP->addWidget(myPrefixEditGP,    5, 2);
+
   GroupMakePoints = new DlgRef_3Sel2Check3Spin(centralWidget());
 
   GroupMakePoints->GroupBox1->setTitle(tr("GEOM_ARGUMENTS"));
@@ -92,6 +108,12 @@ GenerationGUI_PipeDlg::GenerationGUI_PipeDlg (GeometryGUI* theGeometryGUI, QWidg
   GroupMakePoints->PushButton3->setIcon(image1);
   GroupMakePoints->CheckBox1->setText(tr("GEOM_WITH_CONTACT"));
   GroupMakePoints->CheckBox2->setText(tr("GEOM_WITH_CORRECTION"));
+  GroupMakePoints->SpinBox1->setAttribute(Qt::WA_DeleteOnClose);
+  GroupMakePoints->SpinBox2->setAttribute(Qt::WA_DeleteOnClose);
+  GroupMakePoints->SpinBox3->setAttribute(Qt::WA_DeleteOnClose);
+  GroupMakePoints->TextLabel4->setAttribute(Qt::WA_DeleteOnClose);
+  GroupMakePoints->TextLabel5->setAttribute(Qt::WA_DeleteOnClose);
+  GroupMakePoints->TextLabel6->setAttribute(Qt::WA_DeleteOnClose);
   GroupMakePoints->SpinBox1->close();
   GroupMakePoints->SpinBox2->close();
   GroupMakePoints->SpinBox3->close();
@@ -99,6 +121,19 @@ GenerationGUI_PipeDlg::GenerationGUI_PipeDlg (GeometryGUI* theGeometryGUI, QWidg
   GroupMakePoints->TextLabel5->close();
   GroupMakePoints->TextLabel6->close();
 
+  // Add widgets for group generation
+  QGridLayout *aLayoutGMP = (QGridLayout *)GroupMakePoints->GroupBox1->layout();
+
+  myGenGroupCheckGMP =
+    new QCheckBox(tr("GEOM_GENERATE_GROUPS"), GroupMakePoints->GroupBox1);
+  myPrefixLblGMP     =
+    new QLabel (tr("GEOM_GROUP_NAME_PREFIX"), GroupMakePoints->GroupBox1);
+  myPrefixEditGMP    = new QLineEdit(GroupMakePoints->GroupBox1);
+
+  aLayoutGMP->addWidget(myGenGroupCheckGMP, 8, 0, 1, 3);
+  aLayoutGMP->addWidget(myPrefixLblGMP,     9, 0, 1, 2);
+  aLayoutGMP->addWidget(myPrefixEditGMP,    9, 2);
+
   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
   layout->setMargin(0); layout->setSpacing(6);
   layout->addWidget(GroupPoints);
@@ -166,6 +201,8 @@ void GenerationGUI_PipeDlg::Init()
   connect(GroupMakePoints->PushButton3, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
   connect(GroupMakePoints->CheckBox1, SIGNAL(clicked()), this, SLOT(processPreview()));
   connect(GroupMakePoints->CheckBox2, SIGNAL(clicked()), this, SLOT(processPreview()));
+  connect(myGenGroupCheckGP,  SIGNAL(toggled(bool)), this, SLOT(GenGroupClicked(bool)));
+  connect(myGenGroupCheckGMP, SIGNAL(toggled(bool)), this, SLOT(GenGroupClicked(bool)));
 
   initName(tr("GEOM_PIPE"));
   resize(100,100);
@@ -177,6 +214,7 @@ void GenerationGUI_PipeDlg::Init()
 
   GroupPoints->PushButton1->click();
   SelectionIntoArgument();
+  updateGenGroup();
 }
 
 //=================================================================================
@@ -195,6 +233,8 @@ void GenerationGUI_PipeDlg::ConstructorsClicked( int constructorId )
     GroupPoints->PushButton3->hide();
     GroupPoints->LineEdit3->hide();
     GroupPoints->PushButton1->click();
+    myGenGroupCheckGP->setChecked(false);
+    resetGenGroup(myGenGroupCheckGP, false, true);
     break;
   case 1:
     GroupMakePoints->hide();
@@ -203,11 +243,15 @@ void GenerationGUI_PipeDlg::ConstructorsClicked( int constructorId )
     GroupPoints->PushButton3->show();
     GroupPoints->LineEdit3->show();
     GroupPoints->PushButton1->click();
+    myGenGroupCheckGP->setChecked(false);
+    resetGenGroup(myGenGroupCheckGP, false, true);
     break;
   case 2:
     GroupPoints->hide();
     GroupMakePoints->show();
     GroupMakePoints->PushButton1->click();
+    myGenGroupCheckGMP->setChecked(false);
+    resetGenGroup(myGenGroupCheckGMP, false, true);
     break;
   default:
     break;
@@ -240,6 +284,7 @@ void GenerationGUI_PipeDlg::SelectionTypeButtonClicked()
   if ( myEditCurrentArgument == GroupPoints->LineEdit2 ) {
     myEditCurrentArgument->setText("");
     myPath.nullify();
+    updateGenGroup();
   }
   processPreview();
 }
@@ -306,6 +351,7 @@ void GenerationGUI_PipeDlg::SelectionIntoArgument()
       else if ( myBaseObjects.isEmpty() )
         GroupPoints->PushButton1->click();
     }
+    updateGenGroup();
   }
   else if (myEditCurrentArgument == GroupPoints->LineEdit3) {
     myVec = getSelected( TopAbs_EDGE );
@@ -345,6 +391,7 @@ void GenerationGUI_PipeDlg::SelectionIntoArgument()
       QString aName = GEOMBase::GetName( myPath.get() );
       myEditCurrentArgument->setText( aName );
     }
+    updateGenGroup();
   }
 
   processPreview();
@@ -480,24 +527,42 @@ bool GenerationGUI_PipeDlg::isValid (QString&)
 //=================================================================================
 bool GenerationGUI_PipeDlg::execute (ObjectList& objects)
 {
-  GEOM::GEOM_Object_var anObj;
+  GEOM::ListOfGO_var aList;
 
   GEOM::GEOM_I3DPrimOperations_var anOper = GEOM::GEOM_I3DPrimOperations::_narrow(getOperation());
+  bool doGroups = !IsPreview();
+
+  myGroupObjectsMap.clear();
+
   switch( getConstructorId() ) {
   case 0:
   case 1:
+    if (doGroups) {
+      doGroups = myGenGroupCheckGP->isEnabled() &&
+                 myGenGroupCheckGP->isChecked();
+    }
+
     for (int i = 0; i < myBaseObjects.count(); i++) {
       switch ( getConstructorId() ) {
       case 0 :
-       anObj = anOper->MakePipe(myBaseObjects[i].get(), myPath.get());
-       break;
+        aList = anOper->MakePipe(myBaseObjects[i].get(),
+                                 myPath.get(), doGroups);
+        break;
       case 1 :
-       anObj = anOper->MakePipeBiNormalAlongVector(myBaseObjects[i].get(), myPath.get(), myVec.get());
-       break;
+        aList = anOper->MakePipeBiNormalAlongVector
+              (myBaseObjects[i].get(), myPath.get(), myVec.get(), doGroups);
+        break;
+      }
+
+      if (aList->length() > 0) {
+        if (doGroups) {
+          addGroups(aList);
+        }
+
+        if (!aList[0]->_is_nil()) {
+          objects.push_back(aList[0]._retn());
+        }
       }
-    
-      if (!anObj->_is_nil())
-       objects.push_back(anObj._retn());
     }
     break;
   case 2:
@@ -507,17 +572,31 @@ bool GenerationGUI_PipeDlg::execute (ObjectList& objects)
       myBaseGO->length( myBaseObjects.count() );
       myLocationsGO->length( myLocations.count() );
       for (int i = 0; i < myBaseObjects.count(); i++) {
-       myBaseGO[i] = myBaseObjects[i].copy();
+        myBaseGO[i] = myBaseObjects[i].copy();
       }
       for (int i = 0; i < myLocations.count(); i++) {
-       myLocationsGO[i] = myLocations[i].copy();
+        myLocationsGO[i] = myLocations[i].copy();
+      }
+
+      if (doGroups) {
+        doGroups = myGenGroupCheckGMP->isEnabled() &&
+                   myGenGroupCheckGMP->isChecked();
+      }
+
+      aList = anOper->MakePipeWithDifferentSections
+                          (myBaseGO.in(), myLocationsGO.in(), myPath.get(), 
+                           GroupMakePoints->CheckBox1->isChecked(), 
+                           GroupMakePoints->CheckBox2->isChecked(), doGroups);
+
+      if (aList->length() > 0) {
+        if (doGroups) {
+          addGroups(aList);
+        }
+
+        if (!aList[0]->_is_nil()) {
+          objects.push_back(aList[0]._retn());
+        }
       }
-      
-      anObj = anOper->MakePipeWithDifferentSections(myBaseGO.in(), myLocationsGO.in(), myPath.get(), 
-                                                   GroupMakePoints->CheckBox1->isChecked(), 
-                                                   GroupMakePoints->CheckBox2->isChecked());
-      if (!anObj->_is_nil())
-       objects.push_back(anObj._retn());
     }
     break;
   default:
@@ -545,6 +624,66 @@ bool GenerationGUI_PipeDlg::extractPrefix() const
   return myBaseObjects.count() > 1;
 }
 
+//=================================================================================
+// function : restoreSubShapes
+// purpose  : virtual method to restore tree of argument's sub-shapes under
+//            the resulting shape. Redefined from GEOMBase_Helper class.
+//=================================================================================
+void GenerationGUI_PipeDlg::restoreSubShapes
+              (SALOMEDS::Study_ptr theStudy, SALOMEDS::SObject_ptr theSObject)
+{
+  QCheckBox *aGenGroupCheck = NULL;
+  QLineEdit *aPrefixEdit    = NULL;
+
+  switch (getConstructorId()) {
+  case 0 :
+  case 1 :
+    aGenGroupCheck = myGenGroupCheckGP;
+    aPrefixEdit    = myPrefixEditGP;
+    break;
+  case 2 :
+    aGenGroupCheck = myGenGroupCheckGMP;
+    aPrefixEdit    = myPrefixEditGMP;
+    break;
+  default:
+    break;
+  }
+
+  if (aGenGroupCheck == NULL || !aGenGroupCheck->isChecked()) {
+    return;
+  }
+
+  // get Object from SObject
+  GEOM::GEOM_Object_var aFather = GEOM::GEOM_Object::_narrow
+            (theSObject->GetObject());
+
+  if (CORBA::is_nil(aFather)) {
+    return;
+  }
+
+  ObjectMap::const_iterator anIter    =
+    myGroupObjectsMap.find(aFather->GetEntry());
+  QString                   aPrefix   = aPrefixEdit->text();
+  bool                      hasPrefix = !aPrefix.isEmpty();
+
+  if (anIter != myGroupObjectsMap.end()) {
+    QList<GEOM::GeomObjPtr>::const_iterator it = anIter->second.begin();
+
+    for (; it != anIter->second.end(); it++) {
+      // Compose the name
+      QString aName;
+
+      if (hasPrefix) {
+        aName = aPrefix + "_";
+      }
+
+      aName += tr((*it)->GetName());
+      getGeomEngine()->AddInStudy(theStudy, (*it).get(),
+                                  aName.toStdString().c_str(), aFather);
+    }
+  }
+}
+
 //=================================================================================
 // function : getSourceObjects
 // purpose  : virtual method to get source objects
@@ -557,3 +696,102 @@ QList<GEOM::GeomObjPtr> GenerationGUI_PipeDlg::getSourceObjects()
     res << myLocations[i];
   return res;
 }
+
+//=================================================================================
+// function : GenGroupClicked
+// purpose  : Slot to treat checking "Generate groups" check box.
+//=================================================================================
+void GenerationGUI_PipeDlg::GenGroupClicked(bool isChecked)
+{
+  resetGenGroup((QCheckBox *)sender(), isChecked, false);
+}
+
+//=================================================================================
+// function : updateGenGroup
+// purpose  : Update "Generate groups" widgets depending on the path.
+//=================================================================================
+void GenerationGUI_PipeDlg::updateGenGroup()
+{
+  bool isEnable = true;
+
+  if (myPath) {
+    // Check if the path is closed.
+    TopoDS_Shape aShapePath;
+
+    if (GEOMBase::GetShape(myPath.get(), aShapePath)) {
+      isEnable = GEOMUtils::IsOpenPath(aShapePath);
+    }
+  }
+
+  QCheckBox *aGenGroupCheck = NULL;
+
+  switch (getConstructorId()) {
+  case 0 :
+  case 1 :
+    aGenGroupCheck = myGenGroupCheckGP;
+    break;
+  case 2 :
+    aGenGroupCheck = myGenGroupCheckGMP;
+    break;
+  default:
+    break;
+  }
+
+  if (aGenGroupCheck != NULL) {
+    const bool isChecked = aGenGroupCheck->isChecked();
+
+    aGenGroupCheck->setEnabled(isEnable);
+    resetGenGroup(aGenGroupCheck, isEnable && isChecked, false);
+  }
+}
+
+//=================================================================================
+// function : resetGenGroup
+// purpose  : Resets data of "Generate groups" widgets.
+//=================================================================================
+void GenerationGUI_PipeDlg::resetGenGroup(QCheckBox  *theGenGroup,
+                                          const bool  isChecked,
+                                          const bool  isClearPrefix)
+{
+  QLabel    *aPrefixLbl  = NULL;
+  QLineEdit *aPrefixEdit = NULL;
+
+  if (theGenGroup == myGenGroupCheckGP) {
+    aPrefixLbl  = myPrefixLblGP;
+    aPrefixEdit = myPrefixEditGP;
+  } else if (theGenGroup == myGenGroupCheckGMP) {
+    aPrefixLbl  = myPrefixLblGMP;
+    aPrefixEdit = myPrefixEditGMP;
+  }
+
+  if (aPrefixLbl != NULL) {
+    aPrefixLbl->setEnabled(isChecked);
+    aPrefixEdit->setEnabled(isChecked);
+
+    if (isClearPrefix) {
+      aPrefixEdit->setText("");
+    }
+  }
+}
+
+//=================================================================================
+// function : addGroups
+// purpose  : Add result groups to the list of groups.
+//=================================================================================
+void GenerationGUI_PipeDlg::addGroups(GEOM::ListOfGO_var &theResult)
+{
+  const int aNbObj = theResult->length();
+
+  if (aNbObj > 0) {
+    if (!theResult[0]->_is_nil()) {
+      QString anEntry = theResult[0]->GetEntry();
+      int     i;
+
+      for (i = 1; i < aNbObj; ++i) {
+        if (!theResult[i]->_is_nil()) {
+          myGroupObjectsMap[anEntry].append(GEOM::GeomObjPtr(theResult[i]));
+        }
+      }
+    }
+  }
+}
index 868b465af2253488f67021f74729d8598a00f513..4b2d88efdff68b6e0e93233e77433d820b7a09a0 100644 (file)
@@ -30,6 +30,9 @@
 #include "GEOMBase_Skeleton.h"
 #include "GEOM_GenericObjPtr.h"
 
+typedef std::map<QString, QList<GEOM::GeomObjPtr> > ObjectMap;
+
+
 class DlgRef_3Sel1Check;
 class DlgRef_3Sel2Check3Spin;
 
@@ -52,11 +55,20 @@ protected:
   virtual bool                       execute( ObjectList& );    
   virtual void                       addSubshapesToStudy();
   virtual bool                       extractPrefix() const;
+  virtual void                       restoreSubShapes
+                                 (SALOMEDS::Study_ptr, SALOMEDS::SObject_ptr);
   virtual QList<GEOM::GeomObjPtr>    getSourceObjects();
 
 private:
   void                               Init();
   void                               enterEvent( QEvent* );
+  void                               updateGenGroup();
+  void                               resetGenGroup
+                                        (QCheckBox *theGenGroup,
+                                         const bool isChecked,
+                                         const bool isClearPrefix);
+  void                               addGroups
+                                      (GEOM::ListOfGO_var &theResult);
   
 private:
   QList<GEOM::GeomObjPtr>            myBaseObjects;  /* Base shapes */
@@ -66,6 +78,13 @@ private:
   
   DlgRef_3Sel1Check*                 GroupPoints;
   DlgRef_3Sel2Check3Spin*            GroupMakePoints;
+  QCheckBox                         *myGenGroupCheckGP;
+  QLabel                            *myPrefixLblGP;
+  QLineEdit                         *myPrefixEditGP;
+  QCheckBox                         *myGenGroupCheckGMP;
+  QLabel                            *myPrefixLblGMP;
+  QLineEdit                         *myPrefixEditGMP;
+  ObjectMap                          myGroupObjectsMap;
 
 private slots:
   void                               ClickOnOk();
@@ -75,6 +94,7 @@ private slots:
   void                               SetEditCurrentArgument();
   void                               ConstructorsClicked( int );
   void                               SelectionTypeButtonClicked();
+  void                               GenGroupClicked(bool);
 };
 
 #endif // GENERATIONGUI_PIPEDLG_H