X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FFeaturesPlugin%2FFeaturesPlugin_CompositeSketch.cpp;h=1759b26b88cc6e136e9556f04bf6f69fce0d2ed4;hb=5f2dd854a118fb9dffec8658d1d234e6587c539f;hp=3d8ce83ef4473825baaffd406a6ac879419bf2cd;hpb=fea939dc45bd225f272f4343a4c806adbc44fb4e;p=modules%2Fshaper.git diff --git a/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp b/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp index 3d8ce83ef..1759b26b8 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -18,27 +17,38 @@ #include #include #include +#include +#include +#include + +#include #include //================================================================================================= -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,192 +56,297 @@ 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) { - 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 aFacesSelectionList = selectionList(LIST_ID()); - if (aFacesSelectionList.get() && aFacesSelectionList->size() > 0) - aFacesSelectionList->clear(); -} - -//================================================================================================= -void FeaturesPlugin_CompositeSketch::erase() -{ - 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); - } + AttributeSelectionListPtr aBaseObjectsSelectionList = selectionList(BASE_OBJECTS_ID()); + if(aBaseObjectsSelectionList.get() && aBaseObjectsSelectionList->size() > 0) { + aBaseObjectsSelectionList->clear(); } - ModelAPI_CompositeFeature::erase(); -} + reference(SKETCH_ID())->setValue(ObjectPtr()); +} //================================================================================================= -void FeaturesPlugin_CompositeSketch::execute() +void FeaturesPlugin_CompositeSketch::getBaseShapes(ListOfShape& theBaseShapesList, + const bool theIsMakeShells) { - // Getting faces to create solids. - std::shared_ptr aSketchFeature = std::dynamic_pointer_cast( - reference(SKETCH_OBJECT_ID())->value()); - if(!aSketchFeature || aSketchFeature->results().empty()) { + 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; } - ResultPtr aSketchRes = aSketchFeature->results().front(); - ResultConstructionPtr aConstruction = std::dynamic_pointer_cast(aSketchRes); - if(!aConstruction.get()) { + if(aBaseObjectsSelectionList->size() == 0) { + setError("Error: Base objects list is empty."); 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()); + 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::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; + } + 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); + } + } } } - 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); + + // 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. - 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; - } + if(theIsMakeShells) { + 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()); + } +} + +//================================================================================================= +bool FeaturesPlugin_CompositeSketch::isMakeShapeValid(const std::shared_ptr theMakeShape) +{ + // Check that algo is done. + if(!theMakeShape->isDone()) { + setError("Error: " + getKind() + " algorithm failed."); + return false; + } - ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); - loadNamingDS(aResultBody, aBaseFace, aMakeShape); - setResult(aResultBody, aResultIndex); - aResultIndex++; + // Check if shape is not null. + if(!theMakeShape->shape().get() || theMakeShape->shape()->isNull()) { + setError("Error: Resulting shape is null."); + return false; } - if(aErrorsNum > 0) { - std::ostringstream aStringStream; - aStringStream << "Error: Could not create solid(s) from " << aErrorsNum << " face(s)."; - setError(aStringStream.str()); + // Check that resulting shape is valid. + if(!theMakeShape->isValid()) { + setError("Error: Resulting shape is not valid."); + return false; } - // Remove the rest results if there were produced in the previous pass. - removeResults(aResultIndex); + return true; } //================================================================================================= -void FeaturesPlugin_CompositeSketch::loadNamingDS(std::shared_ptr theResultBody, - const std::shared_ptr& theBaseShape, - const std::shared_ptr& theMakeShape) +void FeaturesPlugin_CompositeSketch::storeResult(const GeomShapePtr theBaseShape, + const std::shared_ptr theMakeShape, + const int theResultIndex) { - //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++); - } + // Create result body. + ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex); + + // Store generated shape. + aResultBody->storeGenerated(theBaseShape, theMakeShape->shape()); + + // Store generated edges/faces. + int aGenTag = 1; + storeGenerationHistory(aResultBody, theBaseShape, theMakeShape, aGenTag); + + setResult(aResultBody, theResultIndex); +} + +//================================================================================================= +void FeaturesPlugin_CompositeSketch::storeGenerationHistory(ResultBodyPtr theResultBody, + const GeomShapePtr theBaseShape, + const std::shared_ptr theMakeShape, + int& theTag) +{ + GeomAPI_Shape::ShapeType aBaseShapeType = theBaseShape->shapeType(); + GeomAPI_Shape::ShapeType aShapeTypeToExplode; + std::string aGenName = "Generated_"; - //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); + std::shared_ptr aMapOfSubShapes = theMakeShape->mapOfSubShapes(); + switch(aBaseShapeType) { + case GeomAPI_Shape::VERTEX: { + aShapeTypeToExplode = GeomAPI_Shape::VERTEX; + aGenName += "Edge"; + break; + } + case GeomAPI_Shape::EDGE: + case GeomAPI_Shape::WIRE: { + std::shared_ptr aV1, aV2; + GeomAlgoAPI_ShapeTools::findBounds(theBaseShape, aV1, aV2); + ListOfShape aV1History, aV2History; + theMakeShape->generated(aV1, aV1History); + theMakeShape->generated(aV2, aV2History); + if(!aV1History.empty()) { + theResultBody->generated(aV1, aV1History.front(), aGenName + "Edge_1", theTag++); } - std::ostringstream aStr; - aStr << aFromName << "_" << aFromFaceIndex++; - theResultBody->generated(aFromFace, aStr.str(), aFromTag++); + if(!aV2History.empty()) { + theResultBody->generated(aV2, aV2History.front(), aGenName + "Edge_2", theTag++); + } + } + case GeomAPI_Shape::FACE: + case GeomAPI_Shape::SHELL: { + aShapeTypeToExplode = GeomAPI_Shape::EDGE; + aGenName += "Face"; + break; } } + theResultBody->loadAndOrientGeneratedShapes(theMakeShape.get(), theBaseShape, aShapeTypeToExplode, + theTag++, aGenName, *aMapOfSubShapes.get()); + + std::shared_ptr aMakeSweep = std::dynamic_pointer_cast(theMakeShape); + if(aMakeSweep.get()) { + // Store from shapes. + storeShapes(theResultBody, aBaseShapeType, aMapOfSubShapes, aMakeSweep->fromShapes(), "From_", theTag); + + // Store to shapes. + storeShapes(theResultBody, aBaseShapeType, aMapOfSubShapes, aMakeSweep->toShapes(), "To_", theTag); + } } + //================================================================================================= -void FeaturesPlugin_CompositeSketch::setSketchObjectToList() +void FeaturesPlugin_CompositeSketch::storeShapes(ResultBodyPtr theResultBody, + const GeomAPI_Shape::ShapeType theBaseShapeType, + const std::shared_ptr theMapOfSubShapes, + const ListOfShape& theShapes, + const std::string theName, + int& theTag) { - 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()); + 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; } } -} + // Store shapes. + int aShapeIndex = 1; + std::string aName = theName + aShapeTypeStr; + for(ListOfShape::const_iterator anIt = theShapes.cbegin(); anIt != theShapes.cend(); ++anIt) { + GeomShapePtr aShape = *anIt; + for(GeomAPI_ShapeExplorer anExp(aShape, aShapeTypeToExplore); anExp.more(); anExp.next()) { + GeomShapePtr aSubShape = anExp.current(); + if(theMapOfSubShapes->isBound(aSubShape)) { + aSubShape = theMapOfSubShapes->find(aSubShape); + } + std::ostringstream aStr; + aStr << aName << "_" << aShapeIndex++; + theResultBody->generated(aSubShape, aStr.str(), theTag++); + } + } +} \ No newline at end of file