diff --git a/doc/salome/examples/CMakeLists.txt b/doc/salome/examples/CMakeLists.txt index 3d9da7036..67721de68 100644 --- a/doc/salome/examples/CMakeLists.txt +++ b/doc/salome/examples/CMakeLists.txt @@ -114,6 +114,7 @@ SET(GOOD_TESTS transformation_operations_ex11.py transformation_operations_ex12.py transformation_operations_ex13.py + transformation_operations_ex14.py viewing_geom_objs_ex01.py viewing_geom_objs_ex02.py viewing_geom_objs_ex03.py diff --git a/doc/salome/examples/transformation_operations_ex14.py b/doc/salome/examples/transformation_operations_ex14.py new file mode 100644 index 000000000..e8bc167ed --- /dev/null +++ b/doc/salome/examples/transformation_operations_ex14.py @@ -0,0 +1,75 @@ +# Extend Edge and Face + +import salome +salome.salome_init() +import GEOM +from salome.geom import geomBuilder +geompy = geomBuilder.New(salome.myStudy) +gg = salome.ImportComponentGUI("GEOM") + +# create vertices +p1 = geompy.MakeVertex( 0., 0., 0.) +p2 = geompy.MakeVertex(100., 100., 0.) +p3 = geompy.MakeVertex( 0., 100., 0.) + +# create edges +edge1 = geompy.MakeEdge(p1, p2) +edge2 = geompy.MakeCircleR(100) + +# create faces +face1 = geompy.MakePlaneThreePnt(p1, p2, p3, 200) +sphere1 = geompy.MakeSpherePntR(p1, 100) +faces2 = geompy.SubShapeAllSorted(sphere1, GEOM.FACE) +face2 = faces2[0] + +# perform edge extension +resEdge1 = geompy.ExtendEdge(edge1, 0.2, 0.8) +resEdge2 = geompy.ExtendEdge(edge1, -0.3, 1.3) +resEdge3 = geompy.ExtendEdge(edge2, 0.5, 1) +resEdge4 = geompy.ExtendEdge(edge2, 0.2, 0.5) + +# perform face extension +resFace1 = geompy.ExtendFace(face1, 0.2, 0.8, -0.3, 1.3) +resFace2 = geompy.ExtendFace(face1, 0, 0.5, 1, 2) +resFace3 = geompy.ExtendFace(face2, 0.2, 0.8, 0.3, 0.7) +resFace4 = geompy.ExtendFace(face2, 0.5, 1, 0.5, 1) + +# add objects in the study +id_edge1 = geompy.addToStudy(edge1, "Edge 1") +id_edge2 = geompy.addToStudy(edge2, "Edge 2") +id_face1 = geompy.addToStudy(face1, "Face 1") +id_face2 = geompy.addToStudy(face2, "Face 2") +id_resEdge1 = geompy.addToStudy(resEdge1, "Extended Edge 1") +id_resEdge2 = geompy.addToStudy(resEdge2, "Extended Edge 1") +id_resEdge3 = geompy.addToStudy(resEdge3, "Extended Edge 2") +id_resEdge4 = geompy.addToStudy(resEdge4, "Extended Edge 3") +id_resFace1 = geompy.addToStudy(resFace1, "Extended Face 1") +id_resFace2 = geompy.addToStudy(resFace2, "Extended Face 2") +id_resFace3 = geompy.addToStudy(resFace3, "Extended Face 3") +id_resFace4 = geompy.addToStudy(resFace4, "Extended Face 4") + +# display the prism and the results of chamfer operation +gg.createAndDisplayGO(id_edge1) +gg.setDisplayMode(id_edge1, 1) +gg.createAndDisplayGO(id_edge2) +gg.setDisplayMode(id_edge2, 1) +gg.createAndDisplayGO(id_face1) +gg.setDisplayMode(id_face1, 1) +gg.createAndDisplayGO(id_face2) +gg.setDisplayMode(id_face2, 1) +gg.createAndDisplayGO(id_resEdge1) +gg.setDisplayMode(id_resEdge1, 1) +gg.createAndDisplayGO(id_resEdge2) +gg.setDisplayMode(id_resEdge2, 1) +gg.createAndDisplayGO(id_resEdge3) +gg.setDisplayMode(id_resEdge3, 1) +gg.createAndDisplayGO(id_resEdge4) +gg.setDisplayMode(id_resEdge4, 1) +gg.createAndDisplayGO(id_resFace1) +gg.setDisplayMode(id_resFace1, 1) +gg.createAndDisplayGO(id_resFace2) +gg.setDisplayMode(id_resFace2, 1) +gg.createAndDisplayGO(id_resFace3) +gg.setDisplayMode(id_resFace3, 1) +gg.createAndDisplayGO(id_resFace4) +gg.setDisplayMode(id_resFace4, 1) diff --git a/doc/salome/gui/GEOM/images/extend_edge_example.png b/doc/salome/gui/GEOM/images/extend_edge_example.png new file mode 100644 index 000000000..f8a88e9ec Binary files /dev/null and b/doc/salome/gui/GEOM/images/extend_edge_example.png differ diff --git a/doc/salome/gui/GEOM/images/extend_face_example.png b/doc/salome/gui/GEOM/images/extend_face_example.png new file mode 100644 index 000000000..26281f1c4 Binary files /dev/null and b/doc/salome/gui/GEOM/images/extend_face_example.png differ diff --git a/doc/salome/gui/GEOM/images/extension1.png b/doc/salome/gui/GEOM/images/extension1.png new file mode 100644 index 000000000..419d44e66 Binary files /dev/null and b/doc/salome/gui/GEOM/images/extension1.png differ diff --git a/doc/salome/gui/GEOM/images/extension2.png b/doc/salome/gui/GEOM/images/extension2.png new file mode 100644 index 000000000..e4ac66a25 Binary files /dev/null and b/doc/salome/gui/GEOM/images/extension2.png differ diff --git a/doc/salome/gui/GEOM/input/extension_operation.doc b/doc/salome/gui/GEOM/input/extension_operation.doc new file mode 100644 index 000000000..417577adb --- /dev/null +++ b/doc/salome/gui/GEOM/input/extension_operation.doc @@ -0,0 +1,58 @@ +/*! + +\page extension_operation_page Extension of an Edge or a Face + +\n To produce an \b Extension in the Main Menu select +Operations - > Transformation - > Extension + +\n This operation resizes an \b Edge by means of first + and last parameters modification or a \b Face by means of modification + of minimal and maximal U- and V-Parameters. \n +\ref restore_presentation_parameters_page "Advanced options". + +The type of extension is defined using the radio buttons. + +Firstly it is possible to resize an \b Edge. +\n TUI Command: geompy.ExtendEdge(theEdge, theMin, theMax), +where \em theEdge the input edge to be resized, \em theMin the minimal +parameter value, \em theMax the maximal parameter value. +\n Arguments: Name + Object (Edge) + 2 values (Min and Max Parameters). + +\image html extension1.png "Extension of an Edge" + +\n Example: + +\image html extend_edge_example.png "Original edge (white) and extended edge" + +\note The input Edge parameters range is [0, 1]. If \b theMin parameter is + negative, the input Edge is extended, otherwise it is shrinked by + \b theMin parameter. If \b theMax is greater than 1, the Edge is + extended, otherwise it is shrinked by \btheMax parameter. + +Secondly it is possible to resize a \b Face. +\n TUI Command: geompy.ExtendFace(theFace, theUMin, theUMax, +theVMin, theVMax), where \em theFace the input face to be resized, +\em theUMin the minimal U-Parameter value, \em theUMax the maximal U-Parameter +value, \em theVMin the minimal V-Parameter value, \em theVMax the maximal +V-Parameter value. +\n Arguments: Name + Object (Face) + 4 values (Min and Max U- and +V-Parameters). + +\image html extension2.png "Extension of a Face" + +\n Example: + +\image html extend_face_example.png "The original face (gray) and a result + face shrinked along U-Direction and extended along V-Direction" + +\note The input Face U- and V-Parameters range is [0, 1]. If \b theUMin + parameter is negative, the input Face is extended, otherwise it is + shrinked along U-Direction by \b theUMin parameter. If theUMax is + greater than 1, the Face is extended, otherwise it is shrinked along + U-Direction by \b theUMax parameter. So as for \b theVMin, \b theVMax + and V-Direction of the input Face. + +Our TUI Scripts provide you with useful examples of the use of +\ref tui_extend "Extension Operations". + +*/ diff --git a/doc/salome/gui/GEOM/input/transformation_operations.doc b/doc/salome/gui/GEOM/input/transformation_operations.doc index 075973737..ac745b669 100644 --- a/doc/salome/gui/GEOM/input/transformation_operations.doc +++ b/doc/salome/gui/GEOM/input/transformation_operations.doc @@ -16,6 +16,7 @@ which allow to:
  • \subpage scale_operation_page "Scale" an object by one or several scale factors.
  • Create an \subpage offset_operation_page "Offset" of an object.
  • Create a \subpage projection_operation_page "Projection" of an object on a face.
  • +
  • Create an \subpage extension_operation_page "Extension" of an edge or a face.
  • Create a simultaneous \subpage multi_translation_operation_page "Translation in several directions".
  • Create a simultaneous \subpage multi_rotation_operation_page
  • "Rotation in several directions". diff --git a/doc/salome/gui/GEOM/input/tui_transformation_operations.doc b/doc/salome/gui/GEOM/input/tui_transformation_operations.doc index f25eb9c76..2114d7cba 100644 --- a/doc/salome/gui/GEOM/input/tui_transformation_operations.doc +++ b/doc/salome/gui/GEOM/input/tui_transformation_operations.doc @@ -54,4 +54,8 @@

    Chamfer

    \tui_script{transformation_operations_ex13.py} +\anchor tui_extend +

    Extend Edge and Face

    +\tui_script{transformation_operations_ex14.py} + */ diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 0d65fd8f8..2cfbe5a22 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -2537,6 +2537,42 @@ module GEOM ListOfLong GetSameIDs (in GEOM_Object theShapeWhere, in GEOM_Object theShapeWhat); + /*! + * \brief Resize the input edge with the new Min and Max parameters. + * The input edge parameters range is [0, 1]. If theMin parameter is + * negative, the input edge is extended, otherwise it is shrinked by + * theMin parameter. If theMax is greater than 1, the edge is extended, + * otherwise it is shrinked by theMax parameter. + * \param theEdge the input edge to be resized. + * \param theMin the minimal parameter value. + * \param theMax the maximal parameter value. + * \return a newly created edge. + */ + GEOM_Object ExtendEdge(in GEOM_Object theEdge, + in double theMin, + in double theMax); + + /*! + * \brief Resize the input face with the new UMin, UMax, VMin and VMax + * parameters. The input face U and V parameters range is [0, 1]. If + * theUMin parameter is negative, the input face is extended, otherwise + * it is shrinked along U direction by theUMin parameter. If theUMax is + * greater than 1, the face is extended, otherwise it is shrinked along + * U direction by theUMax parameter. So as for theVMin, theVMax and + * V direction of the input face. + * \param theFace the input face to be resized. + * \param theUMin the minimal U parameter value. + * \param theUMax the maximal U parameter value. + * \param theVMin the minimal V parameter value. + * \param theVMax the maximal V parameter value. + * \return a newly created face. + */ + GEOM_Object ExtendFace(in GEOM_Object theFace, + in double theUMin, + in double theUMax, + in double theVMin, + in double theVMax); + }; // # GEOM_IBlocksOperations: diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index 1dd296155..f2e64385a 100755 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -89,10 +89,12 @@ SET( _res_files displayonly.png displayall.png draft.png + edgeextension.png erase.png eraseall.png extruded_boss.png extruded_cut.png + faceextension.png face_hw.png face_vechw.png feature_detect.png diff --git a/resources/edgeextension.png b/resources/edgeextension.png new file mode 100644 index 000000000..c468969c3 Binary files /dev/null and b/resources/edgeextension.png differ diff --git a/resources/faceextension.png b/resources/faceextension.png new file mode 100644 index 000000000..b8429df29 Binary files /dev/null and b/resources/faceextension.png differ diff --git a/src/GEOMGUI/GEOM_images.ts b/src/GEOMGUI/GEOM_images.ts index db8b15dd1..7cf2826df 100644 --- a/src/GEOMGUI/GEOM_images.ts +++ b/src/GEOMGUI/GEOM_images.ts @@ -431,6 +431,14 @@ ICON_DLG_PROJECTION projection.png + + ICON_DLG_EXTEND_EDGE + edgeextension.png + + + ICON_DLG_EXTEND_FACE + faceextension.png + ICON_DLG_PARTITION partition.png @@ -1099,6 +1107,10 @@ ICO_PROJECTION projection.png + + ICO_EXTENSION + edgeextension.png + ICO_ORIGIN_AND_VECTORS origin_and_vectors.png diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 1dcc33e19..6b06a14d6 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -3112,6 +3112,14 @@ Please, select face, shell or solid and try again MEN_POP_PREDEF_MATER_CUSTOM Custom... + + MEN_EDGE_EXTEND + Extended Edge + + + MEN_FACE_EXTEND + Extended Face + NAME_LBL Name: @@ -4980,6 +4988,18 @@ Please, select face, shell or solid and try again STB_GET_SHARED_SHAPES Get shared shapes + + TOP_EXTENSION + Extend Edge or Face + + + MEN_EXTENSION + Extension + + + STB_EXTENSION + Extend Edge or Face + GEOM_PUBLISH_RESULT_GRP Advanced options @@ -7030,4 +7050,47 @@ Do you want to create new material? All interferences + + TransformationGUI_ExtensionDlg + + GEOM_EXTENSION_TITLE + Extension of Edge or Face + + + GEOM_EXTENSION + Extension + + + GEOM_EXTENSION_MIN + First Parameter + + + GEOM_EXTENSION_MAX + Last Parameter + + + GEOM_EXTENSION_MIN_U + First U-Parameter + + + GEOM_EXTENSION_MAX_U + Last U-Parameter + + + GEOM_EXTENSION_MIN_V + First V-Parameter + + + GEOM_EXTENSION_MAX_V + Last V-Parameter + + + GEOM_EXTENSION_EDGE_NAME + ExtendedEdge + + + GEOM_EXTENSION_FACE_NAME + ExtendedFace + + diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index 2b3b7ca83..55c2d9681 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -587,6 +587,7 @@ void GeometryGUI::OnGUIEvent( int id, const QVariant& theParam ) case GEOMOp::OpMultiTranslate: // MENU TRANSFORMATION - MULTI-TRANSLATION case GEOMOp::OpMultiRotate: // MENU TRANSFORMATION - MULTI-ROTATION case GEOMOp::OpReimport: // CONTEXT(POPUP) MENU - RELOAD_IMPORTED + case GEOMOp::OpExtension: // MENU TRANSFORMATION - EXTENSION libName = "TransformationGUI"; break; case GEOMOp::OpPartition: // MENU OPERATION - PARTITION @@ -963,6 +964,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createGeomAction( GEOMOp::OpProjection, "PROJECTION" ); createGeomAction( GEOMOp::OpMultiTranslate, "MUL_TRANSLATION" ); createGeomAction( GEOMOp::OpMultiRotate, "MUL_ROTATION" ); + createGeomAction( GEOMOp::OpExtension, "EXTENSION" ); createGeomAction( GEOMOp::OpPartition, "PARTITION" ); createGeomAction( GEOMOp::OpArchimede, "ARCHIMEDE" ); @@ -1200,6 +1202,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createMenu( GEOMOp::OpScale, transId, -1 ); createMenu( GEOMOp::OpOffset, transId, -1 ); createMenu( GEOMOp::OpProjection, transId, -1 ); + createMenu( GEOMOp::OpExtension, transId, -1 ); createMenu( separator(), transId, -1 ); createMenu( GEOMOp::OpMultiTranslate, transId, -1 ); createMenu( GEOMOp::OpMultiRotate, transId, -1 ); @@ -1372,6 +1375,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createTool( GEOMOp::OpScale, transTbId ); createTool( GEOMOp::OpOffset, transTbId ); createTool( GEOMOp::OpProjection, transTbId ); + createTool( GEOMOp::OpExtension, transTbId ); createTool( separator(), transTbId ); createTool( GEOMOp::OpMultiTranslate, transTbId ); createTool( GEOMOp::OpMultiRotate, transTbId ); diff --git a/src/GEOMGUI/GeometryGUI_Operations.h b/src/GEOMGUI/GeometryGUI_Operations.h index f392e4df6..ca604b2e7 100644 --- a/src/GEOMGUI/GeometryGUI_Operations.h +++ b/src/GEOMGUI/GeometryGUI_Operations.h @@ -142,6 +142,7 @@ namespace GEOMOp { OpMultiRotate = 3607, // MENU OPERATIONS - TRANSFORMATION - MULTI-ROTATION OpReimport = 3608, // POPUP MENU - RELOAD IMPORTED OpProjection = 3609, // MENU OPERATIONS - TRANSFORMATION - PROJECTION + OpExtension = 3610, // MENU OPERATIONS - TRANSFORMATION - EXTENSION // OperationGUI ----------------//-------------------------------- OpPartition = 3700, // MENU OPERATION - PARTITION OpArchimede = 3701, // MENU OPERATION - ARCHIMEDE diff --git a/src/GEOMImpl/CMakeLists.txt b/src/GEOMImpl/CMakeLists.txt index 0fb145931..734f43505 100755 --- a/src/GEOMImpl/CMakeLists.txt +++ b/src/GEOMImpl/CMakeLists.txt @@ -115,6 +115,7 @@ SET(GEOMImpl_HEADERS GEOMImpl_IRevolution.hxx GEOMImpl_IMeasure.hxx GEOMImpl_IShapes.hxx + GEOMImpl_IShapeExtend.hxx GEOMImpl_IFilling.hxx GEOMImpl_IThruSections.hxx GEOMImpl_IPartition.hxx diff --git a/src/GEOMImpl/GEOMImpl_IShapeExtend.hxx b/src/GEOMImpl/GEOMImpl_IShapeExtend.hxx new file mode 100644 index 000000000..7ef0b2297 --- /dev/null +++ b/src/GEOMImpl/GEOMImpl_IShapeExtend.hxx @@ -0,0 +1,72 @@ +// Copyright (C) 2007-2014 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 +// + +//NOTE: This is an intreface to a function for the extended shape creation. +// +#include "GEOM_Function.hxx" + +#define SHAPE_EXTEND_SHAPE 1 +#define SHAPE_EXTEND_UMIN 2 +#define SHAPE_EXTEND_UMAX 3 +#define SHAPE_EXTEND_VMIN 4 +#define SHAPE_EXTEND_VMAX 5 + +class GEOMImpl_IShapeExtend +{ + public: + + GEOMImpl_IShapeExtend(Handle(GEOM_Function) theFunction): _func(theFunction) {} + + void SetShape(Handle(GEOM_Function) theShape) + { _func->SetReference(SHAPE_EXTEND_SHAPE, theShape); } + + Handle(GEOM_Function) GetShape() + { return _func->GetReference(SHAPE_EXTEND_SHAPE); } + + void SetUMin(const Standard_Real theUMin) + { _func->SetReal(SHAPE_EXTEND_UMIN, theUMin); } + + double GetUMin() + { return _func->GetReal(SHAPE_EXTEND_UMIN); } + + void SetUMax(const Standard_Real theUMax) + { _func->SetReal(SHAPE_EXTEND_UMAX, theUMax); } + + double GetUMax() + { return _func->GetReal(SHAPE_EXTEND_UMAX); } + + void SetVMin(const Standard_Real theVMin) + { _func->SetReal(SHAPE_EXTEND_VMIN, theVMin); } + + double GetVMin() + { return _func->GetReal(SHAPE_EXTEND_VMIN); } + + void SetVMax(const Standard_Real theVMax) + { _func->SetReal(SHAPE_EXTEND_VMAX, theVMax); } + + double GetVMax() + { return _func->GetReal(SHAPE_EXTEND_VMAX); } + + private: + + Handle(GEOM_Function) _func; +}; diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index cf840bc75..637eac7d9 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -37,6 +37,7 @@ #include "GEOMImpl_IVector.hxx" #include "GEOMImpl_IShapes.hxx" +#include "GEOMImpl_IShapeExtend.hxx" #include "GEOMImpl_IGlue.hxx" #include "GEOMImpl_Block6Explorer.hxx" @@ -4832,3 +4833,138 @@ Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs return NULL; } } + +//======================================================================= +//function : ExtendEdge +//purpose : +//======================================================================= +Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendEdge + (const Handle(GEOM_Object) &theEdge, + const Standard_Real theMin, + const Standard_Real theMax) +{ + SetErrorCode(KO); + + if (theEdge.IsNull()) { + return NULL; + } + + //Add a new Edge object + Handle(GEOM_Object) aResEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE); + + //Add a new Vector function + Handle(GEOM_Function) aFunction = + aResEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_UV); + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) { + return NULL; + } + + GEOMImpl_IShapeExtend aCI (aFunction); + + Handle(GEOM_Function) anEdge = theEdge->GetLastFunction(); + + if (anEdge.IsNull()) { + return NULL; + } + + aCI.SetShape(anEdge); + aCI.SetUMin(theMin); + aCI.SetUMax(theMax); + + //Compute the Edge value + try { + OCC_CATCH_SIGNALS; + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Shape driver failed"); + + return NULL; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + + return NULL; + } + + //Make a Python command + GEOM::TPythonDump(aFunction) + << aResEdge << " = geompy.ExtendEdge(" + << theEdge << ", " << theMin << ", " << theMax << ")"; + + SetErrorCode(OK); + + return aResEdge; +} + +//======================================================================= +//function : ExtendFace +//purpose : +//======================================================================= +Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendFace + (const Handle(GEOM_Object) &theFace, + const Standard_Real theUMin, + const Standard_Real theUMax, + const Standard_Real theVMin, + const Standard_Real theVMax) +{ + SetErrorCode(KO); + + if (theFace.IsNull()) { + return NULL; + } + + //Add a new Face object + Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE); + + //Add a new Vector function + Handle(GEOM_Function) aFunction = + aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_UV); + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) { + return NULL; + } + + GEOMImpl_IShapeExtend aCI (aFunction); + + Handle(GEOM_Function) aFace = theFace->GetLastFunction(); + + if (aFace.IsNull()) { + return NULL; + } + + aCI.SetShape(aFace); + aCI.SetUMin(theUMin); + aCI.SetUMax(theUMax); + aCI.SetVMin(theVMin); + aCI.SetVMax(theVMax); + + //Compute the Face value + try { + OCC_CATCH_SIGNALS; + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Shape driver failed"); + + return NULL; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + + return NULL; + } + + //Make a Python command + GEOM::TPythonDump(aFunction) + << aResFace << " = geompy.ExtendFace(" + << theFace << ", " << theUMin << ", " << theUMax << ", " + << theVMin << ", " << theVMax << ")"; + + SetErrorCode(OK); + + return aResFace; +} diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx index 8c15f7190..22b3211ec 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx @@ -384,6 +384,18 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations const Standard_Integer theShapeType, GEOMAlgo_State theState); + Standard_EXPORT Handle(GEOM_Object) + ExtendEdge(const Handle(GEOM_Object) &theEdge, + const Standard_Real theMin, + const Standard_Real theMax); + + Standard_EXPORT Handle(GEOM_Object) + ExtendFace(const Handle(GEOM_Object) &theFace, + const Standard_Real theUMin, + const Standard_Real theUMax, + const Standard_Real theVMin, + const Standard_Real theVMax); + private: Handle(GEOM_Object) MakeShape (std::list theShapes, const Standard_Integer theObjectType, diff --git a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx index d09b3a329..01c676407 100644 --- a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -77,6 +78,7 @@ #include #include +#include #include #include #include @@ -650,6 +652,35 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const Standard_NullObject::Raise ("Shape for isoline construction is not a face"); } + } else if (aType == EDGE_UV) { +#ifdef RESULT_TYPE_CHECK + anExpectedType = TopAbs_EDGE; +#endif + GEOMImpl_IShapeExtend aSE (aFunction); + Handle(GEOM_Function) aRefEdge = aSE.GetShape(); + TopoDS_Shape aShapeEdge = aRefEdge->GetValue(); + + if (aShapeEdge.ShapeType() == TopAbs_EDGE) { + TopoDS_Edge anEdge = TopoDS::Edge(aShapeEdge); + + aShape = ExtendEdge(anEdge, aSE.GetUMin(), aSE.GetUMax()); + } + } else if (aType == FACE_UV) { +#ifdef RESULT_TYPE_CHECK + anExpectedType = TopAbs_FACE; +#endif + + GEOMImpl_IShapeExtend aSE (aFunction); + Handle(GEOM_Function) aRefFace = aSE.GetShape(); + TopoDS_Shape aShapeFace = aRefFace->GetValue(); + + if (aShapeFace.ShapeType() == TopAbs_FACE) { + TopoDS_Face aFace = TopoDS::Face(aShapeFace); + + aFace.Orientation(TopAbs_FORWARD); + aShape = ExtendFace(aFace, aSE.GetUMin(), aSE.GetUMax(), + aSE.GetVMin(), aSE.GetVMax()); + } } else { } @@ -1275,6 +1306,150 @@ TopoDS_Shape GEOMImpl_ShapeDriver::MakeIsoline return aResult; } +//============================================================================= +/*! + * \brief Returns an extended edge. + */ +//============================================================================= + +TopoDS_Shape GEOMImpl_ShapeDriver::ExtendEdge + (const TopoDS_Edge &theEdge, + const Standard_Real theMin, + const Standard_Real theMax) const +{ + TopoDS_Shape aResult; + Standard_Real aF; + Standard_Real aL; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, aF, aL); + const Standard_Real aTol = BRep_Tool::Tolerance(theEdge); + Standard_Real aRange2d = aL - aF; + + if (aCurve.IsNull() == Standard_False && aRange2d > aTol) { + Standard_Real aMin = aF + aRange2d*theMin; + Standard_Real aMax = aF + aRange2d*theMax; + + Handle(Standard_Type) aType = aCurve->DynamicType(); + + // Get the curve of original type + while (aType == STANDARD_TYPE(Geom_TrimmedCurve)) { + Handle(Geom_TrimmedCurve) aTrCurve = + Handle(Geom_TrimmedCurve)::DownCast(aCurve); + + aCurve = aTrCurve->BasisCurve(); + aType = aCurve->DynamicType(); + } + + if (aCurve->IsPeriodic()) { + // The curve is periodic. Check if a new range is less then a period. + if (aMax - aMin > aCurve->Period()) { + aMax = aMin + aCurve->Period(); + } + } else { + // The curve is not periodic. Check if aMin and aMax within bounds. + aMin = Max(aMin, aCurve->FirstParameter()); + aMax = Min(aMax, aCurve->LastParameter()); + } + + if (aMax - aMin > aTol) { + // Create a new edge. + BRepBuilderAPI_MakeEdge aME (aCurve, aMin, aMax); + + if (aME.IsDone()) { + aResult = aME.Shape(); + } + } + } + + return aResult; +} + +//============================================================================= +/*! + * \brief Returns an extended face. + */ +//============================================================================= + +TopoDS_Shape GEOMImpl_ShapeDriver::ExtendFace + (const TopoDS_Face &theFace, + const Standard_Real theUMin, + const Standard_Real theUMax, + const Standard_Real theVMin, + const Standard_Real theVMax) const +{ + TopoDS_Shape aResult; + Handle(Geom_Surface) aSurface = BRep_Tool::Surface(theFace); + const Standard_Real aTol = BRep_Tool::Tolerance(theFace); + Standard_Real aU1; + Standard_Real aU2; + Standard_Real aV1; + Standard_Real aV2; + + // Get U, V bounds of the face. + ShapeAnalysis::GetFaceUVBounds(theFace, aU1, aU2, aV1, aV2); + + const Standard_Real aURange = aU2 - aU1; + const Standard_Real aVRange = aV2 - aV1; + + if (aSurface.IsNull() == Standard_False && + aURange > aTol && aURange > aTol) { + Handle(Standard_Type) aType = aSurface->DynamicType(); + + // Get the surface of original type + while (aType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { + Handle(Geom_RectangularTrimmedSurface) aTrSurface = + Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface); + + aSurface = aTrSurface->BasisSurface(); + aType = aSurface->DynamicType(); + } + + Standard_Real aUMin = aU1 + aURange*theUMin; + Standard_Real aUMax = aU1 + aURange*theUMax; + Standard_Real aVMin = aV1 + aVRange*theVMin; + Standard_Real aVMax = aV1 + aVRange*theVMax; + + aSurface->Bounds(aU1, aU2, aV1, aV2); + + if (aSurface->IsUPeriodic()) { + // The surface is U-periodic. Check if a new U range is less + // then a period. + if (aUMax - aUMin > aSurface->UPeriod()) { + aUMax = aUMin + aSurface->UPeriod(); + } + } else { + // The surface is not V-periodic. Check if aUMin and aUMax + // within bounds. + aUMin = Max(aUMin, aU1); + aUMax = Min(aUMax, aU2); + } + + if (aSurface->IsVPeriodic()) { + // The surface is V-periodic. Check if a new V range is less + // then a period. + if (aVMax - aVMin > aSurface->VPeriod()) { + aVMax = aVMin + aSurface->VPeriod(); + } + } else { + // The surface is not V-periodic. Check if aVMin and aVMax + // within bounds. + aVMin = Max(aVMin, aV1); + aVMax = Min(aVMax, aV2); + } + + if (aUMax - aUMin > aTol && aVMax - aVMin > aTol) { + // Create a new edge. + BRepBuilderAPI_MakeFace aMF + (aSurface, aUMin, aUMax, aVMin, aVMax, aTol); + + if (aMF.IsDone()) { + aResult = aMF.Shape(); + } + } + } + + return aResult; +} + //================================================================================ /*! * \brief Returns a name of creation operation and names and values of creation parameters @@ -1376,6 +1551,28 @@ GetCreationInformation(std::string& theOperationName, AddParam(theParams, "Parameter", aII.GetParameter()); break; } + case EDGE_UV: + { + GEOMImpl_IShapeExtend aSE (function); + + theOperationName = "EDGE_EXTEND"; + AddParam(theParams, "Edge", aSE.GetShape()); + AddParam(theParams, "Min", aSE.GetUMin()); + AddParam(theParams, "Max", aSE.GetUMax()); + break; + } + case FACE_UV: + { + GEOMImpl_IShapeExtend aSE (function); + + theOperationName = "FACE_EXTEND"; + AddParam(theParams, "Face", aSE.GetShape()); + AddParam(theParams, "UMin", aSE.GetUMin()); + AddParam(theParams, "UMax", aSE.GetUMax()); + AddParam(theParams, "VMin", aSE.GetVMin()); + AddParam(theParams, "VMax", aSE.GetVMax()); + break; + } default: return false; } diff --git a/src/GEOMImpl/GEOMImpl_ShapeDriver.hxx b/src/GEOMImpl/GEOMImpl_ShapeDriver.hxx index da699188c..45354d569 100644 --- a/src/GEOMImpl/GEOMImpl_ShapeDriver.hxx +++ b/src/GEOMImpl/GEOMImpl_ShapeDriver.hxx @@ -105,6 +105,16 @@ private: const bool IsUIso, const double theParameter) const; + TopoDS_Shape ExtendEdge(const TopoDS_Edge &theEdge, + const Standard_Real theMin, + const Standard_Real theMax) const; + + TopoDS_Shape ExtendFace(const TopoDS_Face &theFace, + const Standard_Real theUMin, + const Standard_Real theUMax, + const Standard_Real theVMin, + const Standard_Real theVMax) const; + }; #endif diff --git a/src/GEOMImpl/GEOMImpl_Types.hxx b/src/GEOMImpl/GEOMImpl_Types.hxx index 720ce5e6e..86e186981 100644 --- a/src/GEOMImpl/GEOMImpl_Types.hxx +++ b/src/GEOMImpl/GEOMImpl_Types.hxx @@ -300,6 +300,8 @@ #define SHAPES_ON_SHAPE 13 #define SHAPE_ISOLINE 14 #define FACE_FROM_SURFACE 15 +#define EDGE_UV 16 +#define FACE_UV 17 #define ARCHIMEDE_TYPE 1 diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.cc b/src/GEOM_I/GEOM_IShapesOperations_i.cc index a03d84e47..b2fae9ae4 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.cc +++ b/src/GEOM_I/GEOM_IShapesOperations_i.cc @@ -1932,3 +1932,71 @@ GEOM::ListOfLong* GEOM_IShapesOperations_i::GetSameIDs return aSeq._retn(); } + +//============================================================================= +/*! + * ExtendEdge + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::ExtendEdge + (GEOM::GEOM_Object_ptr theEdge, + CORBA::Double theMin, + CORBA::Double theMax) +{ + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + + //Get the reference objects + Handle(GEOM_Object) anEdge = GetObjectImpl(theEdge); + + if (anEdge.IsNull()) { + return aGEOMObject._retn(); + } + + //Get Shapes in place of aShapeWhat + Handle(GEOM_Object) aNewEdge = + GetOperations()->ExtendEdge(anEdge, theMin, theMax); + + if (!GetOperations()->IsDone() || aNewEdge.IsNull()) { + return aGEOMObject._retn(); + } + + return GetObject(aNewEdge); +} + +//============================================================================= +/*! + * ExtendFace + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::ExtendFace + (GEOM::GEOM_Object_ptr theFace, + CORBA::Double theUMin, + CORBA::Double theUMax, + CORBA::Double theVMin, + CORBA::Double theVMax) +{ + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + + //Get the reference objects + Handle(GEOM_Object) aFace = GetObjectImpl(theFace); + + if (aFace.IsNull()) { + return aGEOMObject._retn(); + } + + //Get Shapes in place of aShapeWhat + Handle(GEOM_Object) aNewFace = + GetOperations()->ExtendFace(aFace, theUMin, theUMax, theVMin, theVMax); + + if (!GetOperations()->IsDone() || aNewFace.IsNull()) { + return aGEOMObject._retn(); + } + + return GetObject(aNewFace); +} diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.hh b/src/GEOM_I/GEOM_IShapesOperations_i.hh index be9d5584c..72ac7b074 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.hh +++ b/src/GEOM_I/GEOM_IShapesOperations_i.hh @@ -274,6 +274,16 @@ class GEOM_I_EXPORT GEOM_IShapesOperations_i : GEOM::ListOfLong* GetSameIDs (GEOM::GEOM_Object_ptr theShapeWhere, GEOM::GEOM_Object_ptr theShapeWhat); + GEOM::GEOM_Object_ptr ExtendEdge(GEOM::GEOM_Object_ptr theEdge, + CORBA::Double theMin, + CORBA::Double theMax); + + GEOM::GEOM_Object_ptr ExtendFace(GEOM::GEOM_Object_ptr theFace, + CORBA::Double theUMin, + CORBA::Double theUMax, + CORBA::Double theVMin, + CORBA::Double theVMax); + ::GEOMImpl_IShapesOperations* GetOperations() { return (::GEOMImpl_IShapesOperations*)GetImpl(); } }; diff --git a/src/GEOM_SWIG/GEOM_TestAll.py b/src/GEOM_SWIG/GEOM_TestAll.py index a63590d52..9766171a1 100644 --- a/src/GEOM_SWIG/GEOM_TestAll.py +++ b/src/GEOM_SWIG/GEOM_TestAll.py @@ -255,6 +255,8 @@ def TestAll (geompy, math): Offset = geompy.MakeOffset(Box, 10.) #(GEOM_Object, Double)->GEOM_Object Orientation = geompy.ChangeOrientation(Box) ProjOnWire = geompy.MakeProjectionOnWire(p0, Wire) + ExtEdge = geompy.ExtendEdge(Edge1, -0.3, 1.3) + ExtFace = geompy.ExtendFace(Face5, -0.3, 1.3, -0.1, 1.1) #IDList for Fillet/Chamfer prism_edges = geompy.ExtractShapes(Prism, geompy.ShapeType["EDGE"], True) @@ -469,6 +471,8 @@ def TestAll (geompy, math): id_Offset = geompy.addToStudy(Offset, "Offset") id_Orientation = geompy.addToStudy(Orientation, "Orientation") id_ProjOnWire = geompy.addToStudy(ProjOnWire[1], "ProjOnWire") + id_ExtEdge = geompy.addToStudy(ExtEdge, "ExtendedEdge") + id_ExtFace = geompy.addToStudy(ExtFace, "ExtendedFace") id_Fillet = geompy.addToStudy(Fillet, "Fillet") id_Fillet2 = geompy.addToStudy(Fillet2, "Fillet2") diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index 5a0aa557d..3e9b78b94 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -5667,6 +5667,93 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): RaiseIfFailed("GetSameIDs", self.ShapesOp) return anObj + ## Resize the input edge with the new Min and Max parameters. + # The input edge parameters range is [0, 1]. If theMin parameter is + # negative, the input edge is extended, otherwise it is shrinked by + # theMin parameter. If theMax is greater than 1, the edge is extended, + # otherwise it is shrinked by theMax parameter. + # @param theEdge the input edge to be resized. + # @param theMin the minimal parameter value. + # @param theMax the maximal parameter value. + # @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 edge. + # + # @ref tui_extend "Example" + @ManageTransactions("ShapesOp") + def ExtendEdge(self, theEdge, theMin, theMax, theName=None): + """ + Resize the input edge with the new Min and Max parameters. + The input edge parameters range is [0, 1]. If theMin parameter is + negative, the input edge is extended, otherwise it is shrinked by + theMin parameter. If theMax is greater than 1, the edge is extended, + otherwise it is shrinked by theMax parameter. + + Parameters: + theEdge the input edge to be resized. + theMin the minimal parameter value. + theMax the maximal parameter value. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + + Returns: + New GEOM.GEOM_Object, containing the created edge. + """ + anObj = self.ShapesOp.ExtendEdge(theEdge, theMin, theMax) + RaiseIfFailed("ExtendEdge", self.ShapesOp) + self._autoPublish(anObj, theName, "edge") + return anObj + + ## Resize the input face with the new UMin, UMax, VMin and VMax + # parameters. The input face U and V parameters range is [0, 1]. If + # theUMin parameter is negative, the input face is extended, otherwise + # it is shrinked along U direction by theUMin parameter. If theUMax is + # greater than 1, the face is extended, otherwise it is shrinked along + # U direction by theUMax parameter. So as for theVMin, theVMax and + # V direction of the input face. + # @param theFace the input face to be resized. + # @param theUMin the minimal U parameter value. + # @param theUMax the maximal U parameter value. + # @param theVMin the minimal V parameter value. + # @param theVMax the maximal V parameter value. + # @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 face. + # + # @ref tui_extend "Example" + @ManageTransactions("ShapesOp") + def ExtendFace(self, theFace, theUMin, theUMax, + theVMin, theVMax, theName=None): + """ + Resize the input face with the new UMin, UMax, VMin and VMax + parameters. The input face U and V parameters range is [0, 1]. If + theUMin parameter is negative, the input face is extended, otherwise + it is shrinked along U direction by theUMin parameter. If theUMax is + greater than 1, the face is extended, otherwise it is shrinked along + U direction by theUMax parameter. So as for theVMin, theVMax and + V direction of the input face. + + Parameters: + theFace the input face to be resized. + theUMin the minimal U parameter value. + theUMax the maximal U parameter value. + theVMin the minimal V parameter value. + theVMax the maximal V parameter value. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + + Returns: + New GEOM.GEOM_Object, containing the created face. + """ + anObj = self.ShapesOp.ExtendFace(theFace, theUMin, theUMax, + theVMin, theVMax) + RaiseIfFailed("ExtendFace", self.ShapesOp) + self._autoPublish(anObj, theName, "face") + return anObj # end of l4_obtain ## @} diff --git a/src/TransformationGUI/CMakeLists.txt b/src/TransformationGUI/CMakeLists.txt index e20407629..34622e9c4 100755 --- a/src/TransformationGUI/CMakeLists.txt +++ b/src/TransformationGUI/CMakeLists.txt @@ -66,6 +66,7 @@ SET(_uic_files SET(TransformationGUI_HEADERS TransformationGUI.h + TransformationGUI_ExtensionDlg.h TransformationGUI_MultiTranslationDlg.h TransformationGUI_MultiRotationDlg.h TransformationGUI_TranslationDlg.h @@ -79,6 +80,7 @@ SET(TransformationGUI_HEADERS # header files / to be processed by moc SET(_moc_HEADERS + TransformationGUI_ExtensionDlg.h TransformationGUI_MultiTranslationDlg.h TransformationGUI_MultiRotationDlg.h TransformationGUI_TranslationDlg.h @@ -100,6 +102,7 @@ QT4_WRAP_CPP(_moc_SOURCES ${_moc_HEADERS}) SET(TransformationGUI_SOURCES TransformationGUI.cxx + TransformationGUI_ExtensionDlg.cxx TransformationGUI_MultiTranslationDlg.cxx TransformationGUI_MultiRotationDlg.cxx TransformationGUI_TranslationDlg.cxx diff --git a/src/TransformationGUI/TransformationGUI.cxx b/src/TransformationGUI/TransformationGUI.cxx index 4a6fe2fbc..beefbf8f1 100644 --- a/src/TransformationGUI/TransformationGUI.cxx +++ b/src/TransformationGUI/TransformationGUI.cxx @@ -39,6 +39,7 @@ #include #include +#include "TransformationGUI_ExtensionDlg.h" // Method EXTENSION #include "TransformationGUI_MultiTranslationDlg.h" // Method MULTI TRANSLATION #include "TransformationGUI_MultiRotationDlg.h" // Method MULTI ROTATION #include "TransformationGUI_TranslationDlg.h" // Method TRANSLATION @@ -151,6 +152,9 @@ bool TransformationGUI::OnGUIEvent( int theCommandID, SUIT_Desktop* parent ) } // for (; aSelIt.More(); aSelIt.Next()) } break; + case GEOMOp::OpExtension: // EXTENSION + aDlg = new TransformationGUI_ExtensionDlg( getGeometryGUI(), parent ); + break; default: app->putInfo( tr( "GEOM_PRP_COMMAND" ).arg( theCommandID ) ); break; diff --git a/src/TransformationGUI/TransformationGUI_ExtensionDlg.cxx b/src/TransformationGUI/TransformationGUI_ExtensionDlg.cxx new file mode 100644 index 000000000..91428ef36 --- /dev/null +++ b/src/TransformationGUI/TransformationGUI_ExtensionDlg.cxx @@ -0,0 +1,411 @@ +// Copyright (C) 2007-2014 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 : TransformationGUI_ExtensionDlg.cxx +// Author : Sergey KHROMOV, Open CASCADE S.A.S. + +#include "TransformationGUI_ExtensionDlg.h" +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + + +//================================================================================= +// class : TransformationGUI_ExtensionDlg +// purpose : +//================================================================================= +TransformationGUI_ExtensionDlg::TransformationGUI_ExtensionDlg + (GeometryGUI* theGeometryGUI, QWidget* parent, + bool modal, Qt::WindowFlags fl) + : GEOMBase_Skeleton(theGeometryGUI, parent, modal, fl), + myObjLbl (0), + myUMinLbl (0), + myUMaxLbl (0), + myVMinLbl (0), + myVMaxLbl (0), + mySelButton (0), + myEditObjName (0), + myUMinSpinBox (0), + myUMaxSpinBox (0), + myVMinSpinBox (0), + myVMaxSpinBox (0) +{ + QPixmap image0 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT"))); + QPixmap image1 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_EXTEND_EDGE"))); + QPixmap image2 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_EXTEND_FACE"))); + + setWindowTitle(tr("GEOM_EXTENSION_TITLE")); + + /***************************************************************/ + mainFrame()->GroupConstructors->setTitle(tr ("GEOM_EXTENSION")); + mainFrame()->RadioButton1->setIcon(image1); + mainFrame()->RadioButton2->setIcon(image2); + mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose); + mainFrame()->RadioButton3->close(); + + QGroupBox *aGrp = new QGroupBox(tr("GEOM_ARGUMENTS")); + + myObjLbl = new QLabel; + myUMinLbl = new QLabel; + myUMaxLbl = new QLabel; + myVMinLbl = new QLabel; + myVMaxLbl = new QLabel; + mySelButton = new QPushButton; + myEditObjName = new QLineEdit; + myUMinSpinBox = new SalomeApp_DoubleSpinBox; + myUMaxSpinBox = new SalomeApp_DoubleSpinBox; + myVMinSpinBox = new SalomeApp_DoubleSpinBox; + myVMaxSpinBox = new SalomeApp_DoubleSpinBox; + + myVMinLbl->setText(tr("GEOM_EXTENSION_MIN_V")); + myVMaxLbl->setText(tr("GEOM_EXTENSION_MAX_V")); + mySelButton->setIcon(image0); + + QGridLayout *aGrpLayout = new QGridLayout(aGrp); + + aGrpLayout->setMargin(9); + aGrpLayout->setSpacing(6); + aGrpLayout->addWidget(myObjLbl, 0, 0); + aGrpLayout->addWidget(myUMinLbl, 1, 0); + aGrpLayout->addWidget(myUMaxLbl, 2, 0); + aGrpLayout->addWidget(myVMinLbl, 3, 0); + aGrpLayout->addWidget(myVMaxLbl, 4, 0); + aGrpLayout->addWidget(mySelButton, 0, 1); + aGrpLayout->addWidget(myEditObjName, 0, 2); + aGrpLayout->addWidget(myUMinSpinBox, 1, 1, 1, 2); + aGrpLayout->addWidget(myUMaxSpinBox, 2, 1, 1, 2); + aGrpLayout->addWidget(myVMinSpinBox, 3, 1, 1, 2); + aGrpLayout->addWidget(myVMaxSpinBox, 4, 1, 1, 2); + + myVMinLbl->hide(); + myVMaxLbl->hide(); + myVMinSpinBox->hide(); + myVMaxSpinBox->hide(); + + QVBoxLayout* layout = new QVBoxLayout(centralWidget()); + layout->setMargin(0); layout->setSpacing(6); + layout->addWidget(aGrp); + /***************************************************************/ + + setHelpFileName("extension_operation_page.html"); + + /* Initialisations */ + Init(); +} + +//================================================================================= +// function : ~GenerationGUI_FillingDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +TransformationGUI_ExtensionDlg::~TransformationGUI_ExtensionDlg() +{ + // no need to delete child widgets, Qt does it all for us +} + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void TransformationGUI_ExtensionDlg::Init() +{ + /* init variables */ + showOnlyPreviewControl(); + myEditCurrentArgument = myEditObjName; + + double aStep = 0.1; + /* min, max, step and decimals for spin boxes & initial values */ + initSpinBox(myUMinSpinBox, -MAX_NUMBER, MAX_NUMBER, aStep, "parametric_precision"); + initSpinBox(myUMaxSpinBox, -MAX_NUMBER, MAX_NUMBER, aStep, "parametric_precision"); + initSpinBox(myVMinSpinBox, -MAX_NUMBER, MAX_NUMBER, aStep, "parametric_precision"); + initSpinBox(myVMaxSpinBox, -MAX_NUMBER, MAX_NUMBER, aStep, "parametric_precision"); + + myUMinSpinBox->setValue(0.); + myUMaxSpinBox->setValue(1.); + myVMinSpinBox->setValue(0.); + myVMaxSpinBox->setValue(1.); + + /* signals and slots connections */ + connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog())); + connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(ClickOnCancel())); + + connect(this, SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int))); + + connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk())); + connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply())); + connect(mySelButton, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); + + connect(myUMinSpinBox, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); + connect(myUMaxSpinBox, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); + connect(myVMinSpinBox, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); + connect(myVMaxSpinBox, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); + + connect(myGeomGUI, SIGNAL(SignalDefaultStepValueChanged(double)), this, SLOT(SetDoubleSpinBoxStep(double))); + + connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(), + SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); + + initName(tr("GEOM_EXTENSION_EDGE_NAME")); + resize(100,100); + + ConstructorsClicked(0); +} + +//================================================================================= +// function : SetDoubleSpinBoxStep() +// purpose : Double spin box management +//================================================================================= +void TransformationGUI_ExtensionDlg::SetDoubleSpinBoxStep(double step) +{ + myUMinSpinBox->setSingleStep(step); + myUMaxSpinBox->setSingleStep(step); + myVMinSpinBox->setSingleStep(step); + myVMaxSpinBox->setSingleStep(step); +} + +//================================================================================= +// function : ConstructorsClicked() +// purpose : Radio button management +//================================================================================= +void TransformationGUI_ExtensionDlg::ConstructorsClicked (int constructorId) +{ + switch (constructorId) { + case 0: // Extend edge + { + TColStd_MapOfInteger aMap; + + aMap.Add(GEOM_EDGE); + globalSelection(aMap); + + myObjLbl->setText(tr("GEOM_EDGE")); + myUMinLbl->setText(tr("GEOM_EXTENSION_MIN")); + myUMaxLbl->setText(tr("GEOM_EXTENSION_MAX")); + myVMinLbl->hide(); + myVMaxLbl->hide(); + myVMinSpinBox->hide(); + myVMaxSpinBox->hide(); + + initName(tr("GEOM_EXTENSION_EDGE_NAME")); + + break; + } + case 1: // Extend face + { + TColStd_MapOfInteger aMap; + + aMap.Add(GEOM_FACE); + globalSelection(aMap); + + myObjLbl->setText(tr("GEOM_FACE")); + myUMinLbl->setText(tr("GEOM_EXTENSION_MIN_U")); + myUMaxLbl->setText(tr("GEOM_EXTENSION_MAX_U")); + myVMinLbl->show(); + myVMaxLbl->show(); + myVMinSpinBox->show(); + myVMaxSpinBox->show(); + + initName(tr("GEOM_EXTENSION_FACE_NAME")); + + break; + } + default: + break; + } + + myBase.nullify(); + qApp->processEvents(); + updateGeometry(); + resize(minimumSizeHint()); + + SelectionIntoArgument(); +} + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void TransformationGUI_ExtensionDlg::ClickOnOk() +{ + setIsApplyAndClose(true); + if (ClickOnApply()) + ClickOnCancel(); +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +bool TransformationGUI_ExtensionDlg::ClickOnApply() +{ + if (!onAccept()) + return false; + + initName(); + + return true; +} + +//================================================================================= +// function : SelectionIntoArgument() +// purpose : Called when selection as changed or other case +//================================================================================= +void TransformationGUI_ExtensionDlg::SelectionIntoArgument() +{ + erasePreview(); + myEditCurrentArgument->setText(""); + + if (myEditCurrentArgument == myEditObjName) { + const TopAbs_ShapeEnum aType = + getConstructorId() == 0 ? TopAbs_EDGE: TopAbs_FACE; + GEOM::GeomObjPtr aSelectedObject = getSelected(aType); + + if (aSelectedObject) { + myEditCurrentArgument->setText(GEOMBase::GetName(aSelectedObject.get())); + myBase = aSelectedObject; + } else { + myBase.nullify(); + } + } + + processPreview(); +} + +//================================================================================= +// function : SetEditCurrentArgument() +// purpose : +//================================================================================= +void TransformationGUI_ExtensionDlg::SetEditCurrentArgument() +{ + QPushButton* send = (QPushButton*)sender(); + + if (send == mySelButton) { + myEditObjName->setFocus(); + myEditCurrentArgument = myEditObjName; + SelectionIntoArgument(); + } +} + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void TransformationGUI_ExtensionDlg::ActivateThisDialog() +{ + GEOMBase_Skeleton::ActivateThisDialog(); + connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(), + SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); + + ConstructorsClicked(getConstructorId()); +} + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void TransformationGUI_ExtensionDlg::enterEvent(QEvent*) +{ + if (!mainFrame()->GroupConstructors->isEnabled()) + ActivateThisDialog(); +} + +//================================================================================= +// function : ValueChangedInSpinBox() +// purpose : +//================================================================================= +void TransformationGUI_ExtensionDlg::ValueChangedInSpinBox(double newValue) +{ + processPreview(); +} + +//================================================================================= +// function : createOperation +// purpose : +//================================================================================= +GEOM::GEOM_IOperations_ptr TransformationGUI_ExtensionDlg::createOperation() +{ + return getGeomEngine()->GetIShapesOperations(getStudyId()); +} + +//================================================================================= +// function : isValid +// purpose : +//================================================================================= +bool TransformationGUI_ExtensionDlg::isValid(QString& msg) +{ + bool ok = (myUMinSpinBox->isValid(msg, !IsPreview()) && + myUMaxSpinBox->isValid(msg, !IsPreview()) && + myVMinSpinBox->isValid(msg, !IsPreview()) && + myVMaxSpinBox->isValid(msg, !IsPreview()) && + myBase); + return ok; +} + +//================================================================================= +// function : execute +// purpose : +//================================================================================= +bool TransformationGUI_ExtensionDlg::execute(ObjectList& objects) +{ + bool res = false; + GEOM::GEOM_IShapesOperations_var anOper = + GEOM::GEOM_IShapesOperations::_narrow(getOperation()); + GEOM::GEOM_Object_var anObj; + + switch (getConstructorId()) { + case 0: + anObj = anOper->ExtendEdge(myBase.get(), myUMinSpinBox->value(), + myUMaxSpinBox->value()); + res = true; + break; + case 1: + anObj = anOper->ExtendFace(myBase.get(), myUMinSpinBox->value(), + myUMaxSpinBox->value(), + myVMinSpinBox->value(), + myVMaxSpinBox->value()); + res = true; + break; + default: + break; + } + + if (!anObj->_is_nil()) { + objects.push_back(anObj._retn()); + } + + return res; +} diff --git a/src/TransformationGUI/TransformationGUI_ExtensionDlg.h b/src/TransformationGUI/TransformationGUI_ExtensionDlg.h new file mode 100644 index 000000000..b03eb6a2e --- /dev/null +++ b/src/TransformationGUI/TransformationGUI_ExtensionDlg.h @@ -0,0 +1,83 @@ +// Copyright (C) 2007-2014 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 : TransformationGUI_ExtensionDlg.h +// Author : Sergey KHROMOV, Open CASCADE S.A.S. +// +#ifndef TRANSFORMATIONGUI_EXTENSIONDLG_H +#define TRANSFORMATIONGUI_EXTENSIONDLG_H + +#include "GEOMBase_Skeleton.h" +#include "GEOM_GenericObjPtr.h" + +class DlgRef_3Sel4Spin2Check; + +/** + * This is a dialog for ExtendEdge and ExtendFace functionality + */ +class TransformationGUI_ExtensionDlg : public GEOMBase_Skeleton +{ + Q_OBJECT + +public: + TransformationGUI_ExtensionDlg(GeometryGUI*, QWidget* = 0, + bool = false, Qt::WindowFlags = 0); + ~TransformationGUI_ExtensionDlg(); + +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: + + QLabel *myObjLbl; + QLabel *myUMinLbl; + QLabel *myUMaxLbl; + QLabel *myVMinLbl; + QLabel *myVMaxLbl; + QPushButton *mySelButton; + QLineEdit *myEditObjName; + SalomeApp_DoubleSpinBox *myUMinSpinBox; + SalomeApp_DoubleSpinBox *myUMaxSpinBox; + SalomeApp_DoubleSpinBox *myVMinSpinBox; + SalomeApp_DoubleSpinBox *myVMaxSpinBox; + GEOM::GeomObjPtr myBase; + +private slots: + void ClickOnOk(); + bool ClickOnApply(); + void ActivateThisDialog(); + void SelectionIntoArgument(); + void SetEditCurrentArgument(); + void ValueChangedInSpinBox( double ); + void ConstructorsClicked( int ); + void SetDoubleSpinBoxStep( double ); +}; + +#endif // TRANSFORMATIONGUI_EXTENSIONDLG_H