mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
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:
@@ -31,5 +31,6 @@ add_library( ${PROJECT_NAME}
|
||||
cafPdmUiOrdering.h
|
||||
cafPdmUiTreeOrdering.cpp
|
||||
cafPdmUiTreeOrdering.h
|
||||
|
||||
cafPdmUiTreeEditorHandle.h
|
||||
cafPdmUiTreeEditorHandle.cpp
|
||||
)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -59,6 +59,8 @@ QWidget* PdmUiObjectEditorHandle::getOrCreateWidget(QWidget* parent)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiObjectEditorHandle::setPdmObject(PdmObject* object)
|
||||
{
|
||||
cleanupBeforeSettingPdmObject();
|
||||
|
||||
this->bindToPdmItem(object);
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@ public:
|
||||
|
||||
protected:
|
||||
virtual QWidget* createWidget(QWidget* parent) = 0;
|
||||
virtual void cleanupBeforeSettingPdmObject() {};
|
||||
|
||||
protected:
|
||||
QPointer<QWidget> m_widget;
|
||||
|
||||
76
Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeEditorHandle.cpp
Normal file
76
Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeEditorHandle.cpp
Normal 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
|
||||
|
||||
78
Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeEditorHandle.h
Normal file
78
Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeEditorHandle.h
Normal 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
|
||||
13
Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Child.cpp
Normal file
13
Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Child.cpp
Normal 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()
|
||||
{
|
||||
}
|
||||
22
Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Child.h
Normal file
22
Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Child.h
Normal 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;
|
||||
};
|
||||
|
||||
|
||||
32
Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.cpp
Normal file
32
Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.cpp
Normal 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);
|
||||
}
|
||||
52
Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.h
Normal file
52
Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.h
Normal 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;
|
||||
};
|
||||
@@ -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() {}
|
||||
18
Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/TestObj.h
Normal file
18
Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/TestObj.h
Normal 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;
|
||||
};
|
||||
@@ -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
|
||||
|
||||
567
Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.cpp
Normal file
567
Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.cpp
Normal 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
|
||||
114
Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.h
Normal file
114
Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.h
Normal 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
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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>
|
||||
@@ -151,3 +151,4 @@ inline const ArrayWrapperConst< const ElmType*, ElmType > wrapArrayConst( ElmTy
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -130,3 +130,4 @@ inline ArrayWrapperToEdit< ElmType*, ElmType > wrapArrayToEdit(ElmType* array, s
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
193
Fwk/VizFwk/LibCore/cvfAtomicCounter.cpp
Normal file
193
Fwk/VizFwk/LibCore/cvfAtomicCounter.cpp
Normal 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
|
||||
96
Fwk/VizFwk/LibCore/cvfAtomicCounter.h
Normal file
96
Fwk/VizFwk/LibCore/cvfAtomicCounter.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
///
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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).
|
||||
///
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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>
|
||||
106
Fwk/VizFwk/LibGeometry/cvfPrimitiveTests.cpp
Normal file
106
Fwk/VizFwk/LibGeometry/cvfPrimitiveTests.cpp
Normal 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
|
||||
56
Fwk/VizFwk/LibGeometry/cvfPrimitiveTests.h
Normal file
56
Fwk/VizFwk/LibGeometry/cvfPrimitiveTests.h
Normal 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);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -40,7 +40,8 @@
|
||||
class QMouseEvent;
|
||||
class QGraphicsSceneMouseEvent;
|
||||
|
||||
#include <Qt>
|
||||
#include <QtCore/Qt>
|
||||
|
||||
|
||||
namespace cvfqt {
|
||||
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -64,6 +64,7 @@ public:
|
||||
src_TextureGlobalAlpha,
|
||||
src_TextureFromPointCoord,
|
||||
src_TextureRectFromFragCoord_v33,
|
||||
src_VaryingColorGlobalAlpha,
|
||||
|
||||
light_Phong,
|
||||
light_PhongDual,
|
||||
|
||||
@@ -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"
|
||||
|
||||
12
Fwk/VizFwk/LibRender/glsl/src_VaryingColorGlobalAlpha.glsl
Normal file
12
Fwk/VizFwk/LibRender/glsl/src_VaryingColorGlobalAlpha.glsl
Normal 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);
|
||||
}
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -126,6 +126,16 @@ void ModelBasicList::removeAllParts()
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void ModelBasicList::shrinkPartCount(size_t newPartCount)
|
||||
{
|
||||
CVF_ASSERT(newPartCount <= m_parts.size());
|
||||
m_parts.resize(newPartCount);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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>
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
|
||||
141
Fwk/VizFwk/Tests/LibCore_UnitTests/cvfAtomicCounter-Test.cpp
Normal file
141
Fwk/VizFwk/Tests/LibCore_UnitTests/cvfAtomicCounter-Test.cpp
Normal 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
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user