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