Salome HOME
0022666: EDF 7253 GEOM: Add thickness to a shell and integrate BrepOffsetAPI_MakeThic...
authorskv <skv@opencascade.com>
Mon, 16 Mar 2015 14:23:18 +0000 (17:23 +0300)
committervsr <vsr@opencascade.com>
Wed, 18 Mar 2015 07:37:36 +0000 (10:37 +0300)
31 files changed:
doc/salome/examples/CMakeLists.txt
doc/salome/examples/complex_objs_ex11.py [new file with mode: 0755]
doc/salome/gui/GEOM/images/thickness.png [new file with mode: 0644]
doc/salome/gui/GEOM/images/thickness_result.png [new file with mode: 0644]
doc/salome/gui/GEOM/images/thicksolid.png [new file with mode: 0644]
doc/salome/gui/GEOM/images/thicksolid_result.png [new file with mode: 0644]
doc/salome/gui/GEOM/input/creating_complex_obj.doc
doc/salome/gui/GEOM/input/creating_thickness_page.doc [new file with mode: 0644]
doc/salome/gui/GEOM/input/tui_complex_objs.doc
doc/salome/gui/GEOM/input/tui_test_all.doc
idl/GEOM_Gen.idl
resources/CMakeLists.txt
resources/thickness.png [new file with mode: 0644]
resources/thickness2.png [new file with mode: 0644]
src/GEOMGUI/GEOM_images.ts
src/GEOMGUI/GEOM_msg_en.ts
src/GEOMGUI/GeometryGUI.cxx
src/GEOMGUI/GeometryGUI_Operations.h
src/GEOMImpl/GEOMImpl_I3DPrimOperations.cxx
src/GEOMImpl/GEOMImpl_I3DPrimOperations.hxx
src/GEOMImpl/GEOMImpl_IOffset.hxx
src/GEOMImpl/GEOMImpl_OffsetDriver.cxx
src/GEOM_I/GEOM_I3DPrimOperations_i.cc
src/GEOM_I/GEOM_I3DPrimOperations_i.hh
src/GEOM_SWIG/GEOM_TestAll.py
src/GEOM_SWIG/geomBuilder.py [changed mode: 0755->0644]
src/GenerationGUI/CMakeLists.txt
src/GenerationGUI/GenerationGUI.cxx
src/GenerationGUI/GenerationGUI_PrismDlg.cxx
src/GenerationGUI/GenerationGUI_ThicknessDlg.cxx [new file with mode: 0644]
src/GenerationGUI/GenerationGUI_ThicknessDlg.h [new file with mode: 0644]

index 5ba409fb9e9dbbff09b4f24924946e05bb0398ad..6a0baa09a4ae3271048aa0cd0bf16165ff1f8608 100644 (file)
@@ -67,6 +67,7 @@ SET(GOOD_TESTS
   complex_objs_ex08.py  
   complex_objs_ex09.py  
   complex_objs_ex10.py
+  complex_objs_ex11.py
   free_boundaries.py  
   free_faces.py  
   GEOM_box.py  
diff --git a/doc/salome/examples/complex_objs_ex11.py b/doc/salome/examples/complex_objs_ex11.py
new file mode 100755 (executable)
index 0000000..6324233
--- /dev/null
@@ -0,0 +1,39 @@
+# Apply thickness for shell
+
+import salome
+salome.salome_init()
+import GEOM
+from salome.geom import geomBuilder
+geompy = geomBuilder.New(salome.myStudy)
+gg = salome.ImportComponentGUI("GEOM")
+
+# create box
+box = geompy.MakeBoxDXDYDZ(100, 100, 100)
+
+# get the list of faces
+faces = geompy.SubShapeAllSortedCentres(box, geompy.ShapeType["FACE"])
+
+# get the list of face IDs
+faceIDs = geompy.SubShapeAllSortedCentresIDs(box, geompy.ShapeType["FACE"])
+
+# make a shell from 3 faces
+shell = geompy.MakeShell([faces[0], faces[1], faces[2]])
+
+# apply thickness
+solid = geompy.MakeThickSolid(shell, 30.)
+
+# create box
+hsolid = geompy.MakeBoxDXDYDZ(100, 100, 100)
+
+# make hollowed solid
+geompy.Thicken(hsolid, 30., [faceIDs[0], faceIDs[1]])
+
+# add objects in the study
+id_shell  = geompy.addToStudy(shell, "Shell")
+id_solid  = geompy.addToStudy(solid, "Solid")
+id_hsolid = geompy.addToStudy(hsolid, "Hollowed Solid")
+
+# display the shell and the result thicknen solid and hollowed solid
+gg.createAndDisplayGO(id_shell)
+gg.createAndDisplayGO(id_solid)
+gg.createAndDisplayGO(id_hsolid)
diff --git a/doc/salome/gui/GEOM/images/thickness.png b/doc/salome/gui/GEOM/images/thickness.png
new file mode 100644 (file)
index 0000000..5277857
Binary files /dev/null and b/doc/salome/gui/GEOM/images/thickness.png differ
diff --git a/doc/salome/gui/GEOM/images/thickness_result.png b/doc/salome/gui/GEOM/images/thickness_result.png
new file mode 100644 (file)
index 0000000..47ec5a0
Binary files /dev/null and b/doc/salome/gui/GEOM/images/thickness_result.png differ
diff --git a/doc/salome/gui/GEOM/images/thicksolid.png b/doc/salome/gui/GEOM/images/thicksolid.png
new file mode 100644 (file)
index 0000000..079a754
Binary files /dev/null and b/doc/salome/gui/GEOM/images/thicksolid.png differ
diff --git a/doc/salome/gui/GEOM/images/thicksolid_result.png b/doc/salome/gui/GEOM/images/thicksolid_result.png
new file mode 100644 (file)
index 0000000..6a6087a
Binary files /dev/null and b/doc/salome/gui/GEOM/images/thicksolid_result.png differ
index a5c6a090f8a8b788db565d032d0b71aca136642a..6630dfa72193a1689db8859e8bbb3d9b916fa001 100644 (file)
@@ -15,6 +15,7 @@ axis, creating a body of revolution.</li>
 <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>
 </ul>
 
 <b> New entity -> Advanced </b> sub-menu allows creating new geometric
diff --git a/doc/salome/gui/GEOM/input/creating_thickness_page.doc b/doc/salome/gui/GEOM/input/creating_thickness_page.doc
new file mode 100644 (file)
index 0000000..140c02f
--- /dev/null
@@ -0,0 +1,46 @@
+/*!
+
+\page create_thickness_page Thickness Construction
+
+To add a \b Thickness to a shape in the <b>Main Menu</b> select <b>New Entity - > Generation  - > Thickness</b>
+\n
+It is possible to create a Solid from a Face or a Shell by applying a
+\b Thickness. To do it you should define an \b Object that is a Face or a
+Shell, \b Thickness and to define the thickness direction by means of
+<b>Thicken towards the inside</b> check box.
+
+\image html thickness.png
+
+<b>Example:</b>
+
+\image html thickness_result.png "Thickness of Shell"
+
+It is possible to apply \b Thickness to a Solid. The result of this operation
+is the hollowed Solid. To do it you should define an \b Object that is a Solid,
+\b Faces to be removed from result, \b Thickness and the thickness direction by
+means of <b>Thicken towards the inside</b> check box.
+
+\image html thicksolid.png
+
+<b>Example:</b>
+
+\image html thicksolid_result.png "Thickness of Solid"
+
+\n <b>TUI Commands:</b>
+\n
+<em>geompy.MakeThickSolid(theShape, theThickness, theFacesIDs=[])</em> -
+Makes a thick solid from a shape;
+\n
+<em>geompy.Thicken(theShape, theThickness, theFacesIDs=[])</em> -
+Modifies a shape to make it a thick solid.
+
+<b>Arguments:</b> Name + 1 shape (face, shell or solid) + thickness +
+the list of face IDs.
+\n If the shape is face or shell the list of face IDs is not used.
+The thickness can be positive or negative for thicken towards the inside.
+\n\n <b>Advanced options</b> \ref preview_anchor "Preview"
+
+Our <b>TUI Scripts</b> provide you with useful examples of creation of
+\ref tui_creation_thickness "Complex Geometric Objects".
+
+*/
index 61ce18b5a126d1aa268b8735674cb46d87f98225..3ced40bcacf7fd616b5777c4652e46202988c075 100644 (file)
@@ -42,4 +42,8 @@
 <br><h2>Creation of Tangent Plane On Face</h2>
 \tui_script{complex_objs_ex10.py}
 
+\anchor tui_creation_thickness
+<br><h2>Applying a Thickness to Face, Shell or Solid</h2>
+\tui_script{complex_objs_ex11.py}
+
 */
index 1718afb0043bb3d64929ae19ab9482eb3250ce7a..b1f915ea2524e1d94fd7a605cc285de51e3bea6b 100644 (file)
@@ -49,7 +49,7 @@
 \until Line3
 
 \anchor swig_all_advanced
-\until MakeSewing
+\until Thicken
 
 \anchor swig_MakeCopy
 \until MakeCopy
index 4b54e4ddd20883d25ed6c4faee48d68693f53945..9bdfda2b23da4f802093e7f94296f1409eea7318 100644 (file)
@@ -1829,16 +1829,24 @@ module GEOM
 
 
      /*!
-     *  \brief Make a thick solid from a surface shape (face or shell)
-     *  \param theObject Surface from which the thick solid is made
+     *  \brief Make 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 a solid the result is a hollowed
+     *  solid with removed faces.
+     *  \param theObject face or shell to get thick solid or solid to get
+     *         hollowed solid.
+     *  \param theFacesIDs the list of face IDs to be removed from the result.
+     *          It can be empty.
      *  \param theThickness Value of the thickness
-     *  \param isCopy To make a copy of \a theObject ot to modify \a theObject.
+     *  \param isCopy To make a copy of \a theObject or to modify \a theObject
      *  \return New GEOM_Object, containing the created pipe if isCopy = true
      *          or the modified object if isCopy = false
      */
     GEOM_Object MakeThickening (in GEOM_Object theObject,
-                                in double theThickness,
-                                in boolean isCopy);
+                                in ListOfLong  theFacesIDs,
+                                in double      theThickness,
+                                in boolean     isCopy);
 
     
     /*!
index 87d7e929a8b179d46cea5aa8e1a59a250f1770b6..3a1bb3200c155887cf81df7bde30c01d704992ab 100755 (executable)
@@ -180,6 +180,8 @@ SET( _res_files
   supressHolesOnFaceShell.png
   supressface.png
   supresshole.png
+  thickness.png
+  thickness2.png
   tolerance.png
   torus.png
   torusdxyz.png
diff --git a/resources/thickness.png b/resources/thickness.png
new file mode 100644 (file)
index 0000000..bee2928
Binary files /dev/null and b/resources/thickness.png differ
diff --git a/resources/thickness2.png b/resources/thickness2.png
new file mode 100644 (file)
index 0000000..31b9e56
Binary files /dev/null and b/resources/thickness2.png differ
index 84876a3b7ca5c62fae1b21e55aff9b7cbc28c57f..489aaa5aa00e476e2f3f646eaceff3e515d5d97f 100644 (file)
             <source>ICON_DLG_PRISM_DXDYDZ</source>
             <translation>prism3.png</translation>
         </message>
+        <message>
+            <source>ICON_DLG_THICKNESS</source>
+            <translation>thickness.png</translation>
+        </message>
+        <message>
+            <source>ICON_DLG_THICKNESS_HOLLOWED</source>
+            <translation>thickness2.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_PROPAGATE</source>
             <translation>propagate.png</translation>
             <source>ICO_EXTRUSION</source>
             <translation>prism.png</translation>
         </message>
+        <message>
+            <source>ICO_THICKNESS</source>
+            <translation>thickness.png</translation>
+        </message>
         <message>
             <source>ICO_FACE</source>
             <translation>build_face.png</translation>
index d5bdf3e5fa509f9c9abd4934d22716dad89a2860..3d0ebd610cef00c81cb53772cf420b2c0a2bd317 100644 (file)
@@ -675,6 +675,18 @@ Please, select face, shell or solid and try again</translation>
         <source>GEOM_EXTRUSION_TITLE</source>
         <translation>Construction by Extrusion</translation>
     </message>
+    <message>
+        <source>GEOM_THICKNESS_TITLE</source>
+        <translation>Thickness Construction</translation>
+    </message>
+    <message>
+        <source>GEOM_THICKNESS_NAME</source>
+        <translation>Thickness</translation>
+    </message>
+    <message>
+        <source>GEOM_TOWARDS_INSIDE</source>
+        <translation>Thicken towards the inside</translation>
+    </message>
     <message>
         <source>GEOM_SCALE_PRISM</source>
         <translation>Scale the face opposite to the base</translation>
@@ -2852,6 +2864,10 @@ Please, select face, shell or solid and try again</translation>
         <source>MEN_PIPE_PATH</source>
         <translation>Restore Path</translation>
     </message>
+    <message>
+        <source>MEN_THICKNESS</source>
+        <translation>Thickness</translation>
+    </message>
     <message>
         <source>MEN_PLANE</source>
         <translation>Plane</translation>
@@ -3800,6 +3816,10 @@ Please, select face, shell or solid and try again</translation>
         <source>STB_PIPE_PATH</source>
         <translation>Restore path from a pipe-like shape</translation>
     </message>
+    <message>
+        <source>STB_THICKNESS</source>
+        <translation>Make a thick solid</translation>
+    </message>
     <message>
         <source>STB_PLANE</source>
         <translation>Create a plane</translation>
@@ -4416,6 +4436,10 @@ Please, select face, shell or solid and try again</translation>
         <source>TOP_PIPE_PATH</source>
         <translation>Restore path</translation>
     </message>
+    <message>
+        <source>TOP_THICKNESS</source>
+        <translation>Thickness</translation>
+    </message>
     <message>
         <source>TOP_PLANE</source>
         <translation>Create a plane</translation>
@@ -6039,10 +6063,6 @@ Number of sketch points too small</translation>
         <source>GEOM_ADD_THICKNESS</source>
         <translation>Add thickness (edges or wires only)</translation>
     </message>
-    <message>
-        <source>GEOM_TOWARDS_INSIDE</source>
-        <translation>Thicken towards the inside</translation>
-    </message>
 </context>
 <context>
     <name>GroupGUI</name>
index 013b9abc0cb63aae65bd5b612ef5a86ac628486a..526eeaac507160c8cbf8f8e78c7a8e1c3ff023dd 100644 (file)
@@ -548,6 +548,7 @@ void GeometryGUI::OnGUIEvent( int id, const QVariant& theParam )
   case GEOMOp::OpFilling:            // MENU GENERATION - FILLING
   case GEOMOp::OpPipe:               // MENU GENERATION - PIPE
   case GEOMOp::OpPipePath:           // MENU GENERATION - RESTORE PATH
+  case GEOMOp::OpThickness:          // MENU GENERATION - THICKNESS
     libName = "GenerationGUI";
     break;
   case GEOMOp::Op2dSketcher:         // MENU ENTITY - SKETCHER
@@ -921,6 +922,7 @@ void GeometryGUI::initialize( CAM_Application* app )
   createGeomAction( GEOMOp::OpFilling,     "FILLING" );
   createGeomAction( GEOMOp::OpPipe,        "PIPE" );
   createGeomAction( GEOMOp::OpPipePath,    "PIPE_PATH" );
+  createGeomAction( GEOMOp::OpThickness,   "THICKNESS" );
 
   createGeomAction( GEOMOp::OpGroupCreate, "GROUP_CREATE" );
   createGeomAction( GEOMOp::OpGroupEdit,   "GROUP_EDIT" );
@@ -1144,6 +1146,7 @@ void GeometryGUI::initialize( CAM_Application* app )
   createMenu( GEOMOp::OpFilling,    genId, -1 );
   createMenu( GEOMOp::OpPipe,       genId, -1 );
   createMenu( GEOMOp::OpPipePath,   genId, -1 );
+  createMenu( GEOMOp::OpThickness,  genId, -1 );
 
   //int advId = createMenu( tr( "MEN_ADVANCED" ), newEntId, -1 );
   //createMenu( GEOMOp::OpSmoothingSurface, advId, -1 );
@@ -1372,6 +1375,7 @@ void GeometryGUI::initialize( CAM_Application* app )
   createTool( GEOMOp::OpFilling,    genTbId );
   createTool( GEOMOp::OpPipe,       genTbId );
   createTool( GEOMOp::OpPipePath,   genTbId );
+  createTool( GEOMOp::OpThickness,  genTbId );
 
   int transTbId = createTool( tr( "TOOL_TRANSFORMATION" ), QString( "GEOMTransformation" ) );
   createTool( GEOMOp::OpTranslate,      transTbId );
index f7b545c98ef5d59400b148196d4445fb48273d46..2acdd53f41988a4903464f7790e47ac1083f0f10 100644 (file)
@@ -111,6 +111,7 @@ namespace GEOMOp {
     OpFilling             = 3202,   // MENU NEW ENTITY - GENERATION - FILLING
     OpPipe                = 3203,   // MENU NEW ENTITY - GENERATION - EXTRUSION ALONG PATH
     OpPipePath            = 3204,   // MENU NEW ENTITY - GENERATION - RESTORE PATH
+    OpThickness           = 3205,   // MENU NEW ENTITY - GENERATION - THICKNESS
     // EntityGUI -------------------//--------------------------------
     Op2dSketcher          = 3300,   // MENU NEW ENTITY - SKETCHER
     Op3dSketcher          = 3301,   // MENU NEW ENTITY - 3D SKETCHER
index 55c46b26fe480283d7072bdcc214769b42fd240f..6cc3e28d9544fedfd15e489387725d8ebf770737 100644 (file)
@@ -2287,9 +2287,11 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeBiNormalAlongVector (Han
  *  MakeThickening
  */
 //=============================================================================
-Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeThickening(Handle(GEOM_Object) theObject,
-                                                              double theOffset,
-                                                              bool copy = true)
+Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeThickening
+                (Handle(GEOM_Object)                     theObject,
+                 const Handle(TColStd_HArray1OfInteger) &theFacesIDs,
+                 double                                  theOffset,
+                 bool                                    isCopy)
 {
   SetErrorCode(KO);
 
@@ -2301,7 +2303,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeThickening(Handle(GEOM_Objec
   //Add a new Offset function
   Handle(GEOM_Function) aFunction;
   Handle(GEOM_Object) aCopy; 
-  if (copy)
+  if (isCopy)
   { 
     //Add a new Copy object
     aCopy = GetEngine()->AddObject(GetDocID(), theObject->GetType());
@@ -2319,6 +2321,10 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeThickening(Handle(GEOM_Objec
   aTI.SetShape(anOriginal);
   aTI.SetValue(theOffset);
 
+  if (theFacesIDs.IsNull() == Standard_False) {
+    aTI.SetFaceIDs(theFacesIDs);
+  }
+
   //Compute the offset
   try {
     OCC_CATCH_SIGNALS;
@@ -2334,20 +2340,36 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeThickening(Handle(GEOM_Objec
   }
 
   //Make a Python command
-  if(copy)
-  {
-    GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeThickSolid("
-                               << theObject << ", " << theOffset << ")";
-    SetErrorCode(OK);
-    return aCopy;
+  GEOM::TPythonDump   pd (aFunction);
+  Handle(GEOM_Object) aResult; 
+
+  if (isCopy) {
+    pd << aCopy << " = geompy.MakeThickSolid("
+       << theObject << ", " << theOffset;
+    aResult = aCopy;
+  } else {
+    pd << "geompy.Thicken(" << theObject << ", " << theOffset;
+    aResult = theObject;
   }
-  else
-  {
-    GEOM::TPythonDump(aFunction) << "geompy.Thicken("
-                               << theObject << ", " << theOffset << ")";
-    SetErrorCode(OK);
-    return theObject;
+
+  if (theFacesIDs.IsNull() == Standard_False) {
+    // Dump faces IDs.
+    Standard_Integer i;
+
+    pd << ", [";
+
+    for (i = theFacesIDs->Lower(); i < theFacesIDs->Upper(); ++i) {
+      pd << theFacesIDs->Value(i) << ", ";
+    }
+
+    // Dump the last value.
+    pd << theFacesIDs->Value(i) << "]";
   }
+
+  pd << ")";
+  SetErrorCode(OK);
+
+  return aResult;
 }
 
 //=============================================================================
index 21040faa4a2325f2c408d00d811ec2f7ee636fda..3de3f3240d7bf0c74517f452770b57651c1dbc81 100644 (file)
@@ -144,9 +144,11 @@ class GEOMImpl_I3DPrimOperations : public GEOM_IOperations {
                                                                    Handle(GEOM_Object) thePath,
                                                                    Handle(GEOM_Object) theVec);
   
-  Standard_EXPORT Handle(GEOM_Object) MakeThickening (Handle(GEOM_Object) theObject, 
-                                                      double theOffset,
-                                                      bool isCopy);
+  Standard_EXPORT Handle(GEOM_Object) MakeThickening
+                (Handle(GEOM_Object)                     theObject,
+                 const Handle(TColStd_HArray1OfInteger) &theFacesIDs,
+                 double                                  theOffset,
+                 bool                                    isCopy);
 
   Standard_EXPORT Handle(GEOM_Object) RestorePath (Handle(GEOM_Object) theShape,
                                                    Handle(GEOM_Object) theBase1,
index 9d7796844d7ddc2b2366aeaef5d5c77721cbdb83..dfddeb2b23b76e01f0993ac15cc964b22a7c3998 100644 (file)
 //NOTE: This is an intreface to a function for the Offset creation.
 //
 #include "GEOM_Function.hxx"
+#include <TColStd_HArray1OfInteger.hxx>
 
 #define OFF_ARG_SHAPE 1
 #define OFF_ARG_VALUE 2
+#define OFF_ARG_IDS   3
 
 class GEOMImpl_IOffset
 {
@@ -41,6 +43,12 @@ class GEOMImpl_IOffset
 
   double GetValue() { return _func->GetReal(OFF_ARG_VALUE); }
 
+  void SetFaceIDs(const Handle(TColStd_HArray1OfInteger)& theFaceIDs)
+    { _func->SetIntegerArray(OFF_ARG_IDS, theFaceIDs); }
+
+  Handle(TColStd_HArray1OfInteger) GetFaceIDs()
+    { return _func->GetIntegerArray(OFF_ARG_IDS); }
+
  private:
 
   Handle(GEOM_Function) _func;
index 818ce4eceb562b29641552d5cc56d01e764c0b57..495d6294ed614e4e2b57a9d14c936d28bc9bc167 100644 (file)
 #include <GEOMUtils.hxx>
 
 #include <BRepOffsetAPI_MakeOffsetShape.hxx>
+#include <BRepOffsetAPI_MakeThickSolid.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TopAbs.hxx>
+#include <TopExp.hxx>
 #include <BRepClass3d_SolidClassifier.hxx>
 #include <Precision.hxx>
 #include <Standard_ConstructionError.hxx>
@@ -95,31 +97,78 @@ Standard_Integer GEOMImpl_OffsetDriver::Execute(TFunction_Logbook& log) const
   }
   else if (aType == OFFSET_THICKENING || aType == OFFSET_THICKENING_COPY)
   {
-    BRepClass3d_SolidClassifier aClassifier = BRepClass3d_SolidClassifier(aShapeBase);
-    aClassifier.PerformInfinitePoint(Precision::Confusion());
-    if (aClassifier.State()==TopAbs_IN)
-    {
-      // If the generated pipe faces normals are oriented towards the inside, the offset is negative
-      // so that the thickening is still towards outside
-      anOffset=-anOffset;
-    }
-
-    BRepOffset_MakeOffset myOffsetShape(aShapeBase, anOffset, aTol, BRepOffset_Skin,
-                                        Standard_False, Standard_False, GeomAbs_Intersection, Standard_True);
-
-    if (!myOffsetShape.IsDone())
-    {
-      StdFail_NotDone::Raise("Thickening construction failed");
-    }
-    aShape = myOffsetShape.Shape();
-
-    // Control the solid orientation. This is mostly done to fix a bug in case of extrusion
-    // of a circle. The built solid is then badly oriented
-    BRepClass3d_SolidClassifier anotherClassifier = BRepClass3d_SolidClassifier(aShape);
-    anotherClassifier.PerformInfinitePoint(Precision::Confusion());
-    if (anotherClassifier.State()==TopAbs_IN)
-    {
-      aShape.Reverse();
+    const TopAbs_ShapeEnum aType = aShapeBase.ShapeType();
+
+    if (aType == TopAbs_FACE || aType == TopAbs_SHELL) {
+      // Create a thick solid.
+      BRepClass3d_SolidClassifier aClassifier = BRepClass3d_SolidClassifier(aShapeBase);
+      aClassifier.PerformInfinitePoint(Precision::Confusion());
+      if (aClassifier.State()==TopAbs_IN)
+      {
+        // If the generated pipe faces normals are oriented towards the inside, the offset is negative
+        // so that the thickening is still towards outside
+        anOffset=-anOffset;
+      }
+
+      BRepOffset_MakeOffset myOffsetShape(aShapeBase, anOffset, aTol, BRepOffset_Skin,
+                                          Standard_False, Standard_False, GeomAbs_Intersection, Standard_True);
+
+      if (!myOffsetShape.IsDone())
+      {
+        StdFail_NotDone::Raise("Thickening construction failed");
+      }
+      aShape = myOffsetShape.Shape();
+
+      // Control the solid orientation. This is mostly done to fix a bug in case of extrusion
+      // of a circle. The built solid is then badly oriented
+      BRepClass3d_SolidClassifier anotherClassifier = BRepClass3d_SolidClassifier(aShape);
+      anotherClassifier.PerformInfinitePoint(Precision::Confusion());
+      if (anotherClassifier.State()==TopAbs_IN)
+      {
+        aShape.Reverse();
+      }
+    } else if (aType == TopAbs_SOLID) {
+      // Create a hollowed solid.
+      Handle(TColStd_HArray1OfInteger) aFacesIDs = aCI.GetFaceIDs();
+      TopTools_ListOfShape aFacesToRm;
+
+      if (aFacesIDs.IsNull()) {
+        return 0;
+      }
+
+      TopTools_IndexedMapOfShape anIndices;
+
+      TopExp::MapShapes(aShapeBase, anIndices);
+
+      Standard_Integer aNbShapes = anIndices.Extent();
+      Standard_Integer i;
+
+      for (i = aFacesIDs->Lower(); i <= aFacesIDs->Upper(); ++i) {
+        const Standard_Integer anIndex = aFacesIDs->Value(i);
+
+        if (anIndex < 1 || anIndex > aNbShapes) {
+          // Invalid index.
+          return 0;
+        }
+
+        const TopoDS_Shape &aFace = anIndices.FindKey(anIndex);
+
+        if (aFace.ShapeType() != TopAbs_FACE) {
+          // Shape by index is not a face.
+          return 0;
+        }
+
+        aFacesToRm.Append(aFace);
+      }
+
+      // Create a hollowed solid.
+      BRepOffsetAPI_MakeThickSolid aMkSolid
+                  (aShapeBase, aFacesToRm, anOffset, aTol, BRepOffset_Skin,
+                   Standard_False, Standard_False, GeomAbs_Intersection);
+
+      if (aMkSolid.IsDone()) {
+        aShape = aMkSolid.Shape();
+      }
     }
   }
 
@@ -160,6 +209,13 @@ GetCreationInformation(std::string&             theOperationName,
     theOperationName = "MakeThickening";
     AddParam( theParams, "Object", aCI.GetShape() );
     AddParam( theParams, "Offset", aCI.GetValue() );
+    {
+      Handle(TColStd_HArray1OfInteger) aFacesIDs = aCI.GetFaceIDs();
+
+      if (aFacesIDs.IsNull() == Standard_False) {
+        AddParam(theParams, "Faces IDs", aFacesIDs);
+      }
+    }
     break;
   default:
     return false;
index 1b1522990d7eafc9b61a082a617032f4e5d2ebb2..3a67fc1828e144af431295205a3ab2c1eb0d1c26 100644 (file)
@@ -1184,9 +1184,10 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeBiNormalAlongVector
  */
 //=============================================================================
 GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakeThickening
-                 (GEOM::GEOM_Object_ptr theObject,
-                  CORBA::Double theOffset,
-                  CORBA::Boolean doCopy)
+                 (GEOM::GEOM_Object_ptr   theObject,
+                  const GEOM::ListOfLong &theFacesIDs,
+                  CORBA::Double           theOffset,
+                  CORBA::Boolean          doCopy)
 {
   GEOM::GEOM_Object_var aGEOMObject;
   //Set a not done flag
@@ -1206,12 +1207,25 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakeThickening
   //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();
+  Standard_Integer                 i;
+
+  if (aNbIDs > 0) {
+    aFaceIDs = new TColStd_HArray1OfInteger (1, aNbIDs);
+
+    for (i = 0; i < aNbIDs; i++) {
+      aFaceIDs->SetValue(i + 1, theFacesIDs[i]);
+    }
+  }
+
   //Create the thickened shape
   if (doCopy)
   {
     Handle(GEOM_Object) anObject = GetOperations()->MakeThickening(
-      aBasicObject, theOffset, doCopy);
+      aBasicObject, aFaceIDs, theOffset, doCopy);
     if (!GetOperations()->IsDone() || anObject.IsNull())
       return aGEOMObject._retn();
     
@@ -1219,7 +1233,7 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakeThickening
   }
   else
   {
-    GetOperations()->MakeThickening(aBasicObject, theOffset, doCopy);
+    GetOperations()->MakeThickening(aBasicObject, aFaceIDs, theOffset, doCopy);
     
     // Update GUI.
     UpdateGUIForObject(theObject);
index cd241d95334390b73d60f683b6453e0e07518a5c..ab2f135f01aa3ff1d320c48bd9549913b4cd5c48 100644 (file)
@@ -198,9 +198,10 @@ class GEOM_I_EXPORT GEOM_I3DPrimOperations_i :
                                                     GEOM::GEOM_Object_ptr thePath,
                                                     GEOM::GEOM_Object_ptr theVec);
   
-  GEOM::GEOM_Object_ptr MakeThickening (GEOM::GEOM_Object_ptr theObject,
-                                        CORBA::Double theOffset,
-                                        CORBA::Boolean isCopy);
+  GEOM::GEOM_Object_ptr MakeThickening (GEOM::GEOM_Object_ptr   theObject,
+                                        const GEOM::ListOfLong &theFacesIDs,
+                                        CORBA::Double           theOffset,
+                                        CORBA::Boolean          isCopy);
 
   GEOM::GEOM_Object_ptr RestorePath (GEOM::GEOM_Object_ptr theShape,
                                      GEOM::GEOM_Object_ptr theBase1,
index 53e597c6c959e678380d758452046646de4447ab..3aa3eff61de24d843d6521a07770f96c6a01b10d 100644 (file)
@@ -241,6 +241,12 @@ def TestAll (geompy, math):
                                         tol2d, tol3d, nbiter)  #(GEOM_Object, 4 Doubles, Short)->GEOM_Object
   Pipe             = geompy.MakePipe(Wire, Edge)               #(2 GEOM_Object)->GEOM_Object
   Sewing           = geompy.MakeSewing([Face, S], precision)   #(List Of GEOM_Object, Double)->GEOM_Object
+  ThickSolid       = geompy.MakeCopy(Box)
+  faces            = geompy.SubShapeAllSortedCentres(Box, geompy.ShapeType["FACE"])
+  shell            = geompy.MakeShell([faces[0], faces[1], faces[2]])
+  faceIDs          = geompy.SubShapeAllSortedCentresIDs(ThickSolid, geompy.ShapeType["FACE"])
+  ThickShell       = geompy.MakeThickSolid(shell, 50)          #(GEOM_Object, Double)->GEOM_Object
+  geompy.Thicken(ThickSolid, 50, [faceIDs[0], faceIDs[1]])     #(GEOM_Object) modification
   Copy             = geompy.MakeCopy(Box)                      #(GEOM_Object)->GEOM_Object
 
   #Transform objects
@@ -437,6 +443,9 @@ def TestAll (geompy, math):
   id_Plane2   = geompy.addToStudy(Plane2,   "Plane on Face")
 
   id_Copy       = geompy.addToStudy(Copy,       "Copy")
+  id_ThickShell = geompy.addToStudy(ThickShell, "ThickShell")
+  id_ThickSolid = geompy.addToStudy(ThickSolid, "ThickSolid")
+
   id_Prism            = geompy.addToStudy(Prism,            "Prism")
   id_Prism2Ways       = geompy.addToStudy(Prism2Ways,       "Prism2Ways")
   id_PrismTwoPnt      = geompy.addToStudy(PrismTwoPnt,      "PrismTwoPnt")
old mode 100755 (executable)
new mode 100644 (file)
index 9479be3..531c1bf
@@ -4140,61 +4140,88 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
             self._autoPublish(anObj, theName, "pipe")
             return anObj
 
-        ## Makes a thick solid from a face or a shell
-        #  @param theShape Face or Shell to be thicken
+        ## 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
+        #  a solid the result is a hollowed solid with removed faces.
+        #  @param theShape Face or Shell to get thick solid or solid to get
+        #         hollowed solid.
         #  @param theThickness Thickness of the resulting solid
+        #  @param theFacesIDs the list of face IDs to be removed from the
+        #         result. It is ignored if \a theShape is a face or a shell.
+        #         It is empty 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 solid
         #
+        #  @ref tui_creation_thickness "Example"
         @ManageTransactions("PrimOp")
-        def MakeThickSolid(self, theShape, theThickness, theName=None):
+        def MakeThickSolid(self, theShape, theThickness,
+                           theFacesIDs=[], theName=None):
             """
-            Make a thick solid from a face or a shell
+            Make 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
+            a solid the result is a hollowed solid with removed faces.
 
             Parameters:
-                 theShape Face or Shell to be thicken
+                 theShape Face or Shell to get thick solid or solid to get
+                          hollowed solid.
                  theThickness Thickness of the resulting solid
+                 theFacesIDs the list of face IDs to be removed from the
+                          result. It is ignored if theShape is a face or a
+                          shell. It is empty 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.
+                         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 solid
             """
             # Example: see GEOM_TestAll.py
-            anObj = self.PrimOp.MakeThickening(theShape, theThickness, True)
-            RaiseIfFailed("MakeThickening", self.PrimOp)
-            self._autoPublish(anObj, theName, "pipe")
+            anObj = self.PrimOp.MakeThickening(theShape, theFacesIDs,
+                                               theThickness, True)
+            RaiseIfFailed("MakeThickSolid", self.PrimOp)
+            self._autoPublish(anObj, theName, "thickSolid")
             return anObj
 
 
-        ## Modifies a face or a shell to make it a thick solid
-        #  @param theShape Face or Shell to be thicken
+        ## Modifies a shape to make it a thick solid. If the input is a surface
+        #  shape (face or shell) the result is a thick solid. If an input shape
+        #  is a solid the result is a hollowed solid with removed faces.
+        #  @param theShape Face or Shell to get thick solid or solid to get
+        #         hollowed solid.
         #  @param theThickness Thickness of the resulting solid
+        #  @param theFacesIDs the list of face IDs to be removed from the
+        #         result. It is ignored if \a theShape is a face or a shell.
+        #         It is empty by default. 
         #
         #  @return The modified shape
         #
+        #  @ref tui_creation_thickness "Example"
         @ManageTransactions("PrimOp")
-        def Thicken(self, theShape, theThickness):
+        def Thicken(self, theShape, theThickness, theFacesIDs=[]):
             """
-            Modifies a face or a shell to make it a thick solid
+            Modifies a shape to make it a thick solid. If the input is a
+            surface shape (face or shell) the result is a thick solid. If
+            an input shape is a solid the result is a hollowed solid with
+            removed faces.
 
             Parameters:
-                theBase Base shape to be extruded.
-                thePath Path shape to extrude the base shape along it.
-                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.
+                theShape Face or Shell to get thick solid or solid to get
+                         hollowed solid.
+                theThickness Thickness of the resulting solid
+                theFacesIDs the list of face IDs to be removed from the
+                         result. It is ignored if \a theShape is a face or
+                         a shell. It is empty by default. 
 
             Returns:
                 The modified shape
             """
             # Example: see GEOM_TestAll.py
-            anObj = self.PrimOp.MakeThickening(theShape, theThickness, False)
-            RaiseIfFailed("MakeThickening", self.PrimOp)
+            anObj = self.PrimOp.MakeThickening(theShape, theFacesIDs,
+                                               theThickness, False)
+            RaiseIfFailed("Thicken", self.PrimOp)
             return anObj
 
         ## Build a middle path of a pipe-like shape.
index ce6a64e881df1ed83558443d2d07c72c425b5bc5..181522a3c9d79007c8a15782ace2cfeeca4d2081 100755 (executable)
@@ -68,6 +68,7 @@ SET(GenerationGUI_HEADERS
   GenerationGUI_FillingDlg.h
   GenerationGUI_PipeDlg.h
   GenerationGUI_PipePathDlg.h
+  GenerationGUI_ThicknessDlg.h
   )
 
 # header files / to be processed by moc
@@ -77,6 +78,7 @@ SET(_moc_HEADERS
   GenerationGUI_FillingDlg.h
   GenerationGUI_PipeDlg.h
   GenerationGUI_PipePathDlg.h
+  GenerationGUI_ThicknessDlg.h
   )
 
 # --- sources ---
@@ -91,6 +93,7 @@ SET(GenerationGUI_SOURCES
   GenerationGUI_FillingDlg.cxx
   GenerationGUI_PipeDlg.cxx
   GenerationGUI_PipePathDlg.cxx
+  GenerationGUI_ThicknessDlg.cxx
   ${_moc_SOURCES}
   )
 
index f357d09abe05d198511def84ef908f678437763d..f206a4f955e3b8cc9192ed11c3733b1f6f030660 100644 (file)
@@ -37,6 +37,7 @@
 #include "GenerationGUI_FillingDlg.h"   // Method FILLING
 #include "GenerationGUI_PipeDlg.h"      // Method PIPE
 #include "GenerationGUI_PipePathDlg.h"  // Method RESTORE PATH
+#include "GenerationGUI_ThicknessDlg.h" // Method THICKNESS
 
 //=======================================================================
 // function : GenerationGUI()
@@ -70,11 +71,12 @@ bool GenerationGUI::OnGUIEvent( int theCommandID, SUIT_Desktop* parent )
   QDialog* aDlg = NULL;
 
   switch ( theCommandID ) {
-  case GEOMOp::OpPrism:      aDlg = new GenerationGUI_PrismDlg   ( getGeometryGUI(), parent ); break;
-  case GEOMOp::OpRevolution: aDlg = new GenerationGUI_RevolDlg   ( getGeometryGUI(), parent ); break;
-  case GEOMOp::OpFilling:    aDlg = new GenerationGUI_FillingDlg ( getGeometryGUI(), parent ); break;
-  case GEOMOp::OpPipe:       aDlg = new GenerationGUI_PipeDlg    ( getGeometryGUI(), parent ); break;
-  case GEOMOp::OpPipePath:   aDlg = new GenerationGUI_PipePathDlg( getGeometryGUI(), parent ); break;
+  case GEOMOp::OpPrism:      aDlg = new GenerationGUI_PrismDlg    ( getGeometryGUI(), parent ); break;
+  case GEOMOp::OpRevolution: aDlg = new GenerationGUI_RevolDlg    ( getGeometryGUI(), parent ); break;
+  case GEOMOp::OpFilling:    aDlg = new GenerationGUI_FillingDlg  ( getGeometryGUI(), parent ); break;
+  case GEOMOp::OpPipe:       aDlg = new GenerationGUI_PipeDlg     ( getGeometryGUI(), parent ); break;
+  case GEOMOp::OpPipePath:   aDlg = new GenerationGUI_PipePathDlg ( getGeometryGUI(), parent ); break;
+  case GEOMOp::OpThickness:  aDlg = new GenerationGUI_ThicknessDlg( getGeometryGUI(), parent ); break;
     
   default: app->putInfo( tr( "GEOM_PRP_COMMAND" ).arg( theCommandID ) ); break;
   }
index 3250c9db6063761740f5273a8292de3f00263f31..ecdfae3fa08e6652163648fdb02c64440a05921e 100644 (file)
@@ -721,8 +721,11 @@ bool GenerationGUI_PrismDlg::execute (ObjectList& objects)
       {
         aThickness = -aThickness;  
       }
-      
-      anObj = anotherOper->MakeThickening(anObj, aThickness, /*copy=*/false);    
+
+      GEOM::ListOfLong_var anArray = new GEOM::ListOfLong;
+
+      anObj = anotherOper->MakeThickening
+        (anObj, anArray, aThickness, /*copy=*/false);    
     }
     
     if (!anObj->_is_nil())
diff --git a/src/GenerationGUI/GenerationGUI_ThicknessDlg.cxx b/src/GenerationGUI/GenerationGUI_ThicknessDlg.cxx
new file mode 100644 (file)
index 0000000..f743fa6
--- /dev/null
@@ -0,0 +1,467 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// GEOM GEOMGUI : GUI for Geometry component
+// File   : GenerationGUI_ThicknessDlg.cxx
+// Author : Sergey KHROMOV, Open CASCADE S.A.S.
+
+#include "GenerationGUI_ThicknessDlg.h"
+
+#include <GEOMBase.h>
+#include <GeometryGUI.h>
+
+#include <LightApp_SelectionMgr.h>
+#include <SalomeApp_Application.h>
+#include <SalomeApp_DoubleSpinBox.h>
+#include <SUIT_Session.h>
+#include <SUIT_ResourceMgr.h>
+
+#include <QApplication>
+#include <QCheckBox>
+#include <QGridLayout>
+#include <QGroupBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QRadioButton>
+
+#include <TopExp.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <Precision.hxx>
+
+#define GEOM_SOLID_THICK     0
+#define GEOM_SOLID_HOLLOWED  1
+
+//==============================================================================
+// class    : GenerationGUI_ThicknessDlg()
+// purpose  : 
+//==============================================================================
+GenerationGUI_ThicknessDlg::GenerationGUI_ThicknessDlg
+                            (GeometryGUI* theGeometryGUI, QWidget* parent,
+                             bool modal, Qt::WindowFlags fl)
+  : GEOMBase_Skeleton(theGeometryGUI, parent, modal, fl),
+    myFacesLbl       (0),
+    myObjSelBtn      (0),
+    myFacesSelBtn    (0),
+    myObjEdit        (0),
+    myFacesEdit      (0),
+    myThicknessSpin  (0),
+    myInsideCheck    (0)
+{
+  SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
+  QPixmap image0(aResMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
+  QPixmap image1(aResMgr->loadPixmap("GEOM", tr("ICON_DLG_THICKNESS")));
+  QPixmap image2
+    (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_THICKNESS_HOLLOWED")));
+
+  setWindowTitle(tr("GEOM_THICKNESS_TITLE"));
+
+  /***************************************************************/
+  mainFrame()->GroupConstructors->setTitle(tr("GEOM_THICKNESS"));
+  mainFrame()->RadioButton1->setIcon(image1);
+  mainFrame()->RadioButton2->setIcon(image2);
+
+  mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose);
+  mainFrame()->RadioButton3->close();
+
+  mainFrame()->RadioButton1->setChecked(true);
+
+  QGroupBox   *aMainGrp      = new QGroupBox (tr("GEOM_ARGUMENTS"), this);
+  QGridLayout *aParamsLayout = new QGridLayout(aMainGrp);
+  QLabel      *anObjLbl      = new QLabel (tr("GEOM_OBJECT"), aMainGrp);
+  QLabel      *aThicknessLbl = new QLabel (tr("GEOM_THICKNESS"), aMainGrp);
+  
+  myFacesLbl      = new QLabel (tr("GEOM_FACES"), aMainGrp);
+  myObjSelBtn     = new QPushButton(aMainGrp);
+  myFacesSelBtn   = new QPushButton(aMainGrp);
+  myObjEdit       = new QLineEdit(aMainGrp);
+  myFacesEdit     = new QLineEdit(aMainGrp);
+  myThicknessSpin = new SalomeApp_DoubleSpinBox(aMainGrp);
+  myInsideCheck   = new QCheckBox(tr("GEOM_TOWARDS_INSIDE"), aMainGrp);
+
+  myObjSelBtn->setIcon(image0);
+  myFacesSelBtn->setIcon(image0);
+  myObjEdit->setReadOnly(true);
+  myObjEdit->setSizePolicy
+    (QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+  myFacesEdit->setReadOnly(true);
+  myFacesEdit->setSizePolicy
+    (QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+
+  aParamsLayout->setMargin(9);
+  aParamsLayout->setSpacing(6);
+  aParamsLayout->addWidget(anObjLbl,        0, 0);
+  aParamsLayout->addWidget(myObjSelBtn,     0, 1);
+  aParamsLayout->addWidget(myObjEdit,       0, 2);
+  aParamsLayout->addWidget(myFacesLbl,      1, 0);
+  aParamsLayout->addWidget(myFacesSelBtn,   1, 1);
+  aParamsLayout->addWidget(myFacesEdit,     1, 2);
+  aParamsLayout->addWidget(aThicknessLbl,   2, 0);
+  aParamsLayout->addWidget(myThicknessSpin, 2, 1, 1, 2);
+  aParamsLayout->addWidget(myInsideCheck,   3, 0, 1, 3);
+
+  QVBoxLayout* layout = new QVBoxLayout(centralWidget());
+
+  layout->setMargin(0);
+  layout->setSpacing(6);
+  layout->addWidget(aMainGrp);
+
+  myHelpFileName = "create_thickness_page.html";
+
+  /* Initialisation */
+  Init();
+}
+
+//==============================================================================
+// function : ~GenerationGUI_ThicknessDlg()
+// purpose  : 
+//==============================================================================
+GenerationGUI_ThicknessDlg::~GenerationGUI_ThicknessDlg()
+{
+  // no need to delete child widgets, Qt does it all for us
+}
+
+//==============================================================================
+// function : Init()
+// purpose  :
+//==============================================================================
+void GenerationGUI_ThicknessDlg::Init()
+{
+  // Get setting of step value from file configuration
+  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+  double aStep = resMgr->doubleValue("Geometry", "SettingsGeomStep", 100);
+  double aThickness    = 10.;
+  double aThicknessMin = Precision::Confusion() * 10.0;
+
+  initSpinBox(myThicknessSpin, aThicknessMin,
+              COORD_MAX, aStep, "length_precision");
+  myThicknessSpin->setValue(aThickness);
+  myObject.nullify();
+  myFaces.clear();
+
+  showOnlyPreviewControl();
+    
+  // signals and slots connections
+  connect(buttonOk(),      SIGNAL(clicked()), this, SLOT(ClickOnOk()));
+  connect(buttonApply(),   SIGNAL(clicked()), this, SLOT(ClickOnApply()));
+  connect(this,            SIGNAL(constructorsClicked(int)),
+          this,            SLOT(ConstructorsClicked(int)));
+  connect(myObjSelBtn,     SIGNAL(clicked()),
+          this,            SLOT(SetEditCurrentArgument()));
+  connect(myFacesSelBtn,   SIGNAL(clicked()),
+          this,            SLOT(SetEditCurrentArgument()));
+  connect(myThicknessSpin, SIGNAL(valueChanged(double)),
+          this,            SLOT(ValueChangedInSpinBox()));
+  connect(myGeomGUI,       SIGNAL(SignalDefaultStepValueChanged(double)),
+          this,            SLOT(SetDoubleSpinBoxStep(double)));
+  connect(myInsideCheck,   SIGNAL(toggled(bool)),
+          this,            SLOT(onChangeDirection(bool)));
+
+  connect(myGeomGUI->getApp()->selectionMgr(),
+          SIGNAL(currentSelectionChanged()),
+          this, SLOT(SelectionIntoArgument()));
+
+  initName(tr("GEOM_THICKNESS"));
+
+  ConstructorsClicked(0);
+}
+
+//==============================================================================
+// function : SetDoubleSpinBoxStep()
+// purpose  : Double spin box management
+//==============================================================================
+void GenerationGUI_ThicknessDlg::SetDoubleSpinBoxStep (double step)
+{
+  myThicknessSpin->setSingleStep(step);
+}
+
+//==============================================================================
+// function : ConstructorsClicked()
+// purpose  : Radio button management
+//==============================================================================
+void GenerationGUI_ThicknessDlg::ConstructorsClicked (int constructorId)
+{
+  switch (constructorId) {
+  case GEOM_SOLID_THICK:
+    myObjSelBtn->setDown(false);
+    myFacesLbl->hide();
+    myFacesSelBtn->hide();
+    myFacesEdit->hide();
+    myFaces.clear();
+    break;
+  case GEOM_SOLID_HOLLOWED:
+    myObjSelBtn->setDown(true);
+    myFacesLbl->show();
+    myFacesSelBtn->show();
+    myFacesEdit->show();
+    break;
+  default:
+    break;
+  }
+
+  myEditCurrentArgument = myObjEdit;
+  qApp->processEvents();
+  updateGeometry();
+  resize(minimumSizeHint());
+
+  SelectionIntoArgument();
+}
+
+//==============================================================================
+// function : ClickOnOk()
+// purpose  :
+//==============================================================================
+void GenerationGUI_ThicknessDlg::ClickOnOk()
+{
+  setIsApplyAndClose(true);
+
+  if (ClickOnApply()) {
+    ClickOnCancel();
+  }
+}
+
+//==============================================================================
+// function : ClickOnApply()
+// purpose  :
+//==============================================================================
+bool GenerationGUI_ThicknessDlg::ClickOnApply()
+{
+  if (!onAccept()) {
+    return false;
+  }
+
+  initName();
+
+  // activate selection and connect selection manager
+  ConstructorsClicked(getConstructorId());
+
+  return true;
+}
+
+//==============================================================================
+// function : SelectionIntoArgument()
+// purpose  : Called when selection is changed or on dialog initialization or
+//            activation
+//==============================================================================
+void GenerationGUI_ThicknessDlg::SelectionIntoArgument()
+{
+  erasePreview();
+  myEditCurrentArgument->setText("");
+
+  if (myEditCurrentArgument == myObjEdit) {
+    QList<TopAbs_ShapeEnum> aTypes;
+    const int               anID = getConstructorId();
+
+    if (anID == GEOM_SOLID_THICK) {
+      aTypes << TopAbs_SHELL << TopAbs_FACE;
+    } else if (anID == GEOM_SOLID_HOLLOWED) {
+      aTypes << TopAbs_SOLID;
+    }
+
+    myObject = getSelected(aTypes);
+
+    if (myObject) {
+      QString aName = GEOMBase::GetName(myObject.get());
+
+      myEditCurrentArgument->setText(aName);
+
+      if (anID == GEOM_SOLID_HOLLOWED && myFaces.empty()) {
+        myFacesSelBtn->click();
+      }
+    }
+  } else if (myEditCurrentArgument == myFacesEdit) {
+    myFaces.clear();
+    myFaces = getSelected(TopAbs_FACE, -1);
+
+    int i = myFaces.count();
+
+    if (i == 1) {
+      myEditCurrentArgument->setText(GEOMBase::GetName(myFaces.first().get()));
+    } else if (i > 0) {
+      myEditCurrentArgument->setText
+        (QString::number( i ) + "_" + tr("GEOM_OBJECTS"));
+    }
+  }
+
+  processPreview();
+}
+
+//==============================================================================
+// function : SetEditCurrentArgument()
+// purpose  :
+//==============================================================================
+void GenerationGUI_ThicknessDlg::SetEditCurrentArgument()
+{
+  QPushButton* send = (QPushButton*)sender();
+
+  if (send == myObjSelBtn) {
+    myFacesSelBtn->setDown(false);
+    myEditCurrentArgument = myObjEdit;
+    globalSelection(GEOM_ALLSHAPES);
+  } else if (send == myFacesSelBtn) {
+    myObjSelBtn->setDown(false);
+    myEditCurrentArgument = myFacesEdit;
+    globalSelection(); // close local contexts, if any
+    localSelection(myObject.get(), TopAbs_FACE);
+  }
+
+  myEditCurrentArgument->setFocus();
+
+  const int anID = getConstructorId();
+
+  // after setFocus(), because it will be setDown(false) when loses focus
+  send->setDown(anID == GEOM_SOLID_HOLLOWED);
+
+  // seems we need it only to avoid preview disappearing, caused by selection
+  // mode change
+  processPreview();
+}
+
+//==============================================================================
+// function : ActivateThisDialog()
+// purpose  :
+//==============================================================================
+void GenerationGUI_ThicknessDlg::ActivateThisDialog()
+{
+  GEOMBase_Skeleton::ActivateThisDialog();
+
+  connect(myGeomGUI->getApp()->selectionMgr(),
+          SIGNAL(currentSelectionChanged()),
+          this, SLOT(SelectionIntoArgument()));
+
+  ConstructorsClicked(getConstructorId());
+}
+
+//==============================================================================
+// function : enterEvent()
+// purpose  : when mouse enter onto the QWidget
+//==============================================================================
+void GenerationGUI_ThicknessDlg::enterEvent (QEvent*)
+{
+  if (!mainFrame()->GroupConstructors->isEnabled())
+    ActivateThisDialog();
+}
+
+//==============================================================================
+// function : ValueChangedInSpinBox()
+// purpose  :
+//==============================================================================
+void GenerationGUI_ThicknessDlg::ValueChangedInSpinBox()
+{
+  processPreview();
+}
+
+//==============================================================================
+// function : createOperation
+// purpose  :
+//==============================================================================
+GEOM::GEOM_IOperations_ptr GenerationGUI_ThicknessDlg::createOperation()
+{
+  return getGeomEngine()->GetI3DPrimOperations(getStudyId());
+}
+
+//==============================================================================
+// function : isValid
+// purpose  :
+//==============================================================================
+bool GenerationGUI_ThicknessDlg::isValid (QString& msg)
+{
+  bool isOk = false;
+
+  switch (getConstructorId()) {
+  case GEOM_SOLID_THICK:
+    isOk = myThicknessSpin->isValid(msg, !IsPreview()) && myObject;
+    break;
+  case GEOM_SOLID_HOLLOWED:
+    isOk = myThicknessSpin->isValid(msg, !IsPreview()) &&
+           myObject && !myFaces.empty();
+    break;
+  default:
+    break;
+  }
+
+  return isOk;
+}
+
+//==============================================================================
+// function : onChangeDirection(bool)
+// purpose  :
+//==============================================================================
+void GenerationGUI_ThicknessDlg::onChangeDirection(bool)
+{
+  processPreview();
+}
+
+//==============================================================================
+// function : execute
+// purpose  :
+//==============================================================================
+bool GenerationGUI_ThicknessDlg::execute (ObjectList& objects)
+{
+  GEOM::GEOM_Object_var            anObj;
+  GEOM::GEOM_I3DPrimOperations_var anOper       =
+    GEOM::GEOM_I3DPrimOperations::_narrow(getOperation());
+  double                           aThickness   = myThicknessSpin->value();
+  GEOM::ListOfLong_var             anObjIDsList = new GEOM::ListOfLong();
+  TopoDS_Shape                     aShape;
+
+  if (GEOMBase::GetShape(myObject.get(), aShape)) {
+    TopTools_IndexedMapOfShape aMainMap;
+    QList<int>                 aListIDs;
+
+    TopExp::MapShapes(aShape, aMainMap);
+
+    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;
+        }
+      }
+    }
+
+
+    if (!aListIDs.empty()) {
+      anObjIDsList->length(aListIDs.length());
+
+      for (int i = 0; i < aListIDs.length(); i++) {
+        anObjIDsList[i] = aListIDs[i];
+      }
+    }
+  }
+
+  if (myInsideCheck->isChecked()) {
+    aThickness = -aThickness;  
+  }
+
+  anObj = anOper->MakeThickening
+    (myObject.get(), anObjIDsList.in(), aThickness, true);
+    
+  if (!anObj->_is_nil()) {
+    objects.push_back(anObj._retn());
+  }
+
+  return true;
+}
diff --git a/src/GenerationGUI/GenerationGUI_ThicknessDlg.h b/src/GenerationGUI/GenerationGUI_ThicknessDlg.h
new file mode 100644 (file)
index 0000000..b05d9f5
--- /dev/null
@@ -0,0 +1,83 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// GEOM GEOMGUI : GUI for Geometry component
+// File   : GenerationGUI_ThicknessDlg.h
+// Author : Sergey KHROMOV, Open CASCADE S.A.S.
+
+#ifndef GENERATIONGUI_THICKNESSDLG_H
+#define GENERATIONGUI_THICKNESSDLG_H
+
+#include "GEOMBase_Skeleton.h"
+
+
+//=================================================================================
+// class    : GenerationGUI_ThicknessDlg
+// purpose  :
+//=================================================================================
+class GenerationGUI_ThicknessDlg : public GEOMBase_Skeleton
+{ 
+  Q_OBJECT
+
+public:
+
+  GenerationGUI_ThicknessDlg(GeometryGUI*, QWidget* = 0,
+                             bool = false, Qt::WindowFlags = 0);
+  ~GenerationGUI_ThicknessDlg();
+  
+protected:
+
+  // redefined from GEOMBase_Helper
+  virtual GEOM::GEOM_IOperations_ptr createOperation();
+  virtual bool                       isValid( QString& );
+  virtual bool                       execute( ObjectList& );    
+
+private:
+  void                               Init();
+  void                               enterEvent( QEvent* );
+private:
+  GEOM::GeomObjPtr                   myObject;
+  QList<GEOM::GeomObjPtr>            myFaces;
+
+  QLabel                            *myFacesLbl;
+  QPushButton                       *myObjSelBtn;
+  QPushButton                       *myFacesSelBtn;
+  QLineEdit                         *myObjEdit;
+  QLineEdit                         *myFacesEdit;
+  SalomeApp_DoubleSpinBox           *myThicknessSpin;
+  QCheckBox                         *myInsideCheck;
+
+  
+private slots:
+  void                               ClickOnOk();
+  bool                               ClickOnApply();
+  void                               ActivateThisDialog();
+  void                               SelectionIntoArgument();
+  void                               SetEditCurrentArgument();
+  void                               ConstructorsClicked(int);
+  void                               ValueChangedInSpinBox();
+  void                               SetDoubleSpinBoxStep(double);
+  void                               onChangeDirection(bool);
+};
+
+#endif // GENERATIONGUI_THICKNESSDLG_H