X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_ResultConstruction.cpp;h=ad9c9a3070e2f9c060b0a9affef787a4e46d243f;hb=b73fb7468bea81901dbeed8e229d742f788ec282;hp=4826c9e09d34174e7672a3320c8c0d9105d6ad15;hpb=0d86fc6820bb4e2185a4ef443693441193678e63;p=modules%2Fshaper.git diff --git a/src/Model/Model_ResultConstruction.cpp b/src/Model/Model_ResultConstruction.cpp index 4826c9e09..ad9c9a307 100644 --- a/src/Model/Model_ResultConstruction.cpp +++ b/src/Model/Model_ResultConstruction.cpp @@ -1,8 +1,22 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: ModelAPI_ResultConstruction.cpp -// Created: 07 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 @@ -24,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -34,6 +47,7 @@ #include #include #include +#include #include // identifier that it is full result selected, but in external document (for internal index is 0) @@ -50,14 +64,16 @@ void Model_ResultConstruction::colorConfigInfo(std::string& theSection, std::str void Model_ResultConstruction::setShape(std::shared_ptr theShape) { - if (myShape != theShape && (!theShape.get() || !theShape->isEqual(myShape))) { - static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); - ModelAPI_EventCreator::get()->sendUpdated(data()->owner(), anEvent); - myShape = theShape; - if (theShape.get()) { - myFacesUpToDate = false; - myFaces.clear(); + if (myShape != theShape) { + if (!theShape.get() || !theShape->isEqual(myShape)) { + static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); + ModelAPI_EventCreator::get()->sendUpdated(data()->owner(), anEvent); + if (theShape.get()) { + myFacesUpToDate = false; + myFaces.clear(); + } } + myShape = theShape; } } @@ -78,7 +94,7 @@ void Model_ResultConstruction::setIsInHistory(const bool isInHistory) myIsInHistory = isInHistory; } -int Model_ResultConstruction::facesNum() +int Model_ResultConstruction::facesNum(const bool theUpdateNaming) { if (!myFacesUpToDate) { std::shared_ptr aWirePtr = @@ -95,6 +111,23 @@ int Model_ResultConstruction::facesNum() } } myFacesUpToDate = true; + + // update all the faces and sub-elements in the naming structure + if (theUpdateNaming) { + DocumentPtr anEmptyExt; + bool aNotExt = false; + TDF_Label aDataLab = startLabel(anEmptyExt, aNotExt); + TDF_ChildIterator aSubsIter(aDataLab, Standard_False); + for(; aSubsIter.More(); aSubsIter.Next()) { + const TDF_Label aLab = aSubsIter.Value(); + if (aLab.Tag() == 1) // skip the root shape label + continue; + Handle(TNaming_NamedShape) aNS; + if (aLab.FindAttribute(TNaming_NamedShape::GetID(), aNS)) { + update(aLab.Tag() - 1, anEmptyExt, aNotExt); + } + } + } } return int(myFaces.size()); } @@ -116,24 +149,16 @@ void Model_ResultConstruction::setInfinite(const bool theInfinite) void Model_ResultConstruction::setIsConcealed(const bool theValue) { - // do nothing: the construction element is never consealed + // do nothing: the construction element is never concealed } static const int kSTART_VERTEX_DELTA = 1000000; -static void registerSubShape(TDF_Label theMainLabel, TopoDS_Shape theShape, +static void registerSubShape(TDF_Label theMainLabel, TopoDS_Shape theShape, std::string theFullName, const int theID, std::shared_ptr theDoc, - bool theSelectionMode, - std::map& theOrientations, - // name of sub-elements by ID to be exported instead of indexes - std::map& theSubNames, - Handle(TDataStd_IntPackedMap) theRefs = Handle(TDataStd_IntPackedMap)(), - const int theOrientation = 0) + bool theSelectionMode) { TDF_Label aLab = theID == 0 ? theMainLabel : theMainLabel.FindChild(theID); - if (theOrientation != 0) { // store the orientation of edge relatively to face if needed - TDataStd_Integer::Set(aLab, theOrientation); - } TNaming_Builder aBuilder(aLab); // wire never happens as sub, it must be generated to be found // by SelectionNaming TNaming_Tool::NamedShape @@ -141,40 +166,164 @@ static void registerSubShape(TDF_Label theMainLabel, TopoDS_Shape theShape, aBuilder.Select(theShape, theShape); else aBuilder.Generated(theShape); + + theDoc->addNamingName(aLab, theFullName); + TDataStd_Name::Set(aLab, theFullName.c_str()); +} + +// generates a full-name for sub-element of the composite feature (sketch) +std::string fullName(CompositeFeaturePtr theComposite, const TopoDS_Shape& theSubShape, + Handle(TDataStd_IntPackedMap) theRefs = Handle(TDataStd_IntPackedMap)()) +{ + TopAbs_ShapeEnum aShapeType = theSubShape.ShapeType(); + gp_Pnt aVertexPos; + TColStd_MapOfTransient allCurves; + if (aShapeType == TopAbs_VERTEX) { // compare positions + aVertexPos = BRep_Tool::Pnt(TopoDS::Vertex(theSubShape)); + } else { + for(TopExp_Explorer anEdgeExp(theSubShape, TopAbs_EDGE); anEdgeExp.More(); anEdgeExp.Next()) { + TopoDS_Edge anEdge = TopoDS::Edge(anEdgeExp.Current()); + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + allCurves.Add(aCurve); + } + } + std::map anOrientations; //map from edges IDs to orientations of these edges in face + std::map aSubNames; //map from edges IDs to names of edges + TColStd_PackedMapOfInteger aRefs; // indixes of sub-elements in composite + + const int aSubNum = theComposite->numberOfSubs(); + for(int a = 0; a < aSubNum; a++) { + FeaturePtr aSub = theComposite->subFeature(a); + const std::list >& aResults = aSub->results(); + std::list >::const_iterator aRes = aResults.cbegin(); + // there may be many shapes (circle and center): register if at least one is in selection + for(; aRes != aResults.cend(); aRes++) { + ResultConstructionPtr aConstr = + std::dynamic_pointer_cast(*aRes); + if (!aConstr->shape()) { + continue; + } + if (aShapeType == TopAbs_VERTEX) { + if (aConstr->shape()->isVertex()) { // compare vertices positions + const TopoDS_Shape& aVertex = aConstr->shape()->impl(); + gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVertex)); + if (aPnt.IsEqual(aVertexPos, Precision::Confusion())) { + aRefs.Add(theComposite->subFeatureId(a)); + aSubNames[theComposite->subFeatureId(a)] = Model_SelectionNaming::shortName(aConstr); + } + } else { // get first or last vertex of the edge: last is stored with additional delta + const TopoDS_Shape& anEdge = aConstr->shape()->impl(); + int aDelta = kSTART_VERTEX_DELTA; + for(TopExp_Explorer aVExp(anEdge, TopAbs_VERTEX); aVExp.More(); aVExp.Next()) { + gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVExp.Current())); + if (aPnt.IsEqual(aVertexPos, Precision::Confusion())) { + aRefs.Add(aDelta + theComposite->subFeatureId(a)); + aSubNames[aDelta + theComposite->subFeatureId(a)] = + Model_SelectionNaming::shortName(aConstr, aDelta / kSTART_VERTEX_DELTA); + break; + } + aDelta += kSTART_VERTEX_DELTA; + } + } + } else { + if (aConstr->shape()->isEdge()) { + const TopoDS_Shape& aResShape = aConstr->shape()->impl(); + TopoDS_Edge anEdge = TopoDS::Edge(aResShape); + if (!anEdge.IsNull()) { + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + if (allCurves.Contains(aCurve)) { + int anID = theComposite->subFeatureId(a); + aRefs.Add(anID); + aSubNames[anID] = Model_SelectionNaming::shortName(aConstr); + if (aShapeType != TopAbs_EDGE) { // face needs the sub-edges on sub-labels + // add edges to sub-label to support naming for edges selection + TopExp_Explorer anEdgeExp(theSubShape, TopAbs_EDGE); + for(; anEdgeExp.More(); anEdgeExp.Next()) { + TopoDS_Edge anEdge = TopoDS::Edge(anEdgeExp.Current()); + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aFaceCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + if (aFaceCurve == aCurve) { + int anOrient = Model_SelectionNaming::edgeOrientation(theSubShape, anEdge); + anOrientations[anID] = anOrient; + } + } + } + } + } + } + } + } + } std::stringstream aName; // #1839 : do not store name of the feature in the tree, since this name could be changed - //aName<name(); - if (theShape.ShapeType() != TopAbs_COMPOUND) { // compound means the whole result for construction - //aName<<"/"; - if (theShape.ShapeType() == TopAbs_FACE) aName<<"Face"; - else if (theShape.ShapeType() == TopAbs_WIRE) aName<<"Wire"; - else if (theShape.ShapeType() == TopAbs_EDGE) aName<<"Edge"; - else if (theShape.ShapeType() == TopAbs_VERTEX) aName<<"Vertex"; - - if (theRefs.IsNull()) { - aName<GetMap()); - for(; aRef.More(); aRef.Next()) { - aName<<"-"<ChangeMap(aMap); + } + return aName.str(); +} + +// stores shape and name on sub-label of the main stored shape +static void saveSubName(CompositeFeaturePtr theComposite, + TDF_Label& theLab, const bool isSelectionMode, TopoDS_Shape aSub, + std::shared_ptr theDoc, std::string theFullName) +{ + // trying to store the edge of composite result, not sketch sub as it is + if (aSub.ShapeType() == TopAbs_EDGE) { + ResultPtr aRes = theComposite->firstResult(); + ResultConstructionPtr aConstr = std::dynamic_pointer_cast(aRes); + if (aConstr.get()) { + Standard_Real aSubFirst, aSubLast; + TopoDS_Edge aSubEdge = TopoDS::Edge(aSub); + Handle(Geom_Curve) aSubCurve = BRep_Tool::Curve(aSubEdge, aSubFirst, aSubLast); + for(int aFaceIndex = 0; aFaceIndex < aConstr->facesNum(); aFaceIndex++) { + GeomShapePtr aGFace = aConstr->face(aFaceIndex); + TopoDS_Shape aFace = aGFace->impl(); + for(TopExp_Explorer anExp(aFace, TopAbs_EDGE); anExp.More(); anExp.Next()) { + TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current()); + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + if (aCurve == aSubCurve && + ((fabs(aFirst - aSubFirst) < 1.e-9 && fabs(aLast - aSubLast) < 1.e-9)) || + (fabs(aFirst - aSubLast) < 1.e-9 && fabs(aLast - aSubFirst) < 1.e-9)) { + aSub = anEdge; + break; + } } } } } - theDoc->addNamingName(aLab, aName.str()); - TDataStd_Name::Set(aLab, aName.str().c_str()); + TNaming_Builder aBuilder(theLab); + if (isSelectionMode) + aBuilder.Select(aSub, aSub); + else + aBuilder.Generated(aSub); + theDoc->addNamingName(theLab, theFullName.c_str()); + TDataStd_Name::Set(theLab, theFullName.c_str()); } + TDF_Label Model_ResultConstruction::startLabel( const std::shared_ptr theExtDoc, bool& theExternal) { @@ -231,17 +380,50 @@ int Model_ResultConstruction::select(const std::shared_ptr& theSu // if the subshape is part of a result face, select the whole face (#1997) bool isSelectionMode = false; // and other don't set shapes - all the naming is in face label if (!aSubShape.IsNull() && aSubShape.ShapeType() > TopAbs_FACE) { - for(int aFaceIndex = 0; aFaceIndex < facesNum(); aFaceIndex++) { - TopExp_Explorer anExp(face(aFaceIndex)->impl(), aSubShape.ShapeType()); - for(; anExp.More(); anExp.Next()) { - if (aSubShape.IsSame(anExp.Current())) { // this is the case: select the whole face - // here just store the face index (to update face if update of edge is needed) - TNaming_Builder aBuilder(aLab); - aBuilder.Select(aSubShape, aSubShape); - int aFaceSelID = select(face(aFaceIndex), theExtDoc, -1); - TDF_Reference::Set(aLab, aLab.Father().FindChild(aFaceSelID)); - isSelectionMode = true; - break; + // but before check that sub-vertex correctly detected as intersection of sketch edges (#2389) + int anEdgesNum = 2; + if (aSubShape.ShapeType() == TopAbs_VERTEX) { + anEdgesNum = 0; + ResultPtr aThisPtr = std::dynamic_pointer_cast(data()->owner()); + FeaturePtr aThisFeature = document()->feature(aThisPtr); + CompositeFeaturePtr aComposite = + std::dynamic_pointer_cast(aThisFeature); + if (aComposite.get()) { + const int aSubNum = aComposite->numberOfSubs(); + for(int a = 0; a < aSubNum; a++) { + int aSubID = aComposite->subFeatureId(a); + FeaturePtr aSub = aComposite->subFeature(a); + const std::list >& aResults = aSub->results(); + std::list >::const_iterator aRes; + for(aRes = aResults.cbegin(); aRes != aResults.cend(); aRes++) { + ResultConstructionPtr aConstr = + std::dynamic_pointer_cast(*aRes); + if (aConstr->shape() && aConstr->shape()->isEdge()) { + TopoDS_Shape aResShape = aConstr->shape()->impl(); + for(TopExp_Explorer anExp(aResShape, TopAbs_VERTEX); anExp.More(); anExp.Next()) { + if (aSubShape.IsSame(anExp.Current())) { + anEdgesNum++; + break; + } + } + } + } + } + } + } + if (anEdgesNum > 1) { + for(int aFaceIndex = 0; aFaceIndex < facesNum(); aFaceIndex++) { + TopExp_Explorer anExp(face(aFaceIndex)->impl(), aSubShape.ShapeType()); + for(; anExp.More(); anExp.Next()) { + if (aSubShape.IsSame(anExp.Current())) { // this is the case: select the whole face + // here just store the face index (to update face if update of edge is needed) + TNaming_Builder aBuilder(aLab); + aBuilder.Select(aSubShape, aSubShape); + int aFaceSelID = select(face(aFaceIndex), theExtDoc, -1); + TDF_Reference::Set(aLab, aLab.Father().FindChild(aFaceSelID)); + isSelectionMode = true; + break; + } } } } @@ -253,16 +435,10 @@ int Model_ResultConstruction::select(const std::shared_ptr& theSu // empty NS TNaming_Builder aBuilder(aLab); // store all sub-faces naming since faces may be used for extrusion, where all edges are needed + Handle(TDataStd_IntPackedMap) anIndices = TDataStd_IntPackedMap::Set(aLab); std::list aFacesIndexes; for(int a = 0; a < facesNum(); a++) { - aFacesIndexes.push_back(select(face(a), theExtDoc, -1)); - } - if (aFacesIndexes.size()) { - Handle(TDataStd_IntegerArray) anArray = - TDataStd_IntegerArray::Set(aLab, 0, int(aFacesIndexes.size() - 1)); - std::list::iterator anIter = aFacesIndexes.begin(); - for(int anArrayIndex = 0; anIter != aFacesIndexes.end(); anArrayIndex++, anIter++) - anArray->SetValue(anArrayIndex, *anIter); + anIndices->Add(select(face(a), theExtDoc, -1)); } return anIndex - 1; } @@ -313,10 +489,11 @@ int Model_ResultConstruction::select(const std::shared_ptr& theSu std::dynamic_pointer_cast(document()); // iterate and store the result ids of sub-elements and sub-elements to sub-labels Handle(TDataStd_IntPackedMap) aRefs = TDataStd_IntPackedMap::Set(aLab); - std::map anOrientations; //map from edges IDs to orientations of these edges in face - std::map aSubNames; //map from edges IDs to names of edges - aRefs->Clear(); const int aSubNum = aComposite->numberOfSubs(); + // subs are placed on unique labels because of #2248: sketch curve may produce several edges, + // but #2401 - on stable labels + NCollection_Map aUsedIDMap; // already used lab tags for placement of shapes + for(int a = 0; a < aSubNum; a++) { FeaturePtr aSub = aComposite->subFeature(a); const std::list >& aResults = aSub->results(); @@ -328,29 +505,7 @@ int Model_ResultConstruction::select(const std::shared_ptr& theSu if (!aConstr->shape()) { continue; } - if (aShapeType == TopAbs_VERTEX) { - if (aConstr->shape()->isVertex()) { // compare vertices positions - const TopoDS_Shape& aVertex = aConstr->shape()->impl(); - gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVertex)); - if (aPnt.IsEqual(aVertexPos, Precision::Confusion())) { - aRefs->Add(aComposite->subFeatureId(a)); - aSubNames[aComposite->subFeatureId(a)] = Model_SelectionNaming::shortName(aConstr); - } - } else { // get first or last vertex of the edge: last is stored with additional delta - const TopoDS_Shape& anEdge = aConstr->shape()->impl(); - int aDelta = kSTART_VERTEX_DELTA; - for(TopExp_Explorer aVExp(anEdge, TopAbs_VERTEX); aVExp.More(); aVExp.Next()) { - gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVExp.Current())); - if (aPnt.IsEqual(aVertexPos, Precision::Confusion())) { - aRefs->Add(aDelta + aComposite->subFeatureId(a)); - aSubNames[aDelta + aComposite->subFeatureId(a)] = - Model_SelectionNaming::shortName(aConstr, aDelta / kSTART_VERTEX_DELTA); - break; - } - aDelta += kSTART_VERTEX_DELTA; - } - } - } else { + if (aShapeType != TopAbs_VERTEX) { if (aConstr->shape()->isEdge()) { const TopoDS_Shape& aResShape = aConstr->shape()->impl(); TopoDS_Edge anEdge = TopoDS::Edge(aResShape); @@ -359,8 +514,6 @@ int Model_ResultConstruction::select(const std::shared_ptr& theSu Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); if (allCurves.Contains(aCurve)) { int anID = aComposite->subFeatureId(a); - aRefs->Add(anID); - aSubNames[anID] = Model_SelectionNaming::shortName(aConstr); if (aShapeType != TopAbs_EDGE) { // face needs the sub-edges on sub-labels // add edges to sub-label to support naming for edges selection TopExp_Explorer anEdgeExp(aSubShape, TopAbs_EDGE); @@ -369,19 +522,14 @@ int Model_ResultConstruction::select(const std::shared_ptr& theSu Standard_Real aFirst, aLast; Handle(Geom_Curve) aFaceCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); if (aFaceCurve == aCurve) { - int anOrient = Model_SelectionNaming::edgeOrientation(aSubShape, anEdge); - anOrientations[anID] = anOrient; - + while(aUsedIDMap.Contains(anID)) + anID += 100000; + aUsedIDMap.Add(anID); TDF_Label aSubLab = aLab.FindChild(anID); - std::string aName = "Edge-" + Model_SelectionNaming::shortName(aConstr, 0); - TNaming_Builder aBuilder(aSubLab); - if (isSelectionMode) - aBuilder.Select(anEdge, anEdge); - else - aBuilder.Generated(anEdge); - aMyDoc->addNamingName(aSubLab, aName.c_str()); - TDataStd_Name::Set(aSubLab, aName.c_str()); + std::string aFullNameSub = fullName(aComposite, anEdge); + saveSubName(aComposite, aSubLab, isSelectionMode, anEdge, aMyDoc, aFullNameSub); + int anOrient = Model_SelectionNaming::edgeOrientation(aSubShape, anEdge); if (anOrient != 0) { // store the orientation of edge relatively to face if needed TDataStd_Integer::Set(aSubLab, anOrient); @@ -390,25 +538,15 @@ int Model_ResultConstruction::select(const std::shared_ptr& theSu } } else { // put vertices of the selected edge to sub-labels // add edges to sub-label to support naming for edges selection - int aDelta = kSTART_VERTEX_DELTA; - int aTagIndex = anID + kSTART_VERTEX_DELTA; for(TopExp_Explorer anEdgeExp(aSubShape, TopAbs_VERTEX); - anEdgeExp.More(); - anEdgeExp.Next(), - aTagIndex += kSTART_VERTEX_DELTA, - aDelta += kSTART_VERTEX_DELTA) { - TopoDS_Vertex aV = TopoDS::Vertex(anEdgeExp.Current()); - - TDF_Label aSubLab = aLab.FindChild(aTagIndex); - std::string aName = "Vertex-" - + Model_SelectionNaming::shortName(aConstr, aDelta / kSTART_VERTEX_DELTA); - TNaming_Builder aBuilder(aLab); - if (isSelectionMode) - aBuilder.Select(aV, aV); - else - aBuilder.Generated(aV); - aMyDoc->addNamingName(aLab, aName.c_str()); - TDataStd_Name::Set(aLab, aName.c_str()); + anEdgeExp.More(); anEdgeExp.Next()) { + TopoDS_Vertex aV = TopoDS::Vertex(anEdgeExp.Current()); + while(aUsedIDMap.Contains(anID)) + anID += 100000; + aUsedIDMap.Add(anID); + TDF_Label aSubLab = aLab.FindChild(anID); + std::string aFullNameSub = fullName(aComposite, aV); + saveSubName(aComposite, aSubLab, isSelectionMode, aV, aMyDoc, aFullNameSub); } } } @@ -417,8 +555,9 @@ int Model_ResultConstruction::select(const std::shared_ptr& theSu } } } + std::string aFullName = fullName(aComposite, aSubShape, aRefs); // store the selected as primitive - registerSubShape(aLab, aSubShape, 0, aMyDoc, isSelectionMode, anOrientations, aSubNames, aRefs); + registerSubShape(aLab, aSubShape, aFullName, 0, aMyDoc, isSelectionMode); return anIndex - 1; } @@ -457,19 +596,62 @@ bool Model_ResultConstruction::update(const int theIndex, if (!isInfinite()) { // update all faces named by the whole result bool aRes = true; - Handle(TDataStd_IntegerArray) anArray; - if (aLab.FindAttribute(TDataStd_IntegerArray::GetID(), anArray)) { - for(int anIndex = 0; anIndex <= anArray->Upper(); anIndex++) { - if (!update(anArray->Value(anIndex), theExtDoc, theModified)) - aRes = false; + Handle(TDataStd_IntPackedMap) anIndices; + if (aLab.FindAttribute(TDataStd_IntPackedMap::GetID(), anIndices)) { + NCollection_Map aFaces; // collect faces, updated in the tree + TColStd_MapIteratorOfPackedMapOfInteger anIndexIter(anIndices->GetMap()); + Handle(TColStd_HPackedMapOfInteger) aNewPackedMap = + new TColStd_HPackedMapOfInteger; // with only faces that are ok + // iterate to find existing faces, updated + for(; anIndexIter.More(); anIndexIter.Next()) { + if (update(anIndexIter.Key(), theExtDoc, theModified)) { + GeomShapePtr aFace = shape(anIndexIter.Key(), theExtDoc); + if (!aFaces.Contains(aFace->impl())) { + aNewPackedMap->ChangeMap().Add(anIndexIter.Key()); + aFaces.Add(aFace->impl()); + } + } } + // then iterate all existing faces to find new faces + int aCurrentFacesNum = facesNum(); + for(int a = 0; a < aCurrentFacesNum; a++) { + GeomShapePtr aFace = face(a); + if (!aFaces.Contains(aFace->impl())) { + // add this one + int aNewFaceIndex = select(aFace, theExtDoc, -1); + if (aNewFaceIndex > 0) { + aNewPackedMap->ChangeMap().Add(aNewFaceIndex); + } + } + } + anIndices->ChangeMap(aNewPackedMap); } return aRes; } else { + // check is this modified or not + std::shared_ptr aNewShape = shape(); + TopoDS_Shape anOldSh; + Handle(TNaming_NamedShape) aNS; + if (aLab.FindAttribute(TNaming_NamedShape::GetID(), aNS)) { + anOldSh = aNS->Get(); + } + if (aNewShape.get()) { + if (anOldSh.IsNull()) + theModified = true; + else { + std::shared_ptr anOldShape(new GeomAPI_Shape); + anOldShape->setImpl(new TopoDS_Shape(anOldSh)); + theModified = !anOldShape->isEqual(aNewShape); + } + } + else if (!anOldSh.IsNull()) { + theModified = true; + } + // For correct naming selection, put the shape into the naming structure. // It seems sub-shapes are not needed: only this shape is (and can be ) selected. TNaming_Builder aBuilder(aLab); - aBuilder.Generated(shape()->impl()); + aBuilder.Generated(aNewShape->impl()); } return shape() && !shape()->isNull(); } @@ -485,7 +667,7 @@ bool Model_ResultConstruction::update(const int theIndex, Handle(TDF_Reference) aRef; if (aLab.FindAttribute(TDF_Reference::GetID(), aRef)) { int aFaceIndex = aRef->Get().Tag(); - // don't check selection ,since face may disappear, but the shape stays correct + // don't check selection since face may disappear, but the shape stays correct Model_ResultConstruction::update(aFaceIndex, theExtDoc, theModified); } // getting a type of selected shape