Skip to content

Commit 4ddf98e

Browse files
committed
cli: add SCM size-growth preflight
1 parent e16a6c9 commit 4ddf98e

1 file changed

Lines changed: 77 additions & 12 deletions

File tree

‎src/cli/scm_reflow_authoring_commands.hpp‎

Lines changed: 77 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ namespace scm_reflow_authoring_detail {
8181

8282
inline void print_scm_reflow_authoring_help() {
8383
std::cout
84+
<< " scm-find-size-growth-target <input.scm>\n"
85+
<< " Find the first append-break target whose canonical layout is guaranteed to grow\n"
8486
<< " scm-append-break-vertex-copy <input.scm> <object-index> <mesh-index> <source-vertex-index> <output.scm>\n"
8587
<< " Evidence-oriented size-changing canonical rebuild: copy one vertex and append topology break 0x02\n";
8688
}
@@ -90,6 +92,55 @@ inline int try_run_scm_reflow_authoring_command(int argc, char** argv) {
9092

9193
if (argc <= 1) return -1;
9294
const std::string_view command{argv[1]};
95+
96+
if (command == "scm-find-size-growth-target") {
97+
if (argc != 3) {
98+
std::cerr
99+
<< "usage: scm-find-size-growth-target <input.scm>\n";
100+
return 1;
101+
}
102+
103+
const std::filesystem::path input{argv[2]};
104+
std::vector<std::byte> source;
105+
if (!scm_reflow_authoring_detail::read_file(input, source)) {
106+
std::cerr << "scm-find-size-growth-target: cannot read input\n";
107+
return 2;
108+
}
109+
110+
const auto parsed = Parser::parse(std::span<const std::byte>{source});
111+
if (!parsed.ok()) {
112+
std::cerr
113+
<< "scm-find-size-growth-target: canonical parse failed\n";
114+
return 3;
115+
}
116+
117+
const auto plan =
118+
find_append_break_vertex_growth_target(parsed.document);
119+
if (!plan.valid || !plan.grows()) {
120+
std::cerr
121+
<< "scm-find-size-growth-target: no canonical growth target found\n";
122+
return 4;
123+
}
124+
if (plan.source_file_size != source.size()) {
125+
std::cerr
126+
<< "scm-find-size-growth-target: source physical size does not match canonical layout\n";
127+
return 5;
128+
}
129+
130+
std::cout
131+
<< "SCM_SIZE_GROWTH_TARGET_FOUND\n"
132+
<< "object=" << plan.object_index << '\n'
133+
<< "mesh=" << plan.mesh_index << '\n'
134+
<< "sourceVertex=" << plan.source_vertex_index << '\n'
135+
<< "sourceVertices=" << plan.source_vertex_count << '\n'
136+
<< "sourceSize=" << source.size() << '\n'
137+
<< "sourceCanonicalSize=" << plan.source_file_size << '\n'
138+
<< "outputCanonicalSize=" << plan.output_file_size << '\n'
139+
<< "sizeDelta=" << plan.size_delta() << '\n'
140+
<< "sourceLayoutMatch=PASS\n";
141+
return 0;
142+
}
143+
93144
if (command != "scm-append-break-vertex-copy") return -1;
94145

95146
if (argc != 7) {
@@ -153,19 +204,31 @@ inline int try_run_scm_reflow_authoring_command(int argc, char** argv) {
153204
const auto copied_uv = source_mesh.uvs[source_vertex_index];
154205
const auto copied_color = source_mesh.colors_topology[source_vertex_index];
155206

207+
const auto layout_plan = plan_append_break_vertex_copy_layout(
208+
parsed.document,
209+
object_index,
210+
mesh_index,
211+
source_vertex_index);
212+
if (!layout_plan.valid || !layout_plan.grows() ||
213+
layout_plan.source_file_size != source.size()) {
214+
std::cerr
215+
<< "scm-append-break-vertex-copy: selected target is not guaranteed to grow canonical physical size\n";
216+
return 7;
217+
}
218+
156219
auto document = parsed.document;
157220
const auto edit = append_break_vertex_copy(
158221
document, object_index, mesh_index, source_vertex_index);
159222
if (!edit.ok() || !edit.changed) {
160223
std::cerr << "scm-append-break-vertex-copy: typed structural edit rejected\n";
161-
return 7;
224+
return 8;
162225
}
163226

164227
const auto preserve = Writer::write(document, WriteMode::preserve_layout);
165228
if (preserve.ok()) {
166229
std::cerr
167230
<< "scm-append-break-vertex-copy: preserve-layout unexpectedly accepted size-changing edit\n";
168-
return 8;
231+
return 9;
169232
}
170233

171234
const auto written = Writer::write(document, WriteMode::canonical_rebuild);
@@ -176,12 +239,13 @@ inline int try_run_scm_reflow_authoring_command(int argc, char** argv) {
176239
std::cerr << " " << diagnostic.code << ": "
177240
<< diagnostic.message << '\n';
178241
}
179-
return 9;
242+
return 10;
180243
}
181-
if (written.bytes.size() <= source.size()) {
244+
if (written.bytes.size() != layout_plan.output_file_size ||
245+
written.bytes.size() <= source.size()) {
182246
std::cerr
183-
<< "scm-append-break-vertex-copy: output did not grow\n";
184-
return 10;
247+
<< "scm-append-break-vertex-copy: writer size does not match canonical growth plan\n";
248+
return 11;
185249
}
186250

187251
const auto reparsed = Parser::parse(
@@ -190,7 +254,7 @@ inline int try_run_scm_reflow_authoring_command(int argc, char** argv) {
190254
mesh_index >= reparsed.document.objects[object_index].meshes.size()) {
191255
std::cerr
192256
<< "scm-append-break-vertex-copy: rebuilt output reparse failed\n";
193-
return 11;
257+
return 12;
194258
}
195259

196260
const auto& output_object = reparsed.document.objects[object_index];
@@ -200,7 +264,7 @@ inline int try_run_scm_reflow_authoring_command(int argc, char** argv) {
200264
output_mesh.vertex_count != source_vertex_count + 1U) {
201265
std::cerr
202266
<< "scm-append-break-vertex-copy: derived vertex counts mismatch\n";
203-
return 12;
267+
return 13;
204268
}
205269

206270
const auto& appended_position = output_mesh.positions.back();
@@ -220,7 +284,7 @@ inline int try_run_scm_reflow_authoring_command(int argc, char** argv) {
220284
appended_color.topology_flags != triangle_break_bit) {
221285
std::cerr
222286
<< "scm-append-break-vertex-copy: appended vertex reparse mismatch\n";
223-
return 13;
287+
return 14;
224288
}
225289

226290
const auto output_topology =
@@ -231,7 +295,7 @@ inline int try_run_scm_reflow_authoring_command(int argc, char** argv) {
231295
if (output_triangle_count != source_triangle_count) {
232296
std::cerr
233297
<< "scm-append-break-vertex-copy: structural growth changed non-degenerate triangle count\n";
234-
return 14;
298+
return 15;
235299
}
236300

237301
const auto validator = [&](const std::filesystem::path& staged_path) {
@@ -265,7 +329,7 @@ inline int try_run_scm_reflow_authoring_command(int argc, char** argv) {
265329
std::cerr
266330
<< "scm-append-break-vertex-copy: publication failed: "
267331
<< to_string(publication.status) << '\n';
268-
return 15;
332+
return 16;
269333
}
270334

271335
std::cout
@@ -279,10 +343,11 @@ inline int try_run_scm_reflow_authoring_command(int argc, char** argv) {
279343
<< "outputObjectVertices=" << output_object.total_vertex_count << '\n'
280344
<< "sourceSize=" << source.size() << '\n'
281345
<< "outputSize=" << written.bytes.size() << '\n'
282-
<< "sizeDelta=" << (written.bytes.size() - source.size()) << '\n'
346+
<< "sizeDelta=" << layout_plan.size_delta() << '\n'
283347
<< "trianglesBefore=" << source_triangle_count << '\n'
284348
<< "trianglesAfter=" << output_triangle_count << '\n'
285349
<< "appendedTopology=2\n"
350+
<< "layoutPreflight=PASS\n"
286351
<< "reparse=PASS\n"
287352
<< "publication=NO_REPLACE_PASS\n";
288353
return 0;

0 commit comments

Comments
 (0)