Menu

Extract plane from mesh

2018-03-23
2018-03-23
  • Pete Sergeant

    Pete Sergeant - 2018-03-23

    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?

     
  • Michalis Kamburelis

    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 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:

    procedure CalculateSlice(FaceSet: TIndexedFaceSetNode);
    var
      Coord: TCoordinateNode;
      CoordIndex: TLongIntList;
      VertexList: TVector3List;
    begin
      if FaceSet.FdCoord.Value is TCoordinateNode then
      begin
        Coord := TCoordinateNode(FaceSet.FdCoord.Value);
        VertexList := Coord.FdPoint.Items;
      end else
      begin
        // warning or error that IndexedFaceSet coordinate is not assigned,
        // or has unexpected class
      end;
    
      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).

    This function from CastleVectors may be helpful:

    function TrySimplePlaneSegmentIntersection(
      out Intersection: TVector3;
      const PlaneConstCoord: integer; const PlaneConstValue: Single;
      const Pos1, Pos2: TVector3): boolean; overload;
    

    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

     
  • Pete Sergeant

    Pete Sergeant - 2018-03-23

    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.

     

Anonymous
Anonymous

Add attachments
Cancel





Monday.com Logo