0027961: Visualization - remove unused and no more working OpenGl_AVIWriter
[occt.git] / src / ShapeProcess / ShapeProcess_ShapeContext.cxx
1 // Created on: 2000-08-22
2 // Created by: Andrey BETENEV
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 <BRepTools_Modifier.hxx>
19 #include <Message_ListIteratorOfListOfMsg.hxx>
20 #include <Message_ListOfMsg.hxx>
21 #include <Message_Messenger.hxx>
22 #include <Message_Msg.hxx>
23 #include <ShapeBuild_ReShape.hxx>
24 #include <ShapeExtend_DataMapOfShapeListOfMsg.hxx>
25 #include <ShapeExtend_MsgRegistrator.hxx>
26 #include <ShapeProcess_ShapeContext.hxx>
27 #include <Standard_Type.hxx>
28 #include <TCollection_AsciiString.hxx>
29 #include <TopoDS_Iterator.hxx>
30 #include <TopoDS_Shape.hxx>
31 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
32
33 IMPLEMENT_STANDARD_RTTIEXT(ShapeProcess_ShapeContext,ShapeProcess_Context)
34
35 //=======================================================================
36 //function : ShapeProcess_ShapeContext
37 //purpose  : 
38 //=======================================================================
39 ShapeProcess_ShapeContext::ShapeProcess_ShapeContext (const Standard_CString file,
40                                                       const Standard_CString seq) 
41      : ShapeProcess_Context ( file, seq ), myUntil(TopAbs_FACE)
42 {
43 }
44
45 //=======================================================================
46 //function : ShapeProcess_ShapeContext
47 //purpose  : 
48 //=======================================================================
49
50 ShapeProcess_ShapeContext::ShapeProcess_ShapeContext (const TopoDS_Shape &S,
51                                                       const Standard_CString file,
52                                                       const Standard_CString seq) 
53      : ShapeProcess_Context ( file, seq ), myUntil(TopAbs_FACE)
54 {
55   Init ( S );
56 }
57
58 //=======================================================================
59 //function : Init
60 //purpose  : 
61 //=======================================================================
62
63 void ShapeProcess_ShapeContext::Init (const TopoDS_Shape &S)
64 {
65   myMap.Clear();
66   myMsg = new ShapeExtend_MsgRegistrator;
67   myShape = S;
68   myResult = myShape;//.Nullify();
69 }
70
71 //=======================================================================
72 //function : Shape
73 //purpose  : 
74 //=======================================================================
75
76 const TopoDS_Shape &ShapeProcess_ShapeContext::Shape () const
77 {
78   return myShape;
79 }
80
81 //=======================================================================
82 //function : Result
83 //purpose  : 
84 //=======================================================================
85
86 const TopoDS_Shape &ShapeProcess_ShapeContext::Result () const
87 {
88   return myResult;
89 }
90
91 //=======================================================================
92 //function : Map
93 //purpose  : 
94 //=======================================================================
95
96 const TopTools_DataMapOfShapeShape &ShapeProcess_ShapeContext::Map () const
97 {
98   return myMap;
99 }
100
101 //=======================================================================
102 //function : Messages
103 //purpose  : 
104 //=======================================================================
105
106 Handle(ShapeExtend_MsgRegistrator) &ShapeProcess_ShapeContext::Messages () 
107 {
108   return myMsg;
109 }
110
111 //=======================================================================
112 //function : Messages
113 //purpose  : 
114 //=======================================================================
115
116 const Handle(ShapeExtend_MsgRegistrator) &ShapeProcess_ShapeContext::Messages () const
117 {
118   return myMsg;
119 }
120
121 //=======================================================================
122 //function : SetDetalisation
123 //purpose  : 
124 //=======================================================================
125
126 void ShapeProcess_ShapeContext::SetDetalisation (const TopAbs_ShapeEnum level)
127 {
128   myUntil = level;
129 }
130
131 //=======================================================================
132 //function : GetDetalisation
133 //purpose  : 
134 //=======================================================================
135
136 TopAbs_ShapeEnum ShapeProcess_ShapeContext::GetDetalisation () const
137 {
138   return myUntil;
139 }
140        
141 //=======================================================================
142 //function : SetResult
143 //purpose  : 
144 //=======================================================================
145
146 void ShapeProcess_ShapeContext::SetResult (const TopoDS_Shape &res) 
147 {
148   myResult = res;
149   myMap.Bind ( myShape, myResult );
150 }
151
152 //=======================================================================
153 //function : RecordModification
154 //purpose  : 
155 //=======================================================================
156
157 /*
158 #ifdef OCCT_DEBUG
159 static void DumpMap (const TopTools_DataMapOfShapeShape &map)
160 {
161   cout << "----" << endl;
162   cout << "Map:" << endl;
163   for (TopTools_DataMapIteratorOfDataMapOfShapeShape It (map); It.More(); It.Next()) {
164     TopoDS_Shape S0 = It.Key(), S = It.Value();
165     cout << S0.TShape()->DynamicType()->Name() << "\t" << *(void**)&S0.TShape() << 
166       "     \t->    " << S.TShape()->DynamicType()->Name() << "\t" << *(void**)&S.TShape() << endl;
167   }
168   cout << "----" << endl;
169 }            
170 #endif
171 */
172
173 static void RecModif (const TopoDS_Shape &S, 
174                       const TopTools_DataMapOfShapeShape &repl,
175                       const Handle(ShapeExtend_MsgRegistrator) &msg,
176                       TopTools_DataMapOfShapeShape &map,
177                       Handle(ShapeExtend_MsgRegistrator) &myMsg,
178                       const TopAbs_ShapeEnum until)
179 {
180   TopoDS_Shape r = S;
181   //gka  -modification to keep history for shape with location (OCC21617)
182   TopLoc_Location aShLoc = S.Location();
183   TopLoc_Location aNullLoc;
184   r.Location(aNullLoc);
185
186   if ( map.IsBound ( r ) ) 
187     r = map.Find ( r );
188   if ( ! r.IsNull() ) {
189     TopoDS_Shape res = r;
190     
191     if ( repl.IsBound ( r.Located(aShLoc) ) ) {
192       res = repl.Find (  r.Located(aShLoc) );
193       // it is supposed that map is created for r having FORWARD orientation
194       // hence, if it is reversed, result should be reversed too
195       // INTERNAL or EXTERNAL orientations are not allowed
196       if ( r.Orientation() != TopAbs_FORWARD ) 
197         res.Reverse();
198      
199     }
200     // Treat special case: if S was split, r will be a compound of
201     // resulting shapes, each to be checked separately
202     // It is supposed that repl does not contain such splitting
203     else if ( r.ShapeType() < S.ShapeType() ) {
204       TopoDS_Shape result = r.EmptyCopied();
205       result.Orientation(TopAbs_FORWARD); // protect against INTERNAL or EXTERNAL shapes
206       Standard_Boolean modif = Standard_False;
207       BRep_Builder B;
208       for ( TopoDS_Iterator it(r,Standard_False); it.More(); it.Next() ) {
209         TopoDS_Shape sh = it.Value();
210         if ( repl.IsBound(sh) ) {
211           TopoDS_Shape newsh = repl.Find(sh);
212           if ( ! newsh.IsNull() ) B.Add ( result, newsh );
213           modif = Standard_True;
214         }
215         else B.Add ( result, sh );
216       }
217       if ( modif )
218       {
219         if (result.ShapeType() == TopAbs_WIRE || result.ShapeType() == TopAbs_SHELL)
220           result.Closed (BRep_Tool::IsClosed (result));
221         res = result;
222       }
223     }
224     
225     if ( res != r ) map.Bind ( S.Located(aNullLoc), res );
226   }
227   
228   // update messages (messages must be taken from each level in the substitution map)
229   if ( ! r.IsNull() && ! myMsg.IsNull() && 
230        ! msg.IsNull() && msg->MapShape().Extent() >0 )
231   {
232     const ShapeExtend_DataMapOfShapeListOfMsg& msgmap = msg->MapShape();
233     if ( msgmap.IsBound( r )) {
234       const Message_ListOfMsg &msglist = msgmap.Find (r);
235       for (Message_ListIteratorOfListOfMsg iter (msglist); iter.More(); iter.Next())
236         myMsg->Send ( S, iter.Value(), Message_Warning );
237     }
238     else if ( msgmap.IsBound( S )) {
239       const Message_ListOfMsg &msglist = msgmap.Find (S);
240       for (Message_ListIteratorOfListOfMsg iter (msglist); iter.More(); iter.Next())
241         myMsg->Send ( S, iter.Value(), Message_Warning );
242     }
243   }
244
245   if ( until == TopAbs_SHAPE || S.ShapeType() >= until ) return;
246
247   for ( TopoDS_Iterator it(S); it.More(); it.Next() ) {
248     RecModif ( it.Value(), repl, msg, map, myMsg, until );
249   }
250 }
251
252 void ShapeProcess_ShapeContext::RecordModification (const TopTools_DataMapOfShapeShape &repl,
253                                                     const Handle(ShapeExtend_MsgRegistrator)& msg)
254 {
255   if ( repl.Extent() <=0 ) return;
256   RecModif ( myShape, repl, msg, myMap, myMsg, myUntil );
257   if ( myMap.IsBound(myShape) ) myResult = myMap.Find ( myShape );
258 #ifdef OCCT_DEBUG
259 //  cout << "Modifier: " << endl; DumpMap (myMap);
260 #endif
261 }
262
263 //=======================================================================
264 //function : RecordModification
265 //purpose  : 
266 //=======================================================================
267
268 static void RecModif (const TopoDS_Shape &S, 
269                       const Handle(ShapeBuild_ReShape) &repl,
270                       const Handle(ShapeExtend_MsgRegistrator) &msg,
271                       TopTools_DataMapOfShapeShape &map,
272                       Handle(ShapeExtend_MsgRegistrator) &myMsg,
273                       const TopAbs_ShapeEnum until)
274 {
275   if(S.IsNull())
276     return;
277   //gka  -modification to keep history for shape with location (OCC21617)
278   TopLoc_Location aNullLoc;
279   TopoDS_Shape aS = S.Located(aNullLoc);
280   TopoDS_Shape r = aS;
281  
282   if ( map.IsBound ( r ) ) 
283     r = map.Find ( r );
284   if ( ! r.IsNull() ) {
285     TopoDS_Shape res;
286     if ( repl->Status (r, res, Standard_True ) && res != r ) 
287       map.Bind ( aS, res );
288     
289     // Treat special case: if S was split, r will be a compound of
290     // resulting shapes, recursive procedure should be applied
291     else if ( r.ShapeType() < S.ShapeType() ) {
292       res = repl->Apply ( r, (TopAbs_ShapeEnum)((Standard_Integer)S.ShapeType()+1) );
293       if ( res != r ) map.Bind ( aS, res );
294     }
295   }
296
297   // update messages (messages must be taken from each level in the substitution map)
298   if ( ! r.IsNull() && ! myMsg.IsNull() && 
299        ! msg.IsNull() && msg->MapShape().Extent() >0 ) {
300     TopoDS_Shape cur, next = r;
301     const ShapeExtend_DataMapOfShapeListOfMsg& msgmap = msg->MapShape();
302     if ( msgmap.IsBound( S ))
303       next = S;
304     do {
305       cur = next;
306       if (msgmap.IsBound (cur)) {
307         const Message_ListOfMsg &msglist = msgmap.Find (cur);
308         for (Message_ListIteratorOfListOfMsg iter (msglist); iter.More(); iter.Next()) {
309           myMsg->Send ( S, iter.Value(), Message_Warning );
310         }
311       }
312       next = repl->Value (cur);
313     } while ( ! next.IsNull() && cur != next);
314   }
315
316   if ( until == TopAbs_SHAPE || S.ShapeType() >= until ) return;
317   
318   for ( TopoDS_Iterator it(S,Standard_False/*,Standard_False*/); it.More(); it.Next() ) {
319     RecModif ( it.Value(), repl, msg, map, myMsg, until );
320   }
321 }
322
323 void ShapeProcess_ShapeContext::RecordModification (const Handle(ShapeBuild_ReShape) &repl,
324                                                     const Handle(ShapeExtend_MsgRegistrator) &msg)
325 {
326   
327   RecModif ( myShape, repl, msg, myMap, myMsg, myUntil );
328   if ( myMap.IsBound(myShape) ) 
329   {
330     myResult = myMap.Find ( myShape );
331     myResult.Location(myShape.Location());
332   }
333 #ifdef OCCT_DEBUG
334 //  cout << "ReShape: " << endl; DumpMap (myMap);
335 #endif
336 }
337
338 //=======================================================================
339 //function : RecordModification
340 //purpose  : 
341 //=======================================================================
342
343 void ShapeProcess_ShapeContext::RecordModification (const Handle(ShapeBuild_ReShape) &repl)
344 {
345   Handle(ShapeExtend_MsgRegistrator) msg;
346   RecordModification ( repl, msg );
347 }
348
349 //=======================================================================
350 //function : AddMessage
351 //purpose  : 
352 //=======================================================================
353
354 void ShapeProcess_ShapeContext::AddMessage (const TopoDS_Shape &S,
355                                             const Message_Msg &msg,
356                                             const Message_Gravity grv) 
357 {
358   if ( ! myMsg.IsNull() ) myMsg->Send ( S, msg, grv );
359 }
360
361 //=======================================================================
362 //function : RecordModification
363 //purpose  : 
364 //=======================================================================
365
366 static void ExplodeModifier (const TopoDS_Shape &S, 
367                              const BRepTools_Modifier &repl,
368                              TopTools_DataMapOfShapeShape &map,
369                              const TopAbs_ShapeEnum until)
370 {
371   TopoDS_Shape res = repl.ModifiedShape ( S );
372   
373   if ( res != S ) 
374   {
375    map.Bind ( S, res );
376  }
377   if ( until == TopAbs_SHAPE || S.ShapeType() >= until ) return;
378   for ( TopoDS_Iterator it(S); it.More(); it.Next() ) {
379     ExplodeModifier ( it.Value(), repl, map, until );
380   }
381 }
382
383 void ShapeProcess_ShapeContext::RecordModification (const TopoDS_Shape &S, 
384                                                     const BRepTools_Modifier &repl,
385                                                     const Handle(ShapeExtend_MsgRegistrator)& msg)
386 {
387   TopTools_DataMapOfShapeShape map;
388   ExplodeModifier ( S, repl, map, myUntil );
389   RecordModification ( map, msg );
390 }
391
392 //=======================================================================
393 //function : GetContinuity
394 //purpose  : 
395 //=======================================================================
396
397 Standard_Boolean ShapeProcess_ShapeContext::GetContinuity (const Standard_CString param,
398                                                            GeomAbs_Shape &cont) const
399 {
400   TCollection_AsciiString str;
401   if ( ! GetString ( param, str ) ) return Standard_False;
402   
403   str.LeftAdjust();
404   str.RightAdjust();
405   str.UpperCase();
406   
407   if      ( str.IsEqual ( "C0" ) ) cont = GeomAbs_C0;
408   else if ( str.IsEqual ( "G1" ) ) cont = GeomAbs_G1;
409   else if ( str.IsEqual ( "C1" ) ) cont = GeomAbs_C1;
410   else if ( str.IsEqual ( "G2" ) ) cont = GeomAbs_G2;
411   else if ( str.IsEqual ( "C2" ) ) cont = GeomAbs_C2;
412   else if ( str.IsEqual ( "C3" ) ) cont = GeomAbs_C3;
413   else if ( str.IsEqual ( "CN" ) ) cont = GeomAbs_CN;
414   else return Standard_False;
415   return Standard_True;
416 }
417
418 //=======================================================================
419 //function : ContinuityVal
420 //purpose  : 
421 //=======================================================================
422
423 GeomAbs_Shape ShapeProcess_ShapeContext::ContinuityVal (const Standard_CString param,
424                                                         const GeomAbs_Shape def) const
425 {
426   GeomAbs_Shape val;
427   return GetContinuity ( param, val ) ? val : def;
428 }
429
430 //=======================================================================
431 //function : PrintStatistics
432 //purpose  : 
433 //=======================================================================
434
435 void ShapeProcess_ShapeContext::PrintStatistics () const
436 {
437   Standard_Integer SS = 0, SN = 0, FF = 0, FS = 0, FN = 0;
438   for (TopTools_DataMapIteratorOfDataMapOfShapeShape It (myMap); It.More(); It.Next()) {
439     TopoDS_Shape keyshape = It.Key(), valueshape = It.Value();
440     if (keyshape.ShapeType() == TopAbs_SHELL)
441       if (valueshape.IsNull()) SN++;
442       else SS++;
443     else if (keyshape.ShapeType() == TopAbs_FACE)
444     {
445       if (valueshape.IsNull()) FN++;
446       else if (valueshape.ShapeType() == TopAbs_SHELL) FS++;
447       else FF++;
448     }
449   }
450   
451   // mapping
452   Message_Msg EPMSG100 ("PrResult.Print.MSG100"); //Mapping:
453   Messenger()->Send (EPMSG100, Message_Info);
454   Message_Msg TPMSG50 ("PrResult.Print.MSG50"); //  Shells:
455   Messenger()->Send (TPMSG50, Message_Info);
456   Message_Msg EPMSG110 ("PrResult.Print.MSG110"); //    Result is Shell                 : %d
457   EPMSG110.Arg (SS);
458   Messenger()->Send (EPMSG110, Message_Info);
459   Message_Msg EPMSG150 ("PrResult.Print.MSG150"); //    No Result                       : %d
460   EPMSG150.Arg (SN);
461   Messenger()->Send (EPMSG150.Get(), Message_Info);
462   
463   TCollection_AsciiString tmp110 (EPMSG110.Original()), tmp150  (EPMSG150.Original());
464   EPMSG110.Set (tmp110.ToCString());
465   EPMSG150.Set (tmp150.ToCString());
466
467   Message_Msg TPMSG55 ("PrResult.Print.MSG55"); //  Faces:
468   Messenger()->Send (TPMSG55, Message_Info);
469   Message_Msg EPMSG115 ("PrResult.Print.MSG115"); //    Result is Face                  : %d
470   EPMSG115.Arg (FF);
471   Messenger()->Send (EPMSG115, Message_Info);
472   EPMSG110.Arg (FS);
473   Messenger()->Send (EPMSG110, Message_Info);
474   EPMSG150.Arg (FN);
475   Messenger()->Send (EPMSG150, Message_Info);
476   
477   // preparation ratio
478   Standard_Real SPR = 1, FPR = 1;
479   Standard_Integer STotalR = SS, FTotalR  = FF + FS;
480   Standard_Integer NbS = STotalR + SN, NbF = FTotalR + FN;
481   if (NbS > 0) SPR = 1. * (NbS - SN) / NbS;
482   if (NbF > 0) FPR = 1. * (NbF - FN) / NbF;
483   Message_Msg PMSG200 ("PrResult.Print.MSG200"); //Preparation ratio:
484   Messenger()->Send (PMSG200, Message_Info);
485   Message_Msg PMSG205 ("PrResult.Print.MSG205"); //  Shells: %d per cent
486   PMSG205.Arg ((Standard_Integer) (100. * SPR));
487   Messenger()->Send (PMSG205, Message_Info);
488   Message_Msg PMSG210 ("PrResult.Print.MSG210"); //  Faces : %d per cent
489   PMSG210.Arg ((Standard_Integer) (100. * FPR));
490   Messenger()->Send (PMSG210, Message_Info);
491 }