feat(engine): basic attribute implementation

This commit is contained in:
parker
2025-06-28 21:50:26 +01:00
parent 348eb8301d
commit 9734e58897
8 changed files with 297 additions and 1 deletions

View File

@@ -19,6 +19,8 @@ qt_standard_project_setup()
# glm # glm
find_package(glm REQUIRED) find_package(glm REQUIRED)
qt_add_executable(${AppExec} qt_add_executable(${AppExec}
static/resources.qrc static/resources.qrc
src/gui/main.cpp src/gui/main.cpp
@@ -44,6 +46,12 @@ target_link_libraries(${AppExec} PRIVATE Qt6::Core Qt6::Widgets Qt6::SvgWidgets
target_include_directories(${AppExec} PUBLIC src) target_include_directories(${AppExec} PUBLIC src)
# tests # tests
add_executable(${TestExec} tests/main-tests.cpp) add_executable(${TestExec}
tests/main-tests.cpp
tests/OperatorTests.cpp
src/Engine/Operator/Attribute.cpp
# src/Engine/Operator/Primitive.cpp
)
find_package(Catch2 3 REQUIRED) find_package(Catch2 3 REQUIRED)
target_link_libraries(${TestExec} PRIVATE Catch2::Catch2WithMain) target_link_libraries(${TestExec} PRIVATE Catch2::Catch2WithMain)
target_include_directories(${TestExec} PUBLIC src)

View File

@@ -0,0 +1,34 @@
#include "Engine/Operator/Attribute.h"
#include "Engine/Types.h"
#include <memory>
#include <stdexcept>
#include <optional>
using namespace enzo;
ga::Attribute::Attribute(std::string name, ga::AttributeType type)
: name_{name}, type_{type}
{
// init store
switch(type_)
{
case(AttrType::intT):
intStore_=std::make_shared<std::vector<int>>();
break;
case(AttrType::floatT):
floatStore_=std::make_shared<std::vector<float>>();
break;
default:
throw std::runtime_error("Type " + std::to_string(static_cast<int>(type_)) + " was not accounted for");
}
}
ga::AttributeType ga::Attribute::getType()
{
return type_;
}

View File

@@ -0,0 +1,50 @@
#pragma once
#include <string>
#include <optional>
#include <vector>
#include "Engine/Types.h"
#include <memory>
namespace enzo{
namespace ga{
template <typename T>
class AttributeHandle;
class Attribute
{
public:
Attribute(std::string name, ga::AttributeType type);
AttributeType getType();
template <typename T>
friend class AttributeHandle;
private:
// private attributes are attributes that are hidden from the user
// for internal use
bool private_=false;
// hidden attributes are user accessible attributes that the user may
// or may want to use
bool hidden_=false;
// allows the user to read the attribute but not modify it
bool readOnly_=false;
ga::AttributeType type_;
std::string name_;
void* data_;
// data stores
std::shared_ptr<std::vector<int>> intStore_;
std::shared_ptr<std::vector<float>> floatStore_;
};
}
}

View File

@@ -0,0 +1,94 @@
#pragma once
#include <stdexcept>
#include <string>
#include <optional>
#include <vector>
#include "Engine/Operator/Attribute.h"
#include <iostream>
namespace enzo::ga{
template <typename T>
class AttributeHandle
{
public:
ga::AttributeType type_;
AttributeHandle(Attribute& attribute)
{
type_ = attribute.getType();
// get attribute data pointer
// TODO: check types match
// TODO: add the other types
if constexpr (std::is_same<int, T>::value)
{
data_=attribute.intStore_;
}
else if constexpr (std::is_same<float, T>::value)
{
data_=attribute.floatStore_;
}
else
{
throw std::runtime_error("Type " + std::to_string(static_cast<int>(type_)) + " was not accounted for");
}
// switch(type_)
// {
// case(AttrType::intT):
// {
// data_=attribute.intStore_;
// break;
// }
// case(AttrType::floatT):
// {
// data_=attribute.floatStore_;
// break;
// }
// default:
// throw std::runtime_error("Type " + std::to_string(static_cast<int>(type_)) + " was not accounted for");
// }
}
void addValue(T value)
{
// TODO:make this private (primitive friend classes only)
data_->push_back(value);
}
T getValue(uint pos)
{
// TODO:protect against invalid positions
// TODO: cast types
return data_->at(pos);
}
std::string getName()
{
return name_;
}
private:
// private attributes are attributes that are hidden from the user
// for internal use
bool private_=false;
// hidden attributes are user accessible attributes that the user may
// or may want to use
bool hidden_=false;
// allows the user to read the attributeHandle but not modify it
bool readOnly_=false;
std::string name_="";
std::shared_ptr<std::vector<T>> data_;
// int typeID_;
};
using AttributeHandleInt = AttributeHandle<int>;
using AttributeHandleFloat = AttributeHandle<float>;
}

View File

@@ -0,0 +1,24 @@
#include "Engine/Operator/Primitive.h"
#include "Engine/Operator/Attribute.h"
#include "Engine/Types.h"
enzo::Primitive::Primitive()
{
}
bool enzo::Primitive::addIntAttrib(AttributeOwner owner, AttributeInt attribute)
{
bool status = true;
switch(owner)
{
case enzo::AttributeOwner::POINT:
pointAttribs_.push_back(attribute);
break;
}
pointAttribs_.push_back(attribute);
return status;
}

View File

@@ -0,0 +1,20 @@
#pragma once
#include "Engine/Operator/Attribute.h"
#include "Engine/Types.h"
#include <variant>
namespace enzo
{
class Primitive
{
public:
Primitive();
bool addIntAttrib(AttributeOwner owner, AttributeInt attribute);
AttributeInt findAttribByName(AttributeOwner owner, std::string name);
private:
std::vector<std::variant<
AttributeInt,
AttributeFloat
>> pointAttribs_;
};
}

25
src/Engine/Types.h Normal file
View File

@@ -0,0 +1,25 @@
#pragma once
namespace enzo
{
namespace ga
{
enum class AttributeOwner
{
POINT,
VERTEX,
PRIMITIVE,
GLOBAL
};
enum class AttributeType
{
intT,
floatT,
listT,
vectorT,
};
using AttrType = AttributeType;
using AttrOwner = AttributeOwner;
}
}

41
tests/OperatorTests.cpp Normal file
View File

@@ -0,0 +1,41 @@
#include <catch2/catch_test_macros.hpp>
#include "Engine/Operator/Attribute.h"
#include "Engine/Operator/AttributeHandle.h"
#include "Engine/Types.h"
// #include "Engine/Operator/Primitive.h"
TEST_CASE("attrHandleInt")
{
using namespace enzo;
ga::Attribute myAttrib("test", ga::AttrType::intT);
ga::AttributeHandleInt myHandle(myAttrib);
myHandle.addValue(5);
myHandle.addValue(6);
REQUIRE(myHandle.getValue(0)==5);
REQUIRE(myHandle.getValue(1)==6);
}
TEST_CASE("attrHandleFloat")
{
using namespace enzo;
ga::Attribute myAttrib("test", ga::AttrType::floatT);
ga::AttributeHandleFloat myHandle(myAttrib);
myHandle.addValue(5.3f);
myHandle.addValue(6.9f);
REQUIRE(myHandle.getValue(0)==5.3f);
REQUIRE(myHandle.getValue(1)==6.9f);
}
TEST_CASE("Attribute Type")
{
using namespace enzo;
REQUIRE(ga::AttributeType::intT == ga::AttributeType::intT);
REQUIRE(ga::AttributeType::intT != ga::AttributeType::floatT);
REQUIRE(ga::AttributeType::floatT == ga::AttributeType::floatT);
REQUIRE(ga::AttributeType::listT == ga::AttributeType::listT);
REQUIRE(ga::AttributeType::vectorT == ga::AttributeType::vectorT);
}