Sketch on a cylinder primitive's caps; format 15 (#460)

* Sketch on a cylinder primitive's caps (#420)

A solid.cylinder's caps carried no construction certificate, so a sketch
on its top or bottom was refused unless fixed:true (#420's crossed
cylinders, built from primitives).

- kernel: FaceSource::CylinderCap { producer, high, plane };
  Body::with_cylinder_certificate turns a cylinder's two extrude caps into
  certified caps. kernel::cylinder's output is unchanged for its other
  callers.
- doc: FaceCertificate::CylinderCap { high }, named F<id>:top / F<id>:bottom
  as the cylinder's face names already are; New Body and Join cylinders
  are certified, shells carry it as their planar source.
- format 15: designs can store the new certificate kind; version 14
  designs need no change, and older builds ask for an update instead of
  meeting an unknown kind.

Tests: top and bottom attachments follow a height and base edit and a
reopen; crossed joined cylinders keep both caps attachable; a shelled
cylinder's floor keeps its cap identity; malformed certificate JSON is
refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YDDPmNdRoBgkHcLeUDKVfb

* Format 15 also covers sketch_axis links (#448)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YDDPmNdRoBgkHcLeUDKVfb

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Irakli KourtisandClaude Opus 5.5 authored and GitHub committed 2026-10-12 21:32:07 -04:00
1 parent b24e478bc1
commit 49956c2797
10 files changed
+247 -23

No files matched your search

+7 -2
View File
@@ -46,13 +46,17 @@
//! legacy mark (`?F2:top#2`) and are found again as the build that saved them found them.
//! Pieces a feature splits a body into are named after their faces; features saved before
//! keep the kernel's shell order (`shell_piece_order`), which their stored body names mean.
//! - 15: sketch face anchors and face bindings can name a cylinder primitive's cap
//! (`cylinder_cap`), and sketches can link lines to their own axes (`sketch_axis`). Version 14
//! designs need no transformation; the version stamp lets older readers request an update
//! instead of encountering an unknown certificate or link kind.
use serde_json::Value;
use crate::{DocError, Document, Result};
/// The format this build writes.
pub const FORMAT: u32 = 14;
pub const FORMAT: u32 = 15;
pub fn format_string(n: u32) -> String {
format!("solidcraft/{n}")
@@ -69,7 +73,7 @@ pub fn version_of(s: &str) -> Option<u32> {
/// JSON-level upgrades: entry `i` turns format `i + 1` into `i + 2`.
type JsonStep = fn(&mut Value) -> Result<()>;
const JSON_STEPS: [JsonStep; 13] = [
const JSON_STEPS: [JsonStep; 14] = [
|_| Ok(()),
v2_to_v3,
v3_to_v4,
@@ -83,6 +87,7 @@ const JSON_STEPS: [JsonStep; 13] = [
|_| Ok(()),
|_| Ok(()),
v13_to_v14,
|_| Ok(()),
];
/// Stored face and edge names were worked out from geometry before format 14; they get the