Extension Name E57_EXT_surface_normals XML namespace NOR xmlns:nor="http://www.libe57.org/E57_EXT_surface_normals.txt" Contact Stan Coleby, Intelisum (scoleby @ intelisum.com) Contributors none. Version Last Modified Date: October 19, 2011 Revision: 2 Dependencies none. Overview This extension adds a surface normal vector to each point to indicate the surface orientation at the time of sampling the point data. This normal can be used to do shading in a 3D model. IP Status No known IP claims. New Fields none. New Fields none. New Fields none. New PointRecord Fields Element Name Type Description "nor:normalX" Float/ScaledInteger The X component of a surface normal vector. "nor:normalY" Float/ScaledInteger The Y component of a surface normal vector. "nor:normalZ" Float/ScaledInteger The Z component of a surface normal vector. The surface normal is added as a child element to the PointRecord Structure and is optional. If any elements in the set {nor:normalX, nor:normalY, nor:normalZ} are defined, then all elements in that set shall be defined. The surface normal shall be considered to be unit length where 1 = sqrt( nor:normalX^2 + nor:normalY^2 + nor:normalZ^2); Using the right-handed coordinate system the normal vector should be calculated to point toward the direction of the scanner coordinate system's origin. XML Example ... ... Sample Code /////////////////////////////// // Writing with FoundationAPI// /////////////////////////////// imf_.extensionsAdd("nor","http://www.libe57.org/E57_NOR_surface_normals.txt"); ... // Setup PointRecord prototype ////////////////////////////// double normalMinimum = -2147483648; double normalMaximum = 2147483647; double normalScale = 1./normalMaximum; double normalOffset = 0.; StructureNode prototype = StructureNode(imf_); ... prototype.set("nor:normalX", ScaledIntegerNode(imf_, 0, normalMinimum, normalMaximum, normalScale, normalOffset)); prototype.set("nor:normalX", ScaledIntegerNode(imf_, 0, normalMinimum, normalMaximum, normalScale, normalOffset)); prototype.set("nor:normalX", ScaledIntegerNode(imf_, 0, normalMinimum, normalMaximum, normalScale, normalOffset)); ... VectorNode codecs = VectorNode(imf_, true); CompressedVectorNode points = CompressedVectorNode(imf_, prototype, codecs); scan.set("points", points); // Setup buffers ////////////////////////// int count = 1024; //buffer size; double *pNormalX = new double[count]; double *pNormalY = new double[count]; double *pNormalZ = new double[count}; StructureNode scan(data3D_.get(dataIndex)); CompressedVectorNode points(scan.get("points")); StructureNode prototype(points.prototype()); vector sourceBuffers; ... if(prototype.isDefined("nor:normalX") && (pNormalX != NULL)) sourceBuffers.push_back(SourceDestBuffer(imf_, "nor:normalX", pNormalX, (unsigned) count, true, true)); if(prototype.isDefined("nor:normalY") && (pNormalY != NULL)) sourceBuffers.push_back(SourceDestBuffer(imf_, "nor:normalY", pNormalY, (unsigned) count, true, true)); if(prototype.isDefined("nor:normalZ") && (pNormalZ != NULL)) sourceBuffers.push_back(SourceDestBuffer(imf_, "nor:normalZ", pNormalZ, (unsigned) count, true, true)); ... CompressedVectorWriter writer = points.writer(sourceBuffers); // Write data ////////////////////////////// ... unsigned size; while(size = getData()) { for(long i = 0; i < size; i++) { //get normal N load buffer pNormalX[i] = N.x(); pNormalY[i] = N.y(); pNormalZ[i] = N.z(); } writer.write(size); } write.close(); /////////////////////////////// // Reading with FoundationAPI// /////////////////////////////// int count = 1024; //buffer size; double *pNormalX = new double[count]; double *pNormalY = new double[count]; double *pNormalZ = new double[count}; StructureNode scan(data3D_.get(dataIndex)); 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(); NodeType type = prototype.get(protoIndex).type(); bool scaled = type == E57_SCALED_INTEGER ? true : false; if((name.compare("nor:normalX") == 0) && prototype.isDefined("nor:normalX") && (pNormalX != NULL)) destBuffers.push_back(SourceDestBuffer(imf_, "nor:normalX", pNormalX, (unsigned) count, true, scaled)); else if((name.compare("nor:normalY") == 0) && prototype.isDefined("nor:normalY") && (pNormalY != NULL)) destBuffers.push_back(SourceDestBuffer(imf_, "nor:normalY", pNormalY, (unsigned) count, true,scaled)); else if((name.compare("nor:normalZ") == 0) && prototype.isDefined("nor:normalZ") && (pNormalZ != NULL)) destBuffers.push_back(SourceDestBuffer(imf_, "nor:normalZ", pNormalZ, (unsigned) count, true, scaled)); ... } CompressedVectorReader reader = points.reader(destBuffers); ... //Read data ///////////////////////// unsigned size = 0; while(size = reader.read()) { for(long i = 0; i < size; i++) { Point P(pCartesianX[i],pCartesianY[i],pCartesianZ[i]); Normal N(pNormalX[i],pNormalY[i],pNormalZ[i]); ... } } Issues none ASTM E57 Listed Submitted Date: September 20, 2011 Revision History Revision 1, 2011/09/20 - Initial version of this document Revision 2, 2011/10/19 - Added copyright notice Copyright Copyright (c) 2010 Stan Coleby (scoleby @ intelisum.com), All Rights Reserved. Permission is hereby granted, free of charge, to any person or organization obtaining a copy of this extension and accompanying documentation covered by this license (this "Extension") to use, reproduce, display, distribute, execute, and transmit this Extension, and to prepare derivative works of this Extension, and to permit third-parties to whom this Extension is furnished to do so, all subject to the following: The copyright notices in this Extension and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of this Extension, in whole or in part, and all derivative works of this Extension, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. Disclaimer THIS EXTENSION 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 THIS EXTENSION BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THIS EXTENSION OR THE USE OR OTHER DEALINGS IN THIS EXTENSION.