0026377: Passing Handle objects as arguments to functions as non-const reference...
[occt.git] / src / TNaming / TNaming_Naming.cxx
CommitLineData
b311480e 1// Created on: 1997-09-03
2// Created by: Yves FRICAUD
3// Copyright (c) 1997-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
7fd59977 17
42cf5bc1 18#include <BRep_Tool.hxx>
19#include <BRepTools.hxx>
20#include <NCollection_DataMap.hxx>
21#include <NCollection_Map.hxx>
22#include <Standard_DomainError.hxx>
23#include <Standard_GUID.hxx>
24#include <Standard_Type.hxx>
25#include <TColStd_MapIteratorOfMapOfInteger.hxx>
26#include <TColStd_MapOfInteger.hxx>
27#include <TDF_Attribute.hxx>
28#include <TDF_ChildIterator.hxx>
29#include <TDF_Data.hxx>
30#include <TDF_DataSet.hxx>
31#include <TDF_IDFilter.hxx>
32#include <TDF_Label.hxx>
33#include <TDF_LabelList.hxx>
34#include <TDF_LabelMap.hxx>
35#include <TDF_RelocationTable.hxx>
36#include <TDF_TagSource.hxx>
37#include <TNaming.hxx>
7fd59977 38#include <TNaming_Builder.hxx>
7fd59977 39#include <TNaming_Identifier.hxx>
42cf5bc1 40#include <TNaming_Iterator.hxx>
41#include <TNaming_ListIteratorOfListOfNamedShape.hxx>
7fd59977 42#include <TNaming_Localizer.hxx>
42cf5bc1 43#include <TNaming_Name.hxx>
44#include <TNaming_NamedShape.hxx>
45#include <TNaming_Naming.hxx>
46#include <TNaming_NamingTool.hxx>
7fd59977 47#include <TNaming_NewShapeIterator.hxx>
48#include <TNaming_OldShapeIterator.hxx>
42cf5bc1 49#include <TNaming_Scope.hxx>
7fd59977 50#include <TNaming_Selector.hxx>
42cf5bc1 51#include <TNaming_Tool.hxx>
7fd59977 52#include <TopExp.hxx>
53#include <TopExp_Explorer.hxx>
7fd59977 54#include <TopoDS.hxx>
1ec8a59e 55#include <TopoDS_Face.hxx>
42cf5bc1 56#include <TopoDS_Iterator.hxx>
57#include <TopoDS_Shape.hxx>
1ec8a59e 58#include <TopoDS_Shell.hxx>
59#include <TopoDS_Solid.hxx>
42cf5bc1 60#include <TopoDS_Wire.hxx>
61#include <TopTools_HArray1OfShape.hxx>
62#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
63#include <TopTools_IndexedMapOfShape.hxx>
64#include <TopTools_ListIteratorOfListOfShape.hxx>
65#include <TopTools_ListOfShape.hxx>
66#include <TopTools_MapIteratorOfMapOfOrientedShape.hxx>
67#include <TopTools_MapIteratorOfMapOfShape.hxx>
68#include <TopTools_MapOfShape.hxx>
69
92efcf78 70IMPLEMENT_STANDARD_RTTIEXT(TNaming_Naming,TDF_Attribute)
71
7fd59977 72// #include <TNaming_NCollections.hxx>
7fd59977 73typedef NCollection_Map<TopoDS_Shape> TNaming_MapOfShape;
74typedef TNaming_MapOfShape::Iterator TNaming_MapIteratorOfMapOfShape;
75typedef NCollection_DataMap<TopoDS_Shape, TNaming_MapOfShape> TNaming_DataMapOfShapeMapOfShape;
76typedef TNaming_DataMapOfShapeMapOfShape::Iterator TNaming_DataMapIteratorOfDataMapOfShapeMapOfShape;
77// The bug concerns access to a null object in the method Filter():
7fd59977 78
7fd59977 79#define ALLOW_CHILD_NBS
80//#define MDTV_DEB_CC
81//#define MDTV_DEB_OR
82//#define MDTV_DEB_MOD
83//#define MDTV_OR
84//#define MDTV_DEB_INNS
85//#define MDTV_DEB_NBS
86//#define MDTV_DEB_71
87//#define MDTV_DEB_WIN
0797d9d3 88#ifdef OCCT_DEBUG
7fd59977 89#include <TDF_MapIteratorOfLabelMap.hxx>
90#include <TCollection_AsciiString.hxx>
91#include <TDF_Tool.hxx>
92#include <BRepTools.hxx>
93#include <TNaming_Tool.hxx>
7fd59977 94#include <TDF_Tool.hxx>
95#include <TDF_MapIteratorOfLabelMap.hxx>
96
97#include <TCollection_AsciiString.hxx>
98#include <BRepTools.hxx>
99void Print_Entry(const TDF_Label& label)
100{
101 TCollection_AsciiString entry;
102 TDF_Tool::Entry(label, entry);
103 cout << "LabelEntry = "<< entry << endl;
104}
105static void Write(const TopoDS_Shape& shape,
106 const Standard_CString filename)
107{
108 char buf[256];
109 if(strlen(filename) > 256) return;
110 strcpy (buf, filename);
111 char* p = buf;
112 while (*p) {
113 if(*p == ':')
114 *p = '-';
115 p++;
116 }
117 ofstream save (buf);
118 if(!save)
119 cout << "File " << buf << " was not created: rdstate = " << save.rdstate() << endl;
120 save << "DBRep_DrawableShape" << endl << endl;
121 if(!shape.IsNull()) BRepTools::Write(shape, save);
122 save.close();
123}
124void WriteNSOnLabel(const Handle(TNaming_NamedShape) & NS, const TCollection_AsciiString& Nam)
125{
126 if (!NS.IsNull()) {
127 TCollection_AsciiString entry;
128 TDF_Tool::Entry(NS->Label(), entry);
129 TopoDS_Shape Sh = TNaming_Tool::GetShape (NS);
130 if(!Sh.IsNull()) {
131 TCollection_AsciiString Entry = Nam + entry + ".brep";
132 Write(Sh, Entry.ToCString());
133 }
134 else
135 cout << "WriteNSOnLabel>>> TopoDS_Shape IS NULL on Entry = "<< entry << endl;
136 }
137 else
138 cout << "WriteNSOnLabel >>> NamedShape IS NULL" << endl;
139}
7fd59977 140#endif
141
142//==========================================================================================
143static Handle(TNaming_NamedShape) BuildName (const TDF_Label& F,
144 TNaming_Scope& MDF,
145 const TopoDS_Shape& S,
146 const TopoDS_Shape& Context,
147 const Handle(TNaming_NamedShape)& Stop,
148 const Standard_Boolean Geometry);
149
150//=======================================================================
151static Standard_Integer RepeatabilityInContext(const TopoDS_Shape& Selection,
152 const TopoDS_Shape& Context);
153//=======================================================================
154extern Standard_Boolean IsEqual (const TopoDS_Shape& S1, const TopoDS_Shape& S2);
155
156//=======================================================================
157//function : Solve
158//purpose : voir avec YFR comment retrouver le bon resulat et le mettre
159// : dans le NamedShape de L
160//=======================================================================
161Standard_Boolean TNaming_Naming::Solve (TDF_LabelMap& Valid)
162{
163 Handle(TNaming_Naming) subname;
164 for (TDF_ChildIterator it (Label(),Standard_False); it.More(); it.Next()) {
0797d9d3 165#ifdef OCCT_DEBUG_NBS
7fd59977 166 TCollection_AsciiString anEntry;
167 TDF_Tool::Entry(it.Value(), anEntry);
168 cout << "TNaming_Naming::Solve: Label to be solved = " << anEntry << endl;
169#endif
170 if (it.Value().FindAttribute(TNaming_Naming::GetID(),subname)) {
171 if (!subname->Solve (Valid)) {
172 return Standard_False; // not necessary to continue
173 }
174 }
175 }
0797d9d3 176#ifdef OCCT_DEBUG_CC
7fd59977 177 TDF_MapIteratorOfLabelMap anItr(Valid);
178 cout << "TNaming_Naming::Solve:: Valid label Map" << endl;
179 for (; anItr.More(); anItr.Next()) {
180 const TDF_Label& aLabel = anItr.Key();
181 TCollection_AsciiString anEntry;
182 TDF_Tool::Entry(aLabel, anEntry);
183 cout << "Label = " << anEntry << endl;
184 }
185#endif
186 if (Regenerate(Valid)) {
187 if (!Valid.IsEmpty()) Valid.Add(Label());
188 return Standard_True;
189 }
190 return Standard_False;
191}
192
193
194//=======================================================================
195//function : GetID
196//purpose :
197//=======================================================================
198
199const Standard_GUID& TNaming_Naming::GetID ()
200{
201 static Standard_GUID TNaming_NamingID("c0a19201-5b78-11d1-8940-080009dc3333");
202 return TNaming_NamingID;
203}
204
205//=======================================================================
206//function : Insert
207//purpose :
208//=======================================================================
209
210Handle(TNaming_Naming) TNaming_Naming::Insert (const TDF_Label& under)
211{
212 Handle(TNaming_Naming) N;
213 TDF_Label child = TDF_TagSource::NewChild(under);
214 N = new TNaming_Naming ();
215 child.AddAttribute (N);
216 return N;
217}
218
219//=======================================================================
220//function : BuildNS
221//purpose : returns a new NamedShape, which is built as selection:
222// : TNaming_Builder::Select("S","S") at the new child label of the label <F>.
223//=======================================================================
224
225static Handle(TNaming_NamedShape) BuildNS (const TDF_Label& F,
226 const TopoDS_Shape& S,
227 const TNaming_NameType& Name)
228{
229 Handle (TNaming_Naming) Naming = TNaming_Naming::Insert (F);
230
231 TNaming_Name& theName = Naming->ChangeName();
232 theName.ShapeType(S.ShapeType());
233 theName.Shape(S);
7dcac1df 234 theName.Orientation(S.Orientation());
7fd59977 235 theName.Type(Name);
236 TNaming_Builder B(Naming->Label());
237 B.Select(S,S);
238 return B.NamedShape();
239}
240
241//=======================================================================
242//function : FindIndex
243//purpose :
244//=======================================================================
245
246static Standard_Integer FindIndex(const Handle(TNaming_NamedShape)& NS,
247 const TopoDS_Shape& S)
248{
249 TDF_LabelList Labels;
250 TopoDS_Shape IS = TNaming_Tool::InitialShape(S,NS->Label(),Labels);
251 Standard_Integer Index = 1;
252 for (TNaming_Iterator itNS(NS); itNS.More(); itNS.Next(),Index++) {
253 if (IS.IsSame(itNS.NewShape())) break;
254 }
255 return Index;
256}
257
258
259//=======================================================================
260//function : CompareInGeneration
261//purpose : returns true, only if the specified NS contains only <S> in
262// : the "new shapes" set.
263//=======================================================================
264
265static Standard_Boolean CompareInGeneration (const Handle(TNaming_NamedShape)& NS,
266 const TopoDS_Shape& S)
267{
268 for (TNaming_Iterator it(NS); it.More(); it.Next()) {
269 if (!it.NewShape().IsSame(S)) return 0;
270 }
271 return 1;
272}
273
7fd59977 274//=======================================================================
275//function : GetShapeEvolutions
276//purpose : returns Standard_True, if target has parent in source; list contains inheritance chain
277//=======================================================================
278static Standard_Boolean GetShapeEvolutions(const TopoDS_Shape& theTarget, // this is changed in recursion
279 const Handle(TNaming_NamedShape)& theSource,
280 TopTools_ListOfShape& aList) // returns list in the backward order
281{
282 Handle(TNaming_NamedShape) aTarget = TNaming_Tool::NamedShape(theTarget,theSource->Label());
283 if (!aTarget.IsNull()) {
0797d9d3 284#ifdef OCCT_DEBUG_71
7fd59977 285 cout <<"GetShapeEvolutions: target NS = ";
286 Print_Entry(aTarget->Label());
287 cout <<"GetShapeEvolutions: Source NS = ";
288 Print_Entry(theSource->Label());
289 TCollection_AsciiString aNam("GetShapeEvolutions");
290 WriteNSOnLabel(aTarget,aNam);
291#endif
292 if (aTarget->Label() == theSource->Label()) return Standard_True; // check if target is in the source
293 } else return Standard_False;
294
295 TNaming_Iterator anIter(aTarget);
296 for(;anIter.More();anIter.Next()) { // check all appropriate old shapes of target
0797d9d3 297#ifdef OCCT_DEBUG_71
7fd59977 298 if(!anIter.OldShape().IsNull()) {
299 Write(anIter.OldShape(), "Target_OldS.brep");
300 cout <<"Target OldS TS =" <<anIter.OldShape().TShape()->This() <<endl;
301 }
302 if(!anIter.NewShape().IsNull()) {
303 Write(anIter.NewShape(), "Target_NewS.brep");
304 cout <<"Target NewS TS =" <<anIter.NewShape().TShape()->This() <<endl;
305 }
306#endif
307 if (anIter.OldShape().IsNull() || anIter.NewShape().IsNull()) continue;
308 if (!anIter.NewShape().IsSame(theTarget)) continue;
309 if (GetShapeEvolutions(anIter.OldShape(),theSource,aList)) { // recursion: now target is old shape
310 aList.Append(theTarget); // if oldshape has the source as parent (or belongs to it) , fill the list
311 return Standard_True;
312 }
313 }
314 return Standard_False;
315}
316
317//=======================================================================
318//function : CompareInModification
319//purpose : returns empty named shape if naming is already done
320//=======================================================================
321
322static Handle(TNaming_NamedShape) CompareInModification (const Handle(TNaming_NamedShape)& NS, // parent
323 const TopoDS_Shape& S) // target
324{
325 Handle(TNaming_NamedShape) aResult;
326 if (S.IsNull() || NS.IsNull()) return aResult;
0797d9d3 327#ifdef OCCT_DEBUG_71
7fd59977 328 cout <<"CompareInModification: parent NS = ";
329 Print_Entry(NS->Label());
330 Write(S, "CompareInM_S.brep");
331 TCollection_AsciiString aNam("CompareInM");
332 WriteNSOnLabel(NS,aNam);
333#endif
334 Handle(TNaming_NamedShape) aSource; // parent NamedShape, which can be found by TopoDS shape
335 TNaming_Iterator anIt(NS);
336 for(;anIt.More() && aSource.IsNull();anIt.Next()) {
337 if (!anIt.NewShape().IsNull()) {
338 aSource = TNaming_Tool::NamedShape(anIt.NewShape(),NS->Label());
0797d9d3 339#ifdef OCCT_DEBUG_71
7fd59977 340 TCollection_AsciiString aNam("CompareInM_Source");
341 WriteNSOnLabel(aSource,aNam);
342#endif
343 }
344 }
345 // searching for 1:n to the same label modifications (in this case current naming is insufficient)
346 TopTools_ListOfShape aList;
347 if (GetShapeEvolutions(S,aSource,aList) && aList.Extent() > 0) {
348 TopTools_ListIteratorOfListOfShape anIter(aList);
349 for(;anIter.More();anIter.Next()) {
350 aResult = TNaming_Tool::NamedShape(anIter.Value(),NS->Label());
351 if (aResult->Evolution()!=TNaming_MODIFY) { // evolution must be modify, otherwise everything is OK
352 aResult.Nullify();
353 return aResult;
354 }
355 TopTools_MapOfShape aMap; // collection of the old shapes of the shape from list
356 TNaming_Iterator aNIter1(aResult);
357
358 for(;aNIter1.More();aNIter1.Next()) {
359 if (aNIter1.NewShape().IsSame(anIter.Value())) {// if isSame
360 aMap.Add(aNIter1.OldShape());
361 }
362 }
363 TNaming_Iterator aNIter2(aResult); // if some another shapes has oldshape from map, return namedshape with this oldshape
364
365 for(;aNIter2.More();aNIter2.Next()) {
366 if (aNIter2.NewShape().IsSame(anIter.Value())) continue;
367 if (aMap.Contains(aNIter2.OldShape())) { // if one shape was modified to the two at the shared label, return this one
368 aResult = TNaming_Tool::NamedShape(aNIter2.OldShape(),NS->Label());
369 if (!aResult.IsNull()) return aResult;
370 }
371 }
372 }
373 aResult.Nullify();
374 }
375 return aResult;
376}
7fd59977 377
378//=======================================================================
379static Standard_Boolean FillSMap(const TopoDS_Shape& S, TopTools_MapOfShape& MS)
380{
381 if(S.IsNull()) return Standard_False;
382 Standard_Boolean isHomogen(Standard_True);
383 TopAbs_ShapeEnum aPrevType(TopAbs_SHAPE);
384 TopoDS_Iterator it(S);
385 for (; it.More(); it.Next()) {
386 const TopAbs_ShapeEnum aType = it.Value().ShapeType();
0797d9d3 387#ifdef OCCT_DEBUG_CC
7fd59977 388 cout <<"TestSolution_FillMap: S_Type = :" << it.Value().ShapeType() <<" TShape = " << it.Value().TShape()->This() <<endl;
389#endif
390 if(aType > TopAbs_COMPSOLID) {
391 MS.Add(it.Value());
392 if(aPrevType == TopAbs_SHAPE)
393 aPrevType = aType;
394 else if(aPrevType != aType)
395 isHomogen = Standard_False;
396 }
397 else
398 if(!FillSMap(it.Value(), MS))
399 isHomogen = Standard_False;
400 }
401 return isHomogen;
402}
403//=======================================================================
404//function : Compare
405//purpose : checks naming of the shape <S> in the NamedShape <NS>.
406// : Returns true, if it's correct. Details ==>
407// : The method takes all modifications of the "NS" (see CurrentShape method),
408// : which are in the "MDF" (if it's not empty) before <Stop> shape and check them.
409// : whether these modifications contain only "S". If yes then the method
410// : returns true, otherwise it returns false.
411//=======================================================================
412
413static Standard_Boolean Compare (const Handle(TNaming_NamedShape)& NS,
414 const TNaming_Scope& MDF,
415 const Handle(TNaming_NamedShape)& Stop,
416 const TopoDS_Shape& S)
417{
418 TDF_LabelMap Forbiden;
0df87563 419 TopTools_IndexedMapOfShape MS;
7fd59977 420 if (!Stop.IsNull()) TNaming_NamingTool::BuildDescendants(Stop,Forbiden);
421 TNaming_NamingTool::CurrentShape(MDF.GetValid(),Forbiden,NS,MS);
0797d9d3 422#ifdef OCCT_DEBUG_NBS
7fd59977 423 Write(S, "Compare_S.brep");
424 cout << "S: TShape = " <<S.TShape()->This() <<endl;
7fd59977 425 TCollection_AsciiString aNam("Compare_MS_");
426 TCollection_AsciiString ext(".brep");
0df87563 427 for (Standard_Integer anItMS = 1; anItMS <= MS.Extent(); ++anItMS) {
428 TCollection_AsciiString aName = aNam + anItMS + ext;
429 Write (MS (anItMS), aName.ToCString());
430 cout << aName.ToCString()<< ": TShape = " << MS (anItMS).TShape()->This() << endl;
7fd59977 431 }
432#endif
433 return (MS.Contains(S) && MS.Extent() == 1);
434}
435//=======================================================================
436//function : TestSolution
437//purpose : returns true, if last modification of shape from "NS" is equal to "S":
438// : If shape "S" has atomic type (TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX),
439// : then returns S.IsSame(shape from "NS").
440// : Otherwise the result of exploration of these shapes must be same.
441//=======================================================================
442
443static Standard_Boolean TestSolution(const TNaming_Scope& MDF,
444 const Handle(TNaming_NamedShape)& NS,
445 const TopoDS_Shape& S)
446{
447
448 if (NS.IsNull()) return Standard_False;
449 TopoDS_Shape Res = MDF.CurrentShape(NS);// last modification of NS taken into account Valid map
450 if(S.IsNull() || Res.IsNull()) return Standard_False;
0797d9d3 451#ifdef OCCT_DEBUG_CC
7fd59977 452 Write(S, "TSol_S.brep");
453 Write(Res, "TSol_Res.brep");
454#endif
7fd59977 455
456 if ((S.ShapeType() == TopAbs_FACE ||
457 S.ShapeType() == TopAbs_EDGE ||
458 S.ShapeType() == TopAbs_VERTEX ) &&
459 Res.ShapeType() != TopAbs_COMPOUND) {
460 return (Res.IsSame(S));
461 } else if (S.ShapeType() == TopAbs_SOLID ||
462 S.ShapeType() == TopAbs_COMPSOLID) {
463 TopTools_MapOfShape aMS;
464 TopExp_Explorer exp;
465 for (exp.Init(S,TopAbs_FACE) ; exp.More(); exp.Next()) {
466 aMS.Add(exp.Current());
467 }
468 for (exp.Init(Res,TopAbs_FACE) ; exp.More(); exp.Next()) { //content of MS and Res should be the same
469 if (aMS.Contains(exp.Current())) {
470 aMS.Remove(exp.Current());
471 }
472 else return 0;
473 }
474 return aMS.IsEmpty();
475 } else {
476
7fd59977 477 TopTools_MapOfShape MS;
478 Standard_Boolean isHom = FillSMap(S, MS);
479 TopAbs_ShapeEnum aType(TopAbs_SHAPE);
480 TColStd_MapOfInteger aView;
481 TopTools_MapIteratorOfMapOfShape itm(MS);
482 for(;itm.More();itm.Next()) {
483 aType = itm.Key().ShapeType();
484 if(isHom)
485 break;
486 else
487 aView.Add(itm.Key().ShapeType());
488 }
489
490 if (MS.Contains(Res)) {
491 MS.Remove(Res);
492 if (MS.IsEmpty()) return 1;
493 }
494 if (Res.ShapeType() == TopAbs_SOLID ||
495 Res.ShapeType() == TopAbs_COMPSOLID ||
496 Res.ShapeType() == TopAbs_COMPOUND)
497 {
498 TopExp_Explorer exp;
499 if(isHom)
500 for (exp.Init(Res,aType) ; exp.More(); exp.Next()) {
501 if (MS.Contains(exp.Current())) {
502 MS.Remove(exp.Current());
503 }
504 } else {
51740958 505 TColStd_MapIteratorOfMapOfInteger aMapIter(aView);
506 for(; aMapIter.More(); aMapIter.Next()) {
507 TopAbs_ShapeEnum aCurType = (TopAbs_ShapeEnum)aMapIter.Key();
508 for (exp.Init(Res, aCurType) ; exp.More(); exp.Next()) {
7fd59977 509 if (MS.Contains(exp.Current())) {
510 MS.Remove(exp.Current());
511 }
512 }
513 }
514 }
515 } else {
516 if(S.IsSame(Res))
517 return Standard_True;
518 TopoDS_Iterator it(Res);
519 for (; it.More(); it.Next()) { //content of MS and Res should be the same
520 if (MS.Contains(it.Value())) {
521 MS.Remove(it.Value());
522 }
523 else return 0;
524 }
525 }
526 return MS.IsEmpty();
527 }
528}
529
530//=======================================================================
531//function : FindNewShapeInFather
532//purpose :
533//=======================================================================
534
535static void FindNewShapeInFather (const Handle(TNaming_NamedShape)& NS,
536 TopoDS_Shape& SC)
537{
b2197f93 538 const TDF_Label& Father = NS->Label().Father();
7fd59977 539 TNaming_Iterator itLab(Father);
b2197f93 540 if(itLab.More())
541 SC = itLab.NewShape();
7fd59977 542}
543
544//=======================================================================
545//function : NextModif
546//purpose :
547//=======================================================================
548
549static Handle(TNaming_NamedShape) NextModif(const Handle(TNaming_NamedShape)& NS)
550{
551 Handle (TNaming_NamedShape) Next;
552 if (!NS.IsNull()) {
553 TNaming_NewShapeIterator it(NS);
554 if (it.More()&& it.IsModification()) Next = it.NamedShape();
555 }
556 return Next;
557}
558//=======================================================================
559// C1 - cand shape of the father, C2 - shape of rebuild child Naming attr.
560// (to be Compound of elementary shapes)
561//=======================================================================
562static Standard_Boolean IsContSame(const TopoDS_Shape& C1, const TopoDS_Shape& C2)
563{
564 Standard_Boolean aRes(Standard_False);
565 if(!C1.IsNull() && !C2.IsNull()) {
566 TopTools_MapOfShape aMap;
567 if(FillSMap(C1, aMap)) {
568 aRes = Standard_True;
569 TopoDS_Iterator it(C2);
570 for(;it.More();it.Next()) {
571 if(!aMap.Contains(it.Value())) {
572 aRes = Standard_False;
573 break;
574 }
575 }
576 }
577 }
578 return aRes;
579}
580
581//=======================================================================
582// Identifies the case when Filter haven't sense because of multiplicity
583//=======================================================================
584static Standard_Boolean IsMultipleCase(const TopoDS_Shape& S,
585 const TopoDS_Shape& Context,
586 const TopTools_MapOfShape& Neighbourgs) {
587
588 TopTools_IndexedDataMapOfShapeListOfShape aDM;
589 TNaming_MapOfShape aM;
590 TopTools_MapOfShape aNbs;
591 aNbs.Assign(Neighbourgs);
592 aNbs.Add(S);
593 TNaming_DataMapOfShapeMapOfShape aDMM;
594 TopExp::MapShapesAndAncestors (Context, TopAbs_EDGE, TopAbs_FACE, aDM);
595 TopTools_MapIteratorOfMapOfShape it(aNbs);
596 for(;it.More();it.Next()) {
597 if(aDM.Contains(it.Key())) {
598 TNaming_MapOfShape aMS;
599 const TopTools_ListOfShape& aL = aDM.FindFromKey(it.Key());
600 TopTools_ListIteratorOfListOfShape lit(aL);
601 for(;lit.More();lit.Next()) {
602 aM.Add(lit.Value());
603 aMS.Add(lit.Value());
604 }
605 if(aMS.Extent())
606 aDMM.Bind(it.Key(), aMS);
607 } else {
0797d9d3 608#ifdef OCCT_DEBUG
7fd59977 609 cout << "Key is not BOUND!" <<endl;
610#endif
611 return Standard_False;
612 }
613 }
614
615 Standard_Boolean isCommon(Standard_True);
616 TNaming_MapIteratorOfMapOfShape itm(aM);
617 for(;itm.More();itm.Next()) {
618 isCommon = Standard_True; // statement: this shape (itm.Key()) is common (to be checked below)
619 TNaming_DataMapIteratorOfDataMapOfShapeMapOfShape itdm(aDMM);
620 for (;itdm.More();itdm.Next()) {
7fd59977 621 const TNaming_MapOfShape& aMap = itdm.Value();
622 if(!aMap.Contains(itm.Key())) {
623 isCommon = Standard_False;
624 break;
625 }
626 }
627 if(isCommon) break; // common single face found
628 }
629 if(isCommon && aM.Extent() < aNbs.Extent()) {// number of unique faces (to have single solution)
630 //should be at least no less than (Nb of Neighbourgs) +1
631 return Standard_True;
632 }
633 return Standard_False;
634}
635//=======================================================================
636//function : Filter
637//purpose : sets the name with type "FILTERBYNEIGHBOURGS" and returns true,
638// : if it was correctly done.
639// :
640// :
641//=======================================================================
642
643static Standard_Boolean Filter (const TDF_Label& F,
644 TNaming_Scope& MDF,
645 const TopoDS_Shape& S,
646 const TopoDS_Shape& Context,
647 TNaming_Localizer& Localizer,
648 Handle(TNaming_NamedShape)& NS,
649 const Standard_Integer Lev)
650{
651 // 1. Localizer.FindNeighbourg("Context", "S", "Neighbourg") - looks for neighbourgs of "S" with the same shape type in the "Context"
652 // shape and adds them to the "Neighbourg" map;
653 // 2. If "Neighbourg" map is empty, tries to do the same with the new context shape: shape from the father label of the "S" named shape;
654 // 3. If "Neighbourg" map is still empty, returns false;
655 // 4. Adds to the new child of label "L" new TNaming_Naming attribute with the next properties name: shape type is shape type of the "S",
656 // type is TNaming_FILTERBYNEIGHBOURGS, stop shape ( "Until" ) is "Context" of corresponding NamedShape;
657 // first argument of name is "NS" NamedShape.
658 // 5. Adds to the Name all shapes from "Neighbourg" map: build it with the BuildName( new generated TNaming_Naming attribute, MDF,
659 // argument shape from "Neighbourg", "Context", NextModif( "Until" ), true ) method.
660 // 6. Creates resulting NamedShape with the "Regenerate" ( it just calls TName::Solve method ) method from TNaming_Naming class.
661 // 7. If Compare( result NamedShape, MDF, stop, "S" ) returns true, "Filter" method returns true, else returns false.
662
663 //------------------------------
664 // Construction des voisins ==> of neighbors.
665 //------------------------------
666 Standard_Integer aLev(Lev);
667 TopTools_MapOfShape Neighbourg;
668 Localizer.FindNeighbourg (Context,S,Neighbourg);
0797d9d3 669#ifdef OCCT_DEBUG_NBS
7fd59977 670 //DbgTools::DisplayShape(Context, F, Quantity_NOC_GREEN);
671 //DbgTools::DisplayShape(S, F, Quantity_NOC_BLUE1);
672 Write(Context, "FNBS_Context.brep");
673 Write(S, "FNBS_S.brep");
efd4b232 674 Write(Neighbourg, "NBS");
7fd59977 675#endif
7fd59977 676 // mpv : NS and shape must be the same
677 Standard_Boolean isIn = Standard_False;
678 TNaming_Iterator anIter(NS);
679 for(;anIter.More();anIter.Next()) {
0797d9d3 680#ifdef OCCT_DEBUG
7fd59977 681 //DbgTools::DisplayShape(anIter.NewShape(), F, Quantity_NOC_RED);
682#endif
683 if (anIter.NewShape().IsSame(S)) {
684 isIn = Standard_True;
685 break;
686 }
687 }
688 if (!isIn) if (!TNaming_Tool::NamedShape(S,F).IsNull()) NS = TNaming_Tool::NamedShape(S,F);
689// if (!TNaming_Tool::NamedShape(S,F).IsNull()) NS = TNaming_Tool::NamedShape(S,F);
7fd59977 690
691 if (Neighbourg.IsEmpty()) {
692 // Recherche du vrai context. (Research of context truth)
693 Handle(TNaming_NamedShape) GenS = TNaming_Tool::NamedShape(S,NS->Label());
7fd59977 694 if (GenS.IsNull()) return Standard_False;
7fd59977 695 TDF_Label Father = (GenS->Label()).Father();
696 Father.FindAttribute(TNaming_NamedShape::GetID(),GenS);
697 TopoDS_Shape GoodContext = TNaming_Tool::GetShape(GenS);
698 Localizer.FindNeighbourg (GoodContext,S,Neighbourg);
699 }
700
701
702 if (Neighbourg.IsEmpty()) {
0797d9d3 703#ifdef OCCT_DEBUG
7fd59977 704 cout <<"FindNeighbourg: impossible"<<endl;
705#endif
706 return 0;
707 } else {
0797d9d3 708#ifdef OCCT_DEBUG_NBS
7fd59977 709 Write(Neighbourg, "Neighbourgs");
710#endif
711 aLev++;
712 //cout <<"Filter: Lev = " << aLev << endl;
713 }
714 if(aLev > 3) return 0;
715#ifdef ALLOW_CHILD_NBS
716 Handle(TNaming_Naming) aFNaming;
717 TopoDS_Shape aFatherCandSh;
718 F.FindAttribute(TNaming_Naming::GetID(), aFNaming);
719 if(!aFNaming.IsNull()) {
720 const TNaming_Name& aName = aFNaming->GetName();
721 if (aName.Type() == TNaming_FILTERBYNEIGHBOURGS) {
722 aFatherCandSh = aName.Arguments().First()->Get();
723 }
724 }
725 if(S.ShapeType() == TopAbs_EDGE && aFatherCandSh.IsNull()) {
726 //check the applicability
727 if(!NS.IsNull() && !NS->Get().IsNull() && NS->Get().ShapeType() == TopAbs_COMPOUND)
728 if(IsMultipleCase(S, Context, Neighbourg)) {
729 //cout << "Filter: ==> MultipleCase!" << endl;
730 NS->Label().FindAttribute(TNaming_Naming::GetID(), aFNaming);
731 if(!aFNaming.IsNull()) {
732 TNaming_Name& aName = aFNaming->ChangeName();
733 if (aName.Type() == TNaming_INTERSECTION) {
734 Standard_Integer ij(1);
735 TNaming_ListIteratorOfListOfNamedShape itA(aName.Arguments());
736 for (; itA.More(); itA.Next(), ij++) {
737 const TopoDS_Shape& aFace = TNaming_Tool::CurrentShape(itA.Value());
0797d9d3 738#ifdef OCCT_DEBUG_MOD
7fd59977 739 Write(aFace, "First_Face.brep");
740 cout <<"Selection TS = " << S.TShape()->This() <<endl;
741#endif
742 Standard_Integer i(1), indxW(0),indxE(0),nbW(0),nbE(0), indxF(0);
743 Standard_Boolean isFound(Standard_False);
744 TopoDS_Iterator it(aFace);
745 for (;it.More();it.Next(),i++) {
746 nbW++;
0797d9d3 747#ifdef OCCT_DEBUG_MOD
7fd59977 748 Write(it.Value(), "First_Wire.brep");
749#endif
750 if(!isFound) {
751 Standard_Integer j(1);
752 TopoDS_Iterator it2(it.Value());
753 for (;it2.More();it2.Next(),j++) {
754 nbE++;
0797d9d3 755#ifdef OCCT_DEBUG_MOD
7fd59977 756 Write(it2.Value(), "First_Wire.brep");
757 cout <<"Edge TS = " << it2.Value().TShape()->This() <<endl;
758#endif
759 if(S.IsEqual(it2.Value())) {
760 indxE = j;
761 indxW = i;
762 indxF = ij;
763 isFound = Standard_True;
764 }
765 }
766 }
767 }
768 if(isFound) {
769 Standard_Integer Index = indxE & 0x000000FF;
770 Index = Index | (nbE << 8);
771 Index = Index | (indxW << 16);
772 Index = Index | (nbW << 20);
773 Index = Index | (indxF << 24);
774 aName.Index(Index);
775 //------------------------------
776 // Compute the TNaming_NamedShape
777 //------------------------------
778 aFNaming->Regenerate(MDF.ChangeValid());
779 aFNaming->Label().FindAttribute(TNaming_NamedShape::GetID(),NS);
780 Handle (TNaming_NamedShape) Until = TNaming_Tool::NamedShape(Context,NS->Label());
781 Handle (TNaming_NamedShape) Stop = NextModif(Until);
782 if (Compare (NS,MDF,Stop,S)) return 1;
783 break;
784 }
785 }
786 }
787 }
788 return 0;
789 }
790 }
791#endif
792
793 //-----------------------------------------------------
794 // Construction function de naming. et insertion sous F
795 //-----------------------------------------------------
796 Handle (TNaming_Naming) NF = TNaming_Naming::Insert (F);
797
798 Handle (TNaming_NamedShape) Until = TNaming_Tool::NamedShape(Context,NS->Label());
799 Handle (TNaming_NamedShape) Stop = NextModif(Until);
800 TNaming_Name& theName = NF->ChangeName();
801 theName.ShapeType(S.ShapeType());
802 theName.Shape(S);
7dcac1df 803 theName.Orientation(S.Orientation());
7fd59977 804 theName.Type(TNaming_FILTERBYNEIGHBOURGS);
805 theName.Append(NS);
806 theName.StopNamedShape (Until);
0797d9d3 807#ifdef OCCT_DEBUG_NBS
7fd59977 808 cout << "FilterByNBS: ";
809 Print_Entry(NF->Label());
efd4b232 810 cout <<"AppendNS = " ;
811 Print_Entry(NS->Label());
7fd59977 812#endif
813 //---------------------
814 // Naming des voisins.
815 //---------------------
816
817 TopTools_MapIteratorOfMapOfShape itN(Neighbourg);
818 for (; itN.More(); itN.Next()) {
819#ifdef ALLOW_CHILD_NBS
820 const TopoDS_Shape& aS = itN.Key();
821 Handle (TNaming_NamedShape) aNS =
822 BuildName(NF->Label(), MDF, aS, Context, Stop, 1);
0797d9d3 823#ifdef OCCT_DEBUG_NBS
7fd59977 824 const TopoDS_Shape& aS2 = aNS->Get();
825 if(!aS.IsNull())
826 cout << "Shape arg type = " << aS.ShapeType() <<" TSH = " << aS.TShape()->This()<<endl;
efd4b232 827 if(!aS2.IsNull()) {
7fd59977 828 cout << "Build shape type = " << aS2.ShapeType() <<" TSH = " << aS2.TShape()->This()<<endl;
efd4b232 829 Write (aS2, "NBS_BuildShape.brep");
830 }
831 if(aNS.IsNull()) {
832 cout <<"AppendNS = " ;
833 Print_Entry(aNS->Label());
834 }
7fd59977 835#endif
836
837 const TopoDS_Shape aSNS = aNS->Get(); //allow child level
838 Standard_Boolean allowChild(Standard_True);
839 if(!aSNS.IsNull() && aSNS.ShapeType() == TopAbs_COMPOUND && !aFatherCandSh.IsNull())
840 allowChild = !IsContSame(aFatherCandSh, aSNS);
841 if(allowChild && !aSNS.IsNull() && aS.ShapeType() != aSNS.ShapeType() &&
842 aSNS.ShapeType() == TopAbs_COMPOUND)
843 { // aLev < 3
0797d9d3 844#ifdef OCCT_DEBUG_NBS
7fd59977 845 cout <<"Father label = ";
846 Print_Entry(aNS->Label().Father());
847 Write(aS,"SelectionS.brep");
848 Write(aSNS,"SelectionSNS.brep");
849#endif
850 Handle(TNaming_Naming) aNaming;
851 Standard_Boolean StandardFilter(Standard_True);
852 aNS->FindAttribute(TNaming_Naming::GetID(), aNaming);
853 if(!aNaming.IsNull()) {
854 const TNaming_Name& aName = aNaming->GetName();
855 if (aName.Type() == TNaming_GENERATION)
856 StandardFilter = Standard_False;
857 if(StandardFilter)
858 if (!Compare (aNS,MDF,Stop,aS)) {
859 TNaming_Localizer aLocalizer;
860 Filter (NF->Label(), MDF,aS,Context, aLocalizer,aNS, aLev);
861 }
862 }
863 }
864 theName.Append(aNS);
865#else
866 theName.Append(BuildName(NF->Label(), MDF, itN.Key(), Context, Stop, 1));
867#endif
868 }
869 //------------------------------
870 // Compute the TNaming_NamedShape
871 //------------------------------
872 NF->Regenerate(MDF.ChangeValid());
873 NF->Label().FindAttribute(TNaming_NamedShape::GetID(),NS);
874
875 //-----------------
876 // Check du filtre.
877 //-----------------
878 if (Compare (NS,MDF,Stop,S)) return 1;
0797d9d3 879#ifdef OCCT_DEBUG
7fd59977 880 cout <<"TNaming_Naming::Name Filter insufficient"<<endl;
881#endif
882 return 0;
883}
884
885
886//=======================================================================
887//function : BuildNameInNS
888//purpose : Calls BuildName method, but with new context and new stop shape.
889// : Context is searched at the father label of the "Context" label :
890// : old shapes from the NamedShape at the defined father label.
891// : If it's impossible, then "S" set as context.
892// : If "S" is in new context, then stop shape is named shape,
893// : which belongs to the father label of the "Context" named shape.
894// : For example, face (F2) of prism (P) is generated from the edge (E)
895// : of primitive face (F1) of box (B). F2 is named as GENERATION from E.
896// : Naming of E is done with help BuildNameInNS function:
897// : with context B and stop shape P.
898//=======================================================================
899static Handle(TNaming_NamedShape) BuildNameInNS (const TDF_Label& F,
900 TNaming_Scope& MDF,
901 const TopoDS_Shape& S,
902 const Handle(TNaming_NamedShape)& Context,
903 const Handle(TNaming_NamedShape)& Stop,
904 const Standard_Boolean Geometry)
905
906{
907 // il faut determiner un nouveau context et un nouveau Stop.
1ec8a59e 908 // it is necessary to determine a new context and a new Stop
7fd59977 909 TopoDS_Shape SC;
910 Handle(TNaming_NamedShape) NewStop = Stop;
911
912 TNaming_Localizer::FindShapeContext (Context,S,SC);
913
914 if(!SC.IsNull()){
915// <Context> is Ident.NamedShapeOfGeneration() ==
916 TDF_Label Father = Context->Label().Father();
917 Father.FindAttribute(TNaming_NamedShape::GetID(),NewStop);
0797d9d3 918#ifdef OCCT_DEBUG_INNS
7fd59977 919 if(!Stop.IsNull())
920 {cout <<" Stop NS : "; Print_Entry( Stop->Label());}
921 if(!NewStop.IsNull())
922 {cout <<" NewStop : "; Print_Entry( NewStop->Label());}
923 cout <<"ContextLabel: "; Print_Entry( Context->Label());
924 cout <<"Father : "; Print_Entry( Father);
925#endif
926 }
0797d9d3 927#ifdef OCCT_DEBUG_INNS
7fd59977 928 if(NewStop.IsNull())
929 cout <<"BuildNameInNS:: NewStop shape is NULL" << endl;
930#endif
931 return BuildName (F,MDF,S,SC,NewStop,Geometry);
932}
933
934//=======================================================================
935//function :
936//purpose :
937//=======================================================================
938
939static Handle(TNaming_NamedShape) BuildName (const TDF_Label& F,
940 TNaming_Scope& MDF,
941 const TopoDS_Shape& Selection,
942 const TopoDS_Shape& Context,
943 const Handle(TNaming_NamedShape)& Stop,
944 const Standard_Boolean Geom)
945{
946
947
948
949 // Create an identifier
950 Standard_Boolean OnlyOne = !Geom;
951 Standard_Boolean IsGeneration = Standard_False;
0797d9d3 952#ifdef OCCT_DEBUG_MOD
7fd59977 953 cout <<"BuildName: F => ";
954 Print_Entry(F);
955 cout <<" Selection type = " << Selection.ShapeType() << " TS = " << Selection.TShape()->This() << endl;
956 Write(Selection, "BName_Selection.brep");
957 Write(Context, "BName_Context.brep");
958#endif
959 TNaming_Identifier Ident(F, Selection, Context,OnlyOne);
960
961 Handle (TNaming_Naming) Naming;
962 Handle (TNaming_NamedShape) NS;
963
964 if (!Ident.IsDone()) {
965 return BuildNS (F,Selection, TNaming_UNKNOWN);
966 }
967 if (Ident.IsFeature() && Stop.IsNull()) {
968 //-------------
969 // Deja Nomme
970 //-------------
971 if (!OnlyOne) return Ident.FeatureArg();
972 else NS = Ident.FeatureArg();
973 }
974 else {
975 //---------------------------------------------
976 // Construction de la fonction d identification.
977 //---------------------------------------------
978 //Standard_Boolean NotOnlyOne = 0;
979
980 Naming = TNaming_Naming::Insert(F);
981
982 TNaming_Name& theName = Naming->ChangeName();
983 theName.ShapeType(Selection.ShapeType());
984 theName.Shape(Selection);
7dcac1df 985 theName.Orientation(Selection.Orientation());
7fd59977 986 theName.Type(Ident.Type());
0797d9d3 987#ifdef OCCT_DEBUG_MOD
7fd59977 988 cout <<"BuildName: Inserted Naming Att at ";
989 Print_Entry(Naming->Label());
990 cout <<" NameType = " << theName.Type() <<endl;
991#endif
992 if (Ident.IsFeature()) {
993 theName.Append(Ident.FeatureArg());
994 }
995 if (theName.Type() == TNaming_GENERATION) {
996 theName.Append(Ident.NamedShapeOfGeneration());
997 IsGeneration = Standard_True;
998 }
999 if (theName.Type() == TNaming_CONSTSHAPE) {
1000 theName.Index(FindIndex(Ident.FeatureArg(),Selection));
1001 }
1002 //------------------------------------
1003 // Renseignement du NamedShape d arret.
1004 //------------------------------------
1005 theName.StopNamedShape (Stop);
0797d9d3 1006#ifdef OCCT_DEBUG_MOD
7fd59977 1007 if(!Stop.IsNull()) {
1008 TCollection_AsciiString Es;
1009 TDF_Tool::Entry(Stop->Label(), Es);
1010 cout <<"StopNS at Label = "<< Es << endl;
1011 }
1012#endif
1013 //---------------------------------
1014 // Identification des arguments.
1015 //---------------------------------
1016
1017 for (Ident.InitArgs(); Ident.MoreArgs(); Ident.NextArg()) {
1018 if (Ident.ArgIsFeature()) {
1019 theName.Append(Ident.FeatureArg());
0797d9d3 1020#ifdef OCCT_DEBUG_MOD
7fd59977 1021 if(!Ident.FeatureArg().IsNull()) {
1022 TCollection_AsciiString E;
1023 TDF_Tool::Entry(Ident.FeatureArg()->Label(), E);
1024 cout <<"Added argument NS from Label = "<< E << endl;
1025 }
1026#endif
1027 }
1028 else {
0797d9d3 1029#ifdef OCCT_DEBUG_MOD
7fd59977 1030 cout <<"BuildName: NameType = " <<theName.Type() << " NS ";
1031 Print_Entry(Naming->Label());
1032 cout <<"Ident.ShapeArg() type = " << Ident.ShapeArg().ShapeType() << " TS = " << Ident.ShapeArg().TShape()->This() << endl;
1033 Write(Ident.ShapeArg(), "BName_ShapeArg.brep");
1034#endif
1035 if (theName.Type() == TNaming_GENERATION)
1036 theName.Append(BuildNameInNS(Naming->Label(),MDF,Ident.ShapeArg(),Ident.NamedShapeOfGeneration(),Stop,Geom));
1037 else
1038 theName.Append(BuildName(Naming->Label(),MDF,Ident.ShapeArg(),Context,Stop,Geom));
1039 }
1040 }
1041
1042 //------------------------
1043 // Reconstruction of Name
1044 //------------------------
1045 Naming->Regenerate(MDF.ChangeValid());
0797d9d3 1046#ifdef OCCT_DEBUG_MOD
7fd59977 1047 TCollection_AsciiString E2;
1048 TDF_Tool::Entry(Naming->Label(), E2);
1049 cout <<"Regenerated Naming Att at Label = "<< E2 << endl;
1050#endif
1051 Naming->Label().FindAttribute(TNaming_NamedShape::GetID(),NS);
1052 if(NS.IsNull()) return NS;
1053 if (MDF.WithValid()) MDF.Valid(NS->Label());
0797d9d3 1054#ifdef OCCT_DEBUG_MOD
7fd59977 1055 if(!NS.IsNull()) {
1056 TCollection_AsciiString E;
1057 TDF_Tool::Entry(NS->Label(), E);
1058 cout <<"Regenerated NS at Label = "<< E << endl;
1059 }
1060#endif
1061 }
1062
1063 if (OnlyOne) {
1064 //-------------------------------------------------
1065 // Filtre par les voisins
1066 // pour construire le nom correspondant a S.
1067 //-------------------------------------------------
1068
7fd59977 1069 if(NS.IsNull()) return NS;
7fd59977 1070
1071 TNaming_Localizer Localizer;
1072 TNaming_Iterator itNS(NS);
1073 if (itNS.More()) {
1074 //----------------
1075 // Check + Filtre
1076 //----------------
1077
7fd59977 1078 Standard_Boolean StandardFilter = !IsGeneration;
1079 if (IsGeneration) {
1080 if (!CompareInGeneration (NS,Selection)) {
1081
1082 TopoDS_Shape NewContext;
1083 Handle(TNaming_NamedShape) NewStop;
1084 FindNewShapeInFather (Ident.NamedShapeOfGeneration(),NewContext);
1085 Filter (F,MDF,Selection,NewContext,Localizer,NS,0);
1086 }
1087 } else if (Ident.Type() == TNaming_MODIFUNTIL ||
1088 (Ident.Type() == TNaming_INTERSECTION && Naming->ChangeName().Arguments().Extent() == 1)) {
0797d9d3 1089#ifdef OCCT_DEBUG_MOD
7fd59977 1090 cout <<"BuildName(CompareInModification): NameType = " <<Ident.Type() << " NS ";
1091 Print_Entry(Ident.Type() == TNaming_MODIFUNTIL ? NS->Label() : Naming->ChangeName().Arguments().First()->Label());
1092 cout <<"Selection type = " << Selection.ShapeType() << " TS = " << Selection.TShape()->This() << endl;
1093#endif
1094 Handle(TNaming_NamedShape) NewNS =
1095 CompareInModification(Ident.Type() == TNaming_MODIFUNTIL ? NS : Naming->ChangeName().Arguments().First(), Selection);
1096 if (!NewNS.IsNull()) { // there is need to describe name in detail: modification with type 1:n in the same label
1097 StandardFilter = Standard_False;
1098 if (Ident.IsFeature()) { // for MODIFUNTIL: change it to the GENERATION
1099 Naming = TNaming_Naming::Insert(F);
1100 TNaming_Name& theName = Naming->ChangeName();
1101 theName.ShapeType(Selection.ShapeType());
7dcac1df 1102 theName.Shape(Selection);
1103 theName.Orientation(Selection.Orientation());
7fd59977 1104 theName.Type(TNaming_GENERATION);
1105 theName.Append(TNaming_Tool::NamedShape(Selection,F));
1106 theName.Append(NewNS);
1107 Naming->Regenerate(MDF.ChangeValid());
1108 Naming->Label().FindAttribute(TNaming_NamedShape::GetID(),NS);
1109
1110 }
1111 Filter (F,MDF,Selection,Context,Localizer,NS,0);
1112 }
1113 }
1114 if (StandardFilter) if (!Compare (NS,MDF,Stop,Selection)) {
1115 Filter (F,MDF,Selection,Context,Localizer,NS,0);
1116 }
7fd59977 1117 }
1118 }
1119 if (MDF.WithValid()) MDF.Valid(NS->Label());
0797d9d3 1120#ifdef OCCT_DEBUG_MOD
7fd59977 1121 if(!NS.IsNull()) {
1122 TCollection_AsciiString E;
1123 TDF_Tool::Entry(NS->Label(), E);
1124 cout <<"Returned NS from Label = "<< E << endl;
1125 }
1126#endif
1127 return NS;
1128}
1129
1130//=======================================================================
1131//function : Validate
1132//purpose :
1133//=======================================================================
1134
1135static void Validate(TNaming_Scope& MDF,
1136 TNaming_OldShapeIterator& it)
1137{
1138 MDF.Valid(it.Label());
1139 MDF.ValidChildren(it.Label());
1140
1141 TNaming_OldShapeIterator it2(it);
1142 for (; it2.More(); it2.Next()) {
1143 Validate (MDF,it2);
1144 }
1145}
1146
1147//=======================================================================
1148//function : UnValidate
1149//purpose :
1150//=======================================================================
1151
1152static void UnValidate(TNaming_Scope& MDF,
1153 TNaming_NewShapeIterator& it)
1154{
1155 MDF.Unvalid(it.Label());
1156 MDF.UnvalidChildren(it.Label());
1157
1158 TNaming_NewShapeIterator it2(it);
1159 for (; it2.More(); it2.Next()) {
1160 UnValidate (MDF,it2);
1161 }
1162}
1163
1164//=======================================================================
1165//function : BuildScope
1166//purpose : adds to the MDF the label of <Context> NamedShape,
1167// : its children, all its oldShapes and its children.
1168// : unvalidates all newShapes and it's children.
1169// : If <Context> is null or next modification has an empty newShape
1170// : ( this shape was deleted ), then MDF.WithValid(Standard_False)
1171// : and nothing is added to the scope.
1172//=======================================================================
1173
1174static void BuildScope (TNaming_Scope& MDF,
1175 const TopoDS_Shape& Context,
1176 const TDF_Label& Acces)
1177{
1178 if (Context.IsNull()) {
1179 MDF.WithValid(Standard_False);
1180 return;
1181 }
1182
1183 //----------------------------------------------------
1184 // Is context the current state
1185 //----------------------------------------------------
1186 Handle(TNaming_NamedShape) NS = TNaming_Tool::NamedShape(Context,Acces);
1187 Handle(TNaming_NamedShape) Next = NextModif(NS); // if NS has subsequent evolution = MODIFY, return it
1188 if (Next.IsNull()) {
1189 MDF.WithValid(Standard_False);
1190 return;
1191 }
1192 //-----------------------------
1193 // a posteriori naming
1194 //-----------------------------
1195 MDF.WithValid(Standard_True);
1196 MDF.Valid(NS->Label());
1197 MDF.ValidChildren(NS->Label());
1198 TNaming_OldShapeIterator it(Context,Acces);
1199
1200 for (; it.More(); it.Next()) {
1201 Validate(MDF,it);
1202 }
1203
1204 TNaming_NewShapeIterator it2(Context,Acces);
1205 for (;it2.More(); it2.Next()) {
1206 UnValidate (MDF,it2);
1207 }
1208}
1209
1210//=======================================================================
1ec8a59e 1211//function : HasAncFace
1212//purpose : Returns True & <Face> if ancestor face is found
1213//=======================================================================
7fd59977 1214static Standard_Boolean HasAncFace(const TopoDS_Shape& Context,
1ec8a59e 1215 const TopoDS_Shape& W, TopoDS_Shape& Face, Standard_Boolean& isOuter)
7fd59977 1216{
1217 Standard_Boolean hasFace(Standard_False);
1218 if(W.ShapeType() != TopAbs_WIRE)
1219 return hasFace;
1220 TopExp_Explorer exp(Context, TopAbs_FACE);
1221 for(;exp.More(); exp.Next()) {
1222 for (TopoDS_Iterator it(exp.Current()) ; it.More(); it.Next()) {
1223 if(it.Value().IsEqual(W)) {// is the Wire ?
1ec8a59e 1224 Face = exp.Current();
1225 if(!Face.IsNull()) {
1226 hasFace = Standard_True;
1227 // cout << "HasAncFace: TS = " <<theFace.TShape()->This() <<endl;
1228 const TopoDS_Face aFace(TopoDS::Face(Face));
1229 TopoDS_Wire anOuterW;
1230 if(TNaming::OuterWire(aFace, anOuterW)) {
1231 if(!anOuterW.IsNull() && anOuterW.IsEqual(W))
1232 isOuter = Standard_True;
1233 else
1234 isOuter = Standard_False;
1235 }
1236 break;
1237 }
1238 }
1239 }
7fd59977 1240 if(hasFace) break;
1241 }
1242 return hasFace;
1243}
1244
1245//=======================================================================
1246//function : BuildNameWire
1247//purpose : Names Wire
1248//=======================================================================
1249
1250static Handle(TNaming_NamedShape) BuildNameWire (const TDF_Label& F,
1251 TNaming_Scope& MDF,
1252 const TopoDS_Shape& Selection,
1253 const TopoDS_Shape& Context,
1254 const Handle(TNaming_NamedShape)& Stop,
1255 const Standard_Boolean Geom)
1256{
1257 Handle (TNaming_NamedShape) NS;
1258 Standard_Boolean found(Standard_False);
1259 Handle (TNaming_Naming) Naming;
1260 if(!F.FindAttribute(TNaming_Naming::GetID(), Naming)) {
1261 Naming = new TNaming_Naming ();
1262 F.AddAttribute (Naming);
1263 TNaming_Name& theName = Naming->ChangeName();
1264 theName.ShapeType(Selection.ShapeType());
7dcac1df 1265 theName.Shape(Selection);
1266 theName.Orientation(Selection.Orientation());
7fd59977 1267 }
1268
1269 TNaming_Name& theName = Naming->ChangeName();
1270 TopoDS_Shape aFace;
1ec8a59e 1271 Standard_Boolean isOuter(Standard_False);
1272 Standard_Boolean hasFace = HasAncFace(Context, Selection, aFace, isOuter);
1273 if(hasFace && Selection.ShapeType() > Context.ShapeType()) {
7fd59977 1274 theName.Type(TNaming_WIREIN);
1ec8a59e 1275 if(Context.ShapeType() == TopAbs_FACE) {
1276 for (TopoDS_Iterator it(Context) ; it.More(); it.Next()) {
1277 if(it.Value().IsEqual(Selection)) {
1278 if (TNaming_Selector::IsIdentified (F, Context, NS, Geom)) {
1279 theName.Append(NS);
1280 found = Standard_True;
1281 break;
1282 }
1283 }
7fd59977 1284 }
1ec8a59e 1285 if(found) {
1286 theName.Append(BuildName (Naming->Label(),MDF,aFace,Context,Stop,Geom));
1287 if(isOuter) {
1288 theName.Index(1);
1289 } else {
1290 theName.Index(-1);
1291 for (TopExp_Explorer exp(Selection,TopAbs_EDGE) ; exp.More(); exp.Next()) {
1292 if(exp.Current().IsNull()) continue;
1293 if (BRep_Tool::Degenerated(TopoDS::Edge(exp.Current()))) continue;
1294 theName.Append(TNaming_Naming::Name(Naming->Label(),exp.Current(),Context, Geom, 1, 0));
1295 }
1296 }
1297 } else
1298 return BuildNS (F,Selection, TNaming_UNKNOWN);
1299
1300 } else { // context is not Face
1301 theName.Append(BuildName (Naming->Label(),MDF,aFace,Context,Stop,Geom));
1302 if(isOuter) {
1303 theName.Index(1);
1304 } else {
1305 for (TopExp_Explorer exp(Selection,TopAbs_EDGE) ; exp.More(); exp.Next()) {
1306 if(exp.Current().IsNull()) continue;
1307 if (BRep_Tool::Degenerated(TopoDS::Edge(exp.Current()))) continue;
1308 theName.Append(TNaming_Naming::Name(Naming->Label(),exp.Current(),Context, Geom, 1, 0));
1309 }
1310 }
1311 }//
1312 }
1313 else { // => no Face
7fd59977 1314 theName.Type(TNaming_UNION);
1315 for (TopExp_Explorer exp(Selection,TopAbs_EDGE) ; exp.More(); exp.Next()) {
1ec8a59e 1316 if(exp.Current().IsNull()) continue;
1317 if (BRep_Tool::Degenerated(TopoDS::Edge(exp.Current()))) continue;
7fd59977 1318 theName.Append(BuildName (Naming->Label(),MDF,exp.Current(),Context,Stop,Geom));
1319 }
1320 }
1321 //Naming->GetName().Solve(Naming->Label(),MDF.GetValid());
1322 Naming->Label().FindAttribute(TNaming_NamedShape::GetID(),NS);
1323 return NS;
1324}
1325
1326//=======================================================================
1327static Standard_Boolean IsOneIn (const TopoDS_Shape& S, const TopoDS_Shape& Context)
1328{
1329 Standard_Boolean found(Standard_False);
1330 if(S.IsNull() || Context.IsNull()) return found;
1331 for (TopExp_Explorer exp(Context,S.ShapeType()); exp.More(); exp.Next()) {
1332 if (exp.Current().IsEqual(S)) {
1333 found = Standard_True;
1334 break;
1335 }
1336 }
1337 return found;
1338}
1339
1340//=======================================================================
1341static Standard_Boolean IsAllIn (const TopoDS_Shape& S, const TopoDS_Shape& Context)
1342{
0797d9d3 1343#ifdef OCCT_DEBUG_CC
7fd59977 1344 Write(S, "IsAllIn_Sel.brep");
1345#endif
1346 Standard_Boolean found(Standard_False);
1347 if(S.IsNull() || Context.IsNull()) return found;
1348 Standard_Integer num1(0), num2(0);
1349 for(TopoDS_Iterator it(S);it.More();it.Next(),num1++) {
0797d9d3 1350#ifdef OCCT_DEBUG_CC
7fd59977 1351 cout <<"S sub-shape type = " << it.Value().ShapeType() <<endl;
1352 Write (it.Value(), "Sel_ItValue.brep");
1353#endif
1354 if(it.Value().ShapeType() != TopAbs_COMPOUND)
1355 for (TopExp_Explorer exp(Context,it.Value().ShapeType()); exp.More(); exp.Next()) {
0797d9d3 1356#ifdef OCCT_DEBUG_CC
7fd59977 1357 cout <<"Context sub-shape type = " << exp.Current().ShapeType() <<endl;
1358 Write(exp.Current(), "Contex_Curnt.brep");
1359#endif
1360 if (exp.Current().IsEqual(it.Value())) {
1361 num2++;
1362 break;
1363 }
1364 } else {
1365 Standard_Boolean isAll = IsAllIn(it.Value(), Context);
1366 if(isAll)
1367 num2++;
1368 }
1369 }
1370 if(num1 == num2)
1371 found = Standard_True;
0797d9d3 1372#ifdef OCCT_DEBUG_CC
7fd59977 1373 else
1374 cout <<"Compound case : selected num1 = " << num1 << " context contains num2 = " << num2 << endl;
1375#endif
1376 return found;
1377}
1378//=======================================================================
1379//function : RepeatabilityInContext
1380//purpose :
1381//=======================================================================
1382static Standard_Integer RepeatabilityInContext(const TopoDS_Shape& Selection,
1383 const TopoDS_Shape& Context)
1384{
1385 Standard_Integer aNum(0);
1386 if (!Context.IsNull() && !Selection.IsNull()) {
1387// Write(Selection, "Repeat_Selection.brep");
1388// Write(Context, "Repeat_Context.brep");
1389 if (Context.ShapeType() < Selection.ShapeType()) {
1ec8a59e 1390 if(Selection.ShapeType() != TopAbs_SHELL) {
1391 for (TopExp_Explorer exp(Context,Selection.ShapeType()); exp.More(); exp.Next()) {
1392 if (exp.Current().IsSame(Selection))
1393 aNum++;
1394 }
1395 }
1396 }
7fd59977 1397 else if(Selection.ShapeType() == TopAbs_COMPOUND) {
1398 TopoDS_Iterator it(Selection);
1399 for(;it.More();it.Next()) {
1400 Standard_Integer n(0);
1401 for (TopExp_Explorer exp(Context,it.Value().ShapeType()); exp.More(); exp.Next()) {
1402 if (exp.Current().IsSame(it.Value())) {
1403 n++;
1404 }
1405 }
1406 if(n > aNum) aNum = n;
1407 }
1408 }
1409 }
0797d9d3 1410#ifdef OCCT_DEBUG_OR
7fd59977 1411 cout <<"RepeatabilityInContext: = " <<aNum <<endl;
1412#endif
1413 return aNum;
1414}
1ec8a59e 1415
1416//=======================================================================
1417//function : HasAncSolid
1418//purpose : Returns true if Sh has ancestor solid in this context
1419//=======================================================================
1420static Standard_Boolean HasAncSolid(const TopoDS_Shape& Context,
1421 const TopoDS_Shape& Sh, TopoDS_Shape& Solid,
1422 Standard_Boolean& isOuter)
1423{
1424 Standard_Boolean hasSolid(Standard_False);
1425 if(Sh.ShapeType() != TopAbs_SHELL)
1426 return hasSolid;
1427 TopExp_Explorer exp(Context, TopAbs_SOLID);
1428 for(;exp.More(); exp.Next()) {
1429 for (TopoDS_Iterator it(exp.Current()) ; it.More(); it.Next()) {
1430 if(it.Value().IsEqual(Sh)) {// is the Solid ?
1431 Solid = exp.Current();
1432 if(!Solid.IsNull()) {
1433 hasSolid = Standard_True;
1434 TopoDS_Shell anOuterShell;
1435 if(TNaming::OuterShell(TopoDS::Solid(Solid), anOuterShell)) {
0797d9d3 1436#ifdef OCCT_DEBUG_TSOL
1ec8a59e 1437 Write(anOuterShell, "OuterShell.brep");
1438#endif
1439 if(!anOuterShell.IsNull() && anOuterShell.IsEqual(Sh))
1440 isOuter = Standard_True;
1441 else
1442 isOuter = Standard_False;
1443 }
1444 break;
1445 }
1446 }
1447 }
1448 if(hasSolid) break;
1449 }
1450 return hasSolid;
1451}
1452//=======================================================================
1453//function : BuildNameShell
1454//purpose : Names Shell
1455//=======================================================================
1456
1457static Handle(TNaming_NamedShape) BuildNameShell (const TDF_Label& F,
1458 TNaming_Scope& MDF,
1459 const TopoDS_Shape& Selection,
1460 const TopoDS_Shape& Context,
1461 const Handle(TNaming_NamedShape)& Stop,
1462 const Standard_Boolean Geom)
1463{
1464 Handle (TNaming_NamedShape) NS;
1465 Standard_Boolean found(Standard_False);
1466 Handle (TNaming_Naming) Naming;
1467 if(!F.FindAttribute(TNaming_Naming::GetID(), Naming)) {
1468 Naming = new TNaming_Naming ();
1469 F.AddAttribute (Naming);
1470 TNaming_Name& theName = Naming->ChangeName();
1471 theName.ShapeType(Selection.ShapeType());
7dcac1df 1472 theName.Shape(Selection);
1473 theName.Orientation(Selection.Orientation());
1ec8a59e 1474 }
1475
1476 TNaming_Name& theName = Naming->ChangeName();
1477 TopoDS_Shape aSolid;
1478 Standard_Boolean isOuter(Standard_False);
1479 Standard_Boolean hasSolid = HasAncSolid(Context, Selection, aSolid, isOuter);
1480 if(hasSolid && Selection.ShapeType() > Context.ShapeType()) {
1481 theName.Type(TNaming_SHELLIN);// SHELLIN
1482
1483 if(Context.ShapeType() == TopAbs_SOLID) {
1484 for (TopoDS_Iterator it(Context) ; it.More(); it.Next()) {
0797d9d3 1485#ifdef OCCT_DEBUG_TSOL
1ec8a59e 1486 Write(it.Value(), "Shell_inSo.brep");
1487#endif
1488 if(it.Value().IsEqual(Selection)) {
1489 found = Standard_True;
1490 break;
1491 }
1492 }
1493 if(found) {
1494 // solid => aSolid which is also a context
1495 Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(Context,F);
1496 if(!aNS.IsNull())
1497 theName.ContextLabel(aNS->Label());
1498 theName.Append(aNS);
1499 if(isOuter) {
1500 theName.Index(1);
1501 } else { //not OuterShell
1502 theName.Index(-1);
1503 for (TopExp_Explorer exp(Selection,TopAbs_FACE) ; exp.More(); exp.Next()) {
1504 if(exp.Current().IsNull()) continue;
1505 theName.Append(BuildName (Naming->Label(),MDF,exp.Current(),Context,Stop,Geom));
1506 }
1507 }
1508 } else
1509 return BuildNS (F,Selection, TNaming_UNKNOWN);
1510 } else {
1511 // context is not SOLID
1512 //theName.Append(BuildName (Naming->Label(),MDF,aSolid,Context,Stop,Geom));//###########
1513 if(isOuter) {
0797d9d3 1514#ifdef OCCT_DEBUG_TSOL
1ec8a59e 1515 Write(aSolid, "foundSolid.brep");
1516#endif
1517 theName.Index(1);
1518 Handle (TNaming_Naming) NamingSo = TNaming_Naming::Insert(F);
1519 TNaming_Name& theNameSo = NamingSo->ChangeName();
1520 theNameSo.ShapeType(aSolid.ShapeType());
1521 theNameSo.Shape(aSolid);
1522 theNameSo.Type(TNaming_UNION);
1523 Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(Context,F);
1524 if(!aNS.IsNull())
1525 theNameSo.ContextLabel(aNS->Label());
1526 for (TopExp_Explorer exp(aSolid,TopAbs_FACE) ; exp.More(); exp.Next())
1527 theNameSo.Append(BuildName (NamingSo->Label(),MDF,exp.Current(),Context,Stop,Geom));
1528 NamingSo->GetName().Solve(NamingSo->Label(),MDF.GetValid());
1529 aNS.Nullify();
1530 NamingSo->Label().FindAttribute(TNaming_NamedShape::GetID(),aNS);
1531 theName.Append(aNS);
1532 } else {
1533 theName.Index(-1);
1534 // - name Solid: theName.Append(BuildName (Naming->Label(),MDF, aSolid,Context,Stop,Geom));
1535 Handle (TNaming_Naming) NamingSo = TNaming_Naming::Insert(F);
1536 TNaming_Name& theNameSo = NamingSo->ChangeName();
1537 theNameSo.ShapeType(aSolid.ShapeType());
1538 theNameSo.Shape(aSolid);
1539 theNameSo.Type(TNaming_UNION);
1540 Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(Context,F);
1541 if(!aNS.IsNull())
1542 theNameSo.ContextLabel(aNS->Label());
1543 for (TopExp_Explorer exp(aSolid,TopAbs_FACE) ; exp.More(); exp.Next())
1544 theNameSo.Append(BuildName (NamingSo->Label(),MDF,exp.Current(),Context,Stop,Geom));
1545 NamingSo->GetName().Solve(NamingSo->Label(),MDF.GetValid());
1546 aNS.Nullify();
1547 NamingSo->Label().FindAttribute(TNaming_NamedShape::GetID(),aNS);
1548 theName.Append(aNS);
1549
1550 for (TopExp_Explorer exp(Selection,TopAbs_FACE) ; exp.More(); exp.Next()) {
1551 if(exp.Current().IsNull()) continue;
1552 theName.Append(BuildName (Naming->Label(),MDF,exp.Current(),Context,Stop,Geom));
1553 }
1554 }
1555 }//
1556 }
1557 else { // => no Solid
1558 theName.Type(TNaming_UNION);
1559 Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(Context,F);
1560 if(!aNS.IsNull())
1561 theName.ContextLabel(aNS->Label());
1562 for (TopExp_Explorer exp(Selection,TopAbs_FACE) ; exp.More(); exp.Next()) {
1563 if(exp.Current().IsNull()) continue;
1564 theName.Append(BuildName (Naming->Label(),MDF,exp.Current(),Context,Stop,Geom));
1565 }
1566 }
1567 //Naming->GetName().Solve(Naming->Label(),MDF.GetValid());
1568 Naming->Label().FindAttribute(TNaming_NamedShape::GetID(),NS);
1569 return NS;
1570}
1571
7fd59977 1572//=======================================================================
1573//function : BuildAggregationNam
1574//purpose :
1575//=======================================================================
1576static void BuildAggregationName (const TDF_Label& F,
1577 TNaming_Scope& MDF,
1578 const TopoDS_Shape& S,
1579 const TopoDS_Shape& Context,
1580 const Handle(TNaming_NamedShape)& Stop,
1581 const Standard_Boolean Geom)
1582{
1583 const Standard_Boolean found2 = IsAllIn(S, Context);
1584 Handle (TNaming_Naming) Naming;
1585 if(!F.FindAttribute(TNaming_Naming::GetID(), Naming)) {
1586 Naming = new TNaming_Naming ();
1587 F.AddAttribute (Naming);
1588 TNaming_Name& theName = Naming->ChangeName();
1589 theName.ShapeType(S.ShapeType());
1590 theName.Shape(S);
7dcac1df 1591 theName.Orientation(S.Orientation());
7fd59977 1592 }
0797d9d3 1593#ifdef OCCT_DEBUG_CC
7fd59977 1594 cout <<"BuildAggregationName ==> ";
1595 Print_Entry(Naming->Label());
1596#endif
1597 TNaming_Name& theName = Naming->ChangeName();
1598 for (TopoDS_Iterator itc(S) ; itc.More(); itc.Next()) {
1599 const TopoDS_Shape& aS = itc.Value();
1600 if ((aS.ShapeType() == TopAbs_SOLID && !TNaming_Tool::NamedShape(aS,Naming->Label()).IsNull()) ||
1601 aS.ShapeType() == TopAbs_FACE ||
1602 aS.ShapeType() == TopAbs_EDGE ||
1603 aS.ShapeType() == TopAbs_VERTEX ) {
1604 theName.Append(BuildName (F, MDF, aS,Context,Stop,Geom));
1605 } else { // ==> union of union || union of wires
1606 TopAbs_ShapeEnum atomTyp;
1607 switch (aS.ShapeType())
1608 {
1609 case TopAbs_SOLID:
1610 case TopAbs_SHELL:
1611 atomTyp = TopAbs_FACE;
1612 break;
1613 case TopAbs_WIRE:
1614 atomTyp = TopAbs_EDGE;
1615 break;
1616 default:
1617 atomTyp = TopAbs_SHAPE;
1618 }
1619
1620 Handle(TNaming_NamedShape) aNS;
1621 Handle (TNaming_Naming) aNaming = TNaming_Naming::Insert(F);
1622 TNaming_Name& aName = aNaming->ChangeName();
1623 aName.ShapeType(aS.ShapeType());
7dcac1df 1624 aName.Shape(aS);
1625 theName.Orientation(aS.Orientation());
7fd59977 1626 aName.Type(TNaming_UNION);
1627
1628 if (atomTyp != TopAbs_SHAPE) {
1629 if(aS.ShapeType() == TopAbs_WIRE) {
1630 aNS = BuildNameWire (aNaming->Label(), MDF, aS, Context,Stop,Geom);
1631 }
1ec8a59e 1632 else if(aS.ShapeType() == TopAbs_SHELL)
1633 aNS = BuildNameShell (aNaming->Label(), MDF, aS, Context,Stop,Geom);
7fd59977 1634 else {
1635 for (TopExp_Explorer exp(aS,atomTyp) ; exp.More(); exp.Next()) {
1636 aName.Append(BuildName (aNaming->Label(),MDF,exp.Current(),Context,Stop,Geom));
1637 }
1638 }
1639 } else {
0797d9d3 1640#ifdef OCCT_DEBUG_CC
7fd59977 1641 cout << "atomic type is NOT defined ... ==> Aggregation" <<endl;
1642#endif
1643 BuildAggregationName(aNaming->Label(),MDF, aS, Context,Stop,Geom);
1644 }
1645 if(found2) {
1646 aNS = TNaming_Tool::NamedShape(Context, F);
1647 if(!aNS.IsNull())
1648 aNaming->ChangeName().ContextLabel(aNS->Label());
1649 }
1650
1651 aNaming->GetName().Solve(aNaming->Label(),MDF.GetValid());
1652 if(aNaming->Label().FindAttribute(TNaming_NamedShape::GetID(),aNS))
1653 if (!Geom && TestSolution(MDF,aNS,aS)) {
1654 theName.Append(aNS);
1655 }
1656 }
1657 }
1658}
1659
1660
1661//=======================================================================
1662//function : Name
1663//purpose :
1664//=======================================================================
1665
1666Handle(TNaming_NamedShape) TNaming_Naming::Name (const TDF_Label& F,
1667 const TopoDS_Shape& S,
1668 const TopoDS_Shape& Context,
1669 const Standard_Boolean Geom,
1670 const Standard_Boolean KeepOrientation,
1671 const Standard_Boolean BNProblem)
1672
1673{
51740958 1674 Handle(TNaming_NamedShape) aNamedShape;
7fd59977 1675 if (KeepOrientation) {
0797d9d3 1676#ifdef OCCT_DEBUG_INNS
7fd59977 1677 cout <<"KeepOR = 1: "; Print_Entry(F);
1678#endif
1679 Standard_Integer aNum = RepeatabilityInContext(S, Context);
1680
1681 Standard_Boolean aBNproblem = (BNProblem) ? (aNum /*== 1*/ && S != Context) : Standard_False;
1682
1683 if (aNum > 1 || aBNproblem) {
1684 TopoDS_Shape UC = TNaming::FindUniqueContext(S, Context);
1685 Handle(TopTools_HArray1OfShape) Arr;
1686 if (UC.IsNull() && S.ShapeType() == TopAbs_COMPOUND) {
1687 UC = TNaming::FindUniqueContextSet(S, Context, Arr);
0797d9d3 1688#ifdef OCCT_DEBUG_CC
7fd59977 1689 Write(UC, "UniqueContextSet.brep");
1690 Write(S, "InitialSelection.brep");
1691 if(S.ShapeType()==TopAbs_COMPOUND) {
1692 TCollection_AsciiString aNam("S_");
1693 TopoDS_Iterator it(S);
1694 for(int i=1;it.More();it.Next(),i++) {
1695 TCollection_AsciiString aName = aNam + i + ".brep";
1696 Write(it.Value(), aName.ToCString());
1697 }
1698 }
1699#endif
1700 }
1701 if(!UC.IsNull()) {
1702 Handle (TNaming_Naming) Naming = TNaming_Naming::Insert(F);
1703 TNaming_Name& theName = Naming->ChangeName();
1704 theName.ShapeType(S.ShapeType());
1705 theName.Shape(S);
1706 theName.Type(TNaming_ORIENTATION);
7dcac1df 1707 theName.Orientation(S.Orientation());
7fd59977 1708
51740958 1709 if (!TNaming_Selector::IsIdentified (F, S, aNamedShape, Geom))
1710 aNamedShape = TNaming_Naming::Name(Naming->Label(),S,Context,Geom,0);
1711 theName.Append (aNamedShape);
7fd59977 1712#ifdef MDTV_OR
1713 cout << " Sel Label ==> "; Print_Entry(NS->Label());
1714#endif
1715//szy 21.10.2009
1716 if(S.ShapeType() == TopAbs_EDGE && UC.ShapeType() == TopAbs_FACE) {
1717 if(RepeatabilityInContext(S, UC) == 2) { //sim. edge
1718 TopoDS_Iterator itw(UC);
1719 for(;itw.More();itw.Next()) {
1720 Standard_Boolean found(Standard_False);
1721 TopoDS_Iterator it(itw.Value());
1722 for(int i=1;it.More();it.Next(),i++) {
1723 if(it.Value().IsEqual(S)) {
1ec8a59e 1724 theName.Index(i);//We use this field to save a Seam Shape Index; Before this field was used for GENERATED only
7fd59977 1725 found = Standard_True;
1726#ifdef MDTV_OR
1727 cout << "ORDER = " << i <<endl;
1728#endif
1729 break;
1730 }
1731 }
1732 if(found) break;
1733 }
1734 }
1735 }
1736//
1737 if(S.ShapeType() == TopAbs_COMPOUND && Arr->Length() > 1) {
1738 // N arguments: to be optimized to avoid duplication of the same Context shape
1739 for(Standard_Integer i = Arr->Lower(); i <= Arr->Upper(); i++) {
51740958 1740 aNamedShape = TNaming_Naming::Name(Naming->Label(), Arr->Value(i), Context, Geom, 1, aBNproblem);
1741 theName.Append (aNamedShape);
7fd59977 1742 }
1743 } else {
51740958 1744 aNamedShape = TNaming_Naming::Name(Naming->Label(),UC,Context, Geom, 1, aBNproblem);
1745 theName.Append (aNamedShape);
7fd59977 1746#ifdef MDTV_OR
1747 cout << " Cont Label ==> "; Print_Entry(NS->Label());
1748#endif
1749 }
1750 //Naming->Update();
1751 TNaming_Scope MDF;
1752 BuildScope (MDF,Context,F);
1753 Naming->GetName().Solve(Naming->Label(),MDF.GetValid());
51740958 1754 Naming->Label().FindAttribute(TNaming_NamedShape::GetID(), aNamedShape);
1755 theName.ContextLabel(aNamedShape->Label());
1756 if (Geom) return aNamedShape;
1757 if(aNamedShape.IsNull()) {
7fd59977 1758 cout <<" %%% WARNING: TNaming_Naming::Name: FAILED"<<endl;
1759 return BuildNS (F,S, TNaming_UNKNOWN);
1760 }
1761
51740958 1762 if (!Geom && TestSolution(MDF, aNamedShape,S)) return aNamedShape;
7fd59977 1763 cout <<" %%% WARNING: TNaming_Naming::Name: FAILED"<<endl;
1764
1765 // Naming n is unsatisfactory
1766 return BuildNS (F,S, TNaming_UNKNOWN);
1767 }
1768 } else
51740958 1769 if (TNaming_Selector::IsIdentified (F, S, aNamedShape, Geom))
1770 return aNamedShape;
7fd59977 1771 }
1772
1773 //------------------------------------------------------------
1774 // Construction du MDF tel que <Context> soit le dernier etat
1775 // valide,
1776 // Ceci pour les localisation a posteriori par exemple.
1777 //------------------------------------------------------------
1778
1779 TNaming_Scope MDF;
1780 BuildScope (MDF,Context,F);
1781 Handle(TNaming_NamedShape) Stop;
1782
7fd59977 1783
1784 if ((S.ShapeType() == TopAbs_SOLID && !TNaming_Tool::NamedShape(S,F).IsNull()) ||
1785
7fd59977 1786 S.ShapeType() == TopAbs_FACE ||
1787 S.ShapeType() == TopAbs_EDGE ||
1788 S.ShapeType() == TopAbs_VERTEX ) {
1789 //---------------------------------------
1790 // Localisation de S comme element simple.
1791 //---------------------------------------
1792 Handle(TNaming_NamedShape) NS = BuildName (F,MDF,S,Context,Stop,Geom);
1793 if (Geom) return NS;
1794 if (!Geom && TestSolution(MDF,NS,S)) return NS;
1795 }
1796 else {
1797 //----------------------------------------------------
1798 // Localisation de S comme ensemble d elements simples.
1799 //-----------------------------------------------------
1800 Handle(TNaming_NamedShape) NS;
1801 Handle (TNaming_Naming) Naming = TNaming_Naming::Insert(F);
1802 TNaming_Name& theName = Naming->ChangeName();
1803
1804 theName.ShapeType(S.ShapeType());// modified by vro 05.09.00
1805 theName.Shape(S);
7dcac1df 1806 theName.Orientation(S.Orientation());
7fd59977 1807 if(S.ShapeType() != TopAbs_WIRE)
1808 theName.Type(TNaming_UNION);
1809
7fd59977 1810 TopAbs_ShapeEnum atomType;
1811 switch (S.ShapeType()) {
1812 case TopAbs_COMPSOLID:
1813 case TopAbs_SOLID:
1814 case TopAbs_SHELL:
1815 atomType = TopAbs_FACE;
1816 break;
1817 case TopAbs_WIRE:
1818 atomType = TopAbs_EDGE;
1819 break;
1820 default:
1821 atomType = TopAbs_SHAPE;
1822 }
1823 Standard_Boolean found(Standard_False);
1824 if (!Context.IsNull()) {
1825 if (Context.ShapeType() < S.ShapeType())
1826 found = IsOneIn(S, Context);
1827 if(found) {
1828 NS = TNaming_Tool::NamedShape(Context, F);
1829 if(!NS.IsNull())
1830 theName.ContextLabel(NS->Label());
1831 }
1832 }
1833 if (atomType == TopAbs_SHAPE) {
1834 if(S.ShapeType() == TopAbs_COMPOUND) {
1835 BuildAggregationName(Naming->Label(),MDF, S, Context,Stop,Geom);
1836 } else {
1837 for (TopoDS_Iterator it(S) ; it.More(); it.Next()) {
1838 theName.Append(BuildName (Naming->Label(),MDF,it.Value(),Context,Stop,Geom));
1839 }
1840 }
1841 } else {
1842 if(S.ShapeType() == TopAbs_WIRE)
1ec8a59e 1843 NS = BuildNameWire (Naming->Label(), MDF, S, Context,Stop,Geom);
1844 else if(S.ShapeType() == TopAbs_SHELL) {
1845 NS = BuildNameShell (Naming->Label(), MDF, S, Context,Stop,Geom);
1846 }
1847 else {
1848 theName.Type(TNaming_UNION);
1849 for (TopExp_Explorer exp(S,atomType) ; exp.More(); exp.Next()) {
1850 theName.Append(BuildName (Naming->Label(),MDF,exp.Current(),Context,Stop,Geom));
1851 }
1852 }
7fd59977 1853 }
7fd59977 1854
1855 //Naming->Update();
1856 Naming->GetName().Solve(Naming->Label(),MDF.GetValid());
1857 Naming->Label().FindAttribute(TNaming_NamedShape::GetID(),NS);
1858 if (Geom) return NS;
1859
7fd59977 1860 if(NS.IsNull()) return BuildNS (F,S, TNaming_UNKNOWN);
7fd59977 1861
1862 if (!Geom && TestSolution(MDF,NS,S)) return NS;
1863 }
1864
1865 cout <<" %%% WARNING: TNaming_Naming::Name: FAILED"<<endl;
1866
1867 // Naming n is not satisfactory
1868 return BuildNS (F,S, TNaming_UNKNOWN);
1869}
1870
1871
1872//=======================================================================
1873//function : TNaming_Naming
1874//purpose :
1875//=======================================================================
1876
1877TNaming_Naming::TNaming_Naming() {}
1878
1879//=======================================================================
1880//function : ID
1881//purpose :
1882//=======================================================================
1883
1884const Standard_GUID& TNaming_Naming::ID () const
1885{
1886 return GetID();
1887}
1888
1889
1890//=======================================================================
1891//function : IsDefined
1892//purpose :
1893//=======================================================================
1894
1895Standard_Boolean TNaming_Naming::IsDefined() const
1896{
1897 return (myName.Type() != TNaming_UNKNOWN);
1898}
1899
1900//=======================================================================
1901//function : GetName
1902//purpose :
1903//=======================================================================
1904
1905const TNaming_Name& TNaming_Naming::GetName() const
1906{
1907 return myName;
1908}
1909
1910//=======================================================================
1911//function : ChangeName
1912//purpose :
1913//=======================================================================
1914
1915TNaming_Name& TNaming_Naming::ChangeName()
1916{
1917 return myName;
1918}
1919
1920//=======================================================================
1921//function : Regenerate
1922//purpose : idem designer
1923//=======================================================================
1924
1925Standard_Boolean TNaming_Naming::Regenerate (TDF_LabelMap& MDF)
1926
1927{
1928 return myName.Solve(Label(),MDF);
1929}
1930
1931
1932//=======================================================================
1933//function : NewEmpty
1934//purpose :
1935//=======================================================================
1936
1937Handle(TDF_Attribute) TNaming_Naming::NewEmpty () const
1938{
1939 return new TNaming_Naming ();
1940}
1941
1942
1943//=======================================================================
1944//function : Restore
1945//purpose :
1946//=======================================================================
1947
1948void TNaming_Naming::Restore(const Handle(TDF_Attribute)& other)
1949{
1950 Handle(TNaming_Naming) OtherNaming = Handle(TNaming_Naming)::DownCast(other);
1951 myName = OtherNaming->ChangeName();
1952}
1953
1954//=======================================================================
1955//function : Paste
1956//purpose :
1957//=======================================================================
1958
1959void TNaming_Naming::Paste (const Handle(TDF_Attribute)& into,
1960 const Handle(TDF_RelocationTable)& RT) const
1961{
1962 Handle(TNaming_Naming) NewNaming = Handle(TNaming_Naming)::DownCast(into);
1963 myName.Paste(NewNaming->ChangeName(),RT);
1964}
1965
1966//=======================================================================
1967//function : References
1968//purpose : Redefined from TDF_Attribute
1969//=======================================================================
1970
1971void TNaming_Naming::References(const Handle(TDF_DataSet)& DataSet) const
1972{
1973 // Iteration on NamedShape of the name
1974 TNaming_ListIteratorOfListOfNamedShape it(myName.Arguments());
1975 for (;it.More();it.Next()) DataSet->AddAttribute(it.Value());
1976 if (!myName.StopNamedShape().IsNull()) DataSet->AddAttribute(myName.StopNamedShape());
1977}
1978//=======================================================================
1979//function : Dump
1980//purpose :
1981//=======================================================================
1982
1983Standard_OStream& TNaming_Naming::Dump (Standard_OStream& anOS) const
1984{
1985 anOS << "TNaming_Naming";
1986 return anOS;
1987}
1988
1989
1990//=======================================================================
1991//function :ExtendedDump
1992//purpose :
1993//=======================================================================
1994
1995void TNaming_Naming::ExtendedDump(Standard_OStream& anOS,
1996 const TDF_IDFilter& /*aFilter*/,
1997 TDF_AttributeIndexedMap& /*aMap*/) const
1998{
1999 anOS << "TNaming_Naming ExtendedDump ";
2000 //anOS<<"myContext: #" <<aMap.Add(myContext)<<endl;
2001}
2002