diff --git a/happly.h b/happly.h index 46ded3e..d1aed92 100644 --- a/happly.h +++ b/happly.h @@ -76,6 +76,8 @@ template<> inline std::string typeName() { return "short"; template<> inline std::string typeName() { return "ushort"; } template<> inline std::string typeName() { return "int"; } template<> inline std::string typeName() { return "uint"; } +template<> inline std::string typeName() { return "int64"; } +template<> inline std::string typeName() { return "uint64"; } template<> inline std::string typeName() { return "float"; } template<> inline std::string typeName() { return "double"; } @@ -518,11 +520,11 @@ class TypedListProperty : public Property { // Read the size of the list size_t count = 0; stream.read(((char*)&count), listCountBytes); - if (listCountBytes == 8) { + if (listCountBytes == sizeof(uint64_t)) { count = (size_t)swapEndian((uint64_t)count); - } else if (listCountBytes == 4) { + } else if (listCountBytes == sizeof(uint32_t)) { count = (size_t)swapEndian((uint32_t)count); - } else if (listCountBytes == 2) { + } else if (listCountBytes == sizeof(uint16_t)) { count = (size_t)swapEndian((uint16_t)count); } @@ -675,13 +677,15 @@ inline std::unique_ptr createPropertyWithType(const std::string& name, if (isList) { if (listCountTypeStr == "uchar" || listCountTypeStr == "uint8" || listCountTypeStr == "char" || listCountTypeStr == "int8") { - listCountBytes = 1; + listCountBytes = sizeof(uint8_t); } else if (listCountTypeStr == "ushort" || listCountTypeStr == "uint16" || listCountTypeStr == "short" || listCountTypeStr == "int16") { - listCountBytes = 2; + listCountBytes = sizeof(uint16_t); } else if (listCountTypeStr == "uint" || listCountTypeStr == "uint32" || listCountTypeStr == "int" || listCountTypeStr == "int32") { - listCountBytes = 4; + listCountBytes = sizeof(uint32_t); + } else if (listCountTypeStr == "uint64" || listCountTypeStr == "int64") { + listCountBytes = sizeof(uint64_t); } else { throw std::runtime_error("Unrecognized list count type: " + listCountTypeStr); } @@ -716,6 +720,15 @@ inline std::unique_ptr createPropertyWithType(const std::string& name, } } + // 64 bit unsigned + else if (typeStr == "uint64") { + if (isList) { + return std::unique_ptr(new TypedListProperty(name, listCountBytes)); + } else { + return std::unique_ptr(new TypedProperty(name)); + } + } + // = Signed int // 8 bit signed @@ -745,6 +758,15 @@ inline std::unique_ptr createPropertyWithType(const std::string& name, } } + // 64 bit signed + else if (typeStr == "int64") { + if (isList) { + return std::unique_ptr(new TypedListProperty(name, listCountBytes)); + } else { + return std::unique_ptr(new TypedProperty(name)); + } + } + // = Float // 32 bit float @@ -1612,7 +1634,7 @@ class PLYData { /** * @brief Common-case helper to set face indices. Creates a face element if needed. The input type will be casted to a - * 32 bit integer of the same signedness. + * 64 bit integer of the same signedness. * * @param indices The indices into the vertex list around each face. */ @@ -1627,8 +1649,8 @@ class PLYData { addElement(faceName, N); } - // Cast to 32 bit - typedef typename std::conditional::value, int32_t, uint32_t>::type IndType; + // Cast to 64 bit + typedef typename std::conditional::value, int64_t, uint64_t>::type IndType; std::vector> intInds; for (std::vector& l : indices) { std::vector thisInds; @@ -1637,7 +1659,7 @@ class PLYData { if (valConverted != val) { throw std::runtime_error("Index value " + std::to_string(val) + " could not be converted to a .ply integer without loss of data. Note that .ply " - "only supports 32-bit ints."); + "only supports 64-bit ints."); } thisInds.push_back(valConverted); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b07caf5..5f2aad9 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -10,6 +10,9 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +### Find dependencies +find_package(Boost QUIET) + ### Compile options if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # using Clang (linux or apple) or GCC @@ -87,7 +90,10 @@ target_link_libraries(ply-test gtest) target_include_directories(ply-test PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..") +if(Boost_FOUND) +target_compile_definitions(ply-test PRIVATE HAS_BOOST) +endif() + # Add cmake test target ("make test") enable_testing() add_test(MainTest ply-test) - diff --git a/test/CMakeLists.txt.in b/test/CMakeLists.txt.in index c6247af..37b622b 100644 --- a/test/CMakeLists.txt.in +++ b/test/CMakeLists.txt.in @@ -5,7 +5,7 @@ project(googletest-download NONE) include(ExternalProject) ExternalProject_Add(googletest GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG master + GIT_TAG main SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src" BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build" CONFIGURE_COMMAND "" diff --git a/test/main_test.cpp b/test/main_test.cpp index 8785292..0a9bb6e 100644 --- a/test/main_test.cpp +++ b/test/main_test.cpp @@ -4,6 +4,10 @@ #include #include #include +#ifdef HAS_BOOST +#include +using namespace boost::multiprecision; +#endif #include "gtest/gtest.h" @@ -1141,13 +1145,15 @@ TEST(TypePromotionTest, FaceIndSign) { EXPECT_NE(faceIndsU, faceIndGetU); } +#ifdef HAS_BOOST TEST(TypePromotionTest, FaceIndThrow) { happly::PLYData ply; ply.addElement("face", 3); - std::vector> faceInds{{1, 3, 1LL << 40}, {0, 2, 4, 5}, {1, 1, 1}}; + std::vector> faceInds{{1, 3, 1LL << 40}, {0, 2, 4, 5}, {1, 1, 1}}; EXPECT_THROW(ply.getElement("face").addListProperty("vertex_indices", faceInds), std::runtime_error); } +#endif // === Test reading mesh-like files TEST(MeshTest, ReadWriteASCIIMesh) {