1 // Created on: 1997-01-09
2 // Created by: VAUTHIER Jean-Claude & Fricaud Yves
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16 
17 
18 #include <BRep_Tool.hxx>
19 #include <BRepAlgoAPI_BooleanOperation.hxx>
20 #include <BRepBuilderAPI_MakeShape.hxx>
21 #include <BRepLib_FindSurface.hxx>
22 #include <BRepTools.hxx>
23 #include <DDF.hxx>
24 #include <DDF_Data.hxx>
25 #include <DNaming.hxx>
26 #include <Draw.hxx>
27 #include <Geom_Curve.hxx>
28 #include <Geom_Line.hxx>
29 #include <Geom_Plane.hxx>
30 #include <Geom_RectangularTrimmedSurface.hxx>
31 #include <Geom_Surface.hxx>
32 #include <gp_Ax1.hxx>
33 #include <gp_Pln.hxx>
34 #include <gp_Vec.hxx>
35 #include <ModelDefinitions.hxx>
36 #include <TCollection_AsciiString.hxx>
37 #include <TColStd_HArray1OfInteger.hxx>
38 #include <TColStd_ListIteratorOfListOfInteger.hxx>
39 #include <TColStd_ListOfInteger.hxx>
40 #include <TDataStd_Integer.hxx>
41 #include <TDataStd_Name.hxx>
42 #include <TDataStd_Real.hxx>
43 #include <TDataStd_TreeNode.hxx>
44 #include <TDataStd_UAttribute.hxx>
45 #include <TDF_ChildIterator.hxx>
46 #include <TDF_Data.hxx>
47 #include <TDF_Label.hxx>
48 #include <TDF_LabelList.hxx>
49 #include <TDF_LabelMap.hxx>
50 #include <TDF_Reference.hxx>
51 #include <TDF_TagSource.hxx>
52 #include <TDF_Tool.hxx>
53 #include <TFunction_Function.hxx>
54 #include <TNaming_Builder.hxx>
55 #include <TNaming_Iterator.hxx>
56 #include <TNaming_NamedShape.hxx>
57 #include <TNaming_Tool.hxx>
58 #include <TopExp.hxx>
59 #include <TopExp_Explorer.hxx>
60 #include <TopoDS.hxx>
61 #include <TopoDS_Edge.hxx>
62 #include <TopoDS_Face.hxx>
63 #include <TopoDS_Shape.hxx>
64 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
65 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
66 #include <TopTools_DataMapOfShapeListOfShape.hxx>
67 #include <TopTools_DataMapOfShapeShape.hxx>
68 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
69 #include <TopTools_IndexedMapOfShape.hxx>
70 #include <TopTools_ListIteratorOfListOfShape.hxx>
71 #include <TopTools_ListOfShape.hxx>
72 #include <TopTools_MapIteratorOfMapOfShape.hxx>
73 #include <TopTools_MapOfShape.hxx>
74 
75 //=======================================================================
76 //function : DNaming_DFandUS
77 //purpose  :
78 //=======================================================================
79 // Standard_Boolean DNaming_DFandUS(char* a,
80 // 				 Handle(TDF_Data)&           ND,
81 // 				 Handle(TNaming_UsedShapes)& US)
82 // {
83 //   Handle(DDF_Data) DND = Handle(DDF_Data)::DownCast (Draw::Get(a));
84 //   if (DND.IsNull ()) return 0;
85 //   ND = DND->DataFramework ();
86 //   ND->Root().FindAttribute(TNaming_UsedShapes::GetID(),US);
87 //   return 1;
88 // }
89 //=======================================================================
90 //function : GetShape
91 //purpose  :
92 //=======================================================================
GetShape(const Standard_CString LabelName,const Handle (TDF_Data)& DF,TopTools_ListOfShape & L)93 void DNaming::GetShape (const Standard_CString      LabelName,
94 			const Handle(TDF_Data)&     DF,
95 			TopTools_ListOfShape&       L)
96 {
97   L.Clear();
98   TDF_Label Label;
99   Standard_Boolean Found = DDF::AddLabel (DF, LabelName, Label);
100   if (Found) {
101     TNaming_Iterator it (Label, DF->Transaction ());
102     for (; it.More(); it.Next()) {
103       L.Append(it.NewShape());
104     }
105   }
106 }
107 
108 //=======================================================================
109 //function : BuildMap
110 //purpose  :
111 //=======================================================================
112 
DNaming_BuildMap(TDF_LabelMap & Updated,const TDF_Label & Lab)113 void DNaming_BuildMap(TDF_LabelMap& Updated,
114 		      const TDF_Label& Lab)
115 {
116   TDF_ChildIterator it(Lab);
117   for (; it.More(); it.Next()) {
118     Updated.Add(it.Value());
119     DNaming_BuildMap(Updated,it.Value());
120   }
121 }
122 
123 //=======================================================================
124 //function : CurrentShape
125 //purpose  :
126 //=======================================================================
127 
CurrentShape(const Standard_CString LabelName,const Handle (TDF_Data)& DF)128 TopoDS_Shape DNaming::CurrentShape (const Standard_CString  LabelName,
129 				    const Handle(TDF_Data)& DF)
130 {
131   TopoDS_Shape S;
132   TDF_Label Label;
133   Standard_Boolean Found =  DDF::AddLabel (DF, LabelName, Label);
134   if (!Found) {
135 #ifdef OCCT_DEBUG
136     std::cout <<"no labels"<<std::endl;
137 #endif
138     return S;
139   }
140   if (Found) {
141     Handle(TNaming_NamedShape)  NS;
142     Label.FindAttribute(TNaming_NamedShape::GetID(),NS);
143     S =  TNaming_Tool::CurrentShape(NS);
144     if (S.IsNull())
145 #ifdef OCCT_DEBUG
146       std::cout <<"current shape from "<< LabelName <<" is deleted"<<std::endl;
147 #endif
148     return S;
149   }
150   return S;
151 }
152 
153 
154 //=======================================================================
155 //function : GetEntry
156 //purpose  :
157 //=======================================================================
158 
GetEntry(const TopoDS_Shape & Shape,const Handle (TDF_Data)& DF,Standard_Integer & theStatus)159 TCollection_AsciiString DNaming::GetEntry (const TopoDS_Shape&         Shape,
160 					   const Handle(TDF_Data)&     DF,
161 					   Standard_Integer&           theStatus)
162 {
163   theStatus = 0;
164   //Handle(TNaming_UsedShapes) US;
165   //DF->Root().FindAttribute(TNaming_UsedShapes::GetID(),US);
166 
167   if (!TNaming_Tool::HasLabel (DF->Root(), Shape)) {
168     return TCollection_AsciiString ();
169   }
170   Standard_Integer Transdef;
171   TDF_Label Lab = TNaming_Tool::Label (DF->Root(), Shape,Transdef);
172   TCollection_AsciiString entry; TDF_Tool::Entry(Lab,entry);
173   //Update theStatus;
174   TNaming_Iterator it(Lab,DF->Transaction());
175   for (; it.More(); it.Next()) {
176     theStatus++;
177     if (theStatus == 2) break;
178   }
179   return entry;
180 }
181 
182 //=======================================================================
183 //function : AllCommands
184 //purpose  :
185 //=======================================================================
186 
AllCommands(Draw_Interpretor & theCommands)187 void  DNaming::AllCommands(Draw_Interpretor& theCommands)
188 {
189   static Standard_Boolean done = Standard_False;
190   if (done) return;
191   done = Standard_True;
192 
193   DNaming::BasicCommands     (theCommands);
194   DNaming::ToolsCommands     (theCommands);
195   DNaming::SelectionCommands (theCommands);
196   DNaming::ModelingCommands  (theCommands);
197   // define the TCL variable Draw_NamingData
198   const char* com = "set Draw_NamingData 1";
199   theCommands.Eval(com);
200 }
201 
202 //=======================================================================
203 //=======================================================================
204 //function : LoadC0Vertices
205 //purpose  : Method for internal use. It is used by Load() method.
206 //=======================================================================
207 
LoadC0Vertices(const TopoDS_Shape & S,const Handle (TDF_TagSource)& Tagger)208 static void LoadC0Vertices(const TopoDS_Shape& S,
209 			   const Handle(TDF_TagSource)& Tagger)
210 {
211   TopTools_DataMapOfShapeListOfShape vertexNaborFaces;
212   TopTools_ListOfShape empty;
213   TopExp_Explorer explF(S, TopAbs_FACE);
214   for (; explF.More(); explF.Next()) {
215     const TopoDS_Shape& aFace = explF.Current();
216     TopExp_Explorer explV(aFace, TopAbs_VERTEX);
217     for (; explV.More(); explV.Next()) {
218       const TopoDS_Shape& aVertex = explV.Current();
219       if (!vertexNaborFaces.IsBound(aVertex)) vertexNaborFaces.Bind(aVertex, empty);
220       Standard_Boolean faceIsNew = Standard_True;
221       TopTools_ListIteratorOfListOfShape itrF(vertexNaborFaces.Find(aVertex));
222       for (; itrF.More(); itrF.Next()) {
223 	if (itrF.Value().IsSame(aFace)) {
224 	  faceIsNew = Standard_False;
225 	  break;
226 	}
227       }
228       if (faceIsNew) {
229 	vertexNaborFaces.ChangeFind(aVertex).Append(aFace);
230       }
231     }
232   }
233 
234   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(vertexNaborFaces);
235   for (; itr.More(); itr.Next()) {
236     const TopTools_ListOfShape& naborFaces = itr.Value();
237     if (naborFaces.Extent() < 3) {
238       TNaming_Builder bC0Vertex(Tagger->NewChild());
239       bC0Vertex.Generated(itr.Key());
240     }
241   }
242 }
243 
244 //=======================================================================
245 //function : LoadC0Edges
246 //purpose  : Method for internal use. It is used by Load() method.
247 //=======================================================================
248 
LoadC0Edges(const TopoDS_Shape & S,const Handle (TDF_TagSource)& Tagger)249 static void LoadC0Edges(const TopoDS_Shape& S,
250 			const Handle(TDF_TagSource)& Tagger)
251 {
252   TopTools_DataMapOfShapeListOfShape edgeNaborFaces;
253   TopTools_ListOfShape empty;
254   TopExp_Explorer explF(S, TopAbs_FACE);
255   for (; explF.More(); explF.Next()) {
256     const TopoDS_Shape& aFace = explF.Current();
257     TopExp_Explorer explV(aFace, TopAbs_EDGE);
258     for (; explV.More(); explV.Next()) {
259       const TopoDS_Shape& anEdge = explV.Current();
260       if (!edgeNaborFaces.IsBound(anEdge)) edgeNaborFaces.Bind(anEdge, empty);
261       Standard_Boolean faceIsNew = Standard_True;
262       TopTools_ListIteratorOfListOfShape itrF(edgeNaborFaces.Find(anEdge));
263       for (; itrF.More(); itrF.Next()) {
264 	if (itrF.Value().IsSame(aFace)) {
265 	  faceIsNew = Standard_False;
266 	  break;
267 	}
268       }
269       if (faceIsNew) {
270 	edgeNaborFaces.ChangeFind(anEdge).Append(aFace);
271       }
272     }
273   }
274 
275   TopTools_MapOfShape anEdgesToDelete;
276   TopExp_Explorer anEx(S,TopAbs_EDGE); // mpv: new explorer iterator because we need keep edges order
277   for(;anEx.More();anEx.Next()) {
278     Standard_Boolean aC0 = Standard_False;
279     TopoDS_Shape anEdge1 = anEx.Current();
280     if (edgeNaborFaces.IsBound(anEdge1)) {
281       const TopTools_ListOfShape& aList1 = edgeNaborFaces.Find(anEdge1);
282       if (aList1.Extent()<2) continue; // mpv (06.09.2002): these edges already was loaded
283       TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(edgeNaborFaces);
284       for (; itr.More(); itr.Next()) {
285 	TopoDS_Shape anEdge2 = itr.Key();
286 	if(anEdgesToDelete.Contains(anEdge2)) continue;
287 	if (anEdge1.IsSame(anEdge2)) continue;
288 	const TopTools_ListOfShape& aList2 = itr.Value();
289 	// compare lists of the neighbour faces of edge1 and edge2
290 	if (aList1.Extent() == aList2.Extent()) {
291 	  Standard_Integer aMatches = 0;
292 	  for(TopTools_ListIteratorOfListOfShape aLIter1(aList1);aLIter1.More();aLIter1.Next())
293 	    for(TopTools_ListIteratorOfListOfShape aLIter2(aList2);aLIter2.More();aLIter2.Next())
294 	      if (aLIter1.Value().IsSame(aLIter2.Value())) aMatches++;
295 	  if (aMatches == aList1.Extent()) {
296 	    aC0=Standard_True;
297 	    TNaming_Builder bC0Edge(Tagger->NewChild());
298 	    bC0Edge.Generated(anEdge2);
299 	    //edgeNaborFaces.UnBind(anEdge2);
300 	    anEdgesToDelete.Add(anEdge2);
301 	  }
302 	}
303       }
304       //VUN (10/2/2005) avoid UnBind during iterating -^
305       TopTools_MapIteratorOfMapOfShape itDelete(anEdgesToDelete);
306       for(;itDelete.More();itDelete.Next()) {
307 	edgeNaborFaces.UnBind(itDelete.Key());
308       }
309       edgeNaborFaces.UnBind(anEdge1);
310     }
311     if (aC0) {
312       TNaming_Builder bC0Edge(Tagger->NewChild());
313       bC0Edge.Generated(anEdge1);
314     }
315   }
316 }
317 //
318 //=======================================================================
319 //function : GetDangleShapes
320 //purpose  : Returns dangle sub shapes Generator - Dangle.
321 //=======================================================================
322 
GetDangleShapes(const TopoDS_Shape & ShapeIn,const TopAbs_ShapeEnum GeneratedFrom,TopTools_DataMapOfShapeShape & Dangles)323 static Standard_Boolean GetDangleShapes(const TopoDS_Shape& ShapeIn,
324 				 const TopAbs_ShapeEnum GeneratedFrom,
325 				 TopTools_DataMapOfShapeShape& Dangles)
326 {
327   Dangles.Clear();
328   TopTools_IndexedDataMapOfShapeListOfShape subShapeAndAncestors;
329   TopAbs_ShapeEnum GeneratedTo;
330   if (GeneratedFrom == TopAbs_FACE) GeneratedTo = TopAbs_EDGE;
331   else if (GeneratedFrom == TopAbs_EDGE) GeneratedTo = TopAbs_VERTEX;
332   else return Standard_False;
333   TopExp::MapShapesAndAncestors(ShapeIn, GeneratedTo, GeneratedFrom, subShapeAndAncestors);
334   for (Standard_Integer i = 1; i <= subShapeAndAncestors.Extent(); i++) {
335     const TopoDS_Shape& mayBeDangle = subShapeAndAncestors.FindKey(i);
336     const TopTools_ListOfShape& ancestors = subShapeAndAncestors.FindFromIndex(i);
337     if (ancestors.Extent() == 1) Dangles.Bind(ancestors.First(), mayBeDangle);
338   }
339   return !Dangles.IsEmpty();
340 }
341 
342 //=======================================================================
343 //function : LoadGeneratedDangleShapes
344 //purpose  :
345 //=======================================================================
346 
LoadGeneratedDangleShapes(const TopoDS_Shape & ShapeIn,const TopAbs_ShapeEnum GeneratedFrom,TNaming_Builder & Builder)347 static void LoadGeneratedDangleShapes(const TopoDS_Shape&          ShapeIn,
348 				      const TopAbs_ShapeEnum       GeneratedFrom,
349 				      TNaming_Builder&             Builder)
350 {
351   TopTools_DataMapOfShapeShape dangles;
352   if (!GetDangleShapes(ShapeIn, GeneratedFrom, dangles)) return;
353   TopTools_DataMapIteratorOfDataMapOfShapeShape itr(dangles);
354   for (; itr.More(); itr.Next()) Builder.Generated(itr.Key(), itr.Value());
355 }
356 
357 //=======================================================================
358 //function : LoadNextLevels
359 //purpose  : Method for internal use. Is used by LoadFirstLevel()
360 //=======================================================================
361 
LoadNextLevels(const TopoDS_Shape & S,const Handle (TDF_TagSource)& Tagger)362 static void LoadNextLevels(const TopoDS_Shape& S,
363 			   const Handle(TDF_TagSource)& Tagger)
364 {
365 
366   if (S.ShapeType() == TopAbs_SOLID) {
367     TopExp_Explorer aExp(S, TopAbs_FACE);
368     for (; aExp.More(); aExp.Next()) {
369       TNaming_Builder bFace(Tagger->NewChild());
370       bFace.Generated(aExp.Current());
371     }
372   } else if (S.ShapeType() == TopAbs_SHELL || S.ShapeType() == TopAbs_FACE) {
373     // load faces and all the free edges
374     TopTools_IndexedMapOfShape Faces;
375     TopExp::MapShapes(S, TopAbs_FACE, Faces);
376     if (Faces.Extent() > 1 || (S.ShapeType() == TopAbs_SHELL && Faces.Extent() == 1)) {
377       TopExp_Explorer aExp(S, TopAbs_FACE);
378       for (; aExp.More(); aExp.Next()) {
379 	TNaming_Builder bFace(Tagger->NewChild());
380 	bFace.Generated(aExp.Current());
381       }
382     }
383     TopTools_IndexedDataMapOfShapeListOfShape anEdgeAndNeighbourFaces;
384     TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, anEdgeAndNeighbourFaces);
385     for (Standard_Integer i = 1; i <= anEdgeAndNeighbourFaces.Extent(); i++) {
386       const TopTools_ListOfShape& aLL = anEdgeAndNeighbourFaces.FindFromIndex(i);
387       if (aLL.Extent() < 2) {
388 	TNaming_Builder bFreeEdges(Tagger->NewChild());
389 	bFreeEdges.Generated(anEdgeAndNeighbourFaces.FindKey(i));
390       } else {
391 	TopTools_ListIteratorOfListOfShape anIter(aLL);
392 	const TopoDS_Face& aFace = TopoDS::Face(anIter.Value());
393 	anIter.Next();
394 	if(aFace.IsEqual(anIter.Value())) {
395 	  TNaming_Builder bFreeEdges(Tagger->NewChild());
396 	  bFreeEdges.Generated(anEdgeAndNeighbourFaces.FindKey(i));
397 	}
398       }
399     }
400   } else if (S.ShapeType() == TopAbs_WIRE) {
401     TopTools_IndexedMapOfShape Edges;
402     BRepTools::Map3DEdges(S, Edges);
403     if (Edges.Extent() == 1) {
404       TNaming_Builder bEdge(Tagger->NewChild());
405       bEdge.Generated(Edges.FindKey(1));
406       TopExp_Explorer aExp(S, TopAbs_VERTEX);
407       for (; aExp.More(); aExp.Next()) {
408 	TNaming_Builder bVertex(Tagger->NewChild());
409 	bVertex.Generated(aExp.Current());
410       }
411     } else {
412       TopExp_Explorer aExp(S, TopAbs_EDGE);
413       for (; aExp.More(); aExp.Next()) {
414 	TNaming_Builder bEdge(Tagger->NewChild());
415 	bEdge.Generated(aExp.Current());
416       }
417       // and load generated vertices.
418       TopTools_DataMapOfShapeShape generated;
419       if (GetDangleShapes(S, TopAbs_EDGE, generated)) {
420 	TNaming_Builder bGenVertices(Tagger->NewChild());
421 	LoadGeneratedDangleShapes(S, TopAbs_EDGE, bGenVertices);
422       }
423     }
424   } else if (S.ShapeType() == TopAbs_EDGE) {
425     TopExp_Explorer aExp(S, TopAbs_VERTEX);
426     for (; aExp.More(); aExp.Next()) {
427       TNaming_Builder bVertex(Tagger->NewChild());
428       bVertex.Generated(aExp.Current());
429     }
430   }
431 }
432 
433 //=======================================================================
434 //function : LoadFirstLevel
435 //purpose  : Method for internal use. Is used by Load()
436 //=======================================================================
437 
LoadFirstLevel(const TopoDS_Shape & S,const Handle (TDF_TagSource)& Tagger)438 static void LoadFirstLevel(const TopoDS_Shape& S,
439 			   const Handle(TDF_TagSource)& Tagger)
440 {
441   if (S.ShapeType() == TopAbs_COMPOUND || S.ShapeType() == TopAbs_COMPSOLID) {
442     TopoDS_Iterator itr(S);
443     for (; itr.More(); itr.Next()) {
444       TNaming_Builder bIndependentShapes(Tagger->NewChild());
445       bIndependentShapes.Generated(itr.Value());
446       if (itr.Value().ShapeType() == TopAbs_COMPOUND || itr.Value().ShapeType() == TopAbs_COMPSOLID) {
447 	LoadFirstLevel(itr.Value(), Tagger);
448       } else LoadNextLevels(itr.Value(), Tagger);
449     }
450   } else LoadNextLevels(S, Tagger);
451 }
452 
453 //=======================================================================
454 //function : Load
455 //purpose  : To load an ImportShape
456 //           Use this method for a topological naming of an imported shape
457 //=======================================================================
458 
LoadImportedShape(const TDF_Label & theResultLabel,const TopoDS_Shape & theShape)459 void DNaming::LoadImportedShape(const TDF_Label& theResultLabel,
460 				const TopoDS_Shape& theShape) {
461   theResultLabel.ForgetAllAttributes();
462   TNaming_Builder aBuilder(theResultLabel);
463   aBuilder.Generated(theShape);
464 
465   Handle(TDF_TagSource) aTagger = TDF_TagSource::Set(theResultLabel);
466   if (aTagger.IsNull()) return;
467   aTagger->Set(0);
468 
469   LoadFirstLevel(theShape, aTagger);
470   LoadC0Edges(theShape, aTagger);
471   LoadC0Vertices(theShape, aTagger);
472 }
473 
474 //=======================================================================
475 //function : LoadPrime
476 //purpose  :
477 //=======================================================================
478 
LoadPrime(const TDF_Label & theResultLabel,const TopoDS_Shape & theShape)479 void DNaming::LoadPrime(const TDF_Label& theResultLabel,
480 			const TopoDS_Shape& theShape) {
481 
482   Handle(TDF_TagSource) aTagger = TDF_TagSource::Set(theResultLabel);
483   if (aTagger.IsNull()) return;
484   aTagger->Set(0);
485 
486   LoadFirstLevel(theShape, aTagger);
487   LoadC0Edges(theShape,    aTagger);
488   LoadC0Vertices(theShape, aTagger);
489 }
490 
491 //
492 //=======================================================================
493 //function : Real
494 //purpose  : Gives the access to a real argument
495 //=======================================================================
Handle(TDataStd_Real)496 Handle(TDataStd_Real) DNaming::GetReal(const Handle(TFunction_Function)& theFunction,
497 			      const Standard_Integer thePosition) {
498   Handle(TDataStd_Real) aReal;
499   if (!POSITION(theFunction, thePosition).FindAttribute(TDataStd_Real::GetID(),aReal))
500     aReal = TDataStd_Real::Set(POSITION(theFunction,thePosition),0.0);
501   return aReal;
502 }
503 
504 
505 
506 //=======================================================================
507 //function : Integer
508 //purpose  : Give an access to integer attribute
509 //=======================================================================
Handle(TDataStd_Integer)510 Handle(TDataStd_Integer) DNaming::GetInteger(const Handle(TFunction_Function)& theFunction,
511 				    const Standard_Integer thePosition) {
512   Handle(TDataStd_Integer) anInteger;
513   if (!POSITION(theFunction,thePosition).FindAttribute(TDataStd_Integer::GetID(),anInteger))
514      anInteger = TDataStd_Integer::Set(POSITION(theFunction,thePosition),0);
515   return anInteger;
516 }
517 
518 //=======================================================================
519 //function : String
520 //purpose  : Returns Name attribute
521 //=======================================================================
Handle(TDataStd_Name)522 Handle(TDataStd_Name) DNaming::GetString(const Handle(TFunction_Function)& theFunction,
523 						 const Standard_Integer thePosition) {
524   Handle(TDataStd_Name) aString;
525   if (!POSITION(theFunction,thePosition).FindAttribute(TDataStd_Name::GetID(),aString))
526      aString = TDataStd_Name::Set(POSITION(theFunction,thePosition),"");
527   return aString;
528 }
529 
530 //=======================================================================
531 //function : GetResult
532 //purpose  : Returns a result of a function, which is stored on a second label
533 //=======================================================================
Handle(TNaming_NamedShape)534 Handle(TNaming_NamedShape) DNaming::GetFunctionResult(const Handle(TFunction_Function)& theFunction)
535 {
536   Handle(TNaming_NamedShape) aNShape;
537   theFunction->Label().FindChild(FUNCTION_RESULT_LABEL).FindAttribute(TNaming_NamedShape::GetID(),aNShape);
538   return aNShape;
539 }
540 //=======================================================================
541 //function : Object
542 //purpose  : Returns UAttribute associated with Object
543 //=======================================================================
Handle(TDataStd_UAttribute)544 Handle(TDataStd_UAttribute) DNaming::GetObjectArg(const Handle(TFunction_Function)& theFunction,
545 						 const Standard_Integer thePosition) {
546   Handle(TDataStd_UAttribute) anObject;
547   Handle(TDF_Reference) aReference;
548   if (POSITION(theFunction,thePosition).FindAttribute(TDF_Reference::GetID(), aReference))
549     aReference->Get().FindAttribute(GEOMOBJECT_GUID, anObject);
550   return anObject;
551 }
552 
553 //=======================================================================
554 //function : SetObject
555 //purpose  : Replace the argument by new value.
556 //=======================================================================
SetObjectArg(const Handle (TFunction_Function)& theFunction,const Standard_Integer thePosition,const Handle (TDataStd_UAttribute)& theNewValue)557 void DNaming::SetObjectArg (const Handle(TFunction_Function)& theFunction,
558 			 const Standard_Integer thePosition,
559 			 const Handle(TDataStd_UAttribute)& theNewValue)
560 {
561 
562   if(theNewValue.IsNull()) return;
563   TDF_Reference::Set(POSITION(theFunction, thePosition),theNewValue->Label());
564 
565 }
566 
567 //=======================================================================
568 //function : GetObjectValue
569 //purpose  : Returns NamedShape of the Object
570 //=======================================================================
Handle(TNaming_NamedShape)571 Handle(TNaming_NamedShape) DNaming::GetObjectValue(const Handle(TDataStd_UAttribute)& theObject)
572 {
573   Handle(TNaming_NamedShape) aNS;
574 
575   if(!theObject.IsNull() && theObject->ID() == GEOMOBJECT_GUID) {
576 
577     Handle(TDF_Reference) aReference;
578     if(theObject->FindAttribute(TDF_Reference::GetID(), aReference))
579       aReference->Get().FindAttribute(TNaming_NamedShape::GetID(), aNS);
580   }
581   return aNS;
582 
583 /*
584   Handle(TFunction_Function) aFun;
585   Handle(TDataStd_TreeNode) aNode;
586   objLabel.FindAttribute(TDataStd_TreeNode::GetDefaultTreeID(), aNode);
587   if(aNode.IsNull()) return aFun;
588   if(!aNode->HasFirst()) return aFun;
589   else
590     aNode = aNode->First();
591   while(!aNode.IsNull()) {
592     if(aNode->FindAttribute(TFunction_Function::GetID(), aFun)) {
593       const Standard_GUID& aGUID = aFun->GetDriverGUID();
594       if(aGUID == funGUID) break;
595       else aFun.Nullify();
596     }
597     aNode = aNode->Next();
598   }
599 */
600 
601 }
602 
603 //=======================================================================
604 //function : GetPrevFunction
605 //purpose  : Returns previous function
606 //=======================================================================
Handle(TFunction_Function)607 Handle(TFunction_Function) DNaming::GetPrevFunction(const Handle(TFunction_Function)& theFunction)
608 {
609   Handle(TFunction_Function) aPrevFun;
610   if(!theFunction.IsNull() ) {
611     Handle(TDataStd_TreeNode) aNode;
612     theFunction->FindAttribute(TDataStd_TreeNode::GetDefaultTreeID(), aNode);
613     while(!aNode.IsNull()) {
614       if(!aNode->HasPrevious()) return aPrevFun;
615       else
616 	aNode = aNode->Previous();
617       aNode->FindAttribute(TFunction_Function::GetID(),aPrevFun );
618       if(!aPrevFun.IsNull())
619 	break;
620     }
621   }
622   return aPrevFun;
623 /*
624     while(!aNode.IsNull()) {
625     if(aNode->FindAttribute(TFunction_Function::GetID(), aFun)) {
626       const Standard_GUID& aGUID = aFun->GetDriverGUID();
627       if(aGUID == funGUID) break;
628       else aFun.Nullify();
629     }
630     aNode = aNode->Next();
631   }
632 */
633 
634 }
635 
636 //=======================================================================
637 //function : GetFirstFunction
638 //purpose  : Returns first function
639 //=======================================================================
Handle(TFunction_Function)640 Handle(TFunction_Function) DNaming::GetFirstFunction(const Handle(TDataStd_UAttribute)& theObject)
641 {
642   Handle(TFunction_Function) aFirstFun;
643   if(!theObject.IsNull() ) {
644     Handle(TDataStd_TreeNode) aNode;
645     theObject->FindAttribute(TDataStd_TreeNode::GetDefaultTreeID(), aNode);
646     if(aNode.IsNull()) return aFirstFun;
647     if(!aNode->HasFirst()) return aFirstFun;
648     else
649       aNode = aNode->First();
650 
651     while(!aNode.IsNull()) {
652       aNode->FindAttribute(TFunction_Function::GetID(), aFirstFun );
653       if(!aFirstFun.IsNull())
654 	break;
655       aNode = aNode->Next();
656     }
657   }
658   return aFirstFun;
659 }
660 
661 //=======================================================================
662 //function : GetLastFunction
663 //purpose  : Returns Last function
664 //=======================================================================
Handle(TFunction_Function)665 Handle(TFunction_Function) DNaming::GetLastFunction(const Handle(TDataStd_UAttribute)& theObject)
666 {
667   Handle(TFunction_Function) aLastFun;
668   if(!theObject.IsNull() ) {
669     Handle(TDataStd_TreeNode) aNode;
670     theObject->FindAttribute(TDataStd_TreeNode::GetDefaultTreeID(), aNode);
671     if(aNode.IsNull()) return aLastFun;
672     if(!aNode->HasFirst()) return aLastFun;
673     else
674       aNode = aNode->First();
675 
676     while(!aNode.IsNull()) {
677       if(aNode->IsAttribute(TFunction_Function::GetID()))
678 	aNode->FindAttribute(TFunction_Function::GetID(), aLastFun);
679       aNode = aNode->Next();
680     }
681   }
682   return aLastFun;
683 }
684 
685 //=======================================================================
686 //function : GetObjectFromFunction
687 //purpose  : Returns Object
688 //=======================================================================
Handle(TDataStd_UAttribute)689 Handle(TDataStd_UAttribute) DNaming::GetObjectFromFunction(const Handle(TFunction_Function)& theFunction)
690 {
691   Handle(TDataStd_UAttribute) anObject;
692   if(!theFunction.IsNull() ) {
693     Handle(TDataStd_TreeNode) aNode;
694     theFunction->FindAttribute(TDataStd_TreeNode::GetDefaultTreeID(), aNode);
695     if(!aNode.IsNull()) {
696       if(!aNode->HasFather()) return anObject;
697       else
698 	aNode = aNode->Father();
699       aNode->FindAttribute(GEOMOBJECT_GUID,  anObject);
700     }
701   }
702   return anObject;
703 /*
704     while(!aNode.IsNull()) {
705     if(aNode->FindAttribute(TFunction_Function::GetID(), aFun)) {
706       const Standard_GUID& aGUID = aFun->GetDriverGUID();
707       if(aGUID == funGUID) break;
708       else aFun.Nullify();
709     }
710     aNode = aNode->Next();
711   }
712 */
713 
714 }
715 //=======================================================================
716 //function : LoadResult
717 //purpose  :
718 //=======================================================================
LoadResult(const TDF_Label & ResultLabel,BRepAlgoAPI_BooleanOperation & MS)719 void DNaming::LoadResult(const TDF_Label& ResultLabel, BRepAlgoAPI_BooleanOperation& MS)
720 {
721   Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(ResultLabel);
722   if (Tagger.IsNull()) return;
723   Tagger->Set(0);
724   TNaming_Builder Builder (ResultLabel);
725   TopoDS_Shape aResult = MS.Shape();
726   if (aResult.ShapeType() == TopAbs_COMPOUND) {
727     if (aResult.NbChildren() == 1) {
728       TopoDS_Iterator itr (aResult);
729       if (itr.More()) aResult = itr.Value();
730     }
731   }
732   if (MS.Shape1().IsNull()) Builder.Generated(aResult);
733   else {
734     Builder.Modify(MS.Shape1(), aResult);
735   }
736 }
737 //=======================================================================
738 //function : LoadAndOrientModifiedShapes
739 //purpose  :
740 //=======================================================================
LoadAndOrientModifiedShapes(BRepBuilderAPI_MakeShape & MS,const TopoDS_Shape & ShapeIn,const TopAbs_ShapeEnum KindOfShape,TNaming_Builder & Builder,const TopTools_DataMapOfShapeShape & SubShapes)741 void DNaming::LoadAndOrientModifiedShapes (BRepBuilderAPI_MakeShape&    MS,
742 					   const TopoDS_Shape&     ShapeIn,
743 					   const TopAbs_ShapeEnum  KindOfShape,
744 					   TNaming_Builder&        Builder,
745 					   const TopTools_DataMapOfShapeShape& SubShapes)
746 {
747   TopTools_MapOfShape View;
748   TopExp_Explorer ShapeExplorer (ShapeIn, KindOfShape);
749   for (; ShapeExplorer.More(); ShapeExplorer.Next ()) {
750     const TopoDS_Shape& Root = ShapeExplorer.Current ();
751     if (!View.Add(Root)) continue;
752     const TopTools_ListOfShape& Shapes = MS.Modified (Root);
753     TopTools_ListIteratorOfListOfShape ShapesIterator (Shapes);
754     for (;ShapesIterator.More (); ShapesIterator.Next ()) {
755       TopoDS_Shape newShape = ShapesIterator.Value ();
756       if (SubShapes.IsBound(newShape)) {
757 	newShape.Orientation((SubShapes(newShape)).Orientation());
758       }
759       if (!Root.IsSame (newShape)) Builder.Modify (Root, newShape );
760     }
761   }
762 }
763 //=======================================================================
764 //function : LoadDeletedShapes
765 //purpose  :
766 //=======================================================================
LoadDeletedShapes(BRepBuilderAPI_MakeShape & MS,const TopoDS_Shape & ShapeIn,const TopAbs_ShapeEnum KindOfShape,TNaming_Builder & Builder)767 void DNaming::LoadDeletedShapes (BRepBuilderAPI_MakeShape& MS,
768 			       const TopoDS_Shape&     ShapeIn,
769 			       const TopAbs_ShapeEnum  KindOfShape,
770 			       TNaming_Builder&        Builder)
771 {
772   TopTools_MapOfShape View;
773   TopExp_Explorer ShapeExplorer (ShapeIn, KindOfShape);
774   for (; ShapeExplorer.More(); ShapeExplorer.Next ()) {
775     const TopoDS_Shape& Root = ShapeExplorer.Current ();
776     if (!View.Add(Root)) continue;
777     if (MS.IsDeleted (Root)) {
778       Builder.Delete (Root);
779     }
780   }
781 }
782 
783 //=======================================================================
784 //function : LoadAndOrientGeneratedShapes
785 //purpose  :
786 //=======================================================================
787 
LoadAndOrientGeneratedShapes(BRepBuilderAPI_MakeShape & MS,const TopoDS_Shape & ShapeIn,const TopAbs_ShapeEnum KindOfShape,TNaming_Builder & Builder,const TopTools_DataMapOfShapeShape & SubShapes)788 void DNaming::LoadAndOrientGeneratedShapes (BRepBuilderAPI_MakeShape&     MS,
789 					    const TopoDS_Shape&           ShapeIn,
790 					    const TopAbs_ShapeEnum        KindOfShape,
791 					    TNaming_Builder&              Builder,
792 					    const TopTools_DataMapOfShapeShape& SubShapes)
793 {
794   TopTools_MapOfShape View;
795   TopExp_Explorer ShapeExplorer (ShapeIn, KindOfShape);
796   for (; ShapeExplorer.More(); ShapeExplorer.Next ()) {
797     const TopoDS_Shape& Root = ShapeExplorer.Current ();
798     if (!View.Add(Root)) continue;
799     const TopTools_ListOfShape& Shapes = MS.Generated (Root);
800     TopTools_ListIteratorOfListOfShape ShapesIterator (Shapes);
801     for (;ShapesIterator.More (); ShapesIterator.Next ()) {
802       TopoDS_Shape newShape = ShapesIterator.Value ();
803       if (SubShapes.IsBound(newShape)) {
804 	newShape.Orientation((SubShapes(newShape)).Orientation());
805       }
806       if (!Root.IsSame (newShape)) Builder.Generated (Root,newShape );
807     }
808   }
809 }
810 
811 //=======================================================================
812 //function : ComputeNormalizedVector
813 //purpose  : Computes normalized vector from shape if it is possible
814 //=======================================================================
ComputeAxis(const Handle (TNaming_NamedShape)& theNS,gp_Ax1 & theAx1)815 Standard_Boolean DNaming::ComputeAxis (const Handle(TNaming_NamedShape)& theNS,
816 						   gp_Ax1& theAx1)
817 {
818   if(theNS.IsNull() || theNS->IsEmpty()) return Standard_False;
819   TopoDS_Shape aShape = theNS->Get();
820   if(aShape.IsNull()) return Standard_False;
821   if(aShape.ShapeType() == TopAbs_EDGE || aShape.ShapeType() == TopAbs_WIRE) {
822     if (aShape.ShapeType() == TopAbs_WIRE) {
823       TopExp_Explorer anExplorer(aShape, TopAbs_EDGE);
824       aShape = anExplorer.Current();
825     }
826     const TopoDS_Edge& anEdge = TopoDS::Edge(aShape);
827     Standard_Real aFirst, aLast;
828     Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge,aFirst,aLast) ;
829     if (aCurve->IsKind (STANDARD_TYPE(Geom_Line)) ) {
830       Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast(aCurve) ;
831       if(!aLine.IsNull()) {
832 	theAx1  = aLine->Position() ;
833 	return Standard_True;
834       }
835     }
836   }
837   return Standard_False;
838 }
839 
840 //=======================================================================
841 //function : IsAttachment
842 //purpose  :
843 //=======================================================================
IsAttachment(const Handle (TDataStd_UAttribute)& anObj)844 Standard_Boolean DNaming::IsAttachment(const Handle(TDataStd_UAttribute)& anObj)
845 {
846 
847   Handle(TFunction_Function) aFun = GetFirstFunction(anObj);
848   if(!aFun.IsNull()) {
849     const Standard_GUID& aGUID = aFun->GetDriverGUID();
850     if(aGUID == ATTCH_GUID || aGUID == XTTCH_GUID) {
851       return
852 	aFun->Label().FindChild(FUNCTION_ARGUMENTS_LABEL).FindChild(ATTACH_ARG).IsAttribute(TDF_Reference::GetID());
853     }
854   }
855   return Standard_False;
856 }
857 
858 //=======================================================================
859 //function : GetAttachmentsContext
860 //purpose  :
861 //=======================================================================
Handle(TNaming_NamedShape)862 Handle(TNaming_NamedShape) DNaming::GetAttachmentsContext(const Handle(TDataStd_UAttribute)& anObj)
863 {
864   Handle(TNaming_NamedShape) aNS;
865   Handle(TFunction_Function) aFun = GetFirstFunction(anObj);
866   if(!aFun.IsNull()) {
867     const Standard_GUID& aGUID = aFun->GetDriverGUID();
868     if(aGUID == ATTCH_GUID) {
869       const TDF_Label& aLabel = aFun->Label().FindChild(FUNCTION_ARGUMENTS_LABEL).FindChild(ATTACH_ARG);
870       Handle(TDF_Reference) aRef;
871       Handle(TFunction_Function) aFunCnt;
872       if(aLabel.FindAttribute(TDF_Reference::GetID(), aRef)) {
873 	if(aRef->Get().FindAttribute(TFunction_Function::GetID(), aFunCnt)) {
874 	  const TDF_Label& aResultLabel =  aFunCnt->Label().FindChild(FUNCTION_RESULT_LABEL, Standard_True);
875 	  aResultLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS);
876 	}
877       }
878     }
879   }
880   return aNS;
881 }
882 
883 //=======================================================================
884 //function : ComputeSweepDir
885 //purpose  : Computes direction for extrusion
886 //=======================================================================
ComputeSweepDir(const TopoDS_Shape & theShape,gp_Ax1 & theAxis)887 Standard_Boolean DNaming::ComputeSweepDir (const TopoDS_Shape& theShape,
888 						   gp_Ax1& theAxis)
889 {
890   // Find surface
891   TopLoc_Location aLocation = theShape.Location();
892   Handle(Geom_Plane) aPlane;
893 
894   if (theShape.ShapeType() == TopAbs_FACE) {
895     Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(theShape));
896 #ifdef OCCT_DEBUG
897     Standard_CString s = aSurf->DynamicType()->Name();
898     std::cout<<"Surface Dynamic TYPE = "<<s<<std::endl;
899 #endif
900     if (aSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
901       aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
902     aPlane = Handle(Geom_Plane)::DownCast(aSurf);
903   }
904 
905   if(aPlane.IsNull()) {
906     BRepLib_FindSurface aFinder (theShape, 0., Standard_True);
907     if (!aFinder.Found()) return Standard_False;
908     aPlane = Handle(Geom_Plane)::DownCast(aFinder.Surface());
909   }
910 
911   if (aPlane.IsNull())  return  Standard_False;
912 
913   theAxis = aPlane->Pln().Axis();
914   if (!aPlane->Pln().Direct()) theAxis.Reverse();
915 
916   if (theShape.Orientation() == TopAbs_REVERSED) theAxis.Reverse();
917 
918   return Standard_True;
919 }
920