feat(geometrySpreadsheet): add index column

This commit is contained in:
parker
2025-08-10 23:30:12 +01:00
parent b245e5333e
commit 500f860d5c
5 changed files with 103 additions and 20 deletions

View File

@@ -3,6 +3,7 @@
#include "Engine/Operator/AttributeHandle.h" #include "Engine/Operator/AttributeHandle.h"
#include "Engine/Types.h" #include "Engine/Types.h"
#include <memory> #include <memory>
#include <oneapi/tbb/spin_mutex.h>
#include <oneapi/tbb/task_group.h> #include <oneapi/tbb/task_group.h>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
@@ -33,16 +34,45 @@ geo::Geometry::Geometry(const Geometry& other):
posHandlePoint_{enzo::ga::AttributeHandleVector3(getAttribByName(ga::AttrOwner::POINT, "P"))}, posHandlePoint_{enzo::ga::AttributeHandleVector3(getAttribByName(ga::AttrOwner::POINT, "P"))},
// other // other
soloPoints_{other.soloPoints_} soloPoints_{other.soloPoints_},
vertexPrims_{other.vertexPrims_},
primStarts_{other.primStarts_},
primStartsDirty_{other.primStartsDirty_.load()}
{ {
}
enzo::geo::Geometry& enzo::geo::Geometry::operator=(const enzo::geo::Geometry& rhs) {
if (this == &rhs) return *this;
// attributes
pointAttributes_ = deepCopyAttributes(rhs.pointAttributes_);
vertexAttributes_ = deepCopyAttributes(rhs.vertexAttributes_);
primitiveAttributes_ = deepCopyAttributes(rhs.primitiveAttributes_);
globalAttributes_ = deepCopyAttributes(rhs.globalAttributes_);
// handles
vertexCountHandlePrim_ = enzo::ga::AttributeHandleInt(getAttribByName(ga::AttrOwner::PRIMITIVE, "vertexCount"));
closedHandlePrim_ = enzo::ga::AttributeHandleBool(getAttribByName(ga::AttrOwner::PRIMITIVE, "closed"));
pointOffsetHandleVert_ = enzo::ga::AttributeHandleInt(getAttribByName(ga::AttrOwner::VERTEX, "point"));
posHandlePoint_ = enzo::ga::AttributeHandleVector3(getAttribByName(ga::AttrOwner::POINT, "P"));
// other
soloPoints_ = rhs.soloPoints_;
vertexPrims_ = rhs.vertexPrims_;
primStarts_ = rhs.primStarts_;
primStartsDirty_.store(rhs.primStartsDirty_.load());
return *this;
} }
void geo::Geometry::addFace(std::vector<ga::Offset> pointOffsets, bool closed) void geo::Geometry::addFace(std::vector<ga::Offset> pointOffsets, bool closed)
{ {
const ga::Offset primNum = vertexCountHandlePrim_.getSize();
for(ga::Offset pointOffset : pointOffsets) for(ga::Offset pointOffset : pointOffsets)
{ {
pointOffsetHandleVert_.addValue(pointOffset); pointOffsetHandleVert_.addValue(pointOffset);
vertexPrims_.push_back(primNum);
soloPoints_.erase(pointOffset); soloPoints_.erase(pointOffset);
} }
vertexCountHandlePrim_.addValue(pointOffsets.size()); vertexCountHandlePrim_.addValue(pointOffsets.size());
@@ -119,6 +149,11 @@ bt::Vector3 geo::Geometry::getPointPos(ga::Offset pointOffset) const
return posHandlePoint_.getValue(pointOffset); return posHandlePoint_.getValue(pointOffset);
} }
ga::Offset geo::Geometry::getVertexPrim(ga::Offset vertexOffset) const
{
return vertexPrims_[vertexOffset];
}
void geo::Geometry::setPointPos(const ga::Offset offset, const bt::Vector3& pos) void geo::Geometry::setPointPos(const ga::Offset offset, const bt::Vector3& pos)
{ {
posHandlePoint_.setValue(offset, pos); posHandlePoint_.setValue(offset, pos);
@@ -250,19 +285,30 @@ enzo::geo::HeMesh geo::Geometry::computeHalfEdgeMesh()
ga::Offset geo::Geometry::getPrimStartVertex(ga::Offset primOffset) const ga::Offset geo::Geometry::getPrimStartVertex(ga::Offset primOffset) const
{ {
if(primStartsDirty_.load())
{
tbb::spin_mutex::scoped_lock lock(primStartsMutex_); //lock
if(primStartsDirty_.load()) // double check
{
computePrimStartVertices();
}
}
return primStarts_[primOffset]; return primStarts_[primOffset];
} }
// TODO: handle this automatically // TODO: handle this automatically
void geo::Geometry::computePrimStartVertices() void geo::Geometry::computePrimStartVertices() const
{ {
const ga::Offset handleSize = vertexCountHandlePrim_.getSize(); const ga::Offset handleSize = vertexCountHandlePrim_.getSize();
primStarts_.clear();
primStarts_.reserve(handleSize);
bt::intT primStart = 0; bt::intT primStart = 0;
for(size_t i=0; i<handleSize; ++i) for(size_t i=0; i<handleSize; ++i)
{ {
primStarts_.push_back(primStart); primStarts_.push_back(primStart);
primStart += vertexCountHandlePrim_.getValue(i); primStart += vertexCountHandlePrim_.getValue(i);
} }
primStartsDirty_.store(false);
} }

View File

@@ -5,6 +5,8 @@
#include <CGAL/Simple_cartesian.h> #include <CGAL/Simple_cartesian.h>
#include "Engine/Operator/AttributeHandle.h" #include "Engine/Operator/AttributeHandle.h"
#include <memory> #include <memory>
#include <oneapi/tbb/spin_mutex.h>
#include <tbb/spin_mutex.h>
#include <variant> #include <variant>
@@ -27,6 +29,7 @@ class Geometry
public: public:
Geometry(); Geometry();
Geometry(const Geometry& other); Geometry(const Geometry& other);
Geometry& operator=(const Geometry& rhs);
ga::AttributeHandle<bt::intT> addIntAttribute(ga::AttributeOwner owner, std::string name); ga::AttributeHandle<bt::intT> addIntAttribute(ga::AttributeOwner owner, std::string name);
ga::AttributeHandleBool addBoolAttribute(ga::AttributeOwner owner, std::string name); ga::AttributeHandleBool addBoolAttribute(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);
@@ -48,18 +51,19 @@ public:
void setPointPos(const ga::Offset offset, const bt::Vector3& pos); void setPointPos(const ga::Offset offset, const bt::Vector3& pos);
ga::Offset getPrimStartVertex(ga::Offset primOffset) const; // returns the first vertex of the primitive ga::Offset getPrimStartVertex(ga::Offset primOffset) const; // returns the first vertex of the primitive
bt::Vector3 getPosFromVert(ga::Offset vertexOffset) const; bt::Vector3 getPosFromVert(ga::Offset vertexOffset) const;
bt::Vector3 getPointPos(ga::Offset pointOffset) const; bt::Vector3 getPointPos(ga::Offset pointOffset) const;
unsigned int getPrimVertCount(ga::Offset primOffset) const; unsigned int getPrimVertCount(ga::Offset primOffset) const;
ga::Offset getNumPrims() const; ga::Offset getVertexPrim(ga::Offset vertexOffset) const;
ga::Offset getNumVerts() const; ga::Offset getNumPrims() const;
ga::Offset getNumPoints() const; ga::Offset getNumVerts() const;
ga::Offset getNumSoloPoints() const; ga::Offset getNumPoints() const;
ga::Offset getNumSoloPoints() const;
bt::boolT isClosed(ga::Offset primOffset) const; bt::boolT isClosed(ga::Offset primOffset) const;
void computePrimStartVertices(); void computePrimStartVertices() const;
private: private:
using attribVector = std::vector<std::shared_ptr<ga::Attribute>>; using attribVector = std::vector<std::shared_ptr<ga::Attribute>>;
geo::Geometry::attribVector& getAttributeStore(const ga::AttributeOwner& owner); geo::Geometry::attribVector& getAttributeStore(const ga::AttributeOwner& owner);
@@ -74,7 +78,11 @@ private:
std::set<ga::Offset> soloPoints_; std::set<ga::Offset> soloPoints_;
std::vector<ga::Offset> primStarts_; mutable std::vector<ga::Offset> primStarts_;
mutable std::vector<ga::Offset> vertexPrims_;
mutable std::atomic<bool> primStartsDirty_{true};
mutable tbb::spin_mutex primStartsMutex_;
// handles // handles
enzo::ga::AttributeHandleInt vertexCountHandlePrim_; enzo::ga::AttributeHandleInt vertexCountHandlePrim_;

View File

@@ -133,8 +133,12 @@ GeometrySpreadsheetMenuBar::GeometrySpreadsheetMenuBar(QWidget *parent, Qt::Wind
nodeLabel_ = new QLabel(); nodeLabel_ = new QLabel();
mainLayout_->addWidget(nodeLabel_); mainLayout_->addWidget(nodeLabel_);
modeSelection = new GeoSheetMenuBarModeSelection(); modeSelection = new GeoSheetMenuBarModeSelection();
mainLayout_->addStretch();
mainLayout_->addWidget(modeSelection); mainLayout_->addWidget(modeSelection);
const int margins = 0;
mainLayout_->setContentsMargins(margins, margins, margins, margins);
setLayout(mainLayout_); setLayout(mainLayout_);
} }

View File

@@ -87,7 +87,7 @@ int GeometrySpreadsheetModel::rowCount(const QModelIndex &parent) const
int GeometrySpreadsheetModel::columnCount(const QModelIndex &parent) const int GeometrySpreadsheetModel::columnCount(const QModelIndex &parent) const
{ {
int columnCount = 0; int columnCount = attributeColumnPadding_; // first column is for indices
for(auto size : attribSizes_) for(auto size : attribSizes_)
{ {
columnCount += size; columnCount += size;
@@ -114,11 +114,34 @@ QVariant GeometrySpreadsheetModel::data(const QModelIndex &index, int role) cons
if (role == Qt::DisplayRole) if (role == Qt::DisplayRole)
{ {
// std::cout << geometry_.getPointPos(index.row()).x() << "\n"; if(index.column()==0)
int attributeIndex = indexFromSection(index.column()); {
switch(attributeOwner_)
{
case enzo::ga::AttributeOwner::POINT:
case enzo::ga::AttributeOwner::PRIMITIVE:
{
return index.row();
}
case enzo::ga::AttributeOwner::VERTEX:
{
const enzo::ga::Offset primOffset = geometry_.getVertexPrim(index.row());
const enzo::ga::Offset startVert = geometry_.getPrimStartVertex(primOffset);
const enzo::ga::Offset vertexNumber = index.row()-startVert;
return QString::fromStdString(std::to_string(primOffset)+":"+std::to_string(vertexNumber));
}
case enzo::ga::AttributeOwner::GLOBAL:
{
return "global";
}
}
}
int attributeIndex = indexFromSection(index.column()-attributeColumnPadding_);
if(std::shared_ptr<const enzo::ga::Attribute> attrib = geometry_.getAttributeByIndex(attributeOwner_, attributeIndex).lock()) if(std::shared_ptr<const enzo::ga::Attribute> attrib = geometry_.getAttributeByIndex(attributeOwner_, attributeIndex).lock())
{ {
const unsigned int valueIndex = index.column()-attributeIndex; const unsigned int valueIndex = index.column()-attributeIndex-attributeColumnPadding_;
using namespace enzo::ga; using namespace enzo::ga;
switch(attrib->getType()) switch(attrib->getType())
@@ -167,9 +190,8 @@ int GeometrySpreadsheetModel::indexFromSection(unsigned int section) const
{ {
if(section>=sectionAttribMap_.size()) if(section>=sectionAttribMap_.size())
{ {
throw std::out_of_range("Section is out of range of sectionAttributMap_"); throw std::out_of_range("Section is out of range of sectionAttributMap_, value: " + std::to_string(section) + " expected: <"+std::to_string(sectionAttribMap_.size()));
} }
IC(sectionAttribMap_);
return sectionAttribMap_[section]; return sectionAttribMap_[section];
} }
@@ -182,12 +204,13 @@ QVariant GeometrySpreadsheetModel::headerData(int section, Qt::Orientation orien
if (orientation == Qt::Horizontal) if (orientation == Qt::Horizontal)
{ {
auto attributeIndex = indexFromSection(section); if(section==0) return "Index";
auto attributeIndex = indexFromSection(section-attributeColumnPadding_);
if(auto attrib = geometry_.getAttributeByIndex(attributeOwner_, attributeIndex).lock()) if(auto attrib = geometry_.getAttributeByIndex(attributeOwner_, attributeIndex).lock())
{ {
if(attribSizes_[attributeIndex]>1) if(attribSizes_[attributeIndex]>1)
{ {
const unsigned int valueIndex = section-attributeIndex; const unsigned int valueIndex = section-attributeIndex-attributeColumnPadding_;
std::string valueIndexString; std::string valueIndexString;
if(attrib->getType()==enzo::ga::AttrType::vectorT) if(attrib->getType()==enzo::ga::AttrType::vectorT)

View File

@@ -23,11 +23,13 @@ public:
void initBuffers(); void initBuffers();
private: private:
enzo::nt::OpId opId_; enzo::nt::OpId opId_;
enzo::geo::Geometry geometry_; enzo::geo::Geometry geometry_;
std::vector<unsigned int> attribSizes_; std::vector<unsigned int> attribSizes_;
std::vector<unsigned int> sectionAttribMap_; std::vector<unsigned int> sectionAttribMap_;
const int attributeColumnPadding_ = 1;
enzo::ga::AttributeOwner attributeOwner_=enzo::ga::AttributeOwner::POINT; enzo::ga::AttributeOwner attributeOwner_=enzo::ga::AttributeOwner::POINT;
}; };