Salome HOME
Adding Scale feature.
authorClarisse Genrault <clarisse.genrault@cea.fr>
Thu, 26 Jan 2017 07:03:16 +0000 (08:03 +0100)
committerClarisse Genrault <clarisse.genrault@cea.fr>
Thu, 26 Jan 2017 07:03:16 +0000 (08:03 +0100)
25 files changed:
src/FeaturesAPI/CMakeLists.txt
src/FeaturesAPI/FeaturesAPI.i
src/FeaturesAPI/FeaturesAPI_Scale.cpp [new file with mode: 0644]
src/FeaturesAPI/FeaturesAPI_Scale.h [new file with mode: 0644]
src/FeaturesAPI/FeaturesAPI_swig.h
src/FeaturesAPI/Test/APIParam_Scale.py [new file with mode: 0644]
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp
src/FeaturesPlugin/FeaturesPlugin_Scale.cpp [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_Scale.h [new file with mode: 0644]
src/FeaturesPlugin/icons/SVG/scale.svg [new file with mode: 0644]
src/FeaturesPlugin/icons/SVG/scale_dimensions_32x32.svg [new file with mode: 0644]
src/FeaturesPlugin/icons/SVG/scale_factor_32x32.svg [new file with mode: 0644]
src/FeaturesPlugin/icons/scale.png [new file with mode: 0644]
src/FeaturesPlugin/icons/scale_dimensions_32x32.png [new file with mode: 0644]
src/FeaturesPlugin/icons/scale_factor_32x32.png [new file with mode: 0644]
src/FeaturesPlugin/plugin-Features.xml
src/FeaturesPlugin/scale_widget.xml [new file with mode: 0644]
src/GeomAlgoAPI/CMakeLists.txt
src/GeomAlgoAPI/GeomAlgoAPI_Scale.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_Scale.h [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.h
src/GeomAlgoAPI/Test/TestAPI_Scale.py [new file with mode: 0644]
src/PythonAPI/model/features/__init__.py

index e109499003f091b13e5d938c0baec7ba82d6e6c5..af088777a46c35ddc485c40ebfa18b4d3bc4de81 100644 (file)
@@ -17,6 +17,7 @@ SET(PROJECT_HEADERS
   FeaturesAPI_Revolution.h
   FeaturesAPI_RevolutionBoolean.h
   FeaturesAPI_Rotation.h
+  FeaturesAPI_Scale.h
   FeaturesAPI_Symmetry.h
   FeaturesAPI_Translation.h
   FeaturesAPI_Union.h
@@ -35,6 +36,7 @@ SET(PROJECT_SOURCES
   FeaturesAPI_Revolution.cpp
   FeaturesAPI_RevolutionBoolean.cpp
   FeaturesAPI_Rotation.cpp
+  FeaturesAPI_Scale.cpp
   FeaturesAPI_Symmetry.cpp
   FeaturesAPI_Translation.cpp
   FeaturesAPI_Union.cpp
@@ -94,5 +96,6 @@ INSTALL(TARGETS _FeaturesAPI DESTINATION ${SHAPER_INSTALL_SWIG})
 INSTALL(TARGETS FeaturesAPI DESTINATION ${SHAPER_INSTALL_BIN})
 INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/FeaturesAPI.py DESTINATION ${SHAPER_INSTALL_SWIG})
 
-ADD_UNIT_TESTS(APIParam_Symmetry.py
+ADD_UNIT_TESTS(APIParam_Scale.py
+               APIParam_Symmetry.py
                APIParam_Translation.py)
\ No newline at end of file
index 68817ec5f468a322202c715ef12d252de07dc840..9a0ff26becc71e059869150cd07de6cc42d9fa4e 100644 (file)
@@ -35,6 +35,7 @@
 %shared_ptr(FeaturesAPI_RevolutionCut)
 %shared_ptr(FeaturesAPI_RevolutionFuse)
 %shared_ptr(FeaturesAPI_Rotation)
+%shared_ptr(FeaturesAPI_Scale)
 %shared_ptr(FeaturesAPI_Symmetry)
 %shared_ptr(FeaturesAPI_Translation)
 %shared_ptr(FeaturesAPI_Union)
@@ -52,6 +53,7 @@
 %include "FeaturesAPI_Revolution.h"
 %include "FeaturesAPI_RevolutionBoolean.h"
 %include "FeaturesAPI_Rotation.h"
+%include "FeaturesAPI_Scale.h"
 %include "FeaturesAPI_Symmetry.h"
 %include "FeaturesAPI_Translation.h"
 %include "FeaturesAPI_Union.h"
diff --git a/src/FeaturesAPI/FeaturesAPI_Scale.cpp b/src/FeaturesAPI/FeaturesAPI_Scale.cpp
new file mode 100644 (file)
index 0000000..e80f3b4
--- /dev/null
@@ -0,0 +1,144 @@
+// Copyright (C) 2014-201x CEA/DEN, EDF R&D -->
+
+// File:        FeaturesAPI_Scale.cpp
+// Created:     24 Jan 2017
+// Author:      Clarisse Genrault (CEA)
+
+#include "FeaturesAPI_Scale.h"
+
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Tools.h>
+
+//==================================================================================================
+FeaturesAPI_Scale::FeaturesAPI_Scale(const std::shared_ptr<ModelAPI_Feature>& theFeature)
+: ModelHighAPI_Interface(theFeature)
+{
+  initialize();
+}
+
+//==================================================================================================
+FeaturesAPI_Scale::FeaturesAPI_Scale(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                     const std::list<ModelHighAPI_Selection>& theMainObjects,
+                                     const ModelHighAPI_Selection& theCenterPoint,
+                                     const ModelHighAPI_Double& theScaleFactor)
+: ModelHighAPI_Interface(theFeature)
+{
+  if (initialize()) {
+    fillAttribute(theMainObjects, mainObjects());
+    fillAttribute(theCenterPoint, centerPoint());
+    setScaleFactor(theScaleFactor);
+  }
+}
+
+//==================================================================================================
+FeaturesAPI_Scale::FeaturesAPI_Scale(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                     const std::list<ModelHighAPI_Selection>& theMainObjects,
+                                     const ModelHighAPI_Selection& theCenterPoint,
+                                     const ModelHighAPI_Double& theScaleFactorX,
+                                     const ModelHighAPI_Double& theScaleFactorY,
+                                     const ModelHighAPI_Double& theScaleFactorZ)
+: ModelHighAPI_Interface(theFeature)
+{
+  if (initialize()) {
+    fillAttribute(theMainObjects, mainObjects());
+    fillAttribute(theCenterPoint, centerPoint());
+    setDimensions(theScaleFactorX, theScaleFactorY, theScaleFactorZ);
+  }
+}
+
+//==================================================================================================
+FeaturesAPI_Scale::~FeaturesAPI_Scale()
+{
+}
+
+//==================================================================================================
+void FeaturesAPI_Scale::setMainObjects(const std::list<ModelHighAPI_Selection>& theMainObjects)
+{
+  fillAttribute(theMainObjects, mainObjects());
+  execute();
+}
+
+//==================================================================================================
+void FeaturesAPI_Scale::setCenterPoint(const ModelHighAPI_Selection& theCenterPoint)
+{
+  fillAttribute(theCenterPoint, centerPoint());
+  execute();
+}
+
+//==================================================================================================
+void FeaturesAPI_Scale::setScaleFactor(const ModelHighAPI_Double& theScaleFactor)
+{
+  fillAttribute(FeaturesPlugin_Scale::CREATION_METHOD_BY_FACTOR(), creationMethod());
+  fillAttribute(theScaleFactor, scaleFactor());
+  execute();
+}
+
+//==================================================================================================
+void FeaturesAPI_Scale::setDimensions(const ModelHighAPI_Double& theScaleFactorX,
+                                      const ModelHighAPI_Double& theScaleFactorY,
+                                      const ModelHighAPI_Double& theScaleFactorZ)
+{
+  fillAttribute(FeaturesPlugin_Scale::CREATION_METHOD_BY_DIMENSIONS(), creationMethod());
+  fillAttribute(theScaleFactorX, scaleFactorX());
+  fillAttribute(theScaleFactorY, scaleFactorY());
+  fillAttribute(theScaleFactorZ, scaleFactorZ());
+  execute();
+}
+
+//==================================================================================================
+void FeaturesAPI_Scale::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  AttributeSelectionListPtr anAttrObjects =
+    aBase->selectionList(FeaturesPlugin_Scale::OBJECTS_LIST_ID());
+  theDumper << aBase << " = model.addScale(" << aDocName << ", " << anAttrObjects;
+
+  AttributeSelectionPtr anAttrPoint =
+    aBase->selection(FeaturesPlugin_Scale::CENTER_POINT_ID());
+  theDumper << " , " << anAttrPoint;
+
+  std::string aCreationMethod =
+    aBase->string(FeaturesPlugin_Scale::CREATION_METHOD())->value();
+
+  if (aCreationMethod == FeaturesPlugin_Scale::CREATION_METHOD_BY_FACTOR()) {
+    AttributeDoublePtr anAttrScaleFactor =
+      aBase->real(FeaturesPlugin_Scale::SCALE_FACTOR_ID());
+    theDumper << ", " << anAttrScaleFactor;
+  } else if (aCreationMethod == FeaturesPlugin_Scale::CREATION_METHOD_BY_DIMENSIONS()) {
+    AttributeDoublePtr anAttrScaleFactorX =
+      aBase->real(FeaturesPlugin_Scale::SCALE_FACTOR_X_ID());
+    AttributeDoublePtr anAttrScaleFactorY =
+      aBase->real(FeaturesPlugin_Scale::SCALE_FACTOR_Y_ID());
+    AttributeDoublePtr anAttrScaleFactorZ =
+      aBase->real(FeaturesPlugin_Scale::SCALE_FACTOR_Z_ID());
+    theDumper << ", " << anAttrScaleFactorX << " , " << anAttrScaleFactorY;
+    theDumper << ", " << anAttrScaleFactorZ;
+  }
+
+  theDumper << ")" << std::endl;
+}
+
+//==================================================================================================
+ScalePtr addScale(const std::shared_ptr<ModelAPI_Document>& thePart,
+                  const std::list<ModelHighAPI_Selection>& theMainObjects,
+                  const ModelHighAPI_Selection& theCenterPoint,
+                  const ModelHighAPI_Double& theScaleFactor)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(FeaturesAPI_Scale::ID());
+  return ScalePtr(new FeaturesAPI_Scale(aFeature, theMainObjects, theCenterPoint, theScaleFactor));
+}
+
+//==================================================================================================
+ScalePtr addScale(const std::shared_ptr<ModelAPI_Document>& thePart,
+                  const std::list<ModelHighAPI_Selection>& theMainObjects,
+                  const ModelHighAPI_Selection& theCenterPoint,
+                  const ModelHighAPI_Double& theScaleFactorX,
+                  const ModelHighAPI_Double& theScaleFactorY,
+                  const ModelHighAPI_Double& theScaleFactorZ)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(FeaturesAPI_Scale::ID());
+  return ScalePtr(new FeaturesAPI_Scale(aFeature, theMainObjects, theCenterPoint,
+                  theScaleFactorX, theScaleFactorY, theScaleFactorZ));
+}
\ No newline at end of file
diff --git a/src/FeaturesAPI/FeaturesAPI_Scale.h b/src/FeaturesAPI/FeaturesAPI_Scale.h
new file mode 100644 (file)
index 0000000..d53ff17
--- /dev/null
@@ -0,0 +1,112 @@
+// Copyright (C) 2014-201x CEA/DEN, EDF R&D -->
+
+// File:        FeaturesAPI_Scale.h
+// Created:     24 Jan 2017
+// Author:      Clarisse Genrault (CEA)
+
+#ifndef FEATURESAPI_SCALE_H_
+#define FEATURESAPI_SCALE_H_
+
+#include "FeaturesAPI.h"
+
+#include <FeaturesPlugin_Scale.h>
+
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
+
+class ModelHighAPI_Double;
+class ModelHighAPI_Dumper;
+class ModelHighAPI_Selection;
+
+/// \class FeaturesAPI_Scale
+/// \ingroup CPPHighAPI
+/// \brief Interface for Scale feature.
+class FeaturesAPI_Scale: public ModelHighAPI_Interface
+{
+public:
+  /// Constructor without values.
+  FEATURESAPI_EXPORT
+  explicit FeaturesAPI_Scale(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
+  /// Constructor with values.
+  FEATURESAPI_EXPORT
+  explicit FeaturesAPI_Scale(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                             const std::list<ModelHighAPI_Selection>& theMainObjects,
+                             const ModelHighAPI_Selection& theCenterPoint,
+                             const ModelHighAPI_Double& theScaleFactor);
+
+  /// Constructor with values.
+  FEATURESAPI_EXPORT
+  explicit FeaturesAPI_Scale(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                             const std::list<ModelHighAPI_Selection>& theMainObjects,
+                             const ModelHighAPI_Selection& theCenterPoint,
+                             const ModelHighAPI_Double& theScaleFactorX,
+                             const ModelHighAPI_Double& theScaleFactorY,
+                             const ModelHighAPI_Double& theScaleFactorZ);
+
+  /// Destructor.
+  FEATURESAPI_EXPORT
+  virtual ~FeaturesAPI_Scale();
+
+  INTERFACE_7(FeaturesPlugin_Scale::ID(),
+              creationMethod, FeaturesPlugin_Scale::CREATION_METHOD(),
+              ModelAPI_AttributeString, /** Creation method */,
+              mainObjects, FeaturesPlugin_Scale::OBJECTS_LIST_ID(),
+              ModelAPI_AttributeSelectionList, /** Main objects */,
+              centerPoint, FeaturesPlugin_Scale::CENTER_POINT_ID(),
+              ModelAPI_AttributeSelection, /** Center point */,
+              scaleFactor, FeaturesPlugin_Scale::SCALE_FACTOR_ID(),
+              ModelAPI_AttributeDouble, /** Scale factor */,
+              scaleFactorX, FeaturesPlugin_Scale::SCALE_FACTOR_X_ID(),
+              ModelAPI_AttributeDouble, /** Scale factor in X */,
+              scaleFactorY, FeaturesPlugin_Scale::SCALE_FACTOR_Y_ID(),
+              ModelAPI_AttributeDouble, /** Scale factor in Y */,
+              scaleFactorZ, FeaturesPlugin_Scale::SCALE_FACTOR_Z_ID(),
+              ModelAPI_AttributeDouble, /** Scale factor in Z */)
+
+  /// Set main objects.
+  FEATURESAPI_EXPORT
+  void setMainObjects(const std::list<ModelHighAPI_Selection>& theMainObjects);
+
+  /// Modify center_point attribute of the feature.
+  FEATURESAPI_EXPORT
+  void setCenterPoint(const ModelHighAPI_Selection& theCenterPoint);
+
+  /// Modify Creation Method and scale_factor attribute of the feature.
+  FEATURESAPI_EXPORT
+  void setScaleFactor(const ModelHighAPI_Double& theScaleFactor);
+
+  /// Modify Creation Method and scale_factor_x, scale_factor_y and scale_factor_z
+  /// attributes of the feature.
+  FEATURESAPI_EXPORT
+  void setDimensions(const ModelHighAPI_Double& theScaleFactorX,
+                     const ModelHighAPI_Double& theScaleFactorY,
+                     const ModelHighAPI_Double& theScaleFactorZ);
+
+  /// Dump wrapped feature
+  FEATURESAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+};
+
+/// Pointer on Scale object.
+typedef std::shared_ptr<FeaturesAPI_Scale> ScalePtr;
+
+/// \ingroup CPPHighAPI
+/// \brief Create Scale feature.
+FEATURESAPI_EXPORT
+ScalePtr addScale(const std::shared_ptr<ModelAPI_Document>& thePart,
+                  const std::list<ModelHighAPI_Selection>& theMainObjects,
+                  const ModelHighAPI_Selection& theCenterPoint,
+                  const ModelHighAPI_Double& theScaleFactor);
+
+/// \ingroup CPPHighAPI
+/// \brief Create Scale feature.
+FEATURESAPI_EXPORT
+ScalePtr addScale(const std::shared_ptr<ModelAPI_Document>& thePart,
+                  const std::list<ModelHighAPI_Selection>& theMainObjects,
+                  const ModelHighAPI_Selection& theCenterPoint,
+                  const ModelHighAPI_Double& theScaleFactorX,
+                  const ModelHighAPI_Double& theScaleFactorY,
+                  const ModelHighAPI_Double& theScaleFactorZ);
+
+#endif // FEATURESAPI_SCALE_H_
\ No newline at end of file
index cb100d4c4f273554ccf09c53b4afa68b3b2c588a..35a794d38406e00c935bce28f2ca134f65707a20 100644 (file)
@@ -22,6 +22,7 @@
   #include "FeaturesAPI_Revolution.h"
   #include "FeaturesAPI_RevolutionBoolean.h"
   #include "FeaturesAPI_Rotation.h"
+  #include "FeaturesAPI_Scale.h"
   #include "FeaturesAPI_Symmetry.h"
   #include "FeaturesAPI_Translation.h"
   #include "FeaturesAPI_Union.h"
diff --git a/src/FeaturesAPI/Test/APIParam_Scale.py b/src/FeaturesAPI/Test/APIParam_Scale.py
new file mode 100644 (file)
index 0000000..f0a33e0
--- /dev/null
@@ -0,0 +1,37 @@
+"""
+Test case for Scale feature. 
+Written on High API.
+"""
+from ModelAPI import *
+from GeomAPI import *
+
+from salome.shaper import model
+
+# Get session
+aSession = ModelAPI_Session.get()
+
+# Create a part
+aDocument = aSession.activeDocument()
+aSession.startOperation()
+model.addPart(aDocument)
+aDocument = aSession.activeDocument()
+aSession.finishOperation()
+
+# Create a box
+aSession.startOperation()
+aCenterPoint = model.addPoint(aDocument, 20, 20, 0).result()
+aBox1 =  model.addBox(aDocument, 10, 10, 10)
+aBox2 =  model.addBox(aDocument, 10, 10, 10)
+aSession.finishOperation()
+
+# Perform a symmetry by a point
+aSession.startOperation()
+aScale1 = model.addScale(aDocument, [model.selection("SOLID", "Box_1_1")], aCenterPoint, 2.0).result()
+aSession.finishOperation()
+assert (aScale1 is not None)
+
+# Perform a symmetry by an axis
+aSession.startOperation()
+aScale2 = model.addScale(aDocument, [model.selection("SOLID", "Box_2_1")], aCenterPoint, -0.5, 2, 3.7).result()
+aSession.finishOperation()
+assert (aScale2 is not None)
\ No newline at end of file
index 42e4c363b892337214a612e463621209fbe8c003..f04d203ab579a3da0f0daa8db6087b0819c3b751 100644 (file)
@@ -30,6 +30,7 @@ SET(PROJECT_HEADERS
     FeaturesPlugin_RemoveSubShapes.h
     FeaturesPlugin_Tools.h
     FeaturesPlugin_Symmetry.h
+    FeaturesPlugin_Scale.h
 )
 
 SET(PROJECT_SOURCES
@@ -58,6 +59,7 @@ SET(PROJECT_SOURCES
     FeaturesPlugin_RemoveSubShapes.cpp
     FeaturesPlugin_Tools.cpp
     FeaturesPlugin_Symmetry.cpp
+    FeaturesPlugin_Scale.cpp
 )
 
 SET(XML_RESOURCES
@@ -79,6 +81,7 @@ SET(XML_RESOURCES
   remove_subshapes_widget.xml
   union_widget.xml
   symmetry_widget.xml
+  scale_widget.xml
 )
 
 SET(TEXT_RESOURCES
index 89f735cf17c02791d371c91b126a835b81de56d7..4f1344b1d948c312cb220d3a4e670cb2a6e0f0a2 100644 (file)
 #include <FeaturesPlugin_RevolutionCut.h>
 #include <FeaturesPlugin_RevolutionFuse.h>
 #include <FeaturesPlugin_Rotation.h>
+#include <FeaturesPlugin_Scale.h>
+#include <FeaturesPlugin_Symmetry.h>
 #include <FeaturesPlugin_Union.h>
 #include <FeaturesPlugin_ValidatorTransform.h>
 #include <FeaturesPlugin_Validators.h>
-#include <FeaturesPlugin_Symmetry.h>
 
 #include <ModelAPI_Session.h>
 
@@ -102,6 +103,8 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(std::string theFeatureID)
     return FeaturePtr(new FeaturesPlugin_Union);
   } else if (theFeatureID == FeaturesPlugin_Symmetry::ID()) {
     return FeaturePtr(new FeaturesPlugin_Symmetry);
+  } else if (theFeatureID == FeaturesPlugin_Scale::ID()) {
+    return FeaturePtr(new FeaturesPlugin_Scale);
   }
 
   // feature of such kind is not found
diff --git a/src/FeaturesPlugin/FeaturesPlugin_Scale.cpp b/src/FeaturesPlugin/FeaturesPlugin_Scale.cpp
new file mode 100644 (file)
index 0000000..ee82f61
--- /dev/null
@@ -0,0 +1,267 @@
+// Copyright (C) 2014-201x CEA/DEN, EDF R&D
+
+// File:        FeaturesPlugin_Scale.cpp
+// Created:     13 Jan 2017
+// Author:      Clarisse Genrault (CEA)
+
+#include <FeaturesPlugin_Scale.h>
+
+#include <GeomAlgoAPI_PointBuilder.h>
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultPart.h>
+
+//=================================================================================================
+FeaturesPlugin_Scale::FeaturesPlugin_Scale()
+{
+}
+
+//=================================================================================================
+void FeaturesPlugin_Scale::initAttributes()
+{
+  data()->addAttribute(FeaturesPlugin_Scale::CREATION_METHOD(),
+                       ModelAPI_AttributeString::typeId());
+
+  AttributeSelectionListPtr aSelection =
+    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
+    FeaturesPlugin_Scale::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
+
+  data()->addAttribute(FeaturesPlugin_Scale::CENTER_POINT_ID(),
+                       ModelAPI_AttributeSelection::typeId());
+
+  data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_ID(),
+                       ModelAPI_AttributeDouble::typeId());
+
+  data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_X_ID(),
+                       ModelAPI_AttributeDouble::typeId());
+  data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_Y_ID(),
+                       ModelAPI_AttributeDouble::typeId());
+  data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_Z_ID(),
+                       ModelAPI_AttributeDouble::typeId());
+}
+
+//=================================================================================================
+void FeaturesPlugin_Scale::execute()
+{
+  AttributeStringPtr aMethodTypeAttr = string(FeaturesPlugin_Scale::CREATION_METHOD());
+  std::string aMethodType = aMethodTypeAttr->value();
+
+  if (aMethodType == FeaturesPlugin_Scale::CREATION_METHOD_BY_FACTOR()) {
+    performScaleByFactor();
+  }
+
+  if (aMethodType == FeaturesPlugin_Scale::CREATION_METHOD_BY_DIMENSIONS()) {
+    performScaleByDimensions();
+  }
+}
+
+//=================================================================================================
+void FeaturesPlugin_Scale::performScaleByFactor()
+{
+  // Getting objects.
+  ListOfShape anObjects;
+  std::list<ResultPtr> aContextes;
+  AttributeSelectionListPtr anObjectsSelList =
+    selectionList(FeaturesPlugin_Scale::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 the center point
+  std::shared_ptr<GeomAPI_Pnt> aCenterPoint;
+  std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
+    selection(FeaturesPlugin_Scale::CENTER_POINT_ID());
+  if (anObjRef.get() != NULL) {
+    GeomShapePtr aShape = anObjRef->value();
+    if (!aShape.get()) {
+      aShape = anObjRef->context()->shape();
+    }
+    if (aShape) {
+      aCenterPoint = GeomAlgoAPI_PointBuilder::point(aShape);
+    }
+  }
+
+  // Getting scale factor
+  double aScaleFactor = real(FeaturesPlugin_Scale::SCALE_FACTOR_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();
+
+    // Setting result.
+    if (isPart) {
+      std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
+      //aTrsf->setSymmetry(anAxis);
+      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_Scale aScaleAlgo(aBaseShape, aCenterPoint, aScaleFactor);
+
+      if (!aScaleAlgo.check()) {
+        setError(aScaleAlgo.getError());
+        return;
+      }
+
+      aScaleAlgo.build();
+
+      // Checking that the algorithm worked properly.
+      if(!aScaleAlgo.isDone()) {
+        static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
+        setError(aFeatureError);
+        break;
+      }
+      if(aScaleAlgo.shape()->isNull()) {
+        static const std::string aShapeError = "Error: Resulting shape is Null.";
+        setError(aShapeError);
+        break;
+      }
+      if(!aScaleAlgo.isValid()) {
+        std::string aFeatureError = "Error: Resulting shape is not valid.";
+        setError(aFeatureError);
+        break;
+      }
+
+      ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+      loadNamingDS(aScaleAlgo, aResultBody, aBaseShape);
+      setResult(aResultBody, aResultIndex);
+    }
+    aResultIndex++;
+  }
+
+  // Remove the rest results if there were produced in the previous pass.
+  removeResults(aResultIndex);
+}
+
+//=================================================================================================
+void FeaturesPlugin_Scale::performScaleByDimensions()
+{
+  // Getting objects.
+  ListOfShape anObjects;
+  std::list<ResultPtr> aContextes;
+  AttributeSelectionListPtr anObjectsSelList =
+    selectionList(FeaturesPlugin_Scale::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 the center point
+  std::shared_ptr<GeomAPI_Pnt> aCenterPoint;
+  std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
+    selection(FeaturesPlugin_Scale::CENTER_POINT_ID());
+  if (anObjRef.get() != NULL) {
+    GeomShapePtr aShape = anObjRef->value();
+    if (!aShape.get()) {
+      aShape = anObjRef->context()->shape();
+    }
+    if (aShape) {
+      aCenterPoint = GeomAlgoAPI_PointBuilder::point(aShape);
+    }
+  }
+
+  // Getting dimensions
+  double aScaleFactorX = real(FeaturesPlugin_Scale::SCALE_FACTOR_X_ID())->value();
+  double aScaleFactorY = real(FeaturesPlugin_Scale::SCALE_FACTOR_Y_ID())->value();
+  double aScaleFactorZ = real(FeaturesPlugin_Scale::SCALE_FACTOR_Z_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();
+
+    // Setting result.
+    if (isPart) {
+      std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
+      //aTrsf->setSymmetry(anAxis);
+      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_Scale aScaleAlgo(aBaseShape, aCenterPoint,
+                                   aScaleFactorX, aScaleFactorY, aScaleFactorZ);
+
+      if (!aScaleAlgo.check()) {
+        setError(aScaleAlgo.getError());
+        return;
+      }
+
+      aScaleAlgo.build();
+
+      // Checking that the algorithm worked properly.
+      if(!aScaleAlgo.isDone()) {
+        static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
+        setError(aFeatureError);
+        break;
+      }
+      if(aScaleAlgo.shape()->isNull()) {
+        static const std::string aShapeError = "Error: Resulting shape is Null.";
+        setError(aShapeError);
+        break;
+      }
+      if(!aScaleAlgo.isValid()) {
+        std::string aFeatureError = "Error: Resulting shape is not valid.";
+        setError(aFeatureError);
+        break;
+      }
+
+      ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+      loadNamingDS(aScaleAlgo, aResultBody, aBaseShape);
+      setResult(aResultBody, aResultIndex);
+    }
+    aResultIndex++;
+  }
+
+  // Remove the rest results if there were produced in the previous pass.
+  removeResults(aResultIndex);
+}
+
+//=================================================================================================
+void FeaturesPlugin_Scale::loadNamingDS(GeomAlgoAPI_Scale& theScaleAlgo,
+                                        std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+                                        std::shared_ptr<GeomAPI_Shape> theBaseShape)
+{
+  // Store and name the result.
+  theResultBody->storeModified(theBaseShape, theScaleAlgo.shape());
+
+  // Name the faces
+  std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theScaleAlgo.mapOfSubShapes();
+  int aReflectedTag = 1;
+  std::string aReflectedName = "Scaled";
+  theResultBody->loadAndOrientModifiedShapes(&theScaleAlgo,
+                                              theBaseShape, GeomAPI_Shape::FACE,
+                                              aReflectedTag, aReflectedName, *aSubShapes.get());
+}
\ No newline at end of file
diff --git a/src/FeaturesPlugin/FeaturesPlugin_Scale.h b/src/FeaturesPlugin/FeaturesPlugin_Scale.h
new file mode 100644 (file)
index 0000000..71bf032
--- /dev/null
@@ -0,0 +1,122 @@
+// Copyright (C) 2014-201x CEA/DEN, EDF R&D
+
+// File:        FeaturesPlugin_Scale.h
+// Created:     13 Jan 2017
+// Author:      Clarisse Genrault (CEA)
+
+#ifndef FEATURESPLUGIN_SCALE_H_
+#define FEATURESPLUGIN_SCALE_H_
+
+#include <FeaturesPlugin.h>
+
+#include <ModelAPI_Feature.h>
+
+#include <GeomAlgoAPI_Scale.h>
+
+/** \class FeaturesPlugin_Scale
+ *  \ingroup Plugins
+ *  \brief Feature for changing the scale of an object.
+ */
+class FeaturesPlugin_Scale : public ModelAPI_Feature
+{
+ public:
+  /// Scale kind.
+  inline static const std::string& ID()
+  {
+    static const std::string MY_SCALE_ID("Scale");
+    return MY_SCALE_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 "ByFactor".
+  inline static const std::string& CREATION_METHOD_BY_FACTOR()
+  {
+    static const std::string MY_CREATION_METHOD_ID("ByFactor");
+    return MY_CREATION_METHOD_ID;
+  }
+
+  /// Attribute name for creation method "ByFactor".
+  inline static const std::string& CREATION_METHOD_BY_DIMENSIONS()
+  {
+    static const std::string MY_CREATION_METHOD_ID("ByDimensions");
+    return MY_CREATION_METHOD_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 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 scale factor.
+  inline static const std::string& SCALE_FACTOR_ID()
+  {
+    static const std::string MY_SCALE_FACTOR_ID("scale_factor");
+    return MY_SCALE_FACTOR_ID;
+  }
+
+  /// Attribute name of scale factor in X.
+  inline static const std::string& SCALE_FACTOR_X_ID()
+  {
+    static const std::string MY_SCALE_FACTOR_X_ID("scale_factor_x");
+    return MY_SCALE_FACTOR_X_ID;
+  }
+
+  /// Attribute name of scale factor in Y.
+  inline static const std::string& SCALE_FACTOR_Y_ID()
+  {
+    static const std::string MY_SCALE_FACTOR_Y_ID("scale_factor_y");
+    return MY_SCALE_FACTOR_Y_ID;
+  }
+
+  /// Attribute name of scale factor in Z.
+  inline static const std::string& SCALE_FACTOR_Z_ID()
+  {
+    static const std::string MY_SCALE_FACTOR_Z_ID("scale_factor_z");
+    return MY_SCALE_FACTOR_Z_ID;
+  }
+
+  /// \return the kind of a feature.
+  FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    static std::string MY_KIND = FeaturesPlugin_Scale::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_Scale();
+
+private:
+  /// Perform scale using a central point and a value of the scale.
+  void performScaleByFactor();
+
+  /// Perform symmetry using a central point and three dimensions
+  void performScaleByDimensions();
+
+  /// Perform the naming
+  void loadNamingDS(GeomAlgoAPI_Scale& theScaleAlgo,
+                    std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+                    std::shared_ptr<GeomAPI_Shape> theBaseShape);
+};
+
+#endif // FEATURESPLUGIN_SCALE_H_
\ No newline at end of file
diff --git a/src/FeaturesPlugin/icons/SVG/scale.svg b/src/FeaturesPlugin/icons/SVG/scale.svg
new file mode 100644 (file)
index 0000000..6e8d4c0
--- /dev/null
@@ -0,0 +1,332 @@
+<?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="16"
+   height="16"
+   id="svg5187"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   viewBox="0 0 16 16"
+   sodipodi:docname="scale_cla.svg"
+   inkscape:export-filename="/export/home/cgenraul/SHAPER-CEA-FD20_64/INSTALL/SHAPER/share/salome/resources/shaper/icons/Features/scale.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90">
+  <defs
+     id="defs5189">
+    <filter
+       inkscape:label="Pixellize"
+       inkscape:menu="Pixel tools"
+       inkscape:menu-tooltip="Reduce or remove antialiasing around shapes"
+       style="color-interpolation-filters:sRGB"
+       id="filter5039-5">
+      <feColorMatrix
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1000 -500 "
+         id="feColorMatrix5041-7" />
+    </filter>
+    <filter
+       inkscape:label="Pixellize"
+       inkscape:menu="Pixel tools"
+       inkscape:menu-tooltip="Reduce or remove antialiasing around shapes"
+       style="color-interpolation-filters:sRGB"
+       id="filter5039-1">
+      <feColorMatrix
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1000 -500 "
+         id="feColorMatrix5041-6" />
+    </filter>
+    <filter
+       inkscape:label="Pixellize"
+       inkscape:menu="Pixel tools"
+       inkscape:menu-tooltip="Reduce or remove antialiasing around shapes"
+       style="color-interpolation-filters:sRGB"
+       id="filter5039">
+      <feColorMatrix
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1000 -500 "
+         id="feColorMatrix5041" />
+    </filter>
+    <filter
+       inkscape:label="Pixellize"
+       inkscape:menu="Pixel tools"
+       inkscape:menu-tooltip="Reduce or remove antialiasing around shapes"
+       style="color-interpolation-filters:sRGB"
+       id="filter5039-5-5">
+      <feColorMatrix
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1000 -500 "
+         id="feColorMatrix5041-7-9" />
+    </filter>
+    <filter
+       inkscape:label="Pixellize"
+       inkscape:menu="Pixel tools"
+       inkscape:menu-tooltip="Reduce or remove antialiasing around shapes"
+       style="color-interpolation-filters:sRGB"
+       id="filter5039-1-2">
+      <feColorMatrix
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1000 -500 "
+         id="feColorMatrix5041-6-5" />
+    </filter>
+    <filter
+       inkscape:label="Pixellize"
+       inkscape:menu="Pixel tools"
+       inkscape:menu-tooltip="Reduce or remove antialiasing around shapes"
+       style="color-interpolation-filters:sRGB"
+       id="filter5039-51">
+      <feColorMatrix
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1000 -500 "
+         id="feColorMatrix5041-76" />
+    </filter>
+    <filter
+       inkscape:label="Pixellize"
+       inkscape:menu="Pixel tools"
+       inkscape:menu-tooltip="Reduce or remove antialiasing around shapes"
+       style="color-interpolation-filters:sRGB"
+       id="filter5039-5-1">
+      <feColorMatrix
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1000 -500 "
+         id="feColorMatrix5041-7-2" />
+    </filter>
+    <filter
+       inkscape:label="Pixellize"
+       inkscape:menu="Pixel tools"
+       inkscape:menu-tooltip="Reduce or remove antialiasing around shapes"
+       style="color-interpolation-filters:sRGB"
+       id="filter5039-1-6">
+      <feColorMatrix
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1000 -500 "
+         id="feColorMatrix5041-6-2" />
+    </filter>
+    <filter
+       inkscape:label="Pixellize"
+       inkscape:menu="Pixel tools"
+       inkscape:menu-tooltip="Reduce or remove antialiasing around shapes"
+       style="color-interpolation-filters:sRGB"
+       id="filter5039-9">
+      <feColorMatrix
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1000 -500 "
+         id="feColorMatrix5041-9" />
+    </filter>
+    <filter
+       color-interpolation-filters="sRGB"
+       inkscape:label="Pixellize"
+       inkscape:menu="Pixel tools"
+       inkscape:menu-tooltip="Reduce or remove antialiasing around shapes"
+       id="filter5039-51-0">
+      <feColorMatrix
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1000 -500 "
+         id="feColorMatrix5041-76-7" />
+    </filter>
+    <filter
+       color-interpolation-filters="sRGB"
+       inkscape:label="Pixellize"
+       inkscape:menu="Pixel tools"
+       inkscape:menu-tooltip="Reduce or remove antialiasing around shapes"
+       id="filter5039-1-2-4">
+      <feColorMatrix
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1000 -500 "
+         id="feColorMatrix5041-6-5-0" />
+    </filter>
+    <filter
+       color-interpolation-filters="sRGB"
+       inkscape:label="Pixellize"
+       inkscape:menu="Pixel tools"
+       inkscape:menu-tooltip="Reduce or remove antialiasing around shapes"
+       id="filter5039-5-5-3">
+      <feColorMatrix
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1000 -500 "
+         id="feColorMatrix5041-7-9-6" />
+    </filter>
+    <filter
+       color-interpolation-filters="sRGB"
+       inkscape:label="Pixellize"
+       inkscape:menu="Pixel tools"
+       inkscape:menu-tooltip="Reduce or remove antialiasing around shapes"
+       id="filter5039-9-1">
+      <feColorMatrix
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1000 -500 "
+         id="feColorMatrix5041-9-0" />
+    </filter>
+    <filter
+       color-interpolation-filters="sRGB"
+       inkscape:label="Pixellize"
+       inkscape:menu="Pixel tools"
+       inkscape:menu-tooltip="Reduce or remove antialiasing around shapes"
+       id="filter5039-1-6-4">
+      <feColorMatrix
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1000 -500 "
+         id="feColorMatrix5041-6-2-8" />
+    </filter>
+    <filter
+       color-interpolation-filters="sRGB"
+       inkscape:label="Pixellize"
+       inkscape:menu="Pixel tools"
+       inkscape:menu-tooltip="Reduce or remove antialiasing around shapes"
+       id="filter5039-5-1-3">
+      <feColorMatrix
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1000 -500 "
+         id="feColorMatrix5041-7-2-0" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="32"
+     inkscape:cx="4.091365"
+     inkscape:cy="1.7382622"
+     inkscape:current-layer="g4157"
+     showgrid="true"
+     inkscape:grid-bbox="true"
+     inkscape:document-units="px"
+     inkscape:window-width="1920"
+     inkscape:window-height="1110"
+     inkscape:window-x="-2"
+     inkscape:window-y="32"
+     inkscape:window-maximized="1"
+     inkscape:snap-object-midpoints="true"
+     inkscape:snap-grids="true"
+     inkscape:snap-global="false"
+     showborder="true"
+     inkscape:showpageshadow="false">
+    <inkscape:grid
+       type="xygrid"
+       id="grid5735"
+       empspacing="5"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata5192">
+    <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></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     id="layer1"
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     transform="translate(0,-16)">
+    <g
+       transform="matrix(0.63448229,0,0,0.66946808,-4.3899484,25.170817)"
+       id="g4929">
+      <g
+         transform="matrix(1.9791667,0,0,1.7986112,14.390346,-26.351415)"
+         id="g4929-2">
+        <path
+           sodipodi:nodetypes="ccccccc"
+           style="fill:#b7d9ea;fill-opacity:1;fill-rule:evenodd;stroke:none"
+           d="m -0.04504951,16.04505 0,-8.0000005 4.00000001,0 0,4.0000005 4,0 0,4 z"
+           id="path4836-9"
+           inkscape:connector-curvature="0" />
+        <path
+           sodipodi:nodetypes="ccccccccccc"
+           style="fill:#1b4955;fill-opacity:1;fill-rule:evenodd;stroke:none"
+           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-1"
+           inkscape:connector-curvature="0" />
+      </g>
+      <g
+         id="g4157"
+         transform="matrix(1.0416667,0,0,1.138889,7.0643776,-8.1659798)">
+        <path
+           inkscape:connector-curvature="0"
+           id="path4836"
+           d="m -0.09233215,16.086036 0,-7.7540824 4.02364135,0 0,3.8770414 4.0236413,0 0,3.877041 z"
+           style="fill:#b7d9ea;fill-opacity:1;fill-rule:evenodd;stroke:none"
+           sodipodi:nodetypes="ccccccc" />
+        <path
+           inkscape:connector-curvature="0"
+           id="path4838"
+           d="m 0.95495049,7.3729399 -1.04728264,1.1502831 4.00000005,0 0,3.781407 4,0 0,3.781406 1.5673917,-0.74042 0,-4.396201 -4.0472826,0 0.047283,-3.5764751 z"
+           style="fill:#1b4955;fill-opacity:1;fill-rule:evenodd;stroke:none"
+           sodipodi:nodetypes="ccccccccccc" />
+        <path
+           style="fill:#fecc02;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.49498981;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+           d="M 0.43176439,5.5504343 3.0658515,2.4423037 1.9622047,1.7879886 6.0758265,0.23284672 5.6790852,3.9916072 4.5817809,3.3410498 1.9526269,6.4629967 z"
+           id="path7489"
+           inkscape:connector-curvature="0" />
+        <path
+           style="fill:#fecc02;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.7043528;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+           d="m -36.429984,4.7088008 4.529681,-3.91662105 -1.330539,-1.1533572 6.117421,-1.40524255 -1.63641,5.2895453 -1.322892,-1.1467325 -4.526892,3.9373319 z"
+           id="path7489-1"
+           inkscape:connector-curvature="0" />
+      </g>
+    </g>
+    <g
+       id="g4174"
+       transform="matrix(0.98480776,0.17364818,-0.17364818,0.98480776,-36.722922,-4.2807752)">
+      <g
+         id="g4203"
+         transform="matrix(0.66631551,0.12829473,-0.1174894,0.72759554,20.163784,10.26169)">
+        <rect
+           transform="matrix(1.2338926,-0.21756856,0.17138179,0.97195444,4.642175,29.656091)"
+           y="0.19999999"
+           x="0.19999999"
+           height="3.7633102"
+           width="1.4661478"
+           id="rect4199-9-3"
+           style="fill:#fecc02;fill-opacity:1;stroke:#000000;stroke-width:0.39999998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:16.58592415;filter:url(#filter5039-51-0)" />
+        <rect
+           transform="matrix(1.2338926,-0.21756856,0.17138179,0.97195444,5.594284,35.167226)"
+           y="0.19999999"
+           x="0.19999999"
+           height="3.7633102"
+           width="1.4661478"
+           id="rect4199-9-8-2"
+           style="fill:#fecc02;fill-opacity:1;stroke:#000000;stroke-width:0.38157293;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:16.58592415;filter:url(#filter5039-1-2-4)" />
+        <rect
+           transform="matrix(1.2338926,-0.21756856,0.17138179,0.97195444,3.64053,24.270381)"
+           y="0.19999999"
+           x="0.19999999"
+           height="3.7633102"
+           width="1.4661478"
+           id="rect4199-9-2-5"
+           style="fill:#fecc02;fill-opacity:1;stroke:#000000;stroke-width:0.39999998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:16.58592415;filter:url(#filter5039-5-5-3)" />
+      </g>
+      <g
+         id="g4230"
+         transform="matrix(0.20877417,0.62707939,-0.70901103,0.27752298,52.430494,19.461286)"
+         style="stroke-width:0.28212538;stroke-miterlimit:4;stroke-dasharray:none">
+        <rect
+           transform="matrix(1.2338926,-0.21756856,0.17138179,0.97195444,12.700519,36.485529)"
+           y="0.19999999"
+           x="0.19999999"
+           height="3.7633102"
+           width="1.4661478"
+           id="rect4199-9"
+           style="fill:#fecc02;fill-opacity:1;stroke:#000000;stroke-width:0.3805601;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:16.58592415;filter:url(#filter5039-9-1)" />
+        <rect
+           transform="matrix(1.2338926,-0.21756856,0.17138179,0.97195444,13.652628,41.996664)"
+           y="0.19999999"
+           x="0.19999999"
+           height="3.7633102"
+           width="1.4661478"
+           id="rect4199-9-8"
+           style="fill:#fecc02;fill-opacity:1;stroke:#000000;stroke-width:0.3805601;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:16.58592415;filter:url(#filter5039-1-6-4)" />
+        <rect
+           transform="matrix(1.2338926,-0.21756856,0.17138179,0.97195444,11.698874,31.099819)"
+           y="0.19999999"
+           x="0.19999999"
+           height="3.7633102"
+           width="1.4661478"
+           id="rect4199-9-2"
+           style="fill:#fecc02;fill-opacity:1;stroke:#000000;stroke-width:0.3805601;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:16.58592415;filter:url(#filter5039-5-1-3)" />
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/src/FeaturesPlugin/icons/SVG/scale_dimensions_32x32.svg b/src/FeaturesPlugin/icons/SVG/scale_dimensions_32x32.svg
new file mode 100644 (file)
index 0000000..f017244
--- /dev/null
@@ -0,0 +1,102 @@
+<?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="svg5924"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   viewBox="0 0 32 32"
+   sodipodi:docname="scale_along_axes_32x32.svg"
+   inkscape:export-filename="/export/home/ldigallo/DOC_ALYOTECH/icones/Transformations/scale_along_axes_32x32.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90">
+  <defs
+     id="defs5926" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="22.395604"
+     inkscape:cx="3.866323"
+     inkscape:cy="13.387727"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:grid-bbox="true"
+     inkscape:document-units="px"
+     inkscape:snap-object-midpoints="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1006"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:window-maximized="1">
+    <inkscape:grid
+       type="xygrid"
+       id="grid6472" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata5929">
+    <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">
+    <circle
+       style="opacity:1;fill:#b7d9ea;fill-opacity:1;stroke:#1b4955;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="path6474"
+       cx="8.7674179"
+       cy="18.544161"
+       r="3.0553663" />
+    <g
+       transform="translate(0,17)"
+       id="g4195-7">
+      <path
+         inkscape:connector-curvature="0"
+         id="path7134-4"
+         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>
+    <ellipse
+       style="opacity:1;fill:#b7d9ea;fill-opacity:1;stroke:#1b4955;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="path6474-4"
+       cx="19.151121"
+       cy="4.3449473"
+       rx="11.427674"
+       ry="2.8569186" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0"
+       d="M 7,4 2,30"
+       id="path6584"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:2,1;stroke-dashoffset:0"
+       d="M 31,5 2,30"
+       id="path6586"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/src/FeaturesPlugin/icons/SVG/scale_factor_32x32.svg b/src/FeaturesPlugin/icons/SVG/scale_factor_32x32.svg
new file mode 100644 (file)
index 0000000..39c7bc7
--- /dev/null
@@ -0,0 +1,101 @@
+<?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="svg5924"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   viewBox="0 0 32 32"
+   sodipodi:docname="scale_32x32.svg"
+   inkscape:export-filename="/export/home/ldigallo/DOC_ALYOTECH/icones/Transformations/scale_32x32.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90">
+  <defs
+     id="defs5926" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="22.395604"
+     inkscape:cx="5.622915"
+     inkscape:cy="16.959857"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:grid-bbox="true"
+     inkscape:document-units="px"
+     inkscape:snap-object-midpoints="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1006"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:window-maximized="1">
+    <inkscape:grid
+       type="xygrid"
+       id="grid6472" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata5929">
+    <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">
+    <circle
+       style="opacity:1;fill:#b7d9ea;fill-opacity:1;stroke:#1b4955;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="path6474"
+       cx="11.491167"
+       cy="20.776743"
+       r="2.8569186" />
+    <circle
+       style="opacity:1;fill:#b7d9ea;fill-opacity:1;stroke:#1b4955;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="path6474-6"
+       cx="22"
+       cy="10"
+       r="8.3168182" />
+    <g
+       transform="translate(0,17)"
+       id="g4195-7">
+      <path
+         inkscape:connector-curvature="0"
+         id="path7134-4"
+         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>
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:2,1;stroke-dashoffset:0"
+       d="M 2,30 15,4"
+       id="path6512"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0"
+       d="M 2,30 29,17"
+       id="path6514"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/src/FeaturesPlugin/icons/scale.png b/src/FeaturesPlugin/icons/scale.png
new file mode 100644 (file)
index 0000000..156659c
Binary files /dev/null and b/src/FeaturesPlugin/icons/scale.png differ
diff --git a/src/FeaturesPlugin/icons/scale_dimensions_32x32.png b/src/FeaturesPlugin/icons/scale_dimensions_32x32.png
new file mode 100644 (file)
index 0000000..b5204f9
Binary files /dev/null and b/src/FeaturesPlugin/icons/scale_dimensions_32x32.png differ
diff --git a/src/FeaturesPlugin/icons/scale_factor_32x32.png b/src/FeaturesPlugin/icons/scale_factor_32x32.png
new file mode 100644 (file)
index 0000000..b82b643
Binary files /dev/null and b/src/FeaturesPlugin/icons/scale_factor_32x32.png differ
index cade0deccbb757d10ff61aa956b0d61490895531..65488474bfc7e008b83aae9808fcc3057efcd8d0 100644 (file)
@@ -71,6 +71,9 @@
       <feature id="Symmetry" title="Symmetry" tooltip="Perform symmetry with respect to a point, an axis or a plane" icon="icons/Features/symmetry.png">
         <source path="symmetry_widget.xml"/>
       </feature>
+      <feature id="Scale" title="Scale" tooltip="Perform scale an objects" icon="icons/Features/scale.png">
+        <source path="scale_widget.xml"/>
+      </feature>
     </group>
   </workbench>
 </plugin>
diff --git a/src/FeaturesPlugin/scale_widget.xml b/src/FeaturesPlugin/scale_widget.xml
new file mode 100644 (file)
index 0000000..3f6f812
--- /dev/null
@@ -0,0 +1,76 @@
+<!-- Copyright (C) 2014-201x CEA/DEN, EDF R&D -->
+
+<source>
+  <toolbox id="CreationMethod">
+    <box id="ByFactor"
+         title="By one common factor for the three directions"
+         icon="icons/Features/scale_factor_32x32.png">
+      <multi_selector id="main_objects"
+                      label="Main objects"
+                      icon=""
+                      tooltip="Select objects"
+                      type_choice="objects"
+                      concealment="true">
+        <validator id="FeaturesPlugin_ValidatorTransform"/>
+      </multi_selector>
+      <shape_selector id="center_point"
+                      icon=""
+                      label="Center point"
+                      tooltip="Select the center point"
+                      shape_types="vertex"
+                      default="">
+        <validator id="GeomValidators_ShapeType" parameters="vertex"/>
+        <validator id="GeomValidators_ConstructionComposite"/>
+      </shape_selector>
+      <doublevalue
+          id="scale_factor"
+          label="Scale factor"
+          step="1."
+          default="2."
+          tooltip="Scale factor">
+      </doublevalue>
+    </box>
+    <box id="ByDimensions"
+         title="Different factors for the three directions"
+         icon="icons/Features/scale_dimensions_32x32.png">
+      <multi_selector id="main_objects"
+                      label="Main objects"
+                      icon=""
+                      tooltip="Select objects"
+                      type_choice="objects"
+                      concealment="true">
+        <validator id="FeaturesPlugin_ValidatorTransform"/>
+      </multi_selector>
+      <shape_selector id="center_point"
+                      icon=""
+                      label="Center point"
+                      tooltip="Select the center point"
+                      shape_types="vertex"
+                      default="">
+        <validator id="GeomValidators_ShapeType" parameters="vertex"/>
+        <validator id="GeomValidators_ConstructionComposite"/>
+      </shape_selector>
+      <doublevalue
+          id="scale_factor_x"
+          label="Scale factor in X"
+          step="1."
+          default="2."
+          tooltip="Scale factor in X">
+      </doublevalue>
+      <doublevalue
+          id="scale_factor_y"
+          label="Scale factor in Y"
+          step="1."
+          default="2."
+          tooltip="Scale factor in Y">
+      </doublevalue>
+      <doublevalue
+          id="scale_factor_z"
+          label="Scale factor in Z"
+          step="1."
+          default="2."
+          tooltip="Scale factor in Z">
+      </doublevalue>
+    </box>
+  </toolbox>
+</source>
\ No newline at end of file
index 68048d8e9c858202525e6d5b11ee27653ba515eb..352e5738d62924973eb000cfdf200efc032327b3 100644 (file)
@@ -49,6 +49,7 @@ SET(PROJECT_HEADERS
     GeomAlgoAPI_Copy.h
     GeomAlgoAPI_ConeSegment.h
     GeomAlgoAPI_Symmetry.h
+    GeomAlgoAPI_Scale.h
 )
 
 SET(PROJECT_SOURCES
@@ -93,6 +94,7 @@ SET(PROJECT_SOURCES
     GeomAlgoAPI_Copy.cpp
     GeomAlgoAPI_ConeSegment.cpp
     GeomAlgoAPI_Symmetry.cpp
+    GeomAlgoAPI_Scale.cpp
 )
 
 SET(PROJECT_LIBRARIES
@@ -161,6 +163,7 @@ INSTALL(FILES ${SWIG_SCRIPTS} DESTINATION ${SHAPER_INSTALL_SWIG})
 ADD_UNIT_TESTS(TestAPI_Box.py
                TestAPI_Cylinder.py
                TestAPI_GDMLConeSegment.py
+               TestAPI_Scale.py
                TestAPI_Symmetry.py
                TestAPI_Translation.py)
 
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Scale.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Scale.cpp
new file mode 100644 (file)
index 0000000..bfdd1d0
--- /dev/null
@@ -0,0 +1,184 @@
+// Copyright (C) 2014-201x CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_Scale.cpp
+// Created:     23 Jan 2017
+// Author:      Clarisse Genrault (CEA)
+
+#include "GeomAlgoAPI_Scale.h"
+
+#include <BRepBuilderAPI_Transform.hxx>
+#include <BRepBuilderAPI_GTransform.hxx>
+
+//=================================================================================================
+GeomAlgoAPI_Scale::GeomAlgoAPI_Scale(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                     std::shared_ptr<GeomAPI_Pnt>   theCenterPoint,
+                                     double theScaleFactor)
+{
+  myMethodType = BY_FACTOR;
+  mySourceShape = theSourceShape;
+  myCenterPoint = theCenterPoint;
+  myScaleFactor = theScaleFactor;
+}
+
+//=================================================================================================
+GeomAlgoAPI_Scale::GeomAlgoAPI_Scale(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                     std::shared_ptr<GeomAPI_Pnt>   theCenterPoint,
+                                     double theScaleFactorX,
+                                     double theScaleFactorY,
+                                     double theScaleFactorZ)
+{
+  myMethodType = BY_DIMENSIONS;
+  mySourceShape = theSourceShape;
+  myCenterPoint = theCenterPoint;
+  myScaleFactorX = theScaleFactorX;
+  myScaleFactorY = theScaleFactorY;
+  myScaleFactorZ = theScaleFactorZ;
+}
+
+//=================================================================================================
+bool GeomAlgoAPI_Scale::check()
+{
+  if (!mySourceShape) {
+    myError = "Scale builder :: source shape is invalid.";
+    return false;
+  }
+  if (!myCenterPoint) {
+    myError = "Scale builder :: center point is invalid.";
+    return false;
+  }
+  switch (myMethodType) {
+    case BY_FACTOR: {
+      if (fabs(myScaleFactor) < Precision::Confusion()) {
+        myError = "Scale builder :: the scale factor is null.";
+        return false;
+      }
+      return true;
+    }
+    case BY_DIMENSIONS: {
+      if (fabs(myScaleFactorX) < Precision::Confusion()) {
+        myError = "Scale builder :: the scale factor in X is null.";
+        return false;
+      }
+      if (fabs(myScaleFactorY) < Precision::Confusion()) {
+        myError = "Scale builder :: the scale factor in Y is null.";
+        return false;
+      }
+      if (fabs(myScaleFactorZ) < Precision::Confusion()) {
+        myError = "Scale builder :: the scale factor in Z is null.";
+        return false;
+      }
+      return true;
+    }
+    default: {
+      myError = "Scale builder :: method not implemented.";
+      return false;
+    }
+  }
+}
+
+//=================================================================================================
+void GeomAlgoAPI_Scale::build()
+{
+  switch (myMethodType) {
+   case BY_FACTOR : {
+     buildByFactor();
+     break;
+   }
+   case BY_DIMENSIONS : {
+     buildByDimensions();
+     break;
+   }
+   default : {
+     myError = "Scale builder :: method not yet implemented";
+     return;
+   }
+  }
+}
+
+//=================================================================================================
+void GeomAlgoAPI_Scale::buildByFactor()
+{
+  const gp_Pnt& aCenterPoint = myCenterPoint->impl<gp_Pnt>();
+  gp_Trsf* aTrsf = new gp_Trsf();
+  aTrsf->SetScale(aCenterPoint, myScaleFactor);
+
+  const TopoDS_Shape& aSourceShape = mySourceShape->impl<TopoDS_Shape>();
+
+  if(aSourceShape.IsNull()) {
+    myError = "Scale builder :: source shape does not contain any actual shape.";
+    return;
+  }
+
+  // Transform the shape while copying it.
+  BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, *aTrsf, true);
+  if(!aBuilder) {
+    myError = "Scale builder :: transform initialization failed.";
+    return;
+  }
+
+  setImpl(aBuilder);
+  setBuilderType(OCCT_BRepBuilderAPI_MakeShape);
+
+  if(!aBuilder->IsDone()) {
+    myError = "Scale builder :: algorithm failed.";
+    return;
+  }
+
+  TopoDS_Shape aResult = aBuilder->Shape();
+
+  std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+  aShape->setImpl(new TopoDS_Shape(aResult));
+  setShape(aShape);
+  setDone(true);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_Scale::buildByDimensions()
+{
+  const gp_Pnt& aCenterPoint = myCenterPoint->impl<gp_Pnt>();
+
+  // Perform the rotation matrix
+  gp_Mat aMatRot(myScaleFactorX, 0., 0.,
+                 0., myScaleFactorY, 0.,
+                 0., 0., myScaleFactorZ);
+
+  // Perform the tranformation
+  gp_Pnt anOriginPnt(0., 0., 0.);
+  gp_GTrsf aGTrsf;
+  gp_GTrsf aGTrsfP0;
+  gp_GTrsf aGTrsf0P;
+  aGTrsfP0.SetTranslationPart(anOriginPnt.XYZ() - aCenterPoint.XYZ());
+  aGTrsf0P.SetTranslationPart(aCenterPoint.XYZ());
+  aGTrsf.SetVectorialPart(aMatRot);
+  aGTrsf = aGTrsf0P.Multiplied(aGTrsf);
+  aGTrsf = aGTrsf.Multiplied(aGTrsfP0);
+
+  const TopoDS_Shape& aSourceShape = mySourceShape->impl<TopoDS_Shape>();
+
+  if(aSourceShape.IsNull()) {
+    myError = "Scale builder :: source shape does not contain any actual shape.";
+    return;
+  }
+
+  // Transform the shape while copying it.
+  BRepBuilderAPI_GTransform* aBuilder = new BRepBuilderAPI_GTransform(aSourceShape, aGTrsf, true);
+  if(!aBuilder) {
+    myError = "Scale builder :: transform initialization failed.";
+    return;
+  }
+
+  setImpl(aBuilder);
+  setBuilderType(OCCT_BRepBuilderAPI_MakeShape);
+
+  if(!aBuilder->IsDone()) {
+    myError = "Scale builder :: algorithm failed.";
+    return;
+  }
+
+  TopoDS_Shape aResult = aBuilder->Shape();
+
+  std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+  aShape->setImpl(new TopoDS_Shape(aResult));
+  setShape(aShape);
+  setDone(true);
+}
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Scale.h b/src/GeomAlgoAPI/GeomAlgoAPI_Scale.h
new file mode 100644 (file)
index 0000000..3fcb1c4
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright (C) 2014-201x CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_Scale.h
+// Created:     23 Jan 2017
+// Author:      Clarisse Genrault (CEA)
+
+#ifndef GEOMALGOAPI_SCALE_H_
+#define GEOMALGOAPI_SCALE_H_
+
+#include <GeomAlgoAPI_MakeShape.h>
+
+#include <GeomAPI_Pnt.h>
+
+/// \class GeomAlgoAPI_Scale
+/// \ingroup DataAlgo
+/// \brief Creates a copy of the object by performing a scale operation by a factor or
+///        by dimensions.
+class GeomAlgoAPI_Scale : public GeomAlgoAPI_MakeShape
+{
+public:
+  /// Type of scale operation
+  enum MethodType {
+    BY_FACTOR,     ///< Scale by factor.
+    BY_DIMENSIONS, ///< Scale by dimensions.
+  };
+
+  /// \brief Creates an object which is obtained from current object by performing
+  ///        a scale operation by a factor.
+  /// \param[in] theSourceShape  the shape to be moved.
+  /// \param[in] theCenterPoint  the center point.
+  /// \param[in] theFactor       the scale factor.
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_Scale(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                       std::shared_ptr<GeomAPI_Pnt>   theCenterPoint,
+                                       double                         theScaleFactor);
+
+  /// \brief Creates an object which is obtained from current object by performing
+  ///        a scale operation by dimensions.
+  /// \param[in] theSourceShape  the shape to be moved.
+  /// \param[in] theCenterPoint  the center point.
+  /// \param[in] theFactorX      the scale factor in X.
+  /// \param[in] theFactorY      the scale factor in Y.
+  /// \param[in] theFactorZ      the scale factor in Z.
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_Scale(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                       std::shared_ptr<GeomAPI_Pnt>   theCenterPoint,
+                                       double                         theScaleFactorX,
+                                       double                         theScaleFactorY,
+                                       double                         theScaleFactorZ);
+
+  /// Checks if data for the scale transform is OK.
+  GEOMALGOAPI_EXPORT bool check();
+
+  /// Execute the scale transform.
+  GEOMALGOAPI_EXPORT void build();
+
+private:
+  MethodType myMethodType; /// Type of method used.
+  std::shared_ptr<GeomAPI_Shape> mySourceShape; /// Shape to be moved.
+  std::shared_ptr<GeomAPI_Pnt> myCenterPoint; /// Center point.
+  double myScaleFactor; /// Scale factor.
+  double myScaleFactorX; /// Scale factor in X.
+  double myScaleFactorY; /// Scale factor in Y.
+  double myScaleFactorZ; /// Scale factor in Z.
+
+  void buildByFactor();
+  void buildByDimensions();
+};
+
+#endif // GEOMALGOAPI_SCALE_H_
\ No newline at end of file
index 223517a4a2c3fb79f46c6dc68ace5de8770c29a1..faba77138781436e08d0054a31eb6ba9a824cde7 100644 (file)
@@ -10,6 +10,7 @@
 #include <GeomAlgoAPI_Cylinder.h>
 #include <GeomAlgoAPI_ConeSegment.h>
 #include <GeomAlgoAPI_EdgeBuilder.h>
+#include <GeomAlgoAPI_Scale.h>
 #include <GeomAlgoAPI_Symmetry.h>
 #include <GeomAlgoAPI_Translation.h>
 
@@ -305,6 +306,55 @@ namespace GeomAlgoAPI_ShapeAPI
     return aSymmetryAlgo.shape();
   }
 
+  //===============================================================================================
+  std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeScale(
+    std::shared_ptr<GeomAPI_Shape> theSourceShape,
+    std::shared_ptr<GeomAPI_Pnt>   theCenterPoint,
+    const double                   theScaleFactor) throw (GeomAlgoAPI_Exception)
+  {
+    GeomAlgoAPI_Scale aScaleAlgo(theSourceShape, theCenterPoint, theScaleFactor);
+
+    if (!aScaleAlgo.check()) {
+      throw GeomAlgoAPI_Exception(aScaleAlgo.getError());
+    }
+
+    aScaleAlgo.build();
+
+    if(!aScaleAlgo.isDone()) {
+      throw GeomAlgoAPI_Exception(aScaleAlgo.getError());
+    }
+    if (!aScaleAlgo.checkValid("Scale builder by a scale factor")) {
+      throw GeomAlgoAPI_Exception(aScaleAlgo.getError());
+    }
+    return aScaleAlgo.shape();
+  }
+
+  //===============================================================================================
+  std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeScale(
+   std::shared_ptr<GeomAPI_Shape> theSourceShape,
+   std::shared_ptr<GeomAPI_Pnt>   theCenterPoint,
+   const double                   theScaleFactorX,
+   const double                   theScaleFactorY,
+   const double                   theScaleFactorZ) throw (GeomAlgoAPI_Exception)
+  {
+    GeomAlgoAPI_Scale aScaleAlgo(theSourceShape, theCenterPoint,
+                                 theScaleFactorX, theScaleFactorY, theScaleFactorZ);
+
+    if (!aScaleAlgo.check()) {
+      throw GeomAlgoAPI_Exception(aScaleAlgo.getError());
+    }
+
+    aScaleAlgo.build();
+
+    if(!aScaleAlgo.isDone()) {
+      throw GeomAlgoAPI_Exception(aScaleAlgo.getError());
+    }
+    if (!aScaleAlgo.checkValid("Scale builder by dimensions")) {
+      throw GeomAlgoAPI_Exception(aScaleAlgo.getError());
+    }
+    return aScaleAlgo.shape();
+  }
+
   //===============================================================================================
   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeConeSegment(
     const double theRMin1, const double theRMax1,
index 454f88495088cce9d0affde6df6d510bbea909e9..2f478373b92b23f98db05a5ef7eb8eb4410dbac4 100644 (file)
@@ -124,6 +124,28 @@ public:
                      std::shared_ptr<GeomAPI_Shape> theSourceShape,
                      std::shared_ptr<GeomAPI_Ax2>   thePlane) throw (GeomAlgoAPI_Exception);
 
+  /// Performs a scale by a scale factor.
+  /// \param theSourceShape Shape be scaled
+  /// \param theCenterPoint Point of scale
+  /// \param theScaleFactor Factor of scale
+  static std::shared_ptr<GeomAPI_Shape> makeScale(
+                     std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                     std::shared_ptr<GeomAPI_Pnt>   theCenterPoint,
+                     const double                   theScaleFactor) throw (GeomAlgoAPI_Exception);
+
+  /// Performs a scale by dimensions.
+  /// \param theSourceShape Shape be scaled
+  /// \param theCenterPoint Point of scale
+  /// \param theScaleFactorX Factor of scale in X
+  /// \param theScaleFactorY Factor of scale in Y
+  /// \param theScaleFactorZ Factor of scale in Z
+  static std::shared_ptr<GeomAPI_Shape> makeScale(
+                     std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                     std::shared_ptr<GeomAPI_Pnt>   theCenterPoint,
+                     const double                   theScaleFactorX,
+                     const double                   theScaleFactorY,
+                     const double                   theScaleFactorZ) throw (GeomAlgoAPI_Exception);
+
   /// Creates a cone segment using standard GDML parameters.
   /// \param theRMin1 Inner radius at base of cone
   /// \param theRMax1 Outer radius at base of cone
diff --git a/src/GeomAlgoAPI/Test/TestAPI_Scale.py b/src/GeomAlgoAPI/Test/TestAPI_Scale.py
new file mode 100644 (file)
index 0000000..a601348
--- /dev/null
@@ -0,0 +1,32 @@
+# Copyright (C) 2014-201x CEA/DEN, EDF R&D
+
+# File:        TestAPI_Scale.py
+# Created:     25 Jan 2017
+# Author:      Clarisse Genrault (CEA)
+
+from GeomAlgoAPI import GeomAlgoAPI_ShapeAPI as shaperpy
+from GeomAlgoAPI import GeomAlgoAPI_Exception as myExcept
+from GeomAPI import GeomAPI_Pnt as pnt
+
+# Create a box
+try :
+  box1 = shaperpy.makeBox(10.,10.,10.)
+  box2 = shaperpy.makeBox(10.,10.,10.)
+  centerPoint = pnt(20.,20.,0.)
+except myExcept, ec:
+  print ec.what()
+
+# Perfom a scale by a factor.
+try :
+  scale1 = shaperpy.makeScale(box1,centerPoint, -1.6)
+except myExcept, ec:
+  print ec.what()
+
+# Perfom a scale by dimensions.
+try :
+  scale2 = shaperpy.makeScale(box2,centerPoint, 2, -0.5, 1.3)
+except myExcept, ec:
+  print ec.what()
index 07471e912a7080f7ba79e0a0ac4da4c766393943..4632e171ac9e3e16db947ac6599cd7cdfbec7b8e 100644 (file)
@@ -1,7 +1,7 @@
 """Package for Features plugin for the Parametric Geometry API of the Modeler.
 """
 
-from FeaturesAPI import addPlacement, addRotation, addSymmetry, addTranslation
+from FeaturesAPI import addPlacement, addRotation, addScale, addSymmetry, addTranslation
 from FeaturesAPI import addExtrusion, addExtrusionCut, addExtrusionFuse
 from FeaturesAPI import addRevolution, addRevolutionCut, addRevolutionFuse
 from FeaturesAPI import addPipe