Saving drawing shading styles to ifc #2991

Now shading styles are stored in ifc. It's actually stored in json file (by default it's in projects "assets/shading_styles.json") and the path to it saved in `EPset_Drawing.ShadingStyles`.
Current shading styles is stored in `EPset_Drawing.CurrentShadingStyle`.

This change could potentially cause problems but I've added some temporary fallback to make sure `EPset_Drawing.ShadingStyles` will be set to some default path and default shading styles will be copied to the project's folder.
This commit is contained in:
Andrej730
2023-05-11 17:22:41 +05:00
parent 7ca6f9d7a1
commit 38cf88d5d2
15 changed files with 423 additions and 130 deletions
@@ -0,0 +1,125 @@
{
"Technical": {
"raster_style": {
"bpy.data.worlds[0].color": [
1,
1,
1
],
"scene.render.engine": "BLENDER_WORKBENCH",
"scene.render.film_transparent": false,
"scene.display.shading.show_object_outline": true,
"scene.display.shading.show_cavity": false,
"scene.display.shading.cavity_type": "BOTH",
"scene.display.shading.curvature_ridge_factor": 1,
"scene.display.shading.curvature_valley_factor": 1,
"scene.view_settings.view_transform": "Standard",
"scene.display.shading.light": "FLAT",
"scene.display.shading.color_type": "SINGLE",
"scene.display.shading.single_color": [
1,
1,
1
],
"scene.display.shading.show_shadows": false,
"scene.display.shading.shadow_intensity": 0.5,
"scene.display.light_direction": [
0.5,
0.5,
0.5
],
"scene.view_settings.use_curve_mapping": false,
"space.overlay.show_wireframes": true,
"space.overlay.wireframe_threshold": 0,
"space.overlay.show_floor": false,
"space.overlay.show_axis_x": false,
"space.overlay.show_axis_y": false,
"space.overlay.show_axis_z": false,
"space.overlay.show_object_origins": false,
"space.overlay.show_relationship_lines": false
},
"render_type": "VIEWPORT"
},
"Shaded": {
"raster_style": {
"bpy.data.worlds[0].color": [
1,
1,
1
],
"scene.render.engine": "BLENDER_WORKBENCH",
"scene.render.film_transparent": false,
"scene.display.shading.show_object_outline": true,
"scene.display.shading.show_cavity": true,
"scene.display.shading.cavity_type": "BOTH",
"scene.display.shading.curvature_ridge_factor": 1,
"scene.display.shading.curvature_valley_factor": 1,
"scene.view_settings.view_transform": "Standard",
"scene.display.shading.light": "STUDIO",
"scene.display.shading.color_type": "MATERIAL",
"scene.display.shading.single_color": [
1,
1,
1
],
"scene.display.shading.show_shadows": true,
"scene.display.shading.shadow_intensity": 0.5,
"scene.display.light_direction": [
0.5,
0.5,
0.5
],
"scene.view_settings.use_curve_mapping": false,
"space.overlay.show_wireframes": false,
"space.overlay.wireframe_threshold": 0,
"space.overlay.show_floor": false,
"space.overlay.show_axis_x": false,
"space.overlay.show_axis_y": false,
"space.overlay.show_axis_z": false,
"space.overlay.show_object_origins": false,
"space.overlay.show_relationship_lines": false
},
"render_type": "VIEWPORT"
},
"Blender Default": {
"raster_style": {
"bpy.data.worlds[0].color": [
0.05087608844041824,
0.05087608844041824,
0.05087608844041824
],
"scene.render.engine": "BLENDER_EEVEE",
"scene.render.film_transparent": false,
"scene.view_settings.view_transform": "Filmic",
"scene.display.shading.show_object_outline": false,
"scene.display.shading.show_cavity": false,
"scene.display.shading.cavity_type": "WORLD",
"scene.display.shading.curvature_ridge_factor": 0.0,
"scene.display.shading.curvature_valley_factor": 0.0,
"scene.display.shading.light": "STUDIO",
"scene.display.shading.color_type": "MATERIAL",
"scene.display.shading.single_color": [
0.800000011920929,
0.800000011920929,
0.800000011920929
],
"scene.display.shading.show_shadows": false,
"scene.display.shading.shadow_intensity": 0.5,
"scene.display.light_direction": [
0.5773502588272095,
0.5773502588272095,
0.5773502588272095
],
"scene.view_settings.use_curve_mapping": false,
"space.overlay.show_wireframes": false,
"space.overlay.wireframe_threshold": 1.0,
"space.overlay.show_floor": true,
"space.overlay.show_axis_x": true,
"space.overlay.show_axis_y": true,
"space.overlay.show_axis_z": false,
"space.overlay.show_object_origins": true,
"space.overlay.show_relationship_lines": true
},
"render_type": "VIEWPORT"
}
}
@@ -5,7 +5,7 @@ FILE_NAME('EPset_Drawing.ifc','2020-01-01T00:00:00',(),(),'EPset_Drawing','EPset
FILE_SCHEMA(('IFC4'));
ENDSEC;
DATA;
#1=IFCPROPERTYSETTEMPLATE('2JhNIvqZrFnAgxfhK0XVQX',$,'EPset_Drawing','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation',(#2,#3,#4,#5,#6,#7,#8,#9,#10,#11,#12,#13,#14,#15,#16,#17,#18,#19));
#1=IFCPROPERTYSETTEMPLATE('2JhNIvqZrFnAgxfhK0XVQX',$,'EPset_Drawing','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation',(#2,#3,#4,#5,#6,#7,#8,#9,#10,#11,#12,#13,#14,#15,#16,#17,#18,#19,#20,#21));
#2=IFCSIMPLEPROPERTYTEMPLATE('23JavTMk98ZxXhrUEnjAcf',$,'TargetView','',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
#3=IFCSIMPLEPROPERTYTEMPLATE('1yVWUt5H9DAOuu0OaMMLpe',$,'Scale','The scale of this drawing represented as a numerator and denominator, such as 1/100',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
#4=IFCSIMPLEPROPERTYTEMPLATE('3gsuPBtU93b8f0gg1pjkq6',$,'HumanScale','The scale of this drawing in human readable format, such as 1:100',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
@@ -24,5 +24,7 @@ DATA;
#17=IFCSIMPLEPROPERTYTEMPLATE('38uAtrp9nD_901NO42zd$7',$,'ImperialPrecision','',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
#18=IFCSIMPLEPROPERTYTEMPLATE('1MX0uffTL6TOvtvEJpxFmk',$,'DecimalPlaces','',.P_SINGLEVALUE.,'IfcInteger',$,$,$,$,$,.READWRITE.);
#19=IFCSIMPLEPROPERTYTEMPLATE('0joEq0Rd10cxweEh0NeHT6',$,'JoinCriteria','Comma separated selection keys which determine what cut objects are to be joined.',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.);
#20=IFCSIMPLEPROPERTYTEMPLATE('0nYMT3OSj5gArVniCWZRtv',$,'ShadingStyles','',.P_SINGLEVALUE.,'IfcURIReference',$,$,$,$,$,.READWRITE.);
#21=IFCSIMPLEPROPERTYTEMPLATE('3VWG22eZXBdQwdKlzMeVQH',$,'CurrentShadingStyle','',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
ENDSEC;
END-ISO-10303-21;
@@ -18,7 +18,7 @@ DATA;
#11=IFCSIMPLEPROPERTYTEMPLATE('1DtsPn5a9FG8$zXHDDMavY',$,'ShowEndArrow','Display end arrow.',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
#12=IFCSIMPLEPROPERTYTEMPLATE('2$6U0mLI9AiPRWeBabdY3u',$,'EndArrowSymbol','Custom symbol for the end of the section marker arrow. Need to make sure it''s present in "symbols.svg".',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
#13=IFCSIMPLEPROPERTYTEMPLATE('1naFqntIL7igCY7hCaE7kq',$,'HasConnectedSectionLine','Connect or disconnect section markers with line (by default = True).',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
#14=IFCPROPERTYSETTEMPLATE('3V8oZ8YRD3_O7uR5vcUleS',$,'BBIM_Documentation','',.PSET_OCCURRENCEDRIVEN.,'IfcProject',(#15,#16,#17,#18,#19,#20,#21,#22));
#14=IFCPROPERTYSETTEMPLATE('3V8oZ8YRD3_O7uR5vcUleS',$,'BBIM_Documentation','',.PSET_OCCURRENCEDRIVEN.,'IfcProject',(#15,#16,#17,#18,#19,#20,#21,#22,#23));
#15=IFCSIMPLEPROPERTYTEMPLATE('0ulAhgk3v9qfGlDILauR6J',$,'SheetsDir','Default sheets directory',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
#16=IFCSIMPLEPROPERTYTEMPLATE('2yvlVKiQXASucfH40deCvu',$,'LayoutsDir','Default layouts directory',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
#17=IFCSIMPLEPROPERTYTEMPLATE('2kXZqXicL3jRwsOnLM_0ho',$,'TitleblocksDir','Default titleblocks directory',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
@@ -27,10 +27,12 @@ DATA;
#20=IFCSIMPLEPROPERTYTEMPLATE('23tejOrxj859R_eCRp1AFP',$,'MarkersPath','Default markers SVG',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
#21=IFCSIMPLEPROPERTYTEMPLATE('1UDakJ5_f7kBhggNSW4$h5',$,'SymbolsPath','Default symbols SVG',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
#22=IFCSIMPLEPROPERTYTEMPLATE('0d53LEtgLDQxnv__NfgH7i',$,'PatternsPath','Default patterns SVG',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
#23=IFCPROPERTYSETTEMPLATE('0I9merLinF5Ap$aZwaclgm',$,'BBIM_Dimension','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation,IfcTypeProduct',(#24,#25,#26,#27));
#24=IFCSIMPLEPROPERTYTEMPLATE('1rL2AbQsXD8RbpoWH5pYOV',$,'ShowDescriptionOnly','Hide the measurement values and show only annotation description',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
#25=IFCSIMPLEPROPERTYTEMPLATE('0SVyOfB0rC2xNfdRYf3XvY',$,'SuppressZeroInches','Suppress 0 inch values in dimension annotation text (for example: 12'' - 0" -> 12'')',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
#26=IFCSIMPLEPROPERTYTEMPLATE('2bUmj458PBqPAtUoI3MXsb',$,'TextPrefix','Text to add before annotation measurement value',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
#27=IFCSIMPLEPROPERTYTEMPLATE('0bnzttUb9BPuN597uNTXOE',$,'TextSuffix','Text to add after annotation measurement value',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
#23=IFCSIMPLEPROPERTYTEMPLATE('26qFNMv7nCHgU6Jd7Anga5',$,'ShadingStylesPath','Default shading styles',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
#24=IFCPROPERTYSETTEMPLATE('0I9merLinF5Ap$aZwaclgm',$,'BBIM_Dimension','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation,IfcTypeProduct',(#25,#26,#27,#28));
#25=IFCSIMPLEPROPERTYTEMPLATE('1rL2AbQsXD8RbpoWH5pYOV',$,'ShowDescriptionOnly','Hide the measurement values and show only annotation description',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
#26=IFCSIMPLEPROPERTYTEMPLATE('0SVyOfB0rC2xNfdRYf3XvY',$,'SuppressZeroInches','Suppress 0 inch values in dimension annotation text (for example: 12'' - 0" -> 12'')',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
#27=IFCSIMPLEPROPERTYTEMPLATE('2bUmj458PBqPAtUoI3MXsb',$,'TextPrefix','Text to add before annotation measurement value',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
#28=IFCSIMPLEPROPERTYTEMPLATE('0bnzttUb9BPuN597uNTXOE',$,'TextSuffix','Text to add after annotation measurement value',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
ENDSEC;
END-ISO-10303-21;
+1 -70
View File
@@ -282,73 +282,4 @@ def setDefaultProperties(scene):
)
ifcopenshell.api.owner.settings.get_user = lambda ifc: core_owner.get_user(tool.Owner)
ifcopenshell.api.owner.settings.get_application = get_application
# TODO: Move to drawing module
if len(bpy.context.scene.DocProperties.drawing_styles) == 0:
drawing_style = bpy.context.scene.DocProperties.drawing_styles.add()
drawing_style.name = "Blender Default"
drawing_style.render_type = "DEFAULT"
bpy.ops.bim.save_drawing_style(index="0")
drawing_style = bpy.context.scene.DocProperties.drawing_styles.add()
drawing_style.name = "Technical"
drawing_style.render_type = "VIEWPORT"
drawing_style.raster_style = json.dumps(
{
RasterStyleProperty.WORLD_COLOR.value: (1, 1, 1),
RasterStyleProperty.RENDER_ENGINE.value: "BLENDER_WORKBENCH",
RasterStyleProperty.RENDER_TRANSPARENT.value: False,
RasterStyleProperty.SHADING_SHOW_OBJECT_OUTLINE.value: True,
RasterStyleProperty.SHADING_SHOW_CAVITY.value: False,
RasterStyleProperty.SHADING_CAVITY_TYPE.value: "BOTH",
RasterStyleProperty.SHADING_CURVATURE_RIDGE_FACTOR.value: 1,
RasterStyleProperty.SHADING_CURVATURE_VALLEY_FACTOR.value: 1,
RasterStyleProperty.VIEW_TRANSFORM.value: "Standard",
RasterStyleProperty.SHADING_LIGHT.value: "FLAT",
RasterStyleProperty.SHADING_COLOR_TYPE.value: "SINGLE",
RasterStyleProperty.SHADING_SINGLE_COLOR.value: (1, 1, 1),
RasterStyleProperty.SHADING_SHOW_SHADOWS.value: False,
RasterStyleProperty.SHADING_SHADOW_INTENSITY.value: 0.5,
RasterStyleProperty.DISPLAY_LIGHT_DIRECTION.value: (0.5, 0.5, 0.5),
RasterStyleProperty.VIEW_USE_CURVE_MAPPING.value: False,
RasterStyleProperty.OVERLAY_SHOW_WIREFRAMES.value: True,
RasterStyleProperty.OVERLAY_WIREFRAME_THRESHOLD.value: 0,
RasterStyleProperty.OVERLAY_SHOW_FLOOR.value: False,
RasterStyleProperty.OVERLAY_SHOW_AXIS_X.value: False,
RasterStyleProperty.OVERLAY_SHOW_AXIS_Y.value: False,
RasterStyleProperty.OVERLAY_SHOW_AXIS_Z.value: False,
RasterStyleProperty.OVERLAY_SHOW_OBJECT_ORIGINS.value: False,
RasterStyleProperty.OVERLAY_SHOW_RELATIONSHIP_LINES.value: False,
}
)
drawing_style = bpy.context.scene.DocProperties.drawing_styles.add()
drawing_style.name = "Shaded"
drawing_style.render_type = "VIEWPORT"
drawing_style.raster_style = json.dumps(
{
RasterStyleProperty.WORLD_COLOR.value: (1, 1, 1),
RasterStyleProperty.RENDER_ENGINE.value: "BLENDER_WORKBENCH",
RasterStyleProperty.RENDER_TRANSPARENT.value: False,
RasterStyleProperty.SHADING_SHOW_OBJECT_OUTLINE.value: True,
RasterStyleProperty.SHADING_SHOW_CAVITY.value: True,
RasterStyleProperty.SHADING_CAVITY_TYPE.value: "BOTH",
RasterStyleProperty.SHADING_CURVATURE_RIDGE_FACTOR.value: 1,
RasterStyleProperty.SHADING_CURVATURE_VALLEY_FACTOR.value: 1,
RasterStyleProperty.VIEW_TRANSFORM.value: "Standard",
RasterStyleProperty.SHADING_LIGHT.value: "STUDIO",
RasterStyleProperty.SHADING_COLOR_TYPE.value: "MATERIAL",
RasterStyleProperty.SHADING_SINGLE_COLOR.value: (1, 1, 1),
RasterStyleProperty.SHADING_SHOW_SHADOWS.value: True,
RasterStyleProperty.SHADING_SHADOW_INTENSITY.value: 0.5,
RasterStyleProperty.DISPLAY_LIGHT_DIRECTION.value: (0.5, 0.5, 0.5),
RasterStyleProperty.VIEW_USE_CURVE_MAPPING.value: False,
RasterStyleProperty.OVERLAY_SHOW_WIREFRAMES.value: False,
RasterStyleProperty.OVERLAY_WIREFRAME_THRESHOLD.value: 0,
RasterStyleProperty.OVERLAY_SHOW_FLOOR.value: False,
RasterStyleProperty.OVERLAY_SHOW_AXIS_X.value: False,
RasterStyleProperty.OVERLAY_SHOW_AXIS_Y.value: False,
RasterStyleProperty.OVERLAY_SHOW_AXIS_Z.value: False,
RasterStyleProperty.OVERLAY_SHOW_OBJECT_ORIGINS.value: False,
RasterStyleProperty.OVERLAY_SHOW_RELATIONSHIP_LINES.value: False,
}
)
AuthoringData.type_thumbnails = {}
AuthoringData.type_thumbnails = {}
@@ -61,11 +61,13 @@ classes = (
operator.RemoveDrawingStyle,
operator.RemoveDrawingStyleAttribute,
operator.RemoveSchedule,
operator.ReloadDrawingStyles,
operator.RemoveSheet,
operator.RemoveTextLiteral,
operator.SelectAllDrawings,
operator.ResizeText,
operator.SaveDrawingStyle,
operator.SaveDrawingStylesData,
operator.SelectAssignedProduct,
operator.SelectDocIfcFile,
prop.Variable,
@@ -103,6 +103,7 @@ class DrawingsData:
"has_saved_ifc": cls.has_saved_ifc(),
"total_drawings": cls.total_drawings(),
"location_hint": cls.location_hint(),
"active_drawing_pset_data": cls.active_drawing_pset_data(),
}
cls.is_loaded = True
@@ -124,6 +125,15 @@ class DrawingsData:
return results
return [(h.upper(), h, "") for h in ["North", "South", "East", "West"]]
@classmethod
def active_drawing_pset_data(cls):
ifc_file = tool.Ifc.get()
drawing_id = bpy.context.scene.DocProperties.active_drawing_id
if drawing_id == 0:
return {}
drawing = ifc_file.by_id(bpy.context.scene.DocProperties.active_drawing_id)
return ifcopenshell.util.element.get_pset(drawing, "EPset_Drawing")
class SchedulesData:
data = {}
@@ -41,7 +41,7 @@ import blenderbim.bim.module.drawing.sheeter as sheeter
import blenderbim.bim.module.drawing.scheduler as scheduler
import blenderbim.bim.module.drawing.helper as helper
from blenderbim.bim.module.drawing.decoration import CutDecorator
from blenderbim.bim.module.drawing.data import DecoratorData
from blenderbim.bim.module.drawing.data import DecoratorData, DrawingsData
import blenderbim.bim.export_ifc
from lxml import etree
from mathutils import Vector
@@ -628,7 +628,6 @@ class CreateDrawing(bpy.types.Operator):
# Loop over the cell paths
for pi, p in enumerate(g2.getElementsByTagName("path")):
d = p.getAttribute("d")
coords = [co[1:].split(",") for co in d.split() if co[1:]]
polygon = shapely.Polygon(coords)
@@ -943,11 +942,17 @@ class CreateDrawing(bpy.types.Operator):
camera_props = self.camera.data.BIMCameraProperties
if camera_props.diagram_scale == "CUSTOM":
if context.scene.unit_settings.system == "IMPERIAL":
if camera_props.custom_diagram_scale_input1[-1] == "'" or camera_props.custom_diagram_scale_input1[-1] == "\"":
if (
camera_props.custom_diagram_scale_input1[-1] == "'"
or camera_props.custom_diagram_scale_input1[-1] == '"'
):
camera_props.custom_diagram_scale_input1 = camera_props.custom_diagram_scale_input1[:-1]
if camera_props.custom_diagram_scale_input2[-1] == "'":
camera_props.custom_diagram_scale_input2 = camera_props.custom_diagram_scale_input2[:-1]
if camera_props.custom_diagram_scale_input2[1:] == "'-0\"" or camera_props.custom_diagram_scale_input2[1:] == "' 0\"":
if (
camera_props.custom_diagram_scale_input2[1:] == "'-0\""
or camera_props.custom_diagram_scale_input2[1:] == "' 0\""
):
camera_props.custom_diagram_scale_input2 = camera_props.custom_diagram_scale_input2[0]
if "/" in camera_props.custom_diagram_scale_input1:
if " " in camera_props.custom_diagram_scale_input1:
@@ -1333,9 +1338,12 @@ class ActivateDrawing(bpy.types.Operator):
def execute(self, context):
drawing = tool.Ifc.get().by_id(self.drawing)
dprops = bpy.context.scene.DocProperties
core.activate_drawing_view(tool.Ifc, tool.Drawing, drawing=drawing)
bpy.context.scene.DocProperties.active_drawing_id = self.drawing
dprops.active_drawing_id = self.drawing
dprops.drawing_styles.clear()
if ifcopenshell.util.element.get_pset(drawing, "EPset_Drawing", "HasUnderlay"):
bpy.ops.bim.reload_drawing_styles()
bpy.ops.bim.activate_drawing_style()
core.sync_references(tool.Ifc, tool.Collector, tool.Drawing, drawing=tool.Ifc.get().by_id(self.drawing))
CutDecorator.install(context)
@@ -1405,18 +1413,81 @@ class RemoveDrawing(bpy.types.Operator, Operator):
core.remove_drawing(tool.Ifc, tool.Drawing, drawing=drawing)
class AddDrawingStyle(bpy.types.Operator):
class ReloadDrawingStyles(bpy.types.Operator):
bl_idname = "bim.reload_drawing_styles"
bl_label = "Reload Drawing Styles"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
if not DrawingsData.is_loaded:
DrawingsData.load()
drawing_pset_data = DrawingsData.data["active_drawing_pset_data"]
camera_props = context.active_object.data.BIMCameraProperties
# added this part as a temporary fallback
# TODO: should remove it a bit later when projects get more accommodated
# with saving shadingstyles to ifc and separate json file
if "ShadingStyles" not in drawing_pset_data:
ifc_file = tool.Ifc.get()
pset = ifc_file.by_id(drawing_pset_data["id"])
edit_properties = {
"ShadingStyles": (
shading_styles_path := tool.Drawing.get_default_drawing_resource_path("ShadingStyles")
),
"CurrentShadingStyle": tool.Drawing.get_default_shading_style(),
}
ifcopenshell.api.run("pset.edit_pset", ifc_file, pset=pset, properties=edit_properties)
tool.Drawing.setup_shading_styles_path(shading_styles_path)
DrawingsData.load()
drawing_pset_data = DrawingsData.data["active_drawing_pset_data"]
if "ShadingStyles" not in drawing_pset_data:
self.report({"ERROR"}, "Could not find shading styles path in EPset_Drawing.ShadingStyles.")
return {"CANCELLED"}
rel_path = drawing_pset_data["ShadingStyles"]
current_style = drawing_pset_data.get("CurrentShadingStyle", None)
json_path = Path(tool.Ifc.resolve_uri(rel_path))
if not json_path.exists():
self.report({"ERROR"}, "Shading styles file not found: {}".format(json_path))
return {"CANCELLED"}
with open(json_path, "r") as fi:
shading_styles_json = json.load(fi)
drawing_styles = context.scene.DocProperties.drawing_styles
drawing_styles.clear()
styles = [style for style in shading_styles_json]
for style_name in styles:
style_data = shading_styles_json[style_name]
drawing_style = drawing_styles.add()
drawing_style["name"] = style_name # setting as attribute to avoid triggering setter
drawing_style.render_type = style_data["render_type"]
drawing_style.raster_style = json.dumps(style_data["raster_style"])
if current_style is not None:
camera_props.active_drawing_style_index = styles.index(current_style)
return {"FINISHED"}
class AddDrawingStyle(bpy.types.Operator, Operator):
bl_idname = "bim.add_drawing_style"
bl_label = "Add Drawing Style"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
new = context.scene.DocProperties.drawing_styles.add()
new.name = "New Drawing Style"
drawing_styles = context.scene.DocProperties.drawing_styles
new = drawing_styles.add()
# drawing style is saved to ifc on rename
new.name = tool.Blender.ensure_unique_name("New Drawing Style", drawing_styles)
context.scene.camera.data.BIMCameraProperties.active_drawing_style_index = len(drawing_styles) - 1
return {"FINISHED"}
class RemoveDrawingStyle(bpy.types.Operator):
class RemoveDrawingStyle(bpy.types.Operator, Operator):
bl_idname = "bim.remove_drawing_style"
bl_label = "Remove Drawing Style"
bl_options = {"REGISTER", "UNDO"}
@@ -1424,13 +1495,17 @@ class RemoveDrawingStyle(bpy.types.Operator):
def execute(self, context):
context.scene.DocProperties.drawing_styles.remove(self.index)
context.scene.camera.data.BIMCameraProperties.active_drawing_style_index = max(self.index - 1, 0)
bpy.ops.bim.save_drawing_styles_data()
return {"FINISHED"}
class SaveDrawingStyle(bpy.types.Operator):
class SaveDrawingStyle(bpy.types.Operator, Operator):
bl_idname = "bim.save_drawing_style"
bl_label = "Save Drawing Style"
bl_options = {"REGISTER", "UNDO"}
bl_description = "Save current render setting to currently selected drawing style. Also resaves styles data to IFC"
index: bpy.props.StringProperty()
# TODO: check undo redo
@@ -1446,11 +1521,14 @@ class SaveDrawingStyle(bpy.types.Operator):
except TypeError:
pass
style[prop.value] = value
if self.index:
index = int(self.index)
else:
index = context.active_object.data.BIMCameraProperties.active_drawing_style_index
scene.DocProperties.drawing_styles[index].raster_style = json.dumps(style)
bpy.ops.bim.save_drawing_styles_data()
return {"FINISHED"}
def get_view_3d(self, context):
@@ -1463,19 +1541,83 @@ class SaveDrawingStyle(bpy.types.Operator):
return space
class ActivateDrawingStyle(bpy.types.Operator):
class SaveDrawingStylesData(bpy.types.Operator, Operator):
bl_idname = "bim.save_drawing_styles_data"
bl_label = "Save Drawing Styles Data"
bl_options = {"REGISTER", "UNDO"}
skip_updating_current_style: bpy.props.BoolProperty(default=False)
rename_style: bpy.props.BoolProperty(default=False)
rename_style_from: bpy.props.StringProperty(default="")
rename_style_to: bpy.props.StringProperty(default="")
def execute(self, context):
if not DrawingsData.is_loaded:
DrawingsData.load()
drawing_pset_data = DrawingsData.data["active_drawing_pset_data"]
drawing_styles = context.scene.DocProperties.drawing_styles
rel_path = drawing_pset_data["ShadingStyles"]
current_style = drawing_pset_data.get("CurrentShadingStyle", None)
json_path = Path(tool.Ifc.resolve_uri(rel_path))
if not json_path.exists():
self.report({"ERROR"}, "Shading styles file not found: {}".format(json_path))
return {"CANCELLED"}
styles_data = {}
for style in drawing_styles:
style_data = {"render_type": style.render_type, "raster_style": json.loads(style.raster_style)}
styles_data[style.name] = style_data
with open(json_path, "w") as fo:
json.dump(styles_data, fo, indent=4)
# TODO: currently it doesn't update current style for the other drawings
# handling case when current style is not present in styles saved in ifc
if not self.skip_updating_current_style and current_style not in styles_data and current_style is not None:
# style was renamed
if self.rename_style and current_style == self.rename_style_from:
new_style_name = self.rename_style_to
# style was removed
else:
new_style_name = None
ifc_file = tool.Ifc.get()
drawing = ifc_file.by_id(context.scene.DocProperties.active_drawing_id)
pset = tool.Pset.get_element_pset(drawing, "EPset_Drawing")
ifcopenshell.api.run(
"pset.edit_pset", ifc_file, pset=pset, properties={"CurrentShadingStyle": new_style_name}
)
blenderbim.bim.handler.refresh_ui_data()
return {"FINISHED"}
class ActivateDrawingStyle(bpy.types.Operator, Operator):
bl_idname = "bim.activate_drawing_style"
bl_label = "Activate Drawing Style"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
scene = context.scene
if scene.camera.data.BIMCameraProperties.active_drawing_style_index < len(scene.DocProperties.drawing_styles):
self.drawing_style = scene.DocProperties.drawing_styles[
scene.camera.data.BIMCameraProperties.active_drawing_style_index
]
self.set_raster_style(context)
self.set_query(context)
ifc_file = tool.Ifc.get()
active_drawing_style_index = scene.camera.data.BIMCameraProperties.active_drawing_style_index
if active_drawing_style_index >= len(scene.DocProperties.drawing_styles):
return
self.drawing_style = scene.DocProperties.drawing_styles[active_drawing_style_index]
self.set_raster_style(context)
self.set_query(context)
drawing = ifc_file.by_id(scene.DocProperties.active_drawing_id)
pset = tool.Pset.get_element_pset(drawing, "EPset_Drawing")
ifcopenshell.api.run(
"pset.edit_pset", ifc_file, pset=pset, properties={"CurrentShadingStyle": self.drawing_style.name}
)
blenderbim.bim.handler.refresh_ui_data()
return {"FINISHED"}
def set_raster_style(self, context):
@@ -1658,6 +1800,7 @@ class AddScheduleToSheet(bpy.types.Operator, Operator):
tool.Drawing.import_sheets()
# TODO: dead code - drawing style attributes are never used?
class AddDrawingStyleAttribute(bpy.types.Operator):
bl_idname = "bim.add_drawing_style_attribute"
bl_label = "Add Drawing Style Attribute"
@@ -1669,6 +1812,7 @@ class AddDrawingStyleAttribute(bpy.types.Operator):
return {"FINISHED"}
# TODO: dead code - drawing style attributes are never used?
class RemoveDrawingStyleAttribute(bpy.types.Operator):
bl_idname = "bim.remove_drawing_style_attribute"
bl_label = "Remove Drawing Style Attribute"
@@ -156,6 +156,21 @@ def update_drawing_name(self, context):
core.update_drawing_name(tool.Ifc, tool.Drawing, drawing=drawing, name=self.name)
def get_drawing_style_name(self):
"""needed to make `set_drawing_style_name` work"""
return self.get("name", "")
def set_drawing_style_name(self, new_value):
"""ensure the name is unique"""
scene = bpy.context.scene
drawing_styles = [s.name for s in scene.DocProperties.drawing_styles if s.name != self.name]
new_value = tool.Blender.ensure_unique_name(new_value, drawing_styles)
old_value = self.name
self["name"] = new_value
bpy.ops.bim.save_drawing_styles_data(rename_style=True, rename_style_from=old_value, rename_style_to=new_value)
def update_schedule_name(self, context):
schedule = tool.Ifc.get().by_id(self.ifc_definition_id)
core.update_schedule_name(tool.Ifc, tool.Drawing, schedule=schedule, name=self.name)
@@ -236,8 +251,8 @@ class Sheet(PropertyGroup):
class DrawingStyle(PropertyGroup):
name: StringProperty(name="Name")
raster_style: StringProperty(name="Raster Style")
name: StringProperty(name="Name", get=get_drawing_style_name, set=set_drawing_style_name)
raster_style: StringProperty(name="Raster Style", default="{}")
render_type: EnumProperty(
items=[
("NONE", "None", ""),
@@ -324,6 +339,10 @@ class DocProperties(PropertyGroup):
markers_path: StringProperty(default=os.path.join("drawings", "assets", "markers.svg"), name="Default Markers")
symbols_path: StringProperty(default=os.path.join("drawings", "assets", "symbols.svg"), name="Default Symbols")
patterns_path: StringProperty(default=os.path.join("drawings", "assets", "patterns.svg"), name="Default Patterns")
shadingstyles_path: StringProperty(
default=os.path.join("drawings", "assets", "shading_styles.json"), name="Default Shading Styles"
)
shadingstyle_default: StringProperty(default="Blender Default", name="Default Shading Style")
class BIMCameraProperties(PropertyGroup):
@@ -117,38 +117,53 @@ class BIM_PT_drawing_underlay(Panel):
layout.use_property_split = True
dprops = context.scene.DocProperties
props = context.active_object.data.BIMCameraProperties
drawing_index_is_valid = props.active_drawing_style_index < len(dprops.drawing_styles)
if not DrawingsData.is_loaded:
DrawingsData.load()
drawing_pset_data = DrawingsData.data["active_drawing_pset_data"]
row = layout.row(align=True)
row.operator("bim.add_drawing_style")
current_shading_style = drawing_pset_data.get("CurrentShadingStyle", None)
if current_shading_style is None:
row.label(text="Current style is not set.")
else:
row.label(text="Current Shading Style:")
row.label(text=current_shading_style)
row.operator("bim.add_drawing_style", icon="ADD", text="")
if drawing_index_is_valid:
row.operator("bim.remove_drawing_style", icon="X", text="").index = props.active_drawing_style_index
row.operator("bim.reload_drawing_styles", icon="FILE_REFRESH", text="")
if dprops.drawing_styles:
layout.template_list("BIM_UL_generic", "", dprops, "drawing_styles", props, "active_drawing_style_index")
if not dprops.drawing_styles:
return
layout.template_list("BIM_UL_generic", "", dprops, "drawing_styles", props, "active_drawing_style_index")
if props.active_drawing_style_index < len(dprops.drawing_styles):
drawing_style = dprops.drawing_styles[props.active_drawing_style_index]
if not drawing_index_is_valid:
return
drawing_style = dprops.drawing_styles[props.active_drawing_style_index]
row = layout.row(align=True)
row.prop(drawing_style, "name")
row.operator("bim.remove_drawing_style", icon="X", text="").index = props.active_drawing_style_index
row = layout.row(align=True)
row.prop(drawing_style, "name")
row = layout.row()
row.prop(drawing_style, "render_type")
row = layout.row(align=True)
row.prop(drawing_style, "include_query")
row = layout.row(align=True)
row.prop(drawing_style, "exclude_query")
row = layout.row()
row.prop(drawing_style, "render_type")
row = layout.row(align=True)
row.prop(drawing_style, "include_query")
row = layout.row(align=True)
row.prop(drawing_style, "exclude_query")
row = layout.row()
row.operator("bim.add_drawing_style_attribute")
row = layout.row()
row.operator("bim.add_drawing_style_attribute")
for index, attribute in enumerate(drawing_style.attributes):
row = layout.row(align=True)
row.prop(attribute, "name", text="")
row.operator("bim.remove_drawing_style_attribute", icon="X", text="").index = index
for index, attribute in enumerate(drawing_style.attributes):
row = layout.row(align=True)
row.prop(attribute, "name", text="")
row.operator("bim.remove_drawing_style_attribute", icon="X", text="").index = index
row = layout.row(align=True)
row.operator("bim.save_drawing_style")
row.operator("bim.activate_drawing_style")
row = layout.row(align=True)
row.operator("bim.save_drawing_style")
row.operator("bim.activate_drawing_style")
class BIM_PT_drawings(Panel):
+4
View File
@@ -237,6 +237,10 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
row.prop(context.scene.DocProperties, "symbols_path")
row = self.layout.row(align=True)
row.prop(context.scene.DocProperties, "patterns_path")
row = self.layout.row(align=True)
row.prop(context.scene.DocProperties, "shadingstyles_path")
row = self.layout.row(align=True)
row.prop(context.scene.DocProperties, "shadingstyle_default")
row = layout.row()
row.operator("bim.configure_visibility")
+7 -4
View File
@@ -104,9 +104,7 @@ def remove_sheet(ifc, drawing, sheet=None):
def rename_sheet(ifc, drawing, sheet=None, identification=None, name=None):
ifc.run(
"document.edit_information", information=sheet, attributes={"Identification": identification, "Name": name}
)
ifc.run("document.edit_information", information=sheet, attributes={"Identification": identification, "Name": name})
for reference in drawing.get_document_references(sheet):
description = drawing.get_reference_description(reference)
if description == "SHEET":
@@ -198,7 +196,9 @@ def add_drawing(ifc, collector, drawing, target_view=None, location_hint=None):
human_scale = "1:100"
else:
scale = "1/96"
human_scale = "1/8\"=1'-0\""
human_scale = '1/8"=1\'-0"'
shading_styles_path = drawing.get_default_drawing_resource_path("ShadingStyles")
ifc.run(
"pset.edit_pset",
pset=pset,
@@ -214,8 +214,11 @@ def add_drawing(ifc, collector, drawing, target_view=None, location_hint=None):
"Markers": drawing.get_default_drawing_resource_path("Markers"),
"Symbols": drawing.get_default_drawing_resource_path("Symbols"),
"Patterns": drawing.get_default_drawing_resource_path("Patterns"),
"ShadingStyles": (shading_styles_path := drawing.get_default_drawing_resource_path("ShadingStyles")),
"CurrentShadingStyle": drawing.get_default_shading_style(),
},
)
drawing.setup_shading_styles_path(shading_styles_path)
information = ifc.run("document.add_information")
uri = drawing.get_default_drawing_path(drawing_name)
reference = ifc.run("document.add_reference", information=information)
+2
View File
@@ -274,6 +274,8 @@ class Drawing:
def get_body_context(cls): pass
def get_default_drawing_path(cls, name): pass
def get_default_drawing_resource_path(cls, resource): pass
def get_default_shading_style(cls): pass
def setup_shading_styles_path(cls, resource_path): pass
def get_default_layout_path(cls, identification, name): pass
def get_default_sheet_path(cls, identification, name): pass
def get_default_sheet_path(cls, identification, name): pass
+10
View File
@@ -115,6 +115,16 @@ class Blender:
tool.Blender.get_viewport_context()["area"].tag_redraw()
@classmethod
def ensure_unique_name(cls, name, objects, iteration=0):
"""returns a unique name for the given name and dictionary of objects
blender style name with .001, .002, etc. suffix
"""
current_iteration = name if not iteration else f"{name}.{iteration:03d}"
if current_iteration not in objects:
return current_iteration
return cls.ensure_unique_name(name, objects, iteration + 1)
@classmethod
def get_default_selection_keypmap(cls):
"""keymap to replicate default blender selection behaviour with click and box selection"""
+26 -7
View File
@@ -877,6 +877,21 @@ class Drawing(blenderbim.core.tool.Drawing):
if resource_path:
return resource_path.replace("\\", "/")
@classmethod
def get_default_shading_style(cls):
dprops = bpy.context.scene.DocProperties
return dprops.shadingstyle_default
@classmethod
def setup_shading_styles_path(cls, resource_path):
resource_path = tool.Ifc.resolve_uri(resource_path)
os.makedirs(os.path.dirname(resource_path), exist_ok=True)
if not os.path.exists(resource_path):
resource_basename = os.path.basename(resource_path)
ootb_resource = os.path.join(bpy.context.scene.BIMProperties.data_dir, "assets", resource_basename)
if os.path.exists(ootb_resource):
shutil.copy(ootb_resource, resource_path)
@classmethod
def get_potential_reference_elements(cls, drawing):
elements = []
@@ -1376,7 +1391,9 @@ class Drawing(blenderbim.core.tool.Drawing):
ifc_file = tool.Ifc.get()
pset = ifcopenshell.util.element.get_psets(drawing).get("EPset_Drawing", {})
include = pset.get("Include", None)
elements = cls.get_elements_in_camera_view(tool.Ifc.get_object(drawing), [tool.Ifc.get_object(e) for e in ifc_file.by_type("IfcSpace")])
elements = cls.get_elements_in_camera_view(
tool.Ifc.get_object(drawing), [tool.Ifc.get_object(e) for e in ifc_file.by_type("IfcSpace")]
)
if include:
elements = set(ifcopenshell.util.selector.Selector.parse(ifc_file, include, elements=elements))
exclude = pset.get("Exclude", None)
@@ -1508,12 +1525,14 @@ class Drawing(blenderbim.core.tool.Drawing):
x = (camera.data.BIMCameraProperties.raster_x / camera.data.BIMCameraProperties.raster_y) * y
camera_inverse_matrix = camera.matrix_world.inverted()
return set([
tool.Ifc.get_entity(o)
for o in objs
if cls.is_in_camera_view(o, camera_inverse_matrix, x, y, camera.data.clip_start, camera.data.clip_end)
and tool.Ifc.get_entity(o)
])
return set(
[
tool.Ifc.get_entity(o)
for o in objs
if cls.is_in_camera_view(o, camera_inverse_matrix, x, y, camera.data.clip_start, camera.data.clip_end)
and tool.Ifc.get_entity(o)
]
)
@classmethod
def is_in_camera_view(cls, obj, camera_inverse_matrix, x, y, clip_start, clip_end):
+5
View File
@@ -264,6 +264,9 @@ class TestAddDrawing:
drawing.get_default_drawing_resource_path("Markers").should_be_called().will_return("markers.svg")
drawing.get_default_drawing_resource_path("Symbols").should_be_called().will_return("symbols.svg")
drawing.get_default_drawing_resource_path("Patterns").should_be_called().will_return("patterns.svg")
drawing.get_default_drawing_resource_path("ShadingStyles").should_be_called().will_return("shading_styles.json")
drawing.get_default_shading_style().should_be_called().will_return("Blender Default")
drawing.setup_shading_styles_path("shading_styles.json").should_be_called()
drawing.get_unit_system().should_be_called().will_return("METRIC")
ifc.run(
"pset.edit_pset",
@@ -280,6 +283,8 @@ class TestAddDrawing:
"Markers": "markers.svg",
"Symbols": "symbols.svg",
"Patterns": "patterns.svg",
"ShadingStyles": "shading_styles.json",
"CurrentShadingStyle": "Blender Default",
},
).should_be_called()
drawing.get_default_drawing_path("name").should_be_called().will_return("uri")