Merge branch 'master' of https://github.com/assimp/assimp
commit
56e8dc5a43
18
.travis.yml
18
.travis.yml
|
@ -15,12 +15,12 @@ env:
|
||||||
matrix:
|
matrix:
|
||||||
- LINUX=1 TRAVIS_NO_EXPORT=YES
|
- LINUX=1 TRAVIS_NO_EXPORT=YES
|
||||||
- LINUX=1 TRAVIS_NO_EXPORT=NO
|
- LINUX=1 TRAVIS_NO_EXPORT=NO
|
||||||
- LINUX=1 TRAVIS_STATIC_BUILD=ON
|
- LINUX=1 SHARED_BUILD=ON
|
||||||
- LINUX=1 TRAVIS_STATIC_BUILD=OFF
|
- LINUX=1 SHARED_BUILD=OFF
|
||||||
- WINDOWS=1 TRAVIS_NO_EXPORT=YES
|
- WINDOWS=1 TRAVIS_NO_EXPORT=YES
|
||||||
- WINDOWS=1 TRAVIS_NO_EXPORT=NO
|
- WINDOWS=1 TRAVIS_NO_EXPORT=NO
|
||||||
- WINDOWS=1 TRAVIS_STATIC_BUILD=ON
|
- WINDOWS=1 SHARED_BUILD=ON
|
||||||
- WINDOWS=1 TRAVIS_STATIC_BUILD=OFF
|
- WINDOWS=1 SHARED_BUILD=OFF
|
||||||
- ANDROID=1
|
- ANDROID=1
|
||||||
|
|
||||||
language: cpp
|
language: cpp
|
||||||
|
@ -35,10 +35,18 @@ install:
|
||||||
script:
|
script:
|
||||||
- if [ $ANDROID ]; then
|
- if [ $ANDROID ]; then
|
||||||
ant -v -Dmy.dir=${TRAVIS_BUILD_DIR} -f ${TRAVIS_BUILD_DIR}/port/jassimp/build.xml ndk-jni ;
|
ant -v -Dmy.dir=${TRAVIS_BUILD_DIR} -f ${TRAVIS_BUILD_DIR}/port/jassimp/build.xml ndk-jni ;
|
||||||
|
elif [ $WINDOWS -a $CC = "gcc" ]; then
|
||||||
|
sudo sh -c "wget http://source.winehq.org/git/wine.git/commitdiff_plain/86781a6a524fa336f893ffd0a87373ffd306913c?hp=076edfe9d4b6cd39b6cf41b9f1d3e18688cc8673 -O - | patch -p 1 -d /usr/x86_64-w64-mingw32" ;
|
||||||
|
sudo sh -c "wget https://www.winehq.org/pipermail/wine-patches/2012-February/111438.html -O - | patch -p 1 -d /usr/x86_64-w64-mingw32" ;
|
||||||
|
cmake -G "Unix Makefiles" -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -DBUILD_SHARED_LIBS=$SHARED_BUILD -DCMAKE_TOOLCHAIN_FILE=cmake-modules/MinGW_x86_64.cmake ;
|
||||||
|
cmake --build . ;
|
||||||
|
make install ;
|
||||||
|
elif [ $WINDOWS ]; then
|
||||||
|
echo "Skip compile with non-gcc setting." ;
|
||||||
elif [ $RESERVED ]; then
|
elif [ $RESERVED ]; then
|
||||||
echo "Reserved condition" ;
|
echo "Reserved condition" ;
|
||||||
else
|
else
|
||||||
cmake -G "Unix Makefiles" -DASSIMP_ENABLE_BOOST_WORKAROUND=YES -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -STATIC_BUILD=$TRAVIS_STATIC_BUILD ;
|
cmake -G "Unix Makefiles" -DASSIMP_ENABLE_BOOST_WORKAROUND=YES -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -DBUILD_SHARED_LIBS=$SHARED_BUILD ;
|
||||||
make ;
|
make ;
|
||||||
sudo make install ;
|
sudo make install ;
|
||||||
sudo ldconfig ;
|
sudo ldconfig ;
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
cmake_minimum_required( VERSION 2.8 )
|
cmake_minimum_required( VERSION 2.8 )
|
||||||
PROJECT( Assimp )
|
PROJECT( Assimp )
|
||||||
|
|
||||||
|
option(BUILD_SHARED_LIBS "Build package with shared libraries." ON)
|
||||||
|
if(NOT BUILD_SHARED_LIBS)
|
||||||
|
#set(CMAKE_EXE_LINKER_FLAGS "-static")
|
||||||
|
set(LINK_SEARCH_START_STATIC TRUE)
|
||||||
|
endif(NOT BUILD_SHARED_LIBS)
|
||||||
|
|
||||||
# Define here the needed parameters
|
# Define here the needed parameters
|
||||||
set (ASSIMP_VERSION_MAJOR 3)
|
set (ASSIMP_VERSION_MAJOR 3)
|
||||||
set (ASSIMP_VERSION_MINOR 1)
|
set (ASSIMP_VERSION_MINOR 1)
|
||||||
|
@ -88,9 +94,6 @@ SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE PATH
|
||||||
|
|
||||||
SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfitx for lib, samples and tools")
|
SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfitx for lib, samples and tools")
|
||||||
|
|
||||||
# Allow the user to build a shared or static library
|
|
||||||
option ( BUILD_SHARED_LIBS "Build a shared version of the library" ON )
|
|
||||||
|
|
||||||
# Only generate this target if no higher-level project already has
|
# Only generate this target if no higher-level project already has
|
||||||
IF (NOT TARGET uninstall)
|
IF (NOT TARGET uninstall)
|
||||||
# add make uninstall capability
|
# add make uninstall capability
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
# this one sets internal to crosscompile (in theory)
|
||||||
|
SET(CMAKE_SYSTEM_NAME Windows)
|
||||||
|
|
||||||
|
# the minimalistic settings
|
||||||
|
SET(CMAKE_C_COMPILER "/usr/bin/x86_64-w64-mingw32-gcc")
|
||||||
|
SET(CMAKE_CXX_COMPILER "/usr/bin/x86_64-w64-mingw32-g++")
|
||||||
|
SET(CMAKE_RC_COMPILER "/usr/bin/x86_64-w64-mingw32-windres")
|
||||||
|
|
||||||
|
# where is the target (so called staging) environment
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)
|
||||||
|
|
||||||
|
# search for programs in the build host directories (default BOTH)
|
||||||
|
#SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
# for libraries and headers in the target directories
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
|
@ -148,13 +148,17 @@ void COBImporter::InternReadFile( const std::string& pFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultLogger::get()->info("File format tag: "+std::string(head+9,6));
|
DefaultLogger::get()->info("File format tag: "+std::string(head+9,6));
|
||||||
void (COBImporter::* load)(Scene&,StreamReaderLE*)= head[15]=='A'?&COBImporter::ReadAsciiFile:&COBImporter::ReadBinaryFile;
|
|
||||||
if (head[16]!='L') {
|
if (head[16]!='L') {
|
||||||
ThrowException("File is big-endian, which is not supported");
|
ThrowException("File is big-endian, which is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
// load data into intermediate structures
|
// load data into intermediate structures
|
||||||
(this->*load)(scene,stream.get());
|
if (head[15]=='A') {
|
||||||
|
ReadAsciiFile(scene, stream.get());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ReadBinaryFile(scene, stream.get());
|
||||||
|
}
|
||||||
if(scene.nodes.empty()) {
|
if(scene.nodes.empty()) {
|
||||||
ThrowException("No nodes loaded");
|
ThrowException("No nodes loaded");
|
||||||
}
|
}
|
||||||
|
|
|
@ -522,43 +522,23 @@ IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVect
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extrudes the given polygon along the direction, converts it into an opening or applies all openings as necessary.
|
||||||
// ------------------------------------------------------------------------------------------------
|
void ProcessExtrudedArea(const IfcExtrudedAreaSolid& solid, const TempMesh& curve,
|
||||||
void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& result,
|
const IfcVector3& extrusionDir, TempMesh& result, ConversionData &conv, bool collect_openings)
|
||||||
ConversionData& conv, bool collect_openings)
|
|
||||||
{
|
{
|
||||||
TempMesh meshout;
|
// Outline: 'curve' is now a list of vertex points forming the underlying profile, extrude along the given axis,
|
||||||
|
// forming new triangles.
|
||||||
// First read the profile description
|
const bool has_area = solid.SweptArea->ProfileType == "AREA" && curve.verts.size() > 2;
|
||||||
if(!ProcessProfile(*solid.SweptArea,meshout,conv) || meshout.verts.size()<=1) {
|
if( solid.Depth < 1e-6 ) {
|
||||||
return;
|
if( has_area ) {
|
||||||
}
|
result.Append(curve);
|
||||||
|
|
||||||
IfcVector3 dir;
|
|
||||||
ConvertDirection(dir,solid.ExtrudedDirection);
|
|
||||||
|
|
||||||
dir *= solid.Depth; /*
|
|
||||||
if(conv.collect_openings && !conv.apply_openings) {
|
|
||||||
dir *= 1000.0;
|
|
||||||
} */
|
|
||||||
|
|
||||||
// Outline: assuming that `meshout.verts` is now a list of vertex points forming
|
|
||||||
// the underlying profile, extrude along the given axis, forming new
|
|
||||||
// triangles.
|
|
||||||
|
|
||||||
std::vector<IfcVector3>& in = meshout.verts;
|
|
||||||
const size_t size=in.size();
|
|
||||||
|
|
||||||
const bool has_area = solid.SweptArea->ProfileType == "AREA" && size>2;
|
|
||||||
if(solid.Depth < 1e-6) {
|
|
||||||
if(has_area) {
|
|
||||||
result = meshout;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.verts.reserve(size*(has_area?4:2));
|
result.verts.reserve(curve.verts.size()*(has_area ? 4 : 2));
|
||||||
result.vertcnt.reserve(meshout.vertcnt.size()+2);
|
result.vertcnt.reserve(curve.verts.size() + 2);
|
||||||
|
std::vector<IfcVector3> in = curve.verts;
|
||||||
|
|
||||||
// First step: transform all vertices into the target coordinate space
|
// First step: transform all vertices into the target coordinate space
|
||||||
IfcMatrix4 trafo;
|
IfcMatrix4 trafo;
|
||||||
|
@ -566,7 +546,7 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
|
||||||
|
|
||||||
IfcVector3 vmin, vmax;
|
IfcVector3 vmin, vmax;
|
||||||
MinMaxChooser<IfcVector3>()(vmin, vmax);
|
MinMaxChooser<IfcVector3>()(vmin, vmax);
|
||||||
BOOST_FOREACH(IfcVector3& v,in) {
|
BOOST_FOREACH(IfcVector3& v, in) {
|
||||||
v *= trafo;
|
v *= trafo;
|
||||||
|
|
||||||
vmin = std::min(vmin, v);
|
vmin = std::min(vmin, v);
|
||||||
|
@ -575,14 +555,12 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
|
||||||
|
|
||||||
vmax -= vmin;
|
vmax -= vmin;
|
||||||
const IfcFloat diag = vmax.Length();
|
const IfcFloat diag = vmax.Length();
|
||||||
|
IfcVector3 dir = IfcMatrix3(trafo) * extrusionDir;
|
||||||
IfcVector3 min = in[0];
|
|
||||||
dir *= IfcMatrix3(trafo);
|
|
||||||
|
|
||||||
// reverse profile polygon if it's winded in the wrong direction in relation to the extrusion direction
|
// reverse profile polygon if it's winded in the wrong direction in relation to the extrusion direction
|
||||||
IfcVector3 profileNormal = TempMesh::ComputePolygonNormal( in.data(), in.size());
|
IfcVector3 profileNormal = TempMesh::ComputePolygonNormal(in.data(), in.size());
|
||||||
if( profileNormal * dir < 0.0 )
|
if( profileNormal * dir < 0.0 )
|
||||||
std::reverse( in.begin(), in.end());
|
std::reverse(in.begin(), in.end());
|
||||||
|
|
||||||
std::vector<IfcVector3> nors;
|
std::vector<IfcVector3> nors;
|
||||||
const bool openings = !!conv.apply_openings && conv.apply_openings->size();
|
const bool openings = !!conv.apply_openings && conv.apply_openings->size();
|
||||||
|
@ -590,25 +568,24 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
|
||||||
// Compute the normal vectors for all opening polygons as a prerequisite
|
// Compute the normal vectors for all opening polygons as a prerequisite
|
||||||
// to TryAddOpenings_Poly2Tri()
|
// to TryAddOpenings_Poly2Tri()
|
||||||
// XXX this belongs into the aforementioned function
|
// XXX this belongs into the aforementioned function
|
||||||
if (openings) {
|
if( openings ) {
|
||||||
|
|
||||||
if (!conv.settings.useCustomTriangulation) {
|
if( !conv.settings.useCustomTriangulation ) {
|
||||||
// it is essential to apply the openings in the correct spatial order. The direction
|
// it is essential to apply the openings in the correct spatial order. The direction
|
||||||
// doesn't matter, but we would screw up if we started with e.g. a door in between
|
// doesn't matter, but we would screw up if we started with e.g. a door in between
|
||||||
// two windows.
|
// two windows.
|
||||||
std::sort(conv.apply_openings->begin(),conv.apply_openings->end(),
|
std::sort(conv.apply_openings->begin(), conv.apply_openings->end(), TempOpening::DistanceSorter(in[0]));
|
||||||
TempOpening::DistanceSorter(min));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nors.reserve(conv.apply_openings->size());
|
nors.reserve(conv.apply_openings->size());
|
||||||
BOOST_FOREACH(TempOpening& t,*conv.apply_openings) {
|
BOOST_FOREACH(TempOpening& t, *conv.apply_openings) {
|
||||||
TempMesh& bounds = *t.profileMesh.get();
|
TempMesh& bounds = *t.profileMesh.get();
|
||||||
|
|
||||||
if (bounds.verts.size() <= 2) {
|
if( bounds.verts.size() <= 2 ) {
|
||||||
nors.push_back(IfcVector3());
|
nors.push_back(IfcVector3());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
nors.push_back(((bounds.verts[2]-bounds.verts[0])^(bounds.verts[1]-bounds.verts[0]) ).Normalize());
|
nors.push_back(((bounds.verts[2] - bounds.verts[0]) ^ (bounds.verts[1] - bounds.verts[0])).Normalize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -618,18 +595,18 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
|
||||||
std::vector<IfcVector3>& out = curmesh.verts;
|
std::vector<IfcVector3>& out = curmesh.verts;
|
||||||
|
|
||||||
size_t sides_with_openings = 0;
|
size_t sides_with_openings = 0;
|
||||||
for(size_t i = 0; i < size; ++i) {
|
for( size_t i = 0; i < in.size(); ++i ) {
|
||||||
const size_t next = (i+1)%size;
|
const size_t next = (i + 1) % in.size();
|
||||||
|
|
||||||
curmesh.vertcnt.push_back(4);
|
curmesh.vertcnt.push_back(4);
|
||||||
|
|
||||||
out.push_back(in[i]);
|
out.push_back(in[i]);
|
||||||
out.push_back(in[next]);
|
out.push_back(in[next]);
|
||||||
out.push_back(in[next]+dir);
|
out.push_back(in[next] + dir);
|
||||||
out.push_back(in[i]+dir);
|
out.push_back(in[i] + dir);
|
||||||
|
|
||||||
if(openings) {
|
if( openings ) {
|
||||||
if((in[i]-in[next]).Length() > diag * 0.1 && GenerateOpenings(*conv.apply_openings,nors,temp,true, true, dir)) {
|
if( (in[i] - in[next]).Length() > diag * 0.1 && GenerateOpenings(*conv.apply_openings, nors, temp, true, true, dir) ) {
|
||||||
++sides_with_openings;
|
++sides_with_openings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -638,9 +615,9 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(openings) {
|
if( openings ) {
|
||||||
BOOST_FOREACH(TempOpening& opening, *conv.apply_openings) {
|
BOOST_FOREACH(TempOpening& opening, *conv.apply_openings) {
|
||||||
if (!opening.wallPoints.empty()) {
|
if( !opening.wallPoints.empty() ) {
|
||||||
IFCImporter::LogError("failed to generate all window caps");
|
IFCImporter::LogError("failed to generate all window caps");
|
||||||
}
|
}
|
||||||
opening.wallPoints.clear();
|
opening.wallPoints.clear();
|
||||||
|
@ -648,20 +625,21 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t sides_with_v_openings = 0;
|
size_t sides_with_v_openings = 0;
|
||||||
if(has_area) {
|
if( has_area ) {
|
||||||
|
|
||||||
for(size_t n = 0; n < 2; ++n) {
|
for( size_t n = 0; n < 2; ++n ) {
|
||||||
if( n > 0 ) {
|
if( n > 0 ) {
|
||||||
for(size_t i = 0; i < size; ++i )
|
for( size_t i = 0; i < in.size(); ++i )
|
||||||
out.push_back(in[i]+dir);
|
out.push_back(in[i] + dir);
|
||||||
} else {
|
}
|
||||||
for(size_t i = size; i--; )
|
else {
|
||||||
|
for( size_t i = in.size(); i--; )
|
||||||
out.push_back(in[i]);
|
out.push_back(in[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
curmesh.vertcnt.push_back(size);
|
curmesh.vertcnt.push_back(in.size());
|
||||||
if(openings && size > 2) {
|
if( openings && in.size() > 2 ) {
|
||||||
if(GenerateOpenings(*conv.apply_openings,nors,temp,true, true, dir)) {
|
if( GenerateOpenings(*conv.apply_openings, nors, temp, true, true, dir) ) {
|
||||||
++sides_with_v_openings;
|
++sides_with_v_openings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -671,7 +649,7 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(openings && ((sides_with_openings == 1 && sides_with_openings) || (sides_with_v_openings == 2 && sides_with_v_openings))) {
|
if( openings && ((sides_with_openings == 1 && sides_with_openings) || (sides_with_v_openings == 2 && sides_with_v_openings)) ) {
|
||||||
IFCImporter::LogWarn("failed to resolve all openings, presumably their topology is not supported by Assimp");
|
IFCImporter::LogWarn("failed to resolve all openings, presumably their topology is not supported by Assimp");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -679,19 +657,60 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
|
||||||
|
|
||||||
// If this is an opening element, store both the extruded mesh and the 2D profile mesh
|
// If this is an opening element, store both the extruded mesh and the 2D profile mesh
|
||||||
// it was created from. Return an empty mesh to the caller.
|
// it was created from. Return an empty mesh to the caller.
|
||||||
if(collect_openings && !result.IsEmpty()) {
|
if( collect_openings && !result.IsEmpty() ) {
|
||||||
ai_assert(conv.collect_openings);
|
ai_assert(conv.collect_openings);
|
||||||
boost::shared_ptr<TempMesh> profile = boost::shared_ptr<TempMesh>(new TempMesh());
|
boost::shared_ptr<TempMesh> profile = boost::shared_ptr<TempMesh>(new TempMesh());
|
||||||
profile->Swap(result);
|
profile->Swap(result);
|
||||||
|
|
||||||
boost::shared_ptr<TempMesh> profile2D = boost::shared_ptr<TempMesh>(new TempMesh());
|
boost::shared_ptr<TempMesh> profile2D = boost::shared_ptr<TempMesh>(new TempMesh());
|
||||||
profile2D->Swap(meshout);
|
profile2D->verts.insert(profile2D->verts.end(), in.begin(), in.end());
|
||||||
conv.collect_openings->push_back(TempOpening(&solid,dir,profile, profile2D));
|
profile2D->vertcnt.push_back(in.size());
|
||||||
|
conv.collect_openings->push_back(TempOpening(&solid, dir, profile, profile2D));
|
||||||
|
|
||||||
ai_assert(result.IsEmpty());
|
ai_assert(result.IsEmpty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& result,
|
||||||
|
ConversionData& conv, bool collect_openings)
|
||||||
|
{
|
||||||
|
TempMesh meshout;
|
||||||
|
|
||||||
|
// First read the profile description.
|
||||||
|
if(!ProcessProfile(*solid.SweptArea,meshout,conv) || meshout.verts.size()<=1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IfcVector3 dir;
|
||||||
|
ConvertDirection(dir,solid.ExtrudedDirection);
|
||||||
|
dir *= solid.Depth;
|
||||||
|
|
||||||
|
// Some profiles bring their own holes, for which we need to provide a container. This all is somewhat backwards,
|
||||||
|
// and there's still so many corner cases uncovered - we really need a generic solution to all of this hole carving.
|
||||||
|
std::vector<TempOpening> fisherPriceMyFirstOpenings;
|
||||||
|
std::vector<TempOpening>* oldApplyOpenings = conv.apply_openings;
|
||||||
|
if( const IfcArbitraryProfileDefWithVoids* const cprofile = solid.SweptArea->ToPtr<IfcArbitraryProfileDefWithVoids>() ) {
|
||||||
|
if( !cprofile->InnerCurves.empty() ) {
|
||||||
|
// read all inner curves and extrude them to form proper openings.
|
||||||
|
std::vector<TempOpening>* oldCollectOpenings = conv.collect_openings;
|
||||||
|
conv.collect_openings = &fisherPriceMyFirstOpenings;
|
||||||
|
|
||||||
|
BOOST_FOREACH(const IfcCurve* curve, cprofile->InnerCurves) {
|
||||||
|
TempMesh curveMesh, tempMesh;
|
||||||
|
ProcessCurve(*curve, curveMesh, conv);
|
||||||
|
ProcessExtrudedArea(solid, curveMesh, dir, tempMesh, conv, true);
|
||||||
|
}
|
||||||
|
// and then apply those to the geometry we're about to generate
|
||||||
|
conv.apply_openings = conv.collect_openings;
|
||||||
|
conv.collect_openings = oldCollectOpenings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessExtrudedArea(solid, meshout, dir, result, conv, collect_openings);
|
||||||
|
conv.apply_openings = oldApplyOpenings;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ProcessSweptAreaSolid(const IfcSweptAreaSolid& swept, TempMesh& meshout,
|
void ProcessSweptAreaSolid(const IfcSweptAreaSolid& swept, TempMesh& meshout,
|
||||||
ConversionData& conv)
|
ConversionData& conv)
|
||||||
|
@ -784,7 +803,7 @@ bool ProcessGeometricItem(const IfcRepresentationItem& geo, unsigned int matid,
|
||||||
meshtmp->RemoveDegenerates();
|
meshtmp->RemoveDegenerates();
|
||||||
|
|
||||||
if(fix_orientation) {
|
if(fix_orientation) {
|
||||||
meshtmp->FixupFaceOrientation();
|
// meshtmp->FixupFaceOrientation();
|
||||||
}
|
}
|
||||||
|
|
||||||
aiMesh* const mesh = meshtmp->ToMesh();
|
aiMesh* const mesh = meshtmp->ToMesh();
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
7622
code/IFCReaderGen.h
7622
code/IFCReaderGen.h
File diff suppressed because it is too large
Load Diff
|
@ -271,6 +271,7 @@ IfcFloat ConvertSIPrefix(const std::string& prefix);
|
||||||
|
|
||||||
// IFCProfile.cpp
|
// IFCProfile.cpp
|
||||||
bool ProcessProfile(const IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv);
|
bool ProcessProfile(const IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv);
|
||||||
|
bool ProcessCurve(const IfcCurve& curve, TempMesh& meshout, ConversionData& conv);
|
||||||
|
|
||||||
// IFCMaterial.cpp
|
// IFCMaterial.cpp
|
||||||
unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionData& conv, bool forceDefaultMat);
|
unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionData& conv, bool forceDefaultMat);
|
||||||
|
|
|
@ -1023,7 +1023,9 @@ void SceneCombiner::CopyScene(aiScene** _dest,const aiScene* src,bool allocate)
|
||||||
dest->mFlags = src->mFlags;
|
dest->mFlags = src->mFlags;
|
||||||
|
|
||||||
// source private data might be NULL if the scene is user-allocated (i.e. for use with the export API)
|
// source private data might be NULL if the scene is user-allocated (i.e. for use with the export API)
|
||||||
|
if (dest->mPrivate != NULL) {
|
||||||
ScenePriv(dest)->mPPStepsApplied = ScenePriv(src) ? ScenePriv(src)->mPPStepsApplied : 0;
|
ScenePriv(dest)->mPPStepsApplied = ScenePriv(src) ? ScenePriv(src)->mPPStepsApplied : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
entities and data types contained"""
|
entities and data types contained"""
|
||||||
|
|
||||||
import sys, os, re
|
import sys, os, re
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
re_match_entity = re.compile(r"""
|
re_match_entity = re.compile(r"""
|
||||||
ENTITY\s+(\w+)\s* # 'ENTITY foo'
|
ENTITY\s+(\w+)\s* # 'ENTITY foo'
|
||||||
|
@ -68,8 +69,8 @@ re_match_field = re.compile(r"""
|
||||||
|
|
||||||
class Schema:
|
class Schema:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.entities = {}
|
self.entities = OrderedDict()
|
||||||
self.types = {}
|
self.types = OrderedDict()
|
||||||
|
|
||||||
class Entity:
|
class Entity:
|
||||||
def __init__(self,name,parent,members):
|
def __init__(self,name,parent,members):
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
IfcAnnotation
|
IfcAnnotation
|
||||||
IfcArbitraryClosedProfileDef
|
IfcArbitraryClosedProfileDef
|
||||||
IfcArbitraryOpenProfileDef
|
IfcArbitraryOpenProfileDef
|
||||||
|
IfcArbitraryProfileDefWithVoids
|
||||||
IfcAxis1Placement
|
IfcAxis1Placement
|
||||||
IfcAxis2Placement
|
IfcAxis2Placement
|
||||||
IfcAxis2Placement2D
|
IfcAxis2Placement2D
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,83 +3,81 @@ Assimp Regression Test Suite
|
||||||
|
|
||||||
1) How does it work?
|
1) How does it work?
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
run.py checks all model in the <root>/test/models folder and compares the result
|
run.py checks all model in the <root>/test/models* folders and compares the result
|
||||||
against a regression database provided by us (db.zip). If the test passes
|
against a regression database provided with assimp (db.zip). A few failures
|
||||||
successfully, Assimp definitely WORKS perfectly on your system. A few failures
|
are totally fine (see sections 7+). You need to worry if a huge
|
||||||
are totally fine as well (see sections 7+). You need to worry if a huge
|
majority of all files in a particular format (or post-processing configuration)
|
||||||
majority of all files in a particular format or post-processing configuration
|
fails as this might be a sign of a recent regression in assimp's codebase or
|
||||||
fails - this might be a sign of a recent regression in assimp's codebase.
|
gross incompatibility with your system or compiler.
|
||||||
|
|
||||||
2) What do I need?
|
2) What do I need?
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
- you need Python installed - 3.x !!
|
- You need Python installed (2.7+, 3.x). On Windows, run the scripts using "py".
|
||||||
- you need to build tools/assimp_cmd as described in the INSTALL file (
|
- You need to build the assimp command line tool (ASSIMP_BUILD_ASSIMP_TOOLS
|
||||||
make && make install on unixes,release-dll target with msvc).
|
CMake build flag). Both run.py and gen_db.py take the full path to the binary
|
||||||
|
as first command line parameter.
|
||||||
|
|
||||||
3) How to add more test files?
|
3) How to add more test files?
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
Use the following procedure:
|
Use the following procedure:
|
||||||
- verify the correctness of your assimp build - run the regression suite.
|
- Verify the correctness of your assimp build - run the regression suite.
|
||||||
DO NOT continue if one or more tests fail.
|
DO NOT continue if more tests fail than usual.
|
||||||
- add your additional test files to <root>/test/models/<fileformat>, where
|
- Add your additional test files to <root>/test/models/<fileformat>, where
|
||||||
<fileformat> is the file type (typically the file extension)
|
<fileformat> is the file type (typically the file extension).
|
||||||
- rebuild the regression database using gen_db.py
|
- If you test file does not meet the BSD license requirements, add it to
|
||||||
- run the regression suite again - all tests should pass, including
|
<root>/test/models-nonbsd/<fileformat> so people know to be careful with it.
|
||||||
those for the new files.
|
- Rebuild the regression database:
|
||||||
|
"gen_db.py <binary> -ixyz" where .xyz is the file extension of the new file.
|
||||||
|
- Run the regression suite again. There should be no new failures and the new
|
||||||
|
file should not be among the failures.
|
||||||
|
- Include the db.zip file with your Pull Request. Travis CI enforces a passing
|
||||||
|
regression suite (with offenders whitelisted as a last resort).
|
||||||
|
|
||||||
- contributors: commit the db.zip plus your additional test files to
|
4) I made a change/fix/patch to a loader, how to update the database?
|
||||||
the SVN repository.
|
|
||||||
|
|
||||||
4) I made a change/fix/.. to a loader, how to update the database?
|
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
- rebuild the regression database using gen_db.py
|
- Rebuild the regression database using "gen_db.py <binary> -ixyz"
|
||||||
- run the suite - all tests should pass now. If they do not, don't continue
|
where .xyz is the file extension for which the loader was patched.
|
||||||
|
- Run the regression suite again. There should be no new failures and the new
|
||||||
|
file should not be among the failures.
|
||||||
|
- Include the db.zip file with your Pull Request. Travis CI enforces a passing
|
||||||
|
regression suite (with offenders whitelisted as a last resort).
|
||||||
|
|
||||||
- contributors: commit the db.zip to the SVN repository
|
5) How to add my whole model repository to the database?
|
||||||
|
|
||||||
5) How to add my whole model repository to the suite?
|
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
|
|
||||||
Edit the reg_settings.py file and add the path to your repository to
|
Edit the reg_settings.py file and add the path to your repository to
|
||||||
<<model_directories>>. Then, rebuild the suite.
|
<<model_directories>>. Then, rebuild the database.
|
||||||
|
|
||||||
6) So what is actually verified?
|
6) So what is actually tested?
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
The regression database includes mini dumps of the aiScene data structure -
|
The regression database includes mini dumps of the aiScene data structure, i.e.
|
||||||
the scene hierarchy plus the sizes of all data arrays MUST match. Floating-point
|
the scene hierarchy plus the sizes of all data arrays MUST match. Floating-point
|
||||||
data buffers, such as vertex positions, are handled less strictly: min,max and
|
data buffers, such as vertex positions are handled less strictly: min, max and
|
||||||
average values are stored with lower precision. This takes hardware- or
|
average values are stored with low precision. This takes hardware- or
|
||||||
compiler-specific differences in floating-point computations into account.
|
compiler-specific differences in floating-point computations into account.
|
||||||
Generally, almost all significant regressions will be detected while the
|
Generally, almost all significant regressions will be detected while the
|
||||||
number of false positives is relatively low.
|
number of false positives is relatively low.
|
||||||
|
|
||||||
7) The test suite fails, what do do?
|
7) The test suite fails, what do do?
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
Get back to ../results and check out regression_suite_failures.txt
|
Get back to <root>/test/results and look at regression_suite_failures.txt.
|
||||||
It contains a list of all files which failed the test ... they're copied to
|
It contains a list of all files which failed the test. Failing dumps are copied to
|
||||||
../results/tmp. Both an EXPECTED and an ACTUAL file is produced per test.
|
root>/test/results/tmp. Both an EXPECTED and an ACTUAL file is produced per test.
|
||||||
The output of `assimp cmpdump` is written to regressions_suite_output.txt.
|
The output of "assimp cmpdump" is written to regressions_suite_output.txt. Grep
|
||||||
To quickly find all all reports pertaining to tests which failed, I'd
|
for the file name in question and locate the log for the failed comparison. It
|
||||||
recommend grepping for 'but' because its a constituent of all error messages
|
contains a full trace of which scene elements have been compared before, which
|
||||||
produced by assimp_cmd :) Error reports contain detailed information
|
makes it reasonably easy to locate the offending field.
|
||||||
regarding the point of failure inside the data structure, the values of
|
|
||||||
the two corresponding fields that were found to be different from EXPECTED
|
|
||||||
and ACTUAL, respectively, ... this should offer you enough information to start
|
|
||||||
debugging.
|
|
||||||
|
|
||||||
8) fp:fast vs fp:precise fails the test suite (same for gcc equivalents)
|
8) fp:fast vs fp:precise fails the test suite (same for gcc equivalents)
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
As mentioned above, floating-point inaccuracies between differently optimized
|
As mentioned above, floating-point inaccuracies between differently optimized
|
||||||
builds are not considered regressions and all float comparisons done by the test
|
builds are not considered regressions and all float comparisons done by the test
|
||||||
suite involve an epsilon. Changing floating-point optimizations can, however,
|
suite involve an epsilon to accomodate. However compiler settings that allow
|
||||||
lead to *real* changes in the output data structure, such as different number
|
compilers to perform non-IEEE754 compliant optimizations can cause arbitrary
|
||||||
of vertices or faces, ... this violates one of our primary targets, that is
|
failures in the test suite. Even if the compiler is configured to be IEE754
|
||||||
produce reliable and portable output. We're working hard on removing these
|
comformant, there is lots of code in assimp that leaves the compiler a choice
|
||||||
issues, but at the moment you have to live with few of them.
|
and different compilers make different choices (for example the precision of
|
||||||
|
float intermediaries is implementation-specified).
|
||||||
Currently, the regression database is build on Windows using MSVC8 with
|
|
||||||
fp:precise. This leads to a small number of failures with fp:fast and
|
|
||||||
virtally every build with gcc. Be patient, it will be fixed.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,9 @@ configs for an IDE, make sure to build the assimp_cmd project.
|
||||||
|
|
||||||
-i,--include: List of file extensions to update dumps for. If omitted,
|
-i,--include: List of file extensions to update dumps for. If omitted,
|
||||||
all file extensions are updated except those in `exclude`.
|
all file extensions are updated except those in `exclude`.
|
||||||
|
Example: -ixyz,abc
|
||||||
|
-i.xyz,.abc
|
||||||
|
--include=xyz,abc
|
||||||
|
|
||||||
-e,--exclude: Merged with settings.exclude_extensions to produce a
|
-e,--exclude: Merged with settings.exclude_extensions to produce a
|
||||||
list of all file extensions to ignore. If dumps exist,
|
list of all file extensions to ignore. If dumps exist,
|
||||||
|
@ -78,8 +81,6 @@ configs for an IDE, make sure to build the assimp_cmd project.
|
||||||
Dont' change anything.
|
Dont' change anything.
|
||||||
|
|
||||||
-n,--nozip: Don't pack to ZIP archive. Keep all dumps in individual files.
|
-n,--nozip: Don't pack to ZIP archive. Keep all dumps in individual files.
|
||||||
|
|
||||||
(lists of file extensions are comma delimited, i.e. `3ds,lwo,x`)
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
|
@ -172,30 +173,32 @@ def gen_db(ext_list,outfile):
|
||||||
|
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
assimp_bin_path = sys.argv[1] if len(sys.argv) > 1 else 'assimp'
|
|
||||||
|
|
||||||
def clean(f):
|
def clean(f):
|
||||||
f = f.strip("* \'")
|
f = f.strip("* \'")
|
||||||
return "."+f if f[:1] != '.' else f
|
return "."+f if f[:1] != '.' else f
|
||||||
|
|
||||||
if len(sys.argv)>1 and (sys.argv[1] == "--help" or sys.argv[1] == "-h"):
|
if len(sys.argv) <= 1 or sys.argv[1] == "--help" or sys.argv[1] == "-h":
|
||||||
print(usage)
|
print(usage)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
assimp_bin_path = sys.argv[1]
|
||||||
ext_list, preview, nozip = None, False, False
|
ext_list, preview, nozip = None, False, False
|
||||||
for m in sys.argv[1:]:
|
for m in sys.argv[2:]:
|
||||||
if m[:10]=="--exclude=":
|
if m[:10]=="--exclude=":
|
||||||
settings.exclude_extensions += map(clean, m[10:].split(","))
|
settings.exclude_extensions += map(clean, m[10:].split(","))
|
||||||
elif m[:3]=="-e=":
|
elif m[:2]=="-e":
|
||||||
settings.exclude_extensions += map(clean, m[3:].split(","))
|
settings.exclude_extensions += map(clean, m[2:].split(","))
|
||||||
elif m[:10]=="--include=":
|
elif m[:10]=="--include=":
|
||||||
ext_list = m[10:].split(",")
|
ext_list = m[10:].split(",")
|
||||||
elif m[:3]=="-i=":
|
elif m[:2]=="-i":
|
||||||
ext_list = m[3:].split(",")
|
ext_list = m[2:].split(",")
|
||||||
elif m=="-p" or m == "--preview":
|
elif m=="-p" or m == "--preview":
|
||||||
preview = True
|
preview = True
|
||||||
elif m=="-n" or m == "--nozip":
|
elif m=="-n" or m == "--nozip":
|
||||||
nozip = True
|
nozip = True
|
||||||
|
else:
|
||||||
|
print("Unrecognized parameter: " + m)
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
outfile = open(os.path.join("..", "results", "gen_regression_db_output.txt"), "w")
|
outfile = open(os.path.join("..", "results", "gen_regression_db_output.txt"), "w")
|
||||||
if ext_list is None:
|
if ext_list is None:
|
||||||
|
@ -206,9 +209,8 @@ if __name__ == "__main__":
|
||||||
# todo: Fix for multi dot extensions like .skeleton.xml
|
# todo: Fix for multi dot extensions like .skeleton.xml
|
||||||
ext_list = list(filter(lambda f: not f in settings.exclude_extensions,
|
ext_list = list(filter(lambda f: not f in settings.exclude_extensions,
|
||||||
map(clean, ext_list)))
|
map(clean, ext_list)))
|
||||||
|
print('File extensions processed: ' + ', '.join(ext_list))
|
||||||
if preview:
|
if preview:
|
||||||
print(','.join(ext_list))
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
extract_zip()
|
extract_zip()
|
||||||
|
|
Loading…
Reference in New Issue