0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / DNaming / DNaming_TransformationDriver.cxx
CommitLineData
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 56IMPLEMENT_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>
73void 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//=======================================================================
84DNaming_TransformationDriver::DNaming_TransformationDriver()
85{}
86
87//=======================================================================
88//function : Validate
89//purpose : Validates labels of a function in <log>.
90//=======================================================================
f486f64d 91void 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 98Standard_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 108Standard_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//=================================================================================
188static 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//=================================================================================
201static 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//=======================================================================
343void 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}