Merge pull request #710 from jdumas/master
Update multi-mesh tutorial
Former-commit-id: 85eec4da42
This commit is contained in:
@@ -1,40 +0,0 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2018 Jérémie Dumas <jeremie.dumas@ens-lyon.org>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#ifndef IGL_ATTRIBUTE_H
|
||||
#define IGL_ATTRIBUTE_H
|
||||
|
||||
#include <typeindex>
|
||||
|
||||
namespace igl
|
||||
{
|
||||
|
||||
struct AttributeBase
|
||||
{
|
||||
private:
|
||||
std::type_index derived_type_;
|
||||
public:
|
||||
AttributeBase(std::type_index t) : derived_type_(t) { }
|
||||
virtual ~AttributeBase() = default;
|
||||
std::type_index type() const { return derived_type_; }
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<typename T>
|
||||
struct Attribute : public AttributeBase
|
||||
{
|
||||
// Constructor
|
||||
Attribute() : AttributeBase(typeid(T)) { }
|
||||
|
||||
// Data
|
||||
T content_;
|
||||
};
|
||||
|
||||
} // namespace igl
|
||||
|
||||
#endif // IGL_ATTRIBUTE_H
|
||||
@@ -29,7 +29,8 @@ IGL_INLINE igl::opengl::ViewerData::ViewerData()
|
||||
point_size(30),
|
||||
line_width(0.5f),
|
||||
line_color(0,0,0,1),
|
||||
shininess(35.0f)
|
||||
shininess(35.0f),
|
||||
id(-1)
|
||||
{
|
||||
clear();
|
||||
};
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#define IGL_VIEWERDATA_H
|
||||
|
||||
#include "../igl_inline.h"
|
||||
#include "../Attribute.h"
|
||||
#include "MeshGL.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
@@ -193,16 +192,12 @@ public:
|
||||
// Shape material
|
||||
float shininess;
|
||||
|
||||
// Unique identifier
|
||||
int id;
|
||||
|
||||
// OpenGL representation of the mesh
|
||||
igl::opengl::MeshGL meshgl;
|
||||
|
||||
// User-defined attribute
|
||||
std::shared_ptr<AttributeBase> attr_ptr;
|
||||
|
||||
// Retrieve custom attribute
|
||||
template<typename T> T & attr();
|
||||
template<typename T> const T & attr() const;
|
||||
|
||||
// Update contents from a 'Data' instance
|
||||
IGL_INLINE void updateGL(
|
||||
const igl::opengl::ViewerData& data,
|
||||
@@ -210,32 +205,6 @@ public:
|
||||
igl::opengl::MeshGL& meshgl);
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Retrieve custom attribute
|
||||
template<typename T>
|
||||
inline T & ViewerData::attr()
|
||||
{
|
||||
if (!attr_ptr)
|
||||
{
|
||||
attr_ptr = std::make_shared<Attribute<T>>();
|
||||
}
|
||||
auto * derived = dynamic_cast<Attribute<T> *>(attr_ptr.get());
|
||||
assert(derived && "Incompatible type requested for attribute");
|
||||
return derived->content_;
|
||||
}
|
||||
|
||||
|
||||
// Retrieve custom attribute
|
||||
template<typename T>
|
||||
inline const T & ViewerData::attr() const
|
||||
{
|
||||
assert(attr_ptr);
|
||||
const auto * derived = dynamic_cast<const Attribute<T> *>(attr_ptr.get());
|
||||
assert(derived && "Incompatible type requested for attribute");
|
||||
return derived->content_;
|
||||
}
|
||||
|
||||
} // namespace opengl
|
||||
} // namespace igl
|
||||
|
||||
@@ -282,6 +251,7 @@ namespace igl
|
||||
SERIALIZE_MEMBER(line_width);
|
||||
SERIALIZE_MEMBER(line_color);
|
||||
SERIALIZE_MEMBER(shininess);
|
||||
SERIALIZE_MEMBER(id);
|
||||
}
|
||||
template<>
|
||||
inline void serialize(const igl::opengl::ViewerData& obj, std::vector<char>& buffer)
|
||||
|
||||
@@ -285,7 +285,8 @@ namespace glfw
|
||||
|
||||
IGL_INLINE Viewer::Viewer():
|
||||
data_list(1),
|
||||
selected_data_index(0)
|
||||
selected_data_index(0),
|
||||
next_data_id(0)
|
||||
{
|
||||
window = nullptr;
|
||||
|
||||
@@ -905,13 +906,14 @@ namespace glfw
|
||||
return data_list[selected_data_index];
|
||||
}
|
||||
|
||||
IGL_INLINE size_t Viewer::append_mesh()
|
||||
IGL_INLINE int Viewer::append_mesh()
|
||||
{
|
||||
assert(data_list.size() >= 1);
|
||||
|
||||
data_list.emplace_back();
|
||||
selected_data_index = data_list.size()-1;
|
||||
return data_list.size();
|
||||
data_list.back().id = next_data_id++;
|
||||
return data_list.back().id;
|
||||
}
|
||||
|
||||
IGL_INLINE bool Viewer::erase_mesh(const size_t index)
|
||||
@@ -932,6 +934,16 @@ namespace glfw
|
||||
return true;
|
||||
}
|
||||
|
||||
IGL_INLINE size_t Viewer::mesh_index(const int id) {
|
||||
for (size_t i = 0; i < data_list.size(); ++i)
|
||||
{
|
||||
if (data_list[i].id == id)
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace
|
||||
} // end namespace
|
||||
}
|
||||
|
||||
@@ -80,15 +80,17 @@ namespace glfw
|
||||
IGL_INLINE void open_dialog_load_mesh();
|
||||
IGL_INLINE void open_dialog_save_mesh();
|
||||
IGL_INLINE ViewerData& data();
|
||||
|
||||
// Append a new "slot" for a mesh (i.e., create empty entires at the end of
|
||||
// the data_list and opengl_state_list.
|
||||
//
|
||||
// Returns number of meshes (always >= 1)
|
||||
// Returns the id of the last appended mesh
|
||||
//
|
||||
// Side Effects:
|
||||
// selected_data_index is set this newly created, last entry (i.e.,
|
||||
// #meshes-1)
|
||||
IGL_INLINE size_t append_mesh();
|
||||
IGL_INLINE int append_mesh();
|
||||
|
||||
// Erase a mesh (i.e., its corresponding data and state entires in data_list
|
||||
// and opengl_state_list)
|
||||
//
|
||||
@@ -107,12 +109,17 @@ namespace glfw
|
||||
//
|
||||
IGL_INLINE bool erase_mesh(const size_t index);
|
||||
|
||||
// Retrieve mesh index from its unique identifier
|
||||
// Returns 0 if not found
|
||||
IGL_INLINE size_t mesh_index(const int id);
|
||||
|
||||
// Alec: I call this data_list instead of just data to avoid confusion with
|
||||
// old "data" variable.
|
||||
// Stores all the data that should be visualized
|
||||
std::vector<ViewerData> data_list;
|
||||
|
||||
size_t selected_data_index;
|
||||
int next_data_id;
|
||||
GLFWwindow* window;
|
||||
// Stores all the viewing options
|
||||
ViewerCore core;
|
||||
|
||||
@@ -3,38 +3,53 @@
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
igl::opengl::glfw::Viewer viewer;
|
||||
const auto names =
|
||||
const auto names =
|
||||
{"cube.obj","sphere.obj","xcylinder.obj","ycylinder.obj","zcylinder.obj"};
|
||||
std::map<int, Eigen::RowVector3d> colors;
|
||||
int last_selected = -1;
|
||||
for(const auto & name : names)
|
||||
{
|
||||
viewer.load_mesh_from_file(std::string(TUTORIAL_SHARED_PATH) + "/" + name);
|
||||
colors.emplace(viewer.data().id, 0.5*Eigen::RowVector3d::Random().array() + 0.5);
|
||||
}
|
||||
|
||||
// Set colors of each mesh by selecting its index first
|
||||
viewer.selected_data_index = 0;
|
||||
viewer.data().set_colors(Eigen::RowVector3d(0.8,0.47,0.22));
|
||||
viewer.selected_data_index = 1;
|
||||
viewer.data().set_colors(Eigen::RowVector3d(0.6,0.01,0.11));
|
||||
viewer.selected_data_index = 2;
|
||||
viewer.data().set_colors(Eigen::RowVector3d(0.37,0.06,0.25));
|
||||
viewer.selected_data_index = 3;
|
||||
viewer.data().set_colors(Eigen::RowVector3d(1,1,1));
|
||||
|
||||
viewer.callback_key_down =
|
||||
viewer.callback_key_down =
|
||||
[&](igl::opengl::glfw::Viewer &, unsigned int key, int mod)
|
||||
{
|
||||
if(key == GLFW_KEY_BACKSPACE)
|
||||
{
|
||||
viewer.erase_mesh(viewer.selected_data_index);
|
||||
int old_id = viewer.data().id;
|
||||
if (viewer.erase_mesh(viewer.selected_data_index))
|
||||
{
|
||||
colors.erase(old_id);
|
||||
last_selected = -1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// Refresh selected mesh colors
|
||||
viewer.callback_pre_draw =
|
||||
[&](igl::opengl::glfw::Viewer &)
|
||||
{
|
||||
if (last_selected != viewer.selected_data_index)
|
||||
{
|
||||
for (auto &data : viewer.data_list)
|
||||
{
|
||||
data.set_colors(colors[data.id]);
|
||||
}
|
||||
viewer.data_list[viewer.selected_data_index].set_colors(Eigen::RowVector3d(0.9,0.1,0.1));
|
||||
last_selected = viewer.selected_data_index;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
viewer.launch();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user