0025748: Parallel version of progress indicator
[occt.git] / src / STEPControl / STEPControl_Reader.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14
15 #include <Interface_EntityIterator.hxx>
16 #include <Interface_Graph.hxx>
17 #include <Interface_ShareFlags.hxx>
18 #include <Interface_Static.hxx>
19 #include <StepBasic_ApplicationContext.hxx>
20 #include <StepBasic_ConversionBasedUnit.hxx>
21 #include <StepBasic_DocumentProductEquivalence.hxx>
22 #include <StepBasic_HArray1OfNamedUnit.hxx>
23 #include <StepBasic_LengthMeasureWithUnit.hxx>
24 #include <StepBasic_MeasureWithUnit.hxx>
25 #include <StepBasic_NamedUnit.hxx>
26 #include <StepBasic_PlaneAngleMeasureWithUnit.hxx>
27 #include <StepBasic_ProductDefinition.hxx>
28 #include <StepBasic_ProductDefinitionContext.hxx>
29 #include <StepBasic_ProductDefinitionFormation.hxx>
30 #include <StepBasic_ProductDefinitionFormationRelationship.hxx>
31 #include <StepBasic_ProductDefinitionWithAssociatedDocuments.hxx>
32 #include <StepBasic_SiPrefix.hxx>
33 #include <StepBasic_SiUnit.hxx>
34 #include <StepBasic_SiUnitAndLengthUnit.hxx>
35 #include <StepBasic_SiUnitAndPlaneAngleUnit.hxx>
36 #include <StepBasic_SiUnitAndSolidAngleUnit.hxx>
37 #include <StepBasic_SiUnitName.hxx>
38 #include <StepBasic_SolidAngleMeasureWithUnit.hxx>
39 #include <StepBasic_SolidAngleUnit.hxx>
40 #include <STEPConstruct_UnitContext.hxx>
41 #include <STEPControl_Controller.hxx>
42 #include <STEPControl_Reader.hxx>
43 #include <StepData_StepModel.hxx>
44 #include <StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext.hxx>
45 #include <StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx.hxx>
46 #include <StepRepr_GlobalUncertaintyAssignedContext.hxx>
47 #include <StepRepr_GlobalUnitAssignedContext.hxx>
48 #include <StepRepr_MappedItem.hxx>
49 #include <StepRepr_NextAssemblyUsageOccurrence.hxx>
50 #include <StepRepr_ProductDefinitionShape.hxx>
51 #include <StepRepr_PropertyDefinition.hxx>
52 #include <StepRepr_RepresentationContext.hxx>
53 #include <StepRepr_RepresentationMap.hxx>
54 #include <StepRepr_RepresentationRelationship.hxx>
55 #include <StepRepr_ShapeAspect.hxx>
56 #include <StepShape_ManifoldSolidBrep.hxx>
57 #include <StepShape_ShapeDefinitionRepresentation.hxx>
58 #include <StepShape_ShapeRepresentation.hxx>
59 #include <StepShape_ShellBasedSurfaceModel.hxx>
60 #include <TCollection_AsciiString.hxx>
61 #include <TColStd_Array1OfAsciiString.hxx>
62 #include <TColStd_Array1OfReal.hxx>
63 #include <TColStd_HSequenceOfTransient.hxx>
64 #include <TColStd_MapOfAsciiString.hxx>
65 #include <TColStd_SequenceOfAsciiString.hxx>
66 #include <Transfer_TransientProcess.hxx>
67 #include <XSControl_Controller.hxx>
68 #include <XSControl_TransferReader.hxx>
69 #include <XSControl_WorkSession.hxx>
70
71 //=======================================================================
72 //function : STEPControl_Reader
73 //purpose  : 
74 //=======================================================================
75 STEPControl_Reader::STEPControl_Reader ()
76 {
77   STEPControl_Controller::Init();
78   SetNorm ("STEP");
79 }
80
81 //=======================================================================
82 //function : STEPControl_Reader
83 //purpose  : 
84 //=======================================================================
85
86 STEPControl_Reader::STEPControl_Reader
87   (const Handle(XSControl_WorkSession)& WS, const Standard_Boolean scratch)
88 {
89   STEPControl_Controller::Init();
90   SetWS (WS,scratch);
91   SetNorm ("STEP");
92 }
93
94 //=======================================================================
95 //function : StepModel
96 //purpose  : 
97 //=======================================================================
98
99 Handle(StepData_StepModel) STEPControl_Reader::StepModel () const
100 {
101   return Handle(StepData_StepModel)::DownCast(Model());
102 }
103
104 //=======================================================================
105 //function : TransferRoot
106 //purpose  : 
107 //=======================================================================
108
109 Standard_Boolean STEPControl_Reader::TransferRoot (const Standard_Integer num,
110                                                    const Message_ProgressRange& theProgress)
111 {
112   return TransferOneRoot(num, theProgress);
113 }
114
115 //=======================================================================
116 //function : NbRootsForTransfer
117 //purpose  : 
118 //=======================================================================
119
120 Standard_Integer STEPControl_Reader::NbRootsForTransfer() 
121 {
122   if (therootsta) return theroots.Length();
123   therootsta = Standard_True;
124
125   //theroots.Clear();
126   Standard_Integer nb = Model()->NbEntities();
127   for (Standard_Integer i = 1; i <= nb; i ++) {
128     Handle(Standard_Transient) ent = Model()->Value(i);
129     if (Interface_Static::IVal("read.step.all.shapes") == 1) {
130       // Special case to read invalid shape_representation without links to shapes.
131       if (ent->IsKind(STANDARD_TYPE(StepShape_ManifoldSolidBrep))) {
132         Interface_EntityIterator aShareds = WS()->Graph().Sharings(ent);
133         if (!aShareds.More()) {
134           theroots.Append(ent);
135           WS()->TransferReader()->TransientProcess()->RootsForTransfer()->Append(ent);
136         }
137       }
138       if (ent->IsKind(STANDARD_TYPE(StepShape_ShellBasedSurfaceModel))) {
139         Interface_EntityIterator aShareds = WS()->Graph().Sharings(ent);
140         if (!aShareds.More()) {
141           theroots.Append(ent);
142           WS()->TransferReader()->TransientProcess()->RootsForTransfer()->Append(ent);
143         }
144       }
145     }
146     if(ent->IsKind(STANDARD_TYPE(StepBasic_ProductDefinition))) {
147       // PTV 31.01.2003 TRJ11 exclude Product Definition With Associated Document from roots
148       if (ent->IsKind(STANDARD_TYPE(StepBasic_ProductDefinitionWithAssociatedDocuments))) {
149         // check if PDWAD-> PDF <-Document_Product_Equivalence.
150         Standard_Boolean iSexclude = Standard_False;
151         Handle(StepBasic_ProductDefinitionWithAssociatedDocuments) PDWAD =
152           Handle(StepBasic_ProductDefinitionWithAssociatedDocuments)::DownCast(ent);
153         Interface_EntityIterator PDWADsubs = WS()->Graph().Shareds(PDWAD);
154         for (PDWADsubs.Start(); PDWADsubs.More(); PDWADsubs.Next()) {
155           if ( !PDWADsubs.Value()->IsKind(STANDARD_TYPE(StepBasic_ProductDefinitionFormation)))
156             continue;
157           Handle(StepBasic_ProductDefinitionFormation) localPDF = 
158             Handle(StepBasic_ProductDefinitionFormation)::DownCast(PDWADsubs.Value());
159           Interface_EntityIterator PDFsubs = WS()->Graph().Sharings(localPDF);
160           for( PDFsubs.Start(); PDFsubs.More(); PDFsubs.Next() )
161             if (PDFsubs.Value()->IsKind(STANDARD_TYPE(StepBasic_DocumentProductEquivalence))) {
162               iSexclude = Standard_True;
163               break;
164             }
165           if (iSexclude)
166             break;
167         }
168         if (iSexclude) {
169 #ifdef OCCT_DEBUG
170           std::cout << "Warning: STEPControl_Reader::NbRootsForTransfer exclude PDWAD from roots" << std::endl;
171 #endif
172           continue;
173         }
174       }
175       Handle(StepBasic_ProductDefinition) PD = 
176         Handle(StepBasic_ProductDefinition)::DownCast(ent);
177       Standard_Boolean IsRoot = Standard_True;
178       const Interface_Graph& graph = WS()->Graph();
179       // determinate roots used NextAssemblyUsageOccurrence
180       Interface_EntityIterator subs = graph.Sharings(PD);
181       for(subs.Start(); subs.More(); subs.Next()) {
182         Handle(StepRepr_NextAssemblyUsageOccurrence) NAUO = 
183           Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(subs.Value());
184         if (NAUO.IsNull()) continue;
185         if (PD==NAUO->RelatedProductDefinition()) IsRoot=Standard_False;
186       }
187       // determinate roots used ProductDefinitionContext
188       if(IsRoot) {
189         const char *str1 = Interface_Static::CVal("read.step.product.context");
190         Standard_Integer ICS = Interface_Static::IVal("read.step.product.context");
191         if(ICS>1) {
192           subs = graph.Shareds(PD);
193           for(subs.Start(); subs.More(); subs.Next()) {
194             Handle(StepBasic_ProductDefinitionContext) PDC = 
195               Handle(StepBasic_ProductDefinitionContext)::DownCast(subs.Value());
196             if (PDC.IsNull()) continue;
197             const char *str2 = PDC->LifeCycleStage()->String().ToCString();
198             const char *str3 = PDC->Name()->String().ToCString();
199             if( !( strcasecmp(str1,str2)==0 || strcasecmp(str1,str3)==0 ) )
200               IsRoot=Standard_False;
201           }
202         }
203       }
204       // determinate roots used ProductDefinitionFormationRelationship
205       //subs = graph.Shareds(PD);
206       //for(subs.Start(); subs.More(); subs.Next()) {
207       //  Handle(StepBasic_ProductDefinitionFormation) PDF = 
208       //    Handle(StepBasic_ProductDefinitionFormation)::DownCast(subs.Value());
209       //  if (PDF.IsNull()) continue;
210       //  Interface_EntityIterator subs1 = graph.Sharings(PDF);
211       //  for(subs1.Start(); subs1.More(); subs1.Next()) {
212       //    Handle(StepBasic_ProductDefinitionFormationRelationship) PDFR = 
213       //      Handle(StepBasic_ProductDefinitionFormationRelationship)::DownCast(subs1.Value());
214       //    if (PDFR.IsNull()) continue;
215       //    if (PDF==PDFR->RelatedProductDefinition()) IsRoot=Standard_False;
216       //  }
217       //}
218       if (IsRoot) {
219         theroots.Append(ent);
220         WS()->TransferReader()->TransientProcess()->RootsForTransfer()->Append(ent);
221       }
222     }
223     TCollection_AsciiString aProdMode = Interface_Static::CVal("read.step.product.mode");
224     if(!aProdMode.IsEqual("ON")) {
225       if(ent->IsKind(STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation))) {
226         Standard_Boolean IsRoot = Standard_True;
227         Handle(StepShape_ShapeDefinitionRepresentation) SDR =
228           Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(ent);
229         Handle(StepRepr_PropertyDefinition) PropDef = SDR->Definition().PropertyDefinition();
230         if(!PropDef.IsNull()) {
231           Handle(StepBasic_ProductDefinition) PD = PropDef->Definition().ProductDefinition();
232           if(!PD.IsNull()) IsRoot = Standard_False;
233           if(IsRoot) {
234             Handle(StepRepr_ShapeAspect) SA = PropDef->Definition().ShapeAspect();
235             if(!SA.IsNull()) {
236               Handle(StepRepr_ProductDefinitionShape) PDS = SA->OfShape();
237               PD = PDS->Definition().ProductDefinition();
238               if(!PD.IsNull()) IsRoot = Standard_False;
239             }
240           }
241           if(IsRoot) {
242             Handle(StepRepr_NextAssemblyUsageOccurrence) NAUO =
243               Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(PropDef->Definition().ProductDefinitionRelationship());
244             if(!NAUO.IsNull()) IsRoot = Standard_False;
245           }
246           if(IsRoot) {
247             Handle(StepShape_ShapeRepresentation) SR =
248               Handle(StepShape_ShapeRepresentation)::DownCast(SDR->UsedRepresentation());
249             if(SR.IsNull()) IsRoot = Standard_False;
250           }
251         }
252         if(IsRoot) {
253           theroots.Append(ent);
254           WS()->TransferReader()->TransientProcess()->RootsForTransfer()->Append(ent);
255         }
256       }
257       if(ent->IsKind(STANDARD_TYPE(StepShape_ShapeRepresentation))) {
258         Standard_Boolean IsRoot = Standard_True;
259         Handle(StepShape_ShapeRepresentation) SR =
260           Handle(StepShape_ShapeRepresentation)::DownCast(ent);
261         const Interface_Graph& graph = WS()->Graph();
262         Interface_EntityIterator subs = graph.Sharings(SR);
263         for(subs.Start(); subs.More() && IsRoot; subs.Next()) {
264           Handle(StepShape_ShapeDefinitionRepresentation) SDR = 
265             Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(subs.Value());
266           if(!SDR.IsNull()) IsRoot = Standard_False;
267           if(IsRoot) {
268             Handle(StepRepr_RepresentationRelationship) RR =
269               Handle(StepRepr_RepresentationRelationship)::DownCast(subs.Value());
270             if(!RR.IsNull()) {
271               Handle(StepShape_ShapeRepresentation) SR2 =
272                 Handle(StepShape_ShapeRepresentation)::DownCast(RR->Rep1());
273               if(SR==SR2)
274                 SR2 = Handle(StepShape_ShapeRepresentation)::DownCast(RR->Rep2());
275               if(!SR2.IsNull())
276               {
277                 Interface_EntityIterator subs2 = graph.Sharings(SR2);
278                 for(subs2.Start(); subs2.More(); subs2.Next()) {
279                   Handle(StepShape_ShapeDefinitionRepresentation) SDR2 = 
280                     Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(subs2.Value());
281                   if(!SDR2.IsNull()) IsRoot = Standard_False;
282                   //else {
283                   //  if(SR==SRR->Rep2()) IsRoot = Standard_False;
284                   //}
285                 }
286               }
287             }
288           }
289           if(IsRoot) {
290             Handle(StepRepr_RepresentationMap) RM =
291               Handle(StepRepr_RepresentationMap)::DownCast(subs.Value());
292             if(!RM.IsNull()) {
293               Interface_EntityIterator subs2 = graph.Sharings(RM);
294               for(subs2.Start(); subs2.More(); subs2.Next()) {
295                 Handle(StepRepr_MappedItem) MI = Handle(StepRepr_MappedItem)::DownCast(subs2.Value());
296                 if(!MI.IsNull()) {
297                   Interface_EntityIterator subs3 = graph.Sharings(MI);
298                   for(subs3.Start(); subs3.More(); subs3.Next()) {
299                     Handle(StepShape_ShapeRepresentation) SR2 =
300                       Handle(StepShape_ShapeRepresentation)::DownCast(subs3.Value());
301                     if(!SR2.IsNull()) IsRoot = Standard_False;
302                   }
303                 }
304               }
305             }
306           }
307         }
308         if(IsRoot) {
309           theroots.Append(ent);
310           WS()->TransferReader()->TransientProcess()->RootsForTransfer()->Append(ent);
311         }
312       }
313     }
314
315   }
316
317
318   return theroots.Length();
319 }
320
321 //=======================================================================
322 //function : FileUnits
323 //purpose  : 
324 //=======================================================================
325
326 void STEPControl_Reader::FileUnits( TColStd_SequenceOfAsciiString& theUnitLengthNames,
327                                    TColStd_SequenceOfAsciiString& theUnitAngleNames,
328                                    TColStd_SequenceOfAsciiString& theUnitSolidAngleNames) 
329 {
330   Standard_Integer nbroots = NbRootsForTransfer();
331   if(!nbroots)
332     return;
333   enum
334   {
335     LENGTH = 0,
336     ANLGE =  1,
337     SOLID_ANGLE = 2
338   };
339   const Interface_Graph& graph = WS()->Graph();
340   TColStd_MapOfAsciiString aMapUnits[3];
341
342   for(Standard_Integer i = 1; i <= nbroots; i++)
343   {
344     Handle(Standard_Transient) anEnt = theroots(i);
345     Standard_Integer num   = graph.EntityNumber(anEnt);
346     if(!num )
347       continue;
348     Handle(StepBasic_ProductDefinition) aProdDef = 
349       Handle(StepBasic_ProductDefinition)::DownCast(anEnt);
350     Handle(StepShape_ShapeDefinitionRepresentation) aShapeDefRepr;
351     if(!aProdDef.IsNull())
352     {
353       Interface_EntityIterator subsPD = graph.Sharings(aProdDef);
354       for(subsPD.Start(); subsPD.More() && aShapeDefRepr.IsNull(); subsPD.Next()) 
355       {
356         Handle(StepRepr_ProductDefinitionShape) aProdDefShape =
357           Handle(StepRepr_ProductDefinitionShape)::DownCast(subsPD.Value());
358         if(aProdDefShape.IsNull())
359           continue;
360         Interface_EntityIterator subsSR = graph.Sharings(aProdDefShape);
361         Handle(StepShape_ShapeRepresentation) SR;
362         for(subsSR.Start(); subsSR.More() && aShapeDefRepr.IsNull(); subsSR.Next())
363         {
364           Handle(StepShape_ShapeDefinitionRepresentation) aCurShapeDefRepr =
365             Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(subsSR.Value());
366           if(aCurShapeDefRepr.IsNull()) 
367             continue;
368           Handle(StepRepr_Representation) aUseRepr = aCurShapeDefRepr->UsedRepresentation();
369           if(aUseRepr.IsNull())
370             continue;
371           Handle(StepShape_ShapeRepresentation) aShapeRepr = 
372             Handle(StepShape_ShapeRepresentation)::DownCast(aUseRepr);
373           if(aShapeRepr.IsNull()) 
374             continue;
375           aShapeDefRepr = aCurShapeDefRepr;
376
377         }
378
379
380       }
381
382     }
383     else
384       aShapeDefRepr = Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(anEnt);
385     if(!aShapeDefRepr.IsNull())
386     {
387       Handle(StepShape_ShapeRepresentation) aShapeRepr =
388         Handle(StepShape_ShapeRepresentation)::DownCast(aShapeDefRepr->UsedRepresentation());
389       Handle(StepRepr_RepresentationContext) aRepCont = aShapeRepr->ContextOfItems();
390       if (aRepCont.IsNull())
391         continue;
392       TColStd_Array1OfAsciiString aNameUnits(1,3);
393       TColStd_Array1OfReal aFactorUnits(1,3);
394       if(findUnits(aRepCont,aNameUnits,aFactorUnits))
395       {
396         Standard_Integer k = LENGTH;
397         for ( ; k <= SOLID_ANGLE ; k++)
398         {
399           if(!aMapUnits[k].Contains(aNameUnits(k+1)))
400           {
401             aMapUnits[k].Add(aNameUnits(k+1));
402             TColStd_SequenceOfAsciiString& anUnitSeq = (k == LENGTH ? 
403                 theUnitLengthNames : ( k == ANLGE ? theUnitAngleNames : theUnitSolidAngleNames ));
404             anUnitSeq.Append(aNameUnits(k+1));
405           }
406         }
407       }
408
409     }
410
411   }
412   //for case when units was not found through PDF or SDR
413   if(theUnitLengthNames.IsEmpty())
414   {
415     const Handle(Interface_InterfaceModel) &aModel = WS()->Model();
416     if(aModel.IsNull())
417       return;
418     Standard_Integer nb = aModel->NbEntities();
419     for(Standard_Integer i = 1; i <= nb; i++)
420     {
421       Handle(Standard_Transient) anEnt = aModel->Value(i);
422       Handle(StepRepr_RepresentationContext) aRepCont = Handle(StepRepr_RepresentationContext)::DownCast(anEnt);
423       if (aRepCont.IsNull())
424         continue;
425       TColStd_Array1OfAsciiString aNameUnits(1,3);
426       TColStd_Array1OfReal aFactorUnits(1,3);
427       if(findUnits(aRepCont,aNameUnits,aFactorUnits))
428       {
429         Standard_Integer k = LENGTH;
430         for ( ; k <= SOLID_ANGLE ; k++)
431         {
432           if(!aMapUnits[k].Contains(aNameUnits(k+1)))
433           {
434             aMapUnits[k].Add(aNameUnits(k+1));
435             TColStd_SequenceOfAsciiString& anUnitSeq = (k == LENGTH ? 
436                theUnitLengthNames : ( k == ANLGE ? theUnitAngleNames : theUnitSolidAngleNames ));
437             anUnitSeq.Append(aNameUnits(k+1));
438           }
439         }
440       }
441     }
442   }
443 }
444
445 //=======================================================================
446 //function : getSiName
447 //purpose  : 
448 //=======================================================================
449
450 inline static TCollection_AsciiString getSiName(const Handle(StepBasic_SiUnit)& theUnit)
451 {
452  
453   TCollection_AsciiString aName;
454   if (theUnit->HasPrefix()) {
455     switch (theUnit->Prefix()) {
456       case StepBasic_spExa:   aName += "exa"; break;
457       case StepBasic_spPeta: aName += "peta"; break;
458       case StepBasic_spTera: aName += "tera"; break;
459       case StepBasic_spGiga: aName += "giga"; break;
460       case StepBasic_spMega:  aName += "mega"; break;
461       case StepBasic_spHecto: aName += "hecto"; break;
462       case StepBasic_spDeca:  aName += "deca"; break;
463       case StepBasic_spDeci:  aName += "deci"; break;
464       
465       case StepBasic_spPico:  aName += "pico"; break;
466       case StepBasic_spFemto: aName += "femto"; break;
467       case StepBasic_spAtto:  aName += "atto"; break;
468       
469       case StepBasic_spKilo : aName += "kilo"; break;
470       case StepBasic_spCenti :aName += "centi"; break;
471       case StepBasic_spMilli :aName += "milli"; break;
472       case StepBasic_spMicro :aName += "micro"; break;
473       case StepBasic_spNano :aName += "nano"; break;
474       default: break;
475     };
476   }
477   
478   switch(theUnit->Name()) {
479     case StepBasic_sunMetre : aName += "metre"; break;
480     case StepBasic_sunRadian : aName += "radian"; break;
481     case StepBasic_sunSteradian : aName += "steradian"; break; 
482     default: break;
483   };
484   return aName;
485 }
486
487 //=======================================================================
488 //function : findUnits
489 //purpose  : 
490 //=======================================================================
491
492 Standard_Boolean STEPControl_Reader::findUnits(
493        const Handle(StepRepr_RepresentationContext)& theRepCont,
494        TColStd_Array1OfAsciiString& theNameUnits,
495        TColStd_Array1OfReal& theFactorUnits)
496 {
497    Handle(StepRepr_GlobalUnitAssignedContext) aContext;
498   Handle(StepRepr_GlobalUncertaintyAssignedContext) aTol;
499
500   if (theRepCont->IsKind(STANDARD_TYPE(StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext))) {
501     aContext = Handle(StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext)::
502       DownCast(theRepCont)->GlobalUnitAssignedContext();
503   }
504
505  
506   if (theRepCont->IsKind(STANDARD_TYPE(StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx))) {
507     aContext = Handle(StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx)::
508       DownCast(theRepCont)->GlobalUnitAssignedContext();
509    
510   }
511   if(aContext.IsNull())
512     return Standard_False;
513   // Start Computation
514   Handle(StepBasic_HArray1OfNamedUnit) anUnits = aContext->Units();
515   Standard_Integer nbU = aContext->NbUnits();
516   Standard_Integer nbFind = 0;
517   for (Standard_Integer i = 1; i <= nbU; i++) {
518     Handle(StepBasic_NamedUnit) aNamedUnit = aContext->UnitsValue(i);
519     Handle(StepBasic_ConversionBasedUnit) aConvUnit =
520       Handle(StepBasic_ConversionBasedUnit)::DownCast(aNamedUnit);
521     Standard_Integer anInd = 0;
522     TCollection_AsciiString aName;
523     Standard_Real anUnitFact = 0;
524     if( !aConvUnit.IsNull() )
525     {
526       Handle(StepBasic_MeasureWithUnit) aMeasWithUnit = 
527         aConvUnit->ConversionFactor();
528       
529        if(aMeasWithUnit.IsNull())
530          continue;
531        
532        if( aMeasWithUnit->IsKind(STANDARD_TYPE(StepBasic_LengthMeasureWithUnit)) )
533          anInd = 1;
534        else if( aMeasWithUnit->IsKind(STANDARD_TYPE(StepBasic_PlaneAngleMeasureWithUnit)) )
535          anInd = 2;
536        else if( aMeasWithUnit->IsKind(STANDARD_TYPE(StepBasic_SolidAngleMeasureWithUnit)) )
537          anInd = 3;
538       if(!anInd)
539         continue;
540       aName = aConvUnit->Name()->String(); 
541       anUnitFact = aMeasWithUnit->ValueComponent();
542     }
543     else
544     {
545       Handle(StepBasic_SiUnit) aSiUnit = Handle(StepBasic_SiUnit)::DownCast(aNamedUnit);
546       if( aSiUnit.IsNull())
547         continue;
548       if(aSiUnit->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndLengthUnit)))
549         anInd =1;
550       else if(aSiUnit->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndPlaneAngleUnit)))
551         anInd = 2;
552       else if(aSiUnit->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndSolidAngleUnit)))
553         anInd = 3;
554       if( !anInd )
555          continue;
556       anUnitFact = (!aSiUnit->HasPrefix()  ? 
557                     1. : STEPConstruct_UnitContext::ConvertSiPrefix(aSiUnit->Prefix()));
558       aName = getSiName(aSiUnit);
559       
560            
561     }
562     if( !anInd )
563       continue;
564  
565    theNameUnits.SetValue(anInd, aName);
566    theFactorUnits.SetValue(anInd, anUnitFact);
567     nbFind++;
568        
569    }
570
571   return nbFind != 0;
572 }