@@ -3863,29 +3863,29 @@ def set_mesh(self, name: str, pos: Any, faces: Any,
38633863 make_normals : bool = False ) -> None :
38643864 """Create new mesh geometry.
38653865
3866- Data is provided in form of arrays: vertices :math:`[x, y, z]`, with the shape
3867- ``(n, 3)``, and faces ( triplets of vertex indices), with the shape ``(n, 3)``
3868- or ``(m)`` where ``m = 3*n``. Data features can be visualized with color (array
3869- of RGB values assigned to the mesh vertices, shape ``(n, 3)``).
3870-
3871- Mesh ``normals`` can be provided as an array of 3D vectors. Mappng of normals to
3872- faces can be provided as an array of ``nidx`` indexes. If mapping is not provided
3873- then face vertex data is used (requires same number of vertices and normal vectors).
3874-
3875- Smooth shading normals can be pre-calculated if ``make_normals=True`` and normals
3876- data is not provided.
3877-
3878- Texture UV mapping ``uvmap`` can be provided as an array of 2D vectors. Mappng of
3879- UV coordinates to faces can be provided as an array of ``uvidx`` indexes. If mapping
3880- is not provided then face vertex data is used (requires same number of vertices
3881- and UV points).
3882-
3866+ Data is provided as vertices :math:`[x, y, z]`, with the shape ``(n, 3)``, and faces
3867+ ( triplets of vertex indices), with the shape ``(n, 3)`` or ``(m)`` where :math:`m = 3*n`.
3868+ Data features can be visualized with color (array of RGB values assigned to the mesh
3869+ vertices, shape ``(n, 3)``).
3870+
3871+ Mesh ``normals`` can be provided as an array of 3D vectors. Mappng of normals to
3872+ faces can be provided as an array of ``nidx`` indexes. If mapping is not provided
3873+ then face vertex data is used (requires same number of vertices and normal vectors).
3874+
3875+ Smooth shading normals can be pre-calculated if ``make_normals=True`` and normals
3876+ data is not provided.
3877+
3878+ Texture UV mapping ``uvmap`` can be provided as an array of 2D vectors. Mappng of
3879+ UV coordinates to faces can be provided as an array of ``uvidx`` indexes. If mapping
3880+ is not provided then face vertex data is used (requires same number of vertices
3881+ and UV points).
3882+
38833883 Parameters
38843884 ----------
38853885 name : string
38863886 Name of the new surface geometry.
38873887 pos : array_like
3888- XYZ values of mesh vertices.
3888+ XYZ values of the mesh vertices.
38893889 faces : array_like
38903890 Mesh faces as indices (triplets) to the ``pos`` array.
38913891 c : Any, optional
@@ -3999,7 +3999,7 @@ def set_mesh(self, name: str, pos: Any, faces: Any,
39993999 self ._logger .info ("...done, handle: %d" , g_handle )
40004000 self .geometry_names [g_handle ] = name
40014001 self .geometry_handles [name ] = g_handle
4002- self .geometry_sizes [name ] = pos . shape [ 0 ] * pos . shape [ 1 ]
4002+ self .geometry_sizes [name ] = n_vertices
40034003 else :
40044004 msg = "Mesh setup failed."
40054005 self ._logger .error (msg )
@@ -4011,6 +4011,161 @@ def set_mesh(self, name: str, pos: Any, faces: Any,
40114011 finally :
40124012 self ._padlock .release ()
40134013
4014+ def update_mesh (self , name : str ,
4015+ pos : Optional [Any ] = None ,
4016+ faces : Optional [Any ] = None ,
4017+ c : Optional [Any ] = None ,
4018+ normals : Optional [Any ] = None ,
4019+ nidx : Optional [Any ] = None ,
4020+ uvmap : Optional [Any ] = None ,
4021+ uvidx : Optional [Any ] = None ) -> None :
4022+ """Update data of an existing mesh geometry.
4023+
4024+ All data or only some of arrays may be uptated. If vertices and faces are left
4025+ unchanged then other arrays sizes should match the sizes of the mesh, i.e. ``c``
4026+ shape should match existing ``pos`` shape, ``nidx`` and ``uvidx`` shapes should
4027+ match ``faces`` shape or if index mapping is not provided then ``normals`` and
4028+ ``uvmap`` shapes should match ``pos`` shape.
4029+
4030+ Parameters
4031+ ----------
4032+ name : string
4033+ Name of the new surface geometry.
4034+ pos : array_like, optional
4035+ XYZ values of the mesh vertices.
4036+ faces : array_like, optional
4037+ Mesh faces as indices (triplets) to the ``pos`` array.
4038+ c : Any, optional
4039+ Colors of mesh vertices. Single value means a constant gray level.
4040+ 3-component array means a constant RGB color. Array of the shape
4041+ ``(n, 3)`` will set individual color for each vertex,
4042+ interpolated on face surfaces; ``n`` has to be equal to the vertex
4043+ number in ``pos`` array.
4044+ normals : array_like, optional
4045+ Normal vectors.
4046+ nidx : array_like, optional
4047+ Normal to face mapping, existing mesh ``faces`` is used if not provided.
4048+ uvmap : array_like, optional
4049+ Texture UV coordinates.
4050+ uvidx : array_like, optional
4051+ Texture UV to face mapping, existing mesh ``faces`` is used if not provided.
4052+ """
4053+
4054+ if name is None : raise ValueError ()
4055+ if not isinstance (name , str ): name = str (name )
4056+
4057+
4058+ if not name in self .geometry_handles :
4059+ msg = "Mesh %s does not exists yet, use set_mesh() instead." % name
4060+ self ._logger .error (msg )
4061+ if self ._raise_on_error : raise ValueError (msg )
4062+ return
4063+
4064+ m_vertices = self ._optix .get_geometry_size (name )
4065+ m_faces = self ._optix .get_faces_count (name )
4066+ size_changed = False
4067+
4068+ pos_ptr = 0
4069+ n_vertices = 0
4070+ if pos is not None :
4071+ if not isinstance (pos , np .ndarray ): pos = np .ascontiguousarray (pos , dtype = np .float32 )
4072+ assert len (pos .shape ) == 2 and pos .shape [0 ] > 2 and pos .shape [1 ] == 3 , "Required vertex data shape is (n,3), where n >= 3."
4073+ if pos .dtype != np .float32 : pos = np .ascontiguousarray (pos , dtype = np .float32 )
4074+ if not pos .flags ['C_CONTIGUOUS' ]: pos = np .ascontiguousarray (pos , dtype = np .float32 )
4075+ if pos .shape [0 ] != m_vertices : size_changed = True
4076+ pos_ptr = pos .ctypes .data
4077+ n_vertices = pos .shape [0 ]
4078+ m_vertices = n_vertices
4079+
4080+ faces_ptr = 0
4081+ n_faces = 0
4082+ if faces is not None :
4083+ if not isinstance (faces , np .ndarray ): faces = np .ascontiguousarray (faces , dtype = np .int32 )
4084+ if faces .dtype != np .int32 : faces = np .ascontiguousarray (faces , dtype = np .int32 )
4085+ if not faces .flags ['C_CONTIGUOUS' ]: faces = np .ascontiguousarray (faces , dtype = np .int32 )
4086+ assert (len (faces .shape ) == 2 and faces .shape [1 ] == 3 ) or (len (faces .shape ) == 1 and (faces .shape [0 ] % 3 == 0 )), "Required index shape is (n,3) or (m), where m is a multiple of 3."
4087+ faces_ptr = faces .ctypes .data
4088+ n_faces = faces .size // 3
4089+ m_faces = n_faces
4090+
4091+ c_ptr = 0
4092+ c_const = None
4093+ if size_changed and c is None : c = np .ascontiguousarray ([0.94 , 0.94 , 0.94 ], dtype = np .float32 )
4094+ if c is not None :
4095+ if isinstance (c , float ) or isinstance (c , int ): c = np .full (3 , c , dtype = np .float32 )
4096+ if not isinstance (c , np .ndarray ): c = np .ascontiguousarray (c , dtype = np .float32 )
4097+ if len (c .shape ) == 1 and c .shape [0 ] == 3 :
4098+ c_const = c
4099+ cm = np .zeros ((m_vertices , 3 ), dtype = np .float32 )
4100+ cm [:,:] = c
4101+ c = cm
4102+ assert c .shape [0 ] == m_vertices , "Colors shape must be (n,3), with n matching the number of mesh vertices."
4103+ if c .dtype != np .float32 : c = np .ascontiguousarray (c , dtype = np .float32 )
4104+ if not c .flags ['C_CONTIGUOUS' ]: c = np .ascontiguousarray (c , dtype = np .float32 )
4105+ c_ptr = c .ctypes .data
4106+
4107+ n_ptr = 0
4108+ n_normals = 0
4109+ if normals is not None :
4110+ if not isinstance (normals , np .ndarray ): normals = np .ascontiguousarray (normals , dtype = np .float32 )
4111+ if nidx is None :
4112+ assert normals .shape [0 ] == m_vertices , "If normal index data not provided, normals shape must be (n,3), with n matching the mesh vertex positions shape."
4113+ else :
4114+ assert len (normals .shape ) == 2 and normals .shape [0 ] > 2 and normals .shape [1 ] == 3 , "Required normals data shape is (n,3), where n >= 3."
4115+ if normals .dtype != np .float32 : normals = np .ascontiguousarray (normals , dtype = np .float32 )
4116+ if not normals .flags ['C_CONTIGUOUS' ]: normals = np .ascontiguousarray (normals , dtype = np .float32 )
4117+ n_ptr = normals .ctypes .data
4118+ n_normals = normals .shape [0 ]
4119+ make_normals = False
4120+
4121+ nidx_ptr = 0
4122+ if nidx is not None :
4123+ if not isinstance (nidx , np .ndarray ): nidx = np .ascontiguousarray (nidx , dtype = np .int32 )
4124+ if nidx .dtype != np .int32 : nidx = np .ascontiguousarray (nidx , dtype = np .int32 )
4125+ if not nidx .flags ['C_CONTIGUOUS' ]: nidx = np .ascontiguousarray (nidx , dtype = np .int32 )
4126+ assert (len (nidx .shape ) == 2 and nidx .shape [0 ] == m_faces ) or (len (nidx .shape ) == 1 and nidx .shape [0 ] == 3 * m_faces ), "Required same shape of normal index and face index arrays."
4127+ nidx_ptr = nidx .ctypes .data
4128+
4129+ uv_ptr = 0
4130+ n_uv = 0
4131+ if uvmap is not None :
4132+ if not isinstance (uvmap , np .ndarray ): uvmap = np .ascontiguousarray (uvmap , dtype = np .float32 )
4133+ if uvidx is None :
4134+ assert uvmap .shape [0 ] == m_vertices , "If UV index data not provided, uvmap shape must be (n,2), with n matching the number of mesh vertices."
4135+ else :
4136+ assert len (uvmap .shape ) == 2 and uvmap .shape [0 ] > 2 and uvmap .shape [1 ] == 2 , "Required UV data shape is (n,2), where n >= 3."
4137+ if uvmap .dtype != np .float32 : uvmap = np .ascontiguousarray (uvmap , dtype = np .float32 )
4138+ if not uvmap .flags ['C_CONTIGUOUS' ]: uvmap = np .ascontiguousarray (uvmap , dtype = np .float32 )
4139+ uv_ptr = uvmap .ctypes .data
4140+ n_uv = uvmap .shape [0 ]
4141+
4142+ uvidx_ptr = 0
4143+ if uvidx is not None :
4144+ if not isinstance (uvidx , np .ndarray ): uvidx = np .ascontiguousarray (uvidx , dtype = np .int32 )
4145+ if uvidx .dtype != np .int32 : uvidx = np .ascontiguousarray (uvidx , dtype = np .int32 )
4146+ if not uvidx .flags ['C_CONTIGUOUS' ]: uvidx = np .ascontiguousarray (uvidx , dtype = np .int32 )
4147+ assert (len (uvidx .shape ) == 2 and uvidx .shape [0 ] == m_faces ) or (len (uvidx .shape ) == 1 and uvidx .shape [0 ] == 3 * m_faces ), "Required same shape of UV index and face index arrays."
4148+ uvidx_ptr = uvidx .ctypes .data
4149+
4150+ try :
4151+ self ._padlock .acquire ()
4152+ self ._logger .info ("Update mesh %s..." , name )
4153+ g_handle = self ._optix .update_mesh (name , n_vertices , n_faces , n_normals , n_uv , pos_ptr , faces_ptr , c_ptr , n_ptr , nidx_ptr , uv_ptr , uvidx_ptr )
4154+
4155+ if (g_handle > 0 ) and (g_handle == self .geometry_handles [name ]):
4156+ self ._logger .info ("...done, handle: %d" , g_handle )
4157+ self .geometry_sizes [name ] = m_vertices
4158+ else :
4159+ msg = "Mesh update failed."
4160+ self ._logger .error (msg )
4161+ if self ._raise_on_error : raise RuntimeError (msg )
4162+
4163+ except Exception as e :
4164+ self ._logger .error (str (e ))
4165+ if self ._raise_on_error : raise
4166+ finally :
4167+ self ._padlock .release ()
4168+
40144169
40154170 def load_mesh_obj (self , file_name : str , mesh_name : Optional [str ] = None ,
40164171 c : Any = np .ascontiguousarray ([0.94 , 0.94 , 0.94 ], dtype = np .float32 ),
0 commit comments