using Speckle.Objects.Other;
using Speckle.Sdk;
using Speckle.Sdk.Common;
using Speckle.Sdk.Models;
namespace Speckle.Objects.Geometry;
///
/// A collection of points, with color and size support.
///
[SpeckleType("Objects.Geometry.Pointcloud")]
public class Pointcloud : Base, IHasBoundingBox, ITransformable
{
///
/// Gets or sets the list of points of this , stored as a flat list of coordinates [x1,y1,z1,x2,y2,...]
///
[DetachProperty, Chunkable(31250)]
public required List points { get; set; }
///
/// Gets or sets the list of colors of this 's points., stored as ARGB s.
///
[DetachProperty, Chunkable(62500)]
public List colors { get; set; } = new();
///
/// Gets or sets the list of sizes of this 's points.
///
[DetachProperty, Chunkable(62500)]
public List sizes { get; set; } = new();
///
/// The unit's this is in.
/// This should be one of
///
public required string units { get; set; }
///
public Box? bbox { get; set; }
///
public bool TransformTo(Transform transform, out Pointcloud transformed)
{
// transform points
var transformedPoints = new List();
foreach (var point in GetPoints())
{
point.TransformTo(transform, out Point transformedPoint);
transformedPoints.Add(transformedPoint);
}
transformed = new Pointcloud
{
units = units,
points = transformedPoints.SelectMany(o => o.ToList()).ToList(),
colors = colors,
sizes = sizes,
applicationId = applicationId,
};
return true;
}
///
public bool TransformTo(Transform transform, out ITransformable transformed)
{
var res = TransformTo(transform, out Pointcloud pc);
transformed = pc;
return res;
}
/// as list of s
/// when list is malformed
public List GetPoints()
{
if (points.Count % 3 != 0)
{
throw new SpeckleException(
$"{nameof(Pointcloud)}.{nameof(points)} list is malformed: expected length to be multiple of 3"
);
}
var pts = new List(points.Count / 3);
for (int i = 2; i < points.Count; i += 3)
{
pts.Add(new Point(points[i - 2], points[i - 1], points[i], units));
}
return pts;
}
}