b9c45100b7ff10c2d97e8a23add97aa075e99064
[occt.git] / src / TransferBRep / TransferBRep.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
15 #include <BRep_Builder.hxx>
16 #include <BRep_Tool.hxx>
17 #include <BRepLib.hxx>
18 #include <Interface_Check.hxx>
19 #include <Interface_CheckIterator.hxx>
20 #include <Interface_InterfaceModel.hxx>
21 #include <Interface_Macros.hxx>
22 #include <Message_Msg.hxx>
23 #include <Message_Printer.hxx>
24 #include <Standard_ErrorHandler.hxx>
25 #include <Standard_Failure.hxx>
26 #include <Standard_Transient.hxx>
27 #include <TopExp_Explorer.hxx>
28 #include <TopoDS.hxx>
29 #include <TopoDS_Edge.hxx>
30 #include <TopoDS_HShape.hxx>
31 #include <TopoDS_Iterator.hxx>
32 #include <TopoDS_Shape.hxx>
33 #include <Transfer_Binder.hxx>
34 #include <Transfer_FinderProcess.hxx>
35 #include <Transfer_IteratorOfProcessForTransient.hxx>
36 #include <Transfer_SimpleBinderOfTransient.hxx>
37 #include <Transfer_TransientProcess.hxx>
38 #include <TransferBRep.hxx>
39 #include <TransferBRep_BinderOfShape.hxx>
40 #include <TransferBRep_ShapeBinder.hxx>
41 #include <TransferBRep_ShapeListBinder.hxx>
42 #include <TransferBRep_ShapeMapper.hxx>
43 #include <TransferBRep_TransferResultInfo.hxx>
44
45 #include <stdio.h>
46 //#include <TransferBRep_Analyzer.hxx>
47 static void  ShapeAppend
48   (const Handle(Transfer_Binder)& binder,
49    const Handle(TopTools_HSequenceOfShape)& shapes)
50 {
51   if (binder.IsNull()) return;
52   if (binder->IsKind(STANDARD_TYPE(TransferBRep_BinderOfShape))) {
53     DeclareAndCast(TransferBRep_BinderOfShape,shbind,binder);
54     if (shbind->HasResult()) shapes->Append (shbind->Result());
55   }
56   else if (binder->IsKind(STANDARD_TYPE(TransferBRep_ShapeListBinder))) {
57     DeclareAndCast(TransferBRep_ShapeListBinder,slbind,binder);
58     Standard_Integer i,nb = slbind->NbShapes();
59     for (i = 1; i <= nb; i ++) shapes->Append (slbind->Shape(i));
60   }
61   else if (binder->IsKind(STANDARD_TYPE(Transfer_SimpleBinderOfTransient))) {
62     DeclareAndCast(Transfer_SimpleBinderOfTransient,trbind,binder);
63     DeclareAndCast(TopoDS_HShape,hs,trbind->Result());
64     if (!hs.IsNull()) shapes->Append (hs->Shape());
65   }
66   Handle(Transfer_Binder) nextr = binder->NextResult();
67   if (!nextr.IsNull()) ShapeAppend (nextr,shapes);
68 }
69
70
71     TopoDS_Shape  TransferBRep::ShapeResult
72   (const Handle(Transfer_Binder)& binder)
73 {
74   TopoDS_Shape shape;
75   Handle(Transfer_Binder) bnd = binder;
76   while (!bnd.IsNull()) {
77     DeclareAndCast(TransferBRep_BinderOfShape,shb,bnd);
78     if (!shb.IsNull()) return shb->Result();
79     DeclareAndCast(Transfer_SimpleBinderOfTransient,hsb,bnd);
80     if (!hsb.IsNull()) {
81       Handle(TopoDS_HShape) hsp = GetCasted(TopoDS_HShape,hsb->Result());
82       if (!hsp.IsNull()) return hsp->Shape();
83     }
84     bnd = bnd->NextResult();
85   }
86   return shape;
87 }
88
89     TopoDS_Shape  TransferBRep::ShapeResult
90   (const Handle(Transfer_TransientProcess)& TP,
91    const Handle(Standard_Transient)& ent)
92 {
93   TopoDS_Shape shape;
94   Handle(Transfer_Binder) binder = TP->Find(ent);
95   if (binder.IsNull())  binder = GetCasted (Transfer_Binder,ent);
96   if (!binder.IsNull()) return TransferBRep::ShapeResult (binder);
97   DeclareAndCast(TopoDS_HShape,hsp,ent);
98   if (!hsp.IsNull()) return hsp->Shape();
99   return shape;
100 }
101
102
103     void  TransferBRep::SetShapeResult
104   (const Handle(Transfer_TransientProcess)& TP,
105    const Handle(Standard_Transient)& ent, const TopoDS_Shape& result)
106 {
107   if (result.IsNull() || ent.IsNull() || TP.IsNull()) return;
108   TP->Bind (ent,new TransferBRep_ShapeBinder(result));
109 }
110
111
112     Handle(TopTools_HSequenceOfShape)  TransferBRep::Shapes
113   (const Handle(Transfer_TransientProcess)& TP, const Standard_Boolean roots)
114 {
115   Handle(TopTools_HSequenceOfShape) shapes;
116   if (TP.IsNull()) return shapes;
117   shapes = new TopTools_HSequenceOfShape();
118
119   Transfer_IteratorOfProcessForTransient list = 
120     (roots ? TP->RootResult() : TP->CompleteResult());
121
122   for (list.Start(); list.More(); list.Next()) {
123     Handle(Transfer_Binder) binder = list.Value();
124     ShapeAppend (binder,shapes);
125   }
126   return shapes;
127 }
128
129     Handle(TopTools_HSequenceOfShape)  TransferBRep::Shapes
130   (const Handle(Transfer_TransientProcess)& TP,
131    const Handle(TColStd_HSequenceOfTransient)& list)
132 {
133   Handle(TopTools_HSequenceOfShape) shapes;
134   if (TP.IsNull() && list.IsNull()) return shapes;
135   shapes = new TopTools_HSequenceOfShape();
136
137   Standard_Integer ie, ne = list->Length();
138   for (ie = 1; ie <= ne; ie ++) {
139     Handle(Transfer_Binder) binder = TP->Find(list->Value(ie));
140     ShapeAppend (binder,shapes);
141   }
142
143   return shapes;
144 }
145
146
147     TopAbs_Orientation  TransferBRep::ShapeState
148   (const Handle(Transfer_FinderProcess)& FP, const TopoDS_Shape& shape)
149 {
150   if (FP.IsNull() || shape.IsNull()) return TopAbs_EXTERNAL;
151   Handle(TransferBRep_ShapeMapper) sm = new TransferBRep_ShapeMapper(shape);
152   Standard_Integer index = FP->MapIndex (sm);
153   if (index == 0) return TopAbs_EXTERNAL;
154   sm = Handle(TransferBRep_ShapeMapper)::DownCast(FP->Mapped(index));
155   if (sm.IsNull()) return TopAbs_EXTERNAL;
156   const TopoDS_Shape& mapped = sm->Value();
157 //  l egalite est assumee, on ne teste que l orientation
158   if (mapped.Orientation() != shape.Orientation()) return TopAbs_REVERSED;
159   return TopAbs_FORWARD;
160 }
161
162     Handle(Transfer_Binder)  TransferBRep::ResultFromShape
163   (const Handle(Transfer_FinderProcess)& FP, const TopoDS_Shape& shape)
164 {
165   Handle(Transfer_Binder) res;
166   if (FP.IsNull() || shape.IsNull()) return res;
167   Handle(TransferBRep_ShapeMapper) sm = new TransferBRep_ShapeMapper(shape);
168   return FP->Find (sm);
169 }
170
171     Handle(Standard_Transient)  TransferBRep::TransientFromShape
172   (const Handle(Transfer_FinderProcess)& FP, const TopoDS_Shape& shape)
173 {
174   Handle(Standard_Transient) res;
175   if (FP.IsNull() || shape.IsNull()) return res;
176   Handle(TransferBRep_ShapeMapper) sm = new TransferBRep_ShapeMapper(shape);
177   return FP->FindTransient (sm);
178 }
179
180
181     void  TransferBRep::SetTransientFromShape
182   (const Handle(Transfer_FinderProcess)& FP,
183    const TopoDS_Shape& shape, const Handle(Standard_Transient)& result)
184 {
185   if (FP.IsNull() || shape.IsNull()) return;
186   Handle(TransferBRep_ShapeMapper) sm = new TransferBRep_ShapeMapper(shape);
187   FP->BindTransient (sm,result);
188 }
189
190     Handle(TransferBRep_ShapeMapper)  TransferBRep::ShapeMapper
191   (const Handle(Transfer_FinderProcess)& FP,
192    const TopoDS_Shape& shape)
193 {
194   Handle(TransferBRep_ShapeMapper) mapper = new TransferBRep_ShapeMapper(shape);
195   Standard_Integer index = FP->MapIndex (mapper);
196   if (index == 0) return mapper;
197   return Handle(TransferBRep_ShapeMapper)::DownCast(FP->Mapped(index));
198 }
199
200 // Functions to collect transfer result information
201
202 //=======================================================================
203 //function : FillInfo
204 //purpose  : 
205 //=======================================================================
206
207 static void FillInfo (const Handle(Transfer_Binder)& Binder,
208                       const Handle(Interface_Check)& Check,
209                       const Handle(TransferBRep_TransferResultInfo)& Info)
210 {
211   Standard_Integer R = 0, RW = 0, RF = 0, RWF = 0, NR = 0, NRW = 0, NRF = 0, NRWF = 0;
212   if (Binder->HasResult())
213     if (Check->HasWarnings() && Check->HasFailed()) RWF++;
214     else if (Check->HasWarnings()) RW++;
215     else if (Check->HasFailed()) RF++;
216     else R++;
217   else 
218     if (Check->HasWarnings() && Check->HasFailed()) NRWF++;
219     else if (Check->HasWarnings()) NRW++;
220     else if (Check->HasFailed()) NRF++;
221     else NR++;
222   Info->Result()   += R;  Info->ResultWarning()   += RW;  Info->ResultFail()   += RF;  Info->ResultWarningFail()   += RWF;
223   Info->NoResult() += NR; Info->NoResultWarning() += NRW; Info->NoResultFail() += NRF; Info->NoResultWarningFail() += NRWF;
224 }     
225              
226 //=======================================================================
227 //function : TransferResultInfo
228 //purpose  : 
229 //=======================================================================
230
231  void TransferBRep::TransferResultInfo (const Handle(Transfer_TransientProcess)& TP,
232                                         const Handle(TColStd_HSequenceOfTransient)& EntityTypes,
233                                         Handle(TransferBRep_HSequenceOfTransferResultInfo)& InfoSeq)
234 {
235   // create output Sequence in accordance with required ShapeTypes
236   InfoSeq = new TransferBRep_HSequenceOfTransferResultInfo;
237   if (TP.IsNull() || EntityTypes.IsNull()) return;
238   Standard_Integer SeqLen = EntityTypes->Length();
239   Standard_Integer i; // svv Jan11 2000 : porting on DEC
240   for (i = 1; i <= SeqLen; i++) {
241     InfoSeq->Append (new TransferBRep_TransferResultInfo);
242   }
243   
244   // fill Sequence
245   Standard_Integer NbMapped = TP->NbMapped();
246   for (i = 1; i <= NbMapped; i++) {
247     Handle(Standard_Transient) Entity = TP->Mapped (i);
248
249     Handle(Transfer_Binder) Binder = TP->Find (Entity);
250     if (Binder.IsNull()) continue;
251     const Handle(Interface_Check) Check = Binder->Check ();
252     
253     // find appropriate element in the Sequence
254     for (Standard_Integer index = 1; index <= SeqLen; index++) {
255       if (Entity->IsKind (EntityTypes->Value(index)->DynamicType())) {
256         Handle(TransferBRep_TransferResultInfo) Info = InfoSeq->Value (index);
257         // fill element
258         FillInfo (Binder, Check, Info);
259       }
260     }
261   }
262 }
263
264 //=======================================================================
265 //function : TransferResultInfo
266 //purpose  : 
267 //=======================================================================
268
269  void TransferBRep::TransferResultInfo (const Handle(Transfer_FinderProcess)& FP,
270                                         const Handle(TColStd_HSequenceOfInteger)& ShapeTypes,
271                                         Handle(TransferBRep_HSequenceOfTransferResultInfo)& InfoSeq)
272 {
273   // create output Sequence in accordance with required ShapeTypes
274   InfoSeq = new TransferBRep_HSequenceOfTransferResultInfo;
275   if (FP.IsNull() || ShapeTypes.IsNull()) return;
276   Standard_Integer SeqLen = ShapeTypes->Length();
277   Standard_Integer i; // svv Jan11 2000 : porting on DEC
278   for (i = 1; i <= SeqLen; i++) {
279     InfoSeq->Append (new TransferBRep_TransferResultInfo);
280   }
281   
282   // fill Sequence
283   Standard_Integer NbMapped = FP->NbMapped();
284   for (i = 1; i <= NbMapped; i++) {
285     Handle(TransferBRep_ShapeMapper) Mapper = Handle(TransferBRep_ShapeMapper)::DownCast (FP->Mapped (i));
286     Handle(Transfer_Binder) Binder = FP->Find (Mapper);
287     if (Binder.IsNull()) continue;
288     const Handle(Interface_Check) Check = Binder->Check ();
289     
290     TopoDS_Shape S = Mapper->Value();
291     TopAbs_ShapeEnum ShapeType = S.ShapeType();
292     
293     // find appropriate element in the Sequence
294     for (Standard_Integer index = 1; index <= SeqLen; index++) {
295 //JR/Hp :
296       TopAbs_ShapeEnum CurrentType = (TopAbs_ShapeEnum)ShapeTypes->Value (index);
297 //      TopAbs_ShapeEnum CurrentType = (TopAbs_ShapeEnum)ShapeTypes->Value (index);
298       if (CurrentType == ShapeType || CurrentType == TopAbs_SHAPE) {
299         Handle(TransferBRep_TransferResultInfo) Info = InfoSeq->Value (index);
300         // fill element
301         FillInfo (Binder, Check, Info);
302       }
303     }
304   }
305 }
306
307 //  ########  CHECK LOURD  ########
308
309 // # # # # # #    Enchainement General du CHECK LOURD    # # # # # #
310
311 /*
312 Interface_CheckIterator TransferBRep::BRepCheck
313   (const TopoDS_Shape& shape, const Standard_Integer lev)
314 {
315   Interface_CheckIterator result;
316   TransferBRep_Analyzer ana;
317   ana.Check (shape,lev);
318   return ana.CheckResult ();
319 }
320 */
321
322 //  ###  conversion resultat -> starting
323
324     Interface_CheckIterator  TransferBRep::ResultCheckList
325   (const Interface_CheckIterator& chl,
326    const Handle(Transfer_FinderProcess)& FP,
327    const Handle(Interface_InterfaceModel)& model)
328 {
329   Interface_CheckIterator  nchl;
330   if (FP.IsNull() || model.IsNull()) return nchl;
331   nchl.SetModel(model);
332   for (chl.Start(); chl.More(); chl.Next()) {
333     Standard_Integer num = 0;
334     Handle(Interface_Check) ach = chl.Value();
335     if (ach->NbFails() + ach->NbWarnings() == 0) continue;
336     DeclareAndCast(Transfer_Finder,starting,ach->Entity());
337     Handle(Standard_Transient) ent;
338     if (!starting.IsNull()) ent = FP->FindTransient(starting);
339     if (!ent.IsNull()) {
340       ach->SetEntity(ent);
341       num = model->Number(ent);
342     }
343     nchl.Add (ach,num);
344   }
345   return nchl;
346 }
347
348     Handle(TColStd_HSequenceOfTransient)  TransferBRep::Checked
349   (const Interface_CheckIterator& chl, const Standard_Boolean alsoshapes)
350 {
351   Handle(TColStd_HSequenceOfTransient) ls = new TColStd_HSequenceOfTransient();
352   for (chl.Start(); chl.More(); chl.Next()) {
353     const Handle(Interface_Check) ach = chl.Value();
354     if (ach->NbFails() + ach->NbWarnings() == 0) continue;
355     Handle(Standard_Transient) ent = ach->Entity();
356     if (ent.IsNull()) continue;
357     if (!alsoshapes) {
358       if (ent->IsKind(STANDARD_TYPE(TransferBRep_BinderOfShape)) ||
359           ent->IsKind(STANDARD_TYPE(TopoDS_HShape)) ||
360           ent->IsKind(STANDARD_TYPE(TransferBRep_ShapeMapper)) ) continue;
361     }
362     ls->Append(ent);
363   }
364   return ls;
365 }
366
367     Handle(TopTools_HSequenceOfShape)  TransferBRep::CheckedShapes
368   (const Interface_CheckIterator& chl)
369 {
370   Handle(TopTools_HSequenceOfShape) ls = new TopTools_HSequenceOfShape();
371   for (chl.Start(); chl.More(); chl.Next()) {
372     const Handle(Interface_Check) ach = chl.Value();
373     if (ach->NbFails() + ach->NbWarnings() == 0) continue;
374     Handle(Standard_Transient) ent = ach->Entity();
375     if (ent.IsNull()) continue;
376     DeclareAndCast(TopoDS_HShape,hs,ent);
377     DeclareAndCast(TransferBRep_BinderOfShape,sb,ent);
378     DeclareAndCast(TransferBRep_ShapeMapper,sm,ent);
379     if (!hs.IsNull()) ls->Append (hs->Shape());
380     if (!sb.IsNull()) ls->Append (sb->Result());
381     if (!sm.IsNull()) ls->Append (sm->Value());
382   }
383   return ls;
384 }
385
386     Interface_CheckIterator  TransferBRep::CheckObject
387   (const Interface_CheckIterator& chl, const Handle(Standard_Transient)& obj)
388 {
389   TopoDS_Shape S;
390   DeclareAndCast(TopoDS_HShape,hs,obj);
391   DeclareAndCast(TransferBRep_BinderOfShape,sb,obj);
392   DeclareAndCast(TransferBRep_ShapeMapper,sm,obj);
393   if (!hs.IsNull()) S = hs->Shape();
394   if (!sb.IsNull()) S = sb->Result();
395   if (!sm.IsNull()) S = sm->Value();
396   Interface_CheckIterator nchl;
397
398   for (chl.Start(); chl.More(); chl.Next()) {
399     const Handle(Interface_Check) ach = chl.Value();
400     if (ach->NbFails() + ach->NbWarnings() == 0) continue;
401     Handle(Standard_Transient) ent = ach->Entity();
402     if (ent.IsNull()) continue;
403     if (S.IsNull()) {
404       if (ent == obj) {
405         Handle(Interface_Check) bch(ach);  bch->SetEntity(ent);
406         nchl.Add (bch,0);
407       }
408     } else {
409       TopoDS_Shape sh;
410       DeclareAndCast(TopoDS_HShape,hsh,ent);
411       DeclareAndCast(TransferBRep_BinderOfShape,sbs,ent);
412       DeclareAndCast(TransferBRep_ShapeMapper,smp,ent);
413       if (!hsh.IsNull()) sh = hsh->Shape();
414       if (!sbs.IsNull()) sh = sbs->Result();
415       if (!smp.IsNull()) sh = smp->Value();
416       if (sh == S) {
417         Handle(Interface_Check) bch(ach);  bch->SetEntity(ent);
418         nchl.Add (bch,0);
419       }
420     }
421   }
422   return nchl;
423 }
424
425 //=======================================================================
426 //function : PrintResultInfo
427 //purpose  : 
428 //=======================================================================
429
430 void TransferBRep::PrintResultInfo(const Handle(Message_Printer)& Printer,
431                                    const Message_Msg& Header,
432                                    const Handle(TransferBRep_TransferResultInfo)& ResultInfo,
433                                    const Standard_Boolean printEmpty)
434 {
435   Standard_Integer R, RW, RF, RWF, NR, NRW, NRF, NRWF;
436   R    = ResultInfo->Result();
437   RW   = ResultInfo->ResultWarning();
438   RF   = ResultInfo->ResultFail();
439   RWF  = ResultInfo->ResultWarningFail();
440   NR   = ResultInfo->NoResult();
441   NRW  = ResultInfo->NoResultWarning();
442   NRF  = ResultInfo->NoResultFail();
443   NRWF = ResultInfo->NoResultWarningFail();
444   
445   Message_Msg aLocalHeader = Header;
446   Printer->Send (aLocalHeader, Message_Info, Standard_True);
447   
448   Message_Msg EPMSG30 ("Result.Print.MSG30"); //    Result: %d
449   EPMSG30.Arg (R);
450   Printer->Send (EPMSG30, Message_Info, Standard_True);
451   if(printEmpty || (RW > 0 )) {
452     Message_Msg EPMSG32 ("Result.Print.MSG32"); //    Result + Warning(s): %d
453     EPMSG32.Arg (RW);
454     Printer->Send (EPMSG32, Message_Info, Standard_True);
455   }
456   if(printEmpty || (RF > 0 )) {
457     Message_Msg EPMSG34 ("Result.Print.MSG34"); //    Result + Fail(s): %d
458     EPMSG34.Arg (RF);
459     Printer->Send (EPMSG34, Message_Info, Standard_True);
460   }
461   if(printEmpty || (RWF > 0)) {
462     Message_Msg EPMSG36 ("Result.Print.MSG36"); //    Result + Warning(s) + Fail(s): %d
463     EPMSG36.Arg (RWF);
464     Printer->Send (EPMSG36, Message_Info, Standard_True);
465   }
466   Message_Msg EPMSG38 ("Result.Print.MSG38"); //    TOTAL Result: %d
467   EPMSG38.Arg (R + RW + RF + RWF);
468   Printer->Send (EPMSG38, Message_Info, Standard_True);
469   if(printEmpty || (NR > 0)) {
470     Message_Msg EPMSG40 ("Result.Print.MSG40"); //    No Result: %d
471     EPMSG40.Arg (NR);
472     Printer->Send (EPMSG40, Message_Info, Standard_True);
473   }
474   if(printEmpty || (NRW > 0)) {
475     Message_Msg EPMSG42 ("Result.Print.MSG42"); //    No Result + Warning(s): %d
476     EPMSG42.Arg (NRW);
477     Printer->Send (EPMSG42, Message_Info, Standard_True);
478   }
479   if(printEmpty || (NRF > 0)) {
480     Message_Msg EPMSG44 ("Result.Print.MSG44"); //    No Result + Fail(s): %d
481     EPMSG44.Arg (NRF);
482     Printer->Send (EPMSG44, Message_Info, Standard_True);
483   }
484   if(printEmpty || (NRWF > 0)) {
485     Message_Msg EPMSG46 ("Result.Print.MSG46"); //    No Result + Warning(s) + Fail(s): %d
486     EPMSG46.Arg (NRWF);
487     Printer->Send (EPMSG46, Message_Info, Standard_True);
488   }
489   
490   Message_Msg EPMSG48 ("Result.Print.MSG48"); //    TOTAL No Result: %d
491   EPMSG48.Arg (NR + NRW + NRF + NRWF);
492   Printer->Send (EPMSG48, Message_Info, Standard_True);
493
494 }