# How can I create a point cloud from the surfaces of a model?

How can one go about generating a point cloud from the surfaces/faces of a model?

Initially the models are going to be fairly simple (just cubes, cylinders, and spheres), but eventually the models will be progressing on to more complicated shapes.

The type of point cloud that I need to generate needs to be similar to the point cloud that would result from a laser scanner. So I do not need any edge or vertex information, just a point for every face of the mesh.

• – user1853
Dec 7 '14 at 2:33
• I'm not quite sure what you mean by "no edge or vertex information". Should it look like the model was 3D printed and then scanned? I.e. an arbitrary scattering of points on the surface, regardless of topology? If so, I'd recommend using a particle system.
– gandalf3
Dec 7 '14 at 8:59
• This sound somewhat contradictory, point cloud but no edge or vertex info, just faces. Could you add an image to show what you mean. Vertices are points in space. If you simply want only vertices press 'X' to bring up the delete popup in edit mode and select 'Only Edges & Faces' Dec 7 '14 at 10:46

Following script creates a new point cloud from the selected object based the center of each face:

import bpy

def point_cloud(ob_name, coords):
"""Create point cloud object based on given coordinates and name."""
me = bpy.data.meshes.new(ob_name + "Mesh")
ob = bpy.data.objects.new(ob_name, me)
me.from_pydata(coords, [], [])
ob.show_name = True
me.update()
return ob

def face_centers(obj):
"""Returns median center coordinates for each face of given mesh object."""
if obj.type == 'MESH':
import bmesh
bm = bmesh.new()
bm.from_mesh(obj.data)
return [obj.matrix_world @ f.calc_center_median() for f in bm.faces]
else:
return [(0.0, 0.0, 0.0)]

ob = bpy.context.active_object
pc = point_cloud(ob.name + "-pointcloud", face_centers(ob))

# Link object to the active collection


Related: Add a simple vertex via python?

• For active collection have been using context.collection or context.scene.collection any particular reason to use context.view_layer.active_layer_collection.collection instead? Dec 18 '19 at 13:07
• As always, good catch @batFINGER. New to collections, I personally would expect that the new object is part of whatever collection I'm currently selected in the outliner. Your are right and C.collection reference seems to be the perfect, I didn't noticed the property in the console... Many thanks for your comment. Cheers
– p2or
Dec 18 '19 at 14:41
• Cheers for your prodding comments of late. Have found that C.collection can be None hence use C.collection or C.scene.collection since the latter always exists. Dec 18 '19 at 14:45

Just playing around, this seems like the simplest solution, although it may have trouble on more complex models.