mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-06 07:51:47 +00:00
Compare commits
73 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 16566f1766 | |||
| 06d8b738e2 | |||
| 4d8633d40d | |||
| d6218307a9 | |||
| 1e7affa797 | |||
| bb54b33594 | |||
| 73f31477d5 | |||
| adf2b99569 | |||
| 815699f64b | |||
| ba629e9615 | |||
| 1f102bfd83 | |||
| 3700e2fdce | |||
| a31d3623bb | |||
| f898d19679 | |||
| 3a8bc04fc0 | |||
| 3377cb7225 | |||
| 43d34e6ca3 | |||
| d3e7fab7d5 | |||
| 6eee66a3cf | |||
| 89933d18bc | |||
| 8bfb039e36 | |||
| cbd7b58bf6 | |||
| 01252d9087 | |||
| aab8ed4f40 | |||
| 059d736e89 | |||
| 9c791d4a68 | |||
| 1542ab4afc | |||
| 43e87090e1 | |||
| 225b81c37e | |||
| b00714132d | |||
| c7cde331e9 | |||
| 5aca9ca67e | |||
| 997f03fe63 | |||
| c5d6d535d2 | |||
| eb2e4a44ee | |||
| d5e141b773 | |||
| 1e8aa0b7b8 | |||
| feffe88613 | |||
| 967dee0369 | |||
| b4e48cf300 | |||
| eb842a7f44 | |||
| 321f9dc099 | |||
| b12e807571 | |||
| e837a1b5e4 | |||
| 1986f4e3df | |||
| 69d62a66a0 | |||
| 95defa5657 | |||
| 4559fa8466 | |||
| 82a58d4554 | |||
| 352f2bf794 | |||
| 981d503b9d | |||
| 9fbd24ffb4 | |||
| 4aedeb71fd | |||
| 55c2deea37 | |||
| 6f871fb13b | |||
| 737097312e | |||
| 7f8ce5d44f | |||
| 451a9a74cf | |||
| 885844925e | |||
| 35e05a382d | |||
| bf6a71cda0 | |||
| 4bc8efd354 | |||
| cf08550d7e | |||
| 0a45bda8e4 | |||
| c750bd63e9 | |||
| 6c4189436d | |||
| ae51f08c6d | |||
| b0a7273e37 | |||
| ba2f48e210 | |||
| 3add345bb7 | |||
| 11daabc3ea | |||
| 7537435001 | |||
| a9af9341b9 |
+93
-18
@@ -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
@@ -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
@@ -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.
@@ -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
@@ -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 "")
|
||||
@@ -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
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user