Commit 8b021578 authored by Jan Möbius's avatar Jan Möbius
Browse files

Splatcloud object now contains the splatcloud itself, not the node

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@13896 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 42b3d1e0
......@@ -142,12 +142,7 @@ SplatCloud* splatCloud( BaseObjectData *_object )
if ( object == 0 )
return 0;
SplatCloudNode *node = object->splatCloudNode();
if( node == 0 )
return 0;
return node->splatCloud();
return object->splatCloud();
}
......@@ -165,8 +160,10 @@ SplatCloudObject* splatCloudObject( BaseObjectData *_object )
return dynamic_cast<SplatCloudObject *>( _object );
}
//----------------------------------------------------------------
SplatCloudObject* splatCloudObject( int _objectId ) {
if (_objectId == -1)
......
......@@ -69,9 +69,9 @@ namespace SceneGraph {
//== IMPLEMENTATION ==============================================
SplatCloudNode::SplatCloudNode( BaseNode *_parent, std::string _name ) :
SplatCloudNode::SplatCloudNode( const SplatCloud &_splatCloud, BaseNode *_parent, std::string _name ) :
BaseNode ( _parent, _name ),
splatCloud_ ( 0 ),
splatCloud_ ( _splatCloud ),
pointsModified_ ( false ),
normalsModified_ ( false ),
pointsizesModified_ ( false ),
......@@ -95,13 +95,6 @@ SplatCloudNode::SplatCloudNode( BaseNode *_parent, std::string _name ) :
vboSelectionsOffset_( -1 ),
vboPickColorsOffset_( -1 )
{
// allocate memory for splat cloud
splatCloud_ = new SplatCloud;
if( !splatCloud_ )
{
std::cerr << "SplatCloudNode::SplatCloudNode() : Out of memory." << std::endl;
}
// add (possibly) new drawmodes
pointsDrawMode_ = DrawModes::addDrawMode( "Points" );
dotsDrawMode_ = DrawModes::addDrawMode( "Dots" );
......@@ -118,9 +111,6 @@ SplatCloudNode::SplatCloudNode( BaseNode *_parent, std::string _name ) :
SplatCloudNode::~SplatCloudNode()
{
destroyVBO();
delete splatCloud_;
splatCloud_ = 0;
}
......@@ -129,15 +119,11 @@ SplatCloudNode::~SplatCloudNode()
void SplatCloudNode::boundingBox( ACG::Vec3d &_bbMin, ACG::Vec3d &_bbMax )
{
// if something went wrong in the initialization, abort
if( !splatCloud_ )
return;
ACG::Vec3f bbMin( FLT_MAX, FLT_MAX, FLT_MAX );
ACG::Vec3f bbMax(-FLT_MAX,-FLT_MAX,-FLT_MAX );
SplatCloud::PointVector::const_iterator pointIter, pointsEnd = splatCloud_->points().end();
for ( pointIter = splatCloud_->points().begin(); pointIter != pointsEnd; ++pointIter )
SplatCloud::PointVector::const_iterator pointIter, pointsEnd = splatCloud_.points().end();
for ( pointIter = splatCloud_.points().begin(); pointIter != pointsEnd; ++pointIter )
{
const Point &p = *pointIter;
......@@ -157,10 +143,6 @@ void SplatCloudNode::boundingBox( ACG::Vec3d &_bbMin, ACG::Vec3d &_bbMax )
void SplatCloudNode::draw( GLState &_state, const DrawModes::DrawMode &_drawMode )
{
// if something went wrong in the initialization, abort
if( !splatCloud_ )
return;
static const int RENDERMODE_POINTS = 0;
static const int RENDERMODE_DOTS = 1;
static const int RENDERMODE_SPLATS = 2;
......@@ -329,15 +311,11 @@ void SplatCloudNode::enterPick( GLState &_state, PickTarget _target, const DrawM
void SplatCloudNode::pick( GLState &_state, PickTarget _target )
{
// if something went wrong in the initialization, abort
if( !splatCloud_ )
return;
// if pick target is valid...
if( _target == PICK_ANYTHING || _target == PICK_VERTEX )
{
// set number of pick colors used (each points gets a unique pick color)
if( !_state.pick_set_maximum( splatCloud_->numPoints() ) ) // number of points could have changed, so use new number of points (*not* the one in VBO memory!)
if( !_state.pick_set_maximum( splatCloud_.numPoints() ) ) // number of points could have changed, so use new number of points (*not* the one in VBO memory!)
{
std::cerr << "SplatCloudNode::pick() : Color range too small, picking failed." << std::endl;
return;
......@@ -362,21 +340,6 @@ void SplatCloudNode::pick( GLState &_state, PickTarget _target )
//----------------------------------------------------------------
void SplatCloudNode::copySplatCloud( const SplatCloud &_splatCloud )
{
delete splatCloud_;
splatCloud_ = new SplatCloud( _splatCloud );
if( !splatCloud_ )
{
std::cerr << "SplatCloudNode::copySplatCloud() : Out of memory." << std::endl;
}
}
//----------------------------------------------------------------
void SplatCloudNode::createVBO()
{
// create new VBO (if *not* already existing)
......@@ -413,7 +376,7 @@ void SplatCloudNode::destroyVBO()
void SplatCloudNode::rebuildVBO( GLState &_state )
{
// if something went wrong in the initialization, make VBO invalid and abort
if( vboGlId_ == 0 || !splatCloud_)
if( vboGlId_ == 0 )
{
vboData_ = 0;
return;
......@@ -423,7 +386,7 @@ void SplatCloudNode::rebuildVBO( GLState &_state )
ACG::GLState::bindBufferARB( GL_ARRAY_BUFFER_ARB, vboGlId_ );
// calculate size of data and offsets
unsigned int numPoints = splatCloud_->numPoints();
unsigned int numPoints = splatCloud_.numPoints();
unsigned int size = 0;
int pointsOffset = -1;
......@@ -433,11 +396,11 @@ void SplatCloudNode::rebuildVBO( GLState &_state )
int selectionsOffset = -1;
int pickColorsOffset = -1;
if( splatCloud_->hasPoints() ) { pointsOffset = size; size += numPoints * 12; }
if( splatCloud_->hasNormals() ) { normalsOffset = size; size += numPoints * 12; }
if( splatCloud_->hasPointsizes() ) { pointsizesOffset = size; size += numPoints * 4; }
if( splatCloud_->hasColors() ) { colorsOffset = size; size += numPoints * 3; }
if( splatCloud_->hasSelections() ) { selectionsOffset = size; size += numPoints * 4; }
if( splatCloud_.hasPoints() ) { pointsOffset = size; size += numPoints * 12; }
if( splatCloud_.hasNormals() ) { normalsOffset = size; size += numPoints * 12; }
if( splatCloud_.hasPointsizes() ) { pointsizesOffset = size; size += numPoints * 4; }
if( splatCloud_.hasColors() ) { colorsOffset = size; size += numPoints * 3; }
if( splatCloud_.hasSelections() ) { selectionsOffset = size; size += numPoints * 4; }
/* has pick colors = true */ { pickColorsOffset = size; size += numPoints * 4; }
// tell GL that we are seldomly updating the VBO but are often drawing it
......@@ -544,7 +507,7 @@ static void addUCharToBuffer( unsigned char _value, unsigned char *&_buffer )
void SplatCloudNode::rebuildVBOPoints()
{
if( vboPointsOffset_ == -1 || !splatCloud_->hasPoints() )
if( vboPointsOffset_ == -1 || !splatCloud_.hasPoints() )
return;
# ifdef REPORT_VBO_UPDATES
......@@ -555,7 +518,7 @@ void SplatCloudNode::rebuildVBOPoints()
unsigned char *buffer = vboData_ + vboPointsOffset_;
// for all points...
unsigned int i, num = splatCloud_->numPoints();
unsigned int i, num = splatCloud_.numPoints();
for( i=0; i<num; ++i )
{
// add point
......@@ -572,7 +535,7 @@ void SplatCloudNode::rebuildVBOPoints()
void SplatCloudNode::rebuildVBONormals()
{
if( vboNormalsOffset_ == -1 || !splatCloud_->hasNormals() )
if( vboNormalsOffset_ == -1 || !splatCloud_.hasNormals() )
return;
# ifdef REPORT_VBO_UPDATES
......@@ -583,7 +546,7 @@ void SplatCloudNode::rebuildVBONormals()
unsigned char *buffer = vboData_ + vboNormalsOffset_;
// for all points...
unsigned int i, num = splatCloud_->numPoints();
unsigned int i, num = splatCloud_.numPoints();
for( i=0; i<num; ++i )
{
// add normal
......@@ -600,7 +563,7 @@ void SplatCloudNode::rebuildVBONormals()
void SplatCloudNode::rebuildVBOPointsizes()
{
if( vboPointsizesOffset_ == -1 || !splatCloud_->hasPointsizes() )
if( vboPointsizesOffset_ == -1 || !splatCloud_.hasPointsizes() )
return;
# ifdef REPORT_VBO_UPDATES
......@@ -611,7 +574,7 @@ void SplatCloudNode::rebuildVBOPointsizes()
unsigned char *buffer = vboData_ + vboPointsizesOffset_;
// for all points...
unsigned int i, num = splatCloud_->numPoints();
unsigned int i, num = splatCloud_.numPoints();
for( i=0; i<num; ++i )
{
// add pointsize
......@@ -626,7 +589,7 @@ void SplatCloudNode::rebuildVBOPointsizes()
void SplatCloudNode::rebuildVBOColors()
{
if( vboColorsOffset_ == -1 || !splatCloud_->hasColors() )
if( vboColorsOffset_ == -1 || !splatCloud_.hasColors() )
return;
# ifdef REPORT_VBO_UPDATES
......@@ -637,7 +600,7 @@ void SplatCloudNode::rebuildVBOColors()
unsigned char *buffer = vboData_ + vboColorsOffset_;
// for all points...
unsigned int i, num = splatCloud_->numPoints();
unsigned int i, num = splatCloud_.numPoints();
for( i=0; i<num; ++i )
{
// add color
......@@ -654,7 +617,7 @@ void SplatCloudNode::rebuildVBOColors()
void SplatCloudNode::rebuildVBOSelections()
{
if( vboSelectionsOffset_ == -1 || !splatCloud_->hasSelections() )
if( vboSelectionsOffset_ == -1 || !splatCloud_.hasSelections() )
return;
# ifdef REPORT_VBO_UPDATES
......@@ -665,7 +628,7 @@ void SplatCloudNode::rebuildVBOSelections()
unsigned char *buffer = vboData_ + vboSelectionsOffset_;
// for all points...
unsigned int i, num = splatCloud_->numPoints();
unsigned int i, num = splatCloud_.numPoints();
for( i=0; i<num; ++i )
{
const bool &s = getSelection( i );
......@@ -690,7 +653,7 @@ void SplatCloudNode::rebuildVBOPickColors( GLState &_state )
unsigned char *buffer = vboData_ + vboPickColorsOffset_;
// for all points...
unsigned int i, num = splatCloud_->numPoints();
unsigned int i, num = splatCloud_.numPoints();
for( i=0; i<num; ++i )
{
// add pick color
......
......@@ -101,7 +101,7 @@ private:
public:
/// constructor
SplatCloudNode( BaseNode *_parent = 0, std::string _name = "<SplatCloudNode>" );
SplatCloudNode( const SplatCloud &_splatCloud, BaseNode *_parent = 0, std::string _name = "<SplatCloudNode>" );
/// destructor
~SplatCloudNode();
......@@ -123,10 +123,9 @@ public:
// ---- splat cloud ----
void copySplatCloud( const SplatCloud &_splatCloud );
inline const SplatCloud &splatCloud() const { return splatCloud_; }
inline SplatCloud *splatCloud() { return splatCloud_; }
inline const SplatCloud *splatCloud() const { return splatCloud_; }
// ---- modification tags ----
inline void modifiedPoints() { pointsModified_ = true; }
inline void modifiedNormals() { normalsModified_ = true; }
......@@ -147,12 +146,12 @@ public:
inline const Pointsize &defaultPointsize() const { return defaultPointsize_; }
inline const Color &defaultColor() const { return defaultColor_; }
/// if the data array exists, the entry with the given _index is returned, otherwise the default value is returned (check for splatCloud_ != 0 first)
inline Point getPoint ( unsigned int _index ) const { return splatCloud_->hasPoints() ? splatCloud_->points() [ _index ] : Point(0.0f,0.0f,0.0f); }
inline Normal getNormal ( unsigned int _index ) const { return splatCloud_->hasNormals() ? splatCloud_->normals() [ _index ] : defaultNormal_ ; }
inline Pointsize getPointsize( unsigned int _index ) const { return splatCloud_->hasPointsizes() ? splatCloud_->pointsizes()[ _index ] : defaultPointsize_ ; }
inline Color getColor ( unsigned int _index ) const { return splatCloud_->hasColors() ? splatCloud_->colors() [ _index ] : defaultColor_ ; }
inline Selection getSelection( unsigned int _index ) const { return splatCloud_->hasSelections() ? splatCloud_->selections()[ _index ] : false ; }
/// if the data array exists, the entry with the given _index is returned, otherwise the default value is returned
inline Point getPoint ( unsigned int _index ) const { return splatCloud_.hasPoints() ? splatCloud_.points() [ _index ] : Point(0.0f,0.0f,0.0f); }
inline Normal getNormal ( unsigned int _index ) const { return splatCloud_.hasNormals() ? splatCloud_.normals() [ _index ] : defaultNormal_ ; }
inline Pointsize getPointsize( unsigned int _index ) const { return splatCloud_.hasPointsizes() ? splatCloud_.pointsizes()[ _index ] : defaultPointsize_ ; }
inline Color getColor ( unsigned int _index ) const { return splatCloud_.hasColors() ? splatCloud_.colors() [ _index ] : defaultColor_ ; }
inline Selection getSelection( unsigned int _index ) const { return splatCloud_.hasSelections() ? splatCloud_.selections()[ _index ] : false ; }
//----------------------------------------------------------------
......@@ -160,8 +159,10 @@ private:
// ---- splat cloud ----
/// pointer to class containing all the data
SplatCloud *splatCloud_;
/// reference to class containing all the data
const SplatCloud &splatCloud_;
// ---- modification tags ----
/// marks if parts of the data has been modified
bool pointsModified_;
......@@ -205,14 +206,16 @@ private:
int vboSelectionsOffset_;
int vboPickColorsOffset_;
/// returns true iff the internal block structure of the VBO has to be changed (check for splatCloud_ != 0 first)
inline bool vboStructureModified() const { return
vboNumPoints_ != splatCloud_->numPoints() ||
(vboPointsOffset_ != -1) != splatCloud_->hasPoints() ||
(vboNormalsOffset_ != -1) != splatCloud_->hasNormals() ||
(vboPointsizesOffset_ != -1) != splatCloud_->hasPointsizes() ||
(vboColorsOffset_ != -1) != splatCloud_->hasColors() ||
(vboSelectionsOffset_ != -1) != splatCloud_->hasSelections(); }
/// returns true iff the internal block structure of the VBO has to be changed
inline bool vboStructureModified() const
{
return vboNumPoints_ != splatCloud_.numPoints() ||
(vboPointsOffset_ != -1) != splatCloud_.hasPoints() ||
(vboNormalsOffset_ != -1) != splatCloud_.hasNormals() ||
(vboPointsizesOffset_ != -1) != splatCloud_.hasPointsizes() ||
(vboColorsOffset_ != -1) != splatCloud_.hasColors() ||
(vboSelectionsOffset_ != -1) != splatCloud_.hasSelections();
}
void createVBO();
void destroyVBO();
......
......@@ -75,8 +75,15 @@ BaseObjectData ( ),
backfaceCullingEnabled_( false ),
pointsizeScale_ ( 1.0f ),
shaderNode_ ( 0 ),
splatCloudNode_ ( 0 )
splatCloudNode_ ( 0 )
{
// allocate memory for splat cloud
splatCloud_ = new SplatCloud;
if( !splatCloud_ )
{
std::cerr << "SplatCloudObject::SplatCloudObject() : Out of memory." << std::endl;
}
setDataType( DATA_SPLATCLOUD );
setTypeIcon( DATA_SPLATCLOUD, "SplatCloudType.png" );
init();
......@@ -89,9 +96,9 @@ splatCloudNode_ ( 0 )
/**
* Copy Constructor - generates a copy of the given object
*/
SplatCloudObject::SplatCloudObject( const SplatCloudObject &_object) : BaseObjectData( _object )
SplatCloudObject::SplatCloudObject( const SplatCloudObject &_object ) : BaseObjectData( _object )
{
init( _object.splatCloudNode_ );
init( _object.splatCloud_ );
setName( name() );
}
......@@ -112,8 +119,12 @@ SplatCloudObject::~SplatCloudObject()
deleteData();
// No need to delete the scenegraph Nodes as this will be managed by baseplugin
shaderNode_ = 0;
shaderNode_ = 0;
splatCloudNode_ = 0;
// free memory of splat cloud
delete splatCloud_;
splatCloud_ = 0;
}
......@@ -127,12 +138,9 @@ void SplatCloudObject::cleanup()
{
BaseObjectData::cleanup();
shaderNode_ = 0;
shaderNode_ = 0;
splatCloudNode_ = 0;
setDataType( DATA_SPLATCLOUD );
setTypeIcon( DATA_SPLATCLOUD, "SplatCloudType.png" );
init();
}
......@@ -387,23 +395,37 @@ void SplatCloudObject::setPointsizeScale( float _scale )
/** This function initalizes the SplatCloud object. It creates the scenegraph nodes.
*/
void SplatCloudObject::init( SplatCloudNode *_node )
void SplatCloudObject::init( const SplatCloud *_splatCloud )
{
if( materialNode() == NULL )
std::cerr << "Error when creating SplatCloud Object! materialNode is NULL!" << std::endl;
// create new scenegraph nodes
shaderNode_ = new ShaderNode( materialNode(), "NEW ShaderNode for" );
splatCloudNode_ = new SplatCloudNode( shaderNode_, "NEW SplatCloudNode" );
// if _splatCloud is *not* 0, copy it's contents
if( _splatCloud )
{
delete splatCloud_;
// load shaders
reloadShaders();
splatCloud_ = new SplatCloud( *_splatCloud );
if( !splatCloud_ )
{
std::cerr << "SplatCloudObject::init() : Out of memory." << std::endl;
}
}
// if _node is *not* 0 we want to have a copy of the scenegraph node, so copy it's contents
if( _node && _node->splatCloud() )
// if something went wrong during initialization, abort
if( !splatCloud_ )
{
splatCloudNode_->copySplatCloud( *_node->splatCloud() );
shaderNode_ = 0;
splatCloudNode_ = 0;
return;
}
// create new scenegraph nodes
shaderNode_ = new ShaderNode ( materialNode(), "NEW ShaderNode for" );
splatCloudNode_ = new SplatCloudNode( *splatCloud_, shaderNode_, "NEW SplatCloudNode" );
// load shaders
reloadShaders();
}
......@@ -429,32 +451,6 @@ void SplatCloudObject::setName( QString _name )
}
//----------------------------------------------------------------
// Visualization
//----------------------------------------------------------------
/** Returns a pointer to the shader node
* @return Pointer to the shader node
*/
ACG::SceneGraph::ShaderNode *SplatCloudObject::shaderNode()
{
return shaderNode_;
}
//----------------------------------------------------------------
/** Returns a pointer to the splatcloud node
* @return Pointer to the splatcloud node
*/
SplatCloudNode *SplatCloudObject::splatCloudNode()
{
return splatCloudNode_;
}
//----------------------------------------------------------------
// Object information
//----------------------------------------------------------------
......@@ -476,12 +472,12 @@ QString SplatCloudObject::getObjectinfo()
{
output += "Object Contains SplatCloud : ";
if( splatCloudNode_->splatCloud() )
if( splatCloud_ )
{
output += " # points: " + QString::number( splatCloudNode_->splatCloud()->numPoints() );
output += ", normals used: "; output += splatCloudNode_->splatCloud()->hasNormals() ? "true" : "false";
output += ", pointsizes used: "; output += splatCloudNode_->splatCloud()->hasPointsizes() ? "true" : "false";
output += ", colors used: "; output += splatCloudNode_->splatCloud()->hasColors() ? "true" : "false";
output += " # points: " + QString::number( splatCloud_->numPoints() );
output += ", normals used: "; output += splatCloud_->hasNormals() ? "true" : "false";
output += ", pointsizes used: "; output += splatCloud_->hasPointsizes() ? "true" : "false";
output += ", colors used: "; output += splatCloud_->hasColors() ? "true" : "false";
}
output += "\n";
......
......@@ -62,6 +62,8 @@
#include "SplatCloudTypes.hh"
#include "SplatCloud/SplatCloud.hh"
#include <OpenFlipper/common/BaseObjectData.hh>
#include <OpenFlipper/common/GlobalDefines.hh>
......@@ -116,7 +118,7 @@ private:
protected:
/// Initialise current Object, including all related Nodes
virtual void init( SplatCloudNode *_node = 0 );
virtual void init( const SplatCloud *_splatCloud = 0 );
//--------------------------------
/** @name Name and Path handling
......@@ -128,20 +130,36 @@ public:
/** @} */
//--------------------------------
/** @name Content
* @{ */
//--------------------------------
public:
/// Get SplatCloud
inline SplatCloud *splatCloud() { return splatCloud_; }
inline const SplatCloud *splatCloud() const { return splatCloud_; }
private:
SplatCloud *splatCloud_;
/** @} */
//--------------------------------
/** @name Visualization
* @{ */
//--------------------------------
public:
/// Get Shader's scenegraph Node
ShaderNode *shaderNode();
inline ShaderNode *shaderNode() { return shaderNode_; }
inline const ShaderNode *shaderNode() const { return shaderNode_; }
/// Get SplatCloud's scenegraph Node
SplatCloudNode *splatCloudNode();
inline SplatCloudNode *splatCloudNode() { return splatCloudNode_; }
inline const SplatCloudNode *splatCloudNode() const { return splatCloudNode_; }
private:
ShaderNode *shaderNode_;
SplatCloudNode *splatCloudNode_;
ShaderNode *shaderNode_;
SplatCloudNode *splatCloudNode_;
/** @} */
......
/*! \page changelog Changelog
- <b>OpenFlipper 1.2 ( ? , 13833 )</b>
- <b>OpenFlipper 1.2 ( ? , 13888 )</b>
- <b>ACG</b>
- DrawMesh
- Fixed crash with some empty meshes
......@@ -66,12 +66,15 @@
- Do not reset picking toolbar's position and orientation each time it is shown.
- Fixed bug where logger and toolbar where invisible
- Modified drawmode context menu to stay open if drawmodes are combined.
- Help
- Open Help browser if waht's this links are clicked.
- <b>Interfaces</b>
- General
- Use const ref for passing strings where possible
- BaseInterface
- Added Basinterface function to switch renderer
- Added function to get current renderer
- Added slotSceneDrawn. Gets triggered after gl update. (closes #449)
- FileInterface
- Added getAllFileFilters signal to LoadSaveInterface. This signal was documented but in fact never implemented.
- Added two convenience functions for list of recent items bookkeeping. (rememberRecentItem,getRecentItems)
......@@ -168,7 +171,9 @@
- Documentation for Render Interface
- Added lots of documentation for plugin programming (with tikz pictures for the flow diagrams)
- <b>Testing</b>
- Integrated basic testing framework for file load/save testing
- Integrated testing framework for file load/save testing
- Integrated testing generators for algorithms
- Run unittests of OpenMesh when OpenFlipper tests are run
- <b>Build System</b>
- Support Visual Studio 2010 and QT 4.8
- Added option to allow in source builds (not recommended but it works)
......@@ -180,6 +185,7 @@
- Default warnings now contain -Wextra
- Moved OpenMesh sources to libs_required subfolder
- Switched to QWT 6 (and enabled it on mac)
- Use one global doxy file to control the generation of the help files for plugins
- <b>OpenFlipper 1.1 ( 2011.09.26 , 12468 )</b>
- <b>ACG</b>
......
......@@ -91,7 +91,7 @@ FilePTSPlugin::FilePTSPlugin() :
}
bool FilePTSPlugin::readBinaryFile(std::ifstream &_instream, SplatCloudNode *_splatCloudNode)
bool FilePTSPlugin::readBinaryFile( std::ifstream &_instream, SplatCloud *_splatCloud )
{
// set default options
bool loadNormals = true;
......@@ -131,7 +131,7 @@ bool FilePTSPlugin::readBinaryFile(std::ifstream &_instream, SplatCloudNode *_sp
point[1] = pnt[1];
point[2] = pnt[2];
_splatCloudNode->splatCloud()->addPoint(point);
_splatCloud->addPoint(point);
}
}
......@@ -147,7 +147,7 @@ bool FilePTSPlugin::readBinaryFile(std::ifstream &_instream, SplatCloudNode *_sp
normal[1] = nrm[1];