How can I extract a 2D slice from a 3D mesh using CGE? The mesh is the outline of an object, think carrot-shaped, and I have it as an IndexedFaceSet. I would like to extract a 2D slice at any given y ... resulting in an IndexedLineSet that represents the boundary of that mesh at that elevation. Where do I start looking?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It's easiest to use ready triangulation method TShape.Triangulate, see the examples/3d_rendering_processing/triangulate_demo.lpr example.
Although, if needed, you could also triangulate more manually:
The vertex positions of the IndexedFaceSet are inside it's coordinate array. You can get their lists like this:
procedureCalculateSlice(FaceSet:TIndexedFaceSetNode);varCoord:TCoordinateNode;CoordIndex:TLongIntList;VertexList:TVector3List;beginifFaceSet.FdCoord.ValueisTCoordinateNodethenbeginCoord:=TCoordinateNode(FaceSet.FdCoord.Value);VertexList:=Coord.FdPoint.Items;endelsebegin// warning or error that IndexedFaceSet coordinate is not assigned,// or has unexpected classend;CoordIndex:=FaceSet.FdCoordIndex.Items;...end;
Once you have CoordIndex and VertexList, you iterate over CoordIndex. The -1 separates polygons, other values refer to the vertex on VertexList. This way you can extract polygons.
If the mesh is convex (FaceSet.Convex) then splitting the polygon into triangles is easy (make a triangle fan).
2. For each triangle, calculate whether it's split by your plane. Since your plane is Y = "constant planeY", then a triangle is split by a plane if some vertexes have Y coordinate <= planeY, and some other vertexes have Y coordinate >= planeY.
(If all 3 triangle vertexes are above planeY, or all 3 vertexes are below planeY, then a triangle is not cut by your plane.)
If the triangle is indeed split by plane, calculate the actual line segment.
Note: I'm assumig that a triangle, 3 edges, when intersected by Y = const plane, will collide at exactly 2 triangle edges, and thus wil result in exactly 1 line segment to the outline. Your implementation should probably check and reject, or otherwise deal with, possible weird cases (e.g. a triangle that lies completely at this Y = const plane).
Thanks Michalis, that's more than a sketch, it's a painting! I'll give that a go. Many thanks, would never have found the TrySimplePlaneSegmentIntersection() function.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi all,
How can I extract a 2D slice from a 3D mesh using CGE? The mesh is the outline of an object, think carrot-shaped, and I have it as an IndexedFaceSet. I would like to extract a 2D slice at any given y ... resulting in an IndexedLineSet that represents the boundary of that mesh at that elevation. Where do I start looking?
Here's a sketch how I would approach this :)
1. First, get the triangles of your mesh.
It's easiest to use ready triangulation method
TShape.Triangulate, see theexamples/3d_rendering_processing/triangulate_demo.lprexample.Although, if needed, you could also triangulate more manually:
The vertex positions of the IndexedFaceSet are inside it's coordinate array. You can get their lists like this:
Once you have CoordIndex and VertexList, you iterate over CoordIndex. The -1 separates polygons, other values refer to the vertex on VertexList. This way you can extract polygons.
If the mesh is convex (FaceSet.Convex) then splitting the polygon into triangles is easy (make a triangle fan).
2. For each triangle, calculate whether it's split by your plane. Since your plane is Y = "constant planeY", then a triangle is split by a plane if some vertexes have Y coordinate <= planeY, and some other vertexes have Y coordinate >= planeY.
(If all 3 triangle vertexes are above planeY, or all 3 vertexes are below planeY, then a triangle is not cut by your plane.)
If the triangle is indeed split by plane, calculate the actual line segment.
Note: I'm assumig that a triangle, 3 edges, when intersected by Y = const plane, will collide at exactly 2 triangle edges, and thus wil result in exactly 1 line segment to the outline. Your implementation should probably check and reject, or otherwise deal with, possible weird cases (e.g. a triangle that lies completely at this Y = const plane).
This function from CastleVectors may be helpful:
In your case, PlaneConstCoord = 1 (Y). And Pos1, Pos2 are two corners of the triangle.
3. Add all resulting line segments to a new TLineSetNode.
Some demo about how one can construct TLineSetNode is e.g. here: https://castle-engine.io/x3d_implementation_geometry2d.php
Thanks Michalis, that's more than a sketch, it's a painting! I'll give that a go. Many thanks, would never have found the TrySimplePlaneSegmentIntersection() function.