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