Skip to content

Commit

Permalink
Autosaving of IFC files
Browse files Browse the repository at this point in the history
  • Loading branch information
yorikvanhavre committed Mar 21, 2024
1 parent 5d3f7ac commit ebf5805
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 28 deletions.
21 changes: 12 additions & 9 deletions ifc_observer.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,17 +139,18 @@ def save(self):
return
doc = FreeCAD.getDocument(self.docname)
del self.docname
objs = []
projects = []
if hasattr(doc, "IfcFilePath") and hasattr(doc, "Modified"):
if doc.Modified:
objs.append(doc)
projects.append(doc)
else:
for obj in doc.findObjects(Type="Part::FeaturePython"):
if hasattr(obj, "IfcFilePath") and hasattr(obj, "Modified"):
if obj.Modified:
objs.append(obj)
if objs:
projects.append(obj)
if projects:
import ifc_tools # lazy loading
import ifc_viewproviders

ask = params.GetBool("AskBeforeSaving", True)
if ask and FreeCAD.GuiUp:
Expand All @@ -164,11 +165,13 @@ def save(self):
ask = dlg.checkAskBeforeSaving.isChecked()
params.SetBool("AskBeforeSaving", ask)

for obj in objs:
if obj.IfcFilePath and getattr(obj.Proxy, "ifcfile", None):
obj.ViewObject.Proxy.save()
else:
obj.ViewObject.Proxy.save_as()
for project in projects:
if getattr(project.Proxy, "ifcfile", None):
if project.IfcFilePath:
ifc_tools.save(project)
else:
ifc_viewproviders.get_filepath(project)
ifc_tools.save(project)

def convert(self):
"""Converts an object to IFC"""
Expand Down
6 changes: 5 additions & 1 deletion ifc_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ def unlock_document():
props += [p for p in doc.PropertiesList if doc.getGroupOfProperty(p) == "IFC"]
for prop in props:
doc.removeProperty(prop)
project.Modified = True
doc.commitTransaction()
doc.recompute()

Expand Down Expand Up @@ -153,6 +154,7 @@ def lock_document():
# 1a all objects are already inside a project
pass
doc.removeObject(project.Name)
doc.Modified = True
doc.commitTransaction()
doc.recompute()
elif len(projects) > 1:
Expand All @@ -165,10 +167,12 @@ def lock_document():
ifc_tools.convert_document(doc, silent=True)
ifcfile = doc.Proxy.ifcfile
objs = find_toplevel(doc.Objects)
exportIFC.export(objs, ifcfile)
prefs, context = ifc_tools.get_export_preferences(ifcfile)
exportIFC.export(objs, ifcfile, preferences=prefs)
for n in [o.Name for o in doc.Objects]:
doc.removeObject(n)
ifc_tools.create_children(doc, ifcfile, recursive=True)
doc.Modified = True
doc.commitTransaction()
doc.recompute()
else:
Expand Down
5 changes: 3 additions & 2 deletions ifc_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ def setup_project(proj, filename, shapemode, silent):
project = ifcfile.by_type("IfcProject")[0]
# TODO configure version history
# https://blenderbim.org/docs-python/autoapi/ifcopenshell/api/owner/create_owner_history/index.html
# In IFC4, history is optional. What should we do here?
proj.Proxy.ifcfile = ifcfile
add_properties(proj, ifcfile, project, shapemode=shapemode)
if not "Schema" in proj.PropertiesList:
Expand Down Expand Up @@ -1030,8 +1031,8 @@ def get_export_preferences(ifcfile):
# the above lines yields meter -> file unit scale factor. We need mm
prefs["SCALE_FACTOR"] = 0.001 / s
context = ifcfile[
get_body_context_ids(ifcfile)[-1]
] # TODO should this be different?
get_body_context_ids(ifcfile)[0]
] # we take the first one (first found subcontext)
return prefs, context


Expand Down
40 changes: 24 additions & 16 deletions ifc_viewproviders.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,29 +417,18 @@ def save(self):

import ifc_tools # lazy import

ifc_tools.save_ifc(self.Object)
self.Object.Modified = False
ifc_tools.save(self.Object)
self.Object.Document.recompute()

def saveas(self):
"""Saves the associated IFC file to another file"""

import ifc_tools # lazy import
from PySide import QtCore, QtGui # lazy import

sf = QtGui.QFileDialog.getSaveFileName(
None,
"Save an IFC file",
self.Object.IfcFilePath,
"Industry Foundation Classes (*.ifc)",
)
if sf and sf[0]:
sf = sf[0]
if not sf.lower().endswith(".ifc"):
sf += ".ifc"
ifc_tools.save_ifc(self.Object, sf)
self.replace_file(self.Object, sf)
self.Object.Document.recompute()
get_filepath(self.Object)
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"""
Expand Down Expand Up @@ -626,3 +615,22 @@ def overlay(icon1, icon2):
b.open(QtCore.QIODevice.WriteOnly)
baseicon.save(b, "XPM")
return ba.data().decode("latin1")


def get_filepath(project):
"""Saves the associated IFC file to another file"""

import ifc_tools # lazy import
from PySide import QtCore, QtGui # lazy import

sf = QtGui.QFileDialog.getSaveFileName(
None,
"Save an IFC file",
project.IfcFilePath,
"Industry Foundation Classes (*.ifc)",
)
if sf and sf[0]:
sf = sf[0]
if not sf.lower().endswith(".ifc"):
sf += ".ifc"
project.IfcFilePath = sf

0 comments on commit ebf5805

Please sign in to comment.