//--------------------------------------------------------------------------- // // Project: OpenWalnut ( http://www.openwalnut.org ) // // Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-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 . // //--------------------------------------------------------------------------- #include #include // std::ifstream #include // std::cout #include #include #include "core/kernel/WModule.h" #include "core/dataHandler/WDataSetScalar.h" #include "core/graphicsEngine/callbacks/WGELinearTranslationCallback.h" #include "core/graphicsEngine/shaders/WGEPropertyUniform.h" #include "core/graphicsEngine/shaders/WGEShader.h" #include "core/graphicsEngine/WGEGeodeUtils.h" #include "core/graphicsEngine/WGEManagedGroupNode.h" #include "core/kernel/WKernel.h" #include "core/kernel/WModuleInputData.h" #include "WMSurfaceDetectionByPCL.xpm" #include "WMSurfaceDetectionByPCL.h" #include "WSurfaceDetectorPCL.h" WMSurfaceDetectionByPCL::WMSurfaceDetectionByPCL(): WModule(), m_propCondition( new WCondition() ) { } WMSurfaceDetectionByPCL::~WMSurfaceDetectionByPCL() { } boost::shared_ptr< WModule > WMSurfaceDetectionByPCL::factory() const { return boost::shared_ptr< WModule >( new WMSurfaceDetectionByPCL() ); } const char** WMSurfaceDetectionByPCL::getXPMIcon() const { return WMSurfaceDetectionByPCL_xpm; } const std::string WMSurfaceDetectionByPCL::getName() const { return "Surface Detection by PCL"; } const std::string WMSurfaceDetectionByPCL::getDescription() const { return "Should draw values above some threshold."; } void WMSurfaceDetectionByPCL::connectors() { m_input = WModuleInputData< WDataSetPoints >::createAndAdd( shared_from_this(), "input", "The mesh to display" ); m_outputPointsGrouped = boost::shared_ptr< WModuleOutputData< WDataSetPointsGrouped > >( new WModuleOutputData< WDataSetPointsGrouped >( shared_from_this(), "Grouped points", "The loaded mesh." ) ); addConnector( m_outputPointsGrouped ); WModule::connectors(); } void WMSurfaceDetectionByPCL::properties() { m_infoNbPoints = m_infoProperties->addProperty( "Points: ", "Input points count.", 0 ); m_infoRenderTimeMinutes = m_infoProperties->addProperty( "Wall time (min): ", "Time in seconds that the " "whole render process took.", 0.0 ); m_infoPointsPerSecond = m_infoProperties->addProperty( "Points per second: ", "The current speed in points per second.", 0.0 ); m_infoXMin = m_infoProperties->addProperty( "X min.: ", "Minimal x coordinate of all input points.", 0.0 ); m_infoXMax = m_infoProperties->addProperty( "X max.: ", "Maximal x coordinate of all input points.", 0.0 ); m_infoYMin = m_infoProperties->addProperty( "Y min.: ", "Minimal y coordinate of all input points.", 0.0 ); m_infoYMax = m_infoProperties->addProperty( "Y max.: ", "Maximal y coordinate of all input points.", 0.0 ); m_infoZMin = m_infoProperties->addProperty( "Z min.: ", "Minimal z coordinate of all input points.", 0.0 ); m_infoZMax = m_infoProperties->addProperty( "Z max.: ", "Maximal z coordinate of all input points.", 0.0 ); m_reloadData = m_properties->addProperty( "Reload data:", "Execute", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition ); m_clusterSizeMin = m_properties->addProperty( "Cluster size min.: ", "Minimal size of a surface point set.", 50 ); m_clusterSizeMax = m_properties->addProperty( "Cluster size max.: ", "Maximal size of a surface point set.", 1000 * 1000 ); m_numberOfNeighbours = m_properties->addProperty( "Number of neighbors: ", "Resulting detail depth " "in meters for the octree search tree.", 30 ); m_smoothnessThresholdDegrees = m_properties->addProperty( "Smoothness threshold: ", "", 3.0 ); m_smoothnessThresholdDegrees->setMin( 0.0 ); m_smoothnessThresholdDegrees->setMax( 30 ); m_curvatureThreshold = m_properties->addProperty( "Curvature Threshold: ", "", 1.0 ); WModule::properties(); } void WMSurfaceDetectionByPCL::requirements() { } void WMSurfaceDetectionByPCL::moduleMain() { m_moduleState.setResetable( true, true ); m_moduleState.add( m_input->getDataChangedCondition() ); m_moduleState.add( m_propCondition ); ready(); // graphics setup m_rootNode = osg::ref_ptr< WGEManagedGroupNode >( new WGEManagedGroupNode( m_active ) ); WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( m_rootNode ); // main loop while( !m_shutdownFlag() ) { m_moduleState.wait(); boost::shared_ptr< WDataSetPoints > points = m_input->getData(); if ( points ) { WRealtimeTimer timer; timer.reset(); WDataSetPoints::VertexArray inputVerts = points->getVertices(); size_t count = inputVerts->size()/3; setProgressSettings( count ); WSurfaceDetectorPCL detector = WSurfaceDetectorPCL(); detector.setClusterSizeRange( m_clusterSizeMin->get(), m_clusterSizeMax->get() ); detector.setNumberOfNeighbors( m_numberOfNeighbours->get() ); detector.setSmoothnessThreshold( m_smoothnessThresholdDegrees->get() ); detector.setCurvatureThreshold( m_curvatureThreshold->get() ); WQuadTree* boundingBox = new WQuadTree( 16 ); boost::shared_ptr< WTriangleMesh > tmpMesh( new WTriangleMesh( 0, 0 ) ); for ( size_t vertex = 0; vertex < count; vertex++) { float x = inputVerts->at( vertex * 3 ); float y = inputVerts->at( vertex * 3 + 1 ); float z = inputVerts->at( vertex * 3 + 2 ); boundingBox->registerPoint( x, y, z ); } boost::shared_ptr< WDataSetPointsGrouped > outputPcl = detector.detectSurfaces( points ); m_outputPointsGrouped->updateData( outputPcl ); m_infoNbPoints->set( count ); m_infoRenderTimeMinutes->set( timer.elapsed() / 60.0 ); m_infoPointsPerSecond->set( m_infoRenderTimeMinutes->get() == 0.0 ?m_infoNbPoints->get() :m_infoNbPoints->get() / ( m_infoRenderTimeMinutes->get() * 60.0 ) ); m_infoXMin->set( boundingBox->getRootNode()->getXMin() ); m_infoXMax->set( boundingBox->getRootNode()->getXMax() ); m_infoYMin->set( boundingBox->getRootNode()->getYMin() ); m_infoYMax->set( boundingBox->getRootNode()->getYMax() ); m_infoZMin->set( boundingBox->getRootNode()->getValueMin() ); m_infoZMax->set( boundingBox->getRootNode()->getValueMax() ); m_progressStatus->finish(); } m_reloadData->set( WPVBaseTypes::PV_TRIGGER_READY, true ); m_reloadData->get( true ); // woke up since the module is requested to finish? if ( m_shutdownFlag() ) { break; } boost::shared_ptr< WDataSetPoints > points2 = m_input->getData(); if ( !points2 ) { continue; } } WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( m_rootNode ); } void WMSurfaceDetectionByPCL::setProgressSettings( size_t steps ) { m_progress->removeSubProgress( m_progressStatus ); std::string headerText = "Loading data"; m_progressStatus = boost::shared_ptr< WProgress >( new WProgress( headerText, steps ) ); m_progress->addSubProgress( m_progressStatus ); }