FindClosestVertex(): retrieve a vertex inside a Brep or Solid entity

The following derived class gets the vertex closest to the mouse and adds a Point entity on its position when clicking with the right mouse button.

It manages nested BlockReferences, standard Entities, and the more complex Solid and Brep entities.

internal class MyModel: devDept.Eyeshot.Model
{
    protected override void OnMouseUp(MouseEventArgs e)
    {
        if (ActionMode == actionType.None && e.Button == MouseButtons.Right)
        {

            HitVertex hv;
            int entID = FindClosestVertex(e.Location, 10, out hv);

            Debug.WriteLine(entID);

            if (entID < 0)
                return;

            if (hv.Parents != null)
            {
                for (int i = 0; i < hv.Parents.Count; i++)
                {
                    // Set as current all the parents, so I can use the BlockReference.AccumulatedParentsTransform to transform the vertex
                    Entities.SetCurrent(hv.Parents[i]);
                }
            }

            Entity ent;
            if (Entities.CurrentBlockReference == null)
            {
                ent = Entities[entID];
            }
            else
            {
                // Get the Block entities
                ent = Blocks[Entities.CurrentBlockReference.BlockName].Entities[hv.EntityIndex];
            }

            Point3D pt;
            if (ent is Solid)
            {
                var sol = (Solid) ent;

                // Retrieve the vertex from the proper Solid portion
                pt = sol.Portions[hv.FaceIndex].Vertices[hv.VertexIndex];
            }
            else if (ent is Brep)
            {
                var sol = (Brep) ent;

                // retrieve the vertex from the proper Solid3D face and tesselation index
                if (hv.ShellOrElementIndex == 0)
                {
                    
                    pt = sol.Faces[hv.FaceIndex].Tessellation[hv.ParamSurfaceIndex].Vertices[hv.VertexIndex];
                }
                else
                    pt =
                        sol.Inners[hv.ShellOrElementIndex - 1][hv.FaceIndex].Tessellation[hv.ParamSurfaceIndex]
                            .Vertices[
                                hv.VertexIndex];

            }
            else
            {
                pt = ent.Vertices[hv.VertexIndex];
            }


            if (Entities.CurrentBlockReference != null)
            {
                // Transform the point by the accumulated BlockReference transformation to get the final world position
                pt = Entities.CurrentBlockReference.AccumulatedParentsTransform * pt;
            }

            if (hv.Parents != null)
                for (int i = 0; i < hv.Parents.Count; i++)
                {
                    // Go back to the original parent
                    Entities.SetParentAsCurrent();
                }

            if (pt != null)
                Entities.Add(new devDept.Eyeshot.Entities.Point(pt, 10), Color.Red);
        }

        base.OnMouseUp(e);
    }

}

Previous versions of this article: Eyeshot 9

Was this article helpful?
0 out of 0 found this helpful
Have more questions? Submit a request

Comments

3 comments
  • >pt = sol.Faces[hv.FaceIndex].Tessellation[hv.TessellationIndex].Vertices[hv.VertexIndex];

    There is no TessellationIndex in the properties of the HitVertex class. (version 12.0.351.0)

    Is the version difference?
  • I replaced it with a ParamSurfaceIndex, and it seems to be working properly.

  • Article updated. Thanks for reporting it. 

Please sign in to leave a comment.