Lagrange
bind_simple_scene.h
1/*
2 * Copyright 2023 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/python/tensor_utils.h>
15#include <lagrange/scene/SimpleScene.h>
16#include <lagrange/scene/simple_scene_convert.h>
17#include <lagrange/utils/assert.h>
18
19// clang-format off
20#include <lagrange/utils/warnoff.h>
21#include <Eigen/Core>
22#include <nanobind/nanobind.h>
23#include <nanobind/stl/optional.h>
24#include <lagrange/utils/warnon.h>
25// clang-format on
26
27#include <type_traits>
28
29namespace lagrange::python {
30
31namespace nb = nanobind;
32
33template <typename Scalar, typename Index>
34void bind_simple_scene(nb::module_& m)
35{
37 nb::class_<MeshInstance3D>(m, "MeshInstance3D", "A single mesh instance in a scene")
38 .def(nb::init<>())
39 .def_rw("mesh_index", &MeshInstance3D::mesh_index)
40 .def_prop_rw(
41 "transform",
42 [](MeshInstance3D& self) {
43 auto& M = self.transform.matrix();
44 using MatrixType = std::decay_t<decltype(M)>;
45 static_assert(!MatrixType::IsRowMajor, "Transformation matrix is not column major");
46
47 span<Scalar> data(M.data(), M.size());
48 size_t shape[2]{static_cast<size_t>(M.rows()), static_cast<size_t>(M.cols())};
49 int64_t stride[2]{1, 4};
50 return span_to_tensor(data, shape, stride, nb::cast(&self));
51 },
52 [](MeshInstance3D& self, Tensor<Scalar> tensor) {
53 auto [values, shape, stride] = tensor_to_span(tensor);
54 auto& M = self.transform.matrix();
55 using MatrixType = std::decay_t<decltype(M)>;
56 static_assert(!MatrixType::IsRowMajor, "Transformation matrix is not column major");
57
58 la_runtime_assert(is_dense(shape, stride));
59 la_runtime_assert(check_shape(shape, 4, 4));
60 if (stride[0] == 1) {
61 // Tensor is col major.
62 std::copy(values.begin(), values.end(), M.data());
63 } else {
64 // Tensor is row major.
65 M(0, 0) = values[0];
66 M(0, 1) = values[1];
67 M(0, 2) = values[2];
68 M(0, 3) = values[3];
69
70 M(1, 0) = values[4];
71 M(1, 1) = values[5];
72 M(1, 2) = values[6];
73 M(1, 3) = values[7];
74
75 M(2, 0) = values[8];
76 M(2, 1) = values[9];
77 M(2, 2) = values[10];
78 M(2, 3) = values[11];
79
80 M(3, 0) = values[12];
81 M(3, 1) = values[13];
82 M(3, 2) = values[14];
83 M(3, 3) = values[15];
84 }
85 });
86
88 nb::class_<SimpleScene3D>(m, "SimpleScene3D", "Simple scene container for instanced meshes")
89 .def(nb::init<>())
90 .def_prop_ro("num_meshes", &SimpleScene3D::get_num_meshes, "Number of meshes in the scene")
91 .def("num_instances", &SimpleScene3D::get_num_instances, "mesh_index"_a)
92 .def_prop_ro(
93 "total_num_instances",
94 &SimpleScene3D::compute_num_instances,
95 "Total number of instances for all meshes in the scene")
96 .def("get_mesh", &SimpleScene3D::get_mesh, "mesh_index"_a)
97 .def("ref_mesh", &SimpleScene3D::ref_mesh, "mesh_index"_a)
98 .def("get_instance", &SimpleScene3D::get_instance, "mesh_index"_a, "instance_index"_a)
99 .def("reserve_meshes", &SimpleScene3D::reserve_meshes, "num_meshes"_a)
100 .def("add_mesh", &SimpleScene3D::add_mesh, "mesh"_a)
101 .def(
102 "reserve_instances",
103 &SimpleScene3D::reserve_instances,
104 "mesh_index"_a,
105 "num_instances"_a)
106 .def("add_instance", &SimpleScene3D::add_instance, "instance"_a);
107
108 // Mesh to scene + scene to mesh
109
110 m.def(
111 "simple_scene_to_mesh",
112 [](const SimpleScene3D& scene,
113 bool normalize_normals,
114 bool normalize_tangents_bitangents,
115 bool preserve_attributes) {
116 TransformOptions transform_options;
117 transform_options.normalize_normals = normalize_normals;
118 transform_options.normalize_tangents_bitangents = normalize_tangents_bitangents;
119 return scene::simple_scene_to_mesh(scene, transform_options, preserve_attributes);
120 },
121 "scene"_a,
122 "normalize_normals"_a = TransformOptions{}.normalize_normals,
123 "normalize_tangents_bitangents"_a = TransformOptions{}.normalize_tangents_bitangents,
124 "preserve_attributes"_a = true,
125 R"(Converts a scene into a concatenated mesh with all the transforms applied.
126
127:param scene: Scene to convert.
128:param normalize_normals: If enabled, normals are normalized after transformation.
129:param normalize_tangents_bitangents: If enabled, tangents and bitangents are normalized after transformation.
130:param preserve_attributes: Preserve shared attributes and map them to the output mesh.
131
132:return: Concatenated mesh.)");
133
135 m.def(
136 "mesh_to_simple_scene",
137 [](const MeshType& mesh) { return scene::mesh_to_simple_scene<3>(mesh); },
138 "mesh"_a,
139 R"(Converts a single mesh into a simple scene with a single identity instance of the input mesh.
140
141:param mesh: Input mesh to convert.
142
143:return: Simple scene containing the input mesh.)");
144
145 m.def(
146 "meshes_to_simple_scene",
147 [](std::vector<MeshType> meshes) {
148 return scene::meshes_to_simple_scene<3>(std::move(meshes));
149 },
150 "meshes"_a,
151 R"(Converts a list of meshes into a simple scene with a single identity instance of each input mesh.
152
153:param meshes: Input meshes to convert.
154
155:return: Simple scene containing the input meshes.)");
156}
157
158} // namespace lagrange::python
Definition: Mesh.h:48
Simple scene container for instanced meshes.
Definition: SimpleScene.h:62
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.
#define la_runtime_assert(...)
Runtime assertion check.
Definition: assert.h:169
A single mesh instance in a scene.
Definition: SimpleScene.h:36