feat: geometry spreadsheet
This commit is contained in:
@@ -31,6 +31,9 @@ set(GUI_SOURCES
|
|||||||
src/Gui/main.cpp
|
src/Gui/main.cpp
|
||||||
src/Gui/Interface.cpp
|
src/Gui/Interface.cpp
|
||||||
src/Gui/UtilWidgets/Splitter.cpp
|
src/Gui/UtilWidgets/Splitter.cpp
|
||||||
|
src/Gui/GeometrySpreadsheetPanel/GeometrySpreadsheetPanel.cpp
|
||||||
|
src/Gui/GeometrySpreadsheetPanel/GeometrySpreadsheetMenuBar.cpp
|
||||||
|
src/Gui/GeometrySpreadsheetPanel/GeometrySpreadsheetModel.cpp
|
||||||
src/Gui/Viewport/Viewport.cpp
|
src/Gui/Viewport/Viewport.cpp
|
||||||
src/Gui/Viewport/ViewportGLWidget.cpp
|
src/Gui/Viewport/ViewportGLWidget.cpp
|
||||||
src/Gui/Viewport/GLCamera.cpp
|
src/Gui/Viewport/GLCamera.cpp
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ enzo::nt::OpId enzo::nt::NetworkManager::addOperator(op::OpInfo opInfo)
|
|||||||
if(getDisplayOp().has_value() && getDisplayOp().value()==dependentId)
|
if(getDisplayOp().has_value() && getDisplayOp().value()==dependentId)
|
||||||
{
|
{
|
||||||
cookOp(dependentId);
|
cookOp(dependentId);
|
||||||
updateDisplay(dependentOp.getOutputGeo(0));
|
displayGeoChanged(dependentOp.getOutputGeo(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,8 +80,8 @@ void enzo::nt::NetworkManager::setDisplayOp(OpId opId)
|
|||||||
cookOp(opId);
|
cookOp(opId);
|
||||||
|
|
||||||
enzo::nt::GeometryOperator& displayOp = getGeoOperator(opId);
|
enzo::nt::GeometryOperator& displayOp = getGeoOperator(opId);
|
||||||
updateDisplay(displayOp.getOutputGeo(0));
|
displayGeoChanged(displayOp.getOutputGeo(0));
|
||||||
displayNodeChanged();
|
displayNodeChanged(opId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void enzo::nt::NetworkManager::cookOp(enzo::nt::OpId opId)
|
void enzo::nt::NetworkManager::cookOp(enzo::nt::OpId opId)
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ public:
|
|||||||
GeometryOperator& getGeoOperator(nt::OpId opId);
|
GeometryOperator& getGeoOperator(nt::OpId opId);
|
||||||
void setDisplayOp(OpId opId);
|
void setDisplayOp(OpId opId);
|
||||||
|
|
||||||
boost::signals2::signal<void ()> displayNodeChanged;
|
boost::signals2::signal<void (nt::OpId)> displayNodeChanged;
|
||||||
|
boost::signals2::signal<void (enzo::geo::Geometry& geometry)> displayGeoChanged;
|
||||||
|
|
||||||
#ifdef UNIT_TEST
|
#ifdef UNIT_TEST
|
||||||
void _reset();
|
void _reset();
|
||||||
@@ -47,9 +48,6 @@ private:
|
|||||||
std::optional<OpId> displayOp_=std::nullopt;
|
std::optional<OpId> displayOp_=std::nullopt;
|
||||||
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void updateDisplay(enzo::geo::Geometry& geometry);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline enzo::nt::NetworkManager& nm() {
|
inline enzo::nt::NetworkManager& nm() {
|
||||||
|
|||||||
@@ -15,15 +15,19 @@ ga::Attribute::Attribute(std::string name, ga::AttributeType type)
|
|||||||
{
|
{
|
||||||
case(AttrType::intT):
|
case(AttrType::intT):
|
||||||
intStore_=std::make_shared<std::vector<bt::intT>>();
|
intStore_=std::make_shared<std::vector<bt::intT>>();
|
||||||
|
typeSize_=1;
|
||||||
break;
|
break;
|
||||||
case(AttrType::floatT):
|
case(AttrType::floatT):
|
||||||
floatStore_=std::make_shared<std::vector<bt::floatT>>();
|
floatStore_=std::make_shared<std::vector<bt::floatT>>();
|
||||||
|
typeSize_=1;
|
||||||
break;
|
break;
|
||||||
case(AttrType::vectorT):
|
case(AttrType::vectorT):
|
||||||
vector3Store_=std::make_shared<std::vector<enzo::bt::Vector3>>();
|
vector3Store_=std::make_shared<std::vector<enzo::bt::Vector3>>();
|
||||||
|
typeSize_=3;
|
||||||
break;
|
break;
|
||||||
case(AttrType::boolT):
|
case(AttrType::boolT):
|
||||||
boolStore_=std::make_shared<std::vector<enzo::bt::boolT>>();
|
boolStore_=std::make_shared<std::vector<enzo::bt::boolT>>();
|
||||||
|
typeSize_=1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("Type " + std::to_string(static_cast<int>(type_)) + " was not properly accounted for in Attribute constructor");
|
throw std::runtime_error("Type " + std::to_string(static_cast<int>(type_)) + " was not properly accounted for in Attribute constructor");
|
||||||
@@ -32,6 +36,13 @@ ga::Attribute::Attribute(std::string name, ga::AttributeType type)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int ga::Attribute::Attribute::getTypeSize() const
|
||||||
|
{
|
||||||
|
return typeSize_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ga::Attribute::Attribute(const Attribute& other)
|
ga::Attribute::Attribute(const Attribute& other)
|
||||||
{
|
{
|
||||||
type_ = other.type_;
|
type_ = other.type_;
|
||||||
@@ -39,6 +50,7 @@ ga::Attribute::Attribute(const Attribute& other)
|
|||||||
hidden_ = other.hidden_;
|
hidden_ = other.hidden_;
|
||||||
readOnly_ = other.readOnly_;
|
readOnly_ = other.readOnly_;
|
||||||
name_ = other.name_;
|
name_ = other.name_;
|
||||||
|
typeSize_ = other.typeSize_;
|
||||||
|
|
||||||
switch(type_)
|
switch(type_)
|
||||||
{
|
{
|
||||||
@@ -61,12 +73,12 @@ ga::Attribute::Attribute(const Attribute& other)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ga::AttributeType ga::Attribute::getType()
|
ga::AttributeType ga::Attribute::getType() const
|
||||||
{
|
{
|
||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ga::Attribute::getName()
|
std::string ga::Attribute::getName() const
|
||||||
{
|
{
|
||||||
return name_;
|
return name_;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,13 +21,16 @@ namespace enzo{
|
|||||||
public:
|
public:
|
||||||
Attribute(std::string name, ga::AttributeType type);
|
Attribute(std::string name, ga::AttributeType type);
|
||||||
Attribute(const Attribute& other);
|
Attribute(const Attribute& other);
|
||||||
AttributeType getType();
|
AttributeType getType() const;
|
||||||
std::string getName();
|
std::string getName() const;
|
||||||
|
unsigned int getTypeSize() const;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
friend class AttributeHandle;
|
friend class AttributeHandle;
|
||||||
|
template <typename T>
|
||||||
|
friend class AttributeHandleRO;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// private attributes are attributes that are hidden from the user
|
// private attributes are attributes that are hidden from the user
|
||||||
@@ -40,6 +43,7 @@ namespace enzo{
|
|||||||
bool readOnly_=false;
|
bool readOnly_=false;
|
||||||
|
|
||||||
ga::AttributeType type_;
|
ga::AttributeType type_;
|
||||||
|
unsigned int typeSize_=1;
|
||||||
|
|
||||||
std::string name_;
|
std::string name_;
|
||||||
|
|
||||||
|
|||||||
@@ -51,14 +51,15 @@ public:
|
|||||||
{
|
{
|
||||||
throw std::runtime_error("Type " + std::to_string(static_cast<int>(type_)) + " was not properly accounted for in AttributeHandle constructor");
|
throw std::runtime_error("Type " + std::to_string(static_cast<int>(type_)) + " was not properly accounted for in AttributeHandle constructor");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addValue(T value)
|
void addValue(T value)
|
||||||
{
|
{
|
||||||
// TODO:make this private (primitive friend classes only)
|
// TODO:make this private (primitive friend classes only)
|
||||||
data_->push_back(value);
|
data_->push_back(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void reserve(std::size_t newCap)
|
void reserve(std::size_t newCap)
|
||||||
{
|
{
|
||||||
data_->reserve(newCap);
|
data_->reserve(newCap);
|
||||||
@@ -118,4 +119,94 @@ using AttributeHandleFloat = AttributeHandle<bt::floatT>;
|
|||||||
using AttributeHandleVector3 = AttributeHandle<enzo::bt::Vector3>;
|
using AttributeHandleVector3 = AttributeHandle<enzo::bt::Vector3>;
|
||||||
using AttributeHandleBool = AttributeHandle<enzo::bt::boolT>;
|
using AttributeHandleBool = AttributeHandle<enzo::bt::boolT>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class AttributeHandleRO
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ga::AttributeType type_;
|
||||||
|
|
||||||
|
AttributeHandleRO(std::shared_ptr<const Attribute> attribute)
|
||||||
|
{
|
||||||
|
type_ = attribute->getType();
|
||||||
|
// get attribute data pointer
|
||||||
|
// TODO: check types match
|
||||||
|
// TODO: add the other types
|
||||||
|
|
||||||
|
// int
|
||||||
|
if constexpr (std::is_same<bt::intT, T>::value)
|
||||||
|
{
|
||||||
|
data_=attribute->intStore_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// float
|
||||||
|
else if constexpr (std::is_same<bt::floatT, T>::value)
|
||||||
|
{
|
||||||
|
data_=attribute->floatStore_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vector 3
|
||||||
|
else if constexpr (std::is_same<enzo::bt::Vector3, T>::value)
|
||||||
|
{
|
||||||
|
data_=attribute->vector3Store_;
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same<enzo::bt::boolT, T>::value)
|
||||||
|
{
|
||||||
|
data_=attribute->boolStore_;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Type " + std::to_string(static_cast<int>(type_)) + " was not properly accounted for in AttributeHandle constructor");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: replace with iterator
|
||||||
|
std::vector<T> getAllValues() const
|
||||||
|
{
|
||||||
|
return {data_->begin(), data_->end()};
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t getSize() const
|
||||||
|
{
|
||||||
|
return data_->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
T getValue(size_t pos) const
|
||||||
|
{
|
||||||
|
// TODO:protect against invalid positions
|
||||||
|
// TODO: cast types
|
||||||
|
return (*data_)[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getName() const
|
||||||
|
{
|
||||||
|
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<StoreContainer<T>> data_;
|
||||||
|
|
||||||
|
// int typeID_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
using AttributeHandleInt = AttributeHandle<bt::intT>;
|
||||||
|
using AttributeHandleFloat = AttributeHandle<bt::floatT>;
|
||||||
|
using AttributeHandleVector3 = AttributeHandle<enzo::bt::Vector3>;
|
||||||
|
using AttributeHandleBool = AttributeHandle<enzo::bt::boolT>;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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());
|
||||||
@@ -63,6 +93,36 @@ ga::Offset geo::Geometry::getNumSoloPoints() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// enzo::geo::attributeIterator geo::Geometry::attributesBegin(const ga::AttributeOwner owner)
|
||||||
|
// {
|
||||||
|
// return getAttributeStore(owner).begin();
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// enzo::geo::attributeIterator geo::Geometry::attributesEnd(const ga::AttributeOwner owner)
|
||||||
|
// {
|
||||||
|
// return getAttributeStore(owner).end();
|
||||||
|
// }
|
||||||
|
|
||||||
|
const size_t geo::Geometry::getNumAttributes(const ga::AttributeOwner owner) const
|
||||||
|
{
|
||||||
|
return getAttributeStore(owner).size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::weak_ptr<const ga::Attribute> geo::Geometry::getAttributeByIndex(ga::AttributeOwner owner, unsigned int index) const
|
||||||
|
{
|
||||||
|
auto attribStore = getAttributeStore(owner);
|
||||||
|
if(index>=attribStore.size())
|
||||||
|
{
|
||||||
|
throw std::out_of_range("Attribute index out of range: " + std::to_string(index) + " max size: " + std::to_string(attribStore.size()) + "\n");
|
||||||
|
}
|
||||||
|
return getAttributeStore(owner)[index];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::set<ga::Offset>::const_iterator geo::Geometry::soloPointsBegin()
|
std::set<ga::Offset>::const_iterator geo::Geometry::soloPointsBegin()
|
||||||
{
|
{
|
||||||
@@ -89,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);
|
||||||
@@ -220,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -265,7 +341,7 @@ ga::AttributeHandle<bt::Vector3> geo::Geometry::addVector3Attribute(ga::Attribut
|
|||||||
return ga::AttributeHandle<bt::Vector3>(newAttribute);
|
return ga::AttributeHandle<bt::Vector3>(newAttribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::shared_ptr<ga::Attribute>>& geo::Geometry::getAttributeStore(ga::AttributeOwner& owner)
|
geo::Geometry::attribVector& geo::Geometry::getAttributeStore(const ga::AttributeOwner& owner)
|
||||||
{
|
{
|
||||||
switch(owner)
|
switch(owner)
|
||||||
{
|
{
|
||||||
@@ -286,6 +362,26 @@ std::vector<std::shared_ptr<ga::Attribute>>& geo::Geometry::getAttributeStore(ga
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const geo::Geometry::attribVector& geo::Geometry::getAttributeStore(const ga::AttributeOwner& owner) const
|
||||||
|
{
|
||||||
|
switch(owner)
|
||||||
|
{
|
||||||
|
case ga::AttributeOwner::POINT:
|
||||||
|
return pointAttributes_;
|
||||||
|
break;
|
||||||
|
case ga::AttributeOwner::VERTEX:
|
||||||
|
return vertexAttributes_;
|
||||||
|
break;
|
||||||
|
case ga::AttributeOwner::PRIMITIVE:
|
||||||
|
return primitiveAttributes_;
|
||||||
|
break;
|
||||||
|
case ga::AttributeOwner::GLOBAL:
|
||||||
|
return globalAttributes_;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Unexpected, owner could not be found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<ga::Attribute> geo::Geometry::getAttribByName(ga::AttributeOwner owner, std::string name)
|
std::shared_ptr<ga::Attribute> geo::Geometry::getAttribByName(ga::AttributeOwner owner, std::string name)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
#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 "Engine/Operator/AttributeHandle.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <oneapi/tbb/spin_mutex.h>
|
||||||
|
#include <tbb/spin_mutex.h>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
|
|
||||||
@@ -19,16 +22,25 @@ using faceDescriptor = HeMesh::Face_index;
|
|||||||
using V_index = HeMesh::Vertex_index;
|
using V_index = HeMesh::Vertex_index;
|
||||||
using F_index = HeMesh::Face_index;
|
using F_index = HeMesh::Face_index;
|
||||||
|
|
||||||
|
using attributeIterator = std::vector<std::shared_ptr<ga::Attribute>>::iterator;
|
||||||
|
|
||||||
class Geometry
|
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);
|
||||||
// TODO: return weak ptr
|
// 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);
|
||||||
|
|
||||||
|
const size_t getNumAttributes(const ga::AttributeOwner owner) const;
|
||||||
|
std::weak_ptr<const ga::Attribute> getAttributeByIndex(ga::AttributeOwner owner, unsigned int index) const;
|
||||||
|
// attributeIterator attributesBegin(const ga::AttributeOwner owner);
|
||||||
|
// attributeIterator attributesEnd(const ga::AttributeOwner owner);
|
||||||
|
|
||||||
std::vector<bt::Vector3> derivePointNormals();
|
std::vector<bt::Vector3> derivePointNormals();
|
||||||
HeMesh computeHalfEdgeMesh();
|
HeMesh computeHalfEdgeMesh();
|
||||||
void addFace(std::vector<ga::Offset> pointOffsets, bool closed=true);
|
void addFace(std::vector<ga::Offset> pointOffsets, bool closed=true);
|
||||||
@@ -43,6 +55,7 @@ public:
|
|||||||
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 getVertexPrim(ga::Offset vertexOffset) const;
|
||||||
ga::Offset getNumPrims() const;
|
ga::Offset getNumPrims() const;
|
||||||
ga::Offset getNumVerts() const;
|
ga::Offset getNumVerts() const;
|
||||||
ga::Offset getNumPoints() const;
|
ga::Offset getNumPoints() const;
|
||||||
@@ -50,10 +63,11 @@ public:
|
|||||||
|
|
||||||
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>>;
|
||||||
attribVector& getAttributeStore(ga::AttributeOwner& owner);
|
geo::Geometry::attribVector& getAttributeStore(const ga::AttributeOwner& owner);
|
||||||
|
const geo::Geometry::attribVector& getAttributeStore(const ga::AttributeOwner& owner) const;
|
||||||
|
|
||||||
attribVector deepCopyAttributes(attribVector source);
|
attribVector deepCopyAttributes(attribVector source);
|
||||||
|
|
||||||
@@ -64,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_;
|
||||||
|
|||||||
@@ -124,6 +124,12 @@ std::vector<std::weak_ptr<prm::Parameter>> nt::GeometryOperator::getParameters()
|
|||||||
return {parameters_.begin(), parameters_.end()};
|
return {parameters_.begin(), parameters_.end()};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string nt::GeometryOperator::getLabel()
|
||||||
|
{
|
||||||
|
return getTypeName();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<std::weak_ptr<const nt::GeometryConnection>> nt::GeometryOperator::getOutputConnections() const
|
std::vector<std::weak_ptr<const nt::GeometryConnection>> nt::GeometryOperator::getOutputConnections() const
|
||||||
{
|
{
|
||||||
return {outputConnections_.begin(), outputConnections_.end()};
|
return {outputConnections_.begin(), outputConnections_.end()};
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ public:
|
|||||||
std::vector<std::weak_ptr<prm::Parameter>> getParameters();
|
std::vector<std::weak_ptr<prm::Parameter>> getParameters();
|
||||||
std::weak_ptr<prm::Parameter> getParameter(std::string parameterName);
|
std::weak_ptr<prm::Parameter> getParameter(std::string parameterName);
|
||||||
|
|
||||||
|
std::string getLabel(); // TODO: implement node labels
|
||||||
std::string getTypeName();
|
std::string getTypeName();
|
||||||
|
|
||||||
void dirtyNode(bool dirtyDescendents=true);
|
void dirtyNode(bool dirtyDescendents=true);
|
||||||
|
|||||||
161
src/Gui/GeometrySpreadsheetPanel/GeometrySpreadsheetMenuBar.cpp
Normal file
161
src/Gui/GeometrySpreadsheetPanel/GeometrySpreadsheetMenuBar.cpp
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
#include "Gui/GeometrySpreadsheetPanel/GeometrySpreadsheetMenuBar.h"
|
||||||
|
#include "Engine/Network/NetworkManager.h"
|
||||||
|
#include "Engine/Operator/GeometryOperator.h"
|
||||||
|
#include <QLabel>
|
||||||
|
#include <qpainter.h>
|
||||||
|
#include <qpushbutton.h>
|
||||||
|
#include <qwidget.h>
|
||||||
|
#include <QButtonGroup>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QPaintEvent>
|
||||||
|
#include <icecream.hpp>
|
||||||
|
|
||||||
|
GeoSheetModeButton::GeoSheetModeButton(QWidget* parent)
|
||||||
|
: QPushButton(parent)
|
||||||
|
{
|
||||||
|
setFixedSize(QSize(23,23));
|
||||||
|
setObjectName("GeoSheetModeButton");
|
||||||
|
setCheckable(true);
|
||||||
|
// setStyleSheet(
|
||||||
|
// R"(
|
||||||
|
// #GeoSheetModeButton
|
||||||
|
// {
|
||||||
|
// background: transparent;
|
||||||
|
// border: none;
|
||||||
|
// }
|
||||||
|
// #GeoSheetModeButton::checked
|
||||||
|
// {
|
||||||
|
// opacity: 50;
|
||||||
|
// border: none;
|
||||||
|
// }
|
||||||
|
// )");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeoSheetModeButton::enterEvent(QEnterEvent *event)
|
||||||
|
{
|
||||||
|
hovered_=true;
|
||||||
|
QPushButton::enterEvent(event);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeoSheetModeButton::leaveEvent(QEvent *event)
|
||||||
|
{
|
||||||
|
hovered_=false;
|
||||||
|
QPushButton::leaveEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeoSheetModeButton::paintEvent(QPaintEvent* event)
|
||||||
|
{
|
||||||
|
const QIcon buttonIcon = icon();
|
||||||
|
|
||||||
|
if(!buttonIcon.isNull())
|
||||||
|
{
|
||||||
|
QPainter painter(this);
|
||||||
|
|
||||||
|
QSize size = iconSize();
|
||||||
|
|
||||||
|
if(!isChecked())
|
||||||
|
{
|
||||||
|
painter.setOpacity(0.5);
|
||||||
|
}
|
||||||
|
if(hovered_)
|
||||||
|
{
|
||||||
|
size*=1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QPixmap pixmap = buttonIcon.pixmap(size);
|
||||||
|
QPoint center = rect().center() - QPoint(size.width() / 2, size.height() / 2);
|
||||||
|
painter.drawPixmap(center, pixmap);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GeoSheetMenuBarModeSelection::GeoSheetMenuBarModeSelection(QWidget *parent, Qt::WindowFlags f)
|
||||||
|
: QWidget(parent, f)
|
||||||
|
{
|
||||||
|
mainLayout_ = new QHBoxLayout();
|
||||||
|
constexpr int mainMargin = 0;
|
||||||
|
mainLayout_->setContentsMargins(mainMargin,mainMargin,mainMargin,mainMargin);
|
||||||
|
|
||||||
|
QWidget* buttonBg = new QWidget();
|
||||||
|
buttonBg->setObjectName("GeoSheetMenuBarButtonBg");
|
||||||
|
buttonBg->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
||||||
|
constexpr int bgSizeMargin = 5;
|
||||||
|
buttonBg->setContentsMargins(bgSizeMargin,0,bgSizeMargin,0);
|
||||||
|
buttonBg->setStyleSheet(
|
||||||
|
R"(
|
||||||
|
#GeoSheetMenuBarButtonBg
|
||||||
|
{
|
||||||
|
background-color: #242424;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
)");
|
||||||
|
QHBoxLayout* buttonBgLayout = new QHBoxLayout();
|
||||||
|
constexpr int margin = 0;
|
||||||
|
buttonBgLayout->setContentsMargins(margin,margin,margin,margin);
|
||||||
|
|
||||||
|
modeButtonGroup_.setExclusive(true);
|
||||||
|
|
||||||
|
auto newButton = [this, &buttonBgLayout](const char* tooltip="", const char* iconPath=":/icons/attributePoint.svg")
|
||||||
|
{
|
||||||
|
auto newButton = new GeoSheetModeButton();
|
||||||
|
newButton->setToolTip(tooltip);
|
||||||
|
newButton->setIcon(QIcon(iconPath));
|
||||||
|
modeButtonGroup_.addButton(newButton);
|
||||||
|
buttonBgLayout->addWidget(newButton);
|
||||||
|
return newButton;
|
||||||
|
};
|
||||||
|
|
||||||
|
pointButton = newButton("Point Attributes", ":/icons/attributePoint.svg");
|
||||||
|
vertexButton = newButton("Vertex Attributes", ":/icons/attributeVertex.svg");
|
||||||
|
primitiveButton = newButton("Primitive Attributes", ":/icons/attributePrimitive.svg");
|
||||||
|
globalButton = newButton("Global Attributes", ":/icons/attributeGlobal.svg");
|
||||||
|
|
||||||
|
pointButton->setChecked(true);
|
||||||
|
|
||||||
|
buttonBg->setLayout(buttonBgLayout);
|
||||||
|
|
||||||
|
mainLayout_->addWidget(buttonBg);
|
||||||
|
|
||||||
|
setLayout(mainLayout_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GeometrySpreadsheetMenuBar::GeometrySpreadsheetMenuBar(QWidget *parent, Qt::WindowFlags f)
|
||||||
|
: QWidget(parent, f)
|
||||||
|
{
|
||||||
|
mainLayout_ = new QHBoxLayout();
|
||||||
|
nodeLabel_ = new QLabel();
|
||||||
|
modeSelection = new GeoSheetMenuBarModeSelection();
|
||||||
|
|
||||||
|
mainLayout_->addWidget(nodeLabel_);
|
||||||
|
mainLayout_->addStretch();
|
||||||
|
mainLayout_->addWidget(modeSelection);
|
||||||
|
setProperty("class", "GeometrySpreadsheetMenuBar");
|
||||||
|
setStyleSheet(
|
||||||
|
R"(
|
||||||
|
.GeometrySpreadsheetMenuBar,
|
||||||
|
.GeometrySpreadsheetMenuBar *
|
||||||
|
{
|
||||||
|
background-color: #1B1B1B;
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
|
||||||
|
constexpr int margins = 5;
|
||||||
|
mainLayout_->setContentsMargins(margins, margins, margins, margins);
|
||||||
|
|
||||||
|
setLayout(mainLayout_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeometrySpreadsheetMenuBar::setNode(enzo::nt::OpId opId)
|
||||||
|
{
|
||||||
|
enzo::nt::GeometryOperator& geoOp = enzo::nt::nm().getGeoOperator(opId);
|
||||||
|
nodeLabel_->setText("<b>Node: </b>" + QString::fromStdString(geoOp.getLabel()));
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Engine/Operator/OpInfo.h"
|
||||||
|
#include "Engine/Types.h"
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <qbuttongroup.h>
|
||||||
|
#include <qpushbutton.h>
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
class GeoSheetModeButton
|
||||||
|
: public QPushButton
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GeoSheetModeButton(QWidget *parent = nullptr);
|
||||||
|
private:
|
||||||
|
QHBoxLayout* mainLayout_;
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *) override;
|
||||||
|
void enterEvent(QEnterEvent *event) override;
|
||||||
|
void leaveEvent(QEvent *event) override;
|
||||||
|
bool hovered_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GeoSheetMenuBarModeSelection
|
||||||
|
: public QWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GeoSheetMenuBarModeSelection(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
|
||||||
|
|
||||||
|
GeoSheetModeButton* pointButton;
|
||||||
|
GeoSheetModeButton* vertexButton;
|
||||||
|
GeoSheetModeButton* primitiveButton;
|
||||||
|
GeoSheetModeButton* globalButton;
|
||||||
|
private:
|
||||||
|
QHBoxLayout* mainLayout_;
|
||||||
|
QButtonGroup modeButtonGroup_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GeometrySpreadsheetMenuBar
|
||||||
|
: public QWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GeometrySpreadsheetMenuBar(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
|
||||||
|
GeoSheetMenuBarModeSelection* modeSelection;
|
||||||
|
void setNode(enzo::nt::OpId opId);
|
||||||
|
private:
|
||||||
|
QHBoxLayout* mainLayout_;
|
||||||
|
QLabel* nodeLabel_;
|
||||||
|
};
|
||||||
|
|
||||||
249
src/Gui/GeometrySpreadsheetPanel/GeometrySpreadsheetModel.cpp
Normal file
249
src/Gui/GeometrySpreadsheetPanel/GeometrySpreadsheetModel.cpp
Normal file
@@ -0,0 +1,249 @@
|
|||||||
|
#include "Gui/GeometrySpreadsheetPanel/GeometrySpreadsheetModel.h"
|
||||||
|
#include "Engine/Operator/Attribute.h"
|
||||||
|
#include "Engine/Operator/AttributeHandle.h"
|
||||||
|
#include "Engine/Operator/Geometry.h"
|
||||||
|
#include "Engine/Types.h"
|
||||||
|
#include <icecream.hpp>
|
||||||
|
#include <memory>
|
||||||
|
#include <qnamespace.h>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <QBrush>
|
||||||
|
|
||||||
|
|
||||||
|
GeometrySpreadsheetModel::GeometrySpreadsheetModel(QObject *parent)
|
||||||
|
: QAbstractListModel(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeometrySpreadsheetModel::geometryChanged(enzo::geo::Geometry& geometry)
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
geometry_ = geometry;
|
||||||
|
initBuffers();
|
||||||
|
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeometrySpreadsheetModel::initBuffers()
|
||||||
|
{
|
||||||
|
// get sizes
|
||||||
|
const auto attribCount = geometry_.getNumAttributes(attributeOwner_);
|
||||||
|
|
||||||
|
attribSizes_.clear();
|
||||||
|
sectionAttribMap_.clear();
|
||||||
|
attribSizes_.reserve(attribCount);
|
||||||
|
|
||||||
|
for(size_t i=0; i<attribCount; ++i)
|
||||||
|
{
|
||||||
|
if(auto attrib = geometry_.getAttributeByIndex(attributeOwner_, i).lock())
|
||||||
|
{
|
||||||
|
const auto size = attrib->getTypeSize();
|
||||||
|
attribSizes_.push_back(size);
|
||||||
|
|
||||||
|
for(size_t j=0; j<size; ++j)
|
||||||
|
{
|
||||||
|
sectionAttribMap_.push_back(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GeometrySpreadsheetModel::setOwner(const enzo::ga::AttributeOwner owner)
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
attributeOwner_ = owner;
|
||||||
|
initBuffers();
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
int GeometrySpreadsheetModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
switch(attributeOwner_)
|
||||||
|
{
|
||||||
|
case enzo::ga::AttributeOwner::POINT:
|
||||||
|
{
|
||||||
|
return geometry_.getNumPoints();
|
||||||
|
}
|
||||||
|
case enzo::ga::AttributeOwner::VERTEX:
|
||||||
|
{
|
||||||
|
return geometry_.getNumVerts();
|
||||||
|
}
|
||||||
|
case enzo::ga::AttributeOwner::PRIMITIVE:
|
||||||
|
{
|
||||||
|
return geometry_.getNumPrims();
|
||||||
|
}
|
||||||
|
case enzo::ga::AttributeOwner::GLOBAL:
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GeometrySpreadsheetModel::columnCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
|
||||||
|
int columnCount = attributeColumnPadding_; // first column is for indices
|
||||||
|
for(auto size : attribSizes_)
|
||||||
|
{
|
||||||
|
columnCount += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return columnCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QVariant GeometrySpreadsheetModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
{
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: reimplement check
|
||||||
|
// if (index.row() >= geometry_.getNumPoints())
|
||||||
|
// {
|
||||||
|
// return QVariant();
|
||||||
|
// }
|
||||||
|
|
||||||
|
if(role == Qt::BackgroundRole && index.column()==0)
|
||||||
|
{
|
||||||
|
return QBrush("#1B1B1B");
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (role == Qt::DisplayRole)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(index.column()==0)
|
||||||
|
{
|
||||||
|
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())
|
||||||
|
{
|
||||||
|
const unsigned int valueIndex = index.column()-attributeIndex-attributeColumnPadding_;
|
||||||
|
using namespace enzo::ga;
|
||||||
|
|
||||||
|
switch(attrib->getType())
|
||||||
|
{
|
||||||
|
case(AttributeType::intT):
|
||||||
|
{
|
||||||
|
const auto attribHandle = enzo::ga::AttributeHandleRO<enzo::bt::intT>(attrib);
|
||||||
|
return static_cast<float>(attribHandle.getValue(index.row()));
|
||||||
|
}
|
||||||
|
case(AttributeType::floatT):
|
||||||
|
{
|
||||||
|
const auto attribHandle = enzo::ga::AttributeHandleRO<enzo::bt::floatT>(attrib);
|
||||||
|
return attribHandle.getValue(index.row());
|
||||||
|
}
|
||||||
|
case(AttributeType::boolT):
|
||||||
|
{
|
||||||
|
const auto attribHandle = enzo::ga::AttributeHandleRO<enzo::bt::boolT>(attrib);
|
||||||
|
return attribHandle.getValue(index.row()) ? "true" : "false";
|
||||||
|
}
|
||||||
|
case(AttributeType::vectorT):
|
||||||
|
{
|
||||||
|
const auto attribHandle = enzo::ga::AttributeHandleRO<enzo::bt::Vector3>(attrib);
|
||||||
|
return attribHandle.getValue(index.row())[valueIndex];
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
return "Failed";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Couldn't lock attribute");
|
||||||
|
}
|
||||||
|
// return geometry_.getPointPos(index.row()).x();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int GeometrySpreadsheetModel::indexFromSection(unsigned int section) const
|
||||||
|
{
|
||||||
|
if(section>=sectionAttribMap_.size())
|
||||||
|
{
|
||||||
|
throw std::out_of_range("Section is out of range of sectionAttributMap_, value: " + std::to_string(section) + " expected: <"+std::to_string(sectionAttribMap_.size()));
|
||||||
|
}
|
||||||
|
return sectionAttribMap_[section];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QVariant GeometrySpreadsheetModel::headerData(int section, Qt::Orientation orientation,
|
||||||
|
int role) const
|
||||||
|
{
|
||||||
|
if (role != Qt::DisplayRole)
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
if (orientation == Qt::Horizontal)
|
||||||
|
{
|
||||||
|
if(section==0) return "Index";
|
||||||
|
auto attributeIndex = indexFromSection(section-attributeColumnPadding_);
|
||||||
|
if(auto attrib = geometry_.getAttributeByIndex(attributeOwner_, attributeIndex).lock())
|
||||||
|
{
|
||||||
|
if(attribSizes_[attributeIndex]>1)
|
||||||
|
{
|
||||||
|
const unsigned int valueIndex = section-attributeIndex-attributeColumnPadding_;
|
||||||
|
|
||||||
|
std::string valueIndexString;
|
||||||
|
if(attrib->getType()==enzo::ga::AttrType::vectorT)
|
||||||
|
{
|
||||||
|
valueIndexString = std::array{".x", ".y", ".z", ".w"}.at(valueIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
valueIndexString = "["+std::to_string(valueIndex)+"]";
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString::fromStdString(attrib->getName() + valueIndexString);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return QString::fromStdString(attrib->getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error("failed to lock attriubte index");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return QStringLiteral("Row %1").arg(section);
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/Gui/GeometrySpreadsheetPanel/GeometrySpreadsheetModel.h
Normal file
35
src/Gui/GeometrySpreadsheetPanel/GeometrySpreadsheetModel.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
#include "Engine/Types.h"
|
||||||
|
#include "Engine/Operator/Geometry.h"
|
||||||
|
|
||||||
|
class GeometrySpreadsheetModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
GeometrySpreadsheetModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
QVariant data(const QModelIndex &index, int role) const override;
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation,
|
||||||
|
int role = Qt::DisplayRole) const override;
|
||||||
|
int indexFromSection(unsigned int section) const;
|
||||||
|
|
||||||
|
void geometryChanged(enzo::geo::Geometry& geometry);
|
||||||
|
void setOwner(const enzo::ga::AttributeOwner owner);
|
||||||
|
void initBuffers();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
enzo::nt::OpId opId_;
|
||||||
|
enzo::geo::Geometry geometry_;
|
||||||
|
std::vector<unsigned int> attribSizes_;
|
||||||
|
std::vector<unsigned int> sectionAttribMap_;
|
||||||
|
const int attributeColumnPadding_ = 1;
|
||||||
|
enzo::ga::AttributeOwner attributeOwner_=enzo::ga::AttributeOwner::POINT;
|
||||||
|
|
||||||
|
};
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
#include "Gui/GeometrySpreadsheetPanel/GeometrySpreadsheetPanel.h"
|
||||||
|
#include "Gui/GeometrySpreadsheetPanel/GeometrySpreadsheetMenuBar.h"
|
||||||
|
#include "Gui/GeometrySpreadsheetPanel/GeometrySpreadsheetModel.h"
|
||||||
|
#include "Engine/Network/NetworkManager.h"
|
||||||
|
#include <QTableWidget>
|
||||||
|
#include <QTreeWidget>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <qframe.h>
|
||||||
|
#include <qpushbutton.h>
|
||||||
|
#include <qtablewidget.h>
|
||||||
|
#include <QPainterPath>
|
||||||
|
|
||||||
|
GeometrySpreadsheetPanel::GeometrySpreadsheetPanel(QWidget *parent, Qt::WindowFlags f)
|
||||||
|
: QWidget(parent, f)
|
||||||
|
{
|
||||||
|
mainLayout_ = new QVBoxLayout();
|
||||||
|
mainLayout_->setSpacing(0);
|
||||||
|
|
||||||
|
|
||||||
|
view_ = new QTreeView(parent);
|
||||||
|
view_->setRootIsDecorated(false);
|
||||||
|
view_->setAlternatingRowColors(true);
|
||||||
|
view_->setUniformRowHeights(true); // improves performance
|
||||||
|
view_->setStyleSheet(R"(
|
||||||
|
QTreeView {
|
||||||
|
background-color: #282828;
|
||||||
|
alternate-background-color: #242424;
|
||||||
|
paint-alternating-row-colors-for-empty-area: 1;
|
||||||
|
}
|
||||||
|
QTreeView QScrollBar {
|
||||||
|
background: #1B1B1B;
|
||||||
|
width: 15px;
|
||||||
|
}
|
||||||
|
QTreeView QScrollBar::handle:vertical {
|
||||||
|
background: #282828;
|
||||||
|
min-height: 50px;
|
||||||
|
border-radius: 5px;
|
||||||
|
border-width: 1px;
|
||||||
|
border-color: #2D2D2D;
|
||||||
|
border-style: solid;
|
||||||
|
margin:2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTreeView QScrollBar::add-page:vertical,
|
||||||
|
QTreeView QScrollBar::sub-page:vertical,
|
||||||
|
QTreeView QScrollBar::add-line:vertical,
|
||||||
|
QTreeView QScrollBar::sub-line:vertical
|
||||||
|
{ height: 0px; }
|
||||||
|
|
||||||
|
QHeaderView::section {
|
||||||
|
background-color: #1B1B1B;
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
view_->setFrameStyle(QFrame::NoFrame);
|
||||||
|
|
||||||
|
model_ = new GeometrySpreadsheetModel();
|
||||||
|
view_->setModel(model_);
|
||||||
|
|
||||||
|
menuBar_ = new GeometrySpreadsheetMenuBar();
|
||||||
|
// connect buttons
|
||||||
|
connect(menuBar_->modeSelection->pointButton, &QPushButton::clicked, this, [this](){model_->setOwner(enzo::ga::AttributeOwner::POINT);});
|
||||||
|
connect(menuBar_->modeSelection->vertexButton, &QPushButton::clicked, this, [this](){model_->setOwner(enzo::ga::AttributeOwner::VERTEX);});
|
||||||
|
connect(menuBar_->modeSelection->primitiveButton, &QPushButton::clicked, this, [this](){model_->setOwner(enzo::ga::AttributeOwner::PRIMITIVE);});
|
||||||
|
connect(menuBar_->modeSelection->globalButton, &QPushButton::clicked, this, [this](){model_->setOwner(enzo::ga::AttributeOwner::GLOBAL);});
|
||||||
|
// set default
|
||||||
|
menuBar_->modeSelection->pointButton->click();
|
||||||
|
|
||||||
|
|
||||||
|
mainLayout_->addWidget(menuBar_);
|
||||||
|
mainLayout_->addWidget(view_);
|
||||||
|
|
||||||
|
setLayout(mainLayout_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeometrySpreadsheetPanel::setNode(enzo::nt::OpId opId)
|
||||||
|
{
|
||||||
|
menuBar_->setNode(opId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GeometrySpreadsheetPanel::geometryChanged(enzo::geo::Geometry& geometry)
|
||||||
|
{
|
||||||
|
model_->geometryChanged(geometry);
|
||||||
|
view_->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeometrySpreadsheetPanel::resizeEvent(QResizeEvent *event)
|
||||||
|
{
|
||||||
|
QPainterPath path;
|
||||||
|
constexpr float radius = 10;
|
||||||
|
path.addRoundedRect(mainLayout_->contentsRect(), radius, radius);
|
||||||
|
QRegion region = QRegion(path.toFillPolygon().toPolygon());
|
||||||
|
this->setMask(region);
|
||||||
|
}
|
||||||
|
|
||||||
28
src/Gui/GeometrySpreadsheetPanel/GeometrySpreadsheetPanel.h
Normal file
28
src/Gui/GeometrySpreadsheetPanel/GeometrySpreadsheetPanel.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <qtreeview.h>
|
||||||
|
#include "Engine/Types.h"
|
||||||
|
#include "Gui/GeometrySpreadsheetPanel/GeometrySpreadsheetModel.h"
|
||||||
|
#include "Gui/GeometrySpreadsheetPanel/GeometrySpreadsheetMenuBar.h"
|
||||||
|
|
||||||
|
class GeometrySpreadsheetPanel
|
||||||
|
: public QWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GeometrySpreadsheetPanel(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
|
||||||
|
public Q_SLOTS:
|
||||||
|
void geometryChanged(enzo::geo::Geometry& geometry);
|
||||||
|
void setNode(enzo::nt::OpId opId);
|
||||||
|
private:
|
||||||
|
QVBoxLayout* mainLayout_;
|
||||||
|
QWidget* bgWidget_;
|
||||||
|
GeometrySpreadsheetModel* model_;
|
||||||
|
QTreeView* view_;
|
||||||
|
GeometrySpreadsheetMenuBar* menuBar_;
|
||||||
|
protected:
|
||||||
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "Gui/Interface.h"
|
#include "Gui/Interface.h"
|
||||||
#include "Engine/Network/NetworkManager.h"
|
#include "Engine/Network/NetworkManager.h"
|
||||||
|
#include "Engine/Operator/Geometry.h"
|
||||||
|
#include "Gui/GeometrySpreadsheetPanel/GeometrySpreadsheetPanel.h"
|
||||||
#include "Gui/ParametersPanel/ParametersPanel.h"
|
#include "Gui/ParametersPanel/ParametersPanel.h"
|
||||||
#include "Gui/Viewport/Viewport.h"
|
#include "Gui/Viewport/Viewport.h"
|
||||||
#include "Gui/Network/Network.h"
|
#include "Gui/Network/Network.h"
|
||||||
@@ -8,6 +10,7 @@
|
|||||||
#include <qsplitter.h>
|
#include <qsplitter.h>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <Gui/UtilWidgets/Splitter.h>
|
#include <Gui/UtilWidgets/Splitter.h>
|
||||||
|
#include <icecream.hpp>
|
||||||
|
|
||||||
EnzoUI::EnzoUI()
|
EnzoUI::EnzoUI()
|
||||||
{
|
{
|
||||||
@@ -26,35 +29,41 @@ EnzoUI::EnzoUI()
|
|||||||
Viewport* viewport = new Viewport();
|
Viewport* viewport = new Viewport();
|
||||||
Network* network = new Network();
|
Network* network = new Network();
|
||||||
ParametersPanel* parametersPanel = new ParametersPanel();
|
ParametersPanel* parametersPanel = new ParametersPanel();
|
||||||
|
GeometrySpreadsheetPanel* geometrySpreadsheetPanel = new GeometrySpreadsheetPanel();
|
||||||
|
|
||||||
constexpr int margin = 2;
|
constexpr int margin = 2;
|
||||||
viewport->layout()->setContentsMargins(margin, margin, margin, margin);
|
viewport->layout()->setContentsMargins(margin, margin, margin, margin);
|
||||||
network->layout()->setContentsMargins(margin, margin, margin, margin);
|
network->layout()->setContentsMargins(margin, margin, margin, margin);
|
||||||
parametersPanel->layout()->setContentsMargins(margin, margin, margin, margin);
|
parametersPanel->layout()->setContentsMargins(margin, margin, margin, margin);
|
||||||
|
geometrySpreadsheetPanel->layout()->setContentsMargins(margin, margin, margin, margin);
|
||||||
mainLayout_->setContentsMargins(margin, margin, margin, margin);
|
mainLayout_->setContentsMargins(margin, margin, margin, margin);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: dynamic splitters
|
||||||
viewportSplitter_ = new Splitter(this);
|
viewportSplitter_ = new Splitter(this);
|
||||||
networkSplitter_ = new Splitter(this);
|
networkSplitter_ = new Splitter(this);
|
||||||
|
spreadsheetSplitter_ = new Splitter(this);
|
||||||
networkSplitter_->setOrientation(Qt::Vertical);
|
networkSplitter_->setOrientation(Qt::Vertical);
|
||||||
|
spreadsheetSplitter_->setOrientation(Qt::Vertical);
|
||||||
|
|
||||||
|
spreadsheetSplitter_->addWidget(viewport);
|
||||||
|
spreadsheetSplitter_->addWidget(geometrySpreadsheetPanel);
|
||||||
|
spreadsheetSplitter_->setSizes({200,100});
|
||||||
|
|
||||||
|
viewportSplitter_->addWidget(spreadsheetSplitter_);
|
||||||
viewportSplitter_->addWidget(viewport);
|
|
||||||
viewportSplitter_->addWidget(networkSplitter_);
|
viewportSplitter_->addWidget(networkSplitter_);
|
||||||
viewportSplitter_->setStretchFactor(0, 4);
|
viewportSplitter_->setSizes({100,200});
|
||||||
viewportSplitter_->setStretchFactor(1, 1);
|
|
||||||
|
|
||||||
networkSplitter_->addWidget(parametersPanel);
|
networkSplitter_->addWidget(parametersPanel);
|
||||||
networkSplitter_->addWidget(network);
|
networkSplitter_->addWidget(network);
|
||||||
networkSplitter_->setStretchFactor(0, 10);
|
networkSplitter_->setSizes({40,100});
|
||||||
networkSplitter_->setStretchFactor(1, 1);
|
|
||||||
|
|
||||||
mainLayout_->addWidget(viewportSplitter_);
|
mainLayout_->addWidget(viewportSplitter_);
|
||||||
|
|
||||||
// connect signals
|
// connect signals
|
||||||
connect(&enzo::nt::nm(), &enzo::nt::NetworkManager::updateDisplay, viewport, &Viewport::geometryChanged);
|
enzo::nt::nm().displayNodeChanged.connect([parametersPanel](enzo::nt::OpId opId){parametersPanel->selectionChanged(opId);});
|
||||||
enzo::nt::nm().displayNodeChanged.connect([parametersPanel](){parametersPanel->selectionChanged();});
|
enzo::nt::nm().displayNodeChanged.connect([geometrySpreadsheetPanel](enzo::nt::OpId opId){geometrySpreadsheetPanel->setNode(opId);});
|
||||||
// connect(&enzo::nt::nm(), &enzo::nt::NetworkManager::updateDisplay, parametersPanel, &ParametersPanel::selectionChanged);
|
enzo::nt::nm().displayGeoChanged.connect([geometrySpreadsheetPanel](enzo::geo::Geometry& geometry){geometrySpreadsheetPanel->geometryChanged(geometry);});
|
||||||
|
enzo::nt::nm().displayGeoChanged.connect([viewport](enzo::geo::Geometry& geometry){viewport->setGeometry(geometry);});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class EnzoUI
|
|||||||
QVBoxLayout* viewportSplitLayout_;
|
QVBoxLayout* viewportSplitLayout_;
|
||||||
Splitter* viewportSplitter_;
|
Splitter* viewportSplitter_;
|
||||||
Splitter* networkSplitter_;
|
Splitter* networkSplitter_;
|
||||||
|
Splitter* spreadsheetSplitter_;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -36,13 +36,11 @@ ParametersPanel::ParametersPanel(QWidget *parent, Qt::WindowFlags f)
|
|||||||
setLayout(mainLayout_);
|
setLayout(mainLayout_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParametersPanel::selectionChanged()
|
void ParametersPanel::selectionChanged(enzo::nt::OpId opId)
|
||||||
{
|
{
|
||||||
using namespace enzo;
|
using namespace enzo;
|
||||||
enzo::nt::NetworkManager& nm = enzo::nt::nm();
|
enzo::nt::NetworkManager& nm = enzo::nt::nm();
|
||||||
std::optional<enzo::nt::OpId> displayOpId = nm.getDisplayOp();
|
const enzo::nt::OpId displayOpId = opId;
|
||||||
|
|
||||||
if(!displayOpId.has_value()) return;
|
|
||||||
|
|
||||||
// clear layout safely
|
// clear layout safely
|
||||||
QLayoutItem *child;
|
QLayoutItem *child;
|
||||||
@@ -51,7 +49,7 @@ void ParametersPanel::selectionChanged()
|
|||||||
delete child;
|
delete child;
|
||||||
}
|
}
|
||||||
|
|
||||||
enzo::nt::GeometryOperator& displayOp = nm.getGeoOperator(displayOpId.value());
|
enzo::nt::GeometryOperator& displayOp = nm.getGeoOperator(displayOpId);
|
||||||
auto parameters = displayOp.getParameters();
|
auto parameters = displayOp.getParameters();
|
||||||
|
|
||||||
std::vector<enzo::ui::AbstractFormParm*> parameterWidgets;
|
std::vector<enzo::ui::AbstractFormParm*> parameterWidgets;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
#include "Engine/Types.h"
|
||||||
|
|
||||||
class ParametersPanel
|
class ParametersPanel
|
||||||
: public QWidget
|
: public QWidget
|
||||||
@@ -9,7 +10,7 @@ class ParametersPanel
|
|||||||
public:
|
public:
|
||||||
ParametersPanel(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
|
ParametersPanel(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void selectionChanged();
|
void selectionChanged(enzo::nt::OpId opId);
|
||||||
private:
|
private:
|
||||||
QVBoxLayout* mainLayout_;
|
QVBoxLayout* mainLayout_;
|
||||||
QVBoxLayout* parametersLayout_;
|
QVBoxLayout* parametersLayout_;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ Viewport::Viewport(QWidget *parent, Qt::WindowFlags f)
|
|||||||
this->setLayout(mainLayout_);
|
this->setLayout(mainLayout_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewport::geometryChanged(enzo::geo::Geometry& geometry)
|
void Viewport::setGeometry(enzo::geo::Geometry& geometry)
|
||||||
{
|
{
|
||||||
openGLWidget_->geometryChanged(geometry);
|
openGLWidget_->geometryChanged(geometry);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ class Viewport
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Viewport(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
|
Viewport(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
|
||||||
|
void setGeometry(enzo::geo::Geometry& geometry);
|
||||||
private:
|
private:
|
||||||
QVBoxLayout* mainLayout_;
|
QVBoxLayout* mainLayout_;
|
||||||
ViewportGLWidget* openGLWidget_;
|
ViewportGLWidget* openGLWidget_;
|
||||||
@@ -23,6 +24,4 @@ private:
|
|||||||
QPointF leftStartPos_;
|
QPointF leftStartPos_;
|
||||||
bool rightMouseDown_=false;
|
bool rightMouseDown_=false;
|
||||||
QPointF rightStartPos_;
|
QPointF rightStartPos_;
|
||||||
public Q_SLOTS:
|
|
||||||
void geometryChanged(enzo::geo::Geometry& geometry);
|
|
||||||
};
|
};
|
||||||
|
|||||||
76
static/icons/attributeBase.svg
Normal file
76
static/icons/attributeBase.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 18 KiB |
76
static/icons/attributeGlobal.svg
Normal file
76
static/icons/attributeGlobal.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 18 KiB |
81
static/icons/attributePoint.svg
Normal file
81
static/icons/attributePoint.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 18 KiB |
76
static/icons/attributePrimitive.svg
Normal file
76
static/icons/attributePrimitive.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 18 KiB |
121
static/icons/attributeVertex.svg
Normal file
121
static/icons/attributeVertex.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 20 KiB |
@@ -1,5 +1,10 @@
|
|||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
<file>node-icons/grid.svg</file>
|
<file>node-icons/grid.svg</file>
|
||||||
|
<file>icons/attributePoint.svg</file>
|
||||||
|
<file>icons/attributeVertex.svg</file>
|
||||||
|
<file>icons/attributePrimitive.svg</file>
|
||||||
|
<file>icons/attributeGlobal.svg</file>
|
||||||
|
<file>icons/attributeBase.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
Reference in New Issue
Block a user