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