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