Skip to content

Commit

Permalink
Enhance point cloud creation with size and color options
Browse files Browse the repository at this point in the history
- Added parameters for point size and color in create_from_point_cloud.
- Simplified mesh creation using from_pydata for points.
- Updated geometry nodes setup for better material handling.
  • Loading branch information
Matthias Humt committed Dec 10, 2024
1 parent b67bed9 commit 17b3de5
Showing 1 changed file with 25 additions and 30 deletions.
55 changes: 25 additions & 30 deletions blenderproc/python/types/MeshObjectUtility.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,11 @@ def create_with_empty_mesh(object_name: str, mesh_name: str = None) -> "MeshObje
mesh_name = object_name
return create_from_blender_mesh(bpy.data.meshes.new(mesh_name), object_name)

def create_from_point_cloud(points: np.ndarray, object_name: str, add_geometry_nodes_visualization: bool = False) -> "MeshObject":
def create_from_point_cloud(points: np.ndarray,
object_name: str,
add_geometry_nodes_visualization: bool = False,
point_size: float = 0.015,
point_color: Tuple[float, float, float] = (1, 0, 0)) -> "MeshObject":
""" Create a mesh from a point cloud.
The mesh's vertices are filled with the points from the given point cloud.
Expand All @@ -619,44 +623,35 @@ def create_from_point_cloud(points: np.ndarray, object_name: str, add_geometry_n
:param add_geometry_nodes_visualization: If yes, a geometry nodes modifier is added,
which adds a sphere to every point. In this way,
the point cloud will appear in renderings.
:param point_size: The size of the spheres that are added to the points.
:param point_color: The color of the spheres that are added to the points.
:return: The new Mesh object.
"""
point_cloud = create_with_empty_mesh(object_name)

# Go into mesh edit mode
point_cloud.edit_mode()
bm = point_cloud.mesh_as_bmesh()

# Add a vertex for each point
for p, point in enumerate(points):
if not np.isnan(point).any():
bm.verts.new(point)
"""

# Persist the changes
point_cloud.update_from_bmesh(bm)
point_cloud.object_mode()
# Create point cloud object and fill it with the given points
point_cloud = create_with_empty_mesh(object_name)
point_cloud.get_mesh().from_pydata(points, [], [])
point_cloud.get_mesh().validate()

# If desired, add geometry nodes that add a icosphere instance to every point
if add_geometry_nodes_visualization:
# Make nodes
geometry_nodes = point_cloud.add_geometry_nodes()
# Collect all nodes
input_node = Utility.get_the_one_node_with_type(geometry_nodes.nodes, "NodeGroupInput")
output_node = Utility.get_the_one_node_with_type(geometry_nodes.nodes, "NodeGroupOutput")
instances_node = geometry_nodes.nodes.new("GeometryNodeInstanceOnPoints")
sphere_node = geometry_nodes.nodes.new("GeometryNodeMeshIcoSphere")
material_node = geometry_nodes.nodes.new("GeometryNodeSetMaterial")
mesh_to_points_node = geometry_nodes.nodes.new(type='GeometryNodeMeshToPoints')
mesh_to_points_node.inputs['Radius'].default_value = point_size

# Material setup
material_node = geometry_nodes.nodes.new("GeometryNodeSetMaterial")
mat = point_cloud.new_material("point_cloud_mat")
mat.set_principled_shader_value("Base Color", [1, 0, 0, 1])

# Link them
sphere_node.inputs["Radius"].default_value = 0.015
mat.set_principled_shader_value("Base Color", [*point_color, 1])
material_node.inputs["Material"].default_value = mat.blender_obj
geometry_nodes.links.new(input_node.outputs["Geometry"], instances_node.inputs["Points"])
geometry_nodes.links.new(sphere_node.outputs["Mesh"], instances_node.inputs["Instance"])
geometry_nodes.links.new(instances_node.outputs["Instances"], material_node.inputs["Geometry"])
geometry_nodes.links.new(material_node.outputs["Geometry"], output_node.inputs["Geometry"])


# Link nodes
input_node = Utility.get_the_one_node_with_type(geometry_nodes.nodes, "NodeGroupInput")
output_node = Utility.get_the_one_node_with_type(geometry_nodes.nodes, "NodeGroupOutput")
geometry_nodes.links.new(input_node.outputs['Geometry'], mesh_to_points_node.inputs['Mesh'])
geometry_nodes.links.new(mesh_to_points_node.outputs['Points'], material_node.inputs['Geometry'])
geometry_nodes.links.new(material_node.outputs['Geometry'], output_node.inputs['Geometry'])

return point_cloud

Expand Down

0 comments on commit 17b3de5

Please sign in to comment.