X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_ResultConstruction.cpp;h=5f5d588ee22180e90dded0a2437a8f4ba2d7c872;hb=e8fce5fe73fee1a8ea2929934a7e6f71bd1e3eb5;hp=8fc24dd9592e97cf3d5b7b4419ba891cd71c04f1;hpb=9fcb5e33430824bcf0bca3e1beb11e6f8744d0f5;p=modules%2Fshaper.git diff --git a/src/Model/Model_ResultConstruction.cpp b/src/Model/Model_ResultConstruction.cpp index 8fc24dd95..5f5d588ee 100644 --- a/src/Model/Model_ResultConstruction.cpp +++ b/src/Model/Model_ResultConstruction.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2021 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 @@ -12,10 +12,9 @@ // // 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 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or -// email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include @@ -23,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -48,26 +48,66 @@ #include +typedef NCollection_IndexedDataMap MapFaceToEdgeIndices; + +/// Convert each edge of sketch to corresponding integer value +/// \param[in] theComposite sketch feature +/// \param[out] theCurvesIndices map curve to its index +/// \param[out] theEdgesIndices indexed edge +/// \param[out] theEdgesNames indexed name for edge +static void indexingSketchEdges( + const CompositeFeaturePtr& theComposite, + NCollection_DataMap& theCurvesIndices, + NCollection_DataMap& theEdgesIndices, + std::map& theEdgesNames); + +/// Convert each face to the list of indices of its edges +/// \param[in] theFaces list of faces to proceed +/// \param[in] theCurvesIndices index of each curve +/// \param[out] theFaceEdges map face to indices of its edges +static void faceToEdgeIndices( + const ListOfShape& theFaces, + const NCollection_DataMap& theCurvesIndices, + MapFaceToEdgeIndices& theFaceEdges); + +/// Assign faces to tags for the specified label +/// \param theDocument current document +/// \param theShapeLabel label to store shapes +/// \param theName name of the object +/// \param theShape shape to be stored to the label +/// \param theFacesOrder faces to be assigned to specified tag +/// \param theUnorderedFaces faces which may be stored to any tag +/// \param theFaceEdges indices of edges for each face +/// \param theEdgesIndices indices of edges +/// \param theEdgesNames named of edges +static void storeFacesOnLabel(std::shared_ptr& theDocument, + TDF_Label& theShapeLabel, + const std::wstring& theName, + const TopoDS_Shape& theShape, + NCollection_DataMap& theFacesOrder, + NCollection_List& theUnorderedFaces, + const MapFaceToEdgeIndices& theFaceEdges, + const NCollection_DataMap& theEdgesIndices, + const std::map& theEdgesNames); + // identifier of the infinite result Standard_GUID kIS_INFINITE("dea8cc5a-53f2-49c1-94e8-a947bed20a9f"); // identifier of the result not in history Standard_GUID kIS_IN_HISTORY("a9aec01c-805e-44d1-b5d2-a63f06522f8a"); - void Model_ResultConstruction::colorConfigInfo(std::string& theSection, std::string& theName, std::string& theDefault) { theSection = "Visualization"; - theName = "result_construction_color"; + theName = RESULT_COLOR_NAME(); theDefault = DEFAULT_COLOR(); } void Model_ResultConstruction::setShape(std::shared_ptr theShape) { if (myShape != theShape) { - if (!isInfinite()) - storeShape(theShape); + storeShape(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); @@ -81,19 +121,19 @@ std::shared_ptr Model_ResultConstruction::shape() return myShape; } -static std::string shortName( +static std::wstring shortName( std::shared_ptr& theConstr) { - std::string aName = theConstr->data()->name(); + std::wstring aName = theConstr->data()->name(); // remove "-", "/" and "&" command-symbols aName.erase(std::remove(aName.begin(), aName.end(), '-'), aName.end()); aName.erase(std::remove(aName.begin(), aName.end(), '/'), aName.end()); aName.erase(std::remove(aName.begin(), aName.end(), '&'), aName.end()); // remove the last 's', 'e', 'f' and 'r' symbols: // they are used as markers of start/end/forward/reversed indicators - static const std::string aSyms("sefr"); - std::string::iterator aSuffix = aName.end() - 1; - while(aSyms.find(*aSuffix) != std::string::npos) { + static const std::wstring aSyms(L"sefr"); + std::wstring::iterator aSuffix = aName.end() - 1; + while(aSyms.find(*aSuffix) != std::wstring::npos) { --aSuffix; } aName.erase(aSuffix + 1, aName.end()); @@ -130,7 +170,7 @@ bool Model_ResultConstruction::updateShape() // just restore shape GeomShapePtr aGShape(new GeomAPI_Shape); aGShape->setImpl(new TopoDS_Shape(aShape)); - myShape = aGShape; // restore the sketch sub-components + myShape = GeomAPI_Tools::getTypedShape(aGShape); // restore the sketch sub-components return true; } } @@ -182,7 +222,7 @@ void Model_ResultConstruction::setInfinite(const bool theInfinite) } } -int Model_ResultConstruction::facesNum(const bool theUpdateNaming) +int Model_ResultConstruction::facesNum(const bool /*theUpdateNaming*/) { int aResult = 0; std::shared_ptr aData = std::dynamic_pointer_cast(data()); @@ -218,16 +258,19 @@ std::shared_ptr Model_ResultConstruction::face(const int theIndex) return aResult; } -void Model_ResultConstruction::setIsConcealed(const bool theValue) +void Model_ResultConstruction::setIsConcealed(const bool theValue, const bool theForced) { - // do nothing: the construction element is never concealed + // the construction element may be concealed only by "delete" feature + if (!theValue || theForced) { + ModelAPI_ResultConstruction::setIsConcealed(theValue, theForced); + } } void Model_ResultConstruction::storeShape(std::shared_ptr theShape) { std::shared_ptr aData = std::dynamic_pointer_cast(data()); if (aData && aData->isValid()) { - std::string aMyName = data()->name(); + std::wstring aMyName = data()->name(); TDF_Label aShapeLab = aData->shapeLab(); if (!theShape.get() || theShape->isNull()) { aShapeLab.ForgetAllAttributes(); @@ -237,7 +280,7 @@ void Model_ResultConstruction::storeShape(std::shared_ptr theShap std::shared_ptr aMyDoc = std::dynamic_pointer_cast(document()); const TopoDS_Shape& aShape = theShape->impl(); - if (aShape.ShapeType() == TopAbs_VERTEX) { + if (isInfinite() || aShape.ShapeType() == TopAbs_VERTEX) { aShapeLab.ForgetAllAttributes(); // clear all previously stored TNaming_Builder aBuilder(aShapeLab); aBuilder.Generated(aShape); @@ -251,9 +294,10 @@ void Model_ResultConstruction::storeShape(std::shared_ptr theShap TopExp_Explorer anExp(aShape, TopAbs_VERTEX); for(int anIndex = 1; anExp.More(); anExp.Next(), anIndex++) { TDF_Label aSubLab = aShapeLab.FindChild(anIndex); - TNaming_Builder aBuilder(aSubLab); - aBuilder.Generated(anExp.Current()); - std::string aVertexName = aMyName + "_" + (anIndex == 1 ? "StartVertex" : "EndVertex"); + TNaming_Builder aSubBuilder(aSubLab); + aSubBuilder.Generated(anExp.Current()); + std::wstring aVertexName = aMyName + L"_" + + (anIndex == 1 ? L"StartVertex" : L"EndVertex"); TDataStd_Name::Set(aSubLab, aVertexName.c_str()); aMyDoc->addNamingName(aSubLab, aVertexName); } @@ -273,57 +317,20 @@ void Model_ResultConstruction::storeShape(std::shared_ptr theShap // collect indices of curves of current composite NCollection_DataMap aCurvesIndices; NCollection_DataMap anEdgeIndices; - std::map aComponentsNames; // names of components that lay on index - const int aSubNum = aComposite->numberOfSubs(); - for (int a = 0; a < aSubNum; a++) { - FeaturePtr aSub = aComposite->subFeature(a); - const std::list >& aResults = aSub->results(); - std::list >::const_iterator aRes = aResults.cbegin(); - for (; aRes != aResults.cend(); aRes++) { - ResultConstructionPtr aConstr = - std::dynamic_pointer_cast(*aRes); - if (aConstr->shape() && aConstr->shape()->isEdge()) { - TopoDS_Edge anEdge = TopoDS::Edge(aConstr->shape()->impl()); - Standard_Real aFirst, aLast; - Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); - aCurvesIndices.Bind(aCurve, a); - anEdgeIndices.Bind(a, anEdge); - aComponentsNames[a] = shortName(aConstr); - } - } - } + std::map aComponentsNames; // names of components that lay on index + indexingSketchEdges(aComposite, aCurvesIndices, anEdgeIndices, aComponentsNames); - std::list > aFaces; - GeomAlgoAPI_SketchBuilder::createFaces(aWirePtr->origin(), aWirePtr->dirX(), - aWirePtr->norm(), aWirePtr, aFaces); + GeomAlgoAPI_SketchBuilder aSketchBuilder(aWirePtr->origin(), aWirePtr->dirX(), + aWirePtr->norm(), aWirePtr); + const ListOfShape& aFaces = aSketchBuilder.faces(); // order is important to store faces in the same order if sketch is created from scratch - NCollection_IndexedDataMap aNewIndices; // edges indices - std::list >::iterator aFIter = aFaces.begin(); - for (; aFIter != aFaces.end(); aFIter++) { - std::shared_ptr aFace(new GeomAPI_Face(*aFIter)); - // put them to a label, trying to keep the same faces on the same labels - if (aFace.get() && !aFace->isNull()) { - TopoDS_Face aTopoFace = TopoDS::Face(aFace->impl()); - aNewIndices.Add(aTopoFace, TColStd_ListOfInteger()); - // keep new indices of sub-elements used in this face - for (TopExp_Explorer anEdges(aTopoFace, TopAbs_EDGE); anEdges.More(); anEdges.Next()) { - TopoDS_Edge anEdge = TopoDS::Edge(anEdges.Current()); - Standard_Real aFirst, aLast; - Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); - if (aCurvesIndices.IsBound(aCurve)) { - int anIndex = aCurvesIndices.Find(aCurve); - if ((aFirst > aLast) != (anEdge.Orientation() == TopAbs_REVERSED)) - anIndex = -anIndex; - aNewIndices.ChangeFromKey(aTopoFace).Append(anIndex); - } - } - } - } + MapFaceToEdgeIndices aNewIndices; // edges indices + faceToEdgeIndices(aFaces, aCurvesIndices, aNewIndices); + NCollection_DataMap aFacesOrder; // faces -> tag where they must be set NCollection_List anUnorderedFaces; // faces that may be located at any index // searching for the best new candidate to old location - NCollection_IndexedDataMap::Iterator - aNewIter(aNewIndices); + MapFaceToEdgeIndices::Iterator aNewIter(aNewIndices); for (; aNewIter.More(); aNewIter.Next()) { double aBestFound = 0, aBestNotFound = 1.e+100; int aBestTag = 0; @@ -349,7 +356,7 @@ void Model_ResultConstruction::storeShape(std::shared_ptr theShap aNotFound += 1.; } } - if (aNotFound < aBestNotFound) { + if (aNotFound <= aBestNotFound) { // less and equal to find better "found": #2859 if (aFound > aBestFound) { aBestNotFound = aNotFound; aBestFound = aFound; @@ -363,82 +370,220 @@ void Model_ResultConstruction::storeShape(std::shared_ptr theShap anUnorderedFaces.Append(aNewIter.Key()); } } - aShapeLab.ForgetAllAttributes(); // clear all previously stored - TDataStd_Name::Set(aShapeLab, aMyName.c_str()); // restore name forgotten - TNaming_Builder aBuilder(aShapeLab); // store the compound to get it ready on open of document - aBuilder.Generated(aShape); - aMyDoc->addNamingName(aShapeLab, aMyName); - // set new faces to the labels - int aCurrentTag = 1; - NCollection_List::Iterator anUnordered(anUnorderedFaces); - for(int aCurrentTag = 1; !aFacesOrder.IsEmpty() || anUnordered.More(); aCurrentTag++) { - TopoDS_Face aFaceToPut; - if (aFacesOrder.IsBound(aCurrentTag)) { - aFaceToPut = aFacesOrder.Find(aCurrentTag); - aFacesOrder.UnBind(aCurrentTag); - } else if (anUnordered.More()){ - aFaceToPut = anUnordered.Value(); - anUnordered.Next(); - } + storeFacesOnLabel(aMyDoc, aShapeLab, aMyName, aShape, aFacesOrder, anUnorderedFaces, + aNewIndices, anEdgeIndices, aComponentsNames); + } + } +} - if (!aFaceToPut.IsNull()) { - TopTools_MapOfShape aFaceEdges; - for(TopExp_Explorer anEdges(aFaceToPut, TopAbs_EDGE); anEdges.More(); anEdges.Next()) { - aFaceEdges.Add(anEdges.Current()); - } +void Model_ResultConstruction::setFacesOrder(const std::list& theFaces) +{ + std::shared_ptr aData = std::dynamic_pointer_cast(data()); + if (aData && aData->isValid()) { + std::wstring aMyName = data()->name(); + TDF_Label aShapeLab = aData->shapeLab(); + GeomShapePtr aResShape = shape(); + if (!aResShape.get() || aResShape->isNull()) { + // do nothing + return; + } + std::shared_ptr aMyDoc = + std::dynamic_pointer_cast(document()); + const TopoDS_Shape& aShape = aResShape->impl(); + if (aShape.ShapeType() != TopAbs_VERTEX && + aShape.ShapeType() != TopAbs_EDGE) { + ResultPtr aThisPtr = std::dynamic_pointer_cast(data()->owner()); + FeaturePtr aThisFeature = aMyDoc->feature(aThisPtr); + CompositeFeaturePtr aComposite = + std::dynamic_pointer_cast(aThisFeature); + if (!aComposite || aComposite->numberOfSubs() == 0) + return; // unknown case + // collect indices of curves of current composite + NCollection_DataMap aCurvesIndices; + NCollection_DataMap anEdgeIndices; + std::map aComponentsNames; // names of components that lay on index + indexingSketchEdges(aComposite, aCurvesIndices, anEdgeIndices, aComponentsNames); + + ListOfShape aFaces; + NCollection_DataMap aFacesOrder; // faces -> tag where they must be set + NCollection_List anUnorderedFaces; // unordered faces are empty in this case + int aTagId = 0; + for (std::list::const_iterator aFIt = theFaces.begin(); + aFIt != theFaces.end(); ++aFIt) { + aFaces.push_back(*aFIt); + aFacesOrder.Bind(++aTagId, (*aFIt)->impl()); + } + + MapFaceToEdgeIndices aNewIndices; // edges indices + faceToEdgeIndices(aFaces, aCurvesIndices, aNewIndices); + + storeFacesOnLabel(aMyDoc, aShapeLab, aMyName, aShape, aFacesOrder, anUnorderedFaces, + aNewIndices, anEdgeIndices, aComponentsNames); + } + } +} + +// ========================== Auxiliary functions ========================================= + +void storeFacesOnLabel(std::shared_ptr& theDocument, + TDF_Label& theShapeLabel, + const std::wstring& theName, + const TopoDS_Shape& theShape, + NCollection_DataMap& theFacesOrder, + NCollection_List& theUnorderedFaces, + const MapFaceToEdgeIndices& theFaceEdges, + const NCollection_DataMap& theEdgesIndices, + const std::map& theEdgesNames) +{ + theShapeLabel.ForgetAllAttributes(); // clear all previously stored + TDataStd_Name::Set(theShapeLabel, theName.c_str()); // restore name forgotten + TNaming_Builder aBuilder(theShapeLabel); // store the compound to get it ready on open of document + aBuilder.Generated(theShape); + theDocument->addNamingName(theShapeLabel, theName); + // set new faces to the labels + NCollection_List::Iterator anUnordered(theUnorderedFaces); + for (int aCurrentTag = 1; !theFacesOrder.IsEmpty() || anUnordered.More(); aCurrentTag++) { + TopoDS_Face aFaceToPut; + if (theFacesOrder.IsBound(aCurrentTag)) { + aFaceToPut = theFacesOrder.Find(aCurrentTag); + theFacesOrder.UnBind(aCurrentTag); + } + else if (anUnordered.More()) { + aFaceToPut = anUnordered.Value(); + anUnordered.Next(); + } + + if (aFaceToPut.IsNull()) + continue; + + TopTools_MapOfShape aFaceEdges; + for (TopExp_Explorer anEdges(aFaceToPut, TopAbs_EDGE); anEdges.More(); anEdges.Next()) + aFaceEdges.Add(anEdges.Current()); - TDF_Label aLab = aShapeLab.FindChild(aCurrentTag); - TNaming_Builder aFaceBuilder(aLab); - aFaceBuilder.Generated(aFaceToPut); - // store also indices of the new face edges - Handle(TDataStd_IntPackedMap) aNewMap = TDataStd_IntPackedMap::Set(aLab); - const TColStd_ListOfInteger& aNewInd = aNewIndices.FindFromKey(aFaceToPut); - std::stringstream aName; - aName<<"Face"; - TopExp_Explorer aPutEdges(aFaceToPut, TopAbs_EDGE); - TNaming_Builder* anEdgesBuilder = 0; - for(TColStd_ListOfInteger::Iterator anIter(aNewInd); anIter.More(); anIter.Next()) { - int anIndex = anIter.Value(); - int aModIndex = anIndex > 0 ? anIndex : -anIndex; - aNewMap->Add(anIndex); - aName<<"-"< 0) - aName<<"f"; - else - aName<<"r"; - // collect all edges of the face which are modified in sub-label of the face - if (anEdgeIndices.IsBound(aModIndex) && - !aFaceEdges.Contains(anEdgeIndices.Find(aModIndex))) { - if (!anEdgesBuilder) { - TDF_Label anEdgesLabel = aLab.FindChild(1); - anEdgesBuilder = new TNaming_Builder(anEdgesLabel); - std::ostringstream aSubName; - // tag is needed for Test1922 to distinguish sub-edges of different faces - aSubName<<"SubEdge_"<Modify(anEdgeIndices.Find(aModIndex), aPutEdges.Current()); + TDF_Label aLab = theShapeLabel.FindChild(aCurrentTag); + TNaming_Builder aFaceBuilder(aLab); + aFaceBuilder.Generated(aFaceToPut); + // store also indices of the new face edges + Handle(TDataStd_IntPackedMap) aNewMap = TDataStd_IntPackedMap::Set(aLab); + const TColStd_ListOfInteger& aNewInd = theFaceEdges.FindFromKey(aFaceToPut); + std::wstringstream aName; + aName<<"Face"; + TopExp_Explorer aPutEdges(aFaceToPut, TopAbs_EDGE); + TNaming_Builder *anEdgesBuilder = 0, *aVerticesBuilder = 0; + for(TColStd_ListOfInteger::Iterator anIter(aNewInd); anIter.More(); anIter.Next()) { + int anIndex = anIter.Value(); + int aModIndex = anIndex > 0 ? anIndex : -anIndex; + aNewMap->Add(anIndex); + aName<<"-"<second; + if (anIter.Value() > 0) + aName<<"f"; + else + aName<<"r"; + // collect all edges of the face which are modified in sub-label of the face + if (theEdgesIndices.IsBound(aModIndex) && + !aFaceEdges.Contains(theEdgesIndices.Find(aModIndex))) { + if (!anEdgesBuilder) { + TDF_Label anEdgesLabel = aLab.FindChild(1); + anEdgesBuilder = new TNaming_Builder(anEdgesLabel); + std::ostringstream aSubName; + // tag is needed for Test1922 to distinguish sub-edges of different faces + aSubName<<"SubEdge_"<Modify(theEdgesIndices.Find(aModIndex), aPutEdges.Current()); + } + // put also modified vertices, otherwise vertex of original edge has no history + if (theEdgesIndices.IsBound(aModIndex)) { + TopExp_Explorer aVExpOld(theEdgesIndices.Find(aModIndex), TopAbs_VERTEX); + TopExp_Explorer aVExpNew(aPutEdges.Current(), TopAbs_VERTEX); + for(; aVExpNew.More() && aVExpOld.More(); aVExpNew.Next(), aVExpOld.Next()) { + if (!aVExpOld.Current().IsSame(aVExpNew.Current())) { + if (!aVerticesBuilder) { + TDF_Label aVertLabel = aLab.FindChild(2); + aVerticesBuilder = new TNaming_Builder(aVertLabel); + std::ostringstream aSubName; + // tag is needed for Test1922 to distinguish sub-edges of different faces + aSubName<<"SubVertex_"<addNamingName(aLab, aName.str()); - // put also wires to sub-labels to correctly select them instead of collection by edges - int aWireTag = 2; // first tag is for SubEdge-s - for(TopExp_Explorer aWires(aFaceToPut, TopAbs_WIRE); aWires.More(); aWires.Next()) { - TDF_Label aWireLab = aLab.FindChild(aWireTag); - TNaming_Builder aWireBuilder(aWireLab); - aWireBuilder.Generated(aWires.Current()); - std::ostringstream aWireName; - aWireName< 2) - aWireName<<"_"<addNamingName(aWireLab, aWireName.str()); - aWireTag++; + aVerticesBuilder->Modify(aVExpOld.Current(), aVExpNew.Current()); + } } } + aPutEdges.Next(); + } + if (anEdgesBuilder) + delete anEdgesBuilder; + if (aVerticesBuilder) + delete aVerticesBuilder; + TDataStd_Name::Set(aLab, TCollection_ExtendedString(aName.str().c_str())); + theDocument->addNamingName(aLab, aName.str()); + // put also wires to sub-labels to correctly select them instead of collection by edges + int aWireTag = 3; // first tag is for SubEdge-s, second - for vertices + for(TopExp_Explorer aWires(aFaceToPut, TopAbs_WIRE); aWires.More(); aWires.Next()) { + TDF_Label aWireLab = aLab.FindChild(aWireTag); + TNaming_Builder aWireBuilder(aWireLab); + aWireBuilder.Generated(aWires.Current()); + std::wostringstream aWireName; + aWireName< 3) + aWireName<<"_"<addNamingName(aWireLab, aWireName.str()); + aWireTag++; + } + } +} + +void indexingSketchEdges(const CompositeFeaturePtr& theComposite, + NCollection_DataMap& theCurvesIndices, + NCollection_DataMap& theEdgesIndices, + std::map& theEdgesNames) +{ + 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(); + for (; aRes != aResults.cend(); aRes++) { + ResultConstructionPtr aConstr = + std::dynamic_pointer_cast(*aRes); + if (aConstr->shape() && aConstr->shape()->isEdge()) { + TopoDS_Edge anEdge = TopoDS::Edge(aConstr->shape()->impl()); + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + theCurvesIndices.Bind(aCurve, a); + theEdgesIndices.Bind(a, anEdge); + theEdgesNames[a] = shortName(aConstr); + } + } + } +} + +void faceToEdgeIndices(const ListOfShape& theFaces, + const NCollection_DataMap& theCurvesIndices, + MapFaceToEdgeIndices& theFaceEdges) +{ + std::list >::const_iterator aFIter = theFaces.begin(); + for (; aFIter != theFaces.end(); aFIter++) { + std::shared_ptr aFace(new GeomAPI_Face(*aFIter)); + // put them to a label, trying to keep the same faces on the same labels + if (aFace.get() && !aFace->isNull()) { + TopoDS_Face aTopoFace = TopoDS::Face(aFace->impl()); + theFaceEdges.Add(aTopoFace, TColStd_ListOfInteger()); + // keep new indices of sub-elements used in this face + for (TopExp_Explorer anEdges(aTopoFace, TopAbs_EDGE); anEdges.More(); anEdges.Next()) { + TopoDS_Edge anEdge = TopoDS::Edge(anEdges.Current()); + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + if (theCurvesIndices.IsBound(aCurve)) { + int anIndex = theCurvesIndices.Find(aCurve); + if ((aFirst > aLast) != (anEdge.Orientation() == TopAbs_REVERSED)) + anIndex = -anIndex; + theFaceEdges.ChangeFromKey(aTopoFace).Append(anIndex); + } + } } } }