1 // Created on: 1999-09-30
2 // Created by: Denis PASCAL
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
23 #include <TNaming_Selector.ixx>
24 #include <TNaming.hxx>
25 #include <TNaming_Naming.hxx>
26 #include <TNaming_Builder.hxx>
27 #include <TNaming_Identifier.hxx>
28 #include <TNaming_NameType.hxx>
29 #include <TDF_ChildIterator.hxx>
30 #include <TDF_Tool.hxx>
31 #include <TDF_IDFilter.hxx>
32 #include <TNaming_NamingTool.hxx>
33 #include <TNaming_NewShapeIterator.hxx>
35 #include <TopTools_MapOfShape.hxx>
36 #include <TopTools_MapIteratorOfMapOfShape.hxx>
37 #include <TopTools_ListIteratorOfListOfShape.hxx>
38 #include <TopoDS_Iterator.hxx>
43 //#define MDTV_DEB_SEL
45 //#define MDTV_DEB_BNP
46 #include <TopExp_Explorer.hxx>
47 #include <TCollection_AsciiString.hxx>
48 #include <TNaming_Tool.hxx>
49 #include <BRep_Tool.hxx>
51 #include <TNaming_UsedShapes.hxx>
52 void PrintEntry(const TDF_Label& label, const Standard_Boolean allLevels)
54 TCollection_AsciiString entry;
55 TDF_Tool::Entry(label, entry);
56 cout << "LabelEntry = "<< entry << endl;
58 TDF_ChildIterator it (label, allLevels);
59 for (; it.More(); it.Next()) {
60 TDF_Tool::Entry(it.Value(), entry);
61 cout << "ChildLabelEntry = "<< entry << endl;
65 #include <BRepTools.hxx>
66 static void Write(const TopoDS_Shape& shape,
67 const Standard_CString filename)
70 if(strlen(filename) > 255) return;
72 strcpy_s (buf, filename);
74 strcpy (buf, filename);
84 cout << "File " << buf << " was not created: rdstate = " << save.rdstate() << endl;
85 save << "DBRep_DrawableShape" << endl << endl;
86 if(!shape.IsNull()) BRepTools::Write(shape, save);
91 #define ORIENTATION_DSOPT
92 #ifdef ORIENTATION_DSOPT
93 #include <TopTools_MapOfOrientedShape.hxx>
94 #include <TopTools_MapIteratorOfMapOfOrientedShape.hxx>
95 #include <TDF_ChildIDIterator.hxx>
96 #include <TNaming_Tool.hxx>
97 #include <TNaming_Iterator.hxx>
98 #include <TNaming_OldShapeIterator.hxx>
99 //==========================================================================================
100 inline static void MapOfOrientedShapes(const TopoDS_Shape& S, TopTools_MapOfOrientedShape& M)
103 TopoDS_Iterator It(S,Standard_True,Standard_True);
105 MapOfOrientedShapes(It.Value(),M);
109 //=======================================================================
110 static void BuildAtomicMap(const TopoDS_Shape& S, TopTools_MapOfOrientedShape& M)
112 if(S.ShapeType() > TopAbs_COMPSOLID) return;
113 TopoDS_Iterator it(S);
114 for(;it.More();it.Next()) {
115 if(it.Value().ShapeType() > TopAbs_COMPSOLID)
118 BuildAtomicMap(it.Value(), M);
122 //==========================================================================================
123 static const Handle(TNaming_NamedShape) FindPrevNDS(const Handle(TNaming_NamedShape)& CNS)
125 Handle(TNaming_NamedShape) aNS;
126 TNaming_Iterator it(CNS);
128 if(!it.OldShape().IsNull()) {
129 aNS = TNaming_Tool::NamedShape(it.OldShape(), CNS->Label());
136 //==========================================================================================
137 // Purpose: checks correspondens between orientation of sub-shapes of Context and orientation
138 // of sub-shapes registered in DF and put under result label
139 //==========================================================================================
140 static Standard_Boolean IsSpecificCase(const TDF_Label& F, const TopoDS_Shape& Context)
142 Standard_Boolean isFound(Standard_False);
143 TopTools_MapOfOrientedShape shapesOfContext;
144 MapOfOrientedShapes(Context,shapesOfContext);
145 Handle(TNaming_NamedShape) CNS = TNaming_Tool::NamedShape(Context, F);
147 PrintEntry (CNS->Label(),0);
150 TNaming_ListOfNamedShape aLNS;
151 TDF_ChildIDIterator cit(CNS->Label(), TNaming_NamedShape::GetID(), Standard_False);
153 // Naming data structure is empty - no sub-shapes under resulting shape
154 const Handle(TNaming_NamedShape) aNS = FindPrevNDS(CNS); //look to old shape data structure if exist
157 PrintEntry (aNS->Label(),0);
159 cit.Initialize(aNS->Label(), TNaming_NamedShape::GetID(), Standard_False);
161 return Standard_True;
164 for(;cit.More();cit.Next()) {
165 const Handle(TNaming_NamedShape)& NS = Handle(TNaming_NamedShape)::DownCast(cit.Value());
167 TopoDS_Shape aS = TNaming_Tool::CurrentShape(NS);
168 if(aS.IsNull()) continue;
170 PrintEntry(NS->Label(), 0);
171 cout <<"ShapeType =" << aS.ShapeType() <<endl;
172 Write (aS, "BNProblem.brep");
174 if(aS.ShapeType() != TopAbs_COMPOUND) {//single shape at the child label
175 if(!shapesOfContext.Contains(aS)) {
176 isFound = Standard_True;
181 TopTools_MapOfOrientedShape M;
182 BuildAtomicMap(aS, M);
183 TopTools_MapIteratorOfMapOfOrientedShape it(M);
184 for(;it.More();it.Next()) {
185 if(!shapesOfContext.Contains(it.Key())) {
187 cout <<"BNProblem: ShapeType in AtomicMap = " << it.Key().ShapeType() << " TShape = " <<it.Key().TShape() <<" OR = " <<it.Key().Orientation() <<endl;
188 Write (it.Key(), "BNProblem_AtomicMap_Item.brep");
189 TopTools_MapIteratorOfMapOfOrientedShape itC(shapesOfContext);
190 for(;itC.More(); itC.Next())
191 cout <<" ShapeType = " << itC.Key().ShapeType() << " TShape = " << itC.Key().TShape() << " OR = " << itC.Key().Orientation() << endl;
194 isFound = Standard_True;
206 //==========================================================================================
207 static Standard_Boolean IsSpecificCase2(const TDF_Label& F, const TopoDS_Shape& Selection)
209 Standard_Boolean isTheCase(Standard_False);
210 if(Selection.ShapeType() == TopAbs_EDGE) {
211 Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(Selection, F);
212 if(!aNS.IsNull()) { //presented in DF
214 PrintEntry (aNS->Label(),0);
216 const TopoDS_Shape& aS = TNaming_Tool::CurrentShape(aNS);
217 if(!aS.IsNull() && aS.ShapeType() == Selection.ShapeType()) {
218 if(Selection.Orientation() != aS.Orientation()) {
219 isTheCase = Standard_True;
227 //=======================================================================
228 //function : FindGenerated
229 //purpose : Finds all generated from the <S>
230 //=======================================================================
232 static void FindGenerated(const Handle(TNaming_NamedShape)& NS, const TopoDS_Shape& S,
233 TopTools_ListOfShape& theList)
236 const TDF_Label& LabNS = NS->Label();
237 for (TNaming_NewShapeIterator it (S, LabNS); it.More(); it.Next()) {
238 if (it.Label() == LabNS) {
239 theList.Append(it.Shape());
243 //=======================================================================
244 //function : IsIdentified
246 //=======================================================================
247 Standard_Boolean TNaming_Selector::IsIdentified (const TDF_Label& L,
248 const TopoDS_Shape& Selection,
249 Handle(TNaming_NamedShape)& NS,
250 const Standard_Boolean Geometry)
252 TopoDS_Shape Context;
253 Standard_Boolean OnlyOne =!Geometry;
254 TNaming_Identifier Ident(L,Selection,Context,OnlyOne);
255 if (Ident.IsFeature()) {
256 if (!OnlyOne) return Standard_False;
258 NS = Ident.FeatureArg();
261 // mpv : external condition
262 TDF_LabelMap Forbiden,Valid;
263 TopTools_MapOfShape MS;
264 TNaming_NamingTool::CurrentShape(Valid,Forbiden,NS,MS);
265 return (MS.Contains(Selection) && MS.Extent() == 1);
267 return Standard_True;
271 else if(Ident.Type() == TNaming_GENERATION) {
272 NS = Ident.NamedShapeOfGeneration();
274 TDF_LabelMap Forbiden,Valid;
275 TopTools_MapOfShape MS;
276 TNaming_NamingTool::CurrentShape(Valid,Forbiden,NS,MS);
277 if(MS.Contains(Selection) && MS.Extent() == 1) {
278 const TopoDS_Shape& aS = Ident.ShapeArg();
279 TopTools_ListOfShape aList;
280 FindGenerated(NS, aS, aList);
282 while(Ident.MoreArgs()) {
283 const TopoDS_Shape& aS = Ident.ShapeArg();
284 FindGenerated(NS, aS, aList);
287 TopTools_MapIteratorOfMapOfShape itm(MS);
288 const TopoDS_Shape& aC = itm.Key();
289 Standard_Boolean isEq(Standard_False);
290 TopTools_ListIteratorOfListOfShape itl(aList);
291 for(;itl.More();itl.Next()) {
292 if(itl.Value() == aC)
293 isEq = Standard_True;
295 isEq = Standard_False;
302 return Standard_False;
304 return Standard_False;
307 //=======================================================================
308 //function : TNaming_Selector
310 //=======================================================================
312 TNaming_Selector::TNaming_Selector (const TDF_Label& L)
317 //=======================================================================
320 //=======================================================================
321 Standard_Boolean TNaming_Selector::Select (const TopoDS_Shape& Selection,
322 const TopoDS_Shape& Context,
323 const Standard_Boolean Geometry,
324 const Standard_Boolean KeepOrientation) const
326 myLabel.ForgetAllAttributes();
327 Handle(TNaming_NamedShape)NS;
328 Standard_Boolean aKeepOrientation((Selection.ShapeType() == TopAbs_VERTEX) ? Standard_False : KeepOrientation);
329 if(Selection.ShapeType() == TopAbs_COMPOUND) {
330 Standard_Boolean isVertex(Standard_True);
331 TopoDS_Iterator it(Selection);
332 for(;it.More();it.Next())
333 if(it.Value().ShapeType() != TopAbs_VERTEX) {
334 isVertex = Standard_False;
337 if(isVertex) aKeepOrientation = Standard_False;
340 // for debug opposite orientation
341 TopoDS_Shape selection;
342 Standard_Boolean found(Standard_False);
343 TopExp_Explorer exp(Context,TopAbs_EDGE);
344 for(;exp.More();exp.Next()) {
345 TopoDS_Shape E = exp.Current();
346 if(E.IsSame(Selection) && E.Orientation() != Selection.Orientation()) {
348 found = Standard_True;
349 cout <<" FOUND: Entity orientation = " << selection.Orientation() <<endl;
353 selection = Selection;
357 cout << "SELECTION ORIENTATION = " << Selection.Orientation() <<", TShape = " << Selection.TShape() <<endl;
358 //cout << "SELECTION ORIENTATION = " << selection.Orientation() <<", TShape = " << selection.TShape() <<endl;
359 PrintEntry(myLabel, 0);
360 TNaming::Print(myLabel, cout);
363 if(aKeepOrientation) {
364 #ifdef ORIENTATION_DSOPT
365 const Standard_Boolean aBNproblem = IsSpecificCase(myLabel, Context) || IsSpecificCase2(myLabel, Selection);
367 NS = TNaming_Naming::Name (myLabel,Selection,Context,Geometry,aKeepOrientation,aBNproblem);
369 NS = TNaming_Naming::Name (myLabel,Selection,Context,Geometry,aKeepOrientation);
373 if (!IsIdentified (myLabel,Selection,NS,Geometry)) {
374 NS = TNaming_Naming::Name (myLabel,Selection,Context,Geometry,aKeepOrientation);
376 if (NS.IsNull()) return Standard_False;
378 // namedshape with SELECTED Evolution
380 TNaming_Builder B (myLabel);
382 // mpv: if oldShape for selection is some shape from used map of shapes,
383 // then naming structure becomes more complex, can be cycles
384 const TopoDS_Shape& aSelection = TNaming_Tool::CurrentShape(NS); //szy
385 #ifdef MDTV_DEB_CHECK_TYPE
386 if(!Selection.IsSame(aSelection) && Selection.ShapeType() != TopAbs_COMPOUND) {
387 TCollection_AsciiString entry;
388 TDF_Tool::Entry(NS->Label(), entry);
389 cout << "Selection is Not Same (NSLabel = " <<entry<<"): " << "TShape1 = " <<
390 Selection.TShape()->This() << " TShape2 = " <<aSelection.TShape()->This() <<endl;
393 if(aSelection.ShapeType() == TopAbs_COMPOUND && aSelection.ShapeType() != Selection.ShapeType())
394 B.Select(aSelection,aSelection); // type migration
396 B.Select(Selection,Selection);
398 B.Select(Selection,Context);
401 // naming with IDENTITY NameType
403 Handle(TNaming_Naming) N = new TNaming_Naming ();
404 N->ChangeName().Type(TNaming_IDENTITY);
405 N->ChangeName().Append(NS);
406 N->ChangeName().Orientation(Selection.Orientation());
408 // inserted by vro 06.09.00:
409 N->ChangeName().ShapeType(Selection.ShapeType());
412 myLabel.AddAttribute(N);
413 return Standard_True;
416 //=======================================================================
419 //=======================================================================
420 Standard_Boolean TNaming_Selector::Select (const TopoDS_Shape& Selection,
421 const Standard_Boolean Geometry,
422 const Standard_Boolean KeepOrientation) const
424 // we give a Null shape. How to guess what is the good context ?
425 TopoDS_Shape Context;
426 // return Select (Selection,Context,Geometry);
428 return Select (Selection,Selection,Geometry, KeepOrientation);
432 //=======================================================================
435 //=======================================================================
436 Standard_Boolean TNaming_Selector::Solve (TDF_LabelMap& Valid) const
438 Handle(TNaming_Naming) name;
440 cout <<"TNaming_Selector::Solve==> ";
441 PrintEntry(myLabel,0);
443 if (myLabel.FindAttribute(TNaming_Naming::GetID(),name)) {
444 return name->Solve(Valid);
446 return Standard_False;
449 //=======================================================================
450 //function : Arguments
452 //=======================================================================
453 void TNaming_Selector::Arguments (TDF_AttributeMap& args) const
455 TDF_Tool::OutReferences(myLabel,args);
458 //=======================================================================
459 //function : TNaming_Selector
461 //=======================================================================
463 Handle(TNaming_NamedShape) TNaming_Selector::NamedShape() const
465 Handle(TNaming_NamedShape) NS;
466 myLabel.FindAttribute(TNaming_NamedShape::GetID(),NS);