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