X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_ResultPart.cpp;h=fb3eb3bed05b69273ecb6673fa0f0f6bdf2578dd;hb=81baa77e52cb1ade2bfbe5b21e893cc34b03c323;hp=c01d714f4e4ac5e4048e64b87c47fc31ad71151a;hpb=59d1fb7d2e01dbe3fef0247ea45afaa5ce92b029;p=modules%2Fshaper.git diff --git a/src/Model/Model_ResultPart.cpp b/src/Model/Model_ResultPart.cpp index c01d714f4..fb3eb3bed 100644 --- a/src/Model/Model_ResultPart.cpp +++ b/src/Model/Model_ResultPart.cpp @@ -1,8 +1,21 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: ModelAPI_ResultPart.cpp -// Created: 07 Jul 2014 -// Author: Mikhail PONIKAROV +// Copyright (C) 2014-2020 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// #include #include @@ -14,45 +27,58 @@ #include #include #include +#include #include +#include #include #include +#include + +#include + +#include + +#include #include #include -#include #include #include #include #include -#define baseRef() std::dynamic_pointer_cast(data()->reference(BASE_REF_ID())->value()) +#define baseRef() \ + std::dynamic_pointer_cast(data()->reference(BASE_REF_ID())->value()) void Model_ResultPart::initAttributes() { // append the color attribute. It is empty, the attribute will be filled by a request - data()->addAttribute(DOC_REF(), ModelAPI_AttributeDocRef::typeId()); + AttributeDocRefPtr aDocRef = std::dynamic_pointer_cast( + data()->addAttribute(DOC_REF(), ModelAPI_AttributeDocRef::typeId())); data()->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::typeId()); data()->addAttribute(BASE_REF_ID(), ModelAPI_AttributeReference::typeId()); + data()->addAttribute(DEFLECTION_ID(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(TRANSPARENCY_ID(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(ISO_LINES_ID(), ModelAPI_AttributeIntArray::typeId()); + + if (aDocRef->isInitialized() && // initialized immediately means already exist and will be loaded + !Model_Application::getApplication()->hasDocument(aDocRef->docId())) + Model_Application::getApplication()->setLoadByDemand(data()->name(), aDocRef->docId()); } std::shared_ptr Model_ResultPart::partDoc() { - if (myTrsf.get()) { + if (myTrsf.get() && baseRef().get()) { // the second condition is due to #2035 return baseRef()->partDoc(); } + if (!data()->isValid()) + return DocumentPtr(); DocumentPtr aRes = data()->document(DOC_REF())->value(); - if (!aRes.get() && myIsInLoad) { // trying to get this document from the session - aRes = document()->subDocument(data()->name()); - } return aRes; } Model_ResultPart::Model_ResultPart() { - myIsDisabled = true; // by default it is not initialized and false to be after created - myIsInLoad = false; - setIsConcealed(false); } void Model_ResultPart::activate() @@ -63,40 +89,66 @@ void Model_ResultPart::activate() } std::shared_ptr aDocRef = data()->document(DOC_REF()); - + + // activation may cause changes in current features in document, so it must be in transaction + bool isNewTransaction = false; + SessionPtr aMgr = ModelAPI_Session::get(); + if (!aMgr->isOperation()) { + // open transaction even document is not created to set current docs in setActiveDocument + std::string aMsg = "Activation " + Locale::Convert::toString(data()->name()); + aMgr->startOperation(aMsg); + isNewTransaction = true; + } if (!aDocRef->value().get()) { // create (or open) a document if it is not yet created - myIsInLoad = true; - std::shared_ptr aDoc = document()->subDocument(data()->name()); - myIsInLoad = false; - if (aDoc) { + Handle(Model_Application) anApp = Model_Application::getApplication(); + if (anApp->isLoadByDemand(data()->name(), aDocRef->docId())) { + anApp->loadDocument(data()->name(), aDocRef->docId()); // if it is just new part, load fails + } else { + anApp->createDocument(aDocRef->docId()); + } + std::shared_ptr aDoc = aDocRef->value(); + if (aDoc.get()) { + aDoc->synchronizeTransactions(); aDocRef->setValue(aDoc); } } if (aDocRef->value().get()) { - SessionPtr aMgr = ModelAPI_Session::get(); - bool isNewTransaction = !aMgr->isOperation(); - // activation may cause changes in current features in document, so it must be in transaction - if (isNewTransaction) { - aMgr->startOperation("Activation"); - } ModelAPI_Session::get()->setActiveDocument(aDocRef->value()); - if (isNewTransaction) { - aMgr->finishOperation(); + } + if (isNewTransaction) { + aMgr->finishOperation(); + } +} + + +void Model_ResultPart::loadPart() +{ + std::shared_ptr aDocRef = data()->document(DOC_REF()); + if (!aDocRef->value().get()) { // create (or open) a document if it is not yet created + Handle(Model_Application) anApp = Model_Application::getApplication(); + if (anApp->isLoadByDemand(data()->name(), aDocRef->docId())) { + anApp->loadDocument(data()->name(), aDocRef->docId()); // if it is just new part, load fails + } + else { + anApp->createDocument(aDocRef->docId()); } } } + std::shared_ptr Model_ResultPart::original() { - if (myTrsf.get()) { + if (myTrsf.get() && baseRef().get()) { // the second condition is due to #2035 return baseRef()->original(); } return std::dynamic_pointer_cast(data()->owner()); } -bool Model_ResultPart::isActivated() +bool Model_ResultPart::isActivated() { if (myTrsf.get()) { + if (!baseRef().get()) // may be on close + return false; return baseRef()->isActivated(); } @@ -111,15 +163,24 @@ bool Model_ResultPart::setDisabled(std::shared_ptr theThis, 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)); + // make the current feature the last in any case: to update shapes before deactivation too + int aSize = aDoc->size(ModelAPI_Feature::group()); + FeaturePtr aLastFeature; + if (aSize) + aLastFeature = std::dynamic_pointer_cast(aDoc->object( + ModelAPI_Feature::group(), aSize - 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); + // in order to update OB sub-elements of document before the document closing + Events_Loop* aLoop = Events_Loop::loop(); + aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); + aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); + aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED)); } } } @@ -128,47 +189,76 @@ bool Model_ResultPart::setDisabled(std::shared_ptr theThis, return false; } -std::shared_ptr Model_ResultPart::shape() +static GeomShapePtr transformShape(const GeomShapePtr theShape, const gp_Trsf& theTrsf) { - std::shared_ptr aResult(new GeomAPI_Shape); - if (myTrsf.get()) { // get shape of the base result and apply the transformation - ResultPtr anOrigResult = baseRef(); - 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)); - } + GeomShapePtr aResult(new GeomAPI_Shape); + if (theTrsf.ScaleFactor() > 0) { + // just update the location of the shape in case of affine transformation + TopoDS_Shape aShape = theShape->impl(); + if (!aShape.IsNull()) { + aShape.Move(theTrsf); + aResult->setImpl(new TopoDS_Shape(aShape)); } - return aResult; } + else { + // all other transformations will modify the shape + GeomTrsfPtr aTrsf = std::make_shared(new gp_Trsf(theTrsf)); + GeomAlgoAPI_Transform aTransform(theShape, aTrsf); + aResult = aTransform.shape(); + } + return aResult; +} + +std::shared_ptr Model_ResultPart::shape() +{ + std::shared_ptr aResult(new GeomAPI_Shape); 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(); - TopoDS_Compound aResultComp; - BRep_Builder aBuilder; - aBuilder.MakeCompound(aResultComp); - int aNumSubs = 0; - for(int a = aDoc->size(aBodyGroup) - 1; a >= 0; a--) { - ResultPtr aBody = std::dynamic_pointer_cast(aDoc->object(aBodyGroup, a)); - // "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); - aNumSubs++; + SessionPtr aMgr = ModelAPI_Session::get(); + bool aToSendUpdate = aMgr->isOperation(); // inside of operation may send an update event + if (myTrsf.get()) { // get shape of the base result and apply the transformation + ResultPtr anOrigResult = baseRef(); + std::shared_ptr anOrigShape = anOrigResult->shape(); + if (anOrigShape.get()) { + aResult = transformShape(anOrigShape, *myTrsf); + myShape = aResult->impl(); + } + if (!myShape.IsNull() && aToSendUpdate) { + static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); + ModelAPI_EventCreator::get()->sendUpdated(data()->owner(), anEvent); + } + return aResult; + } else { + DocumentPtr aDoc = Model_ResultPart::partDoc(); + if (aDoc.get() && aDoc->isOpened()) { + const std::string& aBodyGroup = ModelAPI_ResultBody::group(); + TopoDS_Compound aResultComp; + BRep_Builder aBuilder; + aBuilder.MakeCompound(aResultComp); + int aNumSubs = 0; + for(int a = aDoc->size(aBodyGroup) - 1; a >= 0; a--) { + ResultPtr aBody = std::dynamic_pointer_cast(aDoc->object(aBodyGroup, a)); + // "object" method filters out disabled and concealed anyway, so don't check + if (aBody.get() && aBody->data()->isValid() && aBody->shape().get()) { + TopoDS_Shape aShape = *(aBody->shape()->implPtr()); + if (!aShape.IsNull()) { + aBuilder.Add(aResultComp, aShape); + aNumSubs++; + } } } + if (aNumSubs) { + myShape = aResultComp; + } } - if (aNumSubs) { - myShape = aResultComp; - } + } + if (!myShape.IsNull() && aToSendUpdate) { + static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); + ModelAPI_EventCreator::get()->sendUpdated(data()->owner(), anEvent); } } - if (!myShape.IsNull()) + if (!myShape.IsNull()) { aResult->setImpl(new TopoDS_Shape(myShape)); + } return aResult; } @@ -184,7 +274,7 @@ static bool IsEqualTrsf(gp_Trsf& theT1, gp_Trsf theT2) { return true; } -std::string Model_ResultPart::nameInPart(const std::shared_ptr& theShape, +std::wstring Model_ResultPart::nameInPart(const std::shared_ptr& theShape, int& theIndex) { theIndex = 0; // not initialized @@ -210,65 +300,43 @@ std::string Model_ResultPart::nameInPart(const std::shared_ptr& t } } // something is not right - return ""; + return L""; } TopoDS_Shape aShape = theShape->impl(); if (aShape.IsNull()) - return ""; + return L""; // 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 - return ""; - TDF_Label anAccessLabel = aDoc->generalLabel(); - - std::string aName; - // check if the subShape is already in DF - Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(aShape, anAccessLabel); - Handle(TDataStd_Name) anAttr; - if(!aNS.IsNull() && !aNS->IsEmpty()) { // in the document - if(aNS->Label().FindAttribute(TDataStd_Name::GetID(), anAttr)) { - aName = TCollection_AsciiString(anAttr->Get()).ToCString(); - if(!aName.empty()) { - const TDF_Label& aLabel = aDoc->findNamingName(aName); - - static const std::string aPostFix("_"); - TNaming_Iterator anItL(aNS); - for(int i = 1; anItL.More(); anItL.Next(), i++) { - if(anItL.NewShape() == aShape) { - aName += aPostFix; - aName += TCollection_AsciiString (i).ToCString(); - break; - } - } - } - } - } - 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; - } + return L""; + MAYBE_UNUSED TDF_Label anAccessLabel = aDoc->generalLabel(); + // make the selection attribute anyway: + // otherwise just by name it is not stable to search the result + std::wstring aName; + // 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.IsSame(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(); - } + } + 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; } @@ -280,18 +348,89 @@ bool Model_ResultPart::updateInPart(const int theIndex) AttributeSelectionListPtr aSelAttr = aDoc->selectionInPartFeature(); AttributeSelectionPtr aThisAttr = aSelAttr->value(theIndex - 1); if (aThisAttr.get()) { - return aThisAttr->update(); + if (aThisAttr->update()) { + bool aRemove = false; + aThisAttr->updateInHistory(aRemove); + return true; // it was updated + } } } return false; // something is wrong } -std::shared_ptr Model_ResultPart::shapeInPart(const std::string& theName) +gp_Trsf Model_ResultPart::sumTrsf() { + gp_Trsf aResult; + if (myTrsf) { + aResult = *myTrsf; + aResult = aResult * baseRef()->sumTrsf(); + } + return aResult; +} + +bool Model_ResultPart::combineGeometrical(const int theIndex, std::wstring& theNewName) { - /// TODO: not implemented yet - return std::shared_ptr(); + 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()) { + aThisAttr->combineGeometrical(); + if (aThisAttr->value().get()) { + int anIndex; + theNewName = nameInPart(aThisAttr->value(), anIndex); + return true; + } + } + } + return false; // something is wrong } +std::shared_ptr Model_ResultPart::shapeInPart( + const std::wstring& theName, const std::string& theType, int& theIndex) +{ + theIndex = 0; // not found yet + std::shared_ptr aResult; + std::shared_ptr aDoc = std::dynamic_pointer_cast(partDoc()); + if (!aDoc.get()) // the part document is not presented for the moment + return aResult; + + AttributeSelectionListPtr aSelAttr = aDoc->selectionInPartFeature(); + // check this selection is already there: reuse it + int aSize = aSelAttr->size(); + for(int a = 0; a < aSize; a++) { + if (aSelAttr->value(a)->namingName() == theName) { + theIndex = a; + return aSelAttr->value(a)->value(); + } + } + + aSelAttr->append(theName, theType); + theIndex = aSelAttr->size(); + aResult = aSelAttr->value(theIndex - 1)->value(); + if (myTrsf.get() && aResult.get() && !aResult->isNull()) { + gp_Trsf aSumTrsf = sumTrsf(); + TopoDS_Shape anOrigMoved = aResult->impl().Moved(aSumTrsf); + aResult->setImpl(new TopoDS_Shape(anOrigMoved)); + } + return aResult; +} + +std::shared_ptr Model_ResultPart::selectionValue(const int theIndex) +{ + std::shared_ptr aResult; + std::shared_ptr aDoc = std::dynamic_pointer_cast(partDoc()); + if (!aDoc.get()) // the part document is not presented for the moment + return aResult; + + AttributeSelectionListPtr aSelAttr = aDoc->selectionInPartFeature(); + aResult = aSelAttr->value(theIndex - 1)->value(); + if (myTrsf.get() && aResult.get() && !aResult->isNull()) { + gp_Trsf aSumTrsf = sumTrsf(); + TopoDS_Shape anOrigMoved = aResult->impl().Moved(aSumTrsf); + aResult->setImpl(new TopoDS_Shape(anOrigMoved)); + } + return aResult; +} void Model_ResultPart::colorConfigInfo(std::string& theSection, std::string& theName, std::string& theDefault) @@ -307,7 +446,7 @@ void Model_ResultPart::updateShape() myTrsf.reset(); } -void Model_ResultPart::setTrsf(std::shared_ptr theThis, +void Model_ResultPart::setTrsf(std::shared_ptr theThis, const std::shared_ptr& theTransformation) { updateShape(); @@ -319,3 +458,10 @@ void Model_ResultPart::setTrsf(std::shared_ptr theThis, static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); ModelAPI_EventCreator::get()->sendUpdated(theThis, EVENT_DISP); // flush is in preview-update } + +std::shared_ptr Model_ResultPart::summaryTrsf() +{ + GeomTrsfPtr aResult(new GeomAPI_Trsf); + aResult->setImpl(new gp_Trsf(sumTrsf())); + return aResult; +}