using Rhino; using Rhino.ApplicationSettings; using Rhino.Commands; using Rhino.Display; using Rhino.DocObjects; using Rhino.Geometry; using Rhino.Input; using Rhino.Input.Custom; using System; using System.Collections.Generic; using System.Drawing; namespace SphereOnMesh { /// TestTaraskydon display conduit public class SphereOnMeshDisplayConduit : DisplayConduit { private readonly List m_spheres = new List(); private readonly Color m_color = AppearanceSettings.DefaultObjectColor; private double v_radius; /// Gets the spheres public Sphere[] Spheres { get { if (m_spheres.Count > 0) return m_spheres.ToArray(); return new Sphere[0]; } } /// Get the number of spheres public int SphereCount => m_spheres.Count; /// Gets or sets the sphere radius public double Radius { get => v_radius; set { if (value > RhinoMath.ZeroTolerance) { v_radius = value; for (var i = 0; i < m_spheres.Count; i++) m_spheres[i] = new Sphere(m_spheres[i].Center, v_radius); } } } /// Adds a new sphere public void AddSphere(Point3d point) { if (m_spheres.Count > 0) { foreach (var sphere in m_spheres) { if (sphere.Center.DistanceTo(point) < RhinoMath.ZeroTolerance) return; } } m_spheres.Add(new Sphere(point, v_radius)); } /// Removes the last sphere public void RemoveLastSphere() { if (m_spheres.Count > 0) m_spheres.RemoveAt(m_spheres.Count - 1); } /// DisplayConduit.CalculateBoundingBox overrid3 protected override void CalculateBoundingBox(CalculateBoundingBoxEventArgs e) { if (m_spheres.Count > 0) { var bbox = new BoundingBox(); foreach (var sphere in m_spheres) bbox.Union(sphere.BoundingBox); e.IncludeBoundingBox(bbox); } } /// DisplayConduit.CalculateBoundingBoxZoomExtents override protected override void CalculateBoundingBoxZoomExtents(CalculateBoundingBoxEventArgs e) { CalculateBoundingBox(e); } /// DisplayConduit.DrawOverlay override } /// TestTaraskydon get point public class SphereOnMeshGetPoint : GetPoint { //private readonly Color m_color = AppearanceSettings.DefaultObjectColor; private readonly Color m_color = System.Drawing.Color.Magenta; private readonly Color m_color2 = System.Drawing.Color.Black; private double m_radius=0.0; private bool e_key_pressed; private bool q_key_pressed; private const int VK_E = 69; private const int VK_Q = 81; /// HOT Key private void OnRhinoKeyboardEvent(int key) { if (key == 69) { e_key_pressed = false; m_radius += 0.025; return; } if (key == 81) { q_key_pressed = false; m_radius -= 0.025; return; } } /// Gets or sets the sphere radius public double Radius { get => m_radius; set { if (value > RhinoMath.ZeroTolerance) m_radius = value; RhinoApp.KeyboardEvent += OnRhinoKeyboardEvent;/// HOT Key } } /// GetPoint.OnDynamicDraw protected override void OnDynamicDraw(GetPointDrawEventArgs e) { Sphere nsphere = new Sphere(e.CurrentPoint, m_radius / 2.0); Mesh mSphere = Mesh.CreateFromSphere(nsphere, 40, 40); DisplayMaterial GIG = new DisplayMaterial(); GIG.Diffuse = System.Drawing.Color.FromArgb(115, 8, 255, 0); //GIG.IsTwoSided = true; //GIG.Diffuse = AppearanceSettings.DefaultObjectColor; GIG.Transparency = 0.5; //GIG.Shine = 0.5; //GIG.Specular = AppearanceSettings.DefaultObjectColor; //GIG.Emission = System.Drawing.Color.FromArgb(115, 8, 255, 0); //GIG.BackDiffuse = System.Drawing.Color.FromArgb(115, 8, 255, 0); //GIG.BackTransparency = 0.5; string texg = m_radius.ToString(); Point3d n_3d = new Point3d(m_radius / 2.0, m_radius / 2.0, m_radius / 2.0); var sPoint = new Point3d(e.CurrentPoint + n_3d); e.Display.DrawDot(sPoint, texg, m_color, m_color2); e.Display.DrawMeshShaded(mSphere, GIG); e.Display.DrawPoint(nsphere.Center, PointStyle.ControlPoint, 3, m_color); base.OnDynamicDraw(e); } } /// SphereOnMesh command public class SphereOnMesh : Command { private double n_radius = 0.5; private bool e_key_pressed; private bool q_key_pressed; private const int VK_E = 69; private const int VK_Q = 81; /// Gets the command name public override string EnglishName => "SphereOnMesh"; /// Command.RunCommand override /// /// HOT Key private void OnRhinoKeyboardEvent(int key) { if (key == 69) { e_key_pressed = false; n_radius += 0.025; return; } if (key == 81) { q_key_pressed = false; n_radius -= 0.025; return; } } protected override Result RunCommand(RhinoDoc doc, RunMode mode) { var rc = RhinoGet.GetOneObject("Select mesh", false, ObjectType.Mesh, out var obj_ref); if (rc != Result.Success) return rc; var mesh_obj = obj_ref.Object(); var mesh = obj_ref.Mesh(); if (null == mesh_obj || null == mesh) return Result.Failure; /// This might make it easier to pick points mesh_obj.Select(false); doc.Views.Redraw(); var conduit = new SphereOnMeshDisplayConduit { Enabled = true, Radius = n_radius }; RhinoApp.KeyboardEvent += OnRhinoKeyboardEvent;/// HOT Key var gp = new SphereOnMeshGetPoint(); var msphere = new GetObject(); while (true) { gp.Radius = n_radius; if (0 == conduit.SphereCount) { gp.SetCommandPrompt("Location of sphere."); gp.Constrain(mesh, false); gp.AcceptNothing(false); gp.AcceptUndo(false); } else { gp.SetCommandPrompt("Location of sphere. Press Enter when done"); gp.Constrain(mesh, true); gp.AcceptNothing(true); gp.AcceptUndo(true); } gp.ClearCommandOptions(); var radius_option = new OptionDouble(n_radius); gp.AddOptionDouble("Diam", ref radius_option); var res = gp.Get(); if (res == GetResult.Point) { conduit.AddSphere(gp.Point()); Point3d mpoint = gp.Point(); Sphere msphere2 = new Sphere(mpoint, n_radius/2.0); doc.Objects.AddSphere(msphere2); continue; } if (res == GetResult.Option) { var radius = radius_option.CurrentValue; if (radius <= 0) RhinoApp.WriteLine("Radius must be a value greater than zero."); else { n_radius = radius; conduit.Radius = n_radius; } continue; } if (res == GetResult.Undo) { msphere.Get(); ObjRef msphereRef = msphere.Object(0); RhinoObject msphere2 = msphereRef.Object(); doc.Objects.Delete(msphere2, true); conduit.RemoveLastSphere(); continue; } else if (res == GetResult.Nothing) { rc = Result.Success; break; } else { rc = Result.Cancel; break; } } conduit.Enabled = false; if (rc == Result.Success && conduit.SphereCount > 0) doc.Views.Redraw(); return rc; } } }