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
1 change: 1 addition & 0 deletions include/polyscope/camera_parameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class CameraParameters {
// create/test 'invalid' params
static CameraParameters createInvalid();
bool isValid() const;
bool isfinite() const;

// The intrinsic & extrinsics parameters that define the camera
CameraIntrinsics intrinsics;
Expand Down
28 changes: 28 additions & 0 deletions include/polyscope/check_invalid_values.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2017-2023, Nicholas Sharp and the Polyscope contributors. https://polyscope.run

#pragma once

#include <polyscope/numeric_helpers.h>
#include <polyscope/options.h>

#include <cmath>
#include <glm/glm.hpp>
#include <glm/gtx/compatibility.hpp>
#include <type_traits>

namespace polyscope {

template <typename T>
void checkInvalidValues(std::string name, const std::vector<T>& data) {
if (options::warnForInvalidValues) {
for (const T& val : data) {
if (!allComponentsFinite(val)) {
warning("Invalid +-inf or NaN values detected.\n(set warnForInvalidValues=false to disable this warning)",
"In buffer: " + name);
break;
}
}
}
}

} // namespace polyscope
4 changes: 3 additions & 1 deletion include/polyscope/color_quantity.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ namespace polyscope {

template <typename QuantityT>
ColorQuantity<QuantityT>::ColorQuantity(QuantityT& quantity_, const std::vector<glm::vec3>& colors_)
: quantity(quantity_), colors(&quantity, quantity.uniquePrefix() + "colors", colorsData), colorsData(colors_) {}
: quantity(quantity_), colors(&quantity, quantity.uniquePrefix() + "colors", colorsData), colorsData(colors_) {
colors.checkInvalidValues();
}

template <typename QuantityT>
void ColorQuantity<QuantityT>::buildColorUI() {}
Expand Down
84 changes: 84 additions & 0 deletions include/polyscope/numeric_helpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright 2017-2023, Nicholas Sharp and the Polyscope contributors. https://polyscope.run

#pragma once

#include <cmath>
#include <glm/glm.hpp>
#include <glm/gtx/compatibility.hpp>
#include <type_traits>

namespace polyscope {


// Base case: call the scalar version
template <typename T>
bool allComponentsFinite(const T& x) {
return std::isfinite(x);
}

template <>
inline bool allComponentsFinite<glm::vec2>(const glm::vec2& x) {
return glm::all(glm::isfinite(x));
}
template <>
inline bool allComponentsFinite<glm::vec3>(const glm::vec3& x) {
return glm::all(glm::isfinite(x));
}
template <>
inline bool allComponentsFinite<glm::vec4>(const glm::vec4& x) {
return glm::all(glm::isfinite(x));
}

template <>
inline bool allComponentsFinite<glm::uvec2>(const glm::uvec2& x) {
return true;
}
template <>
inline bool allComponentsFinite<glm::uvec3>(const glm::uvec3& x) {
return true;
}
template <>
inline bool allComponentsFinite<glm::uvec4>(const glm::uvec4& x) {
return true;
}

template <>
inline bool allComponentsFinite<glm::mat2x2>(const glm::mat2x2& x) {
for (size_t i = 0; i < 2; i++)
if (!allComponentsFinite(glm::row(x, i))) return false;
return true;
}
template <>
inline bool allComponentsFinite<glm::mat3x3>(const glm::mat3x3& x) {
for (size_t i = 0; i < 3; i++)
if (!allComponentsFinite(glm::row(x, i))) return false;
return true;
}
template <>
inline bool allComponentsFinite<glm::mat4x4>(const glm::mat4x4& x) {
for (size_t i = 0; i < 4; i++)
if (!allComponentsFinite(glm::row(x, i))) return false;
return true;
}

template <>
inline bool allComponentsFinite<std::array<glm::vec3, 2>>(const std::array<glm::vec3, 2>& x) {
for (size_t i = 0; i < x.size(); i++)
if (!glm::all(glm::isfinite(x[i]))) return false;
return true;
}
template <>
inline bool allComponentsFinite<std::array<glm::vec3, 3>>(const std::array<glm::vec3, 3>& x) {
for (size_t i = 0; i < x.size(); i++)
if (!glm::all(glm::isfinite(x[i]))) return false;
return true;
}
template <>
inline bool allComponentsFinite<std::array<glm::vec3, 4>>(const std::array<glm::vec3, 4>& x) {
for (size_t i = 0; i < x.size(); i++)
if (!glm::all(glm::isfinite(x[i]))) return false;
return true;
}


} // namespace polyscope
3 changes: 3 additions & 0 deletions include/polyscope/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ extern bool giveFocusOnShow;
// If true, hide the polyscope window when a show() command finishes (default: true)
extern bool hideWindowAfterShow;

// Give warnings for inf/nan values
extern bool warnForInvalidValues;

// === Scene options

// Behavior of the ground plane
Expand Down
5 changes: 3 additions & 2 deletions include/polyscope/parameterization_quantity.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ ParameterizationQuantity<QuantityT>::ParameterizationQuantity(QuantityT& quantit
gridBackgroundColor(quantity.uniquePrefix() + "#gridBackgroundColor", render::RGB_PINK),
altDarkness(quantity.uniquePrefix() + "#altDarkness", 0.5), cMap(quantity.uniquePrefix() + "#cMap", "phase")


{}
{
coords.checkInvalidValues();
}


template <typename QuantityT>
Expand Down
2 changes: 2 additions & 0 deletions include/polyscope/render/managed_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ class ManagedBuffer : public virtual WeakReferrable {
bool dataGetsComputed; // if true, the value gets computed on-demand by calling computeFunc()
std::function<void()> computeFunc; // (optional) callback which populates the `data` buffer

// sanity check helper
void checkInvalidValues();

// mark as texture, set size
void setTextureSize(uint32_t sizeX);
Expand Down
3 changes: 3 additions & 0 deletions include/polyscope/render/mock_opengl/mock_gl_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,9 @@ class MockGLEngine : public Engine {
virtual void shutdown() override;
void checkError(bool fatal = false) override;

// mock backend is always headless
virtual bool isHeadless() override { return true; }

void swapDisplayBuffers() override;
std::vector<unsigned char> readDisplayBuffer() override;

Expand Down
3 changes: 3 additions & 0 deletions include/polyscope/scalar_quantity.ipp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Copyright 2017-2023, Nicholas Sharp and the Polyscope contributors. https://polyscope.run

#include "imgui.h"
#include "polyscope/check_invalid_values.h"
#include "polyscope/utilities.h"

namespace polyscope {

template <typename QuantityT>
Expand All @@ -17,6 +19,7 @@ ScalarQuantity<QuantityT>::ScalarQuantity(QuantityT& quantity_, const std::vecto
isolineDarkness(quantity.uniquePrefix() + "isolineDarkness", 0.7)

{
values.checkInvalidValues();
hist.updateColormap(cMap.get());
hist.buildHistogram(values.data);

Expand Down
5 changes: 4 additions & 1 deletion include/polyscope/vector_quantity.ipp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright 2017-2023, Nicholas Sharp and the Polyscope contributors. https://polyscope.run


#include "polyscope/standardize_data_array.h"

namespace polyscope {
Expand Down Expand Up @@ -125,6 +124,7 @@ VectorQuantity<QuantityT>::VectorQuantity(QuantityT& quantity_, const std::vecto
: VectorQuantityBase<QuantityT>(quantity_, vectorType_),
vectors(&quantity_, quantity_.uniquePrefix() + "#values", vectorsData), vectorRoots(vectorRoots_),
vectorsData(vectors_) {
vectors.checkInvalidValues();
this->updateMaxLength();
}

Expand Down Expand Up @@ -236,6 +236,9 @@ TangentVectorQuantity<QuantityT>::TangentVectorQuantity(QuantityT& quantity_,
tangentBasisY(&quantity_, quantity_.uniquePrefix() + "#basisY", tangentBasisYData), vectorRoots(vectorRoots_),
tangentVectorsData(tangentVectors_), tangentBasisXData(tangentBasisX_), tangentBasisYData(tangentBasisY_),
nSym(nSym_) {
tangentVectors.checkInvalidValues();
tangentBasisX.checkInvalidValues();
tangentBasisY.checkInvalidValues();
this->updateMaxLength();
}

Expand Down
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ SET(HEADERS
${INCLUDE_ROOT}/camera_parameters.ipp
${INCLUDE_ROOT}/camera_view.h
${INCLUDE_ROOT}/camera_view.ipp
${INCLUDE_ROOT}/check_invalid_values.h
${INCLUDE_ROOT}/color_management.h
${INCLUDE_ROOT}/color_image_quantity.h
${INCLUDE_ROOT}/color_render_image_quantity.h
Expand Down Expand Up @@ -293,6 +294,7 @@ SET(HEADERS
${INCLUDE_ROOT}/implicit_helpers.h
${INCLUDE_ROOT}/implicit_helpers.ipp
${INCLUDE_ROOT}/messages.h
${INCLUDE_ROOT}/numeric_helpers.h
${INCLUDE_ROOT}/options.h
${INCLUDE_ROOT}/parameterization_quantity.h
${INCLUDE_ROOT}/parameterization_quantity.ipp
Expand Down
16 changes: 16 additions & 0 deletions src/camera_parameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

#include "polyscope/camera_parameters.h"

#include "polyscope/numeric_helpers.h"
#include "polyscope/options.h"

#include <cmath>
#include <iostream>

Expand Down Expand Up @@ -171,6 +174,19 @@ CameraParameters CameraParameters::createInvalid() {
}
bool CameraParameters::isValid() const { return intrinsics.isValid() && extrinsics.isValid(); }

bool CameraParameters::isfinite() const {
// confusing: two different notions of "valid". Here we mean "finite". There's another notion above which uses a flag
// to mark not-set-yet params.

bool isValid = true;

isValid = isValid && allComponentsFinite(intrinsics.getAspectRatioWidthOverHeight());
isValid = isValid && allComponentsFinite(intrinsics.getFoVVerticalDegrees());
isValid = isValid && allComponentsFinite(extrinsics.getE());

return isValid;
}

// == Forwarding getters for the camera class

glm::vec3 CameraParameters::getT() const { return extrinsics.getT(); }
Expand Down
7 changes: 7 additions & 0 deletions src/camera_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ CameraView::CameraView(std::string name, const CameraParameters& params_)
widgetThickness(uniquePrefix() + "#widgetThickness", 0.02),
widgetColor(uniquePrefix() + "#widgetColor", glm::vec3{0., 0., 0.}) {

if (options::warnForInvalidValues) {
if (!params.isfinite()) {
warning("Invalid +-inf or NaN values detected.\n(set warnForInvalidValues=false to disable this warning)",
"In camera view: " + name);
}
}

updateObjectSpaceBounds();
}

Expand Down
1 change: 1 addition & 0 deletions src/curve_network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ CurveNetwork::CurveNetwork(std::string name, std::vector<glm::vec3> nodes_, std:
material(uniquePrefix() + "#material", "clay")
// clang-format on
{
nodePositions.checkInvalidValues();

// Copy interleaved data in to tip and tails buffers below
edgeTailIndsData.resize(edges_.size());
Expand Down
29 changes: 19 additions & 10 deletions src/messages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,10 @@ void buildWarningUI(std::string warningBaseString, std::string warningDetailStri
std::max(warningBaseTextSize.y, std::max(warningDetailTextSize.y, warningRepeatTextSize.y)));
ImVec2 warningModalSize(
std::max(view::windowWidth / 5.0f, std::min(warningMaxTextSize.x + 50, view::windowWidth / 2.0f)), 0);
ImVec2 warningModalPos((view::windowWidth - warningModalSize.x) / 2, view::windowHeight / 3);

ImGui::SetNextWindowSize(warningModalSize);
ImGui::SetNextWindowPos(warningModalPos, ImGuiCond_Always);
ImGui::PushStyleColor(ImGuiCol_TitleBgActive, ImVec4(190. / 255., 166. / 255., 0, 1.0));
if (ImGui::BeginPopupModal("WARNING", NULL, ImGuiWindowFlags_NoMove)) {

Expand Down Expand Up @@ -231,8 +233,11 @@ void terminatingError(std::string message) {
std::cout << options::printPrefix << "[ERROR] " << message << std::endl;
}

auto func = std::bind(buildErrorUI, message, true);
pushContext(func, false);
// Enter a modal UI loop showing the warning
if (!isHeadless()) { // don't do it if running headless
auto func = std::bind(buildErrorUI, message, true);
pushContext(func, false);
}

// Quit the program
shutdown(true);
Expand All @@ -241,6 +246,13 @@ void terminatingError(std::string message) {

void warning(std::string baseMessage, std::string detailMessage) {

// print to stdout
if (options::verbosity > 0) {
std::cout << options::printPrefix << "[WARNING] " << baseMessage;
if (detailMessage != "") std::cout << " --- " << detailMessage;
std::cout << std ::endl;
}

// Look for a message with the same name
bool found = false;
for (WarningMessage& w : warningMessages) {
Expand All @@ -266,16 +278,13 @@ void showDelayedWarnings() {
showingWarning = true;
WarningMessage& currMessage = warningMessages.front();

if (options::verbosity > 0) {
std::cout << options::printPrefix << "[WARNING] " << currMessage.baseMessage;
if (currMessage.detailMessage != "") std::cout << " --- " << currMessage.detailMessage;
if (currMessage.repeatCount > 0) std::cout << " (and " << currMessage.repeatCount << " similar messages).";
std::cout << std ::endl;
// Enter a modal UI loop showing the warning
if (!isHeadless()) { // don't do it if running headless
auto func =
std::bind(buildWarningUI, currMessage.baseMessage, currMessage.detailMessage, currMessage.repeatCount);
pushContext(func, false);
}

auto func = std::bind(buildWarningUI, currMessage.baseMessage, currMessage.detailMessage, currMessage.repeatCount);
pushContext(func, false);

warningMessages.pop_front();
showingWarning = false;
}
Expand Down
1 change: 1 addition & 0 deletions src/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ bool automaticallyComputeSceneExtents = true;
bool invokeUserCallbackForNestedShow = false;
bool giveFocusOnShow = false;
bool hideWindowAfterShow = true;
bool warnForInvalidValues = true;

bool screenshotTransparency = true;
std::string screenshotExtension = ".png";
Expand Down
1 change: 1 addition & 0 deletions src/point_cloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ PointCloud::PointCloud(std::string name, std::vector<glm::vec3> points_)
material(uniquePrefix() + "material", "clay")
// clang-format on
{
points.checkInvalidValues();
cullWholeElements.setPassive(true);
updateObjectSpaceBounds();
}
Expand Down
20 changes: 11 additions & 9 deletions src/polyscope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,18 +319,20 @@ void processInputEvents() {
}

bool widgetCapturedMouse = false;
for (WeakHandle<Widget> wHandle : state::widgets) {
if (wHandle.isValid()) {
Widget& w = wHandle.get();
widgetCapturedMouse = w.interact();
if (widgetCapturedMouse) {
break;
}
}
}

// Handle scroll events for 3D view
if (state::doDefaultMouseInteraction) {

for (WeakHandle<Widget> wHandle : state::widgets) {
if (wHandle.isValid()) {
Widget& w = wHandle.get();
widgetCapturedMouse = w.interact();
if (widgetCapturedMouse) {
break;
}
}
}

if (!io.WantCaptureMouse && !widgetCapturedMouse) {
double xoffset = io.MouseWheelH;
double yoffset = io.MouseWheel;
Expand Down
Loading
Loading