BIM: NativeIFC 2D support - dimensions
This commit is contained in:
committed by
Yorik van Havre
parent
4fba4abe5f
commit
9c53a024c0
@@ -121,10 +121,33 @@ def get_text(annotation):
|
||||
"""Determines if an IfcAnnotation contains an IfcTextLiteral.
|
||||
Returns the IfcTextLiteral or None"""
|
||||
|
||||
for rep in annotation.Representation.Representations:
|
||||
for item in rep.Items:
|
||||
if item.is_a("IfcTextLiteral"):
|
||||
return item
|
||||
if annotation.is_a("IfcAnnotation"):
|
||||
for rep in annotation.Representation.Representations:
|
||||
for item in rep.Items:
|
||||
if item.is_a("IfcTextLiteral"):
|
||||
return item
|
||||
return None
|
||||
|
||||
|
||||
def get_dimension(annotation):
|
||||
"""Determines if an IfcAnnotation is representing a dimension.
|
||||
Returns a list containing the representation, two points indicating
|
||||
the mesured points, and optionally a third point indicating where
|
||||
the dimension line is located, if available"""
|
||||
|
||||
if annotation.is_a("IfcAnnotation"):
|
||||
if annotation.ObjectType == "DIMENSION":
|
||||
s = ifcopenshell.util.unit.calculate_unit_scale(annotation.file) * 1000
|
||||
for rep in annotation.Representation.Representations:
|
||||
shape = importIFCHelper.get2DShape(rep, s)
|
||||
if shape and len(shape) == 1:
|
||||
if len(shape[0].Vertexes) >= 2:
|
||||
# two-point polyline (BBIM)
|
||||
res = [rep, shape[0].Vertexes[0].Point, shape[0].Vertexes[-1].Point]
|
||||
if len(shape[0].Vertexes) > 2:
|
||||
# 4-point polyline (FreeCAD)
|
||||
res.append(shape[0].Vertexes[0].Point)
|
||||
return res
|
||||
return None
|
||||
|
||||
|
||||
@@ -163,3 +186,15 @@ def get_placement(ifcelement, ifcfile):
|
||||
|
||||
s = 0.001 / ifcopenshell.util.unit.calculate_unit_scale(ifcfile)
|
||||
return importIFCHelper.getPlacement(ifcelement, scaling=s)
|
||||
|
||||
|
||||
def get_scaled_point(point, ifcfile, is2d=False):
|
||||
"""Returns a scaled 2d or 3d point tuple form a FreeCAD point"""
|
||||
|
||||
s = 0.001 / ifcopenshell.util.unit.calculate_unit_scale(ifcfile)
|
||||
v = FreeCAD.Vector(point)
|
||||
v.multiply(s)
|
||||
v = tuple(v)
|
||||
if is2d:
|
||||
v = v[:2]
|
||||
return v
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
import FreeCAD
|
||||
translate = FreeCAD.Qt.translate
|
||||
|
||||
# the property groups below should not be treated as psets
|
||||
NON_PSETS = ["Base", "IFC", "", "Geometry", "Dimension", "Linear/radial dimension", "PhysicalProperties"]
|
||||
|
||||
class ifc_object:
|
||||
"""Base class for all IFC-based objects"""
|
||||
@@ -66,6 +68,8 @@ class ifc_object:
|
||||
self.edit_attribute(obj, "Name", obj.Label)
|
||||
elif prop == "Text":
|
||||
self.edit_annotation(obj, "Text", "\n".join(obj.Text))
|
||||
elif prop in ["Start", "End"]:
|
||||
self.edit_annotation(obj, prop)
|
||||
elif prop == "Placement":
|
||||
if getattr(self, "virgin_placement", False):
|
||||
self.virgin_placement = False
|
||||
@@ -77,7 +81,7 @@ class ifc_object:
|
||||
obj.ViewObject.signalChangeIcon()
|
||||
elif obj.getGroupOfProperty(prop) == "Geometry":
|
||||
self.edit_geometry(obj, prop)
|
||||
elif obj.getGroupOfProperty(prop) not in ["Base", "IFC", "", "Geometry", "PhysicalProperties"]:
|
||||
elif obj.getGroupOfProperty(prop) not in NON_PSETS:
|
||||
# Treat all property groups outside the default ones as Psets
|
||||
# print("DEBUG: editinog pset prop",prop)
|
||||
self.edit_pset(obj, prop)
|
||||
@@ -186,6 +190,23 @@ class ifc_object:
|
||||
text = ifc_export.get_text(elt)
|
||||
if text:
|
||||
result = ifc_tools.set_attribute(ifcfile, text, "Literal", value)
|
||||
elif attribute in ["Start", "End"]:
|
||||
dim = ifc_export.get_dimension(elt)
|
||||
if dim:
|
||||
rep = dim[0]
|
||||
for curve in rep.Items:
|
||||
for sub in curve.Elements:
|
||||
if sub.is_a("IfcIndexedPolyCurve"):
|
||||
points = sub.Points
|
||||
value = list(points.CoordList)
|
||||
is2d = "2D" in points.is_a()
|
||||
if attribute == "Start":
|
||||
value[0] = ifc_export.get_scaled_point(obj.Start, ifcfile, is2d)
|
||||
else:
|
||||
value[-1] = ifc_export.get_scaled_point(obj.End, ifcfile, is2d)
|
||||
result = ifc_tools.set_attribute(ifcfile, points, "CoordList", value)
|
||||
else:
|
||||
print("DEBUG: unknown dimension curve type:",sub)
|
||||
|
||||
def edit_geometry(self, obj, prop):
|
||||
"""Edits a geometry property of an object"""
|
||||
|
||||
@@ -259,6 +259,8 @@ def create_object(ifcentity, document, ifcfile, shapemode=0, objecttype=None):
|
||||
if ifcentity.is_a("IfcAnnotation"):
|
||||
if ifc_export.get_text(ifcentity):
|
||||
objecttype = "text"
|
||||
elif ifc_export.get_dimension(ifcentity):
|
||||
objecttype = "dimension"
|
||||
FreeCAD.Console.PrintLog(s)
|
||||
obj = add_object(document, otype=objecttype)
|
||||
add_properties(obj, ifcfile, ifcentity, shapemode=shapemode)
|
||||
@@ -483,11 +485,21 @@ def add_object(document, otype=None, oname="IfcObject"):
|
||||
'material',
|
||||
'layer',
|
||||
'text',
|
||||
'dimension',
|
||||
or anything else for a standard IFC object"""
|
||||
|
||||
if not document:
|
||||
return None
|
||||
if otype == "text":
|
||||
if otype == "dimension":
|
||||
obj = Draft.make_dimension(FreeCAD.Vector(), FreeCAD.Vector(1,0,0))
|
||||
obj.Proxy = ifc_objects.ifc_object(otype)
|
||||
obj.removeProperty("Diameter")
|
||||
obj.removeProperty("Distance")
|
||||
obj.setPropertyStatus("LinkedGeometry", "Hidden")
|
||||
obj.setGroupOfProperty("Start", "Dimension")
|
||||
obj.setGroupOfProperty("End", "Dimension")
|
||||
obj.setGroupOfProperty("Direction", "Dimension")
|
||||
elif otype == "text":
|
||||
obj = Draft.make_text("")
|
||||
obj.Proxy = ifc_objects.ifc_object(otype)
|
||||
elif otype == "layer":
|
||||
@@ -653,6 +665,24 @@ def add_properties(
|
||||
obj.addProperty("App::PropertyStringList", "Text", "Base")
|
||||
obj.Text = [text.Literal]
|
||||
obj.Placement = ifc_export.get_placement(ifcentity.ObjectPlacement, ifcfile)
|
||||
else:
|
||||
dim = ifc_export.get_dimension(ifcentity)
|
||||
if dim and len(dim) >= 3:
|
||||
# the two props below are already taken care of, normally
|
||||
if "Start" not in obj.PropertiesList:
|
||||
obj.addProperty("App::PropertyVectorDistance", "Start", "Base")
|
||||
if "End" not in obj.PropertiesList:
|
||||
obj.addProperty("App::PropertyVectorDistance", "End", "Base")
|
||||
if "Dimline" not in obj.PropertiesList:
|
||||
obj.addProperty("App::PropertyVectorDistance", "Dimline", "Base")
|
||||
obj.Start = dim[1]
|
||||
obj.End = dim[2]
|
||||
if len(dim) > 3:
|
||||
obj.Dimline = dim[3]
|
||||
else:
|
||||
mid = obj.End.sub(obj.Start)
|
||||
mid.multiply(0.5)
|
||||
obj.Dimline = obj.Start.add(mid)
|
||||
# link Label2 and Description
|
||||
if "Description" in obj.PropertiesList and hasattr(obj, "setExpression"):
|
||||
obj.setExpression("Label2", "Description")
|
||||
|
||||
Reference in New Issue
Block a user