Salome HOME
Task 2.6. Behavior of the Symmetry feature
authorazv <azv@opencascade.com>
Tue, 22 May 2018 13:03:39 +0000 (16:03 +0300)
committerazv <azv@opencascade.com>
Tue, 22 May 2018 13:04:26 +0000 (16:04 +0300)
* Symmetry has been renamed to Mirror Copy
* Original shape is kept when mirroring

src/FeaturesAPI/FeaturesAPI_Symmetry.cpp
src/FeaturesAPI/FeaturesAPI_Symmetry.h
src/FeaturesPlugin/FeaturesPlugin_Symmetry.cpp
src/FeaturesPlugin/FeaturesPlugin_Symmetry.h
src/FeaturesPlugin/plugin-Features.xml
src/ModelAPI/Test/TestCustomName_Recover.py
src/PythonAPI/model/features/__init__.py
test.API/SHAPER/Transformations/TestSymmetry.py

index 8f48cc96599a72169e5a8c359351bdab651814da..6e8b8b6220b5557d4e7cbd53bd241c750415bfba 100644 (file)
@@ -32,8 +32,8 @@ FeaturesAPI_Symmetry::FeaturesAPI_Symmetry(const std::shared_ptr<ModelAPI_Featur
 
 //==================================================================================================
 FeaturesAPI_Symmetry::FeaturesAPI_Symmetry(const std::shared_ptr<ModelAPI_Feature>& theFeature,
-                                       const std::list<ModelHighAPI_Selection>& theMainObjects,
-                                       const ModelHighAPI_Selection& theObject)
+                                           const std::list<ModelHighAPI_Selection>& theMainObjects,
+                                           const ModelHighAPI_Selection& theObject)
 : ModelHighAPI_Interface(theFeature)
 {
   if(initialize()) {
@@ -98,7 +98,7 @@ void FeaturesAPI_Symmetry::dump(ModelHighAPI_Dumper& theDumper) const
 
   AttributeSelectionListPtr anAttrObjects =
     aBase->selectionList(FeaturesPlugin_Symmetry::OBJECTS_LIST_ID());
-  theDumper << aBase << " = model.addSymmetry(" << aDocName << ", " << anAttrObjects;
+  theDumper << aBase << " = model.addMirror(" << aDocName << ", " << anAttrObjects;
 
   std::string aCreationMethod =
     aBase->string(FeaturesPlugin_Symmetry::CREATION_METHOD())->value();
@@ -121,9 +121,9 @@ void FeaturesAPI_Symmetry::dump(ModelHighAPI_Dumper& theDumper) const
 }
 
 //==================================================================================================
-SymmetryPtr addSymmetry(const std::shared_ptr<ModelAPI_Document>& thePart,
-                              const std::list<ModelHighAPI_Selection>& theMainObjects,
-                              const ModelHighAPI_Selection& theObject)
+SymmetryPtr addMirror(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));
index 77ef644980ce7d3f3ccbf55da13f0d97fc290131..1b4ab9dacdc172394ea5a61c59474484976e3c20 100644 (file)
@@ -34,7 +34,7 @@ class ModelHighAPI_Selection;
 
 /// \class FeaturesAPI_Symmetry
 /// \ingroup CPPHighAPI
-/// \brief Interface for Symmetry feature.
+/// \brief Interface for the Mirror Copy feature.
 class FeaturesAPI_Symmetry: public ModelHighAPI_Interface
 {
 public:
@@ -45,8 +45,8 @@ public:
   /// 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);
+                                const std::list<ModelHighAPI_Selection>& theMainObjects,
+                                const ModelHighAPI_Selection& theObject);
 
   /// Destructor.
   FEATURESAPI_EXPORT
@@ -89,10 +89,10 @@ public:
 typedef std::shared_ptr<FeaturesAPI_Symmetry> SymmetryPtr;
 
 /// \ingroup CPPHighAPI
-/// \brief Create Symmetry feature.
+/// \brief Create the Mirror Copy feature.
 FEATURESAPI_EXPORT
-SymmetryPtr addSymmetry(const std::shared_ptr<ModelAPI_Document>& thePart,
-                    const std::list<ModelHighAPI_Selection>& theMainObjects,
-                    const ModelHighAPI_Selection& theObject);
+SymmetryPtr addMirror(const std::shared_ptr<ModelAPI_Document>& thePart,
+                      const std::list<ModelHighAPI_Selection>& theMainObjects,
+                      const ModelHighAPI_Selection& theObject);
 
 #endif // FEATURESAPI_SYMMETRY_H_
index 7121e968d710362ec4be831088e383c6ba14f249..418913246cdd883fae29ab0f9c868cdcd0f7e8ef 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <FeaturesPlugin_Symmetry.h>
 
+#include <GeomAlgoAPI_CompoundBuilder.h>
 #include <GeomAlgoAPI_PointBuilder.h>
 #include <GeomAlgoAPI_FaceBuilder.h>
 
@@ -81,27 +82,36 @@ void FeaturesPlugin_Symmetry::execute()
 }
 
 //=================================================================================================
-void FeaturesPlugin_Symmetry::performSymmetryByPoint()
+bool FeaturesPlugin_Symmetry::collectSourceObjects(ListOfShape& theSourceShapes,
+                                                   std::list<ResultPtr>& theSourceResults)
 {
-  // Getting objects.
-  ListOfShape anObjects;
-  std::list<ResultPtr> aContextes;
   AttributeSelectionListPtr anObjectsSelList =
     selectionList(FeaturesPlugin_Symmetry::OBJECTS_LIST_ID());
   if (anObjectsSelList->size() == 0) {
-    return;
+    return false;
   }
-  for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
+  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
+    if (!anObject.get()) { // may be for not-activated parts
       eraseResults();
-      return;
+      return false;
     }
-    anObjects.push_back(anObject);
-    aContextes.push_back(anObjectAttr->context());
+    theSourceShapes.push_back(anObject);
+    theSourceResults.push_back(anObjectAttr->context());
   }
+  return true;
+}
+
+//=================================================================================================
+void FeaturesPlugin_Symmetry::performSymmetryByPoint()
+{
+  // Getting objects.
+  ListOfShape anObjects;
+  std::list<ResultPtr> aContextes;
+  if (!collectSourceObjects(anObjects, aContextes))
+    return;
 
   //Getting point.
   std::shared_ptr<GeomAPI_Pnt> aPoint;
@@ -130,10 +140,9 @@ void FeaturesPlugin_Symmetry::performSymmetryByPoint()
       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 {
+      buildResult(anOrigin, aTrsf, aResultIndex);
+    }
+    else {
       GeomAlgoAPI_Symmetry aSymmetryAlgo(aBaseShape, aPoint);
 
       if (!aSymmetryAlgo.check()) {
@@ -160,9 +169,7 @@ void FeaturesPlugin_Symmetry::performSymmetryByPoint()
         break;
       }
 
-      ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
-      loadNamingDS(aSymmetryAlgo, aResultBody, aBaseShape);
-      setResult(aResultBody, aResultIndex);
+      buildResult(aSymmetryAlgo, aBaseShape, aResultIndex);
     }
     aResultIndex++;
   }
@@ -177,22 +184,8 @@ void FeaturesPlugin_Symmetry::performSymmetryByAxis()
   // Getting objects.
   ListOfShape anObjects;
   std::list<ResultPtr> aContextes;
-  AttributeSelectionListPtr anObjectsSelList =
-    selectionList(FeaturesPlugin_Symmetry::OBJECTS_LIST_ID());
-  if (anObjectsSelList->size() == 0) {
+  if (!collectSourceObjects(anObjects, aContextes))
     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;
@@ -223,10 +216,9 @@ void FeaturesPlugin_Symmetry::performSymmetryByAxis()
       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 {
+      buildResult(anOrigin, aTrsf, aResultIndex);
+    }
+    else {
       GeomAlgoAPI_Symmetry aSymmetryAlgo(aBaseShape, anAxis);
 
       if (!aSymmetryAlgo.check()) {
@@ -253,9 +245,7 @@ void FeaturesPlugin_Symmetry::performSymmetryByAxis()
         break;
       }
 
-      ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
-      loadNamingDS(aSymmetryAlgo, aResultBody, aBaseShape);
-      setResult(aResultBody, aResultIndex);
+      buildResult(aSymmetryAlgo, aBaseShape, aResultIndex);
     }
     aResultIndex++;
   }
@@ -270,22 +260,8 @@ void FeaturesPlugin_Symmetry::performSymmetryByPlane()
   // Getting objects.
   ListOfShape anObjects;
   std::list<ResultPtr> aContextes;
-  AttributeSelectionListPtr anObjectsSelList =
-    selectionList(FeaturesPlugin_Symmetry::OBJECTS_LIST_ID());
-  if (anObjectsSelList->size() == 0) {
+  if (!collectSourceObjects(anObjects, aContextes))
     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;
@@ -318,9 +294,7 @@ void FeaturesPlugin_Symmetry::performSymmetryByPlane()
       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);
+      buildResult(anOrigin, aTrsf, aResultIndex);
     } else {
       GeomAlgoAPI_Symmetry aSymmetryAlgo(aBaseShape, aPlane);
 
@@ -348,9 +322,7 @@ void FeaturesPlugin_Symmetry::performSymmetryByPlane()
         break;
       }
 
-      ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
-      loadNamingDS(aSymmetryAlgo, aResultBody, aBaseShape);
-      setResult(aResultBody, aResultIndex);
+      buildResult(aSymmetryAlgo, aBaseShape, aResultIndex);
     }
     aResultIndex++;
   }
@@ -359,14 +331,46 @@ void FeaturesPlugin_Symmetry::performSymmetryByPlane()
   removeResults(aResultIndex);
 }
 
+//=================================================================================================
+void FeaturesPlugin_Symmetry::buildResult(GeomAlgoAPI_Symmetry& theSymmetryAlgo,
+                                          std::shared_ptr<GeomAPI_Shape> theBaseShape,
+                                          int theResultIndex)
+{
+  // Compose source shape and the result of symmetry.
+  ListOfShape aShapes;
+  aShapes.push_back(theBaseShape);
+  aShapes.push_back(theSymmetryAlgo.shape());
+  std::shared_ptr<GeomAPI_Shape> aCompound = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
+
+  // Store and name the result.
+  ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
+  aResultBody->storeModified(theBaseShape, aCompound);
+  loadNamingDS(theSymmetryAlgo, aResultBody, theBaseShape);
+  setResult(aResultBody, theResultIndex);
+}
+
+//=================================================================================================
+void FeaturesPlugin_Symmetry::buildResult(ResultPartPtr theOriginal,
+                                          std::shared_ptr<GeomAPI_Trsf> theTrsf,
+                                          int& theResultIndex)
+{
+  std::shared_ptr<GeomAPI_Trsf> anIdentity(new GeomAPI_Trsf());
+  ResultPartPtr aCopy = document()->copyPart(theOriginal, data(), theResultIndex);
+  aCopy->setTrsf(theOriginal, anIdentity);
+  setResult(aCopy, theResultIndex);
+
+  ++theResultIndex;
+
+  ResultPartPtr aResultPart = document()->copyPart(theOriginal, data(), theResultIndex);
+  aResultPart->setTrsf(theOriginal, theTrsf);
+  setResult(aResultPart, theResultIndex);
+}
+
 //=================================================================================================
 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();
   std::string aReflectedName = "Symmetried";
index aa67bd79b72580d9c245a18f0bb0bfbf8e38c668..edb152dd117499dc8af9c0bf6746c5efb2379327 100644 (file)
@@ -27,6 +27,8 @@
 
 #include <GeomAlgoAPI_Symmetry.h>
 
+class GeomAPI_Trsf;
+
 /** \class FeaturesPlugin_Symmetry
  *  \ingroup Plugins
  *  \brief Feature that performs reflection with respect to a point, axis, or plane.
@@ -37,7 +39,7 @@ class FeaturesPlugin_Symmetry : public ModelAPI_Feature
   /// Symmetry kind.
   inline static const std::string& ID()
   {
-    static const std::string MY_SYMMETRY_ID("Symmetry");
+    static const std::string MY_SYMMETRY_ID("MirrorCopy");
     return MY_SYMMETRY_ID;
   }
 
@@ -114,6 +116,10 @@ class FeaturesPlugin_Symmetry : public ModelAPI_Feature
   FeaturesPlugin_Symmetry();
 
 private:
+  /// Obtain list of source objects of the mirror
+  bool collectSourceObjects(ListOfShape& theSourceShapes,
+                            std::list<std::shared_ptr<ModelAPI_Result>>& theSourceResults);
+
   /// Perform symmetry with respect to a point.
   void performSymmetryByPoint();
 
@@ -127,6 +133,16 @@ private:
   void loadNamingDS(GeomAlgoAPI_Symmetry& theSymmetryAlgo,
                     std::shared_ptr<ModelAPI_ResultBody> theResultBody,
                     std::shared_ptr<GeomAPI_Shape> theBaseShape);
+
+  /// Create new result on given shapes and the index of result
+  void buildResult(GeomAlgoAPI_Symmetry& theSymmetryAlgo,
+                   std::shared_ptr<GeomAPI_Shape> theBaseShape,
+                   int theResultIndex);
+
+  /// Create new result for the given part and transformation
+  void buildResult(std::shared_ptr<ModelAPI_ResultPart> theOriginal,
+                   std::shared_ptr<GeomAPI_Trsf> theTrsf,
+                   int& theResultIndex);
 };
 
 #endif // FEATURESPLUGIN_SYMMETRY_H_
index 88c1c02908bff6ea939f6287c325168571af6078..31d9e290331f6f9bb1d6961a04d37e0c29d30ad6 100644 (file)
@@ -97,7 +97,7 @@ email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com
       <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">
+      <feature id="MirrorCopy" title="Mirror copy" 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="LinearCopy" title="Linear copy" tooltip="Perform copy and translate" icon="icons/Features/multitranslation.png">
index e069c44fb65b3a7eab72b4bfa3c8bd4198ff7341..cae44462df16b2c985e665bc34e7153537801d19 100644 (file)
@@ -27,7 +27,7 @@ Part_1_doc = Part_1.document()
 Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
 Cylinder_1.result().setName("cylinder")
 Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "cylinder/Face_2"), 10, False)
-Symmetry_1 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "cylinder")], model.selection("FACE", "Plane_1"))
+Symmetry_1 = model.addMirror(Part_1_doc, [model.selection("SOLID", "cylinder")], model.selection("FACE", "Plane_1"))
 model.do()
 
 # check the name of the Symmetry
index 0347b26b273484f14c39702e969245bb5e132788..fb5939d5f972519a16e78016905bb2270d06e705 100644 (file)
@@ -1,7 +1,7 @@
 """Package for Features plugin for the Parametric Geometry API of the Modeler.
 """
 
-from FeaturesAPI import addPlacement, addRotation, addScale, addSymmetry, addTranslation
+from FeaturesAPI import addPlacement, addRotation, addScale, addMirror, addTranslation
 from FeaturesAPI import addMultiTranslation, addMultiRotation
 from FeaturesAPI import addExtrusion, addExtrusionCut, addExtrusionFuse
 from FeaturesAPI import addRevolution, addRevolutionCut, addRevolutionFuse
index 161a53449815671c6ba03969bc2e4813b419bd28..d7e0195fac79fdf93d704544ffdd094f9df200f4 100644 (file)
@@ -104,26 +104,26 @@ Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-Sketc
 
 
 # Symmetries
-Symmetry_1 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("VERTEX", "PartSet/Origin"))
-Symmetry_2 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Box_2_1")], model.selection("VERTEX", "Point_1"))
-Symmetry_3 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("VERTEX", "Box_3_1/Front&Box_3_1/Right&Box_3_1/Top"))
-Symmetry_4 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Box_4_1")], model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_1e"))
-Symmetry_5 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Box_5_1")], model.selection("VERTEX", "Vertex_1_1"))
-Symmetry_6 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Box_6_1")], model.selection("VERTEX", "InvalidName"))
-
-Symmetry_7 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Box_7_1")], model.selection("EDGE", "PartSet/OZ"))
-Symmetry_8 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Box_8_1")], model.selection("EDGE", "Axis_1"))
-Symmetry_9 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Box_9_1")], model.selection("EDGE", "Box_9_1/Front&Box_9_1/Top"))
-Symmetry_10 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Box_10_1")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"))
-Symmetry_11 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Box_11_1")], model.selection("EDGE", "Edge_1_1"))
-Symmetry_12 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Box_12_1")], model.selection("EDGE", "InvalidName"))
-
-Symmetry_13 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Box_13_1")], model.selection("FACE", "PartSet/XOY"))
-Symmetry_14 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Box_14_1")], model.selection("FACE", "Plane_1"))
-Symmetry_15 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Box_15_1")], model.selection("FACE", "Box_15_1/Front"))
-Symmetry_16 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Box_16_1")], model.selection("FACE", "Face_1_1"))
-Symmetry_17 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Box_17_1")], model.selection("FACE", "InvalidName"))
-Symmetry_18 = model.addSymmetry(Part_1_doc, [model.selection("SHELL", "Extrusion_1_1")], model.selection("FACE", "Plane_2"))
+Symmetry_1 = model.addMirror(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("VERTEX", "PartSet/Origin"))
+Symmetry_2 = model.addMirror(Part_1_doc, [model.selection("SOLID", "Box_2_1")], model.selection("VERTEX", "Point_1"))
+Symmetry_3 = model.addMirror(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("VERTEX", "Box_3_1/Front&Box_3_1/Right&Box_3_1/Top"))
+Symmetry_4 = model.addMirror(Part_1_doc, [model.selection("SOLID", "Box_4_1")], model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_1e"))
+Symmetry_5 = model.addMirror(Part_1_doc, [model.selection("SOLID", "Box_5_1")], model.selection("VERTEX", "Vertex_1_1"))
+Symmetry_6 = model.addMirror(Part_1_doc, [model.selection("SOLID", "Box_6_1")], model.selection("VERTEX", "InvalidName"))
+
+Symmetry_7 = model.addMirror(Part_1_doc, [model.selection("SOLID", "Box_7_1")], model.selection("EDGE", "PartSet/OZ"))
+Symmetry_8 = model.addMirror(Part_1_doc, [model.selection("SOLID", "Box_8_1")], model.selection("EDGE", "Axis_1"))
+Symmetry_9 = model.addMirror(Part_1_doc, [model.selection("SOLID", "Box_9_1")], model.selection("EDGE", "Box_9_1/Front&Box_9_1/Top"))
+Symmetry_10 = model.addMirror(Part_1_doc, [model.selection("SOLID", "Box_10_1")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"))
+Symmetry_11 = model.addMirror(Part_1_doc, [model.selection("SOLID", "Box_11_1")], model.selection("EDGE", "Edge_1_1"))
+Symmetry_12 = model.addMirror(Part_1_doc, [model.selection("SOLID", "Box_12_1")], model.selection("EDGE", "InvalidName"))
+
+Symmetry_13 = model.addMirror(Part_1_doc, [model.selection("SOLID", "Box_13_1")], model.selection("FACE", "PartSet/XOY"))
+Symmetry_14 = model.addMirror(Part_1_doc, [model.selection("SOLID", "Box_14_1")], model.selection("FACE", "Plane_1"))
+Symmetry_15 = model.addMirror(Part_1_doc, [model.selection("SOLID", "Box_15_1")], model.selection("FACE", "Box_15_1/Front"))
+Symmetry_16 = model.addMirror(Part_1_doc, [model.selection("SOLID", "Box_16_1")], model.selection("FACE", "Face_1_1"))
+Symmetry_17 = model.addMirror(Part_1_doc, [model.selection("SOLID", "Box_17_1")], model.selection("FACE", "InvalidName"))
+Symmetry_18 = model.addMirror(Part_1_doc, [model.selection("SHELL", "Extrusion_1_1")], model.selection("FACE", "Plane_2"))
 
 model.do()
 model.end()
@@ -132,87 +132,87 @@ model.end()
 from GeomAPI import GeomAPI_Shape
 
 model.testNbResults(Symmetry_1, 1)
-model.testNbSubResults(Symmetry_1, [0])
-model.testNbSubShapes(Symmetry_1, GeomAPI_Shape.SOLID, [1])
-model.testNbSubShapes(Symmetry_1, GeomAPI_Shape.FACE, [6])
+model.testNbSubResults(Symmetry_1, [2])
+model.testNbSubShapes(Symmetry_1, GeomAPI_Shape.SOLID, [2])
+model.testNbSubShapes(Symmetry_1, GeomAPI_Shape.FACE, [12])
 model.testHaveNamingFaces(Symmetry_1, model, Part_1_doc)
 
 model.testNbResults(Symmetry_2, 1)
-model.testNbSubResults(Symmetry_2, [0])
-model.testNbSubShapes(Symmetry_2, GeomAPI_Shape.SOLID, [1])
-model.testNbSubShapes(Symmetry_2, GeomAPI_Shape.FACE, [6])
+model.testNbSubResults(Symmetry_2, [2])
+model.testNbSubShapes(Symmetry_2, GeomAPI_Shape.SOLID, [2])
+model.testNbSubShapes(Symmetry_2, GeomAPI_Shape.FACE, [12])
 model.testHaveNamingFaces(Symmetry_2, model, Part_1_doc)
 
 model.testNbResults(Symmetry_3, 1)
-model.testNbSubResults(Symmetry_3, [0])
-model.testNbSubShapes(Symmetry_3, GeomAPI_Shape.SOLID, [1])
-model.testNbSubShapes(Symmetry_3, GeomAPI_Shape.FACE, [6])
+model.testNbSubResults(Symmetry_3, [2])
+model.testNbSubShapes(Symmetry_3, GeomAPI_Shape.SOLID, [2])
+model.testNbSubShapes(Symmetry_3, GeomAPI_Shape.FACE, [12])
 model.testHaveNamingFaces(Symmetry_3, model, Part_1_doc)
 
 model.testNbResults(Symmetry_4, 1)
-model.testNbSubResults(Symmetry_4, [0])
-model.testNbSubShapes(Symmetry_4, GeomAPI_Shape.SOLID, [1])
-model.testNbSubShapes(Symmetry_4, GeomAPI_Shape.FACE, [6])
+model.testNbSubResults(Symmetry_4, [2])
+model.testNbSubShapes(Symmetry_4, GeomAPI_Shape.SOLID, [2])
+model.testNbSubShapes(Symmetry_4, GeomAPI_Shape.FACE, [12])
 model.testHaveNamingFaces(Symmetry_4, model, Part_1_doc)
 
 model.testNbResults(Symmetry_5, 1)
-model.testNbSubResults(Symmetry_5, [0])
-model.testNbSubShapes(Symmetry_5, GeomAPI_Shape.SOLID, [1])
-model.testNbSubShapes(Symmetry_5, GeomAPI_Shape.FACE, [6])
+model.testNbSubResults(Symmetry_5, [2])
+model.testNbSubShapes(Symmetry_5, GeomAPI_Shape.SOLID, [2])
+model.testNbSubShapes(Symmetry_5, GeomAPI_Shape.FACE, [12])
 model.testHaveNamingFaces(Symmetry_5, model, Part_1_doc)
 
 model.testNbResults(Symmetry_7, 1)
-model.testNbSubResults(Symmetry_7, [0])
-model.testNbSubShapes(Symmetry_7, GeomAPI_Shape.SOLID, [1])
-model.testNbSubShapes(Symmetry_7, GeomAPI_Shape.FACE, [6])
+model.testNbSubResults(Symmetry_7, [2])
+model.testNbSubShapes(Symmetry_7, GeomAPI_Shape.SOLID, [2])
+model.testNbSubShapes(Symmetry_7, GeomAPI_Shape.FACE, [12])
 model.testHaveNamingFaces(Symmetry_7, model, Part_1_doc)
 
 model.testNbResults(Symmetry_8, 1)
-model.testNbSubResults(Symmetry_8, [0])
-model.testNbSubShapes(Symmetry_8, GeomAPI_Shape.SOLID, [1])
-model.testNbSubShapes(Symmetry_8, GeomAPI_Shape.FACE, [6])
+model.testNbSubResults(Symmetry_8, [2])
+model.testNbSubShapes(Symmetry_8, GeomAPI_Shape.SOLID, [2])
+model.testNbSubShapes(Symmetry_8, GeomAPI_Shape.FACE, [12])
 model.testHaveNamingFaces(Symmetry_8, model, Part_1_doc)
 
 model.testNbResults(Symmetry_9, 1)
-model.testNbSubResults(Symmetry_9, [0])
-model.testNbSubShapes(Symmetry_9, GeomAPI_Shape.SOLID, [1])
-model.testNbSubShapes(Symmetry_9, GeomAPI_Shape.FACE, [6])
+model.testNbSubResults(Symmetry_9, [2])
+model.testNbSubShapes(Symmetry_9, GeomAPI_Shape.SOLID, [2])
+model.testNbSubShapes(Symmetry_9, GeomAPI_Shape.FACE, [12])
 model.testHaveNamingFaces(Symmetry_9, model, Part_1_doc)
 
 model.testNbResults(Symmetry_10, 1)
-model.testNbSubResults(Symmetry_10, [0])
-model.testNbSubShapes(Symmetry_10, GeomAPI_Shape.SOLID, [1])
-model.testNbSubShapes(Symmetry_10, GeomAPI_Shape.FACE, [6])
+model.testNbSubResults(Symmetry_10, [2])
+model.testNbSubShapes(Symmetry_10, GeomAPI_Shape.SOLID, [2])
+model.testNbSubShapes(Symmetry_10, GeomAPI_Shape.FACE, [12])
 model.testHaveNamingFaces(Symmetry_10, model, Part_1_doc)
 
 model.testNbResults(Symmetry_11, 1)
-model.testNbSubResults(Symmetry_11, [0])
-model.testNbSubShapes(Symmetry_11, GeomAPI_Shape.SOLID, [1])
-model.testNbSubShapes(Symmetry_11, GeomAPI_Shape.FACE, [6])
+model.testNbSubResults(Symmetry_11, [2])
+model.testNbSubShapes(Symmetry_11, GeomAPI_Shape.SOLID, [2])
+model.testNbSubShapes(Symmetry_11, GeomAPI_Shape.FACE, [12])
 model.testHaveNamingFaces(Symmetry_11, model, Part_1_doc)
 
 model.testNbResults(Symmetry_13, 1)
-model.testNbSubResults(Symmetry_13, [0])
-model.testNbSubShapes(Symmetry_13, GeomAPI_Shape.SOLID, [1])
-model.testNbSubShapes(Symmetry_13, GeomAPI_Shape.FACE, [6])
+model.testNbSubResults(Symmetry_13, [2])
+model.testNbSubShapes(Symmetry_13, GeomAPI_Shape.SOLID, [2])
+model.testNbSubShapes(Symmetry_13, GeomAPI_Shape.FACE, [12])
 model.testHaveNamingFaces(Symmetry_13, model, Part_1_doc)
 
 model.testNbResults(Symmetry_14, 1)
-model.testNbSubResults(Symmetry_14, [0])
-model.testNbSubShapes(Symmetry_14, GeomAPI_Shape.SOLID, [1])
-model.testNbSubShapes(Symmetry_14, GeomAPI_Shape.FACE, [6])
+model.testNbSubResults(Symmetry_14, [2])
+model.testNbSubShapes(Symmetry_14, GeomAPI_Shape.SOLID, [2])
+model.testNbSubShapes(Symmetry_14, GeomAPI_Shape.FACE, [12])
 model.testHaveNamingFaces(Symmetry_14, model, Part_1_doc)
 
 model.testNbResults(Symmetry_15, 1)
-model.testNbSubResults(Symmetry_15, [0])
-model.testNbSubShapes(Symmetry_15, GeomAPI_Shape.SOLID, [1])
-model.testNbSubShapes(Symmetry_15, GeomAPI_Shape.FACE, [6])
+model.testNbSubResults(Symmetry_15, [2])
+model.testNbSubShapes(Symmetry_15, GeomAPI_Shape.SOLID, [2])
+model.testNbSubShapes(Symmetry_15, GeomAPI_Shape.FACE, [12])
 model.testHaveNamingFaces(Symmetry_15, model, Part_1_doc)
 
 model.testNbResults(Symmetry_16, 1)
-model.testNbSubResults(Symmetry_16, [0])
-model.testNbSubShapes(Symmetry_16, GeomAPI_Shape.SOLID, [1])
-model.testNbSubShapes(Symmetry_16, GeomAPI_Shape.FACE, [6])
+model.testNbSubResults(Symmetry_16, [2])
+model.testNbSubShapes(Symmetry_16, GeomAPI_Shape.SOLID, [2])
+model.testNbSubShapes(Symmetry_16, GeomAPI_Shape.FACE, [12])
 model.testHaveNamingFaces(Symmetry_16, model, Part_1_doc)
 
 model.testNbResults(Symmetry_6, 0)
@@ -224,10 +224,9 @@ assert(Symmetry_12.feature().error() == 'Attribute "axis_object" is not initiali
 model.testNbResults(Symmetry_17, 0)
 assert(Symmetry_17.feature().error() == 'Attribute "plane_object" is not initialized.')
 
-# To uncomment when #2046 will be performed
-#model.testNbResults(Symmetry_18, 1)
-#model.testNbSubResults(Symmetry_18, [0])
-#model.testNbSubShapes(Symmetry_18, GeomAPI_Shape.SOLID, [0])
-#model.testNbSubShapes(Symmetry_18, GeomAPI_Shape.SHELL, [1])
-#model.testNbSubShapes(Symmetry_18, GeomAPI_Shape.FACE, [5])
-#model.testHaveNamingFaces(Symmetry_18, model, Part_1_doc)
\ No newline at end of file
+model.testNbResults(Symmetry_18, 1)
+model.testNbSubResults(Symmetry_18, [2])
+model.testNbSubShapes(Symmetry_18, GeomAPI_Shape.SOLID, [0])
+model.testNbSubShapes(Symmetry_18, GeomAPI_Shape.SHELL, [2])
+model.testNbSubShapes(Symmetry_18, GeomAPI_Shape.FACE, [10])
+model.testHaveNamingFaces(Symmetry_18, model, Part_1_doc)