I need to create a mesh from a set of three-dimensional points.
An example of such a point-array is given below (string with x y z coordinates separated by a space).
The points are given in a specific order that form a linear ring and the first point in the array is the same as the last one so that the boundary is closed. The point coordinates come from a cityGML file and define various surfaces of buildings (roof, wall…).
To give you a feel on what the mesh should look like, I created a LineLoop like seen in the code below (using react-three-fiber, but that should be irrelevant).
But I can´t get my head around how to create a mesh within that boundary!
I would probably sooner or later find out how to draw a 2D-Shape from this and rotate it back up, BUT the mesh geometry is expected to be not perfectly planar!
Viewing the mesh in various modeling softwares it shows that triangulation will be necessary, but I am too stupid to apply the common libraries for triangulations to this three-dimensional geometry.
Please help me or I will lose my mind.
CODE TO CREATE THE LINE LOOP:
const vertices = new Float32Array(points.flat());
const geometry = new BufferGeometry();
geometry.setAttribute("position", new BufferAttribute(vertices, 3));
const material = new MeshBasicMaterial({ color: "red" });
return (
<lineLoop geometry={geometry} material={material} />
);
Thank you for the recommendation!
I tried it and below is a picture of the result.
For some geometries, for example the one I posted before (one roof surface) it worked perfectly, but for some reason the smaller areas (side walls) don´t seem to work. Why could this be?
Every surface I have in the sample points array is correctly rendered with the line loop but not with earcut.
const EarcutGeometry = ({ points }) => {
const mesh = useMemo(() => {
const flattenedPoints = points.flat();
const triangles = Earcut.triangulate(flattenedPoints, null, 3);
const vertices = [];
for (let i = 0; i < points.length; i++) {
vertices.push(new Vector3(...points[i]));
}
const geometry = new BufferGeometry().setFromPoints(vertices);
const indices = [];
for (let i = 0; i < triangles.length; i += 3) {
indices.push(triangles[i], triangles[i + 1], triangles[i + 2]);
}
geometry.setIndex(indices);
geometry.computeVertexNormals(); // To smooth out the lighting
const material = new MeshBasicMaterial({
color: 0x00ff00,
side: DoubleSide,
});
return <mesh geometry={geometry} material={material} />;
}, [points]);
return mesh;
};
Also it might be worth mentioning that when I leave the point coordinates untreated (with the really high numbers) the rendering gets messy. When I move everything closer to 0 the rendering gets fine.