Simulate strokes from pano cli
This commit is contained in:
@@ -98,6 +98,8 @@ Known local toolchain state:
|
|||||||
`pano_cli_inspect_png_metadata_smoke` with a tiny IHDR fixture.
|
`pano_cli_inspect_png_metadata_smoke` with a tiny IHDR fixture.
|
||||||
- `pano_cli create-document` supports `--frames` and `--frame-duration-ms` and
|
- `pano_cli create-document` supports `--frames` and `--frame-duration-ms` and
|
||||||
is covered by `pano_cli_create_animation_document_smoke`.
|
is covered by `pano_cli_create_animation_document_smoke`.
|
||||||
|
- `pano_cli simulate-stroke` exposes the pure stroke sampler for scripted
|
||||||
|
automation and is covered by `pano_cli_simulate_stroke_smoke`.
|
||||||
- `panopainter_validate_shaders` validates the current combined GLSL shader
|
- `panopainter_validate_shaders` validates the current combined GLSL shader
|
||||||
files for one vertex stage marker, one fragment stage marker, valid marker
|
files for one vertex stage marker, one fragment stage marker, valid marker
|
||||||
order, and existing relative includes.
|
order, and existing relative includes.
|
||||||
|
|||||||
@@ -328,9 +328,10 @@ length parsing, color parsing, tinyxml-backed layout XML parsing, and invalid
|
|||||||
input tests.
|
input tests.
|
||||||
`pano_cli inspect-image` exposes PNG IHDR metadata as JSON, and
|
`pano_cli inspect-image` exposes PNG IHDR metadata as JSON, and
|
||||||
`pano_cli create-document` can create simple animation documents with explicit
|
`pano_cli create-document` can create simple animation documents with explicit
|
||||||
frame count/duration. `pano_cli parse-layout` exercises the XML layout path.
|
frame count/duration, and `pano_cli simulate-stroke` exercises the pure stroke
|
||||||
Continue expanding document behavior toward legacy Canvas parity and then port
|
sampler for scripted-stroke automation. `pano_cli parse-layout` exercises the
|
||||||
OpenGL classes behind the renderer boundary.
|
XML layout path. Continue expanding document behavior toward legacy Canvas
|
||||||
|
parity and then port OpenGL classes behind the renderer boundary.
|
||||||
|
|
||||||
Implementation tasks:
|
Implementation tasks:
|
||||||
|
|
||||||
@@ -582,6 +583,8 @@ Results:
|
|||||||
- `pano_cli_inspect_png_metadata_smoke` passed and reports PNG metadata JSON
|
- `pano_cli_inspect_png_metadata_smoke` passed and reports PNG metadata JSON
|
||||||
for the tiny IHDR fixture.
|
for the tiny IHDR fixture.
|
||||||
- `pano_cli_parse_layout_smoke` passed.
|
- `pano_cli_parse_layout_smoke` passed.
|
||||||
|
- `pano_cli_simulate_stroke_smoke` passed and reports deterministic stroke
|
||||||
|
sample counts/distances.
|
||||||
- `panopainter_validate_shaders` passed, validating 25 shader programs and 7
|
- `panopainter_validate_shaders` passed, validating 25 shader programs and 7
|
||||||
shader includes for stage markers and include graph integrity.
|
shader includes for stage markers and include graph integrity.
|
||||||
- PowerShell analyze automation returns JSON summaries and includes the shader
|
- PowerShell analyze automation returns JSON summaries and includes the shader
|
||||||
|
|||||||
@@ -224,4 +224,10 @@ if(TARGET pano_cli)
|
|||||||
COMMAND pano_cli parse-layout --path "${CMAKE_CURRENT_SOURCE_DIR}/data/layouts/simple-layout.xml")
|
COMMAND pano_cli parse-layout --path "${CMAKE_CURRENT_SOURCE_DIR}/data/layouts/simple-layout.xml")
|
||||||
set_tests_properties(pano_cli_parse_layout_smoke PROPERTIES
|
set_tests_properties(pano_cli_parse_layout_smoke PROPERTIES
|
||||||
LABELS "ui;integration;desktop-fast")
|
LABELS "ui;integration;desktop-fast")
|
||||||
|
|
||||||
|
add_test(NAME pano_cli_simulate_stroke_smoke
|
||||||
|
COMMAND pano_cli simulate-stroke --x1 0 --y1 0 --x2 10 --y2 0 --spacing 2)
|
||||||
|
set_tests_properties(pano_cli_simulate_stroke_smoke PROPERTIES
|
||||||
|
LABELS "paint;integration;desktop-fast"
|
||||||
|
PASS_REGULAR_EXPRESSION "\"samples\":6.*\"distance\":10")
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "document/document.h"
|
#include "document/document.h"
|
||||||
#include "foundation/parse.h"
|
#include "foundation/parse.h"
|
||||||
#include "foundation/result.h"
|
#include "foundation/result.h"
|
||||||
|
#include "paint/stroke.h"
|
||||||
#include "ui_core/layout_xml.h"
|
#include "ui_core/layout_xml.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@@ -37,6 +38,14 @@ struct InspectProjectArgs {
|
|||||||
std::string path;
|
std::string path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SimulateStrokeArgs {
|
||||||
|
std::uint32_t x1 = 0;
|
||||||
|
std::uint32_t y1 = 0;
|
||||||
|
std::uint32_t x2 = 0;
|
||||||
|
std::uint32_t y2 = 0;
|
||||||
|
std::uint32_t spacing = 1;
|
||||||
|
};
|
||||||
|
|
||||||
void print_error(std::string_view command, std::string_view message)
|
void print_error(std::string_view command, std::string_view message)
|
||||||
{
|
{
|
||||||
std::cout << "{\"ok\":false,\"command\":\"" << command
|
std::cout << "{\"ok\":false,\"command\":\"" << command
|
||||||
@@ -51,6 +60,7 @@ void print_help()
|
|||||||
<< " inspect-image --path FILE\n"
|
<< " inspect-image --path FILE\n"
|
||||||
<< " inspect-project --path FILE\n"
|
<< " inspect-project --path FILE\n"
|
||||||
<< " parse-layout --path FILE\n"
|
<< " parse-layout --path FILE\n"
|
||||||
|
<< " simulate-stroke --x1 N --y1 N --x2 N --y2 N [--spacing N]\n"
|
||||||
<< " --help\n";
|
<< " --help\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,6 +301,84 @@ int inspect_project(int argc, char** argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pp::foundation::Status parse_simulate_stroke_args(int argc, char** argv, SimulateStrokeArgs& args)
|
||||||
|
{
|
||||||
|
for (int i = 2; i < argc; ++i) {
|
||||||
|
const std::string_view key(argv[i]);
|
||||||
|
if (key == "--x1" || key == "--y1" || key == "--x2" || key == "--y2" || key == "--spacing") {
|
||||||
|
if (i + 1 >= argc) {
|
||||||
|
return pp::foundation::Status::invalid_argument("missing value for option");
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto value = pp::foundation::parse_u32(argv[++i]);
|
||||||
|
if (!value) {
|
||||||
|
return value.status();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == "--x1") {
|
||||||
|
args.x1 = value.value();
|
||||||
|
} else if (key == "--y1") {
|
||||||
|
args.y1 = value.value();
|
||||||
|
} else if (key == "--x2") {
|
||||||
|
args.x2 = value.value();
|
||||||
|
} else if (key == "--y2") {
|
||||||
|
args.y2 = value.value();
|
||||||
|
} else {
|
||||||
|
args.spacing = value.value();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return pp::foundation::Status::invalid_argument("unknown option");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.spacing == 0) {
|
||||||
|
return pp::foundation::Status::invalid_argument("stroke spacing must be greater than zero");
|
||||||
|
}
|
||||||
|
|
||||||
|
return pp::foundation::Status::success();
|
||||||
|
}
|
||||||
|
|
||||||
|
int simulate_stroke(int argc, char** argv)
|
||||||
|
{
|
||||||
|
SimulateStrokeArgs args;
|
||||||
|
const auto status = parse_simulate_stroke_args(argc, argv, args);
|
||||||
|
if (!status.ok()) {
|
||||||
|
print_error("simulate-stroke", status.message);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pp::paint::StrokePoint points[] {
|
||||||
|
pp::paint::StrokePoint {
|
||||||
|
.x = static_cast<float>(args.x1),
|
||||||
|
.y = static_cast<float>(args.y1),
|
||||||
|
.pressure = 1.0F,
|
||||||
|
},
|
||||||
|
pp::paint::StrokePoint {
|
||||||
|
.x = static_cast<float>(args.x2),
|
||||||
|
.y = static_cast<float>(args.y2),
|
||||||
|
.pressure = 1.0F,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const auto samples = pp::paint::sample_stroke(
|
||||||
|
points,
|
||||||
|
pp::paint::StrokeSamplingConfig {
|
||||||
|
.spacing = static_cast<float>(args.spacing),
|
||||||
|
});
|
||||||
|
if (!samples) {
|
||||||
|
print_error("simulate-stroke", samples.status().message);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& first = samples.value().front();
|
||||||
|
const auto& last = samples.value().back();
|
||||||
|
std::cout << "{\"ok\":true,\"command\":\"simulate-stroke\""
|
||||||
|
<< ",\"samples\":" << samples.value().size()
|
||||||
|
<< ",\"first\":{\"x\":" << first.x << ",\"y\":" << first.y << "}"
|
||||||
|
<< ",\"last\":{\"x\":" << last.x << ",\"y\":" << last.y
|
||||||
|
<< ",\"distance\":" << last.distance << "}}\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
pp::foundation::Status parse_layout_args(int argc, char** argv, ParseLayoutArgs& args)
|
pp::foundation::Status parse_layout_args(int argc, char** argv, ParseLayoutArgs& args)
|
||||||
{
|
{
|
||||||
for (int i = 2; i < argc; ++i) {
|
for (int i = 2; i < argc; ++i) {
|
||||||
@@ -372,6 +460,10 @@ int main(int argc, char** argv)
|
|||||||
return inspect_project(argc, argv);
|
return inspect_project(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (command == "simulate-stroke") {
|
||||||
|
return simulate_stroke(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
if (command == "parse-layout") {
|
if (command == "parse-layout") {
|
||||||
return parse_layout(argc, argv);
|
return parse_layout(argc, argv);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user