Simulate strokes from pano cli

This commit is contained in:
2026-06-01 09:12:55 +02:00
parent d0ef88be89
commit dc252b2f24
4 changed files with 106 additions and 3 deletions

View File

@@ -4,6 +4,7 @@
#include "document/document.h"
#include "foundation/parse.h"
#include "foundation/result.h"
#include "paint/stroke.h"
#include "ui_core/layout_xml.h"
#include <cstdint>
@@ -37,6 +38,14 @@ struct InspectProjectArgs {
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)
{
std::cout << "{\"ok\":false,\"command\":\"" << command
@@ -51,6 +60,7 @@ void print_help()
<< " inspect-image --path FILE\n"
<< " inspect-project --path FILE\n"
<< " parse-layout --path FILE\n"
<< " simulate-stroke --x1 N --y1 N --x2 N --y2 N [--spacing N]\n"
<< " --help\n";
}
@@ -291,6 +301,84 @@ int inspect_project(int argc, char** argv)
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)
{
for (int i = 2; i < argc; ++i) {
@@ -372,6 +460,10 @@ int main(int argc, char** argv)
return inspect_project(argc, argv);
}
if (command == "simulate-stroke") {
return simulate_stroke(argc, argv);
}
if (command == "parse-layout") {
return parse_layout(argc, argv);
}