X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_AttributeSelectionList.cpp;h=9fb4124075eac962de1a6d8b15a7770541194003;hb=88be48ed1ea478b9d9d6ac2d965092418ef4dae6;hp=9fbef11c6911236e985f44ba8a97e08ebae35ddb;hpb=37a97e259237763b1db3cee43ebf829bde336a52;p=modules%2Fshaper.git diff --git a/src/Model/Model_AttributeSelectionList.cpp b/src/Model/Model_AttributeSelectionList.cpp index 9fbef11c6..9fb412407 100644 --- a/src/Model/Model_AttributeSelectionList.cpp +++ b/src/Model/Model_AttributeSelectionList.cpp @@ -1,8 +1,22 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: Model_AttributeSelectionList.cpp -// Created: 22 Oct 2014 -// Author: Mikhail PONIKAROV +// Copyright (C) 2014-2017 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 "Model_AttributeSelectionList.h" #include "Model_AttributeSelection.h" @@ -10,9 +24,13 @@ #include "Model_Events.h" #include "Model_Data.h" +#include +#include + #include #include #include +#include #include #include #include @@ -20,11 +38,11 @@ #include #include #include - -using namespace std; +#include +#include void Model_AttributeSelectionList::append( - const ResultPtr& theContext, const std::shared_ptr& theSubShape, + const ObjectPtr& theContext, const std::shared_ptr& theSubShape, const bool theTemporarily) { // do not use the degenerated edge as a shape, a list is not incremented in this case @@ -35,34 +53,42 @@ void Model_AttributeSelectionList::append( } } + if (myIsCashed && !theTemporarily) { + ResultPtr aResContext = std::dynamic_pointer_cast(theContext); + if (aResContext.get()) + myCash[aResContext].push_back(theSubShape); + } + int aNewTag = mySize->Get() + 1; TDF_Label aNewLab = mySize->Label().FindChild(aNewTag); - std::shared_ptr aNewAttr = + std::shared_ptr aNewAttr = std::shared_ptr(new Model_AttributeSelection(aNewLab)); if (owner()) { aNewAttr->setObject(owner()); + aNewAttr->setParent(this); } aNewAttr->setID(id()); mySize->Set(aNewTag); aNewAttr->setValue(theContext, theSubShape, theTemporarily); if (theTemporarily) myTmpAttr = aNewAttr; - else + else myTmpAttr.reset(); owner()->data()->sendAttributeUpdated(this); } void Model_AttributeSelectionList::append( - const std::string theNamingName, const std::string& theType) + const std::string& theNamingName, const std::string& theType) { int aNewTag = mySize->Get() + 1; TDF_Label aNewLab = mySize->Label().FindChild(aNewTag); - std::shared_ptr aNewAttr = + std::shared_ptr aNewAttr = std::shared_ptr(new Model_AttributeSelection(aNewLab)); if (owner()) { aNewAttr->setObject(owner()); + aNewAttr->setParent(this); } aNewAttr->setID(id()); mySize->Set(aNewTag); @@ -70,13 +96,55 @@ void Model_AttributeSelectionList::append( owner()->data()->sendAttributeUpdated(this); } -void Model_AttributeSelectionList::removeLast() +void Model_AttributeSelectionList::append(const GeomPointPtr& thePoint, const std::string& theType) +{ + int aNewTag = mySize->Get() + 1; + TDF_Label aNewLab = mySize->Label().FindChild(aNewTag); + + std::shared_ptr aNewAttr = + std::shared_ptr(new Model_AttributeSelection(aNewLab)); + if (owner()) { + aNewAttr->setObject(owner()); + aNewAttr->setParent(this); + } + aNewAttr->setID(id()); + mySize->Set(aNewTag); + aNewAttr->selectSubShape(theType, thePoint); + owner()->data()->sendAttributeUpdated(this); +} + +void Model_AttributeSelectionList::append(const std::string& theType, + const std::string& theContextName, const int theIndex) +{ + int aNewTag = mySize->Get() + 1; + TDF_Label aNewLab = mySize->Label().FindChild(aNewTag); + + std::shared_ptr aNewAttr = + std::shared_ptr(new Model_AttributeSelection(aNewLab)); + if (owner()) { + aNewAttr->setObject(owner()); + aNewAttr->setParent(this); + } + aNewAttr->setID(id()); + mySize->Set(aNewTag); + aNewAttr->selectSubShape(theType, theContextName, theIndex); + owner()->data()->sendAttributeUpdated(this); +} + +void Model_AttributeSelectionList::removeTemporaryValues() +{ + if (myTmpAttr.get()) { + myTmpAttr.reset(); + } +} + +void Model_AttributeSelectionList::removeLast() { int anOldSize = mySize->Get(); if (anOldSize != 0) { mySize->Set(anOldSize - 1); TDF_Label aLab = mySize->Label().FindChild(anOldSize); - std::shared_ptr aOldAttr = + std::shared_ptr aOldAttr = std::shared_ptr(new Model_AttributeSelection(aLab)); aOldAttr->setObject(owner()); REMOVE_BACK_REF(aOldAttr->context()); @@ -86,34 +154,45 @@ void Model_AttributeSelectionList::removeLast() } } -// copies named shapes: we need the implementation of this +// copies named shapes: we need the implementation of this static void CopyNS(const Handle(TNaming_NamedShape)& theFrom, const Handle(TDF_Attribute)& theTo) -{ +{ TDF_Label aLab = theTo->Label(); TNaming_Builder B(aLab); - TNaming_Iterator It (theFrom); - for ( ;It.More() ; It.Next()) { - const TopoDS_Shape& OS = It.OldShape(); - const TopoDS_Shape& NS = It.NewShape(); - TNaming_Evolution Status = It.Evolution(); + // TNaming_Iterator iterates in reversed way than it was put in Builder, so, keep it in container + // and iterate from end to begin + NCollection_List aOlds; + NCollection_List aNews; + NCollection_List aStatuses; + + TNaming_Iterator anIt (theFrom); + for ( ;anIt.More() ; anIt.Next()) { + aOlds.Prepend(anIt.OldShape()); + aNews.Prepend(anIt.NewShape()); + aStatuses.Prepend(anIt.Evolution()); + } - switch (Status) { + NCollection_List::Iterator aOldIter(aOlds); + NCollection_List::Iterator aNewIter(aNews); + NCollection_List::Iterator aStatIter(aStatuses); + for(; aOldIter.More(); aOldIter.Next(), aNewIter.Next(), aStatIter.Next()) { + switch (aStatIter.Value()) { case TNaming_PRIMITIVE : - B.Generated(NS); + B.Generated(aNewIter.Value()); break; case TNaming_GENERATED : - B.Generated(OS, NS); + B.Generated(aOldIter.Value(), aNewIter.Value()); break; - case TNaming_MODIFY : - B.Modify(OS, NS); + case TNaming_MODIFY : + B.Modify(aOldIter.Value(), aNewIter.Value()); break; - case TNaming_DELETE : - B.Delete (OS); + case TNaming_DELETE : + B.Delete (aOldIter.Value()); break; case TNaming_SELECTED : - B.Select(NS, OS); + B.Select(aNewIter.Value(), aOldIter.Value()); break; default: break; @@ -134,7 +213,8 @@ static void copyAttrs(TDF_Label theSource, TDF_Label theDestination) { // for named shape copy exact shapes (in NamedShape Paste method the CopyTool is used) Handle(TNaming_NamedShape) aNS = Handle(TNaming_NamedShape)::DownCast(anAttrIter.Value()); if (aNS.IsNull()) { - Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable(); // no relocation, empty map + // no special relocation, empty map, but self-relocation is on: copy references w/o changes + Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable(Standard_True); anAttrIter.Value()->Paste(aTargetAttr, aRelocTable); } else { CopyNS(aNS, aTargetAttr); @@ -163,7 +243,7 @@ void Model_AttributeSelectionList::remove(const std::set& theIndices) } } else { // this is removed, so remove everything from this label TDF_Label aLab = mySize->Label().FindChild(aCurrent + 1); - std::shared_ptr aOldAttr = + std::shared_ptr aOldAttr = std::shared_ptr(new Model_AttributeSelection(aLab)); aOldAttr->setObject(owner()); REMOVE_BACK_REF(aOldAttr->context()); @@ -183,27 +263,31 @@ int Model_AttributeSelectionList::size() return mySize->Get(); } -bool Model_AttributeSelectionList::isInList(const ResultPtr& theContext, +bool Model_AttributeSelectionList::isInList(const ObjectPtr& theContext, const std::shared_ptr& theSubShape, const bool theTemporarily) { - if (!myCash.empty()) { // the cashing is active - std::map > >::iterator aContext = - myCash.find(theContext); - if (aContext != myCash.end()) { - // iterate shapes because "isEqual" method must be called for each shape - std::list >::iterator aShapes = aContext->second.begin(); - for(; aShapes != aContext->second.end(); aShapes++) { - if (!theSubShape.get()) { - if (!aShapes->get()) - return true; - } else { - if (theSubShape->isEqual(*aShapes)) - return true; + ResultPtr aResCont = std::dynamic_pointer_cast(theContext); + if (myIsCashed) { // the cashing is active + if (aResCont.get()) { + std::map > >::iterator aContext = + myCash.find(aResCont); + if (aContext != myCash.end()) { + // iterate shapes because "isSame" method must be called for each shape + std::list >::iterator aShapes = aContext->second.begin(); + for(; aShapes != aContext->second.end(); aShapes++) { + if (!theSubShape.get()) { + if (!aShapes->get() || (*aShapes)->isSame(aContext->first->shape())) + return true; + } else { + // we need to call here isSame instead of isEqual to do not check shapes orientation + if (theSubShape->isSame(*aShapes)) + return true; + } } } + return false; } - return false; } // no-cash method for(int anIndex = size() - 1; anIndex >= 0; anIndex--) { @@ -211,12 +295,13 @@ bool Model_AttributeSelectionList::isInList(const ResultPtr& theContext, if (anAttr.get()) { if (anAttr->context() == theContext) { // contexts are equal, so, check that values are also std::shared_ptr aValue = anAttr->value(); - if (!aValue.get()) { - if (!theSubShape.get()) { // both are null + if (!theSubShape.get()) { + if (!aValue.get() || (aResCont.get() && aValue->isSame(aResCont->shape()))) {// both null return true; } } else { - if (aValue->isEqual(theSubShape)) // shapes are equal + // we need to call here isSame instead of isEqual to do not check shapes orientation + if (theSubShape->isSame(aValue)) // shapes are equal return true; } } @@ -235,7 +320,7 @@ void Model_AttributeSelectionList::setSelectionType(const std::string& theType) mySelectionType->Set(theType.c_str()); } -std::shared_ptr +std::shared_ptr Model_AttributeSelectionList::value(const int theIndex) { if (myTmpAttr.get() && theIndex == size() - 1) { @@ -245,10 +330,12 @@ std::shared_ptr // create a new attribute each time, by demand // supporting of old attributes is too slow (synch each time) and buggy on redo // (if attribute is deleted and created, the abort updates attriute and makes the Attr invalid) - std::shared_ptr aNewAttr = + std::shared_ptr aNewAttr = std::shared_ptr(new Model_AttributeSelection(aLabel)); + aNewAttr->setID(id()); if (owner()) { aNewAttr->setObject(owner()); + aNewAttr->setParent(this); } return aNewAttr; } @@ -261,10 +348,11 @@ void Model_AttributeSelectionList::clear() TDF_ChildIterator aSubIter(mySize->Label()); for(; aSubIter.More(); aSubIter.Next()) { TDF_Label aLab = aSubIter.Value(); - std::shared_ptr aNewAttr = + std::shared_ptr aNewAttr = std::shared_ptr(new Model_AttributeSelection(aLab)); if (owner()) { aNewAttr->setObject(owner()); + aNewAttr->setParent(this); } REMOVE_BACK_REF(aNewAttr->context()); @@ -284,16 +372,26 @@ bool Model_AttributeSelectionList::isInitialized() Model_AttributeSelectionList::Model_AttributeSelectionList(TDF_Label& theLabel) { - myIsInitialized = theLabel.FindAttribute(TDataStd_Integer::GetID(), mySize) == Standard_True; + myLab = theLabel; + reinit(); +} + +void Model_AttributeSelectionList::reinit() +{ + myIsInitialized = myLab.FindAttribute(TDataStd_Integer::GetID(), mySize) == Standard_True; if (!myIsInitialized) { - mySize = TDataStd_Integer::Set(theLabel, 0); - mySelectionType = TDataStd_Comment::Set(theLabel, ""); + mySize = TDataStd_Integer::Set(myLab, 0); + mySelectionType = TDataStd_Comment::Set(myLab, ""); } else { // recollect mySubs - theLabel.FindAttribute(TDataStd_Comment::GetID(), mySelectionType); + myLab.FindAttribute(TDataStd_Comment::GetID(), mySelectionType); } + myIsCashed = false; } -void Model_AttributeSelectionList::cashValues(const bool theEnabled) { + +void Model_AttributeSelectionList::cashValues(const bool theEnabled) +{ + myIsCashed = theEnabled; myCash.clear(); // empty list as indicator that cash is not used if (theEnabled) { for(int anIndex = size() - 1; anIndex >= 0; anIndex--) {