Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
CAMP
campvis-public
Commits
1c50f447
Commit
1c50f447
authored
Oct 09, 2013
by
Christian Schulte zu Berge
Browse files
Merge remote-tracking branch 'remotes/origin/refactor-pipeline-concept' into development
parents
37886930
73cd3ed8
Changes
239
Hide whitespace changes
Inline
Side-by-side
application/campvis.cpp
View file @
1c50f447
...
...
@@ -28,24 +28,6 @@
// ================================================================================================
#include
"application/campvisapplication.h"
#include
"modules/advancedusvis/pipelines/advancedusvis.h"
#include
"modules/advancedusvis/pipelines/cmbatchgeneration.h"
#include
"modules/vis/pipelines/ixpvdemo.h"
#include
"modules/vis/pipelines/dvrvis.h"
#include
"modules/vis/pipelines/volumerendererdemo.h"
#include
"modules/vis/pipelines/volumeexplorerdemo.h"
#include
"modules/vis/pipelines/slicevis.h"
#ifdef HAS_KISSCL
#include
"modules/opencl/pipelines/openclpipeline.h"
#endif
#ifdef CAMPVIS_HAS_MODULE_SCR_MSK
#include
"modules/scr_msk/pipelines/uscompounding.h"
#endif
#ifdef CAMPVIS_HAS_MODULE_COLUMBIA
#include
"modules/columbia/pipelines/columbia1.h"
#endif
#ifdef Q_WS_X11
#include
<X11/Xlib.h>
...
...
@@ -66,27 +48,6 @@ int main(int argc, char** argv) {
#endif
CampVisApplication
app
(
argc
,
argv
);
// app.addVisualizationPipeline("Advanced Ultrasound Visualization", new AdvancedUsVis());
// app.addVisualizationPipeline("Confidence Map Generation", new CmBatchGeneration());
// app.addVisualizationPipeline("IXPV", new IxpvDemo());
app
.
addVisualizationPipeline
(
"SliceVis"
,
new
SliceVis
());
// app.addVisualizationPipeline("DVRVis", new DVRVis());
// app.addVisualizationPipeline("VolumeRendererDemo", new VolumeRendererDemo());
app
.
addVisualizationPipeline
(
"VolumeExplorerDemo"
,
new
VolumeExplorerDemo
());
#ifdef HAS_KISSCL
// app.addVisualizationPipeline("DVR with OpenCL", new OpenCLPipeline());
#endif
#ifdef CAMPVIS_HAS_MODULE_SCR_MSK
app
.
addVisualizationPipeline
(
"US Compounding"
,
new
UsCompounding
());
#endif
#ifdef CAMPVIS_HAS_MODULE_COLUMBIA
app
.
addVisualizationPipeline
(
"Columbia"
,
new
Columbia1
());
#endif
app
.
init
();
int
toReturn
=
app
.
run
();
app
.
deinit
();
...
...
application/campvisapplication.cpp
View file @
1c50f447
...
...
@@ -47,9 +47,10 @@
#include
"application/gui/mainwindow.h"
#include
"core/tools/opengljobprocessor.h"
#include
"core/tools/simplejobprocessor.h"
#include
"core/tools/stringutils.h"
#include
"core/tools/quadrenderer.h"
#include
"core/pipeline/abstractpipeline.h"
#include
"
core
/pipeline
/visualizationpipeline
.h"
#include
"
modules
/pipeline
factory
.h"
namespace
campvis
{
...
...
@@ -78,17 +79,29 @@ namespace campvis {
tgtAssert
(
_initialized
==
false
,
"Destructing initialized CampVisApplication, deinitialize first!"
);
// delete everything in the right order:
for
(
std
::
vector
<
std
::
pair
<
Visualization
Pipeline
*
,
CampVisPainter
*>
>::
iterator
it
=
_visualizations
.
begin
();
it
!=
_visualizations
.
end
();
++
it
)
{
for
(
std
::
vector
<
std
::
pair
<
Abstract
Pipeline
*
,
CampVisPainter
*>
>::
iterator
it
=
_visualizations
.
begin
();
it
!=
_visualizations
.
end
();
++
it
)
{
delete
it
->
second
;
}
for
(
std
::
vector
<
AbstractPipeline
*>::
iterator
it
=
_pipelines
.
begin
();
it
!=
_pipelines
.
end
();
++
it
)
{
delete
*
it
;
}
for
(
std
::
vector
<
DataContainer
*>::
iterator
it
=
_dataContainers
.
begin
();
it
!=
_dataContainers
.
end
();
++
it
)
{
delete
*
it
;
}
}
void
CampVisApplication
::
init
()
{
tgtAssert
(
_initialized
==
false
,
"Tried to initialize CampVisApplication twice."
);
// parse argument list and create pipelines
QStringList
pipelinesToAdd
=
this
->
arguments
();
for
(
int
i
=
1
;
i
<
pipelinesToAdd
.
size
();
++
i
)
{
DataContainer
*
dc
=
createAndAddDataContainer
(
"DataContainer #"
+
StringUtils
::
toString
(
_dataContainers
.
size
()
+
1
));
AbstractPipeline
*
p
=
PipelineFactory
::
getRef
().
createPipeline
(
pipelinesToAdd
[
i
].
toStdString
(),
dc
);
if
(
p
!=
0
)
addPipeline
(
pipelinesToAdd
[
i
].
toStdString
(),
p
);
}
// Init TGT
tgt
::
InitFeature
::
Features
featureset
=
tgt
::
InitFeature
::
ALL
;
tgt
::
init
(
featureset
);
...
...
@@ -167,7 +180,7 @@ namespace campvis {
}
// Now init painters:
for
(
std
::
vector
<
std
::
pair
<
Visualization
Pipeline
*
,
CampVisPainter
*>
>::
iterator
it
=
_visualizations
.
begin
();
it
!=
_visualizations
.
end
();
++
it
)
{
for
(
std
::
vector
<
std
::
pair
<
Abstract
Pipeline
*
,
CampVisPainter
*>
>::
iterator
it
=
_visualizations
.
begin
();
it
!=
_visualizations
.
end
();
++
it
)
{
it
->
second
->
init
();
}
...
...
@@ -190,7 +203,7 @@ namespace campvis {
}
// Now deinit painters:
for
(
std
::
vector
<
std
::
pair
<
Visualization
Pipeline
*
,
CampVisPainter
*>
>::
iterator
it
=
_visualizations
.
begin
();
it
!=
_visualizations
.
end
();
++
it
)
{
for
(
std
::
vector
<
std
::
pair
<
Abstract
Pipeline
*
,
CampVisPainter
*>
>::
iterator
it
=
_visualizations
.
begin
();
it
!=
_visualizations
.
end
();
++
it
)
{
it
->
second
->
deinit
();
}
...
...
@@ -235,33 +248,57 @@ namespace campvis {
return
toReturn
;
}
void
CampVisApplication
::
addPipeline
(
AbstractPipeline
*
pipeline
)
{
tgtAssert
(
_initialized
==
false
,
"Adding pipelines after initialization is currently not supported."
);
void
CampVisApplication
::
addPipeline
(
const
std
::
string
&
name
,
AbstractPipeline
*
pipeline
)
{
tgtAssert
(
pipeline
!=
0
,
"Pipeline must not be 0."
);
_pipelines
.
push_back
(
pipeline
);
// if CAMPVis is already fully initialized, we need to temporarily shut down its
// OpenGL job processor, since we need to create a new context.
if
(
_initialized
)
{
GLJobProc
.
pause
();
{
tgt
::
QtThreadedCanvas
*
canvas
=
CtxtMgr
.
createContext
(
name
,
"CAMPVis"
,
tgt
::
ivec2
(
512
,
512
));
tgt
::
GLContextScopedLock
lock
(
canvas
->
getContext
());
addPipelineImpl
(
canvas
,
name
,
pipeline
);
}
GLJobProc
.
resume
();
}
else
{
tgt
::
QtThreadedCanvas
*
canvas
=
CtxtMgr
.
createContext
(
name
,
"CAMPVis"
,
tgt
::
ivec2
(
512
,
512
));
addPipelineImpl
(
canvas
,
name
,
pipeline
);
}
s_PipelinesChanged
();
}
void
CampVisApplication
::
addVisualizationPipeline
(
const
std
::
string
&
name
,
VisualizationPipeline
*
vp
)
{
tgtAssert
(
_initialized
==
false
,
"Adding pipelines after initialization is currently not supported."
);
tgtAssert
(
vp
!=
0
,
"Pipeline must not be 0."
);
// create canvas and painter for the VisPipeline and connect all together
tgt
::
QtThreadedCanvas
*
canvas
=
CtxtMgr
.
createContext
(
name
,
"CAMPVis"
,
tgt
::
ivec2
(
512
,
512
));
void
CampVisApplication
::
addPipelineImpl
(
tgt
::
QtThreadedCanvas
*
canvas
,
const
std
::
string
&
name
,
AbstractPipeline
*
pipeline
)
{
// create canvas and painter for the pipeline and connect all together
GLJobProc
.
registerContext
(
canvas
);
_mainWindow
->
addVisualizationPipelineWidget
(
name
,
canvas
);
canvas
->
init
();
CampVisPainter
*
painter
=
new
CampVisPainter
(
canvas
,
v
p
);
CampVisPainter
*
painter
=
new
CampVisPainter
(
canvas
,
p
ipeline
);
canvas
->
setPainter
(
painter
,
false
);
pipeline
->
setCanvas
(
canvas
);
_visualizations
.
push_back
(
std
::
make_pair
(
vp
,
painter
));
_visualizations
.
push_back
(
std
::
make_pair
(
pipeline
,
painter
));
_pipelines
.
push_back
(
pipeline
);
vp
->
setCanvas
(
canvas
);
addPipeline
(
vp
);
if
(
_initialized
)
{
LGL_ERROR
;
pipeline
->
init
();
LGL_ERROR
;
painter
->
init
();
LGL_ERROR
;
}
CtxtMgr
.
releaseCurrentContext
();
_mainWindow
->
addVisualizationPipelineWidget
(
name
,
canvas
);
// enable pipeline and invalidate all processors
pipeline
->
setEnabled
(
true
);
for
(
std
::
vector
<
AbstractProcessor
*>::
const_iterator
it
=
pipeline
->
getProcessors
().
begin
();
it
!=
pipeline
->
getProcessors
().
end
();
++
it
)
{
(
*
it
)
->
invalidate
(
AbstractProcessor
::
INVALID_RESULT
);
}
}
void
CampVisApplication
::
registerDockWidget
(
Qt
::
DockWidgetArea
area
,
QDockWidget
*
dock
)
{
...
...
@@ -270,4 +307,12 @@ namespace campvis {
_mainWindow
->
addDockWidget
(
area
,
dock
);
}
DataContainer
*
CampVisApplication
::
createAndAddDataContainer
(
const
std
::
string
&
name
)
{
DataContainer
*
dc
=
new
DataContainer
(
name
);
_dataContainers
.
push_back
(
dc
);
s_DataContainersChanged
();
return
dc
;
}
}
application/campvisapplication.h
View file @
1c50f447
...
...
@@ -38,6 +38,8 @@
#include
<utility>
#include
<vector>
#include
"core/datastructures/datacontainer.h"
namespace
tgt
{
class
QtThreadedCanvas
;
}
...
...
@@ -46,7 +48,6 @@ namespace campvis {
class
AbstractPipeline
;
class
MainWindow
;
class
CampVisPainter
;
class
VisualizationPipeline
;
/**
* The CampVisApplication class wraps Pipelines, Evaluators and Painters all together and takes
...
...
@@ -89,25 +90,14 @@ namespace campvis {
void
deinit
();
/**
* Adds a pipeline which doesn't need visualization (OpenGL) support.
* Each pipeline will automatically get its own evaluator.
*
* \note If you want to add a pipeline that needs a valid OpenGL context, use
* addVisualizationPipeline() instead.
* \param pipeline Pipeline to add, must not need OpenGL support.
*/
void
addPipeline
(
AbstractPipeline
*
pipeline
);
/**
* Adds a visualization pipeline (i.e. a pipeline that needs a OpenGL context).
* For each added pipeline, an OpenGL context will be created (for the evaluation
* and rendering).
* Adds a pipeline to this CAMPVis application.
* Each pipeline will automatically get its own OpenGL context, the corresponding CampvisPainter
* and all necessary connections will be created.
*
* \note You do \b not need to call addPipeline.
* \param name Name of the OpenGL context to create for the pipeline.
* \param vp
Visualization
Pipeline to add.
* \param vp
Abstract
Pipeline to add.
*/
void
add
Visualization
Pipeline
(
const
std
::
string
&
name
,
Visualization
Pipeline
*
v
p
);
void
addPipeline
(
const
std
::
string
&
name
,
Abstract
Pipeline
*
p
ipeline
);
/**
* Adds a dock widget to the main window.
...
...
@@ -125,14 +115,30 @@ namespace campvis {
*/
int
run
();
/**
* Creates a new DataContainer with the given name.
* \param name Name of the new DataContainer
* \return The newly created DataContainer
*/
DataContainer
*
createAndAddDataContainer
(
const
std
::
string
&
name
);
/// Signal emitted when the collection of pipelines has changed.
sigslot
::
signal0
<>
s_PipelinesChanged
;
/// Signal emitted when the collection of DataContainers has changed.
sigslot
::
signal0
<>
s_DataContainersChanged
;
private:
/// All pipelines (incuding VisualizationPipelines)
void
addPipelineImpl
(
tgt
::
QtThreadedCanvas
*
canvas
,
const
std
::
string
&
name
,
AbstractPipeline
*
pipeline
);
/// All pipelines
std
::
vector
<
AbstractPipeline
*>
_pipelines
;
/// All visualisations (i.e. VisualizationPipelines with their corresponding painters/canvases)
std
::
vector
<
std
::
pair
<
VisualizationPipeline
*
,
CampVisPainter
*>
>
_visualizations
;
/// All visualisations (i.e. Pipelines with their corresponding painters/canvases)
std
::
vector
<
std
::
pair
<
AbstractPipeline
*
,
CampVisPainter
*>
>
_visualizations
;
/// All DataContainers
std
::
vector
<
DataContainer
*>
_dataContainers
;
/// A local OpenGL context used for initialization
tgt
::
QtThreadedCanvas
*
_localContext
;
...
...
application/campvispainter.cpp
View file @
1c50f447
...
...
@@ -41,7 +41,7 @@
#include
"core/datastructures/imagedata.h"
#include
"core/datastructures/renderdata.h"
#include
"core/pipeline/
visualization
pipeline.h"
#include
"core/pipeline/
abstract
pipeline.h"
#include
"core/tools/job.h"
#include
"core/tools/opengljobprocessor.h"
#include
"core/tools/quadrenderer.h"
...
...
@@ -49,7 +49,7 @@
namespace
campvis
{
const
std
::
string
CampVisPainter
::
loggerCat_
=
"CAMPVis.core.CampVisPainter"
;
CampVisPainter
::
CampVisPainter
(
tgt
::
GLCanvas
*
canvas
,
Visualization
Pipeline
*
pipeline
)
CampVisPainter
::
CampVisPainter
(
tgt
::
GLCanvas
*
canvas
,
Abstract
Pipeline
*
pipeline
)
:
Runnable
()
,
tgt
::
Painter
(
canvas
)
,
_pipeline
(
0
)
...
...
@@ -97,7 +97,7 @@ namespace campvis {
glViewport
(
0
,
0
,
size
.
x
,
size
.
y
);
// try get Data
DataContainer
::
ScopedTypedData
<
RenderData
>
rd
(
_pipeline
->
getDataContainer
(),
_pipeline
->
getRenderTargetID
());
ScopedTypedData
<
RenderData
>
rd
(
_pipeline
->
getDataContainer
(),
_pipeline
->
getRenderTargetID
());
glClear
(
GL_COLOR_BUFFER_BIT
|
GL_DEPTH_BUFFER_BIT
);
if
(
rd
!=
0
)
{
// activate shader
...
...
@@ -175,7 +175,7 @@ namespace campvis {
}
}
void
CampVisPainter
::
setPipeline
(
Visualization
Pipeline
*
pipeline
)
{
void
CampVisPainter
::
setPipeline
(
Abstract
Pipeline
*
pipeline
)
{
tgtAssert
(
pipeline
!=
0
,
"The given pipeline must not be 0."
);
if
(
_pipeline
!=
0
)
{
_pipeline
->
s_renderTargetChanged
.
disconnect
(
this
);
...
...
application/campvispainter.h
View file @
1c50f447
...
...
@@ -44,16 +44,16 @@ namespace tgt {
}
namespace
campvis
{
class
Visualization
Pipeline
;
class
Abstract
Pipeline
;
/**
* Painter class for CAMPVis, rendering the render target of a
Visualization
Pipeline.
* Painter class for CAMPVis, rendering the render target of a
n Abstract
Pipeline.
* This painter implements Runnable, hence, it runs in its own thread and the associated canvas
* must be of type QtThreadedCanvas.
* Rendering is implemented using condidional wait - hence the canvas is only updated when
* \a pipeline emits the s_RenderTargetChanged signal.
*
* \sa Runnable,
Visualization
Pipeline
* \sa Runnable,
Abstract
Pipeline
*/
class
CampVisPainter
:
public
Runnable
,
public
tgt
::
Painter
,
public
sigslot
::
has_slots
<>
{
public:
...
...
@@ -62,7 +62,7 @@ namespace campvis {
* \param canvas Canvas to render on
* \param pipeline Pipeline to render
*/
CampVisPainter
(
tgt
::
GLCanvas
*
canvas
,
Visualization
Pipeline
*
pipeline
);
CampVisPainter
(
tgt
::
GLCanvas
*
canvas
,
Abstract
Pipeline
*
pipeline
);
/**
* Destructor, stops and waits for the rendering thread if it's still running.
...
...
@@ -106,7 +106,7 @@ namespace campvis {
* Pipeline with the render target to render.
* \param pipeline Pipeline to render
*/
void
setPipeline
(
Visualization
Pipeline
*
pipeline
);
void
setPipeline
(
Abstract
Pipeline
*
pipeline
);
/**
* Slot being notified when the pipeline's render target changed.
...
...
@@ -121,7 +121,7 @@ namespace campvis {
static
const
std
::
string
loggerCat_
;
Visualization
Pipeline
*
_pipeline
;
///< Pipeline to render
Abstract
Pipeline
*
_pipeline
;
///< Pipeline to render
tgt
::
Shader
*
_copyShader
;
///< Shader for copying the render target to the framebuffer.
tbb
::
atomic
<
bool
>
_dirty
;
///< Flag whether render result is dirty and needs to be rerendered.
std
::
condition_variable
_renderCondition
;
///< conditional wait condition for rendering
...
...
application/gui/mainwindow.cpp
View file @
1c50f447
...
...
@@ -35,18 +35,25 @@
#include
"application/gui/datacontainerinspectorcanvas.h"
#include
"application/gui/qtdatahandle.h"
#include
"application/gui/visualizationpipelinewrapper.h"
#include
"core/datastructures/datacontainer.h"
#include
"core/pipeline/abstractpipeline.h"
#include
"core/pipeline/abstractprocessor.h"
#include
"core/tools/stringutils.h"
#include
"modules/pipelinefactory.h"
#include
<QMdiSubWindow>
#include
<QScrollBar>
namespace
campvis
{
MainWindow
::
MainWindow
(
CampVisApplication
*
application
)
:
QMainWindow
()
,
_application
(
application
)
,
_mdiArea
(
0
)
,
_containerWidget
(
0
)
,
_cbPipelineFactory
(
0
)
,
_btnPipelineFactory
(
0
)
,
_pipelineWidget
(
0
)
,
_propCollectionWidget
(
0
)
,
_dcInspectorWidget
(
0
)
...
...
@@ -55,6 +62,7 @@ namespace campvis {
,
_btnShowDataContainerInspector
(
0
)
,
_selectedPipeline
(
0
)
,
_selectedProcessor
(
0
)
,
_selectedDataContainer
(
0
)
,
_logViewer
(
0
)
{
tgtAssert
(
_application
!=
0
,
"Application must not be 0."
);
...
...
@@ -64,6 +72,7 @@ namespace campvis {
MainWindow
::~
MainWindow
()
{
_application
->
s_PipelinesChanged
.
disconnect
(
this
);
_application
->
s_DataContainersChanged
.
disconnect
(
this
);
delete
_dcInspectorWidget
;
}
...
...
@@ -81,9 +90,24 @@ namespace campvis {
_mdiArea
->
tileSubWindows
();
setCentralWidget
(
_mdiArea
);
_containerWidget
=
new
QWidget
(
this
);
QGridLayout
*
_cwLayout
=
new
QGridLayout
(
_containerWidget
);
_cbPipelineFactory
=
new
QComboBox
(
_containerWidget
);
std
::
vector
<
std
::
string
>
registeredPipelines
=
PipelineFactory
::
getRef
().
getRegisteredPipelines
();
for
(
std
::
vector
<
std
::
string
>::
const_iterator
it
=
registeredPipelines
.
begin
();
it
!=
registeredPipelines
.
end
();
++
it
)
_cbPipelineFactory
->
addItem
(
QString
::
fromStdString
(
*
it
));
_cwLayout
->
addWidget
(
_cbPipelineFactory
,
0
,
0
);
_btnPipelineFactory
=
new
QPushButton
(
"Add Pipeline"
,
_containerWidget
);
_cwLayout
->
addWidget
(
_btnPipelineFactory
,
0
,
1
);
_pipelineWidget
=
new
PipelineTreeWidget
();
_pipelineWidget
->
setSizePolicy
(
QSizePolicy
::
Preferred
,
QSizePolicy
::
Maximum
);
ui
.
pipelineTreeDock
->
setWidget
(
_pipelineWidget
);
_containerWidget
->
setSizePolicy
(
QSizePolicy
::
Preferred
,
QSizePolicy
::
Maximum
);
_cwLayout
->
addWidget
(
_pipelineWidget
,
1
,
0
,
1
,
2
);
_containerWidget
->
setLayout
(
_cwLayout
);
ui
.
pipelineTreeDock
->
setWidget
(
_containerWidget
);
_pipelinePropertiesScrollArea
=
new
QScrollArea
();
_pipelinePropertiesScrollArea
->
setWidgetResizable
(
true
);
...
...
@@ -115,8 +139,8 @@ namespace campvis {
_dcInspectorWidget
=
new
DataContainerInspectorWidget
();
connect
(
this
,
SIGNAL
(
updatePipelineWidget
(
const
std
::
vector
<
AbstractPipeline
*>&
)),
_pipelineWidget
,
SLOT
(
update
(
const
std
::
vector
<
AbstractPipeline
*>&
)));
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
&
)));
...
...
@@ -129,7 +153,12 @@ namespace campvis {
connect
(
_btnShowDataContainerInspector
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
onBtnShowDataContainerInspectorClicked
()));
connect
(
_btnPipelineFactory
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
onBtnPipelineFactoryClicked
()));
_application
->
s_PipelinesChanged
.
connect
(
this
,
&
MainWindow
::
onPipelinesChanged
);
_application
->
s_DataContainersChanged
.
connect
(
this
,
&
MainWindow
::
onDataContainersChanged
);
}
bool
MainWindow
::
eventFilter
(
QObject
*
watched
,
QEvent
*
event
)
{
...
...
@@ -142,38 +171,51 @@ namespace campvis {
}
void
MainWindow
::
onPipelinesChanged
()
{
emit
updatePipelineWidget
(
_application
->
_pipelines
);
emit
updatePipelineWidget
(
_application
->
_dataContainers
,
_application
->
_pipelines
);
}
void
MainWindow
::
onDataContainersChanged
()
{
emit
updatePipelineWidget
(
_application
->
_dataContainers
,
_application
->
_pipelines
);
}
void
MainWindow
::
onPipelineWidgetItemClicked
(
const
QModelIndex
&
index
)
{
if
(
index
.
isValid
())
{
// Yak, this is so ugly - another reason why GUI programming sucks...
QVariant
item
=
index
.
data
(
Qt
::
UserRole
);
HasPropertyCollection
*
ptr
=
static_cast
<
HasPropertyCollection
*>
(
item
.
value
<
void
*>
());
if
(
item
.
isValid
())
{
HasPropertyCollection
*
ptr
=
static_cast
<
HasPropertyCollection
*>
(
item
.
value
<
void
*>
());
if
(
AbstractPipeline
*
pipeline
=
dynamic_cast
<
AbstractPipeline
*>
(
ptr
))
{
_selectedPipeline
=
pipeline
;
_selectedProcessor
=
0
;
}
else
if
(
AbstractProcessor
*
processor
=
dynamic_cast
<
AbstractProcessor
*>
(
ptr
))
{
_selectedProcessor
=
processor
;
QVariant
parentItem
=
index
.
parent
().
data
(
Qt
::
UserRole
);
HasPropertyCollection
*
pptr
=
static_cast
<
HasPropertyCollection
*>
(
parentItem
.
value
<
void
*>
());
if
(
AbstractPipeline
*
pipeline
=
dynamic_cast
<
AbstractPipeline
*>
(
pptr
))
{
if
(
AbstractPipeline
*
pipeline
=
dynamic_cast
<
AbstractPipeline
*>
(
ptr
))
{
_selectedPipeline
=
pipeline
;
_selectedProcessor
=
0
;
_selectedDataContainer
=
&
pipeline
->
getDataContainer
();
}
else
if
(
AbstractProcessor
*
processor
=
dynamic_cast
<
AbstractProcessor
*>
(
ptr
))
{
_selectedProcessor
=
processor
;
QVariant
parentItem
=
index
.
parent
().
data
(
Qt
::
UserRole
);
HasPropertyCollection
*
pptr
=
static_cast
<
HasPropertyCollection
*>
(
parentItem
.
value
<
void
*>
());
if
(
AbstractPipeline
*
pipeline
=
dynamic_cast
<
AbstractPipeline
*>
(
pptr
))
{
_selectedPipeline
=
pipeline
;
_selectedDataContainer
=
&
pipeline
->
getDataContainer
();
}
}
}
emit
updatePropCollectionWidget
(
ptr
,
&
_selectedPipeline
->
getDataContainer
());
emit
updatePropCollectionWidget
(
ptr
,
&
_selectedPipeline
->
getDataContainer
());
}
else
{
emit
updatePropCollectionWidget
(
0
,
0
);
_selectedDataContainer
=
0
;
}
}
else
{
emit
updatePropCollectionWidget
(
0
,
0
);
_selectedDataContainer
=
0
;
}
}
QSize
MainWindow
::
sizeHint
()
const
{
return
QSize
(
8
00
,
45
0
);
return
QSize
(
10
00
,
60
0
);
}
void
MainWindow
::
onBtnExecuteClicked
()
{
...
...
@@ -239,4 +281,14 @@ namespace campvis {
return
dockWidget
;
}
void
MainWindow
::
onBtnPipelineFactoryClicked
()
{
std
::
string
name
=
this
->
_cbPipelineFactory
->
currentText
().
toStdString
();
DataContainer
*
dc
=
_selectedDataContainer
;
if
(
dc
==
0
)
{
dc
=
_application
->
createAndAddDataContainer
(
"DataContainer #"
+
StringUtils
::
toString
(
_application
->
_dataContainers
.
size
()
+
1
));
}
AbstractPipeline
*
p
=
PipelineFactory
::
getRef
().
createPipeline
(
name
,
dc
);
_application
->
addPipeline
(
name
,
p
);
}
}
application/gui/mainwindow.h
View file @
1c50f447
...
...
@@ -42,6 +42,7 @@
#include
<QVBoxLayout>
#include
<QHBoxLayout>
#include
<QPushButton>
#include
<QComboBox>
#include
<QMdiArea>
#include
<QScrollArea>
#include
<vector>
...
...
@@ -80,11 +81,6 @@ namespace campvis {
*/
void
deinit
();
/**
* Slot to be called by the application when its collection of pipelines has changed.
*/
void
onPipelinesChanged
();
/**
* Size hint for the default window size
* \return QSize(800, 450)
...
...
@@ -108,7 +104,8 @@ namespace campvis {
signals:
/// Qt signal for updating the PipelineWidget.
void
updatePipelineWidget
(
const
std
::
vector
<
AbstractPipeline
*>&
);
void
updatePipelineWidget
(
const
std
::
vector
<
DataContainer
*>&
,
const
std
::
vector
<
AbstractPipeline
*>&
);
/// Qt signal for updating the PropertyCollectionWidget
void
updatePropCollectionWidget
(
HasPropertyCollection
*
,
DataContainer
*
);
...
...
@@ -129,7 +126,22 @@ namespace campvis {
*/
void
onBtnShowDataContainerInspectorClicked
();
/// Slot to be called when _btnPipelineFactory was clicked;
void
onBtnPipelineFactoryClicked
();
private:
/**
* Slot to be called by the application when its collection of pipelines has changed.
*/
void
onPipelinesChanged
();
/**
* Slot to be called by the application when its collection of DataContainers has changed.
*/
void
onDataContainersChanged
();
/**
* Setup Qt GUI stuff
*/
...
...
@@ -152,6 +164,9 @@ namespace campvis {
CampVisApplication
*
_application
;
///< Pointer to the application hosting the whole stuff
QMdiArea
*
_mdiArea
;
///< MDI area (the window's central widget)
QWidget
*
_containerWidget
;
///< Widget to manage the app's DataContainers and pipelines
QComboBox
*
_cbPipelineFactory
;
///< Combobox for selecting the Pipelines from the PipelineFactory
QPushButton
*
_btnPipelineFactory
;
///< Button to add a Pipeline from the factory
PipelineTreeWidget
*
_pipelineWidget
;
///< Widget for browsing the active pipelines
QWidget
*
_pipelinePropertiesWidget
;
///< Widget showing the selected pipeline's properties
QScrollArea
*
_pipelinePropertiesScrollArea
;
///< Scroll area for _pipelinePropertiesWidget
...
...
@@ -164,6 +179,8 @@ namespace campvis {
AbstractPipeline
*
_selectedPipeline
;
///< currently selected pipeline
AbstractProcessor
*
_selectedProcessor
;
///< currently selected processor
DataContainer
*
_selectedDataContainer
;
///< currently selected DataContainer
LogViewerWidget
*
_logViewer
;
///< Widget displaying log messages
std
::
vector
<
QDockWidget
*>
_primaryDocks
;
///< Docks located in top docking area of the main window
};
...
...
application/gui/pipelinetreewidget.cpp
View file @
1c50f447
...
...
@@ -45,6 +45,38 @@ namespace campvis {
// = TreeModel items ==============================================================================
DataContainerTreeItem
::
DataContainerTreeItem
(
DataContainer
*
dc
,
TreeItem
*
parent
)
:
TreeItem
(
parent
)
,
_dataContainer
(
dc
)
{
tgtAssert
(
_dataContainer
!=
0
,
"Pipeline must not be 0."
);