mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-06 10:47:27 +00:00
Review fix from #6087. Bounds::of and Camera::fit_meshes framed every finite triangle, but render skips those whose colour has zero alpha, so a clear, distant mesh could shrink the visible model in the image. The vertices they frame now skip fully transparent triangles, as render does. Test, shown failing with the fix reverted: a_fully_transparent_triangle_does_not_widen_the_box_or_the_fit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SqmHYx8FiWM5PcsoiErgp9
pdfcraft-prc-render
A headless CPU renderer for PRC 3D models read by pdfcraft-prc: placed meshes in world space, a fitted camera, a
depth-buffered triangle fill and headlight shading, into a straight-RGBA image.
- Layer: L3. Depends on
pdfcraft-prconly. - Licence: MIT OR Apache-2.0.
#![forbid(unsafe_code)]. Never panics on input: image size, triangle count and every index are checked, and damage returnsRenderError.
API
assemble(&PrcFile) -> Result<Vec<WorldMesh>, RenderError> // every placement's mesh moved into the world and coloured
place(&TriangleMesh, &Matrix, colour, triangle_colours) -> WorldMesh
Camera::fit(&Bounds, direction, up, perspective, aspect) / Camera::fit_meshes(&[WorldMesh], ...)
render(&[WorldMesh], &Camera, &RenderOptions) -> Result<Image, RenderError>
- With no product tree, each tessellated mesh is drawn where it lies, in the default colour.
- A triangle's own colour wins over its mesh's, which wins over
RenderOptions::colour. - Opaque triangles are drawn first, then translucent ones blended over them; alpha 0 is not drawn.
Lighting::Headlight(default) shades by the angle to the view direction;Lighting::Unlitdraws flat colour.- Perspective triangles are clipped at a near plane 1/10,000 of the eye-to-target distance from the eye; orthographic views are not clipped.
MAX_RENDER_PIXELS(2^24, about 16 MP) bounds the image: at most 64 MB of RGBA plus 128 MB of depth.MAX_ASSEMBLED_TRIANGLESandMAX_ASSEMBLED_VERTICES(2^24 each) bound oneassemblecall.MAX_RENDER_WORK(2^31) bounds the pixel centres onerendertests, summed over each triangle's clipped bounding box; past it the render returnsRenderError::TooMuchWork. That is still seconds of CPU at the top, so callers on a UI thread should render small or off-thread.- Not yet: shadows, ambient occlusion, specular light, scene lights, textures, wires and markups.