Continue refactor, and provide user options to regenerate vector base layer / annotation layer of drawings. See #1153.

This commit is contained in:
Dion Moult
2021-05-16 22:15:55 +10:00
parent f2352e9a17
commit 537efdcb53
12 changed files with 361 additions and 315 deletions
-17
View File
@@ -117,24 +117,15 @@ if bpy is not None:
operator.AddSectionsAnnotations, operator.AddSectionsAnnotations,
prop.StrProperty, prop.StrProperty,
prop.Attribute, prop.Attribute,
prop.Variable,
prop.Drawing,
prop.Schedule,
prop.DrawingStyle,
prop.Sheet,
prop.BIMProperties, prop.BIMProperties,
prop.DocProperties,
prop.IfcParameter, prop.IfcParameter,
prop.PsetQto, prop.PsetQto,
prop.GlobalId, prop.GlobalId,
prop.RepresentationItem,
prop.BIMObjectProperties, prop.BIMObjectProperties,
prop.BIMMaterialProperties, prop.BIMMaterialProperties,
prop.SweptSolid, prop.SweptSolid,
prop.ItemSlotMap, prop.ItemSlotMap,
prop.BIMMeshProperties, prop.BIMMeshProperties,
prop.BIMCameraProperties,
prop.BIMTextProperties,
ui.BIM_PT_section_plane, ui.BIM_PT_section_plane,
ui.BIM_PT_drawings, ui.BIM_PT_drawings,
ui.BIM_PT_schedules, ui.BIM_PT_schedules,
@@ -176,7 +167,6 @@ if bpy is not None:
bpy.types.TOPBAR_MT_file_export.append(menu_func_export) bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
bpy.types.TOPBAR_MT_file_import.append(menu_func_import) bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
bpy.types.Scene.BIMProperties = bpy.props.PointerProperty(type=prop.BIMProperties) bpy.types.Scene.BIMProperties = bpy.props.PointerProperty(type=prop.BIMProperties)
bpy.types.Scene.DocProperties = bpy.props.PointerProperty(type=prop.DocProperties)
bpy.types.Object.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties) bpy.types.Object.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties)
bpy.types.Material.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties) bpy.types.Material.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties)
bpy.types.Collection.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties) # Check if we need this bpy.types.Collection.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties) # Check if we need this
@@ -184,15 +174,12 @@ if bpy is not None:
bpy.types.Mesh.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties) bpy.types.Mesh.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
bpy.types.Curve.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties) bpy.types.Curve.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
bpy.types.Camera.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties) bpy.types.Camera.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
bpy.types.Camera.BIMCameraProperties = bpy.props.PointerProperty(type=prop.BIMCameraProperties)
bpy.types.TextCurve.BIMTextProperties = bpy.props.PointerProperty(type=prop.BIMTextProperties)
bpy.types.SCENE_PT_unit.append(ui.ifc_units) bpy.types.SCENE_PT_unit.append(ui.ifc_units)
for module in modules.values(): for module in modules.values():
module.register() module.register()
bpy.app.handlers.depsgraph_update_pre.append(operator.depsgraph_update_pre_handler) bpy.app.handlers.depsgraph_update_pre.append(operator.depsgraph_update_pre_handler)
bpy.app.handlers.load_post.append(handler.toggleDecorationsOnLoad)
def unregister(): def unregister():
for cls in reversed(classes): for cls in reversed(classes):
@@ -203,7 +190,6 @@ if bpy is not None:
bpy.types.TOPBAR_MT_file_export.remove(menu_func_export) bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
bpy.types.TOPBAR_MT_file_import.remove(menu_func_import) bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
del bpy.types.Scene.BIMProperties del bpy.types.Scene.BIMProperties
del bpy.types.Scene.DocProperties
del bpy.types.Object.BIMObjectProperties del bpy.types.Object.BIMObjectProperties
del bpy.types.Material.BIMObjectProperties del bpy.types.Material.BIMObjectProperties
del bpy.types.Collection.BIMObjectProperties # Check if we need this del bpy.types.Collection.BIMObjectProperties # Check if we need this
@@ -211,12 +197,9 @@ if bpy is not None:
del bpy.types.Mesh.BIMMeshProperties del bpy.types.Mesh.BIMMeshProperties
del bpy.types.Curve.BIMMeshProperties del bpy.types.Curve.BIMMeshProperties
del bpy.types.Camera.BIMMeshProperties del bpy.types.Camera.BIMMeshProperties
del bpy.types.Camera.BIMCameraProperties
del bpy.types.TextCurve.BIMTextProperties
bpy.types.SCENE_PT_unit.remove(ui.ifc_units) bpy.types.SCENE_PT_unit.remove(ui.ifc_units)
for module in reversed(list(modules.values())): for module in reversed(list(modules.values())):
module.unregister() module.unregister()
bpy.app.handlers.depsgraph_update_pre.remove(operator.depsgraph_update_pre_handler) bpy.app.handlers.depsgraph_update_pre.remove(operator.depsgraph_update_pre_handler)
bpy.app.handlers.load_post.remove(handler.toggleDecorationsOnLoad)
-10
View File
@@ -1,7 +1,6 @@
import bpy import bpy
import json import json
import addon_utils import addon_utils
import blenderbim.bim.decoration as decoration
import ifcopenshell.api.owner.settings import ifcopenshell.api.owner.settings
from bpy.app.handlers import persistent from bpy.app.handlers import persistent
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
@@ -252,12 +251,3 @@ def setDefaultProperties(scene):
drawing_style.name = "Blender Default" drawing_style.name = "Blender Default"
drawing_style.render_type = "DEFAULT" drawing_style.render_type = "DEFAULT"
bpy.ops.bim.save_drawing_style(index="2") bpy.ops.bim.save_drawing_style(index="2")
@persistent
def toggleDecorationsOnLoad(*args):
toggle = bpy.context.scene.DocProperties.should_draw_decorations
if toggle:
decoration.DecorationsHandler.install(bpy.context)
else:
decoration.DecorationsHandler.uninstall()
-12
View File
@@ -97,18 +97,6 @@ def get_project_collection(scene):
return colls[0] return colls[0]
def get_active_drawing(scene):
"""Get active drawing collection and camera"""
props = scene.DocProperties
if props.active_drawing_index is None or len(props.drawings) == 0:
return None, None
try:
drawing = props.drawings[props.active_drawing_index]
return scene.collection.children["Views"].children[f"IfcGroup/{drawing.name}"], drawing.camera
except (KeyError, IndexError):
raise RuntimeError("missing drawing collection")
def ortho_view_frame(camera, margin=0.015): def ortho_view_frame(camera, margin=0.015):
"""Calculates 2d bounding box of camera view area. """Calculates 2d bounding box of camera view area.
@@ -1,17 +1,31 @@
import bpy import bpy
from . import ui, operator from . import ui, prop, operator, handler
classes = ( classes = (
operator.AddDrawing, operator.AddDrawing,
operator.CreateDrawing, operator.CreateDrawing,
operator.AddAnnotation, operator.AddAnnotation,
prop.Variable,
prop.Drawing,
prop.Schedule,
prop.DrawingStyle,
prop.Sheet,
prop.DocProperties,
prop.BIMCameraProperties,
prop.BIMTextProperties,
ui.BIM_PT_camera, ui.BIM_PT_camera,
) )
def register(): def register():
pass bpy.types.Scene.DocProperties = bpy.props.PointerProperty(type=prop.DocProperties)
bpy.types.Camera.BIMCameraProperties = bpy.props.PointerProperty(type=prop.BIMCameraProperties)
bpy.types.TextCurve.BIMTextProperties = bpy.props.PointerProperty(type=prop.BIMTextProperties)
bpy.app.handlers.load_post.append(handler.toggleDecorationsOnLoad)
def unregister(): def unregister():
pass del bpy.types.Scene.DocProperties
del bpy.types.Camera.BIMCameraProperties
del bpy.types.TextCurve.BIMTextProperties
bpy.app.handlers.load_post.remove(handler.toggleDecorationsOnLoad)
@@ -13,7 +13,7 @@ import gpu
import bgl import bgl
from gpu.types import GPUShader, GPUBatch, GPUIndexBuf, GPUVertBuf, GPUVertFormat from gpu.types import GPUShader, GPUBatch, GPUIndexBuf, GPUVertBuf, GPUVertFormat
from gpu_extras.batch import batch_for_shader from gpu_extras.batch import batch_for_shader
from . import helper import blenderbim.bim.module.drawing.helper as helper
class BaseDecorator(): class BaseDecorator():
@@ -0,0 +1,12 @@
import bpy
import blenderbim.bim.module.drawing.decoration as decoration
from bpy.app.handlers import persistent
@persistent
def toggleDecorationsOnLoad(*args):
toggle = bpy.context.scene.DocProperties.should_draw_decorations
if toggle:
decoration.DecorationsHandler.install(bpy.context)
else:
decoration.DecorationsHandler.uninstall()
@@ -139,3 +139,15 @@ def format_distance(value, isArea=False, hide_units=True):
tx_dist = fmt % value tx_dist = fmt % value
return tx_dist return tx_dist
def get_active_drawing(scene):
"""Get active drawing collection and camera"""
props = scene.DocProperties
if props.active_drawing_index is None or len(props.drawings) == 0:
return None, None
try:
drawing = props.drawings[props.active_drawing_index]
return scene.collection.children["Views"].children[f"IfcGroup/{drawing.name}"], drawing.camera
except (KeyError, IndexError):
raise RuntimeError("missing drawing collection")
@@ -7,7 +7,6 @@ import ifcopenshell.util.representation
import blenderbim.bim.module.drawing.svgwriter as svgwriter import blenderbim.bim.module.drawing.svgwriter as svgwriter
import blenderbim.bim.module.drawing.annotation as annotation import blenderbim.bim.module.drawing.annotation as annotation
from mathutils import Vector, Matrix, Euler, geometry from mathutils import Vector, Matrix, Euler, geometry
from blenderbim.bim.operator import open_with_user_command
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from ifcopenshell.api.group.data import Data as GroupData from ifcopenshell.api.group.data import Data as GroupData
from ifcopenshell.api.pset.data import Data as PsetData from ifcopenshell.api.pset.data import Data as PsetData
@@ -15,6 +14,15 @@ from ifcopenshell.api.pset.data import Data as PsetData
cwd = os.path.dirname(os.path.realpath(__file__)) cwd = os.path.dirname(os.path.realpath(__file__))
def open_with_user_command(user_command, path):
if user_command:
commands = eval(user_command)
for command in commands:
subprocess.run(command)
else:
webbrowser.open("file://" + path)
class AddDrawing(bpy.types.Operator): class AddDrawing(bpy.types.Operator):
bl_idname = "bim.add_drawing" bl_idname = "bim.add_drawing"
bl_label = "Add Drawing" bl_label = "Add Drawing"
@@ -62,6 +70,14 @@ class CreateDrawing(bpy.types.Operator):
bl_label = "Create Drawing" bl_label = "Create Drawing"
def execute(self, context): def execute(self, context):
self.camera = context.scene.camera
if (
not (self.camera.type == "CAMERA" and self.camera.data.type == "ORTHO")
or not self.camera.BIMObjectProperties.ifc_definition_id
):
return
self.props = context.scene.DocProperties
self.drawing_name = IfcStore.get_file().by_id(self.camera.BIMObjectProperties.ifc_definition_id).Name
base_svg = self.ifc_to_svg(context) base_svg = self.ifc_to_svg(context)
annotation_svg = self.annotation_to_svg(context) annotation_svg = self.annotation_to_svg(context)
svg_path = self.combine_svgs(context, base_svg, annotation_svg) svg_path = self.combine_svgs(context, base_svg, annotation_svg)
@@ -70,7 +86,7 @@ class CreateDrawing(bpy.types.Operator):
def combine_svgs(self, context, base, annotation): def combine_svgs(self, context, base, annotation):
# Hacky :) # Hacky :)
svg_path = context.scene.BIMProperties.ifc_file[0:-4] + ".svg" svg_path = os.path.join(context.scene.BIMProperties.data_dir, "diagrams", self.drawing_name + ".svg")
with open(svg_path, "w") as outfile: with open(svg_path, "w") as outfile:
with open(base) as infile: with open(base) as infile:
for line in infile: for line in infile:
@@ -85,7 +101,9 @@ class CreateDrawing(bpy.types.Operator):
return svg_path return svg_path
def ifc_to_svg(self, context): def ifc_to_svg(self, context):
svg_path = context.scene.BIMProperties.ifc_file[0:-4] + "-base.svg" svg_path = os.path.join(context.scene.BIMProperties.data_dir, "cache", self.drawing_name + "-base.svg")
if os.path.isfile(svg_path) and not self.props.should_regenerate_base_layer:
return svg_path
ifcconvert_path = os.path.join(cwd, "..", "..", "..", "libs", "IfcConvert") ifcconvert_path = os.path.join(cwd, "..", "..", "..", "libs", "IfcConvert")
subprocess.run( subprocess.run(
[ [
@@ -109,11 +127,11 @@ class CreateDrawing(bpy.types.Operator):
return svg_path return svg_path
def annotation_to_svg(self, context): def annotation_to_svg(self, context):
camera = context.scene.camera svg_path = os.path.join(context.scene.BIMProperties.data_dir, "cache", self.drawing_name + "-annotation.svg")
if os.path.isfile(svg_path) and not self.props.should_regenerate_annotation_layer:
if not (camera.type == "CAMERA" and camera.data.type == "ORTHO"): return svg_path
return
camera = self.camera
svg_writer = svgwriter.SvgWriter() svg_writer = svgwriter.SvgWriter()
if camera.data.BIMCameraProperties.diagram_scale == "CUSTOM": if camera.data.BIMCameraProperties.diagram_scale == "CUSTOM":
@@ -141,7 +159,7 @@ class CreateDrawing(bpy.types.Operator):
width = height / render.resolution_y * render.resolution_x width = height / render.resolution_y * render.resolution_x
svg_writer.scale = float(numerator) / float(denominator) svg_writer.scale = float(numerator) / float(denominator)
svg_writer.output = context.scene.BIMProperties.ifc_file[0:-4] + "-annotation.svg" svg_writer.output = svg_path
svg_writer.data_dir = bpy.context.scene.BIMProperties.data_dir svg_writer.data_dir = bpy.context.scene.BIMProperties.data_dir
svg_writer.vector_style = drawing_style.vector_style svg_writer.vector_style = drawing_style.vector_style
svg_writer.camera = camera svg_writer.camera = camera
@@ -0,0 +1,278 @@
import os
import bpy
import blenderbim.bim.module.drawing.annotation as annotation
import blenderbim.bim.module.drawing.decoration as decoration
from pathlib import Path
from blenderbim.bim.prop import Attribute, StrProperty
from bpy.types import PropertyGroup
from bpy.props import (
PointerProperty,
StringProperty,
EnumProperty,
BoolProperty,
IntProperty,
FloatProperty,
FloatVectorProperty,
CollectionProperty,
)
diagram_scales_enum = []
titleblocks_enum = []
sheets_enum = []
vector_styles_enum = []
def purge():
global diagram_scales_enum
global titleblocks_enum
global sheets_enum
global vector_styles_enum
diagram_scales_enum = []
titleblocks_enum = []
sheets_enum = []
vector_styles_enum = []
def getDiagramScales(self, context):
global diagram_scales_enum
if (
len(diagram_scales_enum) < 1
or (context.scene.unit_settings.system == "IMPERIAL" and len(diagram_scales_enum) == 13)
or (context.scene.unit_settings.system == "METRIC" and len(diagram_scales_enum) == 31)
):
if context.scene.unit_settings.system == "IMPERIAL":
diagram_scales_enum = [
("CUSTOM", "Custom", ""),
("1'=1'-0\"|1/1", "1'=1'-0\"", ""),
('6"=1\'-0"|1/6', '6"=1\'-0"', ""),
('1-1/2"=1\'-0"|1/8', '1-1/2"=1\'-0"', ""),
('1"=1\'-0"|1/12', '1"=1\'-0"', ""),
('3/4"=1\'-0"|1/16', '3/4"=1\'-0"', ""),
('1/2"=1\'-0"|1/24', '1/2"=1\'-0"', ""),
('3/8"=1\'-0"|1/32', '3/8"=1\'-0"', ""),
('1/4"=1\'-0"|1/48', '1/4"=1\'-0"', ""),
('3/16"=1\'-0"|1/64', '3/16"=1\'-0"', ""),
('1/8"=1\'-0"|1/96', '1/8"=1\'-0"', ""),
('3/32"=1\'-0"|1/128', '3/32"=1\'-0"', ""),
('1/16"=1\'-0"|1/192', '1/16"=1\'-0"', ""),
('1/32"=1\'-0"|1/384', '1/32"=1\'-0"', ""),
('1/64"=1\'-0"|1/768', '1/64"=1\'-0"', ""),
('1/128"=1\'-0"|1/1536', '1/128"=1\'-0"', ""),
("1\"=10'|1/120", "1\"=10'", ""),
("1\"=20'|1/240", "1\"=20'", ""),
("1\"=30'|1/360", "1\"=30'", ""),
("1\"=40'|1/480", "1\"=40'", ""),
("1\"=50'|1/600", "1\"=50'", ""),
("1\"=60'|1/720", "1\"=60'", ""),
("1\"=70'|1/840", "1\"=70'", ""),
("1\"=80'|1/960", "1\"=80'", ""),
("1\"=90'|1/1080", "1\"=90'", ""),
("1\"=100'|1/1200", "1\"=100'", ""),
("1\"=150'|1/1800", "1\"=150'", ""),
("1\"=200'|1/2400", "1\"=200'", ""),
("1\"=300'|1/3600", "1\"=300'", ""),
("1\"=400'|1/4800", "1\"=400'", ""),
("1\"=500'|1/6000", "1\"=500'", ""),
]
else:
diagram_scales_enum = [
("CUSTOM", "Custom", ""),
("1:5000|1/5000", "1:5000", ""),
("1:2000|1/2000", "1:2000", ""),
("1:1000|1/1000", "1:1000", ""),
("1:500|1/500", "1:500", ""),
("1:200|1/200", "1:200", ""),
("1:100|1/100", "1:100", ""),
("1:50|1/50", "1:50", ""),
("1:20|1/20", "1:20", ""),
("1:10|1/10", "1:10", ""),
("1:5|1/5", "1:5", ""),
("1:2|1/2", "1:2", ""),
("1:1|1/1", "1:1", ""),
]
return diagram_scales_enum
def updateDrawingName(self, context):
if not self.camera:
return
if self.camera.name == self.name:
return
self.camera.name = "IfcGroup/{}".format(self.name)
self.camera.users_collection[0].name = self.camera.name
self.name = self.camera.name.split("/")[1]
def refreshActiveDrawingIndex(self, context):
bpy.ops.bim.activate_view(drawing_index=context.scene.DocProperties.active_drawing_index)
def getTitleblocks(self, context):
global titleblocks_enum
if len(titleblocks_enum) < 1:
titleblocks_enum.clear()
for filename in Path(os.path.join(context.scene.BIMProperties.data_dir, "templates", "titleblocks")).glob(
"*.svg"
):
f = str(filename.stem)
titleblocks_enum.append((f, f, ""))
return titleblocks_enum
def refreshTitleblocks(self, context):
global titleblocks_enum
titleblocks_enum.clear()
getTitleblocks(self, context)
def toggleDecorations(self, context):
toggle = self.should_draw_decorations
if toggle:
decoration.DecorationsHandler.install(context)
else:
decoration.DecorationsHandler.uninstall()
def getVectorStyles(self, context):
global vector_styles_enum
if len(vector_styles_enum) < 1:
sheets_enum.clear()
for filename in Path(os.path.join(context.scene.BIMProperties.data_dir, "styles")).glob("*.css"):
f = str(filename.stem)
vector_styles_enum.append((f, f, ""))
return vector_styles_enum
def refreshFontSize(self, context):
annotation.Annotator.resize_text(context.active_object)
class Variable(PropertyGroup):
name: StringProperty(name="Name")
prop_key: StringProperty(name="Property Key")
class Drawing(PropertyGroup):
name: StringProperty(name="Name", update=updateDrawingName)
camera: PointerProperty(name="Camera", type=bpy.types.Object)
class Schedule(PropertyGroup):
name: StringProperty(name="Name")
file: StringProperty(name="File")
class Sheet(PropertyGroup):
def set_name(self, new):
old = self.get("name")
path = os.path.join(bpy.context.scene.BIMProperties.data_dir, "sheets")
if old and os.path.isfile(os.path.join(path, old + ".svg")):
os.rename(os.path.join(path, old + ".svg"), os.path.join(path, new + ".svg"))
self["name"] = new
def get_name(self):
return self.get("name")
name: StringProperty(name="Name", get=get_name, set=set_name)
drawings: CollectionProperty(name="Drawings", type=Drawing)
active_drawing_index: IntProperty(name="Active Drawing Index")
class DrawingStyle(PropertyGroup):
name: StringProperty(name="Name")
raster_style: StringProperty(name="Raster Style")
render_type: EnumProperty(
items=[
("NONE", "None", ""),
("DEFAULT", "Default", ""),
("VIEWPORT", "Viewport", ""),
],
name="Render Type",
default="VIEWPORT",
)
vector_style: EnumProperty(items=getVectorStyles, name="Vector Style")
include_query: StringProperty(name="Include Query")
exclude_query: StringProperty(name="Exclude Query")
attributes: CollectionProperty(name="Attributes", type=StrProperty)
class DocProperties(PropertyGroup):
should_regenerate_base_layer: BoolProperty(name="Regenerate Base Layer", default=True)
should_regenerate_annotation_layer: BoolProperty(name="Regenerate Annotation Layer", default=True)
should_recut: BoolProperty(name="Should Recut", default=True)
should_recut_selected: BoolProperty(name="Should Recut Selected Only", default=False)
should_extract: BoolProperty(name="Should Extract", default=True)
drawings: CollectionProperty(name="Drawings", type=Drawing)
active_drawing_index: IntProperty(name="Active Drawing Index", update=refreshActiveDrawingIndex)
current_drawing_index: IntProperty(name="Current Drawing Index")
schedules: CollectionProperty(name="Schedules", type=Schedule)
active_schedule_index: IntProperty(name="Active Schedule Index")
titleblock: EnumProperty(items=getTitleblocks, name="Titleblock", update=refreshTitleblocks)
sheets: CollectionProperty(name="Sheets", type=Sheet)
active_sheet_index: IntProperty(name="Active Sheet Index")
ifc_files: CollectionProperty(name="IFCs", type=StrProperty)
drawing_styles: CollectionProperty(name="Drawing Styles", type=DrawingStyle)
should_draw_decorations: BoolProperty(name="Should Draw Decorations", update=toggleDecorations)
decorations_colour: FloatVectorProperty(
name="Decorations Colour", subtype="COLOR", default=(1, 0, 0, 1), min=0.0, max=1.0, size=4
)
class BIMCameraProperties(PropertyGroup):
view_name: StringProperty(name="View Name")
target_view: EnumProperty(
items=[
("PLAN_VIEW", "PLAN_VIEW", ""),
("ELEVATION_VIEW", "ELEVATION_VIEW", ""),
("SECTION_VIEW", "SECTION_VIEW", ""),
("REFLECTED_PLAN_VIEW", "REFLECTED_PLAN_VIEW", ""),
("MODEL_VIEW", "MODEL_VIEW", ""),
],
name="Target View",
default="PLAN_VIEW",
)
diagram_scale: EnumProperty(items=getDiagramScales, name="Drawing Scale")
custom_diagram_scale: StringProperty(name="Custom Scale")
raster_x: IntProperty(name="Raster X", default=1000)
raster_y: IntProperty(name="Raster Y", default=1000)
is_nts: BoolProperty(name="Is NTS")
cut_objects: EnumProperty(
items=[
(
".IfcWall|.IfcSlab|.IfcCurtainWall|.IfcStair|.IfcStairFlight|.IfcColumn|.IfcBeam|.IfcMember|.IfcCovering|.IfcSpace",
"Overall Plan / Section",
"",
),
(".IfcElement", "Detail Drawing", ""),
("CUSTOM", "Custom", ""),
],
name="Cut Objects",
)
cut_objects_custom: StringProperty(name="Custom Cut")
active_drawing_style_index: IntProperty(name="Active Drawing Style Index")
class BIMTextProperties(PropertyGroup):
font_size: EnumProperty(
items=[
("1.8", "1.8 - Small", ""),
("2.5", "2.5 - Regular", ""),
("3.5", "3.5 - Large", ""),
("5.0", "5.0 - Header", ""),
("7.0", "7.0 - Title", ""),
],
update=refreshFontSize,
name="Font Size",
)
symbol: EnumProperty(
items=[
("None", "None", ""),
("rectangle-tag", "Rectangle Tag", ""),
("door-tag", "Door Tag", ""),
],
update=refreshFontSize,
name="Symbol",
)
related_element: PointerProperty(name="Related Element", type=bpy.types.Object)
variables: CollectionProperty(name="Variables", type=Variable)
@@ -29,6 +29,10 @@ class BIM_PT_camera(Panel):
layout.label(text="Generation Options:") layout.label(text="Generation Options:")
row = layout.row()
row.prop(dprops, "should_regenerate_base_layer")
row = layout.row()
row.prop(dprops, "should_regenerate_annotation_layer")
row = layout.row() row = layout.row()
row.prop(dprops, "should_recut") row.prop(dprops, "should_recut")
row = layout.row() row = layout.row()
@@ -13,6 +13,8 @@ import ifcopenshell.util.geolocation
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.representation import ifcopenshell.util.representation
import ifcopenshell.util.schema import ifcopenshell.util.schema
# Deleting the below drawing import breaks svgwrite's ElementTree appending because ... magic?
import blenderbim.bim.module.drawing
import numpy as np import numpy as np
from . import export_ifc from . import export_ifc
from . import import_ifc from . import import_ifc
+9 -264
View File
@@ -1,14 +1,9 @@
import json
import os import os
from pathlib import Path import bpy
import json
import importlib import importlib
import ifcopenshell import ifcopenshell
from . import export_ifc import ifcopenshell.util.pset
from . import schema
from . import ifc
import blenderbim.bim.module.drawing.annotation as annotation
from . import decoration
import bpy
from blenderbim.bim.handler import purge_module_data from blenderbim.bim.handler import purge_module_data
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from bpy.types import PropertyGroup from bpy.types import PropertyGroup
@@ -25,14 +20,14 @@ from bpy.props import (
cwd = os.path.dirname(os.path.realpath(__file__)) cwd = os.path.dirname(os.path.realpath(__file__))
diagram_scales_enum = []
titleblocks_enum = []
materialpsetnames_enum = [] materialpsetnames_enum = []
contexts_enum = [] contexts_enum = []
subcontexts_enum = [] subcontexts_enum = []
target_views_enum = [] target_views_enum = []
sheets_enum = []
vector_styles_enum = []
def getAttributeEnumValues(self, context):
return [(e, e, "") for e in json.loads(self.enum_items)]
def updateIfcFile(self, context): def updateIfcFile(self, context):
@@ -42,114 +37,11 @@ def updateIfcFile(self, context):
purge_module_data() purge_module_data()
def getDiagramScales(self, context):
global diagram_scales_enum
if (
len(diagram_scales_enum) < 1
or (bpy.context.scene.unit_settings.system == "IMPERIAL" and len(diagram_scales_enum) == 13)
or (bpy.context.scene.unit_settings.system == "METRIC" and len(diagram_scales_enum) == 31)
):
if bpy.context.scene.unit_settings.system == "IMPERIAL":
diagram_scales_enum = [
("CUSTOM", "Custom", ""),
("1'=1'-0\"|1/1", "1'=1'-0\"", ""),
('6"=1\'-0"|1/6', '6"=1\'-0"', ""),
('1-1/2"=1\'-0"|1/8', '1-1/2"=1\'-0"', ""),
('1"=1\'-0"|1/12', '1"=1\'-0"', ""),
('3/4"=1\'-0"|1/16', '3/4"=1\'-0"', ""),
('1/2"=1\'-0"|1/24', '1/2"=1\'-0"', ""),
('3/8"=1\'-0"|1/32', '3/8"=1\'-0"', ""),
('1/4"=1\'-0"|1/48', '1/4"=1\'-0"', ""),
('3/16"=1\'-0"|1/64', '3/16"=1\'-0"', ""),
('1/8"=1\'-0"|1/96', '1/8"=1\'-0"', ""),
('3/32"=1\'-0"|1/128', '3/32"=1\'-0"', ""),
('1/16"=1\'-0"|1/192', '1/16"=1\'-0"', ""),
('1/32"=1\'-0"|1/384', '1/32"=1\'-0"', ""),
('1/64"=1\'-0"|1/768', '1/64"=1\'-0"', ""),
('1/128"=1\'-0"|1/1536', '1/128"=1\'-0"', ""),
("1\"=10'|1/120", "1\"=10'", ""),
("1\"=20'|1/240", "1\"=20'", ""),
("1\"=30'|1/360", "1\"=30'", ""),
("1\"=40'|1/480", "1\"=40'", ""),
("1\"=50'|1/600", "1\"=50'", ""),
("1\"=60'|1/720", "1\"=60'", ""),
("1\"=70'|1/840", "1\"=70'", ""),
("1\"=80'|1/960", "1\"=80'", ""),
("1\"=90'|1/1080", "1\"=90'", ""),
("1\"=100'|1/1200", "1\"=100'", ""),
("1\"=150'|1/1800", "1\"=150'", ""),
("1\"=200'|1/2400", "1\"=200'", ""),
("1\"=300'|1/3600", "1\"=300'", ""),
("1\"=400'|1/4800", "1\"=400'", ""),
("1\"=500'|1/6000", "1\"=500'", ""),
]
else:
diagram_scales_enum = [
("CUSTOM", "Custom", ""),
("1:5000|1/5000", "1:5000", ""),
("1:2000|1/2000", "1:2000", ""),
("1:1000|1/1000", "1:1000", ""),
("1:500|1/500", "1:500", ""),
("1:200|1/200", "1:200", ""),
("1:100|1/100", "1:100", ""),
("1:50|1/50", "1:50", ""),
("1:20|1/20", "1:20", ""),
("1:10|1/10", "1:10", ""),
("1:5|1/5", "1:5", ""),
("1:2|1/2", "1:2", ""),
("1:1|1/1", "1:1", ""),
]
return diagram_scales_enum
def updateDrawingName(self, context):
if not self.camera:
return
if self.camera.name == self.name:
return
self.camera.name = "IfcGroup/{}".format(self.name)
self.camera.users_collection[0].name = self.camera.name
self.name = self.camera.name.split("/")[1]
def refreshActiveDrawingIndex(self, context):
bpy.ops.bim.activate_view(drawing_index=context.scene.DocProperties.active_drawing_index)
def getAttributeEnumValues(self, context):
return [(e, e, "") for e in json.loads(self.enum_items)]
def getTitleblocks(self, context):
global titleblocks_enum
if len(titleblocks_enum) < 1:
titleblocks_enum.clear()
for filename in Path(os.path.join(context.scene.BIMProperties.data_dir, "templates", "titleblocks")).glob(
"*.svg"
):
f = str(filename.stem)
titleblocks_enum.append((f, f, ""))
return titleblocks_enum
def refreshTitleblocks(self, context):
global titleblocks_enum
titleblocks_enum.clear()
getTitleblocks(self, context)
def toggleDecorations(self, context):
toggle = self.should_draw_decorations
if toggle:
decoration.DecorationsHandler.install(context)
else:
decoration.DecorationsHandler.uninstall()
def getMaterialPsetNames(self, context): def getMaterialPsetNames(self, context):
global materialpsetnames_enum global materialpsetnames_enum
materialpsetnames_enum.clear() materialpsetnames_enum.clear()
pset_names = schema.ifc.psetqto.get_applicable_names("IfcMaterial", pset_only=True) psetqto = ifcopenshell.util.pset.get_template("IFC4")
pset_names = psetqto.get_applicable_names("IfcMaterial", pset_only=True)
materialpsetnames_enum.extend([(p, p, "") for p in pset_names]) materialpsetnames_enum.extend([(p, p, "") for p in pset_names])
return materialpsetnames_enum return materialpsetnames_enum
@@ -215,29 +107,10 @@ def getTargetViews(self, context):
return target_views_enum return target_views_enum
def getVectorStyles(self, context):
global vector_styles_enum
if len(vector_styles_enum) < 1:
sheets_enum.clear()
for filename in Path(os.path.join(context.scene.BIMProperties.data_dir, "styles")).glob("*.css"):
f = str(filename.stem)
vector_styles_enum.append((f, f, ""))
return vector_styles_enum
def refreshFontSize(self, context):
annotation.Annotator.resize_text(context.active_object)
class StrProperty(PropertyGroup): class StrProperty(PropertyGroup):
pass pass
class Variable(PropertyGroup):
name: StringProperty(name="Name")
prop_key: StringProperty(name="Property Key")
def updateAttributeStringValue(self, context): def updateAttributeStringValue(self, context):
updateAttributeValue(self, self.string_value) updateAttributeValue(self, self.string_value)
@@ -276,129 +149,6 @@ class Attribute(PropertyGroup):
enum_value: EnumProperty(items=getAttributeEnumValues, name="Value", update=updateAttributeEnumValue) enum_value: EnumProperty(items=getAttributeEnumValues, name="Value", update=updateAttributeEnumValue)
class Drawing(PropertyGroup):
name: StringProperty(name="Name", update=updateDrawingName)
camera: PointerProperty(name="Camera", type=bpy.types.Object)
class Schedule(PropertyGroup):
name: StringProperty(name="Name")
file: StringProperty(name="File")
class Sheet(PropertyGroup):
def set_name(self, new):
old = self.get("name")
path = os.path.join(bpy.context.scene.BIMProperties.data_dir, "sheets")
if old and os.path.isfile(os.path.join(path, old + ".svg")):
os.rename(os.path.join(path, old + ".svg"), os.path.join(path, new + ".svg"))
self["name"] = new
def get_name(self):
return self.get("name")
name: StringProperty(name="Name", get=get_name, set=set_name)
drawings: CollectionProperty(name="Drawings", type=Drawing)
active_drawing_index: IntProperty(name="Active Drawing Index")
class DrawingStyle(PropertyGroup):
name: StringProperty(name="Name")
raster_style: StringProperty(name="Raster Style")
render_type: EnumProperty(
items=[
("NONE", "None", ""),
("DEFAULT", "Default", ""),
("VIEWPORT", "Viewport", ""),
],
name="Render Type",
default="VIEWPORT",
)
vector_style: EnumProperty(items=getVectorStyles, name="Vector Style")
include_query: StringProperty(name="Include Query")
exclude_query: StringProperty(name="Exclude Query")
attributes: CollectionProperty(name="Attributes", type=StrProperty)
class DocProperties(PropertyGroup):
should_recut: BoolProperty(name="Should Recut", default=True)
should_recut_selected: BoolProperty(name="Should Recut Selected Only", default=False)
should_extract: BoolProperty(name="Should Extract", default=True)
drawings: CollectionProperty(name="Drawings", type=Drawing)
active_drawing_index: IntProperty(name="Active Drawing Index", update=refreshActiveDrawingIndex)
current_drawing_index: IntProperty(name="Current Drawing Index")
schedules: CollectionProperty(name="Schedules", type=Schedule)
active_schedule_index: IntProperty(name="Active Schedule Index")
titleblock: EnumProperty(items=getTitleblocks, name="Titleblock", update=refreshTitleblocks)
sheets: CollectionProperty(name="Sheets", type=Sheet)
active_sheet_index: IntProperty(name="Active Sheet Index")
ifc_files: CollectionProperty(name="IFCs", type=StrProperty)
drawing_styles: CollectionProperty(name="Drawing Styles", type=DrawingStyle)
should_draw_decorations: BoolProperty(name="Should Draw Decorations", update=toggleDecorations)
decorations_colour: FloatVectorProperty(
name="Decorations Colour", subtype="COLOR", default=(1, 0, 0, 1), min=0.0, max=1.0, size=4
)
class BIMCameraProperties(PropertyGroup):
view_name: StringProperty(name="View Name")
target_view: EnumProperty(
items=[
("PLAN_VIEW", "PLAN_VIEW", ""),
("ELEVATION_VIEW", "ELEVATION_VIEW", ""),
("SECTION_VIEW", "SECTION_VIEW", ""),
("REFLECTED_PLAN_VIEW", "REFLECTED_PLAN_VIEW", ""),
("MODEL_VIEW", "MODEL_VIEW", ""),
],
name="Target View",
default="PLAN_VIEW",
)
diagram_scale: EnumProperty(items=getDiagramScales, name="Drawing Scale")
custom_diagram_scale: StringProperty(name="Custom Scale")
raster_x: IntProperty(name="Raster X", default=1000)
raster_y: IntProperty(name="Raster Y", default=1000)
is_nts: BoolProperty(name="Is NTS")
cut_objects: EnumProperty(
items=[
(
".IfcWall|.IfcSlab|.IfcCurtainWall|.IfcStair|.IfcStairFlight|.IfcColumn|.IfcBeam|.IfcMember|.IfcCovering|.IfcSpace",
"Overall Plan / Section",
"",
),
(".IfcElement", "Detail Drawing", ""),
("CUSTOM", "Custom", ""),
],
name="Cut Objects",
)
cut_objects_custom: StringProperty(name="Custom Cut")
active_drawing_style_index: IntProperty(name="Active Drawing Style Index")
class BIMTextProperties(PropertyGroup):
font_size: EnumProperty(
items=[
("1.8", "1.8 - Small", ""),
("2.5", "2.5 - Regular", ""),
("3.5", "3.5 - Large", ""),
("5.0", "5.0 - Header", ""),
("7.0", "7.0 - Title", ""),
],
update=refreshFontSize,
name="Font Size",
)
symbol: EnumProperty(
items=[
("None", "None", ""),
("rectangle-tag", "Rectangle Tag", ""),
("door-tag", "Door Tag", ""),
],
update=refreshFontSize,
name="Symbol",
)
related_element: PointerProperty(name="Related Element", type=bpy.types.Object)
variables: CollectionProperty(name="Variables", type=Variable)
class BIMProperties(PropertyGroup): class BIMProperties(PropertyGroup):
schema_dir: StringProperty(default=os.path.join(cwd, "schema") + os.path.sep, name="Schema Directory") schema_dir: StringProperty(default=os.path.join(cwd, "schema") + os.path.sep, name="Schema Directory")
data_dir: StringProperty(default=os.path.join(cwd, "data") + os.path.sep, name="Data Directory") data_dir: StringProperty(default=os.path.join(cwd, "data") + os.path.sep, name="Data Directory")
@@ -516,11 +266,6 @@ class SweptSolid(PropertyGroup):
extrusion: StringProperty(name="Extrusion") extrusion: StringProperty(name="Extrusion")
class RepresentationItem(PropertyGroup):
name: StringProperty(name="Name")
vgroup: StringProperty(name="Vertex Group")
class ItemSlotMap(PropertyGroup): class ItemSlotMap(PropertyGroup):
name: StringProperty(name="Item Element ID") name: StringProperty(name="Item Element ID")
slot_index: IntProperty(name="Material Slot Index") slot_index: IntProperty(name="Material Slot Index")