From: mpv Date: Thu, 19 Mar 2015 08:04:29 +0000 (+0300) Subject: Make selection of results as arguments of extrusion working correctly X-Git-Tag: V_1.1.0~107^2 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=c0d601caf98a080b0276f8cb29def42adb6d2306;p=modules%2Fshaper.git Make selection of results as arguments of extrusion working correctly --- diff --git a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp index c84c00702..873753a8c 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp @@ -42,14 +42,9 @@ void FeaturesPlugin_Extrusion::execute() AttributeSelectionListPtr aFaceRefs = selectionList(FeaturesPlugin_Extrusion::LIST_ID()); // for each selected face generate a result - int anIndex = 0; + int anIndex = 0, aResultIndex = 0; for(; anIndex < aFaceRefs->size(); anIndex++) { std::shared_ptr aFaceRef = aFaceRefs->value(anIndex); - if (!aFaceRef.get()) - continue; - std::shared_ptr aFace = aFaceRef->value(); - if (!aFace.get()) - continue; ResultPtr aContextRes = aFaceRef->context(); std::shared_ptr aContext = aContextRes->shape(); if (!aContext.get()) { @@ -57,37 +52,58 @@ void FeaturesPlugin_Extrusion::execute() setError(aContextError); break; } - double aSize = real(FeaturesPlugin_Extrusion::SIZE_ID())->value(); if (boolean(FeaturesPlugin_Extrusion::REVERSE_ID())->value()) aSize = -aSize; - ResultBodyPtr aResultBody = document()->createBody(data(), anIndex); - GeomAlgoAPI_Extrusion aFeature(aFace, aSize); - if(!aFeature.isDone()) { - static const std::string aFeatureError = "Extrusion algorithm failed"; - setError(aFeatureError); - break; + std::shared_ptr aValueFace = aFaceRef->value(); + int aFacesNum = -1; // this mean that "aFace" is used + ResultConstructionPtr aConstruction = + std::dynamic_pointer_cast(aContextRes); + if (!aValueFace.get()) { // this may be the whole sketch result selected, check and get faces + if (aConstruction.get()) { + aFacesNum = aConstruction->facesNum(); + } else { + static const std::string aFaceError = "Can not find basis for extrusion"; + setError(aFaceError); + break; + } } - // Check if shape is valid - if (aFeature.shape()->isNull()) { - static const std::string aShapeError = "Resulting shape is Null"; - setError(aShapeError); - break; + for(int aFaceIndex = 0; aFaceIndex < aFacesNum || aFacesNum == -1; aFaceIndex++) { + ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); + std::shared_ptr aFace = + aFacesNum == -1 ? aValueFace : aConstruction->face(aFaceIndex); + GeomAlgoAPI_Extrusion aFeature(aFace, aSize); + if(!aFeature.isDone()) { + static const std::string aFeatureError = "Extrusion algorithm failed"; + setError(aFeatureError); + break; + } + + // Check if shape is valid + if (aFeature.shape()->isNull()) { + static const std::string aShapeError = "Resulting shape is Null"; + setError(aShapeError); + break; + } + if(!aFeature.isValid()) { + std::string aFeatureError = "Warning: resulting shape is not valid"; + setError(aFeatureError); + break; + } + //LoadNamingDS + LoadNamingDS(aFeature, aResultBody, aFace, aContext); + + setResult(aResultBody, aResultIndex); + aResultIndex++; + + if (aFacesNum == -1) + break; } - if(!aFeature.isValid()) { - std::string aFeatureError = "Warning: resulting shape is not valid"; - setError(aFeatureError); - break; - } - //LoadNamingDS - LoadNamingDS(aFeature, aResultBody, aFace, aContext); - - setResult(aResultBody, anIndex); } // remove the rest results if there were produced in the previous pass - removeResults(anIndex); + removeResults(aResultIndex); } //============================================================================ diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index b6fe2ea02..03ccb8984 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -61,6 +61,7 @@ using namespace std; static const int kSTART_VERTEX_DELTA = 1000000; // identifier that there is simple reference: selection equals to context Standard_GUID kSIMPLE_REF_ID("635eacb2-a1d6-4dec-8348-471fae17cb29"); +Standard_GUID kCONSTUCTION_SIMPLE_REF_ID("635eacb2-a1d6-4dec-8348-471fae17cb28"); // on this label is stored: // TNaming_NamedShape - selected shape @@ -73,19 +74,18 @@ void Model_AttributeSelection::setValue(const ResultPtr& theContext, const std::shared_ptr& theSubShape) { const std::shared_ptr& anOldShape = value(); - bool isOldShape = + bool isOldContext = theContext == myRef.value(); + bool isOldShape = isOldContext && (theSubShape == anOldShape || (theSubShape && anOldShape && theSubShape->isEqual(anOldShape))); if (isOldShape) return; // shape is the same, so context is also unchanged // update the referenced object if needed - bool isOldContext = theContext == myRef.value(); - - if (!isOldContext) myRef.setValue(theContext); // do noth use naming if selected shape is result shape itself, but not sub-shape TDF_Label aSelLab = selectionLabel(); aSelLab.ForgetAttribute(kSIMPLE_REF_ID); + aSelLab.ForgetAttribute(kCONSTUCTION_SIMPLE_REF_ID); if (theContext->groupName() == ModelAPI_ResultBody::group()) { // do not select the whole shape for body:it is already must be in the data framework if (theContext->shape().get() && theContext->shape()->isEqual(theSubShape)) { @@ -95,7 +95,13 @@ void Model_AttributeSelection::setValue(const ResultPtr& theContext, selectBody(theContext, theSubShape); } } else if (theContext->groupName() == ModelAPI_ResultConstruction::group()) { - selectConstruction(theContext, theSubShape); + if (!theSubShape.get()) { + // to sub, so the whole result is selected + aSelLab.ForgetAllAttributes(true); + TDataStd_UAttribute::Set(aSelLab, kCONSTUCTION_SIMPLE_REF_ID); + } else { + selectConstruction(theContext, theSubShape); + } } myIsInitialized = true; @@ -123,6 +129,9 @@ std::shared_ptr Model_AttributeSelection::value() return aResult; // empty result return aContext->shape(); } + if (aSelLab.IsAttribute(kCONSTUCTION_SIMPLE_REF_ID)) { // it is just reference to construction, nothing is in value + return aResult; // empty result + } Handle(TNaming_NamedShape) aSelection; if (selectionLabel().FindAttribute(TNaming_NamedShape::GetID(), aSelection)) { @@ -188,6 +197,9 @@ bool Model_AttributeSelection::update() if (aSelLab.IsAttribute(kSIMPLE_REF_ID)) { // it is just reference to shape, not sub-shape return aContext->shape() && !aContext->shape()->isNull(); } + if (aSelLab.IsAttribute(kCONSTUCTION_SIMPLE_REF_ID)) { // it is just reference to construction, not sub-shape + return aContext->shape() && !aContext->shape()->isNull(); + } if (aContext->groupName() == ModelAPI_ResultBody::group()) { // body: just a named shape, use selection mechanism from OCCT @@ -222,7 +234,7 @@ bool Model_AttributeSelection::update() return false; } - if (aShapeType == TopAbs_FACE) { + if (aShapeType == TopAbs_FACE) { // compound is for the whole sketch selection // If this is a wire with plane defined thin it is a sketch-like object std::list > aFaces; GeomAlgoAPI_SketchBuilder::createFaces(aWirePtr->origin(), aWirePtr->dirX(), @@ -611,8 +623,11 @@ std::string Model_AttributeSelection::namingName() std::shared_ptr aSubSh = value(); ResultPtr aCont = context(); aName = "Undefined name"; - if(!aSubSh.get() || aSubSh->isNull() || !aCont.get() || aCont->shape()->isNull()) + if(!aCont.get() || aCont->shape()->isNull()) return aName; + if (!aSubSh.get() || aSubSh->isNull()) { // no subshape, so just the whole feature name + return aCont->data()->name(); + } TopoDS_Shape aSubShape = aSubSh->impl(); TopoDS_Shape aContext = aCont->shape()->impl(); #ifdef DEB_NAMING diff --git a/src/Model/Model_ResultConstruction.cpp b/src/Model/Model_ResultConstruction.cpp index a0f3b9306..17b20df98 100644 --- a/src/Model/Model_ResultConstruction.cpp +++ b/src/Model/Model_ResultConstruction.cpp @@ -8,6 +8,8 @@ #include #include +#include +#include void Model_ResultConstruction::initAttributes() { @@ -26,7 +28,13 @@ void Model_ResultConstruction::colorConfigInfo(std::string& theSection, std::str void Model_ResultConstruction::setShape(std::shared_ptr theShape) { - myShape = theShape; + if (myShape != theShape) { + myShape = theShape; + if (theShape.get() && (!myShape.get() || !theShape->isEqual(myShape))) { + myFacesUpToDate = false; + myFaces.clear(); + } + } } std::shared_ptr Model_ResultConstruction::shape() @@ -37,6 +45,7 @@ std::shared_ptr Model_ResultConstruction::shape() Model_ResultConstruction::Model_ResultConstruction() { myIsInHistory = true; + myFacesUpToDate = false; setIsConcealed(false); } @@ -44,3 +53,27 @@ void Model_ResultConstruction::setIsInHistory(const bool isInHistory) { myIsInHistory = isInHistory; } + +int Model_ResultConstruction::facesNum() +{ + if (!myFacesUpToDate) { + std::shared_ptr aWirePtr = + std::dynamic_pointer_cast(myShape); + std::list > aFaces; + GeomAlgoAPI_SketchBuilder::createFaces(aWirePtr->origin(), aWirePtr->dirX(), + aWirePtr->dirY(), aWirePtr->norm(), aWirePtr, aFaces); + std::list >::iterator aFIter = aFaces.begin(); + for(; aFIter != aFaces.end(); aFIter++) { + std::shared_ptr aFace(new GeomAPI_Face(*aFIter)); + if (aFace.get()) + myFaces.push_back(aFace); + } + myFacesUpToDate = true; + } + return myFaces.size(); +} + +std::shared_ptr Model_ResultConstruction::face(const int theIndex) +{ + return myFaces[theIndex]; +} diff --git a/src/Model/Model_ResultConstruction.h b/src/Model/Model_ResultConstruction.h index 8292e09bc..84f048f6d 100644 --- a/src/Model/Model_ResultConstruction.h +++ b/src/Model/Model_ResultConstruction.h @@ -9,6 +9,7 @@ #include "Model.h" #include +#include /**\class Model_ResultConstruction * \ingroup DataModel @@ -21,6 +22,8 @@ class Model_ResultConstruction : public ModelAPI_ResultConstruction { std::shared_ptr myOwner; ///< owner of this result std::shared_ptr myShape; ///< shape of this result created "on the fly" + bool myFacesUpToDate; ///< is true if faces in myuFaces are computed and up to date + std::vector > myFaces; ///< stores the up to date faces if they exist bool myIsInHistory; public: /// default color for a result construction @@ -51,6 +54,11 @@ class Model_ResultConstruction : public ModelAPI_ResultConstruction /// Sets the flag that it must be displayed in history (default is true) MODEL_EXPORT virtual void setIsInHistory(const bool myIsInHistory); + /// if the construction result may be used as faces, this method returns not zero number of faces + MODEL_EXPORT virtual int facesNum(); + /// if the construction result may be used as faces, this method returns face by zero based index + MODEL_EXPORT virtual std::shared_ptr face(const int theIndex); + protected: /// Makes a body on the given feature Model_ResultConstruction(); diff --git a/src/ModelAPI/ModelAPI_Feature.cpp b/src/ModelAPI/ModelAPI_Feature.cpp index e158d48a0..b08640fda 100644 --- a/src/ModelAPI/ModelAPI_Feature.cpp +++ b/src/ModelAPI/ModelAPI_Feature.cpp @@ -97,7 +97,7 @@ void ModelAPI_Feature::removeResults(const int theSinceIndex) } std::list >::iterator aResIter = myResults.begin(); - for(int anIndex = 0; anIndex < theSinceIndex; anIndex++) + for(int anIndex = 0; anIndex < theSinceIndex && aResIter != myResults.end(); anIndex++) aResIter++; std::list >::iterator aNextIter = aResIter; for(; aNextIter != myResults.end(); aNextIter++) { diff --git a/src/ModelAPI/ModelAPI_ResultConstruction.h b/src/ModelAPI/ModelAPI_ResultConstruction.h index 85a8d81ba..6040b35a5 100644 --- a/src/ModelAPI/ModelAPI_ResultConstruction.h +++ b/src/ModelAPI/ModelAPI_ResultConstruction.h @@ -9,6 +9,7 @@ #include "ModelAPI_Result.h" #include +#include #include @@ -37,6 +38,11 @@ class ModelAPI_ResultConstruction : public ModelAPI_Result /// Sets the flag that it must be displayed in history (default is true) virtual void setIsInHistory(const bool isInHistory) = 0; + + /// if the construction result may be used as faces, this method returns not zero number of faces + virtual int facesNum() = 0; + /// if the construction result may be used as faces, this method returns face by zero based index + virtual std::shared_ptr face(const int theIndex) = 0; }; //! Pointer on feature object