fix: general optimization, lazy cooking, transform caching, fix geometry copying

This commit is contained in:
parker
2025-08-02 23:02:14 +01:00
parent 92bfc8ff26
commit 48ad8909cc
12 changed files with 104 additions and 62 deletions

1
.gitignore vendored
View File

@@ -2,3 +2,4 @@ build
.cache .cache
docs/html docs/html
docs/latex docs/latex
perf.data*

View File

@@ -19,16 +19,13 @@ enzo::nt::OpId enzo::nt::NetworkManager::addOperator(op::OpInfo opInfo)
maxOpId_++; maxOpId_++;
std::unique_ptr<GeometryOperator> newOp = std::make_unique<GeometryOperator>(maxOpId_, opInfo); std::unique_ptr<GeometryOperator> newOp = std::make_unique<GeometryOperator>(maxOpId_, opInfo);
newOp->nodeDirtied.connect( newOp->nodeDirtied.connect(
[this](nt::OpId opId, bool dirtyDescendents) [this](nt::OpId opId, bool dirtyDependents)
{ {
IC(); if(dirtyDependents)
if(dirtyDescendents)
{ {
IC();
std::vector<OpId> dependentIds = getDependentsGraph(opId); std::vector<OpId> dependentIds = getDependentsGraph(opId);
for(OpId dependentId : dependentIds) for(OpId dependentId : dependentIds)
{ {
IC();
// dirty node // dirty node
enzo::nt::GeometryOperator& dependentOp = getGeoOperator(opId); enzo::nt::GeometryOperator& dependentOp = getGeoOperator(opId);
std::cout << "dirtying id: " << dependentId << "\n"; std::cout << "dirtying id: " << dependentId << "\n";
@@ -37,7 +34,6 @@ enzo::nt::OpId enzo::nt::NetworkManager::addOperator(op::OpInfo opInfo)
// cook display op // cook display op
if(getDisplayOp().has_value() && getDisplayOp().value()==dependentId) if(getDisplayOp().has_value() && getDisplayOp().value()==dependentId)
{ {
IC();
cookOp(dependentId); cookOp(dependentId);
updateDisplay(dependentOp.getOutputGeo(0)); updateDisplay(dependentOp.getOutputGeo(0));
} }
@@ -46,7 +42,6 @@ enzo::nt::OpId enzo::nt::NetworkManager::addOperator(op::OpInfo opInfo)
}); });
gopStore_.emplace(maxOpId_, std::move(newOp)); gopStore_.emplace(maxOpId_, std::move(newOp));
std::cout << "adding operator " << maxOpId_ << "\n";
return maxOpId_; return maxOpId_;
} }
@@ -96,10 +91,13 @@ void enzo::nt::NetworkManager::cookOp(enzo::nt::OpId opId)
for(enzo::nt::OpId dependencyOpId : dependencyGraph) for(enzo::nt::OpId dependencyOpId : dependencyGraph)
{ {
enzo::nt::GeometryOperator& op = getGeoOperator(dependencyOpId); enzo::nt::GeometryOperator& op = getGeoOperator(dependencyOpId);
if(op.isDirty())
{
enzo::op::Context context(dependencyOpId, enzo::nt::nm()); enzo::op::Context context(dependencyOpId, enzo::nt::nm());
op.cookOp(context); op.cookOp(context);
} }
} }
}
std::vector<enzo::nt::OpId> enzo::nt::NetworkManager::getDependencyGraph(enzo::nt::OpId opId) std::vector<enzo::nt::OpId> enzo::nt::NetworkManager::getDependencyGraph(enzo::nt::OpId opId)
{ {

View File

@@ -29,6 +29,32 @@ ga::Attribute::Attribute(std::string name, ga::AttributeType type)
} }
ga::Attribute::Attribute(const Attribute& other)
{
type_ = other.type_;
private_= other.private_;
hidden_ = other.hidden_;
readOnly_ = other.readOnly_;
name_ = other.name_;
switch(type_)
{
case(AttrType::intT):
intStore_=std::make_shared<std::vector<int>>(*other.intStore_);
break;
case(AttrType::floatT):
floatStore_=std::make_shared<std::vector<float>>(*other.floatStore_);
break;
case(AttrType::vectorT):
vector3Store_=std::make_shared<std::vector<enzo::bt::Vector3>>(*other.vector3Store_);
break;
default:
throw std::runtime_error("Type " + std::to_string(static_cast<int>(type_)) + " was not properly accounted for");
}
}
ga::AttributeType ga::Attribute::getType() ga::AttributeType ga::Attribute::getType()
{ {
return type_; return type_;

View File

@@ -20,6 +20,7 @@ namespace enzo{
{ {
public: public:
Attribute(std::string name, ga::AttributeType type); Attribute(std::string name, ga::AttributeType type);
Attribute(const Attribute& other);
AttributeType getType(); AttributeType getType();
std::string getName(); std::string getName();
@@ -42,7 +43,7 @@ namespace enzo{
std::string name_; std::string name_;
void* data_; // void* data_;
// data stores // data stores
std::shared_ptr<StoreContainer<int>> intStore_; std::shared_ptr<StoreContainer<int>> intStore_;

View File

@@ -25,7 +25,8 @@ enzo::geo::Geometry enzo::op::Context::cloneInputGeo(unsigned int inputIndex)
auto inputConnection = inputConnections.at(inputIndex); auto inputConnection = inputConnections.at(inputIndex);
if(auto inputConnectionSP = inputConnection.lock()) if(auto inputConnectionSP = inputConnection.lock())
{ {
return networkManager_.getGeoOperator(inputConnectionSP->getInputOpId()).getOutputGeo(inputConnectionSP->getInputIndex()); const nt::GeometryOperator& geoOp = networkManager_.getGeoOperator(inputConnectionSP->getInputOpId());
return geoOp.getOutputGeo(inputConnectionSP->getInputIndex());
} }
else else
{ {
@@ -33,6 +34,7 @@ enzo::geo::Geometry enzo::op::Context::cloneInputGeo(unsigned int inputIndex)
} }
} }
// TODO: cache value
enzo::bt::floatT enzo::op::Context::evalFloatParm(const char* parmName) const enzo::bt::floatT enzo::op::Context::evalFloatParm(const char* parmName) const
{ {
enzo::nt::GeometryOperator& selfOp = networkManager_.getGeoOperator(opId_); enzo::nt::GeometryOperator& selfOp = networkManager_.getGeoOperator(opId_);

View File

@@ -17,6 +17,39 @@ geo::Geometry::Geometry()
addIntAttribute(ga::AttrOwner::PRIMITIVE, "vertexCount"); addIntAttribute(ga::AttrOwner::PRIMITIVE, "vertexCount");
} }
geo::Geometry::Geometry(const Geometry& other)
{
pointAttributes_ = deepCopyAttributes(other.pointAttributes_);
vertexAttributes_ = deepCopyAttributes(other.vertexAttributes_);
primitiveAttributes_ = deepCopyAttributes(other.primitiveAttributes_);
globalAttributes_ = deepCopyAttributes(other.globalAttributes_);
}
geo::Geometry::attribVector geo::Geometry::deepCopyAttributes(attribVector originalVector)
{
geo::Geometry::attribVector copied;
const size_t sourceSize = originalVector.size();
copied.reserve(sourceSize);
for(const std::shared_ptr<ga::Attribute> sourceAttrib : originalVector)
{
if(sourceAttrib)
{
copied.push_back(std::make_shared<ga::Attribute>(*sourceAttrib));
}
else
{
copied.push_back(nullptr);
}
}
return copied;
}
enzo::geo::HeMesh geo::Geometry::computeHalfEdgeMesh() enzo::geo::HeMesh geo::Geometry::computeHalfEdgeMesh()
{ {
HeMesh heMesh; HeMesh heMesh;

View File

@@ -22,14 +22,19 @@ class Geometry
{ {
public: public:
Geometry(); Geometry();
Geometry(const Geometry& other);
ga::AttributeHandle<int> addIntAttribute(ga::AttributeOwner owner, std::string name); ga::AttributeHandle<int> addIntAttribute(ga::AttributeOwner owner, std::string name);
ga::AttributeHandle<bt::Vector3> addVector3Attribute(ga::AttributeOwner owner, std::string name); ga::AttributeHandle<bt::Vector3> addVector3Attribute(ga::AttributeOwner owner, std::string name);
// TODO: return weak ptr
std::shared_ptr<ga::Attribute> getAttribByName(ga::AttributeOwner owner, std::string name); std::shared_ptr<ga::Attribute> getAttribByName(ga::AttributeOwner owner, std::string name);
std::vector<bt::Vector3> derivePointNormals(); std::vector<bt::Vector3> derivePointNormals();
HeMesh computeHalfEdgeMesh(); HeMesh computeHalfEdgeMesh();
private: private:
using attribVector = std::vector<std::shared_ptr<ga::Attribute>>; using attribVector = std::vector<std::shared_ptr<ga::Attribute>>;
attribVector& getAttributeStore(ga::AttributeOwner& owner); attribVector& getAttributeStore(ga::AttributeOwner& owner);
attribVector deepCopyAttributes(attribVector source);
attribVector pointAttributes_; attribVector pointAttributes_;
attribVector vertexAttributes_; attribVector vertexAttributes_;
attribVector primitiveAttributes_; attribVector primitiveAttributes_;

View File

@@ -53,13 +53,19 @@ void enzo::nt::GeometryOperator::dirtyNode(bool dirtyDescendents)
nodeDirtied(opId_, dirtyDescendents); nodeDirtied(opId_, dirtyDescendents);
} }
bool enzo::nt::GeometryOperator::isDirty()
{
return dirty_;
}
void enzo::nt::GeometryOperator::cookOp(op::Context context) void enzo::nt::GeometryOperator::cookOp(op::Context context)
{ {
opDef_->cookOp(context); opDef_->cookOp(context);
dirty_=false; dirty_=false;
} }
geo::Geometry& enzo::nt::GeometryOperator::getOutputGeo(unsigned outputIndex) geo::Geometry& enzo::nt::GeometryOperator::getOutputGeo(unsigned outputIndex) const
{ {
return opDef_->getOutputGeo(outputIndex); return opDef_->getOutputGeo(outputIndex);
} }

View File

@@ -20,7 +20,7 @@ public:
GeometryOperator& operator=(const GeometryOperator&) = delete; GeometryOperator& operator=(const GeometryOperator&) = delete;
void cookOp(op::Context context); void cookOp(op::Context context);
geo::Geometry& getOutputGeo(unsigned outputIndex); geo::Geometry& getOutputGeo(unsigned outputIndex) const;
void addInputConnection(std::shared_ptr<nt::GeometryConnection> connection); void addInputConnection(std::shared_ptr<nt::GeometryConnection> connection);
void addOutputConnection(std::shared_ptr<nt::GeometryConnection> connection); void addOutputConnection(std::shared_ptr<nt::GeometryConnection> connection);
@@ -33,6 +33,7 @@ public:
std::string getTypeName(); std::string getTypeName();
void dirtyNode(bool dirtyDescendents=true); void dirtyNode(bool dirtyDescendents=true);
bool isDirty();
unsigned int getMinInputs() const; unsigned int getMinInputs() const;

View File

@@ -57,22 +57,4 @@ EnzoUI::EnzoUI()
connect(&enzo::nt::nm(), &enzo::nt::NetworkManager::updateDisplay, viewport, &Viewport::geometryChanged); connect(&enzo::nt::nm(), &enzo::nt::NetworkManager::updateDisplay, viewport, &Viewport::geometryChanged);
enzo::nt::nm().displayNodeChanged.connect([parametersPanel](){parametersPanel->selectionChanged();}); enzo::nt::nm().displayNodeChanged.connect([parametersPanel](){parametersPanel->selectionChanged();});
// connect(&enzo::nt::nm(), &enzo::nt::NetworkManager::updateDisplay, parametersPanel, &ParametersPanel::selectionChanged); // connect(&enzo::nt::nm(), &enzo::nt::NetworkManager::updateDisplay, parametersPanel, &ParametersPanel::selectionChanged);
// ─── end of EnzoUI ctor ───
QTimer::singleShot(0, this, [=] {
auto dump = [](const char* name, QWidget* w) {
qInfo().nospace()
<< name
<< " sizeHint=" << w->sizeHint()
<< " minHint=" << w->minimumSizeHint()
<< " min=" << w->minimumSize()
<< " policy=" << w->sizePolicy();
};
dump("Viewport ", viewport);
dump("ParametersPanel ", parametersPanel);
dump("Network ", network);
dump("NetworkSplitter ", networkSplitter_); // will show max(childmins)
});
} }

View File

@@ -20,6 +20,7 @@ void GopGeometryImport::cookOp(enzo::op::Context context)
if(outputRequested(0)) if(outputRequested(0))
{ {
std::string filePath = "/home/parker/Downloads/Rat_Placeholder_Polycount_12.obj"; std::string filePath = "/home/parker/Downloads/Rat_Placeholder_Polycount_12.obj";
std::cout << "COOKING IMPORT NODE\n";
geo::Geometry geo; geo::Geometry geo;
@@ -59,31 +60,26 @@ void GopGeometryImport::cookOp(enzo::op::Context context)
} }
const bt::Vector3 pointPos = {std::stod(result[1]), std::stod(result[2]), std::stod(result[3])}; const bt::Vector3 pointPos = {std::stod(result[1]), std::stod(result[2]), std::stod(result[3])};
PAttrHandle.addValue(pointPos); PAttrHandle.addValue(pointPos);
std::cout << "adding vector: " << pointPos.x() << " " << pointPos.y() << " " << pointPos.z() << "\n";
} }
else if(firstChar=='f') else if(firstChar=='f')
{ {
std::vector<std::string> result; std::vector<std::string> result;
boost::split(result, line, isspace); boost::split(result, line, isspace);
// if(result.size()<3) if(result.size()<3)
// { {
// continue; continue;
// } }
// set vertex attributes // set vertex attributes
std::cout << "connecting:";
for(int i=1; i<result.size(); ++i) for(int i=1; i<result.size(); ++i)
{ {
const int primNum = std::stoi(result[i]); const int primNum = std::stoi(result[i]);
pointAttrHandle.addValue(primNum-1); pointAttrHandle.addValue(primNum-1);
std::cout << " " << primNum;
} }
std::cout << "\n";
// set face attribute // set face attribute
std::cout << "face size: " << result.size()-1 << "\n";
vertexCountHandle.addValue(result.size()-1); vertexCountHandle.addValue(result.size()-1);
} }
@@ -98,15 +94,6 @@ void GopGeometryImport::cookOp(enzo::op::Context context)
enzo::bt::Vector3 pointPos = PAttrHandle.getValue(i); enzo::bt::Vector3 pointPos = PAttrHandle.getValue(i);
pointPos*=scale; pointPos*=scale;
PAttrHandle.setValue(i, pointPos); PAttrHandle.setValue(i, pointPos);
std::cout << "adding point: " << pointPos.x() << " " << pointPos.y() << " " << pointPos.z() << "\n";
}
for(auto value : pointAttrHandle.getAllValues())
{
std::cout << "adding vector: " << value << "\n";
}
for(auto value : vertexCountHandle.getAllValues())
{
std::cout << "adding face: " << value << "\n";
} }
// ---- // ----

View File

@@ -1,8 +1,10 @@
#include "OpDefs/GopTransform.hpp" #include "OpDefs/GopTransform.hpp"
#include "Engine/Operator/AttributeHandle.h" #include "Engine/Operator/AttributeHandle.h"
#include "Engine/Parameter/Template.h" #include "Engine/Parameter/Template.h"
#include "Engine/Types.h"
#include <Eigen/src/Core/Matrix.h> #include <Eigen/src/Core/Matrix.h>
#include <Eigen/src/Geometry/AngleAxis.h> #include <Eigen/src/Geometry/AngleAxis.h>
#include <Eigen/src/Geometry/Transform.h>
GopTransform::GopTransform(enzo::nt::NetworkManager* network, enzo::op::OpInfo opInfo) GopTransform::GopTransform(enzo::nt::NetworkManager* network, enzo::op::OpInfo opInfo)
: GeometryOpDef(network, opInfo) : GeometryOpDef(network, opInfo)
@@ -25,20 +27,18 @@ void GopTransform::cookOp(enzo::op::Context context)
auto PAttr = geo.getAttribByName(ga::AttrOwner::POINT, "P"); auto PAttr = geo.getAttribByName(ga::AttrOwner::POINT, "P");
ga::AttributeHandleVector3 PAttrHandle(PAttr); ga::AttributeHandleVector3 PAttrHandle(PAttr);
for(int i=0; i<PAttrHandle.getAllValues().size(); ++i) Eigen::Affine3d transform = Eigen::Affine3d::Identity();
{ transform.rotate(Eigen::AngleAxisd(context.evalFloatParm("rotateX"), Eigen::Vector3d(1,0,0)));
enzo::bt::Vector3 vector = PAttrHandle.getValue(i); transform.rotate(Eigen::AngleAxisd(context.evalFloatParm("rotateY"), Eigen::Vector3d(0,1,0)));
Eigen::AngleAxisd rotationX(context.evalFloatParm("rotateX"), Eigen::Vector3d(1,0,0)); transform.rotate(Eigen::AngleAxisd(context.evalFloatParm("rotateZ"), Eigen::Vector3d(0,0,1)));
Eigen::AngleAxisd rotationY(context.evalFloatParm("rotateY"), Eigen::Vector3d(0,1,0)); transform.translate(bt::Vector3(context.evalFloatParm("translateX"), context.evalFloatParm("translateY"), context.evalFloatParm("translateZ")));
Eigen::AngleAxisd rotationZ(context.evalFloatParm("rotateZ"), Eigen::Vector3d(0,0,1));
vector = (rotationX*rotationY*rotationZ)*vector;
vector.x()+=context.evalFloatParm("translateX");
vector.y()+=context.evalFloatParm("translateY");
vector.z()+=context.evalFloatParm("translateZ");
PAttrHandle.setValue(i, vector);
}
// ----
for(int i=0; i<PAttrHandle.getSize(); ++i)
{
enzo::bt::Vector3 pointPos = PAttrHandle.getValue(i);
pointPos = transform*pointPos;
PAttrHandle.setValue(i, pointPos);
}
// set output geometry // set output geometry