1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-01 09:24:10 +01:00

Merge remote-tracking branch 'origin/filnet/qt5.1.0' into next

Conflicts:
	ground/openpilotgcs/src/plugins/coreplugin/connectionmanager.h
	ground/openpilotgcs/src/plugins/coreplugin/workspacesettings.cpp
This commit is contained in:
Philippe Renon 2013-10-17 22:00:54 +02:00
commit 6998c782db
1140 changed files with 6439 additions and 82709 deletions

View File

@ -7,77 +7,74 @@ equals(copydata, 1) {
# Windows release only, no debug target DLLs ending with 'd'
# It is assumed that SDL.dll can be found in the same directory as mingw32-make.exe
win32:CONFIG(release, debug|release) {
win32 {
# copy Qt DLLs and phonon4
QT_DLLS = phonon4.dll \
QtCore4.dll \
QtGui4.dll \
QtNetwork4.dll \
QtOpenGL4.dll \
QtSql4.dll \
QtSvg4.dll \
QtTest4.dll \
QtXml4.dll \
QtDeclarative4.dll \
QtXmlPatterns4.dll \
QtScript4.dll
# set debug suffix if needed
CONFIG(debug, debug|release):DS = "d"
# copy Qt DLLs
QT_DLLS = Qt5Core$${DS}.dll \
Qt5Gui$${DS}.dll \
Qt5Widgets$${DS}.dll \
Qt5Network$${DS}.dll \
Qt5OpenGL$${DS}.dll \
Qt5Sql$${DS}.dll \
Qt5Svg$${DS}.dll \
Qt5Test$${DS}.dll \
Qt5Xml$${DS}.dll \
Qt5Declarative$${DS}.dll \
Qt5XmlPatterns$${DS}.dll \
Qt5Script$${DS}.dll \
Qt5Concurrent$${DS}.dll \
Qt5PrintSupport$${DS}.dll \
Qt5OpenGL$${DS}.dll \
Qt5SerialPort$${DS}.dll \
Qt5Multimedia$${DS}.dll \
Qt5MultimediaWidgets$${DS}.dll \
icuin51.dll \
icudt51.dll \
icuuc51.dll
# it is more robust to take the following DLLs from Qt rather than from MinGW
QT_DLLS += libgcc_s_dw2-1.dll \
libstdc++-6.dll \
libwinpthread-1.dll
for(dll, QT_DLLS) {
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_BINS]/$$dll\") $$targetPath(\"$$GCS_APP_PATH/$$dll\") $$addNewline()
}
# create Qt plugin directories
QT_PLUGIN_DIRS = iconengines \
imageformats \
platforms \
mediaservice \
sqldrivers
for(dir, QT_PLUGIN_DIRS) {
data_copy.commands += -@$(MKDIR) $$targetPath(\"$$GCS_APP_PATH/$$dir\") $$addNewline()
}
# copy Qt plugin DLLs
QT_PLUGIN_DLLS = iconengines/qsvgicon$${DS}.dll \
imageformats/qgif$${DS}.dll \
imageformats/qico$${DS}.dll \
imageformats/qjpeg$${DS}.dll \
imageformats/qmng$${DS}.dll \
imageformats/qsvg$${DS}.dll \
imageformats/qtiff$${DS}.dll \
platforms/qwindows$${DS}.dll \
mediaservice/dsengine$${DS}.dll \
sqldrivers/qsqlite$${DS}.dll
for(dll, QT_PLUGIN_DLLS) {
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_PLUGINS]/$$dll\") $$targetPath(\"$$GCS_APP_PATH/$$dll\") $$addNewline()
}
# copy MinGW DLLs
MINGW_DLLS = libgcc_s_dw2-1.dll \
mingwm10.dll
MINGW_DLLS = SDL.dll
for(dll, MINGW_DLLS) {
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$(QTMINGW)/$$dll\") $$targetPath(\"$$GCS_APP_PATH/$$dll\") $$addNewline()
}
# copy iconengines
QT_ICONENGINE_DLLS = qsvgicon4.dll
data_copy.commands += -@$(MKDIR) $$targetPath(\"$$GCS_APP_PATH/iconengines\") $$addNewline()
for(dll, QT_ICONENGINE_DLLS) {
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_PLUGINS]/iconengines/$$dll\") $$targetPath(\"$$GCS_APP_PATH/iconengines/$$dll\") $$addNewline()
}
# copy imageformats
QT_IMAGEFORMAT_DLLS = qgif4.dll qico4.dll qjpeg4.dll qmng4.dll qsvg4.dll qtiff4.dll
data_copy.commands += -@$(MKDIR) $$targetPath(\"$$GCS_APP_PATH/imageformats\") $$addNewline()
for(dll, QT_IMAGEFORMAT_DLLS) {
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_PLUGINS]/imageformats/$$dll\") $$targetPath(\"$$GCS_APP_PATH/imageformats/$$dll\") $$addNewline()
}
# copy phonon_backend
QT_PHONON_BACKEND_DLLS = phonon_ds94.dll
data_copy.commands += -@$(MKDIR) $$targetPath(\"$$GCS_APP_PATH/phonon_backend\") $$addNewline()
for(dll, QT_PHONON_BACKEND_DLLS) {
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_PLUGINS]/phonon_backend/$$dll\") $$targetPath(\"$$GCS_APP_PATH/phonon_backend/$$dll\") $$addNewline()
}
# copy sqldrivers
QT_SQLDRIVERS_DLLS = qsqlite4.dll
data_copy.commands += -@$(MKDIR) $$targetPath(\"$$GCS_APP_PATH/sqldrivers\") $$addNewline()
for(dll, QT_SQLDRIVERS_DLLS) {
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_PLUGINS]/sqldrivers/$$dll\") $$targetPath(\"$$GCS_APP_PATH/sqldrivers/$$dll\") $$addNewline()
}
# copy SDL - Simple DirectMedia Layer (www.libsdl.org)
# Check the wiki for SDL installation, it should be copied first
# (make sure that the Qt installation path below is correct)
#
# - For qt-sdk-win-opensource-2010.05.exe:
# xcopy /s /e <SDL>\bin\SDL.dll C:\Qt\2010.05\mingw\bin\SDL.dll
# xcopy /s /e <SDL>\include\SDL\* C:\Qt\2010.05\mingw\include\SDL
# xcopy /s /e <SDL>\lib\* C:\Qt\2010.05\mingw\lib
#
# - For Qt_SDK_Win_offline_v1_1_1_en.exe:
# xcopy /s /e <SDL>\bin\SDL.dll C:\QtSDK\Desktop\Qt\4.7.3\mingw\bin\SDL.dll
# xcopy /s /e <SDL>\include\SDL\* C:\QtSDK\Desktop\Qt\4.7.3\mingw\include\SDL
# xcopy /s /e <SDL>\lib\* C:\QtSDK\Desktop\Qt\4.7.3\mingw\lib
SDL_DLL = SDL.dll
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$(QTMINGW)/$$SDL_DLL\") $$targetPath(\"$$GCS_APP_PATH/$$SDL_DLL\") $$addNewline()
data_copy.target = FORCE
QMAKE_EXTRA_TARGETS += data_copy
}
}

View File

@ -41,7 +41,7 @@ defineReplace(stripSrcDir) {
!contains(1, ^/.*):1 = $$OUT_PWD/$$1
}
out = $$cleanPath($$1)
out ~= s|^$$re_escape($$PWD/)||$$i_flag
out ~= s|^$$re_escape($$_PRO_FILE_PWD_/)||$$i_flag
return($$out)
}
@ -133,3 +133,9 @@ linux-g++-* {
QMAKE_LFLAGS += -Wl,--allow-shlib-undefined -Wl,--no-undefined
}
win32 {
# Fix ((packed)) pragma handling issue introduced when upgrading MinGW from 4.4 to 4.8
# See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991
# The ((packet)) pragma is used in uav metadata struct and other places
QMAKE_CXXFLAGS += -mno-ms-bitfields
}

View File

@ -4,7 +4,9 @@ include(../shared/qtsingleapplication/qtsingleapplication.pri)
TEMPLATE = app
TARGET = $$GCS_APP_TARGET
DESTDIR = $$GCS_APP_PATH
QT += xml
QT += xml widgets
SOURCES += main.cpp \
gcssplashscreen.cpp

View File

@ -86,6 +86,7 @@
#include <extensionsystem/iplugin.h>
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QElapsedTimer>
#include <QtCore/QTextStream>
#include <QtCore/QFileInfo>
@ -96,10 +97,10 @@
#include <QtCore/QSettings>
#include <QtCore/QVariant>
#include <QtGui/QMessageBox>
#include <QtGui/QApplication>
#include <QtGui/QMainWindow>
#include <QtGui/QSplashScreen>
#include <QMessageBox>
#include <QtWidgets/QApplication>
#include <QMainWindow>
#include <QSplashScreen>
namespace {
typedef QList<ExtensionSystem::PluginSpec *> PluginSpecSet;
@ -208,6 +209,34 @@ inline QString msgSendArgumentFailed()
"Unable to send command line arguments to the already running instance. It appears to be not responding.");
}
void mainMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QFile file(QDir::tempPath() + "/gcs.log");
if (file.open(QIODevice::Append | QIODevice::Text)) {
QTextStream out(&file);
out << QTime::currentTime().toString("hh:mm:ss.zzz ");
switch (type) {
case QtDebugMsg:
out << "DBG: ";
break;
case QtWarningMsg:
out << "WRN: ";
break;
case QtCriticalMsg:
out << "CRT: ";
break;
case QtFatalMsg:
out << "FTL: ";
break;
}
out << msg << '\n';
out.flush();
}
}
// Prepare a remote argument: If it is a relative file, add the current directory
// since the the central instance might be running in a different directory.
inline QString prepareRemoteArgument(const QString &arg)
@ -258,6 +287,17 @@ void systemInit()
#endif
}
void logInit()
{
qInstallMessageHandler(mainMessageOutput);
QFile file(QDir::tempPath() + "/gcs.log");
if (file.exists()) {
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
// erase old log
}
}
}
inline QStringList getPluginPaths()
{
QStringList rc;
@ -415,6 +455,10 @@ int main(int argc, char * *argv)
// low level init
systemInit();
#ifdef QT_NO_DEBUG
// logInit();
#endif
// create application
SharedTools::QtSingleApplication app(APP_NAME, argc, argv);

View File

@ -8,6 +8,8 @@ unix:!macx:!freebsd*:LIBS += -ldl
DEFINES += GCS_TEST_DIR=\\\"$$GCS_SOURCE_TREE\\\"
QT += widgets
HEADERS += pluginerrorview.h \
plugindetailsview.h \
iplugin.h \

View File

@ -31,7 +31,7 @@
#include "extensionsystem_global.h"
#include <QtGui/QWidget>
#include <QWidget>
namespace ExtensionSystem {
class PluginSpec;

View File

@ -31,7 +31,7 @@
#include "extensionsystem_global.h"
#include <QtGui/QWidget>
#include <QWidget>
namespace ExtensionSystem {
class PluginSpec;

View File

@ -433,8 +433,8 @@ void PluginManager::startTests()
methods.append("arg0");
// We only want slots starting with "test"
for (int i = mo->methodOffset(); i < mo->methodCount(); ++i) {
if (QByteArray(mo->method(i).signature()).startsWith("test")) {
QString method = QString::fromLatin1(mo->method(i).signature());
if (QByteArray(mo->method(i).methodSignature()).startsWith("test")) {
QString method = QString::fromLatin1(mo->method(i).methodSignature());
methods.append(method.left(method.size() - 2));
}
}

View File

@ -33,8 +33,8 @@
#include "ui_pluginview.h"
#include <QtCore/QDir>
#include <QtGui/QHeaderView>
#include <QtGui/QTreeWidgetItem>
#include <QHeaderView>
#include <QTreeWidgetItem>
#include <QtDebug>
/*!
@ -76,9 +76,9 @@ PluginView::PluginView(PluginManager *manager, QWidget *parent)
{
m_ui->setupUi(this);
QHeaderView *header = m_ui->pluginWidget->header();
header->setResizeMode(0, QHeaderView::ResizeToContents);
header->setResizeMode(1, QHeaderView::ResizeToContents);
header->setResizeMode(2, QHeaderView::ResizeToContents);
header->setSectionResizeMode(0, QHeaderView::ResizeToContents);
header->setSectionResizeMode(1, QHeaderView::ResizeToContents);
header->setSectionResizeMode(2, QHeaderView::ResizeToContents);
m_ui->pluginWidget->sortItems(1, Qt::AscendingOrder);
p->manager = manager;
connect(p->manager, SIGNAL(pluginsChanged()), this, SLOT(updateList()));

View File

@ -31,7 +31,7 @@
#include "extensionsystem_global.h"
#include <QtGui/QWidget>
#include <QWidget>
QT_BEGIN_NAMESPACE
class QTreeWidgetItem;

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

@ -1,18 +1,14 @@
TEMPLATE = lib
TARGET = GLC_lib
#VERSION = 2.2.0
DEFINES += GLC_LIB_LIBRARY
include(../../openpilotgcslibrary.pri)
# GLC_lib qmake configuration
#TEMPLATE = lib
QT += opengl \
core
QT += core opengl
CONFIG += exceptions \
warn_on
#TARGET = GLC_lib
#VERSION = 2.2.0
# disable all warnings (no need for warnings as glc sources are imported)
CONFIG += exceptions warn_off
DEFINES += CREATE_GLC_LIB_DLL
DEFINES += LIB3DS_EXPORTS
@ -82,6 +78,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 +119,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 +237,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 +275,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 +284,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 +418,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 +438,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;

View File

@ -1,7 +0,0 @@
Arvid Picciani <aep@libqxt.org>
Adam Higerd <ahigerd@libqxt.org>
J-P Nurmi <jpnurmi@libqxt.org>
Benjamin Zeller <zbenjamin@libqxt.org>
Thomas Mueller <deepdiver@libqxt.org>
thanks for all the minor contributions, bug reports, beta tests, and the free beer :-)

View File

@ -1,89 +0,0 @@
Qt Extension Library
Copyright (C) 2007 Qxt Foundation
------------------- Disclaimer ------------------------------------------------
Until the Qxt Foundation is legally established, copyright for the
source code falls back to the original contributor. For information about the
status of the Qxt Foundation, or about the copyright status of any part of Qxt,
contact the Qxt project maintainers at <foundation@libqxt.org>
Once the Qxt Foundation has been legally established, all contributors must
transfer all copyright interest to the Qxt Foundation before their submissions
will be added to the project.
------------------- License ---------------------------------------------------
This library is free software; you can redistribute it and/or modify it
under the terms of the Common Public License, version 1.0, as published by IBM
or under the terms of the GNU Lesser General Public License, version 2.1,
as published by the Free Software Foundation
This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
FITNESS FOR A PARTICULAR PURPOSE.
You should have received a copy of the CPL along with this file.
See the LICENSE file and the cpl1.0.txt file included with the source
distribution for more information. If you did not receive a copy of the
license, contact the Qxt Foundation.
You should have received a copy of the LGPL along with this file.
See the LICENSE file and the lgpl-2.1.txt file included with the source
distribution for more information. If you did not receive a copy of the
license, contact the Qxt Foundation.
Parts of Qxt depend on Qt 4 and/or other libraries that have their own
licenses. Qxt is independent of these licenses; however, use of these other
libraries is subject to their respective license agreements.
------------------- Intent ----------------------------------------------------
The following section describes the opinions and intent of the Qxt Foundation
with regards to the licensing and use of the Qxt source code and library. In
the event that the CPL is found to be illegal or invalid, or if any application
or clause of the license is subjected to question or abuse, this section is a
general statement of the desired interpretation.
This section has no legal standing and the statements made here are strictly
subject to the text of the CPL; that is, if this section and the CPL are in
disagreement, the text of the CPL takes precedence. In no way does this
intent grant you any additional rights or impose any additional restrictions.
If you have questions about licensing, contact the maintainers.
Qxt is built and supported by open-source enthusiasts.
- Please respect the open-source background of the contributors. The code is
provided for everyone's use; you may not restrict the rights of anyone to
use it.
- No individual may claim ownership of any part of the code. It belongs
to the community.
- You may modify the source code to suit your needs, but these changes
must be made free. If you distribute a modified form of Qxt, you must
also distribute the entire source code of the modified form.
- Digital Rights Management (DRM) puts unfair, unfree restrictions on
users and developers. It is the opposite of Free Software. We can't
stop you from using it, but please don't use the Qxt name for software
restricted by DRM.
- Please respect the time and effort put into the project by the developers.
- If you find Qxt useful, it would be appreciated if you would include
text in your application (for instance, in the About dialog) giving
acknowledgement to Qxt.
- If you make modifications to the source code, you must not call the
modified version "Qxt." It's okay to include "Qxt" in the name, but
anyone who receives the modified version needs to know that it's not
the same as the version distributed by the Qxt Foundation.
- We want everyone to be able to use Qxt without restrictions.
- If you distribute Qxt in compiled binary form, please ensure that
everyone who receives it can get the source code used to create it.
- You are free to use Qxt in closed-source applications as long as you
distribute Qxt in an open-source fashion. This does not require you
to make your entire application open-source.
- The Qxt Foundation is a non-profit, non-political organization.
- Please don't use the Qxt name in any political or semi-political
propaganda or publication. We don't like it.
- Qxt is distributed "as-is," with no warranty.
- If it makes your program crash, your computer blow up, or tiny demons
fly out of your nose, please don't sue us.

View File

@ -1,39 +0,0 @@
1) configure
make sure qmake is in your PATH and run ./configure or configure.bat on windows.
see configure --help for more information
(for msvc you could try ./configure.bat -msvc and open
the solution file in msvc, we recomend compiling on
commandline though)
2) build
type make or nmake when using msvc
then don't forget to make install
Note: This will also install qxt.prf to your qtdir/mkspecs/features directory.
3) use
Add the following lines to your qmake project file:
CONFIG += qxt
QXT += core gui
The QXT variable should contain the modules you want. (In this example core and gui are used.)
Note: Some modules depend on other modules. The required modules are added automatically.
if you have an existing msvc project and can't swtich to qmake you can use zbenjamins solution:
Howto use libqxt in a existing Visual Studio Project:
1. create and install libqxt. (See install instructions)
2. add {libqxtinstalldir}\include\qxt\QxtCore to your include path
3. add {libqxtinstalldir}\lib to your library search path
4. to add a specific libqxt module (f.e QxtSql) you have to:
- add {libqxtinstalldir}\include\qxt\QxtSql to your include path
- add the library QxtSql.lib to your project
Most of the times you have also to include the QxtCore and QxtKit modules.
It's done the same way like the example above.

View File

@ -1,213 +0,0 @@
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC
LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
1. DEFINITIONS
"Contribution" means:
a) in the case of the initial Contributor, the initial code and
documentation distributed under this Agreement, and
b) in the case of each subsequent Contributor:
i) changes to the Program, and
ii) additions to the Program;
where such changes and/or additions to the Program originate from and are
distributed by that particular Contributor. A Contribution 'originates' from a
Contributor if it was added to the Program by such Contributor itself or anyone
acting on such Contributor's behalf. Contributions do not include additions to
the Program which: (i) are separate modules of software distributed in
conjunction with the Program under their own license agreement, and (ii) are not
derivative works of the Program.
"Contributor" means any person or entity that distributes the Program.
"Licensed Patents " mean patent claims licensable by a Contributor which are
necessarily infringed by the use or sale of its Contribution alone or when
combined with the Program.
"Program" means the Contributions distributed in accordance with this Agreement.
"Recipient" means anyone who receives the Program under this Agreement,
including all Contributors.
2. GRANT OF RIGHTS
a) Subject to the terms of this Agreement, each Contributor hereby grants
Recipient a non-exclusive, worldwide, royalty-free copyright license to
reproduce, prepare derivative works of, publicly display, publicly perform,
distribute and sublicense the Contribution of such Contributor, if any, and such
derivative works, in source code and object code form.
b) Subject to the terms of this Agreement, each Contributor hereby grants
Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed
Patents to make, use, sell, offer to sell, import and otherwise transfer the
Contribution of such Contributor, if any, in source code and object code form.
This patent license shall apply to the combination of the Contribution and the
Program if, at the time the Contribution is added by the Contributor, such
addition of the Contribution causes such combination to be covered by the
Licensed Patents. The patent license shall not apply to any other combinations
which include the Contribution. No hardware per se is licensed hereunder.
c) Recipient understands that although each Contributor grants the licenses
to its Contributions set forth herein, no assurances are provided by any
Contributor that the Program does not infringe the patent or other intellectual
property rights of any other entity. Each Contributor disclaims any liability to
Recipient for claims brought by any other entity based on infringement of
intellectual property rights or otherwise. As a condition to exercising the
rights and licenses granted hereunder, each Recipient hereby assumes sole
responsibility to secure any other intellectual property rights needed, if any.
For example, if a third party patent license is required to allow Recipient to
distribute the Program, it is Recipient's responsibility to acquire that license
before distributing the Program.
d) Each Contributor represents that to its knowledge it has sufficient
copyright rights in its Contribution, if any, to grant the copyright license set
forth in this Agreement.
3. REQUIREMENTS
A Contributor may choose to distribute the Program in object code form under its
own license agreement, provided that:
a) it complies with the terms and conditions of this Agreement; and
b) its license agreement:
i) effectively disclaims on behalf of all Contributors all warranties and
conditions, express and implied, including warranties or conditions of title and
non-infringement, and implied warranties or conditions of merchantability and
fitness for a particular purpose;
ii) effectively excludes on behalf of all Contributors all liability for
damages, including direct, indirect, special, incidental and consequential
damages, such as lost profits;
iii) states that any provisions which differ from this Agreement are offered
by that Contributor alone and not by any other party; and
iv) states that source code for the Program is available from such
Contributor, and informs licensees how to obtain it in a reasonable manner on or
through a medium customarily used for software exchange.
When the Program is made available in source code form:
a) it must be made available under this Agreement; and
b) a copy of this Agreement must be included with each copy of the Program.
Contributors may not remove or alter any copyright notices contained within the
Program.
Each Contributor must identify itself as the originator of its Contribution, if
any, in a manner that reasonably allows subsequent Recipients to identify the
originator of the Contribution.
4. COMMERCIAL DISTRIBUTION
Commercial distributors of software may accept certain responsibilities with
respect to end users, business partners and the like. While this license is
intended to facilitate the commercial use of the Program, the Contributor who
includes the Program in a commercial product offering should do so in a manner
which does not create potential liability for other Contributors. Therefore, if
a Contributor includes the Program in a commercial product offering, such
Contributor ("Commercial Contributor") hereby agrees to defend and indemnify
every other Contributor ("Indemnified Contributor") against any losses, damages
and costs (collectively "Losses") arising from claims, lawsuits and other legal
actions brought by a third party against the Indemnified Contributor to the
extent caused by the acts or omissions of such Commercial Contributor in
connection with its distribution of the Program in a commercial product
offering. The obligations in this section do not apply to any claims or Losses
relating to any actual or alleged intellectual property infringement. In order
to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
Contributor in writing of such claim, and b) allow the Commercial Contributor to
control, and cooperate with the Commercial Contributor in, the defense and any
related settlement negotiations. The Indemnified Contributor may participate in
any such claim at its own expense.
For example, a Contributor might include the Program in a commercial product
offering, Product X. That Contributor is then a Commercial Contributor. If that
Commercial Contributor then makes performance claims, or offers warranties
related to Product X, those performance claims and warranties are such
Commercial Contributor's responsibility alone. Under this section, the
Commercial Contributor would have to defend claims against the other
Contributors related to those performance claims and warranties, and if a court
requires any other Contributor to pay any damages as a result, the Commercial
Contributor must pay those damages.
5. NO WARRANTY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each
Recipient is solely responsible for determining the appropriateness of using and
distributing the Program and assumes all risks associated with its exercise of
rights under this Agreement, including but not limited to the risks and costs of
program errors, compliance with applicable laws, damage to or loss of data,
programs or equipment, and unavailability or interruption of operations.
6. DISCLAIMER OF LIABILITY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST
PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS
GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
7. GENERAL
If any provision of this Agreement is invalid or unenforceable under applicable
law, it shall not affect the validity or enforceability of the remainder of the
terms of this Agreement, and without further action by the parties hereto, such
provision shall be reformed to the minimum extent necessary to make such
provision valid and enforceable.
If Recipient institutes patent litigation against a Contributor with respect to
a patent applicable to software (including a cross-claim or counterclaim in a
lawsuit), then any patent licenses granted by that Contributor to such Recipient
under this Agreement shall terminate as of the date such litigation is filed. In
addition, if Recipient institutes patent litigation against any entity
(including a cross-claim or counterclaim in a lawsuit) alleging that the Program
itself (excluding combinations of the Program with other software or hardware)
infringes such Recipient's patent(s), then such Recipient's rights granted under
Section 2(b) shall terminate as of the date such litigation is filed.
All Recipient's rights under this Agreement shall terminate if it fails to
comply with any of the material terms or conditions of this Agreement and does
not cure such failure in a reasonable period of time after becoming aware of
such noncompliance. If all Recipient's rights under this Agreement terminate,
Recipient agrees to cease use and distribution of the Program as soon as
reasonably practicable. However, Recipient's obligations under this Agreement
and any licenses granted by Recipient relating to the Program shall continue and
survive.
Everyone is permitted to copy and distribute copies of this Agreement, but in
order to avoid inconsistency the Agreement is copyrighted and may only be
modified in the following manner. The Agreement Steward reserves the right to
publish new versions (including revisions) of this Agreement from time to time.
No one other than the Agreement Steward has the right to modify this Agreement.
IBM is the initial Agreement Steward. IBM may assign the responsibility to serve
as the Agreement Steward to a suitable separate entity. Each new version of the
Agreement will be given a distinguishing version number. The Program (including
Contributions) may always be distributed subject to the version of the Agreement
under which it was received. In addition, after a new version of the Agreement
is published, Contributor may elect to distribute the Program (including its
Contributions) under the new version. Except as expressly stated in Sections
2(a) and 2(b) above, Recipient receives no rights or licenses to the
intellectual property of any Contributor under this Agreement, whether
expressly, by implication, estoppel or otherwise. All rights in the Program not
expressly granted under this Agreement are reserved.
This Agreement is governed by the laws of the State of New York and the
intellectual property laws of the United States of America. No party to this
Agreement will bring a legal action under this Agreement more than one year
after the cause of action arose. Each party waives its rights to a jury trial in
any resulting litigation.

View File

@ -1,504 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library 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 2.1 of the License, or (at your option) any later version.
This library 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 this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@ -1,7 +0,0 @@
LIBS *= -l$$qtLibraryName(QxtCore)
INCLUDEPATH += \
$$GCS_SOURCE_TREE/src/libs/libqxt/src/core
INCLUDEPATH += \
$$GCS_SOURCE_TREE/src/libs/libqxt/src/core/logengines

View File

@ -1,66 +0,0 @@
#
# Qxt main project file
#
#
TEMPLATE = subdirs
QXT_MODULES = core
contains( QXT_MODULES, core ){
message( building core module )
sub_core.subdir = src/core
SUBDIRS += sub_core
}
contains( QXT_MODULES, gui ){
message( building gui module )
sub_gui.subdir = src/gui
sub_gui.depends = sub_core
SUBDIRS += sub_gui
contains( QXT_MODULES, designer ){
sub_designer.subdir = src/designer
sub_designer.depends = sub_core sub_gui
SUBDIRS += sub_designer
}
}
contains( QXT_MODULES, network ){
message( building network module )
sub_network.subdir = src/network
sub_network.depends = sub_core
SUBDIRS += sub_network
}
contains( QXT_MODULES, sql ){
message( building sql module )
sub_sql.subdir = src/sql
sub_sql.depends = sub_core
SUBDIRS += sub_sql
}
contains(DEFINES,HAVE_DB){
contains( QXT_MODULES, berkeley ){
message( building berkeley module )
sub_berkeley.subdir = src/berkeley
sub_berkeley.depends = sub_core
SUBDIRS += sub_berkeley
}
}
contains(DEFINES,HAVE_ZEROCONF){
contains( QXT_MODULES, zeroconf ){
message( building zeroconf module )
sub_zeroconf.subdir = src/zeroconf
sub_zeroconf.depends = sub_network
SUBDIRS += sub_zeroconf
}
}
contains( QXT_MODULES, web ){
message( building web module )
sub_web.subdir = src/web
sub_web.depends = sub_core sub_network
SUBDIRS += sub_web
}

View File

@ -1,11 +0,0 @@
INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD
HEADERS += qxtberkeley.h
HEADERS += qxtbdb.h
HEADERS += qxtbdbhash.h
HEADERS += qxtbdbtree.h
SOURCES += qxtbdb.cpp
SOURCES += qxtbdbhash.cpp
SOURCES += qxtbdbtree.cpp

View File

@ -1,10 +0,0 @@
CLEAN_TARGET = QxtBerkeley
DEFINES += BUILD_QXT_BERKELEY
QT = core
QXT = core
CONVENIENCE += $$CLEAN_TARGET
include(berkeley.pri)
#include(../qxtbase.pri)
!win32:LIBS += -ldb

View File

@ -1,377 +0,0 @@
/****************************************************************************
**
** Copyright (C) Qxt Foundation. Some rights reserved.
**
** This file is part of the QxtBerkeley module of the Qxt library.
**
** This library is free software; you can redistribute it and/or modify it
** under the terms of the Common Public License, version 1.0, as published
** by IBM, and/or under the terms of the GNU Lesser General Public License,
** version 2.1, as published by the Free Software Foundation.
**
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
** FITNESS FOR A PARTICULAR PURPOSE.
**
** You should have received a copy of the CPL and the LGPL along with this
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
** included with the source distribution for more information.
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
**
** <http://libqxt.org> <foundation@libqxt.org>
**
****************************************************************************/
#include "qxtbdb.h"
#include <QFileInfo>
#include <QBuffer>
#include <QDataStream>
#include <QVariant>
static void qxtBDBDatabaseErrorHandler(const BerkeleyDB::DB_ENV*, const char* a, const char* b)
{
qDebug("QxtBDBDatabase: %s, %s", a, b);
}
QxtBdb::QxtBdb()
{
isOpen = false;
if (db_create(&db, NULL, 0) != 0)
qFatal("db_create failed");
db->set_errcall(db, qxtBDBDatabaseErrorHandler);
}
QxtBdb::~QxtBdb()
{
db->close(db, 0);
}
bool QxtBdb::open(QString path, OpenFlags f)
{
Q_ASSERT(!isOpen);
if (QFileInfo(path).exists())
{
BerkeleyDB::DB * tdb;
if (db_create(&tdb, NULL, 0) != 0)
qFatal("db_create failed");
if (tdb->verify(tdb, qPrintable(path), NULL, NULL, 0) == DB_VERIFY_BAD)
qCritical("QxtBdb::open Database '%s' is corrupted.", qPrintable(path));
}
int flags = 0;
if (f&CreateDatabase)
flags |= DB_CREATE;
if (f&ReadOnly)
flags |= DB_RDONLY;
if (f&LockFree)
flags |= DB_THREAD;
isOpen = (db->open(db, /* DB structure pointer */
NULL, /* Transaction pointer */
qPrintable(path), /* On-disk file that holds the database. */
NULL, /* Optional logical database name */
BerkeleyDB::DB_BTREE, /* Database access method */
flags, /* Open flags */
0)
== 0);
return isOpen;
}
QxtBdb::OpenFlags QxtBdb::openFlags()
{
if (!isOpen)
return 0;
OpenFlags f;
BerkeleyDB::u_int32_t open_flags;
db->get_open_flags(db, &open_flags);
if (open_flags&DB_CREATE)
f |= CreateDatabase;
if (open_flags&DB_RDONLY)
f |= ReadOnly;
if (open_flags&DB_THREAD)
f |= LockFree;
return f;
}
bool QxtBdb::flush()
{
if (!isOpen)
return false;
return (db->sync(db, 0) == 0);
}
/*!
low level get function.
serialised key and value with the given meta ids.
always reads <b>and</b> writes both key and value, if given.
use this when doing operations that require the key to be read out of the db.
*/
bool QxtBdb::get(void* key, int keytype, void* value, int valuetype, BerkeleyDB::u_int32_t flags, BerkeleyDB::DBC * cursor) const
{
BerkeleyDB::DBT dbkey, dbvalue;
::memset(&dbkey, 0, sizeof(BerkeleyDB::DBT));
::memset(&dbvalue, 0, sizeof(BerkeleyDB::DBT));
if (key)
{
QByteArray d_key;
QBuffer buffer(&d_key);
buffer.open(QIODevice::WriteOnly);
QDataStream s(&buffer);
if (!QMetaType::save(s, keytype, key))
qCritical("QMetaType::save failed. is your key registered with the QMetaType?");
buffer.close();
dbkey.size = d_key.size();
dbkey.data = ::malloc(d_key.size());
::memcpy(dbkey.data, d_key.data(), d_key.size());
}
if (value)
{
QByteArray d_value;
QBuffer buffer(&d_value);
buffer.open(QIODevice::WriteOnly);
QDataStream s(&buffer);
if (!QMetaType::save(s, valuetype, value))
qCritical("QMetaType::save failed. is your value registered with the QMetaType?");
buffer.close();
dbvalue.size = d_value.size();
dbvalue.data = ::malloc(d_value.size());
::memcpy(dbvalue.data, d_value.data(), d_value.size());
}
dbvalue.ulen = 0;
dbvalue.flags = DB_DBT_USERMEM;
dbkey.ulen = 0;
dbkey.flags = DB_DBT_USERMEM;
int ret;
if (cursor)
ret = cursor->c_get(cursor, &dbkey, &dbvalue, flags);
else
ret = db->get(db, NULL, &dbkey, &dbvalue, flags);
if (ret != DB_BUFFER_SMALL)
{
::free(dbvalue.data);
::free(dbkey.data);
return (ret == 0);
}
dbvalue.ulen = dbvalue.size;
dbvalue.data =::malloc(dbvalue.size);
dbkey.ulen = dbkey.size;
dbkey.data =::malloc(dbkey.size);
if (cursor)
ret = cursor->c_get(cursor, &dbkey, &dbvalue, flags);
else
ret = db->get(db, NULL, &dbkey, &dbvalue, flags);
QByteArray d_value = QByteArray::fromRawData((const char*) dbvalue.data, dbvalue.size);
QByteArray d_key = QByteArray::fromRawData((const char*) dbkey.data, dbkey.size);
if (ret != 0)
{
::free(dbvalue.data);
::free(dbkey.data);
return false;
}
if (key)
{
QBuffer buffer(&d_key);
buffer.open(QIODevice::ReadOnly);
QDataStream s(&buffer);
if (!QMetaType::load(s, keytype, key))
qCritical("QMetaType::load failed. is your key registered with the QMetaType?");
buffer.close();
}
if (value)
{
QBuffer buffer(&d_value);
buffer.open(QIODevice::ReadOnly);
QDataStream s(&buffer);
if (!QMetaType::load(s, valuetype, value))
qCritical("QMetaType::load failed. is your value registered with the QMetaType?");
buffer.close();
}
::free(dbvalue.data);
::free(dbkey.data);
return true;
}
/*!
low level get function.
serialised key and value with the given meta ids.
doesn't write to the key. use this when doing operations that require the key to be passed.
*/
bool QxtBdb::get(const void* key, int keytype, void* value, int valuetype, BerkeleyDB::u_int32_t flags, BerkeleyDB::DBC * cursor) const
{
BerkeleyDB::DBT dbkey, dbvalue;
memset(&dbkey, 0, sizeof(BerkeleyDB::DBT));
memset(&dbvalue, 0, sizeof(BerkeleyDB::DBT));
if (key)
{
QByteArray d_key;
QBuffer buffer(&d_key);
buffer.open(QIODevice::WriteOnly);
QDataStream s(&buffer);
if (!QMetaType::save(s, keytype, key))
qCritical("QMetaType::save failed. is your key registered with the QMetaType?");
buffer.close();
dbkey.size = d_key.size();
dbkey.data = ::malloc(d_key.size());
::memcpy(dbkey.data, d_key.data(), d_key.size());
}
if (value)
{
QByteArray d_value;
QBuffer buffer(&d_value);
buffer.open(QIODevice::WriteOnly);
QDataStream s(&buffer);
if (!QMetaType::save(s, valuetype, value))
qCritical("QMetaType::save failed. is your value registered with the QMetaType?");
buffer.close();
dbvalue.size = d_value.size();
dbvalue.data = ::malloc(d_value.size());
::memcpy(dbvalue.data, d_value.data(), d_value.size());
}
dbvalue.ulen = 0;
dbvalue.flags = DB_DBT_USERMEM;
dbkey.ulen = 0;
dbkey.flags = 0;
dbkey.flags = DB_DBT_USERMEM; //it's my memory, ffs. stop deleting it! >_<
int ret;
if (cursor)
ret = cursor->c_get(cursor, &dbkey, &dbvalue, flags);
else
ret = db->get(db, NULL, &dbkey, &dbvalue, flags);
if (ret != DB_BUFFER_SMALL)
{
::free(dbvalue.data);
::free(dbkey.data);
return (ret == 0);
}
dbvalue.ulen = dbvalue.size;
dbvalue.data =::malloc(dbvalue.size);
if (cursor)
ret = cursor->c_get(cursor, &dbkey, &dbvalue, flags);
else
ret = db->get(db, NULL, &dbkey, &dbvalue, flags);
QByteArray d_value((const char*) dbvalue.data, dbvalue.size);
QByteArray d_key((const char*) dbkey.data, dbkey.size);
::free(dbvalue.data);
::free(dbkey.data);
Q_ASSERT_X(ret != DB_BUFFER_SMALL, Q_FUNC_INFO, "QxtBdb::get bdb inists on retriving the key for this operation. You need to specify a non const key. (or just specify a non const void* with the value of 0, i'll delete the key for you after bdb fetched it, so you don't need to bother)");
if (ret != 0)
{
return false;
}
if (value)
{
QBuffer buffer(&d_value);
buffer.open(QIODevice::ReadOnly);
QDataStream s(&buffer);
if (!QMetaType::load(s, valuetype, value))
qCritical("QMetaType::load failed. is your value registered with the QMetaType?");
buffer.close();
}
return true;
}
QString QxtBdb::dbErrorCodeToString(int e)
{
switch (e)
{
case DB_LOCK_DEADLOCK:
return QString("Dead locked (%1)").arg(e);
case DB_SECONDARY_BAD:
return QString("Bad Secondary index (%1)").arg(e);
case DB_RUNRECOVERY:
return QString("Database corrupted. Run Recovery. (%1)").arg(e);
default:
return QString("Unknown error %1").arg(e);
};
}

View File

@ -1,171 +0,0 @@
/****************************************************************************
**
** Copyright (C) Qxt Foundation. Some rights reserved.
**
** This file is part of the QxtBerkeley module of the Qxt library.
**
** This library is free software; you can redistribute it and/or modify it
** under the terms of the Common Public License, version 1.0, as published
** by IBM, and/or under the terms of the GNU Lesser General Public License,
** version 2.1, as published by the Free Software Foundation.
**
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
** FITNESS FOR A PARTICULAR PURPOSE.
**
** You should have received a copy of the CPL and the LGPL along with this
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
** included with the source distribution for more information.
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
**
** <http://libqxt.org> <foundation@libqxt.org>
**
****************************************************************************/
/**************************************************************************
This is private API. it might change at any time without warning.
****************************************************************************/
#ifndef QxtBdb_H_kpasd
#define QxtBdb_H_kpasd
#include <QFlags>
#include <QBuffer>
#include <QDataStream>
#include <QMetaType>
#include <QString>
#include <qxtglobal.h>
#include <cstdlib>
#include <cstdio>
///its impossible to forward anyway,
namespace BerkeleyDB
{
extern "C"
{
#include <db.h>
}
/// aparantly MSVC and GCC have different understanding of what goes into a namespace and what not.
#ifndef Q_CC_MSVC
typedef quint32 u_int32_t;
#endif
}
class QXT_BERKELEY_EXPORT QxtBdb
{
public:
enum OpenFlag
{
CreateDatabase = 0x1,
ReadOnly = 0x2,
LockFree = 0x4
};
Q_DECLARE_FLAGS(OpenFlags, OpenFlag);
QxtBdb();
~QxtBdb();
bool get(void* key, int keytype, void* value, int valuetype, BerkeleyDB::u_int32_t flags = NULL, BerkeleyDB::DBC * cursor = 0) const ;
bool get(const void* key, int keytype, void* value, int valuetype, BerkeleyDB::u_int32_t flags = NULL, BerkeleyDB::DBC * cursor = 0) const ;
bool open(QString path, OpenFlags f = 0);
OpenFlags openFlags();
bool flush();
BerkeleyDB::DB * db;
bool isOpen;
static QString dbErrorCodeToString(int e);
template<class T>
static T qxtMetaLoad(const void * data, size_t size)
{
T t;
QByteArray b = QByteArray::fromRawData((const char*)data, size);
QBuffer buffer(&b);
buffer.open(QIODevice::ReadOnly);
QDataStream s(&buffer);
if (!QMetaType::load(s, qMetaTypeId<T>(), &t))
qCritical("QMetaType::load failed. is your type registered with the QMetaType?");
buffer.close();
return t;
}
static void * qxtMetaLoad(const void * data, size_t size, int type)
{
void *p = QMetaType::construct(type);
QByteArray b = QByteArray::fromRawData(static_cast<const char*>(data), size);
QBuffer buffer(&b);
buffer.open(QIODevice::ReadOnly);
QDataStream s(&buffer);
if (!QMetaType::load(s, type, p))
qCritical("QMetaType::load failed. is your type registered with the QMetaType?");
buffer.close();
return p;
}
template<class T>
static QByteArray qxtMetaSave(const T & t)
{
QByteArray d;
QBuffer buffer(&d);
buffer.open(QIODevice::WriteOnly);
QDataStream s(&buffer);
if (!QMetaType::save(s, qMetaTypeId<T>(), &t))
qCritical("QMetaType::save failed. is your type registered with the QMetaType?");
buffer.close();
return d;
}
static void * qxtMetaSave(size_t * size, void * t, int type)
{
QByteArray d;
QBuffer buffer(&d);
buffer.open(QIODevice::WriteOnly);
QDataStream s(&buffer);
if (!QMetaType::save(s, type, t))
qCritical("QMetaType::save failed. is your type registered with the QMetaType?");
buffer.close();
*size = d.size();
void *p = ::malloc(d.size());
::memcpy(p, d.data(), d.size());
return p;
}
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QxtBdb::OpenFlags);
#endif

View File

@ -1,264 +0,0 @@
/****************************************************************************
**
** Copyright (C) Qxt Foundation. Some rights reserved.
**
** This file is part of the QxtBerkeley module of the Qxt library.
**
** This library is free software; you can redistribute it and/or modify it
** under the terms of the Common Public License, version 1.0, as published
** by IBM, and/or under the terms of the GNU Lesser General Public License,
** version 2.1, as published by the Free Software Foundation.
**
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
** FITNESS FOR A PARTICULAR PURPOSE.
**
** You should have received a copy of the CPL and the LGPL along with this
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
** included with the source distribution for more information.
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
**
** <http://libqxt.org> <foundation@libqxt.org>
**
****************************************************************************/
#include "qxtbdbhash.h"
/*!
\class QxtBdbHash
\inmodule QxtBerkeley
\brief The QxtBdbHash class is a template class that provides key/value access to a berkeley db file.
Both value and key must be registered with the qt meta system.
You may not touch the file while a QxtBdbHash instance is running on it.
examples usage:
\code
QxtBdbHash<qreal,QStringList> db("test.db");
db.insert(344.4,QStringList<<"HI"<<":)");
qDebug()<<db[344.4];
\endcode
There is an extensive example in /examples/berkeley/adressbook.
All functions of this class are thread safe.
Calling open() multiple times is undefined.
An iterator may only be used from one thread at once, but you can have multiple iterators.
TODO: {implicitshared}
\sa QxtBdbHashIterator
*/
/*!
\fn void QxtBdbHash::QxtBdbHash()
Constructs an invalid QxtBdbHash
*/
/*!
\fn void QxtBdbHash::QxtBdbHash(QString file)
Constructs a QxtBdbHash, and opens the \a file specified as its database.
*/
/*!
\fn bool QxtBdbHash::open(QString file)
Opens the specified \a file.
Returns \c true on success and \c false on failure.
\bold {Note:} A sanity check is performed before opening the file.
*/
/*!
\fn void QxtBdbHash::clear()
Erase all records. This does not delete the underlying file.
*/
/*!
\fn QxtBdbHashIterator<KEY,VAL> QxtBdbHash::begin()
Returns an iterator to the first key,value pair.
\sa QxtBdbHashIterator
*/
/*!
\fn QxtBdbHashIterator<KEY,VAL> QxtBdbHash::end()
Return an iterator to the last key,value pair
\sa QxtBdbHashIterator
*/
/*!
\fn QxtBdbHashIterator<KEY,VAL> QxtBdbHash::find ( const KEY & key )
Returns an iterator to the position of the pair identified by \a key
\sa QxtBdbHashIterator
*/
/*!
\fn bool QxtBdbHash::contains ( const KEY & key ) const
Returns \c true if there is a record for the specified \a key.
*/
/*!
\fn bool QxtBdbHash::remove ( const KEY & key )
Removes all records with the specified \a key. Returns \c true on success and \c false on failure.
*/
/*!
\fn bool QxtBdbHash::insert( KEY key, VAL value )
Inserts a record with the specified \a key / \a value combination. Replaces any record with the same key.
\bold {Note:} When working with iterators, keep in mind that inserting pairs, works reverse to the iteration.
*/
/*!
\fn const VAL QxtBdbHash::value( const KEY & key ) const
Returns the value associated with the specified \a key, or a default contructed value, if no such key exists.
*/
/*!
\fn const VAL QxtBdbHash::operator[] ( const KEY & key ) const
Same as value()
*/
/*!
\fn bool QxtBdbHash::flush()
Flushes the underlying DB file. All changes are synced to disk.
*/
/*!
\class QxtBdbHashIterator
\inmodule QxtBerkeley
\brief The QxtBdbHashIterator class provides a fast iterator over a QxtBdbHash
\sa QxtBdbHash
TODO: {implicitshared}
*/
/*!
\fn void QxtBdbHashIterator<KEY,VAL>::QxtBdbHashIterator()
Constructs an invalid QxtBdbHashIterator
*/
/*!
\fn QxtBdbHashIterator<KEY,VAL>::QxtBdbHashIterator(const QxtBdbHashIterator<KEY,VAL> & other)
Copy constructor
*/
/*!
\fn QxtBdbHashIterator<KEY,VAL> & QxtBdbHashIterator<KEY,VAL>::operator= ( const QxtBdbHashIterator<KEY,VAL> & other )
Assignment operator
*/
/*!
\fn bool QxtBdbHashIterator<KEY,VAL>::isValid() const
Returns \c true if the iterator is valid.
Invalid iterators are unusable and accessing any function will fail.
*/
/*!
\fn QxtBdbHashIterator<KEY,VAL>::operator KEY() const
Convertion operator to the current value.
\sa key()
*/
/*!
\fn KEY QxtBdbHashIterator<KEY,VAL>::key() const
Returns the current key.
\sa value()
*/
/*!
\fn VAL QxtBdbHashIterator<KEY,VAL>::value() const
Returns the current value.
\sa key()
*/
/*!
\fn QxtBdbHashIterator<KEY,VAL> QxtBdbHashIterator<KEY,VAL>::operator + ( int j ) const
Returns an iterator to the item at \a j positions forward from this iterator.
*/
/*!
\fn QxtBdbHashIterator<KEY,VAL> & QxtBdbHashIterator<KEY,VAL>::operator ++ ()
The prefix ++ operator (++i) advances the iterator to the next item in the hash and returns an iterator to the new current item.
*/
/*!
\fn QxtBdbHashIterator<KEY,VAL> QxtBdbHashIterator<KEY,VAL>::operator ++ (int)
The postfix ++ operator (i++) advances the iterator to the next item in the hash and returns an iterator to the previously current item.
*/
/*!
\fn QxtBdbHashIterator<KEY,VAL> & QxtBdbHashIterator<KEY,VAL>::operator += ( int j )
Advances the iterator by \a j items.
*/
/*!
\fn QxtBdbHashIterator<KEY,VAL> QxtBdbHashIterator<KEY,VAL>::operator - ( int j ) const
Returns an iterator to the item at \a j positions backward from this iterator.
*/
/*!
\fn QxtBdbHashIterator<KEY,VAL> & QxtBdbHashIterator<KEY,VAL>::operator -- ()
The prefix -- operator (--i) makes the preceding item current and returns an iterator pointing to the new current item.
*/
/*!
\fn QxtBdbHashIterator<KEY,VAL> QxtBdbHashIterator<KEY,VAL>::operator -- (int)
The postfix -- operator (i--) makes the preceding item current and returns an iterator pointing to the previously current item.
*/
/*!
\fn QxtBdbHashIterator<KEY,VAL> & QxtBdbHashIterator<KEY,VAL>::operator -= ( int j )
Makes the iterator go back by \a j items.
*/
/*!
\fn QxtBdbHashIterator<KEY,VAL> QxtBdbHashIterator<KEY,VAL>::erase ()
Removes the (key, value) pair associated with the iterator from the hash, and returns an iterator to the next item in the hash.
This instance is invalid then, and cannot be used further.
*/

View File

@ -1,577 +0,0 @@
/****************************************************************************
**
** Copyright (C) Qxt Foundation. Some rights reserved.
**
** This file is part of the QxtBerkeley module of the Qxt library.
**
** This library is free software; you can redistribute it and/or modify it
** under the terms of the Common Public License, version 1.0, as published
** by IBM, and/or under the terms of the GNU Lesser General Public License,
** version 2.1, as published by the Free Software Foundation.
**
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
** FITNESS FOR A PARTICULAR PURPOSE.
**
** You should have received a copy of the CPL and the LGPL along with this
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
** included with the source distribution for more information.
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
**
** <http://libqxt.org> <foundation@libqxt.org>
**
****************************************************************************/
#ifndef QxtBdbHash_H_kpasd
#define QxtBdbHash_H_kpasd
#include "qxtbdb.h"
#include <QBuffer>
#include <QDataStream>
#include <QVariant>
#include <qxtsharedprivate.h>
#include <qxtglobal.h>
template<class KEY, class VAL>
class QxtBdbHashIterator;
template<class KEY, class VAL>
class /*QXT_BERKELEY_EXPORT*/ QxtBdbHash
{
public:
QxtBdbHash();
QxtBdbHash(QString file);
bool open(QString file);
QxtBdbHashIterator<KEY, VAL> begin();
QxtBdbHashIterator<KEY, VAL> end();
QxtBdbHashIterator<KEY, VAL> find(const KEY & key);
void clear();
bool contains(const KEY & key) const;
bool remove(const KEY & key);
bool insert(KEY k, VAL v);
const VAL value(const KEY & key) const;
const VAL operator[](const KEY & key) const;
bool flush();
private:
int meta_id_key;
int meta_id_val;
QxtSharedPrivate<QxtBdb> qxt_d;
};
class QxtBdbHashIteratorPrivate
{
public:
QxtBdb * db;
BerkeleyDB::DBC *dbc;
void invalidate()
{
if (dbc)
dbc->c_close(dbc);
dbc = 0;
}
~QxtBdbHashIteratorPrivate()
{
invalidate();
}
};
template<class KEY, class VAL>
class QxtBdbHashIterator
{
public:
QxtBdbHashIterator();
QxtBdbHashIterator(const QxtBdbHashIterator<KEY, VAL> & other);
QxtBdbHashIterator & operator= (const QxtBdbHashIterator<KEY, VAL> & other);
bool isValid() const;
operator KEY() const;
KEY key() const;
VAL value() const;
QxtBdbHashIterator<KEY, VAL> operator + (int j) const;
QxtBdbHashIterator<KEY, VAL> & operator ++ ();
QxtBdbHashIterator<KEY, VAL> operator ++ (int);
QxtBdbHashIterator<KEY, VAL> & operator += (int j);
QxtBdbHashIterator<KEY, VAL> operator - (int j) const;
QxtBdbHashIterator<KEY, VAL> & operator -- ();
QxtBdbHashIterator<KEY, VAL> operator -- (int);
QxtBdbHashIterator<KEY, VAL> & operator -= (int j);
QxtBdbHashIterator<KEY, VAL> erase();
private:
friend class QxtBdbHash<KEY, VAL>;
QxtBdbHashIterator(BerkeleyDB::DBC*, QxtBdb * p);
QxtSharedPrivate<QxtBdbHashIteratorPrivate> qxt_d;
int meta_id_key;
int meta_id_val;
/*won't work. no support in bdb*/
bool operator== (const QxtBdbHashIterator<KEY, VAL> & other) const
{
return false;
}
bool operator!= (const QxtBdbHashIterator<KEY, VAL> & other) const
{
return false;
}
};
template<class KEY, class VAL>
QxtBdbHash<KEY, VAL>::QxtBdbHash()
{
qxt_d = new QxtBdb();
///this will fail to compile if KEY or VALUE are not declared metatypes. Good.
meta_id_key = qMetaTypeId<KEY>();
meta_id_val = qMetaTypeId<VAL>();
}
template<class KEY, class VAL>
QxtBdbHash<KEY, VAL>::QxtBdbHash(QString file)
{
qxt_d = new QxtBdb();
open(file);
///this will fail to compile if KEY or VALUE are not declared metatypes. Good.
meta_id_key = qMetaTypeId<KEY>();
meta_id_val = qMetaTypeId<VAL>();
}
template<class KEY, class VAL>
bool QxtBdbHash<KEY, VAL>::open(QString file)
{
return qxt_d().open(file, QxtBdb::CreateDatabase | QxtBdb::LockFree);
}
template<class KEY, class VAL>
QxtBdbHashIterator<KEY, VAL> QxtBdbHash<KEY, VAL>::begin()
{
BerkeleyDB::DBC *cursor;
qxt_d().db->cursor(qxt_d().db, NULL, &cursor, 0);
if (qxt_d().get((void*)0, 0, 0, 0, DB_FIRST, cursor))
return QxtBdbHashIterator<KEY, VAL>(cursor, &qxt_d());
else
return QxtBdbHashIterator<KEY, VAL>();
}
template<class KEY, class VAL>
QxtBdbHashIterator<KEY, VAL> QxtBdbHash<KEY, VAL>::end()
{
BerkeleyDB::DBC *cursor;
qxt_d().db->cursor(qxt_d().db, NULL, &cursor, 0);
if (qxt_d().get((void*)0, 0, 0, 0, DB_LAST, cursor))
return QxtBdbHashIterator<KEY, VAL>(cursor, &qxt_d());
else
return QxtBdbHashIterator<KEY, VAL>();
}
template<class KEY, class VAL>
QxtBdbHashIterator<KEY, VAL> QxtBdbHash<KEY, VAL>::find(const KEY & k)
{
BerkeleyDB::DBC *cursor;
qxt_d().db->cursor(qxt_d().db, NULL, &cursor, 0);
if (qxt_d().get(&k, meta_id_key, 0, 0, DB_SET, cursor))
return QxtBdbHashIterator<KEY, VAL>(cursor, &qxt_d());
else
return QxtBdbHashIterator<KEY, VAL>();
}
template<class KEY, class VAL>
void QxtBdbHash<KEY, VAL>::clear()
{
if (!qxt_d().isOpen)
return;
BerkeleyDB::u_int32_t x;
qxt_d().db->truncate(qxt_d().db, NULL, &x, 0);
}
template<class KEY, class VAL>
bool QxtBdbHash<KEY, VAL>::contains(const KEY & k) const
{
if (!qxt_d().isOpen)
return false;
BerkeleyDB::DBT key;
/* Zero out the DBTs before using them. */
memset(&key, 0, sizeof(BerkeleyDB::DBT));
QByteArray d_key;
{
QBuffer buffer(&d_key);
buffer.open(QIODevice::WriteOnly);
QDataStream s(&buffer);
if (!QMetaType::save(s, meta_id_key, &k))
qCritical("QMetaType::save failed. is your type registered with the QMetaType?");
buffer.close();
}
key.data = d_key.data();
key.size = d_key.size();
return (qxt_d().db->exists(qxt_d().db, NULL, &key, 0) == 0);
}
template<class KEY, class VAL>
bool QxtBdbHash<KEY, VAL>::remove(const KEY & k)
{
if (!qxt_d().isOpen)
return false;
BerkeleyDB::DBT key;
/* Zero out the DBTs before using them. */
memset(&key, 0, sizeof(BerkeleyDB::DBT));
QByteArray d_key;
{
QBuffer buffer(&d_key);
buffer.open(QIODevice::WriteOnly);
QDataStream s(&buffer);
if (!QMetaType::save(s, meta_id_key, &k))
qCritical("QMetaType::save failed. is your type registered with the QMetaType?");
buffer.close();
}
key.data = d_key.data();
key.size = d_key.size();
return (qxt_d().db->del(qxt_d().db, NULL, &key, 0) == 0);
}
template<class KEY, class VAL>
bool QxtBdbHash<KEY, VAL>::insert(KEY k, VAL v)
{
if (!qxt_d().isOpen)
return false;
QByteArray d_key, d_value;
{
QBuffer buffer(&d_key);
buffer.open(QIODevice::WriteOnly);
QDataStream s(&buffer);
if (!QMetaType::save(s, meta_id_key, &k))
qCritical("QMetaType::save failed. is your type registered with the QMetaType?");
buffer.close();
}
{
QBuffer buffer(&d_value);
buffer.open(QIODevice::WriteOnly);
QDataStream s(&buffer);
if (!QMetaType::save(s, meta_id_val, &v))
qCritical("QMetaType::save failed. is your value registered with the QMetaType?");
buffer.close();
}
BerkeleyDB::DBT key, value;
/* Zero out the DBTs before using them. */
memset(&key, 0, sizeof(BerkeleyDB::DBT));
memset(&value, 0, sizeof(BerkeleyDB::DBT));
key.data = d_key.data();
key.size = d_key.size();
value.data = d_value.data();
value.size = d_value.size();
int ret = qxt_d().db->put(qxt_d().db, NULL, &key, &value, 0);
return (ret == 0);
}
template<class KEY, class VAL>
const VAL QxtBdbHash<KEY, VAL>::value(const KEY & k) const
{
if (!qxt_d().isOpen)
return VAL() ;
VAL v;
if (!qxt_d().get(&k, meta_id_key, &v, meta_id_val))
return VAL();
return v;
}
template<class KEY, class VAL>
const VAL QxtBdbHash<KEY, VAL>::operator[](const KEY & key) const
{
return value(key);
}
template<class KEY, class VAL>
bool QxtBdbHash<KEY, VAL>::flush()
{
return qxt_d().flush();
}
template<class KEY, class VAL>
QxtBdbHashIterator<KEY, VAL>::QxtBdbHashIterator()
{
qxt_d = new QxtBdbHashIteratorPrivate;
qxt_d().dbc = 0;
qxt_d().db = 0;
meta_id_key = qMetaTypeId<KEY>();
meta_id_val = qMetaTypeId<VAL>();
}
template<class KEY, class VAL>
QxtBdbHashIterator<KEY, VAL>::QxtBdbHashIterator(const QxtBdbHashIterator<KEY, VAL> & other)
{
///FIXME: possible leaking, since the other isnt properly destructed?
qxt_d = other.qxt_d;
meta_id_key = qMetaTypeId<KEY>();
meta_id_val = qMetaTypeId<VAL>();
}
template<class KEY, class VAL>
QxtBdbHashIterator<KEY, VAL> & QxtBdbHashIterator<KEY, VAL>::operator= (const QxtBdbHashIterator<KEY, VAL> & other)
{
///FIXME: possible leaking, since the other isnt properly destructed?
qxt_d = other.qxt_d;
return *this;
}
template<class KEY, class VAL>
bool QxtBdbHashIterator<KEY, VAL>::isValid() const
{
return (qxt_d().dbc != 0);
}
template<class KEY, class VAL>
QxtBdbHashIterator<KEY, VAL>::operator KEY() const
{
return key();
}
template<class KEY, class VAL>
KEY QxtBdbHashIterator<KEY, VAL>::key() const
{
if (!isValid())
return KEY();
KEY k;
if (qxt_d().db->get(&k, meta_id_key, 0, 0, DB_CURRENT, qxt_d().dbc))
return k;
else
return KEY();
}
template<class KEY, class VAL>
VAL QxtBdbHashIterator<KEY, VAL>::value() const
{
if (!isValid())
return VAL();
VAL v;
if (qxt_d().db->get((void*)0, 0, &v, meta_id_val, DB_CURRENT, qxt_d().dbc))
return v;
else
return VAL();
}
template<class KEY, class VAL>
QxtBdbHashIterator<KEY, VAL> QxtBdbHashIterator<KEY, VAL>::operator + (int j) const
{
// if j is negative, it should subtract as apposed to do nothing...
if(j < 0)
return this->operator-(j*(-1));
QxtBdbHashIterator<KEY, VAL> d = *this;
for (int i = 0;i < j;i++)
++d;
return d;
}
template<class KEY, class VAL>
QxtBdbHashIterator<KEY, VAL> & QxtBdbHashIterator<KEY, VAL>::operator ++ () /*prefix*/
{
if (!isValid())
return *this;
if (!qxt_d().db->get((void*)0, 0, 0, 0, DB_NEXT, qxt_d().dbc))
{
qxt_d().invalidate();
}
return *this;
}
template<class KEY, class VAL>
QxtBdbHashIterator<KEY, VAL> QxtBdbHashIterator<KEY, VAL>::operator ++ (int) /*postfix*/
{
if (!isValid())
return *this;
QxtBdbHashIterator<KEY, VAL> d = *this;
this->operator++();
return d;
}
template<class KEY, class VAL>
QxtBdbHashIterator<KEY, VAL> & QxtBdbHashIterator<KEY, VAL>::operator += (int j)
{
// if j is negative it should subtract as apposed to do nothing
if(j < 0)
return this->operator-=(j*(-1));
for (int i = 0;i < j;i++)
this->operator++();
return *this;
}
template<class KEY, class VAL>
QxtBdbHashIterator<KEY, VAL> QxtBdbHashIterator<KEY, VAL>::operator - (int j) const
{
// if j is negative, then we should add as opposed to do noting... I really need to learn to spell "opposed" correctly more regularly... hmm..
if(j < 0)
return this->operator+(j*(-1));
QxtBdbHashIterator<KEY, VAL> d = *this;
for (int i = 0;i < j;i++)
--d;
return d;
}
template<class KEY, class VAL>
QxtBdbHashIterator<KEY, VAL> & QxtBdbHashIterator<KEY, VAL>::operator -- () /*prefix*/
{
if (!isValid())
return *this;
if (!qxt_d().db->get((void*)0, 0, 0, 0, DB_PREV, qxt_d().dbc))
qxt_d().invalidate();
return *this;
}
template<class KEY, class VAL>
QxtBdbHashIterator<KEY, VAL> QxtBdbHashIterator<KEY, VAL>::operator -- (int) /*postfix*/
{
if (!isValid())
return *this;
QxtBdbHashIterator<KEY, VAL> d = *this;
this->operator--();
return d;
}
template<class KEY, class VAL>
QxtBdbHashIterator<KEY, VAL> & QxtBdbHashIterator<KEY, VAL>::operator -= (int j)
{
// if j is negative, we should add
if(j < 0)
return this->operator+=(j*(-1));
for (int i = 0;i < j;i++)
this->operator--();
return *this;
}
template<class KEY, class VAL>
QxtBdbHashIterator<KEY, VAL> QxtBdbHashIterator<KEY, VAL>::erase()
{
BerkeleyDB::DBC * newdbc;
qxt_d().dbc->c_dup(qxt_d().dbc, &newdbc, DB_POSITION);
QxtBdbHashIterator<KEY, VAL> d(newdbc, qxt_d().db);
qxt_d().dbc->del(qxt_d().dbc, NULL);
++d;
qxt_d().invalidate();
return d;
}
template<class KEY, class VAL>
QxtBdbHashIterator<KEY, VAL>::QxtBdbHashIterator(BerkeleyDB::DBC* dbc, QxtBdb * p)
{
qxt_d = new QxtBdbHashIteratorPrivate;
qxt_d().dbc = dbc;
qxt_d().db = p;
meta_id_key = qMetaTypeId<KEY>();
meta_id_val = qMetaTypeId<VAL>();
}
#endif

View File

@ -1,247 +0,0 @@
/****************************************************************************
**
** Copyright (C) Qxt Foundation. Some rights reserved.
**
** This file is part of the QxtBerkeley module of the Qxt library.
**
** This library is free software; you can redistribute it and/or modify it
** under the terms of the Common Public License, version 1.0, as published
** by IBM, and/or under the terms of the GNU Lesser General Public License,
** version 2.1, as published by the Free Software Foundation.
**
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
** FITNESS FOR A PARTICULAR PURPOSE.
**
** You should have received a copy of the CPL and the LGPL along with this
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
** included with the source distribution for more information.
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
**
** <http://libqxt.org> <foundation@libqxt.org>
**
****************************************************************************/
#include "qxtbdbtree.h"
/*!
\class QxtBdbTree
\inmodule QxtBerkeley
\brief The QxtBdbTree class is a template berkeley container for tree structured data
The template argument must be registered with the Qt meta system.
You may not touch the file while a QxtBdbTree instance is running on it.
Example usage:
\code
QxtBdbTree<QString> db("test.db");
db.root().append("fooooo").append("bla");
db.dumpTree(); //try this if you are unsure, how the data will look like
\endcode
There is an extensive example in /examples/berkeley/xmlstorage
All functions of this class are thread safe.
Calling open() multiple times is undefined.
An iterator may only be used from one thread at once, but you can have multiple iterators.
TODO: {implicitshared}
\sa QxtBdbTreeIterator
*/
/*!
\fn QxtBdbTree<T>::QxtBdbTree()
Constructs an invalid QxtBdbTree
*/
/*!
\fn QxtBdbTree<T>::QxtBdbTree (QString file)
Constructs a QxtBdbTree, and opens the \a file specified as its database.
*/
/*!
\fn bool QxtBdbTree<T>::open (QString file)
Opens the specified \a file.
Returns \c true on success and \c false on failure.
\bold {Note:} a sanity check is performed before opening the file.
*/
/*!
\fn void QxtBdbTree<T>::clear()
Erase all records. This does not delete the underlying file.
*/
/*!
\fn bool QxtBdbTree<T>::flush()
Flushes the underlying DB file. All changes are synced to disk.
*/
/*!
\fn QxtBdbTreeIterator<T> QxtBdbTree<T>::root() const
Returns the rootnode, which is, similar to QAbstractItemModel, invalid and has no data itself.
*/
/*!
\fn void QxtBdbTree<T>::dumpTree() const
Outputs the contents of the database as flat file, and as iterateable tree onto qDebug().
This function assumes, the class used for template initialisation implements the QDebug<< operator
*/
/*!
\class QxtBdbTreeIterator
\inmodule QxtBerkeley
\brief The QxtBdbTreeIterator class provides a tree iterator on QxtBdbtree
TODO: {implicitshared}
\sa QxtBdbTree
*/
/*!
\fn QxtBdbTreeIterator<T>::QxtBdbTreeIterator()
Constructs an invalid QxtBdbTreeIterator
It's an error to use this to iterate, access data, etc..
*/
/*!
\fn QxtBdbTreeIterator<T>::~QxtBdbTreeIterator()
Destructs the iterator.
The underlying cursors will be closed.
*/
/*!
\fn QxtBdbTreeIterator<T>::QxtBdbTreeIterator(const QxtBdbTreeIterator<T> & other)
Copies the \a other iterator.
The underlying cursor is duped, meaning the position will be copied, but the copy can be used independently.
*/
/*!
\fn QxtBdbTreeIterator<T> & QxtBdbTreeIterator<T>::operator= ( const QxtBdbTreeIterator<T> & other )
Copies the \a other iterator.
The underlying cursor is duped, meaning the position will be copied, but the copy can be used independently
*/
/*!
\fn bool QxtBdbTreeIterator<T>::isValid() const
Returns \c true if the iterator seems to point to a valid location.
Calls to value() might fail anyway (but not crash), in case of concurrent access.
If you want to be 100% sure value() will return valid data, while using multiple threads, then you have to track changes yourself.
*/
/*!
\fn QxtBdbTreeIterator<T>::operator T() const
\sa value()
*/
/*!
\fn T QxtBdbTreeIterator<T>::value() const
Returns the value, the iterator is currently pointing to.
It is an error to call value() when isValid() returns \c false.
In case an database error ocures, like the item been deleted, value() will return a default constructed T.
*/
/*!
\fn QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::parent () const
Returns the parent of this item, or an invalid QxtBdbTreeIterator if this is the root item.
*/
/*!
\fn QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::next () const
Returns the next sibling of this item, or an invalid QxtBdbTreeIterator if this is the last one.
*/
/*!
\fn QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::previous () const
Returns the previous sibling of this item, or an invalid QxtBdbTreeIterator if this is the last one.
*/
/*!
\fn QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::child () const
Returns the first child of this item, or an invalid QxtBdbTreeIterator if there are none.
*/
/*!
\fn QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::operator + ( int j ) const
Returns an iterator, \a j items next to this one.
If there is no such item, the returned iterator is invalid.
\sa next()
*/
/*!
\fn QxtBdbTreeIterator<T> & QxtBdbTreeIterator<T>::operator ++ ()
This prefix operator increments the item by one.
If there are no more items, the iterator becomes invalid.
*/
/*!
\fn QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::operator ++ (int)
This postfix operator makes a copy of the item, then increments itself and returns the copy.
If there are no more items, the iterator becomes invalid.
*/
/*!
\fn QxtBdbTreeIterator<T> & QxtBdbTreeIterator<T>::operator += ( int j )
Increments the item by \a j.
If there are no more items, the iterator becomes invalid.
*/
/*!
\fn QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::operator - ( int j ) const
Returns an iterator, \a j previous next to this one.
If there is no such item, the returnediterator is invalid.
\sa previous()
*/
/*!
\fn QxtBdbTreeIterator<T> & QxtBdbTreeIterator<T>::operator -- ()
This prefix operator decrements the item by one.
If there are no more items, the iterator becomes invalid.
*/
/*!
\fn QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::operator -- (int)
This postfix operator makes a copy of the item, then decrements itself and returns the copy.
If there are no more items, the iterator becomes invalid.
*/
/*!
\fn QxtBdbTreeIterator<T> & QxtBdbTreeIterator<T>::operator -= ( int j )
Decrements the item by \a j.
If there are no more items, the iterator becomes invalid.
*/
/*!
\fn QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::append (const T & item )
Appends an \a item to the children of this one, and returns an iterator to it.
If insertion fails, an invalid iterator is returned.
*/
/*!
\fn QxtBdbTreeIterator<T> QxtBdbTreeIterator::erase()
TODO returns
*/
/*!
\fn void QxtBdbTreeIterator::invalidate()
TODO
*/
/*!
\fn quint64 QxtBdbTreeIterator::level() const
TODO returns
*/
/*!
\fn QxtBdbTreeIterator<T> QxtBdbTreeIterator::prepend(const T& t)
TODO \a t
*/
/*!
\fn bool QxtBdbTreeIterator::setValue(T value)
TODO \a value
*/

View File

@ -1,848 +0,0 @@
/****************************************************************************
**
** Copyright (C) Qxt Foundation. Some rights reserved.
**
** This file is part of the QxtBerkeley module of the Qxt library.
**
** This library is free software; you can redistribute it and/or modify it
** under the terms of the Common Public License, version 1.0, as published
** by IBM, and/or under the terms of the GNU Lesser General Public License,
** version 2.1, as published by the Free Software Foundation.
**
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
** FITNESS FOR A PARTICULAR PURPOSE.
**
** You should have received a copy of the CPL and the LGPL along with this
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
** included with the source distribution for more information.
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
**
** <http://libqxt.org> <foundation@libqxt.org>
**
****************************************************************************/
#ifndef QxtBdbTree_H_Guard_pyxvby
#define QxtBdbTree_H_Guard_pyxvby
#include <qxtsharedprivate.h>
#include <QVariant>
#include <QPair>
#include <QDebug>
#include "qxtbdb.h"
template<class T>
class QxtBdbTreeIterator;
template<class T>
class QxtBdbTree
{
public:
QxtBdbTree();
QxtBdbTree(QString file);
bool open(QString file);
void clear();
bool flush();
QxtBdbTreeIterator<T> root() const;
void dumpTree() const;
private:
int meta_id;
QxtSharedPrivate<QxtBdb> qxt_d;
void debugprintchildren(QxtBdbTreeIterator<T> it) const;
};
template<class T>
QxtBdbTree<T>::QxtBdbTree()
{
meta_id = qMetaTypeId<T>();
qxt_d = new QxtBdb;
}
template<class T>
QxtBdbTree<T>::QxtBdbTree(QString file)
{
meta_id = qMetaTypeId<T>();
qxt_d = new QxtBdb;
open(file);
}
template<class T>
bool QxtBdbTree<T>::open(QString file)
{
BerkeleyDB::u_int32_t f;
qxt_d().db->get_flags(qxt_d().db, &f);
f |= DB_DUP;
qxt_d().db->set_flags(qxt_d().db, f);
bool r = qxt_d().open(file, QxtBdb::CreateDatabase | QxtBdb::LockFree);
return r;
}
template<class T>
void QxtBdbTree<T>::clear()
{
if (!qxt_d().isOpen)
return;
BerkeleyDB::u_int32_t x;
qxt_d().db->truncate(qxt_d().db, NULL, &x, 0);
}
template<class T>
bool QxtBdbTree<T>::flush()
{
return qxt_d().flush();
}
template<class T>
QxtBdbTreeIterator<T> QxtBdbTree<T>::root() const
{
QxtBdbTreeIterator<T> r(0, const_cast<QxtBdb*>(&qxt_d()));
r.root = true;
return r;
}
template<class T>
void QxtBdbTree<T>::debugprintchildren(QxtBdbTreeIterator<T> it) const
{
it = it.child();
while (it.isValid())
{
QByteArray p;
for (quint64 x = 0; x < it.level();x++)
{
p += " |";
}
qDebug() << p.data() << "-" << it.value();
debugprintchildren(it);
++it;
}
}
/*
|-n1
|-n2
| |-n3
|-n1
| |-n1
| | |-n3
| | | -n2
*/
template<class T>
void QxtBdbTree<T>::dumpTree() const
{
BerkeleyDB::DBC *cursor;
qxt_d().db->cursor(qxt_d().db, NULL, &cursor, 0);
if (!qxt_d().get((void*)0, 0, 0, 0, DB_FIRST, cursor))
{
return;
}
QxtBdbTreeIterator<T> k(cursor, const_cast<QxtBdb*>(&qxt_d()));
qDebug() << "\r\nQxtBdbTree<" << QMetaType::typeName(qMetaTypeId<T>()) << ">::dumpTree()\r\n";
qDebug() << "Level\t \t Value";
Q_FOREVER
{
qDebug() << k.level() << " \t->\t" << k.value();
if (!qxt_d().get((void*)0, 0, 0, 0, DB_NEXT, cursor))
break;
}
qDebug() << "\r\n";
qDebug() << "Iterate";
debugprintchildren(root());
qDebug() << "\r\n";
}
template<class T>
class QxtBdbTreeIterator
{
public:
QxtBdbTreeIterator();
~QxtBdbTreeIterator();
QxtBdbTreeIterator(const QxtBdbTreeIterator<T> & other);
QxtBdbTreeIterator<T> & operator= (const QxtBdbTreeIterator<T> & other);
bool isValid() const;
operator T() const;
T value() const;
bool setValue(T);
QxtBdbTreeIterator<T> parent() const;
QxtBdbTreeIterator<T> next() const;
QxtBdbTreeIterator<T> previous() const;
QxtBdbTreeIterator<T> child() const;
QxtBdbTreeIterator<T> operator + (int j) const;
QxtBdbTreeIterator<T> & operator ++ ();
QxtBdbTreeIterator<T> operator ++ (int);
QxtBdbTreeIterator<T> & operator += (int j);
QxtBdbTreeIterator<T> operator - (int j) const;
QxtBdbTreeIterator<T> & operator -- ();
QxtBdbTreeIterator<T> operator -- (int);
QxtBdbTreeIterator<T> & operator -= (int j);
QxtBdbTreeIterator<T> append(const T & t);
QxtBdbTreeIterator<T> prepend(const T & t);
QxtBdbTreeIterator<T> erase();
protected:
quint64 level() const;
void invalidate()
{
if (dbc)
dbc->c_close(dbc);
dbc = 0;
}
private:
friend class QxtBdbTree<T>;
QxtBdbTreeIterator(BerkeleyDB::DBC*, QxtBdb * p);
QxtBdbTreeIterator<T> croot() const;
int meta_id;
QxtBdb * db;
BerkeleyDB::DBC *dbc;
bool root;
/*won't work. no support in bdb*/
bool operator== (const QxtBdbTreeIterator<T> & other) const
{
return false;
}
bool operator!= (const QxtBdbTreeIterator<T> & other) const
{
return false;
}
};
template<class T>
QxtBdbTreeIterator<T>::QxtBdbTreeIterator()
{
dbc = 0;
db = 0;
root = false;
meta_id = qMetaTypeId<T>();
}
template<class T>
QxtBdbTreeIterator<T>::~QxtBdbTreeIterator()
{
invalidate();
}
template<class T>
QxtBdbTreeIterator<T>::QxtBdbTreeIterator(const QxtBdbTreeIterator<T> & other)
{
dbc = 0;
db = 0;
root = false;
meta_id = qMetaTypeId<T>();
db = other.db;
root = other.root;
if (other.dbc)
{
other.dbc->c_dup(other.dbc, &dbc, DB_POSITION);
}
}
template<class T>
QxtBdbTreeIterator<T>::QxtBdbTreeIterator(BerkeleyDB::DBC* dbc, QxtBdb * p)
{
this->dbc = dbc;
db = p;
root = false;
meta_id = qMetaTypeId<T>();
}
template<class T>
QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::croot() const
{
QxtBdbTreeIterator<T> k = *this;
k.invalidate();
k.root = true;
return k;
}
template<class T>
QxtBdbTreeIterator<T> & QxtBdbTreeIterator<T>::operator= (const QxtBdbTreeIterator<T> & other)
{
invalidate();
db = other.db;
root = other.root;
if (other.dbc)
{
other.dbc->c_dup(other.dbc, &dbc, DB_POSITION);
}
return *this;
}
template<class T>
bool QxtBdbTreeIterator<T>::isValid() const
{
if (root)
return true;
return (dbc != 0 && db != 0);
}
template<class T>
QxtBdbTreeIterator<T>::operator T() const
{
return value();
}
template<class T>
T QxtBdbTreeIterator<T>::value() const
{
if (!dbc)
{
qWarning("QxtBdbTreeIterator<T>::value() on invalid iterator ");
return T();
}
BerkeleyDB::DBT dbkey, dbvalue;
memset(&dbkey, 0, sizeof(BerkeleyDB::DBT));
memset(&dbvalue, 0, sizeof(BerkeleyDB::DBT));
dbvalue.ulen = 0;
dbvalue.flags = DB_DBT_USERMEM;
dbkey.ulen = 0;
dbkey.flags = DB_DBT_USERMEM;
int ret = dbc->c_get(dbc, &dbkey, &dbvalue, DB_CURRENT);
if (ret != DB_BUFFER_SMALL)
return T();
dbvalue.ulen = dbvalue.size;
dbvalue.data =::malloc(dbvalue.size);
dbkey.ulen = dbkey.size;
dbkey.data =::malloc(dbkey.size);
ret = dbc->c_get(dbc, &dbkey, &dbvalue, DB_CURRENT);
T t = QxtBdb::qxtMetaLoad<T>((quint64*)dbvalue.data + 1, dbvalue.size - sizeof(quint64));
::free(dbkey.data);
::free(dbvalue.data);
if (ret != 0)
return T();
return t;
}
template<class T>
bool QxtBdbTreeIterator<T>::setValue(T t)
{
if (!dbc)
{
qWarning("QxtBdbTreeIterator<T>::setValue() on invalid iterator ");
return false;
}
BerkeleyDB::DBT dbkey, dbvalue;
::memset(&dbkey, 0, sizeof(BerkeleyDB::DBT));
::memset(&dbvalue, 0, sizeof(BerkeleyDB::DBT));
char uselesszero = 0;
dbkey.data = &uselesszero;
dbkey.size = sizeof(char);
dbkey.ulen = 0;
dbkey.flags = DB_DBT_USERMEM;
quint64 mylevel = level();
QByteArray d = QxtBdb::qxtMetaSave<T>(t);
dbvalue.size = sizeof(quint64) + d.size();
dbvalue.ulen = dbvalue.size;
dbvalue.data =::malloc(dbvalue.size);
::memcpy(dbvalue.data, &mylevel, sizeof(quint64));
::memcpy((quint64*)dbvalue.data + 1, d.data(), d.size());
dbvalue.flags = DB_DBT_USERMEM;
int ret = 234525;
ret = dbc->c_put(dbc, &dbkey, &dbvalue, DB_CURRENT);
::free(dbvalue.data);
if (ret != 0)
return false;
return true;
}
template<class T>
QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::parent() const
{
if (root)
return croot();
if (!dbc)
return QxtBdbTreeIterator<T>();
QxtBdbTreeIterator<T> d(*this);
quint64 lvl = level();
Q_FOREVER
{
#if DB_VERSION_MINOR > 5
if (!d.db->get((void*)0, 0, 0, 0, DB_PREV_DUP, d.dbc))
#else
if (!d.db->get((void*)0, 0, 0, 0, DB_PREV, d.dbc))
#endif
return croot();
if (d.level() == lvl - 1)
break;
}
return d;
}
template<class T>
QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::next() const
{
if (root)
return QxtBdbTreeIterator<T>();
return QxtBdbTreeIterator<T>(*this) + 1;
}
template<class T>
QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::previous() const
{
if (root)
return QxtBdbTreeIterator<T>();
return QxtBdbTreeIterator<T>(*this) - 1;
}
template<class T>
QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::child() const
{
QxtBdbTreeIterator<T> d(*this);
if (root)
{
BerkeleyDB::DBC *cursor;
db->db->cursor(db->db, NULL, &cursor, 0);
d = QxtBdbTreeIterator<T>(cursor, db);
if (!d.db->get((void*)0, 0, 0, 0, DB_FIRST, d.dbc))
{
return QxtBdbTreeIterator<T>();
}
}
else
{
if (!dbc)
return QxtBdbTreeIterator<T>();
quint64 lvl = level();
if (!d.db->get((void*)0, 0, 0, 0, DB_NEXT_DUP, d.dbc))
{
return QxtBdbTreeIterator<T>();
}
if (d.level() != lvl + 1)
return QxtBdbTreeIterator<T>();
}
return d;
}
template<class T>
QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::operator + (int j) const
{
if(j < 0)
return this->operator-(j*(-1));
QxtBdbTreeIterator<T> d(*this);
for (int i = 0;i < j;i++)
++d;
return d;
}
template<class T>
QxtBdbTreeIterator<T> & QxtBdbTreeIterator<T>::operator ++ ()
{
if (root)
{
invalidate();
return *this;
}
if (!dbc)
return *this;
quint64 before = level();
Q_FOREVER
{
if (!db->get((void*)0, 0, 0, 0, DB_NEXT_DUP, dbc))
{
invalidate();
break;
}
if (before == level())
break;
if (before > level())
{
invalidate();
break;
}
}
return *this;
}
template<class T>
QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::operator ++ (int)
{
QxtBdbTreeIterator<T> d(*this);
operator++();
return d;
}
template<class T>
QxtBdbTreeIterator<T> & QxtBdbTreeIterator<T>::operator += (int j)
{
if(j < 0)
return this->operator-=(j*(-1));
for (int i = 0;i < j;i++)
operator++();
return *this;
}
template<class T>
QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::operator - (int j) const
{
if(j < 0)
return this->operator+(j*(-1));
QxtBdbTreeIterator<T> d(*this);
for (int i = 0;i < j;i++)
--d;
return d;
}
template<class T>
QxtBdbTreeIterator<T> & QxtBdbTreeIterator<T>::operator -- ()
{
if (root)
return *this;
if (!dbc)
return *this;
int lvl = level();
#if DB_VERSION_MINOR > 5
do
{
if (!db->get((void*)0, 0, 0, 0, DB_PREV_DUP, dbc))
{
invalidate();
break;
}
}
while (lvl != level());
#else
do
{
if (!db->get((void*)0, 0, 0, 0, DB_PREV, dbc))
{
invalidate();
break;
}
}
while (lvl != level());
#endif
return *this;
}
template<class T>
QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::operator -- (int)
{
QxtBdbTreeIterator<T> d(*this);
operator--();
return d;
}
template<class T>
QxtBdbTreeIterator<T> & QxtBdbTreeIterator<T>::operator -= (int j)
{
if(j < 0)
return this->operator+=(j*(-1));
for (int i = 0;i < j;i++)
operator--();
return *this;
}
template<class T>
QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::append(const T & t)
{
Q_ASSERT(isValid());
BerkeleyDB::DBT dbkey, dbvalue;
::memset(&dbkey, 0, sizeof(BerkeleyDB::DBT));
::memset(&dbvalue, 0, sizeof(BerkeleyDB::DBT));
char uselesszero = 0;
dbkey.data = &uselesszero;
dbkey.size = sizeof(char);
dbkey.ulen = 0;
dbkey.flags = DB_DBT_USERMEM;
quint64 newlevel = level() + 1;
QByteArray d = QxtBdb::qxtMetaSave<T>(t);
dbvalue.size = sizeof(quint64) + d.size();
dbvalue.ulen = dbvalue.size;
dbvalue.data =::malloc(dbvalue.size);
::memcpy(dbvalue.data, &newlevel, sizeof(quint64));
::memcpy((quint64*)dbvalue.data + 1, d.data(), d.size());
dbvalue.flags = DB_DBT_USERMEM;
int ret = 234525;
QxtBdbTreeIterator<T> e = *this;
if (dbc)
{
while (e.db->get((void*)0, 0, 0, 0, DB_NEXT_DUP, e.dbc))
{
if (e.level() <= level())
{
#if DB_VERSION_MINOR > 5
e.db->get((void*)0, 0, 0, 0, DB_PREV_DUP, e.dbc);
#else
e.db->get((void*)0, 0, 0, 0, DB_PREV, e.dbc);
#endif
break;
}
}
ret = dbc->c_put(e.dbc, &dbkey, &dbvalue, DB_AFTER);
}
else if (root)
{
ret = db->db->put(db->db, NULL, &dbkey, &dbvalue, NULL);
BerkeleyDB::DBC *cursor;
db->db->cursor(db->db, NULL, &cursor, 0);
if (db->get((void*)0, 0, 0, 0, DB_LAST, cursor))
e = QxtBdbTreeIterator<T>(cursor, db);
}
::free(dbvalue.data);
if (ret != 0)
{
qWarning("QxtBdbTreeIterator::append failed %i", ret);
return QxtBdbTreeIterator<T>();
}
return e;
}
template<class T>
QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::prepend(const T & t)
{
if (!dbc)
return QxtBdbTreeIterator<T>();
QxtBdbTreeIterator<T> e(*this);
BerkeleyDB::DBT dbkey, dbvalue;
::memset(&dbkey, 0, sizeof(BerkeleyDB::DBT));
::memset(&dbvalue, 0, sizeof(BerkeleyDB::DBT));
char uselesszero = 0;
dbkey.data = &uselesszero;
dbkey.size = sizeof(char);
dbkey.ulen = 0;
dbkey.flags = DB_DBT_USERMEM;
quint64 newlevel = level();
QByteArray d = QxtBdb::qxtMetaSave<T>(t);
dbvalue.size = sizeof(quint64) + d.size();
dbvalue.ulen = dbvalue.size;
dbvalue.data =::malloc(dbvalue.size);
::memcpy(dbvalue.data, &newlevel, sizeof(quint64));
::memcpy((quint64*)dbvalue.data + 1, d.data(), d.size());
dbvalue.flags = DB_DBT_USERMEM;
int ret = 234525;
ret = e.dbc->c_put(e.dbc, &dbkey, &dbvalue, DB_BEFORE);
::free(dbvalue.data);
if (ret != 0)
return QxtBdbTreeIterator<T>();
return e;
}
template<class T>
quint64 QxtBdbTreeIterator<T>::level() const
{
if (!dbc)
return 0;
BerkeleyDB::DBT dbkey, dbvalue;
memset(&dbkey, 0, sizeof(BerkeleyDB::DBT));
memset(&dbvalue, 0, sizeof(BerkeleyDB::DBT));
dbvalue.size = 0;
dbvalue.size = 0;
dbvalue.ulen = 0;
dbvalue.flags = DB_DBT_USERMEM;
dbkey.ulen = 0;
dbkey.flags = DB_DBT_USERMEM;
int ret = dbc->c_get(dbc, &dbkey, &dbvalue, DB_CURRENT);
if (ret != DB_BUFFER_SMALL)
qFatal("QxtBdbTreeIterator::level() %s", qPrintable(QxtBdb::dbErrorCodeToString(ret)));
dbvalue.ulen = dbvalue.size;
dbvalue.data =::malloc(dbvalue.size);
dbkey.ulen = dbkey.size;
dbkey.data =::malloc(dbkey.size);
ret = dbc->c_get(dbc, &dbkey, &dbvalue, DB_CURRENT);
quint64 lvl;
::memcpy(&lvl, dbvalue.data, sizeof(quint64));
::free(dbkey.data);
::free(dbvalue.data);
if (ret != 0)
return 0;
return lvl;
}
template<class T>
QxtBdbTreeIterator<T> QxtBdbTreeIterator<T>::erase()
{
Q_ASSERT(isValid());
quint64 before = level();
Q_FOREVER
{
int ret = dbc->c_del(dbc, 0);
if (ret != 0)
{
qWarning("QxtBdbTreeIterator<T>::erase() failed %s", qPrintable(QxtBdb::dbErrorCodeToString(ret)));
return QxtBdbTreeIterator<T>();
}
if (!db->get((void*)0, 0, 0, 0, DB_NEXT_DUP, dbc))
return *this;
if (level() <= before)
return *this;
}
Q_ASSERT(false);
return *this;
}
#endif

View File

@ -1,32 +0,0 @@
/****************************************************************************
**
** Copyright (C) Qxt Foundation. Some rights reserved.
**
** This file is part of the QxtBerkeley module of the Qxt library.
**
** This library is free software; you can redistribute it and/or modify it
** under the terms of the Common Public License, version 1.0, as published
** by IBM, and/or under the terms of the GNU Lesser General Public License,
** version 2.1, as published by the Free Software Foundation.
**
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
** FITNESS FOR A PARTICULAR PURPOSE.
**
** You should have received a copy of the CPL and the LGPL along with this
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
** included with the source distribution for more information.
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
**
** <http://libqxt.org> <foundation@libqxt.org>
**
****************************************************************************/
#ifndef QXTBERKELEY_H_INCLUDED
#define QXTBERKELEY_H_INCLUDED
#include "qxtbdb.h"
#include "qxtbdbhash.h"
#include "qxtbdbtree.h"
#endif // QXTBERKELEY_H_INCLUDED

View File

@ -1,114 +0,0 @@
INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD
HEADERS += qxtabstractconnectionmanager.h
HEADERS += qxtabstractsignalserializer.h
HEADERS += qxtalgorithms.h
HEADERS += qxtboundcfunction.h
HEADERS += qxtboundfunction.h
HEADERS += qxtboundfunctionbase.h
HEADERS += qxtcore.h
HEADERS += qxtcommandoptions.h
HEADERS += qxtcsvmodel.h
HEADERS += qxtdaemon.h
HEADERS += qxtdatastreamsignalserializer.h
HEADERS += qxtdeplex.h
HEADERS += qxtdeplex_p.h
HEADERS += qxterror.h
HEADERS += qxtfifo.h
HEADERS += qxtglobal.h
HEADERS += qxthmac.h
HEADERS += qxtjson.h
HEADERS += qxtjob.h
HEADERS += qxtjob_p.h
HEADERS += qxtlinesocket.h
HEADERS += qxtlinesocket_p.h
HEADERS += qxtlinkedtree.h
HEADERS += qxtlocale.h
HEADERS += qxtlocale_data_p.h
HEADERS += qxtlogger.h
HEADERS += qxtlogger_p.h
HEADERS += qxtloggerengine.h
HEADERS += qxtlogstream.h
HEADERS += qxtlogstream_p.h
HEADERS += qxtmetaobject.h
HEADERS += qxtmetatype.h
HEADERS += qxtmodelserializer.h
HEADERS += qxtmultisignalwaiter.h
HEADERS += qxtnamespace.h
HEADERS += qxtnull.h
HEADERS += qxtnullable.h
HEADERS += qxtpairlist.h
HEADERS += qxtpimpl.h
HEADERS += qxtpipe.h
HEADERS += qxtpipe_p.h
HEADERS += qxtpointerlist.h
HEADERS += qxtsharedprivate.h
HEADERS += qxtsignalgroup.h
HEADERS += qxtsignalwaiter.h
HEADERS += qxtslotjob.h
HEADERS += qxtslotjob_p.h
HEADERS += qxtslotmapper.h
HEADERS += qxtstdio.h
HEADERS += qxtstdio_p.h
HEADERS += qxtstdstreambufdevice.h
HEADERS += qxttimer.h
HEADERS += qxttypelist.h
HEADERS += qxtrpcservice.h
HEADERS += qxtrpcservice_p.h
SOURCES += qxtabstractconnectionmanager.cpp
SOURCES += qxtcommandoptions.cpp
SOURCES += qxtcsvmodel.cpp
SOURCES += qxtdaemon.cpp
SOURCES += qxtdatastreamsignalserializer.cpp
SOURCES += qxtdeplex.cpp
SOURCES += qxterror.cpp
SOURCES += qxtfifo.cpp
SOURCES += qxtglobal.cpp
SOURCES += qxthmac.cpp
SOURCES += qxtlocale.cpp
SOURCES += qxtjson.cpp
SOURCES += qxtjob.cpp
SOURCES += qxtlinesocket.cpp
SOURCES += qxtlinkedtree.cpp
SOURCES += qxtlogger.cpp
SOURCES += qxtloggerengine.cpp
SOURCES += qxtlogstream.cpp
SOURCES += qxtmetaobject.cpp
SOURCES += qxtmodelserializer.cpp
SOURCES += qxtmultisignalwaiter.cpp
SOURCES += qxtnull.cpp
SOURCES += qxtpipe.cpp
SOURCES += qxtpointerlist.cpp
SOURCES += qxtsignalgroup.cpp
SOURCES += qxtsignalwaiter.cpp
SOURCES += qxtslotjob.cpp
SOURCES += qxtslotmapper.cpp
SOURCES += qxtstdio.cpp
SOURCES += qxtstdstreambufdevice.cpp
SOURCES += qxttimer.cpp
SOURCES += qxtrpcservice.cpp
!symbian {
# QxtSerialDevice and QxtFileLock
# are disabled for Symbian pending implementation
HEADERS += qxtfilelock.h
HEADERS += qxtfilelock_p.h
SOURCES += qxtfilelock.cpp
unix {
HEADERS += qxtserialdevice.h
HEADERS += qxtserialdevice_p.h
SOURCES += qxtfilelock_unix.cpp
SOURCES += qxtserialdevice.cpp
SOURCES += qxtserialdevice_unix.cpp
}
win32 {
SOURCES += qxtfilelock_win.cpp
}
}

View File

@ -1,11 +0,0 @@
TEMPLATE = lib
TARGET = QxtCore
DEFINES += QXTCORE_LIBRARY
include(../../../../openpilotgcslibrary.pri)
DEFINES += BUILD_QXT_CORE
include(core.pri)
include(logengines/logengines.pri)
#include(../qxtbase.pri)

View File

@ -1,18 +0,0 @@
INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD
# interfaces
HEADERS += $$PWD/qxtabstractfileloggerengine.h $$PWD/qxtabstractiologgerengine.h
SOURCES += $$PWD/qxtabstractfileloggerengine.cpp $$PWD/qxtabstractiologgerengine.cpp
# Basic STD Logger Engine
HEADERS += $$PWD/qxtbasicstdloggerengine.h
SOURCES += $$PWD/qxtbasicstdloggerengine.cpp
# Basic File Logger Engine
HEADERS += $$PWD/qxtbasicfileloggerengine.h
SOURCES += $$PWD/qxtbasicfileloggerengine.cpp
# XML File Logger Engine
HEADERS += $$PWD/qxtxmlfileloggerengine.h
SOURCES += $$PWD/qxtxmlfileloggerengine.cpp

View File

@ -1,166 +0,0 @@
/****************************************************************************
**
** Copyright (C) Qxt Foundation. Some rights reserved.
**
** This file is part of the QxtCore module of the Qxt library.
**
** This library is free software; you can redistribute it and/or modify it
** under the terms of the Common Public License, version 1.0, as published
** by IBM, and/or under the terms of the GNU Lesser General Public License,
** version 2.1, as published by the Free Software Foundation.
**
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
** FITNESS FOR A PARTICULAR PURPOSE.
**
** You should have received a copy of the CPL and the LGPL along with this
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
** included with the source distribution for more information.
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
**
** <http://libqxt.org> <foundation@libqxt.org>
**
****************************************************************************/
#include "qxtabstractfileloggerengine.h"
/*!
\class QxtAbstractFileLoggerEngine
\brief The QxtAbstractFileLoggerEngine class is the base class of file logger engines.
\inmodule QxtCore
\sa QxtLogger
*/
class QxtAbstractFileLoggerEnginePrivate : public QxtPrivate<QxtAbstractFileLoggerEngine>
{
QXT_DECLARE_PUBLIC(QxtAbstractFileLoggerEngine)
public:
QString logFile;
QIODevice::OpenMode mode;
};
/*!
Constructs a QxtAbstractFileLoggerEngine with \a fileName and open \a mode.
*/
QxtAbstractFileLoggerEngine::QxtAbstractFileLoggerEngine(const QString &fileName, QIODevice::OpenMode mode)
: QxtAbstractIOLoggerEngine(0)
{
QXT_INIT_PRIVATE(QxtAbstractFileLoggerEngine);
qxt_d().mode = mode;
setLogFileName(fileName);
}
/*!
Destructs the file logger engine.
*/
QxtAbstractFileLoggerEngine::~QxtAbstractFileLoggerEngine()
{
killLoggerEngine();
}
/*!
\reimp
*/
void QxtAbstractFileLoggerEngine::initLoggerEngine()
{
// Are we already logging to a file? If so, close it and disable logging.
killLoggerEngine();
// If the file exists, check if we can write to it. If we can, we append!
// If the file doesn't exits, try to create it.
// If we can't write to a file, disable this plugin.
if (qxt_d().logFile.isEmpty()) return; // if there's no filename, disable the engine until one is given
setDevice(new QFile(qxt_d().logFile));
if (!device()->open(qxt_d().mode)
|| !device()->isWritable())
{
killLoggerEngine();
return;
}
enableLogging();
}
/*!
\reimp
*/
void QxtAbstractFileLoggerEngine::killLoggerEngine()
{
if (device() != 0)
{
if (device()->isOpen()) device()->close();
delete device();
setDevice(0);
}
}
/*!
\reimp
*/
bool QxtAbstractFileLoggerEngine::isInitialized() const
{
return (device() != 0);
}
/*!
\reimp
*/
void QxtAbstractFileLoggerEngine::writeFormatted(QxtLogger::LogLevel level, const QList<QVariant> &messages)
{
switch (level)
{
case QxtLogger::ErrorLevel:
writeToFile("Error", messages);
break;
case QxtLogger::WarningLevel:
writeToFile("Warning", messages);
break;
case QxtLogger::CriticalLevel:
writeToFile("Critical", messages);
break;
case QxtLogger::FatalLevel:
writeToFile("Fatal", messages);
break;
case QxtLogger::TraceLevel:
writeToFile("Trace", messages);
break;
case QxtLogger::DebugLevel:
writeToFile("Debug", messages);
break;
case QxtLogger::InfoLevel:
writeToFile("Info", messages);
break;
default:
writeToFile(QString(), messages);
break;
}
}
/*!
Sets the log \a fileName.
*/
void QxtAbstractFileLoggerEngine::setLogFileName(const QString &fileName)
{
qxt_d().logFile = fileName;
initLoggerEngine();
}
/*!
Returns the log file name.
*/
QString QxtAbstractFileLoggerEngine::logFileName() const
{
return qxt_d().logFile;
}
/*!
\fn virtual void QxtAbstractFileLoggerEngine::writeToFile( const QString &level, const QVariantList &messages ) = 0
Writes \a messages to file with given \a level.
This function is called by QxtAbstractFileLoggerEngine. Reimplement this function when creating a subclass of QxtAbstractFileLoggerEngine.
*/

View File

@ -1,55 +0,0 @@
/****************************************************************************
**
** Copyright (C) Qxt Foundation. Some rights reserved.
**
** This file is part of the QxtCore module of the Qxt library.
**
** This library is free software; you can redistribute it and/or modify it
** under the terms of the Common Public License, version 1.0, as published
** by IBM, and/or under the terms of the GNU Lesser General Public License,
** version 2.1, as published by the Free Software Foundation.
**
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
** FITNESS FOR A PARTICULAR PURPOSE.
**
** You should have received a copy of the CPL and the LGPL along with this
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
** included with the source distribution for more information.
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
**
** <http://libqxt.org> <foundation@libqxt.org>
**
****************************************************************************/
#ifndef QXTABSTRACTFILELOGGERENGINE_H
#define QXTABSTRACTFILELOGGERENGINE_H
#include "qxtabstractiologgerengine.h"
#include "qxtglobal.h"
class QxtAbstractFileLoggerEnginePrivate;
class QXT_CORE_EXPORT QxtAbstractFileLoggerEngine : public QxtAbstractIOLoggerEngine
{
QXT_DECLARE_PRIVATE(QxtAbstractFileLoggerEngine)
public:
QxtAbstractFileLoggerEngine(const QString &fileName, QIODevice::OpenMode mode);
~QxtAbstractFileLoggerEngine();
virtual void initLoggerEngine();
virtual void killLoggerEngine();
virtual bool isInitialized() const;
virtual void writeFormatted(QxtLogger::LogLevel level, const QList<QVariant> &messages);
void setLogFileName(const QString &fileName);
QString logFileName() const;
protected:
virtual void writeToFile(const QString &level, const QVariantList &messages) = 0;
};
#endif // QXTABSTRACTFILELOGGERENGINE_H

View File

@ -1,74 +0,0 @@
/****************************************************************************
**
** Copyright (C) Qxt Foundation. Some rights reserved.
**
** This file is part of the QxtCore module of the Qxt library.
**
** This library is free software; you can redistribute it and/or modify it
** under the terms of the Common Public License, version 1.0, as published
** by IBM, and/or under the terms of the GNU Lesser General Public License,
** version 2.1, as published by the Free Software Foundation.
**
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
** FITNESS FOR A PARTICULAR PURPOSE.
**
** You should have received a copy of the CPL and the LGPL along with this
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
** included with the source distribution for more information.
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
**
** <http://libqxt.org> <foundation@libqxt.org>
**
****************************************************************************/
#include "qxtabstractiologgerengine.h"
/*!
\class QxtAbstractIOLoggerEngine
\brief The QxtAbstractIOLoggerEngine class is the base class of IO logger engines.
\inmodule QxtCore
\sa QxtLogger
*/
class QxtAbstractIOLoggerEnginePrivate : public QxtPrivate<QxtAbstractIOLoggerEngine>
{
QXT_DECLARE_PUBLIC(QxtAbstractIOLoggerEngine)
public:
QxtAbstractIOLoggerEnginePrivate();
QIODevice *io_device;
};
QxtAbstractIOLoggerEnginePrivate::QxtAbstractIOLoggerEnginePrivate()
: io_device(0)
{
}
/*!
Constructs a QxtAbstractIOLoggerEngine with \a device.
*/
QxtAbstractIOLoggerEngine::QxtAbstractIOLoggerEngine(QIODevice *device)
{
QXT_INIT_PRIVATE(QxtAbstractFileLoggerEngine);
setDevice(device);
}
/*!
Sets the IO \a device.
*/
void QxtAbstractIOLoggerEngine::setDevice(QIODevice *device)
{
qxt_d().io_device = device;
}
/*!
Returns the IO device.
*/
QIODevice *QxtAbstractIOLoggerEngine::device() const
{
return qxt_d().io_device;
}

View File

@ -1,45 +0,0 @@
/****************************************************************************
**
** Copyright (C) Qxt Foundation. Some rights reserved.
**
** This file is part of the QxtCore module of the Qxt library.
**
** This library is free software; you can redistribute it and/or modify it
** under the terms of the Common Public License, version 1.0, as published
** by IBM, and/or under the terms of the GNU Lesser General Public License,
** version 2.1, as published by the Free Software Foundation.
**
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
** FITNESS FOR A PARTICULAR PURPOSE.
**
** You should have received a copy of the CPL and the LGPL along with this
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
** included with the source distribution for more information.
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
**
** <http://libqxt.org> <foundation@libqxt.org>
**
****************************************************************************/
#ifndef QXTABSTRACTIOLOGGERENGINE_H
#define QXTABSTRACTIOLOGGERENGINE_H
#include "qxtloggerengine.h"
#include "qxtglobal.h"
class QxtAbstractIOLoggerEnginePrivate;
class QXT_CORE_EXPORT QxtAbstractIOLoggerEngine : public QxtLoggerEngine
{
QXT_DECLARE_PRIVATE(QxtAbstractIOLoggerEngine)
public:
QxtAbstractIOLoggerEngine(QIODevice *device = 0);
void setDevice(QIODevice *device);
QIODevice* device() const;
};
#endif // QXTABSTRACTIOLOGGERENGINE_H

Some files were not shown because too many files have changed in this diff Show More