@@ -2481,6 +2481,12 @@ class Data:
24812481 min_response : wp .float32
24822482 sorting_mode : wp .int32
24832483
2484+ _WARP_DATA_DEPRECATION_MSG = (
2485+ "Gaussian.warp_data is deprecated in Newton 1.6; use the Gaussian.Data object returned by "
2486+ "Gaussian.finalize() instead."
2487+ )
2488+ _WARP_BVH_DEPRECATION_MSG = "Gaussian.warp_bvh is deprecated in Newton 1.6; use Gaussian.bvh instead."
2489+
24842490 def __init__ (
24852491 self ,
24862492 positions : np .ndarray ,
@@ -2554,8 +2560,8 @@ def __init__(
25542560 self ._sh_coeffs .setflags (write = False )
25552561
25562562 # GPU arrays populated by finalize()
2557- self .warp_bvh : wp .Bvh = None
2558- self .warp_data : Gaussian .Data = None
2563+ self ._warp_bvh : wp .Bvh = None
2564+ self ._warp_data : Gaussian .Data = None
25592565
25602566 # Inertia: Gaussians are render-only so they contribute no mass
25612567 self .has_inertia = False
@@ -2611,6 +2617,46 @@ def sorting_mode(self) -> SortingMode:
26112617 """Sorting mode, Gaussian.SortingMode."""
26122618 return self ._sorting_mode
26132619
2620+ @property
2621+ def bvh (self ) -> wp .Bvh | None :
2622+ """The finalized Warp BVH over the Gaussians, or ``None`` before :meth:`finalize`.
2623+
2624+ Mirrors the scene shape BVH exposed as :attr:`~newton.Model.bvh_shapes`.
2625+ Use :meth:`bvh_refit` to update it in place after the finalized
2626+ :class:`Data` arrays change.
2627+ """
2628+ return self ._warp_bvh
2629+
2630+ @property
2631+ def warp_data (self ) -> "Gaussian.Data | None" :
2632+ """Deprecated alias for the finalized Warp Gaussian data.
2633+
2634+ .. deprecated:: 1.6
2635+ Use the :class:`Data` object returned by :meth:`finalize` instead.
2636+ """
2637+ warnings .warn (self ._WARP_DATA_DEPRECATION_MSG , DeprecationWarning , stacklevel = 2 )
2638+ return self ._warp_data
2639+
2640+ @warp_data .setter
2641+ def warp_data (self , value : "Gaussian.Data | None" ) -> None :
2642+ warnings .warn (self ._WARP_DATA_DEPRECATION_MSG , DeprecationWarning , stacklevel = 2 )
2643+ self ._warp_data = value
2644+
2645+ @property
2646+ def warp_bvh (self ) -> wp .Bvh | None :
2647+ """Deprecated alias for :attr:`bvh`.
2648+
2649+ .. deprecated:: 1.6
2650+ Use :attr:`bvh` instead.
2651+ """
2652+ warnings .warn (self ._WARP_BVH_DEPRECATION_MSG , DeprecationWarning , stacklevel = 2 )
2653+ return self ._warp_bvh
2654+
2655+ @warp_bvh .setter
2656+ def warp_bvh (self , value : wp .Bvh | None ) -> None :
2657+ warnings .warn (self ._WARP_BVH_DEPRECATION_MSG , DeprecationWarning , stacklevel = 2 )
2658+ self ._warp_bvh = value
2659+
26142660 def _find_sh_degree (self ) -> int :
26152661 """Spherical harmonics degree (0-3), inferred from *sh_coeffs* shape."""
26162662 c = self ._sh_coeffs .shape [1 ]
@@ -2637,29 +2683,55 @@ def finalize(self, device: Devicelike = None, *, bvh_constructor: str | None = N
26372683 from ..sensors .warp_raytrace .gaussians import compute_gaussian_bvh_bounds # noqa: PLC0415
26382684
26392685 with wp .ScopedDevice (device ):
2640- self .warp_data = Gaussian .Data ()
2641- self .warp_data .transforms = wp .array (
2642- np .append (self ._positions , self ._rotations , axis = 1 ), dtype = wp .transformf
2643- )
2644- self .warp_data .scales = wp .array (self ._scales , dtype = wp .vec3f )
2645- self .warp_data .opacities = wp .array (self ._opacities , dtype = wp .float32 )
2646- self .warp_data .sh_coeffs = wp .array (self ._sh_coeffs , dtype = wp .float32 )
2647- self .warp_data .min_response = self .min_response
2648- self .warp_data .sorting_mode = self .sorting_mode
2649- self .warp_data .num_points = self .warp_data .transforms .shape [0 ]
2650-
2686+ warp_data = Gaussian .Data ()
2687+ warp_data .transforms = wp .array (np .append (self ._positions , self ._rotations , axis = 1 ), dtype = wp .transformf )
2688+ warp_data .scales = wp .array (self ._scales , dtype = wp .vec3f )
2689+ warp_data .opacities = wp .array (self ._opacities , dtype = wp .float32 )
2690+ warp_data .sh_coeffs = wp .array (self ._sh_coeffs , dtype = wp .float32 )
2691+ warp_data .min_response = self .min_response
2692+ warp_data .sorting_mode = self .sorting_mode
2693+ warp_data .num_points = warp_data .transforms .shape [0 ]
26512694 lowers = wp .zeros (self .count , dtype = wp .vec3f )
26522695 uppers = wp .zeros (self .count , dtype = wp .vec3f )
2653-
26542696 wp .launch (
26552697 kernel = compute_gaussian_bvh_bounds ,
26562698 dim = self .count ,
2657- inputs = [self . warp_data , lowers , uppers ],
2699+ inputs = [warp_data , lowers , uppers ],
26582700 )
2701+ warp_bvh = wp .Bvh (lowers , uppers , constructor = bvh_constructor )
2702+ warp_data .bvh_id = warp_bvh .id
2703+ self ._warp_data = warp_data
2704+ self ._warp_bvh = warp_bvh
2705+ return warp_data
2706+
2707+ def bvh_refit (self ) -> None :
2708+ """Refit the Gaussian :attr:`bvh` in place for the current finalized data.
26592709
2660- self .warp_bvh = wp .Bvh (lowers , uppers , constructor = bvh_constructor )
2661- self .warp_data .bvh_id = self .warp_bvh .id
2662- return self .warp_data
2710+ Recomputes per-Gaussian bounds from the finalized GPU data and refits
2711+ the BVH in place, keeping its existing topology. Call this after
2712+ mutating the finalized :class:`Data` arrays (e.g. ``transforms`` or
2713+ ``scales``) on the device so the acceleration structure tracks the
2714+ moved Gaussians. Structural changes (a different Gaussian count)
2715+ require a full rebuild via :meth:`finalize` instead.
2716+
2717+ This mirrors :meth:`~newton.Model.bvh_refit_shapes` for the scene
2718+ shape BVH.
2719+
2720+ Raises:
2721+ RuntimeError: If :meth:`finalize` has not been called yet.
2722+ """
2723+ from ..sensors .warp_raytrace .gaussians import compute_gaussian_bvh_bounds # noqa: PLC0415
2724+
2725+ if self ._warp_bvh is None or self ._warp_data is None :
2726+ raise RuntimeError ("Gaussian.bvh_refit() requires Gaussian.finalize() to have been called first." )
2727+
2728+ with wp .ScopedDevice (self ._warp_bvh .device ):
2729+ wp .launch (
2730+ kernel = compute_gaussian_bvh_bounds ,
2731+ dim = self .count ,
2732+ inputs = [self ._warp_data , self ._warp_bvh .lowers , self ._warp_bvh .uppers ],
2733+ )
2734+ self ._warp_bvh .refit ()
26632735
26642736 # ---- Factory methods -----------------------------------------------------
26652737
0 commit comments