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