Salome HOME
Added rotation by three points.
authorClarisse Genrault <clarisse.genrault@cea.fr>
Tue, 7 Mar 2017 12:55:18 +0000 (13:55 +0100)
committerClarisse Genrault <clarisse.genrault@cea.fr>
Tue, 7 Mar 2017 12:55:18 +0000 (13:55 +0100)
15 files changed:
src/FeaturesAPI/FeaturesAPI_Rotation.cpp
src/FeaturesAPI/FeaturesAPI_Rotation.h
src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp
src/FeaturesPlugin/FeaturesPlugin_Rotation.h
src/FeaturesPlugin/icons/SVG/rotation_3pt_32x32.svg [new file with mode: 0644]
src/FeaturesPlugin/icons/SVG/rotation_axis_32x32.svg [new file with mode: 0644]
src/FeaturesPlugin/icons/rotation_3pt_32x32.png [new file with mode: 0644]
src/FeaturesPlugin/icons/rotation_axis_32x32.png [new file with mode: 0644]
src/FeaturesPlugin/rotation_widget.xml
src/GeomAPI/GeomAPI_Trsf.cpp
src/GeomAPI/GeomAPI_Trsf.h
src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp
src/GeomAlgoAPI/GeomAlgoAPI_Rotation.h
src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.h

index 366a751b4da62eae4bee3729be6729c1140d77a2..ef0c55fdbd7608e0c72fb092d14e28bd57813eb2 100644 (file)
@@ -30,6 +30,20 @@ FeaturesAPI_Rotation::FeaturesAPI_Rotation(const std::shared_ptr<ModelAPI_Featur
   }
 }
 
+//==================================================================================================
+FeaturesAPI_Rotation::FeaturesAPI_Rotation(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                           const std::list<ModelHighAPI_Selection>& theMainObjects,
+                                           const ModelHighAPI_Selection& theCenterPoint,
+                                           const ModelHighAPI_Selection& theStartPoint,
+                                           const ModelHighAPI_Selection& theEndPoint)
+: ModelHighAPI_Interface(theFeature)
+{
+  if(initialize()) {
+    fillAttribute(theMainObjects, mymainObjects);
+    setPoints(theCenterPoint, theStartPoint, theEndPoint);
+  }
+}
+
 //==================================================================================================
 FeaturesAPI_Rotation::~FeaturesAPI_Rotation()
 {
@@ -47,6 +61,7 @@ void FeaturesAPI_Rotation::setMainObjects(const std::list<ModelHighAPI_Selection
 //==================================================================================================
 void FeaturesAPI_Rotation::setAxisObject(const ModelHighAPI_Selection& theAxisObject)
 {
+  fillAttribute(FeaturesPlugin_Rotation::CREATION_METHOD_BY_ANGLE(), mycreationMethod);
   fillAttribute(theAxisObject, myaxisObject);
 
   execute();
@@ -55,11 +70,25 @@ void FeaturesAPI_Rotation::setAxisObject(const ModelHighAPI_Selection& theAxisOb
 //==================================================================================================
 void FeaturesAPI_Rotation::setAngle(const ModelHighAPI_Double& theAngle)
 {
+  fillAttribute(FeaturesPlugin_Rotation::CREATION_METHOD_BY_ANGLE(), mycreationMethod);
   fillAttribute(theAngle, myangle);
 
   execute();
 }
 
+//==================================================================================================
+void FeaturesAPI_Rotation::setPoints(const ModelHighAPI_Selection& theCenterPoint,
+                                     const ModelHighAPI_Selection& theStartPoint,
+                                     const ModelHighAPI_Selection& theEndPoint)
+{
+  fillAttribute(FeaturesPlugin_Rotation::CREATION_METHOD_BY_THREE_POINTS(), mycreationMethod);
+  fillAttribute(theCenterPoint, centerPoint());
+  fillAttribute(theStartPoint, startPoint());
+  fillAttribute(theEndPoint, endPoint());
+
+  execute();
+}
+
 //==================================================================================================
 void FeaturesAPI_Rotation::dump(ModelHighAPI_Dumper& theDumper) const
 {
@@ -68,11 +97,27 @@ void FeaturesAPI_Rotation::dump(ModelHighAPI_Dumper& theDumper) const
 
   AttributeSelectionListPtr anAttrObjects =
     aBase->selectionList(FeaturesPlugin_Rotation::OBJECTS_LIST_ID());
-  AttributeSelectionPtr anAttrAxis = aBase->selection(FeaturesPlugin_Rotation::AXIS_OBJECT_ID());
-  AttributeDoublePtr anAttrAngle = aBase->real(FeaturesPlugin_Rotation::ANGLE_ID());
 
-  theDumper << aBase << " = model.addRotation(" << aDocName << ", "
-            << anAttrObjects << ", " << anAttrAxis << ", " << anAttrAngle << ")" << std::endl;
+  theDumper << aBase << " = model.addRotation(" << aDocName << ", " << anAttrObjects;
+
+  std::string aCreationMethod =
+    aBase->string(FeaturesPlugin_Rotation::CREATION_METHOD())->value();
+
+  if (aCreationMethod == FeaturesPlugin_Rotation::CREATION_METHOD_BY_ANGLE()) {
+    AttributeSelectionPtr anAttrAxis = aBase->selection(FeaturesPlugin_Rotation::AXIS_OBJECT_ID());
+    AttributeDoublePtr anAttrAngle = aBase->real(FeaturesPlugin_Rotation::ANGLE_ID());
+    theDumper << ", " << anAttrAxis << ", " << anAttrAngle;
+  } else if (aCreationMethod == FeaturesPlugin_Rotation::CREATION_METHOD_BY_THREE_POINTS()) {
+    AttributeSelectionPtr anAttrCenterPoint =
+      aBase->selection(FeaturesPlugin_Rotation::CENTER_POINT_ID());
+    AttributeSelectionPtr anAttrStartPoint =
+      aBase->selection(FeaturesPlugin_Rotation::START_POINT_ID());
+    AttributeSelectionPtr anAttrEndPoint =
+      aBase->selection(FeaturesPlugin_Rotation::END_POINT_ID());
+    theDumper << ", " << anAttrCenterPoint << ", " << anAttrStartPoint << ", " << anAttrEndPoint;
+  }
+
+  theDumper << ")" << std::endl;
 }
 
 //==================================================================================================
@@ -84,3 +129,15 @@ RotationPtr addRotation(const std::shared_ptr<ModelAPI_Document>& thePart,
   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(FeaturesAPI_Rotation::ID());
   return RotationPtr(new FeaturesAPI_Rotation(aFeature, theMainObjects, theAxisObject, theAngle));
 }
+
+//==================================================================================================
+RotationPtr addRotation(const std::shared_ptr<ModelAPI_Document>& thePart,
+                        const std::list<ModelHighAPI_Selection>& theMainObjects,
+                        const ModelHighAPI_Selection& theCenterPoint,
+                        const ModelHighAPI_Selection& theStartPoint,
+                        const ModelHighAPI_Selection& theEndPoint)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(FeaturesAPI_Rotation::ID());
+  return RotationPtr(new FeaturesAPI_Rotation(aFeature, theMainObjects, theCenterPoint,
+                                              theStartPoint, theEndPoint));
+}
index 243af921b2b4ee6b7139c18a20d6b5f6ff0f1f1d..c123f02e9fd9c24ac8825be666b7536a952d8ddc 100644 (file)
@@ -35,17 +35,34 @@ public:
                        const ModelHighAPI_Selection& theAxisObject,
                        const ModelHighAPI_Double& theAngle);
 
+  /// Constructor with values.
+  FEATURESAPI_EXPORT
+  FeaturesAPI_Rotation(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                       const std::list<ModelHighAPI_Selection>& theMainObjects,
+                       const ModelHighAPI_Selection& theCenterPoint,
+                       const ModelHighAPI_Selection& theStartPoint,
+                       const ModelHighAPI_Selection& theEndPoint);
+
   /// Destructor.
   FEATURESAPI_EXPORT
   virtual ~FeaturesAPI_Rotation();
 
-  INTERFACE_3(FeaturesPlugin_Rotation::ID(),
+  INTERFACE_7(FeaturesPlugin_Rotation::ID(),
+              creationMethod, FeaturesPlugin_Rotation::CREATION_METHOD(),
+              ModelAPI_AttributeString, /** Creation method */,
               mainObjects, FeaturesPlugin_Rotation::OBJECTS_LIST_ID(),
               ModelAPI_AttributeSelectionList, /** Main objects */,
               axisObject, FeaturesPlugin_Rotation::AXIS_OBJECT_ID(),
               ModelAPI_AttributeSelection, /** Axis object */,
               angle, FeaturesPlugin_Rotation::ANGLE_ID(),
-              ModelAPI_AttributeDouble, /** Angle */)
+              ModelAPI_AttributeDouble, /** Angle */,
+              centerPoint, FeaturesPlugin_Rotation::CENTER_POINT_ID(),
+              ModelAPI_AttributeSelection, /** Center point */,
+              startPoint, FeaturesPlugin_Rotation::START_POINT_ID(),
+              ModelAPI_AttributeSelection, /** Start point */,
+              endPoint, FeaturesPlugin_Rotation::END_POINT_ID(),
+              ModelAPI_AttributeSelection, /** End point */
+             )
 
   /// Set main objects.
   FEATURESAPI_EXPORT
@@ -59,6 +76,11 @@ public:
   FEATURESAPI_EXPORT
   void setAngle(const ModelHighAPI_Double& theAngle);
 
+  /// Set center point, start point and end point
+  void setPoints(const ModelHighAPI_Selection& theCenterPoint,
+                 const ModelHighAPI_Selection& theStartPoint,
+                 const ModelHighAPI_Selection& theEndPoint);
+
   /// Dump wrapped feature
   FEATURESAPI_EXPORT
   virtual void dump(ModelHighAPI_Dumper& theDumper) const;
@@ -75,4 +97,13 @@ RotationPtr addRotation(const std::shared_ptr<ModelAPI_Document>& thePart,
                         const ModelHighAPI_Selection& theAxisObject,
                         const ModelHighAPI_Double& theAngle);
 
+/// \ingroup CPPHighAPI
+/// \brief Create Rotation feature.
+FEATURESAPI_EXPORT
+RotationPtr addRotation(const std::shared_ptr<ModelAPI_Document>& thePart,
+                        const std::list<ModelHighAPI_Selection>& theMainObjects,
+                        const ModelHighAPI_Selection& theCenterPoint,
+                        const ModelHighAPI_Selection& theStartPoint,
+                        const ModelHighAPI_Selection& theEndPoint);
+
 #endif // FeaturesAPI_Rotation_H_
index 16028546cda773f9cc404da96c96521d5085fc47..41e0468bee760c58dfddb50d989a01d5db5d995c 100755 (executable)
@@ -8,9 +8,12 @@
 
 #include <ModelAPI_AttributeDouble.h>
 #include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_ResultPart.h>
 
+#include <GeomAlgoAPI_PointBuilder.h>
+
 #include <GeomAPI_Edge.h>
 #include <GeomAPI_Lin.h>
 
@@ -24,6 +27,9 @@ FeaturesPlugin_Rotation::FeaturesPlugin_Rotation()
 //=================================================================================================
 void FeaturesPlugin_Rotation::initAttributes()
 {
+  data()->addAttribute(FeaturesPlugin_Rotation::CREATION_METHOD(),
+                       ModelAPI_AttributeString::typeId());
+
   AttributeSelectionListPtr aSelection =
     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
     FeaturesPlugin_Rotation::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
@@ -31,10 +37,32 @@ void FeaturesPlugin_Rotation::initAttributes()
   data()->addAttribute(FeaturesPlugin_Rotation::AXIS_OBJECT_ID(),
                        ModelAPI_AttributeSelection::typeId());
   data()->addAttribute(FeaturesPlugin_Rotation::ANGLE_ID(), ModelAPI_AttributeDouble::typeId());
+
+  data()->addAttribute(FeaturesPlugin_Rotation::CENTER_POINT_ID(),
+                       ModelAPI_AttributeSelection::typeId());
+  data()->addAttribute(FeaturesPlugin_Rotation::START_POINT_ID(),
+                       ModelAPI_AttributeSelection::typeId());
+  data()->addAttribute(FeaturesPlugin_Rotation::END_POINT_ID(),
+                       ModelAPI_AttributeSelection::typeId());
 }
 
 //=================================================================================================
 void FeaturesPlugin_Rotation::execute()
+{
+  AttributeStringPtr aMethodTypeAttr = string(FeaturesPlugin_Rotation::CREATION_METHOD());
+  std::string aMethodType = aMethodTypeAttr->value();
+
+  if (aMethodType == CREATION_METHOD_BY_ANGLE()) {
+    performTranslationByAxisAndAngle();
+  }
+
+  if (aMethodType == CREATION_METHOD_BY_THREE_POINTS()) {
+    performTranslationByThreePoints();
+  }
+}
+
+//=================================================================================================
+void FeaturesPlugin_Rotation::performTranslationByAxisAndAngle()
 {
   // Getting objects.
   ListOfShape anObjects;
@@ -93,6 +121,13 @@ void FeaturesPlugin_Rotation::execute()
     } else {
       GeomAlgoAPI_Rotation aRotationAlgo(aBaseShape, anAxis, anAngle);
 
+      if (!aRotationAlgo.check()) {
+        setError(aRotationAlgo.getError());
+        return;
+      }
+
+      aRotationAlgo.build();
+
       // Checking that the algorithm worked properly.
       if(!aRotationAlgo.isDone()) {
         static const std::string aFeatureError = "Error: Rotation algorithm failed.";
@@ -121,6 +156,108 @@ void FeaturesPlugin_Rotation::execute()
   removeResults(aResultIndex);
 }
 
+//=================================================================================================
+void FeaturesPlugin_Rotation::performTranslationByThreePoints()
+{
+  // Getting objects.
+  ListOfShape anObjects;
+  std::list<ResultPtr> aContextes;
+  AttributeSelectionListPtr anObjectsSelList =
+    selectionList(FeaturesPlugin_Rotation::OBJECTS_LIST_ID());
+  if (anObjectsSelList->size() == 0) {
+    return;
+  }
+  for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
+    std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
+      anObjectsSelList->value(anObjectsIndex);
+    std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
+    if(!anObject.get()) {
+      return;
+    }
+    anObjects.push_back(anObject);
+    aContextes.push_back(anObjectAttr->context());
+  }
+
+  // Getting the center point and two points (start and end)
+  std::shared_ptr<GeomAPI_Pnt> aCenterPoint;
+  std::shared_ptr<GeomAPI_Pnt> aStartPoint;
+  std::shared_ptr<GeomAPI_Pnt> anEndPoint;
+  std::shared_ptr<ModelAPI_AttributeSelection> aCenterRef =
+    selection(FeaturesPlugin_Rotation::CENTER_POINT_ID());
+  std::shared_ptr<ModelAPI_AttributeSelection> aStartPointRef =
+    selection(FeaturesPlugin_Rotation::START_POINT_ID());
+  std::shared_ptr<ModelAPI_AttributeSelection> anEndPointRef =
+    selection(FeaturesPlugin_Rotation::END_POINT_ID());
+  if ((aCenterRef.get() != NULL) && (aStartPointRef.get() != NULL)
+      && (anEndPointRef.get() != NULL)) {
+    GeomShapePtr aCenterShape = aCenterRef->value();
+    if (!aCenterShape.get())
+      aCenterShape = aCenterRef->context()->shape();
+    GeomShapePtr aStartShape = aStartPointRef->value();
+    if (!aStartShape.get())
+      aStartShape = aStartPointRef->context()->shape();
+      GeomShapePtr anEndShape = anEndPointRef->value();
+    if (!anEndShape.get())
+      anEndShape = anEndPointRef->context()->shape();
+    if (aStartShape && anEndShape && aCenterShape) {
+      aCenterPoint = GeomAlgoAPI_PointBuilder::point(aCenterShape);
+      aStartPoint = GeomAlgoAPI_PointBuilder::point(aStartShape);
+      anEndPoint = GeomAlgoAPI_PointBuilder::point(anEndShape);
+    }
+  }
+
+  // Rotating each object.
+  int aResultIndex = 0;
+  std::list<ResultPtr>::iterator aContext = aContextes.begin();
+  for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
+        anObjectsIt++, aContext++) {
+    std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
+    bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
+
+    // Setting result.
+    if (isPart) {
+       std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
+       aTrsf->setRotation(aCenterPoint, aStartPoint, anEndPoint);
+       ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
+       ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
+       aResultPart->setTrsf(*aContext, aTrsf);
+       setResult(aResultPart, aResultIndex);
+    } else {
+      GeomAlgoAPI_Rotation aRotationAlgo(aBaseShape, aCenterPoint, aStartPoint, anEndPoint);
+
+      if (!aRotationAlgo.check()) {
+        setError(aRotationAlgo.getError());
+        return;
+      }
+
+      aRotationAlgo.build();
+
+      // Checking that the algorithm worked properly.
+      if(!aRotationAlgo.isDone()) {
+        static const std::string aFeatureError = "Error: Rotation algorithm failed.";
+        setError(aFeatureError);
+        break;
+      }
+      if(aRotationAlgo.shape()->isNull()) {
+        static const std::string aShapeError = "Error : Resulting shape is Null.";
+        setError(aShapeError);
+        break;
+      }
+      if(!aRotationAlgo.isValid()) {
+        std::string aFeatureError = "Error: Resulting shape is not valid.";
+        setError(aFeatureError);
+        break;
+      }
+
+      ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+      loadNamingDS(aRotationAlgo, aResultBody, aBaseShape);
+      setResult(aResultBody, aResultIndex);
+    }
+    aResultIndex++;
+  }
+}
+
+//=================================================================================================
 void FeaturesPlugin_Rotation::loadNamingDS(GeomAlgoAPI_Rotation& theRotaionAlgo,
                                            std::shared_ptr<ModelAPI_ResultBody> theResultBody,
                                            std::shared_ptr<GeomAPI_Shape> theBaseShape)
index 1326e7ac55f90488149e5328a2f5f770021d6fc3..6eeea6a18a6bfe88a6aa24f0acc524ab0c33ff06 100755 (executable)
@@ -26,6 +26,27 @@ class FeaturesPlugin_Rotation : public ModelAPI_Feature
     return MY_ROTATION_ID;
   }
 
+  /// Attribute name for creation method.
+  inline static const std::string& CREATION_METHOD()
+  {
+    static const std::string MY_CREATION_METHOD_ID("CreationMethod");
+    return MY_CREATION_METHOD_ID;
+  }
+
+  /// Attribute name for creation method "ByAxisAndAngle".
+  inline static const std::string& CREATION_METHOD_BY_ANGLE()
+  {
+    static const std::string MY_CREATION_METHOD_ID("ByAxisAndAngle");
+    return MY_CREATION_METHOD_ID;
+  }
+
+  /// Attribute name for creation method "ByThreePoints".
+  inline static const std::string& CREATION_METHOD_BY_THREE_POINTS()
+  {
+    static const std::string MY_CREATION_METHOD_ID("ByThreePoints");
+    return MY_CREATION_METHOD_ID;
+  }
+
   /// Attribute name of referenced objects.
   inline static const std::string& OBJECTS_LIST_ID()
   {
@@ -47,6 +68,27 @@ class FeaturesPlugin_Rotation : public ModelAPI_Feature
     return MY_ANGLE_ID;
   }
 
+  /// Attribute name of a center point.
+  inline static const std::string& CENTER_POINT_ID()
+  {
+    static const std::string MY_CENTER_POINT_ID("center_point");
+    return MY_CENTER_POINT_ID;
+  }
+
+  /// Attribute name of a center point.
+  inline static const std::string& START_POINT_ID()
+  {
+    static const std::string MY_START_POINT_ID("start_point");
+    return MY_START_POINT_ID;
+  }
+
+  /// Attribute name of a center point.
+  inline static const std::string& END_POINT_ID()
+  {
+    static const std::string MY_END_POINT_ID("end_point");
+    return MY_END_POINT_ID;
+  }
+
   /// \return the kind of a feature.
   FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
   {
@@ -64,6 +106,12 @@ class FeaturesPlugin_Rotation : public ModelAPI_Feature
   FeaturesPlugin_Rotation();
 
 private:
+  ///Perform the rotation using an axis and an angle.
+  void performTranslationByAxisAndAngle();
+
+  ///Perform the rotation using a center and two points.
+  void performTranslationByThreePoints();
+
   void loadNamingDS(GeomAlgoAPI_Rotation& theRotaionAlgo,
                     std::shared_ptr<ModelAPI_ResultBody> theResultBody,
                     std::shared_ptr<GeomAPI_Shape> theBaseShape);
diff --git a/src/FeaturesPlugin/icons/SVG/rotation_3pt_32x32.svg b/src/FeaturesPlugin/icons/SVG/rotation_3pt_32x32.svg
new file mode 100644 (file)
index 0000000..d6fb9de
--- /dev/null
@@ -0,0 +1,411 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="32"
+   height="32"
+   id="svg11250"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   viewBox="0 0 32 32"
+   sodipodi:docname="rotation_3pt_32x32.svg"
+   inkscape:export-filename="/export/home/ldigallo/DOC_ALYOTECH/icones/Transformations/rotation_3pt_32x32.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90">
+  <defs
+     id="defs11252">
+    <marker
+       inkscape:isstock="true"
+       style="overflow:visible"
+       id="marker21544"
+       refX="0.0"
+       refY="0.0"
+       orient="auto"
+       inkscape:stockid="TriangleOutS">
+      <path
+         transform="scale(0.2)"
+         style="fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt;stroke-opacity:1;fill:#ff0000;fill-opacity:1"
+         d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
+         id="path21546" />
+    </marker>
+    <marker
+       inkscape:stockid="TriangleOutS"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="TriangleOutS"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path5715"
+         d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
+         style="fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt;stroke-opacity:1;fill:#ff0000;fill-opacity:1"
+         transform="scale(0.2)" />
+    </marker>
+    <inkscape:path-effect
+       effect="spiro"
+       id="path-effect13212"
+       is_visible="true" />
+    <marker
+       inkscape:stockid="EmptyTriangleOutS"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="EmptyTriangleOutS"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path5733"
+         d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
+         style="fill-rule:evenodd;fill:#ffffff;stroke:#ff0000;stroke-width:1pt;stroke-opacity:1"
+         transform="scale(0.2) translate(-3.0,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="TriangleOutM"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="TriangleOutM"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path5712"
+         d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
+         style="fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt;stroke-opacity:1;fill:#ff0000;fill-opacity:1"
+         transform="scale(0.4)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Send"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Send"
+       style="overflow:visible;"
+       inkscape:isstock="true">
+      <path
+         id="path5582"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt;stroke-opacity:1;fill:#ff0000;fill-opacity:1"
+         transform="scale(0.2) rotate(180) translate(6,0)" />
+    </marker>
+    <inkscape:path-effect
+       effect="spiro"
+       id="path-effect12156"
+       is_visible="true" />
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 16 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="32 : 16 : 1"
+       inkscape:persp3d-origin="16 : 10.666667 : 1"
+       id="perspective12136" />
+    <inkscape:path-effect
+       effect="spiro"
+       id="path-effect12134"
+       is_visible="true" />
+    <inkscape:path-effect
+       effect="skeletal"
+       id="path-effect12130"
+       is_visible="true"
+       pattern="M 0,5 C 0,2.24 2.24,0 5,0 7.76,0 10,2.24 10,5 10,7.76 7.76,10 5,10 2.24,10 0,7.76 0,5 Z"
+       copytype="single_stretched"
+       prop_scale="1"
+       scale_y_rel="false"
+       spacing="0"
+       normal_offset="0"
+       tang_offset="0"
+       prop_units="false"
+       vertical_pattern="false"
+       fuse_tolerance="0" />
+    <inkscape:path-effect
+       effect="spiro"
+       id="path-effect12128"
+       is_visible="true" />
+    <inkscape:path-effect
+       effect="skeletal"
+       id="path-effect12124"
+       is_visible="true"
+       pattern="M 0,5 C 0,2.24 2.24,0 5,0 7.76,0 10,2.24 10,5 10,7.76 7.76,10 5,10 2.24,10 0,7.76 0,5 Z"
+       copytype="single_stretched"
+       prop_scale="1"
+       scale_y_rel="false"
+       spacing="0"
+       normal_offset="0"
+       tang_offset="0"
+       prop_units="false"
+       vertical_pattern="false"
+       fuse_tolerance="0" />
+    <inkscape:path-effect
+       effect="spiro"
+       id="path-effect12122"
+       is_visible="true" />
+    <inkscape:path-effect
+       effect="skeletal"
+       id="path-effect12118"
+       is_visible="true"
+       pattern="m -0.04465162,5 c 0,-2.76 2.24000002,-5 5.00000002,-5 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 -2.76,0 -5.00000002,-2.24 -5.00000002,-5 z"
+       copytype="single_stretched"
+       prop_scale="1"
+       scale_y_rel="false"
+       spacing="0"
+       normal_offset="0"
+       tang_offset="0"
+       prop_units="false"
+       vertical_pattern="false"
+       fuse_tolerance="0" />
+    <marker
+       inkscape:stockid="TriangleOutS"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker18553-4"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path18555-7"
+         d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt;stroke-opacity:1"
+         transform="scale(0.2,0.2)" />
+    </marker>
+    <marker
+       inkscape:stockid="TriangleOutS"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker18553-3"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path18555-3"
+         d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt;stroke-opacity:1"
+         transform="scale(0.2,0.2)" />
+    </marker>
+    <marker
+       inkscape:stockid="TriangleOutS"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker18553-5"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path18555-73"
+         d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt;stroke-opacity:1"
+         transform="scale(0.2,0.2)" />
+    </marker>
+    <inkscape:path-effect
+       effect="spiro"
+       id="path-effect4359"
+       is_visible="true" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="15.836083"
+     inkscape:cx="1.3603736"
+     inkscape:cy="17.299667"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:grid-bbox="true"
+     inkscape:document-units="px"
+     inkscape:window-width="1920"
+     inkscape:window-height="1006"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:window-maximized="1"
+     inkscape:snap-center="true"
+     inkscape:snap-object-midpoints="true"
+     inkscape:snap-others="false"
+     inkscape:snap-nodes="false"
+     inkscape:snap-grids="true"
+     inkscape:object-paths="true"
+     inkscape:snap-intersection-paths="true">
+    <inkscape:grid
+       type="xygrid"
+       id="grid11798" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata11255">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     id="layer1"
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer">
+    <g
+       transform="matrix(1.6666667,0,0,1.6666667,13.163818,-1.3994682)"
+       id="g4195">
+      <path
+         inkscape:connector-curvature="0"
+         id="path7134"
+         d="m 0.5,14.5 3,-3"
+         style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+      <path
+         inkscape:connector-curvature="0"
+         id="path7134-3"
+         d="m 0.5,11.5 3,3"
+         style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    </g>
+    <g
+       transform="matrix(1.6666667,0,0,1.6666667,-0.33100563,-6.3787664)"
+       id="g4195-72">
+      <path
+         inkscape:connector-curvature="0"
+         id="path7134-1"
+         d="m 0.5,14.5 3,-3"
+         style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+      <path
+         inkscape:connector-curvature="0"
+         id="path7134-3-9"
+         d="m 0.5,11.5 3,3"
+         style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    </g>
+    <g
+       transform="matrix(1.6666667,0,0,1.6666667,-0.0980781,7.2299176)"
+       id="g4195-0">
+      <path
+         inkscape:connector-curvature="0"
+         id="path7134-7"
+         d="m 0.5,14.5 3,-3"
+         style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+      <path
+         inkscape:connector-curvature="0"
+         id="path7134-3-4"
+         d="m 0.5,11.5 3,3"
+         style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    </g>
+    <g
+       transform="matrix(1.3333333,0,0,1.3333333,0.36857465,-9.2029161)"
+       id="g4929-6">
+      <path
+         sodipodi:nodetypes="ccccccc"
+         style="fill:#b7d9ea;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m -0.04504951,16.04505 0,-8.0000005 4.00000001,0 0,4.0000005 4,0 0,4 z"
+         id="path4836-7"
+         inkscape:connector-curvature="0" />
+      <path
+         sodipodi:nodetypes="ccccccccccc"
+         style="fill:#1b4955;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 0.95495049,7.0450495 -1,1 4.00000001,0 0,4.0000005 4,0 0,4 1,-1 0,-4 -4,0 0,-4.0000005 z"
+         id="path4838-5"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       transform="matrix(0.76476856,1.0922027,-1.0922027,0.76476856,35.699435,2.305)"
+       id="g4929-6-4">
+      <path
+         sodipodi:nodetypes="ccccccc"
+         style="fill:#b7d9ea;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m -0.04504951,16.04505 0,-8.0000005 4.00000001,0 0,4.0000005 4,0 0,4 z"
+         id="path4836-7-5"
+         inkscape:connector-curvature="0" />
+      <path
+         sodipodi:nodetypes="ccccccccccc"
+         style="fill:#1b4955;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 0.95495049,7.0450495 -1,1 4.00000001,0 0,4.0000005 4,0 0,4 1,-1 0,-4 -4,0 0,-4.0000005 z"
+         id="path4838-5-2"
+         inkscape:connector-curvature="0" />
+    </g>
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:3,1.5;stroke-dashoffset:3.6"
+       d="m 2.9679056,17.286766 0.063147,9.156304"
+       id="path4376"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 1.5;stroke-dashoffset:3.5999999;stroke-opacity:1"
+       d="m 13.742966,21.697607 -7.4641843,5.30357"
+       id="path4376-7"
+       inkscape:connector-curvature="0" />
+    <g
+       id="g4393"
+       transform="translate(33.504004,1.4376008)">
+      <g
+         id="g4401"
+         transform="translate(0.06314693,0.4420285)">
+        <path
+           sodipodi:type="star"
+           style="opacity:1;fill:#fecc02;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="path4301"
+           sodipodi:sides="3"
+           sodipodi:cx="-0.0020759429"
+           sodipodi:cy="-15.710785"
+           sodipodi:r1="3.4919641"
+           sodipodi:r2="1.7459821"
+           sodipodi:arg1="0.43995835"
+           sodipodi:arg2="1.4871559"
+           inkscape:flatsided="true"
+           inkscape:rounded="0"
+           inkscape:randomized="0"
+           d="m 3.1573463,-14.223551 -6.0271156,0.505289 2.57596441,-5.47228 z"
+           inkscape:transform-center-x="0.71004521"
+           inkscape:transform-center-y="0.18262461"
+           transform="matrix(0.7570385,0.65337029,-0.65337029,0.7570385,-22.693604,17.089749)" />
+        <path
+           style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="path4337"
+           sodipodi:type="arc"
+           sodipodi:cx="-20.008839"
+           sodipodi:cy="8.7009048"
+           sodipodi:rx="9.7877741"
+           sodipodi:ry="9.7877741"
+           sodipodi:start="4.712389"
+           sodipodi:end="5.6723201"
+           d="m -20.008838,-1.0868692 a 9.7877741,9.7877741 0 0 1 8.017675,4.1737377"
+           sodipodi:open="true" />
+        <path
+           style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="path4339"
+           sodipodi:type="arc"
+           sodipodi:cx="-21.246632"
+           sodipodi:cy="8.9839478"
+           sodipodi:rx="8.4932623"
+           sodipodi:ry="8.4932623"
+           sodipodi:start="4.712389"
+           sodipodi:end="5.6723201"
+           d="m -21.246631,0.49068546 a 8.4932623,8.4932623 0 0 1 6.957273,3.62172744"
+           sodipodi:open="true" />
+        <path
+           style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+           d="m -14.289358,4.1124129 2.298195,-1.0255444"
+           id="path4355"
+           inkscape:connector-curvature="0" />
+        <path
+           style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+           d="M -21.246631,0.49068546 -20.003904,-1.086868"
+           id="path4357"
+           inkscape:path-effect="#path-effect4359"
+           inkscape:original-d="M -21.246631,0.49068546 -20.003904,-1.086868"
+           inkscape:connector-curvature="0" />
+        <path
+           style="opacity:1;fill:#fecc02;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           d="m -14.318618,3.6344572 c -0.177437,-0.2416573 -0.57376,-0.6807689 -0.876609,-0.9712503 -1.410253,-1.3526642 -3.17999,-2.169572 -5.170145,-2.38653106 l -0.349421,-0.0380926 0.416399,-0.53233536 0.416398,-0.53233536 0.323725,0.0134903 c 1.698384,0.0707754 3.399911,0.63266941 4.851373,1.60206591 0.808999,0.54031107 1.570576,1.24433567 2.17848,2.01385227 l 0.138938,0.1758759 -0.894206,0.3990138 c -0.491814,0.2194573 -0.902284,0.3990135 -0.912156,0.3990135 -0.0099,0 -0.06512,-0.064245 -0.122776,-0.142767 z"
+           id="path4391"
+           inkscape:connector-curvature="0" />
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/src/FeaturesPlugin/icons/SVG/rotation_axis_32x32.svg b/src/FeaturesPlugin/icons/SVG/rotation_axis_32x32.svg
new file mode 100644 (file)
index 0000000..20e8b8b
--- /dev/null
@@ -0,0 +1,349 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="32"
+   height="32"
+   id="svg11250"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   viewBox="0 0 32 32"
+   sodipodi:docname="rotation_axis_32x32.svg"
+   inkscape:export-filename="/export/home/ldigallo/DOC_ALYOTECH/icones/Transformations/rotation_axis_32x32.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90">
+  <defs
+     id="defs11252">
+    <inkscape:path-effect
+       effect="spiro"
+       id="path-effect4359"
+       is_visible="true" />
+    <marker
+       inkscape:stockid="TriangleOutS"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="TriangleOutS"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path5715"
+         d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt"
+         transform="scale(0.2)" />
+    </marker>
+    <marker
+       inkscape:isstock="true"
+       style="overflow:visible"
+       id="marker17270"
+       refX="0.0"
+       refY="0.0"
+       orient="auto"
+       inkscape:stockid="TriangleOutS">
+      <path
+         transform="scale(0.2)"
+         style="fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt;stroke-opacity:1;fill:#ff0000;fill-opacity:1"
+         d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
+         id="path17272" />
+    </marker>
+    <inkscape:path-effect
+       effect="spiro"
+       id="path-effect13212"
+       is_visible="true" />
+    <marker
+       inkscape:stockid="EmptyTriangleOutS"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="EmptyTriangleOutS"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path5733"
+         d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
+         style="fill-rule:evenodd;fill:#ffffff;stroke:#ff0000;stroke-width:1pt;stroke-opacity:1"
+         transform="scale(0.2) translate(-3.0,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="TriangleOutM"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="TriangleOutM"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path5712"
+         d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
+         style="fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt;stroke-opacity:1;fill:#ff0000;fill-opacity:1"
+         transform="scale(0.4)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Send"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Send"
+       style="overflow:visible;"
+       inkscape:isstock="true">
+      <path
+         id="path5582"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt;stroke-opacity:1;fill:#ff0000;fill-opacity:1"
+         transform="scale(0.2) rotate(180) translate(6,0)" />
+    </marker>
+    <inkscape:path-effect
+       effect="spiro"
+       id="path-effect12156"
+       is_visible="true" />
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 16 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="32 : 16 : 1"
+       inkscape:persp3d-origin="16 : 10.666667 : 1"
+       id="perspective12136" />
+    <inkscape:path-effect
+       effect="spiro"
+       id="path-effect12134"
+       is_visible="true" />
+    <inkscape:path-effect
+       effect="skeletal"
+       id="path-effect12130"
+       is_visible="true"
+       pattern="M 0,5 C 0,2.24 2.24,0 5,0 7.76,0 10,2.24 10,5 10,7.76 7.76,10 5,10 2.24,10 0,7.76 0,5 Z"
+       copytype="single_stretched"
+       prop_scale="1"
+       scale_y_rel="false"
+       spacing="0"
+       normal_offset="0"
+       tang_offset="0"
+       prop_units="false"
+       vertical_pattern="false"
+       fuse_tolerance="0" />
+    <inkscape:path-effect
+       effect="spiro"
+       id="path-effect12128"
+       is_visible="true" />
+    <inkscape:path-effect
+       effect="skeletal"
+       id="path-effect12124"
+       is_visible="true"
+       pattern="M 0,5 C 0,2.24 2.24,0 5,0 7.76,0 10,2.24 10,5 10,7.76 7.76,10 5,10 2.24,10 0,7.76 0,5 Z"
+       copytype="single_stretched"
+       prop_scale="1"
+       scale_y_rel="false"
+       spacing="0"
+       normal_offset="0"
+       tang_offset="0"
+       prop_units="false"
+       vertical_pattern="false"
+       fuse_tolerance="0" />
+    <inkscape:path-effect
+       effect="spiro"
+       id="path-effect12122"
+       is_visible="true" />
+    <inkscape:path-effect
+       effect="skeletal"
+       id="path-effect12118"
+       is_visible="true"
+       pattern="m -0.04465162,5 c 0,-2.76 2.24000002,-5 5.00000002,-5 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 -2.76,0 -5.00000002,-2.24 -5.00000002,-5 z"
+       copytype="single_stretched"
+       prop_scale="1"
+       scale_y_rel="false"
+       spacing="0"
+       normal_offset="0"
+       tang_offset="0"
+       prop_units="false"
+       vertical_pattern="false"
+       fuse_tolerance="0" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="15.836083"
+     inkscape:cx="0.30977264"
+     inkscape:cy="19.889099"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:grid-bbox="true"
+     inkscape:document-units="px"
+     inkscape:window-width="1920"
+     inkscape:window-height="1006"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:window-maximized="1"
+     inkscape:snap-center="false"
+     inkscape:snap-object-midpoints="true"
+     inkscape:snap-others="false"
+     inkscape:snap-nodes="true"
+     inkscape:snap-global="false"
+     inkscape:snap-bbox="true"
+     inkscape:object-paths="false"
+     inkscape:snap-grids="false"
+     showguides="false"
+     inkscape:object-nodes="false"
+     inkscape:snap-smooth-nodes="false"
+     inkscape:snap-intersection-paths="false"
+     inkscape:snap-midpoints="true"
+     inkscape:bbox-nodes="true"
+     inkscape:snap-bbox-midpoints="true"
+     inkscape:bbox-paths="true"
+     inkscape:snap-bbox-edge-midpoints="true">
+    <inkscape:grid
+       type="xygrid"
+       id="grid11798" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata11255">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     id="layer1"
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer">
+    <g
+       transform="matrix(0.65352553,1.1319394,-1.1319394,0.65352553,31.527765,-6.5089423)"
+       id="g4158-7">
+      <g
+         id="g4155-8" />
+    </g>
+    <g
+       transform="matrix(1.307051,0,0,1.307051,4.711877,-9.1430832)"
+       id="g4158">
+      <g
+         id="g4155" />
+    </g>
+    <g
+       id="g4178"
+       transform="translate(-9.7898571,3.378881)">
+      <path
+         sodipodi:nodetypes="ccccccc"
+         style="fill:#b7d9ea;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 19.017599,28.449619 0,-24.8888888 4.964802,-0.060729 0,12.9999998 5,0 0,11.999999 z"
+         id="path4836"
+         inkscape:connector-curvature="0" />
+      <path
+         sodipodi:nodetypes="ccccccccccc"
+         style="fill:#1b4955;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 20.982401,1.5 -1.964802,2.0607302 4.964802,-0.060729 0,12.9999998 5,0 0,11.999999 2,-1.999999 0,-12 -5,0 0,-12.9999986 z"
+         id="path4838"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       id="g4178-5"
+       transform="matrix(0.57357644,0.81915204,-0.81915204,0.57357644,15.129291,-11.609996)">
+      <path
+         sodipodi:nodetypes="ccccccc"
+         style="fill:#b7d9ea;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 19.017599,28.449619 0,-24.8888888 4.964802,-0.060729 0,12.9999998 5,0 0,11.999999 z"
+         id="path4836-3"
+         inkscape:connector-curvature="0" />
+      <path
+         sodipodi:nodetypes="ccccccccccc"
+         style="fill:#1b4955;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 20.982401,1.5 -1.964802,2.0607302 4.964802,-0.060729 0,12.9999998 5,0 0,11.999999 2,-1.999999 0,-12 -5,0 0,-12.9999986 z"
+         id="path4838-9"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       transform="matrix(1.6666667,0,0,1.6666667,9.8768091,-2.2877861)"
+       id="g4195">
+      <path
+         inkscape:connector-curvature="0"
+         id="path7134"
+         d="m 0.5,14.5 3,-3"
+         style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+      <path
+         inkscape:connector-curvature="0"
+         id="path7134-3"
+         d="m 0.5,11.5 3,3"
+         style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    </g>
+    <g
+       id="g4393"
+       transform="translate(34.48226,1.4790039)">
+      <g
+         id="g4401"
+         transform="translate(0.06314693,0.4420285)">
+        <path
+           sodipodi:type="star"
+           style="opacity:1;fill:#fecc02;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="path4301"
+           sodipodi:sides="3"
+           sodipodi:cx="-0.0020759429"
+           sodipodi:cy="-15.710785"
+           sodipodi:r1="3.4919641"
+           sodipodi:r2="1.7459821"
+           sodipodi:arg1="0.43995835"
+           sodipodi:arg2="1.4871559"
+           inkscape:flatsided="true"
+           inkscape:rounded="0"
+           inkscape:randomized="0"
+           d="m 3.1573463,-14.223551 -6.0271156,0.505289 2.57596441,-5.47228 z"
+           inkscape:transform-center-x="0.71004521"
+           inkscape:transform-center-y="0.18262461"
+           transform="matrix(0.7570385,0.65337029,-0.65337029,0.7570385,-22.693604,17.089749)" />
+        <path
+           style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="path4337"
+           sodipodi:type="arc"
+           sodipodi:cx="-20.008839"
+           sodipodi:cy="8.7009048"
+           sodipodi:rx="9.7877741"
+           sodipodi:ry="9.7877741"
+           sodipodi:start="4.712389"
+           sodipodi:end="5.6723201"
+           d="m -20.008838,-1.0868692 a 9.7877741,9.7877741 0 0 1 8.017675,4.1737377"
+           sodipodi:open="true" />
+        <path
+           style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="path4339"
+           sodipodi:type="arc"
+           sodipodi:cx="-21.246632"
+           sodipodi:cy="8.9839478"
+           sodipodi:rx="8.4932623"
+           sodipodi:ry="8.4932623"
+           sodipodi:start="4.712389"
+           sodipodi:end="5.6723201"
+           d="m -21.246631,0.49068546 a 8.4932623,8.4932623 0 0 1 6.957273,3.62172744"
+           sodipodi:open="true" />
+        <path
+           style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+           d="m -14.289358,4.1124129 2.298195,-1.0255444"
+           id="path4355"
+           inkscape:connector-curvature="0" />
+        <path
+           style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+           d="M -21.246631,0.49068546 -20.003904,-1.086868"
+           id="path4357"
+           inkscape:path-effect="#path-effect4359"
+           inkscape:original-d="M -21.246631,0.49068546 -20.003904,-1.086868"
+           inkscape:connector-curvature="0" />
+        <path
+           style="opacity:1;fill:#fecc02;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           d="m -14.318618,3.6344572 c -0.177437,-0.2416573 -0.57376,-0.6807689 -0.876609,-0.9712503 -1.410253,-1.3526642 -3.17999,-2.169572 -5.170145,-2.38653106 l -0.349421,-0.0380926 0.416399,-0.53233536 0.416398,-0.53233536 0.323725,0.0134903 c 1.698384,0.0707754 3.399911,0.63266941 4.851373,1.60206591 0.808999,0.54031107 1.570576,1.24433567 2.17848,2.01385227 l 0.138938,0.1758759 -0.894206,0.3990138 c -0.491814,0.2194573 -0.902284,0.3990135 -0.912156,0.3990135 -0.0099,0 -0.06512,-0.064245 -0.122776,-0.142767 z"
+           id="path4391"
+           inkscape:connector-curvature="0" />
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/src/FeaturesPlugin/icons/rotation_3pt_32x32.png b/src/FeaturesPlugin/icons/rotation_3pt_32x32.png
new file mode 100644 (file)
index 0000000..e2493da
Binary files /dev/null and b/src/FeaturesPlugin/icons/rotation_3pt_32x32.png differ
diff --git a/src/FeaturesPlugin/icons/rotation_axis_32x32.png b/src/FeaturesPlugin/icons/rotation_axis_32x32.png
new file mode 100644 (file)
index 0000000..cf443b3
Binary files /dev/null and b/src/FeaturesPlugin/icons/rotation_axis_32x32.png differ
index a5eddcf7f0cf1032f2c600e351a3da158dfa09ea..1d94eea3caf68a91ab30ce8a060c1482aaac61c3 100755 (executable)
@@ -1,30 +1,73 @@
 <!-- Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+<!-- Modified by Clarisse Genrault (CEA) : 02 Mar 2017 -->
 
 <source>
-  <multi_selector id="main_objects"
-    label="Main objects"
-    icon="icons/Features/cut_shape.png"
-    tooltip="Select solid objects"
-    type_choice="objects"
-    concealment="true">
-    <validator id="FeaturesPlugin_ValidatorTransform"/>
-  </multi_selector>
-  <shape_selector id="axis_object"
+  <toolbox id="CreationMethod">
+    <box id="ByAxisAndAngle"
+         title="By an axis and an angle"
+         icon="icons/Features/rotation_axis_32x32.png">
+      <multi_selector id="main_objects"
+                      label="Main objects"
+                      icon=""
+                      tooltip="Select solid objects"
+                      type_choice="objects"
+                      concealment="true">
+        <validator id="FeaturesPlugin_ValidatorTransform"/>
+      </multi_selector>
+      <shape_selector id="axis_object"
                   icon="icons/Features/axis.png"
                   label="Axis"
                   tooltip="Select an edge for axis"
                   shape_types="edge"
                   default="">
-    <validator id="GeomValidators_ShapeType" parameters="line"/>
-  </shape_selector>
-  <doublevalue
-    id="angle"
-    label="Angle"
-    min="-360"
-    max="360"
-    step="1.0"
-    default="0"
-    icon="icons/Features/angle.png"
-    tooltip="Angle">
-  </doublevalue>
-</source>
\ No newline at end of file
+        <validator id="GeomValidators_ShapeType" parameters="line"/>
+      </shape_selector>
+      <doublevalue id="angle"
+                   label="Angle"
+                   min="-360"
+                   max="360"
+                   step="1.0"
+                   default="0"
+                   icon="icons/Features/angle.png"
+                   tooltip="Angle">
+      </doublevalue>
+    </box>
+    <box id="ByThreePoints"
+         title="By a center and two points"
+         icon="icons/Features/rotation_3pt_32x32.png">
+      <multi_selector id="main_objects"
+                      label="Main objects"
+                      icon=""
+                      tooltip="Select solid objects"
+                      type_choice="objects"
+                      concealment="true">
+        <validator id="FeaturesPlugin_ValidatorTransform"/>
+      </multi_selector>
+      <shape_selector id="center_point"
+                      label="Center point"
+                      icon="icons/Features/point.png"
+                      tooltip="Select a center point"
+                      shape_types="vertex">
+        <validator id="GeomValidators_ConstructionComposite"/>
+        <validator id="GeomValidators_ShapeType" parameters="vertex"/>
+      </shape_selector>
+      <shape_selector id="start_point"
+                      label="Start point"
+                      icon="icons/Features/point.png"  
+                      tooltip="Select a starting point"
+                      shape_types="vertex">
+        <validator id="GeomValidators_ConstructionComposite"/>
+        <validator id="GeomValidators_ShapeType" parameters="vertex"/>
+      </shape_selector>
+      <shape_selector id="end_point"
+                      label="End point"
+                      icon="icons/Features/point.png"
+                      tooltip="Select an end point"
+                      shape_types="vertex">
+        <validator id="GeomValidators_ConstructionComposite"/>
+        <validator id="GeomValidators_ShapeType" parameters="vertex"/>
+        <validator id="GeomValidators_DifferentShapes"/>
+      </shape_selector>
+    </box>
+  </toolbox>
+</source>
index 701e0bdff3871f59b88cfac9ae5a972b780f2424..7246364f13031cf51b8f097f38c69c3be94be06e 100644 (file)
@@ -59,6 +59,25 @@ void GeomAPI_Trsf::setRotation(const std::shared_ptr<GeomAPI_Ax1> theAxis,
   MY_TRSF->SetRotation(theAxis->impl<gp_Ax1>(), theAngle / 180.0 * M_PI);
 }
 
+//=================================================================================================
+void GeomAPI_Trsf::setRotation(const std::shared_ptr<GeomAPI_Pnt> theCenterPoint,
+                               const std::shared_ptr<GeomAPI_Pnt> theStartPoint,
+                               const std::shared_ptr<GeomAPI_Pnt> theEndPoint)
+{
+  gp_Pnt aCenterPoint = theCenterPoint->impl<gp_Pnt>();
+  gp_Pnt aStartPoint = theStartPoint->impl<gp_Pnt>();
+  gp_Pnt aEndPoint = theEndPoint->impl<gp_Pnt>();
+
+  gp_Vec aVec1(aCenterPoint, aStartPoint);
+  gp_Vec aVec2(aCenterPoint, aEndPoint);
+  gp_Dir aDir(aVec1 ^ aVec2);
+  gp_Ax1 anAxis(aCenterPoint, aDir);
+  double anAngle = aVec1.Angle(aVec2);
+  if (fabs(anAngle) < Precision::Angular()) anAngle += 2.*M_PI; // Taken from old GEOM code
+
+  MY_TRSF->SetRotation(anAxis, anAngle);
+}
+
 //=================================================================================================
 void GeomAPI_Trsf::setSymmetry(const std::shared_ptr<GeomAPI_Pnt> thePoint)
 {
index 9f7a7f811e84f1b800c9babd742ff18d108bbdb2..822afde1d6a25402570c61bd4f5050d8c16cba52 100644 (file)
@@ -59,6 +59,15 @@ class GeomAPI_Trsf : public GeomAPI_Interface
   GEOMAPI_EXPORT void setRotation(const std::shared_ptr<GeomAPI_Ax1> theAxis,
                                   const double theAngle);
 
+  /** \brief Sets a rotation transformation using three points.
+   *  \param[in] theCenterPoint  rotation center.
+   *  \param[in] theStartPoint   start rotation point.
+   *  \param[in] theEndPoint     end rotation point.
+   */
+  GEOMAPI_EXPORT void setRotation(const std::shared_ptr<GeomAPI_Pnt> theCenterPoint,
+                                  const std::shared_ptr<GeomAPI_Pnt> theStartPoint,
+                                  const std::shared_ptr<GeomAPI_Pnt> theEndPoint);
+
   /** \brief Sets a point symmetry transformation.
    *  \param[in] thePoint symmetry point.
    */
index c5244788b8949eab1b51c3e828023111ce93e93e..e3d52db32f8cf90fe908ad3ba76f917f96fda9f9 100644 (file)
 
 #include "GeomAlgoAPI_Rotation.h"
 
+#include <GeomAPI_XYZ.h>
+
 #include <BRepBuilderAPI_Transform.hxx>
 
+#include <gp_Ax1.hxx>
+#include <gp_Dir.hxx>
+#include <gp_Vec.hxx>
+
+#include <Precision.hxx>
+
 //=================================================================================================
 GeomAlgoAPI_Rotation::GeomAlgoAPI_Rotation(std::shared_ptr<GeomAPI_Shape> theSourceShape,
                                            std::shared_ptr<GeomAPI_Ax1>   theAxis,
                                            double                         theAngle)
 {
-  build(theSourceShape, theAxis, theAngle);
+  myMethodType = BY_ANGLE;
+  mySourceShape = theSourceShape;
+  myAxis = theAxis;
+  myAngle = theAngle;
 }
 
+
 //=================================================================================================
-void GeomAlgoAPI_Rotation::build(std::shared_ptr<GeomAPI_Shape> theSourceShape,
-                                 std::shared_ptr<GeomAPI_Ax1>   theAxis,
-                                 double                         theAngle)
+GeomAlgoAPI_Rotation::GeomAlgoAPI_Rotation(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                           std::shared_ptr<GeomAPI_Pnt>   theCenterPoint,
+                                           std::shared_ptr<GeomAPI_Pnt>   theStartPoint,
+                                           std::shared_ptr<GeomAPI_Pnt>   theEndPoint)
 {
-  if(!theSourceShape || !theAxis) {
-    return;
+  myMethodType = BY_POINTS;
+  mySourceShape = theSourceShape;
+  myCenterPoint = theCenterPoint;
+  myStartPoint = theStartPoint;
+  myEndPoint = theEndPoint;
+}
+
+//=================================================================================================
+bool GeomAlgoAPI_Rotation::check()
+{
+  switch (myMethodType) {
+    case BY_ANGLE: {
+      if (!myAxis) {
+        myError = "Rotation builder :: axis is not valid.";
+        return false;
+      }
+      if (!mySourceShape) {
+        myError = "Rotation builder :: source shape is not valid.";
+        return false;
+      }
+      if (myAngle < -360.) {
+        myError = "Rotation builder :: angle smaller than -360 degrees.";
+        return false;
+      }
+      if (myAngle > 360.) {
+        myError = "Rotation builder :: angle greater than 360 degrees.";
+        return false;
+      }
+      return true;
+    }
+    case BY_POINTS: {
+      if (!myCenterPoint) {
+        myError = "Rotation builder :: start point is not valid.";
+        return false;
+      }
+      if (!myStartPoint) {
+        myError = "Rotation builder :: start point is not valid.";
+        return false;
+      }
+      if (!myEndPoint) {
+        myError = "Rotation builder :: start point is not valid.";
+        return false;
+      }
+      if (!mySourceShape) {
+        myError = "Rotation builder :: source shape is invalid.";
+        return false;
+      }
+      if(myCenterPoint->distance(myStartPoint) < Precision::Confusion()) {
+        myError = "Rotation builder :: center point and start point coincide.";
+        return false;
+      }
+      if(myCenterPoint->distance(myEndPoint) < Precision::Confusion()) {
+        myError = "Rotation builder :: center point and end point coincide.";
+        return false;
+      }
+      if(myStartPoint->distance(myEndPoint) < Precision::Confusion()) {
+        myError = "Rotation builder :: start point and end point coincide.";
+        return false;
+      }
+      std::shared_ptr<GeomAPI_XYZ> aCenterPointXYZ = myCenterPoint->xyz();
+      std::shared_ptr<GeomAPI_XYZ> aStartPointXYZ = myStartPoint->xyz();
+      std::shared_ptr<GeomAPI_XYZ> aEndPointXYZ = myEndPoint->xyz();
+      std::shared_ptr<GeomAPI_XYZ> vectCenterPointStartPoint =
+        aStartPointXYZ->decreased(aCenterPointXYZ);
+      std::shared_ptr<GeomAPI_XYZ> vectCenterPointEndPoint =
+        aEndPointXYZ->decreased(aCenterPointXYZ);
+      std::shared_ptr<GeomAPI_XYZ> crossProduct =
+        vectCenterPointStartPoint->cross(vectCenterPointEndPoint);
+      std::shared_ptr<GeomAPI_Pnt> aOriginPnt =
+        std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(0.,0.,0.));
+      std::shared_ptr<GeomAPI_XYZ> aOriginXYZ = aOriginPnt->xyz();
+
+      if (crossProduct->distance(aOriginXYZ) < Precision::Confusion()) {
+        myError = "Rotation builder :: center point, start point and end point are on a line.";
+        return false;
+      }
+      return true;
+    }
+    default: {
+      myError = "Rotation builder :: method not implemented.";
+      return false;
+    }
   }
+}
+
+//=================================================================================================
+void GeomAlgoAPI_Rotation::build()
+{
+  gp_Trsf* aTrsf = new gp_Trsf();
 
-  const TopoDS_Shape& aSourceShape = theSourceShape->impl<TopoDS_Shape>();
-  const gp_Ax1& anAxis = theAxis->impl<gp_Ax1>();
+  switch (myMethodType) {
+    case BY_ANGLE: {
+      const gp_Ax1& anAxis = myAxis->impl<gp_Ax1>();
+      aTrsf->SetRotation(anAxis, myAngle/180.0*M_PI);
+      break;
+    }
+    case BY_POINTS: {
+      const gp_Pnt& aCenterPoint = myCenterPoint->impl<gp_Pnt>();
+      const gp_Pnt& aStartPoint = myStartPoint->impl<gp_Pnt>();
+      const gp_Pnt& aEndPoint = myEndPoint->impl<gp_Pnt>();
+      gp_Vec aVec1(aCenterPoint, aStartPoint);
+      gp_Vec aVec2(aCenterPoint, aEndPoint);
+      gp_Dir aDir(aVec1^aVec2);
+      gp_Ax1 anAxis(aCenterPoint, aDir);
+      double anAngle = aVec1.Angle(aVec2);
+      if (fabs(anAngle) < Precision::Angular()) anAngle += 2.*M_PI;
+      aTrsf->SetRotation(anAxis, anAngle);
+      break;
+    }
+    default: {
+      myError = "Rotation builder :: method not supported";
+      return;
+    }
+  }
+
+  const TopoDS_Shape& aSourceShape = mySourceShape->impl<TopoDS_Shape>();
 
   if(aSourceShape.IsNull()) {
+    myError = "Rotation builder :: source shape does not contain any actual shape.";
     return;
   }
 
-  gp_Trsf* aTrsf = new gp_Trsf();
-  aTrsf->SetRotation(anAxis, theAngle / 180.0 * M_PI);
-
-  // Transform the shape with copying it.
+  // Transform the shape while copying it.
   BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, *aTrsf, true);
   if(!aBuilder) {
+    myError = "Rotation builder :: transform initialization failed.";
     return;
   }
-  this->setImpl(aBuilder);
-  this->setBuilderType(OCCT_BRepBuilderAPI_MakeShape);
 
-  if(aBuilder->IsDone() != Standard_True) {
+  setImpl(aBuilder);
+  setBuilderType(OCCT_BRepBuilderAPI_MakeShape);
+
+  if(!aBuilder->IsDone()) {
+    myError = "Rotation builder :: algorithm failed.";
     return;
   }
+
   TopoDS_Shape aResult = aBuilder->Shape();
 
   std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
   aShape->setImpl(new TopoDS_Shape(aResult));
-  this->setShape(aShape);
-  this->setDone(true);
+  setShape(aShape);
+  setDone(true);
 }
index 48f922b04e90ffcac4913121c6bc6658b79e7f52..e5aee67e6950878433a009c7270a5d57ff748abd 100644 (file)
@@ -3,6 +3,8 @@
 // File:        GeomAlgoAPI_Rotation.h
 // Created:     12 May 2015
 // Author:      Dmitry Bobylev
+//
+// Modified by Clarisse Genrault (CEA) : 03 Mar 2017
 
 #ifndef GeomAlgoAPI_Rotation_H_
 #define GeomAlgoAPI_Rotation_H_
 class GeomAlgoAPI_Rotation : public GeomAlgoAPI_MakeShape
 {
 public:
-  /// \brief Creates an object which is obtained from current object by rotating it around the axis.
+  /// Type of rotation operation
+  enum MethodType {
+    BY_ANGLE, ///< Rotation by axis and an angle
+    BY_POINTS ///< Rotation by a center and two points
+  };
+
+  /// \brief Creates an object which is obtained from current object by rotating it around the axis
+  ///        with the angle.
   /// \param[in] theSourceShape  a shape to be rotated.
   /// \param[in] theAxis         rotation axis.
   /// \param[in] theAngle        rotation angle(in degree).
@@ -27,11 +36,31 @@ public:
                                           std::shared_ptr<GeomAPI_Ax1>   theAxis,
                                           double                         theAngle);
 
+  /// \brief Creates an object which is obtained from current object by rotating it around the axis
+  ///        withe angle using the center and two points.
+  /// \param[in] theSourceShape  a shape to be rotated.
+  /// \param[in] theCenterPoint  center point.
+  /// \param[in] theStartPoint   start point.
+  /// \param[in] theEndPoint     end point.
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_Rotation(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                          std::shared_ptr<GeomAPI_Pnt>   theCenterPoint,
+                                          std::shared_ptr<GeomAPI_Pnt>   theStartPoint,
+                                          std::shared_ptr<GeomAPI_Pnt>   theEndPoint);
+
+  /// Checks if data for the translation execution is OK.
+  GEOMALGOAPI_EXPORT bool check();
+
+  /// Execute the translation.
+  GEOMALGOAPI_EXPORT void build();
+
 private:
-  /// Builds resulting shape.
-  void build(std::shared_ptr<GeomAPI_Shape> theSourceShape,
-             std::shared_ptr<GeomAPI_Ax1>   theAxis,
-             double                         theAngle);
+  MethodType myMethodType; /// Type of method used.
+  std::shared_ptr<GeomAPI_Shape> mySourceShape; /// Shape to be rotated.
+  std::shared_ptr<GeomAPI_Ax1> myAxis; /// Rotation axis.
+  double myAngle; /// Rotation angle.
+  std::shared_ptr<GeomAPI_Pnt> myCenterPoint; /// Rotation center point.
+  std::shared_ptr<GeomAPI_Pnt> myStartPoint; /// Rotation start point.
+  std::shared_ptr<GeomAPI_Pnt> myEndPoint; /// Rotation end point.
 };
 
 #endif
index b0dabccc9cb1f3866c7ea8ae3773f29b8dc069d9..9c8e9aa6d6569219e4ce4feba344df64dbf67bd5 100644 (file)
@@ -11,6 +11,7 @@
 #include <GeomAlgoAPI_CompoundBuilder.h>
 #include <GeomAlgoAPI_ConeSegment.h>
 #include <GeomAlgoAPI_EdgeBuilder.h>
+#include <GeomAlgoAPI_Rotation.h>
 #include <GeomAlgoAPI_Scale.h>
 #include <GeomAlgoAPI_Symmetry.h>
 #include <GeomAlgoAPI_Translation.h>
@@ -261,6 +262,51 @@ namespace GeomAlgoAPI_ShapeAPI
     return aTranslationAlgo.shape();
   }
 
+  std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeRotation(
+    std::shared_ptr<GeomAPI_Shape> theSourceShape,
+    std::shared_ptr<GeomAPI_Ax1> theAxis,
+    const double theAngle) throw (GeomAlgoAPI_Exception)
+  {
+    GeomAlgoAPI_Rotation aRotationAlgo(theSourceShape, theAxis, theAngle);
+
+    if (!aRotationAlgo.check()) {
+      throw GeomAlgoAPI_Exception(aRotationAlgo.getError());
+    }
+
+    aRotationAlgo.build();
+
+    if(!aRotationAlgo.isDone()) {
+      throw GeomAlgoAPI_Exception(aRotationAlgo.getError());
+    }
+    if (!aRotationAlgo.checkValid("Rotation builder with two points")) {
+      throw GeomAlgoAPI_Exception(aRotationAlgo.getError());
+    }
+    return aRotationAlgo.shape();
+  }
+
+  std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeRotation(
+    std::shared_ptr<GeomAPI_Shape> theSourceShape,
+    std::shared_ptr<GeomAPI_Pnt> theCenterPoint,
+    std::shared_ptr<GeomAPI_Pnt> theStartPoint,
+    std::shared_ptr<GeomAPI_Pnt> theEndPoint) throw (GeomAlgoAPI_Exception)
+  {
+    GeomAlgoAPI_Rotation aRotationAlgo(theSourceShape, theCenterPoint, theStartPoint, theEndPoint);
+
+    if (!aRotationAlgo.check()) {
+      throw GeomAlgoAPI_Exception(aRotationAlgo.getError());
+    }
+
+    aRotationAlgo.build();
+
+    if(!aRotationAlgo.isDone()) {
+      throw GeomAlgoAPI_Exception(aRotationAlgo.getError());
+    }
+    if (!aRotationAlgo.checkValid("Rotation builder with two points")) {
+      throw GeomAlgoAPI_Exception(aRotationAlgo.getError());
+    }
+    return aRotationAlgo.shape();
+  }
+
   //===============================================================================================
   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeSymmetry(
     std::shared_ptr<GeomAPI_Shape> theSourceShape,
index 81dbfd70557648d35fdeb631a64a3c012a1b917c..3f137c4fe033d332c836e1fc6ae937a74042fcd6 100644 (file)
@@ -103,6 +103,28 @@ public:
                      std::shared_ptr<GeomAPI_Pnt> theStartPoint,
                      std::shared_ptr<GeomAPI_Pnt> theEndPoint) throw (GeomAlgoAPI_Exception);
 
+  /// Performs a rotation from an axis and an angle.
+  /// \param theSourceShape Shape to be rotated
+  /// \param theAxis Movement axis
+  /// \param theAngle Movement angle
+  /// \return a shape
+  static std::shared_ptr<GeomAPI_Shape> makeRotation(
+                     std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                     std::shared_ptr<GeomAPI_Ax1> theAxis,
+                     const double theAngle) throw (GeomAlgoAPI_Exception);
+
+  /// Performs a rotation from three points.
+  /// \param theSourceShape Shape to be rotated
+  /// \param theCenterPoint Movement center point
+  /// \param theStartPoint Movement start point
+  /// \param theEndPoint Movement end point
+  /// \return a shape
+  static std::shared_ptr<GeomAPI_Shape> makeRotation(
+                     std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                     std::shared_ptr<GeomAPI_Pnt> theCenterPoint,
+                     std::shared_ptr<GeomAPI_Pnt> theStartPoint,
+                     std::shared_ptr<GeomAPI_Pnt> theEndPoint) throw (GeomAlgoAPI_Exception);
+
   /// Performs a symmetry by a point.
   /// \param theSourceShape Shape be symmetrized
   /// \param thePoint Point of symmetry