Lagrange
Loading...
Searching...
No Matches
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// clang-format off
18#include <lagrange/utils/warnoff.h>
19#include <openvdb/openvdb.h>
20#include <openvdb/tools/VolumeToMesh.h>
21#include <lagrange/utils/warnon.h>
22// clang-format on
23
24namespace lagrange {
25namespace volume {
26LAGRANGE_LEGACY_INLINE
27namespace legacy {
28
44template <typename MeshType, typename GridType>
45std::unique_ptr<MeshType> volume_to_mesh_legacy(
46 const GridType& grid,
47 double isovalue = 0.0,
48 double adaptivity = 0.0,
49 bool relax_disoriented_triangles = true)
50{
51 static_assert(MeshTrait<MeshType>::is_mesh(), "Input type is not Mesh");
52
53 openvdb::initialize();
54
55 using Scalar = ScalarOf<MeshType>;
56 using Index = IndexOf<MeshType>;
57 using VertexArray = VertexArrayOf<MeshType>;
58 using FacetArray = FacetArrayOf<MeshType>;
59 using RowVector3s = Eigen::Matrix<float, 1, 3>;
60 using RowVector3I = Eigen::Matrix<openvdb::Index32, 1, 3>;
61 using RowVector3I = Eigen::Matrix<openvdb::Index32, 1, 3>;
62 using RowVector4I = Eigen::Matrix<openvdb::Index32, 1, 4>;
63 using RowVector4i = Eigen::Matrix<Index, 1, 4>;
64
65 if (adaptivity < 0 || adaptivity > 1) {
66 logger().warn("Adaptivity needs to be between 0 and 1.");
67 adaptivity = std::max(0.0, std::min(1.0, adaptivity));
68 }
69
70 std::vector<openvdb::Vec3s> points;
71 std::vector<openvdb::Vec3I> triangles;
72 std::vector<openvdb::Vec4I> quads;
73
74 openvdb::tools::volumeToMesh(
75 grid,
76 points,
77 triangles,
78 quads,
79 isovalue,
80 adaptivity,
81 relax_disoriented_triangles);
82
83 VertexArray vertices(points.size(), 3);
84 FacetArray facets(triangles.size() + 2 * quads.size(), 3);
85
86 // Level set grids need their facet flipped
87 const bool need_flip = (grid.getGridClass() == openvdb::GRID_LEVEL_SET);
88
89 for (size_t v = 0; v < points.size(); ++v) {
90 const RowVector3s p(points[v].x(), points[v].y(), points[v].z());
91 vertices.row(v) << p.template cast<Scalar>();
92 }
93
94 for (size_t f = 0; f < triangles.size(); ++f) {
95 const RowVector3I triangle(triangles[f].x(), triangles[f].y(), triangles[f].z());
96 facets.row(f) << triangle.template cast<Index>();
97 if (need_flip) {
98 facets.row(f) = facets.row(f).reverse().eval();
99 }
100 }
101
102 for (size_t f = 0, o = triangles.size(); f < quads.size(); ++f) {
103 const RowVector4I quad_(quads[f].x(), quads[f].y(), quads[f].z(), quads[f].w());
104 const RowVector4i quad = quad_.template cast<Index>();
105 facets.row(o + 2 * f) << quad(0), quad(1), quad(3);
106 facets.row(o + 2 * f + 1) << quad(3), quad(1), quad(2);
107 if (need_flip) {
108 facets.row(o + 2 * f) = facets.row(o + 2 * f).reverse().eval();
109 facets.row(o + 2 * f + 1) = facets.row(o + 2 * f + 1).reverse().eval();
110 }
111 }
112
113 return lagrange::create_mesh<VertexArray, FacetArray>(std::move(vertices), std::move(facets));
114}
115
116} // namespace legacy
117} // namespace volume
118} // namespace lagrange
LA_CORE_API spdlog::logger & logger()
Retrieves the current logger.
Definition Logger.cpp:40
@ Scalar
Mesh attribute must have exactly 1 channel.
Definition AttributeFwd.h:56
SurfaceMesh< ToScalar, ToIndex > cast(const SurfaceMesh< FromScalar, FromIndex > &source_mesh, const AttributeFilter &convertible_attributes={}, std::vector< std::string > *converted_attributes_names=nullptr)
Cast a mesh to a mesh of different scalar and/or index type.
Main namespace for Lagrange.
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