feat: add parameter ranges

This commit is contained in:
parker
2025-08-11 21:46:07 +01:00
parent 1268de4f97
commit f7a96ae05d
16 changed files with 175 additions and 45 deletions

View File

@@ -66,6 +66,11 @@ enzo::bt::String enzo::prm::Parameter::evalString(unsigned int index) const
return stringValues_[index];
}
const enzo::prm::Template& enzo::prm::Parameter::getTemplate()
{
return template_;
}
enzo::prm::Type enzo::prm::Parameter::getType() const

View File

@@ -20,6 +20,8 @@ public:
void setFloat(bt::floatT value, unsigned int index=0);
void setString(bt::String value, unsigned int index=0);
const Template& getTemplate();
boost::signals2::signal<void ()> valueChanged;
private:
Template template_;

View File

@@ -0,0 +1,8 @@
#include "Engine/Parameter/Range.h"
enzo::prm::Range::Range(bt::floatT minValue, RangeFlag minFlag, bt::floatT maxValue, RangeFlag maxFlag)
: minValue_{minValue}, minFlag_{minFlag}, maxValue_{maxValue}, maxFlag_{maxFlag}
{
}

View File

@@ -0,0 +1,29 @@
#pragma once
#include "Engine/Types.h"
namespace enzo::prm
{
enum class RangeFlag
{
UNLOCKED,
LOCKED
};
class Range
{
public:
Range(bt::floatT minValue=0, RangeFlag minFlag=RangeFlag::UNLOCKED, bt::floatT maxValue=10, RangeFlag maxFlag=RangeFlag::UNLOCKED);
bt::floatT getMin() const { return minValue_; }
bt::floatT getMax() const { return maxValue_; }
RangeFlag getMinFlag() const { return minFlag_; }
RangeFlag getMaxFlag() const { return maxFlag_; }
private:
bt::floatT minValue_;
bt::floatT maxValue_;
RangeFlag minFlag_;
RangeFlag maxFlag_;
};
}

View File

@@ -1,5 +1,6 @@
#include "Engine/Parameter/Template.h"
#include "Engine/Parameter/Default.h"
#include "Engine/Parameter/Range.h"
#include "Engine/Parameter/Type.h"
enzo::prm::Template::Template(enzo::prm::Type type, const char* name)
@@ -14,17 +15,18 @@ enzo::prm::Template::Template(enzo::prm::Type type, const char* name, unsigned i
}
enzo::prm::Template::Template(enzo::prm::Type type, const char* name, std::vector<prm::Default> defaults, unsigned int vectorSize)
enzo::prm::Template::Template(enzo::prm::Type type, const char* name, std::vector<prm::Default> defaults, unsigned int vectorSize, std::vector<prm::Range> ranges)
: type_{type}, name_{name}, defaults_{defaults}, vectorSize_(vectorSize)
{
ranges.resize(vectorSize);
ranges_ = ranges;
}
enzo::prm::Template::Template(enzo::prm::Type type, const char* name, prm::Default theDefault, unsigned int vectorSize)
enzo::prm::Template::Template(enzo::prm::Type type, const char* name, prm::Default theDefault, unsigned int vectorSize, Range range)
: type_{type}, name_{name}, vectorSize_(vectorSize)
{
defaults_.push_back(theDefault);
ranges_.push_back(range);
}
enzo::prm::Template::Template()
@@ -55,6 +57,11 @@ const enzo::prm::Default enzo::prm::Template::getDefault(unsigned int index) con
return defaults_.at(index);
}
const enzo::prm::Range& enzo::prm::Template::getRange(unsigned int index) const
{
return ranges_.at(index);
}
const unsigned int enzo::prm::Template::getNumDefaults() const
{
return defaults_.size();

View File

@@ -1,5 +1,6 @@
#pragma once
#include "Engine/Parameter/Default.h"
#include "Engine/Parameter/Range.h"
#include "Engine/Parameter/Type.h"
#include "Engine/Types.h"
@@ -22,17 +23,20 @@ public:
enzo::prm::Type type,
const char* name,
std::vector<prm::Default> defaults,
unsigned int vectorSize = 1
unsigned int vectorSize = 1,
std::vector<prm::Range> ranges=std::vector<prm::Range>()
);
Template(
enzo::prm::Type type,
const char* name,
prm::Default theDefault,
unsigned int vectorSize = 1
unsigned int vectorSize = 1,
Range range=Range()
);
Template();
const char* getName() const;
const prm::Default getDefault(unsigned int index=0) const;
const prm::Range& getRange(unsigned int index=0) const;
const prm::Type getType() const;
const unsigned int getSize() const;
const unsigned int getNumDefaults() const;
@@ -40,6 +44,7 @@ public:
private:
enzo::prm::Type type_;
std::vector<prm::Default> defaults_;
std::vector<prm::Range> ranges_;
// TODO: make a class that holds token and name
const char* name_;
unsigned int vectorSize_;

View File

@@ -6,17 +6,19 @@
#include <iostream>
#include <qboxlayout.h>
#include <qnamespace.h>
#include <icecream.hpp>
#include <algorithm>
#include <string>
enzo::ui::FloatSliderParm::FloatSliderParm(bt::floatT value, QWidget *parent, Qt::WindowFlags f)
enzo::ui::FloatSliderParm::FloatSliderParm(std::weak_ptr<prm::Parameter> parameter, unsigned int vectorIndex, QWidget *parent, Qt::WindowFlags f)
: QWidget(parent, f)
{
// tells qt to style the widget even though it's a Q_OBJECT
setAttribute(Qt::WA_StyledBackground, true);
setFixedHeight(24);
parameter_ = parameter;
mainLayout_ = new QVBoxLayout();
setLayout(mainLayout_);
@@ -34,7 +36,19 @@ enzo::ui::FloatSliderParm::FloatSliderParm(bt::floatT value, QWidget *parent, Qt
)");
mainLayout_->addWidget(valueLabel_);
setValueImpl(value);
if(auto parameterShared=parameter_.lock())
{
auto range = parameterShared->getTemplate().getRange();
minValue_=range.getMin();
maxValue_=range.getMax();
clampMin_=range.getMinFlag()==prm::RangeFlag::LOCKED;
clampMax_=range.getMaxFlag()==prm::RangeFlag::LOCKED;
setValueImpl(parameterShared->evalFloat(vectorIndex));
}
else
{
throw std::bad_weak_ptr();
}
}
void enzo::ui::FloatSliderParm::paintEvent(QPaintEvent *event)
@@ -45,7 +59,7 @@ void enzo::ui::FloatSliderParm::paintEvent(QPaintEvent *event)
painter.setBrush(QColor("#383838"));
const int valueRange = maxValue_-minValue_;
float fillPercent = static_cast<float>(value_-minValue_)/valueRange;
float fillPercent = std::min<float>(static_cast<float>(value_-minValue_)/valueRange, 1);
constexpr float margin = 3;
float fillWidth = rect().width()-margin*2;

View File

@@ -3,6 +3,7 @@
#include <QWidget>
#include <QVBoxLayout>
#include <QLabel>
#include "Engine/Parameter/Parameter.h"
namespace enzo::ui
{
@@ -12,7 +13,7 @@ class FloatSliderParm
{
Q_OBJECT
public:
FloatSliderParm(bt::floatT value, QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
FloatSliderParm(std::weak_ptr<prm::Parameter> parameter, unsigned int vectorIndex=0, QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
void setValue(bt::floatT value);
Q_SIGNALS:
@@ -23,10 +24,11 @@ private:
QVBoxLayout* mainLayout_;
QLabel* valueLabel_;
bt::floatT value_;
bool clampMin_ = true;
bool clampMax_ = true;
bt::floatT minValue_=-5;
bt::floatT maxValue_=10;
bool clampMin_;
bool clampMax_;
bt::floatT minValue_;
bt::floatT maxValue_;
std::weak_ptr<prm::Parameter> parameter_;
void setValueImpl(bt::floatT value);

View File

@@ -28,23 +28,23 @@ enzo::ui::FormParm::FormParm(std::weak_ptr<prm::Parameter> parameter)
{
case prm::Type::FLOAT:
{
FloatSliderParm* slider = new FloatSliderParm(sharedParameter->evalFloat());
FloatSliderParm* slider = new FloatSliderParm(parameter);
mainLayout_->addWidget(slider);
connect(slider, &FloatSliderParm::valueChanged, this, [this](bt::floatT value){this->changeValue(value, 0);});
break;
}
case prm::Type::INT:
{
IntSliderParm* slider = new IntSliderParm(sharedParameter->evalInt());
IntSliderParm* slider = new IntSliderParm(parameter_);
mainLayout_->addWidget(slider);
connect(slider, &IntSliderParm::valueChanged, this, [this](bt::intT value){this->changeValue(value, 0);});
break;
}
case prm::Type::XYZ:
{
FloatSliderParm* slider1 = new FloatSliderParm(sharedParameter->evalFloat(0));
FloatSliderParm* slider2 = new FloatSliderParm(sharedParameter->evalFloat(1));
FloatSliderParm* slider3 = new FloatSliderParm(sharedParameter->evalFloat(2));
FloatSliderParm* slider1 = new FloatSliderParm(parameter, 0);
FloatSliderParm* slider2 = new FloatSliderParm(parameter, 0);
FloatSliderParm* slider3 = new FloatSliderParm(parameter, 0);
QHBoxLayout* vectorLayout = new QHBoxLayout();
vectorLayout->addWidget(slider1);
vectorLayout->addWidget(slider2);
@@ -57,7 +57,7 @@ enzo::ui::FormParm::FormParm(std::weak_ptr<prm::Parameter> parameter)
}
case prm::Type::STRING:
{
StringParm* stringParm = new StringParm(sharedParameter->evalString());
StringParm* stringParm = new StringParm(parameter);
connect(stringParm, &StringParm::valueChanged, this, [this](bt::String value){this->changeValue(value, 0);});

View File

@@ -1,4 +1,5 @@
#include "Gui/Parameters/IntSliderParm.h"
#include "Engine/Parameter/Range.h"
#include "Engine/Types.h"
#include <QPainter>
#include <QPaintEvent>
@@ -12,7 +13,7 @@
#include <icecream.hpp>
enzo::ui::IntSliderParm::IntSliderParm(bt::intT value, QWidget *parent, Qt::WindowFlags f)
enzo::ui::IntSliderParm::IntSliderParm(std::weak_ptr<prm::Parameter> parameter, QWidget *parent, Qt::WindowFlags f)
: QWidget(parent, f)
{
// tells qt to style the widget even though it's a Q_OBJECT
@@ -21,8 +22,8 @@ enzo::ui::IntSliderParm::IntSliderParm(bt::intT value, QWidget *parent, Qt::Wind
notchPen_ = QPen(QColor("#383838"), notchWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
parameter_=parameter;
mainLayout_ = new QVBoxLayout();
setLayout(mainLayout_);
@@ -39,7 +40,19 @@ enzo::ui::IntSliderParm::IntSliderParm(bt::intT value, QWidget *parent, Qt::Wind
)");
mainLayout_->addWidget(valueLabel_);
setValueImpl(value);
if(auto parameterShared=parameter_.lock())
{
auto range = parameterShared->getTemplate().getRange();
minValue_=range.getMin();
maxValue_=range.getMax();
clampMin_=range.getMinFlag()==prm::RangeFlag::LOCKED;
clampMax_=range.getMaxFlag()==prm::RangeFlag::LOCKED;
setValueImpl(parameterShared->evalInt());
}
else
{
throw std::bad_weak_ptr();
}
}
void enzo::ui::IntSliderParm::paintEvent(QPaintEvent *event)
@@ -48,7 +61,7 @@ void enzo::ui::IntSliderParm::paintEvent(QPaintEvent *event)
painter.setRenderHint(QPainter::Antialiasing, true);
const int valueRange = maxValue_-minValue_;
float fillPercent = static_cast<float>(value_-minValue_)/valueRange;
float fillPercent = std::min<float>(static_cast<float>(value_-minValue_)/valueRange, 1);
IC(value_, fillPercent);
float margin = 3;
float fillWidth = rect().width()-margin*2;

View File

@@ -4,6 +4,7 @@
#include <QVBoxLayout>
#include <QLabel>
#include <QPen>
#include "Engine/Parameter/Parameter.h"
namespace enzo::ui
{
@@ -13,7 +14,7 @@ class IntSliderParm
{
Q_OBJECT
public:
IntSliderParm(bt::intT value, QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
IntSliderParm(std::weak_ptr<enzo::prm::Parameter> parameter, QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
void setValue(bt::intT value);
Q_SIGNALS:
@@ -24,10 +25,12 @@ private:
QVBoxLayout* mainLayout_;
QLabel* valueLabel_;
bt::intT value_;
bool clampMin_ = true;
bool clampMax_ = true;
bt::intT minValue_=-5;
bt::intT maxValue_=10;
bool clampMin_;
bool clampMax_;
bt::intT minValue_;
bt::intT maxValue_;
std::weak_ptr<prm::Parameter> parameter_;
QPen notchPen_;
static constexpr int notchWidth = 2;

View File

@@ -9,16 +9,25 @@
#include <algorithm>
#include <QLineEdit>
#include <string>
#include <icecream.hpp>
enzo::ui::StringParm::StringParm(bt::String value, QWidget *parent)
enzo::ui::StringParm::StringParm(std::weak_ptr<prm::Parameter> parameter, QWidget *parent)
: QLineEdit(parent)
{
// tells qt to style the widget even though it's a Q_OBJECT
setAttribute(Qt::WA_StyledBackground, true);
setFixedHeight(24);
value_ = value;
parameter_ = parameter;
if(auto parameterShared=parameter_.lock())
{
value_ = parameterShared->evalString();
}
else
{
throw std::bad_weak_ptr();
}
setText(QString::fromStdString(value_));

View File

@@ -4,6 +4,7 @@
#include <QVBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include "Engine/Parameter/Parameter.h"
namespace enzo::ui
{
@@ -13,9 +14,10 @@ class StringParm
{
Q_OBJECT
public:
StringParm(bt::String value, QWidget *parent = nullptr);
StringParm(std::weak_ptr<prm::Parameter>, QWidget *parent = nullptr);
void setValue(bt::String value);
void setValueQString(QString value);
std::weak_ptr<prm::Parameter> parameter_;
Q_SIGNALS:
void valueChanged(bt::String value);

View File

@@ -20,6 +20,7 @@ add_library(${libName} SHARED
../Engine/Parameter/Template.cpp
../Engine/Parameter/Parameter.cpp
../Engine/Parameter/Default.cpp
../Engine/Parameter/Range.cpp
GopTransform.cpp
GopHouse.cpp
GopTestCube.cpp

View File

@@ -1,4 +1,5 @@
#include "OpDefs/GopGrid.h"
#include "Engine/Parameter/Range.h"
#include "Engine/Types.h"
#include <cmath>
#include <cstdio>
@@ -25,30 +26,46 @@ void GopGrid::cookOp(enzo::op::Context context)
const bt::intT columns = context.evalFloatParm("columns");
const bt::intT rows = context.evalFloatParm("rows");
if(columns==0 || rows==0)
if(columns<=0 || rows<=0)
{
setOutputGeometry(0, geo);
return;
}
const bt::floatT centerOffsetX = (columns-1)*width/2.0;
const bt::floatT centerOffsetY = (rows-1)*height/2.0;
const bt::floatT centerOffsetX = width/2.0;
const bt::floatT centerOffsetY = height/2.0;
// add points
for(int i=0;i<columns;i++)
{
for(int j=0;j<rows;++j)
{
geo.addPoint(bt::Vector3(i*width-centerOffsetX, sin(i+j), j*height-centerOffsetY));
const bt::floatT x = static_cast<bt::floatT>(i)/columns*width-centerOffsetX;
const bt::floatT z = static_cast<bt::floatT>(j)/rows*height-centerOffsetY;
geo.addPoint(bt::Vector3(x, sin(i+j)/10, z));
}
}
for(int i=0;i<std::floor((columns-1)*(rows)-1);i++)
if(columns > 1 && rows > 1)
{
const int endOffset = (i+1)%rows==0;
const ga::Offset startPt = i+endOffset;
geo.addFace(startPt,startPt+rows,startPt+rows+1,startPt+1);
// add faces
for(int i=0;i<std::floor((columns-1)*(rows)-1);i++)
{
const int endOffset = (i+1)%rows==0;
const ga::Offset startPt = i+endOffset;
geo.addFace({startPt,startPt+rows,startPt+rows+1,startPt+1});
}
}
else
{
// add lines
const size_t iterationLimit = std::max(columns, rows)-1;
for(int i=0;i<iterationLimit;i++)
{
const ga::Offset startPt = i;
geo.addFace({startPt,startPt+1}, false);
}
}
setOutputGeometry(0, geo);
}
@@ -57,9 +74,21 @@ void GopGrid::cookOp(enzo::op::Context context)
enzo::prm::Template GopGrid::parameterList[] =
{
enzo::prm::Template(enzo::prm::Type::FLOAT, "width", enzo::prm::Default(1)),
enzo::prm::Template(enzo::prm::Type::FLOAT, "height", enzo::prm::Default(1)),
enzo::prm::Template(enzo::prm::Type::INT, "rows", enzo::prm::Default(10)),
enzo::prm::Template(enzo::prm::Type::INT, "columns", enzo::prm::Default(10)),
enzo::prm::Template(enzo::prm::Type::FLOAT, "width", enzo::prm::Default(10), 1, enzo::prm::Range(0, enzo::prm::RangeFlag::UNLOCKED, 100, enzo::prm::RangeFlag::UNLOCKED)),
enzo::prm::Template(enzo::prm::Type::FLOAT, "height", enzo::prm::Default(10), 1, enzo::prm::Range(0, enzo::prm::RangeFlag::UNLOCKED, 100, enzo::prm::RangeFlag::UNLOCKED)),
enzo::prm::Template(
enzo::prm::Type::INT,
"rows",
enzo::prm::Default(10),
1,
enzo::prm::Range(0, enzo::prm::RangeFlag::LOCKED, 100, enzo::prm::RangeFlag::UNLOCKED)
),
enzo::prm::Template(
enzo::prm::Type::INT,
"columns",
enzo::prm::Default(10),
1,
enzo::prm::Range(0, enzo::prm::RangeFlag::LOCKED, 100, enzo::prm::RangeFlag::UNLOCKED)
),
enzo::prm::Terminator
};