Compare commits

...

73 Commits

Author SHA1 Message Date
Josef Wienerroither 16566f1766 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-07-16 08:03:29 +02:00
Josef Wienerroither 06d8b738e2 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-07-12 07:52:15 +02:00
Josef Wienerroither 4d8633d40d Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-07-11 13:50:38 +02:00
Josef Wienerroither d6218307a9 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-06-25 11:46:22 +02:00
Josef Wienerroither 1e7affa797 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-06-24 10:20:59 +02:00
Josef Wienerroither bb54b33594 update TODO comments 2026-06-24 10:19:42 +02:00
Josef Wienerroither 73f31477d5 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-06-21 08:18:19 +02:00
Josef Wienerroither adf2b99569 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-06-18 10:46:27 +02:00
Josef Wienerroither 815699f64b Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-06-12 11:59:40 +02:00
Josef Wienerroither ba629e9615 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-06-11 07:29:19 +02:00
Josef Wienerroither 1f102bfd83 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-06-06 12:42:45 +02:00
Josef Wienerroither 3700e2fdce Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-06-05 08:05:26 +02:00
Josef Wienerroither a31d3623bb Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-05-31 06:44:50 +02:00
Josef Wienerroither f898d19679 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-05-19 07:06:22 +02:00
Josef Wienerroither 3a8bc04fc0 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-05-05 11:47:06 +02:00
Josef Wienerroither 3377cb7225 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-05-02 10:11:34 +02:00
Josef Wienerroither 43d34e6ca3 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-05-01 11:21:15 +02:00
Josef Wienerroither d3e7fab7d5 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-04-25 11:16:14 +02:00
Josef Wienerroither 6eee66a3cf Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-04-12 08:22:23 +02:00
Josef Wienerroither 89933d18bc Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-04-08 10:42:06 +02:00
Josef Wienerroither 8bfb039e36 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-04-06 10:24:07 +02:00
Josef Wienerroither cbd7b58bf6 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-04-03 16:11:07 +02:00
Josef Wienerroither 01252d9087 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-04-01 16:49:01 +02:00
Josef Wienerroither aab8ed4f40 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-03-30 12:02:32 +02:00
Josef Wienerroither 059d736e89 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-03-22 09:20:00 +01:00
Josef Wienerroither 9c791d4a68 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-03-16 07:00:17 +01:00
Josef Wienerroither 1542ab4afc Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-03-15 10:03:47 +01:00
Josef Wienerroither 43e87090e1 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-03-15 10:02:53 +01:00
Josef Wienerroither 225b81c37e Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-03-14 07:15:11 +01:00
Josef Wienerroither b00714132d Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-03-10 07:18:24 +01:00
Josef Wienerroither c7cde331e9 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-03-09 09:23:03 +01:00
Josef Wienerroither 5aca9ca67e Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-03-07 08:21:43 +01:00
Josef Wienerroither 997f03fe63 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-03-04 09:41:03 +01:00
Josef Wienerroither c5d6d535d2 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-03-03 13:35:01 +01:00
Josef Wienerroither eb2e4a44ee Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-02-27 12:13:08 +01:00
Josef Wienerroither d5e141b773 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-02-26 13:24:08 +01:00
Josef Wienerroither 1e8aa0b7b8 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-02-20 09:00:52 +01:00
Josef Wienerroither feffe88613 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-02-18 10:23:01 +01:00
Josef Wienerroither 967dee0369 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-02-15 07:47:47 +01:00
Josef Wienerroither b4e48cf300 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-02-13 10:24:14 +01:00
Josef Wienerroither eb842a7f44 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-02-11 12:20:14 +01:00
Josef Wienerroither 321f9dc099 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-02-11 11:59:12 +01:00
Josef Wienerroither b12e807571 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-02-11 10:42:12 +01:00
dependabot[bot] e837a1b5e4 Bump aws-actions/configure-aws-credentials from 5 to 6
Bumps [aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials) from 5 to 6.
- [Release notes](https://github.com/aws-actions/configure-aws-credentials/releases)
- [Changelog](https://github.com/aws-actions/configure-aws-credentials/blob/main/CHANGELOG.md)
- [Commits](https://github.com/aws-actions/configure-aws-credentials/compare/v5...v6)

---
updated-dependencies:
- dependency-name: aws-actions/configure-aws-credentials
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-10 07:09:00 +01:00
dependabot[bot] 1986f4e3df Bump ruff from 0.14.14 to 0.15.0
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.14.14 to 0.15.0.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.14.14...0.15.0)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-10 07:09:00 +01:00
Dion Moult 69d62a66a0 Reimplement sort / reverse / join function to format language, simplify text annotation variables, add tests
Previously, sort, reverse list, and join functionality was implemented
as special cases in Bonsai itself. Given that it has usecases
(especially in material lists, but any sort of list applies) I've moved
this function into the IOS formatting language.

The IOS formatting language previously wasn't capable of this, but the
awesome addition by @falken10vdl made the formatting language accept
queries inline, so that means it can handle lists. I also added tests
for all the new functions and expression syntax (+-*/ operators).

I simplified the code that gets the evaluated text literal - previously
it seems to call format() multiple times.
2026-02-10 07:09:00 +01:00
Josef Wienerroither 95defa5657 build: add 3ds Max 2028 build target 2026-02-08 08:21:23 +01:00
Josef Wienerroither 4559fa8466 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-02-07 13:30:19 +01:00
Josef Wienerroither 82a58d4554 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-01-27 17:25:44 +01:00
Josef Wienerroither 352f2bf794 import safeguarding 2026-01-27 17:22:01 +01:00
Josef Wienerroither 981d503b9d Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-01-24 09:58:11 +01:00
Josef Wienerroither 9fbd24ffb4 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-01-23 07:24:49 +01:00
Josef Wienerroither 4aedeb71fd Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-01-17 06:50:15 +01:00
Josef Wienerroither 55c2deea37 ci: add patch for mpir build script to fix failing build when VS2026 is installed 2026-01-16 12:24:24 +01:00
Josef Wienerroither 6f871fb13b Merge branch 'v0.8.0' into ifcmax/initial-refresh 2026-01-16 07:51:51 +01:00
Josef Wienerroither 737097312e Merge branch 'v0.8.0' into ifcmax/initial-refresh 2025-12-31 12:47:47 +01:00
Josef Wienerroither 7f8ce5d44f fix: ensure uppercase tier name in cmakefile 2025-12-31 12:46:15 +01:00
Josef Wienerroither 451a9a74cf chore: add tier name to listener log 2025-12-31 12:45:37 +01:00
Josef Wienerroither 885844925e Merge branch 'v0.8.0' into ifcmax/initial-refresh 2025-12-30 09:42:42 +01:00
Josef Wienerroither 35e05a382d tweak ifcmax cmake file 2025-12-26 17:15:12 +01:00
Josef Wienerroither bf6a71cda0 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2025-12-26 11:47:45 +01:00
Josef Wienerroither 4bc8efd354 Merge branch 'v0.8.0' into ifcmax/initial-refresh
# Conflicts:
#	src/ifcmax/CMakeLists.txt
2025-12-25 08:29:52 +01:00
Josef Wienerroither cf08550d7e Merge branch 'v0.8.0' into ifcmax/initial-refresh 2025-12-21 16:31:19 +01:00
Josef Wienerroither 0a45bda8e4 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2025-12-17 13:01:24 +01:00
Josef Wienerroither c750bd63e9 Merge branch 'v0.8.0' into ifcmax/initial-refresh 2025-12-17 12:49:13 +01:00
Josef Wienerroither 6c4189436d Merge branch 'v0.8.0' into ifcmax/initial-refresh 2025-12-16 08:58:48 +01:00
Josef Wienerroither ae51f08c6d update and fix dependency build script 2025-12-14 15:06:29 +01:00
Josef Wienerroither b0a7273e37 Merge branch 'ifcmax/initial-refresh' into v0.8.0 2025-12-13 09:34:57 +01:00
Josef Wienerroither ba2f48e210 refactor: improve string conversions 2025-12-08 16:12:18 +01:00
Josef Wienerroither 3add345bb7 feat: add ifcmax specific build-deps.cmd 2025-12-08 15:04:18 +01:00
Josef Wienerroither 11daabc3ea feature: add ifcmax free core 2025-12-08 14:45:23 +01:00
Josef Wienerroither 7537435001 chore: add opencascade 7.9.1 patch file 2025-12-08 14:44:50 +01:00
Josef Wienerroither a9af9341b9 chore: update ifcmax cmakelists 2025-12-08 14:43:46 +01:00
8 changed files with 1670 additions and 174 deletions
+93 -18
View File
@@ -18,9 +18,20 @@
################################################################################
# check for 3ds Max SDK
foreach(max_year RANGE 2014 2030)
set(max_sdk "$ENV{ADSK_3DSMAX_SDK_${max_year}}")
set(valid_max_years 2028 2027 2026 2025 2024 2023 2022 2021 2020 2019 2018 2017)
# might be dangerous to use tools 143 for all max versions
set(max_toolset_versions_143 "2017" "2018" "2019" "2020" "2021" "2022" "2023" "2024" "2025" "2026" "2027" "2028" )
# set(max_toolset_versions_143 "2025" "2026" "2027" "2028" )
# set(max_toolset_versions_142 "2022" "2023" "2024" )
# set(max_toolset_versions_141 "2020" "2021" )
# set(max_toolset_versions_140 "2017" "2018" "2019" )
# set(max_toolset_versions_110 "2015" "2016" )
# set(max_toolset_versions_100 "2013" "2014" )
# set(max_toolset_versions_90 "2010" "2011" "2012" )
foreach(max_year ${valid_max_years})
set(max_sdk "$ENV{ADSK_3DSMAX_SDK_${max_year}}")
if(NOT "${max_sdk}" STREQUAL "")
message(STATUS "Autodesk 3ds Max SDK ${max_year} found at ${max_sdk}")
list(APPEND FOUND_MAX_YEARS ${max_year})
@@ -29,35 +40,58 @@ foreach(max_year RANGE 2014 2030)
endif()
endforeach()
if(HAS_MAX)
# build libraray for each found 3ds Max SDK
foreach(max_year max_sdk IN ZIP_LISTS FOUND_MAX_YEARS FOUND_MAX_SDKS)
message(STATUS "Building IFCMax library for Autodesk 3ds Max SDK ${max_year}")
message(STATUS)
include_directories(
if(HAS_MAX)
# set depenency include and link directoris outside of MaxSDK loop
include_directories(
${INCLUDE_DIRECTORIES}
${OPENCOLLADA_INCLUDE_DIRS}
${ICU_INCLUDE_DIR}
${Boost_INCLUDE_DIRS}
${max_sdk}/include
)
# All recent versions of 3ds Max (2014 and newer) are 64-bit only so assume lib/x64 directory
link_directories(
${LINK_DIRECTORIES}
${IfcOpenShell_BINARY_DIR}
${OPENCOLLADA_LIBRARY_DIR}
${ICU_LIBRARY_DIR}
${Boost_LIBRARY_DIRS}
${max_sdk}/lib/x64/Release
)
add_library(IfcMax_${max_year} SHARED IfcMax.h IfcMax.cpp)
# Specify individual source files
set(MAX_SOURCES
IfcMax.h
IfcMax.cpp
IfcMax.rc
resource.h
# IfcHelper.h
# IfcHelper.cpp
# MaxUtils.h
# MaxUtils.cpp
)
# build library for each found 3ds Max SDK
foreach(max_year max_sdk IN ZIP_LISTS FOUND_MAX_YEARS FOUND_MAX_SDKS)
# skip 3ds Max versions that do not match the vs toolset
if( NOT ${max_year} IN_LIST max_toolset_versions_${MSVC_TOOLSET_VERSION} )
continue()
endif()
message(STATUS "Building IFCMax library for Autodesk 3ds Max SDK ${max_year}, Tier: ${BUILD_TIER_NAME}")
add_library(IfcMax_${max_year} SHARED ${MAX_SOURCES})
target_include_directories(IfcMax_${max_year} PRIVATE ${max_sdk}/include)
# All recent versions of 3ds Max (2014 and newer) are 64-bit only so assume lib/x64 directory
target_link_directories(IfcMax_${max_year} PRIVATE ${max_sdk}/lib/x64/Release)
# TODO: find the minimal subset of 3dsmax libraries to reference
target_link_libraries(
IfcMax_${max_year}
${IFCOPENSHELL_LIBRARIES}
IfcMax_${max_year}
${IFCOPENSHELL_LIBRARIES}
bmm.lib
Comctl32.lib
core.lib
@@ -73,8 +107,6 @@ if(HAS_MAX)
maxnet.lib
Maxscrpt.lib
maxutil.lib
MenuMan.lib
menus.lib
mesh.lib
MNMath.lib
Paramblk2.lib
@@ -83,14 +115,57 @@ if(HAS_MAX)
RenderUtil.lib
tessint.lib
viewfile.lib
zlibdll.lib
${OpenCASCADE_LIBRARIES}
)
${OPENCASCADE_LIBRARIES}
)
# Note: libraries build by same major vs toolset versions are binary compatible. so v14x builds can be intermixed
# Older Max versions using v110 or older require dependencies being build using the according toolset version ( most likely )
if( ${max_year} IN_LIST max_toolset_versions_143 )
set_target_properties( IfcMax_${max_year} PROPERTIES VS_PLATFORM_TOOLSET v143)
elseif( ${max_year} IN_LIST max_toolset_versions_142 )
set_target_properties( IfcMax_${max_year} PROPERTIES VS_PLATFORM_TOOLSET v142)
elseif( ${max_year} IN_LIST max_toolset_versions_141 )
set_target_properties( IfcMax_${max_year} PROPERTIES VS_PLATFORM_TOOLSET v141)
elseif( ${max_year} IN_LIST max_toolset_versions_140 )
set_target_properties( IfcMax_${max_year} PROPERTIES VS_PLATFORM_TOOLSET v140)
elseif( ${max_year} IN_LIST max_toolset_versions_110 )
set_target_properties( IfcMax_${max_year} PROPERTIES VS_PLATFORM_TOOLSET v110)
elseif( ${max_year} IN_LIST max_toolset_versions_100 )
set_target_properties( IfcMax_${max_year} PROPERTIES VS_PLATFORM_TOOLSET v100)
elseif( ${max_year} IN_LIST max_toolset_versions_90 )
set_target_properties( IfcMax_${max_year} PROPERTIES VS_PLATFORM_TOOLSET v90)
endif()
# prevent minmax macro clashes occuring with ifcOpenShell v0.8
target_compile_definitions(IfcMax_${max_year} PRIVATE NOMINMAX)
# fix 3ds Max 2020 SDK's "/permissive-" flag incompatibility / disables C++ language conformance mode
if( ${max_year} EQUAL 2020 )
set_source_files_properties( "IfcMax.cpp" PROPERTIES COMPILE_FLAGS "/permissive")
endif()
# C++17 required for 3ds Max SDK 2025 and higher
if( ${max_year} GREATER_EQUAL 2025 )
set_target_properties(IfcMax_${max_year} PROPERTIES CXX_STANDARD 17)
endif()
set_target_properties(IfcMax_${max_year} PROPERTIES SUFFIX ".dli")
if(BUILD_TIER_NAME)
string(TOUPPER "${BUILD_TIER_NAME}" BUILD_TIER_NAME)
target_compile_definitions(IfcMax_${max_year} PRIVATE BUILD_${BUILD_TIER_NAME}_TIER)
string(TOLOWER "${BUILD_TIER_NAME}" BUILD_TIER_lower)
if(BUILD_TIER_lower STREQUAL "free")
set_target_properties(IfcMax_${max_year} PROPERTIES OUTPUT_NAME "IfcMax_Free_${max_year}")
endif()
endif()
install(TARGETS IfcMax_${max_year})
endforeach()
message(STATUS)
else()
message(STATUS "Autodesk 3ds Max SDK not found, is required to build IFCMax.")
endif()
+412 -141
View File
@@ -22,17 +22,44 @@
#include <stdmat.h>
#include <istdplug.h>
#include <spline3d.h>
#include <splshape.h>
#include <hold.h>
// should fix a iterator missallignment assertion ?
#define IFOPSH_WITH_ROCKSDB
#include "../ifcgeom/Iterator.h"
#include "../ifcgeom/taxonomy.h"
#include "../ifcgeom/ConversionSettings.h"
#include "../ifcgeom/hybrid_kernel.h"
#include "resource.h"
#include "IfcMax.h"
#include "../ifcgeom_schema_agnostic/IfcGeomIterator.h"
#include "../ifcgeom_schema_agnostic/IfcGeomMaterial.h"
#include "../ifcgeom/IfcGeomElement.h"
// include those at last, as they cause compile errors regarding boost templates
#include <maxscript/maxscript.h>
#include <maxscript/util/listener.h>
static const Class_ID IFCIMP_CLASS_ID = Class_ID(0x3f230dbf, 0x5b3015c2);
static const TSTR IFCIMP_CLASS_NAME = _T("IFCImp");
static const TSTR IFCIMP_CATEGORY_NAME = _T("Importer Plugins");
static const int NUM_MATERIAL_SLOTS = 24;
BOOL WINAPI DllMain(HINSTANCE /*hinstDLL*/, ULONG /*fdwReason*/, LPVOID /*lpvReserved*/) {
static HINSTANCE hInstance;
static TCHAR *GetString(int id)
{
static TCHAR buf[256];
if (hInstance)
return LoadString(hInstance, id, buf, _countof(buf)) ? buf : NULL;
return NULL;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, ULONG /*fdwReason*/, LPVOID /*lpvReserved*/) {
static int controlsInit = false;
hInstance = hinstDLL;
if (!controlsInit) {
controlsInit = true;
InitCommonControls();
@@ -45,65 +72,51 @@ public:
int IsPublic() { return 1; }
void * Create(BOOL /*loading = FALSE*/) { return new IFCImp; }
// TODO Delete() function?
const TCHAR * ClassName() { return _T("IFCImp"); }
const TCHAR* ClassName() { return IFCIMP_CLASS_NAME; }
#if MAX_VERSION_MAJOR >= 24
const TCHAR * NonLocalizedClassName() { return ClassName(); }
#endif
SClass_ID SuperClassID() { return SCENE_IMPORT_CLASS_ID; }
Class_ID ClassID() { return Class_ID(0x3f230dbf, 0x5b3015c2); }
const TCHAR* Category() { return _T("Chrutilities"); }
Class_ID ClassID() { return IFCIMP_CLASS_ID; }
const TCHAR* Category() { return IFCIMP_CATEGORY_NAME; }
} IFCImpDesc;
#define DLLEXPORT __declspec(dllexport)
extern "C" {
DLLEXPORT const TCHAR* LibDescription() {
return _T("IfcOpenShell IFC Importer");
}
#if BUILD_FREE_TIER
DLLEXPORT const TCHAR* LibDescription() { return GetString(IDS_LIBDESCRIPTION_FREE); }
#else
DLLEXPORT const TCHAR* LibDescription() { return GetString(IDS_LIBDESCRIPTION); }
#endif
DLLEXPORT int LibNumberClasses() { return 1; }
DLLEXPORT ClassDesc* LibClassDesc(int i) {
return i == 0 ? &IFCImpDesc : 0;
}
DLLEXPORT ClassDesc* LibClassDesc(int i) { return i == 0 ? &IFCImpDesc : 0; }
DLLEXPORT ULONG LibVersion() {
return VERSION_3DSMAX;
}
DLLEXPORT ULONG LibVersion() { return VERSION_3DSMAX; }
} // extern "C"
int IFCImp::ExtCount() { return 1; }
const TCHAR * IFCImp::Ext(int n) {
return n == 0 ? _T("IFC") : _T("");
}
const TCHAR * IFCImp::Ext(int n) { return n == 0 ? _T("IFC") : _T(""); }
const TCHAR * IFCImp::LongDesc() {
return _T("IfcOpenShell IFC Importer for 3ds Max");
}
const TCHAR * IFCImp::LongDesc() { return GetString(IDS_LONG_DESCRIPTION); }
const TCHAR * IFCImp::ShortDesc() {
return _T("Industry Foundation Classes");
}
const TCHAR * IFCImp::ShortDesc() { return GetString(IDS_SHORT_DESCRIPTION); }
const TCHAR * IFCImp::AuthorName() {
return _T("Thomas Krijnen");
}
const TCHAR * IFCImp::AuthorName() { return GetString(IDS_AUTHOR_NAME); }
const TCHAR * IFCImp::CopyrightMessage() {
return _T("Copyright (c) 2011-2016 IfcOpenShell");
}
const TCHAR * IFCImp::CopyrightMessage() { return GetString(IDS_COPYRIGHT_MESSAGE); }
const TCHAR * IFCImp::OtherMessage1() {
return _T("");
}
const TCHAR * IFCImp::OtherMessage1() { return _T(""); }
const TCHAR * IFCImp::OtherMessage2() {
return _T("");
}
const TCHAR * IFCImp::OtherMessage2() { return _T(""); }
unsigned int IFCImp::Version() {
return 12;
}
unsigned int IFCImp::Version() { return 25; }
// TODO Use this in IFCImp::ShowAbout() if/when wanted
//static BOOL CALLBACK AboutBoxDlgProc(HWND /*hWnd*/, UINT /*msg*/, WPARAM /*wParam*/, LPARAM /*lParam*/) {
@@ -122,6 +135,40 @@ DWORD WINAPI fn(LPVOID /*arg*/) { return 0; }
# define S(x) (CStr(x.c_str()))
#endif
// Function to log messages to the Listener
static void LogToListener(const MCHAR* format, ...)
{
if (format == nullptr) {
return;
}
const int BUFFER_SIZE = 2048;
static MCHAR buffer[BUFFER_SIZE];
va_list args;
va_start(args, format);
int result = _vstprintf_s(buffer, BUFFER_SIZE, format, args);
va_end(args);
#if BUILD_FREE_TIER
if(result < 0) {
the_listener->edit_stream->printf(_M("IfcImp[Free]: Skipped invalid log output !\n"));
return;
}
the_listener->edit_stream->printf(_M("IfcImp[Free]: %s"), buffer);
#else
if(result < 0) {
the_listener->edit_stream->printf(_M("IfcImp[Pro]: Skipped invalid log output !\n"));
return;
}
the_listener->edit_stream->printf(_M("IfcImp[Pro]: %s"), buffer);
#endif
}
static Mtl* FindMaterialByName(MtlBaseLib* library, const std::string& material_name) {
TSTR mat_name = S(material_name);
const int mat_index = library->FindMtlByName(mat_name);
@@ -132,27 +179,32 @@ static Mtl* FindMaterialByName(MtlBaseLib* library, const std::string& material_
return m;
}
static Mtl* FindOrCreateMaterial(MtlBaseLib* library, Interface* max_interface, int& slot, const IfcGeom::Material& material) {
Mtl* m = FindMaterialByName(library, material.name());
static Mtl* FindOrCreateMaterial(MtlBaseLib* library, Interface* max_interface, int& slot, const ifcopenshell::geometry::taxonomy::style::ptr styleptr) {
auto& style = *styleptr;
std::string material_name = style.name;
Mtl* m = FindMaterialByName(library, material_name);
if (m == 0) {
StdMat2* stdm = NewDefaultStdMat();
const TimeValue t = -1;
if (material.hasDiffuse()) {
const double* diffuse = material.diffuse();
stdm->SetDiffuse(Color(diffuse[0], diffuse[1], diffuse[2]),t);
if (style.diffuse) {
const ifcopenshell::geometry::taxonomy::colour diffuse = style.diffuse;
stdm->SetDiffuse(Color(diffuse.r(), diffuse.g(), diffuse.b()),t);
}
if (material.hasSpecular()) {
const double* specular = material.specular();
stdm->SetSpecular(Color(specular[0], specular[1], specular[2]),t);
if (style.specular) {
const ifcopenshell::geometry::taxonomy::colour specular = style.specular;
stdm->SetSpecular(Color(specular.r(), specular.g(), specular.b()),t);
}
if (material.hasSpecularity()) {
stdm->SetShininess((float)material.specularity(), t);
if (style.has_specularity()) {
stdm->SetShininess((float)style.specularity, t);
}
if (material.hasTransparency()) {
stdm->SetOpacity(1.0f - (float)material.transparency(), t);
if (style.has_transparency()) {
stdm->SetOpacity(1.0f - (float)style.transparency, t);
}
m = stdm;
m->SetName(S(material.name()));
m->SetName(S(material_name));
library->Add(m);
if (slot < NUM_MATERIAL_SLOTS) {
max_interface->PutMtlToMtlEditor(m,slot++);
@@ -161,18 +213,22 @@ static Mtl* FindOrCreateMaterial(MtlBaseLib* library, Interface* max_interface,
return m;
}
static Mtl* ComposeMultiMaterial(std::map<std::vector<std::string>, Mtl*>& multi_mats, MtlBaseLib* library,
Interface* max_interface, int& slot, const std::vector<IfcGeom::Material>& materials,
Interface* max_interface, int& slot, const std::vector<ifcopenshell::geometry::taxonomy::style::ptr> styleptrs,
const std::string& object_type, const std::vector<int>& material_ids)
{
std::vector<std::string> material_names;
bool needs_default = std::find(material_ids.begin(), material_ids.end(), -1) != material_ids.end();
if (needs_default) {
material_names.push_back(object_type);
}
for (auto it = materials.begin(); it != materials.end(); ++it) {
material_names.push_back(it->name());
for (auto it = styleptrs.begin(); it != styleptrs.end(); ++it) {
material_names.push_back( (*it)->name);
}
Mtl* default_material = 0;
if (needs_default) {
default_material = FindMaterialByName(library, object_type);
@@ -185,13 +241,15 @@ static Mtl* ComposeMultiMaterial(std::map<std::vector<std::string>, Mtl*>& multi
}
}
}
if (material_names.size() == 1) {
if (needs_default) {
return default_material;
} else {
return FindOrCreateMaterial(library, max_interface, slot, *materials.begin());
return FindOrCreateMaterial(library, max_interface, slot, *styleptrs.begin());
}
}
std::map<std::vector<std::string>, Mtl*>::const_iterator i = multi_mats.find(material_names);
if (i != multi_mats.end()) {
return i->second;
@@ -202,7 +260,7 @@ static Mtl* ComposeMultiMaterial(std::map<std::vector<std::string>, Mtl*>& multi
if (needs_default) {
multi_mat->SetSubMtlAndName(mtl_id ++, default_material, default_material->GetName());
}
for (auto it = materials.begin(); it != materials.end(); ++it) {
for (auto it = styleptrs.begin(); it != styleptrs.end(); ++it) {
Mtl* mtl = FindOrCreateMaterial(library, max_interface, slot, *it);
multi_mat->SetSubMtl(mtl_id ++, mtl);
}
@@ -214,114 +272,327 @@ static Mtl* ComposeMultiMaterial(std::map<std::vector<std::string>, Mtl*>& multi
return multi_mat;
}
int IFCImp::DoImport(const TCHAR *name, ImpInterface *impitfc, Interface *itfc, BOOL /*suppressPrompts*/) {
int IFCImp::DoImport(const TCHAR *file_name, ImpInterface *impitfc, Interface *ip, BOOL noPrompts ) {
IfcGeom::IteratorSettings settings;
settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, false);
settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, true);
settings.set(IfcGeom::IteratorSettings::SEW_SHELLS, true);
ifcopenshell::geometry::Settings settings;
//settings.get<ifcopenshell::geometry::settings::MesherLinearDeflection>().value = 0.001;
//settings.get<ifcopenshell::geometry::settings::MesherAngularDeflection>().value = 0.5;
// should adapt to 3ds Max Systemm units ?
//settings.get<ifcopenshell::geometry::settings::LengthUnit>().value = 1.0;
//settings.get<ifcopenshell::geometry::settings::PlaneUnit>().value = 1.0;
//settings.get<ifcopenshell::geometry::settings::Precision>().value = 0.00001;
//settings.get<ifcopenshell::geometry::settings::PrecisionFactor>().value = 1.0;
//settings.get<ifcopenshell::geometry::settings::BooleanAttempt2d>().value = true;
//settings.get<ifcopenshell::geometry::settings::LayersetFirst>().value = false;
//settings.get<ifcopenshell::geometry::settings::DisableBooleanResult>().value = false;
//settings.get<ifcopenshell::geometry::settings::NoWireIntersectionCheck>().value = false;
//settings.get<ifcopenshell::geometry::settings::NoWireIntersectionTolerance>().value = false;
settings.get<ifcopenshell::geometry::settings::ReorientShells>().value = true; // should be true
settings.get<ifcopenshell::geometry::settings::UnifyShapes>().value = true; // should be true
settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = false; // should be false to get a pivot with correct coordinates
//settings.get<ifcopenshell::geometry::settings::UseMaterialNames>().value = false;
//settings.get<ifcopenshell::geometry::settings::ConvertBackUnits>().value = false;
// some settings which seem to make sense
settings.get<ifcopenshell::geometry::settings::UseElementHierarchy>().value = true;
settings.get<ifcopenshell::geometry::settings::BuildingLocalPlacement>().value = true; // should be true
// ATTENTION: breaks hierarchy positioning when active ( "site-local-placement" )
settings.get<ifcopenshell::geometry::settings::SiteLocalPlacement>().value = false; // should be FALSE
// when vertex welding is enabled, normals calculation is internally disabled ( see OpenCascadeConversionResult.cpp:239 )
settings.get<ifcopenshell::geometry::settings::WeldVertices>().value = true; // should be true
settings.get<ifcopenshell::geometry::settings::DontEmitNormals>().value = false;
settings.get<ifcopenshell::geometry::settings::GenerateUvs>().value = false;
settings.get<ifcopenshell::geometry::settings::CircleSegments>().value = 32; // should be 32
settings.get<ifcopenshell::geometry::settings::EdgeArrows>().value = true;
settings.get<ifcopenshell::geometry::settings::OutputDimensionality>().value = ifcopenshell::geometry::settings::SURFACES_AND_SOLIDS; // default is SURFACES_AND_SOLIDS
#ifdef _UNICODE
int fn_buffer_size = WideCharToMultiByte(CP_UTF8, 0, name, -1, 0, 0, 0, 0);
int fn_buffer_size = WideCharToMultiByte(CP_UTF8, 0, file_name, -1, 0, 0, 0, 0);
char* fn_mb = new char[fn_buffer_size];
WideCharToMultiByte(CP_UTF8, 0, name, -1, fn_mb, fn_buffer_size, 0, 0);
WideCharToMultiByte(CP_UTF8, 0, file_name, -1, fn_mb, fn_buffer_size, 0, 0);
#else
const char* fn_mb = name;
#endif
IfcParse::IfcFile file(fn_mb);
IfcGeom::Iterator<float> iterator(settings, &file);
delete fn_mb;
if (!iterator.initialize()) return false;
IfcParse::IfcFile file(fn_mb);
itfc->ProgressStart(_T("Importing file..."), TRUE, fn, NULL);
IfcParse::file_open_status status = file.good();
MtlBaseLib* mats = itfc->GetSceneMtls();
if (status != IfcParse::file_open_status::SUCCESS) {
const MCHAR* reason = status == IfcParse::file_open_status::UNSUPPORTED_SCHEMA
? _M("Import aborted: unsupported IFC Schema")
: _M("Import aborted: failure parsing IFC file");
ip->DisplayTempPrompt( reason, 10000 );
return false;
}
auto mapped = file.instances_by_type( "IfcMappedItem" );
auto annotations = file.instances_by_type("IfcAnnotation");
auto solids = file.instances_by_type("IfcSolidModel");
// cgal kernels produce std::vector incompatiblities
// TODO: cgal kernels produce std::vector incompatibilities -> 3ds Max asserts crashes
// ifcopenshell::geometry::kernels::construct(&ifc_file, KernelName.at(Kernel::HybridCGALSimpleOCC), settings),
IfcGeom::Iterator iterator(ifcopenshell::geometry::kernels::construct(&file, "opencascade", settings), settings, &file);
delete[] fn_mb;
LogToListener(_M("Importing '%s'...\n"), file_name);
if (!iterator.initialize()) {
if(!iterator.had_error_processing_elements()) {
LogToListener(_M("No elements found in '%s'...\n"), file_name);
return IMPEXP_SUCCESS;
}
LogToListener(_M("Error processing elements in '%s'...\n"), file_name);
return IMPEXP_FAIL;
}
ip->ProgressStart(_T("Importing file..."), TRUE, fn, NULL);
MtlBaseLib* mats = ip->GetSceneMtls();
int slot = mats->Count();
std::vector<ImpNode *> impnode_cache;
std::map<std::vector<std::string>, Mtl*> material_cache;
do{
const IfcGeom::TriangulationElement<float>* o = static_cast<const IfcGeom::TriangulationElement<float>*>(iterator.get());
bool wasCanceled=false;
auto startTime = std::chrono::high_resolution_clock::now();
std::stringstream log_stream;
TSTR o_type = S(o->type());
TSTR o_guid = S(o->guid());
do {
// clear the log
log_stream.str("");
Mtl *m = ComposeMultiMaterial(material_cache, mats, itfc, slot, o->geometry().materials(), o->type(), o->geometry().material_ids());
//const IfcGeom::Element* element = static_cast<const IfcGeom::Element*>(iterator.get());
//const IfcGeom::BRepElement* brepElement = static_cast<const IfcGeom::BRepElement*>(iterator.get_native());
const IfcGeom::Element* element = iterator.get();
const IfcGeom::TriangulationElement* triElement = static_cast<const IfcGeom::TriangulationElement*>(element);
TriObject* tri = CreateNewTriObject();
const int numVerts = (int)o->geometry().verts().size()/3;
tri->mesh.setNumVerts(numVerts);
for( int i = 0; i < numVerts; i ++ ) {
tri->mesh.setVert(i,o->geometry().verts()[3*i+0],o->geometry().verts()[3*i+1],o->geometry().verts()[3*i+2]);
}
const int numFaces = (int)o->geometry().faces().size()/3;
tri->mesh.setNumFaces(numFaces);
bool needs_default = std::find(o->geometry().material_ids().begin(), o->geometry().material_ids().end(), -1) != o->geometry().material_ids().end();
typedef std::pair<int, int> edge_t;
std::set<edge_t> face_boundaries;
for(std::vector<int>::const_iterator it = o->geometry().edges().begin(); it != o->geometry().edges().end();) {
const int v1 = *it++;
const int v2 = *it++;
const edge_t e((std::min)(v1, v2), (std::max)(v1, v2));
face_boundaries.insert(e);
if(triElement==nullptr)
{
LogToListener(_M("%3d%% - Skipping non/null TriangulationElement [#%d]\n"), iterator.progress(), element != nullptr ? element->id() : -1);
continue;
}
for( int i = 0; i < numFaces; i ++ ) {
const int v1 = o->geometry().faces()[3*i+0];
const int v2 = o->geometry().faces()[3*i+1];
const int v3 = o->geometry().faces()[3*i+2];
const edge_t e1((std::min)(v1, v2), (std::max)(v1, v2));
const edge_t e2((std::min)(v2, v3), (std::max)(v2, v3));
const edge_t e3((std::min)(v3, v1), (std::max)(v3, v1));
auto prod = triElement->product();
TSTR e_type = TSTR::FromUTF8(triElement->type().c_str());
TSTR e_guid = TSTR::FromUTF8(triElement->guid().c_str());
TSTR e_name = TSTR::FromUTF8(triElement->name().c_str());
TSTR e_idStr = TSTR(std::to_wstring(triElement->id()).c_str());
const bool b1 = face_boundaries.find(e1) != face_boundaries.end();
const bool b2 = face_boundaries.find(e2) != face_boundaries.end();
const bool b3 = face_boundaries.find(e3) != face_boundaries.end();
tri->mesh.faces[i].setVerts(v1, v2, v3);
tri->mesh.faces[i].setEdgeVisFlags(b1, b2, b3);
MtlID mtlid = (MtlID)o->geometry().material_ids()[i];
if (needs_default) {
mtlid ++;
// dump out the parent tree up to IfcProject for each element
auto parents = triElement->parents(); // keep a persistent copy
if (!parents.empty()) {
for(auto it =parents.rbegin(); it != parents.rend(); ++it) {
auto p_e = *it;
log_stream << "->" << p_e->type() << " [#" << p_e->id() << "]";
}
tri->mesh.faces[i].setMatID(mtlid);
}
tri->mesh.buildNormals();
// Either use this or undefine the FACESETS_AS_COMPOUND option in IfcGeom.h to have
// properly oriented normals. Using only the line below will result in a consistent
// orientation of normals across shells, but not always oriented towards the
// outside.
// tri->mesh.UnifyNormals(false);
tri->mesh.BuildStripsAndEdges();
tri->mesh.InvalidateTopologyCache();
tri->mesh.InvalidateGeomCache();
TSTR logString = TSTR::FromUTF8(log_stream.str().c_str());
LogToListener(_M("%3d%% - [#%d] %s: '%s' %s\n"), iterator.progress(), triElement->id(), e_type.data(), e_name.data(), logString.data());
ImpNode* node = impitfc->CreateNode();
node->Reference(tri);
node->SetName(o_guid);
node->GetINode()->Hide(o->type() == "IfcOpeningElement" || o->type() == "IfcSpace");
if (m) {
node->GetINode()->SetMtl(m);
}
const std::vector<float>& matrix_data = o->transformation().matrix().data();
node->SetTransform(0,Matrix3 ( Point3(matrix_data[0],matrix_data[1],matrix_data[2]),Point3(matrix_data[3],matrix_data[4],matrix_data[5]),
Point3(matrix_data[6],matrix_data[7],matrix_data[8]),Point3(matrix_data[9],matrix_data[10],matrix_data[11]) ));
impitfc->AddNodeToScene(node);
Mtl *mat = ComposeMultiMaterial(material_cache, mats, ip, slot, triElement->geometry().materials(), triElement->type(), triElement->geometry().material_ids());
itfc->ProgressUpdate(iterator.progress(), true, _T(""));
ImpNode* impNode = impitfc->CreateNode();
RefResult refSuccess = REF_INVALID;
auto mesh = BuildMesh(triElement);
if ( mesh != nullptr)
refSuccess = impNode->Reference(mesh);
if (refSuccess != REF_SUCCEED) {
LogToListener(_M("Error creating importer reference for imported element #%d.\n"), triElement->id());
continue;
}
TSTR longName;
BuildFullName( *prod, longName);
impNode->SetName(longName);
const auto& mtx = triElement->transformation().data()->ccomponents();
impNode->SetTransform(0, Matrix3(Point3(mtx(0, 0), mtx(1, 0), mtx(2, 0)), Point3(mtx(0, 1), mtx(1, 1), mtx(2, 1)), Point3(mtx(0, 2), mtx(1, 2), mtx(2, 2)), Point3(mtx(0, 3), mtx(1, 3), mtx(2, 3))));
INode* inode = impNode->GetINode();
inode->Hide(triElement->type() == "IfcOpeningElement" || triElement->type() == "IfcSpace");
if (mat != nullptr) {
inode->SetMtl(mat);
// set wirecolor to material color
inode->SetWireColor(mat->GetDiffuse().toRGB());
}
// add to the cache, not to the scene, thisd allows a clean exit if cancel was pressed
impnode_cache.push_back(impNode);
ip->ProgressUpdate(iterator.progress(), true, _T(""));
if (ip->GetCancel()) {
wasCanceled = noPrompts ? true : VerifyCancel();
if (wasCanceled)
break;
else
ip->SetCancel(false);
}
} while (iterator.next());
itfc->ProgressEnd();
return true;
ip->ProgressEnd();
if(wasCanceled) {
LogToListener(_T("Import canceled by User\n"));
return IMPEXP_CANCEL;
}
// add all objects to the scene
for( int i = 0; i < impnode_cache.size(); i++ )
impitfc->AddNodeToScene(impnode_cache[i]);
// Calculate the duration
INT64 seconds = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::high_resolution_clock::now() - startTime).count();
LogToListener(_M("Import finished in %u seconds\n"), seconds);
return IMPEXP_SUCCESS;
}
BOOL IFCImp::VerifyCancel() {
#if MAX_VERSION_MAJOR < 23
return IDYES == MaxMsgBox(GetCOREInterface()->GetMAXHWnd(), GetString(IDS_IMPORT_CANCEL_MESSAGE), GetString(IDS_IMPORT_CANCEL_CAPTION), MB_YESNO);
#else
// new MaxMessageBox API
return IDYES == MaxSDK::MaxMessageBox(GetCOREInterface()->GetMAXHWnd(), GetString(IDS_IMPORT_CANCEL_MESSAGE), GetString(IDS_IMPORT_CANCEL_CAPTION), MB_YESNO);
#endif
}
void IFCImp::BuildFullName( const IfcUtil::IfcBaseEntity& entity, MSTR& long_name)
{
TSTR name = TSTR::FromUTF8(entity.get_value<std::string>("Name", "").c_str());
TSTR declName = TSTR::FromUTF8(entity.declaration().name().c_str());
if( _tcslen( name ) > 0) {
long_name.printf(_M("%s/%s [#%d]"), declName.data(), name.data(), entity.id_);
}
else {
long_name.printf(_M("%s [#%d]"), declName.data(), entity.id_);
}
}
TriObject* IFCImp::BuildMesh(const IfcGeom::TriangulationElement* element) {
TriObject* tri = CreateNewTriObject();
const IfcGeom::Representation::Triangulation& ios_mesh = element->geometry();
const auto& verts = ios_mesh.verts();
const int numVerts = (int)verts.size() / 3;
//const auto& normals = ios_mesh.normals();
// const int numNormals = (int)normals.size() / 3;
// const auto& uvs = ios_mesh.uvs();
// const int numUVs = (int)uvs.size() / 3;
tri->mesh.setNumVerts(numVerts);
for (int i = 0; i < numVerts; i++) {
tri->mesh.setVert(i, Point3ByIndex(verts, i));
//if( i < numNormals ) {
// tri->mesh.setNormal(i, Point3ByIndex(normals, i));
// }
}
bool needs_default = std::find(ios_mesh.material_ids().begin(), ios_mesh.material_ids().end(), -1) != ios_mesh.material_ids().end();
typedef std::pair<int, int> edge_t;
std::set<edge_t> face_boundaries;
for (std::vector<int>::const_iterator it = ios_mesh.edges().begin(); it != ios_mesh.edges().end();) {
const int v1 = *it++;
const int v2 = *it++;
const edge_t e((std::min)(v1, v2), (std::max)(v1, v2));
face_boundaries.insert(e);
}
const auto& faces = ios_mesh.faces();
const int numFaces = (int)faces.size() / 3;
tri->mesh.setNumFaces(numFaces);
for (int i = 0; i < numFaces; i++) {
const int v1 = faces[3 * i + 0];
const int v2 = faces[3 * i + 1];
const int v3 = faces[3 * i + 2];
const edge_t e1((std::min)(v1, v2), (std::max)(v1, v2));
const edge_t e2((std::min)(v2, v3), (std::max)(v2, v3));
const edge_t e3((std::min)(v3, v1), (std::max)(v3, v1));
const bool b1 = face_boundaries.find(e1) != face_boundaries.end();
const bool b2 = face_boundaries.find(e2) != face_boundaries.end();
const bool b3 = face_boundaries.find(e3) != face_boundaries.end();
tri->mesh.faces[i].setVerts(v1, v2, v3);
tri->mesh.faces[i].setEdgeVisFlags(b1, b2, b3);
MtlID mtlid = (MtlID)ios_mesh.material_ids()[i];
if (needs_default) {
mtlid++;
}
tri->mesh.faces[i].setMatID(mtlid);
}
bool valid = tri->CheckObjectIntegrity();
if (!valid) {
return nullptr;
}
// apply simple box mapping
#if MAX_VERSION_MAJOR < 22
// in 3ds Max 2017-2019 SDK, Matrix3::Identity was declared in matrix3.h, but did'nt actually exist in the lib ....
Matrix3 ident(TRUE);
tri->mesh.ApplyUVWMap(MAP_ACAD_BOX, 1, 1, 1, 0, 0, 0, 0, ident);
#else
tri->mesh.ApplyUVWMap(MAP_ACAD_BOX, 1, 1, 1, 0, 0, 0, 0, Matrix3::Identity);
#endif
// this one tends to crash, so we skip it for the time being
// tri->mesh.buildNormals();
// Either use this or undefine the FACESETS_AS_COMPOUND option in IfcGeom.h to have
// properly oriented normals. Using only the line below will result in a consistent
// orientation of normals across shells, but not always oriented towards the
// outside.
// tri->mesh.UnifyNormals(false);
tri->mesh.BuildStripsAndEdges();
tri->mesh.InvalidateTopologyCache();
tri->mesh.InvalidateGeomCache();
return tri;
}
inline Point3 IFCImp::Point3ByIndex(const std::vector<double>& verts, int index) {
return Point3(verts[3 * index + 0], verts[3 * index + 1], verts[3 * index + 2]);
}
+19 -15
View File
@@ -21,23 +21,27 @@
#define IFCMAX_H
#include "Max.h"
#include "../ifcgeom/IfcGeomElement.h"
extern ClassDesc* GetIFCImpDesc();
class IFCImp : public SceneImport {
public:
int ExtCount(); // = 1
const TCHAR* Ext(int n); // = "IFC"
const TCHAR* LongDesc(); // = "IFC Importer for 3ds Max"
const TCHAR* ShortDesc(); // = "Industry Foundation Classes"
const TCHAR* AuthorName(); // = "Josef Wienerroither"
const TCHAR* CopyrightMessage(); // = "Copyright (c) 2025 Josef Wienerroither, 2011-2016 IfcOpenShell"
const TCHAR* OtherMessage1(); // = ""
const TCHAR* OtherMessage2(); // = ""
unsigned int Version(); // = 25
void ShowAbout(HWND hWnd);
int DoImport(const TCHAR* name, ImpInterface* ei, Interface* i, BOOL suppressPrompts);
BOOL VerifyCancel();
class IFCImp : public SceneImport
{
public:
int ExtCount(); // = 1
const TCHAR * Ext(int n); // = "IFC"
const TCHAR * LongDesc(); // = "IfcOpenShell IFC Importer for 3ds Max"
const TCHAR * ShortDesc(); // = "Industry Foundation Classes"
const TCHAR * AuthorName(); // = "Thomas Krijnen"
const TCHAR * CopyrightMessage(); // = "Copyright (c) 2011-2016 IfcOpenShell"
const TCHAR * OtherMessage1(); // = ""
const TCHAR * OtherMessage2(); // = ""
unsigned int Version(); // = 12
void ShowAbout(HWND hWnd);
int DoImport(const TCHAR *name,ImpInterface *ei,Interface *i, BOOL suppressPrompts);
private:
inline Point3 Point3ByIndex(const std::vector<double>& verts, int index);
void BuildFullName(const IfcUtil::IfcBaseEntity& entity, MSTR& long_name);
TriObject* BuildMesh(const IfcGeom::TriangulationElement* triElement);
};
#endif
Binary file not shown.
+23
View File
@@ -0,0 +1,23 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by IfcMax.rc
//
#define IDS_LIBDESCRIPTION 101
#define IDS_LIBDESCRIPTION_FREE 102
#define IDS_SHORT_DESCRIPTION 103
#define IDS_LONG_DESCRIPTION 104
#define IDS_AUTHOR_NAME 105
#define IDS_COPYRIGHT_MESSAGE 106
#define IDS_IMPORT_CANCEL_CAPTION 107
#define IDS_IMPORT_CANCEL_MESSAGE 108
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
File diff suppressed because it is too large Load Diff
+86
View File
@@ -0,0 +1,86 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 34300d41ad..efe3065499 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -363,6 +363,10 @@ else()
set (USE_D3D OFF)
endif()
+# IfcOpenShell begin
+add_definitions(-DHAVE_NO_DLL)
+# IfcOpenShell end
+
# Enable/Disable the floating point exceptions (FPE) during runtime.
if (NOT BUILD_ENABLE_FPE_SIGNAL_HANDLER)
set (BUILD_ENABLE_FPE_SIGNAL_HANDLER OFF CACHE BOOL "${BUILD_ENABLE_FPE_SIGNAL_HANDLER_DESCR}" FORCE)
@@ -721,6 +725,8 @@ else()
OCCT_CHECK_AND_UNSET ("3RDPARTY_DOT_EXECUTABLE")
endif()
+list (REMOVE_ITEM BUILD_TOOLKITS ExpToCasExe)
+
# bison
if (BUILD_YACCLEX)
list (APPEND OCCT_3RDPARTY_CMAKE_LIST "adm/cmake/bison")
diff --git a/adm/cmake/occt_defs_flags.cmake b/adm/cmake/occt_defs_flags.cmake
index 5bd3313d3c..d647ff05ab 100644
--- a/adm/cmake/occt_defs_flags.cmake
+++ b/adm/cmake/occt_defs_flags.cmake
@@ -214,7 +214,23 @@ if (CMAKE_COMPILER_IS_GNUCXX AND NOT APPLE)
set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
endif()
-if (BUILD_RELEASE_DISABLE_EXCEPTIONS)
- set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNo_Exception")
- set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DNo_Exception")
-endif()
+# IfcOpenShell begin
+# https://salsa.debian.org/science-team/opencascade/blob/739e7e9c4fbe575165eb3ff0251774bfad27139e/debian/patches/enable-exception-handling.patch
+# if (BUILD_RELEASE_DISABLE_EXCEPTIONS)
+# set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNo_Exception")
+# set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DNo_Exception")
+# endif()
+
+if (MSVC AND MSVC_STATIC_RUNTIME)
+ foreach(flag CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL
+ CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
+ CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
+ if (${flag} MATCHES "/MD")
+ string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}")
+ endif()
+ if (${flag} MATCHES "/MDd")
+ string(REGEX REPLACE "/MDd" "/MTd" ${flag} "${${flag}}")
+ endif()
+ endforeach()
+endif()
+# IfcOpenShell end
diff --git a/adm/cmake/occt_toolkit.cmake b/adm/cmake/occt_toolkit.cmake
index 22e94d0629..c6995bb247 100644
--- a/adm/cmake/occt_toolkit.cmake
+++ b/adm/cmake/occt_toolkit.cmake
@@ -135,15 +135,22 @@ else()
else()
set (aReleasePdbConf)
endif()
+ # IfcOpenShell begin
if (BUILD_SHARED_LIBS)
install (FILES ${CMAKE_BINARY_DIR}/${OS_WITH_BIT}/${COMPILER}/bin\${OCCT_INSTALL_BIN_LETTER}/${PROJECT_NAME}.pdb
CONFIGURATIONS Debug ${aReleasePdbConf} RelWithDebInfo
DESTINATION "${INSTALL_DIR_BIN}\${OCCT_INSTALL_BIN_LETTER}")
else()
- install (FILES ${CMAKE_BINARY_DIR}/${OS_WITH_BIT}/${COMPILER}/lib\${OCCT_INSTALL_BIN_LETTER}/${PROJECT_NAME}.pdb
- CONFIGURATIONS Debug ${aReleasePdbConf} RelWithDebInfo
- DESTINATION "${INSTALL_DIR_LIB}\${OCCT_INSTALL_BIN_LETTER}")
+ set_target_properties (${PROJECT_NAME} PROPERTIES
+ COMPILE_PDB_NAME ${PROJECT_NAME}
+ COMPILE_PDB_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${OS_WITH_BIT}/${COMPILER}/pdb/
+ )
+
+ install (FILES ${CMAKE_BINARY_DIR}/${OS_WITH_BIT}/${COMPILER}/pdb/\${CMAKE_INSTALL_CONFIG_NAME}/${PROJECT_NAME}.pdb
+ CONFIGURATIONS Debug ${aReleasePdbConf} RelWithDebInfo
+ DESTINATION "${INSTALL_DIR_LIB}\${OCCT_INSTALL_BIN_LETTER}")
endif()
+ # IfcOpenShell end
endif()
if (BUILD_SHARED_LIBS AND NOT "${BUILD_SHARED_LIBRARY_NAME_POSTFIX}" STREQUAL "")
+14
View File
@@ -0,0 +1,14 @@
diff --git a/msvc/vs22/msbuild.bat b/msvc/vs22/msbuild.bat
index f119c3e9..35e46217 100644
--- a/msvc/vs22/msbuild.bat
+++ b/msvc/vs22/msbuild.bat
@@ -14,7 +14,8 @@ set vs_version=2019
set vsw_exe="%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
-for /f "usebackq tokens=*" %%i in (`"!vsw_exe!" -latest -products * -requires Microsoft.Component.MSBuild -property installationPath`) do (
+rem limit to VS2022, as VS2026 does not build currently
+for /f "usebackq tokens=*" %%i in (`"!vsw_exe! -version [17,18)" -sort -products * -requires Microsoft.Component.MSBuild -property installationPath`) do (
set InstallDir=%%i
)