1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-18 03:52:11 +01:00

[OP-835] Qt 5.1.0 - migrated GCS libs/glc_lib

This commit is contained in:
Philippe Renon 2013-09-15 23:00:38 +02:00
parent 7e042a0bd3
commit b249e58861
66 changed files with 2730 additions and 542 deletions

View File

@ -66,6 +66,10 @@ public:
inline GLC_3DWidget* widget(GLC_uint id) const
{return m_pWidgetManagerHandle->widget(id);}
//! Return true if this 3DWidget manager is empty
inline bool isEmpty() const
{return m_pWidgetManagerHandle->isEmpty();}
//@}
//////////////////////////////////////////////////////////////////////

View File

@ -91,6 +91,10 @@ public:
inline GLC_3DWidget* widget(GLC_uint id) const
{return m_3DWidgetHash.value(id);}
//! Return true if this 3DWidget manager is empty
inline bool isEmpty() const
{return m_3DWidgetHash.isEmpty();}
//@}
//////////////////////////////////////////////////////////////////////

View File

@ -51,18 +51,7 @@ GLC_CuttingPlane::GLC_CuttingPlane(const GLC_Point3d& center, const GLC_Vector3d
create3DviewInstance();
}
if (glc::Z_AXIS != m_Normal)
{
if (m_Normal != -glc::Z_AXIS)
{
m_CompMatrix.setMatRot(glc::Z_AXIS, m_Normal);
}
else
{
m_CompMatrix.setMatRot(glc::X_AXIS, glc::PI);
}
}
m_CompMatrix.setMatRot(glc::Z_AXIS, m_Normal);
}
GLC_CuttingPlane::GLC_CuttingPlane(const GLC_CuttingPlane& cuttingPlane)

View File

@ -367,7 +367,11 @@ extern "C" {
#endif
#ifndef GL_VERSION_2_0
#ifndef GL_BLEND_EQUATION_RGB
#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION
#endif
#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624

View File

@ -60,7 +60,7 @@ GLC_3DRep& GLC_3DRep::operator=(const GLC_Rep& rep)
Q_ASSERT(NULL != p3DRep);
if (this != &rep)
{
clear();
clear3DRepGeom();
GLC_Rep::operator=(rep);
m_pGeomList= p3DRep->m_pGeomList;
m_pType= p3DRep->m_pType;
@ -91,7 +91,16 @@ GLC_Rep* GLC_3DRep::deepCopy() const
GLC_3DRep::~GLC_3DRep()
{
clear();
if (isTheLast())
{
clear3DRepGeom();
delete m_pGeomList;
m_pGeomList= NULL;
delete m_pType;
m_pType= NULL;
}
}
//////////////////////////////////////////////////////////////////////
@ -274,6 +283,9 @@ void GLC_3DRep::replace(GLC_Rep* pRep)
GLC_3DRep* p3DRep= dynamic_cast<GLC_3DRep*>(pRep);
Q_ASSERT(NULL != p3DRep);
(*m_pType)= *(p3DRep->m_pType);
clear3DRepGeom();
setFileName(p3DRep->fileName());
setName(p3DRep->name());
@ -404,22 +416,16 @@ bool GLC_3DRep::unload()
// private services functions
//////////////////////////////////////////////////////////////////////
void GLC_3DRep::clear()
void GLC_3DRep::clear3DRepGeom()
{
if (isTheLast())
{
const int size= m_pGeomList->size();
for (int i= 0; i < size; ++i)
{
delete (*m_pGeomList)[i];
}
delete m_pGeomList;
m_pGeomList= NULL;
delete m_pType;
m_pType= NULL;
}
const int size= m_pGeomList->size();
for (int i= 0; i < size; ++i)
{
delete (*m_pGeomList)[i];
}
m_pGeomList->clear();
}
// Non Member methods
QDataStream &operator<<(QDataStream & stream, const GLC_3DRep & rep)
{

View File

@ -180,8 +180,8 @@ public:
// private services functions
//////////////////////////////////////////////////////////////////////
private:
//! Clear current representation
void clear();
//! Clear current representation geometries
void clear3DRepGeom();
//////////////////////////////////////////////////////////////////////
// Private members

View File

@ -26,11 +26,11 @@
// Class chunk id
quint32 GLC_Cone::m_ChunkId= 0xA709;
GLC_Cone::GLC_Cone(double dRadius, double dLength)
GLC_Cone::GLC_Cone(double dRadius, double dLength, int discretization)
:GLC_Mesh()
, m_Radius(dRadius)
, m_Length(dLength)
, m_Discret(glc::GLC_POLYDISCRET) // Default discretion
, m_Discret(discretization) // Default discretion
{
Q_ASSERT((m_Radius > 0.0) && (m_Length > 0.0));
createMeshAndWire();

View File

@ -45,7 +45,7 @@ public:
* By default, Axis of Cylinder is Z Axis
* dRadius must be > 0
* dLength must be > 0*/
GLC_Cone(double dRadius, double dLength);
GLC_Cone(double dRadius, double dLength, int discretization= glc::GLC_POLYDISCRET);
//! Copy contructor
GLC_Cone(const GLC_Cone& sourceCone);

View File

@ -36,11 +36,11 @@ quint32 GLC_Cylinder::m_ChunkId= 0xA705;
// Constructor destructor
//////////////////////////////////////////////////////////////////////
GLC_Cylinder::GLC_Cylinder(double dRadius, double dLength)
GLC_Cylinder::GLC_Cylinder(double dRadius, double dLength, int discretization)
:GLC_Mesh()
, m_Radius(dRadius)
, m_Length(dLength)
, m_Discret(glc::GLC_POLYDISCRET) // Default discretion
, m_Discret(discretization) // Default discretion
, m_EndedIsCaped(true) // Cylinder ended are closed
{
Q_ASSERT((m_Radius > 0.0) && (m_Length > 0.0));
@ -55,9 +55,9 @@ GLC_Cylinder::GLC_Cylinder(const GLC_Cylinder& sourceCylinder)
, m_EndedIsCaped(sourceCylinder.m_EndedIsCaped)
{
Q_ASSERT((m_Radius > 0.0) && (m_Length > 0.0) && (m_Discret > 0));
createMeshAndWire();
if (isEmpty()) createMeshAndWire();
}
GLC_Cylinder::~GLC_Cylinder()
{

View File

@ -49,7 +49,7 @@ public:
* By default, Axis of Cylinder is Z Axis
* dRadius must be > 0
* dLength must be > 0*/
GLC_Cylinder(double dRadius, double dLength);
GLC_Cylinder(double dRadius, double dLength, int discretization= glc::GLC_POLYDISCRET);
//! Copy contructor
GLC_Cylinder(const GLC_Cylinder& sourceCylinder);

View File

@ -23,10 +23,10 @@
#include "glc_disc.h"
GLC_Disc::GLC_Disc(double radius, double angle)
GLC_Disc::GLC_Disc(double radius, double angle, int discretization)
: GLC_Mesh()
, m_Radius(radius)
, m_Discret(glc::GLC_POLYDISCRET)
, m_Discret(discretization)
, m_Angle(angle)
, m_Step(0)
{

View File

@ -41,7 +41,7 @@ class GLC_LIB_EXPORT GLC_Disc : public GLC_Mesh
//////////////////////////////////////////////////////////////////////
public:
//! Construct a disc with the given radius
GLC_Disc(double radius, double angle= 2.0 * glc::PI);
GLC_Disc(double radius, double angle= 2.0 * glc::PI, int discretization= glc::GLC_POLYDISCRET);
//! Copy constructor
GLC_Disc(const GLC_Disc& disc);

View File

@ -0,0 +1,535 @@
/****************************************************************************
This file is part of the GLC-lib library.
Copyright (C) 2005-2013 Laurent Ribon (laumaya@users.sourceforge.net)
http://glc-lib.sourceforge.net
GLC-lib is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
GLC-lib is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with GLC-lib; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
//! \file glc_extrudedmesh.cpp Implementation of the GLC_ExtrudedMesh class.
#include <QtDebug>
#include "glc_extrudedmesh.h"
#include "../maths/glc_plane.h"
#include "../maths/glc_geomtools.h"
// Class chunk id
quint32 GLC_ExtrudedMesh::m_ChunkId= 0xA712;
GLC_ExtrudedMesh::GLC_ExtrudedMesh(const QList<GLC_Point3d> &points, const GLC_Vector3d &dir, double lenght)
:GLC_Mesh()
, m_Points(points)
, m_ExtrusionVector(GLC_Vector3d(dir).normalize())
, m_ExtrusionLenght(lenght)
, m_GivenFaceNormal()
{
Q_ASSERT(m_Points.size() > 2);
Q_ASSERT(pointsLieOnAPlane());
Q_ASSERT(!glc::compare(m_Points.first(), m_Points.last(), glc::EPSILON));
computeGivenFaceNormal();
createMeshAndWire();
}
GLC_ExtrudedMesh::GLC_ExtrudedMesh(const GLC_ExtrudedMesh &other)
:GLC_Mesh(other)
, m_Points(other.m_Points)
, m_ExtrusionVector(other.m_ExtrusionVector)
, m_ExtrusionLenght(other.m_ExtrusionLenght)
, m_GivenFaceNormal(other.m_GivenFaceNormal)
{
if (GLC_Mesh::isEmpty())
{
createMeshAndWire();
}
}
GLC_ExtrudedMesh::~GLC_ExtrudedMesh()
{
}
quint32 GLC_ExtrudedMesh::chunckID()
{
return m_ChunkId;
}
GLC_Geometry *GLC_ExtrudedMesh::clone() const
{
return new GLC_ExtrudedMesh(*this);
}
const GLC_BoundingBox &GLC_ExtrudedMesh::boundingBox()
{
if (GLC_Mesh::isEmpty())
{
createMeshAndWire();
}
return GLC_Mesh::boundingBox();
}
GLC_ExtrudedMesh &GLC_ExtrudedMesh::operator =(const GLC_ExtrudedMesh &other)
{
if (this != &other)
{
GLC_Mesh::operator =(other);
m_Points= other.m_Points;
m_ExtrusionVector= other.m_ExtrusionVector;
m_ExtrusionLenght= other.m_ExtrusionLenght;
m_GivenFaceNormal= other.m_GivenFaceNormal;
}
return *this;
}
void GLC_ExtrudedMesh::setGeometry(const QList<GLC_Point3d> &points, const GLC_Vector3d &extrudedVector, double lenght)
{
m_Points= points;
m_ExtrusionVector= extrudedVector;
m_ExtrusionLenght= lenght;
GLC_Mesh::clearMeshWireAndBoundingBox();
createMeshAndWire();
}
void GLC_ExtrudedMesh::setPoints(const QList<GLC_Point3d> &points)
{
m_Points= points;
GLC_Mesh::clearMeshWireAndBoundingBox();
createMeshAndWire();
}
void GLC_ExtrudedMesh::setExtrudedVector(const GLC_Vector3d &extrudedVector)
{
m_ExtrusionVector= extrudedVector;
GLC_Mesh::clearMeshWireAndBoundingBox();
createMeshAndWire();
}
void GLC_ExtrudedMesh::setExtrudedLenght(double lenght)
{
m_ExtrusionLenght= lenght;
GLC_Mesh::clearMeshWireAndBoundingBox();
createMeshAndWire();
}
void GLC_ExtrudedMesh::createMeshAndWire()
{
Q_ASSERT(GLC_Mesh::isEmpty());
Q_ASSERT(m_WireData.isEmpty());
createMesh();
createWire();
finish();
}
void GLC_ExtrudedMesh::createMesh()
{
// Bulk data
GLfloatVector vertices;
GLfloatVector normals;
GLfloatVector texels= baseFaceTexels() + createdFaceTexels() + basedOutlineFacesTexels() + createdOutlineFacesTexels();
GLC_Mesh::addTexels(texels);
// Set the material to use
GLC_Material* pMaterial;
if (hasMaterial()) pMaterial= this->firstMaterial();
else pMaterial= new GLC_Material();
{
// Given face (Face 1)
GLfloatVector face1Vertices= baseFaceVertices();
GLfloatVector face1Normals= baseFaceNormals();
IndexList face1Index;
const GLuint count= m_Points.count();
for (GLuint i= 0; i < (count + 1); ++i)
{
face1Index.append(i % count);
}
vertices+= face1Vertices;
normals+= face1Normals;
Q_ASSERT(vertices.size() == normals.size());
glc::triangulatePolygon(&face1Index, vertices.toList());
addTriangles(pMaterial, face1Index);
}
{
// Created face (Face2)
GLfloatVector face2Vertices= createdFaceVertices();
GLfloatVector face2Normals= createdFaceNormals();
IndexList face2Index;
const int offset= vertices.size() / 3;
const GLuint count= m_Points.count();
for (GLuint i= 0; i < (count + 1); ++i)
{
face2Index.append(offset + (i % count));
}
vertices+= face2Vertices;
normals+= face2Normals;
Q_ASSERT(vertices.size() == normals.size());
glc::triangulatePolygon(&face2Index, vertices.toList());
addTriangles(pMaterial, face2Index);
}
{
// Add outline faces
const GLuint count= m_Points.count();
GLuint offset1= vertices.size() / 3;
GLfloatVector facesNormals= baseOutlineNormals();
GLuint indexLenght= (facesNormals.size() / 3);
GLuint offset2= offset1 + indexLenght;
facesNormals= facesNormals + createdOutlineNormals();
GLfloatVector facesVertices= baseOutlineFacesVertices() + createdOutlineFacesVertices();
vertices+= facesVertices;
normals+= facesNormals;
for (GLuint face= 0; face < count; ++face)
{
IndexList faceIndex;
GLuint startIndex1= offset1 + (face * 2);
GLuint startIndex2= offset2 + (indexLenght -1) - (face * 2);
faceIndex << startIndex1 << startIndex2 << (startIndex1 + 1) << (startIndex2 - 1);
addTrianglesStrip(pMaterial, faceIndex);
}
}
// Add bulk data in to the mesh
GLC_Mesh::addVertice(vertices);
GLC_Mesh::addNormals(normals);
}
void GLC_ExtrudedMesh::createWire()
{
GLfloatVector baseFaceWire= baseFaceVertices();
baseFaceWire << baseFaceWire.at(0) << baseFaceWire.at(1) << baseFaceWire.at(2);
GLC_Geometry::addVerticeGroup(baseFaceWire);
GLfloatVector createdFaceWire= createdFaceVertices();
createdFaceWire << createdFaceWire.at(0) << createdFaceWire.at(1) << createdFaceWire.at(2);
GLC_Geometry::addVerticeGroup(createdFaceWire);
// Outline edges
const int count= m_Points.count();
for (int i= 0; i < count; ++i)
{
GLfloatVector edge(6); // the edge is a line
edge[0]= baseFaceWire.at(i * 3);
edge[1]= baseFaceWire.at(i * 3 + 1);
edge[2]= baseFaceWire.at(i * 3 + 2);
edge[3]= createdFaceWire.at(((count - i) % count) * 3);
edge[4]= createdFaceWire.at(((count - i) % count) * 3 + 1);
edge[5]= createdFaceWire.at(((count - i) % count) * 3 + 2);
GLC_Geometry::addVerticeGroup(edge);
}
}
void GLC_ExtrudedMesh::computeGivenFaceNormal()
{
Q_ASSERT(m_Points.count() > 2);
const GLC_Vector3d edge1(GLC_Vector3d(m_Points.at(1) - m_Points.at(0)).normalize());
const GLC_Vector3d edge2(GLC_Vector3d(m_Points.at(2) - m_Points.at(1)).normalize());
m_GivenFaceNormal= edge1 ^ edge2;
}
bool GLC_ExtrudedMesh::pointsLieOnAPlane() const
{
bool subject= true;
const int count= m_Points.count();
Q_ASSERT(count > 2);
if (count > 3)
{
// Create a plane on the first 3 points
GLC_Plane plane(m_Points.at(0), m_Points.at(1), m_Points.at(2));
// Check if others points lie on the plane
for (int i= 3; i < count; ++i)
{
subject= plane.lieOnThisPlane(m_Points.at(i));
if (!subject) break;
}
}
return subject;
}
GLfloatVector GLC_ExtrudedMesh::baseOutlineNormals() const
{
const int count= m_Points.count();
GLfloatVector subject(count * 6); // 2 normals by vertex and 3 components pear normal => 6
for (int i= 0; i < count; ++i)
{
GLC_Vector3d vect(m_Points.at((i + 1) % count) - m_Points.at(i));
GLC_Vector3d normal= GLC_Vector3d(m_ExtrusionVector ^ vect).normalize();
// First segment point
subject[(6 * i)]= static_cast<GLfloat>(normal.x());
subject[(6 * i) + 1]= static_cast<GLfloat>(normal.y());
subject[(6 * i) + 2]= static_cast<GLfloat>(normal.z());
// Second segment point
subject[(6 * i) + 3]= static_cast<GLfloat>(normal.x());
subject[(6 * i) + 4]= static_cast<GLfloat>(normal.y());
subject[(6 * i) + 5]= static_cast<GLfloat>(normal.z());
}
return subject;
}
GLfloatVector GLC_ExtrudedMesh::createdOutlineNormals() const
{
const int count= m_Points.count();
GLfloatVector subject(count * 6); // 2 normals by vertex and 3 components pear normal => 6
int index= 0.0;
for (int i= count; i > 0; --i)
{
GLC_Vector3d vect(m_Points.at(i % count) - m_Points.at(i - 1));
GLC_Vector3d normal= GLC_Vector3d(m_ExtrusionVector ^ vect).normalize();
// First segment point
subject[(6 * index)]= static_cast<GLfloat>(normal.x());
subject[(6 * index) + 1]= static_cast<GLfloat>(normal.y());
subject[(6 * index) + 2]= static_cast<GLfloat>(normal.z());
// Second segment point
subject[(6 * index) + 3]= static_cast<GLfloat>(normal.x());
subject[(6 * index) + 4]= static_cast<GLfloat>(normal.y());
subject[(6 * index) + 5]= static_cast<GLfloat>(normal.z());
++index;
}
return subject;
}
GLfloatVector GLC_ExtrudedMesh::baseFaceVertices() const
{
const int count= m_Points.count();
GLfloatVector subject(count * 3); // 3 components pear vertice
for (int i= 0; i < count; ++i)
{
GLC_Point3d point= m_Points.at(i);
subject[(3 * i)]= static_cast<GLfloat>(point.x());
subject[(3 * i) + 1]= static_cast<GLfloat>(point.y());
subject[(3 * i) + 2]= static_cast<GLfloat>(point.z());
}
return subject;
}
GLfloatVector GLC_ExtrudedMesh::baseFaceTexels() const
{
const int count= m_Points.count();
GLfloatVector subject(count * 2);
QList<GLC_Point2d> baseFace2DPolygon= glc::polygonIn2d(m_Points);
QList<GLC_Point2d> normalizePolygon= glc::normalyzePolygon(baseFace2DPolygon);
for (int i= 0; i < count; ++i)
{
GLC_Point2d texel= normalizePolygon.at(i);
subject[i * 2]= static_cast<GLfloat>(texel.x());
subject[i * 2 + 1]= static_cast<GLfloat>(texel.y());
}
return subject;
}
GLfloatVector GLC_ExtrudedMesh::baseOutlineFacesVertices() const
{
const int count= m_Points.count();
GLfloatVector subject(count * 6); // 3 components pear vertice * 2
for (int i= 0; i < count; ++i)
{
GLC_Point3d point1= m_Points.at(i);
subject[(6 * i)]= static_cast<GLfloat>(point1.x());
subject[(6 * i) + 1]= static_cast<GLfloat>(point1.y());
subject[(6 * i) + 2]= static_cast<GLfloat>(point1.z());
GLC_Point3d point2= m_Points.at((i + 1) % count);
subject[(6 * i) + 3]= static_cast<GLfloat>(point2.x());
subject[(6 * i) + 4]= static_cast<GLfloat>(point2.y());
subject[(6 * i) + 5]= static_cast<GLfloat>(point2.z());
}
return subject;
}
GLfloatVector GLC_ExtrudedMesh::basedOutlineFacesTexels() const
{
const int count= m_Points.count();
GLfloatVector subject(count * 4);
QList<GLC_Point2d> baseFace2DPolygon= glc::polygonIn2d(m_Points);
QList<GLC_Point2d> normalizePolygon= glc::normalyzePolygon(baseFace2DPolygon);
for (int i= 0; i < count; ++i)
{
GLC_Point2d texel1= normalizePolygon.at(i);
subject[i * 4]= static_cast<GLfloat>(texel1.x());
subject[i * 4 + 1]= static_cast<GLfloat>(texel1.y());
GLC_Point2d texel2= normalizePolygon.at((i + 1) % count);
subject[i * 4 + 2]= static_cast<GLfloat>(texel2.x());
subject[i * 4 + 3]= static_cast<GLfloat>(texel2.y());
}
return subject;
}
GLfloatVector GLC_ExtrudedMesh::baseFaceNormals() const
{
const int count= m_Points.count();
GLfloatVector subject(count * 3); // 3 components pear normal
for (int i= 0; i < count; ++i)
{
subject[(3 * i)]= static_cast<GLfloat>(m_GivenFaceNormal.x());
subject[(3 * i) + 1]= static_cast<GLfloat>(m_GivenFaceNormal.y());
subject[(3 * i) + 2]= static_cast<GLfloat>(m_GivenFaceNormal.z());
}
return subject;
}
QList<GLC_Point3d> GLC_ExtrudedMesh::createdFacePoints() const
{
// The order is inverted to preserve face counterclockwise order
const GLC_Vector3d offset(m_ExtrusionVector * m_ExtrusionLenght);
const int count= m_Points.count();
QList<GLC_Point3d> subject;
for (int i= 0; i < count; ++i)
{
subject.append(m_Points.at((count -i) % count) + offset);
}
return subject;
}
GLfloatVector GLC_ExtrudedMesh::createdFaceNormals() const
{
const GLC_Vector3d normal= m_GivenFaceNormal.inverted();
const int count= m_Points.count();
GLfloatVector subject(count * 3); // 3 components pear normal
for (int i= 0; i < count; ++i)
{
subject[(3 * i)]= static_cast<GLfloat>(normal.x());
subject[(3 * i) + 1]= static_cast<GLfloat>(normal.y());
subject[(3 * i) + 2]= static_cast<GLfloat>(normal.z());
}
return subject;
}
GLfloatVector GLC_ExtrudedMesh::createdFaceVertices() const
{
QList<GLC_Point3d> points= createdFacePoints();
const int count= points.count();
GLfloatVector subject(count * 3); // 3 components pear normal
for (int i= 0; i < count; ++i)
{
GLC_Point3d point= points.at(i);
subject[(3 * i)]= static_cast<GLfloat>(point.x());
subject[(3 * i) + 1]= static_cast<GLfloat>(point.y());
subject[(3 * i) + 2]= static_cast<GLfloat>(point.z());
}
return subject;
}
GLfloatVector GLC_ExtrudedMesh::createdFaceTexels() const
{
const int count= m_Points.count();
GLfloatVector subject(count * 2);
QList<GLC_Point2d> baseFace2DPolygon= glc::polygonIn2d(createdFacePoints());
QList<GLC_Point2d> normalizePolygon= glc::normalyzePolygon(baseFace2DPolygon);
for (int i= 0; i < count; ++i)
{
GLC_Point2d texel= normalizePolygon.at(i);
subject[i * 2]= static_cast<GLfloat>(texel.x());
subject[i * 2 + 1]= static_cast<GLfloat>(texel.y());
}
return subject;
}
GLfloatVector GLC_ExtrudedMesh::createdOutlineFacesVertices() const
{
QList<GLC_Point3d> points= createdFacePoints();
const int count= points.count();
GLfloatVector subject(count * 6); // 3 components pear vertice * 2
for (int i= 0; i < count; ++i)
{
GLC_Point3d point1= points.at(i);
subject[(6 * i)]= static_cast<GLfloat>(point1.x());
subject[(6 * i) + 1]= static_cast<GLfloat>(point1.y());
subject[(6 * i) + 2]= static_cast<GLfloat>(point1.z());
GLC_Point3d point2= points.at((i + 1) % count);
subject[(6 * i) + 3]= static_cast<GLfloat>(point2.x());
subject[(6 * i) + 4]= static_cast<GLfloat>(point2.y());
subject[(6 * i) + 5]= static_cast<GLfloat>(point2.z());
}
return subject;
}
GLfloatVector GLC_ExtrudedMesh::createdOutlineFacesTexels() const
{
const int count= m_Points.count();
GLfloatVector subject(count * 4);
QList<GLC_Point2d> baseFace2DPolygon= glc::polygonIn2d(createdFacePoints());
QList<GLC_Point2d> normalizePolygon= glc::normalyzePolygon(baseFace2DPolygon);
for (int i= 0; i < count; ++i)
{
GLC_Point2d texel1= normalizePolygon.at(i);
subject[i * 4]= static_cast<GLfloat>(texel1.x());
subject[i * 4 + 1]= static_cast<GLfloat>(texel1.y());
GLC_Point2d texel2= normalizePolygon.at((i + 1) % count);
subject[i * 4 + 2]= static_cast<GLfloat>(texel2.x());
subject[i * 4 + 3]= static_cast<GLfloat>(texel2.y());
}
return subject;
}
void GLC_ExtrudedMesh::glDraw(const GLC_RenderProperties& renderProperties)
{
if (GLC_Mesh::isEmpty())
{
createMeshAndWire();
}
GLC_Mesh::glDraw(renderProperties);
}

View File

@ -0,0 +1,203 @@
/****************************************************************************
This file is part of the GLC-lib library.
Copyright (C) 2005-2013 Laurent Ribon (laumaya@users.sourceforge.net)
http://glc-lib.sourceforge.net
GLC-lib is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
GLC-lib is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with GLC-lib; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
//! \file glc_extrudedmesh.h Interface for the GLC_ExtrudedMesh class.
#ifndef GLC_EXTRUDEDMESH_H
#define GLC_EXTRUDEDMESH_H
#include <QList>
#include "glc_mesh.h"
#include "../maths/glc_vector3d.h"
#include "../glc_config.h"
//////////////////////////////////////////////////////////////////////
//! \class GLC_ExtrudedMesh
/*! \brief GLC_ExtrudedMesh : An Extruded mesh defined by a list of points,
*a direction and a distance*/
//////////////////////////////////////////////////////////////////////
class GLC_LIB_EXPORT GLC_ExtrudedMesh : public GLC_Mesh
{
//////////////////////////////////////////////////////////////////////
/*! @name Constructor / Destructor */
//@{
//////////////////////////////////////////////////////////////////////
public:
//! Default constructor
/*! The points list must be in counterclockwise order*/
GLC_ExtrudedMesh(const QList<GLC_Point3d>& points, const GLC_Vector3d& dir, double lenght);
//! Copy constructor
GLC_ExtrudedMesh(const GLC_ExtrudedMesh& other);
//! Destructor
virtual ~GLC_ExtrudedMesh();
//@}
//////////////////////////////////////////////////////////////////////
/*! \name Get Functions*/
//@{
//////////////////////////////////////////////////////////////////////
public:
//! Return the class Chunk ID
static quint32 chunckID();
//! Return the list of points which defined the face to extrude
inline QList<GLC_Point3d> facePoints() const
{return m_Points;}
//! Return the extrusion vector
inline GLC_Vector3d extrusionVector() const
{return m_ExtrusionVector;}
//! Return the extrusion lenght
inline double extrusionLenght() const
{return m_ExtrusionLenght;}
//! Return a copy of the extruded mesh
virtual GLC_Geometry* clone() const;
//! Return the extruded mesh bounding box
virtual const GLC_BoundingBox& boundingBox(void);
//@}
//////////////////////////////////////////////////////////////////////
/*! \name Set Functions*/
//@{
//////////////////////////////////////////////////////////////////////
public:
//! Assignement operator overload
GLC_ExtrudedMesh& operator=(const GLC_ExtrudedMesh& other);
//! Set the mesh from the given points, vector and lenght
void setGeometry(const QList<GLC_Point3d>& points, const GLC_Vector3d& extrudedVector, double lenght);
//! Set the mesh points list
void setPoints(const QList<GLC_Point3d>& points);
//! Set the mesh extruded vector
void setExtrudedVector(const GLC_Vector3d& extrudedVector);
//! Set the mesh extruded lenght
void setExtrudedLenght(double lenght);
//@}
//////////////////////////////////////////////////////////////////////
/*! \name OpenGL Functions*/
//@{
//////////////////////////////////////////////////////////////////////
protected:
//! Virtual interface for OpenGL Geometry set up.
/*! This Virtual function have to be implemented in concrete class.*/
virtual void glDraw(const GLC_RenderProperties& renderProperties);
//@}
//////////////////////////////////////////////////////////////////////
/*! \name Private services Functions*/
//@{
//////////////////////////////////////////////////////////////////////
private:
//! Create the extruded mesh mesh and wire
void createMeshAndWire();
//! Create the extruded mesh mesh
void createMesh();
//! Create the extruded mesh wire
void createWire();
//! compute the given face normal
void computeGivenFaceNormal();
//! Return true if the list of points lie on a plane
bool pointsLieOnAPlane() const;
//! Return base outline normmals
GLfloatVector baseOutlineNormals() const;
//! Return created outline normmals
GLfloatVector createdOutlineNormals() const;
//! Return base face vertices
GLfloatVector baseFaceVertices() const;
//! Return base face texel
GLfloatVector baseFaceTexels() const;
//! Return base outline faces vertices
GLfloatVector baseOutlineFacesVertices() const;
//! Return base outline faces texels
GLfloatVector basedOutlineFacesTexels() const;
//! Return the base face normals
GLfloatVector baseFaceNormals() const;
//! Return the list of points of the created face
QList<GLC_Point3d> createdFacePoints() const;
//! Return the created face normals
GLfloatVector createdFaceNormals() const;
//! Return created face vertices
GLfloatVector createdFaceVertices() const;
//! Return created face texels
GLfloatVector createdFaceTexels() const;
//! Return created outline faces vertices
GLfloatVector createdOutlineFacesVertices() const;
//! Return created outline faces texels
GLfloatVector createdOutlineFacesTexels() const;
//@}
//////////////////////////////////////////////////////////////////////
// Private members
//////////////////////////////////////////////////////////////////////
private:
//! The list of point which define the face to extrude
QList<GLC_Point3d> m_Points;
//! The direction of extrusion
GLC_Vector3d m_ExtrusionVector;
//! The extrusion lenght
double m_ExtrusionLenght;
//! The normal of the given face
GLC_Vector3d m_GivenFaceNormal;
//! Class chunk id
static quint32 m_ChunkId;
};
#endif // GLC_EXTRUDEDMESH_H

View File

@ -228,6 +228,29 @@ QVector<GLuint> GLC_Mesh::getTrianglesIndex(int lod, GLC_uint materialId) const
return resultIndex;
}
IndexList GLC_Mesh::getEquivalentTrianglesStripsFansIndex(int lod, GLC_uint materialId)
{
IndexList subject;
if (containsTriangles(lod, materialId))
{
subject= getTrianglesIndex(lod, materialId).toList();
}
if (containsStrips(lod, materialId))
{
subject.append(equivalentTrianglesIndexOfstripsIndex(lod, materialId));
}
if (containsFans(lod, materialId))
{
subject.append(equivalentTrianglesIndexOfFansIndex(lod, materialId));
}
Q_ASSERT((subject.count() % 3) == 0);
return subject;
}
// Return the number of triangles
int GLC_Mesh::numberOfTriangles(int lod, GLC_uint materialId) const
{
@ -317,7 +340,39 @@ int GLC_Mesh::numberOfFans(int lod, GLC_uint materialId) const
// Check if the lod exist and material exists
if(!m_PrimitiveGroups.contains(lod))return 0;
else if (!m_PrimitiveGroups.value(lod)->contains(materialId)) return 0;
else return m_PrimitiveGroups.value(lod)->value(materialId)->fansSizes().size();
else return m_PrimitiveGroups.value(lod)->value(materialId)->fansSizes().size();
}
GLC_Material *GLC_Mesh::MaterialOfPrimitiveId(GLC_uint id, int lod) const
{
GLC_Material* pSubject= NULL;
if (!m_PrimitiveGroups.isEmpty())
{
LodPrimitiveGroups* pMasterLodPrimitiveGroup= m_PrimitiveGroups.value(lod);
LodPrimitiveGroups::const_iterator iGroup= pMasterLodPrimitiveGroup->constBegin();
while (iGroup != pMasterLodPrimitiveGroup->constEnd())
{
GLC_PrimitiveGroup* pCurrentGroup= iGroup.value();
QList<GLC_uint> listOfId;
listOfId.append(pCurrentGroup->triangleGroupId());
listOfId.append(pCurrentGroup->stripGroupId());
listOfId.append(pCurrentGroup->fanGroupId());
if (listOfId.contains(id))
{
const GLC_uint materialId= pCurrentGroup->id();
pSubject= this->material(materialId);
iGroup= pMasterLodPrimitiveGroup->constEnd();
}
else
{
++iGroup;
}
}
}
return pSubject;
}
// Return the strips index
@ -365,6 +420,26 @@ QList<QVector<GLuint> > GLC_Mesh::getFansIndex(int lod, GLC_uint materialId) con
return result;
}
QSet<GLC_uint> GLC_Mesh::setOfPrimitiveId() const
{
QList<GLC_uint> subject;
if (!m_PrimitiveGroups.isEmpty())
{
LodPrimitiveGroups* pMasterLodPrimitiveGroup= m_PrimitiveGroups.value(0);
LodPrimitiveGroups::const_iterator iGroup= pMasterLodPrimitiveGroup->constBegin();
while (iGroup != pMasterLodPrimitiveGroup->constEnd())
{
GLC_PrimitiveGroup* pCurrentGroup= iGroup.value();
subject.append(pCurrentGroup->triangleGroupId());
subject.append(pCurrentGroup->stripGroupId());
subject.append(pCurrentGroup->fanGroupId());
++iGroup;
}
}
return QSet<GLC_uint>::fromList(subject);
}
GLC_Mesh* GLC_Mesh::createMeshOfGivenLod(int lodIndex)
{
Q_ASSERT(m_MeshData.lodCount() > lodIndex);
@ -645,11 +720,18 @@ void GLC_Mesh::reverseNormals()
// Copy index list in a vector for Vertex Array Use
void GLC_Mesh::finish()
{
boundingBox();
if (m_MeshData.lodCount() > 0)
{
boundingBox();
m_MeshData.finishLod();
m_MeshData.finishLod();
moveIndexToMeshDataLod();
moveIndexToMeshDataLod();
}
else
{
clear();
}
//qDebug() << "Mesh mem size= " << memmorySize();
}
@ -662,7 +744,7 @@ void GLC_Mesh::setCurrentLod(const int value)
{
const int numberOfLod= m_MeshData.lodCount() - 1;
// Clamp value to number of load
m_CurrentLod= qRound(static_cast<int>((static_cast<double>(value) / 100.0) * numberOfLod));
m_CurrentLod= static_cast<int>((static_cast<double>(value) / 100.0) * numberOfLod);
}
else
{

View File

@ -123,6 +123,9 @@ public:
/*! The specified LOD must exists and uses the specified material id*/
QVector<GLuint> getTrianglesIndex(int lod, GLC_uint materialId) const;
//! Return the equivalent triangle index of (triangle, strip and fan)
IndexList getEquivalentTrianglesStripsFansIndex(int lod, GLC_uint materialId);
//! Return the number of triangles in the specified LOD
int numberOfTriangles(int lod, GLC_uint materialId) const;
@ -169,6 +172,12 @@ public:
inline GLC_uint nextPrimitiveLocalId() const
{return m_NextPrimitiveLocalId;}
//! Return the GLC_Material applyed on the given primitive id of the given lod
GLC_Material* MaterialOfPrimitiveId(GLC_uint id, int lod= 0) const;
//! Return the set of primitives id
QSet<GLC_uint> setOfPrimitiveId() const;
//! Return true if the mesh position data is empty
inline bool isEmpty() const
{return m_MeshData.isEmpty();}

View File

@ -146,8 +146,13 @@ public:
//! Return the number of triangle from the given lod index
inline unsigned int trianglesCount(int lod) const
{
Q_ASSERT(lod < m_LodList.size());
return m_LodList.at(lod)->trianglesCount();
unsigned int subject= 0;
if (!m_LodList.isEmpty())
{
Q_ASSERT(lod < m_LodList.size());
subject= m_LodList.at(lod)->trianglesCount();
}
return subject;
}
//! Return true if the position size is set

View File

@ -88,8 +88,12 @@ public:
inline bool containsTrianglesGroupId() const
{return !m_TrianglesId.isEmpty();}
//! Return the Triangle group ID
inline GLC_uint triangleGroupId(int index)
//! Return the triangle group ID
inline QList<GLC_uint> triangleGroupId() const
{return m_TrianglesId;}
//! Return the Triangle group ID at the given index
inline GLC_uint triangleGroupId(int index) const
{return m_TrianglesId.at(index);}
//! Return the size of list of triangles index of the group
@ -132,7 +136,11 @@ public:
{return !m_StripsId.isEmpty();}
//! Return the strip ID
inline GLC_uint stripGroupId(int index)
inline QList<GLC_uint> stripGroupId() const
{return m_StripsId;}
//! Return the strip ID at the given index
inline GLC_uint stripGroupId(int index) const
{return m_StripsId.at(index);}
//! Return the size of index of strips
@ -167,7 +175,11 @@ public:
{return !m_FansId.isEmpty();}
//! Return the fan ID
inline GLC_uint fanGroupId(int index)
inline QList<GLC_uint> fanGroupId() const
{return m_FansId;}
//! Return the fan ID at the given index
inline GLC_uint fanGroupId(int index) const
{return m_FansId.at(index);}
//! Return the size of index of fans

View File

@ -130,9 +130,6 @@ void GLC_Rectangle::createMeshAndWire()
GLfloatVector normalsVector;
GLfloatVector texelVector;
// Wire data
GLfloatVector wireData;
// the unique face of this rectangle
verticeVector << -lgX; verticeVector << -lgY; verticeVector << 0.0f;
normalsVector << 0.0f; normalsVector << 0.0f; normalsVector << 1.0f;

View File

@ -27,14 +27,28 @@
// Class chunk id
quint32 GLC_Sphere::m_ChunkId= 0xA710;
GLC_Sphere::GLC_Sphere(double radius)
GLC_Sphere::GLC_Sphere(double radius, int discretization)
: GLC_Mesh()
, m_Radius (radius)
, m_Discret(glc::GLC_POLYDISCRET)
, m_Discret(discretization)
, m_ThetaMin (0.0)
, m_ThetaMax(2 * glc::PI)
, m_PhiMin(-glc::PI / 2.0)
, m_PhiMax(glc::PI / 2.0)
, m_Center()
{
createMesh();
}
GLC_Sphere::GLC_Sphere(double radius, const GLC_Point3d& center, int discretization)
: GLC_Mesh()
, m_Radius (radius)
, m_Discret(discretization)
, m_ThetaMin (0.0)
, m_ThetaMax(2 * glc::PI)
, m_PhiMin(-glc::PI / 2.0)
, m_PhiMax(glc::PI / 2.0)
, m_Center(center)
{
createMesh();
}
@ -48,8 +62,9 @@ GLC_Sphere::GLC_Sphere(const GLC_Sphere & sphere)
, m_ThetaMax(sphere.m_ThetaMax)
, m_PhiMin(sphere.m_PhiMin)
, m_PhiMax(sphere.m_PhiMax)
, m_Center(sphere.m_Center)
{
createMesh();
if (isEmpty()) createMesh();
}
GLC_Sphere::~GLC_Sphere()
@ -92,6 +107,16 @@ void GLC_Sphere::setDiscretion(int TargetDiscret)
}
}
void GLC_Sphere::setCenter(const GLC_Point3d& pos)
{
if (pos != m_Center)
{
m_Center= pos;
GLC_Mesh::clearMeshWireAndBoundingBox();
}
}
void GLC_Sphere::glDraw(const GLC_RenderProperties& renderProperties)
{
if (GLC_Mesh::isEmpty())
@ -139,6 +164,10 @@ void GLC_Sphere::createMesh()
else
pMaterial= new GLC_Material();
const double dx= m_Center.x();
const double dy= m_Center.y();
const double dz= m_Center.z();
// shaded face
for (int p= 0; p < nbPhiSteps; ++p)
{
@ -164,7 +193,7 @@ void GLC_Sphere::createMesh()
xf= m_Radius * cost * cospp;
yf= m_Radius * sint * cospp;
verticeFloat << xf << yf << zf << xi << yi << zi;
verticeFloat << (xf + dx) << (yf + dy) << (zf + dz) << (xi + dx) << (yi + dy) << (zi + dz);
normalsFloat << cost * cospp << sint * cospp << sinpp << cost * cosp << sint * cosp << sinp;
texelVector << static_cast<double>(t) * 1.0 / static_cast<double>(nbThetaSteps)
<< static_cast<double>(p) * 1.0 / static_cast<double>(nbPhiSteps)

View File

@ -26,7 +26,7 @@
#define GLC_SPHERE_H_
#include "glc_mesh.h"
#include "../maths/glc_vector3d.h"
#include "../glc_config.h"
//////////////////////////////////////////////////////////////////////
@ -43,7 +43,10 @@ class GLC_LIB_EXPORT GLC_Sphere : public GLC_Mesh
//////////////////////////////////////////////////////////////////////
public:
//! Construct a sphere with the given radius
GLC_Sphere(double radius);
GLC_Sphere(double radius, int discretization= glc::GLC_POLYDISCRET);
//! Construct a sphere with the given radius and center
GLC_Sphere(double radius, const GLC_Point3d& center, int discretization= glc::GLC_POLYDISCRET);
//! Copy constructor
GLC_Sphere(const GLC_Sphere & sphere);
@ -73,6 +76,10 @@ public:
//! Return the sphere bounding box
virtual const GLC_BoundingBox& boundingBox(void);
//! Return the sphere center
inline GLC_Point3d center() const
{return m_Center;}
//@}
//////////////////////////////////////////////////////////////////////
@ -88,6 +95,9 @@ public:
/*! Discretion must be > 0*/
void setDiscretion(int TargetDiscret);
//! Set Sphere center
void setCenter(const GLC_Point3d& pos);
//@}
//////////////////////////////////////////////////////////////////////
@ -126,6 +136,8 @@ private:
double m_PhiMin;
double m_PhiMax;
GLC_Point3d m_Center;
//! Class chunk id
static quint32 m_ChunkId;

View File

@ -46,5 +46,5 @@ const char* GLC_Exception::what() const throw()
{
QString exceptionmsg("GLC_Exception : ");
exceptionmsg.append(m_ErrorDescription);
return exceptionmsg.toAscii().data();
return exceptionmsg.toLatin1().data();
}

View File

@ -25,19 +25,20 @@
#define GLC_EXT_H_
#include <QtOpenGL>
#include "3rdparty/glext/glext.h"
// Buffer offset used by VBO
#define BUFFER_OFFSET(i) ((char*)NULL + (i))
#if !defined(Q_OS_MAC)
// GL_point_parameters Point Sprite
#include "3rdparty/glext/glext.h"
extern PFNGLPOINTPARAMETERFARBPROC glPointParameterf;
extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfv;
#endif
// Buffer offset used by VBO
#define BUFFER_OFFSET(i) ((char*)NULL + (i))
namespace glc
{
//! Return true if the extension is supported

View File

@ -47,5 +47,5 @@ const char* GLC_FileFormatException::what() const throw()
exceptionmsg.append(m_ErrorDescription);
exceptionmsg.append(" in file : ");
exceptionmsg.append(m_FileName);
return exceptionmsg.toAscii().data();
return exceptionmsg.toLatin1().data();
}

View File

@ -120,7 +120,7 @@ namespace glc
GLC_LIB_EXPORT QString archiveEntryFileName(const QString& archiveString);
// GLC_Lib version
const QString version("2.2.0");
const QString version("2.5.0");
const QString description("GLC_lib is a Open Source C++ class library that enables the quick creation of an OpenGL application based on QT4.");
};

View File

@ -82,6 +82,7 @@ HEADERS_GLC_IO += io/glc_objmtlloader.h \
io/glc_3dxmltoworld.h \
io/glc_colladatoworld.h \
io/glc_worldto3dxml.h \
io/glc_worldto3ds.h \
io/glc_bsreptoworld.h \
io/glc_xmlutil.h \
io/glc_fileloader.h \
@ -122,14 +123,16 @@ HEADERS_GLC_GEOMETRY += geometry/glc_geometry.h \
geometry/glc_disc.h \
geometry/glc_cone.h \
geometry/glc_sphere.h \
geometry/glc_pointcloud.h
geometry/glc_pointcloud.h \
geometry/glc_extrudedmesh.h
HEADERS_GLC_SHADING += shading/glc_material.h \
shading/glc_texture.h \
shading/glc_shader.h \
shading/glc_selectionmaterial.h \
shading/glc_light.h \
shading/glc_renderproperties.h
shading/glc_renderproperties.h \
shading/glc_renderer.h
HEADERS_GLC_VIEWPORT += viewport/glc_camera.h \
viewport/glc_imageplane.h \
@ -238,6 +241,7 @@ SOURCES += io/glc_objmtlloader.cpp \
io/glc_3dxmltoworld.cpp \
io/glc_colladatoworld.cpp \
io/glc_worldto3dxml.cpp \
io/glc_worldto3ds.cpp \
io/glc_bsreptoworld.cpp \
io/glc_fileloader.cpp
@ -275,7 +279,8 @@ SOURCES += geometry/glc_geometry.cpp \
geometry/glc_disc.cpp \
geometry/glc_cone.cpp \
geometry/glc_sphere.cpp \
geometry/glc_pointcloud.cpp
geometry/glc_pointcloud.cpp \
geometry/glc_extrudedmesh.cpp
SOURCES += shading/glc_material.cpp \
@ -283,7 +288,8 @@ SOURCES += shading/glc_material.cpp \
shading/glc_light.cpp \
shading/glc_selectionmaterial.cpp \
shading/glc_shader.cpp \
shading/glc_renderproperties.cpp
shading/glc_renderproperties.cpp \
shading/glc_renderer.cpp
SOURCES += viewport/glc_camera.cpp \
viewport/glc_imageplane.cpp \
@ -416,6 +422,7 @@ HEADERS_INST = include/GLC_BoundingBox \
include/GLC_FlyMover \
include/GLC_RepFlyMover \
include/GLC_WorldTo3dxml \
include/GLC_WorldTo3ds \
include/GLC_RenderStatistics \
include/GLC_Ext \
include/GLC_Cone \
@ -435,7 +442,9 @@ HEADERS_INST = include/GLC_BoundingBox \
include/GLC_TsrMover \
include/GLC_Glu \
include/GLC_Context \
include/GLC_ContextManager
include/GLC_ContextManager \
include/GLC_Renderer \
include/GLC_ExtrudedMesh
# Linux and macx install configuration

View File

@ -31,6 +31,15 @@
GLC_Object::GLC_Object(const QString& name)
: m_Uid(glc::GLC_GenID()) // Object ID
, m_Name(name) // Object Name
, m_Mutex()
{
}
GLC_Object::GLC_Object(GLC_uint id, const QString& name)
: m_Uid(id)
, m_Name(name)
, m_Mutex()
{
}
@ -38,6 +47,7 @@ GLC_Object::GLC_Object(const QString& name)
GLC_Object::GLC_Object(const GLC_Object& sourceObject)
: m_Uid(sourceObject.m_Uid)
, m_Name(sourceObject.m_Name)
, m_Mutex()
{
}

View File

@ -57,6 +57,9 @@ public:
* and set GLC_Object::m_Name to specified name*/
GLC_Object(const QString& name= QString());
//! Construct a GLC_Object with the given UID
GLC_Object(GLC_uint id, const QString& name= QString());
//! Construct a GLC_Object from the given GLC_Object
GLC_Object(const GLC_Object& sourceObject);

View File

@ -74,5 +74,5 @@ const char* GLC_OpenGlException::what() const throw()
QString exceptionmsg("GLC_OpenGlException : ");
exceptionmsg.append(m_ErrorDescription);
exceptionmsg.append(m_GlErrorDescription);
return exceptionmsg.toAscii().data();
return exceptionmsg.toLatin1().data();
}

View File

@ -0,0 +1 @@
#include "geometry/glc_extrudedmesh.h"

View File

@ -0,0 +1,2 @@
#include "shading/glc_renderer.h"

View File

@ -0,0 +1 @@
#include "io/glc_worldto3ds.h"

View File

@ -97,7 +97,7 @@ bool GLC_ObjMtlLoader::loadMaterials()
{
lineBuff= mtlStream.readLine();
//qDebug() << lineBuff;
QTextStream streamLine(lineBuff.toAscii());
QTextStream streamLine(lineBuff.toLatin1());
if ((streamLine >> header).status() ==QTextStream::Ok)
{

View File

@ -0,0 +1,497 @@
/****************************************************************************
This file is part of the GLC-lib library.
Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
http://glc-lib.sourceforge.net
GLC-lib is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
GLC-lib is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with GLC-lib; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
//! \file glc_worldto3ds.cpp implementation of the GLC_WorldTo3ds class.
#include <QFile>
#include <QtDebug>
#include "../geometry/glc_3drep.h"
#include "../geometry/glc_geometry.h"
#include "../geometry/glc_mesh.h"
#include "../shading/glc_material.h"
// Lib3ds Header
#include "3rdparty/lib3ds/file.h"
#include "3rdparty/lib3ds/mesh.h"
#include "3rdparty/lib3ds/node.h"
#include "3rdparty/lib3ds/matrix.h"
#include "3rdparty/lib3ds/material.h"
#include "glc_worldto3ds.h"
GLC_WorldTo3ds::GLC_WorldTo3ds(const GLC_World& world)
: QObject()
, m_World(world)
, m_pLib3dsFile(NULL)
, m_FileName()
, m_ReferenceToMesh()
, m_NameToMaterial()
, m_pRootLib3dsNode(NULL)
, m_CurrentNodeId(0)
, m_OccIdToNodeId()
, m_CurrentMeshIndex(0)
, m_UseAbsolutePosition(false)
, m_TextureToFileName()
{
}
GLC_WorldTo3ds::~GLC_WorldTo3ds()
{
}
//////////////////////////////////////////////////////////////////////
// Set Functions
//////////////////////////////////////////////////////////////////////
bool GLC_WorldTo3ds::exportToFile(const QString& fileName, bool useAbsolutePosition)
{
m_ReferenceToMesh.clear();
m_NameToMaterial.clear();
m_pRootLib3dsNode= NULL;
m_CurrentNodeId= 0;
m_OccIdToNodeId.clear();
m_CurrentMeshIndex= 0;
m_UseAbsolutePosition= useAbsolutePosition;
m_TextureToFileName.clear();
m_FileName= fileName;
bool subject= false;
{
QFile exportFile(m_FileName);
subject= exportFile.open(QIODevice::WriteOnly);
exportFile.close();
}
if (subject)
{
m_pLib3dsFile= lib3ds_file_new();
saveWorld();
subject= lib3ds_file_save(m_pLib3dsFile, fileName.toLatin1().data());
}
return subject;
}
//////////////////////////////////////////////////////////////////////
// Private services functions
//////////////////////////////////////////////////////////////////////
void GLC_WorldTo3ds::saveWorld()
{
if (!m_UseAbsolutePosition)
{
saveMeshes();
}
// Save node structure
GLC_StructOccurence* pRoot= m_World.rootOccurence();
const int childCount= pRoot->childCount();
for (int i= 0; i < childCount; ++i)
{
saveBranch(pRoot->child(i));
}
}
void GLC_WorldTo3ds::saveMeshes()
{
// Retrieve the list of mesh and save them into the 3ds
QList<GLC_StructReference*> refList= m_World.references();
const int refCount= refList.count();
for (int i= 0; i < refCount; ++i)
{
GLC_StructReference* pRef= refList.at(i);
if (pRef->hasRepresentation())
{
GLC_3DRep* pRep= dynamic_cast<GLC_3DRep*>(pRef->representationHandle());
if (NULL != pRep)
{
// This reference has a mesh
const QString meshName= pRef->name() + '_' + QString::number(++m_CurrentMeshIndex);
QList<Lib3dsMesh*> meshes= createMeshsFrom3DRep(pRep, meshName);
{
const int count= meshes.count();
for (int i= 0; i < count; ++i)
{
lib3ds_file_insert_mesh(m_pLib3dsFile, meshes.at(i));
m_ReferenceToMesh.insertMulti(pRef, meshes.at(i));
}
}
}
}
}
}
void GLC_WorldTo3ds::saveBranch(GLC_StructOccurence* pOcc)
{
createNodeFromOccurrence(pOcc);
const int childCount= pOcc->childCount();
for (int i= 0; i < childCount; ++i)
{
saveBranch(pOcc->child(i));
}
}
void GLC_WorldTo3ds::createNodeFromOccurrence(GLC_StructOccurence* pOcc)
{
Lib3dsNode* p3dsNode = lib3ds_node_new_object();
p3dsNode->node_id= m_CurrentNodeId;
m_OccIdToNodeId.insert(pOcc->id(), m_CurrentNodeId++);
if (pOcc->parent() == m_World.rootOccurence())
{
p3dsNode->parent_id= LIB3DS_NO_PARENT;
}
else
{
Q_ASSERT(m_OccIdToNodeId.contains(pOcc->parent()->id()));
p3dsNode->parent_id= m_OccIdToNodeId.value(pOcc->parent()->id());
}
lib3ds_file_insert_node(m_pLib3dsFile, p3dsNode);
GLC_StructReference* pRef= pOcc->structReference();
if (m_UseAbsolutePosition)
{
if (pOcc->structReference()->hasRepresentation())
{
GLC_3DRep* pRep= dynamic_cast<GLC_3DRep*>(pOcc->structReference()->representationHandle());
if (NULL != pRep)
{
// This reference has a mesh
const GLC_Matrix4x4 matrix= pOcc->absoluteMatrix();
const QString meshName= pRef->name() + '_' + QString::number(++m_CurrentMeshIndex);
QList<Lib3dsMesh*> meshes= createMeshsFrom3DRep(pRep, meshName, matrix);
const int meshCount= meshes.count();
for (int i= 0; i < meshCount; ++i)
{
lib3ds_file_insert_mesh(m_pLib3dsFile, meshes.at(i));
}
if (meshCount > 1)
{
for (int i= 0; i < meshCount; ++i)
{
Lib3dsNode* pCurrent3dsNode = lib3ds_node_new_object();
pCurrent3dsNode->node_id= m_CurrentNodeId++;
pCurrent3dsNode->parent_id= p3dsNode->node_id;
strcpy(pCurrent3dsNode->name, meshes.at(i)->name);
lib3ds_file_insert_node(m_pLib3dsFile, pCurrent3dsNode);
}
}
else if (!meshes.isEmpty())
{
strcpy(p3dsNode->name, meshes.first()->name);
}
}
}
}
else
{
// Node matrix
const GLC_Matrix4x4 matrix= pOcc->structInstance()->relativeMatrix();
setNodePosition(p3dsNode, matrix);
// Set mesh name if necessary
if (m_ReferenceToMesh.contains(pRef))
{
QList<Lib3dsMesh*> meshes= m_ReferenceToMesh.values(pRef);
const int meshCount= meshes.count();
if (meshCount > 1)
{
for (int i= 0; i < meshCount; ++i)
{
Lib3dsNode* pCurrent3dsNode = lib3ds_node_new_object();
pCurrent3dsNode->node_id= m_CurrentNodeId++;
pCurrent3dsNode->parent_id= p3dsNode->node_id;
strcpy(pCurrent3dsNode->name, meshes.at(i)->name);
lib3ds_file_insert_node(m_pLib3dsFile, pCurrent3dsNode);
}
}
else
{
strcpy(p3dsNode->name, m_ReferenceToMesh.value(pRef)->name);
}
}
}
}
QList<Lib3dsMesh*> GLC_WorldTo3ds::createMeshsFrom3DRep(GLC_3DRep* pRep, const QString& name, const GLC_Matrix4x4& matrix)
{
QList<Lib3dsMesh*> subject;
int bodyIndex= 0;
const int bodyCount= pRep->numberOfBody();
for (int i= 0; i < bodyCount; ++i)
{
GLC_Mesh* pCurrentMesh= dynamic_cast<GLC_Mesh*>(pRep->geomAt(i));
if ((NULL != pCurrentMesh) && !pCurrentMesh->isEmpty())
{
bool deleteCurrentMesh= false;
if (pCurrentMesh->lodCount() > 1)
{
// Keep only the first level of detail
pCurrentMesh= pCurrentMesh->createMeshOfGivenLod(0);
deleteCurrentMesh= true;
}
const QString bodyMeshName= name + '_' + QString::number(bodyIndex++);
if (matrix.type() != GLC_Matrix4x4::Identity)
{
if (!deleteCurrentMesh)
{
pCurrentMesh= new GLC_Mesh(*pCurrentMesh);
deleteCurrentMesh= true;
}
pCurrentMesh->transformVertice(matrix);
Q_ASSERT(!pCurrentMesh->isEmpty());
}
Lib3dsMesh* p3dsMesh= create3dsMeshFromGLC_Mesh(pCurrentMesh, bodyMeshName);
if (deleteCurrentMesh) delete pCurrentMesh;
subject.append(p3dsMesh);
}
}
return subject;
}
Lib3dsMesh* GLC_WorldTo3ds::create3dsMeshFromGLC_Mesh(GLC_Mesh* pMesh, const QString& meshName)
{
// Create empty 3ds mesh with the given name
Lib3dsMesh* p3dsMesh= lib3ds_mesh_new(meshName.toLatin1().data());
const int stride= 3;
GLfloatVector vertice= pMesh->positionVector();
const uint pointsCount= vertice.count() / stride;
// Add points to the 3DS mesh
lib3ds_mesh_new_point_list(p3dsMesh, pointsCount);
for (uint i= 0; i < pointsCount; ++i)
{
Lib3dsPoint point;
point.pos[0]= vertice[i * 3];
point.pos[1]= vertice[i * 3 + 1];
point.pos[2]= vertice[i * 3 + 2];
p3dsMesh->pointL[i]= point;
}
// Add texel to the 3DS mesh
GLfloatVector texelVector= pMesh->texelVector();
if(!texelVector.isEmpty())
{
lib3ds_mesh_new_texel_list(p3dsMesh, pointsCount);
for (uint i= 0; i < pointsCount; ++i)
{
p3dsMesh->texelL[i][0]= texelVector[i * 2];
p3dsMesh->texelL[i][1]= texelVector[i * 2 + 1];
}
}
// Add faces to the 3ds mesh
const uint totalFaceCount= pMesh->faceCount(0);
lib3ds_mesh_new_face_list(p3dsMesh, totalFaceCount);
QSet<GLC_Material*> materialSet= pMesh->materialSet();
QSet<GLC_Material*>::iterator iMat= materialSet.begin();
uint currentFaceIndex= 0;
while(iMat != materialSet.end())
{
GLC_Material* pCurrentGLCMat= *iMat;
Lib3dsMaterial* pMaterial= get3dsMaterialFromGLC_Material(pCurrentGLCMat);
IndexList currentTriangleIndex= pMesh->getEquivalentTrianglesStripsFansIndex(0, pCurrentGLCMat->id());
const int faceCount= currentTriangleIndex.count() / 3;
for (int i= 0; i < faceCount; ++i)
{
Lib3dsFace face;
strcpy(face.material, pMaterial->name);
face.points[0]= currentTriangleIndex.at(i * 3);
face.points[1]= currentTriangleIndex.at(i * 3 + 1);
face.points[2]= currentTriangleIndex.at(i * 3 + 2);
p3dsMesh->faceL[currentFaceIndex++]= face;
Q_ASSERT(currentFaceIndex <= totalFaceCount);
}
++iMat;
}
return p3dsMesh;
}
Lib3dsMaterial* GLC_WorldTo3ds::get3dsMaterialFromGLC_Material(GLC_Material* pMat)
{
Lib3dsMaterial* pSubject= NULL;
const QString matName= materialName(pMat);
if (m_NameToMaterial.contains(matName))
{
pSubject= m_NameToMaterial.value(matName);
}
else
{
pSubject= create3dsMaterialFromGLC_Material(pMat, matName);
}
return pSubject;
}
Lib3dsMaterial* GLC_WorldTo3ds::create3dsMaterialFromGLC_Material(GLC_Material* pMat, const QString& matName)
{
Lib3dsMaterial* pSubject= lib3ds_material_new();
strcpy(pSubject->name, matName.toLatin1().data());
// Ambient Color
QColor ambient= pMat->ambientColor();
pSubject->ambient[0]= static_cast<float>(ambient.redF());
pSubject->ambient[1]= static_cast<float>(ambient.greenF());
pSubject->ambient[2]= static_cast<float>(ambient.blueF());
pSubject->ambient[3]= static_cast<float>(ambient.alphaF());
// Diffuse Color
QColor diffuse= pMat->diffuseColor();
pSubject->diffuse[0]= static_cast<float>(diffuse.redF());
pSubject->diffuse[1]= static_cast<float>(diffuse.greenF());
pSubject->diffuse[2]= static_cast<float>(diffuse.blueF());
pSubject->diffuse[3]= static_cast<float>(diffuse.alphaF());
// Specular Color
QColor specular= pMat->specularColor();
pSubject->specular[0]= static_cast<float>(specular.redF());
pSubject->specular[1]= static_cast<float>(specular.greenF());
pSubject->specular[2]= static_cast<float>(specular.blueF());
pSubject->specular[3]= static_cast<float>(specular.alphaF());
// Shininess
pSubject->shininess= pMat->shininess();
// Transparency
pSubject->transparency= 1.0f - static_cast<float>(pMat->opacity());
// Texture
if (pMat->hasTexture())
{
if (!m_TextureToFileName.contains(pMat->textureHandle()))
{
QString filePath= QFileInfo(m_FileName).absolutePath();
QString textureName= matName;
QImage textureImage= pMat->textureHandle()->imageOfTexture();
if (!pMat->textureFileName().isEmpty())
{
textureName= QFileInfo(pMat->textureFileName()).fileName();
if (QFileInfo(pMat->textureFileName()).exists())
{
textureImage.load(pMat->textureFileName());
}
}
else
{
textureName= textureName + ".jpg";
}
textureName= textureName.right(63);
if (!textureImage.isNull())
{
const QString type(QFileInfo(textureName).suffix());
QString newTextureFile= filePath + '/' + textureName;
textureImage.save(newTextureFile, type.toUpper().toLatin1().data());
strcpy(pSubject->texture1_map.name, textureName.toLatin1().data());
m_TextureToFileName.insert(pMat->textureHandle(), textureName);
}
}
else
{
QString textureName= m_TextureToFileName.value(pMat->textureHandle());
strcpy(pSubject->texture1_map.name, textureName.toLatin1().data());
}
}
lib3ds_file_insert_material(m_pLib3dsFile, pSubject);
m_NameToMaterial.insert(matName, pSubject);
return pSubject;
}
QString GLC_WorldTo3ds::materialName(GLC_Material* pMat) const
{
QString subject= pMat->name() + '_' + QString::number(pMat->id());
subject= subject.right(63);
return subject;
}
void GLC_WorldTo3ds::setNodePosition(Lib3dsNode* pNode, const GLC_Matrix4x4& matrix)
{
Lib3dsObjectData *pObjectData= &pNode->data.object;
GLC_Matrix4x4 isoMatrix(matrix.isometricMatrix());
// Translation
Lib3dsLin3Key* pLin3Key= lib3ds_lin3_key_new();
pLin3Key->value[0]= isoMatrix.getData()[12];
pLin3Key->value[1]= isoMatrix.getData()[13];
pLin3Key->value[2]= isoMatrix.getData()[14];
pLin3Key->tcb.frame= 1;
pObjectData->pos_track.keyL= pLin3Key;
// Scaling
Lib3dsLin3Key* pScale3Key= lib3ds_lin3_key_new();
pScale3Key->value[0]= static_cast<float>(matrix.scalingX());
pScale3Key->value[1]= static_cast<float>(matrix.scalingY());
pScale3Key->value[2]= static_cast<float>(matrix.scalingZ());
pScale3Key->tcb.frame= 1;
pObjectData->scl_track.keyL= pScale3Key;
// Rotation
Lib3dsQuatKey* pQuatKey= lib3ds_quat_key_new();
QQuaternion quaternion= matrix.quaternion();
QPair<GLC_Vector3d, double> pair= matrix.rotationVectorAndAngle();
pQuatKey->angle= static_cast<float>(pair.second);
pQuatKey->axis[0]= static_cast<float>(pair.first.x());
pQuatKey->axis[1]= static_cast<float>(pair.first.y());
pQuatKey->axis[2]= static_cast<float>(pair.first.z());
pQuatKey->tcb.frame= 1;
pObjectData->rot_track.keyL= pQuatKey;
}

View File

@ -0,0 +1,152 @@
/****************************************************************************
This file is part of the GLC-lib library.
Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
http://glc-lib.sourceforge.net
GLC-lib is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
GLC-lib is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with GLC-lib; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
//! \file glc_worldto3ds.h interface for the GLC_WorldTo3ds class.
#ifndef GLC_WORLDTO3DS_H_
#define GLC_WORLDTO3DS_H_
#include <QObject>
#include <QString>
#include "../sceneGraph/glc_world.h"
#include "../glc_config.h"
struct Lib3dsFile;
struct Lib3dsMesh;
struct Lib3dsMaterial;
struct Lib3dsNode;
class GLC_StructReference;
class GLC_3DRep;
class GLC_Mesh;
class GLC_StructOccurence;
class GLC_Matrix4x4;
//////////////////////////////////////////////////////////////////////
//! \class GLC_WorldTo3ds
/*! \brief GLC_WorldTo3ds : Export a GLC_World to a 3ds file */
//////////////////////////////////////////////////////////////////////
class GLC_LIB_EXPORT GLC_WorldTo3ds : public QObject
{
Q_OBJECT
//////////////////////////////////////////////////////////////////////
/*! @name Constructor / Destructor */
//@{
//////////////////////////////////////////////////////////////////////
public:
GLC_WorldTo3ds(const GLC_World& world);
virtual ~GLC_WorldTo3ds();
//@}
//////////////////////////////////////////////////////////////////////
/*! @name Set Functions*/
//@{
//////////////////////////////////////////////////////////////////////
public:
//! Save the world to the specified file name
bool exportToFile(const QString& fileName, bool useAbsolutePosition= false);
//@}
//////////////////////////////////////////////////////////////////////
/*! @name Private services functions */
//@{
//////////////////////////////////////////////////////////////////////
private:
//! Save the world into the lib3ds file structure
void saveWorld();
//! Save all meshes into the lib3ds file structure
void saveMeshes();
//! Save the branch from the given GLC_StructOccurence
void saveBranch(GLC_StructOccurence* pOcc);
//! Create 3ds node from the given GLC_StructOccurence
void createNodeFromOccurrence(GLC_StructOccurence* pOcc);
//! Return the list of 3ds mesh from the given GLC_3DRep
QList<Lib3dsMesh*> createMeshsFrom3DRep(GLC_3DRep* pRep, const QString& name, const GLC_Matrix4x4& matrix= GLC_Matrix4x4());
//! Return the 3ds mesh from the given GLC_Mesh
Lib3dsMesh* create3dsMeshFromGLC_Mesh(GLC_Mesh* pMesh, const QString& meshName);
//! Return the 3ds material from the given GLC_Material
Lib3dsMaterial* get3dsMaterialFromGLC_Material(GLC_Material* pMat);
//! Create and return the 3ds material from the given GLC_Material and name
Lib3dsMaterial* create3dsMaterialFromGLC_Material(GLC_Material* pMat, const QString& materialName);
//! Return the material name of the given material
QString materialName(GLC_Material* pMat) const;
//! Set the object data position from the given matrix
void setNodePosition(Lib3dsNode* pNode, const GLC_Matrix4x4& matrix);
//@}
//////////////////////////////////////////////////////////////////////
// Qt Signals
//////////////////////////////////////////////////////////////////////
signals:
void currentQuantum(int);
//////////////////////////////////////////////////////////////////////
/* Private members */
//////////////////////////////////////////////////////////////////////
private:
//! The world to export
GLC_World m_World;
//! The Lib3dsFile Structure
Lib3dsFile* m_pLib3dsFile;
//! The file absolute path
QString m_FileName;
//! Reference to 3ds mesh hash table
QHash<GLC_StructReference*, Lib3dsMesh*> m_ReferenceToMesh;
//! Name to 3ds material hash table
QHash<QString, Lib3dsMaterial*> m_NameToMaterial;
//! The root lib3ds node
Lib3dsNode* m_pRootLib3dsNode;
//! The current node id
int m_CurrentNodeId;
//! Occurence id to node id hash
QHash<GLC_uint, int> m_OccIdToNodeId;
//! The current mesh inde
int m_CurrentMeshIndex;
//! Use absolute position (meshes are duplicated)
bool m_UseAbsolutePosition;
//! GLC_Texture to fileName hash table
QHash<GLC_Texture*, QString> m_TextureToFileName;
};
#endif /* GLC_WORLDTO3DS_H_ */

View File

@ -405,7 +405,19 @@ void GLC_WorldTo3dxml::exportAssemblyFromOccurence(const GLC_StructOccurence* pO
GLC_3DViewInstance* pInstance= m_World.collection()->instanceHandle(pOccurence->id());
Q_ASSERT(NULL != pInstance);
const bool isVisible= pInstance->isVisible();
const bool isOverload= !isVisible || !pInstance->renderPropertiesHandle()->isDefault() || pOccurence->isFlexible();
// Test if render properties are overloaded
GLC_RenderProperties* pRenderProperties= pInstance->renderPropertiesHandle();
bool RenderOverloaded= !pRenderProperties->isDefault();
if (RenderOverloaded)
{
RenderOverloaded= false;
RenderOverloaded= (pRenderProperties->renderingMode() == glc::OverwriteMaterial);
RenderOverloaded= RenderOverloaded || (pRenderProperties->renderingMode() == glc::OverwriteTransparency);
RenderOverloaded= RenderOverloaded || (pRenderProperties->renderingMode() == glc::OverwriteTransparencyAndMaterial);
}
const bool isOverload= !isVisible || RenderOverloaded || pOccurence->isFlexible();
if (isOverload)
{
m_ListOfOverLoadedOccurence.append(pOccurence);
@ -773,8 +785,14 @@ void GLC_WorldTo3dxml::writeMaterial(const GLC_Material* pMaterial)
else
{
materialName= symplifyName(pMaterial->name());
}
// If the materialName is already uses append material id to the name
QSet<QString> materialsName= QSet<QString>::fromList(m_MaterialIdToMaterialName.values());
while (materialsName.contains(materialName))
{
materialName= materialName + '_' + QString::number(materialId);
}
}
m_MaterialIdToMaterialName.insert(materialId, materialName);
@ -1085,7 +1103,7 @@ void GLC_WorldTo3dxml::addImageTextureTo3dxml(const QImage& image, const QString
success= m_pCurrentZipFile->open(QIODevice::WriteOnly, quazipNewInfo);
if (success)
{
image.save(m_pCurrentZipFile, QFileInfo(fileName).suffix().toAscii().constData());
image.save(m_pCurrentZipFile, QFileInfo(fileName).suffix().toLatin1().constData());
m_pCurrentZipFile->close();
delete m_pCurrentZipFile;
m_pCurrentZipFile= NULL;
@ -1098,7 +1116,7 @@ void GLC_WorldTo3dxml::addImageTextureTo3dxml(const QImage& image, const QString
success= m_pCurrentFile->open(QIODevice::WriteOnly);
if (success)
{
image.save(m_pCurrentFile, QFileInfo(fileName).suffix().toAscii().constData());
image.save(m_pCurrentFile, QFileInfo(fileName).suffix().toLatin1().constData());
delete m_pCurrentFile;
m_pCurrentFile= NULL;
}
@ -1114,9 +1132,10 @@ QString GLC_WorldTo3dxml::xmlFileName(QString fileName)
fileName.remove(prefix);
}
fileName= symplifyName(fileName);
if (m_ExportType != StructureOnly)
{
fileName= symplifyName(fileName);
}
QString newName;
if (!m_3dxmlFileSet.contains(prefix + fileName))
@ -1257,7 +1276,10 @@ QString GLC_WorldTo3dxml::symplifyName(QString name)
const int nameSize= name.size();
for (int i= 0; i < nameSize; ++i)
{
if (!name.at(i).isLetterOrNumber() && (name.at(i) != '.'))
const QChar curChar= name.at(i);
bool simplifyCharacter= !curChar.isLetterOrNumber() && (curChar != '.');
simplifyCharacter= simplifyCharacter && (curChar != '/') && (curChar != '\\');
if (simplifyCharacter)
{
name.replace(i, 1, '_');
}

View File

@ -44,7 +44,7 @@ bool glc::polygon2DIsConvex(const QList<GLC_Point2d>& vertices)
GLC_Point2d s0(vertices.at(0));
GLC_Point2d s1(vertices.at(1));
GLC_Point2d s2(vertices.at(2));
const bool openAngle= ((s1.getX() - s0.getX()) * (s2.getY() - s0.getY()) - (s2.getX() - s0.getX()) * (s1.getY() - s0.getY())) < 0.0;
const bool openAngle= ((s1.x() - s0.x()) * (s2.y() - s0.y()) - (s2.x() - s0.x()) * (s1.y() - s0.y())) < 0.0;
int i= 3;
while ((i < size) && isConvex)
@ -52,7 +52,7 @@ bool glc::polygon2DIsConvex(const QList<GLC_Point2d>& vertices)
s0= s1;
s1= s2;
s2= vertices.at(i);
isConvex= openAngle == (((s1.getX() - s0.getX()) * (s2.getY() - s0.getY()) - (s2.getX() - s0.getX()) * (s1.getY() - s0.getY())) < 0.0);
isConvex= openAngle == (((s1.x() - s0.x()) * (s2.y() - s0.y()) - (s2.x() - s0.x()) * (s1.y() - s0.y())) < 0.0);
++i;
}
}
@ -90,8 +90,8 @@ QVector<GLC_Point2d> glc::findIntersection(const GLC_Point2d& s1p1, const GLC_Po
const GLC_Vector2d E(s2p1 - s1p1);
double kross= D0 ^ D1;
double sqrKross= kross * kross;
const double sqrLen0= D0.getX() * D0.getX() + D0.getY() * D0.getY();
const double sqrLen1= D1.getX() * D1.getX() + D1.getY() * D1.getY();
const double sqrLen0= D0.x() * D0.x() + D0.y() * D0.y();
const double sqrLen1= D1.x() * D1.x() + D1.y() * D1.y();
// Test if the line are nor parallel
if (sqrKross > (EPSILON * sqrLen0 * sqrLen1))
{
@ -115,7 +115,7 @@ QVector<GLC_Point2d> glc::findIntersection(const GLC_Point2d& s1p1, const GLC_Po
}
// Lines of the segments are parallel
const double sqrLenE= E.getX() * E.getX() + E.getY() * E.getY();
const double sqrLenE= E.x() * E.x() + E.y() * E.y();
kross= E ^ D0;
sqrKross= kross * kross;
if (sqrKross > (EPSILON * sqrLen0 * sqrLenE))
@ -147,8 +147,8 @@ bool glc::isIntersected(const GLC_Point2d& s1p1, const GLC_Point2d& s1p2, const
const GLC_Vector2d E(s2p1 - s1p1);
double kross= D0 ^ D1;
double sqrKross= kross * kross;
const double sqrLen0= D0.getX() * D0.getX() + D0.getY() * D0.getY();
const double sqrLen1= D1.getX() * D1.getX() + D1.getY() * D1.getY();
const double sqrLen0= D0.x() * D0.x() + D0.y() * D0.y();
const double sqrLen1= D1.x() * D1.x() + D1.y() * D1.y();
// Test if the line are nor parallel
if (sqrKross > (EPSILON * sqrLen0 * sqrLen1))
{
@ -171,7 +171,7 @@ bool glc::isIntersected(const GLC_Point2d& s1p1, const GLC_Point2d& s1p2, const
}
// Lines of the segments are parallel
const double sqrLenE= E.getX() * E.getX() + E.getY() * E.getY();
const double sqrLenE= E.x() * E.x() + E.y() * E.y();
kross= E ^ D0;
sqrKross= kross * kross;
if (sqrKross > (EPSILON * sqrLen0 * sqrLenE))
@ -198,8 +198,8 @@ bool glc::isIntersectedRaySegment(const GLC_Point2d& s1p1, const GLC_Vector2d& s
const GLC_Vector2d E(s2p1 - s1p1);
double kross= D0 ^ D1;
double sqrKross= kross * kross;
const double sqrLen0= D0.getX() * D0.getX() + D0.getY() * D0.getY();
const double sqrLen1= D1.getX() * D1.getX() + D1.getY() * D1.getY();
const double sqrLen0= D0.x() * D0.x() + D0.y() * D0.y();
const double sqrLen1= D1.x() * D1.x() + D1.y() * D1.y();
// Test if the line are nor parallel
if (sqrKross > (EPSILON * sqrLen0 * sqrLen1))
{
@ -222,7 +222,7 @@ bool glc::isIntersectedRaySegment(const GLC_Point2d& s1p1, const GLC_Vector2d& s
}
// Lines of the segments are parallel
const double sqrLenE= E.getX() * E.getX() + E.getY() * E.getY();
const double sqrLenE= E.x() * E.x() + E.y() * E.y();
kross= E ^ D0;
sqrKross= kross * kross;
if (sqrKross > (EPSILON * sqrLen0 * sqrLenE))
@ -459,7 +459,6 @@ void glc::triangulatePolygon(QList<GLuint>* pIndexList, const QList<float>& bulk
// Create the index
QList<int> index= face;
QList<int> tList;
const bool faceIsCounterclockwise= isCounterclockwiseOrdered(polygon);
if(!faceIsCounterclockwise)
@ -475,6 +474,7 @@ void glc::triangulatePolygon(QList<GLuint>* pIndexList, const QList<float>& bulk
}
}
QList<int> tList;
triangulate(polygon, index, tList);
size= tList.size();
for (int i= 0; i < size; i+= 3)
@ -558,6 +558,11 @@ bool glc::compare(double p1, double p2)
return qAbs(p1 - p2) <= comparedPrecision;
}
bool glc::compare(double p1, double p2, double accuracy)
{
return qAbs(p1 - p2) <= accuracy;
}
bool glc::compareAngle(double p1, double p2)
{
const double anglePrecision= toRadian(comparedPrecision);
@ -573,10 +578,25 @@ bool glc::compare(const GLC_Vector3d& v1, const GLC_Vector3d& v2)
return compareResult;
}
bool glc::compare(const GLC_Vector3d& v1, const GLC_Vector3d& v2, double accuracy)
{
bool compareResult= (qAbs(v1.x() - v2.x()) <= accuracy);
compareResult= compareResult && (qAbs(v1.y() - v2.y()) <= accuracy);
compareResult= compareResult && (qAbs(v1.z() - v2.z()) <= accuracy);
return compareResult;
}
bool glc::compare(const GLC_Vector2d& v1, const GLC_Vector2d& v2)
{
bool compareResult= (qAbs(v1.getX() - v2.getX()) <= comparedPrecision);
return compareResult && (qAbs(v1.getY() - v2.getY()) <= comparedPrecision);
bool compareResult= (qAbs(v1.x() - v2.x()) <= comparedPrecision);
return compareResult && (qAbs(v1.y() - v2.y()) <= comparedPrecision);
}
bool glc::compare(const GLC_Vector2d& v1, const GLC_Vector2d& v2, double accuracy)
{
bool compareResult= (qAbs(v1.x() - v2.x()) <= accuracy);
return compareResult && (qAbs(v1.y() - v2.y()) <= accuracy);
}
bool glc::compare(const QPointF& v1, const QPointF& v2)
@ -585,6 +605,68 @@ bool glc::compare(const QPointF& v1, const QPointF& v2)
return compareResult && (qAbs(v1.y() - v2.y()) <= comparedPrecision);
}
bool glc::compare(const QPointF& v1, const QPointF& v2, double accuracy)
{
bool compareResult= (qAbs(v1.x() - v2.x()) <= accuracy);
return compareResult && (qAbs(v1.y() - v2.y()) <= accuracy);
}
double glc::round(double value)
{
value= value / comparedPrecision;
value= (value >= 0.0 ? floor(value + 0.5) : ceil(value - 0.5));
value= value * comparedPrecision;
return value;
}
double glc::round(double value, double accuracy)
{
value= value / accuracy;
value= (value >= 0.0 ? floor(value + 0.5) : ceil(value - 0.5));
value= value * accuracy;
return value;
}
QPointF glc::round(const QPointF& point)
{
QPointF subject(glc::round(static_cast<double>(point.x())), glc::round(static_cast<double>(point.y())));
return subject;
}
QPointF glc::round(const QPointF& point, double accuracy)
{
QPointF subject(glc::round(static_cast<double>(point.x()), accuracy), glc::round(static_cast<double>(point.y()), accuracy));
return subject;
}
GLC_Vector2d round(const GLC_Vector2d& vector)
{
GLC_Vector2d subject(glc::round(vector.x()), glc::round(vector.y()));
return subject;
}
GLC_Vector2d round(const GLC_Vector2d& vector, double accuracy)
{
GLC_Vector2d subject(glc::round(vector.x(), accuracy), glc::round(vector.y(), accuracy));
return subject;
}
GLC_Vector3d round(const GLC_Vector3d& vector)
{
GLC_Vector3d subject(glc::round(vector.x()), glc::round(vector.y()), glc::round(vector.z()));
return subject;
}
GLC_Vector3d round(const GLC_Vector3d& vector, double accuracy)
{
GLC_Vector3d subject(glc::round(vector.x(), accuracy), glc::round(vector.y(), accuracy), glc::round(vector.z(), accuracy));
return subject;
}
bool glc::pointInPolygon(const GLC_Point2d& point, const QList<GLC_Point2d>& polygon)
{
const int polygonSize= polygon.size();
@ -596,22 +678,22 @@ bool glc::pointInPolygon(const GLC_Point2d& point, const QList<GLC_Point2d>& pol
{
const GLC_Point2d point0= polygon.at(i);
const GLC_Point2d point1= polygon.at(j);
if (point.getY() < point1.getY())
if (point.y() < point1.y())
{
//point1 above ray
if (point0.getY() <= point.getY())
if (point0.y() <= point.y())
{
//point2 on or below ray
const double val1= (point.getY() - point0.getY()) * (point1.getX() - point0.getX());
const double val2= (point.getX() - point0.getX()) * (point1.getY() - point0.getY());
const double val1= (point.y() - point0.y()) * (point1.x() - point0.x());
const double val2= (point.x() - point0.x()) * (point1.y() - point0.y());
if (val1 > val2) inside= !inside;
}
}
else if (point.getY() < point0.getY())
else if (point.y() < point0.y())
{
// point 1 on or below ray, point0 above ray
const double val1= (point.getY() - point0.getY()) * (point1.getX() - point0.getX());
const double val2= (point.getX() - point0.getX()) * (point1.getY() - point0.getY());
const double val1= (point.y() - point0.y()) * (point1.x() - point0.x());
const double val2= (point.x() - point0.x()) * (point1.y() - point0.y());
if (val1 < val2) inside= !inside;
}
j= i;
@ -632,3 +714,74 @@ double glc::zeroTo2PIAngle(double angle)
}
return angle;
}
QList<GLC_Point2d> glc::polygonIn2d(QList<GLC_Point3d> polygon3d)
{
const int count= polygon3d.count();
Q_ASSERT(count > 2);
// Compute face normal
const GLC_Point3d point1(polygon3d[0]);
const GLC_Point3d point2(polygon3d[1]);
const GLC_Point3d point3(polygon3d[2]);
const GLC_Vector3d edge1(point2 - point1);
const GLC_Vector3d edge2(point3 - point2);
GLC_Vector3d polygonPlaneNormal(edge1 ^ edge2);
polygonPlaneNormal.normalize();
// Create the transformation matrix
GLC_Matrix4x4 transformation;
GLC_Vector3d rotationAxis(polygonPlaneNormal ^ Z_AXIS);
if (!rotationAxis.isNull())
{
const double angle= acos(polygonPlaneNormal * Z_AXIS);
transformation.setMatRot(rotationAxis, angle);
}
QList<GLC_Point2d> subject;
// Transform polygon vertexs
for (int i=0; i < count; ++i)
{
polygon3d[i]= transformation * polygon3d[i];
// Create 2d vector
subject << polygon3d[i].toVector2d(Z_AXIS);
}
return subject;
}
QList<GLC_Point2d> glc::normalyzePolygon(const QList<GLC_Point2d>& polygon)
{
QList<GLC_Point2d> subject;
const int count= polygon.count();
Q_ASSERT(count > 2);
GLC_Point2d minPoint= polygon.first();
GLC_Point2d maxPoint= minPoint;
for (int i= 1; i < count; ++i)
{
GLC_Point2d point= polygon.at(i);
minPoint.setX(qMin(point.x(), minPoint.x()));
minPoint.setY(qMin(point.y(), minPoint.y()));
maxPoint.setX(qMax(point.x(), maxPoint.x()));
maxPoint.setY(qMax(point.y(), maxPoint.y()));
}
const GLC_Vector2d range= maxPoint - minPoint;
Q_ASSERT(range.x() != 0.0);
Q_ASSERT(range.y() != 0.0);
for (int i= 0; i < count; ++i)
{
const GLC_Point2d point= polygon.at(i);
const GLC_Point2d temp= (point - minPoint);
const GLC_Point2d result(temp.x() / range.x(), temp.y() / range.y());
subject.append(result);
}
return subject;
}

View File

@ -40,7 +40,7 @@
namespace glc
{
const double defaultPrecision= 0.01;
extern double comparedPrecision;
GLC_LIB_EXPORT extern double comparedPrecision;
//////////////////////////////////////////////////////////////////////
/*! \name Tools Functions*/
//@{
@ -87,7 +87,7 @@ namespace glc
/*! If the polygon is convex the returned index is a fan*/
GLC_LIB_EXPORT void triangulatePolygon(QList<GLuint>*, const QList<float>&);
//! Return true if the given 3d line intersect the given plane
//! Return true if the given 3d line is intersected with the given plane
/*! If there is an intersection point is set to the given 3d point
* If the line lie on the plane this method return false*/
GLC_LIB_EXPORT bool lineIntersectPlane(const GLC_Line3d& line, const GLC_Plane& plane, GLC_Point3d* pPoint);
@ -101,7 +101,7 @@ namespace glc
//! Return the perpendicular 2D vector of the given 2D vector
inline GLC_Vector2d perpVector(const GLC_Vector2d& vect)
{return GLC_Vector2d(-vect.getY(), vect.getX());}
{return GLC_Vector2d(-vect.y(), vect.x());}
//! Return the distance between the given point and line
GLC_LIB_EXPORT double pointLineDistance(const GLC_Point3d& point, const GLC_Line3d& line);
@ -111,22 +111,52 @@ namespace glc
GLC_LIB_EXPORT bool compare(double p1, double p2);
GLC_LIB_EXPORT bool compare(double p1, double p2, double accuracy);
GLC_LIB_EXPORT bool compareAngle(double p1, double p2);
GLC_LIB_EXPORT bool compare(const GLC_Vector3d& v1, const GLC_Vector3d& v2);
GLC_LIB_EXPORT bool compare(const GLC_Vector3d& v1, const GLC_Vector3d& v2, double accuracy);
GLC_LIB_EXPORT bool compare(const GLC_Vector2d& v1, const GLC_Vector2d& v2);
GLC_LIB_EXPORT bool compare(const GLC_Vector2d& v1, const GLC_Vector2d& v2, double accuracy);
GLC_LIB_EXPORT bool compare(const QPointF& v1, const QPointF& v2);
GLC_LIB_EXPORT bool compare(const QPointF& v1, const QPointF& v2, double accuracy);
GLC_LIB_EXPORT double round(double value);
GLC_LIB_EXPORT double round(double value, double accuracy);
GLC_LIB_EXPORT QPointF round(const QPointF& point);
GLC_LIB_EXPORT QPointF round(const QPointF& point, double accuracy);
GLC_LIB_EXPORT GLC_Vector2d round(const GLC_Vector2d& vector);
GLC_LIB_EXPORT GLC_Vector2d round(const GLC_Vector2d& vector, double accuracy);
GLC_LIB_EXPORT GLC_Vector3d round(const GLC_Vector3d& vector);
GLC_LIB_EXPORT GLC_Vector3d round(const GLC_Vector3d& vector, double accuracy);
//! Return true if the given 2d point is inside the given polygon
GLC_LIB_EXPORT bool pointInPolygon(const GLC_Point2d& point, const QList<GLC_Point2d>& polygon);
//! Return the angle from 0 to 2PI from an given angle from -PI to PI
GLC_LIB_EXPORT double zeroTo2PIAngle(double angle);
//! Return the 2D polygon from the given plane 3D polygon
GLC_LIB_EXPORT QList<GLC_Point2d> polygonIn2d(QList<GLC_Point3d> polygon3d);
//! Return 2D polygon with normalyze coordinate
GLC_LIB_EXPORT QList<GLC_Point2d> normalyzePolygon(const QList<GLC_Point2d>& polygon);
//@}
};
}
#endif /*GLC_GEOMTOOLS_H_*/

View File

@ -82,7 +82,7 @@ QVector<double> GLC_Matrix4x4::toEuler(void) const
angle_y= -asin(m_Matrix[8]);
double C= cos(angle_y);
if (!qFuzzyCompare(C, 0.0)) // Gimball lock?
if (!(qAbs(C - 0.0) <= glc::EPSILON)) // Gimball lock?
{
tracex= m_Matrix[10] / C;
tracey= - m_Matrix[9] / C;
@ -120,3 +120,82 @@ QString GLC_Matrix4x4::toString() const
result.remove(result.size() - 1, 1);
return result;
}
QQuaternion GLC_Matrix4x4::quaternion() const
{
QQuaternion subject;
GLC_Matrix4x4 rotMat= rotationMatrix();
if ((this->type() != GLC_Matrix4x4::Identity) && (rotMat != GLC_Matrix4x4()))
{
const double matrixTrace= rotMat.trace();
double s, w, x, y, z;
if (matrixTrace > 0.0)
{
s= 0.5 / sqrt(matrixTrace);
w= 0.25 / s;
x= (rotMat.m_Matrix[9] - rotMat.m_Matrix[6]) * s;
y= (rotMat.m_Matrix[2] - rotMat.m_Matrix[8]) * s;
z= (rotMat.m_Matrix[4] - rotMat.m_Matrix[1]) * s;
}
else
{
if ((abs(rotMat.m_Matrix[0]) > abs(rotMat.m_Matrix[5])) && (abs(rotMat.m_Matrix[0]) > abs(rotMat.m_Matrix[15])))
{ // column 0 greater
s= sqrt(1.0 + rotMat.m_Matrix[0] - rotMat.m_Matrix[5] - rotMat.m_Matrix[10]) * 2.0;
w= (rotMat.m_Matrix[6] + rotMat.m_Matrix[9] ) / s;
x= 0.5 / s;
y= (rotMat.m_Matrix[1] + rotMat.m_Matrix[4] ) / s;
z= (rotMat.m_Matrix[2] + rotMat.m_Matrix[8] ) / s;
}
else if ((abs(rotMat.m_Matrix[5]) > abs(rotMat.m_Matrix[0])) && (abs(rotMat.m_Matrix[5]) > abs(rotMat.m_Matrix[15])))
{ // column 1 greater
s= sqrt(1.0 + rotMat.m_Matrix[5] - rotMat.m_Matrix[0] - rotMat.m_Matrix[10]) * 2.0;
w= (rotMat.m_Matrix[2] + rotMat.m_Matrix[8]) / s;
x= (rotMat.m_Matrix[1] + rotMat.m_Matrix[4]) / s;
y= 0.5 / s;
z= (rotMat.m_Matrix[6] + rotMat.m_Matrix[9]) / s;
}
else
{ // column 3 greater
s= sqrt(1.0 + rotMat.m_Matrix[10] - rotMat.m_Matrix[0] - rotMat.m_Matrix[5]) * 2.0;
w = (rotMat.m_Matrix[1] + rotMat.m_Matrix[4]) / s;
x = (rotMat.m_Matrix[2] + rotMat.m_Matrix[8]) / s;
y = (rotMat.m_Matrix[6] + rotMat.m_Matrix[9]) / s;
z = 0.5 / s;
}
}
subject= QQuaternion(w, x, y, z);
}
return subject;
}
QPair<GLC_Vector3d, double> GLC_Matrix4x4::rotationVectorAndAngle() const
{
QPair<GLC_Vector3d, double> subject(GLC_Vector3d(), 0.0);
if (GLC_Matrix4x4(*this).optimise().type() != GLC_Matrix4x4::Identity)
{
QQuaternion quaternion= this->quaternion();
quaternion.normalize();
const double cos_angle= quaternion.scalar();
const double angle= acos(cos_angle);
double sin_angle= sqrt(1.0 - cos_angle * cos_angle);
if (fabs(sin_angle) < 0.0005) sin_angle= 1.0;
subject.first.setX(quaternion.x() / sin_angle);
subject.first.setY(quaternion.y() / sin_angle);
subject.first.setZ(quaternion.z() / sin_angle);
subject.second= angle * 2.0;
}
return subject;
}

View File

@ -26,6 +26,9 @@
#define GLC_MATRIX4X4_H_
#include <QVector>
#include <QQuaternion>
#include <QPair>
#include "glc_vector3d.h"
#include "../glc_config.h"
@ -177,6 +180,16 @@ public:
inline bool isDirect() const
{return (m_Type & Direct);}
//! Return this matrix trace
inline double trace() const
{return (m_Matrix[0] + m_Matrix[5] + m_Matrix[10] + m_Matrix[15]);}
//! Return the quaternion of this matrix
QQuaternion quaternion() const;
//! Return the rotation vector and angle of this matrix
QPair<GLC_Vector3d, double> rotationVectorAndAngle() const;
//@}
//////////////////////////////////////////////////////////////////////
@ -402,7 +415,7 @@ bool GLC_Matrix4x4::operator==(const GLC_Matrix4x4& mat) const
int i= 0;
while (result && (i < TAILLEMAT4X4))
{
result= (qFuzzyCompare(m_Matrix[i], mat.m_Matrix[i]));
result= (qAbs(m_Matrix[i] - mat.m_Matrix[i]) <= glc::EPSILON);
++i;
}
return result;
@ -502,16 +515,31 @@ GLC_Matrix4x4& GLC_Matrix4x4::setMatRot(const GLC_Vector3d &Vect, const double &
return *this;
}
GLC_Matrix4x4& GLC_Matrix4x4::setMatRot(const GLC_Vector3d &Vect1, const GLC_Vector3d &Vect2)
GLC_Matrix4x4& GLC_Matrix4x4::setMatRot(const GLC_Vector3d &v1, const GLC_Vector3d &v2)
{
// Compute rotation matrix
const GLC_Vector3d VectAxeRot(Vect1 ^ Vect2);
// Check if rotation vector axis is not null
if (!VectAxeRot.isNull())
{ // Ok, vector not null
const double Angle= acos(Vect1 * Vect2);
setMatRot(VectAxeRot, Angle);
if ((v1 != v2) && !v1.isNull() && !v2.isNull())
{
if (v1 != -v2)
{
const GLC_Vector3d rotationAxis(v1 ^ v2);
if (!rotationAxis.isNull())
{
const double Angle= acos(v1 * v2);
setMatRot(rotationAxis, Angle);
}
}
else
{
// v1 == -v2
GLC_Vector3d otherVector(glc::Z_AXIS);
if ((otherVector == v1) || (otherVector == -v2))
{
otherVector= glc::Y_AXIS;
}
const GLC_Vector3d rotationVector((v1 ^ otherVector).normalize());
setMatRot(rotationVector, glc::PI);
}
}
return *this;

View File

@ -23,6 +23,7 @@
#include <QtDebug>
#include "glc_plane.h"
#include "glc_geomtools.h"
GLC_Plane::GLC_Plane()
{
@ -101,12 +102,21 @@ bool GLC_Plane::operator==(GLC_Plane p2) const
GLC_Plane p1(*this);
p1.normalize();
p2.normalize();
bool areEqual= qFuzzyCompare(p1.m_Eq[0], p2.m_Eq[0]);
areEqual= areEqual && qFuzzyCompare(p1.m_Eq[1], p2.m_Eq[1]);
areEqual= areEqual && qFuzzyCompare(p1.m_Eq[2], p2.m_Eq[2]);
areEqual= areEqual && qFuzzyCompare(p1.m_Eq[3], p2.m_Eq[3]);
return areEqual;
bool areEqual= glc::compare(p1.m_Eq[0], p2.m_Eq[0], glc::EPSILON);
areEqual= areEqual && glc::compare(p1.m_Eq[1], p2.m_Eq[1], glc::EPSILON);
areEqual= areEqual && glc::compare(p1.m_Eq[2], p2.m_Eq[2], glc::EPSILON);
areEqual= areEqual && glc::compare(p1.m_Eq[3], p2.m_Eq[3], glc::EPSILON);
return areEqual;
}
bool GLC_Plane::lieOnThisPlane(const GLC_Point3d &p)
{
const double value= (m_Eq[0] * p.x() + m_Eq[1] * p.y() + m_Eq[2] * p.z() + m_Eq[3]);
bool subject = glc::compare(value, 0.0, glc::EPSILON);
return subject;
}
QString GLC_Plane::toString() const
@ -137,3 +147,12 @@ GLC_Plane& GLC_Plane::setPlane(const GLC_Vector3d& normal, const GLC_Point3d& po
return *this;
}
GLC_Plane& GLC_Plane::setNormal(const GLC_Vector3d& normal)
{
m_Eq[0]= normal.x();
m_Eq[1]= normal.y();
m_Eq[2]= normal.z();
return *this;
}

View File

@ -106,8 +106,7 @@ public:
{return GLC_Vector3d(m_Eq[0], m_Eq[1], m_Eq[2]);}
//! Return true if the given point is on this plane
inline bool lieOnThisPlane(const GLC_Point3d& p)
{return (m_Eq[0] * p.x() + m_Eq[1] * p.y() + m_Eq[2] * p.z() + m_Eq[3]) == 0.0f;}
bool lieOnThisPlane(const GLC_Point3d& p);
//! Return a pointer to this plane equation data
const double* data() const
@ -144,6 +143,9 @@ public:
//! Set the plane from the given normal and point and return a reference to this plane
GLC_Plane& setPlane(const GLC_Vector3d& normal, const GLC_Point3d& point);
//! Set this plane normal to the given normal and return a reference to this plane
GLC_Plane& setNormal(const GLC_Vector3d& normal);
//@}

View File

@ -38,9 +38,13 @@ namespace glc
* \brief Define the magic number PI */
const double PI= acos(-1.0);
//! Convert the given degre angle in radian
inline double toRadian(double angle)
{return PI * angle / 180.0;}
};
//! Convert the given degrees angle in radian
inline double toRadian(double angleInDegrees)
{return PI * angleInDegrees / 180.0;}
//! Convert the given radian angle in degre
inline double toDegrees(double angleInRadians)
{return 180.0 * angleInRadians / PI;}
}
#endif /*GLC_UTILS_MATHS_H_*/

View File

@ -41,8 +41,7 @@
//! \class GLC_Vector2d
/*! \brief GLC_Vector2d is a 2 dimensions Vector*/
/*! GLC_Vector2d is used to represent 2D position and vectors.
* */
/*! GLC_Vector2d is used to represent 2D position and vectors.*/
//////////////////////////////////////////////////////////////////////
class GLC_LIB_EXPORT GLC_Vector2d
@ -80,12 +79,7 @@ public:
m_Vector[1]= dY;
}
/*! Recopy constructor
* Sample use
* \code
* NewVect = new GLC_Vector2d(OldVect);
* \endcode
*/
//! Copy constructor
inline GLC_Vector2d(const GLC_Vector2d &Vect)
{
m_Vector[0]= Vect.m_Vector[0];
@ -165,18 +159,29 @@ public:
return m_Vector[0] * Vect.m_Vector[0] + m_Vector[1] * Vect.m_Vector[1];
}
/*! Overload scalar division "/" operator between 2 vector*/
inline double operator / (const GLC_Vector2d &Vect) const
{
return m_Vector[0] / Vect.m_Vector[0] + m_Vector[1] / Vect.m_Vector[1];
}
/*! Overload scalar product "*" operator between 1 vector and one scalar*/
inline GLC_Vector2d operator * (double Scalaire) const
inline GLC_Vector2d operator * (double Scalaire) const
{
return GLC_Vector2d(m_Vector[0] * Scalaire, m_Vector[1] * Scalaire);;
}
/*! Overload scalar division "/" operator between 1 vector and one scalar*/
inline GLC_Vector2d operator / (double Scalaire) const
{
return GLC_Vector2d(m_Vector[0] / Scalaire, m_Vector[1] / Scalaire);;
}
/*! Overload equality "==" operator*/
inline bool operator == (const GLC_Vector2d &Vect) const
{
bool bResult= qFuzzyCompare(m_Vector[0], Vect.m_Vector[0]);
bResult= bResult && qFuzzyCompare(m_Vector[1], Vect.m_Vector[1]);
bool bResult= (qAbs(m_Vector[0]) - qAbs(Vect.m_Vector[0])) < glc::EPSILON;
bResult= bResult && ((qAbs(m_Vector[1]) - qAbs(Vect.m_Vector[1])) < glc::EPSILON);
return bResult;
}
@ -238,36 +243,34 @@ public:
//@{
//////////////////////////////////////////////////////////////////////
public:
/*! X Composante*/
inline double getX(void) const
{
return m_Vector[0];
}
/*! Y Composante*/
inline double getY(void) const
{
return m_Vector[1];
}
/*! X Component*/
inline double x(void) const
{return m_Vector[0];}
/*! Y Component*/
inline double y(void) const
{return m_Vector[1];}
/*! retourne un pointeur constant vers le tableau du vecteur.*/
inline const double *return_dVect(void) const
{
return m_Vector;
}
{return m_Vector;}
/*! Return true if the vector is null*/
inline bool isNull(void) const
{
return qFuzzyCompare(m_Vector[0], 0.0) && qFuzzyCompare(m_Vector[1], 0.0);
}
{return (qAbs(m_Vector[0]) < glc::EPSILON) && (qAbs(m_Vector[1]) < glc::EPSILON);}
//! return the string representation of vector
inline QString toString() const
{
return QString("[") + QString::number(m_Vector[0]) + QString(" , ") + QString::number(m_Vector[1]) + QString("]");
}
//! return a vector perpendicular to this
{return QString("[") + QString::number(m_Vector[0]) + QString(" , ") + QString::number(m_Vector[1]) + QString("]");}
//! Return a vector perpendicular to this
inline GLC_Vector2d perp() const
{
return GLC_Vector2d(-m_Vector[1], m_Vector[0]);
}
{return GLC_Vector2d(-m_Vector[1], m_Vector[0]);}
//! Return the length of this vector
inline double length() const
{return sqrt(m_Vector[0] * m_Vector[0] + m_Vector[1] * m_Vector[1]);}
//@}
//////////////////////////////////////////////////////////////////////
@ -285,13 +288,13 @@ private:
//! Define GLC_Point2D
typedef GLC_Vector2d GLC_Point2d;
inline GLC_Vector2d& GLC_Vector2d::setLength(double norme)
inline GLC_Vector2d& GLC_Vector2d::setLength(double lenght)
{
const double normCur= sqrt( m_Vector[0] * m_Vector[0] + m_Vector[1] * m_Vector[1]);
const double currentLenght= sqrt( m_Vector[0] * m_Vector[0] + m_Vector[1] * m_Vector[1]);
if (normCur != 0.0f)
if (currentLenght != 0.0f)
{
const double Coef = norme / normCur;
const double Coef = lenght / currentLenght;
m_Vector[0] = m_Vector[0] * Coef;
m_Vector[1] = m_Vector[1] * Coef;

View File

@ -104,7 +104,7 @@ public:
//! Return true if this vector is null
inline bool isNull() const
{return (m_Vector[0] == 0.0f) && (m_Vector[1] == 0.0f) && (m_Vector[2] == 0.0f);}
{return (qAbs(m_Vector[0]) < glc::EPSILON) && (qAbs(m_Vector[1]) < glc::EPSILON) && (qAbs(m_Vector[2]) < glc::EPSILON);}
//! Return the length of this vector
inline double length() const
@ -234,7 +234,7 @@ public:
}
//! Set vector lenght from the given scalar and return a reference of this vector
inline GLC_Vector3d& setLength(double);
inline GLC_Vector3d& setLength(double lenght);
//! Normalize this vector and return a reference to it
inline GLC_Vector3d& normalize()
@ -334,8 +334,8 @@ GLC_Vector3d::GLC_Vector3d(const GLC_Vector3df &vector)
GLC_Vector3d::GLC_Vector3d(const GLC_Vector2d &vector)
{
m_Vector[0]= vector.getX();
m_Vector[1]= vector.getY();
m_Vector[0]= vector.x();
m_Vector[1]= vector.y();
m_Vector[2]= 0.0;
}
@ -392,13 +392,13 @@ GLC_Vector3d& GLC_Vector3d::setVect(double x, double y, double z)
return *this;
}
inline GLC_Vector3d& GLC_Vector3d::setLength(double norme)
inline GLC_Vector3d& GLC_Vector3d::setLength(double lenght)
{
const double normCur= sqrt( m_Vector[0] * m_Vector[0] + m_Vector[1] * m_Vector[1] + m_Vector[2] * m_Vector[2]);
const double currentLenght= sqrt( m_Vector[0] * m_Vector[0] + m_Vector[1] * m_Vector[1] + m_Vector[2] * m_Vector[2]);
if (normCur != 0.0f)
if (qAbs(currentLenght) > glc::EPSILON)
{
const double Coef = norme / normCur;
const double Coef = lenght / currentLenght;
m_Vector[0] = m_Vector[0] * Coef;
m_Vector[1] = m_Vector[1] * Coef;

View File

@ -402,7 +402,6 @@ void GLC_3DViewCollection::setPolygonModeForAll(GLenum face, GLenum mode)
while (iEntry != m_3DViewInstanceHash.constEnd())
{
// Update Instance Polygon Mode
iEntry.value().setPolygonMode(face, mode);
iEntry++;
}
@ -424,8 +423,7 @@ void GLC_3DViewCollection::showAll()
while (iEntry != m_3DViewInstanceHash.constEnd())
{
// Update Instance Polygon Mode
iEntry.value().setVisibility(true);
iEntry.value().setVisibility(true);
iEntry++;
}
}
@ -436,7 +434,6 @@ void GLC_3DViewCollection::hideAll()
while (iEntry != m_3DViewInstanceHash.constEnd())
{
// Update Instance Polygon Mode
iEntry.value().setVisibility(false);
iEntry++;
}

View File

@ -39,7 +39,6 @@ int GLC_3DViewInstance::m_GlobalDefaultLOD= 10;
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
// Default constructor
GLC_3DViewInstance::GLC_3DViewInstance()
: GLC_Object()
, m_3DRep()
@ -55,11 +54,8 @@ GLC_3DViewInstance::GLC_3DViewInstance()
// Encode Color Id
glc::encodeRgbId(m_Uid, m_colorId);
//qDebug() << "GLC_3DViewInstance::GLC_3DViewInstance null instance ID = " << m_Uid;
//qDebug() << "Number of instance" << (*m_pNumberOfInstance);
}
// Contruct instance with a geometry
GLC_3DViewInstance::GLC_3DViewInstance(GLC_Geometry* pGeom)
: GLC_Object()
, m_3DRep(pGeom)
@ -76,15 +72,11 @@ GLC_3DViewInstance::GLC_3DViewInstance(GLC_Geometry* pGeom)
glc::encodeRgbId(m_Uid, m_colorId);
setName(m_3DRep.name());
//qDebug() << "GLC_3DViewInstance::GLC_3DViewInstance ID = " << m_Uid;
//qDebug() << "Number of instance" << (*m_pNumberOfInstance);
}
// Contruct instance with a 3DRep
GLC_3DViewInstance::GLC_3DViewInstance(const GLC_3DRep& rep)
: GLC_Object()
, m_3DRep(rep)
GLC_3DViewInstance::GLC_3DViewInstance(GLC_Geometry* pGeom, GLC_uint id)
: GLC_Object(id)
, m_3DRep(pGeom)
, m_pBoundingBox(NULL)
, m_AbsoluteMatrix()
, m_IsBoundingBoxValid(false)
@ -98,9 +90,40 @@ GLC_3DViewInstance::GLC_3DViewInstance(const GLC_3DRep& rep)
glc::encodeRgbId(m_Uid, m_colorId);
setName(m_3DRep.name());
}
GLC_3DViewInstance::GLC_3DViewInstance(const GLC_3DRep& rep)
: GLC_Object(rep.name())
, m_3DRep(rep)
, m_pBoundingBox(NULL)
, m_AbsoluteMatrix()
, m_IsBoundingBoxValid(false)
, m_RenderProperties()
, m_IsVisible(true)
, m_DefaultLOD(m_GlobalDefaultLOD)
, m_ViewableFlag(GLC_3DViewInstance::FullViewable)
, m_ViewableGeomFlag()
{
// Encode Color Id
glc::encodeRgbId(m_Uid, m_colorId);
}
GLC_3DViewInstance::GLC_3DViewInstance(const GLC_3DRep& rep, GLC_uint id)
: GLC_Object(id, rep.name())
, m_3DRep(rep)
, m_pBoundingBox(NULL)
, m_AbsoluteMatrix()
, m_IsBoundingBoxValid(false)
, m_RenderProperties()
, m_IsVisible(true)
, m_DefaultLOD(m_GlobalDefaultLOD)
, m_ViewableFlag(GLC_3DViewInstance::FullViewable)
, m_ViewableGeomFlag()
{
// Encode Color Id
glc::encodeRgbId(m_Uid, m_colorId);
//qDebug() << "GLC_3DViewInstance::GLC_3DViewInstance ID = " << m_Uid;
//qDebug() << "Number of instance" << (*m_pNumberOfInstance);
}
// Copy constructor

View File

@ -69,12 +69,18 @@ public:
//! Default constructor
GLC_3DViewInstance();
//! Contruct instance with a geometry
//! Contruct instance from a geometry
GLC_3DViewInstance(GLC_Geometry* pGeom);
//! Contruct instance with a 3DRep
//! Contruct instance from a geometry and the given UID
GLC_3DViewInstance(GLC_Geometry* pGeom, GLC_uint id);
//! Contruct instance from a 3DRep
GLC_3DViewInstance(const GLC_3DRep&);
//! Contruct instance from a 3DRep and the given UID
GLC_3DViewInstance(const GLC_3DRep& rep, GLC_uint id);
//! Copy constructor
GLC_3DViewInstance(const GLC_3DViewInstance& );

View File

@ -27,7 +27,6 @@
GLC_SelectionSet::GLC_SelectionSet(GLC_WorldHandle* pWorldHandle)
: m_pWorldHandle(pWorldHandle)
, m_OccurenceHash()
, m_InstanceToPrimitiveId()
{
Q_ASSERT(0 == m_pWorldHandle->collection()->selectionSize());
@ -50,50 +49,14 @@ bool GLC_SelectionSet::isEmpty() const
int GLC_SelectionSet::count() const
{
return m_OccurenceHash.size() - m_InstanceToPrimitiveId.size();
return m_OccurenceHash.size();
}
QList<GLC_StructOccurence*> GLC_SelectionSet::occurencesList() const
{
QList<GLC_StructOccurence*> listOfOccurence;
QHash<GLC_uint, GLC_StructOccurence*>::const_iterator iOcc= m_OccurenceHash.constBegin();
while (m_OccurenceHash.constEnd() != iOcc)
{
if (!m_InstanceToPrimitiveId.contains(iOcc.key()))
{
listOfOccurence.append(iOcc.value());
}
++iOcc;
}
return listOfOccurence;
return m_OccurenceHash.values();
}
QList<GLC_StructOccurence*> GLC_SelectionSet::occurencesListWithSelectedPrimitive() const
{
QList<GLC_StructOccurence*> listOfOccurence;
QHash<GLC_uint, QSet<GLC_uint> >::const_iterator iOcc= m_InstanceToPrimitiveId.constBegin();
while (m_InstanceToPrimitiveId.constEnd() != iOcc)
{
listOfOccurence.append(m_OccurenceHash.value(iOcc.key()));
++iOcc;
}
return listOfOccurence;
}
QSet<GLC_uint> GLC_SelectionSet::selectedPrimitivesId(GLC_uint instanceId) const
{
QSet<GLC_uint> primitivesIdSet;
if (m_InstanceToPrimitiveId.contains(instanceId))
{
primitivesIdSet= m_InstanceToPrimitiveId.value(instanceId);
}
return primitivesIdSet;
}
bool GLC_SelectionSet::hasPrimitiveSelected(GLC_uint instanceId) const
{
return m_InstanceToPrimitiveId.contains(instanceId);
}
//////////////////////////////////////////////////////////////////////
// Set Functions
@ -126,7 +89,6 @@ bool GLC_SelectionSet::remove(GLC_uint occurenceId)
if (m_OccurenceHash.contains(occurenceId))
{
m_OccurenceHash.remove(occurenceId);
m_InstanceToPrimitiveId.remove(occurenceId);
return true;
}
else return false;
@ -135,81 +97,4 @@ bool GLC_SelectionSet::remove(GLC_uint occurenceId)
void GLC_SelectionSet::clear()
{
m_OccurenceHash.clear();
m_InstanceToPrimitiveId.clear();
}
bool GLC_SelectionSet::insertPrimitiveId(GLC_StructOccurence* pOccurence, GLC_uint primitiveId)
{
return insertPrimitiveId(pOccurence->id(), primitiveId);
}
bool GLC_SelectionSet::insertPrimitiveId(GLC_uint occurenceId, GLC_uint primitiveId)
{
bool returnValue= false;
insert(occurenceId);
if (m_InstanceToPrimitiveId.contains(occurenceId))
{
if (!m_InstanceToPrimitiveId[occurenceId].contains(primitiveId))
{
m_InstanceToPrimitiveId[occurenceId].insert(primitiveId);
returnValue= true;
}
else returnValue= false;
}
else
{
QSet<GLC_uint> primitiveSet;
primitiveSet.insert(primitiveId);
m_InstanceToPrimitiveId.insert(occurenceId, primitiveSet);
returnValue= true;
}
return returnValue;
}
void GLC_SelectionSet::insertSetOfPrimitivesId(GLC_StructOccurence* pOccurence, const QSet<GLC_uint>& setOfPrimitivesId)
{
insertSetOfPrimitivesId(pOccurence->id(), setOfPrimitivesId);
}
void GLC_SelectionSet::insertSetOfPrimitivesId(GLC_uint occurenceId, const QSet<GLC_uint>& setOfPrimitivesId)
{
insert(occurenceId);
if (m_InstanceToPrimitiveId.contains(occurenceId))
{
m_InstanceToPrimitiveId[occurenceId].unite(setOfPrimitivesId);
}
else
{
m_InstanceToPrimitiveId.insert(occurenceId, setOfPrimitivesId);
}
}
bool GLC_SelectionSet::removePrimitiveId(GLC_StructOccurence* pOccurence, GLC_uint primitiveId)
{
return removePrimitiveId(pOccurence->id(), primitiveId);
}
bool GLC_SelectionSet::removePrimitiveId(GLC_uint occurenceId, GLC_uint primitiveId)
{
Q_ASSERT(m_pWorldHandle->containsOccurence(occurenceId));
if (m_InstanceToPrimitiveId.contains(occurenceId))
{
if (m_InstanceToPrimitiveId[occurenceId].contains(primitiveId))
{
if (m_InstanceToPrimitiveId[occurenceId].size() == 1)
{
remove(occurenceId);
}
else
{
m_InstanceToPrimitiveId[occurenceId].remove(primitiveId);
}
return true;
}
else return false;
}
else return false;
}

View File

@ -72,15 +72,6 @@ public:
//! Return the list of selected occurences
QList<GLC_StructOccurence*> occurencesList() const;
//! Return the list of occurences with selected primitive
QList<GLC_StructOccurence*> occurencesListWithSelectedPrimitive() const;
//! Return the set of primitive id of the given GLC_StructOccurence/GLC_3DviewInstance id
QSet<GLC_uint> selectedPrimitivesId(GLC_uint instanceId) const;
//! Return true if the given GLC_StructOccurence/GLC_3DviewInstance id has selected primitives
bool hasPrimitiveSelected(GLC_uint instanceId) const;
//! Return true if this selection set contains the given occurence
bool contains(const GLC_StructOccurence* pOccurence) const
{return contains(pOccurence->id());}
@ -114,37 +105,6 @@ public:
//! Clear this selection set
void clear();
//! Insert the given primitive id to the given Occurence return true on success
/*! The given occurence must belongs to this selection set's world*/
bool insertPrimitiveId(GLC_StructOccurence* pOccurence, GLC_uint primitiveId);
//! Insert the given primitive id to the given Occurence id return true on success
/*! The given occurence id must belongs to this selection set's world*/
bool insertPrimitiveId(GLC_uint occurenceId, GLC_uint primitiveId);
//! Insert the given set of primitive id to the given Occurence
/*! The given occurence must belongs to this selection set's world*/
void insertSetOfPrimitivesId(GLC_StructOccurence* pOccurence, const QSet<GLC_uint>& setOfPrimitivesId);
//! Insert the given set of primitive id to the given Occurence id
/*! The given occurence id must belongs to this selection set's world*/
void insertSetOfPrimitivesId(GLC_uint occurenceId, const QSet<GLC_uint>& setOfPrimitivesId);
//! Remove the given primitive id to the given Occurence return true on success
/*! The given occurence must belongs to this selection set's world
* If the set of primitive only contains the given primitive ID
* the given occurence is removed from this selection set
*/
bool removePrimitiveId(GLC_StructOccurence* pOccurence, GLC_uint primitiveId);
//! Remove the given primitive id to the given Occurence return true on success
/*! The given occurence must belongs to this selection set's world
* If the set of primitive only contains the given primitive ID
* the given occurence is removed from this selection set
*/
bool removePrimitiveId(GLC_uint occurenceId, GLC_uint primitiveId);
//@}
//////////////////////////////////////////////////////////////////////
@ -157,9 +117,6 @@ private:
//! Hash table of selected occurence
QHash<GLC_uint, GLC_StructOccurence*> m_OccurenceHash;
//! Hash table of instance id to set of primitive id
QHash<GLC_uint, QSet<GLC_uint> > m_InstanceToPrimitiveId;
};
#endif /* GLC_SELECTIONSET_H_ */

View File

@ -28,7 +28,6 @@
#include "glc_worldhandle.h"
#include "../glc_errorlog.h"
// Default constructor
GLC_StructOccurence::GLC_StructOccurence()
: m_Uid(glc::GLC_GenID())
, m_pWorldHandle(NULL)
@ -47,8 +46,6 @@ GLC_StructOccurence::GLC_StructOccurence()
m_pStructInstance->structOccurenceCreated(this);
}
// Default constructor
GLC_StructOccurence::GLC_StructOccurence(GLC_StructInstance* pStructInstance, GLC_WorldHandle* pWorldHandle, GLuint shaderId)
: m_Uid(glc::GLC_GenID())
, m_pWorldHandle(pWorldHandle)
@ -63,40 +60,26 @@ GLC_StructOccurence::GLC_StructOccurence(GLC_StructInstance* pStructInstance, GL
, m_AutomaticCreationOf3DViewInstance(true)
, m_pRelativeMatrix(NULL)
{
// Update the number of occurences
if (pStructInstance->hasStructOccurence())
{
GLC_StructOccurence* pFirstOccurence= pStructInstance->firstOccurenceHandle();
m_pNumberOfOccurence= pFirstOccurence->m_pNumberOfOccurence;
++(*m_pNumberOfOccurence);
QList<GLC_StructOccurence*> childs= pFirstOccurence->m_Childs;
const int size= childs.size();
for (int i= 0; i < size; ++i)
{
GLC_StructOccurence* pChild= childs.at(i)->clone(m_pWorldHandle, true);
addChild(pChild);
}
}
else
{
m_pNumberOfOccurence= new int(1);
}
setName(m_pStructInstance->name());
// Inform the world Handle
if (NULL != m_pWorldHandle)
{
m_pWorldHandle->addOccurence(this, shaderId);
}
// Update Absolute matrix
updateAbsoluteMatrix();
// Update instance
m_pStructInstance->structOccurenceCreated(this);
doCreateOccurrenceFromInstance(shaderId);
}
// Construct Occurence with the specified GLC_3DRep
GLC_StructOccurence::GLC_StructOccurence(GLC_StructInstance* pStructInstance, GLC_uint id, GLC_WorldHandle* pWorldHandle, GLuint shaderId)
: m_Uid(id)
, m_pWorldHandle(pWorldHandle)
, m_pNumberOfOccurence(NULL)
, m_pStructInstance(pStructInstance)
, m_pParent(NULL)
, m_Childs()
, m_AbsoluteMatrix()
, m_OccurenceNumber(0)
, m_IsVisible(true)
, m_pRenderProperties(NULL)
, m_AutomaticCreationOf3DViewInstance(true)
, m_pRelativeMatrix(NULL)
{
doCreateOccurrenceFromInstance(shaderId);
}
GLC_StructOccurence::GLC_StructOccurence(GLC_3DRep* pRep)
: m_Uid(glc::GLC_GenID())
, m_pWorldHandle(NULL)
@ -112,13 +95,31 @@ GLC_StructOccurence::GLC_StructOccurence(GLC_3DRep* pRep)
, m_pRelativeMatrix(NULL)
{
m_pStructInstance= new GLC_StructInstance(pRep);
setName(m_pStructInstance->name());
// Update instance
m_pStructInstance->structOccurenceCreated(this);
}
// Copy constructor
GLC_StructOccurence::GLC_StructOccurence(GLC_3DRep* pRep, GLC_uint id)
: m_Uid(id)
, m_pWorldHandle(NULL)
, m_pNumberOfOccurence(new int(1))
, m_pStructInstance(NULL)
, m_pParent(NULL)
, m_Childs()
, m_AbsoluteMatrix()
, m_OccurenceNumber(0)
, m_IsVisible(true)
, m_pRenderProperties(NULL)
, m_AutomaticCreationOf3DViewInstance(true)
, m_pRelativeMatrix(NULL)
{
m_pStructInstance= new GLC_StructInstance(pRep);
// Update instance
m_pStructInstance->structOccurenceCreated(this);
}
GLC_StructOccurence::GLC_StructOccurence(GLC_WorldHandle* pWorldHandle, const GLC_StructOccurence& structOccurence, bool shareInstance)
: m_Uid(glc::GLC_GenID())
, m_pWorldHandle(pWorldHandle)
@ -204,7 +205,6 @@ GLC_StructOccurence::GLC_StructOccurence(GLC_WorldHandle* pWorldHandle, const GL
m_pStructInstance->structOccurenceCreated(this);
}
// Destructor
GLC_StructOccurence::~GLC_StructOccurence()
{
//qDebug() << "Delete " << id();
@ -265,7 +265,7 @@ GLC_Matrix4x4 GLC_StructOccurence::occurrenceRelativeMatrix() const
bool GLC_StructOccurence::hasRepresentation() const
{
if ((NULL != m_pStructInstance) && (m_pStructInstance->hasStructOccurence()))
if ((NULL != m_pStructInstance) && (m_pStructInstance->structReference() != NULL))
{
return this->structReference()->hasRepresentation();
}
@ -352,7 +352,6 @@ unsigned int GLC_StructOccurence::numberOfVertex() const
return result;
}
// Get number of materials
unsigned int GLC_StructOccurence::numberOfMaterials() const
{
unsigned int result= 0;
@ -372,7 +371,6 @@ unsigned int GLC_StructOccurence::numberOfMaterials() const
return result;
}
// Get materials List
QSet<GLC_Material*> GLC_StructOccurence::materialSet() const
{
QSet<GLC_Material*> materialSet;
@ -390,13 +388,11 @@ QSet<GLC_Material*> GLC_StructOccurence::materialSet() const
return materialSet;
}
// Clone the occurence
GLC_StructOccurence* GLC_StructOccurence::clone(GLC_WorldHandle* pWorldHandle, bool shareInstance) const
{
return new GLC_StructOccurence(pWorldHandle, *this, shareInstance);
}
// Return true if the occurence is visible
bool GLC_StructOccurence::isVisible() const
{
bool isHidden= true;
@ -422,7 +418,6 @@ bool GLC_StructOccurence::isVisible() const
return !isHidden;
}
// Return the occurence Bounding Box
GLC_BoundingBox GLC_StructOccurence::boundingBox() const
{
GLC_BoundingBox boundingBox;
@ -495,11 +490,32 @@ QSet<GLC_StructReference*> GLC_StructOccurence::parentsReferences(const GLC_Stru
return parentSet;
}
int GLC_StructOccurence::indexOf(const GLC_StructOccurence* pOcc) const
{
int subject= -1;
const int childCount= m_Childs.count();
bool containsOcc= false;
int i= 0;
while (!containsOcc && (i < childCount))
{
if (m_Childs.at(i) == pOcc)
{
containsOcc= true;
subject= i;
}
++i;
}
return subject;
}
bool GLC_StructOccurence::containsChild(const GLC_StructOccurence* pOcc) const
{
return pOcc->parent() == this;
}
//////////////////////////////////////////////////////////////////////
// Set Functions
//////////////////////////////////////////////////////////////////////
// Update the absolute matrix
GLC_StructOccurence* GLC_StructOccurence::updateAbsoluteMatrix()
{
GLC_Matrix4x4 relativeMatrix;
@ -529,7 +545,6 @@ GLC_StructOccurence* GLC_StructOccurence::updateAbsoluteMatrix()
return this;
}
// Update children obsolute Matrix
GLC_StructOccurence* GLC_StructOccurence::updateChildrenAbsoluteMatrix()
{
updateAbsoluteMatrix();
@ -541,7 +556,6 @@ GLC_StructOccurence* GLC_StructOccurence::updateChildrenAbsoluteMatrix()
return this;
}
// Add Child
void GLC_StructOccurence::addChild(GLC_StructOccurence* pChild)
{
Q_ASSERT(pChild->isOrphan());
@ -559,7 +573,24 @@ void GLC_StructOccurence::addChild(GLC_StructOccurence* pChild)
pChild->updateChildrenAbsoluteMatrix();
}
// Add Child instance and returns the newly created occurence
void GLC_StructOccurence::insertChild(int index, GLC_StructOccurence* pChild)
{
Q_ASSERT(pChild->isOrphan());
Q_ASSERT((NULL == pChild->m_pWorldHandle) || (m_pWorldHandle == pChild->m_pWorldHandle));
Q_ASSERT(m_Childs.count() >= index);
//qDebug() << "Add Child " << pChild->name() << "id=" << pChild->id() << " to " << name() << " id=" << id();
// Add the child to the list of child
// Get occurence reference
m_Childs.insert(index, pChild);
pChild->m_pParent= this;
if (NULL == pChild->m_pWorldHandle)
{
pChild->setWorldHandle(m_pWorldHandle);
}
pChild->updateChildrenAbsoluteMatrix();
}
GLC_StructOccurence* GLC_StructOccurence::addChild(GLC_StructInstance* pInstance)
{
GLC_StructOccurence* pOccurence;
@ -570,17 +601,28 @@ GLC_StructOccurence* GLC_StructOccurence::addChild(GLC_StructInstance* pInstance
return pOccurence;
}
// make the occurence orphan
void GLC_StructOccurence::makeOrphan()
GLC_StructOccurence* GLC_StructOccurence::insertChild(int index, GLC_StructInstance* pInstance)
{
//qDebug() << "GLC_StructOccurence::makeOrphan() " << id();
//qDebug() << name() << " " << id();
Q_ASSERT(!isOrphan());
m_pParent->removeChild(this);
//qDebug() << "GLC_StructOccurence::makeOrphan() DONE!";
GLC_StructOccurence* pOccurence;
pOccurence= new GLC_StructOccurence(pInstance, m_pWorldHandle);
insertChild(index, pOccurence);
return pOccurence;
}
void GLC_StructOccurence::makeOrphan()
{
if(!isOrphan())
{
m_pParent->removeChild(this);
}
else
{
detach();
}
}
// Remove the specified child
bool GLC_StructOccurence::removeChild(GLC_StructOccurence* pChild)
{
Q_ASSERT(pChild->m_pParent == this);
@ -592,7 +634,6 @@ bool GLC_StructOccurence::removeChild(GLC_StructOccurence* pChild)
}
// Reverse Normals of this Occurence and childs
void GLC_StructOccurence::reverseNormals()
{
if (has3DViewInstance())
@ -601,21 +642,17 @@ void GLC_StructOccurence::reverseNormals()
}
}
// Check the presence of representation
bool GLC_StructOccurence::create3DViewInstance()
bool GLC_StructOccurence::create3DViewInstance(GLuint shaderId)
{
bool creationSuccess= false;
if ((NULL != m_pWorldHandle) && hasRepresentation())
bool subject= false;
if (!has3DViewInstance() && (NULL != m_pWorldHandle) && hasRepresentation())
{
GLC_3DRep* p3DRep= dynamic_cast<GLC_3DRep*>(structReference()->representationHandle());
if (NULL != p3DRep)
{
GLC_3DViewInstance instance(*p3DRep);
GLC_3DViewInstance instance(*p3DRep, m_Uid);
instance.setName(name());
// Force instance representation id
instance.setId(id());
if (NULL != m_pRenderProperties)
{
instance.setRenderProperties(*m_pRenderProperties);
@ -623,7 +660,8 @@ bool GLC_StructOccurence::create3DViewInstance()
m_pRenderProperties= NULL;
}
creationSuccess= m_pWorldHandle->collection()->add(instance);
if (0 != shaderId) m_pWorldHandle->collection()->bindShader(shaderId);
subject= m_pWorldHandle->collection()->add(instance, shaderId);
m_pWorldHandle->collection()->setVisibility(m_Uid, m_IsVisible);
if (m_pWorldHandle->selectionSetHandle()->contains(m_Uid))
{
@ -631,7 +669,7 @@ bool GLC_StructOccurence::create3DViewInstance()
}
}
}
return creationSuccess;
return subject;
}
bool GLC_StructOccurence::remove3DViewInstance()
@ -752,12 +790,15 @@ void GLC_StructOccurence::setVisibility(bool visibility)
void GLC_StructOccurence::setRenderProperties(const GLC_RenderProperties& renderProperties)
{
qDebug() << "GLC_StructOccurence::setRenderProperties";
delete m_pRenderProperties;
m_pRenderProperties= NULL;
if (has3DViewInstance())
{
m_pWorldHandle->collection()->instanceHandle(m_Uid)->setRenderProperties(renderProperties);
}
else if (hasChild())
if (hasChild())
{
const int childCount= m_Childs.size();
for (int i= 0; i < childCount; ++i)
@ -765,7 +806,7 @@ void GLC_StructOccurence::setRenderProperties(const GLC_RenderProperties& render
m_Childs[i]->setRenderProperties(renderProperties);
}
}
else
else if (!has3DViewInstance())
{
m_pRenderProperties= new GLC_RenderProperties(renderProperties);
}
@ -845,6 +886,22 @@ void GLC_StructOccurence::makeRigid()
updateChildrenAbsoluteMatrix();
}
void GLC_StructOccurence::swap(int i, int j)
{
Q_ASSERT(i != j);
GLC_StructReference* pRef= this->structReference();
QList<GLC_StructOccurence*> occurences= pRef->listOfStructOccurence();
const int count= occurences.count();
for (int i= 0; i < count; ++i)
{
GLC_StructOccurence* pOcc= occurences.at(i);
Q_ASSERT(i <= pOcc->m_Childs.count());
Q_ASSERT(j <= pOcc->m_Childs.count());
pOcc->m_Childs.swap(i, j);
}
}
//////////////////////////////////////////////////////////////////////
// Private services function
@ -876,3 +933,37 @@ void GLC_StructOccurence::detach()
}
}
}
void GLC_StructOccurence::doCreateOccurrenceFromInstance(GLuint shaderId)
{
// Update the number of occurences
if (m_pStructInstance->hasStructOccurence())
{
GLC_StructOccurence* pFirstOccurence= m_pStructInstance->firstOccurenceHandle();
m_pNumberOfOccurence= pFirstOccurence->m_pNumberOfOccurence;
++(*m_pNumberOfOccurence);
QList<GLC_StructOccurence*> childs= pFirstOccurence->m_Childs;
const int size= childs.size();
for (int i= 0; i < size; ++i)
{
GLC_StructOccurence* pChild= childs.at(i)->clone(m_pWorldHandle, true);
addChild(pChild);
}
}
else
{
m_pNumberOfOccurence= new int(1);
}
// Inform the world Handle
if (NULL != m_pWorldHandle)
{
m_pWorldHandle->addOccurence(this, shaderId);
}
// Update Absolute matrix
updateAbsoluteMatrix();
// Update instance
m_pStructInstance->structOccurenceCreated(this);
}

View File

@ -52,10 +52,16 @@ public:
GLC_StructOccurence();
//! Create Occurence of the specified instance
GLC_StructOccurence(GLC_StructInstance*, GLC_WorldHandle* pWorldHandle= NULL, GLuint shaderId=0);
GLC_StructOccurence(GLC_StructInstance* pStructInstance, GLC_WorldHandle* pWorldHandle= NULL, GLuint shaderId=0);
//! Construct Occurence withe the specified GLC_3DRep
GLC_StructOccurence(GLC_3DRep*);
//! Create Occurence of the specified instance and Uid
GLC_StructOccurence(GLC_StructInstance* pStructInstance, GLC_uint id, GLC_WorldHandle* pWorldHandle= NULL, GLuint shaderId=0);
//! Construct Occurence with the specified GLC_3DRep
GLC_StructOccurence(GLC_3DRep* pRep);
//! Construct Occurence from the given GLC_3DRep and Uid
GLC_StructOccurence(GLC_3DRep* pRep, GLC_uint id);
//! Copy constructor
GLC_StructOccurence(GLC_WorldHandle*, const GLC_StructOccurence&, bool shareInstance);
@ -184,6 +190,13 @@ public:
//! Return true if this occurence is flexible
inline bool isFlexible() const
{return (m_pRelativeMatrix != NULL);}
//! Return the index position of the given occurrence
/*! Return -1 if the given occurence is not a child of this occurence*/
int indexOf(const GLC_StructOccurence* pOcc) const;
//! Return true if this occurence contains the given occurence has child
bool containsChild(const GLC_StructOccurence* pOcc) const;
//@}
//////////////////////////////////////////////////////////////////////
/*! \name Set Functions*/
@ -204,9 +217,16 @@ public:
/*! The new child must be orphan*/
void addChild(GLC_StructOccurence*);
//! insert Child at the given position
/*! The new child must be orphan and index >= childcount*/
void insertChild(int index, GLC_StructOccurence* pChild);
//! Add Child instance and returns the newly created occurence
GLC_StructOccurence* addChild(GLC_StructInstance*);
//! Insert Child instance and returns the newly created occurence
GLC_StructOccurence* insertChild(int index, GLC_StructInstance* pInstance);
//! make the occurence orphan
void makeOrphan();
@ -218,7 +238,7 @@ public:
void reverseNormals();
//! Create the 3DViewInstance of this occurence if there is a valid 3DRep
bool create3DViewInstance();
bool create3DViewInstance(GLuint shaderId= 0);
//! Remove the 3DViewInstance of this occurence
bool remove3DViewInstance();
@ -239,7 +259,7 @@ public:
//! Update the occurence number of this occurence branch
unsigned int updateOccurenceNumber(unsigned int n);
//! Set this occurence visibility
//! Set this occurence and children visibility
void setVisibility(bool visibility);
//! set the renderProperties of this occurence
@ -260,6 +280,10 @@ public:
//! Make this occurence rigid
void makeRigid();
//! Exchange the occurrence at index position i with the occurrence at index position j
/*!This function assumes that both i and j are at least 0 but less than childCount().*/
void swap(int i, int j);
//@}
//////////////////////////////////////////////////////////////////////
@ -269,6 +293,9 @@ private:
//! Detach the occurence from the GLC_World
void detach();
//! Create occurrence from instance and given shader id
void doCreateOccurrenceFromInstance(GLuint shaderId);
//////////////////////////////////////////////////////////////////////
// Private members
//////////////////////////////////////////////////////////////////////

View File

@ -241,37 +241,32 @@ bool GLC_StructReference::unloadRepresentation()
else return false;
}
bool GLC_StructReference::addChild(GLC_StructOccurence* pOccurence)
QList<GLC_StructOccurence*> GLC_StructReference::addChild(GLC_StructOccurence* pOccurence)
{
QList<GLC_StructOccurence*> subject;
if (hasStructInstance() && firstInstanceHandle()->hasStructOccurence())
{
GLC_StructOccurence* pCurrentChildOccurence= pOccurence;
QSet<GLC_StructInstance*>::iterator iInstance= m_SetOfInstance.begin();
while (m_SetOfInstance.constEnd() != iInstance)
QList<GLC_StructOccurence*> parentOccurences= listOfStructOccurence();
const int parentCount= parentOccurences.count();
GLC_StructInstance* pNewInstance= NULL;
for (int i= 0; i < parentCount; ++i)
{
GLC_StructInstance* pCurrentInstance= *iInstance;
QList<GLC_StructOccurence*> occurenceList= pCurrentInstance->listOfStructOccurences();
const int occurenceCount= occurenceList.count();
for (int i= 0; i < occurenceCount; ++i)
GLC_StructOccurence* pCurrentParent= parentOccurences.at(i);
GLC_StructOccurence* pNewChild= NULL;
if (NULL == pNewInstance)
{
GLC_StructOccurence* pCurrentOccurence= occurenceList.at(i);
if ((i != 0) || (NULL == pCurrentChildOccurence))
{
pCurrentChildOccurence= pOccurence->clone(pCurrentOccurence->worldHandle(), true);
}
pCurrentOccurence->addChild(pCurrentChildOccurence);
pNewChild= pOccurence;
pNewInstance= pNewChild->structInstance();
pCurrentParent->addChild(pNewChild);
}
pCurrentChildOccurence= NULL;
++iInstance;
else
{
pNewChild= pCurrentParent->addChild(pNewInstance);
}
subject.append(pNewChild);
}
return true;
}
else
{
return false;
}
return subject;
}

View File

@ -210,9 +210,9 @@ public:
/*! The representation must exists*/
bool unloadRepresentation();
//! Add the given occurence as a child
/*! Return true on success*/
bool addChild(GLC_StructOccurence* pOccurence);
//! Add the given occurence as a child of all occurrences of this reference
/*! Return the list of added occurence*/
QList<GLC_StructOccurence*> addChild(GLC_StructOccurence* pOccurence);
//@}

View File

@ -26,7 +26,6 @@
#include "glc_structinstance.h"
#include "glc_structreference.h"
// Default constructor
GLC_World::GLC_World()
: m_pWorldHandle(new GLC_WorldHandle())
, m_pRoot(new GLC_StructOccurence())
@ -34,7 +33,13 @@ GLC_World::GLC_World()
m_pRoot->setWorldHandle(m_pWorldHandle);
}
// Copy constructor
GLC_World::GLC_World(GLC_StructOccurence* pOcc)
: m_pWorldHandle(new GLC_WorldHandle())
, m_pRoot(pOcc)
{
m_pRoot->setWorldHandle(m_pWorldHandle);
}
GLC_World::GLC_World(const GLC_World& world)
: m_pWorldHandle(world.m_pWorldHandle)
, m_pRoot(world.m_pRoot)
@ -58,7 +63,25 @@ GLC_World::~GLC_World()
}
}
// Merge this world with another world
GLC_StructOccurence* GLC_World::takeRootOccurrence()
{
GLC_StructOccurence* pSubject= m_pRoot;
pSubject->makeOrphan();
m_pRoot= new GLC_StructOccurence();
m_pRoot->setWorldHandle(m_pWorldHandle);
return pSubject;
}
void GLC_World::replaceRootOccurrence(GLC_StructOccurence* pOcc)
{
Q_ASSERT(pOcc->isOrphan());
delete m_pRoot;
m_pRoot= pOcc;
m_pRoot->setWorldHandle(m_pWorldHandle);
}
void GLC_World::mergeWithAnotherWorld(GLC_World& anotherWorld)
{
GLC_StructOccurence* pAnotherRoot= anotherWorld.rootOccurence();
@ -78,7 +101,6 @@ void GLC_World::mergeWithAnotherWorld(GLC_World& anotherWorld)
}
}
// Assignment operator
GLC_World& GLC_World::operator=(const GLC_World& world)
{
if (this != &world)

View File

@ -53,6 +53,9 @@ public:
//! Default constructor
GLC_World();
//! Create a world and set the root occurrence to the given occurrence
explicit GLC_World(GLC_StructOccurence* pOcc);
//! Copy constructor
GLC_World(const GLC_World&);
@ -174,9 +177,8 @@ public:
inline QList<GLC_StructOccurence*> selectedOccurenceList() const
{return m_pWorldHandle->selectionSetHandle()->occurencesList();}
//! Return the list of selected occurences
inline QList<GLC_StructOccurence*> selectedPrimitiveOccurenceList() const
{return m_pWorldHandle->selectionSetHandle()->occurencesListWithSelectedPrimitive();}
//! Take the root occurence of this world
GLC_StructOccurence* takeRootOccurrence();
//@}
@ -185,6 +187,9 @@ public:
//@{
//////////////////////////////////////////////////////////////////////
public:
//! Replace the root occurrence of this world by the given occurrence
void replaceRootOccurrence(GLC_StructOccurence* pOcc);
//! Merge this world with another world
void mergeWithAnotherWorld(GLC_World &);
@ -244,8 +249,6 @@ public:
//! Hide selected 3DViewInstance
inline void hideSelected3DViewInstance()
{m_pWorldHandle->setSelected3DViewInstanceVisibility(false);}
//@}
//////////////////////////////////////////////////////////////////////

View File

@ -102,20 +102,8 @@ void GLC_WorldHandle::addOccurence(GLC_StructOccurence* pOccurence, bool isSelec
// Add instance representation in the collection
if (pOccurence->useAutomatic3DViewInstanceCreation() && pRef->representationIsLoaded())
{
//qDebug() << "GLC_WorldHandle::addOccurence with rep";
GLC_3DRep* p3DRep= dynamic_cast<GLC_3DRep*>(pRef->representationHandle());
GLC_3DViewInstance representation(*p3DRep);
// Force instance representation id
representation.setId(pOccurence->id());
// Force instance representation name
representation.setName(pOccurence->name());
if (0 != shaderId) m_Collection.bindShader(shaderId);
m_Collection.add(representation, shaderId);
if (isSelected)
{
//qDebug() << pOccurence->name() << "selected";
m_Collection.select(pOccurence->id());
}
pOccurence->create3DViewInstance(shaderId);
if (isSelected) select(pOccurence->id());
}
}
@ -209,6 +197,6 @@ void GLC_WorldHandle::setSelected3DViewInstanceVisibility(bool isVisible)
{
GLC_3DViewInstance* pCurrentInstance= selected3dviewInstance.at(i);
pCurrentInstance->setVisibility(isVisible);
}
}
}

View File

@ -152,7 +152,7 @@ public:
//! Select all occurence of this world handle
void selectAllWith3DViewInstance(bool allShowState);
//! Unselecte all occurence of this world handle
//! Unselect all occurence of this world handle
void unselectAll();
//! Show / Hide selected 3DViewInstance
@ -161,7 +161,6 @@ public:
//! Set selected 3DViewInstance visibility
void setSelected3DViewInstanceVisibility(bool isVisible);
//@}
//////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,139 @@
/****************************************************************************
This file is part of the GLC-lib library.
Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
http://glc-lib.sourceforge.net
GLC-lib is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
GLC-lib is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with GLC-lib; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
//! \file glc_renderer.cpp implementation of the GLC_Renderer class.
#include <QtDebug>
#include "../sceneGraph/glc_3dviewcollection.h"
#include "glc_renderer.h"
GLC_Renderer::GLC_Renderer()
: m_pCollection(NULL)
, m_IdToRenderProperties()
, m_IsCurrent(false)
{
}
GLC_Renderer::GLC_Renderer(GLC_3DViewCollection* pCollection)
: m_pCollection(pCollection)
, m_IdToRenderProperties()
, m_IsCurrent(false)
{
}
GLC_Renderer::GLC_Renderer(const GLC_Renderer& other)
: m_pCollection(other.m_pCollection)
, m_IdToRenderProperties(other.m_IdToRenderProperties)
, m_IsCurrent(false)
{
}
GLC_Renderer::~GLC_Renderer()
{
clear();
}
bool GLC_Renderer::instanceRenderPropertiesIsAvailable(GLC_uint id) const
{
return m_IdToRenderProperties.contains(id);
}
const GLC_RenderProperties& GLC_Renderer::renderPropertiesOfInstance(GLC_uint id) const
{
Q_ASSERT(m_IdToRenderProperties.contains(id));
return m_IdToRenderProperties.find(id).value();
}
void GLC_Renderer::clear()
{
m_pCollection= NULL;
m_IdToRenderProperties.clear();
}
GLC_Renderer& GLC_Renderer::operator=(const GLC_Renderer& other)
{
if (this != &other)
{
m_pCollection= other.m_pCollection;
m_IdToRenderProperties= other.m_IdToRenderProperties;
// m_IsCurrent doesn't change
}
return *this;
}
void GLC_Renderer::setCollection(GLC_3DViewCollection* pCollection)
{
if (pCollection != m_pCollection)
{
clear();
m_pCollection= pCollection;
}
}
void GLC_Renderer::setCurrent()
{
if (NULL != m_pCollection)
{
Q_ASSERT(!m_IsCurrent);
m_IsCurrent= true;
QHash<GLC_uint, GLC_RenderProperties>::const_iterator iRender= m_IdToRenderProperties.constBegin();
while (iRender != m_IdToRenderProperties.constEnd())
{
if (m_pCollection->contains(iRender.key()))
{
m_pCollection->instanceHandle(iRender.key())->renderPropertiesHandle()->operator =(iRender.value());
}
++iRender;
}
m_IdToRenderProperties.clear();
}
}
void GLC_Renderer::unSetCurrent()
{
if (NULL != m_pCollection)
{
Q_ASSERT(m_IdToRenderProperties.isEmpty());
Q_ASSERT(m_IsCurrent);
m_IsCurrent= false;
QList<GLC_3DViewInstance*> instances= m_pCollection->instancesHandle();
const int count= instances.count();
for (int i= 0; i < count; ++i)
{
GLC_3DViewInstance* pInstance= instances.at(i);
m_IdToRenderProperties.insert(pInstance->id(), *(pInstance->renderPropertiesHandle()));
}
}
}
void GLC_Renderer::addRenderPropertiesOfInstanceId(GLC_uint id)
{
Q_ASSERT(NULL != m_pCollection);
Q_ASSERT(m_pCollection->contains(id));
m_IdToRenderProperties.insert(id, *(m_pCollection->instanceHandle(id)->renderPropertiesHandle()));
}

View File

@ -0,0 +1,126 @@
/****************************************************************************
This file is part of the GLC-lib library.
Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
http://glc-lib.sourceforge.net
GLC-lib is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
GLC-lib is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with GLC-lib; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
//! \file glc_renderer.h interface for the GLC_Renderer class.
#ifndef GLC_RENDERER_H_
#define GLC_RENDERER_H_
#include <QHash>
#include "glc_renderproperties.h"
#include "../glc_config.h"
class GLC_3DViewCollection;
//////////////////////////////////////////////////////////////////////
//! \class GLC_Renderer
/*! \brief GLC_Renderer : Is used to store and retrieve overload rendering properties*/
/*! An GLC_Renderer is attached to a GLC_3DViewCollection \n
* The renderer is used to render a scene in a specific way.*/
//////////////////////////////////////////////////////////////////////
class GLC_LIB_EXPORT GLC_Renderer
{
public:
//////////////////////////////////////////////////////////////////////
/*! @name Constructor / Destructor */
//@{
//////////////////////////////////////////////////////////////////////
GLC_Renderer();
GLC_Renderer(GLC_3DViewCollection* pCollection);
GLC_Renderer(const GLC_Renderer& other);
virtual ~GLC_Renderer();
//@}
//////////////////////////////////////////////////////////////////////
/*! \name Get Functions*/
//@{
//////////////////////////////////////////////////////////////////////
public:
//! Return true if this renderer has an attached collection
inline bool hasCollection() const
{return m_pCollection != NULL;}
//! Return the 3DView collection attached to this renderer
inline GLC_3DViewCollection* collection() const
{return m_pCollection;}
//! Return true if the renderProperties of the given instance id is available
bool instanceRenderPropertiesIsAvailable(GLC_uint id) const;
//! Return the renderProperties of the given instance id
const GLC_RenderProperties& renderPropertiesOfInstance(GLC_uint id) const;
//! Return true if this renderer is current
inline bool isCurrent() const
{return m_IsCurrent;}
//@}
//////////////////////////////////////////////////////////////////////
/*! \name Set Functions*/
//@{
//////////////////////////////////////////////////////////////////////
public:
//! Clear the content of this render
void clear();
//! Assignement operator
GLC_Renderer& operator=(const GLC_Renderer& other);
//! Set the collection to use
void setCollection(GLC_3DViewCollection* pCollection);
//! Set this renderer the current renderer
/*! Apply stored renderProperties to the attached collection*/
void setCurrent();
//! Unset this rendere the current rendere
/*! Save the render properties of all instance of the scene*/
void unSetCurrent();
//! Add the renderProperties of the given instance id
void addRenderPropertiesOfInstanceId(GLC_uint id);
//@}
//////////////////////////////////////////////////////////////////////
// Private services fonction
//////////////////////////////////////////////////////////////////////
private:
//////////////////////////////////////////////////////////////////////
// Private Members
//////////////////////////////////////////////////////////////////////
private:
//! The 3DView collection attached to this renderer
GLC_3DViewCollection* m_pCollection;
QHash<GLC_uint, GLC_RenderProperties> m_IdToRenderProperties;
bool m_IsCurrent;
};
#endif /* GLC_RENDERER_H_ */

View File

@ -382,5 +382,10 @@ void GLC_RenderProperties::clearOverwritePrimitiveMaterials()
delete m_pOverwritePrimitiveMaterialMaps;
m_pOverwritePrimitiveMaterialMaps= NULL;
if ((m_SavedRenderMode == glc::OverwritePrimitiveMaterial))
{
m_SavedRenderMode= glc::NormalRenderMode;
}
}

View File

@ -40,14 +40,14 @@ namespace glc
//! Geometry rendering mode enumeration
enum RenderMode
{
NormalRenderMode,
OverwriteMaterial,
OverwriteTransparency,
OverwriteTransparencyAndMaterial,
PrimitiveSelected,
OverwritePrimitiveMaterial,
BodySelection,
PrimitiveSelection
NormalRenderMode= 0,
OverwriteMaterial= 1,
OverwriteTransparency= 2,
OverwriteTransparencyAndMaterial= 3,
PrimitiveSelected= 4,
OverwritePrimitiveMaterial= 5,
BodySelection= 6,
PrimitiveSelection= 7
};
//! Geometry rendring flag enumaration

View File

@ -131,6 +131,7 @@ void GLC_RepFlyMover::glDraw()
m_Hud.render(glc::TransparentRenderFlag);
m_Plane.render(glc::TransparentRenderFlag);
/*
// Render velocity value + text
QString velocity(QChar(' ') + QString::number(static_cast<int>(100.0 * m_pRepMoverInfo->m_DoubleInfo.first())));
QFont myFont;
@ -139,6 +140,7 @@ void GLC_RepFlyMover::glDraw()
int txtHeight= fontmetrics.boundingRect(velocity).height();
double posy= 2.0 * static_cast<double>(txtHeight) / calibre;
m_pViewport->qGLWidgetHandle()->renderText(- m_HudOffset.getX(), m_HudOffset.getY() - posy, 0.0, velocity, myFont);
*/
GLC_Context::current()->glcPopMatrix();
GLC_Context::current()->glcMatrixMode(GL_PROJECTION);
@ -158,8 +160,8 @@ void GLC_RepFlyMover::createRepresentation()
GLC_Polylines* pPolylines= new GLC_Polylines();
GLfloatVector points;
const double hudx= m_HudOffset.getX();
const double hudy= m_HudOffset.getY();
const double hudx= m_HudOffset.x();
const double hudy= m_HudOffset.y();
points << -hudx << -hudy << 0.0;
points << -hudx << hudy << 0.0;
pPolylines->addPolyline(points);

View File

@ -80,7 +80,7 @@ bool GLC_TsrMover::move(const GLC_UserInput& userInput)
qDebug() << "Pas cool";
if (!userInput.translation().isNull())
{
m_PreviousVector= GLC_Vector3d(userInput.translation().getX(), userInput.translation().getY(), 0.0) + m_PreviousVector;
m_PreviousVector= GLC_Vector3d(userInput.translation().x(), userInput.translation().y(), 0.0) + m_PreviousVector;
}
}
@ -97,7 +97,7 @@ bool GLC_TsrMover::move(const GLC_UserInput& userInput)
m_pViewport->setDistMinAndMax(dummy.boundingBox());
GLC_Point2d nPos= m_pViewport->mapNormalyzeToOpenGLScreen(x, y);
GLC_Point3d nPos3D(nPos.getX(), nPos.getY(), 1.0);
GLC_Point3d nPos3D(nPos.x(), nPos.y(), 1.0);
GLC_Point3d projected= m_pViewport->compositionMatrix().inverted() * nPos3D;
m_pViewport->cameraHandle()->zoom(userInput.scaleFactor());
@ -114,7 +114,7 @@ bool GLC_TsrMover::move(const GLC_UserInput& userInput)
m_pViewport->setDistMinAndMax(dummy.boundingBox());
GLC_Point2d nPos= m_pViewport->mapNormalyzeToOpenGLScreen(x, y);
GLC_Point3d nPos3D(nPos.getX(), nPos.getY(), 1.0);
GLC_Point3d nPos3D(nPos.x(), nPos.y(), 1.0);
GLC_Point3d center= m_pViewport->compositionMatrix().inverted() * nPos3D;
GLC_Vector3d axis= m_pViewport->cameraHandle()->forward();
@ -124,8 +124,8 @@ bool GLC_TsrMover::move(const GLC_UserInput& userInput)
if (!userInput.translation().isNull())
{
double transX= userInput.translation().getX() * m_pViewport->viewHSize();
double transY= userInput.translation().getY() * m_pViewport->viewVSize();
double transX= userInput.translation().x() * m_pViewport->viewHSize();
double transY= userInput.translation().y() * m_pViewport->viewVSize();
GLC_Vector3d mappedTranslation(-transX, -transY, 0.0);
// Compute the length of camera's field of view

View File

@ -39,7 +39,7 @@ using namespace glc;
// Constructor Destructor
//////////////////////////////////////////////////////////////////////
GLC_Viewport::GLC_Viewport(QGLWidget *GLWidget)
GLC_Viewport::GLC_Viewport()
// Camera definition
: m_pViewCam(new GLC_Camera()) // Camera
, m_DistanceMax(500.0) // Camera Maximum distance
@ -51,7 +51,6 @@ GLC_Viewport::GLC_Viewport(QGLWidget *GLWidget)
, m_WindowHSize(0) // Horizontal OpenGL viewport size
, m_WindowVSize(0) // Vertical OpenGL viewport size
, m_AspectRatio(1.0)
, m_pQGLWidget(GLWidget) // Attached QGLWidget
// the default backgroundColor
, m_BackgroundColor(Qt::black)
, m_SelectionSquareSize(4)
@ -108,14 +107,14 @@ GLC_Point2d GLC_Viewport::mapToOpenGLScreen(int x, int y)
{
GLC_Point2d nPos= normalyseMousePosition(x, y);
return mapNormalyzeToOpenGLScreen(nPos.getX(), nPos.getY());
return mapNormalyzeToOpenGLScreen(nPos.x(), nPos.y());
}
GLC_Point2d GLC_Viewport::mapNormalyzeToOpenGLScreen(double x, double y)
{
GLC_Point2d pos(x, y);
pos= pos * 2.0;
pos.setY(pos.getY() * -1.0);
pos.setY(pos.y() * -1.0);
pos= pos + GLC_Point2d(-1.0, 1.0);
return pos;
}
@ -153,7 +152,7 @@ GLC_Vector3d GLC_Viewport::mapNormalyzePosMouse(double Posx, double Posy) const
void GLC_Viewport::initGl()
{
m_pQGLWidget->qglClearColor(m_BackgroundColor); // Background
glClearColor(m_BackgroundColor.redF(), m_BackgroundColor.greenF(), m_BackgroundColor.blueF(), 1.0f);
glClearDepth(1.0f); // Depth Buffer Setup
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
@ -324,31 +323,34 @@ void GLC_Viewport::render3DWidget()
void GLC_Viewport::setWinGLSize(int HSize, int VSize)
{
m_WindowHSize= HSize;
m_WindowVSize= VSize;
// from NeHe's Tutorial 3
if (m_WindowVSize == 0) // Prevent A Divide By Zero By
if ((m_WindowHSize != HSize) || (m_WindowVSize != VSize))
{
m_WindowVSize= 1; // Making Height Equal One
m_WindowHSize= HSize;
m_WindowVSize= VSize;
// from NeHe's Tutorial 3
if (m_WindowVSize == 0) // Prevent A Divide By Zero By
{
m_WindowVSize= 1; // Making Height Equal One
}
glViewport(0,0,m_WindowHSize,m_WindowVSize); // Reset The Current Viewport
updateAspectRatio();
updateProjectionMat();
updateMinimumRatioSize();
}
glViewport(0,0,m_WindowHSize,m_WindowVSize); // Reset The Current Viewport
updateAspectRatio();
updateProjectionMat();
updateMinimumRatioSize();
}
GLC_uint GLC_Viewport::renderAndSelect(int x, int y)
{
m_pQGLWidget->qglClearColor(Qt::black);
const QColor clearColor(Qt::black);
glClearColor(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), 1.0f);
GLC_State::setSelectionMode(true);
// Draw the scene
m_pQGLWidget->updateGL();
emit updateOpenGL();
GLC_State::setSelectionMode(false);
return selectOnPreviousRender(x, y);
@ -359,7 +361,7 @@ GLC_uint GLC_Viewport::selectOnPreviousRender(int x, int y)
GLsizei width= m_SelectionSquareSize;
GLsizei height= width;
GLint newX= x - width / 2;
GLint newY= (m_pQGLWidget->size().height() - y) - height / 2;
GLint newY= (m_WindowVSize - y) - height / 2;
if (newX < 0) newX= 0;
if (newY < 0) newY= 0;
@ -367,7 +369,8 @@ GLC_uint GLC_Viewport::selectOnPreviousRender(int x, int y)
}
GLC_uint GLC_Viewport::selectBody(GLC_3DViewInstance* pInstance, int x, int y)
{
m_pQGLWidget->qglClearColor(Qt::black);
const QColor clearColor(Qt::black);
glClearColor(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), 1.0f);
GLC_State::setSelectionMode(true);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLC_Context::current()->glcLoadIdentity();
@ -385,7 +388,7 @@ GLC_uint GLC_Viewport::selectBody(GLC_3DViewInstance* pInstance, int x, int y)
GLsizei width= 6;
GLsizei height= width;
GLint newX= x - width / 2;
GLint newY= (m_pQGLWidget->size().height() - y) - height / 2;
GLint newY= (m_WindowVSize - y) - height / 2;
if (newX < 0) newX= 0;
if (newY < 0) newY= 0;
@ -396,7 +399,8 @@ QPair<int, GLC_uint> GLC_Viewport::selectPrimitive(GLC_3DViewInstance* pInstance
{
QPair<int, GLC_uint> result;
m_pQGLWidget->qglClearColor(Qt::black);
const QColor clearColor(Qt::black);
glClearColor(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), 1.0f);
GLC_State::setSelectionMode(true);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLC_Context::current()->glcLoadIdentity();
@ -414,7 +418,7 @@ QPair<int, GLC_uint> GLC_Viewport::selectPrimitive(GLC_3DViewInstance* pInstance
GLsizei width= 6;
GLsizei height= width;
GLint newX= x - width / 2;
GLint newY= (m_pQGLWidget->size().height() - y) - height / 2;
GLint newY= (m_WindowVSize - y) - height / 2;
if (newX < 0) newX= 0;
if (newY < 0) newY= 0;
@ -449,16 +453,17 @@ QSet<GLC_uint> GLC_Viewport::selectInsideSquare(int x1, int y1, int x2, int y2)
y1= y2;
y2= yTemp;
}
m_pQGLWidget->qglClearColor(Qt::black);
const QColor clearColor(Qt::black);
glClearColor(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), 1.0f);
GLC_State::setSelectionMode(true);
// Draw the scene
m_pQGLWidget->updateGL();
updateOpenGL();
GLC_State::setSelectionMode(false);
GLsizei width= x2 - x1;
GLsizei height= y1 - y2;
GLint newX= x1;
GLint newY= (m_pQGLWidget->size().height() - y1);
GLint newY= (m_WindowVSize - y1);
if (newX < 0) newX= 0;
if (newY < 0) newY= 0;
@ -475,7 +480,7 @@ GLC_uint GLC_Viewport::meaningfulIdInsideSquare(GLint x, GLint y, GLsizei width,
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, colorId.data());
// Restore Background color
m_pQGLWidget->qglClearColor(m_BackgroundColor);
glClearColor(m_BackgroundColor.redF(), m_BackgroundColor.greenF(), m_BackgroundColor.blueF(), 1.0f);
QHash<GLC_uint, int> idHash;
QList<int> idWeight;
@ -522,7 +527,7 @@ QSet<GLC_uint> GLC_Viewport::listOfIdInsideSquare(GLint x, GLint y, GLsizei widt
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, colorId.data());
// Restore Background color
m_pQGLWidget->qglClearColor(m_BackgroundColor);
glClearColor(m_BackgroundColor.redF(), m_BackgroundColor.greenF(), m_BackgroundColor.blueF(), 1.0f);
QSet<GLC_uint> idSet;
@ -562,6 +567,11 @@ void GLC_Viewport::deleteBackGroundImage()
m_pImagePlane= NULL;
}
void GLC_Viewport::clearBackground(const QColor& color) const
{
glClearColor(color.redF(), color.greenF(), color.blueF(), 1.0f);
}
void GLC_Viewport::setToOrtho(bool useOrtho)
{
if (m_UseParallelProjection != useOrtho)
@ -580,7 +590,7 @@ void GLC_Viewport::reframe(const GLC_BoundingBox& box)
const GLC_Vector3d deltaVector(box.center() - m_pViewCam->target());
m_pViewCam->translate(deltaVector);
double cameraCover= box.boundingSphereRadius() * 2.0;
double cameraCover= box.boundingSphereRadius() * 2.2;
// Compute Camera distance
const double distance = cameraCover / m_ViewTangent;
@ -680,7 +690,7 @@ void GLC_Viewport::setDistMinAndMax(const GLC_BoundingBox& bBox)
void GLC_Viewport::setBackgroundColor(QColor setColor)
{
m_BackgroundColor= setColor;
m_pQGLWidget->qglClearColor(m_BackgroundColor);
glClearColor(m_BackgroundColor.redF(), m_BackgroundColor.greenF(), m_BackgroundColor.blueF(), 1.0f);
}
void GLC_Viewport::addClipPlane(GLenum planeGlEnum,GLC_Plane* pPlane)

View File

@ -27,6 +27,8 @@
#include <QGLWidget>
#include <QPair>
#include <QHash>
#include <QObject>
#include "glc_camera.h"
#include "glc_imageplane.h"
#include "../glc_boundingbox.h"
@ -50,8 +52,9 @@ class GLC_3DViewInstance;
* - Maximum zoom factor
*/
//////////////////////////////////////////////////////////////////////
class GLC_LIB_EXPORT GLC_Viewport
class GLC_LIB_EXPORT GLC_Viewport : public QObject
{
Q_OBJECT
//////////////////////////////////////////////////////////////////////
/*! @name Constructor / Destructor */
@ -66,7 +69,7 @@ public:
* - Angle of view : <b>35</b>
* - Maximum zoom factor : <b>3.0</b>
* */
GLC_Viewport(QGLWidget *GLWidget);
GLC_Viewport();
//! Delete Camera, Image Plane and orbit circle
virtual ~GLC_Viewport();
@ -198,10 +201,6 @@ public:
/*! The size of the given list must be a multiple of 2*/
QList<GLC_Point3d> unproject(const QList<int>&)const;
//! Return an handle of the QGLWidget of this viewport
inline QGLWidget* qGLWidgetHandle()
{return m_pQGLWidget;}
//@}
//////////////////////////////////////////////////////////////////////
@ -302,8 +301,7 @@ public:
{m_3DWidgetCollection.add(widget);}
//! Clear the background color with the specified color
inline void clearBackground(const QColor& c) const
{m_pQGLWidget->qglClearColor(c);}
void clearBackground(const QColor& color) const;
//! Set othographic usage to the given flag
void setToOrtho(bool useOrtho);
@ -327,6 +325,17 @@ public:
//@} End Zooming functions
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
//! @name Signals
//{@
signals:
//! Set the viewport's camera in order to reframe on the current scene
void updateOpenGL();
//@} End Signals
/////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// private services functions
//////////////////////////////////////////////////////////////////////
@ -365,9 +374,6 @@ private:
//! View AspectRatio
double m_AspectRatio;
//! The QGLWidget attached to the viewport (rendering context)
QGLWidget* m_pQGLWidget;
//! Viewport Background color
QColor m_BackgroundColor;