Commit 258944b5 authored by aschwarzkopf's avatar aschwarzkopf

[ADD #309] Added some point output features and bugfixes.

Following bugfixes new features:
  - Points group selector plugin: Can output selected buildings as
    WDataSetPointsGrouped in order to be able to view data in other plug-ins
  - Elevation image export plugin: Features to switch elevation display
    in triangle mesh height and color.
  - Fixes in documentation and few code cleanup.
parent c04b1e87
......@@ -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().
*/
......
......@@ -111,10 +111,15 @@ void WMBuildingsDetection::properties()
"in meters for the octree search tree.", 1.0 );
m_detailDepthLabel->setPurpose( PV_PURPOSE_INFORMATION );
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 );
......@@ -169,7 +174,7 @@ void WMBuildingsDetection::moduleMain()
WOctree* buildingGroups = detector.getBuildingGroups();
m_detailDepthLabel->set( pow( 2.0, m_detailDepth->get() ) );
WQuadTree* boundingBox = new WQuadTree( m_detailDepthLabel->get() ); //TODO(schwarzkopf): replace functions of this field by m_tree
WQuadTree* boundingBox = new WQuadTree( m_detailDepthLabel->get() );
boost::shared_ptr< WTriangleMesh > tmpMesh( new WTriangleMesh( 0, 0 ) );
for ( size_t vertex = 0; vertex < count; vertex++)
......@@ -178,12 +183,11 @@ void WMBuildingsDetection::moduleMain()
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( buildingVoxel != 0 )
{
m_progressStatus->increment( 1 );
boundingBox->registerPoint( x, y, z );
outputVerts->push_back( x );
outputVerts->push_back( y );
outputVerts->push_back( z );
......
......@@ -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();
......@@ -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.
*/
......@@ -199,11 +195,12 @@ private:
WPropDouble m_zMax;
/**
* 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;
......@@ -214,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;
/**
......@@ -224,12 +223,7 @@ private:
WPropDouble m_minSearchCutUntilAbove;
/**
* 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;
};
......
......@@ -38,7 +38,7 @@
* Dataset to store a bunch of points without order or topology.
*/
class WDataSetPointsGrouped : public WDataSet // NOLINT
{ //TODO(schwarzkopf): Extend WDataSetPoints instead of writing lines again. Make Code cleaner that way.
{ //TODO(schwarzkopf): Extension of WDataSetPoints can't be done because WDataSetPoints fields are private and not protected.
public:
// some type alias for the used arrays.
/**
......@@ -62,7 +62,7 @@ public:
typedef boost::shared_ptr< std::vector< float > > ColorArray;
/**
* Group IDs for each vertex in VertexArray
* Group IDs for each vertex in VertexArray.
*/
typedef boost::shared_ptr< std::vector< size_t > > GroupArray;
......@@ -236,7 +236,7 @@ private:
ColorArray m_colors;
/**
* Group index parameter for each vertex.
* Group ID array that is related to m_vertices and m_colors.
*/
GroupArray m_groups;
......
......@@ -129,7 +129,7 @@ void WOctNode::setGroupNr( size_t groupNr )
}
void WOctNode::registerPoint( double x, double y, double z )
void WOctNode::updateMinMax( double x, double y, double z )
{
if( !m_pointCount > 0 )
{
......
......@@ -35,7 +35,7 @@ class WOctNode
public:
/**
* Octree node constructor.
* \param centerX Xcoordinate of the octree node center.
* \param centerX X coordinate of the octree node center.
* \param centerY Y coordinate of the octree node center.
* \param centerZ Z coordinate of the octree node center.
* \param radius Range from the center point that the node covers in each X/Y/Z direction.
......@@ -47,15 +47,14 @@ public:
virtual ~WOctNode();
/**
* Returns an octree child object of a particular case.
* \param drawer Corresponding index of vX/vY/vZ which depict which octree node
* \param drawer Corresponding index (0-7) of vX/vY/vZ which depict which octree node
* to return regarding the X/Y/Z coordinates.
* \return Octree child node of that case.
*/
WOctNode* getChild( size_t drawer );
/**
* Checks whether a coordinate fits into the existing root octree node. A false value
* indicates that the node should be expanded. This method should be applied only
* using the root noce.
* Checks whether a coordinate fits into the octree node. If it's a root noe then
* it will indicate whether it should be expanded to fit in a point..
* \param x X coordinate to determine whether the node covers it.
* \param y Y coordinate to determine whether the node covers it.
* \param z Z coordinate to determine whether the node covers it.
......@@ -63,12 +62,11 @@ public:
*/
bool fitsIn( double x, double y, double z );
/**
* Returns which child case index is covered by particular coordinates. An invalid
* index is returned if ther's no possible child for that coordinate.
* Returns which child case index (0-7) is covered by a particular coordinate.
* \param x X coordinate to analyze.
* \param y Y coordinate to analyze.
* \param z Z coordinate to analyze.
* \return Case index regarding the x/Y/Z coordinates described by the vX/vY/vZ
* \return Case index regarding the X/Y/Z coordinate described by the vX/vY/vZ
* constants.
*/
size_t getFittingCase( double x, double y, double z );
......@@ -85,9 +83,7 @@ public:
*/
void touchNode( size_t drawer );
/**
* Range that the octree node covers in each dimension. Smallest possible dimension
* value is included but the largest should be excluded in order to put in the octree
* node standing next to the current.
* Returns the radius of the octree node.
* \return Node range from its center.
*/
double getRadius();
......@@ -98,12 +94,12 @@ public:
*/
double getCenter( size_t dimension );
/**
* Returns the Node group ID that is calculated regarding the node neighbors.
* \return The voxel group ID.
* Returns the Node group ID that is calculated regarding the lear node neighbors.
* \return The voxel group ID. Applyable only on leaf nodes.
*/
size_t getGroupNr();
/**
* Sets the octree node group ID. It's usually calculated regarding the voxel neighbors.
* Sets the octree node group ID. It's usually calculated regarding the leaf voxel neighbors.
* \param groupNr The voxel group ID.
*/
void setGroupNr( size_t groupNr );
......@@ -122,14 +118,12 @@ public:
static const size_t vZ[];
/**
* Registers a point to the node. During that minimum and maximum values of the
* coordinates are refreshed. Each step the point count is incremented by 1.
* The method doesn't traverse parents and children.
* \param x X coordinate to register.
* \param y Y coordinate to register.
* \param z Z coordinate to register.
* Updates minimal and maximal X/Y/Z value parameters. The point count is incremented by 1.
* \param x X coordinate to update.
* \param y Y coordinate to update.
* \param z Z coordinate to update.
*/
void registerPoint( double x, double y, double z );
void updateMinMax( double x, double y, double z );
/**
* Returns the count of registered points.
* \return Registered points count.
......@@ -176,23 +170,23 @@ private:
void setChild( WOctNode* child, size_t drawer );
/**
* Children of the current octree node
* Children of the current octree node.
*/
WOctNode* m_child[8];
/**
* Center of the current octree node
* Absolute center coordinate of the current octree node.
*/
double m_center[3];
/**
* Range that the octree node covers in each dimension. Smallest possible dimension
* value is included but the largest should be excluded in order to put in the octree
* node standing next to the current.
* Radius from the center that is covered by the octree node area.
*/
double m_radius;
//TODO(schwarzkopf): Function parameters that don't belong to the main function don't belong to it.
/**
* The node group ID. This number usually corresponds to its voxel neighborship
* The node group ID. This number usually corresponds to its voxel neighborship.
*/
size_t m_groupNr;
size_t m_groupNr; //TODO(schwarzkopf): Implement the following parameter another way somewhere else.
/**
* Point count of the node.
*/
......
......@@ -43,13 +43,13 @@ void WOctree::registerPoint( double x, double y, double z )
m_root->expand();
WOctNode* node = m_root;
node->registerPoint( x, y, z );
node->updateMinMax( x, y, z );
while ( node->getRadius() > m_detailLevel )
{
size_t drawer = node->getFittingCase( x, y, z );
node->touchNode( drawer );
node = node->getChild( drawer );
node->registerPoint( x, y, z );
node->updateMinMax( x, y, z );
}
}
WOctNode* WOctree::getLeafNode( double x, double y, double z )
......
......@@ -30,15 +30,16 @@
#include "WOctNode.h"
/**
* Octree structure for analyzing buildings point data
* Octree structure for analyzing the point data
*/
class WOctree
{
public:
/**
* Octree constructor
* \param detailDepth Supported octree node resolution resolution. Currently only
* numbers covering 2^n results including negative n values.
* Octree constructor.
* \param detailDepth Supported octree node resolution resolution. It equals the
* node's radius. Currently only numbers covering 2^n results
* including negative n values.
*/
explicit WOctree( double detailDepth );
/**
......@@ -80,33 +81,28 @@ public:
*/
void refreshNodeGroup( WOctNode* node );
/**
* Returns the voxel neighbor group count. Execute groupNeighbourLeafs() befor
* Returns the voxel neighbor group count. Execute groupNeighbourLeafs() before
* acquiring that parameter.
* \return The voxel neighbor group count.
*/
size_t getGroupCount();
/**
* Returns the detail level. It's the minimal allowed radius of any quadnode.
* \return The minimal radius of any quadnode.
* Returns the detail level. It's the minimal allowed radius of any octnode.
* \return The minimal radius of any octnode.
*/
double getDetailLevel();
//TODO(schwarzkopf): Function parameters that don't belong to the main function don't belong to it.
/**
* Returns a color channel value for a particular building or point group.
* Returns a color channel value for a particular point group.
* \param groupNr Group number to assign a corresponding color
* \param colorChannel Channel of the whole color that is returned. 0=red, 1=green and 2=blue.
* \return Group color of values between 0.0 and 1.0 corresponding to a particular colorChannel.
*/
static float calcColor( size_t groupNr, size_t colorChannel );
static float calcColor( size_t groupNr, size_t colorChannel ); //TODO(schwarzkopf): Implement the following parameter another way somewhere else.
private:
/**
* Draws an octree node. All subchildren will also be drawn.
* \param node Octree node to draw
* \param outputMesh Output triangle mesh where the outline will be drawn.
*/
void drawNode( WOctNode* node, boost::shared_ptr< WTriangleMesh > outputMesh );
/**
* method that traverses a node in order to group all neighbor cubes into mutual
* Method that traverses a node in order to group all neighbor cubes into mutual
* group numbers.
* \param node Subnodes to traverse recursively.
*/
......@@ -121,12 +117,12 @@ private:
*/
WOctNode* m_root;
/**
* Detail level of the octree. Currently 2^value is the smallest possible radius of
* all octree nodes.
* The radius of smallest octree nodes. Currently only numbers covering 2^n (included negative n).
* are supported.
*/
double m_detailLevel;
/**
* Variable used during voxel grouping.
* Variable used during voxel grouping for correcting group IDs.
* It contains Voxel group number to building ID mapping.
* After the process the size corresponds to the recognized building count.
*/
......@@ -139,12 +135,6 @@ private:
* Color count or size of the field colors[].
*/
static const size_t colorCount;
/**
* Draws a Quadtree node and its subchildren to the triangle mesh.
* \param node Octree node to draw on the triangle mesh.
* \param outputMesh Target triangle mesh where the voxels will be drawn
* \param octree The octree that is drawn. Still requires that param to gather some parameters.
*/
};
#endif // WOCTREE_H
......@@ -111,7 +111,7 @@ double WQuadNode::getCenter( size_t dimension )
{
return m_center[dimension];
}
void WQuadNode::registerPoint( double x, double y, double elevation )
void WQuadNode::updateMinMax( double x, double y, double elevation )
{
if( !m_pointCount > 0 )
{
......
......@@ -27,17 +27,17 @@
#define WQUADNODE_H
/**
* Octree node class designed for points data. Each node represents an area where at least
* Quadtree node class designed for points data. Each node represents an area where at least
* one data set point exists.
*/
class WQuadNode
{
public:
/**
* Octree node constructor.
* \param centerX Xcoordinate of the quadtree node center.
* Quadtree node constructor.
* \param centerX X coordinate of the quadtree node center.
* \param centerY Y coordinate of the quadtree node center.
* \param radius Range from the center point that the node covers in each X/Y/Z direction.
* \param radius Range from the center point that the node covers in each X/Y direction.
*/
WQuadNode( double centerX, double centerY, double radius );
/**
......@@ -45,24 +45,22 @@ public:
*/
virtual ~WQuadNode();
/**
* Returns an quadtree child object of a particular case.
* \param drawer Corresponding index of vX/vY/vZ which depict which quadtree node
* to return regarding the X/Y/Z coordinates.
* \return Octree child node of that case.
* Returns a quadtree child object of a particular case.
* \param drawer Corresponding index of vX/vY which depicts which quadtree node
* to return regarding the X/Y coordinates.
* \return Quadtree child node of that case.
*/
WQuadNode* getChild( size_t drawer );
/**
* Checks whether a coordinate fits into the existing root quadtree node. A false value
* indicates that the node should be expanded. This method should be applied only
* using the root noce.
* Checks whether a coordinate fits into the quadtree node. If it's a rot node then
* it indicates whether it should be expanded in order to access the coordinate.
* \param x X coordinate to determine whether the node covers it.
* \param y Y coordinate to determine whether the node covers it.
* \return Shows whether the quadtree node covers the X/Y/Z coordinate.
* \return Shows whether the quadtree node covers the X/Y coordinate.
*/
bool fitsIn( double x, double y );
/**
* Returns which child case index is covered by particular coordinates. An invalid
* index is returned if ther's no possible child for that coordinate.
* Returns which child case index is covered by particular coordinates.
* \param x X coordinate to analyze.
* \param y Y coordinate to analyze.
* \return Case index regarding the x/Y/Z coordinates described by the vX/vY/vZ
......@@ -82,31 +80,28 @@ public:
*/
void touchNode( size_t drawer );
/**
* Range that the quadtree node covers in each dimension. Smallest possible dimension
* value is included but the largest should be excluded in order to put in the quadtree
* node standing next to the current.
* Returns the quadnode's radiius from the center.
* \return Node range from its center.
*/
double getRadius();
/**
* Returns center coordinates of an quadtree node.
* \param dimension center dimension to return (0/1/2 = X/Y/Z)
* \return the center coordinate to the corresponding dimension parameter
* \param dimension Center dimension to return (0/1 = X/Y)
* \return The center coordinate to the corresponding dimension parameter.
*/
double getCenter( size_t dimension );
/**
* Registers a point to the node. During that minimum and maximum values of the
* coordinates and the elevation is refreshed. Each step the point count is
* incremented by 1. The method doesn't traverse parents and children.
* \param x X coordinate to register.
* \param y Y coordinate to register.
* \param elevation Elevation to register.
* Updates minimal and maximal X/Y/elevation value parameters. The point count is incremented by 1.
* It doesn't alter or add any node.
* \param x X coordinate to update.
* \param y Y coordinate to update.
* \param elevation Elevation to update.
*/
void registerPoint( double x, double y, double elevation );
void updateMinMax( double x, double y, double elevation );
/**
* Returns the count of registered points.
* Returns the count of registered points using updateMinMax().
* \return Registered points count.
*/
size_t getPointCount();
......@@ -131,22 +126,22 @@ public:
*/
double getYMax();
/**
* Returns the minimal Elevation.
* \return The minimal Elevation.
* Returns the minimal elevation.
* \return The minimal elevation.
*/
double getElevationMin();
/**
* Returns the maximal Elevation.
* \return The maximal Elevation.
* Returns the maximal elevation.
* \return The maximal elevation.
*/
double getElevationMax();
/**
* Determines which X coordinate axis case a m_child has.
* Determines which X coordinate axis case an m_child has.
*/
static const size_t vX[];
/**
* Determines which Y coordinate axis case a m_child has.
* Determines which Y coordinate axis case an m_child has.
*/
static const size_t vY[];
......@@ -164,9 +159,9 @@ public: