0022972: Eliminate macro definitions that has compiler-provided analogs (WNT and...
[occt.git] / src / DNaming / DNaming_TransformationDriver.cxx
1 // Created on: 2009-05-07
2 // Created by: Sergey ZARITCHNY
3 // Copyright (c) 2009-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <BRep_Builder.hxx>
18 #include <BRep_Tool.hxx>
19 #include <BRepBuilderAPI_MakeShape.hxx>
20 #include <BRepBuilderAPI_Transform.hxx>
21 #include <DNaming.hxx>
22 #include <DNaming_TransformationDriver.hxx>
23 #include <GeomLib_IsPlanarSurface.hxx>
24 #include <gp_Ax1.hxx>
25 #include <gp_Ax2.hxx>
26 #include <gp_Pln.hxx>
27 #include <gp_Trsf.hxx>
28 #include <gp_Vec.hxx>
29 #include <ModelDefinitions.hxx>
30 #include <NCollection_Handle.hxx>
31 #include <Standard_NullObject.hxx>
32 #include <Standard_Type.hxx>
33 #include <TDataStd_Real.hxx>
34 #include <TDF_Label.hxx>
35 #include <TFunction_Function.hxx>
36 #include <TFunction_Logbook.hxx>
37 #include <TNaming_Builder.hxx>
38 #include <TNaming_NamedShape.hxx>
39 #include <TNaming_Tool.hxx>
40 #include <TopAbs.hxx>
41 #include <TopExp.hxx>
42 #include <TopExp_Explorer.hxx>
43 #include <TopoDS.hxx>
44 #include <TopoDS_Compound.hxx>
45 #include <TopoDS_Edge.hxx>
46 #include <TopoDS_Iterator.hxx>
47 #include <TopoDS_Shape.hxx>
48 #include <TopoDS_Vertex.hxx>
49 #include <TopTools_DataMapIteratorOfDataMapOfShapeInteger.hxx>
50 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
51 #include <TopTools_DataMapOfShapeInteger.hxx>
52 #include <TopTools_DataMapOfShapeShape.hxx>
53 #include <TopTools_MapIteratorOfMapOfShape.hxx>
54 #include <TopTools_MapOfShape.hxx>
55
56 #ifdef _WIN32
57 #define EXCEPTION ...
58 #else
59 #define EXCEPTION Standard_Failure
60 #endif 
61
62 #define FACES_TAG  1
63 #define EDGES_TAG  2
64 #define VERTEX_TAG 3
65
66 //#define MDTV_DEB_TRSF
67 #ifdef OCCT_DEBUG_TRSF
68 #include <TCollection_AsciiString.hxx>
69 #include <BRepTools.hxx>
70 #include <TDF_Tool.hxx>
71 void PrintE(const TDF_Label&       label)
72 {
73   TCollection_AsciiString entry;
74   TDF_Tool::Entry(label, entry);
75   cout << "LabelEntry = "<< entry << endl;
76 }
77 #endif
78 //=======================================================================
79 //function : TransformationDriver
80 //purpose  : Constructor
81 //=======================================================================
82 DNaming_TransformationDriver::DNaming_TransformationDriver()
83 {}
84
85 //=======================================================================
86 //function : Validate
87 //purpose  : Validates labels of a function in <log>.
88 //=======================================================================
89 void DNaming_TransformationDriver::Validate(TFunction_Logbook&) const
90 {}
91
92 //=======================================================================
93 //function : MustExecute
94 //purpose  : Analyse in <log> if the loaded function must be executed
95 //=======================================================================
96 Standard_Boolean DNaming_TransformationDriver::MustExecute(const TFunction_Logbook&) const
97 {
98   return Standard_True;
99 }
100
101
102 //=======================================================================
103 //function : Execute
104 //purpose  : Execute the function and push in <log> the impacted labels
105 //=======================================================================
106 Standard_Integer DNaming_TransformationDriver::Execute(TFunction_Logbook& theLog) const
107 {
108   Handle(TFunction_Function) aFunction;
109   Label().FindAttribute(TFunction_Function::GetID(),aFunction);
110   if(aFunction.IsNull()) return -1;
111
112   Handle(TFunction_Function) aPrevFun = DNaming::GetPrevFunction(aFunction);
113   if(aPrevFun.IsNull()) return -1;
114   const TDF_Label& aLab = RESPOSITION(aPrevFun);
115   Handle(TNaming_NamedShape) aContextNS;
116   aLab.FindAttribute(TNaming_NamedShape::GetID(), aContextNS);
117   if (aContextNS.IsNull() || aContextNS->IsEmpty()) {
118 #ifdef OCCT_DEBUG
119     cout<<"TransformationDriver:: Context is empty"<<endl;
120 #endif
121     aFunction->SetFailure(WRONG_CONTEXT);
122     return -1;
123   }
124 //
125   gp_Trsf aTransformation;
126   const Standard_GUID& aGUID = aFunction->GetDriverGUID();
127   
128   try {
129     if(aGUID == PTXYZ_GUID) {
130       Standard_Real aDX = DNaming::GetReal(aFunction,PTRANSF_DX)->Get();
131       Standard_Real aDY = DNaming::GetReal(aFunction,PTRANSF_DY)->Get();
132       Standard_Real aDZ = DNaming::GetReal(aFunction,PTRANSF_DZ)->Get();  
133       gp_Vec aVector(aDX, aDY, aDZ);
134       aTransformation.SetTranslation(aVector);      
135     }  
136     else if(aGUID == PTALINE_GUID) {
137       Handle(TDataStd_UAttribute) aLineObj  = DNaming::GetObjectArg(aFunction, PTRANSF_LINE);
138       Handle(TNaming_NamedShape) aLineNS = DNaming::GetObjectValue(aLineObj);
139       gp_Ax1 anAxis;
140       if(!DNaming::ComputeAxis(aLineNS, anAxis)) Standard_Failure::Raise();
141       gp_Vec aVector(anAxis.Direction());
142       aVector.Normalize();
143       Standard_Real anOffset = DNaming::GetReal(aFunction,PTRANSF_OFF)->Get();
144       aVector *= anOffset;
145       aTransformation.SetTranslation(aVector);   
146
147     }  else if(aGUID == PRRLINE_GUID) {
148       Handle(TDataStd_UAttribute) aLineObj  = DNaming::GetObjectArg(aFunction, PTRANSF_LINE);
149       Handle(TNaming_NamedShape) aLineNS = DNaming::GetObjectValue(aLineObj);
150       gp_Ax1 anAxis;
151       if(!DNaming::ComputeAxis(aLineNS, anAxis)) Standard_Failure::Raise();
152
153       Standard_Real anAngle = DNaming::GetReal(aFunction,PTRANSF_ANG)->Get();
154       aTransformation.SetRotation(anAxis, anAngle);
155     }  else if(aGUID == PMIRR_GUID) {
156       Handle(TDataStd_UAttribute) aPlaneObj  = DNaming::GetObjectArg(aFunction, PTRANSF_PLANE);
157       Handle(TNaming_NamedShape) aNS = DNaming::GetObjectValue(aPlaneObj);
158       
159       if(aNS.IsNull() ||  aNS->IsEmpty() || aNS->Get().IsNull() || 
160          aNS->Get().ShapeType() != TopAbs_FACE) Standard_Failure::Raise();
161       TopoDS_Face aFace = TopoDS::Face(aNS->Get());
162       Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
163       GeomLib_IsPlanarSurface isPlanarSurface (aSurf);
164       if(!isPlanarSurface.IsPlanar()) Standard_Failure::Raise();
165       gp_Pln aPlane = isPlanarSurface.Plan();
166       gp_Ax2 aMirrorAx2 = aPlane.Position().Ax2();
167       aTransformation.SetMirror(aMirrorAx2);
168     } else {
169       aFunction->SetFailure(UNSUPPORTED_FUNCTION);
170       return -1;
171     }
172   } catch (EXCEPTION) {
173     aFunction->SetFailure(WRONG_ARGUMENT);
174     return -1;
175   }
176 //
177
178 // Naming
179   LoadNamingDS(RESPOSITION(aFunction), aContextNS, aTransformation);
180
181   theLog.SetValid(RESPOSITION(aFunction),Standard_True);  
182   aFunction->SetFailure(DONE);
183   return 0;
184 }
185 //=================================================================================
186 static void BuildMap(const TopTools_MapOfShape& SMap,
187                      BRepBuilderAPI_Transform& Transformer,
188                      TopTools_DataMapOfShapeShape& M)
189 {
190   TopTools_MapIteratorOfMapOfShape anIt(SMap);
191   for(;anIt.More();anIt.Next()) {
192     if(!anIt.Key().IsNull()) {
193       const TopoDS_Shape& aS = anIt.Key(); 
194       M.Bind(aS,Transformer.ModifiedShape(aS));
195     }
196   } 
197 }
198 //=================================================================================
199 static void CollectShapes(const TopoDS_Shape& SSh, TopoDS_Compound& C, 
200                           TopTools_MapOfShape& SMap, const TDF_Label& theLab,
201                           TopTools_DataMapOfShapeInteger& TagMap, const Standard_Boolean isPrimitive)
202 {
203   const TopAbs_ShapeEnum aType = SSh.ShapeType();
204   BRep_Builder aB;
205   switch(aType) {
206   case TopAbs_COMPOUND:
207     {
208       TopoDS_Iterator it(SSh);
209       for(;it.More();it.Next()) 
210         CollectShapes(it.Value(), C, SMap, theLab, TagMap,isPrimitive);
211     }
212     break;
213   case TopAbs_COMPSOLID:
214   case TopAbs_SOLID:
215   case TopAbs_SHELL:
216     {
217       TopExp_Explorer anEx(SSh, TopAbs_FACE);
218       for(;anEx.More();anEx.Next()) {
219         const Handle(TNaming_NamedShape) aNS =  TNaming_Tool::NamedShape(anEx.Current(), theLab);
220         if(aNS.IsNull()) continue;
221         if(SMap.Add(anEx.Current())) {
222           aB.Add(C,anEx.Current());
223           if(isPrimitive)
224             TagMap.Bind(anEx.Current(), aNS->Label().Tag());
225         }
226       }
227       anEx.Init(SSh, TopAbs_EDGE); 
228       for(;anEx.More();anEx.Next()) {
229         const Handle(TNaming_NamedShape) aNS =  TNaming_Tool::NamedShape(anEx.Current(), theLab);
230         if(aNS.IsNull()) continue;
231         if(SMap.Add(anEx.Current())) {
232           aB.Add(C,anEx.Current());
233           if(isPrimitive)
234             TagMap.Bind(anEx.Current(), aNS->Label().Tag());
235         }
236       }
237       anEx.Init(SSh, TopAbs_VERTEX); 
238       for(;anEx.More();anEx.Next()) {
239         const Handle(TNaming_NamedShape) aNS =  TNaming_Tool::NamedShape(anEx.Current(), theLab);
240         if(aNS.IsNull()) continue;
241         if(SMap.Add(anEx.Current())) {
242           aB.Add(C,anEx.Current());
243           if(isPrimitive)
244             TagMap.Bind(anEx.Current(), aNS->Label().Tag());
245         }
246       }
247     }    
248     break;
249   case  TopAbs_FACE:
250     {
251       const Handle(TNaming_NamedShape) aNamedShape =  TNaming_Tool::NamedShape(SSh, theLab);
252       if(!aNamedShape.IsNull())
253         if(SMap.Add(SSh)) 
254           aB.Add(C,SSh); 
255       TopExp_Explorer anEx(SSh, TopAbs_EDGE);
256       for(;anEx.More();anEx.Next()) {
257         const Handle(TNaming_NamedShape) aNS =  TNaming_Tool::NamedShape(anEx.Current(), theLab);
258         if(aNS.IsNull()) continue;
259         if(SMap.Add(anEx.Current())) {
260           aB.Add(C,anEx.Current());
261           if(isPrimitive)
262             TagMap.Bind(anEx.Current(), aNS->Label().Tag());
263         }
264       }
265       anEx.Init(SSh, TopAbs_VERTEX); 
266       for(;anEx.More();anEx.Next()) {
267         const Handle(TNaming_NamedShape) aNS =  TNaming_Tool::NamedShape(anEx.Current(), theLab);
268         if(aNS.IsNull()) continue;
269         if(SMap.Add(anEx.Current())) {
270           aB.Add(C,anEx.Current());
271           if(isPrimitive)
272             TagMap.Bind(anEx.Current(), aNS->Label().Tag());
273         }
274       }
275     }
276     break;
277   case TopAbs_WIRE:
278     {      
279       TopExp_Explorer anEx(SSh, TopAbs_EDGE);
280       for(;anEx.More();anEx.Next()) {
281         const Handle(TNaming_NamedShape) aNS =  TNaming_Tool::NamedShape(anEx.Current(), theLab);
282         if(aNS.IsNull()) continue;
283         if(SMap.Add(anEx.Current())) {
284           aB.Add(C,anEx.Current());
285           if(isPrimitive)
286             TagMap.Bind(anEx.Current(), aNS->Label().Tag());
287         }
288       }  
289       anEx.Init(SSh, TopAbs_VERTEX); 
290       for(;anEx.More();anEx.Next()) {
291         const Handle(TNaming_NamedShape) aNS =  TNaming_Tool::NamedShape(anEx.Current(), theLab);
292         if(aNS.IsNull()) continue;
293         if(SMap.Add(anEx.Current())) {
294           aB.Add(C,anEx.Current()); 
295           if(isPrimitive)
296             TagMap.Bind(anEx.Current(), aNS->Label().Tag());
297         }
298       }     
299     }
300     break;
301     
302   case TopAbs_EDGE:
303     {
304       const Handle(TNaming_NamedShape) aNamedShape =  TNaming_Tool::NamedShape(SSh, theLab);
305       if(!aNamedShape.IsNull())
306         if(SMap.Add(SSh))
307           aB.Add(C,SSh); 
308       TopExp_Explorer anEx(SSh, TopAbs_VERTEX);      
309       anEx.Init(SSh, TopAbs_VERTEX); 
310       for(;anEx.More();anEx.Next()) {
311         const Handle(TNaming_NamedShape) aNS =  TNaming_Tool::NamedShape(anEx.Current(), theLab);
312         if(aNS.IsNull()) continue;
313         if(SMap.Add(anEx.Current())) {
314           aB.Add(C,anEx.Current()); 
315           if(isPrimitive)
316             TagMap.Bind(anEx.Current(), aNS->Label().Tag());
317         }
318       }   
319     }
320     break;
321   case TopAbs_VERTEX:
322   {
323     const Handle(TNaming_NamedShape) aNS =  TNaming_Tool::NamedShape(SSh, theLab);
324     if(!aNS.IsNull())
325       if(SMap.Add(SSh)) {
326         aB.Add(C,SSh); 
327 //      if(isPrimitive)
328 //        TagMap.Bind(SSh, aNS->Label().Tag());
329       }
330    }
331   break;
332     default:
333     break;
334   }
335 }
336
337 //=======================================================================
338 //function : LoadAndName
339 //purpose  : 
340 //=======================================================================
341 void DNaming_TransformationDriver::LoadNamingDS (const TDF_Label& theResultLabel, 
342                                                  const Handle(TNaming_NamedShape)& theSourceNS,
343                                                  const gp_Trsf& theTrsf) const 
344 {
345   if(theSourceNS.IsNull() || theSourceNS->IsEmpty())
346     return;
347   const TopoDS_Shape& aSrcShape  = theSourceNS->Get();
348   if (aSrcShape.IsNull()) {
349 #ifdef OCCT_DEBUG
350     cout<<"DNaming_TransformationDriver::LoadNamingDS: The result of the Transform operation is null"<<endl;
351 #endif
352     return;
353   }
354   Standard_Boolean isPrimitive(Standard_False);
355   if(theSourceNS->Evolution() == TNaming_PRIMITIVE) isPrimitive = Standard_True;
356   const TDF_Label& aSrcLabel     = theSourceNS->Label();
357 #ifdef OCCT_DEBUG_TRSF
358   cout <<"TransformationDriver: ";
359   PrintE(aSrcLabel);
360 #endif
361
362   TopoDS_Compound aCompShape;
363   BRep_Builder    aB;
364   aB.MakeCompound(aCompShape);
365   TopTools_MapOfShape aSMap;
366   TopTools_DataMapOfShapeInteger aTagMap;
367   //Collect  shapes
368   if(aSMap.Add(aSrcShape))
369     aB.Add(aCompShape, aSrcShape); 
370   CollectShapes(aSrcShape,aCompShape,aSMap, aSrcLabel, aTagMap, isPrimitive);
371
372   //Transform
373   BRepBuilderAPI_Transform aTransformer(aCompShape, theTrsf, Standard_False);
374   TopTools_DataMapOfShapeShape aTMap;
375   BuildMap (aSMap, aTransformer,aTMap);
376
377 //Load
378   TopoDS_Shape aNewSh;
379   if (aTMap.IsBound(aSrcShape)) aNewSh  = aTMap(aSrcShape);
380   if(!aNewSh.IsNull()) {
381     TNaming_Builder aBuilder (theResultLabel);
382     aBuilder.Modify(aSrcShape, aNewSh);
383     aTMap.UnBind(aSrcShape);
384   }
385
386   TopTools_DataMapOfShapeShape SubShapes;
387   TopExp_Explorer Exp(aNewSh, TopAbs_FACE);
388   for (; Exp.More(); Exp.Next()) {
389     SubShapes.Bind(Exp.Current(),Exp.Current());
390   }
391   for (Exp.Init(aNewSh, TopAbs_EDGE); Exp.More(); Exp.Next()) {
392     SubShapes.Bind(Exp.Current(),Exp.Current());
393   }
394   for (Exp.Init(aNewSh, TopAbs_VERTEX); Exp.More(); Exp.Next()) {
395     SubShapes.Bind(Exp.Current(),Exp.Current());
396   }
397
398   Standard_Integer aNextTag(0);
399   TopTools_DataMapIteratorOfDataMapOfShapeInteger it(aTagMap);
400   for(;it.More();it.Next()) {
401     if(it.Value() > aNextTag)
402       aNextTag = it.Value();
403   }
404   NCollection_Handle<TNaming_Builder> aFBuilder, anEBuilder, aVBuilder;
405   TopTools_DataMapIteratorOfDataMapOfShapeShape anIt(aTMap);
406   for(;anIt.More();anIt.Next()) {
407     const TopoDS_Shape& aKey = anIt.Key();
408     TopoDS_Shape newShape = anIt.Value();
409     if (SubShapes.IsBound(newShape)) {
410       newShape.Orientation((SubShapes(newShape)).Orientation());
411     }
412     if(isPrimitive) {
413       if(aTagMap.IsBound(aKey)) {
414         const TDF_Label& aLabel = theResultLabel.FindChild(aTagMap.Find(aKey),  Standard_True);
415         TNaming_Builder aBuilder(aLabel);
416         aBuilder.Modify(aKey, newShape);
417       } else {
418         aNextTag++;
419         const TDF_Label& aLabel = theResultLabel.FindChild(aNextTag,  Standard_True);
420         TNaming_Builder aBuilder(aLabel);
421         aBuilder.Modify(aKey, newShape);
422       }
423     } 
424     else {
425       if(aKey.ShapeType() == TopAbs_FACE) {
426         if (aFBuilder.IsNull()) 
427         {
428           const TDF_Label& aFLabel = theResultLabel.FindChild(FACES_TAG,  Standard_True);
429           aFBuilder = new TNaming_Builder (aFLabel);
430         }
431         aFBuilder->Modify(anIt.Key(), newShape);
432       }
433       else if(aKey.ShapeType() == TopAbs_EDGE) {
434         if (anEBuilder.IsNull()) 
435         {
436           const TDF_Label& aELabel = theResultLabel.FindChild(EDGES_TAG,  Standard_True);
437           anEBuilder = new TNaming_Builder (aELabel);
438         }
439         anEBuilder->Modify(anIt.Key(), newShape);
440       }
441       else if(aKey.ShapeType() == TopAbs_VERTEX) {
442         if (aVBuilder.IsNull())
443         {
444           const TDF_Label& aVLabel = theResultLabel.FindChild(VERTEX_TAG,  Standard_True);
445           aVBuilder = new TNaming_Builder (aVLabel);
446         }
447         aVBuilder->Modify(anIt.Key(), newShape);
448       }
449     }
450   }
451 }