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