Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 26 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
IfcOpenShell
============
Open source (LGPL) software library for working with the IFC ([IFC2x3 TC1] and [IFC4]) file format.

[http://ifcopenshell.org](http://ifcopenshell.org)
[http://academy.ifcopenshell.org](http://academy.ifcopenshell.org)
IfcOpenShell is an open source ([LGPL]) software library for working with the Industry Foundation Classes ([IFC])
file format. Currently supported IFC releases are [IFC2x3 TC1] and [IFC4].

For more information, see
* [http://ifcopenshell.org](http://ifcopenshell.org)
* [http://academy.ifcopenshell.org](http://academy.ifcopenshell.org)

Prerequisites
=============
* Git, CMake (2.6 or newer), Visual Studio 2008 or newer with C++ toolset (Windows), or GCC (*nix, Clang untested).

-------------
* Git
* CMake (2.6 or newer)
* Windows: Visual Studio 2008 or newer with C++ toolset, MinGW not supported currently
* *nix: GCC 4.7 or newer, or Clang (any version should work, but not tested)

Dependencies
============
-------------
* [Boost](http://www.boost.org/)
* Open Cascade - *optional*, but required for building IfcGeom
([official](http://www.opencascade.org/getocc/download/loadocc/) or [community edition](https://github.com/tpaviot/oce))
Expand All @@ -21,17 +24,15 @@ Dependencies
For handling code pages and Unicode in the parser
* [OpenCOLLADA](https://github.com/khronosGroup/OpenCOLLADA/) - *optional*
For IfcConvert to be able to write tessellated Collada (.dae) files
* [SWIG](http://www.swig.org/), [Python](https://www.python.org/) libraries - *optional*
* [SWIG](http://www.swig.org/) and [Python](https://www.python.org/) - *optional*
For building the IfcOpenShell Python interface and the Blender add-on
* 3ds Max SDK - *optional*
For building the 3ds Max plug-in


Compiling on Windows
====================
Users are advised to build IfcOpenShell using the CMake file provided in
the cmake/ folder.
* [3ds Max SDK](http://www.autodesk.com/products/3ds-max/free-trial) - *optional*
For building the 3ds Max plug-in.
All recent versions of 3ds Max (2014 and newer) are 64-bit only, so a 64-bit installation is assumed.

Building IfcOpenShell
---------------------
### Compiling on Windows
The preferred way to fetch and build this project's dependencies is to use the build scripts
in win/ folder. **See [win/readme.md] for more information**. Instructions in a nutshell
(**assuming Visual Studio 2015 x64 environment variables set**):
Expand All @@ -54,16 +55,9 @@ Alternatively, one can use the utility batch files to build and install the proj
> build-ifcopenshell.cmd
> install-ifcopenshell.cmd

Alternatively, the old Visual Studio solution and project files requiring manual work can
be found from the win/sln folder.


Compiling on *nix
=================
Users are advised to build IfcOpenShell using the CMake file provided in
the cmake/ folder. There might be an Open CASCADE package in your operating
system's software repository. If not, you will need to compile Open
CASCADE yourself. See http://opencascade.org.
### Compiling on *nix
There might be an Open CASCADE package in your operating system's software repository. If not, you will need to compile
Open CASCADE yourself. See http://opencascade.org.

For building the IfcPython wrapper, SWIG and Python development are
required.
Expand Down Expand Up @@ -95,7 +89,7 @@ To build IfcOpenShell please take the following steps:
If all worked out correctly you can now use IfcOpenShell. See the examples below.

Usage examples
==============
--------------

**Invoking IfcConvert from the command line**

Expand Down Expand Up @@ -165,6 +159,8 @@ Usage examples
>>> # Writing IFC-SPF files to disk:
>>> f.write("out.ifc")

[win/readme.md]: https://github.com/IfcOpenShell/IfcOpenShell/tree/master/win/readme.md "win/readme.md"
[LGPL]: https://github.com/IfcOpenShell/IfcOpenShell/tree/master/COPYING "LGPL"
[IFC]: http://www.buildingsmart-tech.org/specifications/ifc-overview "IFC"
[IFC2x3 TC1]: http://www.buildingsmart-tech.org/specifications/ifc-releases/ifc2x3-tc1-release "IFC2x3 TC1"
[IFC4]: http://www.buildingsmart-tech.org/specifications/ifc-releases/ifc4-release "IFC4"
[IFC4]: http://www.buildingsmart-tech.org/specifications/ifc-releases/ifc4-release "IFC4"
[win/readme.md]: https://github.com/IfcOpenShell/IfcOpenShell/tree/master/win/readme.md "win/readme.md"
13 changes: 13 additions & 0 deletions cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ OPTION(USE_IFC4 "Use IFC 4 instead of IFC 2x3 (full rebuild recommended when swi
OPTION(BUILD_IFCPYTHON "Build IfcPython." ON)
OPTION(BUILD_EXAMPLES "Build example applications." ON)
OPTION(USE_VLD "Use Visual Leak Detector for debugging memory leaks, MSVC-only." OFF)
OPTION(BUILD_IFCMAX "Build IfcMax, a 3ds Max plug-in, Windows-only." OFF)
# TODO QtViewer is deprecated ATM as it uses the 0.4 API
# OPTION(BUILD_QTVIEWER "Build IfcOpenShell Qt GUI Viewer (requires Qt 4 framework)." OFF)

Expand All @@ -48,6 +49,9 @@ UNIFY_ENVVARS_AND_CACHE(OPENCOLLADA_INCLUDE_DIR)
UNIFY_ENVVARS_AND_CACHE(OPENCOLLADA_LIBRARY_DIR)
UNIFY_ENVVARS_AND_CACHE(PCRE_LIBRARY_DIR)
UNIFY_ENVVARS_AND_CACHE(PYTHON_EXECUTABLE)
IF(WIN32)
UNIFY_ENVVARS_AND_CACHE(THREEDS_MAX_SDK_HOME)
ENDIF()

# Find Boost
IF(MSVC)
Expand Down Expand Up @@ -239,6 +243,11 @@ if(ENABLE_BUILD_OPTIMIZATIONS)
endif()

IF(MSVC)
# Enable solution folders (free VS versions prior to 2012 don't support solution folders)
if (MSVC_VERSION GREATER 1600)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
endif()

IF(USE_VLD)
ADD_DEFINITIONS(-DUSE_VLD)
ENDIF()
Expand Down Expand Up @@ -419,6 +428,10 @@ IF(BUILD_EXAMPLES)
ADD_SUBDIRECTORY(../src/examples examples)
ENDIF()

IF(BUILD_IFCMAX)
ADD_SUBDIRECTORY(../src/ifcmax ifcmax)
ENDIF()

# CMake installation targets
INSTALL(FILES ${IFCPARSE_H_FILES} DESTINATION include/ifcparse)
INSTALL(FILES ${IFCGEOM_H_FILES} DESTINATION include/ifcgeom)
Expand Down
2 changes: 2 additions & 0 deletions src/examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

ADD_EXECUTABLE(IfcParseExamples IfcParseExamples.cpp)
TARGET_LINK_LIBRARIES(IfcParseExamples IfcParse)
set_target_properties(IfcParseExamples PROPERTIES FOLDER Examples)

ADD_EXECUTABLE(IfcOpenHouse IfcOpenHouse.cpp)
TARGET_LINK_LIBRARIES(IfcOpenHouse IfcParse IfcGeom ${OPENCASCADE_LIBRARIES})
set_target_properties(IfcOpenHouse PROPERTIES FOLDER Examples)
39 changes: 39 additions & 0 deletions src/ifcmax/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
################################################################################
# #
# 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/>. #
# #
################################################################################

INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES} ${OCC_INCLUDE_DIR} ${OPENCOLLADA_INCLUDE_DIRS} ${ICU_INCLUDE_DIR}
${Boost_INCLUDE_DIRS} ${THREEDS_MAX_SDK_HOME}/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} ${OCC_LIBRARY_DIR} ${OPENCOLLADA_LIBRARY_DIR}
${ICU_LIBRARY_DIR} ${Boost_LIBRARY_DIRS} ${THREEDS_MAX_SDK_HOME}/lib/x64/Release
)

ADD_LIBRARY(IfcMax SHARED IfcMax.h IfcMax.cpp)

TARGET_LINK_LIBRARIES(IfcMax IfcParse IfcGeom Comctl32.lib zlibdll.lib bmm.lib core.lib CustDlg.lib edmodel.lib expr.lib
flt.lib geom.lib gfx.lib gup.lib imageViewers.lib ManipSys.lib maxnet.lib Maxscrpt.lib
maxutil.lib MenuMan.lib menus.lib mesh.lib MNMath.lib Paramblk2.lib particle.lib Poly.lib RenderUtil.lib
tessint.lib viewfile.lib ${OPENCASCADE_LIBRARIES}
)

SET_TARGET_PROPERTIES(IfcMax PROPERTIES SUFFIX ".dli")

INSTALL(TARGETS IfcMax RUNTIME DESTINATION bin)
96 changes: 53 additions & 43 deletions src/ifcmax/IfcMax.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,49 +20,54 @@
#include <map>
#include <set>

#include <Max.h>
#include <stdmat.h>
#include <istdplug.h>

#include "../ifcmax/IfcMax.h"
#include "IfcMax.h"
#include "../ifcgeom/IfcGeomIterator.h"

static const int NUM_MATERIAL_SLOTS = 24;

int controlsInit = false;

BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved) {
BOOL WINAPI DllMain(HINSTANCE /*hinstDLL*/, ULONG /*fdwReason*/, LPVOID /*lpvReserved*/) {
static int controlsInit = false;
if (!controlsInit) {
controlsInit = true;
InitCommonControls();
}
return true;
}

__declspec( dllexport ) const TCHAR* LibDescription() {
return _T("IfcOpenShell IFC Importer");
}
return TRUE;
}

__declspec( dllexport ) int LibNumberClasses() { return 1; }

static class IFCImpClassDesc:public ClassDesc {
static class IFCImpClassDesc :public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading = FALSE) {return new IFCImp;}
const TCHAR * ClassName() {return _T("IFCImp");}
SClass_ID SuperClassID() {return SCENE_IMPORT_CLASS_ID;}
Class_ID ClassID() {return Class_ID(0x3f230dbf, 0x5b3015c2);}
const TCHAR* Category() {return _T("Chrutilities");}
int IsPublic() { return 1; }
void * Create(BOOL /*loading = FALSE*/) { return new IFCImp; }
// TODO Delete() function?
const TCHAR * ClassName() { return _T("IFCImp"); }
SClass_ID SuperClassID() { return SCENE_IMPORT_CLASS_ID; }
Class_ID ClassID() { return Class_ID(0x3f230dbf, 0x5b3015c2); }
const TCHAR* Category() { return _T("Chrutilities"); }
} IFCImpDesc;

__declspec( dllexport ) ClassDesc* LibClassDesc(int i) {
return i == 0 ? &IFCImpDesc : 0;
#define DLLEXPORT __declspec(dllexport)

extern "C" {

DLLEXPORT const TCHAR* LibDescription() {
return _T("IfcOpenShell IFC Importer");
}

DLLEXPORT int LibNumberClasses() { return 1; }

DLLEXPORT ClassDesc* LibClassDesc(int i) {
return i == 0 ? &IFCImpDesc : 0;
}

__declspec( 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) {
Expand All @@ -82,7 +87,7 @@ const TCHAR * IFCImp::AuthorName() {
}

const TCHAR * IFCImp::CopyrightMessage() {
return _T("Copyight (c) 2011 IfcOpenShell");
return _T("Copyright (c) 2011-2016 IfcOpenShell");
}

const TCHAR * IFCImp::OtherMessage1() {
Expand All @@ -97,13 +102,14 @@ unsigned int IFCImp::Version() {
return 12;
}

static BOOL CALLBACK AboutBoxDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
return TRUE;
}
// TODO Use this in IFCImp::ShowAbout() if/when wanted
//static BOOL CALLBACK AboutBoxDlgProc(HWND /*hWnd*/, UINT /*msg*/, WPARAM /*wParam*/, LPARAM /*lParam*/) {
// return TRUE;
//}

void IFCImp::ShowAbout(HWND hWnd) {}
void IFCImp::ShowAbout(HWND /*hWnd*/) {}

DWORD WINAPI fn(LPVOID arg) { return 0; }
DWORD WINAPI fn(LPVOID /*arg*/) { return 0; }

#if MAX_RELEASE > 14000
# define S(x) (TSTR::FromCStr(x.c_str()))
Expand All @@ -113,16 +119,17 @@ DWORD WINAPI fn(LPVOID arg) { return 0; }
# define S(x) (CStr(x.c_str()))
#endif

Mtl* FindMaterialByName(MtlBaseLib* library, const std::string& material_name) {
const int mat_index = library->FindMtlByName(S(material_name));
static Mtl* FindMaterialByName(MtlBaseLib* library, const std::string& material_name) {
TSTR mat_name = S(material_name);
const int mat_index = library->FindMtlByName(mat_name);
Mtl* m = 0;
if (mat_index != -1) {
m = static_cast<Mtl*>((*library)[mat_index]);
}
return m;
}

Mtl* FindOrCreateMaterial(MtlBaseLib* library, Interface* max_interface, int& slot, const IfcGeom::Material& material) {
static Mtl* FindOrCreateMaterial(MtlBaseLib* library, Interface* max_interface, int& slot, const IfcGeom::Material& material) {
Mtl* m = FindMaterialByName(library, material.name());
if (m == 0) {
StdMat2* stdm = NewDefaultStdMat();
Expand All @@ -136,10 +143,10 @@ Mtl* FindOrCreateMaterial(MtlBaseLib* library, Interface* max_interface, int& sl
stdm->SetSpecular(Color(specular[0], specular[1], specular[2]),t);
}
if (material.hasSpecularity()) {
stdm->SetShininess(material.specularity(), t);
stdm->SetShininess((float)material.specularity(), t);
}
if (material.hasTransparency()) {
stdm->SetOpacity(1.0 - material.transparency(), t);
stdm->SetOpacity(1.0f - (float)material.transparency(), t);
}
m = stdm;
m->SetName(S(material.name()));
Expand All @@ -151,7 +158,10 @@ Mtl* FindOrCreateMaterial(MtlBaseLib* library, Interface* max_interface, int& sl
return m;
}

Mtl* ComposeMultiMaterial(std::map<std::vector<std::string>, Mtl*>& multi_mats, MtlBaseLib* library, Interface* max_interface, int& slot, const std::vector<IfcGeom::Material>& materials, const std::string& object_type, const std::vector<int>& material_ids) {
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,
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) {
Expand Down Expand Up @@ -184,7 +194,7 @@ Mtl* ComposeMultiMaterial(std::map<std::vector<std::string>, Mtl*>& multi_mats,
return i->second;
}
MultiMtl* multi_mat = NewDefaultMultiMtl();
multi_mat->SetNumSubMtls(material_names.size());
multi_mat->SetNumSubMtls((int)material_names.size());
int mtl_id = 0;
if (needs_default) {
multi_mat->SetSubMtlAndName(mtl_id ++, default_material, default_material->GetName());
Expand All @@ -201,7 +211,7 @@ Mtl* ComposeMultiMaterial(std::map<std::vector<std::string>, Mtl*>& multi_mats,
return multi_mat;
}

int IFCImp::DoImport(const TCHAR *name, ImpInterface *impitfc, Interface *itfc, BOOL suppressPrompts) {
int IFCImp::DoImport(const TCHAR *name, ImpInterface *impitfc, Interface *itfc, BOOL /*suppressPrompts*/) {

IfcGeom::IteratorSettings settings;
settings.use_world_coords() = false;
Expand All @@ -217,7 +227,7 @@ int IFCImp::DoImport(const TCHAR *name, ImpInterface *impitfc, Interface *itfc,
#endif

IfcGeom::Iterator<float> iterator(settings, fn_mb);

delete fn_mb;
if (!iterator.initialize()) return false;

itfc->ProgressStart(_T("Importing file..."), TRUE, fn, NULL);
Expand All @@ -237,12 +247,12 @@ int IFCImp::DoImport(const TCHAR *name, ImpInterface *impitfc, Interface *itfc,

TriObject* tri = CreateNewTriObject();

const int numVerts = o->geometry().verts().size()/3;
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 = o->geometry().faces().size()/3;
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();
Expand Down Expand Up @@ -274,7 +284,7 @@ int IFCImp::DoImport(const TCHAR *name, ImpInterface *impitfc, Interface *itfc,
tri->mesh.faces[i].setVerts(v1, v2, v3);
tri->mesh.faces[i].setEdgeVisFlags(b1, b2, b3);

MtlID mtlid = o->geometry().material_ids()[i];
MtlID mtlid = (MtlID)o->geometry().material_ids()[i];
if (needs_default) {
mtlid ++;
}
Expand Down Expand Up @@ -310,4 +320,4 @@ int IFCImp::DoImport(const TCHAR *name, ImpInterface *impitfc, Interface *itfc,
itfc->ProgressEnd();

return true;
}
}
Loading