diff --git a/include/meshio/meshio_defines.hpp b/include/meshio/meshio_defines.hpp index 857d306..34c9cef 100644 --- a/include/meshio/meshio_defines.hpp +++ b/include/meshio/meshio_defines.hpp @@ -11,6 +11,7 @@ #define __MESHIO_DEFINES_HPP__ #include +#include "vectors.hpp" namespace meshio { @@ -20,39 +21,6 @@ enum STLFormat { STL_BINARY = 1 }; -template -struct Vec4 { - T x; - T y; - T z; - T w; -}; - -template -struct Vec3 { - T x; - T y; - T z; - struct Vec3& operator+=(const struct Vec3& pVec3) { - x += pVec3.x; - y += pVec3.y; - z += pVec3.z; - return *this; - } - struct Vec3& operator/=(const int pDiv) { - x /= pDiv; - y /= pDiv; - z /= pDiv; - return *this; - } -}; - -template -struct Vec2 { - T x; - T y; -}; - template class Mesh { public: @@ -62,6 +30,12 @@ class Mesh { std::vector< Vec4 > mColors; std::vector< unsigned > mIndices; + Mesh() {} + + ~Mesh() { + this->clear(); + } + void resize(unsigned pSize) { mPositions.resize(pSize); mNormals.resize(pSize); @@ -82,14 +56,19 @@ class Mesh { } }; -/* - * struct to store data from STL file - */ -template -struct STLData { +/* STLData class to store data from STL file */ +template +class STLData { + public: std::vector< Vec4 > mPositions; std::vector< Vec3 > mNormals; + STLData() {} + + ~STLData() { + this->clear(); + } + void resize(unsigned pNumTriangles) { mPositions.resize(3*pNumTriangles); mNormals.resize(pNumTriangles); @@ -99,6 +78,24 @@ struct STLData { mPositions.clear(); mNormals.clear(); } + + bool operator==(STLData& pSTLObj) { + if(this->mPositions.size() != pSTLObj.mPositions.size()) + return false; + + if(this->mNormals.size() != pSTLObj.mNormals.size()) + return false; + + for(unsigned i = 0; i < mPositions.size(); ++i) + if(!(this->mPositions[i] == pSTLObj.mPositions[i])) + return false; + + for(unsigned i = 0; i < mNormals.size(); ++i) + if(!(this->mNormals[i] == pSTLObj.mNormals[i])) + return false; + + return true; + } }; } diff --git a/include/meshio/vectors.hpp b/include/meshio/vectors.hpp new file mode 100644 index 0000000..8c21b91 --- /dev/null +++ b/include/meshio/vectors.hpp @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2015, Lakshman Anumolu, Pradeep Garigipati + * All rights reserved. + * + * This file is part of MeshIO whose distribution is governed by + * the BSD 2-Clause License contained in the accompanying LICENSE.txt + * file. + */ + +#ifndef __VECTORS_HPP__ +#define __VECTORS_HPP__ + +#include + +namespace meshio +{ + +template +class Vec2 { + public: + T x,y; + + Vec2(T pX, T pY) { + x = pX; + y = pY; + } + + Vec2(T pX) { + Vec2(pX, 0); + } + + Vec2() { + Vec2(0, 0); + } + + Vec2(const Vec2& pVec2) { + *this = pVec2; + } + + ~Vec2() {} + + void operator=(const Vec2& pVec2) { + x = pVec2.x; + y = pVec2.y; + } + + Vec2& operator+=(const Vec2& pVec2) { + x += pVec2.x; + y += pVec2.y; + return *this; + } + + Vec2& operator-=(const Vec2& pVec2) { + x -= pVec2.x; + y -= pVec2.y; + return *this; + } + + Vec2& operator*=(const T pDiv) { + x *= pDiv; + y *= pDiv; + return *this; + } + + Vec2& operator/=(const T pDiv) { + T oneByPDiv = (T)1/pDiv; + x *= oneByPDiv; + y *= oneByPDiv; + return *this; + } + + bool operator==(const Vec2& pVec2) { + return ((x == pVec2.x) && (y == pVec2.y)); + } + + /* Dot product of two vectors */ + Vec2 operator&(const Vec2& pVec2) { + return Vec2(this->x*pVec2.x, this->y*pVec2.y); + } + + /* Cross product of two vectors */ + Vec2 operator^(const Vec2& pVec2) { + return Vec3(0, 0, this->x*pVec2.y-this->y*pVec2.x); + } +}; + +template +class Vec3 { + public: + T x,y,z; + + Vec3(T pX, T pY, T pZ) { + x = pX; + y = pY; + z = pZ; + } + + Vec3(T pX, T pY) { + Vec3(pX, pY, 0); + } + + Vec3(T pX) { + Vec3(pX, 0, 0); + } + + Vec3() { + Vec3(0, 0, 0); + } + + Vec3(const Vec3& pVec3) { + *this = pVec3; + } + + ~Vec3() {} + + void operator=(const Vec3& pVec3) { + x = pVec3.x; + y = pVec3.y; + z = pVec3.z; + } + + Vec3& operator+=(const Vec3& pVec3) { + x += pVec3.x; + y += pVec3.y; + z += pVec3.z; + return *this; + } + + Vec3& operator-=(const Vec3& pVec3) { + x -= pVec3.x; + y -= pVec3.y; + z -= pVec3.z; + return *this; + } + + Vec3& operator*=(const T pDiv) { + x *= pDiv; + y *= pDiv; + z *= pDiv; + return *this; + } + + Vec3& operator/=(const T pDiv) { + T oneByPDiv = (T)1/pDiv; + x *= oneByPDiv; + y *= oneByPDiv; + z *= oneByPDiv; + return *this; + } + + bool operator==(const Vec3& pVec3) { + return ((x == pVec3.x) && (y == pVec3.y) && (z == pVec3.z)); + } + + /* Dot product of two vectors */ + Vec3 operator&(const Vec3& pVec3) { + return Vec3(this->x*pVec3.x, this->y*pVec3.y, this->z*pVec3.z); + } + + /* Cross product of two vectors */ + Vec3 operator^(const Vec3& pVec3) { + return Vec3(this->y*pVec3.z-this->z*pVec3.y, + this->z*pVec3.x-this->x*pVec3.z, + this->x*pVec3.y-this->y*pVec3.x); + } +}; + +template +class Vec4 { + public: + T x,y,z,w; + + Vec4(T pX, T pY, T pZ, T pW) { + x = pX; + y = pY; + z = pZ; + w = pW; + } + + Vec4(T pX, T pY, T pZ) { + Vec4(pX, pY, pZ, 0); + } + + Vec4(T pX, T pY) { + Vec4(pX, pY, 0, 0); + } + + Vec4(T pX) { + Vec4(pX, 0, 0, 0); + } + + Vec4() { + Vec4(0, 0, 0, 0); + } + + Vec4(const Vec4& pVec4) { + *this = pVec4; + } + + ~Vec4() {} + + void operator=(const Vec4& pVec4) { + x = pVec4.x; + y = pVec4.y; + z = pVec4.z; + w = pVec4.w; + } + + Vec4& operator+=(const Vec4& pVec4) { + x += pVec4.x; + y += pVec4.y; + z += pVec4.z; + w += pVec4.w; + return *this; + } + + Vec4& operator-=(const Vec4& pVec4) { + x -= pVec4.x; + y -= pVec4.y; + z -= pVec4.z; + w -= pVec4.w; + return *this; + } + + Vec4& operator*=(const T pDiv) { + x *= pDiv; + y *= pDiv; + z *= pDiv; + w *= pDiv; + return *this; + } + + Vec4& operator/=(const T pDiv) { + T oneByPDiv = (T)1/pDiv; + x *= oneByPDiv; + y *= oneByPDiv; + z *= oneByPDiv; + w *= oneByPDiv; + return *this; + } + + bool operator==(const Vec4& pVec4) { + return ((x == pVec4.x) && (y == pVec4.y) && (z == pVec4.z) && + (w == pVec4.w)); + } +}; + + +} + +#endif // __VECTORS_HPP__ diff --git a/resources/cube_binary.stl b/resources/cube_binary.stl new file mode 100644 index 0000000..3f9189c Binary files /dev/null and b/resources/cube_binary.stl differ diff --git a/test/initialize_reference_objs.inl b/test/initialize_reference_objs.inl new file mode 100644 index 0000000..95dbff1 --- /dev/null +++ b/test/initialize_reference_objs.inl @@ -0,0 +1,61 @@ +template +void initializeReferenceSTLObj(vector< STLData > &refObjs) +{ + for(unsigned i = 0; i < refObjs.size(); ++i) + refObjs[i].clear(); + refObjs.clear(); + + STLData refObj; + refObj.resize(12); + refObj.mNormals[0] = Vec3(0,0,-1); + refObj.mPositions[0] = Vec4(0,0,0,1); + refObj.mPositions[1] = Vec4(1,1,0,1); + refObj.mPositions[2] = Vec4(1,0,0,1); + refObj.mNormals[1] = Vec3(0,0,-1); + refObj.mPositions[3] = Vec4(0,0,0,1); + refObj.mPositions[4] = Vec4(0,1,0,1); + refObj.mPositions[5] = Vec4(1,1,0,1); + refObj.mNormals[2] = Vec3(1,0,0); + refObj.mPositions[6] = Vec4(1,0,0,1); + refObj.mPositions[7] = Vec4(1,1,1,1); + refObj.mPositions[8] = Vec4(1,0,1,1); + refObj.mNormals[3] = Vec3(1,0,0); + refObj.mPositions[9] = Vec4(1,0,0,1); + refObj.mPositions[10] = Vec4(1,1,0,1); + refObj.mPositions[11] = Vec4(1,1,1,1); + refObj.mNormals[4] = Vec3(0,0,1); + refObj.mPositions[12] = Vec4(1,0,1,1); + refObj.mPositions[13] = Vec4(0,1,1,1); + refObj.mPositions[14] = Vec4(0,0,1,1); + refObj.mNormals[5] = Vec3(0,0,1); + refObj.mPositions[15] = Vec4(1,0,1,1); + refObj.mPositions[16] = Vec4(1,1,1,1); + refObj.mPositions[17] = Vec4(0,1,1,1); + refObj.mNormals[6] = Vec3(-1,0,0); + refObj.mPositions[18] = Vec4(0,0,0,1); + refObj.mPositions[19] = Vec4(0,1,1,1); + refObj.mPositions[20] = Vec4(0,1,0,1); + refObj.mNormals[7] = Vec3(-1,0,0); + refObj.mPositions[21] = Vec4(0,0,0,1); + refObj.mPositions[22] = Vec4(0,0,1,1); + refObj.mPositions[23] = Vec4(0,1,1,1); + refObj.mNormals[8] = Vec3(0,1,0); + refObj.mPositions[24] = Vec4(0,1,0,1); + refObj.mPositions[25] = Vec4(1,1,1,1); + refObj.mPositions[26] = Vec4(1,1,0,1); + refObj.mNormals[9] = Vec3(0,1,0); + refObj.mPositions[27] = Vec4(0,1,0,1); + refObj.mPositions[28] = Vec4(0,1,1,1); + refObj.mPositions[29] = Vec4(1,1,1,1); + refObj.mNormals[10] = Vec3(0,-1,0); + refObj.mPositions[30] = Vec4(0,0,0,1); + refObj.mPositions[31] = Vec4(1,0,0,1); + refObj.mPositions[32] = Vec4(1,0,1,1); + refObj.mNormals[11] = Vec3(0,-1,0); + refObj.mPositions[33] = Vec4(0,0,0,1); + refObj.mPositions[34] = Vec4(1,0,1,1); + refObj.mPositions[35] = Vec4(0,0,1,1); + + refObjs.push_back(refObj); +} + diff --git a/test/stl_read_test.cpp b/test/stl_read_test.cpp index 6a7f573..94a391a 100644 --- a/test/stl_read_test.cpp +++ b/test/stl_read_test.cpp @@ -14,54 +14,49 @@ using namespace std; using namespace meshio; -TEST(STL, ReadWrite_BinaryFile) +#include "initialize_reference_objs.inl" + +TEST(STL, READ_BINARY) { - // FIXME - /* - The tests still need to be fixed. This message for Laxman to get to know how to - write unit tests using google test. - */ + /* Reference STLData object */ + vector< STLData > referenceObjs; + initializeReferenceSTLObj(referenceObjs); /* Read stl file using library function */ vector< STLData > objs; - stl::read(objs, TEST_DIR "/binary.stl"); + stl::read(objs, TEST_DIR "/cube_binary.stl"); - /* Write STL file */ - stl::write(objs, TEST_DIR "/binary2binary.stl", meshio::STL_BINARY); + EXPECT_TRUE((objs[0] == referenceObjs[0]) == true); - for(unsigned i = 0; i < objs.size(); ++i) - objs[i].clear(); + referenceObjs.clear(); objs.clear(); - - /* read gold data using regular file reading */ - - /* Now write another helper function that helps you compare two - objects that has same type of data. - - For example, iIn our case we can handle simple objects like square with - hard coded data and much bigger objects can be compared - by cross checking data read from different formats or something - like that. - */ - - /* use the boolean returned by the comparison helper functon - to find check for expected result which is TRUE because the - results should match for our test to pass. This can be done - using Google Test macros such as EXPECT_EQ (Check Below) - */ - - EXPECT_TRUE(true == true/* Ideally you should your comparison function called here*/); } TEST(STL, READ_ASCII) { + /* Reference STLData object */ + vector< STLData > referenceObjs; + initializeReferenceSTLObj(referenceObjs); + vector< STLData > objs; - stl::read(objs, TEST_DIR "/ascii.stl"); + stl::read(objs, TEST_DIR "/cube_ascii.stl"); + + EXPECT_TRUE((objs[0] == referenceObjs[0]) == true); + + referenceObjs.clear(); + objs.clear(); } TEST(STL, WRITE_ASCII) { + /* Reference STLData object */ + vector< STLData > referenceObjs; + initializeReferenceSTLObj(referenceObjs); + vector< STLData > objs; - stl::read(objs, TEST_DIR "/ascii.stl"); - stl::write(objs, TEST_DIR "/ascii2ascii.stl"); + stl::read(objs, TEST_DIR "/cube_ascii.stl"); + stl::write(objs, TEST_DIR "/cube_ascii2ascii.stl"); + + referenceObjs.clear(); + objs.clear(); }