Warnings on vc14 were eliminated
[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 {
111   return TransferOneRoot (num);
112 }
113
114 //=======================================================================
115 //function : NbRootsForTransfer
116 //purpose  : 
117 //=======================================================================
118
119 Standard_Integer STEPControl_Reader::NbRootsForTransfer() 
120 {
121   if (therootsta) return theroots.Length();
122   therootsta = Standard_True;
123
124   //theroots.Clear();
125   Standard_Integer nb = Model()->NbEntities();
126   for (Standard_Integer i = 1; i <= nb; i ++) {
127     Handle(Standard_Transient) ent = Model()->Value(i);
128     if (Interface_Static::IVal("read.step.all.shapes") == 1) {
129       // Special case to read invalid shape_representation without links to shapes.
130       if (ent->IsKind(STANDARD_TYPE(StepShape_ManifoldSolidBrep))) {
131         Interface_EntityIterator aShareds = WS()->Graph().Sharings(ent);
132         if (!aShareds.More()) {
133           theroots.Append(ent);
134           WS()->TransferReader()->TransientProcess()->RootsForTransfer()->Append(ent);
135         }
136       }
137       if (ent->IsKind(STANDARD_TYPE(StepShape_ShellBasedSurfaceModel))) {
138         Interface_EntityIterator aShareds = WS()->Graph().Sharings(ent);
139         if (!aShareds.More()) {
140           theroots.Append(ent);
141           WS()->TransferReader()->TransientProcess()->RootsForTransfer()->Append(ent);
142         }
143       }
144     }
145     if(ent->IsKind(STANDARD_TYPE(StepBasic_ProductDefinition))) {
146       // PTV 31.01.2003 TRJ11 exclude Product Definition With Associated Document from roots
147       if (ent->IsKind(STANDARD_TYPE(StepBasic_ProductDefinitionWithAssociatedDocuments))) {
148         // check if PDWAD-> PDF <-Document_Product_Equivalence.
149         Standard_Boolean iSexclude = Standard_False;
150         Handle(StepBasic_ProductDefinitionWithAssociatedDocuments) PDWAD =
151           Handle(StepBasic_ProductDefinitionWithAssociatedDocuments)::DownCast(ent);
152         Interface_EntityIterator PDWADsubs = WS()->Graph().Shareds(PDWAD);
153         for (PDWADsubs.Start(); PDWADsubs.More(); PDWADsubs.Next()) {
154           if ( !PDWADsubs.Value()->IsKind(STANDARD_TYPE(StepBasic_ProductDefinitionFormation)))
155             continue;
156           Handle(StepBasic_ProductDefinitionFormation) localPDF = 
157             Handle(StepBasic_ProductDefinitionFormation)::DownCast(PDWADsubs.Value());
158           Interface_EntityIterator PDFsubs = WS()->Graph().Sharings(localPDF);
159           for( PDFsubs.Start(); PDFsubs.More(); PDFsubs.Next() )
160             if (PDFsubs.Value()->IsKind(STANDARD_TYPE(StepBasic_DocumentProductEquivalence))) {
161               iSexclude = Standard_True;
162               break;
163             }
164           if (iSexclude)
165             break;
166         }
167         if (iSexclude) {
168 #ifdef OCCT_DEBUG
169           cout << "Warning: STEPControl_Reader::NbRootsForTransfer exclude PDWAD from roots" << endl;
170 #endif
171           continue;
172         }
173       }
174       Handle(StepBasic_ProductDefinition) PD = 
175         Handle(StepBasic_ProductDefinition)::DownCast(ent);
176       Standard_Boolean IsRoot = Standard_True;
177       const Interface_Graph& graph = WS()->Graph();
178       // determinate roots used NextAssemblyUsageOccurrence
179       Interface_EntityIterator subs = graph.Sharings(PD);
180       for(subs.Start(); subs.More(); subs.Next()) {
181         Handle(StepRepr_NextAssemblyUsageOccurrence) NAUO = 
182           Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(subs.Value());
183         if (NAUO.IsNull()) continue;
184         if (PD==NAUO->RelatedProductDefinition()) IsRoot=Standard_False;
185       }
186       // determinate roots used ProductDefinitionContext
187       if(IsRoot) {
188         const char *str1 = Interface_Static::CVal("read.step.product.context");
189         Standard_Integer ICS = Interface_Static::IVal("read.step.product.context");
190         if(ICS>1) {
191           subs = graph.Shareds(PD);
192           for(subs.Start(); subs.More(); subs.Next()) {
193             Handle(StepBasic_ProductDefinitionContext) PDC = 
194               Handle(StepBasic_ProductDefinitionContext)::DownCast(subs.Value());
195             if (PDC.IsNull()) continue;
196             const char *str2 = PDC->LifeCycleStage()->String().ToCString();
197             const char *str3 = PDC->Name()->String().ToCString();
198             if( !( strcasecmp(str1,str2)==0 || strcasecmp(str1,str3)==0 ) )
199               IsRoot=Standard_False;
200           }
201         }
202       }
203       // determinate roots used ProductDefinitionFormationRelationship
204       //subs = graph.Shareds(PD);
205       //for(subs.Start(); subs.More(); subs.Next()) {
206       //  Handle(StepBasic_ProductDefinitionFormation) PDF = 
207       //    Handle(StepBasic_ProductDefinitionFormation)::DownCast(subs.Value());
208       //  if (PDF.IsNull()) continue;
209       //  Interface_EntityIterator subs1 = graph.Sharings(PDF);
210       //  for(subs1.Start(); subs1.More(); subs1.Next()) {
211       //    Handle(StepBasic_ProductDefinitionFormationRelationship) PDFR = 
212       //      Handle(StepBasic_ProductDefinitionFormationRelationship)::DownCast(subs1.Value());
213       //    if (PDFR.IsNull()) continue;
214       //    if (PDF==PDFR->RelatedProductDefinition()) IsRoot=Standard_False;
215       //  }
216       //}
217       if (IsRoot) {
218         theroots.Append(ent);
219         WS()->TransferReader()->TransientProcess()->RootsForTransfer()->Append(ent);
220       }
221     }
222     TCollection_AsciiString aProdMode = Interface_Static::CVal("read.step.product.mode");
223     if(!aProdMode.IsEqual("ON")) {
224       if(ent->IsKind(STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation))) {
225         Standard_Boolean IsRoot = Standard_True;
226         Handle(StepShape_ShapeDefinitionRepresentation) SDR =
227           Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(ent);
228         Handle(StepRepr_PropertyDefinition) PropDef = SDR->Definition().PropertyDefinition();
229         if(!PropDef.IsNull()) {
230           Handle(StepBasic_ProductDefinition) PD = PropDef->Definition().ProductDefinition();
231           if(!PD.IsNull()) IsRoot = Standard_False;
232           if(IsRoot) {
233             Handle(StepRepr_ShapeAspect) SA = PropDef->Definition().ShapeAspect();
234             if(!SA.IsNull()) {
235               Handle(StepRepr_ProductDefinitionShape) PDS = SA->OfShape();
236               PD = PDS->Definition().ProductDefinition();
237               if(!PD.IsNull()) IsRoot = Standard_False;
238             }
239           }
240           if(IsRoot) {
241             Handle(StepRepr_NextAssemblyUsageOccurrence) NAUO =
242               Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(PropDef->Definition().ProductDefinitionRelationship());
243             if(!NAUO.IsNull()) IsRoot = Standard_False;
244           }
245           if(IsRoot) {
246             Handle(StepShape_ShapeRepresentation) SR =
247               Handle(StepShape_ShapeRepresentation)::DownCast(SDR->UsedRepresentation());
248             if(SR.IsNull()) IsRoot = Standard_False;
249           }
250         }
251         if(IsRoot) {
252           theroots.Append(ent);
253           WS()->TransferReader()->TransientProcess()->RootsForTransfer()->Append(ent);
254         }
255       }
256       if(ent->IsKind(STANDARD_TYPE(StepShape_ShapeRepresentation))) {
257         Standard_Boolean IsRoot = Standard_True;
258         Handle(StepShape_ShapeRepresentation) SR =
259           Handle(StepShape_ShapeRepresentation)::DownCast(ent);
260         const Interface_Graph& graph = WS()->Graph();
261         Interface_EntityIterator subs = graph.Sharings(SR);
262         for(subs.Start(); subs.More() && IsRoot; subs.Next()) {
263           Handle(StepShape_ShapeDefinitionRepresentation) SDR = 
264             Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(subs.Value());
265           if(!SDR.IsNull()) IsRoot = Standard_False;
266           if(IsRoot) {
267             Handle(StepRepr_RepresentationRelationship) RR =
268               Handle(StepRepr_RepresentationRelationship)::DownCast(subs.Value());
269             if(!RR.IsNull()) {
270               Handle(StepShape_ShapeRepresentation) SR2 =
271                 Handle(StepShape_ShapeRepresentation)::DownCast(RR->Rep1());
272               if(SR==SR2)
273                 SR2 = Handle(StepShape_ShapeRepresentation)::DownCast(RR->Rep2());
274               if(!SR2.IsNull())
275               {
276                 Interface_EntityIterator subs2 = graph.Sharings(SR2);
277                 for(subs2.Start(); subs2.More(); subs2.Next()) {
278                   Handle(StepShape_ShapeDefinitionRepresentation) SDR2 = 
279                     Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(subs2.Value());
280                   if(!SDR2.IsNull()) IsRoot = Standard_False;
281                   //else {
282                   //  if(SR==SRR->Rep2()) IsRoot = Standard_False;
283                   //}
284                 }
285               }
286             }
287           }
288           if(IsRoot) {
289             Handle(StepRepr_RepresentationMap) RM =
290               Handle(StepRepr_RepresentationMap)::DownCast(subs.Value());
291             if(!RM.IsNull()) {
292               Interface_EntityIterator subs2 = graph.Sharings(RM);
293               for(subs2.Start(); subs2.More(); subs2.Next()) {
294                 Handle(StepRepr_MappedItem) MI = Handle(StepRepr_MappedItem)::DownCast(subs2.Value());
295                 if(!MI.IsNull()) {
296                   Interface_EntityIterator subs3 = graph.Sharings(MI);
297                   for(subs3.Start(); subs3.More(); subs3.Next()) {
298                     Handle(StepShape_ShapeRepresentation) SR2 =
299                       Handle(StepShape_ShapeRepresentation)::DownCast(subs3.Value());
300                     if(!SR2.IsNull()) IsRoot = Standard_False;
301                   }
302                 }
303               }
304             }
305           }
306         }
307         if(IsRoot) {
308           theroots.Append(ent);
309           WS()->TransferReader()->TransientProcess()->RootsForTransfer()->Append(ent);
310         }
311       }
312     }
313
314   }
315
316
317   return theroots.Length();
318 }
319
320 //=======================================================================
321 //function : FileUnits
322 //purpose  : 
323 //=======================================================================
324
325 void STEPControl_Reader::FileUnits( TColStd_SequenceOfAsciiString& theUnitLengthNames,
326                                    TColStd_SequenceOfAsciiString& theUnitAngleNames,
327                                    TColStd_SequenceOfAsciiString& theUnitSolidAngleNames) 
328 {
329   Standard_Integer nbroots = NbRootsForTransfer();
330   if(!nbroots)
331     return;
332   enum
333   {
334     LENGTH = 0,
335     ANLGE =  1,
336     SOLID_ANGLE = 2
337   };
338   const Interface_Graph& graph = WS()->Graph();
339   TColStd_MapOfAsciiString aMapUnits[3];
340
341   for(Standard_Integer i = 1; i <= nbroots; i++)
342   {
343     Handle(Standard_Transient) anEnt = theroots(i);
344     Standard_Integer num   = graph.EntityNumber(anEnt);
345     if(!num )
346       continue;
347     Handle(StepBasic_ProductDefinition) aProdDef = 
348       Handle(StepBasic_ProductDefinition)::DownCast(anEnt);
349     Handle(StepShape_ShapeDefinitionRepresentation) aShapeDefRepr;
350     if(!aProdDef.IsNull())
351     {
352       Interface_EntityIterator subsPD = graph.Sharings(aProdDef);
353       for(subsPD.Start(); subsPD.More() && aShapeDefRepr.IsNull(); subsPD.Next()) 
354       {
355         Handle(StepRepr_ProductDefinitionShape) aProdDefShape =
356           Handle(StepRepr_ProductDefinitionShape)::DownCast(subsPD.Value());
357         if(aProdDefShape.IsNull())
358           continue;
359         Interface_EntityIterator subsSR = graph.Sharings(aProdDefShape);
360         Handle(StepShape_ShapeRepresentation) SR;
361         for(subsSR.Start(); subsSR.More() && aShapeDefRepr.IsNull(); subsSR.Next())
362         {
363           Handle(StepShape_ShapeDefinitionRepresentation) aCurShapeDefRepr =
364             Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(subsSR.Value());
365           if(aCurShapeDefRepr.IsNull()) 
366             continue;
367           Handle(StepRepr_Representation) aUseRepr = aCurShapeDefRepr->UsedRepresentation();
368           if(aUseRepr.IsNull())
369             continue;
370           Handle(StepShape_ShapeRepresentation) aShapeRepr = 
371             Handle(StepShape_ShapeRepresentation)::DownCast(aUseRepr);
372           if(aShapeRepr.IsNull()) 
373             continue;
374           aShapeDefRepr = aCurShapeDefRepr;
375
376         }
377
378
379       }
380
381     }
382     else
383       aShapeDefRepr = Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(anEnt);
384     if(!aShapeDefRepr.IsNull())
385     {
386       Handle(StepShape_ShapeRepresentation) aShapeRepr =
387         Handle(StepShape_ShapeRepresentation)::DownCast(aShapeDefRepr->UsedRepresentation());
388       Handle(StepRepr_RepresentationContext) aRepCont = aShapeRepr->ContextOfItems();
389       if (aRepCont.IsNull())
390         continue;
391       TColStd_Array1OfAsciiString aNameUnits(1,3);
392       TColStd_Array1OfReal aFactorUnits(1,3);
393       if(findUnits(aRepCont,aNameUnits,aFactorUnits))
394       {
395         Standard_Integer k = LENGTH;
396         for ( ; k <= SOLID_ANGLE ; k++)
397         {
398           if(!aMapUnits[k].Contains(aNameUnits(k+1)))
399           {
400             aMapUnits[k].Add(aNameUnits(k+1));
401             TColStd_SequenceOfAsciiString& anUnitSeq = (k == LENGTH ? 
402                 theUnitLengthNames : ( k == ANLGE ? theUnitAngleNames : theUnitSolidAngleNames ));
403             anUnitSeq.Append(aNameUnits(k+1));
404           }
405         }
406       }
407
408     }
409
410   }
411   //for case when units was not found through PDF or SDR
412   if(theUnitLengthNames.IsEmpty())
413   {
414     const Handle(Interface_InterfaceModel) &aModel = WS()->Model();
415     if(aModel.IsNull())
416       return;
417     Standard_Integer nb = aModel->NbEntities();
418     for(Standard_Integer i = 1; i <= nb; i++)
419     {
420       Handle(Standard_Transient) anEnt = aModel->Value(i);
421       Handle(StepRepr_RepresentationContext) aRepCont = Handle(StepRepr_RepresentationContext)::DownCast(anEnt);
422       if (aRepCont.IsNull())
423         continue;
424       TColStd_Array1OfAsciiString aNameUnits(1,3);
425       TColStd_Array1OfReal aFactorUnits(1,3);
426       if(findUnits(aRepCont,aNameUnits,aFactorUnits))
427       {
428         Standard_Integer k = LENGTH;
429         for ( ; k <= SOLID_ANGLE ; k++)
430         {
431           if(!aMapUnits[k].Contains(aNameUnits(k+1)))
432           {
433             aMapUnits[k].Add(aNameUnits(k+1));
434             TColStd_SequenceOfAsciiString& anUnitSeq = (k == LENGTH ? 
435                theUnitLengthNames : ( k == ANLGE ? theUnitAngleNames : theUnitSolidAngleNames ));
436             anUnitSeq.Append(aNameUnits(k+1));
437           }
438         }
439       }
440     }
441   }
442 }
443
444 //=======================================================================
445 //function : getSiName
446 //purpose  : 
447 //=======================================================================
448
449 inline static TCollection_AsciiString getSiName(const Handle(StepBasic_SiUnit)& theUnit)
450 {
451  
452   TCollection_AsciiString aName;
453   if (theUnit->HasPrefix()) {
454     switch (theUnit->Prefix()) {
455       case StepBasic_spExa:   aName += "exa"; break;
456       case StepBasic_spPeta: aName += "peta"; break;
457       case StepBasic_spTera: aName += "tera"; break;
458       case StepBasic_spGiga: aName += "giga"; break;
459       case StepBasic_spMega:  aName += "mega"; break;
460       case StepBasic_spHecto: aName += "hecto"; break;
461       case StepBasic_spDeca:  aName += "deca"; break;
462       case StepBasic_spDeci:  aName += "deci"; break;
463       
464       case StepBasic_spPico:  aName += "pico"; break;
465       case StepBasic_spFemto: aName += "femto"; break;
466       case StepBasic_spAtto:  aName += "atto"; break;
467       
468       case StepBasic_spKilo : aName += "kilo"; break;
469       case StepBasic_spCenti :aName += "centi"; break;
470       case StepBasic_spMilli :aName += "milli"; break;
471       case StepBasic_spMicro :aName += "micro"; break;
472       case StepBasic_spNano :aName += "nano"; break;
473       default: break;
474     };
475   }
476   
477   switch(theUnit->Name()) {
478     case StepBasic_sunMetre : aName += "metre"; break;
479     case StepBasic_sunRadian : aName += "radian"; break;
480     case StepBasic_sunSteradian : aName += "steradian"; break; 
481     default: break;
482   };
483   return aName;
484 }
485
486 //=======================================================================
487 //function : findUnits
488 //purpose  : 
489 //=======================================================================
490
491 Standard_Boolean STEPControl_Reader::findUnits(
492        const Handle(StepRepr_RepresentationContext)& theRepCont,
493        TColStd_Array1OfAsciiString& theNameUnits,
494        TColStd_Array1OfReal& theFactorUnits)
495 {
496    Handle(StepRepr_GlobalUnitAssignedContext) aContext;
497   Handle(StepRepr_GlobalUncertaintyAssignedContext) aTol;
498
499   if (theRepCont->IsKind(STANDARD_TYPE(StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext))) {
500     aContext = Handle(StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext)::
501       DownCast(theRepCont)->GlobalUnitAssignedContext();
502   }
503
504  
505   if (theRepCont->IsKind(STANDARD_TYPE(StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx))) {
506     aContext = Handle(StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx)::
507       DownCast(theRepCont)->GlobalUnitAssignedContext();
508    
509   }
510   if(aContext.IsNull())
511     return Standard_False;
512   // Start Computation
513   Handle(StepBasic_HArray1OfNamedUnit) anUnits = aContext->Units();
514   Standard_Integer nbU = aContext->NbUnits();
515   Standard_Integer nbFind = 0;
516   for (Standard_Integer i = 1; i <= nbU; i++) {
517     Handle(StepBasic_NamedUnit) aNamedUnit = aContext->UnitsValue(i);
518     Handle(StepBasic_ConversionBasedUnit) aConvUnit =
519       Handle(StepBasic_ConversionBasedUnit)::DownCast(aNamedUnit);
520     Standard_Integer anInd = 0;
521     TCollection_AsciiString aName;
522     Standard_Real anUnitFact = 0;
523     if( !aConvUnit.IsNull() )
524     {
525       Handle(StepBasic_MeasureWithUnit) aMeasWithUnit = 
526         aConvUnit->ConversionFactor();
527       
528        if(aMeasWithUnit.IsNull())
529          continue;
530        
531        if( aMeasWithUnit->IsKind(STANDARD_TYPE(StepBasic_LengthMeasureWithUnit)) )
532          anInd = 1;
533        else if( aMeasWithUnit->IsKind(STANDARD_TYPE(StepBasic_PlaneAngleMeasureWithUnit)) )
534          anInd = 2;
535        else if( aMeasWithUnit->IsKind(STANDARD_TYPE(StepBasic_SolidAngleMeasureWithUnit)) )
536          anInd = 3;
537       if(!anInd)
538         continue;
539       aName = aConvUnit->Name()->String(); 
540       anUnitFact = aMeasWithUnit->ValueComponent();
541     }
542     else
543     {
544       Handle(StepBasic_SiUnit) aSiUnit = Handle(StepBasic_SiUnit)::DownCast(aNamedUnit);
545       if( aSiUnit.IsNull())
546         continue;
547       if(aSiUnit->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndLengthUnit)))
548         anInd =1;
549       else if(aSiUnit->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndPlaneAngleUnit)))
550         anInd = 2;
551       else if(aSiUnit->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndSolidAngleUnit)))
552         anInd = 3;
553       if( !anInd )
554          continue;
555       anUnitFact = (!aSiUnit->HasPrefix()  ? 
556                     1. : STEPConstruct_UnitContext::ConvertSiPrefix(aSiUnit->Prefix()));
557       aName = getSiName(aSiUnit);
558       
559            
560     }
561     if( !anInd )
562       continue;
563  
564    theNameUnits.SetValue(anInd, aName);
565    theFactorUnits.SetValue(anInd, anUnitFact);
566     nbFind++;
567        
568    }
569
570   return nbFind != 0;
571 }