From 0c0c2fd5b941ad2e65a0e82251dca2f796750b97 Mon Sep 17 00:00:00 2001 From: mpv Date: Wed, 15 Jul 2015 12:25:37 +0300 Subject: [PATCH] Debug of movement of part results --- .../FeaturesPlugin_Movement.cpp | 2 +- .../FeaturesPlugin_Placement.cpp | 5 +- .../FeaturesPlugin_Rotation.cpp | 2 +- src/FeaturesPlugin/plugin-Features.xml | 6 +- src/GeomAPI/CMakeLists.txt | 2 + src/GeomAPI/GeomAPI.i | 3 + src/GeomAPI/GeomAPI_Trsf.cpp | 19 +++ src/GeomAPI/GeomAPI_Trsf.h | 28 ++++ src/GeomAlgoAPI/GeomAlgoAPI_Movement.cpp | 9 ++ src/GeomAlgoAPI/GeomAlgoAPI_Movement.h | 5 + src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp | 16 ++- src/GeomAlgoAPI/GeomAlgoAPI_Placement.h | 5 + src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp | 8 ++ src/GeomAlgoAPI/GeomAlgoAPI_Rotation.h | 5 + src/Model/Model_AttributeSelection.cpp | 50 ++++--- src/Model/Model_ResultPart.cpp | 127 +++++++++++------- src/Model/Model_ResultPart.h | 10 +- src/Model/Model_Update.cpp | 32 +++-- src/ModelAPI/ModelAPI_ResultPart.h | 7 +- 19 files changed, 244 insertions(+), 97 deletions(-) create mode 100644 src/GeomAPI/GeomAPI_Trsf.cpp create mode 100644 src/GeomAPI/GeomAPI_Trsf.h diff --git a/src/FeaturesPlugin/FeaturesPlugin_Movement.cpp b/src/FeaturesPlugin/FeaturesPlugin_Movement.cpp index a65e1d9e4..ca4b8a579 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Movement.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Movement.cpp @@ -110,7 +110,7 @@ void FeaturesPlugin_Movement::execute() } } ResultPartPtr aResultPart = document()->copyPart(aCurrentResult, anOrigin, aResultIndex); - aResultPart->setShape(*aContext, aMovementAlgo.shape()); + aResultPart->setTrsf(*aContext, aMovementAlgo.transformation()); setResult(aResultPart); } else { ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); diff --git a/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp b/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp index dbc17b850..28ae85234 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp @@ -119,7 +119,8 @@ void FeaturesPlugin_Placement::execute() std::shared_ptr aResultBody; if (!isPart) aResultBody = document()->createBody(data()); - GeomAlgoAPI_Placement aFeature(aSlaveObject, aBaseObject, aSlaveShape, aBaseShape, isReverse, isCentering); + GeomAlgoAPI_Placement aFeature( + aSlaveObject, aBaseObject, aSlaveShape, aBaseShape, isReverse, isCentering, isPart); if(!aFeature.isDone()) { static const std::string aFeatureError = "Placement algorithm failed"; setError(aFeatureError); @@ -141,7 +142,7 @@ void FeaturesPlugin_Placement::execute() 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()); + aResultPart->setTrsf(aContextRes, aFeature.transformation()); setResult(aResultPart); } else { //LoadNamingDS diff --git a/src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp b/src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp index aa29c2273..a2229a95d 100755 --- a/src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp @@ -110,7 +110,7 @@ void FeaturesPlugin_Rotation::execute() } } ResultPartPtr aResultPart = document()->copyPart(aCurrentResult, anOrigin, aResultIndex); - aResultPart->setShape(*aContext, aRotationAlgo.shape()); + aResultPart->setTrsf(*aContext, aRotationAlgo.transformation()); setResult(aResultPart); } else { ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); diff --git a/src/FeaturesPlugin/plugin-Features.xml b/src/FeaturesPlugin/plugin-Features.xml index 6772d2bda..b5dc47317 100644 --- a/src/FeaturesPlugin/plugin-Features.xml +++ b/src/FeaturesPlugin/plugin-Features.xml @@ -38,12 +38,12 @@ - - + + - + diff --git a/src/GeomAPI/CMakeLists.txt b/src/GeomAPI/CMakeLists.txt index 8a66dfa86..12450b5ef 100644 --- a/src/GeomAPI/CMakeLists.txt +++ b/src/GeomAPI/CMakeLists.txt @@ -32,6 +32,7 @@ SET(PROJECT_HEADERS GeomAPI_Vertex.h GeomAPI_Ax1.h GeomAPI_Ax3.h + GeomAPI_Trsf.h ) SET(PROJECT_SOURCES @@ -60,6 +61,7 @@ SET(PROJECT_SOURCES GeomAPI_Ax1.cpp GeomAPI_Ax3.cpp GeomAPI_IPresentable.cpp + GeomAPI_Trsf.cpp ) SET(PROJECT_LIBRARIES diff --git a/src/GeomAPI/GeomAPI.i b/src/GeomAPI/GeomAPI.i index ea223aac6..ff20e6714 100644 --- a/src/GeomAPI/GeomAPI.i +++ b/src/GeomAPI/GeomAPI.i @@ -27,6 +27,7 @@ #include "GeomAPI_Vertex.h" #include "GeomAPI_XY.h" #include "GeomAPI_XYZ.h" + #include "GeomAPI_Trsf.h" #include #include @@ -66,6 +67,7 @@ %shared_ptr(GeomAPI_Vertex) %shared_ptr(GeomAPI_XY) %shared_ptr(GeomAPI_XYZ) +%shared_ptr(GeomAPI_Trsf) // all supported interfaces @@ -94,3 +96,4 @@ %include "GeomAPI_Vertex.h" %include "GeomAPI_XY.h" %include "GeomAPI_XYZ.h" +%include "GeomAPI_Trsf.h" diff --git a/src/GeomAPI/GeomAPI_Trsf.cpp b/src/GeomAPI/GeomAPI_Trsf.cpp new file mode 100644 index 000000000..7a3c8c178 --- /dev/null +++ b/src/GeomAPI/GeomAPI_Trsf.cpp @@ -0,0 +1,19 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: GeomAPI_Trsf.cpp +// Created: 13 Jul 2015 +// Author: Mikhail PONIKAROV + +#include + +#include + +GeomAPI_Trsf::GeomAPI_Trsf() + : GeomAPI_Interface() +{ +} + +GeomAPI_Trsf::GeomAPI_Trsf(void* theTrsf) + : GeomAPI_Interface(theTrsf) +{ +} diff --git a/src/GeomAPI/GeomAPI_Trsf.h b/src/GeomAPI/GeomAPI_Trsf.h new file mode 100644 index 000000000..ebb7871f9 --- /dev/null +++ b/src/GeomAPI/GeomAPI_Trsf.h @@ -0,0 +1,28 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: GeomAPI_XYZ.hxx +// Created: 13 July 2015 +// Author: Mikhail PONIKAROV + +#ifndef GeomAPI_Trsf_H_ +#define GeomAPI_Trsf_H_ + +#include +#include + +/**\class GeomAPI_Trsf + * \ingroup DataModel + * \brief Keep the transformation matrix coefficients + */ + +class GeomAPI_Trsf : public GeomAPI_Interface +{ + public: + /// Keeps no transformation, it may be set by setImpl + GEOMAPI_EXPORT GeomAPI_Trsf(); + /// Takes the pointer to existing transformation + GEOMAPI_EXPORT GeomAPI_Trsf(void* theTrsf); +}; + +#endif + diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Movement.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Movement.cpp index 40a14a5a5..a35988cde 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Movement.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Movement.cpp @@ -52,6 +52,9 @@ void GeomAlgoAPI_Movement::build(std::shared_ptr theSourceShape, if (theSimpleTransform) { TopLoc_Location aDelta(aTrsf); aResult = aSourceShape.Moved(aDelta); + // store the accumulated information about the result and this delta + myTrsf = std::make_shared( + new gp_Trsf(aTrsf * aSourceShape.Location().Transformation())); myDone = true; // is OK for sure } else { BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true); @@ -112,3 +115,9 @@ std::shared_ptr GeomAlgoAPI_Movement::makeShape() const { return myMkShape; } + +//================================================================================================= +std::shared_ptr GeomAlgoAPI_Movement::transformation() const +{ + return myTrsf; +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Movement.h b/src/GeomAlgoAPI/GeomAlgoAPI_Movement.h index 53eb4f4d1..e3cced35b 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Movement.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Movement.h @@ -12,6 +12,7 @@ #include #include #include +#include /** \class GeomAlgoAPI_Movement * \ingroup DataAlgo @@ -50,6 +51,9 @@ public: /// \return interface for for History processing. GEOMALGOAPI_EXPORT std::shared_ptr makeShape() const; + /// Returns the simple transformation + GEOMALGOAPI_EXPORT std::shared_ptr transformation() const; + private: /// Builds resulting shape. void build(std::shared_ptr theSourceShape, @@ -63,6 +67,7 @@ private: std::shared_ptr myShape; std::shared_ptr myMap; std::shared_ptr myMkShape; + std::shared_ptr myTrsf; ///< transformation of the shape in case theSimpleTransform }; #endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp index 35ea7c186..d8fd7a749 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp @@ -24,7 +24,6 @@ #include #include -#define DEB_PLACEMENT 1 GeomAlgoAPI_Placement::GeomAlgoAPI_Placement( std::shared_ptr theSourceSolid, std::shared_ptr theDestSolid, @@ -195,6 +194,10 @@ void GeomAlgoAPI_Placement::build( TopLoc_Location aDelta(aTrsf); TopoDS_Shape aResult = aSourceShape.Moved(aDelta); myShape->setImpl(new TopoDS_Shape(aResult)); + // store the accumulated information about the result and this delta + myTrsf = std::make_shared( + new gp_Trsf(aTrsf * aSourceShape.Location().Transformation())); + myDone = true; // it is allways true for simple transformation generation } else { // internal rebuild of the shape // Transform the shape with copying it BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true); @@ -209,12 +212,6 @@ void GeomAlgoAPI_Placement::build( 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); } @@ -264,6 +261,11 @@ GeomAlgoAPI_MakeShape * GeomAlgoAPI_Placement::makeShape() const return myMkShape; } +std::shared_ptr GeomAlgoAPI_Placement::transformation() const +{ + return myTrsf; +} + //============================================================================ GeomAlgoAPI_Placement::~GeomAlgoAPI_Placement() { diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Placement.h b/src/GeomAlgoAPI/GeomAlgoAPI_Placement.h index 9d8852b2f..866791a02 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Placement.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Placement.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -59,6 +60,9 @@ public: /// Return interface for for History processing GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShape* makeShape () const; + /// Returns the simple transformation + GEOMALGOAPI_EXPORT std::shared_ptr transformation() const; + /// Destructor GEOMALGOAPI_EXPORT virtual ~GeomAlgoAPI_Placement(); @@ -77,6 +81,7 @@ private: std::shared_ptr myShape; GeomAPI_DataMapOfShapeShape myMap; GeomAlgoAPI_MakeShape * myMkShape; + std::shared_ptr myTrsf; ///< transformation of the shape in case theSimpleTransform }; #endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp index 218153110..dc150f194 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp @@ -51,6 +51,8 @@ void GeomAlgoAPI_Rotation::build(std::shared_ptr theSourceShape, if (theSimpleTransform) { TopLoc_Location aDelta(aTrsf); aResult = aSourceShape.Moved(aDelta); + myTrsf = std::make_shared( + new gp_Trsf(aTrsf * aSourceShape.Location().Transformation())); myDone = true; // is OK for sure } else { BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true); @@ -111,3 +113,9 @@ std::shared_ptr GeomAlgoAPI_Rotation::makeShape() const { return myMkShape; } + +//================================================================================================= +std::shared_ptr GeomAlgoAPI_Rotation::transformation() const +{ + return myTrsf; +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.h b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.h index 5a44625a2..bf8e03579 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.h @@ -12,6 +12,7 @@ #include #include #include +#include /** \class GeomAlgoAPI_Rotation * \ingroup DataAlgo @@ -50,6 +51,9 @@ public: /// \return interface for for History processing. GEOMALGOAPI_EXPORT std::shared_ptr makeShape() const; + /// Returns the simple transformation + GEOMALGOAPI_EXPORT std::shared_ptr transformation() const; + private: /// Builds resulting shape. void build(std::shared_ptr theSourceShape, @@ -63,6 +67,7 @@ private: std::shared_ptr myShape; std::shared_ptr myMap; std::shared_ptr myMkShape; + std::shared_ptr myTrsf; ///< transformation of the shape in case theSimpleTransform }; #endif diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 69a1185d2..1f3336a54 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -193,7 +193,7 @@ bool Model_AttributeSelection::isInitialized() TDF_Label aSelLab = selectionLabel(); if (aSelLab.IsAttribute(kSIMPLE_REF_ID)) { // it is just reference to shape, not sub-shape ResultPtr aContext = context(); - return aContext.get(); + return aContext.get() != NULL; } if (aSelLab.IsAttribute(kCONSTUCTION_SIMPLE_REF_ID)) { // it is just reference to construction, nothing is in value return true; @@ -206,7 +206,7 @@ bool Model_AttributeSelection::isInitialized() ResultConstructionPtr aConstr = std::dynamic_pointer_cast(context()); if (aConstr.get()) { - return aConstr->shape().get(); + return aConstr->shape().get() != NULL; } } } @@ -227,7 +227,23 @@ void Model_AttributeSelection::setID(const std::string theID) } ResultPtr Model_AttributeSelection::context() { - return std::dynamic_pointer_cast(myRef.value()); + ResultPtr aResult = std::dynamic_pointer_cast(myRef.value()); + // for parts there could be same-data result, so take the last enabled + if (aResult.get() && aResult->groupName() == ModelAPI_ResultPart::group()) { + int aSize = aResult->document()->size(ModelAPI_ResultPart::group()); + for(int a = aSize - 1; a >= 0; a--) { + ObjectPtr aPart = aResult->document()->object(ModelAPI_ResultPart::group(), a); + if (aPart.get() && aPart->data() == aResult->data()) { + ResultPtr aPartResult = std::dynamic_pointer_cast(aPart); + FeaturePtr anOwnerFeature = std::dynamic_pointer_cast(owner()); + // check that this result is not this-feature result (it is forbidden t oselect itself) + if (anOwnerFeature.get() && anOwnerFeature->firstResult() != aPartResult) { + return aPartResult; + } + } + } + } + return aResult; } @@ -240,19 +256,21 @@ void Model_AttributeSelection::setObject(const std::shared_ptr& TDF_LabelMap& Model_AttributeSelection::scope() { if (myScope.IsEmpty()) { // create a new scope if not yet done - // gets all labels with named shapes that are bofore this feature label (before in history) - TDF_Label aFeatureLab = std::dynamic_pointer_cast( - owner()->data())->label().Father(); - int aFeatureID = aFeatureLab.Tag(); - TDF_ChildIterator aFeaturesIter(aFeatureLab.Father()); - for(; aFeaturesIter.More(); aFeaturesIter.Next()) { - if (aFeaturesIter.Value().Tag() >= aFeatureID) // the left labels are created later - break; - TDF_ChildIDIterator aNSIter(aFeaturesIter.Value(), TNaming_NamedShape::GetID(), 1); - for(; aNSIter.More(); aNSIter.Next()) { - Handle(TNaming_NamedShape) aNS = Handle(TNaming_NamedShape)::DownCast(aNSIter.Value()); - if (!aNS.IsNull() && aNS->Evolution() != TNaming_SELECTED) { - myScope.Add(aNS->Label()); + // gets all featueres with named shapes that are bofore this feature label (before in history) + DocumentPtr aMyDoc = owner()->document(); + std::list > allFeatures = aMyDoc->allFeatures(); + std::list >::iterator aFIter = allFeatures.begin(); + for(; aFIter != allFeatures.end(); aFIter++) { + if (*aFIter == owner()) break; // the left features are created later + if (aFIter->get() && (*aFIter)->data()->isValid()) { + TDF_Label aFeatureLab = std::dynamic_pointer_cast( + (*aFIter)->data())->label().Father(); + TDF_ChildIDIterator aNSIter(aFeatureLab, TNaming_NamedShape::GetID(), 1); + for(; aNSIter.More(); aNSIter.Next()) { + Handle(TNaming_NamedShape) aNS = Handle(TNaming_NamedShape)::DownCast(aNSIter.Value()); + if (!aNS.IsNull() && aNS->Evolution() != TNaming_SELECTED) { + myScope.Add(aNS->Label()); + } } } } diff --git a/src/Model/Model_ResultPart.cpp b/src/Model/Model_ResultPart.cpp index 5523e7fbd..872dbaf02 100644 --- a/src/Model/Model_ResultPart.cpp +++ b/src/Model/Model_ResultPart.cpp @@ -28,8 +28,8 @@ void Model_ResultPart::initAttributes() { // append the color attribute. It is empty, the attribute will be filled by a request - DataPtr aData = data(); - aData->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::typeId()); + data()->addAttribute(DOC_REF(), ModelAPI_AttributeDocRef::typeId()); + data()->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::typeId()); } std::shared_ptr Model_ResultPart::partDoc() @@ -48,14 +48,6 @@ Model_ResultPart::Model_ResultPart() setIsConcealed(false); } -void Model_ResultPart::setData(std::shared_ptr theData) -{ - ModelAPI_Result::setData(theData); - if (theData) { - data()->addAttribute(DOC_REF(), ModelAPI_AttributeDocRef::typeId()); - } -} - void Model_ResultPart::activate() { std::shared_ptr aDocRef = data()->document(DOC_REF()); @@ -83,24 +75,26 @@ void Model_ResultPart::activate() bool Model_ResultPart::isActivated() { std::shared_ptr aDocRef = data()->document(DOC_REF()); - return aDocRef->value().get(); + return aDocRef->value().get() != NULL; } bool Model_ResultPart::setDisabled(std::shared_ptr theThis, const bool theFlag) { if (ModelAPI_ResultPart::setDisabled(theThis, theFlag)) { - DocumentPtr aDoc = Model_ResultPart::partDoc(); - if (aDoc.get() && aDoc->isOpened()) { - // make the current feature the last in any case: to update shapes defore deactivation too - FeaturePtr aLastFeature = std::dynamic_pointer_cast(aDoc->object( - ModelAPI_Feature::group(), aDoc->size(ModelAPI_Feature::group()) - 1)); - aDoc->setCurrentFeature(aLastFeature, false); - if (theFlag) { // disable, so make all features disabled too - // update the shape just before the deactivation: it will be used outside of part - myShape.Nullify(); - shape(); - aDoc->setCurrentFeature(FeaturePtr(), false); + if (!myTrsf.get()) { // disable of base result part + DocumentPtr aDoc = Model_ResultPart::partDoc(); + if (aDoc.get() && aDoc->isOpened()) { + // make the current feature the last in any case: to update shapes defore deactivation too + FeaturePtr aLastFeature = std::dynamic_pointer_cast(aDoc->object( + ModelAPI_Feature::group(), aDoc->size(ModelAPI_Feature::group()) - 1)); + aDoc->setCurrentFeature(aLastFeature, false); + if (theFlag) { // disable, so make all features disabled too + // update the shape just before the deactivation: it will be used outside of part + updateShape(); + shape(); + aDoc->setCurrentFeature(FeaturePtr(), false); + } } } return true; @@ -110,7 +104,21 @@ bool Model_ResultPart::setDisabled(std::shared_ptr theThis, std::shared_ptr Model_ResultPart::shape() { - if (myShape.IsNull()) { + std::shared_ptr aResult(new GeomAPI_Shape); + if (myTrsf.get()) { // get shape of the base result and apply the transformation + ResultPtr anOrigResult = + std::dynamic_pointer_cast(data()->attribute(COLOR_ID())->owner()); + std::shared_ptr anOrigShape = anOrigResult->shape(); + if (anOrigShape.get()) { + TopoDS_Shape aShape = anOrigShape->impl(); + if (!aShape.IsNull()) { + aShape.Move(*(myTrsf.get())); + aResult->setImpl(new TopoDS_Shape(aShape)); + } + } + return aResult; + } + if (myShape.IsNull()) { // shape is not produced yet, create it DocumentPtr aDoc = Model_ResultPart::partDoc(); if (aDoc.get() && aDoc->isOpened()) { const std::string& aBodyGroup = ModelAPI_ResultBody::group(); @@ -120,7 +128,8 @@ std::shared_ptr Model_ResultPart::shape() int aNumSubs = 0; 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()) { + // "object" method filters out disabled and concealed anyway, so don't check + if (aBody.get() && aBody->shape().get()) { TopoDS_Shape aShape = *(aBody->shape()->implPtr()); if (!aShape.IsNull()) { aBuilder.Add(aResultComp, aShape); @@ -133,41 +142,57 @@ std::shared_ptr Model_ResultPart::shape() } } } - if (myShape.IsNull()) - return std::shared_ptr(); - std::shared_ptr aResult(new GeomAPI_Shape); - aResult->setImpl(new TopoDS_Shape(myShape)); + if (!myShape.IsNull()) + aResult->setImpl(new TopoDS_Shape(myShape)); return aResult; } +// Returns true is transformation matrices are equal +static bool IsEqualTrsf(gp_Trsf& theT1, gp_Trsf theT2) { + for(int aRow = 1; aRow < 4; aRow++) { + for(int aCol = 1; aCol < 5; aCol++) { + double aDiff = theT1.Value(aRow, aCol) - theT2.Value(aRow, aCol); + if (Abs(aDiff) > 1.e-9) + return false; + } + } + return true; +} + 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); - } + if (myTrsf.get()) { // if this is moved copy of part => return the name of original shape + ResultPartPtr anOrigResult = + std::dynamic_pointer_cast(data()->attribute(COLOR_ID())->owner()); + // searching in the origin the shape equal to the given but with myTrsf + TopoDS_Shape aSelection = theShape->impl(); + gp_Trsf aSelTrsf = aSelection.Location().Transformation(); + TopoDS_Shape anOrigMain = anOrigResult->shape()->impl(); + if (!aSelection.IsNull() && !anOrigMain.IsNull()) { + TopExp_Explorer anExp(anOrigMain, aSelection.ShapeType()); + for(; anExp.More(); anExp.Next()) { + if (anExp.Current().IsPartner(aSelection)) { + TopoDS_Shape anOrigMoved = anExp.Current().Moved(*(myTrsf.get())); + //if (anOrigMoved.IsSame(aSelection)) { + if (IsEqualTrsf(aSelTrsf, anOrigMoved.Location().Transformation())) { + std::shared_ptr anOrigSel(new GeomAPI_Shape); + anOrigSel->setImpl(new TopoDS_Shape(anExp.Current())); + return anOrigResult->nameInPart(anOrigSel, theIndex); } } } } + // something is not right + return ""; } + + TopoDS_Shape aShape = theShape->impl(); + if (aShape.IsNull()) + return ""; + // 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 @@ -255,12 +280,16 @@ void Model_ResultPart::colorConfigInfo(std::string& theSection, std::string& the void Model_ResultPart::updateShape() { myShape.Nullify(); + myTrsf.reset(); } -void Model_ResultPart::setShape(std::shared_ptr theThis, - const std::shared_ptr& theTransformed) +void Model_ResultPart::setTrsf(std::shared_ptr theThis, + const std::shared_ptr& theTransformation) { - myShape = theTransformed->impl(); + updateShape(); + if (theTransformation.get()) { + myTrsf = std::make_shared(theTransformation->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); diff --git a/src/Model/Model_ResultPart.h b/src/Model/Model_ResultPart.h index 1f4ca4946..a04e0024f 100644 --- a/src/Model/Model_ResultPart.h +++ b/src/Model/Model_ResultPart.h @@ -10,6 +10,7 @@ #include "Model.h" #include #include +#include /**\class Model_ResultPart * \ingroup DataModel @@ -21,6 +22,7 @@ class Model_ResultPart : public ModelAPI_ResultPart { TopoDS_Shape myShape; ///< shape of this part created from bodies (updated only of Part deactivation) + std::shared_ptr myTrsf; ///< if it is just copy of original shape, keep just transformation public: /// Request for initialization of data model of the result: adding all attributes virtual void initAttributes(); @@ -52,8 +54,9 @@ class Model_ResultPart : public ModelAPI_ResultPart 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); + /// Applies the additional transformation of the part + MODEL_EXPORT virtual void setTrsf(std::shared_ptr theThis, + const std::shared_ptr& theTransformation); /// Returns the parameters of color definition in the resources config manager MODEL_EXPORT virtual void colorConfigInfo(std::string& theSection, std::string& theName, @@ -63,9 +66,6 @@ protected: /// makes a result on a temporary feature (an action) Model_ResultPart(); - /// Sets the data manager of an object (document does), here also attributes are initialized - virtual void setData(std::shared_ptr theData); - /// Returns true if document is activated (loaded into the memory) virtual bool isActivated(); diff --git a/src/Model/Model_Update.cpp b/src/Model/Model_Update.cpp index 8dce5e1ca..561882b7c 100644 --- a/src/Model/Model_Update.cpp +++ b/src/Model/Model_Update.cpp @@ -33,7 +33,7 @@ using namespace std; Model_Update MY_UPDATER_INSTANCE; /// the only one instance initialized on load of the library -// #define DEB_UPDATE +//#define DEB_UPDATE Model_Update::Model_Update() { @@ -113,7 +113,6 @@ void Model_Update::processEvent(const std::shared_ptr& theMessag processOperation(false); } else if (theMessage->eventID() == kOpFinishEvent || theMessage->eventID() == kOpAbortEvent || theMessage->eventID() == kOpStartEvent) { - myIsParamUpdated = false; if (!(theMessage->eventID() == kOpStartEvent)) { myIsFinish = true; @@ -142,6 +141,7 @@ void Model_Update::processEvent(const std::shared_ptr& theMessag } // in the end of transaction everything is updated, so clear the old objects (the only one // place where results are cleared) + myIsParamUpdated = false; myJustUpdated.clear(); myWaitForFinish.clear(); } @@ -190,12 +190,12 @@ void Model_Update::processOperation(const bool theTotalUpdate, const bool theFin FeaturePtr aFeatureIter = anObjs->firstFeature(); std::set aProcessedFeatures; // to avoid processing twice for (; aFeatureIter.get(); aFeatureIter = anObjs->nextFeature(aFeatureIter)) { - if (aFeatureIter->groupName() == "Parameter") + if (aFeatureIter->getKind() == "Parameter") updateFeature(aFeatureIter, aProcessedFeatures); } aFeatureIter = anObjs->firstFeature(); for (; aFeatureIter.get(); aFeatureIter = anObjs->nextFeature(aFeatureIter)) { - if (aFeatureIter->groupName() != "Parameter") + if (aFeatureIter->getKind() != "Parameter") updateFeature(aFeatureIter, aProcessedFeatures); } @@ -245,13 +245,13 @@ void Model_Update::updateFeature(FeaturePtr theFeature, std::set& th // two cycles: parameters must be processed first for(int a = 0; a < aCompos->numberOfSubs(); a++) { FeaturePtr aSub = aCompos->subFeature(a); - if (aSub->groupName() == "Parameter") + if (aSub->getKind() == "Parameter") updateFeature(aSub, theProcessed); } // number of subs can be changed in execution: like fillet for(int a = 0; a < aCompos->numberOfSubs(); a++) { FeaturePtr aSub = aCompos->subFeature(a); - if (aSub->groupName() != "Parameter") + if (aSub->getKind() != "Parameter") updateFeature(aSub, theProcessed); } } @@ -320,7 +320,8 @@ void Model_Update::redisplayWithResults(FeaturePtr theFeature, const ModelAPI_Ex std::list >::const_iterator aRIter = aResults.begin(); for (; aRIter != aResults.cend(); aRIter++) { std::shared_ptr aRes = *aRIter; - aRes->data()->execState(theState); + if (!aRes->isDisabled()) // update state only for enabled results (Placement Result Part may make the original Part Result as invalid) + aRes->data()->execState(theState); if (theFeature->data()->updateID() > aRes->data()->updateID()) { aRes->data()->setUpdateID(theFeature->data()->updateID()); } @@ -491,10 +492,21 @@ void Model_Update::updateArguments(FeaturePtr theFeature) { // number of subs can be changed in execution: like fillet for(int a = 0; a < aCompos->numberOfSubs(); a++) { FeaturePtr aSub = aCompos->subFeature(a); - if (myJustUpdated.find(aSub) != myJustUpdated.end() || - (aSub.get() && aSub->data()->updateID() > theFeature->data()->updateID())) { - if (aState == ModelAPI_StateDone) + if (aSub.get() && aState == ModelAPI_StateDone) { + if (myJustUpdated.find(aSub) != myJustUpdated.end() || + (aSub->data()->updateID() > theFeature->data()->updateID())) { + aState = ModelAPI_StateMustBeUpdated; + } + // also check that all results of subs were updated: composite also depends on the results + const std::list >& aResults = aSub->results(); + std::list >::const_iterator aResIter = aResults.begin(); + for(; aResIter != aResults.end(); aResIter++) { + if (aResIter->get() && (*aResIter)->data()->isValid() && !(*aResIter)->isDisabled() && + (myJustUpdated.find(*aResIter) != myJustUpdated.end() || + ((*aResIter)->data()->updateID() > theFeature->data()->updateID()))) { aState = ModelAPI_StateMustBeUpdated; + } + } } } } diff --git a/src/ModelAPI/ModelAPI_ResultPart.h b/src/ModelAPI/ModelAPI_ResultPart.h index 6d23fe38b..46d75e438 100644 --- a/src/ModelAPI/ModelAPI_ResultPart.h +++ b/src/ModelAPI/ModelAPI_ResultPart.h @@ -8,6 +8,7 @@ #define ModelAPI_ResultPart_H_ #include "ModelAPI_Result.h" +#include #include @@ -63,9 +64,9 @@ class ModelAPI_ResultPart : public ModelAPI_Result /// 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; + /// Applies the additional transformation of the part + virtual void setTrsf(std::shared_ptr theThis, + const std::shared_ptr& theTransformation) = 0; /// Returns the shape by the name in the part virtual std::shared_ptr shapeInPart(const std::string& theName) = 0; -- 2.39.2