0023005: Unjustified memory grow during undo/redo operation
[occt.git] / src / NIS / NIS_Drawer.cxx
CommitLineData
7fd59977 1// File: NIS_Drawer.cxx
2// Created: 06.07.07 22:15
3// Author: Alexander GRIGORIEV
4// Copyright: Open Cascade 2007
5
6#include <NIS_Drawer.hxx>
ffe2bea7 7#include <NIS_View.hxx>
7fd59977 8#include <NIS_InteractiveContext.hxx>
9#include <NIS_InteractiveObject.hxx>
10#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
11#include <Standard_TypeMismatch.hxx>
12#include <Standard_NoSuchObject.hxx>
13
14IMPLEMENT_STANDARD_HANDLE (NIS_Drawer, Standard_Transient)
15IMPLEMENT_STANDARD_RTTIEXT (NIS_Drawer, Standard_Transient)
16
17//=======================================================================
18//function : NIS_Drawer
19//purpose : Destructor
20//=======================================================================
21
22NIS_Drawer::~NIS_Drawer ()
23{
24 NCollection_List<NIS_DrawList*>::Iterator anIter (myLists);
25 for (; anIter.More(); anIter.Next())
26 delete anIter.Value();
27}
28
29//=======================================================================
30//function : Assign
31//purpose :
32//=======================================================================
33
34void NIS_Drawer::Assign (const Handle_NIS_Drawer& theOther)
35{
36 if (theOther->IsKind(DynamicType()) == Standard_False)
37 Standard_TypeMismatch::Raise ("NIS_Drawer::Assign");
ffe2bea7
A
38 myIniId = theOther->myIniId;
39 myObjPerDrawer = theOther->myObjPerDrawer;
40 myTransparency = theOther->myTransparency;
7fd59977 41}
42
43//=======================================================================
44//function : HashCode
45//purpose :
46//=======================================================================
47
48Standard_Integer NIS_Drawer::HashCode(const Standard_Integer theN) const
49{
ffe2bea7
A
50 Standard_Integer aKey = ::HashCode (DynamicType(), theN);
51 aKey += (myIniId / myObjPerDrawer);
52 return ((aKey & 0x7fffffff) % theN) + 1;
7fd59977 53}
54
55//=======================================================================
56//function : IsEqual
57//purpose :
58//=======================================================================
59
60Standard_Boolean NIS_Drawer::IsEqual (const Handle_NIS_Drawer& theOther) const
61{
62 Standard_Boolean aResult (Standard_False);
63 if (theOther.IsNull() == Standard_False)
64 if (DynamicType() == theOther->DynamicType())
ffe2bea7
A
65 if (theOther->myIniId/theOther->myObjPerDrawer == myIniId/myObjPerDrawer)
66 aResult = Standard_True;
67
68 if (aResult)
69 if (fabs(myTransparency - theOther->myTransparency) > 0.01)
70 aResult = Standard_False;
71
7fd59977 72 return aResult;
73}
74
75//=======================================================================
76//function : BeforeDraw
77//purpose : Called before Draw(), once per group of interactive objects.
78//=======================================================================
79
80void NIS_Drawer::BeforeDraw (const DrawType, const NIS_DrawList&)
81{
82}
83
84//=======================================================================
85//function : AfterDraw
86//purpose : Called after Draw(), once per group of interactive objects.
87//=======================================================================
88
89void NIS_Drawer::AfterDraw (const DrawType, const NIS_DrawList&)
90{
91}
92
ffe2bea7
A
93//=======================================================================
94//function : UpdateExListId
95//purpose :
96//=======================================================================
97
98void NIS_Drawer::UpdateExListId (const Handle_NIS_View& theView) const
99{
100 if (theView.IsNull()) {
101 if (myCtx) {
102 if (myCtx->myViews.IsEmpty() == Standard_False) {
103 const Handle(NIS_View)& aView = myCtx->myViews.First();
104 NCollection_List<NIS_DrawList *>::Iterator anIterL(myLists);
105 for (; anIterL.More(); anIterL.Next()) {
106 NIS_DrawList * const pList = anIterL.Value();
107 pList->ClearListID(aView);
108 }
109 }
110 }
111 } else {
112 NCollection_List<NIS_DrawList *>::Iterator anIterL(myLists);
113 for (; anIterL.More(); anIterL.Next()) {
114 NIS_DrawList * const pList = anIterL.Value();
115 if (pList->GetView() == theView) {
116 pList->ClearListID(theView);
117 break;
118 }
119 }
120 }
121}
122
7fd59977 123//=======================================================================
124//function : redraw
125//purpose :
126//=======================================================================
127
128void NIS_Drawer::redraw (const DrawType theType,
129 const Handle_NIS_View& theView)
130{
131 if (myCtx &&
132 myMapID.IsEmpty() == Standard_False &&
133 theView.IsNull() == Standard_False)
134 {
135 NCollection_List<NIS_DrawList*>::Iterator anIter (myLists);
136 for (; anIter.More(); anIter.Next()) {
137 NIS_DrawList& aDrawList = * anIter.ChangeValue();
ffe2bea7
A
138 const Handle_NIS_View& aView = aDrawList.GetView();
139 if (aView == theView || aView.IsNull()) {
7fd59977 140 if (aDrawList.IsUpdated(theType)) {
ffe2bea7
A
141 // Get the IDs of objects concerned
142 TColStd_PackedMapOfInteger mapObj;
143 mapObj.Intersection (myCtx->myMapObjects[theType], myMapID);
144#ifndef ARRAY_LISTS
145 // Release the list that is no more in use
146 if (mapObj.IsEmpty() && theType != Draw_DynHilighted) {
147 aDrawList.ClearListID(theType);
148 break;
149 }
150#endif
7fd59977 151 aDrawList.BeginPrepare(theType);
ffe2bea7 152 prepareList (theType, aDrawList, mapObj);
7fd59977 153 aDrawList.EndPrepare(theType);
154 }
ffe2bea7
A
155 if (aDrawList.GetListID(theType) > 0)
156 aDrawList.Call(theType);
7fd59977 157 break;
158 }
159 }
160 }
161}
162
163//=======================================================================
164//function : SetUpdated
165//purpose :
166//=======================================================================
167
168void NIS_Drawer::SetUpdated (const DrawType theType) const
169{
170 NCollection_List<NIS_DrawList*>::Iterator anIter (myLists);
171 for (; anIter.More(); anIter.Next()) {
172 NIS_DrawList& aDrawList = * anIter.ChangeValue();
173 aDrawList.SetUpdated (theType);
174 }
175 const_cast<Bnd_B3f&>(myBox).Clear();
176}
177
178//=======================================================================
179//function : SetUpdated
180//purpose :
181//=======================================================================
182
183void NIS_Drawer::SetUpdated (const DrawType theType1,
184 const DrawType theType2) const
185{
186 NCollection_List<NIS_DrawList*>::Iterator anIter (myLists);
187 for (; anIter.More(); anIter.Next()) {
188 NIS_DrawList& aDrawList = * anIter.ChangeValue();
189 aDrawList.SetUpdated (theType1);
190 aDrawList.SetUpdated (theType2);
191 }
192 const_cast<Bnd_B3f&>(myBox).Clear();
193}
194
195//=======================================================================
196//function : SetUpdated
197//purpose :
198//=======================================================================
199
200
201void NIS_Drawer::SetUpdated (const DrawType theType1,
202 const DrawType theType2,
203 const DrawType theType3) const
204{
205 NCollection_List<NIS_DrawList*>::Iterator anIter (myLists);
206 for (; anIter.More(); anIter.Next()) {
207 NIS_DrawList& aDrawList = * anIter.ChangeValue();
208 aDrawList.SetUpdated (theType1);
209 aDrawList.SetUpdated (theType2);
210 aDrawList.SetUpdated (theType3);
211 }
212 const_cast<Bnd_B3f&>(myBox).Clear();
213}
214
ffe2bea7
A
215//=======================================================================
216//function : SetUpdated
217//purpose :
218//=======================================================================
219
220
221void NIS_Drawer::SetUpdated (const DrawType theType1,
222 const DrawType theType2,
223 const DrawType theType3,
224 const DrawType theType4) const
225{
226 NCollection_List<NIS_DrawList*>::Iterator anIter (myLists);
227 for (; anIter.More(); anIter.Next()) {
228 NIS_DrawList& aDrawList = * anIter.ChangeValue();
229 aDrawList.SetUpdated (theType1);
230 aDrawList.SetUpdated (theType2);
231 aDrawList.SetUpdated (theType3);
232 aDrawList.SetUpdated (theType4);
233 }
234 const_cast<Bnd_B3f&>(myBox).Clear();
235}
236
7fd59977 237//=======================================================================
238//function : SetDynamicHilighted
239//purpose :
240//=======================================================================
241
242void NIS_Drawer::SetDynamicHilighted
243 (const Standard_Boolean isHilighted,
244 const Handle_NIS_InteractiveObject& theObj,
245 const Handle_NIS_View& theView)
246{
247 if (myCtx && theObj.IsNull() == Standard_False) {
248 NCollection_List<NIS_DrawList*>::Iterator anIter (myLists);
249 if (theView.IsNull()) {
250 for (; anIter.More(); anIter.Next()) {
251 NIS_DrawList& aDrawList = * anIter.ChangeValue();
252 aDrawList.SetDynHilighted (isHilighted, theObj);
253 aDrawList.SetUpdated (Draw_DynHilighted);
254 }
255 theObj->myIsDynHilighted = isHilighted;
256 } else
257 for (; anIter.More(); anIter.Next()) {
258 NIS_DrawList& aDrawList = * anIter.ChangeValue();
ffe2bea7
A
259 const Handle(NIS_View)& aView = aDrawList.GetView();
260 if (aView == theView || aView.IsNull()) {
7fd59977 261 aDrawList.SetDynHilighted (isHilighted, theObj);
262 theObj->myIsDynHilighted = isHilighted;
263 aDrawList.SetUpdated (Draw_DynHilighted);
264 }
265 }
266 }
267}
268
269//=======================================================================
270//function : removeObject
271//purpose :
272//=======================================================================
273
274void NIS_Drawer::removeObject (const NIS_InteractiveObject * theObj,
ffe2bea7 275 const Standard_Boolean isUpdateViews)
7fd59977 276{
277 const Standard_Integer anID = theObj->ID();
278 myMapID.Remove (anID);
279 // Stop dynamic hilighting if it has been activated
280 if (theObj->IsDynHilighted())
281 SetDynamicHilighted (Standard_False, theObj);
ffe2bea7
A
282 if (myMapID.IsEmpty()) {
283 UpdateExListId(NULL);
0f524ba0 284 // Remove the drawer from context.
285 myCtx->myDrawers.Remove(this);
ffe2bea7 286 }
7fd59977 287 // Set Updated for the draw type.
ffe2bea7 288 else if (theObj->IsHidden() == Standard_False && isUpdateViews)
7fd59977 289 SetUpdated (theObj->DrawType());
290}
291
292//=======================================================================
293//function : addObject
294//purpose :
295//=======================================================================
296
297void NIS_Drawer::addObject (const NIS_InteractiveObject * theObj,
ffe2bea7 298 const Standard_Boolean isShareList,
7fd59977 299 const Standard_Boolean isUpdateViews)
300{
301 myMapID.Add (theObj->ID());
302
303 // Fill the drawer (if new) with DrawList instances for available Views.
304 if ( myLists.IsEmpty())
305 {
ffe2bea7
A
306 if (isShareList)
307 myLists.Append (createDefaultList(NULL));
308 else {
309 NCollection_List<Handle_NIS_View>::Iterator anIter(GetContext()->myViews);
310 for (; anIter.More(); anIter.Next())
311 myLists.Append (createDefaultList(anIter.Value()));
312 }
7fd59977 313 }
314
315 if (theObj->IsHidden() == Standard_False && isUpdateViews)
316 SetUpdated (theObj->DrawType());
317}
318
319//=======================================================================
320//function : GetBox
321//purpose :
322//=======================================================================
323
324const Bnd_B3f& NIS_Drawer::GetBox (const NIS_View * pView) const
325{
326 if (myBox.IsVoid()) {
327 if (myCtx) {
328 TColStd_MapIteratorOfPackedMapOfInteger anIter;
329 if (pView == 0L)
330 anIter.Initialize (myMapID);
331 else {
332 NCollection_List<NIS_DrawList*>::Iterator anIterL (myLists);
333 for (; anIterL.More(); anIterL.Next()) {
334 NIS_DrawList& aDrawList = * anIterL.ChangeValue();
ffe2bea7
A
335 const Handle(NIS_View)& aView = aDrawList.GetView();
336 if (aView.IsNull() || aView.operator->() == pView)
7fd59977 337 break;
338 }
339 if (anIterL.More())
340 anIter.Initialize (myMapID);
341 }
342
343 for (; anIter.More(); anIter.Next()) {
344 const Handle(NIS_InteractiveObject)& anObj =
345 myCtx->GetObject(anIter.Key());
346 if (anObj.IsNull() == Standard_False)
347 if (anObj->IsHidden() == Standard_False)
348 const_cast<Bnd_B3f&>(myBox).Add (anObj->GetBox());
349 }
350 }
351 }
352 return myBox;
353}
354
355
356//=======================================================================
357//function : prepareList
358//purpose :
359//=======================================================================
ffe2bea7
A
360void NIS_Drawer::prepareList(const NIS_Drawer::DrawType theType,
361 const NIS_DrawList& theDrawList,
362 const TColStd_PackedMapOfInteger& mapObj)
7fd59977 363{
364 if (!myCtx)
365 return;
366
367 // Dynamic hilighting is treated in a separate loop because the hilighted
368 // instances are contained in the special list rather than in the Context
369 if (theType == NIS_Drawer::Draw_DynHilighted) {
370 NCollection_List<Handle_NIS_InteractiveObject>::Iterator
371 anIter (theDrawList.DynHilightedList());
ffe2bea7 372 if (anIter.More()) {
7fd59977 373 BeforeDraw (theType, theDrawList);
ffe2bea7
A
374 for (; anIter.More(); anIter.Next())
375 Draw (anIter.Value(), NIS_Drawer::Draw_DynHilighted, theDrawList);
7fd59977 376 AfterDraw (theType, theDrawList);
377 }
378 } else {
379 // The common part of two maps (objects for this draw type & objects in
380 // the current Drawer) is used for updating the presentation.
7fd59977 381 TColStd_MapIteratorOfPackedMapOfInteger anIter (mapObj);
382 if (anIter.More()) {
383 BeforeDraw (theType, theDrawList);
384 for (; anIter.More(); anIter.Next()) {
385 const Handle(NIS_InteractiveObject)& anObj =
386 myCtx->GetObject(anIter.Key());
387 if (anObj.IsNull() == Standard_False)
388 if (anObj->IsHidden() == Standard_False)
389 Draw (anObj, theType, theDrawList);
390 }
391 AfterDraw (theType, theDrawList);
392 }
393 }
394}
395
396//=======================================================================
397//function : createDefaultList
398//purpose :
399//=======================================================================
400NIS_DrawList* NIS_Drawer::createDefaultList
401 (const Handle_NIS_View& theView) const
402{
ffe2bea7 403 return new NIS_DrawList(theView);
7fd59977 404}