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