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