GLC_lib  2.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
glc_3dviewcollection.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 
3  This file is part of the GLC-lib library.
4  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
5  http://glc-lib.sourceforge.net
6 
7  GLC-lib is free software; you can redistribute it and/or modify
8  it under the terms of the GNU Lesser General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  GLC-lib is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public License
18  along with GLC-lib; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 
21 *****************************************************************************/
22 
24 
25 
26 #include "glc_3dviewcollection.h"
27 #include "../shading/glc_material.h"
28 #include "../glc_openglexception.h"
29 #include "../shading/glc_selectionmaterial.h"
30 #include "../glc_state.h"
31 #include "../shading/glc_shader.h"
32 #include "../viewport/glc_viewport.h"
33 #include "glc_spacepartitioning.h"
34 
35 #include <QtDebug>
36 
38 // Constructor/Destructor
40 
42 : m_3DViewInstanceHash()
43 , m_SelectedInstances()
44 , m_ShadedPointerViewInstanceHash()
45 , m_ShaderGroup()
46 , m_MainInstances()
47 , m_IsInShowSate(true)
48 , m_UseLod(false)
49 , m_pViewport(NULL)
50 , m_pSpacePartitioning(NULL)
51 , m_UseSpacePartitioning(false)
52 , m_IsViewable(true)
53 {
54 }
55 
57 {
58  // Delete all collection's elements and the collection bounding box
59  clear();
60 }
62 // Set Functions
64 
66 {
67  if (m_ShadedPointerViewInstanceHash.contains(shaderId))
68  {
69  return false;
70  }
71  else
72  {
74  m_ShadedPointerViewInstanceHash.insert(shaderId, pNodeHash);
75  return true;
76  }
77 }
78 
80 {
81  bool result= false;
82  if (m_ShadedPointerViewInstanceHash.contains(shaderId))
83  {
84  // Find node which use the shader
85  QList<GLC_uint> nodeId(m_ShaderGroup.keys(shaderId));
86 
87  // Move these node in the standard hash and remove them from shader group
88  PointerViewInstanceHash* pShaderNodeHash= m_ShadedPointerViewInstanceHash.take(shaderId);
89  for (int i= 0; i < nodeId.size(); ++i)
90  {
91  const GLC_uint id= nodeId[i];
92  GLC_3DViewInstance* pInstance= pShaderNodeHash->value(id);
93 
94  if (!pInstance->isSelected())
95  {
96  m_MainInstances.insert(id, pInstance);
97  }
98  else
99  {
100  m_SelectedInstances.insert(id, pInstance);
101  }
102  m_ShaderGroup.remove(id);
103  }
104  pShaderNodeHash->clear();
105  delete pShaderNodeHash;
106  result= true;
107  }
108  Q_ASSERT(!m_ShadedPointerViewInstanceHash.contains(shaderId));
109  return result;
110 }
111 
113 {
114  bool result= true;
115  HashList::iterator iEntry= m_ShadedPointerViewInstanceHash.begin();
116  QList<GLuint> shaderList;
117  while (iEntry != m_ShadedPointerViewInstanceHash.constEnd())
118  {
119  shaderList.append(iEntry.key());
120  ++iEntry;
121  }
122  const int size= shaderList.size();
123  for (int i=0; i < size; ++i)
124  {
125  result= result && unBindShader(shaderList[i]);
126  }
127  return result;
128 }
129 
131 {
132  bool result= false;
133  const GLC_uint key= node.id();
134  if (m_3DViewInstanceHash.contains(key))
135  {
136  return false;
137  }
138 
139  m_3DViewInstanceHash.insert(key, node);
140  // Create an GLC_3DViewInstance pointer of the inserted instance
141  ViewInstancesHash::iterator iNode= m_3DViewInstanceHash.find(key);
142  GLC_3DViewInstance* pInstance= &(iNode.value());
143  // Chose the hash where instance is
144  if(0 != shaderID)
145  {
146  // Test if shaderId group exist
147  if (m_ShadedPointerViewInstanceHash.contains(shaderID))
148  {
149  m_ShaderGroup.insert(key, shaderID);
150 
151  if(pInstance->isSelected())
152  {
153  m_SelectedInstances.insert(key, pInstance);
154  }
155  else
156  {
157  m_ShadedPointerViewInstanceHash.value(shaderID)->insert(key, pInstance);
158  }
159  result=true;
160  }
161  }
162  else if (!pInstance->isSelected())
163  {
164  m_MainInstances.insert(key, pInstance);
165  result=true;
166  }
167  else
168  {
169  m_SelectedInstances.insert(key, pInstance);
170  result=true;
171  }
172 
173  return result;
174 }
175 
177 {
178  // Test if the specified instance exist
179  Q_ASSERT(m_3DViewInstanceHash.contains(instanceId));
180  // Get the instance shading group
181  const GLuint instanceShadingGroup= shadingGroup(instanceId);
182  // Get a pointer to the instance
183  GLC_3DViewInstance* pInstance= NULL;
184  if (0 == instanceShadingGroup)
185  {
186  // The instance is not in a shading group
187  if (m_MainInstances.contains(instanceId))
188  {
189  pInstance= m_MainInstances.take(instanceId);
190  }
191  else if (m_SelectedInstances.contains(instanceId))
192  {
193  // The instance is selected don't take it
194  pInstance= m_SelectedInstances.value(instanceId);
195  }
196  else
197  {
198  Q_ASSERT(false);
199  }
200  }
201  else
202  {
203  m_ShaderGroup.remove(instanceId);
204  // The instance is in a shading group
205  if (m_SelectedInstances.contains(instanceId))
206  {
207  // The instance is selected don't take it
208  pInstance= m_SelectedInstances.value(instanceId);
209  }
210  else
211  {
212  pInstance= m_ShadedPointerViewInstanceHash.value(instanceShadingGroup)->take(instanceId);
213  }
214 
215  }
216  // Put the instance in specified shading group
217  if (0 != shaderId)
218  {
219  m_ShaderGroup.insert(instanceId, shaderId);
220  if (!pInstance->isSelected())
221  {
222  m_ShadedPointerViewInstanceHash.value(shaderId)->insert(instanceId, pInstance);
223  }
224  }
225  else if (!pInstance->isSelected())
226  {
227  m_MainInstances.insert(instanceId, pInstance);
228  }
229 }
230 
232 {
233  ViewInstancesHash::iterator iNode= m_3DViewInstanceHash.find(Key);
234 
235  if (iNode != m_3DViewInstanceHash.end())
236  { // Ok, the key exist
237 
238  if (selectionSize() > 0)
239  {
240  // if the geometry is selected, unselect it
241  unselect(Key);
242  }
243 
244  m_MainInstances.remove(Key);
245 
246  m_3DViewInstanceHash.remove(Key); // Delete the conteneur
247 
248  //qDebug("GLC_3DViewCollection::removeNode : Element succesfuly deleted");
249  return true;
250 
251  }
252  else
253  { // KO, key doesn't exist
254  return false;
255  }
256 
257 }
258 
260 {
261  // Clear Selected node Hash Table
262  m_SelectedInstances.clear();
263  // Clear the not transparent Hash Table
264  m_MainInstances.clear();
265  // Clear Other Node Hash List
266  HashList::iterator iEntry= m_ShadedPointerViewInstanceHash.begin();
267  while (iEntry != m_ShadedPointerViewInstanceHash.constEnd())
268  {
269  iEntry.value()->clear();
270  delete iEntry.value();
271  iEntry= m_ShadedPointerViewInstanceHash.erase(iEntry);
272  }
273 
275  m_ShaderGroup.clear();
276 
277  // Clear main Hash table
278  m_3DViewInstanceHash.clear();
279 
280  // delete the space partitioning
281  delete m_pSpacePartitioning;
282 }
283 
284 bool GLC_3DViewCollection::select(GLC_uint key, bool primitive)
285 {
286  if (!m_3DViewInstanceHash.contains(key)) return false;
287  //qDebug() << "GLC_Collection::select " << key;
288 
289  GLC_3DViewInstance* pSelectedInstance;
290  ViewInstancesHash::iterator iNode= m_3DViewInstanceHash.find(key);
291  PointerViewInstanceHash::iterator iSelectedNode= m_SelectedInstances.find(key);
292 
293  if ((iNode != m_3DViewInstanceHash.end()) && (iSelectedNode == m_SelectedInstances.end()))
294  { // Ok, the key exist and the node is not selected
295  pSelectedInstance= &(iNode.value());
296  m_SelectedInstances.insert(pSelectedInstance->id(), pSelectedInstance);
297 
298  // Remove Selected Node from is previous collection
299  if (isInAShadingGroup(key))
300  {
301  m_ShadedPointerViewInstanceHash.value(shadingGroup(key))->remove(key);
302  //qDebug() << "remove from shader list";
303  }
304  else
305  {
306  m_MainInstances.remove(key);
307  }
308  pSelectedInstance->select(primitive);
309 
310  //qDebug("GLC_3DViewCollection::selectNode : Element succesfuly selected");
311  return true;
312  }
313  else
314  { // KO, instance allready selected
315  return false;
316  }
317 }
318 
319 void GLC_3DViewCollection::selectAll(bool allShowState)
320 {
321  unselectAll();
322  ViewInstancesHash::iterator iNode= m_3DViewInstanceHash.begin();
323  while (iNode != m_3DViewInstanceHash.end())
324  {
325  GLC_3DViewInstance *pCurrentInstance= &(iNode.value());
326  const GLC_uint instanceId= pCurrentInstance->id();
327 
328  if (allShowState || (pCurrentInstance->isVisible() == m_IsInShowSate))
329  {
330  pCurrentInstance->select(false);
331  m_SelectedInstances.insert(instanceId, pCurrentInstance);
332  m_MainInstances.remove(instanceId);
333  if(isInAShadingGroup(instanceId))
334  {
335  m_ShadedPointerViewInstanceHash.value(shadingGroup(instanceId))->remove(instanceId);
336  }
337  }
338  iNode++;
339  }
340 }
341 
343 {
344  GLC_3DViewInstance* pSelectedNode;
345 
346  PointerViewInstanceHash::iterator iSelectedNode= m_SelectedInstances.find(key);
347 
348  if (iSelectedNode != m_SelectedInstances.end())
349  { // Ok, the key exist and the node is selected
350  iSelectedNode.value()->unselect();
351 
352  pSelectedNode= iSelectedNode.value();
353  m_SelectedInstances.remove(key);
354 
355  // Insert Selected Node to the right collection
356  if (isInAShadingGroup(key))
357  {
358  m_ShadedPointerViewInstanceHash.value(shadingGroup(key))->insert(key, pSelectedNode);
359  }
360  else
361  {
362  m_MainInstances.insert(key, pSelectedNode);
363  }
364 
365  //qDebug("GLC_3DViewCollection::unselectNode : Node succesfuly unselected");
366  return true;
367 
368  }
369  else
370  { // KO, key doesn't exist or node allready selected
371  //qDebug("GLC_3DViewCollection::unselectNode : Node not unselected");
372  return false;
373  }
374 }
375 
377 {
378  PointerViewInstanceHash::iterator iSelectedNode= m_SelectedInstances.begin();
379 
380  while (iSelectedNode != m_SelectedInstances.end())
381  {
382  GLC_3DViewInstance* pInstance= iSelectedNode.value();
383  pInstance->unselect();
384  if (isInAShadingGroup(pInstance->id()))
385  {
386  m_ShadedPointerViewInstanceHash.value(shadingGroup(pInstance->id()))->insert(pInstance->id(), pInstance);
387  }
388  else
389  {
390  m_MainInstances.insert(pInstance->id(), pInstance);
391  }
392 
393  ++iSelectedNode;
394  }
395  // Clear selected node hash table
396  m_SelectedInstances.clear();
397 }
398 
399 void GLC_3DViewCollection::setPolygonModeForAll(GLenum face, GLenum mode)
400 {
401  ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
402 
403  while (iEntry != m_3DViewInstanceHash.constEnd())
404  {
405  iEntry.value().setPolygonMode(face, mode);
406  iEntry++;
407  }
408 
409 }
410 
411 void GLC_3DViewCollection::setVisibility(const GLC_uint key, const bool visibility)
412 {
413  ViewInstancesHash::iterator iNode= m_3DViewInstanceHash.find(key);
414  if (iNode != m_3DViewInstanceHash.end())
415  { // Ok, the key exist
416  iNode.value().setVisibility(visibility);
417  }
418 }
419 
421 {
422  ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
423 
424  while (iEntry != m_3DViewInstanceHash.constEnd())
425  {
426  iEntry.value().setVisibility(true);
427  iEntry++;
428  }
429 }
430 
432 {
433  ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
434 
435  while (iEntry != m_3DViewInstanceHash.constEnd())
436  {
437  iEntry.value().setVisibility(false);
438  iEntry++;
439  }
440 
441 }
442 
444 {
445  Q_ASSERT(NULL != pSpacePartitioning);
446  Q_ASSERT(pSpacePartitioning->collectionHandle() == this);
447 
448  delete m_pSpacePartitioning;
449  m_pSpacePartitioning= pSpacePartitioning;
450 }
451 
453 {
454  delete m_pSpacePartitioning;
455  m_pSpacePartitioning= NULL;
456  m_UseSpacePartitioning= false;
457 
458  ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
459  while (iEntry != m_3DViewInstanceHash.constEnd())
460  {
461  // Update Instance viewable flag
462  iEntry.value().setViewable(GLC_3DViewInstance::FullViewable);
463  iEntry++;
464  }
465 
466 }
467 
469 {
470  if ((NULL != m_pViewport) && m_UseSpacePartitioning && (NULL != m_pSpacePartitioning))
471  {
472  if (m_pViewport->updateFrustum(pMatrix))
474  }
475 }
476 
478 {
479  if (NULL != m_pSpacePartitioning)
480  {
482  }
483 }
484 
486 {
487  if (NULL != m_pSpacePartitioning)
488  {
490  }
491 }
492 
494 {
495  ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
496 
497  while (iEntry != m_3DViewInstanceHash.constEnd())
498  {
499  iEntry.value().setVboUsage(usage);
500  iEntry++;
501  }
502 }
503 
504 QList<GLC_3DViewInstance*> GLC_3DViewCollection::instancesHandle()
505 {
506  QList<GLC_3DViewInstance*> instancesList;
507 
508  ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
509 
510  while (iEntry != m_3DViewInstanceHash.constEnd())
511  {
512  instancesList.append(&(iEntry.value()));
513  iEntry++;
514  }
515  return instancesList;
516 }
517 
519 {
520  QList<GLC_3DViewInstance*> instancesList;
521 
522  ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
523 
524  while (iEntry != m_3DViewInstanceHash.constEnd())
525  {
526  if (iEntry.value().isVisible())
527  {
528  instancesList.append(&(iEntry.value()));
529  }
530  iEntry++;
531  }
532  return instancesList;
533 
534 }
535 
537 {
538  QList<GLC_3DViewInstance*> instancesList;
539 
540  ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
541 
542  while (iEntry != m_3DViewInstanceHash.constEnd())
543  {
544  if (iEntry.value().isVisible() == m_IsInShowSate)
545  {
546  instancesList.append(&(iEntry.value()));
547  }
548  iEntry++;
549  }
550  return instancesList;
551 }
552 
554 {
555  Q_ASSERT(m_3DViewInstanceHash.contains(Key));
556  return &(m_3DViewInstanceHash[Key]);
557 }
558 
560 {
562  // Check if the bounding box have to be updated
563  if (!m_3DViewInstanceHash.isEmpty())
564  {
565  ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
566  while (iEntry != m_3DViewInstanceHash.constEnd())
567  {
568  if(allObject || iEntry.value().isVisible() == m_IsInShowSate)
569  {
570  // Combine Collection BoundingBox with element Bounding Box
571  boundingBox.combine(iEntry.value().boundingBox());
572  }
573  ++iEntry;
574  }
575  }
576  return boundingBox;
577 }
578 
580 {
581  // The number of object to drw
582  int numberOffDrawnHit= 0;
583 
584  // Count the number off instance to draw
585  ViewInstancesHash::const_iterator i= m_3DViewInstanceHash.begin();
586  while (i != m_3DViewInstanceHash.constEnd())
587  {
588  //qDebug() << "transparent";
589  if (i.value().isVisible() == m_IsInShowSate)
590  {
591  ++numberOffDrawnHit;
592  }
593  ++i;
594  }
595  return numberOffDrawnHit;
596 }
597 
598 QList<QString> GLC_3DViewCollection::instanceNamesFromShadingGroup(GLuint shaderId) const
599 {
600  QList<QString> listOfInstanceName;
601  QList<GLC_uint> listOfInstanceNameId= m_ShaderGroup.keys(shaderId);
602  if (!listOfInstanceNameId.isEmpty())
603  {
604  const int size= listOfInstanceNameId.size();
605  for (int i= 0; i < size; ++i)
606  {
607  listOfInstanceName << m_3DViewInstanceHash.value(listOfInstanceNameId[i]).name();
608  }
609  }
610  return listOfInstanceName;
611 }
612 
614 {
615  return m_ShaderGroup.values().toSet().size();
616 }
617 
619 // OpenGL Functions
621 
622 void GLC_3DViewCollection::render(GLuint groupId, glc::RenderFlag renderFlag)
623 {
624  if (!isEmpty() && m_IsViewable)
625  {
626  if (renderFlag == glc::WireRenderFlag)
627  {
628  glEnable(GL_POLYGON_OFFSET_FILL);
629  glPolygonOffset (1.0, 1.0);
630  }
632  {
633  glDisable(GL_BLEND);
635  glDisable(GL_TEXTURE_2D);
636  }
637  else
638  {
640  }
641  glDraw(groupId, renderFlag);
642 
643  if (renderFlag == glc::WireRenderFlag)
644  {
645  glDisable(GL_POLYGON_OFFSET_FILL);
646  }
647  }
648 }
650 {
651  if (!isEmpty() && m_IsViewable)
652  {
654  {
655  glDisable(GL_BLEND);
657  glDisable(GL_TEXTURE_2D);
658  }
659 
660  HashList::iterator iEntry= m_ShadedPointerViewInstanceHash.begin();
661  while (iEntry != m_ShadedPointerViewInstanceHash.constEnd())
662  {
663  glDraw(iEntry.key(), renderFlag);
664  ++iEntry;
665  }
666  }
667 }
668 
670 {
671  // Set render Mode and OpenGL state
672  if (!GLC_State::isInSelectionMode() && (groupId == 0))
673  {
674  if (renderFlag == glc::TransparentRenderFlag)
675  {
676  glEnable(GL_BLEND);
677  glDepthMask(GL_FALSE);
678  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
679 
680  }
681  else
682  {
683  glDisable(GL_BLEND);
684  glDepthMask(GL_TRUE);
685  glEnable(GL_DEPTH_TEST);
686  }
687  }
688 
689  // Normal GLC_3DViewInstance
690  if ((groupId == 0) && !m_MainInstances.isEmpty())
691  {
692  glDrawInstancesOf(&m_MainInstances, renderFlag);
693 
694  }
695  // Selected GLC_3DVIewInstance
696  else if ((groupId == 1) && !m_SelectedInstances.isEmpty())
697  {
699 
701 
703  }
704  // GLC_3DViewInstance with shader
705  else if (!m_ShadedPointerViewInstanceHash.isEmpty())
706  {
707  if(m_ShadedPointerViewInstanceHash.contains(groupId) && !m_ShadedPointerViewInstanceHash.value(groupId)->isEmpty())
708  {
709  PointerViewInstanceHash* pNodeHash= m_ShadedPointerViewInstanceHash.value(groupId);
710 
711  GLC_Shader::use(groupId);
712  glDrawInstancesOf(pNodeHash, renderFlag);
714  }
715  }
716 
717  // Restore OpenGL state
718  if (renderFlag && !GLC_State::isInSelectionMode() && (groupId == 0))
719  {
720  glDisable(GL_BLEND);
721  glDepthMask(GL_TRUE);
722  glEnable(GL_DEPTH_TEST);
723  }
724 }

©2005-2013 Laurent Ribon