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