BIM: NativeIFC 2D support - misc fixes cf comment #2383181661

This commit is contained in:
Yorik van Havre
2024-10-01 13:23:03 +02:00
committed by Yorik van Havre
parent 14585a760e
commit dcbbdcec0a
4 changed files with 55 additions and 31 deletions

View File

@@ -2464,6 +2464,7 @@ def create_annotation(anno, ifcfile, context, history, preferences):
ovc = None
zvc = None
xvc = None
reps = []
repid = "Annotation"
reptype = "Annotation2D"
if anno.isDerivedFrom("Part::Feature"):
@@ -2475,7 +2476,6 @@ def create_annotation(anno, ifcfile, context, history, preferences):
objectType = "AREA"
else:
objectType = "LINEWORK"
reps = []
sh = anno.Shape.copy()
sh.scale(preferences['SCALE_FACTOR']) # to meters
ehc = []
@@ -2520,24 +2520,13 @@ def create_annotation(anno, ifcfile, context, history, preferences):
if FreeCAD.GuiUp:
objectType = "DIMENSION"
vp = anno.ViewObject.Proxy
reps = []
sh = Part.makePolygon([vp.p1,vp.p2,vp.p3,vp.p4])
if "BBIMDIMS" in preferences and preferences["BBIMDIMS"]:
sh = Part.makePolygon([vp.p2,vp.p3])
else:
sh = Part.makePolygon([vp.p1,vp.p2,vp.p3,vp.p4])
sh.scale(preferences['SCALE_FACTOR']) # to meters
ehc = []
curves = []
for w in sh.Wires:
curves.append(createCurve(ifcfile,w))
for e in w.Edges:
ehc.append(e.hashCode())
if curves:
reps.append(ifcfile.createIfcGeometricCurveSet(curves))
curves = []
# leftover edges
for e in sh.Edges:
if e.hashCode() not in ehc:
curves.append(createCurve(ifcfile,e))
if curves:
reps.append(ifcfile.createIfcGeometricCurveSet(curves))
curve = createCurve(ifcfile,sh)
reps = [ifcfile.createIfcGeometricCurveSet([curve])]
# Append text
l = FreeCAD.Vector(vp.tbase).multiply(preferences['SCALE_FACTOR'])
zdir = None

View File

@@ -31,18 +31,41 @@ from importers import importIFCHelper
from nativeifc import ifc_tools
def get_export_preferences(ifcfile):
"""returns a preferences dict for exportIFC"""
def get_export_preferences(ifcfile, preferred_context=None):
"""returns a preferences dict for exportIFC.
Preferred context can either indicate a ContextType like 'Model' or 'Plan',
or a [ContextIdentifier,ContextType] list or tuple, for ex.
('Annotation','Plan'). This function will do its best to find the most
appropriate context."""
prefs = exportIFC.getPreferences()
prefs["SCHEMA"] = ifcfile.wrapped_data.schema_name()
s = ifcopenshell.util.unit.calculate_unit_scale(ifcfile)
# the above lines yields meter -> file unit scale factor. We need mm
prefs["SCALE_FACTOR"] = 0.001 / s
context = ifcfile[
ifc_tools.get_body_context_ids(ifcfile)[0]
] # we take the first one (first found subcontext)
return prefs, context
cids = ifc_tools.get_body_context_ids(ifcfile)
contexts = [ifcfile[i] for i in cids]
best_context = None
if preferred_context:
if isinstance(preferred_context, str):
for context in contexts:
if context.ContextType == preferred_context:
best_context = context
break
elif isinstance(preferred_context, (list, tuple)):
second_choice = None
for context in contexts:
if context.ContextType == preferred_context[1]:
second_choice = context
if context.ContextIdentifier == preferred_context[0]:
best_context = context
break
else:
if second_choice:
best_context = second_choice
if not best_context:
best_context = contexts[0]
return prefs, best_context
def create_product(obj, parent, ifcfile, ifcclass=None):
@@ -198,7 +221,8 @@ def create_annotation(obj, ifcfile):
exportIFC.curvestyles = {}
exportIFC.ifcopenshell = ifcopenshell
exportIFC.ifcbin = exportIFCHelper.recycler(ifcfile, template=False)
prefs, context = get_export_preferences(ifcfile)
prefs, context = get_export_preferences(ifcfile, preferred_context="Plan")
prefs["BBIMDIMS"] = True # Save dimensions as 2-point polylines
history = get_history(ifcfile)
# TODO The following prints each edge as a separate IfcGeometricCurveSet
# It should be refined to create polylines instead

View File

@@ -214,11 +214,11 @@ class ifc_object:
l = w = h = 1000
if obj.ViewObject:
if obj.ViewObject.DisplayLength.Value:
l = ifc_export.get_scaled_value(obj.ViewObject.DisplayLength.Value)
l = ifc_export.get_scaled_value(obj.ViewObject.DisplayLength.Value, ifcfile)
if obj.ViewObject.DisplayHeight.Value:
w = ifc_export.get_scaled_value(obj.ViewObject.DisplayHeight.Value)
w = ifc_export.get_scaled_value(obj.ViewObject.DisplayHeight.Value, ifcfile)
if obj.Depth.Value:
h = ifc_export.get_scaled_value(obj.Depth.Value)
h = ifc_export.get_scaled_value(obj.Depth.Value, ifcfile)
if elt.Representation.Representations:
for rep in elt.Representation.Representations:
for item in rep.Items:
@@ -356,9 +356,9 @@ class ifc_object:
import Part
if not obj.IfcClass == "IfcAnnotation":
return None, None
return [], None
if obj.ObjectType != "DRAWING":
return None, None
return [], None
objs = getattr(obj, "Objects", [])
if not objs:
# no object defined, we automatically use the project
@@ -388,7 +388,8 @@ class ifc_object:
plane.Placement = obj.Placement
return objs, plane
else:
return None, None
print("DEBUG: Section plane returned no objects")
return [], None
class document_object:

View File

@@ -1216,7 +1216,17 @@ def create_relationship(old_obj, obj, parent, element, ifcfile, mode=None):
parent_element = parent
# case 4: anything inside group
if parent_element.is_a("IfcGroup"):
# special case: adding a section plane to a grouo turns it into a drawing
# and removes it from any containment
if element.is_a("IfcAnnotation") and element.ObjectType == "DRAWING":
parent.ObjectType = "DRAWING"
try:
api_run("spatial.unassign_container", ifcfile, products=[parent_element])
except:
# older version of IfcOpenShell
api_run("spatial.unassign_container", ifcfile, product=parent_element)
# IFC objects can be part of multiple groups but we do the FreeCAD way here
# and remove from any previous group
for assignment in getattr(element,"HasAssignments",[]):
if assignment.is_a("IfcRelAssignsToGroup"):
if element in assignment.RelatedObjects: