X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FFeaturesPlugin%2FFeaturesPlugin_Placement.cpp;h=efc09092acf21eee33242bd10659d3541a7c11ae;hb=1fd15bed1c62f994a3438bc4a12f44d0361f98c9;hp=3ba02779f5b5a7cdb10b849ae6676bb742986070;hpb=7fcf163a8a369889707c5b73eeeb2bc68a4b906e;p=modules%2Fshaper.git diff --git a/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp b/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp index 3ba02779f..efc09092a 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp @@ -1,155 +1,232 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> - -// File: FeaturesPlugin_Placement.cpp -// Created: 2 Dec 2014 -// Author: Artem ZHIDKOV +// Copyright (C) 2014-2021 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// #include "FeaturesPlugin_Placement.h" #include #include +#include #include #include +#include +#include +#include #include #include #include +#include +#include + +#include #include +#include +#include + +#include + +static const std::string PLACEMENT_VERSION_1("v9.5"); -#define _MODIFIEDF_TAG 1 -#define _MODIFIEDE_TAG 2 -#define _MODIFIEDV_TAG 3 -#define _FACE 4 FeaturesPlugin_Placement::FeaturesPlugin_Placement() { } void FeaturesPlugin_Placement::initAttributes() { - data()->addAttribute(FeaturesPlugin_Placement::BASE_OBJECT_ID(), ModelAPI_AttributeSelection::typeId()); - data()->addAttribute(FeaturesPlugin_Placement::ATTRACT_OBJECT_ID(), ModelAPI_AttributeSelection::typeId()); - data()->addAttribute(FeaturesPlugin_Placement::REVERSE_ID(), ModelAPI_AttributeBoolean::typeId()); - data()->addAttribute(FeaturesPlugin_Placement::CENTERING_ID(), ModelAPI_AttributeBoolean::typeId()); + AttributeSelectionListPtr aSelection = + std::dynamic_pointer_cast(data()->addAttribute( + OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId())); + + data()->addAttribute(START_SHAPE_ID(), ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(END_SHAPE_ID(), ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(REVERSE_ID(), ModelAPI_AttributeBoolean::typeId()); + data()->addAttribute(CENTERING_ID(), ModelAPI_AttributeBoolean::typeId()); + + if (!aSelection->isInitialized()) { + // new feature, not read from file + data()->setVersion(PLACEMENT_VERSION_1); + } } void FeaturesPlugin_Placement::execute() { - // Verify the base face - std::shared_ptr anObjRef = std::dynamic_pointer_cast< - ModelAPI_AttributeSelection>(data()->attribute(FeaturesPlugin_Placement::BASE_OBJECT_ID())); - if (!anObjRef) + bool isKeepSubShapes = data()->version() == PLACEMENT_VERSION_1; + + // Getting objects. + GeomAPI_ShapeHierarchy anObjects; + std::list aParts; + std::string theTextureFile; + AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECTS_LIST_ID()); + if (!FeaturesPlugin_Tools::shapesFromSelectionList( + anObjectsSelList, isKeepSubShapes, anObjects, aParts, theTextureFile)) return; - std::shared_ptr aBaseShape = - std::dynamic_pointer_cast(anObjRef->value()); - if (!aBaseShape) + // Verify the start shape + AttributeSelectionPtr anObjRef = selection(START_SHAPE_ID()); + if(!anObjRef) { return; + } + std::shared_ptr aStartShape = anObjRef->value(); + if(!aStartShape) { + static const std::string aSelectionError = "Error: The start shape selection is bad."; + setError(aSelectionError); + return; + } - std::shared_ptr aBaseObject; + + std::shared_ptr aStartShapeContext; ResultPtr aContextRes = anObjRef->context(); - if (aContextRes) { - if (aContextRes->groupName() == ModelAPI_ResultBody::group()) - aBaseObject = std::dynamic_pointer_cast(aContextRes)->shape(); - else if (aContextRes->groupName() == ModelAPI_ResultConstruction::group()) - aBaseObject = std::dynamic_pointer_cast(aContextRes)->shape(); - } - if (!aBaseObject) { - static const std::string aContextError = "The selection context is bad"; + if (aContextRes.get()) { + aStartShapeContext = aContextRes->shape(); + } + if(!aStartShapeContext.get()) { + static const std::string aContextError = "Error: The start shape selection context is bad."; setError(aContextError); return; } - // Verify the attractive face - anObjRef = std::dynamic_pointer_cast( - data()->attribute(FeaturesPlugin_Placement::ATTRACT_OBJECT_ID())); - - std::shared_ptr aSlaveShape = - std::dynamic_pointer_cast(anObjRef->value()); - if (!aSlaveShape) + // Verify the end shape + anObjRef = selection(END_SHAPE_ID()); + std::shared_ptr anEndShape = anObjRef->value(); + if(!anEndShape) { + static const std::string aSelectionError = "Error: The end shape selection is bad."; + setError(aSelectionError); return; + } - std::shared_ptr aSlaveObject; + std::shared_ptr anEndShapeContext; aContextRes = anObjRef->context(); - if (aContextRes) { - if (aContextRes->groupName() == ModelAPI_ResultBody::group()) - aSlaveObject = std::dynamic_pointer_cast(aContextRes)->shape(); - else if (aContextRes->groupName() == ModelAPI_ResultConstruction::group()) - aSlaveObject = std::dynamic_pointer_cast(aContextRes)->shape(); - } - if (!aSlaveObject) { - static const std::string aContextError = "The selection context is bad"; + if(aContextRes.get()) { + anEndShapeContext = aContextRes->shape(); + } + if(!anEndShapeContext.get()) { + static const std::string aContextError = "Error: The end shape selection context is bad."; setError(aContextError); return; } // Verify planarity of faces and linearity of edges - std::shared_ptr aShapes[2] = {aBaseShape, aSlaveShape}; + std::shared_ptr aShapes[2] = {aStartShape, anEndShape}; for (int i = 0; i < 2; i++) { - if (aShapes[i]->isFace()) { - std::shared_ptr aFace(new GeomAPI_Face(aShapes[i])); - if (!aFace->isPlanar()) { - static const std::string aPlanarityError = "One of selected faces is not planar"; - setError(aPlanarityError); - return; - } - } - else if (aShapes[i]->isEdge()) { - std::shared_ptr anEdge(new GeomAPI_Edge(aShapes[i])); - if (!anEdge->isLine()) { - static const std::string aLinearityError = "One of selected endges is not linear"; - setError(aLinearityError); - return; - } + if (!isShapeValid(aShapes[i])) { + return; } } // Flags of the Placement - AttributeBooleanPtr aBoolAttr = std::dynamic_pointer_cast( - data()->attribute(FeaturesPlugin_Placement::REVERSE_ID())); - bool isReverse = aBoolAttr->value(); - aBoolAttr = std::dynamic_pointer_cast( - data()->attribute(FeaturesPlugin_Placement::CENTERING_ID())); - bool isCentering = aBoolAttr->value(); - - std::shared_ptr aResultBody = document()->createBody(data()); - GeomAlgoAPI_Placement aFeature(aSlaveObject, aBaseObject, aSlaveShape, aBaseShape, isReverse, isCentering); - if(!aFeature.isDone()) { - static const std::string aFeatureError = "Placement algorithm failed"; + bool isReverse = boolean(REVERSE_ID())->value(); + bool isCentering = boolean(CENTERING_ID())->value(); + + // Getting transformation. + GeomAlgoAPI_Placement aPlacementAlgo( + aStartShapeContext, anEndShapeContext, aStartShape, anEndShape, isReverse, isCentering, true); + if(!aPlacementAlgo.isDone()) { + static const std::string aFeatureError = "Error: Placement algorithm failed."; setError(aFeatureError); return; } + std::shared_ptr aTrsf = aPlacementAlgo.transformation(); + + int aResultIndex = 0; + std::string anError; + for (std::list::iterator aPRes = aParts.begin(); aPRes != aParts.end(); ++aPRes) { + // Applying transformation to each part. + ResultPartPtr anOrigin = std::dynamic_pointer_cast(*aPRes); + ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex); + aResultPart->setTrsf(aContextRes, aTrsf); + setResult(aResultPart, aResultIndex++); + } - // Check if shape is valid - if (aFeature.shape()->isNull()) { - static const std::string aShapeError = "Resulting shape is Null"; - setError(aShapeError); - return; + // Collect transformations for each object. + std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList); + + for(GeomAPI_ShapeHierarchy::iterator anObjectsIt = anObjects.begin(); + anObjectsIt != anObjects.end(); anObjectsIt++) { + std::shared_ptr aBaseShape = *anObjectsIt; + std::shared_ptr aTransformAlgo( + new GeomAlgoAPI_Transform(aBaseShape, aTrsf)); + + // Checking that the algorithm worked properly. + if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aTransformAlgo, getKind(), anError)) { + setError(anError); + break; + } + + anObjects.markModified(aBaseShape, aTransformAlgo->shape()); + aMakeShapeList->appendAlgo(aTransformAlgo); + } + + // Build results of the operation. + const ListOfShape& anOriginalShapes = anObjects.objects(); + ListOfShape aTopLevel; + anObjects.topLevelObjects(aTopLevel); + for (ListOfShape::iterator anIt = aTopLevel.begin(); anIt != aTopLevel.end(); ++anIt) { + //LoadNamingDS + ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); + FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(), + aMakeShapeList, *anIt, "Placed"); + aResultBody->setTextureFile(theTextureFile); + setResult(aResultBody, aResultIndex++); } - if(!aFeature.isValid()) { - std::string aFeatureError = "Warning: resulting shape is not valid"; - setError(aFeatureError); - return; - } - //LoadNamingDS - LoadNamingDS(aFeature, aResultBody, aSlaveObject); - setResult(aResultBody); + // Remove the rest results if there were produced in the previous pass. + removeResults(aResultIndex); } -//============================================================================ -void FeaturesPlugin_Placement::LoadNamingDS( - GeomAlgoAPI_Placement& theFeature, - std::shared_ptr theResultBody, - std::shared_ptr theSlaveObject) +//================================================================================================== +bool FeaturesPlugin_Placement::isShapeValid(GeomShapePtr theShape) { - //load result - theResultBody->storeModified(theSlaveObject, theFeature.shape()); // the initial Slave, the resulting Slave + if (theShape->isCompound()) { + GeomAPI_Shape::ShapeType aShapeType = GeomAPI_Shape::SHAPE; + for (GeomAPI_ShapeIterator anIt(theShape); anIt.more(); anIt.next()) { + GeomShapePtr aCurrentShape = anIt.current(); + if (aShapeType == GeomAPI_Shape::SHAPE) { + aShapeType = aCurrentShape->shapeType(); + } + else if (aShapeType != aCurrentShape->shapeType()) { + static const std::string aLinearityError = + "Error: Selected compound contains shapes with different types."; + setError(aLinearityError); + return false; + } - GeomAPI_DataMapOfShapeShape* aSubShapes = new GeomAPI_DataMapOfShapeShape(); - theFeature.mapOfShapes(*aSubShapes); - - // put modifed faces in DF - std::string aModName = "Modified"; - theResultBody->loadAndOrientModifiedShapes(theFeature.makeShape(), theSlaveObject, _FACE, _MODIFIEDF_TAG, aModName, *aSubShapes); + if (!isShapeValid(aCurrentShape)) { + return false; + } + } + } + else if (theShape->isFace()) { + std::shared_ptr aFace(new GeomAPI_Face(theShape)); + if (!aFace->isPlanar()) { + static const std::string aPlanarityError = "Error: One of selected faces is not planar."; + setError(aPlanarityError); + return false; + } + } + else if (theShape->isEdge()) { + std::shared_ptr anEdge(new GeomAPI_Edge(theShape)); + if (!anEdge->isLine()) { + static const std::string aLinearityError = "Error: One of selected edges is not linear."; + setError(aLinearityError); + return false; + } + } + return true; }