Repository: fury-gl/fury
Pull request #968: NF: Adding point actor and all its requirements.
Author: login: ManishReddyR
Created: 2025-02-13T01:19:26Z | Merged: 2025-04-08T03:13:52Z

Hello.
Added the point actor with required geometry, material and test cases.

![point_nc](https://github.com/user-attachments/assets/bd5552e2-9c3a-4634-a6f3-26130bb9a372)

![point_normal](https://github.com/user-attachments/assets/3ae6e3ce-cd5e-4d86-a853-c3cb53158f72)

Thank you


Diff:
diff --git a/fury/actor.py b/fury/actor.py
index fb5678429..220655e69 100644
--- a/fury/actor.py
+++ b/fury/actor.py
@@ -1,7 +1,10 @@
 import numpy as np
 
-from fury.geometry import buffer_to_geometry, create_mesh
-from fury.material import _create_mesh_material
+from fury.geometry import buffer_to_geometry, create_mesh, create_point
+from fury.material import (
+    _create_mesh_material,
+    _create_points_material,
+)
 import fury.primitive as fp
 
 
@@ -1127,3 +1130,143 @@ def star(
         material=material,
         enable_picking=enable_picking,
     )
+
+
+def point(
+    centers,
+    *,
+    size=4.0,
+    colors=(1.0, 0.0, 0.0),
+    material="basic",
+    map=None,
+    aa=True,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many points with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3).
+        The positions of the points.
+    size : float
+        The size (diameter) of the points in logical pixels.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+        RGB or RGBA values in the range [0, 1].
+    material : str, optional
+        The material type for the points.
+        Options are 'basic', 'gaussian'.
+    map : TextureMap | Texture
+        The texture map specifying the color for each texture coordinate.
+    aa : bool, optional
+        Whether or not the points are anti-aliased in the shader.
+    opacity : float, optional
+        Takes values from 0 (fully transparent) to 1 (opaque).
+    enable_picking : bool, optional
+        Whether the points should be pickable in a 3D scene.
+
+    Returns
+    -------
+    point_actor : Actor
+        An point actor containing the generated points with the specified material
+        and properties.
+
+    Examples
+    --------
+    >>> from fury import window, actor
+    >>> import numpy as np
+    >>> scene = window.Scene()
+    >>> centers = np.random.rand(1000, 3) * 10
+    >>> colors = np.random.rand(1000, 3)
+    >>> point_actor = actor.point(centers=centers, colors=colors)
+    >>> scene.add(point_actor)
+    >>> show_manager = window.ShowManager(scene=scene, size=(600, 600))
+    >>> show_manager.start()
+    """
+    geo = buffer_to_geometry(
+        positions=centers.astype("float32"),
+        colors=colors.astype("float32"),
+    )
+
+    mat = _create_points_material(
+        size=size,
+        material=material,
+        map=map,
+        aa=aa,
+        opacity=opacity,
+        enable_picking=enable_picking,
+    )
+
+    obj = create_point(geo, mat)
+    return obj
+
+
+def marker(
+    centers,
+    *,
+    size=15,
+    colors=(1.0, 0.0, 0.0),
+    marker="circle",
+    edge_color="black",
+    edge_width=1.0,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many marker with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3).
+        The positions of the markers.
+    size : float
+        The size (diameter) of the points in logical pixels.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+        RGB or RGBA values in the range [0, 1].
+    marker : str | MarkerShape
+        The shape of the marker.
+        Options are "●": "circle", "+": "plus", "x": "cross", "♥": "heart",
+        "✳": "asterix".
+    edge_color : str | tuple | Color
+        The color of line marking the edge of the markers.
+    edge_width : float, optional
+        The width of the edge of the markers.
+    opacity : float, optional
+        Takes values from 0 (fully transparent) to 1 (opaque).
+    enable_picking : bool, optional
+        Whether the points should be pickable in a 3D scene.
+
+    Returns
+    -------
+    marker_actor : Actor
+        An marker actor containing the generated points with the specified material
+        and properties.
+
+    Examples
+    --------
+    >>> from fury import window, actor
+    >>> import numpy as np
+    >>> scene = window.Scene()
+    >>> centers = np.random.rand(1000, 3) * 10
+    >>> colors = np.random.rand(1000, 3)
+    >>> marker_actor = actor.marker(centers=centers, colors=colors)
+    >>> scene.add(marker_actor)
+    >>> show_manager = window.ShowManager(scene=scene, size=(600, 600))
+    >>> show_manager.start()
+    """
+    geo = buffer_to_geometry(
+        positions=centers.astype("float32"),
+        colors=colors.astype("float32"),
+    )
+
+    mat = _create_points_material(
+        material="marker",
+        size=size,
+        marker=marker,
+        edge_color=edge_color,
+        edge_width=edge_width,
+        opacity=opacity,
+        enable_picking=enable_picking,
+    )
+
+    obj = create_point(geo, mat)
+    return obj
diff --git a/fury/geometry.py b/fury/geometry.py
index af0b4ed44..b942f07ea 100644
--- a/fury/geometry.py
+++ b/fury/geometry.py
@@ -1,4 +1,13 @@
-from pygfx import Geometry, Mesh
+from fury.lib import (
+    Geometry,
+    Mesh,
+    MeshBasicMaterial,
+    MeshPhongMaterial,
+    Points,
+    PointsGaussianBlobMaterial,
+    PointsMarkerMaterial,
+    PointsMaterial,
+)
 
 
 def buffer_to_geometry(positions, **kwargs):
@@ -19,6 +28,9 @@ def buffer_to_geometry(positions, **kwargs):
     geo : Geometry
         The geometry object.
     """
+    if positions is None or positions.size == 0:
+        raise ValueError("positions array cannot be empty or None.")
+
     geo = Geometry(positions=positions, **kwargs)
     return geo
 
@@ -39,5 +51,44 @@ def create_mesh(geometry, material):
     mesh : Mesh
         The mesh object.
     """
+    if not isinstance(geometry, Geometry):
+        raise TypeError("geometry must be an instance of Geometry.")
+
+    if not isinstance(material, (MeshPhongMaterial, MeshBasicMaterial)):
+        raise TypeError(
+            "material must be an instance of MeshPhongMaterial or MeshBasicMaterial."
+        )
+
     mesh = Mesh(geometry=geometry, material=material)
     return mesh
+
+
+def create_point(geometry, material):
+    """
+    Create a point object.
+
+    Parameters
+    ----------
+    geometry : Geometry
+        The geometry object.
+    material : Material
+        The material object.
+
+    Returns
+    -------
+    points : Points
+        The point object.
+    """
+    if not isinstance(geometry, Geometry):
+        raise TypeError("geometry must be an instance of Geometry.")
+
+    if not isinstance(
+        material, (PointsMaterial, PointsGaussianBlobMaterial, PointsMarkerMaterial)
+    ):
+        raise TypeError(
+            "material must be an instance of PointsMaterial, "
+            "PointsGaussianBlobMaterial or PointsMarkerMaterial."
+        )
+
+    point = Points(geometry=geometry, material=material)
+    return point
diff --git a/fury/lib.py b/fury/lib.py
index a8986f574..53811b339 100644
--- a/fury/lib.py
+++ b/fury/lib.py
@@ -29,6 +29,16 @@
 Scene: TypeAlias = gfx.Scene
 Viewport: TypeAlias = gfx.Viewport
 
+Geometry = gfx.Geometry
+Mesh = gfx.Mesh
+Points = gfx.Points
+
+MeshBasicMaterial = gfx.MeshBasicMaterial
+MeshPhongMaterial = gfx.MeshPhongMaterial
+PointsMaterial = gfx.PointsMaterial
+PointsGaussianBlobMaterial = gfx.PointsGaussianBlobMaterial
+PointsMarkerMaterial = gfx.PointsMarkerMaterial
+
 DirectionalLight = gfx.DirectionalLight
 OrbitController = gfx.OrbitController
 PerspectiveCamera = gfx.PerspectiveCamera
diff --git a/fury/material.py b/fury/material.py
index 3999c4c66..333e8de92 100644
--- a/fury/material.py
+++ b/fury/material.py
@@ -1,7 +1,12 @@
 import pygfx as gfx
-from pygfx import Mesh
 from pygfx.renderers.wgpu import register_wgpu_render_function
 
+from fury.lib import (
+    Mesh,
+    PointsGaussianBlobMaterial,
+    PointsMarkerMaterial,
+    PointsMaterial,
+)
 from fury.shader import MeshBasicShader, MeshPhongShader
 
 
@@ -28,6 +33,31 @@ def __init__(self, **kwargs):
 register_wgpu_render_function(Mesh, MeshBasicMaterial)(MeshBasicShader)
 
 
+def validate_opacity(opacity):
+    """Ensure opacity is between 0 and 1."""
+    if not (0 <= opacity <= 1):
+        raise ValueError("Opacity must be between 0 and 1.")
+    return opacity
+
+
+def validate_color(color, opacity, mode):
+    """Validate and modify color based on opacity and mode."""
+    if color is None and mode == "auto":
+        raise ValueError("Color must be specified when mode is 'auto'.")
+
+    if mode == "vertex":
+        return (1, 1, 1)
+
+    if color is not None:
+        if len(color) == 3:
+            return (*color, opacity)
+        elif len(color) == 4:
+            return (*color[:3], color[3] * opacity)
+        else:
+            raise ValueError("Color must be a tuple of length 3 or 4.")
+    return color
+
+
 def _create_mesh_material(
     *,
     material="phong",
@@ -64,24 +94,8 @@ def _create_mesh_material(
     MeshMaterial
         A mesh material object of the specified type with the given properties.
     """
-
-    if not (0 <= opacity <= 1):
-        raise ValueError("Opacity must be between 0 and 1.")
-
-    if color is None and mode == "auto":
-        raise ValueError("Color must be specified when mode is 'auto'.")
-
-    elif color is not None:
-        if len(color) == 3:
-            color = (*color, opacity)
-        elif len(color) == 4:
-            color = color
-            color = (*color[:3], color[3] * opacity)
-        else:
-            raise ValueError("Color must be a tuple of length 3 or 4.")
-
-    if mode == "vertex":
-        color = (1, 1, 1)
+    opacity = validate_opacity(opacity)
+    color = validate_color(color, opacity, mode)
 
     if material == "phong":
         return MeshPhongMaterial(
@@ -99,3 +113,90 @@ def _create_mesh_material(
         )
     else:
         raise ValueError(f"Unsupported material type: {material}")
+
+
+def _create_points_material(
+    *,
+    material="basic",
+    color=(1.0, 1.0, 1.0),
+    size=4.0,
+    map=None,
+    aa=True,
+    marker="circle",
+    edge_color="black",
+    edge_width=1.0,
+    mode="vertex",
+    opacity=1.0,
+    enable_picking=True,
+):
+    """
+    Create a points material.
+
+    Parameters
+    ----------
+    material : str, optional
+        The type of material to create. Options are 'basic' (default),
+        'gaussian', and 'marker'.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+        RGB or RGBA values in the range [0, 1].
+    size : float, optional
+        The size (diameter) of the points in logical pixels.
+    map : TextureMap | Texture
+        The texture map specifying the color for each texture coordinate.
+    aa : bool, optional
+        Whether or not the points are anti-aliased in the shader.
+    marker : str | MarkerShape
+        The shape of the marker.
+        Options are "●": "circle", "+": "plus", "x": "cross", "♥": "heart",
+        "✳": "asterix".
+    edge_color : str | tuple | Color
+        The color of line marking the edge of the markers.
+    edge_width : float
+        The width of the edge of the markers.
+    mode : str, optional
+        The color mode of the material. Options are 'auto' and 'vertex'.
+    opacity : float, optional
+        The opacity of the material, from 0 (transparent) to 1 (opaque).
+        If RGBA is provided, the final alpha will be:
+        final_alpha = alpha_in_RGBA * opacity
+    enable_picking : bool, optional
+        Whether the material should be pickable in a scene.
+
+    Returns
+    -------
+    PointsMaterial
+        A point material object of the specified type with the given properties.
+    """
+    opacity = validate_opacity(opacity)
+    color = validate_color(color, opacity, mode)
+
+    if material == "basic":
+        return PointsMaterial(
+            color=color,
+            size=size,
+            color_mode=mode,
+            map=map,
+            aa=aa,
+            pick_write=enable_picking,
+        )
+    elif material == "gaussian":
+        return PointsGaussianBlobMaterial(
+            color=color,
+            size=size,
+            color_mode=mode,
+            map=map,
+            aa=aa,
+            pick_write=enable_picking,
+        )
+    elif material == "marker":
+        return PointsMarkerMaterial(
+            color=color,
+            size=size,
+            marker=marker,
+            edge_color=edge_color,
+            edge_width=edge_width,
+            pick_write=enable_picking,
+            color_mode=mode,
+        )
+    else:
+        raise ValueError(f"Unsupported material type: {material}")
diff --git a/fury/tests/test_actor.py b/fury/tests/test_actor.py
index ed8057d76..a6ee336fb 100644
--- a/fury/tests/test_actor.py
+++ b/fury/tests/test_actor.py
@@ -23,7 +23,7 @@ def validate_actors(centers, colors, actor_type="actor_name"):
     img = Image.open(fname)
     img_array = np.array(img)
 
-    mean_r, mean_g, mean_b, mean_a = np.mean(
+    mean_r, mean_g, mean_b, _mean_a = np.mean(
         img_array.reshape(-1, img_array.shape[2]), axis=0
     )
 
@@ -43,7 +43,7 @@ def validate_actors(centers, colors, actor_type="actor_name"):
     img = Image.open(fname_1)
     img_array = np.array(img)
 
-    mean_r, mean_g, mean_b, mean_a = np.mean(
+    mean_r, mean_g, mean_b, _mean_a = np.mean(
         img_array.reshape(-1, img_array.shape[2]), axis=0
     )
 
@@ -147,3 +147,89 @@ def test_star():
     centers = np.array([[0, 0, 0]])
     colors = np.array([[1, 0, 0]])
     validate_actors(centers=centers, colors=colors, actor_type="star")
+
+
+def test_point():
+    centers = np.array([[0, 0, 0]])
+    colors = np.array([[1, 0, 0]])
+    scene = window.Scene()
+    point_actor = actor.point(centers=centers, colors=colors)
+    scene.add(point_actor)
+
+    npt.assert_array_equal(point_actor.local.position, centers[0])
+
+    mean_vertex = np.round(np.mean(point_actor.geometry.positions.view, axis=0))
+    npt.assert_array_almost_equal(mean_vertex, centers[0])
+
+    fname = "point_test.png"
+    window.snapshot(scene=scene, fname=fname)
+
+    img = Image.open(fname)
+    img_array = np.array(img)
+
+    mean_r, mean_g, mean_b, _mean_a = np.mean(
+        img_array.reshape(-1, img_array.shape[2]), axis=0
+    )
+
+    assert mean_r > mean_b and mean_r > mean_g
+    scene.remove(point_actor)
+
+    point_actor_1 = actor.point(centers=centers, colors=colors, material="gaussian")
+    scene.add(point_actor_1)
+    fname_1 = "point_test_1.png"
+    window.snapshot(scene=scene, fname=fname_1)
+    img = Image.open(fname_1)
+    img_array = np.array(img)
+
+    mean_r, mean_g, mean_b, _mean_a = np.mean(
+        img_array.reshape(-1, img_array.shape[2]), axis=0
+    )
+
+    assert mean_r > mean_b and mean_r > mean_g
+    assert 0 < mean_r < 255
+    assert mean_g == 0 and mean_b == 0
+
+    scene.remove(point_actor_1)
+
+
+def test_marker():
+    centers = np.array([[0, 0, 0]])
+    colors = np.array([[1, 0, 0]])
+    scene = window.Scene()
+    marker_actor = actor.marker(centers=centers, colors=colors)
+    scene.add(marker_actor)
+
+    npt.assert_array_equal(marker_actor.local.position, centers[0])
+
+    mean_vertex = np.round(np.mean(marker_actor.geometry.positions.view, axis=0))
+    npt.assert_array_almost_equal(mean_vertex, centers[0])
+
+    fname = "marker_test.png"
+    window.snapshot(scene=scene, fname=fname)
+
+    img = Image.open(fname)
+    img_array = np.array(img)
+
+    mean_r, mean_g, mean_b, _mean_a = np.mean(
+        img_array.reshape(-1, img_array.shape[2]), axis=0
+    )
+
+    assert mean_r > mean_b and mean_r > mean_g
+    scene.remove(marker_actor)
+
+    marker_actor_1 = actor.marker(centers=centers, colors=colors, marker="heart")
+    scene.add(marker_actor_1)
+    fname_1 = "marker_test_1.png"
+    window.snapshot(scene=scene, fname=fname_1)
+    img = Image.open(fname_1)
+    img_array = np.array(img)
+
+    mean_r, mean_g, mean_b, _mean_a = np.mean(
+        img_array.reshape(-1, img_array.shape[2]), axis=0
+    )
+
+    assert mean_r > mean_b and mean_r > mean_g
+    assert 0 < mean_r < 255
+    assert mean_g == 0 and mean_b == 0
+
+    scene.remove(marker_actor_1)
diff --git a/fury/tests/test_geometry.py b/fury/tests/test_geometry.py
index ca1d5fea0..3712ce6d2 100644
--- a/fury/tests/test_geometry.py
+++ b/fury/tests/test_geometry.py
@@ -30,3 +30,14 @@ def test_create_mesh():
     mesh = geometry.create_mesh(geometry=geo, material=mat)
     assert mesh.geometry == geo
     assert mesh.material == mat
+
+
+def test_create_point():
+    vertices = np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2]]).astype("float32")
+    geo = geometry.buffer_to_geometry(vertices)
+    mat = material._create_points_material(
+        material="basic", color=(1, 0, 0), opacity=0.5, mode="auto"
+    )
+    point = geometry.create_point(geometry=geo, material=mat)
+    assert point.geometry == geo
+    assert point.material == mat
diff --git a/fury/tests/test_material.py b/fury/tests/test_material.py
index bd9e4383e..65af4ae61 100644
--- a/fury/tests/test_material.py
+++ b/fury/tests/test_material.py
@@ -2,6 +2,11 @@
 
 from fury import material, window
 from fury.geometry import buffer_to_geometry, create_mesh
+from fury.lib import (
+    PointsGaussianBlobMaterial,
+    PointsMarkerMaterial,
+    PointsMaterial,
+)
 from fury.material import _create_mesh_material
 from fury.primitive import prim_sphere
 
@@ -76,3 +81,45 @@ def test_create_mesh_material():
     # assert 0 <= mean_r <= 255 and 0 <= mean_g <= 255 and 0 <= mean_b <= 255
     #
     # assert sum([mean_r, mean_g, mean_b]) > 0
+
+
+def test_create_point_material():
+    color = (1, 0, 0)
+    mat = material._create_points_material(
+        material="basic", color=color, opacity=0.5, mode="auto"
+    )
+    assert isinstance(mat, PointsMaterial)
+    assert mat.color == color + (0.5,)
+    assert mat.color_mode == "auto"
+
+    color = (1, 0, 0)
+    mat = material._create_points_material(
+        material="gaussian", color=color, opacity=0.5, mode="auto"
+    )
+    assert isinstance(mat, PointsGaussianBlobMaterial)
+    assert mat.color == color + (0.5,)
+    assert mat.color_mode == "auto"
+
+    color = (1, 0, 0)
+    mat = material._create_points_material(
+        material="marker", color=color, opacity=0.5, mode="auto"
+    )
+    assert isinstance(mat, PointsMarkerMaterial)
+    assert mat.color == color + (0.5,)
+    assert mat.color_mode == "auto"
+
+    color = (1, 0, 0, 0.5)
+    mat = material._create_points_material(
+        material="basic", color=color, opacity=0.5, mode="auto"
+    )
+    assert isinstance(mat, PointsMaterial)
+    assert mat.color == (1, 0, 0, 0.25)
+    assert mat.color_mode == "auto"
+
+    color = (1, 0, 0)
+    mat = material._create_points_material(
+        material="basic", color=color, opacity=0.5, mode="vertex"
+    )
+    assert isinstance(mat, PointsMaterial)
+    assert mat.color == (1, 1, 1)
+    assert mat.color_mode == "vertex"


Reviews:
user: login: maharshi-gor
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T17:02:36Z
user: login: maharshi-gor
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T17:06:53Z
user: login: maharshi-gor
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T17:07:33Z
user: login: maharshi-gor
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T17:09:29Z
user: login: maharshi-gor
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T17:09:49Z
user: login: maharshi-gor
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T17:10:32Z
user: login: maharshi-gor
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T17:14:13Z
user: login: maharshi-gor
body: I have left a lot of comments on this

![image](https://github.com/user-attachments/assets/0cdbd982-28ea-49fb-a9fe-cd8e25045fe1)

Also @ManishReddyR why do we see the borders changing its colors while moving the scroll wheel
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T17:18:56Z
user: login: ManishReddyR
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T01:47:22Z
user: login: ManishReddyR
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-03T00:01:07Z
user: login: ManishReddyR
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-03T00:01:15Z
user: login: maharshi-gor
body: The PR looks good but there are some docstring changes required and some methods needs refractoring.
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-04T18:07:15Z
user: login: maharshi-gor
body: Just fix one small comment on the marker actor method parameters.
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T13:42:29Z
user: login: maharshi-gor
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-08T03:13:19Z

Review comments:
diff_hunk: @@ -1,4 +1,4 @@
-from pygfx import Geometry, Mesh
+from pygfx import Geometry, Mesh, Points
path: fury/geometry.py
user: login: maharshi-gor
body: import the pygfx things in fury.lib and then use it.
created_at: 2025-03-24T17:02:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -99,3 +99,162 @@ def _create_mesh_material(
         )
     else:
         raise ValueError(f"Unsupported material type: {material}")
+
+
+def _create_points_material(
+    *,
+    material="basic",
+    color=(1.0, 1.0, 1.0),
+    size=4,
+    map=None,
+    aa=True,
+    mode="vertex",
+    opacity=1.0,
+    enable_picking=True,
+):
+    """
+     Create a points material.
+
+     Parameters
+     ----------
+     material : str, optional
+         The type of material to create. Options are 'baisc' (default),
+         'gaussian', and 'marker'.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+         RGB or RGBA values in the range [0, 1].
+     size : float
+         The size (diameter) of the points in logical pixels. Default 4.
+     map : TextureMap | Texture
+         The texture map specifying the color for each texture coordinate.
+     aa : bool
+         Whether or not the points are anti-aliased in the shader. Default True.
+     mode : str, optional
+         The color mode of the material. Options are 'auto' and 'vertex'.
+     opacity : float, optional
+         The opacity of the material, from 0 (transparent) to 1 (opaque).
+         If RGBA is provided, the final alpha will be:
+         final_alpha = alpha_in_RGBA * opacity
+     enable_picking : bool, optional
+         Whether the material should be pickable in a scene.
+
+     Returns
+     -------
+     PointsMaterial
+         A point material object of the specified type with the given properties.
+    """
+
+    if not (0 <= opacity <= 1):
+        raise ValueError("Opacity must be between 0 and 1.")
+
+    if color is None and mode == "auto":
+        raise ValueError("Color must be specified when mode is 'auto'.")
+
+    elif color is not None:
+        if len(color) == 3:
+            color = (*color, opacity)
+        elif len(color) == 4:
+            color = color
+            color = (*color[:3], color[3] * opacity)
+        else:
+            raise ValueError("Color must be a tuple of length 3 or 4.")
+
+    if mode == "vertex":
+        color = (1, 1, 1)
+
+    if material == "basic":
+        return gfx.PointsMaterial(
+            color=color,
+            size=size,
+            color_mode=mode,
+            map=map,
+            aa=aa,
+            pick_write=enable_picking,
+        )
+    elif material == "gaussian":
+        return gfx.PointsGaussianBlobMaterial(
+            color=color,
+            size=size,
+            color_mode=mode,
+            map=map,
+            aa=aa,
+            pick_write=enable_picking,
+        )
+    else:
+        raise ValueError(f"Unsupported material type: {material}")
+
+
+def _create_marker_material(
+    *,
+    material="marker",
+    color=(1.0, 1.0, 1.0),
+    size=4,
+    marker="circle",
+    edge_color="black",
+    edge_width=1,
+    mode="vertex",
+    opacity=1.0,
+    enable_picking=True,
+):
+    """
+     Create a marker material.
+
+     Parameters
+     ----------
+     material : str, optional
+         The type of material to create. Options are 'baisc' (default),
+         'gaussian', and 'marker'.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+         RGB or RGBA values in the range [0, 1].
+     size : float
+         The size (diameter) of the points in logical pixels. Default 4.
+     marker : str | MarkerShape
+         The shape of the marker. Default 'circle'.
+     edge_color : str | tuple | Color
+         The color of line marking the edge of the markers. Default 'black'.
+     edge_width : float
+         The width of the edge of the markers. Default 1.
+     mode : str, optional
+         The color mode of the material. Options are 'auto' and 'vertex'.
+     opacity : float, optional
+         The opacity of the material, from 0 (transparent) to 1 (opaque).
+         If RGBA is provided, the final alpha will be:
+         final_alpha = alpha_in_RGBA * opacity
+     enable_picking : bool, optional
+         Whether the material should be pickable in a scene.
+
+     Returns
+     -------
+     MarkerMaterial
+         A marker material object of the specified type with the given properties.
+    """
+
+    if not (0 <= opacity <= 1):
path: fury/material.py
user: login: maharshi-gor
body: These kind of checks can be curated into a separate file called validation and where we can verify the opacity, color and other things.

All the actors and other functions can leverage that validation if they need to check opacity value or colors 
created_at: 2025-03-24T17:06:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -17,46 +17,46 @@ def validate_actors(centers, colors, actor_type="actor_name"):
     npt.assert_array_almost_equal(mean_vertex, centers[0])
 
     assert get_actor.prim_count == 1
-    fname = f"{actor_type}_test.png"
-    window.snapshot(scene=scene, fname=fname)
+    # fname = f"{actor_type}_test.png"
path: fury/tests/test_actor.py
user: login: maharshi-gor
body: Why are we commenting a lot of stuff?

created_at: 2025-03-24T17:07:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1127,3 +1131,139 @@ def star(
         material=material,
         enable_picking=enable_picking,
     )
+
+
+def point(
+    centers,
+    *,
+    size=4,
+    colors=(1.0, 0.0, 0.0),
+    material="basic",
+    map=None,
+    aa=True,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many points with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
+        The positions of the points. If None, random points will be generated.
+    size : float
+        The size (diameter) of the points in logical pixels. Default 4.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+        RGB or RGBA values in the range [0, 1].
+    material : str, optional
+        The material type for the points. Options are 'basic', 'gaussian'.
+    map : TextureMap | Texture
+        The texture map specifying the color for each texture coordinate.
+    aa : bool
+        Whether or not the points are anti-aliased in the shader. Default True.
+    opacity : float, optional
+        Takes values from 0 (fully transparent) to 1 (opaque).
+    enable_picking : bool, optional
+        Whether the points should be pickable in a 3D scene.
+
+    Returns
+    -------
+    point_actor : Actor
+        An point actor containing the generated points with the specified material
+        and properties.
+
+    Examples
+    --------
+    >>> from fury import window, actor
+    >>> import numpy as np
+    >>> scene = window.Scene()
+    >>> centers = np.random.rand(1000, 3) * 10
+    >>> colors = np.random.rand(1000, 3)
+    >>> point_actor = actor.point(centers=centers, colors=colors)
+    >>> scene.add(point_actor)
+    >>> show_manager = window.ShowManager(scene=scene, size=(600, 600))
+    >>> show_manager.start()
+    """
+    geo = buffer_to_geometry(
path: fury/actor.py
user: login: maharshi-gor
body: No check for the shape of the centers or if they are empty?
created_at: 2025-03-24T17:09:29Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1127,3 +1131,139 @@ def star(
         material=material,
         enable_picking=enable_picking,
     )
+
+
+def point(
+    centers,
+    *,
+    size=4,
+    colors=(1.0, 0.0, 0.0),
+    material="basic",
+    map=None,
+    aa=True,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many points with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
+        The positions of the points. If None, random points will be generated.
+    size : float
+        The size (diameter) of the points in logical pixels. Default 4.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+        RGB or RGBA values in the range [0, 1].
+    material : str, optional
+        The material type for the points. Options are 'basic', 'gaussian'.
+    map : TextureMap | Texture
+        The texture map specifying the color for each texture coordinate.
+    aa : bool
+        Whether or not the points are anti-aliased in the shader. Default True.
+    opacity : float, optional
+        Takes values from 0 (fully transparent) to 1 (opaque).
+    enable_picking : bool, optional
+        Whether the points should be pickable in a 3D scene.
+
+    Returns
+    -------
+    point_actor : Actor
+        An point actor containing the generated points with the specified material
+        and properties.
+
+    Examples
+    --------
+    >>> from fury import window, actor
+    >>> import numpy as np
+    >>> scene = window.Scene()
+    >>> centers = np.random.rand(1000, 3) * 10
+    >>> colors = np.random.rand(1000, 3)
+    >>> point_actor = actor.point(centers=centers, colors=colors)
+    >>> scene.add(point_actor)
+    >>> show_manager = window.ShowManager(scene=scene, size=(600, 600))
+    >>> show_manager.start()
+    """
+    geo = buffer_to_geometry(
+        positions=centers.astype("float32"),
+        colors=colors.astype("float32"),
+    )
+
+    mat = _create_points_material(
+        size=size,
+        material=material,
+        map=map,
+        aa=aa,
+        opacity=opacity,
+        enable_picking=enable_picking,
+    )
+
+    obj = create_point(geo, mat)
+    return obj
+
+
+def marker(
+    centers,
+    *,
+    size=15,
+    colors=(1.0, 0.0, 0.0),
+    marker="circle",
+    edge_color="black",
+    edge_width=1,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many marker with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
+        The positions of the points. If None, random points will be generated.
+    size : float
+        The size (diameter) of the points in logical pixels. Default 4.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+        RGB or RGBA values in the range [0, 1].
+    marker : str | MarkerShape
+        The shape of the marker. Default 'circle'.
+    edge_color : str | tuple | Color
+        The color of line marking the edge of the markers. Default 'black'.
+    edge_width : float
+        The width of the edge of the markers. Default 1.
+    opacity : float, optional
+        Takes values from 0 (fully transparent) to 1 (opaque).
+    enable_picking : bool, optional
+        Whether the points should be pickable in a 3D scene.
+
+    Returns
+    -------
+    marker_actor : Actor
+        An marker actor containing the generated points with the specified material
+        and properties.
+
+    Examples
+    --------
+    >>> from fury import window, actor
+    >>> import numpy as np
+    >>> scene = window.Scene()
+    >>> centers = np.random.rand(1000, 3) * 10
+    >>> colors = np.random.rand(1000, 3)
+    >>> marker_actor = actor.marker(centers=centers, colors=colors)
+    >>> scene.add(marker_actor)
+    >>> show_manager = window.ShowManager(scene=scene, size=(600, 600))
+    >>> show_manager.start()
+    """
+    geo = buffer_to_geometry(
path: fury/actor.py
user: login: maharshi-gor
body: no check for shape of the centers or if they are empty
created_at: 2025-03-24T17:09:49Z
author_association: CONTRIBUTOR
diff_hunk: @@ -41,3 +41,23 @@ def create_mesh(geometry, material):
     """
     mesh = Mesh(geometry=geometry, material=material)
     return mesh
+
+
+def create_point(geometry, material):
+    """
+    Create a point object.
+
+    Parameters
+    ----------
+    geometry : Geometry
+        The geometry object.
+    material : Material
+        The material object.
+
+    Returns
+    -------
+    points : Points
+        The point object.
+    """
+    point = Points(geometry=geometry, material=material)
path: fury/geometry.py
user: login: maharshi-gor
body: Any public method needs validations for the inputs
created_at: 2025-03-24T17:10:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1127,3 +1131,139 @@ def star(
         material=material,
         enable_picking=enable_picking,
     )
+
+
+def point(
+    centers,
+    *,
+    size=4,
+    colors=(1.0, 0.0, 0.0),
+    material="basic",
+    map=None,
+    aa=True,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many points with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
+        The positions of the points. If None, random points will be generated.
+    size : float
+        The size (diameter) of the points in logical pixels. Default 4.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+        RGB or RGBA values in the range [0, 1].
+    material : str, optional
+        The material type for the points. Options are 'basic', 'gaussian'.
+    map : TextureMap | Texture
+        The texture map specifying the color for each texture coordinate.
+    aa : bool
+        Whether or not the points are anti-aliased in the shader. Default True.
+    opacity : float, optional
+        Takes values from 0 (fully transparent) to 1 (opaque).
+    enable_picking : bool, optional
+        Whether the points should be pickable in a 3D scene.
+
+    Returns
+    -------
+    point_actor : Actor
+        An point actor containing the generated points with the specified material
+        and properties.
+
+    Examples
+    --------
+    >>> from fury import window, actor
+    >>> import numpy as np
+    >>> scene = window.Scene()
+    >>> centers = np.random.rand(1000, 3) * 10
+    >>> colors = np.random.rand(1000, 3)
+    >>> point_actor = actor.point(centers=centers, colors=colors)
+    >>> scene.add(point_actor)
+    >>> show_manager = window.ShowManager(scene=scene, size=(600, 600))
+    >>> show_manager.start()
+    """
+    geo = buffer_to_geometry(
+        positions=centers.astype("float32"),
+        colors=colors.astype("float32"),
+    )
+
+    mat = _create_points_material(
+        size=size,
+        material=material,
+        map=map,
+        aa=aa,
+        opacity=opacity,
+        enable_picking=enable_picking,
+    )
+
+    obj = create_point(geo, mat)
+    return obj
+
+
+def marker(
+    centers,
+    *,
+    size=15,
+    colors=(1.0, 0.0, 0.0),
+    marker="circle",
+    edge_color="black",
+    edge_width=1,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many marker with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
+        The positions of the points. If None, random points will be generated.
+    size : float
+        The size (diameter) of the points in logical pixels. Default 4.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+        RGB or RGBA values in the range [0, 1].
+    marker : str | MarkerShape
path: fury/actor.py
user: login: maharshi-gor
body: provide the options that you can make

created_at: 2025-03-24T17:14:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -17,46 +17,46 @@ def validate_actors(centers, colors, actor_type="actor_name"):
     npt.assert_array_almost_equal(mean_vertex, centers[0])
 
     assert get_actor.prim_count == 1
-    fname = f"{actor_type}_test.png"
-    window.snapshot(scene=scene, fname=fname)
+    # fname = f"{actor_type}_test.png"
path: fury/tests/test_actor.py
user: login: ManishReddyR
body: Due to the new pygfx update, all the commented test cases are getting failed because the actor created is looking like this.

![arrow_test_1](https://github.com/user-attachments/assets/0f1cff29-303f-46d6-b597-2550c74fc77a)

I not sure whats happening, but I think its due the change of shader form the recent update.

created_at: 2025-03-25T01:47:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1127,3 +1131,139 @@ def star(
         material=material,
         enable_picking=enable_picking,
     )
+
+
+def point(
+    centers,
+    *,
+    size=4,
+    colors=(1.0, 0.0, 0.0),
+    material="basic",
+    map=None,
+    aa=True,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many points with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
+        The positions of the points. If None, random points will be generated.
+    size : float
+        The size (diameter) of the points in logical pixels. Default 4.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+        RGB or RGBA values in the range [0, 1].
+    material : str, optional
+        The material type for the points. Options are 'basic', 'gaussian'.
+    map : TextureMap | Texture
+        The texture map specifying the color for each texture coordinate.
+    aa : bool
+        Whether or not the points are anti-aliased in the shader. Default True.
+    opacity : float, optional
+        Takes values from 0 (fully transparent) to 1 (opaque).
+    enable_picking : bool, optional
+        Whether the points should be pickable in a 3D scene.
+
+    Returns
+    -------
+    point_actor : Actor
+        An point actor containing the generated points with the specified material
+        and properties.
+
+    Examples
+    --------
+    >>> from fury import window, actor
+    >>> import numpy as np
+    >>> scene = window.Scene()
+    >>> centers = np.random.rand(1000, 3) * 10
+    >>> colors = np.random.rand(1000, 3)
+    >>> point_actor = actor.point(centers=centers, colors=colors)
+    >>> scene.add(point_actor)
+    >>> show_manager = window.ShowManager(scene=scene, size=(600, 600))
+    >>> show_manager.start()
+    """
+    geo = buffer_to_geometry(
path: fury/actor.py
user: login: ManishReddyR
body: I have added a check for positions, as a validation for buffer_to_geometry in fury/geometry.py
created_at: 2025-04-03T00:01:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1127,3 +1131,139 @@ def star(
         material=material,
         enable_picking=enable_picking,
     )
+
+
+def point(
+    centers,
+    *,
+    size=4,
+    colors=(1.0, 0.0, 0.0),
+    material="basic",
+    map=None,
+    aa=True,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many points with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
+        The positions of the points. If None, random points will be generated.
+    size : float
+        The size (diameter) of the points in logical pixels. Default 4.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+        RGB or RGBA values in the range [0, 1].
+    material : str, optional
+        The material type for the points. Options are 'basic', 'gaussian'.
+    map : TextureMap | Texture
+        The texture map specifying the color for each texture coordinate.
+    aa : bool
+        Whether or not the points are anti-aliased in the shader. Default True.
+    opacity : float, optional
+        Takes values from 0 (fully transparent) to 1 (opaque).
+    enable_picking : bool, optional
+        Whether the points should be pickable in a 3D scene.
+
+    Returns
+    -------
+    point_actor : Actor
+        An point actor containing the generated points with the specified material
+        and properties.
+
+    Examples
+    --------
+    >>> from fury import window, actor
+    >>> import numpy as np
+    >>> scene = window.Scene()
+    >>> centers = np.random.rand(1000, 3) * 10
+    >>> colors = np.random.rand(1000, 3)
+    >>> point_actor = actor.point(centers=centers, colors=colors)
+    >>> scene.add(point_actor)
+    >>> show_manager = window.ShowManager(scene=scene, size=(600, 600))
+    >>> show_manager.start()
+    """
+    geo = buffer_to_geometry(
+        positions=centers.astype("float32"),
+        colors=colors.astype("float32"),
+    )
+
+    mat = _create_points_material(
+        size=size,
+        material=material,
+        map=map,
+        aa=aa,
+        opacity=opacity,
+        enable_picking=enable_picking,
+    )
+
+    obj = create_point(geo, mat)
+    return obj
+
+
+def marker(
+    centers,
+    *,
+    size=15,
+    colors=(1.0, 0.0, 0.0),
+    marker="circle",
+    edge_color="black",
+    edge_width=1,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many marker with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
+        The positions of the points. If None, random points will be generated.
+    size : float
+        The size (diameter) of the points in logical pixels. Default 4.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+        RGB or RGBA values in the range [0, 1].
+    marker : str | MarkerShape
+        The shape of the marker. Default 'circle'.
+    edge_color : str | tuple | Color
+        The color of line marking the edge of the markers. Default 'black'.
+    edge_width : float
+        The width of the edge of the markers. Default 1.
+    opacity : float, optional
+        Takes values from 0 (fully transparent) to 1 (opaque).
+    enable_picking : bool, optional
+        Whether the points should be pickable in a 3D scene.
+
+    Returns
+    -------
+    marker_actor : Actor
+        An marker actor containing the generated points with the specified material
+        and properties.
+
+    Examples
+    --------
+    >>> from fury import window, actor
+    >>> import numpy as np
+    >>> scene = window.Scene()
+    >>> centers = np.random.rand(1000, 3) * 10
+    >>> colors = np.random.rand(1000, 3)
+    >>> marker_actor = actor.marker(centers=centers, colors=colors)
+    >>> scene.add(marker_actor)
+    >>> show_manager = window.ShowManager(scene=scene, size=(600, 600))
+    >>> show_manager.start()
+    """
+    geo = buffer_to_geometry(
path: fury/actor.py
user: login: ManishReddyR
body: I have added a check for positions, as a validation for buffer_to_geometry in fury/geometry.py
created_at: 2025-04-03T00:01:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1127,3 +1131,140 @@ def star(
         material=material,
         enable_picking=enable_picking,
     )
+
+
+def point(
+    centers,
+    *,
+    size=4,
+    colors=(1.0, 0.0, 0.0),
+    material="basic",
+    map=None,
+    aa=True,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many points with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
path: fury/actor.py
user: login: maharshi-gor
body: centers is not optional parameter in this case and we do not generate random points
```suggestion
    centers : ndarray, shape (N, 3)
```
created_at: 2025-04-04T17:44:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1127,3 +1131,140 @@ def star(
         material=material,
         enable_picking=enable_picking,
     )
+
+
+def point(
+    centers,
+    *,
+    size=4,
+    colors=(1.0, 0.0, 0.0),
+    material="basic",
+    map=None,
+    aa=True,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many points with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
+        The positions of the points. If None, random points will be generated.
path: fury/actor.py
user: login: maharshi-gor
body: 
```suggestion
```
created_at: 2025-04-04T17:45:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1127,3 +1131,140 @@ def star(
         material=material,
         enable_picking=enable_picking,
     )
+
+
+def point(
+    centers,
+    *,
+    size=4,
path: fury/actor.py
user: login: maharshi-gor
body: 
```suggestion
    size=4.0,
```
created_at: 2025-04-04T17:45:41Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1127,3 +1131,140 @@ def star(
         material=material,
         enable_picking=enable_picking,
     )
+
+
+def point(
+    centers,
+    *,
+    size=4,
+    colors=(1.0, 0.0, 0.0),
+    material="basic",
+    map=None,
+    aa=True,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many points with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
+        The positions of the points. If None, random points will be generated.
+    size : float
+        The size (diameter) of the points in logical pixels. Default 4.
path: fury/actor.py
user: login: maharshi-gor
body: Remove the default values as we might not be updating it when we change the default value on top.
created_at: 2025-04-04T17:47:05Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1127,3 +1131,140 @@ def star(
         material=material,
         enable_picking=enable_picking,
     )
+
+
+def point(
+    centers,
+    *,
+    size=4,
+    colors=(1.0, 0.0, 0.0),
+    material="basic",
+    map=None,
+    aa=True,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many points with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
+        The positions of the points. If None, random points will be generated.
+    size : float
+        The size (diameter) of the points in logical pixels. Default 4.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+        RGB or RGBA values in the range [0, 1].
+    material : str, optional
+        The material type for the points. Options are 'basic', 'gaussian'.
+    map : TextureMap | Texture
+        The texture map specifying the color for each texture coordinate.
+    aa : bool
+        Whether or not the points are anti-aliased in the shader. Default True.
+    opacity : float, optional
+        Takes values from 0 (fully transparent) to 1 (opaque).
+    enable_picking : bool, optional
+        Whether the points should be pickable in a 3D scene.
+
+    Returns
+    -------
+    point_actor : Actor
+        An point actor containing the generated points with the specified material
+        and properties.
+
+    Examples
+    --------
+    >>> from fury import window, actor
+    >>> import numpy as np
+    >>> scene = window.Scene()
+    >>> centers = np.random.rand(1000, 3) * 10
+    >>> colors = np.random.rand(1000, 3)
+    >>> point_actor = actor.point(centers=centers, colors=colors)
+    >>> scene.add(point_actor)
+    >>> show_manager = window.ShowManager(scene=scene, size=(600, 600))
+    >>> show_manager.start()
+    """
+    geo = buffer_to_geometry(
+        positions=centers.astype("float32"),
+        colors=colors.astype("float32"),
+    )
+
+    mat = _create_points_material(
+        size=size,
+        material=material,
+        map=map,
+        aa=aa,
+        opacity=opacity,
+        enable_picking=enable_picking,
+    )
+
+    obj = create_point(geo, mat)
+    return obj
+
+
+def marker(
+    centers,
+    *,
+    size=15,
+    colors=(1.0, 0.0, 0.0),
+    marker="circle",
+    edge_color="black",
+    edge_width=1,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many marker with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
path: fury/actor.py
user: login: maharshi-gor
body: Same changes here as well
created_at: 2025-04-04T17:48:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1127,3 +1131,140 @@ def star(
         material=material,
         enable_picking=enable_picking,
     )
+
+
+def point(
+    centers,
+    *,
+    size=4,
+    colors=(1.0, 0.0, 0.0),
+    material="basic",
+    map=None,
+    aa=True,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many points with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
+        The positions of the points. If None, random points will be generated.
+    size : float
+        The size (diameter) of the points in logical pixels. Default 4.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+        RGB or RGBA values in the range [0, 1].
+    material : str, optional
+        The material type for the points. Options are 'basic', 'gaussian'.
+    map : TextureMap | Texture
+        The texture map specifying the color for each texture coordinate.
+    aa : bool
+        Whether or not the points are anti-aliased in the shader. Default True.
+    opacity : float, optional
+        Takes values from 0 (fully transparent) to 1 (opaque).
+    enable_picking : bool, optional
+        Whether the points should be pickable in a 3D scene.
+
+    Returns
+    -------
+    point_actor : Actor
+        An point actor containing the generated points with the specified material
+        and properties.
+
+    Examples
+    --------
+    >>> from fury import window, actor
+    >>> import numpy as np
+    >>> scene = window.Scene()
+    >>> centers = np.random.rand(1000, 3) * 10
+    >>> colors = np.random.rand(1000, 3)
+    >>> point_actor = actor.point(centers=centers, colors=colors)
+    >>> scene.add(point_actor)
+    >>> show_manager = window.ShowManager(scene=scene, size=(600, 600))
+    >>> show_manager.start()
+    """
+    geo = buffer_to_geometry(
+        positions=centers.astype("float32"),
+        colors=colors.astype("float32"),
+    )
+
+    mat = _create_points_material(
+        size=size,
+        material=material,
+        map=map,
+        aa=aa,
+        opacity=opacity,
+        enable_picking=enable_picking,
+    )
+
+    obj = create_point(geo, mat)
+    return obj
+
+
+def marker(
+    centers,
+    *,
+    size=15,
+    colors=(1.0, 0.0, 0.0),
+    marker="circle",
+    edge_color="black",
+    edge_width=1,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many marker with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
+        The positions of the points. If None, random points will be generated.
+    size : float
+        The size (diameter) of the points in logical pixels. Default 4.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+        RGB or RGBA values in the range [0, 1].
+    marker : str | MarkerShape
+        The shape of the marker. Options are "●": "circle", "+": "plus",
path: fury/actor.py
user: login: maharshi-gor
body: Please add them in new lines
created_at: 2025-04-04T17:49:29Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1127,3 +1131,140 @@ def star(
         material=material,
         enable_picking=enable_picking,
     )
+
+
+def point(
+    centers,
+    *,
+    size=4,
+    colors=(1.0, 0.0, 0.0),
+    material="basic",
+    map=None,
+    aa=True,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many points with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
+        The positions of the points. If None, random points will be generated.
+    size : float
+        The size (diameter) of the points in logical pixels. Default 4.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+        RGB or RGBA values in the range [0, 1].
+    material : str, optional
+        The material type for the points. Options are 'basic', 'gaussian'.
+    map : TextureMap | Texture
+        The texture map specifying the color for each texture coordinate.
+    aa : bool
+        Whether or not the points are anti-aliased in the shader. Default True.
+    opacity : float, optional
+        Takes values from 0 (fully transparent) to 1 (opaque).
+    enable_picking : bool, optional
+        Whether the points should be pickable in a 3D scene.
+
+    Returns
+    -------
+    point_actor : Actor
+        An point actor containing the generated points with the specified material
+        and properties.
+
+    Examples
+    --------
+    >>> from fury import window, actor
+    >>> import numpy as np
+    >>> scene = window.Scene()
+    >>> centers = np.random.rand(1000, 3) * 10
+    >>> colors = np.random.rand(1000, 3)
+    >>> point_actor = actor.point(centers=centers, colors=colors)
+    >>> scene.add(point_actor)
+    >>> show_manager = window.ShowManager(scene=scene, size=(600, 600))
+    >>> show_manager.start()
+    """
+    geo = buffer_to_geometry(
+        positions=centers.astype("float32"),
+        colors=colors.astype("float32"),
+    )
+
+    mat = _create_points_material(
+        size=size,
+        material=material,
+        map=map,
+        aa=aa,
+        opacity=opacity,
+        enable_picking=enable_picking,
+    )
+
+    obj = create_point(geo, mat)
+    return obj
+
+
+def marker(
+    centers,
+    *,
+    size=15,
+    colors=(1.0, 0.0, 0.0),
+    marker="circle",
+    edge_color="black",
+    edge_width=1,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many marker with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
+        The positions of the points. If None, random points will be generated.
+    size : float
+        The size (diameter) of the points in logical pixels. Default 4.
path: fury/actor.py
user: login: maharshi-gor
body: The default value in the doc-string and method does not match. That is the reason we would like to eliminate this
created_at: 2025-04-04T17:50:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1127,3 +1131,140 @@ def star(
         material=material,
         enable_picking=enable_picking,
     )
+
+
+def point(
+    centers,
+    *,
+    size=4,
+    colors=(1.0, 0.0, 0.0),
+    material="basic",
+    map=None,
+    aa=True,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many points with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
+        The positions of the points. If None, random points will be generated.
+    size : float
+        The size (diameter) of the points in logical pixels. Default 4.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+        RGB or RGBA values in the range [0, 1].
+    material : str, optional
+        The material type for the points. Options are 'basic', 'gaussian'.
+    map : TextureMap | Texture
+        The texture map specifying the color for each texture coordinate.
+    aa : bool
+        Whether or not the points are anti-aliased in the shader. Default True.
+    opacity : float, optional
+        Takes values from 0 (fully transparent) to 1 (opaque).
+    enable_picking : bool, optional
+        Whether the points should be pickable in a 3D scene.
+
+    Returns
+    -------
+    point_actor : Actor
+        An point actor containing the generated points with the specified material
+        and properties.
+
+    Examples
+    --------
+    >>> from fury import window, actor
+    >>> import numpy as np
+    >>> scene = window.Scene()
+    >>> centers = np.random.rand(1000, 3) * 10
+    >>> colors = np.random.rand(1000, 3)
+    >>> point_actor = actor.point(centers=centers, colors=colors)
+    >>> scene.add(point_actor)
+    >>> show_manager = window.ShowManager(scene=scene, size=(600, 600))
+    >>> show_manager.start()
+    """
+    geo = buffer_to_geometry(
+        positions=centers.astype("float32"),
+        colors=colors.astype("float32"),
+    )
+
+    mat = _create_points_material(
+        size=size,
+        material=material,
+        map=map,
+        aa=aa,
+        opacity=opacity,
+        enable_picking=enable_picking,
+    )
+
+    obj = create_point(geo, mat)
+    return obj
+
+
+def marker(
+    centers,
+    *,
+    size=15,
+    colors=(1.0, 0.0, 0.0),
+    marker="circle",
+    edge_color="black",
+    edge_width=1,
path: fury/actor.py
user: login: maharshi-gor
body: 
```suggestion
    edge_width=1.0,
```
created_at: 2025-04-04T17:50:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1127,3 +1131,140 @@ def star(
         material=material,
         enable_picking=enable_picking,
     )
+
+
+def point(
+    centers,
+    *,
+    size=4,
+    colors=(1.0, 0.0, 0.0),
+    material="basic",
+    map=None,
+    aa=True,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many points with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
+        The positions of the points. If None, random points will be generated.
+    size : float
+        The size (diameter) of the points in logical pixels. Default 4.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+        RGB or RGBA values in the range [0, 1].
+    material : str, optional
+        The material type for the points. Options are 'basic', 'gaussian'.
+    map : TextureMap | Texture
+        The texture map specifying the color for each texture coordinate.
+    aa : bool
+        Whether or not the points are anti-aliased in the shader. Default True.
+    opacity : float, optional
+        Takes values from 0 (fully transparent) to 1 (opaque).
+    enable_picking : bool, optional
+        Whether the points should be pickable in a 3D scene.
+
+    Returns
+    -------
+    point_actor : Actor
+        An point actor containing the generated points with the specified material
+        and properties.
+
+    Examples
+    --------
+    >>> from fury import window, actor
+    >>> import numpy as np
+    >>> scene = window.Scene()
+    >>> centers = np.random.rand(1000, 3) * 10
+    >>> colors = np.random.rand(1000, 3)
+    >>> point_actor = actor.point(centers=centers, colors=colors)
+    >>> scene.add(point_actor)
+    >>> show_manager = window.ShowManager(scene=scene, size=(600, 600))
+    >>> show_manager.start()
+    """
+    geo = buffer_to_geometry(
+        positions=centers.astype("float32"),
+        colors=colors.astype("float32"),
+    )
+
+    mat = _create_points_material(
+        size=size,
+        material=material,
+        map=map,
+        aa=aa,
+        opacity=opacity,
+        enable_picking=enable_picking,
+    )
+
+    obj = create_point(geo, mat)
+    return obj
+
+
+def marker(
+    centers,
+    *,
+    size=15,
+    colors=(1.0, 0.0, 0.0),
+    marker="circle",
+    edge_color="black",
+    edge_width=1,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many marker with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3), optional
+        The positions of the points. If None, random points will be generated.
+    size : float
+        The size (diameter) of the points in logical pixels. Default 4.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+        RGB or RGBA values in the range [0, 1].
+    marker : str | MarkerShape
+        The shape of the marker. Options are "●": "circle", "+": "plus",
+        "x": "cross", "♥": "heart", "✳": "asterix", Default 'circle'.
+    edge_color : str | tuple | Color
+        The color of line marking the edge of the markers. Default 'black'.
+    edge_width : float
path: fury/actor.py
user: login: maharshi-gor
body: remove the default value.
created_at: 2025-04-04T17:51:00Z
author_association: CONTRIBUTOR
diff_hunk: @@ -147,3 +147,89 @@ def test_star():
     centers = np.array([[0, 0, 0]])
     colors = np.array([[1, 0, 0]])
     validate_actors(centers=centers, colors=colors, actor_type="star")
+
+
+def test_point():
+    centers = np.array([[0, 0, 0]])
+    colors = np.array([[1, 0, 0]])
+    scene = window.Scene()
+    get_actor = actor.point(centers=centers, colors=colors)
path: fury/tests/test_actor.py
user: login: maharshi-gor
body: Please provide better names to objects. 
```suggestion
    point_actor = actor.point(centers=centers, colors=colors)
```
created_at: 2025-04-04T17:52:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -147,3 +147,89 @@ def test_star():
     centers = np.array([[0, 0, 0]])
     colors = np.array([[1, 0, 0]])
     validate_actors(centers=centers, colors=colors, actor_type="star")
+
+
+def test_point():
+    centers = np.array([[0, 0, 0]])
+    colors = np.array([[1, 0, 0]])
+    scene = window.Scene()
+    get_actor = actor.point(centers=centers, colors=colors)
+    scene.add(get_actor)
+
+    npt.assert_array_equal(get_actor.local.position, centers[0])
+
+    mean_vertex = np.round(np.mean(get_actor.geometry.positions.view, axis=0))
+    npt.assert_array_almost_equal(mean_vertex, centers[0])
+
+    fname = "point_test.png"
+    window.snapshot(scene=scene, fname=fname)
+
+    img = Image.open(fname)
+    img_array = np.array(img)
+
+    mean_r, mean_g, mean_b, mean_a = np.mean(
+        img_array.reshape(-1, img_array.shape[2]), axis=0
+    )
+
+    assert mean_r > mean_b and mean_r > mean_g
+    scene.remove(get_actor)
+
+    get_actor_1 = actor.point(centers=centers, colors=colors, material="gaussian")
+    scene.add(get_actor_1)
+    fname_1 = "point_test_1.png"
+    window.snapshot(scene=scene, fname=fname_1)
+    img = Image.open(fname_1)
+    img_array = np.array(img)
+
+    mean_r, mean_g, mean_b, mean_a = np.mean(
+        img_array.reshape(-1, img_array.shape[2]), axis=0
+    )
+
+    assert mean_r > mean_b and mean_r > mean_g
+    assert 0 < mean_r < 255
+    assert mean_g == 0 and mean_b == 0
+
+    scene.remove(get_actor_1)
+
+
+def test_marker():
+    centers = np.array([[0, 0, 0]])
+    colors = np.array([[1, 0, 0]])
+    scene = window.Scene()
+    get_actor = actor.marker(centers=centers, colors=colors)
path: fury/tests/test_actor.py
user: login: maharshi-gor
body: Please do the same
created_at: 2025-04-04T17:52:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -147,3 +147,89 @@ def test_star():
     centers = np.array([[0, 0, 0]])
     colors = np.array([[1, 0, 0]])
     validate_actors(centers=centers, colors=colors, actor_type="star")
+
+
+def test_point():
+    centers = np.array([[0, 0, 0]])
+    colors = np.array([[1, 0, 0]])
+    scene = window.Scene()
+    get_actor = actor.point(centers=centers, colors=colors)
+    scene.add(get_actor)
+
+    npt.assert_array_equal(get_actor.local.position, centers[0])
+
+    mean_vertex = np.round(np.mean(get_actor.geometry.positions.view, axis=0))
+    npt.assert_array_almost_equal(mean_vertex, centers[0])
+
+    fname = "point_test.png"
+    window.snapshot(scene=scene, fname=fname)
+
+    img = Image.open(fname)
+    img_array = np.array(img)
+
+    mean_r, mean_g, mean_b, mean_a = np.mean(
+        img_array.reshape(-1, img_array.shape[2]), axis=0
+    )
+
+    assert mean_r > mean_b and mean_r > mean_g
+    scene.remove(get_actor)
+
+    get_actor_1 = actor.point(centers=centers, colors=colors, material="gaussian")
+    scene.add(get_actor_1)
+    fname_1 = "point_test_1.png"
+    window.snapshot(scene=scene, fname=fname_1)
+    img = Image.open(fname_1)
+    img_array = np.array(img)
+
+    mean_r, mean_g, mean_b, mean_a = np.mean(
+        img_array.reshape(-1, img_array.shape[2]), axis=0
+    )
+
+    assert mean_r > mean_b and mean_r > mean_g
+    assert 0 < mean_r < 255
+    assert mean_g == 0 and mean_b == 0
+
+    scene.remove(get_actor_1)
+
+
+def test_marker():
+    centers = np.array([[0, 0, 0]])
+    colors = np.array([[1, 0, 0]])
+    scene = window.Scene()
+    get_actor = actor.marker(centers=centers, colors=colors)
+    scene.add(get_actor)
+
+    npt.assert_array_equal(get_actor.local.position, centers[0])
+
+    mean_vertex = np.round(np.mean(get_actor.geometry.positions.view, axis=0))
+    npt.assert_array_almost_equal(mean_vertex, centers[0])
+
+    fname = "marker_test.png"
+    window.snapshot(scene=scene, fname=fname)
+
+    img = Image.open(fname)
+    img_array = np.array(img)
+
+    mean_r, mean_g, mean_b, mean_a = np.mean(
path: fury/tests/test_actor.py
user: login: maharshi-gor
body: if you are not going to use a variable mark it with `_` which indicates you are not using this specific variable.
```suggestion
    mean_r, mean_g, mean_b, _mean_a = np.mean(
```
created_at: 2025-04-04T17:54:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -147,3 +147,89 @@ def test_star():
     centers = np.array([[0, 0, 0]])
     colors = np.array([[1, 0, 0]])
     validate_actors(centers=centers, colors=colors, actor_type="star")
+
+
+def test_point():
+    centers = np.array([[0, 0, 0]])
+    colors = np.array([[1, 0, 0]])
+    scene = window.Scene()
+    get_actor = actor.point(centers=centers, colors=colors)
+    scene.add(get_actor)
+
+    npt.assert_array_equal(get_actor.local.position, centers[0])
+
+    mean_vertex = np.round(np.mean(get_actor.geometry.positions.view, axis=0))
+    npt.assert_array_almost_equal(mean_vertex, centers[0])
+
+    fname = "point_test.png"
+    window.snapshot(scene=scene, fname=fname)
+
+    img = Image.open(fname)
+    img_array = np.array(img)
+
+    mean_r, mean_g, mean_b, mean_a = np.mean(
+        img_array.reshape(-1, img_array.shape[2]), axis=0
+    )
+
+    assert mean_r > mean_b and mean_r > mean_g
+    scene.remove(get_actor)
+
+    get_actor_1 = actor.point(centers=centers, colors=colors, material="gaussian")
+    scene.add(get_actor_1)
+    fname_1 = "point_test_1.png"
+    window.snapshot(scene=scene, fname=fname_1)
+    img = Image.open(fname_1)
+    img_array = np.array(img)
+
+    mean_r, mean_g, mean_b, mean_a = np.mean(
+        img_array.reshape(-1, img_array.shape[2]), axis=0
+    )
+
+    assert mean_r > mean_b and mean_r > mean_g
+    assert 0 < mean_r < 255
+    assert mean_g == 0 and mean_b == 0
+
+    scene.remove(get_actor_1)
+
+
+def test_marker():
+    centers = np.array([[0, 0, 0]])
+    colors = np.array([[1, 0, 0]])
+    scene = window.Scene()
+    get_actor = actor.marker(centers=centers, colors=colors)
+    scene.add(get_actor)
+
+    npt.assert_array_equal(get_actor.local.position, centers[0])
+
+    mean_vertex = np.round(np.mean(get_actor.geometry.positions.view, axis=0))
+    npt.assert_array_almost_equal(mean_vertex, centers[0])
+
+    fname = "marker_test.png"
+    window.snapshot(scene=scene, fname=fname)
+
+    img = Image.open(fname)
+    img_array = np.array(img)
+
+    mean_r, mean_g, mean_b, mean_a = np.mean(
+        img_array.reshape(-1, img_array.shape[2]), axis=0
+    )
+
+    assert mean_r > mean_b and mean_r > mean_g
+    scene.remove(get_actor)
+
+    get_actor_1 = actor.marker(centers=centers, colors=colors, marker="heart")
+    scene.add(get_actor_1)
+    fname_1 = "marker_test_1.png"
+    window.snapshot(scene=scene, fname=fname_1)
+    img = Image.open(fname_1)
+    img_array = np.array(img)
+
+    mean_r, mean_g, mean_b, mean_a = np.mean(
path: fury/tests/test_actor.py
user: login: maharshi-gor
body: same here
created_at: 2025-04-04T17:54:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -99,3 +113,130 @@ def _create_mesh_material(
         )
     else:
         raise ValueError(f"Unsupported material type: {material}")
+
+
+def _create_points_material(
+    *,
+    material="basic",
+    color=(1.0, 1.0, 1.0),
+    size=4,
path: fury/material.py
user: login: maharshi-gor
body: 
```suggestion
    size=4.0,
```
created_at: 2025-04-04T18:01:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -99,3 +113,130 @@ def _create_mesh_material(
         )
     else:
         raise ValueError(f"Unsupported material type: {material}")
+
+
+def _create_points_material(
+    *,
+    material="basic",
+    color=(1.0, 1.0, 1.0),
+    size=4,
+    map=None,
+    aa=True,
+    mode="vertex",
+    opacity=1.0,
+    enable_picking=True,
+):
+    """
+     Create a points material.
+
+     Parameters
+     ----------
+     material : str, optional
+         The type of material to create. Options are 'baisc' (default),
path: fury/material.py
user: login: maharshi-gor
body: Let's not create two different materials for the points and have one more if with marker and use the same method for both actors internally. Also the spelling for basic is incorrect in the doc.



created_at: 2025-04-04T18:06:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1127,3 +1130,146 @@ def star(
         material=material,
         enable_picking=enable_picking,
     )
+
+
+def point(
+    centers,
+    *,
+    size=4.0,
+    colors=(1.0, 0.0, 0.0),
+    material="basic",
+    map=None,
+    aa=True,
+    opacity=1.0,
+    enable_picking=True,
+):
+    """Visualize one or many points with different features.
+
+    Parameters
+    ----------
+    centers : ndarray, shape (N, 3).
+        The positions of the points.
+    size : float
+        The size (diameter) of the points in logical pixels.
+    colors : ndarray (N,3) or (N,4) or tuple (3,) or tuple (4,), optional
+        RGB or RGBA values in the range [0, 1].
+    material : str, optional
+        The material type for the points.
+        Options are 'basic', 'gaussian'.
+    map : TextureMap | Texture
+        The texture map specifying the color for each texture coordinate.
+    aa : bool, optional
+        Whether or not the points are anti-aliased in the shader.
+    opacity : float, optional
+        Takes values from 0 (fully transparent) to 1 (opaque).
+    enable_picking : bool, optional
+        Whether the points should be pickable in a 3D scene.
+
+    Returns
+    -------
+    point_actor : Actor
+        An point actor containing the generated points with the specified material
+        and properties.
+
+    Examples
+    --------
+    >>> from fury import window, actor
+    >>> import numpy as np
+    >>> scene = window.Scene()
+    >>> centers = np.random.rand(1000, 3) * 10
+    >>> colors = np.random.rand(1000, 3)
+    >>> point_actor = actor.point(centers=centers, colors=colors)
+    >>> scene.add(point_actor)
+    >>> show_manager = window.ShowManager(scene=scene, size=(600, 600))
+    >>> show_manager.start()
+    """
+    geo = buffer_to_geometry(
+        positions=centers.astype("float32"),
+        colors=colors.astype("float32"),
+    )
+
+    mat = _create_points_material(
+        size=size,
+        material=material,
+        map=map,
+        aa=aa,
+        opacity=opacity,
+        enable_picking=enable_picking,
+    )
+
+    obj = create_point(geo, mat)
+    return obj
+
+
+def marker(
+    centers,
+    *,
+    size=15,
+    colors=(1.0, 0.0, 0.0),
+    material="marker",
path: fury/actor.py
user: login: maharshi-gor
body: Remove material option as it can be marker in marker actor's case
created_at: 2025-04-07T13:41:03Z
author_association: CONTRIBUTOR

PR comments:
user: login: ManishReddyR
created_at: 2025-03-16T01:33:58Z
body: Hello, 
Modified point actor and also added the maker actor. Here is the screenshot of the marker actor.


<img width="601" alt="Screenshot 2025-03-15 at 9 13 19 PM" src="https://github.com/user-attachments/assets/95d4cd0d-3b89-45ca-9dfe-9ad0c9b3ab85" />

Thanks
author_association: CONTRIBUTOR
user: login: ManishReddyR
created_at: 2025-03-27T20:32:30Z
body: > I have left a lot of comments on this
> 
> ![image](https://private-user-images.githubusercontent.com/39947025/426192505-0cdbd982-28ea-49fb-a9fe-cd8e25045fe1.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDI5NDkwMzksIm5iZiI6MTc0Mjk0ODczOSwicGF0aCI6Ii8zOTk0NzAyNS80MjYxOTI1MDUtMGNkYmQ5ODItMjhlYS00OWZiLWE5ZmUtY2Q4ZTI1MDQ1ZmUxLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMjYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzI2VDAwMjUzOVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTA0MTAyY2RhMzA2YWQ1YzhlNmY1ODExMjE2ZGIwMzhkY2U4ZGNjOTk5MmY3ZDRiZmZiOTA4NzIwMWI3Y2U2NWQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.6Nhq6zPdYDoD-auN_BDLtDHyq9yw2D0bIfgR2K00DsM)
> 
> Also @ManishReddyR why do we see the borders changing its colors while moving the scroll wheel



Its due to the over lapping of multiple actors at a time.

author_association: CONTRIBUTOR
user: login: ManishReddyR
created_at: 2025-04-05T20:25:58Z
body: Thanks for review @maharshi-gor 

I made the changes which you have suggested. 
author_association: CONTRIBUTOR
user: login: maharshi-gor
created_at: 2025-04-08T03:13:50Z
body: @ManishReddyR Thank you for the work. LGTM! Merging.
author_association: CONTRIBUTOR