Hello! These are snippets of my model, view model and view, I am trying to keep track of all points that are currently in the rhino doc, my view model is in charge of adding objects to the model´s queues based on rhino add and delete object events, what I am not sure about is if this is a right approach, how to process the queues, do I use an async task? do I run another thread? do I trigger the queue processing by another event? I am very much new to csharp so I want to be careful about choosing next steps and Id like to get some advice from more experienced developers. The list of points is what I would like the viewmodel to watch and expose to my view but I am struggling to glue everything together. any advice is greatly appreciated, thank you
public class MyPoint
{
public string Id { get; set; }
public string X { get; set; }
public string Y { get; set; }
public string Z { get; set; }
}
// Model
internal class ObjPoints
{
List<MyPoint> points;
public List<MyPoint> Points
{
get { return points; }
set { points = value; }
}
Queue<RhinoObject> addedObjs;
public Queue<RhinoObject> AddedObjs
{
get { return addedObjs; }
set { addedObjs = value; }
}
Queue<RhinoObject> deletedObjs;
public Queue<RhinoObject> DeletedObjs
{
get { return deletedObjs; }
set { deletedObjs = value; }
}
public ObjPoints()
{
points = new List<MyPoint>();
addedObjs = new Queue<RhinoObject>();
deletedObjs = new Queue<RhinoObject>();
}
public HashSet<Point3d> ObjectToPoints(RhinoObject obj)
{
var geometry = obj.Geometry;
List<Point3d> controlPoints = new List<Point3d>();
HashSet<Point3d> resultSet = new HashSet<Point3d>();
if (geometry is Brep brep)
{
foreach (var vertex in brep.Vertices)
{
controlPoints.Add(vertex.Location);
}
}
else if (geometry is Surface surface)
{
var nurbsSurface = surface.ToNurbsSurface();
for (int i = 0; i < nurbsSurface.Points.CountU; i++)
{
for (int j = 0; j < nurbsSurface.Points.CountV; j++)
{
controlPoints.Add(nurbsSurface.Points.GetControlPoint(i, j).Location);
}
}
}
else if (geometry is Curve curve)
{
var nurbsCurve = curve.ToNurbsCurve();
for (int i = 0; i < nurbsCurve.Points.Count; i++)
{
controlPoints.Add(nurbsCurve.Points[i].Location);
}
}
else if (geometry is Point point)
{
controlPoints.Add(point.Location);
}
if (controlPoints.Count > 0)
{
resultSet = new HashSet<Point3d>(controlPoints);
}
else
{
RhinoApp.WriteLine($"Failed to get control points of object {obj}");
}
return resultSet;
}
}
// View model
public class MainViewModel : BaseViewModel
{
ObjPoints objPoints;
ObservableCollection<MyPoint> _points;
public IEnumerable<MyPoint> Points => _points;
public MainViewModel()
{
RhinoApp.Idle += OnIdle;
RhinoDoc.DeleteRhinoObject += OnDeleteRhinoObject;
RhinoDoc.AddRhinoObject += OnAddRhinoObject;
_points = new ObservableCollection<MyPoint>();
}
private void OnAddRhinoObject(object sender, RhinoObjectEventArgs e)
{
RhinoApp.WriteLine("Adding object");
var obj = e.TheObject;
objPoints.AddedObjs.Enqueue(obj);
}
private void OnDeleteRhinoObject(object sender, RhinoObjectEventArgs e)
{
RhinoApp.WriteLine("Deleting objects");
var obj = e.TheObject;
objPoints.DeletedObjs.Enqueue(obj);
}
private void OnIdle(object sender, EventArgs e)
{
//RhinoApp.WriteLine("Rhino Idling");
}
}
// grid whose data should be bound to my view model
var grid = new GridView { ShowHeader = true, DataStore = v_model.Points};
CommonViewFuncs.AddGridColumn<MyPoint>(grid, "Point_ID", (p => p.Id));
CommonViewFuncs.AddGridColumn<MyPoint>(grid, "Coord_X", (p => p.X));
CommonViewFuncs.AddGridColumn<MyPoint>(grid, "Coord_Y", (p => p.Y));
CommonViewFuncs.AddGridColumn<MyPoint>(grid, "Coord_Z", (p => p.Z));
internal static void AddGridColumn<TItem>(GridView grid, string headerText, Expression<Func<TItem, string>> propertySelector)
{
var col = new GridColumn
{
HeaderText = headerText,
DataCell = new TextBoxCell { Binding = Binding.Property(propertySelector) },
AutoSize = true,
Editable = false
};
grid.Columns.Add(col);
}