glc_geometry.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00035
00036 GLC_Geometry::GLC_Geometry(const QString& name, const bool typeIsWire)
00037 : m_GeometryIsValid(false)
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)
00046 , m_TransparentMaterialNumber(0)
00047 , m_Id(glc::GLC_GenGeomID())
00048 , m_Name(name)
00049 {
00050
00051 }
00052
00053 GLC_Geometry::GLC_Geometry(const GLC_Geometry& sourceGeom)
00054 : m_GeometryIsValid(false)
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
00068 MaterialHash::const_iterator i= sourceGeom.m_MaterialHash.constBegin();
00069 while (i != sourceGeom.m_MaterialHash.constEnd())
00070 {
00071
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
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
00107 {
00108 MaterialHash::const_iterator i= m_MaterialHash.begin();
00109 while (i != m_MaterialHash.constEnd())
00110 {
00111
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
00126
00127
00128 unsigned int GLC_Geometry::faceCount() const
00129 {
00130 return 0;
00131 }
00132
00133
00134 unsigned int GLC_Geometry::VertexCount() const
00135 {
00136 return 0;
00137 }
00138
00140
00142
00143 void GLC_Geometry::clear()
00144 {
00145 clearGeometry();
00146 }
00147
00148
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
00157 MaterialHash::iterator iMaterial= m_MaterialHash.begin();
00158 removeMaterial(iMaterial.value()->id());
00159
00160
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
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
00199 Q_ASSERT(iMaterial == m_MaterialHash.end());
00200
00201
00202 pMaterial->addGLC_Geom(this);
00203
00204 m_MaterialHash.insert(materialID, pMaterial);
00205
00206
00207 if (pMaterial->isTransparent())
00208 {
00209
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
00231
00232
00233 void GLC_Geometry::glLoadTexture(void)
00234 {
00235 MaterialHash::iterator iMaterial= m_MaterialHash.begin();
00236
00237 while (iMaterial != m_MaterialHash.constEnd())
00238 {
00239
00240 iMaterial.value()->glLoadTexture();
00241 ++iMaterial;
00242 }
00243 }
00244
00245
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
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
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
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
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
00326 void GLC_Geometry::removeMaterial(GLC_uint id)
00327 {
00328 Q_ASSERT(containsMaterial(id));
00329
00330 GLC_Material* pMaterial= m_MaterialHash.value(id);
00331
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
00343 void GLC_Geometry::clearGeometry()
00344 {
00345 m_GeometryIsValid= false;
00346
00347 delete m_pBoundingBox;
00348 m_pBoundingBox= NULL;
00349
00350
00351 {
00352 MaterialHash::const_iterator i= m_MaterialHash.begin();
00353 while (i != m_MaterialHash.constEnd())
00354 {
00355
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 }