@@ -184,6 +184,7 @@ def _add_to_solver(self):
184184 self ._add_particles_to_solver ()
185185 if self ._need_skinning :
186186 self ._add_vverts_to_solver ()
187+ self ._add_uvs_and_faces_to_solver ()
187188
188189 def _add_particles_to_solver (self ):
189190 raise NotImplementedError
@@ -229,6 +230,45 @@ def _kernel_add_vverts_to_solver(
229230 for j in range (self .solver ._n_vvert_supports ):
230231 self .solver .vverts_info .support_idxs [i_vv ][j ] = support_idxs_local [i_vv_ , j ] + self ._particle_start
231232
233+ def _add_uvs_and_faces_to_solver (self ):
234+ """Add UV coordinates and face indices to the solver's global buffers."""
235+ # Get UVs from vmesh (may be None if no texture)
236+ uvs = self ._vmesh .uvs if self ._vmesh is not None else None
237+ if uvs is not None and len (uvs ) == self .n_vverts :
238+ uvs_np = np .asarray (uvs , dtype = gs .np_float )
239+ else :
240+ # No UVs available, use zeros
241+ uvs_np = np .zeros ((self .n_vverts , 2 ), dtype = gs .np_float )
242+
243+ # Get face indices and offset them by vvert_start for global indexing
244+ faces_np = np .asarray (self ._vfaces , dtype = gs .np_int )
245+
246+ self ._kernel_add_uvs_and_faces_to_solver (
247+ uvs = uvs_np ,
248+ faces = faces_np ,
249+ )
250+
251+ @ti .kernel
252+ def _kernel_add_uvs_and_faces_to_solver (
253+ self ,
254+ uvs : ti .types .ndarray (element_dim = 1 ),
255+ faces : ti .types .ndarray (element_dim = 1 ),
256+ ):
257+ # Copy UVs to solver's global UV buffer
258+ for i_vv_ in range (self .n_vverts ):
259+ i_vv = i_vv_ + self ._vvert_start
260+ self .solver .vverts_uvs [i_vv ] = uvs [i_vv_ ]
261+
262+ # Copy faces to solver's global face buffer (with global vertex indices)
263+ for i_vf_ in range (self .n_vfaces ):
264+ i_vf = i_vf_ + self ._vface_start
265+ # Offset face indices by vvert_start for global vertex indexing
266+ self .solver .vfaces_indices [i_vf ] = ti .Vector ([
267+ ti .cast (faces [i_vf_ ][0 ], gs .ti_int ) + self ._vvert_start ,
268+ ti .cast (faces [i_vf_ ][1 ], gs .ti_int ) + self ._vvert_start ,
269+ ti .cast (faces [i_vf_ ][2 ], gs .ti_int ) + self ._vvert_start ,
270+ ])
271+
232272 def sample (self ):
233273 """
234274 Sample particles from the morph based on its type and the specified sampler.
0 commit comments