Salome HOME
Adding the "Symmetry" feature.
authorClarisse Genrault <clarisse.genrault@cea.fr>
Wed, 4 Jan 2017 11:26:57 +0000 (12:26 +0100)
committerClarisse Genrault <clarisse.genrault@cea.fr>
Wed, 4 Jan 2017 11:26:57 +0000 (12:26 +0100)
28 files changed:
src/FeaturesAPI/CMakeLists.txt
src/FeaturesAPI/FeaturesAPI.i
src/FeaturesAPI/FeaturesAPI_Symmetry.cpp [new file with mode: 0644]
src/FeaturesAPI/FeaturesAPI_Symmetry.h [new file with mode: 0644]
src/FeaturesAPI/FeaturesAPI_swig.h
src/FeaturesAPI/Test/APIParam_Symmetry.py [new file with mode: 0644]
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp
src/FeaturesPlugin/FeaturesPlugin_Symmetry.cpp [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_Symmetry.h [new file with mode: 0644]
src/FeaturesPlugin/icons/point.png [new file with mode: 0755]
src/FeaturesPlugin/icons/symmetry.png [new file with mode: 0644]
src/FeaturesPlugin/icons/symmetry_axis_32x32.png [new file with mode: 0644]
src/FeaturesPlugin/icons/symmetry_plane_32x32.png [new file with mode: 0644]
src/FeaturesPlugin/icons/symmetry_point_32x32.png [new file with mode: 0644]
src/FeaturesPlugin/plugin-Features.xml
src/FeaturesPlugin/symmetry_widget.xml [new file with mode: 0644]
src/GeomAPI/GeomAPI_Trsf.cpp
src/GeomAPI/GeomAPI_Trsf.h
src/GeomAlgoAPI/CMakeLists.txt
src/GeomAlgoAPI/GeomAlgoAPI.i
src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.h
src/GeomAlgoAPI/GeomAlgoAPI_Symmetry.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_Symmetry.h [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_swig.h
src/GeomAlgoAPI/Test/TestAPI_Symmetry.py [new file with mode: 0644]
src/PythonAPI/model/features/__init__.py

index 155141244d859a7e4d789677bf557974bf120f27..e109499003f091b13e5d938c0baec7ba82d6e6c5 100644 (file)
@@ -17,6 +17,7 @@ SET(PROJECT_HEADERS
   FeaturesAPI_Revolution.h
   FeaturesAPI_RevolutionBoolean.h
   FeaturesAPI_Rotation.h
+  FeaturesAPI_Symmetry.h
   FeaturesAPI_Translation.h
   FeaturesAPI_Union.h
 )
@@ -34,6 +35,7 @@ SET(PROJECT_SOURCES
   FeaturesAPI_Revolution.cpp
   FeaturesAPI_RevolutionBoolean.cpp
   FeaturesAPI_Rotation.cpp
+  FeaturesAPI_Symmetry.cpp
   FeaturesAPI_Translation.cpp
   FeaturesAPI_Union.cpp
 )
@@ -92,4 +94,5 @@ 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_Translation.py)
\ No newline at end of file
+ADD_UNIT_TESTS(APIParam_Symmetry.py
+               APIParam_Translation.py)
\ No newline at end of file
index 7a8a5562830680fe0cf3b024cef1ae291c65fa59..68817ec5f468a322202c715ef12d252de07dc840 100644 (file)
@@ -35,6 +35,7 @@
 %shared_ptr(FeaturesAPI_RevolutionCut)
 %shared_ptr(FeaturesAPI_RevolutionFuse)
 %shared_ptr(FeaturesAPI_Rotation)
+%shared_ptr(FeaturesAPI_Symmetry)
 %shared_ptr(FeaturesAPI_Translation)
 %shared_ptr(FeaturesAPI_Union)
 
@@ -51,5 +52,6 @@
 %include "FeaturesAPI_Revolution.h"
 %include "FeaturesAPI_RevolutionBoolean.h"
 %include "FeaturesAPI_Rotation.h"
+%include "FeaturesAPI_Symmetry.h"
 %include "FeaturesAPI_Translation.h"
 %include "FeaturesAPI_Union.h"
diff --git a/src/FeaturesAPI/FeaturesAPI_Symmetry.cpp b/src/FeaturesAPI/FeaturesAPI_Symmetry.cpp
new file mode 100644 (file)
index 0000000..24a41f3
--- /dev/null
@@ -0,0 +1,119 @@
+// Copyright (C) 2014-2016 CEA/DEN, EDF R&D -->
+
+// File:        FeaturesAPI_Symmetry.cpp
+// Created:     07 Dec 2016
+// Author:      Clarisse Genrault (CEA)
+
+#include "FeaturesAPI_Symmetry.h"
+
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Tools.h>
+
+//==================================================================================================
+FeaturesAPI_Symmetry::FeaturesAPI_Symmetry(
+  const std::shared_ptr<ModelAPI_Feature>& theFeature)
+: ModelHighAPI_Interface(theFeature)
+{
+  initialize();
+}
+
+//==================================================================================================
+FeaturesAPI_Symmetry::FeaturesAPI_Symmetry(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                       const std::list<ModelHighAPI_Selection>& theMainObjects,
+                                       const ModelHighAPI_Selection& theObject)
+: ModelHighAPI_Interface(theFeature)
+{
+  if(initialize()) {
+    fillAttribute(theMainObjects, mymainObjects);
+    GeomAPI_Shape::ShapeType aType = getShapeType(theObject);
+    if(aType == GeomAPI_Shape::VERTEX) {
+      setPoint(theObject);
+    } else if(aType == GeomAPI_Shape::EDGE) {
+      setAxis(theObject);
+    } else if(aType == GeomAPI_Shape::FACE) {
+      setPlane(theObject);
+    }
+  }
+}
+
+//==================================================================================================
+FeaturesAPI_Symmetry::~FeaturesAPI_Symmetry()
+{
+
+}
+
+//==================================================================================================
+void FeaturesAPI_Symmetry::setMainObjects(
+  const std::list<ModelHighAPI_Selection>& theMainObjects)
+{
+  fillAttribute(theMainObjects, mainObjects());
+
+  execute();
+}
+
+//==================================================================================================
+void FeaturesAPI_Symmetry::setPoint(const ModelHighAPI_Selection& thePointObject)
+{
+  fillAttribute(FeaturesPlugin_Symmetry::CREATION_METHOD_BY_POINT(), creationMethod());
+  fillAttribute(thePointObject, pointObject());
+
+  execute();
+}
+
+//==================================================================================================
+void FeaturesAPI_Symmetry::setAxis(const ModelHighAPI_Selection& theAxisObject)
+{
+  fillAttribute(FeaturesPlugin_Symmetry::CREATION_METHOD_BY_AXIS(), creationMethod());
+  fillAttribute(theAxisObject, axisObject());
+
+  execute();
+}
+
+//==================================================================================================
+void FeaturesAPI_Symmetry::setPlane(const ModelHighAPI_Selection& thePlaneObject)
+{
+  fillAttribute(FeaturesPlugin_Symmetry::CREATION_METHOD_BY_PLANE(), creationMethod());
+  fillAttribute(thePlaneObject, planeObject());
+
+  execute();
+}
+
+//==================================================================================================
+void FeaturesAPI_Symmetry::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  std::cout << "DUMP SYMMETRY" << std::endl;
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+
+  AttributeSelectionListPtr anAttrObjects =
+    aBase->selectionList(FeaturesPlugin_Symmetry::OBJECTS_LIST_ID());
+  theDumper << aBase << " = model.addSymmetry(" << aDocName << ", " << anAttrObjects;
+
+  std::string aCreationMethod =
+    aBase->string(FeaturesPlugin_Symmetry::CREATION_METHOD())->value();
+
+  if (aCreationMethod == FeaturesPlugin_Symmetry::CREATION_METHOD_BY_POINT()) {
+    AttributeSelectionPtr anAttrPoint =
+      aBase->selection(FeaturesPlugin_Symmetry::POINT_OBJECT_ID());
+    theDumper << ", " << anAttrPoint;
+  } else if (aCreationMethod == FeaturesPlugin_Symmetry::CREATION_METHOD_BY_AXIS()) {
+    AttributeSelectionPtr anAttrAxis =
+      aBase->selection(FeaturesPlugin_Symmetry::AXIS_OBJECT_ID());
+    theDumper << ", " << anAttrAxis;
+  } else if (aCreationMethod == FeaturesPlugin_Symmetry::CREATION_METHOD_BY_PLANE()) {
+    AttributeSelectionPtr anAttrPlane =
+      aBase->selection(FeaturesPlugin_Symmetry::PLANE_OBJECT_ID());
+    theDumper << ", " << anAttrPlane;
+  }
+
+   theDumper << ")" << std::endl;
+}
+
+//==================================================================================================
+SymmetryPtr addSymmetry(const std::shared_ptr<ModelAPI_Document>& thePart,
+                              const std::list<ModelHighAPI_Selection>& theMainObjects,
+                              const ModelHighAPI_Selection& theObject)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(FeaturesAPI_Symmetry::ID());
+  return SymmetryPtr(new FeaturesAPI_Symmetry(aFeature, theMainObjects, theObject));
+}
diff --git a/src/FeaturesAPI/FeaturesAPI_Symmetry.h b/src/FeaturesAPI/FeaturesAPI_Symmetry.h
new file mode 100644 (file)
index 0000000..7b0bf31
--- /dev/null
@@ -0,0 +1,84 @@
+// Copyright (C) 2014-2016 CEA/DEN, EDF R&D -->
+
+// File:        FeaturesAPI_Symmetry.h
+// Created:     07 Dec 2016
+// Author:      Clarisse Genrault (CEA)
+
+#ifndef FEATURESAPI_SYMMETRY_H_
+#define FEATURESAPI_SYMMETRY_H_
+
+#include "FeaturesAPI.h"
+
+#include <FeaturesPlugin_Symmetry.h>
+
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
+
+class ModelHighAPI_Double;
+class ModelHighAPI_Dumper;
+class ModelHighAPI_Selection;
+
+/// \class FeaturesAPI_Symmetry
+/// \ingroup CPPHighAPI
+/// \brief Interface for Symmetry feature.
+class FeaturesAPI_Symmetry: public ModelHighAPI_Interface
+{
+public:
+  /// Constructor without values.
+  FEATURESAPI_EXPORT
+  explicit FeaturesAPI_Symmetry(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
+  /// Constructor with values.
+  FEATURESAPI_EXPORT
+  explicit FeaturesAPI_Symmetry(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                   const std::list<ModelHighAPI_Selection>& theMainObjects,
+                                   const ModelHighAPI_Selection& theObject);
+
+  /// Destructor.
+  FEATURESAPI_EXPORT
+  virtual ~FeaturesAPI_Symmetry();
+
+  INTERFACE_5(FeaturesPlugin_Symmetry::ID(),
+              creationMethod, FeaturesPlugin_Symmetry::CREATION_METHOD(),
+              ModelAPI_AttributeString, /** Creation method */,
+              mainObjects, FeaturesPlugin_Symmetry::OBJECTS_LIST_ID(),
+              ModelAPI_AttributeSelectionList, /** Main objects */,
+              pointObject, FeaturesPlugin_Symmetry::POINT_OBJECT_ID(),
+              ModelAPI_AttributeSelection, /** Point object */,
+              axisObject, FeaturesPlugin_Symmetry::AXIS_OBJECT_ID(),
+              ModelAPI_AttributeSelection, /** Axis object */,
+              planeObject, FeaturesPlugin_Symmetry::PLANE_OBJECT_ID(),
+              ModelAPI_AttributeSelection, /** Plane object */)
+
+  /// Set main objects.
+  FEATURESAPI_EXPORT
+  void setMainObjects(const std::list<ModelHighAPI_Selection>& theMainObjects);
+
+  /// Modify CreationMethod, point_object attribute of the feature.
+  FEATURESAPI_EXPORT
+  void setPoint(const ModelHighAPI_Selection& thePointObject);
+
+  /// Modify CreationMethod, axis_object attribute of the feature.
+  FEATURESAPI_EXPORT
+  void setAxis(const ModelHighAPI_Selection& theAxisObject);
+
+  /// Modify CreationMethod, plane_object attribute of the feature.
+  FEATURESAPI_EXPORT
+  void setPlane(const ModelHighAPI_Selection& thePlaneObject);
+
+  /// Dump wrapped feature
+  FEATURESAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+};
+
+/// Pointer on Symmetry object.
+typedef std::shared_ptr<FeaturesAPI_Symmetry> SymmetryPtr;
+
+/// \ingroup CPPHighAPI
+/// \brief Create Symmetry feature.
+FEATURESAPI_EXPORT
+SymmetryPtr addSymmetry(const std::shared_ptr<ModelAPI_Document>& thePart,
+                    const std::list<ModelHighAPI_Selection>& theMainObjects,
+                    const ModelHighAPI_Selection& theObject);
+
+#endif // FEATURESAPI_SYMMETRY_H_
index 6e25cbad6b230c1b3784b2509d9a6db48494a104..cb100d4c4f273554ccf09c53b4afa68b3b2c588a 100644 (file)
@@ -22,6 +22,7 @@
   #include "FeaturesAPI_Revolution.h"
   #include "FeaturesAPI_RevolutionBoolean.h"
   #include "FeaturesAPI_Rotation.h"
+  #include "FeaturesAPI_Symmetry.h"
   #include "FeaturesAPI_Translation.h"
   #include "FeaturesAPI_Union.h"
 
diff --git a/src/FeaturesAPI/Test/APIParam_Symmetry.py b/src/FeaturesAPI/Test/APIParam_Symmetry.py
new file mode 100644 (file)
index 0000000..0f78546
--- /dev/null
@@ -0,0 +1,47 @@
+"""
+Test case for Translation feature. 
+Written on High API.
+"""
+from ModelAPI import *
+from GeomAPI import *
+
+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()
+aBox1 =  model.addBox(aDocument, 10, 10, 10)
+aBox2 =  model.addBox(aDocument, 10, 10, 10)
+aBox3 =  model.addBox(aDocument, 10, 10, 10)
+
+# Perform a symmetry by a point
+aSession.startOperation()
+aPoint = model.addPoint(aDocument, 0, 0, 0).result()
+aSymmetry1 = model.addSymmetry(aDocument, [model.selection("SOLID", "Box_1_1")], aPoint).result()
+aSession.finishOperation()
+assert (aSymmetry1 is not None)
+
+# Perform a symmetry by an axis
+aSession.startOperation()
+anAxis = model.addAxis(aDocument, 10, 0, 0).result()
+aSymmetry2 = model.addSymmetry(aDocument, [model.selection("SOLID", "Box_2_1")], anAxis).result()
+aSession.finishOperation()
+assert (aSymmetry2 is not None)
+
+# Perform a symmetry by a plane
+aSession.startOperation()
+aPoint1 = model.addPoint(aDocument, 0, 0, 0).result()
+aPoint2 = model.addPoint(aDocument, 10, 10, 0).result()
+aSymmetry3 = model.addSymmetry(aDocument, [model.selection("SOLID", "Box_3_1")], model.selection("FACE", "Box_3_1/Top")).result()
+aSession.finishOperation()
+assert (aSymmetry3 is not None)
\ No newline at end of file
index 637f3b578309f1741130872482cbc168e14be1cf..52b30210d75721d040b2d87b8bb381574cb3c319 100644 (file)
@@ -29,6 +29,7 @@ SET(PROJECT_HEADERS
     FeaturesPlugin_Validators.h
     FeaturesPlugin_RemoveSubShapes.h
     FeaturesPlugin_Tools.h
+    FeaturesPlugin_Symmetry.h
 )
 
 SET(PROJECT_SOURCES
@@ -56,6 +57,7 @@ SET(PROJECT_SOURCES
     FeaturesPlugin_Validators.cpp
     FeaturesPlugin_RemoveSubShapes.cpp
     FeaturesPlugin_Tools.cpp
+    FeaturesPlugin_Symmetry.cpp
 )
 
 SET(XML_RESOURCES
@@ -76,6 +78,7 @@ SET(XML_RESOURCES
   pipe_widget.xml
   remove_subshapes_widget.xml
   union_widget.xml
+  symmetry_widget.xml
 )
 
 SET(TEXT_RESOURCES
index a602a866f13ed57947021155a9d7ec7851a31922..89f735cf17c02791d371c91b126a835b81de56d7 100644 (file)
@@ -20,6 +20,7 @@
 #include <FeaturesPlugin_Union.h>
 #include <FeaturesPlugin_ValidatorTransform.h>
 #include <FeaturesPlugin_Validators.h>
+#include <FeaturesPlugin_Symmetry.h>
 
 #include <ModelAPI_Session.h>
 
@@ -99,6 +100,8 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(std::string theFeatureID)
     return FeaturePtr(new FeaturesPlugin_RemoveSubShapes);
   } else if (theFeatureID == FeaturesPlugin_Union::ID()) {
     return FeaturePtr(new FeaturesPlugin_Union);
+  } else if (theFeatureID == FeaturesPlugin_Symmetry::ID()) {
+    return FeaturePtr(new FeaturesPlugin_Symmetry);
   }
 
   // feature of such kind is not found
diff --git a/src/FeaturesPlugin/FeaturesPlugin_Symmetry.cpp b/src/FeaturesPlugin/FeaturesPlugin_Symmetry.cpp
new file mode 100644 (file)
index 0000000..e38bff2
--- /dev/null
@@ -0,0 +1,360 @@
+// Copyright (C) 2014-2016 CEA/DEN, EDF R&D
+
+// File:        FeaturesPlugin_Symmetry.cpp
+// Created:     30 Nov 2016
+// Author:      Clarisse Genrault (CEA)
+
+#include <FeaturesPlugin_Symmetry.h>
+
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_ResultBody.h>
+
+#include <GeomAPI_Edge.h>
+#include <GeomAPI_Face.h>
+#include <GeomAPI_Lin.h>
+#include <GeomAPI_Pln.h>
+
+#include <GeomAlgoAPI_PointBuilder.h>
+
+#include <ModelAPI_ResultPart.h>
+
+//=================================================================================================
+FeaturesPlugin_Symmetry::FeaturesPlugin_Symmetry()
+{
+}
+
+//=================================================================================================
+void FeaturesPlugin_Symmetry::initAttributes()
+{
+  data()->addAttribute(FeaturesPlugin_Symmetry::CREATION_METHOD(),
+                       ModelAPI_AttributeString::typeId());
+
+  AttributeSelectionListPtr aSelection =
+    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
+    FeaturesPlugin_Symmetry::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
+
+  data()->addAttribute(FeaturesPlugin_Symmetry::POINT_OBJECT_ID(),
+                       ModelAPI_AttributeSelection::typeId());
+
+  data()->addAttribute(FeaturesPlugin_Symmetry::AXIS_OBJECT_ID(),
+                       ModelAPI_AttributeSelection::typeId());
+
+  data()->addAttribute(FeaturesPlugin_Symmetry::PLANE_OBJECT_ID(),
+                       ModelAPI_AttributeSelection::typeId());
+}
+
+//=================================================================================================
+void FeaturesPlugin_Symmetry::execute()
+{
+  AttributeStringPtr aMethodTypeAttr = string(FeaturesPlugin_Symmetry::CREATION_METHOD());
+  std::string aMethodType = aMethodTypeAttr->value();
+
+  if (aMethodType == CREATION_METHOD_BY_POINT()) {
+    performSymmetryByPoint();
+  }
+
+  if (aMethodType == CREATION_METHOD_BY_AXIS()) {
+    performSymmetryByAxis();
+  }
+
+  if (aMethodType == CREATION_METHOD_BY_PLANE()) {
+    performSymmetryByPlane();
+  }
+}
+
+//=================================================================================================
+void FeaturesPlugin_Symmetry::performSymmetryByPoint()
+{
+  // Getting objects.
+  ListOfShape anObjects;
+  std::list<ResultPtr> aContextes;
+  AttributeSelectionListPtr anObjectsSelList =
+    selectionList(FeaturesPlugin_Symmetry::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 point.
+  std::shared_ptr<GeomAPI_Pnt> aPoint;
+  std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
+    selection(FeaturesPlugin_Symmetry::POINT_OBJECT_ID());
+  if (anObjRef.get() != NULL) {
+    GeomShapePtr aShape1 = anObjRef->value();
+    if (!aShape1.get()) {
+      aShape1 = anObjRef->context()->shape();
+    }
+    if (aShape1) {
+      aPoint = GeomAlgoAPI_PointBuilder::point(aShape1);
+    }
+  }
+
+  // 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(aPoint);
+      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_Symmetry aSymmetryAlgo(aBaseShape, aPoint);
+
+      if (!aSymmetryAlgo.check()) {
+        setError(aSymmetryAlgo.getError());
+        return;
+      }
+
+      aSymmetryAlgo.build();
+
+      // Checking that the algorithm worked properly.
+      if(!aSymmetryAlgo.isDone()) {
+        static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
+        setError(aFeatureError);
+        break;
+      }
+      if(aSymmetryAlgo.shape()->isNull()) {
+        static const std::string aShapeError = "Error: Resulting shape is Null.";
+        setError(aShapeError);
+        break;
+      }
+      if(!aSymmetryAlgo.isValid()) {
+        std::string aFeatureError = "Error: Resulting shape is not valid.";
+        setError(aFeatureError);
+        break;
+      }
+
+      ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+      loadNamingDS(aSymmetryAlgo, aResultBody, aBaseShape);
+      setResult(aResultBody, aResultIndex);
+    }
+    aResultIndex++;
+  }
+
+  // Remove the rest results if there were produced in the previous pass.
+  removeResults(aResultIndex);
+}
+
+//=================================================================================================
+void FeaturesPlugin_Symmetry::performSymmetryByAxis()
+{
+  // Getting objects.
+  ListOfShape anObjects;
+  std::list<ResultPtr> aContextes;
+  AttributeSelectionListPtr anObjectsSelList =
+    selectionList(FeaturesPlugin_Symmetry::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_Symmetry::AXIS_OBJECT_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()));
+  }
+
+  // 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_Symmetry aSymmetryAlgo(aBaseShape, anAxis);
+
+      if (!aSymmetryAlgo.check()) {
+        setError(aSymmetryAlgo.getError());
+        return;
+      }
+
+      aSymmetryAlgo.build();
+
+      // Checking that the algorithm worked properly.
+      if(!aSymmetryAlgo.isDone()) {
+        static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
+        setError(aFeatureError);
+        break;
+      }
+      if(aSymmetryAlgo.shape()->isNull()) {
+        static const std::string aShapeError = "Error: Resulting shape is Null.";
+        setError(aShapeError);
+        break;
+      }
+      if(!aSymmetryAlgo.isValid()) {
+        std::string aFeatureError = "Error: Resulting shape is not valid.";
+        setError(aFeatureError);
+        break;
+      }
+
+      ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+      loadNamingDS(aSymmetryAlgo, aResultBody, aBaseShape);
+      setResult(aResultBody, aResultIndex);
+    }
+    aResultIndex++;
+  }
+
+  // Remove the rest results if there were produced in the previous pass.
+  removeResults(aResultIndex);
+}
+
+//=================================================================================================
+void FeaturesPlugin_Symmetry::performSymmetryByPlane()
+{
+  // Getting objects.
+  ListOfShape anObjects;
+  std::list<ResultPtr> aContextes;
+  AttributeSelectionListPtr anObjectsSelList =
+    selectionList(FeaturesPlugin_Symmetry::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_Ax2> aPlane;
+  std::shared_ptr<GeomAPI_Pln> aPln;
+  std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
+    selection(FeaturesPlugin_Symmetry::PLANE_OBJECT_ID());
+  if(anObjRef && anObjRef->value() && anObjRef->value()->isFace()) {
+    aPln = std::shared_ptr<GeomAPI_Face>(new GeomAPI_Face(anObjRef->value()))->getPlane();
+  }
+  else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
+             anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
+    aPln =
+      std::shared_ptr<GeomAPI_Face>(new GeomAPI_Face(anObjRef->context()->shape()))->getPlane();
+  }
+  if(aPln) {
+    aPlane = std::shared_ptr<GeomAPI_Ax2>(new GeomAPI_Ax2(aPln->location(),
+                                                          aPln->direction()));
+  }
+
+  // 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(aPlane);
+      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_Symmetry aSymmetryAlgo(aBaseShape, aPlane);
+
+      if (!aSymmetryAlgo.check()) {
+        setError(aSymmetryAlgo.getError());
+        return;
+      }
+
+      aSymmetryAlgo.build();
+
+      // Checking that the algorithm worked properly.
+      if(!aSymmetryAlgo.isDone()) {
+        static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
+        setError(aFeatureError);
+        break;
+      }
+      if(aSymmetryAlgo.shape()->isNull()) {
+        static const std::string aShapeError = "Error: Resulting shape is Null.";
+        setError(aShapeError);
+        break;
+      }
+      if(!aSymmetryAlgo.isValid()) {
+        std::string aFeatureError = "Error: Resulting shape is not valid.";
+        setError(aFeatureError);
+        break;
+      }
+
+      ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+      loadNamingDS(aSymmetryAlgo, aResultBody, aBaseShape);
+      setResult(aResultBody, aResultIndex);
+    }
+    aResultIndex++;
+  }
+
+  // Remove the rest results if there were produced in the previous pass.
+  removeResults(aResultIndex);
+}
+
+//=================================================================================================
+void FeaturesPlugin_Symmetry::loadNamingDS(GeomAlgoAPI_Symmetry& theSymmetryAlgo,
+                                           std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+                                           std::shared_ptr<GeomAPI_Shape> theBaseShape)
+{
+  // Store and name the result.
+  theResultBody->storeModified(theBaseShape, theSymmetryAlgo.shape());
+
+  // Name the faces
+  std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theSymmetryAlgo.mapOfSubShapes();
+  int aReflectedTag = 1;
+  std::string aReflectedName = "Symmetried";
+  theResultBody->loadAndOrientModifiedShapes(&theSymmetryAlgo,
+                                              theBaseShape, GeomAPI_Shape::FACE,
+                                              aReflectedTag, aReflectedName, *aSubShapes.get());
+}
diff --git a/src/FeaturesPlugin/FeaturesPlugin_Symmetry.h b/src/FeaturesPlugin/FeaturesPlugin_Symmetry.h
new file mode 100644 (file)
index 0000000..988f583
--- /dev/null
@@ -0,0 +1,117 @@
+// Copyright (C) 2014-2016 CEA/DEN, EDF R&D
+
+// File:        FeaturesPlugin_Symmetry.h
+// Created:     30 Nov 2016
+// Author:      Clarisse Genrault (CEA)
+
+#ifndef FEATURESPLUGIN_SYMMETRY_H_
+#define FEATURESPLUGIN_SYMMETRY_H_
+
+#include <FeaturesPlugin.h>
+
+#include <ModelAPI_Feature.h>
+
+#include <GeomAlgoAPI_Symmetry.h>
+
+/** \class FeaturesPlugin_Symmetry
+ *  \ingroup Plugins
+ *  \brief Feature that performs reflection with respect to a point, axis, or plane.
+ */
+class FeaturesPlugin_Symmetry : public ModelAPI_Feature
+{
+ public:
+  /// Symmetry kind.
+  inline static const std::string& ID()
+  {
+    static const std::string MY_SYMMETRY("Symmetry");
+    return MY_SYMMETRY;
+  }
+
+  /// 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 "ByAxisAndDistance".
+  inline static const std::string& CREATION_METHOD_BY_POINT()
+  {
+    static const std::string MY_CREATION_METHOD_ID("ByPoint");
+    return MY_CREATION_METHOD_ID;
+  }
+
+  /// Attribute name for creation method "ByDimensions".
+  inline static const std::string& CREATION_METHOD_BY_AXIS()
+  {
+    static const std::string MY_CREATION_METHOD_ID("ByAxis");
+    return MY_CREATION_METHOD_ID;
+  }
+
+  /// Attribute name for creation method "ByTwoPoints".
+  inline static const std::string& CREATION_METHOD_BY_PLANE()
+  {
+    static const std::string MY_CREATION_METHOD_ID("ByPlane");
+    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 a point.
+  inline static const std::string& POINT_OBJECT_ID()
+  {
+    static const std::string MY_POINT_OBJECT_ID("point_object");
+    return MY_POINT_OBJECT_ID;
+  }
+
+  /// Attribute name of an axis.
+  inline static const std::string& AXIS_OBJECT_ID()
+  {
+    static const std::string MY_AXIS_OBJECT_ID("axis_object");
+    return MY_AXIS_OBJECT_ID;
+  }
+
+  /// Attribute name of a plane.
+  inline static const std::string& PLANE_OBJECT_ID()
+  {
+    static const std::string MY_PLANE_OBJECT_ID("plane_object");
+    return MY_PLANE_OBJECT_ID;
+  }
+
+  /// \return the kind of a feature.
+  FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    static std::string MY_KIND = FeaturesPlugin_Symmetry::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_Symmetry();
+
+private:
+  ///Perform symmetry with respect to a point.
+  void performSymmetryByPoint();
+
+  ///Perform symmetry with respect to an axis.
+  void performSymmetryByAxis();
+
+  ///Perform symmetry with respect to a plane.
+  void performSymmetryByPlane();
+
+  void loadNamingDS(GeomAlgoAPI_Symmetry& theSymmetryAlgo,
+                    std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+                    std::shared_ptr<GeomAPI_Shape> theBaseShape);
+};
+
+#endif // FEATURESPLUGIN_SYMMETRY_H_
diff --git a/src/FeaturesPlugin/icons/point.png b/src/FeaturesPlugin/icons/point.png
new file mode 100755 (executable)
index 0000000..96149eb
Binary files /dev/null and b/src/FeaturesPlugin/icons/point.png differ
diff --git a/src/FeaturesPlugin/icons/symmetry.png b/src/FeaturesPlugin/icons/symmetry.png
new file mode 100644 (file)
index 0000000..fdc73b2
Binary files /dev/null and b/src/FeaturesPlugin/icons/symmetry.png differ
diff --git a/src/FeaturesPlugin/icons/symmetry_axis_32x32.png b/src/FeaturesPlugin/icons/symmetry_axis_32x32.png
new file mode 100644 (file)
index 0000000..3873378
Binary files /dev/null and b/src/FeaturesPlugin/icons/symmetry_axis_32x32.png differ
diff --git a/src/FeaturesPlugin/icons/symmetry_plane_32x32.png b/src/FeaturesPlugin/icons/symmetry_plane_32x32.png
new file mode 100644 (file)
index 0000000..ddecb82
Binary files /dev/null and b/src/FeaturesPlugin/icons/symmetry_plane_32x32.png differ
diff --git a/src/FeaturesPlugin/icons/symmetry_point_32x32.png b/src/FeaturesPlugin/icons/symmetry_point_32x32.png
new file mode 100644 (file)
index 0000000..2cda225
Binary files /dev/null and b/src/FeaturesPlugin/icons/symmetry_point_32x32.png differ
index b7f98d6ae3ef6c3663daf4d45b790f020a153988..40c2194e2ff56899ab288e6afe8b0c8f4fb28047 100644 (file)
@@ -68,6 +68,9 @@
       <feature id="Rotation" title="Rotation" tooltip="Perform rotation of an objects around the axis to specified angle" icon="icons/Features/rotation.png">
         <source path="rotation_widget.xml"/>
       </feature>
+      <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>
     </group>
   </workbench>
 </plugin>
diff --git a/src/FeaturesPlugin/symmetry_widget.xml b/src/FeaturesPlugin/symmetry_widget.xml
new file mode 100644 (file)
index 0000000..2d25350
--- /dev/null
@@ -0,0 +1,60 @@
+<!-- Copyright (C) 2014-2016 CEA/DEN, EDF R&D -->
+
+<source>
+  <toolbox id="CreationMethod"> 
+    <box id="ByPoint" title="Point reflection" icon="icons/Features/symmetry_point_32x32.png">
+      <multi_selector id="main_objects"
+                      label="Main objects"
+                      icon="icons/Features/cut_shape.png"
+                      tooltip="Select solid objects"
+                      type_choice="solid objects"
+                      concealment="true">
+        <validator id="FeaturesPlugin_ValidatorTransform"/>
+      </multi_selector>
+      <shape_selector id="point_object"
+                      icon="icons/Features/point.png"
+                      label="Point"
+                      tooltip="Select a point"
+                      shape_types="vertex"
+                      default="">
+        <validator id="GeomValidators_ShapeType" parameters="vertex"/>
+      </shape_selector>
+    </box>
+    <box id="ByAxis" title="Axis reflection" icon="icons/Features/symmetry_axis_32x32.png">
+      <multi_selector id="main_objects"
+                      label="Main objects"
+                      icon="icons/Features/cut_shape.png"
+                      tooltip="Select solid objects"
+                      type_choice="solid objects"
+                      concealment="true">
+        <validator id="FeaturesPlugin_ValidatorTransform"/>
+      </multi_selector>
+      <shape_selector id="axis_object"
+                      icon="icons/Features/axis.png"
+                      label="Axis"
+                      tooltip="Select an axis"
+                      shape_types="edge"
+                      default="">
+        <validator id="GeomValidators_ShapeType" parameters="line"/>
+      </shape_selector>
+    </box>
+    <box id="ByPlane" title="Plane reflection" icon="icons/Features/symmetry_plane_32x32.png">
+      <multi_selector id="main_objects"
+                      label="Main objects"
+                      icon="icons/Features/cut_shape.png"
+                      tooltip="Select solid objects"
+                      type_choice="solid objects"
+                      concealment="true">
+        <validator id="FeaturesPlugin_ValidatorTransform"/>
+      </multi_selector>
+      <shape_selector id="plane_object"
+                      label="Plane"
+                      icon="icons/Features/plane.png"
+                      tooltip="Select a plane"
+                      shape_types="face"
+                      default="">
+        <validator id="GeomValidators_Face" parameters="plane"/>
+      </shape_selector>
+    </box>
+  </toolbox>
+</source>
index 322c14b9061bcd06cb446382ce298918a0cd9efb..21a972872bbf2ca3a10d58fc0e14b3f0e66c5eac 100644 (file)
@@ -9,9 +9,11 @@
 #include<GeomAPI_Trsf.h>
 
 #include <GeomAPI_Ax1.h>
+#include <GeomAPI_Ax2.h>
 
 #include <gp_Ax1.hxx>
-#include<gp_Trsf.hxx>
+#include <gp_Ax2.hxx>
+#include <gp_Trsf.hxx>
 
 #define MY_TRSF implPtr<gp_Trsf>()
 
@@ -53,3 +55,21 @@ void GeomAPI_Trsf::setRotation(const std::shared_ptr<GeomAPI_Ax1> theAxis,
 {
   MY_TRSF->SetRotation(theAxis->impl<gp_Ax1>(), theAngle / 180.0 * M_PI);
 }
+
+//=================================================================================================
+void GeomAPI_Trsf::setSymmetry(const std::shared_ptr<GeomAPI_Pnt> thePoint)
+{
+  MY_TRSF->SetMirror(thePoint->impl<gp_Pnt>());
+}
+
+//=================================================================================================
+void GeomAPI_Trsf::setSymmetry(const std::shared_ptr<GeomAPI_Ax1> theAxis)
+{
+  MY_TRSF->SetMirror(theAxis->impl<gp_Ax1>());
+}
+
+//=================================================================================================
+void GeomAPI_Trsf::setSymmetry(const std::shared_ptr<GeomAPI_Ax2> thePlane)
+{
+  MY_TRSF->SetMirror(thePlane->impl<gp_Ax2>());
+}
index ed97f4bebe32880bb307ba33e64cb9d87d86169d..9f7a7f811e84f1b800c9babd742ff18d108bbdb2 100644 (file)
@@ -13,6 +13,7 @@
 #include <memory>
 
 class GeomAPI_Ax1;
+class GeomAPI_Ax2;
 class GeomAPI_Pnt;
 
 /**\class GeomAPI_Trsf
@@ -57,6 +58,21 @@ class GeomAPI_Trsf : public GeomAPI_Interface
    */
   GEOMAPI_EXPORT void setRotation(const std::shared_ptr<GeomAPI_Ax1> theAxis,
                                   const double theAngle);
+
+  /** \brief Sets a point symmetry transformation.
+   *  \param[in] thePoint symmetry point.
+   */
+  GEOMAPI_EXPORT void setSymmetry(const std::shared_ptr<GeomAPI_Pnt> thePoint);
+
+  /** \brief Sets an axis symmetry transformation.
+   *  \param[in] theAxis symmetry axis.
+   */
+  GEOMAPI_EXPORT void setSymmetry(const std::shared_ptr<GeomAPI_Ax1> theAxis);
+
+  /** \brief Sets a plane symmetry transformation.
+   *  \param[in] thePlane symmetry plane.
+   */
+  GEOMAPI_EXPORT void setSymmetry(const std::shared_ptr<GeomAPI_Ax2> thePlane);
 };
 
 #endif
index d79ee14662f6884d08274d97dca9b81c08546388..96ba617a96af92b7798acf2fa28bbce5f0991f82 100644 (file)
@@ -47,6 +47,7 @@ SET(PROJECT_HEADERS
     GeomAlgoAPI_XAOImport.h
     GeomAlgoAPI_Copy.h
     GeomAlgoAPI_ConeSegment.h
+    GeomAlgoAPI_Symmetry.h
 )
 
 SET(PROJECT_SOURCES
@@ -89,6 +90,7 @@ SET(PROJECT_SOURCES
     GeomAlgoAPI_XAOImport.cpp
     GeomAlgoAPI_Copy.cpp
     GeomAlgoAPI_ConeSegment.cpp
+    GeomAlgoAPI_Symmetry.cpp
 )
 
 SET(PROJECT_LIBRARIES
@@ -155,5 +157,6 @@ INSTALL(FILES ${SWIG_SCRIPTS} DESTINATION ${SHAPER_INSTALL_SWIG})
 
 ADD_UNIT_TESTS(TestAPI_Box.py
                TestAPI_GDMLConeSegment.py
+               TestAPI_Symmetry.py
                TestAPI_Translation.py)
 
index 3476e73f2ae05aca0d97685d961966b258b8c37e..6ba7fc781e0e444790fdcf1af8f142171ae0b453 100644 (file)
@@ -36,6 +36,7 @@
 %shared_ptr(GeomAlgoAPI_Box)
 %shared_ptr(GeomAlgoAPI_ConeSegment)
 %shared_ptr(GeomAlgoAPI_Copy)
+%shared_ptr(GeomAlgoAPI_Symmetry)
 
 // all supported interfaces
 %include "GeomAlgoAPI_MakeShape.h"
@@ -72,6 +73,7 @@
 %include "GeomAlgoAPI_Exception.h"
 %include "GeomAlgoAPI_ShapeAPI.h"
 %include "GeomAlgoAPI_Copy.h"
+%include "GeomAlgoAPI_Symmetry.h"
 
 %typemap(out) std::list< std::shared_ptr< GeomAPI_Shape > >::value_type & {
   $result = SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr<GeomAPI_Shape>(*$1)), $descriptor(std::shared_ptr<GeomAPI_Shape> *), SWIG_POINTER_OWN | 0 );
index d778964e8c52bff31d207ae5c8c4026c905347b1..185a2ca8b9b9010a83873b26c87d690dfb546c4c 100644 (file)
@@ -9,13 +9,9 @@
 #include <GeomAlgoAPI_Box.h>
 #include <GeomAlgoAPI_ConeSegment.h>
 #include <GeomAlgoAPI_EdgeBuilder.h>
+#include <GeomAlgoAPI_Symmetry.h>
 #include <GeomAlgoAPI_Translation.h>
 
-#include <GeomAPI_Pnt.h>
-#include <GeomAPI_Edge.h>
-
-//#include <iostream>
-
 namespace GeomAlgoAPI_ShapeAPI
 {
   //=======================================================================================
@@ -132,6 +128,72 @@ namespace GeomAlgoAPI_ShapeAPI
     return aTranslationAlgo.shape();
   }
 
+  //=========================================================================================================
+  std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeSymmetry(
+    std::shared_ptr<GeomAPI_Shape> theSourceShape,
+    std::shared_ptr<GeomAPI_Pnt>   thePoint) throw (GeomAlgoAPI_Exception)
+  {
+    GeomAlgoAPI_Symmetry aSymmetryAlgo(theSourceShape, thePoint);
+    
+    if (!aSymmetryAlgo.check()) {
+      throw GeomAlgoAPI_Exception(aSymmetryAlgo.getError());
+    }
+
+    aSymmetryAlgo.build();
+
+    if(!aSymmetryAlgo.isDone()) {
+      throw GeomAlgoAPI_Exception(aSymmetryAlgo.getError());
+    }
+    if (!aSymmetryAlgo.checkValid("Symmetry builder by a point")) {
+      throw GeomAlgoAPI_Exception(aSymmetryAlgo.getError());
+    }
+    return aSymmetryAlgo.shape();
+  }
+
+  //=========================================================================================================
+  std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeSymmetry(
+    std::shared_ptr<GeomAPI_Shape> theSourceShape,
+    std::shared_ptr<GeomAPI_Ax1>   theAxis) throw (GeomAlgoAPI_Exception)
+  {
+    GeomAlgoAPI_Symmetry aSymmetryAlgo(theSourceShape, theAxis);
+    
+    if (!aSymmetryAlgo.check()) {
+      throw GeomAlgoAPI_Exception(aSymmetryAlgo.getError());
+    }
+
+    aSymmetryAlgo.build();
+
+    if(!aSymmetryAlgo.isDone()) {
+      throw GeomAlgoAPI_Exception(aSymmetryAlgo.getError());
+    }
+    if (!aSymmetryAlgo.checkValid("Symmetry builder by an axis")) {
+      throw GeomAlgoAPI_Exception(aSymmetryAlgo.getError());
+    }
+    return aSymmetryAlgo.shape();
+  }
+
+  //=========================================================================================================
+  std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeSymmetry(
+    std::shared_ptr<GeomAPI_Shape> theSourceShape,
+    std::shared_ptr<GeomAPI_Ax2>   thePlane) throw (GeomAlgoAPI_Exception)
+  {
+    GeomAlgoAPI_Symmetry aSymmetryAlgo(theSourceShape, thePlane);
+    
+    if (!aSymmetryAlgo.check()) {
+      throw GeomAlgoAPI_Exception(aSymmetryAlgo.getError());
+    }
+
+    aSymmetryAlgo.build();
+
+    if(!aSymmetryAlgo.isDone()) {
+      throw GeomAlgoAPI_Exception(aSymmetryAlgo.getError());
+    }
+    if (!aSymmetryAlgo.checkValid("Symmetry builder by a plane")) {
+      throw GeomAlgoAPI_Exception(aSymmetryAlgo.getError());
+    }
+    return aSymmetryAlgo.shape();
+  }
+
   //=========================================================================================================
   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeConeSegment(
     const double theRMin1, const double theRMax1,
index 92f0574442c54be223c0d7d703d4081bda2c82cf..da69e20d41b51ad4b7dd1d5595c78e53e2f38317 100644 (file)
@@ -8,6 +8,7 @@
 #define GEOMALGOAPI_SHAPEAPI_H
 
 #include <GeomAPI_Ax1.h>
+#include <GeomAPI_Ax2.h>
 #include <GeomAPI_Edge.h>
 #include <GeomAPI_Pnt.h>
 #include <GeomAPI_Shape.h>
@@ -69,6 +70,21 @@ public:
                      std::shared_ptr<GeomAPI_Shape> theSourceShape,
                      std::shared_ptr<GeomAPI_Pnt>   theStartPoint,
                      std::shared_ptr<GeomAPI_Pnt>   theEndPoint) throw (GeomAlgoAPI_Exception);
+                     
+  /// Performs a symmetry by a point
+  static std::shared_ptr<GeomAPI_Shape> makeSymmetry(
+                     std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                     std::shared_ptr<GeomAPI_Pnt>   thePoint) throw (GeomAlgoAPI_Exception);
+
+  /// Performs a symmetry by an axis
+  static std::shared_ptr<GeomAPI_Shape> makeSymmetry(
+                     std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                     std::shared_ptr<GeomAPI_Ax1>   theAxis) throw (GeomAlgoAPI_Exception);
+
+  /// Performs a symmetry by a plane
+  static std::shared_ptr<GeomAPI_Shape> makeSymmetry(
+                     std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                     std::shared_ptr<GeomAPI_Ax2>   thePlane) throw (GeomAlgoAPI_Exception);
 
   /// Creates a cone segment using standard GDML parameters
   /// \param theRMin1 Inner radius at base of cone
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Symmetry.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Symmetry.cpp
new file mode 100644 (file)
index 0000000..e8f4db1
--- /dev/null
@@ -0,0 +1,137 @@
+// Copyright (C) 2014-2016 CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_Symmetry.cpp
+// Created:     30 Nov 2016
+// Author:      Clarisse Genrault (CEA)
+
+#include "GeomAlgoAPI_Symmetry.h"
+
+#include <BRepBuilderAPI_Transform.hxx>
+
+//=================================================================================================
+GeomAlgoAPI_Symmetry::GeomAlgoAPI_Symmetry(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                           std::shared_ptr<GeomAPI_Pnt>   thePoint)
+{
+  myMethodType = BY_POINT;
+  mySourceShape = theSourceShape;
+  myPoint = thePoint;
+}
+
+//=================================================================================================
+GeomAlgoAPI_Symmetry::GeomAlgoAPI_Symmetry(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                           std::shared_ptr<GeomAPI_Ax1>   theAxis)
+{
+  myMethodType = BY_AXIS;
+  mySourceShape = theSourceShape;
+  myAxis = theAxis;
+}
+
+//=================================================================================================
+GeomAlgoAPI_Symmetry::GeomAlgoAPI_Symmetry(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                           std::shared_ptr<GeomAPI_Ax2>   thePlane)
+{
+  myMethodType = BY_PLANE;
+  mySourceShape = theSourceShape;
+  myPlane = thePlane;
+}
+
+//=================================================================================================
+bool GeomAlgoAPI_Symmetry::check()
+{
+  switch (myMethodType) {
+    case BY_POINT: {
+      if (!myPoint) {
+        myError = "Mirror builder :: point is invalid.";
+        return false;
+      }
+      if (!mySourceShape) {
+        myError = "Mirror builder :: source shape is invalid.";
+        return false;
+      }
+      return true;
+    }
+    case BY_AXIS: {
+      if (!myAxis) {
+        myError = "Mirror builder :: axis is invalid.";
+        return false;
+      }
+      if (!mySourceShape) {
+        myError = "Mirror builder :: source shape is invalid.";
+        return false;
+      }
+      return true;
+    }
+    case BY_PLANE: {
+      if (!myPlane) {
+        myError = "Mirror builder :: plane is invalid.";
+        return false;
+      }
+      if (!mySourceShape) {
+        myError = "Translation builder :: source shape is invalid.";
+        return false;
+      }
+      return true;
+    }
+    default: {
+      myError = "Translation builder :: method not implemented.";
+      return false;
+    }
+  }
+}
+
+//=================================================================================================
+void GeomAlgoAPI_Symmetry::build()
+{
+  gp_Trsf* aTrsf = new gp_Trsf();
+
+  switch (myMethodType) {
+    case BY_POINT: {
+      const gp_Pnt& aPoint = myPoint->impl<gp_Pnt>();
+      aTrsf->SetMirror(aPoint);
+      break;
+    }
+    case BY_AXIS: {
+      const gp_Ax1& anAxis = myAxis->impl<gp_Ax1>();
+      aTrsf->SetMirror(anAxis);
+      break;
+    }
+    case BY_PLANE: {
+      const gp_Ax2& aPlane = myPlane->impl<gp_Ax2>();
+      aTrsf->SetMirror(aPlane);
+      break;
+    }
+    default: {
+      myError = "Mirror builder :: method not supported";
+      return;
+    }
+  }
+  
+  const TopoDS_Shape& aSourceShape = mySourceShape->impl<TopoDS_Shape>();
+  
+  if(aSourceShape.IsNull()) {
+    myError = "Mirror 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 = "Mirror builder :: source shape does not contain any actual shape.";
+    return;
+  }
+
+  setImpl(aBuilder);
+  setBuilderType(OCCT_BRepBuilderAPI_MakeShape);
+
+  if(!aBuilder->IsDone()) {
+    myError = "Mirror builder :: source shape does not contain any actual shape.";
+    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);
+}
\ No newline at end of file
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Symmetry.h b/src/GeomAlgoAPI/GeomAlgoAPI_Symmetry.h
new file mode 100644 (file)
index 0000000..955e06a
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (C) 2014-2016 CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_Symmetry.h
+// Created:     30 Nov 2016
+// Author:      Clarisse Genrault (CEA)
+
+#ifndef GEOMALGOAPI_SYMMETRY_H_
+#define GEOMALGOAPI_SYMMETRY_H_
+
+#include <GeomAlgoAPI.h>
+#include <GeomAlgoAPI_MakeShape.h>
+
+#include <GeomAPI_Pnt.h>
+#include <GeomAPI_Ax1.h>
+#include <GeomAPI_Ax2.h>
+
+/// \class GeomAlgoAPI_Symmetry
+/// \ingroup DataAlgo
+/// \brief Creates a copy of the object by performing a symmetry operation by a point,
+///        by an axis or by a plane.
+class GeomAlgoAPI_Symmetry : public GeomAlgoAPI_MakeShape
+{
+public:
+  /// Type of mirror operation
+  enum MethodType {
+    BY_POINT, ///< Mirror by point.
+    BY_AXIS,  ///< Mirror by axis.
+    BY_PLANE  ///< Mirror by plane.
+  };
+
+  /// \brief Creates an object which is obtained from current object by performing
+  ///        a symmetry operation by a point.
+  /// \param[in] theSourceShape  a shape to be moved.
+  /// \param[in] thePoint         symmetry point.
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_Symmetry(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                          std::shared_ptr<GeomAPI_Pnt>   thePoint);
+
+  /// \brief Creates an object which is obtained from current object by performing
+  ///        a symmetry operation by a point.
+  /// \param[in] theSourceShape  a shape to be moved.
+  /// \param[in] theAxis         symmetry axis.
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_Symmetry(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                          std::shared_ptr<GeomAPI_Ax1>   theAxis);
+
+  /// \brief Creates an object which is obtained from current object by performing
+  ///        a symmetry operation by a point.
+  /// \param[in] theSourceShape  a shape to be moved.
+  /// \param[in] thePlane        symmetry plane.
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_Symmetry(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                          std::shared_ptr<GeomAPI_Ax2>   thePlane);
+
+  /// Checks if data for the translation execution is OK.
+  GEOMALGOAPI_EXPORT bool check();
+
+  /// Execute the translation.
+  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> myPoint; /// Reflection point.
+  std::shared_ptr<GeomAPI_Ax1> myAxis; /// Reflection axis.
+  std::shared_ptr<GeomAPI_Ax2> myPlane; /// Reflection plane.
+};
+
+#endif // GEOMALGOAPI_SYMMETRY_H_
index e39352b1ecde107c2885ab192b0ac644d3c4526b..b759eebd409ea04601cc369e4bea0f4292379a51 100644 (file)
@@ -47,6 +47,7 @@
   #include "GeomAlgoAPI_Box.h"
   #include "GeomAlgoAPI_ConeSegment.h"
   #include "GeomAlgoAPI_Copy.h"
+  #include "GeomAlgoAPI_Symmetry.h"
 
   #include <memory>
   #include <string>
diff --git a/src/GeomAlgoAPI/Test/TestAPI_Symmetry.py b/src/GeomAlgoAPI/Test/TestAPI_Symmetry.py
new file mode 100644 (file)
index 0000000..409d398
--- /dev/null
@@ -0,0 +1,48 @@
+# Copyright (C) 2014-2016 CEA/DEN, EDF R&D
+
+# File:        TestAPI_Symmetry.py
+# Created:     15 Nov 2016
+# Author:      Clarisse Genrault (CEA)
+
+from GeomAlgoAPI import GeomAlgoAPI_ShapeAPI as shaperpy
+from GeomAlgoAPI import GeomAlgoAPI_Exception as myExcept
+from GeomAPI import GeomAPI_Ax1 as axis
+from GeomAPI import GeomAPI_Ax2 as plane
+from GeomAPI import GeomAPI_Pnt as pnt
+from GeomAPI import GeomAPI_Dir as direction
+
+# Create a box
+try :
+  box1 = shaperpy.makeBox(10.,10.,10.)
+  box2 = shaperpy.makeBox(10.,10.,10.)
+  box3 = shaperpy.makeBox(10.,10.,10.)
+except myExcept, ec:
+  print ec.what()
+
+# Perfom a symmetry by a point.
+try :
+  origin = pnt(0.,0.,0.)
+  symmetry1 = shaperpy.makeSymmetry(box1,origin)
+except myExcept, ec:
+  print ec.what()
+
+# Perfom a symmetry by an axis.
+try :
+  xDir = direction(1.,0.,0.)
+  xAxis = axis(origin, xDir)
+  translation2 = shaperpy.makeSymmetry(box2,xAxis)
+except myExcept, ec:
+  print ec.what()
+
+# Perfom a symmetry by a plane.
+try :
+  pnt1 = pnt(0.,0.,10.)
+  pnt2 = pnt(10.,0.,10.)
+  aPlane = plane(origin, xDir)
+  translation3 = shaperpy.makeSymmetry(box3,aPlane)
+except myExcept, ec:
+  print ec.what()
index 90c7d95fc7e295212f07735d5363f6131b02c466..07471e912a7080f7ba79e0a0ac4da4c766393943 100644 (file)
@@ -1,7 +1,7 @@
 """Package for Features plugin for the Parametric Geometry API of the Modeler.
 """
 
-from FeaturesAPI import addPlacement, addRotation, addTranslation
+from FeaturesAPI import addPlacement, addRotation, addSymmetry, addTranslation
 from FeaturesAPI import addExtrusion, addExtrusionCut, addExtrusionFuse
 from FeaturesAPI import addRevolution, addRevolutionCut, addRevolutionFuse
 from FeaturesAPI import addPipe