Initial import
This commit is contained in:
commit
6f7bfd31e6
21
qmake.build/compiler_config.pri
Normal file
21
qmake.build/compiler_config.pri
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
CONFIG *= debug_and_release
|
||||||
|
CONFIG *= warn_on stl rtti exceptions
|
||||||
|
|
||||||
|
QT -= core gui
|
||||||
|
|
||||||
|
CONFIG(debug, debug|release) {
|
||||||
|
DEFINES *= _DEBUG_CONFIG_
|
||||||
|
CONFIG *= console
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CONFIG -= console
|
||||||
|
}
|
||||||
|
|
||||||
|
CONFIG(warn_on) {
|
||||||
|
*-g++*:QMAKE_CXXFLAGS *= -Wextra
|
||||||
|
}
|
||||||
|
|
||||||
|
win32-msvc20*:QMAKE_CXXFLAGS *= -wd4996 -wd4290 -wd4503
|
||||||
|
win32-msvc*:DEFINES *= NOMINMAX
|
||||||
|
# This explicitely defines INTXX_C() and UINTXX_C() macros in <stdint.h>
|
||||||
|
DEFINES *= __STDC_CONSTANT_MACROS
|
7
qmake.build/config.pri
Normal file
7
qmake.build/config.pri
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
include(compiler_config.pri)
|
||||||
|
CONFIG(debug, debug|release) {
|
||||||
|
TARGET_SUFFIX = .debug
|
||||||
|
} else {
|
||||||
|
TARGET_SUFFIX = .release
|
||||||
|
}
|
||||||
|
CONFIG *= build_all debug_and_release
|
4
qmake.build/foug_dataex.pro
Normal file
4
qmake.build/foug_dataex.pro
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
TEMPLATE = subdirs
|
||||||
|
CONFIG *= ordered
|
||||||
|
|
||||||
|
SUBDIRS += libstl
|
24
src/abstract_stream.h
Normal file
24
src/abstract_stream.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef FOUG_ABSTRACT_STREAM_H
|
||||||
|
#define FOUG_ABSTRACT_STREAM_H
|
||||||
|
|
||||||
|
#include "foug_global.h"
|
||||||
|
|
||||||
|
namespace foug {
|
||||||
|
|
||||||
|
class AbstractStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool atEnd() const = 0;
|
||||||
|
|
||||||
|
virtual bool isWritable() const = 0;
|
||||||
|
virtual bool isReadable() const = 0;
|
||||||
|
virtual bool isSequential() const = 0;
|
||||||
|
|
||||||
|
virtual bool seek(foug::Int64 pos) = 0;
|
||||||
|
virtual Int64 read(char* data, Int64 maxSize) = 0;
|
||||||
|
virtual Int64 write(const char* data, Int64 maxSize) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace foug
|
||||||
|
|
||||||
|
#endif // FOUG_ABSTRACT_STREAM_H
|
112
src/abstract_task_progress.cpp
Normal file
112
src/abstract_task_progress.cpp
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
#include "abstract_task_progress.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace foug {
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
class AbstractTaskProgressPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AbstractTaskProgressPrivate()
|
||||||
|
: m_stepId(-1),
|
||||||
|
m_value(-1.),
|
||||||
|
m_rangeMin(-1.),
|
||||||
|
m_rangeMax(-2.),
|
||||||
|
m_rangeLength(0.),
|
||||||
|
m_progressThreshold(0.01) // Notifies each percent only
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int m_stepId;
|
||||||
|
double m_value;
|
||||||
|
double m_rangeMin;
|
||||||
|
double m_rangeMax;
|
||||||
|
double m_rangeLength;
|
||||||
|
double m_progressThreshold;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
AbstractTaskProgress::AbstractTaskProgress()
|
||||||
|
: d(new internal::AbstractTaskProgressPrivate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractTaskProgress::~AbstractTaskProgress()
|
||||||
|
{
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
|
double AbstractTaskProgress::rangeMin() const
|
||||||
|
{
|
||||||
|
return d->m_rangeMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
double AbstractTaskProgress::rangeMax() const
|
||||||
|
{
|
||||||
|
return d->m_rangeMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTaskProgress::setRange(double min, double max)
|
||||||
|
{
|
||||||
|
d->m_rangeMin = min;
|
||||||
|
d->m_rangeMax = max;
|
||||||
|
d->m_rangeLength = max - min;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AbstractTaskProgress::stepId() const
|
||||||
|
{
|
||||||
|
return d->m_stepId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTaskProgress::setStepId(int id)
|
||||||
|
{
|
||||||
|
d->m_stepId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
double AbstractTaskProgress::progress() const
|
||||||
|
{
|
||||||
|
const double result = (d->m_value - d->m_rangeMin) / d->m_rangeLength;
|
||||||
|
return std::fabs(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
double AbstractTaskProgress::value() const
|
||||||
|
{
|
||||||
|
return d->m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTaskProgress::setValue(double v)
|
||||||
|
{
|
||||||
|
if (std::fabs(v - d->m_value) > std::fabs(d->m_progressThreshold * d->m_rangeLength)) {
|
||||||
|
d->m_value = v;
|
||||||
|
this->handleProgressUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double AbstractTaskProgress::progressUpdateThreshold() const
|
||||||
|
{
|
||||||
|
return d->m_progressThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTaskProgress::setProgressUpdateThreshold(double v)
|
||||||
|
{
|
||||||
|
d->m_progressThreshold = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AbstractTaskProgress::isStopRequested() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTaskProgress::reset()
|
||||||
|
{
|
||||||
|
d->m_stepId = -1;
|
||||||
|
d->m_value = -1.;
|
||||||
|
d->m_rangeMin = -1.;
|
||||||
|
d->m_rangeMax = -2.;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace foug
|
38
src/abstract_task_progress.h
Normal file
38
src/abstract_task_progress.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef FOUG_ABSTRACT_TASK_PROGRESS_H
|
||||||
|
#define FOUG_ABSTRACT_TASK_PROGRESS_H
|
||||||
|
|
||||||
|
namespace foug {
|
||||||
|
|
||||||
|
namespace internal { class AbstractTaskProgressPrivate; }
|
||||||
|
|
||||||
|
class AbstractTaskProgress
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AbstractTaskProgress();
|
||||||
|
virtual ~AbstractTaskProgress();
|
||||||
|
|
||||||
|
double rangeMin() const;
|
||||||
|
double rangeMax() const;
|
||||||
|
void setRange(double min, double max);
|
||||||
|
|
||||||
|
int stepId() const;
|
||||||
|
void setStepId(int id);
|
||||||
|
|
||||||
|
double progress() const;
|
||||||
|
double value() const;
|
||||||
|
void setValue(double v);
|
||||||
|
|
||||||
|
double progressUpdateThreshold() const;
|
||||||
|
void setProgressUpdateThreshold(double v);
|
||||||
|
|
||||||
|
virtual bool isStopRequested() const;
|
||||||
|
virtual void handleProgressUpdate() = 0;
|
||||||
|
virtual void reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
internal::AbstractTaskProgressPrivate* const d;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace foug
|
||||||
|
|
||||||
|
#endif // FOUG_ABSTRACT_TASK_PROGRESS_H
|
39
src/foug_global.h
Normal file
39
src/foug_global.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef FOUG_GLOBAL_H
|
||||||
|
#define FOUG_GLOBAL_H
|
||||||
|
|
||||||
|
#if defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
|
||||||
|
|| defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
|
||||||
|
# define FOUG_DECL_EXPORT __declspec(dllexport)
|
||||||
|
# define FOUG_DECL_IMPORT __declspec(dllimport)
|
||||||
|
#else
|
||||||
|
# define FOUG_DECL_EXPORT
|
||||||
|
# define FOUG_DECL_IMPORT
|
||||||
|
#endif // WIN
|
||||||
|
|
||||||
|
//#include <QtCore/QtGlobal>
|
||||||
|
|
||||||
|
namespace foug {
|
||||||
|
|
||||||
|
typedef char Int8;
|
||||||
|
typedef unsigned char UInt8;
|
||||||
|
|
||||||
|
typedef short Int16;
|
||||||
|
typedef unsigned short UInt16;
|
||||||
|
|
||||||
|
typedef int Int32;
|
||||||
|
typedef unsigned int UInt32;
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
typedef __int64 Int64;
|
||||||
|
typedef unsigned __int64 UInt64;
|
||||||
|
#else
|
||||||
|
typedef long long Int64;
|
||||||
|
typedef unsigned long long UInt64;
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
|
typedef float Real32;
|
||||||
|
typedef double Real64;
|
||||||
|
|
||||||
|
} // namespace foug
|
||||||
|
|
||||||
|
#endif // FOUG_GLOBAL_H
|
90
src/io_base.cpp
Normal file
90
src/io_base.cpp
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#include "io_base.h"
|
||||||
|
|
||||||
|
#include "abstract_stream.h"
|
||||||
|
#include "abstract_task_progress.h"
|
||||||
|
|
||||||
|
namespace foug {
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
class IoBasePrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IoBasePrivate()
|
||||||
|
: m_stream(0),
|
||||||
|
m_taskProgress(0),
|
||||||
|
m_autoDeleteStream(true),
|
||||||
|
m_autoDeleteTaskProgress(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractStream* m_stream;
|
||||||
|
AbstractTaskProgress* m_taskProgress;
|
||||||
|
bool m_autoDeleteStream;
|
||||||
|
bool m_autoDeleteTaskProgress;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
IoBase::IoBase(AbstractStream *stream)
|
||||||
|
: d(new internal::IoBasePrivate)
|
||||||
|
{
|
||||||
|
d->m_stream = stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
IoBase::~IoBase()
|
||||||
|
{
|
||||||
|
if (this->autoDeleteStream() && d->m_stream != 0)
|
||||||
|
delete d->m_stream;
|
||||||
|
|
||||||
|
if (this->autoDeleteTaskProgress() && d->m_taskProgress != 0)
|
||||||
|
delete d->m_taskProgress;
|
||||||
|
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractStream* IoBase::stream() const
|
||||||
|
{
|
||||||
|
return d->m_stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IoBase::setStream(AbstractStream* stream)
|
||||||
|
{
|
||||||
|
if (this->autoDeleteStream() && d->m_stream != 0 && d->m_stream != stream)
|
||||||
|
delete d->m_stream;
|
||||||
|
d->m_stream = stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractTaskProgress* IoBase::taskProgress() const
|
||||||
|
{
|
||||||
|
return d->m_taskProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IoBase::setTaskProgress(AbstractTaskProgress* progress)
|
||||||
|
{
|
||||||
|
if (this->autoDeleteTaskProgress() && d->m_taskProgress != 0 && d->m_taskProgress != progress)
|
||||||
|
delete d->m_taskProgress;
|
||||||
|
d->m_taskProgress = progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IoBase::autoDeleteStream() const
|
||||||
|
{
|
||||||
|
return d->m_autoDeleteStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IoBase::setAutoDeleteStream(bool on)
|
||||||
|
{
|
||||||
|
d->m_autoDeleteStream = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IoBase::autoDeleteTaskProgress() const
|
||||||
|
{
|
||||||
|
return d->m_autoDeleteTaskProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IoBase::setAutoDeleteTaskProgress(bool on) const
|
||||||
|
{
|
||||||
|
d->m_autoDeleteTaskProgress = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace foug
|
35
src/io_base.h
Normal file
35
src/io_base.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef FOUG_IO_BASE_H
|
||||||
|
#define FOUG_IO_BASE_H
|
||||||
|
|
||||||
|
namespace foug {
|
||||||
|
|
||||||
|
class AbstractStream;
|
||||||
|
class AbstractTaskProgress;
|
||||||
|
|
||||||
|
namespace internal { class IoBasePrivate; }
|
||||||
|
|
||||||
|
class IoBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IoBase(AbstractStream* stream = 0);
|
||||||
|
virtual ~IoBase();
|
||||||
|
|
||||||
|
AbstractStream* stream() const;
|
||||||
|
void setStream(AbstractStream* stream);
|
||||||
|
|
||||||
|
AbstractTaskProgress* taskProgress() const;
|
||||||
|
void setTaskProgress(AbstractTaskProgress* progress);
|
||||||
|
|
||||||
|
bool autoDeleteStream() const;
|
||||||
|
void setAutoDeleteStream(bool on);
|
||||||
|
|
||||||
|
bool autoDeleteTaskProgress() const;
|
||||||
|
void setAutoDeleteTaskProgress(bool on) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
internal::IoBasePrivate* const d;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace foug
|
||||||
|
|
||||||
|
#endif // FOUG_IO_BASE_H
|
40
src/libstl/abstract_geometry.h
Normal file
40
src/libstl/abstract_geometry.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#ifndef FOUG_STL_ABSTRACT_GEOMETRY_H
|
||||||
|
#define FOUG_STL_ABSTRACT_GEOMETRY_H
|
||||||
|
|
||||||
|
#include "stl_global.h"
|
||||||
|
|
||||||
|
namespace foug {
|
||||||
|
|
||||||
|
template <typename NUMERIC>
|
||||||
|
struct Coords3d
|
||||||
|
{
|
||||||
|
NUMERIC x;
|
||||||
|
NUMERIC y;
|
||||||
|
NUMERIC z;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename COORDS>
|
||||||
|
struct Triangle
|
||||||
|
{
|
||||||
|
COORDS normal;
|
||||||
|
COORDS v1;
|
||||||
|
COORDS v2;
|
||||||
|
COORDS v3;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace stl {
|
||||||
|
|
||||||
|
typedef Coords3d<Real32> Coords;
|
||||||
|
typedef Triangle<Coords> Triangle;
|
||||||
|
|
||||||
|
class FOUG_STL_EXPORT AbstractGeometry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual UInt32 triangleCount() const = 0;
|
||||||
|
virtual void getTriangle(UInt32 index, Triangle* triangle) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace stl
|
||||||
|
} // namespace foug
|
||||||
|
|
||||||
|
#endif // FOUG_STL_ABSTRACT_GEOMETRY_H
|
16
src/libstl/stl_global.h
Normal file
16
src/libstl/stl_global.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef FOUG_STL_GLOBAL_H
|
||||||
|
#define FOUG_STL_GLOBAL_H
|
||||||
|
|
||||||
|
#include "foug_global.h"
|
||||||
|
|
||||||
|
#ifdef FOUG_STL_DLL
|
||||||
|
# ifdef FOUG_STL_MAKE_DLL
|
||||||
|
# define FOUG_STL_EXPORT FOUG_DECL_EXPORT
|
||||||
|
# else
|
||||||
|
# define FOUG_STL_EXPORT FOUG_DECL_IMPORT
|
||||||
|
# endif // FOUG_STL_MAKE_DLL
|
||||||
|
#else
|
||||||
|
# define FOUG_STL_EXPORT
|
||||||
|
#endif // FOUG_STL_DLL
|
||||||
|
|
||||||
|
#endif // FOUG_STL_GLOBAL_H
|
30
src/libstl/stla.cpp
Normal file
30
src/libstl/stla.cpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#include "abstract_stream.h"
|
||||||
|
#include "stla.h"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
namespace foug {
|
||||||
|
namespace stl {
|
||||||
|
namespace asc {
|
||||||
|
|
||||||
|
bool Io::read(AbstractGeometryBuilder* builder, Int64 streamSize)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Io::write(const AbstractGeometry& geom, const std::string& solidName)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractGeometryBuilder::beginSolid(const std::string& /*name*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractGeometryBuilder::endSolid(const std::string& /*name*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace asc
|
||||||
|
} // namespace stl
|
||||||
|
} // namespace foug
|
34
src/libstl/stla.h
Normal file
34
src/libstl/stla.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef FOUG_STLA_H
|
||||||
|
#define FOUG_STLA_H
|
||||||
|
|
||||||
|
#include "stl_global.h"
|
||||||
|
#include "abstract_geometry.h"
|
||||||
|
#include "io_base.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace foug {
|
||||||
|
namespace stl {
|
||||||
|
namespace asc {
|
||||||
|
|
||||||
|
class FOUG_STL_EXPORT AbstractGeometryBuilder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void beginSolid(const std::string& name);
|
||||||
|
virtual void nextTriangle(const Triangle& triangle) = 0;
|
||||||
|
virtual void endSolid(const std::string& name);
|
||||||
|
};
|
||||||
|
|
||||||
|
class FOUG_STL_EXPORT Io : public IoBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Io(AbstractStream* stream = 0);
|
||||||
|
|
||||||
|
bool read(AbstractGeometryBuilder* builder, Int64 streamSize = -1);
|
||||||
|
bool write(const AbstractGeometry& geom, const std::string& solidName);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace asc
|
||||||
|
} // namespace stl
|
||||||
|
} // namespace foug
|
||||||
|
|
||||||
|
#endif // FOUG_STLA_H
|
251
src/libstl/stlb.cpp
Normal file
251
src/libstl/stlb.cpp
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
#include "abstract_stream.h"
|
||||||
|
#include "stlb.h"
|
||||||
|
#include "abstract_task_progress.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
// Read tools
|
||||||
|
|
||||||
|
template<typename NUMERIC>
|
||||||
|
NUMERIC fromLittleEndian(const foug::UInt8* bytes)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
foug::UInt16 fromLittleEndian<foug::UInt16>(const foug::UInt8* bytes)
|
||||||
|
{
|
||||||
|
// |BB|AA| -> 0xAABB
|
||||||
|
return (bytes[1] << 8) | bytes[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
foug::UInt32 fromLittleEndian<foug::UInt32>(const foug::UInt8* bytes)
|
||||||
|
{
|
||||||
|
// |DD|CC|BB|AA| -> 0xAABBCCDD
|
||||||
|
return bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
foug::Real32 fromLittleEndian<foug::Real32>(const foug::UInt8* bytes)
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
foug::UInt32 asInteger;
|
||||||
|
foug::Real32 asFloat;
|
||||||
|
} helper;
|
||||||
|
|
||||||
|
helper.asInteger = fromLittleEndian<foug::UInt32>(bytes);
|
||||||
|
return helper.asFloat;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write tools
|
||||||
|
|
||||||
|
template<typename NUMERIC>
|
||||||
|
void toLittleEndian(NUMERIC n, foug::UInt8* bytes)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
NUMERIC asNumeric;
|
||||||
|
foug::UInt8 asBytes[sizeof(NUMERIC)];
|
||||||
|
} helper;
|
||||||
|
helper.asNumeric = n;
|
||||||
|
// std::copy(helper.asBytes, helper.asBytes + sizeof(NUMERIC), bytes);
|
||||||
|
for (unsigned i = 0; i < sizeof(NUMERIC); ++i)
|
||||||
|
bytes[i] = helper.asBytes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace foug {
|
||||||
|
namespace stl {
|
||||||
|
namespace bin {
|
||||||
|
|
||||||
|
static const int stlHeaderSize = 80;
|
||||||
|
static const int stlFacetSize = 50;
|
||||||
|
static const int stlMinFileSize = 284;
|
||||||
|
static const int stlTriangleDataSize = (4 * 3) * sizeof(foug::Real32) + sizeof(foug::UInt16);
|
||||||
|
|
||||||
|
void AbstractGeometryBuilder::header(const Header& /*data*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractGeometryBuilder::beginTriangles(UInt32 /*count*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractGeometryBuilder::endTriangles()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Io::ReadError streamRead(AbstractStream* stream, char* buffer, Int64 size)
|
||||||
|
{
|
||||||
|
const Int64 result = stream->read(buffer, size);
|
||||||
|
if (result == -1)
|
||||||
|
return Io::StreamReadError;
|
||||||
|
else if (result != size)
|
||||||
|
return Io::UnexpectedSizeReadError;
|
||||||
|
return Io::NoReadError;
|
||||||
|
}
|
||||||
|
|
||||||
|
Io::ReadError getReadError(Int64 readResult, Int64 expectedSize)
|
||||||
|
{
|
||||||
|
if (readResult == -1)
|
||||||
|
return Io::StreamReadError;
|
||||||
|
else if (readResult != expectedSize)
|
||||||
|
return Io::UnexpectedSizeReadError;
|
||||||
|
else
|
||||||
|
return Io::NoReadError;
|
||||||
|
}
|
||||||
|
|
||||||
|
Io::Io(AbstractStream *stream)
|
||||||
|
: IoBase(stream)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Io::ReadError Io::read(AbstractGeometryBuilder* builder)
|
||||||
|
{
|
||||||
|
// // Check file size
|
||||||
|
// const qint64 fileSize = stream->size();
|
||||||
|
// if (((fileSize - stlHeaderSize - stlFacetCountSize) % stlFacetSize != 0)
|
||||||
|
// || fileSize < stlMinFileSize) {
|
||||||
|
// cpp::checkedAssign(err, WrongFileSizeBinaryStlLoadError);
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const int facetCount = (fileSize - stlHeaderSize - stlFacetCountSize) / stlFacetSize;
|
||||||
|
|
||||||
|
AbstractStream* istream = this->stream();
|
||||||
|
AbstractTaskProgress* progress = this->taskProgress();
|
||||||
|
// Io::ReadError readErr = Io::NoReadError;
|
||||||
|
|
||||||
|
UInt8 buffer[8192];
|
||||||
|
char* charBuffer = reinterpret_cast<char*>(buffer);
|
||||||
|
|
||||||
|
// Read header
|
||||||
|
Header headerData;
|
||||||
|
istream->read(reinterpret_cast<char*>(&headerData), 80);
|
||||||
|
// if ((readErr = streamRead(istream, reinterpret_cast<char*>(&headerData), 80)) != NoReadError)
|
||||||
|
// return readErr;
|
||||||
|
builder->header(headerData);
|
||||||
|
|
||||||
|
// Read facet count
|
||||||
|
istream->read(charBuffer, sizeof(UInt32));
|
||||||
|
// if ((readErr = streamRead(istream, charBuffer, sizeof(UInt32))) != NoReadError)
|
||||||
|
// return readErr;
|
||||||
|
const UInt32 facetCount = ::fromLittleEndian<UInt32>(buffer);
|
||||||
|
builder->beginTriangles(facetCount);
|
||||||
|
|
||||||
|
if (progress != 0) {
|
||||||
|
progress->reset();
|
||||||
|
progress->setRange(0., facetCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read triangles
|
||||||
|
Triangle triangle;
|
||||||
|
for (UInt32 facet = 0; facet < facetCount; ++facet) {
|
||||||
|
istream->read(charBuffer, stlTriangleDataSize);
|
||||||
|
// if ((readErr = streamRead(istream, charBuffer, stlTriangleDataSize)) != NoReadError)
|
||||||
|
// return readErr;
|
||||||
|
|
||||||
|
// Read normal
|
||||||
|
triangle.normal.x = ::fromLittleEndian<Real32>(buffer);
|
||||||
|
triangle.normal.y = ::fromLittleEndian<Real32>(buffer + 1*sizeof(Real32));
|
||||||
|
triangle.normal.z = ::fromLittleEndian<Real32>(buffer + 2*sizeof(Real32));
|
||||||
|
|
||||||
|
// Read vertex1
|
||||||
|
triangle.v1.x = ::fromLittleEndian<Real32>(buffer + 3*sizeof(Real32));
|
||||||
|
triangle.v1.y = ::fromLittleEndian<Real32>(buffer + 4*sizeof(Real32));
|
||||||
|
triangle.v1.z = ::fromLittleEndian<Real32>(buffer + 5*sizeof(Real32));
|
||||||
|
|
||||||
|
// Read vertex2
|
||||||
|
triangle.v2.x = ::fromLittleEndian<Real32>(buffer + 6*sizeof(Real32));
|
||||||
|
triangle.v2.y = ::fromLittleEndian<Real32>(buffer + 7*sizeof(Real32));
|
||||||
|
triangle.v2.z = ::fromLittleEndian<Real32>(buffer + 8*sizeof(Real32));
|
||||||
|
|
||||||
|
// Read vertex3
|
||||||
|
triangle.v3.x = ::fromLittleEndian<Real32>(buffer + 9*sizeof(Real32));
|
||||||
|
triangle.v3.y = ::fromLittleEndian<Real32>(buffer + 10*sizeof(Real32));
|
||||||
|
triangle.v3.z = ::fromLittleEndian<Real32>(buffer + 11*sizeof(Real32));
|
||||||
|
|
||||||
|
// Attribute byte count
|
||||||
|
const UInt16 attributeByteCount = ::fromLittleEndian<UInt16>(buffer + 12*sizeof(Real32));
|
||||||
|
|
||||||
|
// Add triangle
|
||||||
|
builder->nextTriangle(triangle, attributeByteCount);
|
||||||
|
|
||||||
|
if (progress != 0)
|
||||||
|
progress->setValue(facet + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder->endTriangles();
|
||||||
|
|
||||||
|
return NoReadError;
|
||||||
|
}
|
||||||
|
|
||||||
|
Io::WriteError Io::write(const AbstractGeometry& geom, const AbstractGeometryExtraData* extraData)
|
||||||
|
{
|
||||||
|
AbstractStream* ostream = this->stream();
|
||||||
|
AbstractTaskProgress* progress = this->taskProgress();
|
||||||
|
|
||||||
|
UInt8 buffer[128];
|
||||||
|
|
||||||
|
// Write header
|
||||||
|
Header headerData;
|
||||||
|
if (extraData != 0)
|
||||||
|
extraData->getHeaderData(headerData);
|
||||||
|
else
|
||||||
|
std::fill(headerData, headerData + 80, 0);
|
||||||
|
|
||||||
|
ostream->write(reinterpret_cast<char*>(&headerData), 80);
|
||||||
|
|
||||||
|
// Write facet count
|
||||||
|
const UInt32 facetCount = geom.triangleCount();
|
||||||
|
::toLittleEndian<UInt32>(facetCount, buffer);
|
||||||
|
ostream->write(reinterpret_cast<char*>(&buffer), sizeof(UInt32));
|
||||||
|
|
||||||
|
if (progress != 0) {
|
||||||
|
progress->reset();
|
||||||
|
progress->setRange(0., facetCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write triangles
|
||||||
|
Triangle triangle;
|
||||||
|
for (UInt32 facet = 0; facet < facetCount; ++facet) {
|
||||||
|
geom.getTriangle(facet, &triangle);
|
||||||
|
|
||||||
|
// Write normal
|
||||||
|
::toLittleEndian<Real32>(triangle.normal.x, buffer);
|
||||||
|
::toLittleEndian<Real32>(triangle.normal.y, buffer + 1*sizeof(Real32));
|
||||||
|
::toLittleEndian<Real32>(triangle.normal.z, buffer + 2*sizeof(Real32));
|
||||||
|
|
||||||
|
// Write vertex1
|
||||||
|
::toLittleEndian<Real32>(triangle.v1.x, buffer + 3*sizeof(Real32));
|
||||||
|
::toLittleEndian<Real32>(triangle.v1.y, buffer + 4*sizeof(Real32));
|
||||||
|
::toLittleEndian<Real32>(triangle.v1.z, buffer + 5*sizeof(Real32));
|
||||||
|
|
||||||
|
// Write vertex2
|
||||||
|
::toLittleEndian<Real32>(triangle.v2.x, buffer + 6*sizeof(Real32));
|
||||||
|
::toLittleEndian<Real32>(triangle.v2.y, buffer + 7*sizeof(Real32));
|
||||||
|
::toLittleEndian<Real32>(triangle.v2.z, buffer + 8*sizeof(Real32));
|
||||||
|
|
||||||
|
// Write vertex3
|
||||||
|
::toLittleEndian<Real32>(triangle.v3.x, buffer + 9*sizeof(Real32));
|
||||||
|
::toLittleEndian<Real32>(triangle.v3.y, buffer + 10*sizeof(Real32));
|
||||||
|
::toLittleEndian<Real32>(triangle.v3.z, buffer + 11*sizeof(Real32));
|
||||||
|
|
||||||
|
// Attribute byte count
|
||||||
|
const UInt16 attrByteCount = extraData != 0 ? extraData->attributeByteCount(facet) : 0;
|
||||||
|
::toLittleEndian<UInt16>(attrByteCount, buffer + 12*sizeof(Real32));
|
||||||
|
|
||||||
|
// Write to stream
|
||||||
|
ostream->write(reinterpret_cast<const char*>(buffer), stlTriangleDataSize);
|
||||||
|
|
||||||
|
if (progress != 0)
|
||||||
|
progress->setValue(facet + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NoWriteError;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace bin
|
||||||
|
} // namespace stl
|
||||||
|
} // namespace foug
|
55
src/libstl/stlb.h
Normal file
55
src/libstl/stlb.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#ifndef FOUG_STLB_H
|
||||||
|
#define FOUG_STLB_H
|
||||||
|
|
||||||
|
#include "stl_global.h"
|
||||||
|
#include "abstract_geometry.h"
|
||||||
|
#include "io_base.h"
|
||||||
|
#include <abstract_stream.h>
|
||||||
|
|
||||||
|
namespace foug {
|
||||||
|
namespace stl {
|
||||||
|
namespace bin {
|
||||||
|
|
||||||
|
typedef UInt8 Header[80];
|
||||||
|
|
||||||
|
class FOUG_STL_EXPORT AbstractGeometryBuilder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void header(const Header& data);
|
||||||
|
virtual void beginTriangles(UInt32 count);
|
||||||
|
virtual void nextTriangle(const stl::Triangle& triangle, UInt16 attributeByteCount) = 0;
|
||||||
|
virtual void endTriangles();
|
||||||
|
};
|
||||||
|
|
||||||
|
class FOUG_STL_EXPORT AbstractGeometryExtraData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void getHeaderData(Header& data) const = 0;
|
||||||
|
virtual UInt16 attributeByteCount(UInt32 triangleIndex) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FOUG_STL_EXPORT Io : public IoBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Io(AbstractStream* stream = 0);
|
||||||
|
|
||||||
|
enum ReadError
|
||||||
|
{
|
||||||
|
NoReadError,
|
||||||
|
StreamReadError,
|
||||||
|
UnexpectedSizeReadError
|
||||||
|
};
|
||||||
|
ReadError read(AbstractGeometryBuilder* builder);
|
||||||
|
|
||||||
|
enum WriteError
|
||||||
|
{
|
||||||
|
NoWriteError
|
||||||
|
};
|
||||||
|
WriteError write(const AbstractGeometry& geom, const AbstractGeometryExtraData* extraData = 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace bin
|
||||||
|
} // namespace stl
|
||||||
|
} // namespace foug
|
||||||
|
|
||||||
|
#endif // FOUG_STLB_H
|
48
src/streams/qt4_stream.cpp
Normal file
48
src/streams/qt4_stream.cpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#include "qt4_stream.h"
|
||||||
|
|
||||||
|
#include <QtCore/QIODevice>
|
||||||
|
#include <QtCore/QtDebug>
|
||||||
|
|
||||||
|
namespace foug {
|
||||||
|
|
||||||
|
Qt4Stream::Qt4Stream(QIODevice *device)
|
||||||
|
: m_device(device)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Qt4Stream::atEnd() const
|
||||||
|
{
|
||||||
|
return m_device->atEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Qt4Stream::isWritable() const
|
||||||
|
{
|
||||||
|
return m_device != 0 ? m_device->isWritable() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Qt4Stream::isReadable() const
|
||||||
|
{
|
||||||
|
return m_device != 0 ? m_device->isReadable() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Qt4Stream::isSequential() const
|
||||||
|
{
|
||||||
|
return m_device != 0 ? m_device->isSequential() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Qt4Stream::seek(Int64 pos)
|
||||||
|
{
|
||||||
|
return m_device->seek(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
Int64 Qt4Stream::read(char *data, Int64 maxSize)
|
||||||
|
{
|
||||||
|
return m_device->read(data, maxSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
Int64 Qt4Stream::write(const char *data, Int64 maxSize)
|
||||||
|
{
|
||||||
|
return m_device->write(data, maxSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace foug
|
30
src/streams/qt4_stream.h
Normal file
30
src/streams/qt4_stream.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef FOUG_QT4_STREAM_H
|
||||||
|
#define FOUG_QT4_STREAM_H
|
||||||
|
|
||||||
|
#include "abstract_stream.h"
|
||||||
|
class QIODevice;
|
||||||
|
|
||||||
|
namespace foug {
|
||||||
|
|
||||||
|
class Qt4Stream : public AbstractStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Qt4Stream(QIODevice* device);
|
||||||
|
|
||||||
|
bool atEnd() const;
|
||||||
|
|
||||||
|
bool isWritable() const;
|
||||||
|
bool isReadable() const;
|
||||||
|
bool isSequential() const;
|
||||||
|
|
||||||
|
bool seek(foug::Int64 pos);
|
||||||
|
Int64 read(char* data, Int64 maxSize);
|
||||||
|
Int64 write(const char* data, Int64 maxSize);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QIODevice* m_device;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace foug
|
||||||
|
|
||||||
|
#endif // FOUG_QT4_STREAM_H
|
29
src/streams/std_io_stream.cpp
Normal file
29
src/streams/std_io_stream.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include "std_io_stream.h"
|
||||||
|
|
||||||
|
namespace foug {
|
||||||
|
|
||||||
|
StdIoStream::StdIoStream(std::iostream* iostr)
|
||||||
|
: m_iostr(iostr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Int64 StdIoStream::read(char* data, Int64 maxSize)
|
||||||
|
{
|
||||||
|
if (!m_iostr->eof())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
m_iostr->read(data, maxSize);
|
||||||
|
if (!m_iostr->good())
|
||||||
|
return -1;
|
||||||
|
return maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
Int64 StdIoStream::write(const char* data, Int64 maxSize)
|
||||||
|
{
|
||||||
|
m_iostr->write(data, maxSize);
|
||||||
|
if (!m_iostr->good())
|
||||||
|
return -1;
|
||||||
|
return maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace foug
|
114
src/streams/std_io_stream.h
Normal file
114
src/streams/std_io_stream.h
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
#ifndef FOUG_STD_IO_STREAM_H
|
||||||
|
#define FOUG_STD_IO_STREAM_H
|
||||||
|
|
||||||
|
#include "abstract_stream.h"
|
||||||
|
|
||||||
|
namespace foug {
|
||||||
|
|
||||||
|
template<typename STD_STREAM>
|
||||||
|
class StdInputStream : public AbstractStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StdInputStream(STD_STREAM* istr)
|
||||||
|
: m_istr(istr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool atEnd() const
|
||||||
|
{
|
||||||
|
return m_istr->eof();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isWritable() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isReadable() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSequential() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool seek(foug::Int64 pos)
|
||||||
|
{
|
||||||
|
m_istr->seekg(pos);
|
||||||
|
return m_istr->good();
|
||||||
|
}
|
||||||
|
|
||||||
|
Int64 read(char* data, Int64 maxSize)
|
||||||
|
{
|
||||||
|
m_istr->read(data, maxSize);
|
||||||
|
if (!m_istr->eof() && (m_istr->fail()))
|
||||||
|
return -1;
|
||||||
|
return m_istr->gcount();
|
||||||
|
}
|
||||||
|
|
||||||
|
Int64 write(const char* /*data*/, Int64 /*maxSize*/)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
STD_STREAM* m_istr;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename STD_STREAM>
|
||||||
|
class StdOutputStream : public AbstractStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StdOutputStream(STD_STREAM* ostr)
|
||||||
|
: m_ostr(ostr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool atEnd() const
|
||||||
|
{
|
||||||
|
return m_ostr->eof();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isWritable() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isReadable() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSequential() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool seek(foug::Int64 pos)
|
||||||
|
{
|
||||||
|
m_ostr->seekp(pos);
|
||||||
|
return m_ostr->good();
|
||||||
|
}
|
||||||
|
|
||||||
|
Int64 read(char* /*data*/, Int64 /*maxSize*/)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Int64 write(const char* data, Int64 maxSize)
|
||||||
|
{
|
||||||
|
m_ostr->write(data, maxSize);
|
||||||
|
if (!m_ostr->good())
|
||||||
|
return -1;
|
||||||
|
return maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
STD_STREAM* m_ostr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace foug
|
||||||
|
|
||||||
|
#endif // FOUG_STD_IO_STREAM_H
|
17
tests/bench_occ/bench_occ.pro
Normal file
17
tests/bench_occ/bench_occ.pro
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
include(../../qmake.build/config.pri)
|
||||||
|
include(_local_config.pri)
|
||||||
|
include(occ.pri)
|
||||||
|
|
||||||
|
TEMPLATE = app
|
||||||
|
TARGET = bench_occ$$TARGET_SUFFIX
|
||||||
|
|
||||||
|
QT *= core
|
||||||
|
|
||||||
|
HEADERS +=
|
||||||
|
|
||||||
|
SOURCES += main.cpp
|
||||||
|
|
||||||
|
LIBS *= -lTKSTL -lTKernel
|
||||||
|
|
||||||
|
INCLUDEPATH += ../../src
|
||||||
|
LIBS += -L../../bin -lfougstl$$TARGET_SUFFIX
|
90
tests/bench_occ/main.cpp
Normal file
90
tests/bench_occ/main.cpp
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <QtCore/QFile>
|
||||||
|
#include <QtCore/QScopedPointer>
|
||||||
|
#include <QtCore/QStringList>
|
||||||
|
#include <QtCore/QTime>
|
||||||
|
|
||||||
|
#include <QtCore/QtDebug>
|
||||||
|
|
||||||
|
#include <OSD_Path.hxx>
|
||||||
|
#include <RWStl.hxx>
|
||||||
|
#include <StlMesh_Mesh.hxx>
|
||||||
|
|
||||||
|
#include "streams/qt4_stream.h"
|
||||||
|
#include "libstl/stlb.h"
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
class OccStlMeshBuilder : public foug::stl::bin::AbstractGeometryBuilder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void beginTriangles(foug::UInt32 count)
|
||||||
|
{
|
||||||
|
Q_UNUSED(count);
|
||||||
|
m_stlMesh = new StlMesh_Mesh;
|
||||||
|
m_stlMesh->AddDomain();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nextTriangle(const foug::stl::Triangle& triangle, foug::UInt16 attributeByteCount)
|
||||||
|
{
|
||||||
|
Q_UNUSED(attributeByteCount);
|
||||||
|
const int uId = m_stlMesh->AddOnlyNewVertex(triangle.v1.x, triangle.v1.y, triangle.v1.z);
|
||||||
|
const int vId = m_stlMesh->AddOnlyNewVertex(triangle.v2.x, triangle.v2.y, triangle.v2.z);
|
||||||
|
const int wId = m_stlMesh->AddOnlyNewVertex(triangle.v3.x, triangle.v3.y, triangle.v3.z);
|
||||||
|
const foug::stl::Coords& n = triangle.normal;
|
||||||
|
m_stlMesh->AddTriangle(uId, vId, wId, n.x, n.y, n.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle_StlMesh_Mesh stlMesh() const
|
||||||
|
{
|
||||||
|
return m_stlMesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Handle_StlMesh_Mesh m_stlMesh;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
QStringList filePaths;
|
||||||
|
for (int i = 1; i < argc; ++i)
|
||||||
|
filePaths.append(argv[i]);
|
||||||
|
|
||||||
|
const int benchCount = 1;
|
||||||
|
QTime time;
|
||||||
|
time.start();
|
||||||
|
|
||||||
|
qDebug() << sizeof(foug::stl::Triangle);
|
||||||
|
|
||||||
|
for (int i = 0; i < benchCount; ++i) {
|
||||||
|
foreach (const QString& filePath, filePaths) {
|
||||||
|
Handle_StlMesh_Mesh stlMesh = RWStl::ReadBinary(OSD_Path(filePath.toAscii().constData()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << QString("OCC read time : %1sec").arg(time.elapsed() / 1000.);
|
||||||
|
|
||||||
|
|
||||||
|
time.restart();
|
||||||
|
|
||||||
|
internal::OccStlMeshBuilder occStlMeshBuilder;
|
||||||
|
foug::stl::bin::Io io;
|
||||||
|
io.setAutoDeleteStream(false);
|
||||||
|
for (int i = 0; i < benchCount; ++i) {
|
||||||
|
foreach (const QString& filePath, filePaths) {
|
||||||
|
QFile file(filePath);
|
||||||
|
if (file.open(QIODevice::ReadOnly)) {
|
||||||
|
foug::Qt4Stream stream(&file);
|
||||||
|
io.setStream(&stream);
|
||||||
|
io.read(&occStlMeshBuilder);
|
||||||
|
Handle_StlMesh_Mesh stlMesh = occStlMeshBuilder.stlMesh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << QString("FougSTL read time : %1sec").arg(time.elapsed() / 1000.);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
32
tests/bench_occ/occ.pri
Normal file
32
tests/bench_occ/occ.pri
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
use_oce {
|
||||||
|
INCLUDEPATH += $$CASCADE_ROOT/include/oce
|
||||||
|
!isEmpty(OCE_VERSION) {
|
||||||
|
LIBS += -L$$CASCADE_ROOT/lib/$$OCE_VERSION
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
INCLUDEPATH += $$CASCADE_ROOT/inc
|
||||||
|
}
|
||||||
|
|
||||||
|
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-*:LIBS += -L$$CASCADE_ROOT/lib
|
||||||
|
win32-*:LIBS += -L$$CASCADE_ROOT/win32/lib
|
||||||
|
|
||||||
|
# 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 $CASROOT/win32/lib
|
||||||
|
win32-msvc* {
|
||||||
|
OCC_TKSTEP = TKSTEP_tzn
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
OCC_TKSTEP = TKSTEP209
|
||||||
|
}
|
13
tests/cmd/cmd.pro
Normal file
13
tests/cmd/cmd.pro
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
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
|
234
tests/cmd/main.cpp
Normal file
234
tests/cmd/main.cpp
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
#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 header(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 nextTriangle(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 header(const foug::stl::bin::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 nextTriangle(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[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[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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user