88
99from .._Cpp import CameraView as CameraViewCpp
1010from ..types import NumericMaxRank1 , NumericScalarNative , to_Vec3f
11+ from ._viewer_server import _get_viewer_server_cpp
1112
1213
13- class CameraView :
14+ class CamerasView :
1415 """
15- A view for a set of camera frusta and axes in a `Viewer` with parameters to adjust how the cameras are rendered.
16+ A view for a set of camera frusta and axes in a :class:`fvdb.viz.Scene` with parameters to
17+ adjust how the cameras are rendered.
1618
17- Each camera is represented by its camera-to-world and projection matrices, and drawn as a wireframe frustum
18- with orthogonal axes at the camera origin.
19+ Each camera is represented by its camera-to-world and projection matrices, and drawn as a
20+ wireframe frustum with orthogonal axes at the camera's origin.
1921 """
2022
2123 __PRIVATE__ = object ()
2224
23- def __init__ (self , view : CameraViewCpp , _private : Any = None ) :
25+ def _get_view (self ) -> CameraViewCpp :
2426 """
25- Create a new `CameraView` from a C++ implementation. This constructor is private and should not be called directly.
26- Use `Viewer.add_camera_view()` instead.
27+ Get the underlying C++ CameraView instance from the viewer server or raise
28+ a :class:`RuntimeError` if it is not registered.
29+
30+ Returns:
31+ view (CameraViewCpp): The C++ CameraView instance
32+ """
33+ server = _get_viewer_server_cpp ()
34+
35+ if not server .has_camera_view (self ._name ):
36+ raise RuntimeError (f"CameraView '{ self ._name } ' is not registered with the viewer server." )
37+ return server .get_camera_view (self ._name )
38+
39+ def __init__ (
40+ self ,
41+ scene_name : str ,
42+ name : str ,
43+ camera_to_world_matrices : torch .Tensor ,
44+ projection_matrices : torch .Tensor ,
45+ image_sizes : torch .Tensor ,
46+ axis_length : float ,
47+ axis_thickness : float ,
48+ frustum_line_width : float ,
49+ frustum_scale : float ,
50+ frustum_color : tuple [float , float , float ],
51+ frustum_near_plane : float ,
52+ frustum_far_plane : float ,
53+ enabled : bool ,
54+ _private : Any = None ,
55+ ):
56+ """
57+ Create a new :class:`CamerasView` or update an existing one within a scene with the given name.
58+
59+ .. warning::
60+
61+ This constructor is private and should never be called directly. Use :meth:`fvdb.viz.Scene.add_cameras()` instead.
62+
63+ Args:
64+ scene_name (str): The name of the scene the view belongs to.
65+ name (str): The name of the :class:`CamerasView`.
66+ camera_to_world_matrices (torch.Tensor): A tensor of shape ``(N, 4, 4)`` representing the camera-to-world matrices for N cameras.
67+ projection_matrices (torch.Tensor): A tensor of shape ``(N, 4, 4)`` representing the projection matrices for N cameras.
68+ image_sizes (torch.Tensor): A tensor of shape ``(N, 2)`` representing the image sizes (width, height) for N cameras.
69+ axis_length (float): The length of the axes drawn at each camera origin in world units.
70+ axis_thickness (float): The thickness of the axes drawn at each camera origin in pixel units.
71+ frustum_line_width (float): The line width of the frustum in pixel units.
72+ frustum_scale (float): The scale factor applied to the frustum visualization.
73+ frustum_color (tuple[float, float, float]): The color of the frustum lines as an RGB tuple with values in [0, 1].
74+ frustum_near_plane (float): The near plane distance for the camera frusta.
75+ frustum_far_plane (float): The far plane distance for the camera frusta.
76+ enabled (bool): Whether the camera frusta and axes are shown in the viewer.
77+ _private (Any): A private object to prevent direct construction. Must be :attr:`CamerasView.__PRIVATE__`.
2778 """
28- self ._view = view
2979 if _private is not self .__PRIVATE__ :
30- raise ValueError ("CameraView constructor is private. Use Viewer.add_camera_view() instead." )
80+ raise ValueError ("CameraView constructor is private. Use Scene.add_cameras() instead." )
81+
82+ server = _get_viewer_server_cpp ()
83+ self ._scene_name = scene_name
84+ self ._name = name
85+
86+ view : CameraViewCpp = server .add_camera_view (
87+ name = name ,
88+ camera_to_world_matrices = camera_to_world_matrices ,
89+ projection_matrices = projection_matrices ,
90+ image_sizes = image_sizes ,
91+ frustum_near_plane = frustum_near_plane ,
92+ frustum_far_plane = frustum_far_plane ,
93+ )
94+
95+ view .axis_length = axis_length
96+ view .axis_thickness = axis_thickness
97+ view .frustum_line_width = frustum_line_width
98+ view .frustum_scale = frustum_scale
99+ view .frustum_color = frustum_color
100+ view .visible = enabled
31101
32102 @property
33- def visible (self ) -> bool :
103+ def enabled (self ) -> bool :
34104 """
35- Get whether the camera frusta and axes are shown in the viewer .
105+ Return whether the camera frusta and axes are shown in the scene .
36106
37107 Returns:
38- bool: True if the camera frusta and axes are visible, False otherwise.
108+ enabled (bool): ``True`` if the camera frusta and axes are shown in the
109+ scene, ``False`` otherwise.
39110 """
40- return self ._view .visible
111+ view = self ._get_view ()
112+ return view .visible
41113
42- @visible .setter
43- def visible (self , visible : bool ):
114+ @enabled .setter
115+ def enabled (self , enabled : bool ):
44116 """
45- Set whether the camera frusta and axes are shown in the viewer.
117+ Set whether the camera frusta and axes are shown in the scene.
118+
46119 Args:
47- visible (bool): True to show the camera frusta and axes, False to hide them
120+ enabled (bool): `` True`` to show the camera frusta and axes, `` False`` to hide them.
48121 """
49- self ._view .visible = visible
122+ view = self ._get_view ()
123+ view .visible = enabled
50124
51125 @property
52126 def axis_length (self ) -> float :
53127 """
54128 Get the length of the axes drawn at each camera origin in world units.
55129
56130 Returns:
57- float: The length of the axes.
131+ length ( float) : The length of the axes.
58132 """
59- return self ._view .axis_length
133+ view = self ._get_view ()
134+ return view .axis_length
60135
61136 @axis_length .setter
62137 def axis_length (self , length : NumericScalarNative ):
63138 """
64139 Set the length of the axes drawn at each camera origin in world units.
140+
65141 Args:
66142 length (NumericScalarNative): The length of the axes.
67143 """
68- self ._view .axis_length = float (length )
144+ view = self ._get_view ()
145+ view .axis_length = float (length )
69146
70147 @property
71148 def axis_thickness (self ) -> float :
72149 """
73- Get the thickness of the axes drawn at each camera origin in world units.
150+ Get the thickness of the axes drawn at each camera origin in pixel units.
74151
75152 Returns:
76- float: The thickness of the axes.
153+ thickness ( float) : The thickness of the axes.
77154 """
78- return self ._view .axis_thickness
155+ view = self ._get_view ()
156+ return view .axis_thickness
79157
80158 @axis_thickness .setter
81159 def axis_thickness (self , thickness : NumericScalarNative ):
82160 """
83- Set the thickness of the axes drawn at each camera origin in world units.
161+ Set the thickness of the axes drawn at each camera origin in pixel units.
84162
85163 Args:
86164 thickness (NumericScalarNative): The thickness of the axes.
87165 """
88- self ._view .axis_thickness = float (thickness )
166+ view = self ._get_view ()
167+ view .axis_thickness = float (thickness )
89168
90169 @property
91170 def frustum_line_width (self ) -> float :
92171 """
93172 Get the line width of the frustum in the camera frustum view.
94173 """
95- return self ._view .frustum_line_width
174+ view = self ._get_view ()
175+ return view .frustum_line_width
96176
97177 @frustum_line_width .setter
98178 def frustum_line_width (self , width : NumericScalarNative ):
@@ -102,46 +182,63 @@ def frustum_line_width(self, width: NumericScalarNative):
102182 Args:
103183 width (NumericScalarNative): The line width of the frustum in world units.
104184 """
105- self ._view .frustum_line_width = float (width )
185+ view = self ._get_view ()
186+ view .frustum_line_width = float (width )
106187
107188 @property
108189 def frustum_scale (self ) -> float :
109190 """
110- Get the scale factor applied to the frustum visualization.
191+ Get the scale factor applied to the frustum visualization. Each frustum will have its size
192+ multiplied by this scale factor when rendered.
193+
194+ *E.g.* if the frustum has ``near = 0.1``, and ``far = 1.0``, then setting the frustum
195+ scale to ``2.0`` will render the frustum as if ``near = 0.2`` and ``far = 2.0``.
196+
197+ Returns:
198+ scale (float): The scale factor applied to the frustum visualization.
111199 """
112- return self ._view .frustum_scale
200+ view = self ._get_view ()
201+ return view .frustum_scale
113202
114203 @frustum_scale .setter
115204 def frustum_scale (self , scale : NumericScalarNative ):
116205 """
117- Set the scale factor applied to the frustum visualization.
206+ Set the scale factor applied to the frustum visualization. Each frustum will have its size
207+ multiplied by this scale factor when rendered.
208+
209+ *E.g.* if the frustum has ``near = 0.1``, and ``far = 1.0``, then setting the frustum
210+ scale to ``2.0`` will render the frustum as if ``near = 0.2`` and ``far = 2.0``.
118211
119212 Args:
120213 scale (NumericScalarNative): The scale factor to apply to the frustum visualization.
121214 """
122- self ._view .frustum_scale = float (scale )
215+ view = self ._get_view ()
216+ view .frustum_scale = float (scale )
123217
124218 @property
125219 def frustum_color (self ) -> torch .Tensor :
126220 """
127- Get the color of the frustum lines as a tensor of shape (3,) with values in [0, 1].
221+ Get the RGB color of the frustum lines as a tensor of shape ``(3,)`` with
222+ values in ``[0, 1]``.
128223
129224 Returns:
130- torch.Tensor: The color of the frustum lines.
225+ torch.Tensor: The RGB color of the frustum lines.
131226 """
132- r , g , b = self ._view .frustum_color
227+ view = self ._get_view ()
228+ r , g , b = view .frustum_color
133229 return torch .tensor ([r , g , b ], dtype = torch .float32 )
134230
135231 @frustum_color .setter
136232 def frustum_color (self , color : NumericMaxRank1 ):
137233 """
138- Set the color of the frustum lines.
234+ Set the RGB color of the frustum lines. Color values must be in ``[0, 1]`` .
139235
140236 Args:
141- color (NumericMaxRank1): A tensor-like object of shape (3,) representing the color of the frustum lines
142- with values in [0, 1].
237+ color (NumericMaxRank1): A tensor-like object of shape `` (3,)`` representing the
238+ RGB color of the frustum lines with values in `` [0, 1]`` .
143239 """
240+ view = self ._get_view ()
144241 color_vec3f = to_Vec3f (color ).cpu ().numpy ().tolist ()
145242 if any (c < 0.0 or c > 1.0 for c in color_vec3f ):
146243 raise ValueError (f"Frustum color components must be in [0, 1], got { color_vec3f } " )
147- self . _view .frustum_color = tuple (color_vec3f )
244+ view .frustum_color = tuple (color_vec3f )
0 commit comments