diff --git a/include/polyscope/render/managed_buffer.h b/include/polyscope/render/managed_buffer.h index ccaefb87..594b6b3d 100644 --- a/include/polyscope/render/managed_buffer.h +++ b/include/polyscope/render/managed_buffer.h @@ -178,6 +178,12 @@ class ManagedBuffer : public virtual WeakReferrable { // same view will be returned repeatedly at no additional cost. std::shared_ptr getIndexedRenderAttributeBuffer(ManagedBuffer& indices); + // Get a copy of the data viewed through an index, such that view[i] = data[indices[i]]. + // + // This follows the same logic as above, but rather than returning a render buffer it simply returns a host-side + // copy (which is not cached). + std::vector getIndexedView(ManagedBuffer& indices); + // ======================================================================== // == Direct access to the GPU (device-side) render texture buffer // ======================================================================== diff --git a/include/polyscope/surface_parameterization_quantity.h b/include/polyscope/surface_parameterization_quantity.h index 8e90c47d..957bac4a 100644 --- a/include/polyscope/surface_parameterization_quantity.h +++ b/include/polyscope/surface_parameterization_quantity.h @@ -48,6 +48,7 @@ class SurfaceParameterizationQuantity : public SurfaceMeshQuantity, void createProgram(); size_t nFaces(); // works around an incomplete def of the parent mesh virtual void fillCoordBuffers(render::ShaderProgram& p) = 0; + virtual std::vector getCornerCoords() = 0; }; @@ -66,6 +67,7 @@ class SurfaceCornerParameterizationQuantity : public SurfaceParameterizationQuan protected: virtual void fillCoordBuffers(render::ShaderProgram& p) override; + virtual std::vector getCornerCoords() override; }; @@ -84,6 +86,7 @@ class SurfaceVertexParameterizationQuantity : public SurfaceParameterizationQuan protected: virtual void fillCoordBuffers(render::ShaderProgram& p) override; + virtual std::vector getCornerCoords() override; }; diff --git a/src/render/managed_buffer.cpp b/src/render/managed_buffer.cpp index b8287ff7..35317b12 100644 --- a/src/render/managed_buffer.cpp +++ b/src/render/managed_buffer.cpp @@ -392,6 +392,14 @@ ManagedBuffer::getIndexedRenderAttributeBuffer(ManagedBuffer& indic return newBuffer; } +template +std::vector ManagedBuffer::getIndexedView(ManagedBuffer& indices) { + checkDeviceBufferTypeIs(DeviceBufferType::Attribute); + ensureHostBufferPopulated(); + indices.ensureHostBufferPopulated(); + return gather(data, indices.data); +} + template void ManagedBuffer::updateIndexedViews() { checkDeviceBufferTypeIs(DeviceBufferType::Attribute); diff --git a/src/surface_parameterization_quantity.cpp b/src/surface_parameterization_quantity.cpp index fc7b8a44..11945be6 100644 --- a/src/surface_parameterization_quantity.cpp +++ b/src/surface_parameterization_quantity.cpp @@ -109,12 +109,14 @@ CurveNetwork* SurfaceParameterizationQuantity::createCurveNetworkFromSeams(std:: } // Populate data on the host - coords.ensureHostBufferPopulated(); parent.triangleCornerInds.ensureHostBufferPopulated(); parent.triangleVertexInds.ensureHostBufferPopulated(); parent.edgeIsReal.ensureHostBufferPopulated(); parent.vertexPositions.ensureHostBufferPopulated(); + // expand out the coords buffer based on how the quantity is indexed + std::vector cornerCoords = getCornerCoords(); + // helper to canonicalize edge direction auto canonicalizeEdge = [](std::pair& inds, std::pair& coords) { @@ -141,7 +143,7 @@ CurveNetwork* SurfaceParameterizationQuantity::createCurveNetworkFromSeams(std:: int32_t iC_tail = parent.triangleCornerInds.data[3*iT + (k+0)%3]; int32_t iC_tip = parent.triangleCornerInds.data[3*iT + (k+1)%3]; std::pair eInd (iV_tail, iV_tip); - std::pair eC (coords.data[iC_tail], coords.data[iC_tip]); + std::pair eC (cornerCoords[iC_tail], cornerCoords[iC_tip]); canonicalizeEdge(eInd, eC); // make sure ordering is consistent // increment the count @@ -178,7 +180,7 @@ CurveNetwork* SurfaceParameterizationQuantity::createCurveNetworkFromSeams(std:: for(const std::pair& edge: seamEdges) { int32_t vA = edge.first; int32_t vB = edge.second; - + // get unique vertices for the edges if(vertexIndToDense.find(vA) == vertexIndToDense.end()) { vertexIndToDense[vA] = seamEdgeNodes.size(); @@ -196,7 +198,6 @@ CurveNetwork* SurfaceParameterizationQuantity::createCurveNetworkFromSeams(std:: } // add the curve network - return registerCurveNetwork(structureName, seamEdgeNodes, seamEdgeInds); } @@ -227,6 +228,11 @@ void SurfaceCornerParameterizationQuantity::fillCoordBuffers(render::ShaderProgr p.setAttribute("a_value2", coords.getIndexedRenderAttributeBuffer(parent.triangleCornerInds)); } + +std::vector SurfaceCornerParameterizationQuantity::getCornerCoords() { + return coords.getIndexedView(parent.triangleCornerInds); +} + void SurfaceCornerParameterizationQuantity::buildCornerInfoGUI(size_t cInd) { glm::vec2 coord = coords.getValue(cInd); @@ -254,6 +260,10 @@ void SurfaceVertexParameterizationQuantity::fillCoordBuffers(render::ShaderProgr p.setAttribute("a_value2", coords.getIndexedRenderAttributeBuffer(parent.triangleVertexInds)); } +std::vector SurfaceVertexParameterizationQuantity::getCornerCoords() { + return coords.getIndexedView(parent.triangleVertexInds); +} + void SurfaceVertexParameterizationQuantity::buildVertexInfoGUI(size_t vInd) { glm::vec2 coord = coords.getValue(vInd); diff --git a/test/src/curve_network_test.cpp b/test/src/curve_network_test.cpp index 8b7fd794..3225a9cf 100644 --- a/test/src/curve_network_test.cpp +++ b/test/src/curve_network_test.cpp @@ -18,6 +18,14 @@ TEST_F(PolyscopeTest, ShowCurveNetwork) { EXPECT_FALSE(polyscope::hasCurveNetwork("test1")); } +TEST_F(PolyscopeTest, EmptyCurveNetwork) { + std::vector points; + std::vector> edges; + polyscope::registerCurveNetwork("empty", points, edges); + polyscope::show(3); + polyscope::removeAllStructures(); +} + TEST_F(PolyscopeTest, CurveNetworkAppearance) { auto psCurve = registerCurveNetwork(); diff --git a/test/src/surface_mesh_test.cpp b/test/src/surface_mesh_test.cpp index dc593f11..16b2ca21 100644 --- a/test/src/surface_mesh_test.cpp +++ b/test/src/surface_mesh_test.cpp @@ -497,6 +497,10 @@ TEST_F(PolyscopeTest, SurfaceMeshVertexParam) { q1->setStyle(polyscope::ParamVizStyle::LOCAL_RAD); polyscope::show(3); + // create the curve network + q1->createCurveNetworkFromSeams(); + polyscope::show(3); + polyscope::removeAllStructures(); }