benchs: revamp benchs for Assimp and OpenCascade
This commit is contained in:
parent
83a8b004f1
commit
00c28e1b44
74
benchs/CMakeLists.txt
Normal file
74
benchs/CMakeLists.txt
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#############################################################################
|
||||||
|
## GeomIO Library
|
||||||
|
## Copyright FougSys (2 Mar. 2015)
|
||||||
|
## contact@fougsys.fr
|
||||||
|
##
|
||||||
|
## This software is a reusable library whose purpose is to provide complete
|
||||||
|
## I/O support for various CAD file formats (eg. STL)
|
||||||
|
##
|
||||||
|
## This software is governed by the CeCILL-B license under French law and
|
||||||
|
## abiding by the rules of distribution of free software. You can use,
|
||||||
|
## modify and/ or redistribute the software under the terms of the CeCILL-B
|
||||||
|
## license as circulated by CEA, CNRS and INRIA at the following URL
|
||||||
|
## "http://www.cecill.info".
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 2.6)
|
||||||
|
|
||||||
|
project(gmio_benchmark)
|
||||||
|
|
||||||
|
#set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||||
|
|
||||||
|
# Options
|
||||||
|
option(BENCHMARK_ASSIMP "Build benchmark for Assimp" ON)
|
||||||
|
option(BENCHMARK_OPENCASCADE "Build benchmark for OpenCascade" ON)
|
||||||
|
|
||||||
|
set(ASSIMP_DIR ${CMAKE_SOURCE_DIR} CACHE PATH "Directory where the Assimp library resides")
|
||||||
|
set(OPENCASCADE_DIR ${CMAKE_SOURCE_DIR} CACHE PATH "Directory where the OpenCascade library resides")
|
||||||
|
set(GMIO_DIR ${CMAKE_SOURCE_DIR} CACHE PATH "Directory where the GeomIO library resides")
|
||||||
|
|
||||||
|
# List source files in commons/
|
||||||
|
file(GLOB COMMONS_FILES commons/*)
|
||||||
|
set(COMMONS_FILES ${COMMONS_FILES})
|
||||||
|
#add_definitions(-DGMIO_HAVE_STDINT_H)
|
||||||
|
|
||||||
|
if(BENCHMARK_ASSIMP)
|
||||||
|
add_executable(bench_assimp bench_assimp/main.cpp ${COMMONS_FILES})
|
||||||
|
target_include_directories(
|
||||||
|
bench_assimp
|
||||||
|
PUBLIC ${ASSIMP_DIR}/include
|
||||||
|
PUBLIC ${GMIO_DIR}/include)
|
||||||
|
target_link_libraries(
|
||||||
|
bench_assimp
|
||||||
|
${ASSIMP_DIR}/lib64/assimp.lib
|
||||||
|
${GMIO_DIR}/lib/gmio.lib)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(BENCHMARK_OPENCASCADE)
|
||||||
|
add_executable(bench_occ
|
||||||
|
bench_occ/main.cpp
|
||||||
|
${GMIO_DIR}/src/gmio_support/occ_libstl.cpp
|
||||||
|
${COMMONS_FILES})
|
||||||
|
add_definitions(-D_OCC64 -DWNT)
|
||||||
|
target_include_directories(
|
||||||
|
bench_occ
|
||||||
|
PUBLIC ${OPENCASCADE_DIR}/inc
|
||||||
|
PUBLIC ${GMIO_DIR}/include)
|
||||||
|
target_link_libraries(
|
||||||
|
bench_occ
|
||||||
|
${OPENCASCADE_DIR}/win64/vc11/lib/TKernel.lib
|
||||||
|
${OPENCASCADE_DIR}/win64/vc11/lib/TKMath.lib
|
||||||
|
${OPENCASCADE_DIR}/win64/vc11/lib/TKSTL.lib
|
||||||
|
${GMIO_DIR}/lib/gmio.lib)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
# Find bit size of the target architecture
|
||||||
|
math(EXPR GMIO_TARGET_ARCH_BIT_SIZE "8 * ${CMAKE_SIZEOF_VOID_P}")
|
||||||
|
|
||||||
|
|
||||||
|
# Specific flags for Visual C++
|
||||||
|
if(MSVC)
|
||||||
|
# Disable deprecation warnings about "non-secure" CRT functions
|
||||||
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
endif()
|
@ -1,15 +0,0 @@
|
|||||||
include(../../qmake.build/config.pri)
|
|
||||||
|
|
||||||
TEMPLATE = app
|
|
||||||
TARGET = bench_assimp$$TARGET_SUFFIX
|
|
||||||
|
|
||||||
INCLUDEPATH += $$ASSIMP_ROOT/include
|
|
||||||
|
|
||||||
HEADERS += ../commons/bench_tools.h
|
|
||||||
|
|
||||||
SOURCES += \
|
|
||||||
../commons/bench_tools.c \
|
|
||||||
main.cpp
|
|
||||||
|
|
||||||
LIBS *= -L$$ASSIMP_ROOT/lib -lassimp
|
|
||||||
QMAKE_RPATHDIR *= $$ASSIMP_ROOT/lib
|
|
@ -1,16 +1,15 @@
|
|||||||
#include <assimp/IOSystem.hpp>
|
#include "../commons/bench_tools.h"
|
||||||
#include <assimp/Exporter.hpp>
|
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
#include <assimp/ProgressHandler.hpp>
|
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
extern "C" {
|
#include <gmio_core/error.h>
|
||||||
#include "../commons/bench_tools.h"
|
#include <gmio_stl/stl_io.h>
|
||||||
}
|
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
static void assimp_Importer(const char* filepath)
|
static void bench_assimp_Importer(const char* filepath)
|
||||||
{
|
{
|
||||||
Assimp::Importer importer;
|
Assimp::Importer importer;
|
||||||
const aiScene* scene = importer.ReadFile(filepath, 0);
|
const aiScene* scene = importer.ReadFile(filepath, 0);
|
||||||
@ -19,9 +18,159 @@ static void assimp_Importer(const char* filepath)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gmio_assimp_allocate_stl_scene(aiScene* pScene)
|
||||||
|
{
|
||||||
|
// allocate one mesh
|
||||||
|
pScene->mNumMeshes = 1;
|
||||||
|
pScene->mMeshes = new aiMesh*[1];
|
||||||
|
aiMesh* pMesh = pScene->mMeshes[0] = new aiMesh();
|
||||||
|
pMesh->mMaterialIndex = 0;
|
||||||
|
|
||||||
|
// allocate a single node
|
||||||
|
pScene->mRootNode = new aiNode();
|
||||||
|
pScene->mRootNode->mNumMeshes = 1;
|
||||||
|
pScene->mRootNode->mMeshes = new unsigned int[1];
|
||||||
|
pScene->mRootNode->mMeshes[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gmio_assimp_ascii_begin_solid_func(
|
||||||
|
void* cookie, size_t stream_size, const char* solid_name)
|
||||||
|
{
|
||||||
|
aiScene* pScene = (aiScene*)cookie;
|
||||||
|
gmio_assimp_allocate_stl_scene(pScene);
|
||||||
|
aiMesh* pMesh = pScene->mMeshes[0];
|
||||||
|
|
||||||
|
std::strcpy(pScene->mRootNode->mName.data, solid_name);
|
||||||
|
pScene->mRootNode->mName.length = std::strlen(solid_name);
|
||||||
|
|
||||||
|
// try to guess how many vertices we could have
|
||||||
|
// assume we'll need 160 bytes for each face
|
||||||
|
const unsigned facetSize = 200u;
|
||||||
|
pMesh->mNumFaces = std::max(1u, static_cast<unsigned>(stream_size) / facetSize);
|
||||||
|
pMesh->mNumVertices = pMesh->mNumFaces * 3;
|
||||||
|
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
|
||||||
|
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gmio_assimp_binary_begin_solid(
|
||||||
|
void* cookie, uint32_t tri_count, const uint8_t* /*header*/)
|
||||||
|
{
|
||||||
|
aiScene* pScene = (aiScene*)cookie;
|
||||||
|
gmio_assimp_allocate_stl_scene(pScene);
|
||||||
|
aiMesh* pMesh = pScene->mMeshes[0];
|
||||||
|
|
||||||
|
pScene->mRootNode->mName.Set("<STL_BINARY>");
|
||||||
|
pMesh->mNumFaces = tri_count;
|
||||||
|
|
||||||
|
pMesh->mNumVertices = pMesh->mNumFaces*3;
|
||||||
|
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
|
||||||
|
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gmio_assimp_add_triangle(
|
||||||
|
void* cookie, uint32_t tri_id, const gmio_stl_triangle_t* triangle)
|
||||||
|
{
|
||||||
|
aiScene* pScene = (aiScene*)cookie;
|
||||||
|
aiMesh* pMesh = pScene->mMeshes[0];
|
||||||
|
if (pMesh->mNumFaces <= tri_id) {
|
||||||
|
// need to resize the arrays, our size estimate was wrong
|
||||||
|
#if 0
|
||||||
|
unsigned int iNeededSize = (unsigned int)(sz-mBuffer) / pMesh->mNumFaces;
|
||||||
|
if (iNeededSize <= 160)
|
||||||
|
iNeededSize >>= 1; // prevent endless looping
|
||||||
|
unsigned int add = (unsigned int)((mBuffer+fileSize)-sz) / iNeededSize;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned int add = pMesh->mNumFaces;
|
||||||
|
add += add >> 3; // add 12.5% as buffer
|
||||||
|
const unsigned int iNeededSize = (pMesh->mNumFaces + add)*3;
|
||||||
|
|
||||||
|
aiVector3D* pv = new aiVector3D[iNeededSize];
|
||||||
|
memcpy(pv, pMesh->mVertices, pMesh->mNumVertices*sizeof(aiVector3D));
|
||||||
|
delete[] pMesh->mVertices;
|
||||||
|
pMesh->mVertices = pv;
|
||||||
|
pv = new aiVector3D[iNeededSize];
|
||||||
|
memcpy(pv, pMesh->mNormals, pMesh->mNumVertices*sizeof(aiVector3D));
|
||||||
|
delete[] pMesh->mNormals;
|
||||||
|
pMesh->mNormals = pv;
|
||||||
|
|
||||||
|
pMesh->mNumVertices = iNeededSize;
|
||||||
|
pMesh->mNumFaces += add;
|
||||||
|
}
|
||||||
|
|
||||||
|
aiVector3D* vp = &pMesh->mVertices[tri_id * 3];
|
||||||
|
aiVector3D* vn = &pMesh->mNormals[tri_id];
|
||||||
|
|
||||||
|
*vn = *((aiVector3D*)&triangle->normal);
|
||||||
|
*vp++ = *((aiVector3D*)&triangle->v1);
|
||||||
|
*vp++ = *((aiVector3D*)&triangle->v2);
|
||||||
|
*vp++ = *((aiVector3D*)&triangle->v3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gmio_assimp_end_solid(void* cookie)
|
||||||
|
{
|
||||||
|
aiScene* pScene = (aiScene*)cookie;
|
||||||
|
aiMesh* pMesh = pScene->mMeshes[0];
|
||||||
|
|
||||||
|
// now copy faces
|
||||||
|
pMesh->mFaces = new aiFace[pMesh->mNumFaces];
|
||||||
|
for (unsigned int i = 0, p = 0; i < pMesh->mNumFaces;++i) {
|
||||||
|
aiFace& face = pMesh->mFaces[i];
|
||||||
|
face.mIndices = new unsigned int[face.mNumIndices = 3];
|
||||||
|
for (unsigned int o = 0; o < 3;++o,++p) {
|
||||||
|
face.mIndices[o] = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a single default material, using a light gray diffuse color for consistency with
|
||||||
|
// other geometric types (e.g., PLY).
|
||||||
|
aiMaterial* pcMat = new aiMaterial;
|
||||||
|
aiString s;
|
||||||
|
s.Set(AI_DEFAULT_MATERIAL_NAME);
|
||||||
|
pcMat->AddProperty(&s, AI_MATKEY_NAME);
|
||||||
|
|
||||||
|
aiColor4D clrDiffuse(0.6f,0.6f,0.6f,1.0f);
|
||||||
|
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_DIFFUSE);
|
||||||
|
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_SPECULAR);
|
||||||
|
clrDiffuse = aiColor4D(0.05f,0.05f,0.05f,1.0f);
|
||||||
|
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_AMBIENT);
|
||||||
|
|
||||||
|
pScene->mNumMaterials = 1;
|
||||||
|
pScene->mMaterials = new aiMaterial*[1];
|
||||||
|
pScene->mMaterials[0] = pcMat;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bench_gmio_stl_read(const char* filepath)
|
||||||
|
{
|
||||||
|
// void* mbuffer = std::malloc(512 * 1024);
|
||||||
|
// gmio_buffer_t buffer = gmio_buffer(mbuffer, 512 * 1024);
|
||||||
|
char mbuffer[256 * 1024];
|
||||||
|
gmio_buffer_t buffer = gmio_buffer(&mbuffer[0], sizeof(mbuffer));
|
||||||
|
|
||||||
|
aiScene scene;
|
||||||
|
gmio_stl_mesh_creator_t mesh_creator = { 0 };
|
||||||
|
mesh_creator.cookie = &scene;
|
||||||
|
mesh_creator.ascii_begin_solid_func = gmio_assimp_ascii_begin_solid_func;
|
||||||
|
mesh_creator.binary_begin_solid_func = gmio_assimp_binary_begin_solid;
|
||||||
|
mesh_creator.add_triangle_func = gmio_assimp_add_triangle;
|
||||||
|
mesh_creator.end_solid_func = gmio_assimp_end_solid;
|
||||||
|
|
||||||
|
int error = gmio_stl_read_file(filepath, &mesh_creator, &buffer);
|
||||||
|
if (error != GMIO_NO_ERROR)
|
||||||
|
printf("GeomIO error: 0x%X\n", error);
|
||||||
|
|
||||||
|
//std::free(mbuffer);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
if (argc > 1)
|
if (argc > 1) {
|
||||||
benchmark(&assimp_Importer, "Assimp::Importer::ReadFile()", argc - 1, argv + 1);
|
benchmark(&bench_assimp_Importer,
|
||||||
|
"Assimp::Importer::ReadFile()",
|
||||||
|
argc - 1, argv + 1);
|
||||||
|
benchmark(&bench_gmio_stl_read,
|
||||||
|
"gmio_stl_read()",
|
||||||
|
argc - 1, argv + 1);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
include(../../qmake.build/config.pri)
|
|
||||||
include(occ.pri)
|
|
||||||
|
|
||||||
TEMPLATE = app
|
|
||||||
TARGET = bench_occ$$TARGET_SUFFIX
|
|
||||||
|
|
||||||
HEADERS += ../commons/bench_tools.h
|
|
||||||
|
|
||||||
SOURCES += \
|
|
||||||
../commons/bench_tools.c \
|
|
||||||
main.cpp
|
|
||||||
|
|
||||||
LIBS *= -lTKSTL -lTKernel -lTKMath
|
|
||||||
QMAKE_RPATHDIR *= $$CASCADE_LIB_PATH
|
|
@ -1,38 +1,47 @@
|
|||||||
extern "C" {
|
|
||||||
#include "../commons/bench_tools.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <OSD_Path.hxx>
|
#include <OSD_Path.hxx>
|
||||||
#include <RWStl.hxx>
|
#include <RWStl.hxx>
|
||||||
#include <StlMesh_Mesh.hxx>
|
#include <StlMesh_Mesh.hxx>
|
||||||
#include <StlAPI_Reader.hxx>
|
#include <StlAPI_Reader.hxx>
|
||||||
#include <TopoDS_Shape.hxx>
|
|
||||||
|
|
||||||
static void occ_RWStl_ReadBinary(const char* filepath)
|
#include <gmio_core/error.h>
|
||||||
|
#include <gmio_stl/stl_io.h>
|
||||||
|
#include <gmio_support/occ_libstl.h>
|
||||||
|
|
||||||
|
#include "../commons/bench_tools.h"
|
||||||
|
|
||||||
|
static void bench_occ_RWStl_ReadFile(const char* filepath)
|
||||||
{
|
{
|
||||||
/*Handle_StlMesh_Mesh stlMesh = */RWStl::ReadBinary(OSD_Path(filepath));
|
RWStl::ReadFile(OSD_Path(filepath));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void occ_StlAPI_Reader(const char* filepath)
|
static void bench_gmio_stl_read(const char* filepath)
|
||||||
{
|
{
|
||||||
StlAPI_Reader reader;
|
// void* mbuffer = std::malloc(512 * 1024);
|
||||||
TopoDS_Shape shape;
|
// gmio_buffer_t buffer = gmio_buffer(mbuffer, 512 * 1024);
|
||||||
reader.Read(shape, filepath);
|
char mbuffer[256 * 1024];
|
||||||
|
gmio_buffer_t buffer = gmio_buffer(&mbuffer[0], sizeof(mbuffer));
|
||||||
|
|
||||||
|
Handle_StlMesh_Mesh mesh = new StlMesh_Mesh;
|
||||||
|
gmio_stl_mesh_creator_t mesh_creator = gmio_stl_occmesh_creator(mesh);
|
||||||
|
|
||||||
|
int error = gmio_stl_read_file(filepath, &mesh_creator, &buffer);
|
||||||
|
if (error != GMIO_NO_ERROR)
|
||||||
|
printf("GeomIO error: 0x%X\n", error);
|
||||||
|
|
||||||
|
//std::free(mbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
if (argc > 1)
|
if (argc > 1) {
|
||||||
benchmark(&occ_RWStl_ReadBinary, "RWStl::ReadBinary()", argc - 1, argv + 1);
|
benchmark(&bench_occ_RWStl_ReadFile,
|
||||||
|
"RWStl::ReadFile()",
|
||||||
|
argc - 1, argv + 1);
|
||||||
|
|
||||||
// startTick = std::clock();
|
benchmark(&bench_gmio_stl_read,
|
||||||
// std::cout << "Read with StlAPI_Reader::Read() ..." << std::endl;
|
"gmio_stl_read()",
|
||||||
// for (int iarg = 1; iarg < argc; ++iarg) {
|
argc - 1, argv + 1);
|
||||||
// StlAPI_Reader reader;
|
}
|
||||||
// TopoDS_Shape shape;
|
|
||||||
// reader.Read(shape, argv[iarg]);
|
|
||||||
// }
|
|
||||||
// std::cout << " StlAPI_Reader::Read() read time: " << elapsed_secs(startTick) << "s" << std::endl;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
# Return the input path re-written using the system-dependent separator
|
|
||||||
defineReplace(sysPath) {
|
|
||||||
win*:result = $$replace(1, /, \\)
|
|
||||||
else:result = $$1
|
|
||||||
return($$result)
|
|
||||||
}
|
|
||||||
|
|
||||||
use_oce {
|
|
||||||
CASCADE_INC_PATH = $$CASCADE_ROOT/include/oce
|
|
||||||
!isEmpty(OCE_VERSION) {
|
|
||||||
CASCADE_LIB_PATH += -$CASCADE_ROOT/lib/$$OCE_VERSION
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
CASCADE_INC_PATH = $$CASCADE_ROOT/inc
|
|
||||||
}
|
|
||||||
INCLUDEPATH += $$CASCADE_INC_PATH
|
|
||||||
|
|
||||||
linux-*:DEFINES *= HAVE_CONFIG_H \
|
|
||||||
HAVE_FSTREAM \
|
|
||||||
HAVE_IOSTREAM \
|
|
||||||
HAVE_LIMITS_H
|
|
||||||
|
|
||||||
win32-*:DEFINES *= WNT
|
|
||||||
linux-*:DEFINES *= LIN LININTEL OCC_CONVERT_SIGNALS
|
|
||||||
*-64:DEFINES *= _OCC64
|
|
||||||
|
|
||||||
linux-*:CASCADE_LIB_PATH += $$CASCADE_ROOT/lib
|
|
||||||
CONFIG(debug, debug|release) {
|
|
||||||
win32-msvc2005:CASCADE_LIB_PATH += $$CASCADE_ROOT/win32/vc8/libd
|
|
||||||
win32-msvc2008:CASCADE_LIB_PATH += $$CASCADE_ROOT/win32/vc9/lib
|
|
||||||
win32-msvc2010:CASCADE_LIB_PATH += $$CASCADE_ROOT/win32/vc10/libd
|
|
||||||
} else {
|
|
||||||
win32-msvc2005:CASCADE_LIB_PATH += $$CASCADE_ROOT/win32/vc8/lib
|
|
||||||
win32-msvc2008:CASCADE_LIB_PATH += $$CASCADE_ROOT/win32/vc9/lib
|
|
||||||
win32-msvc2010:CASCADE_LIB_PATH += $$CASCADE_ROOT/win32/vc10/lib
|
|
||||||
}
|
|
||||||
LIBS += $$sysPath($$join(CASCADE_LIB_PATH, " -L", -L))
|
|
||||||
|
|
||||||
# There is a weird bug with qmake on windows : it fails to correctly link with TKSTEP209 due to the
|
|
||||||
# name of library mixing characters and digits.
|
|
||||||
# Or maybe nmake is the problem ?
|
|
||||||
# Note : you have to rename TKSTEP209 to TKSTEP_tzn in $$CASCADE_ROOT/win32/lib
|
|
||||||
win32-msvc* {
|
|
||||||
OCC_TKSTEP = TKSTEP_tzn
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
OCC_TKSTEP = TKSTEP209
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
include(../../qmake.build/config.pri)
|
|
||||||
|
|
||||||
TEMPLATE = app
|
|
||||||
TARGET = cmd$$TARGET_SUFFIX
|
|
||||||
|
|
||||||
QT *= core
|
|
||||||
|
|
||||||
HEADERS +=
|
|
||||||
|
|
||||||
SOURCES += main.cpp
|
|
||||||
|
|
||||||
INCLUDEPATH += ../../src
|
|
||||||
LIBS += -L../../bin -lfougstl$$TARGET_SUFFIX
|
|
@ -1,234 +0,0 @@
|
|||||||
#include <QtCore/QCoreApplication>
|
|
||||||
#include <QtCore/QFile>
|
|
||||||
#include <QtCore/QScopedPointer>
|
|
||||||
#include <QtCore/QStringList>
|
|
||||||
|
|
||||||
#include "abstract_task_progress.h"
|
|
||||||
#include "libstl/abstract_geometry.h"
|
|
||||||
#include "libstl/stlb.h"
|
|
||||||
#include "streams/qt4_stream.h"
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include "streams/std_io_stream.h"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <QtCore/QtDebug>
|
|
||||||
#include <QtCore/QTime>
|
|
||||||
#include <QtCore/QVector>
|
|
||||||
|
|
||||||
#define USE_QT4STREAM
|
|
||||||
//#define USE_STDSTREAM
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
class ConsoleTaskProgress : public foug::AbstractTaskProgress
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void handleProgressUpdate()
|
|
||||||
{
|
|
||||||
qDebug() << this->progress();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class DummyGeometryBuilder : public foug::stl::bin::AbstractGeometryBuilder
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void processHeader(const foug::stl::bin::Header& data)
|
|
||||||
{
|
|
||||||
qDebug() << "HEADER : \n" << QString::fromAscii(reinterpret_cast<const char*>(data), 79);
|
|
||||||
}
|
|
||||||
|
|
||||||
void beginTriangles(foug::UInt32 count)
|
|
||||||
{
|
|
||||||
m_triangleCounter = 0;
|
|
||||||
qDebug() << "Triangle count" << count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void processNextTriangle(const foug::stl::Triangle& triangle, foug::UInt16 attributeByteCount)
|
|
||||||
{
|
|
||||||
// qDebug() << "TRIANGLE " << m_triangleCounter++;
|
|
||||||
// qDebug() << " normal" << triangle.normal.x << triangle.normal.y << triangle.normal.z;
|
|
||||||
// qDebug() << " v1" << triangle.v1.x << triangle.v1.y << triangle.v1.z;
|
|
||||||
// qDebug() << " v2" << triangle.v2.x << triangle.v2.y << triangle.v2.z;
|
|
||||||
// qDebug() << " v3" << triangle.v3.x << triangle.v3.y << triangle.v3.z;
|
|
||||||
// qDebug() << " attr" << attributeByteCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
foug::UInt32 m_triangleCounter;
|
|
||||||
};
|
|
||||||
|
|
||||||
class BasicGeometryHelper :
|
|
||||||
public foug::stl::AbstractGeometry,
|
|
||||||
public foug::stl::bin::AbstractGeometryBuilder,
|
|
||||||
public foug::stl::bin::AbstractGeometryExtraData
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
struct TriangleData
|
|
||||||
{
|
|
||||||
foug::stl::Triangle triangle;
|
|
||||||
foug::UInt16 attributeByteCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
QVector<TriangleData> triangles() const
|
|
||||||
{
|
|
||||||
return m_triangles;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- foug::stl::bin::AbstractGeometryBuilder
|
|
||||||
|
|
||||||
void processHeader(const foug::stlb::Header& data)
|
|
||||||
{
|
|
||||||
std::memcpy(m_header, data, 80);
|
|
||||||
}
|
|
||||||
|
|
||||||
void beginTriangles(foug::UInt32 count)
|
|
||||||
{
|
|
||||||
m_triangles.reserve(count);
|
|
||||||
m_triangles.clear();
|
|
||||||
m_triangles.resize(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void processNextTriangle(const foug::stl::Triangle& triangle, foug::UInt16 attributeByteCount)
|
|
||||||
{
|
|
||||||
TriangleData data;
|
|
||||||
data.triangle = triangle;
|
|
||||||
data.attributeByteCount = attributeByteCount;
|
|
||||||
m_triangles.append(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- foug::stl::bin::AbstractGeometryExtraData
|
|
||||||
|
|
||||||
void getHeaderData(foug::stl::bin::Header& data) const
|
|
||||||
{
|
|
||||||
std::memcpy(data, m_header, 80);
|
|
||||||
}
|
|
||||||
|
|
||||||
foug::UInt16 attributeByteCount(foug::UInt32 triangleIndex) const
|
|
||||||
{
|
|
||||||
return m_triangles.at(triangleIndex).attributeByteCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- foug::stl::AbstractGeometry
|
|
||||||
|
|
||||||
foug::UInt32 triangleCount() const
|
|
||||||
{
|
|
||||||
return m_triangles.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void getTriangle(foug::UInt32 index, foug::stl::Triangle* triangle) const
|
|
||||||
{
|
|
||||||
*triangle = m_triangles.at(index).triangle;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
QVector<TriangleData> m_triangles;
|
|
||||||
foug::stl::bin::Header m_header;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
using namespace foug::stl;
|
|
||||||
|
|
||||||
QString inputFilePath;
|
|
||||||
QString outputFilePath;
|
|
||||||
int iarg = 1;
|
|
||||||
while (iarg < argc) {
|
|
||||||
if (!std::strcmp(argv[iarg], "-i"))
|
|
||||||
inputFilePath = argv[++iarg];
|
|
||||||
else if (!std::strcmp(argv[iarg], "-o"))
|
|
||||||
outputFilePath = argv[++iarg];
|
|
||||||
++iarg;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inputFilePath.isEmpty()) {
|
|
||||||
qCritical() << "No input files";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bin::Io io;
|
|
||||||
// internal::ConsoleTaskProgress taskProgress;
|
|
||||||
// io.setTaskProgress(&taskProgress);
|
|
||||||
// io.setAutoDeleteTaskProgress(false);
|
|
||||||
|
|
||||||
#ifdef USE_STDSTREAM
|
|
||||||
std::ifstream inputFile(inputFilePath.toStdString().c_str(), std::ios::binary);
|
|
||||||
if (!inputFile.is_open()) {
|
|
||||||
qCritical() << "Failed to open input file";
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
io.setStream(new foug::StdInputStream<std::ifstream>(&inputFile));
|
|
||||||
#elif defined(USE_QT4STREAM)
|
|
||||||
QFile inputFile(inputFilePath);
|
|
||||||
if (!inputFile.open(QIODevice::ReadOnly)) {
|
|
||||||
qCritical() << "Failed to open input file :" << inputFile.errorString();
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
io.setStream(new foug::Qt4Stream(&inputFile));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{ // BENCH READ
|
|
||||||
QTime time;
|
|
||||||
time.start();
|
|
||||||
|
|
||||||
internal::DummyGeometryBuilder geomBuilder;
|
|
||||||
const int benchCount = 100;
|
|
||||||
for (int i = 0; i < benchCount; ++i) {
|
|
||||||
io.stream()->seek(0);
|
|
||||||
io.read(&geomBuilder);
|
|
||||||
}
|
|
||||||
|
|
||||||
qDebug() << QString("Total read time : %1sec").arg(time.elapsed() / 1000.);
|
|
||||||
qDebug() << QString("Test read time : %1sec")
|
|
||||||
.arg(time.elapsed() / 1000. / static_cast<double>(benchCount));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outputFilePath.isEmpty())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#ifdef USE_STDSTREAM
|
|
||||||
std::ofstream outputFile(outputFilePath.toStdString().c_str(), std::ios::out | std::ios::binary);
|
|
||||||
//std::ofstream outputFile(outputFilePath.toStdString().c_str(), std::ios::binary);
|
|
||||||
if (!outputFile.is_open()) {
|
|
||||||
qCritical() << "Failed to open output file";
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
#elif defined(USE_QT4STREAM)
|
|
||||||
QFile outputFile(outputFilePath);
|
|
||||||
if (!outputFile.open(QIODevice::WriteOnly)) {
|
|
||||||
qCritical() << "Failed to open output file :" << outputFile.errorString();
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
internal::BasicGeometryHelper geomHelper;
|
|
||||||
{ // READ GEOMETRY
|
|
||||||
io.stream()->seek(0);
|
|
||||||
io.read(&geomHelper);
|
|
||||||
}
|
|
||||||
|
|
||||||
{ // BENCH WRITE
|
|
||||||
#ifdef USE_STDSTREAM
|
|
||||||
io.setStream(new foug::StdOutputStream<std::ofstream>(&outputFile));
|
|
||||||
#elif defined(USE_QT4STREAM)
|
|
||||||
io.setStream(new foug::Qt4Stream(&outputFile));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QTime time;
|
|
||||||
time.start();
|
|
||||||
|
|
||||||
const int benchCount = 100;
|
|
||||||
for (int i = 0; i < benchCount; ++i) {
|
|
||||||
io.stream()->seek(0);
|
|
||||||
io.write(geomHelper, &geomHelper);
|
|
||||||
}
|
|
||||||
|
|
||||||
qDebug() << QString("Total write time : %1sec").arg(time.elapsed() / 1000.);
|
|
||||||
qDebug() << QString("Test write time : %1sec")
|
|
||||||
.arg(time.elapsed() / 1000. / static_cast<double>(benchCount));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -7,7 +7,8 @@ float elapsed_secs(clock_t start_tick)
|
|||||||
return (float)((clock() - start_tick) / (float)CLOCKS_PER_SEC);
|
return (float)((clock() - start_tick) / (float)CLOCKS_PER_SEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
void benchmark(void (*func)(const char*), const char* title, int argc, char** argv)
|
void benchmark(
|
||||||
|
void (*func)(const char*), const char* title, int argc, char** argv)
|
||||||
{
|
{
|
||||||
const clock_t start_tick = clock();
|
const clock_t start_tick = clock();
|
||||||
int iarg;
|
int iarg;
|
||||||
|
@ -3,8 +3,15 @@
|
|||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <gmio_core/global.h>
|
||||||
|
|
||||||
|
GMIO_C_LINKAGE_BEGIN
|
||||||
|
|
||||||
float elapsed_secs(clock_t start_tick);
|
float elapsed_secs(clock_t start_tick);
|
||||||
|
|
||||||
void benchmark(void (*func)(const char*), const char* title, int argc, char** argv);
|
void benchmark(
|
||||||
|
void (*func)(const char*), const char* title, int argc, char** argv);
|
||||||
|
|
||||||
|
GMIO_C_LINKAGE_END
|
||||||
|
|
||||||
#endif /* BENCH_TOOLS_H */
|
#endif /* BENCH_TOOLS_H */
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
TEMPLATE = subdirs
|
|
||||||
|
|
||||||
SUBDIRS += \
|
|
||||||
#bench_occ \
|
|
||||||
bench_libstl \
|
|
||||||
#bench_assimp \
|
|
||||||
#c-lib
|
|
Loading…
Reference in New Issue
Block a user