GLC_lib  2.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
glc_geometry.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 #include "../shading/glc_selectionmaterial.h"
26 #include "../glc_openglexception.h"
27 #include "../glc_state.h"
28 #include "../glc_context.h"
29 #include "glc_geometry.h"
30 
32 // Constructor destructor
34 // Default constructor
35 GLC_Geometry::GLC_Geometry(const QString& name, const bool typeIsWire)
36 : m_GeometryIsValid(false) // By default geometry is invalid
37 , m_pBoundingBox(NULL)
38 , m_MaterialHash()
39 , m_UseColorPerVertex(false)
40 , m_IsSelected(false)
41 , m_WireData()
42 , m_WireColor(Qt::black)
43 , m_LineWidth(1.0f)
44 , m_IsWire(typeIsWire) // the geometry type
45 , m_TransparentMaterialNumber(0)
46 , m_Id(glc::GLC_GenGeomID())
47 , m_Name(name)
48 , m_UseVbo(false)
49 {
50 
51 }
52 // Copy constructor
54 : m_GeometryIsValid(false) // By default geometry is invalid
55 , m_pBoundingBox(NULL)
56 , m_MaterialHash(sourceGeom.m_MaterialHash)
57 , m_UseColorPerVertex(sourceGeom.m_UseColorPerVertex)
58 , m_IsSelected(false)
59 , m_WireData(sourceGeom.m_WireData)
60 , m_WireColor(sourceGeom.m_WireColor)
61 , m_LineWidth(sourceGeom.m_LineWidth)
62 , m_IsWire(sourceGeom.m_IsWire)
63 , m_TransparentMaterialNumber(sourceGeom.m_TransparentMaterialNumber)
64 , m_Id(glc::GLC_GenGeomID())
65 , m_Name(sourceGeom.m_Name)
66 , m_UseVbo(sourceGeom.m_UseVbo)
67 {
68  // Add this mesh to inner material
69  MaterialHash::const_iterator i= sourceGeom.m_MaterialHash.constBegin();
70  while (i != sourceGeom.m_MaterialHash.constEnd())
71  {
72  // update inner material use table
73  i.value()->addGLC_Geom(this);
74  ++i;
75  }
76 
77  if (NULL != sourceGeom.m_pBoundingBox)
78  {
80  }
81 }
82 
83 // Overload "=" operator
85 {
86  if (this != &sourceGeom)
87  {
88  clear();
89  m_GeometryIsValid= false;
90  m_pBoundingBox= NULL;
91  m_MaterialHash= sourceGeom.m_MaterialHash;
93  m_IsSelected= false;
94  m_WireData= sourceGeom.m_WireData;
95  m_WireColor= sourceGeom.m_WireColor;
96  m_LineWidth= sourceGeom.m_LineWidth;
97  m_IsWire= sourceGeom.m_IsWire;
100  m_Name= sourceGeom.m_Name;
101  m_UseVbo= sourceGeom.m_UseVbo;
102  }
103  return *this;
104 }
105 
107 {
108  // delete mesh inner material
109  {
110  MaterialHash::const_iterator i= m_MaterialHash.begin();
111  while (i != m_MaterialHash.constEnd())
112  {
113  // delete the material if necessary
114  i.value()->delGLC_Geom(id());
115  if (i.value()->isUnused()) delete i.value();
116  ++i;
117  }
118  }
119  m_MaterialHash.clear();
120 
121  delete m_pBoundingBox;
122 
123 }
124 
126 // Get Functions
128 
129 // Get number of faces
130 unsigned int GLC_Geometry::faceCount(int) const
131 {
132  return 0;
133 }
134 
135 // Get number of vertex
136 unsigned int GLC_Geometry::VertexCount() const
137 {
138  return 0;
139 }
140 
142 {
143  return 0.0;
144 }
145 
147 // Set Functions
149 // Clear the content of the geometry and makes it empty
151 {
152  clearGeometry();
153 }
154 
155 // Replace the Master material
157 {
158  Q_ASSERT(!m_IsWire);
159  if (!m_MaterialHash.isEmpty())
160  {
161  if (pMaterial != firstMaterial())
162  {
163  // Remove the first material
164  MaterialHash::iterator iMaterial= m_MaterialHash.begin();
165  removeMaterial(iMaterial.value()->id());
166 
167  // Add the new material
168  addMaterial(pMaterial);
169  }
170  }
171  else
172  {
173  addMaterial(pMaterial);
174  }
175 }
178 {
180  MaterialHash::const_iterator iMat= m_MaterialHash.constBegin();
181  while (iMat != m_MaterialHash.constEnd())
182  {
183  if (iMat.value()->isTransparent())
184  {
186  }
187  ++iMat;
188  }
189  if (m_WireColor.alpha() != 255)
190  {
192  }
193 }
194 
195 // Add material to mesh
197 {
198  if (pMaterial != NULL)
199  {
200  const GLC_uint materialID= pMaterial->id();
201  MaterialHash::const_iterator iMaterial= m_MaterialHash.find(materialID);
202  // Check if there is a material at specified index
203  Q_ASSERT(iMaterial == m_MaterialHash.end());
204 
205  // Add this geometry in the material use table
206  pMaterial->addGLC_Geom(this);
207  // Add the Material to Material hash table
208  m_MaterialHash.insert(materialID, pMaterial);
209 
210  // Test if the material is transparent
211  if (pMaterial->isTransparent())
212  {
213  //qDebug() << "Add transparent material";
215  }
216  }
217 }
218 
219 void GLC_Geometry::setWireColor(const QColor& color)
220 {
221  bool previousColorIsTransparent= (m_WireColor.alpha() != 255);
222  bool newColorIsTransparent= (color.alpha() != 255);
223 
224  if (previousColorIsTransparent != newColorIsTransparent)
225  {
226  if (newColorIsTransparent) ++m_TransparentMaterialNumber;
227  else if (previousColorIsTransparent) --m_TransparentMaterialNumber;
228  }
229 
230  m_WireColor= color;
231 }
232 
234 {
236 }
237 
239 {
241 }
242 
244 {
245  m_UseVbo= usage;
246  if (!usage || (usage && GLC_State::vboSupported()))
247  {
249  }
250 }
251 
253 // OpenGL Functions
255 
256 // if the geometry have a texture, load it
258 {
259  MaterialHash::iterator iMaterial= m_MaterialHash.begin();
260 
261  while (iMaterial != m_MaterialHash.constEnd())
262  {
263  // Load texture of mesh materials
264  iMaterial.value()->glLoadTexture();
265  ++iMaterial;
266  }
267 }
268 
269 // Geometry display
270 void GLC_Geometry::render(const GLC_RenderProperties& renderProperties)
271 {
272  Q_ASSERT(!m_IsWire || (m_IsWire && m_MaterialHash.isEmpty()));
273  bool renderWire= (renderProperties.renderingFlag() == glc::TransparentRenderFlag) && isTransparent();
274  renderWire= renderWire || ((renderProperties.renderingFlag() != glc::TransparentRenderFlag) && !isTransparent());
275  if (!m_IsWire || renderWire)
276  {
277  if (m_MaterialHash.isEmpty() && !m_IsWire)
278  {
279  GLC_Material* pMaterial= new GLC_Material();
280  pMaterial->setName(name());
281  addMaterial(pMaterial);
282  }
283 
284  m_IsSelected= renderProperties.isSelected();
285 
286  // Define Geometry's property
288  {
289  glPropGeom(renderProperties);
290  }
291 
292  glDraw(renderProperties);
293 
294  m_IsSelected= false;
295  m_GeometryIsValid= true;
296 
297  // OpenGL error handler
298  GLenum error= glGetError();
299  if (error != GL_NO_ERROR)
300  {
301  GLC_OpenGlException OpenGlException("GLC_Geometry::render " + name(), error);
302  throw(OpenGlException);
303  }
304  }
305 }
306 
307 // Virtual interface for OpenGL Geometry properties.
308 void GLC_Geometry::glPropGeom(const GLC_RenderProperties& renderProperties)
309 {
310  glLineWidth(lineWidth());
311 
312  if(m_IsWire)
313  {
314  glLineWidth(m_LineWidth);
316  if (!renderProperties.isSelected())
317  {
318  // Set polyline colors
319  GLfloat color[4]= {static_cast<float>(m_WireColor.redF()),
320  static_cast<float>(m_WireColor.greenF()),
321  static_cast<float>(m_WireColor.blueF()),
322  static_cast<float>(m_WireColor.alphaF())};
323 
324  glColor4fv(color);
325  }
326  else
327  {
329  }
330  }
331  else if (m_MaterialHash.size() == 1)
332  {
333  GLC_Material* pCurrentMaterial= m_MaterialHash.begin().value();
334  if (pCurrentMaterial->hasTexture())
335  {
337  pCurrentMaterial->glExecute();
338  if (renderProperties.isSelected()) GLC_SelectionMaterial::glExecute();
339  }
340  else
341  {
343  if (renderProperties.isSelected()) GLC_SelectionMaterial::glExecute();
344  else pCurrentMaterial->glExecute();
345  }
346  }
347 }
348 
349 // Remove the specified material from the geometry
351 {
352  Q_ASSERT(containsMaterial(id));
353  // Remove the first material
354  GLC_Material* pMaterial= m_MaterialHash.value(id);
355  // delete the material if necessary
356  pMaterial->delGLC_Geom(this->id());
357  if (pMaterial->isTransparent())
358  {
360  }
361  if (pMaterial->isUnused()) delete pMaterial;
362  m_MaterialHash.remove(id);
363 
364 }
365 
366 // Clear the content of this object and makes it empty
368 {
369  m_GeometryIsValid= false;
370 
371  delete m_pBoundingBox;
372  m_pBoundingBox= NULL;
373 
374  // delete mesh inner material
375  {
376  MaterialHash::const_iterator i= m_MaterialHash.begin();
377  while (i != m_MaterialHash.constEnd())
378  {
379  // delete the material if necessary
380  i.value()->delGLC_Geom(id());
381  if (i.value()->isUnused()) delete i.value();
382  ++i;
383  }
384  }
385  m_MaterialHash.clear();
386 
387  m_UseColorPerVertex= false;
388  m_IsSelected= false;
389  m_WireData.clear();
390  m_IsWire= false;
392  m_Name.clear();
393 
394 }

©2005-2013 Laurent Ribon