Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render a cross section from the Curvewise measured body format #74

Draft
wants to merge 16 commits into
base: main
Choose a base branch
from
Draft
68 changes: 66 additions & 2 deletions hobart_svg/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def horizontal_xs(mesh_path, heights, out, reference):
from .core import render_longest_xsection_to_svg

if reference and not reference.endswith(".dae"):
raise ValueError("reference-mesh should end with .dae")
raise ValueError("reference path should end with .dae")

mesh = lacecore.load_obj(mesh_path, triangulate=True)

Expand All @@ -45,7 +45,7 @@ def horizontal_xs(mesh_path, heights, out, reference):
for height in heights:
if out is None:
filename, extension = os.path.splitext(os.path.basename(mesh_path))
out_path = "{}_cross_section_at_{}.svg".format(filename, height)
out_path = f"{filename}_cross_section_at_{height}.svg"

plane = Plane(
reference_point=np.array([0.0, height, 0.0]), normal=vg.basis.neg_y
Expand All @@ -61,5 +61,69 @@ def horizontal_xs(mesh_path, heights, out, reference):
Scene().add_meshes(mesh).add_lines(*reference_lines).write(reference)


@cli.command()
@click.argument("measured_body_json_path")
@click.option(
"--up",
type=click.Choice(["x", "y", "z", "neg_z", "neg_y", "neg_z"]),
help="Up vector",
)
@click.option("--flip", is_flag=True, help="Flip the output relative to the plane")
@click.option("-o", "--out", help="Output path")
@click.option("--stroke-color", default="purple", help="Stroke color")
@click.option("--fill-color", default="none", help="Fill color")
def measured_body(measured_body_json_path, out, up, flip, fill_color, stroke_color):
"""
Find the horizontal cross section at the given height and write it to an
SVG file. Optionally write a COLLADA reference with the mesh and cross
section.
"""
import os
from missouri import json
import numpy as np
from polliwog import Plane, Polyline
import vg
from hobart_svg.svg import write_polyline_3d

measured_body = json.load(measured_body_json_path)

num_items = len(measured_body["curves"])

for measurement_name, curve_data in measured_body["curves"].items():
curve = Polyline.deserialize(
{"vertices": curve_data["vertices"], "isClosed": curve_data["is_closed"]}
)

plane = Plane.fit_from_points(curve.v)

# Given a pair of these on different meshes, try to produce consistent
# normals.
plane = plane.flipped_if(
not np.array_equal(
vg.aligned_with(plane.normal, np.array([1, 1, 1])), plane.normal
)
)

if flip:
plane = plane.flipped()

if out is None:
filename, extension = os.path.splitext(
os.path.basename(measured_body_json_path)
)
if num_items == 1:
out = f"{filename}.svg"
else:
out = f"{filename}_{measurement_name}.svg"

write_polyline_3d(
polyline=curve,
filename=out,
look=plane.normal,
up=None if up is None else getattr(vg.basis, up),
polyline_format_attrs={"stroke": stroke_color, "fill": fill_color},
)


if __name__ == "__main__":
cli()
Loading