107 lines
4.7 KiB
C++
107 lines
4.7 KiB
C++
#include "procgen/editing/MeshModifierGraph.h"
|
|
|
|
#include "editing/EditingGraph.h"
|
|
#include "zeroerr/unittest.h"
|
|
|
|
#include <cmath>
|
|
|
|
using namespace eve::editing;
|
|
using namespace eve::procgen_editing;
|
|
|
|
namespace {
|
|
|
|
eve::procgen::MeshBuild triangle() {
|
|
eve::procgen::MeshBuild mesh;
|
|
mesh.addVertex(0.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f);
|
|
mesh.addVertex(1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f);
|
|
mesh.addVertex(0.f, 1.f, 0.f, 0.f, 0.f, 1.f, 0.f, 1.f);
|
|
mesh.addTriangle(0, 1, 2);
|
|
return mesh;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
TEST_CASE("editor.meshModifierGraph.reflectsCompilesAndPreviewsFusedGraph") {
|
|
MeshModifierGraphDomain domain;
|
|
auto input = domain.makeNode(GraphNodeId("input"), "mesh.input");
|
|
auto move = domain.makeNode(GraphNodeId("move"), "deform.transform");
|
|
auto twist = domain.makeNode(GraphNodeId("twist"), "deform.twist");
|
|
auto output = domain.makeNode(GraphNodeId("output"), "mesh.output");
|
|
REQUIRE(input.ok());
|
|
REQUIRE(move.ok());
|
|
REQUIRE(twist.ok());
|
|
REQUIRE(output.ok());
|
|
auto* moveProperties = move.value().properties.getIf<EditorValue::Object>();
|
|
REQUIRE(moveProperties != nullptr);
|
|
(*moveProperties)["x"] = EditorValue(3.0);
|
|
|
|
GraphDocument document;
|
|
CHECK(document.createNode(input.value()).ok());
|
|
CHECK(document.createNode(move.value()).ok());
|
|
CHECK(document.createNode(twist.value()).ok());
|
|
CHECK(document.createNode(output.value()).ok());
|
|
const auto connect = [&](const char* edge, const char* from, const char* to) {
|
|
const auto* source = document.findPin(GraphPinId(from));
|
|
const auto* target = document.findPin(GraphPinId(to));
|
|
REQUIRE(source != nullptr);
|
|
REQUIRE(target != nullptr);
|
|
CHECK(document.connect({StableId(edge), source->id, target->id}, domain.canConnect(*source, *target)).ok());
|
|
};
|
|
connect("e0", "input.out", "move.in0");
|
|
connect("e1", "move.out", "twist.in0");
|
|
connect("e2", "twist.out", "output.in0");
|
|
const auto snapshot = document.snapshot(domain.domain());
|
|
const auto compiled = domain.compile(snapshot);
|
|
CHECK_EQ(static_cast<int>(compiled.status), static_cast<int>(EditorStatus::Applied));
|
|
|
|
const auto preview = domain.preview(snapshot, "input", triangle(), "output");
|
|
CHECK_EQ(static_cast<int>(preview.status), static_cast<int>(EditorStatus::Applied));
|
|
CHECK_EQ(preview.mesh.getVertexCount(), 3);
|
|
CHECK(std::abs(preview.mesh.getPositionX(0) - 3.f) < 1e-6f);
|
|
CHECK_EQ(preview.fusedOperationCount, 2);
|
|
}
|
|
|
|
TEST_CASE("editor.meshModifierGraph.rejectsWrongDomainAndPinTypes") {
|
|
MeshModifierGraphDomain domain;
|
|
GraphDocumentData wrong;
|
|
wrong.domain = "procgen.point";
|
|
const auto compiled = domain.compile(wrong);
|
|
CHECK_EQ(static_cast<int>(compiled.status), static_cast<int>(EditorStatus::Rejected));
|
|
|
|
GraphPinRecord scalar{GraphPinId("scalar"), GraphNodeId("a"), "float", GraphPinDirection::Output};
|
|
GraphPinRecord mesh{GraphPinId("mesh"), GraphNodeId("b"), "mesh", GraphPinDirection::Input};
|
|
const auto decision = domain.canConnect(scalar, mesh);
|
|
CHECK(!decision.allowed);
|
|
CHECK(!decision.diagnostics.empty());
|
|
}
|
|
|
|
TEST_CASE("editor.meshModifierGraph.compileRejectsDisconnectedInputsAndCycles") {
|
|
MeshModifierGraphDomain domain;
|
|
GraphDocument disconnected;
|
|
auto output = domain.makeNode(GraphNodeId("output"), "mesh.output");
|
|
REQUIRE(output.ok());
|
|
CHECK(disconnected.createNode(output.value()).ok());
|
|
auto compiled = domain.compile(disconnected.snapshot(domain.domain()));
|
|
CHECK_EQ(static_cast<int>(compiled.status), static_cast<int>(EditorStatus::Rejected));
|
|
|
|
GraphDocument cyclic;
|
|
auto a = domain.makeNode(GraphNodeId("a"), "deform.bend");
|
|
auto b = domain.makeNode(GraphNodeId("b"), "deform.twist");
|
|
REQUIRE(a.ok());
|
|
REQUIRE(b.ok());
|
|
CHECK(cyclic.createNode(a.value()).ok());
|
|
CHECK(cyclic.createNode(b.value()).ok());
|
|
const auto* aOut = cyclic.findPin(GraphPinId("a.out"));
|
|
const auto* aIn = cyclic.findPin(GraphPinId("a.in0"));
|
|
const auto* bOut = cyclic.findPin(GraphPinId("b.out"));
|
|
const auto* bIn = cyclic.findPin(GraphPinId("b.in0"));
|
|
REQUIRE(aOut != nullptr);
|
|
REQUIRE(aIn != nullptr);
|
|
REQUIRE(bOut != nullptr);
|
|
REQUIRE(bIn != nullptr);
|
|
CHECK(cyclic.connect({StableId("e0"), aOut->id, bIn->id}, domain.canConnect(*aOut, *bIn)).ok());
|
|
CHECK(cyclic.connect({StableId("e1"), bOut->id, aIn->id}, domain.canConnect(*bOut, *aIn)).ok());
|
|
compiled = domain.compile(cyclic.snapshot(domain.domain()));
|
|
CHECK_EQ(static_cast<int>(compiled.status), static_cast<int>(EditorStatus::Rejected));
|
|
}
|