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