Commit db28eed0 authored by KLOCZKO Thibaud's avatar KLOCZKO Thibaud

Add stream tracer.

parent fd81f6bd
......@@ -296,17 +296,18 @@ void dtkVisualizationViewer::importDataSet(const QString& path)
QVariant data = dtk::variantFromValue(d->dataset);
dtkVisualizationDecoratorInfo *decorator_info = new dtkVisualizationDecoratorInfo;
dtkVisualizationDecoratorAxes *decorator_axes = new dtkVisualizationDecoratorAxes;
dtkVisualizationDecoratorDelaunay2D *decorator_delaunay_2D = new dtkVisualizationDecoratorDelaunay2D;
dtkVisualizationDecoratorPoints *decorator_points = new dtkVisualizationDecoratorPoints;
dtkVisualizationDecoratorScalarColorMap *decorator_scalar_colormap = new dtkVisualizationDecoratorScalarColorMap;
dtkVisualizationDecoratorScalarGlyphs *decorator_scalar_glyphs = new dtkVisualizationDecoratorScalarGlyphs;
dtkVisualizationDecoratorScalarIsolines *decorator_scalar_isolines = new dtkVisualizationDecoratorScalarIsolines;
dtkVisualizationDecoratorSlices *decorator_slices = new dtkVisualizationDecoratorSlices;
dtkVisualizationDecoratorSnapshot *decorator_snapshot = new dtkVisualizationDecoratorSnapshot;
dtkVisualizationDecoratorVectorStreamlines *decorator_vector_streamlines = new dtkVisualizationDecoratorVectorStreamlines;
dtkVisualizationDecoratorVolume *decorator_volume = new dtkVisualizationDecoratorVolume;
dtkVisualizationDecoratorInfo *decorator_info = new dtkVisualizationDecoratorInfo;
dtkVisualizationDecoratorAxes *decorator_axes = new dtkVisualizationDecoratorAxes;
dtkVisualizationDecoratorDelaunay2D *decorator_delaunay_2D = new dtkVisualizationDecoratorDelaunay2D;
dtkVisualizationDecoratorPoints *decorator_points = new dtkVisualizationDecoratorPoints;
dtkVisualizationDecoratorScalarColorMap *decorator_scalar_colormap = new dtkVisualizationDecoratorScalarColorMap;
dtkVisualizationDecoratorScalarGlyphs *decorator_scalar_glyphs = new dtkVisualizationDecoratorScalarGlyphs;
dtkVisualizationDecoratorScalarIsolines *decorator_scalar_isolines = new dtkVisualizationDecoratorScalarIsolines;
dtkVisualizationDecoratorSlices *decorator_slices = new dtkVisualizationDecoratorSlices;
dtkVisualizationDecoratorSnapshot *decorator_snapshot = new dtkVisualizationDecoratorSnapshot;
dtkVisualizationDecoratorVectorStreamlines *decorator_vector_streamlines = new dtkVisualizationDecoratorVectorStreamlines;
dtkVisualizationDecoratorVectorStreamTracer *decorator_vector_streamtracer = new dtkVisualizationDecoratorVectorStreamTracer;
dtkVisualizationDecoratorVolume *decorator_volume = new dtkVisualizationDecoratorVolume;
QList<dtkVisualizationDecorator *> decorators;
decorators << decorator_points
......@@ -315,6 +316,7 @@ void dtkVisualizationViewer::importDataSet(const QString& path)
<< decorator_scalar_isolines
<< decorator_scalar_glyphs
<< decorator_vector_streamlines
<< decorator_vector_streamtracer
<< decorator_volume
<< decorator_slices
<< decorator_axes
......
......@@ -53,6 +53,8 @@ set(${PROJECT_NAME}_HEADERS
dtkVisualizationDecoratorSnapshot.h
dtkVisualizationDecoratorVectorStreamlines
dtkVisualizationDecoratorVectorStreamlines.h
dtkVisualizationDecoratorVectorStreamTracer
dtkVisualizationDecoratorVectorStreamTracer.h
dtkVisualizationDecoratorVolume
dtkVisualizationDecoratorVolume.h
dtkVisualizationDecoratorWithClut
......@@ -103,6 +105,7 @@ set(${PROJECT_NAME}_SOURCES
dtkVisualizationDecoratorSlices.cpp
dtkVisualizationDecoratorSnapshot.cpp
dtkVisualizationDecoratorVectorStreamlines.cpp
dtkVisualizationDecoratorVectorStreamTracer.cpp
dtkVisualizationDecoratorVolume.cpp
dtkVisualizationDecoratorWithClut.cpp
dtkVisualizationMetaType.cpp
......
......@@ -15,6 +15,7 @@
#include "dtkVisualizationDecoratorSlices.h"
#include "dtkVisualizationDecoratorSnapshot.h"
#include "dtkVisualizationDecoratorVectorStreamlines.h"
#include "dtkVisualizationDecoratorVectorStreamTracer.h"
#include "dtkVisualizationDecoratorVolume.h"
#include "dtkVisualizationDecoratorWithClut.h"
#include "dtkVisualizationMetaType.h"
......
#include "dtkVisualizationDecoratorVectorStreamTracer.h"
// dtkVisualizationDecoratorVectorStreamTracer.cpp
//
#include "dtkVisualizationDecoratorVectorStreamTracer.h"
#include "dtkVisualizationDecoratorWithClut_p.h"
#include "dtkVisualizationMetaType.h"
#include "dtkVisualizationView2D.h"
#include <dtkLog>
#include <QtGui>
#include <QtWidgets>
#include <vtkActor.h>
#include <vtkCellCenters.h>
#include <vtkCellData.h>
#include <vtkCenterOfMass.h>
#include <vtkColorTransferFunction.h>
#include <vtkLineRepresentation.h>
#include <vtkLineSource.h>
#include <vtkLineWidget2.h>
#include <vtkLookupTable.h>
#include <vtkPiecewiseFunction.h>
#include <vtkPointData.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>
#include <vtkStreamTracer.h>
#include <vtkTubeFilter.h>
// /////////////////////////////////////////////////////////////////
// dtkStreamTracerObserver
// /////////////////////////////////////////////////////////////////
class dtkVisualizationDecoratorStreamTracerObserver : public vtkCommand
{
private:
dtkVisualizationDecoratorStreamTracerObserver(void) {
};
public:
static dtkVisualizationDecoratorStreamTracerObserver *New(void)
{
return new dtkVisualizationDecoratorStreamTracerObserver;
};
virtual void Execute(vtkObject *caller, unsigned long event, void *)
{
if (event == vtkCommand::InteractionEvent) {
source_line->GetPolyData(source_line_data);
stream_tracer->SetSourceData(source_line_data);
stream_tracer->Modified();
}
};
public:
vtkSmartPointer<vtkPolyData> source_line_data;
vtkSmartPointer<vtkLineRepresentation> source_line;
vtkSmartPointer<vtkStreamTracer> stream_tracer;
};
// ///////////////////////////////////////////////////////////////////
// dtkVisualizationDecoratorVectorStreamTracerPrivate declaration
// ///////////////////////////////////////////////////////////////////
class dtkVisualizationDecoratorVectorStreamTracerPrivate
{
public:
vtkSmartPointer<dtkVisualizationDecoratorStreamTracerObserver> source_line_observer;
vtkSmartPointer<vtkLineWidget2> source_line_widget;
vtkSmartPointer<vtkPolyData> source_line_data;
vtkSmartPointer<vtkLineRepresentation> source_line;
public:
vtkSmartPointer<vtkStreamTracer> streamtracer;
vtkSmartPointer<vtkPolyDataMapper> mapper;
vtkSmartPointer<vtkActor> actor;
public:
vtkSmartPointer<vtkTubeFilter> tube_filter;
vtkSmartPointer<vtkActor> tube_filter_actor;
public:
vtkSmartPointer<vtkCellCenters> cell_centers;
public:
QCheckBox *show_actor_cb = nullptr;
QCheckBox *show_source_actor_cb = nullptr;
};
// ///////////////////////////////////////////////////////////////////
// dtkVisualizationDecoratorVectorStreamTracer implementation
// ///////////////////////////////////////////////////////////////////
dtkVisualizationDecoratorVectorStreamTracer::dtkVisualizationDecoratorVectorStreamTracer(void): dtkVisualizationDecoratorWithClut(), d(new dtkVisualizationDecoratorVectorStreamTracerPrivate())
{
d->source_line_data = vtkSmartPointer<vtkPolyData> ::New();
d->source_line = vtkSmartPointer<vtkLineRepresentation>::New();
d->source_line->SetResolution(1000);
d->source_line->GetPolyData(d->source_line_data);
d->source_line_widget = vtkSmartPointer<vtkLineWidget2>::New();
d->source_line_widget->SetEnabled(false);
d->source_line_widget->SetRepresentation(d->source_line);
d->streamtracer = vtkSmartPointer<vtkStreamTracer>::New();
d->streamtracer->SetSourceData(d->source_line_data);
d->streamtracer->SetIntegrationDirectionToBoth();
d->streamtracer->SetIntegratorTypeToRungeKutta4();
d->streamtracer->SetIntegrationStepUnit(vtkStreamTracer::Units::CELL_LENGTH_UNIT);
d->streamtracer->SetInitialIntegrationStep(0.2);
d->streamtracer->SetMinimumIntegrationStep(0.01);
d->streamtracer->SetMaximumIntegrationStep(0.5);
d->streamtracer->SetMaximumNumberOfSteps(2000);
d->streamtracer->SetMaximumPropagation(10); // To be set as the maximum size of the dataset
d->streamtracer->SetTerminalSpeed(1.e-12);
d->streamtracer->SetMaximumError(1.e-6);
d->streamtracer->SetComputeVorticity(true);
d->mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
d->mapper->SetInputConnection(d->streamtracer->GetOutputPort());
d->actor = vtkSmartPointer<vtkActor>::New();
d->actor->SetMapper(d->mapper);
d->cell_centers = vtkSmartPointer<vtkCellCenters>::New();
d->source_line_observer = vtkSmartPointer<dtkVisualizationDecoratorStreamTracerObserver>::New();
d->source_line_observer->source_line_data = d->source_line_data;
d->source_line_observer->source_line = d->source_line;
d->source_line_observer->stream_tracer = d->streamtracer;
d->source_line_widget->AddObserver(vtkCommand::InteractionEvent, d->source_line_observer);
//////////
// Inspectors creation and setup
d->show_actor_cb = new QCheckBox;
d->show_source_actor_cb = new QCheckBox;
d->show_source_actor_cb->setChecked(true);
//////////
// Inspectors connections
connect(d->show_actor_cb, &QCheckBox::stateChanged, [=] (int state)
{
this->saveSettings("visibility",state == Qt::Checked);
this->setVisibility(state == Qt::Checked);
this->draw();
});
connect(d->show_source_actor_cb, &QCheckBox::stateChanged, [=] (int state)
{
d->source_line_widget->SetEnabled(state == Qt::Checked);
this->draw();
});
this->setObjectName("Vector Stream Tracer");
d->show_actor_cb->setObjectName("Display");
d->show_source_actor_cb->setObjectName("Display Source");
d_func()->inspectors << d->show_actor_cb << d->show_source_actor_cb;
}
dtkVisualizationDecoratorVectorStreamTracer::~dtkVisualizationDecoratorVectorStreamTracer(void)
{
dtkVisualizationDecoratorVectorStreamTracer::unsetCanvas();
delete d;
d = nullptr;
}
void dtkVisualizationDecoratorVectorStreamTracer::restoreSettings(void)
{
if (this->objectName().isEmpty()) {
return;
}
dtkVisualizationDecoratorWithClut::restoreSettings();
d->actor->SetVisibility(d_func()->default_visibility);
d->show_actor_cb->blockSignals(true);
d->show_actor_cb->setChecked(d_func()->default_visibility);
d->show_actor_cb->blockSignals(false);
}
void dtkVisualizationDecoratorVectorStreamTracer::setData(const QVariant& data)
{
vtkDataSet *dataset = data.value<vtkDataSet *>();
if (!dataset) {
dtkWarn() << Q_FUNC_INFO << "vtkDataSet is expected. Input data is not stored.";
return;
}
d_func()->clear();
d_func()->retrieveVectorPoints(dataset);
d_func()->retrieveVectorCells(dataset);
if (!this->isDecorating()) {
dtkWarn() << Q_FUNC_INFO << "vtkDataSet has no field to decorate. Nothing is done.";
d_func()->clear();
return;
}
d_func()->dataset = dataset;
this->restoreSettings();
d->cell_centers->SetInputData(dataset);
double bounds[6];
dataset->GetBounds(bounds);
double pos1[3]; pos1[0] = bounds[0]; pos1[1] = bounds[1]; pos1[2] = bounds[2];
double pos2[3]; pos2[0] = bounds[3]; pos2[1] = bounds[4]; pos2[2] = bounds[5];
d->source_line->SetPoint1WorldPosition(pos1);
d->source_line->SetPoint2WorldPosition(pos2);
d->source_line->Modified();
d->source_line->GetPolyData(d->source_line_data);
d->streamtracer->SetInputData(d->source_line_data);
d->streamtracer->Modified();
d_func()->sortEligibleFields();
this->setCurrentFieldName(d_func()->current_field_name);
if (this->canvas()) {
this->canvas()->renderer()->AddActor(d->actor);
d->source_line_widget->SetInteractor(this->canvas()->renderer()->GetRenderWindow()->GetInteractor());
d->source_line_widget->On();
}
d_func()->enableScalarBar();
}
void dtkVisualizationDecoratorVectorStreamTracer::setCanvas(dtkVisualizationCanvas *canvas)
{
this->unsetCanvas();
d_func()->view = dynamic_cast<dtkVisualizationView2D *>(canvas);
if (!d_func()->view) {
qWarning() << Q_FUNC_INFO << "View 2D or view 3D expected as canvas. Canvas is reset to nullptr.";
return;
}
if (this->isDecorating()) {
d_func()->view->renderer()->AddActor(d->actor);
d->source_line_widget->SetInteractor(this->canvas()->renderer()->GetRenderWindow()->GetInteractor());
d->source_line_widget->On();
}
d_func()->enableScalarBar();
}
void dtkVisualizationDecoratorVectorStreamTracer::unsetCanvas(void)
{
if (d_func()->view) {
d->source_line_widget->Off();
d->source_line_widget->SetInteractor(nullptr);
d_func()->view->renderer()->RemoveActor(d->actor);
}
d_func()->disableScalarBar();
d_func()->view = nullptr;
}
void dtkVisualizationDecoratorVectorStreamTracer::touch()
{
dtkVisualizationDecoratorWithClut::touch();
d->source_line->GetPolyData(d->source_line_data);
d->streamtracer->SetSourceData(d->source_line_data);
d->streamtracer->Modified();
}
void dtkVisualizationDecoratorVectorStreamTracer::setVisibility(bool visible)
{
dtkVisualizationDecoratorWithClut::setVisibility(visible);
d->actor->SetVisibility(visible);
d->source_line_widget->SetEnabled(visible);
}
bool dtkVisualizationDecoratorVectorStreamTracer::setCurrentFieldName(const QString& field_name)
{
if (field_name.isEmpty()) {
dtkWarn() << Q_FUNC_INFO << "Field name is empty, nothing is done.";
return false;
}
if (!d_func()->dataset) {
dtkWarn() << Q_FUNC_INFO << "Before calling setCurrentFieldName, setDataSet must be called.";
return false;
}
if(!d_func()->eligible_field_names.contains(field_name)) {
dtkWarn() << Q_FUNC_INFO << "The field name :" << field_name << "that was specified doesn't match any of the eligible scalar field names";
return false;
}
d_func()->current_field_name = field_name;
using Support = dtkVisualizationDecoratorWithClut::Support;
int support = d_func()->supports[field_name];
if(support == Support::Point) {
d->streamtracer->SetInputData(d_func()->dataset);
d->streamtracer->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, qPrintable(field_name));
d->mapper->SetScalarModeToUsePointData();
} else if(support == Support::Cell) {
d->streamtracer->SetInputConnection(d->cell_centers->GetOutputPort());
d->streamtracer->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_CELLS, qPrintable(field_name));
}
d->streamtracer->Modified();
return dtkVisualizationDecoratorWithClut::setCurrentFieldName(field_name);
}
void dtkVisualizationDecoratorVectorStreamTracer::setColorMap(const QMap<double, QColor>& new_colormap)
{
dtkVisualizationDecoratorWithClut::setColorMap(new_colormap);
// d->mapper->SetLookupTable(d_func()->color_function);
// d->mapper->SelectColorArray(qPrintable(d_func()->current_field_name));
// auto&& range = d_func()->ranges[d_func()->current_field_name];
// d->mapper->SetScalarRange(range[0], range[1]);
// d->mapper->Modified();
}
//
// dtkVisualizationDecoratorVectorStreamTracer.cpp ends here
// dtkVisualizationDecoratorVectorStreamTracer.h
//
#pragma once
#include <dtkVisualizationExport>
#include "dtkVisualizationDecoratorWithClut.h"
class DTKVISUALIZATION_EXPORT dtkVisualizationDecoratorVectorStreamTracer : public dtkVisualizationDecoratorWithClut
{
Q_OBJECT
public:
dtkVisualizationDecoratorVectorStreamTracer(void);
~dtkVisualizationDecoratorVectorStreamTracer(void);
public:
void setData(const QVariant&) override;
void setCanvas(dtkVisualizationCanvas *) override;
void unsetCanvas(void) override;
void touch(void) override;
protected:
void restoreSettings(void) override;
bool setCurrentFieldName(const QString&) override;
void setColorMap(const QMap<double, QColor>&) override;
public:
void setVisibility(bool visible) override;
protected:
bool isCurrentFieldUniform(void);
protected:
class dtkVisualizationDecoratorVectorStreamTracerPrivate *d = nullptr;
};
//
// dtkVisualizationDecoratorVectorStreamTracer.h ends here
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment