diff --git a/src/modules/sbstudio/api/base.py b/src/modules/sbstudio/api/base.py index 0cc083d8..768c657a 100644 --- a/src/modules/sbstudio/api/base.py +++ b/src/modules/sbstudio/api/base.py @@ -389,6 +389,7 @@ def create_formation_from_svg( num_points: int, size: float, angle: float, + center: Point3D, ) -> Tuple[List[Point3D], List[Color3D]]: """Samples the path objects of an SVG string into a list of coordinates and corresponding colors. @@ -398,6 +399,7 @@ def create_formation_from_svg( n: the number of points to generate size: the maximum extent of the returned points along the main axes angle: the mimimum angle change at path nodes to treat them as corners + center: the center of the created formation Returns: the list of evenly sampled points and corresponding colors @@ -412,6 +414,7 @@ def create_formation_from_svg( "n": num_points, "size": size, "angle": angle, + "center": center.as_json(), }, } diff --git a/src/modules/sbstudio/model/point.py b/src/modules/sbstudio/model/point.py index c9f54d24..f9123047 100644 --- a/src/modules/sbstudio/model/point.py +++ b/src/modules/sbstudio/model/point.py @@ -33,6 +33,10 @@ def as_vector(self) -> Vector: """Converts a Point3D instance to a Blender vector.""" return Vector((self.x, self.y, self.z)) + def as_json(self) -> list[float]: + """Converts a Point3D instance to a JSON serializable format.""" + return [round(value, ndigits=3) for value in [self.x, self.y, self.z]] + @dataclass class Point4D: diff --git a/src/modules/sbstudio/plugin/operators/add_markers_from_svg.py b/src/modules/sbstudio/plugin/operators/add_markers_from_svg.py index 72c5a972..b810dbc9 100644 --- a/src/modules/sbstudio/plugin/operators/add_markers_from_svg.py +++ b/src/modules/sbstudio/plugin/operators/add_markers_from_svg.py @@ -8,6 +8,7 @@ from bpy.props import BoolProperty, FloatProperty, IntProperty, StringProperty from bpy_extras.io_utils import ImportHelper +from sbstudio.model.point import Point3D from sbstudio.plugin.api import call_api_from_blender_operator from .base import StaticMarkerCreationOperator, PointsAndColors @@ -82,13 +83,14 @@ def _create_points(self, context) -> PointsAndColors: num_points=self.count, size=self.size, angle=degrees(self.angle), + center=Point3D(*context.scene.cursor.location), api=api, ) return PointsAndColors(points, colors) def parse_svg( - filename: str, *, num_points: int, size: float, angle: float, api + filename: str, *, num_points: int, size: float, angle: float, center: Point3D, api ) -> Tuple[NDArray[float], NDArray[float]]: """Parse an .svg file (containing a list of static positions and colors) using the backend API @@ -98,6 +100,7 @@ def parse_svg( num_points: the number of points to generate size: the maximum extent of the points along the main axes angle: maximum angle change at nodes to treat the path continuous around them, in degrees + center: the center of the created formation api: the Skybrush Studio API object Returns: @@ -109,7 +112,7 @@ def parse_svg( source = Path(filename).read_text() points, colors = api.create_formation_from_svg( - source=source, num_points=num_points, size=size, angle=angle + source=source, num_points=num_points, size=size, angle=angle, center=center ) # rotate from XY to ZY plane