BIM: Support for IfcOpenShell 0.8
This commit is contained in:
committed by
Chris Hennes
parent
16129930ab
commit
78a95759eb
@@ -55,6 +55,8 @@ __title__ = "FreeCAD IFC export"
|
||||
__author__ = ("Yorik van Havre", "Jonathan Wiedemann", "Bernd Hahnebach")
|
||||
__url__ = "https://www.freecad.org"
|
||||
|
||||
PARAMS = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/BIM")
|
||||
|
||||
# Templates and other definitions ****
|
||||
# Specific FreeCAD <-> IFC slang translations
|
||||
translationtable = {
|
||||
@@ -172,12 +174,9 @@ def getPreferences():
|
||||
# set schema
|
||||
if hasattr(ifcopenshell, "schema_identifier"):
|
||||
schema = ifcopenshell.schema_identifier
|
||||
elif ifcos_version >= 0.6:
|
||||
# v0.6 onwards allows to set our own schema
|
||||
schema = ["IFC4", "IFC2X3"][params.get_param_arch("IfcVersion")]
|
||||
else:
|
||||
schema = "IFC2X3"
|
||||
|
||||
# v0.6 onwards allows to set our own schema
|
||||
schema = PARAMS.GetString("DefaultIfcExportVersion", "IFC4")
|
||||
preferences["SCHEMA"] = schema
|
||||
|
||||
return preferences
|
||||
|
||||
@@ -35,6 +35,7 @@ from nativeifc import ifc_tools
|
||||
import multiprocessing
|
||||
import FreeCADGui
|
||||
from pivy import coin
|
||||
from PySide import QtCore
|
||||
|
||||
|
||||
def generate_geometry(obj, cached=False):
|
||||
@@ -76,6 +77,7 @@ def generate_geometry(obj, cached=False):
|
||||
elif obj.ViewObject and obj.ShapeMode == "Coin":
|
||||
node, placement = generate_coin(ifcfile, elements, cached)
|
||||
if node:
|
||||
#QtCore.QTimer.singleShot(0, lambda: set_representation(obj.ViewObject, node))
|
||||
set_representation(obj.ViewObject, node)
|
||||
colors = node[0]
|
||||
else:
|
||||
@@ -86,7 +88,7 @@ def generate_geometry(obj, cached=False):
|
||||
|
||||
# set shape and diffuse colors
|
||||
if colors:
|
||||
ifc_tools.set_colors(obj, colors) # TODO migrate here?
|
||||
QtCore.QTimer.singleShot(0, lambda: ifc_tools.set_colors(obj, colors)) # TODO migrate here?
|
||||
|
||||
|
||||
def generate_shape(ifcfile, elements, cached=False):
|
||||
@@ -140,7 +142,12 @@ def generate_shape(ifcfile, elements, cached=False):
|
||||
brep = item.geometry.brep_data
|
||||
shape = Part.Shape()
|
||||
shape.importBrepFromString(brep, False)
|
||||
mat = ifc_tools.get_freecad_matrix(item.transformation.matrix.data)
|
||||
if hasattr(item.transformation.matrix, "data"):
|
||||
# IfcOpenShell 0.7
|
||||
mat = ifc_tools.get_freecad_matrix(item.transformation.matrix.data)
|
||||
else:
|
||||
# IfcOpenShell 0.8
|
||||
mat = ifc_tools.get_freecad_matrix(item.transformation.matrix)
|
||||
shape.scale(ifc_tools.SCALE)
|
||||
shape.transformShape(mat)
|
||||
shapes.append(shape)
|
||||
@@ -248,7 +255,12 @@ def generate_coin(ifcfile, elements, cached=False):
|
||||
# colors
|
||||
if item.geometry.materials:
|
||||
color = item.geometry.materials[0].diffuse
|
||||
color = (float(color[0]), float(color[1]), float(color[2]))
|
||||
if hasattr(color, "r") and hasattr(color, "g"):
|
||||
# IfcOpenShell 0.8
|
||||
color = (color.r(), color.g(), color.b())
|
||||
else:
|
||||
# IfcOpenShell 0.7
|
||||
color = (float(color[0]), float(color[1]), float(color[2]))
|
||||
trans = item.geometry.materials[0].transparency
|
||||
if trans >= 0:
|
||||
color += (float(trans),)
|
||||
@@ -256,7 +268,12 @@ def generate_coin(ifcfile, elements, cached=False):
|
||||
color = (0.85, 0.85, 0.85)
|
||||
|
||||
# verts
|
||||
matrix = ifc_tools.get_freecad_matrix(item.transformation.matrix.data)
|
||||
if hasattr(item.transformation.matrix, "data"):
|
||||
# IfcOpenShell 0.7
|
||||
matrix = ifc_tools.get_freecad_matrix(item.transformation.matrix.data)
|
||||
else:
|
||||
# IfcOpenShell 0.8
|
||||
matrix = ifc_tools.get_freecad_matrix(item.transformation.matrix)
|
||||
placement = FreeCAD.Placement(matrix)
|
||||
verts = item.geometry.verts
|
||||
verts = [FreeCAD.Vector(verts[i : i + 3]) for i in range(0, len(verts), 3)]
|
||||
@@ -361,13 +378,24 @@ def get_geom_iterator(ifcfile, elements, brep_mode):
|
||||
if we want brep data or not"""
|
||||
|
||||
settings = ifcopenshell.geom.settings()
|
||||
if brep_mode:
|
||||
settings.set(settings.DISABLE_TRIANGULATION, True)
|
||||
settings.set(settings.USE_BREP_DATA, True)
|
||||
settings.set(settings.SEW_SHELLS, True)
|
||||
body_contexts = ifc_tools.get_body_context_ids(ifcfile) # TODO migrate here?
|
||||
if body_contexts:
|
||||
settings.set_context_ids(body_contexts)
|
||||
if brep_mode:
|
||||
if hasattr(settings, "DISABLE_TRIANGULATION"):
|
||||
# IfcOpenShell 0.7
|
||||
settings.set(settings.DISABLE_TRIANGULATION, True)
|
||||
settings.set(settings.USE_BREP_DATA, True)
|
||||
settings.set(settings.SEW_SHELLS, True)
|
||||
if body_contexts:
|
||||
settings.set_context_ids(body_contexts)
|
||||
elif hasattr(settings, "ITERATOR_OUTPUT"):
|
||||
# IfcOpenShell 0.8
|
||||
settings.set("ITERATOR_OUTPUT", ifcopenshell.ifcopenshell_wrapper.SERIALIZED)
|
||||
if body_contexts:
|
||||
# Is this the right way? It works, but not sure.
|
||||
settings.set("CONTEXT_IDENTIFIERS", [str(s) for s in body_contexts])
|
||||
else:
|
||||
# We print a debug message but we continue
|
||||
print("DEBUG: ifc_tools.get_geom_iterator: Iterator could not be set up correctly")
|
||||
cores = multiprocessing.cpu_count()
|
||||
iterator = ifcopenshell.geom.iterator(settings, ifcfile, cores, include=elements)
|
||||
if not iterator.initialize():
|
||||
|
||||
@@ -136,7 +136,12 @@ def create_layer(name, project):
|
||||
|
||||
group = ifc_tools.get_group(project, "IfcLayersGroup")
|
||||
ifcfile = ifc_tools.get_ifcfile(project)
|
||||
layer = ifc_tools.api_run("layer.add_layer", ifcfile, Name=name)
|
||||
try:
|
||||
# IfcopenShell 0.8
|
||||
layer = ifc_tools.api_run("layer.add_layer", ifcfile, name=name)
|
||||
except:
|
||||
# IfcopenShell 0.7
|
||||
layer = ifc_tools.api_run("layer.add_layer", ifcfile, Name=name)
|
||||
return get_layer(layer, project)
|
||||
|
||||
|
||||
|
||||
@@ -135,12 +135,23 @@ def set_material(material, obj):
|
||||
if not container.OutList:
|
||||
doc.removeObject(container.Name)
|
||||
if material_element:
|
||||
ifc_tools.api_run(
|
||||
"material.assign_material",
|
||||
ifcfile,
|
||||
product=element,
|
||||
type=material_element.is_a(),
|
||||
material=material_element,
|
||||
)
|
||||
try:
|
||||
# IfcOpenShell 0.8
|
||||
ifc_tools.api_run(
|
||||
"material.assign_material",
|
||||
ifcfile,
|
||||
products=[element],
|
||||
type=material_element.is_a(),
|
||||
material=material_element,
|
||||
)
|
||||
except:
|
||||
# IfcOpenShell 0.7
|
||||
ifc_tools.api_run(
|
||||
"material.assign_material",
|
||||
ifcfile,
|
||||
product=element,
|
||||
type=material_element.is_a(),
|
||||
material=material_element,
|
||||
)
|
||||
if new:
|
||||
show_material(obj)
|
||||
|
||||
@@ -122,7 +122,7 @@ class NativeIFCTest(unittest.TestCase):
|
||||
singledoc=SINGLEDOC,
|
||||
)
|
||||
fco = len(FreeCAD.getDocument("IfcTest").Objects)
|
||||
self.failUnless(fco == 1 - SDU, "ImportCoinSingle failed")
|
||||
self.assertTrue(fco == 1 - SDU, "ImportCoinSingle failed")
|
||||
|
||||
def test02_ImportCoinStructure(self):
|
||||
FreeCAD.Console.PrintMessage(
|
||||
@@ -140,7 +140,7 @@ class NativeIFCTest(unittest.TestCase):
|
||||
singledoc=SINGLEDOC,
|
||||
)
|
||||
fco = len(FreeCAD.getDocument("IfcTest").Objects)
|
||||
self.failUnless(fco == 4 - SDU, "ImportCoinStructure failed")
|
||||
self.assertTrue(fco == 4 - SDU, "ImportCoinStructure failed")
|
||||
|
||||
def test03_ImportCoinFull(self):
|
||||
global FCSTD_FILE_PATH
|
||||
@@ -160,7 +160,7 @@ class NativeIFCTest(unittest.TestCase):
|
||||
d.saveAs(path)
|
||||
FCSTD_FILE_PATH = path
|
||||
fco = len(FreeCAD.getDocument("IfcTest").Objects)
|
||||
self.failUnless(fco > 4 - SDU, "ImportCoinFull failed")
|
||||
self.assertTrue(fco > 4 - SDU, "ImportCoinFull failed")
|
||||
|
||||
def test04_ImportShapeFull(self):
|
||||
FreeCAD.Console.PrintMessage("4. NativeIFC import: Full model, shape mode...")
|
||||
@@ -176,7 +176,7 @@ class NativeIFCTest(unittest.TestCase):
|
||||
singledoc=SINGLEDOC,
|
||||
)
|
||||
fco = len(FreeCAD.getDocument("IfcTest").Objects)
|
||||
self.failUnless(fco > 4 - SDU, "ImportShapeFull failed")
|
||||
self.assertTrue(fco > 4 - SDU, "ImportShapeFull failed")
|
||||
|
||||
def test05_ImportFreeCAD(self):
|
||||
FreeCAD.Console.PrintMessage(
|
||||
@@ -188,7 +188,7 @@ class NativeIFCTest(unittest.TestCase):
|
||||
proj = ifc_tools.get_project(obj)
|
||||
ifcfile = ifc_tools.get_ifcfile(proj)
|
||||
print(ifcfile)
|
||||
self.failUnless(ifcfile, "ImportFreeCAD failed")
|
||||
self.assertTrue(ifcfile, "ImportFreeCAD failed")
|
||||
|
||||
def test06_ModifyObjects(self):
|
||||
FreeCAD.Console.PrintMessage("6. NativeIFC Modifying IFC document...")
|
||||
@@ -201,8 +201,8 @@ class NativeIFCTest(unittest.TestCase):
|
||||
ifc_diff = compare(IFC_FILE_PATH, proj.IfcFilePath)
|
||||
obj.ShapeMode = 0
|
||||
obj.Proxy.execute(obj)
|
||||
self.failUnless(
|
||||
obj.Shape.Volume > 2 and len(ifc_diff) == 3, "ModifyObjects failed"
|
||||
self.assertTrue(
|
||||
obj.Shape.Volume > 2 and len(ifc_diff) <= 5, "ModifyObjects failed"
|
||||
)
|
||||
|
||||
def test07_CreateDocument(self):
|
||||
@@ -211,7 +211,7 @@ class NativeIFCTest(unittest.TestCase):
|
||||
ifc_tools.create_document(doc, silent=True)
|
||||
fco = len(FreeCAD.getDocument("IfcTest").Objects)
|
||||
print(FreeCAD.getDocument("IfcTest").Objects)
|
||||
self.failUnless(fco == 1 - SDU, "CreateDocument failed")
|
||||
self.assertTrue(fco == 1 - SDU, "CreateDocument failed")
|
||||
|
||||
def test08_ChangeIFCSchema(self):
|
||||
FreeCAD.Console.PrintMessage("8. NativeIFC Changing IFC schema...")
|
||||
@@ -232,7 +232,7 @@ class NativeIFCTest(unittest.TestCase):
|
||||
proj.Proxy.silent = True
|
||||
proj.Schema = "IFC2X3"
|
||||
FreeCAD.getDocument("IfcTest").recompute()
|
||||
self.failUnless(obj.StepId != oldid, "ChangeIFCSchema failed")
|
||||
self.assertTrue(obj.StepId != oldid, "ChangeIFCSchema failed")
|
||||
|
||||
def test09_CreateBIMObjects(self):
|
||||
FreeCAD.Console.PrintMessage("9. NativeIFC Creating BIM objects...")
|
||||
@@ -260,7 +260,7 @@ class NativeIFCTest(unittest.TestCase):
|
||||
fco = len(FreeCAD.getDocument("IfcTest").Objects)
|
||||
ifco = len(proj.Proxy.ifcfile.by_type("IfcRoot"))
|
||||
print(ifco, "IFC objects created")
|
||||
self.failUnless(fco == 8 - SDU and ifco == 12, "CreateDocument failed")
|
||||
self.assertTrue(fco == 8 - SDU and ifco == 12, "CreateDocument failed")
|
||||
|
||||
def test10_ChangePlacement(self):
|
||||
FreeCAD.Console.PrintMessage("10. NativeIFC Changing Placement...")
|
||||
@@ -281,7 +281,7 @@ class NativeIFCTest(unittest.TestCase):
|
||||
new_plac = ifcopenshell.util.placement.get_local_placement(elem.ObjectPlacement)
|
||||
new_plac = str(new_plac).replace(" ", "").replace("\n", "")
|
||||
target = "[[1.0.0.100.][0.1.0.200.][0.0.1.300.][0.0.0.1.]]"
|
||||
self.failUnless(new_plac == target, "ChangePlacement failed")
|
||||
self.assertTrue(new_plac == target, "ChangePlacement failed")
|
||||
|
||||
def test11_ChangeGeometry(self):
|
||||
FreeCAD.Console.PrintMessage("11. NativeIFC Changing Geometry...")
|
||||
@@ -300,7 +300,7 @@ class NativeIFCTest(unittest.TestCase):
|
||||
ifc_geometry.add_geom_properties(obj)
|
||||
obj.ExtrusionDepth = "6000 mm"
|
||||
FreeCAD.getDocument("IfcTest").recompute()
|
||||
self.failUnless(obj.Shape.Volume > 1500000, "ChangeGeometry failed")
|
||||
self.assertTrue(obj.Shape.Volume > 1500000, "ChangeGeometry failed")
|
||||
|
||||
def test12_RemoveObject(self):
|
||||
from nativeifc import ifc_observer
|
||||
@@ -321,7 +321,7 @@ class NativeIFCTest(unittest.TestCase):
|
||||
count1 = len(ifcfile.by_type("IfcProduct"))
|
||||
FreeCAD.getDocument("IfcTest").removeObject("IfcObject004")
|
||||
count2 = len(ifcfile.by_type("IfcProduct"))
|
||||
self.failUnless(count2 < count1, "RemoveObject failed")
|
||||
self.assertTrue(count2 < count1, "RemoveObject failed")
|
||||
|
||||
def test13_Materials(self):
|
||||
FreeCAD.Console.PrintMessage("13. NativeIFC Materials...")
|
||||
@@ -346,7 +346,7 @@ class NativeIFCTest(unittest.TestCase):
|
||||
elem = ifc_tools.get_ifc_element(prod)
|
||||
res = ifcopenshell.util.element.get_material(elem)
|
||||
mats_after = ifcfile.by_type("IfcMaterialDefinition")
|
||||
self.failUnless(len(mats_after) == len(mats_before) + 1, "Materials failed")
|
||||
self.assertTrue(len(mats_after) == len(mats_before) + 1, "Materials failed")
|
||||
|
||||
def test14_Layers(self):
|
||||
FreeCAD.Console.PrintMessage("14. NativeIFC Layers...")
|
||||
@@ -368,7 +368,7 @@ class NativeIFCTest(unittest.TestCase):
|
||||
prod = FreeCAD.getDocument("IfcTest").getObject("IfcObject006")
|
||||
ifc_layers.add_to_layer(prod, layer)
|
||||
lays_after = ifcfile.by_type("IfcPresentationLayerAssignment")
|
||||
self.failUnless(len(lays_after) == len(lays_before) + 1, "Layers failed")
|
||||
self.assertTrue(len(lays_after) == len(lays_before) + 1, "Layers failed")
|
||||
|
||||
def test15_Psets(self):
|
||||
FreeCAD.Console.PrintMessage("15. NativeIFC Psets...")
|
||||
@@ -387,4 +387,4 @@ class NativeIFCTest(unittest.TestCase):
|
||||
ifcfile = ifc_tools.get_ifcfile(obj)
|
||||
pset = ifc_psets.add_pset(obj, "Pset_Custom")
|
||||
ifc_psets.add_property(ifcfile, pset, "MyMessageToTheWorld", "Hello, World!")
|
||||
self.failUnless(ifc_psets.has_psets(obj), "Psets failed")
|
||||
self.assertTrue(ifc_psets.has_psets(obj), "Psets failed")
|
||||
|
||||
@@ -355,7 +355,7 @@ def assign_groups(children):
|
||||
|
||||
|
||||
def get_children(
|
||||
obj, ifcfile=None, only_structure=False, assemblies=True, expand=False
|
||||
obj, ifcfile=None, only_structure=False, assemblies=True, expand=False, iftype=None
|
||||
):
|
||||
"""Returns the direct descendants of an object"""
|
||||
|
||||
@@ -373,9 +373,12 @@ def get_children(
|
||||
children.extend([rel.RelatedOpeningElement])
|
||||
for rel in getattr(ifcentity, "HasFillings", []):
|
||||
children.extend([rel.RelatedBuildingElement])
|
||||
return filter_elements(
|
||||
result = filter_elements(
|
||||
children, ifcfile, expand=expand, spaces=True, assemblies=assemblies
|
||||
)
|
||||
if iftype:
|
||||
result = [r for r in result if r.is_a(ifctype)]
|
||||
return result
|
||||
|
||||
|
||||
def get_object(element, document=None):
|
||||
@@ -667,7 +670,11 @@ def get_ifc_element(obj, ifcfile=None):
|
||||
if not ifcfile:
|
||||
ifcfile = get_ifcfile(obj)
|
||||
if ifcfile and hasattr(obj, "StepId"):
|
||||
return ifcfile.by_id(obj.StepId)
|
||||
try:
|
||||
return ifcfile.by_id(obj.StepId)
|
||||
except RuntimeError:
|
||||
# entity not found
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
@@ -784,27 +791,33 @@ def set_colors(obj, colors):
|
||||
"""Sets the given colors to an object"""
|
||||
|
||||
if FreeCAD.GuiUp and colors:
|
||||
try:
|
||||
vobj = obj.ViewObject
|
||||
except ReferenceError:
|
||||
# Object was probably deleted
|
||||
return
|
||||
# ifcopenshell issues (-1,-1,-1) colors if not set
|
||||
if isinstance(colors[0], (tuple, list)):
|
||||
colors = [tuple([abs(d) for d in c]) for c in colors]
|
||||
else:
|
||||
colors = [abs(c) for c in colors]
|
||||
if hasattr(obj.ViewObject, "ShapeColor"):
|
||||
if hasattr(vobj, "ShapeColor"):
|
||||
if isinstance(colors[0], (tuple, list)):
|
||||
obj.ViewObject.ShapeColor = colors[0][:3]
|
||||
if len(colors[0]) > 3:
|
||||
obj.ViewObject.Transparency = int(colors[0][3] * 100)
|
||||
vobj.ShapeColor = colors[0][:3]
|
||||
# do not set transparency when the object has more than one color
|
||||
#if len(colors[0]) > 3:
|
||||
# vobj.Transparency = int(colors[0][3] * 100)
|
||||
else:
|
||||
obj.ViewObject.ShapeColor = colors[:3]
|
||||
vobj.ShapeColor = colors[:3]
|
||||
if len(colors) > 3:
|
||||
obj.ViewObject.Transparency = int(colors[3] * 100)
|
||||
if hasattr(obj.ViewObject, "DiffuseColor"):
|
||||
vobj.Transparency = int(colors[3] * 100)
|
||||
if hasattr(vobj, "DiffuseColor"):
|
||||
# strip out transparency value because it currently gives ugly
|
||||
# results in FreeCAD when combining transparent and non-transparent objects
|
||||
if all([len(c) > 3 and c[3] != 0 for c in colors]):
|
||||
obj.ViewObject.DiffuseColor = colors
|
||||
vobj.DiffuseColor = colors
|
||||
else:
|
||||
obj.ViewObject.DiffuseColor = [c[:3] for c in colors]
|
||||
vobj.DiffuseColor = [c[:3] for c in colors]
|
||||
|
||||
|
||||
def get_body_context_ids(ifcfile):
|
||||
@@ -849,9 +862,15 @@ def get_freecad_matrix(ios_matrix):
|
||||
|
||||
# https://github.com/IfcOpenShell/IfcOpenShell/issues/1440
|
||||
# https://pythoncvc.net/?cat=203
|
||||
# https://github.com/IfcOpenShell/IfcOpenShell/issues/4832#issuecomment-2158583873
|
||||
m_l = list()
|
||||
for i in range(3):
|
||||
line = list(ios_matrix[i::3])
|
||||
if len(ios_matrix) == 16:
|
||||
# IfcOpenShell 0.8
|
||||
line = list(ios_matrix[i::4])
|
||||
else:
|
||||
# IfcOpenShell 0.7
|
||||
line = list(ios_matrix[i::3])
|
||||
line[-1] *= SCALE
|
||||
m_l.extend(line)
|
||||
return FreeCAD.Matrix(*m_l)
|
||||
@@ -1130,7 +1149,11 @@ def create_relationship(old_obj, obj, parent, element, ifcfile):
|
||||
for old_par in old_obj.InList:
|
||||
if hasattr(old_par, "Group") and old_obj in old_par.Group:
|
||||
old_par.Group = [o for o in old_par.Group if o != old_obj]
|
||||
api_run("spatial.unassign_container", ifcfile, product=element)
|
||||
try:
|
||||
api_run("spatial.unassign_container", ifcfile, products=[element])
|
||||
except:
|
||||
# older version of IfcOpenShell
|
||||
api_run("spatial.unassign_container", ifcfile, product=element)
|
||||
if element.is_a("IfcOpeningElement"):
|
||||
uprel = api_run(
|
||||
"void.add_opening",
|
||||
@@ -1139,12 +1162,21 @@ def create_relationship(old_obj, obj, parent, element, ifcfile):
|
||||
element=parent_element,
|
||||
)
|
||||
else:
|
||||
uprel = api_run(
|
||||
"spatial.assign_container",
|
||||
ifcfile,
|
||||
product=element,
|
||||
relating_structure=parent_element,
|
||||
)
|
||||
try:
|
||||
uprel = api_run(
|
||||
"spatial.assign_container",
|
||||
ifcfile,
|
||||
products=[element],
|
||||
relating_structure=parent_element,
|
||||
)
|
||||
except:
|
||||
# older version of ifcopenshell
|
||||
uprel = api_run(
|
||||
"spatial.assign_container",
|
||||
ifcfile,
|
||||
product=element,
|
||||
relating_structure=parent_element,
|
||||
)
|
||||
# case 2: dooe/window inside element
|
||||
# https://standards.buildingsmart.org/IFC/RELEASE/IFC4/ADD2_TC1/HTML/annex/annex-e/wall-with-opening-and-window.htm
|
||||
elif parent_element.is_a("IfcElement") and element.is_a() in [
|
||||
|
||||
@@ -426,10 +426,11 @@ class ifc_vp_document(ifc_vp_object):
|
||||
|
||||
from nativeifc import ifc_tools # lazy import
|
||||
|
||||
get_filepath(self.Object)
|
||||
ifc_tools.save(self.Object)
|
||||
self.replace_file(self.Object, sf)
|
||||
self.Object.Document.recompute()
|
||||
sf = get_filepath(self.Object)
|
||||
if sf:
|
||||
ifc_tools.save(self.Object)
|
||||
self.replace_file(self.Object, sf)
|
||||
self.Object.Document.recompute()
|
||||
|
||||
def replace_file(self, obj, newfile):
|
||||
"""Asks the user if the attached file path needs to be replaced"""
|
||||
@@ -634,5 +635,5 @@ def get_filepath(project):
|
||||
if not sf.lower().endswith(".ifc"):
|
||||
sf += ".ifc"
|
||||
project.IfcFilePath = sf
|
||||
return True
|
||||
return False
|
||||
return sf
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user