]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Added multirotation feature.
authorClarisse Genrault <clarisse.genrault@cea.fr>
Mon, 3 Apr 2017 14:26:45 +0000 (16:26 +0200)
committerClarisse Genrault <clarisse.genrault@cea.fr>
Mon, 3 Apr 2017 14:26:45 +0000 (16:26 +0200)
src/FeaturesPlugin/FeaturesPlugin_MultiRotation.cpp [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_MultiRotation.h [new file with mode: 0644]
src/FeaturesPlugin/multirotation_widget.xml [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_MultiRotation.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_MultiRotation.h [new file with mode: 0644]

diff --git a/src/FeaturesPlugin/FeaturesPlugin_MultiRotation.cpp b/src/FeaturesPlugin/FeaturesPlugin_MultiRotation.cpp
new file mode 100644 (file)
index 0000000..4c1d847
--- /dev/null
@@ -0,0 +1,480 @@
+// Copyright (C) 2014-201x CEA/DEN, EDF R&D
+
+// File:        FeaturesPlugin_MultiRotation.cpp
+// Created:     30 Jan 2017
+// Author:      Clarisse Genrault (CEA)
+
+#include <FeaturesPlugin_MultiRotation.h>
+
+#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAlgoAPI_Translation.h>
+
+#include <GeomAPI_ShapeExplorer.h>
+
+#include <GeomAPI_Ax1.h>
+#include <GeomAPI_Edge.h>
+#include <GeomAPI_Lin.h>
+#include <GeomAPI_Trsf.h>
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultPart.h>
+
+#include <math.h>
+#include <iostream>
+
+//=================================================================================================
+FeaturesPlugin_MultiRotation::FeaturesPlugin_MultiRotation()
+{
+}
+
+//=================================================================================================
+void FeaturesPlugin_MultiRotation::initAttributes()
+{
+  AttributeSelectionListPtr aSelection =
+    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
+    FeaturesPlugin_MultiRotation::OBJECTS_LIST_ID(),
+    ModelAPI_AttributeSelectionList::typeId()));
+
+  data()->addAttribute(FeaturesPlugin_MultiRotation::AXIS_ANGULAR_ID(),
+                       ModelAPI_AttributeSelection::typeId());
+  data()->addAttribute(FeaturesPlugin_MultiRotation::USE_ANGULAR_STEP_ID(),
+                       ModelAPI_AttributeString::typeId());
+  data()->addAttribute(FeaturesPlugin_MultiRotation::STEP_ANGULAR_ID(),
+                       ModelAPI_AttributeDouble::typeId());
+  data()->addAttribute(FeaturesPlugin_MultiRotation::NB_COPIES_ANGULAR_ID(),
+                       ModelAPI_AttributeInteger::typeId());
+
+  /*data()->addAttribute(FeaturesPlugin_MultiRotation::USE_RADIAL_DIR_ID(),
+                       ModelAPI_AttributeString::typeId());
+  data()->addAttribute(FeaturesPlugin_MultiRotation::STEP_RADIAL_ID(),
+                       ModelAPI_AttributeDouble::typeId());
+  data()->addAttribute(FeaturesPlugin_MultiRotation::NB_COPIES_RADIAL_ID(),
+                       ModelAPI_AttributeInteger::typeId());*/
+}
+
+//=================================================================================================
+void FeaturesPlugin_MultiRotation::execute()
+{
+  /*std::string useRadialDir = string(FeaturesPlugin_MultiRotation::USE_RADIAL_DIR_ID())->value();
+  if (useRadialDir.empty()) {
+    performRotation1D();
+  } else {
+    performRotation2D();
+  }*/
+  performRotation1D();
+}
+
+//=================================================================================================
+void FeaturesPlugin_MultiRotation::performRotation1D()
+{
+  // Getting objects.
+  ListOfShape anObjects;
+  std::list<ResultPtr> aContextes;
+  AttributeSelectionListPtr anObjectsSelList =
+    selectionList(FeaturesPlugin_MultiRotation::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()) { // may be for not-activated parts
+      eraseResults();
+      return;
+    }
+    anObjects.push_back(anObject);
+    aContextes.push_back(anObjectAttr->context());
+  }
+
+  //Getting axis.
+  std::shared_ptr<GeomAPI_Ax1> anAxis;
+  std::shared_ptr<GeomAPI_Edge> anEdge;
+  std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
+    selection(FeaturesPlugin_MultiRotation::AXIS_ANGULAR_ID());
+  if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
+    anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
+  } else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
+             anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
+    anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
+  }
+  if(anEdge) {
+    anAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(),
+                                                          anEdge->line()->direction()));
+  }
+
+  // Getting number of copies.
+  int nbCopies =
+    integer(FeaturesPlugin_MultiRotation::NB_COPIES_ANGULAR_ID())->value();
+    
+  if (nbCopies <=0) {
+    std::string aFeatureError = "Multirotation builder ";
+    aFeatureError+=":: the number of copies for the angular direction is null or negative.";
+    setError(aFeatureError);
+    return;
+  }
+  
+  // Getting angle
+  double anAngle;
+  std::string useAngularStep =
+    string(FeaturesPlugin_MultiRotation::USE_ANGULAR_STEP_ID())->value();
+  if (!useAngularStep.empty()) {
+    anAngle = real(FeaturesPlugin_MultiRotation::STEP_ANGULAR_ID())->value();
+  } else {
+    anAngle = 360./nbCopies;
+  }
+  
+  // Moving 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) {
+      ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
+      std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
+      for (int i=0; i<nbCopies; i++) {
+        aTrsf->setRotation(anAxis, i*anAngle);
+        ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
+        aResultPart->setTrsf(*aContext, aTrsf);
+        setResult(aResultPart, aResultIndex);
+        aResultIndex++;
+      }
+    } else {
+      ListOfShape aListOfShape;
+      std::list<std::shared_ptr<GeomAlgoAPI_Rotation> > aListOfRotationAlgo;
+
+      for (int i=0; i<nbCopies; i++) {
+        std::shared_ptr<GeomAlgoAPI_Rotation> aRotationnAlgo(
+          new GeomAlgoAPI_Rotation(aBaseShape, anAxis, i*anAngle));
+
+        if (!aRotationnAlgo->check()) {
+          setError(aRotationnAlgo->getError());
+          break;
+        }
+
+        aRotationnAlgo->build();
+
+        // Checking that the algorithm worked properly.
+        if (!aRotationnAlgo->isDone()) {
+          static const std::string aFeatureError = "Error : Multitranslation algorithm failed.";
+          setError(aFeatureError);
+          break;
+        }
+        if (aRotationnAlgo->shape()->isNull()) {
+          static const std::string aShapeError = "Error : Resulting shape is null.";
+          setError(aShapeError);
+          break;
+        }
+        if (!aRotationnAlgo->isValid()) {
+          static const std::string aFeatureError = "Error : Resulting shape in not valid.";
+          setError(aFeatureError);
+          break;
+        }
+        aListOfShape.push_back(aRotationnAlgo->shape());
+        aListOfRotationAlgo.push_back(aRotationnAlgo);
+      }
+      std::shared_ptr<GeomAPI_Shape> aCompound =
+        GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
+      ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+      aResultBody->storeModified(aBaseShape, aCompound);
+      loadNamingDS(aListOfRotationAlgo, aResultBody, aBaseShape);
+
+      setResult(aResultBody, aResultIndex);
+    }
+    aResultIndex++;
+  }
+
+  // Remove the rest results if there were produced in the previous pass.
+  removeResults(aResultIndex);
+}
+
+//=================================================================================================
+void FeaturesPlugin_MultiRotation::performRotation2D()
+{
+  // Getting objects.
+  ListOfShape anObjects;
+  std::list<ResultPtr> aContextes;
+  AttributeSelectionListPtr anObjectsSelList =
+    selectionList(FeaturesPlugin_MultiRotation::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()) { // may be for not-activated parts
+      eraseResults();
+      return;
+    }
+    anObjects.push_back(anObject);
+    aContextes.push_back(anObjectAttr->context());
+  }
+
+  //Getting axis.
+  std::shared_ptr<GeomAPI_Ax1> anAxis;
+  std::shared_ptr<GeomAPI_Edge> anEdge;
+  std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
+    selection(FeaturesPlugin_MultiRotation::AXIS_ANGULAR_ID());
+  if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
+    anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
+  } else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
+             anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
+    anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
+  }
+  if(anEdge) {
+    anAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(),
+                                                          anEdge->line()->direction()));
+  }
+  
+  // Getting number of copies int he angular direction.
+  int nbAngular =
+    integer(FeaturesPlugin_MultiRotation::NB_COPIES_ANGULAR_ID())->value();
+    
+  if (nbAngular <=0) {
+    std::string aFeatureError = "Multirotation builder ";
+    aFeatureError+=":: the number of copies for the angular direction is null or negative.";
+    setError(aFeatureError);
+    return;
+  }
+  
+  // Getting number of copies int he radial direction.
+  int nbRadial =
+    integer(FeaturesPlugin_MultiRotation::NB_COPIES_RADIAL_ID())->value();
+    
+  if (nbRadial <=0) {
+    std::string aFeatureError = "Multirotation builder ";
+    aFeatureError+=":: the number of copies for the radial direction is null or negative.";
+    setError(aFeatureError);
+    return;
+  }
+  
+  // Getting angle
+  double anAngle;
+  std::string useAngularStep =
+    string(FeaturesPlugin_MultiRotation::USE_ANGULAR_STEP_ID())->value();
+  if (!useAngularStep.empty()) {
+    anAngle = real(FeaturesPlugin_MultiRotation::STEP_ANGULAR_ID())->value();
+  } else {
+    anAngle = 360./nbAngular;
+  }
+  
+  // 
+  double aStep = real(FeaturesPlugin_MultiRotation::STEP_RADIAL_ID())->value();
+
+  // Moving 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();
+  
+    std::shared_ptr<GeomAPI_Dir> aDir = GeomAlgoAPI_ShapeTools::makeToto(aBaseShape, anAxis);
+    double x = aDir->x();
+    double y = aDir->y();
+    double z = aDir->z();
+    double norm = sqrt(x*x+y*y+z*z);
+
+    // Setting result.
+    if (isPart) {
+      /*ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
+      std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
+      for (int j=0; j<aSecondNbCopies; j++) {
+        for (int i=0; i<aFirstNbCopies; i++) {
+          double dx = i*aFirstStep*x1/norm1+j*aSecondStep*x2/norm2;
+          double dy = i*aFirstStep*y1/norm1+j*aSecondStep*y2/norm2;
+          double dz = i*aFirstStep*z1/norm1+j*aSecondStep*z2/norm2;
+          aTrsf->setTranslation(dx, dy, dz);
+          ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
+          aResultPart->setTrsf(*aContext, aTrsf);
+          setResult(aResultPart, aResultIndex);
+          aResultIndex++;
+        }
+      }*/
+    } else {
+      ListOfShape aListOfShape;
+      std::list<std::shared_ptr<GeomAlgoAPI_Translation> > aListOfTranslationAlgo;
+      std::list<std::shared_ptr<GeomAlgoAPI_Rotation> > aListOfRotationAlgo;
+      for (int j=0; j<nbRadial; j++) {
+        // Translation
+        double dx = j*aStep*x/norm;
+        double dy = j*aStep*y/norm;
+        double dz = j*aStep*z/norm;
+        std::shared_ptr<GeomAlgoAPI_Translation> aTranslationAlgo(
+          new GeomAlgoAPI_Translation(aBaseShape, dx, dy, dz));
+
+        if (!aTranslationAlgo->check()) {
+          setError(aTranslationAlgo->getError());
+          break;
+        }
+
+        aTranslationAlgo->build();
+
+        // Checking that the algorithm worked properly.
+        if (!aTranslationAlgo->isDone()) {
+          static const std::string aFeatureError = "Error : Multirotation algorithm failed.";
+          setError(aFeatureError);
+          break;
+        }
+        if (aTranslationAlgo->shape()->isNull()) {
+          static const std::string aShapeError = "Error : Resulting shape is null.";
+          setError(aShapeError);
+          break;
+        }
+        if (!aTranslationAlgo->isValid()) {
+          static const std::string aFeatureError = "Error : Resulting shape in not valid.";
+          setError(aFeatureError);
+          break;
+        }
+        aListOfShape.push_back(aTranslationAlgo->shape());
+        aListOfTranslationAlgo.push_back(aTranslationAlgo);
+        for (int i=1; i<nbAngular; i++) {
+          std::shared_ptr<GeomAlgoAPI_Rotation> aRotationnAlgo(
+            new GeomAlgoAPI_Rotation(aTranslationAlgo->shape(), anAxis, i*anAngle));
+          if (!aRotationnAlgo->check()) {
+            setError(aTranslationAlgo->getError());
+            break;
+          }
+          aRotationnAlgo->build();// Checking that the algorithm worked properly.
+          if (!aRotationnAlgo->isDone()) {
+            static const std::string aFeatureError = "Error : Multirotation algorithm failed.";
+            setError(aFeatureError);
+            break;
+          }
+          if (aRotationnAlgo->shape()->isNull()) {
+            static const std::string aShapeError = "Error : Resulting shape is null.";
+            setError(aShapeError);
+            break;
+          }
+          if (!aRotationnAlgo->isValid()) {
+            static const std::string aFeatureError = "Error : Resulting shape in not valid.";
+            setError(aFeatureError);
+            break;
+          }
+          aListOfShape.push_back(aRotationnAlgo->shape());
+          aListOfRotationAlgo.push_back(aRotationnAlgo);
+        }
+      }
+      std::shared_ptr<GeomAPI_Shape> aCompound =
+        GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
+      ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+      aResultBody->storeModified(aBaseShape, aCompound);
+      
+      loadNamingDS2(aListOfTranslationAlgo, aResultBody, aBaseShape);
+      loadNamingDS3(aListOfRotationAlgo, aResultBody, aBaseShape, nbRadial);
+      setResult(aResultBody, aResultIndex);
+    }
+    aResultIndex++;
+  }
+
+  // Remove the rest results if there were produced in the previous pass.
+  removeResults(aResultIndex);
+}
+
+//=================================================================================================
+void FeaturesPlugin_MultiRotation::loadNamingDS2(
+    std::list<std::shared_ptr<GeomAlgoAPI_Translation> > theListOfTranslationAlgo,
+    std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+    std::shared_ptr<GeomAPI_Shape> theBaseShape)
+{
+  int aTag = 1;
+  int anIndex = 1;
+  std::string aRotatedName;
+
+  for (std::list<std::shared_ptr<GeomAlgoAPI_Translation> >::const_iterator anIt =
+    theListOfTranslationAlgo.begin(); anIt != theListOfTranslationAlgo.cend(); ++anIt) {
+    std::cout << "LOAD" << std::endl;
+    std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = (*anIt)->mapOfSubShapes();
+
+    // naming of faces
+    aRotatedName = "Rotated_Face_" + std::to_string((long long) anIndex);
+    theResultBody->loadAndOrientModifiedShapes((*anIt).get(), theBaseShape, GeomAPI_Shape::FACE,
+                                               aTag++, aRotatedName, *aSubShapes.get(),
+                                               false, true);
+
+    // naming of edges
+    aRotatedName = "Rotated_Edge_" + std::to_string((long long) anIndex);
+    theResultBody->loadAndOrientModifiedShapes((*anIt).get(), theBaseShape, GeomAPI_Shape::EDGE,
+                                               aTag++, aRotatedName, *aSubShapes.get(),
+                                               false, true);
+
+    // naming of vertex
+    aRotatedName = "Rotated_Vertex_" + std::to_string((long long) anIndex);
+    theResultBody->loadAndOrientModifiedShapes((*anIt).get(), theBaseShape, GeomAPI_Shape::VERTEX,
+                                               aTag++, aRotatedName, *aSubShapes.get(),
+                                               false, true);
+
+    ++anIndex;
+  }
+}
+
+//=================================================================================================
+void FeaturesPlugin_MultiRotation::loadNamingDS3(
+    std::list<std::shared_ptr<GeomAlgoAPI_Rotation> > theListOfRotationAlgo,
+    std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+    std::shared_ptr<GeomAPI_Shape> theBaseShape, int nb)
+{
+  int aTag = 6*nb+1;
+  int anIndex = nb+1;
+  std::string aRotatedName;
+
+  for (std::list<std::shared_ptr<GeomAlgoAPI_Rotation> >::const_iterator anIt =
+    theListOfRotationAlgo.begin(); anIt != theListOfRotationAlgo.cend(); ++anIt) {
+    
+    // naming of faces
+    int numFace = 1;
+    GeomAPI_ShapeExplorer anExp((*anIt)->shape(), GeomAPI_Shape::FACE);
+    for(; anExp.more(); anExp.next()) {
+       aRotatedName = "Rotated_Face_" + std::to_string((long long) anIndex);
+       aRotatedName = aRotatedName + "_" + std::to_string((long long) numFace);
+       theResultBody->generated(anExp.current(), aRotatedName, aTag++);
+       ++numFace;
+    }
+    ++anIndex;
+  }
+}
+
+//=================================================================================================
+void FeaturesPlugin_MultiRotation::loadNamingDS(
+    std::list<std::shared_ptr<GeomAlgoAPI_Rotation> > theListOfRotationAlgo,
+    std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+    std::shared_ptr<GeomAPI_Shape> theBaseShape)
+{
+  int aTag = 1;
+  int anIndex = 1;
+  std::string aRotatedName;
+
+  for (std::list<std::shared_ptr<GeomAlgoAPI_Rotation> >::const_iterator anIt =
+    theListOfRotationAlgo.begin(); anIt != theListOfRotationAlgo.cend(); ++anIt) {
+    std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = (*anIt)->mapOfSubShapes();
+
+    // naming of faces
+    aRotatedName = "Rotated_Face_" + std::to_string((long long) anIndex);
+    theResultBody->loadAndOrientModifiedShapes((*anIt).get(), theBaseShape, GeomAPI_Shape::FACE,
+                                               aTag++, aRotatedName, *aSubShapes.get(),
+                                               false, true);
+
+    // naming of edges
+    aRotatedName = "Rotated_Edge_" + std::to_string((long long) anIndex);
+    theResultBody->loadAndOrientModifiedShapes((*anIt).get(), theBaseShape, GeomAPI_Shape::EDGE,
+                                               aTag++, aRotatedName, *aSubShapes.get(),
+                                               false, true);
+
+    // naming of vertex
+    aRotatedName = "Rotated_Vertex_" + std::to_string((long long) anIndex);
+    theResultBody->loadAndOrientModifiedShapes((*anIt).get(), theBaseShape, GeomAPI_Shape::VERTEX,
+                                               aTag++, aRotatedName, *aSubShapes.get(),
+                                               false, true);
+    ++anIndex;
+  }
+}
diff --git a/src/FeaturesPlugin/FeaturesPlugin_MultiRotation.h b/src/FeaturesPlugin/FeaturesPlugin_MultiRotation.h
new file mode 100644 (file)
index 0000000..b39d4b4
--- /dev/null
@@ -0,0 +1,124 @@
+// Copyright (C) 2014-201x CEA/DEN, EDF R&D
+
+// File:        FeaturesPlugin_MultiRotation.h
+// Created:     30 Jan 2017
+// Author:      Clarisse Genrault (CEA)
+
+#ifndef FEATURESPLUGIN_MULTIROTATION_H_
+#define FEATURESPLUGIN_MULTIROTATION_H_
+
+#include <FeaturesPlugin.h>
+
+#include <GeomAlgoAPI_Rotation.h>
+#include <GeomAlgoAPI_Translation.h>
+
+#include <ModelAPI_Feature.h>
+
+/** \class FeaturesPlugin_MultiRotation
+ *  \ingroup Plugins
+ *  \brief Feature for movement objects along one or two axes an arbitary number of times,
+ *         making a copy every time.
+ */
+class FeaturesPlugin_MultiRotation : public ModelAPI_Feature
+{
+  public:
+  /// Multi-rotation kind.
+  inline static const std::string& ID()
+  {
+    static const std::string MY_MULTIROTATION_ID("MultiRotation");
+    return MY_MULTIROTATION_ID;
+  }
+
+  /// Attribute name of referenced objects.
+  inline static const std::string& OBJECTS_LIST_ID()
+  {
+    static const std::string MY_OBJECTS_LIST_ID("main_objects");
+    return MY_OBJECTS_LIST_ID;
+  }
+
+  /// Attribute name of the angular direction.
+  inline static const std::string& AXIS_ANGULAR_ID()
+  {
+    static const std::string MY_AXIS_ANGULAR_ID("axis_angular");
+    return MY_AXIS_ANGULAR_ID;
+  }
+
+  /// Attribute name for use angular step.
+  inline static const std::string& USE_ANGULAR_STEP_ID()
+  {
+    static const std::string MY_USE_ANGULAR_STEP_ID("use_step_angular");
+    return MY_USE_ANGULAR_STEP_ID;
+  }
+
+  /// Attribute name of step for the first direction.
+  inline static const std::string& STEP_ANGULAR_ID()
+  {
+    static const std::string MY_STEP_ANGULAR_ID("step_angular");
+    return MY_STEP_ANGULAR_ID;
+  }
+
+  /// Attribute name of number of copies for the first direction.
+  inline static const std::string& NB_COPIES_ANGULAR_ID()
+  {
+    static const std::string MY_NB_COPIES_ANGULAR_ID("nb_angular");
+    return MY_NB_COPIES_ANGULAR_ID;
+  }
+
+  /// Attribute name for use second dir.
+  inline static const std::string& USE_RADIAL_DIR_ID()
+  {
+    static const std::string MY_USE_RADIAL_DIR_ID("use_radial_dir");
+    return MY_USE_RADIAL_DIR_ID;
+  }
+
+  /// Attribute name of step for the second direction.
+  inline static const std::string& STEP_RADIAL_ID()
+  {
+    static const std::string MY_STEP_RADIAL_ID("step_radial");
+    return MY_STEP_RADIAL_ID;
+  }
+
+  /// Attribute name of number of copies for the second direction.
+  inline static const std::string& NB_COPIES_RADIAL_ID()
+  {
+    static const std::string MY_NB_COPIES_RADIAL_ID("nb_radial");
+    return MY_NB_COPIES_RADIAL_ID;
+  }
+
+  /// \return the kind of a feature.
+  FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    static std::string MY_KIND = FeaturesPlugin_MultiRotation::ID();
+    return MY_KIND;
+  }
+
+  /// Creates a new part document if needed.
+  FEATURESPLUGIN_EXPORT virtual void execute();
+
+  /// Request for initialization of data model of the feature: adding all attributes.
+  FEATURESPLUGIN_EXPORT virtual void initAttributes();
+
+  /// Use plugin manager for features creation.
+  FeaturesPlugin_MultiRotation();
+
+private:
+  /// Perform the multi translation in one direction.
+  void performRotation1D();
+
+  /// Perform the multi translation in two directions.
+  void performRotation2D();
+
+  void loadNamingDS2(std::list<std::shared_ptr<GeomAlgoAPI_Translation> > theListOfTranslationAlgo,
+                    std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+                    std::shared_ptr<GeomAPI_Shape> theBaseShape);
+
+  void loadNamingDS3(std::list<std::shared_ptr<GeomAlgoAPI_Rotation> > theListOfRotationAlgo,
+                    std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+                    std::shared_ptr<GeomAPI_Shape> theBaseShape, int nb);
+
+  void loadNamingDS(std::list<std::shared_ptr<GeomAlgoAPI_Rotation> > theListOfRotationAlgo,
+                    std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+                    std::shared_ptr<GeomAPI_Shape> theBaseShape);
+};
+
+#endif // FEATURESPLUGIN_MULTIROTATION_H_
\ No newline at end of file
diff --git a/src/FeaturesPlugin/multirotation_widget.xml b/src/FeaturesPlugin/multirotation_widget.xml
new file mode 100644 (file)
index 0000000..8396f48
--- /dev/null
@@ -0,0 +1,53 @@
+<!-- Copyright (C) 2014-201x CEA/DEN, EDF R&D -->
+
+<source>
+  <multi_selector id="main_objects"
+                  label="Main objects"
+                  icon=""
+                  tooltip="Select objects"
+                  type_choice="objects"
+                  concealment="true">
+    <validator id="FeaturesPlugin_ValidatorTransform"/>
+  </multi_selector>
+  <groupbox title="Angular direction">
+    <shape_selector id="axis_angular"
+                    icon="icons/Features/axis.png"
+                    label="Axis"
+                    tooltip="Select an edge for the angular direction"
+                    shape_types="edge"
+                    default="">
+      <validator id="GeomValidators_ShapeType" parameters="line"/>
+    </shape_selector>
+    <optionalbox id="use_step_angular" title="Angular step">
+      <doublevalue id="step_angular"
+                   label="Angular step"
+                   step="1.0"
+                   default="0"
+                   tooltip="Step for the angular direction">
+      </doublevalue>
+    </optionalbox>
+    <integervalue id="nb_angular"
+                  label="Nb copies"
+                  step="1"
+                  default="2"
+                  icon=""
+                  tooltip="Number of copies for the first direction">
+    </integervalue>
+  </groupbox>
+  <!--<optionalbox id="use_radial_dir" title="Radial direction">
+    <doublevalue id="step_radial"
+                 label="Step"
+                 step="1.0"
+                 default="0"
+                 icon="icons/Features/dimension_v.png"
+                 tooltip="Step for the radial direction">
+    </doublevalue>
+    <integervalue id="nb_radial"
+                  label="Nb copies"
+                  step="1"
+                  default="2"
+                  icon=""
+                  tooltip="Number of copies for the radial direction">
+    </integervalue>
+  </optionalbox>-->
+</source>
\ No newline at end of file
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MultiRotation.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_MultiRotation.cpp
new file mode 100644 (file)
index 0000000..0c706d3
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_MultiRotation.cpp
+// Created:     30 Mar 2017
+// Author:      Clarisse Genrault (CEA)
+
+#include "GeomAlgoAPI_MultiRotation.h"
+
+//=================================================================================================
+GeomAlgoAPI_MultiRotation::GeomAlgoAPI_MultiRotation(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                           std::shared_ptr<GeomAPI_Ax1>   theAxis,
+                                           double                         theAngle)
+{
+}
+
+//=================================================================================================
+bool GeomAlgoAPI_MultiRotation::check()
+{
+  return true;
+}
+
+//=================================================================================================
+void GeomAlgoAPI_MultiRotation::build()
+{
+  setDone(true);
+}
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MultiRotation.h b/src/GeomAlgoAPI/GeomAlgoAPI_MultiRotation.h
new file mode 100644 (file)
index 0000000..d687e4a
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_MultiRotation.h
+// Created:     30 Mar 2017
+// Author:      Clarisse Genrault (CEA)
+
+#ifndef GEOMALGOAPI_MULTIROTATION_H_
+#define GEOMALGOAPI_MULTIROTATION_H_
+
+#include <GeomAlgoAPI.h>
+#include <GeomAlgoAPI_MakeShape.h>
+
+#include <GeomAPI_Ax1.h>
+#include <GeomAPI_Shape.h>
+
+/// \class GeomAlgoAPI_MultiRotation
+/// \ingroup DataAlgo
+/// \brief Creates a copy of the object by rotating it around the axis.
+class GeomAlgoAPI_MultiRotation : public GeomAlgoAPI_MakeShape
+{
+public:
+
+  /// \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).
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_MultiRotation(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                          std::shared_ptr<GeomAPI_Ax1>   theAxis,
+                                          double                         theAngle);
+
+  /// Checks if data for the translation execution is OK.
+  GEOMALGOAPI_EXPORT bool check();
+
+  /// Execute the translation.
+  GEOMALGOAPI_EXPORT void build();
+
+private:
+  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 // GEOMALGOAPI_MULTIROTATION_H_