Lagrange
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Modules Pages
load_mesh_ply.h
1/*
2 * Copyright 2020 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12#pragma once
13
14#include <lagrange/fs/filesystem.h>
15
16#include <lagrange/MeshTrait.h>
17#include <lagrange/create_mesh.h>
18#include <lagrange/legacy/inline.h>
19
20// clang-format off
21#include <lagrange/utils/warnoff.h>
22#include <igl/readPLY.h>
23#include <lagrange/utils/warnon.h>
24// clang-format on
25
26#include <string>
27#include <vector>
28
29namespace lagrange::io {
30LAGRANGE_LEGACY_INLINE
31namespace legacy {
32
34template <typename MeshType>
35std::unique_ptr<MeshType> load_mesh_ply(const fs::path& filename)
36{
37 static_assert(MeshTrait<MeshType>::is_mesh(), "Input type is not Mesh");
38 using VertexArray = typename MeshType::VertexArray;
39 using FacetArray = typename MeshType::FacetArray;
40 using AttributeArray = typename MeshType::AttributeArray;
41 using Index = typename MeshType::Index;
42
43 VertexArray V;
44 FacetArray F;
45 Eigen::Matrix<Index, Eigen::Dynamic, Eigen::Dynamic> E;
46 AttributeArray N;
47 AttributeArray UV;
48
49 AttributeArray VD;
50 std::vector<std::string> VDheader;
51
52 AttributeArray FD;
53 std::vector<std::string> FDheader;
54
55 AttributeArray ED;
56 std::vector<std::string> EDheader;
57 std::vector<std::string> comments;
58
59 // TODO: libigl's wrapper around tinyply doesn't allow to load attributes of different tyeps
60 // (e.g. char for colors + float for normals).
61 igl::readPLY(
62 filename.string(),
63 V,
64 F,
65 E,
66 N,
67 UV,
68 VD,
69 VDheader,
70 FD,
71 FDheader,
72 ED,
73 EDheader,
74 comments);
75
76 auto mesh = create_mesh(std::move(V), std::move(F));
77 if (static_cast<Index>(N.rows()) == mesh->get_num_vertices()) {
78 logger().debug("Setting vertex normal");
79 mesh->add_vertex_attribute("normal");
80 mesh->import_vertex_attribute("normal", N);
81 }
82
83 auto has_attribute = [&](const std::string& name) {
84 return std::find(VDheader.begin(), VDheader.end(), name) != VDheader.end();
85 };
86
87 if (static_cast<Index>(VD.rows()) == mesh->get_num_vertices()) {
88 if (has_attribute("red") && has_attribute("green") && has_attribute("blue")) {
89 bool has_alpha = has_attribute("alpha");
90 int n = (has_alpha ? 4 : 3);
91 AttributeArray color(mesh->get_num_vertices(), n);
92 color.setZero();
93 for (size_t i = 0; i < VDheader.size(); ++i) {
94 if (VDheader[i] == "red") {
95 la_runtime_assert(n >= 1);
96 color.col(0) = VD.col(i);
97 } else if (VDheader[i] == "green") {
98 la_runtime_assert(n >= 2);
99 color.col(1) = VD.col(i);
100 } else if (VDheader[i] == "blue") {
101 la_runtime_assert(n >= 3);
102 color.col(2) = VD.col(i);
103 } else if (VDheader[i] == "alpha") {
104 la_runtime_assert(n >= 4);
105 color.col(3) = VD.col(i);
106 } else {
107 logger().warn("Unknown vertex attribute: {}", VDheader[i]);
108 }
109 }
110 logger().debug("Setting vertex color");
111 mesh->add_vertex_attribute("color");
112 mesh->import_vertex_attribute("color", color);
113 }
114 }
115
116 return mesh;
117}
118
119} // namespace legacy
120} // namespace lagrange::io
Index get_num_vertices() const
Retrieves the number of vertices.
Definition: SurfaceMesh.h:671
LA_CORE_API spdlog::logger & logger()
Retrieves the current logger.
Definition: Logger.cpp:40
@ UV
Mesh attribute must have exactly 2 channels.
#define la_runtime_assert(...)
Runtime assertion check.
Definition: assert.h:169
Mesh input/output.
Definition: detect_file_format.h:18
MeshType load_mesh_ply(std::istream &input_stream, const LoadOptions &options={})
Loads a mesh from a stream in PLY format.
Definition: load_mesh_ply.cpp:301
auto create_mesh(const Eigen::MatrixBase< DerivedV > &vertices, const Eigen::MatrixBase< DerivedF > &facets)
This function create a new mesh given the vertex and facet arrays by copying data into the Mesh objec...
Definition: create_mesh.h:39