E57 Reader Best Practices
This is a list of the best practices on interpreting the E2807 standard and using the libE57 library. 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
Click each item to expand its details. 
- 
Using IntensityLimits
 
Since the intensity unit is unspecified it is necessary to normalize it into a known range before converting it into other usable forms.
 
//  SimpleAPI
	double	intOffset = header.intensityLimits.intensityMinimum;
	double	intRange = header.intensityLimits.intensityMaximum - intOffset;
	if(intRange <= 0.) intRange = 1.;
	
//  FoundationAPI
	double intensityMinimum = 0.;
	double intensityMaximum = 1.;
	if(scan.isDefined("intensityLimits"))
	{
		StructureNode intbox(scan.get("intensityLimits"));
		if( intbox.get("intensityMaximum").type() == E57_SCALED_INTEGER ) {
			intensityMaximum = (double)	ScaledIntegerNode(intbox.get("intensityMaximum")).scaledValue();
			intensityMinimum = (double)	ScaledIntegerNode(intbox.get("intensityMinimum")).scaledValue();
		}
		else if( intbox.get("intensityMaximum").type() == E57_FLOAT ){
			intensityMaximum = FloatNode(intbox.get("intensityMaximum")).value();
			intensityMinimum = FloatNode(intbox.get("intensityMinimum")).value();
		}
		else if( intbox.get("intensityMaximum").type() == E57_INTEGER) {
			intensityMaximum = (double)	IntegerNode(intbox.get("intensityMaximum")).value();
			intensityMinimum = (double)	IntegerNode(intbox.get("intensityMinimum")).value();
		}
	}
	double	intOffset = intensityMinimum;
	double	intRange = intensityMaximum - intOffset;
	if(intRange <= 0.) intRange = 1.;	
...
//for each point this converts intensity data into 0. to 1. range
	double	intensity = (intensityData[i] - intOffset) / intRange;
 
 
- 
Using ColorLimits
 
Since the color unit is unspecified it is necessary to convert it into a known range before using it.
 
//  SimpleAPI
	double	redOffset = header.colorLimits.colorRedMinimum;
	double	redRange = header.colorLimits.colorRedMaximum - redOffset;
	if(redRange <= 0.) redRange = 1.;
	double	greenOffset = header.colorLimits.colorGreenMinimum;
	double	greenRange = header.colorLimits.colorGreenMaximum - greenOffset;
	if(greenRange <= 0.) greenRange = 1.;
	double	blueOffset = header.colorLimits.colorBlueMinimum;
	double	blueRange = header.colorLimits.colorBlueMaximum - blueOffset;
	if(blueRange <= 0.) blueRange = 1.;
//  FoundationAPI
	double	colorRedMinimum = 0.;
	double	colorRedMaximum = 0.;
	double	colorGreenMinimum = 0.;
	double	colorGreenMaximum = 0.;
	double	colorBlueMinimum = 0.;
	double	colorBlueMaximum = 0.;
	if(scan.isDefined("colorLimits"))
	{
		StructureNode colorbox(scan.get("colorLimits"));
		if( colorbox.get("colorRedMaximum").type() == E57_SCALED_INTEGER ) {
			colorRedMaximum = (double) ScaledIntegerNode(colorbox.get("colorRedMaximum")).scaledValue();
			colorRedMinimum = (double) ScaledIntegerNode(colorbox.get("colorRedMinimum")).scaledValue();
			colorGreenMaximum = (double) ScaledIntegerNode(colorbox.get("colorGreenMaximum")).scaledValue();
			colorGreenMinimum = (double) ScaledIntegerNode(colorbox.get("colorGreenMinimum")).scaledValue();
			colorBlueMaximum = (double) ScaledIntegerNode(colorbox.get("colorBlueMaximum")).scaledValue();
			colorBlueMinimum = (double) ScaledIntegerNode(colorbox.get("colorBlueMinimum")).scaledValue();
		}
		else if( colorbox.get("colorRedMaximum").type() == E57_FLOAT ){
			colorRedMaximum = FloatNode(colorbox.get("colorRedMaximum")).value();
			colorRedMinimum = FloatNode(colorbox.get("colorRedMinimum")).value();
			colorGreenMaximum = FloatNode(colorbox.get("colorGreenMaximum")).value();
			colorGreenMinimum = FloatNode(colorbox.get("colorGreenMinimum")).value();
			colorBlueMaximum = FloatNode(colorbox.get("colorBlueMaximum")).value();
			colorBlueMinimum = FloatNode(colorbox.get("colorBlueMinimum")).value();
		}
		else if( colorbox.get("colorRedMaximum").type() == E57_INTEGER) {
			colorRedMaximum = (double) IntegerNode(colorbox.get("colorRedMaximum")).value();
			colorRedMinimum = (double) IntegerNode(colorbox.get("colorRedMinimum")).value();
			colorGreenMaximum = (double) IntegerNode(colorbox.get("colorGreenMaximum")).value();
			colorGreenMinimum = (double) IntegerNode(colorbox.get("colorGreenMinimum")).value();
			colorBlueMaximum = (double) IntegerNode(colorbox.get("colorBlueMaximum")).value();
			colorBlueMinimum = (double) IntegerNode(colorbox.get("colorBlueMinimum")).value();
		}
	}
	double	redOffset = colorRedMinimum;
	double	redRange = colorRedMaximum - redOffset;
	if(redRange <= 0.) redRange = 1.;
	double	greenOffset = colorGreenMinimum;
	double	greenRange = colorGreenMaximum - greenOffset;
	if(greenRange <= 0.) greenRange = 1.;
	double	blueOffset = colorBlueMinimum;
	double	blueRange = colorBlueMaximum - blueOffset;
	if(blueRange <= 0.) blueRange = 1.;
...
//for each point this converts color data into 0 to 255 range
	UCHAR	red = (UCHAR) (((redData[i] - redOffset) * 255) / redRange);
	UCHAR	green = (UCHAR) (((greenData[i] - greenOffset) * 255) / greenRange);
	UCHAR	blue = (UCHAR) (((blueData[i] - blueOffset) * 255) / blueRange);
 
 
- 
Using IndexBounds for Structured Size
 
The structure point cloud size can be calculated using the following:
 
//  SimpleAPI
	int		nSizeRows = header.indexBounds.rowMaximum - header.indexBounds.rowMinimum + 1;
	int		nSizeColumns = header.indexBounds.columnMaximum - header.indexBounds.columnMinimum + 1;
	int		nSizeReturns = header.indexBounds.returnMaximum - header.indexBounds.returnMinimum + 1;
	
//  FoundationAPI
	int		rowMaximum = 0.;
	int		rowMinimum = 0.;
	int		columnMaximum = 0.;
	int		columnMinimum = 0.;
	int		returnMaximum = 0.;
	int		returnMinimum = 0.;
	
	if(scan.isDefined("indexBounds"))
	{
		StructureNode ibox(scan.get("indexBounds"));
		if(ibox.isDefined("rowMaximum"))
		{
			rowMinimum = IntegerNode(ibox.get("rowMinimum")).value();
			rowMaximum = IntegerNode(ibox.get("rowMaximum")).value();
		}
		if(ibox.isDefined("columnMaximum"))
		{
			columnMinimum = IntegerNode(ibox.get("columnMinimum")).value();
			columnMaximum = IntegerNode(ibox.get("columnMaximum")).value();
		}
		if(ibox.isDefined("returnMaximum"))
		{
			returnMinimum = IntegerNode(ibox.get("returnMinimum")).value();
			returnMaximum = IntegerNode(ibox.get("returnMaximum")).value();
		}
	}
	int		nSizeRows = rowMaximum - rowMinimum + 1;
	int		nSizeColumns = columnMaximum - columnMinimum + 1;
	int		nSizeReturns = returnMaximum - returnMinimum + 1;
 
 
- 
Converting Quaternion to Matrix
 
Creating a rotation matrix from a quaternion:
 
//  SimpleAPI
	double w = header.pose.rotation.w;
	double x = header.pose.rotation.x;
	double y = header.pose.rotation.y;
	double z = header.pose.rotation.z;
	
//  FoundationAPI
	double w,x,y,z;
	if(scan.isDefined("pose"))
	{
		StructureNode pose(scan.get("pose"));
		if(pose.isDefined("rotation"))
		{
			StructureNode rotation(pose.get("rotation"));
			w = FloatNode(rotation.get("w")).value();
			x = FloatNode(rotation.get("x")).value();
			y = FloatNode(rotation.get("y")).value();
			z = FloatNode(rotation.get("z")).value();
		}
	}
	
//  make rotation matrix	
	double mat[3][3];
	
	mat[0][0] = 1. - 2.*y*y - 2.*z*z;
	mat[0][1] = 2.*x*y - 2.*z*w;
	mat[0][2] = 2.*x*z + 2.*y*w;
	mat[1][0] = 2.*x*y + 2.*z*w;
	mat[1][1] = 1. - 2.*x*x - 2.*z*z;
	mat[1][2] = 2.*y*z - 2.*x*w;
	mat[2][0] = 2.*x*z - 2.*y*w;
	mat[2][1] = 2.*y*z + 2.*x*w;
	mat[2][2] = 1. - 2.*x*x - 2.*y*y;
 
 
- 
Reading Guids
 
If the E57 writer used a windows GUID then this code will recover the GUID structure from a string.
 
#if defined(_MSC_VER)	// Only for windows
	GUID guid;	//--- Here is the GUID
	
//  FoundationAPI
	ustring guid = StringNode(root_.get("guid")).value();
	CString strGuid = (_bstr_t) guid;	//converts char to wchar
	
//  SimpleAPI
	CString strGuid = (_bstr_t) header.guid.c_str();
	
//add {} if missing
	CString winGuid = strGuid;
	if( strGuid[0] != _T('{'))
	{
		winGuid = _T("{");
		winGuid += strGuid;
		winGuid += _T("}");
	}
	
//looking for a string like "{6A91E935-5559-477b-BE0C-7CE4E0BDFB7C}"	
	if( winGuid.GetLength() == 38 &&
		winGuid[0] == _T('{') &&
		winGuid[9] == _T('-') &&
		winGuid[14] == _T('-') &&
		winGuid[19] == _T('-') &&
		winGuid[24] == _T('-') &&
		winGuid[37] == _T('}'))
	{
//convert to GUID	
		HRESULT hr = IIDFromString((LPOLESTR) winGuid,(LPIID) &guid);
	}
	else
	{
	...	//guid is not a windows guid
	}
	
#else	//Non-windows
#  include "boost/uuid/uuid.hpp"
#  include "boost/uuid/uuid_generators.hpp"
#  include "boost/uuid/uuid_io.hpp"
	boost::uuids::uuid Uuid;	//--- Here is the UUID
	
//  FoundationAPI
	string  strUuid = StringNode(root_.get("guid")).value();
	
//  SimpleAPI
	string	strUuid = header.guid.c_str();
	
//remove {} if present
	if(strUuid[0] == '{')
		strUuid.erase(1,0);
		
//looking for a string like "6A91E935-5559-477b-BE0C-7CE4E0BDFB7C"
	if( strUuid.length() >= 36 &&
		strUuid[8] == '-' &&
		strUuid[13] == '-' &&
		strUuid[18] == '-' &&
		strUuid[23] == '-')
	{
//convert to uuid	
		std::stringstream ss;
		ss << strUuid;
		ss >> Uuid;
	}
	else
	{
	...  //uuid is not a windows guid
	}
#endif	
 
 
- 
Reading GPS Date Time
 
Use this code to read the GPS Date Time fields.
 
//  SimpleAPI
#if defined(_MSC_VER)	// Only for windows
	SYSTEMTIME		fileDateTime;
	header.acquisitionStart.dateTimeValue.GetSystemTime(fileDateTime);
#else
	int year, month, day, hour, minute;
	float seconds;
	header.acquisitionStart.dateTimeValue.GetUTCDateTime(year, month, day, hour, minute, seconds);
#endif
	
//  FoundationAPI
	double 	dateTimeValue = 0.;
	int	isAtomicClockReferenced = 0;
	
	if(scan.isDefined("acquisitionStart"))
	{
		StructureNode acquisitionStart(scan.get("acquisitionStart"));
		dateTimeValue = FloatNode(acquisitionStart.get("dateTimeValue")).value();
		isAtomicClockReferenced = (int32_t) IntegerNode(acquisitionStart.get("isAtomicClockReferenced")).value();
	}
	
#ifdef _C_TIMECONV_H_
	unsigned short	utc_year;	//Universal Time Coordinated [year]
	unsigned char	utc_month;	//1-12 months
	unsigned char	utc_day;	//1-31 days
	unsigned char	utc_hour;	//hours
	unsigned char	utc_minute;	//minutes
	float		utc_seconds;//seconds
	unsigned short	gps_week;	//GPS week (0-1024+)
	double		gps_tow;	//GPS time of week(0-604800.0) seconds
	
	gps_week = ((int)floor(dateTimeValue))/604800;
	gps_tow = dateTimeValue - gps_week*604800.;
	
	bool result = TIMECONV_GetUTCTimeFromGPSTime( gps_week, gps_tow,
		&utc_year, &utc_month, &utc_day, &utc_hour, &utc_minute, &utc_seconds);
#endif
 
 
- 
Reading Scaled Integers
 
Use this code to recover the scaled integer point data range.  However, the point data has already been converted when you get the data.
 
//  SimpleAPI
	double pointRangeScaledInteger = header.pointFields.pointRangeScaledInteger;
	double pointRangeMinimum = header.pointFields.pointRangeMinimum;
	double pointRangeMaximum = header.pointFields.pointRangeMaximum; 
	
//  FoundationAPI
	double pointRangeScaledInteger = 0.; //FloatNode
	double pointRangeMinimum = 0.;
	double pointRangeMaximum = 0.; 
	if( proto.isDefined("cartesianX"))
	{
		if( proto.get("cartesianX").type() == E57_SCALED_INTEGER )
		{
			double scale = ScaledIntegerNode(proto.get("cartesianX")).scale();
			double offset = ScaledIntegerNode(proto.get("cartesianX")).offset();
			int64_t minimum = ScaledIntegerNode(proto.get("cartesianX")).minimum();
			int64_t maximum = ScaledIntegerNode(proto.get("cartesianX")).maximum();
			pointRangeMinimum = (double) minimum * scale + offset;	
			pointRangeMaximum = (double) maximum * scale + offset;
			pointRangeScaledInteger = scale;
		}
		else if( proto.get("cartesianX").type() == E57_FLOAT )
		{
			pointRangeMinimum =	FloatNode(proto.get("cartesianX")).minimum();
			pointRangeMaximum =	FloatNode(proto.get("cartesianX")).maximum();
		}
	} 
 
 
- 
Reading Cartesian Bounds
 
Use this code to read the CartesianBounds data.
 
  FoundationAPI
	double MaxX,MinX,MaxY,MinY,MaxZ,MinZ;
	if(scan.isDefined("cartesianBounds"))
	{
		StructureNode bbox(scan.get("cartesianBounds"));
		if( bbox.get("xMinimum").type() == E57_SCALED_INTEGER ) {
			MinX = (double) ScaledIntegerNode(bbox.get("xMinimum")).scaledValue();
			MaxX = (double) ScaledIntegerNode(bbox.get("xMaximum")).scaledValue();
			MinY = (double) ScaledIntegerNode(bbox.get("yMinimum")).scaledValue();
			MaxY = (double) ScaledIntegerNode(bbox.get("yMaximum")).scaledValue();
			MinZ = (double) ScaledIntegerNode(bbox.get("zMinimum")).scaledValue();
			MaxZ = (double) ScaledIntegerNode(bbox.get("zMaximum")).scaledValue();
		}
		else if( bbox.get("xMinimum").type() == E57_INTEGER ) {
			MinX = (double) IntegerNode(bbox.get("xMinimum")).value();
			MaxX = (double) IntegerNode(bbox.get("xMaximum")).value();
			MinY = (double) IntegerNode(bbox.get("yMinimum")).value();
			MaxY = (double) IntegerNode(bbox.get("yMaximum")).value();
			MinZ = (double) IntegerNode(bbox.get("zMinimum")).value();
			MaxZ = (double) IntegerNode(bbox.get("zMaximum")).value();
		}	
		else if( bbox.get("xMinimum").type() == E57_FLOAT ){
			MinX = FloatNode(bbox.get("xMinimum")).value();
			MaxX = FloatNode(bbox.get("xMaximum")).value();
			MinY = FloatNode(bbox.get("yMinimum")).value();
			MaxY = FloatNode(bbox.get("yMaximum")).value();
			MinZ = FloatNode(bbox.get("zMinimum")).value();
			MaxZ = FloatNode(bbox.get("zMaximum")).value();
		}
	}
  SimpleAPI
	double MinX = header.cartesianBounds.xMinimum;
	double MaxX = header.cartesianBounds.xMaximum;
	double MinY = header.cartesianBounds.yMinimum;
	double MaxY = header.cartesianBounds.yMaximum;
	double MinZ = header.cartesianBounds.zMinimum;
	double MaxZ = header.cartesianBounds.zMaximum;
 
 
- 
Reading Spherical Bounds
 
Use this code to read the SphericalBounds data.
 
  FoundationAPI
	double MaxRange,MinRange,AzimuthStart,AzimuthEnd,MaxElevation,MinElevation;
	if(scan.isDefined("sphericalBounds"))
	{
		StructureNode sbox(scan.get("sphericalBounds"));
		if( sbox.get("rangeMinimum").type() == E57_SCALED_INTEGER ) {
			MinRange = (double) ScaledIntegerNode(sbox.get("rangeMinimum")).scaledValue();
			MaxRange = (double) ScaledIntegerNode(sbox.get("rangeMaximum")).scaledValue();
		}
		else if( sbox.get("rangeMinimum").type() == E57_FLOAT ){
			MinRange = FloatNode(sbox.get("rangeMinimum")).value();
			MaxRange = FloatNode(sbox.get("rangeMaximum")).value();
		}
		if( sbox.get("elevationMinimum").type() == E57_SCALED_INTEGER ) {
			MinElevation = (double) ScaledIntegerNode(sbox.get("elevationMinimum")).scaledValue();
			MaxElevation = (double) ScaledIntegerNode(sbox.get("elevationMaximum")).scaledValue();
		}
		else if( sbox.get("elevationMinimum").type() == E57_FLOAT ){
			MinElevation = FloatNode(sbox.get("elevationMinimum")).value();
			MaxElevation = FloatNode(sbox.get("elevationMaximum")).value();
		}
		if( sbox.get("azimuthStart").type() == E57_SCALED_INTEGER ) {
			AzimuthStart = (double) ScaledIntegerNode(sbox.get("azimuthStart")).scaledValue();
			AzimuthEnd = (double) ScaledIntegerNode(sbox.get("azimuthEnd")).scaledValue();
		}
		else if( sbox.get("azimuthStart").type() == E57_FLOAT ){
			AzimuthStart = FloatNode(sbox.get("azimuthStart")).value();
			AzimuthEnd = FloatNode(sbox.get("azimuthEnd")).value();
		}
	}
  SimpleAPI
	double MinRange = header.sphericalBounds.rangeMinimum;
	double MaxRange = header.sphericalBounds.rangeMaximum;
	double MinElevation = header.sphericalBounds.elevationMinimum;
	double MaxElevation = header.sphericalBounds.elevationMaximum;
	double AzimuthStart = header.sphericalBounds.azimuthStart;
	double AzimuthEnd = header.sphericalBounds.azimuthEnd;
 
 
- 
Reading Return Index
 
The standard states that returnIndex is zero based.  That is, 0 is the first return, 1 is the second, and so on.  Shall be in the interval [0, returnCount - 1].  That means the indexBounds.returnMinimum will always be 0. 
 
The returnCount is the total number of returns for the pulse that is corresponds to.  Shall be in the interval of [0, indexBounds.returnMaximum + 1].  This means the a returnCount of 0 is an invalid point.
 
So for a scanner returning upto 3 return points, the returnIndex,returnCount would be 0,3 for the first return,  1,3 for the second return, and 2,3 for the last return.  indexBounds.returnMinimum will be 0 and indexBounds.returnMaximum will be 2;
 
	int nSize = 1024;  //buffer size;
	int8_t *pReturnIndex = NULL;
	int8_t *pReturnCount = NULL;
//  SimpleAPI
	int	returnMaximum = 0.;
	int	returnMinimum = 0.;
	if(header.pointFields.returnIndexField)
	{
		pReturnIndex = new int8_t[nSize];
		returnMinimum = (int) header.indexBounds.returnMinimum;
		returnMaximum = (int) header.indexBounds.returnMaximum;
	}
	if(header.pointFields.returnCountField)
		pReturnCount = new int8_t[nSize];
	...
	e57::CompressedVectorReader reader = eReader->SetUpData3DPointsData(
		scanIndex,		// data block index given by the NewData3D
		nSize,			// size of each element buffer.
		pCartesianX,		// pointer to a buffer with the X coordinate (in meters) of the point in Cartesian coordinates
		pCartesianY,		// pointer to a buffer with the Y coordinate (in meters) of the point in Cartesian coordinates
		pCartesianZ,		// pointer to a buffer with the Z coordinate (in meters) of the point in Cartesian coordinates
		pXYZInvalid,		// Value = 0 if the point is considered valid, 1 or 2 otherwise
		pIntData,		// pointer to a buffer with the Point response intensity. Unit is unspecified
		pIntInvalid,		// Value = 0 if the intensity is considered valid, 1 otherwise
		pRedData,		// pointer to a buffer with the Red color coefficient. Unit is unspecified
		pGreenData,		// pointer to a buffer with the Green color coefficient. Unit is unspecified
		pBlueData,		// pointer to a buffer with the Blue color coefficient. Unit is unspecified
		pColorInvalid,		// Value = 0 if the color is considered valid, 1 otherwise
		pRangeData,		// pointer to a buffer with the range (in meters) of points in spherical coordinates. Shall be non-negative
		pAzimuthData,		// pointer to a buffer with the Azimuth angle (in radians) of point in spherical coordinates
		pElevationData,		// pointer to a buffer with the Elevation angle (in radians) of point in spherical coordinates
		pRAEInvalid,		// Value = 0 if the range is considered valid, 1 otherwise
		pRowIndex,		// pointer to a buffer with the row number of point (zero based).
					// This is useful for data that is stored in a regular grid.  Shall be in the interval (0, 2^63).
		pColumnIndex,		// pointer to a buffer with the column number of point (zero based).
					// This is useful for data that is stored in a regular grid. Shall be in the interval (0, 2^63).
		pReturnIndex,		// pointer to a buffer with the number of this return (zero based).
					// That is, 0 is the first return, 1 is the second, and so on. Shall be in the interval (0, returnCount).
					// Only for multi-return sensors. 
		pReturnCount,		// pointer to a buffer with the total number of returns for the pulse that this corresponds to.
					// Shall be in the interval (0, 2^63).  Only for multi-return sensors. 
		pTimeStamp,		// pointer to a buffer with the time (in seconds) since the start time for the data,
					// which is given by acquisitionStart in the parent Data3D Structure.  Shall be non-negative
		pTimeInvalid		// Value = 0 if the timeStamp is considered valid, 1 otherwise
		);
	...
//  FoundationAPI
	StructureNode scan(data3D_.get(dataIndex));
	
	int	returnMaximum = 0.;
	int	returnMinimum = 0.;
	if(scan.isDefined("indexBounds"))
	{
		StructureNode ibox(scan.get("indexBounds"));
		...
		if(ibox.isDefined("returnMaximum"))
		{
			returnMinimum = IntegerNode(ibox.get("returnMinimum")).value();
			returnMaximum = IntegerNode(ibox.get("returnMaximum")).value();
		}
	}
	
	CompressedVectorNode points(scan.get("points"));
	StructureNode prototype(points.prototype());
	...
	int64_t protoCount = prototype.childCount();
	int64_t protoIndex;
	vector destBuffers;
	for( protoIndex = 0; protoIndex < protoCount; protoIndex++)
	{
		ustring		name = prototype.get(protoIndex).elementName();
		...
		if((name.compare("returnIndex") == 0) && prototype.isDefined("returnIndex")) 
		{
			pReturnIndex = new int8_t[count];
			destBuffers.push_back(SourceDestBuffer(imf_, "returnIndex", pReturnIndex,  (unsigned) count, true, false));
		}
		else if((name.compare("returnCount") == 0) && prototype.isDefined("returnCount"))
		{
			pReturnCount = new int8_t[count];
			destBuffers.push_back(SourceDestBuffer(imf_, "returnCount", pReturnCount,  (unsigned) count, true, false));
		}
		...
	}
	CompressedVectorReader reader = points.reader(destBuffers);
	...
// Both
	unsigned	size = 0;
	while(size = reader.read())
	{
		for(long i = 0; i < size; i++)
		{
			Point  P(pCartesianX[i],pCartesianY[i],pCartesianZ[i]);
			if(pReturnIndex)
			{
				int ret = (pReturnIndex[i] - returnMinimum);
				
			//cannot deal with more than one return per point
				// use only the first return
				if(ret > 0)	continue;	//discard other returns
				
				// or use only the last return
				if(ret != (pReturnCount[i] - 1))	continue;	//discard all others
				
				... //use this point
			}
			...
		}
	}
 
 
 
   
   
   
   
   
   
   
   
  
  
   
   
   
   
   
   
   
   
   
   
   
   
   
   
  
This site is © Copyright 2010 E57.04 3D Imaging System File Format Committee, All Rights Reserved 
 			 |