Commit 29432ed2 authored by cornimueller's avatar cornimueller
Browse files

[ADD] EEG View module now displays the head surface with vertex normals...

[ADD] EEG View module now displays the head surface with vertex normals calculated by WTriangleMesh.
[FIX] WGEGeometryUtils' triangulate function now returns the correct triangles (had to undo the sorting which osg::DelaunayTriangulator does).
parent 7db1cc05
......@@ -72,6 +72,11 @@ void WTriangleMesh::setVertices( const std::vector< wmath::WPosition >& vertices
m_vertices = vertices;
}
const std::vector< wmath::WPosition >& WTriangleMesh::getVertices() const
{
return m_vertices;
}
size_t WTriangleMesh::getFastAddVertId() const
{
return m_fastAddVertId;
......
......@@ -103,6 +103,13 @@ public:
*/
void setVertices( const std::vector< wmath::WPosition >& vertices );
/**
* Get vector of the vertex positions.
*
* \return const reference to the vertices
*/
const std::vector< wmath::WPosition >& getVertices() const;
/**
* \return the state of the variable telling fastAddVert where to insert the vertex.
*/
......
......@@ -22,16 +22,17 @@
//
//---------------------------------------------------------------------------
#include <osg/Array>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Vec3>
#include <osg/Array>
#include <osg/ShapeDrawable>
#include <osg/MatrixTransform>
#include <osg/ShapeDrawable>
#include <osg/Vec3>
#include "../math/WPosition.h"
#include "WGEGeodeUtils.h"
#include "WGEUtils.h"
#include "../math/WPosition.h"
osg::ref_ptr< osg::Geode > wge::generateBoundingBoxGeode( const wmath::WPosition& pos1, const wmath::WPosition& pos2, const WColor& color )
{
......@@ -182,3 +183,36 @@ osg::ref_ptr< osg::Node > wge::generateSolidBoundingBoxNode( const wmath::WPosit
return transform;
}
osg::ref_ptr< osg::Geometry > wge::convertToOsgGeometry( WTriangleMesh* mesh, bool includeNormals )
{
osg::ref_ptr< osg::Vec3Array > vertices = wge::osgVec3Array( mesh->getVertices() );
osg::DrawElementsUInt* triangles = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES );
triangles->reserve( 3 * mesh->getNumTriangles() );
for( size_t triangleID = 0; triangleID < mesh->getNumTriangles(); ++triangleID )
{
triangles->push_back( mesh->getTriangleVertexId( triangleID, 0 ) );
triangles->push_back( mesh->getTriangleVertexId( triangleID, 1 ) );
triangles->push_back( mesh->getTriangleVertexId( triangleID, 2 ) );
}
osg::ref_ptr< osg::Geometry> geometry( new osg::Geometry );
geometry->setVertexArray( vertices );
geometry->addPrimitiveSet( triangles );
if( includeNormals )
{
mesh->computeVertNormals();
osg::Vec3Array* normals = new osg::Vec3Array();
normals->reserve( mesh->getNumVertices() );
for( size_t vertexID = 0; vertexID < mesh->getNumVertices(); ++vertexID )
{
normals->push_back( wge::osgVec3( mesh->getVertexNormal( vertexID ) ) );
}
geometry->setNormalArray( normals );
geometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
}
return geometry;
}
......@@ -27,9 +27,11 @@
#include <osg/Geode>
#include "../common/datastructures/WTriangleMesh.h"
#include "../common/WColor.h"
#include "../math/WPosition.h"
namespace wge
{
/**
......@@ -66,6 +68,16 @@ namespace wge
*/
osg::ref_ptr< osg::Geometry > createUnitCube( const WColor& color );
/**
* Extract the vertices and triangles from a WTriangleMesh and save them
* into an osg::Geometry.
*
* \param mesh the WTriangleMesh used as input
* \param includeNormals When true, calculate the vertex normals and include
* them into the geometry.
* \return an osg::Geometry containing the mesh
*/
osg::ref_ptr< osg::Geometry > convertToOsgGeometry( WTriangleMesh* mesh, bool includeNormals = false );
} // end of namespace wge
#endif // WGEGEODEUTILS_H
......@@ -22,6 +22,7 @@
//
//---------------------------------------------------------------------------
#include <map>
#include <vector>
#include <osg/Array>
......@@ -96,7 +97,18 @@ osg::ref_ptr< osg::Vec3Array > wge::generateCuboidQuadNormals( const std::vector
WTriangleMesh wge::triangulate( const std::vector< wmath::WPosition >& points )
{
osg::ref_ptr< osgUtil::DelaunayTriangulator > triangulator( new osgUtil::DelaunayTriangulator( wge::osgVec3Array( points ) ) );
osg::ref_ptr< osg::Vec3Array > osgPoints = wge::osgVec3Array( points );
// The osg triangulator sorts the points and returns the triangles with the
// indizes of the sorted points. Since we don't want to change the sequence
// of the points, we have to save the original index of each point.
std::map< osg::Vec3, size_t > map;
for( size_t index = 0; index < osgPoints->size(); ++index )
{
map[ (*osgPoints)[index] ] = index;
}
osg::ref_ptr< osgUtil::DelaunayTriangulator > triangulator( new osgUtil::DelaunayTriangulator( osgPoints ) );
if( triangulator->triangulate() )
{
osg::ref_ptr< const osg::DrawElementsUInt > osgTriangles( triangulator->getTriangles() );
......@@ -104,9 +116,11 @@ WTriangleMesh wge::triangulate( const std::vector< wmath::WPosition >& points )
std::vector< Triangle > triangles( nbTriangles );
for( size_t triangleID = 0; triangleID < nbTriangles; ++triangleID )
{
triangles[triangleID].pointID[0] = (*osgTriangles)[3 * triangleID];
triangles[triangleID].pointID[1] = (*osgTriangles)[3 * triangleID + 1];
triangles[triangleID].pointID[2] = (*osgTriangles)[3 * triangleID + 2];
// Convert the new index of the osgTriangle to the original index
// stored in map.
triangles[triangleID].pointID[0] = map[ (*osgPoints)[ (*osgTriangles)[3 * triangleID] ] ];
triangles[triangleID].pointID[1] = map[ (*osgPoints)[ (*osgTriangles)[3 * triangleID + 1] ] ];
triangles[triangleID].pointID[2] = map[ (*osgPoints)[ (*osgTriangles)[3 * triangleID + 2] ] ];
}
WTriangleMesh mesh;
......
......@@ -23,9 +23,10 @@
//---------------------------------------------------------------------------
#include <string>
#include <vector>
#include <osgUtil/DelaunayTriangulator>
#include "../../graphicsEngine/WGEGeodeUtils.h"
#include "../../graphicsEngine/WGEGeometryUtils.h"
#include "../../graphicsEngine/WGEUtils.h"
#include "../../kernel/WKernel.h"
#include "WMEEGView.h"
......@@ -343,37 +344,26 @@ void WMEEGView::redraw()
}
// draw head surface
osg::ref_ptr< osg::Vec3Array > positions( new osg::Vec3Array );
std::vector< wmath::WPosition > positions;
positions.reserve( nbChannels );
for( size_t channel = 0; channel < nbChannels; ++channel )
{
positions->push_back( wge::osgVec3( m_eeg->getChannelPosition( channel ) ) );
positions.push_back( m_eeg->getChannelPosition( channel ) );
}
osg::ref_ptr< osg::Vec3Array > normals( new osg::Vec3Array );
osg::ref_ptr< osgUtil::DelaunayTriangulator> triangulator( new osgUtil::DelaunayTriangulator( positions, normals ) );
if( triangulator->triangulate() )
{
osg::Geometry* geometry = new osg::Geometry;
geometry->setVertexArray( positions );
geometry->setNormalArray( normals );
geometry->setNormalBinding( osg::Geometry::BIND_PER_PRIMITIVE );
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back( osg::Vec4( 1.0, 1.0, 1.0, 1.0 ) );
geometry->setColorArray( colors );
geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
WTriangleMesh mesh = wge::triangulate( positions );
osg::ref_ptr< osg::Geometry > geometry = wge::convertToOsgGeometry( &mesh, true );
geometry->addPrimitiveSet( triangulator->getTriangles() );
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back( osg::Vec4( 1.0, 1.0, 1.0, 1.0 ) );
geometry->setColorArray( colors );
geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
osg::Geode* geode = new osg::Geode;
geode->addDrawable( geometry );
m_rootNode3d->addChild( geode );
}
else
{
errorLog() << "Couldn't triangulate head surface";
}
osg::Geode* geode = new osg::Geode;
geode->addDrawable( geometry );
m_rootNode3d->addChild( geode );
// add rootNode to scene
if( m_wasActive )
{
debugLog() << "Adding rootNode to scene after redraw";
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment