1 // Created on: 1999-09-30
2 // Created by: Denis PASCAL
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <TDF_ChildIterator.hxx>
19 #include <TDF_IDFilter.hxx>
20 #include <TDF_Label.hxx>
21 #include <TDF_Tool.hxx>
22 #include <TNaming.hxx>
23 #include <TNaming_Builder.hxx>
24 #include <TNaming_Identifier.hxx>
25 #include <TNaming_NamedShape.hxx>
26 #include <TNaming_NameType.hxx>
27 #include <TNaming_Naming.hxx>
28 #include <TNaming_NamingTool.hxx>
29 #include <TNaming_NewShapeIterator.hxx>
30 #include <TNaming_Selector.hxx>
31 #include <TopoDS_Iterator.hxx>
32 #include <TopoDS_Shape.hxx>
33 #include <TopTools_IndexedMapOfShape.hxx>
34 #include <TopTools_ListIteratorOfListOfShape.hxx>
36 //#define MDTV_DEB_SEL
38 //#define MDTV_DEB_BNP
39 #include <TopExp_Explorer.hxx>
40 #include <TCollection_AsciiString.hxx>
41 #include <TNaming_Tool.hxx>
42 #include <BRep_Tool.hxx>
44 #include <TNaming_UsedShapes.hxx>
45 void PrintEntry(const TDF_Label& label, const Standard_Boolean allLevels)
47 TCollection_AsciiString entry;
48 TDF_Tool::Entry(label, entry);
49 std::cout << "LabelEntry = "<< entry << std::endl;
51 TDF_ChildIterator it (label, allLevels);
52 for (; it.More(); it.Next()) {
53 TDF_Tool::Entry(it.Value(), entry);
54 std::cout << "ChildLabelEntry = "<< entry << std::endl;
58 #include <BRepTools.hxx>
59 static void Write(const TopoDS_Shape& shape,
60 const Standard_CString filename)
63 if(strlen(filename) > 255) return;
65 strcpy_s (buf, filename);
67 strcpy (buf, filename);
75 std::ofstream save (buf);
77 std::cout << "File " << buf << " was not created: rdstate = " << save.rdstate() << std::endl;
78 save << "DBRep_DrawableShape" << std::endl << std::endl;
79 if(!shape.IsNull()) BRepTools::Write(shape, save);
84 #define ORIENTATION_DSOPT
85 #ifdef ORIENTATION_DSOPT
86 #include <TopTools_MapOfOrientedShape.hxx>
87 #include <TopTools_MapIteratorOfMapOfOrientedShape.hxx>
88 #include <TDF_ChildIDIterator.hxx>
89 #include <TNaming_Tool.hxx>
90 #include <TNaming_Iterator.hxx>
91 #include <TNaming_OldShapeIterator.hxx>
92 #include <TNaming_NamedShape.hxx>
93 //==========================================================================================
94 inline static void MapOfOrientedShapes(const TopoDS_Shape& S, TopTools_MapOfOrientedShape& M)
97 TopoDS_Iterator It(S,Standard_True,Standard_True);
99 MapOfOrientedShapes(It.Value(),M);
103 //=======================================================================
104 static void BuildAtomicMap(const TopoDS_Shape& S, TopTools_MapOfOrientedShape& M)
106 if(S.ShapeType() > TopAbs_COMPSOLID) return;
107 TopoDS_Iterator it(S);
108 for(;it.More();it.Next()) {
109 if(it.Value().ShapeType() > TopAbs_COMPSOLID)
112 BuildAtomicMap(it.Value(), M);
116 //==========================================================================================
117 static const Handle(TNaming_NamedShape) FindPrevNDS(const Handle(TNaming_NamedShape)& CNS)
119 Handle(TNaming_NamedShape) aNS;
120 TNaming_Iterator it(CNS);
122 if(!it.OldShape().IsNull()) {
123 aNS = TNaming_Tool::NamedShape(it.OldShape(), CNS->Label());
130 //==========================================================================================
131 // Purpose: checks correspondens between orientation of sub-shapes of Context and orientation
132 // of sub-shapes registered in DF and put under result label
133 //==========================================================================================
134 static Standard_Boolean IsSpecificCase(const TDF_Label& F, const TopoDS_Shape& Context)
136 Standard_Boolean isFound(Standard_False);
137 TopTools_MapOfOrientedShape shapesOfContext;
138 MapOfOrientedShapes(Context,shapesOfContext);
139 Handle(TNaming_NamedShape) CNS = TNaming_Tool::NamedShape(Context, F);
140 #ifdef OCCT_DEBUG_BNP
141 PrintEntry (CNS->Label(),0);
144 TNaming_ListOfNamedShape aLNS;
145 TDF_ChildIDIterator cit(CNS->Label(), TNaming_NamedShape::GetID(), Standard_False);
147 // Naming data structure is empty - no sub-shapes under resulting shape
148 const Handle(TNaming_NamedShape) aNS = FindPrevNDS(CNS); //look to old shape data structure if exist
150 #ifdef OCCT_DEBUG_BNP
151 PrintEntry (aNS->Label(),0);
153 cit.Initialize(aNS->Label(), TNaming_NamedShape::GetID(), Standard_False);
155 return Standard_True;
158 for(;cit.More();cit.Next()) {
159 Handle(TNaming_NamedShape) NS (Handle(TNaming_NamedShape)::DownCast(cit.Value()));
161 TopoDS_Shape aS = TNaming_Tool::CurrentShape(NS);
162 if(aS.IsNull()) continue;
163 #ifdef OCCT_DEBUG_BNP
164 PrintEntry(NS->Label(), 0);
165 std::cout <<"ShapeType =" << aS.ShapeType() <<std::endl;
166 Write (aS, "BNProblem.brep");
168 if(aS.ShapeType() != TopAbs_COMPOUND) {//single shape at the child label
169 if(!shapesOfContext.Contains(aS)) {
170 isFound = Standard_True;
175 TopTools_MapOfOrientedShape M;
176 BuildAtomicMap(aS, M);
177 TopTools_MapIteratorOfMapOfOrientedShape it(M);
178 for(;it.More();it.Next()) {
179 if(!shapesOfContext.Contains(it.Key())) {
180 #ifdef OCCT_DEBUG_BNP
181 std::cout <<"BNProblem: ShapeType in AtomicMap = " << it.Key().ShapeType() << " TShape = " <<it.Key().TShape() <<" OR = " <<it.Key().Orientation() <<std::endl;
182 Write (it.Key(), "BNProblem_AtomicMap_Item.brep");
183 TopTools_MapIteratorOfMapOfOrientedShape itC(shapesOfContext);
184 for(;itC.More(); itC.Next())
185 std::cout <<" ShapeType = " << itC.Key().ShapeType() << " TShape = " << itC.Key().TShape() << " OR = " << itC.Key().Orientation() << std::endl;
188 isFound = Standard_True;
200 //==========================================================================================
201 static Standard_Boolean IsSpecificCase2(const TDF_Label& F, const TopoDS_Shape& Selection)
203 Standard_Boolean isTheCase(Standard_False);
204 if(Selection.ShapeType() == TopAbs_EDGE) {
205 Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(Selection, F);
206 if(!aNS.IsNull()) { //presented in DF
207 #ifdef OCCT_DEBUG_BNP
208 PrintEntry (aNS->Label(),0);
210 const TopoDS_Shape& aS = TNaming_Tool::CurrentShape(aNS);
211 if(!aS.IsNull() && aS.ShapeType() == Selection.ShapeType()) {
212 if(Selection.Orientation() != aS.Orientation()) {
213 isTheCase = Standard_True;
221 //=======================================================================
222 //function : FindGenerated
223 //purpose : Finds all generated from the <S>
224 //=======================================================================
226 static void FindGenerated(const Handle(TNaming_NamedShape)& NS, const TopoDS_Shape& S,
227 TopTools_ListOfShape& theList)
230 const TDF_Label& LabNS = NS->Label();
231 for (TNaming_NewShapeIterator it (S, LabNS); it.More(); it.Next()) {
232 if (it.Label() == LabNS) {
233 theList.Append(it.Shape());
237 //=======================================================================
238 //function : IsIdentified
240 //=======================================================================
241 Standard_Boolean TNaming_Selector::IsIdentified (const TDF_Label& L,
242 const TopoDS_Shape& Selection,
243 Handle(TNaming_NamedShape)& NS,
244 const Standard_Boolean Geometry)
246 TopoDS_Shape Context;
247 Standard_Boolean OnlyOne =!Geometry;
248 TNaming_Identifier Ident(L,Selection,Context,OnlyOne);
249 if (Ident.IsFeature()) {
250 if (!OnlyOne) return Standard_False;
252 NS = Ident.FeatureArg();
254 // mpv : external condition
255 TDF_LabelMap Forbiden,Valid;
256 TopTools_IndexedMapOfShape MS;
257 TNaming_NamingTool::CurrentShape(Valid,Forbiden,NS,MS);
258 return (MS.Contains(Selection) && MS.Extent() == 1);
261 else if(Ident.Type() == TNaming_GENERATION) {
262 NS = Ident.NamedShapeOfGeneration();
264 TDF_LabelMap Forbiden,Valid;
265 TopTools_IndexedMapOfShape MS;
266 TNaming_NamingTool::CurrentShape(Valid,Forbiden,NS,MS);
267 if(MS.Contains(Selection) && MS.Extent() == 1) {
268 const TopoDS_Shape& aS = Ident.ShapeArg();
269 TopTools_ListOfShape aList;
270 FindGenerated(NS, aS, aList);
272 while(Ident.MoreArgs()) {
273 const TopoDS_Shape& aShape = Ident.ShapeArg();
274 FindGenerated(NS, aShape, aList);
277 const TopoDS_Shape& aC = MS (1);
278 Standard_Boolean isEq(Standard_False);
279 TopTools_ListIteratorOfListOfShape itl(aList);
280 for(;itl.More();itl.Next()) {
281 if(itl.Value() == aC)
282 isEq = Standard_True;
284 isEq = Standard_False;
291 return Standard_False;
293 return Standard_False;
296 //=======================================================================
297 //function : TNaming_Selector
299 //=======================================================================
301 TNaming_Selector::TNaming_Selector (const TDF_Label& L)
306 //=======================================================================
309 //=======================================================================
310 Standard_Boolean TNaming_Selector::Select (const TopoDS_Shape& Selection,
311 const TopoDS_Shape& Context,
312 const Standard_Boolean Geometry,
313 const Standard_Boolean KeepOrientation) const
315 myLabel.ForgetAllAttributes();
316 Handle(TNaming_NamedShape)NS;
317 Standard_Boolean aKeepOrientation((Selection.ShapeType() == TopAbs_VERTEX) ? Standard_False : KeepOrientation);
318 if(Selection.ShapeType() == TopAbs_COMPOUND) {
319 Standard_Boolean isVertex(Standard_True);
320 TopoDS_Iterator it(Selection);
321 for(;it.More();it.Next())
322 if(it.Value().ShapeType() != TopAbs_VERTEX) {
323 isVertex = Standard_False;
326 if(isVertex) aKeepOrientation = Standard_False;
329 // for debug opposite orientation
330 TopoDS_Shape selection;
331 Standard_Boolean found(Standard_False);
332 TopExp_Explorer exp(Context,TopAbs_EDGE);
333 for(;exp.More();exp.Next()) {
334 TopoDS_Shape E = exp.Current();
335 if(E.IsSame(Selection) && E.Orientation() != Selection.Orientation()) {
337 found = Standard_True;
338 std::cout <<" FOUND: Entity orientation = " << selection.Orientation() <<std::endl;
342 selection = Selection;
345 #ifdef OCCT_DEBUG_SEL
346 std::cout << "SELECTION ORIENTATION = " << Selection.Orientation() <<", TShape = " << Selection.TShape() <<std::endl;
347 //std::cout << "SELECTION ORIENTATION = " << selection.Orientation() <<", TShape = " << selection.TShape() <<std::endl;
348 PrintEntry(myLabel, 0);
349 TNaming::Print(myLabel, std::cout);
352 if(aKeepOrientation) {
353 #ifdef ORIENTATION_DSOPT
354 const Standard_Boolean aBNproblem = IsSpecificCase(myLabel, Context) || IsSpecificCase2(myLabel, Selection);
356 NS = TNaming_Naming::Name (myLabel,Selection,Context,Geometry,aKeepOrientation,aBNproblem);
358 NS = TNaming_Naming::Name (myLabel,Selection,Context,Geometry,aKeepOrientation);
362 if (!IsIdentified (myLabel,Selection,NS,Geometry)) {
363 NS = TNaming_Naming::Name (myLabel,Selection,Context,Geometry,aKeepOrientation);
365 if (NS.IsNull()) return Standard_False;
367 // namedshape with SELECTED Evolution
369 TNaming_Builder B (myLabel);
370 // mpv: if oldShape for selection is some shape from used map of shapes,
371 // then naming structure becomes more complex, can be cycles
372 const TopoDS_Shape& aSelection = TNaming_Tool::CurrentShape(NS); //szy
373 #ifdef OCCT_DEBUG_CHECK_TYPE
374 if(!Selection.IsSame(aSelection) && Selection.ShapeType() != TopAbs_COMPOUND) {
375 TCollection_AsciiString entry;
376 TDF_Tool::Entry(NS->Label(), entry);
377 std::cout << "Selection is Not Same (NSLabel = " <<entry<<"): TShape1 = " <<
378 Selection.TShape()->This() << " TShape2 = " <<aSelection.TShape()->This() <<std::endl;
381 if(aSelection.ShapeType() == TopAbs_COMPOUND && aSelection.ShapeType() != Selection.ShapeType())
382 B.Select(aSelection,aSelection); // type migration
384 B.Select(Selection,Selection);
386 // naming with IDENTITY NameType
388 Handle(TNaming_Naming) N = new TNaming_Naming ();
389 N->ChangeName().Type(TNaming_IDENTITY);
390 N->ChangeName().Append(NS);
391 N->ChangeName().Orientation(Selection.Orientation());
392 // inserted by vro 06.09.00:
393 N->ChangeName().ShapeType(Selection.ShapeType());
395 myLabel.AddAttribute(N);
396 return Standard_True;
399 //=======================================================================
402 //=======================================================================
403 Standard_Boolean TNaming_Selector::Select (const TopoDS_Shape& Selection,
404 const Standard_Boolean Geometry,
405 const Standard_Boolean KeepOrientation) const
407 // we give a Null shape. How to guess what is the good context ?
408 TopoDS_Shape Context;
409 // return Select (Selection,Context,Geometry);
411 return Select (Selection,Selection,Geometry, KeepOrientation);
415 //=======================================================================
418 //=======================================================================
419 Standard_Boolean TNaming_Selector::Solve (TDF_LabelMap& Valid) const
421 Handle(TNaming_Naming) name;
422 #ifdef OCCT_DEBUG_SEL
423 std::cout <<"TNaming_Selector::Solve==> ";
424 PrintEntry(myLabel,0);
426 if (myLabel.FindAttribute(TNaming_Naming::GetID(),name)) {
427 return name->Solve(Valid);
429 return Standard_False;
432 //=======================================================================
433 //function : Arguments
435 //=======================================================================
436 void TNaming_Selector::Arguments (TDF_AttributeMap& args) const
438 TDF_Tool::OutReferences(myLabel,args);
441 //=======================================================================
442 //function : TNaming_Selector
444 //=======================================================================
446 Handle(TNaming_NamedShape) TNaming_Selector::NamedShape() const
448 Handle(TNaming_NamedShape) NS;
449 myLabel.FindAttribute(TNaming_NamedShape::GetID(),NS);