glc_geometry.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
00005  http://glc-lib.sourceforge.net
00006 
00007  GLC-lib is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU Lesser General Public License as published by
00009  the Free Software Foundation; either version 3 of the License, or
00010  (at your option) any later version.
00011 
00012  GLC-lib is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU Lesser General Public License for more details.
00016 
00017  You should have received a copy of the GNU Lesser General Public License
00018  along with GLC-lib; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 *****************************************************************************/
00022 
00024 
00025 #include "../shading/glc_selectionmaterial.h"
00026 #include "../glc_openglexception.h"
00027 #include "../glc_state.h"
00028 #include "glc_geometry.h"
00029 
00031 // Constructor destructor
00033 // Default constructor
00034 GLC_Geometry::GLC_Geometry(const QString& name, const bool typeIsWire)
00035 : m_GeometryIsValid(false)      // By default geometry is invalid
00036 , m_pBoundingBox(NULL)
00037 , m_MaterialHash()
00038 , m_UseColorPerVertex(false)
00039 , m_IsSelected(false)
00040 , m_WireData()
00041 , m_WireColor(Qt::black)
00042 , m_LineWidth(1.0f)
00043 , m_IsWire(typeIsWire)          // the geometry type
00044 , m_TransparentMaterialNumber(0)
00045 , m_Id(glc::GLC_GenGeomID())
00046 , m_Name(name)
00047 {
00048 
00049 }
00050 // Copy constructor
00051 GLC_Geometry::GLC_Geometry(const GLC_Geometry& sourceGeom)
00052 : m_GeometryIsValid(false)      // By default geometry is invalid
00053 , m_pBoundingBox(NULL)
00054 , m_MaterialHash(sourceGeom.m_MaterialHash)
00055 , m_UseColorPerVertex(sourceGeom.m_UseColorPerVertex)
00056 , m_IsSelected(false)
00057 , m_WireData(sourceGeom.m_WireData)
00058 , m_WireColor(sourceGeom.m_WireColor)
00059 , m_LineWidth(sourceGeom.m_LineWidth)
00060 , m_IsWire(sourceGeom.m_IsWire)
00061 , m_TransparentMaterialNumber(sourceGeom.m_TransparentMaterialNumber)
00062 , m_Id(glc::GLC_GenGeomID())
00063 , m_Name(sourceGeom.m_Name)
00064 {
00065         // Add this mesh to inner material
00066         MaterialHash::const_iterator i= sourceGeom.m_MaterialHash.constBegin();
00067     while (i != sourceGeom.m_MaterialHash.constEnd())
00068     {
00069         // update inner material use table
00070         i.value()->addGLC_Geom(this);
00071         ++i;
00072     }
00073 
00074         if (NULL != sourceGeom.m_pBoundingBox)
00075         {
00076                 m_pBoundingBox= new GLC_BoundingBox(*sourceGeom.m_pBoundingBox);
00077         }
00078 }
00079 
00080 // Overload "=" operator
00081 GLC_Geometry& GLC_Geometry::operator=(const GLC_Geometry& sourceGeom)
00082 {
00083         if (this != &sourceGeom)
00084         {
00085                 clear();
00086                 m_GeometryIsValid= false;
00087                 m_pBoundingBox= NULL;
00088                 m_MaterialHash= sourceGeom.m_MaterialHash;
00089                 m_UseColorPerVertex= sourceGeom.m_UseColorPerVertex;
00090                 m_IsSelected= false;
00091                 m_WireData= sourceGeom.m_WireData;
00092                 m_WireColor= sourceGeom.m_WireColor;
00093                 m_LineWidth= sourceGeom.m_LineWidth;
00094                 m_IsWire= sourceGeom.m_IsWire;
00095                 m_TransparentMaterialNumber= sourceGeom.m_TransparentMaterialNumber;
00096                 m_Id= glc::GLC_GenGeomID();
00097                 m_Name= sourceGeom.m_Name;
00098         }
00099         return *this;
00100 }
00101 
00102 GLC_Geometry::~GLC_Geometry()
00103 {
00104         // delete mesh inner material
00105         {
00106                 MaterialHash::const_iterator i= m_MaterialHash.begin();
00107             while (i != m_MaterialHash.constEnd())
00108             {
00109                 // delete the material if necessary
00110                 i.value()->delGLC_Geom(id());
00111                 if (i.value()->isUnused()) delete i.value();
00112                 ++i;
00113             }
00114         }
00115         m_MaterialHash.clear();
00116 
00117         delete m_pBoundingBox;
00118 
00119 }
00120 
00122 // Get Functions
00124 
00125 // Get number of faces
00126 unsigned int GLC_Geometry::faceCount(int) const
00127 {
00128         return 0;
00129 }
00130 
00131 // Get number of vertex
00132 unsigned int GLC_Geometry::VertexCount() const
00133 {
00134         return 0;
00135 }
00136 
00138 // Set Functions
00140 // Clear the content of the geometry and makes it empty
00141 void GLC_Geometry::clear()
00142 {
00143         clearGeometry();
00144 }
00145 
00146 // Replace the Master material
00147 void GLC_Geometry::replaceMasterMaterial(GLC_Material* pMaterial)
00148 {
00149         Q_ASSERT(!m_IsWire);
00150         if (!m_MaterialHash.isEmpty())
00151         {
00152                 if (pMaterial != firstMaterial())
00153                 {
00154                         // Remove the first material
00155                         MaterialHash::iterator iMaterial= m_MaterialHash.begin();
00156                         removeMaterial(iMaterial.value()->id());
00157 
00158                         // Add the new material
00159                         addMaterial(pMaterial);
00160                 }
00161         }
00162         else
00163         {
00164                 addMaterial(pMaterial);
00165         }
00166 }
00168 void GLC_Geometry::updateTransparentMaterialNumber()
00169 {
00170         m_TransparentMaterialNumber= 0;
00171         MaterialHash::const_iterator iMat= m_MaterialHash.constBegin();
00172         while (iMat != m_MaterialHash.constEnd())
00173         {
00174                 if (iMat.value()->isTransparent())
00175                 {
00176                         ++m_TransparentMaterialNumber;
00177                 }
00178                 ++iMat;
00179         }
00180         if (m_WireColor.alpha() != 255)
00181         {
00182                 qDebug() << "GLC_Geometry::updateTransparentMaterialNumber()";
00183                 ++m_TransparentMaterialNumber;
00184         }
00185 }
00186 
00187 // Add material to mesh
00188 void GLC_Geometry::addMaterial(GLC_Material* pMaterial)
00189 {
00190         Q_ASSERT(!m_IsWire);
00191 
00192         if (pMaterial != NULL)
00193         {
00194                 const GLC_uint materialID= pMaterial->id();
00195                 MaterialHash::const_iterator iMaterial= m_MaterialHash.find(materialID);
00196                 // Check if there is a material at specified index
00197                 Q_ASSERT(iMaterial == m_MaterialHash.end());
00198 
00199                 // Add this geometry in the material use table
00200                 pMaterial->addGLC_Geom(this);
00201                 // Add the Material to Material hash table
00202                 m_MaterialHash.insert(materialID, pMaterial);
00203 
00204                 // Test if the material is transparent
00205                 if (pMaterial->isTransparent())
00206                 {
00207                         //qDebug() << "Add transparent material";
00208                         ++m_TransparentMaterialNumber;
00209                 }
00210         }
00211 }
00212 
00213 void GLC_Geometry::setWireColor(const QColor& color)
00214 {
00215         bool previousColorIsTransparent= (m_WireColor.alpha() != 255);
00216         bool newColorIsTransparent= (color.alpha() != 255);
00217 
00218         if (previousColorIsTransparent != newColorIsTransparent)
00219         {
00220                 if (newColorIsTransparent) ++m_TransparentMaterialNumber;
00221                 else if (previousColorIsTransparent) --m_TransparentMaterialNumber;
00222         }
00223 
00224         m_WireColor= color;
00225 }
00226 
00227 void GLC_Geometry::copyVboToClientSide()
00228 {
00229         m_WireData.copyVboToClientSide();
00230 }
00231 
00232 void GLC_Geometry::releaseVboClientSide(bool update)
00233 {
00234         m_WireData.releaseVboClientSide(update);
00235 }
00236 
00238 // OpenGL Functions
00240 
00241 // if the geometry have a texture, load it
00242 void GLC_Geometry::glLoadTexture(void)
00243 {
00244         MaterialHash::iterator iMaterial= m_MaterialHash.begin();
00245 
00246     while (iMaterial != m_MaterialHash.constEnd())
00247     {
00248         // Load texture of mesh materials
00249         iMaterial.value()->glLoadTexture();
00250         ++iMaterial;
00251     }
00252 }
00253 
00254 // Geometry display
00255 void GLC_Geometry::render(const GLC_RenderProperties& renderProperties)
00256 {
00257         Q_ASSERT(!m_IsWire || (m_IsWire && m_MaterialHash.isEmpty()));
00258         bool renderWire= (renderProperties.renderingFlag() == glc::TransparentRenderFlag) && isTransparent();
00259         renderWire= renderWire || ((renderProperties.renderingFlag() != glc::TransparentRenderFlag) && !isTransparent());
00260         if (!m_IsWire || renderWire)
00261         {
00262                 if (m_MaterialHash.isEmpty() && !m_IsWire)
00263                 {
00264                         GLC_Material* pMaterial= new GLC_Material();
00265                         pMaterial->setName(name());
00266                         addMaterial(pMaterial);
00267                 }
00268 
00269                 m_IsSelected= renderProperties.isSelected();
00270 
00271                 // Define Geometry's property
00272                 if(!GLC_State::isInSelectionMode())
00273                 {
00274                         glPropGeom(renderProperties);
00275                 }
00276 
00277                 glDraw(renderProperties);
00278 
00279                 m_IsSelected= false;
00280                 m_GeometryIsValid= true;
00281 
00282                 // OpenGL error handler
00283                 GLenum error= glGetError();
00284                 if (error != GL_NO_ERROR)
00285                 {
00286                         GLC_OpenGlException OpenGlException("GLC_Geometry::glExecute " + name(), error);
00287                         throw(OpenGlException);
00288                 }
00289         }
00290 }
00291 
00292 // Virtual interface for OpenGL Geometry properties.
00293 void GLC_Geometry::glPropGeom(const GLC_RenderProperties& renderProperties)
00294 {
00295         glLineWidth(lineWidth());
00296 
00297         if(m_IsWire)
00298         {
00299                 glLineWidth(m_LineWidth);
00300                 glDisable(GL_LIGHTING);
00301                 if (!renderProperties.isSelected())
00302                 {
00303                         // Set polyline colors
00304                         GLfloat color[4]= {static_cast<float>(m_WireColor.redF()),
00305                                                                         static_cast<float>(m_WireColor.greenF()),
00306                                                                         static_cast<float>(m_WireColor.blueF()),
00307                                                                         static_cast<float>(m_WireColor.alphaF())};
00308 
00309                         glColor4fv(color);
00310                 }
00311                 else
00312                 {
00313                         GLC_SelectionMaterial::glExecute();
00314                 }
00315         }
00316         else if (m_MaterialHash.size() == 1)
00317         {
00318                 GLC_Material* pCurrentMaterial= m_MaterialHash.begin().value();
00319                 if (pCurrentMaterial->hasTexture())
00320                 {
00321                         glEnable(GL_LIGHTING);
00322                         pCurrentMaterial->glExecute();
00323                         if (renderProperties.isSelected()) GLC_SelectionMaterial::glExecute();
00324                 }
00325                 else
00326                 {
00327                         glEnable(GL_LIGHTING);
00328                         if (renderProperties.isSelected()) GLC_SelectionMaterial::glExecute();
00329                         else pCurrentMaterial->glExecute();
00330                 }
00331         }
00332 }
00333 
00334 // Remove the specified material from the geometry
00335 void GLC_Geometry::removeMaterial(GLC_uint id)
00336 {
00337         Q_ASSERT(containsMaterial(id));
00338         // Remove the first material
00339         GLC_Material* pMaterial= m_MaterialHash.value(id);
00340     // delete the material if necessary
00341         pMaterial->delGLC_Geom(this->id());
00342         if (pMaterial->isTransparent())
00343         {
00344                 --m_TransparentMaterialNumber;
00345         }
00346     if (pMaterial->isUnused()) delete pMaterial;
00347         m_MaterialHash.remove(id);
00348 
00349 }
00350 
00351 // Clear the content of this object and makes it empty
00352 void  GLC_Geometry::clearGeometry()
00353 {
00354         m_GeometryIsValid= false;
00355 
00356         delete m_pBoundingBox;
00357         m_pBoundingBox= NULL;
00358 
00359         // delete mesh inner material
00360         {
00361                 MaterialHash::const_iterator i= m_MaterialHash.begin();
00362             while (i != m_MaterialHash.constEnd())
00363             {
00364                 // delete the material if necessary
00365                 i.value()->delGLC_Geom(id());
00366                 if (i.value()->isUnused()) delete i.value();
00367                 ++i;
00368             }
00369         }
00370         m_MaterialHash.clear();
00371 
00372         m_UseColorPerVertex= false;
00373         m_IsSelected= false;
00374         m_WireData.clear();
00375         m_IsWire= false;
00376         m_TransparentMaterialNumber= 0;
00377         m_Name.clear();
00378 
00379 }

SourceForge.net Logo

©2005-2011 Laurent Ribon