X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FFeaturesPlugin%2FFeaturesPlugin_Extrusion.cpp;h=3f7ed7efdc9ed42fd3ad344ac2c9090ec4db461e;hb=2413ba5e387ebc030eb89aaad917991844ae518d;hp=295fb1c9de489e55cd14f0df7190b7c341e05625;hpb=d77708ba98445935aae7a0d93b5506e1f16018de;p=modules%2Fshaper.git diff --git a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp index 295fb1c9d..3f7ed7efd 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp @@ -1,58 +1,204 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> + // File: FeaturesPlugin_Extrusion.cpp // Created: 30 May 2014 // Author: Vitaly SMETANNIKOV -#include "FeaturesPlugin_Extrusion.h" +#include + +#include #include +#include #include #include #include +#include #include #include -#include +#include +#include #include +#include +#include -#include - -using namespace std; +#include +#include +#include +//================================================================================================= FeaturesPlugin_Extrusion::FeaturesPlugin_Extrusion() { } +//================================================================================================= void FeaturesPlugin_Extrusion::initAttributes() { - data()->addAttribute(FeaturesPlugin_Extrusion::FACE_ID(), ModelAPI_AttributeReference::type()); - data()->addAttribute(FeaturesPlugin_Extrusion::SIZE_ID(), ModelAPI_AttributeDouble::type()); - data()->addAttribute(FeaturesPlugin_Extrusion::REVERSE_ID(), ModelAPI_AttributeBoolean::type()); + AttributeSelectionListPtr aSelection = + std::dynamic_pointer_cast(data()->addAttribute( + LIST_ID(), ModelAPI_AttributeSelectionList::typeId())); + // extrusion works with faces always + aSelection->setSelectionType("FACE"); + + data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId()); + + data()->addAttribute(TO_SIZE_ID(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(FROM_SIZE_ID(), ModelAPI_AttributeDouble::typeId()); + + data()->addAttribute(TO_OBJECT_ID(), ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(TO_OFFSET_ID(), ModelAPI_AttributeDouble::typeId()); + + data()->addAttribute(FROM_OBJECT_ID(), ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(FROM_OFFSET_ID(), ModelAPI_AttributeDouble::typeId()); + + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TO_OBJECT_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), FROM_OBJECT_ID()); } +//================================================================================================= void FeaturesPlugin_Extrusion::execute() { - boost::shared_ptr aFaceRef = boost::dynamic_pointer_cast< - ModelAPI_AttributeReference>(data()->attribute(FeaturesPlugin_Extrusion::FACE_ID())); - if (!aFaceRef) - return; - boost::shared_ptr aFace; - boost::shared_ptr aConstr = boost::dynamic_pointer_cast< - ModelAPI_ResultConstruction>(aFaceRef->value()); - if (aConstr) { - aFace = aConstr->shape(); + // Getting faces. + ListOfShape aFacesList; + AttributeSelectionListPtr aFacesSelectionList = selectionList(LIST_ID()); + for(int anIndex = 0; anIndex < aFacesSelectionList->size(); anIndex++) { + AttributeSelectionPtr aFaceSel = aFacesSelectionList->value(anIndex); + std::shared_ptr aFaceShape = aFaceSel->value(); + if(aFaceShape.get() && !aFaceShape->isNull()) { // Getting face. + aFacesList.push_back(aFaceShape); + } else { // This may be the whole sketch result selected, check and get faces. + ResultPtr aContext = aFaceSel->context(); + std::shared_ptr aContextShape = aContext->shape(); + if(!aContextShape.get()) { + static const std::string aContextError = "The selection context is bad"; + setError(aContextError); + return; + } + ResultConstructionPtr aConstruction = std::dynamic_pointer_cast(aContext); + if(!aConstruction.get()) { + static const std::string aFaceError = "Can not find basis for extrusion"; + setError(aFaceError); + return; + } + int aFacesNum = aConstruction->facesNum(); + for(int aFaceIndex = 0; aFaceIndex < aFacesNum || aFacesNum == -1; aFaceIndex++) { + aFaceShape = std::dynamic_pointer_cast(aConstruction->face(aFaceIndex)); + aFacesList.push_back(aFaceShape); + } + } + } + + // Getting sizes. + double aToSize = 0.0; + double aFromSize = 0.0; + + if(string(CREATION_METHOD())->value() == "BySizes") { + aToSize = real(TO_SIZE_ID())->value(); + aFromSize = real(FROM_SIZE_ID())->value(); + } else { + aToSize = real(TO_OFFSET_ID())->value(); + aFromSize = real(FROM_OFFSET_ID())->value(); + } + + // Getting bounding planes. + std::shared_ptr aToShape; + std::shared_ptr aFromShape; + + if(string(CREATION_METHOD())->value() == "ByPlanesAndOffsets") { + std::shared_ptr anObjRef = selection(TO_OBJECT_ID()); + if(anObjRef.get() != NULL) { + aToShape = std::dynamic_pointer_cast(anObjRef->value()); + if(aToShape.get() == NULL && anObjRef->context().get() != NULL) { + aToShape = anObjRef->context()->shape(); + } + } + anObjRef = selection(FROM_OBJECT_ID()); + if(anObjRef.get() != NULL) { + aFromShape = std::dynamic_pointer_cast(anObjRef->value()); + if(aFromShape.get() == NULL && anObjRef->context().get() != NULL) { + aFromShape = anObjRef->context()->shape(); + } + } } - if (!aFace) { - // Check for body - boost::shared_ptr aBody = boost::dynamic_pointer_cast< - ModelAPI_ResultBody>(aFaceRef->value()); - if (aBody) - aFace = aBody->shape(); + + // 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 aResultIndex = 0; + for(ListOfShape::const_iterator anIter = aShells.cbegin(); anIter != aShells.cend(); anIter++) { + std::shared_ptr aBaseShape = *anIter; + + GeomAlgoAPI_Prism aPrismAlgo(aBaseShape, aToShape, aToSize, aFromShape, aFromSize); + if(!aPrismAlgo.isDone()) { + static const std::string aPrismAlgoError = "Extrusion algorithm failed"; + setError(aPrismAlgoError); + aResultIndex = 0; + break; + } + + // Check if shape is valid + if(!aPrismAlgo.shape().get() || aPrismAlgo.shape()->isNull()) { + static const std::string aShapeError = "Resulting shape is Null"; + setError(aShapeError); + aResultIndex = 0; + break; + } + if(!aPrismAlgo.isValid()) { + std::string aPrismAlgoError = "Warning: resulting shape is not valid"; + setError(aPrismAlgoError); + aResultIndex = 0; + break; + } + + ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); + loadNamingDS(aPrismAlgo, aResultBody, aBaseShape); + setResult(aResultBody, aResultIndex); + aResultIndex++; + } + + removeResults(aResultIndex); +} + +//================================================================================================= +void FeaturesPlugin_Extrusion::loadNamingDS(GeomAlgoAPI_Prism& thePrismAlgo, + std::shared_ptr theResultBody, + std::shared_ptr theBasis) +{ + //load result + theResultBody->storeGenerated(theBasis, thePrismAlgo.shape()); + + std::shared_ptr aSubShapes = thePrismAlgo.mapOfShapes(); + + //Insert lateral face : Face from Edge + const std::string aLatName = "LateralFace"; + const int aLatTag = 1; + theResultBody->loadAndOrientGeneratedShapes(thePrismAlgo.makeShape().get(), theBasis, GeomAPI_Shape::EDGE, aLatTag, aLatName, *aSubShapes); + + //Insert to faces + const std::string aToName = "ToFace"; + int aToTag = 2; + const ListOfShape& aToFaces = thePrismAlgo.toFaces(); + for(ListOfShape::const_iterator anIt = aToFaces.cbegin(); anIt != aToFaces.cend(); anIt++) { + std::shared_ptr aToFace = *anIt; + if(aSubShapes->isBound(aToFace)) { + aToFace = aSubShapes->find(aToFace); + } + theResultBody->generated(aToFace, aToName, aToTag++); + } + + //Insert from faces + const std::string aFromName = "FromFace"; + int aFromTag = aToTag > 10000 ? aToTag : 10000; + const ListOfShape& aFromFaces = thePrismAlgo.fromFaces(); + for(ListOfShape::const_iterator anIt = aFromFaces.cbegin(); anIt != aFromFaces.cend(); anIt++) { + std::shared_ptr aFromFace = *anIt; + if(aSubShapes->isBound(aFromFace)) { + aFromFace = aSubShapes->find(aFromFace); + } + theResultBody->generated(aFromFace, aFromName, aFromTag++); } - if (!aFace) - return; - - double aSize = data()->real(FeaturesPlugin_Extrusion::SIZE_ID())->value(); - if (data()->boolean(FeaturesPlugin_Extrusion::REVERSE_ID())->value()) - aSize = -aSize; - boost::shared_ptr aResult = document()->createBody(data()); - aResult->store(GeomAlgoAPI_Extrusion::makeExtrusion(aFace, aSize)); - setResult(aResult); }