Commit fef9f926 authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge

Merge branch 'cuda-cm-rebased' into 'development'

Cuda cm rebased

See merge request !114
parents e68b3980 382b2a24
......@@ -196,6 +196,10 @@ namespace campvis {
++i;
}
else if (pipelinesToAdd[i] == "-k") {
// set kiosk mode
_mainWindow->enableKioskMode();
}
else {
DataContainer* dc = createAndAddDataContainer("DataContainer #" + StringUtils::toString(_dataContainers.size() + 1));
AbstractPipeline* p = PipelineFactory::getRef().createPipeline(pipelinesToAdd[i].toStdString(), dc);
......
......@@ -135,7 +135,7 @@ namespace campvis {
_localDataContainer.clear();
_textures.clear();
ShdrMgr.dispose(_paintShader);
delete _quad;
_quad = nullptr;
GLCtxtMgr.removeContext(this);
}
......@@ -262,8 +262,6 @@ namespace campvis {
}
void DataContainerInspectorCanvas::createQuad() {
delete _quad;
_quad = 0;
_quad = GeometryDataFactory::createQuad(cgt::vec3(0.f), cgt::vec3(1.f), cgt::vec3(0.f, 1.f, 0.f), cgt::vec3(1.f, 0.f, 0.f));
}
......@@ -431,7 +429,7 @@ namespace campvis {
}
if (maxSlices == 1)
maxSlices = -1;
maxSlices = 0;
p_currentSlice.setMaxValue(maxSlices - 1);
_texturesDirty = false;
_geometriesDirty = false;
......
......@@ -44,6 +44,8 @@
#include "modules/base/processors/trackballcameraprovider.h"
#include "modules/vis/processors/geometryrenderer.h"
#include <memory>
namespace cgt {
class Shader;
......@@ -213,7 +215,7 @@ namespace campvis {
tbb::mutex _localMutex; ///< Mutex protecting the local members
cgt::Shader* _paintShader; ///< GLSL shader for rendering the textures
FaceGeometry* _quad; ///< Quad used for rendering
std::unique_ptr<FaceGeometry> _quad; ///< Quad used for rendering
cgt::ivec2 _numTiles; ///< number of tiles on texture overview
cgt::ivec2 _quadSize; ///< size in pixels for each tile in overview
......
......@@ -186,8 +186,8 @@ namespace campvis {
this, SIGNAL(updatePipelineWidget(const std::vector<DataContainer*>&, const std::vector<AbstractPipeline*>&)),
_pipelineWidget, SLOT(update(const std::vector<DataContainer*>&, const std::vector<AbstractPipeline*>&)));
connect(
_pipelineWidget, SIGNAL(clicked(const QModelIndex&)),
this, SLOT(onPipelineWidgetItemClicked(const QModelIndex&)));
_pipelineWidget, SIGNAL(itemChanged(const QModelIndex&)),
this, SLOT(onPipelineWidgetItemChanged(const QModelIndex&)));
connect(
this, SIGNAL(updatePropCollectionWidget(HasPropertyCollection*, DataContainer*)),
_propCollectionWidget, SLOT(updatePropCollection(HasPropertyCollection*, DataContainer*)));
......@@ -252,7 +252,7 @@ namespace campvis {
emit updatePipelineWidget(_application->_dataContainers, pipelines);
}
void MainWindow::onPipelineWidgetItemClicked(const QModelIndex& index) {
void MainWindow::onPipelineWidgetItemChanged(const QModelIndex& index) {
if (index.isValid()) {
// Yak, this is so ugly - another reason why GUI programming sucks...
QVariant item = index.data(Qt::UserRole);
......@@ -463,4 +463,13 @@ namespace campvis {
_workflowWidget->setWorkflow(w);
}
void MainWindow::enableKioskMode() {
ui.logViewerDock->hide();
ui.pipelineTreeDock->hide();
ui.pipelinePropertiesDock->hide();
ui.scriptingConsoleDock->hide();
ui.workflowDock->show();
}
}
......@@ -99,6 +99,12 @@ namespace campvis {
*/
void setWorkflow(AbstractWorkflow* w);
/**
* Enables the kiosk mode of the MainWindow.
* In kiosk mode, all docks but the main canvas and the workflow dock are hidden.
*/
void enableKioskMode();
protected:
/**
* Listens to resize events on _pipelinePropertiesWidget and resizes _pipelinePropertiesScrollArea accordingly
......@@ -119,8 +125,8 @@ namespace campvis {
* Slot to be called by the PipelineWidget when the selected item changes.
* \param index Index of the selected item
*/
void onPipelineWidgetItemClicked(const QModelIndex& index);
void onPipelineWidgetItemChanged(const QModelIndex& index);
/**
* Slot to be called when _btnExecute was clicked.
*/
......@@ -163,7 +169,7 @@ namespace campvis {
/**
* Slot to be called by the application when its collection of DataContainers has changed.
*/
void onDataContainersChanged();
void onDataContainersChanged();
/**
* Setup Qt GUI stuff
......
......@@ -379,6 +379,13 @@ namespace campvis {
updateGeometry();
}
void PipelineTreeWidget::selectionChanged(const QItemSelection& selected, const QItemSelection &deselected) {
QTreeView::selectionChanged(selected, deselected);
QModelIndexList selection = this->selectedIndexes();
if (!selection.isEmpty())
emit itemChanged(selection.first());
}
void PipelineTreeWidget::setupWidget() {
_treeModel = new PipelineTreeModel(this);
cgtAssert(_treeModel != 0, "Failed creating TreeViewWidget model.");
......
......@@ -171,6 +171,11 @@ namespace campvis {
virtual QSize sizeHint() const;
signals:
/// Emitted whenever the currently selected item changes
void itemChanged(const QModelIndex& index);
public slots:
/**
* Updates the data in the tree view by the given collection of pipelines \a pipelines.
......@@ -179,6 +184,10 @@ namespace campvis {
void update(const std::vector<DataContainer*>& dataContainers, const std::vector<AbstractPipeline*>& pipelines);
protected:
virtual void selectionChanged(const QItemSelection& selected, const QItemSelection &deselected);
private:
/**
* Sets up the widget.
......
......@@ -67,6 +67,11 @@ namespace campvis {
_property->s_changed.disconnect(this);
}
void AbstractPropertyWidget::setLabelVisibile(bool isVisible) {
if (_titleLabel)
_titleLabel->setVisible(isVisible);
}
void AbstractPropertyWidget::addWidget(QWidget* widget, int stretch) {
_layout->addWidget(widget, stretch);
}
......
......@@ -59,6 +59,13 @@ namespace campvis {
*/
virtual ~AbstractPropertyWidget();
/**
* Shows or hides the label that appears on the left hand side of the widget.
*
* \param isVisible Wether the label should be shown or not
*/
void setLabelVisibile(bool isVisible);
protected:
/**
* Adds a widget to the local Qt layout.
......
......@@ -31,6 +31,8 @@ namespace campvis {
: AbstractPropertyWidget(property, false, dataContainer, parent)
, _button(0)
{
setLabelVisibile(false);
_button = new QPushButton(QString::fromStdString(property->getTitle()), this);
connect(_button, SIGNAL(clicked(bool)), this, SLOT(onButtonClicked(bool)));
addWidget(_button);
......
......@@ -36,9 +36,10 @@
namespace campvis {
PropertyCollectionWidget::PropertyCollectionWidget(QWidget* parent /*= 0*/)
: QWidget(parent)
, _propCollection(0)
, _dataContainer(0)
, _layout(0)
, _propCollection(nullptr)
, _dataContainer(nullptr)
, _layout(nullptr)
, _strechWidget(nullptr)
{
setupWidget();
}
......@@ -63,7 +64,6 @@ namespace campvis {
propertyCollection->s_propertyAdded.connect(this, &PropertyCollectionWidget::onPropCollectionPropAdded);
propertyCollection->s_propertyRemoved.connect(this, &PropertyCollectionWidget::onPropCollectionPropRemoved);
}
_layout->addStretch(1);
}
void PropertyCollectionWidget::setupWidget() {
......@@ -71,7 +71,10 @@ namespace campvis {
_layout->setSpacing(8);
_layout->setMargin(0);
setLayout(_layout);
connect(this, SIGNAL(s_propertyVisibilityChanged(const AbstractProperty*)), this, SLOT(onWidgetVisibilityChanged(const AbstractProperty*)), Qt::QueuedConnection);
_strechWidget = new QWidget(this);
connect(this, SIGNAL(s_propertyVisibilityChanged(const AbstractProperty*)), this, SLOT(onWidgetVisibilityChanged(const AbstractProperty*)));
connect(this, SIGNAL(propertyAdded(AbstractProperty*)), this, SLOT(addProperty(AbstractProperty*)));
connect(this, SIGNAL(propertyRemoved(AbstractProperty*, QWidget*)), this, SLOT(removeProperty(AbstractProperty*, QWidget*)));
}
......@@ -125,6 +128,9 @@ namespace campvis {
_widgetMap.insert(std::make_pair(prop, propWidget));
_layout->addWidget(propWidget);
_layout->removeWidget(_strechWidget);
_layout->addWidget(_strechWidget, 1);
prop->s_visibilityChanged.connect(this, &PropertyCollectionWidget::onPropertyVisibilityChanged);
prop->s_visibilityChanged.emitSignal(prop);
}
......
......@@ -117,6 +117,7 @@ namespace campvis {
DataContainer* _dataContainer; ///< The DataContainer the properties shall work on
QVBoxLayout* _layout;
QWidget* _strechWidget;
std::map<AbstractProperty*, QWidget*> _widgetMap;
};
}
......
......@@ -30,7 +30,7 @@
namespace campvis {
FaceGeometry* GeometryDataFactory::createQuad(const cgt::vec3& llf, const cgt::vec3& urb, const cgt::vec3& texLlf, const cgt::vec3& texUrb) {
std::unique_ptr<FaceGeometry> GeometryDataFactory::createQuad(const cgt::vec3& llf, const cgt::vec3& urb, const cgt::vec3& texLlf, const cgt::vec3& texUrb) {
std::vector<cgt::vec3> vertices, texCorods;
vertices.push_back(cgt::vec3(llf.x, llf.y, llf.z));
......@@ -43,10 +43,54 @@ namespace campvis {
texCorods.push_back(cgt::vec3(texUrb.x, texUrb.y, texLlf.z));
texCorods.push_back(cgt::vec3(texLlf.x, texUrb.y, texLlf.z));
return new FaceGeometry(vertices, texCorods);
return std::unique_ptr<FaceGeometry>(new FaceGeometry(vertices, texCorods));
}
MeshGeometry* GeometryDataFactory::createCube(const cgt::Bounds& bounds, const cgt::Bounds& texBounds) {
std::unique_ptr<MultiIndexedGeometry> GeometryDataFactory::createGrid(const cgt::vec3& llf, const cgt::vec3& urb, const cgt::vec3& texLlf, const cgt::vec3& texUrb, int xSegments, int ySegments) {
cgtAssert(xSegments > 0 && ySegments > 1, "Grid must have at least one segment in each direction");
int numVertices = (xSegments + 1) * (ySegments + 1);
std::vector<cgt::vec3> vertices(numVertices);
std::vector<cgt::vec3> textureCoordinates(numVertices);
std::vector<cgt::vec3> normals(numVertices);
// Compute vertices of the grid in x-major order
for (int y = 0; y <= ySegments; ++y) {
for (int x = 0; x <= xSegments; ++x) {
int idx = y * (xSegments + 1) + x;
float ux = x / static_cast<float>(xSegments);
float uy = y / static_cast<float>(ySegments);
vertices[idx] = cgt::vec3(llf.x * (1-ux) + urb.x * ux,
llf.y * (1-uy) + urb.y * uy,
llf.z);
textureCoordinates[idx] = cgt::vec3(texLlf.x * (1-ux) + texUrb.x * ux,
texLlf.y * (1-uy) + texUrb.y * uy,
texLlf.z);
normals[idx] = cgt::vec3(0, 0, 1);
}
}
auto result = new MultiIndexedGeometry(vertices, textureCoordinates, std::vector<cgt::vec4>(), normals);
// For each horizontal stripe, construct the indeces for triangle strips
int verticesPerStrip = (xSegments + 1) * 2;
for (int y = 0; y < ySegments; ++y) {
std::vector<uint16_t> indices(verticesPerStrip);
for (uint16_t x = 0; x <= xSegments; ++x) {
indices[x*2 + 0] = (y + 0) * (xSegments + 1) + x;
indices[x*2 + 1] = (y + 1) * (xSegments + 1) + x;
}
result->addPrimitive(indices);
}
return std::unique_ptr<MultiIndexedGeometry>(result);
}
std::unique_ptr<MeshGeometry> GeometryDataFactory::createCube(const cgt::Bounds& bounds, const cgt::Bounds& texBounds) {
const cgt::vec3& llf = bounds.getLLF();
const cgt::vec3& urb = bounds.getURB();
const cgt::vec3& tLlf = texBounds.getLLF();
......@@ -134,10 +178,10 @@ namespace campvis {
vertices.clear();
texCoords.clear();
return new MeshGeometry(faces);
return std::unique_ptr<MeshGeometry>(new MeshGeometry(faces));
}
MultiIndexedGeometry* GeometryDataFactory::createTeapot() {
std::unique_ptr<MultiIndexedGeometry> GeometryDataFactory::createTeapot() {
std::vector<cgt::vec3> vertices, normals;
vertices.reserve(Teapot::num_teapot_vertices);
normals.reserve(Teapot::num_teapot_vertices);
......@@ -157,10 +201,10 @@ namespace campvis {
currentOffset += count + 1;
}
return toReturn;
return std::unique_ptr<MultiIndexedGeometry>(toReturn);
}
MultiIndexedGeometry* GeometryDataFactory::createSphere(uint16_t numStacks /*= 6*/, uint16_t numSlices /*= 12*/, const cgt::vec3& exponents /*= cgt::vec3(1.f)*/) {
std::unique_ptr<MultiIndexedGeometry> GeometryDataFactory::createSphere(uint16_t numStacks /*= 6*/, uint16_t numSlices /*= 12*/, const cgt::vec3& exponents /*= cgt::vec3(1.f)*/) {
cgtAssert(numStacks > 1 && numSlices > 2, "Sphere must have minimum 2 stacks and 3 slices!");
std::vector<cgt::vec3> vertices;
std::vector<cgt::vec3> textureCoordinates;
......@@ -241,10 +285,10 @@ namespace campvis {
toReturn->addPrimitive(indices);
}
return toReturn;
return std::unique_ptr<MultiIndexedGeometry>(toReturn);
}
MultiIndexedGeometry* GeometryDataFactory::createArrow(uint16_t numSlices, float tipLen, float cylRadius, float tipRadius) {
std::unique_ptr<MultiIndexedGeometry> GeometryDataFactory::createArrow(uint16_t numSlices, float tipLen, float cylRadius, float tipRadius) {
cgtAssert(numSlices > 2, "Arrow shaft must have minimum 3 slices!");
cgtAssert(tipRadius > cylRadius, "Tip radius must exceed cyclinder radius (for correct normals)!");
cgtAssert(tipLen > 0, "Tip length must be between 0 and 1!");
......@@ -351,7 +395,7 @@ namespace campvis {
toReturn->addPrimitive(indices);
}
return toReturn;
return std::unique_ptr<MultiIndexedGeometry>(toReturn);
}
}
\ No newline at end of file
......@@ -34,6 +34,7 @@
#include "core/datastructures/multiindexedgeometry.h"
#include <vector>
#include <memory>
namespace campvis {
......@@ -42,29 +43,41 @@ namespace campvis {
/**
* Creates a FaceGeometry building an axis-aligned rectangle face in the YX plane (quad)
* with the given bounds and texture coordinates.
* \note Caller has to take ownership of the returned pointer.
* \param llf Coordinates of the lower left vertex
* \param urb Coordinates of the upper right vertex
* \param texLlf Texture coordinates of the lower left vertex
* \param texUrb Texture coordinates of the upper right vertex
* \return A FaceGeometry building a quad with the given bounds and texture coordinates.
*/
static FaceGeometry* createQuad(const cgt::vec3& llf, const cgt::vec3& urb, const cgt::vec3& texLlf, const cgt::vec3& texUrb);
static std::unique_ptr<FaceGeometry> createQuad(const cgt::vec3& llf, const cgt::vec3& urb, const cgt::vec3& texLlf, const cgt::vec3& texUrb);
/**
* Creates a MultiIndexedGeometry building an axis-aligned rectangular gird in the YX plane
* with the given bounds and texture coordinates. This primitive is useful to display a distorted
* texture without noticeable artefacts.
* \param llf Coordinates of the lower left vertex
* \param urb Coordinates of the upper right vertex
* \param texLlf Texture coordinates of the lower left vertex
* \param texUrb Texture coordinates of the upper right vertex
* \param xSegments Number of segments along x direction
* \param ySegments Number of segments along y direction
* \return A MultiIndexedGeometry building a grid with the given bounds and texture coordinates.
*/
static std::unique_ptr<MultiIndexedGeometry> createGrid(const cgt::vec3& llf, const cgt::vec3& urb, const cgt::vec3& texLlf, const cgt::vec3& texUrb, int xSegments = 4, int ySegments = 4);
/**
* Creates a MeshGeometry building a cube with the given bounds and texture coordinates.
* \note Caller has to take ownership of the returned pointer.
* \param bounds coordinates of the cube bounds
* \param texBounds texture coordinates at the cube bounds
* \return A MeshGeometry building a cube with the given bounds and texture coordinates.
*/
static MeshGeometry* createCube(const cgt::Bounds& bounds, const cgt::Bounds& texBounds);
static std::unique_ptr<MeshGeometry> createCube(const cgt::Bounds& bounds, const cgt::Bounds& texBounds);
/**
* Creates an MultiIndexedGeometry storing the famous Utah teapot.
* \return MultiIndexedGeometry storing the famous Utah teapot.
*/
static MultiIndexedGeometry* createTeapot();
static std::unique_ptr<MultiIndexedGeometry> createTeapot();