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