Lagrange
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Modules Pages
volume_to_mesh.h
1/*
2 * Copyright 2021 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/create_mesh.h>
15#include <lagrange/legacy/inline.h>
16
17#include <openvdb/openvdb.h>
18#include <openvdb/tools/VolumeToMesh.h>
19
20namespace lagrange {
21namespace volume {
22LAGRANGE_LEGACY_INLINE
23namespace legacy {
24
40template <typename MeshType, typename GridType>
41std::unique_ptr<MeshType> volume_to_mesh_legacy(
42 const GridType& grid,
43 double isovalue = 0.0,
44 double adaptivity = 0.0,
45 bool relax_disoriented_triangles = true)
46{
47 static_assert(MeshTrait<MeshType>::is_mesh(), "Input type is not Mesh");
48
49 openvdb::initialize();
50
51 using Scalar = ScalarOf<MeshType>;
52 using Index = IndexOf<MeshType>;
53 using VertexArray = VertexArrayOf<MeshType>;
54 using FacetArray = FacetArrayOf<MeshType>;
55 using RowVector3s = Eigen::Matrix<float, 1, 3>;
56 using RowVector3I = Eigen::Matrix<openvdb::Index32, 1, 3>;
57 using RowVector3I = Eigen::Matrix<openvdb::Index32, 1, 3>;
58 using RowVector4I = Eigen::Matrix<openvdb::Index32, 1, 4>;
59 using RowVector4i = Eigen::Matrix<Index, 1, 4>;
60
61 if (adaptivity < 0 || adaptivity > 1) {
62 logger().warn("Adaptivity needs to be between 0 and 1.");
63 adaptivity = std::max(0.0, std::min(1.0, adaptivity));
64 }
65
66 std::vector<openvdb::Vec3s> points;
67 std::vector<openvdb::Vec3I> triangles;
68 std::vector<openvdb::Vec4I> quads;
69
70 openvdb::tools::volumeToMesh(
71 grid,
72 points,
73 triangles,
74 quads,
75 isovalue,
76 adaptivity,
77 relax_disoriented_triangles);
78
79 VertexArray vertices(points.size(), 3);
80 FacetArray facets(triangles.size() + 2 * quads.size(), 3);
81
82 // Level set grids need their facet flipped
83 const bool need_flip = (grid.getGridClass() == openvdb::GRID_LEVEL_SET);
84
85 for (size_t v = 0; v < points.size(); ++v) {
86 const RowVector3s p(points[v].x(), points[v].y(), points[v].z());
87 vertices.row(v) << p.template cast<Scalar>();
88 }
89
90 for (size_t f = 0; f < triangles.size(); ++f) {
91 const RowVector3I triangle(triangles[f].x(), triangles[f].y(), triangles[f].z());
92 facets.row(f) << triangle.template cast<Index>();
93 if (need_flip) {
94 facets.row(f) = facets.row(f).reverse().eval();
95 }
96 }
97
98 for (size_t f = 0, o = triangles.size(); f < quads.size(); ++f) {
99 const RowVector4I quad_(quads[f].x(), quads[f].y(), quads[f].z(), quads[f].w());
100 const RowVector4i quad = quad_.template cast<Index>();
101 facets.row(o + 2 * f) << quad(0), quad(1), quad(3);
102 facets.row(o + 2 * f + 1) << quad(3), quad(1), quad(2);
103 if (need_flip) {
104 facets.row(o + 2 * f) = facets.row(o + 2 * f).reverse().eval();
105 facets.row(o + 2 * f + 1) = facets.row(o + 2 * f + 1).reverse().eval();
106 }
107 }
108
109 return lagrange::create_mesh<VertexArray, FacetArray>(std::move(vertices), std::move(facets));
110}
111
112} // namespace legacy
113} // namespace volume
114} // namespace lagrange
LA_CORE_API spdlog::logger & logger()
Retrieves the current logger.
Definition: Logger.cpp:40
Main namespace for Lagrange.
Definition: AABBIGL.h:30