1 // Created on: 2009-05-07
2 // Created by: Sergey ZARITCHNY
3 // Copyright (c) 2009-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
21 #include <DNaming_TransformationDriver.ixx>
22 #include <Standard_NullObject.hxx>
25 #include <TopoDS_Shape.hxx>
26 #include <TopoDS_Edge.hxx>
27 #include <TopoDS_Vertex.hxx>
28 #include <TopoDS_Compound.hxx>
29 #include <TopoDS_Iterator.hxx>
31 #include <TopExp_Explorer.hxx>
32 #include <BRep_Builder.hxx>
33 #include <BRepBuilderAPI_Transform.hxx>
34 #include <BRep_Tool.hxx>
35 #include <BRepBuilderAPI_MakeShape.hxx>
36 #include <TopTools_MapOfShape.hxx>
37 #include <TopTools_DataMapOfShapeShape.hxx>
38 #include <TopTools_MapIteratorOfMapOfShape.hxx>
39 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
40 #include <TopTools_DataMapOfShapeInteger.hxx>
41 #include <TopTools_DataMapIteratorOfDataMapOfShapeInteger.hxx>
42 #include <TNaming_Builder.hxx>
43 #include <TNaming_NamedShape.hxx>
44 #include <TNaming_Tool.hxx>
45 #include <TFunction_Function.hxx>
46 #include <TFunction_Logbook.hxx>
47 #include <DNaming.hxx>
48 #include <TDataStd_Real.hxx>
53 #include <GeomLib_IsPlanarSurface.hxx>
54 #include <NCollection_Handle.hxx>
55 #include <ModelDefinitions.hxx>
60 #define EXCEPTION Standard_Failure
67 //#define MDTV_DEB_TRSF
69 #include <TCollection_AsciiString.hxx>
70 #include <BRepTools.hxx>
71 #include <TDF_Tool.hxx>
72 void PrintE(const TDF_Label& label)
74 TCollection_AsciiString entry;
75 TDF_Tool::Entry(label, entry);
76 cout << "LabelEntry = "<< entry << endl;
79 //=======================================================================
80 //function : TransformationDriver
81 //purpose : Constructor
82 //=======================================================================
83 DNaming_TransformationDriver::DNaming_TransformationDriver()
86 //=======================================================================
88 //purpose : Validates labels of a function in <log>.
89 //=======================================================================
90 void DNaming_TransformationDriver::Validate(TFunction_Logbook& theLog) const
93 //=======================================================================
94 //function : MustExecute
95 //purpose : Analyse in <log> if the loaded function must be executed
96 //=======================================================================
97 Standard_Boolean DNaming_TransformationDriver::MustExecute(const TFunction_Logbook& theLog) const
103 //=======================================================================
105 //purpose : Execute the function and push in <log> the impacted labels
106 //=======================================================================
107 Standard_Integer DNaming_TransformationDriver::Execute(TFunction_Logbook& theLog) const
109 Handle(TFunction_Function) aFunction;
110 Label().FindAttribute(TFunction_Function::GetID(),aFunction);
111 if(aFunction.IsNull()) return -1;
113 Handle(TFunction_Function) aPrevFun = DNaming::GetPrevFunction(aFunction);
114 if(aPrevFun.IsNull()) return -1;
115 const TDF_Label& aLab = RESPOSITION(aPrevFun);
116 Handle(TNaming_NamedShape) aContextNS;
117 aLab.FindAttribute(TNaming_NamedShape::GetID(), aContextNS);
118 if (aContextNS.IsNull() || aContextNS->IsEmpty()) {
120 cout<<"TransformationDriver:: Context is empty"<<endl;
122 aFunction->SetFailure(WRONG_CONTEXT);
126 gp_Trsf aTransformation;
127 const Standard_GUID& aGUID = aFunction->GetDriverGUID();
130 if(aGUID == PTXYZ_GUID) {
131 Standard_Real aDX = DNaming::GetReal(aFunction,PTRANSF_DX)->Get();
132 Standard_Real aDY = DNaming::GetReal(aFunction,PTRANSF_DY)->Get();
133 Standard_Real aDZ = DNaming::GetReal(aFunction,PTRANSF_DZ)->Get();
134 gp_Vec aVector(aDX, aDY, aDZ);
135 aTransformation.SetTranslation(aVector);
137 else if(aGUID == PTALINE_GUID) {
138 Handle(TDataStd_UAttribute) aLineObj = DNaming::GetObjectArg(aFunction, PTRANSF_LINE);
139 Handle(TNaming_NamedShape) aLineNS = DNaming::GetObjectValue(aLineObj);
141 if(!DNaming::ComputeAxis(aLineNS, anAxis)) Standard_Failure::Raise();
142 gp_Vec aVector(anAxis.Direction());
144 Standard_Real anOffset = DNaming::GetReal(aFunction,PTRANSF_OFF)->Get();
146 aTransformation.SetTranslation(aVector);
148 } else if(aGUID == PRRLINE_GUID) {
149 Handle(TDataStd_UAttribute) aLineObj = DNaming::GetObjectArg(aFunction, PTRANSF_LINE);
150 Handle(TNaming_NamedShape) aLineNS = DNaming::GetObjectValue(aLineObj);
152 if(!DNaming::ComputeAxis(aLineNS, anAxis)) Standard_Failure::Raise();
154 Standard_Real anAngle = DNaming::GetReal(aFunction,PTRANSF_ANG)->Get();
155 aTransformation.SetRotation(anAxis, anAngle);
156 } else if(aGUID == PMIRR_GUID) {
157 Handle(TDataStd_UAttribute) aPlaneObj = DNaming::GetObjectArg(aFunction, PTRANSF_PLANE);
158 Handle(TNaming_NamedShape) aNS = DNaming::GetObjectValue(aPlaneObj);
160 if(aNS.IsNull() || aNS->IsEmpty() || aNS->Get().IsNull() ||
161 aNS->Get().ShapeType() != TopAbs_FACE) Standard_Failure::Raise();
162 TopoDS_Face aFace = TopoDS::Face(aNS->Get());
163 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
164 GeomLib_IsPlanarSurface isPlanarSurface (aSurf);
165 if(!isPlanarSurface.IsPlanar()) Standard_Failure::Raise();
166 gp_Pln aPlane = isPlanarSurface.Plan();
167 gp_Ax2 aMirrorAx2 = aPlane.Position().Ax2();
168 aTransformation.SetMirror(aMirrorAx2);
170 aFunction->SetFailure(UNSUPPORTED_FUNCTION);
173 } catch (EXCEPTION) {
174 aFunction->SetFailure(WRONG_ARGUMENT);
180 LoadNamingDS(RESPOSITION(aFunction), aContextNS, aTransformation);
182 theLog.SetValid(RESPOSITION(aFunction),Standard_True);
183 aFunction->SetFailure(DONE);
186 //=================================================================================
187 static void BuildMap(const TopTools_MapOfShape& SMap,
188 BRepBuilderAPI_Transform& Transformer,
189 TopTools_DataMapOfShapeShape& M)
191 TopTools_MapIteratorOfMapOfShape anIt(SMap);
192 for(;anIt.More();anIt.Next()) {
193 if(!anIt.Key().IsNull()) {
194 const TopoDS_Shape& aS = anIt.Key();
195 M.Bind(aS,Transformer.ModifiedShape(aS));
199 //=================================================================================
200 static void CollectShapes(const TopoDS_Shape& SSh, TopoDS_Compound& C,
201 TopTools_MapOfShape& SMap, const TDF_Label& theLab,
202 TopTools_DataMapOfShapeInteger& TagMap, const Standard_Boolean isPrimitive)
204 const TopAbs_ShapeEnum aType = SSh.ShapeType();
207 case TopAbs_COMPOUND:
209 TopoDS_Iterator it(SSh);
210 for(;it.More();it.Next())
211 CollectShapes(it.Value(), C, SMap, theLab, TagMap,isPrimitive);
214 case TopAbs_COMPSOLID:
218 TopExp_Explorer anEx(SSh, TopAbs_FACE);
219 for(;anEx.More();anEx.Next()) {
220 const Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(anEx.Current(), theLab);
221 if(aNS.IsNull()) continue;
222 if(SMap.Add(anEx.Current())) {
223 aB.Add(C,anEx.Current());
225 TagMap.Bind(anEx.Current(), aNS->Label().Tag());
228 anEx.Init(SSh, TopAbs_EDGE);
229 for(;anEx.More();anEx.Next()) {
230 const Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(anEx.Current(), theLab);
231 if(aNS.IsNull()) continue;
232 if(SMap.Add(anEx.Current())) {
233 aB.Add(C,anEx.Current());
235 TagMap.Bind(anEx.Current(), aNS->Label().Tag());
238 anEx.Init(SSh, TopAbs_VERTEX);
239 for(;anEx.More();anEx.Next()) {
240 const Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(anEx.Current(), theLab);
241 if(aNS.IsNull()) continue;
242 if(SMap.Add(anEx.Current())) {
243 aB.Add(C,anEx.Current());
245 TagMap.Bind(anEx.Current(), aNS->Label().Tag());
252 const Handle(TNaming_NamedShape) aNamedShape = TNaming_Tool::NamedShape(SSh, theLab);
253 if(!aNamedShape.IsNull())
256 TopExp_Explorer anEx(SSh, TopAbs_EDGE);
257 for(;anEx.More();anEx.Next()) {
258 const Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(anEx.Current(), theLab);
259 if(aNS.IsNull()) continue;
260 if(SMap.Add(anEx.Current())) {
261 aB.Add(C,anEx.Current());
263 TagMap.Bind(anEx.Current(), aNS->Label().Tag());
266 anEx.Init(SSh, TopAbs_VERTEX);
267 for(;anEx.More();anEx.Next()) {
268 const Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(anEx.Current(), theLab);
269 if(aNS.IsNull()) continue;
270 if(SMap.Add(anEx.Current())) {
271 aB.Add(C,anEx.Current());
273 TagMap.Bind(anEx.Current(), aNS->Label().Tag());
280 TopExp_Explorer anEx(SSh, TopAbs_EDGE);
281 for(;anEx.More();anEx.Next()) {
282 const Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(anEx.Current(), theLab);
283 if(aNS.IsNull()) continue;
284 if(SMap.Add(anEx.Current())) {
285 aB.Add(C,anEx.Current());
287 TagMap.Bind(anEx.Current(), aNS->Label().Tag());
290 anEx.Init(SSh, TopAbs_VERTEX);
291 for(;anEx.More();anEx.Next()) {
292 const Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(anEx.Current(), theLab);
293 if(aNS.IsNull()) continue;
294 if(SMap.Add(anEx.Current())) {
295 aB.Add(C,anEx.Current());
297 TagMap.Bind(anEx.Current(), aNS->Label().Tag());
305 const Handle(TNaming_NamedShape) aNamedShape = TNaming_Tool::NamedShape(SSh, theLab);
306 if(!aNamedShape.IsNull())
309 TopExp_Explorer anEx(SSh, TopAbs_VERTEX);
310 anEx.Init(SSh, TopAbs_VERTEX);
311 for(;anEx.More();anEx.Next()) {
312 const Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(anEx.Current(), theLab);
313 if(aNS.IsNull()) continue;
314 if(SMap.Add(anEx.Current())) {
315 aB.Add(C,anEx.Current());
317 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());
334 //=======================================================================
335 //function : LoadAndName
337 //=======================================================================
338 void DNaming_TransformationDriver::LoadNamingDS (const TDF_Label& theResultLabel,
339 const Handle(TNaming_NamedShape)& theSourceNS,
340 const gp_Trsf& theTrsf) const
342 if(theSourceNS.IsNull() || theSourceNS->IsEmpty())
344 const TopoDS_Shape& aSrcShape = theSourceNS->Get();
345 if (aSrcShape.IsNull()) {
347 cout<<"DNaming_TransformationDriver::LoadNamingDS: The result of the Transform operation is null"<<endl;
351 Standard_Boolean isPrimitive(Standard_False);
352 if(theSourceNS->Evolution() == TNaming_PRIMITIVE) isPrimitive = Standard_True;
353 const TDF_Label& aSrcLabel = theSourceNS->Label();
355 cout <<"TransformationDriver: ";
359 TopoDS_Compound aCompShape;
361 aB.MakeCompound(aCompShape);
362 TopTools_MapOfShape aSMap;
363 TopTools_DataMapOfShapeInteger aTagMap;
365 if(aSMap.Add(aSrcShape))
366 aB.Add(aCompShape, aSrcShape);
367 CollectShapes(aSrcShape,aCompShape,aSMap, aSrcLabel, aTagMap, isPrimitive);
370 BRepBuilderAPI_Transform aTransformer(aCompShape, theTrsf, Standard_False);
371 TopTools_DataMapOfShapeShape aTMap;
372 BuildMap (aSMap, aTransformer,aTMap);
376 if (aTMap.IsBound(aSrcShape)) aNewSh = aTMap(aSrcShape);
377 if(!aNewSh.IsNull()) {
378 TNaming_Builder aBuilder (theResultLabel);
379 aBuilder.Modify(aSrcShape, aNewSh);
380 aTMap.UnBind(aSrcShape);
383 TopTools_DataMapOfShapeShape SubShapes;
384 TopExp_Explorer Exp(aNewSh, TopAbs_FACE);
385 for (; Exp.More(); Exp.Next()) {
386 SubShapes.Bind(Exp.Current(),Exp.Current());
388 for (Exp.Init(aNewSh, TopAbs_EDGE); Exp.More(); Exp.Next()) {
389 SubShapes.Bind(Exp.Current(),Exp.Current());
391 for (Exp.Init(aNewSh, TopAbs_VERTEX); Exp.More(); Exp.Next()) {
392 SubShapes.Bind(Exp.Current(),Exp.Current());
395 Standard_Integer aNextTag(0);
396 TopTools_DataMapIteratorOfDataMapOfShapeInteger it(aTagMap);
397 for(;it.More();it.Next()) {
398 if(it.Value() > aNextTag)
399 aNextTag = it.Value();
401 NCollection_Handle<TNaming_Builder> aFBuilder, anEBuilder, aVBuilder;
402 TopTools_DataMapIteratorOfDataMapOfShapeShape anIt(aTMap);
403 for(;anIt.More();anIt.Next()) {
404 const TopoDS_Shape& aKey = anIt.Key();
405 TopoDS_Shape newShape = anIt.Value();
406 if (SubShapes.IsBound(newShape)) {
407 newShape.Orientation((SubShapes(newShape)).Orientation());
410 if(aTagMap.IsBound(aKey)) {
411 const TDF_Label& aLabel = theResultLabel.FindChild(aTagMap.Find(aKey), Standard_True);
412 TNaming_Builder aBuilder(aLabel);
413 aBuilder.Modify(aKey, newShape);
416 const TDF_Label& aLabel = theResultLabel.FindChild(aNextTag, Standard_True);
417 TNaming_Builder aBuilder(aLabel);
418 aBuilder.Modify(aKey, newShape);
422 if(aKey.ShapeType() == TopAbs_FACE) {
423 if (aFBuilder.IsNull())
425 const TDF_Label& aFLabel = theResultLabel.FindChild(FACES_TAG, Standard_True);
426 aFBuilder = new TNaming_Builder (aFLabel);
428 aFBuilder->Modify(anIt.Key(), newShape);
430 else if(aKey.ShapeType() == TopAbs_EDGE) {
431 if (anEBuilder.IsNull())
433 const TDF_Label& aELabel = theResultLabel.FindChild(EDGES_TAG, Standard_True);
434 anEBuilder = new TNaming_Builder (aELabel);
436 anEBuilder->Modify(anIt.Key(), newShape);
438 else if(aKey.ShapeType() == TopAbs_VERTEX) {
439 if (aVBuilder.IsNull())
441 const TDF_Label& aVLabel = theResultLabel.FindChild(VERTEX_TAG, Standard_True);
442 aVBuilder = new TNaming_Builder (aVLabel);
444 aVBuilder->Modify(anIt.Key(), newShape);