1 // Created on: 2000-08-17
2 // Created by: Andrey BETENEV
3 // Copyright (c) 2000-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.
16 #include <IGESCAFControl_Writer.ixx>
17 #include <XCAFDoc_ShapeTool.hxx>
18 #include <TDF_LabelSequence.hxx>
19 #include <TopoDS_Shape.hxx>
20 #include <XCAFDoc_ColorTool.hxx>
21 #include <XCAFPrs.hxx>
22 #include <TransferBRep_ShapeMapper.hxx>
23 #include <TransferBRep.hxx>
24 #include <Transfer_FinderProcess.hxx>
25 #include <IGESGraph_Color.hxx>
26 #include <IGESCAFControl.hxx>
27 #include <TCollection_HAsciiString.hxx>
28 #include <TopoDS_Iterator.hxx>
29 #include <XCAFDoc_DocumentTool.hxx>
30 #include <TDF_Label.hxx>
31 #include <Transfer_TransientListBinder.hxx>
32 #include <Standard_Transient.hxx>
33 #include <XCAFDoc_LayerTool.hxx>
34 #include <IGESGraph_DefinitionLevel.hxx>
35 #include <TCollection_AsciiString.hxx>
36 #include <TopExp_Explorer.hxx>
38 #include <TopoDS_Face.hxx>
40 #include <TopoDS_Iterator.hxx>
41 #include <TDF_ChildIterator.hxx>
42 #include <TDataStd_Name.hxx>
43 #include <IGESData_NameEntity.hxx>
44 #include <TopTools_SequenceOfShape.hxx>
45 #include <TColStd_HSequenceOfExtendedString.hxx>
46 #include <NCollection_DataMap.hxx>
50 typedef NCollection_DataMap<TopoDS_Shape, TCollection_ExtendedString> DataMapOfShapeNames;
52 void CollectShapeNames (const TDF_Label& theLabel,
53 const TopLoc_Location& theLocation,
54 const Handle(TDataStd_Name)& thePrevName,
55 DataMapOfShapeNames& theMapOfShapeNames)
57 Standard_Boolean hasReferredShape = Standard_False;
58 Standard_Boolean hasComponents = Standard_False;
59 TDF_Label aReferredLabel;
61 Handle(TDataStd_Name) aName;
62 theLabel.FindAttribute (TDataStd_Name::GetID(), aName);
64 if ( XCAFDoc_ShapeTool::GetReferredShape ( theLabel, aReferredLabel ) )
66 TopLoc_Location aSubLocation = theLocation.Multiplied ( XCAFDoc_ShapeTool::GetLocation ( theLabel ) );
67 CollectShapeNames (aReferredLabel, aSubLocation, aName, theMapOfShapeNames);
68 hasReferredShape = Standard_True;
71 TDF_LabelSequence aSeq;
72 if (XCAFDoc_ShapeTool::GetComponents (theLabel, aSeq))
74 for (Standard_Integer anIter = 1; anIter <= aSeq.Length(); anIter++)
76 CollectShapeNames (aSeq.Value (anIter), theLocation, aName, theMapOfShapeNames );
78 hasComponents = Standard_True;
82 if (XCAFDoc_ShapeTool::GetSubShapes (theLabel, aSeq))
84 for (Standard_Integer anIter = 1; anIter <= aSeq.Length(); anIter++)
87 if (!XCAFDoc_ShapeTool::GetShape (aSeq.Value (anIter), aShape)) continue;
88 if (!aSeq.Value (anIter).FindAttribute (TDataStd_Name::GetID(), aName)) continue;
89 theMapOfShapeNames.Bind (aShape, aName->Get());
93 if (!hasReferredShape && !hasComponents)
96 if (!XCAFDoc_ShapeTool::GetShape (theLabel, aShape)) return;
97 aShape.Move (theLocation);
98 theMapOfShapeNames.Bind (aShape, thePrevName->Get());
103 //=======================================================================
104 //function : IGESCAFControl_Writer
106 //=======================================================================
108 IGESCAFControl_Writer::IGESCAFControl_Writer () :
109 myColorMode( Standard_True ),
110 myNameMode ( Standard_True ),
111 myLayerMode( Standard_True )
115 //=======================================================================
116 //function : IGESCAFControl_Writer
118 //=======================================================================
120 IGESCAFControl_Writer::IGESCAFControl_Writer (const Handle(XSControl_WorkSession)& WS,
121 const Standard_Boolean /*scratch*/ )
123 // this code does things in a wrong way, it should be vice-versa
124 WS->SetModel ( Model() );
125 WS->SetMapWriter ( TransferProcess() );
126 myColorMode = Standard_True;
127 myNameMode = Standard_True;
128 myLayerMode = Standard_True;
130 // SetWS (WS,scratch); // this should be the only required command here
133 //=======================================================================
134 //function : Transfer
136 //=======================================================================
138 Standard_Boolean IGESCAFControl_Writer::Transfer (const Handle(TDocStd_Document) &doc)
140 // translate free top-level shapes of the DECAF document
141 Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool( doc->Main() );
142 if ( STool.IsNull() ) return Standard_False;
144 TDF_LabelSequence labels;
145 STool->GetFreeShapes ( labels );
146 return Transfer (labels);
149 //=======================================================================
152 //=======================================================================
154 Standard_Boolean IGESCAFControl_Writer::Perform (const Handle(TDocStd_Document) &doc,
155 const Standard_CString filename)
157 if ( ! Transfer ( doc ) ) return Standard_False;
158 return Write ( filename ) == IFSelect_RetDone;
161 //=======================================================================
164 //=======================================================================
166 Standard_Boolean IGESCAFControl_Writer::Perform (const Handle(TDocStd_Document) &doc,
167 const TCollection_AsciiString &filename)
169 if ( ! Transfer ( doc ) ) return Standard_False;
170 return Write ( filename.ToCString() ) == IFSelect_RetDone;
173 //=======================================================================
174 //function : Transfer
176 //=======================================================================
178 Standard_Boolean IGESCAFControl_Writer::Transfer (const TDF_LabelSequence& labels)
180 if ( labels.Length() <=0 ) return Standard_False;
181 for ( Standard_Integer i=1; i <= labels.Length(); i++ ) {
182 TopoDS_Shape shape = XCAFDoc_ShapeTool::GetShape ( labels.Value(i) );
183 if ( ! shape.IsNull() )
185 // IGESControl_Writer::Transfer ( shape );
189 if ( GetColorMode() )
190 WriteAttributes ( labels );
193 if ( GetLayerMode() )
194 WriteLayers ( labels );
198 WriteNames( labels );
201 // WS()->ComputeGraph ( Standard_True );
204 return Standard_True;
207 //=======================================================================
208 //function : WriteAttributes
210 //=======================================================================
212 Standard_Boolean IGESCAFControl_Writer::WriteAttributes (const TDF_LabelSequence& labels)
215 if ( labels.Length() <=0 ) return Standard_False;
216 for ( Standard_Integer i=1; i <= labels.Length(); i++ ) {
217 TDF_Label L = labels.Value(i);
219 // collect color settings
220 XCAFPrs_DataMapOfShapeStyle settings;
222 XCAFPrs::CollectStyleSettings ( L, loc, settings );
223 if ( settings.Extent() <=0 ) continue;
225 // get a target shape and try to find corresponding context
226 // (all the colors set under that label will be put into that context)
228 if ( ! XCAFDoc_ShapeTool::GetShape ( L, S ) ) continue;
230 // iterate on subshapes and create IGES styles
231 XCAFPrs_DataMapOfStyleTransient colors;
232 TopTools_MapOfShape Map;
233 const XCAFPrs_Style inherit;
234 MakeColors ( S, settings, colors, Map, inherit );
237 return Standard_True;
240 //=======================================================================
241 //function : MakeColors
243 //=======================================================================
245 void IGESCAFControl_Writer::MakeColors (const TopoDS_Shape &S,
246 const XCAFPrs_DataMapOfShapeStyle &settings,
247 XCAFPrs_DataMapOfStyleTransient &colors,
248 TopTools_MapOfShape &Map,
249 const XCAFPrs_Style &inherit)
251 // skip already processed shapes
252 if ( ! Map.Add ( S ) ) return;
254 // check if shape has its own style (or inherits from ancestor)
255 XCAFPrs_Style style = inherit;
256 if ( settings.IsBound(S) ) {
257 XCAFPrs_Style own = settings.Find(S);
258 if ( own.IsSetColorCurv() ) style.SetColorCurv ( own.GetColorCurv() );
259 if ( own.IsSetColorSurf() ) style.SetColorSurf ( own.GetColorSurf() );
262 // analyze whether current entity should get a color
263 Standard_Boolean hasColor = Standard_False;
265 if ( S.ShapeType() == TopAbs_FACE ) {
266 if ( style.IsSetColorSurf() ) {
267 hasColor = Standard_True;
268 col = style.GetColorSurf();
271 else if ( S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE ) {
272 if ( style.IsSetColorCurv() ) {
273 hasColor = Standard_True;
274 col = style.GetColorCurv();
278 // if color has to be assigned, try to do this
280 Handle(IGESGraph_Color) colent;
281 Standard_Integer rank = IGESCAFControl::EncodeColor ( col );
283 XCAFPrs_Style c; // style used as key in the map
284 c.SetColorSurf ( col );
285 if ( colors.IsBound ( c ) ) {
286 colent = Handle(IGESGraph_Color)::DownCast ( colors.Find(c) );
289 Handle(TCollection_HAsciiString) str =
290 new TCollection_HAsciiString ( col.StringName ( col.Name() ) );
291 colent = new IGESGraph_Color;
292 colent->Init ( col.Red() * 100., col.Green() * 100., col.Blue() * 100., str );
293 AddEntity ( colent );
294 colors.Bind ( c, colent );
297 Handle(Transfer_FinderProcess) FP = TransferProcess();
298 Handle(IGESData_IGESEntity) ent;
299 Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper ( FP, S );
300 if ( FP->FindTypedTransient ( mapper, STANDARD_TYPE(IGESData_IGESEntity), ent ) ) {
301 ent->InitColor ( colent, rank );
304 // may be S was splited during shape process
305 Handle(Transfer_Binder) bnd = FP->Find ( mapper );
306 if ( ! bnd.IsNull() ) {
307 Handle(Transfer_TransientListBinder) TransientListBinder =
308 //Handle(Transfer_TransientListBinder)::DownCast( bnd->Next(Standard_True) );
309 Handle(Transfer_TransientListBinder)::DownCast( bnd );
310 Standard_Integer i=0, nb=0;
311 if (! TransientListBinder.IsNull() ) {
312 nb = TransientListBinder->NbTransients();
313 for (i=1; i<=nb; i++) {
314 Handle(Standard_Transient) t = TransientListBinder->Transient(i);
315 ent = Handle(IGESData_IGESEntity)::DownCast(t);
316 if (!ent.IsNull()) ent->InitColor ( colent, rank );
319 /* // alternative: consider recursive mapping S -> compound -> entities
321 TopoDS_Shape comp = TransferBRep::ShapeResult(bnd);
322 if ( ! comp.IsNull() && comp.ShapeType() < S.ShapeType() )
323 for ( TopoDS_Iterator it(comp); it.More(); it.Next() ) {
324 MakeColors ( it.Value(), settings, colors, Map, style );
332 // iterate on subshapes (except vertices :)
333 if ( S.ShapeType() == TopAbs_EDGE ) return;
334 for ( TopoDS_Iterator it(S); it.More(); it.Next() ) {
335 MakeColors ( it.Value(), settings, colors, Map, style );
340 static void AttachLayer (const Handle(Transfer_FinderProcess) &FP,
341 const Handle(XCAFDoc_LayerTool)& LTool,
342 const TopoDS_Shape& aSh,
343 const Standard_Integer localIntName)
346 TopTools_SequenceOfShape shseq;
347 if ( aSh.ShapeType() == TopAbs_COMPOUND ) {
348 TopoDS_Iterator aShIt(aSh);
349 for ( ; aShIt.More(); aShIt.Next() ) {
350 TopoDS_Shape newSh = aShIt.Value();
351 Handle(TColStd_HSequenceOfExtendedString) shLayers = new TColStd_HSequenceOfExtendedString;
352 if (! LTool->GetLayers( newSh, shLayers) || newSh.ShapeType() == TopAbs_COMPOUND )
353 AttachLayer(FP, LTool, newSh, localIntName);
356 } else if ( aSh.ShapeType() == TopAbs_SOLID || aSh.ShapeType() == TopAbs_SHELL ) {
357 for (TopExp_Explorer exp(aSh,TopAbs_FACE) ; exp.More(); exp.Next()) {
358 TopoDS_Face entSh = TopoDS::Face (exp.Current());
365 for (Standard_Integer i = 1; i <= shseq.Length(); i++ ) {
366 TopoDS_Shape localShape = shseq.Value(i);
367 Handle(IGESData_IGESEntity) Igesent;
368 Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper ( FP, localShape );
369 if ( FP->FindTypedTransient ( mapper, STANDARD_TYPE(IGESData_IGESEntity), Igesent ) ) {
370 Igesent->InitLevel( 0, localIntName );
372 #ifdef IGESCAFCONTROL_DEB
373 else cout << "Warning: Can't find entity for shape in mapper" << endl;
379 static void MakeLayers (const Handle(Transfer_FinderProcess) &FP,
380 const Handle(XCAFDoc_ShapeTool)& STool,
381 const Handle(XCAFDoc_LayerTool)& LTool,
382 const TDF_LabelSequence& aShapeLabels,
383 const Standard_Integer localIntName)
385 for ( Standard_Integer j = 1; j <= aShapeLabels.Length(); j++ ) {
386 TDF_Label aShapeLabel = aShapeLabels.Value(j);
388 if ( ! STool->GetShape ( aShapeLabel, aSh ) ) continue;
389 AttachLayer (FP, LTool, aSh, localIntName);
395 //=======================================================================
396 //function : WriteLayers
398 //=======================================================================
400 Standard_Boolean IGESCAFControl_Writer::WriteLayers (const TDF_LabelSequence& labels)
402 if ( labels.Length() <=0 ) return Standard_False;
403 Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool( labels(1) );
404 if ( STool.IsNull() ) return Standard_False;
405 Handle(XCAFDoc_LayerTool) LTool = XCAFDoc_DocumentTool::LayerTool( labels(1) );
406 if ( LTool.IsNull() ) return Standard_False;
408 Standard_Integer globalIntName = 0;
409 TDF_LabelSequence aLayerLabels;
410 LTool->GetLayerLabels( aLayerLabels );
412 Handle(Transfer_FinderProcess) FP = TransferProcess();
413 for ( Standard_Integer i = 1; i <= aLayerLabels.Length(); i++ ){
414 TDF_Label aOneLayerL = aLayerLabels.Value(i);
415 if ( aOneLayerL.IsNull() ) continue;
416 TCollection_ExtendedString localName;
417 LTool->GetLayer(aOneLayerL, localName);
418 Standard_Integer localIntName = 0;
419 TCollection_AsciiString asciiName(localName,'?');
420 if (asciiName.IsIntegerValue() ) {
421 localIntName = asciiName.IntegerValue();
422 if (globalIntName < localIntName) globalIntName = localIntName;
424 TDF_LabelSequence aShapeLabels;
425 LTool->GetShapesOfLayer( aOneLayerL, aShapeLabels );
426 if ( aShapeLabels.Length() <= 0 ) continue;
427 MakeLayers(FP, STool, LTool, aShapeLabels, localIntName);
431 for ( Standard_Integer i1 = 1; i1 <= aLayerLabels.Length(); i1++ ) {
432 TDF_Label aOneLayerL = aLayerLabels.Value(i1);
433 if ( aOneLayerL.IsNull() ) continue;
434 TCollection_ExtendedString localName;
435 LTool->GetLayer(aOneLayerL, localName);
436 Standard_Integer localIntName = 0;
437 TCollection_AsciiString asciiName(localName,'?');
438 if (asciiName.IsIntegerValue() ) continue;
439 TDF_LabelSequence aShapeLabels;
440 LTool->GetShapesOfLayer( aOneLayerL, aShapeLabels );
441 if ( aShapeLabels.Length() <= 0 ) continue;
442 localIntName = ++globalIntName;
443 MakeLayers (FP, STool, LTool, aShapeLabels, localIntName);
446 return Standard_True;
450 //=======================================================================
451 //function : WriteNames
453 //=======================================================================
455 Standard_Boolean IGESCAFControl_Writer::WriteNames (const TDF_LabelSequence& theLabels)
457 if (theLabels.Length() <= 0) return Standard_False;
459 DataMapOfShapeNames aMapOfShapeNames;
461 for (Standard_Integer anIter = 1; anIter <= theLabels.Length(); anIter++ )
463 TDF_Label aLabel = theLabels.Value (anIter);
466 Handle(TDataStd_Name) aName;
467 if (!XCAFDoc_ShapeTool::GetShape (aLabel, aShape)) continue;
468 if (!aLabel.FindAttribute (TDataStd_Name::GetID(), aName)) continue;
470 aMapOfShapeNames.Bind (aShape, aName->Get());
472 // Collect names for subshapes
473 TopLoc_Location aLocation;
474 CollectShapeNames (aLabel, aLocation, aName, aMapOfShapeNames);
477 for (DataMapOfShapeNames::Iterator anIter (aMapOfShapeNames);
478 anIter.More(); anIter.Next())
480 const TopoDS_Shape& aShape = anIter.Key();
481 const TCollection_ExtendedString& aName = anIter.Value();
483 Handle(Transfer_FinderProcess) aFinderProcess = TransferProcess();
484 Handle(IGESData_IGESEntity) anIGESEntity;
485 Handle(TransferBRep_ShapeMapper) aShapeMapper = TransferBRep::ShapeMapper (aFinderProcess, aShape);
487 if (aFinderProcess->FindTypedTransient (aShapeMapper, STANDARD_TYPE(IGESData_IGESEntity), anIGESEntity))
489 Handle(TCollection_HAsciiString) anAsciiName = new TCollection_HAsciiString (" ");
490 Standard_Integer aNameLength = 8 - aName.Length();
491 if (aNameLength < 0) aNameLength = 0;
492 for (Standard_Integer aCharPos = 1; aNameLength < 8; aCharPos++, aNameLength++)
494 anAsciiName->SetValue (aNameLength+1, IsAnAscii (aName.Value (aCharPos)) ? (Standard_Character )aName.Value (aCharPos) : '?');
496 anIGESEntity->SetLabel (anAsciiName);
500 return Standard_True;
503 //=======================================================================
504 //function : SetColorMode
506 //=======================================================================
508 void IGESCAFControl_Writer::SetColorMode (const Standard_Boolean colormode)
510 myColorMode = colormode;
513 //=======================================================================
514 //function : GetColorMode
516 //=======================================================================
518 Standard_Boolean IGESCAFControl_Writer::GetColorMode () const
523 //=======================================================================
524 //function : SetNameMode
526 //=======================================================================
528 void IGESCAFControl_Writer::SetNameMode (const Standard_Boolean namemode)
530 myNameMode = namemode;
533 //=======================================================================
534 //function : GetNameMode
536 //=======================================================================
538 Standard_Boolean IGESCAFControl_Writer::GetNameMode () const
543 //=======================================================================
544 //function : SetLayerMode
546 //=======================================================================
548 void IGESCAFControl_Writer::SetLayerMode (const Standard_Boolean layermode)
550 myLayerMode = layermode;
553 //=======================================================================
554 //function : GetLayerMode
556 //=======================================================================
558 Standard_Boolean IGESCAFControl_Writer::GetLayerMode () const