Commit 9006f304 authored by aschwarzkopf's avatar aschwarzkopf
Browse files

[ADD #309] Added Simplistic Building detection feature.

Some simplistic algorithms are done in order to group buildings. Evaluation:
  + Important data structures as Octree and Quadtree are implemented with important functions
  + Grouping neighbor voxels runs even if still not 26-neighborship (few steps required)
     + Algorithm can easily be transferred to the quadtree set.
  + First new plugin for cutting of outlier points using the algorithm that calculates
    figuring out cube connectivity. Other points are cut off that don't belong to the
    largest voxel group
  - Possibly vaporized effort
      - The algorithm that takes relative elevation minimums has problems detecting low buildings.
          - Probably the algorithm won't be taken
          + The great deal of the code amount used for it can be very useful for the final code.
      + It's easy to differ trees from buildings
          - Not thought to the end to differ trees that are very close to buildings
parent d28ad199
......@@ -15,4 +15,4 @@
#VERSION=1.2.0
#VERSION=1.2.0+hgX -> replaces the X with the current revision number
#VERSUIB=1.2.0+hg1234 -> here, revision number was set by the build scripts for example.
VERSION=0.0.1+hgX
VERSION=0.0.2+hgX
......@@ -31,6 +31,7 @@
#include <core/kernel/WModule.h>
#include "buildingsDetection/WMBuildingsDetection.h"
#include "pointsCutOutliers/WMPointsCutOutliers.h"
#include "readLAS/WMReadLAS.h"
// #include "WToolkit.h"
......@@ -48,6 +49,7 @@
extern "C" void WLoadModule( WModuleList& m ) // NOLINT
{
m.push_back( boost::shared_ptr< WModule >( new WMBuildingsDetection ) );
m.push_back( boost::shared_ptr< WModule >( new WMPointsCutOutliers ) );
m.push_back( boost::shared_ptr< WModule >( new WMReadLAS ) );
}
......
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2013 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 <iostream>
#include "WBuildingDetector.h"
WBuildingDetector::WBuildingDetector()
{
m_detailDepth = 0.5;
m_minSearchDetailDepth = 8.0;
m_minSearchCutUntilAbove = 4.0;
m_detailDepthBigHeights = 32.0;
m_minSearchCutUntilAboveBigHeights = 20.0;
}
WBuildingDetector::~WBuildingDetector()
{
}
void WBuildingDetector::detectBuildings( boost::shared_ptr< WDataSetPoints > points )
{
WDataSetPoints::VertexArray verts = points->getVertices();
size_t count = verts->size()/3;
WOctree* zones3d = new WOctree( m_detailDepth );
WQuadTree* zones2d = new WQuadTree( m_detailDepth );
WQuadTree* minimalMaxima = new WQuadTree( m_minSearchDetailDepth );
WQuadTree* targetShowables = new WQuadTree( m_detailDepth );
m_targetGrouped3d = new WOctree( m_detailDepth );
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 );
zones3d->registerPoint( x, y, z );
zones2d->registerPoint( x, y, z );
}
initMinimalMaxima( zones2d->getRootNode(), minimalMaxima );
projectDrawableAreas( zones2d->getRootNode(), minimalMaxima, targetShowables );
fetchBuildingVoxels( zones3d->getRootNode(), targetShowables, m_targetGrouped3d );
m_targetGrouped3d->groupNeighbourLeafs();
//targetShowables->setExportElevationImageSettings( -16.0, 8.0 );
//targetShowables->exportElevationImage( "/home/renegade/Dokumente/Projekte/OpenWalnut@Eclipse/elevation images/targetShowables.bmp", 1 );
}
void WBuildingDetector::setDetectionParams( int detailDepth, int minSearchDetailDepth,
double minSearchCutUntilAbove )
{
m_detailDepth = pow( 2.0, detailDepth );
m_minSearchDetailDepth = pow( 2.0, minSearchDetailDepth );
m_minSearchCutUntilAbove = minSearchCutUntilAbove;
}
WOctree* WBuildingDetector::getBuildingGroups()
{
return m_targetGrouped3d;
}
void WBuildingDetector::initMinimalMaxima( WQuadNode* sourceNode, WQuadTree* targetTree )
{
if ( sourceNode->getRadius() <= m_detailDepth )
{
double coordX = sourceNode->getCenter( 0 );
double coordY = sourceNode->getCenter( 1 );
double d = m_minSearchDetailDepth / 2.0;
double height = sourceNode->getElevationMax();
targetTree->registerPoint( coordX - d, coordY - d, height );
targetTree->registerPoint( coordX - d, coordY + d, height );
targetTree->registerPoint( coordX + d, coordY - d, height );
targetTree->registerPoint( coordX + d, coordY + d, height );
}
else
{
for( int child = 0; child < 4; child++ )
if( sourceNode->getChild( child ) != 0 )
initMinimalMaxima( sourceNode->getChild( child ), targetTree );
}
}
void WBuildingDetector::projectDrawableAreas( WQuadNode* sourceNode,
WQuadTree* minimalMaxima, WQuadTree* targetTree )
{
if( sourceNode->getRadius() <= m_detailDepth )
{
double coordX = sourceNode->getCenter( 0 );
double coordY = sourceNode->getCenter( 1 );
WQuadNode* minimalNode = minimalMaxima->getLeafNode( coordX, coordY );
WQuadNode* minimalNodeBigHeight = minimalMaxima->getLeafNode( coordX, coordY,
m_minSearchCutUntilAboveBigHeights );
if( minimalNode == 0 || minimalNodeBigHeight == 0 ) return;
double minimalHeight = m_minSearchCutUntilAbove + minimalNode->getElevationMin();
double minimalHeightBigHeights = m_minSearchCutUntilAbove + minimalNodeBigHeight->getElevationMin();
if( sourceNode->getElevationMax() < minimalHeight
&& sourceNode->getElevationMax() < minimalHeightBigHeights ) return;
targetTree->registerPoint( coordX, coordY, sourceNode->getElevationMax() );
}
else
{
for( int child = 0; child < 4; child++ )
if( sourceNode->getChild( child ) != 0 )
projectDrawableAreas( sourceNode->getChild( child ), minimalMaxima, targetTree );
}
}
void WBuildingDetector::fetchBuildingVoxels( WOctNode* sourceNode, WQuadTree* buildingPixels,
WOctree* targetTree )
{
if( sourceNode->getRadius() <= m_detailDepth )
{
double coordX = sourceNode->getCenter( 0 );
double coordY = sourceNode->getCenter( 1 );
double coordZ = sourceNode->getCenter( 2 );
WQuadNode* buildingArea = buildingPixels->getLeafNode( coordX, coordY );
if( buildingArea != 0 )
targetTree->registerPoint( coordX, coordY, coordZ );
}
else
{
for( int child = 0; child < 8; child++ )
if( sourceNode->getChild( child ) != 0 )
fetchBuildingVoxels( sourceNode->getChild( child ), buildingPixels, targetTree );
}
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2013 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/>.
//
//---------------------------------------------------------------------------
#ifndef WBUILDINGDETECTOR_H
#define WBUILDINGDETECTOR_H
#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"
/**
* Class that detects buildings using the WDataSetPoints
*/
class WBuildingDetector
{
public:
/**
* Constructor of the building detector instance.
*/
explicit WBuildingDetector();
/**
* Destructor of the building detector instance.
*/
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
*/
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 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
* search area of the relative minimum.
* \param minSearchCutUntilAbove The minimal height above the relative minimal
* height in order to recognize as a building.
*/
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
* 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.
*/
WOctree* getBuildingGroups();
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.
*/
void initMinimalMaxima( WQuadNode* sourceNode, WQuadTree* targetTree );
/**
* Calculates 2D-areas which cover buildings.
* \param sourceImage Input image, maximal points.
* \param minimalMaxima Image of relative minimums calculated by initMinimalMaxima();
* \param targetTree Output image containing elevation data. Areas covering no
* buildings should contain no 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
* 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.
*/
void fetchBuildingVoxels( WOctNode* sourceNode, WQuadTree* buildingPixels,
WOctree* targetTree );
/**
* Resolution of input/output data in meters. Use only numbers depictable by 2^n
* where n can also be 0 or below.
*/
double m_detailDepth;
/**
* 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.
*/
double m_minSearchDetailDepth;
/**
* Height that must exceed above an relative minimum to recognize it as a building pixel.
*/
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.
*/
double m_detailDepthBigHeights;
/**
* The corresponding height setting for m_detailDepthBigHeights.
*/
double m_minSearchCutUntilAboveBigHeights;
/**
* The Octree that depicts the set of all buildings. Each 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().
*/
WOctree* m_targetGrouped3d;
};
#endif // WBUILDINGDETECTOR_H
......@@ -41,10 +41,11 @@
#include "core/kernel/WModuleInputData.h"
#include "WMBuildingsDetection.xpm"
#include "WMBuildingsDetection.h"
#include "WBuildingDetector.h"
#include "structure/WOctree.h"
// This line is needed by the module loader to actually find your module.
W_LOADABLE_MODULE( WMBuildingsDetection )
//W_LOADABLE_MODULE( WMBuildingsDetection )
//TODO(aschwarzkopf): Reenable above after solving the toolbox problem
WMBuildingsDetection::WMBuildingsDetection():
......@@ -102,37 +103,57 @@ 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_propCondition );
"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_propCondition );
"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_propCondition );
"depth for the octree search tree.", 0 );
m_detailDepth->setMin( -3 );
m_detailDepth->setMax( 4 );
m_detailDepthLabel = m_properties->addProperty( "Detail Depth meters: ", "Resulting detail depth "
"in meters for the octree search tree.", 1.0, m_propCondition );
"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_propCondition );
"las file.", false );
m_minSearchDetailDepth = m_properties->addProperty( "Detail Depth min. search: ", "//TODO", 3 );
m_minSearchDetailDepth->setMin( 2 );
m_minSearchDetailDepth->setMax( 6 );
m_minSearchCutUntilAbove = m_properties->addProperty( "Cut until above min: ", "//TODO", 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(),
m_propCondition );
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( "Do read", "Press!", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
m_exportTriggerProp = m_properties->addProperty( "Write: ", "Export elevation image", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
WModule::properties();
......@@ -165,51 +186,71 @@ void WMBuildingsDetection::moduleMain()
boost::shared_ptr< WDataSetPoints > points = m_input->getData();
std::cout << "Execute cycle\r\n";
WItemSelector elevImageModeSelector = m_elevImageMode->get( true );
WItemSelector elevImageModeSelector = m_elevImageMode->get();
if ( points )
{
m_tree = new WOctree( m_detailDepthLabel->get( true ) );
m_elevationImage = new WQuadTree( m_detailDepthLabel->get( true ) );
WDataSetPoints::VertexArray verts = points->getVertices();
WDataSetPoints::ColorArray colors = points->getColors();
size_t count = verts->size()/3;
setProgressSettings( count );
WBuildingDetector detector = WBuildingDetector();
detector.setDetectionParams( m_detailDepth->get(), m_minSearchDetailDepth->get(),
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() );
boost::shared_ptr< WTriangleMesh > tmpMesh( new WTriangleMesh( 0, 0 ) );
float a = m_stubSize->get();
float contrast = m_contrast->get();
setProgressSettings( count );
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 );
if ( m_showTrianglesInsteadOfOctreeCubes->get( true ) )
WOctNode* buildingVoxel = buildingGroups->getLeafNode( x, y, z );
if( selectedGroup == 0 || ( buildingVoxel != 0 && (
selectedGroup == 1 || selectedGroup == buildingVoxel->getGroupNr() + 2 ) ) )
{
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 );
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 );
}
m_progressStatus->increment( 1 );
m_tree->registerPoint( x, y, z );
m_elevationImage->registerPoint( x, y, z );
}
m_tree->groupNeighbourLeafs();
m_output->updateData( m_showTrianglesInsteadOfOctreeCubes->get( true )
?tmpMesh :m_tree->getOutline( ) );
?tmpMesh :m_tree->getOutline() );
m_nbPoints->set( count );
m_xMin->set( m_elevationImage->getRootNode()->getXMin() );
m_xMax->set( m_elevationImage->getRootNode()->getXMax() );
......@@ -223,9 +264,9 @@ void WMBuildingsDetection::moduleMain()
m_exportTriggerProp->set( WPVBaseTypes::PV_TRIGGER_READY, true );
m_progressStatus->finish();
}
m_reloadData->set( WPVBaseTypes::PV_TRIGGER_READY, true );
m_reloadData->get( true );
m_detailDepthLabel->set( pow( 2.0, m_detailDepth->get() ) );
std::cout << "this is WOTree " << std::endl;
// woke up since the module is requested to finish?
if ( m_shutdownFlag() )
......
......@@ -228,12 +228,49 @@ private:
* 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,
/**
* 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.
*/
WPropInt m_minSearchDetailDepth;
/**
* Main building detection setting.
* Height that must exceed above an relative minimum to recognize it as a building pixel.
*/
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.
*/
......
......@@ -33,6 +33,7 @@ const size_t WOctNode::vZ[] = {0, 0, 0, 0, 1, 1, 1, 1};
WOctNode::WOctNode( double centerX, double centerY, double centerZ, double radius )
{
m_groupNr = 0;
m_center[0] = centerX;
m_center[1] = centerY;
m_center[2] = centerZ;
......@@ -118,7 +119,14 @@ double WOctNode::getCenter( size_t dimension )
return m_center[dimension];
}
size_t WOctNode::getGroupNr()
{
return m_groupNr;
}
void WOctNode::setGroupNr( size_t groupNr )
{
m_groupNr = groupNr;
}
void WOctNode::setChild( WOctNode* child, size_t drawer )
......
......@@ -97,6 +97,16 @@ public:
* \return the center coordinate to the corresponding dimension parameter
*/
double getCenter( size_t dimension );
/**