Merge branch 'ifcmax/initial-refresh' into v0.8.0

This commit is contained in:
Josef Wienerroither
2025-12-13 09:34:57 +01:00
7 changed files with 1598 additions and 176 deletions
+88 -19
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 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" )
# set(max_toolset_versions_143 "2025" "2026" "2027" )
# 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,22 +40,41 @@ foreach(max_year RANGE 2014 2030)
endif()
endforeach()
message(STATUS)
if(HAS_MAX)
# build libraray for each found 3ds Max SDK
# set depenency include and link directoris outside of MaxSDK loop
include_directories(${INCLUDE_DIRECTORIES} ${OCC_INCLUDE_DIR} ${OPENCOLLADA_INCLUDE_DIRS} ${ICU_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} )
link_directories(${LINK_DIRECTORIES} ${IfcOpenShell_BINARY_DIR} ${OCC_LIBRARY_DIR} ${OPENCOLLADA_LIBRARY_DIR} ${ICU_LIBRARY_DIR} ${Boost_LIBRARY_DIRS} )
# 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)
message(STATUS "Building IFCMax library for Autodesk 3ds Max SDK ${max_year}")
# 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()
include_directories(${INCLUDE_DIRECTORIES} ${OPENCOLLADA_INCLUDE_DIRS} ${ICU_INCLUDE_DIR}
${Boost_INCLUDE_DIRS} ${max_sdk}/include
)
message(STATUS "Adding build target: IFCMax for 3ds Max SDK ${max_year}, Tier: ${BUILD_TIER_NAME}")
# 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)
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}
@@ -63,8 +93,6 @@ if(HAS_MAX)
maxnet.lib
Maxscrpt.lib
maxutil.lib
MenuMan.lib
menus.lib
mesh.lib
MNMath.lib
Paramblk2.lib
@@ -73,14 +101,55 @@ 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)
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} RUNTIME DESTINATION ${BINDIR})
install(TARGETS IfcMax_${max_year})
endforeach()
message(STATUS)
else()
message(STATUS "Autodesk 3ds Max SDK not found, is required to build IFCMax.")
endif()
+413 -142
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: Skipped invalid log output !\n"));
return;
}
the_listener->edit_stream->printf(_M("IfcImp: %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
//auto kernel = ifcopenshell::geometry::kernels::construct(&file, "hybrid-cgal-simple-opencascade", settings);
//auto kernel = ifcopenshell::geometry::kernels::construct(&file, "opencascade", settings);
//IfcGeom::Iterator iterator( std::move( kernel), settings, &file);
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;
bool wasCanceled=false;
auto startTime = std::chrono::high_resolution_clock::now();
std::stringstream log_stream;
do{
const IfcGeom::TriangulationElement<float>* o = static_cast<const IfcGeom::TriangulationElement<float>*>(iterator.get());
TSTR o_type = S(o->type());
TSTR o_guid = S(o->guid());
auto iter = iterator.get();
auto prod = iter->product();
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::TriangulationElement* triElement = static_cast<const IfcGeom::TriangulationElement*>(iterator.get());
TriObject* tri = CreateNewTriObject();
TSTR e_type = TSTR::FromUTF8(element->type().c_str());
TSTR e_guid = TSTR::FromUTF8(element->guid().c_str());
TSTR e_name = TSTR::FromUTF8(element->name().c_str());
TSTR e_idStr = TSTR(std::to_wstring(element->id()).c_str());
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);
}
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));
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
log_stream.str("");
auto parents = element->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(), element->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"), element->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
+969
View File
@@ -0,0 +1,969 @@
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: ::
:: This file is part of IfcOpenShell. ::
:: ::
:: IfcOpenShell is free software: you can redistribute it and/or modify ::
:: it under the terms of the Lesser GNU General Public License as published by ::
:: the Free Software Foundation, either version 3.0 of the License, or ::
:: (at your option) any later version. ::
:: ::
:: IfcOpenShell is distributed in the hope that it will be useful, ::
:: but WITHOUT ANY WARRANTY; without even the implied warranty of ::
:: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ::
:: Lesser GNU General Public License for more details. ::
:: ::
:: You should have received a copy of the Lesser GNU General Public License ::
:: along with this program. If not, see <http://www.gnu.org/licenses/>. ::
:: ::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: This batch file expects CMake generator as %1 and build configuration type as %2. If not provided,
:: a deduced generator will be used for %1 and BUILD_CFG_DEFAULT for %2 (both set in vs-cfg.cmd)
:: Optionally a build type (Build/Rebuild/Clean) can be passed as %3.
::
:: Example usage (all arguments are optional):
:: build-deps.cmd vs2022-x64 RelWithDebInfo Build
@if not defined ECHO_ON ( echo off )
echo.
for %%Q in ("%~dp0\.") DO set "batpath=%%~fQ"
if NOT "%CD%" == "%batpath%" (
GOTO :ErrorAndPrintUsage
)
set PROJECT_NAME=IfcOpenShell
call utils\cecho.cmd 0 15 "This script fetches and builds all %PROJECT_NAME% dependencies"
echo.
:: Enable the delayed environment variable expansion needed in vs-cfg.cmd.
setlocal EnableDelayedExpansion
:: Make sure vcvarsall.bat is called and dev env set is up.
IF "%VSINSTALLDIR%"=="" (
call utils\cecho.cmd 0 12 "Visual Studio environment variables not set- cannot proceed."
GOTO :ErrorAndPrintUsage
)
:: Check for cl.exe - at least the "Typical" Visual Studio 2015 installation does not include the C++ toolset by default,
:: http://blogs.msdn.com/b/vcblog/archive/2015/07/24/setup-changes-in-visual-studio-2015-affecting-c-developers.aspx
where cl.exe 2>&1>NUL
if not %ERRORLEVEL%==0 (
call utils\cecho.cmd 0 12 "%~nx0: cl.exe not in PATH. Make sure to select the C++ toolset when installing Visual Studio- cannot proceed."
GOTO :ErrorAndPrintUsage
)
:: Set up variables depending on the used Visual Studio version
call vs-cfg.cmd %1
IF NOT %ERRORLEVEL%==0 GOTO :Error
:: Set up the BuildDepsCache.txt filename
IF DEFINED VS_TOOLSET (
set BUILD_DEPS_CACHE_PATH=BuildDepsCache-%VS_PLATFORM%-%VS_TOOLSET%.txt
) ELSE (
set BUILD_DEPS_CACHE_PATH=BuildDepsCache-%VS_PLATFORM%.txt
)
:: fix for Visual C++ hanging when compiling 32-bit release OCCT up to version 7.4.0
:: see https://tracker.dev.opencascade.org/view.php?id=31628
SET COMPILE_WITH_WPO=FALSE
call build-type-cfg.cmd %2
IF NOT %ERRORLEVEL%==0 GOTO :Error
set BUILD_TYPE=%3
IF "%BUILD_TYPE%"=="" set BUILD_TYPE=Build
IF NOT "!BUILD_TYPE!"=="Build" IF NOT "!BUILD_TYPE!"=="Rebuild" IF NOT "!BUILD_TYPE!"=="Clean" (
call utils\cecho.cmd 0 12 "Invalid build type passed: !BUILD_TYPE!. Cannot proceed, aborting!"
GOTO :Error
)
:: Make sure deps and install folders exists.
IF NOT EXIST "%DEPS_DIR%". mkdir "%DEPS_DIR%"
IF NOT EXIST "%INSTALL_DIR%". mkdir "%INSTALL_DIR%"
:: If we use VS2008, framework path (for MSBuild) may not be correctly set. Manually attempt to add in that case
IF %VS_VER%==2008 set PATH=C:\Windows\Microsoft.NET\Framework\v3.5;%PATH%
:: User-configurable build options
IF NOT DEFINED IFCOS_INSTALL_PYTHON set IFCOS_INSTALL_PYTHON=TRUE
IF NOT DEFINED IFCOS_NUM_BUILD_PROCS set IFCOS_NUM_BUILD_PROCS=%NUMBER_OF_PROCESSORS%
:: For subroutines
REM /clp:ErrorsOnly;WarningsOnly
:: Note BUILD_TYPE not passed, Clean e.g. wouldn't delete the installed files.
set MSBUILD_CMD=MSBuild.exe /nologo /m:%IFCOS_NUM_BUILD_PROCS%
echo.
:: Check that required tools are in PATH
FOR %%i IN (powershell git cmake) DO (
where.exe %%i 1> NUL 2> NUL || call cecho.cmd 0 12 "Required tool `'%%i`' not installed or not added to PATH" && goto :ErrorAndPrintUsage
)
:: Check powershell version
powershell -c "exit $PSVersionTable.PSVersion.Major -lt 5"
IF NOT %ERRORLEVEL%==0 call cecho.cmd 0 12 "Powershell version 5 or higher required" && goto :ErrorAndPrintUsage
cmake --version | findstr version > temp.txt
set /p CMAKE_VERSION=<temp.txt
del temp.txt
if "%CMAKE_VERSION%" LSS "cmake version 3.11.4" (
echo "CMake v3.11.4 or higher is required"
goto :ErrorAndPrintUsage
)
:: BEGIN JW added
set JSON_VERSION=3.6.1
set CGAL_VERSION=v5.5.5
REM set CGAL_VERSION=v5.6.3
set EIGEN_VERSION=3.4.0
:: NOTE Should be v1.6.68, but that caused problems with LIBXML2
REM set OPENCOLLADA_VERSION=v1.6.68
set OPENCOLLADA_VERSION=064a60b65c2c31b94f013820856bc84fb1937cc6
:: END JW added
:: NOTE Boost < 1.64 doesn't work without tricks if the user has only VS 2017 installed and no earlier versions.
set BOOST_VERSION=1.86.0
:: Version string with underscores instead of dots.
set BOOST_VER=%BOOST_VERSION:.=_%
:: Print build configuration information
call cecho.cmd 0 10 "Script configuration:"
call cecho.cmd 0 13 "* CMake Generator`t= '`"%GENERATOR%`'`t
echo - Passed to CMake -G option.
call cecho.cmd 0 13 "* Target Architecture`t= %TARGET_ARCH%"
echo - Whether were doing 32-bit (x86) or 64-bit (x64) build.
call cecho.cmd 0 13 "* Target Platform`t= %VS_PLATFORM%"
echo - Passed to CMake -A option.
call cecho.cmd 0 13 "* Target Toolset`t= %VS_TOOLSET%"
echo - Passed to CMake -T option.
call cecho.cmd 0 13 "* Dependency Directory`t= %DEPS_DIR%"
echo - The directory where %PROJECT_NAME% dependencies are fetched and built.
call cecho.cmd 0 13 "* Installation Directory = %INSTALL_DIR%"
echo - The directory where %PROJECT_NAME% dependencies are installed.
call cecho.cmd 0 13 "* Build Config Type`t= %BUILD_CFG%"
echo - The used build configuration type for the dependencies.
echo Defaults to RelWithDebInfo if not specified.
IF %BUILD_CFG%==MinSizeRel call cecho.cmd 0 14 " WARNING: MinSizeRel build can suffer from a significant performance loss."
call cecho.cmd 0 13 "* Build Type`t`t= %BUILD_TYPE%"
echo - The used build type for the dependencies (Build, Rebuild, Clean).
echo Defaults to Build if not specified.
call cecho.cmd 0 13 "* IFCOS_INSTALL_PYTHON`t= %IFCOS_INSTALL_PYTHON%"
echo - Download and install Python.
echo Set to something other than TRUE if you wish to use an already installed version of Python.
echo But then you'll need to set PYTHONHOME env variable to your Python installation before running run-cmake.bat
echo to your Python installation path.
call cecho.cmd 0 13 "* IFCOS_NUM_BUILD_PROCS`t= %IFCOS_NUM_BUILD_PROCS%"
echo - How many MSBuild.exe processes may be run in parallel.
echo Defaults to NUMBER_OF_PROCESSORS. Used also by other IfcOpenShell build scripts.
echo.
call :PrintUsage
call cecho.cmd 0 14 "Warning: You will need roughly 8 GB of disk space to proceed."
echo.
call cecho.cmd black cyan "If you are not ready with the above: type `'n`' in the prompt below. Build proceeds on all other inputs!"
set /p do_continue="> "
if "%do_continue%"=="n" goto :Finish
echo.
set START_TIME=%TIME%
echo Build started at %START_TIME%.
set BUILD_STARTED=TRUE
echo.
cd "%DEPS_DIR%"
:: VERSIONS
:: Don't use HDF5 1.13.0, because it has a broken cmake package path.
set HDF5_VERSION=1_13_1
set OCCT_VERSION=7.8.1
IF DEFINED PYTHON_VERSION (
echo Using overridden PYTHON_VERSION: '%PYTHON_VERSION%'
) else (
set PYTHON_VERSION=3.11.7
)
:: VERSION DERIVATIONS
set OCC_INCLUDE_DIR=%INSTALL_DIR%\opencascade-%OCCT_VERSION%\inc>>"%~dp0\%BUILD_DEPS_CACHE_PATH%"
set OCC_LIBRARY_DIR=%INSTALL_DIR%\opencascade-%OCCT_VERSION%\win%ARCH_BITS%\lib>>"%~dp0\%BUILD_DEPS_CACHE_PATH%"
IF "%IFCOS_INSTALL_PYTHON%"=="TRUE" (
set PYTHONHOME=%DEPS_DIR%\python.%PYTHON_VERSION%\tools
)
:: Cache last used CMake generator and configurable dependency dirs for other scripts to use
:: This is consolidated at the beginning of the script so that the script can be partially
:: executed by jumping (using goto) to different labels.
if defined GEN_SHORTHAND echo GEN_SHORTHAND=%GEN_SHORTHAND%>"%~dp0\%BUILD_DEPS_CACHE_PATH%"
echo HDF5_VERSION=%HDF5_VERSION%>>"%~dp0\%BUILD_DEPS_CACHE_PATH%"
echo OCC_INCLUDE_DIR=%OCC_INCLUDE_DIR%>>"%~dp0\%BUILD_DEPS_CACHE_PATH%"
echo OCC_LIBRARY_DIR=%OCC_LIBRARY_DIR%>>"%~dp0\%BUILD_DEPS_CACHE_PATH%"
IF "%IFCOS_INSTALL_PYTHON%"=="TRUE" (
echo PYTHONHOME=%PYTHONHOME%>>"%~dp0\%BUILD_DEPS_CACHE_PATH%"
)
:nuget
set DEPENDENCY_NAME=nuget
set NUGET_VERSION=6.14.0
set NUGET_INSTALL_DIR=%DEPS_DIR%\nuget-%NUGET_VERSION%
set NUGET_EXE=%NUGET_INSTALL_DIR%\nuget.exe
where nuget >nul 2>&1
IF %ERRORLEVEL%==0 (
echo Found existing nuget in PATH. Skipping.
for /f "delims=" %%i in ('where nuget') do set "NUGET_EXE=%%i"
goto :ccache
)
IF EXIST "%NUGET_EXE%" (
echo Found existing "%DEPS_DIR%\nuget.exe", skipping
goto :ccache
)
cd %DEPS_DIR%
call :DownloadFile ^
https://dist.nuget.org/win-x86-commandline/v%NUGET_VERSION%/nuget.exe ^
"%NUGET_INSTALL_DIR%" nuget.exe
IF NOT %ERRORLEVEL%==0 GOTO :Error
:ccache
set DEPENDENCY_NAME=ccache
set CCACHE_VERSION=4.12.1
set CCACHE_INSTALL_DIR=%DEPS_DIR%\%DEPENDENCY_NAME%.%CCACHE_VERSION%\tools
set DEPENDENCY_DIR=%CCACHE_INSTALL_DIR%
where ccache >nul 2>&1
IF %ERRORLEVEL%==0 (
echo Found existing ccache in PATH. Skipping.
goto :proj
)
echo CCACHE_INSTALL_DIR=%CCACHE_INSTALL_DIR%>>"%~dp0\%BUILD_DEPS_CACHE_PATH%"
IF EXIST "%DEPENDENCY_DIR%" (
echo Found existing "%DEPENDENCY_DIR%", skipping
goto :proj
)
"%NUGET_EXE%" install ccache -Version %CCACHE_VERSION% -OutputDirectory "%DEPS_DIR%"
IF NOT %ERRORLEVEL%==0 GOTO :Error
:proj
IF NOT DEFINED SKIP_INSTALLED_DEPS_CHECK IF EXIST "%INSTALL_DIR%\proj-9.2.1" (
echo Found existing "%INSTALL_DIR%\proj-9.2.1", skipping
goto :mpir
)
set DEPENDENCY_NAME=sqlite3
md %INSTALL_DIR%\sqlite3\lib %INSTALL_DIR%\sqlite3\bin %INSTALL_DIR%\sqlite3\include
call :DownloadFile https://www.sqlite.org/2023/sqlite-amalgamation-3430100.zip "%DEPS_DIR%" sqlite-amalgamation-3430100.zip
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :ExtractArchive sqlite-amalgamation-3430100.zip "%DEPS_DIR%" "%DEPS_DIR%\sqlite-amalgamation-3430100"
IF NOT %ERRORLEVEL%==0 GOTO :Error
pushd "%DEPS_DIR%\sqlite-amalgamation-3430100"
cl /c sqlite3.c
lib /OUT:%INSTALL_DIR%\sqlite3\lib\sqlite3.lib sqlite3.obj
cl sqlite3.c shell.c /link /out:%INSTALL_DIR%\sqlite3\bin\sqlite3.exe
set PATH=%PATH%;%INSTALL_DIR%\sqlite3\bin
copy sqlite3.h %INSTALL_DIR%\sqlite3\include
popd
set DEPENDENCY_NAME=proj
set DEPENDENCY_DIR=%DEPS_DIR%\proj-9.2.1
call :DownloadFile https://download.osgeo.org/proj/proj-9.2.1.zip "%DEPS_DIR%" proj-9.2.1.zip
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :ExtractArchive proj-9.2.1.zip "%DEPS_DIR%" "%DEPS_DIR%\proj-9.2.1"
IF NOT %ERRORLEVEL%==0 GOTO :Error
pushd "%DEPENDENCY_DIR%"
call :RunCMake -DCMAKE_INSTALL_PREFIX="%INSTALL_DIR%\proj-9.2.1" ^
-DSQLITE3_INCLUDE_DIR=%INSTALL_DIR%\sqlite3\include ^
-DSQLITE3_LIBRARY=%INSTALL_DIR%\sqlite3\lib\sqlite3.lib ^
-DENABLE_TIFF=Off -DENABLE_CURL=Off -DBUILD_PROJSYNC=Off ^
-DBUILD_SHARED_LIBS=Off ^
-DBUILD_TESTING=Off
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :BuildSolution "%DEPENDENCY_DIR%\%BUILD_DIR%\PROJ.sln" %BUILD_CFG%
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :InstallCMakeProject "%DEPENDENCY_DIR%\%BUILD_DIR%" %BUILD_CFG%
IF NOT %ERRORLEVEL%==0 GOTO :Error
popd
:mpir
IF NOT DEFINED SKIP_INSTALLED_DEPS_CHECK IF EXIST "%INSTALL_DIR%\mpir" (
echo Found existing "%INSTALL_DIR%\mpir", skipping
goto :mpfr
)
set DEPENDENCY_NAME=mpir
set DEPENDENCY_DIR=%DEPS_DIR%\mpir
call :GitCloneAndCheckoutRevision https://github.com/BrianGladman/mpir.git "%DEPENDENCY_DIR%"
IF NOT %ERRORLEVEL%==0 GOTO :Error
pushd "%DEPENDENCY_DIR%"
git reset --hard
git clean -fdx
REM There probably need to be quotes here around the filename
powershell -c "get-content %~dp0patches\mpir.patch | %%{$_ -replace \"sdk\",\"%UCRTVersion%\"} | %%{$_ -replace \"fn\",\"lib_mpir_cxx\"}" | git apply --unidiff-zero --ignore-whitespace
IF NOT %ERRORLEVEL%==0 GOTO :Error
powershell -c "get-content %~dp0patches\mpir.patch | %%{$_ -replace \"sdk\",\"%UCRTVersion%\"} | %%{$_ -replace \"fn\",\"lib_mpir_gc\"}" | git apply --unidiff-zero --ignore-whitespace
IF NOT %ERRORLEVEL%==0 GOTO :Error
if NOT "%USE_STATIC_RUNTIME%"=="FALSE" git apply "%~dp0patches\mpir_runtime.patch" --unidiff-zero --ignore-whitespace
IF NOT %ERRORLEVEL%==0 GOTO :Error
cd msvc
cd vs%VS_VER:~2,2%
call .\msbuild.bat gc LIB %VS_PLATFORM% %DEBUG_OR_RELEASE%
IF NOT %ERRORLEVEL%==0 GOTO :Error
IF NOT EXIST "%INSTALL_DIR%\mpir". mkdir "%INSTALL_DIR%\mpir"
copy ..\..\lib\%VS_PLATFORM%\%DEBUG_OR_RELEASE%\* "%INSTALL_DIR%\mpir"
IF NOT %ERRORLEVEL%==0 GOTO :Error
popd
:mpfr
IF NOT DEFINED SKIP_INSTALLED_DEPS_CHECK IF EXIST "%INSTALL_DIR%\mpfr" (
echo Found existing "%INSTALL_DIR%\mpfr", skipping
goto :HDF5
)
set DEPENDENCY_NAME=mpfr
set DEPENDENCY_DIR=%DEPS_DIR%\mpfr
call :GitCloneAndCheckoutRevision https://github.com/aothms/mpfr.git "%DEPENDENCY_DIR%" 2ebbe10fd029a480cf6e8a64c493afa9f3654251
IF NOT %ERRORLEVEL%==0 GOTO :Error
pushd "%DEPENDENCY_DIR%"
git reset --hard
powershell -c "get-content %~dp0patches\mpfr.patch | %%{$_ -replace \"sdk\",\"%UCRTVersion%\"} | %%{$_ -replace \"fn\",\"lib_mpfr\"}" | git apply --unidiff-zero --ignore-whitespace
IF NOT %ERRORLEVEL%==0 GOTO :Error
if NOT "%USE_STATIC_RUNTIME%"=="FALSE" git apply "%~dp0patches\mpfr_runtime.patch" --unidiff-zero --ignore-whitespace
IF NOT %ERRORLEVEL%==0 GOTO :Error
if "%VS_VER%"=="2017" (
set mpfr_sln=build.vc15
set orig_platform_toolset=v141
) else (
set mpfr_sln=build.vs19
set orig_platform_toolset=v142
)
powershell -c "get-childitem %DEPENDENCY_DIR%\%mpfr_sln% -recurse -include *.vcxproj | select -expand fullname | foreach { (Get-Content $_) -replace '%orig_platform_toolset%', 'v%VC_VER:.=%' | Set-Content $_ }"
call :BuildSolution "%DEPENDENCY_DIR%\%mpfr_sln%\lib_mpfr.sln" %DEBUG_OR_RELEASE% lib_mpfr
IF NOT %ERRORLEVEL%==0 GOTO :Error
REM This command fails because not all msvc projects are patched with the right sdk version
IF NOT EXIST lib\%VS_PLATFORM%\%DEBUG_OR_RELEASE%\mpfr.lib GOTO :Error
IF NOT EXIST "%INSTALL_DIR%\mpfr". mkdir "%INSTALL_DIR%\mpfr"
copy lib\%VS_PLATFORM%\%DEBUG_OR_RELEASE%\* "%INSTALL_DIR%\mpfr"
IF NOT %ERRORLEVEL%==0 GOTO :Error
popd
:HDF5
set DEPENDENCY_NAME=hdf5
set DEPENDENCY_DIR=%DEPS_DIR%\hdf5-%HDF5_VERSION%
set HDF5_CMAKE_ZIP=hdf5-%HDF5_VERSION%.zip
set HDF5_INSTALL_NAME=HDF5-%HDF5_VERSION%-win%ARCH_BITS%
IF NOT DEFINED SKIP_INSTALLED_DEPS_CHECK IF EXIST "%INSTALL_DIR%\%HDF5_INSTALL_NAME%" (
echo Found existing "%INSTALL_DIR%\%HDF5_INSTALL_NAME%", skipping
goto :Boost
)
if "%ARCH_BITS%"=="64" set ARCH_BITS_64=64
call :DownloadFile ^
https://github.com/HDFGroup/hdf5/archive/refs/tags/hdf5-%HDF5_VERSION%.zip ^
"%DEPS_DIR%" %HDF5_CMAKE_ZIP%
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :ExtractArchive %HDF5_CMAKE_ZIP% "%DEPS_DIR%" "%DEPS_DIR%\hdf5-%HDF5_VERSION%"
IF NOT %ERRORLEVEL%==0 GOTO :Error
if exist "%DEPS_DIR%\hdf5-hdf5-%HDF5_VERSION%" ren "%DEPS_DIR%\hdf5-hdf5-%HDF5_VERSION%" "hdf5-%HDF5_VERSION%"
pushd "%DEPENDENCY_DIR%"
call :RunCMake -DCMAKE_INSTALL_PREFIX="%INSTALL_DIR%\%HDF5_INSTALL_NAME%" ^
-DHDF5_ENABLE_Z_LIB_SUPPORT=OFF -DBUILD_TESTING=OFF ^
-DHDF5_BUILD_TOOLS=OFF -DHDF5_BUILD_EXAMPLES=OFF -DBUILD_SHARED_LIBS=OFF -DHDF5_BUILD_UTILS=OFF ^
-DHDF5_BUILD_CPP_LIB=ON
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :BuildSolution "%DEPENDENCY_DIR%\%BUILD_DIR%\HDF5.sln" %DEBUG_OR_RELEASE%
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :InstallCMakeProject "%DEPENDENCY_DIR%\%BUILD_DIR%" %DEBUG_OR_RELEASE%
IF NOT %ERRORLEVEL%==0 GOTO :Error
popd
:: Note all of the dependencies have appropriate label so that user can easily skip something if wanted
:: by modifying this file and using goto.
:Boost
:: DEPENDENCY_NAME is used for logging and DEPENDENCY_DIR for saving from some redundant typing
set DEPENDENCY_NAME=Boost %BOOST_VERSION%
set DEPENDENCY_DIR=%DEPS_DIR%\boost_%BOOST_VER%
set DEPENDENCY_INSTALL_DIR=%DEPENDENCY_DIR%\stage\%GEN_SHORTHAND%
echo BOOST_INSTALL_DIR=%DEPENDENCY_INSTALL_DIR%>>"%~dp0\%BUILD_DEPS_CACHE_PATH%"
:: Needed for CGAL build.
set BOOST_ROOT=%DEPENDENCY_DIR%
set BOOST_LIBRARYDIR=%DEPENDENCY_DIR%\stage\%GEN_SHORTHAND%\lib
:: NOTE Also zip download exists, if encountering problems with 7z for some reason.
set ZIP_EXT=7z
set BOOST_ZIP=boost-%BOOST_VERSION%-b2-nodocs.%ZIP_EXT%
cd "%DEPS_DIR%"
call :DownloadFile https://github.com/boostorg/boost/releases/download/boost-%BOOST_VERSION%/%BOOST_ZIP% "%DEPS_DIR%" %BOOST_ZIP%
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :ExtractArchive %BOOST_ZIP% "%DEPS_DIR%" %DEPENDENCY_DIR%
IF NOT %ERRORLEVEL%==0 GOTO :Error
:: top-level folder name changed when migrating to github releases
if exist "%DEPS_DIR%\boost-%BOOST_VERSION%". (
ren %DEPS_DIR%\boost-%BOOST_VERSION% boost_%BOOST_VER%
)
:: Build Boost build script
if not exist "%DEPENDENCY_DIR%\project-config.jam". (
cd "%DEPS_DIR%"
IF NOT EXIST "%DEPENDENCY_DIR%\boost.css" GOTO :Error
cd "%DEPENDENCY_DIR%"
call cecho.cmd 0 13 "Building Boost build script."
call bootstrap %BOOST_BOOTSTRAP_VER%
IF NOT %ERRORLEVEL%==0 GOTO :Error
)
set BOOST_LIBS=--with-system --with-regex --with-thread --with-program_options --with-date_time --with-iostreams --with-filesystem
:: NOTE Boost is fast to build with limited set of libraries so build it always.
cd "%DEPENDENCY_DIR%"
call cecho.cmd 0 13 "Building %DEPENDENCY_NAME% %BOOST_LIBS% Please be patient, this will take a while."
IF EXIST "%DEPENDENCY_DIR%\bin.v2\project-cache.jam" del "%DEPENDENCY_DIR%\bin.v2\project-cache.jam"
call .\b2 toolset=%BOOST_TOOLSET% runtime-link=shared address-model=%ARCH_BITS% --abbreviate-paths -j%IFCOS_NUM_BUILD_PROCS% ^
variant=%DEBUG_OR_RELEASE_LOWERCASE% %BOOST_WIN_API% %BOOST_LIBS% stage --stagedir=%DEPENDENCY_INSTALL_DIR%
IF NOT %ERRORLEVEL%==0 GOTO :Error
:JSON
set DEPENDENCY_NAME=JSON for Modern C++ v%JSON_VERSION%
IF NOT EXIST "%INSTALL_DIR%\json\nlohmann". mkdir "%INSTALL_DIR%\json\nlohmann"
call :DownloadFile https://github.com/nlohmann/json/releases/download/v%JSON_VERSION%/json.hpp "%INSTALL_DIR%\json\nlohmann" json.hpp
:OpenCOLLADA
:: Note OpenCOLLADA has only Release and Debug builds.
set DEPENDENCY_NAME=OpenCOLLADA
set DEPENDENCY_DIR=%DEPS_DIR%\OpenCOLLADA
:: Always clone it, even if it's installed, because it contains xml headers we need.
:: Use a fixed revision in order to prevent introducing breaking changes
call :GitCloneAndCheckoutRevision https://github.com/KhronosGroup/OpenCOLLADA.git "%DEPENDENCY_DIR%" %OPENCOLLADA_VERSION%
IF NOT DEFINED SKIP_INSTALLED_DEPS_CHECK IF EXIST "%INSTALL_DIR%\OpenCOLLADA" (
echo Found existing "%INSTALL_DIR%\OpenCOLLADA", skipping
:: we do need to clone though because the bundled libxml includes are not installed
goto :OCCT
)
IF NOT %ERRORLEVEL%==0 GOTO :Error
cd "%DEPENDENCY_DIR%"
:: Debug build of OpenCOLLADAValidator fails (https://github.com/KhronosGroup/OpenCOLLADA/issues/377) so
:: so disable it from the build altogether as we have no use for it
findstr #add_subdirectory(COLLADAValidator) CMakeLists.txt>NUL
IF NOT %ERRORLEVEL%==0 git apply --reject --whitespace=fix "%~dp0patches\OpenCOLLADA_CMakeLists.txt.patch" --ignore-whitespace
:: NOTE OpenCOLLADA has been observed to have problems with switching between debug and release builds so
:: uncomment to following line in order to delete the CMakeCache.txt always if experiencing problems.
REM IF EXIST "%DEPENDENCY_DIR%\%BUILD_DIR%\CMakeCache.txt". del "%DEPENDENCY_DIR%\%BUILD_DIR%\CMakeCache.txt"
:: NOTE Enforce that the embedded LibXml2 and PCRE are used as there might be problems with arbitrary versions of the libraries.
call :RunCMake -DCMAKE_INSTALL_PREFIX="%INSTALL_DIR%\OpenCOLLADA" -DUSE_STATIC_MSVC_RUNTIME=0 -DCMAKE_DEBUG_POSTFIX=d ^
-DLIBXML2_LIBRARIES="" -DLIBXML2_INCLUDE_DIR="" -DPCRE_INCLUDE_DIR="" -DPCRE_LIBRARIES=""
IF NOT %ERRORLEVEL%==0 GOTO :Error
REM IF NOT EXIST "%DEPS_DIR%\OpenCOLLADA\%BUILD_DIR%\lib\%DEBUG_OR_RELEASE%\OpenCOLLADASaxFrameworkLoader.lib".
call :BuildSolution "%DEPENDENCY_DIR%\%BUILD_DIR%\OPENCOLLADA.sln" %DEBUG_OR_RELEASE%
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :InstallCMakeProject "%DEPENDENCY_DIR%\%BUILD_DIR%" %DEBUG_OR_RELEASE%
IF NOT %ERRORLEVEL%==0 GOTO :Error
:OCCT
SET OCCT_VER=V%OCCT_VERSION:.=_%
IF NOT DEFINED SKIP_INSTALLED_DEPS_CHECK IF EXIST "%INSTALL_DIR%\opencascade-%OCCT_VERSION%" (
echo Found existing "%INSTALL_DIR%\opencascade-%OCCT_VERSION%", skipping
goto :Python
)
:: OCCT has many dependencies but FreeType is the only mandatory
set DEPENDENCY_NAME=FreeType
set DEPENDENCY_DIR=%DEPS_DIR%\freetype-2.7.1
set FREETYPE_ZIP=VER-2-7-1.zip
cd "%DEPS_DIR%"
call :DownloadFile https://github.com/freetype/freetype/archive/refs/tags/%FREETYPE_ZIP% "%DEPS_DIR%" %FREETYPE_ZIP%
if not %ERRORLEVEL%==0 goto :Error
call :ExtractArchive %FREETYPE_ZIP% "%DEPS_DIR%" "%DEPENDENCY_DIR%"
if not %ERRORLEVEL%==0 goto :Error
if exist "%DEPS_DIR%\freetype-VER-2-7-1" ren "%DEPS_DIR%\freetype-VER-2-7-1" "freetype-2.7.1"
cd "%DEPENDENCY_DIR%"
:: NOTE FreeType is built as a static library by default
call :RunCMake -DCMAKE_INSTALL_PREFIX="%INSTALL_DIR%\freetype"
if not %ERRORLEVEL%==0 goto :Error
call :BuildSolution "%DEPENDENCY_DIR%\%BUILD_DIR%\freetype.sln" %BUILD_CFG%
if not %ERRORLEVEL%==0 goto :Error
call :InstallCMakeProject "%DEPENDENCY_DIR%\%BUILD_DIR%" %BUILD_CFG%
if not %ERRORLEVEL%==0 goto :Error
set DEPENDENCY_NAME=Open CASCADE %OCCT_VERSION%
set DEPENDENCY_DIR=%DEPS_DIR%\occt_git
cd "%DEPS_DIR%"
call :GitCloneAndCheckoutRevision https://github.com/Open-Cascade-SAS/OCCT "%DEPENDENCY_DIR%" %OCCT_VER%
if not %ERRORLEVEL%==0 goto :Error
:: Patching always blindly would trigger a rebuild each time
findstr IfcOpenShell "%DEPENDENCY_DIR%\CMakeLists.txt">NUL
if not %ERRORLEVEL%==0 (
pushd "%DEPENDENCY_DIR%"
git apply --ignore-whitespace ""%~dp0patches\%OCCT_VER%.patch"
popd
)
findstr IfcOpenShell "%DEPENDENCY_DIR%\CMakeLists.txt">NUL
if not %ERRORLEVEL%==0 goto :Error
cd "%DEPENDENCY_DIR%"
call :RunCMake -DINSTALL_DIR="%INSTALL_DIR%\opencascade-%OCCT_VERSION%" -DBUILD_LIBRARY_TYPE="Static" -DCMAKE_DEBUG_POSTFIX=d ^
-DBUILD_MODULE_Draw=0 -D3RDPARTY_FREETYPE_DIR="%INSTALL_DIR%\freetype"
if not %ERRORLEVEL%==0 goto :Error
:: whole program optimization avoids Visual C++ hanging when compiling 32-bit release OCCT up to version 7.4.0
IF %ARCH_BITS%==32 (
IF %BUILD_CFG%==Release (
SET COMPILE_WITH_WPO=TRUE
)
)
call :BuildSolution "%DEPENDENCY_DIR%\%BUILD_DIR%\OCCT.sln" %BUILD_CFG%
if not %ERRORLEVEL%==0 goto :Error
call :InstallCMakeProject "%DEPENDENCY_DIR%\%BUILD_DIR%" %BUILD_CFG%
if not %ERRORLEVEL%==0 goto :Error
SET COMPILE_WITH_WPO=FALSE
:: Use a single lib directory for release and debug libraries as is done with OCE
if not exist "%OCC_LIBRARY_DIR%". mkdir "%OCC_LIBRARY_DIR%"
:: NOTE OCCT (at least occt-V7_0_0-9059ca1) directory creation code is hardcoded and doesn't seem handle future VC versions
set OCCT_VC_VER=%VC_VER%
IF %OCCT_VC_VER% GTR 14 (
set OCCT_VC_VER=14
)
move /y "%INSTALL_DIR%\opencascade-%OCCT_VERSION%\win%ARCH_BITS%\vc%OCCT_VC_VER%\libi\*.*" "%OCC_LIBRARY_DIR%"
move /y "%INSTALL_DIR%\opencascade-%OCCT_VERSION%\win%ARCH_BITS%\vc%OCCT_VC_VER%\libd\*.*" "%OCC_LIBRARY_DIR%"
move /y "%INSTALL_DIR%\opencascade-%OCCT_VERSION%\win%ARCH_BITS%\vc%OCCT_VC_VER%\lib\*.*" "%OCC_LIBRARY_DIR%"
rmdir /s /q "%INSTALL_DIR%\opencascade-%OCCT_VERSION%\win%ARCH_BITS%\vc%OCCT_VC_VER%"
:: Removed unneeded bits
rmdir /s /q "%INSTALL_DIR%\opencascade-%OCCT_VERSION%\data"
rmdir /s /q "%INSTALL_DIR%\opencascade-%OCCT_VERSION%\samples"
del "%INSTALL_DIR%\opencascade-%OCCT_VERSION%\*.bat"
:Python
set DEPENDENCY_NAME=Python %PYTHON_VERSION%
set DEPENDENCY_DIR=N/A
set PYTHON_AMD64_POSTFIX=-amd64
IF NOT %TARGET_ARCH%==x64 set PYTHON_AMD64_POSTFIX=
set PYTHON_INSTALLER=python-%PYTHON_VERSION%%PYTHON_AMD64_POSTFIX%.exe
IF NOT "%IFCOS_INSTALL_PYTHON%"=="TRUE" (
call cecho.cmd 0 13 "IFCOS_INSTALL_PYTHON not 'TRUE', skipping installation of Python."
goto :SWIG
)
:: nuget doesn't support providing architecture for packages.
if NOT %TARGET_ARCH%==x64 (
call cecho.cmd 0 12 "Automatic insallation of Python for x86 builds is not supported,"
call cecho.cmd 0 12 "please install Python %PYTHON_VERSION% manually and ensure that it is available in PATH."
call cecho.cmd 0 12 "https://www.python.org/ftp/python/%PYTHON_VERSION%/%PYTHON_INSTALLER%"
goto :Error
)
if EXIST "%PYTHONHOME%" (
echo Found existing '%PYTHONHOME%', skipping installation.
goto :SWIG
)
"%NUGET_EXE%" install Python -Version %PYTHON_VERSION% -OutputDirectory "%DEPS_DIR%"
IF NOT %ERRORLEVEL%==0 GOTO :Error
:SWIG
set DEPENDENCY_NAME=SWIG
set SWIG_VERSION=4.1.0
set DEPENDENCY_DIR=%DEPS_DIR%\swig-%SWIG_VERSION%
set DEPENDENCY_INSTALL_DIR=%INSTALL_DIR%\swig-%SWIG_VERSION%
echo SWIG_INSTALL_DIR=%DEPENDENCY_INSTALL_DIR%>>"%~dp0\%BUILD_DEPS_CACHE_PATH%"
IF NOT DEFINED SKIP_INSTALLED_DEPS_CHECK IF EXIST "%DEPENDENCY_INSTALL_DIR%" (
echo Found existing "%DEPENDENCY_INSTALL_DIR%", skipping
goto :cgal
)
cd "%DEPS_DIR%"
:: Install bizon dependency for SWIG.
set SWIG_DEPENDENCY_NAME=%DEPENDENCY_NAME%
set DEPENDENCY_NAME=win_flex_bison
set WIN_FLEX_BIZON=win_flex_bison-2.5.25
set WIN_FLEX_BIZON_ZIP=%WIN_FLEX_BIZON%.zip
call :DownloadFile https://github.com/lexxmark/winflexbison/releases/download/v2.5.25/%WIN_FLEX_BIZON_ZIP% "%DEPS_DIR%" %WIN_FLEX_BIZON_ZIP%
IF NOT %ERRORLEVEL%==0 GOTO :Error
echo test %WIN_FLEX_BIZON%
call :ExtractArchive %WIN_FLEX_BIZON_ZIP% "%DEPS_DIR%\%WIN_FLEX_BIZON%" "%DEPS_DIR%\%WIN_FLEX_BIZON%"
IF NOT %ERRORLEVEL%==0 GOTO :Error
set DEPENDENCY_NAME=%SWIG_DEPENDENCY_NAME%
set SWIG_ZIP=swigwin-%SWIG_VERSION%.zip
call :DownloadFile https://github.com/swig/swig/archive/refs/tags/v%SWIG_VERSION%.zip "%DEPS_DIR%" swig-%SWIG_VERSION%.zip
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :ExtractArchive swig-%SWIG_VERSION%.zip "%DEPS_DIR%" "%DEPENDENCY_DIR%"
IF NOT %ERRORLEVEL%==0 GOTO :Error
cd "%DEPENDENCY_DIR%"
call :RunCMake -DCMAKE_INSTALL_PREFIX="%DEPENDENCY_INSTALL_DIR%" ^
-DWITH_PCRE=OFF ^
-DBISON_EXECUTABLE="%DEPS_DIR%\%WIN_FLEX_BIZON%\win_bison.exe"
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :BuildSolution "%DEPENDENCY_DIR%\%BUILD_DIR%\swig.sln" Release
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :InstallCMakeProject "%DEPENDENCY_DIR%\%BUILD_DIR%" Release
IF NOT %ERRORLEVEL%==0 GOTO :Error
robocopy "%INSTALL_DIR%\swigwin\bin" "%INSTALL_DIR%\swigwin" /move /e
:cgal
IF NOT DEFINED SKIP_INSTALLED_DEPS_CHECK IF EXIST "%INSTALL_DIR%\cgal" (
echo Found existing "%INSTALL_DIR%\cgal", skipping
goto :Eigen
)
set DEPENDENCY_NAME=cgal
set DEPENDENCY_DIR=%DEPS_DIR%\cgal
call :GitCloneAndCheckoutRevision https://github.com/CGAL/cgal.git "%DEPENDENCY_DIR%" %CGAL_VERSION%
IF NOT %ERRORLEVEL%==0 GOTO :Error
cd "%DEPENDENCY_DIR%"
git reset --hard
git apply --ignore-whitespace "%~dp0patches\cgal_no_zlib.patch"
call :RunCMake -DCMAKE_INSTALL_PREFIX="%INSTALL_DIR%\cgal" ^
-DBOOST_ROOT="%BOOST_ROOT%" ^
-DGMP_INCLUDE_DIR="%INSTALL_DIR%\mpir" ^
-DGMP_LIBRARIES="%INSTALL_DIR%\mpir\mpir.lib" ^
-DMPFR_INCLUDE_DIR="%INSTALL_DIR%\mpfr" ^
-DMPFR_LIBRARIES="%INSTALL_DIR%\mpfr\mpfr.lib" ^
-DCGAL_HEADER_ONLY=On ^
-DBOOST_LIBRARYDIR="%BOOST_LIBRARYDIR%"
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :BuildSolution "%DEPENDENCY_DIR%\%BUILD_DIR%\CGAL.sln" %BUILD_CFG%
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :InstallCMakeProject "%DEPENDENCY_DIR%\%BUILD_DIR%" %BUILD_CFG%
IF NOT %ERRORLEVEL%==0 GOTO :Error
:Eigen
set DEPENDENCY_NAME=Eigen
set DEPENDENCY_DIR=%INSTALL_DIR%\%DEPENDENCY_NAME%
IF NOT DEFINED SKIP_INSTALLED_DEPS_CHECK IF EXIST "%INSTALL_DIR%\%DEPENDENCY_NAME%" (
echo Found existing "%INSTALL_DIR%\%DEPENDENCY_NAME%", skipping
goto :zstd
)
call :GitCloneAndCheckoutRevision https://gitlab.com/libeigen/eigen.git "%DEPENDENCY_DIR%" %EIGEN_VERSION%
:zstd
set DEPENDENCY_NAME=zstd
set ZSTD_VERSION=1.5.7
set ZSTD_ZIP=zstd-%ZSTD_VERSION%.zip
set DEPENDENCY_DIR=%DEPS_DIR%\%DEPENDENCY_NAME%-%ZSTD_VERSION%
IF NOT DEFINED SKIP_INSTALLED_DEPS_CHECK IF EXIST "%INSTALL_DIR%\%DEPENDENCY_NAME%" (
echo Found existing "%INSTALL_DIR%\%DEPENDENCY_NAME%", skipping
goto :rocksdb
)
cd %DEPS_DIR%
call :DownloadFile ^
https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD_VERSION%.zip ^
"%DEPS_DIR%" %ZSTD_ZIP%
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :ExtractArchive %ZSTD_ZIP% "%DEPS_DIR%" "%DEPENDENCY_DIR%"
IF NOT %ERRORLEVEL%==0 GOTO :Error
cd "%DEPENDENCY_DIR%"\build\cmake
call :RunCMake -DCMAKE_INSTALL_PREFIX="%INSTALL_DIR%\zstd" -DZSTD_BUILD_STATIC=ON -DZSTD_BUILD_SHARED=OFF
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :BuildSolution "%DEPENDENCY_DIR%\build\cmake\%BUILD_DIR%\zstd.sln" %BUILD_CFG%
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :InstallCMakeProject "%DEPENDENCY_DIR%\build\cmake\%BUILD_DIR%" %BUILD_CFG%
IF NOT %ERRORLEVEL%==0 GOTO :Error
:rocksdb
set DEPENDENCY_NAME=rocksdb
set ROCKSDB_VERSION=9.11.2
set ROCKSDB_ZIP=rocksdb-%ROCKSDB_VERSION%.zip
set DEPENDENCY_DIR=%DEPS_DIR%\%DEPENDENCY_NAME%-%ROCKSDB_VERSION%
IF NOT DEFINED SKIP_INSTALLED_DEPS_CHECK IF EXIST "%INSTALL_DIR%\%DEPENDENCY_NAME%" (
echo Found existing "%INSTALL_DIR%\%DEPENDENCY_NAME%", skipping
goto :Successful
)
cd %DEPS_DIR%
call :DownloadFile ^
https://github.com/facebook/rocksdb/archive/refs/tags/v%ROCKSDB_VERSION%.zip ^
"%DEPS_DIR%" %ROCKSDB_ZIP%
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :ExtractArchive %ROCKSDB_ZIP% "%DEPS_DIR%" "%DEPENDENCY_DIR%"
IF NOT %ERRORLEVEL%==0 GOTO :Error
cd "%DEPENDENCY_DIR%"
:: see rocksdb\thirdparty.inc
:: providing package is not supported on Windows.
set ZSTD_INCLUDE=%INSTALL_DIR%\zstd\include
set ZSTD_LIB_DEBUG=%INSTALL_DIR%\zstd\lib\zstd_static.lib
set ZSTD_LIB_RELEASE=%INSTALL_DIR%\zstd\lib\zstd_static.lib
call :RunCMake -DCMAKE_INSTALL_PREFIX="%INSTALL_DIR%\rocksdb" ^
-DROCKSDB_INSTALL_ON_WINDOWS=On ^
-DFAIL_ON_WARNINGS=Off ^
-DWITH_TESTS=OFF ^
-DWITH_ZSTD=On ^
-DPORTABLE=1
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :BuildSolution "%DEPENDENCY_DIR%\%BUILD_DIR%\rocksdb.sln" %BUILD_CFG%
IF NOT %ERRORLEVEL%==0 GOTO :Error
call :InstallCMakeProject "%DEPENDENCY_DIR%\%BUILD_DIR%" %BUILD_CFG%
IF NOT %ERRORLEVEL%==0 GOTO :Error
:: :tbb
:: set DEPENDENCY_NAME=tbb
:: set DEPENDENCY_DIR=%DEPS_DIR%\tbb
:: call :GitCloneAndCheckoutRevision https://github.com/wjakob/tbb "%DEPENDENCY_DIR%" 9e219e24fe223b299783200f217e9d27790a87b0
:: IF NOT %ERRORLEVEL%==0 GOTO :Error
:: cd "%DEPENDENCY_DIR%"
:: call :RunCMake -DCMAKE_INSTALL_PREFIX="%INSTALL_DIR%\tbb" ^
:: -DBUILD_SHARED_LIBS=Off
:: IF NOT %ERRORLEVEL%==0 GOTO :Error
:: call :BuildSolution "%DEPENDENCY_DIR%\%BUILD_DIR%\TBB.sln" %BUILD_CFG%
:: IF NOT %ERRORLEVEL%==0 GOTO :Error
:: call :InstallCMakeProject "%DEPENDENCY_DIR%\%BUILD_DIR%" %BUILD_CFG%
:: IF NOT %ERRORLEVEL%==0 GOTO :Error
::
:: :usd
:: set DEPENDENCY_NAME=usd
:: set DEPENDENCY_DIR=%DEPS_DIR%\usd
:: call :GitCloneAndCheckoutRevision https://github.com/PixarAnimationStudios/OpenUSD "%DEPENDENCY_DIR%" v24.05
:: IF NOT %ERRORLEVEL%==0 GOTO :Error
:: cd "%DEPENDENCY_DIR%"
:: call :RunCMake -DCMAKE_INSTALL_PREFIX="%INSTALL_DIR%\usd" ^
:: -DBOOST_ROOT="%DEPS_DIR%\boost_%BOOST_VER%" ^
:: -DOneTBB_CMAKE_ENABLE=On ^
:: -DTBB_ROOT_DIR="%INSTALL_DIR%\tbb" ^
:: -DPXR_ENABLE_PYTHON_SUPPORT=FALSE ^
:: -DPXR_ENABLE_GL_SUPPORT=FALSE ^
:: -DPXR_BUILD_IMAGING=FALSE ^
:: -DPXR_BUILD_TUTORIALS=FALSE ^
:: -DPXR_BUILD_EXAMPLES=FALSE ^
:: -DPXR_BUILD_USD_TOOLS=FALSE ^
:: -DPXR_BUILD_TESTS=FALSE ^
:: -DBUILD_SHARED_LIBS=Off ^
:: -DBOOST_LIBRARYDIR="%DEPS_DIR%\boost_%BOOST_VER%\stage\vs%VS_VER%-%VS_PLATFORM%\lib"
:: IF NOT %ERRORLEVEL%==0 GOTO :Error
:: call :BuildSolution "%DEPENDENCY_DIR%\%BUILD_DIR%\USD.sln" %BUILD_CFG%
:: IF NOT %ERRORLEVEL%==0 GOTO :Error
:: call :InstallCMakeProject "%DEPENDENCY_DIR%\%BUILD_DIR%" %BUILD_CFG%
:: IF NOT %ERRORLEVEL%==0 GOTO :Error
:Successful
echo.
call "%~dp0\utils\cecho.cmd" 0 10 "%PROJECT_NAME% dependencies built."
set IFCOS_SCRIPT_RET=0
goto :Finish
:ErrorAndPrintUsage
echo.
call :PrintUsage
:Error
echo.
call "%~dp0\utils\cecho.cmd" 0 12 "An error occurred! Aborting! Last logged action: %LAST_ACTION%"
set IFCOS_SCRIPT_RET=1
goto :Finish
:Finish
:: Print end time and elapsed time, http://stackoverflow.com/a/9935540
if not defined BUILD_STARTED goto :BuildTimeSkipped
set END_TIME=%TIME%
for /F "tokens=1-4 delims=:.," %%a in ("%START_TIME%") do (
set /A "start=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
)
for /F "tokens=1-4 delims=:.," %%a in ("%END_TIME%") do (
set /A "end=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
)
set /A elapsed=end-start
set /A hh=elapsed/(60*60*100), rest=elapsed%%(60*60*100), mm=rest/(60*100), rest%%=60*100, ss=rest/100, cc=rest%%100
if %mm% lss 10 set mm=0%mm%
if %ss% lss 10 set ss=0%ss%
if %cc% lss 10 set cc=0%cc%
echo.
echo Build ended at %END_TIME%. Time elapsed %hh%:%mm%:%ss%.%cc%.
:BuildTimeSkipped
set PATH=%ORIGINAL_PATH%
cd "%~dp0"
exit /b %IFCOS_SCRIPT_RET%
::::::::::::::::::::::::::::::::::::: Subroutines :::::::::::::::::::::::::::::::::::::
:: DownloadFile - Downloads a file using PowerShell
:: Params: %1 url, %2 destinationDir, %3 filename
:DownloadFile
mkdir "%2"
pushd "%2"
if not exist "%~3". (
call cecho.cmd 0 13 "Downloading %DEPENDENCY_NAME% into %~2."
powershell -Command "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; $webClient = new-object System.Net.WebClient; $webClient.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials; $webClient.DownloadFile('%1', '%3')"
REM Old wget version in case someone has problem with PowerShell: wget --no-check-certificate %1
) else (
call cecho.cmd 0 13 "%DEPENDENCY_NAME% already downloaded. Skipping."
)
set RET=%ERRORLEVEL%
set LAST_ACTION=DownloadFile '%DEPENDENCY_NAME%'.
popd
exit /b %RET%
:: ExtractArchive - Extracts an archive file using 7-zip
:: Params: %1 filename, %2 destinationDir, %3 dirAfterExtraction
:ExtractArchive
if not exist "%~3". (
call cecho.cmd 0 13 "Extracting %DEPENDENCY_NAME% into %~2 from %1"
7za x %1 -y -o%2 > nul
) else (
call cecho.cmd 0 13 "%DEPENDENCY_NAME% already extracted into %~3. Skipping."
)
set RET=%ERRORLEVEL%
set LAST_ACTION=ExtractArchive '%DEPENDENCY_NAME%'.
exit /b %RET%
:: GitCloneOrPullRepository - Clones or pulls (if repository already cloned) a Git repository
:: Params: %1 gitUrl, %2 destDir
:: F.ex. call :GitCloneRepository https://github.com/KhronosGroup/OpenCOLLADA.git "%DEPS_DIR%\OpenCOLLADA\"
:GitCloneOrPullRepository
if not exist "%~2". (
call cecho.cmd 0 13 "Cloning %DEPENDENCY_NAME% into %~2."
pushd "%DEPS_DIR%"
call git clone %1 %2
set RET=!ERRORLEVEL!
) else (
call cecho.cmd 0 13 "%DEPENDENCY_NAME% already cloned. Pulling latest changes."
git reset --hard
pushd %2
call git pull
set RET=0
)
popd
exit /b %RET%
:: GitCloneAndCheckoutRevision - Clones a Git repository and checks out a specific revision or tag
:: Params: %1 gitUrl, %2 destDir, %3 revision
:: F.ex. call :GitCloneAndCheckoutRevision https://github.com/KhronosGroup/OpenCOLLADA.git "%DEPENDENCY_DIR%" 064a60b65c2c31b94f013820856bc84fb1937cc6
:GitCloneAndCheckoutRevision
if not exist "%~2". (
call cecho.cmd 0 13 "Cloning %DEPENDENCY_NAME% into %~2."
pushd "%DEPS_DIR%"
call git clone %1 %2
set RET=!ERRORLEVEL!
if not "!RET!"=="0" exit /b !RET!
popd
) else (
call cecho.cmd 0 13 "%DEPENDENCY_NAME% already cloned."
set RET=0
)
pushd "%2"
call git fetch
call cecho.cmd 0 13 "Checking out %DEPENDENCY_NAME% revision %3."
call git reset --hard
call git checkout %3
set RET=%ERRORLEVEL%
popd
exit /b %RET%
:: RunCMake - Runs CMake for a CMake-based project
:: Params: %* cmakeOptions
:: NOTE cd to root CMakeLists.txt folder before calling this if the CMakeLists.txt is not in the repo root.
:RunCMake
call cecho.cmd 0 13 "Running CMake for %DEPENDENCY_NAME%."
IF NOT EXIST %BUILD_DIR%. mkdir %BUILD_DIR%
IF NOT %ERRORLEVEL%==0 GOTO :Error
pushd %BUILD_DIR%
:: TODO make deleting cache a parameter for this subroutine? We probably want to delete the
:: cache always e.g. when we've had new changes in the repository.
IF %BUILD_TYPE%==Rebuild IF EXIST CMakeCache.txt. del CMakeCache.txt
IF NOT "%VS_TOOLSET_HOST%"=="" (
cmake .. -G %GENERATOR% -A %VS_PLATFORM% -T %VS_TOOLSET_HOST% %*
) ELSE (
cmake .. -G %GENERATOR% -A %VS_PLATFORM% %*
)
set RET=%ERRORLEVEL%
popd
exit /b %RET%
:: TODO add BuildCMakeProject which utilizes cmake --build
:: BuildSolution - Builds/Rebuilds/Cleans a solution using MSBuild
:: Params: %1 solutioName, %2 configuration
:BuildSolution
IF [%~3]==[] (
set TARGET=%BUILD_TYPE%
) ELSE (
IF /I %BUILD_TYPE%==Build (
set TARGET="%3"
) ELSE (
set TARGET="%3:%BUILD_TYPE%"
)
)
call cecho.cmd 0 13 "Building %TARGET% of %DEPENDENCY_NAME%. Please be patient, this will take a while."
:: whole program optimization avoids Visual C++ hanging when compiling 32-bit release OCCT up to version 7.4.0
IF %COMPILE_WITH_WPO%==FALSE (
%MSBUILD_CMD% %1 /p:configuration=%2;platform=%VS_PLATFORM% /t:"%TARGET%"
) ELSE (
%MSBUILD_CMD% %1 /p:configuration=%2;platform=%VS_PLATFORM%;WholeProgramOptimization=TRUE /t:"%TARGET%"
)
exit /b %ERRORLEVEL%
:: InstallCMakeProject - Builds the INSTALL project of CMake-based project
:: Params: %1 buildDir, %2 == configuration
:: NOTE the actual install dir is set during cmake run.
:: TODO Utilize cmake --build --target INSTALL
:InstallCMakeProject
pushd %1
call cecho.cmd 0 13 "Installing %2 %DEPENDENCY_NAME%. Please be patient, this will take a while."
:: whole program optimization avoids Visual C++ hanging when compiling 32-bit release OCCT up to version 7.4.0
IF %COMPILE_WITH_WPO%==FALSE (
%MSBUILD_CMD% INSTALL.%VCPROJ_FILE_EXT% /p:configuration=%2;platform=%VS_PLATFORM%
) ELSE (
%MSBUILD_CMD% INSTALL.%VCPROJ_FILE_EXT% /p:configuration=%2;platform=%VS_PLATFORM%;WholeProgramOptimization=TRUE
)
set RET=%ERRORLEVEL%
popd
exit /b %RET%
:: PrintUsage - Prints usage information
:PrintUsage
call "%~dp0\utils\cecho.cmd" 0 10 "Requirements for a successful execution:"
echo 1. Install PowerShell (preinstalled in Windows ^>= 7) version 5 or higher and make sure 'powershell' is accessible from PATH.
echo - https://support.microsoft.com/en-us/kb/968929
echo 2. Install Git and make sure 'git' is accessible from PATH.
echo - https://git-for-windows.github.io/
echo 3. Install CMake and make sure 'cmake' is accessible from PATH.
echo - http://www.cmake.org/
echo 4. Visual Studio 2013 or newer with C++ toolset.
echo - https://www.visualstudio.com/
echo 5. Run this batch script with Visual Studio environment variables set.
echo - https://msdn.microsoft.com/en-us/library/ms229859(v=vs.110).aspx
echo.
echo NB: This script needs to be ran from the directory directly containing it.
echo.
+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 "")