From: skv Date: Mon, 16 Mar 2015 14:23:18 +0000 (+0300) Subject: 0022666: EDF 7253 GEOM: Add thickness to a shell and integrate BrepOffsetAPI_MakeThic... X-Git-Tag: V7_6_0a1~15 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=58b6d007bceec500c219b94e16c7c62d76458012;p=modules%2Fgeom.git 0022666: EDF 7253 GEOM: Add thickness to a shell and integrate BrepOffsetAPI_MakeThickSolid --- diff --git a/doc/salome/examples/CMakeLists.txt b/doc/salome/examples/CMakeLists.txt index 5ba409fb9..6a0baa09a 100644 --- a/doc/salome/examples/CMakeLists.txt +++ b/doc/salome/examples/CMakeLists.txt @@ -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 index 000000000..63242331a --- /dev/null +++ b/doc/salome/examples/complex_objs_ex11.py @@ -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 index 000000000..527785762 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 index 000000000..47ec5a002 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 index 000000000..079a75499 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 index 000000000..6a6087a4c Binary files /dev/null and b/doc/salome/gui/GEOM/images/thicksolid_result.png differ diff --git a/doc/salome/gui/GEOM/input/creating_complex_obj.doc b/doc/salome/gui/GEOM/input/creating_complex_obj.doc index a5c6a090f..6630dfa72 100644 --- a/doc/salome/gui/GEOM/input/creating_complex_obj.doc +++ b/doc/salome/gui/GEOM/input/creating_complex_obj.doc @@ -15,6 +15,7 @@ axis, creating a body of revolution.
  • \subpage create_extrusion_alongpath_page "Extrude an object along a path", creating a more complex trajectory object.
  • \subpage create_pipe_path_page "Restore Path" of a pipe-like shape.
  • +
  • \subpage create_thickness_page "Thickness" operation that allows to add a thickness to objects.
  • New entity -> Advanced 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 index 000000000..140c02fc1 --- /dev/null +++ b/doc/salome/gui/GEOM/input/creating_thickness_page.doc @@ -0,0 +1,46 @@ +/*! + +\page create_thickness_page Thickness Construction + +To add a \b Thickness to a shape in the Main Menu select New Entity - > Generation - > Thickness +\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 +Thicken towards the inside check box. + +\image html thickness.png + +Example: + +\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 Thicken towards the inside check box. + +\image html thicksolid.png + +Example: + +\image html thicksolid_result.png "Thickness of Solid" + +\n TUI Commands: +\n +geompy.MakeThickSolid(theShape, theThickness, theFacesIDs=[]) - +Makes a thick solid from a shape; +\n +geompy.Thicken(theShape, theThickness, theFacesIDs=[]) - +Modifies a shape to make it a thick solid. + +Arguments: 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 Advanced options \ref preview_anchor "Preview" + +Our TUI Scripts provide you with useful examples of creation of +\ref tui_creation_thickness "Complex Geometric Objects". + +*/ diff --git a/doc/salome/gui/GEOM/input/tui_complex_objs.doc b/doc/salome/gui/GEOM/input/tui_complex_objs.doc index 61ce18b5a..3ced40bca 100644 --- a/doc/salome/gui/GEOM/input/tui_complex_objs.doc +++ b/doc/salome/gui/GEOM/input/tui_complex_objs.doc @@ -42,4 +42,8 @@

    Creation of Tangent Plane On Face

    \tui_script{complex_objs_ex10.py} +\anchor tui_creation_thickness +

    Applying a Thickness to Face, Shell or Solid

    +\tui_script{complex_objs_ex11.py} + */ diff --git a/doc/salome/gui/GEOM/input/tui_test_all.doc b/doc/salome/gui/GEOM/input/tui_test_all.doc index 1718afb00..b1f915ea2 100644 --- a/doc/salome/gui/GEOM/input/tui_test_all.doc +++ b/doc/salome/gui/GEOM/input/tui_test_all.doc @@ -49,7 +49,7 @@ \until Line3 \anchor swig_all_advanced -\until MakeSewing +\until Thicken \anchor swig_MakeCopy \until MakeCopy diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 4b54e4ddd..9bdfda2b2 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -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); /*! diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index 87d7e929a..3a1bb3200 100755 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -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 index 000000000..bee29286b Binary files /dev/null and b/resources/thickness.png differ diff --git a/resources/thickness2.png b/resources/thickness2.png new file mode 100644 index 000000000..31b9e5677 Binary files /dev/null and b/resources/thickness2.png differ diff --git a/src/GEOMGUI/GEOM_images.ts b/src/GEOMGUI/GEOM_images.ts index 84876a3b7..489aaa5aa 100644 --- a/src/GEOMGUI/GEOM_images.ts +++ b/src/GEOMGUI/GEOM_images.ts @@ -555,6 +555,14 @@ ICON_DLG_PRISM_DXDYDZ prism3.png + + ICON_DLG_THICKNESS + thickness.png + + + ICON_DLG_THICKNESS_HOLLOWED + thickness2.png + ICON_DLG_PROPAGATE propagate.png @@ -1011,6 +1019,10 @@ ICO_EXTRUSION prism.png + + ICO_THICKNESS + thickness.png + ICO_FACE build_face.png diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index d5bdf3e5f..3d0ebd610 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -675,6 +675,18 @@ Please, select face, shell or solid and try again GEOM_EXTRUSION_TITLE Construction by Extrusion + + GEOM_THICKNESS_TITLE + Thickness Construction + + + GEOM_THICKNESS_NAME + Thickness + + + GEOM_TOWARDS_INSIDE + Thicken towards the inside + GEOM_SCALE_PRISM Scale the face opposite to the base @@ -2852,6 +2864,10 @@ Please, select face, shell or solid and try again MEN_PIPE_PATH Restore Path + + MEN_THICKNESS + Thickness + MEN_PLANE Plane @@ -3800,6 +3816,10 @@ Please, select face, shell or solid and try again STB_PIPE_PATH Restore path from a pipe-like shape + + STB_THICKNESS + Make a thick solid + STB_PLANE Create a plane @@ -4416,6 +4436,10 @@ Please, select face, shell or solid and try again TOP_PIPE_PATH Restore path + + TOP_THICKNESS + Thickness + TOP_PLANE Create a plane @@ -6039,10 +6063,6 @@ Number of sketch points too small GEOM_ADD_THICKNESS Add thickness (edges or wires only) - - GEOM_TOWARDS_INSIDE - Thicken towards the inside - GroupGUI diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index 013b9abc0..526eeaac5 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -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 ); diff --git a/src/GEOMGUI/GeometryGUI_Operations.h b/src/GEOMGUI/GeometryGUI_Operations.h index f7b545c98..2acdd53f4 100644 --- a/src/GEOMGUI/GeometryGUI_Operations.h +++ b/src/GEOMGUI/GeometryGUI_Operations.h @@ -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 diff --git a/src/GEOMImpl/GEOMImpl_I3DPrimOperations.cxx b/src/GEOMImpl/GEOMImpl_I3DPrimOperations.cxx index 55c46b26f..6cc3e28d9 100644 --- a/src/GEOMImpl/GEOMImpl_I3DPrimOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_I3DPrimOperations.cxx @@ -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; } //============================================================================= diff --git a/src/GEOMImpl/GEOMImpl_I3DPrimOperations.hxx b/src/GEOMImpl/GEOMImpl_I3DPrimOperations.hxx index 21040faa4..3de3f3240 100644 --- a/src/GEOMImpl/GEOMImpl_I3DPrimOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_I3DPrimOperations.hxx @@ -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, diff --git a/src/GEOMImpl/GEOMImpl_IOffset.hxx b/src/GEOMImpl/GEOMImpl_IOffset.hxx index 9d7796844..dfddeb2b2 100644 --- a/src/GEOMImpl/GEOMImpl_IOffset.hxx +++ b/src/GEOMImpl/GEOMImpl_IOffset.hxx @@ -23,9 +23,11 @@ //NOTE: This is an intreface to a function for the Offset creation. // #include "GEOM_Function.hxx" +#include #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; diff --git a/src/GEOMImpl/GEOMImpl_OffsetDriver.cxx b/src/GEOMImpl/GEOMImpl_OffsetDriver.cxx index 818ce4ece..495d6294e 100644 --- a/src/GEOMImpl/GEOMImpl_OffsetDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_OffsetDriver.cxx @@ -29,8 +29,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -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; diff --git a/src/GEOM_I/GEOM_I3DPrimOperations_i.cc b/src/GEOM_I/GEOM_I3DPrimOperations_i.cc index 1b1522990..3a67fc182 100644 --- a/src/GEOM_I/GEOM_I3DPrimOperations_i.cc +++ b/src/GEOM_I/GEOM_I3DPrimOperations_i.cc @@ -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); diff --git a/src/GEOM_I/GEOM_I3DPrimOperations_i.hh b/src/GEOM_I/GEOM_I3DPrimOperations_i.hh index cd241d953..ab2f135f0 100644 --- a/src/GEOM_I/GEOM_I3DPrimOperations_i.hh +++ b/src/GEOM_I/GEOM_I3DPrimOperations_i.hh @@ -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, diff --git a/src/GEOM_SWIG/GEOM_TestAll.py b/src/GEOM_SWIG/GEOM_TestAll.py index 53e597c6c..3aa3eff61 100644 --- a/src/GEOM_SWIG/GEOM_TestAll.py +++ b/src/GEOM_SWIG/GEOM_TestAll.py @@ -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") diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py old mode 100755 new mode 100644 index 9479be3b8..531c1bf18 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -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. diff --git a/src/GenerationGUI/CMakeLists.txt b/src/GenerationGUI/CMakeLists.txt index ce6a64e88..181522a3c 100755 --- a/src/GenerationGUI/CMakeLists.txt +++ b/src/GenerationGUI/CMakeLists.txt @@ -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} ) diff --git a/src/GenerationGUI/GenerationGUI.cxx b/src/GenerationGUI/GenerationGUI.cxx index f357d09ab..f206a4f95 100644 --- a/src/GenerationGUI/GenerationGUI.cxx +++ b/src/GenerationGUI/GenerationGUI.cxx @@ -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; } diff --git a/src/GenerationGUI/GenerationGUI_PrismDlg.cxx b/src/GenerationGUI/GenerationGUI_PrismDlg.cxx index 3250c9db6..ecdfae3fa 100644 --- a/src/GenerationGUI/GenerationGUI_PrismDlg.cxx +++ b/src/GenerationGUI/GenerationGUI_PrismDlg.cxx @@ -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 index 000000000..f743fa631 --- /dev/null +++ b/src/GenerationGUI/GenerationGUI_ThicknessDlg.cxx @@ -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 +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#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 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 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 index 000000000..b05d9f51b --- /dev/null +++ b/src/GenerationGUI/GenerationGUI_ThicknessDlg.h @@ -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 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