增加笔画生产尺寸与数量报告

按最终矢量页面汇总每个相机单元的笔画包络,并标出低于 0.2 mm 的数量。
已核对 SVG、清单哈希和 Blender 导出,175 项相关测试通过。
This commit is contained in:
ykcheungab
2026-10-06 14:17:13 +08:00
parent afe1ce39cb
commit ccf0f5f940
11 changed files with 34026 additions and 19 deletions
+28 -9
View File
@@ -24,12 +24,14 @@ from random_patch_dd02c import (
_prepare_mesh_object,
_require_object,
_require_uv_layer,
clip_polygon_to_page,
fill_background,
fill_polygon,
save_png_image,
write_pdf_vector,
write_svg_vector,
)
from stroke_production_report import summarize_view, write_report
MODE = "camera_grid_capsules"
DEFAULT_PARAMS = {
@@ -64,8 +66,8 @@ def _pixel_polygon(uv_polygon, width, height):
def render_stroke_polygons(uv_name, mesh, strokes, width, height, vector,
base):
"""Write the shared raster and vector artwork from UV polygons."""
base, view_id=None):
"""Write artwork and measure the same page-clipped vector polygons."""
image_name = f"CameraGridStroke_{uv_name}"
if image_name in bpy.data.images:
bpy.data.images.remove(bpy.data.images[image_name])
@@ -79,11 +81,13 @@ def render_stroke_polygons(uv_name, mesh, strokes, width, height, vector,
fill_polygon(None, pixels, width, height, poly, (1, 1, 1, 1))
shapes = []
for polygon in strokes:
labelled_shapes = []
for i, j, polygon in strokes:
pixel_poly = _pixel_polygon(polygon, width, height)
if len(pixel_poly) < 3:
continue
shapes.append((pixel_poly, (0, 0, 0, 1)))
labelled_shapes.append((i, j, pixel_poly))
fill_polygon(None, pixels, width, height, pixel_poly, (0, 0, 0, 1))
image.pixels[:] = pixels
@@ -99,6 +103,16 @@ def render_stroke_polygons(uv_name, mesh, strokes, width, height, vector,
page_mesh, page_shapes, [], (0, 0, 0, 1),
artwork_label="stroke")
print(f"{uv_name}: {len(shapes)} projected stroke fragments")
report_shapes = [
(i, j, [(round(x, 4), round(y, 4)) for x, y in clipped])
for i, j, polygon in labelled_shapes
if (clipped := clip_polygon_to_page(polygon, width, height))
]
return summarize_view(
view_id or uv_name, uv_name, report_shapes, page_mesh,
(width, height), (vector["width_mm"], vector["height_mm"]),
base.with_suffix(".svg"),
)
def _render(uv_name, geometry, settings, output_dir, width_ratio, length_ratio,
@@ -113,13 +127,14 @@ def _render(uv_name, geometry, settings, output_dir, width_ratio, length_ratio,
outline_cache[key] = capsule_in_cell(
i, j, nx, ny, seed, width_ratio, length_ratio,
angle=None if angle_map is None else float(angle_map[j, i]))
strokes.append(projected_stroke_uv(fragment, loop_uvs, outline_cache[key]))
strokes.append((i, j, projected_stroke_uv(fragment, loop_uvs, outline_cache[key])))
label = artifact_prefix
if angle_map is not None and artifact_prefix == "camera_grid_stroke":
label += "_optimized"
base = output_dir / f"{label}_{uv_name}"
render_stroke_polygons(uv_name, geometry["mesh"], strokes,
settings["width"], settings["height"], settings["vector"], base)
return render_stroke_polygons(uv_name, geometry["mesh"], strokes,
settings["width"], settings["height"], settings["vector"],
base)
def main():
@@ -164,10 +179,14 @@ def main():
names, settings["nx"], settings["ny"], settings["edge_sample_grid"],
capture_camera_fragments=True,
)
views = []
for name in names:
_render(name, geometry[name], settings, args.output_dir,
params["width_ratio"], params["length_ratio"], angle_map,
args.artifact_prefix)
views.append(_render(name, geometry[name], settings, args.output_dir,
params["width_ratio"], params["length_ratio"], angle_map,
args.artifact_prefix))
report_path = args.output_dir / f"{args.artifact_prefix}_production_report.json"
write_report(report_path, args.job.resolve(), params, views)
print(f"Stroke production report: {report_path}")
if __name__ == "__main__":