From c39f725bfe98395871c5853dacb89ab1a6ecc6f2 Mon Sep 17 00:00:00 2001 From: mpv Date: Wed, 8 Jul 2015 16:05:43 +0300 Subject: [PATCH] Make the movement, placement and rotation 3D features may be applied to the Part results in PartSet: issue #500 --- .../FeaturesPlugin_Movement.cpp | 33 ++++++-- .../FeaturesPlugin_Placement.cpp | 43 +++++----- .../FeaturesPlugin_Rotation.cpp | 33 ++++++-- src/FeaturesPlugin/plugin-Features.xml | 24 +++--- src/GeomAPI/GeomAPI.i | 4 +- src/GeomAlgoAPI/GeomAlgoAPI_Movement.cpp | 51 +++++++----- src/GeomAlgoAPI/GeomAlgoAPI_Movement.h | 7 +- src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp | 60 ++++++++------ src/GeomAlgoAPI/GeomAlgoAPI_Placement.h | 7 +- src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp | 51 +++++++----- src/GeomAlgoAPI/GeomAlgoAPI_Rotation.h | 7 +- src/Model/Model_AttributeSelection.cpp | 55 ++++++++++--- src/Model/Model_AttributeSelection.h | 9 ++- src/Model/Model_Data.cpp | 5 ++ src/Model/Model_Data.h | 4 + src/Model/Model_Document.cpp | 53 ++++++++++++ src/Model/Model_Document.h | 12 +++ src/Model/Model_Objects.cpp | 16 ++++ src/Model/Model_Objects.h | 4 + src/Model/Model_ResultPart.cpp | 80 ++++++++++++++++++- src/Model/Model_ResultPart.h | 11 ++- src/Model/Model_Update.cpp | 38 ++++++--- src/ModelAPI/ModelAPI.i | 2 +- src/ModelAPI/ModelAPI_Data.h | 4 + src/ModelAPI/ModelAPI_Document.h | 5 ++ src/ModelAPI/ModelAPI_Object.cpp | 3 +- src/ModelAPI/ModelAPI_Object.h | 1 + src/ModelAPI/ModelAPI_Result.cpp | 5 ++ src/ModelAPI/ModelAPI_Result.h | 5 +- src/ModelAPI/ModelAPI_ResultPart.cpp | 6 ++ src/ModelAPI/ModelAPI_ResultPart.h | 13 ++- 31 files changed, 506 insertions(+), 145 deletions(-) diff --git a/src/FeaturesPlugin/FeaturesPlugin_Movement.cpp b/src/FeaturesPlugin/FeaturesPlugin_Movement.cpp index 12bced349..3b6779bc7 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Movement.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Movement.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,7 @@ void FeaturesPlugin_Movement::execute() { // Getting objects. ListOfShape anObjects; + std::list aContextes; AttributeSelectionListPtr anObjectsSelList = selectionList(FeaturesPlugin_Movement::OBJECTS_LIST_ID()); if (anObjectsSelList->size() == 0) { return; @@ -48,6 +50,7 @@ void FeaturesPlugin_Movement::execute() return; } anObjects.push_back(anObject); + aContextes.push_back(anObjectAttr->context()); } //Getting axis. @@ -66,9 +69,12 @@ void FeaturesPlugin_Movement::execute() // Moving each object. int aResultIndex = 0; - for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) { + std::list::iterator aContext = aContextes.begin(); + for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); + anObjectsIt++, aContext++) { std::shared_ptr aBaseShape = *anObjectsIt; - GeomAlgoAPI_Movement aMovementAlgo(aBaseShape, anAxis, aDistance); + bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group(); + GeomAlgoAPI_Movement aMovementAlgo(aBaseShape, anAxis, aDistance, isPart); // Checking that the algorithm worked properly. if(!aMovementAlgo.isDone()) { @@ -88,9 +94,26 @@ void FeaturesPlugin_Movement::execute() } // Setting result. - ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); - LoadNamingDS(aMovementAlgo, aResultBody, aBaseShape); - setResult(aResultBody, aResultIndex); + if (isPart) { + ResultPartPtr anOrigin = std::dynamic_pointer_cast(*aContext); + + ResultPartPtr aCurrentResult; + const std::list >& aResults = results(); + std::list >::const_iterator aResIter = aResults.begin(); + for(int a = 0; aResIter != aResults.end(); aResIter++, a++) { + if (a == aResultIndex) { + aCurrentResult = std::dynamic_pointer_cast(*aResIter); + break; + } + } + ResultPartPtr aResultPart = document()->copyPart(aCurrentResult, anOrigin, aResultIndex); + aResultPart->setShape(*aContext, aMovementAlgo.shape()); + setResult(aResultPart); + } else { + ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); + LoadNamingDS(aMovementAlgo, aResultBody, aBaseShape); + setResult(aResultBody, aResultIndex); + } aResultIndex++; } diff --git a/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp b/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp index d069858d4..63f25c921 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -55,14 +56,11 @@ void FeaturesPlugin_Placement::execute() std::shared_ptr aBaseObject; ResultPtr aContextRes = anObjRef->context(); - if (aContextRes) { - if (aContextRes->groupName() == ModelAPI_ResultBody::group()) - aBaseObject = std::dynamic_pointer_cast(aContextRes)->shape(); - else if (aContextRes->groupName() == ModelAPI_ResultConstruction::group()) - aBaseObject = std::dynamic_pointer_cast(aContextRes)->shape(); + if (aContextRes.get()) { + aBaseObject = aContextRes->shape(); } - if (!aBaseObject) { - static const std::string aContextError = "The selection context is bad"; + if (!aBaseObject.get()) { + static const std::string aContextError = "The base selection context is bad"; setError(aContextError); return; } @@ -78,14 +76,11 @@ void FeaturesPlugin_Placement::execute() std::shared_ptr aSlaveObject; aContextRes = anObjRef->context(); - if (aContextRes) { - if (aContextRes->groupName() == ModelAPI_ResultBody::group()) - aSlaveObject = std::dynamic_pointer_cast(aContextRes)->shape(); - else if (aContextRes->groupName() == ModelAPI_ResultConstruction::group()) - aSlaveObject = std::dynamic_pointer_cast(aContextRes)->shape(); + if (aContextRes.get()) { + aSlaveObject = aContextRes->shape(); } - if (!aSlaveObject) { - static const std::string aContextError = "The selection context is bad"; + if (!aSlaveObject.get()) { + static const std::string aContextError = "The tool selection context is bad"; setError(aContextError); return; } @@ -119,7 +114,11 @@ void FeaturesPlugin_Placement::execute() data()->attribute(FeaturesPlugin_Placement::CENTERING_ID())); bool isCentering = aBoolAttr->value(); - std::shared_ptr aResultBody = document()->createBody(data()); + bool isPart = aContextRes->groupName() == ModelAPI_ResultPart::group(); + + std::shared_ptr aResultBody; + if (isPart) + aResultBody = document()->createBody(data()); GeomAlgoAPI_Placement aFeature(aSlaveObject, aBaseObject, aSlaveShape, aBaseShape, isReverse, isCentering); if(!aFeature.isDone()) { static const std::string aFeatureError = "Placement algorithm failed"; @@ -138,10 +137,18 @@ void FeaturesPlugin_Placement::execute() setError(aFeatureError); return; } - //LoadNamingDS - LoadNamingDS(aFeature, aResultBody, aSlaveObject); - setResult(aResultBody); + if (isPart) { // for part results just set transformation + ResultPartPtr anOrigin = std::dynamic_pointer_cast(aContextRes); + ResultPartPtr aResultPart = document()->copyPart(firstResult(), anOrigin); + aResultPart->setShape(aContextRes, aFeature.shape()); + setResult(aResultPart); + } else { + //LoadNamingDS + LoadNamingDS(aFeature, aResultBody, aSlaveObject); + + setResult(aResultBody); + } } //============================================================================ diff --git a/src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp b/src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp index 25faa8dd6..bbaf84a0e 100755 --- a/src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,7 @@ void FeaturesPlugin_Rotation::execute() { // Getting objects. ListOfShape anObjects; + std::list aContextes; AttributeSelectionListPtr anObjectsSelList = selectionList(FeaturesPlugin_Rotation::OBJECTS_LIST_ID()); if (anObjectsSelList->size() == 0) { return; @@ -48,6 +50,7 @@ void FeaturesPlugin_Rotation::execute() return; } anObjects.push_back(anObject); + aContextes.push_back(anObjectAttr->context()); } //Getting axis. @@ -66,9 +69,12 @@ void FeaturesPlugin_Rotation::execute() // Rotating each object. int aResultIndex = 0; - for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) { + std::list::iterator aContext = aContextes.begin(); + for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); + anObjectsIt++, aContext++) { std::shared_ptr aBaseShape = *anObjectsIt; - GeomAlgoAPI_Rotation aRotationAlgo(aBaseShape, anAxis, anAngle); + bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group(); + GeomAlgoAPI_Rotation aRotationAlgo(aBaseShape, anAxis, anAngle, isPart); // Checking that the algorithm worked properly. if(!aRotationAlgo.isDone()) { @@ -88,9 +94,26 @@ void FeaturesPlugin_Rotation::execute() } // Setting result. - ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); - LoadNamingDS(aRotationAlgo, aResultBody, aBaseShape); - setResult(aResultBody, aResultIndex); + if (isPart) { + ResultPartPtr anOrigin = std::dynamic_pointer_cast(*aContext); + + ResultPartPtr aCurrentResult; + const std::list >& aResults = results(); + std::list >::const_iterator aResIter = aResults.begin(); + for(int a = 0; aResIter != aResults.end(); aResIter++, a++) { + if (a == aResultIndex) { + aCurrentResult = std::dynamic_pointer_cast(*aResIter); + break; + } + } + ResultPartPtr aResultPart = document()->copyPart(aCurrentResult, anOrigin, aResultIndex); + aResultPart->setShape(*aContext, aRotationAlgo.shape()); + setResult(aResultPart); + } else { + ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); + LoadNamingDS(aRotationAlgo, aResultBody, aBaseShape); + setResult(aResultBody, aResultIndex); + } aResultIndex++; } diff --git a/src/FeaturesPlugin/plugin-Features.xml b/src/FeaturesPlugin/plugin-Features.xml index 62a41318d..d9437f131 100644 --- a/src/FeaturesPlugin/plugin-Features.xml +++ b/src/FeaturesPlugin/plugin-Features.xml @@ -1,6 +1,19 @@ + + + + + + + + + + + + + @@ -29,17 +42,6 @@ - - - - - - - - - - - theSourceShape, std::shared_ptr theAxis, - double theDistance) + double theDistance, + bool theSimpleTransform) : myDone(false), myShape(new GeomAPI_Shape()), myMap(new GeomAPI_DataMapOfShapeShape()), myMkShape(new GeomAlgoAPI_MakeShape()) { - build(theSourceShape, theAxis, theDistance); + build(theSourceShape, theAxis, theDistance, theSimpleTransform); } //================================================================================================= void GeomAlgoAPI_Movement::build(std::shared_ptr theSourceShape, std::shared_ptr theAxis, - double theDistance) + double theDistance, + bool theSimpleTransform) { if(!theSourceShape || !theAxis) { return; @@ -45,28 +47,35 @@ void GeomAlgoAPI_Movement::build(std::shared_ptr theSourceShape, gp_Trsf aTrsf; aTrsf.SetTranslation(gp_Vec(anAxis.Direction()) * theDistance); + TopoDS_Shape aResult; // Transform the shape with copying it. - BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true); - if(!aBuilder) { - return; - } - - myDone = aBuilder->IsDone() == Standard_True; - - if(!myDone) { - return; - } - - TopoDS_Shape aResult = aBuilder->Shape(); - // Fill data map to keep correct orientation of sub-shapes. - for(TopExp_Explorer anExp(aResult, TopAbs_FACE); anExp.More(); anExp.Next()) { - std::shared_ptr aCurrentShape(new GeomAPI_Shape()); - aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current())); - myMap->bind(aCurrentShape, aCurrentShape); + if (theSimpleTransform) { + TopLoc_Location aDelta(aTrsf); + aResult = aSourceShape.Moved(aDelta); + myDone = true; // is OK for sure + } else { + BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true); + if(!aBuilder) { + return; + } + + myDone = aBuilder->IsDone() == Standard_True; + + if(!myDone) { + return; + } + + aResult = aBuilder->Shape(); + // Fill data map to keep correct orientation of sub-shapes. + for(TopExp_Explorer anExp(aResult, TopAbs_FACE); anExp.More(); anExp.Next()) { + std::shared_ptr aCurrentShape(new GeomAPI_Shape()); + aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current())); + myMap->bind(aCurrentShape, aCurrentShape); + } + myMkShape->setImpl(aBuilder); } myShape->setImpl(new TopoDS_Shape(aResult)); - myMkShape->setImpl(aBuilder); } //================================================================================================= diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Movement.h b/src/GeomAlgoAPI/GeomAlgoAPI_Movement.h index 2068ec844..53eb4f4d1 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Movement.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Movement.h @@ -24,10 +24,12 @@ public: * \param[in] theSourceShape a shape to be moved. * \param[in] theAxis movement axis. * \param[in] theDistance movement distance. + * \param[in] theSimpleTransform makes just transformation of shape without changing of topology or geometry */ GEOMALGOAPI_EXPORT GeomAlgoAPI_Movement(std::shared_ptr theSourceShape, std::shared_ptr theAxis, - double theDistance); + double theDistance, + bool theSimpleTransform = false); /// \return true if algorithm succeed. GEOMALGOAPI_EXPORT const bool isDone() const @@ -52,7 +54,8 @@ private: /// Builds resulting shape. void build(std::shared_ptr theSourceShape, std::shared_ptr theAxis, - double theDistance); + double theDistance, + bool theSimpleTransform); private: /// Fields. diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp index 651e03601..35ea7c186 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp @@ -31,11 +31,13 @@ GeomAlgoAPI_Placement::GeomAlgoAPI_Placement( std::shared_ptr theSourceShape, std::shared_ptr theDestShape, bool theIsReverse, - bool theIsCentering) + bool theIsCentering, + bool theSimpleTransform) : myDone(false), myShape(new GeomAPI_Shape()) { - build(theSourceSolid, theDestSolid, theSourceShape, theDestShape, theIsReverse, theIsCentering); + build(theSourceSolid, theDestSolid, theSourceShape, theDestShape, + theIsReverse, theIsCentering, theSimpleTransform); } void GeomAlgoAPI_Placement::build( @@ -44,7 +46,8 @@ void GeomAlgoAPI_Placement::build( const std::shared_ptr& theSourceShape, const std::shared_ptr& theDestShape, bool theIsReverse, - bool theIsCentering) + bool theIsCentering, + bool theSimpleTransform) { // Filling the parameters of the objects static const int aNbObjects = 2; @@ -188,27 +191,33 @@ void GeomAlgoAPI_Placement::build( gp_Vec aTrans = aDstLoc - aSrcLoc; aTrsf.SetTransformation(aRot, aTrans); - // Transform the shape with copying it - BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true); - if(aBuilder) { - setImpl(aBuilder); - myDone = aBuilder->IsDone() == Standard_True; - if (myDone) { - TopoDS_Shape aResult = aBuilder->Shape(); - // fill data map to keep correct orientation of sub-shapes - for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) { - std::shared_ptr aCurrentShape(new GeomAPI_Shape()); - aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current())); - myMap.bind(aCurrentShape, aCurrentShape); - } -#ifdef DEB_PLACEMENT - int aNum = myMap.size(); - cout << "MAP of Oriented shapes =" << aNum <setImpl(new TopoDS_Shape(aResult)); + } else { // internal rebuild of the shape + // Transform the shape with copying it + BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true); + if(aBuilder) { + setImpl(aBuilder); + myDone = aBuilder->IsDone() == Standard_True; + if (myDone) { + TopoDS_Shape aResult = aBuilder->Shape(); + // fill data map to keep correct orientation of sub-shapes + for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) { + std::shared_ptr aCurrentShape(new GeomAPI_Shape()); + aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current())); + myMap.bind(aCurrentShape, aCurrentShape); + } + #ifdef DEB_PLACEMENT + int aNum = myMap.size(); + cout << "MAP of Oriented shapes =" << aNum <setImpl(new TopoDS_Shape(aResult)); - myMkShape = new GeomAlgoAPI_MakeShape (aBuilder); + myShape->setImpl(new TopoDS_Shape(aResult)); + myMkShape = new GeomAlgoAPI_MakeShape (aBuilder); + } } } } @@ -216,8 +225,11 @@ void GeomAlgoAPI_Placement::build( //============================================================================ const bool GeomAlgoAPI_Placement::isValid() const { - BRepCheck_Analyzer aChecker(myShape->impl()); - return (aChecker.IsValid() == Standard_True); + if (myShape.get()) { // only for not-simple transform + BRepCheck_Analyzer aChecker(myShape->impl()); + return (aChecker.IsValid() == Standard_True); + } + return true; } //============================================================================ diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Placement.h b/src/GeomAlgoAPI/GeomAlgoAPI_Placement.h index 1e1e88e49..9d8852b2f 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Placement.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Placement.h @@ -30,13 +30,15 @@ public: * \param[in] theDestShape destination object * \param[in] theIsReverse indicates that the solid materials should be on the same side against the destination plane * \param[in] theIsCentering indicates the planes should be centered + * \param[in] theSimpleTransform makes just transformation of shape without changing of topology or geometry */ GEOMALGOAPI_EXPORT GeomAlgoAPI_Placement(std::shared_ptr theSourceSolid, std::shared_ptr theDestSolid, std::shared_ptr theSourceShape, std::shared_ptr theDestShape, bool theIsReverse = false, - bool theIsCentering = false); + bool theIsCentering = false, + bool theSimpleTransform = false); /// Returns True if algorithm succeed GEOMALGOAPI_EXPORT const bool isDone() const @@ -67,7 +69,8 @@ private: const std::shared_ptr& theSourceShape, const std::shared_ptr& theDestShape, bool theIsReverse, - bool theIsCentering); + bool theIsCentering, + bool theSimpleTransform); /// fields bool myDone; diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp index 81c3ca6e3..218153110 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp @@ -16,19 +16,21 @@ //================================================================================================= GeomAlgoAPI_Rotation::GeomAlgoAPI_Rotation(std::shared_ptr theSourceShape, std::shared_ptr theAxis, - double theAngle) + double theAngle, + bool theSimpleTransform) : myDone(false), myShape(new GeomAPI_Shape()), myMap(new GeomAPI_DataMapOfShapeShape()), myMkShape(new GeomAlgoAPI_MakeShape()) { - build(theSourceShape, theAxis, theAngle); + build(theSourceShape, theAxis, theAngle, theSimpleTransform); } //================================================================================================= void GeomAlgoAPI_Rotation::build(std::shared_ptr theSourceShape, std::shared_ptr theAxis, - double theAngle) + double theAngle, + bool theSimpleTransform) { if(!theSourceShape || !theAxis) { return; @@ -44,28 +46,35 @@ void GeomAlgoAPI_Rotation::build(std::shared_ptr theSourceShape, gp_Trsf aTrsf; aTrsf.SetRotation(anAxis, theAngle / 180.0 * M_PI); + TopoDS_Shape aResult; // Transform the shape with copying it. - BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true); - if(!aBuilder) { - return; - } - - myDone = aBuilder->IsDone() == Standard_True; - - if(!myDone) { - return; - } - - TopoDS_Shape aResult = aBuilder->Shape(); - // Fill data map to keep correct orientation of sub-shapes. - for(TopExp_Explorer anExp(aResult, TopAbs_FACE); anExp.More(); anExp.Next()) { - std::shared_ptr aCurrentShape(new GeomAPI_Shape()); - aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current())); - myMap->bind(aCurrentShape, aCurrentShape); + if (theSimpleTransform) { + TopLoc_Location aDelta(aTrsf); + aResult = aSourceShape.Moved(aDelta); + myDone = true; // is OK for sure + } else { + BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true); + if(!aBuilder) { + return; + } + + myDone = aBuilder->IsDone() == Standard_True; + + if(!myDone) { + return; + } + + aResult = aBuilder->Shape(); + // Fill data map to keep correct orientation of sub-shapes. + for(TopExp_Explorer anExp(aResult, TopAbs_FACE); anExp.More(); anExp.Next()) { + std::shared_ptr aCurrentShape(new GeomAPI_Shape()); + aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current())); + myMap->bind(aCurrentShape, aCurrentShape); + } + myMkShape->setImpl(aBuilder); } myShape->setImpl(new TopoDS_Shape(aResult)); - myMkShape->setImpl(aBuilder); } //================================================================================================= diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.h b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.h index c3a81d54e..5a44625a2 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.h @@ -24,10 +24,12 @@ public: * \param[in] theSourceShape a shape to be rotated. * \param[in] theAxis rotation axis. * \param[in] theAngle rotation angle(in degree). + * \param[in] theSimpleTransform makes just transformation of shape without changing of topology or geometry */ GEOMALGOAPI_EXPORT GeomAlgoAPI_Rotation(std::shared_ptr theSourceShape, std::shared_ptr theAxis, - double theAngle); + double theAngle, + bool theSimpleTransform = false); /// \return true if algorithm succeed. GEOMALGOAPI_EXPORT const bool isDone() const @@ -52,7 +54,8 @@ private: /// Builds resulting shape. void build(std::shared_ptr theSourceShape, std::shared_ptr theAxis, - double theAngle); + double theAngle, + bool theSimpleTransform); private: /// Fields. diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index df8ea041b..864975b2e 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -73,7 +73,6 @@ Standard_GUID kPART_REF_ID("635eacb2-a1d6-4dec-8348-471fae17cb27"); // TDataStd_IntPackedMap - indexes of edges in composite element (for construction) // TDataStd_Integer - type of the selected shape (for construction) // TDF_Reference - from ReferenceAttribute, the context -#define DDDD 1 void Model_AttributeSelection::setValue(const ResultPtr& theContext, const std::shared_ptr& theSubShape) { @@ -137,13 +136,6 @@ void Model_AttributeSelection::setValue(const ResultPtr& theContext, std::string aSelName = namingName(); if(!aSelName.empty()) TDataStd_Name::Set(selectionLabel(), aSelName.c_str()); //set name -#ifdef DDDD - //#### - //selectSubShape("FACE", "Extrusion_1/LateralFace_3"); - //selectSubShape("FACE", "Extrusion_1/TopFace"); - //selectSubShape("EDGE", "Extrusion_1/TopFace|Extrusion_1/LateralFace_1"); - //selectSubShape("EDGE", "Sketch_1/Edge_6"); -#endif } std::shared_ptr Model_AttributeSelection::value() @@ -160,6 +152,22 @@ std::shared_ptr Model_AttributeSelection::value() if (aSelLab.IsAttribute(kCONSTUCTION_SIMPLE_REF_ID)) { // it is just reference to construction, nothing is in value return aResult; // empty result } + if (aSelLab.IsAttribute(kPART_REF_ID)) { + /* TODO: implement used text here + ResultPartPtr aPart = std::dynamic_pointer_cast(context()); + if (!aPart.get() || !aPart->isActivated()) + return std::shared_ptr(); // postponed naming needed + Handle(TDataStd_Integer) anIndex; + if (selectionLabel().FindAttribute(TDataStd_Integer::GetID(), anIndex)) { + return aPart->selectionValue(anIndex->Get()); + } + Handle(TDataStd_Name) aName; + if (!selectionLabel().FindAttribute(TDataStd_Name::GetID(), aName)) { + return std::shared_ptr(); // something is wrong + } + return aPart->shapeInPart(TCollection_AsciiString(aName).ToCString()); + */ + } Handle(TNaming_NamedShape) aSelection; if (selectionLabel().FindAttribute(TNaming_NamedShape::GetID(), aSelection)) { @@ -264,6 +272,11 @@ bool Model_AttributeSelection::update() return aContext->shape() && !aContext->shape()->isNull(); } + if (aSelLab.IsAttribute(kPART_REF_ID)) { // it is reference to the part object + std::shared_ptr aNoSelection; + return selectPart(aContext, aNoSelection, true); + } + if (aContext->groupName() == ModelAPI_ResultBody::group()) { // body: just a named shape, use selection mechanism from OCCT TNaming_Selector aSelector(aSelLab); @@ -614,9 +627,25 @@ void Model_AttributeSelection::selectConstruction( registerSubShape(selectionLabel(), aSubShape, 0, aContextFeature, aMyDoc, "", aRefs); } -void Model_AttributeSelection::selectPart( - const ResultPtr& theContext, const std::shared_ptr& theSubShape) +bool Model_AttributeSelection::selectPart( + const ResultPtr& theContext, const std::shared_ptr& theSubShape, + const bool theUpdate) { + ResultPartPtr aPart = std::dynamic_pointer_cast(theContext); + if (!aPart.get() || !aPart->isActivated()) + return true; // postponed naming + if (theUpdate) { + Handle(TDataStd_Integer) anIndex; + if (selectionLabel().FindAttribute(TDataStd_Integer::GetID(), anIndex)) { // by internal selection + if (anIndex->Get() > 0) { + // update the selection by index + return aPart->updateInPart(anIndex->Get()); + } else { + return true; // nothing to do, referencing just by name + } + } + return true; // nothing to do, referencing just by name + } // store the shape (in case part is not loaded it should be usefull TopoDS_Shape aShape; std::string aName = theContext->data()->name(); @@ -624,13 +653,15 @@ void Model_AttributeSelection::selectPart( aShape = theContext->shape()->impl(); } else { aShape = theSubShape->impl(); - ResultPartPtr aPart = std::dynamic_pointer_cast(theContext); - aName += "/" + aPart->nameInPart(theSubShape); + int anIndex; + aName += "/" + aPart->nameInPart(theSubShape, anIndex); + TDataStd_Integer::Set(selectionLabel(), anIndex); } TNaming_Builder aBuilder(selectionLabel()); aBuilder.Select(aShape, aShape); // identify by name in the part TDataStd_Name::Set(selectionLabel(), aName.c_str()); + return !aName.empty(); } TDF_Label Model_AttributeSelection::selectionLabel() diff --git a/src/Model/Model_AttributeSelection.h b/src/Model/Model_AttributeSelection.h index 9e9213f87..91e77e6e8 100644 --- a/src/Model/Model_AttributeSelection.h +++ b/src/Model/Model_AttributeSelection.h @@ -69,8 +69,13 @@ protected: const ResultPtr& theContext, const std::shared_ptr& theSubShape); /// Performs the selection for the part result (selection by name of body result inside of part) - virtual void selectPart( - const ResultPtr& theContext, const std::shared_ptr& theSubShape); + /// \param theContext the result - owner of the selection + /// \param theSubShape selected shape + /// \param theUpdate flag that shows that it must be just update, theShape is null + /// \param returns true if eveything is selected correctly + virtual bool selectPart( + const ResultPtr& theContext, const std::shared_ptr& theSubShape, + const bool theUpdate = false); /// Returns the label where TNaming_Selection results are stored /// Note: there must be no attributes stored at the same label because Selector clears this lab diff --git a/src/Model/Model_Data.cpp b/src/Model/Model_Data.cpp index 347a21820..29a9266a5 100644 --- a/src/Model/Model_Data.cpp +++ b/src/Model/Model_Data.cpp @@ -502,3 +502,8 @@ std::shared_ptr Model_Data::invalidData() { return kInvalid; } + +bool Model_Data::isOwner(ModelAPI_Object* theOwner) +{ + return theOwner == myObject.get(); +} diff --git a/src/Model/Model_Data.h b/src/Model/Model_Data.h index 5e51c9d50..1a502b4b0 100644 --- a/src/Model/Model_Data.h +++ b/src/Model/Model_Data.h @@ -200,6 +200,10 @@ class Model_Data : public ModelAPI_Data /// This method is called by the updater. MODEL_EXPORT virtual void setUpdateID(const int theID); + /// Returns true if the given object is owner of this data (needed for correct erase of object + /// with duplicated data) + MODEL_EXPORT virtual bool isOwner(ModelAPI_Object* theOwner); + protected: /// Returns true if "is in history" custom behaviors is defined for the feature MODEL_EXPORT virtual bool isInHistory(); diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 1c61d4f7c..1cdd0bcf1 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -47,6 +48,7 @@ static const int TAG_GENERAL = 1; // general properties tag // general sub-labels static const int TAG_CURRENT_FEATURE = 1; ///< where the reference to the current feature label is located (or no attribute if null feature) static const int TAG_CURRENT_TRANSACTION = 2; ///< integer, index of the cransaction +static const int TAG_SELECTION_FEATURE = 3; ///< integer, tag of the selection feature label Model_Document::Model_Document(const std::string theID, const std::string theKind) : myID(theID), myKind(theKind), myIsActive(false), @@ -274,6 +276,7 @@ void Model_Document::close(const bool theForever) myObjs = 0; if (myDoc->CanClose() == CDM_CCS_OK) myDoc->Close(); + mySelectionFeature.reset(); } else { setCurrentFeature(FeaturePtr(), false); // disables all features } @@ -801,6 +804,14 @@ std::shared_ptr Model_Document::createPart( return myObjs->createPart(theFeatureData, theIndex); } +std::shared_ptr Model_Document::copyPart( + const std::shared_ptr& theOldPart, + const std::shared_ptr& theOrigin, + const int theIndex) +{ + return myObjs->copyPart(theOldPart, theOrigin, theIndex); +} + std::shared_ptr Model_Document::createGroup( const std::shared_ptr& theFeatureData, const int theIndex) { @@ -919,3 +930,45 @@ std::shared_ptr Model_Document::internalFeature(const int theI { return myObjs->internalFeature(theIndex); } + +// Feature that is used for selection in the Part document by the external request +class Model_SelectionInPartFeature : public ModelAPI_Feature { +public: + /// Nothing to do in constructor + Model_SelectionInPartFeature() : ModelAPI_Feature() {} + + /// Returns the unique kind of a feature + virtual const std::string& getKind() { + static std::string MY_KIND("InternalSelectionInPartFeature"); + return MY_KIND; + } + /// Request for initialization of data model of the object: adding all attributes + virtual void initAttributes() { + data()->addAttribute("selection", ModelAPI_AttributeSelectionList::typeId()); + } + /// Nothing to do in the execution function + virtual void execute() {} + +}; + +//! Returns the feature that is used for calculation of selection externally from the document +AttributeSelectionListPtr Model_Document::selectionInPartFeature() +{ + // return already created, otherwise create + if (!mySelectionFeature.get() || !mySelectionFeature->data()->isValid()) { + // create a new one + mySelectionFeature = FeaturePtr(new Model_SelectionInPartFeature); + + TDF_Label aFeatureLab = generalLabel().FindChild(TAG_SELECTION_FEATURE); + std::shared_ptr aData(new Model_Data); + aData->setLabel(aFeatureLab.FindChild(1)); + aData->setObject(mySelectionFeature); + mySelectionFeature->setDoc(myObjs->owner()); + mySelectionFeature->setData(aData); + std::string aName = id() + "_Part"; + mySelectionFeature->data()->setName(aName); + mySelectionFeature->setDoc(myObjs->owner()); + mySelectionFeature->initAttributes(); + } + return mySelectionFeature->selectionList("selection"); +} diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index 70cfcf618..7c757ce07 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -19,6 +19,7 @@ class Handle_Model_Document; class Model_Objects; +class ModelAPI_AttributeSelectionList; /**\class Model_Document * \ingroup DataModel @@ -153,6 +154,11 @@ class Model_Document : public ModelAPI_Document /// Creates a part results MODEL_EXPORT virtual std::shared_ptr createPart( const std::shared_ptr& theFeatureData, const int theIndex = 0); + //! Copies a part result, keeping the same data + MODEL_EXPORT virtual std::shared_ptr copyPart( + const std::shared_ptr& theOldPart, + const std::shared_ptr& theOrigin, + const int theIndex = 0); /// Creates a group results MODEL_EXPORT virtual std::shared_ptr createGroup( const std::shared_ptr& theFeatureData, const int theIndex = 0); @@ -241,6 +247,9 @@ class Model_Document : public ModelAPI_Document //! Returns true if this document is currently active virtual bool isActive() const; + //! Returns the selection attribute that is used for calculation of selection externally from the document + std::shared_ptr selectionInPartFeature(); + friend class Model_Application; friend class Model_Session; friend class Model_Update; @@ -283,6 +292,9 @@ class Model_Document : public ModelAPI_Document bool myExecuteFeatures; bool myIsActive; ///< flag that stores the active/not active state + + //! The selection feature, if needed + FeaturePtr mySelectionFeature; }; #endif diff --git a/src/Model/Model_Objects.cpp b/src/Model/Model_Objects.cpp index 1acc94806..0eab9cf32 100644 --- a/src/Model/Model_Objects.cpp +++ b/src/Model/Model_Objects.cpp @@ -774,6 +774,22 @@ std::shared_ptr Model_Objects::createPart( return aResult; } +std::shared_ptr Model_Objects::copyPart( + const std::shared_ptr& theOldPart, + const std::shared_ptr& theOrigin, const int theIndex) +{ + std::shared_ptr aResult; + if (theOldPart.get()) { + aResult = std::dynamic_pointer_cast(theOldPart); + } + if (!aResult) { + aResult = std::shared_ptr(new Model_ResultPart); + aResult->setDoc(myDoc); + aResult->setData(theOrigin->data()); + } + return aResult; +} + std::shared_ptr Model_Objects::createGroup( const std::shared_ptr& theFeatureData, const int theIndex) { diff --git a/src/Model/Model_Objects.h b/src/Model/Model_Objects.h index 52df45200..ec81a9f6a 100644 --- a/src/Model/Model_Objects.h +++ b/src/Model/Model_Objects.h @@ -103,6 +103,10 @@ class Model_Objects /// Creates a part results std::shared_ptr createPart( const std::shared_ptr& theFeatureData, const int theIndex = 0); + /// Copies a part results, keeping the same data + std::shared_ptr copyPart( + const std::shared_ptr& theOldPart, + const std::shared_ptr& theOrigin, const int theIndex = 0); /// Creates a group results std::shared_ptr createGroup( const std::shared_ptr& theFeatureData, const int theIndex = 0); diff --git a/src/Model/Model_ResultPart.cpp b/src/Model/Model_ResultPart.cpp index 87552e362..5023340b1 100644 --- a/src/Model/Model_ResultPart.cpp +++ b/src/Model/Model_ResultPart.cpp @@ -6,12 +6,16 @@ #include #include +#include #include #include #include #include #include +#include #include +#include +#include #include #include @@ -19,6 +23,7 @@ #include #include #include +#include void Model_ResultPart::initAttributes() { @@ -135,9 +140,34 @@ std::shared_ptr Model_ResultPart::shape() return aResult; } -std::string Model_ResultPart::nameInPart(const std::shared_ptr& theShape) +std::string Model_ResultPart::nameInPart(const std::shared_ptr& theShape, + int& theIndex) { + theIndex = 0; // not initialized TopoDS_Shape aShape = theShape->impl(); + if (aShape.IsNull()) + return ""; + if (data()->isOwner(this)) { // if this is moved copy of part => return the name of original shape + FeaturePtr anOrigFeature = + std::dynamic_pointer_cast(data()->attribute(COLOR_ID())->owner()); + if (anOrigFeature.get()) { + if (anOrigFeature->firstResult().get() && anOrigFeature->firstResult()->shape().get()) { + TopoDS_Shape anOrigShape = anOrigFeature->firstResult()->shape()->impl(); + if (!anOrigShape.IsNull()) { + TopExp_Explorer anExp(anOrigShape, aShape.ShapeType()); + for(; anExp.More(); anExp.Next()) { + if (aShape.IsPartner(anExp.Current())) { + std::shared_ptr anOrigGeomShape(new GeomAPI_Shape); + anOrigGeomShape->setImpl(new TopoDS_Shape(anExp.Current())); + + return std::dynamic_pointer_cast(anOrigFeature->firstResult())-> + nameInPart(theShape, theIndex); + } + } + } + } + } + } // getting an access to the document of part std::shared_ptr aDoc = std::dynamic_pointer_cast(partDoc()); if (!aDoc.get()) // the part document is not presented for the moment @@ -166,9 +196,47 @@ std::string Model_ResultPart::nameInPart(const std::shared_ptr& t } } } + if (aName.empty()) { // not found, so use the selection mechanism + // for this the context result is needed + ResultPtr aContext; + const std::string& aBodyGroup = ModelAPI_ResultBody::group(); + for(int a = aDoc->size(aBodyGroup) - 1; a >= 0; a--) { + ResultPtr aBody = std::dynamic_pointer_cast(aDoc->object(aBodyGroup, a)); + if (aBody.get() && aBody->shape().get() && !aBody->isDisabled()) { + TopoDS_Shape aBodyShape = *(aBody->shape()->implPtr()); + // check is body contain the selected sub-shape + for(TopExp_Explorer anExp(aBodyShape, aShape.ShapeType()); anExp.More(); anExp.Next()) { + if (aShape.IsEqual(anExp.Current())) { + aContext = aBody; + break; + } + } + } + } + if (aContext.get()) { + AttributeSelectionListPtr aSelAttr = aDoc->selectionInPartFeature(); + aSelAttr->append(aContext, theShape); + theIndex = aSelAttr->size(); + AttributeSelectionPtr aNewAttr = aSelAttr->value(theIndex - 1); + return aNewAttr->namingName(); + } + } return aName; } +bool Model_ResultPart::updateInPart(const int theIndex) +{ + std::shared_ptr aDoc = std::dynamic_pointer_cast(partDoc()); + if (aDoc.get()) { + AttributeSelectionListPtr aSelAttr = aDoc->selectionInPartFeature(); + AttributeSelectionPtr aThisAttr = aSelAttr->value(theIndex - 1); + if (aThisAttr.get()) { + return aThisAttr->update(); + } + } + return false; // something is wrong +} + std::shared_ptr Model_ResultPart::shapeInPart(const std::string& theName) { /// TODO: not implemented yet @@ -188,3 +256,13 @@ void Model_ResultPart::updateShape() { myShape.Nullify(); } + +void Model_ResultPart::setShape(std::shared_ptr theThis, + const std::shared_ptr& theTransformed) +{ + myShape = theTransformed->impl(); + // the result must be explicitly updated + static Events_Loop* aLoop = Events_Loop::loop(); + static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); + ModelAPI_EventCreator::get()->sendUpdated(theThis, EVENT_DISP); // flush is in preview-update +} diff --git a/src/Model/Model_ResultPart.h b/src/Model/Model_ResultPart.h index 06c6efdad..1f4ca4946 100644 --- a/src/Model/Model_ResultPart.h +++ b/src/Model/Model_ResultPart.h @@ -40,11 +40,20 @@ class Model_ResultPart : public ModelAPI_ResultPart MODEL_EXPORT virtual std::shared_ptr shape(); /// Returns the name of the shape inside of the part - MODEL_EXPORT virtual std::string nameInPart(const std::shared_ptr& theShape); + /// \param theShape selected shape in this document + /// \param theIndex is returned as one-based index if selection was required, "0" otherwise + /// \returns empty name is selection is not correct + MODEL_EXPORT virtual std::string nameInPart(const std::shared_ptr& theShape, + int& theIndex); + + /// Updates the selection inside of the part by the selection index + MODEL_EXPORT virtual bool updateInPart(const int theIndex); /// Returns the shape by the name in the part MODEL_EXPORT virtual std::shared_ptr shapeInPart(const std::string& theName); /// Updates the shape-result of the part (called on Part feature execution) MODEL_EXPORT virtual void updateShape(); + MODEL_EXPORT virtual void setShape(std::shared_ptr theThis, + const std::shared_ptr& theTransformed); /// Returns the parameters of color definition in the resources config manager MODEL_EXPORT virtual void colorConfigInfo(std::string& theSection, std::string& theName, diff --git a/src/Model/Model_Update.cpp b/src/Model/Model_Update.cpp index 1e5bb3fed..3262812a5 100644 --- a/src/Model/Model_Update.cpp +++ b/src/Model/Model_Update.cpp @@ -238,17 +238,37 @@ void Model_Update::updateFeature(FeaturePtr theFeature, std::set& th if (myIsAutomatic && theFeature->data()->execState() == ModelAPI_StateMustBeUpdated) aJustUpdated = true; + // On abort, undo or redo execute is not needed: results in document are updated automatically + // But redisplay is needed: results are updated, must be also updated in the viewer. + if (aJustUpdated && + !std::dynamic_pointer_cast(theFeature->document())->executeFeatures()) { + if (!theFeature->isPersistentResult()) { // not persistent must be re-executed on abort, etc. + ModelAPI_ExecState aState = theFeature->data()->execState(); + if (aFactory->validate(theFeature)) { + executeFeature(theFeature); + } else { + theFeature->eraseResults(); + redisplayWithResults(theFeature, ModelAPI_StateInvalidArgument); // result also must be updated + } + } else { + redisplayWithResults(theFeature, ModelAPI_StateNothing); + if (theFeature->data()->execState() == ModelAPI_StateMustBeUpdated) { // it is done (in the tree) + theFeature->data()->execState(ModelAPI_StateDone); + } + } + return; + } + // execute feature if it must be updated if (theFeature->isPreviewNeeded() || myIsFinish) { - if (aJustUpdated && - std::dynamic_pointer_cast(theFeature->document())->executeFeatures()) { - ModelAPI_ExecState aState = theFeature->data()->execState(); - if (aFactory->validate(theFeature)) { - executeFeature(theFeature); - } else { - theFeature->eraseResults(); - redisplayWithResults(theFeature, ModelAPI_StateInvalidArgument); // result also must be updated - } + if (aJustUpdated) { + ModelAPI_ExecState aState = theFeature->data()->execState(); + if (aFactory->validate(theFeature)) { + executeFeature(theFeature); + } else { + theFeature->eraseResults(); + redisplayWithResults(theFeature, ModelAPI_StateInvalidArgument); // result also must be updated + } } } else { // preview is not needed => make state Done if (theFeature->data()->execState() == ModelAPI_StateMustBeUpdated) { diff --git a/src/ModelAPI/ModelAPI.i b/src/ModelAPI/ModelAPI.i index 5f2a84178..692cc0881 100644 --- a/src/ModelAPI/ModelAPI.i +++ b/src/ModelAPI/ModelAPI.i @@ -38,7 +38,7 @@ #include "ModelAPI_ResultParameter.h" #include "ModelAPI_ResultGroup.h" #include "ModelAPI_Tools.h" - + #include #include diff --git a/src/ModelAPI/ModelAPI_Data.h b/src/ModelAPI/ModelAPI_Data.h index 0cd4631e6..dfc6ee32a 100644 --- a/src/ModelAPI/ModelAPI_Data.h +++ b/src/ModelAPI/ModelAPI_Data.h @@ -154,6 +154,10 @@ class MODELAPI_EXPORT ModelAPI_Data /// This method is called by the updater. virtual void setUpdateID(const int theID) = 0; + /// Returns true if the given object is owner of this data (needed for correct erase of object + /// with duplicated data) + virtual bool isOwner(ModelAPI_Object* theOwner) = 0; + protected: /// Objects are created for features automatically ModelAPI_Data(); diff --git a/src/ModelAPI/ModelAPI_Document.h b/src/ModelAPI/ModelAPI_Document.h index 4c06461fa..9f9297001 100644 --- a/src/ModelAPI/ModelAPI_Document.h +++ b/src/ModelAPI/ModelAPI_Document.h @@ -124,6 +124,11 @@ public: //! Creates a part results virtual std::shared_ptr createPart( const std::shared_ptr& theFeatureData, const int theIndex = 0) = 0; + //! Copies a part result, keeping the same data + virtual std::shared_ptr copyPart( + const std::shared_ptr& theOldPart, + const std::shared_ptr& theOrigin, + const int theIndex = 0) = 0; //! Creates a group results virtual std::shared_ptr createGroup( const std::shared_ptr& theFeatureData, const int theIndex = 0) = 0; diff --git a/src/ModelAPI/ModelAPI_Object.cpp b/src/ModelAPI/ModelAPI_Object.cpp index dc76a0792..9d08a0c37 100644 --- a/src/ModelAPI/ModelAPI_Object.cpp +++ b/src/ModelAPI/ModelAPI_Object.cpp @@ -68,7 +68,8 @@ void ModelAPI_Object::setDoc(std::shared_ptr theDoc) void ModelAPI_Object::erase() { - if (myData->isValid() && myData != myData->invalidPtr()) myData->erase(); + if (myData->isValid() && myData != myData->invalidPtr() && myData->isOwner(this)) + myData->erase(); setData(myData->invalidPtr()); } diff --git a/src/ModelAPI/ModelAPI_Object.h b/src/ModelAPI/ModelAPI_Object.h index 9d1d04c39..fd54a5f2d 100644 --- a/src/ModelAPI/ModelAPI_Object.h +++ b/src/ModelAPI/ModelAPI_Object.h @@ -86,6 +86,7 @@ class ModelAPI_Object MODELAPI_EXPORT virtual void erase(); friend class Model_Objects; + friend class Model_Document; }; diff --git a/src/ModelAPI/ModelAPI_Result.cpp b/src/ModelAPI/ModelAPI_Result.cpp index 1816c54d9..25b97c3a9 100644 --- a/src/ModelAPI/ModelAPI_Result.cpp +++ b/src/ModelAPI/ModelAPI_Result.cpp @@ -41,6 +41,11 @@ bool ModelAPI_Result::isDisabled() const return myIsDisabled; } +bool ModelAPI_Result::isConcealed() +{ + return myIsConcealed; +} + void ModelAPI_Result::setIsConcealed(const bool theValue) { if (myIsConcealed != theValue) { diff --git a/src/ModelAPI/ModelAPI_Result.h b/src/ModelAPI/ModelAPI_Result.h index 9889e4884..7922612c6 100644 --- a/src/ModelAPI/ModelAPI_Result.h +++ b/src/ModelAPI/ModelAPI_Result.h @@ -35,10 +35,7 @@ class ModelAPI_Result : public ModelAPI_Object } /// Returns true if the result is concealed from the data tree (referenced by other objects) - inline bool isConcealed() - { - return myIsConcealed; - } + MODELAPI_EXPORT virtual bool isConcealed(); /// Returns true if the result is concealed from the data tree (referenced by other objects) MODELAPI_EXPORT void setIsConcealed(const bool theValue); diff --git a/src/ModelAPI/ModelAPI_ResultPart.cpp b/src/ModelAPI/ModelAPI_ResultPart.cpp index 9790051d7..3639c47b1 100644 --- a/src/ModelAPI/ModelAPI_ResultPart.cpp +++ b/src/ModelAPI/ModelAPI_ResultPart.cpp @@ -12,3 +12,9 @@ std::string ModelAPI_ResultPart::groupName() { return ModelAPI_ResultPart::group(); } + +bool ModelAPI_ResultPart::isConcealed() +{ + //return false; + return ModelAPI_Result::isConcealed(); // the way with different results is applied +} diff --git a/src/ModelAPI/ModelAPI_ResultPart.h b/src/ModelAPI/ModelAPI_ResultPart.h index 74d86953f..6d23fe38b 100644 --- a/src/ModelAPI/ModelAPI_ResultPart.h +++ b/src/ModelAPI/ModelAPI_ResultPart.h @@ -45,6 +45,9 @@ class ModelAPI_ResultPart : public ModelAPI_Result return RESULT_BODY_COLOR; } + // Part result can not be cencealed, even by the movement features + MODELAPI_EXPORT virtual bool isConcealed(); + /// Returns the part-document of this result virtual std::shared_ptr partDoc() = 0; @@ -55,7 +58,15 @@ class ModelAPI_ResultPart : public ModelAPI_Result virtual bool isActivated() = 0; /// Returns the name of the shape inside of the part - virtual std::string nameInPart(const std::shared_ptr& theShape) = 0; + virtual std::string nameInPart(const std::shared_ptr& theShape, + int& theIndex) = 0; + /// Updates the selection inside of the part by the selection index + virtual bool updateInPart(const int theIndex) = 0; + + /// Applies the additional transformation ofthe part + virtual void setShape(std::shared_ptr theThis, + const std::shared_ptr& theTransformed) = 0; + /// Returns the shape by the name in the part virtual std::shared_ptr shapeInPart(const std::string& theName) = 0; /// Updates the shape-result of the part (called on Part feature execution) -- 2.39.2