// Created on: 1997-09-03 // Created by: Yves FRICAUD // Copyright (c) 1997-1999 Matra Datavision // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include IMPLEMENT_STANDARD_RTTIEXT(TNaming_Naming,TDF_Attribute) // #include typedef NCollection_Map TNaming_MapOfShape; typedef TNaming_MapOfShape::Iterator TNaming_MapIteratorOfMapOfShape; typedef NCollection_DataMap TNaming_DataMapOfShapeMapOfShape; typedef TNaming_DataMapOfShapeMapOfShape::Iterator TNaming_DataMapIteratorOfDataMapOfShapeMapOfShape; // The bug concerns access to a null object in the method Filter(): #define ALLOW_CHILD_NBS //#define MDTV_DEB_CC //#define MDTV_DEB_OR //#define MDTV_DEB_MOD //#define MDTV_OR //#define MDTV_DEB_INNS //#define MDTV_DEB_NBS //#define MDTV_DEB_71 //#define MDTV_DEB_WIN #ifdef OCCT_DEBUG #include #include #include #include #include #include #include #include #include void Print_Entry(const TDF_Label& label) { TCollection_AsciiString entry; TDF_Tool::Entry(label, entry); cout << "LabelEntry = "<< entry << endl; } static void Write(const TopoDS_Shape& shape, const Standard_CString filename) { char buf[256]; if(strlen(filename) > 256) return; strcpy (buf, filename); char* p = buf; while (*p) { if(*p == ':') *p = '-'; p++; } ofstream save (buf); if(!save) cout << "File " << buf << " was not created: rdstate = " << save.rdstate() << endl; save << "DBRep_DrawableShape" << endl << endl; if(!shape.IsNull()) BRepTools::Write(shape, save); save.close(); } void WriteNSOnLabel(const Handle(TNaming_NamedShape) & NS, const TCollection_AsciiString& Nam) { if (!NS.IsNull()) { TCollection_AsciiString entry; TDF_Tool::Entry(NS->Label(), entry); TopoDS_Shape Sh = TNaming_Tool::GetShape (NS); if(!Sh.IsNull()) { TCollection_AsciiString Entry = Nam + entry + ".brep"; Write(Sh, Entry.ToCString()); } else cout << "WriteNSOnLabel>>> TopoDS_Shape IS NULL on Entry = "<< entry << endl; } else cout << "WriteNSOnLabel >>> NamedShape IS NULL" << endl; } #endif //========================================================================================== static Handle(TNaming_NamedShape) BuildName (const TDF_Label& F, TNaming_Scope& MDF, const TopoDS_Shape& S, const TopoDS_Shape& Context, const Handle(TNaming_NamedShape)& Stop, const Standard_Boolean Geometry); //======================================================================= static Standard_Integer RepeatabilityInContext(const TopoDS_Shape& Selection, const TopoDS_Shape& Context); //======================================================================= extern Standard_Boolean IsEqual (const TopoDS_Shape& S1, const TopoDS_Shape& S2); //======================================================================= //function : Solve //purpose : voir avec YFR comment retrouver le bon resulat et le mettre // : dans le NamedShape de L //======================================================================= Standard_Boolean TNaming_Naming::Solve (TDF_LabelMap& Valid) { Handle(TNaming_Naming) subname; for (TDF_ChildIterator it (Label(),Standard_False); it.More(); it.Next()) { #ifdef OCCT_DEBUG_NBS TCollection_AsciiString anEntry; TDF_Tool::Entry(it.Value(), anEntry); cout << "TNaming_Naming::Solve: Label to be solved = " << anEntry << endl; #endif if (it.Value().FindAttribute(TNaming_Naming::GetID(),subname)) { if (!subname->Solve (Valid)) { return Standard_False; // not necessary to continue } } } #ifdef OCCT_DEBUG_CC TDF_MapIteratorOfLabelMap anItr(Valid); cout << "TNaming_Naming::Solve:: Valid label Map" << endl; for (; anItr.More(); anItr.Next()) { const TDF_Label& aLabel = anItr.Key(); TCollection_AsciiString anEntry; TDF_Tool::Entry(aLabel, anEntry); cout << "Label = " << anEntry << endl; } #endif if (Regenerate(Valid)) { if (!Valid.IsEmpty()) Valid.Add(Label()); return Standard_True; } return Standard_False; } //======================================================================= //function : GetID //purpose : //======================================================================= const Standard_GUID& TNaming_Naming::GetID () { static Standard_GUID TNaming_NamingID("c0a19201-5b78-11d1-8940-080009dc3333"); return TNaming_NamingID; } //======================================================================= //function : Insert //purpose : //======================================================================= Handle(TNaming_Naming) TNaming_Naming::Insert (const TDF_Label& under) { Handle(TNaming_Naming) N; TDF_Label child = TDF_TagSource::NewChild(under); N = new TNaming_Naming (); child.AddAttribute (N); return N; } //======================================================================= //function : BuildNS //purpose : returns a new NamedShape, which is built as selection: // : TNaming_Builder::Select("S","S") at the new child label of the label . //======================================================================= static Handle(TNaming_NamedShape) BuildNS (const TDF_Label& F, const TopoDS_Shape& S, const TNaming_NameType& Name) { Handle (TNaming_Naming) Naming = TNaming_Naming::Insert (F); TNaming_Name& theName = Naming->ChangeName(); theName.ShapeType(S.ShapeType()); theName.Shape(S); theName.Orientation(S.Orientation()); theName.Type(Name); TNaming_Builder B(Naming->Label()); B.Select(S,S); return B.NamedShape(); } //======================================================================= //function : FindIndex //purpose : //======================================================================= static Standard_Integer FindIndex(const Handle(TNaming_NamedShape)& NS, const TopoDS_Shape& S) { TDF_LabelList Labels; TopoDS_Shape IS = TNaming_Tool::InitialShape(S,NS->Label(),Labels); Standard_Integer Index = 1; for (TNaming_Iterator itNS(NS); itNS.More(); itNS.Next(),Index++) { if (IS.IsSame(itNS.NewShape())) break; } return Index; } //======================================================================= //function : CompareInGeneration //purpose : returns true, only if the specified NS contains only in // : the "new shapes" set. //======================================================================= static Standard_Boolean CompareInGeneration (const Handle(TNaming_NamedShape)& NS, const TopoDS_Shape& S) { for (TNaming_Iterator it(NS); it.More(); it.Next()) { if (!it.NewShape().IsSame(S)) return 0; } return 1; } //======================================================================= //function : GetShapeEvolutions //purpose : returns Standard_True, if target has parent in source; list contains inheritance chain //======================================================================= static Standard_Boolean GetShapeEvolutions(const TopoDS_Shape& theTarget, // this is changed in recursion const Handle(TNaming_NamedShape)& theSource, TopTools_ListOfShape& aList) // returns list in the backward order { Handle(TNaming_NamedShape) aTarget = TNaming_Tool::NamedShape(theTarget,theSource->Label()); if (!aTarget.IsNull()) { #ifdef OCCT_DEBUG_71 cout <<"GetShapeEvolutions: target NS = "; Print_Entry(aTarget->Label()); cout <<"GetShapeEvolutions: Source NS = "; Print_Entry(theSource->Label()); TCollection_AsciiString aNam("GetShapeEvolutions"); WriteNSOnLabel(aTarget,aNam); #endif if (aTarget->Label() == theSource->Label()) return Standard_True; // check if target is in the source } else return Standard_False; TNaming_Iterator anIter(aTarget); for(;anIter.More();anIter.Next()) { // check all appropriate old shapes of target #ifdef OCCT_DEBUG_71 if(!anIter.OldShape().IsNull()) { Write(anIter.OldShape(), "Target_OldS.brep"); cout <<"Target OldS TS =" <This() <Label()); #ifdef OCCT_DEBUG_71 TCollection_AsciiString aNam("CompareInM_Source"); WriteNSOnLabel(aSource,aNam); #endif } } // searching for 1:n to the same label modifications (in this case current naming is insufficient) TopTools_ListOfShape aList; if (GetShapeEvolutions(S,aSource,aList) && aList.Extent() > 0) { TopTools_ListIteratorOfListOfShape anIter(aList); for(;anIter.More();anIter.Next()) { aResult = TNaming_Tool::NamedShape(anIter.Value(),NS->Label()); if (aResult->Evolution()!=TNaming_MODIFY) { // evolution must be modify, otherwise everything is OK aResult.Nullify(); return aResult; } TopTools_MapOfShape aMap; // collection of the old shapes of the shape from list TNaming_Iterator aNIter1(aResult); for(;aNIter1.More();aNIter1.Next()) { if (aNIter1.NewShape().IsSame(anIter.Value())) {// if isSame aMap.Add(aNIter1.OldShape()); } } TNaming_Iterator aNIter2(aResult); // if some another shapes has oldshape from map, return namedshape with this oldshape for(;aNIter2.More();aNIter2.Next()) { if (aNIter2.NewShape().IsSame(anIter.Value())) continue; if (aMap.Contains(aNIter2.OldShape())) { // if one shape was modified to the two at the shared label, return this one aResult = TNaming_Tool::NamedShape(aNIter2.OldShape(),NS->Label()); if (!aResult.IsNull()) return aResult; } } } aResult.Nullify(); } return aResult; } //======================================================================= static Standard_Boolean FillSMap(const TopoDS_Shape& S, TopTools_MapOfShape& MS) { if(S.IsNull()) return Standard_False; Standard_Boolean isHomogen(Standard_True); TopAbs_ShapeEnum aPrevType(TopAbs_SHAPE); TopoDS_Iterator it(S); for (; it.More(); it.Next()) { const TopAbs_ShapeEnum aType = it.Value().ShapeType(); #ifdef OCCT_DEBUG_CC cout <<"TestSolution_FillMap: S_Type = :" << it.Value().ShapeType() <<" TShape = " << it.Value().TShape()->This() < TopAbs_COMPSOLID) { MS.Add(it.Value()); if(aPrevType == TopAbs_SHAPE) aPrevType = aType; else if(aPrevType != aType) isHomogen = Standard_False; } else if(!FillSMap(it.Value(), MS)) isHomogen = Standard_False; } return isHomogen; } //======================================================================= //function : Compare //purpose : checks naming of the shape in the NamedShape . // : Returns true, if it's correct. Details ==> // : The method takes all modifications of the "NS" (see CurrentShape method), // : which are in the "MDF" (if it's not empty) before shape and check them. // : whether these modifications contain only "S". If yes then the method // : returns true, otherwise it returns false. //======================================================================= static Standard_Boolean Compare (const Handle(TNaming_NamedShape)& NS, const TNaming_Scope& MDF, const Handle(TNaming_NamedShape)& Stop, const TopoDS_Shape& S) { TDF_LabelMap Forbiden; TopTools_IndexedMapOfShape MS; if (!Stop.IsNull()) TNaming_NamingTool::BuildDescendants(Stop,Forbiden); TNaming_NamingTool::CurrentShape(MDF.GetValid(),Forbiden,NS,MS); #ifdef OCCT_DEBUG_NBS Write(S, "Compare_S.brep"); cout << "S: TShape = " <This() <Label().Father(); TNaming_Iterator itLab(Father); if(itLab.More()) SC = itLab.NewShape(); } //======================================================================= //function : NextModif //purpose : //======================================================================= static Handle(TNaming_NamedShape) NextModif(const Handle(TNaming_NamedShape)& NS) { Handle (TNaming_NamedShape) Next; if (!NS.IsNull()) { TNaming_NewShapeIterator it(NS); if (it.More()&& it.IsModification()) Next = it.NamedShape(); } return Next; } //======================================================================= // C1 - cand shape of the father, C2 - shape of rebuild child Naming attr. // (to be Compound of elementary shapes) //======================================================================= static Standard_Boolean IsContSame(const TopoDS_Shape& C1, const TopoDS_Shape& C2) { Standard_Boolean aRes(Standard_False); if(!C1.IsNull() && !C2.IsNull()) { TopTools_MapOfShape aMap; if(FillSMap(C1, aMap)) { aRes = Standard_True; TopoDS_Iterator it(C2); for(;it.More();it.Next()) { if(!aMap.Contains(it.Value())) { aRes = Standard_False; break; } } } } return aRes; } //======================================================================= // Identifies the case when Filter haven't sense because of multiplicity //======================================================================= static Standard_Boolean IsMultipleCase(const TopoDS_Shape& S, const TopoDS_Shape& Context, const TopTools_MapOfShape& Neighbourgs) { TopTools_IndexedDataMapOfShapeListOfShape aDM; TNaming_MapOfShape aM; TopTools_MapOfShape aNbs; aNbs.Assign(Neighbourgs); aNbs.Add(S); TNaming_DataMapOfShapeMapOfShape aDMM; TopExp::MapShapesAndAncestors (Context, TopAbs_EDGE, TopAbs_FACE, aDM); TopTools_MapIteratorOfMapOfShape it(aNbs); for(;it.More();it.Next()) { if(aDM.Contains(it.Key())) { TNaming_MapOfShape aMS; const TopTools_ListOfShape& aL = aDM.FindFromKey(it.Key()); TopTools_ListIteratorOfListOfShape lit(aL); for(;lit.More();lit.Next()) { aM.Add(lit.Value()); aMS.Add(lit.Value()); } if(aMS.Extent()) aDMM.Bind(it.Key(), aMS); } else { #ifdef OCCT_DEBUG cout << "Key is not BOUND!" < of neighbors. //------------------------------ Standard_Integer aLev(Lev); TopTools_MapOfShape Neighbourg; Localizer.FindNeighbourg (Context,S,Neighbourg); #ifdef OCCT_DEBUG_NBS //DbgTools::DisplayShape(Context, F, Quantity_NOC_GREEN); //DbgTools::DisplayShape(S, F, Quantity_NOC_BLUE1); Write(Context, "FNBS_Context.brep"); Write(S, "FNBS_S.brep"); Write(Neighbourg, "NBS"); #endif // mpv : NS and shape must be the same Standard_Boolean isIn = Standard_False; TNaming_Iterator anIter(NS); for(;anIter.More();anIter.Next()) { #ifdef OCCT_DEBUG //DbgTools::DisplayShape(anIter.NewShape(), F, Quantity_NOC_RED); #endif if (anIter.NewShape().IsSame(S)) { isIn = Standard_True; break; } } if (!isIn) if (!TNaming_Tool::NamedShape(S,F).IsNull()) NS = TNaming_Tool::NamedShape(S,F); // if (!TNaming_Tool::NamedShape(S,F).IsNull()) NS = TNaming_Tool::NamedShape(S,F); if (Neighbourg.IsEmpty()) { // Recherche du vrai context. (Research of context truth) Handle(TNaming_NamedShape) GenS = TNaming_Tool::NamedShape(S,NS->Label()); if (GenS.IsNull()) return Standard_False; TDF_Label Father = (GenS->Label()).Father(); Father.FindAttribute(TNaming_NamedShape::GetID(),GenS); TopoDS_Shape GoodContext = TNaming_Tool::GetShape(GenS); Localizer.FindNeighbourg (GoodContext,S,Neighbourg); } if (Neighbourg.IsEmpty()) { #ifdef OCCT_DEBUG cout <<"FindNeighbourg: impossible"< MultipleCase!" << endl; NS->Label().FindAttribute(TNaming_Naming::GetID(), aFNaming); if(!aFNaming.IsNull()) { TNaming_Name& aName = aFNaming->ChangeName(); if (aName.Type() == TNaming_INTERSECTION) { Standard_Integer ij(1); TNaming_ListIteratorOfListOfNamedShape itA(aName.Arguments()); for (; itA.More(); itA.Next(), ij++) { const TopoDS_Shape& aFace = TNaming_Tool::CurrentShape(itA.Value()); #ifdef OCCT_DEBUG_MOD Write(aFace, "First_Face.brep"); cout <<"Selection TS = " << S.TShape()->This() <Label()); cout <<"AppendNS = " ; Print_Entry(NS->Label()); #endif //--------------------- // Naming des voisins. //--------------------- TopTools_MapIteratorOfMapOfShape itN(Neighbourg); for (; itN.More(); itN.Next()) { #ifdef ALLOW_CHILD_NBS const TopoDS_Shape& aS = itN.Key(); Handle (TNaming_NamedShape) aNS = BuildName(NF->Label(), MDF, aS, Context, Stop, 1); #ifdef OCCT_DEBUG_NBS const TopoDS_Shape& aS2 = aNS->Get(); if(!aS.IsNull()) cout << "Shape arg type = " << aS.ShapeType() <<" TSH = " << aS.TShape()->This()<FindAttribute(TNaming_Naming::GetID(), aNaming); if(!aNaming.IsNull()) { const TNaming_Name& aName = aNaming->GetName(); if (aName.Type() == TNaming_GENERATION) StandardFilter = Standard_False; if(StandardFilter) if (!Compare (aNS,MDF,Stop,aS)) { TNaming_Localizer aLocalizer; Filter (NF->Label(), MDF,aS,Context, aLocalizer,aNS, aLev); } } } theName.Append(aNS); #else theName.Append(BuildName(NF->Label(), MDF, itN.Key(), Context, Stop, 1)); #endif } //------------------------------ // Compute the TNaming_NamedShape //------------------------------ NF->Regenerate(MDF.ChangeValid()); NF->Label().FindAttribute(TNaming_NamedShape::GetID(),NS); //----------------- // Check du filtre. //----------------- if (Compare (NS,MDF,Stop,S)) return 1; #ifdef OCCT_DEBUG cout <<"TNaming_Naming::Name Filter insufficient"< is Ident.NamedShapeOfGeneration() == TDF_Label Father = Context->Label().Father(); Father.FindAttribute(TNaming_NamedShape::GetID(),NewStop); #ifdef OCCT_DEBUG_INNS if(!Stop.IsNull()) {cout <<" Stop NS : "; Print_Entry( Stop->Label());} if(!NewStop.IsNull()) {cout <<" NewStop : "; Print_Entry( NewStop->Label());} cout <<"ContextLabel: "; Print_Entry( Context->Label()); cout <<"Father : "; Print_Entry( Father); #endif } #ifdef OCCT_DEBUG_INNS if(NewStop.IsNull()) cout <<"BuildNameInNS:: NewStop shape is NULL" << endl; #endif return BuildName (F,MDF,S,SC,NewStop,Geometry); } //======================================================================= //function : //purpose : //======================================================================= static Handle(TNaming_NamedShape) BuildName (const TDF_Label& F, TNaming_Scope& MDF, const TopoDS_Shape& Selection, const TopoDS_Shape& Context, const Handle(TNaming_NamedShape)& Stop, const Standard_Boolean Geom) { // Create an identifier Standard_Boolean OnlyOne = !Geom; Standard_Boolean IsGeneration = Standard_False; #ifdef OCCT_DEBUG_MOD cout <<"BuildName: F => "; Print_Entry(F); cout <<" Selection type = " << Selection.ShapeType() << " TS = " << Selection.TShape()->This() << endl; Write(Selection, "BName_Selection.brep"); Write(Context, "BName_Context.brep"); #endif TNaming_Identifier Ident(F, Selection, Context,OnlyOne); Handle (TNaming_Naming) Naming; Handle (TNaming_NamedShape) NS; if (!Ident.IsDone()) { return BuildNS (F,Selection, TNaming_UNKNOWN); } if (Ident.IsFeature() && Stop.IsNull()) { //------------- // Deja Nomme //------------- if (!OnlyOne) return Ident.FeatureArg(); else NS = Ident.FeatureArg(); } else { //--------------------------------------------- // Construction de la fonction d identification. //--------------------------------------------- //Standard_Boolean NotOnlyOne = 0; Naming = TNaming_Naming::Insert(F); TNaming_Name& theName = Naming->ChangeName(); theName.ShapeType(Selection.ShapeType()); theName.Shape(Selection); theName.Orientation(Selection.Orientation()); theName.Type(Ident.Type()); #ifdef OCCT_DEBUG_MOD cout <<"BuildName: Inserted Naming Att at "; Print_Entry(Naming->Label()); cout <<" NameType = " << theName.Type() <Label(), Es); cout <<"StopNS at Label = "<< Es << endl; } #endif //--------------------------------- // Identification des arguments. //--------------------------------- for (Ident.InitArgs(); Ident.MoreArgs(); Ident.NextArg()) { if (Ident.ArgIsFeature()) { theName.Append(Ident.FeatureArg()); #ifdef OCCT_DEBUG_MOD if(!Ident.FeatureArg().IsNull()) { TCollection_AsciiString E; TDF_Tool::Entry(Ident.FeatureArg()->Label(), E); cout <<"Added argument NS from Label = "<< E << endl; } #endif } else { #ifdef OCCT_DEBUG_MOD cout <<"BuildName: NameType = " <Label()); cout <<"Ident.ShapeArg() type = " << Ident.ShapeArg().ShapeType() << " TS = " << Ident.ShapeArg().TShape()->This() << endl; Write(Ident.ShapeArg(), "BName_ShapeArg.brep"); #endif if (theName.Type() == TNaming_GENERATION) theName.Append(BuildNameInNS(Naming->Label(),MDF,Ident.ShapeArg(),Ident.NamedShapeOfGeneration(),Stop,Geom)); else theName.Append(BuildName(Naming->Label(),MDF,Ident.ShapeArg(),Context,Stop,Geom)); } } //------------------------ // Reconstruction of Name //------------------------ Naming->Regenerate(MDF.ChangeValid()); #ifdef OCCT_DEBUG_MOD TCollection_AsciiString E2; TDF_Tool::Entry(Naming->Label(), E2); cout <<"Regenerated Naming Att at Label = "<< E2 << endl; #endif Naming->Label().FindAttribute(TNaming_NamedShape::GetID(),NS); if(NS.IsNull()) return NS; if (MDF.WithValid()) MDF.Valid(NS->Label()); #ifdef OCCT_DEBUG_MOD if(!NS.IsNull()) { TCollection_AsciiString E; TDF_Tool::Entry(NS->Label(), E); cout <<"Regenerated NS at Label = "<< E << endl; } #endif } if (OnlyOne) { //------------------------------------------------- // Filtre par les voisins // pour construire le nom correspondant a S. //------------------------------------------------- if(NS.IsNull()) return NS; TNaming_Localizer Localizer; TNaming_Iterator itNS(NS); if (itNS.More()) { //---------------- // Check + Filtre //---------------- Standard_Boolean StandardFilter = !IsGeneration; if (IsGeneration) { if (!CompareInGeneration (NS,Selection)) { TopoDS_Shape NewContext; Handle(TNaming_NamedShape) NewStop; FindNewShapeInFather (Ident.NamedShapeOfGeneration(),NewContext); Filter (F,MDF,Selection,NewContext,Localizer,NS,0); } } else if (Ident.Type() == TNaming_MODIFUNTIL || (Ident.Type() == TNaming_INTERSECTION && Naming->ChangeName().Arguments().Extent() == 1)) { #ifdef OCCT_DEBUG_MOD cout <<"BuildName(CompareInModification): NameType = " <Label() : Naming->ChangeName().Arguments().First()->Label()); cout <<"Selection type = " << Selection.ShapeType() << " TS = " << Selection.TShape()->This() << endl; #endif Handle(TNaming_NamedShape) NewNS = CompareInModification(Ident.Type() == TNaming_MODIFUNTIL ? NS : Naming->ChangeName().Arguments().First(), Selection); if (!NewNS.IsNull()) { // there is need to describe name in detail: modification with type 1:n in the same label StandardFilter = Standard_False; if (Ident.IsFeature()) { // for MODIFUNTIL: change it to the GENERATION Naming = TNaming_Naming::Insert(F); TNaming_Name& theName = Naming->ChangeName(); theName.ShapeType(Selection.ShapeType()); theName.Shape(Selection); theName.Orientation(Selection.Orientation()); theName.Type(TNaming_GENERATION); theName.Append(TNaming_Tool::NamedShape(Selection,F)); theName.Append(NewNS); Naming->Regenerate(MDF.ChangeValid()); Naming->Label().FindAttribute(TNaming_NamedShape::GetID(),NS); } Filter (F,MDF,Selection,Context,Localizer,NS,0); } } if (StandardFilter) if (!Compare (NS,MDF,Stop,Selection)) { Filter (F,MDF,Selection,Context,Localizer,NS,0); } } } if (MDF.WithValid()) MDF.Valid(NS->Label()); #ifdef OCCT_DEBUG_MOD if(!NS.IsNull()) { TCollection_AsciiString E; TDF_Tool::Entry(NS->Label(), E); cout <<"Returned NS from Label = "<< E << endl; } #endif return NS; } //======================================================================= //function : Validate //purpose : //======================================================================= static void Validate(TNaming_Scope& MDF, TNaming_OldShapeIterator& it) { MDF.Valid(it.Label()); MDF.ValidChildren(it.Label()); TNaming_OldShapeIterator it2(it); for (; it2.More(); it2.Next()) { Validate (MDF,it2); } } //======================================================================= //function : UnValidate //purpose : //======================================================================= static void UnValidate(TNaming_Scope& MDF, TNaming_NewShapeIterator& it) { MDF.Unvalid(it.Label()); MDF.UnvalidChildren(it.Label()); TNaming_NewShapeIterator it2(it); for (; it2.More(); it2.Next()) { UnValidate (MDF,it2); } } //======================================================================= //function : BuildScope //purpose : adds to the MDF the label of NamedShape, // : its children, all its oldShapes and its children. // : unvalidates all newShapes and it's children. // : If is null or next modification has an empty newShape // : ( this shape was deleted ), then MDF.WithValid(Standard_False) // : and nothing is added to the scope. //======================================================================= static void BuildScope (TNaming_Scope& MDF, const TopoDS_Shape& Context, const TDF_Label& Acces) { if (Context.IsNull()) { MDF.WithValid(Standard_False); return; } //---------------------------------------------------- // Is context the current state //---------------------------------------------------- Handle(TNaming_NamedShape) NS = TNaming_Tool::NamedShape(Context,Acces); Handle(TNaming_NamedShape) Next = NextModif(NS); // if NS has subsequent evolution = MODIFY, return it if (Next.IsNull()) { MDF.WithValid(Standard_False); return; } //----------------------------- // a posteriori naming //----------------------------- MDF.WithValid(Standard_True); MDF.Valid(NS->Label()); MDF.ValidChildren(NS->Label()); TNaming_OldShapeIterator it(Context,Acces); for (; it.More(); it.Next()) { Validate(MDF,it); } TNaming_NewShapeIterator it2(Context,Acces); for (;it2.More(); it2.Next()) { UnValidate (MDF,it2); } } //======================================================================= //function : HasAncFace //purpose : Returns True & if ancestor face is found //======================================================================= static Standard_Boolean HasAncFace(const TopoDS_Shape& Context, const TopoDS_Shape& W, TopoDS_Shape& Face, Standard_Boolean& isOuter) { Standard_Boolean hasFace(Standard_False); if(W.ShapeType() != TopAbs_WIRE) return hasFace; TopExp_Explorer exp(Context, TopAbs_FACE); for(;exp.More(); exp.Next()) { for (TopoDS_Iterator it(exp.Current()) ; it.More(); it.Next()) { if(it.Value().IsEqual(W)) {// is the Wire ? Face = exp.Current(); if(!Face.IsNull()) { hasFace = Standard_True; // cout << "HasAncFace: TS = " <This() <ChangeName(); theName.ShapeType(Selection.ShapeType()); theName.Shape(Selection); theName.Orientation(Selection.Orientation()); } TNaming_Name& theName = Naming->ChangeName(); TopoDS_Shape aFace; Standard_Boolean isOuter(Standard_False); Standard_Boolean hasFace = HasAncFace(Context, Selection, aFace, isOuter); if(hasFace && Selection.ShapeType() > Context.ShapeType()) { theName.Type(TNaming_WIREIN); if(Context.ShapeType() == TopAbs_FACE) { for (TopoDS_Iterator it(Context) ; it.More(); it.Next()) { if(it.Value().IsEqual(Selection)) { if (TNaming_Selector::IsIdentified (F, Context, NS, Geom)) { theName.Append(NS); found = Standard_True; break; } } } if(found) { theName.Append(BuildName (Naming->Label(),MDF,aFace,Context,Stop,Geom)); if(isOuter) { theName.Index(1); } else { theName.Index(-1); for (TopExp_Explorer exp(Selection,TopAbs_EDGE) ; exp.More(); exp.Next()) { if(exp.Current().IsNull()) continue; if (BRep_Tool::Degenerated(TopoDS::Edge(exp.Current()))) continue; theName.Append(TNaming_Naming::Name(Naming->Label(),exp.Current(),Context, Geom, 1, 0)); } } } else return BuildNS (F,Selection, TNaming_UNKNOWN); } else { // context is not Face theName.Append(BuildName (Naming->Label(),MDF,aFace,Context,Stop,Geom)); if(isOuter) { theName.Index(1); } else { for (TopExp_Explorer exp(Selection,TopAbs_EDGE) ; exp.More(); exp.Next()) { if(exp.Current().IsNull()) continue; if (BRep_Tool::Degenerated(TopoDS::Edge(exp.Current()))) continue; theName.Append(TNaming_Naming::Name(Naming->Label(),exp.Current(),Context, Geom, 1, 0)); } } }// } else { // => no Face theName.Type(TNaming_UNION); for (TopExp_Explorer exp(Selection,TopAbs_EDGE) ; exp.More(); exp.Next()) { if(exp.Current().IsNull()) continue; if (BRep_Tool::Degenerated(TopoDS::Edge(exp.Current()))) continue; theName.Append(BuildName (Naming->Label(),MDF,exp.Current(),Context,Stop,Geom)); } } //Naming->GetName().Solve(Naming->Label(),MDF.GetValid()); Naming->Label().FindAttribute(TNaming_NamedShape::GetID(),NS); return NS; } //======================================================================= static Standard_Boolean IsOneIn (const TopoDS_Shape& S, const TopoDS_Shape& Context) { Standard_Boolean found(Standard_False); if(S.IsNull() || Context.IsNull()) return found; for (TopExp_Explorer exp(Context,S.ShapeType()); exp.More(); exp.Next()) { if (exp.Current().IsEqual(S)) { found = Standard_True; break; } } return found; } //======================================================================= static Standard_Boolean IsAllIn (const TopoDS_Shape& S, const TopoDS_Shape& Context) { #ifdef OCCT_DEBUG_CC Write(S, "IsAllIn_Sel.brep"); #endif Standard_Boolean found(Standard_False); if(S.IsNull() || Context.IsNull()) return found; Standard_Integer num1(0), num2(0); for(TopoDS_Iterator it(S);it.More();it.Next(),num1++) { #ifdef OCCT_DEBUG_CC cout <<"S sub-shape type = " << it.Value().ShapeType() < aNum) aNum = n; } } } #ifdef OCCT_DEBUG_OR cout <<"RepeatabilityInContext: = " <ChangeName(); theName.ShapeType(Selection.ShapeType()); theName.Shape(Selection); theName.Orientation(Selection.Orientation()); } TNaming_Name& theName = Naming->ChangeName(); TopoDS_Shape aSolid; Standard_Boolean isOuter(Standard_False); Standard_Boolean hasSolid = HasAncSolid(Context, Selection, aSolid, isOuter); if(hasSolid && Selection.ShapeType() > Context.ShapeType()) { theName.Type(TNaming_SHELLIN);// SHELLIN if(Context.ShapeType() == TopAbs_SOLID) { for (TopoDS_Iterator it(Context) ; it.More(); it.Next()) { #ifdef OCCT_DEBUG_TSOL Write(it.Value(), "Shell_inSo.brep"); #endif if(it.Value().IsEqual(Selection)) { found = Standard_True; break; } } if(found) { // solid => aSolid which is also a context Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(Context,F); if(!aNS.IsNull()) theName.ContextLabel(aNS->Label()); theName.Append(aNS); if(isOuter) { theName.Index(1); } else { //not OuterShell theName.Index(-1); for (TopExp_Explorer exp(Selection,TopAbs_FACE) ; exp.More(); exp.Next()) { if(exp.Current().IsNull()) continue; theName.Append(BuildName (Naming->Label(),MDF,exp.Current(),Context,Stop,Geom)); } } } else return BuildNS (F,Selection, TNaming_UNKNOWN); } else { // context is not SOLID //theName.Append(BuildName (Naming->Label(),MDF,aSolid,Context,Stop,Geom));//########### if(isOuter) { #ifdef OCCT_DEBUG_TSOL Write(aSolid, "foundSolid.brep"); #endif theName.Index(1); Handle (TNaming_Naming) NamingSo = TNaming_Naming::Insert(F); TNaming_Name& theNameSo = NamingSo->ChangeName(); theNameSo.ShapeType(aSolid.ShapeType()); theNameSo.Shape(aSolid); theNameSo.Type(TNaming_UNION); Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(Context,F); if(!aNS.IsNull()) theNameSo.ContextLabel(aNS->Label()); for (TopExp_Explorer exp(aSolid,TopAbs_FACE) ; exp.More(); exp.Next()) theNameSo.Append(BuildName (NamingSo->Label(),MDF,exp.Current(),Context,Stop,Geom)); NamingSo->GetName().Solve(NamingSo->Label(),MDF.GetValid()); aNS.Nullify(); NamingSo->Label().FindAttribute(TNaming_NamedShape::GetID(),aNS); theName.Append(aNS); } else { theName.Index(-1); // - name Solid: theName.Append(BuildName (Naming->Label(),MDF, aSolid,Context,Stop,Geom)); Handle (TNaming_Naming) NamingSo = TNaming_Naming::Insert(F); TNaming_Name& theNameSo = NamingSo->ChangeName(); theNameSo.ShapeType(aSolid.ShapeType()); theNameSo.Shape(aSolid); theNameSo.Type(TNaming_UNION); Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(Context,F); if(!aNS.IsNull()) theNameSo.ContextLabel(aNS->Label()); for (TopExp_Explorer exp(aSolid,TopAbs_FACE) ; exp.More(); exp.Next()) theNameSo.Append(BuildName (NamingSo->Label(),MDF,exp.Current(),Context,Stop,Geom)); NamingSo->GetName().Solve(NamingSo->Label(),MDF.GetValid()); aNS.Nullify(); NamingSo->Label().FindAttribute(TNaming_NamedShape::GetID(),aNS); theName.Append(aNS); for (TopExp_Explorer exp(Selection,TopAbs_FACE) ; exp.More(); exp.Next()) { if(exp.Current().IsNull()) continue; theName.Append(BuildName (Naming->Label(),MDF,exp.Current(),Context,Stop,Geom)); } } }// } else { // => no Solid theName.Type(TNaming_UNION); Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(Context,F); if(!aNS.IsNull()) theName.ContextLabel(aNS->Label()); for (TopExp_Explorer exp(Selection,TopAbs_FACE) ; exp.More(); exp.Next()) { if(exp.Current().IsNull()) continue; theName.Append(BuildName (Naming->Label(),MDF,exp.Current(),Context,Stop,Geom)); } } //Naming->GetName().Solve(Naming->Label(),MDF.GetValid()); Naming->Label().FindAttribute(TNaming_NamedShape::GetID(),NS); return NS; } //======================================================================= //function : BuildAggregationNam //purpose : //======================================================================= static void BuildAggregationName (const TDF_Label& F, TNaming_Scope& MDF, const TopoDS_Shape& S, const TopoDS_Shape& Context, const Handle(TNaming_NamedShape)& Stop, const Standard_Boolean Geom) { const Standard_Boolean found2 = IsAllIn(S, Context); Handle (TNaming_Naming) Naming; if(!F.FindAttribute(TNaming_Naming::GetID(), Naming)) { Naming = new TNaming_Naming (); F.AddAttribute (Naming); TNaming_Name& theName = Naming->ChangeName(); theName.ShapeType(S.ShapeType()); theName.Shape(S); theName.Orientation(S.Orientation()); } #ifdef OCCT_DEBUG_CC cout <<"BuildAggregationName ==> "; Print_Entry(Naming->Label()); #endif TNaming_Name& theName = Naming->ChangeName(); for (TopoDS_Iterator itc(S) ; itc.More(); itc.Next()) { const TopoDS_Shape& aS = itc.Value(); if ((aS.ShapeType() == TopAbs_SOLID && !TNaming_Tool::NamedShape(aS,Naming->Label()).IsNull()) || aS.ShapeType() == TopAbs_FACE || aS.ShapeType() == TopAbs_EDGE || aS.ShapeType() == TopAbs_VERTEX ) { theName.Append(BuildName (F, MDF, aS,Context,Stop,Geom)); } else { // ==> union of union || union of wires TopAbs_ShapeEnum atomTyp; switch (aS.ShapeType()) { case TopAbs_SOLID: case TopAbs_SHELL: atomTyp = TopAbs_FACE; break; case TopAbs_WIRE: atomTyp = TopAbs_EDGE; break; default: atomTyp = TopAbs_SHAPE; } Handle(TNaming_NamedShape) aNS; Handle (TNaming_Naming) aNaming = TNaming_Naming::Insert(F); TNaming_Name& aName = aNaming->ChangeName(); aName.ShapeType(aS.ShapeType()); aName.Shape(aS); theName.Orientation(aS.Orientation()); aName.Type(TNaming_UNION); if (atomTyp != TopAbs_SHAPE) { if(aS.ShapeType() == TopAbs_WIRE) { aNS = BuildNameWire (aNaming->Label(), MDF, aS, Context,Stop,Geom); } else if(aS.ShapeType() == TopAbs_SHELL) aNS = BuildNameShell (aNaming->Label(), MDF, aS, Context,Stop,Geom); else { for (TopExp_Explorer exp(aS,atomTyp) ; exp.More(); exp.Next()) { aName.Append(BuildName (aNaming->Label(),MDF,exp.Current(),Context,Stop,Geom)); } } } else { #ifdef OCCT_DEBUG_CC cout << "atomic type is NOT defined ... ==> Aggregation" <Label(),MDF, aS, Context,Stop,Geom); } if(found2) { aNS = TNaming_Tool::NamedShape(Context, F); if(!aNS.IsNull()) aNaming->ChangeName().ContextLabel(aNS->Label()); } aNaming->GetName().Solve(aNaming->Label(),MDF.GetValid()); if(aNaming->Label().FindAttribute(TNaming_NamedShape::GetID(),aNS)) if (!Geom && TestSolution(MDF,aNS,aS)) { theName.Append(aNS); } } } } //======================================================================= //function : Name //purpose : //======================================================================= Handle(TNaming_NamedShape) TNaming_Naming::Name (const TDF_Label& F, const TopoDS_Shape& S, const TopoDS_Shape& Context, const Standard_Boolean Geom, const Standard_Boolean KeepOrientation, const Standard_Boolean BNProblem) { Handle(TNaming_NamedShape) aNamedShape; if (KeepOrientation) { #ifdef OCCT_DEBUG_INNS cout <<"KeepOR = 1: "; Print_Entry(F); #endif Standard_Integer aNum = RepeatabilityInContext(S, Context); Standard_Boolean aBNproblem = (BNProblem) ? (aNum /*== 1*/ && S != Context) : Standard_False; if (aNum > 1 || aBNproblem) { TopoDS_Shape UC = TNaming::FindUniqueContext(S, Context); Handle(TopTools_HArray1OfShape) Arr; if (UC.IsNull() && S.ShapeType() == TopAbs_COMPOUND) { UC = TNaming::FindUniqueContextSet(S, Context, Arr); #ifdef OCCT_DEBUG_CC Write(UC, "UniqueContextSet.brep"); Write(S, "InitialSelection.brep"); if(S.ShapeType()==TopAbs_COMPOUND) { TCollection_AsciiString aNam("S_"); TopoDS_Iterator it(S); for(int i=1;it.More();it.Next(),i++) { TCollection_AsciiString aName = aNam + i + ".brep"; Write(it.Value(), aName.ToCString()); } } #endif } if(!UC.IsNull()) { Handle (TNaming_Naming) Naming = TNaming_Naming::Insert(F); TNaming_Name& theName = Naming->ChangeName(); theName.ShapeType(S.ShapeType()); theName.Shape(S); theName.Type(TNaming_ORIENTATION); theName.Orientation(S.Orientation()); if (!TNaming_Selector::IsIdentified (F, S, aNamedShape, Geom)) aNamedShape = TNaming_Naming::Name(Naming->Label(),S,Context,Geom,0); theName.Append (aNamedShape); #ifdef MDTV_OR cout << " Sel Label ==> "; Print_Entry(NS->Label()); #endif //szy 21.10.2009 if(S.ShapeType() == TopAbs_EDGE && UC.ShapeType() == TopAbs_FACE) { if(RepeatabilityInContext(S, UC) == 2) { //sim. edge TopoDS_Iterator itw(UC); for(;itw.More();itw.Next()) { Standard_Boolean found(Standard_False); TopoDS_Iterator it(itw.Value()); for(int i=1;it.More();it.Next(),i++) { if(it.Value().IsEqual(S)) { theName.Index(i);//We use this field to save a Seam Shape Index; Before this field was used for GENERATED only found = Standard_True; #ifdef MDTV_OR cout << "ORDER = " << i <Length() > 1) { // N arguments: to be optimized to avoid duplication of the same Context shape for(Standard_Integer i = Arr->Lower(); i <= Arr->Upper(); i++) { aNamedShape = TNaming_Naming::Name(Naming->Label(), Arr->Value(i), Context, Geom, 1, aBNproblem); theName.Append (aNamedShape); } } else { aNamedShape = TNaming_Naming::Name(Naming->Label(),UC,Context, Geom, 1, aBNproblem); theName.Append (aNamedShape); #ifdef MDTV_OR cout << " Cont Label ==> "; Print_Entry(NS->Label()); #endif } //Naming->Update(); TNaming_Scope MDF; BuildScope (MDF,Context,F); Naming->GetName().Solve(Naming->Label(),MDF.GetValid()); Naming->Label().FindAttribute(TNaming_NamedShape::GetID(), aNamedShape); theName.ContextLabel(aNamedShape->Label()); if (Geom) return aNamedShape; if(aNamedShape.IsNull()) { cout <<" %%% WARNING: TNaming_Naming::Name: FAILED"< soit le dernier etat // valide, // Ceci pour les localisation a posteriori par exemple. //------------------------------------------------------------ TNaming_Scope MDF; BuildScope (MDF,Context,F); Handle(TNaming_NamedShape) Stop; if ((S.ShapeType() == TopAbs_SOLID && !TNaming_Tool::NamedShape(S,F).IsNull()) || S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_VERTEX ) { //--------------------------------------- // Localisation de S comme element simple. //--------------------------------------- Handle(TNaming_NamedShape) NS = BuildName (F,MDF,S,Context,Stop,Geom); if (Geom) return NS; if (!Geom && TestSolution(MDF,NS,S)) return NS; } else { //---------------------------------------------------- // Localisation de S comme ensemble d elements simples. //----------------------------------------------------- Handle(TNaming_NamedShape) NS; Handle (TNaming_Naming) Naming = TNaming_Naming::Insert(F); TNaming_Name& theName = Naming->ChangeName(); theName.ShapeType(S.ShapeType());// modified by vro 05.09.00 theName.Shape(S); theName.Orientation(S.Orientation()); if(S.ShapeType() != TopAbs_WIRE) theName.Type(TNaming_UNION); TopAbs_ShapeEnum atomType; switch (S.ShapeType()) { case TopAbs_COMPSOLID: case TopAbs_SOLID: case TopAbs_SHELL: atomType = TopAbs_FACE; break; case TopAbs_WIRE: atomType = TopAbs_EDGE; break; default: atomType = TopAbs_SHAPE; } Standard_Boolean found(Standard_False); if (!Context.IsNull()) { if (Context.ShapeType() < S.ShapeType()) found = IsOneIn(S, Context); if(found) { NS = TNaming_Tool::NamedShape(Context, F); if(!NS.IsNull()) theName.ContextLabel(NS->Label()); } } if (atomType == TopAbs_SHAPE) { if(S.ShapeType() == TopAbs_COMPOUND) { BuildAggregationName(Naming->Label(),MDF, S, Context,Stop,Geom); } else { for (TopoDS_Iterator it(S) ; it.More(); it.Next()) { theName.Append(BuildName (Naming->Label(),MDF,it.Value(),Context,Stop,Geom)); } } } else { if(S.ShapeType() == TopAbs_WIRE) NS = BuildNameWire (Naming->Label(), MDF, S, Context,Stop,Geom); else if(S.ShapeType() == TopAbs_SHELL) { NS = BuildNameShell (Naming->Label(), MDF, S, Context,Stop,Geom); } else { theName.Type(TNaming_UNION); for (TopExp_Explorer exp(S,atomType) ; exp.More(); exp.Next()) { theName.Append(BuildName (Naming->Label(),MDF,exp.Current(),Context,Stop,Geom)); } } } //Naming->Update(); Naming->GetName().Solve(Naming->Label(),MDF.GetValid()); Naming->Label().FindAttribute(TNaming_NamedShape::GetID(),NS); if (Geom) return NS; if(NS.IsNull()) return BuildNS (F,S, TNaming_UNKNOWN); if (!Geom && TestSolution(MDF,NS,S)) return NS; } cout <<" %%% WARNING: TNaming_Naming::Name: FAILED"<ChangeName(); } //======================================================================= //function : Paste //purpose : //======================================================================= void TNaming_Naming::Paste (const Handle(TDF_Attribute)& into, const Handle(TDF_RelocationTable)& RT) const { Handle(TNaming_Naming) NewNaming = Handle(TNaming_Naming)::DownCast(into); myName.Paste(NewNaming->ChangeName(),RT); } //======================================================================= //function : References //purpose : Redefined from TDF_Attribute //======================================================================= void TNaming_Naming::References(const Handle(TDF_DataSet)& DataSet) const { // Iteration on NamedShape of the name TNaming_ListIteratorOfListOfNamedShape it(myName.Arguments()); for (;it.More();it.Next()) DataSet->AddAttribute(it.Value()); if (!myName.StopNamedShape().IsNull()) DataSet->AddAttribute(myName.StopNamedShape()); } //======================================================================= //function : Dump //purpose : //======================================================================= Standard_OStream& TNaming_Naming::Dump (Standard_OStream& anOS) const { anOS << "TNaming_Naming"; return anOS; } //======================================================================= //function :ExtendedDump //purpose : //======================================================================= void TNaming_Naming::ExtendedDump(Standard_OStream& anOS, const TDF_IDFilter& /*aFilter*/, TDF_AttributeIndexedMap& /*aMap*/) const { anOS << "TNaming_Naming ExtendedDump "; //anOS<<"myContext: #" <