X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FFeaturesPlugin%2FFeaturesPlugin_CompositeSketch.cpp;h=8ee137663d548bb7d3fe7ce080caa3e2abc63ac9;hb=380f01e1fce1a012267d604a1190d04bf4659447;hp=57a711e0ccc2d1598eed7cc25585c05883bf901f;hpb=5c0a5d1054fc9d185ab08b77583aa7cc4453d41a;p=modules%2Fshaper.git diff --git a/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp b/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp index 57a711e0c..8ee137663 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp @@ -1,239 +1,323 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: FeaturesPlugin_CompositeSketch.cpp -// Created: 11 September 2015 -// Author: Dmitry Bobylev +// Copyright (C) 2014-2020 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 +#include #include #include #include -#include #include #include #include -#include -#include #include -#include -#include +#include + + +static void storeSubShape(const std::shared_ptr theMakeShape, + ResultBodyPtr theResultBody, + const GeomShapePtr theShape, + const GeomAPI_Shape::ShapeType theType, + const std::string& theName); //================================================================================================= -void FeaturesPlugin_CompositeSketch::initAttributes() +void FeaturesPlugin_CompositeSketch::initCompositeSketchAttribtues(const int theInitFlags) { - data()->addAttribute(SKETCH_OBJECT_ID(), ModelAPI_AttributeReference::typeId()); - data()->addAttribute(SKETCH_SELECTION_ID(), ModelAPI_AttributeSelection::typeId()); - ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SKETCH_SELECTION_ID()); + // Initialize sketch launcher. + if(theInitFlags & InitSketchLauncher) { + data()->addAttribute(SKETCH_ID(), ModelAPI_AttributeReference::typeId()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SKETCH_ID()); + } - //initMakeSolidsAttributes(); + // Initialize selection list. + if(theInitFlags & InitBaseObjectsList) { + data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId()); + myCurrentSelectionType = selectionList(BASE_OBJECTS_ID())->selectionType(); + } } //================================================================================================= std::shared_ptr FeaturesPlugin_CompositeSketch::addFeature(std::string theID) { - std::shared_ptr aNew = document()->addFeature(theID, false); - if (aNew) { - data()->reference(SKETCH_OBJECT_ID())->setValue(aNew); + FeaturePtr aNew = document()->addFeature(theID, false); + if(aNew) { + data()->reference(SKETCH_ID())->setValue(aNew); } - // set as current also after it becomes sub to set correctly enabled for other sketch subs + + // Set as current also after it becomes sub to set correctly enabled for other sketch subs. document()->setCurrentFeature(aNew, false); return aNew; } //================================================================================================= -int FeaturesPlugin_CompositeSketch::numberOfSubs(bool forTree) const +int FeaturesPlugin_CompositeSketch::numberOfSubs(bool /*forTree*/) const { - ObjectPtr aObj = data()->reference(SKETCH_OBJECT_ID())->value(); - return aObj.get()? 1 : 0; + ObjectPtr aObj = data()->reference(SKETCH_ID())->value(); + return aObj.get() ? 1 : 0; } //================================================================================================= -std::shared_ptr FeaturesPlugin_CompositeSketch::subFeature(const int theIndex, bool forTree) +std::shared_ptr FeaturesPlugin_CompositeSketch::subFeature(const int theIndex, + bool /*forTree*/) { - if (theIndex == 0) - return std::dynamic_pointer_cast(data()->reference(SKETCH_OBJECT_ID())->value()); - return std::shared_ptr(); + FeaturePtr aSubFeature; + if(theIndex == 0) { + aSubFeature = + std::dynamic_pointer_cast(data()->reference(SKETCH_ID())->value()); + } + return aSubFeature; } //================================================================================================= int FeaturesPlugin_CompositeSketch::subFeatureId(const int theIndex) const { - if (theIndex == 0) { - FeaturePtr aFeature = - std::dynamic_pointer_cast(data()->reference(SKETCH_OBJECT_ID())->value()); - if (aFeature.get()) + if(theIndex == 0) { + FeaturePtr aFeature = + std::dynamic_pointer_cast(data()->reference(SKETCH_ID())->value()); + if(aFeature.get()) { return aFeature->data()->featureId(); + } } + return -1; } //================================================================================================= bool FeaturesPlugin_CompositeSketch::isSub(ObjectPtr theObject) const { - // check is this feature of result + bool isSubFeature = false; + // Check is this feature of result FeaturePtr aFeature = std::dynamic_pointer_cast(theObject); - if (!aFeature) - return false; - - ObjectPtr aSub = data()->reference(SKETCH_OBJECT_ID())->value(); - return aSub == theObject; + if (aFeature.get()) { + ObjectPtr aSub = data()->reference(SKETCH_ID())->value(); + isSubFeature = aSub == theObject; + } + return isSubFeature; } //================================================================================================= void FeaturesPlugin_CompositeSketch::removeFeature(std::shared_ptr theFeature) { - AttributeSelectionListPtr aFacesSelectionList = selectionList(LIST_ID()); - if (aFacesSelectionList.get() && aFacesSelectionList->size() > 0) - aFacesSelectionList->clear(); + AttributeSelectionListPtr aBaseObjectsSelectionList = selectionList(BASE_OBJECTS_ID()); + if(aBaseObjectsSelectionList.get() && aBaseObjectsSelectionList->size() > 0) { + aBaseObjectsSelectionList->clear(); + } - data()->reference(SKETCH_OBJECT_ID())->setValue(ObjectPtr()); + reference(SKETCH_ID())->setValue(ObjectPtr()); } //================================================================================================= -void FeaturesPlugin_CompositeSketch::erase() +void FeaturesPlugin_CompositeSketch::getBaseShapes(ListOfShape& theBaseShapesList, + const bool theIsMakeShells) { - if (data().get() && data()->isValid()) { // on abort of sketch of this composite it may be invalid - FeaturePtr aSketch = - std::dynamic_pointer_cast(data()->reference(SKETCH_OBJECT_ID())->value()); - if (aSketch.get() && aSketch->data()->isValid()) { - document()->removeFeature(aSketch); - } - } - ModelAPI_CompositeFeature::erase(); + AttributeSelectionListPtr aBaseObjectsSelectionList = selectionList(BASE_OBJECTS_ID()); + std::string anError; + bool isOk = FeaturesPlugin_Tools::getShape( + aBaseObjectsSelectionList, theIsMakeShells, theBaseShapesList, anError); + if (!isOk) + setError(anError); } +//================================================================================================= +void FeaturesPlugin_CompositeSketch::storeResult(const GeomShapePtr theBaseShape, + const std::shared_ptr theMakeShape, + const int theIndex) +{ + // Create result body. + ResultBodyPtr aResultBody = document()->createBody(data(), theIndex); + + // Store generated shape. + aResultBody->storeGenerated(theBaseShape, theMakeShape->shape()); + + // Store generated edges/faces. + storeGenerationHistory(aResultBody, theBaseShape, theMakeShape); + + setResult(aResultBody, theIndex); +} //================================================================================================= -void FeaturesPlugin_CompositeSketch::execute() +void FeaturesPlugin_CompositeSketch::storeGenerationHistory(ResultBodyPtr theResultBody, + const GeomShapePtr theBaseShape, + const std::shared_ptr theMakeShape) { - // Getting faces to create solids. - std::shared_ptr aSketchFeature = std::dynamic_pointer_cast( - reference(SKETCH_OBJECT_ID())->value()); - if(!aSketchFeature || aSketchFeature->results().empty()) { - return; - } - ResultPtr aSketchRes = aSketchFeature->results().front(); - ResultConstructionPtr aConstruction = std::dynamic_pointer_cast(aSketchRes); - if(!aConstruction.get()) { - return; - } - - /// feature extrusion does not have the next attribute - if (data()->attribute(SKETCH_SELECTION_ID()).get()) { - if (!selection(SKETCH_SELECTION_ID())->isInitialized() || selection(SKETCH_SELECTION_ID())->context() != aSketchRes) { - selection(SKETCH_SELECTION_ID())->setValue(aSketchRes, std::shared_ptr()); + GeomAPI_Shape::ShapeType aBaseShapeType = theBaseShape->shapeType(); + GeomAPI_Shape::ShapeType aShapeTypeToExplode = GeomAPI_Shape::SHAPE; + + switch(aBaseShapeType) { + case GeomAPI_Shape::EDGE: { + aShapeTypeToExplode = GeomAPI_Shape::VERTEX; + break; } - } - int aSketchFacesNum = aConstruction->facesNum(); - if(aSketchFacesNum == 0) { - return; - } - ListOfShape aFacesList; - for(int aFaceIndex = 0; aFaceIndex < aSketchFacesNum; aFaceIndex++) { - std::shared_ptr aFace = std::dynamic_pointer_cast(aConstruction->face(aFaceIndex)); - aFacesList.push_back(aFace); - } - - // Searching faces with common edges. - ListOfShape aShells; - ListOfShape aFreeFaces; - std::shared_ptr aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aFacesList); - GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, aShells, aFreeFaces); - aShells.insert(aShells.end(), aFreeFaces.begin(), aFreeFaces.end()); - - // Generating result for each shell and face. - int aErrorsNum = 0; - int aResultIndex = 0; - for(ListOfShape::const_iterator anIter = aShells.cbegin(); anIter != aShells.cend(); anIter++) { - std::shared_ptr aMakeShape; - - std::shared_ptr aBaseFace = *anIter; - makeSolid(aBaseFace, aMakeShape); - if(!aMakeShape.get()) { - aErrorsNum++; - continue; + case GeomAPI_Shape::WIRE: { + aShapeTypeToExplode = GeomAPI_Shape::COMPOUND; + break; } - - ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); - loadNamingDS(aResultBody, aBaseFace, aMakeShape); - setResult(aResultBody, aResultIndex); - aResultIndex++; + case GeomAPI_Shape::FACE: + case GeomAPI_Shape::SHELL: { + aShapeTypeToExplode = GeomAPI_Shape::EDGE; + break; + } + case GeomAPI_Shape::COMPOUND: { + aShapeTypeToExplode = GeomAPI_Shape::COMPOUND; + } + default: // [to avoid compilation warnings] + break; } - if(aErrorsNum > 0) { - std::ostringstream aStringStream; - aStringStream << "Error: Could not create solid(s) from " << aErrorsNum << " face(s)."; - setError(aStringStream.str()); + if(aShapeTypeToExplode == GeomAPI_Shape::VERTEX || + aShapeTypeToExplode == GeomAPI_Shape::COMPOUND) { + theResultBody->loadGeneratedShapes(theMakeShape, theBaseShape, GeomAPI_Shape::VERTEX); } + if(aShapeTypeToExplode == GeomAPI_Shape::EDGE || + aShapeTypeToExplode == GeomAPI_Shape::COMPOUND) { + theResultBody->loadGeneratedShapes(theMakeShape, theBaseShape, GeomAPI_Shape::EDGE); + } + std::list > aSweeps; // all sweeps collected + std::shared_ptr aMakeSweep = + std::dynamic_pointer_cast(theMakeShape); + if(aMakeSweep.get()) { + aSweeps.push_back(aMakeSweep); + } else { + std::shared_ptr aMakeList = + std::dynamic_pointer_cast(theMakeShape); + if (aMakeList.get()) { + ListOfMakeShape::const_iterator anIter = aMakeList->list().cbegin(); + for(; anIter != aMakeList->list().cend(); anIter++) { + std::shared_ptr aSweep = + std::dynamic_pointer_cast(*anIter); + if (aSweep.get()) + aSweeps.push_back(aSweep); + } + } + } + std::list >::iterator aSweep = aSweeps.begin(); + for(; aSweep != aSweeps.end(); aSweep++) { + // Store from shapes. + storeShapes(theMakeShape, theResultBody, aBaseShapeType, (*aSweep)->fromShapes(), "From_"); - // Remove the rest results if there were produced in the previous pass. - removeResults(aResultIndex); + // Store to shapes. + storeShapes(theMakeShape, theResultBody, aBaseShapeType, (*aSweep)->toShapes(), "To_"); + } } //================================================================================================= -void FeaturesPlugin_CompositeSketch::loadNamingDS(std::shared_ptr theResultBody, - const std::shared_ptr& theBaseShape, - const std::shared_ptr& theMakeShape) +void FeaturesPlugin_CompositeSketch::storeShapes( + const std::shared_ptr theMakeShape, + ResultBodyPtr theResultBody, + const GeomAPI_Shape::ShapeType theBaseShapeType, + const ListOfShape& theShapes, + const std::string theName) { - //load result - theResultBody->storeGenerated(theBaseShape, theMakeShape->shape()); - - //Insert lateral face : Face from Edge - const std::string aLatName = "LateralFace"; - const int aLatTag = 1; - std::shared_ptr aDataMap = theMakeShape->mapOfSubShapes(); - theResultBody->loadAndOrientGeneratedShapes(theMakeShape.get(), theBaseShape, GeomAPI_Shape::EDGE, aLatTag, aLatName, *aDataMap.get()); - - std::shared_ptr aSweepAlgo = std::dynamic_pointer_cast(theMakeShape); - if(aSweepAlgo.get()) { - //Insert to faces - int aToFaceIndex = 1; - const std::string aToName = "ToFace"; - int aToTag = 2; - const ListOfShape& aToFaces = aSweepAlgo->toShapes(); - for(ListOfShape::const_iterator anIt = aToFaces.cbegin(); anIt != aToFaces.cend(); anIt++) { - std::shared_ptr aToFace = *anIt; - if(aDataMap->isBound(aToFace)) { - aToFace = aDataMap->find(aToFace); + GeomAPI_Shape::ShapeType aShapeTypeToExplore = GeomAPI_Shape::FACE; + std::string aShapeTypeStr = "Face"; + switch(theBaseShapeType) { + case GeomAPI_Shape::VERTEX: { + aShapeTypeToExplore = GeomAPI_Shape::VERTEX; + aShapeTypeStr = "Vertex"; + break; + } + case GeomAPI_Shape::EDGE: + case GeomAPI_Shape::WIRE: { + aShapeTypeToExplore = GeomAPI_Shape::EDGE; + aShapeTypeStr = "Edge"; + break; + } + case GeomAPI_Shape::FACE: + case GeomAPI_Shape::SHELL: { + aShapeTypeToExplore = GeomAPI_Shape::FACE; + aShapeTypeStr = "Face"; + break; + } + case GeomAPI_Shape::COMPOUND: { + aShapeTypeToExplore = GeomAPI_Shape::COMPOUND; + break; + } + default: // [to avoid compilation warnings] + break; + } + + // Store shapes. + for(ListOfShape::const_iterator anIt = theShapes.cbegin(); anIt != theShapes.cend(); ++anIt) { + GeomShapePtr aShape = *anIt; + + if(aShapeTypeToExplore == GeomAPI_Shape::COMPOUND) { + std::string aName = theName + (aShape->shapeType() == GeomAPI_Shape::EDGE ? "Edge" : "Face"); + storeSubShape(theMakeShape, theResultBody, aShape, aShape->shapeType(), aName); + } else { + std::string aName = theName + aShapeTypeStr; + storeSubShape(theMakeShape, theResultBody, aShape, aShapeTypeToExplore, aName); + if (theBaseShapeType == GeomAPI_Shape::WIRE) { // issue 2289: special names also for vertices + aName = theName + "Vertex"; + storeSubShape(theMakeShape, theResultBody, aShape, GeomAPI_Shape::VERTEX, aName); } - std::ostringstream aStr; - aStr << aToName << "_" << aToFaceIndex++; - theResultBody->generated(aToFace, aStr.str(), aToTag++); } + } +} - //Insert from faces - int aFromFaceIndex = 1; - const std::string aFromName = "FromFace"; - int aFromTag = aToTag > 10000 ? aToTag : 10000; - const ListOfShape& aFromFaces = aSweepAlgo->fromShapes(); - for(ListOfShape::const_iterator anIt = aFromFaces.cbegin(); anIt != aFromFaces.cend(); anIt++) { - std::shared_ptr aFromFace = *anIt; - if(aDataMap->isBound(aFromFace)) { - aFromFace = aDataMap->find(aFromFace); +void storeSubShape( + const std::shared_ptr theMakeShape, + ResultBodyPtr theResultBody, + const GeomShapePtr theShape, + const GeomAPI_Shape::ShapeType theType, + const std::string& theName) +{ + for(GeomAPI_ShapeExplorer anExp(theShape, theType); anExp.more(); anExp.next()) { + GeomShapePtr aSubShape = anExp.current(); + if (!theResultBody->generated(aSubShape, theName)) { + int aNbSubs = theResultBody->numberOfSubs(); + if (aNbSubs > 0) { + // check the modified shape is in the result body, don't store it if not + ListOfShape aNewShapes; + theMakeShape->modified(aSubShape, aNewShapes); + for (int i = 0; i < aNbSubs; ++i) { + ResultBodyPtr aSubRes = theResultBody->subResult(i); + GeomShapePtr aShape = aSubRes->shape(); + ListOfShape::iterator aNewIt = aNewShapes.begin(); + for (; aNewIt != aNewShapes.end(); ++aNewIt) + if (aShape->isSubShape(*aNewIt, false)) + break; + if (aNewIt != aNewShapes.end()) { + // store from/to shapes as primitives and then store modification of them by the boolean + aSubRes->generated(aSubShape, theName, false); + aSubRes->loadModifiedShapes(theMakeShape, aSubShape, theType); + } + } + } + else { + // store from/to shapes as primitives and then store modification of them by the boolean + theResultBody->generated(aSubShape, theName, false); + theResultBody->loadModifiedShapes(theMakeShape, aSubShape, theType); } - std::ostringstream aStr; - aStr << aFromName << "_" << aFromFaceIndex++; - theResultBody->generated(aFromFace, aStr.str(), aFromTag++); } } } + //================================================================================================= -void FeaturesPlugin_CompositeSketch::setSketchObjectToList() +void FeaturesPlugin_CompositeSketch::attributeChanged(const std::string& theID) { - std::shared_ptr aSketchFeature = std::dynamic_pointer_cast( - reference(SKETCH_OBJECT_ID())->value()); - - if(aSketchFeature.get() && !aSketchFeature->results().empty()) { - ResultPtr aSketchRes = aSketchFeature->results().front(); - ResultConstructionPtr aConstruction = std::dynamic_pointer_cast(aSketchRes); - if(aConstruction.get()) { - AttributeSelectionListPtr aFacesSelectionList = selectionList(LIST_ID()); - if (aFacesSelectionList.get() && aFacesSelectionList->size() == 0) - aFacesSelectionList->append(aSketchRes, std::shared_ptr()); + if (theID == BASE_OBJECTS_ID()) { + AttributeSelectionListPtr anObjects = selectionList(BASE_OBJECTS_ID()); + if (anObjects->size() == 0 || anObjects->selectionType() != myCurrentSelectionType) { + myCurrentSelectionType = anObjects->selectionType(); + removeResults(0); // clear the results } } } -