Refactorings
parent
b5daee2f41
commit
eb20942f03
|
@ -74,12 +74,6 @@ jobs:
|
|||
repository: cpp-pm/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
|
||||
id: dxcache
|
||||
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"
|
||||
SHA1 "e6396699e414120e32557fe92db097b7655b760b"
|
||||
)
|
||||
|
||||
add_definitions(-DASSIMP_USE_HUNTER)
|
||||
ENDIF()
|
||||
|
||||
|
@ -201,12 +200,9 @@ SET (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VER
|
|||
SET (ASSIMP_SOVERSION 5)
|
||||
|
||||
SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" )
|
||||
if(NOT ASSIMP_HUNTER_ENABLED)
|
||||
# Enable C++17 support globally
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
endif()
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
|
||||
IF(NOT ASSIMP_IGNORE_GIT_HASH)
|
||||
# Get the current working branch
|
||||
|
@ -254,8 +250,7 @@ IF( UNIX )
|
|||
# Use GNUInstallDirs for Unix predefined directories
|
||||
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
|
||||
IF( ${OPERATING_SYSTEM} MATCHES "Android")
|
||||
ELSE()
|
||||
IF(NOT ${OPERATING_SYSTEM} MATCHES "Android")
|
||||
IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux
|
||||
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 )
|
||||
ENDIF()
|
||||
|
@ -265,7 +260,6 @@ ENDIF()
|
|||
# Grouped compiler settings ########################################
|
||||
IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT MINGW)
|
||||
IF(NOT ASSIMP_HUNTER_ENABLED)
|
||||
SET(CMAKE_CXX_STANDARD 17)
|
||||
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
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")
|
||||
ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||
IF(NOT ASSIMP_HUNTER_ENABLED)
|
||||
SET(CMAKE_CXX_STANDARD 17)
|
||||
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
ENDIF()
|
||||
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long ${CMAKE_CXX_FLAGS}" )
|
||||
|
@ -327,17 +320,17 @@ ENDIF()
|
|||
|
||||
IF ( IOS AND NOT ASSIMP_HUNTER_ENABLED)
|
||||
IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -Og")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -Og")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -Og")
|
||||
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")
|
||||
# Experimental for pdb generation
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF (ASSIMP_COVERALLS)
|
||||
MESSAGE(STATUS "Coveralls enabled")
|
||||
|
||||
INCLUDE(Coveralls)
|
||||
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")
|
||||
|
@ -345,14 +338,16 @@ ENDIF()
|
|||
|
||||
IF (ASSIMP_ASAN)
|
||||
MESSAGE(STATUS "AddressSanitizer enabled")
|
||||
|
||||
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()
|
||||
|
||||
IF (ASSIMP_UBSAN)
|
||||
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_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()
|
||||
|
||||
INCLUDE (FindPkgMacros)
|
||||
|
@ -673,13 +668,13 @@ ELSE()
|
|||
set_target_properties(draco_encoder draco_decoder PROPERTIES
|
||||
EXCLUDE_FROM_ALL TRUE
|
||||
EXCLUDE_FROM_DEFAULT_BUILD TRUE
|
||||
)
|
||||
)
|
||||
|
||||
# Do build the draco shared library
|
||||
set_target_properties(${draco_LIBRARIES} PROPERTIES
|
||||
EXCLUDE_FROM_ALL FALSE
|
||||
EXCLUDE_FROM_DEFAULT_BUILD FALSE
|
||||
)
|
||||
)
|
||||
|
||||
TARGET_USE_COMMON_OUTPUT_DIRECTORY(${draco_LIBRARIES})
|
||||
TARGET_USE_COMMON_OUTPUT_DIRECTORY(draco_encoder)
|
||||
|
@ -696,8 +691,7 @@ ELSE()
|
|||
FRAMEWORK DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
|
||||
COMPONENT ${LIBASSIMP_COMPONENT}
|
||||
INCLUDES DESTINATION include
|
||||
)
|
||||
|
||||
)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
|
|
@ -102,10 +102,6 @@ void Structure::Convert<CollectionObject>(
|
|||
|
||||
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;
|
||||
ReadFieldPtr<ErrorPolicy_Igno>(ob, "*ob", db);
|
||||
dest.ob = ob.get();
|
||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
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
|
||||
* @brief A simple tessellation wrapper
|
||||
*/
|
||||
|
||||
/// @file BlenderTessellator.cpp
|
||||
/// @brief A simple tessellation wrapper
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
@ -144,7 +143,7 @@ namespace Assimp
|
|||
|
||||
#if ASSIMP_BLEND_WITH_POLY_2_TRI
|
||||
|
||||
#include "../contrib/poly2tri/poly2tri/poly2tri.h"
|
||||
#include "contrib/poly2tri/poly2tri/poly2tri.h"
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
|
|
|
@ -38,9 +38,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file IFCBoolean.cpp
|
||||
* @brief Implements a subset of Ifc boolean operations
|
||||
*/
|
||||
/// @file IFCBoolean.cpp
|
||||
/// @brief Implements a subset of Ifc boolean operations
|
||||
|
||||
#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 "PostProcessing/ProcessHelper.h"
|
||||
|
||||
|
||||
#include <iterator>
|
||||
#include <tuple>
|
||||
#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
|
||||
// point leaves the plane through the other side
|
||||
if (std::abs(dotOne + dotTwo) < ai_epsilon)
|
||||
if (std::abs(dotOne + dotTwo) < ai_epsilon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if segment starts on the plane, report a hit only if the end lies on the *other* side
|
||||
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
|
||||
// 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;
|
||||
}
|
||||
|
||||
// t must be in [0..1] if the intersection point is within the given segment
|
||||
const IfcFloat t = dotTwo / dotOne;
|
||||
if (t > 1.0 || t < 0.0)
|
||||
if (t > 1.0 || t < 0.0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
out = e0 + t * seg;
|
||||
return true;
|
||||
|
@ -110,11 +111,13 @@ void FilterPolygon(std::vector<IfcVector3> &resultpoly) {
|
|||
FuzzyVectorCompare fz(epsilon);
|
||||
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());
|
||||
}
|
||||
|
||||
if (!resultpoly.empty() && fz(resultpoly.front(), resultpoly.back()))
|
||||
if (!resultpoly.empty() && fz(resultpoly.front(), resultpoly.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
|
||||
if (endsAtSegment && !halfOpen)
|
||||
if (endsAtSegment && !halfOpen) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 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,
|
||||
|
@ -301,15 +305,17 @@ bool IntersectsBoundaryProfile(const IfcVector3 &e0, const IfcVector3 &e1, const
|
|||
if (startsAtSegment) {
|
||||
IfcVector3 inside_dir = IfcVector3(b.y, -b.x, 0.0) * windingOrder;
|
||||
bool isGoingInside = (inside_dir * e) > 0.0;
|
||||
if (isGoingInside == isStartAssumedInside)
|
||||
if (isGoingInside == isStartAssumedInside) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 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.
|
||||
if (!intersect_results.empty() && intersect_results.back().first == i - 1) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
intersect_results.emplace_back(i, e0);
|
||||
continue;
|
||||
|
@ -322,8 +328,9 @@ 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.
|
||||
if (!intersect_results.empty() && intersect_results.back().first == i - 1) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
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,
|
||||
ConversionData &conv) {
|
||||
ai_assert(as != nullptr);
|
||||
|
@ -763,4 +771,4 @@ void ProcessBoolean(const Schema_2x3::IfcBooleanResult &boolean, TempMesh &resul
|
|||
} // namespace IFC
|
||||
} // 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
|
||||
* @brief Read profile and curves entities from IFC files
|
||||
*/
|
||||
/// @file IFCProfile.cpp
|
||||
/// @brief Read profile and curves entities from IFC files
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||
#include "IFCUtil.h"
|
||||
|
||||
namespace Assimp {
|
||||
namespace IFC {
|
||||
|
||||
namespace {
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
@ -56,8 +56,7 @@ namespace {
|
|||
class Conic : public Curve {
|
||||
public:
|
||||
// --------------------------------------------------
|
||||
Conic(const Schema_2x3::IfcConic& entity, ConversionData& conv)
|
||||
: Curve(entity,conv) {
|
||||
Conic(const Schema_2x3::IfcConic& entity, ConversionData& conv) : Curve(entity,conv) {
|
||||
IfcMatrix4 trafo;
|
||||
ConvertAxisPlacement(trafo,*entity.Position,conv);
|
||||
|
||||
|
@ -99,15 +98,14 @@ protected:
|
|||
// --------------------------------------------------------------------------------
|
||||
// Circle
|
||||
// --------------------------------------------------------------------------------
|
||||
class Circle : public Conic {
|
||||
class Circle final : public Conic {
|
||||
public:
|
||||
// --------------------------------------------------
|
||||
Circle(const Schema_2x3::IfcCircle& entity, ConversionData& conv)
|
||||
: Conic(entity,conv)
|
||||
, entity(entity)
|
||||
{
|
||||
}
|
||||
|
||||
Circle(const Schema_2x3::IfcCircle& entity, ConversionData& conv) : Conic(entity,conv) , entity(entity) {}
|
||||
|
||||
// --------------------------------------------------
|
||||
~Circle() override = default;
|
||||
|
||||
// --------------------------------------------------
|
||||
IfcVector3 Eval(IfcFloat u) const {
|
||||
u = -conv.angle_scale * u;
|
||||
|
|
|
@ -38,11 +38,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file IFCGeometry.cpp
|
||||
* @brief Geometry conversion and synthesis for IFC
|
||||
*/
|
||||
|
||||
|
||||
/// @file IFCGeometry.cpp
|
||||
/// @brief Geometry conversion and synthesis for IFC
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||
#include "IFCUtil.h"
|
||||
|
@ -59,8 +56,7 @@ namespace Assimp {
|
|||
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;
|
||||
for(const Schema_2x3::IfcCartesianPoint& c : loop.Polygon) {
|
||||
IfcVector3 tmp;
|
||||
|
@ -85,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
|
||||
if(inmesh.mVertcnt.empty()) {
|
||||
return;
|
||||
|
@ -121,8 +116,7 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m
|
|||
if (master_bounds != (size_t)-1) {
|
||||
ai_assert(master_bounds < inmesh.mVertcnt.size());
|
||||
outer_polygon_it = begin + master_bounds;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
for(iit = begin; iit != end; ++iit) {
|
||||
// find the polygon with the largest area and take it as the outer bound.
|
||||
IfcVector3& n = normals[std::distance(begin,iit)];
|
||||
|
@ -133,7 +127,8 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m
|
|||
}
|
||||
}
|
||||
}
|
||||
if (outer_polygon_it == end) {
|
||||
|
||||
if (outer_polygon_it == end) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -199,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(ProcessPolyloop(*polyloop, meshout,conv)) {
|
||||
|
||||
// The outer boundary is better determined by checking which
|
||||
// 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());
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessRevolvedAreaSolid(const Schema_2x3::IfcRevolvedAreaSolid& solid, TempMesh& result, ConversionData& conv)
|
||||
{
|
||||
void ProcessRevolvedAreaSolid(const Schema_2x3::IfcRevolvedAreaSolid& solid, TempMesh& result, ConversionData& conv) {
|
||||
TempMesh meshout;
|
||||
|
||||
// first read the profile description
|
||||
|
@ -259,7 +234,8 @@ void ProcessRevolvedAreaSolid(const Schema_2x3::IfcRevolvedAreaSolid& solid, Tem
|
|||
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;
|
||||
|
||||
has_area = has_area && std::fabs(max_angle) < AI_MATH_TWO_PI_F*0.99;
|
||||
|
@ -318,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);
|
||||
if(!curve) {
|
||||
IFCImporter::LogError("failed to convert Directrix curve (IfcSweptDiskSolid)");
|
||||
|
@ -454,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;
|
||||
IfcMatrix3 m;
|
||||
|
||||
|
@ -498,10 +474,6 @@ IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVect
|
|||
IfcVector3 r = (out[idx]-any_point);
|
||||
r.Normalize();
|
||||
|
||||
//if(d) {
|
||||
// *d = -any_point * nor;
|
||||
//}
|
||||
|
||||
// Reconstruct orthonormal basis
|
||||
// XXX use Gram Schmidt for increased robustness
|
||||
IfcVector3 u = r ^ nor;
|
||||
|
@ -525,8 +497,7 @@ IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVect
|
|||
const auto closeDistance = ai_epsilon;
|
||||
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
|
@ -534,10 +505,10 @@ bool areClose(Schema_2x3::IfcCartesianPoint pt1,Schema_2x3::IfcCartesianPoint pt
|
|||
auto coord2 = pt2.Coordinates.begin();
|
||||
// we're just testing each dimension separately rather than doing euclidean distance, as we're
|
||||
// looking for very close coordinates
|
||||
for(; coord1 != pt1.Coordinates.end(); coord1++,coord2++)
|
||||
{
|
||||
if(std::fabs(*coord1 - *coord2) > closeDistance)
|
||||
for(; coord1 != pt1.Coordinates.end(); coord1++,coord2++) {
|
||||
if(std::fabs(*coord1 - *coord2) > closeDistance) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -547,6 +518,7 @@ bool areClose(IfcVector3 pt1,IfcVector3 pt2) {
|
|||
std::fabs(pt1.y - pt2.y) < 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.
|
||||
void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const TempMesh& curve,
|
||||
const IfcVector3& extrusionDir, TempMesh& result, ConversionData &conv, bool collect_openings)
|
||||
|
@ -584,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
|
||||
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::vector<IfcVector3> nors;
|
||||
const bool openings = !!conv.apply_openings && conv.apply_openings->size();
|
||||
|
@ -672,8 +645,7 @@ void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const Te
|
|||
if(n > 0) {
|
||||
for(size_t i = 0; i < in.size(); ++i)
|
||||
out.push_back(in[i] + dir);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
for(size_t i = in.size(); i--; )
|
||||
out.push_back(in[i]);
|
||||
}
|
||||
|
@ -715,9 +687,10 @@ void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const Te
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessExtrudedAreaSolid(const Schema_2x3::IfcExtrudedAreaSolid& solid, TempMesh& result,
|
||||
ConversionData& conv, bool collect_openings)
|
||||
{
|
||||
void ProcessExtrudedAreaSolid(const Schema_2x3::IfcExtrudedAreaSolid& solid,
|
||||
TempMesh& result,
|
||||
ConversionData& conv,
|
||||
bool collect_openings) {
|
||||
TempMesh meshout;
|
||||
|
||||
// First read the profile description.
|
||||
|
@ -755,24 +728,23 @@ void ProcessExtrudedAreaSolid(const Schema_2x3::IfcExtrudedAreaSolid& solid, Tem
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessSweptAreaSolid(const Schema_2x3::IfcSweptAreaSolid& swept, TempMesh& meshout,
|
||||
ConversionData& conv)
|
||||
{
|
||||
void ProcessSweptAreaSolid(const Schema_2x3::IfcSweptAreaSolid& swept,
|
||||
TempMesh& meshout,
|
||||
ConversionData& conv) {
|
||||
if(const Schema_2x3::IfcExtrudedAreaSolid* const solid = swept.ToPtr<Schema_2x3::IfcExtrudedAreaSolid>()) {
|
||||
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);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
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,
|
||||
ConversionData& conv)
|
||||
{
|
||||
bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo,
|
||||
unsigned int matid,
|
||||
std::set<unsigned int>& mesh_indices,
|
||||
ConversionData& conv) {
|
||||
bool fix_orientation = false;
|
||||
std::shared_ptr< TempMesh > meshtmp = std::make_shared<TempMesh>();
|
||||
if(const Schema_2x3::IfcShellBasedSurfaceModel* shellmod = geo.ToPtr<Schema_2x3::IfcShellBasedSurfaceModel>()) {
|
||||
|
@ -782,41 +754,32 @@ bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo, unsigned
|
|||
const Schema_2x3::IfcConnectedFaceSet& fs = conv.db.MustGetObject(e).To<Schema_2x3::IfcConnectedFaceSet>();
|
||||
|
||||
ProcessConnectedFaceSet(fs, *meshtmp, conv);
|
||||
}
|
||||
catch(std::bad_cast&) {
|
||||
} catch(std::bad_cast&) {
|
||||
IFCImporter::LogWarn("unexpected type error, IfcShell ought to inherit from IfcConnectedFaceSet");
|
||||
}
|
||||
}
|
||||
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);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
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) {
|
||||
ProcessConnectedFaceSet(fc, *meshtmp, conv);
|
||||
}
|
||||
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);
|
||||
}
|
||||
else if(geo.ToPtr<Schema_2x3::IfcBoundingBox>()) {
|
||||
} else if(geo.ToPtr<Schema_2x3::IfcBoundingBox>()) {
|
||||
// silently skip over bounding boxes
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
std::stringstream toLog;
|
||||
toLog << "skipping unknown IfcGeometricRepresentationItem entity, type is " << geo.GetClassName() << " id is " << geo.GetID();
|
||||
IFCImporter::LogWarn(toLog.str().c_str());
|
||||
|
@ -862,9 +825,7 @@ bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo, unsigned
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void AssignAddedMeshes(std::set<unsigned int>& mesh_indices,aiNode* nd,
|
||||
ConversionData& /*conv*/)
|
||||
{
|
||||
void AssignAddedMeshes(std::set<unsigned int>& mesh_indices,aiNode* nd, ConversionData& /*conv*/) {
|
||||
if (!mesh_indices.empty()) {
|
||||
std::set<unsigned int>::const_iterator it = mesh_indices.cbegin();
|
||||
std::set<unsigned int>::const_iterator end = mesh_indices.cend();
|
||||
|
@ -880,9 +841,9 @@ void AssignAddedMeshes(std::set<unsigned int>& mesh_indices,aiNode* nd,
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool TryQueryMeshCache(const Schema_2x3::IfcRepresentationItem& item,
|
||||
std::set<unsigned int>& mesh_indices, unsigned int mat_index,
|
||||
ConversionData& conv)
|
||||
{
|
||||
std::set<unsigned int>& mesh_indices,
|
||||
unsigned int mat_index,
|
||||
ConversionData& conv) {
|
||||
ConversionData::MeshCacheIndex idx(&item, mat_index);
|
||||
ConversionData::MeshCache::const_iterator it = conv.cached_meshes.find(idx);
|
||||
if (it != conv.cached_meshes.end()) {
|
||||
|
@ -894,18 +855,18 @@ bool TryQueryMeshCache(const Schema_2x3::IfcRepresentationItem& item,
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void PopulateMeshCache(const Schema_2x3::IfcRepresentationItem& item,
|
||||
const std::set<unsigned int>& mesh_indices, unsigned int mat_index,
|
||||
ConversionData& conv)
|
||||
{
|
||||
const std::set<unsigned int>& mesh_indices,
|
||||
unsigned int mat_index,
|
||||
ConversionData& conv) {
|
||||
ConversionData::MeshCacheIndex idx(&item, mat_index);
|
||||
conv.cached_meshes[idx] = mesh_indices;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool ProcessRepresentationItem(const Schema_2x3::IfcRepresentationItem& item, unsigned int matid,
|
||||
std::set<unsigned int>& mesh_indices,
|
||||
ConversionData& conv)
|
||||
{
|
||||
bool ProcessRepresentationItem(const Schema_2x3::IfcRepresentationItem& item,
|
||||
unsigned int matid,
|
||||
std::set<unsigned int>& mesh_indices,
|
||||
ConversionData& conv) {
|
||||
// determine material
|
||||
unsigned int localmatid = ProcessMaterials(item.GetID(), matid, conv, true);
|
||||
|
||||
|
@ -914,8 +875,9 @@ bool ProcessRepresentationItem(const Schema_2x3::IfcRepresentationItem& item, un
|
|||
if(mesh_indices.size()) {
|
||||
PopulateMeshCache(item,mesh_indices,localmatid,conv);
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -924,4 +886,4 @@ bool ProcessRepresentationItem(const Schema_2x3::IfcRepresentationItem& item, un
|
|||
} // ! IFC
|
||||
} // ! Assimp
|
||||
|
||||
#endif
|
||||
#endif // ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
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
|
||||
* @brief Implementation of the Industry Foundation Classes loader.
|
||||
*/
|
||||
/// @file IFCLoad.cpp
|
||||
/// @brief Implementation of the Industry Foundation Classes loader.
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||
|
||||
|
@ -92,7 +90,6 @@ using namespace Assimp::IFC;
|
|||
IfcUnitAssignment
|
||||
IfcClosedShell
|
||||
IfcDoor
|
||||
|
||||
*/
|
||||
|
||||
namespace {
|
||||
|
@ -119,14 +116,6 @@ static const aiImporterDesc desc = {
|
|||
"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.
|
||||
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
|
||||
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
|
||||
|
@ -928,4 +922,4 @@ void MakeTreeRelative(ConversionData &conv) {
|
|||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
#endif // ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||
|
|
|
@ -87,8 +87,8 @@ public:
|
|||
int cylindricalTessellation;
|
||||
};
|
||||
|
||||
IFCImporter();
|
||||
~IFCImporter() override;
|
||||
IFCImporter() = default;
|
||||
~IFCImporter() override = default;
|
||||
|
||||
// --------------------
|
||||
bool CanRead(const std::string &pFile,
|
||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
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
|
||||
* @brief Implementation of conversion routines to convert IFC materials to aiMaterial
|
||||
*/
|
||||
/// @file IFCMaterial.cpp
|
||||
/// @brief Implementation of conversion routines to convert IFC materials to aiMaterial
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||
|
||||
|
@ -174,7 +172,6 @@ unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionDat
|
|||
|
||||
aiString name;
|
||||
name.Set("<IFCDefault>");
|
||||
// ConvertColorToString( color, name);
|
||||
|
||||
// look if there's already a default material with this base color
|
||||
for( size_t a = 0; a < conv.materials.size(); ++a ) {
|
||||
|
|
|
@ -47,14 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "IFCUtil.h"
|
||||
#include "Common/PolyTools.h"
|
||||
#include "PostProcessing/ProcessHelper.h"
|
||||
|
||||
//#ifdef ASSIMP_USE_HUNTER
|
||||
//# include <poly2tri/poly2tri.h>
|
||||
//# include <polyclipping/clipper.hpp>
|
||||
//#else
|
||||
# include "contrib/poly2tri/poly2tri/poly2tri.h"
|
||||
# include "contrib/clipper/clipper.hpp"
|
||||
//#endif // ASSIMP_USE_HUNTER
|
||||
#include "contrib/poly2tri/poly2tri/poly2tri.h"
|
||||
#include "contrib/clipper/clipper.hpp"
|
||||
|
||||
#include <deque>
|
||||
#include <forward_list>
|
||||
|
@ -69,14 +63,21 @@ using ClipperLib::ulong64;
|
|||
// XXX use full -+ range ...
|
||||
const ClipperLib::long64 max_ulong64 = 1518500249; // clipper.cpp / hiRange var
|
||||
|
||||
inline ulong64 to_int64(IfcFloat p) {
|
||||
AI_FORCE_INLINE ulong64 to_int64(IfcFloat p) {
|
||||
return (static_cast<ulong64>(static_cast<IfcFloat>((p) ) * max_ulong64 ));
|
||||
}
|
||||
|
||||
inline IfcFloat from_int64(ulong64 p) {
|
||||
AI_FORCE_INLINE IfcFloat from_int64(ulong64 p) {
|
||||
return (static_cast<IfcFloat>((p)) / max_ulong64);
|
||||
}
|
||||
|
||||
AI_FORCE_INLINE void fillRectangle(const IfcVector2& pmin, const IfcVector2& pmax, std::vector<IfcVector2>& out) {
|
||||
out.emplace_back(pmin.x, pmin.y);
|
||||
out.emplace_back(pmin.x, pmax.y);
|
||||
out.emplace_back(pmax.x, pmax.y);
|
||||
out.emplace_back(pmax.x, pmin.y);
|
||||
}
|
||||
|
||||
const IfcVector2 one_vec(IfcVector2(static_cast<IfcFloat>(1.0),static_cast<IfcFloat>(1.0)));
|
||||
|
||||
// fallback method to generate wall openings
|
||||
|
@ -114,10 +115,7 @@ void QuadrifyPart(const IfcVector2& pmin, const IfcVector2& pmax, XYSortedField&
|
|||
|
||||
if (!found) {
|
||||
// the rectangle [pmin,pend] is opaque, fill it
|
||||
out.push_back(pmin);
|
||||
out.emplace_back(pmin.x,pmax.y);
|
||||
out.push_back(pmax);
|
||||
out.emplace_back(pmax.x,pmin.y);
|
||||
fillRectangle(pmin, pmax, out);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -181,6 +179,8 @@ struct ProjectedWindowContour {
|
|||
ProjectedWindowContour(const Contour& contour, const BoundingBox& bb, bool is_rectangular)
|
||||
: contour(contour), bb(bb) , is_rectangular(is_rectangular) {}
|
||||
|
||||
~ProjectedWindowContour() = default;
|
||||
|
||||
bool IsInvalid() const {
|
||||
return contour.empty();
|
||||
}
|
||||
|
@ -362,7 +362,8 @@ void InsertWindowContours(const ContourVector& contours, const std::vector<TempO
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void MergeWindowContours (const std::vector<IfcVector2>& a, const std::vector<IfcVector2>& b, ClipperLib::Paths& out) {
|
||||
void MergeWindowContours (const std::vector<IfcVector2>& a, const std::vector<IfcVector2>& b,
|
||||
ClipperLib::Paths& out) {
|
||||
out.clear();
|
||||
|
||||
ClipperLib::Clipper clipper;
|
||||
|
@ -394,14 +395,12 @@ void MergeWindowContours (const std::vector<IfcVector2>& a, const std::vector<If
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Subtract a from b
|
||||
void MakeDisjunctWindowContours (const std::vector<IfcVector2>& a,
|
||||
const std::vector<IfcVector2>& b,
|
||||
ClipperLib::Paths& out)
|
||||
{
|
||||
const std::vector<IfcVector2>& b,
|
||||
ClipperLib::Paths& out) {
|
||||
out.clear();
|
||||
|
||||
ClipperLib::Clipper clipper;
|
||||
ClipperLib::Path clip;
|
||||
|
||||
for(const IfcVector2& pip : a) {
|
||||
clip.emplace_back(to_int64(pip.x), to_int64(pip.y));
|
||||
}
|
||||
|
@ -454,8 +453,8 @@ void CleanupWindowContour(ProjectedWindowContour& window) {
|
|||
IFCImporter::LogError("error during polygon clipping, window contour is not convex");
|
||||
}
|
||||
|
||||
ExtractVerticesFromClipper(clipped[0], scratch);
|
||||
// Assume the bounding box doesn't change during this operation
|
||||
ExtractVerticesFromClipper(clipped[0], scratch);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -543,13 +542,11 @@ void CleanupOuterContour(const std::vector<IfcVector2>& contour_flat, TempMesh&
|
|||
std::swap(iold,curmesh.mVertcnt);
|
||||
}
|
||||
|
||||
typedef std::vector<TempOpening*> OpeningRefs;
|
||||
typedef std::vector<OpeningRefs > OpeningRefVector;
|
||||
|
||||
typedef std::vector<std::pair<
|
||||
using OpeningRefs = std::vector<TempOpening*> ;
|
||||
using OpeningRefVector = std::vector<OpeningRefs >;
|
||||
using ContourRefVector = std::vector<std::pair<
|
||||
ContourVector::const_iterator,
|
||||
Contour::const_iterator>
|
||||
> ContourRefVector;
|
||||
Contour::const_iterator> >;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool BoundingBoxesAdjacent(const BoundingBox& bb, const BoundingBox& ibb) {
|
||||
|
@ -565,9 +562,8 @@ bool BoundingBoxesAdjacent(const BoundingBox& bb, const BoundingBox& ibb) {
|
|||
// Check if m0,m1 intersects n0,n1 assuming same ordering of the points in the line segments
|
||||
// output the intersection points on n0,n1
|
||||
bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1,
|
||||
const IfcVector2& m0, const IfcVector2& m1,
|
||||
IfcVector2& out0, IfcVector2& out1)
|
||||
{
|
||||
const IfcVector2& m0, const IfcVector2& m1,
|
||||
IfcVector2& out0, IfcVector2& out1) {
|
||||
const IfcVector2 n0_to_n1 = n1 - n0;
|
||||
|
||||
const IfcVector2 n0_to_m0 = m0 - n0;
|
||||
|
@ -639,8 +635,7 @@ bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1,
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void FindAdjacentContours(ContourVector::iterator current, const ContourVector& contours)
|
||||
{
|
||||
void FindAdjacentContours(ContourVector::iterator current, const ContourVector& contours) {
|
||||
const IfcFloat sqlen_epsilon = static_cast<IfcFloat>(Math::getEpsilon<float>());
|
||||
const BoundingBox& bb = (*current).bb;
|
||||
|
||||
|
@ -655,13 +650,6 @@ void FindAdjacentContours(ContourVector::iterator current, const ContourVector&
|
|||
continue;
|
||||
}
|
||||
|
||||
// this left here to make clear we also run on the current contour
|
||||
// to check for overlapping contour segments (which can happen due
|
||||
// to projection artifacts).
|
||||
//if(it == current) {
|
||||
// continue;
|
||||
//}
|
||||
|
||||
const bool is_me = it == current;
|
||||
|
||||
const BoundingBox& ibb = (*it).bb;
|
||||
|
@ -697,8 +685,7 @@ void FindAdjacentContours(ContourVector::iterator current, const ContourVector&
|
|||
|
||||
ncontour.insert(ncontour.begin() + n, isect0);
|
||||
skiplist.insert(skiplist.begin() + n, true);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
skiplist[n] = true;
|
||||
}
|
||||
|
||||
|
@ -716,15 +703,13 @@ void FindAdjacentContours(ContourVector::iterator current, const ContourVector&
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE bool LikelyBorder(const IfcVector2& vdelta)
|
||||
{
|
||||
AI_FORCE_INLINE bool LikelyBorder(const IfcVector2& vdelta) {
|
||||
const IfcFloat dot_point_epsilon = static_cast<IfcFloat>(Math::getEpsilon<float>());
|
||||
return std::fabs(vdelta.x * vdelta.y) < dot_point_epsilon;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void FindBorderContours(ContourVector::iterator current)
|
||||
{
|
||||
void FindBorderContours(ContourVector::iterator current) {
|
||||
const IfcFloat border_epsilon_upper = static_cast<IfcFloat>(1-1e-4);
|
||||
const IfcFloat border_epsilon_lower = static_cast<IfcFloat>(1e-4);
|
||||
|
||||
|
@ -744,20 +729,17 @@ void FindBorderContours(ContourVector::iterator current)
|
|||
// not have any geometry to close them (think of door openings).
|
||||
if (proj_point.x <= border_epsilon_lower || proj_point.x >= border_epsilon_upper ||
|
||||
proj_point.y <= border_epsilon_lower || proj_point.y >= border_epsilon_upper) {
|
||||
|
||||
if (outer_border) {
|
||||
ai_assert(cit != cbegin);
|
||||
if (LikelyBorder(proj_point - last_proj_point)) {
|
||||
skiplist[std::distance(cbegin, cit) - 1] = true;
|
||||
}
|
||||
}
|
||||
else if (cit == cbegin) {
|
||||
} else if (cit == cbegin) {
|
||||
start_on_outer_border = true;
|
||||
}
|
||||
|
||||
outer_border = true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
outer_border = false;
|
||||
}
|
||||
|
||||
|
@ -774,16 +756,14 @@ void FindBorderContours(ContourVector::iterator current)
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE bool LikelyDiagonal(IfcVector2 vdelta)
|
||||
{
|
||||
AI_FORCE_INLINE bool LikelyDiagonal(IfcVector2 vdelta) {
|
||||
vdelta.x = std::fabs(vdelta.x);
|
||||
vdelta.y = std::fabs(vdelta.y);
|
||||
return (std::fabs(vdelta.x-vdelta.y) < 0.8 * std::max(vdelta.x, vdelta.y));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void FindLikelyCrossingLines(ContourVector::iterator current)
|
||||
{
|
||||
void FindLikelyCrossingLines(ContourVector::iterator current) {
|
||||
SkipList& skiplist = (*current).skiplist;
|
||||
IfcVector2 last_proj_point;
|
||||
|
||||
|
@ -809,10 +789,9 @@ void FindLikelyCrossingLines(ContourVector::iterator current)
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
size_t CloseWindows(ContourVector& contours,
|
||||
const IfcMatrix4& minv,
|
||||
OpeningRefVector& contours_to_openings,
|
||||
TempMesh& curmesh)
|
||||
{
|
||||
const IfcMatrix4& minv,
|
||||
OpeningRefVector& contours_to_openings,
|
||||
TempMesh& curmesh) {
|
||||
size_t closed = 0;
|
||||
// For all contour points, check if one of the assigned openings does
|
||||
// already have points assigned to it. In this case, assume this is
|
||||
|
@ -921,8 +900,7 @@ size_t CloseWindows(ContourVector& contours,
|
|||
if (drop_this_edge) {
|
||||
curmesh.mVerts.pop_back();
|
||||
curmesh.mVerts.pop_back();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
curmesh.mVerts.push_back(((cit == cbegin) != reverseCountourFaces) ? world_point : bestv);
|
||||
curmesh.mVerts.push_back(((cit == cbegin) != reverseCountourFaces) ? bestv : world_point);
|
||||
|
||||
|
@ -949,16 +927,13 @@ size_t CloseWindows(ContourVector& contours,
|
|||
curmesh.mVertcnt.pop_back();
|
||||
curmesh.mVerts.pop_back();
|
||||
curmesh.mVerts.pop_back();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
curmesh.mVerts.push_back(reverseCountourFaces ? start0 : start1);
|
||||
curmesh.mVerts.push_back(reverseCountourFaces ? start1 : start0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
} else {
|
||||
const Contour::const_iterator cbegin = (*it).contour.begin(), cend = (*it).contour.end();
|
||||
for(TempOpening* opening : refs) {
|
||||
ai_assert(opening->wallPoints.empty());
|
||||
|
@ -975,8 +950,7 @@ size_t CloseWindows(ContourVector& contours,
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Quadrify(const std::vector< BoundingBox >& bbs, TempMesh& curmesh)
|
||||
{
|
||||
void Quadrify(const std::vector< BoundingBox >& bbs, TempMesh& curmesh) {
|
||||
ai_assert(curmesh.IsEmpty());
|
||||
|
||||
std::vector<IfcVector2> quads;
|
||||
|
@ -1002,8 +976,7 @@ void Quadrify(const std::vector< BoundingBox >& bbs, TempMesh& curmesh)
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Quadrify(const ContourVector& contours, TempMesh& curmesh)
|
||||
{
|
||||
void Quadrify(const ContourVector& contours, TempMesh& curmesh) {
|
||||
std::vector<BoundingBox> bbs;
|
||||
bbs.reserve(contours.size());
|
||||
|
||||
|
@ -1015,12 +988,17 @@ void Quadrify(const ContourVector& contours, TempMesh& curmesh)
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh& in_mesh,
|
||||
bool &ok, IfcVector3& nor_out)
|
||||
{
|
||||
IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour,
|
||||
const TempMesh& in_mesh,
|
||||
bool &ok,
|
||||
IfcVector3& nor_out) {
|
||||
const std::vector<IfcVector3>& in_verts = in_mesh.mVerts;
|
||||
if (in_verts.empty()){
|
||||
ok = false;
|
||||
return IfcMatrix4();
|
||||
}
|
||||
|
||||
ok = true;
|
||||
|
||||
IfcMatrix4 m = IfcMatrix4(DerivePlaneCoordinateSpace(in_mesh, ok, nor_out));
|
||||
if(!ok) {
|
||||
return IfcMatrix4();
|
||||
|
@ -1033,7 +1011,6 @@ IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh
|
|||
IfcFloat zcoord = 0;
|
||||
out_contour.reserve(in_verts.size());
|
||||
|
||||
|
||||
IfcVector3 vmin, vmax;
|
||||
MinMaxChooser<IfcVector3>()(vmin, vmax);
|
||||
|
||||
|
@ -1044,11 +1021,6 @@ IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh
|
|||
// (which are present, of course), this should be the same value for
|
||||
// all polygon vertices (assuming the polygon is planar).
|
||||
|
||||
// XXX this should be guarded, but we somehow need to pick a suitable
|
||||
// epsilon
|
||||
// if(coord != -1.0f) {
|
||||
// assert(std::fabs(coord - vv.z) < 1e-3f);
|
||||
// }
|
||||
zcoord += vv.z;
|
||||
vmin = std::min(vv, vmin);
|
||||
vmax = std::max(vv, vmax);
|
||||
|
@ -1100,11 +1072,10 @@ IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool GenerateOpenings(std::vector<TempOpening>& openings,
|
||||
TempMesh& curmesh,
|
||||
bool check_intersection,
|
||||
bool generate_connection_geometry,
|
||||
const IfcVector3& wall_extrusion_axis)
|
||||
{
|
||||
TempMesh& curmesh,
|
||||
bool check_intersection,
|
||||
bool generate_connection_geometry,
|
||||
const IfcVector3& wall_extrusion_axis) {
|
||||
OpeningRefVector contours_to_openings;
|
||||
|
||||
// Try to derive a solid base plane within the current surface for use as
|
||||
|
@ -1140,8 +1111,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
|||
IfcVector3 norm_extrusion_dir = opening.extrusionDir;
|
||||
if (norm_extrusion_dir.SquareLength() > 1e-10) {
|
||||
norm_extrusion_dir.Normalize();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
norm_extrusion_dir = IfcVector3();
|
||||
}
|
||||
|
||||
|
@ -1206,10 +1176,8 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
|||
const IfcVector3 v = m * x;
|
||||
IfcVector2 vv(v.x, v.y);
|
||||
|
||||
//if(check_intersection) {
|
||||
dmin = std::min(dmin, v.z);
|
||||
dmax = std::max(dmax, v.z);
|
||||
//}
|
||||
dmin = std::min(dmin, v.z);
|
||||
dmax = std::max(dmax, v.z);
|
||||
|
||||
// sanity rounding
|
||||
vv = std::max(vv,IfcVector2());
|
||||
|
@ -1218,8 +1186,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
|||
if(side_flag) {
|
||||
vpmin = std::min(vpmin,vv);
|
||||
vpmax = std::max(vpmax,vv);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
vpmin2 = std::min(vpmin2,vv);
|
||||
vpmax2 = std::max(vpmax2,vv);
|
||||
}
|
||||
|
@ -1267,9 +1234,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
|||
// See if this BB intersects or is in close adjacency to any other BB we have so far.
|
||||
for (ContourVector::iterator it = contours.begin(); it != contours.end(); ) {
|
||||
const BoundingBox& ibb = (*it).bb;
|
||||
|
||||
if (BoundingBoxesOverlapping(ibb, bb)) {
|
||||
|
||||
if (!(*it).is_rectangular) {
|
||||
is_rectangle = false;
|
||||
}
|
||||
|
@ -1282,7 +1247,6 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
|||
// no longer overlaps ibb
|
||||
MakeDisjunctWindowContours(other, temp_contour, poly);
|
||||
if(poly.size() == 1) {
|
||||
|
||||
const BoundingBox newbb = GetBoundingBox(poly[0]);
|
||||
if (!BoundingBoxesOverlapping(ibb, newbb )) {
|
||||
// Good guy bounding box
|
||||
|
@ -1384,9 +1348,14 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
|||
return true;
|
||||
}
|
||||
|
||||
std::vector<IfcVector2> GetContourInPlane2D(const std::shared_ptr<TempMesh>& mesh,IfcMatrix3 planeSpace,
|
||||
IfcVector3 planeNor,IfcFloat planeOffset,
|
||||
IfcVector3 extrusionDir,IfcVector3& wall_extrusion,bool& first,bool& ok) {
|
||||
std::vector<IfcVector2> GetContourInPlane2D(const std::shared_ptr<TempMesh>& mesh,
|
||||
IfcMatrix3 planeSpace,
|
||||
IfcVector3 planeNor,
|
||||
IfcFloat planeOffset,
|
||||
IfcVector3 extrusionDir,
|
||||
IfcVector3& wall_extrusion,
|
||||
bool& first,
|
||||
bool& ok) {
|
||||
std::vector<IfcVector2> contour;
|
||||
|
||||
const auto outernor = ((mesh->mVerts[2] - mesh->mVerts[0]) ^ (mesh->mVerts[1] - mesh->mVerts[0])).Normalize();
|
||||
|
@ -1475,8 +1444,8 @@ std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(const std::shared_ptr<
|
|||
IFCImporter::LogInfo(msg.str().c_str());
|
||||
}
|
||||
|
||||
if(nVertices <= 2) // not a plane, a point or line
|
||||
{
|
||||
// not a plane, a point or line
|
||||
if(nVertices <= 2) {
|
||||
std::stringstream msg;
|
||||
msg << "GetContoursInPlane3D: found point or line when expecting plane (only " << nVertices << " vertices)";
|
||||
IFCImporter::LogWarn(msg.str().c_str());
|
||||
|
@ -1640,29 +1609,28 @@ std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(const std::shared_ptr<
|
|||
return contours;
|
||||
}
|
||||
|
||||
std::vector<std::vector<IfcVector2>> GetContoursInPlane(const std::shared_ptr<TempMesh>& mesh,IfcMatrix3 planeSpace,
|
||||
IfcVector3 planeNor,IfcFloat planeOffset,
|
||||
IfcVector3 extrusionDir,IfcVector3& wall_extrusion,bool& first) {
|
||||
|
||||
if(mesh->mVertcnt.size() == 1)
|
||||
{
|
||||
std::vector<std::vector<IfcVector2>> GetContoursInPlane(const std::shared_ptr<TempMesh>& mesh,
|
||||
IfcMatrix3 planeSpace,
|
||||
IfcVector3 planeNor,
|
||||
IfcFloat planeOffset,
|
||||
IfcVector3 extrusionDir,
|
||||
IfcVector3& wall_extrusion,
|
||||
bool& first) {
|
||||
if(mesh->mVertcnt.size() == 1) {
|
||||
bool ok;
|
||||
auto contour = GetContourInPlane2D(mesh,planeSpace,planeNor,planeOffset,extrusionDir,wall_extrusion,first,ok);
|
||||
if(ok)
|
||||
return std::vector<std::vector<IfcVector2>> {std::move(contour)};
|
||||
else
|
||||
return std::vector<std::vector<IfcVector2>> {};
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return GetContoursInPlane3D(mesh,planeSpace,planeOffset);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
||||
TempMesh& curmesh)
|
||||
{
|
||||
TempMesh& curmesh) {
|
||||
IFCImporter::LogWarn("forced to use poly2tri fallback method to generate wall openings");
|
||||
std::vector<IfcVector3>& out = curmesh.mVerts;
|
||||
|
||||
|
@ -1695,14 +1663,6 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
|||
// keep Z offset in the plane coordinate system. Ignoring precision issues
|
||||
// (which are present, of course), this should be the same value for
|
||||
// all polygon vertices (assuming the polygon is planar).
|
||||
|
||||
|
||||
// XXX this should be guarded, but we somehow need to pick a suitable
|
||||
// epsilon
|
||||
// if(coord != -1.0f) {
|
||||
// assert(std::fabs(coord - vv.z) < 1e-3f);
|
||||
// }
|
||||
|
||||
coord = vv.z;
|
||||
|
||||
vmin = std::min(IfcVector2(vv.x, vv.y), vmin);
|
||||
|
@ -1744,15 +1704,8 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
|||
|
||||
if(!ClipperLib::Orientation(hole)) {
|
||||
std::reverse(hole.begin(),hole.end());
|
||||
// assert(ClipperLib::Orientation(hole));
|
||||
}
|
||||
|
||||
/*ClipperLib::Polygons pol_temp(1), pol_temp2(1);
|
||||
pol_temp[0] = hole;
|
||||
|
||||
ClipperLib::OffsetPolygons(pol_temp,pol_temp2,5.0);
|
||||
hole = pol_temp2[0];*/
|
||||
|
||||
clipper_holes.AddPath(hole,ClipperLib::ptSubject, true);
|
||||
{
|
||||
std::stringstream msg;
|
||||
|
@ -1795,7 +1748,6 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
|||
ClipperLib::pftNonZero,
|
||||
ClipperLib::pftNonZero);
|
||||
}
|
||||
|
||||
} catch (const char* sx) {
|
||||
IFCImporter::LogError("Ifc: error during polygon clipping, skipping openings for this face: (Clipper: "
|
||||
+ std::string(sx) + ")");
|
||||
|
@ -1827,14 +1779,12 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
|||
// happen in production use if the input data is broken. An assertion would be
|
||||
// inappropriate.
|
||||
cdt = new p2t::CDT(contour_points);
|
||||
}
|
||||
catch(const std::exception& e) {
|
||||
} catch(const std::exception& e) {
|
||||
IFCImporter::LogError("Ifc: error during polygon triangulation, skipping some openings: (poly2tri: "
|
||||
+ std::string(e.what()) + ")");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Build the poly2tri inner contours for all holes we got from ClipperLib
|
||||
for(ClipperLib::Path& opening : holes_union) {
|
||||
|
||||
|
@ -1851,8 +1801,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
|||
try {
|
||||
// Note: See above
|
||||
cdt->Triangulate();
|
||||
}
|
||||
catch(const std::exception& e) {
|
||||
} catch(const std::exception& e) {
|
||||
IFCImporter::LogError("Ifc: error during polygon triangulation, skipping some openings: (poly2tri: "
|
||||
+ std::string(e.what()) + ")");
|
||||
continue;
|
||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
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
|
||||
* @brief Read profile and curves entities from IFC files
|
||||
*/
|
||||
/// @file IFCProfile.cpp
|
||||
/// @brief Read profile and curves entities from IFC files
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||
|
||||
|
@ -52,8 +50,9 @@ namespace Assimp {
|
|||
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
|
||||
IfcVector3 t;
|
||||
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));
|
||||
if (!cv) {
|
||||
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);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
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);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
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>()) {
|
||||
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.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>()) {
|
||||
// TODO
|
||||
}
|
||||
|
@ -129,8 +131,7 @@ void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& de
|
|||
}
|
||||
|
||||
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
|
||||
const IfcFloat offset = (ishape->OverallWidth - ishape->WebThickness) / 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.mVertcnt.push_back(12);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
IFCImporter::LogWarn("skipping unknown IfcParameterizedProfileDef entity, type is ", def.GetClassName());
|
||||
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>()) {
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
IFCImporter::LogWarn("skipping unknown IfcProfileDef entity, type is ", prof.GetClassName());
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
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
|
||||
* @brief Implementation of conversion routines for some common Ifc helper entities.
|
||||
*/
|
||||
/// @file IFCUtil.cpp
|
||||
/// @brief Implementation of conversion routines for some common Ifc helper entities.
|
||||
|
||||
#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)));
|
||||
|
||||
if (mVerts.empty()) {
|
||||
|
@ -105,36 +102,31 @@ aiMesh* TempMesh::ToMesh()
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void TempMesh::Clear()
|
||||
{
|
||||
void TempMesh::Clear() {
|
||||
mVerts.clear();
|
||||
mVertcnt.clear();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void TempMesh::Transform(const IfcMatrix4& mat)
|
||||
{
|
||||
void TempMesh::Transform(const IfcMatrix4& mat) {
|
||||
for(IfcVector3& v : mVerts) {
|
||||
v *= mat;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
IfcVector3 TempMesh::Center() const
|
||||
{
|
||||
return (mVerts.size() == 0) ? IfcVector3(0.0f, 0.0f, 0.0f) : (std::accumulate(mVerts.begin(),mVerts.end(),IfcVector3()) / static_cast<IfcFloat>(mVerts.size()));
|
||||
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()));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void TempMesh::Append(const TempMesh& other)
|
||||
{
|
||||
void TempMesh::Append(const TempMesh& other) {
|
||||
mVerts.insert(mVerts.end(),other.mVerts.begin(),other.mVerts.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
|
||||
// Newell's algorithm. The length of the normals gives the area
|
||||
// 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);
|
||||
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];
|
||||
temp[i++] = v.x;
|
||||
temp[i++] = v.y;
|
||||
|
@ -185,9 +175,8 @@ IfcVector3 TempMesh::ComputePolygonNormal(const IfcVector3* vtcs, size_t cnt, bo
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void TempMesh::ComputePolygonNormals(std::vector<IfcVector3>& normals,
|
||||
bool normalize,
|
||||
size_t ofs) const
|
||||
{
|
||||
bool normalize,
|
||||
size_t ofs) const {
|
||||
size_t max_vcount = 0;
|
||||
std::vector<unsigned int>::const_iterator begin = mVertcnt.begin()+ofs, end = mVertcnt.end(), iit;
|
||||
for(iit = begin; iit != end; ++iit) {
|
||||
|
@ -250,29 +239,27 @@ struct FindVector {
|
|||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void TempMesh::FixupFaceOrientation()
|
||||
{
|
||||
void TempMesh::FixupFaceOrientation() {
|
||||
const IfcVector3 vavg = Center();
|
||||
|
||||
// create a list of start indices for all faces to allow random access to faces
|
||||
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;
|
||||
}
|
||||
|
||||
// list all faces on a vertex
|
||||
std::map<IfcVector3, std::vector<size_t>, CompareVector> facesByVertex;
|
||||
for( size_t a = 0; a < mVertcnt.size(); ++a )
|
||||
{
|
||||
for( size_t b = 0; b < mVertcnt[a]; ++b )
|
||||
for( size_t a = 0; a < mVertcnt.size(); ++a ) {
|
||||
for( size_t b = 0; b < mVertcnt[a]; ++b ) {
|
||||
facesByVertex[mVerts[faceStartIndices[a] + b]].push_back(a);
|
||||
}
|
||||
}
|
||||
// determine neighbourhood for all polys
|
||||
std::vector<size_t> neighbour(mVerts.size(), SIZE_MAX);
|
||||
std::vector<size_t> tempIntersect(10);
|
||||
for( size_t a = 0; a < mVertcnt.size(); ++a )
|
||||
{
|
||||
for( size_t b = 0; b < mVertcnt[a]; ++b )
|
||||
{
|
||||
for( size_t a = 0; a < mVertcnt.size(); ++a ) {
|
||||
for( size_t b = 0; b < mVertcnt[a]; ++b ) {
|
||||
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>& facesOnNB = facesByVertex[mVerts[nib]];
|
||||
|
@ -281,10 +268,12 @@ void TempMesh::FixupFaceOrientation()
|
|||
std::vector<size_t>::iterator sectend = std::set_intersection(
|
||||
facesOnB.begin(), facesOnB.end(), facesOnNB.begin(), facesOnNB.end(), sectstart);
|
||||
|
||||
if( std::distance(sectstart, sectend) != 2 )
|
||||
if( std::distance(sectstart, sectend) != 2 ) {
|
||||
continue;
|
||||
if( *sectstart == a )
|
||||
}
|
||||
if( *sectstart == a ) {
|
||||
++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
|
||||
// faces to have the same winding until all faces have been tested.
|
||||
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
|
||||
size_t farthestIndex = SIZE_MAX;
|
||||
IfcFloat farthestDistance = -1.0;
|
||||
for( size_t a = 0; a < mVertcnt.size(); ++a )
|
||||
{
|
||||
if( faceDone[a] )
|
||||
for( size_t a = 0; a < mVertcnt.size(); ++a ) {
|
||||
if( faceDone[a] ) {
|
||||
continue;
|
||||
}
|
||||
IfcVector3 faceCenter = std::accumulate(mVerts.begin() + faceStartIndices[a],
|
||||
mVerts.begin() + faceStartIndices[a] + mVertcnt[a], IfcVector3(0.0)) / IfcFloat(mVertcnt[a]);
|
||||
IfcFloat dst = (faceCenter - vavg).SquareLength();
|
||||
|
@ -315,8 +303,7 @@ void TempMesh::FixupFaceOrientation()
|
|||
/ IfcFloat(mVertcnt[farthestIndex]);
|
||||
// We accept a bit of negative orientation without reversing. In case of doubt, prefer the orientation given in
|
||||
// the file.
|
||||
if( (farthestNormal * (farthestCenter - vavg).Normalize()) < -0.4 )
|
||||
{
|
||||
if( (farthestNormal * (farthestCenter - vavg).Normalize()) < -0.4 ) {
|
||||
size_t fsi = faceStartIndices[farthestIndex], fvc = mVertcnt[farthestIndex];
|
||||
std::reverse(mVerts.begin() + fsi, mVerts.begin() + fsi + fvc);
|
||||
std::reverse(neighbour.begin() + fsi, neighbour.begin() + fsi + fvc);
|
||||
|
@ -333,19 +320,18 @@ void TempMesh::FixupFaceOrientation()
|
|||
todo.push_back(farthestIndex);
|
||||
|
||||
// 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 vsi = faceStartIndices[tdf], vc = mVertcnt[tdf];
|
||||
todo.pop_back();
|
||||
|
||||
// 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
|
||||
size_t nbi = neighbour[vsi + a];
|
||||
if( nbi == SIZE_MAX || faceDone[nbi] )
|
||||
if( nbi == SIZE_MAX || faceDone[nbi] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const IfcVector3& vp = mVerts[vsi + a];
|
||||
size_t nbvsi = faceStartIndices[nbi], nbvc = mVertcnt[nbi];
|
||||
|
@ -388,32 +374,8 @@ void TempMesh::RemoveAdjacentDuplicates() {
|
|||
IfcVector3 vmin,vmax;
|
||||
ArrayBounds(&*base, cnt ,vmin,vmax);
|
||||
|
||||
|
||||
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
|
||||
// of the previous pass as a side-effect.
|
||||
FuzzyVectorCompare fz(epsilon);
|
||||
|
@ -440,78 +402,58 @@ void TempMesh::RemoveAdjacentDuplicates() {
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void TempMesh::Swap(TempMesh& other)
|
||||
{
|
||||
void TempMesh::Swap(TempMesh& other) {
|
||||
mVertcnt.swap(other.mVertcnt);
|
||||
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";
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
IfcFloat ConvertSIPrefix(const std::string& prefix)
|
||||
{
|
||||
IfcFloat ConvertSIPrefix(const std::string& prefix) {
|
||||
if (prefix == "EXA") {
|
||||
return 1e18f;
|
||||
}
|
||||
else if (prefix == "PETA") {
|
||||
} else if (prefix == "PETA") {
|
||||
return 1e15f;
|
||||
}
|
||||
else if (prefix == "TERA") {
|
||||
} else if (prefix == "TERA") {
|
||||
return 1e12f;
|
||||
}
|
||||
else if (prefix == "GIGA") {
|
||||
} else if (prefix == "GIGA") {
|
||||
return 1e9f;
|
||||
}
|
||||
else if (prefix == "MEGA") {
|
||||
} else if (prefix == "MEGA") {
|
||||
return 1e6f;
|
||||
}
|
||||
else if (prefix == "KILO") {
|
||||
} else if (prefix == "KILO") {
|
||||
return 1e3f;
|
||||
}
|
||||
else if (prefix == "HECTO") {
|
||||
} else if (prefix == "HECTO") {
|
||||
return 1e2f;
|
||||
}
|
||||
else if (prefix == "DECA") {
|
||||
} else if (prefix == "DECA") {
|
||||
return 1e-0f;
|
||||
}
|
||||
else if (prefix == "DECI") {
|
||||
} else if (prefix == "DECI") {
|
||||
return 1e-1f;
|
||||
}
|
||||
else if (prefix == "CENTI") {
|
||||
} else if (prefix == "CENTI") {
|
||||
return 1e-2f;
|
||||
}
|
||||
else if (prefix == "MILLI") {
|
||||
} else if (prefix == "MILLI") {
|
||||
return 1e-3f;
|
||||
}
|
||||
else if (prefix == "MICRO") {
|
||||
} else if (prefix == "MICRO") {
|
||||
return 1e-6f;
|
||||
}
|
||||
else if (prefix == "NANO") {
|
||||
} else if (prefix == "NANO") {
|
||||
return 1e-9f;
|
||||
}
|
||||
else if (prefix == "PICO") {
|
||||
} else if (prefix == "PICO") {
|
||||
return 1e-12f;
|
||||
}
|
||||
else if (prefix == "FEMTO") {
|
||||
} else if (prefix == "FEMTO") {
|
||||
return 1e-15f;
|
||||
}
|
||||
else if (prefix == "ATTO") {
|
||||
} else if (prefix == "ATTO") {
|
||||
return 1e-18f;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
IFCImporter::LogError("Unrecognized SI prefix: ", prefix);
|
||||
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.g = static_cast<float>( in.Green );
|
||||
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>()) {
|
||||
out.r = out.g = out.b = static_cast<float>(*r);
|
||||
if(base) {
|
||||
|
@ -528,20 +472,18 @@ void ConvertColor(aiColor4D& out, const Schema_2x3::IfcColourOrFactor& in,Conver
|
|||
out.g *= static_cast<float>( base->g );
|
||||
out.b *= static_cast<float>( base->b );
|
||||
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);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
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();
|
||||
for(size_t i = 0; i < in.Coordinates.size(); ++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);
|
||||
out *= in.Magnitude;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertDirection(IfcVector3& out, const Schema_2x3::IfcDirection& in)
|
||||
{
|
||||
void ConvertDirection(IfcVector3& out, const Schema_2x3::IfcDirection& in) {
|
||||
out = IfcVector3();
|
||||
for(size_t i = 0; i < in.DirectionRatios.size(); ++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.b1 = x.y;
|
||||
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;
|
||||
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;
|
||||
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);
|
||||
if (in.Axis) {
|
||||
ConvertDirection(axis,in.Axis.Get());
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
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)) {
|
||||
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);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
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;
|
||||
ConvertCartesianPoint(loc,op.LocalOrigin);
|
||||
|
||||
|
@ -677,14 +608,12 @@ void ConvertTransformOperator(IfcMatrix4& out, const Schema_2x3::IfcCartesianTra
|
|||
IfcMatrix4::Translation(loc,locm);
|
||||
AssignMatrixAxes(out,x,y,z);
|
||||
|
||||
|
||||
IfcVector3 vscale;
|
||||
if (const Schema_2x3::IfcCartesianTransformationOperator3DnonUniform* nuni = op.ToPtr<Schema_2x3::IfcCartesianTransformationOperator3DnonUniform>()) {
|
||||
vscale.x = nuni->Scale?op.Scale.Get():1.f;
|
||||
vscale.y = nuni->Scale2?nuni->Scale2.Get():1.f;
|
||||
vscale.z = nuni->Scale3?nuni->Scale3.Get():1.f;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
const IfcFloat sc = op.Scale?op.Scale.Get():1.f;
|
||||
vscale = IfcVector3(sc,sc,sc);
|
||||
}
|
||||
|
@ -695,8 +624,7 @@ void ConvertTransformOperator(IfcMatrix4& out, const Schema_2x3::IfcCartesianTra
|
|||
out = locm * out * s;
|
||||
}
|
||||
|
||||
|
||||
} // ! IFC
|
||||
} // ! Assimp
|
||||
|
||||
#endif
|
||||
#endif // ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||
|
|
Loading…
Reference in New Issue