0031382: Data Exchange - BinXCAF should preserve length unit information
[occt.git] / src / IGESCAFControl / IGESCAFControl_Writer.cxx
1 // Created on: 2000-08-17
2 // Created by: Andrey BETENEV
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <IGESCAFControl.hxx>
17 #include <IGESCAFControl_Writer.hxx>
18 #include <IGESData_IGESEntity.hxx>
19 #include <IGESData_IGESModel.hxx>
20 #include <IGESData_NameEntity.hxx>
21 #include <IGESGraph_Color.hxx>
22 #include <IGESGraph_DefinitionLevel.hxx>
23 #include <IGESSolid_Face.hxx>
24 #include <IGESBasic_Name.hxx>
25 #include <Message_ProgressScope.hxx>
26 #include <NCollection_DataMap.hxx>
27 #include <Standard_Transient.hxx>
28 #include <TCollection_AsciiString.hxx>
29 #include <TCollection_HAsciiString.hxx>
30 #include <TCollection_HExtendedString.hxx>
31 #include <TColStd_HSequenceOfExtendedString.hxx>
32 #include <TDataStd_Name.hxx>
33 #include <TDF_ChildIterator.hxx>
34 #include <TDF_Label.hxx>
35 #include <TDF_LabelSequence.hxx>
36 #include <TDocStd_Document.hxx>
37 #include <TopAbs.hxx>
38 #include <TopExp_Explorer.hxx>
39 #include <TopoDS.hxx>
40 #include <TopoDS_Face.hxx>
41 #include <TopoDS_Iterator.hxx>
42 #include <TopoDS_Shape.hxx>
43 #include <TopTools_SequenceOfShape.hxx>
44 #include <Transfer_FinderProcess.hxx>
45 #include <Transfer_TransientListBinder.hxx>
46 #include <TransferBRep.hxx>
47 #include <TransferBRep_ShapeMapper.hxx>
48 #include <XCAFDoc_ColorTool.hxx>
49 #include <XCAFDoc_DocumentTool.hxx>
50 #include <XCAFDoc_LayerTool.hxx>
51 #include <XCAFDoc_LengthUnit.hxx>
52 #include <XCAFDoc_ShapeTool.hxx>
53 #include <XCAFPrs.hxx>
54 #include <XCAFPrs_Style.hxx>
55 #include <XSAlgo.hxx>
56 #include <XSAlgo_AlgoContainer.hxx>
57 #include <XSControl_WorkSession.hxx>
58 #include <UnitsMethods.hxx>
59
60 namespace
61 {
62   typedef NCollection_DataMap<TopoDS_Shape, TCollection_ExtendedString> DataMapOfShapeNames;
63
64   void  CollectShapeNames (const TDF_Label& theLabel,
65                            const TopLoc_Location& theLocation,
66                            const Handle(TDataStd_Name)& thePrevName,
67                            DataMapOfShapeNames& theMapOfShapeNames)
68   {
69     Standard_Boolean hasReferredShape = Standard_False;
70     Standard_Boolean hasComponents    = Standard_False;
71     TDF_Label aReferredLabel;
72
73     Handle(TDataStd_Name) aName;
74     theLabel.FindAttribute (TDataStd_Name::GetID(), aName);
75
76     if ( XCAFDoc_ShapeTool::GetReferredShape ( theLabel, aReferredLabel ) )
77     {
78       TopLoc_Location aSubLocation = theLocation.Multiplied ( XCAFDoc_ShapeTool::GetLocation ( theLabel ) );
79       CollectShapeNames (aReferredLabel, aSubLocation, aName, theMapOfShapeNames);
80       hasReferredShape = Standard_True;
81     }
82
83     TDF_LabelSequence aSeq;
84     if (XCAFDoc_ShapeTool::GetComponents (theLabel, aSeq))
85     {
86       for (Standard_Integer anIter = 1; anIter <= aSeq.Length(); anIter++)
87       {
88         CollectShapeNames (aSeq.Value (anIter), theLocation, aName, theMapOfShapeNames );
89       }
90       hasComponents = Standard_True;
91     }
92
93     aSeq.Clear();
94     if (XCAFDoc_ShapeTool::GetSubShapes (theLabel, aSeq))
95     {
96       for (Standard_Integer anIter = 1; anIter <= aSeq.Length(); anIter++)
97       {
98         TopoDS_Shape aShape;
99         if (!XCAFDoc_ShapeTool::GetShape (aSeq.Value (anIter), aShape)) continue;
100         if (!aSeq.Value (anIter).FindAttribute (TDataStd_Name::GetID(), aName)) continue;
101         theMapOfShapeNames.Bind (aShape, aName->Get());
102       }
103     }
104
105     if (!hasReferredShape && !hasComponents)
106     {
107       TopoDS_Shape aShape;
108       if (!XCAFDoc_ShapeTool::GetShape (theLabel, aShape)) return;
109       aShape.Move (theLocation, Standard_False);
110       theMapOfShapeNames.Bind (aShape, thePrevName->Get());
111     }
112   }
113 }
114
115 //=======================================================================
116 //function : IGESCAFControl_Writer
117 //purpose  : 
118 //=======================================================================
119
120 IGESCAFControl_Writer::IGESCAFControl_Writer () :
121        myColorMode( Standard_True ),
122        myNameMode ( Standard_True ),
123        myLayerMode( Standard_True )
124 {
125 }
126
127 //=======================================================================
128 //function : IGESCAFControl_Writer
129 //purpose  : 
130 //=======================================================================
131
132 IGESCAFControl_Writer::IGESCAFControl_Writer (const Handle(XSControl_WorkSession)& WS,
133                                               const Standard_Boolean /*scratch*/ )
134 {
135   // this code does things in a wrong way, it should be vice-versa
136   WS->SetModel ( Model() );
137   WS->SetMapWriter ( TransferProcess() );
138   myColorMode = Standard_True;
139   myNameMode = Standard_True;
140   myLayerMode = Standard_True;
141   
142 //  SetWS (WS,scratch); // this should be the only required command here
143 }
144
145 //=======================================================================
146 //function : Transfer
147 //purpose  : 
148 //=======================================================================
149
150 Standard_Boolean IGESCAFControl_Writer::Transfer (const Handle(TDocStd_Document) &doc,
151                                                   const Message_ProgressRange& theProgress)
152 {  
153   // translate free top-level shapes of the DECAF document
154   Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool( doc->Main() );
155   if ( STool.IsNull() ) return Standard_False;
156
157   TDF_LabelSequence labels;
158   STool->GetFreeShapes ( labels );
159   return Transfer (labels, theProgress);
160 }  
161
162 //=======================================================================
163 //function : Transfer
164 //purpose  : 
165 //=======================================================================
166
167 Standard_Boolean IGESCAFControl_Writer::Transfer (const TDF_Label& label,
168                                                   const Message_ProgressRange& theProgress)
169 {
170   TDF_LabelSequence labels;
171   labels.Append( label );
172   return Transfer( labels, theProgress );
173 }
174
175 //=======================================================================
176 //function : Transfer
177 //purpose  : 
178 //=======================================================================
179
180 Standard_Boolean IGESCAFControl_Writer::Transfer (const TDF_LabelSequence& labels,
181                                                   const Message_ProgressRange& theProgress)
182 {  
183   if ( labels.Length() <=0 ) return Standard_False;
184   prepareUnit(labels.First()); // set local length unit to the model
185   Message_ProgressScope aPS(theProgress, "Labels", labels.Length());
186   for ( Standard_Integer i=1; i <= labels.Length() && aPS.More(); i++ )
187   {
188     TopoDS_Shape shape = XCAFDoc_ShapeTool::GetShape ( labels.Value(i) );
189     if ( ! shape.IsNull() ) 
190       AddShape (shape, aPS.Next());
191 //      IGESControl_Writer::Transfer ( shape );
192   }
193   
194   // write colors
195   if ( GetColorMode() )
196     WriteAttributes ( labels );
197
198   // write layers
199   if ( GetLayerMode() )
200     WriteLayers ( labels );
201   
202   // write names
203   if ( GetNameMode() )
204     WriteNames( labels );
205   
206   // refresh graph
207 //  WS()->ComputeGraph ( Standard_True );
208   ComputeModel();
209   
210   return Standard_True;
211 }
212
213 //=======================================================================
214 //function : Perform
215 //purpose  : 
216 //=======================================================================
217
218 Standard_Boolean IGESCAFControl_Writer::Perform (const Handle(TDocStd_Document) &doc,
219                                                  const Standard_CString filename,
220                                                  const Message_ProgressRange& theProgress)
221 {
222   if ( ! Transfer ( doc, theProgress ) ) return Standard_False;
223   return Write ( filename ) == IFSelect_RetDone;
224 }
225   
226 //=======================================================================
227 //function : Perform
228 //purpose  : 
229 //=======================================================================
230
231 Standard_Boolean IGESCAFControl_Writer::Perform (const Handle(TDocStd_Document) &doc,
232                                                  const TCollection_AsciiString &filename,
233                                                  const Message_ProgressRange& theProgress)
234 {
235   if ( ! Transfer ( doc, theProgress ) ) return Standard_False;
236   return Write ( filename.ToCString() ) == IFSelect_RetDone;
237 }
238   
239 //=======================================================================
240 //function : WriteAttributes
241 //purpose  : 
242 //=======================================================================
243
244 Standard_Boolean IGESCAFControl_Writer::WriteAttributes (const TDF_LabelSequence& labels) 
245 {
246   // Iterate on labels
247   if ( labels.Length() <=0 ) return Standard_False;
248   for ( Standard_Integer i=1; i <= labels.Length(); i++ ) {
249     TDF_Label L = labels.Value(i);
250
251     // collect color settings
252     XCAFPrs_IndexedDataMapOfShapeStyle settings;
253     TopLoc_Location loc;
254     XCAFPrs::CollectStyleSettings ( L, loc, settings );
255     if ( settings.Extent() <=0 ) continue;
256     
257     // get a target shape and try to find corresponding context
258     // (all the colors set under that label will be put into that context)
259     TopoDS_Shape S;
260     if ( ! XCAFDoc_ShapeTool::GetShape ( L, S ) ) continue;
261         
262     // iterate on subshapes and create IGES styles 
263     XCAFPrs_DataMapOfStyleTransient colors;
264     TopTools_MapOfShape Map;
265     const XCAFPrs_Style inherit;
266     MakeColors ( S, settings, colors, Map, inherit );
267   }
268   
269   return Standard_True;
270 }
271
272 //=======================================================================
273 //function : MakeColors
274 //purpose  : 
275 //=======================================================================
276
277 void IGESCAFControl_Writer::MakeColors (const TopoDS_Shape &S, 
278                                         const XCAFPrs_IndexedDataMapOfShapeStyle &settings,
279                                         XCAFPrs_DataMapOfStyleTransient &colors,
280                                         TopTools_MapOfShape &Map,
281                                         const XCAFPrs_Style &inherit) 
282 {
283   // skip already processed shapes
284   if ( ! Map.Add ( S ) ) return;
285   
286   // check if shape has its own style (or inherits from ancestor)
287   XCAFPrs_Style style = inherit;
288   if ( settings.Contains(S) ) {
289     XCAFPrs_Style own = settings.FindFromKey(S);
290     if ( own.IsSetColorCurv() ) style.SetColorCurv ( own.GetColorCurv() );
291     if ( own.IsSetColorSurf() ) style.SetColorSurf ( own.GetColorSurf() );
292     style.SetMaterial (own.Material());
293   }
294   
295   // analyze whether current entity should get a color 
296   Standard_Boolean hasColor = Standard_False;
297   Quantity_Color col;
298   if ( S.ShapeType() == TopAbs_FACE  || S.ShapeType() == TopAbs_SOLID) {
299     if ( style.IsSetColorSurf() ) {
300       hasColor = Standard_True;
301       col = style.GetColorSurf();
302     }
303     else if (!style.Material().IsNull()
304           && !style.Material()->IsEmpty())
305     {
306       hasColor = Standard_True;
307       col = style.Material()->BaseColor().GetRGB();
308     }
309   }
310   else if ( S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE ) {
311     if ( style.IsSetColorCurv() ) {
312       hasColor = Standard_True;
313       col = style.GetColorCurv();
314     }
315   }
316   
317   // if color has to be assigned, try to do this
318   if ( hasColor ) {
319     Handle(IGESGraph_Color) colent;
320     Standard_Integer rank = IGESCAFControl::EncodeColor ( col );
321     if ( ! rank ) {
322       XCAFPrs_Style c; // style used as key in the map
323       c.SetColorSurf ( col );
324       if ( colors.IsBound ( c ) ) {
325         colent = Handle(IGESGraph_Color)::DownCast ( colors.Find(c) );
326       }
327       else {
328         Handle(TCollection_HAsciiString) str = 
329           new TCollection_HAsciiString ( col.StringName ( col.Name() ) );
330         colent = new IGESGraph_Color;
331         NCollection_Vec3<Standard_Real> aColor_sRGB;
332         col.Values (aColor_sRGB.r(), aColor_sRGB.g(), aColor_sRGB.b(), Quantity_TOC_sRGB);
333         colent->Init ( aColor_sRGB.r() * 100., aColor_sRGB.g() * 100., aColor_sRGB.b() * 100., str );
334         AddEntity ( colent );
335         colors.Bind ( c, colent );
336       }
337     }
338     Handle(Transfer_FinderProcess) FP = TransferProcess();
339     Handle(IGESData_IGESEntity) ent;
340     Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper ( FP, S );
341     Handle(TransferBRep_ShapeMapper) aNoLocMapper = TransferBRep::ShapeMapper(FP, S.Located(TopLoc_Location()));
342     if ( FP->FindTypedTransient ( mapper, STANDARD_TYPE(IGESData_IGESEntity), ent ) || 
343          FP->FindTypedTransient(aNoLocMapper, STANDARD_TYPE(IGESData_IGESEntity), ent)) {
344       ent->InitColor ( colent, rank );
345       Handle(IGESSolid_Face) ent_f = Handle(IGESSolid_Face)::DownCast(ent);
346       if (!ent_f.IsNull())
347       {
348         if (!ent_f->Surface().IsNull())
349           ent_f->Surface()->InitColor ( colent, rank );
350       }
351     }
352     else {
353       // may be S was splited during shape process
354       Handle(Transfer_Binder) bnd = FP->Find ( mapper );
355       if ( ! bnd.IsNull() ) {
356         Handle(Transfer_TransientListBinder) TransientListBinder =
357           //Handle(Transfer_TransientListBinder)::DownCast( bnd->Next(Standard_True) );
358           Handle(Transfer_TransientListBinder)::DownCast( bnd );
359         Standard_Integer i=0, nb=0;
360         if (! TransientListBinder.IsNull() ) {
361           nb = TransientListBinder->NbTransients();
362           for (i=1; i<=nb; i++) {
363             Handle(Standard_Transient) t = TransientListBinder->Transient(i);
364             ent = Handle(IGESData_IGESEntity)::DownCast(t);
365             if (!ent.IsNull())
366       {
367         ent->InitColor ( colent, rank );
368         Handle(IGESSolid_Face) ent_f = Handle(IGESSolid_Face)::DownCast(ent);
369         if (!ent_f.IsNull())
370         {
371           if (!ent_f->Surface().IsNull())
372             ent_f->Surface()->InitColor ( colent, rank );
373         }
374       }
375           }
376         }
377         /* // alternative: consider recursive mapping S -> compound -> entities
378         else {
379           TopoDS_Shape comp = TransferBRep::ShapeResult(bnd);
380           if ( ! comp.IsNull() && comp.ShapeType() < S.ShapeType() ) 
381             for ( TopoDS_Iterator it(comp); it.More(); it.Next() ) {
382               MakeColors ( it.Value(), settings, colors, Map, style );
383             }
384         }
385         */
386       }
387     }
388   }
389
390   // iterate on subshapes (except vertices :)
391   if ( S.ShapeType() == TopAbs_EDGE ) return;
392   for ( TopoDS_Iterator it(S); it.More(); it.Next() ) {
393     MakeColors ( it.Value(), settings, colors, Map, style );
394   }
395 }
396
397
398 static void AttachLayer (const Handle(Transfer_FinderProcess) &FP,
399                          const Handle(XCAFDoc_LayerTool)& LTool,
400                          const TopoDS_Shape& aSh,
401                          const Standard_Integer localIntName)
402 {
403
404   TopTools_SequenceOfShape shseq;
405   if ( aSh.ShapeType() == TopAbs_COMPOUND ) {
406     TopoDS_Iterator aShIt(aSh);
407     for ( ; aShIt.More(); aShIt.Next() ) {
408       TopoDS_Shape newSh = aShIt.Value();
409       Handle(TColStd_HSequenceOfExtendedString) shLayers = new TColStd_HSequenceOfExtendedString;
410       if (! LTool->GetLayers( newSh, shLayers) || newSh.ShapeType() == TopAbs_COMPOUND )
411         AttachLayer(FP, LTool, newSh, localIntName);
412     }
413     return;
414   } else if ( aSh.ShapeType() == TopAbs_SOLID || aSh.ShapeType() == TopAbs_SHELL ) {
415     for (TopExp_Explorer exp(aSh,TopAbs_FACE) ; exp.More(); exp.Next()) {
416       TopoDS_Face entSh = TopoDS::Face (exp.Current());
417       shseq.Append(entSh);
418     }
419   } else {
420     shseq.Append(aSh);
421   }
422   
423   for (Standard_Integer i = 1; i <= shseq.Length(); i++ ) {
424     TopoDS_Shape localShape = shseq.Value(i);
425     Handle(IGESData_IGESEntity) Igesent;
426     Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper ( FP, localShape );
427     if ( FP->FindTypedTransient ( mapper, STANDARD_TYPE(IGESData_IGESEntity), Igesent ) ) {
428       Igesent->InitLevel( 0, localIntName );
429     }
430 #ifdef OCCT_DEBUG
431     else std::cout << "Warning: Can't find entity for shape in mapper" << std::endl;
432 #endif
433   }
434 }
435
436
437 static void MakeLayers (const Handle(Transfer_FinderProcess) &FP, 
438                         const Handle(XCAFDoc_ShapeTool)& STool,
439                         const Handle(XCAFDoc_LayerTool)& LTool,
440                         const TDF_LabelSequence& aShapeLabels,
441                         const Standard_Integer localIntName) 
442 {
443   for ( Standard_Integer j = 1; j <= aShapeLabels.Length(); j++ ) {
444     TDF_Label aShapeLabel = aShapeLabels.Value(j);
445     TopoDS_Shape aSh;
446     if ( ! STool->GetShape ( aShapeLabel, aSh ) ) continue;
447     AttachLayer (FP, LTool, aSh, localIntName);
448   }
449 }
450
451
452
453 //=======================================================================
454 //function : WriteLayers
455 //purpose  : 
456 //=======================================================================
457
458 Standard_Boolean IGESCAFControl_Writer::WriteLayers (const TDF_LabelSequence& labels) 
459 {
460   if ( labels.Length() <=0 ) return Standard_False;
461   Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool( labels(1) );
462   if ( STool.IsNull() ) return Standard_False;
463   Handle(XCAFDoc_LayerTool) LTool = XCAFDoc_DocumentTool::LayerTool( labels(1) );
464   if ( LTool.IsNull() ) return Standard_False;
465   
466   Standard_Integer globalIntName = 0;
467   TDF_LabelSequence aLayerLabels;
468   LTool->GetLayerLabels( aLayerLabels );
469   
470   Handle(Transfer_FinderProcess) FP = TransferProcess();
471   for ( Standard_Integer i = 1; i <= aLayerLabels.Length(); i++ ){
472     TDF_Label aOneLayerL = aLayerLabels.Value(i);
473     if ( aOneLayerL.IsNull() ) continue;
474     TCollection_ExtendedString localName;
475     LTool->GetLayer(aOneLayerL, localName);
476     Standard_Integer localIntName = 0;
477     TCollection_AsciiString asciiName(localName,'?');
478     if (asciiName.IsIntegerValue() ) {
479       localIntName = asciiName.IntegerValue();
480       if (globalIntName < localIntName) globalIntName = localIntName;
481       
482       TDF_LabelSequence aShapeLabels;
483       LTool->GetShapesOfLayer( aOneLayerL, aShapeLabels );
484       if ( aShapeLabels.Length() <= 0 ) continue;
485       MakeLayers(FP, STool, LTool, aShapeLabels, localIntName);
486     }
487   }
488   
489   for ( Standard_Integer i1 = 1; i1 <= aLayerLabels.Length(); i1++ ) {
490     TDF_Label aOneLayerL = aLayerLabels.Value(i1);
491     if ( aOneLayerL.IsNull() ) continue;
492     TCollection_ExtendedString localName; 
493     LTool->GetLayer(aOneLayerL, localName);
494     Standard_Integer localIntName = 0;
495     TCollection_AsciiString asciiName(localName,'?');
496     if (asciiName.IsIntegerValue() ) continue;
497     TDF_LabelSequence aShapeLabels;
498     LTool->GetShapesOfLayer( aOneLayerL, aShapeLabels );
499     if ( aShapeLabels.Length() <= 0 ) continue;
500     localIntName = ++globalIntName;
501     MakeLayers (FP, STool, LTool, aShapeLabels, localIntName);
502   }
503   
504   return Standard_True;
505 }
506
507
508 //=======================================================================
509 //function : WriteNames
510 //purpose  : 
511 //=======================================================================
512
513 Standard_Boolean IGESCAFControl_Writer::WriteNames (const TDF_LabelSequence& theLabels)
514 {
515   if (theLabels.Length() <= 0) return Standard_False;
516
517   DataMapOfShapeNames aMapOfShapeNames;
518
519   for (Standard_Integer anIter = 1; anIter <= theLabels.Length(); anIter++ )
520   {
521     TDF_Label aLabel = theLabels.Value (anIter);
522
523     TopoDS_Shape aShape;
524     Handle(TDataStd_Name) aName;
525     if (!XCAFDoc_ShapeTool::GetShape (aLabel, aShape)) continue;
526     if (!aLabel.FindAttribute (TDataStd_Name::GetID(), aName)) continue;
527
528     aMapOfShapeNames.Bind (aShape, aName->Get());
529
530     // Collect names for subshapes
531     TopLoc_Location aLocation;
532     CollectShapeNames (aLabel, aLocation, aName, aMapOfShapeNames);
533   }
534
535   for (DataMapOfShapeNames::Iterator anIter (aMapOfShapeNames);
536        anIter.More(); anIter.Next())
537   {
538     const TopoDS_Shape& aShape = anIter.Key();
539     const TCollection_ExtendedString& aName = anIter.Value();
540
541     Handle(Transfer_FinderProcess) aFinderProcess = TransferProcess();
542     Handle(IGESData_IGESEntity) anIGESEntity;
543     Handle(TransferBRep_ShapeMapper) aShapeMapper = TransferBRep::ShapeMapper (aFinderProcess, aShape);
544
545     if (aFinderProcess->FindTypedTransient (aShapeMapper, STANDARD_TYPE(IGESData_IGESEntity), anIGESEntity))
546     {
547       Handle(TCollection_HAsciiString) anAsciiName = new TCollection_HAsciiString ("        ");
548       Standard_Integer aNameLength = 8 - aName.Length();
549       if (aNameLength < 0) aNameLength = 0;
550       for (Standard_Integer aCharPos = 1; aNameLength < 8; aCharPos++, aNameLength++)
551       {
552         anAsciiName->SetValue (aNameLength+1, IsAnAscii (aName.Value (aCharPos)) ? (Standard_Character )aName.Value (aCharPos) : '?');
553       }
554       anIGESEntity->SetLabel (anAsciiName);
555
556       // Set long IGES name using 406 form 15 entity
557       Handle(IGESBasic_Name) aLongNameEntity = new IGESBasic_Name;
558       Handle(TCollection_HExtendedString) aTmpStr = new TCollection_HExtendedString(aName);
559       aLongNameEntity->Init(1, new TCollection_HAsciiString(aTmpStr, '_'));
560
561       anIGESEntity->AddProperty(aLongNameEntity);
562       AddEntity(aLongNameEntity);
563     }
564   }
565
566   return Standard_True;
567 }
568
569 //=======================================================================
570 //function : prepareUnit
571 //purpose  :
572 //=======================================================================
573 void IGESCAFControl_Writer::prepareUnit(const TDF_Label& theLabel)
574 {
575   Handle(XCAFDoc_LengthUnit) aLengthAttr;
576   if (!theLabel.IsNull() &&
577     theLabel.Root().FindAttribute(XCAFDoc_LengthUnit::GetID(), aLengthAttr))
578   {
579     Model()->ChangeGlobalSection().SetCascadeUnit(aLengthAttr->GetUnitValue() * 1000);
580   }
581   else
582   {
583     XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
584     Model()->ChangeGlobalSection().SetCascadeUnit(UnitsMethods::GetCasCadeLengthUnit());
585   }
586 }
587
588 //=======================================================================
589 //function : SetColorMode
590 //purpose  : 
591 //=======================================================================
592
593 void IGESCAFControl_Writer::SetColorMode (const Standard_Boolean colormode)
594 {
595   myColorMode = colormode;
596 }
597
598 //=======================================================================
599 //function : GetColorMode
600 //purpose  : 
601 //=======================================================================
602
603 Standard_Boolean IGESCAFControl_Writer::GetColorMode () const
604 {
605   return myColorMode;
606 }
607
608 //=======================================================================
609 //function : SetNameMode
610 //purpose  : 
611 //=======================================================================
612
613 void IGESCAFControl_Writer::SetNameMode (const Standard_Boolean namemode)
614 {
615   myNameMode = namemode;
616 }
617
618 //=======================================================================
619 //function : GetNameMode
620 //purpose  : 
621 //=======================================================================
622
623 Standard_Boolean IGESCAFControl_Writer::GetNameMode () const
624 {
625   return myNameMode;
626 }
627
628 //=======================================================================
629 //function : SetLayerMode
630 //purpose  : 
631 //=======================================================================
632
633 void IGESCAFControl_Writer::SetLayerMode (const Standard_Boolean layermode)
634 {
635   myLayerMode = layermode;
636 }
637
638 //=======================================================================
639 //function : GetLayerMode
640 //purpose  : 
641 //=======================================================================
642
643 Standard_Boolean IGESCAFControl_Writer::GetLayerMode () const
644 {
645   return myLayerMode;
646 }