0031682: Visualization - Prs3d_ShadingAspect::SetTransparency() has no effect with...
[occt.git] / src / TNaming / TNaming_Name.cxx
CommitLineData
b311480e 1// Created on: 1997-03-21
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
42cf5bc1 17
7fd59977 18#include <BRep_Builder.hxx>
42cf5bc1 19#include <BRepBuilderAPI_MakeFace.hxx>
20#include <BRepBuilderAPI_MakeSolid.hxx>
21#include <BRepBuilderAPI_MakeWire.hxx>
1ec8a59e 22#include <BRepTools.hxx>
42cf5bc1 23#include <Standard_ConstructionError.hxx>
24#include <Standard_ErrorHandler.hxx>
25#include <Standard_NotImplemented.hxx>
26#include <TColStd_Array1OfInteger.hxx>
7fd59977 27#include <TDF_Label.hxx>
28#include <TDF_LabelList.hxx>
29#include <TDF_LabelMap.hxx>
42cf5bc1 30#include <TDF_RelocationTable.hxx>
bc73b006 31#include <TDF_Tool.hxx>
42cf5bc1 32#include <TNaming.hxx>
33#include <TNaming_Builder.hxx>
34#include <TNaming_Iterator.hxx>
35#include <TNaming_ListIteratorOfListOfNamedShape.hxx>
36#include <TNaming_ListOfNamedShape.hxx>
37#include <TNaming_Name.hxx>
38#include <TNaming_NamedShape.hxx>
39#include <TNaming_Naming.hxx>
40#include <TNaming_NamingTool.hxx>
41#include <TNaming_NCollections.hxx>
42#include <TNaming_NewShapeIterator.hxx>
43#include <TNaming_ShapesSet.hxx>
7fd59977 44#include <TNaming_Tool.hxx>
42cf5bc1 45#include <TopExp.hxx>
46#include <TopExp_Explorer.hxx>
7fd59977 47#include <TopoDS.hxx>
7fd59977 48#include <TopoDS_Compound.hxx>
42cf5bc1 49#include <TopoDS_CompSolid.hxx>
50#include <TopoDS_Face.hxx>
7fd59977 51#include <TopoDS_Iterator.hxx>
42cf5bc1 52#include <TopoDS_Shape.hxx>
53#include <TopoDS_Shell.hxx>
54#include <TopoDS_Solid.hxx>
55#include <TopoDS_Wire.hxx>
56#include <TopTools_Array1OfShape.hxx>
57#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
58#include <TopTools_DataMapOfShapeListOfShape.hxx>
7fd59977 59#include <TopTools_HArray2OfShape.hxx>
42cf5bc1 60#include <TopTools_IndexedMapOfShape.hxx>
61#include <TopTools_ListIteratorOfListOfShape.hxx>
7fd59977 62#include <TopTools_ListOfShape.hxx>
42cf5bc1 63#include <TopTools_MapIteratorOfMapOfShape.hxx>
64#include <TopTools_MapOfShape.hxx>
7fd59977 65
42cf5bc1 66// mpv modifications 08.04.2002
67// end of mpv modifications 08.04.2002
0797d9d3 68#ifdef OCCT_DEBUG_DBGTOOLS_WRITE
4e18e72a 69#define MDTV_DEB
70#define MDTV_DEB_OR
71#define MDTV_DEB_UNN
72#define MDTV_DEB_INT
73#define MDTV_DEB_GEN
74#define MDTV_DEB_MODUN
75#define MDTV_DEB_FNB
76#define MDTV_DEB_WIN
77#define MDTV_DEB_ARG
78#define MDTV_DEB_SHELL
79#endif
0797d9d3 80#ifdef OCCT_DEBUG
7fd59977 81#include <TCollection_AsciiString.hxx>
82#include <TDF_Tool.hxx>
83#include <BRepTools.hxx>
7fd59977 84#endif
0797d9d3 85#ifdef OCCT_DEBUG
7fd59977 86#include <TCollection_AsciiString.hxx>
87#include <TDF_Tool.hxx>
88#include <TDF_ChildIterator.hxx>
89#include <TDF_MapIteratorOfLabelMap.hxx>
90//=======================================================================
91void PrintEntry(const TDF_Label& label)
92{
93 TCollection_AsciiString entry;
94 TDF_Tool::Entry(label, entry);
04232180 95 std::cout << "LabelEntry = "<< entry << std::endl;
7fd59977 96}
97//=======================================================================
98void PrintEntries(const TDF_LabelMap& map)
99{
04232180 100 std::cout << "=== Labels Map ===" <<std::endl;
7fd59977 101 TCollection_AsciiString entry;
102 TDF_MapIteratorOfLabelMap it(map);
103 for(;it.More();it.Next()) {
104 TDF_Tool::Entry(it.Key(), entry);
04232180 105 std::cout << "LabelEntry = "<< entry << std::endl;
7fd59977 106 }
107}
0797d9d3 108#ifdef OCCT_DEBUG_DBGTOOLS_WRITE
7fd59977 109//=======================================================================
110static void DbgTools_Write(const TopoDS_Shape& shape,
111 const Standard_CString filename)
112{
113 char buf[256];
114 if(strlen(filename) > 256) return;
115 strcpy (buf, filename);
116 char* p = buf;
117 while (*p) {
118 if(*p == ':')
119 *p = '-';
120 p++;
121 }
04232180 122 std::ofstream save (buf);
7fd59977 123 if(!save)
04232180 124 std::cout << "File " << buf << " was not created: rdstate = " << save.rdstate() << std::endl;
125 save << "DBRep_DrawableShape" << std::endl << std::endl;
7fd59977 126 if(!shape.IsNull()) BRepTools::Write(shape, save);
127 save.close();
128}
129//=======================================================================
0df87563 130static void DbgTools_Write(const TopTools_IndexedMapOfShape& MS, const Standard_CString filename)
7fd59977 131{
132 if (!MS.IsEmpty ()) {
133 TCollection_AsciiString aNam (filename);
0df87563 134 for (Standard_Integer anIt = 1; anIt <= MS.Extent(); ++anIt) {
135 TCollection_AsciiString aName = aNam + "_" + (anIt - 1) + ".brep";
136 DbgTools_Write (MS (anIt), aName.ToCString());
7fd59977 137 }
138 }
139}
140//=======================================================================
141static void DbgTools_WriteNSOnLabel (const Handle(TNaming_NamedShape)& NS,
142 const Standard_CString filename)
143{
144 if(!NS.IsNull() && !NS->IsEmpty() ) {
145 TCollection_AsciiString aNam (filename);
146 TCollection_AsciiString oldS ("_Old");
147 TCollection_AsciiString newS ("_New_");
148 Standard_Integer i(0);
149 TNaming_Iterator it(NS);
150 for(;it.More(); it.Next(),i++) {
151 TCollection_AsciiString aName1 = aNam + oldS + i + ".brep";
152 TCollection_AsciiString aName2 = aNam + newS + i + ".brep";
153 const TopoDS_Shape& oldShape = it.OldShape();
154 const TopoDS_Shape& newShape = it.NewShape();
155 if(!oldShape.IsNull())
156 DbgTools_Write ( oldShape, aName1.ToCString());
157 if(!newShape.IsNull())
158 DbgTools_Write ( newShape, aName2.ToCString());
159 }
160 }
161}
162#endif
4e18e72a 163#endif
7fd59977 164//
165//====================================================================
166static Standard_Boolean ValidArgs(const TNaming_ListOfNamedShape& Args)
167{
168 TNaming_ListIteratorOfListOfNamedShape it(Args);
169 for (;it.More();it.Next()) {
170 const Handle(TNaming_NamedShape)& aNS = it.Value();
171 if(aNS.IsNull()) {
0797d9d3 172#ifdef OCCT_DEBUG_ARG
04232180 173 std::cout << "ValidArgs:: NS (Naming argument) is NULL" <<std::endl;
7fd59977 174#endif
175 return Standard_False;
176 }
177 else
178 if(aNS->IsEmpty()) {
0797d9d3 179#ifdef OCCT_DEBUG_ARG
7fd59977 180 TCollection_AsciiString entry;
181 TDF_Tool::Entry(aNS->Label(), entry);
04232180 182 std::cout << "ValidArgs:: Empty NS, Label = " << entry <<std::endl;
7fd59977 183#endif
184 return Standard_False;
185 }
186 else
187 if(!aNS->IsValid()) {
0797d9d3 188#ifdef OCCT_DEBUG_ARG
7fd59977 189 TCollection_AsciiString entry;
190 TDF_Tool::Entry(aNS->Label(), entry);
04232180 191 std::cout << "ValidArgs::Not valid NS Label = " << entry <<std::endl;
7fd59977 192#endif
193 return Standard_False;
194 }
195 }
196 return Standard_True;
197}
198
199//=======================================================================
200//function : TNaming_Name
201//purpose :
202//=======================================================================
203
c24d4017 204TNaming_Name::TNaming_Name() :
205 myType(TNaming_UNKNOWN),
206 myIndex(-1)
7fd59977 207{
208}
209
210
211//=======================================================================
212//function : Type
213//purpose :
214//=======================================================================
215
216void TNaming_Name::Type(const TNaming_NameType aType)
217{
218 myType = aType;
219}
220
221//=======================================================================
222//function : Type
223//purpose :
224//=======================================================================
225
226void TNaming_Name::ShapeType(const TopAbs_ShapeEnum T)
227{
228 myShapeType = T;
229}
230
231//=======================================================================
232//function : Shape
233//purpose :
234//=======================================================================
235
236void TNaming_Name::Shape(const TopoDS_Shape& theShape)
237{
238 myShape = theShape;
239
240}
241
242//=======================================================================
243//function : Shape
244//purpose :
245//=======================================================================
246
247TopoDS_Shape TNaming_Name::Shape() const
248{
249 return myShape;
250}
251
252//=======================================================================
253//function : Append
254//purpose :
255//=======================================================================
256
257void TNaming_Name::Append(const Handle(TNaming_NamedShape)& arg)
258{
259 myArgs.Append (arg);
260}
261
262//=======================================================================
263//function : StopNamedShape
264//purpose :
265//=======================================================================
266
267void TNaming_Name::StopNamedShape (const Handle(TNaming_NamedShape)& arg)
268{
269 myStop = arg;
270}
271
272//=======================================================================
273//function : Index
274//purpose :
275//=======================================================================
276
277void TNaming_Name::Index (const Standard_Integer I)
278{
279 myIndex = I;
280}
281
282
283//=======================================================================
284//function : TNaming_NameType
285//purpose :
286//=======================================================================
287
288TNaming_NameType TNaming_Name::Type() const
289{
290 return myType;
291}
292
293//=======================================================================
294//function : TNaming_NameType
295//purpose :
296//=======================================================================
297
298TopAbs_ShapeEnum TNaming_Name::ShapeType() const
299{
300 return myShapeType;
301}
302
303//=======================================================================
f18ccc8c 304//function : Paste
7fd59977 305//purpose :
306//=======================================================================
307
308void TNaming_Name::Paste (TNaming_Name& into,
309 const Handle(TDF_RelocationTable)& RT) const
310{
311 into.myType = myType;
312 into.myShapeType = myShapeType;
f18ccc8c 313 into.myShape = myShape;
314 into.myIndex = myIndex;
7fd59977 315 into.myArgs.Clear();
316// into.myOrientation = myOrientation;
317 Handle(TNaming_NamedShape) NS;
318
319 for (TNaming_ListIteratorOfListOfNamedShape it(myArgs); it.More(); it.Next()) {
320 RT->HasRelocation(it.Value(),NS);
321 into.myArgs.Append (NS);
322 }
323 if (!myStop.IsNull()) {
324 RT->HasRelocation(myStop,NS);
325 into.myStop = NS;
326 }
327 if (!myContextLabel.IsNull()) {
328 RT->HasRelocation(myContextLabel,into.myContextLabel);
329 }
330}
331
332//=======================================================================
333//function : Arguments
334//purpose :
335//=======================================================================
336
337const TNaming_ListOfNamedShape& TNaming_Name::Arguments() const
338{
339 return myArgs;
340}
341
342//=======================================================================
343//function : Arguments
344//purpose :
345//=======================================================================
346
347Handle(TNaming_NamedShape) TNaming_Name::StopNamedShape() const
348{
349 return myStop;
350}
351
352//=======================================================================
353//function : Index
354//purpose :
355//=======================================================================
356
357Standard_Integer TNaming_Name::Index() const
358{
359 return myIndex;
360}
361
362//=======================================================================
363//function : MakeShape
364//purpose :
365//=======================================================================
366
0df87563 367static TopoDS_Shape MakeShape (const TopTools_IndexedMapOfShape& MS)
7fd59977 368{
369 if (!MS.IsEmpty ()) {
7fd59977 370 if (MS.Extent() == 1) {
0df87563 371 return MS (1);
7fd59977 372 }
373 else {
374 TopoDS_Compound C;
375 BRep_Builder B;
376 B.MakeCompound(C);
0df87563 377 for (Standard_Integer anIt = 1; anIt <= MS.Extent(); ++anIt)
378 B.Add (C, MS (anIt));
7fd59977 379 return C;
380 }
381 }
382 return TopoDS_Shape();
383}
384
7fd59977 385//=======================================================================
386//function : ShapeWithType
387//purpose : Tries to make shape with given type from the given shape
388//=======================================================================
389
390static TopoDS_Shape ShapeWithType(const TopoDS_Shape theShape,
391 const TopAbs_ShapeEnum theType ) {
392 if (theShape.IsNull() || theType == TopAbs_SHAPE) return theShape;
393 Standard_Integer aType = theShape.ShapeType();
394 if (aType == theType) return theShape;
395
396 TopTools_ListOfShape aShapes;
397 if (aType == TopAbs_COMPOUND) {
398 TopoDS_Iterator anIter(theShape);
399 if (anIter.More()) aType = anIter.Value().ShapeType();
400 for(;anIter.More();anIter.Next()) aShapes.Append(anIter.Value());
401 if (aType == theType) {
402 if (aShapes.Extent() == 1) return aShapes.First();
403 else return theShape;
404 }
405 } else aShapes.Append(theShape);
406
407 TopoDS_Shape aResult;
408 TopTools_ListIteratorOfListOfShape aListIter(aShapes);
409
410 if (aType < theType) {
411 Standard_Integer aCount;
412 for(aCount=0;aListIter.More();aListIter.Next()) {
413 TopExp_Explorer anExp(aListIter.Value(),theType);
414 if (anExp.More()) {
415 if (!anExp.Current().IsNull()) {
416 aResult = anExp.Current();
417 aCount++;
418 if (aCount > 1) return theShape;
419 }
420 }
421 }
422 if (aCount == 1) return aResult;
423 } else { // if the shape type more complex than shapes from aShapes list, try make it
424 switch (aType) {
425 case TopAbs_VERTEX: // can't do something from vertex
426 break;
b1811c1d 427 case TopAbs_EDGE:
428 {
429 // make wire from edges
430 if (theType <= TopAbs_SOLID) break;
431 BRepBuilderAPI_MakeWire aMakeWire;
432 aMakeWire.Add(aShapes);
433 if (!aMakeWire.IsDone()) return theShape;
434 if (theType == TopAbs_WIRE) return aMakeWire.Wire();
435 aShapes.Clear(); // don't break: we can do something more of it
436 aShapes.Append(aMakeWire.Wire());
437 aListIter.Initialize(aShapes);
7fd59977 438 }
b1811c1d 439 Standard_FALLTHROUGH
440 case TopAbs_WIRE:
441 {
442 // make faceS from wires (one per one)
443 if (theType < TopAbs_SOLID) break;
444 TopTools_ListOfShape aFaces;
445 for(;aListIter.More();aListIter.Next()) {
446 BRepBuilderAPI_MakeFace aMakeFace(TopoDS::Wire(aListIter.Value()));
447 if (!aMakeFace.IsDone()) aFaces.Append(aMakeFace.Face());
448 }
449 if (theType == TopAbs_FACE) {
450 if (aFaces.Extent() == 1) return aFaces.First();
451 return theShape;
452 }
453 aShapes.Assign(aFaces); // don't break: we can do something more of it
454 aListIter.Initialize(aShapes);
7fd59977 455 }
b1811c1d 456 Standard_FALLTHROUGH
457 case TopAbs_FACE:
458 {
459 // make shell from faces
460 if (theType < TopAbs_SOLID) break;
461 BRep_Builder aShellBuilder;
462 TopoDS_Shell aShell;
463 aShellBuilder.MakeShell(aShell);
464 for(;aListIter.More();aListIter.Next()) aShellBuilder.Add(aShell,TopoDS::Face(aListIter.Value()));
465 aShell.Closed (BRep_Tool::IsClosed (aShell));
466 if (theType == TopAbs_SHELL) return aShell;
467 aShapes.Clear(); // don't break: we can do something more of it
468 aShapes.Append(aShell);
469 aListIter.Initialize(aShapes);
7fd59977 470 }
b1811c1d 471 Standard_FALLTHROUGH
472 case TopAbs_SHELL:
473 {
474 // make solids from shells (one per one)
475 TopTools_ListOfShape aSolids;
476 for(;aListIter.More();aListIter.Next()) {
477 BRepBuilderAPI_MakeSolid aMakeSolid(TopoDS::Shell(aListIter.Value()));
478 if (aMakeSolid.IsDone()) aSolids.Append(aMakeSolid.Solid());
479 }
480 if (theType == TopAbs_SOLID) {
481 if (aSolids.Extent() == 1) return aSolids.First();
482 return theShape;
483 }
484 aShapes.Assign(aSolids); // don't break: we can do something more of it
485 aListIter.Initialize(aShapes);
486 }
487 Standard_FALLTHROUGH
488 case TopAbs_SOLID:
489 {
490 // make compsolid from solids
491 BRep_Builder aCompBuilder;
492 TopoDS_CompSolid aCompSolid;
493 aCompBuilder.MakeCompSolid(aCompSolid);
494 for(;aListIter.More();aListIter.Next()) aCompBuilder.Add(aCompSolid,TopoDS::Solid(aListIter.Value()));
495 if (theType == TopAbs_COMPSOLID) return aCompSolid;
7fd59977 496 }
7fd59977 497 }
498 }
499 return theShape;
500}
501
7fd59977 502//=======================================================================
503//function : FindModifUntil
504//purpose :
505//=======================================================================
506
507static Standard_Boolean FindModifUntil (TNaming_NewShapeIterator& it,
0df87563 508 TopTools_IndexedMapOfShape& MS,
7fd59977 509 const TopoDS_Shape& S,
510 const Handle(TNaming_NamedShape)& Context)
511{
0797d9d3 512#ifdef OCCT_DEBUG_MODUN
1ec8a59e 513 if(!Context.IsNull())
514 PrintEntry(Context->Label());
515#endif
7fd59977 516 Standard_Boolean found = Standard_False;
517 for (; it.More(); it.Next()) {
518 if (!it.Shape().IsNull()) {
0797d9d3 519#ifdef OCCT_DEBUG_MODUN
1ec8a59e 520 if(!it.NamedShape().IsNull())
521 PrintEntry(it.NamedShape()->Label());
522#endif
7fd59977 523 if (it.NamedShape() == Context) {
524 MS.Add(S);
525 found = Standard_True;
526 }
527 else { // New shape != Context
528 TNaming_NewShapeIterator it2(it);
529 found = FindModifUntil (it2,MS,it.Shape(),Context);
530 }
531 }
532 }
533 return found;
534}
535
536//=======================================================================
537//function : ModifUntil
538//purpose : returns map <theMS> of generators of Target
539//=======================================================================
540
541static void SearchModifUntil (const TDF_LabelMap& /*Valid*/,
542 const Handle(TNaming_NamedShape)& Target,
543 const TNaming_ListOfNamedShape& theListOfGenerators,
0df87563 544 TopTools_IndexedMapOfShape& theMS)
7fd59977 545{
546
0797d9d3 547#ifdef OCCT_DEBUG_MODUN
7fd59977 548 DbgTools_WriteNSOnLabel(Target, "SMUntil_"); // Target <== generated
549 Standard_Integer i = 0;
550 TCollection_AsciiString aGen1("Gens_New_"), aGen2("Gented_Old_"), Und("_");
551#endif
552 // Test si S apparait comme oldshape dans Context. : Test if S appears as oldshape in Context.
553 Standard_Boolean found = Standard_False;
554 for (TNaming_ListIteratorOfListOfNamedShape it(theListOfGenerators); it.More(); it.Next()) {
555 const Handle(TNaming_NamedShape)& aNS = it.Value();
0797d9d3 556#ifdef OCCT_DEBUG_MODUN
7fd59977 557 i++;
558 Standard_Integer j = 0;
559#endif
560 for (TNaming_Iterator itL (aNS); itL.More(); itL.Next()) { // <- generators
561 const TopoDS_Shape& S = itL.NewShape();
562 found = Standard_False;
563
0797d9d3 564#ifdef OCCT_DEBUG_MODUN
7fd59977 565 j++;
566 Standard_Integer k = 0;
567 TCollection_AsciiString aNam1 = aGen1 + i + Und + j + ".brep";
568 DbgTools_Write(S, aNam1.ToCString());
1ec8a59e 569 PrintEntry(aNS->Label());//NSLabel
7fd59977 570#endif
1ec8a59e 571 TNaming_Iterator itC (Target);
572 for (; itC.More(); itC.Next()) { // <- generated
7fd59977 573 const TopoDS_Shape& OS = itC.OldShape();
0797d9d3 574#ifdef OCCT_DEBUG_MODUN
7fd59977 575 k++;
576 TCollection_AsciiString aNam2 = aGen2 + i + Und + j + Und + k + ".brep";
577 DbgTools_Write(OS, aNam2.ToCString());
1ec8a59e 578 PrintEntry(Target->Label());//Target Label
7fd59977 579#endif
580 if (OS.IsSame(S)) {
581 theMS.Add(S);
582 found = Standard_True;
0797d9d3 583#ifdef OCCT_DEBUG_MODUN
04232180 584 std::cout << aNam2 << " is Same with " << aNam1 <<std::endl;
7fd59977 585#endif
586 break;
587 }
588 }
589 if (!found) {
590 TNaming_NewShapeIterator it1(itL);
591 found = FindModifUntil (it1,theMS,S,Target);
592 }
593 }
594 }
595}
596
597//=======================================================================
598//function : ModifUntil
599//purpose :
600//=======================================================================
601// NamedShape for this type is assembled from all last modifications of the
602// last argument shapes (see method TNaming_NamingTool::CurrentShape),
603// which are not descendants (see method TNaming_NamingTool::BuildDescendants)
604// of the stop shape. This type of naming is used for identification shapes,
605// which has only one parent with evolution PRIMITIVE (or itself), which
606// uniquely identifies it. In most cases stop shape is empty and this algorithm
607// is equal to the algorithm for IDENTITY.
608//=======================================================================
609static Standard_Boolean ModifUntil (const TDF_Label& L,
610 const TDF_LabelMap& Valid,
611 const TNaming_ListOfNamedShape& Args,
612 const Handle(TNaming_NamedShape)& Stop)
613{
0df87563 614 TopTools_IndexedMapOfShape MS;
7fd59977 615 TDF_LabelMap Forbiden;
7fd59977 616 if(!ValidArgs(Args)) return Standard_False;
7fd59977 617 TNaming_NamingTool::BuildDescendants (Stop, Forbiden); // fills Forbidden from Stop
618
0797d9d3 619#ifdef OCCT_DEBUG_GEN
04232180 620 std::cout <<"Regenerating ModifUntil => ";
7fd59977 621 PrintEntry(L);
622 DbgTools_WriteNSOnLabel(Args.Last(), "ModifUntil-");
623
624#endif
625 // all last modifications of the last argument
626 TNaming_NamingTool::CurrentShape (Valid, Forbiden,Args.Last(),MS);
0797d9d3 627#ifdef OCCT_DEBUG_GEN
7fd59977 628 Standard_Integer i(0);
7fd59977 629 TCollection_AsciiString aNam("ModifUnti_MS_");
630 TCollection_AsciiString ext(".brep");
631#endif
632 TNaming_Builder B(L);
0df87563 633 for (Standard_Integer anItMS = 1; anItMS <= MS.Extent(); ++anItMS) {
634 const TopoDS_Shape& S = MS (anItMS);
7fd59977 635 B.Select(S,S);
0797d9d3 636#ifdef OCCT_DEBUG_GEN
7fd59977 637 TCollection_AsciiString aName = aNam + ++i + ext;
638 DbgTools_Write(S, aName.ToCString()) ;
04232180 639 std::cout << aName.ToCString() << " TS = " << S.TShape()->This() <<std::endl;
7fd59977 640#endif
641 }
642 return Standard_True;
643}
644
645//=======================================================================
646//function : ContShape
647//purpose :
648//=======================================================================
649// from the NS of the first argument TNaming_Iterator is started, shape "S"
650// is the NewShape from Iterator with index "myIndex" of the Name, this
651// shape and all last modifications (except NamedShapes - descendants of
652// the stop shape) are the parts of resulting NamedShape.
653//=======================================================================
654static Standard_Boolean ConstShape (const TDF_Label& L,
655 const TDF_LabelMap& Valid,
656 const TNaming_ListOfNamedShape& Args,
657 const Handle(TNaming_NamedShape)& Stop,
658 const Standard_Integer Index)
659{
0df87563 660 TopTools_IndexedMapOfShape MS;
7fd59977 661 TDF_LabelMap Forbiden;
7fd59977 662 if(!ValidArgs(Args)) return Standard_False;
7fd59977 663 TNaming_NamingTool::BuildDescendants (Stop, Forbiden);
664
665 TopoDS_Shape S;
666 Standard_Integer i = 1;
667 for (TNaming_Iterator it(Args.First()); it.More(); it.Next(), i++) {
668 if (Index == i) {
669 S = it.NewShape();
670 break;
671 }
672 }
673 if (S.IsNull()) return Standard_False;
674
675 TNaming_NamingTool::CurrentShapeFromShape (Valid,Forbiden,L,S,MS);
676
677
678 TNaming_Builder B(L);
0df87563 679 for (Standard_Integer anItMS = 1; anItMS <= MS.Extent(); ++anItMS) {
680 const TopoDS_Shape& SS = MS (anItMS);
7fd59977 681 B.Select(SS,SS);
682 }
683 return Standard_True;
684}
685
686//=======================================================================
687//function : Intersection
688//purpose :
689//=======================================================================
690//algorithm does next steps:
691// 1. Sets to the "Forbiden" map all shapes, which are descendants of stop
692// shape. Named shapes at these labels can't be used.
693// 2. Takes first argument (with method CurrentShape) and sets map "S" of
694// ancestors (shapes, which belong to this one) of its shape with type
695// "ShapeType" of Name.
696// 3. Takes next argument of Name (with method CurrentShape) and removes
697// from the map "S" all ancestors, which not belongs to the shape of
698// this argument. This step is repeated for all arguments of this Name.
699// 4. Adds to the result NamedShape all rest of shapes from the map "S".
700//=======================================================================
701static Standard_Boolean Intersection (const TDF_Label& L,
702 const TDF_LabelMap& Valid,
703 const TNaming_ListOfNamedShape& Args,
704 const Handle(TNaming_NamedShape)& Stop,
705 const TopAbs_ShapeEnum ShapeType,
706 const Standard_Integer Index)
707{
708 if (Args.IsEmpty()) return Standard_False;
7fd59977 709 if(!ValidArgs(Args)) return Standard_False;
7fd59977 710 TNaming_ListIteratorOfListOfNamedShape it(Args);
0df87563 711 TopTools_IndexedMapOfShape MS;
7fd59977 712 TDF_LabelMap Forbiden;
713
0797d9d3 714#ifdef OCCT_DEBUG_INT
7fd59977 715 if(!Stop.IsNull() && !Stop->Get().IsNull()) {
716 DbgTools_Write(Stop->Get(), "Ints_Stop.brep");
717 PrintEntry(Stop->Label());
718 }
04232180 719 std::cout <<"Ints: ShapeType = " << ShapeType << std::endl;
720 std::cout <<"Argument 1 at ";
7fd59977 721 PrintEntry(it.Value()->Label());
722#endif
723
724 TNaming_NamingTool::BuildDescendants (Stop, Forbiden); // <==<1>
725
0797d9d3 726#ifdef OCCT_DEBUG_INT
04232180 727 std::cout << "Intersection:: Valid Map: "<<std::endl;
7fd59977 728 PrintEntries(Valid);
04232180 729 std::cout << "Intersection:: Forbidden Map: "<<std::endl;
7fd59977 730 PrintEntries(Forbiden);
731#endif
732 TopTools_ListOfShape aListOfAnc;
733 TNaming_NamingTool::CurrentShape (Valid, Forbiden,it.Value(),MS); // first argument
734 TopoDS_Shape CS = MakeShape(MS);
735 TNaming_ShapesSet S(CS,ShapeType); // <==<2>
736 aListOfAnc.Append(CS);
0797d9d3 737#ifdef OCCT_DEBUG_INT
7fd59977 738 if(!CS.IsNull())
739 DbgTools_Write(CS, "Int_CS_1.brep");
740 Standard_Integer i=2;
741 TCollection_AsciiString aNam("Int_CS_");
742 TCollection_AsciiString ext(".brep");
743
744#endif
745 it.Next(); // <<===<3.1>
746 for (; it.More(); it.Next()) {
747 MS.Clear();
748 TNaming_NamingTool::CurrentShape (Valid,Forbiden,it.Value(),MS);
749 CS = MakeShape(MS);
750 aListOfAnc.Append(CS);
0797d9d3 751#ifdef OCCT_DEBUG_INT
7fd59977 752 TCollection_AsciiString aName = aNam + i++ + ext;
753 DbgTools_Write(CS, aName.ToCString()) ;
04232180 754 std::cout <<"Argument " << i << " at ";
7fd59977 755 PrintEntry(it.Value()->Label());
756#endif
757
758 TNaming_ShapesSet OS(CS,ShapeType);
759 S.Filter(OS); //<<===<3.2>
0797d9d3 760#ifdef OCCT_DEBUG_INT
7fd59977 761 Standard_Integer j = 1;
762 TCollection_AsciiString aNam2("SSMap_"), aName3;
763 TopTools_MapIteratorOfMapOfShape itm(S.Map());
764 for(;itm.More();itm.Next(), j++) {
765 aName3 = aNam2 + i + "_" + j + ".brep";
766 DbgTools_Write(itm.Key(), aName3.ToCString());
767 }
768#endif
769 }
770
0797d9d3 771#ifdef OCCT_DEBUG_INT
7fd59977 772 aNam = "Int_S_";
773 i =1;
774#endif
775
776 TNaming_Builder B(L); //<<===<4>
777 Standard_Boolean isOK(Standard_False);
778 if(S.Map().Extent() > 1 && Index > 0 && ShapeType == TopAbs_EDGE) {
779 Standard_Integer indxE(0), nbE(0), indxW(0),nbW(0), indxF(0);
780 indxE = Index & 0x000000FF;
781 nbE = (Index & 0x0000FF00) >> 8;
782 indxW = (Index & 0x000F0000) >> 16;
783 nbW = (Index & 0x00F00000) >> 20;
784 indxF = (Index & 0x0F000000) >> 24;
51740958 785 Standard_Integer k(1);
7fd59977 786 TopoDS_Shape aS;
787 TopTools_ListIteratorOfListOfShape itl(aListOfAnc);
51740958 788 for(;itl.More();itl.Next(),k++) {
789 if(indxF == k) {
7fd59977 790 aS = itl.Value();
791 break;
792 }
793 }
0797d9d3 794#ifdef OCCT_DEBUG_INT
04232180 795 std::cout <<"Kept: indxE = " << indxE <<" maxENum = " << nbE << " indxW = " <<indxW << " nbW = " <<nbW<<std::endl;
7fd59977 796#endif
b2d1851c 797 Standard_Integer aCaseW(0);
798 Standard_Integer aNbW = aS.NbChildren();
7fd59977 799 if(aNbW == nbW) aCaseW = 1;//exact solution for wire (nb of wires is kept)
800 else aCaseW = 2; // indefinite description ==> compound which can include expected wire
801 if(aCaseW == 1) {
802 TopoDS_Shape aWire;
b2d1851c 803 Standard_Integer i = 1;
804 for (TopoDS_Iterator it2 (aS); it2.More(); it2.Next(), i++)
805 {
7fd59977 806 if(indxW == i) {
807 aWire = it2.Value();
808 break;
809 }
810 }
b2d1851c 811 Standard_Integer aCaseE(0);
812 Standard_Integer aNbE = aWire.NbChildren();
7fd59977 813 if(aNbE == nbE) aCaseE = 1;//exact solution for edge
814 else aCaseE = 2;
815 if(aCaseE == 1) {
816 i=1;
817 TopoDS_Shape anEdge;
b2d1851c 818 for (TopoDS_Iterator it2 (aWire); it2.More(); it2.Next(), i++) {
7fd59977 819 if(indxE == i) {
820 anEdge = it2.Value();
821 break;
822 }
823 }
824 if(!anEdge.IsNull()) {
825 B.Select(anEdge, anEdge);
826 isOK = Standard_True;
827 }
828 }
829 }
830 }
831 if(!isOK)
0797d9d3 832#ifdef OCCT_DEBUG_INT
7fd59977 833 for (TopTools_MapIteratorOfMapOfShape itM(S.Map()); itM.More(); itM.Next(),i++) {
834#else
835
836 for (TopTools_MapIteratorOfMapOfShape itM(S.Map()); itM.More(); itM.Next()) {
837#endif
838 const TopoDS_Shape& S1 = itM.Key();
0797d9d3 839#ifdef OCCT_DEBUG_INT
7fd59977 840 TCollection_AsciiString aName = aNam + i + ext;
841 DbgTools_Write(S1, aName.ToCString()) ;
842#endif
843
844 B.Select(S1,S1);
845 isOK = Standard_True;
846 }
847 return isOK;
848}
849//=======================================================================
850static void KeepInList(const TopoDS_Shape& CS, const TopAbs_ShapeEnum Type, TopTools_ListOfShape& aList)
851{
852 if (CS.IsNull()) return;
853
854 if (Type == TopAbs_SHAPE) {
855 if (CS.ShapeType() == TopAbs_SOLID ||
856 CS.ShapeType() == TopAbs_FACE ||
857 CS.ShapeType() == TopAbs_EDGE ||
858 CS.ShapeType() == TopAbs_VERTEX ) {
859 aList.Append(CS);
860 }
861 else {
862 for (TopoDS_Iterator it(CS) ; it.More(); it.Next()) {
863 aList.Append(it.Value());
864 }
865 }
866 }
867 else {
868 if (Type > CS.ShapeType()) {
869 for (TopExp_Explorer exp(CS,Type) ; exp.More(); exp.Next()) {
870 aList.Append(exp.Current());
871 }
872 } else {
873 aList.Append(CS);
874 }
875 }
876}
877
878//=======================================================================
879//function : Union
880//purpose :
881//=======================================================================
882// Resulting NamedShape contains compound of next shapes:
883// compound of last modifications of each argument (see CurrentShape method)
884// without descendants of the stop shape.
885//=======================================================================
886static Standard_Boolean Union (const TDF_Label& L,
887 const TDF_LabelMap& Valid,
888 const TNaming_ListOfNamedShape& Args,
889 const Handle(TNaming_NamedShape)& Stop,
890 const TopAbs_ShapeEnum ShapeType,
891 const TDF_Label& ContextLabel)
892{
893 if (Args.IsEmpty()) return Standard_False;
7fd59977 894 if(!ValidArgs(Args)) return Standard_False;
7fd59977 895 // temporary solution for Orientation name
896 Standard_Boolean isOr(Standard_True);
897/* not completed
898 const TDF_Label& aLabel = L.Father();
899 if(!aLabel.IsNull()) {
900 PrintEntry(L);
901 PrintEntry(aLabel);
902 Handle (TNaming_Naming) Naming;
903 if(aLabel.FindAttribute(TNaming_Naming::GetID(), Naming)) {
904 const TNaming_Name& aName = Naming->GetName();
905 if(aName.Type() == TNaming_ORIENTATION) {
906 const TNaming_ListOfNamedShape& Args = aName.Arguments();
907 if(Args.Extent() > 2) {
908 const Handle(TNaming_NamedShape)& A = Args.First();
909 if(!A.IsNull()) {
910 PrintEntry(A->Label());
911 if (A->Label() == L)
912 isOr = Standard_True;
913 }
914 } else
915 if(!Args.Extent())
916 isOr = Standard_True;
917 }
918 }
919 }
920*/
921 // end of temp. sol.
922
923 TNaming_ListIteratorOfListOfNamedShape it(Args);
0df87563 924 TopTools_IndexedMapOfShape MS;
7fd59977 925 TDF_LabelMap Forbiden;
926
927 TNaming_NamingTool::BuildDescendants (Stop, Forbiden);//fill Forbidden
928 TNaming_NamingTool::CurrentShape (Valid, Forbiden,it.Value(),MS); // fill MS with last modifications of the first argument
929 TopoDS_Shape CS = MakeShape(MS);
930
931 TopTools_ListOfShape aListS;
932 if(isOr)
933 KeepInList(CS,ShapeType,aListS);
934 TNaming_ShapesSet S(CS,ShapeType);//fill internal map of shapeset by shapes of the specified type
0797d9d3 935#ifdef OCCT_DEBUG_UNN
7fd59977 936 TCollection_AsciiString entry;
937 TDF_Tool::Entry(it.Value()->Label(), entry);
938 TCollection_AsciiString Nam("Arg_");
939 TCollection_AsciiString aNam = Nam + entry + "_" + "1.brep";
940 DbgTools_Write(CS, aNam.ToCString());
941 Standard_Integer ii = 1;
942#endif
943 it.Next();
944 for (; it.More(); it.Next()) {
0797d9d3 945#ifdef OCCT_DEBUG_UNN
7fd59977 946 TDF_Tool::Entry(it.Value()->Label(), entry);
947#endif
948 MS.Clear();
949 TNaming_NamingTool::CurrentShape (Valid, Forbiden,it.Value(),MS);// fill MS with last modifications of the it.Value()
950 CS = MakeShape(MS);
951 if(isOr)
952 KeepInList(CS,ShapeType,aListS);
953 TNaming_ShapesSet OS(CS,ShapeType);
954 S.Add(OS); //concatenate both shapesets
955
0797d9d3 956#ifdef OCCT_DEBUG_UNN
7fd59977 957 ii++;
958 TCollection_AsciiString aNm = Nam + entry + "_" + ii + ".brep";
959 DbgTools_Write(CS, aNm.ToCString());
04232180 960 std::cout <<"Arg: Entry = " <<entry <<" TShape = " << CS.TShape() <<std::endl;
7fd59977 961#endif
962 }
963
964// start szy 27.05.08
965 TopoDS_Shape aCand;
966 Standard_Boolean found = Standard_False;
967 if(!ContextLabel.IsNull()) {
968 Handle(TNaming_NamedShape) CNS;
969 ContextLabel.FindAttribute(TNaming_NamedShape::GetID(),CNS);
970 TopoDS_Shape aContext;
971 if(!CNS.IsNull()) {
972 MS.Clear();
973 TNaming_NamingTool::CurrentShape (Valid, Forbiden, CNS, MS);
974 aContext = MakeShape(MS);
0797d9d3 975#ifdef OCCT_DEBUG_UNN
7fd59977 976 TCollection_AsciiString anEntry;
977 TDF_Tool::Entry(ContextLabel, anEntry);
04232180 978 std::cout << "UNION: Context Label = " << anEntry << std::endl;
7fd59977 979 DbgTools_Write(aContext, "Union_Context.brep");
980 TCollection_AsciiString aN ("aMap_");
981 TopTools_MapIteratorOfMapOfShape it(S.Map());
982 for(Standard_Integer i=1; it.More();it.Next(), i++) {
983 TCollection_AsciiString aName = aN + i + ".brep";
984 DbgTools_Write(it.Key(), aName.ToCString());
985 }
986#endif
987 }
988 TopTools_ListOfShape aList;
989 TopExp_Explorer anExpl(aContext, ShapeType);
990 for(;anExpl.More(); anExpl.Next())
991 aList.Append(anExpl.Current());
0797d9d3 992#ifdef OCCT_DEBUG_UNN
04232180 993 std::cout <<"UNION: ShapeType = " << ShapeType << " List ext = " << aList.Extent()<<std::endl;
7fd59977 994 TopAbs_ShapeEnum aTyp = TopAbs_SHAPE;
995 TopTools_MapIteratorOfMapOfShape it1 (S.Map());
996 for (int i=1;it1.More();it1.Next(),i++) {
04232180 997 std::cout << "Map("<<i<<"): TShape = " << it1.Key().TShape() << " Orient = " << it1.Key().Orientation() <<std::endl;
7fd59977 998 aTyp = it1.Key().ShapeType();
999 }
1000
1001 TopExp_Explorer exp(aContext, aTyp);
1002 for(int i =1;exp.More();exp.Next(), i++) {
04232180 1003 std::cout << "Context("<<i<<"): TShape = " << exp.Current().TShape() << " Orient = " << exp.Current().Orientation() <<std::endl;
7fd59977 1004 }
1005
1006#endif
1007 TopTools_ListIteratorOfListOfShape itl(aList);
1008 for(;itl.More();itl.Next()) {
1009 aCand = itl.Value();
0797d9d3 1010#ifdef OCCT_DEBUG_UNN
7fd59977 1011 DbgTools_Write(aCand, "Cand.brep");
1012#endif
1013 Standard_Integer num = S.Map().Extent();
1014 anExpl.Init(aCand, (ShapeType == TopAbs_WIRE) ? TopAbs_EDGE : TopAbs_FACE);
1015 for(;anExpl.More();anExpl.Next()) {
1016 if(S.Map().Contains(anExpl.Current()))
1017 num--;
1018 }
1019 if(num == 0) {
1020 found = Standard_True;
1021 break;
1022 }
1023 }
1024// end szy 27.05.08
1025 }
1026
1027 TNaming_Builder B(L);
0797d9d3 1028#ifdef OCCT_DEBUG_UNN
7fd59977 1029 if(!ContextLabel.IsNull()) {
04232180 1030 if(found) std::cout << "UNION: Shape is found in Context" <<std::endl;
1031 else std::cout << "UNION: Shape is NOT found in Context" <<std::endl;
7fd59977 1032 }
1033#endif
7fd59977 1034 if(found)
1035 B.Select(aCand, aCand);
1036 else {
1037 BRep_Builder aCompoundBuilder;
1038 TopoDS_Compound aCompound;
1039 aCompoundBuilder.MakeCompound(aCompound);
1040 if(!isOr)
1041 for (TopTools_MapIteratorOfMapOfShape itM(S.Map()); itM.More(); itM.Next()) {
1042 aCompoundBuilder.Add(aCompound,itM.Key());
1043 }
1044 else
1045 for (TopTools_ListIteratorOfListOfShape itL(aListS); itL.More(); itL.Next()) {
1046 aCompoundBuilder.Add(aCompound,itL.Value());
1047 }
1048 TopoDS_Shape aShape = ShapeWithType(aCompound,ShapeType);
0797d9d3 1049#ifdef OCCT_DEBUG_UNN
7fd59977 1050 DbgTools_Write(aShape, "Union_Selected.brep");
1051 DbgTools_Write(aCompound, "Union_Compound.brep");
1052#endif
1053 B.Select(aShape,aShape);
1054 }
7fd59977 1055 return Standard_True;
1056}
1057
7fd59977 1058//=======================================================================
1059static TopoDS_Shape FindShape(const TNaming_DataMapOfShapeMapOfShape& DM)
1060{
1061 TopoDS_Shape aResult;
1062 Standard_Integer aNum = DM.Extent();
1063 if(aNum < 1) return aResult;
1064 TopTools_ListOfShape List;
1065 TNaming_DataMapIteratorOfDataMapOfShapeMapOfShape it(DM);
b2197f93 1066 if(it.More()) {
7fd59977 1067 const TopoDS_Shape& aKey1 = it.Key();
1068 const TNaming_MapOfShape& aMap = it.Value();
1069
1070 TNaming_MapIteratorOfMapOfShape itm(aMap); // iterate first map
1071 for (;itm.More();itm.Next()) {
1072 const TopoDS_Shape& aS = itm.Key(); // element of the first map
1073 Standard_Boolean isCand(Standard_True); // aS is a Candidate
1074 TNaming_DataMapIteratorOfDataMapOfShapeMapOfShape it2(DM);
1075 for (;it2.More();it2.Next()) {
7dcac1df 1076 const TopoDS_Shape& aKey2 = it2.Key();
1077 if(aKey2 == aKey1) continue;
1078 const TNaming_MapOfShape& aMap2 = it2.Value();
1079 if(!aMap2.Contains(aS)) isCand = Standard_False;
7fd59977 1080 }
7dcac1df 1081 if(isCand)
1082 List.Append(aS);
7fd59977 1083 }
7fd59977 1084 }
1085 if(List.IsEmpty()) return aResult;
1086 if(List.Extent() == 1) return List.First();
1087 TopTools_ListIteratorOfListOfShape itl (List);
1088 TopoDS_Compound Compound;
1089 BRep_Builder B;
1090 B.MakeCompound(Compound);
1091 for (; itl.More(); itl.Next()){
1092 B.Add(Compound,itl.Value());
1093 }
1094 return Compound;
1095}
1096
1097//=======================================================================
1098//function : Generation
1099//purpose : Resolves Name from arguments: arg1 - generated (target shape)
1100// : arg2 - the generator: the oldest ancestor (usually NS with
1101// : PRIMITIVE evolution. (See TNaming_Localizer::FindGenerator).
1102// : Resulting NamedShape contains shape, which is in the first
1103// : argument NamedShape and is modification of the last argument NS.
1104//=======================================================================
1105
1106static Standard_Boolean Generated (const TDF_Label& L,
1107 const TDF_LabelMap& Valid,
1108 const TNaming_ListOfNamedShape& Args)
1109{
1110 if (Args.Extent() < 2) {
9775fa61 1111 throw Standard_ConstructionError("TNaming_Name::Solve: => Generated");
7fd59977 1112 }
1113 // First argument : label of generation
1114 // Next arguments : generators.
1115
7fd59977 1116 if(!ValidArgs(Args)) return Standard_False;
7fd59977 1117
1118 TDF_Label LabelOfGeneration = Args.First()->Label();
0797d9d3 1119#ifdef OCCT_DEBUG_GEN
7fd59977 1120 DbgTools_Write(Args.First()->Get(), "Generated.brep") ;
1121#endif
1122 // Nouvell valeurs des generateurs dans l attribut de generation
0df87563 1123 TopTools_IndexedMapOfShape aMS;
7fd59977 1124 TNaming_ListOfNamedShape aGenerators;
1125 aGenerators.Assign(Args);
1126 aGenerators.RemoveFirst();
0797d9d3 1127#ifdef OCCT_DEBUG_GEN
7fd59977 1128 DbgTools_Write(aGenerators.First()->Get(), "Generators.brep") ;
1129#endif
1130 SearchModifUntil (Valid, Args.First(), aGenerators, aMS);
1131 Handle(TNaming_Naming) aNaming;
1132 TopoDS_Shape aSelection;
1133 L.FindAttribute(TNaming_Naming::GetID(),aNaming);
1134 if(!aNaming.IsNull())
1135 aSelection = aNaming->GetName().Shape();
0797d9d3 1136#ifdef OCCT_DEBUG_GEN
7fd59977 1137 DbgTools_Write(aSelection, "G_Selection.brep") ;
04232180 1138 std::cout << "Generated::SearchModifUntil aMS.Extent() = " << aMS.Extent() <<std::endl;
7fd59977 1139 DbgTools_Write(aMS, "SearchModifUntil_Result");
1140#endif
1141 Handle(TNaming_NamedShape) anOldNS;
1142 Standard_Integer aVer = -1;// Initial build of name
1143 L.FindAttribute(TNaming_NamedShape::GetID(),anOldNS);
1144 if(!anOldNS.IsNull())
1145 aVer = anOldNS->Version();
1146
0797d9d3 1147#ifdef OCCT_DEBUG_GEN
7fd59977 1148 Standard_Integer i = 0, j=1;
1149 TCollection_AsciiString aNam2("Gen_New_");
1150 TCollection_AsciiString aNam1("Gen_Old_");
1151 TCollection_AsciiString ext(".brep");
1152#endif
1153 TNaming_Builder B(L); // NS
1154 TopTools_ListOfShape aList;
1155 TNaming_DataMapOfShapeMapOfShape aDM;
0df87563 1156 for (Standard_Integer anItMS = 1; anItMS <= aMS.Extent(); ++anItMS) {
1157 const TopoDS_Shape& OS = aMS (anItMS);
0797d9d3 1158#ifdef OCCT_DEBUG_GEN
7fd59977 1159 TCollection_AsciiString aName = aNam1 + ++i + ext;
1160 DbgTools_Write(OS, aName.ToCString()) ;
1161 Standard_Integer j=0;
1162#endif
1163 TNaming_MapOfShape aMapDM;
1164 for (TNaming_NewShapeIterator itNew(OS,L); itNew.More(); itNew.Next())
1165 if (itNew.Label() == LabelOfGeneration) {
1166 aMapDM.Add(itNew.Shape());
1167 aList.Append(itNew.Shape());//szy 21.10.03
0797d9d3 1168#ifdef OCCT_DEBUG_GEN
7fd59977 1169 TCollection_AsciiString aName = aNam2 + i + "_" + ++j + ext;
1170 DbgTools_Write(itNew.Shape(), aName.ToCString()) ;
1171#endif
1172 }
1173 if(aMapDM.Extent())
1174 aDM.Bind(OS, aMapDM);
1175 }
1176
1177 if(aVer == -1) { //initial
1178 Standard_Integer i = 1;
1179 TNaming_Name& aName = aNaming->ChangeName();
1180 TopTools_ListIteratorOfListOfShape it(aList);
1181 if(!aSelection.IsNull()) {
1182 for(;it.More();it.Next(),i++) {
1183 if(it.Value().IsSame(aSelection)) {
1184 B.Select(it.Value(), it.Value());
1185 aName.Index(i); // for debug - index of selection in the list
1186 break;
1187 }
1188 }
1189 } else {// Selection == Null
1190 for(;it.More();it.Next())
1191 B.Select(it.Value(), it.Value());
1192 }
1193 }
1194 else {
1195 // *** Regeneration *** //
1196 if(aList.Extent() == 1) { // trivial case
1197 B.Select(aList.Last(), aList.Last());
1198 }
1199 else {
1200 TNaming_Name& aName = aNaming->ChangeName();
1201 const TopAbs_ShapeEnum aType = aName.ShapeType();
1202 TopTools_ListOfShape aList2;
1203 TopTools_ListIteratorOfListOfShape it(aList);
1204 for(;it.More();it.Next()) {
1205 if(it.Value().ShapeType() == aType) //collect only the same type
1206 aList2.Append(it.Value());
1207 }
1208 if(!aList2.Extent()) return Standard_False; // Empty
1209
1210 Standard_Boolean found = Standard_False;
7fd59977 1211 TopoDS_Shape aShape = FindShape(aDM);
0797d9d3 1212#ifdef OCCT_DEBUG_GEN
7fd59977 1213 if(!aShape.IsNull())
1214 DbgTools_Write(aShape, "G_FindShape.brep") ;
1215#endif
1216 if(!aShape.IsNull()) found = Standard_True;
0797d9d3 1217#ifdef OCCT_DEBUG_GEN
04232180 1218 std::cout << "Generated ==>aGenerators.Extent() = " <<aGenerators.Extent() <<" aMS.Extent()= " <<aMS.Extent()<<std::endl;
7fd59977 1219#endif
1220 if(found) {
0797d9d3 1221#ifdef OCCT_DEBUG_GEN
04232180 1222 std::cout << "Generated ==> Shape is found!" <<std::endl;
7fd59977 1223#endif
1224 TopTools_ListOfShape aLM;
1225 Standard_Boolean aHas = Standard_False;
1226 Standard_Boolean a1NB = Standard_False;
1227 if(aGenerators.Extent() != aMS.Extent()) { //missed generators
1228 aHas = Standard_True;//has lost generatos
0797d9d3 1229#ifdef OCCT_DEBUG_GEN
04232180 1230 std::cout << "Generated ==> has lost generatos!" <<std::endl;
7fd59977 1231#endif
1232 for (TNaming_ListIteratorOfListOfNamedShape itg(aGenerators); itg.More(); itg.Next()) {
1233 if(!aMS.Contains(itg.Value()->Get()))
1234 aLM.Append(itg.Value()->Get());
1235 }
1236 if(aLM.Extent() == 1) {//lost 1
1237 TopTools_ListIteratorOfListOfShape itm(aLM);
1238 TopoDS_Shape aSM = itm.Value(); // Missed
0df87563 1239 for (Standard_Integer anItMS1 = 1; anItMS1 <= aMS.Extent(); ++anItMS1) {
1240 const TopoDS_Shape& aS = aMS (anItMS1);
7fd59977 1241 if(aSM.ShapeType() == aS.ShapeType()) {
1242 if(aS.ShapeType() == TopAbs_EDGE) {
1243 TopoDS_Vertex aVCom;
1244 if(TopExp::CommonVertex(TopoDS::Edge(aS), TopoDS::Edge(aSM), aVCom))
1245 {a1NB = Standard_True;
1246 break;} //lost only 1 neigbour
1247 } else if(aS.ShapeType() == TopAbs_FACE) {
1248 TopExp_Explorer expl1(aS, TopAbs_EDGE);
1249 for(;expl1.More();expl1.Next()) {
1250 TopExp_Explorer expl2(aSM, TopAbs_EDGE);
1251 for(;expl2.More();expl2.Next()) {
1252 if(expl1.Current().IsSame(expl2.Current()))
1253 {a1NB = Standard_True;
1254 break;} //lost only 1 neigbour
1255 }
1256 }
1257 }
1258 }
1259 }
1260// if(aShape.ShapeType() == TopAbs_VERTEX && a1NBE) {
1261// //if atleast 1 Gen was missed and the Gen is Edge
1262// TopTools_ListIteratorOfListOfShape it(aList);
1263// for(;it.More();it.Next()) {
1264// if(it.Value().ShapeType() == TopAbs_EDGE) {
1265// const TopoDS_Shape& aV1 = TopExp::FirstVertex(TopoDS::Edge(it.Value()));
1266// const TopoDS_Shape& aV2 = TopExp::LastVertex(TopoDS::Edge(it.Value()));
04232180 1267// if(aShape.IsSame(aV1)) {aShape2 = aV2; std::cout << "##### => V2 " <<std::endl;break;}
7fd59977 1268// else
04232180 1269// if(aShape.IsSame(aV2)) {aShape2 = aV1; std::cout << "##### => V1 " <<std::endl;break;}
7fd59977 1270// }
1271// }
1272// }
1273 }
1274 }
1275 if(!aHas) // all arguments were kept
1276 B.Select(aShape, aShape); //only this case is correct on 100%
1277 else {
1278 if (a1NB) //Has, but may be ...
1279 B.Select(aShape, aShape);
1280 else {
1281 // put Compound, may be if possible processed later in Sel. Driver
1282 TopTools_ListIteratorOfListOfShape it1(aList2);
1283 for(;it1.More();it1.Next())
1284 B.Select(it1.Value(), it1.Value());
1285 }
1286 }
1287 } else
1288 { //not found
0797d9d3 1289#ifdef OCCT_DEBUG_GEN
04232180 1290 std::cout << "Generated ==> Shape is NOT found! Probably Compound will be built" <<std::endl;
7fd59977 1291#endif
1292
1293 TopTools_ListIteratorOfListOfShape it2(aList2);
1294 for(;it2.More();it2.Next())
1295 B.Select(it2.Value(), it2.Value());
1296 }
1297 }
1298 }
1299 return Standard_True;
1300}
1301
1302//=======================================================================
1303//function : Identity
1304//purpose : Regenerates Naming attribute with Name = IDENTITY
1305//=======================================================================
1306// Name with this type must contain only one NamedShape attribute as argument.
1307// Algorithm takes all last modifications of NamedShape of this argument
1308// starting with this one ( see method TNaming_NamingTool::CurrentShape ).
1309// Algorithm takes only NamedShapes belonging to the labels from the Valid
1310// labels map (if it's not empty) and put to the resulting NamedShape as compound.
1311//=======================================================================
1312static Standard_Boolean Identity (const TDF_Label& L,
1313 const TDF_LabelMap& Valid,
1314 const TNaming_ListOfNamedShape& Args,
1315 const TopAbs_ShapeEnum ShapeType)
1316{
1317 if (Args.Extent() > 2) {
9775fa61 1318 throw Standard_ConstructionError("TNaming_Name::Solve");
7fd59977 1319 }
7fd59977 1320 if(!ValidArgs(Args)) return Standard_False;
7fd59977 1321 const Handle(TNaming_NamedShape)& A = Args.First();
0df87563 1322 TopTools_IndexedMapOfShape MS;
7fd59977 1323 TDF_LabelMap Forbiden;
1324 TNaming_NamingTool::CurrentShape (Valid,Forbiden,A,MS);
0797d9d3 1325#ifdef OCCT_DEBUG_SOL2
7fd59977 1326 //TCollection_AsciiString entry;
1327 //TDF_Tool::Entry(L, entry);
1328 //TDF_Tool::Entry(A->Label(), entry);
1329#endif
1330 TNaming_Builder B(L);
0df87563 1331 for (Standard_Integer anItMS = 1; anItMS <= MS.Extent(); ++anItMS) {
1332 const TopoDS_Shape& S = ShapeWithType (MS (anItMS), ShapeType);
0797d9d3 1333#ifdef OCCT_DEBUG_SOL2
7fd59977 1334 //TopAbs_Orientation Or = S.Orientation();
1335#endif
1336 B.Select(S,S);
1337 }
1338 return Standard_True;
1339}
1340
1341//=======================================================================
1342//function : FilterByNeighbourgs
1343//purpose : regenerated the specified shape with help of its neighbours
1344//=======================================================================
1345// result - is a subshape of the first argument of the Name with type =
1346// ShapeType of this Name, which has a common subshapes (boundaries) with
1347// each neighbour - shapes from the other arguments of the Name.
1348//=======================================================================
1349static Standard_Boolean FilterByNeighbourgs (const TDF_Label& L,
1350 const TDF_LabelMap& Valid,
1351 const TNaming_ListOfNamedShape& Args,
1352 const Handle(TNaming_NamedShape)& Stop,
1353 const TopAbs_ShapeEnum ShapeType)
1354{
1355
1356 TNaming_Builder B(L);
1357
1358 TDF_LabelMap Forbiden;
7fd59977 1359 if(!ValidArgs(Args)) return Standard_False;
7fd59977 1360 TNaming_NamingTool::BuildDescendants (Stop, Forbiden); //all descendants of Stop (New shapes) are forbidden
1361 if (!Stop.IsNull()) Forbiden.Remove(Stop->Label());
1362 //----------------------------------------
1363 // First argument: collection has to be filtered.
1364 //----------------------------------------
1365 Handle(TNaming_NamedShape) Cand = Args.First(); //collection of candidates
1366
0797d9d3 1367#ifdef OCCT_DEBUG_FNB
7fd59977 1368 Standard_Integer i = 1;
1369 TCollection_AsciiString aNam("Cand_");
1370 TCollection_AsciiString ext(".brep");
1371 DbgTools_WriteNSOnLabel(Cand, aNam.ToCString());
04232180 1372 std::cout << "Cand (Args.First()) Label = ";
7fd59977 1373 PrintEntry(Cand->Label());
04232180 1374 std::cout << "Valid Label map:" <<std::endl;
7fd59977 1375 PrintEntries(Valid);
1376#endif
1377
0df87563 1378 TopTools_IndexedMapOfShape SCand;
7fd59977 1379 TNaming_NamingTool::CurrentShape (Valid, Forbiden,Cand,SCand);//fills SCand with last modifications of Cand. CandNS should be at the same level (before) as NS of FilterByNBS
1380
0797d9d3 1381#ifdef OCCT_DEBUG_FNB
7fd59977 1382 TCollection_AsciiString aNam2("SCand");
1383 DbgTools_Write(SCand, aNam2.ToCString());
04232180 1384 std::cout <<"SCand Extent = " << SCand.Extent() << " Expected ShapeType = " << ShapeType << std::endl;
7fd59977 1385#endif
1386
1387 //------------------------------------------------------------
1388 // Autres arguments : contiennent les voisins du bon candidat.
1389 // Other arguments : contains the neighbors of the good candidate.
1390 //------------------------------------------------------------
1391 TopAbs_ShapeEnum TC = TopAbs_EDGE;
1392 if (ShapeType == TopAbs_EDGE) TC = TopAbs_VERTEX;
1393 if (ShapeType == TopAbs_VERTEX) TC = TopAbs_VERTEX; // szy 31.03.10 - to process case when Candidate is of type Vertex
1394
0797d9d3 1395#ifdef OCCT_DEBUG_FNB
7fd59977 1396 i=1;
1397 aNam = "Boundaries";
1398#endif
efd4b232 1399 Standard_Boolean isDone = Standard_False;
7fd59977 1400 if(SCand.Extent() == 1) { // check if a collection is inside
0df87563 1401 TopoDS_Shape aS = SCand (1);
7fd59977 1402 if(!aS.IsNull())
1403 if(aS.ShapeType() == TopAbs_COMPOUND && aS.ShapeType() != ShapeType) {
0df87563 1404 SCand.Clear();
7fd59977 1405 TopoDS_Iterator itt(aS);
1406 for(;itt.More();itt.Next())
1407 SCand.Add(itt.Value());
7fd59977 1408 }
1409 }
0df87563 1410 for (Standard_Integer anItSCand = 1; anItSCand <= SCand.Extent(); ++anItSCand) { //1
1411 const TopoDS_Shape& S = SCand (anItSCand);
7fd59977 1412 TopTools_MapOfShape Boundaries;
1413 if(S.ShapeType() == TopAbs_VERTEX) //# szy 31.03.10
1414 Boundaries.Add (S); //#
1415 else //#
1416 for (TopExp_Explorer exp(S,TC); exp.More(); exp.Next()) { //put boundaries of each candidate (from SCand) to the Boundaries map
1417 Boundaries.Add (exp.Current());
0797d9d3 1418#ifdef OCCT_DEBUG_FNB
7fd59977 1419 TCollection_AsciiString aName = aNam + i++ + ext;
1420 DbgTools_Write(exp.Current(), aName.ToCString()) ;
1421#endif
1422 }
1423
1424 TNaming_ListIteratorOfListOfNamedShape it(Args);
1425 it.Next();
1426 Standard_Boolean Keep = 1;
0797d9d3 1427#ifdef OCCT_DEBUG_FNB
04232180 1428 std::cout <<"Args number = " << Args.Extent() <<std::endl;
7fd59977 1429 i=1;
1430 aNam = "Boundaries";
1431#endif
1432 for ( ; it.More(); it.Next()) { //2 ==> for each Arg
1433 Standard_Boolean Connected = Standard_False;
1434 // Le candidat doit etre connexe a au moins un shape de
1435 // chaque NamedShape des voisins.
1436 // The candidate should be connectedand and have at least one shape of NamedShape
1437 // of each neighbor.
1438 const Handle(TNaming_NamedShape)& NSVois = it.Value(); //neighbor
1439
0797d9d3 1440#ifdef OCCT_DEBUG_FNB
7fd59977 1441 DbgTools_WriteNSOnLabel(NSVois, "Next_Neighbor_") ;
1442#endif
1443
0df87563 1444 TopTools_IndexedMapOfShape SVois;
7fd59977 1445 TNaming_NamingTool::CurrentShape (Valid, Forbiden,NSVois,SVois); // fills SVois with last modifications of NSVois
1446
0797d9d3 1447#ifdef OCCT_DEBUG_FNB
7fd59977 1448 TCollection_AsciiString aNam2("SVois");
1449 DbgTools_Write(SVois, aNam2.ToCString());
1450#endif
1451
0df87563 1452 for (Standard_Integer anItSVois = 1; anItSVois <= SVois.Extent(); ++anItSVois) { //6
1453 const TopoDS_Shape& Vois = SVois (anItSVois);
7fd59977 1454 for (TopExp_Explorer exp1(Vois,TC); exp1.More(); exp1.Next()) { //7
1455 if (Boundaries.Contains(exp1.Current())) {
1456 Connected = Standard_True; // has common boundaries with candidate shape
0797d9d3 1457#ifdef OCCT_DEBUG_FNB
7fd59977 1458 DbgTools_Write(Vois, "Neighbor_Connected.brep");
1459#endif
1460 break;
1461 }
1462 } //7
1463 if (Connected) break;
1464 } //6
1465 if (!Connected) {
1466 Keep = 0;
1467 break;
1468 }
1469 } //2
1470 if (Keep) {
1471 B.Select (S,S);
efd4b232 1472 isDone = Standard_True;
0797d9d3 1473#ifdef OCCT_DEBUG_FNB
7fd59977 1474 DbgTools_Write(S, "FilterByNbs_Sel.brep") ;
1475#endif
1476 }
1477 } //1
efd4b232 1478 return isDone;
7fd59977 1479}
1480
1481//=======================================================================
1482static const TopoDS_Shape FindSubShapeInAncestor(const TopoDS_Shape& Selection, const TopoDS_Shape& Context )
1483{
0797d9d3 1484#ifdef OCCT_DEBUG_OR_AG
7fd59977 1485 DbgTools_Write(Selection, "Orientation_Selection.brep");
1486 DbgTools_Write(Context, "Orientation_Context.brep");
1487 TopExp_Explorer expl1(Context, Selection.ShapeType());
1488 int i = 0;
1489 TCollection_AsciiString SS( "Orientation_Current_");
1490 for(;expl1.More(); expl1.Next()) {
1491 if(expl1.Current().IsSame(Selection)) {
1492 i++;
04232180 1493 std::cout <<"FindSubShape: = " <<expl1.Current().ShapeType() << " TS = " <<expl1.Current().TShape() << std::endl;
7fd59977 1494 TCollection_AsciiString nam = SS + i + ".brep";
1495 DbgTools_Write(expl1.Current(), nam.ToCString());
1496 }
1497 }
1498#endif
1499 if(Selection.ShapeType() != TopAbs_COMPOUND) {
1500 TopExp_Explorer anExpl(Context, Selection.ShapeType());
1501 for(;anExpl.More(); anExpl.Next()) {
0797d9d3 1502#ifdef OCCT_DEBUG_OR_AG
04232180 1503 std::cout <<"FindSubShape: = " <<anExpl.Current().ShapeType() << " TS = " <<anExpl.Current().TShape()->This() << std::endl;
7fd59977 1504 DbgTools_Write(anExpl.Current(), "Orientation_Current.brep");
1505#endif
1506 if(anExpl.Current().IsSame(Selection))
1507 return anExpl.Current();
1508 }
1509 }
1510
1511 return TopoDS_Shape();
1512}
1513
1514//=======================================================================
1515//static Standard_Integer Count(const TopoDS_Shape& S)
1516//{
1517// Standard_Integer N(0);
1518// TopoDS_Iterator it(S);
1519// for(;it.More();it.Next()) {
1520// if(it.Value().ShapeType() != TopAbs_COMPOUND && it.Value().ShapeType() != TopAbs_COMPSOLID)
1521// N++;
1522// else {
1523// N += Count(it.Value());
1524// }
1525// }
1526// return N;
1527//}
1528//=======================================================================
1529static Standard_Integer Aggregation (const TopoDS_Shape& S, const TopoDS_Shape& AS, TNaming_Builder& B)
1530{
1531 Standard_Integer N(0);
1532 TopoDS_Iterator it(S);
1533 for(;it.More();it.Next()) {
1534 const TopoDS_Shape& sel = it.Value();
1535 if(sel.ShapeType() > TopAbs_COMPSOLID) {
1536 const TopoDS_Shape& CS = FindSubShapeInAncestor(sel, AS);
1537 if(!CS.IsNull()) {
1538 B.Select(CS, CS);
1539 N++;
1540 }
1541 } else
1542 N += Aggregation(sel, AS, B);
1543 }
1544 return N;
1545}
1546
1547//==========================================================================
1548//function : Orientation
1549//purpose : to solve ORIENTATION name
1550// this function explores the second argument | arguments (Context) and
1551// keeps at the label (L) the first argument (S) with the orientation it
1552// has in the context. Index is used only for Seam edge recomputing
1553//==========================================================================
1554static Standard_Boolean ORientation (const TDF_Label& L,
1555 const TDF_LabelMap& Valid,
1556 const TNaming_ListOfNamedShape& Args,
1557 const Handle(TNaming_NamedShape)& Stop,
1558 const Standard_Integer Index)
1559{
1560
1561 if(!ValidArgs(Args)) return Standard_False;
1562
1563 const Handle(TNaming_NamedShape)& A = Args.First();
0df87563 1564 TopTools_IndexedMapOfShape MS;
7fd59977 1565 TDF_LabelMap Forbiden;
1566 TNaming_NamingTool::BuildDescendants (Stop, Forbiden);
1567 TNaming_NamingTool::CurrentShape (Valid,Forbiden,A,MS);
1568
51740958 1569 TopoDS_Shape aShape;
7fd59977 1570 Standard_Boolean isSplit(Standard_False);
1571 if (!MS.IsEmpty ()) {
7fd59977 1572 if (MS.Extent() == 1) {
51740958 1573 aShape = MS (1);
7fd59977 1574 }
1575 else {
1576 isSplit = Standard_True;
51740958 1577 aShape = MakeShape(MS);
0797d9d3 1578#ifdef OCCT_DEBUG_OR
0df87563 1579 for(Standard_Integer anItMS = 1; anItMS <= MS.Extent(); anItMS++) {
7fd59977 1580 TCollection_AsciiString aNam("OR_Selection_");
0df87563 1581 TCollection_AsciiString aName = aNam + anItMS + ".brep";
1582 DbgTools_Write(MS (anItMS), aName.ToCString());
7fd59977 1583 }
1584#endif
1585 }
1586 }
1587
1588 TNaming_Builder B(L);
51740958 1589 if(aShape.IsNull())
7fd59977 1590 return Standard_False;
0797d9d3 1591#ifdef OCCT_DEBUG_OR
7fd59977 1592 DbgTools_Write(S, "Orientation_S.brep");
1593#endif
1594
1595 TopTools_ListOfShape aSList;
1596 // tmp. solution
51740958 1597 if(aShape.ShapeType() == TopAbs_COMPOUND && !isSplit) {
1598 TopoDS_Iterator it(aShape);
7fd59977 1599 for(;it.More();it.Next())
1600 aSList.Append(it.Value());
1601 } //
1602
0df87563 1603 TopTools_IndexedMapOfShape MSC;
7fd59977 1604 if(aSList.Extent() == 0) {
1605 const Handle(TNaming_NamedShape)& Anc = Args.Last();
0797d9d3 1606#ifdef OCCT_DEBUG_OR
04232180 1607 std::cout << "### ORIENTATION: Ancestor ";
7fd59977 1608 PrintEntry(Anc->Label());
1609#endif
1610 MSC.Clear();
1611 TNaming_NamingTool::CurrentShape (Valid,Forbiden,Anc,MSC);
1612 if(MSC.Extent() == 1) {
0df87563 1613 for (Standard_Integer anItMSC = 1; anItMSC <= MSC.Extent(); ++anItMSC) {
1614 const TopoDS_Shape& AS = MSC (anItMSC);
7fd59977 1615// <=== start 21.10.2009
1616 TopoDS_Shape CS;
1617 if(Index > 0) { //only for seam edge
1618 TopoDS_Iterator itw(AS);
1619 for(;itw.More();itw.Next()) {
1620 Standard_Boolean found(Standard_False);
1621 TopoDS_Iterator it(itw.Value());
1622 for(int i=1;it.More();it.Next(),i++) {
51740958 1623 if(i == Index && it.Value().IsSame(aShape)) {
7fd59977 1624 CS = it.Value();
1625 found = Standard_True;
0797d9d3 1626#ifdef OCCT_DEBUG_OR
04232180 1627 std::cout << "ORIENTATION => ORDER = " << i <<std::endl;
7fd59977 1628#endif
1629 break;
1630 }
1631 }
1632 if(found) break;
1633 }
1634 } else
51740958 1635 CS = FindSubShapeInAncestor(aShape, AS);
7fd59977 1636// <=== end 21.10.2009
0797d9d3 1637#ifdef OCCT_DEBUG_OR
04232180 1638 std::cout << "ORIENTATION: Selection TShape = " <<CS.TShape() <<" Orientation = " << CS.Orientation() <<std::endl;
1639 std::cout << "ORIENTATION: Context ShapeType = "<<AS.ShapeType() << " TShape = " <<AS.TShape() <<std::endl;
7fd59977 1640 DbgTools_Write(AS, "Orientation_Cnt.brep");
1641#endif
1642 if(!CS.IsNull()) {
1643 B.Select(CS, CS);
1644 } else {
51740958 1645 if(!Aggregation(aShape, AS, B))
7fd59977 1646 return Standard_False;
1647 }
1648 }
1649 } else {
1650 const TopoDS_Shape AS = MakeShape(MSC);
51740958 1651 const TopoDS_Shape& CS = FindSubShapeInAncestor(aShape, AS);
7fd59977 1652 if(!CS.IsNull()) {
1653 B.Select(CS, CS);
1654 } else {
51740958 1655 if(!Aggregation(aShape, AS, B))
7fd59977 1656 return Standard_False;
1657 }
1658 }
1659 } else {
1660 TNaming_ListIteratorOfListOfNamedShape it(Args);
1661 it.Next(); //skip first
1662
1663 // temporary solution. To be optimized (+ has connection with Union name)
1664 Handle(TopTools_HArray2OfShape) Arr; // Arr(1,1) - selection; Arr(1,2) - Context shape
1665 Arr = new TopTools_HArray2OfShape (1, aSList.Extent(), 1, 2);
1666 TopTools_ListIteratorOfListOfShape it1(aSList);
1667 Standard_Integer i = 1;
1668 for(; it1.More(); it1.Next(), it.Next(), i++) {
1669 Arr->SetValue(i, 1, it1.Value());
1670 MSC.Clear();
1671 TNaming_NamingTool::CurrentShape (Valid,Forbiden,it.Value(),MSC);
1672 if(MSC.Extent() == 1) {
0df87563 1673 Arr->SetValue(i, 2, MSC (1));
7fd59977 1674 } else {
1675 const TopoDS_Shape AS = MakeShape(MSC);
1676 Arr->SetValue(i, 2, AS);
1677 }
1678 }
1679
1680 if(aSList.Extent() == 1) {
1681 const TopoDS_Shape& S = Arr->Value(1,1);
1682 if(S.ShapeType() != TopAbs_COMPOUND) {
1683 const TopoDS_Shape& CS = FindSubShapeInAncestor(S, Arr->Value(1,2));
1684 if(!CS.IsNull()) {
1685 B.Select(CS, CS);
1686 } else
1687 return Standard_False;
1688 }
1689 else {
0797d9d3 1690#ifdef OCCT_DEBUG_OR
7fd59977 1691 DbgTools_Write(Arr->Value(1,2), "Ancestor.brep");
1692#endif
1693 if(!Aggregation(S, Arr->Value(1,2), B)) {
1694 return Standard_False;
1695 }
1696 }
1697 }
1698 else { // > 1
51740958 1699 for(Standard_Integer k = Arr->LowerRow();k <= Arr->UpperRow();k++) {
1700 const TopoDS_Shape& S = Arr->Value(k,1);
1701 const TopoDS_Shape& AC = Arr->Value(k,2);
7fd59977 1702 if(S.ShapeType() != TopAbs_COMPOUND) {
1703 const TopoDS_Shape& CS = FindSubShapeInAncestor(S, AC);
1704 if(!CS.IsNull()) {
1705 B.Select(CS, CS);
1706 } else
1707 return Standard_False;
1708 }
1709 else {
0797d9d3 1710#ifdef OCCT_DEBUG_OR
7fd59977 1711 DbgTools_Write(AC, "Aggregation.brep");
1712#endif
1713 if(!Aggregation(S, AC, B)) {
1714 return Standard_False;
1715 }
1716 }
1717 }
1718 }
1719 } // end of tmp. solution
1720
1721 return Standard_True;
1722}
1723
1724//===========================================================================
1725//function : WireIN
1ec8a59e 1726//purpose : to solve WIREIN name
7fd59977 1727//=======================================================================
1728static Standard_Boolean WireIN(const TDF_Label& L,
1729 const TDF_LabelMap& Valid,
1ec8a59e 1730 const TNaming_ListOfNamedShape& Args,
1731 const Handle(TNaming_NamedShape)& Stop,
1732 Standard_Integer Index)
7fd59977 1733{
1734 Standard_Boolean aResult(Standard_False);
1735 if(!ValidArgs(Args)) return aResult;
51740958 1736 TopTools_IndexedMapOfShape aMapOfSh;
1737 TDF_LabelMap aForbiden;
1ec8a59e 1738 if (Args.Extent() < 1 )
9775fa61 1739 throw Standard_ConstructionError("TNaming_Name::Solve");
1ec8a59e 1740 const Handle(TNaming_NamedShape)& A = Args.First();
51740958 1741 TNaming_NamingTool::CurrentShape (Valid,aForbiden,A, aMapOfSh);
1742 if (aMapOfSh.Extent() != 1) return aResult;
1743 const TopoDS_Shape& aCF = aMapOfSh(1);
0797d9d3 1744#ifdef OCCT_DEBUG_WIN
04232180 1745 std::cout <<"MS Extent = " <<MS.Extent() <<std::endl;
1ec8a59e 1746 DbgTools_Write(aCF, "Context_Face.brep");
7fd59977 1747#endif
7fd59977 1748 TNaming_Builder B(L);
1ec8a59e 1749 if(Index == 1 ){ //Outer wire case
1750 TopoDS_Wire anOuterWire;
1751 TNaming::OuterWire(TopoDS::Face(aCF), anOuterWire);
1752 if(!anOuterWire.IsNull()) {
1753 B.Select(anOuterWire, anOuterWire);
1754 aResult = Standard_True;
1755 }
1756 } else { //has internal wires
1757 TNaming_ListOfNamedShape ArgsE;
1758 ArgsE.Assign(Args);
1759 ArgsE.RemoveFirst();
1760 // fill Map with edges
51740958 1761 TNaming_ListIteratorOfListOfNamedShape anIter(ArgsE);
0df87563 1762 TopTools_IndexedMapOfShape MS;
1ec8a59e 1763 TDF_LabelMap Forbiden;
1764
1765 TNaming_NamingTool::BuildDescendants (Stop, Forbiden);//fill Forbidden
51740958 1766 TNaming_NamingTool::CurrentShape (Valid, Forbiden, anIter.Value(),MS); // fill MS with last modifications of the first additional argument
1ec8a59e 1767 TopoDS_Shape CS = MakeShape(MS);
1768
1769 TNaming_ShapesSet aSet(CS,TopAbs_EDGE);//fill internal map of shapeset by shapes of the specified type
0797d9d3 1770#ifdef OCCT_DEBUG_WIN
1ec8a59e 1771 TCollection_AsciiString entry;
1772 TDF_Tool::Entry(it.Value()->Label(), entry);
1773 TCollection_AsciiString Nam("Arg_");
1774 TCollection_AsciiString aNam = Nam + entry + "_" + "2.brep";
1775 DbgTools_Write(CS, aNam.ToCString());
1776 Standard_Integer ii = 2;
1777#endif
51740958 1778 anIter.Next();
1779 for (; anIter.More(); anIter.Next()) {
0797d9d3 1780#ifdef OCCT_DEBUG_WIN
1ec8a59e 1781 TDF_Tool::Entry(it.Value()->Label(), entry);
1782#endif
1783 MS.Clear();
51740958 1784 TNaming_NamingTool::CurrentShape (Valid, Forbiden,anIter.Value(),MS);// fill MS with last modifications of the it.Value()
1ec8a59e 1785 CS = MakeShape(MS);
1786 TNaming_ShapesSet OS(CS,TopAbs_EDGE);
1787 aSet.Add(OS); //concatenate both shapesets
1788
0797d9d3 1789#ifdef OCCT_DEBUG_WIN
1ec8a59e 1790 ii++;
1791 TCollection_AsciiString aNm = Nam + entry + "_" + ii + ".brep";
1792 DbgTools_Write(CS, aNm.ToCString());
04232180 1793 std::cout <<"Arg: Entry = " <<entry <<" TShape = " << CS.TShape() <<std::endl;
7fd59977 1794#endif
1ec8a59e 1795 }
1796
0797d9d3 1797#ifdef OCCT_DEBUG_WIN
04232180 1798 std::cout <<"WIREIN: Internal Map ext = " << aSet.Map().Extent()<<std::endl;
1ec8a59e 1799 TopTools_MapIteratorOfMapOfShape it1 (aSet.Map());
1800 for (int i=1;it1.More();it1.Next(),i++) {
04232180 1801 std::cout << "Map("<<i<<"): TShape = " << it1.Key().TShape() << " Orient = " << it1.Key().Orientation() <<" Type = " <<
1802 it1.Key().ShapeType()<<std::endl;
7fd59977 1803 }
1804
1ec8a59e 1805 TopExp_Explorer exp(aCF, TopAbs_EDGE);
1806 for(int i =1;exp.More();exp.Next(), i++) {
04232180 1807 std::cout << "Context_Face("<<i<<"): TShape = " << exp.Current().TShape() << " Orient = " << exp.Current().Orientation() <<std::endl;
1ec8a59e 1808 }
7fd59977 1809#endif
1ec8a59e 1810//end for edges
1811
1812 for (TopoDS_Iterator itF(aCF); itF.More(); itF.Next()) {// find the expected wire in the face
1813 const TopoDS_Shape& S = itF.Value();//wire
1814 if(!S.IsNull()) {
0797d9d3 1815#ifdef OCCT_DEBUG_WIN
1ec8a59e 1816 DbgTools_Write(S, "WireIN_S.brep");
04232180 1817 std::cout <<"WIREIN: ShapeType = " << S.ShapeType() << " TS = " << S.TShape()->This() <<std::endl;
1ec8a59e 1818#endif
1819 if(S.ShapeType() == TopAbs_WIRE) {
1820 TopTools_MapOfShape aView;
1821 Standard_Integer aNum(0x7FFFFFFF);
1822 for (TopoDS_Iterator it(S);it.More();it.Next())
1823 aView.Add(it.Value());// edges of wire of the face in map
1824
1825 TopTools_MapIteratorOfMapOfShape it (aSet.Map());
1826 aNum = aView.Extent();
1827 if(aNum == aSet.Map().Extent()) {
1828 for (;it.More();it.Next()) {
1829 if(aView.Contains(it.Key())) {
1830 aNum--;
1831 }
1832 }
1833 }
1834 if(aNum == 0) {
1835 B.Select(S, S);
1836 aResult = Standard_True;
7fd59977 1837 break;
1ec8a59e 1838 }
1839 }
1840 }
1841 } //
1842
1843 if(!aResult) {
1844 TopoDS_Wire anOuterWire;
1845 TNaming::OuterWire(TopoDS::Face(aCF), anOuterWire);
1846 if(!anOuterWire.IsNull()) {
1847 for (TopoDS_Iterator itF(aCF); itF.More(); itF.Next()) {
1848 const TopoDS_Shape& S = itF.Value();//wire
1849 if(!S.IsNull()&& S.ShapeType() == TopAbs_WIRE) {
1850 if(S.IsEqual(anOuterWire)) continue;
1851 B.Select(S, S);
1852 }
7fd59977 1853 }
1854 }
1ec8a59e 1855 }
1856 }
1857 return aResult;
1858}
1859//===========================================================================
1860//function : ShellIN
1861//purpose : to solve SHELLIN name
1862//===========================================================================
1863static Standard_Boolean ShellIN(const TDF_Label& L,
1864 const TDF_LabelMap& Valid,
1865 const TNaming_ListOfNamedShape& Args,
1866 const Handle(TNaming_NamedShape)& Stop,
1867 Standard_Integer Index)
1868{
1869 Standard_Boolean aResult(Standard_False);
1870 if(!ValidArgs(Args))
1871 return aResult;
51740958 1872 TopTools_IndexedMapOfShape aMapOfSh;
1873 TDF_LabelMap aForbiden;
1ec8a59e 1874 if (Args.Extent() < 1 )
9775fa61 1875 throw Standard_ConstructionError("TNaming_Name::Solve");
1ec8a59e 1876 const Handle(TNaming_NamedShape)& A = Args.First();
51740958 1877 TNaming_NamingTool::CurrentShape (Valid,aForbiden,A, aMapOfSh);
1878 if (aMapOfSh.Extent() != 1) return aResult;
1879 const TopoDS_Shape& aCSO = aMapOfSh(1);
0797d9d3 1880#ifdef OCCT_DEBUG_SHELL
04232180 1881 std::cout <<"MS Extent = " <<MS.Extent() <<std::endl;
1ec8a59e 1882 DbgTools_Write(aCSO, "Context_Solid.brep");
1883#endif
1884 TNaming_Builder B(L);
1885 if(Index == 1 ){ //Outer Shell case
1886 TopoDS_Shell anOuterShell;
1887 TNaming::OuterShell(TopoDS::Solid(aCSO), anOuterShell);
1888 if(!anOuterShell.IsNull()) {
1889 B.Select(anOuterShell, anOuterShell);
7fd59977 1890 aResult = Standard_True;
0797d9d3 1891#ifdef OCCT_DEBUG_SHELL
04232180 1892 std::cout << "Outer Shell case" <<std::endl;
1ec8a59e 1893 PrintEntry(L);
1894 DbgTools_Write(anOuterShell, "ShellOut_S.brep");
0df87563 1895 TopoDS_Iterator it (aCSO);
1ec8a59e 1896 for(;it.More();it.Next()){
1897 DbgTools_Write(it.Value(), "ShOut_S.brep");
1898 }
1899#endif
7fd59977 1900 }
1ec8a59e 1901 } else { //has internal Shells
1902 TNaming_ListOfNamedShape ArgsF;
1903 ArgsF.Assign(Args);
1904 ArgsF.RemoveFirst();
1905 // fill Map with faces
51740958 1906 TNaming_ListIteratorOfListOfNamedShape anIter(ArgsF);
0df87563 1907 TopTools_IndexedMapOfShape MS;
1ec8a59e 1908 TDF_LabelMap Forbiden;
1909
1910 TNaming_NamingTool::BuildDescendants (Stop, Forbiden);//fill Forbidden
51740958 1911 TNaming_NamingTool::CurrentShape (Valid, Forbiden, anIter.Value(),MS); // fill MS with last modifications of the first additional argument
1ec8a59e 1912 TopoDS_Shape CS = MakeShape(MS);
1913
1914 TNaming_ShapesSet aSet(CS,TopAbs_FACE);//fill internal map of shapeset by shapes of the specified type
0797d9d3 1915#ifdef OCCT_DEBUG_SHELL
1ec8a59e 1916 TCollection_AsciiString entry;
51740958 1917 TDF_Tool::Entry(anIter.Value()->Label(), entry);
1ec8a59e 1918 TCollection_AsciiString Nam("Arg_");
1919 TCollection_AsciiString aNam = Nam + entry + "_" + "2.brep";
1920 DbgTools_Write(CS, aNam.ToCString());
1921 Standard_Integer ii = 2;
1922#endif
51740958 1923 anIter.Next();
1924 for (; anIter.More(); anIter.Next()) {
0797d9d3 1925#ifdef OCCT_DEBUG_SHELL
51740958 1926 TDF_Tool::Entry(anIter.Value()->Label(), entry);
1ec8a59e 1927#endif
1928 MS.Clear();
51740958 1929 TNaming_NamingTool::CurrentShape (Valid, Forbiden,anIter.Value(),MS);// fill MS with last modifications of the it.Value()
1ec8a59e 1930 CS = MakeShape(MS);
1931 TNaming_ShapesSet OS(CS,TopAbs_FACE);
1932 aSet.Add(OS); //concatenate both shapesets
1933
0797d9d3 1934#ifdef OCCT_DEBUG_SHELL
1ec8a59e 1935 ii++;
1936 TCollection_AsciiString aNm = Nam + entry + "_" + ii + ".brep";
1937 DbgTools_Write(CS, aNm.ToCString());
04232180 1938 std::cout <<"Arg: Entry = " <<entry <<" TShape = " << CS.TShape() <<std::endl;
1ec8a59e 1939#endif
1940 }
1941
0797d9d3 1942#ifdef OCCT_DEBUG_SHELL
04232180 1943 std::cout <<"SHELLIN: Internal Map ext = " << aSet.Map().Extent()<<std::endl;
1ec8a59e 1944 TopTools_MapIteratorOfMapOfShape it1 (aSet.Map());
1945 for (int i=1;it1.More();it1.Next(),i++) {
04232180 1946 std::cout << "Map("<<i<<"): TShape = " << it1.Key().TShape() << " Orient = " << it1.Key().Orientation() <<" Type = " <<
1947 it1.Key().ShapeType()<<std::endl;
7fd59977 1948 }
1ec8a59e 1949
1950 TopExp_Explorer exp(aCSO, TopAbs_FACE);
1951 for(int i = 1;exp.More();exp.Next(), i++) {
04232180 1952 std::cout << "Context_Solid("<<i<<"): TShape = " << exp.Current().TShape() << " Orient = " << exp.Current().Orientation() <<std::endl;
1ec8a59e 1953 }
1954#endif
1955//end for faces
1956
1957 for (TopoDS_Iterator itS(aCSO); itS.More(); itS.Next()) {// find the expected shell in the solid
1958 const TopoDS_Shape& S = itS.Value();//shell
1959 if(!S.IsNull()) {
0797d9d3 1960#ifdef OCCT_DEBUG_SHELL
1ec8a59e 1961 DbgTools_Write(S, "ShellIN_S.brep");
04232180 1962 std::cout <<"SHELLIN: ShapeType = " << S.ShapeType() << " TS = " << S.TShape()->This() <<std::endl;
1ec8a59e 1963#endif
1964 if(S.ShapeType() == TopAbs_SHELL) {
1965 TopTools_MapOfShape aView;
1966 Standard_Integer aNum(0x7FFFFFFF);
1967 for (TopoDS_Iterator it(S);it.More();it.Next())
1968 aView.Add(it.Value());// faces of shell of the solid in map
1969
1970 aNum = aView.Extent();
1971 if(aNum == aSet.Map().Extent()) {
1972 TopTools_MapIteratorOfMapOfShape it (aSet.Map());
1973 for (;it.More();it.Next()) {
1974 if(aView.Contains(it.Key())) {
1975 aNum--;
1976 }
1977 }
1978 }
1979 if(aNum == 0) {
1980 B.Select(S, S);
1981 aResult = Standard_True;
1982 break;
1983 }
1984 }
1985 }
1986 } //
1987
1988 if(!aResult) {
1989 TopoDS_Shell anOuterShell;
1990 TNaming::OuterShell(TopoDS::Solid(aCSO), anOuterShell);
1991 if(!anOuterShell.IsNull()) {
1992 for (TopoDS_Iterator itS(aCSO); itS.More(); itS.Next()) {
1993 const TopoDS_Shape& S = itS.Value();//shell
1994 if(!S.IsNull()&& S.ShapeType() == TopAbs_SHELL) {
1995 if(S.IsEqual(anOuterShell)) continue;
1996 B.Select(S, S);
1997 }
1998 }
1999 }
2000 }
7fd59977 2001 }
2002 return aResult;
2003}
0797d9d3 2004#ifdef OCCT_DEBUG
7fd59977 2005//=======================================================================
2006static Standard_CString NameTypeToString (const TNaming_NameType Type)
2007{
2008 switch(Type)
2009 {
2010 case TNaming_UNKNOWN : return "UNKNOWN";
2011 case TNaming_IDENTITY : return "IDENTITY";
2012 case TNaming_MODIFUNTIL : return "MODIFUNTIL";
2013 case TNaming_GENERATION : return "GENERATION";
2014 case TNaming_INTERSECTION : return "INTERSECTION";
2015 case TNaming_UNION : return "UNION";
2016 case TNaming_SUBSTRACTION : return "SUBSTRACTION";
2017 case TNaming_CONSTSHAPE : return "CONSTSHAPE";
2018 case TNaming_FILTERBYNEIGHBOURGS : return "FILTERBYNEIGHBOURGS";
2019 case TNaming_ORIENTATION : return "ORIENTATION";
2020 case TNaming_WIREIN : return "WIREIN";
2021 default :
9775fa61 2022 throw Standard_DomainError("TNaming_NameType; enum term unknown ");
7fd59977 2023 }
7fd59977 2024}
2025#endif
2026//=======================================================================
2027//function : Solve
2028//purpose :
2029//=======================================================================
2030
2031Standard_Boolean TNaming_Name::Solve(const TDF_Label& aLab,
2032 const TDF_LabelMap& Valid) const
2033{
2034 Standard_Boolean Done = 0;
0797d9d3 2035#ifdef OCCT_DEBUG_WIN
1ec8a59e 2036 PrintEntry(aLab);
2037#endif
7fd59977 2038 try {
b350f6ee 2039 OCC_CATCH_SIGNALS
7fd59977 2040 switch (myType) {
2041 case TNaming_UNKNOWN :
2042 {
2043 break;
2044 }
2045 case TNaming_IDENTITY :
2046 {
2047 Done = Identity(aLab,Valid,myArgs,myShapeType);
2048 break;
2049 }
2050 case TNaming_MODIFUNTIL:
2051 {
2052 Done = ModifUntil (aLab,Valid,myArgs,myStop);
2053 break;
2054 }
2055 case TNaming_GENERATION:
2056 {
2057 Done = Generated (aLab,Valid,myArgs);
2058 break;
2059 }
2060 case TNaming_INTERSECTION:
2061 {
2062 Done = Intersection (aLab,Valid,myArgs,myStop,myShapeType,myIndex);
2063 break;
2064 }
2065 case TNaming_UNION:
2066 {
2067 Done = Union (aLab,Valid,myArgs,myStop,myShapeType, myContextLabel);
2068 break;
2069 }
2070 case TNaming_SUBSTRACTION:
2071 {
9775fa61 2072 throw Standard_NotImplemented();
7fd59977 2073// Done = Substraction (aLab,Valid,myArgs);
2074 break;
2075 }
2076 case TNaming_CONSTSHAPE:
2077 {
2078 Done = ConstShape (aLab,Valid,myArgs,myStop,myIndex);
2079 break;
2080 }
2081 case TNaming_FILTERBYNEIGHBOURGS:
2082 {
2083 Done = FilterByNeighbourgs (aLab,Valid,myArgs,myStop,myShapeType);
2084 break;
2085 }
2086 case TNaming_ORIENTATION:
2087 {
2088 Done = ORientation (aLab,Valid,myArgs,myStop,myIndex);
2089 break;
2090 }
2091 case TNaming_WIREIN:
2092 {
0797d9d3 2093#ifdef OCCT_DEBUG_WIN
04232180 2094 std::cout << "Name::Solve: NameType = " << myType << " ";
1ec8a59e 2095 PrintEntry(aLab);
2096#endif
2097 Done = WireIN (aLab,Valid,myArgs,myStop,myIndex);
2098 break;
2099 }
2100case TNaming_SHELLIN:
2101 {
0797d9d3 2102#ifdef OCCT_DEBUG_SHELL
04232180 2103 std::cout << "Name::Solve: NameType = " << myType << " ";
1ec8a59e 2104 PrintEntry(aLab);
2105#endif
2106 Done = ShellIN (aLab,Valid,myArgs,myStop,myIndex);
7fd59977 2107 break;
2108 }
2109 }
a738b534 2110} catch (Standard_Failure const&) {
0797d9d3 2111#ifdef OCCT_DEBUG
04232180 2112 std::cout << "Name::Solve: EXCEPTION==> NameType = " << NameTypeToString(myType) << " ";
7fd59977 2113 PrintEntry(aLab);
2114#endif
2115}
2116 return Done;
2117}
2118
2119//=======================================================================
2120//function : ContextLabel
2121//purpose : Set
2122//=======================================================================
2123
2124void TNaming_Name::ContextLabel(const TDF_Label& theLabel)
2125{
2126 myContextLabel = theLabel;
2127}
2128
2129//=======================================================================
2130//function : ContextLabel
2131//purpose : Get
2132//=======================================================================
2133
2134const TDF_Label& TNaming_Name::ContextLabel() const
2135{
2136 return myContextLabel;
2137}
7dcac1df 2138
7fd59977 2139//=======================================================================
2140//function : Orientation
2141//purpose : Set
2142//=======================================================================
7dcac1df 2143void TNaming_Name::Orientation(const TopAbs_Orientation theOrientation)
7fd59977 2144{
2145 myOrientation = theOrientation;
2146}
2147
bc73b006 2148//=======================================================================
2149//function : DumpJson
2150//purpose :
2151//=======================================================================
2152void TNaming_Name::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
2153{
2154 OCCT_DUMP_CLASS_BEGIN (theOStream, TNaming_Name)
2155
2156 OCCT_DUMP_FIELD_VALUE_STRING (theOStream, myType)
2157 OCCT_DUMP_FIELD_VALUE_STRING (theOStream, myShapeType)
2158
2159 for (TNaming_ListOfNamedShape::Iterator anArgsIt (myArgs); anArgsIt.More(); anArgsIt.Next())
2160 {
2161 const Handle(TNaming_NamedShape)& anArg = anArgsIt.Value();
2162 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, anArg.get())
2163 }
2164
2165 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIndex)
2166 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myShape)
2167
2168 TCollection_AsciiString aLabel;
2169 TDF_Tool::Entry (myContextLabel, aLabel);
2170 OCCT_DUMP_FIELD_VALUE_STRING (theOStream, aLabel)
2171 OCCT_DUMP_FIELD_VALUE_STRING (theOStream, myOrientation)
2172}