X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FFeaturesPlugin%2FFeaturesPlugin_CompositeSketch.cpp;h=4ddac51f8e867af90f5eae03150fd691db6eeede;hb=84ff9a5e90ebf75292b9ef97a05a4609e67c4022;hp=628773d414e90d5a7dc635f37054a85e5665bf68;hpb=5315361b0c34c6e603474413024db5485c850d80;p=modules%2Fshaper.git diff --git a/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp b/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp index 628773d41..4ddac51f8 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp @@ -1,15 +1,28 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: FeaturesPlugin_CompositeSketch.cpp -// Created: 11 September 2015 -// Author: Dmitry Bobylev +// Copyright (C) 2014-2017 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 @@ -18,27 +31,43 @@ #include #include #include +#include + +#include +#include +#include #include +static void storeSubShape(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()); + } } //================================================================================================= 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; } @@ -46,169 +75,316 @@ std::shared_ptr FeaturesPlugin_CompositeSketch::addFeature(std //================================================================================================= 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()); + if(theIndex == 0) { + return std::dynamic_pointer_cast(data()->reference(SKETCH_ID())->value()); + } + return std::shared_ptr(); } //================================================================================================= 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 + // Check is this feature of result FeaturePtr aFeature = std::dynamic_pointer_cast(theObject); - if (!aFeature) + if(!aFeature.get()) { return false; - - ObjectPtr aSub = data()->reference(SKETCH_OBJECT_ID())->value(); + } + + ObjectPtr aSub = data()->reference(SKETCH_ID())->value(); return aSub == theObject; } //================================================================================================= void FeaturesPlugin_CompositeSketch::removeFeature(std::shared_ptr theFeature) { + AttributeSelectionListPtr aBaseObjectsSelectionList = selectionList(BASE_OBJECTS_ID()); + if(aBaseObjectsSelectionList.get() && aBaseObjectsSelectionList->size() > 0) { + aBaseObjectsSelectionList->clear(); + } + + 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); + theBaseShapesList.clear(); + + ListOfShape aBaseFacesList; + std::map aSketchWiresMap; + AttributeSelectionListPtr aBaseObjectsSelectionList = selectionList(BASE_OBJECTS_ID()); + if(!aBaseObjectsSelectionList.get()) { + setError("Error: Could not get base objects selection list."); + return; + } + if(aBaseObjectsSelectionList->size() == 0) { + setError("Error: Base objects list is empty."); + return; + } + for(int anIndex = 0; anIndex < aBaseObjectsSelectionList->size(); anIndex++) { + AttributeSelectionPtr aBaseObjectSelection = aBaseObjectsSelectionList->value(anIndex); + if(!aBaseObjectSelection.get()) { + setError("Error: Selected base object is empty."); + return; + } + GeomShapePtr aBaseShape = aBaseObjectSelection->value(); + if(aBaseShape.get() && !aBaseShape->isNull()) { + GeomAPI_Shape::ShapeType aST = aBaseShape->shapeType(); + if(aST == GeomAPI_Shape::SOLID || aST == GeomAPI_Shape::COMPSOLID) { + setError("Error: Selected shapes has unsupported type."); + return; + } + ResultConstructionPtr aConstruction = + std::dynamic_pointer_cast(aBaseObjectSelection->context()); + if(aConstruction.get() && !aBaseShape->isEqual(aConstruction->shape()) && + aST == GeomAPI_Shape::WIRE) { + // It is a wire on the sketch, store it to make face later. + aSketchWiresMap[aConstruction].push_back(aBaseShape); + continue; + } else { + aST == GeomAPI_Shape::FACE ? aBaseFacesList.push_back(aBaseShape) : + theBaseShapesList.push_back(aBaseShape); + } + } else { + // This may be the whole sketch result selected, check and get faces. + ResultConstructionPtr aConstruction = + std::dynamic_pointer_cast(aBaseObjectSelection->context()); + if(!aConstruction.get()) { + setError("Error: Selected sketches does not have results."); + return; + } + int aFacesNum = aConstruction->facesNum(); + if(aFacesNum == 0) { + // Probably it can be construction. + aBaseShape = aConstruction->shape(); + if(aBaseShape.get() && !aBaseShape->isNull()) { + GeomAPI_Shape::ShapeType aST = aBaseShape->shapeType(); + if(aST != GeomAPI_Shape::VERTEX && aST != GeomAPI_Shape::EDGE && + aST != GeomAPI_Shape::WIRE && + aST != GeomAPI_Shape::FACE && aST != GeomAPI_Shape::SHELL) { + setError("Error: Selected shapes has unsupported type."); + return; + } + aST == GeomAPI_Shape::FACE ? aBaseFacesList.push_back(aBaseShape) : + theBaseShapesList.push_back(aBaseShape); + } + } else { + for(int aFaceIndex = 0; aFaceIndex < aFacesNum; aFaceIndex++) { + GeomShapePtr aBaseFace = aConstruction->face(aFaceIndex); + if(!aBaseFace.get() || aBaseFace->isNull()) { + setError("Error: One of the faces on selected sketch is null."); + return; + } + aBaseFacesList.push_back(aBaseFace); + } + } } } - ModelAPI_CompositeFeature::erase(); -} + // Make faces from sketch wires. + for(std::map::const_iterator anIt = aSketchWiresMap.cbegin(); + anIt != aSketchWiresMap.cend(); ++anIt) { + const std::shared_ptr aSketchPlanarEdges = + std::dynamic_pointer_cast((*anIt).first->shape()); + const ListOfShape& aWiresList = (*anIt).second; + ListOfShape aFaces; + GeomAlgoAPI_ShapeTools::makeFacesWithHoles(aSketchPlanarEdges->origin(), + aSketchPlanarEdges->norm(), + aWiresList, + aFaces); + aBaseFacesList.insert(aBaseFacesList.end(), aFaces.begin(), aFaces.end()); + } + + // Searching faces with common edges. + if(theIsMakeShells && aBaseFacesList.size() > 1) { + ListOfShape aShells; + ListOfShape aFreeFaces; + GeomShapePtr aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseFacesList); + GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, + aShells, aFreeFaces); + theBaseShapesList.insert(theBaseShapesList.end(), aFreeFaces.begin(), aFreeFaces.end()); + theBaseShapesList.insert(theBaseShapesList.end(), aShells.begin(), aShells.end()); + } else { + theBaseShapesList.insert(theBaseShapesList.end(), aBaseFacesList.begin(), + aBaseFacesList.end()); + } +} //================================================================================================= -void FeaturesPlugin_CompositeSketch::execute() +bool FeaturesPlugin_CompositeSketch::isMakeShapeValid( + 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; + // Check that algo is done. + if(!theMakeShape->isDone()) { + setError("Error: " + getKind() + " algorithm failed."); + return false; } - if (!selection(SKETCH_SELECTION_ID())->isInitialized() || selection(SKETCH_SELECTION_ID())->context() != aSketchRes) { - selection(SKETCH_SELECTION_ID())->setValue(aSketchRes, std::shared_ptr()); - } - int aSketchFacesNum = aConstruction->facesNum(); - if(aSketchFacesNum == 0) { - return; + // Check if shape is not null. + if(!theMakeShape->shape().get() || theMakeShape->shape()->isNull()) { + setError("Error: Resulting shape is null."); + return false; } - ListOfShape aFacesList; - for(int aFaceIndex = 0; aFaceIndex < aSketchFacesNum; aFaceIndex++) { - std::shared_ptr aFace = std::dynamic_pointer_cast(aConstruction->face(aFaceIndex)); - aFacesList.push_back(aFace); + + // Check that resulting shape is valid. + if(!theMakeShape->isValid()) { + setError("Error: Resulting shape is not valid."); + return false; } - // 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; - } + return true; +} + +//================================================================================================= +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); +} - ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); - loadNamingDS(aResultBody, aBaseFace, aMakeShape); - setResult(aResultBody, aResultIndex); - aResultIndex++; +//================================================================================================= +void FeaturesPlugin_CompositeSketch::storeGenerationHistory(ResultBodyPtr theResultBody, + const GeomShapePtr theBaseShape, + const std::shared_ptr theMakeShape) +{ + GeomAPI_Shape::ShapeType aBaseShapeType = theBaseShape->shapeType(); + GeomAPI_Shape::ShapeType aShapeTypeToExplode = GeomAPI_Shape::SHAPE; + + switch(aBaseShapeType) { + case GeomAPI_Shape::EDGE: { + aShapeTypeToExplode = GeomAPI_Shape::VERTEX; + break; + } + case GeomAPI_Shape::WIRE: { + aShapeTypeToExplode = GeomAPI_Shape::COMPOUND; + break; + } + case GeomAPI_Shape::FACE: + case GeomAPI_Shape::SHELL: { + aShapeTypeToExplode = GeomAPI_Shape::EDGE; + break; + } + case GeomAPI_Shape::COMPOUND: { + aShapeTypeToExplode = GeomAPI_Shape::COMPOUND; + } } - if(aErrorsNum > 0) { - std::ostringstream aStringStream; - aStringStream << "Error: Could not create solid(s) from " << aErrorsNum << " face(s)."; - setError(aStringStream.str()); + int aLateralIndex = 1; + int aBaseEdgeIndex = 1; + int aVertexIndex = 1; + int aBaseVertexIndex = 1; + + 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); } - // Remove the rest results if there were produced in the previous pass. - removeResults(aResultIndex); + std::shared_ptr aMakeSweep = + std::dynamic_pointer_cast(theMakeShape); + if(aMakeSweep.get()) { + // Store from shapes. + storeShapes(theResultBody, aBaseShapeType, aMakeSweep->fromShapes(), "From_"); + + // Store to shapes. + storeShapes(theResultBody, aBaseShapeType, aMakeSweep->toShapes(), "To_"); + } } //================================================================================================= -void FeaturesPlugin_CompositeSketch::loadNamingDS(std::shared_ptr theResultBody, - const std::shared_ptr& theBaseShape, - const std::shared_ptr& theMakeShape) +void FeaturesPlugin_CompositeSketch::storeShapes(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); - } - std::ostringstream aStr; - aStr << aToName << "_" << aToFaceIndex++; - theResultBody->generated(aToFace, aStr.str(), aToTag++); + 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; + } + } + + // Store shapes. + for(ListOfShape::const_iterator anIt = theShapes.cbegin(); anIt != theShapes.cend(); ++anIt) { + GeomShapePtr aShape = *anIt; - //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); + if(aShapeTypeToExplore == GeomAPI_Shape::COMPOUND) { + std::string aName = theName + (aShape->shapeType() == GeomAPI_Shape::EDGE ? "Edge" : "Face"); + storeSubShape(theResultBody, aShape, aShape->shapeType(), aName); + } else { + std::string aName = theName + aShapeTypeStr; + storeSubShape(theResultBody, aShape, aShapeTypeToExplore, aName); + if (theBaseShapeType == GeomAPI_Shape::WIRE) { // issue 2289: special names also for vertices + aName = theName + "Vertex"; + storeSubShape(theResultBody, aShape, GeomAPI_Shape::VERTEX, aName); } - std::ostringstream aStr; - aStr << aFromName << "_" << aFromFaceIndex++; - theResultBody->generated(aFromFace, aStr.str(), aFromTag++); } } } + +void storeSubShape(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(); + theResultBody->generated(aSubShape, theName); + } +}