Commit 291764e6 authored by Mathias Goldau's avatar Mathias Goldau
Browse files

[MERGE]

parents 5c511912 258944b5
......@@ -75,7 +75,7 @@ INCLUDE( OpenWalnut )
SETUP_MODULE(
${PROJECT_NAME} # use project name as module(-toolbox) name
"." # where to find the sources
"liblas.so" # no additonal dependencies
"liblas.so" # no additonal dependencies
"" # no sources to exclude
)
......
......@@ -25,13 +25,15 @@
// This file's purpose is to provide a list of modules and additional extensions as entry point for OpenWalnut's module loader.
// Both functAdd your modules here. If you miss this step, OpenWalnut will not be able to load your modules/extensions.
#include <string>
#include <boost/shared_ptr.hpp>
#include <core/kernel/WModule.h>
#include "buildingsDetection/WMBuildingsDetection.h"
#include "elevationImageExport/WMElevationImageExport.h"
#include "pointsCutOutliers/WMPointsCutOutliers.h"
#include "pointsGroupSelector/WMPointsGroupSelector.h"
#include "readLAS/WMReadLAS.h"
// #include "WToolkit.h"
......@@ -49,7 +51,9 @@
extern "C" void WLoadModule( WModuleList& m ) // NOLINT
{
m.push_back( boost::shared_ptr< WModule >( new WMBuildingsDetection ) );
m.push_back( boost::shared_ptr< WModule >( new WMElevationImageExport ) );
m.push_back( boost::shared_ptr< WModule >( new WMPointsCutOutliers ) );
m.push_back( boost::shared_ptr< WModule >( new WMPointsGroupSelector ) );
m.push_back( boost::shared_ptr< WModule >( new WMReadLAS ) );
}
......
......@@ -2,7 +2,7 @@
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2013 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
......
......@@ -2,7 +2,7 @@
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2013 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
......@@ -28,10 +28,10 @@
#include <vector>
#include "core/graphicsEngine/WTriangleMesh.h"
#include "core/dataHandler/WDataSetPoints.h"
#include "structure/WOctNode.h"
#include "structure/WQuadNode.h"
#include "structure/WQuadTree.h"
#include "structure/WOctree.h"
#include "../datastructures/octree/WOctNode.h"
#include "../datastructures/quadtree/WQuadNode.h"
#include "../datastructures/quadtree/WQuadTree.h"
#include "../datastructures/octree/WOctree.h"
/**
* Class that detects buildings using the WDataSetPoints
......@@ -49,7 +49,6 @@ public:
virtual ~WBuildingDetector();
/**
* Starts the routine detecting buildings using the point data.
* Don't forget to execute initMinimalMaxima() before using that method.
* After executing you can extract the building number from each node
* using the method getBuildingGroups().
* \param points Point data to extract buildings from
......@@ -57,8 +56,9 @@ public:
void detectBuildings( boost::shared_ptr< WDataSetPoints > points );
/**
* Sets setting params for building recognition
* \param m_detailDepth data grid resolution of cube group data. The number must
* be an element of 2^n. n can be smaller than 0.
* \param m_detailDepth Data grid resolution of cube group data. The number must
* be an element of 2^n. n can be smaller than 0 It means the
* area's radius by 2^n for recognition as building.
* \param minSearchDetailDepth The area width to search a corresponding minimum.
* This number must be an element of 2^n. n can be
* smaller than 0. Finally this parameter determines the
......@@ -69,10 +69,10 @@ public:
void setDetectionParams( int m_detailDepth, int minSearchDetailDepth,
double minSearchCutUntilAbove );
/**
* Returns the 3D node tree. Each node has a group ID number. Many nodes can pe
* Returns the 3D node tree. Each leaf node has a group ID number. Many nodes can pe
* pointed by an equal parameter to a single building area.
* \return The octree of existing buildings. Buildings are grouped by an equal
* group number parameter of WOctNode.
* group number parameter of WOctNode leafs.
*/
WOctree* getBuildingGroups();
......@@ -80,28 +80,29 @@ private:
/**
* Inits the image of minimals which is used to determine a relative minimum of
* a X/Y coordinate.
* \param sourceNode Input image with fine-grain maximal geights to calculate a
* better image of relative minimums. It removes outliers below
* the ground.
* \param targetTree The grifty image to calculate relative minimums.
* \param sourceNode Input image with fine-grain maximal heights to calculate a
* better image of relative minimums. It removes most outliers
* below the ground.
* \param targetTree The grifty image where minimums are takin in order to
* compare whether points are above threshold.
*/
void initMinimalMaxima( WQuadNode* sourceNode, WQuadTree* targetTree );
/**
* Calculates 2D-areas which cover buildings.
* \param sourceImage Input image, maximal points.
* Calculates 2D-areas which cover buildings. Building areas will be outlined in targetTree.
* \param sourceImage Input image. Maximal point values are taken.
* \param minimalMaxima Image of relative minimums calculated by initMinimalMaxima();
* \param targetTree Output image containing elevation data. Areas covering no
* buildings should contain no data.
* buildings won*t contain data.
*/
void projectDrawableAreas( WQuadNode* sourceImage, WQuadTree* minimalMaxima,
WQuadTree* targetTree );
/**
* This is one of the last steps. It sorts out voxels that belong to buildings.
* \param sourceNode Source octree contatining data that represent to contain any
* It generates a voxel structure. Leaf nodes should appear where building points exist.
* \param sourceNode Source octree contatining data that represents any
* point data altogether.
* \param buildingPixels Image that depicts areas covered by buildings in order to map
* the source 3D cubes on them.
* \param targetTree Not grouped voxels that represent building point areas.
* \param targetTree Not grouped output voxels that represent building point areas.
*/
void fetchBuildingVoxels( WOctNode* sourceNode, WQuadTree* buildingPixels,
WOctree* targetTree );
......@@ -114,7 +115,7 @@ private:
/**
* Resolution of the relative minimum search image. Use only numbers depictable by 2^n
* where n can also be 0 or below. The bigger the pixels the greater are the areas
* searched from an examined X/Y area.
* searched from an examined X/Y area. Their radius equals that parameter.
*/
double m_minSearchDetailDepth;
/**
......@@ -123,16 +124,16 @@ private:
double m_minSearchCutUntilAbove;
/**
* The same as m_minSearchDetailDepth. But it's used to still be able tu use smaller
* areas not having big proglems with larger buildings.
* m_minSearchDetailDepth values not having big proglems with larger buildings.
*/
double m_detailDepthBigHeights;
/**
* The corresponding height setting for m_detailDepthBigHeights.
* The corresponding threshold height setting for m_detailDepthBigHeights.
*/
double m_minSearchCutUntilAboveBigHeights;
/**
* The Octree that depicts the set of all buildings. Each node represents a cube
* The Octree that depicts the set of all buildings. Each leaf node represents a cube
* within X/Y/Z. Every cube has a group id which corresponds to a building number.
* This field is calculated by detectBuildings().
*/
......
......@@ -2,7 +2,7 @@
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2013 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
......@@ -42,7 +42,7 @@
#include "WMBuildingsDetection.xpm"
#include "WMBuildingsDetection.h"
#include "WBuildingDetector.h"
#include "structure/WOctree.h"
#include "../datastructures/octree/WOctree.h"
// This line is needed by the module loader to actually find your module.
//W_LOADABLE_MODULE( WMBuildingsDetection )
......@@ -52,8 +52,6 @@ WMBuildingsDetection::WMBuildingsDetection():
WModule(),
m_propCondition( new WCondition() )
{
m_tree = new WOctree( 0 );
m_elevationImage = new WQuadTree( 0 );
}
WMBuildingsDetection::~WMBuildingsDetection()
......@@ -83,10 +81,10 @@ void WMBuildingsDetection::connectors()
{
m_input = WModuleInputData< WDataSetPoints >::createAndAdd( shared_from_this(), "input", "The mesh to display" );
m_output = boost::shared_ptr< WModuleOutputData< WTriangleMesh > >(
new WModuleOutputData< WTriangleMesh >( shared_from_this(), "output", "The loaded mesh." ) );
m_outputPointsGrouped = boost::shared_ptr< WModuleOutputData< WDataSetPointsGrouped > >(
new WModuleOutputData< WDataSetPointsGrouped >( shared_from_this(), "Grouped points", "The loaded mesh." ) );
addConnector( m_output );
addConnector( m_outputPointsGrouped );
// addConnector( m_buildings );
WModule::connectors();
}
......@@ -105,12 +103,6 @@ void WMBuildingsDetection::properties()
// ---> Put the code for your properties here. See "src/modules/template/" for an extensively documented example.
m_reloadData = m_properties->addProperty( "Reload data:", "Execute", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
m_stubSize = m_properties->addProperty( "Stub size: ",
"Size of tetraeders that are used to depict points.", 0.6 );
m_stubSize->setMin( 0.0 );
m_stubSize->setMax( 3.0 );
m_contrast = m_properties->addProperty( "Contrast: ",
"Color intensity multiplier.", 2.0 );
m_detailDepth = m_properties->addProperty( "Detail Depth 2^n m: ", "Resulting 2^n meters detail "
"depth for the octree search tree.", 0 );
m_detailDepth->setMin( -3 );
......@@ -118,42 +110,18 @@ void WMBuildingsDetection::properties()
m_detailDepthLabel = m_properties->addProperty( "Detail Depth meters: ", "Resulting detail depth "
"in meters for the octree search tree.", 1.0 );
m_detailDepthLabel->setPurpose( PV_PURPOSE_INFORMATION );
m_showTrianglesInsteadOfOctreeCubes = m_properties->addProperty( "Triangles instead of cubes: ",
"Depicting the input data set points showing the point outline "
"instead of regions depicted as cubes that cover existing points. "
"Enabling this option you must have 32GB RAM depicting a 400MB"
"las file.", false );
m_minSearchDetailDepth = m_properties->addProperty( "Detail Depth min. search: ", "//TODO", 3 );
m_minSearchDetailDepth = m_properties->addProperty( "Detail Depth min. search: ",
"Main building detection setting.\r\n"
"Resolution of the relative minimum search image. Use only numbers depictable by 2^n "
"where n can also be 0 or below. The bigger the pixels the greater are the areas "
"searched from an examined X/Y area", 3 );
m_minSearchDetailDepth->setMin( 2 );
m_minSearchDetailDepth->setMax( 6 );
m_minSearchCutUntilAbove = m_properties->addProperty( "Cut until above min: ", "//TODO", 4.0 );
m_minSearchCutUntilAbove = m_properties->addProperty( "Cut until above min: ", "Main building detection setting.\r\n"
"Height that must exceed above an relative minimum to recognize it as a building pixel.", 4.0 );
m_minSearchCutUntilAbove->setMin( 2.0 );
m_minSearchCutUntilAbove->setMax( 20.0 );
m_selectedShowableBuilding = m_properties->addProperty( "Showable building idx: ",
"Index of the showable building. 0 is the entire dataset. 1 means all "
"buildings without the ground. Other numbers are all each other buildings in "
"one single piece", 1 );
m_selectedShowableBuilding->setMin( 0 );
m_selectedShowableBuilding->setMax( 1 );
boost::shared_ptr< WItemSelection > imageModes( boost::shared_ptr< WItemSelection >( new WItemSelection() ) );
imageModes->addItem( "Minimals", "Minimal elevation values." );
imageModes->addItem( "Maximals", "Maximal elevation values." );
imageModes->addItem( "Point count", "Store point count to each pixel." );
m_elevImageMode = m_properties->addProperty( "Color mode", "Choose one of the available colorings.", imageModes->getSelectorFirst() );
WPropertyHelper::PC_SELECTONLYONE::addTo( m_elevImageMode );
m_minElevImageZ = m_properties->addProperty( "Min. Z value: ",
"Minimal Z value where image intensities begin to rise. Always watch in the "
"info the minimal Z value and enter a similar value.", 0.0 );
m_intensityIncreasesPerMeter = m_properties->addProperty( "Increases per meter: ",
"The bitmap has a range of possible color intensities. This field determines "
"how many increases per meter are done.", 10.0 );
m_elevationImageExportablePath = m_properties->addProperty( "Elev. image:",
"Target file path of the exportable elevation image *.bmp file",
WPathHelper::getAppPath() );
m_exportTriggerProp = m_properties->addProperty( "Write: ", "Export elevation image", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
WModule::properties();
......@@ -185,13 +153,18 @@ void WMBuildingsDetection::moduleMain()
m_moduleState.wait();
boost::shared_ptr< WDataSetPoints > points = m_input->getData();
std::cout << "Execute cycle\r\n";
WItemSelector elevImageModeSelector = m_elevImageMode->get();
// std::cout << "Execute cycle\r\n";
if ( points )
{
WDataSetPoints::VertexArray verts = points->getVertices();
WDataSetPoints::ColorArray colors = points->getColors();
size_t count = verts->size()/3;
WDataSetPoints::VertexArray inputVerts = points->getVertices();
WDataSetPoints::ColorArray inputColors = points->getColors();
WDataSetPointsGrouped::VertexArray outputVerts(
new WDataSetPointsGrouped::VertexArray::element_type() );
WDataSetPointsGrouped::ColorArray outputColors(
new WDataSetPointsGrouped::ColorArray::element_type() );
WDataSetPointsGrouped::GroupArray outputGroups(
new WDataSetPointsGrouped::GroupArray::element_type() );
size_t count = inputVerts->size()/3;
setProgressSettings( count );
WBuildingDetector detector = WBuildingDetector();
......@@ -199,69 +172,41 @@ void WMBuildingsDetection::moduleMain()
m_minSearchCutUntilAbove->get() );
detector.detectBuildings( points );
WOctree* buildingGroups = detector.getBuildingGroups();
size_t groupCount = buildingGroups->getGroupCount();
m_selectedShowableBuilding->setMax( groupCount + 1 );
size_t selectedGroup = m_selectedShowableBuilding->get();
m_detailDepthLabel->set( pow( 2.0, m_detailDepth->get() ) );
m_tree = new WOctree( m_detailDepthLabel->get() );
m_elevationImage = new WQuadTree( m_detailDepthLabel->get() );
m_elevationImage->setExportElevationImageSettings(
m_minElevImageZ->get( true ), m_intensityIncreasesPerMeter->get() );
WQuadTree* boundingBox = new WQuadTree( m_detailDepthLabel->get() );
boost::shared_ptr< WTriangleMesh > tmpMesh( new WTriangleMesh( 0, 0 ) );
float a = m_stubSize->get();
float contrast = m_contrast->get();
for ( size_t vertex = 0; vertex < count; vertex++)
{
float x = verts->at( vertex*3 );
float y = verts->at( vertex*3+1 );
float z = verts->at( vertex*3+2 );
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 );
WOctNode* buildingVoxel = buildingGroups->getLeafNode( x, y, z );
if( selectedGroup == 0 || ( buildingVoxel != 0 && (
selectedGroup == 1 || selectedGroup == buildingVoxel->getGroupNr() + 2 ) ) )
if( buildingVoxel != 0 )
{
if( m_showTrianglesInsteadOfOctreeCubes->get() )
{
float r = colors->at( vertex*3 );
float g = colors->at( vertex*3+1 );
float b = colors->at( vertex*3+2 );
osg::Vec4f* color = new osg::Vec4f(
r/400.0f*contrast, g/400.0f*contrast, b/400.0f*contrast, 1.0f );
tmpMesh->addVertex( 0+x, 0+y, 0+z );
tmpMesh->addVertex( a+x, 0+y, 0+z );
tmpMesh->addVertex( 0+x, a+y, 0+z );
tmpMesh->addVertex( 0+x, 0+y, a+z );
size_t body = vertex*4;
tmpMesh->addTriangle( 0+body, 2+body, 1+body );
tmpMesh->addTriangle( 0+body, 1+body, 3+body );
tmpMesh->addTriangle( 0+body, 3+body, 2+body );
tmpMesh->addTriangle( 1+body, 2+body, 3+body );
tmpMesh->setVertexColor( body, *color );
tmpMesh->setVertexColor( body+1, *color );
tmpMesh->setVertexColor( body+2, *color );
tmpMesh->setVertexColor( body+3, *color );
}
m_progressStatus->increment( 1 );
m_tree->registerPoint( x, y, z );
m_elevationImage->registerPoint( x, y, z );
outputVerts->push_back( x );
outputVerts->push_back( y );
outputVerts->push_back( z );
for( size_t index = vertex*3; index < vertex*3+3; index++ )
outputColors->push_back( inputColors->at( index ) );
outputGroups->push_back( buildingVoxel->getGroupNr() );
}
}
m_tree->groupNeighbourLeafs();
m_output->updateData( m_showTrianglesInsteadOfOctreeCubes->get( true )
?tmpMesh :m_tree->getOutline() );
boost::shared_ptr< WDataSetPointsGrouped > output(
new WDataSetPointsGrouped( outputVerts, outputColors, outputGroups ) );
m_outputPointsGrouped->updateData( output );
m_nbPoints->set( count );
m_xMin->set( m_elevationImage->getRootNode()->getXMin() );
m_xMax->set( m_elevationImage->getRootNode()->getXMax() );
m_yMin->set( m_elevationImage->getRootNode()->getYMin() );
m_yMax->set( m_elevationImage->getRootNode()->getYMax() );
m_zMin->set( m_elevationImage->getRootNode()->getElevationMin() );
m_zMax->set( m_elevationImage->getRootNode()->getElevationMax() );
if( m_exportTriggerProp->get( true ) )
m_elevationImage->exportElevationImage( m_elevationImageExportablePath->get().c_str(),
elevImageModeSelector.getItemIndexOfSelected( 0 ) );
m_exportTriggerProp->set( WPVBaseTypes::PV_TRIGGER_READY, true );
m_xMin->set( boundingBox->getRootNode()->getXMin() );
m_xMax->set( boundingBox->getRootNode()->getXMax() );
m_yMin->set( boundingBox->getRootNode()->getYMin() );
m_yMax->set( boundingBox->getRootNode()->getYMax() );
m_zMin->set( boundingBox->getRootNode()->getElevationMin() );
m_zMax->set( boundingBox->getRootNode()->getElevationMax() );
m_progressStatus->finish();
}
m_reloadData->set( WPVBaseTypes::PV_TRIGGER_READY, true );
......
......@@ -2,7 +2,7 @@
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2013 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
......@@ -42,10 +42,10 @@
#include <osg/ShapeDrawable>
#include <osg/Geode>
#include "core/dataHandler/WDataSetPoints.h"
#include "structure/WOctree.h"
#include "structure/WQuadTree.h"
#include "../datastructures/octree/WOctree.h"
#include "../datastructures/quadtree/WQuadTree.h"
#include "../datastructures/WDataSetPointsGrouped.h"
......@@ -75,14 +75,15 @@ class WDataSetScalar;
class WGEManagedGroupNode;
/**
* Draws cubes where a value is at least as big as the preset ISO value
* Detects building structures within a WDataSetPoints. The recognition algorithm works by the
* principle of relative height minimum height thresholding.
* \ingroup modules
*/
class WMBuildingsDetection: public WModule
{
public:
/**
* Creates the module for drawing contour lines.
* Creates the module for the Building detection.
*/
WMBuildingsDetection();
......@@ -150,9 +151,9 @@ private:
boost::shared_ptr< WModuleInputData< WDataSetPoints > > m_input;
/**
* WDataSetPoints data output as tetraeders.
* WDataSetPointsGrouped data output as point groups depicting each building
*/
boost::shared_ptr< WModuleOutputData< WTriangleMesh > > m_output;
boost::shared_ptr< WModuleOutputData< WDataSetPointsGrouped > > m_outputPointsGrouped;
/**
* The OSG root node for this module. All other geodes or OSG nodes will be attached on this single node.
......@@ -164,11 +165,6 @@ private:
*/
boost::shared_ptr< WCondition > m_propCondition;
/**
* Shader unit for drawing.
*/
WGEShader::RefPtr m_shader;
/**
* Info tab property: Input points count.
*/
......@@ -197,58 +193,17 @@ private:
* Info tab property: Maximal z value of input x coordunates.
*/
WPropDouble m_zMax;
/**
* Voxel count that is cut off and kept regarding the ISO value.
*/
WPropDouble m_stubSize;
/**
* Voxel count that is cut off and kept regarding the ISO value.
*/
WPropDouble m_contrast;
/**
* Determines the resolution of the smallest octree nodes in 2^n meters
* Determines the resolution of the smallest octree nodes in 2^n meters. The smallest
* radius equals to its result.
*/
WPropInt m_detailDepth;
/**
* Determines the resolution of the smallest octree nodes in meters
* Determines the resolution of smallest octree nodes. Their radius equal that value.
*/
WPropDouble m_detailDepthLabel;
/**
* Depicting the input data set points showing the point outline instead of regions
* depicted as cubes that cover existing points.
*/
WPropBool m_showTrianglesInsteadOfOctreeCubes;
/**
* Mode of the elevation image to display
* 0: Minimal Z value of each X/Y bin coordinate.
* 1: Maximal Z value of each X/Y bin coordinate.
* 2: Point count of each X/Y bin coordinate.
*/
WPropSelection m_elevImageMode;
/**
* Elevation image export setting.
* All areas below that elevation are depicted using the black color.
*/
WPropDouble m_minElevImageZ;
/**
* Elevation image export setting.
* Count of intensity increases per meter.
*/
WPropDouble m_intensityIncreasesPerMeter;
/**
* Path of the exportable elevation image *.bmp file.
*/
WPropFilename m_elevationImageExportablePath; //!< The mesh will be read from this file.
WPropTrigger m_exportTriggerProp; //!< This property triggers the actual reading,
/**
* This trigger button reloads the data to output.
*/
WPropTrigger m_reloadData; //!< This property triggers the actual reading,
......@@ -256,7 +211,9 @@ private:
* Main building detection setting.
* Resolution of the relative minimum search image. Use only numbers depictable by 2^n
* where n can also be 0 or below. The bigger the pixels the greater are the areas
* searched from an examined X/Y area.
* searched from an examined X/Y area. In order to determine whether a point belongs to
* at least four nodes of that detail level will be examined whether at least on of the
* four is below of the height threshold of the examinable point.
*/
WPropInt m_minSearchDetailDepth;
/**
......@@ -266,29 +223,9 @@ private:
WPropDouble m_minSearchCutUntilAbove;
/**
* Property to choose an output building of a voxel group number. Currently 0 is
* cutting nothing and 1 is is showing all buildings altogether.
*/
WPropInt m_selectedShowableBuilding;
/**
* Instance for applying drawable geoms.
*/
osg::ref_ptr< osg::Geode > m_geode;
/**
* Plugin progress status that is shared with the reader.
* Plugin progress status.
*/
boost::shared_ptr< WProgress > m_progressStatus;
/**
* Octree node used for the data set points analysis.
*/
WOctree* m_tree;
/**
* This is the elevation image of the whole data set.
* It depicts some statistical Z coordinate information of each X/Y-coordinate.
*/
WQuadTree* m_elevationImage;
};
#endif // WMBUILDINGSDETECTION_H
//---------------------------------------------------------------------------
//
// 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 <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <algorithm>
#include <string>
#include <vector>
#include "core/common/exceptions/WOutOfBounds.h"
#include "core/common/WAssert.h"
#include "core/common/WColor.h"
#include "core/common/math/linearAlgebra/WPosition.h"
#include "WDataSetPointsGrouped.h"
// prototype instance as singleton
boost::shared_ptr< WPrototyped > WDataSetPointsGrouped::m_prototype = boost::shared_ptr< WPrototyped >();