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