X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_BodyBuilder.cpp;h=6d7fe12db8016ad869beb2216720a694ffcfac4a;hb=86bc0800fb01a81cebe88ec6c0be1854e612207e;hp=38d349bd7386b89dd822b2ab45ff9d03d22b4c22;hpb=5f2b8e1caecd7b637e35ad001344539bd0c09906;p=modules%2Fshaper.git diff --git a/src/Model/Model_BodyBuilder.cpp b/src/Model/Model_BodyBuilder.cpp index 38d349bd7..6d7fe12db 100755 --- a/src/Model/Model_BodyBuilder.cpp +++ b/src/Model/Model_BodyBuilder.cpp @@ -1,8 +1,22 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: Model_ResultBody.cpp -// Created: 08 Jul 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 @@ -17,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -32,84 +47,89 @@ #include #include #include +#include #include +#include #include +#include #include // DEB //#include //#include //#define DEB_IMPORT 1 -Model_BodyBuilder::Model_BodyBuilder(ModelAPI_Object* theOwner) -: ModelAPI_BodyBuilder(theOwner) -{ +static const int INVALID_TAG = -1; +static const int GENERATED_VERTICES_TAG = 1; +static const int GENERATED_EDGES_TAG = 2; +static const int GENERATED_FACES_TAG = 3; +static const int MODIFIED_VERTICES_TAG = 4; +static const int MODIFIED_EDGES_TAG = 5; +static const int MODIFIED_FACES_TAG = 6; +static const int DELETED_TAG = 7; +static const int PRIMITIVES_START_TAG = 11; + +static int getGenerationTag(const TopoDS_Shape& theShape) { + TopAbs_ShapeEnum aShapeType = theShape.ShapeType(); + switch (aShapeType) { + case TopAbs_VERTEX: return GENERATED_VERTICES_TAG; + case TopAbs_EDGE: return GENERATED_EDGES_TAG; + case TopAbs_FACE: return GENERATED_FACES_TAG; + } + + return INVALID_TAG; } -// Converts evolution of naming shape to selection evelution and back to avoid -// naming support on the disabled results. Deeply in the labels tree, recursively. -static void evolutionToSelectionRec(TDF_Label theLab, const bool theFlag) { - std::list > aShapePairs; // to store old and new shapes - Handle(TNaming_NamedShape) aName; - int anEvolution = -1; - if (theLab.FindAttribute(TNaming_NamedShape::GetID(), aName)) { - TNaming_Evolution aNSEvol = aName->Evolution(); - if ((aNSEvol == TNaming_SELECTED && theFlag) || - (aNSEvol != TNaming_SELECTED && !theFlag)) { // nothing to do, it is already correct - return; - } - anEvolution = (int)(aNSEvol); - if (!theFlag) { - Handle(TDataStd_Integer) anAttrEvol; - if (theLab.FindAttribute(TDataStd_Integer::GetID(), anAttrEvol)) { - anEvolution = anAttrEvol->Get(); - } - } else { - TDataStd_Integer::Set(theLab, anEvolution); - } - - for(TNaming_Iterator anIter(aName); anIter.More(); anIter.Next()) { - // iterator goes in reversed order relatively to the Builder, to, make the list reversed - aShapePairs.push_front(std::pair - (anIter.OldShape(), anIter.NewShape())); - } - - // create new - TNaming_Builder aBuilder(theLab); - TNaming_Evolution anEvol = (TNaming_Evolution)(anEvolution); - std::list >::iterator aPairsIter = aShapePairs.begin(); - for(; aPairsIter != aShapePairs.end(); aPairsIter++) { - if (theFlag) { // disabled => make selection - aBuilder.Select(aPairsIter->second, aPairsIter->first); - } else if (anEvol == TNaming_GENERATED) { - aBuilder.Generated(aPairsIter->first, aPairsIter->second); - } else if (anEvol == TNaming_MODIFY) { - aBuilder.Modify(aPairsIter->first, aPairsIter->second); - } else if (anEvol == TNaming_DELETE) { - aBuilder.Delete(aPairsIter->first); - } else if (anEvol == TNaming_PRIMITIVE) { - aBuilder.Generated(aPairsIter->second); - } else if (anEvol == TNaming_SELECTED) { - aBuilder.Select(aPairsIter->second, aPairsIter->first); - } - } +static int getModificationTag(const TopoDS_Shape& theShape) { + TopAbs_ShapeEnum aShapeType = theShape.ShapeType(); + switch (aShapeType) { + case TopAbs_VERTEX: return MODIFIED_VERTICES_TAG; + case TopAbs_EDGE: return MODIFIED_EDGES_TAG; + case TopAbs_FACE: return MODIFIED_FACES_TAG; } - // recursive call for all sub-labels - TDF_ChildIterator anIter(theLab, Standard_False); - for(; anIter.More(); anIter.Next()) { - evolutionToSelectionRec(anIter.Value(), theFlag); + + return INVALID_TAG; +} + +static TopAbs_ShapeEnum convertShapeType(const GeomAPI_Shape::ShapeType theType) { + switch (theType) { + case GeomAPI_Shape::VERTEX: return TopAbs_VERTEX; + case GeomAPI_Shape::EDGE: return TopAbs_EDGE; + case GeomAPI_Shape::WIRE: return TopAbs_WIRE; + case GeomAPI_Shape::FACE: return TopAbs_FACE; + case GeomAPI_Shape::SHELL: return TopAbs_SHELL; + case GeomAPI_Shape::SOLID: return TopAbs_SOLID; + case GeomAPI_Shape::COMPSOLID: return TopAbs_COMPSOLID; + case GeomAPI_Shape::COMPOUND: return TopAbs_COMPOUND; + case GeomAPI_Shape::SHAPE: return TopAbs_SHAPE; } + return TopAbs_SHAPE; } -void Model_BodyBuilder::evolutionToSelection(const bool theFlag) +static bool isAlreadyStored(const TNaming_Builder* theBuilder, + const TopoDS_Shape& theOldShape, + const TopoDS_Shape& theNewShape) { - std::shared_ptr aData = std::dynamic_pointer_cast(data()); - if (!aData) // unknown case - return; - TDF_Label& aShapeLab = aData->shapeLab(); - evolutionToSelectionRec(aShapeLab, theFlag); + for (TNaming_Iterator aNamingIt(theBuilder->NamedShape()); + aNamingIt.More(); + aNamingIt.Next()) + { + if (aNamingIt.NewShape().IsSame(theNewShape) + && aNamingIt.OldShape().IsSame(theOldShape)) + { + return true; + } + } + + return false; } -void Model_BodyBuilder::store(const std::shared_ptr& theShape, +Model_BodyBuilder::Model_BodyBuilder(ModelAPI_Object* theOwner) +: ModelAPI_BodyBuilder(theOwner), + myFreePrimitiveTag(PRIMITIVES_START_TAG) +{ +} + +void Model_BodyBuilder::store(const GeomShapePtr& theShape, const bool theIsStoreSameShapes) { std::shared_ptr aData = std::dynamic_pointer_cast(data()); @@ -153,8 +173,8 @@ void Model_BodyBuilder::store(const std::shared_ptr& theShape, } } -void Model_BodyBuilder::storeGenerated(const std::shared_ptr& theFromShape, - const std::shared_ptr& theToShape) +void Model_BodyBuilder::storeGenerated(const GeomShapePtr& theFromShape, + const GeomShapePtr& theToShape) { std::shared_ptr aData = std::dynamic_pointer_cast(data()); if (aData) { @@ -187,16 +207,29 @@ void Model_BodyBuilder::storeGenerated(const std::shared_ptr& the } } -void Model_BodyBuilder::storeModified(const std::shared_ptr& theOldShape, - const std::shared_ptr& theNewShape, const int theDecomposeSolidsTag) +TNaming_Builder* Model_BodyBuilder::builder(const int theTag) +{ + std::map::iterator aFind = myBuilders.find(theTag); + if (aFind == myBuilders.end()) { + std::shared_ptr aData = std::dynamic_pointer_cast(data()); + myBuilders[theTag] = new TNaming_Builder( + theTag == 0 ? aData->shapeLab() : aData->shapeLab().FindChild(theTag)); + aFind = myBuilders.find(theTag); + } + return aFind->second; +} + +void Model_BodyBuilder::storeModified(const GeomShapePtr& theOldShape, + const GeomShapePtr& theNewShape, + const bool theIsCleanStored) { std::shared_ptr aData = std::dynamic_pointer_cast(data()); if (aData) { TDF_Label& aShapeLab = aData->shapeLab(); // clean builders - clean(); + if (theIsCleanStored) clean(); // store the new shape as primitive - TNaming_Builder aBuilder(aShapeLab); + TNaming_Builder* aBuilder = builder(0); if (!theOldShape || !theNewShape) return; // bad shape TopoDS_Shape aShapeOld = theOldShape->impl(); @@ -205,22 +238,22 @@ void Model_BodyBuilder::storeModified(const std::shared_ptr& theO TopoDS_Shape aShapeNew = theNewShape->impl(); if (aShapeNew.IsNull()) return; // null shape inside - aBuilder.Modify(aShapeOld, aShapeNew); - if(!aBuilder.NamedShape()->IsEmpty()) { + aBuilder->Modify(aShapeOld, aShapeNew); + if(!aBuilder->NamedShape()->IsEmpty()) { Handle(TDataStd_Name) anAttr; - if(aBuilder.NamedShape()->Label().FindAttribute(TDataStd_Name::GetID(),anAttr)) { + if(aBuilder->NamedShape()->Label().FindAttribute(TDataStd_Name::GetID(),anAttr)) { std::string aName (TCollection_AsciiString(anAttr->Get()).ToCString()); if(!aName.empty()) { std::shared_ptr aDoc = std::dynamic_pointer_cast(document()); - aDoc->addNamingName(aBuilder.NamedShape()->Label(), aName); + aDoc->addNamingName(aBuilder->NamedShape()->Label(), aName); } } } } } -void Model_BodyBuilder::storeWithoutNaming(const std::shared_ptr& theShape) +void Model_BodyBuilder::storeWithoutNaming(const GeomShapePtr& theShape) { std::shared_ptr aData = std::dynamic_pointer_cast(data()); if (aData) { @@ -237,10 +270,22 @@ void Model_BodyBuilder::storeWithoutNaming(const std::shared_ptr void Model_BodyBuilder::clean() { - std::vector::iterator aBuilder = myBuilders.begin(); - for(; aBuilder != myBuilders.end(); aBuilder++) - delete *aBuilder; + TDF_Label aLab = std::dynamic_pointer_cast(data())->shapeLab(); + if (aLab.IsNull()) + return; + std::map::iterator aBuilder = myBuilders.begin(); + for(; aBuilder != myBuilders.end(); aBuilder++) { + delete aBuilder->second; + // clear also shapes on cleaned sub-labels (#2241) + Handle(TNaming_NamedShape) aNS; + if (aLab.FindChild(aBuilder->first).FindAttribute(TNaming_NamedShape::GetID(), aNS)) { + aNS->Clear(); + } + } myBuilders.clear(); + // remove the old reference (if any) + aLab.ForgetAttribute(TDF_Reference::GetID()); + myFreePrimitiveTag = PRIMITIVES_START_TAG; } Model_BodyBuilder::~Model_BodyBuilder() @@ -248,202 +293,305 @@ Model_BodyBuilder::~Model_BodyBuilder() clean(); } -TNaming_Builder* Model_BodyBuilder::builder(const int theTag) -{ - if (myBuilders.size() <= (unsigned int)theTag) { - myBuilders.insert(myBuilders.end(), theTag - myBuilders.size() + 1, NULL); - } - if (!myBuilders[theTag]) { - std::shared_ptr aData = std::dynamic_pointer_cast(data()); - myBuilders[theTag] = new TNaming_Builder(aData->shapeLab().FindChild(theTag)); - //TCollection_AsciiString entry;// - //TDF_Tool::Entry(aData->shapeLab().FindChild(theTag), entry); - //cout << "Label = " < aDoc = std::dynamic_pointer_cast(document()); - //aDoc->addNamingName(builder(theTag)->NamedShape()->Label(), theName); - TDataStd_Name::Set(builder(theTag)->NamedShape()->Label(), theName.c_str()); + std::string aName = theName; + std::string aPrefix = ""; + switch (theTag) { + case GENERATED_VERTICES_TAG: aPrefix = aName.empty() ? "Generated_Vertex" : "GV:"; break; + case GENERATED_EDGES_TAG: aPrefix = aName.empty() ? "Generated_Edge" : "GE:"; break; + case GENERATED_FACES_TAG: aPrefix = aName.empty() ? "Generated_Face" : "GF:"; break; + case MODIFIED_VERTICES_TAG: aPrefix = aName.empty() ? "Modified_Vertex" : "MV:"; break; + case MODIFIED_EDGES_TAG: aPrefix = aName.empty() ? "Modified_Edge" : "ME:"; break; + case MODIFIED_FACES_TAG: aPrefix = aName.empty() ? "Modified_Face" : "MF:"; break; + } + aName.insert(0, aPrefix); + + TDataStd_Name::Set(builder(theTag)->NamedShape()->Label(), aName.c_str()); } -void Model_BodyBuilder::generated( - const std::shared_ptr& theNewShape, const std::string& theName, const int theTag) +void Model_BodyBuilder::generated(const GeomShapePtr& theNewShape, + const std::string& theName) { TopoDS_Shape aShape = theNewShape->impl(); - builder(theTag)->Generated(aShape); - if(!theName.empty()) - buildName(theTag, theName); + builder(myFreePrimitiveTag)->Generated(aShape); + if (!theName.empty()) { + buildName(myFreePrimitiveTag, theName); + } + + ++myFreePrimitiveTag; } -void Model_BodyBuilder::generated(const std::shared_ptr& theOldShape, - const std::shared_ptr& theNewShape, const std::string& theName, const int theTag) +void Model_BodyBuilder::generated(const GeomShapePtr& theOldShape, + const GeomShapePtr& theNewShape, + const std::string& theName) { TopoDS_Shape anOldShape = theOldShape->impl(); TopoDS_Shape aNewShape = theNewShape->impl(); - builder(theTag)->Generated(anOldShape, aNewShape); - if(!theName.empty()) - buildName(theTag, theName); - TopAbs_ShapeEnum aGenShapeType = aNewShape.ShapeType(); - if(aGenShapeType == TopAbs_WIRE || aGenShapeType == TopAbs_SHELL) { - TopAbs_ShapeEnum anExplodeShapeType = aGenShapeType == TopAbs_WIRE ? TopAbs_EDGE : TopAbs_FACE; - const TDF_Label aLabel = builder(theTag)->NamedShape()->Label(); - int aTag = 1; - std::shared_ptr aDoc = std::dynamic_pointer_cast(document()); - for(TopExp_Explorer anExp(aNewShape, anExplodeShapeType); anExp.More(); anExp.Next()) { - TDF_Label aChildLabel = aLabel.FindChild(aTag); - TNaming_Builder aBuilder(aChildLabel); - aBuilder.Generated(anOldShape, anExp.Current()); - TCollection_AsciiString aChildName = TCollection_AsciiString((theName + "_").c_str()) + aTag; - //aDoc->addNamingName(aChildLabel, aChildName.ToCString()); - TDataStd_Name::Set(aChildLabel, aChildName.ToCString()); - aTag++; + TopAbs_ShapeEnum aNewShapeType = aNewShape.ShapeType(); + int aTag; + if (aNewShapeType == TopAbs_WIRE || aNewShapeType == TopAbs_SHELL) { + // TODO: This is a workaround. New shape should be only vertex, edge or face. + TopAbs_ShapeEnum aShapeTypeToExplore = aNewShapeType == TopAbs_WIRE ? TopAbs_EDGE : TopAbs_FACE; + aTag = TopAbs_WIRE ? GENERATED_EDGES_TAG : GENERATED_FACES_TAG; + for (TopExp_Explorer anExp(aNewShape, aShapeTypeToExplore); anExp.More(); anExp.Next()) { + builder(aTag)->Generated(anOldShape, anExp.Current()); } + buildName(aTag, theName); + } else { + aTag = getGenerationTag(aNewShape); + if (aTag == INVALID_TAG) return; + builder(aTag)->Generated(anOldShape, aNewShape); + buildName(aTag, theName); } } - -void Model_BodyBuilder::modified(const std::shared_ptr& theOldShape, - const std::shared_ptr& theNewShape, const std::string& theName, const int theTag) +void Model_BodyBuilder::modified(const GeomShapePtr& theOldShape, + const GeomShapePtr& theNewShape, + const std::string& theName) { TopoDS_Shape anOldShape = theOldShape->impl(); TopoDS_Shape aNewShape = theNewShape->impl(); - builder(theTag)->Modify(anOldShape, aNewShape); - if(!theName.empty()) - buildName(theTag, theName); + int aTag = getModificationTag(aNewShape); + if (aTag == INVALID_TAG) return; + builder(aTag)->Modify(anOldShape, aNewShape); + buildName(aTag, theName); } -void Model_BodyBuilder::deleted(const std::shared_ptr& theOldShape, - const int theTag) +void Model_BodyBuilder::deleted(const GeomShapePtr& theOldShape) { TopoDS_Shape aShape = theOldShape->impl(); - builder(theTag)->Delete(aShape); + builder(DELETED_TAG)->Delete(aShape); } -void Model_BodyBuilder::loadDeletedShapes (GeomAlgoAPI_MakeShape* theMS, - std::shared_ptr theShapeIn, - const int theKindOfShape, - const int theTag) +void Model_BodyBuilder::loadDeletedShapes(const GeomMakeShapePtr& theAlgo, + const GeomShapePtr& theOldShape, + const GeomAPI_Shape::ShapeType theShapeTypeToExplore, + const GeomShapePtr& theShapesToExclude) { - TopoDS_Shape aShapeIn = theShapeIn->impl(); - TopTools_MapOfShape aView; - TopExp_Explorer ShapeExplorer (aShapeIn, (TopAbs_ShapeEnum)theKindOfShape); - for (; ShapeExplorer.More(); ShapeExplorer.Next ()) { - const TopoDS_Shape& aRoot = ShapeExplorer.Current (); - if (!aView.Add(aRoot)) continue; - std::shared_ptr aRShape(new GeomAPI_Shape()); - aRShape->setImpl((new TopoDS_Shape(aRoot))); - if (theMS->isDeleted (aRShape)) { - builder(theTag)->Delete(aRoot); + TopTools_MapOfShape anAlreadyProcessedShapes; + GeomShapePtr aResultShape = shape(); + for (GeomAPI_ShapeExplorer anExp(theOldShape, theShapeTypeToExplore); + anExp.more(); + anExp.next()) + { + GeomShapePtr anOldSubShape = anExp.current(); + const TopoDS_Shape& anOldSubShape_ = anOldSubShape->impl(); + if (!anAlreadyProcessedShapes.Add(anOldSubShape_) + || !theAlgo->isDeleted(anOldSubShape) + || aResultShape->isSubShape(anOldSubShape, false) + || (theShapesToExclude.get() && theShapesToExclude->isSubShape(anOldSubShape, false))) + { + continue; + } + + ListOfShape aNewShapes; + if (BRepTools_History::IsSupportedType(anOldSubShape_)) { // to avoid crash in #2572 + theAlgo->modified(anOldSubShape, aNewShapes); + } + + if (aNewShapes.size() == 0 + || (aNewShapes.size() == 1 && aNewShapes.front()->isSame(anOldSubShape))) { + builder(DELETED_TAG)->Delete(anOldSubShape_); } } } -void Model_BodyBuilder::loadAndOrientModifiedShapes ( - GeomAlgoAPI_MakeShape* theMS, - std::shared_ptr theShapeIn, - const int theKindOfShape, - const int theTag, - const std::string& theName, - GeomAPI_DataMapOfShapeShape& theSubShapes, - const bool theIsStoreSeparate) +static void removeBadShapes(ListOfShape& theShapes) +{ + ListOfShape::iterator anIt = theShapes.begin(); + while (anIt != theShapes.end()) { + TopoDS_Shape aNewShape = (*anIt)->impl(); + bool aSkip = aNewShape.IsNull() + || (aNewShape.ShapeType() == TopAbs_EDGE && BRep_Tool::Degenerated(TopoDS::Edge(aNewShape))); + if (aSkip) { + ListOfShape::iterator aRemoveIt = anIt++; + theShapes.erase(aRemoveIt); + } else { + ++anIt; + } + } +} + +// Keep only the shapes with minimal shape type +static void keepTopLevelShapes(ListOfShape& theShapes, + const TopoDS_Shape& theRoot, + const GeomShapePtr& theResultShape = GeomShapePtr()) +{ + GeomAPI_Shape::ShapeType aKeepShapeType = GeomAPI_Shape::SHAPE; + ListOfShape::iterator anIt = theShapes.begin(); + while (anIt != theShapes.end()) { + TopoDS_Shape aNewShape = (*anIt)->impl(); + bool aSkip = aNewShape.IsNull() || + (aNewShape.ShapeType() == TopAbs_EDGE && BRep_Tool::Degenerated(TopoDS::Edge(aNewShape))); + if (aSkip || theRoot.IsSame(aNewShape) || (theResultShape && + (!theResultShape->isSubShape(*anIt, false) || theResultShape->isSame(*anIt)))) { + ListOfShape::iterator aRemoveIt = anIt++; + theShapes.erase(aRemoveIt); + } else { + GeomAPI_Shape::ShapeType aType = (*anIt)->shapeType(); + if (aType < aKeepShapeType) { + // found a shape with lesser shape type => remove all previous shapes + aKeepShapeType = aType; + theShapes.erase(theShapes.begin(), anIt); + ++anIt; + } else if (aType > aKeepShapeType) { + // shapes with greater shape type should be removed from the list + ListOfShape::iterator aRemoveIt = anIt++; + theShapes.erase(aRemoveIt); + } else + ++anIt; + } + } +} + +// returns an ancestor shape-type thaty used for naming-definition of the sub-type +TopAbs_ShapeEnum typeOfAncestor(const TopAbs_ShapeEnum theSubType) { + if (theSubType == TopAbs_VERTEX) + return TopAbs_EDGE; + if (theSubType == TopAbs_EDGE) + return TopAbs_FACE; + return TopAbs_VERTEX; // bad case +} + +void Model_BodyBuilder::loadModifiedShapes(const GeomMakeShapePtr& theAlgo, + const GeomShapePtr& theOldShape, + const GeomAPI_Shape::ShapeType theShapeTypeToExplore, + const std::string& theName) { - int anIndex = 1; - int aTag = theTag; - bool isBuilt = !theName.empty(); - std::string aName = theName; - std::ostringstream aStream; GeomShapePtr aResultShape = shape(); - TopoDS_Shape aShapeIn = theShapeIn->impl(); - TopTools_MapOfShape aView; - TopExp_Explorer aShapeExplorer (aShapeIn, (TopAbs_ShapeEnum)theKindOfShape); - for (; aShapeExplorer.More(); aShapeExplorer.Next ()) { - const TopoDS_Shape& aRoot = aShapeExplorer.Current (); - if (!aView.Add(aRoot)) continue; - ListOfShape aList; - std::shared_ptr aRShape(new GeomAPI_Shape()); - aRShape->setImpl((new TopoDS_Shape(aRoot))); - theMS->modified(aRShape, aList); - std::list >::const_iterator - anIt = aList.begin(), aLast = aList.end(); - for (; anIt != aLast; anIt++) { - TopoDS_Shape aNewShape = (*anIt)->impl(); - if (theSubShapes.isBound(*anIt)) { - std::shared_ptr aMapShape(theSubShapes.find(*anIt)); - aNewShape.Orientation(aMapShape->impl().Orientation()); + GeomShapePtr aShapeToExplore = theOldShape; + if (theAlgo->isNewShapesCollected(theOldShape, theShapeTypeToExplore)) { + // use optimized set of old shapes for this + GeomShapePtr aCompound = theAlgo->oldShapesForNew(theOldShape, + aResultShape, + theShapeTypeToExplore); + if (aCompound.get()) aShapeToExplore = aCompound; + } + + TopTools_MapOfShape anAlreadyProcessedShapes; + std::shared_ptr aData = std::dynamic_pointer_cast(data()); + for (GeomAPI_ShapeExplorer anOldShapeExp(aShapeToExplore, theShapeTypeToExplore); + anOldShapeExp.more(); + anOldShapeExp.next()) + { + GeomShapePtr anOldSubShape = anOldShapeExp.current(); + const TopoDS_Shape& anOldSubShape_ = anOldSubShape->impl(); + + // There is no sense to write history if shape already processed + // or old shape does not exist in the document. + bool anOldSubShapeAlreadyProcessed = !anAlreadyProcessedShapes.Add(anOldSubShape_); + bool anOldSubShapeNotInTree = TNaming_Tool::NamedShape(anOldSubShape_, aData->shapeLab()) + .IsNull(); + if (anOldSubShapeAlreadyProcessed + || anOldSubShapeNotInTree) + { + continue; + } + + // Get new shapes. + ListOfShape aNewShapes; + theAlgo->modified(anOldSubShape, aNewShapes); + + for (ListOfShape::const_iterator aNewShapesIt = aNewShapes.cbegin(); + aNewShapesIt != aNewShapes.cend(); + ++aNewShapesIt) + { + GeomShapePtr aNewShape = *aNewShapesIt; + const TopoDS_Shape& aNewShape_ = aNewShape->impl(); + bool isGenerated = anOldSubShape_.ShapeType() != aNewShape_.ShapeType(); + + bool aNewShapeIsSameAsOldShape = anOldSubShape->isSame(aNewShape); + bool aNewShapeIsNotInResultShape = !aResultShape->isSubShape(aNewShape, false); + if (aNewShapeIsSameAsOldShape + || aNewShapeIsNotInResultShape) + { + continue; } - GeomShapePtr aGeomNewShape(new GeomAPI_Shape()); - aGeomNewShape->setImpl(new TopoDS_Shape(aNewShape)); - if(!aRoot.IsSame(aNewShape) && aResultShape->isSubShape(aGeomNewShape)) { - builder(aTag)->Modify(aRoot,aNewShape); - if(isBuilt) { - if(theIsStoreSeparate) { - aStream.str(std::string()); - aStream.clear(); - aStream << theName << "_" << anIndex++; - aName = aStream.str(); - } - buildName(aTag, aName); + + TNaming_Builder* aBuilder; + if (aResultShape->isSame(aNewShape)) { + // keep the modification evolution on the root level (2241 - history propagation issue) + aBuilder = builder(0); + TDF_Label aShapeLab = aBuilder->NamedShape()->Label(); + Handle(TDF_Reference) aRef; + if (aShapeLab.FindAttribute(TDF_Reference::GetID(), aRef)) { + // Store only in case if it does not have reference. + continue; } - if(theIsStoreSeparate) { - aTag++; + + // Check if new shape was already stored. + if (isAlreadyStored(aBuilder, anOldSubShape_, aNewShape_)) continue; + + if (!aBuilder->NamedShape().IsNull() && + ((isGenerated && aBuilder->NamedShape()->Evolution() != TNaming_GENERATED) + || (!isGenerated && aBuilder->NamedShape()->Evolution() != TNaming_MODIFY))) + { + myBuilders.erase(0); // clear old builder to avoid different evolutions crash + aBuilder = builder(0); } + } else { + int aTag = isGenerated ? getGenerationTag(aNewShape_) + : getModificationTag(aNewShape_); + aBuilder = builder(aTag); + + // Check if new shape was already stored. + if (isAlreadyStored(aBuilder, anOldSubShape_, aNewShape_)) continue; + + buildName(aTag, theName); } + + isGenerated ? aBuilder->Generated(anOldSubShape_, aNewShape_) + : aBuilder->Modify(anOldSubShape_, aNewShape_); } } } -void Model_BodyBuilder::loadAndOrientGeneratedShapes ( - GeomAlgoAPI_MakeShape* theMS, - std::shared_ptr theShapeIn, - const int theKindOfShape, - const int theTag, - const std::string& theName, - GeomAPI_DataMapOfShapeShape& theSubShapes) +void Model_BodyBuilder::loadGeneratedShapes(const GeomMakeShapePtr& theAlgo, + const GeomShapePtr& theOldShape, + const GeomAPI_Shape::ShapeType theShapeTypeToExplore, + const std::string& theName) { - TopoDS_Shape aShapeIn = theShapeIn->impl(); - TopTools_MapOfShape aView; - bool isBuilt = !theName.empty(); - TopExp_Explorer aShapeExplorer (aShapeIn, (TopAbs_ShapeEnum)theKindOfShape); - for (; aShapeExplorer.More(); aShapeExplorer.Next ()) { - const TopoDS_Shape& aRoot = aShapeExplorer.Current (); - if (!aView.Add(aRoot)) continue; - ListOfShape aList; - std::shared_ptr aRShape(new GeomAPI_Shape()); - aRShape->setImpl((new TopoDS_Shape(aRoot))); - theMS->generated(aRShape, aList); - std::list >::const_iterator - anIt = aList.begin(), aLast = aList.end(); - for (; anIt != aLast; anIt++) { - TopoDS_Shape aNewShape = (*anIt)->impl(); - if (theSubShapes.isBound(*anIt)) { - std::shared_ptr aMapShape(theSubShapes.find(*anIt)); - aNewShape.Orientation(aMapShape->impl().Orientation()); - } - if (!aRoot.IsSame (aNewShape)) { - builder(theTag)->Generated(aRoot,aNewShape); - if(isBuilt) - buildName(theTag, theName); - } - TopAbs_ShapeEnum aGenShapeType = aNewShape.ShapeType(); - if(aGenShapeType == TopAbs_WIRE || aGenShapeType == TopAbs_SHELL) { - TopAbs_ShapeEnum anExplodeShapeType = - aGenShapeType == TopAbs_WIRE ? TopAbs_EDGE : TopAbs_FACE; - const TDF_Label aLabel = builder(theTag)->NamedShape()->Label(); - int aTag = 1; - std::shared_ptr aDoc = - std::dynamic_pointer_cast(document()); - for(TopExp_Explorer anExp(aNewShape, anExplodeShapeType); anExp.More(); anExp.Next()) { - TDF_Label aChildLabel = aLabel.FindChild(aTag); - TNaming_Builder aBuilder(aChildLabel); - aBuilder.Generated(aRoot, anExp.Current()); - TCollection_AsciiString aChildName = - TCollection_AsciiString((theName + "_").c_str()) + aTag; - TDataStd_Name::Set(aChildLabel, aChildName.ToCString()); - aTag++; + TopTools_MapOfShape anAlreadyProcessedShapes; + for (GeomAPI_ShapeExplorer anOldShapeExp(theOldShape, theShapeTypeToExplore); + anOldShapeExp.more(); + anOldShapeExp.next()) + { + GeomShapePtr anOldSubShape = anOldShapeExp.current(); + const TopoDS_Shape& anOldSubShape_ = anOldSubShape->impl(); + + // There is no sense to write history if shape already processed. + if (!anAlreadyProcessedShapes.Add(anOldSubShape_)) continue; + + // Get new shapes. + ListOfShape aNewShapes; + theAlgo->generated(anOldSubShape, aNewShapes); + + keepTopLevelShapes(aNewShapes, anOldSubShape_); + + for (ListOfShape::const_iterator aNewShapesIt = aNewShapes.cbegin(); + aNewShapesIt != aNewShapes.cend(); + ++aNewShapesIt) + { + GeomShapePtr aNewShape = *aNewShapesIt; + const TopoDS_Shape& aNewShape_ = aNewShape->impl(); + + TopAbs_ShapeEnum aNewShapeType = aNewShape_.ShapeType(); + if (aNewShapeType == TopAbs_WIRE || aNewShapeType == TopAbs_SHELL) { + // TODO: This is a workaround. New shape should be only edge or face. + TopAbs_ShapeEnum aShapeTypeToExplore = aNewShapeType == TopAbs_WIRE ? TopAbs_EDGE + : TopAbs_FACE; + int aTag = TopAbs_WIRE ? GENERATED_EDGES_TAG : GENERATED_FACES_TAG; + for (TopExp_Explorer anExp(aNewShape_, aShapeTypeToExplore); anExp.More(); anExp.Next()) { + builder(aTag)->Generated(anOldSubShape_, anExp.Current()); } + buildName(aTag, theName); + } + else { + int aTag = getGenerationTag(aNewShape_); + if (aTag == INVALID_TAG) return; + builder(aTag)->Generated(anOldSubShape_, aNewShape_); + buildName(aTag, theName); } } } @@ -483,8 +631,8 @@ void loadGeneratedDangleShapes( } //======================================================================= -void Model_BodyBuilder::loadNextLevels(std::shared_ptr theShape, - const std::string& theName, int& theTag) +void Model_BodyBuilder::loadNextLevels(GeomShapePtr theShape, + const std::string& theName) { if(theShape->isNull()) return; TopoDS_Shape aShape = theShape->impl(); @@ -492,11 +640,11 @@ void Model_BodyBuilder::loadNextLevels(std::shared_ptr theShape, if (aShape.ShapeType() == TopAbs_SOLID) { TopExp_Explorer expl(aShape, TopAbs_FACE); for (; expl.More(); expl.Next()) { - builder(theTag)->Generated(expl.Current()); - TCollection_AsciiString aStr(theTag); - aName = theName + aStr.ToCString(); - buildName(theTag, aName); - theTag++; + builder(myFreePrimitiveTag)->Generated(expl.Current()); + TCollection_AsciiString aStr(myFreePrimitiveTag - PRIMITIVES_START_TAG + 1); + aName = theName + "_" + aStr.ToCString(); + buildName(myFreePrimitiveTag, aName); + ++myFreePrimitiveTag; } } else if (aShape.ShapeType() == TopAbs_SHELL || aShape.ShapeType() == TopAbs_FACE) { @@ -506,11 +654,11 @@ void Model_BodyBuilder::loadNextLevels(std::shared_ptr theShape, if (Faces.Extent() > 1 || (aShape.ShapeType() == TopAbs_SHELL && Faces.Extent() == 1)) { TopExp_Explorer expl(aShape, TopAbs_FACE); for (; expl.More(); expl.Next()) { - builder(theTag)->Generated(expl.Current()); - TCollection_AsciiString aStr(theTag); - aName = theName + aStr.ToCString(); - buildName(theTag, aName); - theTag++; + builder(myFreePrimitiveTag)->Generated(expl.Current()); + TCollection_AsciiString aStr(myFreePrimitiveTag - PRIMITIVES_START_TAG + 1); + aName = theName + "_" + aStr.ToCString(); + buildName(myFreePrimitiveTag, aName); + ++myFreePrimitiveTag; } } TopTools_IndexedDataMapOfShapeListOfShape anEdgeAndNeighbourFaces; @@ -521,21 +669,21 @@ void Model_BodyBuilder::loadNextLevels(std::shared_ptr theShape, if (aLL.Extent() < 2) { if (BRep_Tool::Degenerated(TopoDS::Edge(anEdgeAndNeighbourFaces.FindKey(i)))) continue; - builder(theTag)->Generated(anEdgeAndNeighbourFaces.FindKey(i)); - TCollection_AsciiString aStr(theTag); - aName = theName + aStr.ToCString(); - buildName(theTag, aName); - theTag++; + builder(myFreePrimitiveTag)->Generated(anEdgeAndNeighbourFaces.FindKey(i)); + TCollection_AsciiString aStr(myFreePrimitiveTag - PRIMITIVES_START_TAG + 1); + aName = theName + "_" + aStr.ToCString(); + buildName(myFreePrimitiveTag, aName); + ++myFreePrimitiveTag; } else { TopTools_ListIteratorOfListOfShape anIter(aLL); const TopoDS_Face& aFace = TopoDS::Face(anIter.Value()); anIter.Next(); if(aFace.IsEqual(anIter.Value())) { - builder(theTag)->Generated(anEdgeAndNeighbourFaces.FindKey(i)); - TCollection_AsciiString aStr(theTag); - aName = theName + aStr.ToCString(); - buildName(theTag, aName); - theTag++; + builder(myFreePrimitiveTag)->Generated(anEdgeAndNeighbourFaces.FindKey(i)); + TCollection_AsciiString aStr(myFreePrimitiveTag - PRIMITIVES_START_TAG + 1); + aName = theName + "_" + aStr.ToCString(); + buildName(myFreePrimitiveTag, aName); + ++myFreePrimitiveTag; } } } @@ -543,40 +691,40 @@ void Model_BodyBuilder::loadNextLevels(std::shared_ptr theShape, TopTools_IndexedMapOfShape Edges; BRepTools::Map3DEdges(aShape, Edges); if (Edges.Extent() == 1) { - builder(++theTag)->Generated(Edges.FindKey(1)); + builder(myFreePrimitiveTag++)->Generated(Edges.FindKey(1)); TopExp_Explorer expl(aShape, TopAbs_VERTEX); for (; expl.More(); expl.Next()) { - builder(theTag)->Generated(expl.Current()); - TCollection_AsciiString aStr(theTag); - aName = theName + aStr.ToCString(); - buildName(theTag, aName); - theTag++; + builder(myFreePrimitiveTag)->Generated(expl.Current()); + TCollection_AsciiString aStr(myFreePrimitiveTag - PRIMITIVES_START_TAG + 1); + aName = theName + "_" + aStr.ToCString(); + buildName(myFreePrimitiveTag, aName); + ++myFreePrimitiveTag; } } else { TopExp_Explorer expl(aShape, TopAbs_EDGE); for (; expl.More(); expl.Next()) { - builder(theTag)->Generated(expl.Current()); - TCollection_AsciiString aStr(theTag); - aName = theName + aStr.ToCString(); - buildName(theTag, aName); - theTag++; + builder(myFreePrimitiveTag)->Generated(expl.Current()); + TCollection_AsciiString aStr(myFreePrimitiveTag - PRIMITIVES_START_TAG + 1); + aName = theName + "_" + aStr.ToCString(); + buildName(myFreePrimitiveTag, aName); + ++myFreePrimitiveTag; } // and load generated vertices. TopTools_DataMapOfShapeShape generated; if (getDangleShapes(aShape, TopAbs_EDGE, generated)) { - TNaming_Builder* pBuilder = builder(theTag++); + TNaming_Builder* pBuilder = builder(myFreePrimitiveTag++); loadGeneratedDangleShapes(aShape, TopAbs_EDGE, pBuilder); } } } else if (aShape.ShapeType() == TopAbs_EDGE) { TopExp_Explorer expl(aShape, TopAbs_VERTEX); for (; expl.More(); expl.Next()) { - builder(theTag)->Generated(expl.Current()); - TCollection_AsciiString aStr(theTag); - aName = theName + aStr.ToCString(); - buildName(theTag, aName); - theTag++; + builder(myFreePrimitiveTag)->Generated(expl.Current()); + TCollection_AsciiString aStr(myFreePrimitiveTag - PRIMITIVES_START_TAG + 1); + aName = theName + "_" + aStr.ToCString(); + buildName(myFreePrimitiveTag, aName); + ++myFreePrimitiveTag; } } } @@ -585,91 +733,104 @@ void Model_BodyBuilder::loadNextLevels(std::shared_ptr theShape, int findAmbiguities(const TopoDS_Shape& theShapeIn, TopTools_ListOfShape& theList) { - int aNumEdges(0); theList.Clear(); - TopTools_IndexedDataMapOfShapeListOfShape subShapeAndAncestors; - TopAbs_ShapeEnum aTS(TopAbs_EDGE); - TopAbs_ShapeEnum aTA(TopAbs_FACE); - TopTools_MapOfShape aMap1, aMap2; // map1 - for edge ancestors; map2 - for keys => edges - TopTools_ListOfShape aKeyList; - TopExp::MapShapesAndAncestors(theShapeIn, aTS, aTA, subShapeAndAncestors); - for (Standard_Integer i = 1; i <= subShapeAndAncestors.Extent(); i++) { - const TopoDS_Shape& aKeyEdge1 = subShapeAndAncestors.FindKey(i); - const TopTools_ListOfShape& ancestors1 = subShapeAndAncestors.FindFromIndex(i); - aMap1.Clear(); - TopTools_ListIteratorOfListOfShape it(ancestors1); - for(;it.More();it.Next()) aMap1.Add(it.Value()); // fill map with key ancestors => aKey1 - for (Standard_Integer j = 1; j <= subShapeAndAncestors.Extent(); j++) { - if (i == j) continue; - const TopoDS_Shape& aKeyEdge2 = subShapeAndAncestors.FindKey(j); - const TopTools_ListOfShape& ancestors2 = subShapeAndAncestors.FindFromIndex(j); - if(ancestors1.Extent() == ancestors2.Extent() && ancestors1.Extent() > 1) { - int aNum (ancestors2.Extent()); - TopTools_ListIteratorOfListOfShape it(ancestors2); - for(;it.More();it.Next()) - if(aMap1.Contains(it.Value())) aNum--; - if(aNum == 0) { - if(aMap2.Add(aKeyEdge1)) - aKeyList.Append(aKeyEdge1); - if(aMap2.Add(aKeyEdge2)) - aKeyList.Append(aKeyEdge2); + // edges -> ancestor faces list + TopTools_IndexedDataMapOfShapeListOfShape aSubShapeAndAncestors; + TopExp::MapShapesAndAncestors(theShapeIn, TopAbs_EDGE, TopAbs_FACE, aSubShapeAndAncestors); + // keeps the shapes which are already in the resulting list + TopTools_MapOfShape alreadyThere; + // map from faces identifier (combination of hash-codes) to list of edges produced such ID + NCollection_DataMap > aFacesIDs; + + TopTools_IndexedDataMapOfShapeListOfShape::Iterator anAncestorsIter(aSubShapeAndAncestors); + for (; anAncestorsIter.More(); anAncestorsIter.Next()) { + const TopTools_ListOfShape& ancestors = anAncestorsIter.Value(); + if (ancestors.Extent() < 2) + continue; + Standard_Integer anID = 0; + for(TopTools_ListIteratorOfListOfShape aFaceIt(ancestors); aFaceIt.More(); aFaceIt.Next()) { + anID ^= HashCode(aFaceIt.ChangeValue(), 1990657); // Pierpont prime + } + if (aFacesIDs.IsBound(anID)) { // there found same edge, check they really have same faces + const NCollection_List& aSameFaces1 = + aSubShapeAndAncestors.FindFromKey(anAncestorsIter.Key()); + NCollection_List::Iterator aSameEdge(aFacesIDs.ChangeFind(anID)); + for(; aSameEdge.More(); aSameEdge.Next()) { + const NCollection_List& aSameFaces2 = + aSubShapeAndAncestors.FindFromKey(aSameEdge.Value()); + if (aSameFaces2.Extent() != aSameFaces1.Extent()) // the number of faces is different + break; + + NCollection_List::Iterator aFaceIter1(aSameFaces1); + for(; aFaceIter1.More(); aFaceIter1.Next()) { + NCollection_List::Iterator aFaceIter2(aSameFaces2); + for(; aFaceIter2.More(); aFaceIter2.Next()) { + if (aFaceIter1.Value().IsSame(aFaceIter2.Value())) + break; + } + if (!aFaceIter2.More()) // aFaceIter1 contains a face, which is not in aFaceIter2 + break; + } + if (!aFaceIter1.More()) { // all the faces are same => put to the result + if (alreadyThere.Add(aSameEdge.Value())) + theList.Append(aSameEdge.Value()); + if (alreadyThere.Add(anAncestorsIter.Key())) + theList.Append(anAncestorsIter.Key()); } } - } // at the end ==> List of edges to be named in addition + } else { // ID is unique, just add this edge + aFacesIDs.Bind(anID, NCollection_List()); + } + aFacesIDs.ChangeFind(anID).Append(anAncestorsIter.Key()); // add to the list anyway } - aNumEdges = aKeyList.Extent(); - if(aNumEdges) - theList.Assign(aKeyList); - return aNumEdges; + return theList.Extent(); } //======================================================================= -void Model_BodyBuilder::loadFirstLevel( - std::shared_ptr theShape, const std::string& theName, int& theTag) +void Model_BodyBuilder::loadFirstLevel(GeomShapePtr theShape, const std::string& theName) { if(theShape->isNull()) return; TopoDS_Shape aShape = theShape->impl(); std::string aName; if (aShape.ShapeType() == TopAbs_COMPOUND || aShape.ShapeType() == TopAbs_COMPSOLID) { TopoDS_Iterator itr(aShape); - for (; itr.More(); itr.Next(),theTag++) { - builder(theTag)->Generated(itr.Value()); - TCollection_AsciiString aStr(theTag); - aName = theName + aStr.ToCString(); - buildName(theTag, aName); - if(!theName.empty()) buildName(theTag, aName); + for (; itr.More(); itr.Next()) { + builder(myFreePrimitiveTag)->Generated(itr.Value()); + TCollection_AsciiString aStr(myFreePrimitiveTag - PRIMITIVES_START_TAG + 1); + aName = theName + "_" + aStr.ToCString(); + buildName(myFreePrimitiveTag, aName); + ++myFreePrimitiveTag; if (itr.Value().ShapeType() == TopAbs_COMPOUND || itr.Value().ShapeType() == TopAbs_COMPSOLID) { - std::shared_ptr itrShape(new GeomAPI_Shape()); + GeomShapePtr itrShape(new GeomAPI_Shape()); itrShape->setImpl(new TopoDS_Shape(itr.Value())); - loadFirstLevel(itrShape, theName, theTag); + loadFirstLevel(itrShape, theName); } else { - std::shared_ptr itrShape(new GeomAPI_Shape()); + GeomShapePtr itrShape(new GeomAPI_Shape()); itrShape->setImpl(new TopoDS_Shape(itr.Value())); - loadNextLevels(itrShape, theName, theTag); + loadNextLevels(itrShape, theName); } } } else { - std::shared_ptr itrShape(new GeomAPI_Shape()); + GeomShapePtr itrShape(new GeomAPI_Shape()); itrShape->setImpl(new TopoDS_Shape(aShape)); - loadNextLevels(itrShape, theName, theTag); + loadNextLevels(itrShape, theName); } TopTools_ListOfShape aList; if(findAmbiguities(aShape, aList)) { TopTools_ListIteratorOfListOfShape it(aList); - for (; it.More(); it.Next(),theTag++) { - builder(theTag)->Generated(it.Value()); - TCollection_AsciiString aStr(theTag); - aName = theName + aStr.ToCString(); - buildName(theTag, aName); + for (; it.More(); it.Next(), ++myFreePrimitiveTag) { + builder(myFreePrimitiveTag)->Generated(it.Value()); + TCollection_AsciiString aStr(myFreePrimitiveTag - PRIMITIVES_START_TAG + 1); + aName = theName + "_" + aStr.ToCString(); + buildName(myFreePrimitiveTag, aName); } } } //======================================================================= -void Model_BodyBuilder::loadDisconnectedEdges( - std::shared_ptr theShape, const std::string& theName, int& theTag) +void Model_BodyBuilder::loadDisconnectedEdges(GeomShapePtr theShape, const std::string& theName) { if(theShape->isNull()) return; TopoDS_Shape aShape = theShape->impl(); @@ -718,12 +879,12 @@ void Model_BodyBuilder::loadDisconnectedEdges( if (aLIter1.Value().IsSame(aLIter2.Value())) aMatches++; if (aMatches == aList1.Extent()) { aC0=Standard_True; - builder(theTag)->Generated(anEdge2); + builder(myFreePrimitiveTag)->Generated(anEdge2); anEdgesToDelete.Add(anEdge2); - TCollection_AsciiString aStr(theTag); - aName = theName + aStr.ToCString(); - buildName(theTag, aName); - theTag++; + TCollection_AsciiString aStr(myFreePrimitiveTag - PRIMITIVES_START_TAG + 1); + aName = theName + "_" + aStr.ToCString(); + buildName(myFreePrimitiveTag, aName); + ++myFreePrimitiveTag; } } } @@ -733,17 +894,17 @@ void Model_BodyBuilder::loadDisconnectedEdges( edgeNaborFaces.UnBind(anEdge1); } if (aC0) { - builder(theTag)->Generated(anEdge1); - TCollection_AsciiString aStr(theTag); - aName = theName + aStr.ToCString(); - buildName(theTag, aName); - theTag++; + builder(myFreePrimitiveTag)->Generated(anEdge1); + TCollection_AsciiString aStr(myFreePrimitiveTag - PRIMITIVES_START_TAG + 1); + aName = theName + "_" + aStr.ToCString(); + buildName(myFreePrimitiveTag, aName); + ++myFreePrimitiveTag; } } } -void Model_BodyBuilder::loadDisconnectedVertexes(std::shared_ptr theShape, - const std::string& theName, int& theTag) +void Model_BodyBuilder::loadDisconnectedVertexes(GeomShapePtr theShape, + const std::string& theName) { if(theShape->isNull()) return; TopoDS_Shape aShape = theShape->impl(); @@ -774,19 +935,19 @@ void Model_BodyBuilder::loadDisconnectedVertexes(std::shared_ptr for (; itr.More(); itr.Next()) { const TopTools_ListOfShape& naborEdges = itr.Value(); if (naborEdges.Extent() < 2) { - builder(theTag)->Generated(itr.Key()); - TCollection_AsciiString aStr(theTag); - aName = theName + aStr.ToCString(); - buildName(theTag, aName); - theTag++; + builder(myFreePrimitiveTag)->Generated(itr.Key()); + TCollection_AsciiString aStr(myFreePrimitiveTag - PRIMITIVES_START_TAG + 1); + aName = theName + "_" + aStr.ToCString(); + buildName(myFreePrimitiveTag, aName); + ++myFreePrimitiveTag; } } } -std::shared_ptr Model_BodyBuilder::shape() +GeomShapePtr Model_BodyBuilder::shape() { std::shared_ptr aData = std::dynamic_pointer_cast(data()); - if (aData) { + if (aData && aData->isValid()) { TDF_Label aShapeLab = aData->shapeLab(); Handle(TDF_Reference) aRef; if (aShapeLab.FindAttribute(TDF_Reference::GetID(), aRef)) { @@ -796,16 +957,16 @@ std::shared_ptr Model_BodyBuilder::shape() if (aShapeLab.FindAttribute(TNaming_NamedShape::GetID(), aName)) { TopoDS_Shape aShape = aName->Get(); if (!aShape.IsNull()) { - std::shared_ptr aRes(new GeomAPI_Shape); + GeomShapePtr aRes(new GeomAPI_Shape); aRes->setImpl(new TopoDS_Shape(aShape)); return aRes; } } } - return std::shared_ptr(); + return GeomShapePtr(); } -bool Model_BodyBuilder::isLatestEqual(const std::shared_ptr& theShape) +bool Model_BodyBuilder::isLatestEqual(const GeomShapePtr& theShape) { if (theShape.get()) { TopoDS_Shape aShape = theShape->impl();