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
parent
3cf7d28bc4
commit
aa1996e143
|
@ -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')
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
----------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue