BIM: NativeIFC 2D support - texts
This commit is contained in:
committed by
Yorik van Havre
parent
29ce0ad1d8
commit
1ba6bead9d
@@ -2443,11 +2443,9 @@ def create_annotation(anno, ifcfile, context, history, preferences):
|
||||
|
||||
# uses global ifcbin, curvestyles
|
||||
objectType = None
|
||||
xvc = ifcbin.createIfcDirection((1.0,0.0,0.0))
|
||||
zvc = ifcbin.createIfcDirection((0.0,0.0,1.0))
|
||||
ovc = ifcbin.createIfcCartesianPoint((0.0,0.0,0.0))
|
||||
gpl = ifcbin.createIfcAxis2Placement3D(ovc,zvc,xvc)
|
||||
placement = ifcbin.createIfcLocalPlacement(gpl)
|
||||
ovc = None
|
||||
zvc = None
|
||||
xvc = None
|
||||
if anno.isDerivedFrom("Part::Feature"):
|
||||
if Draft.getType(anno) == "Hatch":
|
||||
objectType = "HATCH"
|
||||
@@ -2477,18 +2475,20 @@ def create_annotation(anno, ifcfile, context, history, preferences):
|
||||
elif anno.isDerivedFrom("App::Annotation"):
|
||||
objectType = "TEXT"
|
||||
l = FreeCAD.Vector(anno.Position).multiply(preferences['SCALE_FACTOR'])
|
||||
pos = ifcbin.createIfcCartesianPoint((l.x,l.y,l.z))
|
||||
pos = ifcbin.createIfcCartesianPoint((0.0,0.0,0.0))
|
||||
tpl = ifcbin.createIfcAxis2Placement3D(pos,None,None)
|
||||
ovc = ifcbin.createIfcCartesianPoint((l.x,l.y,l.z))
|
||||
s = ";".join(anno.LabelText)
|
||||
txt = ifcfile.createIfcTextLiteral(s,tpl,"LEFT")
|
||||
reps = [txt]
|
||||
elif Draft.getType(anno) in ["DraftText","Text"]:
|
||||
objectType = "TEXT"
|
||||
l = FreeCAD.Vector(anno.Placement.Base).multiply(preferences['SCALE_FACTOR'])
|
||||
pos = ifcbin.createIfcCartesianPoint((l.x,l.y,l.z))
|
||||
zdir = ifcbin.createIfcDirection(tuple(anno.Placement.Rotation.multVec(FreeCAD.Vector(0,0,1))))
|
||||
xdir = ifcbin.createIfcDirection(tuple(anno.Placement.Rotation.multVec(FreeCAD.Vector(1,0,0))))
|
||||
tpl = ifcbin.createIfcAxis2Placement3D(pos,zdir,xdir)
|
||||
pos = ifcbin.createIfcCartesianPoint((0.0,0.0,0.0))
|
||||
tpl = ifcbin.createIfcAxis2Placement3D(pos,None,None)
|
||||
ovc = ifcbin.createIfcCartesianPoint((l.x,l.y,l.z))
|
||||
zvc = ifcbin.createIfcDirection(tuple(anno.Placement.Rotation.multVec(FreeCAD.Vector(0,0,1))))
|
||||
xvc = ifcbin.createIfcDirection(tuple(anno.Placement.Rotation.multVec(FreeCAD.Vector(1,0,0))))
|
||||
alg = "LEFT"
|
||||
if FreeCAD.GuiUp and hasattr(anno.ViewObject,"Justification"):
|
||||
if anno.ViewObject.Justification == "Right":
|
||||
@@ -2546,7 +2546,14 @@ def create_annotation(anno, ifcfile, context, history, preferences):
|
||||
for rep in reps:
|
||||
isi = ifcfile.createIfcStyledItem(rep,[psa],None)
|
||||
break
|
||||
|
||||
if not xvc:
|
||||
xvc = ifcbin.createIfcDirection((1.0,0.0,0.0))
|
||||
if not zvc:
|
||||
zvc = ifcbin.createIfcDirection((0.0,0.0,1.0))
|
||||
if not ovc:
|
||||
ovc = ifcbin.createIfcCartesianPoint((0.0,0.0,0.0))
|
||||
gpl = ifcbin.createIfcAxis2Placement3D(ovc,zvc,xvc)
|
||||
placement = ifcbin.createIfcLocalPlacement(gpl)
|
||||
shp = ifcfile.createIfcShapeRepresentation(context,'Annotation','Annotation2D',reps)
|
||||
rep = ifcfile.createIfcProductDefinitionShape(None,None,[shp])
|
||||
label = anno.Label
|
||||
|
||||
@@ -26,6 +26,7 @@ import ifcopenshell
|
||||
|
||||
from importers import exportIFC
|
||||
from importers import exportIFCHelper
|
||||
from importers import importIFCHelper
|
||||
|
||||
from nativeifc import ifc_tools
|
||||
|
||||
@@ -116,6 +117,17 @@ def is_annotation(obj):
|
||||
return False
|
||||
|
||||
|
||||
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
|
||||
return None
|
||||
|
||||
|
||||
def create_annotation(obj, ifcfile):
|
||||
"""Adds an IfcAnnotation from the given object to the given IFC file"""
|
||||
|
||||
@@ -144,3 +156,10 @@ def get_history(ifcfile):
|
||||
# IFC4 allows to not write any history
|
||||
history = None
|
||||
return history
|
||||
|
||||
|
||||
def get_placement(ifcelement, ifcfile):
|
||||
"""Returns a FreeCAD placement from an IFC placement"""
|
||||
|
||||
s = 0.001 / ifcopenshell.util.unit.calculate_unit_scale(ifcfile)
|
||||
return importIFCHelper.getPlacement(ifcelement, scaling=s)
|
||||
|
||||
@@ -64,6 +64,8 @@ class ifc_object:
|
||||
self.edit_attribute(obj, prop)
|
||||
elif prop == "Label":
|
||||
self.edit_attribute(obj, "Name", obj.Label)
|
||||
elif prop == "Text":
|
||||
self.edit_annotation(obj, "Text", "\n".join(obj.Text))
|
||||
elif prop == "Placement":
|
||||
if getattr(self, "virgin_placement", False):
|
||||
self.virgin_placement = False
|
||||
@@ -169,6 +171,22 @@ class ifc_object:
|
||||
if hasattr(result, "id") and (result.id() != obj.StepId):
|
||||
obj.StepId = result.id()
|
||||
|
||||
def edit_annotation(self, obj, attribute, value=None):
|
||||
"""Edits an attribute of an underlying IFC annotation"""
|
||||
|
||||
from nativeifc import ifc_tools # lazy import
|
||||
from nativeifc import ifc_export
|
||||
|
||||
if not value:
|
||||
value = obj.getPropertyByName(attribute)
|
||||
ifcfile = ifc_tools.get_ifcfile(obj)
|
||||
elt = ifc_tools.get_ifc_element(obj, ifcfile)
|
||||
if elt:
|
||||
if attribute == "Text":
|
||||
text = ifc_export.get_text(elt)
|
||||
if text:
|
||||
result = ifc_tools.set_attribute(ifcfile, text, "Literal", value)
|
||||
|
||||
def edit_geometry(self, obj, prop):
|
||||
"""Edits a geometry property of an object"""
|
||||
|
||||
|
||||
@@ -47,6 +47,8 @@ from nativeifc import ifc_layers
|
||||
from nativeifc import ifc_status
|
||||
from nativeifc import ifc_export
|
||||
|
||||
from draftviewproviders import view_layer
|
||||
|
||||
SCALE = 1000.0 # IfcOpenShell works in meters, FreeCAD works in mm
|
||||
SHORT = False # If True, only Step ID attribute is created
|
||||
ROUND = 8 # rounding value for placements
|
||||
@@ -243,7 +245,7 @@ def api_run(*args, **kwargs):
|
||||
return result
|
||||
|
||||
|
||||
def create_object(ifcentity, document, ifcfile, shapemode=0):
|
||||
def create_object(ifcentity, document, ifcfile, shapemode=0, objecttype=None):
|
||||
"""Creates a FreeCAD object from an IFC entity"""
|
||||
|
||||
exobj = get_object(ifcentity, document)
|
||||
@@ -253,7 +255,7 @@ def create_object(ifcentity, document, ifcfile, shapemode=0):
|
||||
ifcentity.id(), ifcentity.is_a(), ifcentity.Name
|
||||
)
|
||||
FreeCAD.Console.PrintLog(s)
|
||||
obj = add_object(document)
|
||||
obj = add_object(document, otype=objecttype)
|
||||
add_properties(obj, ifcfile, ifcentity, shapemode=shapemode)
|
||||
ifc_layers.add_layers(obj, ifcentity, ifcfile)
|
||||
if FreeCAD.GuiUp:
|
||||
@@ -460,37 +462,41 @@ def can_expand(obj, ifcfile=None):
|
||||
|
||||
def add_object(document, otype=None, oname="IfcObject"):
|
||||
"""adds a new object to a FreeCAD document.
|
||||
otype can be 'project', 'group', 'material', 'layer' or None (normal object)"""
|
||||
otype can be:
|
||||
'project',
|
||||
'group',
|
||||
'material',
|
||||
'layer',
|
||||
'text',
|
||||
or anything else for a standard IFC object"""
|
||||
|
||||
if not document:
|
||||
return None
|
||||
proxy = ifc_objects.ifc_object(otype)
|
||||
if otype == "group":
|
||||
proxy = None
|
||||
ftype = "App::DocumentObjectGroupPython"
|
||||
elif otype == "material":
|
||||
ftype = "App::MaterialObjectPython"
|
||||
if otype == "text":
|
||||
obj = Draft.make_text("")
|
||||
obj.Proxy = ifc_objects.ifc_object(otype)
|
||||
elif otype == "layer":
|
||||
ftype = "App::FeaturePython"
|
||||
else:
|
||||
ftype = "Part::FeaturePython"
|
||||
if otype == "project":
|
||||
vp = ifc_viewproviders.ifc_vp_document()
|
||||
proxy = ifc_objects.ifc_object(otype)
|
||||
obj = document.addObject("App::FeaturePython", oname, proxy, None, False)
|
||||
if obj.ViewObject:
|
||||
view_layer.ViewProviderLayer(obj.ViewObject)
|
||||
obj.ViewObject.addProperty("App::PropertyBool", "HideChildren", "Layer")
|
||||
obj.ViewObject.HideChildren = True
|
||||
elif otype == "group":
|
||||
vp = ifc_viewproviders.ifc_vp_group()
|
||||
vproxy = ifc_viewproviders.ifc_vp_group()
|
||||
obj = document.addObject("App::DocumentObjectGroupPython", oname, None, vproxy, False)
|
||||
elif otype == "material":
|
||||
vp = ifc_viewproviders.ifc_vp_material()
|
||||
elif otype == "layer":
|
||||
vp = None
|
||||
else:
|
||||
vp = ifc_viewproviders.ifc_vp_object()
|
||||
obj = document.addObject(ftype, oname, proxy, vp, False)
|
||||
if obj.ViewObject and otype == "layer":
|
||||
from draftviewproviders import view_layer # lazy import
|
||||
|
||||
view_layer.ViewProviderLayer(obj.ViewObject)
|
||||
obj.ViewObject.addProperty("App::PropertyBool", "HideChildren", "Layer")
|
||||
obj.ViewObject.HideChildren = True
|
||||
proxy = ifc_objects.ifc_object(otype)
|
||||
vproxy = ifc_viewproviders.ifc_vp_material()
|
||||
obj = document.addObject("App::MaterialObjectPython", oname, proxy, vproxy, False)
|
||||
elif otype == "project":
|
||||
proxy = ifc_objects.ifc_object(otype)
|
||||
vproxy = ifc_viewproviders.ifc_vp_document()
|
||||
obj = document.addObject("Part::FeaturePython", oname, proxy, vproxy, False)
|
||||
else: # default case, standard IFC object
|
||||
proxy = ifc_objects.ifc_object(otype)
|
||||
vproxy = ifc_viewproviders.ifc_vp_object()
|
||||
obj = document.addObject("Part::FeaturePython", oname, proxy, vproxy, False)
|
||||
return obj
|
||||
|
||||
|
||||
@@ -621,6 +627,17 @@ def add_properties(
|
||||
obj.addProperty("App::PropertyString", attr, "IFC")
|
||||
if value is not None:
|
||||
setattr(obj, attr, str(value))
|
||||
# annotation properties
|
||||
if ifcentity.is_a("IfcAnnotation"):
|
||||
text = ifc_export.get_text(ifcentity)
|
||||
if text:
|
||||
# the two props below are already taken care of, normally
|
||||
if "Placement" not in obj.PropertiesList:
|
||||
obj.addProperty("App::PropertyPlacement", "Placement", "Base")
|
||||
if "Text" not in obj.PropertiesList:
|
||||
obj.addProperty("App::PropertyStringList", "Text", "Base")
|
||||
obj.Text = [text.Literal]
|
||||
obj.Placement = ifc_export.get_placement(ifcentity.ObjectPlacement, ifcfile)
|
||||
# link Label2 and Description
|
||||
if "Description" in obj.PropertiesList and hasattr(obj, "setExpression"):
|
||||
obj.setExpression("Label2", "Description")
|
||||
@@ -1008,12 +1025,15 @@ def aggregate(obj, parent, mode=None):
|
||||
ifcclass = None
|
||||
if mode == "opening":
|
||||
ifcclass = "IfcOpeningElement"
|
||||
objecttype = None
|
||||
if ifc_export.is_annotation(obj):
|
||||
product = ifc_export.create_annotation(obj, ifcfile)
|
||||
if Draft.get_type(obj) in ["DraftText","Text"]:
|
||||
objecttype = "text"
|
||||
else:
|
||||
product = ifc_export.create_product(obj, parent, ifcfile, ifcclass)
|
||||
shapemode = getattr(parent, "ShapeMode", DEFAULT_SHAPEMODE)
|
||||
newobj = create_object(product, obj.Document, ifcfile, shapemode)
|
||||
newobj = create_object(product, obj.Document, ifcfile, shapemode, objecttype)
|
||||
new = True
|
||||
create_relationship(obj, newobj, parent, product, ifcfile, mode)
|
||||
base = getattr(obj, "Base", None)
|
||||
@@ -1317,7 +1337,7 @@ def remove_ifc_element(obj,delete_obj=False):
|
||||
def get_orphan_elements(ifcfile):
|
||||
"""returns a list of orphan products in an ifcfile"""
|
||||
|
||||
products = ifcfile.by_type("IfcElement")
|
||||
products = ifcfile.by_type("IfcProduct")
|
||||
products = [p for p in products if not p.Decomposes]
|
||||
products = [p for p in products if not p.ContainedInStructure]
|
||||
products = [
|
||||
|
||||
Reference in New Issue
Block a user