Integrated changes for framework

Pdm fields can contain a forward declared Pdm object without the include
file
VizFwk: Added VertexColoring shader to be able to use per vertex color
used from drawableGeo::setColorArray()
This commit is contained in:
Magne Sjaastad
2014-04-11 11:06:42 +02:00
parent 4125ab3ae8
commit 486f383de7
68 changed files with 2177 additions and 88 deletions

View File

@@ -31,5 +31,6 @@ add_library( ${PROJECT_NAME}
cafPdmUiOrdering.h
cafPdmUiTreeOrdering.cpp
cafPdmUiTreeOrdering.h
cafPdmUiTreeEditorHandle.h
cafPdmUiTreeEditorHandle.cpp
)

View File

@@ -171,7 +171,7 @@ class PdmField <DataType*> : public PdmFieldHandle
{
typedef DataType* DataTypePtr;
public:
PdmField() : PdmFieldHandle() { m_fieldValue = NULL; }
PdmField() : PdmFieldHandle() { }
PdmField(const PdmField& other);
PdmField(const DataTypePtr& fieldValue);
virtual ~PdmField();

View File

@@ -292,7 +292,7 @@ void caf::PdmField<DataType*>::readFieldData(QXmlStreamReader& xmlStream)
}
else
{
if (dynamic_cast<DataType *>(obj) == NULL)
if (obj->classKeyword() != className)
{
assert(false); // Inconsistency in the factory. It creates objects of wrong type from the ClassKeyword
@@ -341,7 +341,7 @@ void caf::PdmField<DataType*>::readFieldData(QXmlStreamReader& xmlStream)
template<typename DataType >
void caf::PdmField<DataType*>::writeFieldData(QXmlStreamWriter& xmlStream)
{
if (m_fieldValue == NULL) return;
if (m_fieldValue.rawPtr() == NULL) return;
QString className = m_fieldValue.rawPtr()->classKeyword();
@@ -397,7 +397,7 @@ template<typename DataType >
caf::PdmField<DataType*>::~PdmField()
{
if (!m_fieldValue.isNull()) m_fieldValue.rawPtr()->removeParentField(this);
m_fieldValue = NULL;
m_fieldValue.setRawPtr(NULL);
}
//--------------------------------------------------------------------------------------------------
@@ -553,7 +553,6 @@ size_t PdmPointersField<DataType*>::count(const DataType* pointer) const
template<typename DataType>
void PdmPointersField<DataType*>::clear()
{
this->removeThisAsParentField();
m_pointers.clear();
}
@@ -567,7 +566,7 @@ void PdmPointersField<DataType*>::deleteAllChildObjects()
size_t index;
for (index = 0; index < m_pointers.size(); ++index)
{
delete(m_pointers[index]);
delete(m_pointers[index].rawPtr());
}
m_pointers.clear();
@@ -579,7 +578,11 @@ void PdmPointersField<DataType*>::deleteAllChildObjects()
template<typename DataType>
void PdmPointersField<DataType*>::erase(size_t index)
{
if (m_pointers[index]) m_pointers[index]->removeParentField(this);
if (m_pointers[index])
{
m_pointers[index]->removeParentField(this);
}
m_pointers.erase(m_pointers.begin() + index);
}
@@ -589,21 +592,23 @@ void PdmPointersField<DataType*>::erase(size_t index)
template<typename DataType>
void PdmPointersField<DataType*>::removeChildObject(PdmObject* object)
{
DataType* pointer = dynamic_cast<DataType*>(object);
size_t index;
std::vector< PdmPointer<DataType> > tempPointers;
tempPointers = m_pointers;
m_pointers.clear();
for (index = 0; index < tempPointers.size(); ++index)
for (size_t index = 0; index < tempPointers.size(); ++index)
{
if (tempPointers[index] != pointer)
if (tempPointers[index].rawPtr() != object)
{
m_pointers.push_back(tempPointers[index]);
}
else
{
if (tempPointers[index]) tempPointers[index]->removeParentField(this);
if (tempPointers[index].rawPtr())
{
tempPointers[index].rawPtr()->removeParentField(this);
}
}
}
}
@@ -618,12 +623,12 @@ template<typename DataType>
typename std::vector< PdmPointer<DataType> >::iterator it;
for (it = m_pointers.begin(); it != m_pointers.end(); ++it)
{
if (*it == NULL) continue;
if (it->rawPtr() == NULL) continue;
QString className = (*it)->classKeyword();
QString className = it->rawPtr()->classKeyword();
xmlStream.writeStartElement("", className);
(*it)->writeFields(xmlStream);
it->rawPtr()->writeFields(xmlStream);
xmlStream.writeEndElement();
}
}
@@ -661,9 +666,7 @@ template<typename DataType>
continue;
}
currentObject = dynamic_cast<DataType *> (obj);
if (currentObject == NULL)
if (obj->classKeyword() != className)
{
assert(false); // There is an inconsistency in the factory. It creates objects of type not matching the ClassKeyword
@@ -678,8 +681,11 @@ template<typename DataType>
continue;
}
currentObject->readFields(xmlStream);
this->push_back(currentObject);
obj->readFields(xmlStream);
m_pointers.push_back(PdmPointer<DataType>());
m_pointers.back().setRawPtr(obj);
obj->addParentField(this);
// Jump off the end element, and head for next start element (or the final EndElement of the field)
// Qt reports a character token between EndElements and StartElements so skip it
@@ -700,7 +706,7 @@ void PdmPointersField<DataType*>::childObjects(std::vector<PdmObject*>* objects)
size_t i;
for (i = 0; i < m_pointers.size(); ++i)
{
objects->push_back(m_pointers[i]);
objects->push_back(m_pointers[i].rawPtr());
}
}
@@ -715,7 +721,7 @@ void PdmPointersField<DataType*>::removeThisAsParentField()
{
if (!it->isNull())
{
(*it)->removeParentField(this);
it->rawPtr()->removeParentField(this);
}
}
}

View File

@@ -421,7 +421,7 @@ PdmUiTreeOrdering* PdmObject::uiTreeOrdering(QString uiConfigName /*= ""*/)
}
}
expandUiTree(uiTreeOrdering, uiConfigName);
addUiTreeChildren(uiTreeOrdering, uiConfigName);
return uiTreeOrdering;
}
@@ -429,13 +429,13 @@ PdmUiTreeOrdering* PdmObject::uiTreeOrdering(QString uiConfigName /*= ""*/)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmObject::expandUiTree(PdmUiTreeOrdering* root, QString uiConfigName /*= "" */)
void PdmObject::addUiTreeChildren(PdmUiTreeOrdering* root, QString uiConfigName /*= "" */)
{
if (!root) return;
if ( root->childCount() == 0)
if ( root->childCount() == 0) // This means that no one has tried to expand it.
{
if (!root->isSubTreeDefined() && root->dataObject())
if (!root->ignoreSubTree() && root->dataObject())
{
if (root->m_field && !root->m_field->isUiChildrenHidden(uiConfigName))
@@ -449,7 +449,7 @@ void PdmObject::expandUiTree(PdmUiTreeOrdering* root, QString uiConfigName /*= "
}
else
{
root->dataObject()->defineUiTreeOrdering(*root, uiConfigName);
root->object()->defineUiTreeOrdering(*root, uiConfigName);
}
}
}
@@ -457,9 +457,9 @@ void PdmObject::expandUiTree(PdmUiTreeOrdering* root, QString uiConfigName /*= "
for (int cIdx = 0; cIdx < root->childCount(); ++cIdx)
{
PdmUiTreeOrdering* child = dynamic_cast<PdmUiTreeOrdering*>(root->child(cIdx));
if (!child->isSubTreeDefined())
if (!child->ignoreSubTree())
{
expandUiTree(child);
addUiTreeChildren(child);
}
}
}

View File

@@ -255,7 +255,7 @@ private:
private:
/// Recursive function to traverse and create a Ui tree representation of the object hierarchy
static void expandUiTree( PdmUiTreeOrdering* root, QString uiConfigName = "" );
static void addUiTreeChildren( PdmUiTreeOrdering* root, QString uiConfigName = "" );
private:
std::multiset<PdmFieldHandle*> m_parentFields;

View File

@@ -59,6 +59,8 @@ QWidget* PdmUiObjectEditorHandle::getOrCreateWidget(QWidget* parent)
//--------------------------------------------------------------------------------------------------
void PdmUiObjectEditorHandle::setPdmObject(PdmObject* object)
{
cleanupBeforeSettingPdmObject();
this->bindToPdmItem(object);
}

View File

@@ -66,6 +66,7 @@ public:
protected:
virtual QWidget* createWidget(QWidget* parent) = 0;
virtual void cleanupBeforeSettingPdmObject() {};
protected:
QPointer<QWidget> m_widget;

View File

@@ -0,0 +1,76 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// 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 at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cafPdmUiTreeEditorHandle.h"
#include "cafPdmObject.h"
namespace caf
{
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget* PdmUiTreeEditorHandle::getOrCreateWidget(QWidget* parent)
{
if (m_widget.isNull())
{
m_widget = this->createWidget(parent);
}
return m_widget;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeEditorHandle::setPdmItemRoot(PdmUiItem* root)
{
cleanupBeforeSettingPdmObject();
this->bindToPdmItem(root);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiItem* PdmUiTreeEditorHandle::pdmItemRoot()
{
return this->pdmItem();
}
} //End of namespace caf

View File

@@ -0,0 +1,78 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// 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 at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include <vector>
#include <QString>
#include <QWidget>
#include <QPointer>
#include "cafPdmUiEditorHandle.h"
#include "cafPdmPointer.h"
namespace caf
{
class PdmObject;
//==================================================================================================
/// Abstract class to handle editors for complete PdmObjects
//==================================================================================================
class PdmUiTreeEditorHandle: public PdmUiEditorHandle
{
public:
PdmUiTreeEditorHandle() {}
~PdmUiTreeEditorHandle() {}
QWidget* getOrCreateWidget(QWidget* parent);
QWidget* widget() { return m_widget; }
void setPdmItemRoot(PdmUiItem* root);
PdmUiItem* pdmItemRoot();
protected:
virtual QWidget* createWidget(QWidget* parent) = 0;
virtual void cleanupBeforeSettingPdmObject() {};
protected:
QPointer<QWidget> m_widget;
};
} // End of namespace caf

View File

@@ -65,7 +65,11 @@ namespace caf
PdmUiTreeOrdering* PdmUiTreeOrdering::add(const QString & title, const QString& iconResourceName)
{
PdmUiTreeOrdering* to = new PdmUiTreeOrdering(this, -1, NULL);
to->m_uiInfo = new PdmUiItemInfo(title, QIcon(iconResourceName));
to->m_uiItem = new PdmUiItem();
to->m_uiItem->setUiName(title);
to->m_uiItem->setUiIcon(QIcon(iconResourceName));
return to;
}
@@ -98,7 +102,7 @@ namespace caf
{
PdmUiTreeOrdering* child = dynamic_cast<PdmUiTreeOrdering*>(this->child(cIdx));
if (child->dataObject() == object)
if (child->object() == object)
{
return true;
}
@@ -112,15 +116,27 @@ namespace caf
/// Creates an new PdmUiTreeOrdering item, and adds it to parent. If position is -1, it is added
/// at the end of parents existing child list.
//--------------------------------------------------------------------------------------------------
PdmUiTreeOrdering::PdmUiTreeOrdering(PdmUiTreeOrdering* parent /*= NULL*/, int position /*= -1*/, PdmObject* dataObject /*= NULL*/) : UiTreeItem< PdmPointer<PdmObject> >(parent, position, dataObject),
PdmUiTreeOrdering::PdmUiTreeOrdering(PdmUiTreeOrdering* parent /*= NULL*/, int position /*= -1*/, PdmObject* dataObject /*= NULL*/) : PdmUiTreeItem(parent, position, this),
m_field(NULL),
m_uiInfo(NULL),
m_forgetRemainingFields(false),
m_isSubTreeDefined(false)
m_isToIgnoreSubTree(false),
m_uiItem(NULL),
m_object(dataObject)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiTreeOrdering::~PdmUiTreeOrdering()
{
if (m_uiItem)
{
delete m_uiItem;
}
}
} //End of namespace caf

View File

@@ -49,16 +49,19 @@ namespace caf
class PdmObject;
class PdmFieldHandle;
//typedef UiTreeItem<PdmPointer<PdmObject> > PdmUiTreeItem;
class PdmUiTreeOrdering;
typedef UiTreeItem<PdmUiTreeOrdering* > PdmUiTreeItem;
//==================================================================================================
/// Class storing a tree structure representation of some PdmObject hierarchy to be used for tree views in the Gui
//==================================================================================================
class PdmUiTreeOrdering : public UiTreeItem< PdmPointer<PdmObject> >
class PdmUiTreeOrdering : public UiTreeItem< PdmUiTreeOrdering* >
{
public:
PdmUiTreeOrdering(PdmUiTreeOrdering* parent = NULL, int position = -1, PdmObject* dataObject = NULL);
~PdmUiTreeOrdering();
void add(PdmFieldHandle * field);
void add(PdmObject* object);
@@ -67,23 +70,26 @@ public:
/// If the rest of the fields containing children is supposed to be omitted, setForgetRemainingFileds to true.
void setForgetRemainingFields(bool val) { m_forgetRemainingFields = val; }
/// To stop the tree generation at this level, setSubTreeDefined to true
void setSubTreeDefined(bool isSubTreeDefined ) { m_isSubTreeDefined = isSubTreeDefined; }
void setIgnoreSubTree(bool doIgnoreSubTree ) { m_isToIgnoreSubTree = doIgnoreSubTree; }
PdmObject* object() const { return m_object; }
PdmFieldHandle* field() const { return m_field; }
PdmUiItem* uiItem() const { return m_uiItem; }
private:
friend class PdmObject;
bool forgetRemainingFields() const { return m_forgetRemainingFields; }
bool isSubTreeDefined() const { return m_isSubTreeDefined; }
bool ignoreSubTree() const { return m_isToIgnoreSubTree; }
bool containsField(const PdmFieldHandle* field);
bool containsObject(const PdmObject* object);
private:
PdmPointer<PdmObject> m_object;
PdmFieldHandle* m_field;
PdmUiItemInfo* m_uiInfo;
PdmUiItem* m_uiItem;
bool m_forgetRemainingFields;
bool m_isSubTreeDefined;
bool m_isToIgnoreSubTree;
};

View File

@@ -14,6 +14,9 @@ include_directories (
add_executable (${PROJECT_NAME}
cafPdmBasicTest.cpp
cafProjectDataModel_UnitTests.cpp
Child.cpp
Parent.cpp
TestObj.cpp
${CMAKE_SOURCE_DIR}/cafTests/gtest/gtest-all.cpp
)

View File

@@ -0,0 +1,13 @@
#include "Child.h"
#include "TestObj.h"
CAF_PDM_SOURCE_INIT(Child, "Child");
Child::Child()
{
CAF_PDM_InitFieldNoDefault(&m_testObj, "Numbers", "Important Numbers", "", "", "");
}
Child::~Child()
{
}

View File

@@ -0,0 +1,22 @@
#pragma once
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
class TestObj;
class Child: public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
Child();
~Child();
caf::PdmField<TestObj*> m_testObj;
};

View File

@@ -0,0 +1,32 @@
#include "Parent.h"
//#include "Child.h"
CAF_PDM_SOURCE_INIT(Parent, "Parent");
Parent::Parent()
{
CAF_PDM_InitFieldNoDefault(&m_simpleObjectsField, "SimpleObjects", "A child object", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_simpleObjectF, "SimpleObject", "A child object", "", "", "");
}
Parent::~Parent()
{
}
void Parent::doSome()
{
size_t i = m_simpleObjectsField.size();
if (i){
//Child* c = m_simpleObjectsField[0];
//TestObj* to = c->m_testObj();
}
}
#include <gtest/gtest.h>
TEST(IncludeTest, Basic)
{
Parent* p = new Parent;
delete(p);
}

View File

@@ -0,0 +1,52 @@
#pragma once
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
#if 0
class PdmPointerTarget
{
public:
PdmPointerTarget() {}
PdmPointerTarget(const PdmPointerTarget& ) {}
PdmPointerTarget& operator=(const PdmPointerTarget& ) {}
virtual ~PdmPointerTarget()
{
// Set all guarded pointers pointing to this to NULL
std::set<PdmObject**>::iterator it;
for (it = m_pointersReferencingMe.begin(); it != m_pointersReferencingMe.end() ; ++it)
{
(**it) = NULL;
}
}
private:
// Support system for PdmPointer
friend class PdmPointerImpl;
std::set<PdmPointerTarget**> m_pointersReferencingMe;
};
#endif
class Child;
class Parent: public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
Parent();
~Parent();
void doSome();
caf::PdmPointersField<Child*> m_simpleObjectsField;
caf::PdmField<Child*> m_simpleObjectF;
};

View File

@@ -0,0 +1,11 @@
#include "TestObj.h"
CAF_PDM_SOURCE_INIT(TestObj, "TestObj");
TestObj::TestObj()
{
CAF_PDM_InitObject("TestObj", "", "", "");
CAF_PDM_InitField(&m_position, "Position", 8765.2, "Position", "", "", "");
}
TestObj::~TestObj() {}

View File

@@ -0,0 +1,18 @@
#pragma once
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
class TestObj: public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
TestObj();
~TestObj();
caf::PdmField<double> m_position;
};

View File

@@ -25,6 +25,7 @@ set( QOBJECT_HEADERS
cafPdmUiPropertyView.h
cafPdmUiTreeView.h
cafPdmUiTreeViewModel.h
cafPdmUiListView.h
cafPdmUiListViewEditor.h
)
@@ -66,6 +67,8 @@ add_library( ${PROJECT_NAME}
cafPdmUiTextEditor.h
cafPdmUiTreeViewEditor.cpp
cafPdmUiTreeViewEditor.h
cafPdmUiTreeViewModel.cpp
cafPdmUiTreeViewModel.h
cafPdmUiTreeView.cpp
cafProgressInfo.cpp
cafProgressInfo.h

View File

@@ -0,0 +1,567 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2014 Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// 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 at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cafPdmUiTreeViewModel.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmUiTreeOrdering.h"
namespace caf
{
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiTreeViewModel::PdmUiTreeViewModel(QObject* parent)
{
m_treeItemRoot = NULL;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewModel::setTreeItemRoot(PdmUiTreeItem* root)
{
beginResetModel();
if (m_treeItemRoot)
{
delete m_treeItemRoot;
}
m_treeItemRoot = root;
endResetModel();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QModelIndex PdmUiTreeViewModel::index(int row, int column, const QModelIndex &parentIndex /*= QModelIndex( ) */) const
{
// if (!m_treeItemRoot)
// return QModelIndex();
if (!hasIndex(row, column, parentIndex))
return QModelIndex();
PdmUiTreeItem* parentItem = NULL;
if (!parentIndex.isValid())
parentItem = m_treeItemRoot;
else
parentItem = static_cast<PdmUiTreeItem*>(parentIndex.internalPointer());
PdmUiTreeItem* childItem = parentItem->child(row);
if (childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QModelIndex PdmUiTreeViewModel::parent(const QModelIndex &childIndex) const
{
// if (!m_treeItemRoot) return QModelIndex();
if (!childIndex.isValid()) return QModelIndex();
PdmUiTreeItem* childItem = static_cast<PdmUiTreeItem*>(childIndex.internalPointer());
if (!childItem) return QModelIndex();
PdmUiTreeItem* parentItem = childItem->parent();
if (!parentItem) return QModelIndex();
if (parentItem == m_treeItemRoot) return QModelIndex();
return createIndex(parentItem->row(), 0, parentItem);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int PdmUiTreeViewModel::rowCount(const QModelIndex &parentIndex /*= QModelIndex( ) */) const
{
if (!m_treeItemRoot)
return 0;
if (parentIndex.column() > 0)
return 0;
PdmUiTreeItem* parentItem;
if (!parentIndex.isValid())
parentItem = m_treeItemRoot;
else
parentItem = PdmUiTreeViewModel::getTreeItemFromIndex(parentIndex);
return parentItem->childCount();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int PdmUiTreeViewModel::columnCount(const QModelIndex &parentIndex /*= QModelIndex( ) */) const
{
if (!m_treeItemRoot)
return 0;
if (parentIndex.isValid())
{
PdmUiTreeItem* parentItem = PdmUiTreeViewModel::getTreeItemFromIndex(parentIndex);
if (parentItem)
{
return parentItem->columnCount();
}
else
{
return 0;
}
}
else
return m_treeItemRoot->columnCount();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QVariant PdmUiTreeViewModel::data(const QModelIndex &index, int role /*= Qt::DisplayRole */) const
{
if (!index.isValid())
return QVariant();
PdmUiTreeOrdering* uitreeOrdering = static_cast<PdmUiTreeOrdering*>(index.internalPointer());
if (!uitreeOrdering)
{
return QVariant();
}
PdmFieldHandle* pdmField = uitreeOrdering->field();
PdmObject* pdmObj = uitreeOrdering->object();
if (role == Qt::DisplayRole || role == Qt::EditRole)
{
if (pdmField && !pdmField->uiName().isEmpty())
{
return pdmField->uiName();
}
else if (pdmObj)
{
if (pdmObj->userDescriptionField())
return pdmObj->userDescriptionField()->uiValue();
else
return pdmObj->uiName();
}
else if (uitreeOrdering->uiItem())
{
return uitreeOrdering->uiItem()->uiName();
}
else
{
// Should not get here
assert(0);
}
}
else if (role == Qt::DecorationRole)
{
if (pdmField && !pdmField->uiIcon().isNull())
{
return pdmField->uiIcon();
}
else if (pdmObj)
{
return pdmObj->uiIcon();
}
else if (uitreeOrdering->uiItem())
{
return uitreeOrdering->uiItem()->uiIcon();
}
else
{
// Should not get here
assert(0);
}
}
else if (role == Qt::ToolTipRole)
{
if (pdmField && !pdmField->uiToolTip().isEmpty())
return pdmField->uiToolTip();
else if (pdmObj)
{
return pdmObj->uiToolTip();
}
else if (uitreeOrdering->uiItem())
{
return uitreeOrdering->uiItem()->uiToolTip();
}
else
{
// Should not get here
assert(0);
}
}
else if (role == Qt::WhatsThisRole)
{
if (pdmField && !pdmField->uiWhatsThis().isEmpty())
return pdmField->uiWhatsThis();
else if (pdmObj)
{
return pdmObj->uiWhatsThis();
}
else if (uitreeOrdering->uiItem())
{
return uitreeOrdering->uiItem()->uiWhatsThis();
}
else
{
// Should not get here
assert(0);
}
}
else if (role == Qt::CheckStateRole)
{
if (pdmObj && pdmObj->objectToggleField())
{
bool isToggledOn = pdmObj->objectToggleField()->uiValue().toBool();
if (isToggledOn)
{
return Qt::Checked;
}
else
{
return Qt::Unchecked;
}
}
}
return QVariant();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewModel::emitDataChanged(const QModelIndex& index)
{
emit dataChanged(index, index);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool PdmUiTreeViewModel::setData(const QModelIndex &index, const QVariant &value, int role /*= Qt::EditRole*/)
{
if (!index.isValid())
{
return false;
}
PdmUiTreeItem* treeItem = PdmUiTreeViewModel::getTreeItemFromIndex(index);
assert(treeItem);
PdmObject* obj = treeItem->dataObject()->object();
if (!obj)
{
return false;
}
if (role == Qt::EditRole && obj->userDescriptionField())
{
obj->userDescriptionField()->setValueFromUi(value);
emitDataChanged(index);
return true;
}
else if (role == Qt::CheckStateRole && obj->objectToggleField())
{
bool toggleOn = (value == Qt::Checked);
obj->objectToggleField()->setValueFromUi(toggleOn);
emitDataChanged(index);
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
/// Enable edit of this item if we have a editable user description field for a pdmObject
/// Disable edit for other items
//--------------------------------------------------------------------------------------------------
Qt::ItemFlags PdmUiTreeViewModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::ItemIsEnabled;
Qt::ItemFlags flagMask = QAbstractItemModel::flags(index);
PdmUiTreeItem* treeItem = getTreeItemFromIndex(index);
if (treeItem)
{
PdmObject* pdmObject = treeItem->dataObject()->object();
if (pdmObject)
{
if (pdmObject->userDescriptionField() && !pdmObject->userDescriptionField()->isUiReadOnly())
{
flagMask = flagMask | Qt::ItemIsEditable;
}
if (pdmObject->objectToggleField())
{
flagMask = flagMask | Qt::ItemIsUserCheckable;
}
if (pdmObject->isUiReadOnly())
{
flagMask = flagMask & (~Qt::ItemIsEnabled);
}
}
}
else
{
flagMask = flagMask & (~Qt::ItemIsEditable);
}
return flagMask;
}
//--------------------------------------------------------------------------------------------------
/// Refreshes the UI-tree below the supplied root PdmObject
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewModel::updateUiSubTree(PdmObject* pdmRoot)
{
// Build the new "Correct" Tree
PdmUiTreeOrdering* tempUpdatedPdmTree = pdmRoot->uiTreeOrdering();
// Find the corresponding entry for "root" in the existing Ui tree
QModelIndex uiSubTreeRootModelIdx = getModelIndexFromPdmObject(pdmRoot);
PdmUiTreeItem* uiModelSubTreeRoot = NULL;
if (uiSubTreeRootModelIdx.isValid())
{
uiModelSubTreeRoot = getTreeItemFromIndex(uiSubTreeRootModelIdx);
}
else
{
uiModelSubTreeRoot = m_treeItemRoot;
}
updateModelSubTree(uiSubTreeRootModelIdx, uiModelSubTreeRoot, tempUpdatedPdmTree);
delete tempUpdatedPdmTree;
}
//--------------------------------------------------------------------------------------------------
/// Makes the destinationSubTreeRoot tree become identical to the tree in sourceSubTreeRoot,
/// calling begin..() end..() to make the UI update accordingly.
/// This assumes that all the items have a pointer an unique PdmObject
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewModel::updateModelSubTree(const QModelIndex& modelIdxOfDestinationSubTreeRoot, PdmUiTreeItem* destinationSubTreeRoot, PdmUiTreeItem* sourceSubTreeRoot)
{
// First loop over children in the old ui tree, deleting the ones not present in
// the newUiTree
for (int resultChildIdx = 0; resultChildIdx < destinationSubTreeRoot->childCount() ; ++resultChildIdx)
{
PdmUiTreeItem* oldChild = destinationSubTreeRoot->child(resultChildIdx);
int childIndex = sourceSubTreeRoot->findChildItemIndex(oldChild->dataObject());
if (childIndex == -1) // Not found
{
this->beginRemoveRows(modelIdxOfDestinationSubTreeRoot, resultChildIdx, resultChildIdx);
destinationSubTreeRoot->removeChildren(resultChildIdx, 1);
this->endRemoveRows();
resultChildIdx--;
}
}
// Then loop over the children in the new ui tree, finding the corresponding items in the old tree.
// If they are found, we move them to the correct position.
// If not found, we pulls the item out of the old ui tree, inserting it into the new tree to avoid the default delete operation in ~UiTreeItem()
int sourceChildCount = sourceSubTreeRoot->childCount();
int sourceChildIdx = 0;
for (int resultChildIdx = 0; resultChildIdx < sourceChildCount; ++resultChildIdx, ++sourceChildIdx)
{
PdmUiTreeItem* newChild = sourceSubTreeRoot->child(sourceChildIdx);
int childIndex = destinationSubTreeRoot->findChildItemIndex(newChild->dataObject());
if (childIndex == -1) // Not found
{
this->beginInsertRows(modelIdxOfDestinationSubTreeRoot, resultChildIdx, resultChildIdx);
destinationSubTreeRoot->insertChild(resultChildIdx, newChild);
this->endInsertRows();
sourceSubTreeRoot->removeChildrenNoDelete(sourceChildIdx, 1);
sourceChildIdx--;
}
else if (childIndex != resultChildIdx) // Found, but must be moved
{
assert(childIndex > resultChildIdx);
PdmUiTreeItem* oldChild = destinationSubTreeRoot->child(childIndex);
this->beginMoveRows(modelIdxOfDestinationSubTreeRoot, childIndex, childIndex, modelIdxOfDestinationSubTreeRoot, resultChildIdx);
destinationSubTreeRoot->removeChildrenNoDelete(childIndex, 1);
destinationSubTreeRoot->insertChild(resultChildIdx, oldChild);
this->endMoveRows();
updateModelSubTree( index(resultChildIdx, 0, modelIdxOfDestinationSubTreeRoot), oldChild, newChild);
}
else // Found the corresponding item in the right place.
{
PdmUiTreeItem* oldChild = destinationSubTreeRoot->child(childIndex);
updateModelSubTree( index(resultChildIdx, 0, modelIdxOfDestinationSubTreeRoot), oldChild, newChild);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiTreeItem* PdmUiTreeViewModel::treeItemRoot()
{
return m_treeItemRoot;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewModel::notifyModelChanged()
{
QModelIndex startModelIdx = index(0,0);
QModelIndex endModelIdx = index(rowCount(startModelIdx), 0);
emit dataChanged(startModelIdx, endModelIdx);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QVariant PdmUiTreeViewModel::headerData(int section, Qt::Orientation orientation, int role /*= Qt::DisplayRole */) const
{
if (role != Qt::DisplayRole)
return QVariant();
if (section < m_columnHeaders.size())
{
return m_columnHeaders[section];
}
return QVariant();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewModel::setColumnHeaders(const QStringList& columnHeaders)
{
m_columnHeaders = columnHeaders;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiTreeItem* caf::PdmUiTreeViewModel::getTreeItemFromIndex(const QModelIndex& index)
{
if (index.isValid())
{
assert(index.internalPointer());
PdmUiTreeItem* treeItem = static_cast<PdmUiTreeItem*>(index.internalPointer());
return treeItem;
}
return NULL;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QModelIndex caf::PdmUiTreeViewModel::getModelIndexFromPdmObjectRecursive(const QModelIndex& currentIndex, const PdmObject * object) const
{
if (currentIndex.internalPointer())
{
PdmUiTreeItem* treeItem = static_cast<PdmUiTreeItem*>(currentIndex.internalPointer());
if (treeItem->dataObject()->object() == object) return currentIndex;
}
int row;
for (row = 0; row < rowCount(currentIndex); ++row)
{
QModelIndex foundIndex = getModelIndexFromPdmObjectRecursive(index(row, 0, currentIndex), object);
if (foundIndex.isValid()) return foundIndex;
}
return QModelIndex();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QModelIndex caf::PdmUiTreeViewModel::getModelIndexFromPdmObject( const PdmObject * object) const
{
QModelIndex foundIndex;
int numRows = rowCount(QModelIndex());
int r = 0;
while (r < numRows && !foundIndex.isValid())
{
foundIndex = getModelIndexFromPdmObjectRecursive(index(r, 0, QModelIndex()), object);
++r;
}
return foundIndex;
}
} // end namespace caf

View File

@@ -0,0 +1,114 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2014 Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// 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 at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cafUiTreeItem.h"
#include <QAbstractItemModel>
#include <QStringList>
#include <assert.h>
#include "cafPdmPointer.h"
namespace caf
{
class PdmObject;
//typedef UiTreeItem<PdmPointer<PdmObject> > PdmUiTreeItem;
class PdmUiTreeOrdering;
typedef UiTreeItem<PdmUiTreeOrdering* > PdmUiTreeItem;
//==================================================================================================
//
// This class is intended to replace UiTreeModelPdm (cafUiTreeModelPdm)
//
//==================================================================================================
class PdmUiTreeViewModel : public QAbstractItemModel
{
Q_OBJECT
public:
PdmUiTreeViewModel(QObject* parent);
void setTreeItemRoot(PdmUiTreeItem* root);
PdmUiTreeItem* treeItemRoot();
void emitDataChanged(const QModelIndex& index);
static PdmUiTreeItem* getTreeItemFromIndex(const QModelIndex& index);
QModelIndex getModelIndexFromPdmObject(const PdmObject* object) const;
void updateUiSubTree(PdmObject* root);
void notifyModelChanged();
void setColumnHeaders(const QStringList& columnHeaders);
public:
// Overrides from QAbstractItemModel
virtual QModelIndex index(int row, int column, const QModelIndex &parentIndex = QModelIndex( )) const;
virtual QModelIndex parent(const QModelIndex &index) const;
virtual int rowCount(const QModelIndex &parentIndex = QModelIndex( ) ) const;
virtual int columnCount(const QModelIndex &parentIndex = QModelIndex( ) ) const;
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole ) const;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
protected:
QModelIndex getModelIndexFromPdmObjectRecursive(const QModelIndex& currentIndex, const PdmObject * object) const;
private:
void updateModelSubTree(const QModelIndex& uiSubTreeRootModelIdx, PdmUiTreeItem* uiModelSubTreeRoot, PdmUiTreeItem* updatedPdmSubTreeRoot);
PdmUiTreeItem* m_treeItemRoot;
QStringList m_columnHeaders;
};
//==================================================================================================
///
//==================================================================================================
class UiTreeItemBuilderPdm
{
public:
static PdmUiTreeItem* buildViewItems(PdmUiTreeItem* parentTreeItem, int position, caf::PdmObject* object);
};
} // End of namespace caf

View File

@@ -69,7 +69,11 @@ if (MSVC)
# Setup the our STRICT compile flags
# These are the flags we would like to use on all of our own libraries
set(CEE_STRICT_CXX_FLAGS "${CEE_BASE_CXX_FLAGS} /Wall")
if (${MSVC_VERSION} LESS 1600)
set(CEE_STRICT_CXX_FLAGS "${CEE_BASE_CXX_FLAGS} /W4")
elseif()
set(CEE_STRICT_CXX_FLAGS "${CEE_BASE_CXX_FLAGS} /Wall")
endif()
# Must add base warning level after setting up strict
set(CEE_BASE_CXX_FLAGS "${CEE_BASE_CXX_FLAGS} /W3")

View File

@@ -23,6 +23,13 @@ if (CEE_STAND_ALONE)
endif()
# Allow use of non-threadsafe reference counter in cvf::Object on systems with no atomics support
option(CEE_WORKAROUND_ON_SYSTEMS_WITHOUT_ATOMICS "Allow use of non-threadsafe reference counter on systems with no atomics support" OFF)
if (CEE_WORKAROUND_ON_SYSTEMS_WITHOUT_ATOMICS)
add_definitions(-DCVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS)
endif()
add_subdirectory(LibCore)
add_subdirectory(LibIo)
add_subdirectory(LibGeometry)

View File

@@ -6,13 +6,13 @@ project(LibCore)
# Use our strict compile flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CEE_STRICT_CXX_FLAGS}")
set(CEE_HEADER_FILES
cvfArray.h
cvfArray.inl
cvfArrayWrapperConst.h
cvfArrayWrapperToEdit.h
cvfAssert.h
cvfAtomicCounter.h
cvfBase.h
cvfBase64.h
cvfCharArray.h
@@ -68,6 +68,7 @@ cvfVersion.h
set(CEE_SOURCE_FILES
cvfAssert.cpp
cvfAtomicCounter.cpp
cvfBase64.cpp
cvfCharArray.cpp
cvfCodeLocation.cpp

View File

@@ -232,6 +232,7 @@
<ClInclude Include="cvfArrayWrapperConst.h" />
<ClInclude Include="cvfArrayWrapperToEdit.h" />
<ClInclude Include="cvfAssert.h" />
<ClInclude Include="cvfAtomicCounter.h" />
<ClInclude Include="cvfBase.h" />
<ClInclude Include="cvfBase64.h" />
<ClInclude Include="cvfCharArray.h" />
@@ -290,6 +291,7 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="cvfAssert.cpp" />
<ClCompile Include="cvfAtomicCounter.cpp" />
<ClCompile Include="cvfBase64.cpp" />
<ClCompile Include="cvfCharArray.cpp" />
<ClCompile Include="cvfCodeLocation.cpp" />

View File

@@ -45,6 +45,7 @@
<ClInclude Include="cvfArrayWrapperConst.h" />
<ClInclude Include="cvfArrayWrapperToEdit.h" />
<ClInclude Include="cvfProgramOptions.h" />
<ClInclude Include="cvfAtomicCounter.h" />
</ItemGroup>
<ItemGroup>
<None Include="cvfArray.inl" />
@@ -90,5 +91,6 @@
<ClCompile Include="cvfLogDestinationConsole.cpp" />
<ClCompile Include="cvfLogDestinationFile.cpp" />
<ClCompile Include="cvfProgramOptions.cpp" />
<ClCompile Include="cvfAtomicCounter.cpp" />
</ItemGroup>
</Project>
</Project>

View File

@@ -151,3 +151,4 @@ inline const ArrayWrapperConst< const ElmType*, ElmType > wrapArrayConst( ElmTy
}
}

View File

@@ -130,3 +130,4 @@ inline ArrayWrapperToEdit< ElmType*, ElmType > wrapArrayToEdit(ElmType* array, s
}
}

View File

@@ -113,9 +113,11 @@ Assert::FailAction AssertHandlerConsole::handleAssert(const char* fileName, int
// Does the job on both Windows and Linux (creates a console on Windows if one doesn't exist)
reportToConsole(fileName, lineNumber, expr, msg);
#ifdef WIN32
if (::IsDebuggerPresent())
{
#ifdef _MSC_VER
#if (_MSC_VER >= 1600)
if (::IsDebuggerPresent())
#endif
{
__debugbreak();
}
#endif

View File

@@ -0,0 +1,193 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2014 Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// 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 at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfAtomicCounter.h"
// Some older GCC version do not support atomics, we have seen this for RHEL5
#if defined(CVF_ATOMIC_COUNTER_CLASS_EXISTS)
namespace cvf {
#ifdef WIN32
#pragma warning (push)
#pragma warning (disable: 4668)
#include <windows.h>
#pragma warning (pop)
AtomicCounter::AtomicCounter(int initialValue)
: m_counter(initialValue)
{
}
AtomicCounter::~AtomicCounter()
{
}
AtomicCounter::operator int () const
{
return m_counter;
}
int AtomicCounter::operator ++ () // prefix
{
return InterlockedIncrement(&m_counter);
}
int AtomicCounter::operator ++ (int) // postfix
{
int result = InterlockedIncrement(&m_counter);
return --result;
}
int AtomicCounter::operator -- () // prefix
{
return InterlockedDecrement(&m_counter);
}
int AtomicCounter::operator -- (int) // postfix
{
int result = InterlockedDecrement(&m_counter);
return ++result;
}
#elif defined(CVF_IOS) || defined(CVF_OSX)
AtomicCounter::AtomicCounter(int initialValue)
: m_counter(initialValue)
{
}
AtomicCounter::AtomicCounter(const AtomicCounter& counter)
: m_counter(counter.value())
{
}
AtomicCounter::~AtomicCounter()
{
}
AtomicCounter::operator int () const
{
return m_counter;
}
int AtomicCounter::operator ++ () // prefix
{
return OSAtomicIncrement32(&m_counter);
}
int AtomicCounter::operator ++ (int) // postfix
{
int result = OSAtomicIncrement32(&m_counter);
return --result;
}
int AtomicCounter::operator -- () // prefix
{
return OSAtomicDecrement32(&m_counter);
}
int AtomicCounter::operator -- (int) // postfix
{
int result = OSAtomicDecrement32(&m_counter);
return ++result;
}
#elif defined(CVF_HAVE_GCC_ATOMICS)
AtomicCounter::AtomicCounter(int initialValue)
: m_counter(initialValue)
{
}
AtomicCounter::~AtomicCounter()
{
}
AtomicCounter::operator int () const
{
return m_counter;
}
int AtomicCounter::operator ++ () // prefix
{
return __sync_add_and_fetch(&m_counter, 1);
}
int AtomicCounter::operator ++ (int) // postfix
{
return __sync_fetch_and_add(&m_counter, 1);
}
int AtomicCounter::operator -- () // prefix
{
return __sync_sub_and_fetch(&m_counter, 1);
}
int AtomicCounter::operator -- (int) // postfix
{
return __sync_fetch_and_sub(&m_counter, 1);
}
#endif
} // namespace cvf
#endif // CVF_ATOMICS_COMPILED

View File

@@ -0,0 +1,96 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2014 Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// 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 at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfBase.h"
#ifdef WIN32
#define CVF_ATOMIC_COUNTER_CLASS_EXISTS
#elif defined(CVF_IOS) || defined(CVF_OSX)
#include <libkern/OSAtomic.h>
#define CVF_ATOMIC_COUNTER_CLASS_EXISTS
#elif defined __GNUC__
#if (CVF_GCC_VER >= 40200) && (defined(__x86_64__) || defined(__i386__))
#define CVF_HAVE_GCC_ATOMICS
#define CVF_ATOMIC_COUNTER_CLASS_EXISTS
#elif (CVF_GCC_VER >= 40300)
#define CVF_HAVE_GCC_ATOMICS
#define CVF_ATOMIC_COUNTER_CLASS_EXISTS
#endif
#endif
#if defined(CVF_ATOMIC_COUNTER_CLASS_EXISTS)
namespace cvf {
// Inspired by Poco
class AtomicCounter
{
public:
explicit AtomicCounter(int initialValue);
~AtomicCounter();
operator int () const;
int operator ++ (); // prefix
int operator ++ (int); // postfix
int operator -- (); // prefix
int operator -- (int); // postfix
private:
CVF_DISABLE_COPY_AND_ASSIGN(AtomicCounter);
#ifdef WIN32
typedef volatile long ImplType;
#elif defined(CVF_IOS) || defined(CVF_OSX)
typedef int32_t ImplType;
#else
typedef int ImplType;
#endif
ImplType m_counter;
};
} // namespace cvf
#endif

View File

@@ -44,7 +44,7 @@
// Global include file with definitions useful for all library files
// Disable some annoying warnings so we can compile with warning level Wall
#ifdef WIN32
#ifdef _MSC_VER
// 4512 'class' : assignment operator could not be generated : Due to problems with classes with reference member variables (e.g. VertexCompactor)
// 4514 unreferenced inline/local function has been removed
// 4625 copy constructor could not be generated because a base class copy constructor is inaccessible
@@ -54,13 +54,26 @@
// 4711 function 'func_name' selected for automatic inline expansion
// 4738 storing 32-bit float result in memory, possible loss of performance
// 4820 'bytes' bytes padding added after construct 'member_name'
#pragma warning (disable: 4512 4514 4625 4626 4640 4710 4711 4738 4820)
#if (_MSC_VER >= 1600)
// VS2010 and newer
// 4986 'operator new[]': exception specification does not match previous declaration
#pragma warning (disable: 4512 4514 4625 4626 4640 4710 4711 4738 4820 4986)
#pragma warning (disable: 4986)
#endif
#endif
// Makes it easier to check on the current GCC version
#ifdef __GNUC__
// 40302 means version 4.3.2.
# define CVF_GCC_VER (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__)
#endif
// Helper macro to disable (ignore) compiler warnings on GCC
// The needed pragma is only available in GCC for versions 4.2.x and above
#if defined __GNUC__ && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 402)
#if defined(__GNUC__) && (CVF_GCC_VER >= 40200)
#define CVF_DO_PRAGMA(x) _Pragma(#x)
#define CVF_GCC_DIAGNOSTIC_IGNORE(OPTION_STRING) CVF_DO_PRAGMA(GCC diagnostic ignored OPTION_STRING)
#else

View File

@@ -41,6 +41,15 @@
#include <set>
#include "cvfAtomicCounter.h"
#if defined(CVF_ATOMIC_COUNTER_CLASS_EXISTS) && defined(CVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS)
#error Two mutually exclusive defines detected : CVF_ATOMIC_COUNTER_CLASS_EXISTS && CVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS
#endif
#if !defined(CVF_ATOMIC_COUNTER_CLASS_EXISTS) && !defined(CVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS)
#error No support for atomics. Define CVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS to be able to compile
#endif
namespace cvf {
@@ -65,7 +74,13 @@ public:
static void dumpActiveObjectInstances();
private:
#if defined(CVF_ATOMIC_COUNTER_CLASS_EXISTS)
mutable AtomicCounter m_refCount;
#elif defined(CVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS)
mutable int m_refCount;
#endif
CVF_DISABLE_COPY_AND_ASSIGN(Object);
};

View File

@@ -91,9 +91,7 @@ inline int Object::release() const
CVF_TIGHT_ASSERT(m_refCount > 0);
m_refCount--;
if (m_refCount == 0)
if (--m_refCount == 0)
{
delete this;
return 0;

View File

@@ -205,7 +205,7 @@ bool Plane::setFromPointAndNormal(const Vec3d& point, const Vec3d& normal)
/// \param p2 Second point on the plane
/// \param p3 Third point on the plane
///
/// \return true if successfully set. false if points are on the same line.
/// \return true if successfully set. false if points are on the same line.
///
/// The three points must be different from each other and cannot be on the same line in space
//--------------------------------------------------------------------------------------------------
@@ -322,7 +322,7 @@ double Plane::distanceToOrigin() const
/// \param vector Vector to be projected
/// \param projectedVector Projected vector to be returned by pointer
///
/// \return true if successfully projected.
/// \return true if successfully projected.
/// false if the given \a vector is parallel with the plane's normal
//--------------------------------------------------------------------------------------------------
bool Plane::projectVector(const Vec3d& vector, Vec3d* projectedVector) const
@@ -378,7 +378,7 @@ Vec3d Plane::projectPoint(const Vec3d& point) const
/// \param point Point on line
/// \param direction Normalized direction of line
///
/// \return true if success. false if direction is zero -> no point of intersection exists
/// \return true if success. false if direction is zero -> no point of intersection exists
//--------------------------------------------------------------------------------------------------
bool Plane::intersect(const Plane& other, Vec3d* point, Vec3d* direction) const
{
@@ -474,6 +474,125 @@ bool Plane::intersect(const Vec3d& a, const Vec3d& b, Vec3d* intersection) const
return false;
}
//--------------------------------------------------------------------------------------------------
/// Clip a triangle against this plane
///
/// Clip the triangle given by parameters a, b and c against this plane. The vertices of the
/// resulting clipped polygon (triangle or quad) will be returned in \a clippedPolygon. Since the
/// clipped polygon may be a quad, the \a clippedPolygon array must have room for at least 4 elements.
///
/// \return The number of resulting vertices that are populated in \a clippedPolygon. Will be 0, 3 or 4.
//--------------------------------------------------------------------------------------------------
size_t Plane::clipTriangle(const Vec3d& a, const Vec3d& b, const Vec3d& c, Vec3d clippedPolygon[4]) const
{
// Except for the trivial cases where all vertices are in front
// or behind plane, these are the permutations
//
// Single vertex on positive side of plane
// => return a triangle
//
// +\ /\c /\c /+ /\c .
// \ / \ / \ / + / \ + .
// \ \ / \/ ---/----\--- .
// / \ \ / /\ / \ .
// a/___\____\b a/_____/__\b a/________\b .
// +\ /+
//
// Two vertices vertex on positive side of plane
// => return a quad
//
// /\c \+ /\c /\c +/ .
// / \ \ / \ / \ / .
// ___/____\___ \ \ / \/ .
// + / \ + / \ \ / /\ .
// a/________\b a/___\____\b a/_____/__\b .
// \+ +/
bool onPosSide[3];
onPosSide[0] = distanceSquared(a) >= 0 ? true : false;
onPosSide[1] = distanceSquared(b) >= 0 ? true : false;
onPosSide[2] = distanceSquared(c) >= 0 ? true : false;
const int numPositiveVertices = (onPosSide[0] ? 1 : 0) + (onPosSide[1] ? 1 : 0) + (onPosSide[2] ? 1 : 0);
// The entire triangle is on the negative side
// Clip everything
if (numPositiveVertices == 0)
{
return 0;
}
// All triangle vertices are on the positive side
// Return the same triangle
if (numPositiveVertices == 3)
{
clippedPolygon[0] = a;
clippedPolygon[1] = b;
clippedPolygon[2] = c;
return 3;
}
// Handle case where a single vertex is on the positive side
// Will result in the return of a single clipped triangle
if (numPositiveVertices == 1)
{
if (onPosSide[0])
{
clippedPolygon[0] = a;
intersect(a, b, &clippedPolygon[1]);
intersect(a, c, &clippedPolygon[2]);
}
else if (onPosSide[1])
{
clippedPolygon[0] = b;
intersect(b, c, &clippedPolygon[1]);
intersect(b, a, &clippedPolygon[2]);
}
else
{
CVF_ASSERT(onPosSide[2]);
clippedPolygon[0] = c;
intersect(c, a, &clippedPolygon[1]);
intersect(c, b, &clippedPolygon[2]);
}
return 3;
}
else
{
CVF_ASSERT(numPositiveVertices == 2);
if (onPosSide[0] && onPosSide[1])
{
// a & b are on positive side
clippedPolygon[0] = a;
clippedPolygon[1] = b;
intersect(b, c, &clippedPolygon[2]);
intersect(a, c, &clippedPolygon[3]);
}
else if (onPosSide[1] && onPosSide[2])
{
// b & c are on positive side
clippedPolygon[0] = b;
clippedPolygon[1] = c;
intersect(c, a, &clippedPolygon[2]);
intersect(b, a, &clippedPolygon[3]);
}
else
{
// c && a are on positive side
CVF_ASSERT(onPosSide[2] && onPosSide[0]);
clippedPolygon[0] = c;
clippedPolygon[1] = a;
intersect(a, b, &clippedPolygon[2]);
intersect(c, b, &clippedPolygon[3]);
}
return 4;
}
}
//--------------------------------------------------------------------------------------------------
/// Classify where the point is located relative to the plane
///

View File

@@ -91,7 +91,8 @@ public:
bool intersect(const Plane& other, Vec3d* point, Vec3d* direction = NULL) const;
bool intersect(const Vec3d& a, const Vec3d& b, Vec3d* intersection) const;
size_t clipTriangle(const Vec3d& ta, const Vec3d& tb, const Vec3d& tc, Vec3d clippedPolygon[4]) const;
Side side(const Vec3d& point) const;
Side side(const Vec3dArray& points) const;

View File

@@ -108,6 +108,8 @@ public:
inline S lengthSquared() const;
bool setLength(S newLength);
const Vector2 perpendicularVector() const;
public:
static const Vector2 X_AXIS; ///< X axis vector <1, 0>
static const Vector2 Y_AXIS; ///< Y axis vector <0, 1>

View File

@@ -394,6 +394,27 @@ bool Vector2<S>::setLength(S newLength)
}
//--------------------------------------------------------------------------------------------------
/// Return a unit length perpendicular vector
///
/// Returns the vector (y,-x), normalized. This can be thought of as the 'right' vector.
//--------------------------------------------------------------------------------------------------
template<typename S>
const Vector2<S> Vector2<S>::perpendicularVector() const
{
S len = length();
if (len > 0.0)
{
S oneOverLen = (static_cast<S>(1.0)/len);
return Vector2<S>(m_v[1]*oneOverLen, -m_v[0]*oneOverLen);
}
else
{
return Vector2<S>::ZERO;
}
}
//--------------------------------------------------------------------------------------------------
/// Normalize the vector (make sure the length is 1.0).
///

View File

@@ -25,6 +25,7 @@ cvfLibGeometry.h
cvfMeshEdgeExtractor.h
cvfOutlineEdgeExtractor.h
cvfPatchGenerator.h
cvfPrimitiveTests.h
cvfRay.h
cvfTriangleMeshEdgeExtractor.h
cvfTriangleVertexSplitter.h
@@ -46,6 +47,7 @@ cvfGeometryUtils.cpp
cvfMeshEdgeExtractor.cpp
cvfOutlineEdgeExtractor.cpp
cvfPatchGenerator.cpp
cvfPrimitiveTests.cpp
cvfRay.cpp
cvfTriangleMeshEdgeExtractor.cpp
cvfTriangleVertexSplitter.cpp

View File

@@ -253,6 +253,7 @@
<ClInclude Include="cvfMeshEdgeExtractor.h" />
<ClInclude Include="cvfOutlineEdgeExtractor.h" />
<ClInclude Include="cvfPatchGenerator.h" />
<ClInclude Include="cvfPrimitiveTests.h" />
<ClInclude Include="cvfRay.h" />
<ClInclude Include="cvfTriangleMeshEdgeExtractor.h" />
<ClInclude Include="cvfTriangleVertexSplitter.h" />
@@ -273,6 +274,7 @@
<ClCompile Include="cvfMeshEdgeExtractor.cpp" />
<ClCompile Include="cvfOutlineEdgeExtractor.cpp" />
<ClCompile Include="cvfPatchGenerator.cpp" />
<ClCompile Include="cvfPrimitiveTests.cpp" />
<ClCompile Include="cvfRay.cpp" />
<ClCompile Include="cvfTriangleMeshEdgeExtractor.cpp" />
<ClCompile Include="cvfTriangleVertexSplitter.cpp" />

View File

@@ -20,6 +20,7 @@
<ClInclude Include="cvfVertexCompactor.h" />
<ClInclude Include="cvfTriangleMeshEdgeExtractor.h" />
<ClInclude Include="cvfBoundingBoxTree.h" />
<ClInclude Include="cvfPrimitiveTests.h" />
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />
@@ -43,5 +44,6 @@
<ClCompile Include="cvfVertexCompactor.cpp" />
<ClCompile Include="cvfTriangleMeshEdgeExtractor.cpp" />
<ClCompile Include="cvfBoundingBoxTree.cpp" />
<ClCompile Include="cvfPrimitiveTests.cpp" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,106 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// 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 at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfPrimitiveTests.h"
#include <limits>
namespace cvf {
//==================================================================================================
///
/// \class cvf::PrimitiveTests
/// \ingroup Geometry
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Calculate intersection between the lines p1p2 and p3p4
//--------------------------------------------------------------------------------------------------
bool PrimitiveTests::intersectLines(const Vec2d& p1, const Vec2d& p2, const Vec2d& p3, const Vec2d& p4, Vec2d* isect)
{
// See Paul Bourke, Intersection point of two lines in 2 dimensions
const double epsilon = std::numeric_limits<double>::epsilon();
const double denom = (p4.y()-p3.y())*(p2.x()-p1.x()) - (p4.x()-p3.x())*(p2.y()-p1.y());
const double numera = (p4.x()-p3.x())*(p1.y()-p3.y()) - (p4.y()-p3.y())*(p1.x()-p3.x());
const double numerb = (p2.x()-p1.x())*(p1.y()-p3.y()) - (p2.y()-p1.y())*(p1.x()-p3.x());
// Are the lines coincident?
if (cvf::Math::abs(numera) < epsilon &&
cvf::Math::abs(numerb) < epsilon &&
cvf::Math::abs(denom) < epsilon)
{
isect->x() = (p1.x() + p2.x()) / 2;
isect->y() = (p1.y() + p2.y()) / 2;
return true;
}
// Are the lines parallel?
if (cvf::Math::abs(denom) < epsilon)
{
isect->setZero();
return false;
}
const double ta = numera/denom;
// const double tb = numerb/denom;
//
// // Is the intersection along the the segments ?
// if (ta < 0 || ta > 1 || tb < 0 || tb > 1)
// {
// isect->setZero();
// return false;
// }
isect->x() = p1.x() + ta * (p2.x() - p1.x());
isect->y() = p1.y() + ta * (p2.y() - p1.y());
return true;
}
} // namespace cvf

View File

@@ -0,0 +1,56 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// 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 at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfVector2.h"
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class PrimitiveTests
{
public:
static bool intersectLines(const Vec2d& p1, const Vec2d& p2, const Vec2d& p3, const Vec2d& p4, Vec2d* isect);
};
}

View File

@@ -40,7 +40,8 @@
class QMouseEvent;
class QGraphicsSceneMouseEvent;
#include <Qt>
#include <QtCore/Qt>
namespace cvfqt {

View File

@@ -463,7 +463,12 @@
<ClInclude Include="glsl\fs_HighlightMix.glsl">
<FileType>Document</FileType>
</ClInclude>
<None Include="glsl\src_TwoSidedColor.glsl" />
<ClInclude Include="glsl\src_TwoSidedColor.glsl">
<FileType>Document</FileType>
</ClInclude>
<ClInclude Include="glsl\src_VaryingColorGlobalAlpha.glsl">
<FileType>Document</FileType>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClInclude Include="cvfBufferObjectManaged.h" />

View File

@@ -186,15 +186,18 @@
</ClInclude>
<ClInclude Include="cvfOverlayImage.h" />
<ClInclude Include="cvfCameraAnimation.h" />
<ClInclude Include="glsl\src_TwoSidedColor.glsl">
<Filter>glsl</Filter>
</ClInclude>
<ClInclude Include="glsl\src_VaryingColorGlobalAlpha.glsl">
<Filter>glsl</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="glsl\!AddingAndModifyingGlslFiles.txt">
<Filter>glsl</Filter>
</None>
<None Include="CMakeLists.txt" />
<None Include="glsl\src_TwoSidedColor.glsl">
<Filter>glsl</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ClCompile Include="cvfCamera.cpp" />

View File

@@ -119,6 +119,7 @@ const char* ShaderSourceRepository::shaderIdentString(ShaderIdent shaderIdent)
CVF_IDENT_HANDLE_CASE(src_TextureGlobalAlpha);
CVF_IDENT_HANDLE_CASE(src_TextureFromPointCoord);
CVF_IDENT_HANDLE_CASE(src_TextureRectFromFragCoord_v33);
CVF_IDENT_HANDLE_CASE(src_VaryingColorGlobalAlpha);
CVF_IDENT_HANDLE_CASE(light_Phong);
CVF_IDENT_HANDLE_CASE(light_PhongDual);
@@ -179,6 +180,7 @@ bool ShaderSourceRepository::rawShaderSource(ShaderIdent shaderIdent, CharArray*
CVF_SOURCE_HANDLE_CASE(src_TextureGlobalAlpha);
CVF_SOURCE_HANDLE_CASE(src_TextureFromPointCoord);
CVF_SOURCE_HANDLE_CASE(src_TextureRectFromFragCoord_v33);
CVF_SOURCE_HANDLE_CASE(src_VaryingColorGlobalAlpha);
CVF_SOURCE_HANDLE_CASE(light_Phong);
CVF_SOURCE_HANDLE_CASE(light_PhongDual);

View File

@@ -64,6 +64,7 @@ public:
src_TextureGlobalAlpha,
src_TextureFromPointCoord,
src_TextureRectFromFragCoord_v33,
src_VaryingColorGlobalAlpha,
light_Phong,
light_PhongDual,

View File

@@ -914,6 +914,24 @@ static const char src_TwoSidedColor_inl[] =
//#############################################################################################################################
//#############################################################################################################################
static const char src_VaryingColorGlobalAlpha_inl[] =
" \n"
"uniform float u_alpha; \n"
" \n"
"varying vec4 v_color; \n"
" \n"
"//-------------------------------------------------------------------------------------------------- \n"
"/// RGB color from varying, alpha from uniform \n"
"//-------------------------------------------------------------------------------------------------- \n"
"vec4 srcFragment() \n"
"{ \n"
" return vec4(v_color.rgb, u_alpha); \n"
"} \n";
//#############################################################################################################################
//#############################################################################################################################
static const char vs_DistanceScaledPoints_inl[] =
@@ -1147,10 +1165,12 @@ static const char vs_Standard_inl[] =
"attribute vec4 cvfa_vertex; \n"
"attribute vec3 cvfa_normal; \n"
"attribute vec2 cvfa_texCoord; \n"
"attribute vec4 cvfa_color; \n"
" \n"
"varying vec3 v_ecPosition; \n"
"varying vec3 v_ecNormal; \n"
"varying vec2 v_texCoord; \n"
"varying vec4 v_color; \n"
" \n"
"//-------------------------------------------------------------------------------------------------- \n"
"/// Vertex Shader - Standard \n"
@@ -1165,6 +1185,7 @@ static const char vs_Standard_inl[] =
" v_ecPosition = (cvfu_modelViewMatrix * cvfa_vertex).xyz; \n"
" v_ecNormal = cvfu_normalMatrix * cvfa_normal; \n"
" v_texCoord = cvfa_texCoord; \n"
" v_color = cvfa_color; \n"
" \n"
"#ifdef CVF_CALC_CLIP_DISTANCES_IMPL \n"
" calcClipDistances(vec4(v_ecPosition, 1)); \n"

View File

@@ -0,0 +1,12 @@
uniform float u_alpha;
varying vec4 v_color;
//--------------------------------------------------------------------------------------------------
/// RGB color from varying, alpha from uniform
//--------------------------------------------------------------------------------------------------
vec4 srcFragment()
{
return vec4(v_color.rgb, u_alpha);
}

View File

@@ -6,10 +6,12 @@ uniform mat3 cvfu_normalMatrix;
attribute vec4 cvfa_vertex;
attribute vec3 cvfa_normal;
attribute vec2 cvfa_texCoord;
attribute vec4 cvfa_color;
varying vec3 v_ecPosition;
varying vec3 v_ecNormal;
varying vec2 v_texCoord;
varying vec4 v_color;
//--------------------------------------------------------------------------------------------------
/// Vertex Shader - Standard
@@ -24,6 +26,7 @@ void main ()
v_ecPosition = (cvfu_modelViewMatrix * cvfa_vertex).xyz;
v_ecNormal = cvfu_normalMatrix * cvfa_normal;
v_texCoord = cvfa_texCoord;
v_color = cvfa_color;
#ifdef CVF_CALC_CLIP_DISTANCES_IMPL
calcClipDistances(vec4(v_ecPosition, 1));

View File

@@ -1,7 +1,7 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
// Copyright (C) Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
@@ -44,12 +44,13 @@
#include <vector>
#include <string.h>
#ifdef CVF_LINUX
CVF_GCC_DIAGNOSTIC_IGNORE("-Wconversion")
// Apparently, this warning doesn't exist until GCC 4.5
#if defined(__GNUC__) && (CVF_GCC_VER >= 40500)
CVF_GCC_DIAGNOSTIC_IGNORE("-Wunused-result")
#endif
namespace cvfu {
using cvf::ref;

View File

@@ -1,7 +1,7 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
// Copyright (C) Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:

View File

@@ -126,6 +126,16 @@ void ModelBasicList::removeAllParts()
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ModelBasicList::shrinkPartCount(size_t newPartCount)
{
CVF_ASSERT(newPartCount <= m_parts.size());
m_parts.resize(newPartCount);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -60,6 +60,7 @@ public:
size_t partCount() const;
void removePart(Part* part);
void removeAllParts();
void shrinkPartCount(size_t newPartCount);
virtual void findVisibleParts(PartRenderHintCollection* visibleParts, const Camera& camera, const CullSettings& cullSettings, uint enableMask);
virtual void allParts(Collection<Part>* partCollection);

View File

@@ -14,6 +14,7 @@ set(CEE_LIBS LibCore)
set(CEE_SOURCE_FILES
cvfArray-Test.cpp
cvfArrayWrapper-Test.cpp
cvfAtomicCounter-Test.cpp
cvfBase-Test.cpp
cvfBase64-Test.cpp
cvfCharArray-Test.cpp

View File

@@ -251,6 +251,7 @@
<ClCompile Include="..\..\ThirdParty\gtest\gtest-all.cpp" />
<ClCompile Include="cvfArray-Test.cpp" />
<ClCompile Include="cvfArrayWrapper-Test.cpp" />
<ClCompile Include="cvfAtomicCounter-Test.cpp" />
<ClCompile Include="cvfBase-Test.cpp" />
<ClCompile Include="cvfBase64-Test.cpp" />
<ClCompile Include="cvfCharArray-Test.cpp" />

View File

@@ -34,6 +34,7 @@
<ClCompile Include="cvfCodeLocation-Test.cpp" />
<ClCompile Include="cvfArrayWrapper-Test.cpp" />
<ClCompile Include="cvfProgramOptions-Test.cpp" />
<ClCompile Include="cvfAtomicCounter-Test.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />
@@ -41,4 +42,4 @@
<ItemGroup>
<CustomBuild Include="TriggerTBBCopy.txt" />
</ItemGroup>
</Project>
</Project>

View File

@@ -123,10 +123,10 @@ TEST(ArrayWrapperTest, AllSpecializations)
siztCvfArray[0] = 0;
siztCvfArray[1] = 1;
cvf::Array<uint> uintCvfArray(2);
cvf::Array<cvf::uint> uintCvfArray(2);
uintCvfArray[0] = 0;
uintCvfArray[1] = 1;
const cvf::Array<uint>& cuintCvfArray = uintCvfArray;
const cvf::Array<cvf::uint>& cuintCvfArray = uintCvfArray;
size_t siztBarePtrArray[2] = {0, 1};
@@ -187,3 +187,4 @@ TEST(ArrayWrapperTest, AllSpecializations)
EXPECT_EQ(0.0, doubleBarePtr[1]);
EXPECT_EQ(1.0, doubleBarePtr[0]);
}

View File

@@ -0,0 +1,141 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2014 Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// 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 at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfAtomicCounter.h"
#ifdef CVF_ATOMIC_COUNTER_CLASS_EXISTS
#include "cvfDebugTimer.h"
#include "cvfObject.h"
#include "cvfCollection.h"
#include "gtest/gtest.h"
using namespace cvf;
class MyObj : public Object
{
public:
MyObj() { num_ = 0; }
MyObj(int num) { num_ = num; }
int num() const { return num_; }
void num(int num) { num_ = num; }
bool operator<(const MyObj& rhs)
{
return num_ < rhs.num_;
}
private:
int num_;
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(DISABLED_ObjectConstructionBenchmark, TestBasicObjectConstruction)
{
int objectCount = 1000000;
int iterationCount = 5;
String sNumber(objectCount);
String refCountTxt = String("TestBasicObjectConstruction : ") + sNumber;
DebugTimer tim(refCountTxt.toAscii().ptr());
for (int iteration = 0; iteration < iterationCount; iteration++)
{
for (int i = 0; i < objectCount; i++)
{
MyObj* r2 = new MyObj();
r2->addRef();
r2->release();
}
tim.reportLapTimeMS();
}
}
class ObjectReferencingSharedObject : public Object
{
public:
ObjectReferencingSharedObject() { }
cvf::ref<MyObj> m_sharedObject;
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(DISABLED_ObjectConstructionBenchmark, TestReferenceOtherObject)
{
int objectCount = 1000000;
int iterationCount = 5;
String sNumber(objectCount);
String refCountTxt = String("TestReferenceOtherObjectClass : ") + sNumber;
DebugTimer tim(refCountTxt.toAscii().ptr());
for (int iteration = 0; iteration < iterationCount; iteration++)
{
cvf::ref<MyObj> sharedObj = new MyObj();
std::vector< cvf::ref<ObjectReferencingSharedObject> > col;
col.resize(objectCount);
for (int i = 0; i < objectCount; i++)
{
cvf::ref<ObjectReferencingSharedObject> newObj = new ObjectReferencingSharedObject();
newObj->m_sharedObject = sharedObj.p();
col[i] = newObj;
}
String sNumber(sharedObj->refCount());
String refCountTxt = String("Shared object reference count : ") + sNumber;
tim.reportLapTimeMS(refCountTxt.toAscii().ptr());
}
}
#endif //#ifdef CVF_ATOMIC_COUNTER_CLASS_EXISTS

View File

@@ -365,6 +365,38 @@ TEST(Vector2Test, SetLength)
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(Vector2Test, perpendicularVector)
{
{
const Vec2d v(0, 1);
const Vec2d perp = v.perpendicularVector();
EXPECT_DOUBLE_EQ(1, perp.x());
EXPECT_DOUBLE_EQ(0, perp.y());
}
{
const Vec2d v(1, 0);
const Vec2d perp = v.perpendicularVector();
EXPECT_DOUBLE_EQ(0, perp.x());
EXPECT_DOUBLE_EQ(-1, perp.y());
}
{
const Vec2d v(0, -2);
const Vec2d perp = v.perpendicularVector();
EXPECT_DOUBLE_EQ(-1, perp.x());
EXPECT_DOUBLE_EQ(0, perp.y());
}
{
const Vec2d v(-3, 0);
const Vec2d perp = v.perpendicularVector();
EXPECT_DOUBLE_EQ(0, perp.x());
EXPECT_DOUBLE_EQ(1, perp.y());
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -26,6 +26,7 @@ cvfGeometryUtils-Test.cpp
cvfMeshEdgeExtractor-Test.cpp
cvfOutlineEdgeExtractor-Test.cpp
cvfPatchGenerator-Test.cpp
cvfPrimitiveTests-Test.cpp
cvfRay-Test.cpp
cvfTriangleMeshEdgeExtractor-Test.cpp
cvfTriangleVertexSplitter-Test.cpp

View File

@@ -262,6 +262,7 @@
<ClCompile Include="cvfMeshEdgeExtractor-Test.cpp" />
<ClCompile Include="cvfOutlineEdgeExtractor-Test.cpp" />
<ClCompile Include="cvfPatchGenerator-Test.cpp" />
<ClCompile Include="cvfPrimitiveTests-Test.cpp" />
<ClCompile Include="cvfRay-Test.cpp" />
<ClCompile Include="cvfTriangleMeshEdgeExtractor-Test.cpp" />
<ClCompile Include="cvfTriangleVertexSplitter-Test.cpp" />

View File

@@ -21,6 +21,7 @@
<ClCompile Include="cvfVertexCompactor-Test.cpp" />
<ClCompile Include="cvfTriangleMeshEdgeExtractor-Test.cpp" />
<ClCompile Include="cvfBoundingBoxTree-Test.cpp" />
<ClCompile Include="cvfPrimitiveTests-Test.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />

View File

@@ -0,0 +1,90 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// 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 at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfPrimitiveTests.h"
#include "gtest/gtest.h"
using namespace cvf;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(PrimitiveTestsTest, intersectLines)
{
{
Vec2d p1(0, 0); Vec2d p2(2, 0);
Vec2d p3(1, -1); Vec2d p4(1, 1);
Vec2d isect(0, 0);
EXPECT_TRUE(PrimitiveTests::intersectLines(p1, p2, p3, p4, &isect));
EXPECT_DOUBLE_EQ(1, isect.x());
EXPECT_DOUBLE_EQ(0, isect.y());
}
{
Vec2d p1(0, 0); Vec2d p2(2, 0);
Vec2d p3(1, 2); Vec2d p4(1, 1);
Vec2d isect(0, 0);
EXPECT_TRUE(PrimitiveTests::intersectLines(p1, p2, p3, p4, &isect));
EXPECT_DOUBLE_EQ(1, isect.x());
EXPECT_DOUBLE_EQ(0, isect.y());
}
// Incident
{
Vec2d p1(1, 0); Vec2d p2(3, 0);
Vec2d p3(2, 0); Vec2d p4(4, 0);
Vec2d isect(0, 0);
EXPECT_TRUE(PrimitiveTests::intersectLines(p1, p2, p3, p4, &isect));
EXPECT_DOUBLE_EQ(2, isect.x());
EXPECT_DOUBLE_EQ(0, isect.y());
}
// Parallell
{
Vec2d p1(0, 0); Vec2d p2(2, 0);
Vec2d p3(0, 2); Vec2d p4(2, 2);
Vec2d isect(0, 0);
EXPECT_FALSE(PrimitiveTests::intersectLines(p1, p2, p3, p4, &isect));
EXPECT_DOUBLE_EQ(0, isect.x());
EXPECT_DOUBLE_EQ(0, isect.y());
}
}

View File

@@ -128,6 +128,51 @@ TEST(ModelBasicListDeathTest, IllegalIndexing)
}
#endif
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(ModelBasicListTest, shrinkPartCount)
{
ref<Part> p1 = new Part;
ref<Part> p2 = new Part;
ref<Part> p3 = new Part;
{
ref<ModelBasicList> myModel = new ModelBasicList;
myModel->addPart(p1.p());
myModel->addPart(p2.p());
myModel->addPart(p3.p());
ASSERT_EQ(3, myModel->partCount());
EXPECT_EQ(2, p1->refCount());
EXPECT_EQ(2, p2->refCount());
EXPECT_EQ(2, p3->refCount());
myModel->shrinkPartCount(3);
ASSERT_EQ(3, myModel->partCount());
EXPECT_EQ(2, p1->refCount());
EXPECT_EQ(2, p2->refCount());
EXPECT_EQ(2, p3->refCount());
myModel->shrinkPartCount(2);
ASSERT_EQ(2, myModel->partCount());
EXPECT_EQ(2, p1->refCount());
EXPECT_EQ(2, p2->refCount());
EXPECT_EQ(1, p3->refCount());
myModel->shrinkPartCount(0);
ASSERT_EQ(0, myModel->partCount());
EXPECT_EQ(1, p1->refCount());
EXPECT_EQ(1, p2->refCount());
EXPECT_EQ(1, p3->refCount());
}
EXPECT_EQ(1, p1->refCount());
EXPECT_EQ(1, p2->refCount());
EXPECT_EQ(1, p3->refCount());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -47,6 +47,16 @@
namespace snip {
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
VertexColoring::VertexColoring()
: m_useShaders(false)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -54,20 +64,37 @@ bool VertexColoring::onInitialize()
{
ref<ModelBasicList> myModel = new ModelBasicList;
// Create the effect
// Create the fixed function effect
{
m_effect = new Effect;
m_fixedFuncEffect = new Effect;
ref<RenderStateMaterial_FF> mat = new RenderStateMaterial_FF(Color3::BLUE);
mat->enableColorMaterial(true);
m_effect->setRenderState(mat.p());
m_fixedFuncEffect->setRenderState(mat.p());
ref<RenderStateLighting_FF> lighting = new RenderStateLighting_FF;
m_effect->setRenderState(lighting.p());
m_fixedFuncEffect->setRenderState(lighting.p());
}
// Create effect with shader program
{
m_shaderEffect = new Effect;
ShaderProgramGenerator gen("PerVertexColor", ShaderSourceProvider::instance());
gen.addVertexCode(ShaderSourceRepository::vs_Standard);
gen.addFragmentCode(ShaderSourceRepository::src_VaryingColorGlobalAlpha);
gen.addFragmentCode(ShaderSourceRepository::light_SimpleHeadlight);
gen.addFragmentCode(ShaderSourceRepository::fs_Standard);
m_shaderProg = gen.generate();
m_shaderProg->setDefaultUniform(new cvf::UniformFloat("u_alpha", 1.0f));
m_shaderEffect->setShaderProgram(m_shaderProg.p());
}
// "Normal" geometry
ref<Effect> effectToUse = m_useShaders ? m_shaderEffect : m_fixedFuncEffect;
// Lower left: "Normal" geometry
{
GeometryBuilderDrawableGeo builder;
GeometryUtils::createBox(Vec3f(0,0,0), 2.0, 2.0, 2.0, &builder);
@@ -76,12 +103,13 @@ bool VertexColoring::onInitialize()
ref<Part> part = new Part;
part->setDrawable(geo.p());
part->setEffect(m_effect.p());
part->setEffect(effectToUse.p());
myModel->addPart(part.p());
}
// Geometry with per vertex colors
// Lower right: Geometry with per vertex colors
// Results in one color per face of the cube
{
GeometryBuilderDrawableGeo builder;
GeometryUtils::createBox(Vec3f(3,0,0), 2.0, 2.0, 2.0, &builder);
@@ -114,12 +142,12 @@ bool VertexColoring::onInitialize()
ref<Part> part = new Part;
part->setDrawable(geo.p());
part->setEffect(m_effect.p());
part->setEffect(effectToUse.p());
myModel->addPart(part.p());
}
// Geometry with per vertex colors (using ScalarToColorMapper)
// Upper right: Geometry with per vertex colors (using ScalarToColorMapper)
{
BoxGenerator gen;
gen.setMinMax(Vec3d(2,-1,2), Vec3d(4, 1, 4));
@@ -159,12 +187,12 @@ bool VertexColoring::onInitialize()
ref<Part> part = new Part;
part->setDrawable(geo.p());
part->setEffect(m_effect.p());
part->setEffect(effectToUse.p());
myModel->addPart(part.p());
}
// Geometry without normals
// Upper left: Geometry without normals
{
GeometryBuilderDrawableGeo builder;
GeometryUtils::createBox(Vec3f(0,0,3), 2.0, 2.0, 2.0, &builder);
@@ -173,7 +201,7 @@ bool VertexColoring::onInitialize()
ref<Part> part = new Part;
part->setDrawable(geo.p());
part->setEffect(m_effect.p());
part->setEffect(effectToUse.p());
myModel->addPart(part.p());
}
@@ -233,11 +261,24 @@ void VertexColoring::onKeyPressEvent(KeyEvent* keyEvent)
Key key = keyEvent->key();
char character = keyEvent->character();
if (key == Key_S || key == Key_F)
{
m_useShaders = (key == Key_S) ? true : false;
Collection<Part> partCollection;
m_renderSequence->firstRendering()->scene()->model(0)->allParts(&partCollection);
for (size_t i = 0; i < partCollection.size(); i++)
{
ref<Part> part = partCollection[i];
part->setEffect(m_useShaders ? m_shaderEffect.p() : m_fixedFuncEffect.p());
}
}
if (key == Key_L)
{
bool lightingOn = (character == 'l') ? true : false;
RenderStateLighting_FF* rsLighting = dynamic_cast<RenderStateLighting_FF*>(m_effect->renderStateOfType(RenderState::LIGHTING_FF));
RenderStateLighting_FF* rsLighting = dynamic_cast<RenderStateLighting_FF*>(m_fixedFuncEffect->renderStateOfType(RenderState::LIGHTING_FF));
rsLighting->enable(lightingOn);
}
@@ -245,7 +286,7 @@ void VertexColoring::onKeyPressEvent(KeyEvent* keyEvent)
{
bool colorMaterialOn = (character == 'c') ? true : false;
RenderStateMaterial_FF* rsMaterial = dynamic_cast<RenderStateMaterial_FF*>(m_effect->renderStateOfType(RenderState::MATERIAL_FF));
RenderStateMaterial_FF* rsMaterial = dynamic_cast<RenderStateMaterial_FF*>(m_fixedFuncEffect->renderStateOfType(RenderState::MATERIAL_FF));
rsMaterial->enableColorMaterial(colorMaterialOn);
}
@@ -259,8 +300,10 @@ void VertexColoring::onKeyPressEvent(KeyEvent* keyEvent)
std::vector<cvf::String> VertexColoring::helpText() const
{
std::vector<String> help;
help.push_back(String("l/L - to toggle lighting on/off"));
help.push_back(String("c/C - to toggle color material on/off"));
help.push_back("s - to use a shader program for rendering");
help.push_back("f - to use fixed function pipeline for rendering");
help.push_back("l/L - to toggle lighting on/off (in fixed function)");
help.push_back("c/C - to toggle color material on/off (in fixed function)");
return help;

View File

@@ -55,6 +55,7 @@ class VertexColoring : public TestSnippet
CVFU_DECLARE_SNIPPET("Vertex Coloring");
public:
VertexColoring();
virtual bool onInitialize();
virtual void onKeyPressEvent(KeyEvent* keyEvent);
@@ -64,7 +65,10 @@ private:
void addEdgesRendering();
private:
ref<Effect> m_effect;
bool m_useShaders;
ref<ShaderProgram> m_shaderProg;
ref<Effect> m_fixedFuncEffect;
ref<Effect> m_shaderEffect;
};
}