diff --git a/include/igl/exploded_view.cpp b/include/igl/exploded_view.cpp new file mode 100644 index 000000000..d23b6162c --- /dev/null +++ b/include/igl/exploded_view.cpp @@ -0,0 +1,70 @@ +// This file is part of libigl, a simple c++ geometry processing library. +// +// Copyright (C) 2020 Alec Jacobson +// +// 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/. +#include "exploded_view.h" +#include "barycenter.h" +#include "volume.h" + +template < + typename DerivedV, + typename DerivedT, + typename DerivedEV, + typename DerivedEF, + typename DerivedI, + typename DerivedJ> +IGL_INLINE void igl::exploded_view( + const Eigen::MatrixBase & V, + const Eigen::MatrixBase & T, + const typename DerivedV::Scalar s, + const typename DerivedV::Scalar t, + Eigen::PlainObjectBase & EV, + Eigen::PlainObjectBase & EF, + Eigen::PlainObjectBase & I, + Eigen::PlainObjectBase & J) +{ + assert(T.cols() == 4 && "T should be a tet mesh"); + EV.resize(4*T.rows(),3); + EF.resize(4*T.rows(),3); + I.resize(EV.rows()); + J.resize(EF.rows()); + Eigen::MatrixXd BC; + igl::barycenter(V,T,BC); + Eigen::VectorXd vol; + igl::volume(V,T,vol); + const Eigen::RowVectorXd c = vol.transpose()*BC/vol.array().sum(); + for(int i = 0;i, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::Matrix::Scalar, Eigen::Matrix::Scalar, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); +#endif diff --git a/include/igl/exploded_view.h b/include/igl/exploded_view.h new file mode 100644 index 000000000..e925404bb --- /dev/null +++ b/include/igl/exploded_view.h @@ -0,0 +1,50 @@ +// This file is part of libigl, a simple c++ geometry processing library. +// +// Copyright (C) 2020 Alec Jacobson +// +// 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_EXPLODED_VIEW_H +#define IGL_EXPLODED_VIEW_H +#include "igl_inline.h" +#include +namespace igl +{ + // Given a tet-mesh, create a trivial surface mesh (4 triangles per tet) with + // each tet scaled individually and translated outward from the mesh's + // centroid, creating an exploded-view visualization. + // + // Inputs: + // V #V by 3 list of tet mesh vertex positions + // T #T by 4 list of tet mesh indices into rows of V + // s amount to scale each tet indvidually, typically (0,1] + // t amount to scale away from mesh's centroid, typically >=1 + // Outputs: + // EV #T*4 by 3 list of output mesh vertex positions + // EF #T*4 by 3 list of output triangle indices into rows of EV + // I #EV list of indices into V revealing birth parent + // J #EF list of indices into F revealing birth parent + template < + typename DerivedV, + typename DerivedT, + typename DerivedEV, + typename DerivedEF, + typename DerivedI, + typename DerivedJ> + IGL_INLINE void exploded_view( + const Eigen::MatrixBase & V, + const Eigen::MatrixBase & T, + const typename DerivedV::Scalar s, + const typename DerivedV::Scalar t, + Eigen::PlainObjectBase & EV, + Eigen::PlainObjectBase & EF, + Eigen::PlainObjectBase & I, + Eigen::PlainObjectBase & J); +} + +#ifndef IGL_STATIC_LIBRARY +# include "exploded_view.cpp" +#endif + +#endif diff --git a/include/igl/opengl/ViewerData.cpp b/include/igl/opengl/ViewerData.cpp index 702f0995c..e2ca30700 100644 --- a/include/igl/opengl/ViewerData.cpp +++ b/include/igl/opengl/ViewerData.cpp @@ -189,31 +189,35 @@ IGL_INLINE void igl::opengl::ViewerData::set_colors(const Eigen::MatrixXd &C) F_material_ambient = ambient(F_material_diffuse); F_material_specular = specular(F_material_diffuse); } - else if (C.rows() == V.rows()) + else if(C.rows() == V.rows() || C.rows() == F.rows()) { - set_face_based(false); - for (unsigned i=0;i +// +// 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/. + +#include +#include +#include +#include +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + + Eigen::MatrixXd V; + Eigen::MatrixXi T,F; + igl::readMESH(argc>1?argv[1]: TUTORIAL_SHARED_PATH "/octopus-low.mesh",V,T,F); + // Some per-tet data + Eigen::VectorXd D; + { + Eigen::MatrixXd BC; + igl::barycenter(V,T,BC); + Eigen::VectorXd vol; + igl::volume(V,T,vol); + const Eigen::RowVectorXd c = vol.transpose()*BC/vol.array().sum(); + D = (BC.rowwise()-c).rowwise().norm(); + } + + // Plot the mesh + igl::opengl::glfw::Viewer viewer; + + double t = 1; + double s = 1; + const auto update = [&]() + { + Eigen::MatrixXd EV; + Eigen::MatrixXi EF; + Eigen::VectorXi I,J; + igl::exploded_view(V,T,s,t,EV,EF,I,J); + Eigen::VectorXd DJ; + igl::slice(D,J,1,DJ); + static bool first = true; + if(first) + { + viewer.data().clear(); + viewer.data().set_mesh(EV,EF); + first = false; + }else + { + viewer.data().set_vertices(EV); + } + viewer.data().set_face_based(true); + Eigen::MatrixXd C; + igl::colormap(igl::COLOR_MAP_TYPE_VIRIDIS,DJ,true,C); + viewer.data().set_colors(C); + }; + int mod = 0; + float prev_y; + viewer.callback_mouse_move = [&](igl::opengl::glfw::Viewer &, int x, int y)->bool + { + if((mod & IGL_MOD_SHIFT)||(mod & IGL_MOD_ALT)) + { + if(mod & IGL_MOD_SHIFT) + { + t = std::min(std::max(t+0.001*(y-prev_y),1.),2.); + } + if(mod & IGL_MOD_ALT) + { + s = std::min(std::max(s+0.001*(y-prev_y),0.),1.); + } + prev_y = y; + update(); + return true; + } + return false; + }; + // get modifier + viewer.callback_key_down = + [&](igl::opengl::glfw::Viewer &, unsigned char key, int _mod)->bool + { + prev_y = viewer.current_mouse_y; + mod = _mod; + return false; + }; + viewer.callback_key_up = + [&](igl::opengl::glfw::Viewer &, unsigned char key, int _mod)->bool + { + mod = _mod; + return false; + }; + update(); + viewer.launch(); +} diff --git a/tutorial/CMakeLists.txt b/tutorial/CMakeLists.txt index 32fd95d26..68e08f911 100644 --- a/tutorial/CMakeLists.txt +++ b/tutorial/CMakeLists.txt @@ -159,4 +159,5 @@ if(TUTORIALS_CHAPTER7) add_subdirectory("717_FastWindingNumber") endif() add_subdirectory("718_IterativeClosestPoint") + add_subdirectory("719_ExplodedView") endif()