0022746: Progress indicator in ShapeHealing
[occt.git] / src / STEPControl / STEPControl_ActorRead.cxx
1 //:k3 abv 25.11.98 rp1sd.stp
2 //:n4 abv 11.02.99 S4132: recognition of GeometricSet (instead of GeometricCurveSet)
3 //    gka 05.04.99 S4136: eliminate parameter lastpreci
4 //gka,abv 14.04.99 S4136: maintain unit context, precision and maxtolerance values
5 #include <STEPControl_ActorRead.ixx>
6 #include <OSD_Timer.hxx>
7
8 // #include <Interface_InterfaceModel.hxx>  // pour mise au point
9
10 #include <StepShape_ShapeDefinitionRepresentation.hxx>
11 #include <StepShape_ShapeRepresentation.hxx>
12 #include <StepShape_FacetedBrepAndBrepWithVoids.hxx>
13 #include <StepShape_FacetedBrep.hxx>
14 #include <StepShape_ShellBasedSurfaceModel.hxx>
15 #include <StepShape_ManifoldSolidBrep.hxx>
16 #include <StepShape_BrepWithVoids.hxx>
17 #include <StepShape_GeometricSet.hxx>
18
19 // MappedItem :
20 #include <StepRepr_MappedItem.hxx>
21 #include <StepGeom_Axis2Placement3d.hxx>
22 #include <StepRepr_RepresentationMap.hxx>
23 #include <StepToTopoDS_MakeTransformed.hxx>
24
25 // FaceSurface :
26 #include <StepShape_FaceSurface.hxx>
27 #include <StepToTopoDS_Tool.hxx>
28 #include <StepToTopoDS_DataMapOfTRI.hxx>
29 #include <StepToTopoDS_TranslateFace.hxx>
30
31 //  Unites :
32 #include <StepRepr_RepresentationContext.hxx>
33 #include <StepRepr_GlobalUnitAssignedContext.hxx>
34 #include <StepRepr_GlobalUncertaintyAssignedContext.hxx>
35 //#include <StepBasic_UncertaintyMeasureWithUnit.hxx>
36 #include <StepBasic_ProductRelatedProductCategory.hxx>
37 #include <StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext.hxx>
38 #include <StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx.hxx>
39
40 #include <STEPConstruct_UnitContext.hxx>
41 #include <UnitsMethods.hxx>
42
43 //  Representation Relationship & cie
44 #include <Interface_Graph.hxx>
45 #include <Interface_EntityIterator.hxx>
46 #include <TransferBRep.hxx>
47 #include <StepShape_ContextDependentShapeRepresentation.hxx>
48 #include <StepRepr_ShapeRepresentationRelationship.hxx>
49 #include <StepRepr_ShapeRepresentationRelationshipWithTransformation.hxx>
50 #include <StepRepr_Transformation.hxx>
51 #include <StepRepr_ItemDefinedTransformation.hxx>
52
53 #include <BRep_Builder.hxx>
54 #include <StepToTopoDS_Builder.hxx>
55 #include <TopoDS_Compound.hxx>
56 #include <TopoDS_Shape.hxx>
57
58 #include <TransferBRep_ShapeBinder.hxx>
59
60 #include <Interface_Static.hxx>
61 #include <Interface_Macros.hxx>
62 #include <Interface_InterfaceModel.hxx>
63
64 #include <StepBasic_ProductDefinition.hxx>
65 #include <StepRepr_ProductDefinitionShape.hxx>
66 #include <StepRepr_NextAssemblyUsageOccurrence.hxx>
67 #include <STEPConstruct_Assembly.hxx>
68 #include <Precision.hxx>
69 #include <StepToGeom_MakeTransformation3d.hxx>
70 #include <StepToGeom_MakeAxis2Placement.hxx>
71 #include <Geom_Axis2Placement.hxx>
72 #include <gp_Ax3.hxx>
73 #include <StepRepr_ShapeAspect.hxx>
74 #include <XSAlgo.hxx>
75 #include <XSAlgo_AlgoContainer.hxx>
76 #include <StepShape_EdgeBasedWireframeModel.hxx>
77 #include <StepShape_FaceBasedSurfaceModel.hxx>
78
79 #include <StepShape_AdvancedBrepShapeRepresentation.hxx>
80 #include <StepShape_FacetedBrepShapeRepresentation.hxx>
81 #include <StepShape_ManifoldSurfaceShapeRepresentation.hxx>
82 #include <StepShape_EdgeBasedWireframeShapeRepresentation.hxx>
83 #include <StepShape_GeometricallyBoundedSurfaceShapeRepresentation.hxx>
84 #include <StepShape_GeometricallyBoundedWireframeShapeRepresentation.hxx>
85
86 #include <TColStd_HSequenceOfTransient.hxx>
87 #include <Message_ProgressSentry.hxx>
88 #include <Message_Messenger.hxx>
89 #include <StepRepr_HSequenceOfRepresentationItem.hxx>
90 #include <StepBasic_ProductDefinition.hxx>
91 #include <Standard_Failure.hxx>
92 #include <Standard_ErrorHandler.hxx>
93 #include <StepDimTol_DatumFeature.hxx>
94 #include <StepDimTol_GeometricTolerance.hxx>
95 #include <StepDimTol_GeoTolAndGeoTolWthDatRefAndModGeoTolAndPosTol.hxx>
96
97 // For non-manifold topology processing (ssv; 12.11.2010)
98 #include <StepShape_NonManifoldSurfaceShapeRepresentation.hxx>
99 #include <StepRepr_HArray1OfRepresentationItem.hxx>
100 #include <TopTools_MapOfShape.hxx>
101 #include <TopTools_ListOfShape.hxx>
102 #include <TopoDS_Iterator.hxx>
103 #include <TopTools_ListIteratorOfListOfShape.hxx>
104 #include <TopoDS_Solid.hxx>
105 #include <BRepCheck_Shell.hxx>
106 #include <BRepCheck_Status.hxx>
107 #include <TopoDS.hxx>
108 #include <TopoDS_Shell.hxx>
109 #include <TopoDS_Face.hxx>
110 #include <TopExp_Explorer.hxx>
111 #include <StepData_StepModel.hxx>
112 #include <HeaderSection_FileName.hxx>
113
114 #define TRANSLOG
115
116 // ============================================================================
117 // Function: DumpWhatIs   
118 // Purpose: Use it in DEB mode to dump your shapes
119 // ============================================================================
120
121 static void DumpWhatIs(const TopoDS_Shape& S) {
122
123   TopTools_MapOfShape aMapOfShape;
124   aMapOfShape.Add(S);
125   TopTools_ListOfShape aListOfShape;
126   aListOfShape.Append(S);
127   TopTools_ListIteratorOfListOfShape itL(aListOfShape);
128   Standard_Integer nbSolids = 0,
129                    nbShells = 0,
130                    nbOpenShells = 0,
131                    nbFaces = 0, 
132                    nbWires = 0, 
133                    nbEdges = 0, 
134                    nbVertexes = 0,
135                    nbCompounds = 0;
136
137   if (S.ShapeType() == TopAbs_COMPOUND)
138     nbCompounds++;
139
140   for( ; itL.More(); itL.Next() ) {
141     TopoDS_Iterator it( itL.Value() );
142     for ( ; it.More(); it.Next() ) {
143       TopoDS_Shape aSubShape = it.Value();
144       if ( !aMapOfShape.Add(aSubShape) )
145         continue;
146       aListOfShape.Append(aSubShape);
147       if (aSubShape.ShapeType() == TopAbs_COMPOUND)
148         nbCompounds++;
149       if (aSubShape.ShapeType() == TopAbs_SOLID)
150         nbSolids++;
151       if (aSubShape.ShapeType() == TopAbs_SHELL) {
152         if ( !aSubShape.Closed() )
153           nbOpenShells++;
154         nbShells++;
155       }
156       if (aSubShape.ShapeType() == TopAbs_FACE)
157         nbFaces++;
158       if (aSubShape.ShapeType() == TopAbs_WIRE)
159         nbWires++;
160       if (aSubShape.ShapeType() == TopAbs_EDGE)
161         nbEdges++;
162       if (aSubShape.ShapeType() == TopAbs_VERTEX)
163         nbVertexes++;
164     }
165   }
166   #ifdef DEB
167   cout << "//What is?// NB COMPOUNDS: " << nbCompounds << endl;
168   cout << "//What is?// NB SOLIDS: " << nbSolids << endl;
169   cout << "//What is?// NB SHELLS: " << nbShells << endl;
170   cout << "//What is?//    OPEN SHELLS: " << nbOpenShells << endl;
171   cout << "//What is?//    CLOSED SHELLS: " << nbShells - nbOpenShells << endl;
172   cout << "//What is?// NB FACES: " << nbFaces << endl;
173   cout << "//What is?// NB WIRES: " << nbWires << endl;
174   cout << "//What is?// NB EDGES: " << nbEdges << endl;
175   cout << "//What is?// NB VERTEXES: " << nbVertexes << endl;
176   #endif
177 }
178
179 namespace {
180   // Set global var to inform outer methods that current representation item is non-manifold.
181   // The better way is to pass this information via binder or via TopoDS_Shape itself, however,
182   // this is very specific info to do so...
183   Standard_Boolean NM_DETECTED = Standard_False;
184 };
185
186 // ============================================================================
187 // Method  : STEPControl_ActorRead::STEPControl_ActorRead  ()    
188 // Purpose : Empty constructor
189 // ============================================================================
190
191 STEPControl_ActorRead::STEPControl_ActorRead() {}
192
193 // ============================================================================
194 // Method  : STEPControl_ActorRead::Recognize
195 // Purpose : tells if an entity is valid for transfer by this Actor
196 // ============================================================================
197
198 Standard_Boolean  STEPControl_ActorRead::Recognize
199   (const Handle(Standard_Transient)& start)
200 {
201   if (start.IsNull()) return Standard_False;
202
203   if (start->IsKind(STANDARD_TYPE(StepBasic_ProductDefinition))) return Standard_True;
204
205   if (start->IsKind(STANDARD_TYPE(StepRepr_NextAssemblyUsageOccurrence))) return Standard_True;
206
207   TCollection_AsciiString aProdMode = Interface_Static::CVal("read.step.product.mode");
208   if(!aProdMode.IsEqual("ON"))
209     if(start->IsKind(STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation))) return Standard_True;
210
211   DeclareAndCast(StepShape_ShapeRepresentation,sr,start);
212   if (!sr.IsNull()) {
213     Standard_Integer i,nb = sr->NbItems();
214     for (i = 1; i <= nb; i ++) {
215       if (Recognize (sr->ItemsValue(i)) ) return Standard_True;
216     }
217     return Standard_False;
218   }
219
220   if (start->IsKind(STANDARD_TYPE(StepShape_FacetedBrep))) return Standard_True;
221   if (start->IsKind(STANDARD_TYPE(StepShape_BrepWithVoids))) return Standard_True;
222   if (start->IsKind(STANDARD_TYPE(StepShape_ManifoldSolidBrep))) return Standard_True;
223   if (start->IsKind(STANDARD_TYPE(StepShape_ShellBasedSurfaceModel))) return Standard_True;
224   if (start->IsKind(STANDARD_TYPE(StepShape_FacetedBrepAndBrepWithVoids))) return Standard_True;
225   if (start->IsKind(STANDARD_TYPE(StepShape_GeometricSet))) return Standard_True;
226   if (start->IsKind(STANDARD_TYPE(StepRepr_MappedItem))) return Standard_True;
227   if (start->IsKind(STANDARD_TYPE(StepShape_FaceSurface))) return Standard_True;
228   if (start->IsKind(STANDARD_TYPE(StepShape_EdgeBasedWireframeModel))) return Standard_True;
229   if (start->IsKind(STANDARD_TYPE(StepShape_FaceBasedSurfaceModel))) return Standard_True;
230
231
232 //  REPRESENTATION_RELATIONSHIP et consorts : on regarde le contenu ...
233 //  On prend WithTransformation ou non ...
234
235   if (start->IsKind (STANDARD_TYPE(StepRepr_ShapeRepresentationRelationship))) {
236     DeclareAndCast(StepRepr_ShapeRepresentationRelationship,und,start);  
237
238 //  On prend son contenu
239
240     if (Recognize(und->Rep1()) || Recognize(und->Rep2())) return Standard_True;
241     return Standard_False;
242   }
243
244   if (start->IsKind(STANDARD_TYPE(StepShape_ContextDependentShapeRepresentation))) {
245 //    DeclareAndCast(StepShape_ContextDependentShapeRepresentation,CDSR,start);
246 //    return Recognize (CDSR->RepresentationRelation());
247     return Standard_True;
248     //  on fait le pari que, si ce n est pas transferable tel quel,
249     //  des CDSR implicitement references le sont ...
250     //  Sinon cette entite n aurait pas grand sens ...
251   }
252
253   return Standard_False;
254 }
255
256
257 // ============================================================================
258 // Method  : STEPControl_ActorRead::Transfer
259 // Purpose : recursive method that acces to the root entities and start the 
260 //           mapping
261 // ============================================================================
262
263 Handle(Transfer_Binder)  STEPControl_ActorRead::Transfer
264 (const Handle(Standard_Transient)& start,
265  const Handle(Transfer_TransientProcess)& TP)
266 {  
267   // [BEGIN] Get version of preprocessor (to detect I-Deas case) (ssv; 23.11.2010)
268   Handle(StepData_StepModel) aStepModel = Handle(StepData_StepModel)::DownCast ( TP->Model() );
269   Interface_EntityIterator anEntIt = aStepModel->Header();
270   for ( anEntIt.Start(); anEntIt.More(); anEntIt.Next() ) {
271     DeclareAndCast( HeaderSection_FileName, aFileNameEntity, anEntIt.Value() );
272     if ( !aFileNameEntity.IsNull() ) {
273       Handle(TCollection_HAsciiString) aPPVersion = aFileNameEntity->PreprocessorVersion();
274       #ifdef DEB
275       cout << "Preprocessor version detected: " << aPPVersion->ToCString() << endl;
276       #endif
277       Standard_Integer anIDeasResult = aPPVersion->Search("I-DEAS");
278       if (anIDeasResult != -1) {
279         #ifdef DEB
280         cout << "Recognized as I-DEAS STP" << endl;
281         #endif
282         myNMTool.SetIDEASCase(Standard_True);
283       }
284     }
285   }
286   // [END] Get version of preprocessor (to detect I-Deas case) (ssv; 23.11.2010)
287   return TransferShape (start,TP);  
288 }
289
290
291 // ============================================================================
292 // auxiliary function : ApplyTransformation
293 // ============================================================================
294 static void ApplyTransformation (TopoDS_Shape& shape, const gp_Trsf &Trsf) 
295 {
296   if ( Trsf.Form() == gp_Identity ) return;
297   TopLoc_Location theLoc ( Trsf );
298   shape.Move (theLoc);
299 }
300
301
302 // ============================================================================
303 // auxiliary function : FindContext
304 // ============================================================================
305 static Handle(StepRepr_Representation) FindContext (const Handle(Standard_Transient) &start,
306                                                     const Handle(Transfer_TransientProcess) &TP,
307                                                     const Standard_Integer level=10 )
308 {
309   Handle(StepRepr_Representation) rep;
310   const Interface_Graph& graph = TP->Graph();
311   Interface_EntityIterator subs = graph.Sharings(start);
312   for (subs.Start(); subs.More() && rep.IsNull(); subs.Next()) {
313     rep = Handle(StepRepr_Representation)::DownCast(subs.Value());
314     if ( rep.IsNull() && level >0 ) rep = FindContext ( subs.Value(), TP, level-1 );
315   }
316   return rep;
317 }
318
319 //=======================================================================
320 //function : FindShapeReprType
321 //purpose  : Returns integer corresponding to the type of the representation
322 //           as defined in read.step.shape.repr_level parameter
323 //=======================================================================
324
325 static Standard_Integer FindShapeReprType (const Handle(Standard_Transient) &start)
326 {
327   if(start->IsKind(STANDARD_TYPE(StepShape_AdvancedBrepShapeRepresentation)))
328     return 2;
329   if(start->IsKind(STANDARD_TYPE(StepShape_ManifoldSurfaceShapeRepresentation)))
330     return 3;
331   if(start->IsKind(STANDARD_TYPE(StepShape_GeometricallyBoundedSurfaceShapeRepresentation)))
332     return 4;
333   if(start->IsKind(STANDARD_TYPE(StepShape_FacetedBrepShapeRepresentation)))
334     return 5;
335   if(start->IsKind(STANDARD_TYPE(StepShape_EdgeBasedWireframeShapeRepresentation)))
336     return 6;
337   if(start->IsKind(STANDARD_TYPE(StepShape_GeometricallyBoundedWireframeShapeRepresentation)))
338     return 7;
339   return 8;
340 }
341
342 //=======================================================================
343 //function : getListSDR
344 //purpose  : Get SDRs assigned to ShapeAspect, which may potentially
345 //           correspond to hybrid models in AP203 before 1998
346 //=======================================================================
347
348 static void getListSDR(const Handle(StepRepr_ShapeAspect)& sa,
349                        Handle(TColStd_HSequenceOfTransient)& listSDR,
350                        const Handle(Transfer_TransientProcess)& TP)
351 {
352   const Interface_Graph& graph = TP->Graph();
353   
354   // check whether this ShapeAspect is used in G&DT, and if yes, ignore it
355   if(sa->IsKind(STANDARD_TYPE(StepDimTol_DatumFeature))) return;
356   Interface_EntityIterator subs5 = graph.Sharings(sa);
357   for (subs5.Start(); subs5.More(); subs5.Next()) {
358     if(subs5.Value()->IsKind(STANDARD_TYPE(StepDimTol_GeometricTolerance)))
359       return;
360   }
361
362   // reiterate by referred entities and take all SDRs; note that SDRs that
363   // refer to sub-shapes of main SDR will be filtered out further during translation
364   subs5 = graph.Sharings(sa);
365   for (subs5.Start(); subs5.More() ; subs5.Next()) {
366     Handle(StepRepr_PropertyDefinition) propd = 
367       Handle(StepRepr_PropertyDefinition)::DownCast(subs5.Value());
368     if(propd.IsNull()) continue;
369     Interface_EntityIterator subs6 = graph.Sharings(propd);
370     for (subs6.Start(); subs6.More() ; subs6.Next()) {
371       Handle(StepShape_ShapeDefinitionRepresentation) sdr = 
372         Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(subs6.Value());
373       if ( ! sdr.IsNull() )
374         listSDR->Append(sdr);
375     }
376   }
377 }
378
379 //=======================================================================
380 //function : getSDR
381 //purpose  : Find all SDRs related to given PDS
382 //=======================================================================
383
384 static void getSDR(const Handle(StepRepr_ProductDefinitionShape)& PDS,
385                    Handle(TColStd_HSequenceOfTransient)& listSDR,
386                    Handle(TColStd_HSequenceOfTransient)& listSDRAspect,
387                    const Handle(Transfer_TransientProcess)& TP)
388 {
389   // Flag indicating preferred shape representation type, to be chosen if 
390   // several different representations are attached to the same shape
391   Standard_Integer delta = 100;
392   Standard_Integer ICS = Interface_Static::IVal("read.step.shape.repr");
393   Standard_Integer nbSDR0 = listSDR->Length();
394   
395   // Iterate by entities referring PDS
396   const Interface_Graph& graph = TP->Graph();
397   Handle(StepShape_ShapeDefinitionRepresentation) NeedSDR;
398   Interface_EntityIterator subs4 = graph.Sharings(PDS);
399   for (subs4.Start(); subs4.More(); subs4.Next()) {
400
401     // Directly assigned SDR
402     Handle(StepShape_ShapeDefinitionRepresentation) sdr = 
403       Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(subs4.Value());
404     if ( ! sdr.IsNull() ) {
405       Handle(StepRepr_Representation) rep = sdr->UsedRepresentation();
406
407       if ( !rep.IsNull())  {
408         // if specific representation type is preferred, choose the 
409         // representations of the closest type
410         if ( ICS == 1 ) // translate all SDRs
411           listSDR->Append(sdr);
412         else {
413           Standard_Integer iDiff = Abs ( FindShapeReprType(rep) - ICS );
414           // if more suitable representation is found, drop previous if any selected
415           if( iDiff < delta ) {
416             while ( listSDR->Length() > nbSDR0 ) 
417               listSDR->Remove(listSDR->Length());
418             delta = iDiff;
419           }
420           // take all representations of preferred or closest type
421           if ( iDiff <= delta )
422             listSDR->Append(sdr);
423         }
424       }
425       continue;
426     }
427
428     // SDRs assigned via ShapeAspect; may correspond to hybrid model in AP203 before 1998
429     Handle(StepRepr_ShapeAspect) sa = 
430       Handle(StepRepr_ShapeAspect)::DownCast(subs4.Value());
431     if ( ! sa.IsNull() ) {
432       getListSDR(sa,listSDRAspect,TP);
433       continue;
434     }
435   }
436 }
437
438
439 //=======================================================================
440 //function : TransferEntity
441 //purpose  : 
442 //=======================================================================
443  Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Handle(StepBasic_ProductDefinition)& PD,
444                                                                         const Handle(Transfer_TransientProcess)& TP) 
445
446 {
447   Handle(Message_Messenger) sout = TP->Messenger();
448   Handle(TransferBRep_ShapeBinder) shbinder;
449   
450   TopoDS_Compound Cund;
451   TopoDS_Shape Result1;
452   BRep_Builder B;
453   B.MakeCompound (Cund);
454   
455   // Find subcomponents of assembly (NAUO)
456   // and definitions of shape of the current product (SDR)
457   Handle(TColStd_HSequenceOfTransient) listSDR = new TColStd_HSequenceOfTransient;
458   Handle(TColStd_HSequenceOfTransient) listNAUO = new TColStd_HSequenceOfTransient;
459   Handle(TColStd_HSequenceOfTransient) listSDRAspect = new TColStd_HSequenceOfTransient;
460   const Interface_Graph& graph = TP->Graph();
461   Interface_EntityIterator subs3 = graph.Sharings(PD);
462   for (subs3.Start(); subs3.More() ; subs3.Next()) {
463     // PDS is used to find shape definitions attached to this product
464     Handle(StepRepr_ProductDefinitionShape) PDS = 
465       Handle(StepRepr_ProductDefinitionShape)::DownCast(subs3.Value());
466     if ( ! PDS.IsNull() ) {
467       getSDR(PDS,listSDR,listSDRAspect,TP);
468       continue;
469     }
470     // NAUO is used to find sub-assemblies
471     Handle(StepRepr_NextAssemblyUsageOccurrence) NAUO = 
472       Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(subs3.Value());
473     if ( ! NAUO.IsNull() ) {
474       if ( PD == NAUO->RelatingProductDefinition() )
475         listNAUO->Append(NAUO);
476       continue;
477     }
478   }
479   
480   // Flag indicating whether SDRs associated with the product`s main SDR
481   // by SRRs (which correspond to hybrid model representation in AP203 since 1998) 
482   // should be taken into account 
483   Standard_Integer readSRR = Interface_Static::IVal("read.step.shape.relationship");
484   
485   // Flag indicating whether SDRs associated with the product`s main SDR
486   // by SAs (which correspond to hybrid model representation in AP203 before 1998) 
487   // should be taken into account 
488   Standard_Integer readSA = Interface_Static::IVal("read.step.shape.aspect");
489   if ( ! readSA ) 
490     listSDRAspect->Clear();  
491     
492   // remember number of normal SDRs (not those found via ShapeAspect)
493   // and merge both lists in one
494   Standard_Integer nbNotAspect = listSDR->Length();
495   listSDR->Append(listSDRAspect);
496
497   // Flag indicating level of reading assemblies: only structure (3),
498   // structure with shapes of final parts (2), or everything, including shapes
499   // possibly attached directly to intermediate assemblies (1)
500   // Special mode (4) is used to translate shape attached to this product only,
501   // ignoring sub-assemblies if any
502   Standard_Integer readAssembly = Interface_Static::IVal("read.step.assembly.level");
503   if ( readAssembly ==3 || ( readAssembly ==2 && listNAUO->Length() >0 ) ) 
504     listSDR->Clear();
505   else if ( readAssembly == 4 )
506     listNAUO->Clear();
507   
508   Standard_Integer nbEnt = listSDR->Length() + listNAUO->Length();
509   if ( nbEnt <=0 )
510     return shbinder;
511
512   // common progress indicator for translation of own shapes and sub-assemblies
513   Message_ProgressSentry PS ( TP->GetProgress(), "Part", 0, nbEnt, 1 );
514   Standard_Integer nbComponents=0, nbShapes=0;
515
516   // translate sub-assemblies
517   for ( Standard_Integer nbNauo =1; nbNauo <= listNAUO->Length() && PS.More(); nbNauo++, PS.Next()) {
518     Handle(StepRepr_NextAssemblyUsageOccurrence) NAUO = 
519       Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(listNAUO->Value(nbNauo));
520       
521 #ifdef TRANSLOG
522     if (TP->TraceLevel() > 1) 
523       sout<<" -- Actor : Ent.n0 "<<TP->Model()->Number(PD)<<" -> Shared Ent.no"<<TP->Model()->Number(NAUO)<<endl;
524 #endif
525     Handle(Transfer_Binder) binder;
526     if (!TP->IsBound(NAUO)) binder = TransferEntity(NAUO,TP);
527     else                        binder = TP->Find(NAUO);
528
529     TopoDS_Shape theResult = TransferBRep::ShapeResult (binder);
530     if (!theResult.IsNull()) {
531       Result1 = theResult;
532       // [BEGIN] ssv: OCCT#22436: extra compound in NMSSR case
533       if (NM_DETECTED && Result1.ShapeType() == TopAbs_COMPOUND)
534       {
535         TopoDS_Iterator it(Result1);
536         for ( ; it.More(); it.Next() ) 
537         {
538           TopoDS_Shape aSubShape = it.Value();
539           B.Add(Cund, aSubShape);
540         }
541       }
542       else
543         B.Add(Cund, theResult);
544       // [END] ssv: OCCT#22436: extra compound in NMSSR case
545       nbComponents++;
546     }
547   }
548
549   // translate shapes assigned directly
550   for(Standard_Integer i=1; i <= listSDR->Length() && PS.More(); i++, PS.Next()) {
551     Handle(StepShape_ShapeDefinitionRepresentation) sdr = 
552       Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(listSDR->Value(i));
553     Handle(StepShape_ShapeRepresentation) rep =  Handle(StepShape_ShapeRepresentation)::DownCast(sdr->UsedRepresentation());
554     if ( rep.IsNull() )
555       continue;
556
557     // translate SDR representation
558     Standard_Boolean isBound = Standard_True;
559     Handle(Transfer_Binder) binder = TP->Find(rep);
560     if (binder.IsNull())
561       binder = TransferEntity(rep,TP,isBound);
562
563     // if SDR is obtained from ShapeAspect and representation items have already been tramnslated,
564     // this means that that ShapeAspect is used to refer to sub-shape of the main shape
565     // (e.g. for validation properties), and we do not need to translate it actually;
566     // otherwise it is considered as part of hybrid representation in AP203 before 1998
567     if ( i > nbNotAspect && isBound)
568         continue;
569
570     // record shape resulting from translation
571     TopoDS_Shape theResult;
572     if ( ! binder.IsNull() ) {
573       theResult = TransferBRep::ShapeResult (binder);
574       if (!theResult.IsNull()) {
575         Result1 = theResult;
576         // [BEGIN] ssv: OCCT#22436: extra compound in NMSSR case
577         if (NM_DETECTED && Result1.ShapeType() == TopAbs_COMPOUND)
578         {
579           TopoDS_Iterator it(Result1);
580           for ( ; it.More(); it.Next() ) 
581           {
582             TopoDS_Shape aSubShape = it.Value();
583             B.Add(Cund, aSubShape);
584           }
585         }
586         else
587           B.Add(Cund, theResult);
588         // [END] ssv: OCCT#22436: extra compound in NMSSR case
589         nbShapes++;
590       }
591     }
592     
593     // translate possible shapes related by SRRs, which corresponds to
594     // way of writing hybrid models in AP203 since 1998, and AP209
595     // Note that both AP203 and AP209 allow main representation to be non-empty
596     if ( readSRR && /*theResult.IsNull() &&*/ i <= nbNotAspect) {
597       Interface_EntityIterator subs1 = graph.Sharings(rep);
598       Handle(Standard_Type) tSRR = STANDARD_TYPE(StepRepr_ShapeRepresentationRelationship);
599       for (subs1.Start(); subs1.More(); subs1.Next()) {
600         Handle(Standard_Transient) anitem = subs1.Value();
601         if ( anitem->DynamicType() != tSRR ) continue;
602         Handle(StepRepr_ShapeRepresentationRelationship) SRR =
603           Handle(StepRepr_ShapeRepresentationRelationship)::DownCast(anitem);
604         Standard_Integer nbrep = ( rep == SRR->Rep1() ? 2 : 1 );
605         binder = TransferEntity(SRR, TP, nbrep);
606         if ( ! binder.IsNull() ) {
607           theResult = TransferBRep::ShapeResult (binder);
608           Result1 = theResult;
609           B.Add(Cund, theResult);
610           nbShapes++;
611         }
612       }
613     }
614   }
615
616   // make a warning if both own shape and sub-assemblies are present
617   if ( nbShapes >0 && nbComponents > 0 )
618     TP->AddWarning ( PD, "Product has both sub-assemblies and directly assigned shape" );
619
620   // if only single shape is read, add it as it is; otherwise add compound
621   if( nbShapes == 1 && nbComponents == 0 )
622     shbinder = new TransferBRep_ShapeBinder (Result1);
623   else
624     shbinder = new TransferBRep_ShapeBinder (Cund);
625
626   //TP->Unbind( PD ); //:j3: unbind start (let it be bound by TransferProcess)
627   TP->Bind(PD, shbinder);
628   return shbinder;  
629 }
630
631 //=======================================================================
632 //function : TransferEntity
633 //purpose  : 
634 //=======================================================================
635
636 Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Handle(StepRepr_NextAssemblyUsageOccurrence)& NAUO ,
637                                                                        const Handle(Transfer_TransientProcess)& TP)
638 {
639  Handle(TransferBRep_ShapeBinder) shbinder;
640   Handle(StepBasic_ProductDefinition) PD;
641   const Interface_Graph& graph = TP->Graph();
642   gp_Trsf Trsf;
643   Standard_Boolean iatrsf=Standard_False, SRRReversed=Standard_False, IsDepend=Standard_False;
644   Handle(StepRepr_ShapeRepresentationRelationship) SRR;
645   Interface_EntityIterator subs1 = graph.Sharings(NAUO);
646   for (subs1.Start(); subs1.More(); subs1.Next()) {
647     Handle(StepRepr_ProductDefinitionShape) PDS = 
648       Handle(StepRepr_ProductDefinitionShape)::DownCast(subs1.Value());
649     if(PDS.IsNull()) continue;
650     //IsPDS=Standard_True;
651     Interface_EntityIterator subs2 = graph.Sharings(PDS);
652     for (subs2.Start(); subs2.More(); subs2.Next()) {
653       Handle(StepShape_ContextDependentShapeRepresentation) CDSR = 
654         Handle(StepShape_ContextDependentShapeRepresentation)::DownCast(subs2.Value());
655       if (CDSR.IsNull()) continue;
656       IsDepend=Standard_True;
657       Handle(StepRepr_RepresentationRelationship) RR = CDSR->RepresentationRelation();
658       if (RR.IsNull()) continue;
659       SRRReversed = STEPConstruct_Assembly::CheckSRRReversesNAUO ( TP->Model(), CDSR );
660       Handle(StepRepr_Representation) rep = ( SRRReversed ? RR->Rep2() : RR->Rep1() );
661       iatrsf = ComputeSRRWT ( RR, TP, Trsf );
662       // find real ProductDefinition used rep
663       Interface_EntityIterator subs3 = TP->Graph().Sharings(rep);
664       for (subs3.Start(); subs3.More(); subs3.Next()) {
665         if ( subs3.Value()->IsKind(STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation))) {
666           DeclareAndCast(StepShape_ShapeDefinitionRepresentation,SDR,subs3.Value());
667           Handle(StepRepr_ProductDefinitionShape) PDS1 = 
668             Handle(StepRepr_ProductDefinitionShape)::DownCast(SDR->Definition().PropertyDefinition());
669           //Handle(StepRepr_PropertyDefinition) PD = SDR->Definition().PropertyDefinition();
670           if(PDS1.IsNull()) continue;
671           Interface_EntityIterator subs4 = graph.Shareds(PDS1);
672           for (subs4.Start(); subs4.More(); subs4.Next()) {
673             Handle(StepBasic_ProductDefinition) PD1 = 
674               Handle(StepBasic_ProductDefinition)::DownCast(subs4.Value());
675             if(PD1.IsNull()) continue;
676             PD=PD1;
677           }
678         }
679         else if(subs3.Value()->IsKind(STANDARD_TYPE(StepRepr_ShapeRepresentationRelationship))) {
680           SRR = Handle(StepRepr_ShapeRepresentationRelationship)::DownCast(subs3.Value());
681         }
682       }
683     }
684   }
685   
686   Handle(Transfer_Binder) binder;
687   TopoDS_Shape theResult;
688   shbinder.Nullify();
689   
690   if(IsDepend) {
691     
692     if(!PD.IsNull()) {
693       binder = TP->Find(PD);
694       if ( binder.IsNull() ) binder = TransferEntity(PD,TP);
695       theResult = TransferBRep::ShapeResult(binder);
696       if (!theResult.IsNull()) {
697         if (iatrsf) {
698           if ( SRRReversed ) ApplyTransformation ( theResult, Trsf.Inverted() );
699           else               ApplyTransformation ( theResult, Trsf );
700         }
701         shbinder = new TransferBRep_ShapeBinder (theResult);
702       }
703     }
704     
705     if ( theResult.IsNull() && !SRR.IsNull() ) {
706       binder = TP->Find(SRR);
707       if ( binder.IsNull() ) {
708         binder = TransferEntity(SRR,TP);
709         theResult = TransferBRep::ShapeResult (binder);
710         if (!theResult.IsNull())
711           shbinder = new TransferBRep_ShapeBinder (theResult);
712       }
713     }
714     
715   }
716   TP->Bind(NAUO, shbinder);
717   return shbinder;
718   
719 }
720 //=======================================================================
721 //function : TransferEntity
722 //purpose  : 
723 //=======================================================================
724
725 Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Handle(StepShape_ShapeRepresentation)& sr,
726                                                                        const Handle(Transfer_TransientProcess)& TP,
727                                                                        Standard_Boolean& isBound)
728 {
729   NM_DETECTED = Standard_False;
730   Handle(TransferBRep_ShapeBinder) shbinder;
731   if(!Recognize(sr))
732     return shbinder;
733   isBound = Standard_False;
734   Standard_Integer i,nb = sr->NbItems();
735   // Used in XSAlgo::AlgoContainer()->ProcessShape (ssv; 13.11.2010)
736   Standard_Integer nbTPitems = TP->NbMapped();
737   Handle(Message_Messenger) sout = TP->Messenger();
738   #ifdef TRANSLOG
739   if (TP->TraceLevel() > 2) 
740     sout<<" -- Actor : case  ShapeRepr. NbItems="<<nb<<endl;
741   #endif
742   
743     // Compute unit convertion factors and geometric Accuracy
744   Handle(StepRepr_Representation) oldSRContext = mySRContext; //:S4136
745   PrepareUnits(sr,TP);
746   
747   BRep_Builder B;
748   TopoDS_Compound comp;
749   B.MakeCompound (comp);
750   TopoDS_Shape OneResult;
751   Standard_Integer nsh = 0;
752   Message_ProgressSentry PS ( TP->GetProgress(), "Sub-assembly", 0, nb, 1 );
753
754   // [BEGIN] Proceed with non-manifold topology (ssv; 12.11.2010)
755   Standard_Boolean isNMMode = Interface_Static::IVal("read.step.nonmanifold");
756   Standard_Boolean isManifold = Standard_True;
757   if ( isNMMode && sr->IsKind(STANDARD_TYPE(StepShape_NonManifoldSurfaceShapeRepresentation)) ) {
758     isManifold = Standard_False;
759     NM_DETECTED = Standard_True;
760     #ifdef DEB
761     Standard_Integer NMSSRItemsLen = sr->Items()->Length();
762     cout << "NMSSR with " << NMSSRItemsLen << " items detected" << endl;
763     #endif
764   } 
765   // Special processing for I-DEAS STP case (ssv; 15.11.2010)
766   else {
767     Standard_Integer isIDeasMode = Interface_Static::IVal("read.step.ideas");
768     if (isNMMode && myNMTool.IsIDEASCase() && isIDeasMode) {
769       isManifold = Standard_False;
770       NM_DETECTED = Standard_True;
771       #ifdef DEB
772       cout << "I-DEAS post processing for non-manifold topology ENABLED" << endl;
773       #endif
774     }
775     #ifdef DEB
776     else if ( myNMTool.IsIDEASCase() )
777       cout << "I-DEAS post processing for non-manifold topology DISABLED" << endl;
778     #endif
779   }
780   myNMTool.CleanUp();
781   // Don't use NM tool in manifold cases (ssv; 24.11.2010)
782   myNMTool.SetActive(!isManifold && isNMMode);
783   // [END] Proceed with non-manifold topology (ssv; 12.11.2010)
784
785   for (i = 1; i <= nb && PS.More(); i ++,PS.Next()) {
786   //for (i = 1; i <= nb ; i ++) {
787     #ifdef TRANSLOG
788     if (TP->TraceLevel() > 2) 
789       sout<<" -- Actor, shape_representation.item n0. "<<i<<endl;
790     #endif
791     Handle(StepRepr_RepresentationItem) anitem = sr->ItemsValue(i);
792     Handle(Transfer_Binder) binder;
793     if (!TP->IsBound(anitem)) {
794       binder = TransferShape(anitem, TP, isManifold);
795     }
796     else {
797       isBound = Standard_True;
798       binder = TP->Find(anitem);
799     }
800     TopoDS_Shape theResult = TransferBRep::ShapeResult (binder);
801     if (!theResult.IsNull()) {
802       OneResult = theResult;
803       B.Add(comp, theResult);
804       nsh ++;
805     }
806   }
807   
808   // [BEGIN] Proceed with non-manifold topology (ssv; 12.11.2010)
809   if (!isManifold) {
810     Handle(Standard_Transient) info;
811     // IMPORTANT: any fixing on non-manifold topology must be done after the shape is transferred from STEP
812     TopoDS_Shape fixedResult = 
813       XSAlgo::AlgoContainer()->ProcessShape( comp, myPrecision, myMaxTol,
814                                              "read.step.resource.name", 
815                                              "read.step.sequence", info,
816                                              TP->GetProgress() );
817     XSAlgo::AlgoContainer()->MergeTransferInfo(TP, info, nbTPitems);
818
819     BRep_Builder brepBuilder;
820
821     // [BEGIN] Try to close OPEN Shells in I-DEAS case (ssv; 17.11.2010)
822     if ( myNMTool.IsIDEASCase() ) {
823             
824       // ==========================================================
825       //  For each Shell (always OPEN in I-DEAS case) find all 
826       //  the possibilities to close it with adjacent non-manifold
827       //  Shells which are stored separately in I-DEAS-like STP
828       // ==========================================================
829
830       TopTools_IndexedDataMapOfShapeListOfShape shellClosingsMap;
831       // Find possible closings for each shell
832       this->computeIDEASClosings(comp, shellClosingsMap);
833
834       // Make compound to store closed Shells
835       TopoDS_Compound compWithClosings;
836       brepBuilder.MakeCompound(compWithClosings);
837
838       // Attempt to close Shells one-by-one
839       for (Standard_Integer i = 1; i <= shellClosingsMap.Extent(); i++) {
840         TopoDS_Shell adjustedShell = this->closeIDEASShell( TopoDS::Shell( shellClosingsMap.FindKey(i) ),
841                                                             shellClosingsMap.FindFromIndex(i) );     
842         brepBuilder.Add(compWithClosings, adjustedShell);
843       }
844       // Put not suspected open Shells as they are (updated 23.11.2010)
845       TopExp_Explorer allShellsExp(comp, TopAbs_SHELL);
846       for ( ; allShellsExp.More(); allShellsExp.Next() ) {
847         TopoDS_Shape aCurrentShell = allShellsExp.Current();
848         if ( !myNMTool.IsPureNMShell(aCurrentShell) && !shellClosingsMap.Contains(aCurrentShell) )
849           brepBuilder.Add(compWithClosings, aCurrentShell);
850       }
851   
852
853       comp = compWithClosings;
854  
855     }
856     // [END] Try to close OPEN Shells in I-DEAS case (ssv; 17.11.2010)
857
858     // [BEGIN] Reconstruct Solids from Closed Shells (ssv; 15.11.2010)
859     TopoDS_Compound reconstComp;
860     brepBuilder.MakeCompound(reconstComp);
861     
862     TopoDS_Iterator it(comp);
863     for ( ; it.More(); it.Next() ) {
864       TopoDS_Shape aSubShape = it.Value();
865       if ( aSubShape.ShapeType() == TopAbs_SHELL && aSubShape.Closed() ) {
866         TopoDS_Solid nextSolid;
867         brepBuilder.MakeSolid(nextSolid);
868         brepBuilder.Add(nextSolid, aSubShape);
869         brepBuilder.Add(reconstComp, nextSolid);
870       } 
871       else if (aSubShape.ShapeType() == TopAbs_SHELL)
872         brepBuilder.Add(reconstComp, aSubShape);
873     }
874
875     comp = reconstComp;
876     // [END] Reconstruct Solids from Closed Shells (ssv; 15.11.2010)
877   }
878
879   // Bind the resulting shape
880   if      (nsh == 0) shbinder.Nullify();
881   else if (nsh == 1) shbinder = new TransferBRep_ShapeBinder (OneResult);
882   else               shbinder = new TransferBRep_ShapeBinder (comp);
883   PrepareUnits ( oldSRContext, TP ); //:S4136
884   TP->Bind(sr, shbinder);
885
886   
887   #ifdef DEB
888   DumpWhatIs(comp);
889   #endif
890   
891   return shbinder;
892   
893 }
894 //=======================================================================
895 //function : TransferEntity
896 //purpose  : 
897 //=======================================================================
898
899 Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Handle(StepShape_ContextDependentShapeRepresentation)& CDSR,
900                                                                        const Handle(Transfer_TransientProcess)& TP)
901 {
902   Handle(TransferBRep_ShapeBinder) shbinder;
903   //:j2: treat SRRs here in order to compare them with NAUO
904   Handle(StepRepr_ShapeRepresentationRelationship) SRR = CDSR->RepresentationRelation();
905   //DeclareAndCast(StepRepr_RepresentationRelationship,SRR,CDSR->RepresentationRelation());
906   if ( SRR.IsNull() ) return shbinder;
907   
908   Standard_Boolean SRRReversed = STEPConstruct_Assembly::CheckSRRReversesNAUO ( TP->Model(), CDSR );
909   Handle(StepRepr_Representation) rep1 = ( SRRReversed ? SRR->Rep2() : SRR->Rep1() );
910   Handle(StepShape_ShapeRepresentation) rep = Handle(StepShape_ShapeRepresentation)::DownCast(rep1);
911
912   if ( SRRReversed ) 
913     TP->AddWarning ( SRR, "SRR reverses relation defined by NAUO; NAUO definition is taken" );
914   
915   TopoDS_Shape theResult;
916   
917   gp_Trsf Trsf;
918   Standard_Boolean iatrsf = ComputeSRRWT ( SRR, TP, Trsf );
919   /* Delete this part does not work gka
920   // use SDR for reading rep in order to handle subassemblies
921   Interface_EntityIterator subs = TP->Graph().Sharings(rep);
922   Standard_Integer nbitem=0;
923   for (subs.Start(); subs.More(); subs.Next()) nbitem++;
924   Message_ProgressSentry PS ( TP->GetProgress(), "Shape", 0, nbitem, 1 );
925
926   for (subs.Start(); subs.More() && PS.More() ; subs.Next(),PS.Next()) {
927     if ( subs.Value()->IsKind(STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation))) {
928       DeclareAndCast(StepShape_ShapeDefinitionRepresentation,SDR,subs.Value());
929 #ifdef TRANSLOG
930       if (TP->TraceLevel() > 1) 
931         sout<<" -- Actor : Ent.n0 "<<TP->Model()->Number(CDSR)<<" -> Sharing Ent.no"<<TP->Model()->Number(SDR)<<endl;
932 #endif
933       
934       binder = TP->Find ( SDR );
935       if ( binder.IsNull() ) binder = TransferEntity(SDR,TP);
936       theResult = TransferBRep::ShapeResult (binder);
937       break;
938     }
939   }*/
940   //if ( theResult.IsNull() && ! subs.More() ) {
941   Handle(Transfer_Binder) binder;
942   Standard_Boolean isBound = Standard_False;
943     if (!TP->IsBound(rep)) binder = TransferEntity(rep,TP,isBound);
944     else binder = TP->Find(rep);
945     theResult = TransferBRep::ShapeResult (binder);
946   //}
947       
948   if ( ! theResult.IsNull() ) {
949     if ( iatrsf ) {
950       if ( SRRReversed ) ApplyTransformation ( theResult, Trsf.Inverted() );
951       else               ApplyTransformation ( theResult, Trsf );
952     }
953     shbinder = new TransferBRep_ShapeBinder (theResult);
954   }
955   else shbinder.Nullify();
956   TP->Bind(CDSR, shbinder);
957   return shbinder;
958   
959 }
960 //=======================================================================
961 //function : TransferEntity
962 //purpose  : 
963 //=======================================================================
964
965 Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Handle(StepRepr_ShapeRepresentationRelationship)& und,
966                                                                        const Handle(Transfer_TransientProcess)& TP,
967                                                                        const Standard_Integer nbrep)
968 {
969   //  REPRESENTATION_RELATIONSHIP et la famille
970   Handle(TransferBRep_ShapeBinder) shbinder;
971   
972   if (und.IsNull()) return shbinder;
973   
974   //  On prend son contenu : Rep1 ou Rep2 , that is the question
975   //    on prend les 2. Mais quoi faire des axes
976   
977   TopoDS_Compound Cund;
978   TopoDS_Shape OneResult;
979   BRep_Builder B;
980   B.MakeCompound (Cund);
981   Standard_Integer nsh = 0;
982   
983   gp_Trsf Trsf;
984   Standard_Boolean iatrsf = ComputeSRRWT ( und, TP, Trsf );
985   
986   //    Transfert : que faut-il prendre au juste ?
987   
988   for (Standard_Integer i = 1; i <= 2; i ++) {
989     if(nbrep && nbrep != i)
990       continue;
991     Handle(StepRepr_Representation) anitemt;
992     if (i == 1) anitemt = und->Rep1();
993     if (i == 2) anitemt = und->Rep2();
994     Handle(StepShape_ShapeRepresentation) anitem = Handle(StepShape_ShapeRepresentation)::DownCast(anitemt);
995     Handle(Transfer_Binder) binder;
996     Standard_Boolean isBound = Standard_False;
997     if (!TP->IsBound(anitem)) binder = TransferEntity(anitem,TP,isBound);//TP->Transferring(anitem);
998     else                        binder = TP->Find(anitem);
999     TopoDS_Shape theResult = TransferBRep::ShapeResult (binder);
1000     if (!theResult.IsNull()) {
1001       OneResult = theResult;
1002       B.Add(Cund, theResult);
1003       nsh ++;
1004     }
1005   }
1006   
1007   //   La Transformation : selon les cas
1008   
1009   //    Appliquer la transformation
1010   
1011   if (iatrsf) {
1012     if      (nsh == 1) ApplyTransformation ( OneResult, Trsf );
1013     else if (nsh >  1) ApplyTransformation ( Cund, Trsf );
1014   }
1015   if      (nsh == 0) shbinder.Nullify();
1016   else if (nsh == 1) shbinder = new TransferBRep_ShapeBinder (OneResult);
1017   else               shbinder = new TransferBRep_ShapeBinder (Cund);
1018   TP->Bind(und, shbinder);
1019   return shbinder;
1020   
1021 }
1022
1023 //=======================================================================
1024 //function : OldWay
1025 //purpose  : 
1026 //=======================================================================
1027 //=======================================================================
1028 //function : IsNeedRepresentation
1029 //purpose  : 
1030 //=======================================================================
1031
1032 static Standard_Boolean IsNeedRepresentation(const Handle(StepRepr_ShapeAspect)& sa,
1033                                              const Handle(StepRepr_Representation)&repA ,
1034                                              const Handle(Transfer_TransientProcess)& TP)
1035 {
1036   Standard_Boolean IsSDRaspect=Standard_True;
1037   Handle(StepRepr_ProductDefinitionShape) PDSA = sa->OfShape();
1038   const Interface_Graph& graph = TP->Graph();
1039   Interface_EntityIterator subs7 = graph.Sharings(PDSA);
1040   for (subs7.Start(); ! PDSA.IsNull() && subs7.More(); subs7.Next()) {
1041     Handle(StepShape_ShapeDefinitionRepresentation) sdrA = 
1042       Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(subs7.Value());
1043     if ( sdrA.IsNull() ) continue;
1044     // abv 23 Feb 00: use iterator to take into account AP203 hybrid models
1045     Interface_EntityIterator subs8 = graph.Shareds(sdrA);
1046     for (subs8.Start(); subs8.More(); subs8.Next()) {
1047       Handle(StepRepr_Representation) rep2 = 
1048         Handle(StepRepr_Representation)::DownCast ( subs8.Value() );
1049       if ( rep2.IsNull() ) {
1050         Handle(StepRepr_ShapeRepresentationRelationship) SRR = 
1051           Handle(StepRepr_ShapeRepresentationRelationship)::DownCast ( subs8.Value() );
1052         if ( SRR.IsNull() ) continue;
1053         rep2 = ( sdrA->UsedRepresentation() == SRR->Rep1() ? SRR->Rep2() : SRR->Rep1() );
1054       }
1055       Standard_Integer i, j; // svv Jan 11 2000 : porting on DEC
1056       for ( i=1; i <= repA->NbItems(); i++ ) {
1057         Handle(StepRepr_RepresentationItem) it = repA->ItemsValue(i);
1058         for ( j=1; j <= rep2->NbItems(); j++ )
1059           if ( it == rep2->ItemsValue(j) ) break;
1060         if ( j > rep2->NbItems() ) break;
1061       }
1062       if ( i > repA->NbItems() ) IsSDRaspect=Standard_False;
1063     }
1064   }
1065   return IsSDRaspect;
1066 }
1067 //=======================================================================
1068 //function : OldWay
1069 //purpose  : 
1070 //=======================================================================
1071
1072 Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::OldWay(const Handle(Standard_Transient)& start,
1073                                                                const Handle(Transfer_TransientProcess)& TP)
1074 {
1075   Handle(Message_Messenger) sout = TP->Messenger();
1076   const Interface_Graph& graph = TP->Graph();
1077   Handle(TransferBRep_ShapeBinder) shbinder;
1078   DeclareAndCast(StepShape_ShapeDefinitionRepresentation,sdr,start);
1079   Handle(StepRepr_Representation) rep = sdr->UsedRepresentation();
1080
1081   // abv 7 Oct 99: TRJ2: skip SDRs used only for defining SHAPE_ASPECT (validation properties)
1082   // BUT ONLY if they have representation duplicated with other SDR,
1083   // (SHAPE_ASPECT also used by some systems to define geometry)
1084   Handle(StepRepr_PropertyDefinition) PD = sdr->Definition().PropertyDefinition();
1085   if ( ! PD.IsNull() ) {
1086     Handle(StepRepr_ShapeAspect) SA = PD->Definition().ShapeAspect();
1087     if ( ! SA.IsNull() ) {
1088       if(!IsNeedRepresentation(SA,rep,TP))
1089         return shbinder;
1090     }
1091   }
1092     
1093 #ifdef TRANSLOG
1094   if (TP->TraceLevel() > 2) 
1095     sout<<" -- Actor : case  shape_definition_representation."<<endl;
1096 #endif
1097   Handle(Transfer_Binder) binder = TP->Find(rep);
1098   if (binder.IsNull()) binder = TP->Transferring(rep);
1099 //:j2    if (!binder.IsNull()) return binder;
1100
1101 //    SDR designant des CDSR (lien implicite, via la UsedRepr)
1102
1103   TopoDS_Compound Cund;
1104   TopoDS_Shape OneResult;
1105   BRep_Builder B;
1106   B.MakeCompound (Cund);
1107   Standard_Integer nsh = 0;
1108
1109   //:j2
1110   shbinder = new TransferBRep_ShapeBinder;
1111   TP->Bind ( start, shbinder ); //:j3 abv 23 Oct 98: rp1sd.stp: bind something to protect against loops
1112   if (!binder.IsNull()) {
1113     TopoDS_Shape theResult = TransferBRep::ShapeResult (binder);
1114     if (!theResult.IsNull()) {
1115       OneResult = theResult;
1116       B.Add(Cund, theResult);
1117       nsh ++;
1118       shbinder->SetResult (theResult);
1119     }
1120   }
1121
1122   // process subcomponents of assembly (CDSR) and hybrid models (SRR)
1123   Interface_EntityIterator subs = graph.Shareds(start);
1124   Handle(Standard_Type) tCDSR = STANDARD_TYPE(StepShape_ContextDependentShapeRepresentation);
1125   Handle(Standard_Type) tSRR = STANDARD_TYPE(StepRepr_ShapeRepresentationRelationship);
1126   Standard_Integer nbitem=0;
1127   for (subs.Start();subs.More();subs.Next()) nbitem++;
1128   Message_ProgressSentry PS ( TP->GetProgress(), "Sub", 0, nbitem, 1 );
1129   for (subs.Start(); subs.More() && PS.More(); subs.Next() ,PS.Next()) {
1130     Handle(Standard_Transient) anitem = subs.Value();
1131     if ( anitem->DynamicType() != tCDSR && anitem->DynamicType() != tSRR ) continue;
1132 //      DeclareAndCast(StepShape_ContextDependentShapeRepresentation,anitem,subs.Value());
1133 //      if (anitem.IsNull()) continue;
1134 #ifdef TRANSLOG
1135     if (TP->TraceLevel() > 1) 
1136       sout<<" -- Actor : Ent.n0 "<<TP->Model()->Number(start)<<" -> Shared Ent.no"<<TP->Model()->Number(anitem)<<endl;
1137 #endif
1138
1139     if (!TP->IsBound(anitem)) binder = TP->Transferring(anitem);
1140     else                        binder = TP->Find(anitem);
1141     TopoDS_Shape theResult = TransferBRep::ShapeResult (binder);
1142     if (!theResult.IsNull()) {
1143       OneResult = theResult;
1144       B.Add(Cund, theResult);
1145       nsh += 2; //abv 11.10.00: 2 instead of 1 in order to keep assembly structure
1146     }
1147   }
1148
1149   if      (nsh == 0) shbinder = new TransferBRep_ShapeBinder (Cund);//shbinder.Nullify();
1150   else if (nsh == 1) shbinder = new TransferBRep_ShapeBinder (OneResult);
1151   else               shbinder = new TransferBRep_ShapeBinder (Cund);
1152   TP->Unbind( start ); //:j3: unbind start (let it be bound by TransferProcess)
1153   return shbinder;
1154 }
1155
1156 //=======================================================================
1157 //function : TransferEntity
1158 //purpose  : 
1159 //=======================================================================
1160
1161 Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Handle(StepGeom_GeometricRepresentationItem)& start,
1162                                                                        const Handle(Transfer_TransientProcess)& TP,
1163                                                                        const Standard_Boolean isManifold)
1164 {
1165   Handle(Message_Messenger) sout = TP->Messenger();
1166   Handle(TransferBRep_ShapeBinder) shbinder;
1167   Standard_Boolean found = Standard_False;
1168   StepToTopoDS_Builder myShapeBuilder;
1169   TopoDS_Shape mappedShape;
1170   Standard_Integer nbTPitems = TP->NbMapped();
1171 #ifdef TRANSLOG
1172   OSD_Timer chrono;
1173   if (TP->TraceLevel() > 2) 
1174     sout << "Begin transfer STEP -> CASCADE, Type "
1175          << start->DynamicType()->Name() << endl;
1176   chrono.Start();
1177 #endif
1178   
1179   //:S4136
1180   Handle(StepRepr_Representation) oldSRContext = mySRContext;
1181   if ( mySRContext.IsNull() ) { // if no context, try to find it (ex: r0701_ug.stp #4790)
1182     Handle(StepRepr_Representation) context = FindContext ( start, TP );
1183     if ( context.IsNull() ) {
1184       TP->AddWarning ( start, "Entity with no unit context; default units taken" );
1185       ResetUnits();
1186     }
1187     else PrepareUnits ( context, TP );
1188   }
1189   myShapeBuilder.SetPrecision(myPrecision);
1190   myShapeBuilder.SetMaxTol(myMaxTol);
1191
1192   // Start progress scope (no need to check if progress exists -- it is safe)
1193   Message_ProgressSentry aPSentry(TP->GetProgress(), "Transfer stage", 0, 2, 1);
1194
1195   try {
1196     OCC_CATCH_SIGNALS
1197   if (start->IsKind(STANDARD_TYPE(StepShape_FacetedBrep))) {
1198     myShapeBuilder.Init(GetCasted(StepShape_FacetedBrep, start), TP);
1199     found = Standard_True;
1200   } 
1201   else if (start->IsKind(STANDARD_TYPE(StepShape_BrepWithVoids))) {
1202     myShapeBuilder.Init(GetCasted(StepShape_BrepWithVoids, start), TP);
1203     found = Standard_True;
1204   } 
1205   else if (start->IsKind(STANDARD_TYPE(StepShape_ManifoldSolidBrep))) {
1206     myShapeBuilder.Init(GetCasted(StepShape_ManifoldSolidBrep, start), TP);
1207     found = Standard_True;
1208   } 
1209   else if (start->IsKind(STANDARD_TYPE(StepShape_ShellBasedSurfaceModel))) {
1210     myShapeBuilder.Init(GetCasted(StepShape_ShellBasedSurfaceModel, start), TP, myNMTool);
1211     found = Standard_True;
1212   } 
1213   else if (start->IsKind(STANDARD_TYPE(StepShape_FacetedBrepAndBrepWithVoids))) {
1214     myShapeBuilder.Init(GetCasted(StepShape_FacetedBrepAndBrepWithVoids, start), TP);
1215     found = Standard_True;
1216   } 
1217   else if (start->IsKind(STANDARD_TYPE(StepShape_GeometricSet))) {
1218     myShapeBuilder.Init(GetCasted(StepShape_GeometricSet, start), TP);
1219     found = Standard_True;
1220   }
1221   else if (start->IsKind(STANDARD_TYPE(StepShape_EdgeBasedWireframeModel))) {
1222     myShapeBuilder.Init(GetCasted(StepShape_EdgeBasedWireframeModel, start), TP);
1223     found = Standard_True;
1224   }
1225   else if (start->IsKind(STANDARD_TYPE(StepShape_FaceBasedSurfaceModel))) {
1226     myShapeBuilder.Init(GetCasted(StepShape_FaceBasedSurfaceModel, start), TP);
1227     found = Standard_True;
1228   }
1229 }
1230   catch(Standard_Failure) {
1231     TP->AddFail(start,"Exeption is raised. Entity was not translated.");
1232     TP->Bind(start, shbinder);
1233     return shbinder;
1234   }
1235
1236   aPSentry.Next();
1237   
1238   if (found && myShapeBuilder.IsDone()) {
1239     mappedShape = myShapeBuilder.Value();
1240     // Apply ShapeFix (on manifold shapes only. Non-manifold topology is processed separately: ssv; 13.11.2010)
1241     if (isManifold) {
1242       Handle(Standard_Transient) info;
1243       mappedShape = 
1244         XSAlgo::AlgoContainer()->ProcessShape( mappedShape, myPrecision, myMaxTol,
1245                                                "read.step.resource.name", 
1246                                                "read.step.sequence", info,
1247                                                TP->GetProgress() );
1248       XSAlgo::AlgoContainer()->MergeTransferInfo(TP, info, nbTPitems);
1249     }
1250   }
1251   found = !mappedShape.IsNull();
1252   if (found && shbinder.IsNull()) shbinder = new TransferBRep_ShapeBinder (mappedShape);
1253 #ifdef TRANSLOG
1254   chrono.Stop();
1255   if (TP->TraceLevel() > 2) 
1256     sout<<"End transfer STEP -> CASCADE :" << (found ? "OK" : " : no result")<<endl;
1257   if (TP->TraceLevel() > 2) 
1258     chrono.Show();
1259 #endif
1260   if ( oldSRContext.IsNull() && ! mySRContext.IsNull() ) //:S4136
1261     PrepareUnits ( oldSRContext, TP );
1262   TP->Bind(start, shbinder);
1263   return shbinder;
1264 }
1265
1266  
1267 //=======================================================================
1268 //function : TransferEntity
1269 //purpose  : 
1270 //=======================================================================
1271
1272 Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Handle(StepRepr_MappedItem)&  mapit,
1273                                                               const Handle(Transfer_TransientProcess)& TP)
1274 {
1275   Handle(TransferBRep_ShapeBinder) shbinder;
1276   
1277     // --------------------------------------------------------------
1278   // On se trouve ici dans un contexte " d'assemblage geometrique "
1279   //    - MappedItem
1280   // --------------------------------------------------------------
1281   
1282   //:S4136: abv 20 Apr 99: as1ug.stp: MAPPED_ITEM transformation computed
1283   //        taking into account units of origin and target SHAPE_REPRESENTATIONs
1284   
1285   //  La Shape, et la mise en position
1286   Handle(StepShape_ShapeRepresentation) maprep =  Handle(StepShape_ShapeRepresentation)::
1287     DownCast(mapit->MappingSource()->MappedRepresentation());
1288   //Handle(StepRepr_Representation) maprep = mapit->MappingSource()->MappedRepresentation();
1289   Standard_Boolean isBound = Standard_False; 
1290   Handle(Transfer_Binder) binder = TP->Find(maprep);
1291   if (binder.IsNull())    binder = TransferEntity(maprep,TP,isBound);
1292   shbinder = Handle(TransferBRep_ShapeBinder)::DownCast(binder);
1293   if (shbinder.IsNull()) TP->AddWarning(mapit,"No Shape Produced");
1294   else {
1295     TopoDS_Shape mappedShape = shbinder->Result();
1296     if ( ! mappedShape.IsNull() ) {
1297       
1298       //  Positionnement : 2 formules
1299       //  1/ Ax2 dans Source et comme Target  : passage de Source a Target
1300       //  2/ CartesianOperator3d comme Target : on applique
1301       
1302       gp_Trsf Trsf;
1303       Standard_Boolean ok = Standard_False;
1304       
1305       Handle(StepGeom_CartesianTransformationOperator3d) CartOp =
1306         Handle(StepGeom_CartesianTransformationOperator3d)::DownCast(mapit->MappingTarget());
1307       if ( ! CartOp.IsNull() ) {
1308         ok = StepToGeom_MakeTransformation3d::Convert( CartOp, Trsf );
1309       }
1310       else {
1311         Handle(StepGeom_Axis2Placement3d) Origin = 
1312           Handle(StepGeom_Axis2Placement3d)::DownCast(mapit->MappingSource()->MappingOrigin());
1313         Handle(StepGeom_Axis2Placement3d) Target = 
1314           Handle(StepGeom_Axis2Placement3d)::DownCast(mapit->MappingTarget());
1315         if ( ! Origin.IsNull() && ! Target.IsNull() ) {
1316           ok = Standard_True;
1317           Handle(StepRepr_Representation) rep = mySRContext; // NOTE: copy of handle !
1318           ComputeTransformation ( Origin, Target, maprep, rep, TP, Trsf );
1319           ok = Standard_True;
1320         }
1321       }
1322       
1323       if ( ok ) ApplyTransformation ( mappedShape, Trsf );
1324       else TP->AddWarning (mapit,"Mapped Item, case not recognized, location ignored");
1325       
1326       shbinder = new TransferBRep_ShapeBinder (mappedShape);
1327     }
1328   }
1329   TP->Bind(mapit, shbinder);
1330   return shbinder;
1331 }
1332 //=======================================================================
1333 //function : TransferEntity
1334 //purpose  : 
1335 //=======================================================================
1336
1337 Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Handle(StepShape_FaceSurface)& fs,
1338                                                                        const Handle(Transfer_TransientProcess)& TP)
1339 {
1340
1341   //    Cas bien utile meme si non reconnu explicitement
1342   Handle(TransferBRep_ShapeBinder) sb;
1343   Standard_Integer nbTPitems = TP->NbMapped();
1344   try {
1345     OCC_CATCH_SIGNALS
1346
1347   StepToTopoDS_Tool         myTool;
1348   StepToTopoDS_DataMapOfTRI aMap;
1349   
1350   myTool.Init(aMap, TP);
1351   StepToTopoDS_TranslateFace myTF;
1352   myTF.SetPrecision(myPrecision);
1353   myTF.SetMaxTol(myMaxTol);
1354   
1355   // Non-manifold topology is not processed here (ssv; 15.11.2010)
1356   StepToTopoDS_NMTool dummyNMTool;
1357   myTF.Init (fs, myTool, dummyNMTool);
1358   Handle(StepRepr_Representation) oldSRContext = mySRContext;
1359   if ( mySRContext.IsNull() ) { // if no context, try to find it (ex: r0701_ug.stp #4790)
1360     Handle(StepRepr_Representation) context = FindContext ( fs, TP );
1361     if ( context.IsNull() ) {
1362       TP->AddWarning ( fs, "Entity with no unit context; default units taken" );
1363       ResetUnits();
1364     }
1365     else PrepareUnits ( context, TP );
1366   }
1367   
1368   // Apply ShapeFix
1369   Handle(Transfer_Binder) binder = TP->Find (fs);
1370   sb = Handle(TransferBRep_ShapeBinder)::DownCast ( binder );
1371   if ( ! sb.IsNull() && ! sb->Result().IsNull() ) {
1372     TopoDS_Shape S = sb->Result();
1373     
1374     Handle(Standard_Transient) info;
1375     TopoDS_Shape shape = XSAlgo::AlgoContainer()->ProcessShape( S, myPrecision, myMaxTol,
1376                                                                 "read.step.resource.name", 
1377                                                                 "read.step.sequence", info,
1378                                                                 TP->GetProgress() );
1379     //      TopoDS_Shape shape = XSAlgo::AlgoContainer()->PerformFixShape( S, TP, myPrecision, myMaxTol );
1380     if ( shape != S ) 
1381       sb->SetResult ( shape );
1382     
1383     XSAlgo::AlgoContainer()->MergeTransferInfo(TP, info, nbTPitems);
1384   }
1385
1386   
1387   if ( oldSRContext.IsNull() && ! mySRContext.IsNull() ) //:S4136
1388     PrepareUnits ( oldSRContext, TP ); 
1389   TP->Bind(fs, sb);
1390   return sb; // TP->Find (start);
1391 }
1392   catch(Standard_Failure)
1393   {
1394     TP->AddFail(fs,"Exeption is raised. Entity was not translated.");
1395     sb.Nullify();
1396     TP->Bind(fs, sb);
1397     return sb;
1398   }
1399 }
1400 //=======================================================================
1401 //function : TransferShape
1402 //purpose  : 
1403 //=======================================================================
1404
1405 Handle(Transfer_Binder) STEPControl_ActorRead::TransferShape(const Handle(Standard_Transient)& start,
1406                                                              const Handle(Transfer_TransientProcess)& TP,
1407                                                              const Standard_Boolean isManifold)
1408 {
1409   if (start.IsNull()) return NullResult();
1410   XSAlgo::AlgoContainer()->PrepareForTransfer();
1411
1412 //  myContext.SetModel ( Handle(StepData_StepModel)::DownCast ( TP->Model() ) ); // for asking IsAP203?
1413   
1414   Handle(Message_Messenger) sout = TP->Messenger();
1415 #ifdef TRANSLOG
1416 //  POUR MISE AU POINT, a supprimer ensuite
1417 //  sout<<"STEP->Shape, ent n0 "<<TP->Model()->Number(start)<<" Level="<<TP->NestingLevel()<<endl;
1418   if (TP->TraceLevel() > 1) 
1419     sout<<" -- Actor : Transfer Ent.n0 "<<TP->Model()->Number(start)<<"  Type "<<start->DynamicType()->Name()<<endl;
1420 #endif
1421   
1422   Handle(TransferBRep_ShapeBinder) shbinder;
1423   
1424
1425   // Product Definition Entities
1426   // They should be treated with Design Manager
1427    // case ShapeDefinitionRepresentation if ProductMode != ON
1428   TCollection_AsciiString aProdMode = Interface_Static::CVal("read.step.product.mode");
1429   if(!aProdMode.IsEqual("ON") && 
1430      start->IsKind(STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation))) 
1431     shbinder = OldWay(start,TP);
1432   //skl
1433   
1434   else if(start->IsKind(STANDARD_TYPE(StepBasic_ProductDefinition))) {
1435     Handle(StepBasic_ProductDefinition) PD = 
1436       Handle(StepBasic_ProductDefinition)::DownCast(start);
1437      shbinder = TransferEntity(PD,TP);
1438   }
1439   
1440   // NextAssemblyUsageOccurrence
1441   else if (start->IsKind(STANDARD_TYPE(StepRepr_NextAssemblyUsageOccurrence))) {
1442     Handle(StepRepr_NextAssemblyUsageOccurrence) NAUO = 
1443       Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(start);
1444      shbinder = TransferEntity(NAUO,TP);
1445   }
1446   //end skl
1447     
1448   // Shape Representation
1449   else if (start->IsKind(STANDARD_TYPE(StepShape_ShapeRepresentation))) {
1450     DeclareAndCast(StepShape_ShapeRepresentation,sr,start);
1451     Standard_Boolean isBound = Standard_False;
1452     shbinder = TransferEntity(sr,TP,isBound);
1453   }
1454   
1455     // --------------------------------------------------------------
1456     // On se trouve ici aussi dans un contexte " d'assemblage geometrique "
1457     //    - ShapeRepresentationRelationship + Transformation ou non
1458     // --------------------------------------------------------------
1459
1460   else if (start->IsKind(STANDARD_TYPE(StepShape_ContextDependentShapeRepresentation))) {
1461     DeclareAndCast(StepShape_ContextDependentShapeRepresentation,CDSR,start);
1462     shbinder =  TransferEntity(CDSR,TP);
1463   }
1464
1465   else if (start->IsKind (STANDARD_TYPE(StepRepr_ShapeRepresentationRelationship)) ) {
1466     //  REPRESENTATION_RELATIONSHIP et la famille
1467
1468     DeclareAndCast(StepRepr_ShapeRepresentationRelationship,und,start);
1469     shbinder =  TransferEntity(und,TP);
1470   }
1471
1472   else if (start->IsKind (STANDARD_TYPE(StepGeom_GeometricRepresentationItem)) ) {
1473     // Here starts the entity to be treated : Shape Representation Subtype
1474   // It can be also other Root entities
1475     DeclareAndCast(StepGeom_GeometricRepresentationItem,git,start);
1476     shbinder = TransferEntity(git, TP, isManifold);
1477   }
1478   else if (start->IsKind(STANDARD_TYPE(StepRepr_MappedItem))) {
1479     DeclareAndCast(StepRepr_MappedItem,mapit,start);
1480     shbinder=  TransferEntity(mapit,TP);
1481   }
1482   else if (start->IsKind(STANDARD_TYPE(StepShape_FaceSurface))) {
1483     DeclareAndCast(StepShape_FaceSurface,fs,start);
1484     shbinder =  TransferEntity(fs,TP);
1485   }
1486
1487 //  if (!shbinder.IsNull()) TP->Bind(start,binder);
1488   
1489   return shbinder;
1490 }
1491 // ============================================================================
1492 // Method  : STEPControl_ActorRead::PrepareUnits
1493 // Purpose : Set the unit conversion factors
1494 // ============================================================================
1495
1496 void STEPControl_ActorRead::PrepareUnits(const Handle(StepRepr_Representation)& rep,
1497                                          const Handle(Transfer_TransientProcess)& TP)
1498 {
1499   mySRContext = rep;
1500   
1501   Standard_Integer stat1, stat2 = 0;  // sera alimente par STEPControl_Unit
1502 //  DeclareAndCast(StepShape_ShapeRepresentation,sr,start);
1503   if (rep.IsNull()) {
1504 //    TP->AddWarning(sr,"Not a ShapeRepresentation, default unit taken");
1505     ResetUnits();
1506     return;
1507   }
1508   
1509   // Get Units Applied to this model
1510   Handle(StepRepr_RepresentationContext) theRepCont = rep->ContextOfItems();
1511   if (theRepCont.IsNull()) {
1512     TP->AddWarning(rep,"Bad RepresentationContext, default unit taken");
1513     ResetUnits();
1514     return;
1515   }
1516
1517   // --------------------------------------------------
1518   // Complex ENTITY : GeometricRepresentationContext &&
1519   //                  GlobalUnitAssignedContext
1520   // --------------------------------------------------
1521
1522   STEPConstruct_UnitContext myUnit;
1523   Handle(StepRepr_GlobalUnitAssignedContext)        theGUAC;
1524   Handle(StepRepr_GlobalUncertaintyAssignedContext) aTol;
1525
1526   if (theRepCont->IsKind(STANDARD_TYPE(StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext))) {
1527     DeclareAndCast(StepGeom_GeometricRepresentationContextAndGlobalUnitAssignedContext, theGRCAGAUC,theRepCont);
1528     theGUAC = theGRCAGAUC->GlobalUnitAssignedContext();
1529 //    TP->AddWarning(theRepCont,"No Length Uncertainty, last defined one is taken");
1530   }
1531
1532   // ----------------------------------------------------
1533   // Complex ENTITY : GeometricRepresentationContext   &&
1534   //                  GlobalUnitAssignedContext        &&
1535   //                  GlobalUncertaintyAssignedContext
1536   // ----------------------------------------------------
1537
1538   if (theRepCont->IsKind(STANDARD_TYPE(StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx))) {
1539     DeclareAndCast(StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx,
1540                    theGRCAGAUC,theRepCont);
1541     theGUAC = theGRCAGAUC->GlobalUnitAssignedContext();
1542     aTol    = theGRCAGAUC->GlobalUncertaintyAssignedContext();
1543   }
1544
1545
1546   // ----------------------------------------------------
1547   // Decoding and Setting the Values
1548   // ----------------------------------------------------
1549
1550   if (!theGUAC.IsNull()) {
1551     stat1 = myUnit.ComputeFactors(theGUAC);
1552     Standard_Integer anglemode = Interface_Static::IVal("step.angleunit.mode");
1553     Standard_Real angleFactor = ( anglemode == 0 ? myUnit.PlaneAngleFactor() :
1554                                   anglemode == 1 ? 1. : PI/180. );
1555     UnitsMethods::InitializeFactors(myUnit.LengthFactor(),
1556                                     angleFactor,
1557                                     myUnit.SolidAngleFactor());
1558     if (stat1 != 0) TP->AddWarning (theRepCont,myUnit.StatusMessage(stat1));
1559   }
1560
1561   if (!aTol.IsNull()) {
1562     stat2 = myUnit.ComputeTolerance (aTol);
1563     if (stat2 != 0) TP->AddWarning (theRepCont,myUnit.StatusMessage(stat2));
1564   }
1565
1566 //  myPrecision = Precision::Confusion();
1567   if (Interface_Static::IVal("read.precision.mode") == 1)  //:i1 gka S4136 05.04.99
1568     myPrecision = Interface_Static::RVal("read.precision.val");
1569   else if (myUnit.HasUncertainty())
1570     myPrecision = myUnit.Uncertainty() * myUnit.LengthFactor();
1571   else {
1572     TP->AddWarning(theRepCont,"No Length Uncertainty, value of read.precision.val is taken");
1573     myPrecision = Interface_Static::RVal("read.precision.val");
1574   }
1575   myMaxTol = Max ( myPrecision, Interface_Static::RVal("read.maxprecision.val") );
1576   // Assign uncertainty
1577 //  Interface_Static::SetRVal("lastpreci",UpdatedValue);
1578 #ifdef TRANSLOG
1579   if (TP->TraceLevel() > 1) 
1580     TP->Messenger() <<"  Cc1ToTopoDS : Length Unit = "<<myUnit.LengthFactor()<<"  Tolerance CASCADE = "<<myPrecision<<endl;
1581 #endif
1582 }
1583
1584 //=======================================================================
1585 //function : ResetUnits
1586 //purpose  : 
1587 //=======================================================================
1588
1589 void  STEPControl_ActorRead::ResetUnits ()
1590 {
1591   UnitsMethods::InitializeFactors ( 1, 1, 1 );
1592   myPrecision = Interface_Static::RVal("read.precision.val");
1593   myMaxTol = Max ( myPrecision, Interface_Static::RVal("read.maxprecision.val") );
1594 }
1595
1596 //=======================================================================
1597 //function : ComputeTransformation
1598 //purpose  : 
1599 //=======================================================================
1600
1601 //:S4136 abv 20 Apr 99: as1ug.stp: compute transformation taking units into account
1602 Standard_Boolean STEPControl_ActorRead::ComputeTransformation (const Handle(StepGeom_Axis2Placement3d) &Origin, 
1603                                                                const Handle(StepGeom_Axis2Placement3d) &Target,
1604                                                                const Handle(StepRepr_Representation) &OrigContext, 
1605                                                                const Handle(StepRepr_Representation) &TargContext,
1606                                                                const Handle(Transfer_TransientProcess) &TP,
1607                                                                gp_Trsf &Trsf)
1608 {
1609   Trsf = gp_Trsf();  // reinit
1610   if ( Origin.IsNull() || Target.IsNull() ) return Standard_False;
1611
1612   //:abv 31.10.01: TEST_MCI_2.step: check that Ax1 and Ax2 belong to 
1613   // corresponding reps and fix case of inversion error
1614   Handle(StepGeom_Axis2Placement3d) org = Origin;
1615   Handle(StepGeom_Axis2Placement3d) trg = Target;
1616   Standard_Integer code1=0, code2=0, i;
1617   for ( i=1; code1 != 1 && i <= OrigContext->NbItems(); i++ ) {
1618     if ( OrigContext->ItemsValue(i) == org ) code1 = 1;
1619     else if ( OrigContext->ItemsValue(i) == trg ) code1 = -1;
1620   }
1621   for ( i=1; code2 != 1 && i <= TargContext->NbItems(); i++ ) {
1622     if ( TargContext->ItemsValue(i) == org ) code2 = -1;
1623     else if ( TargContext->ItemsValue(i) == trg ) code2 = 1;
1624   }
1625   if ( code1 != 1 && code2 != 1 ) {
1626     if ( code1 == -1 && code2 == -1 ) {
1627       Handle(StepGeom_Axis2Placement3d) swp = org; org = trg; trg = swp;
1628       TP->AddWarning ( org, "Axis placements are swapped in SRRWT; corrected" );
1629     }
1630     else {
1631       TP->AddWarning ( ( code1 == 1 ? trg : org ), 
1632                        "Axis placement used by SRRWT does not belong to corresponding representation" );
1633     }
1634   }
1635   
1636   // translate axis_placements taking units into account 
1637   Handle(StepRepr_Representation) oldSRContext = mySRContext;
1638   if ( OrigContext  != oldSRContext ) PrepareUnits(OrigContext,TP);
1639   Handle(Geom_Axis2Placement) theOrig;
1640   StepToGeom_MakeAxis2Placement::Convert(org,theOrig);
1641   if ( TargContext  != OrigContext  ) PrepareUnits(TargContext,TP);
1642   Handle(Geom_Axis2Placement) theTarg;
1643   StepToGeom_MakeAxis2Placement::Convert(trg,theTarg);
1644   if ( oldSRContext != TargContext  ) PrepareUnits(oldSRContext,TP);
1645
1646   gp_Ax3 ax3Orig(theOrig->Ax2());
1647   gp_Ax3 ax3Targ(theTarg->Ax2());
1648
1649   //  ne pas se tromper de sens !
1650   Trsf.SetTransformation(ax3Targ, ax3Orig);
1651   return Trsf.Form() != gp_Identity;
1652 }
1653
1654 //=======================================================================
1655 //function : ReadSRRWT
1656 //purpose  : 
1657 //=======================================================================
1658
1659 //:j2 abv 22 Oct 98: auxiliary function: reading transformation from SRRWT
1660 Standard_Boolean STEPControl_ActorRead::ComputeSRRWT (const Handle(StepRepr_RepresentationRelationship) &SRR,
1661                                                       const Handle(Transfer_TransientProcess) &TP,
1662                                                       gp_Trsf &Trsf)
1663 {
1664   Trsf = gp_Trsf(); // init
1665   
1666   DeclareAndCast(StepRepr_ShapeRepresentationRelationshipWithTransformation,srwt,SRR);
1667   if ( srwt.IsNull() ) return Standard_False;
1668
1669   StepRepr_Transformation SelectTrans = srwt->TransformationOperator();
1670   
1671   // cartesian transformation
1672   Handle(StepGeom_CartesianTransformationOperator3d) CartOp = 
1673     Handle(StepGeom_CartesianTransformationOperator3d)::DownCast(SelectTrans.Value());
1674   if ( ! CartOp.IsNull() ) {
1675     // reset units (by Rep2 - ?)
1676     Handle(StepRepr_Representation) oldSRContext = mySRContext;
1677     if ( SRR->Rep2() != oldSRContext ) PrepareUnits(SRR->Rep2(),TP);
1678     StepToGeom_MakeTransformation3d::Convert( CartOp, Trsf );
1679     if ( SRR->Rep2() != oldSRContext ) PrepareUnits(oldSRContext,TP);
1680     return Trsf.Form() != gp_Identity;
1681   }
1682
1683   // item-defined transformation
1684   Handle(StepRepr_ItemDefinedTransformation) ItemDef =
1685     SelectTrans.ItemDefinedTransformation();
1686   if ( ItemDef.IsNull() ) return Standard_False;
1687   
1688   Handle(StepGeom_Axis2Placement3d) Ax1 =
1689     Handle(StepGeom_Axis2Placement3d)::DownCast(ItemDef->TransformItem1());
1690   Handle(StepGeom_Axis2Placement3d) Ax2 =
1691     Handle(StepGeom_Axis2Placement3d)::DownCast(ItemDef->TransformItem2());
1692   if ( Ax1.IsNull() || Ax2.IsNull() ) return Standard_False;
1693   return ComputeTransformation ( Ax1, Ax2, SRR->Rep1(), SRR->Rep2(), TP, Trsf);
1694 }
1695
1696 //=======================================================================
1697 // Method  : closeIDEASShell
1698 // Purpose : Attempts to close the passed Shell with the passed closing
1699 //           Shells. Cuts redundant Faces from the closing Shells if any
1700 //=======================================================================
1701
1702 TopoDS_Shell STEPControl_ActorRead::closeIDEASShell(const TopoDS_Shell& shell,
1703                                                     const TopTools_ListOfShape& closingShells) {
1704
1705   // Make Shell to provide closeness adjustments
1706   TopoDS_Shell result;
1707   BRep_Builder brepBuilder;
1708   brepBuilder.MakeShell(result);
1709         
1710   // Firstly, add all existing faces to the new Shell
1711   TopExp_Explorer currentFExp(shell, TopAbs_FACE);
1712   for ( ; currentFExp.More(); currentFExp.Next() ) {
1713     TopoDS_Face currentFace = TopoDS::Face( currentFExp.Current() ); 
1714     brepBuilder.Add(result, currentFace);
1715   }
1716
1717   TopTools_ListIteratorOfListOfShape itL(closingShells);
1718   TopTools_ListOfShape closingFaces;
1719
1720   // Then add the closing faces
1721   for ( ; itL.More(); itL.Next() ) {
1722     TopoDS_Shape currentClosing = itL.Value();
1723     TopExp_Explorer faceExp(currentClosing, TopAbs_FACE);
1724
1725     for ( ; faceExp.More(); faceExp.Next() ) {
1726       TopoDS_Face currentFace = TopoDS::Face( faceExp.Current() ); 
1727       brepBuilder.Add(result, currentFace);
1728       // Store each added closing face for subsequent processing
1729       closingFaces.Append(currentFace);
1730     }
1731   }
1732
1733   // Check if the result is closed
1734   BRepCheck_Shell checker( TopoDS::Shell(result) );
1735   BRepCheck_Status checkStatus = checker.Closed();
1736   if (checkStatus == BRepCheck_NoError)
1737     result.Closed(Standard_True);
1738   else
1739     return shell; // Cannot close this shell, skip it so...
1740
1741   // Try to remove redundant Faces
1742   for ( itL.Initialize(closingFaces); itL.More(); itL.Next() ) {
1743     TopoDS_Face currentFace = TopoDS::Face( itL.Value() );
1744     // Remove face to see if Shell is still closed
1745     brepBuilder.Remove(result, currentFace);
1746     BRepCheck_Shell subChecker( TopoDS::Shell(result) );
1747     BRepCheck_Status subCheckStatus = subChecker.Closed();
1748     // If Shell becomes open, just put the deleted face back
1749     if (subCheckStatus != BRepCheck_NoError)
1750       brepBuilder.Add(result, currentFace);
1751     else {
1752       #ifdef DEB
1753       cout << "Redundant closing face detected: REMOVED from shell";
1754       #endif
1755     }
1756   }
1757
1758   return result;
1759
1760 }
1761
1762 //=======================================================================
1763 // Method  : computeIDEASClosings
1764 // Purpose : For each Shell from the compound passed (comp), find all
1765 //           non-manifold adjacent Shells and put the results into
1766 //           the passed map (shellClosingMap)
1767 //=======================================================================
1768
1769 void STEPControl_ActorRead::computeIDEASClosings(const TopoDS_Compound& comp,
1770                                                  TopTools_IndexedDataMapOfShapeListOfShape& shellClosingsMap) {
1771   TopExp_Explorer shellExpA(comp, TopAbs_SHELL);
1772
1773   for ( ; shellExpA.More(); shellExpA.Next() ) {
1774     TopoDS_Shape shellA = shellExpA.Current();
1775     TopExp_Explorer shellExpB(comp, TopAbs_SHELL);
1776     TopTools_ListOfShape closingShells;
1777
1778     for ( ; shellExpB.More(); shellExpB.Next() ) {
1779       TopoDS_Shape shellB = shellExpB.Current();
1780       if ( shellA.IsSame(shellB) )
1781         continue;
1782       // Check whether ShellB is non-manifold and adjacent to ShellA.
1783       // If so, ShellA has a chance to be closed with ShellB
1784       if ( myNMTool.IsSuspectedAsClosing(shellA, shellB) )
1785         closingShells.Append(shellB);
1786     }
1787       
1788     if ( !closingShells.IsEmpty() )
1789       shellClosingsMap.Add(shellA, closingShells);
1790   }
1791
1792 }