From 0081236a16be70760a62e78efe7fce7f04106220 Mon Sep 17 00:00:00 2001 From: skv Date: Thu, 12 Feb 2015 16:59:30 +0300 Subject: [PATCH] 0022776: [CEA 1269] Project a wire or a face on a cylinder --- .../gui/GEOM/images/proj_on_cyl_dlg.png | Bin 0 -> 25396 bytes .../gui/GEOM/images/proj_on_cyl_preview.png | Bin 0 -> 3218 bytes .../projection_on_cylinder_operation.doc | 41 ++ .../GEOM/input/transformation_operations.doc | 1 + idl/GEOM_Gen.idl | 25 ++ resources/CMakeLists.txt | 1 + resources/proj_on_cyl.png | Bin 0 -> 792 bytes src/GEOMGUI/GEOM_images.ts | 8 + src/GEOMGUI/GEOM_msg_en.ts | 31 ++ src/GEOMGUI/GeometryGUI.cxx | 4 + src/GEOMGUI/GeometryGUI_Operations.h | 1 + src/GEOMImpl/CMakeLists.txt | 1 + src/GEOMImpl/GEOMImpl_IProjOnCyl.hxx | 61 +++ .../GEOMImpl_ITransformOperations.cxx | 76 ++++ .../GEOMImpl_ITransformOperations.hxx | 6 + src/GEOMImpl/GEOMImpl_ProjectionDriver.cxx | 303 +++++++++++++- src/GEOMImpl/GEOMImpl_ProjectionDriver.hxx | 10 + src/GEOMImpl/GEOMImpl_Types.hxx | 5 +- src/GEOMUtils/CMakeLists.txt | 6 + src/GEOMUtils/GEOMUtils_HTrsfCurve2d.cxx | 51 +++ src/GEOMUtils/GEOMUtils_HTrsfCurve2d.hxx | 84 ++++ src/GEOMUtils/GEOMUtils_Trsf2d.cxx | 110 +++++ src/GEOMUtils/GEOMUtils_Trsf2d.hxx | 134 ++++++ src/GEOMUtils/GEOMUtils_TrsfCurve2d.cxx | 382 ++++++++++++++++++ src/GEOMUtils/GEOMUtils_TrsfCurve2d.hxx | 242 +++++++++++ src/GEOM_I/GEOM_ITransformOperations_i.cc | 34 ++ src/GEOM_I/GEOM_ITransformOperations_i.hh | 5 + src/GEOM_SWIG/geomBuilder.py | 65 +++ src/TransformationGUI/CMakeLists.txt | 3 + src/TransformationGUI/TransformationGUI.cxx | 4 + .../TransformationGUI_ProjectionOnCylDlg.cxx | 360 +++++++++++++++++ .../TransformationGUI_ProjectionOnCylDlg.h | 78 ++++ 32 files changed, 2129 insertions(+), 3 deletions(-) create mode 100644 doc/salome/gui/GEOM/images/proj_on_cyl_dlg.png create mode 100644 doc/salome/gui/GEOM/images/proj_on_cyl_preview.png create mode 100644 doc/salome/gui/GEOM/input/projection_on_cylinder_operation.doc create mode 100644 resources/proj_on_cyl.png create mode 100644 src/GEOMImpl/GEOMImpl_IProjOnCyl.hxx create mode 100644 src/GEOMUtils/GEOMUtils_HTrsfCurve2d.cxx create mode 100644 src/GEOMUtils/GEOMUtils_HTrsfCurve2d.hxx create mode 100644 src/GEOMUtils/GEOMUtils_Trsf2d.cxx create mode 100644 src/GEOMUtils/GEOMUtils_Trsf2d.hxx create mode 100644 src/GEOMUtils/GEOMUtils_TrsfCurve2d.cxx create mode 100644 src/GEOMUtils/GEOMUtils_TrsfCurve2d.hxx mode change 100755 => 100644 src/GEOM_SWIG/geomBuilder.py create mode 100644 src/TransformationGUI/TransformationGUI_ProjectionOnCylDlg.cxx create mode 100644 src/TransformationGUI/TransformationGUI_ProjectionOnCylDlg.h diff --git a/doc/salome/gui/GEOM/images/proj_on_cyl_dlg.png b/doc/salome/gui/GEOM/images/proj_on_cyl_dlg.png new file mode 100644 index 0000000000000000000000000000000000000000..4bb2b8ac3f0fd1b42fbb92bb3279b42713fd4b6f GIT binary patch literal 25396 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 literal 0 HcmV?d00001 diff --git a/doc/salome/gui/GEOM/images/proj_on_cyl_preview.png b/doc/salome/gui/GEOM/images/proj_on_cyl_preview.png new file mode 100644 index 0000000000000000000000000000000000000000..85d767eaba8e5ba4ef1c8c788ad248a24f84e696 GIT binary patch literal 3218 zcmb_fc{J2(AD?brLoyX*%XYIwB~)XNB4jsZxRGUusmV5WhCxKO$QlYmGW}#{h%DK& zO_u306Otsu*vHt0cW(E*@4ffD_ubBU|9H-M&a<5JJm2TDJ<(<+dRzwu4}w4-F8ym) zuY*AQ^jOW5{Rh?v%s&eT0v)=kfAxyF|5Mr+(QSw<7`ZH`_wa;%J3l(2PA^5DXl!m& z8~O}^;h>dm|L`PtybUpUJ`aF6#0{Q63|{b1C~;IH%!SMa=j0HoVA7xbi%<2SxslZx zO@}~QyHExjh@T(6AB7h*(1quDB%tIrbfAMFSRfNFg6{+@6SX$b9W< zJ`VF~Tht47*3J9CmmX*T7(?o1;~Hf@pD8c_Wb6yPqvmJ@CALLOyHX(KQ`KfqJ1Kg* zw<(F1Bu3$hq;1F#J-19!TksRj>R)6iz}?eNDaaNDvO-QM6va+l%APsuoH`9(e3%?pB54HfYK zWO_7k>bgqdjl<0|xYM%cmkR4Z5mE~ZN0lvnM`R??x0|1G}$4fOsmQ@Vl+*x)A^o}?>(2mNywqN103%g+Bugugz` zX({P4v)xO9-yS%$m&rLJAaBIzD`Tg=ZO-hd3TlqaFt{#Z^>IQ z$vid6uV9;s-#WS~u2W?b4P@}V%cpVA0U2P!4|Li@0HtQ4@d4vWriC#PFe!1bL1q=X zPqg?42^TFaqjiktGjfKye{m&-5$btkXxFy8UhdQhG!F4*X zul-%57Kz_-`k+yB{$PkL&FkX>XANQry@>6j8T3F#2!;1IQOmchCaQ2>Tvc%g?4X~1 z)jVFf*AX|ox8TQ_B{d@e(z5QH>b+qu96{@roh<`Y*(nK#!AT3BBZT;Qhy17zCX^A` z+q`_iI$$I+;j`3=WS|-&t+%C|`l)WIj(@1ESXG;1aJo|g6Fm26$MZ#eW|R+!#adxU zOD$5u9W@=-jvkNKFQ}(tT)_cy$M+A%0cTPgx743p>Uob*{+M$~widP|k|W~2r_j0J<)@! zVWl|mcf(KyyCE=E%-buUwDx2LBJt#F;~q9&-ZvkujU96u^}_iobD5BQD;|(9+~qNM z#d*&g50byrPS=2wesQLkMVuhUTaL`{dc~f#x zYd2i#{W;S@fdNrTIUZyWh~?#SE2aQTh%SA9B!0B=4g_FZ`|k9UEnk+@@Pb?fWEO4I zd7=0+@=eX5>WWlZPBl8bABlqi9k%TRapoIgGpN-&M-%ic!3r<#Q0-e+9s%(`1M_2Ty4S465V#R4B_ z;DLW|gTi#VNRsT-vvm)x(wg`ffYMzkDCr09ebt8l1}2*n;gjwHJhcCc3l#}+3*R=;5>c@a>TRIY`2soNGqUE*0UMO zaIH7I@w}@DmE?Ovz!&ZG!5ZHRppw>y%N&Z%{c;YTTva(%W?0zW_OrS1;2rEE*$xIB zh2Qet31oC6*kO&DB)xDb3Fp0}ZKgAWz+%eOcHhA4z}BpqsRS`?mX&81DN@SaW15+r z(d(3k&F#oTL0Tp&&7$;K`R6Di=*WWN+BsJA zsXzZ_As)sW!@h#N@v?&OC$sgV5F~^sfrIkAbzL|=V1%$=F77e3ST(McGe10m~Av$VhX!c!_2|7VCtU6G>Js_jI zdzBudwD=kCJ>?%Y@p3+GxZJ`Nx6&$6Nt~U}x;NgSvbDwhI+ZSZvse2W)Ap;4;uTV5 zM({Xa5ti{4Khb05lYMASEbl$^(ev{Mx6z6wD7a0T7{1?_$Sbq(WzK+S&5-t1te*@-DWZM7$ literal 0 HcmV?d00001 diff --git a/doc/salome/gui/GEOM/input/projection_on_cylinder_operation.doc b/doc/salome/gui/GEOM/input/projection_on_cylinder_operation.doc new file mode 100644 index 000000000..10dc98eb1 --- /dev/null +++ b/doc/salome/gui/GEOM/input/projection_on_cylinder_operation.doc @@ -0,0 +1,41 @@ +/*! + +\page projection_on_cylinder_operation_page Projection on Cylinder + +\n To produce a Projection on Cylinder in the Main Menu select +Operations - > Transformation - > Projection on Cylinder + +\n This operation makes a projection of a Source planar wire or face on +a cylinder defined by its radius. The cylinder's coordinate system is +the same as the global coordinate system. The result represents a wire or +a face or a compound of faces that represents a projection of the source +shape onto a cylinder. + +To make a projection it is necessary to define: +- \b Object to be rotated. It can be either a planar wire or a face; +- \b Radius of the cylinder; +- Starting angle from the cylinder's X axis around Z axis. This is +the angle of the projection starting. +- Length angle in which to project the total length of +the wire. If it is unchecked the projection is not scaled and natural +wire length is kept for the projection. + +\ref restore_presentation_parameters_page "Advanced options". + +\image html proj_on_cyl_dlg.png + +\n Example: + +\image html proj_on_cyl_preview.png "The curve (in red) and its projection on the cylinder" + +\n TUI Command: geompy.MakeProjectionOnCylinder(theObject, theRadius, +theStartAngle=0.0, theAngleLength=-1.0), +where \em theObject is a shape which has to be projected, \em theRadius +is a cylinder radius, \em theStartAngle the starting angle of projection in +radians, \em theAngleLength the projection length angle in radians. +The \em Result will be a \em GEOM_Object. + +Our TUI Scripts provide you with useful examples of the use of +\ref tui_projection "Transformation Operations". + +*/ diff --git a/doc/salome/gui/GEOM/input/transformation_operations.doc b/doc/salome/gui/GEOM/input/transformation_operations.doc index ac745b669..6ce6395ce 100644 --- a/doc/salome/gui/GEOM/input/transformation_operations.doc +++ b/doc/salome/gui/GEOM/input/transformation_operations.doc @@ -17,6 +17,7 @@ which allow to:
  • 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 \subpage projection_on_cylinder_operation_page "Projection on cylinder".
  • 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/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 7eb91e9eb..7b4f6ab7f 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -1420,6 +1420,31 @@ module GEOM * \return theObject. */ GEOM_Object RecomputeObject (in GEOM_Object theObject); + + /*! + * \brief Compute the projection of a wire or a face on a cylinder. + * + * This method computes a wire or a face or a compound of faces + * that represents a projection of the source shape onto cylinder. + * The cylinder's coordinate system is the same as the global coordinate + * system. + * + * \param theObject The object to be projected. It can be either + * a planar wire or a face. + * \param theRadius The radius of the cylinder. + * \param theStartAngle The starting angle from the cylinder's X axis + * around Z axis. The angle from which the projection is started. + * \param theAngleLength The projection length angle. The angle in which + * to project the total length of the wire. If it is negative the + * projection is not scaled and natural wire length is kept for + * the projection. + * \return A wire or a face or a compound of faces that represents a + * projection of the source shape onto a cylinder. + */ + GEOM_Object MakeProjectionOnCylinder (in GEOM_Object theObject, + in double theRadius, + in double theStartAngle, + in double theAngleLength); }; /*! diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index 87d7e929a..7c21fc3da 100755 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -134,6 +134,7 @@ SET( _res_files projection.png projection_on_edge.png projection_on_wire.png + proj_on_cyl.png origin_and_vectors.png partition.png partitionkeep.png diff --git a/resources/proj_on_cyl.png b/resources/proj_on_cyl.png new file mode 100644 index 0000000000000000000000000000000000000000..6b22c1dc773ccd140019cc917f06514b058ba5c8 GIT binary patch literal 792 zcmV+z1LypSP)Tlih0-M;wNqJsyeRAE3F`D={=!qw#~29?+Q3f>4Tz zy$}k1AQVAGgjOp=L8W2~Qm`WRqD7IY*cLPeK|zS%O|ozEpTXXa4__49>M#7m4I==o!@ql zWf@abQ^~u4uMH#cC~#q5U|@3Dw*MG zoWqI7SV0*f)s8>*4RG!7dRn<*#qPgY^Zmu>LFi0*x^j1i`uh69XIoEVtjCI=t>@1J zO@@BFfz}4eT8PQ<-j(}@s)ht;SL^`Dv_m@~*Fvg_jVepA*~?<)Gu%779pK-$fE_`c z>F@6k%eS2dKpR0>;o9N#e6e>FtJ+xA!m1YcFYE!h9Wm{C>>Cx>UEpc0R>OM;A>hO_ zZ|eCG^W_Y~BLk z!R4PyyXm-hq8>q%utuX1mTo$RHbQQM+&Hp$cTUINCp8GZYBw2YngI0l^n`l72>kPH zzhaz6+aiQaJ8m8SlGVG;<5UZ$Qp74AUKuIvCMo`=yFgm+?(Pmtw*Ep0#eF?*>7sL1 za7J_c)Yq)q@jEV`!Rf51iP%}~ViwHr>gsBX2#x*M@#0W3&loSNz{>B=AXddN6kaTk z{ysUYT?t%35zG*<1)zWDIlR?)XAr9qtMJa?#q#){pG#Off<}QSrE)^?5BJ7!76S`` zuK;>Ck04g_|J9>ZMhTk$ZpLR?1rnhPBe1s<%$wqt_ckl63M|LFz)*CpO{H_4Fo0Ld Wi=bn&Fz%E90000ICON_DLG_EXTEND_FACE faceextension.png + + ICO_DLG_PROJ_ON_CYL + proj_on_cyl.png + ICON_DLG_PARTITION partition.png @@ -1143,6 +1147,10 @@ ICO_EXTENSION edgeextension.png + + ICO_PROJ_ON_CYL + proj_on_cyl.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 c44395e9b..8d91a427f 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -1248,6 +1248,10 @@ Please, select face, shell or solid and try again GEOM_PROJECTION_TITLE Projection + + GEOM_PROJECTION_NAME + Projection + GEOM_PROJ_ON_FACE_SOURCE Source vertex, edge or wire @@ -2832,6 +2836,10 @@ Please, select face, shell or solid and try again MEN_PROJECTION Projection + + MEN_PROJ_ON_CYL + Projection on Cylinder + MEN_OPERATIONS Operations @@ -3768,6 +3776,10 @@ Please, select face, shell or solid and try again STB_PROJECTION Project a point, an edge or a wire on a face + + STB_PROJ_ON_CYL + Project a wire or a face on a cylinder + STB_ORIGIN_AND_VECTORS Create an origin and base Vectors @@ -4376,6 +4388,10 @@ Please, select face, shell or solid and try again TOP_PROJECTION Projection + + TOP_PROJ_ON_CYL + Projection on Cylinder + TOP_ORIGIN_AND_VECTORS Create an origin and base Vectors @@ -7353,4 +7369,19 @@ Do you want to create new material? Materials: %1 of %2 + + TransformationGUI_ProjectionOnCylDlg + + GEOM_PROJ_ON_CYL_TITLE + Projection On A Cylinder + + + GEOM_PROJ_ON_CYL_START_ANGLE + Starting angle + + + GEOM_PROJ_ON_CYL_LENGTH_ANGLE + Length angle + + diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index 91428d94b..b603ddbe9 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -585,6 +585,7 @@ void GeometryGUI::OnGUIEvent( int id, const QVariant& theParam ) case GEOMOp::OpScale: // MENU TRANSFORMATION - SCALE case GEOMOp::OpOffset: // MENU TRANSFORMATION - OFFSET case GEOMOp::OpProjection: // MENU TRANSFORMATION - PROJECTION + case GEOMOp::OpProjOnCyl: // MENU TRANSFORMATION - PROJECTION ON CYLINDER case GEOMOp::OpMultiTranslate: // MENU TRANSFORMATION - MULTI-TRANSLATION case GEOMOp::OpMultiRotate: // MENU TRANSFORMATION - MULTI-ROTATION case GEOMOp::OpReimport: // CONTEXT(POPUP) MENU - RELOAD_IMPORTED @@ -963,6 +964,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createGeomAction( GEOMOp::OpScale, "SCALE" ); createGeomAction( GEOMOp::OpOffset, "OFFSET" ); createGeomAction( GEOMOp::OpProjection, "PROJECTION" ); + createGeomAction( GEOMOp::OpProjOnCyl, "PROJ_ON_CYL" ); createGeomAction( GEOMOp::OpMultiTranslate, "MUL_TRANSLATION" ); createGeomAction( GEOMOp::OpMultiRotate, "MUL_ROTATION" ); createGeomAction( GEOMOp::OpExtension, "EXTENSION" ); @@ -1205,6 +1207,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createMenu( GEOMOp::OpOffset, transId, -1 ); createMenu( GEOMOp::OpProjection, transId, -1 ); createMenu( GEOMOp::OpExtension, transId, -1 ); + createMenu( GEOMOp::OpProjOnCyl, transId, -1 ); createMenu( separator(), transId, -1 ); createMenu( GEOMOp::OpMultiTranslate, transId, -1 ); createMenu( GEOMOp::OpMultiRotate, transId, -1 ); @@ -1378,6 +1381,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createTool( GEOMOp::OpOffset, transTbId ); createTool( GEOMOp::OpProjection, transTbId ); createTool( GEOMOp::OpExtension, transTbId ); + createTool( GEOMOp::OpProjOnCyl, 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 32e3af191..25e0694dc 100644 --- a/src/GEOMGUI/GeometryGUI_Operations.h +++ b/src/GEOMGUI/GeometryGUI_Operations.h @@ -145,6 +145,7 @@ namespace GEOMOp { OpReimport = 3608, // POPUP MENU - RELOAD IMPORTED OpProjection = 3609, // MENU OPERATIONS - TRANSFORMATION - PROJECTION OpExtension = 3610, // MENU OPERATIONS - TRANSFORMATION - EXTENSION + OpProjOnCyl = 3611, // MENU OPERATIONS - TRANSFORMATION - PROJECTION ON CYLINDER // OperationGUI ----------------//-------------------------------- OpPartition = 3700, // MENU OPERATION - PARTITION OpArchimede = 3701, // MENU OPERATION - ARCHIMEDE diff --git a/src/GEOMImpl/CMakeLists.txt b/src/GEOMImpl/CMakeLists.txt index 5b3534e14..f5f61d520 100755 --- a/src/GEOMImpl/CMakeLists.txt +++ b/src/GEOMImpl/CMakeLists.txt @@ -98,6 +98,7 @@ SET(GEOMImpl_HEADERS GEOMImpl_ITranslate.hxx GEOMImpl_IMirror.hxx GEOMImpl_IProjection.hxx + GEOMImpl_IProjOnCyl.hxx GEOMImpl_IOffset.hxx GEOMImpl_IScale.hxx GEOMImpl_IRotate.hxx diff --git a/src/GEOMImpl/GEOMImpl_IProjOnCyl.hxx b/src/GEOMImpl/GEOMImpl_IProjOnCyl.hxx new file mode 100644 index 000000000..9fc6024d1 --- /dev/null +++ b/src/GEOMImpl/GEOMImpl_IProjOnCyl.hxx @@ -0,0 +1,61 @@ +// 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 interface to a function for the Projection on cylinder creation. + +#include "GEOM_Function.hxx" + +#define PROJECTION_ARG_SHAPE 1 +#define PROJECTION_ARG_RADIUS 2 +#define PROJECTION_ARG_START_ANGLE 3 +#define PROJECTION_ARG_ANGLE_LENGTH 4 + +class GEOMImpl_IProjOnCyl +{ + +public: + + GEOMImpl_IProjOnCyl(Handle(GEOM_Function) theFunction): _func(theFunction) {} + + void SetShape (const Handle(GEOM_Function) &theShape) + { _func->SetReference(PROJECTION_ARG_SHAPE, theShape); } + void SetRadius (const Standard_Real theRadius) + { _func->SetReal(PROJECTION_ARG_RADIUS, theRadius); } + void SetStartAngle (const Standard_Real theStartAngle) + { _func->SetReal(PROJECTION_ARG_START_ANGLE, theStartAngle); } + void SetAngleLength (const Standard_Real theAngleLength) + { _func->SetReal(PROJECTION_ARG_ANGLE_LENGTH, theAngleLength); } + + Handle(GEOM_Function) GetShape() + { return _func->GetReference(PROJECTION_ARG_SHAPE); } + Standard_Real GetRadius() + { return _func->GetReal(PROJECTION_ARG_RADIUS ); } + Standard_Real GetStartAngle() + { return _func->GetReal(PROJECTION_ARG_START_ANGLE ); } + Standard_Real GetAngleLength() + { return _func->GetReal(PROJECTION_ARG_ANGLE_LENGTH ); } + + private: + + Handle(GEOM_Function) _func; + +}; diff --git a/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx b/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx index 766531fdb..5d89b0c0a 100644 --- a/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -2267,3 +2268,78 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::TransformLikeOtherCopy SetErrorCode(OK); return aCopy; } + +//============================================================================= +/*! + * MakeProjectionOnCylinder + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_ITransformOperations::MakeProjectionOnCylinder + (const Handle(GEOM_Object) &theObject, + const Standard_Real theRadius, + const Standard_Real theStartAngle, + const Standard_Real theAngleLength) +{ + SetErrorCode(KO); + + if (theObject.IsNull()) { + return NULL; + } + + Handle(GEOM_Function) aLastFunction = theObject->GetLastFunction(); + + if (aLastFunction.IsNull()) { + //There is no function which creates an object to be projected + return NULL; + } + + //Add a new Projection object + Handle(GEOM_Object) aResult = + GetEngine()->AddObject(GetDocID(), GEOM_PROJECTION); + + //Add a Projection function + Handle(GEOM_Function) aFunction = aResult->AddFunction + (GEOMImpl_ProjectionDriver::GetID(), PROJECTION_ON_CYLINDER); + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_ProjectionDriver::GetID()) { + return aResult; + } + + GEOMImpl_IProjOnCyl aProj (aFunction); + + aProj.SetShape(aLastFunction); + aProj.SetRadius(theRadius); + aProj.SetStartAngle(theStartAngle); + aProj.SetAngleLength(theAngleLength); + + //Compute the Projection + try { + OCC_CATCH_SIGNALS; + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Projection driver failed"); + return aResult; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return aResult; + } + + //Make a Python command + GEOM::TPythonDump pd(aFunction); + + pd << aResult << " = geompy.MakeProjectionOnCylinder(" + << theObject << ", " << theRadius << ", " << theStartAngle; + + if (theAngleLength >= 0.) { + pd << ", " << theAngleLength; + } + + pd << ")"; + + SetErrorCode(OK); + + return aResult; +} diff --git a/src/GEOMImpl/GEOMImpl_ITransformOperations.hxx b/src/GEOMImpl/GEOMImpl_ITransformOperations.hxx index 2c44b3854..155dbfdd9 100644 --- a/src/GEOMImpl/GEOMImpl_ITransformOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_ITransformOperations.hxx @@ -191,6 +191,12 @@ class GEOMImpl_ITransformOperations : public GEOM_IOperations Standard_EXPORT Handle(GEOM_Object) TransformLikeOtherCopy (Handle(GEOM_Object) theObject, Handle(GEOM_Object) theSample); + Standard_EXPORT Handle(GEOM_Object) MakeProjectionOnCylinder + (const Handle(GEOM_Object) &theObject, + const Standard_Real theRadius, + const Standard_Real theStartAngle, + const Standard_Real theAngleLength); + }; #endif diff --git a/src/GEOMImpl/GEOMImpl_ProjectionDriver.cxx b/src/GEOMImpl/GEOMImpl_ProjectionDriver.cxx index 064dbb91b..d226969c8 100644 --- a/src/GEOMImpl/GEOMImpl_ProjectionDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ProjectionDriver.cxx @@ -26,16 +26,26 @@ #include #include +#include #include #include +#include +#include +#include #include +#include #include +#include +#include #include +#include #include #include +#include #include #include +#include #include #include @@ -44,11 +54,14 @@ #include #include #include -#include +#include +#include #include #include +#include #include +#include #include #include @@ -400,6 +413,42 @@ Standard_Integer GEOMImpl_ProjectionDriver::Execute(TFunction_Logbook& log) cons if (!hasValidSolution) { Standard_ConstructionError::Raise("Projection aborted : no projection"); } + } else if (aType == PROJECTION_ON_CYLINDER) { + GEOMImpl_IProjOnCyl aProj (aFunction); + Handle(GEOM_Function) aShapeFunction = aProj.GetShape(); + + if (aShapeFunction.IsNull()) { + return 0; + } + + TopoDS_Shape aShape = aShapeFunction->GetValue(); + + if (aShape.IsNull()) { + return 0; + } + + // Get the face. + const TopAbs_ShapeEnum aType = aShape.ShapeType(); + const Standard_Real aRadius = aProj.GetRadius(); + const Standard_Real aStartAngle = aProj.GetStartAngle(); + const Standard_Real aLengthAngle = aProj.GetAngleLength(); + + if (aType != TopAbs_WIRE && aType != TopAbs_FACE) { + return 0; + } + + if (aRadius <= Precision::Confusion()) { + return 0; + } + + TopoDS_Shape aProjShape = + projectOnCylinder(aShape, aRadius, aStartAngle, aLengthAngle); + + if (aProjShape.IsNull()) { + return 0; + } + + aFunction->SetValue(aProjShape); } return 1; @@ -438,6 +487,21 @@ GetCreationInformation(std::string& theOperationName, AddParam(theParams, "Point", aProj.GetPoint()); AddParam(theParams, "Shape", aProj.GetShape()); + break; + } + case PROJECTION_ON_CYLINDER: + { + GEOMImpl_IProjOnCyl aProj (function); + const Standard_Real aLengthAngle = aProj.GetAngleLength(); + + AddParam(theParams, "Shape", aProj.GetShape()); + AddParam(theParams, "Radius", aProj.GetRadius()); + AddParam(theParams, "Start angle", aProj.GetStartAngle()); + + if (aLengthAngle >= 0.) { + AddParam(theParams, "Length angle", aLengthAngle); + } + break; } default: @@ -447,5 +511,242 @@ GetCreationInformation(std::string& theOperationName, return true; } +//================================================================================ +/*! + * \brief Performs projection of a planar wire or a face on a cylinder. + */ +//================================================================================ + +TopoDS_Shape GEOMImpl_ProjectionDriver::projectOnCylinder + (const TopoDS_Shape &theShape, + const Standard_Real theRadius, + const Standard_Real theStartAngle, + const Standard_Real theAngleLength) const +{ + TopoDS_Shape aResult; + + // Get the face. + const TopAbs_ShapeEnum aType = theShape.ShapeType(); + TopoDS_Face aFace; + + if (aType == TopAbs_WIRE) { + // Try to create a planar face. + TopoDS_Wire aWire = TopoDS::Wire(theShape); + BRepBuilderAPI_MakeFace aMkFace(aWire, Standard_True); + + if (aMkFace.IsDone()) { + aFace = aMkFace.Face(); + } else { + // Check if the wire is a straight line. + TopExp_Explorer anEExp(aWire, TopAbs_EDGE); + TopoDS_Edge anEdge; + + for (; anEExp.More(); anEExp.Next()) { + anEdge = TopoDS::Edge(anEExp.Current()); + + if (!BRep_Tool::Degenerated(anEdge)) { + break; + } + } + + if (anEExp.More()) { + // Not degenerated edge found. Try to create a plane. + Standard_Real aPar[2]; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aPar[0], aPar[1]); + gp_Pnt aP0 = aCurve->Value(aPar[0]); + gp_Pnt aP1 = aCurve->Value(0.5*(aPar[1] + aPar[0])); + gp_Vec aX(aP1.XYZ().Subtracted(aP0.XYZ())); + Standard_Real aTolConf = Precision::Confusion(); + + if (aX.Magnitude() > aTolConf) { + aX.Normalize(); + + // Get the plane normal ortogonal to Z axis. + gp_Vec aZ(0., 0., 1.); + gp_Vec aN = aX.Crossed(aZ); + + if (aN.Magnitude() <= aTolConf) { + // aX is parallel to aZ. Get the plane normal ortogonal to Y axis. + gp_Vec aY(0., 1., 0.); + + aN = aX.Crossed(aY); + } + + if (aN.Magnitude() > aTolConf) { + gp_Ax3 anAxis(aP0, gp_Dir(aN), gp_Dir(aX)); + Handle(Geom_Plane) aPlane = new Geom_Plane(anAxis); + BRepBuilderAPI_MakeFace aMkFace(aPlane, aWire); + + if (aMkFace.IsDone()) { + aFace = aMkFace.Face(); + } + } + } + } + } + } else if (aType == TopAbs_FACE) { + aFace = TopoDS::Face(theShape); + } + + if (aFace.IsNull()) { + return aResult; + } + + // Compute 2d translation transformation. + TopoDS_Wire anOuterWire = BRepTools::OuterWire(aFace); + Standard_Real aU[2]; + Standard_Real aV[2]; + BRepTools_WireExplorer aOWExp(anOuterWire, aFace); + + if (!aOWExp.More()) { + // NEVERREACHED + return aResult; + } + + // Compute anisotropic transformation from a face's 2d space + // to cylinder's 2d space. + BRepTools::UVBounds(aFace, anOuterWire, aU[0], aU[1], aV[0], aV[1]); + + TopoDS_Vertex aFirstVertex = aOWExp.CurrentVertex(); + TopoDS_Edge aFirstEdge = aOWExp.Current(); + gp_Pnt aPnt = BRep_Tool::Pnt(aFirstVertex); + BRepAdaptor_Curve2d anAdaptorCurve(aFirstEdge, aFace); + Standard_Real aParam = + BRep_Tool::Parameter(aFirstVertex, aFirstEdge, aFace); + gp_Pnt2d aPntUV = anAdaptorCurve.Value(aParam); + + GEOMUtils::Trsf2d aTrsf2d + (1./theRadius, 0., theStartAngle - aU[0]/theRadius, + 0., 1., aPnt.Z() - 0.5*(aV[1] - aV[0]) - aPntUV.Y()); + + // Compute scaling trsf. + const Standard_Boolean isToScale = theAngleLength >= Precision::Angular(); + gp_Trsf2d aScaleTrsf; + + if (isToScale) { + // Perform 2d scaling. + gp_Pnt2d aMidPnt(0.5*(aU[1] + aU[0]), 0.5*(aV[1] + aV[0])); + const Standard_Real aScaleFactor = theAngleLength*theRadius/(aU[1] - aU[0]); + + aTrsf2d.TransformD0(aMidPnt); + + aScaleTrsf.SetScale(aMidPnt, aScaleFactor); + } + + // Get 2d presentation of a face. + Handle(Geom_Surface) aCylinder = + new Geom_CylindricalSurface(gp_Ax3(), theRadius); + GeomAdaptor_Surface aGACyl(aCylinder); + TopExp_Explorer anExp(aFace, TopAbs_WIRE); + Standard_Real aPar[2]; + TopTools_ListOfShape aWires; + Standard_Real aUResol = aGACyl.UResolution(Precision::Confusion()); + Standard_Real aVResol = aGACyl.VResolution(Precision::Confusion()); + + for (; anExp.More(); anExp.Next()) { + TopoDS_Wire aWire = TopoDS::Wire(anExp.Current()); + BRepTools_WireExplorer aWExp(aWire, aFace); + BRepBuilderAPI_MakeWire aMkWire; + + for (; aWExp.More(); aWExp.Next()) { + TopoDS_Edge anEdge = aWExp.Current(); + Handle(Geom2d_Curve) aCurve = + BRep_Tool::CurveOnSurface(anEdge, aFace, aPar[0], aPar[1]); + + if (aCurve.IsNull()) { + continue; + } + + // Transform the curve to cylinder's parametric space. + GEOMUtils::Handle(HTrsfCurve2d) aTrsfCurve = + new GEOMUtils::HTrsfCurve2d(aCurve, aPar[0], aPar[1], aTrsf2d); + Approx_Curve2d aConv (aTrsfCurve, aPar[0], aPar[1], + aUResol, aVResol, GeomAbs_C1, + 9, 1000); + + if (!aConv.IsDone() && !aConv.HasResult()) { + return aResult; + } + + Handle(Geom2d_Curve) aCylCurve = aConv.Curve(); + + if (isToScale) { + aCylCurve->Transform(aScaleTrsf); + } + + // Create edge and add it to the wire. + BRepBuilderAPI_MakeEdge aMkEdge(aCylCurve, aCylinder); + + if (!aMkEdge.IsDone()) { + return aResult; + } + + aMkWire.Add(aMkEdge.Edge()); + + if (!aMkWire.IsDone()) { + return aResult; + } + } + + if (aWire.IsSame(anOuterWire)) { + // Make the outer wire first. + aWires.Prepend(aMkWire.Wire()); + } else { + aWires.Append(aMkWire.Wire()); + } + } + + // Create a face. + if (aWires.IsEmpty()) { + return aResult; + } + + TopTools_ListIteratorOfListOfShape aWIter(aWires); + TopoDS_Wire aWire = TopoDS::Wire(aWIter.Value()); + BRepBuilderAPI_MakeFace aMkFace(aCylinder, aWire); + + if (!aMkFace.IsDone()) { + return aResult; + } + + for (aWIter.Next(); aWIter.More(); aWIter.Next()) { + aWire = TopoDS::Wire(aWIter.Value()); + aMkFace.Add(aWire); + + if (!aMkFace.IsDone()) { + return aResult; + } + } + + // Build 3D curves. + TopoDS_Face aCylFace = aMkFace.Face(); + TopoDS_Shape aResShape; + + BRepLib::BuildCurves3d(aCylFace); + + // Check shape. + if (aType == TopAbs_WIRE) { + TopExp_Explorer aResExp(aCylFace, TopAbs_WIRE); + + if (aResExp.More()) { + aResShape = aResExp.Current(); + } + } else { + aResShape = aCylFace; + } + + if (aResShape.IsNull() == Standard_False) { + if (!GEOMUtils::CheckShape(aResShape, true)) { + if (!GEOMUtils::FixShapeTolerance(aResShape)) { + return aResult; + } + } + + aResult = aResShape; + } + + return aResult; +} + IMPLEMENT_STANDARD_HANDLE (GEOMImpl_ProjectionDriver,GEOM_BaseDriver); IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_ProjectionDriver,GEOM_BaseDriver); diff --git a/src/GEOMImpl/GEOMImpl_ProjectionDriver.hxx b/src/GEOMImpl/GEOMImpl_ProjectionDriver.hxx index 5766c2392..ee703af55 100644 --- a/src/GEOMImpl/GEOMImpl_ProjectionDriver.hxx +++ b/src/GEOMImpl/GEOMImpl_ProjectionDriver.hxx @@ -58,6 +58,7 @@ #endif class TColStd_SequenceOfExtendedString; +class TopoDS_Shape; #include "GEOM_BaseDriver.hxx" @@ -81,6 +82,15 @@ Standard_EXPORT ~GEOMImpl_ProjectionDriver() {}; bool GetCreationInformation(std::string& theOperationName, std::vector& params); +private: + + TopoDS_Shape projectOnCylinder(const TopoDS_Shape &theShape, + const Standard_Real theRadius, + const Standard_Real theStartAngle, + const Standard_Real theAngleLength) const; + +public: + DEFINE_STANDARD_RTTI( GEOMImpl_ProjectionDriver ) }; diff --git a/src/GEOMImpl/GEOMImpl_Types.hxx b/src/GEOMImpl/GEOMImpl_Types.hxx index f4e151969..393b4303c 100644 --- a/src/GEOMImpl/GEOMImpl_Types.hxx +++ b/src/GEOMImpl/GEOMImpl_Types.hxx @@ -185,8 +185,9 @@ #define OFFSET_THICKENING 3 #define OFFSET_THICKENING_COPY 4 -#define PROJECTION_COPY 1 -#define PROJECTION_ON_WIRE 2 +#define PROJECTION_COPY 1 +#define PROJECTION_ON_WIRE 2 +#define PROJECTION_ON_CYLINDER 3 #define SCALE_SHAPE 1 #define SCALE_SHAPE_COPY 2 diff --git a/src/GEOMUtils/CMakeLists.txt b/src/GEOMUtils/CMakeLists.txt index 4368a6342..039990ab7 100755 --- a/src/GEOMUtils/CMakeLists.txt +++ b/src/GEOMUtils/CMakeLists.txt @@ -52,6 +52,9 @@ SET(_link_LIBRARIES SET(GEOMUtils_HEADERS GEOMUtils.hxx GEOMUtils_Hatcher.hxx + GEOMUtils_HTrsfCurve2d.hxx + GEOMUtils_Trsf2d.hxx + GEOMUtils_TrsfCurve2d.hxx GEOMUtils_XmlHandler.hxx ) # --- sources --- @@ -59,6 +62,9 @@ SET(GEOMUtils_HEADERS SET(GEOMUtils_SOURCES GEOMUtils.cxx GEOMUtils_Hatcher.cxx + GEOMUtils_HTrsfCurve2d.cxx + GEOMUtils_Trsf2d.cxx + GEOMUtils_TrsfCurve2d.cxx GEOMUtils_XmlHandler.cxx ) diff --git a/src/GEOMUtils/GEOMUtils_HTrsfCurve2d.cxx b/src/GEOMUtils/GEOMUtils_HTrsfCurve2d.cxx new file mode 100644 index 000000000..976d29690 --- /dev/null +++ b/src/GEOMUtils/GEOMUtils_HTrsfCurve2d.cxx @@ -0,0 +1,51 @@ +// 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 +// + + +#include + +namespace GEOMUtils { + IMPLEMENT_STANDARD_HANDLE (HTrsfCurve2d, Adaptor2d_HCurve2d); + IMPLEMENT_STANDARD_RTTIEXT(HTrsfCurve2d, Adaptor2d_HCurve2d); +} + +//======================================================================= +//function : TrsfCurve2d +//purpose : +//======================================================================= +GEOMUtils::HTrsfCurve2d::HTrsfCurve2d(const Handle(Geom2d_Curve) &theCurve, + const Trsf2d &theTrsf) +: myCurve (theCurve, theTrsf) +{ +} + +//======================================================================= +//function : TrsfCurve2d +//purpose : +//======================================================================= +GEOMUtils::HTrsfCurve2d::HTrsfCurve2d(const Handle(Geom2d_Curve) &theCurve, + const Standard_Real theUFirst, + const Standard_Real theULast, + const Trsf2d &theTrsf) +: myCurve (theCurve, theUFirst, theULast, theTrsf) +{ +} diff --git a/src/GEOMUtils/GEOMUtils_HTrsfCurve2d.hxx b/src/GEOMUtils/GEOMUtils_HTrsfCurve2d.hxx new file mode 100644 index 000000000..d37b7f293 --- /dev/null +++ b/src/GEOMUtils/GEOMUtils_HTrsfCurve2d.hxx @@ -0,0 +1,84 @@ +// 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 +// + +#ifndef _GEOMUtils_HTrsfCurve2d_HXX_ +#define _GEOMUtils_HTrsfCurve2d_HXX_ + + +#include + +#include + + +namespace GEOMUtils +{ + + class HTrsfCurve2d; + + DEFINE_STANDARD_HANDLE(HTrsfCurve2d, Adaptor2d_HCurve2d); + + /*! + * This class represents an adaptor curve that represents an original curve + * transformed by an anisotropic transformation. This is a class manipulated + * by handle. + */ + class HTrsfCurve2d : public Adaptor2d_HCurve2d + { + + public: + + /** + * Constructor. Initializes the object with the transformation parameters. + * Input parameters are not checked for validity. It is under responsibility + * of the caller. + */ + Standard_EXPORT HTrsfCurve2d(const Handle(Geom2d_Curve) &theCurve, + const Trsf2d &theTrsf); + + /** + * Constructor. Initializes the object with the curve, first and last + * parameters and transformation. Input parameters are not checked + * for validity. It is under responsibility of the caller. + */ + Standard_EXPORT HTrsfCurve2d(const Handle(Geom2d_Curve) &theCurve, + const Standard_Real theUFirst, + const Standard_Real theULast, + const Trsf2d &theTrsf); + + /** + * Redefined method from the base class. + */ + const Adaptor2d_Curve2d &Curve2d() const + { return myCurve; } + + private: + + TrsfCurve2d myCurve; + + public: + + DEFINE_STANDARD_RTTI(HTrsfCurve2d); + + }; +} + +#endif diff --git a/src/GEOMUtils/GEOMUtils_Trsf2d.cxx b/src/GEOMUtils/GEOMUtils_Trsf2d.cxx new file mode 100644 index 000000000..4938d4979 --- /dev/null +++ b/src/GEOMUtils/GEOMUtils_Trsf2d.cxx @@ -0,0 +1,110 @@ +// 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 +// + + +#include + + +//======================================================================= +//function : Trsf2d +//purpose : +//======================================================================= +GEOMUtils::Trsf2d::Trsf2d(const Standard_Real a11, + const Standard_Real a12, + const Standard_Real a13, + const Standard_Real a21, + const Standard_Real a22, + const Standard_Real a23) +: myA11(a11), + myA12(a12), + myA13(a13), + myA21(a21), + myA22(a22), + myA23(a23) +{ +} + +//======================================================================= +//function : TransformD0 +//purpose : +//======================================================================= +void GEOMUtils::Trsf2d::TransformD0(gp_Pnt2d &thePnt) const +{ + const Standard_Real aX = myA11*thePnt.X() + myA12*thePnt.Y() + myA13; + const Standard_Real aY = myA21*thePnt.X() + myA22*thePnt.Y() + myA23; + + thePnt.SetCoord(aX, aY); +} + +//======================================================================= +//function : TransformD1 +//purpose : +//======================================================================= +void GEOMUtils::Trsf2d::TransformD1(gp_Pnt2d &thePnt, + gp_Vec2d &theVec1) const +{ + TransformVector(thePnt, theVec1); + TransformD0(thePnt); +} + +//======================================================================= +//function : TransformD2 +//purpose : +//======================================================================= +void GEOMUtils::Trsf2d::TransformD2(gp_Pnt2d &thePnt, + gp_Vec2d &theVec1, + gp_Vec2d &theVec2) const +{ + TransformVector(thePnt, theVec1); + TransformVector(thePnt, theVec2); + TransformD0(thePnt); +} + +//======================================================================= +//function : TransformD3 +//purpose : +//======================================================================= +void GEOMUtils::Trsf2d::TransformD3(gp_Pnt2d &thePnt, + gp_Vec2d &theVec1, + gp_Vec2d &theVec2, + gp_Vec2d &theVec3) const +{ + TransformVector(thePnt, theVec1); + TransformVector(thePnt, theVec2); + TransformVector(thePnt, theVec3); + TransformD0(thePnt); +} + +//======================================================================= +//function : TransformVector +//purpose : +//======================================================================= +void GEOMUtils::Trsf2d::TransformVector(const gp_Pnt2d &thePnt, + gp_Vec2d &theVec) const +{ + gp_Pnt2d aP0(thePnt.XY()); + gp_Pnt2d aP1(thePnt.XY().Added(theVec.XY())); + + TransformD0(aP0); + TransformD0(aP1); + theVec.SetXY(aP1.XY().Subtracted(aP0.XY())); +} diff --git a/src/GEOMUtils/GEOMUtils_Trsf2d.hxx b/src/GEOMUtils/GEOMUtils_Trsf2d.hxx new file mode 100644 index 000000000..c287f90d8 --- /dev/null +++ b/src/GEOMUtils/GEOMUtils_Trsf2d.hxx @@ -0,0 +1,134 @@ +// 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 +// + +#ifndef _GEOMUtils_Trsf2d_HXX_ +#define _GEOMUtils_Trsf2d_HXX_ + + +#include +#include +#include +#include +#include + + +/*! + * This class represents a non-persistent transformation in 2D space. + * The transformations can be represented as follow : + * + * V1 V2 T XY XY + * | a11 a12 a13 | | x | | x'| + * | a21 a22 a23 | | y | | y'| + * | 0 0 1 | | 1 | | 1 | + + * where {V1, V2} defines the vectorial part of the transformation + * and T defines the translation part of the transformation. + * This transformation can change the nature of the objects if it is + * anisotropic. + */ +namespace GEOMUtils +{ + class Trsf2d + { + + public: + + /** + * Constructor. Initializes the object with the transformation parameters. + * Input parameters are not checked for validity. It is under responsibility + * of the caller. + */ + Standard_EXPORT Trsf2d(const Standard_Real a11, + const Standard_Real a12, + const Standard_Real a13, + const Standard_Real a21, + const Standard_Real a22, + const Standard_Real a23); + + /** + * Transform the point. The passed parameter is modified to have + * a transformed value. + * + * \param thePnt the point. + */ + Standard_EXPORT void TransformD0(gp_Pnt2d &thePnt)const; + + /** + * Transform the point and the first derivative vector. The passed + * parameters are modified to have a transformed value. + * + * \param thePnt the point. + * \param theVec1 the first derivative vector. + */ + Standard_EXPORT void TransformD1(gp_Pnt2d &thePnt, + gp_Vec2d &theVec1) const; + + /** + * Transform the point, the first and second derivative vectors. The passed + * parameters are modified to have a transformed value. + * + * \param thePnt the point. + * \param theVec1 the first derivative vector. + * \param theVec2 the second derivative vector. + */ + Standard_EXPORT void TransformD2(gp_Pnt2d &thePnt, + gp_Vec2d &theVec1, + gp_Vec2d &theVec2) const; + + /** + * Transform the point, the first, second and third derivative vectors. + * The passed parameters are modified to have a transformed value. + * + * \param thePnt the point. + * \param theVec1 the first derivative vector. + * \param theVec2 the second derivative vector. + * \param theVec2 the third derivative vector. + */ + Standard_EXPORT void TransformD3(gp_Pnt2d &thePnt, + gp_Vec2d &theVec1, + gp_Vec2d &theVec2, + gp_Vec2d &theVec3) const; + + private: + + /** + * Transform the vector. + * + * \param thePnt the point. + * \param theVec the vector. + */ + void TransformVector(const gp_Pnt2d &thePnt, + gp_Vec2d &theVec) const; + + private: + + Standard_Real myA11; + Standard_Real myA12; + Standard_Real myA13; + Standard_Real myA21; + Standard_Real myA22; + Standard_Real myA23; + + }; +} + +#endif diff --git a/src/GEOMUtils/GEOMUtils_TrsfCurve2d.cxx b/src/GEOMUtils/GEOMUtils_TrsfCurve2d.cxx new file mode 100644 index 000000000..fe0707eb9 --- /dev/null +++ b/src/GEOMUtils/GEOMUtils_TrsfCurve2d.cxx @@ -0,0 +1,382 @@ +// 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 +// + + +#include +#include + +//======================================================================= +//function : TrsfCurve2d +//purpose : +//======================================================================= +GEOMUtils::TrsfCurve2d::TrsfCurve2d(const Handle(Geom2d_Curve) &theCurve, + const Trsf2d &theTrsf) +: myCurve (theCurve), + myTrsf (theTrsf) +{ +} + +//======================================================================= +//function : TrsfCurve2d +//purpose : +//======================================================================= +GEOMUtils::TrsfCurve2d::TrsfCurve2d(const Handle(Geom2d_Curve) &theCurve, + const Standard_Real theUFirst, + const Standard_Real theULast, + const Trsf2d &theTrsf) +: myCurve (theCurve, theUFirst, theULast), + myTrsf (theTrsf) +{ +} + +//======================================================================= +//function : FirstParameter +//purpose : +//======================================================================= +Standard_Real GEOMUtils::TrsfCurve2d::FirstParameter() const +{ + return myCurve.FirstParameter(); +} + +//======================================================================= +//function : LastParameter +//purpose : +//======================================================================= +Standard_Real GEOMUtils::TrsfCurve2d::LastParameter() const +{ + return myCurve.LastParameter(); +} + +//======================================================================= +//function : Curve +//purpose : +//======================================================================= +const Handle(Geom2d_Curve) &GEOMUtils::TrsfCurve2d::Curve() const +{ + return myCurve.Curve(); +} + +//======================================================================= +//function : GetType +//purpose : +//======================================================================= +GeomAbs_CurveType GEOMUtils::TrsfCurve2d::GetType() const +{ + return GeomAbs_OtherCurve; +} + +//======================================================================= +//function : Load +//purpose : +//======================================================================= +void GEOMUtils::TrsfCurve2d::Load(const Handle(Geom2d_Curve) &C) +{ + myCurve.Load(C); +} + +//======================================================================= +//function : Load +//purpose : +//======================================================================= +void GEOMUtils::TrsfCurve2d::Load(const Handle(Geom2d_Curve) &C, + const Standard_Real UFirst, + const Standard_Real ULast) +{ + myCurve.Load(C, UFirst, ULast); +} + +//======================================================================= +//function : Continuity +//purpose : +//======================================================================= +GeomAbs_Shape GEOMUtils::TrsfCurve2d::Continuity() const +{ + return myCurve.Continuity(); +} + +//======================================================================= +//function : NbIntervals +//purpose : +//======================================================================= +Standard_Integer GEOMUtils::TrsfCurve2d::NbIntervals + (const GeomAbs_Shape S) const +{ + return myCurve.NbIntervals(S); +} + +//======================================================================= +//function : Intervals +//purpose : +//======================================================================= +void GEOMUtils::TrsfCurve2d::Intervals(TColStd_Array1OfReal &T, + const GeomAbs_Shape S) const +{ + myCurve.Intervals(T, S); +} + +//======================================================================= +//function : Trim +//purpose : +//======================================================================= +Handle(Adaptor2d_HCurve2d) GEOMUtils::TrsfCurve2d::Trim + (const Standard_Real First, const Standard_Real Last, + const Standard_Real /*Tol*/) const +{ + Handle(Geom2d_Curve) aCurve = myCurve.Curve(); + GEOMUtils::Handle(HTrsfCurve2d) aAHCurve = + new GEOMUtils::HTrsfCurve2d(aCurve, First, Last, myTrsf); + + return aAHCurve; +} + +//======================================================================= +//function : IsClosed +//purpose : +//======================================================================= +Standard_Boolean GEOMUtils::TrsfCurve2d::IsClosed() const +{ + return myCurve.IsClosed(); +} + +//======================================================================= +//function : IsPeriodic +//purpose : +//======================================================================= +Standard_Boolean GEOMUtils::TrsfCurve2d::IsPeriodic() const +{ + return myCurve.IsPeriodic(); +} + +//======================================================================= +//function : Period +//purpose : +//======================================================================= +Standard_Real GEOMUtils::TrsfCurve2d::Period() const +{ + return myCurve.Period(); +} + +//======================================================================= +//function : Value +//purpose : +//======================================================================= +gp_Pnt2d GEOMUtils::TrsfCurve2d::Value(const Standard_Real U) const +{ + gp_Pnt2d aPnt = myCurve.Value(U); + + myTrsf.TransformD0(aPnt); + + return aPnt; +} + +//======================================================================= +//function : D0 +//purpose : +//======================================================================= +void GEOMUtils::TrsfCurve2d::D0(const Standard_Real U, gp_Pnt2d &P) const +{ + myCurve.D0(U, P); + myTrsf.TransformD0(P); +} + +//======================================================================= +//function : D1 +//purpose : +//======================================================================= +void GEOMUtils::TrsfCurve2d::D1(const Standard_Real U, + gp_Pnt2d &P, gp_Vec2d &V) const +{ + myCurve.D1(U, P, V); + myTrsf.TransformD1(P, V); +} + +//======================================================================= +//function : D2 +//purpose : +//======================================================================= +void GEOMUtils::TrsfCurve2d::D2(const Standard_Real U, gp_Pnt2d &P, + gp_Vec2d &V1, gp_Vec2d &V2) const +{ + myCurve.D2(U, P, V1, V2); + myTrsf.TransformD2(P, V1, V2); +} + +//======================================================================= +//function : D3 +//purpose : +//======================================================================= +void GEOMUtils::TrsfCurve2d::D3(const Standard_Real U, gp_Pnt2d &P, + gp_Vec2d &V1, gp_Vec2d &V2, gp_Vec2d &V3) const +{ + myCurve.D3(U, P, V1, V2, V3); + myTrsf.TransformD3(P, V1, V2, V3); +} + +//======================================================================= +//function : DN +//purpose : +//======================================================================= +gp_Vec2d GEOMUtils::TrsfCurve2d::DN(const Standard_Real U, + const Standard_Integer N) const +{ + gp_Pnt2d aPnt = myCurve.Value(U); + gp_Vec2d aVec = myCurve.DN(U, N); + + myTrsf.TransformD1(aPnt, aVec); +} + +//======================================================================= +//function : Resolution +//purpose : +//======================================================================= +Standard_Real GEOMUtils::TrsfCurve2d::Resolution(const Standard_Real Ruv) const +{ + return Precision::Parametric(Ruv); +} + +//======================================================================= +//function : Line +//purpose : +//======================================================================= +gp_Lin2d GEOMUtils::TrsfCurve2d::Line() const +{ + Standard_NoSuchObject::Raise(); + + return gp_Lin2d(); +} + +//======================================================================= +//function : Circle +//purpose : +//======================================================================= +gp_Circ2d GEOMUtils::TrsfCurve2d::Circle() const +{ + Standard_NoSuchObject::Raise(); + + return gp_Circ2d(); +} + +//======================================================================= +//function : Ellipse +//purpose : +//======================================================================= +gp_Elips2d GEOMUtils::TrsfCurve2d::Ellipse() const +{ + Standard_NoSuchObject::Raise(); + + return gp_Elips2d(); +} + +//======================================================================= +//function : Hyperbola +//purpose : +//======================================================================= +gp_Hypr2d GEOMUtils::TrsfCurve2d::Hyperbola() const +{ + Standard_NoSuchObject::Raise(); + + return gp_Hypr2d(); +} + +//======================================================================= +//function : Parabola +//purpose : +//======================================================================= +gp_Parab2d GEOMUtils::TrsfCurve2d::Parabola() const +{ + Standard_NoSuchObject::Raise(); + + return gp_Parab2d(); +} + +//======================================================================= +//function : Degree +//purpose : +//======================================================================= +Standard_Integer GEOMUtils::TrsfCurve2d::Degree() const +{ + Standard_NoSuchObject::Raise(); + + return 0; +} + +//======================================================================= +//function : IsRational +//purpose : +//======================================================================= +Standard_Boolean GEOMUtils::TrsfCurve2d::IsRational() const +{ + return Standard_False; +} + +//======================================================================= +//function : NbPoles +//purpose : +//======================================================================= +Standard_Integer GEOMUtils::TrsfCurve2d::NbPoles() const +{ + Standard_NoSuchObject::Raise(); + + return 0; +} + +//======================================================================= +//function : NbKnots +//purpose : +//======================================================================= +Standard_Integer GEOMUtils::TrsfCurve2d::NbKnots() const +{ + Standard_NoSuchObject::Raise(); + + return 0; +} + +//======================================================================= +//function : Bezier +//purpose : +//======================================================================= +Handle(Geom2d_BezierCurve) GEOMUtils::TrsfCurve2d::Bezier() const +{ + Standard_NoSuchObject::Raise(); + + return NULL; +} + +//======================================================================= +//function : BSpline +//purpose : +//======================================================================= +Handle(Geom2d_BSplineCurve) GEOMUtils::TrsfCurve2d::BSpline() const +{ + Standard_NoSuchObject::Raise(); + + return NULL; +} + +//======================================================================= +//function : NbSamples +//purpose : +//======================================================================= +Standard_Integer GEOMUtils::TrsfCurve2d::NbSamples() const +{ + return myCurve.NbSamples(); +} diff --git a/src/GEOMUtils/GEOMUtils_TrsfCurve2d.hxx b/src/GEOMUtils/GEOMUtils_TrsfCurve2d.hxx new file mode 100644 index 000000000..b3bd19433 --- /dev/null +++ b/src/GEOMUtils/GEOMUtils_TrsfCurve2d.hxx @@ -0,0 +1,242 @@ +// 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 +// + +#ifndef _GEOMUtils_TrsfCurve2d_HXX_ +#define _GEOMUtils_TrsfCurve2d_HXX_ + + +#include + +#include +#include +#include +#include +#include + + +namespace GEOMUtils +{ + /*! + * This class represents an adaptor curve that represents an original curve + * transformed by an anisotropic transformation. + */ + class TrsfCurve2d : public Adaptor2d_Curve2d + { + + public: + + /** + * Constructor. Initializes the object with the transformation parameters. + * Input parameters are not checked for validity. It is under responsibility + * of the caller. + */ + Standard_EXPORT TrsfCurve2d(const Handle(Geom2d_Curve) &theCurve, + const Trsf2d &theTrsf); + + /** + * Constructor. Initializes the object with the curve, first and last + * parameters and transformation. Input parameters are not checked + * for validity. It is under responsibility of the caller. + */ + Standard_EXPORT TrsfCurve2d(const Handle(Geom2d_Curve) &theCurve, + const Standard_Real theUFirst, + const Standard_Real theULast, + const Trsf2d &theTrsf); + + /** + * Redefined method from the base class. + */ + Standard_EXPORT Standard_Real FirstParameter() const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT Standard_Real LastParameter() const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT const Handle(Geom2d_Curve)& Curve() const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT GeomAbs_CurveType GetType() const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT void Load(const Handle(Geom2d_Curve) &C); + + /** + * Redefined method from the base class. + */ + Standard_EXPORT void Load(const Handle(Geom2d_Curve) &C, + const Standard_Real UFirst, + const Standard_Real ULast); + + /** + * Redefined method from the base class. + */ + Standard_EXPORT GeomAbs_Shape Continuity() const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT Standard_Integer NbIntervals(const GeomAbs_Shape S) const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT void Intervals(TColStd_Array1OfReal &T, + const GeomAbs_Shape S) const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT Handle(Adaptor2d_HCurve2d) Trim + (const Standard_Real First, const Standard_Real Last, + const Standard_Real ) const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT Standard_Boolean IsClosed() const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT Standard_Boolean IsPeriodic() const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT Standard_Real Period() const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT gp_Pnt2d Value(const Standard_Real U) const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT void D0(const Standard_Real U, gp_Pnt2d &P) const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT void D1(const Standard_Real U, + gp_Pnt2d &P, gp_Vec2d &V) const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT void D2(const Standard_Real U, gp_Pnt2d &P, + gp_Vec2d &V1, gp_Vec2d &V2) const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT void D3(const Standard_Real U, gp_Pnt2d &P, + gp_Vec2d &V1, gp_Vec2d &V2, gp_Vec2d &V3) const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT gp_Vec2d DN(const Standard_Real U, + const Standard_Integer N) const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT Standard_Real Resolution(const Standard_Real Ruv) const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT gp_Lin2d Line() const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT gp_Circ2d Circle() const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT gp_Elips2d Ellipse() const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT gp_Hypr2d Hyperbola() const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT gp_Parab2d Parabola() const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT Standard_Integer Degree() const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT Standard_Boolean IsRational() const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT Standard_Integer NbPoles() const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT Standard_Integer NbKnots() const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT Handle(Geom2d_BezierCurve) Bezier() const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT Handle(Geom2d_BSplineCurve) BSpline() const; + + /** + * Redefined method from the base class. + */ + Standard_EXPORT Standard_Integer NbSamples() const; + + private: + + Geom2dAdaptor_Curve myCurve; + Trsf2d myTrsf; + + }; +} + +#endif diff --git a/src/GEOM_I/GEOM_ITransformOperations_i.cc b/src/GEOM_I/GEOM_ITransformOperations_i.cc index 2281957e3..c18c87b6c 100644 --- a/src/GEOM_I/GEOM_ITransformOperations_i.cc +++ b/src/GEOM_I/GEOM_ITransformOperations_i.cc @@ -1392,3 +1392,37 @@ GEOM::GEOM_Object_ptr GEOM_ITransformOperations_i::RecomputeObject return aGEOMObject._retn(); } + +//============================================================================= +/*! + * MakeProjectionOnCylinder + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_ITransformOperations_i::MakeProjectionOnCylinder + (GEOM::GEOM_Object_ptr theObject, + CORBA::Double theRadius, + CORBA::Double theStartAngle, + CORBA::Double theAngleLength) +{ + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + + //Get the object + Handle(GEOM_Object) anObject = GetObjectImpl(theObject); + + if (anObject.IsNull()) { + return aGEOMObject._retn(); + } + + //Perform the transformation + Handle(GEOM_Object) aResObject = GetOperations()->MakeProjectionOnCylinder + (anObject, theRadius, theStartAngle, theAngleLength); + + if (!GetOperations()->IsDone() || aResObject.IsNull()) { + return aGEOMObject._retn(); + } + + return GetObject(aResObject); +} diff --git a/src/GEOM_I/GEOM_ITransformOperations_i.hh b/src/GEOM_I/GEOM_ITransformOperations_i.hh index 40a5903ed..e507c1f77 100644 --- a/src/GEOM_I/GEOM_ITransformOperations_i.hh +++ b/src/GEOM_I/GEOM_ITransformOperations_i.hh @@ -197,6 +197,11 @@ class GEOM_I_EXPORT GEOM_ITransformOperations_i : GEOM::GEOM_Object_ptr RecomputeObject (GEOM::GEOM_Object_ptr theObject); + GEOM::GEOM_Object_ptr MakeProjectionOnCylinder + (GEOM::GEOM_Object_ptr theObject, + CORBA::Double theRadius, + CORBA::Double theStartAngle, + CORBA::Double theAngleLength); ::GEOMImpl_ITransformOperations* GetOperations() { return (::GEOMImpl_ITransformOperations*)GetImpl(); } }; diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py old mode 100755 new mode 100644 index f3d338af6..2f8c983c2 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -9347,6 +9347,71 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): anObj = self.MultiRotate2DByStep(aShape, aVec, anAngle, nbtimes1, aStep, nbtimes2, theName) return anObj + ## + # Compute a wire or a face or a compound of faces that represents + # a projection of the source shape onto cylinder. The cylinder's + # coordinate system is the same as the global coordinate system. + # + # @param theObject The object to be projected. It can be either + # a planar wire or a face. + # @param theRadius The radius of the cylinder. + # @param theStartAngle The starting angle in radians from + # the cylinder's X axis around Z axis. The angle from which + # the projection is started. + # @param theAngleLength The projection length angle in radians. + # The angle in which to project the total length of the wire. + # If it is negative the projection is not scaled and natural + # wire length is kept for the projection. + # @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 result shape. The result + # represents a wire or a face or a compound of faces that + # represents a projection of the source shape onto a cylinder. + # + # @ref tui_fillet "Example 1" + # \n @ref swig_MakeFilletAll "Example 2" + def MakeProjectionOnCylinder (self, theObject, theRadius, + theStartAngle=0.0, theAngleLength=-1.0, + theName=None): + """ + Compute a wire or a face or a compound of faces that represents + a projection of the source shape onto cylinder. The cylinder's + coordinate system is the same as the global coordinate system. + + Parameters: + theObject The object to be projected. It can be either + a planar wire or a face. + theRadius The radius of the cylinder. + theStartAngle The starting angle in radians from the cylinder's X axis + around Z axis. The angle from which the projection is started. + theAngleLength The projection length angle in radians. The angle in which + to project the total length of the wire. If it is negative the + projection is not scaled and natural wire length is kept for + the projection. + 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 result shape. The result + represents a wire or a face or a compound of faces that + represents a projection of the source shape onto a cylinder. + + Example of usage: + filletall = geompy.MakeFilletAll(prism, 10.) + """ + # Example: see GEOM_TestOthers.py + theRadius, theStartAngle, theAngleLength, Parameters = ParseParameters( + theRadius, theStartAngle, theAngleLength) + anObj = self.TrsfOp.MakeProjectionOnCylinder(theObject, theRadius, + theStartAngle, theAngleLength) + RaiseIfFailed("MakeProjectionOnCylinder", self.TrsfOp) + anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "projection") + return anObj + # end of l3_transform ## @} diff --git a/src/TransformationGUI/CMakeLists.txt b/src/TransformationGUI/CMakeLists.txt index e60a2e84b..2b4b75858 100755 --- a/src/TransformationGUI/CMakeLists.txt +++ b/src/TransformationGUI/CMakeLists.txt @@ -75,6 +75,7 @@ SET(TransformationGUI_HEADERS TransformationGUI_ScaleDlg.h TransformationGUI_OffsetDlg.h TransformationGUI_ProjectionDlg.h + TransformationGUI_ProjectionOnCylDlg.h TransformationGUI_PositionDlg.h ) @@ -89,6 +90,7 @@ SET(_moc_HEADERS TransformationGUI_ScaleDlg.h TransformationGUI_OffsetDlg.h TransformationGUI_ProjectionDlg.h + TransformationGUI_ProjectionOnCylDlg.h TransformationGUI_PositionDlg.h ) @@ -111,6 +113,7 @@ SET(TransformationGUI_SOURCES TransformationGUI_ScaleDlg.cxx TransformationGUI_OffsetDlg.cxx TransformationGUI_ProjectionDlg.cxx + TransformationGUI_ProjectionOnCylDlg.cxx TransformationGUI_PositionDlg.cxx ${_moc_SOURCES} ${_uic_files} diff --git a/src/TransformationGUI/TransformationGUI.cxx b/src/TransformationGUI/TransformationGUI.cxx index 47be80cd1..943e2126b 100644 --- a/src/TransformationGUI/TransformationGUI.cxx +++ b/src/TransformationGUI/TransformationGUI.cxx @@ -49,6 +49,7 @@ #include "TransformationGUI_OffsetDlg.h" // Method OFFSET #include "TransformationGUI_ProjectionDlg.h" // Method PROJECTION #include "TransformationGUI_PositionDlg.h" // Method POSITION +#include "TransformationGUI_ProjectionOnCylDlg.h" // Method PROJECTION ON CYLINDER //======================================================================= // function : TransformationGUI() @@ -102,6 +103,9 @@ bool TransformationGUI::OnGUIEvent( int theCommandID, SUIT_Desktop* parent ) case GEOMOp::OpProjection: // PROJECTION aDlg = new TransformationGUI_ProjectionDlg( getGeometryGUI(), parent ); break; + case GEOMOp::OpProjOnCyl: // PROJECTION ON CYLINDER + aDlg = new TransformationGUI_ProjectionOnCylDlg( getGeometryGUI(), parent ); + break; case GEOMOp::OpMultiTranslate: // MULTI TRANSLATION aDlg = new TransformationGUI_MultiTranslationDlg( getGeometryGUI(), parent ); break; diff --git a/src/TransformationGUI/TransformationGUI_ProjectionOnCylDlg.cxx b/src/TransformationGUI/TransformationGUI_ProjectionOnCylDlg.cxx new file mode 100644 index 000000000..2f9ad4b36 --- /dev/null +++ b/src/TransformationGUI/TransformationGUI_ProjectionOnCylDlg.cxx @@ -0,0 +1,360 @@ +// 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_ProjectionOnCylDlg.cxx +// Author : Sergey KHROMOV, Open CASCADE S.A.S. + +#include "TransformationGUI_ProjectionOnCylDlg.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +//================================================================================= +// class : TransformationGUI_ProjectionOnCylDlg() +// purpose : Constructs a TransformationGUI_ProjectionOnCylDlg which is +// a child of 'parent', with the name 'name' and widget flags set to +// 'f'. The dialog will by default be modeless, unless you set +// 'modal' to TRUE to construct a modal dialog. +//================================================================================= +TransformationGUI_ProjectionOnCylDlg::TransformationGUI_ProjectionOnCylDlg +(GeometryGUI* theGeometryGUI, QWidget* parent, bool modal, Qt::WindowFlags fl) + : GEOMBase_Skeleton (theGeometryGUI, parent, modal, fl), + myObjectName (0), + mySelButton (0), + myRadiusSpin (0), + myStartAngleSpin (0), + myUseAngleLen (0), + myAngleLenSpin (0) +{ + SUIT_ResourceMgr* aResMgr = myGeomGUI->getApp()->resourceMgr(); + QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICO_DLG_PROJ_ON_CYL"))); + QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT"))); + + setWindowTitle(tr("GEOM_PROJ_ON_CYL_TITLE")); + + /***************************************************************/ + mainFrame()->GroupConstructors->setTitle(tr("GEOM_PROJECTION_TITLE")); + mainFrame()->RadioButton1->setIcon(image0); + mainFrame()->RadioButton2->setAttribute(Qt::WA_DeleteOnClose); + mainFrame()->RadioButton2->close(); + mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose); + mainFrame()->RadioButton3->close(); + + QGroupBox *aGrpParams = + new QGroupBox(tr("GEOM_ARGUMENTS"), centralWidget()); + QGridLayout *aParamsLayout = new QGridLayout(aGrpParams); + QLabel *anObjLbl = new QLabel(tr("GEOM_OBJECT"), aGrpParams); + QLabel *aRadiusLbl = new QLabel(tr("GEOM_RADIUS"), aGrpParams); + QLabel *aStartAngleLbl = + new QLabel(tr("GEOM_PROJ_ON_CYL_START_ANGLE"), aGrpParams); + QLabel *anAngleLenLbl = + new QLabel(tr("GEOM_PROJ_ON_CYL_LENGTH_ANGLE"), aGrpParams); + + myObjectName = new QLineEdit(aGrpParams); + mySelButton = new QPushButton(aGrpParams); + myRadiusSpin = new SalomeApp_DoubleSpinBox(aGrpParams); + myStartAngleSpin = new SalomeApp_DoubleSpinBox(aGrpParams); + myUseAngleLen = new QCheckBox(aGrpParams); + myAngleLenSpin = new SalomeApp_DoubleSpinBox(aGrpParams); + + myObjectName->setReadOnly(true); + mySelButton->setIcon(image1); + mySelButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + myUseAngleLen->setChecked(false); + + aParamsLayout->setMargin(9); + aParamsLayout->setSpacing(6); + aParamsLayout->addWidget(anObjLbl, 0, 1); + aParamsLayout->addWidget(mySelButton, 0, 2); + aParamsLayout->addWidget(myObjectName, 0, 3); + aParamsLayout->addWidget(aRadiusLbl, 1, 1); + aParamsLayout->addWidget(myRadiusSpin, 1, 2, 1, 2); + aParamsLayout->addWidget(aStartAngleLbl, 2, 1); + aParamsLayout->addWidget(myStartAngleSpin, 2, 2, 1, 2); + aParamsLayout->addWidget(myUseAngleLen, 3, 0); + aParamsLayout->addWidget(anAngleLenLbl, 3, 1); + aParamsLayout->addWidget(myAngleLenSpin, 3, 2, 1, 2); + + QVBoxLayout* layout = new QVBoxLayout( centralWidget() ); + layout->setMargin( 0 ); layout->setSpacing( 6 ); + layout->addWidget( aGrpParams ); + + /***************************************************************/ + + setHelpFileName("project_on_cylinder_operation_page.html"); + + Init(); +} + +//================================================================================= +// function : ~TransformationGUI_ProjectionOnCylDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +TransformationGUI_ProjectionOnCylDlg::~TransformationGUI_ProjectionOnCylDlg() +{ + // no need to delete child widgets, Qt does it all for us +} + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void TransformationGUI_ProjectionOnCylDlg::Init() +{ + showOnlyPreviewControl(); + + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + double aStep = resMgr->doubleValue("Geometry", "SettingsGeomStep", 100); + double aSpecificStep = 5; + double aRadius = 100.0; + double aStartAngle = 0.; + double anAngleLen = 360.; + + initSpinBox(myRadiusSpin, 0.00001, COORD_MAX, aStep, "length_precision"); + initSpinBox(myStartAngleSpin, -180., 180., aSpecificStep, "angle_precision"); + initSpinBox(myAngleLenSpin, 0.00001, COORD_MAX, aSpecificStep, "angle_precision"); + + myRadiusSpin->setValue(aRadius); + myStartAngleSpin->setValue(aStartAngle); + myAngleLenSpin->setValue(anAngleLen); + + myObjectName->setText(""); + myUseAngleLen->setChecked(true); + + // signals and slots connections + connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk())); + connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply())); + + connect(mySelButton, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); + connect(myRadiusSpin, SIGNAL(valueChanged(double)), this, SLOT(processPreview())); + connect(myStartAngleSpin, SIGNAL(valueChanged(double)), this, SLOT(processPreview())); + connect(myAngleLenSpin, SIGNAL(valueChanged(double)), this, SLOT(processPreview())); + connect(myUseAngleLen, SIGNAL(clicked()), this, SLOT(SetUseLengthAngle())); + + connect(myGeomGUI->getApp()->selectionMgr(),SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); + + initName(tr("GEOM_PROJECTION_NAME")); + + buttonOk()->setEnabled(false); + buttonApply()->setEnabled(false); + + activateSelection(); + SelectionIntoArgument(); +} + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void TransformationGUI_ProjectionOnCylDlg::ClickOnOk() +{ + setIsApplyAndClose( true ); + if (ClickOnApply()) + ClickOnCancel(); +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +bool TransformationGUI_ProjectionOnCylDlg::ClickOnApply() +{ + if ( !onAccept() ) + return false; + + initName(); + return true; +} + +//================================================================================= +// function : SelectionIntoArgument() +// purpose : Called when selection is changed or on dialog initialization or activation +//================================================================================= +void TransformationGUI_ProjectionOnCylDlg::SelectionIntoArgument() +{ + erasePreview(); + myObj = GEOM::GEOM_Object::_nil(); + + LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr(); + SALOME_ListIO aSelList; + aSelMgr->selectedObjects(aSelList); + + if (aSelList.Extent() == 1) { + // Single object is selected. + GEOM::GEOM_Object_var aSelectedObject = + GEOMBase::ConvertIOinGEOMObject( aSelList.First() ); + + if (aSelectedObject->_is_nil()) { + // Null object. + myObjectName->setText(""); + buttonOk()->setEnabled(false); + buttonApply()->setEnabled(false); + } else { + // Not Null object. + myObj = aSelectedObject; + myObjectName->setText(GEOMBase::GetName(myObj)); + buttonOk()->setEnabled(true); + buttonApply()->setEnabled(true); + } + } else { + // Not a single object is selected. + myObjectName->setText(""); + buttonOk()->setEnabled(false); + buttonApply()->setEnabled(false); + } + + processPreview(); +} + +//================================================================================= +// function : SetEditCurrentArgument() +// purpose : +//================================================================================= +void TransformationGUI_ProjectionOnCylDlg::SetEditCurrentArgument() +{ + myObjectName->setFocus(); + myEditCurrentArgument = myObjectName; + SelectionIntoArgument(); +} + +//================================================================================= +// function : SetUseLengthAngle() +// purpose : +//================================================================================= +void TransformationGUI_ProjectionOnCylDlg::SetUseLengthAngle() +{ + myAngleLenSpin->setEnabled(myUseAngleLen->isChecked()); + processPreview(); +} + +//================================================================================= +// function : activateSelection +// purpose : activate selection of wires or faces +//================================================================================= +void TransformationGUI_ProjectionOnCylDlg::activateSelection() +{ + TColStd_MapOfInteger aMap; + + aMap.Add(GEOM_WIRE); + aMap.Add(GEOM_FACE); + globalSelection(aMap); +} + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void TransformationGUI_ProjectionOnCylDlg::ActivateThisDialog() +{ + GEOMBase_Skeleton::ActivateThisDialog(); + connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ), + this, SLOT( SelectionIntoArgument() ) ); + + activateSelection(); +} + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void TransformationGUI_ProjectionOnCylDlg::enterEvent (QEvent*) +{ + if (!mainFrame()->GroupConstructors->isEnabled()) + ActivateThisDialog(); +} + +//================================================================================= +// function : createOperation +// purpose : +//================================================================================= +GEOM::GEOM_IOperations_ptr TransformationGUI_ProjectionOnCylDlg::createOperation() +{ + return getGeomEngine()->GetITransformOperations(getStudyId()); +} + +//================================================================================= +// function : isValid +// purpose : +//================================================================================= +bool TransformationGUI_ProjectionOnCylDlg::isValid (QString &msg) +{ + bool isOk = false; + + if (!myObj->_is_nil() && + myRadiusSpin->isValid(msg, !IsPreview()) && + myStartAngleSpin->isValid(msg, !IsPreview())) { + if (myUseAngleLen->isChecked()) { + // Check length angle spin. + isOk = myAngleLenSpin->isValid(msg, !IsPreview()); + } else { + // Don't check length angle spin. + isOk = true; + } + } + + return isOk; +} + +//================================================================================= +// function : execute +// purpose : +//================================================================================= +bool TransformationGUI_ProjectionOnCylDlg::execute (ObjectList& objects) +{ + GEOM::GEOM_ITransformOperations_var anOper = + GEOM::GEOM_ITransformOperations::_narrow(getOperation()); + + double aRadius = myRadiusSpin->value(); + double aStartAngle = myStartAngleSpin->value()*M_PI/180.; + double aLengthAngle = -1.; + + if (myUseAngleLen->isChecked()) { + aLengthAngle = myAngleLenSpin->value()*M_PI/180.; + } + + GEOM::GEOM_Object_var anObj = anOper->MakeProjectionOnCylinder + (myObj, aRadius, aStartAngle, aLengthAngle); + + if (!anObj->_is_nil()) { + objects.push_back(anObj._retn()); + } + + return true; +} diff --git a/src/TransformationGUI/TransformationGUI_ProjectionOnCylDlg.h b/src/TransformationGUI/TransformationGUI_ProjectionOnCylDlg.h new file mode 100644 index 000000000..beb16d976 --- /dev/null +++ b/src/TransformationGUI/TransformationGUI_ProjectionOnCylDlg.h @@ -0,0 +1,78 @@ +// 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_ProjectionOnCylDlg.h +// Author : Sergey KHROMOV, Open CASCADE S.A.S. +// +#ifndef TRANSFORMATIONGUI_PROJECTIONONCYLDLG_H +#define TRANSFORMATIONGUI_PROJECTIONONCYLDLG_H + + +#include "GEOMBase_Skeleton.h" + + +//================================================================================= +// class : TransformationGUI_ProjectionOnCylDlg +// purpose : +//================================================================================= +class TransformationGUI_ProjectionOnCylDlg : public GEOMBase_Skeleton +{ + Q_OBJECT + +public: + TransformationGUI_ProjectionOnCylDlg(GeometryGUI*, QWidget* = 0, + bool = false, Qt::WindowFlags = 0); + ~TransformationGUI_ProjectionOnCylDlg(); + +protected: + // redefined from GEOMBase_Helper + virtual GEOM::GEOM_IOperations_ptr createOperation(); + virtual bool isValid(QString &msg); + virtual bool execute(ObjectList &); + +private: + void Init(); + void enterEvent( QEvent* ); + void activateSelection(); + +private slots: + void ClickOnOk(); + bool ClickOnApply(); + void ActivateThisDialog(); + void SelectionIntoArgument(); + void SetEditCurrentArgument(); + void SetUseLengthAngle(); + +private: + + GEOM::GEOM_Object_var myObj; + QLineEdit *myObjectName; + QPushButton *mySelButton; + SalomeApp_DoubleSpinBox *myRadiusSpin; + SalomeApp_DoubleSpinBox *myStartAngleSpin; + QCheckBox *myUseAngleLen; + SalomeApp_DoubleSpinBox *myAngleLenSpin; + +}; + +#endif // TRANSFORMATIONGUI_PROJECTIONONCYLDLG_H -- 2.39.2