@@ -81,6 +81,8 @@ namespace scm_reflow_authoring_detail {
8181
8282inline 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