0027104: DownCast() cannot return null for mismatched handle
[occt.git] / src / STEPCAFControl / STEPCAFControl_Writer.cxx
1 // Created on: 2000-08-15
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 // CURRENT LIMITATIONS: 
17 // when val props and names assigned to instance of 
18 // component in assembly, it is in fact supposed that only one CDSR corresponds
19 // to such shape. This can be wrong and should be handled more carefully
20 // (analysis of SDRs which the CDSR links should be done)
21 // Names and validation props are supported for top-level shapes only
22
23 #include <BRep_Builder.hxx>
24 #include <GeomToStep_MakeCartesianPoint.hxx>
25 #include <HeaderSection_FileSchema.hxx>
26 #include <Interface_EntityIterator.hxx>
27 #include <Interface_Static.hxx>
28 #include <Message_Messenger.hxx>
29 #include <MoniTool_DataMapIteratorOfDataMapOfShapeTransient.hxx>
30 #include <OSD_Path.hxx>
31 #include <Quantity_TypeOfColor.hxx>
32 #include <StepAP214_Protocol.hxx>
33 #include <StepAP242_GeometricItemSpecificUsage.hxx>
34 #include <StepBasic_DerivedUnit.hxx>
35 #include <StepBasic_DerivedUnitElement.hxx>
36 #include <StepBasic_HArray1OfDerivedUnitElement.hxx>
37 #include <StepBasic_LengthMeasureWithUnit.hxx>
38 #include <StepBasic_MeasureValueMember.hxx>
39 #include <StepBasic_Product.hxx>
40 #include <StepBasic_ProductDefinition.hxx>
41 #include <StepBasic_ProductDefinitionFormation.hxx>
42 #include <StepBasic_ProductDefinitionRelationship.hxx>
43 #include <StepBasic_SiUnitAndLengthUnit.hxx>
44 #include <StepBasic_SiUnitAndMassUnit.hxx>
45 #include <StepBasic_SiUnitAndPlaneAngleUnit.hxx>
46 #include <STEPCAFControl_ActorWrite.hxx>
47 #include <STEPCAFControl_Controller.hxx>
48 #include <STEPCAFControl_DictionaryOfExternFile.hxx>
49 #include <STEPCAFControl_ExternFile.hxx>
50 #include <STEPCAFControl_IteratorOfDictionaryOfExternFile.hxx>
51 #include <STEPCAFControl_Writer.hxx>
52 #include <STEPConstruct.hxx>
53 #include <STEPConstruct_DataMapOfAsciiStringTransient.hxx>
54 #include <STEPConstruct_DataMapOfPointTransient.hxx>
55 #include <STEPConstruct_ExternRefs.hxx>
56 #include <STEPCAFControl_GDTProperty.hxx>
57 #include <STEPConstruct_Styles.hxx>
58 #include <STEPConstruct_ValidationProps.hxx>
59 #include <STEPControl_StepModelType.hxx>
60 #include <STEPControl_Writer.hxx>
61 #include <StepData_Logical.hxx>
62 #include <StepData_StepModel.hxx>
63 #include <StepDimTol_AngularityTolerance.hxx>
64 #include <StepDimTol_CircularRunoutTolerance.hxx>
65 #include <StepDimTol_CoaxialityTolerance.hxx>
66 #include <StepDimTol_ConcentricityTolerance.hxx>
67 #include <StepDimTol_CylindricityTolerance.hxx>
68 #include <StepDimTol_Datum.hxx>
69 #include <StepDimTol_DatumFeature.hxx>
70 #include <StepDimTol_DatumReference.hxx>
71 #include <StepDimTol_DatumReferenceElement.hxx>
72 #include <StepDimTol_DatumSystem.hxx>
73 #include <StepDimTol_DatumSystemOrReference.hxx>
74 #include <StepDimTol_DatumTarget.hxx>
75 #include <StepDimTol_FlatnessTolerance.hxx>
76 #include <StepDimTol_GeometricToleranceType.hxx>
77 #include <StepDimTol_GeometricToleranceWithDatumReference.hxx>
78 #include <StepDimTol_GeometricToleranceWithModifiers.hxx>
79 #include <StepDimTol_GeoTolAndGeoTolWthDatRef.hxx>
80 #include <StepDimTol_GeoTolAndGeoTolWthDatRefAndGeoTolWthMaxTol.hxx>
81 #include <StepDimTol_GeoTolAndGeoTolWthDatRefAndGeoTolWthMod.hxx>
82 #include <StepDimTol_GeoTolAndGeoTolWthDatRefAndModGeoTolAndPosTol.hxx>
83 #include <StepDimTol_GeoTolAndGeoTolWthMaxTol.hxx>
84 #include <StepDimTol_GeoTolAndGeoTolWthMod.hxx>
85 #include <StepDimTol_HArray1OfDatumReference.hxx>
86 #include <StepDimTol_HArray1OfDatumReferenceElement.hxx>
87 #include <StepDimTol_HArray1OfDatumReferenceModifier.hxx>
88 #include <StepDimTol_HArray1OfDatumSystemOrReference.hxx>
89 #include <StepDimTol_LineProfileTolerance.hxx>
90 #include <StepDimTol_ModifiedGeometricTolerance.hxx>
91 #include <StepDimTol_ParallelismTolerance.hxx>
92 #include <StepDimTol_PerpendicularityTolerance.hxx>
93 #include <StepDimTol_PlacedDatumTargetFeature.hxx>
94 #include <StepDimTol_PositionTolerance.hxx>
95 #include <StepDimTol_RoundnessTolerance.hxx>
96 #include <StepDimTol_RunoutZoneDefinition.hxx>
97 #include <StepDimTol_RunoutZoneOrientation.hxx>
98 #include <StepDimTol_StraightnessTolerance.hxx>
99 #include <StepDimTol_SurfaceProfileTolerance.hxx>
100 #include <StepDimTol_SymmetryTolerance.hxx>
101 #include <StepDimTol_ToleranceZone.hxx>
102 #include <StepDimTol_ToleranceZoneForm.hxx>
103 #include <StepDimTol_TotalRunoutTolerance.hxx>
104 #include <StepGeom_Axis2Placement3d.hxx>
105 #include <StepGeom_CartesianPoint.hxx>
106 #include <StepGeom_Direction.hxx>
107 #include <StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext.hxx>
108 #include <StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx.hxx>
109 #include <StepGeom_Surface.hxx>
110 #include <StepRepr_CompGroupShAspAndCompShAspAndDatumFeatAndShAsp.hxx>
111 #include <StepRepr_CompositeShapeAspect.hxx>
112 #include <StepRepr_DescriptiveRepresentationItem.hxx>
113 #include <StepRepr_FeatureForDatumTargetRelationship.hxx>
114 #include <StepRepr_HArray1OfRepresentationItem.hxx>
115 #include <StepRepr_MeasureRepresentationItem.hxx>
116 #include <StepRepr_NextAssemblyUsageOccurrence.hxx>
117 #include <StepRepr_ProductDefinitionShape.hxx>
118 #include <StepRepr_PropertyDefinition.hxx>
119 #include <StepRepr_RepresentedDefinition.hxx>
120 #include <StepRepr_Representation.hxx>
121 #include <StepRepr_RepresentationItem.hxx>
122 #include <StepRepr_ReprItemAndLengthMeasureWithUnit.hxx>
123 #include <StepRepr_ReprItemAndLengthMeasureWithUnitAndQRI.hxx>
124 #include <StepRepr_ReprItemAndPlaneAngleMeasureWithUnit.hxx>
125 #include <StepRepr_ReprItemAndPlaneAngleMeasureWithUnitAndQRI.hxx>
126 #include <StepRepr_ShapeAspect.hxx>
127 #include <StepRepr_ShapeAspectRelationship.hxx>
128 #include <StepRepr_SpecifiedHigherUsageOccurrence.hxx>
129 #include <StepRepr_ValueRange.hxx>
130 #include <StepShape_AdvancedFace.hxx>
131 #include <StepShape_AngleRelator.hxx>
132 #include <StepShape_AngularLocation.hxx>
133 #include <StepShape_AngularSize.hxx>
134 #include <StepShape_ConnectedFaceSet.hxx>
135 #include <StepShape_ContextDependentShapeRepresentation.hxx>
136 #include <StepShape_DimensionalCharacteristic.hxx>
137 #include <StepShape_DimensionalCharacteristicRepresentation.hxx>
138 #include <StepShape_DimensionalLocation.hxx>
139 #include <StepShape_DimensionalLocationWithPath.hxx>
140 #include <StepShape_DimensionalSize.hxx>
141 #include <StepShape_DimensionalSizeWithPath.hxx>
142 #include <StepShape_EdgeCurve.hxx>
143 #include <StepShape_EdgeLoop.hxx>
144 #include <StepShape_FaceBound.hxx>
145 #include <StepShape_LimitsAndFits.hxx>
146 #include <StepShape_OrientedEdge.hxx>
147 #include <StepShape_PlusMinusTolerance.hxx>
148 #include <StepShape_QualifiedRepresentationItem.hxx>
149 #include <StepShape_ShapeDefinitionRepresentation.hxx>
150 #include <StepShape_ShapeDimensionRepresentation.hxx>
151 #include <StepShape_ShapeRepresentation.hxx>
152 #include <StepShape_ShapeRepresentationWithParameters.hxx>
153 #include <StepShape_ToleranceValue.hxx>
154 #include <StepShape_TypeQualifier.hxx>
155 #include <StepShape_ValueFormatTypeQualifier.hxx>
156 #include <StepVisual_CurveStyle.hxx>
157 #include <StepVisual_HArray1OfInvisibleItem.hxx>
158 #include <StepVisual_HArray1OfLayeredItem.hxx>
159 #include <StepVisual_HArray1OfPresentationStyleAssignment.hxx>
160 #include <StepVisual_HArray1OfPresentationStyleSelect.hxx>
161 #include <StepVisual_Invisibility.hxx>
162 #include <StepVisual_InvisibleItem.hxx>
163 #include <StepVisual_MechanicalDesignGeometricPresentationRepresentation.hxx>
164 #include <StepVisual_PointStyle.hxx>
165 #include <StepVisual_PresentationLayerAssignment.hxx>
166 #include <StepVisual_PresentationRepresentation.hxx>
167 #include <StepVisual_PresentationStyleAssignment.hxx>
168 #include <StepVisual_PresentationStyleByContext.hxx>
169 #include <StepVisual_StyledItem.hxx>
170 #include <StepVisual_SurfaceStyleUsage.hxx>
171 #include <TCollection_AsciiString.hxx>
172 #include <TCollection_HAsciiString.hxx>
173 #include <TColStd_HArray1OfReal.hxx>
174 #include <TColStd_HArray1OfTransient.hxx>
175 #include <TColStd_HSequenceOfTransient.hxx>
176 #include <TColStd_MapOfAsciiString.hxx>
177 #include <TColStd_MapOfTransient.hxx>
178 #include <TDataStd_Name.hxx>
179 #include <TDataStd_TreeNode.hxx>
180 #include <TDataStd_UAttribute.hxx>
181 #include <TDF_AttributeSequence.hxx>
182 #include <TDF_ChildIterator.hxx>
183 #include <TDF_Label.hxx>
184 #include <TDF_LabelSequence.hxx>
185 #include <TDF_Tool.hxx>
186 #include <TDocStd_Document.hxx>
187 #include <TopoDS_Compound.hxx>
188 #include <TopoDS_Iterator.hxx>
189 #include <TopoDS_Shape.hxx>
190 #include <TopTools_MapOfShape.hxx>
191 #include <TopTools_SequenceOfShape.hxx>
192 #include <Transfer_ActorOfFinderProcess.hxx>
193 #include <Transfer_Binder.hxx>
194 #include <Transfer_FinderProcess.hxx>
195 #include <Transfer_TransientListBinder.hxx>
196 #include <TransferBRep.hxx>
197 #include <TransferBRep_ShapeMapper.hxx>
198 #include <XCAFDimTolObjects_DatumObject.hxx>
199 #include <XCAFDimTolObjects_DimensionFormVariance.hxx>
200 #include <XCAFDimTolObjects_DimensionGrade.hxx>
201 #include <XCAFDimTolObjects_DimensionObject.hxx>
202 #include <XCAFDimTolObjects_DimensionModif.hxx>
203 #include <XCAFDimTolObjects_DimensionModifiersSequence.hxx>
204 #include <XCAFDimTolObjects_DimensionQualifier.hxx>
205 #include <XCAFDimTolObjects_GeomToleranceObject.hxx>
206 #include <XCAFDoc.hxx>
207 #include <XCAFDoc_Area.hxx>
208 #include <XCAFDoc_Centroid.hxx>
209 #include <XCAFDoc_ColorTool.hxx>
210 #include <XCAFDoc_Datum.hxx>
211 #include <XCAFDoc_Dimension.hxx>
212 #include <XCAFDoc_DimTol.hxx>
213 #include <XCAFDoc_DimTolTool.hxx>
214 #include <XCAFDoc_DocumentTool.hxx>
215 #include <XCAFDoc_GeomTolerance.hxx>
216 #include <XCAFDoc_GraphNode.hxx>
217 #include <XCAFDoc_LayerTool.hxx>
218 #include <XCAFDoc_Material.hxx>
219 #include <XCAFDoc_MaterialTool.hxx>
220 #include <XCAFDoc_ShapeTool.hxx>
221 #include <XCAFDoc_Volume.hxx>
222 #include <XCAFPrs.hxx>
223 #include <XCAFPrs_DataMapIteratorOfDataMapOfStyleShape.hxx>
224 #include <XCAFPrs_DataMapOfShapeStyle.hxx>
225 #include <XCAFPrs_DataMapOfStyleShape.hxx>
226 #include <XCAFPrs_Style.hxx>
227 #include <XSControl_TransferWriter.hxx>
228 #include <XSControl_WorkSession.hxx>
229
230 enum DimensionalValueNumber {
231   DimensionalValueNumber_Nominal = 1,
232   DimensionalValueNumber_Lower,
233   DimensionalValueNumber_Upper
234 };
235
236 // added by skl 15.01.2004 for D&GT writing
237 //#include <StepRepr_CompoundItemDefinition.hxx>
238 //#include <StepRepr_CompoundItemDefinitionMember.hxx>
239 // added by skl 12.02.2004 for writing materials
240 //=======================================================================
241 //function : GetLabelName
242 //purpose  : auxilary function: take name of label and append it to str
243 //=======================================================================
244 static Standard_Boolean GetLabelName (const TDF_Label &L, Handle(TCollection_HAsciiString) &str)
245 {
246   Handle(TDataStd_Name) N;
247   if ( ! L.FindAttribute ( TDataStd_Name::GetID(), N ) ) return Standard_False;
248   TCollection_ExtendedString name = N->Get();
249   if ( name.Length() <=0 ) return Standard_False;
250
251   // set name, converting it to Ascii and removing spaces
252   TCollection_AsciiString buf ( name, '?' );
253   buf.LeftAdjust();
254   buf.RightAdjust();
255   buf.ChangeAll(' ','_');
256   str->AssignCat ( buf.ToCString() );
257   return Standard_True;
258 }
259
260
261 //=======================================================================
262 //function : STEPCAFControl_Writer
263 //purpose  :
264 //=======================================================================
265
266 STEPCAFControl_Writer::STEPCAFControl_Writer () :
267        myColorMode( Standard_True ),
268        myNameMode ( Standard_True ),
269        myLayerMode( Standard_True ),
270        myPropsMode( Standard_True ),
271        mySHUOMode ( Standard_True ),
272        myDGTMode  ( Standard_True ),
273        myMatMode  ( Standard_True )
274 {
275   STEPCAFControl_Controller::Init();
276   Handle(XSControl_WorkSession) WS = new XSControl_WorkSession;
277   Init ( WS );
278 }
279
280
281 //=======================================================================
282 //function : STEPCAFControl_Writer
283 //purpose  :
284 //=======================================================================
285
286 STEPCAFControl_Writer::STEPCAFControl_Writer (const Handle(XSControl_WorkSession)& WS,
287                                               const Standard_Boolean scratch)
288 {
289   STEPCAFControl_Controller::Init();
290   Init ( WS, scratch );
291   myColorMode = Standard_True;
292   myNameMode = Standard_True;
293   myLayerMode = Standard_True;
294   myPropsMode = Standard_True;
295   mySHUOMode = Standard_True;
296 }
297
298
299 //=======================================================================
300 //function : Init
301 //purpose  :
302 //=======================================================================
303
304 void STEPCAFControl_Writer::Init (const Handle(XSControl_WorkSession)& WS,
305                                   const Standard_Boolean scratch)
306 {
307   WS->SelectNorm ( "STEP" );
308   myWriter.SetWS (WS,scratch);
309   myFiles = new STEPCAFControl_DictionaryOfExternFile;
310   myLabEF.Clear();
311   myLabels.Clear();
312 }
313
314
315 //=======================================================================
316 //function : Write
317 //purpose  :
318 //=======================================================================
319
320 IFSelect_ReturnStatus STEPCAFControl_Writer::Write (const Standard_CString filename)
321 {
322   IFSelect_ReturnStatus status = myWriter.Write ( filename );
323
324   // get directory name of the main file
325   OSD_Path mainfile ( filename );
326   mainfile.SetName ( "" );
327   mainfile.SetExtension ( "" );
328   TCollection_AsciiString dpath;
329   mainfile.SystemName ( dpath );
330
331   STEPCAFControl_IteratorOfDictionaryOfExternFile it ( myFiles );
332   for ( ; it.More(); it.Next() ) {
333     Handle(STEPCAFControl_ExternFile) EF = it.Value();
334     if ( EF->GetWriteStatus() != IFSelect_RetVoid ) continue;
335
336     // construct extern file name
337     TCollection_AsciiString fname = OSD_Path::AbsolutePath ( dpath, EF->GetName()->String() );
338     if ( fname.Length() <= 0 ) fname = EF->GetName()->String();
339 #ifdef OCCT_DEBUG
340     cout << "Writing external file: " << fname.ToCString() << endl;
341 #endif
342     
343     EF->SetWriteStatus ( EF->GetWS()->SendAll ( fname.ToCString() ) );
344   }
345
346   return status;
347 }
348
349
350 //=======================================================================
351 //function : Transfer
352 //purpose  :
353 //=======================================================================
354
355 Standard_Boolean STEPCAFControl_Writer::Transfer( const Handle(TDocStd_Document) &doc,
356                                                   const STEPControl_StepModelType mode,
357                                                   const Standard_CString multi )
358 {
359   Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool( doc->Main() );
360   if ( STool.IsNull() ) return Standard_False;
361
362   TDF_LabelSequence labels;
363   STool->GetFreeShapes ( labels );
364   return Transfer ( myWriter, labels, mode, multi );
365 }
366
367
368 //=======================================================================
369 //function : Transfer
370 //purpose  :
371 //=======================================================================
372
373 Standard_Boolean STEPCAFControl_Writer::Transfer( const TDF_Label& L,
374                                                   const STEPControl_StepModelType mode,
375                                                   const Standard_CString multi )
376 {
377   TDF_LabelSequence labels;
378   labels.Append ( L );
379   return Transfer ( myWriter, labels, mode, multi );
380 }
381
382 //=======================================================================
383 //function : Transfer
384 //purpose  :
385 //=======================================================================
386
387 Standard_Boolean STEPCAFControl_Writer::Transfer( const TDF_LabelSequence& labels,
388                                                   const STEPControl_StepModelType mode,
389                                                   const Standard_CString multi )
390 {
391   return Transfer( myWriter, labels, mode, multi );
392 }
393
394 //=======================================================================
395 //function : Perform
396 //purpose  :
397 //=======================================================================
398
399 Standard_Boolean STEPCAFControl_Writer::Perform (const Handle(TDocStd_Document) &doc,
400                                                  const Standard_CString filename)
401 {
402   if ( ! Transfer ( doc ) ) return Standard_False;
403   return Write ( filename ) == IFSelect_RetDone;
404 }
405
406
407 //=======================================================================
408 //function : Perform
409 //purpose  :
410 //=======================================================================
411
412 Standard_Boolean STEPCAFControl_Writer::Perform (const Handle(TDocStd_Document) &doc,
413                                                  const TCollection_AsciiString &filename)
414 {
415   if ( ! Transfer ( doc ) ) return Standard_False;
416   return Write ( filename.ToCString() ) == IFSelect_RetDone;
417 }
418
419
420 //=======================================================================
421 //function : ExternFiles
422 //purpose  :
423 //=======================================================================
424
425 const Handle(STEPCAFControl_DictionaryOfExternFile) &STEPCAFControl_Writer::ExternFiles () const
426 {
427   return myFiles;
428 }
429
430
431 //=======================================================================
432 //function : ExternFile
433 //purpose  :
434 //=======================================================================
435
436 Standard_Boolean STEPCAFControl_Writer::ExternFile (const TDF_Label &L,
437                                                     Handle(STEPCAFControl_ExternFile) &ef) const
438 {
439   ef.Nullify();
440   if ( ! myLabEF.IsBound ( L ) ) return Standard_False;
441   ef = myLabEF.Find ( L );
442   return Standard_True;
443 }
444
445
446 //=======================================================================
447 //function : ExternFile
448 //purpose  :
449 //=======================================================================
450
451 Standard_Boolean STEPCAFControl_Writer::ExternFile (const Standard_CString name,
452                                                     Handle(STEPCAFControl_ExternFile) &ef) const
453 {
454   ef.Nullify();
455   if ( ! myFiles.IsNull() || ! myFiles->HasItem ( name ) )
456     return Standard_False;
457   ef = myFiles->Item ( name );
458   return Standard_True;
459 }
460
461
462 //=======================================================================
463 //function : Writer
464 //purpose  :
465 //=======================================================================
466
467 STEPControl_Writer &STEPCAFControl_Writer::ChangeWriter ()
468 {
469   return myWriter;
470 }
471
472
473 //=======================================================================
474 //function : Writer
475 //purpose  :
476 //=======================================================================
477
478 const STEPControl_Writer &STEPCAFControl_Writer::Writer () const
479 {
480   return myWriter;
481 }
482
483
484 //=======================================================================
485 //function : Transfer
486 //purpose  :
487 //=======================================================================
488
489 Standard_Boolean STEPCAFControl_Writer::Transfer (STEPControl_Writer &writer,
490                                                   const TDF_LabelSequence &labels,
491                                                   const STEPControl_StepModelType mode,
492                                                   const Standard_CString multi,
493                                                   const Standard_Boolean isExternFile)
494 {
495   if ( labels.Length() <=0 ) return Standard_False;
496
497   Handle(STEPCAFControl_ActorWrite) Actor =
498     Handle(STEPCAFControl_ActorWrite)::DownCast ( writer.WS()->NormAdaptor()->ActorWrite() );
499
500   // translate free top-level shapes of the DECAF document
501   Standard_Integer ap = Interface_Static::IVal ("write.step.schema");
502   TDF_LabelSequence sublabels;
503   for ( Standard_Integer i=1; i <= labels.Length(); i++ ) {
504     TDF_Label L = labels.Value(i);
505     TopoDS_Shape dummy;
506     if ( myLabels.IsBound ( L ) ) continue; // already processed
507
508     TopoDS_Shape shape = XCAFDoc_ShapeTool::GetShape ( L );
509     if ( shape.IsNull() ) continue;
510     
511     // write shape either as a whole, or as multifile (with extern refs)
512     if ( ! multi  ) {
513       Actor->SetStdMode ( Standard_False );
514
515       TDF_LabelSequence comp;
516
517       //for case when only part of assemby structure should be written in the document
518       //if specified label is component of the assembly then
519       //in order to save location of this component in the high-level assembly
520       //and save name of high-level assembly it is necessary to represent structure of high-level assembly 
521       //as assembly with one component specified by current label. 
522       //For that compound containing only specified component is binded to the label of the high-level assembly.
523       //The such way full structure of high-level assembly was replaced on the assembly contaning one component.
524       if ( XCAFDoc_ShapeTool::IsComponent ( L ) )
525       {
526         TopoDS_Compound aComp;
527         BRep_Builder aB;
528         aB.MakeCompound(aComp);
529         aB.Add(aComp, shape);
530         shape = aComp; 
531         comp.Append(L);
532         TDF_Label ref;
533         if ( XCAFDoc_ShapeTool::GetReferredShape ( L, ref ) )
534         {
535           if(XCAFDoc_ShapeTool::IsAssembly ( ref))
536             XCAFDoc_ShapeTool::GetComponents ( ref, comp, Standard_True );
537         }
538         L = L.Father();
539       }
540       else
541       {
542         // fill sequence of (sub) shapes for which attributes should be written
543         // and set actor to handle assemblies in a proper way
544         if(XCAFDoc_ShapeTool::IsAssembly ( L ))
545           XCAFDoc_ShapeTool::GetComponents ( L, comp, Standard_True );
546       }
547       
548       for ( Standard_Integer k=1; k <= comp.Length(); k++ ) {
549         TDF_Label ref;
550         if ( ! XCAFDoc_ShapeTool::GetReferredShape ( comp(k), ref ) ) continue;
551         if ( ! myLabels.IsBound ( ref ) ) {
552           TopoDS_Shape refS = XCAFDoc_ShapeTool::GetShape ( ref );
553           myLabels.Bind ( ref, refS );
554           sublabels.Append ( ref );
555           if ( XCAFDoc_ShapeTool::IsAssembly ( ref ) )
556             Actor->RegisterAssembly ( refS );
557         }
558       }
559       myLabels.Bind ( L, shape );
560       sublabels.Append ( L );
561       if ( XCAFDoc_ShapeTool::IsAssembly ( L ) )
562         Actor->RegisterAssembly ( shape );
563
564       writer.Transfer(shape,mode,Standard_False);
565       Actor->SetStdMode ( Standard_True ); // restore default behaviour
566     }
567     else {
568       // translate final solids
569       TopoDS_Shape Sass = TransferExternFiles ( L, mode, sublabels, multi );
570
571       // translate main assembly structure
572 /*
573       if ( ap == 3 ) { // if AP203, switch to AP214
574         Interface_Static::SetCVal ("write.step.schema", "AP214DIS");
575         Handle(StepData_StepModel) model = 
576           Handle(StepData_StepModel)::DownCast ( writer.WS()->Model() );
577         if ( model->HasHeaderEntity(STANDARD_TYPE(HeaderSection_FileSchema)) ) {
578           Handle(HeaderSection_FileSchema) fs = 
579             Handle(HeaderSection_FileSchema)::DownCast ( model->HeaderEntity(STANDARD_TYPE(HeaderSection_FileSchema)) );
580           Handle(TCollection_HAsciiString) str = fs->SchemaIdentifiersValue ( 1 );
581           Handle(TCollection_HAsciiString) ap214 = new TCollection_HAsciiString ( "AUTOMOTIVE_DESIGN" );
582           if ( str->Search ( ap214 ) <0 ) {
583             str->Clear();
584             str->AssignCat ( ap214 );
585           }
586         }
587       }
588 */      
589       Standard_Integer assemblymode = Interface_Static::IVal ("write.step.assembly");
590       Interface_Static::SetCVal ("write.step.assembly", "On");
591       writer.Transfer ( Sass, STEPControl_AsIs );
592       Interface_Static::SetIVal ("write.step.assembly", assemblymode);
593       Interface_Static::SetIVal ("write.step.schema", ap);
594     }
595   }
596
597   writer.WS()->ComputeGraph(Standard_True );// added by skl 03.11.2003 since we use
598                                             // writer.Transfer() wihtout compute graph
599
600   // write names
601   if ( GetNameMode() )
602     WriteNames ( writer.WS(), sublabels );
603
604   if ( !multi ) {
605     // write colors
606     if ( GetColorMode() )
607       WriteColors ( writer.WS(), sublabels );
608     
609     // write layers
610     if ( GetLayerMode() )
611       WriteLayers ( writer.WS(), sublabels );
612
613     // write SHUO entities
614     if ( GetSHUOMode() && !isExternFile ) 
615       // do not store SHUO for extern reference for the moment
616       WriteSHUOs (  writer.WS(), sublabels );
617     
618     // write G&DTs
619     if(GetDimTolMode())
620       WriteDGTs(writer.WS(),sublabels);
621
622     // write Materials
623     if(GetMaterialMode())
624       WriteMaterials(writer.WS(),sublabels);
625
626     // register all MDGPRs in model
627     MoniTool_DataMapIteratorOfDataMapOfShapeTransient anItr(myMapCompMDGPR);
628     for (; anItr.More(); anItr.Next()) {
629       Handle(Interface_InterfaceModel) Model = writer.WS()->Model();
630       Model->AddWithRefs( anItr.Value() );
631     }
632   }
633   
634   if ( multi ) { // external refs
635     WriteExternRefs ( writer.WS(), sublabels );
636   }
637
638   // write validation props
639 //  if ( multi && ap ==3 ) {
640 //      Interface_Static::SetCVal ("write.step.schema", "AP214DIS");
641 //  }
642   if ( GetPropsMode() ) 
643     WriteValProps ( writer.WS(), sublabels, multi );
644
645   Interface_Static::SetIVal ("write.step.schema", ap);
646
647   // refresh graph
648   writer.WS()->ComputeGraph ( Standard_True );
649
650   /* ================================
651     *  Write names for the sub-shapes
652     * ================================ */
653
654   if ( Interface_Static::IVal("write.stepcaf.subshapes.name") )
655   {
656     Handle(XSControl_TransferWriter) TW = this->ChangeWriter().WS()->TransferWriter();
657     Handle(Transfer_FinderProcess) FP = TW->FinderProcess();
658
659     for ( int i = 1; i <= labels.Length(); i++ )
660     {
661       TDF_Label L = labels.Value(i);
662
663       for ( TDF_ChildIterator it(L, Standard_True); it.More(); it.Next() )
664       {
665         TDF_Label SubL = it.Value();
666
667         // Access name recorded in OCAF TDataStd_Name attribute
668         Handle(TCollection_HAsciiString) hSubName = new TCollection_HAsciiString;
669         if ( !GetLabelName(SubL, hSubName) )
670           continue;
671
672         // Access topological data
673         TopoDS_Shape SubS = XCAFDoc_ShapeTool::GetShape(SubL);
674         if ( SubS.IsNull() )
675           continue;
676
677         // Access the correspondent STEP Representation Item
678         Handle(StepRepr_RepresentationItem) RI;
679         Handle(TransferBRep_ShapeMapper) aShMapper = TransferBRep::ShapeMapper(FP, SubS);
680         if ( !FP->FindTypedTransient(aShMapper, STANDARD_TYPE(StepRepr_RepresentationItem), RI) )
681           continue;
682
683         // Record the name
684         RI->SetName(hSubName);
685       }
686     }
687   }
688
689   return Standard_True;
690 }
691
692
693 //=======================================================================
694 //function : TransferExternFiles
695 //purpose  :
696 //=======================================================================
697
698 TopoDS_Shape STEPCAFControl_Writer::TransferExternFiles (const TDF_Label &L,
699                                                          const STEPControl_StepModelType mode,
700                                                          TDF_LabelSequence &labels,
701                                                          const Standard_CString prefix)
702 {
703   // if label already translated, just return the shape
704   if ( myLabels.IsBound ( L ) ) {
705     return myLabels.Find ( L );
706   }
707
708   TopoDS_Compound C;
709   BRep_Builder B;
710   B.MakeCompound ( C );
711   //labels.Append ( L ); 
712   // if not assembly, write to separate file
713   if ( ! XCAFDoc_ShapeTool::IsAssembly ( L ) && !XCAFDoc_ShapeTool::IsComponent ( L )) {
714     labels.Append ( L );
715     // prepare for transfer
716     Handle(XSControl_WorkSession) newWS = new XSControl_WorkSession;
717     newWS->SelectNorm ( "STEP" );
718     STEPControl_Writer sw ( newWS, Standard_True );
719     TDF_LabelSequence Lseq;
720     Lseq.Append ( L );
721
722     // construct the name for extern file
723     Handle(TCollection_HAsciiString) basename = new TCollection_HAsciiString;
724     if ( prefix && prefix[0] ) basename->AssignCat ( prefix );
725     GetLabelName ( L, basename );
726     Handle(TCollection_HAsciiString) name = new TCollection_HAsciiString ( basename );
727     name->AssignCat ( ".stp" );
728     if ( myFiles->HasItem ( name->ToCString() ) ) { // avoid confusions
729       for ( Standard_Integer k=1; k < 32000; k++ ) {
730         name = new TCollection_HAsciiString ( basename );
731         name->AssignCat ( "_" );
732         name->AssignCat ( TCollection_AsciiString ( k ).ToCString() );
733         name->AssignCat ( ".stp" );
734         if ( ! myFiles->HasItem ( name->ToCString() ) ) break;
735       }
736     }
737
738     // translate and record extern file
739     Handle(STEPCAFControl_ExternFile) EF = new STEPCAFControl_ExternFile;
740     EF->SetWS ( newWS );
741     EF->SetName ( name );
742     EF->SetLabel ( L );
743     Standard_Integer assemblymode = Interface_Static::IVal ("write.step.assembly");
744     Interface_Static::SetCVal ("write.step.assembly", "Off");
745     const Standard_CString multi = 0;
746     EF->SetTransferStatus ( Transfer ( sw, Lseq, mode, multi, Standard_True ) );
747     Interface_Static::SetIVal ("write.step.assembly", assemblymode);
748     myLabEF.Bind ( L, EF );
749     myFiles->SetItem ( name->ToCString(), EF );
750
751     // return empty compound as replacement for the shape
752     myLabels.Bind ( L, C );
753     return C;
754   }
755   TDF_LabelSequence comp;
756   TDF_Label aCurL = L;
757   //if specified shape is component then high-level assembly is considered
758   //to get valid structure with location
759   if ( XCAFDoc_ShapeTool::IsComponent ( L ) )
760   {
761     comp.Append(L);
762     aCurL = L.Father();
763   }
764   // else iterate on components add create structure of empty compounds
765   // representing the assembly
766   else if (XCAFDoc_ShapeTool::IsAssembly ( L ))
767     XCAFDoc_ShapeTool::GetComponents ( L, comp, Standard_False );
768
769   labels.Append ( aCurL );
770   for ( Standard_Integer k=1; k <= comp.Length(); k++ ) {
771     TDF_Label lab = comp(k);
772     TDF_Label ref;
773     if ( ! XCAFDoc_ShapeTool::GetReferredShape ( lab, ref ) ) continue;
774     TopoDS_Shape Scomp = TransferExternFiles ( ref, mode, labels, prefix );
775     Scomp.Location ( XCAFDoc_ShapeTool::GetLocation ( lab ) );
776     B.Add ( C, Scomp );
777   }
778   myLabels.Bind ( aCurL, C );
779   return C;
780 }
781
782
783 //=======================================================================
784 //function : WriteExternRefs
785 //purpose  :
786 //=======================================================================
787
788 Standard_Boolean STEPCAFControl_Writer::WriteExternRefs (const Handle(XSControl_WorkSession) &WS,
789                                                          const TDF_LabelSequence &labels) const
790 {
791   if ( labels.Length() <=0 ) return Standard_False;
792
793   Handle(XSControl_TransferWriter) TW = WS->TransferWriter();
794   Handle(Transfer_FinderProcess) FP = TW->FinderProcess();
795   STEPConstruct_ExternRefs EFTool ( WS );
796   Standard_Integer schema = Interface_Static::IVal("write.step.schema");
797   for ( Standard_Integer k=1; k <= labels.Length(); k++ ) {
798     TDF_Label lab = labels(k);
799     if ( XCAFDoc_ShapeTool::IsAssembly ( lab ) ) continue; // skip assemblies
800
801     // get extern file
802     Handle(STEPCAFControl_ExternFile) EF;
803     if ( ! ExternFile ( lab, EF ) ) continue; // should never be
804
805     // find SDR
806     if ( ! myLabels.IsBound ( lab ) ) continue; // not recorded as translated, skip
807     TopoDS_Shape S = myLabels.Find ( lab );
808
809     Handle(StepShape_ShapeDefinitionRepresentation) SDR;
810     Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper ( FP, S );
811     if ( ! FP->FindTypedTransient ( mapper, STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation), SDR ) ) {
812 #ifdef OCCT_DEBUG
813       cout << "Warning: Cannot find SDR for " << S.TShape()->DynamicType()->Name() << endl;
814 #endif
815       continue;
816     }
817
818     // add extern ref
819     const Standard_CString format = (const Standard_CString) ( schema == 3 ? "STEP AP203" : "STEP AP214" );
820     // try to get PD from SDR
821     StepRepr_RepresentedDefinition RD = SDR->Definition();
822     Handle(StepRepr_PropertyDefinition) aPropDef = RD.PropertyDefinition();
823     if (aPropDef.IsNull()) {
824 #ifdef OCCT_DEBUG
825       cout << "Warning: STEPCAFControl_Writer::WriteExternRefs StepRepr_PropertyDefinition is null for " << S.TShape()->DynamicType()->Name() << endl;
826 #endif
827       continue;
828     }
829     StepRepr_CharacterizedDefinition CharDef = aPropDef->Definition();
830     Handle(StepBasic_ProductDefinition) PD = CharDef.ProductDefinition();
831     if (PD.IsNull()) {
832 #ifdef OCCT_DEBUG
833       cout << "Warning: STEPCAFControl_Writer::WriteExternRefs StepBasic_ProductDefinition is null for " << S.TShape()->DynamicType()->Name() << endl;
834 #endif
835       continue;
836     }
837     EFTool.AddExternRef ( EF->GetName()->ToCString(), PD, format );
838   }
839   EFTool.WriteExternRefs(schema);
840   return Standard_True;
841 }
842
843
844 //=======================================================================
845 //function : FindEntities
846 //purpose  : auxilary
847 //=======================================================================
848 static Standard_Integer FindEntities (const Handle(Transfer_FinderProcess) &FP,
849                                       const TopoDS_Shape &S,
850                                       TopLoc_Location &L,
851                                       TColStd_SequenceOfTransient &seqRI)
852 {
853   Handle(StepRepr_RepresentationItem) item = STEPConstruct::FindEntity ( FP, S, L );
854
855   if ( ! item.IsNull() ) {
856     seqRI.Append ( item );
857     return 1;
858   }
859       
860   // may be S was splited during shape processing
861   Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper ( FP, S );
862   Handle(Transfer_Binder) bnd = FP->Find ( mapper );
863   if ( bnd.IsNull() ) return 0;
864   
865   Handle(Transfer_TransientListBinder) TransientListBinder =
866     //Handle(Transfer_TransientListBinder)::DownCast( bnd->Next(Standard_True) );
867     Handle(Transfer_TransientListBinder)::DownCast( bnd );
868   Standard_Integer nres=0;
869   if ( TransientListBinder.IsNull() && S.ShapeType() == TopAbs_COMPOUND) 
870   {
871     for ( TopoDS_Iterator it(S); it.More(); it.Next() ) {
872       Handle(StepRepr_RepresentationItem) aLocalItem = STEPConstruct::FindEntity ( FP, it.Value(), L );
873       if (aLocalItem.IsNull() ) continue;
874       nres++;
875       seqRI.Append (aLocalItem);
876     }
877   }
878   else
879   {
880     const Standard_Integer nb = TransientListBinder->NbTransients();
881     for (Standard_Integer i=1; i<=nb; i++) {
882       Handle(Standard_Transient) t = TransientListBinder->Transient(i);
883       item = Handle(StepRepr_RepresentationItem)::DownCast(t);
884       if ( item.IsNull() ) continue;
885       nres++;
886       seqRI.Append ( item );
887     }
888   }
889 /*  works but is obsolete: another approach
890   if (i<=nb) {
891     TopoDS_Shape comp = TransferBRep::ShapeResult(bnd);
892     if ( ! comp.IsNull() && comp.ShapeType() < S.ShapeType() ) {
893       for ( TopoDS_Iterator it(comp); it.More(); it.Next() ) {
894         MakeSTEPStyles(Styles, it.Value(), settings, STEPstyle, 
895                        Map, ( hasOwn ? &style : 0 ) );
896       }
897     }
898   }
899 */
900   return nres;
901 }
902
903
904 //=======================================================================
905 //function : getStyledItem
906 //purpose  : auxilary
907 //=======================================================================
908 static Standard_Boolean getStyledItem(const TopoDS_Shape& S,
909                                       const Handle(XCAFDoc_ShapeTool)& STool,
910                                       const STEPConstruct_Styles &Styles, 
911                                       Handle(StepVisual_StyledItem) &resSelItem,
912                                       const MoniTool_DataMapOfShapeTransient& myMapCompMDGPR)
913 {
914   TDF_Label aTopShL = STool->FindShape(S, Standard_False);
915   TopoDS_Shape aTopLevSh = STool->GetShape( aTopShL );
916   Standard_Boolean found = Standard_False;
917   if ( !aTopLevSh.IsNull() &&  myMapCompMDGPR.IsBound( aTopLevSh ) ) {
918     Handle(StepVisual_PresentationRepresentation) aMDGPR = 
919       Handle(StepVisual_PresentationRepresentation)::DownCast( myMapCompMDGPR.Find( aTopLevSh ) );
920     Handle(StepRepr_HArray1OfRepresentationItem) anSelItmHArr = aMDGPR->Items();
921     // search for PSA of Monifold solid
922     if ( !anSelItmHArr.IsNull() )
923     {
924       for (Standard_Integer si = 1; si <= anSelItmHArr->Length(); si++) {
925         Handle(StepVisual_StyledItem) aSelItm =
926           Handle(StepVisual_StyledItem)::DownCast(anSelItmHArr->Value(si));
927
928         if ( aSelItm.IsNull() ) 
929           continue;
930
931         // check that it is a stiled item for monifold solid brep
932         TopLoc_Location Loc;
933         TColStd_SequenceOfTransient aNewseqRI;
934         FindEntities ( Styles.FinderProcess(), aTopLevSh, Loc, aNewseqRI );
935         if ( aNewseqRI.Length() > 0 )
936         {
937           
938           Handle(StepRepr_RepresentationItem) anItem = aSelItm->Item();
939           Standard_Boolean isSameMonSolBR = Standard_False;
940           for (Standard_Integer mi = 1; mi <= aNewseqRI.Length(); mi++) {
941             if ( !anItem.IsNull() && anItem == aNewseqRI.Value( mi ) ) {
942               isSameMonSolBR = Standard_True;
943               break;
944             }
945           }
946           if (!isSameMonSolBR)
947             continue;
948         }
949         
950         
951         for (Standard_Integer jsi = 1; jsi <= aSelItm->NbStyles() && !found; jsi++) {
952           Handle(StepVisual_PresentationStyleAssignment) aFatherPSA = aSelItm->StylesValue(jsi);
953           // check for PSA for top-level (not Presentation style by contex for NAUO)
954           if (aFatherPSA.IsNull() || aFatherPSA->IsKind(STANDARD_TYPE(StepVisual_PresentationStyleByContext)))
955             continue;
956           resSelItem = aSelItm;
957           found = Standard_True;
958         }
959       }
960     }
961   }
962   return found;
963 }
964
965
966 //=======================================================================
967 //function : setDefaultInstanceColor
968 //purpose  : auxilary
969 //=======================================================================
970 static Standard_Boolean setDefaultInstanceColor (const Handle(StepVisual_StyledItem) &aSelItm,
971                                                  Handle(StepVisual_PresentationStyleAssignment)& PSA)
972 {
973    Standard_Boolean found = Standard_False;
974   for (Standard_Integer jsi = 1; jsi <= aSelItm->NbStyles() && !found; jsi++) {
975     Handle(StepVisual_PresentationStyleAssignment) aFatherPSA = aSelItm->StylesValue(jsi);
976   // check for PSA for top-level (not Presentation style by contex for NAUO)
977   if (aFatherPSA.IsNull() || aFatherPSA->IsKind(STANDARD_TYPE(StepVisual_PresentationStyleByContext))) 
978     return Standard_False;
979           
980   // get style select from father PSA
981   if (aFatherPSA->NbStyles() > 0) {
982     Handle(StepVisual_HArray1OfPresentationStyleSelect) aFatherStyles =
983       new StepVisual_HArray1OfPresentationStyleSelect(1, aFatherPSA->NbStyles());
984     for (Standard_Integer k = 1; k <= aFatherPSA->NbStyles(); k++) {
985       StepVisual_PresentationStyleSelect PSS;
986       StepVisual_PresentationStyleSelect olDPSS = aFatherPSA->StylesValue(k);
987       if (!olDPSS.PointStyle().IsNull())
988         PSS.SetValue (olDPSS.PointStyle());
989       else if (!olDPSS.CurveStyle().IsNull())
990         PSS.SetValue (olDPSS.CurveStyle());
991       else if (!olDPSS.SurfaceStyleUsage().IsNull())
992         PSS.SetValue (olDPSS.SurfaceStyleUsage());
993       else {
994         found = Standard_False;
995         break;
996       }
997       //aFatherStyles->SetValue( k, PSS );
998       aFatherStyles->SetValue( k, olDPSS );
999       found = Standard_True;
1000     }
1001             // init PSA of NAUO
1002     if (found) {
1003       PSA->Init( aFatherStyles );
1004     }
1005   }
1006     
1007   }
1008   return found;
1009 }
1010
1011
1012 //=======================================================================
1013 //function : MakeSTEPStyles
1014 //purpose  : auxilary
1015 //=======================================================================
1016 static void MakeSTEPStyles (STEPConstruct_Styles &Styles,
1017                             const TopoDS_Shape &S,
1018                             const XCAFPrs_DataMapOfShapeStyle &settings,
1019                             Handle(StepVisual_StyledItem) &override,
1020                             TopTools_MapOfShape &Map,
1021                             const MoniTool_DataMapOfShapeTransient& myMapCompMDGPR,
1022                             STEPConstruct_DataMapOfAsciiStringTransient &DPDCs,
1023                             STEPConstruct_DataMapOfPointTransient &ColRGBs,
1024                             const Handle(XCAFDoc_ColorTool)& CTool,
1025                             const XCAFPrs_Style *inherit = 0,
1026                             const Standard_Boolean isComponent = Standard_False)
1027 {
1028   // skip already processed shapes
1029   if ( ! Map.Add ( S ) ) return;
1030
1031   // check if shape has its own style (r inherits from ancestor)
1032   XCAFPrs_Style style;
1033   if ( inherit ) style = *inherit;
1034   if ( settings.IsBound(S) ) {
1035     XCAFPrs_Style own = settings.Find(S);
1036     if ( !own.IsVisible() ) style.SetVisibility ( Standard_False );
1037     if ( own.IsSetColorCurv() ) style.SetColorCurv ( own.GetColorCurv() );
1038     if ( own.IsSetColorSurf() ) style.SetColorSurf ( own.GetColorSurf() );
1039   }
1040
1041   // translate colors to STEP
1042   Handle(StepVisual_Colour) surfColor, curvColor;
1043   if ( style.IsSetColorSurf() )
1044     surfColor = Styles.EncodeColor(style.GetColorSurf(),DPDCs,ColRGBs);
1045   if ( style.IsSetColorCurv() )
1046     curvColor = Styles.EncodeColor(style.GetColorCurv(),DPDCs,ColRGBs);
1047   
1048   Standard_Boolean hasOwn = ( ! surfColor.IsNull() || 
1049                               ! curvColor.IsNull() ||
1050                               ! style.IsVisible() );
1051
1052   // find target item and assign style to it
1053   Handle(StepVisual_StyledItem) STEPstyle = override;
1054   if ( hasOwn ) {
1055     if ( S.ShapeType() != TopAbs_COMPOUND || isComponent ) { // skip compounds, let subshapes inherit its colors
1056       TopLoc_Location L;
1057       TColStd_SequenceOfTransient seqRI;
1058       Standard_Integer nb = FindEntities ( Styles.FinderProcess(), S, L, seqRI );
1059 #ifdef OCCT_DEBUG
1060       if ( nb <=0 ) cout << "Warning: Cannot find RI for " << S.TShape()->DynamicType()->Name() << endl;
1061 #endif
1062       //Get overridden style gka 10.06.03
1063       if ( isComponent && nb) 
1064         getStyledItem(S, CTool->ShapeTool(), Styles, override,myMapCompMDGPR);
1065        
1066            
1067       for ( Standard_Integer i=1; i <= nb; i++ ) {
1068         Handle(StepRepr_RepresentationItem) item = 
1069           Handle(StepRepr_RepresentationItem)::DownCast(seqRI(i));
1070         Handle(StepVisual_PresentationStyleAssignment) PSA;
1071         if ( style.IsVisible() || !surfColor.IsNull() || !curvColor.IsNull() ) {
1072           PSA = Styles.MakeColorPSA ( item, surfColor, curvColor, isComponent );
1073         }
1074         else {
1075           // default white color
1076           surfColor = Styles.EncodeColor(Quantity_Color(1,1,1,Quantity_TOC_RGB),DPDCs,ColRGBs);
1077           PSA = Styles.MakeColorPSA ( item, surfColor, curvColor, isComponent );
1078           if ( isComponent ) 
1079             setDefaultInstanceColor( override, PSA);
1080           
1081         } // end of component case
1082         
1083         STEPstyle = Styles.AddStyle ( item, PSA, override );
1084         hasOwn = Standard_False;
1085       }
1086     }
1087   }
1088
1089   // iterate on subshapes (except vertices :)
1090   if ( S.ShapeType() == TopAbs_EDGE ) return;
1091   if ( !isComponent ) // PTV 10.02.2003
1092     for ( TopoDS_Iterator it(S); it.More(); it.Next() ) {
1093       MakeSTEPStyles ( Styles, it.Value(), settings, STEPstyle,
1094                       Map, myMapCompMDGPR, DPDCs, ColRGBs, CTool,
1095                       ( hasOwn ? &style : 0 ) );
1096     }
1097 }
1098
1099 /*
1100 static Standard_Boolean getFatherColor (const TDF_Label& L,
1101                                         const Handle(XCAFDoc_ColorTool)& CTool,
1102                                         XCAFPrs_Style& style)
1103 {
1104   Standard_Boolean done = Standard_False;
1105   TopoDS_Shape aSh = CTool->ShapeTool()->GetShape( L );
1106   TDF_Label aFL = CTool->ShapeTool()->FindShape( aSh );
1107   if (aFL.IsNull() || aFL == L)
1108     return done;
1109   Quantity_Color C;
1110   if ( CTool->GetColor ( aFL, XCAFDoc_ColorGen, C ) ) {
1111     style.SetColorCurv ( C );
1112     style.SetColorSurf ( C );
1113     done = Standard_True;
1114   }
1115   if ( CTool->GetColor ( aFL, XCAFDoc_ColorSurf, C ) ) {
1116     style.SetColorSurf ( C );
1117     done = Standard_True;
1118   }
1119   if ( CTool->GetColor ( aFL, XCAFDoc_ColorCurv, C ) ) {
1120     style.SetColorCurv ( C );
1121     done = Standard_True;
1122   }
1123   
1124   return done;
1125 }
1126 */
1127
1128
1129 //=======================================================================
1130 //function : WriteColors
1131 //purpose  : 
1132 //=======================================================================
1133
1134 Standard_Boolean STEPCAFControl_Writer::WriteColors (const Handle(XSControl_WorkSession) &WS,
1135                                                      const TDF_LabelSequence &labels)
1136 {
1137   if ( labels.Length() <=0 ) return Standard_False;
1138
1139   // Iterate on shapes in the document
1140   Handle(XCAFDoc_ColorTool) CTool = XCAFDoc_DocumentTool::ColorTool( labels(1) );
1141   if ( CTool.IsNull() ) return Standard_False;
1142
1143   STEPConstruct_Styles Styles ( WS );
1144   STEPConstruct_DataMapOfAsciiStringTransient DPDCs;
1145   STEPConstruct_DataMapOfPointTransient ColRGBs;
1146   for ( Standard_Integer i=1; i <= labels.Length(); i++ ) {
1147     TDF_Label L = labels.Value(i);
1148
1149     Handle(XCAFDoc_ShapeTool) aSTool = XCAFDoc_DocumentTool::ShapeTool( labels(1) );
1150     // Skip assemblies: colors assigned to assemblies and their instances
1151     // are not supported (it is not clear how to encode that in STEP)
1152     if ( XCAFDoc_ShapeTool::IsAssembly ( L ) ) {
1153 #ifdef OCCT_DEBUG
1154       cout << "Warning: Cannot write color  for Assembly" << endl;
1155       cout << "Info: Check for colors assigned to components in assembly" << endl;
1156 #endif
1157       // PTV 22.01.2003 Write color for instances.
1158       TDF_LabelSequence compLabels;
1159       if ( aSTool.IsNull() )
1160         continue;
1161       if (!aSTool->GetComponents(L, compLabels))
1162         continue;
1163       WriteColors(WS, compLabels);
1164       continue;
1165     }
1166     Styles.ClearStyles();
1167
1168     // get a target shape and try to find corresponding context
1169     // (all the colors set under that label will be put into that context)
1170     TopoDS_Shape S;
1171     if ( ! XCAFDoc_ShapeTool::GetShape ( L, S ) ) continue;
1172     Standard_Boolean isComponent = aSTool->IsComponent( L );
1173     TopoDS_Shape aTopSh = S;
1174     Handle(StepRepr_RepresentationContext) Context = Styles.FindContext ( S );
1175     if ( isComponent ) {
1176       TDF_Label aTopShL = aSTool->FindShape(S, Standard_False);
1177       if (aTopShL.IsNull())
1178         continue;
1179       aTopSh = aSTool->GetShape( aTopShL );
1180       Context = Styles.FindContext ( aTopSh );
1181     }
1182     if ( Context.IsNull() )
1183         continue;
1184     
1185     // collect settings set on that label
1186     XCAFPrs_DataMapOfShapeStyle settings;
1187     TDF_LabelSequence seq;
1188     seq.Append ( L );
1189     XCAFDoc_ShapeTool::GetSubShapes ( L, seq );
1190     Standard_Boolean isVisible = Standard_True;
1191     for ( Standard_Integer j = 1; j <= seq.Length(); j++ ) {
1192       TDF_Label lab = seq.Value(j);
1193       XCAFPrs_Style style;
1194       Quantity_Color C;
1195       if ( lab == L ) {
1196         // check for invisible status of object on label
1197         if ( !CTool->IsVisible( lab ) ) {
1198           isVisible = Standard_False;
1199           style.SetVisibility( Standard_False );
1200         }
1201       }
1202       if ( CTool->GetColor ( lab, XCAFDoc_ColorGen, C ) ) {
1203         style.SetColorCurv ( C );
1204         style.SetColorSurf ( C );
1205       }
1206       if ( CTool->GetColor ( lab, XCAFDoc_ColorSurf, C ) )
1207         style.SetColorSurf ( C );
1208       if ( CTool->GetColor ( lab, XCAFDoc_ColorCurv, C ) )
1209         style.SetColorCurv ( C );
1210       
1211       // commented, cause we are need to take reference from 
1212 //       if ( isComponent && lab == L && !isVisible)
1213 //         if ( !style.IsSetColorSurf() && !style.IsSetColorCurv() ) {
1214 //           getFatherColor ( L, CTool, style);
1215 //         }
1216       if ( ! style.IsSetColorCurv() && ! style.IsSetColorSurf() && isVisible ) continue;
1217
1218       TopoDS_Shape sub = XCAFDoc_ShapeTool::GetShape ( lab );
1219       settings.Bind ( sub, style );
1220     }
1221     
1222     if ( settings.Extent() <=0 ) continue;
1223
1224     // iterate on subshapes and create STEP styles
1225     Handle(StepVisual_StyledItem) override;
1226     TopTools_MapOfShape Map;
1227     
1228     MakeSTEPStyles(Styles,S,settings,override,Map,myMapCompMDGPR,DPDCs,ColRGBs,CTool,0,isComponent);
1229     
1230     // create MDGPR and record it in model
1231     Handle(StepVisual_MechanicalDesignGeometricPresentationRepresentation) aMDGPR;
1232
1233     if (!isComponent) {
1234       if ( myMapCompMDGPR.IsBound( aTopSh )) {
1235 #ifdef OCCT_DEBUG
1236         cerr << "Error: Current Top-Level shape have MDGPR already " << endl;
1237 #endif
1238       }
1239       Styles.CreateMDGPR ( Context, aMDGPR );
1240       if (!aMDGPR.IsNull())
1241         myMapCompMDGPR.Bind( aTopSh, aMDGPR );
1242     }
1243     else {
1244       // create SDR and add to model.
1245       Handle(XSControl_TransferWriter) TW = WS->TransferWriter();
1246       Handle(Transfer_FinderProcess) FP = TW->FinderProcess();
1247       Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper ( FP, S );
1248       Handle(StepShape_ContextDependentShapeRepresentation) CDSR;
1249       if ( FP->FindTypedTransient(mapper, 
1250                                   STANDARD_TYPE(StepShape_ContextDependentShapeRepresentation),
1251                                   CDSR) ) {
1252         // create SDR for NAUO
1253         Handle(StepRepr_ProductDefinitionShape) nullPDS; // important to be NULL
1254         Styles.CreateNAUOSRD( Context, CDSR, nullPDS );
1255         
1256         // search for MDGPR of the component top-level shape
1257         if ( myMapCompMDGPR.IsBound( aTopSh )) {
1258           aMDGPR = Handle(StepVisual_MechanicalDesignGeometricPresentationRepresentation)::DownCast( myMapCompMDGPR.Find( aTopSh ) );
1259         } else {
1260           aMDGPR = new StepVisual_MechanicalDesignGeometricPresentationRepresentation;
1261           Handle(TCollection_HAsciiString) ReprName = new TCollection_HAsciiString ( "" );
1262           aMDGPR->SetName( ReprName );
1263           aMDGPR->SetContextOfItems( Context );
1264           myMapCompMDGPR.Bind ( aTopSh, aMDGPR );
1265         }
1266         Handle(StepRepr_HArray1OfRepresentationItem) oldItems = aMDGPR->Items();
1267         Standard_Integer oldLengthlen = 0;
1268         if (!oldItems.IsNull())
1269           oldLengthlen = oldItems->Length();
1270         const Standard_Integer nbIt = oldLengthlen + Styles.NbStyles();
1271         if(!nbIt)
1272           continue;
1273         Handle(StepRepr_HArray1OfRepresentationItem) newItems =
1274           new StepRepr_HArray1OfRepresentationItem(1, nbIt);
1275         Standard_Integer si;
1276         Standard_Integer el = 1;
1277         for ( si=1; si <= oldLengthlen; si++ )
1278           newItems->SetValue( el++, oldItems->Value( si ) );
1279         for ( si=1; si <= Styles.NbStyles(); si++ ) {
1280           newItems->SetValue( el++, Styles.Style(si));
1281         }
1282        
1283         if (newItems->Length() > 0)
1284           aMDGPR->SetItems( newItems );
1285       } //end of work with CDSR
1286     }
1287     if ( !isVisible ) {
1288     // create invisibility item and refer for stiledItem
1289       Handle(StepVisual_Invisibility) Invsblt = new StepVisual_Invisibility();
1290       Handle(StepVisual_HArray1OfInvisibleItem) HInvsblItm = 
1291         new StepVisual_HArray1OfInvisibleItem (1,Styles.NbStyles());
1292       // put all style item into the harray
1293       for ( Standard_Integer si=1; si <= Styles.NbStyles(); si++ ) {
1294         Handle(StepRepr_RepresentationItem) styledItm = Styles.Style(si);
1295         StepVisual_InvisibleItem anInvItem;
1296         anInvItem.SetValue( styledItm );
1297         HInvsblItm->SetValue( si, anInvItem );
1298       }
1299       // set the invisibility of items
1300       Invsblt->Init( HInvsblItm );
1301       WS->Model()->AddWithRefs( Invsblt );
1302     }
1303   }
1304
1305   return Standard_True;
1306 }
1307
1308
1309 //=======================================================================
1310 //function : WriteNames
1311 //purpose  :
1312 //=======================================================================
1313
1314 Standard_Boolean STEPCAFControl_Writer::WriteNames (const Handle(XSControl_WorkSession) &WS,
1315                                                     const TDF_LabelSequence &labels) const
1316 {
1317   if ( labels.Length() <=0 ) return Standard_False;
1318
1319   // get working data
1320   Handle(Interface_InterfaceModel) Model = WS->Model();
1321   Handle(XSControl_TransferWriter) TW = WS->TransferWriter();
1322   Handle(Transfer_FinderProcess) FP = TW->FinderProcess();
1323 //  Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool( labels(1) );
1324 //  if ( STool.IsNull() ) return Standard_False;
1325
1326   // Iterate on requested shapes
1327   for ( Standard_Integer i=1; i <= labels.Length(); i++ ) {
1328     TDF_Label L = labels.Value(i);
1329
1330     // get name
1331     Handle(TCollection_HAsciiString) hName = new TCollection_HAsciiString;
1332     if ( ! GetLabelName (L, hName) ) continue;
1333 //    Handle(TDataStd_Name) N;
1334 //    if ( ! L.FindAttribute ( TDataStd_Name::GetID(), N ) ) continue;
1335 //    TCollection_ExtendedString name = N->Get();
1336 //    if ( name.Length() <=0 ) continue;
1337
1338     // find target STEP entity for the current shape
1339 //    TopoDS_Shape S;
1340 //    if ( ! XCAFDoc_ShapeTool::GetShape ( L, S ) ) continue;
1341     if ( ! myLabels.IsBound ( L ) ) continue; // not recorded as translated, skip
1342     TopoDS_Shape S = myLabels.Find ( L );
1343
1344     Handle(StepShape_ShapeDefinitionRepresentation) SDR;
1345     Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper ( FP, S );
1346     if ( ! FP->FindTypedTransient ( mapper, STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation), SDR ) ) {
1347 #ifdef OCCT_DEBUG
1348       cout << "Warning: Cannot find SDR for " << S.TShape()->DynamicType()->Name() << endl;
1349 #endif
1350       continue;
1351     }
1352
1353     // set the name to the PRODUCT
1354     Handle(StepRepr_PropertyDefinition) PropD = SDR->Definition().PropertyDefinition();
1355     if ( PropD.IsNull() ) continue;
1356     Handle(StepBasic_ProductDefinition) PD = PropD->Definition().ProductDefinition();
1357     if ( PD.IsNull() ) continue;
1358     Handle(StepBasic_Product) Prod = PD->Formation()->OfProduct();
1359
1360     Prod->SetId ( hName );
1361     Prod->SetName ( hName );
1362
1363     // write names for components of assemblies
1364     if ( XCAFDoc_ShapeTool::IsAssembly ( L ) ) {
1365       TDF_LabelSequence seq;
1366       XCAFDoc_ShapeTool::GetComponents ( L, seq );
1367       for (Standard_Integer k=1; k <= seq.Length(); k++) {
1368         TDF_Label lab = seq(k);
1369
1370         // get shape with correct location
1371         TDF_Label Lref;
1372         if ( ! XCAFDoc_ShapeTool::GetReferredShape ( lab, Lref ) || 
1373              ! myLabels.IsBound ( Lref ) ) continue;
1374         S = myLabels.Find ( Lref );
1375         S.Move ( XCAFDoc_ShapeTool::GetLocation ( lab ) );
1376         
1377         hName = new TCollection_HAsciiString;
1378         if ( ! GetLabelName (lab, hName) ) continue;
1379         
1380         // find the target CDSR corresponding to a shape
1381         mapper = TransferBRep::ShapeMapper ( FP, S );
1382         Handle(Transfer_Binder) binder = FP->Find ( mapper );
1383         Handle(StepShape_ContextDependentShapeRepresentation) CDSR;
1384         if ( ! FP->FindTypedTransient (mapper,STANDARD_TYPE(StepShape_ContextDependentShapeRepresentation), CDSR) ) 
1385           continue;
1386         Handle(StepRepr_ProductDefinitionShape) PDS = CDSR->RepresentedProductRelation();
1387         Handle(StepBasic_ProductDefinitionRelationship) NAUO = PDS->Definition().ProductDefinitionRelationship();
1388         if ( ! NAUO.IsNull() ) NAUO->SetName ( hName );
1389       }
1390     }
1391   }
1392
1393   return Standard_True;
1394 }
1395
1396
1397 //=======================================================================
1398 //function : WritePropsForLabel
1399 //purpose  :
1400 //=======================================================================
1401 static Standard_Boolean WritePropsForLabel(const Handle(XSControl_WorkSession) &WS,
1402                                            const Handle(XCAFDoc_ShapeTool) &aSTool,
1403                                            const STEPCAFControl_DataMapOfLabelShape &myLabels,
1404                                            const TDF_Label &L,
1405                                            const Standard_CString multi)
1406 {
1407   if(L.IsNull()) return Standard_False;
1408
1409   STEPConstruct_ValidationProps Props ( WS );
1410
1411   TopoDS_Shape S = aSTool->GetShape(L);
1412   if(S.IsNull()) return Standard_False;
1413
1414   if ( ! multi || XCAFDoc_ShapeTool::IsAssembly ( L ) ) {
1415     // write area
1416     Handle(XCAFDoc_Area) A;
1417     L.FindAttribute ( XCAFDoc_Area::GetID(), A );
1418     if ( ! A.IsNull() ) {
1419       Props.AddArea ( S, A->Get() );
1420     }
1421     // write volume
1422     Handle(XCAFDoc_Volume) V;
1423     L.FindAttribute ( XCAFDoc_Volume::GetID(), V );
1424     if ( ! V.IsNull() ) {
1425       Props.AddVolume ( S, V->Get() );
1426     }
1427   }
1428   // write centroid
1429   Handle(XCAFDoc_Centroid) C;
1430   L.FindAttribute ( XCAFDoc_Centroid::GetID(), C );
1431   if ( ! C.IsNull() ) {
1432     Props.AddCentroid ( S, C->Get() );
1433   }
1434
1435   if( XCAFDoc_ShapeTool::IsCompound(L) || XCAFDoc_ShapeTool::IsAssembly(L) ) {
1436     if(L.HasChild()) {
1437       for(Standard_Integer ich=1; ich<=L.NbChildren(); ich++) {
1438         WritePropsForLabel(WS,aSTool,myLabels,L.FindChild(ich),multi);
1439       }
1440     }
1441   }
1442
1443   return Standard_True;
1444 }
1445
1446
1447 //=======================================================================
1448 //function : WriteValProps
1449 //purpose  :
1450 //=======================================================================
1451
1452 Standard_Boolean STEPCAFControl_Writer::WriteValProps (const Handle(XSControl_WorkSession) &WS,
1453                                                        const TDF_LabelSequence &labels,
1454                                                        const Standard_CString multi) const
1455 {
1456   if ( labels.Length() <=0 ) return Standard_False;
1457
1458   // get working data
1459 //  STEPConstruct_ValidationProps Props ( WS );
1460   Handle(XCAFDoc_ShapeTool) aSTool = XCAFDoc_DocumentTool::ShapeTool( labels(1) );
1461
1462   // Iterate on requested shapes
1463   for ( Standard_Integer i=1; i <= labels.Length(); i++ ) {
1464     TDF_Label L = labels.Value(i);
1465
1466     WritePropsForLabel(WS,aSTool,myLabels,L,multi);
1467 /*    
1468     // find target STEP entity for the current shape
1469     if ( ! myLabels.IsBound ( L ) ) continue; // not recorded as translated, skip
1470     TopoDS_Shape S = myLabels.Find ( L );
1471
1472     // write area and volume (except for components in multifile mode)
1473     if ( ! multi || XCAFDoc_ShapeTool::IsAssembly ( L ) ) {
1474       Handle(XCAFDoc_Area) A;
1475       L.FindAttribute ( XCAFDoc_Area::GetID(), A );
1476       if ( ! A.IsNull() ) Props.AddArea ( S, A->Get() );
1477
1478       Handle(XCAFDoc_Volume) V;
1479       L.FindAttribute ( XCAFDoc_Volume::GetID(), V );
1480       if ( ! V.IsNull() ) Props.AddVolume ( S, V->Get() );
1481     }
1482
1483     // write centroid
1484     Handle(XCAFDoc_Centroid) C;
1485     L.FindAttribute ( XCAFDoc_Centroid::GetID(), C );
1486     if ( ! C.IsNull() ) Props.AddCentroid ( S, C->Get() );
1487
1488     // write centroid for components of assemblies
1489     if ( XCAFDoc_ShapeTool::IsAssembly ( L ) ) {
1490       TDF_LabelSequence seq;
1491       XCAFDoc_ShapeTool::GetComponents ( L, seq );
1492       for (Standard_Integer k=1; k <= seq.Length(); k++) {
1493         TDF_Label lab = seq(k);
1494
1495         // get shape with correct location
1496         TDF_Label Lref;
1497         if ( ! XCAFDoc_ShapeTool::GetReferredShape ( lab, Lref ) || 
1498              ! myLabels.IsBound ( Lref ) ) continue;
1499         TopLoc_Location Loc = XCAFDoc_ShapeTool::GetLocation ( lab );
1500         S = myLabels.Find ( Lref );
1501         S.Move ( Loc );
1502                 
1503         C.Nullify();
1504         lab.FindAttribute ( XCAFDoc_Centroid::GetID(), C );
1505         // if centroid is not assigned to an instance, 
1506         // use (shifted) centroid of original shape
1507         gp_Pnt center;
1508         if ( C.IsNull() ) {
1509           Lref.FindAttribute ( XCAFDoc_Centroid::GetID(), C );
1510           if ( C.IsNull() ) continue;
1511           center = C->Get().Transformed ( Loc.Transformation() );
1512         }
1513         else center = C->Get();
1514
1515         Props.AddCentroid ( S, center, Standard_True );
1516       }
1517     }
1518 */
1519   }
1520
1521   return Standard_True;
1522 }
1523
1524
1525 //=======================================================================
1526 //function : WriteLayers
1527 //purpose  : 
1528 //=======================================================================
1529
1530 Standard_Boolean STEPCAFControl_Writer::WriteLayers (const Handle(XSControl_WorkSession) &WS,
1531                                                      const TDF_LabelSequence  &labels ) const
1532 {
1533   
1534   if ( labels.Length() <=0 ) return Standard_False;
1535
1536   // get working data
1537   Handle(Interface_InterfaceModel) Model = WS->Model();
1538   Handle(XSControl_TransferWriter) TW = WS->TransferWriter();
1539   Handle(Transfer_FinderProcess) FP = TW->FinderProcess();
1540   Handle(XCAFDoc_LayerTool) LTool = XCAFDoc_DocumentTool::LayerTool( labels(1) );
1541   if (LTool.IsNull() ) return Standard_False;
1542
1543   TDF_LabelSequence LayerLS;
1544   LTool->GetLayerLabels(LayerLS);
1545   if ( LayerLS.Length() <=0 ) return Standard_False;
1546
1547   // Iterate on requested layers and for each layer take set of shapes.
1548   for ( Standard_Integer i=1; i <= LayerLS.Length(); i++ ) {
1549     TDF_Label L = LayerLS.Value(i);
1550     
1551     // get labels of shapes in that layer
1552     TDF_LabelSequence ShapeLs;
1553     LTool->GetShapesOfLayer(L, ShapeLs);
1554     if ( ShapeLs.Length() <=0 ) continue;
1555     
1556     // name of layer: if not set, is considered as being empty
1557     Handle(TCollection_HAsciiString) hName = new TCollection_HAsciiString;
1558     GetLabelName ( L, hName );
1559
1560     // Find target STEP entity for each shape and add to StepVisual_PresentationLayerAssignment items.
1561     TColStd_SequenceOfTransient seqRI;
1562     for ( Standard_Integer j=1; j <= ShapeLs.Length(); j++) {
1563       TDF_Label shLabel = ShapeLs.Value(j);
1564       if ( shLabel.IsNull() ) continue;
1565       
1566       // there is no way to assign layer to instance in STEP
1567       if ( XCAFDoc_ShapeTool::IsAssembly ( shLabel ) ||
1568            XCAFDoc_ShapeTool::IsReference ( shLabel ) )
1569         continue;
1570       
1571       // check that the shape is one of (uub)labels written during current transfer
1572       Standard_Integer k = 1;
1573       for ( ; k <= labels.Length(); k++ )
1574         if ( shLabel.IsDescendant ( labels(k) ) ) break;
1575       if ( k > labels.Length() ) continue;
1576
1577       // get target STEP entity
1578       TopoDS_Shape oneShape = XCAFDoc_ShapeTool::GetShape(shLabel);
1579       
1580       TopLoc_Location Loc;
1581       Standard_Integer nb = 
1582         FindEntities ( FP, oneShape, Loc, seqRI );
1583       if ( nb <=0 ) 
1584         FP->Messenger() << "Warning: Cannot find RI for " << oneShape.TShape()->DynamicType()->Name() << endl;
1585     }
1586     if ( seqRI.Length() <= 0 ) continue;
1587
1588     // analyze visibility
1589     Handle(StepVisual_PresentationLayerAssignment) StepLayerAs = new StepVisual_PresentationLayerAssignment;
1590     Handle(TCollection_HAsciiString) descr;
1591     Handle(TDataStd_UAttribute) aUAttr;
1592     Standard_Boolean isLinv = Standard_False;
1593     if (L.FindAttribute(XCAFDoc::InvisibleGUID(), aUAttr)) {
1594       descr = new TCollection_HAsciiString ("invisible");
1595 #ifdef OCCT_DEBUG
1596       FP->Messenger() << "\tLayer \"" << hName->String().ToCString() << "\" is invisible"<<endl;
1597 #endif
1598       isLinv = Standard_True;
1599     }
1600     else descr = new TCollection_HAsciiString ("visible");
1601     
1602     // create layer entity
1603     Handle(StepVisual_HArray1OfLayeredItem) HArrayOfLItem = 
1604       new StepVisual_HArray1OfLayeredItem ( 1, seqRI.Length() );
1605     for (Standard_Integer i1 = 1; i1<=seqRI.Length(); i1++) {
1606       StepVisual_LayeredItem LI;
1607       LI.SetValue ( seqRI.Value(i1) );
1608       HArrayOfLItem->SetValue( i1, LI );
1609     }
1610     StepLayerAs->Init(hName, descr, HArrayOfLItem);
1611     Model->AddWithRefs( StepLayerAs );
1612     // PTV 23.01.2003 add the invisibility AFTER adding layer into the model.
1613     // add the invisibility for the layer
1614     if (isLinv) {
1615       // Invisibility Item for containig invisible layers.
1616       Handle(StepVisual_HArray1OfInvisibleItem) HInvsblItm = new StepVisual_HArray1OfInvisibleItem (1,1);
1617       StepVisual_InvisibleItem InvIt;
1618       InvIt.SetValue( StepLayerAs );
1619       HInvsblItm->SetValue( 1, InvIt);
1620       
1621       Handle(StepVisual_Invisibility) Invsblt = new StepVisual_Invisibility();
1622       Invsblt->Init( HInvsblItm );
1623       Model->AddWithRefs( Invsblt );
1624     }
1625   }
1626   return Standard_True;
1627 }
1628
1629
1630 //=======================================================================
1631 //function : getSHUOstyle
1632 //purpose  : auxilary
1633 //=======================================================================
1634 static Standard_Boolean getSHUOstyle(const TDF_Label& aSHUOlab,
1635                                      const Handle(XCAFDoc_ColorTool)& CTool,
1636                                      XCAFPrs_Style& SHUOstyle)
1637 {
1638   Quantity_Color C;
1639   if (!CTool->IsVisible( aSHUOlab ) )
1640     SHUOstyle.SetVisibility(Standard_False);
1641   else {
1642     if ( CTool->GetColor ( aSHUOlab, XCAFDoc_ColorGen, C ) ) {
1643       SHUOstyle.SetColorCurv ( C );
1644       SHUOstyle.SetColorSurf ( C );
1645     }
1646     if ( CTool->GetColor ( aSHUOlab, XCAFDoc_ColorSurf, C ) )
1647       SHUOstyle.SetColorSurf ( C );
1648     if ( CTool->GetColor ( aSHUOlab, XCAFDoc_ColorCurv, C ) )
1649       SHUOstyle.SetColorCurv ( C );
1650   }
1651   if ( !SHUOstyle.IsSetColorCurv() && 
1652       !SHUOstyle.IsSetColorSurf() &&
1653       SHUOstyle.IsVisible() )
1654     return Standard_False;
1655   return Standard_True;
1656 }
1657
1658
1659 //=======================================================================
1660 //function : getProDefinitionOfNAUO
1661 //purpose  : auxilary
1662 //=======================================================================
1663 static Standard_Boolean getProDefinitionOfNAUO(const Handle(XSControl_WorkSession)& WS,
1664                                                const TopoDS_Shape& theShape,
1665                                                Handle(StepBasic_ProductDefinition)& PD,
1666                                                Handle(StepRepr_NextAssemblyUsageOccurrence)& NAUO,
1667                                                Standard_Boolean IsRelating)
1668 {
1669   if ( theShape.IsNull() )
1670     return Standard_False;
1671   // get CDSR
1672   Handle(XSControl_TransferWriter) TW = WS->TransferWriter();
1673   Handle(Transfer_FinderProcess) FP = TW->FinderProcess();
1674   Handle(StepShape_ContextDependentShapeRepresentation) CDSR;
1675   Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper ( FP, theShape );
1676   if (!FP->FindTypedTransient(mapper, 
1677                               STANDARD_TYPE(StepShape_ContextDependentShapeRepresentation),
1678                               CDSR))
1679     return Standard_False;
1680   // get PDS of NAUO
1681   Handle(StepRepr_ProductDefinitionShape) PDS = CDSR->RepresentedProductRelation();
1682   if (PDS.IsNull())
1683     return Standard_False;
1684   // get the NAUO entity
1685   Interface_Graph aGraph = WS->HGraph()->Graph();
1686   Interface_EntityIterator subs = aGraph.Shareds(PDS);
1687   for ( subs.Start(); subs.More(); subs.Next() ) {
1688     if (!subs.Value()->IsKind(STANDARD_TYPE(StepRepr_NextAssemblyUsageOccurrence)))
1689       continue;
1690     NAUO = Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(subs.Value());
1691     break;
1692   }
1693   if ( NAUO.IsNull() )
1694     return Standard_False;
1695   // get Relatinf or Related product definition
1696   if ( !IsRelating )
1697     PD = NAUO->RelatedProductDefinition();
1698   else
1699     PD = NAUO->RelatingProductDefinition();
1700   if ( PD.IsNull() )
1701     return Standard_False;
1702   return Standard_True;
1703 }
1704
1705
1706 //=======================================================================
1707 //function : writeSHUO
1708 //purpose  : auxilary
1709 //=======================================================================
1710 static Standard_Boolean writeSHUO (const Handle(XCAFDoc_GraphNode)& theSHUO,
1711                                    const Handle(XCAFDoc_ShapeTool)& theSTool,
1712                                    const Handle(XSControl_WorkSession)& WS,
1713                                    Handle(StepRepr_SpecifiedHigherUsageOccurrence)& theTopSHUO,
1714                                    TopoDS_Shape& NAUOShape,
1715                                    Handle(StepBasic_ProductDefinition)& theRelatingPD,
1716                                    Standard_Boolean& isDeepest)
1717 {
1718   // set the ProductDefinitionRelationship descriptin information as empty strings.
1719   Handle(TCollection_HAsciiString) EmptyString = new TCollection_HAsciiString("");
1720   
1721   TDF_LabelSequence aNextUsageLabs;
1722   theSTool->GetSHUONextUsage( theSHUO->Label(), aNextUsageLabs );
1723   Handle(XCAFDoc_GraphNode) NuSHUO;
1724   if ( theTopSHUO.IsNull() ) {
1725     // the top SHUO
1726     if (aNextUsageLabs.Length() < 1)
1727       return Standard_False;
1728     theSTool->GetSHUO( aNextUsageLabs.Value(1), NuSHUO );
1729     if (NuSHUO.IsNull())
1730       return Standard_False;
1731     // get relating product definition
1732     TopoDS_Shape aTopCompShape = theSTool->GetShape( theSHUO->Label().Father() ); 
1733     Handle(StepRepr_NextAssemblyUsageOccurrence) UUNAUO;
1734     if (!getProDefinitionOfNAUO( WS, aTopCompShape,
1735                                  theRelatingPD, UUNAUO, Standard_True ))
1736       return Standard_False;
1737     // get related product definition
1738     TopoDS_Shape aNUShape = theSTool->GetShape( NuSHUO->Label().Father() );
1739     Handle(StepBasic_ProductDefinition) aRelatedPD;
1740     Handle(StepRepr_NextAssemblyUsageOccurrence) NUNAUO;
1741     if (!getProDefinitionOfNAUO( WS, aNUShape,
1742                                  aRelatedPD, NUNAUO, Standard_False ))
1743       return Standard_False;
1744     
1745     theTopSHUO = new StepRepr_SpecifiedHigherUsageOccurrence;
1746     // create deepest shuo EmptyString
1747     theTopSHUO->Init(/*id*/EmptyString, /*name*/EmptyString,
1748                      /*no description*/Standard_False,/*description*/EmptyString,
1749                      theRelatingPD, aRelatedPD,
1750                      /*no ACURefDesignator*/Standard_False,/*ACURefDesignator*/EmptyString,
1751                      /*upper_usage*/UUNAUO, /*next_usage*/NUNAUO);
1752     // write the other SHUO.
1753     if(!writeSHUO( NuSHUO, theSTool, WS, theTopSHUO, NAUOShape, theRelatingPD, isDeepest )) {
1754       theTopSHUO.Nullify();
1755       return Standard_False;
1756     }
1757     
1758     return Standard_True;
1759   }
1760 //   Handle(XCAFDoc_GraphNode) NuSHUO;
1761   if ( aNextUsageLabs.Length() > 0) {
1762     // store SHUO recursive
1763 #ifdef OCCT_DEBUG
1764     if ( aNextUsageLabs.Length() > 1 )
1765       cout << "Warning: store only one next_usage of current SHUO"  << endl;
1766 #endif    
1767     theSTool->GetSHUO( aNextUsageLabs.Value(1), NuSHUO );
1768     Handle(StepRepr_SpecifiedHigherUsageOccurrence) aNUEntSHUO =
1769       new StepRepr_SpecifiedHigherUsageOccurrence;
1770     if (!writeSHUO( NuSHUO, theSTool, WS, aNUEntSHUO, NAUOShape, theRelatingPD, isDeepest ))
1771       return Standard_False;
1772     
1773     // store the deepest SHUO to the dociment
1774     TopoDS_Shape aNUSh, aUUSh;
1775     aNUSh = theSTool->GetShape( NuSHUO->Label().Father() );
1776     aUUSh = theSTool->GetShape( theSHUO->Label().Father() );
1777     // get relating PD with upper_usage and related PD with next_usage
1778     Handle(StepBasic_ProductDefinition) nullPD;// no need to use,case have shared <theRelatingPD>
1779     Handle(StepBasic_ProductDefinition) aRelatedPD;
1780     Handle(StepRepr_NextAssemblyUsageOccurrence) UUNAUO, NUNAUO;
1781     if (!getProDefinitionOfNAUO( WS, aUUSh, nullPD, UUNAUO, Standard_True ) ||
1782         !getProDefinitionOfNAUO( WS, aNUSh, aRelatedPD, NUNAUO, Standard_False )) {
1783 #ifdef OCCT_DEBUG
1784       cout << "Warning: cannot get related or relating PD" << endl;
1785 #endif
1786       return Standard_False;
1787     }
1788     aNUEntSHUO->Init(/*id*/EmptyString, /*name*/EmptyString,
1789                      /*no description*/Standard_False,/*description*/EmptyString,
1790                      theRelatingPD, aRelatedPD,
1791                      /*no ACURefDesignator*/Standard_False,/*ACURefDesignator*/EmptyString,
1792                      /*upper_usage*/theTopSHUO, /*next_usage*/NUNAUO);
1793     if ( isDeepest ) {
1794       isDeepest = Standard_False;
1795     }
1796     WS->Model()->AddWithRefs ( aNUEntSHUO );
1797     return Standard_True;
1798   } // end of recurse storing
1799     
1800   // get shape 
1801   TDF_Label aShapeL = theSHUO->Label().Father();
1802   NAUOShape = theSTool->GetShape( aShapeL );
1803   // return to the deepest level from SHUO shape level
1804   // it is because SHUO is attribute on deep level and shape level.
1805   isDeepest = Standard_True;
1806   return Standard_True;
1807 }
1808
1809
1810 //=======================================================================
1811 //function : createSHUOStyledItem
1812 //purpose  : auxilary
1813 //=======================================================================
1814 static Standard_Boolean createSHUOStyledItem (const XCAFPrs_Style& style,
1815                                               const Handle(StepRepr_ProductDefinitionShape)& PDS,
1816                                               const Handle(XSControl_WorkSession) &WS,
1817                                               const TopoDS_Shape& Sh,
1818                                               const Handle(XCAFDoc_ShapeTool)& STool,
1819                                               MoniTool_DataMapOfShapeTransient& myMapCompMDGPR)
1820 {
1821   // create styled item for the indicated SHUO and store to the model
1822   STEPConstruct_Styles Styles( WS );
1823   // translate colors to STEP
1824   Handle(StepVisual_Colour) surfColor, curvColor;
1825   if ( style.IsSetColorSurf() )
1826     surfColor = Styles.EncodeColor ( style.GetColorSurf() );
1827   if ( style.IsSetColorCurv() )
1828     curvColor = Styles.EncodeColor ( style.GetColorCurv() );
1829   Standard_Boolean isComponent = Standard_True;// cause need to get PSBC
1830   Handle(StepRepr_RepresentationItem) item;
1831   // set default color for invisible SHUO.
1832   Standard_Boolean isSetDefaultColor = Standard_False;
1833   if (surfColor.IsNull() && curvColor.IsNull() && !style.IsVisible() ) {
1834     surfColor = Styles.EncodeColor ( Quantity_Color( 1, 1, 1, Quantity_TOC_RGB ) );
1835     isSetDefaultColor = Standard_True;
1836   }
1837   Handle(StepVisual_PresentationStyleAssignment) PSA =
1838     Styles.MakeColorPSA ( item, surfColor, curvColor, isComponent );
1839   Handle(StepVisual_StyledItem) override; //null styled item
1840   
1841   // find the repr item of the shape
1842   Handle(XSControl_TransferWriter) TW = WS->TransferWriter();
1843   Handle(Transfer_FinderProcess) FP = TW->FinderProcess();
1844   Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper ( FP, Sh );
1845   Handle(StepShape_ContextDependentShapeRepresentation) CDSR;
1846   FP->FindTypedTransient(mapper, 
1847                          STANDARD_TYPE(StepShape_ContextDependentShapeRepresentation),
1848                          CDSR);
1849   if ( CDSR.IsNull() )
1850     return Standard_False;
1851   // find context
1852   Handle(StepRepr_RepresentationContext) Context = Styles.FindContext( Sh );
1853   TopoDS_Shape aTopSh = Sh;
1854   if (Context.IsNull()) {
1855     TDF_Label aTopShL = STool->FindShape(Sh, Standard_False);
1856     if (aTopShL.IsNull())
1857       return Standard_False;
1858     aTopSh = STool->GetShape( aTopShL );
1859     Context = Styles.FindContext ( aTopSh );
1860   }
1861   if (Context.IsNull())
1862     return Standard_False;
1863   // get representation item of the shape
1864   TopLoc_Location L;
1865   TColStd_SequenceOfTransient seqRI;
1866   FindEntities ( FP, Sh, L, seqRI );
1867 #ifdef OCCT_DEBUG
1868   if ( seqRI.Length() <=0 ) 
1869     FP->Messenger() << "Warning: Cannot find RI for " << Sh.TShape()->DynamicType()->Name() << endl;
1870 #endif
1871   item = Handle(StepRepr_RepresentationItem)::DownCast(seqRI(1));
1872   //get overridden styled item
1873   getStyledItem(Sh,STool, Styles, override,myMapCompMDGPR);
1874   
1875   // get STEP STYLED ITEM
1876   Handle(StepVisual_StyledItem) STEPstyle = Styles.AddStyle ( item, PSA, override );
1877   // create SR, SDR and all necessary references between them and ST, PDS, PSBC, GRC
1878   Styles.CreateNAUOSRD( Context, CDSR, PDS );
1879   
1880   // add step styled item of SHUO to the model
1881   // do it by additing styled item to the MDGPR
1882   if ( !aTopSh.IsNull() &&  !myMapCompMDGPR.IsBound( aTopSh ) ) {
1883     // create MDGPR and record it in model
1884 #ifdef OCCT_DEBUG
1885     cout << "Warning: " << __FILE__ << ": Create new MDGPR for SHUO instance"  << endl;
1886 #endif
1887     Handle(StepVisual_MechanicalDesignGeometricPresentationRepresentation) aMDGPR;
1888     Styles.CreateMDGPR ( Context, aMDGPR );
1889     if (!aMDGPR.IsNull())
1890       myMapCompMDGPR.Bind( aTopSh, aMDGPR );
1891   }
1892   else if ( !aTopSh.IsNull() &&  myMapCompMDGPR.IsBound( aTopSh ) ) {
1893     // get MDGPR of the top-level shape
1894     Handle(StepVisual_PresentationRepresentation) aMDGPR = 
1895       Handle(StepVisual_PresentationRepresentation)::DownCast( myMapCompMDGPR.Find( aTopSh ) );
1896     // get old styled items to not lose it
1897     Handle(StepRepr_HArray1OfRepresentationItem) oldItems = aMDGPR->Items();
1898     Standard_Integer oldLengthlen = 0;
1899     if (!oldItems.IsNull())
1900       oldLengthlen = oldItems->Length();
1901     // create new array of styled items by an olds and new one
1902     Handle(StepRepr_HArray1OfRepresentationItem) newItems =
1903       new StepRepr_HArray1OfRepresentationItem(1, oldLengthlen + 1);
1904     Standard_Integer si;
1905     Standard_Integer el = 1;
1906     for ( si=1; si <= oldLengthlen; si++ )
1907       newItems->SetValue( el++, oldItems->Value( si ) );
1908     newItems->SetValue (el++, STEPstyle);
1909     // init MDGPR be new array of styled items
1910     if (newItems->Length() > 0)
1911       aMDGPR->SetItems( newItems );
1912   }
1913   else {
1914     WS->Model()->AddWithRefs ( STEPstyle ); // add as root to the model, but it is not good
1915 #ifdef OCCT_DEBUG
1916     cout << "Warning: " << __FILE__ << ": adds styled item of SHUO as root, casue cannot find MDGPR" << endl;
1917 #endif
1918   }
1919   // create invisibility item for the styled item
1920   if ( !style.IsVisible() ) {
1921     if (isSetDefaultColor) {
1922       // try to set default color from top-level shape
1923       
1924       setDefaultInstanceColor(override, PSA);
1925     }
1926     // create invisibility item and refer for stiledItem
1927     Handle(StepVisual_Invisibility) Invsblt = new StepVisual_Invisibility();
1928     Handle(StepVisual_HArray1OfInvisibleItem) HInvsblItm = 
1929       new StepVisual_HArray1OfInvisibleItem (1,1);
1930     // put all style item into the harray
1931     StepVisual_InvisibleItem anInvItem;
1932     anInvItem.SetValue( STEPstyle );
1933     HInvsblItm->SetValue( 1, anInvItem );
1934     Invsblt->Init( HInvsblItm );
1935     WS->Model()->AddWithRefs( Invsblt );
1936   }
1937   
1938   return Standard_True;
1939 }
1940
1941
1942 //=======================================================================
1943 //function : WriteSHUOs
1944 //purpose  : 
1945 //=======================================================================
1946
1947 Standard_Boolean STEPCAFControl_Writer::WriteSHUOs (const Handle(XSControl_WorkSession) &WS,
1948                                                     const TDF_LabelSequence  &labels )
1949 {
1950   if ( labels.Length() <=0 ) return Standard_False;
1951
1952   // get working data
1953   Handle(Interface_InterfaceModel) Model = WS->Model();
1954   Handle(XSControl_TransferWriter) TW = WS->TransferWriter();
1955   Handle(Transfer_FinderProcess) FP = TW->FinderProcess();
1956   Handle(XCAFDoc_ColorTool) CTool = XCAFDoc_DocumentTool::ColorTool( labels(1) );
1957   if (CTool.IsNull() )
1958     return Standard_False;
1959   // map of transfered SHUO
1960   TColStd_MapOfTransient aMapOfMainSHUO;
1961 //   TColStd_IndexedDataMapOfTransientTransient aIndxMapOfSHUOEnt;
1962   // Iterate on requested shapes
1963   for ( Standard_Integer i=1; i <= labels.Length(); i++ ) {
1964     TDF_Label L = labels.Value(i);
1965     if ( ! myLabels.IsBound ( L ) ) continue; // not recorded as translated, skip
1966 //     TopoDS_Shape S = myLabels.Find ( L );
1967     if ( XCAFDoc_ShapeTool::IsAssembly ( L ) ) {
1968       TDF_LabelSequence seq;
1969       XCAFDoc_ShapeTool::GetComponents ( L, seq );
1970       // iterates on components of assembly
1971       for (Standard_Integer k=1; k <= seq.Length(); k++) {
1972         TDF_Label lab = seq(k);
1973         TDF_AttributeSequence anAttrSeq;
1974         CTool->ShapeTool()->GetAllComponentSHUO( lab, anAttrSeq );
1975         // work with SHUO
1976         for (Standard_Integer j = 1; j <= anAttrSeq.Length(); j++) {
1977           Handle(XCAFDoc_GraphNode) aSHUO = 
1978             Handle(XCAFDoc_GraphNode)::DownCast(anAttrSeq.Value( j ));
1979           // take label of SHUO
1980           TDF_Label aSHUOlab = aSHUO->Label();
1981           TDF_LabelSequence aUpLabels;
1982           // check is it SHUO of upper_usage
1983           CTool->ShapeTool()->GetSHUOUpperUsage( aSHUOlab, aUpLabels );
1984           if ( aUpLabels.Length() > 0 )
1985             continue; // transfer only main SHUO
1986           if ( aMapOfMainSHUO.Contains( aSHUO ) )
1987             continue; // do not try to transfer SHUO twice
1988           aMapOfMainSHUO.Add( aSHUO );
1989           // check if it is styled SHUO
1990           XCAFPrs_Style SHUOstyle;
1991           if ( !getSHUOstyle ( aSHUOlab, CTool, SHUOstyle ) ) {
1992 #ifdef OCCT_DEBUG
1993             cout << "Warning: " << __FILE__ << ": do not store SHUO without any style to the STEP model" << endl;
1994 #endif
1995             continue;
1996           }
1997           // write SHUO to the model amd then add structure type.
1998           TopoDS_Shape NAUOShape; // shape of the deepest NAUO in the SHUO structure
1999           Standard_Boolean isDeepest = Standard_False;
2000           Handle(StepRepr_SpecifiedHigherUsageOccurrence) anEntOfSHUO;
2001           Handle(StepBasic_ProductDefinition) aRelatingPD;
2002           // create the top SHUO and all other.
2003           writeSHUO( aSHUO, CTool->ShapeTool(), WS, anEntOfSHUO, NAUOShape, aRelatingPD, isDeepest );
2004           if ( anEntOfSHUO.IsNull() || NAUOShape.IsNull() ) {
2005 #ifdef OCCT_DEBUG
2006             cout << "Warning: " << __FILE__ << ": Cannot store SHUO" << endl;
2007 #endif
2008             continue;
2009           }
2010           // create new Product Definition Shape for TOP SHUO
2011 #ifdef OCCT_DEBUG
2012             cout << "Info: " << __FILE__ << ": Create NEW PDS for current SHUO " << endl;
2013 #endif
2014           Handle(StepRepr_ProductDefinitionShape) PDS = new StepRepr_ProductDefinitionShape;
2015           Handle(TCollection_HAsciiString) aPDSname = new TCollection_HAsciiString("SHUO");
2016           Handle(TCollection_HAsciiString) descrStr = new TCollection_HAsciiString("");
2017           StepRepr_CharacterizedDefinition aCharDef;
2018           aCharDef.SetValue( anEntOfSHUO );
2019           PDS->Init( aPDSname, Standard_False, descrStr, aCharDef );
2020           
2021           // create styled item for SHUO and add to the model
2022           createSHUOStyledItem ( SHUOstyle, PDS, WS, NAUOShape, CTool->ShapeTool(), myMapCompMDGPR );
2023           
2024         } // end work with SHUO
2025       } // end of an assembly components
2026     } // end of IsAssembly case
2027     // nothing to do if it is not assembly
2028     continue;
2029   } // end of iterates on indicated labels
2030   return Standard_True;
2031 }
2032
2033
2034 //=======================================================================
2035 //function : FindPDSforDGT
2036 //purpose  : auxilary: find PDS for AdvancedFace or EdgeCurve for creation
2037 //                     needed ShapeAspect in D&GT structure
2038 //=======================================================================
2039 static Standard_Boolean FindPDSforDGT(const Interface_Graph &aGraph,
2040                                       const Handle(Standard_Transient) &ent,
2041                                       Handle(StepRepr_ProductDefinitionShape) &PDS,
2042                                       Handle(StepRepr_RepresentationContext) &RC,
2043                                       Handle(StepShape_AdvancedFace) &AF,
2044                                       Handle(StepShape_EdgeCurve) &EC)
2045 {
2046   if( !ent->IsKind(STANDARD_TYPE(StepShape_EdgeCurve)) && 
2047       !ent->IsKind(STANDARD_TYPE(StepShape_AdvancedFace)) ) 
2048     return Standard_False;
2049
2050   AF = Handle(StepShape_AdvancedFace)::DownCast(ent);
2051   if( ent->IsKind(STANDARD_TYPE(StepShape_EdgeCurve)) ) {
2052     EC = Handle(StepShape_EdgeCurve)::DownCast(ent);
2053     Interface_EntityIterator subs = aGraph.Sharings(EC);
2054     for(subs.Start(); subs.More() && AF.IsNull(); subs.Next()) {
2055       Handle(StepShape_OrientedEdge) OE = Handle(StepShape_OrientedEdge)::DownCast(subs.Value());
2056       if(OE.IsNull()) continue;
2057       Interface_EntityIterator subs1 = aGraph.Sharings(OE);
2058       for(subs1.Start(); subs1.More() && AF.IsNull(); subs1.Next()) {
2059         Handle(StepShape_EdgeLoop) EL = Handle(StepShape_EdgeLoop)::DownCast(subs1.Value());
2060         if(EL.IsNull()) continue;
2061         Interface_EntityIterator subs2 = aGraph.Sharings(EL);
2062         for(subs2.Start(); subs2.More() && AF.IsNull(); subs2.Next()) {
2063           Handle(StepShape_FaceBound) FB = Handle(StepShape_FaceBound)::DownCast(subs2.Value());
2064           if(FB.IsNull()) continue;
2065           Interface_EntityIterator subs3 = aGraph.Sharings(FB);
2066           for(subs3.Start(); subs3.More() && AF.IsNull(); subs3.Next()) {
2067             AF = Handle(StepShape_AdvancedFace)::DownCast(subs3.Value());
2068           }
2069         }
2070       }
2071     }
2072   }
2073   if(AF.IsNull()) return Standard_False;
2074
2075   Interface_EntityIterator subs = aGraph.Sharings(AF);
2076   for(subs.Start(); subs.More() && PDS.IsNull(); subs.Next()) {
2077     Handle(StepShape_ConnectedFaceSet) CFS =
2078       Handle(StepShape_ConnectedFaceSet)::DownCast(subs.Value());
2079     if(CFS.IsNull()) continue;
2080     Interface_EntityIterator subs1 = aGraph.Sharings(CFS);
2081     for(subs1.Start(); subs1.More() && PDS.IsNull(); subs1.Next()) {
2082       Handle(StepRepr_RepresentationItem) RI = 
2083         Handle(StepRepr_RepresentationItem)::DownCast(subs1.Value());
2084       if(RI.IsNull()) continue;
2085       Interface_EntityIterator subs2 = aGraph.Sharings(RI);
2086       for(subs2.Start(); subs2.More() && PDS.IsNull(); subs2.Next()) {
2087         Handle(StepShape_ShapeRepresentation) SR = 
2088           Handle(StepShape_ShapeRepresentation)::DownCast(subs2.Value());
2089         if(SR.IsNull()) continue;
2090         RC = SR->ContextOfItems();
2091         Interface_EntityIterator subs3 = aGraph.Sharings(SR);
2092         for(subs3.Start(); subs3.More() && PDS.IsNull(); subs3.Next()) {
2093           Handle(StepShape_ShapeDefinitionRepresentation) SDR = 
2094             Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(subs3.Value());
2095           if(SDR.IsNull()) continue;
2096           Handle(StepRepr_PropertyDefinition) PropD = SDR->Definition().PropertyDefinition();
2097           if(PropD.IsNull()) continue;
2098           PDS = Handle(StepRepr_ProductDefinitionShape)::DownCast(PropD);
2099         }
2100       }
2101     }
2102   }
2103   
2104   return Standard_True;
2105 }
2106
2107 //=======================================================================
2108 //function : GetUnit
2109 //purpose  : auxiliary
2110 //=======================================================================
2111
2112 static StepBasic_Unit GetUnit(const Handle(StepRepr_RepresentationContext)& theRC,
2113                               const Standard_Boolean isAngle = Standard_False)
2114 {
2115   StepBasic_Unit aUnit;
2116   if (isAngle) {
2117     Handle(StepBasic_SiUnitAndPlaneAngleUnit) aSiPAU;
2118     Handle(StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext) aCtx =
2119       Handle(StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext)::DownCast(theRC);
2120     if(!aCtx.IsNull()) {
2121       for(Standard_Integer j = 1; j <= aCtx->NbUnits(); j++) {
2122         if(aCtx->UnitsValue(j)->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndPlaneAngleUnit))) {
2123           aSiPAU = Handle(StepBasic_SiUnitAndPlaneAngleUnit)::DownCast(aCtx->UnitsValue(j));
2124           break;
2125         }
2126       }
2127     }
2128     if(aSiPAU.IsNull()) {
2129       Handle(StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx) aCtx1 =
2130         Handle(StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx)::DownCast(theRC);
2131       if(!aCtx1.IsNull()) {
2132         for(Standard_Integer j = 1; j <= aCtx1->NbUnits(); j++) {
2133           if(aCtx1->UnitsValue(j)->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndPlaneAngleUnit))) {
2134             aSiPAU = Handle(StepBasic_SiUnitAndPlaneAngleUnit)::DownCast(aCtx1->UnitsValue(j));
2135             break;
2136           }
2137         }
2138       }
2139     }
2140     if(aSiPAU.IsNull())
2141       aSiPAU = new StepBasic_SiUnitAndPlaneAngleUnit;
2142     aUnit.SetValue(aSiPAU);
2143   }
2144   else {
2145     Handle(StepBasic_SiUnitAndLengthUnit) aSiLU;
2146     Handle(StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext) aCtx =
2147       Handle(StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext)::DownCast(theRC);
2148     if(!aCtx.IsNull()) {
2149       for(Standard_Integer j = 1; j <= aCtx->NbUnits(); j++) {
2150         if(aCtx->UnitsValue(j)->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndLengthUnit))) {
2151           aSiLU = Handle(StepBasic_SiUnitAndLengthUnit)::DownCast(aCtx->UnitsValue(j));
2152           break;
2153         }
2154       }
2155     }
2156     if(aSiLU.IsNull()) {
2157       Handle(StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx) aCtx1 =
2158         Handle(StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx)::DownCast(theRC);
2159       if(!aCtx1.IsNull()) {
2160         for(Standard_Integer j = 1; j <= aCtx1->NbUnits(); j++) {
2161           if(aCtx1->UnitsValue(j)->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndLengthUnit))) {
2162             aSiLU = Handle(StepBasic_SiUnitAndLengthUnit)::DownCast(aCtx1->UnitsValue(j));
2163             break;
2164           }
2165         }
2166       }
2167     }
2168     if(aSiLU.IsNull())
2169       aSiLU = new StepBasic_SiUnitAndLengthUnit;
2170     aUnit.SetValue(aSiLU);
2171   }
2172   return aUnit;
2173 }
2174
2175 //=======================================================================
2176 //function : CreateDimValue
2177 //purpose  : auxiliary
2178 //======================================================================
2179 static Handle(StepRepr_ReprItemAndMeasureWithUnit) CreateDimValue(const Standard_Real theValue,
2180                                                                   const StepBasic_Unit theUnit,
2181                                                                   const Handle(TCollection_HAsciiString)& theName,
2182                                                                   const Standard_CString theMeasureName,
2183                                                                   const Standard_Boolean isAngle,
2184                                                                   const Standard_Boolean isQualified = Standard_False,
2185                                                                   const Handle(StepShape_QualifiedRepresentationItem)& theQRI = NULL)
2186 {
2187   Handle(StepRepr_RepresentationItem) aReprItem = new StepRepr_RepresentationItem();
2188   aReprItem->Init(new TCollection_HAsciiString(theName));
2189   Handle(StepBasic_MeasureWithUnit) aMWU = new StepBasic_MeasureWithUnit();
2190   Handle(StepBasic_MeasureValueMember) aValueMember = new StepBasic_MeasureValueMember();
2191   aValueMember->SetName(theMeasureName);
2192   aValueMember->SetReal(theValue);
2193   aMWU->Init(aValueMember, theUnit);
2194   if (isQualified) {
2195     if (isAngle) {
2196       // Angle & with qualifiers
2197       Handle(StepRepr_ReprItemAndPlaneAngleMeasureWithUnitAndQRI) anItem = 
2198         new StepRepr_ReprItemAndPlaneAngleMeasureWithUnitAndQRI();
2199       anItem->Init(aMWU, aReprItem, theQRI);
2200       return anItem;
2201     }
2202     else {
2203       // Length & with qualifiers
2204       Handle(StepRepr_ReprItemAndLengthMeasureWithUnitAndQRI) anItem = 
2205         new StepRepr_ReprItemAndLengthMeasureWithUnitAndQRI();
2206       anItem->Init(aMWU, aReprItem, theQRI);
2207       return anItem;
2208     }
2209   }
2210   else {
2211     if (isAngle) {
2212       // Angle & without qualifiers
2213       Handle(StepRepr_ReprItemAndPlaneAngleMeasureWithUnit) anItem = 
2214         new StepRepr_ReprItemAndPlaneAngleMeasureWithUnit();
2215       anItem->Init(aMWU, aReprItem);
2216       return anItem;
2217     }
2218     else {
2219       // Length & without qualifiers
2220       Handle(StepRepr_ReprItemAndLengthMeasureWithUnit) anItem = 
2221         new StepRepr_ReprItemAndLengthMeasureWithUnit();
2222       anItem->Init(aMWU, aReprItem);
2223       return anItem;
2224     }
2225   }
2226 }
2227
2228 //=======================================================================
2229 //function : WriteShapeAspect
2230 //purpose  : auxiliary (write Shape_Aspect entity for given shape)
2231 //=======================================================================
2232
2233 static Handle(StepRepr_ShapeAspect) WriteShapeAspect (const Handle(XSControl_WorkSession) &WS,
2234                                                       const TDF_Label theLabel,
2235                                                       const TopoDS_Shape theShape,
2236                                                       Handle(StepRepr_RepresentationContext)& theRC,
2237                                                       Handle(StepAP242_GeometricItemSpecificUsage)& theGISU)
2238 {
2239   // Get working data
2240   Handle(Interface_InterfaceModel) Model = WS->Model();
2241   Handle(XSControl_TransferWriter) TW = WS->TransferWriter();
2242   Handle(Transfer_FinderProcess) FP = TW->FinderProcess();
2243   const Handle(Interface_HGraph) aHGraph = WS->HGraph();
2244   if (aHGraph.IsNull())
2245     return NULL;
2246   Interface_Graph aGraph = aHGraph->Graph();
2247
2248   TopLoc_Location aLoc;
2249   TColStd_SequenceOfTransient aSeqRI;
2250   FindEntities( FP, theShape, aLoc, aSeqRI );
2251   if ( aSeqRI.Length() <= 0 ) {
2252     FP->Messenger() << "Warning: Cannot find RI for "<<theShape.TShape()->DynamicType()->Name()<<endl;
2253     return NULL;
2254   }
2255
2256   Handle(StepRepr_ProductDefinitionShape) aPDS;
2257   Handle(StepRepr_RepresentationContext) aRC;
2258   Handle(Standard_Transient) anEnt = aSeqRI.Value(1);
2259   Handle(StepShape_AdvancedFace) anAF;
2260   Handle(StepShape_EdgeCurve) anEC;
2261   FindPDSforDGT(aGraph, anEnt, aPDS, aRC, anAF, anEC);
2262   if(aPDS.IsNull()) 
2263     return NULL;
2264
2265   theRC = aRC;
2266   // Shape_Aspect
2267   Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString();
2268   Handle(TDataStd_Name) aNameAttr;
2269   if (theLabel.FindAttribute(TDataStd_Name::GetID(), aNameAttr)) {
2270     aName = new TCollection_HAsciiString(TCollection_AsciiString(aNameAttr->Get(), '?'));
2271     Standard_Integer aFirstSpace = aName->Search(" ");
2272     if (aFirstSpace != -1)
2273       aName = aName->SubString(aFirstSpace + 1, aName->Length());
2274     else
2275       aName = new TCollection_HAsciiString();
2276   }
2277   Handle(TCollection_HAsciiString) aDescription = new TCollection_HAsciiString();
2278   Handle(StepRepr_ShapeAspect) aSA = new StepRepr_ShapeAspect;
2279   aSA->Init(aName, aDescription, aPDS, StepData_LTrue);
2280
2281   // Geometric_Item_Specific_Usage
2282   Handle(StepAP242_GeometricItemSpecificUsage) aGISU = new StepAP242_GeometricItemSpecificUsage();
2283   StepAP242_ItemIdentifiedRepresentationUsageDefinition aDefinition;
2284   aDefinition.SetValue(aSA);
2285   Handle(StepRepr_HArray1OfRepresentationItem) anReprItems = new StepRepr_HArray1OfRepresentationItem(1, 1);
2286   Handle(StepRepr_RepresentationItem) anIdentifiedItem = Handle(StepRepr_RepresentationItem)::DownCast(anEnt);
2287   anReprItems->SetValue(1, anIdentifiedItem);
2288   Interface_EntityIterator subs = aGraph.Sharings(aPDS);
2289   Handle(StepShape_ShapeDefinitionRepresentation) aSDR;
2290   for (subs.Start(); subs.More() && aSDR.IsNull(); subs.Next()) {
2291     Handle(Standard_Transient) anEntity = subs.Value();
2292     aSDR = Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(anEntity);
2293   }
2294   if (aSDR.IsNull())
2295     return NULL;
2296
2297   // Set entities to model
2298   aGISU->Init(aName, aDescription, aDefinition, aSDR->UsedRepresentation(), anReprItems);
2299   Model->AddWithRefs(aSA);
2300   Model->AddWithRefs(aGISU);
2301   theGISU = aGISU;
2302   return aSA;
2303 }
2304
2305 //=======================================================================
2306 //function : WriteDatumAP242
2307 //purpose  : auxiliary (write Datum entity for given shape or write all 
2308 //           necessary entities and link them to already written datum 
2309 //           in case of multiple features association)
2310 //=======================================================================
2311 static Handle(StepDimTol_Datum) WriteDatumAP242(const Handle(XSControl_WorkSession) &WS,
2312                                                 const TDF_Label theShapeL,
2313                                                 const TDF_Label theDatumL,
2314                                                 const Standard_Boolean isFirstDTarget,
2315                                                 const Handle(StepDimTol_Datum) theWrittenDatum)
2316 {
2317   // Get working data
2318   Handle(Interface_InterfaceModel) Model = WS->Model();
2319   Handle(XSControl_TransferWriter) TW = WS->TransferWriter();
2320   Handle(Transfer_FinderProcess) FP = TW->FinderProcess();
2321   const Handle(Interface_HGraph) aHGraph = WS->HGraph();
2322   if (aHGraph.IsNull())
2323     return NULL;
2324   Interface_Graph aGraph = aHGraph->Graph();
2325
2326   Handle(StepRepr_ShapeAspect) aSA;
2327   Handle(StepAP242_GeometricItemSpecificUsage) aGISU;
2328   // Link with datum feature
2329   Handle(StepRepr_ProductDefinitionShape) aPDS;
2330   Handle(StepRepr_RepresentationContext) aRC;
2331   Handle(Standard_Transient) anEnt;
2332   Handle(StepShape_AdvancedFace) anAF;
2333   Handle(StepShape_EdgeCurve) anEC;
2334   TopoDS_Shape aShape;
2335   TopLoc_Location aLoc;
2336   TColStd_SequenceOfTransient aSeqRI;
2337
2338   aShape = XCAFDoc_ShapeTool::GetShape(theShapeL);
2339   FindEntities( FP, aShape, aLoc, aSeqRI );
2340   if ( aSeqRI.Length() <= 0 ) {
2341     FP->Messenger() << "Warning: Cannot find RI for "<<aShape.TShape()->DynamicType()->Name()<<endl;
2342     return NULL;
2343   }
2344   anEnt = aSeqRI.Value(1);
2345   FindPDSforDGT(aGraph, anEnt, aPDS, aRC, anAF, anEC);
2346   if (aPDS.IsNull()) 
2347     return NULL;
2348
2349   aSA = WriteShapeAspect(WS, theDatumL, aShape, aRC, aGISU);
2350   if (aSA.IsNull())
2351     return NULL;
2352   Standard_Integer aSANum = Model->Number(aSA);
2353   Standard_Integer aGISUNum = Model->Number(aGISU);
2354   // Find if datum has datum targets and get common datum attributes
2355   Handle(XCAFDoc_Datum) aDatumAttr;
2356   if (!theDatumL.FindAttribute(XCAFDoc_Datum::GetID(), aDatumAttr)) 
2357     return NULL;
2358   Handle(XCAFDimTolObjects_DatumObject) anObject = aDatumAttr->GetObject();
2359   if (anObject.IsNull())
2360     return NULL;
2361   Standard_Boolean isSimpleDatum = !anObject->IsDatumTarget();
2362   Handle(TCollection_HAsciiString) anIdentifier = anObject->GetName();
2363   Handle(TCollection_HAsciiString) aTargetId = (anObject->GetDatumTargetNumber() == 0 ? 
2364     new TCollection_HAsciiString() : new TCollection_HAsciiString(anObject->GetDatumTargetNumber()));
2365
2366   // If datum type is area, but there is no area in object, write as simple datum
2367   if (anObject->GetDatumTargetType() == XCAFDimTolObjects_DatumTargetType_Area &&
2368     anObject->GetDatumTarget().IsNull())
2369     isSimpleDatum = Standard_True;
2370
2371   // Simple datum
2372   if (isSimpleDatum) {
2373     Handle(StepDimTol_DatumFeature) aDF = new StepDimTol_DatumFeature();
2374     aDF->Init(new TCollection_HAsciiString(), new TCollection_HAsciiString(), aSA->OfShape(), aSA->ProductDefinitional());
2375     Model->ReplaceEntity(aSANum, aDF);
2376     aSA = aDF;
2377     StepAP242_ItemIdentifiedRepresentationUsageDefinition aDefinition;
2378     aDefinition.SetValue(aDF);
2379     aGISU->SetDefinition(aDefinition);
2380     Model->ReplaceEntity(aGISUNum, aGISU);
2381   }
2382   // Datum with datum targets
2383   else {
2384     XCAFDimTolObjects_DatumTargetType aDatumType = anObject->GetDatumTargetType();
2385     Handle(StepDimTol_DatumTarget) aDatumTarget;
2386     // Note: the given way to write such datum type may be incorrect (too little information)
2387     if (aDatumType == XCAFDimTolObjects_DatumTargetType_Area) {
2388       TopoDS_Shape aDTShape = anObject->GetDatumTarget();
2389       Handle(StepAP242_GeometricItemSpecificUsage) anAreaGISU;
2390       Handle(StepRepr_ShapeAspect) anAreaSA = WriteShapeAspect(WS, theDatumL, aDTShape, aRC, anAreaGISU);
2391       aSANum = Model->Number(anAreaSA);
2392       aGISUNum = Model->Number(anAreaGISU);
2393       Handle(StepDimTol_DatumTarget) aDT = new StepDimTol_DatumTarget();
2394       aDT->Init(new TCollection_HAsciiString(), new TCollection_HAsciiString("area"), anAreaSA->OfShape(),
2395         anAreaSA->ProductDefinitional(), aTargetId);
2396       Model->ReplaceEntity(aSANum, aDT);
2397       StepAP242_ItemIdentifiedRepresentationUsageDefinition aDefinition;
2398       aDefinition.SetValue(aDT);
2399       anAreaGISU->SetDefinition(aDefinition);
2400       Model->ReplaceEntity(aGISUNum, anAreaGISU);
2401   }
2402     else {
2403       Handle(StepDimTol_PlacedDatumTargetFeature) aPDTF = new StepDimTol_PlacedDatumTargetFeature();
2404       aPDTF->Init(new TCollection_HAsciiString(), STEPCAFControl_GDTProperty::GetDatumTargetName(aDatumType),
2405         aPDS, StepData_LTrue, aTargetId);
2406       Model->AddWithRefs(aPDTF);
2407       aDatumTarget = aPDTF;
2408       // Datum targets
2409       Handle(StepRepr_PropertyDefinition) aPD = new StepRepr_PropertyDefinition();
2410       StepRepr_CharacterizedDefinition aCDefinition;
2411       aCDefinition.SetValue(aPDTF);
2412       aPD->Init(new TCollection_HAsciiString(), Standard_False, NULL, aCDefinition);
2413       Handle(StepShape_ShapeRepresentationWithParameters) aSRWP = new StepShape_ShapeRepresentationWithParameters();
2414       // Common for all datum targets
2415       StepBasic_Unit aUnit = GetUnit(aRC);
2416       gp_Ax2 aDTAxis = anObject->GetDatumTargetAxis();
2417       Handle(StepGeom_Axis2Placement3d) anA2P3D = 
2418         STEPCAFControl_GDTProperty::GetAxis2Placement3D(aDTAxis);
2419       Handle(StepRepr_HArray1OfRepresentationItem) anItems;
2420       // Process each datum target type
2421       if (aDatumType == XCAFDimTolObjects_DatumTargetType_Point) {
2422         anItems = new StepRepr_HArray1OfRepresentationItem(1, 1);
2423       }
2424       else  {
2425         Handle(TCollection_HAsciiString) aTargetValueName;
2426         if (aDatumType == XCAFDimTolObjects_DatumTargetType_Line) {
2427           anItems = new StepRepr_HArray1OfRepresentationItem(1, 2);
2428           aTargetValueName = new TCollection_HAsciiString("target length");
2429         }
2430         else if (aDatumType == XCAFDimTolObjects_DatumTargetType_Rectangle) {
2431           anItems = new StepRepr_HArray1OfRepresentationItem(1, 3);
2432           aTargetValueName = new TCollection_HAsciiString("target length");
2433           // Additional value
2434           Handle(StepRepr_ReprItemAndMeasureWithUnit) aTargetValue = CreateDimValue(anObject->GetDatumTargetWidth(),
2435             aUnit, new TCollection_HAsciiString("target width"), "POSITIVE_LENGTH_MEASURE", Standard_False);
2436           anItems->SetValue(2, aTargetValue);
2437           Model->AddWithRefs(aTargetValue);
2438         }
2439         else if (aDatumType == XCAFDimTolObjects_DatumTargetType_Circle) {
2440           anItems = new StepRepr_HArray1OfRepresentationItem(1, 2);
2441           aTargetValueName = new TCollection_HAsciiString("target diameter");
2442         }
2443         // Value
2444         Handle(StepRepr_ReprItemAndMeasureWithUnit) aTargetValue= CreateDimValue(anObject->GetDatumTargetLength(),
2445           aUnit, aTargetValueName, "POSITIVE_LENGTH_MEASURE", Standard_False);
2446         anItems->SetValue(1, aTargetValue);
2447         Model->AddWithRefs(aTargetValue);
2448       }
2449       anItems->SetValue(anItems->Length(), anA2P3D);
2450       aSRWP->Init(new TCollection_HAsciiString(), anItems, aRC);
2451   
2452       // Create and write auxiliary entities
2453       Handle (StepShape_ShapeDefinitionRepresentation) aSDR = new StepShape_ShapeDefinitionRepresentation();
2454       StepRepr_RepresentedDefinition aRDefinition;
2455       aRDefinition.SetValue(aPD);
2456       aSDR->Init(aRDefinition, aSRWP);
2457       Model->AddWithRefs(aPD);
2458       Model->AddWithRefs(aSRWP);
2459       Model->AddWithRefs(aSDR);
2460     }
2461     // Link datum target to datum feature
2462     Handle(StepRepr_FeatureForDatumTargetRelationship) aFFDTR = new StepRepr_FeatureForDatumTargetRelationship();
2463     aFFDTR->Init(new TCollection_HAsciiString(), Standard_False, NULL, aDatumTarget, aSA);
2464     Model->AddWithRefs(aFFDTR);
2465     aSA = aDatumTarget;
2466   }
2467
2468   // Datum
2469   Handle(StepDimTol_Datum) aDatum = theWrittenDatum;
2470   if (isFirstDTarget) {
2471     aDatum = new StepDimTol_Datum();
2472     aDatum->Init(new TCollection_HAsciiString(), new TCollection_HAsciiString(), aPDS, StepData_LTrue, anIdentifier);
2473     Model->AddWithRefs(aDatum);
2474   }
2475
2476   // Shape_Aspect_Relationship
2477   Handle(StepRepr_ShapeAspectRelationship) aSAR = new StepRepr_ShapeAspectRelationship();
2478   aSAR->Init(new TCollection_HAsciiString(), Standard_False, NULL, aSA, aDatum);
2479   Model->AddWithRefs(aSAR);
2480
2481   // Auxiliary entities
2482   // Property_Definition
2483   Handle(StepRepr_PropertyDefinition) aPD = new StepRepr_PropertyDefinition();
2484   Handle(TCollection_HAsciiString) aPDName = new TCollection_HAsciiString("Datum Feature Symbol ");
2485   aPDName = aPDName->Cat(anIdentifier)->Cat(aTargetId);
2486   StepRepr_CharacterizedDefinition aCD;
2487   aCD.SetValue(aSA);
2488   aPD->Init(aPDName, Standard_False, NULL, aCD);
2489   Model->AddWithRefs(aPD);
2490   // Shape_Representation
2491   Handle(StepShape_ShapeRepresentation) aShapeRepr = new StepShape_ShapeRepresentation();
2492   aShapeRepr->Init(aPDName, aGISU->IdentifiedItem(), aRC);
2493   Model->AddWithRefs(aShapeRepr);
2494   // Shape_Definition_Representation
2495   Handle (StepShape_ShapeDefinitionRepresentation) aSDR = new StepShape_ShapeDefinitionRepresentation();
2496   StepRepr_RepresentedDefinition aRDefinition;
2497   aRDefinition.SetValue(aPD);
2498   aSDR->Init(aRDefinition, aShapeRepr);
2499   Model->AddWithRefs(aSDR);
2500
2501   return aDatum;
2502 }
2503
2504 //=======================================================================
2505 //function : WriteDimValues
2506 //purpose  : auxiliary (write all data for given dimension: values, 
2507 //           qualifiers, modifiers, orientation and tolerance class)
2508 //======================================================================
2509 static void WriteDimValues(const Handle(XSControl_WorkSession) &WS,
2510                            const Handle(XCAFDimTolObjects_DimensionObject) theObject,
2511                            const Handle(StepRepr_RepresentationContext) theRC,
2512                            const StepShape_DimensionalCharacteristic theDimension)
2513 {
2514   // Get working data
2515   Handle(Interface_InterfaceModel) aModel = WS->Model();
2516   XCAFDimTolObjects_DimensionModifiersSequence aModifiers = theObject->GetModifiers();
2517   Handle(Standard_Transient) aDim = theDimension.Value();
2518   Standard_Boolean isAngle = aDim->IsKind(STANDARD_TYPE(StepShape_AngularLocation)) ||
2519                              aDim->IsKind(STANDARD_TYPE(StepShape_AngularSize));
2520
2521   // Unit
2522   StepBasic_Unit aUnit = GetUnit(theRC, isAngle);
2523   Standard_CString aMeasureName;
2524   if (isAngle)
2525     aMeasureName = "POSITIVE_PLANE_ANGLE_MEASURE";
2526   else
2527     aMeasureName = "POSITIVE_LENGTH_MEASURE";
2528
2529   // Values
2530   Handle(StepRepr_HArray1OfRepresentationItem) aValues;
2531   Standard_Integer aNbValItems = 1, aNbAddItems = 0;
2532   if (theObject->IsDimWithRange())
2533     aNbValItems += 2;
2534   if (aModifiers.Length() > 0)
2535     aNbAddItems++;
2536   if (theObject->GetType() == XCAFDimTolObjects_DimensionType_Location_Oriented)
2537     aNbAddItems++;
2538   aValues = new StepRepr_HArray1OfRepresentationItem(1, aNbValItems + aNbAddItems);
2539
2540   // Nominal value
2541   Standard_Real aNominal = theObject->GetValue();
2542   Standard_Integer aLeftNbDigits, aRightNbDigits;
2543   theObject->GetNbOfDecimalPlaces(aLeftNbDigits, aRightNbDigits);
2544   Standard_Integer aNbQualifiers = 0;
2545   if (theObject->HasQualifier() && !isAngle)
2546     aNbQualifiers++;
2547   if (aLeftNbDigits > 0 || aRightNbDigits > 0)
2548     aNbQualifiers++;
2549   // With qualifiers
2550   if (aNbQualifiers > 0) {
2551     Handle(StepShape_QualifiedRepresentationItem) aQRI = new StepShape_QualifiedRepresentationItem();
2552     Handle(StepShape_HArray1OfValueQualifier) aQualifiers = new StepShape_HArray1OfValueQualifier(1, aNbQualifiers);
2553     // Type qualifier
2554     if (theObject->HasQualifier() && !isAngle) {
2555       StepShape_ValueQualifier anItem;
2556       Handle(StepShape_TypeQualifier) aType = new StepShape_TypeQualifier();
2557       XCAFDimTolObjects_DimensionQualifier aQualifier = theObject->GetQualifier();
2558       aType->Init(STEPCAFControl_GDTProperty::GetDimQualifierName(aQualifier));
2559       aModel->AddWithRefs(aType);
2560       anItem.SetValue(aType);
2561       aQualifiers->SetValue(1, anItem);
2562     }
2563     // Number of decimal places
2564     if (aLeftNbDigits > 0 || aRightNbDigits > 0) {
2565       StepShape_ValueQualifier anItem;
2566       Handle(StepShape_ValueFormatTypeQualifier) aType = new StepShape_ValueFormatTypeQualifier();
2567       Handle(TCollection_HAsciiString) aFormatType = new TCollection_HAsciiString("NR2 ");
2568       aFormatType->AssignCat(new TCollection_HAsciiString(aLeftNbDigits));
2569       aFormatType->AssignCat(new TCollection_HAsciiString("."));
2570       aFormatType->AssignCat(new TCollection_HAsciiString(aRightNbDigits));
2571       aType->Init(aFormatType);
2572       aModel->AddWithRefs(aType);
2573       anItem.SetValue(aType);
2574       aQualifiers->SetValue(aNbQualifiers, anItem);
2575     }
2576     // Set qualifiers
2577     aQRI->SetQualifiers(aQualifiers);
2578     Handle(StepRepr_ReprItemAndMeasureWithUnit) anItem = CreateDimValue(aNominal, aUnit,
2579       new TCollection_HAsciiString("nominal value"), aMeasureName, isAngle, Standard_True, aQRI);
2580     aValues->SetValue(DimensionalValueNumber_Nominal, anItem);
2581   }
2582   // Without qualifiers
2583   else {
2584     Handle(StepRepr_ReprItemAndMeasureWithUnit) anItem = CreateDimValue(aNominal, aUnit,
2585       new TCollection_HAsciiString("nominal value"), aMeasureName, isAngle);
2586     aValues->SetValue(DimensionalValueNumber_Nominal, anItem);
2587   }
2588   // Ranges
2589   if (theObject->IsDimWithRange()) {
2590     Handle(StepRepr_ReprItemAndMeasureWithUnit) aLowerItem = CreateDimValue(theObject->GetLowerBound(), aUnit,
2591       new TCollection_HAsciiString("lower limit"), aMeasureName, isAngle);
2592     Handle(StepRepr_ReprItemAndMeasureWithUnit) anUpperItem = CreateDimValue(theObject->GetUpperBound(), aUnit,
2593       new TCollection_HAsciiString("upper limit"), aMeasureName, isAngle);
2594     aValues->SetValue(DimensionalValueNumber_Lower, aLowerItem);
2595     aValues->SetValue(DimensionalValueNumber_Upper, anUpperItem);
2596   }
2597
2598   // Modifiers
2599   if (aModifiers.Length() > 0) {
2600     Handle(StepRepr_CompoundRepresentationItem) aCompoundRI = new StepRepr_CompoundRepresentationItem();
2601     Handle (StepRepr_HArray1OfRepresentationItem) aModifItems = 
2602       new StepRepr_HArray1OfRepresentationItem(1, aModifiers.Length());
2603     for (Standard_Integer i = 1; i <= aModifiers.Length(); i++) {
2604       XCAFDimTolObjects_DimensionModif aModif = aModifiers.Value(i);
2605       Handle(StepRepr_DescriptiveRepresentationItem) aModifItem = 
2606         new StepRepr_DescriptiveRepresentationItem();
2607       aModifItem->Init(new TCollection_HAsciiString(), STEPCAFControl_GDTProperty::GetDimModifierName(aModif));
2608       aModel->AddWithRefs(aModifItem);
2609       aModifItems->SetValue(i, aModifItem);
2610     }
2611     aCompoundRI->Init(new TCollection_HAsciiString(), aModifItems);
2612     aValues->SetValue(aNbValItems + 1, aCompoundRI);
2613   }
2614
2615   // Orientation
2616   if (theObject->GetType() == XCAFDimTolObjects_DimensionType_Location_Oriented) {
2617     Handle(StepGeom_Axis2Placement3d) anOrientation = new StepGeom_Axis2Placement3d();
2618     gp_Dir aDir;
2619     theObject->GetDirection(aDir);
2620     GeomToStep_MakeCartesianPoint MkPoint(theObject->GetPoints()->Value(1));
2621     Handle(StepGeom_CartesianPoint) aLoc = MkPoint.Value();
2622     Handle(StepGeom_Direction) anAxis = new StepGeom_Direction();
2623     Handle(TColStd_HArray1OfReal) aCoords = new TColStd_HArray1OfReal(1, 3);
2624     aCoords->SetValue(1, aDir.X());
2625     aCoords->SetValue(2, aDir.Y());
2626     aCoords->SetValue(3, aDir.Z());
2627     anAxis->Init(new TCollection_HAsciiString(), aCoords);
2628     anOrientation->Init(new TCollection_HAsciiString("orientation"), aLoc, Standard_True, anAxis, Standard_False, NULL);
2629     aValues->SetValue(aValues->Length(), anOrientation);
2630   }
2631
2632   for (Standard_Integer i = 1; i <= aValues->Length(); i++)
2633     aModel->AddWithRefs(aValues->Value(i));
2634
2635   // Create resulting Shape_Dimension_Representation
2636   Handle(StepShape_ShapeDimensionRepresentation) aSDR = new StepShape_ShapeDimensionRepresentation();
2637   aSDR->Init(new TCollection_HAsciiString(), aValues, theRC);
2638   aModel->AddWithRefs(aSDR);
2639   Handle(StepShape_DimensionalCharacteristicRepresentation) aDCR = new StepShape_DimensionalCharacteristicRepresentation();
2640   aDCR->Init(theDimension, aSDR);
2641   aModel->AddWithRefs(aDCR);
2642
2643   // Plus_Minus_Tolerance
2644   if (theObject->IsDimWithPlusMinusTolerance()) {
2645     Handle(TCollection_HAsciiString) aDummyName = new TCollection_HAsciiString(aMeasureName);
2646     aDummyName = aDummyName->SubString(9, aDummyName->Length()); //delete "POSITIVE_"
2647     aMeasureName = aDummyName->ToCString();
2648     Standard_Real aLowerTolValue = -theObject->GetLowerTolValue(),
2649                   anUpperTolValue = theObject->GetUpperTolValue();
2650     // Upper
2651     Handle(StepBasic_MeasureWithUnit) anUpperMWU = new StepBasic_MeasureWithUnit();
2652     Handle(StepBasic_MeasureValueMember) anUpperValue = new StepBasic_MeasureValueMember();
2653     anUpperValue->SetName(aMeasureName);
2654     anUpperValue->SetReal(anUpperTolValue);
2655     anUpperMWU->Init(anUpperValue, aUnit);
2656     aModel->AddWithRefs(anUpperMWU);
2657     // Lower
2658     Handle(StepBasic_MeasureWithUnit) aLowerMWU = new StepBasic_MeasureWithUnit();
2659     Handle(StepBasic_MeasureValueMember) aLowerValue = new StepBasic_MeasureValueMember();
2660     aLowerValue->SetName(aMeasureName);
2661     aLowerValue->SetReal(aLowerTolValue);
2662     aLowerMWU->Init(aLowerValue, aUnit);
2663     aModel->AddWithRefs(aLowerMWU);
2664     // Tolerance
2665     Handle(StepShape_ToleranceValue) aTolValue = new StepShape_ToleranceValue();
2666     aTolValue->Init(aLowerMWU, anUpperMWU);
2667     aModel->AddWithRefs(aTolValue);
2668     StepShape_ToleranceMethodDefinition aMethod;
2669     aMethod.SetValue(aTolValue);
2670     Handle(StepShape_PlusMinusTolerance) aPlusMinusTol = new StepShape_PlusMinusTolerance();
2671     aPlusMinusTol->Init(aMethod, theDimension);
2672     aModel->AddWithRefs(aPlusMinusTol);
2673   }
2674   // Tolerance class
2675   if (theObject->IsDimWithClassOfTolerance()) {
2676     Standard_Boolean isHole;
2677     XCAFDimTolObjects_DimensionFormVariance aFormVariance;
2678     XCAFDimTolObjects_DimensionGrade aGrade;
2679     if (!theObject->GetClassOfTolerance(isHole, aFormVariance, aGrade))
2680       return;
2681     Handle(StepShape_LimitsAndFits) aLAF = STEPCAFControl_GDTProperty::GetLimitsAndFits(isHole, aFormVariance, aGrade);
2682     aModel->AddWithRefs(aLAF);
2683     StepShape_ToleranceMethodDefinition aMethod;
2684     aMethod.SetValue(aLAF);
2685     Handle(StepShape_PlusMinusTolerance) aPlusMinusTol = new StepShape_PlusMinusTolerance();
2686     aPlusMinusTol->Init(aMethod, theDimension);
2687     aModel->AddWithRefs(aPlusMinusTol);
2688   }
2689 }
2690
2691 //=======================================================================
2692 //function : WriteDatumSystem
2693 //purpose  : auxiliary (write Write datum system for given
2694 //           geometric_tolerance)
2695 //======================================================================
2696 static Handle(StepDimTol_HArray1OfDatumSystemOrReference) WriteDatumSystem(const Handle(XSControl_WorkSession) &WS,
2697                                                                            const TDF_Label theGeomTolL,
2698                                                                            const TDF_LabelSequence theDatumSeq,
2699                                                                            const STEPConstruct_DataMapOfAsciiStringTransient theDatumMap,
2700                                                                            const Handle(StepRepr_RepresentationContext)& theRC)
2701 {
2702   // Get working data
2703   Handle(Interface_InterfaceModel) Model = WS->Model();
2704   const Handle(Interface_HGraph) aHGraph = WS->HGraph();
2705   if (aHGraph.IsNull())
2706     return NULL;
2707   Interface_Graph aGraph = aHGraph->Graph();
2708   Handle(XCAFDoc_GeomTolerance) aGTAttr;
2709   if (!theGeomTolL.FindAttribute(XCAFDoc_GeomTolerance::GetID(), aGTAttr)) 
2710     return NULL;
2711   Handle(XCAFDimTolObjects_GeomToleranceObject) anObject = aGTAttr->GetObject();
2712   if (anObject.IsNull())
2713     return NULL;
2714
2715   // Unit
2716   StepBasic_Unit aUnit = GetUnit(theRC);
2717
2718   XCAFDimTolObjects_DatumObjectSequence aDatums;
2719   Standard_Integer aMaxDatumNum = 0;
2720   for (Standard_Integer i = 1; i <= theDatumSeq.Length(); i++) {
2721     Handle(XCAFDoc_Datum) aDatumAttr;
2722     if (!theDatumSeq.Value(i).FindAttribute(XCAFDoc_Datum::GetID(), aDatumAttr)) 
2723       continue;
2724     Handle(XCAFDimTolObjects_DatumObject) aDatumObj = aDatumAttr->GetObject();
2725     if (aDatumObj.IsNull())
2726       continue;
2727     aDatums.Append(aDatumObj);
2728     aMaxDatumNum = Max(aMaxDatumNum, aDatumObj->GetPosition());
2729   }
2730
2731   Handle(StepDimTol_HArray1OfDatumReferenceCompartment) aConstituents =
2732     new StepDimTol_HArray1OfDatumReferenceCompartment(1, aMaxDatumNum);
2733   // Auxiliary datum to initialize attributes in Datum_System
2734   Handle(StepDimTol_Datum) aFirstDatum;
2735   Standard_Integer aConstituentsNum = 0;
2736   for (Standard_Integer i = 1; i <= aMaxDatumNum; i++) {
2737     // Collect datums with i-th position
2738     XCAFDimTolObjects_DatumObjectSequence aDatumSeqPos;
2739     for (Standard_Integer j = 1; j <= aDatums.Length(); j++)
2740       if (aDatums.Value(j)->GetPosition() == i)
2741         aDatumSeqPos.Append(aDatums.Value(j));
2742     if (aDatumSeqPos.Length() < 1)
2743       continue;
2744
2745     aConstituentsNum++;
2746     // Initialize Datum_Reference_Compartment
2747     StepDimTol_DatumOrCommonDatum aDatumRef;
2748     Handle(StepDimTol_DatumReferenceCompartment) aCompartment =
2749       new StepDimTol_DatumReferenceCompartment();
2750     Handle(StepDimTol_HArray1OfDatumReferenceModifier) aModifiers;
2751     if (aDatumSeqPos.Length() == 1) {
2752       // Datum entity
2753       Handle(Standard_Transient) aFDValue;
2754       if (theDatumMap.Find(aDatumSeqPos.Value(1)->GetName()->String(), aFDValue))
2755         aFirstDatum = Handle(StepDimTol_Datum)::DownCast (aFDValue);
2756       aDatumRef.SetValue(aFirstDatum);
2757       // Modifiers
2758       XCAFDimTolObjects_DatumModifiersSequence aSimpleModifiers = aDatumSeqPos.Value(1)->GetModifiers();
2759       XCAFDimTolObjects_DatumModifWithValue aModifWithVal;
2760       Standard_Real aValue = 0;
2761       aDatumSeqPos.Value(1)->GetModifierWithValue(aModifWithVal, aValue);
2762       aModifiers = STEPCAFControl_GDTProperty::GetDatumRefModifiers(aSimpleModifiers, aModifWithVal, aValue, aUnit);
2763       // Add Datum_Reference_Modifier_With_Value
2764       if (!aModifiers.IsNull()) {
2765         Handle(StepDimTol_DatumReferenceModifierWithValue) aDRMWV = 
2766           aModifiers->Value(aModifiers->Length()).DatumReferenceModifierWithValue();
2767         if (!aDRMWV.IsNull()) {
2768           Model->AddWithRefs(aDRMWV);
2769         }
2770       }
2771     }
2772     else {
2773       Handle(StepDimTol_HArray1OfDatumReferenceElement) aCommonDatumList = new StepDimTol_HArray1OfDatumReferenceElement(1, aDatumSeqPos.Length());
2774       for (Standard_Integer j = 1; j <= aDatumSeqPos.Length(); j++) {
2775         // Datum entity
2776         Handle(StepDimTol_Datum) aDatum;
2777         Handle(Standard_Transient) aDValue;
2778         if (theDatumMap.Find(aDatumSeqPos.Value(j)->GetName()->String(), aDValue))
2779           aDatum = Handle(StepDimTol_Datum)::DownCast (aDValue);
2780         StepDimTol_DatumOrCommonDatum anElemDatumRef;
2781         anElemDatumRef.SetValue(aDatum);
2782         if (aFirstDatum.IsNull())
2783           aFirstDatum = aDatum;
2784         // Modifiers
2785         XCAFDimTolObjects_DatumModifiersSequence aSimpleModifiers = aDatumSeqPos.Value(j)->GetModifiers();
2786         XCAFDimTolObjects_DatumModifWithValue aModifWithVal;
2787         Standard_Real aValue = 0;
2788         aDatumSeqPos.Value(j)->GetModifierWithValue(aModifWithVal, aValue);
2789         Handle(StepDimTol_HArray1OfDatumReferenceModifier) anElemModifiers =
2790           STEPCAFControl_GDTProperty::GetDatumRefModifiers(aSimpleModifiers, aModifWithVal, aValue, aUnit);
2791         // Add Datum_Reference_Modifier_With_Value
2792         if (!anElemModifiers.IsNull()) {
2793           Handle(StepDimTol_DatumReferenceModifierWithValue) aDRMWV = 
2794             anElemModifiers->Value(aModifiers->Length()).DatumReferenceModifierWithValue();
2795           if (!aDRMWV.IsNull()) {
2796             Model->AddWithRefs(aDRMWV);
2797           }
2798         }
2799         // Datum_Reference_Element
2800         Handle(StepDimTol_DatumReferenceElement) anElement = new StepDimTol_DatumReferenceElement();
2801         anElement->Init(new TCollection_HAsciiString(), new TCollection_HAsciiString(), aDatum->OfShape(),
2802           aDatum->ProductDefinitional(), anElemDatumRef, !anElemModifiers.IsNull(), anElemModifiers);
2803         Model->AddWithRefs(anElement);
2804         aCommonDatumList->SetValue(j, anElement);
2805       }
2806       aDatumRef.SetValue(aCommonDatumList);
2807     }
2808     aCompartment->Init(new TCollection_HAsciiString(), new TCollection_HAsciiString(), aFirstDatum->OfShape(),
2809       aFirstDatum->ProductDefinitional(), aDatumRef, !aModifiers.IsNull(), aModifiers);
2810     Model->AddWithRefs(aCompartment);
2811     aConstituents->SetValue(aConstituentsNum, aCompartment);
2812   }
2813   // Remove null elements from aConstituents
2814   Standard_Integer aNbConstituents = 0;
2815   for (Standard_Integer i = 1; i <= aConstituents->Length(); i++)
2816     if (!aConstituents->Value(i).IsNull())
2817       aNbConstituents++;
2818   Handle(StepDimTol_HArray1OfDatumReferenceCompartment) aResConstituents =
2819     new StepDimTol_HArray1OfDatumReferenceCompartment(1, aNbConstituents);
2820   Standard_Integer aConstituentsIt = 0;
2821   for (Standard_Integer i = 1; i <= aConstituents->Length(); i++)
2822     if (!aConstituents->Value(i).IsNull()) {
2823       aConstituentsIt++;
2824       aResConstituents->SetValue(aConstituentsIt, aConstituents->Value(i));
2825     }
2826
2827   Handle(StepDimTol_HArray1OfDatumSystemOrReference) aDatumSystem;
2828   Handle(StepDimTol_DatumSystem) aDS = new StepDimTol_DatumSystem();
2829   aDS->Init(new TCollection_HAsciiString(), new TCollection_HAsciiString(), aFirstDatum->OfShape(),
2830     aFirstDatum->ProductDefinitional(), aResConstituents);
2831   Model->AddWithRefs(aDS);
2832   StepDimTol_DatumSystemOrReference anArrayValue;
2833   anArrayValue.SetValue(aDS);
2834   aDatumSystem = new StepDimTol_HArray1OfDatumSystemOrReference(1, 1);
2835   aDatumSystem->SetValue(1, anArrayValue);
2836
2837   // Axis
2838   if (anObject->HasAxis()) {
2839     Handle(StepGeom_Axis2Placement3d) anAxis =
2840       STEPCAFControl_GDTProperty::GetAxis2Placement3D(anObject->GetAxis());
2841     Handle(StepAP242_GeometricItemSpecificUsage) aGISU = new StepAP242_GeometricItemSpecificUsage();
2842     StepAP242_ItemIdentifiedRepresentationUsageDefinition aDefinition;
2843     aDefinition.SetValue(aDS);
2844     Handle(StepRepr_HArray1OfRepresentationItem) anReprItems = new StepRepr_HArray1OfRepresentationItem(1, 1);
2845     Handle(StepRepr_RepresentationItem) anIdentifiedItem = anAxis;
2846     anReprItems->SetValue(1, anIdentifiedItem);
2847     Interface_EntityIterator subs = aGraph.Sharings(aFirstDatum->OfShape());
2848     Handle(StepShape_ShapeDefinitionRepresentation) aSDR;
2849     for (subs.Start(); subs.More() && aSDR.IsNull(); subs.Next()) {
2850       Handle(Standard_Transient) anEntity = subs.Value();
2851       aSDR = Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(anEntity);
2852     }
2853     if (aSDR.IsNull())
2854       return aDatumSystem;
2855     
2856     aGISU->Init(new TCollection_HAsciiString(), new TCollection_HAsciiString(),
2857       aDefinition, aSDR->UsedRepresentation(), anReprItems);
2858     Model->AddWithRefs(anAxis);
2859     Model->AddWithRefs(aGISU);
2860   }
2861
2862   return aDatumSystem;
2863 }
2864
2865 //=======================================================================
2866 //function : WriteToleranceZone
2867 //purpose  : auxiliary (write tolerace zones)
2868 //=======================================================================
2869 static void WriteToleranceZone (const Handle(XSControl_WorkSession) &WS,
2870                                 const Handle(XCAFDimTolObjects_GeomToleranceObject)& theObject,
2871                                 const Handle(StepDimTol_GeometricTolerance)& theEntity,
2872                                 const Handle(StepRepr_RepresentationContext)& theRC)
2873 {
2874   // Get working data
2875   Handle(Interface_InterfaceModel) Model = WS->Model();
2876   if (theEntity.IsNull() || theObject.IsNull())
2877     return;
2878
2879   // Return if there is no tolerance zones
2880   if (theObject->GetTypeOfValue() == XCAFDimTolObjects_GeomToleranceTypeValue_None &&
2881       theObject->GetZoneModifier() != XCAFDimTolObjects_GeomToleranceZoneModif_Runout)
2882     return;
2883
2884   // Create Tolerance_Zone
2885   Handle(StepDimTol_ToleranceZoneForm) aForm = new StepDimTol_ToleranceZoneForm();
2886   Model->AddWithRefs(aForm);
2887   aForm->Init(STEPCAFControl_GDTProperty::GetTolValueType(theObject->GetTypeOfValue()));
2888   Handle(StepDimTol_HArray1OfToleranceZoneTarget) aZoneTargetArray = new StepDimTol_HArray1OfToleranceZoneTarget(1, 1);
2889   StepDimTol_ToleranceZoneTarget aTarget;
2890   aTarget.SetValue(theEntity);
2891   aZoneTargetArray->SetValue(1, aTarget);
2892   Handle(StepDimTol_ToleranceZone) aZone = new StepDimTol_ToleranceZone();
2893   aZone->Init(new TCollection_HAsciiString(), new TCollection_HAsciiString(),
2894     theEntity->TolerancedShapeAspect().ShapeAspect()->OfShape(), StepData_LFalse,
2895     aZoneTargetArray, aForm);
2896   Model->AddWithRefs(aZone);
2897
2898   // Runout_Tolerance_Zone
2899   Handle(StepBasic_PlaneAngleMeasureWithUnit) aPAMWU = new StepBasic_PlaneAngleMeasureWithUnit();
2900   Handle(StepBasic_MeasureValueMember) aValueMember = new StepBasic_MeasureValueMember();
2901   aValueMember->SetName("PLANE_ANGLE_MEASURE");
2902   aValueMember->SetReal(theObject->GetValueOfZoneModifier());
2903   aPAMWU->Init(aValueMember, GetUnit(theRC, Standard_True));
2904   Handle(StepDimTol_RunoutZoneOrientation) anOrientation = new StepDimTol_RunoutZoneOrientation();
2905   anOrientation->Init(aPAMWU);
2906   Handle(StepDimTol_RunoutZoneDefinition) aDefinition = new StepDimTol_RunoutZoneDefinition();
2907   aDefinition->Init(aZone, NULL, anOrientation);
2908   Model->AddWithRefs(aDefinition);
2909   Model->AddWithRefs(anOrientation);
2910   Model->AddWithRefs(aPAMWU);
2911 }
2912
2913 //=======================================================================
2914 //function : WriteGeomTolerance
2915 //purpose  : auxiliary (write Geometric_Tolerance entity for given shapes,
2916 //           label and datum system)
2917 //======================================================================
2918 static void WriteGeomTolerance (const Handle(XSControl_WorkSession) &WS,
2919                                 const TDF_LabelSequence theShapeSeqL,
2920                                 const TDF_Label theGeomTolL,
2921                                 const Handle(StepDimTol_HArray1OfDatumSystemOrReference)& theDatumSystem,
2922                                 const Handle(StepRepr_RepresentationContext)& theRC)
2923 {
2924   // Get working data
2925   Handle(Interface_InterfaceModel) Model = WS->Model();
2926   Handle(XCAFDoc_GeomTolerance) aGTAttr;
2927   if (!theGeomTolL.FindAttribute(XCAFDoc_GeomTolerance::GetID(), aGTAttr)) 
2928     return;
2929   Handle(XCAFDimTolObjects_GeomToleranceObject) anObject = aGTAttr->GetObject();
2930   if (anObject.IsNull())
2931     return;
2932
2933   // Value
2934   Handle(StepBasic_LengthMeasureWithUnit) aLMWU = new StepBasic_LengthMeasureWithUnit();
2935   StepBasic_Unit aUnit = GetUnit(theRC);
2936   Handle(StepBasic_MeasureValueMember) aValueMember = new StepBasic_MeasureValueMember();
2937   aValueMember->SetName("LENGTH_MEASURE");
2938   aValueMember->SetReal(anObject->GetValue());
2939   aLMWU->Init(aValueMember, aUnit);
2940   Model->AddWithRefs(aLMWU);
2941
2942   // Geometric_Tolerance target
2943   Handle(StepRepr_ShapeAspect) aMainSA;
2944   Handle(StepRepr_RepresentationContext) dummyRC;
2945   Handle(StepAP242_GeometricItemSpecificUsage) dummyGISU;
2946   if (theShapeSeqL.Length() == 1) {
2947     TopoDS_Shape aShape = XCAFDoc_ShapeTool::GetShape(theShapeSeqL.Value(1));
2948     aMainSA = WriteShapeAspect(WS, theGeomTolL, aShape, dummyRC, dummyGISU);
2949     Model->AddWithRefs(aMainSA);
2950   }
2951   else {
2952     Handle(StepRepr_CompositeShapeAspect) aCSA;
2953     for (Standard_Integer i = 1; i <= theShapeSeqL.Length(); i++) {
2954       TopoDS_Shape aShape = XCAFDoc_ShapeTool::GetShape(theShapeSeqL.Value(i));
2955       Handle(StepRepr_ShapeAspect) aSA = WriteShapeAspect(WS, theGeomTolL, aShape, dummyRC, dummyGISU);
2956       if (aSA.IsNull())
2957         continue;
2958       if (aCSA.IsNull()) {
2959         aCSA = new StepRepr_CompositeShapeAspect();
2960         aCSA->Init(aSA->Name(), aSA->Description(), aSA->OfShape(), aSA->ProductDefinitional());
2961         Model->AddWithRefs(aCSA);
2962       }
2963       Handle(StepRepr_ShapeAspectRelationship) aSAR = new StepRepr_ShapeAspectRelationship();
2964       aSAR->Init(new TCollection_HAsciiString(), Standard_False, NULL, aCSA, aSA);
2965       Model->AddWithRefs(aSAR);
2966     }
2967     aMainSA = aCSA;
2968   }
2969   StepDimTol_GeometricToleranceTarget aGTTarget;
2970   aGTTarget.SetValue(aMainSA);
2971
2972   Standard_Boolean isWithModif = Standard_False,
2973                    isWithDatRef = Standard_False,
2974                    isWithMaxTol = Standard_False;
2975   // Modifiers
2976   // Simple modifiers
2977   XCAFDimTolObjects_GeomToleranceModifiersSequence aModifiers = anObject->GetModifiers();
2978   Handle(StepDimTol_HArray1OfGeometricToleranceModifier) aModifArray;
2979   Handle(StepBasic_LengthMeasureWithUnit) aMaxLMWU;
2980   Standard_Integer aModifNb = aModifiers.Length();
2981   if (anObject->GetMaterialRequirementModifier() != XCAFDimTolObjects_GeomToleranceMatReqModif_None)
2982       aModifNb++;
2983   for (Standard_Integer i = 1; i < aModifiers.Length(); i++)
2984     if (aModifiers.Value(i) == XCAFDimTolObjects_GeomToleranceModif_All_Around ||
2985         aModifiers.Value(i) == XCAFDimTolObjects_GeomToleranceModif_All_Over)
2986         aModifNb--;
2987   if (aModifNb > 0) {
2988     isWithModif = Standard_True;
2989     aModifArray = new StepDimTol_HArray1OfGeometricToleranceModifier(1, aModifNb);
2990     Standard_Integer k = 1;
2991     for (Standard_Integer i = 1; i <= aModifiers.Length(); i++) {
2992       if (aModifiers.Value(i) == XCAFDimTolObjects_GeomToleranceModif_All_Around ||
2993         aModifiers.Value(i) == XCAFDimTolObjects_GeomToleranceModif_All_Over)
2994         continue;
2995       StepDimTol_GeometricToleranceModifier aModif = 
2996         STEPCAFControl_GDTProperty::GetGeomToleranceModifier(aModifiers.Value(i));
2997       aModifArray->SetValue(k, aModif);
2998       k++;
2999     }
3000     if (anObject->GetMaterialRequirementModifier() == XCAFDimTolObjects_GeomToleranceMatReqModif_L) {
3001       aModifArray->SetValue(aModifNb, StepDimTol_GTMLeastMaterialRequirement);
3002     }
3003     else if (anObject->GetMaterialRequirementModifier() == XCAFDimTolObjects_GeomToleranceMatReqModif_M) {
3004       aModifArray->SetValue(aModifNb, StepDimTol_GTMMaximumMaterialRequirement);
3005     }
3006     // Modifier with value
3007     if (anObject->GetMaxValueModifier() != 0) {
3008       isWithMaxTol = Standard_True;
3009       aMaxLMWU = new StepBasic_LengthMeasureWithUnit();
3010       Handle(StepBasic_MeasureValueMember) aModifierValueMember = new StepBasic_MeasureValueMember();
3011       aModifierValueMember->SetName("LENGTH_MEASURE");
3012       aModifierValueMember->SetReal(anObject->GetMaxValueModifier());
3013       aMaxLMWU->Init(aModifierValueMember, aUnit);
3014       Model->AddWithRefs(aMaxLMWU);
3015     }
3016   }
3017
3018   // Datum Reference
3019   isWithDatRef = !theDatumSystem.IsNull();
3020
3021   // Collect all attributes
3022   Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString(),
3023                                   aDescription = new TCollection_HAsciiString();
3024   Handle(StepDimTol_GeometricToleranceWithDatumReference) aGTWDR = 
3025     new StepDimTol_GeometricToleranceWithDatumReference();
3026   aGTWDR->SetDatumSystem(theDatumSystem);
3027   Handle(StepDimTol_GeometricToleranceWithModifiers) aGTWM = 
3028     new StepDimTol_GeometricToleranceWithModifiers();
3029   aGTWM->SetModifiers(aModifArray);
3030   StepDimTol_GeometricToleranceType aType = 
3031     STEPCAFControl_GDTProperty::GetGeomToleranceType(anObject->GetType());
3032
3033   // Init and write necessary subtype of Geometric_Tolerance entity
3034   Handle(StepDimTol_GeometricTolerance) aGeomTol;
3035   if (isWithModif) {
3036     if (isWithMaxTol) {
3037       if (isWithDatRef) {
3038         // Geometric_Tolerance & Geometric_Tolerance_With_Datum_Reference & 
3039         //Geometric_Tolerance_With_Maximum_Tolerance & Geometric_Tolerance_With_Modifiers
3040         Handle(StepDimTol_GeoTolAndGeoTolWthDatRefAndGeoTolWthMaxTol) aResult =
3041           new StepDimTol_GeoTolAndGeoTolWthDatRefAndGeoTolWthMaxTol();
3042         aResult->Init(aName, aDescription, aLMWU, aGTTarget, aGTWDR, aGTWM, aMaxLMWU, aType);
3043         aGeomTol = aResult;
3044       }
3045       else {
3046         // Geometric_Tolerance & Geometric_Tolerance_With_Maximum_Tolerance & Geometric_Tolerance_With_Modifiers
3047         Handle(StepDimTol_GeoTolAndGeoTolWthMaxTol) aResult =
3048           new StepDimTol_GeoTolAndGeoTolWthMaxTol();
3049         aResult->Init(aName, aDescription, aLMWU, aGTTarget, aGTWM, aMaxLMWU, aType);
3050         aGeomTol = aResult;
3051       }
3052     }
3053     else {
3054       if (isWithDatRef) {
3055         // Geometric_Tolerance & Geometric_Tolerance_With_Datum_Reference & Geometric_Tolerance_With_Modifiers
3056         Handle(StepDimTol_GeoTolAndGeoTolWthDatRefAndGeoTolWthMod) aResult =
3057           new StepDimTol_GeoTolAndGeoTolWthDatRefAndGeoTolWthMod();
3058         aResult->Init(aName, aDescription, aLMWU, aGTTarget, aGTWDR, aGTWM, aType);
3059         aGeomTol = aResult;
3060       }
3061       else {
3062         // Geometric_Tolerance & Geometric_Tolerance_With_Modifiers
3063         Handle(StepDimTol_GeoTolAndGeoTolWthMod) aResult =
3064           new StepDimTol_GeoTolAndGeoTolWthMod();
3065         aResult->Init(aName, aDescription, aLMWU, aGTTarget, aGTWM, aType);
3066         aGeomTol = aResult;
3067       }
3068     }
3069   }
3070   else {
3071     if (isWithDatRef) {
3072       // Geometric_Tolerance & Geometric_Tolerance_With_Datum_Reference
3073       Handle(StepDimTol_GeoTolAndGeoTolWthDatRef) aResult =
3074           new StepDimTol_GeoTolAndGeoTolWthDatRef();
3075         aResult->Init(aName, aDescription, aLMWU, aGTTarget, aGTWDR, aType);
3076         aGeomTol = aResult;
3077     }
3078     else {
3079       // Geometric_Tolerance
3080       Handle(StepDimTol_GeometricTolerance) aResult = 
3081         STEPCAFControl_GDTProperty::GetGeomTolerance(anObject->GetType());
3082       if (!aResult.IsNull()) {
3083         aResult->Init(aName, aDescription, aLMWU, aGTTarget);
3084         aGeomTol = aResult;
3085       }
3086     }
3087   }
3088   Model->AddWithRefs(aGeomTol);
3089   WriteToleranceZone(WS, anObject, aGeomTol, theRC);
3090 }
3091
3092 //=======================================================================
3093 //function : WriteDGTs
3094 //purpose  : 
3095 //=======================================================================
3096 Standard_Boolean STEPCAFControl_Writer::WriteDGTs (const Handle(XSControl_WorkSession) &WS,
3097                                                    const TDF_LabelSequence  &labels ) const
3098 {
3099   
3100   if ( labels.Length() <=0 ) return Standard_False;
3101   
3102   // get working data
3103   Handle(Interface_InterfaceModel) Model = WS->Model();
3104   Handle(XSControl_TransferWriter) TW = WS->TransferWriter();
3105   Handle(Transfer_FinderProcess) FP = TW->FinderProcess();
3106
3107   const Handle(Interface_HGraph) aHGraph = WS->HGraph();
3108   if(aHGraph.IsNull())
3109     return Standard_False;
3110
3111   Interface_Graph aGraph = aHGraph->Graph();
3112   Handle(XCAFDoc_DimTolTool) DGTTool = XCAFDoc_DocumentTool::DimTolTool( labels(1) );
3113   if(DGTTool.IsNull() ) return Standard_False;
3114
3115   TDF_LabelSequence DGTLabels;
3116
3117   // Check for number of Application Protocol
3118   DGTTool->GetDimTolLabels(DGTLabels);
3119   if (DGTLabels.Length() == 0)
3120     return WriteDGTsAP242(WS, labels);
3121
3122   STEPConstruct_DataMapOfAsciiStringTransient DatumMap;
3123
3124   // write Datums
3125   DGTLabels.Clear();
3126   DGTTool->GetDatumLabels(DGTLabels);
3127   if(DGTLabels.Length()<=0) return Standard_False;
3128   Standard_Integer i;
3129   for(i=1; i<=DGTLabels.Length(); i++) {
3130     TDF_Label DatumL = DGTLabels.Value(i);
3131     TDF_LabelSequence ShapeL;
3132     TDF_LabelSequence aNullSeq;
3133     if(!DGTTool->GetRefShapeLabel(DatumL,ShapeL,aNullSeq)) continue;
3134     // find target shape
3135     TopoDS_Shape aShape = XCAFDoc_ShapeTool::GetShape(ShapeL.Value(1));
3136     TopLoc_Location Loc;
3137     TColStd_SequenceOfTransient seqRI;
3138     FindEntities( FP, aShape, Loc, seqRI );
3139     if ( seqRI.Length() <= 0 ) {
3140       FP->Messenger() << "Warning: Cannot find RI for "<<aShape.TShape()->DynamicType()->Name()<<endl;
3141       continue;
3142     }
3143     Handle(StepRepr_ProductDefinitionShape) PDS;
3144     Handle(StepRepr_RepresentationContext) RC;
3145     Handle(Standard_Transient) ent = seqRI.Value(1);
3146     Handle(StepShape_AdvancedFace) AF;
3147     Handle(StepShape_EdgeCurve) EC;
3148     FindPDSforDGT(aGraph,ent,PDS,RC,AF,EC);
3149     if(PDS.IsNull()) continue;
3150     //cout<<"Model->Number(PDS)="<<Model->Number(PDS)<<endl;
3151     Handle(XCAFDoc_Datum) DatumAttr;
3152     if(!DatumL.FindAttribute(XCAFDoc_Datum::GetID(),DatumAttr)) continue;
3153     Handle(TCollection_HAsciiString) aName = DatumAttr->GetName();
3154     Handle(TCollection_HAsciiString) aDescription = DatumAttr->GetDescription();
3155     Handle(TCollection_HAsciiString) anIdentification = DatumAttr->GetIdentification();
3156     Handle(StepDimTol_DatumFeature) DF = new StepDimTol_DatumFeature;
3157     Handle(StepDimTol_Datum) aDatum = new StepDimTol_Datum;
3158     DF->Init(aName, new TCollection_HAsciiString, PDS, StepData_LTrue);
3159     Model->AddWithRefs(DF);
3160     aDatum->Init(aName, new TCollection_HAsciiString, PDS, StepData_LFalse, anIdentification);
3161     Model->AddWithRefs(aDatum);
3162     Handle(StepRepr_ShapeAspectRelationship) SAR = new StepRepr_ShapeAspectRelationship;
3163     SAR->SetName(aName);
3164     SAR->SetRelatingShapeAspect(DF);
3165     SAR->SetRelatedShapeAspect(aDatum);
3166     Model->AddWithRefs(SAR);
3167     // write chain for DatumFeature
3168     StepRepr_CharacterizedDefinition CD;
3169     CD.SetValue(DF);
3170     Handle(StepRepr_PropertyDefinition) PropD = new StepRepr_PropertyDefinition;
3171     PropD->Init(aName,Standard_True,aDescription,CD);
3172     Model->AddWithRefs(PropD);
3173     StepRepr_RepresentedDefinition RD;
3174     RD.SetValue(PropD);
3175     Handle(StepShape_ShapeRepresentation) SR = new StepShape_ShapeRepresentation;
3176     Handle(StepRepr_HArray1OfRepresentationItem) HARI =
3177       new StepRepr_HArray1OfRepresentationItem(1,1);
3178     HARI->SetValue(1,AF);
3179     SR->Init(aName,HARI,RC);
3180     Handle(StepShape_ShapeDefinitionRepresentation) SDR = new StepShape_ShapeDefinitionRepresentation;
3181     SDR->Init(RD,SR);
3182     Model->AddWithRefs(SDR);
3183     // write chain for Datum 
3184     StepRepr_CharacterizedDefinition CD1;
3185     CD1.SetValue(aDatum);
3186     Handle(StepRepr_PropertyDefinition) PropD1 = new StepRepr_PropertyDefinition;
3187     PropD1->Init(aName,Standard_True,aDescription,CD1);
3188     Model->AddWithRefs(PropD1);
3189     StepRepr_RepresentedDefinition RD1;
3190     RD1.SetValue(PropD1);
3191     Handle(StepShape_ShapeRepresentation) SR1 = new StepShape_ShapeRepresentation;
3192     Handle(StepRepr_HArray1OfRepresentationItem) HARI1 =
3193       new StepRepr_HArray1OfRepresentationItem(1,1);
3194     HARI1->SetValue(1,AF->FaceGeometry());
3195     SR1->Init(aName,HARI1,RC);
3196     Model->AddWithRefs(SR1);
3197     Handle(StepShape_ShapeDefinitionRepresentation) SDR1 = new StepShape_ShapeDefinitionRepresentation;
3198     SDR1->Init(RD1,SR1);
3199     Model->AddWithRefs(SDR1);
3200     // add created Datum into Map
3201     TCollection_AsciiString stmp(aName->ToCString());
3202     stmp.AssignCat(aDescription->ToCString());
3203     stmp.AssignCat(anIdentification->ToCString());
3204     DatumMap.Bind(stmp,aDatum);
3205   }
3206
3207   // write Tolerances and Dimensions
3208   DGTLabels.Clear();
3209   DGTTool->GetDimTolLabels(DGTLabels);
3210   if(DGTLabels.Length()<=0) return Standard_False;
3211   for(i=1; i<=DGTLabels.Length(); i++) {
3212     TDF_Label DimTolL = DGTLabels.Value(i);
3213     TDF_LabelSequence ShapeL;
3214     TDF_LabelSequence aNullSeq;
3215     if(!DGTTool->GetRefShapeLabel(DimTolL,ShapeL,aNullSeq)) continue;
3216     // find target shape
3217     TopoDS_Shape aShape = XCAFDoc_ShapeTool::GetShape(ShapeL.Value(1));
3218     TopLoc_Location Loc;
3219     TColStd_SequenceOfTransient seqRI;
3220     FindEntities( FP, aShape, Loc, seqRI );
3221     if ( seqRI.Length() <= 0 ) {
3222       FP->Messenger() << "Warning: Cannot find RI for "<<aShape.TShape()->DynamicType()->Name()<<endl;
3223       continue;
3224     }
3225     Handle(StepRepr_ProductDefinitionShape) PDS;
3226     Handle(StepRepr_RepresentationContext) RC;
3227     Handle(Standard_Transient) ent = seqRI.Value(1);
3228     Handle(StepShape_AdvancedFace) AF;
3229     Handle(StepShape_EdgeCurve) EC;
3230     FindPDSforDGT(aGraph,ent,PDS,RC,AF,EC);
3231     if(PDS.IsNull()) continue;
3232     //cout<<"Model->Number(PDS)="<<Model->Number(PDS)<<endl;
3233
3234     Handle(XCAFDoc_DimTol) DimTolAttr;
3235     if(!DimTolL.FindAttribute(XCAFDoc_DimTol::GetID(),DimTolAttr)) continue;
3236     Standard_Integer kind = DimTolAttr->GetKind();
3237     Handle(TColStd_HArray1OfReal) aVal = DimTolAttr->GetVal();
3238     Handle(TCollection_HAsciiString) aName = DimTolAttr->GetName();
3239     Handle(TCollection_HAsciiString) aDescription = DimTolAttr->GetDescription();
3240
3241     // common part of writing D&GT entities
3242     StepRepr_CharacterizedDefinition CD;
3243     Handle(StepRepr_ShapeAspect) SA = new StepRepr_ShapeAspect;
3244     SA->Init(aName, new TCollection_HAsciiString, PDS, StepData_LTrue);
3245     Model->AddWithRefs(SA);
3246     CD.SetValue(SA);
3247     Handle(StepRepr_PropertyDefinition) PropD = new StepRepr_PropertyDefinition;
3248     PropD->Init(aName,Standard_True,aDescription,CD);
3249     Model->AddWithRefs(PropD);
3250     StepRepr_RepresentedDefinition RD;
3251     RD.SetValue(PropD);
3252     Handle(StepShape_ShapeRepresentation) SR = new StepShape_ShapeRepresentation;
3253     Handle(StepRepr_HArray1OfRepresentationItem) HARI =
3254       new StepRepr_HArray1OfRepresentationItem(1,1);
3255     if(kind<20) 
3256       HARI->SetValue(1,EC);
3257     else
3258       HARI->SetValue(1,AF);
3259     SR->Init(aName,HARI,RC);
3260     Handle(StepShape_ShapeDefinitionRepresentation) SDR = new StepShape_ShapeDefinitionRepresentation;
3261     SDR->Init(RD,SR);
3262     Model->AddWithRefs(SDR);
3263     // define aUnit for creation LengthMeasureWithUnit (common for all)
3264     StepBasic_Unit aUnit;
3265     Handle(StepBasic_SiUnitAndLengthUnit) SLU;
3266     Handle(StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext) Ctx =
3267       Handle(StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext)::DownCast(RC);
3268     if(!Ctx.IsNull()) {
3269       for(Standard_Integer j=1; j<=Ctx->NbUnits(); j++) {
3270         if(Ctx->UnitsValue(j)->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndLengthUnit))) {
3271           SLU = Handle(StepBasic_SiUnitAndLengthUnit)::DownCast(Ctx->UnitsValue(j));
3272           break;
3273         }
3274       }
3275     }
3276     if(SLU.IsNull()) {
3277       Handle(StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx) Ctx1 =
3278         Handle(StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx)::DownCast(RC);
3279       if(!Ctx1.IsNull()) {
3280         for(Standard_Integer j=1; j<=Ctx1->NbUnits(); j++) {
3281           if(Ctx1->UnitsValue(j)->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndLengthUnit))) {
3282             SLU = Handle(StepBasic_SiUnitAndLengthUnit)::DownCast(Ctx1->UnitsValue(j));
3283             break;
3284           }
3285         }
3286       }
3287     }
3288     if(SLU.IsNull()) {
3289       SLU = new StepBasic_SiUnitAndLengthUnit;
3290     }
3291     aUnit.SetValue(SLU);
3292
3293     // specific part of writing D&GT entities
3294     if(kind<20) { //dimension
3295       Handle(StepShape_DimensionalSize) DimSize = new StepShape_DimensionalSize;
3296       DimSize->Init(SA,aDescription);
3297       Model->AddWithRefs(DimSize);
3298       if(aVal->Length()>1) {
3299         // create MeasureWithUnits
3300         Handle(StepBasic_MeasureValueMember) MVM1 = new StepBasic_MeasureValueMember;
3301         MVM1->SetName("POSITIVE_LENGTH_MEASURE");
3302         MVM1->SetReal(aVal->Value(1));
3303         Handle(StepBasic_MeasureWithUnit) MWU1 = new StepBasic_MeasureWithUnit;
3304         MWU1->Init(MVM1,aUnit);
3305         Handle(StepBasic_MeasureValueMember) MVM2 = new StepBasic_MeasureValueMember;
3306         MVM2->SetName("POSITIVE_LENGTH_MEASURE");
3307         MVM2->SetReal(aVal->Value(2));
3308         Handle(StepBasic_MeasureWithUnit) MWU2 = new StepBasic_MeasureWithUnit;