+ setResult(aResultPart, theResultIndex++);
+}
+
+//=================================================================================================
+static bool performShapeSymmetry(std::shared_ptr<GeomAlgoAPI_MakeShapeList>& theAlgoList,
+ GeomAPI_ShapeHierarchy& theHierarchy,
+ GeomShapePtr theBaseShape,
+ GeomTrsfPtr theTrsf,
+ bool isKeepOriginalResult,
+ const std::string& theFeatureKind,
+ std::string& theError)
+{
+ std::shared_ptr<GeomAlgoAPI_Transform> aSymmetryAlgo(
+ new GeomAlgoAPI_Transform(theBaseShape, theTrsf));
+
+ // Checking that the algorithm worked properly.
+ if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aSymmetryAlgo, theFeatureKind, theError))
+ return false;
+
+ theAlgoList->appendAlgo(aSymmetryAlgo);
+
+ // Compose source shape and the result of symmetry.
+ GeomShapePtr aCompound;
+ if (isKeepOriginalResult) {
+ ListOfShape aShapes;
+ // add a copy of a base shape otherwise selection of this base shape is bad (2592)
+ std::shared_ptr<GeomAlgoAPI_Copy> aCopyAlgo(new GeomAlgoAPI_Copy(theBaseShape));
+ aShapes.push_back(aCopyAlgo->shape());
+ theAlgoList->appendAlgo(aCopyAlgo);
+
+ aShapes.push_back(aSymmetryAlgo->shape());
+ aCompound = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
+ }
+ else
+ aCompound = aSymmetryAlgo->shape();
+
+ theHierarchy.markModified(theBaseShape, aCompound);
+ return true;
+}
+
+void FeaturesPlugin_Symmetry::performSymmetry(GeomTrsfPtr theTrsf)
+{
+ if (!theTrsf) {
+ setError("Invalid transformation.");
+ return;
+ }
+
+ bool isKeepOriginal = boolean(KEEP_ORIGINAL_RESULT())->value();
+ bool isKeepSubShapes = data()->version() == SYMMETRY_VERSION_1;
+
+ // Getting objects.
+ GeomAPI_ShapeHierarchy anObjects;
+ std::list<ResultPtr> aParts;
+ ResultPtr aTextureSource;
+ AttributeSelectionListPtr anObjSelList = selectionList(OBJECTS_LIST_ID());
+ if (!FeaturesPlugin_Tools::shapesFromSelectionList(
+ anObjSelList, isKeepSubShapes, anObjects, aParts, aTextureSource))
+ return;
+
+ std::string anError;
+ int aResultIndex = 0;
+ // Symmetrying parts.
+ for (std::list<ResultPtr>::iterator aPRes = aParts.begin(); aPRes != aParts.end(); ++aPRes) {
+ ResultPartPtr anOriginal = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aPRes);
+ buildResult(anOriginal, theTrsf, aResultIndex);
+ }
+
+ // Collect transformations for each object in a part.
+ std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList);
+ for (GeomAPI_ShapeHierarchy::iterator anObjectsIt = anObjects.begin();
+ anObjectsIt != anObjects.end(); ++anObjectsIt) {
+ std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
+ if (!performShapeSymmetry(aMakeShapeList, anObjects, aBaseShape, theTrsf,
+ isKeepOriginal, getKind(), anError)) {
+ setError(anError);
+ break;
+ }
+ }
+
+ // Build results of the rotation.
+ const ListOfShape& anOriginalShapes = anObjects.objects();
+ ListOfShape aTopLevel;
+ anObjects.topLevelObjects(aTopLevel);
+ for (ListOfShape::iterator anIt = aTopLevel.begin(); anIt != aTopLevel.end(); ++anIt)
+ buildResult(aMakeShapeList, anOriginalShapes, *anIt, aResultIndex, aTextureSource);
+
+ // Remove the rest results if there were produced in the previous pass.
+ removeResults(aResultIndex);