#include "Engine/Operator/Geometry.h" #include "Engine/Operator/Attribute.h" #include "Engine/Operator/AttributeHandle.h" #include "Engine/Types.h" #include #include #include #include #include #include "icecream.hpp" using namespace enzo; geo::Geometry::Geometry() : vertexCountHandlePrim_{addIntAttribute(ga::AttrOwner::PRIMITIVE, "vertexCount")}, closedHandlePrim_{addBoolAttribute(ga::AttrOwner::PRIMITIVE, "closed")}, pointOffsetHandleVert_{addIntAttribute(ga::AttrOwner::VERTEX, "point")}, posHandlePoint_{addVector3Attribute(ga::AttrOwner::POINT, "P")} { } geo::Geometry::Geometry(const Geometry& other): // attributes pointAttributes_{deepCopyAttributes(other.pointAttributes_)}, vertexAttributes_{deepCopyAttributes(other.vertexAttributes_)}, primitiveAttributes_{deepCopyAttributes(other.primitiveAttributes_)}, globalAttributes_{deepCopyAttributes(other.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_{other.soloPoints_} { } void geo::Geometry::addFace(std::vector pointOffsets, bool closed) { for(ga::Offset pointOffset : pointOffsets) { pointOffsetHandleVert_.addValue(pointOffset); soloPoints_.erase(pointOffset); } vertexCountHandlePrim_.addValue(pointOffsets.size()); closedHandlePrim_.addValue(closed); } void geo::Geometry::addPoint(const bt::Vector3& pos) { posHandlePoint_.addValue(pos); soloPoints_.emplace(posHandlePoint_.getSize()-1); } ga::Offset geo::Geometry::getNumSoloPoints() const { return soloPoints_.size(); } std::set::const_iterator geo::Geometry::soloPointsBegin() { return soloPoints_.begin(); } std::set::const_iterator geo::Geometry::soloPointsEnd() { return soloPoints_.end(); } 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); } void geo::Geometry::setPointPos(const ga::Offset offset, const bt::Vector3& pos) { posHandlePoint_.setValue(offset, pos); } 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(); } ga::Offset geo::Geometry::getNumPoints() const { return posHandlePoint_.getSize(); } 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 sourceAttrib : originalVector) { if(sourceAttrib) { copied.push_back(std::make_shared(*sourceAttrib)); } else { copied.push_back(nullptr); } } return copied; } enzo::geo::HeMesh geo::Geometry::computeHalfEdgeMesh() { HeMesh heMesh; std::shared_ptr PAttr = getAttribByName(enzo::ga::AttrOwner::POINT, "P"); enzo::ga::AttributeHandleVector3 PAttrHandle = enzo::ga::AttributeHandleVector3(PAttr); auto pointPositions = PAttrHandle.getAllValues(); std::shared_ptr pointAttr = getAttribByName(enzo::ga::AttrOwner::VERTEX, "point"); enzo::ga::AttributeHandleInt pointAttrHandle = enzo::ga::AttributeHandleInt(pointAttr); auto vertexPointIndices = pointAttrHandle.getAllValues(); std::shared_ptr vertexCountAttr = getAttribByName(enzo::ga::AttrOwner::PRIMITIVE, "vertexCount"); enzo::ga::AttributeHandleInt vertexCountHandle = enzo::ga::AttributeHandleInt(vertexCountAttr); auto vertexCounts = vertexCountHandle.getAllValues(); int vertexIndex = 0; std::vector createdPoints; createdPoints.reserve(pointPositions.size()); std::vector facePoints; facePoints.reserve(16); for(auto pointPos : pointPositions) { enzo::geo::vertexDescriptor point = heMesh.add_vertex(geo::Point(pointPos.x(), pointPos.y(), pointPos.z())); createdPoints.push_back(point); } CGAL::Polygon_mesh_processing::orient(heMesh); // iterate through each prim for(int primIndx=0; primIndx(name, ga::AttrType::intT); getAttributeStore(owner).push_back(newAttribute); return ga::AttributeHandleInt(newAttribute); } ga::AttributeHandleBool geo::Geometry::addBoolAttribute(ga::AttributeOwner owner, std::string name) { auto newAttribute = std::make_shared(name, ga::AttrType::boolT); getAttributeStore(owner).push_back(newAttribute); return ga::AttributeHandleBool(newAttribute); } bt::boolT geo::Geometry::isClosed(ga::Offset primOffset) const { return closedHandlePrim_.getValue(primOffset); } ga::AttributeHandle geo::Geometry::addVector3Attribute(ga::AttributeOwner owner, std::string name) { auto newAttribute = std::make_shared(name, ga::AttrType::vectorT); getAttributeStore(owner).push_back(newAttribute); return ga::AttributeHandle(newAttribute); } std::vector>& geo::Geometry::getAttributeStore(ga::AttributeOwner& owner) { 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 geo::Geometry::getAttribByName(ga::AttributeOwner owner, std::string name) { auto& vector = getAttributeStore(owner); for(auto it=vector.begin(); it!=vector.end(); ++it) { if((*it)->getName()==name) { return (*it); } } return nullptr; }