VtkAddFilterDialog::VtkAddFilterDialog( VtkVisPipeline* pipeline,
                                        QModelIndex parentIndex,
                                        QDialog* parent /*= 0*/ )
	: QDialog(parent), _pipeline(pipeline), _parentIndex(parentIndex)
{
	setupUi(this);
	filterListWidget->setSelectionMode(QAbstractItemView::SingleSelection);

	VtkVisPipelineItem* parentItem =
	        static_cast<VtkVisPipelineItem*>(_pipeline->getItem(parentIndex));
	vtkDataObject* parentDataObject = parentItem->algorithm()->GetOutputDataObject(0);
	int parentDataObjectType = parentDataObject->GetDataObjectType();

	QVector<VtkFilterInfo> filterList = VtkFilterFactory::GetFilterList();
	foreach(VtkFilterInfo filter, filterList)
	{
		// Check for suitable filters (see vtkDataSet inheritance diagram)
		int inputType = filter.inputDataObjectType;
		if ((inputType == parentDataObjectType) ||
		    (inputType == VTK_POINT_SET && parentDataObjectType != VTK_IMAGE_DATA) ||
		    (inputType == VTK_IMAGE_DATA &&
		     (parentDataObjectType == VTK_STRUCTURED_POINTS || parentDataObjectType ==
		      VTK_UNIFORM_GRID)))

			new QListWidgetItem(filter.readableName, filterListWidget);
	}
示例#2
0
void VtkVisPipeline::showMeshElementQuality(
    InSituLib::VtkMappedMeshSource* source,
    MeshLib::MeshQualityType t, std::vector<double> const& quality)
{
    if (!source || quality.empty())
        return;

    int const nSources = this->_rootItem->childCount();
    for (int i = 0; i < nSources; i++)
    {
        VtkVisPipelineItem* parentItem =
                static_cast<VtkVisPipelineItem*>(_rootItem->child(i));
        if (parentItem->algorithm() != source)
            continue;

        QList<QVariant> itemData;
        itemData << "MeshQuality: " + QString::fromStdString(
                MeshQualityType2String(t)) << true;

        VtkCompositeFilter* filter =
            VtkFilterFactory::CreateCompositeFilter("VtkCompositeElementSelectionFilter",
                                                    parentItem->transformFilter());
        if (t == MeshLib::MeshQualityType::ELEMENTSIZE)
        {
            auto const range (std::minmax_element(quality.cbegin(), quality.cend()));
            static_cast<VtkCompositeElementSelectionFilter*>(filter)->setRange(*range.first, *range.second);
        }
        static_cast<VtkCompositeElementSelectionFilter*>(filter)->setSelectionArray("Selection", quality);
        VtkVisPointSetItem* item = new VtkVisPointSetItem(filter, parentItem, itemData);
        this->addPipelineItem(item, this->createIndex(i, 0, item));
        break;
    }
}
示例#3
0
void VtkVisPipelineView::addColorTable()
{
	VtkVisPipelineItem* item (
		static_cast<VtkVisPipelineItem*>(static_cast<VtkVisPipeline*>(this->model())->
		                                 getItem(this->selectionModel()->currentIndex())) );
	const QString array_name = item->GetActiveAttribute();

	QSettings settings;
	QString filename = QFileDialog::getOpenFileName(this, "Select color table",
	                                                settings.value("lastOpenedLutFileDirectory"). toString(),
	                                                "Color table files (*.xml);;");
	QFileInfo fi(filename);

	if (fi.suffix().toLower() == "xml")
	{
		VtkVisPointSetItem* pointSetItem = dynamic_cast<VtkVisPointSetItem*>(item);
		if (pointSetItem)
		{
			VtkAlgorithmProperties* props = pointSetItem->getVtkProperties();
			if (props)
			{
				props->SetLookUpTable(array_name, filename);
				item->SetActiveAttribute(array_name);
				emit requestViewUpdate();
			}
		}
		else
			QMessageBox::warning(NULL, "Color lookup table could not be applied.",
			                     "Color lookup tables can only be applied to VtkVisPointSetItem.");
		QDir dir = QDir(filename);
		settings.setValue("lastOpenedLutFileDirectory", dir.absolutePath());
	}
}
示例#4
0
void VtkVisPipelineView::selectionChanged( const QItemSelection &selected,
                                           const QItemSelection &deselected )
{
	QTreeView::selectionChanged(selected, deselected);

	if (selected.empty())
		return;

	QModelIndex index = *selected.indexes().begin();
	if (index.isValid())
	{
		VtkVisPipelineItem* item = static_cast<VtkVisPipelineItem*>(index.internalPointer());
		emit actorSelected(item->actor());
		emit itemSelected(item);
		if (item->transformFilter())
			emit dataObjectSelected(vtkDataObject::SafeDownCast(
				item->transformFilter()->GetOutputDataObject(0)));
	}
	else
	{
		emit actorSelected(NULL);
		emit itemSelected(NULL);
		emit dataObjectSelected(NULL);
	}
}
示例#5
0
void VtkVisPipelineView::convertVTKToOGSMesh()
{
	VtkVisPipelineItem* item = static_cast<VtkVisPipelineItem*>(
		static_cast<VtkVisPipeline*>(this->model())->getItem(this->selectionModel()->currentIndex()));
	vtkSmartPointer<vtkAlgorithm> algorithm = item->algorithm();


	vtkUnstructuredGrid* grid(NULL);
	vtkUnstructuredGridAlgorithm* ugAlg = vtkUnstructuredGridAlgorithm::SafeDownCast(algorithm);
	if (ugAlg)
		grid = ugAlg->GetOutput();
	else
	{
		// for old filetypes
		vtkGenericDataObjectReader* dataReader = vtkGenericDataObjectReader::SafeDownCast(algorithm);
		if (dataReader)
			grid = vtkUnstructuredGrid::SafeDownCast(dataReader->GetOutput());
		else
		{
			// for new filetypes
			vtkXMLUnstructuredGridReader* xmlReader = vtkXMLUnstructuredGridReader::SafeDownCast(algorithm);
			grid = vtkUnstructuredGrid::SafeDownCast(xmlReader->GetOutput());
		}
	}
	MeshLib::Mesh* mesh = MeshLib::VtkMeshConverter::convertUnstructuredGrid(grid);
	mesh->setName(item->data(0).toString().toStdString());
	emit meshAdded(mesh);
}
示例#6
0
void VtkVisTabWidget::on_scaleZ_textChanged(const QString &text)
{
	bool ok = true;
	double scale = text.toDouble(&ok);

	// If z scale becomes zero, the object becomes invisible
	if (ok && scale != 0.0)
	{
		_item->setScale(1.0, 1.0, scale);

		for (int i = 0; i < _item->childCount(); i++)
		{
			VtkVisPipelineItem* childItem = _item->child(i);
			if (childItem)
			{
				VtkCompositeColorByHeightFilter* colorFilter =
				        dynamic_cast<VtkCompositeColorByHeightFilter*>
				        (childItem->compositeFilter());
				if (colorFilter)
					VtkColorByHeightFilter::SafeDownCast(
					        colorFilter->GetOutputAlgorithm())->
					SetTableRangeScaling(scale);
			}
		}

		emit requestViewUpdate();
	}
}
示例#7
0
void VtkVisPipelineView::contextMenuEvent( QContextMenuEvent* event )
{
	QModelIndex index = selectionModel()->currentIndex();
	if (index.isValid())
	{
		// check object type
		VtkVisPipelineItem* item = static_cast<VtkVisPipelineItem*>(static_cast<VtkVisPipeline*>(
			this->model())->getItem(this->selectionModel()->currentIndex()));
		int objectType = item->algorithm()->GetOutputDataObject(0)->GetDataObjectType();
		VtkAlgorithmProperties* vtkProps = item->getVtkProperties();
		bool isSourceItem =
		        (this->selectionModel()->currentIndex().parent().isValid()) ? 0 : 1;

		QMenu menu;
		QAction* addFilterAction = menu.addAction("Add filter...");

		QAction* addLUTAction(NULL);
		QAction* addMeshingAction(NULL);
		if (objectType == VTK_IMAGE_DATA)
		{
			// this exception is needed as image object are only displayed in the vis-pipeline
			isSourceItem = false;
			addMeshingAction = menu.addAction("Convert Image to Mesh...");
			connect(addMeshingAction, SIGNAL(triggered()), this,
			        SLOT(showImageToMeshConversionDialog()));
		}
		else
		{
			addLUTAction = menu.addAction("Add color table...");
			connect(addLUTAction, SIGNAL(triggered()), this, SLOT(addColorTable()));
		}

		QAction* addConvertToMeshAction(NULL);
		if (objectType == VTK_UNSTRUCTURED_GRID)
		{
			addConvertToMeshAction = menu.addAction("Convert to Mesh...");
			connect(addConvertToMeshAction, SIGNAL(triggered()), this,
			        SLOT(convertVTKToOGSMesh()));
		}
		menu.addSeparator();
		QAction* exportVtkAction = menu.addAction("Export as VTK");
		QAction* exportOsgAction = menu.addAction("Export as OpenSG");
		QAction* removeAction = NULL;
		if (!isSourceItem || vtkProps->IsRemovable())
		{
			removeAction = menu.addAction("Remove");
			connect(removeAction, SIGNAL(triggered()), this,
			        SLOT(removeSelectedPipelineItem()));
		}

		connect(addFilterAction, SIGNAL(triggered()), this, SLOT(addPipelineFilterItem()));
		connect(exportVtkAction, SIGNAL(triggered()), this,
		        SLOT(exportSelectedPipelineItemAsVtk()));
		connect(exportOsgAction, SIGNAL(triggered()), this,
		        SLOT(exportSelectedPipelineItemAsOsg()));

		menu.exec(event->globalPos());
	}
}
示例#8
0
void VtkVisPipeline::removeSourceItem(StationTreeModel* model, const std::string &name)
{
	for (int i = 0; i < _rootItem->childCount(); i++)
	{
		VtkVisPipelineItem* item = static_cast<VtkVisPipelineItem*>(getItem(index(i, 0)));
		if (item->algorithm() == model->vtkSource(name))
		{
			removePipelineItem(index(i, 0));
			return;
		}
	}
}
示例#9
0
void VtkVisPipeline::removeSourceItem(ProcessModel* model, const FiniteElement::ProcessType pcs_type, const FEMCondition::CondType cond_type)
{
	for (int i = 0; i < _rootItem->childCount(); i++)
	{
		VtkVisPipelineItem* item = static_cast<VtkVisPipelineItem*>(getItem(index(i, 0)));
		if (item->algorithm() == model->vtkSource(pcs_type, cond_type))
		{
			removePipelineItem(index(i, 0));
			return;
		}
	}
}
示例#10
0
void VtkVisPipeline::removeSourceItem(MshModel* model, const QModelIndex &idx)
{
	MshItem* sItem = static_cast<MshItem*>(model->getItem(idx));

	for (int i = 0; i < _rootItem->childCount(); i++)
	{
		VtkVisPipelineItem* item = static_cast<VtkVisPipelineItem*>(getItem(index(i, 0)));
		if (item->algorithm() == sItem->vtkSource())
		{
			removePipelineItem(index(i, 0));
			return;
		}
	}
}
示例#11
0
void VtkVisPipeline::setGlobalBackfaceCulling(bool enable) const
{
	// iterate over all source items
	for (int i = 0; i < _rootItem->childCount(); ++i)
	{
		VtkVisPipelineItem* item = static_cast<VtkVisPipelineItem*>(_rootItem->child(i));
		item->setBackfaceCulling(enable);

		// recursively set on all child items
		item->setBackfaceCullingOnChildren(enable);
	}

	emit vtkVisPipelineChanged();
}
示例#12
0
void VtkVisPipeline::setGlobalSuperelevation(double factor) const
{
	// iterate over all source items
	for (int i = 0; i < _rootItem->childCount(); ++i)
	{
		VtkVisPipelineItem* item = static_cast<VtkVisPipelineItem*>(_rootItem->child(i));
		item->setScale(1.0, 1.0, factor);

		// recursively set on all child items
		item->setScaleOnChildren(1.0, 1.0, 1.0);
	}

	emit vtkVisPipelineChanged();
}
示例#13
0
VtkVisPointSetItem::VtkVisPointSetItem(
        vtkAlgorithm* algorithm, TreeItem* parentItem,
        const QList<QVariant> data /*= QList<QVariant>()*/)
    : VtkVisPipelineItem(algorithm, parentItem, data), _mapper(nullptr),
    _transformFilter(nullptr), _onPointData(true), _activeArrayName("")
{
    VtkVisPipelineItem* visParentItem = dynamic_cast<VtkVisPipelineItem*>(parentItem);
    if (parentItem->parentItem())
    {
        // special case if parent is image but child is not (e.g. Image2BarChartFilter)
        if (dynamic_cast<vtkImageAlgorithm*>(visParentItem->algorithm()))
            _algorithm->SetInputConnection(visParentItem->algorithm()->GetOutputPort());
        else
        {
            VtkVisPointSetItem* pointSetItem =
                    dynamic_cast<VtkVisPointSetItem*>(parentItem);
            if (pointSetItem)
                _algorithm->SetInputConnection(
                        pointSetItem->transformFilter()->GetOutputPort());
        }
    }
}
示例#14
0
void VtkVisPipeline::highlightGeoObject(const vtkPolyDataAlgorithm* source, int index)
{
	this->removeHighlightedGeoObject();
	int nSources = this->_rootItem->childCount();
	for (int i = 0; i < nSources; i++)
	{
		VtkVisPipelineItem* parentItem = static_cast<VtkVisPipelineItem*>(_rootItem->child(i));
		if (parentItem->algorithm() == source)
		{
			QList<QVariant> itemData;
			itemData << "Selected GeoObject" << true;

			VtkCompositeFilter* filter = VtkFilterFactory::CreateCompositeFilter(
															"VtkCompositeGeoObjectFilter",
															parentItem->transformFilter());
			static_cast<VtkCompositeGeoObjectFilter*>(filter)->SetIndex(index);
			VtkVisPointSetItem* item = new VtkVisPointSetItem(filter, parentItem, itemData);
			QModelIndex parent_index = static_cast<TreeModel*>(this)->index(i, 0, QModelIndex());
			_highlighted_geo_index = this->addPipelineItem(item, parent_index);
			break;
		}
	}
}
示例#15
0
void VtkVisPipeline::highlightMeshComponent(vtkUnstructuredGridAlgorithm const*const source, unsigned index, bool is_element)
{
    int nSources = this->_rootItem->childCount();
    for (int i = 0; i < nSources; i++)
    {
        VtkVisPipelineItem* parentItem = static_cast<VtkVisPipelineItem*>(_rootItem->child(i));
        if (parentItem->algorithm() == source)
        {
            QList<QVariant> itemData;
            itemData << "Selected Mesh Component" << true;
            QList<QVariant> selected_index;
            selected_index << index << index;

            VtkCompositeFilter* filter (nullptr);
            if (is_element)
            {
                filter = VtkFilterFactory::CreateCompositeFilter("VtkCompositeElementSelectionFilter",
                                                                  parentItem->transformFilter());
                static_cast<VtkCompositeElementSelectionFilter*>(filter)->setSelectionArray("vtkIdFilter_Ids");
                static_cast<VtkCompositeElementSelectionFilter*>(filter)->SetUserVectorProperty("Threshold Between", selected_index);
            }
            else
            {
                filter = VtkFilterFactory::CreateCompositeFilter("VtkCompositeNodeSelectionFilter",
                                                                  parentItem->transformFilter());
                std::vector<unsigned> indeces(1);
                indeces[0] = index;
                static_cast<VtkCompositeNodeSelectionFilter*>(filter)->setSelectionArray(indeces);
            }
            VtkVisPointSetItem* item = new VtkVisPointSetItem(filter, parentItem, itemData);
            QModelIndex parent_index = static_cast<TreeModel*>(this)->index(i, 0, QModelIndex());
            _highlighted_mesh_component = this->addPipelineItem(item, parent_index);
            break;
        }
    }
}
示例#16
0
void VtkVisImageItem::Initialize(vtkRenderer* renderer)
{
	vtkImageAlgorithm* img = dynamic_cast<vtkImageAlgorithm*>(_algorithm);
	img->Update();
	//VtkGeoImageSource* img = dynamic_cast<VtkGeoImageSource*>(_algorithm);

	double origin[3];
	double spacing[3];
	double range[2];
	img->GetOutput()->GetOrigin(origin);
	img->GetOutput()->GetSpacing(spacing);
	//img->getRange(range);
	img->GetOutput()->GetPointData()->GetScalars()->GetRange(range);
	vtkImageShiftScale* scale = vtkImageShiftScale::New();
	scale->SetOutputScalarTypeToUnsignedChar();
	scale->SetInputConnection(img->GetOutputPort());
	scale->SetShift(-range[0]);
	scale->SetScale(255.0/(range[1]-range[0]));

	_transformFilter = vtkImageChangeInformation::New();
	_transformFilter->SetInputConnection(scale->GetOutputPort());
	//double origin[3];
	//img->getOrigin(origin);
	//double spacing = img->getSpacing();
	//_transformFilter->SetOutputOrigin(origin2);
	//_transformFilter->SetOutputSpacing(spacing2);
	_transformFilter->Update();

	_renderer = renderer;

	// Use a special vtkImageActor instead of vtkActor
	vtkImageActor* imageActor = vtkImageActor::New();
	imageActor->SetInput(_transformFilter->GetOutput());
	_actor = imageActor;
	_renderer->AddActor(_actor);

	// Set pre-set properties
	VtkAlgorithmProperties* vtkProps = dynamic_cast<VtkAlgorithmProperties*>(_algorithm);
	if (vtkProps)
		setVtkProperties(vtkProps);

	VtkVisPipelineItem* parentItem = dynamic_cast<VtkVisPipelineItem*>(this->parentItem());
	while (parentItem)
	{
		VtkAlgorithmProperties* parentProps =
		        dynamic_cast<VtkAlgorithmProperties*>(parentItem->algorithm());
		if (parentProps)
		{
			VtkAlgorithmProperties* newProps = new VtkAlgorithmProperties();
			newProps->SetScalarVisibility(parentProps->GetScalarVisibility());
			newProps->SetTexture(parentProps->GetTexture());
			setVtkProperties(newProps);
			vtkProps = newProps;
			parentItem = NULL;
		}
		else
			parentItem = dynamic_cast<VtkVisPipelineItem*>(parentItem->parentItem());
	}

	// Set active scalar to the desired one from VtkAlgorithmProperties
	// or to match those of the parent.
	if (vtkProps)
	{
		if (vtkProps->GetActiveAttribute().length() > 0)
			this->SetActiveAttribute(vtkProps->GetActiveAttribute());
		else
		{
			VtkVisPipelineItem* visParentItem =
			        dynamic_cast<VtkVisPipelineItem*>(this->parentItem());
			if (visParentItem)
				this->SetActiveAttribute(visParentItem->GetActiveAttribute());
			if (vtkProps->GetTexture() != NULL)
				this->SetActiveAttribute("Solid Color");
		}
	}
}
示例#17
0
void VtkVisPipeline::checkMeshQuality(VtkMeshSource* source, MshQualityType::type t)
{
	if (source)
	{
		const MeshLib::Mesh* mesh = source->GetMesh();
		MeshLib::MeshQualityChecker* checker (NULL);
		if (t == MshQualityType::EDGERATIO)
			checker = new MeshLib::MeshQualityShortestLongestRatio(mesh);
		else if (t == MshQualityType::AREA)
			checker = new MeshLib::MeshQualityArea(mesh);
		else if (t == MshQualityType::VOLUME)
			checker = new MeshLib::MeshQualityVolume(mesh);
		else if (t == MshQualityType::EQUIANGLESKEW)
			checker = new MeshLib::MeshQualityEquiAngleSkew(mesh);
		else
		{
			std::cout << "Error in VtkVisPipeline::checkMeshQuality() - Unknown MshQualityType..."
							<< std::endl;
			delete checker;
			return;
		}
		checker->check ();

		std::vector<double> quality (checker->getMeshQuality());
		// transform area and volume criterion values to [0, 1]
		if (t == MshQualityType::AREA || t == MshQualityType::VOLUME) {
			try {
				MathLib::LinearIntervalInterpolation<double> lin_intpol(checker->getMinValue(), checker->getMaxValue(), 0, 1);
				const size_t n_quality(quality.size());
				for (size_t k(0); k<n_quality; k++)
					quality[k] = lin_intpol(quality[k]);
			} catch (std::runtime_error& exception) {
				std::cout << "run time error: " << exception.what() << std::endl;
			}
		}

		int nSources = this->_rootItem->childCount();
		for (int i = 0; i < nSources; i++)
		{
			VtkVisPipelineItem* parentItem =
			        static_cast<VtkVisPipelineItem*>(_rootItem->child(i));
			if (parentItem->algorithm() == source)
			{
				QList<QVariant> itemData;
				itemData << "MeshQuality: " + QString::fromStdString(
				        MshQualityType2String(t)) << true;

				VtkCompositeFilter* filter =
				        VtkFilterFactory::CreateCompositeFilter(
				                "VtkCompositeSelectionFilter",
				                parentItem->transformFilter());
				static_cast<VtkCompositeSelectionFilter*>(filter)->
				setSelectionArray(quality);
				VtkVisPointSetItem* item = new VtkVisPointSetItem(filter,
				                                                  parentItem,
				                                                  itemData);
				this->addPipelineItem(item, this->createIndex(i, 0, item));
				break;
			}
		}

		// *** construct and write histogram
		// simple suggestion: number of classes with Sturges criterion
		size_t nclasses (static_cast<size_t>(1 + 3.3 * log (static_cast<float>(mesh->getNElements()))));
//			bool ok;
//			size_t size (static_cast<size_t>(QInputDialog::getInt(NULL, "OGS-Histogram", "number of histogram classes/spins (min: 1, max: 10000)", static_cast<int>(nclasses), 1, 10000, 1, &ok)));
//			if (ok) ...

		BASELIB::Histogram<double> histogram (checker->getHistogram(nclasses));
		std::ofstream out ("mesh_histogram.txt");
		if (out) {
			out << "# histogram depicts mesh quality criterion " << MshQualityType2String(t)
				<< " for mesh " << source->GetMesh()->getName() << std::endl;
			nclasses = histogram.getNrBins();
			std::vector<size_t> const& bin_cnts(histogram.getBinCounts());
			const double min (histogram.getMinimum());
			const double bin_width (histogram.getBinWidth());

			for (size_t k(0); k < nclasses; k++)
				out << min+k*bin_width << " " << bin_cnts[k] << std::endl;
			out.close ();
		} else {
			std::cerr << "could not open file mesh_histgram.txt" << std::endl;
		}

//		size_t size (100);
//		std::vector<size_t> histogram (size,0);
//		checker->getHistogram(histogram);
//		std::ofstream out ("mesh_histogram.txt");
//		const size_t histogram_size (histogram.size());
//		for (size_t k(0); k < histogram_size; k++)
//			out << k / static_cast<double>(histogram_size) << " " << histogram[k] <<
//			std::endl;
//		out.close ();

		delete checker;
	}
}
示例#18
0
void VtkVisPointSetItem::Initialize(vtkRenderer* renderer)
{
    // TODO vtkTransformFilter creates a new copy of the point coordinates which
    // conflicts with VtkMappedMeshSource. Find a workaround!
    _transformFilter = vtkTransformFilter::New();
    vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
    transform->Identity();
    _transformFilter->SetTransform(transform);

    _transformFilter->SetInputConnection(_algorithm->GetOutputPort());
    _transformFilter->Update();

    _renderer = renderer;
    _mapper = QVtkDataSetMapper::New();
    _mapper->InterpolateScalarsBeforeMappingOff();
    _mapper->SetColorModeToMapScalars();

    _mapper->SetInputConnection(_transformFilter->GetOutputPort());
    _actor = vtkActor::New();
    static_cast<vtkActor*>(_actor)->SetMapper(_mapper);
    _renderer->AddActor(_actor);

    // Determine the right pre-set properties
    // Order is: _algorithm, _compositeFilter, create a new one with props copied from parent
    VtkAlgorithmProperties* vtkProps = dynamic_cast<VtkAlgorithmProperties*>(_algorithm);
    if (!vtkProps)
    {
        vtkProps = dynamic_cast<VtkAlgorithmProperties*>(_compositeFilter);

        // Copy properties from parent or create a new VtkAlgorithmProperties
        if (!vtkProps)
        {
            VtkVisPipelineItem* parentItem = dynamic_cast<VtkVisPipelineItem*>(this->parentItem());
            while (parentItem)
            {
                VtkAlgorithmProperties* parentProps = nullptr;
                if(dynamic_cast<VtkVisPointSetItem*>(parentItem))
                    parentProps = dynamic_cast<VtkVisPointSetItem*>(parentItem)->getVtkProperties();
                if (parentProps)
                {
                    vtkProps = new VtkAlgorithmProperties(); // TODO memory leak?
                    vtkProps->SetScalarVisibility(parentProps->GetScalarVisibility());
                    vtkProps->SetTexture(parentProps->GetTexture());
                    vtkProps->SetActiveAttribute(parentProps->GetActiveAttribute());
                    parentItem = nullptr;
                }
                else
                    parentItem = dynamic_cast<VtkVisPipelineItem*>(parentItem->parentItem());
            }

            // Has no parents
            if (!vtkProps)
                vtkProps = new VtkAlgorithmProperties(); // TODO memory leak?
        }
    }
    _vtkProps = vtkProps;

    if (vtkProps->GetActiveAttribute().length() == 0)
    {
        // Get first scalar and set it to active
        QStringList arrayNames = this->getScalarArrayNames();
        if (arrayNames.length() > 0)
            vtkProps->SetActiveAttribute(arrayNames[0]);
        else
            vtkProps->SetActiveAttribute("Solid Color");
    }
    this->setVtkProperties(vtkProps);
    this->SetActiveAttribute(vtkProps->GetActiveAttribute());


    // Set global backface culling
    QSettings settings;
    bool backfaceCulling = settings.value("globalCullBackfaces", 0).toBool();
    this->setBackfaceCulling(backfaceCulling);

    // Set the correct threshold range
    if (dynamic_cast<VtkCompositeThresholdFilter*>(this->_compositeFilter) )
    {
        double range[2];
        this->GetRangeForActiveAttribute(range);
        QList<QVariant> thresholdRangeList;
        thresholdRangeList.push_back(range[0]);
        thresholdRangeList.push_back(range[1]);
        dynamic_cast<VtkCompositeFilter*>(this->_compositeFilter)
            ->SetUserVectorProperty("Range", thresholdRangeList);
    }

    // Show edges on meshes
    if (dynamic_cast<MeshLib::VtkMappedMeshSource*>(this->_algorithm))
        _vtkProps->GetProperties()->SetEdgeVisibility(1);
}