Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions examples/demo-app/demo_app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -807,8 +807,7 @@ void callback() {
std::tie(xInd, yInd) = polyscope::view::screenCoordsToBufferInds(screenCoords);

glm::vec3 worldRay = polyscope::view::screenCoordsToWorldRay(screenCoords);
glm::vec3 worldPos = polyscope::view::screenCoordsToWorldPosition(screenCoords);
std::pair<polyscope::Structure*, size_t> pickPair = polyscope::pick::pickAtScreenCoords(screenCoords);
polyscope::PickResult pickResult = polyscope::pickAtScreenCoords(screenCoords);

std::cout << "Polyscope scene test click " << std::endl;
std::cout << " io.MousePos.x: " << io.MousePos.x << " io.MousePos.y: " << io.MousePos.y << std::endl;
Expand All @@ -817,16 +816,17 @@ void callback() {
std::cout << " worldRay: ";
polyscope::operator<<(std::cout, worldRay) << std::endl;
std::cout << " worldPos: ";
polyscope::operator<<(std::cout, worldPos) << std::endl;
if (pickPair.first == nullptr) {
polyscope::operator<<(std::cout, pickResult.position) << std::endl;
if (pickResult.isHit) {
std::cout << " structure: " << pickResult.structureType << " " << pickResult.structureName
<< " local ind: " << pickResult.localIndex << std::endl;
} else {
std::cout << " structure: "
<< "none" << std::endl;
} else {
std::cout << " structure: " << pickPair.first << " element id: " << pickPair.second << std::endl;
}

// Construct point at click location
polyscope::registerPointCloud("click point", std::vector<glm::vec3>({worldPos}));
polyscope::registerPointCloud("click point", std::vector<glm::vec3>({pickResult.position}));

// Construct unit-length vector pointing in the direction of the click
// (this depends only on the camera parameters, and does not require accessing the depth buffer)
Expand Down
9 changes: 8 additions & 1 deletion include/polyscope/camera_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ struct QuantityTypeHelper<CameraView> {
};
*/

struct CameraViewPickResult {
// currently nothing, just following the same pattern as other structures
};

class CameraView : public QuantityStructure<CameraView> {
public:
// === Member functions ===
Expand All @@ -37,7 +41,7 @@ class CameraView : public QuantityStructure<CameraView> {
// Build the imgui display
virtual void buildCustomUI() override;
virtual void buildCustomOptionsUI() override;
virtual void buildPickUI(size_t localPickID) override;
virtual void buildPickUI(const PickResult& result) override;

// Standard structure overrides
virtual void draw() override;
Expand Down Expand Up @@ -71,6 +75,9 @@ class CameraView : public QuantityStructure<CameraView> {
// Update the current viewer to look through this camer
void setViewToThisCamera(bool withFlight = false);

// get data related to picking/selection
CameraViewPickResult interpretPickResult(const PickResult& result);

// === Get/set visualization parameters

// Set focal length of the camera. This only effects how it the camera widget is rendered
Expand Down
11 changes: 10 additions & 1 deletion include/polyscope/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

#pragma once

#include <polyscope/pick.h>
#include <polyscope/types.h>
#include <polyscope/weak_handle.h>


#include <glm/glm.hpp>
#include <glm/gtx/dual_quaternion.hpp>
#include <glm/gtx/norm.hpp>
Expand All @@ -15,6 +15,7 @@
#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

Expand Down Expand Up @@ -97,6 +98,14 @@ struct Context {
glm::vec3 flightTargetViewT, flightInitialViewT;
float flightTargetFov, flightInitialFov;

// ======================================================
// === Picking globals from pick.h / pick.cpp
// ======================================================

PickResult currSelectionPickResult;
bool haveSelectionVal = false;
uint64_t nextPickBufferInd = 1;
std::unordered_map<Structure*, std::tuple<uint64_t, uint64_t>> structureRanges;

// ======================================================
// === Internal globals from internal.h
Expand Down
15 changes: 12 additions & 3 deletions include/polyscope/curve_network.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ struct QuantityTypeHelper<CurveNetwork> {
typedef CurveNetworkQuantity type;
};

struct CurveNetworkPickResult {
CurveNetworkElement elementType; // which kind of element did we click
int64_t index; // index of the clicked element
float tEdge = -1; // if the pick is an edge, the t-value in [0,1] along the edge
};

class CurveNetwork : public QuantityStructure<CurveNetwork> {
public:
// === Member functions ===
Expand All @@ -48,7 +54,7 @@ class CurveNetwork : public QuantityStructure<CurveNetwork> {
// Build the imgui display
virtual void buildCustomUI() override;
virtual void buildCustomOptionsUI() override;
virtual void buildPickUI(size_t localPickID) override;
virtual void buildPickUI(const PickResult&) override;

virtual void draw() override;
virtual void drawDelayed() override;
Expand Down Expand Up @@ -127,6 +133,9 @@ class CurveNetwork : public QuantityStructure<CurveNetwork> {
template <class V>
void updateNodePositions2D(const V& newPositions);

// get data related to picking/selection
CurveNetworkPickResult interpretPickResult(const PickResult& result);

// === Get/set visualization parameters

// set the base color of the points
Expand Down Expand Up @@ -183,8 +192,8 @@ class CurveNetwork : public QuantityStructure<CurveNetwork> {
float computeRadiusMultiplierUniform();

// Pick helpers
void buildNodePickUI(size_t nodeInd);
void buildEdgePickUI(size_t edgeInd);
void buildNodePickUI(const CurveNetworkPickResult& result);
void buildEdgePickUI(const CurveNetworkPickResult& result);

// === Quantity adder implementations
// clang-format off
Expand Down
21 changes: 21 additions & 0 deletions include/polyscope/elementary_geometry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2017-2023, Nicholas Sharp and the Polyscope contributors. https://polyscope.run

#pragma once

#include <complex>
#include <tuple>

#include <glm/glm.hpp>

namespace polyscope {

// Compute t \in [0,1] for a point along hte line from lineStart -- lineEnd
float computeTValAlongLine(glm::vec3 queryP, glm::vec3 lineStart, glm::vec3 lineEnd);

// Project a point onto a plane. planeNormal must be unit
glm::vec3 projectToPlane(glm::vec3 queryP, glm::vec3 planeNormal, glm::vec3 pointOnPlane);

// Compute the signed area of triangle ABC which lies in the plane give by normal
float signedTriangleArea(glm::vec3 normal, glm::vec3 pA, glm::vec3 pB, glm::vec3 pC);

}
2 changes: 1 addition & 1 deletion include/polyscope/floating_quantity_structure.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class FloatingQuantityStructure : public QuantityStructure<FloatingQuantityStruc
// Build the imgui display
virtual void buildUI() override;
virtual void buildCustomUI() override;
virtual void buildPickUI(size_t localPickID) override;
virtual void buildPickUI(const PickResult& result) override;
virtual void buildCustomOptionsUI() override;

// Standard structure overrides
Expand Down
2 changes: 2 additions & 0 deletions include/polyscope/persistent_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ extern PersistentCache<BackFacePolicy> persistentCache_BackFacePolicy;
extern PersistentCache<MeshShadeStyle> persistentCache_MeshNormalType;
extern PersistentCache<FilterMode> persistentCache_FilterMode;
extern PersistentCache<IsolineStyle> persistentCache_IsolineStyle;
extern PersistentCache<MeshSelectionMode> persistentCache_MeshSelectionMode;

template<> inline PersistentCache<double>& getPersistentCacheRef<double>() { return persistentCache_double; }
template<> inline PersistentCache<float>& getPersistentCacheRef<float>() { return persistentCache_float; }
Expand All @@ -159,6 +160,7 @@ template<> inline PersistentCache<BackFacePolicy>& getPersistentCacheR
template<> inline PersistentCache<MeshShadeStyle>& getPersistentCacheRef<MeshShadeStyle>() { return persistentCache_MeshNormalType; }
template<> inline PersistentCache<FilterMode>& getPersistentCacheRef<FilterMode>() { return persistentCache_FilterMode; }
template<> inline PersistentCache<IsolineStyle>& getPersistentCacheRef<IsolineStyle>() { return persistentCache_IsolineStyle; }
template<> inline PersistentCache<MeshSelectionMode>& getPersistentCacheRef<MeshSelectionMode>() { return persistentCache_MeshSelectionMode; }
}
// clang-format on

Expand Down
69 changes: 50 additions & 19 deletions include/polyscope/pick.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,76 @@

#pragma once

#include "polyscope/structure.h"

#include <cstdint>
#include <string>
#include <utility>

namespace polyscope {
namespace pick {
#include "polyscope/utilities.h"
#include "polyscope/weak_handle.h"

namespace polyscope {

// == Set up picking
// Called by a structure to figure out what data it should render to the pick buffer.
// Request 'count' contiguous indices for drawing a pick buffer. The return value is the start of the range.
size_t requestPickBufferRange(Structure* requestingStructure, size_t count);

// Forward decls
class Structure;

// == Main query
// Get the structure which was clicked on (nullptr if none), and the pick ID in local indices for that structure (such
// that 0 is the first index as returned from requestPickBufferRange())
std::pair<Structure*, size_t> pickAtScreenCoords(glm::vec2 screenCoords); // takes screen coordinates
std::pair<Structure*, size_t> pickAtBufferCoords(int xPos, int yPos); // takes indices into the buffer
std::pair<Structure*, size_t> evaluatePickQuery(int xPos, int yPos); // old, badly named. takes buffer coordinates.

// Pick queries test a screen location in the rendered viewport, and return a variety of info about what is underneath
// the pixel at that point, including what structure is under the cursor, and the scene depth and color.
//
// This information can be fed into structure-specific functions like SurfaceMesh::interpretPick(PickResult) to get
// structure-specific info, like which vertex/face was clicked on.

// Return type for pick queries
struct PickResult {
bool isHit = false;
Structure* structure = nullptr;
WeakHandle<Structure> structureHandle; // same as .structure, but with lifetime tracking
std::string structureType = "";
std::string structureName = "";
glm::vec2 screenCoords;
glm::ivec2 bufferInds;
glm::vec3 position;
float depth;
uint64_t localIndex = INVALID_IND_64;
};

// Query functions to evaluate a pick.
// Internally, these do a render pass to populate relevant information, then query the resulting buffers.
PickResult pickAtScreenCoords(glm::vec2 screenCoords); // takes screen coordinates
PickResult pickAtBufferInds(glm::ivec2 bufferInds); // takes indices into render buffer


// == Stateful picking: track and update a current selection

// Get/Set the "selected" item, if there is one (output has same meaning as evaluatePickQuery());
std::pair<Structure*, size_t> getSelection();
void setSelection(std::pair<Structure*, size_t> newPick);
// Get/Set the "selected" item, if there is one
PickResult getSelection();
void setSelection(PickResult newPick);
void resetSelection();
bool haveSelection();
void resetSelectionIfStructure(Structure* s); // If something from this structure is selected, clear the selection
// (useful if a structure is being deleted)

namespace pick {

// Old, deprecated picking API. Use the above functions instead.
// Get the structure which was clicked on (nullptr if none), and the pick ID in local indices for that structure (such
// that 0 is the first index as returned from requestPickBufferRange())
std::pair<Structure*, uint64_t> pickAtScreenCoords(glm::vec2 screenCoords); // takes screen coordinates
std::pair<Structure*, uint64_t> pickAtBufferCoords(int xPos, int yPos); // takes indices into the buffer
std::pair<Structure*, uint64_t> evaluatePickQuery(int xPos, int yPos); // old, badly named. takes buffer coordinates.


// == Helpers

// Set up picking (internal)
// Called by a structure to figure out what data it should render to the pick buffer.
// Request 'count' contiguous indices for drawing a pick buffer. The return value is the start of the range.
uint64_t requestPickBufferRange(Structure* requestingStructure, uint64_t count);

// Convert between global pick indexing for the whole program, and local per-structure pick indexing
std::pair<Structure*, size_t> globalIndexToLocal(size_t globalInd);
size_t localIndexToGlobal(std::pair<Structure*, size_t> localPick);
std::pair<Structure*, uint64_t> globalIndexToLocal(uint64_t globalInd);
uint64_t localIndexToGlobal(std::pair<Structure*, uint64_t> localPick);

// Convert indices to float3 color and back
// Structures will want to use these to fill their pick buffers
Expand Down
11 changes: 9 additions & 2 deletions include/polyscope/point_cloud.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "polyscope/affine_remapper.h"
#include "polyscope/color_management.h"
#include "polyscope/persistent_value.h"
#include "polyscope/pick.h"
#include "polyscope/point_cloud_quantity.h"
#include "polyscope/polyscope.h"
#include "polyscope/render/engine.h"
Expand Down Expand Up @@ -37,6 +38,10 @@ struct QuantityTypeHelper<PointCloud> {
typedef PointCloudQuantity type;
};

struct PointCloudPickResult {
int64_t index;
};

class PointCloud : public QuantityStructure<PointCloud> {
public:
// === Member functions ===
Expand All @@ -49,7 +54,7 @@ class PointCloud : public QuantityStructure<PointCloud> {
// Build the imgui display
virtual void buildCustomUI() override;
virtual void buildCustomOptionsUI() override;
virtual void buildPickUI(size_t localPickID) override;
virtual void buildPickUI(const PickResult& result) override;

// Standard structure overrides
virtual void draw() override;
Expand Down Expand Up @@ -116,6 +121,9 @@ class PointCloud : public QuantityStructure<PointCloud> {
size_t nPoints();
glm::vec3 getPointPosition(size_t iPt);

// get data related to picking/selection
PointCloudPickResult interpretPickResult(const PickResult& result);

// Misc data
static const std::string structureTypeName;

Expand Down Expand Up @@ -193,7 +201,6 @@ class PointCloud : public QuantityStructure<PointCloud> {
PointCloudScalarQuantity& resolveTransparencyQuantity(); // helper
};


// Shorthand to add a point cloud to polyscope
template <class T>
PointCloud* registerPointCloud(std::string name, const T& points);
Expand Down
4 changes: 4 additions & 0 deletions include/polyscope/polyscope.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ Structure* getStructure(std::string type, std::string name = "");
// True if such a structure exists
bool hasStructure(std::string type, std::string name = "");

// Look up the string type and name for a structure from its pointer
// (performs a naive search over all structures for now, use sparingly)
std::tuple<std::string, std::string> lookUpStructure(Structure* structure);

// De-register a structure, of any type. Also removes any quantities associated with the structure
void removeStructure(Structure* structure, bool errorIfAbsent = false);
void removeStructure(std::string type, std::string name, bool errorIfAbsent = false);
Expand Down
2 changes: 1 addition & 1 deletion include/polyscope/render/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ class Engine {
TransparencyMode getTransparencyMode();
bool transparencyEnabled();
virtual void applyTransparencySettings() = 0;
void addSlicePlane(std::string uniquePostfix);
void addSlicePlane(std::string uniquePostfix); // TODO move slice planes out of the engine
void removeSlicePlane(std::string uniquePostfix);
bool slicePlanesEnabled(); // true if there is at least one slice plane in the scene
virtual void setFrontFaceCCW(bool newVal) = 0; // true if CCW triangles are considered front-facing; false otherwise
Expand Down
10 changes: 9 additions & 1 deletion include/polyscope/simple_triangle_mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ class SimpleTriangleMesh;
// typedef SimpleTriangleMeshQuantity type;
// };


struct SimpleTriangleMeshPickResult {
// this does nothing for now, just matching pattern from other structures
};

class SimpleTriangleMesh : public QuantityStructure<SimpleTriangleMesh> {
public:
// === Member functions ===
Expand All @@ -36,7 +41,7 @@ class SimpleTriangleMesh : public QuantityStructure<SimpleTriangleMesh> {
// Build the imgui display
virtual void buildCustomUI() override;
virtual void buildCustomOptionsUI() override;
virtual void buildPickUI(size_t localPickID) override;
virtual void buildPickUI(const PickResult& result) override;

// Standard structure overrides
virtual void draw() override;
Expand All @@ -63,6 +68,9 @@ class SimpleTriangleMesh : public QuantityStructure<SimpleTriangleMesh> {
// Misc data
static const std::string structureTypeName;

// get data related to picking/selection
SimpleTriangleMeshPickResult interpretPickResult(const PickResult& result);

// === Get/set visualization parameters

// set the base color of the surface
Expand Down
3 changes: 2 additions & 1 deletion include/polyscope/structure.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "glm/glm.hpp"

#include "polyscope/persistent_value.h"
#include "polyscope/pick.h"
#include "polyscope/render/engine.h"
#include "polyscope/transformation_gizmo.h"
#include "polyscope/weak_handle.h"
Expand Down Expand Up @@ -54,7 +55,7 @@ class Structure : public render::ManagedBufferRegistry, public virtual WeakRefer
virtual void buildStructureOptionsUI(); // overridden by structure quantities to add to the options menu
virtual void buildQuantitiesUI(); // build quantities, if they exist. Overridden by QuantityStructure.
virtual void buildSharedStructureUI(); // Draw any UI elements shared between all instances of the structure
virtual void buildPickUI(size_t localPickID) = 0; // Draw pick UI elements when index localPickID is selected
virtual void buildPickUI(const PickResult& result) = 0; // Draw pick UI elements based on a selection result

// = Identifying data
const std::string name; // should be unique amongst registered structures with this type
Expand Down
Loading