1 // Created on: 2009-05-07
2 // Created by: Sergey ZARITCHNY
3 // Copyright (c) 2009-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
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>
27 #include <gp_Trsf.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>
42 #include <TopExp_Explorer.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>
59 #define EXCEPTION Standard_Failure
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)
73 TCollection_AsciiString entry;
74 TDF_Tool::Entry(label, entry);
75 cout << "LabelEntry = "<< entry << endl;
78 //=======================================================================
79 //function : TransformationDriver
80 //purpose : Constructor
81 //=======================================================================
82 DNaming_TransformationDriver::DNaming_TransformationDriver()
85 //=======================================================================
87 //purpose : Validates labels of a function in <log>.
88 //=======================================================================
89 void DNaming_TransformationDriver::Validate(TFunction_Logbook&) const
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
102 //=======================================================================
104 //purpose : Execute the function and push in <log> the impacted labels
105 //=======================================================================
106 Standard_Integer DNaming_TransformationDriver::Execute(TFunction_Logbook& theLog) const
108 Handle(TFunction_Function) aFunction;
109 Label().FindAttribute(TFunction_Function::GetID(),aFunction);
110 if(aFunction.IsNull()) return -1;
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()) {
119 cout<<"TransformationDriver:: Context is empty"<<endl;
121 aFunction->SetFailure(WRONG_CONTEXT);
125 gp_Trsf aTransformation;
126 const Standard_GUID& aGUID = aFunction->GetDriverGUID();
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);
136 else if(aGUID == PTALINE_GUID) {
137 Handle(TDataStd_UAttribute) aLineObj = DNaming::GetObjectArg(aFunction, PTRANSF_LINE);
138 Handle(TNaming_NamedShape) aLineNS = DNaming::GetObjectValue(aLineObj);
140 if(!DNaming::ComputeAxis(aLineNS, anAxis)) Standard_Failure::Raise();
141 gp_Vec aVector(anAxis.Direction());
143 Standard_Real anOffset = DNaming::GetReal(aFunction,PTRANSF_OFF)->Get();
145 aTransformation.SetTranslation(aVector);
147 } else if(aGUID == PRRLINE_GUID) {
148 Handle(TDataStd_UAttribute) aLineObj = DNaming::GetObjectArg(aFunction, PTRANSF_LINE);
149 Handle(TNaming_NamedShape) aLineNS = DNaming::GetObjectValue(aLineObj);
151 if(!DNaming::ComputeAxis(aLineNS, anAxis)) Standard_Failure::Raise();
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);
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);
169 aFunction->SetFailure(UNSUPPORTED_FUNCTION);
172 } catch (EXCEPTION) {
173 aFunction->SetFailure(WRONG_ARGUMENT);
179 LoadNamingDS(RESPOSITION(aFunction), aContextNS, aTransformation);
181 theLog.SetValid(RESPOSITION(aFunction),Standard_True);
182 aFunction->SetFailure(DONE);
185 //=================================================================================
186 static void BuildMap(const TopTools_MapOfShape& SMap,
187 BRepBuilderAPI_Transform& Transformer,
188 TopTools_DataMapOfShapeShape& M)
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));
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)
203 const TopAbs_ShapeEnum aType = SSh.ShapeType();
206 case TopAbs_COMPOUND:
208 TopoDS_Iterator it(SSh);
209 for(;it.More();it.Next())
210 CollectShapes(it.Value(), C, SMap, theLab, TagMap,isPrimitive);
213 case TopAbs_COMPSOLID:
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());
224 TagMap.Bind(anEx.Current(), aNS->Label().Tag());
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());
234 TagMap.Bind(anEx.Current(), aNS->Label().Tag());
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());
244 TagMap.Bind(anEx.Current(), aNS->Label().Tag());
251 const Handle(TNaming_NamedShape) aNamedShape = TNaming_Tool::NamedShape(SSh, theLab);
252 if(!aNamedShape.IsNull())
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());
262 TagMap.Bind(anEx.Current(), aNS->Label().Tag());
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());
272 TagMap.Bind(anEx.Current(), aNS->Label().Tag());
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());
286 TagMap.Bind(anEx.Current(), aNS->Label().Tag());
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());
296 TagMap.Bind(anEx.Current(), aNS->Label().Tag());
304 const Handle(TNaming_NamedShape) aNamedShape = TNaming_Tool::NamedShape(SSh, theLab);
305 if(!aNamedShape.IsNull())
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());
316 TagMap.Bind(anEx.Current(), aNS->Label().Tag());
323 const Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(SSh, theLab);
328 // TagMap.Bind(SSh, aNS->Label().Tag());
337 //=======================================================================
338 //function : LoadAndName
340 //=======================================================================
341 void DNaming_TransformationDriver::LoadNamingDS (const TDF_Label& theResultLabel,
342 const Handle(TNaming_NamedShape)& theSourceNS,
343 const gp_Trsf& theTrsf) const
345 if(theSourceNS.IsNull() || theSourceNS->IsEmpty())
347 const TopoDS_Shape& aSrcShape = theSourceNS->Get();
348 if (aSrcShape.IsNull()) {
350 cout<<"DNaming_TransformationDriver::LoadNamingDS: The result of the Transform operation is null"<<endl;
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: ";
362 TopoDS_Compound aCompShape;
364 aB.MakeCompound(aCompShape);
365 TopTools_MapOfShape aSMap;
366 TopTools_DataMapOfShapeInteger aTagMap;
368 if(aSMap.Add(aSrcShape))
369 aB.Add(aCompShape, aSrcShape);
370 CollectShapes(aSrcShape,aCompShape,aSMap, aSrcLabel, aTagMap, isPrimitive);
373 BRepBuilderAPI_Transform aTransformer(aCompShape, theTrsf, Standard_False);
374 TopTools_DataMapOfShapeShape aTMap;
375 BuildMap (aSMap, aTransformer,aTMap);
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);
386 TopTools_DataMapOfShapeShape SubShapes;
387 TopExp_Explorer Exp(aNewSh, TopAbs_FACE);
388 for (; Exp.More(); Exp.Next()) {
389 SubShapes.Bind(Exp.Current(),Exp.Current());
391 for (Exp.Init(aNewSh, TopAbs_EDGE); Exp.More(); Exp.Next()) {
392 SubShapes.Bind(Exp.Current(),Exp.Current());
394 for (Exp.Init(aNewSh, TopAbs_VERTEX); Exp.More(); Exp.Next()) {
395 SubShapes.Bind(Exp.Current(),Exp.Current());
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();
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());
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);
419 const TDF_Label& aLabel = theResultLabel.FindChild(aNextTag, Standard_True);
420 TNaming_Builder aBuilder(aLabel);
421 aBuilder.Modify(aKey, newShape);
425 if(aKey.ShapeType() == TopAbs_FACE) {
426 if (aFBuilder.IsNull())
428 const TDF_Label& aFLabel = theResultLabel.FindChild(FACES_TAG, Standard_True);
429 aFBuilder = new TNaming_Builder (aFLabel);
431 aFBuilder->Modify(anIt.Key(), newShape);
433 else if(aKey.ShapeType() == TopAbs_EDGE) {
434 if (anEBuilder.IsNull())
436 const TDF_Label& aELabel = theResultLabel.FindChild(EDGES_TAG, Standard_True);
437 anEBuilder = new TNaming_Builder (aELabel);
439 anEBuilder->Modify(anIt.Key(), newShape);
441 else if(aKey.ShapeType() == TopAbs_VERTEX) {
442 if (aVBuilder.IsNull())
444 const TDF_Label& aVLabel = theResultLabel.FindChild(VERTEX_TAG, Standard_True);
445 aVBuilder = new TNaming_Builder (aVLabel);
447 aVBuilder->Modify(anIt.Key(), newShape);