0022792: Globally defined symbol PI conflicts with VTK definition (Intel compiler)
[occt.git] / src / STEPControl / STEPControl_ActorWrite.cxx
1 //:k8 abv 6 Jan 99: unique names for PRODUCTs
2 //:k9 abv 6 Jan 99: TR10: eliminating duplicated APPLICATION_CONTEXT entities
3 //abv,gka 05.04.99: S4136: change parameters and update units
4 // PTV    22.08.2002 OCC609 transfer solo vertices into step file.
5 // PTV    16.09.2002 OCC725 transfer compound of vertices into one geometrical curve set.
6 #include <STEPControl_ActorWrite.ixx>
7 #include <STEPControl_StepModelType.hxx>
8
9 //  Transfer
10 #include <Transfer_SimpleBinderOfTransient.hxx>
11 #include <gp_Ax2.hxx>
12 #include <GeomToStep_MakeAxis2Placement3d.hxx>
13 #include <StepGeom_Axis2Placement3d.hxx>
14
15 #include <STEPConstruct_Part.hxx>
16 #include <STEPConstruct_Assembly.hxx>
17 #include <STEPConstruct_ContextTool.hxx>
18 #include <STEPConstruct_UnitContext.hxx>
19
20 //  TransferShape
21 #include <TopoDSToStep.hxx>
22 #include <TopoDSToStep_Builder.hxx>
23 #include <TopoDSToStep_FacetedTool.hxx>
24 #include <TopoDSToStep_Tool.hxx>
25 #include <TopoDSToStep_MakeManifoldSolidBrep.hxx>
26 #include <TopoDSToStep_MakeBrepWithVoids.hxx>
27 #include <TopoDSToStep_MakeFacetedBrep.hxx>
28 #include <TopoDSToStep_MakeFacetedBrepAndBrepWithVoids.hxx>
29 #include <TopoDSToStep_MakeGeometricCurveSet.hxx>
30 #include <TopoDSToStep_MakeShellBasedSurfaceModel.hxx>
31
32 #include <TopoDS.hxx>
33 #include <TopoDS_Shape.hxx>
34 #include <TopoDS_Solid.hxx>
35 #include <Geom_Surface.hxx>
36 #include <Geom_Plane.hxx>
37 #include <Geom_Curve.hxx>
38 #include <Geom_Line.hxx>
39
40 #include <StepShape_ShapeDefinitionRepresentation.hxx>
41 #include <StepShape_FacetedBrepAndBrepWithVoids.hxx>
42 #include <StepShape_FacetedBrep.hxx>
43 #include <StepShape_GeometricCurveSet.hxx>
44 #include <StepShape_ShellBasedSurfaceModel.hxx>
45 #include <StepShape_ManifoldSolidBrep.hxx>
46 #include <StepShape_BrepWithVoids.hxx>
47 #include <StepRepr_HArray1OfRepresentationItem.hxx>
48 #include <StepBasic_HArray1OfProduct.hxx>
49 #include <StepRepr_GlobalUnitAssignedContext.hxx>
50 #include <StepShape_AdvancedBrepShapeRepresentation.hxx>
51 #include <StepShape_FacetedBrepShapeRepresentation.hxx>
52 #include <StepShape_TopologicalRepresentationItem.hxx>
53 #include <StepShape_ManifoldSurfaceShapeRepresentation.hxx>
54 #include <StepShape_GeometricallyBoundedWireframeShapeRepresentation.hxx>
55 #include <StepBasic_ApplicationProtocolDefinition.hxx>
56 #include <StepRepr_PropertyDefinition.hxx>
57
58 #include <TopExp_Explorer.hxx>
59 #include <TColStd_HSequenceOfTransient.hxx>
60 #include <TCollection_HAsciiString.hxx>
61
62 #include <Transfer_TransientProcess.hxx>
63 #include <Transfer_Binder.hxx>
64 #include <Transfer_Finder.hxx>
65 #include <Transfer_FinderProcess.hxx>
66 #include <TransferBRep_ShapeMapper.hxx>
67 #include <TransferBRep.hxx>
68 #include <OSD_Timer.hxx>
69
70 #include <ShapeExtend_Explorer.hxx>  
71 #include <ShapeAnalysis_ShapeTolerance.hxx>
72 #include <Interface_MSG.hxx>
73 #include <Interface_Static.hxx>
74
75 #include <Interface_Macros.hxx>
76 #include <TopTools_HSequenceOfShape.hxx>
77
78 #include <BRep_Tool.hxx>
79 #include <TopoDS_Iterator.hxx> //:d6
80 #include <UnitsMethods.hxx>
81 #include <STEPConstruct_AP203Context.hxx>
82 #include <BRepTools_Modifier.hxx>
83
84 #include <XSAlgo.hxx>
85 #include <XSAlgo_AlgoContainer.hxx>
86 #include <StepRepr_ShapeRepresentationRelationship.hxx>
87 #include <Transfer_SequenceOfBinder.hxx>
88
89 #include <TopoDSToStep_MakeStepVertex.hxx>
90 #include <StepShape_VertexPoint.hxx>
91 #include <MoniTool_DataMapOfShapeTransient.hxx>
92 #include <StepShape_HArray1OfGeometricSetSelect.hxx>
93 #include <StepShape_GeometricSetSelect.hxx>
94 #include <TopoDS_Compound.hxx>
95 #include <BRep_Builder.hxx>
96
97 // Non-manifold topology processing (ssv; 10.11.2010)
98 #include <StepShape_NonManifoldSurfaceShapeRepresentation.hxx>
99 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
100 #include <TopTools_ListOfShape.hxx>
101 #include <TopExp.hxx>
102 #include <TopTools_MapOfShape.hxx>
103 #include <TopTools_ListIteratorOfListOfShape.hxx>
104
105 // ============================================================================
106 // Function: DumpWhatIs   
107 // Purpose: Use it in DEB mode to dump your shapes
108 // ============================================================================
109
110 static void DumpWhatIs(const TopoDS_Shape& S) {
111
112   TopTools_MapOfShape aMapOfShape;
113   aMapOfShape.Add(S);
114   TopTools_ListOfShape aListOfShape;
115   aListOfShape.Append(S);
116   TopTools_ListIteratorOfListOfShape itL(aListOfShape);
117   Standard_Integer nbSolids = 0,
118                    nbShells = 0,
119                    nbOpenShells = 0,
120                    nbFaces = 0, 
121                    nbWires = 0, 
122                    nbEdges = 0, 
123                    nbVertexes = 0;
124
125   for( ; itL.More(); itL.Next() ) {
126     TopoDS_Iterator it( itL.Value() );
127     for ( ; it.More(); it.Next() ) {
128       TopoDS_Shape aSubShape = it.Value();
129       if ( !aMapOfShape.Add(aSubShape) )
130         continue;
131       aListOfShape.Append(aSubShape);
132       if (aSubShape.ShapeType() == TopAbs_SOLID)
133         nbSolids++;
134       if (aSubShape.ShapeType() == TopAbs_SHELL) {
135         if ( !aSubShape.Closed() )
136           nbOpenShells++;
137         nbShells++;
138       }
139       if (aSubShape.ShapeType() == TopAbs_FACE)
140         nbFaces++;
141       if (aSubShape.ShapeType() == TopAbs_WIRE)
142         nbWires++;
143       if (aSubShape.ShapeType() == TopAbs_EDGE)
144         nbEdges++;
145       if (aSubShape.ShapeType() == TopAbs_VERTEX)
146         nbVertexes++;
147     }
148   }
149   #ifdef DEB
150   cout << "//What is?// NB SOLIDS: " << nbSolids << endl;
151   cout << "//What is?// NB SHELLS: " << nbShells << endl;
152   cout << "//What is?//    OPEN SHELLS: " << nbOpenShells << endl;
153   cout << "//What is?//    CLOSED SHELLS: " << nbShells - nbOpenShells << endl;
154   cout << "//What is?// NB FACES: " << nbFaces << endl;
155   cout << "//What is?// NB WIRES: " << nbWires << endl;
156   cout << "//What is?// NB EDGES: " << nbEdges << endl;
157   cout << "//What is?// NB VERTEXES: " << nbVertexes << endl;
158   #endif
159 }
160
161 //=======================================================================
162 // Function : IsManifoldShape
163 // Purpose  : Used to define whether the passed shape has manifold
164 //            topology or not
165 //=======================================================================
166
167 static Standard_Boolean IsManifoldShape(const TopoDS_Shape& theShape) {
168
169    Standard_Boolean aResult = Standard_True;
170
171   // Do not check nested Compounds
172   TopoDS_Compound aDirectShapes;
173   BRep_Builder aBrepBuilder;
174   aBrepBuilder.MakeCompound(aDirectShapes);
175
176   TopoDS_Iterator anIt(theShape);
177   for ( ; anIt.More(); anIt.Next() ) {
178     TopoDS_Shape aDirectChild = anIt.Value();
179     if (aDirectChild.ShapeType() != TopAbs_COMPOUND)
180       aBrepBuilder.Add(aDirectShapes, aDirectChild);
181   }  
182
183   #ifdef DEB
184   DumpWhatIs(aDirectShapes);
185   #endif
186
187   TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
188   TopExp::MapShapesAndAncestors(aDirectShapes, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
189
190   Standard_Integer aNbEdges = aMapEdgeFaces.Extent();
191   #ifdef DEB
192   cout << "Checking whether the topology passed is manifold..." << endl;
193   #endif
194
195   // Check topology
196   for (Standard_Integer i = 1; i <= aNbEdges; i++) {
197     TopoDS_Edge aCurrentEdge = TopoDS::Edge( aMapEdgeFaces.FindKey(i) );
198     if ( !BRep_Tool::Degenerated(aCurrentEdge) ) { 
199       Standard_Integer aNbAncestors = aMapEdgeFaces.FindFromIndex(i).Extent();
200       if (aNbAncestors > 2) {
201         aResult = Standard_False;
202         break;
203       }
204     }
205   }
206
207   #ifdef DEB
208   cout << "Check result: "
209        << (aResult ? "TRUE" : "FALSE") << endl;
210   #endif
211
212   return aResult;
213 }
214
215 /* this is a start of a comment! */ 
216 #ifdef DEB
217 void DumpBinder (const Handle(Transfer_Binder) &binder)
218 {
219   Handle(Transfer_Binder) bbb = binder;
220   while ( ! bbb.IsNull() ) {
221     Handle(Transfer_SimpleBinderOfTransient) bx = 
222       Handle(Transfer_SimpleBinderOfTransient)::DownCast ( bbb );
223     cout << (void*)&bx;
224     if ( ! bx.IsNull() ) {
225       cout << "--> " << bx->ResultTypeName() << " " << *(void**)&bx->Result() << endl;
226     }
227     else cout << "--> ???" << endl;
228     bbb = bbb->NextResult();
229   }
230   cout << endl;
231 }
232 #endif
233 /* this is a end of a comment */
234   
235 //=======================================================================
236 //function : STEPControl_ActorWrite
237 //purpose  : 
238 //=======================================================================
239
240 STEPControl_ActorWrite::STEPControl_ActorWrite ()
241 : mygroup (0) , mytoler (-1.)
242 {  
243   SetMode(STEPControl_ShellBasedSurfaceModel);  
244 }
245
246 //=======================================================================
247 //method: getNMSSRForGroup
248 //purpose: allows to get NMSSR (NON_MANIFOLD_SURFACE_SHAPE_REPRESENTATION)
249 //         STEP's entity for the group of shells (!) passed
250 //=======================================================================
251
252 Handle(StepShape_NonManifoldSurfaceShapeRepresentation) STEPControl_ActorWrite::getNMSSRForGroup(const Handle(TopTools_HSequenceOfShape)& shapeGroup,
253                                                                                                  const Handle(Transfer_FinderProcess)& FP, 
254                                                                                                  Standard_Boolean& isNMSSRCreated) const
255 {
256   Handle(StepShape_NonManifoldSurfaceShapeRepresentation) aResult;
257
258   if ( !shapeGroup.IsNull() ) {
259     for (Standard_Integer i = 1; i <= shapeGroup->Length(); i++) {
260       TopoDS_Shape aCurrentShape = shapeGroup->Value(i);
261       Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper(FP, aCurrentShape);
262       if ( FP->FindTypedTransient(mapper, STANDARD_TYPE(StepShape_NonManifoldSurfaceShapeRepresentation), aResult) )
263         break;
264     }
265   }
266
267   if ( aResult.IsNull() ) {
268     #ifdef DEB
269     cout << "\nNew NMSSR created" << endl;
270     #endif
271     aResult = new StepShape_NonManifoldSurfaceShapeRepresentation;
272     isNMSSRCreated = Standard_True;
273   } else {
274     #ifdef DEB
275     cout << "\nExisting NMSSR is used" << endl;
276     #endif
277     isNMSSRCreated = Standard_False;
278   }
279
280   return aResult;
281 }
282
283
284 //=======================================================================
285 //function : SetMode
286 //purpose  : 
287 //=======================================================================
288
289 void STEPControl_ActorWrite::SetMode (const STEPControl_StepModelType M)
290 {
291   switch (M) {
292   case STEPControl_AsIs : ModeTrans() = 0; break;
293   case STEPControl_ManifoldSolidBrep : ModeTrans() = 3; break;
294   case STEPControl_BrepWithVoids :     ModeTrans() = 5; break;
295   case STEPControl_FacetedBrep :       ModeTrans() = 1; break;
296   case STEPControl_FacetedBrepAndBrepWithVoids : ModeTrans() = 6; break;
297   case STEPControl_ShellBasedSurfaceModel :      ModeTrans() = 2;
298   case STEPControl_GeometricCurveSet :           ModeTrans() = 4;
299   case STEPControl_Hybrid : ModeTrans() = 0; break;  // PAS IMPLEMENTE !!
300     default: break;
301   }
302 }
303
304 //=======================================================================
305 //function : Mode
306 //purpose  : 
307 //=======================================================================
308
309 STEPControl_StepModelType STEPControl_ActorWrite::Mode () const
310 {
311   switch (themodetrans) {
312   case 0 : return STEPControl_AsIs;
313   case 1 : return STEPControl_FacetedBrep;
314   case 2 : return STEPControl_ShellBasedSurfaceModel;
315   case 3 : return STEPControl_ManifoldSolidBrep;
316   case 4 : return STEPControl_GeometricCurveSet;
317   case 5 : return STEPControl_BrepWithVoids;
318   case 6 : return STEPControl_FacetedBrepAndBrepWithVoids;
319     default : break;
320   }
321   return STEPControl_AsIs;
322 }
323
324 //=======================================================================
325 //function : SetGroupMode
326 //purpose  : 
327 //=======================================================================
328
329 void STEPControl_ActorWrite::SetGroupMode (const Standard_Integer mode)
330 {  
331   if (mode >= 0) mygroup = mode;  
332 }
333
334 //=======================================================================
335 //function : GroupMode
336 //purpose  : 
337 //=======================================================================
338
339 Standard_Integer STEPControl_ActorWrite::GroupMode () const
340 {  
341   return mygroup;  
342 }
343
344 //=======================================================================
345 //function : SetTolerance
346 //purpose  : 
347 //=======================================================================
348
349 void STEPControl_ActorWrite::SetTolerance (const Standard_Real Tol)
350 {  
351   mytoler = Tol;  
352 }
353
354 //=======================================================================
355 //function : Recognize
356 //  ATTENTION, Recognize doit s aligner sur ce que Transfer sait faire
357 //purpose  : 
358 //=======================================================================
359
360 Standard_Boolean  STEPControl_ActorWrite::Recognize (const Handle(Transfer_Finder)& start)
361 {
362   STEPControl_StepModelType mymode = Mode();
363   Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
364   if (mapper.IsNull()) return Standard_False;
365   if (mymode == STEPControl_AsIs) return Standard_True;
366
367   Standard_Boolean yasolid = Standard_False, yashell = Standard_False,
368                    yaface  = Standard_False;
369
370   TopoDS_Shape theShape, aShape;
371 //  theShape = TopoDSToStep::DirectFaces(mapper->Value());
372   theShape = mapper->Value();  // pour une reconnaissance c est bien assez
373
374   if (theShape.ShapeType() == TopAbs_COMPOUND) {
375     
376     TopExp_Explorer SolidExp, ShellExp, FaceExp;
377     
378     for (SolidExp.Init(theShape, TopAbs_SOLID);
379          SolidExp.More();SolidExp.Next()) yasolid = Standard_True;
380     for (ShellExp.Init(theShape, TopAbs_SHELL, TopAbs_SOLID);
381          ShellExp.More();ShellExp.Next()) yashell = Standard_True;
382     for (FaceExp.Init(theShape, TopAbs_FACE, TopAbs_SHELL);
383          FaceExp.More();FaceExp.Next())   yaface  = Standard_True;
384   }
385   else if (theShape.ShapeType() == TopAbs_SOLID) yasolid = Standard_True;
386   else if (theShape.ShapeType() == TopAbs_SHELL) yashell = Standard_True;
387   else if (theShape.ShapeType() == TopAbs_FACE)  yaface  = Standard_True;
388   else if (mymode != STEPControl_GeometricCurveSet) return Standard_False;
389 //  pour wireframe ?
390
391 //  Faceted : il est OBLIGATOIRE d avoir des surfaces support Plane et des
392 //   courbes 3D Line (pcurves ignorees)
393
394   if (mymode == STEPControl_FacetedBrep || mymode == STEPControl_FacetedBrepAndBrepWithVoids) {
395     for (TopExp_Explorer ffac(theShape,TopAbs_FACE); ffac.More(); ffac.Next()) {
396       const TopoDS_Face& F = TopoDS::Face (ffac.Current());
397       TopLoc_Location locbid;
398       Handle(Geom_Surface) surf = BRep_Tool::Surface (F,locbid);
399       if (surf.IsNull() || !surf->IsKind(STANDARD_TYPE(Geom_Plane)) ) return Standard_False;
400     }
401     for (TopExp_Explorer fedg(theShape,TopAbs_EDGE); fedg.More(); fedg.Next()) {
402       const TopoDS_Edge& E = TopoDS::Edge (fedg.Current());
403       TopLoc_Location locbid;  Standard_Real first,last;
404       Handle(Geom_Curve) curv = BRep_Tool::Curve (E,locbid,first,last);
405       if (curv.IsNull() || !curv->IsKind(STANDARD_TYPE(Geom_Line)) ) return Standard_False;
406     }
407   }
408
409   switch (mymode) {
410     case STEPControl_ManifoldSolidBrep: return (yasolid || yashell);
411     case STEPControl_BrepWithVoids:
412     case STEPControl_FacetedBrep:
413     case STEPControl_FacetedBrepAndBrepWithVoids:       return yasolid;
414     case STEPControl_ShellBasedSurfaceModel:
415                                         return (yasolid || yashell || yaface);
416     case STEPControl_GeometricCurveSet:  return Standard_True;  // tout OK
417     default : break;
418   }
419   return Standard_False;
420 }
421
422
423 //  ########    MAKE PRODUCT DATA + CONTEXT    ########
424
425 //=======================================================================
426 //function : Transfer
427 //purpose  : 
428 //=======================================================================
429
430 Handle(Transfer_Binder) STEPControl_ActorWrite::Transfer (const Handle(Transfer_Finder)& start,
431                                                           const Handle(Transfer_FinderProcess)& FP)
432 {
433   XSAlgo::AlgoContainer()->PrepareForTransfer();
434     
435   Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
436
437   if (mapper.IsNull()) return NullResult();
438   TopoDS_Shape shape = mapper->Value();
439
440   // init context
441   Handle(StepData_StepModel) model = Handle(StepData_StepModel)::DownCast ( FP->Model() );
442   if ( ! model.IsNull() ) myContext.SetModel ( model ); //: abv 04.11.00: take APD from model
443   myContext.AddAPD ( Standard_False ); // update APD
444   myContext.SetLevel ( 1 ); // set assembly level to 1 (to ensure)
445   
446   //:S4136: init UnitsMethods to reset angle unit factors (see TopoDSToStep)
447   Standard_Real lFactor = UnitsMethods::GetLengthFactorValue ( Interface_Static::IVal ( "write.step.unit" ) );
448   lFactor /= UnitsMethods::GetCasCadeLengthUnit();
449   Standard_Integer anglemode = Interface_Static::IVal("step.angleunit.mode");
450   UnitsMethods::InitializeFactors ( lFactor, ( anglemode <= 1 ? 1. : M_PI/180. ), 1. );
451
452   // create SDR
453   STEPConstruct_Part SDRTool;
454   SDRTool.MakeSDR ( 0, myContext.GetProductName(), myContext.GetAPD()->Application() );
455   Handle(StepShape_ShapeDefinitionRepresentation) sdr = SDRTool.SDRValue();
456   // transfer shape
457
458   Handle(Transfer_Binder) resbind = TransferShape (mapper,sdr,FP);
459
460 //  Handle(StepShape_ShapeRepresentation) resultat;
461 //  FP->GetTypedTransient (resbind,STANDARD_TYPE(StepShape_ShapeRepresentation),resultat);
462 //  sdr->SetUsedRepresentation (resultat);
463
464   // create binder with all root entities produced from shape
465   Handle(TColStd_HSequenceOfTransient) roots = myContext.GetRootsForPart ( SDRTool );
466   Handle(Transfer_Binder) resprod = TransientResult ( myContext.GetAPD() );
467   for ( Standard_Integer i=1; i <= roots->Length(); i++ ) 
468     resprod->AddResult ( TransientResult ( roots->Value(i) ) );
469   resprod->AddResult(resbind);
470
471   // bind and exit
472   //FP->Bind (mapper,resprod);
473   myContext.NextIndex();
474   return resprod;
475 }
476
477 //==========================================
478
479 static Standard_Real UsedTolerance (const Standard_Real mytoler, 
480                                     const TopoDS_Shape& theShape)
481 {
482
483   //    COMPUTING 3D TOLERANCE
484   //    Either from Session, or Computed (Least,Average, or Greatest)
485   //    Then given to TopoDSToStep_Tool
486
487   Standard_Real Tol = mytoler;
488   Standard_Integer tolmod = Interface_Static::IVal("write.precision.mode");
489   if (Tol <= 0 && tolmod == 2) Tol =
490     Interface_Static::RVal("write.precision.val");
491   if (Tol <= 0) {
492     ShapeAnalysis_ShapeTolerance stu;
493     Tol = stu.Tolerance (theShape,tolmod);
494     //  Par defaut, on prend une tolerance moyenne, on elimine les aberrations
495     Tol = Interface_MSG::Intervalled (Tol * 1.5);  // arrondi a 1 2 5 ...
496   }
497   if (Tol == 0) Tol = 1.e-07;  // minimum ...
498
499   return Tol;
500 }
501
502 //=======================================================================
503 //function : IsAssembly
504 //purpose  : 
505 //=======================================================================
506 // if GroupMode is >1 downgrades all compounds having single subshape to that 
507 // subshape
508
509 Standard_Boolean STEPControl_ActorWrite::IsAssembly (TopoDS_Shape &S) const
510 {
511   if ( ! GroupMode() || S.ShapeType() != TopAbs_COMPOUND ) return Standard_False;
512   // PTV 16.09.2002  OCC725 for storing compound of vertices
513   if (S.ShapeType() == TopAbs_COMPOUND ) {
514     Standard_Boolean IsOnlyVertices = Standard_True;
515     TopoDS_Iterator anItr( S );
516     for ( ; anItr.More(); anItr.Next() ) {
517       if ( anItr.Value().ShapeType() != TopAbs_VERTEX ) {
518         IsOnlyVertices = Standard_False;
519         break;
520       }
521     }
522     if ( IsOnlyVertices )
523       return Standard_False;
524   }
525   if ( GroupMode() ==1 ) return Standard_True;
526   TopoDS_Iterator it ( S );
527   if ( ! it.More() ) return Standard_False;
528   TopoDS_Shape shape = it.Value();
529   it.Next();
530   if ( it.More() ) return Standard_True;
531   S = shape;
532   return IsAssembly ( S );
533 }
534
535 //=======================================================================
536 //function : TransferShape
537 //purpose  : 
538 //=======================================================================
539
540 /*
541 static void UpdateMap (const TopoDS_Shape &shape, 
542                        BRepTools_Modifier &M1, 
543                        BRepTools_Modifier &M2, 
544                        const Handle(Transfer_FinderProcess) &FinderProcess)
545 {
546   TopoDS_Shape S = M1.ModifiedShape ( shape );
547   S = M2.ModifiedShape ( S );
548   if ( S == shape ) return;
549
550   Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper ( FinderProcess, S );
551   Handle(Transfer_Binder) binder = FinderProcess->Find ( mapper );
552   if ( ! binder.IsNull() ) {
553     mapper = TransferBRep::ShapeMapper ( FinderProcess, shape );
554     FinderProcess->Bind ( mapper, binder );
555   }
556   
557   for ( TopoDS_Iterator it(shape); it.More(); it.Next() ) 
558     UpdateMap ( it.Value(), M1, M2, FinderProcess );
559 }
560 */
561
562 // PTV 16.09.2002 added for transfering vertices.
563 static Standard_Boolean transferVertex (const Handle(Transfer_FinderProcess)& FP,
564                                         Handle(StepShape_HArray1OfGeometricSetSelect)& aGSS,
565                                         const TopoDS_Shape& aShVrtx,
566                                         const Standard_Integer theNum)
567 {
568   Standard_Boolean IsDone = Standard_False;
569   MoniTool_DataMapOfShapeTransient aMap;
570   TopoDSToStep_Tool    aTool(aMap, Standard_True);
571   TopoDSToStep_MakeStepVertex aMkVrtx ( TopoDS::Vertex(aShVrtx), aTool, FP );
572   
573   if (!aMkVrtx.IsDone())
574     return IsDone;
575   
576   Handle(StepShape_VertexPoint) aVP = 
577     Handle(StepShape_VertexPoint)::DownCast(aTool.Find(aShVrtx));
578   if (aVP.IsNull())
579     return IsDone;
580     
581   StepShape_GeometricSetSelect select;
582   select.SetValue(aVP->VertexGeometry());
583   // add current result
584   aGSS->SetValue( theNum, select );
585   IsDone = Standard_True;
586   return IsDone;
587 }
588
589      
590 Handle(Transfer_Binder) STEPControl_ActorWrite::TransferShape (const Handle(Transfer_Finder)& start,
591                                                                const Handle(StepShape_ShapeDefinitionRepresentation)& SDR0,
592                                                                const Handle(Transfer_FinderProcess)& FP,
593                                                                const Handle(TopTools_HSequenceOfShape)& shapeGroup,
594                                                                const Standard_Boolean isManifold)
595 {
596   STEPControl_StepModelType mymode = Mode();
597   Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
598   Handle(Transfer_Binder) binder;
599
600   // Indicates whether to use an exising NMSSR to write items to (ss; 13.11.2010)
601   Standard_Boolean useExistingNMSSR = Standard_False;
602
603   if (mapper.IsNull()) return binder;
604   TopoDS_Shape theShape = mapper->Value();
605
606   if (theShape.IsNull()) return binder;
607
608   // INDIVIDUAL SHAPE ALREADY TRANSFERRED : RETURN IT !
609   binder = FP->Find(start);
610   if (!binder.IsNull()) {  if (!binder->HasResult()) binder.Nullify();  }
611   if (!binder.IsNull()) { 
612     //:abv 20.05.02: writing box & face from it (shared) in one compound 
613     // as assembly - while face already translated, it should be 
614     // re-translated to break sharing
615 #ifdef DEB
616     cout << "Warning: STEPControl_ActorWrite::TransferShape(): shape already translated" << endl;
617 #endif
618 //    return binder;
619   }
620
621   // MODE ASSEMBLY : if Compound, (sub-)assembly
622   if ( IsAssembly(theShape) )
623     return TransferCompound(start, SDR0, FP);
624
625   // [BEGIN] Separate manifold topology from non-manifold in group mode 0 (ssv; 18.11.2010)
626   Standard_Boolean isNMMode = Interface_Static::IVal("write.step.nonmanifold");
627   Handle(Transfer_Binder) aNMBinder;
628   if (isNMMode && !GroupMode() && theShape.ShapeType() == TopAbs_COMPOUND) {
629     TopoDS_Compound aNMCompound;
630     TopoDS_Compound aManifoldCompound;
631     BRep_Builder brepBuilder;
632
633     // Create empty Compounds
634     brepBuilder.MakeCompound(aManifoldCompound);
635     brepBuilder.MakeCompound(aNMCompound);
636
637     // Indicates whether there is only non-manifold topology detected 
638     // (there is no manifold topology found in the Compound passed)
639     Standard_Boolean isOnlyNonManifold = Standard_False;
640     
641     // Find a Compound containing non-manifold topology.
642     // NOTE: only one such Compound must exist in the entire Compound passed
643     if ( !IsManifoldShape(theShape) ) {
644       aNMCompound = TopoDS::Compound(theShape);
645       isOnlyNonManifold = Standard_True;
646     }
647     else {
648       TopTools_ListOfShape aListOfShapes;
649       TopTools_ListOfShape aListOfManifoldShapes;
650       aListOfShapes.Append(theShape);
651
652       TopTools_ListIteratorOfListOfShape itL(aListOfShapes);
653       for ( ; itL.More(); itL.Next() ) {
654         TopoDS_Shape aParentShape = itL.Value();
655         TopoDS_Iterator it(aParentShape);
656         for ( ; it.More(); it.Next() ) {
657           TopoDS_Shape aSubShape = it.Value();
658           if (aSubShape.ShapeType() == TopAbs_COMPOUND && !IsManifoldShape(aSubShape) )
659             aNMCompound = TopoDS::Compound(aSubShape);
660           else if (aSubShape.ShapeType() == TopAbs_COMPOUND)
661             aListOfShapes.Append(aSubShape);
662           else 
663             aListOfManifoldShapes.Append(aSubShape);
664         }
665       }
666             
667       // Group manifold topology together.
668       // NOTE: there is no sense that initial Compound structure was lost as
669       //       group mode is set to 0 (no Assemblies are mapped)
670       for ( itL.Initialize(aListOfManifoldShapes); itL.More(); itL.Next() ) {
671         TopoDS_Shape aCurrentManiShape = itL.Value();
672         brepBuilder.Add(aManifoldCompound, aCurrentManiShape);
673       }
674
675     }
676
677     // Process only manifold topology in the current TransferShape invocation.
678     // Invoke TransferShape for non-manifold topology separately (see below)
679     theShape = aManifoldCompound;
680     
681     // List of items to transfer
682     Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
683     // Non-manifold group to pass into TransferShape with each shape from RepItemSeq
684     Handle(TopTools_HSequenceOfShape) NonManifoldGroup = new TopTools_HSequenceOfShape();
685
686     // Transfer Solids to closed Shells. Prepare RepItemSeq & NonManifoldGroup
687     for ( TopoDS_Iterator iter(aNMCompound); iter.More(); iter.Next() ) {
688       TopoDS_Shape aSubShape = iter.Value();
689       if (aSubShape.ShapeType() == TopAbs_SOLID) {
690         for ( TopoDS_Iterator aSubIter(aSubShape); aSubIter.More(); aSubIter.Next() ) {
691           TopoDS_Shell aSubShell = TopoDS::Shell( aSubIter.Value() );
692           aSubShell.Closed(Standard_True);
693           RepItemSeq->Append(aSubShell);
694           NonManifoldGroup->Append(aSubShell);
695         }
696       }
697       else if (!isManifold && (aSubShape.ShapeType() == TopAbs_SHELL) ) {
698         RepItemSeq->Append(aSubShape);
699         NonManifoldGroup->Append(aSubShape);
700       } 
701       else
702         RepItemSeq->Append( iter.Value() );
703     }
704
705     Standard_Integer aNMItemsNb = RepItemSeq->Length();
706      
707     // In case of pure manifold topology do nothing; theShape is processed as usual (see below)
708     if (aNMItemsNb > 0) {
709
710       // Prepare SDR for non-manifold group. This SDR will be linked to NMSSR by means
711       // of TransferShape invocation. SDR is not created if there is no any manifold
712       // topology in the passed Compound. If topology is pure non-manifold, SDR0 (passed)
713       // is used
714       Handle(StepShape_ShapeDefinitionRepresentation) sdr;
715       if (isOnlyNonManifold)
716         sdr = SDR0;
717       else {
718         STEPConstruct_Part SDRTool;
719         SDRTool.MakeSDR( 0, myContext.GetProductName(), myContext.GetAPD()->Application() );
720         sdr = SDRTool.SDRValue();
721       }
722
723       aNMBinder = TransientResult(sdr);
724     
725       // Complete SDR with shape representations.
726       // NOTE: aNMBinder is connected now with this SDR. It will be added to the resulting
727       //       binder in the end of this invocation of TransferShape
728       for (Standard_Integer i = 1; i <= aNMItemsNb; i++) {
729         Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper( FP, RepItemSeq->Value(i) );
730         TransferShape(mapper, sdr, FP, NonManifoldGroup, Standard_False);
731       }
732
733       // Nothing else needed for pure non-manifold topology, return
734       if (isOnlyNonManifold)
735         return aNMBinder;
736    
737     }
738
739   }
740   // [END] Separate manifold topology from non-manifold in group mode 0 (ssv; 18.11.2010)
741
742   // create a list of items to translate
743   Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
744   
745   // PTV 16.09.2002 OCC725 separate shape from solo vertices.
746   if (theShape.ShapeType() == TopAbs_COMPOUND) {
747     Standard_Integer countVrtx = 0;
748     Standard_Integer countSh = 0;
749     TopoDS_Compound aNewShape, aCompOfVrtx;
750     BRep_Builder aB;
751     aB.MakeCompound(aNewShape);
752     aB.MakeCompound(aCompOfVrtx);
753     TopoDS_Iterator anCompIt(theShape);
754     for (; anCompIt.More(); anCompIt.Next()) {
755       TopoDS_Shape aCurSh = anCompIt.Value();
756       if (aCurSh.ShapeType() != TopAbs_VERTEX) {
757         aB.Add(aNewShape, aCurSh);
758         countSh++;
759       }
760       else {
761         aB.Add(aCompOfVrtx, aCurSh);
762         countVrtx++;
763       }
764     }
765     // replace the shapes
766     if (countSh)
767       theShape = aNewShape;
768     if (countVrtx)
769       RepItemSeq->Append(aCompOfVrtx);
770   } 
771   else if (theShape.ShapeType() == TopAbs_VERTEX)
772     RepItemSeq->Append(theShape); // to translate one vertex
773   
774
775   if (theShape.ShapeType() == TopAbs_COMPOUND) {
776     TopExp_Explorer SolidExp, ShellExp, FaceExp;
777     if (mymode != STEPControl_GeometricCurveSet) {
778       for (SolidExp.Init(theShape, TopAbs_SOLID);
779            SolidExp.More();SolidExp.Next()) {
780         RepItemSeq->Append(TopoDS::Solid(SolidExp.Current()));
781       }
782       for (ShellExp.Init(theShape, TopAbs_SHELL, TopAbs_SOLID);
783            ShellExp.More();ShellExp.Next()) {
784         RepItemSeq->Append(TopoDS::Shell(ShellExp.Current()));
785       }
786       
787       for (FaceExp.Init(theShape, TopAbs_FACE, TopAbs_SHELL);
788            FaceExp.More();FaceExp.Next()) {
789         RepItemSeq->Append(TopoDS::Face(FaceExp.Current()));
790       }
791     }
792     else {
793       RepItemSeq->Append(theShape); //:j1
794     }
795     if(mymode == STEPControl_AsIs) {
796       TopExp_Explorer WireExp, EdgeExp;
797       for (WireExp.Init(theShape, TopAbs_WIRE, TopAbs_FACE);
798            WireExp.More();WireExp.Next()) 
799         RepItemSeq->Append(TopoDS::Wire(WireExp.Current()));
800       for (EdgeExp.Init(theShape, TopAbs_EDGE, TopAbs_WIRE);
801            EdgeExp.More();EdgeExp.Next()) 
802         RepItemSeq->Append(TopoDS::Edge(EdgeExp.Current()));
803     }
804     
805   }
806   else if (theShape.ShapeType() == TopAbs_SOLID) {
807     RepItemSeq->Append(TopoDS::Solid(theShape));
808   }
809   else if (theShape.ShapeType() == TopAbs_SHELL) {
810     RepItemSeq->Append(TopoDS::Shell(theShape));
811   }
812   else if (theShape.ShapeType() == TopAbs_FACE) {
813     RepItemSeq->Append(TopoDS::Face(theShape));
814   }
815   else if (mymode != STEPControl_GeometricCurveSet && mymode != STEPControl_AsIs) {
816     FP->AddFail(start,"The Shape is not a SOLID, nor a SHELL, nor a FACE");
817     return binder;
818   }
819   else RepItemSeq->Append (theShape);
820
821   //    COMPUTING 3D TOLERANCE
822   //    Either from Session, or Computed (Least,Average, or Greatest)
823   //    Then given to TopoDSToStep_Tool
824   Standard_Real Tol = UsedTolerance (mytoler,theShape);
825   
826   // Create a STEP-Entity for each TopoDS_Shape  
827   // according to the current StepModelMode
828   
829   Standard_Integer nbs = RepItemSeq->Length();
830   Handle(TColStd_HSequenceOfTransient) ItemSeq = 
831     new TColStd_HSequenceOfTransient();
832
833 //ptv 10.11.00: allow to write empty Compound:  if (GroupMode() >0)
834   ItemSeq->Append (myContext.GetDefaultAxis());
835   STEPControl_StepModelType trmode = mymode;
836   for (Standard_Integer i = 1; i <= nbs; i++) {
837     TopoDS_Shape xShape = RepItemSeq->Value(i);
838  
839     if(mymode == STEPControl_AsIs) {
840       switch(xShape.ShapeType()) {
841         case TopAbs_SOLID :  trmode = STEPControl_ManifoldSolidBrep;break;
842         case TopAbs_SHELL :  trmode = STEPControl_ShellBasedSurfaceModel; break;
843         case TopAbs_FACE : trmode = STEPControl_ShellBasedSurfaceModel;break;
844         default : trmode =STEPControl_GeometricCurveSet; break;
845       }
846     }
847     //:abv 24Jan99 CAX-IF TRJ3: expanded Shape Processing
848 //    TopoDS_Shape aShape = xShape;
849     // eliminate conical surfaces with negative semiangles
850 //    Handle(TopoDSToStep_ConicalSurfModif) CSM = new TopoDSToStep_ConicalSurfModif();
851 //    BRepTools_Modifier CSMT(aShape,CSM);
852 //    if ( CSMT.IsDone() ) aShape = CSMT.ModifiedShape ( aShape );
853 //    // eliminate indirect elementary surfaces
854 //    Handle(TopoDSToStep_DirectModification) DM = new TopoDSToStep_DirectModification();
855 //    BRepTools_Modifier DMT(aShape,DM);
856 //    if ( DMT.IsDone() ) aShape = DMT.ModifiedShape ( aShape );
857 ////    aShape = TopoDSToStep::DirectFaces(xShape);
858     Handle(Standard_Transient) info;
859     Standard_Real maxTol = Interface_Static::RVal("read.maxprecision.val");
860
861     // Fix only manifold shapes, do nothing with non-manifold topology as it is processed separately (ssv; 13.11.2010)
862     TopoDS_Shape aShape;
863     if (isManifold)
864       aShape = XSAlgo::AlgoContainer()->ProcessShape(xShape, Tol, maxTol, 
865                                                     "write.step.resource.name", 
866                                                     "write.step.sequence", info,
867                                                     FP->GetProgress() );
868     else
869       aShape = xShape;
870     
871     // create a STEP entity corresponding to shape
872     Handle(StepGeom_GeometricRepresentationItem) item;
873     switch (trmode)
874       {
875       case STEPControl_ManifoldSolidBrep:
876         {
877           if (aShape.ShapeType() == TopAbs_SOLID) {
878             TopoDS_Solid aSolid = TopoDS::Solid(aShape);
879
880             //:d6 abv 13 Mar 98: if solid has more than 1 shell, 
881             // try to treat it as solid with voids
882             Standard_Integer nbShells = 0;
883             for ( TopoDS_Iterator It ( aSolid ); It.More(); It.Next() ) 
884               if (It.Value().ShapeType() == TopAbs_SHELL) nbShells++;
885             if ( nbShells >1 ) {
886               TopoDSToStep_MakeBrepWithVoids MkBRepWithVoids(aSolid,FP);
887               MkBRepWithVoids.Tolerance() = Tol;
888               if (MkBRepWithVoids.IsDone()) {
889                 item = MkBRepWithVoids.Value();
890               }
891               else nbShells = 1; //smth went wrong; let it will be just Manifold
892             }
893             if ( nbShells ==1 ) {
894
895               TopoDSToStep_MakeManifoldSolidBrep MkManifoldSolidBrep(aSolid,FP);
896               MkManifoldSolidBrep.Tolerance() = Tol;
897               if (MkManifoldSolidBrep.IsDone()) {
898                 item = MkManifoldSolidBrep.Value();
899               }
900             }
901           }
902           else if (aShape.ShapeType() == TopAbs_SHELL) {
903             TopoDS_Shell aShell = TopoDS::Shell(aShape);
904             TopoDSToStep_MakeManifoldSolidBrep MkManifoldSolidBrep(aShell,FP);
905             MkManifoldSolidBrep.Tolerance() = Tol;
906             if (MkManifoldSolidBrep.IsDone()) {
907               item = MkManifoldSolidBrep.Value();
908             }
909           }
910           break;
911         }
912       case STEPControl_BrepWithVoids:
913         {
914           if (aShape.ShapeType() == TopAbs_SOLID) {
915             TopoDS_Solid aSolid = TopoDS::Solid(aShape);
916             TopoDSToStep_MakeBrepWithVoids MkBRepWithVoids(aSolid,FP);
917             MkBRepWithVoids.Tolerance() = Tol;
918             if (MkBRepWithVoids.IsDone()) {
919               item = MkBRepWithVoids.Value();
920             }
921           }
922           break;
923         }
924       case STEPControl_FacetedBrep:
925         {
926           TopoDSToStep_FacetedError facErr = TopoDSToStep_FacetedTool::CheckTopoDSShape(aShape);
927           if (facErr != TopoDSToStep_FacetedDone) {
928             FP->AddFail(start,"Error in Faceted Shape from TopoDS");
929             if (facErr == TopoDSToStep_SurfaceNotPlane) {
930               FP->AddFail(start,"-- The TopoDS_Face is not plane");
931             }
932             else if (facErr == TopoDSToStep_PCurveNotLinear) {
933               FP->AddFail(start,"-- The Face contains non linear PCurves");
934             }
935             return binder;
936           }
937           if (aShape.ShapeType() == TopAbs_SOLID) {
938             TopoDS_Solid aSolid = TopoDS::Solid(aShape);
939             TopoDSToStep_MakeFacetedBrep MkFacetedBrep(aSolid,FP);
940             MkFacetedBrep.Tolerance() = Tol;
941             if (MkFacetedBrep.IsDone()) {
942               item = MkFacetedBrep.Value();
943             }
944           }
945           break;
946         }
947       case STEPControl_FacetedBrepAndBrepWithVoids:
948         {
949           TopoDSToStep_FacetedError facErr = TopoDSToStep_FacetedTool::CheckTopoDSShape(aShape);
950           if (facErr != TopoDSToStep_FacetedDone) {
951             FP->AddFail(start,"Error in Faceted Shape from TopoDS");
952             if (facErr == TopoDSToStep_SurfaceNotPlane) {
953               FP->AddFail(start,"-- The TopoDS_Face is not plane");
954             }
955             else if (facErr == TopoDSToStep_PCurveNotLinear) {
956               FP->AddFail(start,"-- The Face contains non linear PCurves");
957             }
958             return binder;
959           }
960           if (aShape.ShapeType() == TopAbs_SOLID) {
961             TopoDS_Solid aSolid = TopoDS::Solid(aShape);
962             TopoDSToStep_MakeFacetedBrepAndBrepWithVoids 
963               MkFacetedBrepAndBrepWithVoids(aSolid,FP);
964             MkFacetedBrepAndBrepWithVoids.Tolerance() = Tol;
965             if (MkFacetedBrepAndBrepWithVoids.IsDone()) {
966               item = MkFacetedBrepAndBrepWithVoids.Value();
967             }
968           }
969           break;
970         }
971       case STEPControl_ShellBasedSurfaceModel:
972         {
973           if (aShape.ShapeType() == TopAbs_SOLID) {
974             TopoDS_Solid aSolid = TopoDS::Solid(aShape);
975             TopoDSToStep_MakeShellBasedSurfaceModel
976               MkShellBasedSurfaceModel(aSolid, FP);
977             MkShellBasedSurfaceModel.Tolerance() = Tol;
978             if (MkShellBasedSurfaceModel.IsDone()) {
979               item = MkShellBasedSurfaceModel.Value();
980             }
981           }
982           else if (aShape.ShapeType() == TopAbs_SHELL) {
983             TopoDS_Shell aShell = TopoDS::Shell(aShape);
984             // Non-manifold topology is stored via NMSSR containing series of SBSM (ssv; 13.11.2010)
985             TopoDSToStep_MakeShellBasedSurfaceModel MkShellBasedSurfaceModel(aShell, FP);
986             MkShellBasedSurfaceModel.Tolerance() = Tol;
987             if (MkShellBasedSurfaceModel.IsDone()) {
988               item = MkShellBasedSurfaceModel.Value();
989             }
990           }
991           else if (aShape.ShapeType() == TopAbs_FACE) {
992             TopoDS_Face aFace = TopoDS::Face(aShape);
993             TopoDSToStep_MakeShellBasedSurfaceModel
994               MkShellBasedSurfaceModel(aFace, FP);
995             MkShellBasedSurfaceModel.Tolerance() = Tol;
996             if (MkShellBasedSurfaceModel.IsDone()) {
997               item = MkShellBasedSurfaceModel.Value();
998             }
999           }
1000           break;
1001         }
1002       case STEPControl_GeometricCurveSet:
1003         {
1004           TopoDSToStep_MakeGeometricCurveSet MkGeometricCurveSet(aShape,FP);
1005           MkGeometricCurveSet.Tolerance() = Tol;
1006           if (MkGeometricCurveSet.IsDone()) {
1007             item = MkGeometricCurveSet.Value();
1008           }
1009           // PTV 22.08.2002 OCC609 ------------------------- begin --------------------
1010           // modified by PTV 16.09.2002 OCC725
1011           else if (aShape.ShapeType() == TopAbs_COMPOUND || 
1012                    aShape.ShapeType() == TopAbs_VERTEX) {
1013             // it is compund with solo vertices.
1014             Standard_Integer aNbVrtx = 0;
1015             Standard_Integer curNb = 0;
1016             TopExp_Explorer anExp (aShape, TopAbs_VERTEX);
1017             for ( ; anExp.More(); anExp.Next() ) {
1018               if ( anExp.Current().ShapeType() != TopAbs_VERTEX )
1019                 continue;
1020               aNbVrtx++;
1021             }
1022             if ( aNbVrtx ) {
1023               // create new geometric curve set for all vertices
1024               Handle(StepShape_HArray1OfGeometricSetSelect) aGSS =
1025                 new StepShape_HArray1OfGeometricSetSelect(1,aNbVrtx);
1026               Handle(TCollection_HAsciiString) empty = new TCollection_HAsciiString("");
1027               Handle(StepShape_GeometricCurveSet) aGCSet =
1028                 new StepShape_GeometricCurveSet;
1029               aGCSet->SetName(empty);
1030               // iterates on compound with vertices and trances each vertex
1031               for ( anExp.ReInit() ; anExp.More(); anExp.Next() ) {
1032                 TopoDS_Shape aVertex = anExp.Current();
1033                 if ( aVertex.ShapeType() != TopAbs_VERTEX )
1034                   continue;
1035                 curNb++;
1036                 transferVertex (FP, aGSS, aVertex, curNb);
1037               } // end of iteration on compound with vertices.
1038               aGCSet->SetElements(aGSS);
1039               item = aGCSet;
1040             } // end of check that number of vertices is not null
1041           }
1042           // PTV 22.08.2002 OCC609-------------------------  end  --------------------
1043           break;
1044         }
1045       default: break;
1046       }
1047     if ( item.IsNull() ) continue;
1048
1049     // add resulting item to the FP
1050     ItemSeq->Append(item);
1051     Handle(TransferBRep_ShapeMapper) submapper;
1052     if ( xShape.IsSame ( mapper->Value() ) ) 
1053       submapper = Handle(TransferBRep_ShapeMapper)::DownCast ( start );
1054     if ( submapper.IsNull() ) submapper = TransferBRep::ShapeMapper (FP,xShape);
1055     Handle(Transfer_Binder) subbind = FP->Find ( submapper );
1056     if ( subbind.IsNull() ) {
1057       subbind = TransientResult ( item );
1058       FP->Bind ( submapper, subbind );
1059     }
1060     else subbind->AddResult ( TransientResult ( item ) );
1061
1062     //:abv 24Jan99 CAX-IF TRJ3: Update FinderProcess map to take into account shape processing
1063 //    UpdateMap ( xShape, CSMT, DMT, FP );
1064     XSAlgo::AlgoContainer()->MergeTransferInfo(FP, info);
1065   }
1066   
1067   // - Make Shape Representation 
1068   Standard_Integer nCc1 = ItemSeq->Length();
1069   if (nCc1 < 1) {
1070     FP->AddFail(start,"The Shape has not the appropriate type");
1071     return binder;
1072   }
1073   Handle(StepShape_ShapeRepresentation) shapeRep;
1074   if ( theShape.ShapeType() == TopAbs_SHAPE ) { // for external references
1075     shapeRep = new StepShape_ShapeRepresentation;
1076   }
1077   else {
1078     switch (mymode) {
1079     case STEPControl_ManifoldSolidBrep:
1080       shapeRep = new StepShape_AdvancedBrepShapeRepresentation;
1081       break;
1082     case STEPControl_FacetedBrep:
1083       shapeRep = new StepShape_FacetedBrepShapeRepresentation;
1084       break;
1085     // NOTE: STEPControl_AsIs mode is normally used to transfer non-manifold topology.
1086     //       However, as ShellBasedSurfaceModel is used in non-manifold processing
1087     //       internally, STEPControl_ShellBasedSurfaceModel is also adjusted to
1088     //       be able to work with non-manifold cases
1089     case STEPControl_ShellBasedSurfaceModel:
1090       if (isManifold)
1091         shapeRep = new StepShape_ManifoldSurfaceShapeRepresentation;
1092       else {
1093         Standard_Boolean isNewNMSSRCreated;
1094         shapeRep = this->getNMSSRForGroup(shapeGroup, FP, isNewNMSSRCreated);
1095         useExistingNMSSR = !isNewNMSSRCreated;
1096       }
1097       break;
1098     case STEPControl_GeometricCurveSet:
1099       shapeRep = new StepShape_GeometricallyBoundedWireframeShapeRepresentation;
1100       break;
1101     case STEPControl_AsIs :
1102     {
1103       if(nbs == 1) {
1104         if(trmode == STEPControl_ManifoldSolidBrep)
1105           shapeRep = new StepShape_AdvancedBrepShapeRepresentation;
1106         else if(trmode == STEPControl_ShellBasedSurfaceModel)
1107           // Process non-manifold topology separately (ssv; 13.11.2010)
1108           if (isManifold)
1109             shapeRep = new StepShape_ManifoldSurfaceShapeRepresentation;
1110           else {
1111             Standard_Boolean isNewNMSSRCreated;
1112             shapeRep = this->getNMSSRForGroup(shapeGroup, FP, isNewNMSSRCreated);
1113             useExistingNMSSR = !isNewNMSSRCreated;
1114           }
1115         else if(trmode == STEPControl_GeometricCurveSet)
1116           shapeRep = new StepShape_GeometricallyBoundedWireframeShapeRepresentation;
1117         else if(trmode ==STEPControl_FacetedBrep)
1118           shapeRep = new StepShape_FacetedBrepShapeRepresentation; 
1119       }
1120       else shapeRep = new StepShape_ShapeRepresentation;
1121     }
1122       break;
1123     default: break;
1124     }
1125   }
1126   if(shapeRep.IsNull()) {
1127     Handle(Transfer_Binder) resb;
1128     return resb;
1129   }
1130     
1131   Handle(StepRepr_HArray1OfRepresentationItem) items =
1132     new StepRepr_HArray1OfRepresentationItem(1,nCc1);
1133
1134   for (Standard_Integer rep = 1; rep <= nCc1; rep++) {
1135     Handle(StepRepr_RepresentationItem) repit = 
1136       GetCasted(StepRepr_RepresentationItem, ItemSeq->Value(rep));
1137     items->SetValue(rep,repit);
1138   }
1139   Standard_Integer ap = Interface_Static::IVal("write.step.schema");
1140   Transfer_SequenceOfBinder aSeqBindRelation;
1141   if(ap == 3 && nbs > 1) {
1142     Standard_Integer j = 1;
1143     if(items->Value(j)->IsKind(STANDARD_TYPE(StepGeom_Axis2Placement3d))) {
1144       Handle(StepRepr_HArray1OfRepresentationItem) axis =
1145         new StepRepr_HArray1OfRepresentationItem(1,1);
1146       axis->SetValue(1,items->Value(j++));
1147       shapeRep->SetItems(axis);
1148     }
1149     for (; j <= items->Length(); j++) {
1150       
1151       Handle(StepShape_ShapeRepresentation) ShapeRepr1;
1152       if(items->Value(j)->IsKind(STANDARD_TYPE(StepShape_ManifoldSolidBrep)))
1153          ShapeRepr1 = new StepShape_AdvancedBrepShapeRepresentation;
1154       else if(items->Value(j)->IsKind(STANDARD_TYPE(StepShape_ShellBasedSurfaceModel))) 
1155         ShapeRepr1 = new StepShape_ManifoldSurfaceShapeRepresentation;
1156       else if(items->Value(j)->IsKind(STANDARD_TYPE(StepShape_GeometricCurveSet)))
1157         ShapeRepr1 = new StepShape_GeometricallyBoundedWireframeShapeRepresentation;
1158       else if (items->Value(j)->IsKind(STANDARD_TYPE(StepShape_FacetedBrep)))
1159         ShapeRepr1 = new StepShape_FacetedBrepShapeRepresentation;
1160       else ShapeRepr1 = new StepShape_ShapeRepresentation;
1161       
1162       Handle(StepRepr_HArray1OfRepresentationItem) repr1 = new StepRepr_HArray1OfRepresentationItem(1,2);
1163       repr1->SetValue(1,myContext.GetDefaultAxis());
1164       repr1->SetValue(2,items->Value(j));
1165       ShapeRepr1->SetItems(repr1);
1166       STEPConstruct_UnitContext mk1;
1167       mk1.Init(Tol);
1168       ShapeRepr1->SetContextOfItems(mk1.Value());  // la tolerance, voir au debut
1169       ShapeRepr1->SetName (new TCollection_HAsciiString(""));
1170       
1171       Handle(StepRepr_ShapeRepresentationRelationship) aShapeRel = new StepRepr_ShapeRepresentationRelationship;
1172       Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString("");
1173       Handle(TCollection_HAsciiString) aDescr = new TCollection_HAsciiString("");
1174       aShapeRel->SetName(aName);
1175       aShapeRel->SetDescription(aDescr);
1176       aShapeRel->SetRep2(shapeRep);
1177       aShapeRel->SetRep1(ShapeRepr1);
1178       
1179       aSeqBindRelation.Append(TransientResult (aShapeRel));
1180     }
1181   }
1182   else {
1183     if (!useExistingNMSSR)
1184       shapeRep->SetItems(items);
1185     else {
1186       // Add new representation item to the NMSSR's existing collection (ssv; 13.11.2010)
1187       Handle(StepRepr_HArray1OfRepresentationItem) oldItems = shapeRep->Items();
1188       Handle(StepRepr_HArray1OfRepresentationItem) newItems = 
1189         new StepRepr_HArray1OfRepresentationItem(1, oldItems->Length() + 1);
1190       Standard_Integer el = 1;
1191       for (Standard_Integer i = 1; i <= oldItems->Length(); i++)
1192         newItems->SetValue( el++, oldItems->Value(i) );
1193       newItems->SetValue( el, items->Value( items->Length() ) );
1194       shapeRep->SetItems(newItems);
1195     }
1196   }
1197
1198   // init representation
1199   STEPConstruct_UnitContext mk;
1200   mk.Init(Tol);
1201   shapeRep->SetContextOfItems(mk.Value());  // la tolerance, voir au debut
1202   shapeRep->SetName (new TCollection_HAsciiString(""));
1203
1204   // Create SDR (only once for non-manifold group)
1205   if (!useExistingNMSSR) {
1206     SDR0->SetUsedRepresentation (shapeRep);
1207     // create binder for SR and attach to it binder for RepItem (if exists)
1208     Handle(Transfer_Binder) resbind = TransientResult(shapeRep);
1209     binder = FP->Find(start);
1210     if ( ! binder.IsNull() ) {
1211       resbind->AddResult ( binder );
1212       FP->Rebind(start,resbind);
1213       //binder->AddResult ( resbind );
1214       //resbind = binder;
1215     }
1216     for(Standard_Integer k = 1; k <= aSeqBindRelation.Length(); k++)
1217       resbind->AddResult(aSeqBindRelation.Value(k));
1218
1219     // Add SDR for non-manifold topology in group mode 0 (ssv; 18.11.2010)
1220     if ( !aNMBinder.IsNull() )
1221       resbind->AddResult(aNMBinder);
1222
1223     return resbind;
1224   } else return FP->Find(start);
1225
1226 }
1227
1228 //=======================================================================
1229 //function : TransferCompound
1230 //    ####    TRANSFER COMPOUND AS (SUB-)ASSEMBLY
1231 //purpose  : 
1232 //=======================================================================
1233
1234 Handle(Transfer_Binder) STEPControl_ActorWrite::TransferCompound (const Handle(Transfer_Finder)& start,
1235                                                                   const Handle(StepShape_ShapeDefinitionRepresentation)& SDR0,
1236                                                                   const Handle(Transfer_FinderProcess)& FP)
1237 {
1238   Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
1239   Handle(Transfer_Binder) binder;
1240   if (mapper.IsNull()) return binder;
1241   TopoDS_Shape theShape = mapper->Value();
1242
1243   // Inspect non-manifold topology case (ssv; 10.11.2010)
1244   Standard_Boolean isNMMode = Interface_Static::IVal("write.step.nonmanifold");
1245   Standard_Boolean isManifold;
1246   if (isNMMode)
1247     isManifold = IsManifoldShape(theShape);
1248   else
1249     isManifold = Standard_True;
1250
1251   // get a sequence of components (subshapes)
1252   Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
1253   // Prepare a collection for non-manifold group of shapes
1254   Handle(TopTools_HSequenceOfShape) NonManifoldGroup = new TopTools_HSequenceOfShape();
1255   // PTV OCC725 17.09.2002 -- begin --
1256   Standard_Integer nbFreeVrtx = 0;
1257   TopoDS_Compound aCompOfVrtx;
1258   BRep_Builder aB;
1259   aB.MakeCompound(aCompOfVrtx);
1260  
1261   #ifdef DEB
1262   if (!isManifold)
1263     cout << "Exploding Solids to Shells if any..." << endl;
1264   #endif
1265
1266   for (TopoDS_Iterator iter(theShape); iter.More(); iter.Next()) {
1267     TopoDS_Shape aSubShape = iter.Value();
1268     if (aSubShape.ShapeType() != TopAbs_VERTEX) {
1269
1270       // Store non-manifold topology as shells (ssv; 10.11.2010)
1271       if (!isManifold && aSubShape.ShapeType() == TopAbs_SOLID) {
1272         for ( TopoDS_Iterator aSubIter(aSubShape); aSubIter.More(); aSubIter.Next() ) {
1273           TopoDS_Shell aSubShell = TopoDS::Shell( aSubIter.Value() );
1274           aSubShell.Closed(Standard_True);
1275           RepItemSeq->Append(aSubShell);
1276           NonManifoldGroup->Append(aSubShell);
1277         }
1278       } 
1279       else if (!isManifold && (aSubShape.ShapeType() == TopAbs_SHELL) ) {
1280         RepItemSeq->Append(aSubShape);
1281         NonManifoldGroup->Append(aSubShape);
1282       }
1283       else
1284         RepItemSeq->Append(aSubShape);
1285
1286       continue;
1287     }
1288     aB.Add(aCompOfVrtx, iter.Value());
1289     nbFreeVrtx++;
1290   }
1291   if (nbFreeVrtx)
1292     RepItemSeq->Append (aCompOfVrtx);
1293
1294   // PTV OCC725 17.09.2002 -- end --
1295   
1296   // Constitution : liste d axes, le premier est l origine, les suivants : 1
1297   // par sous-item
1298   Handle(StepShape_ShapeRepresentation) shapeRep =
1299     Handle(StepShape_ShapeRepresentation)::DownCast(SDR0->UsedRepresentation());
1300   if ( shapeRep.IsNull() ) {
1301     shapeRep = new StepShape_ShapeRepresentation;
1302     SDR0->SetUsedRepresentation(shapeRep);  // to be used by MakeItem
1303   }
1304   binder = TransientResult(SDR0); // set SDR as first item in order to be found first (but not SDR of subshape!)
1305   binder->AddResult ( TransientResult(shapeRep) );
1306
1307   // translate components
1308   Standard_Integer i, nbs = RepItemSeq->Length();
1309   Handle(TColStd_HSequenceOfTransient) ItemSeq = new TColStd_HSequenceOfTransient();
1310   ItemSeq->Append (myContext.GetDefaultAxis());
1311   myContext.NextLevel();
1312   for ( i = 1; i <= nbs; i ++) {
1313     Handle(TransferBRep_ShapeMapper) subs = TransferBRep::ShapeMapper (FP,RepItemSeq->Value(i));
1314     Handle(StepGeom_Axis2Placement3d) AX1;
1315     
1316     Handle(Transfer_Binder) bnd = TransferSubShape(subs, SDR0, AX1, FP, NonManifoldGroup, isManifold);
1317
1318     if (!AX1.IsNull()) ItemSeq->Append (AX1);
1319     // copy binders so as to have all roots in upper binder, but do not conflict
1320     while ( !bnd.IsNull() ) {
1321       Handle(Transfer_SimpleBinderOfTransient) bx = 
1322         Handle(Transfer_SimpleBinderOfTransient)::DownCast(bnd);
1323       if ( !bx.IsNull() )
1324         // Single SDR is created for a non-manifold group (ssv: 12.11.2010)
1325         if (!isManifold && i > 1)
1326           break;
1327         else
1328           binder->AddResult( TransientResult( bx->Result() ) );
1329       bnd = bnd->NextResult();
1330     }
1331   }
1332   myContext.PrevLevel();
1333
1334   Standard_Integer nsub = ItemSeq->Length();
1335   Handle(StepRepr_HArray1OfRepresentationItem) items =
1336     new StepRepr_HArray1OfRepresentationItem(1,nsub);
1337
1338   // initialize representation
1339   for (Standard_Integer rep = 1; rep <= nsub; rep++)
1340     items->SetValue(rep,GetCasted(StepRepr_RepresentationItem, ItemSeq->Value(rep)));
1341   shapeRep->SetItems(items);
1342   Standard_Real Tol = UsedTolerance (mytoler,theShape);
1343   STEPConstruct_UnitContext mk;
1344   mk.Init(Tol);
1345   shapeRep->SetContextOfItems(mk.Value());  // la tolerance, voir au debut
1346   shapeRep->SetName (new TCollection_HAsciiString(""));
1347
1348   // set it to SDR
1349 //  SDR0->SetUsedRepresentation (shapeRep);
1350
1351   return binder;
1352 }
1353
1354 //=======================================================================
1355 //function : TransferSubShape
1356 //purpose  : 
1357 //=======================================================================
1358
1359 Handle(Transfer_Binder)  STEPControl_ActorWrite::TransferSubShape (const Handle(Transfer_Finder)& start,
1360                                                                    const Handle(StepShape_ShapeDefinitionRepresentation)& SDR0,
1361                                                                    Handle(StepGeom_Axis2Placement3d)& AX1,
1362                                                                    const Handle(Transfer_FinderProcess)& FP,
1363                                                                    const Handle(TopTools_HSequenceOfShape)& shapeGroup,
1364                                                                    const Standard_Boolean isManifold)
1365 {
1366   Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
1367   if (mapper.IsNull()) return NullResult();
1368   TopoDS_Shape shape = mapper->Value();
1369
1370   //   SHAPE EN POSITION VENANT D UN ASSEMBLAGE
1371   //   Il faut alors distinguer la transformation de la shape meme
1372   //   laquelle est consideree a l origine, puis transferee
1373   //   A part, un item decrivant une occurence en position est cree
1374   //   SINON, la shape est prise et transferee telle quelle
1375   TopoDS_Shape sh0 = shape;
1376   gp_Trsf aLoc;
1377   if ( GroupMode() >0) {
1378     TopLoc_Location shloc = shape.Location();
1379     aLoc = shloc.Transformation();
1380     TopLoc_Location shident;
1381     sh0.Location (shident);
1382     mapper = TransferBRep::ShapeMapper(FP,sh0);
1383     mapper->SameAttributes (start);
1384   }
1385
1386   Handle(Transfer_Binder) resbind = FP->Find(mapper);
1387   Handle(StepShape_ShapeDefinitionRepresentation) sdr;
1388 //  Handle(StepShape_ShapeRepresentation) resultat;
1389   STEPConstruct_Part SDRTool;  
1390
1391   // Already SDR and SR available : take them as are
1392   Standard_Boolean iasdr = FP->GetTypedTransient
1393     (resbind,STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation),sdr);
1394   if ( iasdr ) SDRTool.ReadSDR ( sdr ); 
1395   else { 
1396     SDRTool.MakeSDR ( 0, myContext.GetProductName(), myContext.GetAPD()->Application() );
1397     sdr = SDRTool.SDRValue();
1398   }
1399 //  resultat = GetCasted(StepShape_ShapeRepresentation,sdr->UsedRepresentation());
1400
1401   // if shape itself not yet translated, do it now
1402   //:abv 20.05.02: see comment in TransferShape(): added "! iasdr ||"
1403   Handle(Transfer_Binder) resprod = TransientResult(sdr);  //KA - OCC7141(skl 10.11.2004)
1404   if ( ! iasdr || resbind.IsNull() ) {
1405     resbind = TransferShape(mapper, sdr, FP, shapeGroup, isManifold);
1406     Handle(Transfer_Binder) oldbind = FP->Find ( mapper );
1407     if ( ! oldbind.IsNull() && !resbind.IsNull()) resbind->AddResult ( oldbind );
1408     FP->Bind (mapper,resbind);
1409     resprod=resbind; //KA - OCC7141(skl 10.11.2004)
1410   }
1411
1412   // A new resbind may have been produced
1413 //  DeclareAndCast(Transfer_SimpleBinderOfTransient,restrans,resbind);
1414 //  if (restrans.IsNull()) return resbind;
1415 //  FP->GetTypedTransient (resbind,STANDARD_TYPE(StepShape_ShapeRepresentation),resultat);
1416 //  sdr->SetUsedRepresentation(resultat);  // to be used by MakeItem
1417
1418   // make location for assembly placement
1419   GeomToStep_MakeAxis2Placement3d mkax (aLoc);
1420   Handle(StepGeom_Axis2Placement3d) AxLoc = mkax.Value();
1421   AX1 = AxLoc;
1422
1423   // create assembly structures (CDSR, NAUO etc.)
1424   STEPConstruct_Assembly mkitem;
1425   mkitem.Init (sdr,SDR0,myContext.GetDefaultAxis(),AxLoc);
1426   mkitem.MakeRelationship ();
1427   Handle(TColStd_HSequenceOfTransient) roots = myContext.GetRootsForAssemblyLink ( mkitem );
1428
1429   // add roots corresponding to assembly and product structures to binder
1430   //Handle(Transfer_Binder) resprod = resbind; //KA - OCC7141(skl 10.11.2004)
1431   //KA: we need only the current subshape in resprod, since the binder is copied
1432   //    in Transfershape which calls Transfersubshape   [ OCC7141(skl 10.11.2004) ]
1433   if ( ! iasdr ) {
1434     resprod->AddResult ( TransientResult ( SDRTool.SDRValue() ) );
1435     resbind->AddResult ( TransientResult ( SDRTool.SDRValue() ) ); //KA - OCC7141(skl 10.11.2004)
1436     roots->Append ( myContext.GetRootsForPart ( SDRTool ) );
1437   }
1438   for ( Standard_Integer i=1; i <= roots->Length(); i++ ) {
1439     resprod->AddResult ( TransientResult ( roots->Value(i) ) );
1440     resbind->AddResult ( TransientResult ( roots->Value(i) ) );  //KA - OCC7141(skl 10.11.2004)
1441   }
1442   myContext.NextIndex();
1443
1444   //FP->Bind (mapper,resprod); //KA - OCC7141(skl 10.11.2004)
1445
1446   // abv 16.10.00: bind CDSR (et al) to located shape in order to be able to track instances
1447   if ( mapper != start ) {
1448     Handle(Transfer_Binder) bnd = FP->Find ( start );
1449     for ( Standard_Integer j=1; j <= roots->Length(); j++ ) 
1450       if ( bnd.IsNull() ) bnd = TransientResult ( roots->Value(j) );
1451       else bnd->AddResult ( TransientResult ( roots->Value(j) ) );
1452     FP->Bind ( start, bnd );
1453   }
1454   
1455   return resprod;
1456 }