BIM: Several fixes to nativeIFC lock/unlock system - fixes #17862
This commit is contained in:
committed by
Yorik van Havre
parent
c840b25588
commit
1212c55e38
@@ -967,11 +967,20 @@ class _ViewProviderSite:
|
||||
https://forum.freecad.org/viewtopic.php?t=75883
|
||||
"""
|
||||
|
||||
from pivy import coin
|
||||
|
||||
def find_node(parent, nodetype):
|
||||
for i in range(parent.getNumChildren()):
|
||||
if isinstance(parent.getChild(i), nodetype):
|
||||
return parent.getChild(i)
|
||||
return None
|
||||
|
||||
if not hasattr(self, "terrain_switches"):
|
||||
if vobj.RootNode.getNumChildren() > 2:
|
||||
main_switch = vobj.RootNode.getChild(2) # The display mode switch.
|
||||
main_switch = find_node(vobj.RootNode, coin.SoSwitch)
|
||||
if not main_switch:
|
||||
return
|
||||
if main_switch.getNumChildren() == 4: # Check if all display modes are available.
|
||||
from pivy import coin
|
||||
self.terrain_switches = []
|
||||
for node in tuple(main_switch.getChildren()):
|
||||
new_switch = coin.SoSwitch()
|
||||
|
||||
@@ -37,6 +37,7 @@ def get_diff(proj):
|
||||
|
||||
if not getattr(proj, "IfcFilePath", None):
|
||||
old = []
|
||||
return 1
|
||||
else:
|
||||
# cannot use open() here as it gives different encoding
|
||||
# than ifcopenshell and diff does not work
|
||||
@@ -59,7 +60,11 @@ def htmlize(diff):
|
||||
"""Returns an HTML version of a diff list"""
|
||||
|
||||
html = "<html><body>\n"
|
||||
if diff:
|
||||
if diff == 1:
|
||||
html += translate("BIM", "The IFC file is not saved. Please save once"
|
||||
" to have an existing IFC file to compare with."
|
||||
" Then, run this command again.") + "<br/>\n"
|
||||
elif diff:
|
||||
diff = diff.split("\n")
|
||||
for l in diff:
|
||||
if l.startswith("+"):
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import tempfile
|
||||
|
||||
import FreeCAD
|
||||
import Draft
|
||||
import ifcopenshell
|
||||
@@ -29,6 +31,10 @@ from importers import exportIFCHelper
|
||||
from importers import importIFCHelper
|
||||
|
||||
from nativeifc import ifc_tools
|
||||
from nativeifc import ifc_import
|
||||
|
||||
|
||||
PARAMS = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/NativeIFC")
|
||||
|
||||
|
||||
def get_export_preferences(ifcfile, preferred_context=None, create=None):
|
||||
@@ -354,8 +360,34 @@ def get_scaled_point(point, ifcfile=None, is2d=False):
|
||||
v = v[:2]
|
||||
return v
|
||||
|
||||
|
||||
def get_scaled_value(value, ifcfile):
|
||||
"""Returns a scaled dimension value"""
|
||||
|
||||
s = 0.001 / ifcopenshell.util.unit.calculate_unit_scale(ifcfile)
|
||||
return value * s
|
||||
|
||||
|
||||
def export_and_convert(objs, doc):
|
||||
"""Exports the given objects and their descendents to the given IFC file
|
||||
and re-imports it into the given document. This is slower than direct_conversion()
|
||||
but gives an intermediate file which can be useful for debugging"""
|
||||
|
||||
tf = tempfile.mkstemp(suffix=".ifc")[1]
|
||||
exportIFC.export(objs, tf)
|
||||
ifc_import.insert(tf, doc.Name, singledoc=True)
|
||||
|
||||
|
||||
def direct_conversion(objs, doc):
|
||||
"""Exports the given objects to the given ifcfile and recreates the contents"""
|
||||
|
||||
prj_obj = ifc_tools.convert_document(doc, silent=True)
|
||||
exportIFC.export(objs, doc.Proxy.ifcfile)
|
||||
if PARAMS.GetBool("LoadOrphans", True):
|
||||
ifc_tools.load_orphans(prj_obj)
|
||||
if 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)
|
||||
|
||||
@@ -414,15 +414,14 @@ def lock_document():
|
||||
elif doc.Objects:
|
||||
# 3 there is no project but objects
|
||||
doc.openTransaction("Lock document")
|
||||
ifc_tools.convert_document(doc, silent=True)
|
||||
ifcfile = doc.Proxy.ifcfile
|
||||
objs = find_toplevel(doc.Objects)
|
||||
prefs, context = ifc_export.get_export_preferences(ifcfile)
|
||||
exportIFC.export(objs, ifcfile, preferences=prefs)
|
||||
for n in [o.Name for o in doc.Objects]:
|
||||
deletelist = [o.Name for o in doc.Objects]
|
||||
#ifc_export.export_and_convert(objs, doc)
|
||||
ifc_export.direct_conversion(objs, doc)
|
||||
for n in deletelist:
|
||||
if doc.getObject(n):
|
||||
doc.removeObject(n)
|
||||
ifc_tools.create_children(doc, ifcfile, recursive=True)
|
||||
doc.IfcFilePath = ""
|
||||
doc.Modified = True
|
||||
doc.commitTransaction()
|
||||
doc.recompute()
|
||||
@@ -443,7 +442,7 @@ def lock_document():
|
||||
if create:
|
||||
if not ifcfile:
|
||||
ifcfile = doc.Proxy.ifcfile
|
||||
ifc_tools.create_children(doc, recursive=False)
|
||||
ifc_tools.create_children(doc, ifcfile, recursive=False)
|
||||
|
||||
|
||||
def find_toplevel(objs):
|
||||
|
||||
@@ -66,7 +66,7 @@ def create_document(document, filename=None, shapemode=0, strategy=0, silent=Fal
|
||||
1 = coin only
|
||||
2 = no representation
|
||||
strategy: 0 = only root object
|
||||
1 = only bbuilding structure,
|
||||
1 = only building structure
|
||||
2 = all children
|
||||
"""
|
||||
|
||||
@@ -86,7 +86,7 @@ def create_document_object(
|
||||
1 = coin only
|
||||
2 = no representation
|
||||
strategy: 0 = only root object
|
||||
1 = only bbuilding structure,
|
||||
1 = only building structure
|
||||
2 = all children
|
||||
"""
|
||||
|
||||
@@ -199,10 +199,18 @@ def create_ifcfile():
|
||||
application = "FreeCAD"
|
||||
version = FreeCAD.Version()
|
||||
version = ".".join([str(v) for v in version[0:3]])
|
||||
freecadorg = api_run(
|
||||
"owner.add_organisation",
|
||||
ifcfile,
|
||||
identification="FreeCAD.org",
|
||||
name="The FreeCAD project"
|
||||
)
|
||||
application = api_run(
|
||||
"owner.add_application",
|
||||
ifcfile,
|
||||
application_developer=freecadorg,
|
||||
application_full_name=application,
|
||||
application_identifier=application,
|
||||
version=version,
|
||||
)
|
||||
# context
|
||||
@@ -225,9 +233,14 @@ def create_ifcfile():
|
||||
parent=model3d,
|
||||
)
|
||||
# unit
|
||||
# for now, assign a default metre unit, as per https://blenderbim.org/docs-python/autoapi/ifcopenshell/api/unit/assign_unit/index.html
|
||||
# for now, assign a default metre + sqm +degrees unit, as per
|
||||
# https://docs.ifcopenshell.org/autoapi/ifcopenshell/api/unit/index.html
|
||||
# TODO allow to set this at creation, from the current FreeCAD units schema
|
||||
api_run("unit.assign_unit", ifcfile)
|
||||
length = api_run("unit.add_si_unit", ifcfile, unit_type="LENGTHUNIT")
|
||||
area = api_run("unit.add_si_unit", ifcfile, unit_type="AREAUNIT")
|
||||
angle = api_run("unit.add_conversion_based_unit", ifcfile, name="degree")
|
||||
api_run("unit.assign_unit", ifcfile, units=[length, area, angle])
|
||||
# TODO add user history
|
||||
return ifcfile
|
||||
|
||||
|
||||
@@ -1608,6 +1621,7 @@ def recompute(children):
|
||||
stime = time.time()
|
||||
for c in children:
|
||||
c.touch()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
if not FreeCAD.ActiveDocument.Recomputing:
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
endtime = "%02d:%02d" % (divmod(round(time.time() - stime, 1), 60))
|
||||
print("DEBUG: Extra recomputing of",len(children),"objects took",endtime)
|
||||
|
||||
Reference in New Issue
Block a user