Draw Points on a Mesh Surface

How To Create Points on the Mesh Surface

This utility enables you to create and store Vector3 points each of which is randomly positioned uniformly on the surface of a mesh.

Design Outline.

  1. Take a random triangular facet belonging to the mesh;
  2. Calculate the area of the triangle;
  3. Calculate the number of random points to place on the facet using density * area;
  4. Choose random points inside this triangle;

Design Method.

For the mesh get the vertex positions and indices using

var positions = mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
var indices = mesh.getIndices();

For each facet, F, in turn obtain the three facet vertex positions, vertex0, vertex1 and vertex2 using the positions array. From these construct vectors, vec0, vec1 and vec2, along each side of the triangle. Using the lengths of the sides calculate the area of the triangle. For a value 0 ≤ λ ≤ 1,  λvec0 and λvec1 will form two sides of a triangle similar to the facet. So when also given a value 0 ≤ μ ≤ 1,  λvec0 and λμvec1 will give a point inside the facet. The range of values for λ and μ will determine all points within the facet. Hence random values for λ and μ will give random points on the facet plane.

Find point

lamda = BABYLON.Scalar.RandomRange(0, 1);
mu = BABYLON.Scalar.RandomRange(0, 1);
facetPoint = vertex0.add(vec0.scale(lambda)).add(vec1.scale(lambda * mu));

Repeat for density * area random points for each facet.

The Whole function

Set the density for the points and generate the points and store and return them in an array.

BABYLON.Mesh.prototype.createSurfacePoints = function(pointDensity) {
var positions = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
var indices = this.getIndices();
var point = BABYLON.Vector3.Zero();
var points = [];
var randX = 0;
var randY = 0;
var randZ = 0
var index = 0;
var id0 = 0;
var id1 = 0;
var id2 = 0;
var v0X = 0;
var v0Y = 0;
var v0Z = 0;
var v1X = 0;
var v1Y = 0
var v1Z = 0;
var v2X = 0;
var v2Y = 0;
var v2Z = 0;
var vertex0 = BABYLON.Vector3.Zero();
var vertex1 = BABYLON.Vector3.Zero();
var vertex2 = BABYLON.Vector3.Zero();
var vec0 = BABYLON.Vector3.Zero();
var vec1 = BABYLON.Vector3.Zero();
var vec2 = BABYLON.Vector3.Zero();
var a = 0; //length of side of triangle
var b = 0; //length of side of triangle
var c = 0; //length of side of triangle
var p = 0; //perimeter of triangle
var area = 0;
var nbPoints = 0; //nbPoints per triangle
var lamda = 0;
var mu = 0;
for(let index = 0; index <indices.length / 3; index++) {
id0 = indices[3 * index];
id1 = indices[3 * index + 1];
id2 = indices[3 * index + 2];
v0X = positions[3 * id0];
v0Y = positions[3 * id0 + 1];
v0Z = positions[3 * id0 + 2];
v1X = positions[3 * id1];
v1Y = positions[3 * id1 + 1];
v1Z = positions[3 * id1 + 2];
v2X = positions[3 * id2];
v2Y = positions[3 * id2 + 1];
v2Z = positions[3 * id2 + 2];
vertex0.set(v0X, v0Y, v0Z);
vertex1.set(v1X, v1Y, v1Z);
vertex2.set(v2X, v2Y, v2Z);
vertex1.subtractToRef(vertex0, vec0);
vertex2.subtractToRef(vertex1, vec1);
vertex2.subtractToRef(vertex0, vec2);
a = vec0.length();
b = vec1.length();
c = vec2.length();
p = (a + b + c) / 2;
area = Math.sqrt(p * (p - a) * (p - b) * (p - c));
nbPoints = Math.round(pointDensity * area);
for (let i = 0; i < nbPoints; i++) {
//form a point inside the facet v0, v1, v2;
lamda = BABYLON.Scalar.RandomRange(0, 1);
mu = BABYLON.Scalar.RandomRange(0, 1);
facetPoint = vertex0.add(vec0.scale(lamda)).add(vec1.scale(lamda * mu));
points.push(facetPoint);
}
}
return points;
}
Drawing Points on a Mesh Surface

Further reading

Create Points Inside A Mesh
Helpful code snippet for creating points inside of a mesh in Babylon.js.
Create Points Inside A Mesh
Check When a Point is Inside a Mesh
Helpful code snippet for checking when a point is inside of a mesh in Babylon.js.
Check When a Point is Inside a Mesh