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