freecad-cam/Mod/BIM/nativeifc/ifc_import.py
2026-02-01 01:59:24 +01:00

214 lines
7.8 KiB
Python

# ***************************************************************************
# * *
# * Copyright (c) 2022 Yorik van Havre <yorik@uncreated.net> *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * This program 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 *
# * GNU Library General Public License for more details. *
# * *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
# * *
# ***************************************************************************
import importlib
import os
import time
import FreeCAD
from nativeifc import ifc_tools
from nativeifc import ifc_psets
from nativeifc import ifc_materials
from nativeifc import ifc_layers
from nativeifc import ifc_status
if FreeCAD.GuiUp:
import FreeCADGui
import Arch_rc
PARAMS = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/NativeIFC")
def open(filename):
"""Opens an IFC file"""
from PySide import QtCore # lazy loading
name = os.path.splitext(os.path.basename(filename))[0]
FreeCAD.IsOpeningIFC = True
doc = FreeCAD.newDocument()
doc.Label = name
FreeCAD.setActiveDocument(doc.Name)
insert(filename, doc.Name, singledoc=True)
del FreeCAD.IsOpeningIFC
QtCore.QTimer.singleShot(100, unset_modified)
return doc
def insert(
filename,
docname,
strategy=None,
shapemode=None,
switchwb=None,
silent=False,
singledoc=None,
):
"""Inserts an IFC document in a FreeCAD document"""
from PySide import QtCore # lazy loading
strategy, shapemode, switchwb = get_options(strategy, shapemode, switchwb, silent)
if strategy is None:
print("Aborted.")
return
stime = time.time()
try:
document = FreeCAD.getDocument(docname)
except:
document = FreeCAD.newDocument()
if singledoc is None:
singledoc = PARAMS.GetBool("SingleDoc", False)
if singledoc:
prj_obj = ifc_tools.convert_document(document, filename, shapemode, strategy)
QtCore.QTimer.singleShot(100, toggle_lock_on)
else:
prj_obj = ifc_tools.create_document_object(
document, filename, shapemode, strategy
)
QtCore.QTimer.singleShot(100, toggle_lock_off)
if PARAMS.GetBool("LoadOrphans", True):
ifc_tools.load_orphans(prj_obj)
if not silent and PARAMS.GetBool("LoadMaterials", False):
ifc_materials.load_materials(prj_obj)
if PARAMS.GetBool("LoadLayers", False):
ifc_layers.load_layers(prj_obj)
if PARAMS.GetBool("LoadPsets", False):
ifc_psets.load_psets(prj_obj)
document.recompute()
# print a reference to the IFC file on the console
if FreeCAD.GuiUp and PARAMS.GetBool("IfcFileToConsole", False):
if isinstance(prj_obj, FreeCAD.DocumentObject):
pstr = "FreeCAD.getDocument('{}').{}.Proxy.ifcfile"
pstr = pstr.format(prj_obj.Document.Name, prj_obj.Name)
else:
pstr = "FreeCAD.getDocument('{}').Proxy.ifcfile"
pstr = pstr.format(prj_obj.Name)
pstr = "ifcfile = " + pstr
pstr += " # warning: make sure you know what you are doing when using this!"
FreeCADGui.doCommand(pstr)
endtime = "%02d:%02d" % (divmod(round(time.time() - stime, 1), 60))
fsize = round(os.path.getsize(filename) / 1048576, 2)
print("Imported", os.path.basename(filename), "(", fsize, "Mb ) in", endtime)
if FreeCAD.GuiUp and switchwb:
FreeCADGui.activateWorkbench("BIMWorkbench")
return document
def get_options(strategy=None, shapemode=None, switchwb=None, silent=False):
"""Shows a dialog to get import options
shapemode: 0 = full shape
1 = coin only
2 = no representation
strategy: 0 = only root object
1 = only bbuilding structure,
2 = all children
"""
psets = PARAMS.GetBool("LoadPsets", False)
materials = PARAMS.GetBool("LoadMaterials", False)
layers = PARAMS.GetBool("LoadLayers", False)
singledoc = PARAMS.GetBool("SingleDoc", False)
if strategy is None:
strategy = PARAMS.GetInt("ImportStrategy", 0)
if shapemode is None:
shapemode = PARAMS.GetInt("ShapeMode", 0)
if switchwb is None:
switchwb = PARAMS.GetBool("SwitchWB", True)
if silent:
return strategy, shapemode, switchwb
ask = PARAMS.GetBool("AskAgain", False)
if ask and FreeCAD.GuiUp:
import FreeCADGui
from PySide import QtGui
dlg = FreeCADGui.PySideUic.loadUi(":/ui/dialogImport.ui")
dlg.checkSwitchWB.hide() # TODO see what to do with this...
dlg.comboStrategy.setCurrentIndex(strategy)
dlg.comboShapeMode.setCurrentIndex(shapemode)
dlg.checkSwitchWB.setChecked(switchwb)
dlg.checkAskAgain.setChecked(ask)
dlg.checkLoadPsets.setChecked(psets)
dlg.checkLoadMaterials.setChecked(materials)
dlg.checkLoadLayers.setChecked(layers)
dlg.comboSingleDoc.setCurrentIndex(1 - int(singledoc))
result = dlg.exec_()
if not result:
return None, None, None
strategy = dlg.comboStrategy.currentIndex()
shapemode = dlg.comboShapeMode.currentIndex()
switchwb = dlg.checkSwitchWB.isChecked()
ask = dlg.checkAskAgain.isChecked()
psets = dlg.checkLoadPsets.isChecked()
materials = dlg.checkLoadMaterials.isChecked()
layers = dlg.checkLoadLayers.isChecked()
singledoc = dlg.comboSingleDoc.currentIndex()
PARAMS.SetInt("ImportStrategy", strategy)
PARAMS.SetInt("ShapeMode", shapemode)
PARAMS.SetBool("SwitchWB", switchwb)
PARAMS.SetBool("AskAgain", ask)
PARAMS.SetBool("LoadPsets", psets)
PARAMS.SetBool("LoadMaterials", materials)
PARAMS.SetBool("LoadLayers", layers)
PARAMS.SetBool("SingleDoc", bool(1 - singledoc))
return strategy, shapemode, switchwb
def get_project_type(silent=False):
"""Gets the type of project to make"""
ask = PARAMS.GetBool("ProjectAskAgain", True)
ptype = PARAMS.GetBool("ProjectFull", False)
if silent:
return ptype
if ask and FreeCAD.GuiUp:
import FreeCADGui
from PySide import QtGui
dlg = FreeCADGui.PySideUic.loadUi(":/ui/dialogCreateProject.ui")
result = dlg.exec_()
ask = not (dlg.checkBox.isChecked())
ptype = bool(result)
PARAMS.SetBool("ProjectAskAgain", ask)
PARAMS.SetBool("ProjectFull", ptype)
return ptype
# convenience functions
def toggle_lock_on():
ifc_status.on_toggle_lock(True, noconvert=True, setchecked=True)
def toggle_lock_off():
ifc_status.on_toggle_lock(False, noconvert=True, setchecked=True)
def unset_modified():
try:
FreeCADGui.ActiveDocument.Modified = False
except:
pass