glc_renderproperties.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  *****************************************************************************/
00025 
00026 #include "glc_renderproperties.h"
00027 
00028 // Default constructor
00029 GLC_RenderProperties::GLC_RenderProperties()
00030 : m_Uid(glc::GLC_GenUserID())
00031 , m_IsSelected(false)
00032 , m_PolyFace(GL_FRONT_AND_BACK)
00033 , m_PolyMode(GL_FILL)
00034 , m_RenderMode(glc::NormalRenderMode)
00035 , m_SavedRenderMode(m_RenderMode)
00036 , m_pOverwriteMaterial(NULL)
00037 , m_OverwriteTransparency(-1.0f)
00038 , m_pBodySelectedPrimitvesId(NULL)
00039 , m_pOverwritePrimitiveMaterialMaps(NULL)
00040 , m_RenderingFlag(glc::ShadingFlag)
00041 , m_CurrentBody(0)
00042 , m_MaterialsUsage()
00043 {
00044 
00045 }
00046 
00047 // Copy constructor
00048 GLC_RenderProperties::GLC_RenderProperties(const GLC_RenderProperties& renderProperties)
00049 : m_Uid(glc::GLC_GenUserID())
00050 , m_IsSelected(renderProperties.m_IsSelected)
00051 , m_PolyFace(renderProperties.m_PolyFace)
00052 , m_PolyMode(renderProperties.m_PolyMode)
00053 , m_RenderMode(renderProperties.m_RenderMode)
00054 , m_SavedRenderMode(renderProperties.m_SavedRenderMode)
00055 , m_pOverwriteMaterial(renderProperties.m_pOverwriteMaterial)
00056 , m_OverwriteTransparency(renderProperties.m_OverwriteTransparency)
00057 , m_pBodySelectedPrimitvesId(NULL)
00058 , m_pOverwritePrimitiveMaterialMaps(NULL)
00059 , m_RenderingFlag(renderProperties.m_RenderingFlag)
00060 , m_CurrentBody(renderProperties.m_CurrentBody)
00061 , m_MaterialsUsage(renderProperties.m_MaterialsUsage)
00062 {
00063         // Update overwrite material usage
00064         if (NULL != m_pOverwriteMaterial)
00065         {
00066                 m_pOverwriteMaterial->addUsage(m_Uid);
00067         }
00068 
00069         // Copy the Hash of set of id of selected primitives
00070         if (NULL != renderProperties.m_pBodySelectedPrimitvesId)
00071         {
00072                 m_pBodySelectedPrimitvesId= new QHash<int, QSet<GLC_uint>* >();
00073                 QHash<int, QSet<GLC_uint>* >::const_iterator iSet= renderProperties.m_pBodySelectedPrimitvesId->constBegin();
00074                 while (renderProperties.m_pBodySelectedPrimitvesId->constEnd() != iSet)
00075                 {
00076                         // Copy the current body set of id of selected primitive
00077                         m_pBodySelectedPrimitvesId->insert(iSet.key(), new QSet<GLC_uint>(*(iSet.value())));
00078                         ++iSet;
00079                 }
00080         }
00081 
00082         // Copy of the overwrite primitive materials maps
00083         if (NULL != renderProperties.m_pOverwritePrimitiveMaterialMaps)
00084         {
00085                 // Copy the hash table of overwrite materials
00086                 m_pOverwritePrimitiveMaterialMaps= new QHash<int, QHash<GLC_uint, GLC_Material*>* >;
00087                 QHash<int, QHash<GLC_uint, GLC_Material*>* >::const_iterator iMatMaps= renderProperties.m_pOverwritePrimitiveMaterialMaps->constBegin();
00088                 while (renderProperties.m_pOverwritePrimitiveMaterialMaps->constEnd() != iMatMaps)
00089                 {
00090                         QHash<GLC_uint, GLC_Material*>* pBodyMatMap= new QHash<GLC_uint, GLC_Material*>(*(iMatMaps.value()));
00091                         m_pOverwritePrimitiveMaterialMaps->insert(iMatMaps.key(), pBodyMatMap);
00092                         ++iMatMaps;
00093                 }
00094         }
00095 
00096         // Update material usage
00097         QHash<GLC_Material*, int>::iterator iMatUsage= m_MaterialsUsage.begin();
00098         while (m_MaterialsUsage.constEnd() != iMatUsage)
00099         {
00100                 iMatUsage.key()->addUsage(m_Uid);
00101                 ++iMatUsage;
00102         }
00103 }
00104 
00105 // Assignement operator
00106 GLC_RenderProperties& GLC_RenderProperties::operator=(const GLC_RenderProperties& renderProperties)
00107 {
00108         if (this != &renderProperties)
00109         {
00110                 clear();
00111                 m_IsSelected= renderProperties.m_IsSelected;
00112                 m_PolyFace= renderProperties.m_PolyFace;
00113                 m_PolyMode= renderProperties.m_PolyMode;
00114                 m_RenderMode= renderProperties.m_RenderMode;
00115                 m_SavedRenderMode= renderProperties.m_SavedRenderMode;
00116                 m_pOverwriteMaterial= renderProperties.m_pOverwriteMaterial;
00117                 m_OverwriteTransparency= renderProperties.m_OverwriteTransparency;
00118                 m_pBodySelectedPrimitvesId= NULL;
00119                 m_pOverwritePrimitiveMaterialMaps= NULL;
00120                 m_RenderingFlag= renderProperties.m_RenderingFlag;
00121                 m_CurrentBody= renderProperties.m_CurrentBody;
00122 
00123                 // Update overwrite material usage
00124                 if (NULL != m_pOverwriteMaterial)
00125                 {
00126                         m_pOverwriteMaterial->addUsage(m_Uid);
00127                 }
00128 
00129                 // Copy the Hash of set of id of selected primitives
00130                 if (NULL != renderProperties.m_pBodySelectedPrimitvesId)
00131                 {
00132                         m_pBodySelectedPrimitvesId= new QHash<int, QSet<GLC_uint>* >();
00133                         QHash<int, QSet<GLC_uint>* >::const_iterator iSet= renderProperties.m_pBodySelectedPrimitvesId->constBegin();
00134                         while (renderProperties.m_pBodySelectedPrimitvesId->constEnd() != iSet)
00135                         {
00136                                 // Copy the current body set of id of selected primitive
00137                                 m_pBodySelectedPrimitvesId->insert(iSet.key(), new QSet<GLC_uint>(*(iSet.value())));
00138                                 ++iSet;
00139                         }
00140                 }
00141 
00142                 // Update primitive overwrite material usage
00143                 if (NULL != renderProperties.m_pOverwritePrimitiveMaterialMaps)
00144                 {
00145                         // Copy the hash table of overwrite materials
00146                         m_pOverwritePrimitiveMaterialMaps= new QHash<int, QHash<GLC_uint, GLC_Material*>* >;
00147                         QHash<int, QHash<GLC_uint, GLC_Material*>* >::const_iterator iMatMaps= renderProperties.m_pOverwritePrimitiveMaterialMaps->constBegin();
00148                         while (renderProperties.m_pOverwritePrimitiveMaterialMaps->constEnd() != iMatMaps)
00149                         {
00150                                 QHash<GLC_uint, GLC_Material*>* pBodyMatMap= new QHash<GLC_uint, GLC_Material*>(*(iMatMaps.value()));
00151                                 m_pOverwritePrimitiveMaterialMaps->insert(iMatMaps.key(), pBodyMatMap);
00152 
00153                                 QHash<GLC_uint, GLC_Material*>::iterator iMatMap= pBodyMatMap->begin();
00154                                 while (pBodyMatMap->constEnd() != iMatMap)
00155                                 {
00156                                         iMatMap.value()->addUsage(m_Uid);
00157                                         ++iMatMap;
00158                                 }
00159 
00160                                 ++iMatMaps;
00161                         }
00162                 }
00163         }
00164 
00165         return *this;
00166 }
00167 
00168 // Destructor
00169 GLC_RenderProperties::~GLC_RenderProperties()
00170 {
00171         clear();
00172 }
00173 
00174 // Return true if rendering properties needs to render with transparency
00175 bool GLC_RenderProperties::needToRenderWithTransparency() const
00176 {
00177         bool renderWithTransparency= false;
00178         if (m_RenderMode == glc::OverwriteMaterial)
00179         {
00180                 Q_ASSERT(NULL != m_pOverwriteMaterial);
00181                 renderWithTransparency= m_pOverwriteMaterial->isTransparent();
00182         }
00183         else if (m_RenderMode == glc::OverwriteTransparency)
00184         {
00185                 Q_ASSERT(-1.0f != m_OverwriteTransparency);
00186                 renderWithTransparency= (m_OverwriteTransparency < 1.0f);
00187         }
00188         else if ((m_RenderMode == glc::OverwritePrimitiveMaterial)
00189                         || ((m_RenderMode == glc::PrimitiveSelected) && (NULL != m_pOverwritePrimitiveMaterialMaps) && (!m_pOverwritePrimitiveMaterialMaps->isEmpty())))
00190         {
00191                 Q_ASSERT(NULL != m_pOverwritePrimitiveMaterialMaps);
00192                 Q_ASSERT(!m_pOverwritePrimitiveMaterialMaps->isEmpty());
00193 
00194                 QList<QHash<GLC_uint, GLC_Material* >* > hashList= m_pOverwritePrimitiveMaterialMaps->values();
00195                 QSet<GLC_Material*> materialSet;
00196                 const int size= hashList.size();
00197                 for (int i= 0; i < size; ++i)
00198                 {
00199                         materialSet.unite(QSet<GLC_Material*>::fromList(hashList.at(i)->values()));
00200                 }
00201 
00202                 QSet<GLC_Material*>::const_iterator iMat= materialSet.constBegin();
00203                 while ((materialSet.constEnd() != iMat) && !renderWithTransparency)
00204                 {
00205                         renderWithTransparency= (*iMat)->isTransparent();
00206                         ++iMat;
00207                 }
00208         }
00209 
00210         return renderWithTransparency;
00211 }
00212 
00213 bool GLC_RenderProperties::isDefault() const
00214 {
00215         bool isDefault= (NULL == m_pOverwriteMaterial);
00216         isDefault= isDefault && (m_OverwriteTransparency == -1.0f);
00217         return isDefault;
00218 }
00219 
00220 // Clear the content of the render properties and update materials usage
00221 void GLC_RenderProperties::clear()
00222 {
00223         if (NULL != m_pOverwriteMaterial)
00224         {
00225                 // Delete the material if it is unused
00226                 m_pOverwriteMaterial->delUsage(m_Uid);
00227                 if (m_pOverwriteMaterial->isUnused()) delete m_pOverwriteMaterial;
00228                 m_pOverwriteMaterial= NULL;
00229         }
00230 
00231         clearSelectedPrimitives();
00232 
00233         clearOverwritePrimitiveMaterials();
00234 }
00235 
00236 // Set the overwrite material
00237 void GLC_RenderProperties::setOverwriteMaterial(GLC_Material* pMaterial)
00238 {
00239         Q_ASSERT(NULL != pMaterial);
00240         if (NULL != m_pOverwriteMaterial)
00241         {
00242                 m_pOverwriteMaterial->delUsage(m_Uid);
00243                 if (m_pOverwriteMaterial->isUnused()) delete m_pOverwriteMaterial;
00244         }
00245         m_pOverwriteMaterial= pMaterial;
00246 
00247         m_pOverwriteMaterial->addUsage(m_Uid);
00248 }
00249 
00250 // Return true if the specified primitive id of the specified body index is selected
00251 bool GLC_RenderProperties::primitiveIsSelected(int index, GLC_uint id) const
00252 {
00253         bool result= false;
00254         if ((NULL != m_pBodySelectedPrimitvesId) && m_pBodySelectedPrimitvesId->contains(m_CurrentBody))
00255         {
00256                 result= m_pBodySelectedPrimitvesId->value(index)->contains(id);
00257         }
00258         return result;
00259 }
00260 
00261 // Set the list of selected primitives id
00262 void GLC_RenderProperties::addSetOfSelectedPrimitivesId(const QSet<GLC_uint>& set, int body)
00263 {
00264         if (NULL == m_pBodySelectedPrimitvesId)
00265         {
00266                 m_pBodySelectedPrimitvesId= new QHash<int, QSet<GLC_uint>* >();
00267                 m_pBodySelectedPrimitvesId->insert(body, new QSet<GLC_uint>(set));
00268         }
00269         else if (!m_pBodySelectedPrimitvesId->contains(body))
00270         {
00271                 m_pBodySelectedPrimitvesId->insert(body, new QSet<GLC_uint>(set));
00272         }
00273         else
00274         {
00275                 m_pBodySelectedPrimitvesId->value(body)->unite(set);
00276         }
00277 }
00278 
00279 // Add a selected primitive
00280 void GLC_RenderProperties::addSelectedPrimitive(GLC_uint id, int body)
00281 {
00282         if (NULL == m_pBodySelectedPrimitvesId)
00283         {
00284                 m_pBodySelectedPrimitvesId= new QHash<int, QSet<GLC_uint>* >();
00285                 m_pBodySelectedPrimitvesId->insert(body, new QSet<GLC_uint>());
00286 
00287         }
00288         else if (!m_pBodySelectedPrimitvesId->contains(body))
00289         {
00290                 m_pBodySelectedPrimitvesId->insert(body, new QSet<GLC_uint>());
00291         }
00292         m_pBodySelectedPrimitvesId->value(body)->insert(id);
00293 }
00294 
00295 // Clear selectedPrimitive Set
00296 void GLC_RenderProperties::clearSelectedPrimitives()
00297 {
00298         if (NULL != m_pBodySelectedPrimitvesId)
00299         {
00300                 QHash<int, QSet<GLC_uint>* >::const_iterator iSet= m_pBodySelectedPrimitvesId->constBegin();
00301                 while (m_pBodySelectedPrimitvesId->constEnd() != iSet)
00302                 {
00303                         delete iSet.value();
00304                         ++iSet;
00305                 }
00306         }
00307         delete m_pBodySelectedPrimitvesId;
00308         m_pBodySelectedPrimitvesId= NULL;
00309 }
00310 
00311 // Add an overwrite primitive material
00312 void GLC_RenderProperties::addOverwritePrimitiveMaterial(GLC_uint id, GLC_Material* pMaterial, int bodyIndex)
00313 {
00314         Q_ASSERT(NULL != pMaterial);
00315         if (NULL != m_pOverwritePrimitiveMaterialMaps)
00316         {
00317                 if (m_pOverwritePrimitiveMaterialMaps->contains(bodyIndex))
00318                 {
00319                         QHash<GLC_uint, GLC_Material*>* pHash= m_pOverwritePrimitiveMaterialMaps->value(bodyIndex);
00320                         if (pHash->contains(id))
00321                         {
00322                                 if (pHash->value(id) != pMaterial)
00323                                 {
00324                                         GLC_Material* pOldMaterial= pHash->value(id);
00325                                         unUseMaterial(pOldMaterial);
00326                                         pHash->remove(id);
00327 
00328                                         pHash->insert(id, pMaterial);
00329                                         useMaterial(pMaterial);
00330                                 }
00331                                 // Else, noting to do
00332                         }
00333                         else
00334                         {
00335                                 pHash->insert(id, pMaterial);
00336                                 useMaterial(pMaterial);
00337                         }
00338                 }
00339                 else
00340                 {
00341                         QHash<GLC_uint, GLC_Material*>* pHash= new QHash<GLC_uint, GLC_Material*>();
00342                         pHash->insert(id, pMaterial);
00343                         useMaterial(pMaterial);
00344                         m_pOverwritePrimitiveMaterialMaps->insert(bodyIndex, pHash);
00345                 }
00346         }
00347         else
00348         {
00349                 m_pOverwritePrimitiveMaterialMaps= new QHash<int, QHash<GLC_uint, GLC_Material*>* >();
00350                 QHash<GLC_uint, GLC_Material*>* pHash= new QHash<GLC_uint, GLC_Material*>();
00351                 pHash->insert(id, pMaterial);
00352                 m_pOverwritePrimitiveMaterialMaps->insert(bodyIndex, pHash);
00353                 useMaterial(pMaterial);
00354         }
00355 }
00356 
00357 // Clear overwrite primitive materials
00358 void GLC_RenderProperties::clearOverwritePrimitiveMaterials()
00359 {
00360         if (NULL != m_pOverwritePrimitiveMaterialMaps)
00361         {
00362                 Q_ASSERT(!m_MaterialsUsage.isEmpty());
00363                 QHash<int, QHash<GLC_uint, GLC_Material* >* >::iterator iHash= m_pOverwritePrimitiveMaterialMaps->begin();
00364                 while (m_pOverwritePrimitiveMaterialMaps->constEnd() != iHash)
00365                 {
00366                         delete iHash.value();
00367                         ++iHash;
00368                 }
00369 
00370                 QHash<GLC_Material*, int>::iterator iMat= m_MaterialsUsage.begin();
00371                 while (m_MaterialsUsage.constEnd() != iMat)
00372                 {
00373                         GLC_Material* pMat= iMat.key();
00374                         pMat->delUsage(m_Uid);
00375                         if (pMat->isUnused()) delete pMat;
00376                         ++iMat;
00377                 }
00378                 m_MaterialsUsage.clear();
00379         }
00380         else
00381         {
00382                 Q_ASSERT(m_MaterialsUsage.isEmpty());
00383         }
00384 
00385         delete m_pOverwritePrimitiveMaterialMaps;
00386         m_pOverwritePrimitiveMaterialMaps= NULL;
00387 }
00388 

SourceForge.net Logo

©2005 Laurent Ribon