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