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