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