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

SourceForge.net Logo

©2005-2011 Laurent Ribon