SvgWriter - make required arguments more explicit

This commit is contained in:
Andrej730
2025-05-16 18:14:58 +05:00
parent 68d967c2e5
commit 7941d71feb
3 changed files with 36 additions and 19 deletions
@@ -313,16 +313,15 @@ class CreateDrawing(bpy.types.Operator):
# Reassign props as data is recreated during the update. # Reassign props as data is recreated during the update.
self.cprops = tool.Drawing.get_camera_props(self.camera) self.cprops = tool.Drawing.get_camera_props(self.camera)
self.svg_writer = svgwriter.SvgWriter() camera_dims = self.get_camera_dimensions()
self.svg_writer.human_scale = self.human_scale self.svg_writer = svgwriter.SvgWriter(
self.svg_writer.scale = self.scale camera_width=camera_dims[0],
self.svg_writer.camera = self.camera camera_height=camera_dims[1],
self.svg_writer.camera_width, self.svg_writer.camera_height = self.get_camera_dimensions() camera=self.camera,
self.svg_writer.camera_projection = tuple( camera_projection=(self.camera.matrix_world.to_quaternion() @ Vector((0, 0, -1))),
self.camera.matrix_world.to_quaternion() @ Vector((0, 0, -1)) scale=self.scale,
human_scale=self.human_scale,
) )
self.svg_writer.calculate_scale()
self.svg_writer.setup_drawing_resource_paths(self.camera_element) self.svg_writer.setup_drawing_resource_paths(self.camera_element)
underlay_svg = None underlay_svg = None
@@ -358,8 +357,10 @@ class CreateDrawing(bpy.types.Operator):
bpy.ops.bim.activate_drawing(drawing=original_drawing_id, should_view_from_camera=False) bpy.ops.bim.activate_drawing(drawing=original_drawing_id, should_view_from_camera=False)
return {"FINISHED"} return {"FINISHED"}
def get_camera_dimensions(self): def get_camera_dimensions(self) -> tuple[float, float]:
assert bpy.context.scene
render = bpy.context.scene.render render = bpy.context.scene.render
assert isinstance(self.camera.data, bpy.types.Camera)
if self.is_landscape(render): if self.is_landscape(render):
width = self.camera.data.ortho_scale width = self.camera.data.ortho_scale
height = width / render.resolution_x * render.resolution_y height = width / render.resolution_x * render.resolution_y
@@ -61,15 +61,28 @@ class External(svgwrite.container.Group):
class SvgWriter: class SvgWriter:
metadata: list[str] metadata: list[str]
resource_paths: dict[tool.Drawing.ResourceType, Union[str, None]]
def __init__(self): def __init__(
self,
*,
camera_width: float,
camera_height: float,
camera: bpy.types.Object,
camera_projection: Vector,
scale: float = 1 / 100, # 1:100
human_scale: str = "NTS",
):
self.data_dir = None self.data_dir = None
self.human_scale = "NTS" self.human_scale = human_scale
self.metadata = [] self.metadata = []
self.scale = 1 / 100 # 1:100 self.scale = scale
self.camera_width = None self.camera = camera
self.camera_height = None self.camera_width = camera_width
self.camera_height = camera_height
self.camera_projection = camera_projection
self.resource_paths = {} self.resource_paths = {}
self.calculate_scale()
def create_blank_svg(self, output_path: str) -> Self: def create_blank_svg(self, output_path: str) -> Self:
self.calculate_scale() self.calculate_scale()
@@ -93,7 +106,7 @@ class SvgWriter:
def setup_drawing_resource_paths(self, element: ifcopenshell.entity_instance) -> None: def setup_drawing_resource_paths(self, element: ifcopenshell.entity_instance) -> None:
pset = ifcopenshell.util.element.get_pset(element, "EPset_Drawing") pset = ifcopenshell.util.element.get_pset(element, "EPset_Drawing")
for resource in ("Stylesheet", "Markers", "Symbols", "Patterns", "ShadingStyles"): for resource in tool.Drawing.RESOURCE_TYPES:
resource_path = pset.get(resource) resource_path = pset.get(resource)
if not resource_path: if not resource_path:
self.resource_paths[resource] = None self.resource_paths[resource] = None
@@ -1085,7 +1098,7 @@ class SvgWriter:
# When rewriting to use polylines, we should use this normal instead. # When rewriting to use polylines, we should use this normal instead.
# center = tool.Cad.get_center_of_arc([p.to_3d() for p in arc_points], None).to_2d() # center = tool.Cad.get_center_of_arc([p.to_3d() for p in arc_points], None).to_2d()
# normal = mathutils.geometry.normal([arc_end_pts[0], arc_end_pts[1], center]) # normal = mathutils.geometry.normal([arc_end_pts[0], arc_end_pts[1], center])
# normal = Vector(self.camera_projection) # normal = self.camera_projection
# dir1 = (arc_end_pts[0] - center).normalized() # dir1 = (arc_end_pts[0] - center).normalized()
# arc_mid_dir = (arc_end_pts[1] - center).normalized() # arc_mid_dir = (arc_end_pts[1] - center).normalized()
@@ -1462,9 +1475,9 @@ class SvgWriter:
# TODO is this needlessly complex? # TODO is this needlessly complex?
return self.camera.matrix_world.inverted() @ geometry.intersect_line_plane( return self.camera.matrix_world.inverted() @ geometry.intersect_line_plane(
point.xyz, point.xyz,
point.xyz - Vector(self.camera_projection), point.xyz - self.camera_projection,
self.camera.location, self.camera.location,
Vector(self.camera_projection), self.camera_projection,
) )
def get_spline_points(self, spline: bpy.types.Spline) -> Union[SplineBezierPoints, SplinePoints]: def get_spline_points(self, spline: bpy.types.Spline) -> Union[SplineBezierPoints, SplinePoints]:
+3
View File
@@ -1285,6 +1285,9 @@ class Drawing(bonsai.core.tool.Drawing):
def sanitise_filename(cls, name: str) -> str: def sanitise_filename(cls, name: str) -> str:
return "".join(x for x in name if (x.isalnum() or x in "._- ")) return "".join(x for x in name if (x.isalnum() or x in "._- "))
ResourceType = Literal["Stylesheet", "Markers", "Symbols", "Patterns", "ShadingStyles"]
RESOURCE_TYPES = ("Stylesheet", "Markers", "Symbols", "Patterns", "ShadingStyles")
@classmethod @classmethod
def get_default_drawing_resource_path(cls, resource: str) -> Union[str, None]: def get_default_drawing_resource_path(cls, resource: str) -> Union[str, None]:
project = tool.Ifc.get().by_type("IfcProject")[0] project = tool.Ifc.get().by_type("IfcProject")[0]