modelio/submesh.rs
1use crate::error::Result;
2use crate::ffi;
3use crate::handle::ObjectHandle;
4use crate::material::Material;
5use crate::mesh::MeshBuffer;
6use crate::protocols::Named;
7use crate::types::{GeometryType, IndexBitDepth};
8use crate::util::{c_string, take_string};
9
10#[derive(Debug, Clone)]
11/// Wraps the corresponding Model I/O submesh counterpart.
12pub struct Submesh {
13 handle: ObjectHandle,
14}
15
16impl Named for Submesh {
17 fn name(&self) -> Option<String> {
18 self.name()
19 }
20
21 fn set_name(&self, name: &str) -> Result<()> {
22 self.set_name(name)
23 }
24}
25
26impl Submesh {
27 /// Builds this wrapper from the retained handle of the wrapped Model I/O submesh counterpart.
28 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
29 Self { handle }
30 }
31
32 /// Returns the opaque pointer used to call the wrapped Model I/O submesh counterpart.
33 pub(crate) fn as_ptr(&self) -> *mut core::ffi::c_void {
34 self.handle.as_ptr()
35 }
36
37 #[must_use]
38 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh counterpart.
39 pub fn name(&self) -> Option<String> {
40 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
41 take_string(unsafe { ffi::mdl_submesh_name_string(self.handle.as_ptr()) })
42 }
43
44 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh counterpart.
45 pub fn set_name(&self, name: &str) -> Result<()> {
46 let name = c_string(name)?;
47 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
48 unsafe { ffi::mdl_submesh_set_name(self.handle.as_ptr(), name.as_ptr()) };
49 Ok(())
50 }
51
52 #[must_use]
53 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh counterpart.
54 pub fn index_count(&self) -> usize {
55 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
56 unsafe { ffi::mdl_submesh_index_count(self.handle.as_ptr()) as usize }
57 }
58
59 #[must_use]
60 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh counterpart.
61 pub fn index_type(&self) -> Option<IndexBitDepth> {
62 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
63 IndexBitDepth::from_raw(unsafe { ffi::mdl_submesh_index_type(self.handle.as_ptr()) })
64 }
65
66 #[must_use]
67 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh counterpart.
68 pub fn geometry_type(&self) -> Option<GeometryType> {
69 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
70 GeometryType::from_raw(unsafe { ffi::mdl_submesh_geometry_type(self.handle.as_ptr()) })
71 }
72
73 #[must_use]
74 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh counterpart.
75 pub fn index_buffer(&self) -> Option<MeshBuffer> {
76 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
77 let ptr = unsafe { ffi::mdl_submesh_index_buffer(self.handle.as_ptr()) };
78 // SAFETY: The unsafe operation is valid in this context.
79 unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(MeshBuffer::from_handle)
80 }
81
82 #[must_use]
83 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh counterpart.
84 pub fn index_buffer_as_type(&self, index_type: IndexBitDepth) -> Option<MeshBuffer> {
85 // SAFETY: The unsafe operation is valid in this context.
86 let ptr = unsafe {
87 ffi::mdl_submesh_index_buffer_as_type(self.handle.as_ptr(), index_type.as_raw())
88 };
89 // SAFETY: The unsafe operation is valid in this context.
90 unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(MeshBuffer::from_handle)
91 }
92
93 #[must_use]
94 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh counterpart.
95 pub fn material(&self) -> Option<Material> {
96 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
97 let ptr = unsafe { ffi::mdl_submesh_material(self.handle.as_ptr()) };
98 // SAFETY: The unsafe operation is valid in this context.
99 unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(Material::from_handle)
100 }
101
102 #[must_use]
103 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh counterpart.
104 pub fn topology(&self) -> Option<SubmeshTopology> {
105 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
106 let ptr = unsafe { ffi::mdl_submesh_topology(self.handle.as_ptr()) };
107 // SAFETY: The unsafe operation is valid in this context.
108 unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(SubmeshTopology::from_handle)
109 }
110
111 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh counterpart.
112 pub fn set_topology(&self, topology: Option<&SubmeshTopology>) {
113 // SAFETY: The unsafe operation is valid in this context.
114 unsafe {
115 ffi::mdl_submesh_set_topology(
116 self.handle.as_ptr(),
117 topology.map_or(std::ptr::null_mut(), SubmeshTopology::as_ptr),
118 );
119 };
120 }
121
122 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh counterpart.
123 pub fn set_material(&self, material: Option<&Material>) {
124 // SAFETY: The unsafe operation is valid in this context.
125 unsafe {
126 ffi::mdl_submesh_set_material(
127 self.handle.as_ptr(),
128 material.map_or(std::ptr::null_mut(), Material::as_ptr),
129 );
130 };
131 }
132}
133
134#[derive(Debug, Clone)]
135/// Wraps the corresponding Model I/O submesh topology counterpart.
136pub struct SubmeshTopology {
137 handle: ObjectHandle,
138}
139
140impl SubmeshTopology {
141 /// Builds this wrapper from the retained handle of the wrapped Model I/O submesh topology counterpart.
142 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
143 Self { handle }
144 }
145
146 /// Returns the opaque pointer used to call the wrapped Model I/O submesh topology counterpart.
147 pub(crate) fn as_ptr(&self) -> *mut core::ffi::c_void {
148 self.handle.as_ptr()
149 }
150
151 /// Wraps the corresponding Model I/O initializer for the wrapped Model I/O submesh topology counterpart.
152 pub fn new(submesh: &Submesh) -> Result<Self> {
153 let mut out_topology = std::ptr::null_mut();
154 let mut out_error = std::ptr::null_mut();
155 // SAFETY: The unsafe operation is valid in this context.
156 let status = unsafe {
157 ffi::mdl_submesh_topology_new(submesh.as_ptr(), &mut out_topology, &mut out_error)
158 };
159 crate::util::status_result(status, out_error)?;
160 Ok(Self::from_handle(crate::util::required_handle(
161 out_topology,
162 "MDLSubmeshTopology",
163 )?))
164 }
165
166 #[must_use]
167 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh topology counterpart.
168 pub fn face_topology(&self) -> Option<MeshBuffer> {
169 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
170 let ptr = unsafe { ffi::mdl_submesh_topology_face_topology(self.handle.as_ptr()) };
171 // SAFETY: The unsafe operation is valid in this context.
172 unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(MeshBuffer::from_handle)
173 }
174
175 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh topology counterpart.
176 pub fn set_face_topology(&self, buffer: Option<&MeshBuffer>) {
177 // SAFETY: The unsafe operation is valid in this context.
178 unsafe {
179 ffi::mdl_submesh_topology_set_face_topology(
180 self.handle.as_ptr(),
181 buffer.map_or(std::ptr::null_mut(), MeshBuffer::as_ptr),
182 );
183 };
184 }
185
186 #[must_use]
187 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh topology counterpart.
188 pub fn face_count(&self) -> usize {
189 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
190 unsafe { ffi::mdl_submesh_topology_face_count(self.handle.as_ptr()) as usize }
191 }
192
193 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh topology counterpart.
194 pub fn set_face_count(&self, count: usize) {
195 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
196 unsafe { ffi::mdl_submesh_topology_set_face_count(self.handle.as_ptr(), count as u64) };
197 }
198
199 #[must_use]
200 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh topology counterpart.
201 pub fn vertex_crease_indices(&self) -> Option<MeshBuffer> {
202 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
203 let ptr = unsafe { ffi::mdl_submesh_topology_vertex_crease_indices(self.handle.as_ptr()) };
204 // SAFETY: The unsafe operation is valid in this context.
205 unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(MeshBuffer::from_handle)
206 }
207
208 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh topology counterpart.
209 pub fn set_vertex_crease_indices(&self, buffer: Option<&MeshBuffer>) {
210 // SAFETY: The unsafe operation is valid in this context.
211 unsafe {
212 ffi::mdl_submesh_topology_set_vertex_crease_indices(
213 self.handle.as_ptr(),
214 buffer.map_or(std::ptr::null_mut(), MeshBuffer::as_ptr),
215 );
216 };
217 }
218
219 #[must_use]
220 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh topology counterpart.
221 pub fn vertex_creases(&self) -> Option<MeshBuffer> {
222 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
223 let ptr = unsafe { ffi::mdl_submesh_topology_vertex_creases(self.handle.as_ptr()) };
224 // SAFETY: The unsafe operation is valid in this context.
225 unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(MeshBuffer::from_handle)
226 }
227
228 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh topology counterpart.
229 pub fn set_vertex_creases(&self, buffer: Option<&MeshBuffer>) {
230 // SAFETY: The unsafe operation is valid in this context.
231 unsafe {
232 ffi::mdl_submesh_topology_set_vertex_creases(
233 self.handle.as_ptr(),
234 buffer.map_or(std::ptr::null_mut(), MeshBuffer::as_ptr),
235 );
236 };
237 }
238
239 #[must_use]
240 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh topology counterpart.
241 pub fn vertex_crease_count(&self) -> usize {
242 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
243 unsafe { ffi::mdl_submesh_topology_vertex_crease_count(self.handle.as_ptr()) as usize }
244 }
245
246 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh topology counterpart.
247 pub fn set_vertex_crease_count(&self, count: usize) {
248 // SAFETY: The unsafe operation is valid in this context.
249 unsafe {
250 ffi::mdl_submesh_topology_set_vertex_crease_count(self.handle.as_ptr(), count as u64);
251 };
252 }
253
254 #[must_use]
255 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh topology counterpart.
256 pub fn edge_crease_indices(&self) -> Option<MeshBuffer> {
257 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
258 let ptr = unsafe { ffi::mdl_submesh_topology_edge_crease_indices(self.handle.as_ptr()) };
259 // SAFETY: The unsafe operation is valid in this context.
260 unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(MeshBuffer::from_handle)
261 }
262
263 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh topology counterpart.
264 pub fn set_edge_crease_indices(&self, buffer: Option<&MeshBuffer>) {
265 // SAFETY: The unsafe operation is valid in this context.
266 unsafe {
267 ffi::mdl_submesh_topology_set_edge_crease_indices(
268 self.handle.as_ptr(),
269 buffer.map_or(std::ptr::null_mut(), MeshBuffer::as_ptr),
270 );
271 };
272 }
273
274 #[must_use]
275 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh topology counterpart.
276 pub fn edge_creases(&self) -> Option<MeshBuffer> {
277 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
278 let ptr = unsafe { ffi::mdl_submesh_topology_edge_creases(self.handle.as_ptr()) };
279 // SAFETY: The unsafe operation is valid in this context.
280 unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(MeshBuffer::from_handle)
281 }
282
283 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh topology counterpart.
284 pub fn set_edge_creases(&self, buffer: Option<&MeshBuffer>) {
285 // SAFETY: The unsafe operation is valid in this context.
286 unsafe {
287 ffi::mdl_submesh_topology_set_edge_creases(
288 self.handle.as_ptr(),
289 buffer.map_or(std::ptr::null_mut(), MeshBuffer::as_ptr),
290 );
291 };
292 }
293
294 #[must_use]
295 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh topology counterpart.
296 pub fn edge_crease_count(&self) -> usize {
297 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
298 unsafe { ffi::mdl_submesh_topology_edge_crease_count(self.handle.as_ptr()) as usize }
299 }
300
301 /// Calls the corresponding Model I/O method on the wrapped Model I/O submesh topology counterpart.
302 pub fn set_edge_crease_count(&self, count: usize) {
303 // SAFETY: The unsafe operation is valid in this context.
304 unsafe {
305 ffi::mdl_submesh_topology_set_edge_crease_count(self.handle.as_ptr(), count as u64);
306 };
307 }
308}