diff --git a/doc/salome/gui/GEOM/images/transformation12.png b/doc/salome/gui/GEOM/images/transformation12.png new file mode 100644 index 000000000..66ea98415 Binary files /dev/null and b/doc/salome/gui/GEOM/images/transformation12.png differ diff --git a/doc/salome/gui/GEOM/images/transformation13.png b/doc/salome/gui/GEOM/images/transformation13.png new file mode 100644 index 000000000..71efd5599 Binary files /dev/null and b/doc/salome/gui/GEOM/images/transformation13.png differ diff --git a/doc/salome/gui/GEOM/images/transformation14.png b/doc/salome/gui/GEOM/images/transformation14.png new file mode 100644 index 000000000..ba31ef99b Binary files /dev/null and b/doc/salome/gui/GEOM/images/transformation14.png differ diff --git a/doc/salome/gui/GEOM/images/transformation5.png b/doc/salome/gui/GEOM/images/transformation5.png index 9b405c811..48b632622 100755 Binary files a/doc/salome/gui/GEOM/images/transformation5.png and b/doc/salome/gui/GEOM/images/transformation5.png differ diff --git a/doc/salome/gui/GEOM/images/transformation6.png b/doc/salome/gui/GEOM/images/transformation6.png index 356c8e632..b77c7450f 100755 Binary files a/doc/salome/gui/GEOM/images/transformation6.png and b/doc/salome/gui/GEOM/images/transformation6.png differ diff --git a/doc/salome/gui/GEOM/input/modify_location_operation.doc b/doc/salome/gui/GEOM/input/modify_location_operation.doc index 87c958845..3bb8a6ede 100644 --- a/doc/salome/gui/GEOM/input/modify_location_operation.doc +++ b/doc/salome/gui/GEOM/input/modify_location_operation.doc @@ -54,12 +54,29 @@ translated cube at the position (-100;0;0) \image html image4.gif +The third algorithm modifies the location of an object using the Path object (Wire or Edge) +and the Distance parameter (ranging from 0 to 1) defining how far the object will move along the path. +\n Create a copy checkbox allows to keep the initial object, +otherwise it will be removed. +\n Select Unpublished edges checkbox allows to select subshape edges on +the other objects. +\n Arguments: Name + one or several objects + Translation path. +\n Advanced option: + \ref restore_presentation_parameters_page "Set presentation + parameters and subshapes from arguments". + +\image html transformation13.png + +\image html transformation14.png + +\image html transformation12.png + \n TUI Command: geompy.MakePosition(theObject, theStartLCS, theEndLCS), where \em theObject is a shape, location of which is modified, \em theStartLCS is a location to move the shape from, \em theEndLCS is a location to move the shape to. \n Our TUI Scripts provide you with useful examples of the use -of \ref tui_translation "Transformation Operations". +of \ref tui_modify_location "Transformation Operations". */ diff --git a/doc/salome/gui/GEOM/input/tui_transformation_operations.doc b/doc/salome/gui/GEOM/input/tui_transformation_operations.doc index a4863b537..73985a581 100644 --- a/doc/salome/gui/GEOM/input/tui_transformation_operations.doc +++ b/doc/salome/gui/GEOM/input/tui_transformation_operations.doc @@ -115,6 +115,7 @@ v = geompy.MakeVector(p1, p2) height = 35 radius1 = 20 cylinder = geompy.MakeCylinder(p1, v, radius1, height) +circle = geompy.MakeCircle(p2, v, radius1) # create local coordinate systems cs1 = geompy.MakeMarker( 0, 0, 0, 1,0,0, 0,1,0) @@ -122,18 +123,25 @@ cs2 = geompy.MakeMarker(30,40,40, 1,0,0, 0,1,0) # modify the location of the given object position = geompy.MakePosition(cylinder, cs1, cs2) +position2 = geompy.PositionAlongPath(position, circle, 0.75, 1) # add objects in the study id_cs1 = geompy.addToStudy(cs1, "Coordinate system 1") id_cs2 = geompy.addToStudy(cs2, "Coordinate system 2") id_cylinder = geompy.addToStudy(cylinder, "Cylinder") +id_circle = geompy.addToStudy(circle, "Circle") id_position = geompy.addToStudy(position, "Position") +id_position2 = geompy.addToStudy(position2, "PositionAlongPath") # display the results gg.createAndDisplayGO(id_cylinder) gg.setDisplayMode(id_cylinder,1) gg.createAndDisplayGO(id_position) gg.setDisplayMode(id_position,1) +gg.createAndDisplayGO(id_circle) +gg.setDisplayMode(id_circle,1) +gg.createAndDisplayGO(id_position2) +gg.setDisplayMode(id_position2,1) \endcode \anchor tui_mirror diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index fd153f760..afbc705a5 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -793,6 +793,20 @@ module GEOM in GEOM_Object theStartLCS, in GEOM_Object theEndLCS); + /*! + * Modify the Location of the given object by Path, + * \param theObject The object to be displaced. + * \param thePath Wire or Edge along that the object will be translated. + * \param theDistance progress of Path (0 = actual location, 1 = end of path location). + * \param theCopy is a true or false parameter. true is to create a copy, false to move the object. + * \return New GEOM_Object, containing the displaced shape. + */ + + GEOM_Object PositionAlongPath (in GEOM_Object theObject, + in GEOM_Object thePath, + in double theDistance, + in boolean theCopy); + /*! * Recompute the shape from its arguments. * \param theObject The object to be recomputed. diff --git a/idl/GEOM_Superv.idl b/idl/GEOM_Superv.idl index 725d36075..50c350166 100644 --- a/idl/GEOM_Superv.idl +++ b/idl/GEOM_Superv.idl @@ -343,6 +343,10 @@ module GEOM GEOM_Object PositionShapeCopy (in GEOM_Object theObject, in GEOM_Object theStartLCS, in GEOM_Object theEndLCS) ; + GEOM_Object PositionAlongPath (in GEOM_Object theObject, + in GEOM_Object thePath, + in double theDistance, + in boolean theCopy); //-----------------------------------------------------------// // ShapesOperations // diff --git a/resources/Makefile.am b/resources/Makefile.am index 9f8e9ecfd..3d4405ed0 100644 --- a/resources/Makefile.am +++ b/resources/Makefile.am @@ -184,6 +184,7 @@ marker2.png \ marker3.png \ position.png \ position2.png \ +position3.png \ free_bound.png \ point_coord.png \ point3.png \ diff --git a/resources/position3.png b/resources/position3.png new file mode 100644 index 000000000..301a3bf09 Binary files /dev/null and b/resources/position3.png differ diff --git a/src/DlgRef/DlgRef_4Sel1Spin2Check_QTD.ui b/src/DlgRef/DlgRef_4Sel1Spin2Check_QTD.ui index 43217034f..131736af7 100644 --- a/src/DlgRef/DlgRef_4Sel1Spin2Check_QTD.ui +++ b/src/DlgRef/DlgRef_4Sel1Spin2Check_QTD.ui @@ -5,30 +5,18 @@ 0 0 - 131 - 196 + 225 + 306 - + 0 - - 0 - - - 0 - - - 0 - - - 6 - - + 6 @@ -37,44 +25,12 @@ - + 9 - - 9 - - - 9 - - - 9 - - + 6 - - 6 - - - - - - - - - - - - - 0 - 0 - - - - - - - @@ -229,7 +185,43 @@ + + + + + + + + + + + + 0 + 0 + + + + + + + + SpinBox_DX + TextLabel3 + TextLabel5 + TextLabel4 + TextLabel2 + TextLabel1 + PushButton2 + LineEdit5 + LineEdit1 + PushButton5 + PushButton4 + PushButton1 + LineEdit4 + LineEdit2 + CheckButton1 + CheckButton2 @@ -253,7 +245,6 @@ PushButton5 LineEdit5 SpinBox_DX - CheckButton2 CheckButton1 diff --git a/src/GEOMGUI/GEOM_images.ts b/src/GEOMGUI/GEOM_images.ts index c3f1d2083..5fcf863eb 100644 --- a/src/GEOMGUI/GEOM_images.ts +++ b/src/GEOMGUI/GEOM_images.ts @@ -362,6 +362,10 @@ ICON_DLG_POSITION2 position2.png + + ICON_DLG_POSITION3 + position3.png + ICON_DLG_PRISM prism.png diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 56697113c..fc4d51282 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -1564,6 +1564,10 @@ Please, select face, shell or solid and try again GEOM_START_LCS Start LCS + + SELECT_UNPUBLISHED_EDGES + Select unpublished edges + GEOM_STEP Step : diff --git a/src/GEOMImpl/GEOMImpl_IPosition.hxx b/src/GEOMImpl/GEOMImpl_IPosition.hxx index 77a0e358a..b01b1115a 100644 --- a/src/GEOMImpl/GEOMImpl_IPosition.hxx +++ b/src/GEOMImpl/GEOMImpl_IPosition.hxx @@ -22,9 +22,11 @@ #include "GEOM_Function.hxx" -#define POSITION_ARG_SHAPE 1 +#define POSITION_ARG_SHAPE 1 #define POSITION_ARG_START_LCS 2 -#define POSITION_ARG_END_LCS 3 +#define POSITION_ARG_END_LCS 3 +#define POSITION_ARG_PATH 5 +#define POSITION_ARG_DISTANCE 6 class GEOMImpl_IPosition { @@ -46,6 +48,14 @@ class GEOMImpl_IPosition Handle(GEOM_Function) GetEndLCS() { return _func->GetReference(POSITION_ARG_END_LCS); } + void SetPath(Handle(GEOM_Function) thePath) { _func->SetReference(POSITION_ARG_PATH, thePath); } + + Handle(GEOM_Function) GetPath() { return _func->GetReference(POSITION_ARG_PATH); } + + void SetDistance(double theDistance) { _func->SetReal(POSITION_ARG_DISTANCE, theDistance); } + + double GetDistance() { return _func->GetReal(POSITION_ARG_DISTANCE); } + private: Handle(GEOM_Function) _func; diff --git a/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx b/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx index 957197365..84a0f4991 100644 --- a/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx @@ -1334,6 +1334,74 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::PositionShapeCopy return aCopy; } +//============================================================================= +/*! + * PositionAlongPath + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_ITransformOperations::PositionAlongPath + (Handle(GEOM_Object) theObject, Handle(GEOM_Object) thePath, + double theDistance, bool theCopy) +{ + SetErrorCode(KO); + + if (theObject.IsNull() || thePath.IsNull()) return NULL; + + Handle(GEOM_Function) anOriginal = theObject->GetLastFunction(); + if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be set in position + + //Add a position function + Handle(GEOM_Function) aFunction; + Handle(GEOM_Object) aCopy; + + if (theCopy) { + aCopy = GetEngine()->AddObject(GetDocID(), theObject->GetType()); + aFunction = aCopy->AddFunction(GEOMImpl_PositionDriver::GetID(), POSITION_ALONG_PATH); + } + else + aFunction = theObject->AddFunction(GEOMImpl_PositionDriver::GetID(), POSITION_ALONG_PATH); + + if (aFunction.IsNull()) return NULL; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_PositionDriver::GetID()) return NULL; + + GEOMImpl_IPosition aTI (aFunction); + aTI.SetShape(anOriginal); + aTI.SetPath(thePath->GetLastFunction()); + aTI.SetDistance(theDistance); + + //Compute the position + try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Position driver failed"); + return NULL; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return NULL; + } + + //Make a Python command + if (theCopy) { + GEOM::TPythonDump(aFunction) << aCopy << " = geompy.PositionAlongPath(" + << theObject << ", " << thePath << ", " << theDistance << ", " << theCopy << ")"; + SetErrorCode(OK); + return aCopy; + } + + GEOM::TPythonDump(aFunction) << "geompy.TrsfOp.PositionAlongPath(" + << theObject << ", " << thePath << ", " << theDistance << ", " << theCopy << ")"; + + SetErrorCode(OK); + return theObject; +} + //============================================================================= /*! * Rotate diff --git a/src/GEOMImpl/GEOMImpl_ITransformOperations.hxx b/src/GEOMImpl/GEOMImpl_ITransformOperations.hxx index c949641aa..44830f68c 100644 --- a/src/GEOMImpl/GEOMImpl_ITransformOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_ITransformOperations.hxx @@ -118,6 +118,11 @@ class GEOMImpl_ITransformOperations : public GEOM_IOperations Handle(GEOM_Object) theStartLCS, Handle(GEOM_Object) theEndLCS); + Standard_EXPORT Handle(GEOM_Object) PositionAlongPath (Handle(GEOM_Object) theObject, + Handle(GEOM_Object) thePath, + double theDistance, + bool theCopy); + Standard_EXPORT Handle(GEOM_Object) Rotate (Handle(GEOM_Object) theObject, Handle(GEOM_Object) theAxis, double theAngle); diff --git a/src/GEOMImpl/GEOMImpl_PositionDriver.cxx b/src/GEOMImpl/GEOMImpl_PositionDriver.cxx index 789575c79..c9ddc2097 100644 --- a/src/GEOMImpl/GEOMImpl_PositionDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PositionDriver.cxx @@ -29,19 +29,30 @@ // OCCT Includes #include +#include +#include #include +#include #include #include #include +#include +#include #include #include +#include #include #include +#include #include #include +#include +#include #include #include +#include +#include //======================================================================= //function : GetID @@ -130,6 +141,106 @@ Standard_Integer GEOMImpl_PositionDriver::Execute(TFunction_Logbook& log) const BRepBuilderAPI_Transform aBRepTrsf (aShapeBase, aTrsf, Standard_False); aShape = aBRepTrsf.Shape(); } + else if (aType == POSITION_ALONG_PATH) { + Handle(GEOM_Function) aRefShape = aCI.GetShape(); + Handle(GEOM_Function) aPathShape = aCI.GetPath(); + double aValue = aCI.GetDistance(); + + TopoDS_Shape aShapeBase = aRefShape->GetValue(); + TopoDS_Shape aPath = aPathShape->GetValue(); + + if (aShapeBase.IsNull() || aPath.IsNull()) + return 0; + + TopoDS_Shape aTrimmedPath; + gp_Trsf aTrsf; + Handle(Geom_Curve) aCurve; + Standard_Real aFirst =0.,aLast=0.; + Standard_Real aParam = 0.; + Standard_Real aLength = 0.; + + if ( aPath.ShapeType() == TopAbs_EDGE ) { + TopoDS_Edge anEdge = TopoDS::Edge(aPath); + // Computation by Parameter + BRep_Tool::Range(anEdge,aFirst,aLast); + aCurve = BRep_Tool::Curve(anEdge,aFirst,aLast); + aParam = aFirst + aValue*(aLast - aFirst); + } else if ( aPath.ShapeType() == TopAbs_WIRE ) { + TopExp_Explorer ex; + TopTools_SequenceOfShape Edges; + Standard_Real nbEdges = 0.; + BRepTools_WireExplorer aWE (TopoDS::Wire(aPath)); + for (; aWE.More(); aWE.Next(), nbEdges++) + Edges.Append(aWE.Current()); + + Standard_Real aSummOfLen =0.; + Standard_Real aCurLen =0.; + GeomAdaptor_Curve aAdC; + for(int i=1; i<=Edges.Length(); i++) { + TopoDS_Edge anEdge = TopoDS::Edge(Edges.Value(i)); + BRep_Tool::Range(anEdge,aFirst,aLast); + aCurve = BRep_Tool::Curve(anEdge,aFirst,aLast); + aAdC.Load(aCurve,aFirst,aLast); + aCurLen = GCPnts_AbscissaPoint::Length(aAdC,aFirst,aLast); + aSummOfLen += aCurLen; + } + + Standard_Real aWireLen = aSummOfLen*aValue; + aSummOfLen = 0; + for(int i=1; i<=Edges.Length(); i++) { + TopoDS_Edge anEdge = TopoDS::Edge(Edges.Value(i)); + BRep_Tool::Range(anEdge,aFirst,aLast); + aCurve = BRep_Tool::Curve(anEdge,aFirst,aLast); + aAdC.Load(aCurve,aFirst,aLast); + aCurLen = GCPnts_AbscissaPoint::Length(aAdC,aFirst,aLast); + + if ( aWireLen > (aSummOfLen + aCurLen) ) { + aSummOfLen += aCurLen; // Transform a Base object along this Edge + gp_Pnt aP1, aP2; + gp_Vec aStartVec1, aStartVec2, aDestVec1, aDestVec2; + aCurve->D2(aFirst, aP1, aStartVec1, aStartVec2 ); + aCurve->D2(aLast, aP2, aDestVec1, aDestVec2 ); + gp_Trsf aCurTrsf; + if (aStartVec2.Magnitude() < gp::Resolution() || aDestVec2.Magnitude() < gp::Resolution()) // one of the second derivatives is null + aCurTrsf.SetTranslation(aP1, aP2); + else { + gp_Ax3 aStartAx3(aP1, aStartVec1, aStartVec2); + gp_Ax3 aDestAx3(aP2, aDestVec1, aDestVec2); + aCurTrsf.SetDisplacement(aStartAx3, aDestAx3); + } + aTrsf.PreMultiply(aCurTrsf); + } + else { + aLength = aWireLen - aSummOfLen; + GCPnts_AbscissaPoint anAbsc(aAdC,aLength,aFirst); + if(anAbsc.IsDone()) + aParam = anAbsc.Parameter(); + break; + } + } + } else + return 0; // Unknown Type + + gp_Pnt aP1, aP2; + gp_Vec aStartVec1, aStartVec2, aDestVec1, aDestVec2; + aCurve->D2(aFirst, aP1, aStartVec1, aStartVec2 ); + aCurve->D2(aParam, aP2, aDestVec1, aDestVec2 ); + gp_Trsf aCurTrsf; + + if (aStartVec2.Magnitude() < gp::Resolution() || aDestVec2.Magnitude() < gp::Resolution()) // one of the second derivatives is null + aCurTrsf.SetTranslation(aP1, aP2); + else { + gp_Ax3 aStartAx3(aP1, aStartVec1, aStartVec2); + gp_Ax3 aDestAx3(aP2, aDestVec1, aDestVec2); + aCurTrsf.SetDisplacement(aStartAx3, aDestAx3); + } + + aTrsf.PreMultiply(aCurTrsf); + + // Perform transformation + BRepBuilderAPI_Transform aBRepTrsf (aShapeBase, aTrsf, Standard_False); + aShape = aBRepTrsf.Shape(); + } else return 0; diff --git a/src/GEOMImpl/GEOMImpl_Types.hxx b/src/GEOMImpl/GEOMImpl_Types.hxx index d0cc19686..7b70e9b8b 100755 --- a/src/GEOMImpl/GEOMImpl_Types.hxx +++ b/src/GEOMImpl/GEOMImpl_Types.hxx @@ -153,6 +153,7 @@ #define POSITION_SHAPE_COPY 2 #define POSITION_SHAPE_FROM_GLOBAL 3 #define POSITION_SHAPE_FROM_GLOBAL_COPY 4 +#define POSITION_ALONG_PATH 5 #define TORUS_RR 1 #define TORUS_PNT_VEC_RR 2 diff --git a/src/GEOM_I/GEOM_ITransformOperations_i.cc b/src/GEOM_I/GEOM_ITransformOperations_i.cc index 338e901eb..9715c0c4d 100644 --- a/src/GEOM_I/GEOM_ITransformOperations_i.cc +++ b/src/GEOM_I/GEOM_ITransformOperations_i.cc @@ -988,6 +988,46 @@ GEOM::GEOM_Object_ptr GEOM_ITransformOperations_i::PositionShapeCopy return GetObject(anObject); } +//============================================================================= +/*! + * PositionAlongPath + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_ITransformOperations_i::PositionAlongPath + (GEOM::GEOM_Object_ptr theObject, + GEOM::GEOM_Object_ptr thePath, + CORBA::Double theDistance, + CORBA::Boolean theCopy) +{ + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + + if (theObject == NULL || thePath == NULL) + return aGEOMObject._retn(); + + //Get the basic object + CORBA::String_var anEntry = theObject->GetEntry(); + Handle(GEOM_Object) aBasicObject = + GetOperations()->GetEngine()->GetObject(theObject->GetStudyID(), anEntry); + if (aBasicObject.IsNull()) return aGEOMObject._retn(); + + //Get the path object + CORBA::String_var aPathEntry = thePath->GetEntry(); + Handle(GEOM_Object) aPathObject = + GetOperations()->GetEngine()->GetObject(theObject->GetStudyID(), aPathEntry); + if (aPathObject.IsNull()) return aGEOMObject._retn(); + + //Perform the position + Handle(GEOM_Object) anObject = + GetOperations()->PositionAlongPath(aBasicObject, aPathObject, theDistance, theCopy); + if (!GetOperations()->IsDone() || anObject.IsNull()) + return aGEOMObject._retn(); + + return GetObject(anObject); +} + //============================================================================= /*! * MultiTranslate1D diff --git a/src/GEOM_I/GEOM_ITransformOperations_i.hh b/src/GEOM_I/GEOM_ITransformOperations_i.hh index aed462a00..62dc08c9a 100644 --- a/src/GEOM_I/GEOM_ITransformOperations_i.hh +++ b/src/GEOM_I/GEOM_ITransformOperations_i.hh @@ -141,6 +141,11 @@ class GEOM_I_EXPORT GEOM_ITransformOperations_i : GEOM::GEOM_Object_ptr theStartLCS, GEOM::GEOM_Object_ptr theEndLCS); + GEOM::GEOM_Object_ptr PositionAlongPath (GEOM::GEOM_Object_ptr theObject, + GEOM::GEOM_Object_ptr thePath, + CORBA::Double theDistance, + CORBA::Boolean theCopy); + GEOM::GEOM_Object_ptr RotateThreePoints (GEOM::GEOM_Object_ptr theObject, GEOM::GEOM_Object_ptr theCentPoint, GEOM::GEOM_Object_ptr thePoint1, diff --git a/src/GEOM_I_Superv/GEOM_Superv_i.cc b/src/GEOM_I_Superv/GEOM_Superv_i.cc index 7f4641c65..90ee3a838 100644 --- a/src/GEOM_I_Superv/GEOM_Superv_i.cc +++ b/src/GEOM_I_Superv/GEOM_Superv_i.cc @@ -1820,6 +1820,22 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::PositionShapeCopy (GEOM::GEOM_Object_ptr th return anObj; } +//============================================================================= +// PositionAlongPath: +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_Superv_i::PositionAlongPath (GEOM::GEOM_Object_ptr theObject, + GEOM::GEOM_Object_ptr thePath, + CORBA::Double theDistance, + CORBA::Boolean theCopy) +{ + beginService( " GEOM_Superv_i::PositionAlongPath" ); + MESSAGE("GEOM_Superv_i::PositionAlongPath"); + getTransfOp(); + GEOM::GEOM_Object_ptr anObj = myTransfOp->PositionAlongPath(theObject, thePath, theDistance, theCopy); + endService( " GEOM_Superv_i::PositionAlongPath" ); + return anObj; +} + //=============================== ShapesOperations ============================ //============================================================================= // Make: diff --git a/src/GEOM_I_Superv/GEOM_Superv_i.hh b/src/GEOM_I_Superv/GEOM_Superv_i.hh index b081ff798..3d8425253 100644 --- a/src/GEOM_I_Superv/GEOM_Superv_i.hh +++ b/src/GEOM_I_Superv/GEOM_Superv_i.hh @@ -419,6 +419,10 @@ public: GEOM::GEOM_Object_ptr PositionShapeCopy (GEOM::GEOM_Object_ptr theObject, GEOM::GEOM_Object_ptr theStartLCS, GEOM::GEOM_Object_ptr theEndLCS); + GEOM::GEOM_Object_ptr PositionAlongPath (GEOM::GEOM_Object_ptr theObject, + GEOM::GEOM_Object_ptr thePath, + CORBA::Double theDistance, + CORBA::Boolean theCopy); //-----------------------------------------------------------// // ShapesOperations // diff --git a/src/GEOM_SWIG/GEOM_TestAll.py b/src/GEOM_SWIG/GEOM_TestAll.py index d9a607048..a44d8bcfb 100644 --- a/src/GEOM_SWIG/GEOM_TestAll.py +++ b/src/GEOM_SWIG/GEOM_TestAll.py @@ -206,6 +206,7 @@ def TestAll (geompy, math): MirrorAxis = geompy.MakeMirrorByAxis(Box, Line1) # MirrorPnt = geompy.MakeMirrorByPoint(Box, p200) # Position = geompy.MakePosition(Box, cs1, cs2) #(3 GEOM_Object_ptr)->GEOM_Object_ptr + Position2 = geompy.PositionAlongPath(Box, Arc, 0.5, 1) #(2 GEOM_Object_ptr, 1 Double, 1 Bool)->GEOM_Object_ptr Offset = geompy.MakeOffset(Box, 10.) #(GEOM_Object_ptr, Double)->GEOM_Object_ptr Orientation = geompy.ChangeOrientation(Box) @@ -372,6 +373,7 @@ def TestAll (geompy, math): id_MirrorAxis = geompy.addToStudy(MirrorAxis, "Mirror by Axis") id_MirrorPnt = geompy.addToStudy(MirrorPnt, "Mirror by Point") id_Position = geompy.addToStudy(Position, "Positioned box") + id_Position2 = geompy.addToStudy(Position2, "Positioned box along path") id_Offset = geompy.addToStudy(Offset, "Offset") id_Orientation = geompy.addToStudy(Orientation, "Orientation") diff --git a/src/GEOM_SWIG/geompyDC.py b/src/GEOM_SWIG/geompyDC.py index 17baee494..18b06e9e1 100644 --- a/src/GEOM_SWIG/geompyDC.py +++ b/src/GEOM_SWIG/geompyDC.py @@ -2231,6 +2231,19 @@ class geompyDC(GEOM._objref_GEOM_Gen): RaiseIfFailed("PositionShapeCopy", self.TrsfOp) return anObj + ## Modify the Location of the given object by Path, + # @param theObject The object to be displaced. + # @param thePath Wire or Edge along that the object will be translated. + # @param theDistance progress of Path (0 = start location, 1 = end of path location). + # @return New GEOM_Object, containing the displaced shape. + # + # @ref tui_modify_location "Example" + def PositionAlongPath(self,theObject, thePath, theDistance, theCopy): + # Example: see GEOM_TestAll.py + anObj = self.TrsfOp.PositionAlongPath(theObject, thePath, theDistance, theCopy) + RaiseIfFailed("PositionAlongPath", self.TrsfOp) + return anObj + ## Create new object as offset of the given one. # @param theObject The base object for the offset. # @param theOffset Offset value. diff --git a/src/TransformationGUI/TransformationGUI_PositionDlg.cxx b/src/TransformationGUI/TransformationGUI_PositionDlg.cxx index 7fcac82a4..5fb7891af 100644 --- a/src/TransformationGUI/TransformationGUI_PositionDlg.cxx +++ b/src/TransformationGUI/TransformationGUI_PositionDlg.cxx @@ -33,6 +33,7 @@ #include #include #include +#include // OCCT Includes #include @@ -54,6 +55,7 @@ TransformationGUI_PositionDlg::TransformationGUI_PositionDlg SUIT_ResourceMgr* aResMgr = myGeomGUI->getApp()->resourceMgr(); QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_POSITION"))); QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_POSITION2"))); + QPixmap image2 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_POSITION3"))); QPixmap imageselect (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT"))); setWindowTitle(tr("GEOM_POSITION_TITLE")); @@ -62,24 +64,21 @@ TransformationGUI_PositionDlg::TransformationGUI_PositionDlg mainFrame()->GroupConstructors->setTitle(tr("GEOM_POSITION")); mainFrame()->RadioButton1->setIcon(image0); mainFrame()->RadioButton2->setIcon(image1); - mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose); - mainFrame()->RadioButton3->close(); + mainFrame()->RadioButton3->setIcon(image2); - Group1 = new DlgRef_3Sel3Spin1Check(centralWidget()); - Group1->SpinBox1->hide(); - Group1->SpinBox2->hide(); - Group1->SpinBox3->hide(); - Group1->TextLabel4->hide(); - Group1->TextLabel5->hide(); - Group1->TextLabel6->hide(); + Group1 = new DlgRef_4Sel1Spin2Check(centralWidget()); Group1->GroupBox1->setTitle(tr("GEOM_ARGUMENTS")); Group1->TextLabel1->setText(tr("GEOM_OBJECTS")); Group1->TextLabel2->setText(tr("GEOM_START_LCS")); - Group1->TextLabel3->setText(tr("GEOM_END_LCS")); + Group1->TextLabel3->setText(tr("GEOM_DISTANCE")); + Group1->TextLabel4->setText(tr("GEOM_END_LCS")); + Group1->TextLabel5->setText(tr("GEOM_PATH_OBJECT")); Group1->PushButton1->setIcon(imageselect); Group1->PushButton2->setIcon(imageselect); - Group1->PushButton3->setIcon(imageselect); - Group1->CheckBox1->setText(tr("GEOM_CREATE_COPY")); + Group1->PushButton4->setIcon(imageselect); + Group1->PushButton5->setIcon(imageselect); + Group1->CheckButton1->setText(tr("GEOM_CREATE_COPY")); + Group1->CheckButton2->setText(tr("SELECT_UNPUBLISHED_EDGES")); QVBoxLayout* layout = new QVBoxLayout(centralWidget()); layout->setMargin(0); layout->setSpacing(6); @@ -89,7 +88,8 @@ TransformationGUI_PositionDlg::TransformationGUI_PositionDlg setHelpFileName("modify_location_operation_page.html"); // Activate Create a Copy mode - Group1->CheckBox1->setChecked(true); + Group1->CheckButton1->setChecked(true); + Group1->CheckButton1->setChecked(false); CreateCopyModeChanged(true); Init(); @@ -113,11 +113,18 @@ void TransformationGUI_PositionDlg::Init() // init variables Group1->LineEdit1->setReadOnly(true); Group1->LineEdit2->setReadOnly(true); - Group1->LineEdit3->setReadOnly(true); + Group1->LineEdit4->setReadOnly(true); + Group1->LineEdit5->setReadOnly(true); Group1->LineEdit1->setText(""); Group1->LineEdit2->setText(""); - Group1->LineEdit3->setText(""); + Group1->LineEdit4->setText(""); + Group1->LineEdit5->setText(""); + + initSpinBox(Group1->SpinBox_DX, 0, 1, 0.05, 6); // VSR:TODO : DBL_DIGITS_DISPLAY + Group1->SpinBox_DX->setValue(1); + + Group1->CheckButton2->setEnabled(false); myStartLCS = myEndLCS = GEOM::GEOM_Object::_nil(); @@ -131,13 +138,18 @@ void TransformationGUI_PositionDlg::Init() connect(Group1->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); connect(Group1->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); - connect(Group1->PushButton3, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); + connect(Group1->PushButton4, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); + connect(Group1->PushButton5, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); connect(Group1->LineEdit1, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed())); connect(Group1->LineEdit2, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed())); - connect(Group1->LineEdit3, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed())); + connect(Group1->LineEdit4, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed())); + connect(Group1->LineEdit5, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed())); - connect(Group1->CheckBox1, SIGNAL(toggled(bool)), this, SLOT(CreateCopyModeChanged(bool))); + connect(Group1->CheckButton1, SIGNAL(toggled(bool)), this, SLOT(CreateCopyModeChanged(bool))); + connect(Group1->SpinBox_DX, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox())); + + connect(Group1->CheckButton2, SIGNAL(toggled(bool)), this, SLOT(SelectionTypeButtonClicked())); initName(tr("GEOM_POSITION")); @@ -153,9 +165,11 @@ void TransformationGUI_PositionDlg::ConstructorsClicked (int constructorId) disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0); Group1->LineEdit2->clear(); - Group1->LineEdit3->clear(); + Group1->LineEdit4->clear(); + Group1->LineEdit5->clear(); myStartLCS = GEOM::GEOM_Object::_nil(); myEndLCS = GEOM::GEOM_Object::_nil(); + myPath = GEOM::GEOM_Object::_nil(); switch (constructorId) { case 0: @@ -164,7 +178,20 @@ void TransformationGUI_PositionDlg::ConstructorsClicked (int constructorId) Group1->TextLabel2->hide(); Group1->PushButton2->hide(); + Group1->LineEdit5->hide(); + Group1->TextLabel5->hide(); + Group1->PushButton5->hide(); + + Group1->SpinBox_DX->hide(); + Group1->TextLabel3->hide(); + + Group1->LineEdit4->show(); + Group1->TextLabel4->show(); + Group1->PushButton4->show(); + Group1->PushButton1->click(); + + Group1->CheckButton2->hide(); } break; case 1: @@ -173,7 +200,38 @@ void TransformationGUI_PositionDlg::ConstructorsClicked (int constructorId) Group1->TextLabel2->show(); Group1->PushButton2->show(); + Group1->LineEdit5->hide(); + Group1->TextLabel5->hide(); + Group1->PushButton5->hide(); + + Group1->SpinBox_DX->hide(); + Group1->TextLabel3->hide(); + Group1->PushButton1->click(); + + Group1->CheckButton2->hide(); + } + break; + case 2: + { + Group1->LineEdit4->hide(); + Group1->TextLabel4->hide(); + Group1->PushButton4->hide(); + + Group1->LineEdit2->hide(); + Group1->TextLabel2->hide(); + Group1->PushButton2->hide(); + + Group1->LineEdit5->show(); + Group1->TextLabel5->show(); + Group1->PushButton5->show(); + + Group1->SpinBox_DX->show(); + Group1->TextLabel3->show(); + + Group1->PushButton1->click(); + + Group1->CheckButton2->show(); } break; } @@ -191,6 +249,31 @@ void TransformationGUI_PositionDlg::ConstructorsClicked (int constructorId) } } +//================================================================================= +// function : SelectionBittonClicked() +// purpose : Selection type Radio button management +//================================================================================= +void TransformationGUI_PositionDlg::SelectionTypeButtonClicked() +{ + if ( Group1->CheckButton2->isChecked() ) { + localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE ); + } else { + TColStd_MapOfInteger aMap; + aMap.Add(GEOM_WIRE); + aMap.Add(GEOM_LINE); + globalSelection(aMap); + } +} + +//================================================================================= +// function : ValueChangedInSpinBox() +// purpose : +//================================================================================= +void TransformationGUI_PositionDlg::ValueChangedInSpinBox() +{ + displayPreview(); +} + //================================================================================= // function : ClickOnOk() // purpose : @@ -207,7 +290,7 @@ void TransformationGUI_PositionDlg::ClickOnOk() //================================================================================= bool TransformationGUI_PositionDlg::ClickOnApply() { - if (!onAccept(Group1->CheckBox1->isChecked())) + if (!onAccept(Group1->CheckButton1->isChecked())) return false; initName(); @@ -229,8 +312,10 @@ void TransformationGUI_PositionDlg::SelectionIntoArgument() myObjects.length(0); else if (myEditCurrentArgument == Group1->LineEdit2) myStartLCS = GEOM::GEOM_Object::_nil(); - else if (myEditCurrentArgument == Group1->LineEdit3) + else if (myEditCurrentArgument == Group1->LineEdit4) myEndLCS = GEOM::GEOM_Object::_nil(); + else if (myEditCurrentArgument == Group1->LineEdit5) + myPath = GEOM::GEOM_Object::_nil(); LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr(); SALOME_ListIO aSelList; @@ -263,9 +348,9 @@ void TransformationGUI_PositionDlg::SelectionIntoArgument() myEditCurrentArgument->setText(aName); if (!myStartLCS->_is_nil() && myEndLCS->_is_nil()) - Group1->PushButton3->click(); + Group1->PushButton4->click(); } - else if (myEditCurrentArgument == Group1->LineEdit3) { + else if (myEditCurrentArgument == Group1->LineEdit4) { myEndLCS = GEOM::GEOM_Object::_nil(); if (aSelList.Extent() != 1) return; @@ -278,8 +363,56 @@ void TransformationGUI_PositionDlg::SelectionIntoArgument() aName = GEOMBase::GetName(myEndLCS); myEditCurrentArgument->setText(aName); - if (!myEndLCS->_is_nil() && !myObjects.length()) + if (!myEndLCS->_is_nil() && !myObjects.length() && getConstructorId() != 2) Group1->PushButton1->click(); + else if (getConstructorId() == 2 && !myObjects.length()) + Group1->PushButton5->click(); + } + else if (myEditCurrentArgument == Group1->LineEdit5) { + myPath = GEOM::GEOM_Object::_nil(); + if (aSelList.Extent() != 1) + return; + + Standard_Boolean testResult = Standard_False; + GEOM::GEOM_Object_ptr aSelectedObject = GEOMBase::ConvertIOinGEOMObject(aSelList.First(), testResult); + if (!testResult || aSelectedObject->_is_nil()) + return; + + aName = GEOMBase::GetName(myPath); + // Local Selection + TopoDS_Shape S; + if (!GEOMBase::GetShape(aSelectedObject, S)) + return; + + TColStd_IndexedMapOfInteger aMap; + aSelMgr->GetIndexes(aSelList.First(), aMap); + aName = GEOMBase::GetName(aSelectedObject); + if (aMap.Extent() == 1) { + int anIndex = aMap(1); + aName.append(":edge_" + QString::number(anIndex)); + + //Find SubShape Object in Father + GEOM::GEOM_Object_var aFindedObject = GEOMBase_Helper::findObjectInFather(aSelectedObject, aName); + + if (aFindedObject == GEOM::GEOM_Object::_nil()) { // Object not found in study + GEOM::GEOM_IShapesOperations_var aShapesOp = + getGeomEngine()->GetIShapesOperations(getStudyId()); + aSelectedObject = aShapesOp->GetSubShape(aSelectedObject, anIndex); + } + else { // get Object from study + aSelectedObject = aFindedObject; + } + } + else { + if (S.ShapeType() != TopAbs_EDGE) { + aSelectedObject = GEOM::GEOM_Object::_nil(); + aName = ""; + return; + } + } + + myEditCurrentArgument->setText(aName); + myPath = aSelectedObject; } // clear selection @@ -306,9 +439,13 @@ void TransformationGUI_PositionDlg::SetEditCurrentArgument() globalSelection(); Group1->PushButton2->setDown(false); - Group1->PushButton3->setDown(false); + Group1->PushButton4->setDown(false); + Group1->PushButton5->setDown(false); Group1->LineEdit2->setEnabled(false); - Group1->LineEdit3->setEnabled(false); + Group1->LineEdit4->setEnabled(false); + Group1->LineEdit5->setEnabled(false); + + Group1->CheckButton2->setEnabled(false); } else if (send == Group1->PushButton2) { myEditCurrentArgument = Group1->LineEdit2; @@ -319,12 +456,16 @@ void TransformationGUI_PositionDlg::SetEditCurrentArgument() globalSelection(aMap); Group1->PushButton1->setDown(false); - Group1->PushButton3->setDown(false); + Group1->PushButton4->setDown(false); + Group1->PushButton5->setDown(false); Group1->LineEdit1->setEnabled(false); - Group1->LineEdit3->setEnabled(false); + Group1->LineEdit4->setEnabled(false); + Group1->LineEdit5->setEnabled(false); + + Group1->CheckButton2->setEnabled(false); } - else if (send == Group1->PushButton3) { - myEditCurrentArgument = Group1->LineEdit3; + else if (send == Group1->PushButton4) { + myEditCurrentArgument = Group1->LineEdit4; TColStd_MapOfInteger aMap; aMap.Add(GEOM_PLANE); @@ -333,8 +474,33 @@ void TransformationGUI_PositionDlg::SetEditCurrentArgument() Group1->PushButton1->setDown(false); Group1->PushButton2->setDown(false); + Group1->PushButton5->setDown(false); Group1->LineEdit1->setEnabled(false); Group1->LineEdit2->setEnabled(false); + Group1->LineEdit5->setEnabled(false); + + Group1->CheckButton2->setEnabled(false); + } + else if (send == Group1->PushButton5) { + myEditCurrentArgument = Group1->LineEdit5; + + Group1->CheckButton2->setEnabled(true); + + if ( Group1->CheckButton2->isChecked() ) { + localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE ); + } else { + TColStd_MapOfInteger aMap; + aMap.Add(GEOM_WIRE); + aMap.Add(GEOM_LINE); + globalSelection(aMap); + } + + Group1->PushButton1->setDown(false); + Group1->PushButton2->setDown(false); + Group1->PushButton4->setDown(false); + Group1->LineEdit1->setEnabled(false); + Group1->LineEdit2->setEnabled(false); + Group1->LineEdit4->setEnabled(false); } connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); @@ -358,10 +524,16 @@ void TransformationGUI_PositionDlg::LineEditReturnPressed() QLineEdit* send = (QLineEdit*)sender(); if (send == Group1->LineEdit1 || send == Group1->LineEdit2 || - send == Group1->LineEdit3) { + send == Group1->LineEdit4 || + send == Group1->LineEdit5 ) { myEditCurrentArgument = send; GEOMBase_Skeleton::LineEditReturnPressed(); } + + if (send == Group1->LineEdit5) + Group1->CheckButton2->setEnabled(true); + else + Group1->CheckButton2->setEnabled(false); } //================================================================================= @@ -372,8 +544,10 @@ void TransformationGUI_PositionDlg::ActivateThisDialog() { GEOMBase_Skeleton::ActivateThisDialog(); - // reinit, because some selected objects could be removed - Init(); + connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ), + this, SLOT( SelectionIntoArgument() ) ); + + ConstructorsClicked( getConstructorId() ); } //================================================================================= @@ -404,8 +578,10 @@ bool TransformationGUI_PositionDlg::isValid (QString& /*msg*/) bool res; if (getConstructorId() == 0) res = !(myObjects.length() == 0 || myEndLCS->_is_nil()); - else + else if ( getConstructorId() == 1 ) res = !(myObjects.length() == 0 || myStartLCS->_is_nil() || myEndLCS->_is_nil()); + else if ( getConstructorId() == 2 ) + res = !(myObjects.length() == 0 || myPath->_is_nil()); return res; } @@ -417,7 +593,7 @@ bool TransformationGUI_PositionDlg::isValid (QString& /*msg*/) bool TransformationGUI_PositionDlg::execute (ObjectList& objects) { bool res = false; - bool toCreateCopy = IsPreview() || Group1->CheckBox1->isChecked(); + bool toCreateCopy = IsPreview() || Group1->CheckButton1->isChecked(); GEOM::GEOM_Object_var anObj; switch (getConstructorId()) { @@ -452,6 +628,18 @@ bool TransformationGUI_PositionDlg::execute (ObjectList& objects) res = true; break; } + case 2: + { + double aDistance = Group1->SpinBox_DX->value(); + for (int i = 0; i < myObjects.length(); i++) { + anObj = GEOM::GEOM_ITransformOperations::_narrow(getOperation())-> + PositionAlongPath(myObjects[i], myPath, aDistance, toCreateCopy); + if (!anObj->_is_nil()) + objects.push_back(anObj._retn()); + } + res = true; + break; + } } return res; @@ -480,3 +668,16 @@ void TransformationGUI_PositionDlg::CreateCopyModeChanged (bool isCreateCopy) { mainFrame()->GroupBoxName->setEnabled(isCreateCopy); } + +//================================================================================= +// function : addSubshapeToStudy +// purpose : virtual method to add new SubObjects if local selection +//================================================================================= +void TransformationGUI_PositionDlg::addSubshapesToStudy() +{ + QMap objMap; + + objMap[Group1->LineEdit5->text()] = myPath; + + addSubshapesToFather(objMap); +} diff --git a/src/TransformationGUI/TransformationGUI_PositionDlg.h b/src/TransformationGUI/TransformationGUI_PositionDlg.h index 5da9dea72..9a18399d8 100644 --- a/src/TransformationGUI/TransformationGUI_PositionDlg.h +++ b/src/TransformationGUI/TransformationGUI_PositionDlg.h @@ -28,7 +28,7 @@ #include -class DlgRef_3Sel3Spin1Check; +class DlgRef_4Sel1Spin2Check; //================================================================================= // class : TransformationGUI_PositionDlg @@ -49,6 +49,7 @@ protected: virtual bool isValid( QString& ); virtual bool execute( ObjectList& ); virtual void restoreSubShapes( SALOMEDS::Study_ptr, SALOMEDS::SObject_ptr ); + virtual void addSubshapesToStudy(); private: void Init(); @@ -58,11 +59,12 @@ private: GEOM::GEOM_Object_var myStartLCS; GEOM::GEOM_Object_var myEndLCS; GEOM::ListOfGO myObjects; + GEOM::GEOM_Object_var myPath; // to initialize the first selection field with a selected object on the dialog creation bool myInitial; - - DlgRef_3Sel3Spin1Check* Group1; + + DlgRef_4Sel1Spin2Check* Group1; private slots: void ClickOnOk(); @@ -73,6 +75,8 @@ private slots: void SetEditCurrentArgument(); void ConstructorsClicked( int ); void CreateCopyModeChanged( bool ); + void ValueChangedInSpinBox(); + void SelectionTypeButtonClicked(); }; #endif // TRANSFORMATIONGUI_POSITIONDLG_H