Commit ee37db61 by Sebastian Eichelbaum

[FIX] - fixed merge problems and a crash on module removal

parents 9f970e5a e24a46eb
......@@ -119,96 +119,6 @@ std::vector< size_t > WHierarchicalTree::findXBiggestClusters( size_t cluster, s
return returnVector;
}
std::vector< size_t > WHierarchicalTree::findXBiggestClusters2( size_t cluster, size_t number )
{
//std::cout << number << " largest clusters for cluster: " << cluster << std::endl;
if ( number > m_containsLeafes[cluster].size() )
{
number = m_containsLeafes[cluster].size();
}
// init
std::list<size_t>worklist;
worklist.push_back( cluster );
while ( worklist.size() < number )
{
size_t current = worklist.front();
worklist.pop_front();
if ( m_containsLeafes[current].size() > 1 )
{
size_t left = m_children[current].first;
size_t right = m_children[current].second;
worklist.push_back( left );
worklist.push_back( right );
}
else
{
worklist.push_back( current );
}
}
worklist.sort( compSize( this ) );
bool newSplit = true;
while ( newSplit )
{
newSplit = false;
size_t current = worklist.front();
if ( m_containsLeafes[current].size() > 1 )
{
size_t left = m_children[current].first;
size_t right = m_children[current].second;
size_t last = worklist.back();
if ( ( m_containsLeafes[left].size() > m_containsLeafes[last].size() ) &&
( m_containsLeafes[right].size() > m_containsLeafes[last].size() ) )
{
if ( m_containsLeafes[left].size() > m_containsLeafes[last].size() )
{
worklist.pop_front();
worklist.push_back( left );
worklist.sort( compSize( this ) );
newSplit = true;
}
last = worklist.back();
if ( m_containsLeafes[right].size() > m_containsLeafes[last].size() )
{
if ( !newSplit )
{
worklist.pop_front();
}
if ( worklist.size() == number )
{
worklist.pop_back();
}
worklist.push_back( right );
worklist.sort( compSize( this ) );
newSplit = true;
}
}
}
}
std::vector<size_t>returnVector;
std::list<size_t>::iterator it;
for ( it = worklist.begin(); it != worklist.end(); ++it )
{
size_t current = *it;
//std::cout << "cluster:" << current << " size:" << m_containsLeafes[current].size() << std::endl;
returnVector.push_back( current );
}
return returnVector;
}
std::vector< size_t > WHierarchicalTree::downXLevelsFromTop( size_t level, bool hideOutliers )
{
if ( level > m_maxLevel )
......
......@@ -153,14 +153,6 @@ public:
*/
std::vector< size_t >findXBiggestClusters( size_t cluster, size_t number = 10 );
// TODO(schurade): merge these two function
/**
* finds the X biggest clusters for a given cluster
* \param cluster
* \param number of sub clusters
*/
std::vector< size_t >findXBiggestClusters2( size_t cluster, size_t number = 10 );
/**
* sets the color for a selected cluster and all sub clusters
* \param cluster
......
......@@ -254,10 +254,12 @@ std::ostream& operator<<( std::ostream& out, const WValueSetHistogram& h )
{
std::pair< double, double > interval = h.getIntervalForIndex( i );
// NOTE: the notation for open intervals is [a,b) or alternatively [a,b[.
out << i << " = [" << interval.first << ", " << interval.second << ") = " << h[ i ] << std::endl;
//out << i << " = [" << interval.first << ", " << interval.second << ") = " << h[ i ] << std::endl;
out << interval.first << " " << interval.second << " " << std::min( h[ i ], size_t( 3000 ) ) << std::endl;
}
// the last interval is handled special
out << h.size() - 1 << " = [" << h.getIntervalForIndex( h.size() - 1 ).first << ", inf) = " << h[ h.size() - 1 ] << std::endl;
//out << h.size() - 1 << " = [" << h.getIntervalForIndex( h.size() - 1 ).first << ", inf) = " << h[ h.size() - 1 ] << std::endl;
out << h.getIntervalForIndex( h.size() - 1 ).first << " inf " << std::min( h[ h.size() - 1 ], size_t( 3000 ) ) << std::endl;
return out;
}
......
......@@ -270,12 +270,12 @@ inline size_t WValueSetHistogram::getIndexForValue( double value ) const
// the position on the scala
double pos = ( value - m_minimum ) / static_cast< double >( m_mappedBucketSize );
// the index is the floor( position )
size_t idx = static_cast< size_t >( pos );
size_t idx = static_cast< size_t >( std::floor( pos ) );
// is the index larger than the size?
bool inU = ( idx < m_nMappedBuckets );
// is the index smaller than the size?
bool inL = ( pos > 0.0 );
bool inL = ( pos >= 0.0 );
// the trick done here is to clamp value into [m_minimum,m_maximum] without using if statements. The C++ Standard says that booleans are
// always 1 if true.
......
......@@ -107,7 +107,7 @@ osg::ref_ptr< osg::Image > wge::genWhiteNoiseImage( size_t sizeX, size_t sizeY,
for( size_t i = 0; i < channels * sizeX * sizeY * sizeZ; ++i )
{
// - stylechecker says "use rand_r" but I am not sure about portability.
unsigned char r = ( unsigned char )( std::rand() % 255 ); // NOLINT
unsigned char r = static_cast< unsigned char >( std::rand() % 255 ); // NOLINT
randomLuminance[ i ] = r;
}
......
......@@ -171,7 +171,7 @@ void wge::bindTexture( osg::ref_ptr< osg::Node > node, osg::ref_ptr< WGETexture<
wge::bindTexture< T >( node, osg::ref_ptr< T >( texture ), unit, prefix );
// set the texture matrix to the stateset
osg::TexMat* texMat = new osg::TexMat( osg::Matrix::identity() );
osg::TexMat* texMat = new osg::TexMat( texture->transformation()->get() );
// use a callback to update the tex matrix if needed according to transformation property of texture
texMat->setUpdateCallback( new WGEPropertyTransformationCallback< osg::StateAttribute, osg::TexMat >( texture->transformation() ) );
node->getOrCreateStateSet()->setTextureAttributeAndModes( unit, texMat, osg::StateAttribute::ON );
......
......@@ -399,9 +399,9 @@ boost::shared_ptr<WTriangleMesh> WMarchingLegoAlgorithm::genSurfaceOneValue( siz
resultPos4D[3] = m_matrix( 3, 0 ) * pos[0] + m_matrix( 3, 1 ) * pos[1] + m_matrix( 3, 2 ) * pos[2] + m_matrix( 3, 3 ) * 1;
( *mapIterator ).second.newID = nextID;
triMesh->addVertex( resultPos4D[0] / resultPos4D[3] - 0.5,
resultPos4D[1] / resultPos4D[3] - 0.5,
resultPos4D[2] / resultPos4D[3] - 0.5 );
triMesh->addVertex( resultPos4D[0] / resultPos4D[3],
resultPos4D[1] / resultPos4D[3],
resultPos4D[2] / resultPos4D[3] );
triMesh->addTextureCoordinate( texCoord );
nextID++;
mapIterator++;
......
......@@ -253,9 +253,9 @@ template<typename T> boost::shared_ptr<WTriangleMesh> WMarchingLegoAlgorithm::ge
resultPos4D[3] = m_matrix( 3, 0 ) * pos[0] + m_matrix( 3, 1 ) * pos[1] + m_matrix( 3, 2 ) * pos[2] + m_matrix( 3, 3 ) * 1;
( *mapIterator ).second.newID = nextID;
triMesh->addVertex( resultPos4D[0] / resultPos4D[3] - 0.5,
resultPos4D[1] / resultPos4D[3] - 0.5,
resultPos4D[2] / resultPos4D[3] - 0.5 );
triMesh->addVertex( resultPos4D[0] / resultPos4D[3],
resultPos4D[1] / resultPos4D[3],
resultPos4D[2] / resultPos4D[3] );
triMesh->addTextureCoordinate( texCoord );
nextID++;
mapIterator++;
......
......@@ -284,6 +284,7 @@ void WQt4Gui::slotActivateDatasetOrModuleInTree( boost::shared_ptr< WModule > mo
{
// create a new event for this and insert it into event queue
QCoreApplication::postEvent( m_mainWindow->getControlPanel(), new WModuleReadyEvent( module ) );
QCoreApplication::postEvent( m_mainWindow, new WModuleReadyEvent( module ) );
QCoreApplication::postEvent( m_mainWindow->getNetworkEditor(), new WModuleReadyEvent( module ) );
}
......
......@@ -65,6 +65,10 @@ WPropertyWidget::WPropertyWidget( boost::shared_ptr< WPropertyBase > property,
setCurrentIndex( 1 );
}
// if the property is hidden initially, hide widget too
setHidden( m_property->isHidden() );
m_label.setHidden( m_property->isHidden() );
// setup the update callback
m_connection = m_property->getUpdateCondition()->subscribeSignal( boost::bind( &WPropertyWidget::propertyChangeNotifier, this ) );
}
......
......@@ -804,13 +804,16 @@ void WQtControlPanel::selectDataModule( boost::shared_ptr< WDataSet > dataSet )
void WQtControlPanel::setNewActiveModule( boost::shared_ptr< WModule > module )
{
buildPropTab( module->getProperties(), module->getInformationProperties() );
m_tabWidget->clear();
if ( module )
{
buildPropTab( module->getProperties(), module->getInformationProperties() );
}
}
WQtPropertyGroupWidget* WQtControlPanel::buildPropWidget( boost::shared_ptr< WProperties > props )
{
WQtPropertyGroupWidget* tab = new WQtPropertyGroupWidget( props->getName() );
WQtPropertyGroupWidget* tab = new WQtPropertyGroupWidget( props );
if ( props.get() )
{
// read lock, gets unlocked upon destruction (out of scope)
......@@ -821,47 +824,44 @@ WQtPropertyGroupWidget* WQtControlPanel::buildPropWidget( boost::shared_ptr< WP
// iterate all properties.
for ( WProperties::PropertyConstIterator iter = propAccess->get().begin(); iter != propAccess->get().end(); ++iter )
{
if ( !( *iter )->isHidden() )
switch ( ( *iter )->getType() )
{
switch ( ( *iter )->getType() )
{
case PV_BOOL:
tab->addProp( ( *iter )->toPropBool() );
break;
case PV_INT:
tab->addProp( ( *iter )->toPropInt() );
break;
case PV_DOUBLE:
tab->addProp( ( *iter )->toPropDouble() );
break;
case PV_STRING:
tab->addProp( ( *iter )->toPropString() );
break;
case PV_PATH:
tab->addProp( ( *iter )->toPropFilename() );
break;
case PV_SELECTION:
tab->addProp( ( *iter )->toPropSelection() );
break;
case PV_COLOR:
tab->addProp( ( *iter )->toPropColor() );
break;
case PV_POSITION:
tab->addProp( ( *iter )->toPropPosition() );
break;
case PV_TRIGGER:
tab->addProp( ( *iter )->toPropTrigger() );
break;
case PV_GROUP:
tab->addGroup( buildPropWidget( ( *iter )->toPropGroup() ) );
break;
case PV_MATRIX4X4:
tab->addProp( ( *iter )->toPropMatrix4X4() );
break;
default:
WLogger::getLogger()->addLogMessage( "This property type is not yet supported.", "ControlPanel", LL_WARNING );
break;
}
case PV_BOOL:
tab->addProp( ( *iter )->toPropBool() );
break;
case PV_INT:
tab->addProp( ( *iter )->toPropInt() );
break;
case PV_DOUBLE:
tab->addProp( ( *iter )->toPropDouble() );
break;
case PV_STRING:
tab->addProp( ( *iter )->toPropString() );
break;
case PV_PATH:
tab->addProp( ( *iter )->toPropFilename() );
break;
case PV_SELECTION:
tab->addProp( ( *iter )->toPropSelection() );
break;
case PV_COLOR:
tab->addProp( ( *iter )->toPropColor() );
break;
case PV_POSITION:
tab->addProp( ( *iter )->toPropPosition() );
break;
case PV_TRIGGER:
tab->addProp( ( *iter )->toPropTrigger() );
break;
case PV_GROUP:
tab->addGroup( buildPropWidget( ( *iter )->toPropGroup() ) );
break;
case PV_MATRIX4X4:
tab->addProp( ( *iter )->toPropMatrix4X4() );
break;
default:
WLogger::getLogger()->addLogMessage( "This property type is not yet supported.", "ControlPanel", LL_WARNING );
break;
}
}
}
......
......@@ -24,18 +24,45 @@
#include <string>
#include <QtGui/QApplication>
#include <QtGui/QGroupBox>
#include <QtGui/QPushButton>
#include <QtGui/QScrollArea>
#include "../events/WEventTypes.h"
#include "../events/WPropertyChangedEvent.h"
#include "../../../common/WProperties.h"
#include "WQtPropertyGroupWidget.h"
WQtPropertyGroupWidget::WQtPropertyGroupWidget( WPropGroup group, QWidget* parent )
: QWidget( parent ),
m_name( group->getName().c_str() ),
m_numberOfWidgets( 0 ),
m_group( group )
{
// note: never do layouts as none pointers
// on destruction of a widget it will try to delete them which will cause crashes
m_pageLayout = new QVBoxLayout();
m_controlLayout = new QGridLayout();
m_pageLayout->addLayout( m_controlLayout );
// NOTE: a simple setHidden( group->isHidden() ) causes the QWidgets to popup if hidden is false. This is why we set hidden only if it really
// is needed
if ( group->isHidden() )
{
setHidden( true );
}
// setup the update callback
m_connection = m_group->getUpdateCondition()->subscribeSignal( boost::bind( &WQtPropertyGroupWidget::propertyChangeNotifier, this ) );
}
WQtPropertyGroupWidget::WQtPropertyGroupWidget( std::string name, QWidget* parent )
: QWidget( parent ),
m_name( name.c_str() ),
// m_controlLayout(),
// m_pageLayout(),
m_numberOfWidgets( 0 )
m_numberOfWidgets( 0 ),
m_group()
{
// note: never do layouts as none pointers
// on destruction of a widget it will try to delete them which will cause crashes
......@@ -46,6 +73,26 @@ WQtPropertyGroupWidget::WQtPropertyGroupWidget( std::string name, QWidget* paren
WQtPropertyGroupWidget::~WQtPropertyGroupWidget()
{
// cleanup
m_connection.disconnect();
}
void WQtPropertyGroupWidget::propertyChangeNotifier()
{
QCoreApplication::postEvent( this, new WPropertyChangedEvent() );
}
bool WQtPropertyGroupWidget::event( QEvent* event )
{
// a property changed
if ( event->type() == WQT_PROPERTY_CHANGED_EVENT )
{
setHidden( m_group->isHidden() );
emit hideSignal( m_group->isHidden() );
return true;
}
return QWidget::event( event );
}
WPropertyBoolWidget* WQtPropertyGroupWidget::addProp( WPropBool property )
......@@ -177,6 +224,10 @@ void WQtPropertyGroupWidget::addGroup( WQtPropertyGroupWidget* widget, bool asSc
// insert into layout
int row = m_controlLayout->rowCount();
m_controlLayout->addWidget( box, row, 0, 1, 2 );
// hide the box too if the property gets hidden
box->setHidden( widget->isHidden() );
connect( widget, SIGNAL( hideSignal( bool ) ), box, SLOT( setHidden( bool ) ) );
}
void WQtPropertyGroupWidget::addSpacer()
......
......@@ -52,11 +52,18 @@ class WQtPropertyGroupWidget : public QWidget
public:
/**
* Creates new widget for a property group. Use this constructor to provide automatic hidden-flag management.
* \param group The group
* \param parent The widget managing this widget
*/
WQtPropertyGroupWidget( WPropGroup group, QWidget* parent = 0 );
/**
* Creates new widget for a property group
* \param name Name of the widget
* \param parent The widget managing this widget
*/
explicit WQtPropertyGroupWidget( std::string name, QWidget* parent = 0 );
WQtPropertyGroupWidget( std::string name, QWidget* parent = 0 );
/**
* destructor
......@@ -191,7 +198,33 @@ public:
*/
void setName( QString name );
signals:
/**
* A Signal which gets emitted whenever the widget should be hidden. This is a useful signal for containers which embed this group.
*
* \param hide if true, the widget should be hidden.
*/
void hideSignal( bool hide );
protected:
/**
* Callback for WPropertyBase::getChangeCondition. It emits an event to ensure all updates are done in gui thread.
*/
virtual void propertyChangeNotifier();
/**
* Custom event dispatcher. Gets called by QT's Event system every time an event got sent to this widget. This event handler
* processes property change events.
*
* \note QT Doc says: use event() for custom events.
* \param event the event that got transmitted.
*
* \return true if the event got handled properly.
*/
virtual bool event( QEvent* event );
private:
/**
......@@ -213,6 +246,16 @@ private:
* The number of widgets inside this one.
*/
unsigned int m_numberOfWidgets;
/**
* The property group handled here.
*/
WPropGroup m_group;
/**
* The connection for propertyChangeNotifier().
*/
boost::signals2::connection m_connection;
};
#endif // WQTPROPERTYGROUPWIDGET_H
......@@ -391,7 +391,7 @@ bool WQtNetworkEditor::event( QEvent* event )
if( item != 0 )
{
item->activate( false );
//e->getModule()->requestStop(); // TODO(rfrohl): do we need this ?
e->getModule()->requestStop(); // TODO(rfrohl): do we need this ?
}
return true;
......
......@@ -35,6 +35,7 @@
#include "../../dataHandler/WDataHandler.h"
#include "../../dataHandler/WDataSetScalar.h"
#include "../../dataHandler/WDataTexture3D.h"
#include "../../graphicsEngine/WGETexture.h"
#include "../../dataHandler/WSubject.h"
#include "../../dataHandler/WValueSet.h"
#include "../../graphicsEngine/geodes/WDendrogramGeode.h"
......@@ -186,6 +187,17 @@ private:
*/
void dendrogramClick( WPickInfo pickInfo );
/**
* update the output connector on demand, for performance reasons this is not done every time
* a change to the cluster selection is applied
*/
void updateOutDataset();
/**
* helper function to set the label on the in scene buttons depending on which labeling scheme is selected
*/
void setButtonLabels();
/**
* An input connector that accepts order 1 datasets.
......@@ -218,6 +230,12 @@ private:
osg::ref_ptr<osg::Texture3D>m_texture;
/**
* stores a pointer to the texture we paint in
*/
// osg::ref_ptr< WGETexture3D > m_texture;
/**
* label vector for texture creation
*/
std::vector< size_t >m_data;
......@@ -316,12 +334,6 @@ private:
*/
WPropGroup m_groupTriangulation;
/**
* grouping the properties controlling cluster selection for minimum branch length
*/
WPropGroup m_groupMinBranchLength;
/**
* controls the display of the dendrogram overlay
*/
......@@ -394,6 +406,36 @@ private:
WPropInt m_infoMaxLevel; //!< info property
std::vector< std::vector<size_t> >m_loadedPartitions; //!< set partitions loaded from file
/**
* updates the output connector on demand, as we don't want to do this every paint command
*/
WPropTrigger m_buttonUpdateOutput;
/**
* A list of cluster selection methods
*/
boost::shared_ptr< WItemSelection > m_clusterSelectionsList;
/**
* Selection property for clusters
*/
WPropSelection m_clusterSelection;
/**
* triggers the cluster selection update
*/
WPropTrigger m_buttonExecuteSelection;
/**
* A list of button labels
*/
boost::shared_ptr< WItemSelection > m_buttonLabelList;
/**
* Selection property for button labels
*/
WPropSelection m_buttonLabelSelection;
};
#endif // WMCLUSTERDISPLAYVOXELS_H
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#version 120
void main()
{
gl_FragColor = gl_Color;
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//--------------------------------------------------------------------------
#version 120
mat4 translate(float x, float y, float z)
{
return mat4(
vec4(1.0, 0.0, 0.0, 0.0),
vec4(0.0, 1.0, 0.0, 0.0),
vec4(0.0, 0.0, 1.0, 0.0),
vec4(x, y, z, 0.0)
);
}
void main ()
{
//gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
//gl_Position = ftransform();
gl_FrontColor = gl_Color;
vec4 v = gl_Vertex;
v[3] = 0.0;
gl_Position = gl_ModelViewProjectionMatrix * v ;
}
......@@ -23,6 +23,7 @@
//---------------------------------------------------------------------------
#include <vector>
#include <fstream>
#include <string>
#include "../../kernel/WKernel.h"
......@@ -211,16 +212,21 @@ void WMHistogramEqualization::moduleMain()
curI++;
}
debugLog() << "Clamped " << perc << "% resulting in new interval ["<< lower << ", " << upper <<").";
debugLog() << "Clamped " << perc << "% of [" << hist->getMinimum() << ", " << hist->getMaximum() << "]" <<
" resulting in new interval [" << lower << ", " << upper <<").";
// with this new interval, extract a new histogram and use it for equalization
hist = boost::shared_ptr< const WValueSetHistogram >( new WValueSetHistogram( valueSet, lower, upper, cdfHistRes ) );
}
// the new data
std::vector< unsigned char > newData;
std::vector< double > newData;
newData.resize( hist->getTotalElementCount(), 0 );
// these values are needed to rescale the data to the original interval
double valueMin = hist->getMinimum();
double valueScaler = hist->getMaximum() - valueMin;
// equalize?
++*progress;
if ( m_equalize->get( true ) )
......@@ -232,24 +238,23 @@ void WMHistogramEqualization::moduleMain()
// go through each CDF item and fill it, which is the sum of all previous items in hist
size_t accum = 0;
double cdfMin = ( *hist )[ 0 ];
double cdfScaler = static_cast< double >( valueSet->rawSize() ) - cdfMin;
for( size_t i = 0; i < hist->size(); ++i )
{
// the CDF at i is the summed up histogram from 0 to i
// we additionally require the histogram to be normalized so divide by the total count
accum += ( *hist )[ i ];
cdf[ i ] = accum;
cdf[ i ] = accum - cdfMin;
}
// finally, build the new dataset
debugLog() << "Calculating equalized value-set";
double cdfMin = cdf[ 0 ];
for ( size_t vi = 0; vi < valueSet->rawSize(); ++vi )
{
double cdfVI = cdf[ hist->getIndexForValue( valueSet->getScalarDouble( vi ) ) ];
newData[ vi ] = static_cast< unsigned char >(
255.0 * ( cdfVI - cdfMin ) / ( static_cast< double >( valueSet->rawSize() ) - cdfMin )
);
size_t idx = hist->getIndexForValue( valueSet->getScalarDouble( vi ) );
double cdfVI = cdf[ idx ];