// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2014 Daniele Panozzo // // 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 "ViewerData.h" #include #include #include IGL_INLINE igl::ViewerData::ViewerData() #ifdef ENABLE_XML_SERIALIZATION : XMLSerialization("Data"), dirty(DIRTY_ALL) #endif { clear(); }; IGL_INLINE void igl::ViewerData::InitSerialization() { #ifdef ENABLE_XML_SERIALIZATION xmlSerializer->Add(V,"V"); xmlSerializer->Add(F,"F"); xmlSerializer->Add(F_normals,"F_normals"); xmlSerializer->Add(F_material_ambient,"F_material_ambient"); xmlSerializer->Add(F_material_diffuse,"F_material_diffuse"); xmlSerializer->Add(F_material_specular,"F_material_specular"); xmlSerializer->Add(V_normals,"V_normals"); xmlSerializer->Add(V_material_ambient,"V_material_ambient"); xmlSerializer->Add(V_material_diffuse,"V_material_diffuse"); xmlSerializer->Add(V_material_specular,"V_material_specular"); xmlSerializer->Add(V_uv,"V_uv"); xmlSerializer->Add(F_uv,"F_uv"); xmlSerializer->Add(texture_R,"texture_R"); xmlSerializer->Add(texture_G,"texture_G"); xmlSerializer->Add(texture_B,"texture_B"); xmlSerializer->Add(lines,"lines"); xmlSerializer->Add(points,"points"); xmlSerializer->Add(labels_positions,"labels_positions"); xmlSerializer->Add(labels_strings,"labels_strings"); xmlSerializer->Add(face_based,"face_based"); #endif } IGL_INLINE void igl::ViewerData::set_face_based(bool newvalue) { if (face_based != newvalue) { face_based = newvalue; dirty = DIRTY_ALL; } } // Helpers that draws the most common meshes IGL_INLINE void igl::ViewerData::set_mesh(const Eigen::MatrixXd& _V, const Eigen::MatrixXi& _F) { using namespace std; Eigen::MatrixXd V_temp; // If V only has two columns, pad with a column of zeros if (_V.cols() == 2) { V_temp = Eigen::MatrixXd::Zero(V.rows(),3); V_temp.block(0,0,V.rows(),2) = _V; } else V_temp = _V; if (V.rows() == 0 && F.rows() == 0) { clear(); V = V_temp; F = _F; compute_normals(); uniform_colors(Eigen::Vector3d(51.0/255.0,43.0/255.0,33.3/255.0), Eigen::Vector3d(255.0/255.0,228.0/255.0,58.0/255.0), Eigen::Vector3d(255.0/255.0,235.0/255.0,80.0/255.0)); grid_texture(); } else { if (V.rows() == V.rows() && F.rows() == F.rows()) { V = V_temp; F = _F; } else cerr << "ERROR (set_mesh): The new mesh has a different number of vertices/faces. Please clear the mesh before plotting."; } dirty |= DIRTY_FACE | DIRTY_POSITION; } IGL_INLINE void igl::ViewerData::set_vertices(const Eigen::MatrixXd& _V) { V = _V; assert(F.size() == 0 || F.maxCoeff() < V.rows()); dirty |= DIRTY_POSITION; } IGL_INLINE void igl::ViewerData::set_normals(const Eigen::MatrixXd& N) { using namespace std; if (N.rows() == V.rows()) { set_face_based(false); V_normals = N; } else if (N.rows() == F.rows() || N.rows() == F.rows()*3) { set_face_based(true); F_normals = N; } else cerr << "ERROR (set_normals): Please provide a normal per face, per corner or per vertex."; dirty |= DIRTY_NORMAL; } IGL_INLINE void igl::ViewerData::set_colors(const Eigen::MatrixXd &C) { using namespace std; using namespace Eigen; // Ambient color should be darker color const auto ambient = [](const MatrixXd & C)->MatrixXd { return 0.1*C; }; // Specular color should be a less saturated and darker color: dampened // highlights const auto specular = [](const MatrixXd & C)->MatrixXd { const double grey = 0.3; return grey+0.1*(C.array()-grey); }; if (C.rows() == 1) { for (unsigned i=0;i& R, const Eigen::Matrix& G, const Eigen::Matrix& B) { texture_R = R; texture_G = G; texture_B = B; dirty |= DIRTY_TEXTURE; } IGL_INLINE void igl::ViewerData::set_points( const Eigen::MatrixXd& P, const Eigen::MatrixXd& C) { // clear existing points points.resize(0,0); add_points(P,C); } IGL_INLINE void igl::ViewerData::add_points(const Eigen::MatrixXd& P, const Eigen::MatrixXd& C) { Eigen::MatrixXd P_temp; // If P only has two columns, pad with a column of zeros if (P.cols() == 2) { P_temp = Eigen::MatrixXd::Zero(P.rows(),3); P_temp.block(0,0,P.rows(),2) = P; } else P_temp = P; int lastid = points.rows(); points.conservativeResize(points.rows() + P_temp.rows(),6); for (unsigned i=0; i=size2 && j>=size2)) texture_R(i,j) = 255; } } texture_G = texture_R; texture_B = texture_R; dirty |= DIRTY_TEXTURE; }