mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 19:07:57 +00:00
Reimplement drawing material classes, fix cut projection order, and auto refresh camera representation
This commit is contained in:
@@ -93,7 +93,7 @@ endif
|
||||
cp -r blenderbim/* dist/blenderbim/
|
||||
|
||||
# Provides IfcOpenShell Python functionality
|
||||
cd dist/working && wget https://s3.amazonaws.com/ifcopenshell-builds/ifcblender-python-$(PYNUMBER)-v0.7.0-58ee049-$(PLATFORM)64.zip
|
||||
cd dist/working && wget https://s3.amazonaws.com/ifcopenshell-builds/ifcblender-python-$(PYNUMBER)-v0.7.0-93c5906-$(PLATFORM)64.zip
|
||||
cd dist/working && unzip ifcblender*
|
||||
cp -r dist/working/io_import_scene_ifc/ifcopenshell dist/blenderbim/libs/site/packages/
|
||||
|
||||
@@ -360,7 +360,7 @@ endif
|
||||
cd dist/working/ && patch ../blenderbim/libs/site/packages/behave/runner_util.py < runner_util.patch
|
||||
rm -rf dist/working
|
||||
|
||||
# Required by ids
|
||||
# Required by ids - uh, not any more, but I'm trying it out in the drawing module
|
||||
mkdir dist/working
|
||||
cd dist/working && wget $(LXML_URL)
|
||||
cd dist/working && cp *.whl lxml.zip && unzip lxml.zip
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
*/
|
||||
|
||||
* { stroke-linecap: round; stroke-linejoin: round; }
|
||||
*[id] { fill: black; stroke: black; stroke-linecap: 'round'; stroke-width: 0.35; }
|
||||
text { fill: black; stroke: none; }
|
||||
.cut { fill: black; stroke: black; stroke-linecap: 'round'; stroke-width: 0.35; }
|
||||
.projection { fill: white; stroke: black; stroke-linecap: 'round'; stroke-width: 0.25; }
|
||||
.annotation { fill: none; stroke: black; stroke-linecap: 'round'; stroke-width: 0.25; }
|
||||
.hidden { stroke-dasharray: 3, 2; }
|
||||
|
||||
@@ -149,6 +149,8 @@ class CreateDrawing(bpy.types.Operator):
|
||||
self.props = context.scene.DocProperties
|
||||
self.drawing_name = self.file.by_id(self.camera.BIMObjectProperties.ifc_definition_id).Name
|
||||
self.get_scale()
|
||||
if self.camera.data.BIMCameraProperties.update_representation(self.camera):
|
||||
bpy.ops.bim.update_representation(obj=self.camera.name, ifc_representation_class="")
|
||||
underlay_svg = self.generate_underlay(context)
|
||||
self.profile_code("Generate underlay")
|
||||
linework_svg = self.generate_linework(context)
|
||||
@@ -307,12 +309,43 @@ class CreateDrawing(bpy.types.Operator):
|
||||
|
||||
iterators.append(ifcopenshell.geom.iterator(geom_settings, f, multiprocessing.cpu_count(), exclude=exclude))
|
||||
|
||||
with open(svg_path, "w") as svg:
|
||||
results = ifcopenshell.draw.main(draw_settings, files, iterators=iterators, merge_projection=False)
|
||||
svg.write(str(results))
|
||||
results = ifcopenshell.draw.main(draw_settings, files, iterators=iterators, merge_projection=False)
|
||||
|
||||
from lxml import etree
|
||||
|
||||
root = etree.fromstring(results)
|
||||
self.enrich_linework_with_metadata(root)
|
||||
self.move_projection_to_bottom(root)
|
||||
with open(svg_path, "wb") as svg:
|
||||
svg.write(etree.tostring(root))
|
||||
|
||||
return svg_path
|
||||
|
||||
def enrich_linework_with_metadata(self, root):
|
||||
ifc = tool.Ifc.get()
|
||||
for el in root.findall('.//{http://www.w3.org/2000/svg}g[@{http://www.ifcopenshell.org/ns}guid]'):
|
||||
classes = []
|
||||
element = ifc.by_guid(el.get("{http://www.ifcopenshell.org/ns}guid"))
|
||||
material = ifcopenshell.util.element.get_material(element, should_skip_usage=True)
|
||||
if material:
|
||||
if material.is_a("IfcMaterialLayerSet"):
|
||||
name = material.LayerSetName or "null"
|
||||
else:
|
||||
name = getattr(material, "Name", "null")
|
||||
name = self.canonicalise_class_name(name)
|
||||
classes.append(f"material-{name}")
|
||||
if classes:
|
||||
el.set("class", (el.get("class", "") + " " + " ".join(classes)).strip())
|
||||
|
||||
def move_projection_to_bottom(self, root):
|
||||
# https://stackoverflow.com/questions/36018627/sorting-child-elements-with-lxml-based-on-attribute-value
|
||||
group = root.find('{http://www.w3.org/2000/svg}g')
|
||||
#group[:] = sorted(group, key=lambda e : "projection" in e.get("class"))
|
||||
group[:] = reversed(group)
|
||||
|
||||
def canonicalise_class_name(self, name):
|
||||
return re.sub("[^0-9a-zA-Z]+", "", name)
|
||||
|
||||
def generate_annotation(self, context):
|
||||
if not self.props.has_annotation:
|
||||
return
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
import os
|
||||
import bpy
|
||||
import json
|
||||
import ifcopenshell
|
||||
import blenderbim.tool as tool
|
||||
import blenderbim.bim.module.drawing.annotation as annotation
|
||||
@@ -300,6 +301,7 @@ class DocProperties(PropertyGroup):
|
||||
|
||||
|
||||
class BIMCameraProperties(PropertyGroup):
|
||||
representation: StringProperty(name="Representation")
|
||||
view_name: StringProperty(name="View Name")
|
||||
target_view: EnumProperty(
|
||||
items=[
|
||||
@@ -332,6 +334,21 @@ class BIMCameraProperties(PropertyGroup):
|
||||
cut_objects_custom: StringProperty(name="Custom Cut")
|
||||
active_drawing_style_index: IntProperty(name="Active Drawing Style Index")
|
||||
|
||||
# For now, this JSON dump are all the parameters that determine a camera's "Block representation"
|
||||
# By checking this, you will know whether or not the camera IFC representation needs to be refreshed
|
||||
def update_representation(self, obj):
|
||||
representation = json.dumps({
|
||||
"matrix": [list(x) for x in obj.matrix_world],
|
||||
"raster_x": self.raster_x,
|
||||
"raster_y": self.raster_y,
|
||||
"ortho_scale": obj.data.ortho_scale,
|
||||
"clip_end": obj.data.clip_end,
|
||||
})
|
||||
if self.representation != representation:
|
||||
self.representation = representation
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class BIMTextProperties(PropertyGroup):
|
||||
font_size: EnumProperty(
|
||||
|
||||
@@ -383,14 +383,14 @@ class OverrideDelete(bpy.types.Operator):
|
||||
for obj in context.selected_objects:
|
||||
if obj.BIMObjectProperties.ifc_definition_id:
|
||||
element = file.by_id(obj.BIMObjectProperties.ifc_definition_id)
|
||||
if element.FillsVoids:
|
||||
if getattr(element, "FillsVoids", None):
|
||||
self.remove_filling(element)
|
||||
if element.is_a("IfcOpeningElement"):
|
||||
for rel in element.HasFillings:
|
||||
self.remove_filling(rel.RelatedBuildingElement)
|
||||
if element.VoidsElements:
|
||||
self.delete_opening_element(element)
|
||||
elif element.HasOpenings:
|
||||
elif getattr(element, "HasOpenings", None):
|
||||
for rel in element.HasOpenings:
|
||||
self.delete_opening_element(rel.RelatedOpeningElement)
|
||||
bpy.data.objects.remove(obj)
|
||||
|
||||
Reference in New Issue
Block a user