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

SourceForge.net Logo

©2005 Laurent Ribon