Mosfet80 clipper update (#5220)

* remove deprecated sprinf

* Update clipper
Updated Clipper to V6.4.2

* Fix the build

* Fix the build

* Disable hunter build

* Fix: Fix hided var.

* Fix invalid use of hunter enabled macro.

* Fix misconfig for hunter

* Disable removing contrib folder

* Update BlenderTessellator.h

* Remove Hunter-based includes

* Refactorings

* Remove final

* Update IFCCurve.cpp

* Update IFCCurve.cpp

---------

Co-authored-by: andrea <realeandrea@yahoo.it>
Co-authored-by: Kim Kulling <kim.kullingk@draeger.com>
pull/5225/head
Kim Kulling 2023-09-09 19:29:15 +02:00 committed by GitHub
parent 3cf7d28bc4
commit aa1996e143
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 4320 additions and 3238 deletions

View File

@ -74,12 +74,6 @@ jobs:
repository: cpp-pm/polly repository: cpp-pm/polly
path: cmake/polly path: cmake/polly
- name: Remove contrib directory for Hunter builds
if: contains(matrix.name, 'hunter')
uses: JesseTG/rm@v1.0.3
with:
path: contrib
- name: Cache DX SDK - name: Cache DX SDK
id: dxcache id: dxcache
if: contains(matrix.name, 'windows') if: contains(matrix.name, 'windows')

View File

@ -52,7 +52,6 @@ IF(ASSIMP_HUNTER_ENABLED)
URL "https://github.com/cpp-pm/hunter/archive/v0.24.17.tar.gz" URL "https://github.com/cpp-pm/hunter/archive/v0.24.17.tar.gz"
SHA1 "e6396699e414120e32557fe92db097b7655b760b" SHA1 "e6396699e414120e32557fe92db097b7655b760b"
) )
add_definitions(-DASSIMP_USE_HUNTER) add_definitions(-DASSIMP_USE_HUNTER)
ENDIF() ENDIF()
@ -201,12 +200,9 @@ SET (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VER
SET (ASSIMP_SOVERSION 5) SET (ASSIMP_SOVERSION 5)
SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" ) SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" )
if(NOT ASSIMP_HUNTER_ENABLED) set(CMAKE_CXX_STANDARD 17)
# Enable C++17 support globally set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_STANDARD 99)
endif()
IF(NOT ASSIMP_IGNORE_GIT_HASH) IF(NOT ASSIMP_IGNORE_GIT_HASH)
# Get the current working branch # Get the current working branch
@ -254,8 +250,7 @@ IF( UNIX )
# Use GNUInstallDirs for Unix predefined directories # Use GNUInstallDirs for Unix predefined directories
INCLUDE(GNUInstallDirs) INCLUDE(GNUInstallDirs)
# Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit linux # Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit linux
IF( ${OPERATING_SYSTEM} MATCHES "Android") IF(NOT ${OPERATING_SYSTEM} MATCHES "Android")
ELSE()
IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 ) ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 )
ENDIF() ENDIF()
@ -265,7 +260,6 @@ ENDIF()
# Grouped compiler settings ######################################## # Grouped compiler settings ########################################
IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT MINGW) IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT MINGW)
IF(NOT ASSIMP_HUNTER_ENABLED) IF(NOT ASSIMP_HUNTER_ENABLED)
SET(CMAKE_CXX_STANDARD 17)
SET(CMAKE_POSITION_INDEPENDENT_CODE ON) SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
ENDIF() ENDIF()
@ -302,7 +296,6 @@ ELSEIF(MSVC)
SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG:FULL /PDBALTPATH:%_PDB% /OPT:REF /OPT:ICF") SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG:FULL /PDBALTPATH:%_PDB% /OPT:REF /OPT:ICF")
ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
IF(NOT ASSIMP_HUNTER_ENABLED) IF(NOT ASSIMP_HUNTER_ENABLED)
SET(CMAKE_CXX_STANDARD 17)
SET(CMAKE_POSITION_INDEPENDENT_CODE ON) SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
ENDIF() ENDIF()
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long ${CMAKE_CXX_FLAGS}" ) SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long ${CMAKE_CXX_FLAGS}" )
@ -332,12 +325,12 @@ IF ( IOS AND NOT ASSIMP_HUNTER_ENABLED)
ELSE() ELSE()
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3")
# Experimental for pdb generation
ENDIF() ENDIF()
ENDIF() ENDIF()
IF (ASSIMP_COVERALLS) IF (ASSIMP_COVERALLS)
MESSAGE(STATUS "Coveralls enabled") MESSAGE(STATUS "Coveralls enabled")
INCLUDE(Coveralls) INCLUDE(Coveralls)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
@ -345,12 +338,14 @@ ENDIF()
IF (ASSIMP_ASAN) IF (ASSIMP_ASAN)
MESSAGE(STATUS "AddressSanitizer enabled") MESSAGE(STATUS "AddressSanitizer enabled")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
ENDIF() ENDIF()
IF (ASSIMP_UBSAN) IF (ASSIMP_UBSAN)
MESSAGE(STATUS "Undefined Behavior sanitizer enabled") MESSAGE(STATUS "Undefined Behavior sanitizer enabled")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all")
ENDIF() ENDIF()
@ -697,7 +692,6 @@ ELSE()
COMPONENT ${LIBASSIMP_COMPONENT} COMPONENT ${LIBASSIMP_COMPONENT}
INCLUDES DESTINATION include INCLUDES DESTINATION include
) )
ENDIF() ENDIF()
ENDIF() ENDIF()
ENDIF() ENDIF()

View File

@ -102,10 +102,6 @@ void Structure::Convert<CollectionObject>(
ReadFieldPtr<ErrorPolicy_Fail>(dest.next, "*next", db); ReadFieldPtr<ErrorPolicy_Fail>(dest.next, "*next", db);
{ {
//std::shared_ptr<CollectionObject> prev;
//ReadFieldPtr<ErrorPolicy_Fail>(prev, "*prev", db);
//dest.prev = prev.get();
std::shared_ptr<Object> ob; std::shared_ptr<Object> ob;
ReadFieldPtr<ErrorPolicy_Igno>(ob, "*ob", db); ReadFieldPtr<ErrorPolicy_Igno>(ob, "*ob", db);
dest.ob = ob.get(); dest.ob = ob.get();

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -40,10 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file BlenderTessellator.cpp /// @file BlenderTessellator.cpp
* @brief A simple tessellation wrapper /// @brief A simple tessellation wrapper
*/
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER #ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -144,11 +143,7 @@ namespace Assimp
#if ASSIMP_BLEND_WITH_POLY_2_TRI #if ASSIMP_BLEND_WITH_POLY_2_TRI
#ifdef ASSIMP_USE_HUNTER #include "contrib/poly2tri/poly2tri/poly2tri.h"
# include <poly2tri/poly2tri.h>
#else
# include "../contrib/poly2tri/poly2tri/poly2tri.h"
#endif
namespace Assimp namespace Assimp
{ {

View File

@ -38,9 +38,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file IFCBoolean.cpp /// @file IFCBoolean.cpp
* @brief Implements a subset of Ifc boolean operations /// @brief Implements a subset of Ifc boolean operations
*/
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER #ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
@ -48,7 +47,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Common/PolyTools.h" #include "Common/PolyTools.h"
#include "PostProcessing/ProcessHelper.h" #include "PostProcessing/ProcessHelper.h"
#include <iterator> #include <iterator>
#include <tuple> #include <tuple>
#include <utility> #include <utility>
@ -67,8 +65,9 @@ bool IntersectSegmentPlane(const IfcVector3 &p, const IfcVector3 &n, const IfcVe
// if segment ends on plane, do not report a hit. We stay on that side until a following segment starting at this // if segment ends on plane, do not report a hit. We stay on that side until a following segment starting at this
// point leaves the plane through the other side // point leaves the plane through the other side
if (std::abs(dotOne + dotTwo) < ai_epsilon) if (std::abs(dotOne + dotTwo) < ai_epsilon) {
return false; return false;
}
// if segment starts on the plane, report a hit only if the end lies on the *other* side // if segment starts on the plane, report a hit only if the end lies on the *other* side
if (std::abs(dotTwo) < ai_epsilon) { if (std::abs(dotTwo) < ai_epsilon) {
@ -82,13 +81,15 @@ bool IntersectSegmentPlane(const IfcVector3 &p, const IfcVector3 &n, const IfcVe
// ignore if segment is parallel to plane and far away from it on either side // ignore if segment is parallel to plane and far away from it on either side
// Warning: if there's a few thousand of such segments which slowly accumulate beyond the epsilon, no hit would be registered // Warning: if there's a few thousand of such segments which slowly accumulate beyond the epsilon, no hit would be registered
if (std::abs(dotOne) < ai_epsilon) if (std::abs(dotOne) < ai_epsilon) {
return false; return false;
}
// t must be in [0..1] if the intersection point is within the given segment // t must be in [0..1] if the intersection point is within the given segment
const IfcFloat t = dotTwo / dotOne; const IfcFloat t = dotTwo / dotOne;
if (t > 1.0 || t < 0.0) if (t > 1.0 || t < 0.0) {
return false; return false;
}
out = e0 + t * seg; out = e0 + t * seg;
return true; return true;
@ -110,11 +111,13 @@ void FilterPolygon(std::vector<IfcVector3> &resultpoly) {
FuzzyVectorCompare fz(epsilon); FuzzyVectorCompare fz(epsilon);
std::vector<IfcVector3>::iterator e = std::unique(resultpoly.begin(), resultpoly.end(), fz); std::vector<IfcVector3>::iterator e = std::unique(resultpoly.begin(), resultpoly.end(), fz);
if (e != resultpoly.end()) if (e != resultpoly.end()) {
resultpoly.erase(e, resultpoly.end()); resultpoly.erase(e, resultpoly.end());
}
if (!resultpoly.empty() && fz(resultpoly.front(), resultpoly.back())) if (!resultpoly.empty() && fz(resultpoly.front(), resultpoly.back())) {
resultpoly.pop_back(); resultpoly.pop_back();
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -291,8 +294,9 @@ bool IntersectsBoundaryProfile(const IfcVector3 &e0, const IfcVector3 &e1, const
} }
// Line segment ends at boundary -> ignore any hit, it will be handled by possibly following segments // Line segment ends at boundary -> ignore any hit, it will be handled by possibly following segments
if (endsAtSegment && !halfOpen) if (endsAtSegment && !halfOpen) {
continue; continue;
}
// Line segment starts at boundary -> generate a hit only if following that line would change the INSIDE/OUTSIDE // Line segment starts at boundary -> generate a hit only if following that line would change the INSIDE/OUTSIDE
// state. This should catch the case where a connected set of segments has a point directly on the boundary, // state. This should catch the case where a connected set of segments has a point directly on the boundary,
@ -301,16 +305,18 @@ bool IntersectsBoundaryProfile(const IfcVector3 &e0, const IfcVector3 &e1, const
if (startsAtSegment) { if (startsAtSegment) {
IfcVector3 inside_dir = IfcVector3(b.y, -b.x, 0.0) * windingOrder; IfcVector3 inside_dir = IfcVector3(b.y, -b.x, 0.0) * windingOrder;
bool isGoingInside = (inside_dir * e) > 0.0; bool isGoingInside = (inside_dir * e) > 0.0;
if (isGoingInside == isStartAssumedInside) if (isGoingInside == isStartAssumedInside) {
continue; continue;
}
// only insert the point into the list if it is sufficiently far away from the previous intersection point. // only insert the point into the list if it is sufficiently far away from the previous intersection point.
// This way, we avoid duplicate detection if the intersection is directly on the vertex between two segments. // This way, we avoid duplicate detection if the intersection is directly on the vertex between two segments.
if (!intersect_results.empty() && intersect_results.back().first == i - 1) { if (!intersect_results.empty() && intersect_results.back().first == i - 1) {
const IfcVector3 diff = intersect_results.back().second - e0; const IfcVector3 diff = intersect_results.back().second - e0;
if (IfcVector2(diff.x, diff.y).SquareLength() < 1e-10) if (IfcVector2(diff.x, diff.y).SquareLength() < 1e-10) {
continue; continue;
} }
}
intersect_results.emplace_back(i, e0); intersect_results.emplace_back(i, e0);
continue; continue;
} }
@ -322,9 +328,10 @@ bool IntersectsBoundaryProfile(const IfcVector3 &e0, const IfcVector3 &e1, const
// This way, we avoid duplicate detection if the intersection is directly on the vertex between two segments. // This way, we avoid duplicate detection if the intersection is directly on the vertex between two segments.
if (!intersect_results.empty() && intersect_results.back().first == i - 1) { if (!intersect_results.empty() && intersect_results.back().first == i - 1) {
const IfcVector3 diff = intersect_results.back().second - p; const IfcVector3 diff = intersect_results.back().second - p;
if (IfcVector2(diff.x, diff.y).SquareLength() < 1e-10) if (IfcVector2(diff.x, diff.y).SquareLength() < 1e-10) {
continue; continue;
} }
}
intersect_results.emplace_back(i, p); intersect_results.emplace_back(i, p);
} }
} }
@ -662,7 +669,8 @@ void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const Schema_2x3::IfcPoly
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessBooleanExtrudedAreaSolidDifference(const Schema_2x3::IfcExtrudedAreaSolid *as, TempMesh &result, void ProcessBooleanExtrudedAreaSolidDifference(const Schema_2x3::IfcExtrudedAreaSolid *as,
TempMesh &result,
const TempMesh &first_operand, const TempMesh &first_operand,
ConversionData &conv) { ConversionData &conv) {
ai_assert(as != nullptr); ai_assert(as != nullptr);
@ -763,4 +771,4 @@ void ProcessBoolean(const Schema_2x3::IfcBooleanResult &boolean, TempMesh &resul
} // namespace IFC } // namespace IFC
} // namespace Assimp } // namespace Assimp
#endif #endif // ASSIMP_BUILD_NO_IFC_IMPORTER

View File

@ -39,15 +39,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file IFCProfile.cpp /// @file IFCProfile.cpp
* @brief Read profile and curves entities from IFC files /// @brief Read profile and curves entities from IFC files
*/
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER #ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
#include "IFCUtil.h" #include "IFCUtil.h"
namespace Assimp { namespace Assimp {
namespace IFC { namespace IFC {
namespace { namespace {
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
@ -56,8 +56,7 @@ namespace {
class Conic : public Curve { class Conic : public Curve {
public: public:
// -------------------------------------------------- // --------------------------------------------------
Conic(const Schema_2x3::IfcConic& entity, ConversionData& conv) Conic(const Schema_2x3::IfcConic& entity, ConversionData& conv) : Curve(entity,conv) {
: Curve(entity,conv) {
IfcMatrix4 trafo; IfcMatrix4 trafo;
ConvertAxisPlacement(trafo,*entity.Position,conv); ConvertAxisPlacement(trafo,*entity.Position,conv);
@ -69,12 +68,12 @@ public:
} }
// -------------------------------------------------- // --------------------------------------------------
bool IsClosed() const { bool IsClosed() const override {
return true; return true;
} }
// -------------------------------------------------- // --------------------------------------------------
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const { size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const override {
ai_assert( InRange( a ) ); ai_assert( InRange( a ) );
ai_assert( InRange( b ) ); ai_assert( InRange( b ) );
@ -88,7 +87,7 @@ public:
} }
// -------------------------------------------------- // --------------------------------------------------
ParamRange GetParametricRange() const { ParamRange GetParametricRange() const override {
return std::make_pair(static_cast<IfcFloat>( 0. ), static_cast<IfcFloat>( AI_MATH_TWO_PI / conv.angle_scale )); return std::make_pair(static_cast<IfcFloat>( 0. ), static_cast<IfcFloat>( AI_MATH_TWO_PI / conv.angle_scale ));
} }
@ -102,14 +101,13 @@ protected:
class Circle : public Conic { class Circle : public Conic {
public: public:
// -------------------------------------------------- // --------------------------------------------------
Circle(const Schema_2x3::IfcCircle& entity, ConversionData& conv) Circle(const Schema_2x3::IfcCircle& entity, ConversionData& conv) : Conic(entity,conv) , entity(entity) {}
: Conic(entity,conv)
, entity(entity)
{
}
// -------------------------------------------------- // --------------------------------------------------
IfcVector3 Eval(IfcFloat u) const { ~Circle() override = default;
// --------------------------------------------------
IfcVector3 Eval(IfcFloat u) const override {
u = -conv.angle_scale * u; u = -conv.angle_scale * u;
return location + static_cast<IfcFloat>(entity.Radius)*(static_cast<IfcFloat>(std::cos(u))*p[0] + return location + static_cast<IfcFloat>(entity.Radius)*(static_cast<IfcFloat>(std::cos(u))*p[0] +
static_cast<IfcFloat>(std::sin(u))*p[1]); static_cast<IfcFloat>(std::sin(u))*p[1]);
@ -132,7 +130,7 @@ public:
} }
// -------------------------------------------------- // --------------------------------------------------
IfcVector3 Eval(IfcFloat u) const { IfcVector3 Eval(IfcFloat u) const override {
u = -conv.angle_scale * u; u = -conv.angle_scale * u;
return location + static_cast<IfcFloat>(entity.SemiAxis1)*static_cast<IfcFloat>(std::cos(u))*p[0] + return location + static_cast<IfcFloat>(entity.SemiAxis1)*static_cast<IfcFloat>(std::cos(u))*p[0] +
static_cast<IfcFloat>(entity.SemiAxis2)*static_cast<IfcFloat>(std::sin(u))*p[1]; static_cast<IfcFloat>(entity.SemiAxis2)*static_cast<IfcFloat>(std::sin(u))*p[1];
@ -155,17 +153,17 @@ public:
} }
// -------------------------------------------------- // --------------------------------------------------
bool IsClosed() const { bool IsClosed() const override {
return false; return false;
} }
// -------------------------------------------------- // --------------------------------------------------
IfcVector3 Eval(IfcFloat u) const { IfcVector3 Eval(IfcFloat u) const override {
return p + u*v; return p + u*v;
} }
// -------------------------------------------------- // --------------------------------------------------
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const { size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const override {
ai_assert( InRange( a ) ); ai_assert( InRange( a ) );
ai_assert( InRange( b ) ); ai_assert( InRange( b ) );
// two points are always sufficient for a line segment // two points are always sufficient for a line segment
@ -174,7 +172,7 @@ public:
// -------------------------------------------------- // --------------------------------------------------
void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const { void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const override {
ai_assert( InRange( a ) ); ai_assert( InRange( a ) );
ai_assert( InRange( b ) ); ai_assert( InRange( b ) );
@ -188,7 +186,7 @@ public:
} }
// -------------------------------------------------- // --------------------------------------------------
ParamRange GetParametricRange() const { ParamRange GetParametricRange() const override {
const IfcFloat inf = std::numeric_limits<IfcFloat>::infinity(); const IfcFloat inf = std::numeric_limits<IfcFloat>::infinity();
return std::make_pair(-inf,+inf); return std::make_pair(-inf,+inf);
@ -234,7 +232,7 @@ public:
} }
// -------------------------------------------------- // --------------------------------------------------
IfcVector3 Eval(IfcFloat u) const { IfcVector3 Eval(IfcFloat u) const override {
if (curves.empty()) { if (curves.empty()) {
return IfcVector3(); return IfcVector3();
} }
@ -254,7 +252,7 @@ public:
} }
// -------------------------------------------------- // --------------------------------------------------
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const { size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const override {
ai_assert( InRange( a ) ); ai_assert( InRange( a ) );
ai_assert( InRange( b ) ); ai_assert( InRange( b ) );
size_t cnt = 0; size_t cnt = 0;
@ -275,7 +273,7 @@ public:
} }
// -------------------------------------------------- // --------------------------------------------------
void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const { void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const override {
ai_assert( InRange( a ) ); ai_assert( InRange( a ) );
ai_assert( InRange( b ) ); ai_assert( InRange( b ) );
@ -293,7 +291,7 @@ public:
} }
// -------------------------------------------------- // --------------------------------------------------
ParamRange GetParametricRange() const { ParamRange GetParametricRange() const override {
return std::make_pair(static_cast<IfcFloat>( 0. ),total); return std::make_pair(static_cast<IfcFloat>( 0. ),total);
} }
@ -373,27 +371,27 @@ public:
} }
// -------------------------------------------------- // --------------------------------------------------
IfcVector3 Eval(IfcFloat p) const { IfcVector3 Eval(IfcFloat p) const override {
ai_assert(InRange(p)); ai_assert(InRange(p));
return base->Eval( TrimParam(p) ); return base->Eval( TrimParam(p) );
} }
// -------------------------------------------------- // --------------------------------------------------
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const { size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const override {
ai_assert( InRange( a ) ); ai_assert( InRange( a ) );
ai_assert( InRange( b ) ); ai_assert( InRange( b ) );
return base->EstimateSampleCount(TrimParam(a),TrimParam(b)); return base->EstimateSampleCount(TrimParam(a),TrimParam(b));
} }
// -------------------------------------------------- // --------------------------------------------------
void SampleDiscrete(TempMesh& out,IfcFloat a,IfcFloat b) const { void SampleDiscrete(TempMesh& out,IfcFloat a,IfcFloat b) const override {
ai_assert(InRange(a)); ai_assert(InRange(a));
ai_assert(InRange(b)); ai_assert(InRange(b));
return base->SampleDiscrete(out,TrimParam(a),TrimParam(b)); return base->SampleDiscrete(out,TrimParam(a),TrimParam(b));
} }
// -------------------------------------------------- // --------------------------------------------------
ParamRange GetParametricRange() const { ParamRange GetParametricRange() const override {
return std::make_pair(static_cast<IfcFloat>( 0. ),maxval); return std::make_pair(static_cast<IfcFloat>( 0. ),maxval);
} }
@ -431,7 +429,7 @@ public:
} }
// -------------------------------------------------- // --------------------------------------------------
IfcVector3 Eval(IfcFloat p) const { IfcVector3 Eval(IfcFloat p) const override {
ai_assert(InRange(p)); ai_assert(InRange(p));
const size_t b = static_cast<size_t>(std::floor(p)); const size_t b = static_cast<size_t>(std::floor(p));
@ -444,14 +442,14 @@ public:
} }
// -------------------------------------------------- // --------------------------------------------------
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const { size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const override {
ai_assert(InRange(a)); ai_assert(InRange(a));
ai_assert(InRange(b)); ai_assert(InRange(b));
return static_cast<size_t>( std::ceil(b) - std::floor(a) ); return static_cast<size_t>( std::ceil(b) - std::floor(a) );
} }
// -------------------------------------------------- // --------------------------------------------------
ParamRange GetParametricRange() const { ParamRange GetParametricRange() const override {
return std::make_pair(static_cast<IfcFloat>( 0. ),static_cast<IfcFloat>(points.size()-1)); return std::make_pair(static_cast<IfcFloat>( 0. ),static_cast<IfcFloat>(points.size()-1));
} }
@ -516,7 +514,7 @@ size_t Curve::EstimateSampleCount(IfcFloat a, IfcFloat b) const {
ai_assert( InRange( a ) ); ai_assert( InRange( a ) );
ai_assert( InRange( b ) ); ai_assert( InRange( b ) );
// arbitrary default value, deriving classes should supply better suited values // arbitrary default value, deriving classes should supply better-suited values
return 16; return 16;
} }

View File

@ -38,24 +38,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file IFCGeometry.cpp /// @file IFCGeometry.cpp
* @brief Geometry conversion and synthesis for IFC /// @brief Geometry conversion and synthesis for IFC
*/
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER #ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
#include "IFCUtil.h" #include "IFCUtil.h"
#include "Common/PolyTools.h" #include "Common/PolyTools.h"
#include "PostProcessing/ProcessHelper.h" #include "PostProcessing/ProcessHelper.h"
#include "contrib/poly2tri/poly2tri/poly2tri.h"
#ifdef ASSIMP_USE_HUNTER #include "contrib/clipper/clipper.hpp"
# include <poly2tri/poly2tri.h>
# include <polyclipping/clipper.hpp>
#else
# include "../contrib/poly2tri/poly2tri/poly2tri.h"
# include "../contrib/clipper/clipper.hpp"
#endif
#include <iterator> #include <iterator>
#include <memory> #include <memory>
@ -65,8 +56,7 @@ namespace Assimp {
namespace IFC { namespace IFC {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool ProcessPolyloop(const Schema_2x3::IfcPolyLoop& loop, TempMesh& meshout, ConversionData& /*conv*/) bool ProcessPolyloop(const Schema_2x3::IfcPolyLoop& loop, TempMesh& meshout, ConversionData& /*conv*/) {
{
size_t cnt = 0; size_t cnt = 0;
for(const Schema_2x3::IfcCartesianPoint& c : loop.Polygon) { for(const Schema_2x3::IfcCartesianPoint& c : loop.Polygon) {
IfcVector3 tmp; IfcVector3 tmp;
@ -91,8 +81,7 @@ bool ProcessPolyloop(const Schema_2x3::IfcPolyLoop& loop, TempMesh& meshout, Con
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t master_bounds = (size_t)-1) void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t master_bounds = (size_t)-1) {
{
// handle all trivial cases // handle all trivial cases
if(inmesh.mVertcnt.empty()) { if(inmesh.mVertcnt.empty()) {
return; return;
@ -127,8 +116,7 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m
if (master_bounds != (size_t)-1) { if (master_bounds != (size_t)-1) {
ai_assert(master_bounds < inmesh.mVertcnt.size()); ai_assert(master_bounds < inmesh.mVertcnt.size());
outer_polygon_it = begin + master_bounds; outer_polygon_it = begin + master_bounds;
} } else {
else {
for(iit = begin; iit != end; ++iit) { for(iit = begin; iit != end; ++iit) {
// find the polygon with the largest area and take it as the outer bound. // find the polygon with the largest area and take it as the outer bound.
IfcVector3& n = normals[std::distance(begin,iit)]; IfcVector3& n = normals[std::distance(begin,iit)];
@ -139,6 +127,7 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m
} }
} }
} }
if (outer_polygon_it == end) { if (outer_polygon_it == end) {
return; return;
} }
@ -205,40 +194,20 @@ void ProcessConnectedFaceSet(const Schema_2x3::IfcConnectedFaceSet& fset, TempMe
if(const Schema_2x3::IfcPolyLoop* const polyloop = bound.Bound->ToPtr<Schema_2x3::IfcPolyLoop>()) { if(const Schema_2x3::IfcPolyLoop* const polyloop = bound.Bound->ToPtr<Schema_2x3::IfcPolyLoop>()) {
if(ProcessPolyloop(*polyloop, meshout,conv)) { if(ProcessPolyloop(*polyloop, meshout,conv)) {
// The outer boundary is better determined by checking which // The outer boundary is better determined by checking which
// polygon covers the largest area. // polygon covers the largest area.
//if(bound.ToPtr<IfcFaceOuterBound>()) {
// ob = cnt;
//}
//++cnt;
} }
} } else {
else {
IFCImporter::LogWarn("skipping unknown IfcFaceBound entity, type is ", bound.Bound->GetClassName()); IFCImporter::LogWarn("skipping unknown IfcFaceBound entity, type is ", bound.Bound->GetClassName());
continue; continue;
} }
// And this, even though it is sometimes TRUE and sometimes FALSE,
// does not really improve results.
/*if(!IsTrue(bound.Orientation)) {
size_t c = 0;
for(unsigned int& c : meshout.vertcnt) {
std::reverse(result.verts.begin() + cnt,result.verts.begin() + cnt + c);
cnt += c;
}
}*/
} }
ProcessPolygonBoundaries(result, meshout); ProcessPolygonBoundaries(result, meshout);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessRevolvedAreaSolid(const Schema_2x3::IfcRevolvedAreaSolid& solid, TempMesh& result, ConversionData& conv) void ProcessRevolvedAreaSolid(const Schema_2x3::IfcRevolvedAreaSolid& solid, TempMesh& result, ConversionData& conv) {
{
TempMesh meshout; TempMesh meshout;
// first read the profile description // first read the profile description
@ -265,7 +234,8 @@ void ProcessRevolvedAreaSolid(const Schema_2x3::IfcRevolvedAreaSolid& solid, Tem
return; return;
} }
const unsigned int cnt_segments = std::max(2u,static_cast<unsigned int>(conv.settings.cylindricalTessellation * std::fabs(max_angle)/AI_MATH_HALF_PI_F)); const unsigned int cnt_segments =
std::max(2u,static_cast<unsigned int>(conv.settings.cylindricalTessellation * std::fabs(max_angle)/AI_MATH_HALF_PI_F));
const IfcFloat delta = max_angle/cnt_segments; const IfcFloat delta = max_angle/cnt_segments;
has_area = has_area && std::fabs(max_angle) < AI_MATH_TWO_PI_F*0.99; has_area = has_area && std::fabs(max_angle) < AI_MATH_TWO_PI_F*0.99;
@ -324,8 +294,9 @@ void ProcessRevolvedAreaSolid(const Schema_2x3::IfcRevolvedAreaSolid& solid, Tem
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid &solid, TempMesh& result, ConversionData& conv) void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid &solid,
{ TempMesh& result,
ConversionData& conv) {
const Curve* const curve = Curve::Convert(*solid.Directrix, conv); const Curve* const curve = Curve::Convert(*solid.Directrix, conv);
if(!curve) { if(!curve) {
IFCImporter::LogError("failed to convert Directrix curve (IfcSweptDiskSolid)"); IFCImporter::LogError("failed to convert Directrix curve (IfcSweptDiskSolid)");
@ -460,8 +431,7 @@ void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid &solid, TempMesh&
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVector3& norOut) IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVector3& norOut) {
{
const std::vector<IfcVector3>& out = curmesh.mVerts; const std::vector<IfcVector3>& out = curmesh.mVerts;
IfcMatrix3 m; IfcMatrix3 m;
@ -504,10 +474,6 @@ IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVect
IfcVector3 r = (out[idx]-any_point); IfcVector3 r = (out[idx]-any_point);
r.Normalize(); r.Normalize();
//if(d) {
// *d = -any_point * nor;
//}
// Reconstruct orthonormal basis // Reconstruct orthonormal basis
// XXX use Gram Schmidt for increased robustness // XXX use Gram Schmidt for increased robustness
IfcVector3 u = r ^ nor; IfcVector3 u = r ^ nor;
@ -531,8 +497,7 @@ IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVect
const auto closeDistance = ai_epsilon; const auto closeDistance = ai_epsilon;
bool areClose(Schema_2x3::IfcCartesianPoint pt1,Schema_2x3::IfcCartesianPoint pt2) { bool areClose(Schema_2x3::IfcCartesianPoint pt1,Schema_2x3::IfcCartesianPoint pt2) {
if(pt1.Coordinates.size() != pt2.Coordinates.size()) if(pt1.Coordinates.size() != pt2.Coordinates.size()) {
{
IFCImporter::LogWarn("unable to compare differently-dimensioned points"); IFCImporter::LogWarn("unable to compare differently-dimensioned points");
return false; return false;
} }
@ -540,11 +505,11 @@ bool areClose(Schema_2x3::IfcCartesianPoint pt1,Schema_2x3::IfcCartesianPoint pt
auto coord2 = pt2.Coordinates.begin(); auto coord2 = pt2.Coordinates.begin();
// we're just testing each dimension separately rather than doing euclidean distance, as we're // we're just testing each dimension separately rather than doing euclidean distance, as we're
// looking for very close coordinates // looking for very close coordinates
for(; coord1 != pt1.Coordinates.end(); coord1++,coord2++) for(; coord1 != pt1.Coordinates.end(); coord1++,coord2++) {
{ if(std::fabs(*coord1 - *coord2) > closeDistance) {
if(std::fabs(*coord1 - *coord2) > closeDistance)
return false; return false;
} }
}
return true; return true;
} }
@ -553,6 +518,7 @@ bool areClose(IfcVector3 pt1,IfcVector3 pt2) {
std::fabs(pt1.y - pt2.y) < closeDistance && std::fabs(pt1.y - pt2.y) < closeDistance &&
std::fabs(pt1.z - pt2.z) < closeDistance); std::fabs(pt1.z - pt2.z) < closeDistance);
} }
// Extrudes the given polygon along the direction, converts it into an opening or applies all openings as necessary. // Extrudes the given polygon along the direction, converts it into an opening or applies all openings as necessary.
void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const TempMesh& curve, void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const TempMesh& curve,
const IfcVector3& extrusionDir, TempMesh& result, ConversionData &conv, bool collect_openings) const IfcVector3& extrusionDir, TempMesh& result, ConversionData &conv, bool collect_openings)
@ -590,8 +556,9 @@ void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const Te
// 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();
@ -678,8 +645,7 @@ void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const Te
if(n > 0) { if(n > 0) {
for(size_t i = 0; i < in.size(); ++i) for(size_t i = 0; i < in.size(); ++i)
out.push_back(in[i] + dir); out.push_back(in[i] + dir);
} } else {
else {
for(size_t i = in.size(); i--; ) for(size_t i = in.size(); i--; )
out.push_back(in[i]); out.push_back(in[i]);
} }
@ -721,9 +687,10 @@ void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const Te
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessExtrudedAreaSolid(const Schema_2x3::IfcExtrudedAreaSolid& solid, TempMesh& result, void ProcessExtrudedAreaSolid(const Schema_2x3::IfcExtrudedAreaSolid& solid,
ConversionData& conv, bool collect_openings) TempMesh& result,
{ ConversionData& conv,
bool collect_openings) {
TempMesh meshout; TempMesh meshout;
// First read the profile description. // First read the profile description.
@ -761,24 +728,23 @@ void ProcessExtrudedAreaSolid(const Schema_2x3::IfcExtrudedAreaSolid& solid, Tem
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessSweptAreaSolid(const Schema_2x3::IfcSweptAreaSolid& swept, TempMesh& meshout, void ProcessSweptAreaSolid(const Schema_2x3::IfcSweptAreaSolid& swept,
ConversionData& conv) TempMesh& meshout,
{ ConversionData& conv) {
if(const Schema_2x3::IfcExtrudedAreaSolid* const solid = swept.ToPtr<Schema_2x3::IfcExtrudedAreaSolid>()) { if(const Schema_2x3::IfcExtrudedAreaSolid* const solid = swept.ToPtr<Schema_2x3::IfcExtrudedAreaSolid>()) {
ProcessExtrudedAreaSolid(*solid,meshout,conv, !!conv.collect_openings); ProcessExtrudedAreaSolid(*solid,meshout,conv, !!conv.collect_openings);
} } else if(const Schema_2x3::IfcRevolvedAreaSolid* const rev = swept.ToPtr<Schema_2x3::IfcRevolvedAreaSolid>()) {
else if(const Schema_2x3::IfcRevolvedAreaSolid* const rev = swept.ToPtr<Schema_2x3::IfcRevolvedAreaSolid>()) {
ProcessRevolvedAreaSolid(*rev,meshout,conv); ProcessRevolvedAreaSolid(*rev,meshout,conv);
} } else {
else {
IFCImporter::LogWarn("skipping unknown IfcSweptAreaSolid entity, type is ", swept.GetClassName()); IFCImporter::LogWarn("skipping unknown IfcSweptAreaSolid entity, type is ", swept.GetClassName());
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo, unsigned int matid, std::set<unsigned int>& mesh_indices, bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo,
ConversionData& conv) unsigned int matid,
{ std::set<unsigned int>& mesh_indices,
ConversionData& conv) {
bool fix_orientation = false; bool fix_orientation = false;
std::shared_ptr< TempMesh > meshtmp = std::make_shared<TempMesh>(); std::shared_ptr< TempMesh > meshtmp = std::make_shared<TempMesh>();
if(const Schema_2x3::IfcShellBasedSurfaceModel* shellmod = geo.ToPtr<Schema_2x3::IfcShellBasedSurfaceModel>()) { if(const Schema_2x3::IfcShellBasedSurfaceModel* shellmod = geo.ToPtr<Schema_2x3::IfcShellBasedSurfaceModel>()) {
@ -788,41 +754,32 @@ bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo, unsigned
const Schema_2x3::IfcConnectedFaceSet& fs = conv.db.MustGetObject(e).To<Schema_2x3::IfcConnectedFaceSet>(); const Schema_2x3::IfcConnectedFaceSet& fs = conv.db.MustGetObject(e).To<Schema_2x3::IfcConnectedFaceSet>();
ProcessConnectedFaceSet(fs, *meshtmp, conv); ProcessConnectedFaceSet(fs, *meshtmp, conv);
} } catch(std::bad_cast&) {
catch(std::bad_cast&) {
IFCImporter::LogWarn("unexpected type error, IfcShell ought to inherit from IfcConnectedFaceSet"); IFCImporter::LogWarn("unexpected type error, IfcShell ought to inherit from IfcConnectedFaceSet");
} }
} }
fix_orientation = true; fix_orientation = true;
} } else if(const Schema_2x3::IfcConnectedFaceSet* fset = geo.ToPtr<Schema_2x3::IfcConnectedFaceSet>()) {
else if(const Schema_2x3::IfcConnectedFaceSet* fset = geo.ToPtr<Schema_2x3::IfcConnectedFaceSet>()) {
ProcessConnectedFaceSet(*fset, *meshtmp, conv); ProcessConnectedFaceSet(*fset, *meshtmp, conv);
fix_orientation = true; fix_orientation = true;
} } else if(const Schema_2x3::IfcSweptAreaSolid* swept = geo.ToPtr<Schema_2x3::IfcSweptAreaSolid>()) {
else if(const Schema_2x3::IfcSweptAreaSolid* swept = geo.ToPtr<Schema_2x3::IfcSweptAreaSolid>()) {
ProcessSweptAreaSolid(*swept, *meshtmp, conv); ProcessSweptAreaSolid(*swept, *meshtmp, conv);
} } else if(const Schema_2x3::IfcSweptDiskSolid* disk = geo.ToPtr<Schema_2x3::IfcSweptDiskSolid>()) {
else if(const Schema_2x3::IfcSweptDiskSolid* disk = geo.ToPtr<Schema_2x3::IfcSweptDiskSolid>()) {
ProcessSweptDiskSolid(*disk, *meshtmp, conv); ProcessSweptDiskSolid(*disk, *meshtmp, conv);
} } else if(const Schema_2x3::IfcManifoldSolidBrep* brep = geo.ToPtr<Schema_2x3::IfcManifoldSolidBrep>()) {
else if(const Schema_2x3::IfcManifoldSolidBrep* brep = geo.ToPtr<Schema_2x3::IfcManifoldSolidBrep>()) {
ProcessConnectedFaceSet(brep->Outer, *meshtmp, conv); ProcessConnectedFaceSet(brep->Outer, *meshtmp, conv);
fix_orientation = true; fix_orientation = true;
} } else if(const Schema_2x3::IfcFaceBasedSurfaceModel* surf = geo.ToPtr<Schema_2x3::IfcFaceBasedSurfaceModel>()) {
else if(const Schema_2x3::IfcFaceBasedSurfaceModel* surf = geo.ToPtr<Schema_2x3::IfcFaceBasedSurfaceModel>()) {
for(const Schema_2x3::IfcConnectedFaceSet& fc : surf->FbsmFaces) { for(const Schema_2x3::IfcConnectedFaceSet& fc : surf->FbsmFaces) {
ProcessConnectedFaceSet(fc, *meshtmp, conv); ProcessConnectedFaceSet(fc, *meshtmp, conv);
} }
fix_orientation = true; fix_orientation = true;
} } else if(const Schema_2x3::IfcBooleanResult* boolean = geo.ToPtr<Schema_2x3::IfcBooleanResult>()) {
else if(const Schema_2x3::IfcBooleanResult* boolean = geo.ToPtr<Schema_2x3::IfcBooleanResult>()) {
ProcessBoolean(*boolean, *meshtmp, conv); ProcessBoolean(*boolean, *meshtmp, conv);
} } else if(geo.ToPtr<Schema_2x3::IfcBoundingBox>()) {
else if(geo.ToPtr<Schema_2x3::IfcBoundingBox>()) {
// silently skip over bounding boxes // silently skip over bounding boxes
return false; return false;
} } else {
else {
std::stringstream toLog; std::stringstream toLog;
toLog << "skipping unknown IfcGeometricRepresentationItem entity, type is " << geo.GetClassName() << " id is " << geo.GetID(); toLog << "skipping unknown IfcGeometricRepresentationItem entity, type is " << geo.GetClassName() << " id is " << geo.GetID();
IFCImporter::LogWarn(toLog.str().c_str()); IFCImporter::LogWarn(toLog.str().c_str());
@ -868,9 +825,7 @@ bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo, unsigned
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void AssignAddedMeshes(std::set<unsigned int>& mesh_indices,aiNode* nd, void AssignAddedMeshes(std::set<unsigned int>& mesh_indices,aiNode* nd, ConversionData& /*conv*/) {
ConversionData& /*conv*/)
{
if (!mesh_indices.empty()) { if (!mesh_indices.empty()) {
std::set<unsigned int>::const_iterator it = mesh_indices.cbegin(); std::set<unsigned int>::const_iterator it = mesh_indices.cbegin();
std::set<unsigned int>::const_iterator end = mesh_indices.cend(); std::set<unsigned int>::const_iterator end = mesh_indices.cend();
@ -886,9 +841,9 @@ void AssignAddedMeshes(std::set<unsigned int>& mesh_indices,aiNode* nd,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool TryQueryMeshCache(const Schema_2x3::IfcRepresentationItem& item, bool TryQueryMeshCache(const Schema_2x3::IfcRepresentationItem& item,
std::set<unsigned int>& mesh_indices, unsigned int mat_index, std::set<unsigned int>& mesh_indices,
ConversionData& conv) unsigned int mat_index,
{ ConversionData& conv) {
ConversionData::MeshCacheIndex idx(&item, mat_index); ConversionData::MeshCacheIndex idx(&item, mat_index);
ConversionData::MeshCache::const_iterator it = conv.cached_meshes.find(idx); ConversionData::MeshCache::const_iterator it = conv.cached_meshes.find(idx);
if (it != conv.cached_meshes.end()) { if (it != conv.cached_meshes.end()) {
@ -900,18 +855,18 @@ bool TryQueryMeshCache(const Schema_2x3::IfcRepresentationItem& item,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void PopulateMeshCache(const Schema_2x3::IfcRepresentationItem& item, void PopulateMeshCache(const Schema_2x3::IfcRepresentationItem& item,
const std::set<unsigned int>& mesh_indices, unsigned int mat_index, const std::set<unsigned int>& mesh_indices,
ConversionData& conv) unsigned int mat_index,
{ ConversionData& conv) {
ConversionData::MeshCacheIndex idx(&item, mat_index); ConversionData::MeshCacheIndex idx(&item, mat_index);
conv.cached_meshes[idx] = mesh_indices; conv.cached_meshes[idx] = mesh_indices;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool ProcessRepresentationItem(const Schema_2x3::IfcRepresentationItem& item, unsigned int matid, bool ProcessRepresentationItem(const Schema_2x3::IfcRepresentationItem& item,
unsigned int matid,
std::set<unsigned int>& mesh_indices, std::set<unsigned int>& mesh_indices,
ConversionData& conv) ConversionData& conv) {
{
// determine material // determine material
unsigned int localmatid = ProcessMaterials(item.GetID(), matid, conv, true); unsigned int localmatid = ProcessMaterials(item.GetID(), matid, conv, true);
@ -920,8 +875,9 @@ bool ProcessRepresentationItem(const Schema_2x3::IfcRepresentationItem& item, un
if(mesh_indices.size()) { if(mesh_indices.size()) {
PopulateMeshCache(item,mesh_indices,localmatid,conv); PopulateMeshCache(item,mesh_indices,localmatid,conv);
} }
} else {
return false;
} }
else return false;
} }
return true; return true;
} }
@ -930,4 +886,4 @@ bool ProcessRepresentationItem(const Schema_2x3::IfcRepresentationItem& item, un
} // ! IFC } // ! IFC
} // ! Assimp } // ! Assimp
#endif #endif // ASSIMP_BUILD_NO_IFC_IMPORTER

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -40,9 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file IFCLoad.cpp /// @file IFCLoad.cpp
* @brief Implementation of the Industry Foundation Classes loader. /// @brief Implementation of the Industry Foundation Classes loader.
*/
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER #ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
@ -92,7 +90,6 @@ using namespace Assimp::IFC;
IfcUnitAssignment IfcUnitAssignment
IfcClosedShell IfcClosedShell
IfcDoor IfcDoor
*/ */
namespace { namespace {
@ -119,14 +116,6 @@ static const aiImporterDesc desc = {
"ifc ifczip step stp" "ifc ifczip step stp"
}; };
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
IFCImporter::IFCImporter() = default;
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
IFCImporter::~IFCImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool IFCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { bool IFCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
@ -256,7 +245,12 @@ void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// tell the reader for which types we need to simulate STEPs reverse indices // tell the reader for which types we need to simulate STEPs reverse indices
static const char *const inverse_indices_to_track[] = { static const char *const inverse_indices_to_track[] = {
"ifcrelcontainedinspatialstructure", "ifcrelaggregates", "ifcrelvoidselement", "ifcreldefinesbyproperties", "ifcpropertyset", "ifcstyleditem" "ifcrelcontainedinspatialstructure",
"ifcrelaggregates",
"ifcrelvoidselement",
"ifcreldefinesbyproperties",
"ifcpropertyset",
"ifcstyleditem"
}; };
// feed the IFC schema into the reader and pre-parse all lines // feed the IFC schema into the reader and pre-parse all lines
@ -928,4 +922,4 @@ void MakeTreeRelative(ConversionData &conv) {
} // namespace } // namespace
#endif #endif // ASSIMP_BUILD_NO_IFC_IMPORTER

View File

@ -87,8 +87,8 @@ public:
int cylindricalTessellation; int cylindricalTessellation;
}; };
IFCImporter(); IFCImporter() = default;
~IFCImporter() override; ~IFCImporter() override = default;
// -------------------- // --------------------
bool CanRead(const std::string &pFile, bool CanRead(const std::string &pFile,

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -40,9 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file IFCMaterial.cpp /// @file IFCMaterial.cpp
* @brief Implementation of conversion routines to convert IFC materials to aiMaterial /// @brief Implementation of conversion routines to convert IFC materials to aiMaterial
*/
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER #ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
@ -174,7 +172,6 @@ unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionDat
aiString name; aiString name;
name.Set("<IFCDefault>"); name.Set("<IFCDefault>");
// ConvertColorToString( color, name);
// look if there's already a default material with this base color // look if there's already a default material with this base color
for( size_t a = 0; a < conv.materials.size(); ++a ) { for( size_t a = 0; a < conv.materials.size(); ++a ) {

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -40,9 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file IFCProfile.cpp /// @file IFCProfile.cpp
* @brief Read profile and curves entities from IFC files /// @brief Read profile and curves entities from IFC files
*/
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER #ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
@ -52,8 +50,9 @@ namespace Assimp {
namespace IFC { namespace IFC {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessPolyLine(const Schema_2x3::IfcPolyline& def, TempMesh& meshout, ConversionData& /*conv*/) void ProcessPolyLine(const Schema_2x3::IfcPolyline& def,
{ TempMesh& meshout,
ConversionData& /*conv*/) {
// this won't produce a valid mesh, it just spits out a list of vertices // this won't produce a valid mesh, it just spits out a list of vertices
IfcVector3 t; IfcVector3 t;
for(const Schema_2x3::IfcCartesianPoint& cp : def.Points) { for(const Schema_2x3::IfcCartesianPoint& cp : def.Points) {
@ -64,8 +63,9 @@ void ProcessPolyLine(const Schema_2x3::IfcPolyline& def, TempMesh& meshout, Conv
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool ProcessCurve(const Schema_2x3::IfcCurve& curve, TempMesh& meshout, ConversionData& conv) bool ProcessCurve(const Schema_2x3::IfcCurve& curve,
{ TempMesh& meshout,
ConversionData& conv) {
std::unique_ptr<const Curve> cv(Curve::Convert(curve,conv)); std::unique_ptr<const Curve> cv(Curve::Convert(curve,conv));
if (!cv) { if (!cv) {
IFCImporter::LogWarn("skipping unknown IfcCurve entity, type is ", curve.GetClassName()); IFCImporter::LogWarn("skipping unknown IfcCurve entity, type is ", curve.GetClassName());
@ -90,20 +90,23 @@ bool ProcessCurve(const Schema_2x3::IfcCurve& curve, TempMesh& meshout, Convers
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessClosedProfile(const Schema_2x3::IfcArbitraryClosedProfileDef& def, TempMesh& meshout, ConversionData& conv) void ProcessClosedProfile(const Schema_2x3::IfcArbitraryClosedProfileDef& def,
{ TempMesh& meshout,
ConversionData& conv) {
ProcessCurve(def.OuterCurve,meshout,conv); ProcessCurve(def.OuterCurve,meshout,conv);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessOpenProfile(const Schema_2x3::IfcArbitraryOpenProfileDef& def, TempMesh& meshout, ConversionData& conv) void ProcessOpenProfile(const Schema_2x3::IfcArbitraryOpenProfileDef& def,
{ TempMesh& meshout,
ConversionData& conv) {
ProcessCurve(def.Curve,meshout,conv); ProcessCurve(def.Curve,meshout,conv);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& def, TempMesh& meshout, ConversionData& conv) void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& def,
{ TempMesh& meshout,
ConversionData& conv) {
if(const Schema_2x3::IfcRectangleProfileDef* const cprofile = def.ToPtr<Schema_2x3::IfcRectangleProfileDef>()) { if(const Schema_2x3::IfcRectangleProfileDef* const cprofile = def.ToPtr<Schema_2x3::IfcRectangleProfileDef>()) {
const IfcFloat x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f; const IfcFloat x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f;
@ -113,8 +116,7 @@ void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& de
meshout.mVerts.emplace_back(-x,-y, 0.f ); meshout.mVerts.emplace_back(-x,-y, 0.f );
meshout.mVerts.emplace_back( x,-y, 0.f ); meshout.mVerts.emplace_back( x,-y, 0.f );
meshout.mVertcnt.push_back(4); meshout.mVertcnt.push_back(4);
} } else if( const Schema_2x3::IfcCircleProfileDef* const circle = def.ToPtr<Schema_2x3::IfcCircleProfileDef>()) {
else if( const Schema_2x3::IfcCircleProfileDef* const circle = def.ToPtr<Schema_2x3::IfcCircleProfileDef>()) {
if(def.ToPtr<Schema_2x3::IfcCircleHollowProfileDef>()) { if(def.ToPtr<Schema_2x3::IfcCircleHollowProfileDef>()) {
// TODO // TODO
} }
@ -129,8 +131,7 @@ void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& de
} }
meshout.mVertcnt.push_back(static_cast<unsigned int>(segments)); meshout.mVertcnt.push_back(static_cast<unsigned int>(segments));
} } else if( const Schema_2x3::IfcIShapeProfileDef* const ishape = def.ToPtr<Schema_2x3::IfcIShapeProfileDef>()) {
else if( const Schema_2x3::IfcIShapeProfileDef* const ishape = def.ToPtr<Schema_2x3::IfcIShapeProfileDef>()) {
// construct simplified IBeam shape // construct simplified IBeam shape
const IfcFloat offset = (ishape->OverallWidth - ishape->WebThickness) / 2; const IfcFloat offset = (ishape->OverallWidth - ishape->WebThickness) / 2;
const IfcFloat inner_height = ishape->OverallDepth - ishape->FlangeThickness * 2; const IfcFloat inner_height = ishape->OverallDepth - ishape->FlangeThickness * 2;
@ -150,8 +151,7 @@ void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& de
meshout.mVerts.emplace_back(ishape->OverallWidth,0,0); meshout.mVerts.emplace_back(ishape->OverallWidth,0,0);
meshout.mVertcnt.push_back(12); meshout.mVertcnt.push_back(12);
} } else {
else {
IFCImporter::LogWarn("skipping unknown IfcParameterizedProfileDef entity, type is ", def.GetClassName()); IFCImporter::LogWarn("skipping unknown IfcParameterizedProfileDef entity, type is ", def.GetClassName());
return; return;
} }
@ -162,18 +162,14 @@ void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& de
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool ProcessProfile(const Schema_2x3::IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv) bool ProcessProfile(const Schema_2x3::IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv) {
{
if(const Schema_2x3::IfcArbitraryClosedProfileDef* const cprofile = prof.ToPtr<Schema_2x3::IfcArbitraryClosedProfileDef>()) { if(const Schema_2x3::IfcArbitraryClosedProfileDef* const cprofile = prof.ToPtr<Schema_2x3::IfcArbitraryClosedProfileDef>()) {
ProcessClosedProfile(*cprofile,meshout,conv); ProcessClosedProfile(*cprofile,meshout,conv);
} } else if(const Schema_2x3::IfcArbitraryOpenProfileDef* const copen = prof.ToPtr<Schema_2x3::IfcArbitraryOpenProfileDef>()) {
else if(const Schema_2x3::IfcArbitraryOpenProfileDef* const copen = prof.ToPtr<Schema_2x3::IfcArbitraryOpenProfileDef>()) {
ProcessOpenProfile(*copen,meshout,conv); ProcessOpenProfile(*copen,meshout,conv);
} } else if(const Schema_2x3::IfcParameterizedProfileDef* const cparam = prof.ToPtr<Schema_2x3::IfcParameterizedProfileDef>()) {
else if(const Schema_2x3::IfcParameterizedProfileDef* const cparam = prof.ToPtr<Schema_2x3::IfcParameterizedProfileDef>()) {
ProcessParametrizedProfile(*cparam,meshout,conv); ProcessParametrizedProfile(*cparam,meshout,conv);
} } else {
else {
IFCImporter::LogWarn("skipping unknown IfcProfileDef entity, type is ", prof.GetClassName()); IFCImporter::LogWarn("skipping unknown IfcProfileDef entity, type is ", prof.GetClassName());
return false; return false;
} }

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -40,9 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file IFCUtil.cpp /// @file IFCUtil.cpp
* @brief Implementation of conversion routines for some common Ifc helper entities. /// @brief Implementation of conversion routines for some common Ifc helper entities.
*/
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER #ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
@ -66,8 +64,7 @@ void TempOpening::Transform(const IfcMatrix4& mat) {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiMesh* TempMesh::ToMesh() aiMesh* TempMesh::ToMesh() {
{
ai_assert(mVerts.size() == std::accumulate(mVertcnt.begin(),mVertcnt.end(),size_t(0))); ai_assert(mVerts.size() == std::accumulate(mVertcnt.begin(),mVertcnt.end(),size_t(0)));
if (mVerts.empty()) { if (mVerts.empty()) {
@ -105,36 +102,31 @@ aiMesh* TempMesh::ToMesh()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void TempMesh::Clear() void TempMesh::Clear() {
{
mVerts.clear(); mVerts.clear();
mVertcnt.clear(); mVertcnt.clear();
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void TempMesh::Transform(const IfcMatrix4& mat) void TempMesh::Transform(const IfcMatrix4& mat) {
{
for(IfcVector3& v : mVerts) { for(IfcVector3& v : mVerts) {
v *= mat; v *= mat;
} }
} }
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
IfcVector3 TempMesh::Center() const IfcVector3 TempMesh::Center() const {
{ return mVerts.empty() ? IfcVector3(0.0f, 0.0f, 0.0f) : (std::accumulate(mVerts.begin(),mVerts.end(),IfcVector3()) / static_cast<IfcFloat>(mVerts.size()));
return (mVerts.size() == 0) ? IfcVector3(0.0f, 0.0f, 0.0f) : (std::accumulate(mVerts.begin(),mVerts.end(),IfcVector3()) / static_cast<IfcFloat>(mVerts.size()));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void TempMesh::Append(const TempMesh& other) void TempMesh::Append(const TempMesh& other) {
{
mVerts.insert(mVerts.end(),other.mVerts.begin(),other.mVerts.end()); mVerts.insert(mVerts.end(),other.mVerts.begin(),other.mVerts.end());
mVertcnt.insert(mVertcnt.end(),other.mVertcnt.begin(),other.mVertcnt.end()); mVertcnt.insert(mVertcnt.end(),other.mVertcnt.begin(),other.mVertcnt.end());
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void TempMesh::RemoveDegenerates() void TempMesh::RemoveDegenerates() {
{
// The strategy is simple: walk the mesh and compute normals using // The strategy is simple: walk the mesh and compute normals using
// Newell's algorithm. The length of the normals gives the area // Newell's algorithm. The length of the normals gives the area
// of the polygons, which is close to zero for lines. // of the polygons, which is close to zero for lines.
@ -167,11 +159,9 @@ void TempMesh::RemoveDegenerates()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
IfcVector3 TempMesh::ComputePolygonNormal(const IfcVector3* vtcs, size_t cnt, bool normalize) IfcVector3 TempMesh::ComputePolygonNormal(const IfcVector3* vtcs, size_t cnt, bool normalize) {
{
std::vector<IfcFloat> temp((cnt+2)*3); std::vector<IfcFloat> temp((cnt+2)*3);
for( size_t vofs = 0, i = 0; vofs < cnt; ++vofs ) for( size_t vofs = 0, i = 0; vofs < cnt; ++vofs ) {
{
const IfcVector3& v = vtcs[vofs]; const IfcVector3& v = vtcs[vofs];
temp[i++] = v.x; temp[i++] = v.x;
temp[i++] = v.y; temp[i++] = v.y;
@ -186,8 +176,7 @@ IfcVector3 TempMesh::ComputePolygonNormal(const IfcVector3* vtcs, size_t cnt, bo
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void TempMesh::ComputePolygonNormals(std::vector<IfcVector3>& normals, void TempMesh::ComputePolygonNormals(std::vector<IfcVector3>& normals,
bool normalize, bool normalize,
size_t ofs) const size_t ofs) const {
{
size_t max_vcount = 0; size_t max_vcount = 0;
std::vector<unsigned int>::const_iterator begin = mVertcnt.begin()+ofs, end = mVertcnt.end(), iit; std::vector<unsigned int>::const_iterator begin = mVertcnt.begin()+ofs, end = mVertcnt.end(), iit;
for(iit = begin; iit != end; ++iit) { for(iit = begin; iit != end; ++iit) {
@ -250,29 +239,27 @@ struct FindVector {
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void TempMesh::FixupFaceOrientation() void TempMesh::FixupFaceOrientation() {
{
const IfcVector3 vavg = Center(); const IfcVector3 vavg = Center();
// create a list of start indices for all faces to allow random access to faces // create a list of start indices for all faces to allow random access to faces
std::vector<size_t> faceStartIndices(mVertcnt.size()); std::vector<size_t> faceStartIndices(mVertcnt.size());
for( size_t i = 0, a = 0; a < mVertcnt.size(); i += mVertcnt[a], ++a ) for( size_t i = 0, a = 0; a < mVertcnt.size(); i += mVertcnt[a], ++a ) {
faceStartIndices[a] = i; faceStartIndices[a] = i;
}
// list all faces on a vertex // list all faces on a vertex
std::map<IfcVector3, std::vector<size_t>, CompareVector> facesByVertex; std::map<IfcVector3, std::vector<size_t>, CompareVector> facesByVertex;
for( size_t a = 0; a < mVertcnt.size(); ++a ) for( size_t a = 0; a < mVertcnt.size(); ++a ) {
{ for( size_t b = 0; b < mVertcnt[a]; ++b ) {
for( size_t b = 0; b < mVertcnt[a]; ++b )
facesByVertex[mVerts[faceStartIndices[a] + b]].push_back(a); facesByVertex[mVerts[faceStartIndices[a] + b]].push_back(a);
} }
}
// determine neighbourhood for all polys // determine neighbourhood for all polys
std::vector<size_t> neighbour(mVerts.size(), SIZE_MAX); std::vector<size_t> neighbour(mVerts.size(), SIZE_MAX);
std::vector<size_t> tempIntersect(10); std::vector<size_t> tempIntersect(10);
for( size_t a = 0; a < mVertcnt.size(); ++a ) for( size_t a = 0; a < mVertcnt.size(); ++a ) {
{ for( size_t b = 0; b < mVertcnt[a]; ++b ) {
for( size_t b = 0; b < mVertcnt[a]; ++b )
{
size_t ib = faceStartIndices[a] + b, nib = faceStartIndices[a] + (b + 1) % mVertcnt[a]; size_t ib = faceStartIndices[a] + b, nib = faceStartIndices[a] + (b + 1) % mVertcnt[a];
const std::vector<size_t>& facesOnB = facesByVertex[mVerts[ib]]; const std::vector<size_t>& facesOnB = facesByVertex[mVerts[ib]];
const std::vector<size_t>& facesOnNB = facesByVertex[mVerts[nib]]; const std::vector<size_t>& facesOnNB = facesByVertex[mVerts[nib]];
@ -281,10 +268,12 @@ void TempMesh::FixupFaceOrientation()
std::vector<size_t>::iterator sectend = std::set_intersection( std::vector<size_t>::iterator sectend = std::set_intersection(
facesOnB.begin(), facesOnB.end(), facesOnNB.begin(), facesOnNB.end(), sectstart); facesOnB.begin(), facesOnB.end(), facesOnNB.begin(), facesOnNB.end(), sectstart);
if( std::distance(sectstart, sectend) != 2 ) if( std::distance(sectstart, sectend) != 2 ) {
continue; continue;
if( *sectstart == a ) }
if( *sectstart == a ) {
++sectstart; ++sectstart;
}
neighbour[ib] = *sectstart; neighbour[ib] = *sectstart;
} }
} }
@ -293,15 +282,14 @@ void TempMesh::FixupFaceOrientation()
// facing outwards. So we reverse this face to point outwards in relation to the center. Then we adapt neighbouring // facing outwards. So we reverse this face to point outwards in relation to the center. Then we adapt neighbouring
// faces to have the same winding until all faces have been tested. // faces to have the same winding until all faces have been tested.
std::vector<bool> faceDone(mVertcnt.size(), false); std::vector<bool> faceDone(mVertcnt.size(), false);
while( std::count(faceDone.begin(), faceDone.end(), false) != 0 ) while( std::count(faceDone.begin(), faceDone.end(), false) != 0 ) {
{
// find the farthest of the remaining faces // find the farthest of the remaining faces
size_t farthestIndex = SIZE_MAX; size_t farthestIndex = SIZE_MAX;
IfcFloat farthestDistance = -1.0; IfcFloat farthestDistance = -1.0;
for( size_t a = 0; a < mVertcnt.size(); ++a ) for( size_t a = 0; a < mVertcnt.size(); ++a ) {
{ if( faceDone[a] ) {
if( faceDone[a] )
continue; continue;
}
IfcVector3 faceCenter = std::accumulate(mVerts.begin() + faceStartIndices[a], IfcVector3 faceCenter = std::accumulate(mVerts.begin() + faceStartIndices[a],
mVerts.begin() + faceStartIndices[a] + mVertcnt[a], IfcVector3(0.0)) / IfcFloat(mVertcnt[a]); mVerts.begin() + faceStartIndices[a] + mVertcnt[a], IfcVector3(0.0)) / IfcFloat(mVertcnt[a]);
IfcFloat dst = (faceCenter - vavg).SquareLength(); IfcFloat dst = (faceCenter - vavg).SquareLength();
@ -315,8 +303,7 @@ void TempMesh::FixupFaceOrientation()
/ IfcFloat(mVertcnt[farthestIndex]); / IfcFloat(mVertcnt[farthestIndex]);
// We accept a bit of negative orientation without reversing. In case of doubt, prefer the orientation given in // We accept a bit of negative orientation without reversing. In case of doubt, prefer the orientation given in
// the file. // the file.
if( (farthestNormal * (farthestCenter - vavg).Normalize()) < -0.4 ) if( (farthestNormal * (farthestCenter - vavg).Normalize()) < -0.4 ) {
{
size_t fsi = faceStartIndices[farthestIndex], fvc = mVertcnt[farthestIndex]; size_t fsi = faceStartIndices[farthestIndex], fvc = mVertcnt[farthestIndex];
std::reverse(mVerts.begin() + fsi, mVerts.begin() + fsi + fvc); std::reverse(mVerts.begin() + fsi, mVerts.begin() + fsi + fvc);
std::reverse(neighbour.begin() + fsi, neighbour.begin() + fsi + fvc); std::reverse(neighbour.begin() + fsi, neighbour.begin() + fsi + fvc);
@ -333,19 +320,18 @@ void TempMesh::FixupFaceOrientation()
todo.push_back(farthestIndex); todo.push_back(farthestIndex);
// go over its neighbour faces recursively and adapt their winding order to match the farthest face // go over its neighbour faces recursively and adapt their winding order to match the farthest face
while( !todo.empty() ) while( !todo.empty() ) {
{
size_t tdf = todo.back(); size_t tdf = todo.back();
size_t vsi = faceStartIndices[tdf], vc = mVertcnt[tdf]; size_t vsi = faceStartIndices[tdf], vc = mVertcnt[tdf];
todo.pop_back(); todo.pop_back();
// check its neighbours // check its neighbours
for( size_t a = 0; a < vc; ++a ) for( size_t a = 0; a < vc; ++a ) {
{
// ignore neighbours if we already checked them // ignore neighbours if we already checked them
size_t nbi = neighbour[vsi + a]; size_t nbi = neighbour[vsi + a];
if( nbi == SIZE_MAX || faceDone[nbi] ) if( nbi == SIZE_MAX || faceDone[nbi] ) {
continue; continue;
}
const IfcVector3& vp = mVerts[vsi + a]; const IfcVector3& vp = mVerts[vsi + a];
size_t nbvsi = faceStartIndices[nbi], nbvc = mVertcnt[nbi]; size_t nbvsi = faceStartIndices[nbi], nbvc = mVertcnt[nbi];
@ -388,31 +374,7 @@ void TempMesh::RemoveAdjacentDuplicates() {
IfcVector3 vmin,vmax; IfcVector3 vmin,vmax;
ArrayBounds(&*base, cnt ,vmin,vmax); ArrayBounds(&*base, cnt ,vmin,vmax);
const IfcFloat epsilon = (vmax-vmin).SquareLength() / static_cast<IfcFloat>(1e9); const IfcFloat epsilon = (vmax-vmin).SquareLength() / static_cast<IfcFloat>(1e9);
//const IfcFloat dotepsilon = 1e-9;
//// look for vertices that lie directly on the line between their predecessor and their
//// successor and replace them with either of them.
//for(size_t i = 0; i < cnt; ++i) {
// IfcVector3& v1 = *(base+i), &v0 = *(base+(i?i-1:cnt-1)), &v2 = *(base+(i+1)%cnt);
// const IfcVector3& d0 = (v1-v0), &d1 = (v2-v1);
// const IfcFloat l0 = d0.SquareLength(), l1 = d1.SquareLength();
// if (!l0 || !l1) {
// continue;
// }
// const IfcFloat d = (d0/std::sqrt(l0))*(d1/std::sqrt(l1));
// if ( d >= 1.f-dotepsilon ) {
// v1 = v0;
// }
// else if ( d < -1.f+dotepsilon ) {
// v2 = v1;
// continue;
// }
//}
// drop any identical, adjacent vertices. this pass will collect the dropouts // drop any identical, adjacent vertices. this pass will collect the dropouts
// of the previous pass as a side-effect. // of the previous pass as a side-effect.
@ -440,78 +402,58 @@ void TempMesh::RemoveAdjacentDuplicates() {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void TempMesh::Swap(TempMesh& other) void TempMesh::Swap(TempMesh& other) {
{
mVertcnt.swap(other.mVertcnt); mVertcnt.swap(other.mVertcnt);
mVerts.swap(other.mVerts); mVerts.swap(other.mVerts);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool IsTrue(const ::Assimp::STEP::EXPRESS::BOOLEAN& in) bool IsTrue(const ::Assimp::STEP::EXPRESS::BOOLEAN& in) {
{
return (std::string)in == "TRUE" || (std::string)in == "T"; return (std::string)in == "TRUE" || (std::string)in == "T";
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
IfcFloat ConvertSIPrefix(const std::string& prefix) IfcFloat ConvertSIPrefix(const std::string& prefix) {
{
if (prefix == "EXA") { if (prefix == "EXA") {
return 1e18f; return 1e18f;
} } else if (prefix == "PETA") {
else if (prefix == "PETA") {
return 1e15f; return 1e15f;
} } else if (prefix == "TERA") {
else if (prefix == "TERA") {
return 1e12f; return 1e12f;
} } else if (prefix == "GIGA") {
else if (prefix == "GIGA") {
return 1e9f; return 1e9f;
} } else if (prefix == "MEGA") {
else if (prefix == "MEGA") {
return 1e6f; return 1e6f;
} } else if (prefix == "KILO") {
else if (prefix == "KILO") {
return 1e3f; return 1e3f;
} } else if (prefix == "HECTO") {
else if (prefix == "HECTO") {
return 1e2f; return 1e2f;
} } else if (prefix == "DECA") {
else if (prefix == "DECA") {
return 1e-0f; return 1e-0f;
} } else if (prefix == "DECI") {
else if (prefix == "DECI") {
return 1e-1f; return 1e-1f;
} } else if (prefix == "CENTI") {
else if (prefix == "CENTI") {
return 1e-2f; return 1e-2f;
} } else if (prefix == "MILLI") {
else if (prefix == "MILLI") {
return 1e-3f; return 1e-3f;
} } else if (prefix == "MICRO") {
else if (prefix == "MICRO") {
return 1e-6f; return 1e-6f;
} } else if (prefix == "NANO") {
else if (prefix == "NANO") {
return 1e-9f; return 1e-9f;
} } else if (prefix == "PICO") {
else if (prefix == "PICO") {
return 1e-12f; return 1e-12f;
} } else if (prefix == "FEMTO") {
else if (prefix == "FEMTO") {
return 1e-15f; return 1e-15f;
} } else if (prefix == "ATTO") {
else if (prefix == "ATTO") {
return 1e-18f; return 1e-18f;
} } else {
else {
IFCImporter::LogError("Unrecognized SI prefix: ", prefix); IFCImporter::LogError("Unrecognized SI prefix: ", prefix);
return 1; return 1;
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertColor(aiColor4D& out, const Schema_2x3::IfcColourRgb& in) void ConvertColor(aiColor4D& out, const Schema_2x3::IfcColourRgb& in) {
{
out.r = static_cast<float>( in.Red ); out.r = static_cast<float>( in.Red );
out.g = static_cast<float>( in.Green ); out.g = static_cast<float>( in.Green );
out.b = static_cast<float>( in.Blue ); out.b = static_cast<float>( in.Blue );
@ -519,8 +461,10 @@ void ConvertColor(aiColor4D& out, const Schema_2x3::IfcColourRgb& in)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertColor(aiColor4D& out, const Schema_2x3::IfcColourOrFactor& in,ConversionData& conv,const aiColor4D* base) void ConvertColor(aiColor4D& out,
{ const Schema_2x3::IfcColourOrFactor& in,
ConversionData& conv,
const aiColor4D* base) {
if (const ::Assimp::STEP::EXPRESS::REAL* const r = in.ToPtr<::Assimp::STEP::EXPRESS::REAL>()) { if (const ::Assimp::STEP::EXPRESS::REAL* const r = in.ToPtr<::Assimp::STEP::EXPRESS::REAL>()) {
out.r = out.g = out.b = static_cast<float>(*r); out.r = out.g = out.b = static_cast<float>(*r);
if(base) { if(base) {
@ -528,20 +472,18 @@ void ConvertColor(aiColor4D& out, const Schema_2x3::IfcColourOrFactor& in,Conver
out.g *= static_cast<float>( base->g ); out.g *= static_cast<float>( base->g );
out.b *= static_cast<float>( base->b ); out.b *= static_cast<float>( base->b );
out.a = static_cast<float>( base->a ); out.a = static_cast<float>( base->a );
} else {
out.a = 1.0;
} }
else out.a = 1.0; } else if (const Schema_2x3::IfcColourRgb* const rgb = in.ResolveSelectPtr<Schema_2x3::IfcColourRgb>(conv.db)) {
}
else if (const Schema_2x3::IfcColourRgb* const rgb = in.ResolveSelectPtr<Schema_2x3::IfcColourRgb>(conv.db)) {
ConvertColor(out,*rgb); ConvertColor(out,*rgb);
} } else {
else {
IFCImporter::LogWarn("skipping unknown IfcColourOrFactor entity"); IFCImporter::LogWarn("skipping unknown IfcColourOrFactor entity");
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertCartesianPoint(IfcVector3& out, const Schema_2x3::IfcCartesianPoint& in) void ConvertCartesianPoint(IfcVector3& out, const Schema_2x3::IfcCartesianPoint& in) {
{
out = IfcVector3(); out = IfcVector3();
for(size_t i = 0; i < in.Coordinates.size(); ++i) { for(size_t i = 0; i < in.Coordinates.size(); ++i) {
out[static_cast<unsigned int>(i)] = in.Coordinates[i]; out[static_cast<unsigned int>(i)] = in.Coordinates[i];
@ -549,15 +491,13 @@ void ConvertCartesianPoint(IfcVector3& out, const Schema_2x3::IfcCartesianPoint&
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertVector(IfcVector3& out, const Schema_2x3::IfcVector& in) void ConvertVector(IfcVector3& out, const Schema_2x3::IfcVector& in) {
{
ConvertDirection(out,in.Orientation); ConvertDirection(out,in.Orientation);
out *= in.Magnitude; out *= in.Magnitude;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertDirection(IfcVector3& out, const Schema_2x3::IfcDirection& in) void ConvertDirection(IfcVector3& out, const Schema_2x3::IfcDirection& in) {
{
out = IfcVector3(); out = IfcVector3();
for(size_t i = 0; i < in.DirectionRatios.size(); ++i) { for(size_t i = 0; i < in.DirectionRatios.size(); ++i) {
out[static_cast<unsigned int>(i)] = in.DirectionRatios[i]; out[static_cast<unsigned int>(i)] = in.DirectionRatios[i];
@ -571,8 +511,7 @@ void ConvertDirection(IfcVector3& out, const Schema_2x3::IfcDirection& in)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y, const IfcVector3& z) void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y, const IfcVector3& z) {
{
out.a1 = x.x; out.a1 = x.x;
out.b1 = x.y; out.b1 = x.y;
out.c1 = x.z; out.c1 = x.z;
@ -587,8 +526,7 @@ void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y,
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement3D& in) void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement3D& in) {
{
IfcVector3 loc; IfcVector3 loc;
ConvertCartesianPoint(loc,in.Location); ConvertCartesianPoint(loc,in.Location);
@ -612,8 +550,7 @@ void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement3D
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement2D& in) void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement2D& in) {
{
IfcVector3 loc; IfcVector3 loc;
ConvertCartesianPoint(loc,in.Location); ConvertCartesianPoint(loc,in.Location);
@ -629,34 +566,28 @@ void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement2D
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertAxisPlacement(IfcVector3& axis, IfcVector3& pos, const Schema_2x3::IfcAxis1Placement& in) void ConvertAxisPlacement(IfcVector3& axis, IfcVector3& pos, const Schema_2x3::IfcAxis1Placement& in) {
{
ConvertCartesianPoint(pos,in.Location); ConvertCartesianPoint(pos,in.Location);
if (in.Axis) { if (in.Axis) {
ConvertDirection(axis,in.Axis.Get()); ConvertDirection(axis,in.Axis.Get());
} } else {
else {
axis = IfcVector3(0.f,0.f,1.f); axis = IfcVector3(0.f,0.f,1.f);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement& in, ConversionData& conv) void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement& in, ConversionData& conv) {
{
if(const Schema_2x3::IfcAxis2Placement3D* pl3 = in.ResolveSelectPtr<Schema_2x3::IfcAxis2Placement3D>(conv.db)) { if(const Schema_2x3::IfcAxis2Placement3D* pl3 = in.ResolveSelectPtr<Schema_2x3::IfcAxis2Placement3D>(conv.db)) {
ConvertAxisPlacement(out,*pl3); ConvertAxisPlacement(out,*pl3);
} } else if(const Schema_2x3::IfcAxis2Placement2D* pl2 = in.ResolveSelectPtr<Schema_2x3::IfcAxis2Placement2D>(conv.db)) {
else if(const Schema_2x3::IfcAxis2Placement2D* pl2 = in.ResolveSelectPtr<Schema_2x3::IfcAxis2Placement2D>(conv.db)) {
ConvertAxisPlacement(out,*pl2); ConvertAxisPlacement(out,*pl2);
} } else {
else {
IFCImporter::LogWarn("skipping unknown IfcAxis2Placement entity"); IFCImporter::LogWarn("skipping unknown IfcAxis2Placement entity");
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertTransformOperator(IfcMatrix4& out, const Schema_2x3::IfcCartesianTransformationOperator& op) void ConvertTransformOperator(IfcMatrix4& out, const Schema_2x3::IfcCartesianTransformationOperator& op) {
{
IfcVector3 loc; IfcVector3 loc;
ConvertCartesianPoint(loc,op.LocalOrigin); ConvertCartesianPoint(loc,op.LocalOrigin);
@ -677,14 +608,12 @@ void ConvertTransformOperator(IfcMatrix4& out, const Schema_2x3::IfcCartesianTra
IfcMatrix4::Translation(loc,locm); IfcMatrix4::Translation(loc,locm);
AssignMatrixAxes(out,x,y,z); AssignMatrixAxes(out,x,y,z);
IfcVector3 vscale; IfcVector3 vscale;
if (const Schema_2x3::IfcCartesianTransformationOperator3DnonUniform* nuni = op.ToPtr<Schema_2x3::IfcCartesianTransformationOperator3DnonUniform>()) { if (const Schema_2x3::IfcCartesianTransformationOperator3DnonUniform* nuni = op.ToPtr<Schema_2x3::IfcCartesianTransformationOperator3DnonUniform>()) {
vscale.x = nuni->Scale?op.Scale.Get():1.f; vscale.x = nuni->Scale?op.Scale.Get():1.f;
vscale.y = nuni->Scale2?nuni->Scale2.Get():1.f; vscale.y = nuni->Scale2?nuni->Scale2.Get():1.f;
vscale.z = nuni->Scale3?nuni->Scale3.Get():1.f; vscale.z = nuni->Scale3?nuni->Scale3.Get():1.f;
} } else {
else {
const IfcFloat sc = op.Scale?op.Scale.Get():1.f; const IfcFloat sc = op.Scale?op.Scale.Get():1.f;
vscale = IfcVector3(sc,sc,sc); vscale = IfcVector3(sc,sc,sc);
} }
@ -695,8 +624,7 @@ void ConvertTransformOperator(IfcMatrix4& out, const Schema_2x3::IfcCartesianTra
out = locm * out * s; out = locm * out * s;
} }
} // ! IFC } // ! IFC
} // ! Assimp } // ! Assimp
#endif #endif // ASSIMP_BUILD_NO_IFC_IMPORTER

View File

@ -927,22 +927,22 @@ ELSE()
ENDIF() ENDIF()
# polyclipping # polyclipping
IF(ASSIMP_HUNTER_ENABLED) #IF(ASSIMP_HUNTER_ENABLED)
hunter_add_package(polyclipping) # hunter_add_package(polyclipping)
find_package(polyclipping CONFIG REQUIRED) # find_package(polyclipping CONFIG REQUIRED)
ELSE() #ELSE()
SET( Clipper_SRCS SET( Clipper_SRCS
../contrib/clipper/clipper.hpp ../contrib/clipper/clipper.hpp
../contrib/clipper/clipper.cpp ../contrib/clipper/clipper.cpp
) )
SOURCE_GROUP( Contrib\\Clipper FILES ${Clipper_SRCS}) SOURCE_GROUP( Contrib\\Clipper FILES ${Clipper_SRCS})
ENDIF() #ENDIF()
# poly2tri # poly2tri
IF(ASSIMP_HUNTER_ENABLED) #IF(ASSIMP_HUNTER_ENABLED)
hunter_add_package(poly2tri) # hunter_add_package(poly2tri)
find_package(poly2tri CONFIG REQUIRED) # find_package(poly2tri CONFIG REQUIRED)
ELSE() #ELSE()
SET( Poly2Tri_SRCS SET( Poly2Tri_SRCS
../contrib/poly2tri/poly2tri/common/shapes.cc ../contrib/poly2tri/poly2tri/common/shapes.cc
../contrib/poly2tri/poly2tri/common/shapes.h ../contrib/poly2tri/poly2tri/common/shapes.h
@ -957,7 +957,7 @@ ELSE()
../contrib/poly2tri/poly2tri/sweep/sweep_context.h ../contrib/poly2tri/poly2tri/sweep/sweep_context.h
) )
SOURCE_GROUP( Contrib\\Poly2Tri FILES ${Poly2Tri_SRCS}) SOURCE_GROUP( Contrib\\Poly2Tri FILES ${Poly2Tri_SRCS})
ENDIF() #ENDIF()
# minizip/unzip # minizip/unzip
IF(ASSIMP_HUNTER_ENABLED) IF(ASSIMP_HUNTER_ENABLED)
@ -1267,9 +1267,9 @@ TARGET_INCLUDE_DIRECTORIES ( assimp PUBLIC
IF(ASSIMP_HUNTER_ENABLED) IF(ASSIMP_HUNTER_ENABLED)
TARGET_LINK_LIBRARIES(assimp TARGET_LINK_LIBRARIES(assimp
PUBLIC PUBLIC
polyclipping::polyclipping #polyclipping::polyclipping
openddlparser::openddl_parser openddlparser::openddl_parser
poly2tri::poly2tri #poly2tri::poly2tri
minizip::minizip minizip::minizip
ZLIB::zlib ZLIB::zlib
RapidJSON::rapidjson RapidJSON::rapidjson

View File

@ -1,7 +1,3 @@
The Clipper code library, the "Software" (that includes Delphi, C++ & C#
source code, accompanying samples and documentation), has been released
under the following license, terms and conditions:
Boost Software License - Version 1.0 - August 17th, 2003 Boost Software License - Version 1.0 - August 17th, 2003
http://www.boost.org/LICENSE_1_0.txt http://www.boost.org/LICENSE_1_0.txt
@ -26,4 +22,3 @@ SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,10 @@
/******************************************************************************* /*******************************************************************************
* * * *
* Author : Angus Johnson * * Author : Angus Johnson *
* Version : 4.8.8 * * Version : 6.4.2 *
* Date : 30 August 2012 * * Date : 27 February 2017 *
* Website : http://www.angusj.com * * Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2012 * * Copyright : Angus Johnson 2010-2017 *
* * * *
* License: * * License: *
* Use, modification & distribution is subject to Boost Software License Ver 1. * * Use, modification & distribution is subject to Boost Software License Ver 1. *
@ -34,11 +34,30 @@
#ifndef clipper_hpp #ifndef clipper_hpp
#define clipper_hpp #define clipper_hpp
#define CLIPPER_VERSION "6.4.2"
//use_int32: When enabled 32bit ints are used instead of 64bit ints. This
//improve performance but coordinate values are limited to the range +/- 46340
//#define use_int32
//use_xyz: adds a Z member to IntPoint. Adds a minor cost to perfomance.
//#define use_xyz
//use_lines: Enables line clipping. Adds a very minor cost to performance.
#define use_lines
//use_deprecated: Enables temporary support for the obsolete functions
//#define use_deprecated
#include <vector> #include <vector>
#include <list>
#include <set>
#include <stdexcept> #include <stdexcept>
#include <cstring> #include <cstring>
#include <cstdlib> #include <cstdlib>
#include <ostream> #include <ostream>
#include <functional>
#include <queue>
namespace ClipperLib { namespace ClipperLib {
@ -50,129 +69,150 @@ enum PolyType { ptSubject, ptClip };
//see http://glprogramming.com/red/chapter11.html //see http://glprogramming.com/red/chapter11.html
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative }; enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
typedef signed long long long64; #ifdef use_int32
typedef unsigned long long ulong64; typedef int cInt;
static cInt const loRange = 0x7FFF;
static cInt const hiRange = 0x7FFF;
#else
typedef signed long long cInt;
static cInt const loRange = 0x3FFFFFFF;
static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL;
typedef signed long long long64; //used by Int128 class
typedef unsigned long long ulong64;
#endif
struct IntPoint { struct IntPoint {
cInt X;
cInt Y;
#ifdef use_xyz
cInt Z;
IntPoint(cInt x = 0, cInt y = 0, cInt z = 0): X(x), Y(y), Z(z) {};
#else
IntPoint(cInt x = 0, cInt y = 0): X(x), Y(y) {};
#endif
friend inline bool operator== (const IntPoint& a, const IntPoint& b)
{
return a.X == b.X && a.Y == b.Y;
}
friend inline bool operator!= (const IntPoint& a, const IntPoint& b)
{
return a.X != b.X || a.Y != b.Y;
}
};
//------------------------------------------------------------------------------
typedef std::vector< IntPoint > Path;
typedef std::vector< Path > Paths;
inline Path& operator <<(Path& poly, const IntPoint& p) {poly.push_back(p); return poly;}
inline Paths& operator <<(Paths& polys, const Path& p) {polys.push_back(p); return polys;}
std::ostream& operator <<(std::ostream &s, const IntPoint &p);
std::ostream& operator <<(std::ostream &s, const Path &p);
std::ostream& operator <<(std::ostream &s, const Paths &p);
struct DoublePoint
{
double X;
double Y;
DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {}
DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.Y) {}
};
//------------------------------------------------------------------------------
#ifdef use_xyz
typedef void (*ZFillCallback)(IntPoint& e1bot, IntPoint& e1top, IntPoint& e2bot, IntPoint& e2top, IntPoint& pt);
#endif
enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCollinear = 4};
enum JoinType {jtSquare, jtRound, jtMiter};
enum EndType {etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare, etOpenRound};
class PolyNode;
typedef std::vector< PolyNode* > PolyNodes;
class PolyNode
{
public: public:
long64 X; PolyNode();
long64 Y; virtual ~PolyNode(){};
IntPoint(long64 x = 0, long64 y = 0): X(x), Y(y) {}; Path Contour;
friend std::ostream& operator <<(std::ostream &s, IntPoint &p); PolyNodes Childs;
PolyNode* Parent;
PolyNode* GetNext() const;
bool IsHole() const;
bool IsOpen() const;
int ChildCount() const;
private:
//PolyNode& operator =(PolyNode& other);
unsigned Index; //node index in Parent.Childs
bool m_IsOpen;
JoinType m_jointype;
EndType m_endtype;
PolyNode* GetNextSiblingUp() const;
void AddChild(PolyNode& child);
friend class Clipper; //to access Index
friend class ClipperOffset;
}; };
typedef std::vector< IntPoint > Polygon; class PolyTree: public PolyNode
typedef std::vector< Polygon > Polygons; {
public:
std::ostream& operator <<(std::ostream &s, Polygon &p); ~PolyTree(){ Clear(); };
std::ostream& operator <<(std::ostream &s, Polygons &p); PolyNode* GetFirst() const;
void Clear();
struct ExPolygon { int Total() const;
Polygon outer; private:
Polygons holes; //PolyTree& operator =(PolyTree& other);
}; PolyNodes AllNodes;
typedef std::vector< ExPolygon > ExPolygons; friend class Clipper; //to access AllNodes
enum JoinType { jtSquare, jtRound, jtMiter };
bool Orientation(const Polygon &poly);
double Area(const Polygon &poly);
void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys,
double delta, JoinType jointype = jtSquare, double MiterLimit = 2);
void SimplifyPolygon(const Polygon &in_poly, Polygons &out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(const Polygons &in_polys, Polygons &out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(Polygons &polys, PolyFillType fillType = pftEvenOdd);
void ReversePolygon(Polygon& p);
void ReversePolygons(Polygons& p);
//used internally ...
enum EdgeSide { esNeither = 0, esLeft = 1, esRight = 2, esBoth = 3 };
enum IntersectProtects { ipNone = 0, ipLeft = 1, ipRight = 2, ipBoth = 3 };
struct TEdge {
long64 xbot;
long64 ybot;
long64 xcurr;
long64 ycurr;
long64 xtop;
long64 ytop;
double dx;
long64 tmpX;
PolyType polyType;
EdgeSide side;
int windDelta; //1 or -1 depending on winding direction
int windCnt;
int windCnt2; //winding count of the opposite polytype
int outIdx;
TEdge *next;
TEdge *prev;
TEdge *nextInLML;
TEdge *nextInAEL;
TEdge *prevInAEL;
TEdge *nextInSEL;
TEdge *prevInSEL;
}; };
struct IntersectNode { bool Orientation(const Path &poly);
TEdge *edge1; double Area(const Path &poly);
TEdge *edge2; int PointInPolygon(const IntPoint &pt, const Path &path);
IntPoint pt;
IntersectNode *next;
};
struct LocalMinima { void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
long64 Y; void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
TEdge *leftBound; void SimplifyPolygons(Paths &polys, PolyFillType fillType = pftEvenOdd);
TEdge *rightBound;
LocalMinima *next;
};
struct Scanbeam { void CleanPolygon(const Path& in_poly, Path& out_poly, double distance = 1.415);
long64 Y; void CleanPolygon(Path& poly, double distance = 1.415);
Scanbeam *next; void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance = 1.415);
}; void CleanPolygons(Paths& polys, double distance = 1.415);
struct OutPt; //forward declaration void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed);
void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solution, bool pathIsClosed);
void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution);
struct OutRec { void PolyTreeToPaths(const PolyTree& polytree, Paths& paths);
int idx; void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths);
bool isHole; void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths);
OutRec *FirstLeft;
OutRec *AppendLink;
OutPt *pts;
OutPt *bottomPt;
OutPt *bottomFlag;
EdgeSide sides;
};
struct OutPt { void ReversePath(Path& p);
int idx; void ReversePaths(Paths& p);
IntPoint pt;
OutPt *next;
OutPt *prev;
};
struct JoinRec { struct IntRect { cInt left; cInt top; cInt right; cInt bottom; };
IntPoint pt1a;
IntPoint pt1b;
int poly1Idx;
IntPoint pt2a;
IntPoint pt2b;
int poly2Idx;
};
struct HorzJoinRec { //enums that are used internally ...
TEdge *edge; enum EdgeSide { esLeft = 1, esRight = 2};
int savedIdx;
};
struct IntRect { long64 left; long64 top; long64 right; long64 bottom; }; //forward declarations (for stuff used internally) ...
struct TEdge;
struct IntersectNode;
struct LocalMinimum;
struct OutPt;
struct OutRec;
struct Join;
typedef std::vector < OutRec* > PolyOutList; typedef std::vector < OutRec* > PolyOutList;
typedef std::vector < TEdge* > EdgeList; typedef std::vector < TEdge* > EdgeList;
typedef std::vector < JoinRec* > JoinList; typedef std::vector < Join* > JoinList;
typedef std::vector < HorzJoinRec* > HorzJoinList; typedef std::vector < IntersectNode* > IntersectList;
//------------------------------------------------------------------------------
//ClipperBase is the ancestor to the Clipper class. It should not be //ClipperBase is the ancestor to the Clipper class. It should not be
//instantiated directly. This class simply abstracts the conversion of sets of //instantiated directly. This class simply abstracts the conversion of sets of
@ -182,110 +222,170 @@ class ClipperBase
public: public:
ClipperBase(); ClipperBase();
virtual ~ClipperBase(); virtual ~ClipperBase();
bool AddPolygon(const Polygon &pg, PolyType polyType); virtual bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
bool AddPolygons( const Polygons &ppg, PolyType polyType); bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed);
virtual void Clear(); virtual void Clear();
IntRect GetBounds(); IntRect GetBounds();
bool PreserveCollinear() {return m_PreserveCollinear;};
void PreserveCollinear(bool value) {m_PreserveCollinear = value;};
protected: protected:
void DisposeLocalMinimaList(); void DisposeLocalMinimaList();
TEdge* AddBoundsToLML(TEdge *e); TEdge* AddBoundsToLML(TEdge *e, bool IsClosed);
void PopLocalMinima();
virtual void Reset(); virtual void Reset();
void InsertLocalMinima(LocalMinima *newLm); TEdge* ProcessBound(TEdge* E, bool IsClockwise);
LocalMinima *m_CurrentLM; void InsertScanbeam(const cInt Y);
LocalMinima *m_MinimaList; bool PopScanbeam(cInt &Y);
bool LocalMinimaPending();
bool PopLocalMinima(cInt Y, const LocalMinimum *&locMin);
OutRec* CreateOutRec();
void DisposeAllOutRecs();
void DisposeOutRec(PolyOutList::size_type index);
void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
void DeleteFromAEL(TEdge *e);
void UpdateEdgeIntoAEL(TEdge *&e);
typedef std::vector<LocalMinimum> MinimaList;
MinimaList::iterator m_CurrentLM;
MinimaList m_MinimaList;
bool m_UseFullRange; bool m_UseFullRange;
EdgeList m_edges; EdgeList m_edges;
bool m_PreserveCollinear;
bool m_HasOpenPaths;
PolyOutList m_PolyOuts;
TEdge *m_ActiveEdges;
typedef std::priority_queue<cInt> ScanbeamList;
ScanbeamList m_Scanbeam;
}; };
//------------------------------------------------------------------------------
class Clipper : public virtual ClipperBase class Clipper : public virtual ClipperBase
{ {
public: public:
Clipper(); Clipper(int initOptions = 0);
~Clipper();
bool Execute(ClipType clipType, bool Execute(ClipType clipType,
Polygons &solution, Paths &solution,
PolyFillType subjFillType = pftEvenOdd, PolyFillType fillType = pftEvenOdd);
PolyFillType clipFillType = pftEvenOdd);
bool Execute(ClipType clipType, bool Execute(ClipType clipType,
ExPolygons &solution, Paths &solution,
PolyFillType subjFillType = pftEvenOdd, PolyFillType subjFillType,
PolyFillType clipFillType = pftEvenOdd); PolyFillType clipFillType);
void Clear(); bool Execute(ClipType clipType,
bool ReverseSolution() {return m_ReverseOutput;}; PolyTree &polytree,
PolyFillType fillType = pftEvenOdd);
bool Execute(ClipType clipType,
PolyTree &polytree,
PolyFillType subjFillType,
PolyFillType clipFillType);
bool ReverseSolution() { return m_ReverseOutput; };
void ReverseSolution(bool value) {m_ReverseOutput = value;}; void ReverseSolution(bool value) {m_ReverseOutput = value;};
bool StrictlySimple() {return m_StrictSimple;};
void StrictlySimple(bool value) {m_StrictSimple = value;};
//set the callback function for z value filling on intersections (otherwise Z is 0)
#ifdef use_xyz
void ZFillFunction(ZFillCallback zFillFunc);
#endif
protected: protected:
void Reset(); virtual bool ExecuteInternal();
virtual bool ExecuteInternal(bool fixHoleLinkages);
private: private:
PolyOutList m_PolyOuts;
JoinList m_Joins; JoinList m_Joins;
HorzJoinList m_HorizJoins; JoinList m_GhostJoins;
IntersectList m_IntersectList;
ClipType m_ClipType; ClipType m_ClipType;
Scanbeam *m_Scanbeam; typedef std::list<cInt> MaximaList;
TEdge *m_ActiveEdges; MaximaList m_Maxima;
TEdge *m_SortedEdges; TEdge *m_SortedEdges;
IntersectNode *m_IntersectNodes;
bool m_ExecuteLocked; bool m_ExecuteLocked;
PolyFillType m_ClipFillType; PolyFillType m_ClipFillType;
PolyFillType m_SubjFillType; PolyFillType m_SubjFillType;
bool m_ReverseOutput; bool m_ReverseOutput;
void DisposeScanbeamList(); bool m_UsingPolyTree;
bool m_StrictSimple;
#ifdef use_xyz
ZFillCallback m_ZFill; //custom callback
#endif
void SetWindingCount(TEdge& edge); void SetWindingCount(TEdge& edge);
bool IsEvenOddFillType(const TEdge& edge) const; bool IsEvenOddFillType(const TEdge& edge) const;
bool IsEvenOddAltFillType(const TEdge& edge) const; bool IsEvenOddAltFillType(const TEdge& edge) const;
void InsertScanbeam(const long64 Y); void InsertLocalMinimaIntoAEL(const cInt botY);
long64 PopScanbeam(); void InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge);
void InsertLocalMinimaIntoAEL(const long64 botY);
void InsertEdgeIntoAEL(TEdge *edge);
void AddEdgeToSEL(TEdge *edge); void AddEdgeToSEL(TEdge *edge);
bool PopEdgeFromSEL(TEdge *&edge);
void CopyAELToSEL(); void CopyAELToSEL();
void DeleteFromSEL(TEdge *e); void DeleteFromSEL(TEdge *e);
void DeleteFromAEL(TEdge *e);
void UpdateEdgeIntoAEL(TEdge *&e);
void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2); void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2);
bool IsContributing(const TEdge& edge) const; bool IsContributing(const TEdge& edge) const;
bool IsTopHorz(const long64 XPos); bool IsTopHorz(const cInt XPos);
void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2); void DoMaxima(TEdge *e);
void DoMaxima(TEdge *e, long64 topY);
void ProcessHorizontals(); void ProcessHorizontals();
void ProcessHorizontal(TEdge *horzEdge); void ProcessHorizontal(TEdge *horzEdge);
void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
void AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); OutPt* AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
OutRec* GetOutRec(int idx);
void AppendPolygon(TEdge *e1, TEdge *e2); void AppendPolygon(TEdge *e1, TEdge *e2);
void DoEdge1(TEdge *edge1, TEdge *edge2, const IntPoint &pt); void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt);
void DoEdge2(TEdge *edge1, TEdge *edge2, const IntPoint &pt); OutPt* AddOutPt(TEdge *e, const IntPoint &pt);
void DoBothEdges(TEdge *edge1, TEdge *edge2, const IntPoint &pt); OutPt* GetLastOutPt(TEdge *e);
void IntersectEdges(TEdge *e1, TEdge *e2, bool ProcessIntersections(const cInt topY);
const IntPoint &pt, IntersectProtects protects); void BuildIntersectList(const cInt topY);
OutRec* CreateOutRec();
void AddOutPt(TEdge *e, const IntPoint &pt);
void DisposeBottomPt(OutRec &outRec);
void DisposeAllPolyPts();
void DisposeOutRec(PolyOutList::size_type index);
bool ProcessIntersections(const long64 botY, const long64 topY);
void AddIntersectNode(TEdge *e1, TEdge *e2, const IntPoint &pt);
void BuildIntersectList(const long64 botY, const long64 topY);
void ProcessIntersectList(); void ProcessIntersectList();
void ProcessEdgesAtTopOfScanbeam(const long64 topY); void ProcessEdgesAtTopOfScanbeam(const cInt topY);
void BuildResult(Polygons& polys); void BuildResult(Paths& polys);
void BuildResultEx(ExPolygons& polys); void BuildResult2(PolyTree& polytree);
void SetHoleState(TEdge *e, OutRec *OutRec); void SetHoleState(TEdge *e, OutRec *outrec);
void DisposeIntersectNodes(); void DisposeIntersectNodes();
bool FixupIntersections(); bool FixupIntersectionOrder();
void FixupOutPolygon(OutRec &outRec); void FixupOutPolygon(OutRec &outrec);
void FixupOutPolyline(OutRec &outrec);
bool IsHole(TEdge *e); bool IsHole(TEdge *e);
void FixHoleLinkage(OutRec *outRec); bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl);
void CheckHoleLinkages1(OutRec *outRec1, OutRec *outRec2); void FixHoleLinkage(OutRec &outrec);
void CheckHoleLinkages2(OutRec *outRec1, OutRec *outRec2); void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt);
void AddJoin(TEdge *e1, TEdge *e2, int e1OutIdx = -1, int e2OutIdx = -1);
void ClearJoins(); void ClearJoins();
void AddHorzJoin(TEdge *e, int idx); void ClearGhostJoins();
void ClearHorzJoins(); void AddGhostJoin(OutPt *op, const IntPoint offPt);
void JoinCommonEdges(bool fixHoleLinkages); bool JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2);
void JoinCommonEdges();
void DoSimplePolygons();
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec);
void FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec);
void FixupFirstLefts3(OutRec* OldOutRec, OutRec* NewOutRec);
#ifdef use_xyz
void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2);
#endif
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
class ClipperOffset
{
public:
ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25);
~ClipperOffset();
void AddPath(const Path& path, JoinType joinType, EndType endType);
void AddPaths(const Paths& paths, JoinType joinType, EndType endType);
void Execute(Paths& solution, double delta);
void Execute(PolyTree& solution, double delta);
void Clear();
double MiterLimit;
double ArcTolerance;
private:
Paths m_destPolys;
Path m_srcPoly;
Path m_destPoly;
std::vector<DoublePoint> m_normals;
double m_delta, m_sinA, m_sin, m_cos;
double m_miterLim, m_StepsPerRad;
IntPoint m_lowest;
PolyNode m_polyNodes;
void FixOrientations();
void DoOffset(double delta);
void OffsetPoint(int j, int& k, JoinType jointype);
void DoSquare(int j, int k);
void DoMiter(int j, int k, double r);
void DoRound(int j, int k);
};
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
class clipperException : public std::exception class clipperException : public std::exception

View File

@ -0,0 +1,74 @@
MiniZip - Copyright (c) 1998-2010 - by Gilles Vollant - version 1.1 64 bits from Mathias Svensson
Introduction
---------------------
MiniZip 1.1 is built from MiniZip 1.0 by Gilles Vollant ( http://www.winimage.com/zLibDll/minizip.html )
When adding ZIP64 support into minizip it would result into risk of breaking compatibility with minizip 1.0.
All possible work was done for compatibility.
Background
---------------------
When adding ZIP64 support Mathias Svensson found that Even Rouault have added ZIP64
support for unzip.c into minizip for a open source project called gdal ( http://www.gdal.org/ )
That was used as a starting point. And after that ZIP64 support was added to zip.c
some refactoring and code cleanup was also done.
Changed from MiniZip 1.0 to MiniZip 1.1
---------------------------------------
* Added ZIP64 support for unzip ( by Even Rouault )
* Added ZIP64 support for zip ( by Mathias Svensson )
* Reverted some changed that Even Rouault did.
* Bunch of patches received from Gulles Vollant that he received for MiniZip from various users.
* Added unzip patch for BZIP Compression method (patch create by Daniel Borca)
* Added BZIP Compress method for zip
* Did some refactoring and code cleanup
Credits
Gilles Vollant - Original MiniZip author
Even Rouault - ZIP64 unzip Support
Daniel Borca - BZip Compression method support in unzip
Mathias Svensson - ZIP64 zip support
Mathias Svensson - BZip Compression method support in zip
Resources
ZipLayout http://result42.com/projects/ZipFileLayout
Command line tool for Windows that shows the layout and information of the headers in a zip archive.
Used when debugging and validating the creation of zip files using MiniZip64
ZIP App Note http://www.pkware.com/documents/casestudies/APPNOTE.TXT
Zip File specification
Notes.
* To be able to use BZip compression method in zip64.c or unzip64.c the BZIP2 lib is needed and HAVE_BZIP2 need to be defined.
License
----------------------------------------------------------
Condition of use and distribution are the same than zlib :
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
----------------------------------------------------------