]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
[bos #40618] [CEA] Offset/Thickness Feature. jfa/40618_Offset 27/head
authorjfa <jfa@opencascade.com>
Wed, 14 Aug 2024 00:26:42 +0000 (01:26 +0100)
committerChristophe Bourcier <christophe.bourcier@cea.fr>
Fri, 8 Nov 2024 09:37:36 +0000 (10:37 +0100)
21 files changed:
doc/salome/examples/transformation_operations_ex06.py
doc/salome/gui/GEOM/images/transformation11a.png [new file with mode: 0644]
doc/salome/gui/GEOM/input/offset_operation.doc
idl/GEOM_Gen.idl
resources/CMakeLists.txt
resources/offset_partial.png [new file with mode: 0644]
src/GEOMBase/GEOMBase.cxx
src/GEOMBase/GEOMBase.h
src/GEOMGUI/GEOM_images.ts
src/GEOMGUI/GEOM_msg_en.ts
src/GEOMGUI/GEOM_msg_fr.ts
src/GEOMImpl/GEOMImpl_ConformityDriver.cxx
src/GEOMImpl/GEOMImpl_ITransformOperations.cxx
src/GEOMImpl/GEOMImpl_ITransformOperations.hxx
src/GEOMImpl/GEOMImpl_OffsetDriver.cxx
src/GEOM_I/GEOM_IMeasureOperations_i.cc
src/GEOM_I/GEOM_ITransformOperations_i.cc
src/GEOM_I/GEOM_ITransformOperations_i.hh
src/GEOM_SWIG/geomBuilder.py
src/TransformationGUI/TransformationGUI_OffsetDlg.cxx
src/TransformationGUI/TransformationGUI_OffsetDlg.h

index 16bff16e1ec92c2410f45be7adde5c9a5d963604..3e2ca023d43933de65753ae6a1331ec28c2fb236 100644 (file)
@@ -13,14 +13,17 @@ box = geompy.MakeBox(20, 20, 20, 200, 200, 200)
 # create a new object as offset of the given object
 offset  = geompy.MakeOffset(box, 70.)
 offset2 = geompy.MakeOffsetIntersectionJoin(box, 70.)
+offset3 = geompy.MakeOffsetPartial(box, 70., [13, 33])
 
 # add objects in the study
 id_box = geompy.addToStudy(box, "Box")
 id_offset = geompy.addToStudy(offset, "Offset")
 id_offset2 = geompy.addToStudy(offset2, "Offset_intersection_join")
+id_offset3 = geompy.addToStudy(offset3, "Offset_Partial")
 
 # display the results
 gg.createAndDisplayGO(id_box)
 gg.setDisplayMode(id_box,1)
 gg.createAndDisplayGO(id_offset)
 gg.createAndDisplayGO(id_offset2)
+gg.createAndDisplayGO(id_offset3)
diff --git a/doc/salome/gui/GEOM/images/transformation11a.png b/doc/salome/gui/GEOM/images/transformation11a.png
new file mode 100644 (file)
index 0000000..f9e555b
Binary files /dev/null and b/doc/salome/gui/GEOM/images/transformation11a.png differ
index d3d1fd19743da40fad44c19a931214c2dd600f5e..e75fc12e801fbb7ddae907affa7ac5433b969cf2 100644 (file)
@@ -5,6 +5,10 @@
 \n To produce an <b>Offset Surface</b> in the <b>Main Menu</b> select
 <b>Operations - > Transformation - > Offset Surface</b>
 
+\n There are 2 algorithms for creation of an \b Offset.
+
+\n Firstly, you can offset all faces of selected shape(s) to the same value. 
+
 \n This operation translates each point of an \b Object (a set of
 Objects) along a local normal by a given \b Offset distance (signed
 number, negative value meaning inner offset). Gaps between translated 
@@ -13,12 +17,12 @@ adjacent surfaces are filled in either of two ways:
 - else the surfaces are extended and intersected, so that sharp edges
   are preserved.
 
-\n \b Offset operation is applicable to faces, shells and solids.
-\n \ref restore_presentation_parameters_page "Advanced options".
-
-
 \image html transformation11.png
 
+\n <b>Arguments:</b> Name + Object(s) (face(s), shell(s), solid(s)) + Offset value.
+\n The \b Result will be a \b GEOM_Object. 
+\n \ref restore_presentation_parameters_page "Advanced options".
+
 \n <b>Example:</b>
 
 \image html offsetsn.png "The box and its offset surface (Join by pipes activated)"
@@ -27,11 +31,27 @@ adjacent surfaces are filled in either of two ways:
 - Gaps filled by pipes: <em>geompy.MakeOffset(Shape, Offset),</em>
 - Gaps filled by intersection: <em>geompy.MakeOffsetIntersectionJoin(Shape, Offset),</em>
 
-where Shape is a shape(s) which has to be an offset, Offset is a value of
+where \b Shape is a shape(s) which has to be an offset, \b Offset is a value of
 the offset.
-\n <b>Arguments:</b> Name + Object (face(s), shell(s), solid(s)) +
-Offset value.
+
+\n Secondly, you can offset only selected faces of the shape to the given value,
+   other faces will stay at their initial places,
+   but could be extended to join with offset faces.
+   Gaps between adjacent surfaces are filled by intersection of extended surfaces.
+
+\image html transformation11a.png
+
+\n <b>Arguments:</b> Name + Object (shell or solid) +
+                     Face(s) of the object + Offset value.
 \n The \b Result will be a \b GEOM_Object. 
+\n \ref restore_presentation_parameters_page "Advanced options".
+
+\n <b>TUI Command:</b> 
+- <em>geompy.MakeOffsetPartial(Shape, Offset, ListOfFacesIDs),</em>
+
+where \b Shape is a shape(s) which has to be an offset,
+      \b Offset is a value of the offset,
+      \b ListOfFacesIDs is a list of integer IDs of sub-faces.
 
 Our <b>TUI Scripts</b> provide you with useful examples of the use of
 \ref tui_offset "Transformation Operations".
index d1428637a75e00fa1f489ad69c213e6658e749bb..1d6abe8c3f06b4080aa31df0cd39a1c1c41b931c 100644 (file)
@@ -1345,6 +1345,18 @@ module GEOM
                                  in double      theOffset,
                                  in boolean     theJoinByPipes);
 
+    /*!
+     *  \brief Create new object as offset of the given one.
+     *         Only indexed faces are offset, others keep they original location.
+     *  \param theObject The base object for the offset.
+     *  \param theOffset Offset value.
+     *  \param theFacesIDs The list of face IDs indicating faces to be offset.
+     *  \return New GEOM_Object, containing the offset object.
+     */
+    GEOM_Object OffsetShapePartialCopy (in GEOM_Object theObject,
+                                        in double      theOffset,
+                                        in ListOfLong  theFacesIDs);
+
     /*!
      *  \brief Create new object as projection of the given one on a 2D surface.
      *  \param theSource The source object for the projection. It can be a point, edge or wire.
index 76bb5fbd72640f7259b1bc82e1f2475d9321f115..16985f969b1ee43b4030d46d6949c326052b4b39 100644 (file)
@@ -132,6 +132,7 @@ SET( _res_files
   multitranslationsimple.png
   normale.png
   offset.png
+  offset_partial.png
   projection.png
   projection_on_edge.png
   projection_on_wire.png
diff --git a/resources/offset_partial.png b/resources/offset_partial.png
new file mode 100644 (file)
index 0000000..ced1d32
Binary files /dev/null and b/resources/offset_partial.png differ
index d3371cf1f75104fcea90867deef448ef569f6ba2..1071c3e2132b4899fed1e17c1e25014f0a3758f5 100644 (file)
@@ -822,6 +822,23 @@ QString GEOMBase::GetName( GEOM::GEOM_Object_ptr object )
   return name;
 }
 
+//=======================================================================
+// function : GetName()
+// purpose  : Get name of objects
+//=======================================================================
+QString GEOMBase::GetName( const QList<GEOM::GeomObjPtr>& objects )
+{
+  QString name;
+
+  int nbSel = objects.count();
+  if (nbSel == 1)
+    name = GEOMBase::GetName( objects[0].get() );
+  else if (nbSel > 1)
+    name = QObject::tr("%1_objects").arg( nbSel );
+
+  return name;
+}
+
 //=======================================================================
 // function : IsShape()
 // purpose  : Return TRUE if object is valid and has shape
index c23fe71b2a33f7947de5dc3e7305245e361c13e0..f7e2135514cb02a38b4d07723974845fa25a6b81 100644 (file)
@@ -124,6 +124,7 @@ public :
 
   /* Gets name of object */
   static QString      GetName( GEOM::GEOM_Object_ptr object );
+  static QString      GetName( const QList<GEOM::GeomObjPtr>& objects );
 
   /* Check if object has shape */
   static bool         IsShape( GEOM::GEOM_Object_ptr object );
index 03ffd98e9e2ef25b5d77f3e0387a22dbf5047275..88abb3e22afa5007ace5ed8d38410fe12dba92ad 100644 (file)
             <source>ICON_DLG_OFFSET</source>
             <translation>offset.png</translation>
         </message>
+        <message>
+            <source>ICON_DLG_OFFSET_PARTIAL</source>
+            <translation>offset_partial.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_PROJECTION_ON_FACE</source>
             <translation>projection.png</translation>
index 41c3fa5de4dc3230d24afcc2ac27d5f27a56d54c..c3602d67b4d879d46ca915e266878063a5d4f426 100644 (file)
@@ -7982,6 +7982,14 @@ Do you want to create new material?</translation>
         <source>GEOM_JOIN_BY_PIPES</source>
         <translation>Join by pipes</translation>
     </message>
+    <message>
+        <source>TOOLTIP_OFFSET</source>
+        <translation>Offset</translation>
+    </message>
+    <message>
+        <source>TOOLTIP_OFFSET_PARTIAL</source>
+        <translation>Partial offset</translation>
+    </message>
 </context>
 <context>
     <name>OperationGUI_ExtractionDlg</name>
index 6605a135e88e8ad43c1ab371afc2661607effab4..304834f1cafd4f4300b6fea887f7032e09e8ee5c 100644 (file)
@@ -7960,6 +7960,21 @@ Voulez-vous en créer un nouveau ?</translation>
         <translation>Longueur de l&apos;angle</translation>
     </message>
 </context>
+<context>
+    <name>TransformationGUI_OffsetDlg</name>
+    <message>
+        <source>GEOM_JOIN_BY_PIPES</source>
+        <translation>Rejoindre par des tuyaux</translation>
+    </message>
+    <message>
+        <source>TOOLTIP_OFFSET</source>
+        <translation>Décalage</translation>
+    </message>
+    <message>
+        <source>TOOLTIP_OFFSET_PARTIAL</source>
+        <translation>Décalage partiel</translation>
+    </message>
+</context>
 <context>
     <name>OperationGUI_ExtractionDlg</name>
     <message>
index faed054d0fc9316f48321f75a880df98038b98f8..1ad7c6580526a2d72aa20ba00eea6e411b3549d5 100644 (file)
 
 namespace
 {
-  //=======================================================================
-  //function : ConvertShapesToIndices
-  //purpose  : Convert sub-shapes of shapes to sequence of indices
-  //=======================================================================
-  Handle(TColStd_HArray1OfInteger) ConvertShapesToIndices(const TopoDS_Shape& theShape,
-                                                          const TopTools_ListOfShape& theShapes)
-  {
-    Handle(TColStd_HArray1OfInteger) aSeqOfIDs = new TColStd_HArray1OfInteger(1, theShapes.Size());
-
-    TopTools_IndexedMapOfShape anIndices;
-    TopExp::MapShapes(theShape, anIndices);
-
-    TopTools_ListIteratorOfListOfShape itSub(theShapes);
-    for (int index = 1; itSub.More(); itSub.Next(), ++index)
-    {
-      int id = anIndices.FindIndex(itSub.Value());
-      aSeqOfIDs->SetValue(index, id);
-    }
-
-    return aSeqOfIDs;
-  }
-
   //=======================================================================
   //function : ConvertShapesToIndices
   //purpose  : Convert list of pair shapes to sequence of indices
@@ -203,6 +181,8 @@ Standard_Real GEOMImpl_ConformityDriver::updateTolerance(const TopoDS_Shape& the
       case TopAbs_FACE:
         aCurTolerance = BRep_Tool::Tolerance(TopoDS::Face(anExp.Value()));
         break;
+      default:
+        break;
       }
       aTolerance = Min(aTolerance, aCurTolerance);
     }
@@ -228,6 +208,8 @@ Standard_Real GEOMImpl_ConformityDriver::updateTolerance(const TopoDS_Shape& the
       case TopAbs_FACE:
         aCurTolerance = BRep_Tool::Tolerance(TopoDS::Face(anExp.Value()));
         break;
+      default:
+        break;
       }
       aResTol = Max(aResTol, aCurTolerance);
     }
index 4ca0707de20d85aa5ad60c6c0dde2bfb85a9c0e1..26d3f60056a39d1a0bd9f83fe3ca4bcd08d594c1 100644 (file)
@@ -1090,10 +1090,11 @@ GEOMImpl_ITransformOperations::OffsetShape (Handle(GEOM_Object) theObject,
  *  OffsetShapeCopy
  */
 //=============================================================================
-Handle(GEOM_Object)
-GEOMImpl_ITransformOperations::OffsetShapeCopy( Handle(GEOM_Object) theObject,
-                                                double              theOffset,
-                                                bool                theJoinByPipes)
+Handle(GEOM_Object) GEOMImpl_ITransformOperations::OffsetShapeCopy
+                    (Handle(GEOM_Object)                     theObject,
+                     double                                  theOffset,
+                     bool                                    theJoinByPipes,
+                     const Handle(TColStd_HArray1OfInteger)& theFacesIDs)
 {
   SetErrorCode(KO);
 
@@ -1118,6 +1119,10 @@ GEOMImpl_ITransformOperations::OffsetShapeCopy( Handle(GEOM_Object) theObject,
   aTI.SetValue( theOffset );
   aTI.SetJoinByPipes( theJoinByPipes );
 
+  if (!theFacesIDs.IsNull()) {
+    aTI.SetFaceIDs(theFacesIDs);
+  }
+
   //Compute the offset
   try {
     OCC_CATCH_SIGNALS;
@@ -1132,18 +1137,31 @@ GEOMImpl_ITransformOperations::OffsetShapeCopy( Handle(GEOM_Object) theObject,
   }
 
   //Make a Python command
-  if (theJoinByPipes)
-    GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeOffset("
-                                 << theObject << ", " << theOffset << ")";
-  else
-    GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeOffsetIntersectionJoin("
-                                 << theObject << ", " << theOffset << ")";
+  if (theFacesIDs.IsNull()) {
+    if (theJoinByPipes)
+      GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeOffset("
+                                   << theObject << ", " << theOffset << ")";
+    else
+      GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeOffsetIntersectionJoin("
+                                   << theObject << ", " << theOffset << ")";
+  }
+  else {
+    GEOM::TPythonDump pd (aFunction);
+    pd << aCopy << " = geompy.MakeOffsetPartial("
+       << theObject << ", " << theOffset << ", [";
+
+    // Dump faces IDs.
+    for (Standard_Integer i = theFacesIDs->Lower(); i <= theFacesIDs->Upper(); ++i) {
+      pd << theFacesIDs->Value(i) << ((i == theFacesIDs->Upper()) ? "" : ", ");
+    }
+
+    pd << "])";
+  }
 
   SetErrorCode(OK);
   return aCopy;
 }
 
-
 //=============================================================================
 /*!
  *  ProjectShapeCopy
index 25498ce00f96f27ff4cdce6d7bd99972c1abeb4a..aac62cfdddfa0667763f98860c5e6454a1733d9f 100644 (file)
@@ -108,9 +108,11 @@ class GEOMImpl_ITransformOperations : public GEOM_IOperations
                                                    double              theOffset,
                                                    bool                theJoinByPipes);
 
-  Standard_EXPORT Handle(GEOM_Object) OffsetShapeCopy (Handle(GEOM_Object) theObject,
-                                                       double              theOffset,
-                                                       bool                theJoinByPipes);
+  Standard_EXPORT Handle(GEOM_Object) OffsetShapeCopy
+                              (Handle(GEOM_Object) theObject,
+                               double              theOffset,
+                               bool                theJoinByPipes,
+                               const Handle(TColStd_HArray1OfInteger)& theFacesIDs = NULL);
 
   Standard_EXPORT Handle(GEOM_Object) ProjectShapeCopy (Handle(GEOM_Object) theSource,
                                                         Handle(GEOM_Object) theTarget);
index f33b867217e3bfdd5bc42e6e04859244309d5062..fb47d9e4ea60edbd96321c1fffc38569d26a56e0 100644 (file)
 #include <GEOM_Function.hxx>
 #include <GEOMUtils.hxx>
 
+#include <BRepClass3d_SolidClassifier.hxx>
 #include <BRepOffsetAPI_MakeOffsetShape.hxx>
 #include <BRepOffsetAPI_MakeThickSolid.hxx>
-#include <TopoDS_Shape.hxx>
 #include <TopAbs.hxx>
 #include <TopExp.hxx>
-#include <BRepClass3d_SolidClassifier.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Shape.hxx>
 #include <Precision.hxx>
 #include <Standard_ConstructionError.hxx>
 #include <StdFail_NotDone.hxx>
@@ -88,24 +89,79 @@ Standard_Integer GEOMImpl_OffsetDriver::Execute(Handle(TFunction_Logbook)& log)
 
   if ( aType == OFFSET_SHAPE || aType == OFFSET_SHAPE_COPY )
   {
-    BRepOffsetAPI_MakeOffsetShape MO;
     BRepOffset_Mode aMode = BRepOffset_Skin;
-    Standard_Boolean anIntersection = Standard_False, aSelfInter = Standard_False;
-    MO.PerformByJoin( aShapeBase,
-                      aCI.GetValue(),
-                      aTol,
-                      aMode,
-                      anIntersection,
-                      aSelfInter,
-                      aCI.GetJoinByPipes() ? GeomAbs_Arc : GeomAbs_Intersection );
-
-    if ( MO.IsDone() ) {
-      aShape = MO.Shape();
-      if ( !GEOMUtils::CheckShape(aShape, true) && !GEOMUtils::FixShapeTolerance(aShape) )
-        Standard_ConstructionError::Raise("Boolean operation aborted : non valid shape result");
+    Standard_Boolean anIntersection = Standard_False;
+    Standard_Boolean aSelfInter = Standard_False;
+
+    Handle(TColStd_HArray1OfInteger) aFacesIDs = aCI.GetFaceIDs();
+    if (aFacesIDs.IsNull() || aFacesIDs->Length() < 1) {
+      // Offset entire shape (all faces) with the same offset value
+      BRepOffsetAPI_MakeOffsetShape MO;
+      MO.PerformByJoin( aShapeBase,
+                        anOffset,
+                        aTol,
+                        aMode,
+                        anIntersection,
+                        aSelfInter,
+                        aCI.GetJoinByPipes() ? GeomAbs_Arc : GeomAbs_Intersection );
+
+      if ( MO.IsDone() ) {
+        aShape = MO.Shape();
+        if ( !GEOMUtils::CheckShape(aShape, true) && !GEOMUtils::FixShapeTolerance(aShape) )
+          Standard_ConstructionError::Raise("Offset aborted : non valid shape result");
+      }
+      else {
+        StdFail_NotDone::Raise("Offset construction failed");
+      }
     }
     else {
-      StdFail_NotDone::Raise("Offset construction failed");
+      // Offset selected faces of main shape by given value, other faces by 0
+      BRepOffset_MakeOffset aMakeOffset;
+      aMakeOffset.Initialize(aShapeBase,
+                             anOffset, // set offset on all faces to anOffset
+                             aTol,
+                             aMode,
+                             anIntersection,
+                             aSelfInter,
+                             aCI.GetJoinByPipes() ? GeomAbs_Arc : GeomAbs_Intersection,
+                             Standard_False);
+
+      // put selected faces into a map
+      TopTools_MapOfShape aMapFaces;
+      TopTools_IndexedMapOfShape anIndices;
+      TopExp::MapShapes(aShapeBase, anIndices);
+      Standard_Integer aNbShapes = anIndices.Extent();
+      for (Standard_Integer i = aFacesIDs->Lower(); i <= aFacesIDs->Upper(); ++i) {
+        const Standard_Integer anIndex = aFacesIDs->Value(i);
+        if (anIndex < 1 || anIndex > aNbShapes) {
+          Standard_ConstructionError::Raise("Offset aborted : Invalid face index given");
+        }
+        const TopoDS_Shape &aFace = anIndices.FindKey(anIndex);
+        if (aFace.ShapeType() != TopAbs_FACE) {
+          Standard_ConstructionError::Raise("Offset aborted : Shape by index is not a face");
+        }
+        aMapFaces.Add(aFace);
+      }
+
+      // set offset on non-selected faces to zero
+      TopExp_Explorer anExp (aShapeBase, TopAbs_FACE);
+      for (; anExp.More(); anExp.Next()) {
+        const TopoDS_Shape &aFace = anExp.Current();
+        if (!aMapFaces.Contains(aFace)) {
+          aMakeOffset.SetOffsetOnFace(TopoDS::Face(aFace), 0.0);
+        }
+      }
+
+      // perform offset operation
+      aMakeOffset.MakeOffsetShape();
+      if ( aMakeOffset.IsDone() ) {
+        aShape = aMakeOffset.Shape();
+        if ( !GEOMUtils::CheckShape(aShape, true) && !GEOMUtils::FixShapeTolerance(aShape) )
+          Standard_ConstructionError::Raise("Offset aborted : non valid shape result");
+      }
+      else {
+        StdFail_NotDone::Raise("Offset construction failed");
+      }
     }
   }
   else if (aType == OFFSET_THICKENING || aType == OFFSET_THICKENING_COPY)
@@ -216,6 +272,12 @@ GetCreationInformation(std::string&             theOperationName,
     theOperationName = "OFFSET";
     AddParam( theParams, "Object", aCI.GetShape() );
     AddParam( theParams, "Offset", aCI.GetValue() );
+    {
+      Handle(TColStd_HArray1OfInteger) aFacesIDs = aCI.GetFaceIDs();
+      if (!aFacesIDs.IsNull()) {
+        AddParam(theParams, "Faces IDs", aFacesIDs);
+      }
+    }
     break;
   case OFFSET_THICKENING:
   case OFFSET_THICKENING_COPY:
index 3c7d6343fc1f556083abae3dd09fe4bb9f00d4f0..0acbdb36c94f474915affff79fa9cc414e5a7ad8 100644 (file)
@@ -1366,8 +1366,8 @@ GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* GEOM_IMeasureOperations_i:
   std::list<GEOMImpl_IMeasureOperations::CoupleOfObjects>::iterator anIter(aSelfInters.begin());
   for (Standard_Integer i = 0; i < aLength; i++, ++anIter)
   {
-    aSeq[i].first = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).first));
-    aSeq[i].second = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).second));
+    aSeq[i].first  = GetObject((*anIter).first);
+    aSeq[i].second = GetObject((*anIter).second);
   }
 
   return aSeq._retn();
@@ -1404,8 +1404,8 @@ GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* GEOM_IMeasureOperations_i:
   std::list<GEOMImpl_IMeasureOperations::CoupleOfObjects>::iterator anIter(aSelfInterf.begin());
   for (Standard_Integer i = 0; i < aLength; i++, ++anIter)
   {
-    aSeq[i].first = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).first));
-    aSeq[i].second = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).second));
+    aSeq[i].first  = GetObject((*anIter).first);
+    aSeq[i].second = GetObject((*anIter).second);
   }
 
   return aSeq._retn();
@@ -1471,8 +1471,8 @@ GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* GEOM_IMeasureOperations_i:
   std::list<GEOMImpl_IMeasureOperations::CoupleOfObjects>::iterator anIter(aDistantS.begin());
   for (Standard_Integer i = 0; i < aLength; i++, ++anIter)
   {
-    aSeq[i].first = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).first));
-    aSeq[i].second = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).second));
+    aSeq[i].first  = GetObject((*anIter).first);
+    aSeq[i].second = GetObject((*anIter).second);
   }
 
   return aSeq._retn();
@@ -1502,8 +1502,8 @@ GEOM::GEOM_IMeasureOperations::CheckResults* GEOM_IMeasureOperations_i::CheckCon
   for (Standard_Integer i = 0; i < aLength; i++, ++anIntIt)
   {
     aRes[i].type = (*anIntIt).TypeOfCheck;
-    aRes[i].failedShapes.first  = GetObject(Handle(::GEOM_Object)::DownCast((*anIntIt).FailedShapes.first));
-    aRes[i].failedShapes.second = GetObject(Handle(::GEOM_Object)::DownCast((*anIntIt).FailedShapes.second));
+    aRes[i].failedShapes.first  = GetObject((*anIntIt).FailedShapes.first);
+    aRes[i].failedShapes.second = GetObject((*anIntIt).FailedShapes.second);
   }
 
   return aRes._retn();
@@ -1530,7 +1530,7 @@ CORBA::Double GEOM_IMeasureOperations_i::UpdateTolerance(GEOM::GEOM_Object_ptr t
 void GEOM_IMeasureOperations_i::ConvertToList(const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts,
                                               std::list<GEOMImpl_IMeasureOperations::FailedChecks>& theListOfResults)
 {
-  for (Standard_Integer i = 0; i < theResuts.length(); ++i)
+  for (size_t i = 0; i < theResuts.length(); ++i)
   {
     GEOMImpl_IMeasureOperations::FailedChecks aCheck;
     aCheck.TypeOfCheck = theResuts[i].type;
index 8f866ca415a2a999ef9ef89d24ca651437f80443..c0476d415668c8831477f0c4a381ab4b5f048a9f 100644 (file)
@@ -668,6 +668,47 @@ GEOM_ITransformOperations_i::OffsetShapeCopy (GEOM::GEOM_Object_ptr theObject,
   return GetObject(anObject);
 }
 
+//=============================================================================
+/*!
+ *  OffsetShapePartialCopy
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr
+GEOM_ITransformOperations_i::OffsetShapePartialCopy (GEOM::GEOM_Object_ptr   theObject,
+                                                     CORBA::Double           theOffset,
+                                                     const GEOM::ListOfLong& theFacesIDs)
+{
+  GEOM::GEOM_Object_var aGEOMObject;
+
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+
+  //Get the basic object
+  Handle(::GEOM_Object) aBasicObject = GetObjectImpl(theObject);
+  if (aBasicObject.IsNull()) return aGEOMObject._retn();
+
+  // Get faces IDs.
+  Handle(TColStd_HArray1OfInteger) aFaceIDs;
+  Standard_Integer                 aNbIDs = theFacesIDs.length();
+  if (aNbIDs > 0) {
+    aFaceIDs = new TColStd_HArray1OfInteger (1, aNbIDs);
+    for (Standard_Integer i = 0; i < aNbIDs; i++) {
+      aFaceIDs->SetValue(i + 1, theFacesIDs[i]);
+    }
+  }
+
+  // join by pipes mode is not supported in combination with partial offset
+  bool aJoinByPipes = false;
+
+  //Create the offset shape
+  Handle(::GEOM_Object) anObject =
+    GetOperations()->OffsetShapeCopy(aBasicObject, theOffset, aJoinByPipes, aFaceIDs);
+  if (!GetOperations()->IsDone() || anObject.IsNull())
+    return aGEOMObject._retn();
+
+  return GetObject(anObject);
+}
+
 //=============================================================================
 /*!
  *  ProjectShapeCopy
index d4ad3f00f4ac529aeb9a87191d5637f66d761d3b..66f9983daaa0ce5a0a747a4e09ff46e00e308ea2 100644 (file)
@@ -142,6 +142,10 @@ class GEOM_I_EXPORT GEOM_ITransformOperations_i :
                                          CORBA::Double         theOffset,
                                          CORBA::Boolean        theJoinByPipes);
 
+  GEOM::GEOM_Object_ptr OffsetShapePartialCopy (GEOM::GEOM_Object_ptr   theObject,
+                                                CORBA::Double           theOffset,
+                                                const GEOM::ListOfLong& theFacesIDs);
+
   GEOM::GEOM_Object_ptr ProjectShapeCopy (GEOM::GEOM_Object_ptr theSource,
                                           GEOM::GEOM_Object_ptr theTarget);
 
index 7cf3edc64a4c34e8b7e9013927a28297bee6263d..e9cf78b474ea1ac71a8b25d74d767576b2ebe71a 100644 (file)
@@ -9623,6 +9623,51 @@ class geomBuilder(GEOM._objref_GEOM_Gen):
             self._autoPublish(anObj, theName, "offset")
             return anObj
 
+        ## Create new object as partial offset of the given one.
+        #  Only indexed faces are offset, others keep they original location.
+        #  Gap between adjacent offset surfaces is filled
+        #  by extending and intersecting them.
+        #  @param theObject The base object for the offset.
+        #  @param theOffset Offset value.
+        #  @param theFacesIDs The list of face IDs indicating faces to be offset.
+        #  @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 offset object.
+        #
+        #  @ref tui_offset "Example"
+        @ManageTransactions("TrsfOp")
+        def MakeOffsetPartial(self, theObject, theOffset, theFacesIDs, theName=None):
+            """
+            Create new object as partial offset of the given one.
+            Only indexed faces are offset, others keep they original location.
+            Gap between adjacent offset surfaces is filled
+            by extending and intersecting them.
+
+            Parameters:
+                theObject The base object for the offset.
+                theOffset Offset value.
+                theFacesIDs The list of face IDs indicating faces to be offset.
+                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 offset object.
+
+            Example of usage:
+                 box = geompy.MakeBox(20, 20, 20, 200, 200, 200)
+                 # create a new object from the box, offsetting its top and front faces
+                 offset = geompy.MakeOffsetPartial(box, 70., [13, 33])
+            """
+            theOffset, Parameters = ParseParameters(theOffset)
+            anObj = self.TrsfOp.OffsetShapePartialCopy(theObject, theOffset, theFacesIDs)
+            RaiseIfFailed("OffsetShapePartialCopy", self.TrsfOp)
+            anObj.SetParameters(Parameters)
+            self._autoPublish(anObj, theName, "offset")
+            return anObj
+
         ## Create new object as projection of the given one on another.
         #  @param theSource The source object for the projection. It can be a point, edge or wire.
         #         Edge and wire are acceptable if @a theTarget is a face.
index 523c7b62f5bbe1447c9b8fc5e4802df6dc7154ef..d257792adcc5f4301b1c22863812679452793ce5 100644 (file)
@@ -35,6 +35,9 @@
 #include <SalomeApp_Application.h>
 #include <LightApp_SelectionMgr.h>
 
+#include <TopExp.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+
 //=================================================================================
 // class    : TransformationGUI_OffsetDlg()
 // purpose  : Constructs a TransformationGUI_OffsetDlg which is a child of 'parent', with the
 //            The dialog will by default be modeless, unless you set 'modal' to
 //            TRUE to construct a modal dialog.
 //=================================================================================
-TransformationGUI_OffsetDlg::TransformationGUI_OffsetDlg( GeometryGUI* theGeometryGUI, QWidget* parent,
-                                                          bool modal, Qt::WindowFlags fl )
-  : GEOMBase_Skeleton( theGeometryGUI, parent, modal, fl )
+TransformationGUI_OffsetDlg::TransformationGUI_OffsetDlg
+                             (GeometryGUI* theGeometryGUI, QWidget* parent,
+                              bool modal, Qt::WindowFlags fl)
+  : GEOMBase_Skeleton(theGeometryGUI, parent, modal, fl)
 {
-  QPixmap image0( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_OFFSET" ) ) );
-  QPixmap image1( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) );
+  SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
+  QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
+  QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_OFFSET")));
+  QPixmap image2 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_OFFSET_PARTIAL")));
 
-  setWindowTitle( tr( "GEOM_OFFSET_TITLE" ) );
+  setWindowTitle(tr("GEOM_OFFSET_TITLE"));
 
   /***************************************************************/
-  mainFrame()->GroupConstructors->setTitle( tr( "GEOM_OFFSET" ) );
-  mainFrame()->RadioButton1->setIcon( image0 );
-  mainFrame()->RadioButton2->setAttribute( Qt::WA_DeleteOnClose );
-  mainFrame()->RadioButton2->close();
-  mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose );
+  mainFrame()->GroupConstructors->setTitle(tr("GEOM_OFFSET"));
+  mainFrame()->RadioButton1->setIcon(image1);
+  mainFrame()->RadioButton2->setIcon(image2);
+  mainFrame()->RadioButton1->setToolTip(tr("TOOLTIP_OFFSET"));
+  mainFrame()->RadioButton2->setToolTip(tr("TOOLTIP_OFFSET_PARTIAL"));
+  mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose);
   mainFrame()->RadioButton3->close();
+  mainFrame()->RadioButton1->setChecked(true);
+
+  GroupPoints = new DlgRef_2Sel1Spin2Check( centralWidget() );
 
-  GroupPoints = new DlgRef_1Sel1Spin1Check( centralWidget() );
   GroupPoints->GroupBox1->setTitle( tr( "GEOM_ARGUMENTS" ) );
+
   GroupPoints->TextLabel1->setText( tr( "GEOM_OBJECTS" ) );
-  GroupPoints->TextLabel2->setText( tr( "GEOM_OFFSET" ) );
+  GroupPoints->TextLabel2->setText( tr( "GEOM_FACES" ) );
+  GroupPoints->TextLabel3->setText( tr( "GEOM_OFFSET" ) );
+
+  GroupPoints->PushButton1->setIcon( image0 );
+  GroupPoints->PushButton2->setIcon( image0 );
+
   GroupPoints->CheckButton1->setText( tr( "GEOM_JOIN_BY_PIPES" ) );
   GroupPoints->CheckButton1->setChecked( true );
-
-  GroupPoints->PushButton1->setIcon( image1 );
+  GroupPoints->CheckButton2->setAttribute( Qt::WA_DeleteOnClose );
+  GroupPoints->CheckButton2->close();
 
   QVBoxLayout* layout = new QVBoxLayout( centralWidget() );
   layout->setMargin( 0 ); layout->setSpacing( 6 );
@@ -99,33 +114,76 @@ void TransformationGUI_OffsetDlg::Init()
   /* init variables */
   myEditCurrentArgument = GroupPoints->LineEdit1;
   GroupPoints->LineEdit1->setReadOnly( true );
+  GroupPoints->LineEdit2->setReadOnly( true );
 
   myObjects.clear();
-
-  /* Get setting of step value from file configuration */
-  double step = 1;
+  myFaces.clear();
 
   /* min, max, step and decimals for spin boxes & initial values */
+  double step = 1;
   initSpinBox( GroupPoints->SpinBox_DX, COORD_MIN, COORD_MAX, step, "length_precision" );
   GroupPoints->SpinBox_DX->setValue( 1e-05 );
 
   mainFrame()->GroupBoxPublish->show();
 
   /* signals and slots connections */
-  connect( buttonOk(),    SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
-  connect( buttonApply(), SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
+  connect(buttonOk(),    SIGNAL(clicked()), this, SLOT(ClickOnOk()));
+  connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
+  connect(this,          SIGNAL(constructorsClicked(int)),
+          this,          SLOT(ConstructorsClicked(int)));
 
-  connect( GroupPoints->PushButton1, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
-  connect( myGeomGUI->getApp()->selectionMgr(),
-           SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
+  connect(GroupPoints->PushButton1, SIGNAL(clicked()),
+          this,                     SLOT(SetEditCurrentArgument()));
+  connect(GroupPoints->PushButton2, SIGNAL(clicked()),
+          this,                     SLOT(SetEditCurrentArgument()));
 
-  connect( GroupPoints->SpinBox_DX,   SIGNAL( valueChanged( double ) ), this, SLOT( ValueChangedInSpinBox() ) );
-  connect( GroupPoints->CheckButton1, SIGNAL( toggled( bool ) ),        this, SLOT( JoinModeChanged() ) );
+  connect(GroupPoints->SpinBox_DX,   SIGNAL(valueChanged(double)),
+          this,                      SLOT(ValueChangedInSpinBox()));
+  connect(GroupPoints->CheckButton1, SIGNAL(toggled(bool)),
+          this,                      SLOT(JoinModeChanged()));
 
-  initName( tr( "GEOM_OFFSET" ) );
+  connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
+          this,                                SLOT(SelectionIntoArgument()));
 
-  globalSelection( GEOM_ALLSHAPES );
-  resize(100,100);
+  initName(tr("GEOM_OFFSET"));
+
+  ConstructorsClicked(0);
+}
+
+//==============================================================================
+// function : ConstructorsClicked()
+// purpose  : Radio button management
+//==============================================================================
+void TransformationGUI_OffsetDlg::ConstructorsClicked (int constructorId)
+{
+  switch (constructorId) {
+  case 0:
+    // disable faces selection
+    GroupPoints->TextLabel2->hide();
+    GroupPoints->PushButton2->hide();
+    GroupPoints->LineEdit2->hide();
+
+    // enable joint type
+    GroupPoints->CheckButton1->show();
+    break;
+  case 1:
+    // enable faces selection
+    GroupPoints->TextLabel2->show();
+    GroupPoints->PushButton2->show();
+    GroupPoints->LineEdit2->show();
+
+    // disable joint type
+    GroupPoints->CheckButton1->hide();
+    break;
+  default:
+    break;
+  }
+
+  qApp->processEvents();
+  updateGeometry();
+  resize(minimumSizeHint());
+
+  GroupPoints->PushButton1->click();
   SelectionIntoArgument();
 }
 
@@ -152,6 +210,10 @@ bool TransformationGUI_OffsetDlg::ClickOnApply()
     return false;
 
   initName();
+
+  // activate selection and connect selection manager
+  ConstructorsClicked(getConstructorId());
+
   return true;
 }
 
@@ -162,13 +224,27 @@ bool TransformationGUI_OffsetDlg::ClickOnApply()
 //=================================================================================
 void TransformationGUI_OffsetDlg::SelectionIntoArgument()
 {
-  myObjects = getSelected( TopAbs_SHAPE, -1 );
-  if ( !myObjects.isEmpty() ) {
-    QString aName = myObjects.count() > 1 ? QString( "%1_objects").arg( myObjects.count() ) : GEOMBase::GetName( myObjects[0].get() );
-    myEditCurrentArgument->setText( aName );
+  myEditCurrentArgument->setText("");
+
+  if (myEditCurrentArgument == GroupPoints->LineEdit1) {
+    if (getConstructorId() == 0) {
+      myObjects = getSelected( TopAbs_SHAPE, -1 );
+      myEditCurrentArgument->setText(GEOMBase::GetName(myObjects));
+    }
+    else if (getConstructorId() == 1) {
+      myFaces.clear();
+      GroupPoints->LineEdit2->setText("");
+      myObjects = getSelected(TopAbs_SHAPE, 1); // only one object allowed
+      if (!myObjects.isEmpty()) {
+        myEditCurrentArgument->setText(GEOMBase::GetName(myObjects[0].get()));
+        GroupPoints->PushButton2->click();
+      }
+    }
   }
-  else {
-    myEditCurrentArgument->setText("");
+  else if (myEditCurrentArgument == GroupPoints->LineEdit2) {
+    myFaces.clear();
+    myFaces = getSelected(TopAbs_FACE, -1);
+    myEditCurrentArgument->setText(GEOMBase::GetName(myFaces));
   }
 
   processPreview();
@@ -184,11 +260,20 @@ void TransformationGUI_OffsetDlg::SetEditCurrentArgument()
   QPushButton* send = (QPushButton*)sender();
 
   if ( send == GroupPoints->PushButton1 ) {
-    GroupPoints->PushButton1->setDown(true);
+    GroupPoints->PushButton2->setDown(false);
     myEditCurrentArgument = GroupPoints->LineEdit1;
-    myEditCurrentArgument->setFocus();
-    SelectionIntoArgument();
+    globalSelection(GEOM_ALLSHAPES);
   }
+  else if (send == GroupPoints->PushButton2) {
+    GroupPoints->PushButton1->setDown(false);
+    myEditCurrentArgument = GroupPoints->LineEdit2;
+    globalSelection(); // close local contexts, if any
+    if (myObjects.size() > 0)
+      localSelection(myObjects[0].get(), TopAbs_FACE);
+  }
+
+  myEditCurrentArgument->setFocus();
+  send->setDown(true);
 }
 
 
@@ -210,11 +295,11 @@ void TransformationGUI_OffsetDlg::enterEvent( QEvent* )
 void TransformationGUI_OffsetDlg::ActivateThisDialog()
 {
   GEOMBase_Skeleton::ActivateThisDialog();
+
   connect( myGeomGUI->getApp()->selectionMgr(),
            SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
-  globalSelection( GEOM_ALLSHAPES );
-  myEditCurrentArgument = GroupPoints->LineEdit1;
-  myEditCurrentArgument->setFocus();
+
+  ConstructorsClicked(getConstructorId());
 }
 
 
@@ -243,14 +328,27 @@ GEOM::GEOM_IOperations_ptr TransformationGUI_OffsetDlg::createOperation()
 //=================================================================================
 bool TransformationGUI_OffsetDlg::isValid( QString& msg )
 {
-  bool ok = GroupPoints->SpinBox_DX->isValid( msg, !IsPreview() ) && !myObjects.isEmpty();
-  for ( int i = 0; i < myObjects.count() && ok; i++ ) {
-    GEOM::shape_type aType = myObjects[i]->GetShapeType();
-    ok = aType == GEOM::FACE || aType == GEOM::SHELL || aType == GEOM::SOLID;
-    if ( !ok )
-      msg = tr( "ERROR_SHAPE_TYPE" );
+  bool isOk = GroupPoints->SpinBox_DX->isValid( msg, !IsPreview() ) && !myObjects.isEmpty();
+
+  if (isOk) {
+    switch (getConstructorId()) {
+    case 0:
+      for ( int i = 0; i < myObjects.count() && isOk; i++ ) {
+        GEOM::shape_type aType = myObjects[i]->GetShapeType();
+        isOk = aType == GEOM::FACE || aType == GEOM::SHELL || aType == GEOM::SOLID;
+        if ( !isOk )
+          msg = tr( "ERROR_SHAPE_TYPE" );
+      }
+      break;
+    case 1:
+      isOk = myObjects.size() == 1 && !myFaces.isEmpty();
+      break;
+    default:
+      break;
+    }
   }
-  return ok;
+
+  return isOk;
 }
 
 //=================================================================================
@@ -263,28 +361,59 @@ bool TransformationGUI_OffsetDlg::execute( ObjectList& objects )
 
   GEOM::GEOM_Object_var anObj;
 
-  GEOM::GEOM_ITransformOperations_var anOper = GEOM::GEOM_ITransformOperations::_narrow(getOperation());
+  GEOM::GEOM_ITransformOperations_var anOper =
+    GEOM::GEOM_ITransformOperations::_narrow(getOperation());
 
-  if ( true /*GroupPoints->CheckButton1->isChecked() || IsPreview()*/ ) {
-    for ( int i = 0; i < myObjects.count(); i++ ) {
-
-      anObj = anOper->OffsetShapeCopy( myObjects[i].get(), GetOffset(), GetIsJoinByPipes() );
-      if ( !anObj->_is_nil() ) {
-        if(!IsPreview()) {
+  if (getConstructorId() == 0) {
+    for (int i = 0; i < myObjects.count(); i++) {
+      anObj = anOper->OffsetShapeCopy(myObjects[i].get(), GetOffset(), GetIsJoinByPipes());
+      if (!anObj->_is_nil()) {
+        if (!IsPreview()) {
           anObj->SetParameters(GroupPoints->SpinBox_DX->text().toUtf8().constData());
         }
-        objects.push_back( anObj._retn() );
+        objects.push_back(anObj._retn());
+        res = true;
       }
     }
   }
-  else {
-    for ( int i = 0; i < myObjects.count(); i++ ) {
-      anObj = anOper->OffsetShape( myObjects[i].get(), GetOffset(), GetIsJoinByPipes()  );
-      if ( !anObj->_is_nil() )
-        objects.push_back( anObj._retn() );
+  else if (getConstructorId() == 1) {
+    if (myObjects.count() == 1) {
+      TopoDS_Shape aShape;
+      if (GEOMBase::GetShape(myObjects[0].get(), aShape)) {
+        TopTools_IndexedMapOfShape aMainMap;
+        TopExp::MapShapes(aShape, aMainMap);
+
+        QList<int> aListIDs;
+        for (int i = 0; i < myFaces.count(); i++) {
+          TopoDS_Shape aFace;
+          if (GEOMBase::GetShape(myFaces[i].get(), aFace)) {
+            int anIndex = aMainMap.FindIndex(aFace);
+            if (anIndex >= 0) {
+              aListIDs << anIndex;
+            }
+          }
+        }
+
+        GEOM::ListOfLong_var aFacesIDsList = new GEOM::ListOfLong();
+        if (!aListIDs.empty()) {
+          aFacesIDsList->length(aListIDs.length());
+          for (int i = 0; i < aListIDs.length(); i++) {
+            aFacesIDsList[i] = aListIDs[i];
+          }
+        }
+
+        anObj = anOper->OffsetShapePartialCopy
+          (myObjects[0].get(), GetOffset(), aFacesIDsList);
+        if (!anObj->_is_nil()) {
+          if (!IsPreview()) {
+            anObj->SetParameters(GroupPoints->SpinBox_DX->text().toUtf8().constData());
+          }
+          objects.push_back(anObj._retn());
+          res = true;
+        }
+      }
     }
   }
-  res = true;
 
   return res;
 }
@@ -330,7 +459,6 @@ bool TransformationGUI_OffsetDlg::GetIsJoinByPipes() const
 void TransformationGUI_OffsetDlg::JoinModeChanged()
 {
   processPreview();
-  //mainFrame()->GroupBoxName->setEnabled( GroupPoints->CheckButton1->isChecked() );
 }
 
 //=================================================================================
index b23938044e7be4cf1de987a196ce8a7dd8b8aa8e..9407a3e78b2ce42c9bd230e9dea41bf2f6b77c9d 100644 (file)
 #include "GEOMBase_Skeleton.h"
 #include "GEOM_GenericObjPtr.h"
 
-class DlgRef_1Sel1Spin1Check;  
-  
+class DlgRef_2Sel1Spin2Check;
+
 //=================================================================================
 // class    : TransformationGUI_OffsetDlg
 // purpose  :
 //=================================================================================
 class TransformationGUI_OffsetDlg : public GEOMBase_Skeleton
-{ 
+{
   Q_OBJECT
 
 public:
@@ -52,24 +52,26 @@ protected:
   virtual bool                       execute( ObjectList& );
   virtual void                       restoreSubShapes( SALOMEDS::SObject_ptr );
   virtual QList<GEOM::GeomObjPtr>    getSourceObjects();
-  
+
 private:
   void                               Init();
   void                               enterEvent( QEvent* );
   double                             GetOffset() const;
   bool                               GetIsJoinByPipes() const;
-    
+
 private:
   QList<GEOM::GeomObjPtr>            myObjects;
-    
-  DlgRef_1Sel1Spin1Check*            GroupPoints;
-    
+  QList<GEOM::GeomObjPtr>            myFaces;
+
+  DlgRef_2Sel1Spin2Check*            GroupPoints;
+
 private slots:
   void                               ClickOnOk();
   bool                               ClickOnApply();
   void                               ActivateThisDialog();
   void                               SelectionIntoArgument();
   void                               SetEditCurrentArgument();
+  void                               ConstructorsClicked(int);
   void                               ValueChangedInSpinBox();
   void                               JoinModeChanged();
 };