diff --git a/Base/CMakeLists.txt b/Base/CMakeLists.txt index 60baf90030d8c4f960ca3aa634e295b8841dbaba..8c648d33eae8b3e5e83d36537d14cde2dfd4671c 100644 --- a/Base/CMakeLists.txt +++ b/Base/CMakeLists.txt @@ -9,6 +9,7 @@ set( SOURCES TreeModelIterator.cpp modeltest.cpp CheckboxDelegate.cpp + QValueTooltipSlider.cpp ) # Moc headers @@ -18,6 +19,7 @@ set( MOC_HEADERS ColorPickerPushButton.h modeltest.h CheckboxDelegate.h + QValueTooltipSlider.h ) # Header files diff --git a/Base/QValueTooltipSlider.cpp b/Base/QValueTooltipSlider.cpp new file mode 100644 index 0000000000000000000000000000000000000000..28b49b7287410826250c3001f1854824c1fe435a --- /dev/null +++ b/Base/QValueTooltipSlider.cpp @@ -0,0 +1,26 @@ +/** + * \file QValueSlider.cpp + * 23/03/2011 LB Initial implementation + * + * Implementation of QValueSlider class + */ + +// ** INCLUDES ** +#include "QValueTooltipSlider.h" + +#include <QString> +#include <QToolTip> +#include <QCursor> + +#include <iostream> + +QValueTooltipSlider::QValueTooltipSlider(QWidget *parent) + : QSlider(parent) +{ + connect(this, SIGNAL(sliderMoved(int)), this, SLOT(setTooltipValue(int))); +} + +void QValueTooltipSlider::setTooltipValue(int value) +{ + QToolTip::showText(QCursor::pos(), QString::number(value)); +} diff --git a/Base/QValueTooltipSlider.h b/Base/QValueTooltipSlider.h new file mode 100644 index 0000000000000000000000000000000000000000..5e0e875522e9ae4c4dbb368d8b7a29cbd68dffa5 --- /dev/null +++ b/Base/QValueTooltipSlider.h @@ -0,0 +1,25 @@ +/** + * \file QValueSlider.h + * 23/03/2011 LB Initial implementation + */ + +#ifndef QVALUETOOLTIPSLIDER_H +#define QVALUETOOLTIPSLIDER_H + +#include <QSlider> + +class QValueTooltipSlider : public QSlider +{ + Q_OBJECT + +public: + QValueTooltipSlider(QWidget* parent = 0); + +public slots: + void setTooltipValue(int value); + +protected: + +}; + +#endif // QVALUETOOLTIPSLIDER_H diff --git a/Base/RecentFiles.cpp b/Base/RecentFiles.cpp index 887ab340ff3b9e090b6ba2f7ae523dca7d15195c..9c2613fa29b6d8fd1fbd9499ee38946d2f4ab8d1 100644 --- a/Base/RecentFiles.cpp +++ b/Base/RecentFiles.cpp @@ -26,6 +26,11 @@ RecentFiles::RecentFiles( QObject* parent, const char* slot, updateRecentFileActions(); } +RecentFiles::~RecentFiles() +{ + delete _filesMenu; +} + QMenu* RecentFiles::menu() { return _filesMenu; diff --git a/Base/RecentFiles.h b/Base/RecentFiles.h index 5e9bc99f1953df2a6af8763435a8c64685a0423d..837e0f8691fca86149c84b3986ee028fabd1cfb2 100644 --- a/Base/RecentFiles.h +++ b/Base/RecentFiles.h @@ -46,6 +46,7 @@ public: * should be stored with the same keys: QSettings("UFZ", programName) */ RecentFiles(QObject* parent, const char* slot, QString settingsName, QString programName); + ~RecentFiles(); /// Returns the created menu. Add this menu to your QMainWindow menu. QMenu* menu(); diff --git a/CMakeLists.txt b/CMakeLists.txt index 48f218c21be6ccb07459e65b37e43603ef077442..2bb4b62bf78ac242a761589294c2c74f216df4dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,21 +7,22 @@ IF (MSVC) ENDIF (MSVC) -# Find VTK -FIND_PACKAGE( VTK REQUIRED ) +IF (NOT VTK_FOUND) + MESSAGE(FATAL_ERROR "Error: VTK was not found but is needed for the GUI. Aborting...") +ENDIF (NOT VTK_FOUND) INCLUDE( ${VTK_USE_FILE} ) # Find libgeotiff -FIND_PACKAGE( LibTiff REQUIRED ) -FIND_PACKAGE( LibGeoTiff REQUIRED ) +FIND_PACKAGE( LibTiff ) +FIND_PACKAGE( LibGeoTiff ) SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /ZI /Od /Ob0") # Add subprojects ADD_SUBDIRECTORY( Base ) +ADD_SUBDIRECTORY( DataView/StratView ) ADD_SUBDIRECTORY( DataView ) ADD_SUBDIRECTORY( DataView/DiagramView ) -ADD_SUBDIRECTORY( DataView/StratView ) ADD_SUBDIRECTORY( VtkVis ) ADD_SUBDIRECTORY( VtkAct ) IF (OGS_USE_OPENSG) diff --git a/DataView/CMakeLists.txt b/DataView/CMakeLists.txt index 3ccfa531bff43f8aba3cb2993d3c49d1c4df3575..fb2fef36d29aa1c42d7a7ff77e4d9307ef1105a3 100644 --- a/DataView/CMakeLists.txt +++ b/DataView/CMakeLists.txt @@ -21,15 +21,13 @@ set( SOURCES MshItem.cpp MshLayerMapper.cpp MshModel.cpp + MshQualitySelectionDialog.cpp MshTabWidget.cpp OGSRaster.cpp QueryResultsDialog.cpp - SHPImportDialog.cpp StationTabWidget.cpp StationTreeModel.cpp - StationTreeView.cpp - VisPrefsDialog.cpp - VisualizationWidget.cpp + StationTreeView.cpp ) # Moc Header files @@ -52,20 +50,19 @@ set( MOC_HEADERS ListPropertiesDialog.h MshEditDialog.h MshModel.h + MshQualitySelectionDialog.h MshTabWidget.h QueryResultsDialog.h - SHPImportDialog.h StationTabWidget.h StationTreeModel.h StationTreeView.h - VisPrefsDialog.h - VisualizationWidget.h ) # Header files set( HEADERS BaseItem.h CondItem.h + CondObjectListItem.h GeoObjectListItem.h GeoTreeItem.h ModelTreeItem.h @@ -84,12 +81,17 @@ set( UIS GMSHPrefs.ui LineEdit.ui MshEdit.ui + MshQualitySelection.ui MshTabWidgetBase.ui StationTabWidgetBase.ui - VisPrefs.ui - VisualizationWidgetBase.ui ) +IF (Shapelib_FOUND) + SET( SOURCES ${SOURCES} SHPImportDialog.cpp) + SET( MOC_HEADERS ${MOC_HEADERS} SHPImportDialog.h) + INCLUDE_DIRECTORIES( ${Shapelib_INCLUDE_DIR} ) +ENDIF () # Shapelib_FOUND + # Put filter in a folder SOURCE_GROUP("Dialog Header Files" REGULAR_EXPRESSION "[.]*Dialog.h") SOURCE_GROUP("Dialog Source Files" REGULAR_EXPRESSION "[.]*Dialog.cpp") @@ -121,13 +123,7 @@ include_directories( ./DiagramView ./StratView ../VtkVis - ../VtkAct - ${CMAKE_SOURCE_DIR} - ${Shapelib_INCLUDE_DIR} - #${OpenSG_INCLUDE_DIR} - #${OpenSGSupportlibs_INCLUDE_DIR} - ${libtiff_INCLUDE_DIR} - ${libgeotiff_INCLUDE_DIR} + ${CMAKE_SOURCE_DIR} ) if (OGS_COMPILE_QVTK) @@ -142,6 +138,10 @@ IF (OGS_USE_OPENSG) INCLUDE_DIRECTORIES( ${OpenSG_INCLUDE_DIRS} ) ENDIF (OGS_USE_OPENSG) +IF (libtiff_FOUND AND libgeotiff_FOUND) + INCLUDE_DIRECTORIES( ${libtiff_INCLUDE_DIR} ${libgeotiff_INCLUDE_DIR} ) +ENDIF () # libtiff_FOUND AND libgeotiff_FOUND + # Put moc files in a project folder source_group("UI Files" REGULAR_EXPRESSION "\\w*\\.ui") source_group("Moc Files" REGULAR_EXPRESSION "moc_.*") @@ -160,13 +160,18 @@ add_library( QtDataView STATIC # Link Qt library target_link_libraries( QtDataView ${QT_LIBRARIES} - ${libtiff_LIBRARIES} - ${libgeotiff_LIBRARIES} FEM FileIO GEO MSH QtBase DiagramView - ${Shapelib_LIBRARIES} + StratView ) + +IF (Shapelib_FOUND) + TARGET_LINK_LIBRARIES( QtDataView ${Shapelib_LIBRARIES} ) +ENDIF () # Shapelib_FOUND +IF (libtiff_FOUND AND libgeotiff_FOUND) + TARGET_LINK_LIBRARIES( QtDataView ${libtiff_LIBRARIES} ${libgeotiff_LIBRARIES} ) +ENDIF () # libtiff_FOUND AND libgeotiff_FOUND diff --git a/DataView/CondItem.h b/DataView/CondItem.h index 9798bfed654e24c43e3df23a72b195ed9e03ea05..01e26ef6e073a2511d9f32522c00cc982119895d 100644 --- a/DataView/CondItem.h +++ b/DataView/CondItem.h @@ -12,30 +12,29 @@ /** - * \brief A TreeItem containing conditions of a FEM as well as the vtk object representing these conditions. + * \brief A TreeItem containing a condition of a FEM (BC, IC or ST). * \sa TreeItem */ class CondItem : public TreeItem { public: - /// Constructor, automatically generates VTK object - CondItem(const QList<QVariant> &data, TreeItem *parent, const FEMCondition* cond) : TreeItem(data, parent), _item(cond) + /// Constructor + CondItem(const QList<QVariant> &data, TreeItem *parent, const FEMCondition* cond) + : TreeItem(data, parent), _item(cond) { - //_vtkSource = VtkPointsSource::New(); }; - ~CondItem() { /*_vtkSource->Delete();*/ }; + ~CondItem() {}; + /// Returns the FEM Condition associated with the item. const FEMCondition* getItem() { return _item; }; - /// Returns the VTK object. - //VtkPointsSource* vtkSource() const { return _vtkSource; }; - + /// Returns the geo-object on which the condition is placed. + const GEOLIB::GeoObject* getGeoObject() { return this->getGeoObject(); }; private: const FEMCondition* _item; - //VtkPointsSource* _vtkSource; }; #endif //CONDITEM_H diff --git a/DataView/CondObjectListItem.h b/DataView/CondObjectListItem.h new file mode 100644 index 0000000000000000000000000000000000000000..78e6d842a1926e81216fc47b231e99f42c365da0 --- /dev/null +++ b/DataView/CondObjectListItem.h @@ -0,0 +1,64 @@ +/** + * \file GeoObjectListItem.h + * 2011/04/05 KR Initial implementation + * + */ +#ifndef CONDOBJECTLISTITEM_H +#define CONDOBJECTLISTITEM_H + + +#include "FEMCondition.h" +#include "TreeItem.h" +#include <vtkPolyDataAlgorithm.h> +#include "VtkConditionSource.h" +#include <QModelIndex> + +/** + * \brief The CondObjectListItem is the TreeItem that contains the subtree for either initial conditions, + * boundary conditions source terms. This item also contains the vtk source-item for visualisation of this + * information and the indices of the associated geometry-objects. + * Upon creation the type of condition needs to be defined and the vector of points of the associated geometry + * is needed for created of the vtk-object. + * The actual FEM Condtions are added using the addCondition()-method. + * \sa TreeItem + */ +class CondObjectListItem : public TreeItem +{ + +public: + /// Constructor for the TreeItem specifying FEM Conditions. + CondObjectListItem(const QList<QVariant> &data, TreeItem *parent, FEMCondition::CondType type, const std::vector<GEOLIB::Point*> *points) + : TreeItem(data, parent), _vtkSource(VtkConditionSource::New()), _type(type), _cond_vec(new std::vector<FEMCondition*>) + { + QString display_name = parent->data(0).toString().append(" - ").append(QString::fromStdString(FEMCondition::condTypeToString(type))); + static_cast<VtkConditionSource*>(_vtkSource)->setData( points, _cond_vec); + static_cast<VtkConditionSource*>(_vtkSource)->SetName( display_name ); + } + + ~CondObjectListItem() + { + _vtkSource->Delete(); + delete _cond_vec; + } + + /// Adds FEMCondtion for construction of VTK object. + void addCondition(FEMCondition* cond) { + _cond_vec->push_back(cond); + _vtkSource->Modified(); + }; + + + /// Returns the type of geo-objects contained in the subtree of this item. + FEMCondition::CondType getType() { return _type; }; + + /// Returns the Vtk polydata source object + vtkPolyDataAlgorithm* vtkSource() const { return _vtkSource; }; + +private: + /// The Vtk data source object. This is the starting point for a Vtk data visualization pipeline. + vtkPolyDataAlgorithm* _vtkSource; + FEMCondition::CondType _type; + std::vector<FEMCondition*> *_cond_vec; +}; + +#endif //CONDOBJECTLISTITEM_H diff --git a/DataView/ConditionModel.cpp b/DataView/ConditionModel.cpp index ab101800a145dc622ff9015c1bab8100de69b1ac..b939cd29800fca2f312fdfe88b53aee5f4427df7 100644 --- a/DataView/ConditionModel.cpp +++ b/DataView/ConditionModel.cpp @@ -5,41 +5,28 @@ // ** INCLUDES ** #include "ConditionModel.h" +#include "CondObjectListItem.h" #include "CondItem.h" +#include "GeoObject.h" #include "GEOObjects.h" +#include "GeoType.h" #include "FEMCondition.h" +#include <vtkPolyDataAlgorithm.h> #include <QFileInfo> + ConditionModel::ConditionModel( ProjectData &project, QObject* parent /*= 0*/ ) : TreeModel(parent), _project(project) { QList<QVariant> rootData; delete _rootItem; - rootData << "FEM Conditions"; + rootData << "Name" << "Value" << "" << "" << ""; _rootItem = new TreeItem(rootData, NULL); - - QList<QVariant> bcData; - bcData << "Boundary Conditions" << ""; - _bcParent = new TreeItem(bcData, _rootItem); - _rootItem->appendChild(_bcParent); - - QList<QVariant> icData; - icData << "Initial Conditions" << ""; - _icParent = new TreeItem(icData, _rootItem); - _rootItem->appendChild(_icParent); - - QList<QVariant> stData; - stData << "Source Terms" << ""; - _stParent = new TreeItem(stData, _rootItem); - _rootItem->appendChild(_stParent); } ConditionModel::~ConditionModel() { - delete _icParent; - delete _bcParent; - delete _stParent; } int ConditionModel::columnCount( const QModelIndex &parent /*= QModelIndex()*/ ) const @@ -49,77 +36,193 @@ int ConditionModel::columnCount( const QModelIndex &parent /*= QModelIndex()*/ ) return 2; } - -void ConditionModel::addCondition(FEMCondition* c) +void ConditionModel::addConditionItem(FEMCondition* c) { - QList<QVariant> condData; - condData << QString::fromStdString(c->getGeoName()) << QString::fromStdString(c->getGeoTypeAsString()); - TreeItem* parent(NULL); - size_t row(0); - if (c->getCondType() == FEMCondition::INITIAL_CONDITION) { parent = _icParent; row=0; } - else if (c->getCondType() == FEMCondition::BOUNDARY_CONDITION) { parent = _bcParent; row=1; } - else if (c->getCondType() == FEMCondition::SOURCE_TERM) { parent = _stParent; row=2; } - CondItem* condItem = new CondItem(condData, parent, c); - parent->appendChild(condItem); - // add process information - QList<QVariant> pcsData; - pcsData << QString::fromStdString(convertProcessTypeToString(c->getProcessType())); - TreeItem* pcsInfo = new TreeItem(pcsData, condItem); - // add information on primary variable - QList<QVariant> pvData; - pvData << QString::fromStdString(convertPrimaryVariableToString(c->getProcessPrimaryVariable())); - TreeItem* pvInfo = new TreeItem(pvData, condItem); - // add distribution information - QList<QVariant> disData; - disData << QString::fromStdString(convertDisTypeToString(c->getProcessDistributionType())); - TreeItem* disInfo = new TreeItem(disData, condItem); - - condItem->appendChild(pcsInfo); - condItem->appendChild(pvInfo); - condItem->appendChild(disInfo); - //if (stListItem->vtkSource()) - // stListItem->vtkSource()->SetName(fi.fileName()); - reset(); - - emit condAdded(this, this->index(parent->childCount()-1, 0, this->index(row, 0, QModelIndex()))); -} + TreeItem* geoParent = this->getGEOParent(QString::fromStdString(c->getAssociatedGeometryName()), true); + CondObjectListItem* condParent = this->getCondParent(geoParent, c->getCondType()); + if (condParent==NULL) condParent = this->createCondParent(geoParent, c->getCondType()); + + if (condParent) + { + QList<QVariant> condData; + condData << QString::fromStdString(c->getGeoName()) << QString::fromStdString(c->getGeoTypeAsString()); + CondItem* condItem = new CondItem(condData, condParent, c); + condParent->appendChild(condItem); + // add process information + QList<QVariant> pcsData; + pcsData << QString::fromStdString(convertProcessTypeToString(c->getProcessType())); + TreeItem* pcsInfo = new TreeItem(pcsData, condItem); + // add information on primary variable + QList<QVariant> pvData; + pvData << QString::fromStdString(convertPrimaryVariableToString(c->getProcessPrimaryVariable())); + TreeItem* pvInfo = new TreeItem(pvData, condItem); + // add distribution information + QList<QVariant> disData; + disData << QString::fromStdString(convertDisTypeToString(c->getProcessDistributionType())); + std::vector<double> dis_value = c->getDisValue(); + TreeItem* disInfo; + if (c->getProcessDistributionType() != FiniteElement::LINEAR) + { + for (size_t i=0; i<dis_value.size(); i++) disData << dis_value[i]; + disInfo = new TreeItem(disData, condItem); + } + else + { + size_t nVals = dis_value.size()/2; + disData << static_cast<int>(nVals); + disInfo = new TreeItem(disData, condItem); + for (size_t i=0; i<nVals; i++) + { + QList<QVariant> linData; + linData << dis_value[2*i] << dis_value[2*i+1]; + TreeItem* linInfo = new TreeItem(linData, disInfo); + disInfo->appendChild(linInfo); + } + } + + condItem->appendChild(pcsInfo); + condItem->appendChild(pvInfo); + condItem->appendChild(disInfo); + + condParent->addCondition(c); + reset(); + } + else + std::cout << "Error in ConditionModel::addConditionItem() - Parent object not found..." << std::endl; +} void ConditionModel::addConditions(std::vector<FEMCondition*> &conditions) { for (size_t i=0; i<conditions.size(); i++) - addCondition(conditions[i]); + { + bool is_domain = (conditions[i]->getGeoType() == GEOLIB::GEODOMAIN) ? true : false; + const GEOLIB::GeoObject* object = this->getGEOObject(conditions[i]->getAssociatedGeometryName(), conditions[i]->getGeoType(), conditions[i]->getGeoName()); + if (object || is_domain) + { + conditions[i]->setGeoObj(object); + _project.addCondition(conditions[i]); + this->addConditionItem(conditions[i]); + } + else + std::cout << "Error in ConditionModel::addConditions() - Specified geometrical object " << conditions[i]->getGeoName() << " not found in associated geometry..." << std::endl; + } } - -bool ConditionModel::removeCondition(const QModelIndex &idx) +/* +bool ConditionModel::removeConditionItem(const QModelIndex &idx) { if (idx.isValid()) { - CondItem* item = static_cast<CondItem*>(this->getItem(idx)); - emit condRemoved(this, idx); - TreeItem* parent = item->parentItem(); - parent->removeChildren(item->row(),1); - reset(); - return true; + CondItem* item = dynamic_cast<CondItem*>(this->getItem(idx)); + if (item) + { + emit conditionRemoved(this, idx); + TreeItem* parent = item->parentItem(); + if (parent->childCount() <=1) + this->removeFEMConditions(QString::fromStdString(item->getItem()->getAssociatedGeometryName()), item->getItem()->getCondType()); + else + parent->removeChildren(item->row(),1); + reset(); + return true; + } } - std::cout << "MshModel::removeMesh() - Specified index does not exist." << std::endl; + std::cout << "ConditionModel::removeCondition() - Specified index does not exist." << std::endl; return false; } +*/ -void ConditionModel::removeFEMConditions(const std::string &geometry_name, GEOLIB::GEOTYPE type) +void ConditionModel::removeFEMConditions(const QString &geometry_name, FEMCondition::CondType type) { - for (int j=0; j<this->_rootItem->childCount(); j++) + TreeItem* geoParent = this->getGEOParent(geometry_name); + emit conditionsRemoved(this, geometry_name.toStdString(), type); + + if ((type == FEMCondition::UNSPECIFIED) || (geoParent->childCount() <= 1)) //remove all conditions for the given geometry + removeRows(geoParent->row(), 1, QModelIndex()); + else { - TreeItem* parent = _rootItem->child(j); - for (int i=0; i<parent->childCount(); i++) - { - const FEMCondition* cond = static_cast<CondItem*>(parent->child(i))->getItem(); - if (geometry_name.compare(cond->getAssociatedGeometryName()) == 0) - { - if (type == GEOLIB::INVALID || type == cond->getGeoType()) - parent->removeChildren(i,1); - } - } + TreeItem* condParent = getCondParent(geoParent, type); + removeRows(condParent->row(), 1, index(geoParent->row(), 0)); + } + _project.removeConditions(geometry_name.toStdString(), type); +} + +const GEOLIB::GeoObject* ConditionModel::getGEOObject(const std::string &geo_name, GEOLIB::GEOTYPE type, const std::string &obj_name) const +{ + if (type==GEOLIB::POINT) return this->_project.getGEOObjects()->getPointVecObj(geo_name)->getElementByName(obj_name); + else if (type==GEOLIB::POLYLINE) return this->_project.getGEOObjects()->getPolylineVecObj(geo_name)->getElementByName(obj_name); + else if (type==GEOLIB::SURFACE) return this->_project.getGEOObjects()->getSurfaceVecObj(geo_name)->getElementByName(obj_name); + return NULL; +} + +int ConditionModel::getGEOIndex(const std::string &geo_name, GEOLIB::GEOTYPE type, const std::string &obj_name) const +{ + bool exists(false); + size_t idx(0); + if (type==GEOLIB::POINT) exists = this->_project.getGEOObjects()->getPointVecObj(geo_name)->getElementIDByName(obj_name, idx); + else if (type==GEOLIB::POLYLINE) exists = this->_project.getGEOObjects()->getPolylineVecObj(geo_name)->getElementIDByName(obj_name, idx); + else if (type==GEOLIB::SURFACE) exists = this->_project.getGEOObjects()->getSurfaceVecObj(geo_name)->getElementIDByName(obj_name, idx); + + if (exists) return idx; + return -1; +} + +TreeItem* ConditionModel::getGEOParent(const QString &geoName, bool create_item) +{ + int nLists = _rootItem->childCount(); + for (int i=0; i<nLists; i++) + { + if (_rootItem->child(i)->data(0).toString().compare(geoName) == 0) + return _rootItem->child(i); + } + + if (create_item) + { + QList<QVariant> geoData; + geoData << QVariant(geoName) << ""; + TreeItem* geo = new TreeItem(geoData, _rootItem); + _rootItem->appendChild(geo); + return geo; + } + return NULL; +} + +CondObjectListItem* ConditionModel::getCondParent(TreeItem* parent, FEMCondition::CondType type) +{ + int nLists = parent->childCount(); + for (int i=0; i<nLists; i++) + { + if (dynamic_cast<CondObjectListItem*>(parent->child(i))->getType() == type) + return dynamic_cast<CondObjectListItem*>(parent->child(i)); + } + return NULL; +} + +CondObjectListItem* ConditionModel::createCondParent(TreeItem* parent, FEMCondition::CondType type) +{ + QString condType(QString::fromStdString(FEMCondition::condTypeToString(type))); + QList<QVariant> condData; + condData << condType << ""; + + std::string geo_name = parent->data(0).toString().toStdString(); + const std::vector<GEOLIB::Point*> *pnts = _project.getGEOObjects()->getPointVec(geo_name); + if (pnts) + { + CondObjectListItem* cond = new CondObjectListItem(condData, parent, type, pnts); + parent->appendChild(cond); + emit conditionAdded(this, parent->data(0).toString().toStdString(), type); + return cond; + } + return NULL; +} + +vtkPolyDataAlgorithm* ConditionModel::vtkSource(const std::string &name, FEMCondition::CondType type) +{ + TreeItem* geoParent = this->getGEOParent(QString::fromStdString(name)); + if (geoParent) + { + CondObjectListItem* condParent = this->getCondParent(geoParent, type); + if (condParent) return condParent->vtkSource(); } + return NULL; } diff --git a/DataView/ConditionModel.h b/DataView/ConditionModel.h index 3cd81248b29d9d77c4e9af5ff81af6ae810b7c2d..b24f06a5e42a10673654801376145d442bed90bd 100644 --- a/DataView/ConditionModel.h +++ b/DataView/ConditionModel.h @@ -11,11 +11,18 @@ #include "ProjectData.h" class FEMCondition; +class CondObjectListItem; +class vtkPolyDataAlgorithm; + +namespace GEOLIB { + class GeoObject; + class GeoType; +} /** - * \brief The ConditionModel handels FEM conditions such as ICs, BCs and STs on geometric objects. + * \brief A model for the ConditionView implementing a tree of FEM-Conditions (BCs, ICs, STs) as a double-linked list. + * \sa TreeModel, ConditionView, TreeItem, CondObjectListItem */ - class ConditionModel : public TreeModel { Q_OBJECT @@ -25,43 +32,42 @@ public: ~ConditionModel(); int columnCount(const QModelIndex& parent = QModelIndex()) const; - //QVariant data(const QModelIndex& index, int role) const; - //QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - - //bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); + /// Returns the vtk source object for the specified subtree of a geometry with the given name. + vtkPolyDataAlgorithm* vtkSource(const std::string &name, FEMCondition::CondType type); public slots: - /// Adds new FEM condition - void addCondition(FEMCondition* conditions); - - /// Adds new FEM conditions + /// Adds a vector of FEM Conditions to the model. Objects in the vector can consist of BCs, ICs or STs in any combination and sequence. void addConditions(std::vector<FEMCondition*> &conditions); - /// Returns the FEM condition set on a GeoObject with the given name. - //const FEMCondition* getCondition(const string &name) const; + /// Removes a subtree (BCs, ICs, STs) from the the model. If all conditions for a given geometry are removed, this tree is completely removed. + void removeFEMConditions(const QString &geometry_name, FEMCondition::CondType type = FEMCondition::UNSPECIFIED); - /// Removes the FEM condition set on a GeoObject with the given name. - //bool removeCondition(const string &name); +private: + /// Adds a new FEM condition to the condition tree model. + void addConditionItem(FEMCondition* conditions); /// Removes the FEM condition with the given index. - bool removeCondition(const QModelIndex &idx); + //bool removeConditionItem(const QModelIndex &idx); - /// Removes conditions associated with the given geometry and type. - void removeFEMConditions(const std::string &geometry_name, GEOLIB::GEOTYPE type = GEOLIB::INVALID); - /// Reloads all items. - //void updateData(); + /// Creates the TreeItem for one of the condition subtrees. + CondObjectListItem* createCondParent(TreeItem* parent, FEMCondition::CondType type); + + /// Returns the subtree-item for a given type of condtion. + CondObjectListItem* getCondParent(TreeItem* parent, FEMCondition::CondType type); + + /// Returns the subtree item for a geometry with the given name. If create_item is true, this item will be created if it doesn't exist yet. + TreeItem* getGEOParent(const QString &geoName, bool create_item = false); + /// Returns the geo object for a geometric item of the given name and type for the associated geometry. + const GEOLIB::GeoObject* getGEOObject(const std::string &geo_name, GEOLIB::GEOTYPE type, const std::string &obj_name) const; + /// Returns the index of a geometric item of the given name and type for the associated geometry. + int getGEOIndex(const std::string &geo_name, GEOLIB::GEOTYPE type, const std::string &obj_name) const; -private: - //void setData(std::vector<GEOLIB::GeoObject*> *points, TreeItem* parent); ProjectData& _project; - TreeItem* _bcParent; - TreeItem* _icParent; - TreeItem* _stParent; signals: - void condAdded(ConditionModel*, const QModelIndex&); - void condRemoved(ConditionModel*, const QModelIndex&); + void conditionAdded(ConditionModel*, const std::string &name, FEMCondition::CondType); + void conditionsRemoved(ConditionModel*, const std::string &name, FEMCondition::CondType); }; #endif // CONDITIONMODEL_H diff --git a/DataView/ConditionTabWidget.cpp b/DataView/ConditionTabWidget.cpp index f64cc9bbbdd1e29cd1ce8dfd2dbbf157b1ba9ba4..d669b3cddc77ef97d3234bd79bb3b6cf8b8ecb66 100644 --- a/DataView/ConditionTabWidget.cpp +++ b/DataView/ConditionTabWidget.cpp @@ -15,34 +15,3 @@ ConditionTabWidget::ConditionTabWidget( QWidget* parent /*= 0*/ ) { setupUi(this); } - -void ConditionTabWidget::removeCondition() -{ - emit requestConditionRemoval(this->treeView->selectionModel()->currentIndex()); -} - -void ConditionTabWidget::removeAllConditions() -{ - ConditionModel* model = static_cast<ConditionModel*>(this->treeView->model()); - - for (size_t j=0; j<3; j++) - { - QModelIndex parentIndex = model->index(j, 0, QModelIndex()); - int nChildren = model->getItem(parentIndex)->childCount(); - for (int i=nChildren; i>=0; i--) - emit requestConditionRemoval(model->index(i, 0, parentIndex)); - } -} - - -void ConditionTabWidget::contextMenuEvent( QContextMenuEvent* event ) -{ - /* - QMenu menu; - QAction* editMeshAction = menu.addAction("Edit mesh..."); - QAction* saveMeshAction = menu.addAction("Save mesh..."); - connect(editMeshAction, SIGNAL(triggered()), this, SLOT(openMshEditDialog())); - connect(saveMeshAction, SIGNAL(triggered()), this, SLOT(writeMeshToFile())); - menu.exec(event->globalPos()); - */ -} diff --git a/DataView/ConditionTabWidget.h b/DataView/ConditionTabWidget.h index 2e592509e6fdcb00c1874ad0bd54af2c643808ea..16e58ccd564e58d2e07c8f614351c72f99aeab9b 100644 --- a/DataView/ConditionTabWidget.h +++ b/DataView/ConditionTabWidget.h @@ -21,18 +21,6 @@ class ConditionTabWidget : public QWidget, public Ui_ConditionTabWidgetBase public: ConditionTabWidget(QWidget* parent = 0); - void removeCondition(); - - void removeAllConditions(); - - void contextMenuEvent( QContextMenuEvent* event ); - - -private: - -signals: - void requestConditionRemoval(const QModelIndex&); - }; #endif // CONDITIONTABWIDGET_H diff --git a/DataView/ConditionView.cpp b/DataView/ConditionView.cpp index 1f26184bca85e111579b4626806fc8fcff7f0ff3..9fd5849583587a5dd33a2a6a56d40a9823897a41 100644 --- a/DataView/ConditionView.cpp +++ b/DataView/ConditionView.cpp @@ -7,6 +7,7 @@ #include "ConditionView.h" #include "ConditionModel.h" +#include "CondObjectListItem.h" #include "CondItem.h" @@ -35,14 +36,37 @@ void ConditionView::selectionChanged( const QItemSelection &selected, const QIte void ConditionView::contextMenuEvent( QContextMenuEvent* event ) { -// QModelIndex index = this->selectionModel()->currentIndex(); -// CondItem* item = static_cast<CondItem*>(index.internalPointer()); + Q_UNUSED(event); + + CondObjectListItem* item = dynamic_cast<CondObjectListItem*>(static_cast<ConditionModel*>(this->model())->getItem(this->selectionModel()->currentIndex())); + if (item) + { + QMenu menu; + QAction* removeAction = menu.addAction("Remove"); + connect(removeAction, SIGNAL(triggered()), this, SLOT(removeCondition())); + menu.exec(event->globalPos()); + } } void ConditionView::removeCondition() { - TreeItem* item = static_cast<ConditionModel*>(model())->getItem(this->selectionModel()->currentIndex()); - emit conditionRemoved((item->data(0).toString()).toStdString()); + CondObjectListItem* item = dynamic_cast<CondObjectListItem*>(static_cast<ConditionModel*>(this->model())->getItem(this->selectionModel()->currentIndex())); + QString geo_name = item->parentItem()->data(0).toString(); + FEMCondition::CondType type = item->getType(); + emit conditionsRemoved(geo_name, type); } +/* +void ConditionView::removeAllConditions() +{ + ConditionModel* model = static_cast<ConditionModel*>(this->model()); + for (size_t j=0; j<3; j++) + { + QModelIndex parentIndex = model->index(j, 0, QModelIndex()); + int nChildren = model->getItem(parentIndex)->childCount(); + for (int i=nChildren; i>=0; i--) + emit requestConditionRemoval(model->index(i, 0, parentIndex)); + } +} +*/ diff --git a/DataView/ConditionView.h b/DataView/ConditionView.h index 90d2e7902198ca6e47520f13c6b2fd382469f7b6..2ed40808e31ec621af666224a4b7f5a1c9a4c7bc 100644 --- a/DataView/ConditionView.h +++ b/DataView/ConditionView.h @@ -9,6 +9,11 @@ #include <QTreeView> #include <QContextMenuEvent> +#include "FEMCondition.h" + +class ConditionModel; + + /** * \brief A view for FEM-Conditions (Initial- & Boundary Conditions / Source Terms) with a number of additional * information such as Process Type, Distribution, etc. @@ -36,10 +41,13 @@ private: private slots: void on_Clicked(QModelIndex idx); void removeCondition(); + //void removeAllConditions(); signals: void itemSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected); - void conditionRemoved(std::string name); + void conditionsRemoved(QString, FEMCondition::CondType); + }; + #endif //CONDITIONVIEW_H diff --git a/DataView/DiagramPrefsDialog.cpp b/DataView/DiagramPrefsDialog.cpp index 6568f8294dcbdcffd7af7a3b4c2d4f58d00ad5e0..4eb74bfead5df6b65cfad9fc16b919d220f10971 100644 --- a/DataView/DiagramPrefsDialog.cpp +++ b/DataView/DiagramPrefsDialog.cpp @@ -70,7 +70,7 @@ void DiagramPrefsDialog::accept() DetailWindow* stationView = new DetailWindow(_list[0]); for (size_t i=1; i<_list.size(); i++) stationView->addList(_list[i]); - + stationView->setAttribute(Qt::WA_DeleteOnClose); stationView->show(); } else diff --git a/DataView/DiagramView/DetailWindow.cpp b/DataView/DiagramView/DetailWindow.cpp index 022044f361b08ddbffc528a4567b2b6239c60d00..85f474cf6e11e40f11f91d6fe65aa82b1d8650e7 100644 --- a/DataView/DiagramView/DetailWindow.cpp +++ b/DataView/DiagramView/DetailWindow.cpp @@ -18,15 +18,15 @@ DetailWindow::DetailWindow(QWidget* parent) : QWidget(parent) DiagramList* list2 = new DiagramList(); - /* ================================================== */ - /* input files should be defined in WaterML */ - /* inserting the details below into the list-objects */ - /* kind of simulates the information that would be */ - /* included in a WaterML-file and is needed for */ - /* display */ - /* ================================================== */ - - /* make up list-object for the first test station * + // ================================================== + // input files should be defined in WaterML + // inserting the details below into the list-objects + // kind of simulates the information that would be + // included in a WaterML-file and is needed for + // display + // ================================================== + + // make up list-object for the first test station list->setName("Water Level Observation Station: Halberstadt 2002"); list->setXLabel("Time"); list->setYLabel("Water Level"); @@ -35,7 +35,7 @@ DetailWindow::DetailWindow(QWidget* parent) : QWidget(parent) list->setColor(QColor(Qt::red)); list->readList("c:\\project\\timeseries-a.stn"); - /* make up list-object for the second test station * + // make up list-object for the second test station list2->setName("Water Level Observation Station: Oschersleben 2002"); list2->setXLabel("Time"); list2->setYLabel("Water Level"); @@ -44,7 +44,7 @@ DetailWindow::DetailWindow(QWidget* parent) : QWidget(parent) list2->setColor(QColor(Qt::green)); list2->readList("c:\\project\\timeseries-b.stn"); - /* ================================================== * + // ================================================== stationView->addGraph(list); @@ -106,4 +106,4 @@ void DetailWindow::addList(DiagramList* list, QColor c) { list->setColor(c); this->stationView->addGraph(list); -} \ No newline at end of file +} diff --git a/DataView/DiagramView/DiagramScene.cpp b/DataView/DiagramView/DiagramScene.cpp index cf9bca5aacb7ce33d5a6fc9e889af1a9da018b6c..85f75994a3298fe9af4f4445199f8c17a4a1bbf2 100644 --- a/DataView/DiagramView/DiagramScene.cpp +++ b/DataView/DiagramView/DiagramScene.cpp @@ -167,7 +167,7 @@ void DiagramScene::constructGrid() _grid = addGrid(_bounds, numXTicks, numYTicks, pen); for (int i = 0; i <= numXTicks; ++i) { - float x = _bounds.left()/_scaleX + (i * (_bounds.width()/_scaleX) / numXTicks); + int x = static_cast<int>(_bounds.left()/_scaleX + (i * (_bounds.width()/_scaleX) / numXTicks)); QDateTime currentDate = _startDate.addDays(x); _xTicksText.push_back(addNonScalableText(currentDate.toString("dd.MM.yyyy"))); _xTicksText.last()->setPos(x*_scaleX, _bounds.bottom() + 15); diff --git a/DataView/GeoTreeModel.cpp b/DataView/GeoTreeModel.cpp index 78ad439ecc38606900784934ec23d0f2d12ab9ef..b6bfe15107a64a7f30ff69285bb2c3db7fd3eddf 100644 --- a/DataView/GeoTreeModel.cpp +++ b/DataView/GeoTreeModel.cpp @@ -23,7 +23,7 @@ GeoTreeModel::GeoTreeModel( QObject *parent ) GeoTreeModel::~GeoTreeModel() { } - +/* const GEOLIB::GeoObject* GeoTreeModel::objectFromIndex( const QModelIndex& index, QString &geoName ) const { if (index.isValid()) @@ -35,7 +35,7 @@ const GEOLIB::GeoObject* GeoTreeModel::objectFromIndex( const QModelIndex& index } return NULL; } - +*/ void GeoTreeModel::addPointList(QString geoName, const GEOLIB::PointVec* pointVec) { const std::vector<GEOLIB::Point*> *points = pointVec->getVector(); diff --git a/DataView/GeoTreeModel.h b/DataView/GeoTreeModel.h index 9ac652a99697a751da4a9b210c12cab89cdfafb2..18d1c09bd46bd8b035561cf20bfbc2ccafcd2fbb 100644 --- a/DataView/GeoTreeModel.h +++ b/DataView/GeoTreeModel.h @@ -65,7 +65,7 @@ public: * \param listName Here, the method will put the name of the geometry this object belongs to. * \return A geo-object (Point / Polyline / Surface) */ - const GEOLIB::GeoObject* objectFromIndex( const QModelIndex& index, QString &geoName ) const; + //const GEOLIB::GeoObject* objectFromIndex( const QModelIndex& index, QString &geoName ) const; /// Returns the vtk-object indicated by type of the geometry indicated by name. vtkPolyDataAlgorithm* vtkSource(const std::string &name, GEOLIB::GEOTYPE type) const; diff --git a/DataView/MshLayerMapper.cpp b/DataView/MshLayerMapper.cpp index 2274e70f2e1bfda20caedfd75f0273510008d43c..2225a178069603a0f54735406b1667cff3e1c375 100644 --- a/DataView/MshLayerMapper.cpp +++ b/DataView/MshLayerMapper.cpp @@ -458,7 +458,7 @@ void MshLayerMapper::CheckLayerMapping(Mesh_Group::CFEMesh* mesh, const size_t n if (node->GetMark()) { node->SetIndex(counter); - node->connected_elements.clear(); + node->getConnectedElementIDs().clear(); node->connected_nodes.clear(); counter++; } @@ -529,7 +529,7 @@ void MshLayerMapper::CheckLayerMapping(Mesh_Group::CFEMesh* mesh, const size_t n { last = beg++; Mesh_Group::CNode* node = *last; - if ( node->connected_elements.empty() ) + if ( node->getConnectedElementIDs().empty() ) { delete node; node = NULL; diff --git a/DataView/MshModel.cpp b/DataView/MshModel.cpp index da3a2b6daa809b439583afdb844d3e5a9d02311b..76d8b12a20223f7a64c3a445514fc9da0ab01d77 100644 --- a/DataView/MshModel.cpp +++ b/DataView/MshModel.cpp @@ -31,10 +31,10 @@ MshModel::MshModel(ProjectData &project, QObject* parent /*= 0*/ ) void MshModel::addMesh(Mesh_Group::CFEMesh* mesh, std::string &name) { _project.addMesh(mesh, name); - this->addMesh(new GridAdapter(mesh), name); + this->addMeshObject(new GridAdapter(mesh), name); } -void MshModel::addMesh(GridAdapter* mesh, std::string &name) +void MshModel::addMeshObject(GridAdapter* mesh, std::string &name) { std::cout << "name: " << name << std::endl; QFileInfo fi(QString::fromStdString(name)); @@ -45,7 +45,6 @@ void MshModel::addMesh(GridAdapter* mesh, std::string &name) MshItem* newMesh = new MshItem(meshData, _rootItem, mesh); if (newMesh->vtkSource()) newMesh->vtkSource()->SetName(fi.fileName()); - std::cout << "name: " << fi.fileName().toStdString() << std::endl; _rootItem->appendChild(newMesh); reset(); @@ -110,6 +109,19 @@ bool MshModel::removeMesh(const std::string &name) return false; } +void MshModel::updateModel() +{ + const std::map<std::string, Mesh_Group::CFEMesh*> msh_vec = _project.getMeshObjects(); + for (std::map<std::string, Mesh_Group::CFEMesh*>::const_iterator it(msh_vec.begin()); it != msh_vec.end(); ++it) + { + if (this->getMesh(it->first) == NULL) + { + std::string name = it->first; + addMeshObject(new GridAdapter(it->second), name); + } + } +} + VtkMeshSource* MshModel::vtkSource(const QModelIndex &idx) const { if (idx.isValid()) @@ -177,37 +189,3 @@ bool MshModel::isUniqueMeshName(std::string &name) } */ -Mesh_Group::CFEMesh* MshModel::loadMeshFromFile(std::string fileName) -{ - std::cout << "FEMRead ... " << std::flush; -#ifndef NDEBUG - QTime myTimer; - myTimer.start(); -#endif - FEMDeleteAll(); - - CFEMesh* msh = FEMRead(fileName.substr(0, fileName.length()-4)); - if (msh) - { -#ifndef NDEBUG - QTime constructTimer; - constructTimer.start(); -#endif - msh->ConstructGrid(); - std::cout << "Nr. Nodes: " << msh->nod_vector.size() << endl; - std::cout << "Nr. Elements: " << msh->ele_vector.size() << endl; - -#ifndef NDEBUG - std::cout << "constructGrid time: " << constructTimer.elapsed() << " ms" << std::endl; -#endif - msh->FillTransformMatrix(); - -#ifndef NDEBUG - std::cout << "Loading time: " << myTimer.elapsed() << " ms" << std::endl; -#endif - return msh; - } - - cout << "Failed to load a mesh file: " << fileName << endl; - return NULL; -} diff --git a/DataView/MshModel.h b/DataView/MshModel.h index 88535d05fa4519c8ab75af47dc7f2d7fa8db15ee..f53d4de77fbced5e35b9e026f079fc8be53a0b24 100644 --- a/DataView/MshModel.h +++ b/DataView/MshModel.h @@ -29,8 +29,6 @@ public: /// Returns the number of columns used for the data list int columnCount(const QModelIndex& parent = QModelIndex()) const; - static Mesh_Group::CFEMesh* loadMeshFromFile(std::string fileName); - public slots: /// Adds a new mesh void addMesh(Mesh_Group::CFEMesh* mesh, std::string &name); @@ -42,6 +40,8 @@ public slots: bool removeMesh(const QModelIndex &idx); /// Removes the mesh with the given name. bool removeMesh(const std::string &name); + /// Updates the model based on the ProjectData-object + void updateModel(); /// Returns the VTK source item for the mesh with the given index. VtkMeshSource* vtkSource(const QModelIndex &idx) const; /// Returns the VTK source item for the mesh with the given name. @@ -49,7 +49,7 @@ public slots: private: /// Adds the mesh to the GUI-Mesh-Model und -View - void addMesh(GridAdapter* mesh, std::string &name); + void addMeshObject(GridAdapter* mesh, std::string &name); /// Checks if the name of the mesh is already exists, if so it generates a unique name. //bool isUniqueMeshName(std::string &name); diff --git a/DataView/VisPrefs.ui b/DataView/MshQualitySelection.ui similarity index 52% rename from DataView/VisPrefs.ui rename to DataView/MshQualitySelection.ui index 7ab7fea0f786f1ee3a6dd2ea360d3a87c9fda6c3..d082f66f6f32f99ae798acb28692800d047fe152 100644 --- a/DataView/VisPrefs.ui +++ b/DataView/MshQualitySelection.ui @@ -1,52 +1,50 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> - <class>VisPrefsDialog</class> - <widget class="QDialog" name="VisPrefsDialog"> + <class>MshQualitySelection</class> + <widget class="QDialog" name="MshQualitySelection"> <property name="geometry"> <rect> <x>0</x> <y>0</y> - <width>206</width> - <height>233</height> + <width>247</width> + <height>257</height> </rect> </property> <property name="windowTitle"> - <string>Visualisation Settings</string> + <string>Mesh Quality Selection</string> </property> - <layout class="QVBoxLayout" name="verticalLayout_3"> + <layout class="QVBoxLayout" name="verticalLayout"> <item> - <widget class="QGroupBox" name="LightBox"> + <widget class="QGroupBox" name="groupBox"> <property name="title"> - <string>Additional Illumination</string> + <string>Select Quality Measure</string> </property> <layout class="QVBoxLayout" name="verticalLayout_2"> <item> - <widget class="QCheckBox" name="lightAboveBox"> + <widget class="QRadioButton" name="choiceEdges"> <property name="text"> - <string>Light from above</string> + <string>Aspect Ratio of Edge Length</string> </property> </widget> </item> <item> - <widget class="QCheckBox" name="lightBelowBox"> + <widget class="QRadioButton" name="choiceArea"> <property name="text"> - <string>Light from below</string> + <string>Area of 2D Elements</string> </property> </widget> </item> - </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="ColorBox"> - <property name="title"> - <string>Background Colour</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> <item> - <widget class="ColorPickerPushButton" name="bgColorButton"> + <widget class="QRadioButton" name="choiceVolume"> <property name="text"> - <string>(255,255,255)</string> + <string>Volume of 3D Elements</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="choiceAngles"> + <property name="text"> + <string>Angles between Adjacent Edges</string> </property> </widget> </item> @@ -55,15 +53,6 @@ </item> <item> <widget class="QDialogButtonBox" name="buttonBox"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="layoutDirection"> - <enum>Qt::LeftToRight</enum> - </property> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> @@ -74,19 +63,12 @@ </item> </layout> </widget> - <customwidgets> - <customwidget> - <class>ColorPickerPushButton</class> - <extends>QPushButton</extends> - <header>ColorPickerPushButton.h</header> - </customwidget> - </customwidgets> <resources/> <connections> <connection> <sender>buttonBox</sender> <signal>accepted()</signal> - <receiver>VisPrefsDialog</receiver> + <receiver>MshQualitySelection</receiver> <slot>accept()</slot> <hints> <hint type="sourcelabel"> @@ -102,7 +84,7 @@ <connection> <sender>buttonBox</sender> <signal>rejected()</signal> - <receiver>VisPrefsDialog</receiver> + <receiver>MshQualitySelection</receiver> <slot>reject()</slot> <hints> <hint type="sourcelabel"> diff --git a/DataView/MshQualitySelectionDialog.cpp b/DataView/MshQualitySelectionDialog.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c19c545c9d53fcbc797ab5481fdcbf0916314df8 --- /dev/null +++ b/DataView/MshQualitySelectionDialog.cpp @@ -0,0 +1,39 @@ +/** + * \file MshQualitySelectionDialog.cpp + * 2011/03/16 KR Initial implementation + */ + +#include "MshQualitySelectionDialog.h" +#include "VtkMeshSource.h" + +/// Constructor +MshQualitySelectionDialog::MshQualitySelectionDialog(VtkMeshSource* msh, QDialog* parent) +: QDialog(parent), _msh(msh) +{ + setupUi(this); + this->choiceEdges->toggle(); +} + +MshQualitySelectionDialog::~MshQualitySelectionDialog() +{ +} + +/// Instructions if the OK-Button has been pressed. +void MshQualitySelectionDialog::accept() +{ + MshQualityType::type t; + if (this->choiceEdges->isChecked()) t = MshQualityType::EDGERATIO; + else if (this->choiceArea->isChecked()) t = MshQualityType::AREA; + else if (this->choiceVolume->isChecked()) t = MshQualityType::VOLUME; + else if (this->choiceAngles->isChecked()) t = MshQualityType::EQUIANGLESKEW; + else t = MshQualityType::INVALID; + + emit measureSelected(_msh, t); + this->done(QDialog::Accepted); +} + +/// Instructions if the Cancel-Button has been pressed. +void MshQualitySelectionDialog::reject() +{ + this->done(QDialog::Rejected); +} diff --git a/DataView/MshQualitySelectionDialog.h b/DataView/MshQualitySelectionDialog.h new file mode 100644 index 0000000000000000000000000000000000000000..8441be7b1edac55df99ec3a8adcb3ec05b82f821 --- /dev/null +++ b/DataView/MshQualitySelectionDialog.h @@ -0,0 +1,38 @@ +/** + * \file MshQualitySelectionDialog.h + * 2011/03/16 KR Initial implementation + */ + +#ifndef MSHQUALITYSELECTIONDIALOG_H +#define MSHQUALITYSELECTIONDIALOG_H + + +#include "ui_MshQualitySelection.h" +#include "MSHEnums.h" + +class VtkMeshSource; + +/** + * \brief A dialog window for settung up a database connection + */ +class MshQualitySelectionDialog : public QDialog, private Ui_MshQualitySelection +{ + Q_OBJECT + +public: + MshQualitySelectionDialog(VtkMeshSource* msh, QDialog* parent = 0); + ~MshQualitySelectionDialog(void); + +private: + VtkMeshSource* _msh; + +private slots: + void accept(); + void reject(); + +signals: + void measureSelected(VtkMeshSource*, MshQualityType::type); + +}; + +#endif //MSHQUALITYSELECTIONDIALOG_H diff --git a/DataView/MshTabWidget.cpp b/DataView/MshTabWidget.cpp index 87eea6ed3e6600edca9e8463ab0ee825a5e52a2e..68addf1a13416cc8d1bc2dcf792da131702da4f9 100644 --- a/DataView/MshTabWidget.cpp +++ b/DataView/MshTabWidget.cpp @@ -22,6 +22,7 @@ #include <QFileDialog> #include <QSettings> +#include "MeshIO/OGSMeshIO.h" MshTabWidget::MshTabWidget( QWidget* parent /*= 0*/ ) : QWidget(parent) @@ -50,7 +51,7 @@ void MshTabWidget::addMeshAction() if (!fileName.isEmpty()) { std::string name = fileName.toStdString(); - Mesh_Group::CFEMesh* msh = MshModel::loadMeshFromFile(name); + Mesh_Group::CFEMesh* msh = FileIO::OGSMeshIO::loadMeshFromFile(name); if (msh) static_cast<MshModel*>(this->treeView->model())->addMesh(msh, name); } } @@ -76,7 +77,7 @@ void MshTabWidget::contextMenuEvent( QContextMenuEvent* event ) QAction* checkMeshAction = menu.addAction("Check mesh quality..."); QAction* saveMeshAction = menu.addAction("Save mesh..."); menu.addSeparator(); - QAction* removeMeshAction = menu.addAction("Remove..."); + QAction* removeMeshAction = menu.addAction("Remove mesh"); connect(editMeshAction, SIGNAL(triggered()), this, SLOT(openMshEditDialog())); connect(checkMeshAction, SIGNAL(triggered()), this, SLOT(checkMeshQuality())); connect(saveMeshAction, SIGNAL(triggered()), this, SLOT(writeMeshToFile())); @@ -108,10 +109,15 @@ int MshTabWidget::writeMeshToFile() const if (!fileName.empty()) { std::fstream* out = new std::fstream(fileName.c_str(), std::fstream::out); - if (out->is_open()) - { + if (out->is_open()) { mesh->Write(out); out->close(); + // write mesh without null-volume-elements +// std::ofstream out1 ("mesh_without_null_elements.msh"); +// FileIO::OGSMeshIO ogs_mesh_io; +// ogs_mesh_io.write (mesh, out1); +// out1.close (); + return 1; } else diff --git a/DataView/OGSRaster.cpp b/DataView/OGSRaster.cpp index b0bcf895cf50134ca183b53d626fb0d845270b81..74b0b081e2617ea72b41ce39edfd10906c75b7b7 100644 --- a/DataView/OGSRaster.cpp +++ b/DataView/OGSRaster.cpp @@ -16,10 +16,10 @@ #include "StringTools.h" #include "OGSError.h" -// libgeotiff includes +#ifdef libgeotiff_FOUND #include "geo_tiffp.h" #include "xtiffio.h" - +#endif bool OGSRaster::loadImage(const QString &fileName, QImage &raster, QPointF &origin, double &scalingFactor, bool autoscale /* = true */, bool mirrorX /* = false */) @@ -35,12 +35,14 @@ bool OGSRaster::loadImage(const QString &fileName, QImage &raster, QPointF &orig if (mirrorX) raster = raster.transformed(QTransform(1, 0, 0, -1, 0, 0), Qt::FastTransformation); } +#ifdef libgeotiff_FOUND else if (fileInfo.suffix().toLower() == "tif") { if (!loadImageFromTIFF(fileName, raster, origin, scalingFactor)) return false; if (!mirrorX) raster = raster.transformed(QTransform(1, 0, 0, -1, 0, 0), Qt::FastTransformation); } +#endif else { if (!loadImageFromFile(fileName, raster)) return false; @@ -189,6 +191,7 @@ double* OGSRaster::loadDataFromASC(const QString &fileName, double &x0, double & return NULL; } +#ifdef libgeotiff_FOUND bool OGSRaster::loadImageFromTIFF(const QString &fileName, QImage &raster, QPointF &origin, double &cellsize) { TIFF* tiff = XTIFFOpen(fileName.toStdString().c_str(), "r"); @@ -284,7 +287,7 @@ bool OGSRaster::loadImageFromTIFF(const QString &fileName, QImage &raster, QPoin std::cout << "OGSRaster::loadImageFromTIFF() - File not recognised as TIFF-Image." << std::endl; return false; } - +#endif bool OGSRaster::loadImageFromFile(const QString &fileName, QImage &raster) { diff --git a/DataView/OGSRaster.h b/DataView/OGSRaster.h index 05b7aa02e0f16abfaead40980d13ea62dc83b344..918397539c858ccf60f9e8504c4a5f5d844146fe 100644 --- a/DataView/OGSRaster.h +++ b/DataView/OGSRaster.h @@ -7,6 +7,7 @@ #define OGSRASTER_H #include <fstream> +#include "Configure.h" class QImage; class QPointF; @@ -95,7 +96,9 @@ private: * \param cellsize The size of each pixel in the image which is needed for re-scaling the data * \return True if the raster data was loaded correctly, false otherwise. */ +#ifdef libgeotiff_FOUND static bool loadImageFromTIFF(const QString &fileName, QImage &raster, QPointF &origin, double &scalingFactor); +#endif /** * Loads image files into a QPixmap object. Since images are not geo-referenced no origin point will be returned. diff --git a/DataView/StationTreeView.cpp b/DataView/StationTreeView.cpp index 81633d0c2372ec0251c4df5c97cd4b3f806c9897..ca0204256e9ab629ce9faecd7dba2fc6d097e51a 100644 --- a/DataView/StationTreeView.cpp +++ b/DataView/StationTreeView.cpp @@ -7,6 +7,7 @@ #include <QFileDialog> #include <QMenu> +#include "Configure.h" #include "Station.h" #include "StationIO.h" #include "GMSInterface.h" @@ -112,6 +113,7 @@ void StationTreeView::displayStratigraphy() // get color table (horrible way to do it but there you go ...) std::map<std::string, GEOLIB::Color*> colorLookupTable = static_cast<VtkStationSource*>(static_cast<StationTreeModel*>(model())->vtkSource(temp_name.toStdString()))->getColorLookupTable(); StratWindow* stratView = new StratWindow(static_cast<GEOLIB::StationBorehole*>(static_cast<StationTreeModel*>(model())->stationFromIndex(index, temp_name)), &colorLookupTable); + stratView->setAttribute(Qt::WA_DeleteOnClose); // this fixes the memory leak shown by cppcheck stratView->show(); } @@ -185,6 +187,7 @@ void StationTreeView::writeStratigraphiesAsImages(QString listName) for (size_t i=0; i<stations->size(); i++) { StratWindow* stratView = new StratWindow(static_cast<GEOLIB::StationBorehole*>((*stations)[i]), &colorLookupTable); + stratView->setAttribute(Qt::WA_DeleteOnClose); // this fixes the memory leak shown by cppcheck stratView->show(); stratView->stationView->saveAsImage("c:/project/" + QString::fromStdString(static_cast<GEOLIB::StationBorehole*>((*stations)[i])->getName()) + ".jpg"); stratView->close(); diff --git a/DataView/StratView/StratView.cpp b/DataView/StratView/StratView.cpp index a981fd736dce226c44c86e266510f5b99b98ee2c..1b15ada33dd68d1f3704451aa21c7a438c6dedf6 100644 --- a/DataView/StratView/StratView.cpp +++ b/DataView/StratView/StratView.cpp @@ -47,7 +47,7 @@ void StratView::saveAsImage(QString fileName) this->update(); QRectF viewRect = _scene->itemsBoundingRect(); - QImage img(viewRect.width()+2*_scene->MARGIN, 600, QImage::Format_ARGB32); + QImage img(static_cast<int>(viewRect.width())+2*_scene->MARGIN, 600, QImage::Format_ARGB32); QPainter painter(&img); this->render(&painter); diff --git a/DataView/StratView/StratWindow.h b/DataView/StratView/StratWindow.h index cf9b9cd01c3429be86d9b74429cfd7c0b8868525..85023b7ff1086218c283fb41c784a2739a0e4088 100644 --- a/DataView/StratView/StratWindow.h +++ b/DataView/StratView/StratWindow.h @@ -6,7 +6,7 @@ #ifndef STRATWINDOW_H #define STRATWINDOW_H -#include <QtGui/QWidget> +#include <QWidget> #include "ui_StratWindow.h" namespace GEOLIB diff --git a/DataView/ViewWidget3dBase.ui b/DataView/ViewWidget3dBase.ui deleted file mode 100644 index 9d4103511e6fc612a7feeeb87b1d095e6115db9b..0000000000000000000000000000000000000000 --- a/DataView/ViewWidget3dBase.ui +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>ViewWidget3dBase</class> - <widget class="QMainWindow" name="ViewWidget3dBase"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>341</width> - <height>386</height> - </rect> - </property> - <property name="windowTitle"> - <string>MainWindow</string> - </property> - <widget class="QWidget" name="centralwidget"> - <layout class="QVBoxLayout" name="verticalLayout"> - <property name="margin"> - <number>0</number> - </property> - <item> - <widget class="OSGWidget" name="osgWidget" native="true"/> - </item> - </layout> - </widget> - <widget class="QToolBar" name="toolBar"> - <property name="windowTitle"> - <string>toolBar</string> - </property> - <attribute name="toolBarArea"> - <enum>TopToolBarArea</enum> - </attribute> - <attribute name="toolBarBreak"> - <bool>false</bool> - </attribute> - <addaction name="actionShow_All"/> - </widget> - <action name="actionShow_All"> - <property name="text"> - <string>Show All</string> - </property> - <property name="toolTip"> - <string>Shows the entire 3d scene and adapts the mouse navigation sensitivity to the scenes size.</string> - </property> - </action> - </widget> - <customwidgets> - <customwidget> - <class>OSGWidget</class> - <extends>QWidget</extends> - <header>OSGWidget.h</header> - <container>1</container> - </customwidget> - </customwidgets> - <resources/> - <connections/> -</ui> diff --git a/DataView/VisPrefsDialog.cpp b/DataView/VisPrefsDialog.cpp deleted file mode 100644 index 507e487d51d9bc1f1e00149d732efb8feb501d61..0000000000000000000000000000000000000000 --- a/DataView/VisPrefsDialog.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/** - * \file VisPrefsDialog.cpp - * 14/06/2010 KR Initial implementation - */ - -#include <QSettings> -#include "VisPrefsDialog.h" - -#include "VtkVisPipeline.h" - -/// Constructor -VisPrefsDialog::VisPrefsDialog(VtkVisPipeline* pipeline, QDialog* parent) : - QDialog(parent), _vtkVisPipeline(pipeline), _above(0,0,2000000), _below(0,0,-2000000) -{ - setupUi(this); - if (_vtkVisPipeline->getLight(_above)) - lightAboveBox->toggle(); - if (_vtkVisPipeline->getLight(_below)) - lightBelowBox->toggle(); - - QColor color = _vtkVisPipeline->getBGColor(); - bgColorButton->setColor(_vtkVisPipeline->getBGColor()); -} - -VisPrefsDialog::~VisPrefsDialog() -{ -} - -void VisPrefsDialog::on_bgColorButton_colorPicked( QColor color ) -{ - QColor bgColor(color.red(), color.green(), color.blue()); - _vtkVisPipeline->setBGColor(bgColor); -} - -void VisPrefsDialog::on_lightAboveBox_clicked() -{ - if (lightAboveBox->isChecked()) - _vtkVisPipeline->addLight(_above); - else - _vtkVisPipeline->removeLight(_above); -} - -void VisPrefsDialog::on_lightBelowBox_clicked() -{ - if (lightBelowBox->isChecked()) - _vtkVisPipeline->addLight(_below); - else - _vtkVisPipeline->removeLight(_below); -} - -void VisPrefsDialog::accept() -{ - this->done(QDialog::Accepted); -} - - -void VisPrefsDialog::reject() -{ - this->done(QDialog::Rejected); -} diff --git a/Gui/CMakeLists.txt b/Gui/CMakeLists.txt index 24a8cd3952c1f305a9c097f33c92398b79f416e3..5b5df2e16381a0c51b22a5668d0aca697a7be984 100644 --- a/Gui/CMakeLists.txt +++ b/Gui/CMakeLists.txt @@ -45,9 +45,12 @@ INCLUDE_DIRECTORIES( ../StratView ../VtkVis ../VtkAct - ${Shapelib_INCLUDE_DIR} ) +IF (Shapelib_FOUND) + INCLUDE_DIRECTORIES( ${Shapelib_INCLUDE_DIR} ) +ENDIF () # Shapelib_FOUND + if (OGS_COMPILE_QVTK) INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/Qt/QVTK ../QVTK) endif (OGS_COMPILE_QVTK) @@ -56,7 +59,6 @@ endif (OGS_COMPILE_QVTK) SOURCE_GROUP("UI Files" REGULAR_EXPRESSION "\\w*\\.ui") SOURCE_GROUP("Moc Files" REGULAR_EXPRESSION "moc_.*") - # Create the library ADD_EXECUTABLE( ogs-gui main.cpp @@ -67,7 +69,6 @@ ADD_EXECUTABLE( ogs-gui ${UIS} ) -# Link Qt library TARGET_LINK_LIBRARIES( ogs-gui ${QT_LIBRARIES} Base @@ -79,18 +80,23 @@ TARGET_LINK_LIBRARIES( ogs-gui QtBase QtDataView StratView - ${Shapelib_LIBRARIES} - ${libtiff_LIBRARIES} - ${libgeotiff_LIBRARIES} QVTK VtkVis VtkAct ) +IF (Shapelib_FOUND) + TARGET_LINK_LIBRARIES( ogs-gui ${Shapelib_LIBRARIES} ) +ENDIF () # Shapelib_FOUND + +IF (libtiff_FOUND AND libgeotiff_FOUND) + TARGET_LINK_LIBRARIES( ogs-gui ${libtiff_LIBRARIES} ${libgeotiff_LIBRARIES} ) +ENDIF () # libtiff_FOUND AND libgeotiff_FOUND + ADD_DEPENDENCIES ( ogs-gui VtkVis OGSProject ) -# Set linker flags IF(MSVC) + # Set linker flags SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:MSVCRT") ENDIF(MSVC) diff --git a/Gui/mainwindow.cpp b/Gui/mainwindow.cpp index 394b45cc4c586a544232d4d399a6a2a056a3ecf9..969462fc5c54dd23379239dd16f7e35218d122eb 100644 --- a/Gui/mainwindow.cpp +++ b/Gui/mainwindow.cpp @@ -19,13 +19,16 @@ #include "GMSHPrefsDialog.h" #include "LineEditDialog.h" #include "ListPropertiesDialog.h" -#include "SHPImportDialog.h" +#include "MshQualitySelectionDialog.h" #include "VtkAddFilterDialog.h" #include "VisPrefsDialog.h" +#ifdef Shapelib_FOUND +#include "SHPImportDialog.h" +#endif + #include "OGSRaster.h" #include "OGSError.h" -#include "Configure.h" #include "VtkVisPipeline.h" #include "VtkVisPipelineItem.h" #include "RecentFiles.h" @@ -53,6 +56,8 @@ //test #include "MathIO/CRSIO.h" +#include "StringTools.h" + // MSH #include "msh_mesh.h" @@ -86,20 +91,20 @@ Problem *aproblem = NULL; using namespace FileIO; MainWindow::MainWindow(QWidget *parent /* = 0*/) -: QMainWindow(parent), _db (NULL) +: QMainWindow(parent), _db (NULL), _project() { setupUi(this); // Setup various models _geoModels = new GEOModels(); - geoTabWidget->treeView->setModel(_geoModels->getGeoModel()); + _project.setGEOObjects(_geoModels); + _meshModels = new MshModel(_project); + _conditionModel = new ConditionModel(_project); + geoTabWidget->treeView->setModel(_geoModels->getGeoModel()); stationTabWidget->treeView->setModel(_geoModels->getStationModel()); - - _meshModels = new MshModel(_project); mshTabWidget->treeView->setModel(_meshModels); - - _conditionModel = new ConditionModel(_project); + conditionTabWidget->treeView->setModel(_conditionModel); // vtk visualization pipeline #ifdef OGS_USE_OPENSG @@ -149,12 +154,12 @@ MainWindow::MainWindow(QWidget *parent /* = 0*/) connect(mshTabWidget, SIGNAL(requestMeshRemoval(const QModelIndex&)), _meshModels, SLOT(removeMesh(const QModelIndex&))); connect(mshTabWidget, SIGNAL(qualityCheckRequested(VtkMeshSource*)), - _vtkVisPipeline, SLOT(checkMeshQuality(VtkMeshSource*))); + this, SLOT(showMshQualitySelectionDialog(VtkMeshSource*))); + // Setup connections for condition model to GUI - conditionTabWidget->treeView->setModel(_conditionModel); - connect(conditionTabWidget, SIGNAL(requestConditionRemoval(const QModelIndex&)), - _conditionModel, SLOT(removeCondition(const QModelIndex&))); + connect(conditionTabWidget->treeView, SIGNAL(conditionsRemoved(QString, FEMCondition::CondType)), + _conditionModel, SLOT(removeFEMConditions(QString, FEMCondition::CondType))); // VisPipeline Connects connect(_geoModels, SIGNAL(geoDataAdded(GeoTreeModel*, std::string, GEOLIB::GEOTYPE)), @@ -162,6 +167,11 @@ MainWindow::MainWindow(QWidget *parent /* = 0*/) connect(_geoModels, SIGNAL(geoDataRemoved(GeoTreeModel*, std::string, GEOLIB::GEOTYPE)), _vtkVisPipeline, SLOT(removeSourceItem(GeoTreeModel*, std::string, GEOLIB::GEOTYPE))); + connect(_conditionModel, SIGNAL(conditionAdded(ConditionModel*, std::string, FEMCondition::CondType)), + _vtkVisPipeline, SLOT(addPipelineItem(ConditionModel*, std::string, FEMCondition::CondType))); + connect(_conditionModel, SIGNAL(conditionsRemoved(ConditionModel*, std::string, FEMCondition::CondType)), + _vtkVisPipeline, SLOT(removeSourceItem(ConditionModel*, std::string, FEMCondition::CondType))); + connect(_geoModels, SIGNAL(stationVectorAdded(StationTreeModel*, std::string)), _vtkVisPipeline, SLOT(addPipelineItem(StationTreeModel*, std::string))); connect(_geoModels, SIGNAL(stationVectorRemoved(StationTreeModel*, std::string)), @@ -191,6 +201,15 @@ MainWindow::MainWindow(QWidget *parent /* = 0*/) SIGNAL(actorSelected(vtkProp3D*)), (QObject*) (visualizationWidget->interactorStyle()), SLOT(highlightActor(vtkProp3D*))); + connect((QObject*) (visualizationWidget->interactorStyle()), + SIGNAL(requestViewUpdate()), + visualizationWidget, SLOT(updateView())); + + // Propagates selected vtk object in the pipeline to the pick interactor + connect(vtkVisTabWidget->vtkVisPipelineView, + SIGNAL(dataObjectSelected(vtkDataObject*)), + (QObject*) (visualizationWidget->interactorStyle()), + SLOT(pickableDataObject(vtkDataObject*))); connect((QObject*) (visualizationWidget->vtkPickCallback()), SIGNAL(actorPicked(vtkProp3D*)), vtkVisTabWidget->vtkVisPipelineView, SLOT(selectItem(vtkProp3D*))); @@ -216,7 +235,7 @@ MainWindow::MainWindow(QWidget *parent /* = 0*/) const unsigned int screenCount = desktopWidget->screenCount(); #endif // OGS_QT_VERSION < 46 for (size_t i = 0; i < screenCount; ++i) - _screenGeometries.push_back(desktopWidget->availableGeometry(i)); + _screenGeometries.push_back(desktopWidget->availableGeometry((int)i)); // Setup import files menu menu_File->insertMenu(action_Exit, createImportFilesMenu()); @@ -279,6 +298,9 @@ MainWindow::MainWindow(QWidget *parent /* = 0*/) connect(stationTabWidget->treeView, SIGNAL(propertiesDialogRequested(std::string)), this, SLOT(showPropertiesDialog(std::string))); + + _visPrefsDialog = new VisPrefsDialog(_vtkVisPipeline, visualizationWidget); + // std::cout << "size of Point: " << sizeof (GEOLIB::Point) << std::endl; // std::cout << "size of CGLPoint: " << sizeof (CGLPoint) << std::endl; // @@ -301,7 +323,6 @@ MainWindow::MainWindow(QWidget *parent /* = 0*/) // std::cout << "size of CSourceTerm: " << sizeof (CSourceTerm) << std::endl; // std::cout << "size of CBoundaryCondition: " << sizeof (CBoundaryCondition) << std::endl; - // std::cout << "size of CElem: " << sizeof (CElem) << std::endl; // std::cout << "size of CElement: " << sizeof (FiniteElement::CElement) << std::endl; // std::cout << "size of CRFProcess: " << sizeof (CRFProcess) << std::endl; // std::cout << "size of CFEMesh: " << sizeof (Mesh_Group::CFEMesh) << std::endl; @@ -312,7 +333,9 @@ MainWindow::~MainWindow() delete _db; delete _vtkVisPipeline; delete _meshModels; - delete _geoModels; + delete _conditionModel; + //delete _visPrefsDialog; + //delete _geoModels; #ifdef OGS_USE_VRPN delete _trackingSettingsWidget; @@ -421,7 +444,7 @@ void MainWindow::save() if (fi.suffix().toLower() == "gsp") { std::string schemaName(_fileFinder.getPath("OpenGeoSysProject.xsd")); - XMLInterface xml(_geoModels, schemaName); + XMLInterface xml(&_project, schemaName); xml.writeProjectFile(fileName); /* } else if (fi.suffix().toLower() == "gml") { @@ -485,15 +508,17 @@ void MainWindow::loadFile(const QString &fileName) // GEOCalcPointMinMaxCoordinates(); } else if (fi.suffix().toLower() == "gsp") { std::string schemaName(_fileFinder.getPath("OpenGeoSysProject.xsd")); - XMLInterface xml(_geoModels, schemaName); + XMLInterface xml(&_project, schemaName); xml.readProjectFile(fileName); + std::cout << "Adding missing meshes to GUI..." << std::endl; + _meshModels->updateModel(); } else if (fi.suffix().toLower() == "gml") { #ifndef NDEBUG QTime myTimer0; myTimer0.start(); #endif std::string schemaName(_fileFinder.getPath("OpenGeoSysGLI.xsd")); - XMLInterface xml(_geoModels, schemaName); + XMLInterface xml(&_project, schemaName); xml.readGLIFile(fileName); #ifndef NDEBUG std::cout << myTimer0.elapsed() << " ms" << std::endl; @@ -502,13 +527,13 @@ void MainWindow::loadFile(const QString &fileName) // OpenGeoSys observation station files (incl. boreholes) else if (fi.suffix().toLower() == "stn") { std::string schemaName(_fileFinder.getPath("OpenGeoSysSTN.xsd")); - XMLInterface xml(_geoModels, schemaName); + XMLInterface xml(&_project, schemaName); xml.readSTNFile(fileName); } // OpenGeoSys mesh files else if (fi.suffix().toLower() == "msh") { std::string name = fileName.toStdString(); - Mesh_Group::CFEMesh* msh = MshModel::loadMeshFromFile(name); + Mesh_Group::CFEMesh* msh = FileIO::OGSMeshIO::loadMeshFromFile(name); if (msh) _meshModels->addMesh(msh, name); else @@ -529,7 +554,7 @@ void MainWindow::loadFile(const QString &fileName) else if (fi.suffix().toLower() == "3dm") { std::string name = fileName.toStdString(); Mesh_Group::CFEMesh* mesh = GMSInterface::readGMS3DMMesh(name); - _meshModels->addMesh(mesh, name); + if (mesh) _meshModels->addMesh(mesh, name); } // goCAD files else if (fi.suffix().toLower() == "ts") { @@ -596,7 +621,7 @@ void MainWindow::loadPetrelFiles(const QStringList &sfc_file_names, void MainWindow::updateDataViews() { - visualizationWidget->showAll(); + visualizationWidget->updateViewOnLoad(); geoTabWidget-> treeView->updateView(); stationTabWidget-> treeView->updateView(); mshTabWidget-> treeView->updateView(); @@ -645,8 +670,10 @@ QMenu* MainWindow::createImportFilesMenu() QAction* rasterPolyFiles = importFiles->addAction("R&aster Files as PolyData..."); connect(rasterPolyFiles, SIGNAL(triggered()), this, SLOT(importRasterAsPoly())); #endif +#ifdef Shapelib_FOUND QAction* shapeFiles = importFiles->addAction("&Shape Files..."); connect(shapeFiles, SIGNAL(triggered()), this, SLOT(importShape())); +#endif QAction* vtkFiles = importFiles->addAction("&VTK Files..."); connect( vtkFiles, SIGNAL(triggered()), this, SLOT(importVtk()) ); @@ -684,15 +711,18 @@ void MainWindow::importGoCad() void MainWindow::importRaster() { QSettings settings("UFZ", "OpenGeoSys-5"); + #ifdef libgeotiff_FOUND + QString geotiffExtension(" *.tif"); + #else + QString geotiffExtension(""); + #endif QString fileName = QFileDialog::getOpenFileName(this, "Select raster file to import", settings.value( "lastOpenedFileDirectory").toString(), - "Raster files (*.asc *.bmp *.jpg *.png *.tif);;"); - QFileInfo fi(fileName); - QString fileType = fi.suffix().toLower(); - - if ((fileType == "asc") || (fileType == "tif") || (fileType == "png") - || (fileType == "jpg") || (fileType == "bmp")) { + QString("Raster files (*.asc *.bmp *.jpg *.png%1);;").arg(geotiffExtension)); + + if (!fileName.isEmpty()) + { VtkGeoImageSource* geoImage = VtkGeoImageSource::New(); geoImage->setImageFilename(fileName); _vtkVisPipeline->addPipelineItem(geoImage); @@ -700,22 +730,23 @@ void MainWindow::importRaster() QDir dir = QDir(fileName); settings.setValue("lastOpenedFileDirectory", dir.absolutePath()); } - else if (fileName.length() > 0) OGSError::box( - "File extension not supported."); } void MainWindow::importRasterAsPoly() { QSettings settings("UFZ", "OpenGeoSys-5"); + #ifdef libgeotiff_FOUND + QString geotiffExtension(" *.tif"); + #else + QString geotiffExtension(""); + #endif QString fileName = QFileDialog::getOpenFileName(this, "Select raster file to import", settings.value( "lastOpenedFileDirectory").toString(), - "Raster files (*.asc *.bmp *.jpg *.png *.tif);;"); - QFileInfo fi(fileName); - - if ((fi.suffix().toLower() == "asc") || (fi.suffix().toLower() == "tif") - || (fi.suffix().toLower() == "png") || (fi.suffix().toLower() - == "jpg") || (fi.suffix().toLower() == "bmp")) { + QString("Raster files (*.asc *.bmp *.jpg *.png%1);;").arg(geotiffExtension)); + + if (!fileName.isEmpty()) + { QImage raster; QPointF origin; double scalingFactor; @@ -730,11 +761,10 @@ void MainWindow::importRasterAsPoly() QDir dir = QDir(fileName); settings.setValue("lastOpenedFileDirectory", dir.absolutePath()); - - } else - OGSError::box("File extension not supported."); + } } +#ifdef Shapelib_FOUND void MainWindow::importShape() { QSettings settings("UFZ", "OpenGeoSys-5"); @@ -752,6 +782,7 @@ void MainWindow::importShape() settings.setValue("lastOpenedFileDirectory", dir.absolutePath()); } } +#endif void MainWindow::importPetrel() { @@ -824,14 +855,15 @@ void MainWindow::loadFEMConditionsFromFile(std::string geoName) if (!fileName.isEmpty()) { QFileInfo fi(fileName); + QDir dir = QDir(fileName); + settings.setValue("lastOpenedFileDirectory", dir.absolutePath()); + std::vector<FEMCondition*> conditions; if (fi.suffix().toLower() == "cnd") { std::string schemaName(_fileFinder.getPath("OpenGeoSysCond.xsd")); - XMLInterface xml(_geoModels, schemaName); + XMLInterface xml(&_project, schemaName); xml.readFEMCondFile(conditions, fileName, QString::fromStdString(geoName)); - if (!conditions.empty()) - this->_conditionModel->addConditions(conditions); } else if (fi.suffix().toLower() == "bc") { @@ -865,21 +897,28 @@ void MainWindow::loadFEMConditionsFromFile(std::string geoName) } if (!conditions.empty()) + { this->_conditionModel->addConditions(conditions); + + for (std::list<CBoundaryCondition*>::iterator it=bc_list.begin(); it!=bc_list.end(); ++it) delete *it; + bc_list.clear(); + for (size_t i=0; i<ic_vector.size(); i++) delete ic_vector[i]; + for (size_t i=0; i<st_vector.size(); i++) delete st_vector[i]; + } } } void MainWindow::writeGeometryToFile(QString gliName, QString fileName) { std::string schemaName(_fileFinder.getPath("OpenGeoSysGLI.xsd")); - XMLInterface xml(_geoModels, schemaName); + XMLInterface xml(&_project, schemaName); xml.writeGLIFile(fileName, gliName); } void MainWindow::writeStationListToFile(QString listName, QString fileName) { std::string schemaName(_fileFinder.getPath("OpenGeoSysSTN.xsd")); - XMLInterface xml(_geoModels, schemaName); + XMLInterface xml(&_project, schemaName); xml.writeSTNFile(fileName, listName); } @@ -958,8 +997,8 @@ void MainWindow::showDiagramPrefsDialog(QModelIndex &index) index, listName); if (stn->type() == GEOLIB::Station::STATION) { - DiagramPrefsDialog* prefs = new DiagramPrefsDialog(stn, listName, _db); - prefs->show(); + DiagramPrefsDialog prefs(stn, listName, _db); + prefs.show(); } if (stn->type() == GEOLIB::Station::BOREHOLE) OGSError::box( "No time series data available for borehole."); @@ -970,7 +1009,7 @@ void MainWindow::showLineEditDialog(const std::string &geoName) LineEditDialog lineEdit(*(_geoModels->getPolylineVecObj(geoName))); connect(&lineEdit, SIGNAL(connectPolylines(const std::string&, std::vector<size_t>, double, std::string, bool, bool)), _geoModels, SLOT(connectPolylineSegments(const std::string&, std::vector<size_t>, double, std::string, bool, bool))); - lineEdit.exec(); + lineEdit.exec(); } void MainWindow::showGMSHPrefsDialog() @@ -982,14 +1021,52 @@ void MainWindow::showGMSHPrefsDialog() dlg.exec(); } -void MainWindow::showVisalizationPrefsDialog() +void MainWindow::showMshQualitySelectionDialog(VtkMeshSource* mshSource) { - VisPrefsDialog dlg(_vtkVisPipeline); + MshQualitySelectionDialog dlg(mshSource); + connect(&dlg, SIGNAL(measureSelected(VtkMeshSource*, MshQualityType::type)), + _vtkVisPipeline, SLOT(checkMeshQuality(VtkMeshSource*, MshQualityType::type))); dlg.exec(); } +void MainWindow::showVisalizationPrefsDialog() +{ + _visPrefsDialog->show(); +} + void MainWindow::FEMTestStart() { + std::vector<std::string> station_names; + _geoModels->getStationNames (station_names); + + size_t resolution (36); + for (std::vector<std::string>::const_iterator it (station_names.begin()); + it != station_names.end(); it++) { + + std::string project_name ("Circle"); + project_name += *it; + + std::vector<GEOLIB::Point*> *pnts (new std::vector<GEOLIB::Point*>); + const std::vector<GEOLIB::Point*>* middle_pnts(_geoModels->getPointVec(*it)); + std::vector<GEOLIB::Polyline*> *plys (new std::vector<GEOLIB::Polyline*>); + std::map<std::string, size_t>* ply_names (new std::map<std::string, size_t>); + + for (size_t k(0); k<middle_pnts->size(); k++) { + GEOLIB::Polygon *polygon(createPolygonFromCircle (*((*middle_pnts)[k]), 450.0, *pnts, resolution)); + plys->push_back (polygon); + std::string station_name ("CircleAreaAroundStation"); + if (dynamic_cast<GEOLIB::Station*>((*middle_pnts)[k])) { + station_name += (dynamic_cast<GEOLIB::Station*>((*middle_pnts)[k])->getName()); + } else { + station_name += number2str (k); + } + ply_names->insert (std::pair<std::string, size_t> (station_name, k)); + } + + _geoModels->addPointVec (pnts, project_name); + _geoModels->addPolylineVec (plys, project_name, ply_names); + } + #ifndef NDEBUG std::cout << "FEM Test here ..." << std::endl; QSettings settings("UFZ", "OpenGeoSys-5"); @@ -1004,38 +1081,44 @@ void MainWindow::FEMTestStart() std::ifstream in (fname.c_str(), std::ios::binary); if (in) { - unsigned n(0), *iA(NULL), *jA(NULL); - double *A(NULL); + long n(0), *iA(NULL), *jA(NULL); + double *A(NULL), *rhs(NULL); std::cout << "reading matrix ... " << std::flush; - // read matrix - FileIO::readCompressedStorageFmt (in, n, iA, jA, A); + // read matrix and right hand side (format provided by WW) + FileIO::readCompressedStorageFmt (in, n, iA, jA, A, rhs); in.close (); std::cout << "done" << std::endl; - // *** ToDo - // read right hand side - // solve system of linear equations - - -// std::cout << "n : " << n << std::endl; -// std::cout << "iA[n]: " << iA[n] << std::endl; -// std::cout << "iA: " << std::endl; -// for (size_t i(0); i<=n; i++) { -// std::cout << " " << iA[i]; -// } -// std::cout << std::endl << "jA: " << std::endl; -// for (size_t i(0); i<iA[n]; i++) { -// std::cout << " " << jA[i]; -// } -// std::cout << std::endl << "A: " << std::endl; -// for (size_t i(0); i<iA[n]; i++) { -// std::cout << " " << A[i]; -// } -// std::cout << std::endl; + unsigned n_unsigned (n); + unsigned *iA_unsigned (new unsigned[n_unsigned+1]); + for (unsigned k(0); k<n_unsigned+1; k++) + iA_unsigned[k] = iA[k]; + + unsigned *jA_unsigned (new unsigned[iA_unsigned[n_unsigned]]); + for (unsigned k(0); k<iA_unsigned[n_unsigned]; k++) + jA_unsigned[k] = jA[k]; + + // write matrix + std::ofstream mat_out ("testmat.bin", std::ios::out|std::ios::binary); + if (mat_out) { + FileIO::writeCompressedStorageFmt (mat_out, n_unsigned, iA_unsigned, jA_unsigned, A); + mat_out.close(); + } + // write right hand side + std::ofstream rhs_out ("rhs.dat"); + if (rhs_out) { + for (unsigned k(0); k<n_unsigned; k++) { + rhs_out << rhs[k] << std::endl; + } + rhs_out.close(); + } delete [] iA; delete [] jA; + delete [] iA_unsigned; + delete [] jA_unsigned; + delete [] rhs; delete [] A; } diff --git a/Gui/mainwindow.h b/Gui/mainwindow.h index e2356d93717ab224fc2fc70f9671c28371c778bb..814d755686202ce0b9836bd04ac46360cddc2978 100644 --- a/Gui/mainwindow.h +++ b/Gui/mainwindow.h @@ -8,6 +8,7 @@ #define MAINWINDOW_H #include "ui_mainwindow.h" +#include "Configure.h" #include "FileFinder.h" #include "ProjectData.h" @@ -17,6 +18,7 @@ class StationTreeModel; class ConditionModel; class VtkVisPipeline; class DatabaseConnection; +class VisPrefsDialog; #ifdef OGS_USE_VRPN class TrackingSettingsWidget; @@ -61,7 +63,9 @@ protected slots: void importGoCad(); void importRaster(); void importRasterAsPoly(); +#ifdef Shapelib_FOUND void importShape(); +#endif void importPetrel(); void importNetcdf(); //YW 07.2010 void importVtk(); @@ -73,6 +77,7 @@ protected slots: void showDiagramPrefsDialog(QModelIndex &index); void showLineEditDialog(const std::string &geoName); void showGMSHPrefsDialog(); + void showMshQualitySelectionDialog(VtkMeshSource* mshSource); void showPropertiesDialog(std::string name); void showVisalizationPrefsDialog(); void showTrackingSettingsDialog(); @@ -114,6 +119,7 @@ private: #ifdef OGS_USE_VRPN TrackingSettingsWidget* _trackingSettingsWidget; #endif // OGS_USE_VRPN + VisPrefsDialog* _visPrefsDialog; signals: void fileUsed( QString filename ); diff --git a/Gui/mainwindow.ui b/Gui/mainwindow.ui index cf76bc549247e2a4e2f1025d57ba107458d17eff..675135369f176e0a1c57be13e299799cca5c3dda 100644 --- a/Gui/mainwindow.ui +++ b/Gui/mainwindow.ui @@ -81,7 +81,7 @@ <x>0</x> <y>0</y> <width>801</width> - <height>21</height> + <height>22</height> </rect> </property> <widget class="QMenu" name="menu_File"> @@ -89,6 +89,9 @@ <string>&File</string> </property> <widget class="QMenu" name="menuExport"> + <property name="toolTip"> + <string>Exports the entire scene to a 3d-format for visualization.</string> + </property> <property name="title"> <string>Export</string> </property> @@ -233,11 +236,17 @@ <property name="text"> <string>&Open...</string> </property> + <property name="toolTip"> + <string>Loads a OGS-native file. E.g. gli, gsp, gml, msh, stn.</string> + </property> </action> <action name="action_Exit"> <property name="text"> <string>&Exit</string> </property> + <property name="toolTip"> + <string>Exits the application.</string> + </property> </action> <action name="actionPoints_view"> <property name="checkable"> @@ -287,11 +296,17 @@ <property name="text"> <string>Database...</string> </property> + <property name="toolTip"> + <string>Connects to a database.</string> + </property> </action> <action name="action_DatabaseConnection"> <property name="text"> <string>Database Settings...</string> </property> + <property name="toolTip"> + <string>Sets the database settings.</string> + </property> </action> <action name="actionImport"> <property name="text"> @@ -320,6 +335,9 @@ <property name="text"> <string>Visualisation Settings...</string> </property> + <property name="toolTip"> + <string>Sets settings regarding the 3d view. E.g. Background color, illumantion.</string> + </property> </action> <action name="actionExportVTK"> <property name="text"> @@ -338,11 +356,17 @@ <property name="text"> <string>Tracking Settings...</string> </property> + <property name="toolTip"> + <string>Sets settings for head-tracking.</string> + </property> </action> <action name="actionMesh_Generation"> <property name="text"> <string>Mesh Generation...</string> </property> + <property name="toolTip"> + <string>Generates a mesh from a geometry.</string> + </property> </action> <action name="actionFEM_Test"> <property name="text"> diff --git a/OpenSG/OsgWidget.cpp b/OpenSG/OsgWidget.cpp index 8b8f2ef05de2942d329483cd10a96d21db04dd6c..faa7ce616debbd4b99e59ce02d6429e8ccf2e8a1 100644 --- a/OpenSG/OsgWidget.cpp +++ b/OpenSG/OsgWidget.cpp @@ -11,6 +11,7 @@ OsgWidget::OsgWidget (QWidget * parent, const QGLWidget *shareWidget, Qt::WindowFlags f) :QGLWidget(parent, shareWidget, f) { + _timer = NULL; _passiveWin = OSG::PassiveWindow::create(); _mgr = new OSG::SimpleSceneManager(); _mgr->setWindow(_passiveWin); @@ -19,6 +20,7 @@ OsgWidget::OsgWidget (QWidget * parent, const QGLWidget *shareWidget, Qt::Window OsgWidget::OsgWidget (QGLContext *context, QWidget *parent, const QGLWidget *shareWidget, Qt::WindowFlags f) :QGLWidget(context, parent, shareWidget, f) { + _timer = NULL; _passiveWin = OSG::PassiveWindow::create(); _mgr = new OSG::SimpleSceneManager(); _mgr->setWindow(_passiveWin); @@ -27,6 +29,7 @@ OsgWidget::OsgWidget (QGLContext *context, QWidget *parent, const QGLWidget *sha OsgWidget::OsgWidget (const QGLFormat &format, QWidget *parent, const QGLWidget *shareWidget, Qt::WindowFlags f) :QGLWidget(format, parent, shareWidget, f) { + _timer = NULL; _passiveWin = OSG::PassiveWindow::create(); _mgr = new OSG::SimpleSceneManager(); _mgr->setWindow(_passiveWin); diff --git a/OpenSG/vtkOsgActor.cpp b/OpenSG/vtkOsgActor.cpp index 346e42ef22f0db9551e69b28008d811f64f63759..a6740368311e147ac5589662f325d058b6c81ca0 100644 --- a/OpenSG/vtkOsgActor.cpp +++ b/OpenSG/vtkOsgActor.cpp @@ -780,12 +780,12 @@ NodePtr vtkOsgActor::ProcessGeometryNonIndexedCopyAttributes(int gl_primitive_ty beginEditCP(m_posgColors); beginEditCP(m_posgNormals);{ int prim = 0; - vtkIdType npts, *pts, i; if (pCells->GetNumberOfCells() > 0){ + vtkIdType npts, *pts; for (pCells->InitTraversal(); pCells->GetNextCell(npts, pts); prim++){ m_posgLengths->addValue(npts); m_posgTypes->addValue(GL_POLYGON); - for (i=0; i<npts; i++){ + for (int i=0; i<npts; i++){ double *aVertex; double *aNormal; unsigned char aColor[4]; diff --git a/Vrpn/QVrpnArtTrackingClient.cpp b/Vrpn/QVrpnArtTrackingClient.cpp index cadb732ff7de5a72d3a2460c73c9383d245b01a4..30c3a351617b62999f26129c803b6adc8eb4cfe0 100644 --- a/Vrpn/QVrpnArtTrackingClient.cpp +++ b/Vrpn/QVrpnArtTrackingClient.cpp @@ -34,6 +34,8 @@ QVrpnArtTrackingClient::~QVrpnArtTrackingClient() settings.setValue("artDeviceNameAt", list.at(1)); settings.setValue("artUpdateInterval", _updateInterval); settings.endGroup(); + + delete _timer; } QVrpnArtTrackingClient* QVrpnArtTrackingClient::Instance(QObject* parent /*= NULL*/) diff --git a/Vrpn/SpaceNavigatorClient.cpp b/Vrpn/SpaceNavigatorClient.cpp index 3b1586d2b5239555c0506b2d2b168bac5ef906e4..71217cfcfa36acd1556cdd8fcf64b487f3414dee 100644 --- a/Vrpn/SpaceNavigatorClient.cpp +++ b/Vrpn/SpaceNavigatorClient.cpp @@ -15,6 +15,9 @@ SpaceNavigatorClient::SpaceNavigatorClient() _button = NULL; _analog = NULL; _unconsumedData = false; + _frameRotationFactor = 0.0; + _frameTranslationFactor = 0.0; + _upAxis = Y; // set all fields to start values _spacenavigator = this; @@ -77,14 +80,14 @@ void SpaceNavigatorClient::init( const char *deviceName, SpaceNavigatorAxes axis _upAxis = Y; } -void SpaceNavigatorClient::getTranslation(double& retx, double& rety, double& retz) +void SpaceNavigatorClient::getTranslation(double& retx, double& rety, double& retz) const { retx = x * _frameTranslationFactor; rety = y * _frameTranslationFactor; retz = z * _frameTranslationFactor; } -void SpaceNavigatorClient::getRotation(double& retx, double& rety, double& retz) +void SpaceNavigatorClient::getRotation(double& retx, double& rety, double& retz) const { retx = rx * _frameTranslationFactor; rety = ry * _frameTranslationFactor; diff --git a/Vrpn/SpaceNavigatorClient.h b/Vrpn/SpaceNavigatorClient.h index a27dc727e571bb7b391f297c9c1a786e3253f06e..f322496d696b61f1f2b03cd8ce66f587a5d84f62 100644 --- a/Vrpn/SpaceNavigatorClient.h +++ b/Vrpn/SpaceNavigatorClient.h @@ -60,10 +60,10 @@ public: void init(const char *deviceName, SpaceNavigatorAxes axis = Y); /// @brief Returns the translation values. - void getTranslation(double& retx, double& rety, double& retz); + void getTranslation(double& retx, double& rety, double& retz) const; /// @brief Returns the rotation values - void getRotation(double& retx, double& rety, double& retz); + void getRotation(double& retx, double& rety, double& retz) const; /// @brief Updates the translation and rotation values. /// Must be called once per frame before getTranslation/Rotation. diff --git a/Vrpn/VrpnArtTrackingClient.cpp b/Vrpn/VrpnArtTrackingClient.cpp index ab189de90969a65bb6ed2bbe05fcb302ef453a16..259d9e6c6cce4dfdff08f18e6be950fa6a1ce1b3 100644 --- a/Vrpn/VrpnArtTrackingClient.cpp +++ b/Vrpn/VrpnArtTrackingClient.cpp @@ -190,7 +190,6 @@ bool VrpnArtTrackingClient::GetButtonData(int index) void VRPN_CALLBACK VrpnArtTrackingClient::CBHandleTracker(void *userdata, const vrpn_TRACKERCB t) { - int i; (void)userdata; VrpnArtTrackingClient *art = m_pInstance; @@ -199,12 +198,12 @@ void VRPN_CALLBACK VrpnArtTrackingClient::CBHandleTracker(void *userdata, const if (t.sensor == 0) { //std::cout << "CBHandleTracker" << std::endl; - for (i=0; i<3; i++) + for (int i=0; i<3; i++) { art->m_dBodyTranslation[i] = t.pos[i]; //std::cout << t.pos[i] << std::endl; } - for (i=0; i<4; i++) + for (int i=0; i<4; i++) { art->m_dBodyQuaternion[i] = t.quat[i]; //std::cout << t.quat[i] << std::endl; @@ -212,9 +211,9 @@ void VRPN_CALLBACK VrpnArtTrackingClient::CBHandleTracker(void *userdata, const } else if (t.sensor == 1) { - for (i=0; i<3; i++) + for (int i=0; i<3; i++) art->m_dFlyTranslation[i] = t.pos[i]; - for (i=0; i<4; i++) + for (int i=0; i<4; i++) art->m_dFlyQuaternion[i] = t.quat[i]; } } diff --git a/Vrpn/VrpnArtTrackingClient.h b/Vrpn/VrpnArtTrackingClient.h index 8afc23ab7b6c5c41e838a42b63e6d3aca667734f..212c521420bdf1b43bdd3e7878d36bd9e620452b 100644 --- a/Vrpn/VrpnArtTrackingClient.h +++ b/Vrpn/VrpnArtTrackingClient.h @@ -21,7 +21,7 @@ public: void StopTracking(); /// @brief Returns true if tracking is started - bool IsStarted(){return m_bTrackingStarted;} + bool IsStarted() const {return m_bTrackingStarted;} /// @brief Calls the vrpn mainloop functions. Must be called once per frame. void MainLoop(); diff --git a/VtkAct/VtkCustomInteractorStyle.cpp b/VtkAct/VtkCustomInteractorStyle.cpp index 1b127e6f83841709f3ddcd0f8e3898d3b10ba9f4..268dee572ddd97d1e87fbc46db6ed1f66111f23f 100644 --- a/VtkAct/VtkCustomInteractorStyle.cpp +++ b/VtkAct/VtkCustomInteractorStyle.cpp @@ -11,15 +11,40 @@ #include <vtkRenderWindowInteractor.h> #include <vtkObjectFactory.h> #include <vtkProp.h> +#include <vtkSmartPointer.h> +#include <vtkDataSetMapper.h> +#include <vtkActor.h> +#include <vtkCellPicker.h> +#include <vtkSelection.h> +#include <vtkSelectionNode.h> +#include <vtkExtractSelection.h> +#include <vtkIdTypeArray.h> +#include <vtkUnstructuredGrid.h> +#include <vtkProperty.h> +#include <vtkRenderWindow.h> +#include <vtkRendererCollection.h> +#include <vtkCamera.h> #include <string> vtkStandardNewMacro(VtkCustomInteractorStyle); VtkCustomInteractorStyle::VtkCustomInteractorStyle() -: _highlightActor(true) +: _highlightActor(true), _alternateMouseActions(false) { + selectedMapper = vtkDataSetMapper::New(); + selectedActor = vtkActor::New(); + selectedActor->SetMapper(selectedMapper); + selectedActor->GetProperty()->EdgeVisibilityOn(); + selectedActor->GetProperty()->SetEdgeColor(1,0,0); + selectedActor->GetProperty()->SetLineWidth(3); + Data = NULL; +} +VtkCustomInteractorStyle::~VtkCustomInteractorStyle() +{ + selectedActor->Delete(); + selectedMapper->Delete(); } void VtkCustomInteractorStyle::OnChar() @@ -36,6 +61,32 @@ void VtkCustomInteractorStyle::OnChar() } } +void VtkCustomInteractorStyle::OnKeyDown() +{ + switch (Interactor->GetKeyCode()) + { + case 32: // Space + _alternateMouseActions = true; + emit cursorChanged(Qt::CrossCursor); + break; + default: + vtkInteractorStyleTrackballCamera::OnKeyDown(); + } +} + +void VtkCustomInteractorStyle::OnKeyUp() +{ + switch (Interactor->GetKeyCode()) + { + case 32: // Space + _alternateMouseActions = false; + emit cursorChanged(Qt::ArrowCursor); + break; + default: + vtkInteractorStyleTrackballCamera::OnKeyUp(); + } +} + void VtkCustomInteractorStyle::highlightActor( vtkProp3D* actor ) { if (_highlightActor) @@ -48,3 +99,116 @@ void VtkCustomInteractorStyle::setHighlightActor(bool on) if (!on) HighlightProp((vtkProp*)NULL); } + +void VtkCustomInteractorStyle::pickableDataObject(vtkDataObject* object) +{ + Data = object; + if (!object) + { + this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->RemoveActor(selectedActor); + selectedMapper->SetInputConnection(NULL); + } +} + +// From http://www.vtk.org/Wiki/VTK/Examples/Cxx/Picking/CellPicking +void VtkCustomInteractorStyle::OnLeftButtonDown() +{ + if (!Data) + return vtkInteractorStyleTrackballCamera::OnLeftButtonDown(); + + if (_alternateMouseActions) + { + // Get the location of the click (in window coordinates) + int* pos = this->GetInteractor()->GetEventPosition(); + + vtkSmartPointer<vtkCellPicker> picker = + vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.0005); + + // Pick from this location. + picker->Pick(pos[0], pos[1], 0, this->GetDefaultRenderer()); + + double* worldPosition = picker->GetPickPosition(); + std::cout << "Cell id is: " << picker->GetCellId() << std::endl; + + if(picker->GetCellId() != -1) + { + + std::cout << "Pick position is: " << worldPosition[0] << " " << worldPosition[1] + << " " << worldPosition[2] << endl; + + vtkSmartPointer<vtkIdTypeArray> ids = + vtkSmartPointer<vtkIdTypeArray>::New(); + ids->SetNumberOfComponents(1); + ids->InsertNextValue(picker->GetCellId()); + + vtkSmartPointer<vtkSelectionNode> selectionNode = + vtkSmartPointer<vtkSelectionNode>::New(); + selectionNode->SetFieldType(vtkSelectionNode::CELL); + selectionNode->SetContentType(vtkSelectionNode::INDICES); + selectionNode->SetSelectionList(ids); + + vtkSmartPointer<vtkSelection> selection = + vtkSmartPointer<vtkSelection>::New(); + selection->AddNode(selectionNode); + + vtkSmartPointer<vtkExtractSelection> extractSelection = + vtkSmartPointer<vtkExtractSelection>::New(); + extractSelection->SetInput(0, this->Data); + extractSelection->SetInput(1, selection); + extractSelection->Update(); + + // In selection + vtkSmartPointer<vtkUnstructuredGrid> selected = + vtkSmartPointer<vtkUnstructuredGrid>::New(); + selected->ShallowCopy(extractSelection->GetOutput()); + + std::cout << "There are " << selected->GetNumberOfPoints() + << " points in the selection." << std::endl; + std::cout << "There are " << selected->GetNumberOfCells() + << " cells in the selection." << std::endl; + + + selectedMapper->SetInputConnection(selected->GetProducerPort()); + + this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(selectedActor); + emit requestViewUpdate(); + } + } + else + // Forward events + vtkInteractorStyleTrackballCamera::OnLeftButtonDown(); +} + +void VtkCustomInteractorStyle::OnRightButtonDown() +{ + if (!Data) + return vtkInteractorStyleTrackballCamera::OnRightButtonDown(); + + if (_alternateMouseActions) + { + // Get the location of the click (in window coordinates) + int* pos = this->GetInteractor()->GetEventPosition(); + + vtkSmartPointer<vtkCellPicker> picker = + vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.0005); + + // Pick from this location. + picker->Pick(pos[0], pos[1], 0, this->GetDefaultRenderer()); + + double* worldPosition = picker->GetPickPosition(); + std::cout << "Cell id is: " << picker->GetCellId() << std::endl; + + if(picker->GetCellId() != -1) + { + vtkRenderer* renderer = this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer(); + vtkCamera* cam = renderer->GetActiveCamera(); + cam->SetFocalPoint(worldPosition); + emit requestViewUpdate(); + } + } + else + // Forward events + vtkInteractorStyleTrackballCamera::OnRightButtonDown(); +} diff --git a/VtkAct/VtkCustomInteractorStyle.h b/VtkAct/VtkCustomInteractorStyle.h index eaab31f84801976d3a51f552e32dca8a99a745eb..60ba5c8915ccdacecdc56008edaf09ea18cd8d32 100644 --- a/VtkAct/VtkCustomInteractorStyle.h +++ b/VtkAct/VtkCustomInteractorStyle.h @@ -13,8 +13,16 @@ #include <vtkInteractorStyleTrackballCamera.h> +class vtkDataObject; +class vtkDataSetMapper; +class vtkActor; + /** - * VtkCustomInteractorStyle is sub classed from vtkInteractorStyleTrackballCamera. + * VtkCustomInteractorStyle implements highlighting of an active actor and + * highlighting of picked cells inside a vtk object. + * Picking occurs when a vtk object was selected, the alternate mouse mode is + * active (hold spacebar) and the user left clicks. On right click the cameras + * focal point (center of rotation) is set to the picking position. */ class VtkCustomInteractorStyle : public QObject, public vtkInteractorStyleTrackballCamera { @@ -24,20 +32,53 @@ public: static VtkCustomInteractorStyle* New(); vtkTypeMacro (VtkCustomInteractorStyle, vtkInteractorStyleTrackballCamera); - /// Handles key press events. + /// @biref Handles key press events. virtual void OnChar(); + /// @biref Handles key down events. + virtual void OnKeyDown(); + + /// @biref Handles key up events. + virtual void OnKeyUp(); + + /// @brief Handles left mouse button events (picking). + virtual void OnLeftButtonDown(); + + /// @brief Handles middle mouse button events (rotation point picking). + virtual void OnRightButtonDown(); + public slots: void highlightActor(vtkProp3D* prop); - void setHighlightActor(bool on); + + /// @brief Sets the highlightable vtk object. + void pickableDataObject(vtkDataObject* object); protected: VtkCustomInteractorStyle(); + virtual ~VtkCustomInteractorStyle(); + + /// @brief The vtk object to pick. + vtkDataObject* Data; + + /// @brief The mapper for highlighting the selected cell. + vtkDataSetMapper* selectedMapper; + + /// @brief The actor for highlighting the selected cell. + vtkActor* selectedActor; private: bool _highlightActor; + bool _alternateMouseActions; + +signals: + /// @brief Emitted when something was picked. + void requestViewUpdate(); + + /// @brief Emitted when the cursor shape was changed due to alternate + /// mouse action mode. + void cursorChanged(Qt::CursorShape); }; diff --git a/VtkVis/CMakeLists.txt b/VtkVis/CMakeLists.txt index 4b11b51294bdd511b439c6e1ab8eb3587d260032..e5ff90a49b099c27a8f2313781b36c45fff30d3d 100644 --- a/VtkVis/CMakeLists.txt +++ b/VtkVis/CMakeLists.txt @@ -19,6 +19,7 @@ SET( SOURCES VtkCompositeSelectionFilter.cpp VtkCompositeTextureOnSurfaceFilter.cpp VtkCompositeThresholdFilter.cpp + VtkConditionSource.cpp VtkFilterFactory.cpp VtkGeoImageSource.cpp VtkImageDataToLinePolyDataFilter.cpp @@ -35,6 +36,8 @@ SET( SOURCES VtkVisPipelineView.cpp VtkVisTabWidget.cpp VtkVisHelper.cpp + VisualizationWidget.cpp + VisPrefsDialog.cpp ) # Moc headers @@ -49,6 +52,8 @@ SET( MOC_HEADERS VtkVisPipeline.h VtkVisPipelineView.h VtkVisTabWidget.h + VisualizationWidget.h + VisPrefsDialog.h ) # Header files @@ -67,6 +72,7 @@ SET( HEADERS VtkCompositeSelectionFilter.h VtkCompositeTextureOnSurfaceFilter.h VtkCompositeThresholdFilter.h + VtkConditionSource.h VtkFilterFactory.h VtkGeoImageSource.h VtkImageDataToLinePolyDataFilter.h @@ -85,6 +91,8 @@ SET( HEADERS SET ( UIS VtkAddFilterDialogBase.ui VtkVisTabWidgetBase.ui + VisualizationWidgetBase.ui + VisPrefs.ui ) # Put moc files in a project folder @@ -107,11 +115,13 @@ QT4_WRAP_CPP( MOC_SOURCES ${MOC_HEADERS} ) INCLUDE_DIRECTORIES( . + ../VtkAct ${CMAKE_BINARY_DIR}/Qt/VtkVis ../../Base ../../FEM ../../GEO ../../MathLib + ../../FileIO ../../MSH ../Base ../DataView @@ -126,7 +136,7 @@ ADD_LIBRARY( VtkVis STATIC ${UIS} ) -TARGET_LINK_LIBRARIES( VtkVis ${QT_LIBRARIES} ) +TARGET_LINK_LIBRARIES( VtkVis ${QT_LIBRARIES} QVTK ) IF (OGS_USE_OPENSG) USE_OPENSG(VtkVis) diff --git a/VtkVis/GridAdapter.cpp b/VtkVis/GridAdapter.cpp index 700b09c7bb69101f137187b83dab64462ce52c44..79e1bc88f31e31c75086287c3bcb38e0cb401e1f 100644 --- a/VtkVis/GridAdapter.cpp +++ b/VtkVis/GridAdapter.cpp @@ -21,6 +21,7 @@ // Conversion from vtkUnstructuredGrid #include <vtkUnstructuredGrid.h> #include <vtkCell.h> +#include <vtkCellData.h> using Mesh_Group::CFEMesh; @@ -52,18 +53,18 @@ GridAdapter::~GridAdapter() int GridAdapter::convertCFEMesh(const Mesh_Group::CFEMesh* mesh) { if (!mesh) return 0; - Element* newElem = NULL; - size_t nElemNodes = 0; - - size_t nElems = mesh->ele_vector.size(); + size_t nNodes = mesh->nod_vector.size(); - for (size_t i=0; i<nNodes; i++) { GEOLIB::Point* pnt = new GEOLIB::Point(mesh->nod_vector[i]->X(), mesh->nod_vector[i]->Y(), mesh->nod_vector[i]->Z()); _nodes->push_back(pnt); } + Element* newElem = NULL; + size_t nElems = mesh->ele_vector.size(); + size_t nElemNodes = 0; + for (size_t i=0; i<nElems; i++) { newElem = new Element(); @@ -356,9 +357,10 @@ Mesh_Group::CFEMesh* GridAdapter::convertUnstructuredGrid(vtkUnstructuredGrid* g Mesh_Group::CNode* node(new Mesh_Group::CNode(i, coords[0], coords[1], coords[2])); mesh->nod_vector.push_back(node); } - + // set mesh elements vtkCell* cell(NULL); + vtkDataArray* scalars = grid->GetCellData()->GetScalars("MaterialIDs"); for (size_t i=0; i<nElems; i++) { Mesh_Group::CElem* elem(new Mesh_Group::CElem()); @@ -376,15 +378,16 @@ Mesh_Group::CFEMesh* GridAdapter::convertUnstructuredGrid(vtkUnstructuredGrid* g } if (elem_type != MshElemType::INVALID) + { elem->SetElementType(elem_type); + if (scalars) elem->SetPatchIndex(static_cast<int>(scalars->GetComponent(i,0))); // HACK the name of the correct scalar array of the vtk file should probably be passed as an argument?! + } else { std::cout << "Error in GridAdapter::convertUnstructuredGrid() - Unknown mesh element type ..." << std::endl; return NULL; } - elem->SetPatchIndex(0); // HACK the name of the correct scalar array of the vtk file should probably be passed as an argument?! - cell = grid->GetCell(i); size_t nElemNodes = cell->GetNumberOfPoints(); elem->SetNodesNumber(nElemNodes); diff --git a/VtkVis/VisPrefs.ui b/VtkVis/VisPrefs.ui new file mode 100644 index 0000000000000000000000000000000000000000..10601129dcfbd8dd9eab04d002c6abd576b2ad30 --- /dev/null +++ b/VtkVis/VisPrefs.ui @@ -0,0 +1,148 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>VisPrefsDialog</class> + <widget class="QDialog" name="VisPrefsDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>188</width> + <height>296</height> + </rect> + </property> + <property name="windowTitle"> + <string>Visualisation Settings</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QGroupBox" name="LightBox"> + <property name="title"> + <string>Additional Illumination</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QCheckBox" name="lightAboveBox"> + <property name="text"> + <string>Light from above</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="lightBelowBox"> + <property name="text"> + <string>Light from below</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="ColorBox"> + <property name="title"> + <string>Background Colour</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="ColorPickerPushButton" name="bgColorButton"> + <property name="text"> + <string>(255,255,255)</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="SuperelevationBox"> + <property name="title"> + <string>Superelevation</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLineEdit" name="superelevationLineEdit"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Specify the superelevation factor. Click on the button to apply.</string> + </property> + <property name="text"> + <string>1</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="superelevationPushButton"> + <property name="text"> + <string>Apply</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="ViewUpdateBox"> + <property name="title"> + <string>View Update</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QCheckBox" name="loadShowAllCheckBox"> + <property name="toolTip"> + <string>Resizes view to show the entire scene when loading new data.</string> + </property> + <property name="text"> + <string>Reset view on load</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QPushButton" name="closePushButton"> + <property name="text"> + <string>Close</string> + </property> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>ColorPickerPushButton</class> + <extends>QPushButton</extends> + <header>ColorPickerPushButton.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections> + <connection> + <sender>closePushButton</sender> + <signal>clicked()</signal> + <receiver>VisPrefsDialog</receiver> + <slot>close()</slot> + <hints> + <hint type="sourcelabel"> + <x>93</x> + <y>275</y> + </hint> + <hint type="destinationlabel"> + <x>93</x> + <y>147</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/VtkVis/VisPrefsDialog.cpp b/VtkVis/VisPrefsDialog.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5ddefd228692c3001b7de6aa6046718531ae2a24 --- /dev/null +++ b/VtkVis/VisPrefsDialog.cpp @@ -0,0 +1,69 @@ +/** + * \file VisPrefsDialog.cpp + * 14/06/2010 KR Initial implementation + */ + +#include <QSettings> +#include <QDoubleValidator> +#include <QLineEdit> +#include <QVariant> +#include "VisPrefsDialog.h" + +#include "VtkVisPipeline.h" +#include "VisualizationWidget.h" + +/// Constructor +VisPrefsDialog::VisPrefsDialog(VtkVisPipeline* pipeline, VisualizationWidget* widget, QDialog* parent) : + QDialog(parent), _vtkVisPipeline(pipeline), _visWidget(widget), _above(0,0,2000000), _below(0,0,-2000000) +{ + setupUi(this); + if (_vtkVisPipeline->getLight(_above)) + lightAboveBox->toggle(); + if (_vtkVisPipeline->getLight(_below)) + lightBelowBox->toggle(); + + QColor color = _vtkVisPipeline->getBGColor(); + bgColorButton->setColor(_vtkVisPipeline->getBGColor()); + + QValidator* validator = new QDoubleValidator(0, 100000, 2, this); + superelevationLineEdit->setValidator(validator); + QSettings settings("UFZ, OpenGeoSys-5"); + superelevationLineEdit->setText(settings.value("globalSuperelevation", 1.0).toString()); +} + +void VisPrefsDialog::on_bgColorButton_colorPicked( QColor color ) +{ + QColor bgColor(color.red(), color.green(), color.blue()); + _vtkVisPipeline->setBGColor(bgColor); +} + +void VisPrefsDialog::on_lightAboveBox_clicked() +{ + if (lightAboveBox->isChecked()) + _vtkVisPipeline->addLight(_above); + else + _vtkVisPipeline->removeLight(_above); +} + +void VisPrefsDialog::on_lightBelowBox_clicked() +{ + if (lightBelowBox->isChecked()) + _vtkVisPipeline->addLight(_below); + else + _vtkVisPipeline->removeLight(_below); +} + +void VisPrefsDialog::on_superelevationPushButton_pressed() +{ + double factor = superelevationLineEdit->text().toDouble(); + _vtkVisPipeline->setGlobalSuperelevation(factor); + + QSettings settings("UFZ, OpenGeoSys-5"); + settings.setValue("globalSuperelevation", factor); +} + +void VisPrefsDialog::on_loadShowAllCheckBox_stateChanged(int state) +{ + _visWidget->setShowAllOnLoad((bool)state); + _vtkVisPipeline->resetCameraOnAddOrRemove((bool)state); +} diff --git a/DataView/VisPrefsDialog.h b/VtkVis/VisPrefsDialog.h similarity index 65% rename from DataView/VisPrefsDialog.h rename to VtkVis/VisPrefsDialog.h index dcfd6ca1220412ea6deed661755578a9d9c6bcdd..3f82be69710094c40a79d44d66c446877b24e2ca 100644 --- a/DataView/VisPrefsDialog.h +++ b/VtkVis/VisPrefsDialog.h @@ -6,11 +6,12 @@ #ifndef VISPREFSDIALOG_H #define VISPREFSDIALOG_H -#include <QtGui/QMainWindow> +#include <QDialog> #include "ui_VisPrefs.h" #include "Point.h" class VtkVisPipeline; +class VisualizationWidget; /** * \brief A dialog window for settung up a visualisation preferences @@ -20,13 +21,9 @@ class VisPrefsDialog : public QDialog, private Ui_VisPrefsDialog Q_OBJECT public: - VisPrefsDialog(VtkVisPipeline* pipeline, QDialog* parent = 0); - ~VisPrefsDialog(void); + VisPrefsDialog(VtkVisPipeline* pipeline, VisualizationWidget* widget, QDialog* parent = NULL); - - - -private slots: +protected slots: /// Sets the background colour. void on_bgColorButton_colorPicked(QColor color); @@ -36,14 +33,15 @@ private slots: /// Adds a light below the scene. void on_lightBelowBox_clicked(); - /// Instructions if the OK-Button has been pressed. - void accept(); + /// Sets the given superelevation on all vis pipeline source objects + void on_superelevationPushButton_pressed(); - /// Instructions if the Cancel-Button has been pressed. - void reject(); + /// + void on_loadShowAllCheckBox_stateChanged(int state); private: VtkVisPipeline* _vtkVisPipeline; + VisualizationWidget* _visWidget; GEOLIB::Point _above; GEOLIB::Point _below; diff --git a/DataView/VisualizationWidget.cpp b/VtkVis/VisualizationWidget.cpp similarity index 71% rename from DataView/VisualizationWidget.cpp rename to VtkVis/VisualizationWidget.cpp index c63d94a7fea52ae6d07af6c3621013d818fa3187..041da82ad19ba30bc7edfdb2c39610bf4b9f3f3b 100644 --- a/DataView/VisualizationWidget.cpp +++ b/VtkVis/VisualizationWidget.cpp @@ -25,8 +25,18 @@ #include <vtkCommand.h> #include <vtkAxesActor.h> #include <vtkOrientationMarkerWidget.h> +#include <vtkPNGWriter.h> +#include <vtkWindowToImageFilter.h> +#include <vtkSmartPointer.h> #include <QSettings> +#include <QFileDialog> +#include <QLineEdit> +#include <QString> +#include <QInputDialog> +#include <QSettings> +#include <QDir> +#include <QCursor> #ifdef OGS_USE_VRPN #include "QSpaceNavigatorClient.h" @@ -56,6 +66,7 @@ VisualizationWidget::VisualizationWidget( QWidget* parent /*= 0*/ ) renderWindow->SetStereoTypeToCrystalEyes(); _vtkRender = vtkRenderer::New(); renderWindow->AddRenderer(_vtkRender); + _interactorStyle->SetDefaultRenderer(_vtkRender); #endif // OGS_VRED_PLUGIN QSettings settings("UFZ", "OpenGeoSys-5"); @@ -79,16 +90,19 @@ VisualizationWidget::VisualizationWidget( QWidget* parent /*= 0*/ ) QString deviceName = settings.value("Tracking/artDeviceName").toString(); QString deviceNameAt = settings.value("Tracking/artDeviceNameAt").toString(); art->StartTracking(QString(deviceName + "@" + deviceNameAt).toStdString().c_str(), - settings.value("Tracking/artUpdateInterval").toInt()); + settings.value("Tracking/artUpdateInterval").toInt()); } else art->StartTracking("DTrack@141.65.34.36"); - connect( art, SIGNAL(positionUpdated(double, double, double)), cam, SLOT(setTrackingData(double, double, double)) ); + connect( art, SIGNAL(positionUpdated(double, double, double)), + cam, SLOT(setTrackingData(double, double, double)) ); // Connect the vtk event to the qt slot _qtConnect = vtkEventQtSlotConnect::New(); - _qtConnect->Connect(vtkWidget->GetRenderWindow()->GetInteractor(), vtkCommand::EndInteractionEvent, - cam, SLOT(updatedFromOutside())); + _qtConnect->Connect(vtkWidget->GetRenderWindow()->GetInteractor(), + vtkCommand::EndInteractionEvent, + cam, + SLOT(updatedFromOutside())); #endif // OGS_USE_VRPN @@ -100,13 +114,13 @@ VisualizationWidget::VisualizationWidget( QWidget* parent /*= 0*/ ) // cam->SetEyeAngle(settings.value("stereoEyeAngle").toDouble()); //else // cam->SetEyeAngle(2.0); - +/* if (!stereoToolButton->isChecked()) { eyeAngleLabel->setEnabled(false); eyeAngleSlider->setEnabled(false); } - +*/ //eyeAngleSlider->setValue((int)(_vtkRender->GetActiveCamera()->GetEyeAngle() * 10)); // Create an orientation marker using vtkAxesActor @@ -117,6 +131,12 @@ VisualizationWidget::VisualizationWidget( QWidget* parent /*= 0*/ ) markerWidget->SetInteractor(vtkWidget->GetRenderWindow()->GetInteractor()); markerWidget->EnabledOn(); markerWidget->InteractiveOff(); + + _isShowAllOnLoad = true; + + // Set alternate cursor shapes + connect(_interactorStyle, SIGNAL(cursorChanged(Qt::CursorShape)), + this, SLOT(setCursorShape(Qt::CursorShape))); } VisualizationWidget::~VisualizationWidget() @@ -141,18 +161,7 @@ VtkPickCallback* VisualizationWidget::vtkPickCallback() const return _vtkPickCallback; } void VisualizationWidget::updateView() -{ - /* - vtkCamera* camera = _vtkRender->GetActiveCamera(); - double x,y,z; - camera->GetFocalPoint(x, y, z); - std::cout << "Focal point: " << x << " " << y << " " << z << std::endl; - camera->GetPosition(x, y, z); - std::cout << "Position: " << x << " " << y << " " << z << std::endl; - camera->GetClippingRange(x, y); - std::cout << "Clipping range: " << x << " " << y << std::endl << std::endl; - */ - +{ vtkWidget->GetRenderWindow()->Render(); } @@ -168,31 +177,39 @@ void VisualizationWidget::showAll() this->updateView(); } +void VisualizationWidget::updateViewOnLoad() +{ + if (_isShowAllOnLoad) + this->showAll(); + else + updateView(); +} + void VisualizationWidget::on_stereoToolButton_toggled( bool checked ) { if (checked) { vtkWidget->GetRenderWindow()->StereoRenderOn(); - eyeAngleLabel->setEnabled(true); - eyeAngleSlider->setEnabled(true); + //eyeAngleLabel->setEnabled(true); + //eyeAngleSlider->setEnabled(true); } else { vtkWidget->GetRenderWindow()->StereoRenderOff(); - eyeAngleLabel->setEnabled(false); - eyeAngleSlider->setEnabled(false); + //eyeAngleLabel->setEnabled(false); + //eyeAngleSlider->setEnabled(false); } this->updateView(); } - +/* void VisualizationWidget::on_eyeAngleSlider_valueChanged( int value ) { Q_UNUSED(value); //_vtkRender->GetActiveCamera()->SetEyeAngle(value / 10.0); //updateView(); } - +*/ void VisualizationWidget::on_zoomToolButton_toggled( bool checked ) { if (checked) @@ -228,3 +245,48 @@ void VisualizationWidget::on_orthogonalProjectionToolButton_toggled( bool checke _vtkRender->GetActiveCamera()->SetParallelProjection(checked); this->updateView(); } + +void VisualizationWidget::on_screenshotPushButton_pressed() +{ + QSettings settings("UFZ", "OpenGeoSys-5"); + QString filename = QFileDialog::getSaveFileName(this, tr("Save screenshot"), + settings.value("lastScreenshotDir").toString(), "PNG file (*.png)"); + if (filename.count() > 4) + { + bool ok; + int magnification = QInputDialog::getInt(this, tr("Screenshot magnification"), + tr("Enter a magnification factor for the resulting image."), + 2, 1, 10, 1, &ok); + if (ok) + { + QDir dir(filename); + settings.setValue("lastScreenshotDir", dir.absolutePath()); + this->screenshot(filename, magnification); + } + } +} + +void VisualizationWidget::screenshot(QString filename, int magnification) +{ + vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter = + vtkSmartPointer<vtkWindowToImageFilter>::New(); + windowToImageFilter->SetInput(vtkWidget->GetRenderWindow()); + // Set the resolution of the output image + // magnification times the current resolution of vtk render window + windowToImageFilter->SetMagnification(magnification); + // Also record the alpha (transparency) channel + windowToImageFilter->SetInputBufferTypeToRGBA(); + windowToImageFilter->Update(); + + vtkSmartPointer<vtkPNGWriter> writer = vtkSmartPointer<vtkPNGWriter>::New(); + writer->SetFileName(filename.toStdString().c_str()); + writer->SetInput(windowToImageFilter->GetOutput()); + writer->Write(); + + this->updateView(); +} + +void VisualizationWidget::setCursorShape(Qt::CursorShape shape) +{ + this->setCursor(QCursor(shape)); +} diff --git a/DataView/VisualizationWidget.h b/VtkVis/VisualizationWidget.h similarity index 51% rename from DataView/VisualizationWidget.h rename to VtkVis/VisualizationWidget.h index 442bc761bfbfb872c8c14965d53518279063d01a..6720c118f0d60c4b170f0f2263d9be9b9c979ca3 100644 --- a/DataView/VisualizationWidget.h +++ b/VtkVis/VisualizationWidget.h @@ -28,51 +28,68 @@ class VisualizationWidget : public QWidget, public Ui_VisualizationWidgetBase public: - /// Constructor. + /// @brief Constructor. VisualizationWidget(QWidget* parent = 0); - /// Destructor. + /// @brief Destructor. ~VisualizationWidget(); - /// Returns the VtkCustomInteractorStyle. + /// @brief Returns the VtkCustomInteractorStyle. VtkCustomInteractorStyle* interactorStyle() const; - /// Returns the VtkPickCallback. + /// @brief Returns the VtkPickCallback. VtkPickCallback* vtkPickCallback() const; + /// @brief See updateViewOnLoad(). + void setShowAllOnLoad(bool show) { _isShowAllOnLoad = show; } + public slots: - /// Updates the the 3d view. + /// @brief Updates the the 3d view. void updateView(); - /// Shows the entire scene on the views. + /// @brief Shows the entire scene on the views. void showAll(); - /// Returns the vtk renderer + /// @brief Updates the view only or additionally shows the entire scene. + void updateViewOnLoad(); + + /// @brief Saves a magnified image of the current render window to a file. + void screenshot(QString filename, int magnification); + + /// @brief Returns the vtk renderer vtkRenderer* renderer() const { return _vtkRender; } + /// @brief Sets the widgets cursor shape. + /// @see http://doc.qt.nokia.com/4.7/qt.html#CursorShape-enum + void setCursorShape(Qt::CursorShape shape); + protected slots: - /// Toggles stereo rendering on / off + /// @brief Toggles stereo rendering on / off. void on_stereoToolButton_toggled(bool checked); - /// Adjusts the eye angle (separation) for stereo viewing - void on_eyeAngleSlider_valueChanged(int value); + /// @brief Adjusts the eye angle (separation) for stereo viewing. + //void on_eyeAngleSlider_valueChanged(int value); - /// Toggles rectangular zooming mode. + /// @brief Toggles rectangular zooming mode. void on_zoomToolButton_toggled(bool checked); - /// Resets the camera to view the entire scene + /// @brief Resets the camera to view the entire scene. void on_showAllPushButton_pressed(); - /// Toggles the display of bounding boxes around + /// @brief Toggles the display of bounding boxes around. void on_highlightToolButton_toggled(bool checked); - /// Toggles the orthogonal projection + /// @brief Toggles the orthogonal projection. void on_orthogonalProjectionToolButton_toggled(bool checked); + /// @brief Saves a screenshot. + void on_screenshotPushButton_pressed(); + private: vtkRenderer* _vtkRender; VtkCustomInteractorStyle* _interactorStyle; VtkPickCallback* _vtkPickCallback; + bool _isShowAllOnLoad; #ifdef OGS_USE_VRPN vtkEventQtSlotConnect* _qtConnect; #endif // OGS_USE_VRPN diff --git a/DataView/VisualizationWidgetBase.ui b/VtkVis/VisualizationWidgetBase.ui similarity index 80% rename from DataView/VisualizationWidgetBase.ui rename to VtkVis/VisualizationWidgetBase.ui index 6f81cb046284bb44535ddb3479d7b6879d27971f..bc4108fa752d9aae0e116d447e8ad34f331caed0 100644 --- a/DataView/VisualizationWidgetBase.ui +++ b/VtkVis/VisualizationWidgetBase.ui @@ -28,7 +28,7 @@ </sizepolicy> </property> <property name="toolTip"> - <string>Resets camera to view the entire scene</string> + <string>Resets camera to view the entire scene from above.</string> </property> <property name="text"> <string>Show All</string> @@ -57,6 +57,9 @@ </item> <item> <widget class="QToolButton" name="highlightToolButton"> + <property name="toolTip"> + <string>When enabled a red bounding box is shown on selected items in the visualization pipeline.</string> + </property> <property name="text"> <string>Highlight</string> </property> @@ -70,6 +73,9 @@ </item> <item> <widget class="QToolButton" name="orthogonalProjectionToolButton"> + <property name="toolTip"> + <string>Switches between perspective and orthogonal projection.</string> + </property> <property name="text"> <string>Ortho</string> </property> @@ -99,46 +105,22 @@ </widget> </item> <item> - <widget class="QLabel" name="eyeAngleLabel"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>The eye separation for stereo rendering.</string> - </property> - <property name="text"> - <string>Eye Angle:</string> + <widget class="Line" name="line_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> </property> </widget> </item> <item> - <widget class="QSlider" name="eyeAngleSlider"> + <widget class="QPushButton" name="screenshotPushButton"> <property name="sizePolicy"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="toolTip"> - <string>The eye separation for stereo rendering.</string> - </property> - <property name="maximum"> - <number>100</number> - </property> - <property name="singleStep"> - <number>1</number> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="tickPosition"> - <enum>QSlider::TicksAbove</enum> - </property> - <property name="tickInterval"> - <number>10</number> + <property name="text"> + <string>Screenshot</string> </property> </widget> </item> diff --git a/VtkVis/VtkAddFilterDialog.cpp b/VtkVis/VtkAddFilterDialog.cpp index 40ae44c8a546ee0475a522cdf7638b076be9d6ac..cfdd4faea52748c966ae167bc31b41b1063a15c2 100644 --- a/VtkVis/VtkAddFilterDialog.cpp +++ b/VtkVis/VtkAddFilterDialog.cpp @@ -29,7 +29,7 @@ VtkAddFilterDialog::VtkAddFilterDialog( VtkVisPipeline* pipeline, QModelIndex pa vtkDataObject* parentDataObject = parentItem->algorithm()->GetOutputDataObject(0); int parentDataObjectType = parentDataObject->GetDataObjectType(); - + QVector<VtkFilterInfo> filterList = VtkFilterFactory::GetFilterList(); foreach(VtkFilterInfo filter, filterList) { @@ -42,6 +42,11 @@ VtkAddFilterDialog::VtkAddFilterDialog( VtkVisPipeline* pipeline, QModelIndex pa new QListWidgetItem(filter.readableName, filterListWidget); } + + // On double clicking an item the dialog gets accepted + connect(filterListWidget,SIGNAL(itemDoubleClicked(QListWidgetItem*)), + this->buttonBox,SIGNAL(accepted())); + } void VtkAddFilterDialog::on_buttonBox_accepted() @@ -59,13 +64,13 @@ void VtkAddFilterDialog::on_buttonBox_accepted() VtkVisPipelineItem* parentItem = static_cast<VtkVisPipelineItem*>(_pipeline->getItem(_parentIndex)); QList<QVariant> itemData; itemData << filterListWidget->currentItem()->text() << true; - + VtkCompositeFilter* filter; if (dynamic_cast<vtkImageAlgorithm*>(parentItem->algorithm())) filter = VtkFilterFactory::CreateCompositeFilter(filterName, parentItem->algorithm()); else filter = VtkFilterFactory::CreateCompositeFilter(filterName, parentItem->transformFilter()); - + VtkVisPipelineItem* item; if (filter) item = new VtkVisPipelineItem(filter, parentItem, itemData); diff --git a/VtkVis/VtkAlgorithmProperties.h b/VtkVis/VtkAlgorithmProperties.h index f8e4ed359603f432addd188916e98ed58082d757..142cc20f4a1e79c757c3ec042aec487a46f5038c 100644 --- a/VtkVis/VtkAlgorithmProperties.h +++ b/VtkVis/VtkAlgorithmProperties.h @@ -126,17 +126,19 @@ public: { _property = vtkProperty::New(); _texture = NULL; - _lut = NULL; _scalarVisibility = true; _algorithmUserProperties = new QMap<QString, QVariant>; _algorithmUserVectorProperties = new QMap<QString, QList<QVariant> >; + _activeAttributeName = ""; } virtual ~VtkAlgorithmProperties() { _property->Delete(); if (_texture != NULL) _texture->Delete(); - if (_lut != NULL) _lut->Delete(); + + for (std::map<QString, vtkLookupTable*>::iterator it = _lut.begin(); it != _lut.end(); ++it) + it->second->Delete(); delete _algorithmUserProperties; delete _algorithmUserVectorProperties; }; @@ -150,18 +152,32 @@ public: void SetTexture(vtkTexture* t) { _texture = t; }; /// @brief Returns the colour lookup table (if one has been assigned). - vtkLookupTable* GetLookupTable() { return _lut; }; - /// @brief Sets a colour lookup table for the VtkVisPipelineItem. - void SetLookUpTable(vtkLookupTable* lut) { _lut = lut; }; + vtkLookupTable* GetLookupTable(const QString& array_name) + { + std::map<QString, vtkLookupTable*>::iterator it = _lut.find(array_name); + if (it != _lut.end()) return it->second; + return NULL; + }; + + /// @brief Sets a colour lookup table for the given scalar array of the VtkVisPipelineItem. + void SetLookUpTable(const QString array_name, vtkLookupTable* lut) + { + if (array_name.length()>0) + { + std::map<QString, vtkLookupTable*>::iterator it = _lut.find(array_name); + if (it != _lut.end()) it->second->Delete(); + _lut.insert( std::pair<QString, vtkLookupTable*>(array_name, lut) ); + } + }; - /// Loads a predefined color lookup table from a file. - void SetLookUpTable(const std::string &filename) + /// Loads a predefined color lookup table from a file for the specified scalar array. + void SetLookUpTable(const QString &array_name, const std::string &filename) { VtkColorLookupTable* colorLookupTable = VtkColorLookupTable::New(); colorLookupTable->readFromFile(filename); colorLookupTable->setInterpolationType(VtkColorLookupTable::NONE); colorLookupTable->Build(); - SetLookUpTable(colorLookupTable); + SetLookUpTable(array_name, colorLookupTable); }; /// @brief Returns the scalar visibility. @@ -225,6 +241,9 @@ public: return QList<QVariant>(); } } + + /// @brief Returns the desired active attribute. + QString GetActiveAttribute() const { return _activeAttributeName; } protected: @@ -234,7 +253,7 @@ protected: // Properties set on vtkMapper bool _scalarVisibility; - vtkLookupTable* _lut; + std::map<QString, vtkLookupTable*> _lut; // Properties used in the GUI QString _name; diff --git a/VtkVis/VtkApplyColorTableFilter.cpp b/VtkVis/VtkApplyColorTableFilter.cpp index 46ef664a1424d1caf81807087957db1f9eddc1be..8180f6ef1f77f8058d69e81eeffaffc0a956a8d3 100644 --- a/VtkVis/VtkApplyColorTableFilter.cpp +++ b/VtkVis/VtkApplyColorTableFilter.cpp @@ -18,7 +18,7 @@ #include "VtkApplyColorTableFilter.h" vtkStandardNewMacro(VtkApplyColorTableFilter); -vtkCxxSetObjectMacro(VtkApplyColorTableFilter,ColorLookupTable,vtkLookupTable); +vtkCxxSetObjectMacro(VtkApplyColorTableFilter, ColorLookupTable, vtkLookupTable); vtkCxxRevisionMacro(VtkApplyColorTableFilter, "$Revision: 6575 $"); @@ -29,8 +29,6 @@ VtkApplyColorTableFilter::VtkApplyColorTableFilter() : ColorLookupTable(NULL) VtkApplyColorTableFilter::~VtkApplyColorTableFilter() { - if (this->ColorLookupTable != NULL) - this->ColorLookupTable->UnRegister(this); } int VtkApplyColorTableFilter::RequestData( vtkInformation* request, diff --git a/VtkVis/VtkColorByHeightFilter.cpp b/VtkVis/VtkColorByHeightFilter.cpp index 22f51c1db2b0c009dd9da86fff04dfdf650e38b5..daa917f61de01985f0fa7f142c5933ad8865bd55 100644 --- a/VtkVis/VtkColorByHeightFilter.cpp +++ b/VtkVis/VtkColorByHeightFilter.cpp @@ -27,7 +27,8 @@ VtkColorByHeightFilter::VtkColorByHeightFilter() ColorLookupTable = VtkColorLookupTable::New(); ColorLookupTable->GetTableRange(this->_tableRange); ColorLookupTable->setInterpolationType(VtkColorLookupTable::LINEAR); - this->_tableRangeScaling = 1.0; + _tableRangeScaling = 1.0; + _activeAttributeName = "P-Colors"; } VtkColorByHeightFilter::~VtkColorByHeightFilter() diff --git a/VtkVis/VtkColorLookupTable.cpp b/VtkVis/VtkColorLookupTable.cpp index 87983e7fb78e881b9462baaaae2ca6c8f389e90d..5508d2563f604abbdf372510f43e5c381d91369e 100644 --- a/VtkVis/VtkColorLookupTable.cpp +++ b/VtkVis/VtkColorLookupTable.cpp @@ -110,7 +110,7 @@ void VtkColorLookupTable::readFromFile(const std::string &filename) for (std::map<std::string, GEOLIB::Color*>::iterator it = colors.begin(); it != colors.end(); ++it) { - this->SetTableValue( strtod( it->first.c_str(), 0 ), (*(it->second))[0], (*(it->second))[1], (*(it->second))[2], 255 ); + this->SetTableValue( static_cast<vtkIdType>(strtod( it->first.c_str(), 0 )), (*(it->second))[0], (*(it->second))[1], (*(it->second))[2], 255 ); } } diff --git a/VtkVis/VtkCompositeColorByHeightFilter.cpp b/VtkVis/VtkCompositeColorByHeightFilter.cpp index 686fefc14e51875a912c9f05da1cb5634deb86a1..e47a2eac887293d68caf6f1499e38a7257f4f183 100644 --- a/VtkVis/VtkCompositeColorByHeightFilter.cpp +++ b/VtkVis/VtkCompositeColorByHeightFilter.cpp @@ -52,6 +52,7 @@ void VtkCompositeColorByHeightFilter::init() heightFilter->Update(); _outputAlgorithm = heightFilter; + _activeAttributeName = heightFilter->GetActiveAttribute(); } void VtkCompositeColorByHeightFilter::SetUserProperty( QString name, QVariant value ) diff --git a/VtkVis/VtkCompositeFilter.cpp b/VtkVis/VtkCompositeFilter.cpp index c86905648c2ac80101f4db7ef1a1698730a1dabb..f5ea0e86f0b0cccdb73227a97875bdddccdf86a8 100644 --- a/VtkVis/VtkCompositeFilter.cpp +++ b/VtkVis/VtkCompositeFilter.cpp @@ -15,7 +15,8 @@ #include <QMapIterator> VtkCompositeFilter::VtkCompositeFilter(vtkAlgorithm* inputAlgorithm) -: _inputAlgorithm(inputAlgorithm) +: _inputDataObjectType(0), _outputDataObjectType(1), + _inputAlgorithm(inputAlgorithm) { } diff --git a/VtkVis/VtkCompositeImageToCylindersFilter.cpp b/VtkVis/VtkCompositeImageToCylindersFilter.cpp index bbe584cb98509c2a6a6510c53deae6a0ddcfb2d7..b750545334845f4e92d4acc31d38044f4d1801f5 100644 --- a/VtkVis/VtkCompositeImageToCylindersFilter.cpp +++ b/VtkVis/VtkCompositeImageToCylindersFilter.cpp @@ -40,6 +40,9 @@ void VtkCompositeImageToCylindersFilter::init() (*_algorithmUserProperties)["LengthScaleFactor"] = 1.0; _lineFilter->Update(); + //vtkPointData* pointData = _lineFilter->GetOutput()->GetPointData(); + //pointData->GetArray(0)->SetName("Colors"); + vtkSmartPointer<vtkLookupTable> colormap = vtkSmartPointer<vtkLookupTable>::New(); colormap->SetTableRange(0, 100); colormap->SetHueRange(0.0, 0.666); @@ -54,6 +57,8 @@ void VtkCompositeImageToCylindersFilter::init() (*_algorithmUserVectorProperties)["TableRange"] = tableRangeList; (*_algorithmUserVectorProperties)["HueRange"] = hueRangeList; + this->SetLookUpTable("Colours", colormap); + _ctf = VtkApplyColorTableFilter::New(); _ctf->SetInputConnection(_lineFilter->GetOutputPort()); _ctf->SetColorLookupTable(colormap); @@ -101,6 +106,7 @@ void VtkCompositeImageToCylindersFilter::SetUserVectorProperty( QString name, QL static_cast<vtkLookupTable*>(_ctf->GetColorLookupTable())->SetTableRange(values[0].toInt(), values[1].toInt()); else if (name.compare("HueRange") == 0) static_cast<vtkLookupTable*>(_ctf->GetColorLookupTable())->SetHueRange(values[0].toDouble(), values[1].toDouble()); + } VtkCompositeImageToCylindersFilter::~VtkCompositeImageToCylindersFilter() diff --git a/VtkVis/VtkCompositeLineToTubeFilter.cpp b/VtkVis/VtkCompositeLineToTubeFilter.cpp index 403c3a1b46ad014a229bece9e4c987ac2bc12a39..f44b178ee2f5896a8a468825cbacca40bc3dfda6 100644 --- a/VtkVis/VtkCompositeLineToTubeFilter.cpp +++ b/VtkVis/VtkCompositeLineToTubeFilter.cpp @@ -36,11 +36,11 @@ void VtkCompositeLineToTubeFilter::init() vtkTubeFilter* tubes = vtkTubeFilter::New(); tubes->SetInputConnection(0, mergePoints->GetOutputPort(0)); - tubes->SetInputArrayToProcess(1,0,0,vtkDataObject::FIELD_ASSOCIATION_CELLS,"StratColors"); + tubes->SetInputArrayToProcess(1,0,0,vtkDataObject::FIELD_ASSOCIATION_CELLS,"Stratigraphies"); tubes->SetRadius(150); tubes->SetNumberOfSides(10); tubes->SetCapping(1); - + (*_algorithmUserProperties)["Radius"] = 150.0; (*_algorithmUserProperties)["NumberOfSides"] = 6; (*_algorithmUserProperties)["Capping"] = true; @@ -53,7 +53,7 @@ void VtkCompositeLineToTubeFilter::SetUserProperty( QString name, QVariant value VtkAlgorithmProperties::SetUserProperty(name, value); if (name.compare("Radius") == 0) - static_cast<vtkTubeFilter*>(_outputAlgorithm)->SetRadius(value.toInt()); + static_cast<vtkTubeFilter*>(_outputAlgorithm)->SetRadius(value.toDouble()); else if (name.compare("NumberOfSides") == 0) static_cast<vtkTubeFilter*>(_outputAlgorithm)->SetNumberOfSides(value.toInt()); else if (name.compare("Capping") == 0) diff --git a/VtkVis/VtkCompositeSelectionFilter.cpp b/VtkVis/VtkCompositeSelectionFilter.cpp index ab0961a47d41023c94fcd87bf8705f0b0578ad9b..d15aaa9e14b5cf85309e6dcd69ccb9b7717b477c 100644 --- a/VtkVis/VtkCompositeSelectionFilter.cpp +++ b/VtkVis/VtkCompositeSelectionFilter.cpp @@ -22,31 +22,50 @@ VtkCompositeSelectionFilter::VtkCompositeSelectionFilter( vtkAlgorithm* inputAlg void VtkCompositeSelectionFilter::init() { - double thresholdValue(1.0); + double thresholdLower(0.0), thresholdUpper(1.0); this->_inputDataObjectType = VTK_UNSTRUCTURED_GRID; this->_outputDataObjectType = VTK_UNSTRUCTURED_GRID; VtkSelectionFilter* selFilter = VtkSelectionFilter::New(); selFilter->SetInputConnection(_inputAlgorithm->GetOutputPort()); - selFilter->SetSelectionArray(_selection, thresholdValue, true); + selFilter->SetSelectionArray(_selection, thresholdLower, thresholdUpper); selFilter->Update(); vtkThreshold* threshold = vtkThreshold::New(); threshold->SetInputConnection(selFilter->GetOutputPort()); threshold->SetInputArrayToProcess(0,0,0,vtkDataObject::FIELD_ASSOCIATION_CELLS, "Selection"); threshold->SetSelectedComponent(0); - threshold->ThresholdByLower(thresholdValue); + threshold->ThresholdBetween(thresholdLower, thresholdUpper); threshold->Update(); - (*_algorithmUserProperties)["Threshold"] = thresholdValue; + + QList<QVariant> thresholdRangeList; + thresholdRangeList.push_back(0.0); + thresholdRangeList.push_back(1.0); + (*_algorithmUserVectorProperties)["Threshold Between"] = thresholdRangeList; _outputAlgorithm = threshold; } -void VtkCompositeSelectionFilter::SetUserProperty( QString name, QVariant value ) +void VtkCompositeSelectionFilter::SetUserVectorProperty( QString name, QList<QVariant> values) { - VtkAlgorithmProperties::SetUserProperty(name, value); + VtkAlgorithmProperties::SetUserVectorProperty(name, values); + + if (name.compare("Threshold Between") == 0) + static_cast<vtkThreshold*>(_outputAlgorithm)->ThresholdBetween(values[0].toDouble(), values[1].toDouble()); +} - if (name.compare("Threshold") == 0) - // Set the vector property on the algorithm - static_cast<vtkThreshold*>(_outputAlgorithm)->ThresholdByLower(value.toDouble()); +VtkColorLookupTable* VtkCompositeSelectionFilter::GetLookupTable() +{ + VtkColorLookupTable* lut = VtkColorLookupTable::New(); + lut->SetTableRange(0,1); + unsigned char a[4] = { 0, 0, 255, 255 }; // blue + unsigned char b[4] = { 0, 255, 0, 255 }; // green + unsigned char c[4] = { 255, 255, 0, 255 }; // yellow + unsigned char d[4] = { 255, 0, 0, 255 }; // red + lut->setColor(1.0, a); + lut->setColor(0.5, b); + lut->setColor(0.25, c); + lut->setColor(0.1, d); + lut->Build(); + return lut; } diff --git a/VtkVis/VtkCompositeSelectionFilter.h b/VtkVis/VtkCompositeSelectionFilter.h index ac0ff23b941b79eb327d7bd44d2dac8df716e070..59b518c25ce8d285a636eaa3919e3b96807d8105 100644 --- a/VtkVis/VtkCompositeSelectionFilter.h +++ b/VtkVis/VtkCompositeSelectionFilter.h @@ -19,9 +19,12 @@ public: void setSelectionArray(std::vector<double> selection) { _selection = selection; init(); }; - virtual void SetUserProperty(QString name, QVariant value); + virtual void SetUserVectorProperty(QString name, QList<QVariant> values); private: + /// Returns a colour lookup table optimised for quality measures + VtkColorLookupTable* GetLookupTable(); + std::vector<double> _selection; }; diff --git a/VtkVis/VtkConditionSource.cpp b/VtkVis/VtkConditionSource.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b00d910e6644e6c2fc661b5c801ca915edaf13b4 --- /dev/null +++ b/VtkVis/VtkConditionSource.cpp @@ -0,0 +1,263 @@ +/** + * \file VtkConditionSource.cpp + * 2011/03/02 KR Initial implementation + */ + +// ** INCLUDES ** +#include "VtkConditionSource.h" +#include "AxisAlignedBoundingBox.h" +#include "FEMCondition.h" + +#include <vtkCellArray.h> +#include <vtkDoubleArray.h> +#include <vtkInformation.h> +#include <vtkInformationVector.h> +#include <vtkObjectFactory.h> +#include <vtkSmartPointer.h> +#include <vtkStreamingDemandDrivenPipeline.h> +#include <vtkPointData.h> +#include <vtkPoints.h> +#include <vtkPolyData.h> +#include <vtkPolygon.h> + +#include <vtkLookupTable.h> + +vtkStandardNewMacro(VtkConditionSource); +vtkCxxRevisionMacro(VtkConditionSource, "$Revision$"); + +VtkConditionSource::VtkConditionSource() +: _points(NULL), _cond_vec(NULL) +{ + this->SetNumberOfInputPorts(0); + + const GEOLIB::Color* c = GEOLIB::getRandomColor(); + GetProperties()->SetColor((*c)[0]/255.0,(*c)[1]/255.0,(*c)[2]/255.0); +} + +VtkConditionSource::~VtkConditionSource() +{ +} + +void VtkConditionSource::setData(const std::vector<GEOLIB::Point*>* points, const std::vector<FEMCondition*>* conds) +{ + _points = points; + _cond_vec = conds; +} + +void VtkConditionSource::PrintSelf( ostream& os, vtkIndent indent ) +{ + this->Superclass::PrintSelf(os,indent); + + if (_points->size() == 0) + return; + + os << indent << "== VtkConditionSource ==" << "\n"; +} + +int VtkConditionSource::RequestData( vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector ) +{ + (void)request; + (void)inputVector; + + if ( _points ) + { + if (_points->empty()) + { + std::cout << "ERROR in VtkConditionSource::RequestData : Size of point vector is 0" << std::endl; + return 0; + } + } + else return 0; + + + vtkSmartPointer<vtkPoints> newPoints = vtkSmartPointer<vtkPoints>::New(); + vtkSmartPointer<vtkInformation> outInfo = outputVector->GetInformationObject(0); + vtkSmartPointer<vtkPolyData> output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); + + vtkSmartPointer<vtkDoubleArray> scalars = vtkSmartPointer<vtkDoubleArray>::New(); + scalars->SetNumberOfComponents(1); + scalars->SetName("Scalars"); + //std::map<size_t, size_t> idx_map; + + vtkSmartPointer<vtkCellArray> newVerts = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkCellArray> newLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkCellArray> newPolys = vtkSmartPointer<vtkCellArray>::New(); + + if (outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) > 0) + return 1; + + + size_t n_pnts = _points->size(); + double value(0.0); + if (!_cond_vec->empty()) + { + const std::vector<double> dv = (*_cond_vec)[0]->getDisValue(); + value = dv[dv.size()-1]; // get an existing value for the distribution so scaling on point data will be correct during rendering process! + } + + for (size_t i=0; i<n_pnts; i++) + { + double coords[3] = {(*(*_points)[i])[0], (*(*_points)[i])[1], (*(*_points)[i])[2]}; + newPoints->InsertNextPoint(coords); + scalars->InsertNextValue(value); + } + + + size_t nCond = _cond_vec->size(); + for (size_t n=0; n<nCond; n++) + { + FiniteElement::DistributionType type = (*_cond_vec)[n]->getProcessDistributionType(); + const std::vector<double> dis_values = (*_cond_vec)[n]->getDisValue(); + + if ((*_cond_vec)[n]->getGeoType() == GEOLIB::POINT) + { + size_t nPoints = _points->size(); + const GEOLIB::Point* pnt = static_cast<const GEOLIB::Point*>((*_cond_vec)[n]->getGeoObj()); + int id(-1); + for (size_t i=0; i<nPoints; i++) + { + if ((*_points)[i] == pnt) + { + vtkIdType id = static_cast<int>(i);//(this->getIndex(i, newPoints, scalars, idx_map)); + newVerts->InsertNextCell(1, &id); + if (type == FiniteElement::CONSTANT) + scalars->SetValue(id, dis_values[0]); + break; + } + } + if (id==-1) std::cout << "Error in VtkConditionSource::RequestData() - Point object not found ..." << std::endl; + } + else if ((*_cond_vec)[n]->getGeoType() == GEOLIB::POLYLINE) + { + const GEOLIB::Polyline* ply = static_cast<const GEOLIB::Polyline*>((*_cond_vec)[n]->getGeoObj()); + const int nPoints = ply->getNumberOfPoints(); + newLines->InsertNextCell(nPoints); + for (int i = 0; i < nPoints; i++) + { + size_t x = ply->getPointID(i); + size_t pnt_id = ply->getPointID(i);//this->getIndex(ply->getPointID(i), newPoints, scalars, idx_map); + newLines->InsertCellPoint(pnt_id); + + if (type == FiniteElement::CONSTANT) + scalars->SetValue(pnt_id, dis_values[0]); + else if (type == FiniteElement::LINEAR) + { + for (size_t j=0; j<dis_values.size(); j+=2) + if (static_cast<size_t>(dis_values[j]) == pnt_id) + //if (this->getIndex(static_cast<size_t>(dis_values[j]), newPoints, scalars, idx_map) == pnt_id) + { + scalars->SetValue(pnt_id, dis_values[j+1]); + break; + } + } + } + } + else if ((*_cond_vec)[n]->getGeoType() == GEOLIB::SURFACE) + { + const GEOLIB::Surface* sfc = static_cast<const GEOLIB::Surface*>((*_cond_vec)[n]->getGeoObj()); + + const size_t nTriangles = sfc->getNTriangles(); + + for (size_t i=0; i<nTriangles; i++) + { + vtkPolygon* aPolygon = vtkPolygon::New(); + aPolygon->GetPointIds()->SetNumberOfIds(3); + + const GEOLIB::Triangle* triangle = (*sfc)[i]; + for (size_t j=0; j<3; j++) + { + size_t pnt_id = (*triangle)[j];//this->getIndex((*triangle)[j], newPoints, scalars, idx_map); + aPolygon->GetPointIds()->SetId(j, pnt_id); + + if (type == FiniteElement::CONSTANT) + scalars->SetValue(pnt_id, dis_values[0]); + else if (type == FiniteElement::LINEAR) + { + for (size_t k=0; k<dis_values.size(); k+=2) + if (static_cast<size_t>(dis_values[j]) == pnt_id) + //if (this->getIndex(static_cast<size_t>(dis_values[j]), newPoints, scalars, idx_map) == pnt_id) + { + scalars->SetValue(pnt_id, dis_values[j+1]); + break; + } + } + } + newPolys->InsertNextCell(aPolygon); + + aPolygon->Delete(); + } + } + // draw a bounding box in case of of the conditions is "domain" + else if ((*_cond_vec)[n]->getGeoType() == GEOLIB::GEODOMAIN) + { + GEOLIB::AABB bounding_box (_points); + std::vector<GEOLIB::Point> box; + box.push_back(bounding_box.getMinPoint()); + box.push_back(bounding_box.getMaxPoint()); + + vtkIdType nPoints = newPoints->GetNumberOfPoints(); + size_t pnt_idx = _points->size(); + + for (size_t i=0; i<8; i++) + { + double coords[3] = {box[i%2][0], box[(i>>1)%2][1], box[i>>2][2]}; + newPoints->InsertNextPoint(coords); + scalars->InsertNextValue(0.0); + //idx_map.insert( std::pair<size_t,size_t>(pnt_idx+i, nPoints+i)); + } + + for (size_t i=0; i<4; i++) + { + vtkIdType a[2] = {nPoints+i, nPoints+i+4}; + vtkIdType b[2] = {nPoints+(i*2), nPoints+(i*2+1)}; + vtkIdType c[2] = {nPoints+(static_cast<int>(i/2)*4+(i%2)), nPoints+(static_cast<int>(i/2)*4+(i%2)+2)}; + newLines->InsertNextCell(2, &a[0]); + newLines->InsertNextCell(2, &b[0]); + newLines->InsertNextCell(2, &c[0]); + } + } + } + + + output->SetPoints(newPoints); + output->GetPointData()->AddArray(scalars); + output->GetPointData()->SetActiveScalars("Scalars"); + output->SetVerts(newVerts); + output->SetLines(newLines); + output->SetPolys(newPolys); + + return 1; +} + +int VtkConditionSource::RequestInformation( vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector ) +{ + (void)request; + (void)inputVector; + + vtkInformation* outInfo = outputVector->GetInformationObject(0); + outInfo->Set(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(), -1); + + return 1; +} + +void VtkConditionSource::SetUserProperty( QString name, QVariant value ) +{ + Q_UNUSED(name); + Q_UNUSED(value); +} + +/* +size_t VtkConditionSource::getIndex(size_t idx, vtkSmartPointer<vtkPoints> newPoints, vtkSmartPointer<vtkDoubleArray> scalars, std::map<size_t, size_t> &idx_map) +{ + std::map<size_t,size_t>::iterator mapped_index = idx_map.find(idx); + if (mapped_index != idx_map.end()) return mapped_index->second; + + double coords[3] = {(*(*_points)[idx])[0], (*(*_points)[idx])[1], (*(*_points)[idx])[2]}; + newPoints->InsertNextPoint(coords); + scalars->InsertNextValue(0.0); + size_t new_idx = idx_map.size(); + idx_map.insert( std::pair<size_t,size_t>(idx, new_idx) ); + std::cout << idx << ", " << new_idx << std::endl; + return new_idx; +} +*/ diff --git a/VtkVis/VtkConditionSource.h b/VtkVis/VtkConditionSource.h new file mode 100644 index 0000000000000000000000000000000000000000..1f4f0084f3edf8f87c4f68dfd57248969586cad1 --- /dev/null +++ b/VtkVis/VtkConditionSource.h @@ -0,0 +1,59 @@ +/** + * \file VtkConditionSource.h + * 2011/03/02 KR Initial implementation + * + */ + + +#ifndef VTKCONDITIONSOURCE_H +#define VTKCONDITIONSOURCE_H + +// ** INCLUDES ** +#include <vtkPolyDataAlgorithm.h> +#include "VtkAlgorithmProperties.h" + +#include "GEOObjects.h" +//#include <vtkSmartPointer.h> + +class FEMCondition; +//class vtkPoints; +//class vtkDoubleArray; + +/** + * \brief VtkConditionSource is a VTK source object for the visualization + * of FEM conditions. As a vtkPolyDataAlgorithm it outputs polygonal data. + */ +class VtkConditionSource : public vtkPolyDataAlgorithm, public VtkAlgorithmProperties +{ + +public: + /// Create new objects with New() because of VTKs object reference counting. + static VtkConditionSource* New(); + + vtkTypeRevisionMacro(VtkConditionSource,vtkPolyDataAlgorithm); + + /// Sets the FEMCondition that need to be visualised. The geometry points array is needed because polylines and surfaces are linked to this data. + void setData(const std::vector<GEOLIB::Point*>* points, const std::vector<FEMCondition*>* conds); + + /// Prints its data on a stream. + void PrintSelf(ostream& os, vtkIndent indent); + + virtual void SetUserProperty(QString name, QVariant value); + +protected: + VtkConditionSource(); + ~VtkConditionSource(); + + /// Computes the polygonal data object. + int RequestData(vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector); + + int RequestInformation(vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector); + +private: + //size_t getIndex(size_t idx, vtkSmartPointer<vtkPoints> newPoints, vtkSmartPointer<vtkDoubleArray> scalars, std::map<size_t, size_t> &idx_map); + + const std::vector<GEOLIB::Point*>* _points; + const std::vector<FEMCondition*> *_cond_vec; +}; + +#endif // VTKCONDITIONSOURCE_H diff --git a/VtkVis/VtkImageDataToLinePolyDataFilter.cpp b/VtkVis/VtkImageDataToLinePolyDataFilter.cpp index 66b6af771e1c5d799ae2ea30314645df6088b91e..b6e47ea91fac11204502dfac14683239eac8cad1 100644 --- a/VtkVis/VtkImageDataToLinePolyDataFilter.cpp +++ b/VtkVis/VtkImageDataToLinePolyDataFilter.cpp @@ -126,7 +126,8 @@ int VtkImageDataToLinePolyDataFilter::RequestData(vtkInformation*, // Store the new set of points in the output output->SetPoints(newPts); - + output->GetPointData()->GetArray(0)->SetName("Colours"); + // Avoid keeping extra memory around output->Squeeze(); diff --git a/VtkVis/VtkMeshSource.cpp b/VtkVis/VtkMeshSource.cpp index 9edbd3b5ca7c59e2822f492eff56a0519c1568f0..e2382aedcf282c2a1e9e0d66e48cc56a97dc2c0a 100644 --- a/VtkVis/VtkMeshSource.cpp +++ b/VtkVis/VtkMeshSource.cpp @@ -56,7 +56,7 @@ void VtkMeshSource::PrintSelf( ostream& os, vtkIndent indent ) if (_grid == NULL) return; const std::vector<GEOLIB::Point*> *nodes = _grid->getNodes(); const std::vector<GridAdapter::Element*> *elems = _grid->getElements(); - if (nodes->size() == 0 || elems->size() == 0) return; + if (nodes->empty() || elems->empty() ) return; os << indent << "== VtkMeshSource ==" << "\n"; diff --git a/VtkVis/VtkPointsSource.cpp b/VtkVis/VtkPointsSource.cpp index 416785ad23f7b8669b1f59bd9dae9cfac1d1d4d5..d6dcae1ae103cebf281d37d7bb8d4b837f9562f4 100644 --- a/VtkVis/VtkPointsSource.cpp +++ b/VtkVis/VtkPointsSource.cpp @@ -12,6 +12,7 @@ #include <vtkInformation.h> #include <vtkInformationVector.h> #include <vtkObjectFactory.h> +#include <vtkSmartPointer.h> #include <vtkStreamingDemandDrivenPipeline.h> #include <vtkPointData.h> #include <vtkPoints.h> @@ -62,11 +63,11 @@ int VtkPointsSource::RequestData( vtkInformation* request, vtkInformationVector* return 0; } - vtkInformation *outInfo = outputVector->GetInformationObject(0); - vtkPolyData* output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); + vtkSmartPointer<vtkInformation> outInfo = outputVector->GetInformationObject(0); + vtkSmartPointer<vtkPolyData> output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); - vtkPoints* newPoints = vtkPoints::New(); - vtkCellArray* newVerts = vtkCellArray::New(); + vtkSmartPointer<vtkPoints> newPoints = vtkSmartPointer<vtkPoints>::New(); + vtkSmartPointer<vtkCellArray> newVerts = vtkSmartPointer<vtkCellArray>::New(); newPoints->Allocate(numPoints); newVerts->Allocate(numPoints); @@ -78,16 +79,12 @@ int VtkPointsSource::RequestData( vtkInformation* request, vtkInformationVector* it != _points->end(); ++it) { double coords[3] = {(*(*it))[0], (*(*it))[1], (*(*it))[2]}; - vtkIdType pid[1]; - pid[0] = newPoints->InsertNextPoint(coords); - newVerts->InsertNextCell(1, pid); + vtkIdType pid = newPoints->InsertNextPoint(coords); + newVerts->InsertNextCell(1, &pid); } output->SetPoints(newPoints); - newPoints->Delete(); - output->SetVerts(newVerts); - newVerts->Delete(); return 1; } diff --git a/VtkVis/VtkSelectionFilter.cpp b/VtkVis/VtkSelectionFilter.cpp index 315c1673da0af74bd962a67e50c081a10a86f8e7..90d6701ebe10b9a6e429a1f9ad110923b5408594 100644 --- a/VtkVis/VtkSelectionFilter.cpp +++ b/VtkVis/VtkSelectionFilter.cpp @@ -22,6 +22,7 @@ vtkCxxRevisionMacro(VtkSelectionFilter, "$Revision: 6995 $"); VtkSelectionFilter::VtkSelectionFilter() +: _thresholdLower(0.0), _thresholdUpper(1.0) { } @@ -72,9 +73,9 @@ int VtkSelectionFilter::RequestData( vtkInformation*, return 1; } -void VtkSelectionFilter::SetSelectionArray(std::vector<double> selection, double threshold, bool ifSmaller) +void VtkSelectionFilter::SetSelectionArray(std::vector<double> selection, double thresholdLower, double thresholdUpper) { this->_selection = selection; - this->_threshold = threshold; - this->_ifSmaller = ifSmaller; -} \ No newline at end of file + this->_thresholdLower = thresholdLower; + this->_thresholdUpper = thresholdUpper; +} diff --git a/VtkVis/VtkSelectionFilter.h b/VtkVis/VtkSelectionFilter.h index 2306ab36803d57efe07cc3d7078550c050b09927..16ac539bc61c856c27b6f151fc8f4fa1089576fa 100644 --- a/VtkVis/VtkSelectionFilter.h +++ b/VtkVis/VtkSelectionFilter.h @@ -33,7 +33,7 @@ public: Q_UNUSED(value); } - void SetSelectionArray(std::vector<double> selection, double threshold, bool ifSmaller=true); + void SetSelectionArray(std::vector<double> selection, double thresholdLower, double thresholdUpper); protected: @@ -47,7 +47,8 @@ protected: private: std::vector<double> _selection; - double _threshold; + double _thresholdLower; + double _thresholdUpper; double _ifSmaller; }; diff --git a/VtkVis/VtkStationSource.cpp b/VtkVis/VtkStationSource.cpp index 1aeee106b4f6b63b476fc655190a5fb50e0ff4e3..d32bde45b3abef999be2f3bab3ebd6c9a3872070 100644 --- a/VtkVis/VtkStationSource.cpp +++ b/VtkVis/VtkStationSource.cpp @@ -38,7 +38,7 @@ VtkStationSource::VtkStationSource() VtkStationSource::~VtkStationSource() { std::map<std::string, GEOLIB::Color*>::iterator it; - for (it = _colorLookupTable.begin(); it != _colorLookupTable.end(); it++) { + for (it = _colorLookupTable.begin(); it != _colorLookupTable.end(); ++it) { delete it->second; } } @@ -82,32 +82,26 @@ int VtkStationSource::RequestData( vtkInformation* request, vtkInformationVector vtkSmartPointer<vtkPoints> newStations = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> newVerts = vtkSmartPointer<vtkCellArray>::New(); - //newStations->Allocate(nStations); newVerts->Allocate(nStations); vtkSmartPointer<vtkCellArray> newLines; + if (isBorehole) - { newLines = vtkSmartPointer<vtkCellArray>::New(); - this->setColorLookupTable("./BoreholeColourReference.txt"); - if (_colorLookupTable.empty()) std::cout << "No look-up table for stratigraphy-colors specified. Generating colors on the fly..." << std::endl; - } - if (outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) > 0) return 1; - // create colour (this assumes that all points in a list have the same colour. - // if this is not the case the colour for each point has to be set for each point - // individually in the loop below - GEOLIB::Color* c = static_cast<GEOLIB::Station*>((*_stations)[0])->getColor(); - unsigned char stationColor[3] = { (*c)[0], (*c)[1], (*c)[2] }; + vtkSmartPointer<vtkIntArray> station_ids = vtkSmartPointer<vtkIntArray>::New(); + station_ids->SetNumberOfComponents(1); + station_ids->SetName("SiteIDs"); - vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New(); - colors->SetNumberOfComponents(3); - colors->SetName("StationColors"); + vtkSmartPointer<vtkIntArray> strat_ids = vtkSmartPointer<vtkIntArray>::New(); + strat_ids->SetNumberOfComponents(1); + strat_ids->SetName("Stratigraphies"); - int lastMaxIndex = 0; + size_t lastMaxIndex(0); + size_t site_count(0); // Generate graphic objects for (std::vector<GEOLIB::Point*>::const_iterator it = _stations->begin(); @@ -115,11 +109,11 @@ int VtkStationSource::RequestData( vtkInformation* request, vtkInformationVector { double coords[3] = { (*(*it))[0], (*(*it))[1], (*(*it))[2] }; vtkIdType sid = newStations->InsertNextPoint(coords); - + station_ids->InsertNextValue(site_count); + if (!isBorehole) { newVerts->InsertNextCell(1, &sid); - colors->InsertNextTupleValue(stationColor); } else { @@ -129,31 +123,33 @@ int VtkStationSource::RequestData( vtkInformation* request, vtkInformationVector for (size_t i=1; i<nLayers; i++) { - double*pCoords = const_cast<double*>(profile[i]->getData()); + double* pCoords = const_cast<double*>(profile[i]->getData()); double loc[3] = { pCoords[0], pCoords[1], pCoords[2] }; newStations->InsertNextPoint(loc); + station_ids->InsertNextValue(site_count); newLines->InsertNextCell(2); newLines->InsertCellPoint(lastMaxIndex); // start of borehole-layer newLines->InsertCellPoint(lastMaxIndex+1); //end of boreholelayer lastMaxIndex++; - const GEOLIB::Color *c (GEOLIB::getColor(soilNames[i], _colorLookupTable)); - unsigned char sColor[3] = { (*c)[0], (*c)[1], (*c)[2] }; - colors->InsertNextTupleValue(sColor); + strat_ids->InsertNextValue(this->GetIndexByName(soilNames[i])); } lastMaxIndex++; } + site_count++; } output->SetPoints(newStations); - + //output->GetPointData()->AddArray(station_ids); + if (!isBorehole) output->SetVerts(newVerts); else + { output->SetLines(newLines); - - output->GetCellData()->AddArray(colors); - output->GetCellData()->SetActiveScalars("StationColors"); + output->GetCellData()->AddArray(strat_ids); + output->GetCellData()->SetActiveAttribute("Stratigraphies", vtkDataSetAttributes::SCALARS); + } return 1; } @@ -174,3 +170,18 @@ void VtkStationSource::SetUserProperty( QString name, QVariant value ) Q_UNUSED(name); Q_UNUSED(value); } + +size_t VtkStationSource::GetIndexByName( std::string name ) +{ + vtkIdType max_key(0); + for (std::map<std::string, vtkIdType>::const_iterator it=_id_map.begin(); it != _id_map.end(); ++it) + { + if (name.compare(it->first) == 0) + return it->second; + if (it->second > max_key) max_key = it->second; + } + vtkIdType new_index(max_key+1); + std::cout << "Key \"" << name << "\" not found in color lookup table..." << std::endl; + _id_map.insert(std::pair<std::string, vtkIdType>(name, new_index)); + return new_index; +} diff --git a/VtkVis/VtkStationSource.h b/VtkVis/VtkStationSource.h index 7a1704c2123380423762e64c2356e1c82490b4f3..6732200b5a1f0b6504b45be2a2d4cf136aa79140 100644 --- a/VtkVis/VtkStationSource.h +++ b/VtkVis/VtkStationSource.h @@ -58,7 +58,9 @@ protected: std::map<std::string, GEOLIB::Color*> _colorLookupTable; private: + size_t GetIndexByName( std::string name ); + std::map<std::string, vtkIdType> _id_map; }; diff --git a/VtkVis/VtkVisPipeline.cpp b/VtkVis/VtkVisPipeline.cpp index 80e2249e7f857fe7a32d33bdea0a044f2f4b4728..f06e1a3e4c198b38c42f142b471a02883d3626ea 100644 --- a/VtkVis/VtkVisPipeline.cpp +++ b/VtkVis/VtkVisPipeline.cpp @@ -13,13 +13,17 @@ #include "MshModel.h" #include "MshItem.h" #include "GeoTreeModel.h" +#include "ConditionModel.h" #include "StationTreeModel.h" #include "VtkVisPipelineItem.h" #include "VtkMeshSource.h" #include "VtkAlgorithmProperties.h" #include "VtkTrackedCamera.h" #include "VtkFilterFactory.h" -#include "MeshQualityChecker.h" +#include "MeshQualityShortestLongestRatio.h" +#include "MeshQualityNormalisedArea.h" +#include "MeshQualityNormalisedVolumes.h" +#include "MeshQualityEquiAngleSkew.h" #include "VtkCompositeSelectionFilter.h" #include <vtkSmartPointer.h> @@ -64,6 +68,8 @@ VtkVisPipeline::VtkVisPipeline(vtkRenderer* renderer, OSG::SimpleSceneManager* m QVariant backgroundColorVariant = settings.value("VtkBackgroundColor"); if (backgroundColorVariant != QVariant()) this->setBGColor(backgroundColorVariant.value<QColor>()); + + _resetCameraOnAddOrRemove = true; } #else // OGS_USE_OPENSG VtkVisPipeline::VtkVisPipeline( vtkRenderer* renderer, QObject* parent /*= 0*/ ) @@ -73,11 +79,13 @@ VtkVisPipeline::VtkVisPipeline( vtkRenderer* renderer, QObject* parent /*= 0*/ ) rootData << "Object name" << "Visible"; delete _rootItem; _rootItem = new TreeItem(rootData, NULL); - + QSettings settings("UFZ", "OpenGeoSys-5"); QVariant backgroundColorVariant = settings.value("VtkBackgroundColor"); if (backgroundColorVariant != QVariant()) this->setBGColor(backgroundColorVariant.value<QColor>()); + + _resetCameraOnAddOrRemove = true; } #endif // OGS_USE_OPENSG @@ -228,6 +236,21 @@ void VtkVisPipeline::loadFromFile(QString filename) #endif } +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->setScaleOnChilds(1.0, 1.0, 1.0); + } + + emit vtkVisPipelineChanged(); +} + void VtkVisPipeline::addPipelineItem(GeoTreeModel* model, const std::string &name, GEOLIB::GEOTYPE type) { addPipelineItem(model->vtkSource(name, type)); @@ -238,6 +261,11 @@ void VtkVisPipeline::addPipelineItem(StationTreeModel* model, const std::string addPipelineItem(model->vtkSource(name)); } +void VtkVisPipeline::addPipelineItem(ConditionModel* model, const std::string &name, FEMCondition::CondType type) +{ + addPipelineItem(model->vtkSource(name, type)); +} + void VtkVisPipeline::addPipelineItem(MshModel* model, const QModelIndex &idx) { addPipelineItem(static_cast<MshItem*>(model->getItem(idx))->vtkSource()); @@ -249,16 +277,17 @@ void VtkVisPipeline::addPipelineItem(VtkVisPipelineItem* item, const QModelIndex TreeItem* parentItem = item->parentItem(); parentItem->appendChild(item); - if (parent.isValid()) // KR scale children according to parent + if (!parent.isValid()) // Set global superelevation on source objects { - double* scale = static_cast<VtkVisPipelineItem*>(parentItem)->actor()->GetScale(); - item->actor()->SetScale(scale); + QSettings settings("UFZ, OpenGeoSys-5"); + item->setScale(1.0, 1.0, settings.value("globalSuperelevation", 1.0).toDouble()); } int parentChildCount = parentItem->childCount(); QModelIndex newIndex = index(parentChildCount - 1, 0, parent); - _renderer->ResetCamera(_renderer->ComputeVisiblePropBounds()); + if (_resetCameraOnAddOrRemove) + _renderer->ResetCamera(_renderer->ComputeVisiblePropBounds()); _actorMap.insert(item->actor(), newIndex); // Do not interpolate images @@ -309,7 +338,6 @@ void VtkVisPipeline::addPipelineItem( vtkAlgorithm* source, itemName = QString(source->GetClassName()); itemData << itemName << true; - VtkVisPipelineItem* item = new VtkVisPipelineItem(source, parentItem, itemData); this->addPipelineItem(item, parent); @@ -331,6 +359,19 @@ void VtkVisPipeline::removeSourceItem(GeoTreeModel* model, const std::string &na } } +void VtkVisPipeline::removeSourceItem(ConditionModel* model, const std::string &name, FEMCondition::CondType type) +{ + for (int i = 0; i < _rootItem->childCount(); i++) + { + VtkVisPipelineItem* item = static_cast<VtkVisPipelineItem*>(getItem(index(i, 0))); + if (item->algorithm() == model->vtkSource(name, type)) + { + removePipelineItem(index(i, 0)); + return; + } + } +} + void VtkVisPipeline::removeSourceItem(StationTreeModel* model, const std::string &name) { for (int i = 0; i < _rootItem->childCount(); i++) @@ -379,7 +420,8 @@ void VtkVisPipeline::removePipelineItem( QModelIndex index ) //TreeItem* item = getItem(index); removeRows(index.row(), 1, index.parent()); - _renderer->ResetCamera(_renderer->ComputeVisiblePropBounds()); + if (_resetCameraOnAddOrRemove) + _renderer->ResetCamera(_renderer->ComputeVisiblePropBounds()); emit vtkVisPipelineChanged(); } @@ -401,49 +443,60 @@ void VtkVisPipeline::listArrays(vtkDataSet* dataSet) std::cout << "Error loading vtk file: not a valid vtkDataSet." << std::endl; } -void VtkVisPipeline::checkMeshQuality(VtkMeshSource* source) +void VtkVisPipeline::checkMeshQuality(VtkMeshSource* source, MshQualityType::type t) { if (source) { const Mesh_Group::CFEMesh* mesh = source->GetGrid()->getCFEMesh(); - Mesh_Group::MeshQualityChecker checker (mesh); - checker.check (); + Mesh_Group::MeshQualityChecker* checker (NULL); + if (t == MshQualityType::EDGERATIO) + checker = new Mesh_Group::MeshQualityShortestLongestRatio(mesh); + else if (t == MshQualityType::AREA) + checker = new Mesh_Group::MeshQualityNormalisedArea(mesh); + else if (t == MshQualityType::VOLUME) + checker = new Mesh_Group::MeshQualityNormalisedVolumes(mesh); + else if (t == MshQualityType::EQUIANGLESKEW) + checker = new Mesh_Group::MeshQualityEquiAngleSkew(mesh); + else { + std::cout << "Error in VtkVisPipeline::checkMeshQuality() - Unknown MshQualityType..." << std::endl; + delete checker; + return; + } + checker->check (); - /* - // simple suggestion: number of classes with Sturges criterion - size_t nclasses (static_cast<size_t>(1 + 3.3 * log (static_cast<float>((mesh->getElementVector()).size())))); - bool ok; - size_t size (static_cast<size_t>(QInputDialog::getInt(NULL, "OGS-Histogramm", "number of histogramm classes/spins (min: 1, max: 10000)", static_cast<int>(nclasses), 1, 10000, 1, &ok))); + std::vector<double> const &quality (checker->getMeshQuality()); - if (ok) + int nSources = this->_rootItem->childCount(); + for (int i=0; i<nSources; i++) { - std::vector<size_t> histogramm (size,0); - checker.getHistogramm(histogramm); - */ - std::vector<double> quality = checker.getMeshQuality(); - - int nSources = this->_rootItem->childCount(); - for (int i=0; i<nSources; i++) + VtkVisPipelineItem* parentItem = static_cast<VtkVisPipelineItem*>(_rootItem->child(i)); + if (parentItem->algorithm() == source) { - VtkVisPipelineItem* parentItem = static_cast<VtkVisPipelineItem*>(_rootItem->child(i)); - if (parentItem->algorithm() == source) - { - QList<QVariant> itemData; - itemData << "MeshQualityFilter" << true; - - VtkCompositeFilter* filter = VtkFilterFactory::CreateCompositeFilter("VtkCompositeSelectionFilter", parentItem->transformFilter()); - static_cast<VtkCompositeSelectionFilter*>(filter)->setSelectionArray(quality); - VtkVisPipelineItem* item = new VtkVisPipelineItem(filter, parentItem, itemData); - this->addPipelineItem(item, this->createIndex(i, 0, item)); - } - } - /* - std::ofstream out (file_name.toStdString().c_str()); - const size_t histogramm_size (histogramm.size()); - for (size_t k(0); k<histogramm_size; k++) { - out << k/static_cast<double>(histogramm_size) << " " << histogramm[k] << std::endl; + QList<QVariant> itemData; + itemData << "MeshQuality: " + QString::fromStdString(MshQualityType2String(t)) << true; + + VtkCompositeFilter* filter = VtkFilterFactory::CreateCompositeFilter("VtkCompositeSelectionFilter", parentItem->transformFilter()); + static_cast<VtkCompositeSelectionFilter*>(filter)->setSelectionArray(quality); + VtkVisPipelineItem* item = new VtkVisPipelineItem(filter, parentItem, itemData); + this->addPipelineItem(item, this->createIndex(i, 0, item)); } - out.close (); } - */ + + // *** 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->getElementVector()).size())))); +// bool ok; +// size_t size (static_cast<size_t>(QInputDialog::getInt(NULL, "OGS-Histogramm", "number of histogramm classes/spins (min: 1, max: 10000)", static_cast<int>(nclasses), 1, 10000, 1, &ok))); +// if (ok) ... + size_t size (1000); + std::vector<size_t> histogramm (size,0); + checker->getHistogramm(histogramm); + std::ofstream out ("mesh_histogramm.txt"); + const size_t histogramm_size (histogramm.size()); + for (size_t k(0); k<histogramm_size; k++) { + out << k/static_cast<double>(histogramm_size) << " " << histogramm[k] << std::endl; + } + out.close (); + + delete checker; } -} \ No newline at end of file +} diff --git a/VtkVis/VtkVisPipeline.h b/VtkVis/VtkVisPipeline.h index 37ee3384cd6e438feed305bfe141abeb1848a673..6951ccdf167614be39d288eaf28f3233afb46c3c 100644 --- a/VtkVis/VtkVisPipeline.h +++ b/VtkVis/VtkVisPipeline.h @@ -14,6 +14,8 @@ #include "Color.h" #include "Point.h" #include "GeoType.h" +#include "MSHEnums.h" +#include "FEMCondition.h" #include <QVector> #include <QMap> @@ -29,10 +31,11 @@ class vtkLight; class vtkPointSet; class vtkRenderer; class vtkProp3D; -class MshModel; class QModelIndex; class QString; class GeoTreeModel; +class ConditionModel; +class MshModel; class StationTreeModel; class TreeModel; class VtkVisPipelineItem; @@ -79,14 +82,22 @@ public: QModelIndex getIndex(vtkProp3D* actor); Qt::ItemFlags flags( const QModelIndex &index ) const; - - /// @brief Loads a vtk object from the given file and adds it to the pipeline. + + /// \brief Loads a vtk object from the given file and adds it to the pipeline. void loadFromFile(QString filename); + /// \brief Defaults to on. + void resetCameraOnAddOrRemove(bool reset) { _resetCameraOnAddOrRemove = reset; } + + /// \brief Sets a global superelevation factor on all source items and resets + /// the factor on other items to 1. + void setGlobalSuperelevation(double factor) const; + public slots: /// \brief Adds the given Model to the pipeline. void addPipelineItem(MshModel* model, const QModelIndex &idx); void addPipelineItem(GeoTreeModel* model, const std::string &name, GEOLIB::GEOTYPE type); + void addPipelineItem(ConditionModel* model, const std::string &name, FEMCondition::CondType type); void addPipelineItem(StationTreeModel* model, const std::string &name); void addPipelineItem(VtkVisPipelineItem* item, const QModelIndex &parent); @@ -96,6 +107,7 @@ public slots: /// \brief Removes the given Model (and all attached vtkAlgorithms) from the pipeline. void removeSourceItem(MshModel* model, const QModelIndex &idx); void removeSourceItem(GeoTreeModel* model, const std::string &name, GEOLIB::GEOTYPE type); + void removeSourceItem(ConditionModel* model, const std::string &name, FEMCondition::CondType type); void removeSourceItem(StationTreeModel* model, const std::string &name); /// \brief Removes the vtkAlgorithm at the given QModelIndex (and all attached @@ -103,7 +115,7 @@ public slots: void removePipelineItem(QModelIndex index); /// Checks the quality of a mesh and cal a filter to highlight deformed elements. - void checkMeshQuality(VtkMeshSource* mesh); + void checkMeshQuality(VtkMeshSource* mesh, MshQualityType::type t); private: void listArrays(vtkDataSet* dataSet); @@ -112,7 +124,8 @@ private: QVector<vtkAlgorithm*> _sources; std::list<vtkLight*> _lights; QMap<vtkProp3D*, QModelIndex> _actorMap; - + bool _resetCameraOnAddOrRemove; + #ifdef OGS_USE_OPENSG OSG::SimpleSceneManager* _sceneManager; #endif // OGS_USE_OPENSG @@ -121,7 +134,7 @@ private: signals: /// \brief Is emitted when a pipeline item was added or removed. - void vtkVisPipelineChanged(); + void vtkVisPipelineChanged() const; }; diff --git a/VtkVis/VtkVisPipelineItem.cpp b/VtkVis/VtkVisPipelineItem.cpp index f16c7f190df85be77025210cd2f4fe90c3b682a8..959f285bedab9d3d0ede09042a655983c31556ad 100644 --- a/VtkVis/VtkVisPipelineItem.cpp +++ b/VtkVis/VtkVisPipelineItem.cpp @@ -40,6 +40,8 @@ #include <vtkXMLImageDataWriter.h> #include <vtkImageActor.h> #include <vtkImageAlgorithm.h> +#include <vtkTubeFilter.h> +#include <vtkTriangleFilter.h> #include "VtkCompositeFilter.h" @@ -53,7 +55,8 @@ OSG::NodePtr VtkVisPipelineItem::rootNode = NullFC; vtkAlgorithm* algorithm, TreeItem* parentItem, const QList<QVariant> data /*= QList<QVariant>()*/) - : TreeItem(data, parentItem), _algorithm(algorithm), _compositeFilter(NULL), _transformFilter(NULL) + : TreeItem(data, parentItem), _actor(NULL), _algorithm(algorithm), _mapper(NULL), _renderer(NULL), + _compositeFilter(NULL), _transformFilter(NULL), _activeAttribute("") { VtkVisPipelineItem* visParentItem = dynamic_cast<VtkVisPipelineItem*>(parentItem); if (visParentItem) @@ -75,7 +78,8 @@ OSG::NodePtr VtkVisPipelineItem::rootNode = NullFC; VtkVisPipelineItem::VtkVisPipelineItem( VtkCompositeFilter* compositeFilter, TreeItem* parentItem, const QList<QVariant> data /*= QList<QVariant>()*/ ) - : TreeItem(data, parentItem), _compositeFilter(compositeFilter), _transformFilter(NULL) + : TreeItem(data, parentItem), _actor(NULL), _mapper(NULL), _renderer(NULL), + _compositeFilter(compositeFilter), _transformFilter(NULL), _activeAttribute("") { _algorithm = _compositeFilter->GetOutputAlgorithm(); VtkVisPipelineItem* visParentItem = dynamic_cast<VtkVisPipelineItem*>(parentItem); @@ -89,7 +93,8 @@ OSG::NodePtr VtkVisPipelineItem::rootNode = NullFC; VtkVisPipelineItem::VtkVisPipelineItem( vtkAlgorithm* algorithm, TreeItem* parentItem, const QList<QVariant> data /*= QList<QVariant>()*/) - : TreeItem(data, parentItem), _algorithm(algorithm), _compositeFilter(NULL), _transformFilter(NULL) + : TreeItem(data, parentItem), _actor(NULL), _algorithm(algorithm), _mapper(NULL), _renderer(NULL), + _compositeFilter(NULL), _transformFilter(NULL), _activeAttribute("") { VtkVisPipelineItem* visParentItem = dynamic_cast<VtkVisPipelineItem*>(parentItem); if (parentItem->parentItem()) @@ -104,7 +109,8 @@ OSG::NodePtr VtkVisPipelineItem::rootNode = NullFC; VtkVisPipelineItem::VtkVisPipelineItem( VtkCompositeFilter* compositeFilter, TreeItem* parentItem, const QList<QVariant> data /*= QList<QVariant>()*/) - : TreeItem(data, parentItem), _compositeFilter(compositeFilter), _transformFilter(NULL) + : TreeItem(data, parentItem), _actor(NULL), _mapper(NULL), _renderer(NULL), + _compositeFilter(compositeFilter), _transformFilter(NULL), _activeAttribute("") { _algorithm = _compositeFilter->GetOutputAlgorithm(); } @@ -213,7 +219,18 @@ void VtkVisPipelineItem::Initialize(vtkRenderer* renderer) } else { - _mapper->SetInputConnection(_transformFilter->GetOutputPort()); + // vtkTubeFilter generates triangle strips. These are not handled correctly + // by the OpenSG converter. So the strips are converted to ordinary triangles. + vtkTubeFilter* tubeFilter = dynamic_cast<vtkTubeFilter*>(_algorithm); + if (tubeFilter) + { + vtkSmartPointer<vtkTriangleFilter> triangulate = + vtkSmartPointer<vtkTriangleFilter>::New(); + triangulate->SetInputConnection(_transformFilter->GetOutputPort()); + _mapper->SetInputConnection(triangulate->GetOutputPort()); + } + else + _mapper->SetInputConnection(_transformFilter->GetOutputPort()); } _actor->SetMapper(_mapper); @@ -244,7 +261,6 @@ void VtkVisPipelineItem::Initialize(vtkRenderer* renderer) if (vtkProps) setVtkProperties(vtkProps); - // Copy properties from parent else { @@ -258,6 +274,7 @@ void VtkVisPipelineItem::Initialize(vtkRenderer* renderer) newProps->SetScalarVisibility(parentProps->GetScalarVisibility()); newProps->SetTexture(parentProps->GetTexture()); setVtkProperties(newProps); + vtkProps = newProps; parentItem = NULL; } else @@ -265,6 +282,19 @@ void VtkVisPipelineItem::Initialize(vtkRenderer* renderer) } } + // 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()); + } + } } void VtkVisPipelineItem::setVtkProperties(VtkAlgorithmProperties* vtkProps) @@ -272,27 +302,9 @@ void VtkVisPipelineItem::setVtkProperties(VtkAlgorithmProperties* vtkProps) QObject::connect(vtkProps, SIGNAL(ScalarVisibilityChanged(bool)), _mapper, SLOT(SetScalarVisibility(bool))); - //vtkProps->SetLookUpTable("c:/Project/BoreholeColourReferenceMesh.txt"); //HACK ... needs to be put in GUI - vtkImageAlgorithm* imageAlgorithm = dynamic_cast<vtkImageAlgorithm*>(_algorithm); if (imageAlgorithm==NULL) - { - QVtkDataSetMapper* mapper = dynamic_cast<QVtkDataSetMapper*>(_mapper); - if (mapper) - { - if (vtkProps->GetLookupTable() == NULL) // default color table - { - vtkLookupTable* lut = vtkLookupTable::New(); - vtkProps->SetLookUpTable(lut); - } - else // specific color table - { - _mapper->SetLookupTable(vtkProps->GetLookupTable()); - } - _mapper->SetScalarRange(_transformFilter->GetOutput()->GetScalarRange()); - _mapper->Update(); - } - } + this->setLookupTableForActiveScalar(); vtkActor* actor = dynamic_cast<vtkActor*>(_actor); if (actor) @@ -325,7 +337,6 @@ int VtkVisPipelineItem::writeToFile(const std::string &filename) const osgActor->SetVerbose(true); osgActor->UpdateOsg(); OSG::SceneFileHandler::the().write(osgActor->GetOsgRoot(), filename.c_str()); - osgActor->ClearOsg(); #else QMessageBox::warning(NULL, "Functionality not implemented", "Sorry but this program was not compiled with OpenSG support."); @@ -392,6 +403,7 @@ void VtkVisPipelineItem::SetActiveAttribute( const QString& name ) onPointData = false; else if (name.contains("Solid Color")) { + _activeAttribute = name; _mapper->ScalarVisibilityOff(); return; } @@ -424,9 +436,54 @@ void VtkVisPipelineItem::SetActiveAttribute( const QString& name ) _mapper->SetScalarRange(dataSet->GetScalarRange()); } - _mapper->SetScalarRange(range); + //_mapper->SetScalarRange(range); + this->setLookupTableForActiveScalar(); + _mapper->ScalarVisibilityOn(); _mapper->Update(); _activeAttribute = name; } } + +void VtkVisPipelineItem::setLookupTableForActiveScalar() +{ + VtkAlgorithmProperties* vtkProps = dynamic_cast<VtkAlgorithmProperties*>(_algorithm); + if (vtkProps) + { + QVtkDataSetMapper* mapper = dynamic_cast<QVtkDataSetMapper*>(_mapper); + if (mapper) + { + if (vtkProps->GetLookupTable(this->GetActiveAttribute()) == NULL) // default color table + { + vtkLookupTable* lut = vtkLookupTable::New(); + vtkProps->SetLookUpTable(GetActiveAttribute(), lut); + } + else // specific color table + { + _mapper->SetLookupTable(vtkProps->GetLookupTable(this->GetActiveAttribute())); + } + + _mapper->SetScalarRange(_transformFilter->GetOutput()->GetScalarRange()); + _mapper->Update(); + } + } +} + +void VtkVisPipelineItem::setScale(double x, double y, double z) const +{ + vtkTransform* transform = + static_cast<vtkTransform*>(this->transformFilter()->GetTransform()); + transform->Identity(); + transform->Scale(x, y, z); + this->transformFilter()->Modified(); + +} + +void VtkVisPipelineItem::setScaleOnChilds(double x, double y, double z) const +{ + for (int i = 0; i < this->childCount(); ++i) + { + VtkVisPipelineItem* child = this->child(i); + child->setScale(x, y, z); + } +} diff --git a/VtkVis/VtkVisPipelineItem.h b/VtkVis/VtkVisPipelineItem.h index 708b0c4149cd81cad55e561de1742cb68321956e..eb55d2fee0f4be14e0537fd17eceafca993800ae 100644 --- a/VtkVis/VtkVisPipelineItem.h +++ b/VtkVis/VtkVisPipelineItem.h @@ -90,6 +90,13 @@ public: /// @brief Gets the last selected attribute. const QString& GetActiveAttribute() const {return _activeAttribute; } + + /// @brief Sets the geometry and data scaling. + void setScale(double x, double y, double z) const; + + /// @brief Sets the geometry and date scaling recursively on all childs of + /// this item. + void setScaleOnChilds(double x, double y, double z) const; #ifdef OGS_USE_OPENSG // HACK static rootNode is set by VtkVisPipeline constructor @@ -110,6 +117,9 @@ protected: vtkTransformFilter* _transformFilter; QString _activeAttribute; + /// Sets a color lookup table for the current scalar array. + void setLookupTableForActiveScalar(); + /// @brief Sets pre-set properties on vtkActor and on vtkMapper void setVtkProperties(VtkAlgorithmProperties* vtkProps); diff --git a/VtkVis/VtkVisPipelineView.cpp b/VtkVis/VtkVisPipelineView.cpp index dec116ad43eb81384817b7b9595cd70d4e2731c6..5e9c7f3cf91bbb352d9a254aae1ca16ac63992be 100644 --- a/VtkVis/VtkVisPipelineView.cpp +++ b/VtkVis/VtkVisPipelineView.cpp @@ -33,6 +33,8 @@ #include <vtkUnstructuredGrid.h> #include <vtkXMLUnstructuredGridReader.h> #include <vtkGenericDataObjectReader.h> +#include <vtkUnstructuredGridAlgorithm.h> +#include <vtkTransformFilter.h> VtkVisPipelineView::VtkVisPipelineView( QWidget* parent /*= 0*/ ) : QTreeView(parent) @@ -59,20 +61,30 @@ void VtkVisPipelineView::contextMenuEvent( QContextMenuEvent* event ) QModelIndex index = selectionModel()->currentIndex(); if (index.isValid()) { - // check if object is an image data object - int objectType = static_cast<VtkVisPipelineItem*>(static_cast<VtkVisPipeline*>(this->model())->getItem(this->selectionModel()->currentIndex()))->algorithm()->GetOutputDataObject(0)->GetDataObjectType(); + // check object type + vtkAlgorithm* algorithm = static_cast<VtkVisPipelineItem*>(static_cast<VtkVisPipeline*>(this->model())->getItem(this->selectionModel()->currentIndex()))->algorithm(); + int objectType = algorithm->GetOutputDataObject(0)->GetDataObjectType(); + VtkAlgorithmProperties* vtkProps = dynamic_cast<VtkAlgorithmProperties*>(algorithm); bool isSourceItem = (this->selectionModel()->currentIndex().parent().isValid()) ? 0 : 1; QMenu menu; QAction* addFilterAction = menu.addAction("Add filter..."); - QAction* addMeshingAction = NULL; + + QAction* addLUTAction(NULL); + QAction* addMeshingAction(NULL); if (objectType == VTK_IMAGE_DATA) { isSourceItem = false; // this exception is needed as image object are only displayed in the vis-pipeline addMeshingAction = menu.addAction("Convert Image to Mesh..."); connect(addMeshingAction, SIGNAL(triggered()), this, SLOT(convertImageToMesh())); } - QAction* addConvertToCFEMeshAction = NULL; + else + { + addLUTAction = menu.addAction("Add color table..."); + connect(addLUTAction, SIGNAL(triggered()), this, SLOT(addColorTable())); + } + + QAction* addConvertToCFEMeshAction(NULL); if (objectType == VTK_UNSTRUCTURED_GRID) { addConvertToCFEMeshAction = menu.addAction("Convert to Mesh..."); @@ -82,7 +94,7 @@ void VtkVisPipelineView::contextMenuEvent( QContextMenuEvent* event ) QAction* exportVtkAction = menu.addAction("Export as VTK"); QAction* exportOsgAction = menu.addAction("Export as OpenSG"); QAction* removeAction = NULL; - if (!isSourceItem) + if (!isSourceItem || vtkProps==NULL) { removeAction = menu.addAction("Remove"); connect(removeAction, SIGNAL(triggered()), this, SLOT(removeSelectedPipelineItem())); @@ -101,10 +113,10 @@ void VtkVisPipelineView::exportSelectedPipelineItemAsVtk() QSettings settings("UFZ", "OpenGeoSys-5"); QModelIndex idx = this->selectionModel()->currentIndex(); QString filename = QFileDialog::getSaveFileName(this, "Export object to vtk-file", - settings.value("lastExportedFileDirectory").toString(),"VTK file (*.vtk)"); + settings.value("lastExportedFileDirectory").toString(),"(*.*)"); if (!filename.isEmpty()) { - static_cast<VtkVisPipelineItem*>(static_cast<VtkVisPipeline*>(this->model())->getItem(idx))->writeToFile(filename.toStdString()); + static_cast<VtkVisPipelineItem*>(static_cast<VtkVisPipeline*>(this->model())->getItem(idx))->writeToFile(filename.toStdString()); QDir dir = QDir(filename); settings.setValue("lastExportedFileDirectory", dir.absolutePath()); } @@ -150,16 +162,20 @@ void VtkVisPipelineView::convertImageToMesh() void VtkVisPipelineView::convertVTKToOGSMesh() { vtkSmartPointer<vtkAlgorithm> algorithm = static_cast<VtkVisPipelineItem*>(static_cast<VtkVisPipeline*>(this->model())->getItem(this->selectionModel()->currentIndex()))->algorithm(); + vtkUnstructuredGrid* grid(NULL); - - vtkGenericDataObjectReader* dataReader = vtkGenericDataObjectReader::SafeDownCast(algorithm); // for old filetypes - if (dataReader) grid = vtkUnstructuredGrid::SafeDownCast(dataReader->GetOutput()); + vtkUnstructuredGridAlgorithm* ugAlg = vtkUnstructuredGridAlgorithm::SafeDownCast(algorithm); + if (ugAlg) grid = ugAlg->GetOutput(); else { - vtkXMLUnstructuredGridReader* xmlReader = vtkXMLUnstructuredGridReader::SafeDownCast(algorithm); // for new filetypes - grid = vtkUnstructuredGrid::SafeDownCast(xmlReader->GetOutput()); + vtkGenericDataObjectReader* dataReader = vtkGenericDataObjectReader::SafeDownCast(algorithm); // for old filetypes + if (dataReader) grid = vtkUnstructuredGrid::SafeDownCast(dataReader->GetOutput()); + else + { + vtkXMLUnstructuredGridReader* xmlReader = vtkXMLUnstructuredGridReader::SafeDownCast(algorithm); // for new filetypes + grid = vtkUnstructuredGrid::SafeDownCast(xmlReader->GetOutput()); + } } - Mesh_Group::CFEMesh* mesh = GridAdapter::convertUnstructuredGrid(grid); std::string msh_name("NewMesh"); emit meshAdded(mesh, msh_name); @@ -175,11 +191,13 @@ void VtkVisPipelineView::selectionChanged( const QItemSelection &selected, const 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((vtkProp3D*)NULL); + emit actorSelected(NULL); emit itemSelected(NULL); + emit dataObjectSelected(NULL); } } @@ -196,3 +214,27 @@ void VtkVisPipelineView::selectItem( vtkProp3D* actor ) selectionModel->select(index, QItemSelectionModel::Select); blockSignals(false); } + +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("UFZ", "OpenGeoSys-5"); + QString fileName = QFileDialog::getOpenFileName(this, "Select color table", + settings.value("lastOpenedTextureFileDirectory").toString(), + "Color table files (*.lut);;"); + QFileInfo fi(fileName); + + if (fi.suffix().toLower() == "lut") + { + VtkAlgorithmProperties* props = dynamic_cast<VtkAlgorithmProperties*>(item->algorithm()); + if (props) + { + const std::string file (fileName.toStdString()); + props->SetLookUpTable(array_name, file); + item->SetActiveAttribute(array_name); + emit requestViewUpdate(); + } + } +} diff --git a/VtkVis/VtkVisPipelineView.h b/VtkVis/VtkVisPipelineView.h index 3db2610b5509552b5af4ba9f0416081e36080cba..7605a6de06de9d0ec5a224b344fa923bd3bb7a65 100644 --- a/VtkVis/VtkVisPipelineView.h +++ b/VtkVis/VtkVisPipelineView.h @@ -15,6 +15,7 @@ class QItemSelection; class QAbstractItemModel; class VtkVisPipelineItem; class vtkProp3D; +class vtkDataObject; namespace Mesh_Group { class CFEMesh; @@ -44,6 +45,8 @@ private: void contextMenuEvent(QContextMenuEvent* event); private slots: + /// Adds a color lookup table to the current scalar array of the selected pipeline item. + void addColorTable(); /// Exports the currently selected item as a VTK file void exportSelectedPipelineItemAsVtk(); @@ -65,12 +68,13 @@ private slots: void convertVTKToOGSMesh(); signals: + void requestViewUpdate(); void requestRemovePipelineItem(QModelIndex); void requestAddPipelineFilterItem(QModelIndex); void itemSelected(VtkVisPipelineItem*); void actorSelected(vtkProp3D*); + void dataObjectSelected(vtkDataObject*); void meshAdded(Mesh_Group::CFEMesh*, std::string&); - }; #endif // VTKVISPIPELINEVIEW_H diff --git a/VtkVis/VtkVisTabWidget.cpp b/VtkVis/VtkVisTabWidget.cpp index d32a57f5de8a0c30fbcef117d1ddee467f6f328e..9d335712ce88158c3529e902e923b6ec394b191c 100644 --- a/VtkVis/VtkVisTabWidget.cpp +++ b/VtkVis/VtkVisTabWidget.cpp @@ -35,6 +35,9 @@ VtkVisTabWidget::VtkVisTabWidget( QWidget* parent /*= 0*/ ) this->scaleZ->setValidator(new QDoubleValidator(0, 100, 8, this)); + connect(this->vtkVisPipelineView, SIGNAL(requestViewUpdate()), + this, SIGNAL(requestViewUpdate())); + connect(this->vtkVisPipelineView, SIGNAL(itemSelected(VtkVisPipelineItem*)), this, SLOT(setActiveItem(VtkVisPipelineItem*))); @@ -64,7 +67,7 @@ void VtkVisTabWidget::setActiveItem( VtkVisPipelineItem* item ) transform->GetScale(scale); scaleZ->setText(QString::number(scale[2])); - this->buildScalarArrayComboBox(_item->algorithm()); + this->buildScalarArrayComboBox(_item); // Set to last active attribute QString activeAttribute = item->GetActiveAttribute(); @@ -156,12 +159,8 @@ void VtkVisTabWidget::on_scaleZ_textChanged(const QString &text) if (ok) { - vtkTransform* transform = - static_cast<vtkTransform*>(_item->transformFilter()->GetTransform()); - transform->Identity(); - transform->Scale(1.0, 1.0, scale); - _item->transformFilter()->Modified(); - + _item->setScale(1.0, 1.0, scale); + for (int i = 0; i < _item->childCount(); i++) { VtkVisPipelineItem* childItem = _item->child(i); @@ -270,9 +269,9 @@ void VtkVisTabWidget::buildProportiesDialog(VtkVisPipelineItem* item) } } -void VtkVisTabWidget::buildScalarArrayComboBox(vtkAlgorithm* algorithm) +void VtkVisTabWidget::buildScalarArrayComboBox(VtkVisPipelineItem* item) { - vtkDataSet* dataSet = vtkDataSet::SafeDownCast(algorithm->GetOutputDataObject(0)); + vtkDataSet* dataSet = vtkDataSet::SafeDownCast(item->algorithm()->GetOutputDataObject(0)); QStringList dataSetAttributesList; if (dataSet) { @@ -299,6 +298,9 @@ void VtkVisTabWidget::buildScalarArrayComboBox(vtkAlgorithm* algorithm) this->activeScalarComboBox->clear(); this->activeScalarComboBox->insertItems(0, dataSetAttributesList); this->activeScalarComboBox->blockSignals(false); + QList<QString>::iterator it = dataSetAttributesList.begin(); + if (item->GetActiveAttribute().count() == 0) + item->SetActiveAttribute(*it); } void VtkVisTabWidget::addColorTable() diff --git a/VtkVis/VtkVisTabWidget.h b/VtkVis/VtkVisTabWidget.h index 5387071eb3c519e6d00aa7f7f96d2815a720cf71..26e032b2ac7730941493f2777c19684fb344362c 100644 --- a/VtkVis/VtkVisTabWidget.h +++ b/VtkVis/VtkVisTabWidget.h @@ -44,7 +44,7 @@ private: void buildProportiesDialog(VtkVisPipelineItem* item); /// Reads the scalar arrays of the given vtk-object and constructs content for the scalar array selection box. - void buildScalarArrayComboBox(vtkAlgorithm* algorithm); + void buildScalarArrayComboBox(VtkVisPipelineItem* item); VtkVisPipelineItem* _item; signals: diff --git a/VtkVis/VtkVisTabWidgetBase.ui b/VtkVis/VtkVisTabWidgetBase.ui index c0ae002a680d80fe309fa9a6497d74b6596d2624..07be0bde26e78fbad680454f982d34b81b9578ae 100644 --- a/VtkVis/VtkVisTabWidgetBase.ui +++ b/VtkVis/VtkVisTabWidgetBase.ui @@ -101,7 +101,7 @@ </widget> </item> <item row="4" column="1"> - <widget class="QSlider" name="opacitySlider"> + <widget class="QValueTooltipSlider" name="opacitySlider"> <property name="maximum"> <number>100</number> </property> @@ -199,15 +199,20 @@ </layout> </widget> <customwidgets> + <customwidget> + <class>ColorPickerPushButton</class> + <extends>QPushButton</extends> + <header>ColorPickerPushButton.h</header> + </customwidget> <customwidget> <class>VtkVisPipelineView</class> <extends>QTreeView</extends> <header>VtkVisPipelineView.h</header> </customwidget> <customwidget> - <class>ColorPickerPushButton</class> - <extends>QPushButton</extends> - <header>ColorPickerPushButton.h</header> + <class>QValueTooltipSlider</class> + <extends>QSlider</extends> + <header>QValueTooltipSlider.h</header> </customwidget> </customwidgets> <resources/>