0028715: Invalid shape produced by reading of attached STEP file. Regression from...
[occt.git] / src / XSAlgo / XSAlgo_AlgoContainer.cxx
1 // Created on: 2000-01-19
2 // Created by: data exchange team
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <BRep_Builder.hxx>
18 #include <BRep_Tool.hxx>
19 #include <BRepBuilderAPI_MakeEdge.hxx>
20 #include <Geom2d_Curve.hxx>
21 #include <Geom_Curve.hxx>
22 #include <Geom_Surface.hxx>
23 #include <gp_Pnt.hxx>
24 #include <gp_Pnt2d.hxx>
25 #include <Interface_Static.hxx>
26 #include <Message_ListIteratorOfListOfMsg.hxx>
27 #include <Message_ListOfMsg.hxx>
28 #include <Message_Msg.hxx>
29 #include <Message_ProgressIndicator.hxx>
30 #include <Resource_Manager.hxx>
31 #include <ShapeAlgo.hxx>
32 #include <ShapeAlgo_AlgoContainer.hxx>
33 #include <ShapeAlgo_ToolContainer.hxx>
34 #include <ShapeAnalysis_Edge.hxx>
35 #include <ShapeBuild_Edge.hxx>
36 #include <ShapeBuild_ReShape.hxx>
37 #include <ShapeCustom.hxx>
38 #include <ShapeExtend_DataMapOfShapeListOfMsg.hxx>
39 #include <ShapeExtend_MsgRegistrator.hxx>
40 #include <ShapeFix_Edge.hxx>
41 #include <ShapeFix_Shape.hxx>
42 #include <ShapeProcess.hxx>
43 #include <ShapeProcess_ShapeContext.hxx>
44 #include <Standard_ErrorHandler.hxx>
45 #include <Standard_Failure.hxx>
46 #include <Standard_Transient.hxx>
47 #include <Standard_Type.hxx>
48 #include <TopExp.hxx>
49 #include <TopoDS.hxx>
50 #include <TopoDS_Edge.hxx>
51 #include <TopoDS_Face.hxx>
52 #include <TopoDS_Iterator.hxx>
53 #include <TopoDS_Shape.hxx>
54 #include <TopoDS_Vertex.hxx>
55 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
56 #include <TopTools_DataMapOfShapeShape.hxx>
57 #include <Transfer_FinderProcess.hxx>
58 #include <Transfer_TransientListBinder.hxx>
59 #include <Transfer_TransientProcess.hxx>
60 #include <TransferBRep.hxx>
61 #include <TransferBRep_ShapeBinder.hxx>
62 #include <TransferBRep_ShapeMapper.hxx>
63 #include <UnitsMethods.hxx>
64 #include <XSAlgo_AlgoContainer.hxx>
65 #include <XSAlgo_ToolContainer.hxx>
66 #include <TopExp_Explorer.hxx>
67
68 IMPLEMENT_STANDARD_RTTIEXT(XSAlgo_AlgoContainer,Standard_Transient)
69
70 //=======================================================================
71 //function : XSAlgo_AlgoContainer
72 //purpose  : 
73 //=======================================================================
74 XSAlgo_AlgoContainer::XSAlgo_AlgoContainer()
75 {
76   myTC = new XSAlgo_ToolContainer;
77 }
78
79 //=======================================================================
80 //function : PrepareForTransfer
81 //purpose  : 
82 //=======================================================================
83
84 void XSAlgo_AlgoContainer::PrepareForTransfer() const
85 {
86   UnitsMethods::SetCasCadeLengthUnit ( Interface_Static::IVal("xstep.cascade.unit") );
87 }
88
89 //=======================================================================
90 //function : ProcessShape
91 //purpose  : 
92 //=======================================================================
93
94 TopoDS_Shape XSAlgo_AlgoContainer::ProcessShape (const TopoDS_Shape& shape,
95                                                  const Standard_Real Prec,
96                                                  const Standard_Real maxTol,
97                                                  const Standard_CString prscfile,
98                                                  const Standard_CString pseq,
99                                                  Handle(Standard_Transient)& info,
100                                                  const Handle(Message_ProgressIndicator)& progress,
101                                                  const Standard_Boolean NonManifold) const
102 {
103   if ( shape.IsNull() ) return shape;
104   
105   Handle(ShapeProcess_ShapeContext) context = Handle(ShapeProcess_ShapeContext)::DownCast(info);
106   if ( context.IsNull() )
107   {
108     Standard_CString rscfile = Interface_Static::CVal(prscfile);
109     if (!rscfile)
110       rscfile = prscfile;
111     context = new ShapeProcess_ShapeContext(shape, rscfile);
112     context->SetDetalisation(TopAbs_EDGE);
113     if ( !progress.IsNull() )
114       context->SetProgress(progress);
115   }
116   context->SetNonManifold(NonManifold);
117   info = context;
118   
119   Standard_CString seq = Interface_Static::CVal ( pseq );
120   if ( ! seq ) seq = pseq;
121   
122   // if resource file is not loaded or does not define <seq>.exec.op, 
123   // do default fixes
124   Handle(Resource_Manager) rsc = context->ResourceManager();
125   TCollection_AsciiString str ( seq );
126   str += ".exec.op";
127   if ( ! rsc->Find ( str.ToCString() ) ) {
128 #ifdef OCCT_DEBUG
129     {
130       static Standard_Integer time = 0;
131       if ( ! time )
132         cout << "Warning: XSAlgo_AlgoContainer::ProcessShape(): Sequence " << str.ToCString() << 
133                 " is not defined in " << prscfile << " resource; do default processing" << endl;
134       time++;
135     }
136 #endif
137     // if reading, do default ShapeFix
138     if ( ! strncmp ( pseq, "read.", 5 ) ) {
139       try {
140         OCC_CATCH_SIGNALS
141         Handle(ShapeExtend_MsgRegistrator) msg = new ShapeExtend_MsgRegistrator;
142         Handle(ShapeFix_Shape) sfs = ShapeAlgo::AlgoContainer()->ToolContainer()->FixShape();
143         sfs->Init ( shape );
144         sfs->SetMsgRegistrator ( msg );
145         sfs->SetPrecision ( Prec );
146         sfs->SetMaxTolerance ( maxTol );
147         sfs->FixFaceTool()->FixWireTool()->FixSameParameterMode() = Standard_False;
148         sfs->FixSolidTool()->CreateOpenSolidMode() = Standard_False;
149         sfs->Perform(progress);
150
151         TopoDS_Shape S = sfs->Shape();
152         if ( ! S.IsNull() && S != shape ) {
153           context->RecordModification ( sfs->Context(), msg );
154           context->SetResult ( S );
155         }
156       }
157       catch (Standard_Failure const& anException) {
158 #ifdef OCCT_DEBUG
159         cout << "Error: XSAlgo_AlgoContainer::ProcessShape(): Exception in ShapeFix::Shape" << endl;
160         anException.Print(cout); cout << endl;
161 #endif
162         (void)anException;
163       }
164       return context->Result();
165     }
166     // for writing, define default sequence of DirectFaces
167     else if ( ! strncmp ( pseq, "write.", 6 ) ) {
168       rsc->SetResource ( str.ToCString(), "DirectFaces" );
169     }
170   }
171   
172   // Define runtime tolerances and do Shape Processing 
173   rsc->SetResource ( "Runtime.Tolerance", Prec );
174   rsc->SetResource ( "Runtime.MaxTolerance", maxTol );
175
176   if ( !ShapeProcess::Perform(context, seq) )
177     return shape; // return original shape
178
179   return context->Result();
180 }
181                                                   
182 //=======================================================================
183 //function : PerformFixShape
184 //purpose  : 
185 //=======================================================================
186
187 /*
188 TopoDS_Shape XSAlgo_AlgoContainer::PerformFixShape(const TopoDS_Shape& S,
189                                                       const Handle(Transfer_TransientProcess)& TP,
190                                                       const Standard_Real Prec,
191                                                       const Standard_Real MaxTol) const
192 {
193   if ( S.IsNull() ) return S;
194   
195   TopoDS_Shape shape = S;
196   // fixing shape
197   try {
198     OCC_CATCH_SIGNALS
199     Handle(ShapeFix_Shape) sfs = ShapeAlgo::AlgoContainer()->ToolContainer()->FixShape();
200     sfs->Init ( S );
201     sfs->SetMsgRegistrator ( new ShapeExtend_MsgRegistrator );
202     sfs->SetPrecision ( Prec );
203     sfs->SetMaxTolerance ( MaxTol );
204     sfs->FixFaceTool()->FixWireTool()->FixSameParameterMode() = Standard_False;
205     sfs->Perform();
206
207     shape = sfs->Shape();
208     
209     // to be removed when messages come
210     if ( shape == S || shape.IsNull() ) return S;
211     
212     // update map to reflect the substitutions
213     Handle(ShapeBuild_ReShape) context = sfs->Context();
214     const ShapeExtend_DataMapOfShapeListOfMsg& msgmap = 
215       Handle(ShapeExtend_MsgRegistrator)::DownCast (sfs->MsgRegistrator())->MapShape();
216     for ( Standard_Integer i=1; i <= TP->NbMapped(); i++ ) {
217       Handle(Transfer_Binder) bnd = TP->MapItem ( i );
218       Handle(TransferBRep_ShapeBinder) sb = Handle(TransferBRep_ShapeBinder)::DownCast ( bnd );
219       if ( sb.IsNull() || sb->Result().IsNull() ) continue;
220       
221       TopoDS_Shape orig = sb->Result();
222       
223       // update messages (messages must be taken from each level in the substitution map)
224       TopoDS_Shape cur, next = orig;
225       do {
226         cur = next;
227         Message_ListOfMsg msglist;
228         if (msgmap.IsBound (cur)) {
229           msglist = msgmap.Find (cur);
230           for (Message_ListIteratorOfListOfMsg iter (msglist); iter.More(); iter.Next()) {
231             const Message_Msg& msg = iter.Value();
232             sb->AddWarning (msg.Value(), msg.Original());
233           }
234         }
235         next = context->Value (cur);
236       } while (cur != next);
237
238       // update shapes
239       TopoDS_Shape res;
240       if ( ! context->Status ( orig, res, Standard_True ) ) continue;
241
242       sb->SetResult ( res );
243     }
244   }
245   catch (Standard_Failure) {
246 #ifdef OCCT_DEBUG
247     cout << "Error: XSAlgo_AlgoContainer::PerformFixShape(): Exception in ShapeFix::Shape" << endl;
248 #endif
249   }   
250   return shape;
251 }
252 */
253
254 // ============================================================================
255 // Method  : MakeEdgeOnCurve
256 // Purpose : for CheckPCurve
257 // ============================================================================
258
259 static TopoDS_Edge MakeEdgeOnCurve(const TopoDS_Edge edge)
260 {
261   TopoDS_Edge result;
262   //BRep_Builder B; // B not used - see below (skl)
263   Handle(Geom_Curve) C3d;
264   ShapeAnalysis_Edge sae;
265   Standard_Real cf, cl;
266   if (!sae.Curve3d (edge, C3d, cf, cl, Standard_False )) 
267     return result;
268   gp_Pnt PV1 = C3d->Value(cf);
269   gp_Pnt PV2 = C3d->Value(cl);
270   BRepBuilderAPI_MakeEdge mkEdge(C3d, PV1, PV2, cf, cl);
271 //:S4136  Standard_Real tol = BRep_Tool::Tolerance (edge);
272   ShapeBuild_Edge SBE;          //skl 10.07.2001
273   SBE.SetRange3d(mkEdge,cf,cl); //skl 10.07.2001
274   result = mkEdge.Edge();
275 //:S4136  B.UpdateEdge(result,tol);
276   return result;
277 }
278
279 //=======================================================================
280 //function : CheckPCurve
281 //purpose  : 
282 //=======================================================================
283
284 Standard_Boolean XSAlgo_AlgoContainer::CheckPCurve (const TopoDS_Edge& E,
285                                                     const TopoDS_Face& face,
286                                                     const Standard_Real preci,
287                                                     const Standard_Boolean isSeam) const
288 {
289   Standard_Real w1, w2;  
290   Handle(Geom2d_Curve) thePC;
291   ShapeAnalysis_Edge sae;
292   if ( ! sae.PCurve (E, face, thePC, w1, w2, Standard_False ) ) {
293     return Standard_False;
294   }
295
296   // Check for pcurve longer than surface
297   Handle(Geom_Surface) surf = BRep_Tool::Surface(face);
298   Standard_Real UF,UL,VF,VL;
299   surf->Bounds (UF,UL,VF,VL);
300   gp_Pnt2d PUV1, PUV2;
301   PUV1 = thePC->Value(w1);
302   PUV2 = thePC->Value(w2);
303   //    Multi-periodique ? mieux vaut jeter (attention aux valeurs infinies)
304   Standard_Real DU = Abs (PUV1.X() - PUV2.X());
305   Standard_Real DV = Abs (PUV1.Y() - PUV2.Y());
306   if ( DU/8. > (UL/6. - UF/6.) || DV/8. > (VL/6. - VF/6.) ) {
307     ShapeBuild_Edge().RemovePCurve(E,face);
308 #ifdef OCCT_DEBUG
309     cout<<"Removing pcuve periodic"<<endl;
310 #endif      
311     return Standard_False;
312   }
313
314   // Second Check : 2D and 3D consistency (if the Pcurve has not been 
315   //                dropped)
316   //  On verifie aussi qu on ne s enroule pas trop ...
317   //  ex. : UVV en DEGRES sur une surface en RADIANS, recalee = 57 tours !
318
319   Handle(Geom_Curve) C3d;
320   Standard_Real cf1, cl1;
321   sae.Curve3d (E, C3d, cf1, cl1, Standard_False );
322
323   gp_Pnt P1 = surf->Value(PUV1.X(), PUV1.Y());
324   gp_Pnt P2 = surf->Value(PUV2.X(), PUV2.Y());
325   TopoDS_Vertex V1 = TopExp::FirstVertex(E);
326   TopoDS_Vertex V2 = TopExp::LastVertex(E);
327   gp_Pnt PV1 = ( C3d.IsNull() ? BRep_Tool::Pnt(V1) : C3d->Value(cf1) );
328   gp_Pnt PV2 = ( C3d.IsNull() ? BRep_Tool::Pnt(V2) : C3d->Value(cl1) );
329   Standard_Real Dist11 = PV1.Distance(P1), Dist22 = PV2.Distance(P2);
330     
331   if (!((Dist11 <= preci) && (Dist22 <= preci))) {
332     ShapeBuild_Edge().RemovePCurve(E,face);
333 #ifdef OCCT_DEBUG
334     cout<<"Removing pcurve points"<<endl;
335 #endif      
336     return Standard_False;
337   }
338
339   //
340   // pdn checking deviation between pcurve and 3D curve
341   //
342   
343   // Make temporary edge for analysis
344   if ( C3d.IsNull() ) return Standard_False;
345   TopoDS_Edge edge = MakeEdgeOnCurve(E);
346   
347   // fill it with pcurve(s)
348   BRep_Builder B;
349   Handle(Geom2d_Curve) seamPC;
350   if ( isSeam ) {
351     Standard_Real f, l;
352     TopoDS_Shape REdge = E.Reversed() ;
353     if ( ! sae.PCurve ( TopoDS::Edge ( REdge ), 
354                         face, seamPC, f, l, Standard_False ) ||
355          seamPC == thePC ) 
356       seamPC = Handle(Geom2d_Curve)::DownCast ( thePC->Copy() );
357     B.UpdateEdge ( edge, thePC, seamPC, face, 0.);
358   }
359   else B.UpdateEdge ( edge, thePC, face, 0.);
360   B.Range(edge,face,w1,w2);
361   B.SameRange(edge, Standard_False );
362   //:S4136
363   Standard_Integer SPmode = Interface_Static::IVal("read.stdsameparameter.mode");
364   if ( SPmode ) 
365     B.SameParameter (edge, Standard_False );
366
367   // call FixSP to see what it will do
368   Handle(ShapeFix_Edge) sfe = new ShapeFix_Edge;
369   sfe->FixSameParameter(edge);
370   Standard_Real tol = BRep_Tool::Tolerance (edge);
371   //    Standard_Real tolV1 = BRep_Tool::Tolerance(TopExp::FirstVertex(edge));
372   //    Standard_Real tolV2 = BRep_Tool::Tolerance(TopExp::LastVertex(edge));                          
373   Standard_Boolean sr = BRep_Tool::SameRange ( edge );
374   Standard_Boolean sp = BRep_Tool::SameParameter ( edge );
375   
376   // if result is not nice, try to call projection and take the best
377   if ( tol > Min ( 1., 2.*preci ) || ! sr ) {
378     //pdn trying to recompute pcurve 
379     TopoDS_Edge edgePr = MakeEdgeOnCurve(E);
380     sfe->FixAddPCurve(edgePr, face, isSeam, preci);
381     sfe->FixSameParameter(edgePr);
382     Standard_Real tolPr = BRep_Tool::Tolerance (edgePr);
383     //pdn choose the best pcurve
384     if ( tolPr < tol || ! sr ) {
385       //        tolV1 = BRep_Tool::Tolerance(TopExp::FirstVertex(edgePr));
386       //        tolV2 = BRep_Tool::Tolerance(TopExp::LastVertex(edgePr));
387       sr = BRep_Tool::SameRange ( edgePr );
388       sp = BRep_Tool::SameParameter ( edgePr );
389       tol = tolPr;
390       edge = edgePr;
391     }
392   }
393   
394   // get corrected pcurve from the temporary edge, and put to original
395   sae.PCurve ( edge, face, thePC, w1, w2, Standard_False );
396   if ( isSeam ) {
397     Standard_Real f, l;
398     TopoDS_Shape REdge = edge.Reversed();
399     sae.PCurve ( TopoDS::Edge ( REdge ), face, seamPC, f, l, Standard_False );
400     if ( E.Orientation() == TopAbs_REVERSED ) //:abv 14.11.01: coneEl.sat loop
401       B.UpdateEdge ( E, seamPC, thePC, face, tol );
402     else 
403       B.UpdateEdge ( E, thePC, seamPC, face, tol );
404   }
405   else B.UpdateEdge ( E, thePC, face, tol );
406
407   B.UpdateVertex(V1,tol);
408   B.UpdateVertex(V2,tol);
409   B.Range(E,face, w1, w2);
410   if(BRep_Tool::SameRange(E))
411     B.SameRange( E, sr );
412   if(BRep_Tool::SameParameter(E))
413     B.SameParameter ( E, sp );
414   
415   return Standard_True;
416 }
417
418 //=======================================================================
419 //function : MergeTransferInfo
420 //purpose  : 
421 //=======================================================================
422
423 void XSAlgo_AlgoContainer::MergeTransferInfo(const Handle(Transfer_TransientProcess)& TP,
424                                                 const Handle(Standard_Transient) &info,
425                                                 const Standard_Integer startTPitem) const
426 {
427   Handle(ShapeProcess_ShapeContext) context = Handle(ShapeProcess_ShapeContext)::DownCast ( info );
428   if ( context.IsNull() ) return;
429
430   const TopTools_DataMapOfShapeShape &map = context->Map();
431   Handle(ShapeExtend_MsgRegistrator) msg = context->Messages();
432   if ( map.Extent() <=0 && ( msg.IsNull() || msg->MapShape().Extent() <=0 ) )
433     return;
434
435   Standard_Integer i = ( startTPitem >0 ? startTPitem : 1 );
436   for ( ; i <= TP->NbMapped(); i++ )
437   {
438     Handle(Transfer_Binder) bnd = TP->MapItem ( i );
439     Handle(TransferBRep_ShapeBinder) sb = Handle(TransferBRep_ShapeBinder)::DownCast ( bnd );
440     if ( sb.IsNull() || sb->Result().IsNull() ) continue;
441
442     TopoDS_Shape orig = sb->Result();
443
444     if ( map.IsBound ( orig ) )
445     {
446       sb->SetResult ( map.Find ( orig ) );
447     }
448     else if ( !orig.Location().IsIdentity() )
449     {
450       TopLoc_Location aNullLoc;
451       TopoDS_Shape atmpSh = orig.Located(aNullLoc);
452       if ( map.IsBound ( atmpSh ) ) sb->SetResult ( map.Find ( atmpSh ) );
453     }
454     else
455     {
456       // Some of edges may be modified.
457       BRepTools_ReShape aReShape;
458       Standard_Boolean hasModifiedEdges = Standard_False;
459       TopExp_Explorer anExpSE(orig, TopAbs_EDGE);
460
461       // Remember modifications.
462       for( ; anExpSE.More() ; anExpSE.Next() )
463       {
464         if (  map.IsBound ( anExpSE.Current() ) )
465         {
466           hasModifiedEdges = Standard_True;
467           TopoDS_Shape aModifiedShape = map.Find( anExpSE.Current() );
468           aReShape.Replace(anExpSE.Current(), aModifiedShape);
469         }
470       }
471
472       // Apply modifications and store result in binder.
473       if (hasModifiedEdges)
474       {
475         TopoDS_Shape aRes = aReShape.Apply(orig);
476         sb->SetResult ( aRes );
477       }
478     }
479
480       
481     // update messages
482     if ( ! msg.IsNull() ) {
483       const ShapeExtend_DataMapOfShapeListOfMsg& msgmap = msg->MapShape();
484       if ( msgmap.IsBound (orig) ) {
485         const Message_ListOfMsg &msglist = msgmap.Find (orig);
486         for (Message_ListIteratorOfListOfMsg iter (msglist); iter.More(); iter.Next()) {
487           const Message_Msg& mess = iter.Value();
488           sb->AddWarning (TCollection_AsciiString(mess.Value()).ToCString(),
489                           TCollection_AsciiString(mess.Original()).ToCString());
490         }
491       }
492     }
493   }
494 }
495
496 //=======================================================================
497 //function : MergeTransferInfo
498 //purpose  : 
499 //=======================================================================
500
501 void XSAlgo_AlgoContainer::MergeTransferInfo(const Handle(Transfer_FinderProcess)& FP,
502                                                 const Handle(Standard_Transient) &info) const
503 {
504   Handle(ShapeProcess_ShapeContext) context = Handle(ShapeProcess_ShapeContext)::DownCast ( info );
505   if ( context.IsNull() ) return;
506
507   const TopTools_DataMapOfShapeShape &map = context->Map();
508   TopTools_DataMapIteratorOfDataMapOfShapeShape ShapeShapeIterator(map);
509   Handle(ShapeExtend_MsgRegistrator) msg = context->Messages();
510
511   for ( ; ShapeShapeIterator.More(); ShapeShapeIterator.Next() ) {
512
513     TopoDS_Shape orig = ShapeShapeIterator.Key(), res = ShapeShapeIterator.Value();
514     Handle(TransferBRep_ShapeMapper) resMapper = TransferBRep::ShapeMapper ( FP, res );
515     Handle(Transfer_Binder) resBinder = FP->Find ( resMapper );
516     
517     if (resBinder.IsNull()) {
518       resBinder = new TransferBRep_ShapeBinder(res);
519       //if <orig> shape was splitted, put entities corresponding to new shapes
520       // into Transfer_TransientListBinder.
521       if ( orig.ShapeType() > res.ShapeType() ) {
522         TopoDS_Shape sub;
523         Handle(Transfer_TransientListBinder) TransientListBinder = new Transfer_TransientListBinder;
524         for (TopoDS_Iterator it(res); it.More(); it.Next()) {
525           Handle(Transfer_Finder) subMapper = TransferBRep::ShapeMapper ( FP, it.Value());
526           if (subMapper.IsNull()) continue;
527
528           Handle(Standard_Transient) tr = FP->FindTransient ( subMapper );
529           if (tr.IsNull()) continue;
530           TransientListBinder->AddResult(tr);
531           sub = it.Value();
532         }
533         if ( TransientListBinder->NbTransients() == 1 ) resBinder = new TransferBRep_ShapeBinder(sub);
534         else if ( TransientListBinder->NbTransients() > 1 ) {
535           resBinder->AddResult(TransientListBinder);
536 //        resBinder->SetNext(TransientListBinder, Standard_True);
537 #ifdef OCCT_DEBUG
538           cout<<"Info: TransientListBinder created for splitted shape"<<endl;
539         } 
540         else {
541           cout<<"Warning: XSAlgo_AlgoContainer::MergeTransferInfo() "
542             <<"No results were found for splitted shape. "<<endl;
543           //<<"Transfer_FinderProcess->NbMapped() = "<<FP->NbMapped()<<endl;
544 #endif    
545         }
546       }
547     }
548     
549     Handle(TransferBRep_ShapeMapper) origMapper= TransferBRep::ShapeMapper ( FP, orig);
550     Handle(Transfer_Binder) origBinder = FP->Find ( origMapper );
551     if ( origBinder.IsNull() ) {
552       FP->Bind(origMapper, resBinder);
553     }
554     else {
555       origBinder->AddResult ( resBinder );
556     }
557     
558     // update messages
559     if ( ! msg.IsNull() ) {
560       const ShapeExtend_DataMapOfShapeListOfMsg& msgmap = msg->MapShape();
561       if ( msgmap.IsBound (orig) ) {
562         const Message_ListOfMsg &msglist = msgmap.Find (orig);
563         for (Message_ListIteratorOfListOfMsg iter (msglist); iter.More(); iter.Next()) {
564           const Message_Msg& mess = iter.Value();
565           resBinder->AddWarning (TCollection_AsciiString(mess.Value()).ToCString(),
566                                  TCollection_AsciiString(mess.Original()).ToCString());
567         }
568       }
569     }
570   }
571 }