refactor: cleanup setPosBuffer funciton, add getters for geometry

This commit is contained in:
parker
2025-08-03 03:22:52 +01:00
parent 48ad8909cc
commit 488ff9ff72
6 changed files with 139 additions and 65 deletions

View File

@@ -55,13 +55,18 @@ public:
data_->push_back(value); data_->push_back(value);
} }
void reserve(std::size_t newCap)
{
data_->reserve(newCap);
}
// TODO: replace with iterator // TODO: replace with iterator
std::vector<T> getAllValues() const std::vector<T> getAllValues() const
{ {
return {data_->begin(), data_->end()}; return {data_->begin(), data_->end()};
} }
size_t getSize() size_t getSize() const
{ {
return data_->size(); return data_->size();
} }
@@ -70,7 +75,7 @@ public:
{ {
// TODO:protect against invalid positions // TODO:protect against invalid positions
// TODO: cast types // TODO: cast types
return data_->at(pos); return data_[pos];
} }
void setValue(size_t pos, const T& value) void setValue(size_t pos, const T& value)

View File

@@ -10,22 +10,67 @@
#include "icecream.hpp" #include "icecream.hpp"
using namespace enzo; using namespace enzo;
geo::Geometry::Geometry() geo::Geometry::Geometry() :
vertexCountHandlePrim_{addIntAttribute(ga::AttrOwner::PRIMITIVE, "vertexCount")},
pointOffsetHandleVert_{addIntAttribute(ga::AttrOwner::VERTEX, "point")},
posHandlePoint_{addVector3Attribute(ga::AttrOwner::POINT, "P")}
{ {
addVector3Attribute(ga::AttrOwner::POINT, "P");
addIntAttribute(ga::AttrOwner::VERTEX, "point");
addIntAttribute(ga::AttrOwner::PRIMITIVE, "vertexCount");
} }
geo::Geometry::Geometry(const Geometry& other) geo::Geometry::Geometry(const Geometry& other):
pointAttributes_{deepCopyAttributes(other.pointAttributes_)},
vertexAttributes_{deepCopyAttributes(other.vertexAttributes_)},
primitiveAttributes_{deepCopyAttributes(other.primitiveAttributes_)},
globalAttributes_{deepCopyAttributes(other.globalAttributes_)},
vertexCountHandlePrim_{enzo::ga::AttributeHandleInt(getAttribByName(ga::AttrOwner::PRIMITIVE, "vertexCount"))},
pointOffsetHandleVert_{enzo::ga::AttributeHandleInt(getAttribByName(ga::AttrOwner::VERTEX, "point"))},
posHandlePoint_{enzo::ga::AttributeHandleVector3(getAttribByName(ga::AttrOwner::POINT, "P"))}
{ {
pointAttributes_ = deepCopyAttributes(other.pointAttributes_);
vertexAttributes_ = deepCopyAttributes(other.vertexAttributes_);
primitiveAttributes_ = deepCopyAttributes(other.primitiveAttributes_);
globalAttributes_ = deepCopyAttributes(other.globalAttributes_);
} }
void geo::Geometry::addFace(std::initializer_list<ga::Offset> pointOffsets)
{
for(ga::Offset pointOffset : pointOffsets)
{
pointOffsetHandleVert_.addValue(pointOffset);
}
vertexCountHandlePrim_.addValue(pointOffsets.size());
}
bt::Vector3 geo::Geometry::getPosFromVert(ga::Offset vertexOffset) const
{
// get point offset
const ga::Offset pointOffset = pointOffsetHandleVert_.getValue(vertexOffset);
// get value at point offset
return posHandlePoint_.getValue(pointOffset);
}
bt::Vector3 geo::Geometry::getPointPos(ga::Offset pointOffset) const
{
return posHandlePoint_.getValue(pointOffset);
}
unsigned int geo::Geometry::getPrimVertCount(ga::Offset primOffset) const
{
return vertexCountHandlePrim_.getValue(primOffset);
}
ga::Offset geo::Geometry::getNumPrims() const
{
return vertexCountHandlePrim_.getSize();
}
ga::Offset geo::Geometry::getNumVerts() const
{
return pointOffsetHandleVert_.getSize();
}
geo::Geometry::attribVector geo::Geometry::deepCopyAttributes(attribVector originalVector) geo::Geometry::attribVector geo::Geometry::deepCopyAttributes(attribVector originalVector)
{ {
geo::Geometry::attribVector copied; geo::Geometry::attribVector copied;
@@ -125,6 +170,25 @@ enzo::geo::HeMesh geo::Geometry::computeHalfEdgeMesh()
return heMesh; return heMesh;
} }
unsigned int geo::Geometry::getPrimStartVertex(ga::Offset primOffset)
{
const ga::Offset handleSize = vertexCountHandlePrim_.getSize();
// TODO: add smarter system to recompute primStarts_, also move to separate function
// if size changed, recompute
if(handleSize!=primStarts_.size())
{
bt::intT primStart = 0;
for(size_t i=0; i<handleSize; ++i)
{
primStarts_.push_back(primStart);
primStart += vertexCountHandlePrim_.getValue(i);
}
}
return primStarts_[primOffset];
}
ga::AttributeHandle<int> geo::Geometry::addIntAttribute(ga::AttributeOwner owner, std::string name) ga::AttributeHandle<int> geo::Geometry::addIntAttribute(ga::AttributeOwner owner, std::string name)
{ {

View File

@@ -3,6 +3,7 @@
#include "Engine/Types.h" #include "Engine/Types.h"
#include <CGAL/Surface_mesh/Surface_mesh.h> #include <CGAL/Surface_mesh/Surface_mesh.h>
#include <CGAL/Simple_cartesian.h> #include <CGAL/Simple_cartesian.h>
#include "Engine/Operator/AttributeHandle.h"
#include <variant> #include <variant>
@@ -29,6 +30,15 @@ public:
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();
// returns the first vertex of the primitive
unsigned int getPrimStartVertex(ga::Offset primOffset);
void addFace(std::initializer_list<ga::Offset> pointOffsets);
bt::Vector3 getPosFromVert(ga::Offset vertexOffset) const;
bt::Vector3 getPointPos(ga::Offset pointOffset) const;
unsigned int getPrimVertCount(ga::Offset primOffset) const;
ga::Offset getNumPrims() const;
ga::Offset getNumVerts() const;
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);
@@ -39,5 +49,12 @@ private:
attribVector vertexAttributes_; attribVector vertexAttributes_;
attribVector primitiveAttributes_; attribVector primitiveAttributes_;
attribVector globalAttributes_; attribVector globalAttributes_;
std::vector<ga::Offset> primStarts_;
// handles
enzo::ga::AttributeHandleInt vertexCountHandlePrim_;
enzo::ga::AttributeHandleInt pointOffsetHandleVert_;
enzo::ga::AttributeHandleVector3 posHandlePoint_;
}; };
} }

View File

@@ -22,6 +22,7 @@ namespace enzo
}; };
using AttrType = AttributeType; using AttrType = AttributeType;
using AttrOwner = AttributeOwner; using AttrOwner = AttributeOwner;
using Offset = size_t;
} }
// basic types types // basic types types
namespace bt namespace bt

View File

@@ -57,79 +57,55 @@ void GLMesh::setPosBuffer(enzo::geo::Geometry& geometry)
{ {
bind(); bind();
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
vertices.clear();
// enzo::geo::HeMesh heMesh = geometry.computeHalfEdgeMesh(); const size_t numPrims = geometry.getNumPrims();
// // compute mesh normals vertices.resize(geometry.getNumVerts());
// auto vnormals = heMesh.add_property_map<enzo::geo::V_index, enzo::geo::Vector>("v:normals", CGAL::NULL_VECTOR).first;
// auto fnormals = heMesh.add_property_map<enzo::geo::F_index, enzo::geo::Vector>("f:normals", CGAL::NULL_VECTOR).first;
// namespace PMP = CGAL::Polygon_mesh_processing;
// PMP::compute_normals(
// heMesh,
// vnormals,
// fnormals,
// PMP::parameters::vertex_point_map(heMesh.points())
// );
std::shared_ptr<enzo::ga::Attribute> PAttr = geometry.getAttribByName(enzo::ga::AttrOwner::POINT, "P"); for (int primOffset=0; primOffset<numPrims; ++primOffset)
enzo::ga::AttributeHandleVector3 PAttrHandle = enzo::ga::AttributeHandleVector3(PAttr);
auto pointPositions = PAttrHandle.getAllValues();
std::shared_ptr<enzo::ga::Attribute> pointAttr = geometry.getAttribByName(enzo::ga::AttrOwner::VERTEX, "point");
enzo::ga::AttributeHandleInt pointAttrHandle = enzo::ga::AttributeHandleInt(pointAttr);
auto vertexPointIndices = pointAttrHandle.getAllValues();
std::shared_ptr<enzo::ga::Attribute> vertexCountAttr = geometry.getAttribByName(enzo::ga::AttrOwner::PRIMITIVE, "vertexCount");
enzo::ga::AttributeHandleInt vertexCountHandle = enzo::ga::AttributeHandleInt(vertexCountAttr);
std::vector<int> vertexCounts = vertexCountHandle.getAllValues();
unsigned int vertexCount = 0;
unsigned int primStartVert = 0;
for (int primIndx=0; primIndx<vertexCounts.size(); ++primIndx)
{ {
auto faceIndex = primIndx; const unsigned int primStartVert = geometry.getPrimStartVertex(primOffset);
int faceVertCnt = vertexCounts[primIndx]; auto faceIndex = primOffset;
int faceVertCnt = geometry.getPrimVertCount(primOffset);
enzo::bt::Vector3 n; enzo::bt::Vector3 n;
// compute normal // compute normal
if(faceVertCnt>=3) if(faceVertCnt>=3)
{ {
const unsigned v0 = primStartVert; const unsigned v1 = primStartVert;
const unsigned v1 = primStartVert + 1; const unsigned v2 = primStartVert + 1;
const unsigned v2 = primStartVert + 2; const unsigned v3 = primStartVert + 2;
const enzo::bt::Vector3 pos1 = pointPositions[vertexPointIndices[v0]]; const enzo::bt::Vector3 pos1 = geometry.getPosFromVert(v1);
const enzo::bt::Vector3 pos2 = pointPositions[vertexPointIndices[v1]]; const enzo::bt::Vector3 pos2 = geometry.getPosFromVert(v2);
const enzo::bt::Vector3 pos3 = pointPositions[vertexPointIndices[v2]]; const enzo::bt::Vector3 pos3 = geometry.getPosFromVert(v3);
const enzo::bt::Vector3 tang1 = (pos2-pos1).normalized(); enzo::bt::Vector3 tang1 = (pos2-pos1);
const enzo::bt::Vector3 tang2 = (pos3-pos1).normalized(); enzo::bt::Vector3 tang2 = (pos3-pos1);
tang1.normalize();
tang2.normalize();
n = tang1.cross(tang2); n = tang1.cross(tang2);
} }
for(int i=0; i< faceVertCnt; ++i) for(int i=0; i< faceVertCnt; ++i)
{ {
unsigned int pointIndex = vertexPointIndices[vertexCount]; const unsigned int vertexCount = primStartVert+i;
enzo::bt::Vector3& p = pointPositions[pointIndex]; enzo::bt::Vector3 p = geometry.getPosFromVert(vertexCount);
vertices[vertexCount] ={
vertices.push_back({
{ p.x(), { p.x(),
p.y(), p.y(),
p.z()}, p.z()},
{ n.x(), { n.x(),
n.y(), n.y(),
n.z()} n.z()}
}); };
++vertexCount;
} }
primStartVert+=faceVertCnt;
} }

View File

@@ -5,6 +5,9 @@
#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> #include <Eigen/src/Geometry/Transform.h>
#include <cstddef>
#include <oneapi/tbb/blocked_range.h>
#include <oneapi/tbb/parallel_for.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)
@@ -20,10 +23,8 @@ void GopTransform::cookOp(enzo::op::Context context)
{ {
// copy input geometry // copy input geometry
geo::Geometry geo = context.cloneInputGeo(0); geo::Geometry geo = context.cloneInputGeo(0);
// geo::Geometry geo;
// ----
// create geometry start
// ----
auto PAttr = geo.getAttribByName(ga::AttrOwner::POINT, "P"); auto PAttr = geo.getAttribByName(ga::AttrOwner::POINT, "P");
ga::AttributeHandleVector3 PAttrHandle(PAttr); ga::AttributeHandleVector3 PAttrHandle(PAttr);
@@ -33,12 +34,22 @@ void GopTransform::cookOp(enzo::op::Context context)
transform.rotate(Eigen::AngleAxisd(context.evalFloatParm("rotateZ"), Eigen::Vector3d(0,0,1))); transform.rotate(Eigen::AngleAxisd(context.evalFloatParm("rotateZ"), Eigen::Vector3d(0,0,1)));
transform.translate(bt::Vector3(context.evalFloatParm("translateX"), context.evalFloatParm("translateY"), context.evalFloatParm("translateZ"))); transform.translate(bt::Vector3(context.evalFloatParm("translateX"), context.evalFloatParm("translateY"), context.evalFloatParm("translateZ")));
for(int i=0; i<PAttrHandle.getSize(); ++i) const Eigen::Matrix3d R = transform.linear();
const Eigen::Vector3d t = transform.translation();
const size_t N = PAttrHandle.getSize();
tbb::parallel_for(tbb::blocked_range<size_t>(0, N), [&](tbb::blocked_range<size_t> range)
{ {
enzo::bt::Vector3 pointPos = PAttrHandle.getValue(i); for(size_t i=range.begin(); i<range.end(); ++i)
pointPos = transform*pointPos; {
PAttrHandle.setValue(i, pointPos); enzo::bt::Vector3 pointPos = PAttrHandle.getValue(i);
} pointPos = R * pointPos + t;
// pointPos = transform*pointPos;
PAttrHandle.setValue(i, pointPos);
}
});
// set output geometry // set output geometry