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