+ // 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<TopoDS_Shape>());
+ 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);
+ }
+ }
+ }
+ }
+ NCollection_DataMap<int, TopoDS_Face> aFacesOrder; // faces -> tag where they must be set
+ NCollection_List<TopoDS_Face> anUnorderedFaces; // faces that may be located at any index
+ // searching for the best new candidate to old location
+ NCollection_IndexedDataMap<TopoDS_Face, TColStd_ListOfInteger>::Iterator
+ aNewIter(aNewIndices);
+ for (; aNewIter.More(); aNewIter.Next()) {
+ double aBestFound = 0, aBestNotFound = 1.e+100;
+ int aBestTag = 0;
+ const TColStd_ListOfInteger& aNewInd = aNewIter.Value();
+ // old faces indices where they where located
+ TDF_ChildIDIterator anOldIter(aShapeLab, TDataStd_IntPackedMap::GetID());
+ for (; anOldIter.More(); anOldIter.Next()) {
+ int aTag = anOldIter.Value()->Label().Tag();
+ if (aFacesOrder.IsBound(aTag))
+ continue; // already found a best candidate
+ Handle(TDataStd_IntPackedMap) anOldIndices =
+ Handle(TDataStd_IntPackedMap)::DownCast(anOldIter.Value());
+ double aFound = 0, aNotFound = 0;
+ TColStd_ListOfInteger::Iterator aNewIndIter(aNewInd);
+ for (; aNewIndIter.More(); aNewIndIter.Next()) {
+ if (anOldIndices->Contains(aNewIndIter.Value())) {
+ aFound += 1.;
+ }
+ else if (anOldIndices->Contains(-aNewIndIter.Value())) { // different orientation
+ aFound += 0.001;
+ }
+ else {
+ aNotFound += 1.;
+ }
+ }
+ if (aNotFound < aBestNotFound) {
+ if (aFound > aBestFound) {
+ aBestNotFound = aNotFound;
+ aBestFound = aFound;
+ aBestTag = aTag;
+ }
+ }
+ }
+ if (aBestTag != 0) { // found an appropriate face
+ aFacesOrder.Bind(aBestTag, aNewIter.Key());
+ } else {
+ 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<TopoDS_Face>::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();
+ }
+
+ if (!aFaceToPut.IsNull()) {
+ 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<<"-"<<aComponentsNames[aModIndex];
+ 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 (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 subedges of different faces
+ aSubName<<"SubEdge_"<<aCurrentTag;
+ TDataStd_Name::Set(anEdgesLabel, aSubName.str().c_str());
+ }
+ anEdgesBuilder->Modify(anEdgeIndices.Find(aModIndex), aPutEdges.Current());
+ }
+ aPutEdges.Next();
+ }
+ TDataStd_Name::Set(aLab, TCollection_ExtendedString(aName.str().c_str()));
+ aMyDoc->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<<aName.str()<<"_wire";
+ if (aWireTag > 2)
+ aWireName<<"_"<<aWireTag - 1;
+ TDataStd_Name::Set(aWireLab, aWireName.str().c_str());
+ aMyDoc->addNamingName(aWireLab, aWireName.str());
+ aWireTag++;
+ }
+ }