From f8e2e08886e6ab58cd80765cb0230db0f46dd3bd Mon Sep 17 00:00:00 2001 From: Tim Wundenberg Date: Sun, 11 Jul 2021 10:14:43 +0200 Subject: [PATCH] Add ScanData Controller --- .../Controllers/ScanDataController.cs | 24 ++++++ PointCloudWeb.Server/Models/PointCloud.cs | 73 +++++++++++++++++++ PointCloudWeb.Server/Models/ScanData.cs | 21 ++++++ .../{ => Models}/WeatherForecast.cs | 0 .../Services/IPointCloudRegistration.cs | 14 ++++ .../Services/PointCloudService.cs | 27 +++++++ .../Services/ScanConverterService.cs | 66 +++++++++++++++++ .../Services/ScanDataService.cs | 35 +++++++++ 8 files changed, 260 insertions(+) create mode 100644 PointCloudWeb.Server/Controllers/ScanDataController.cs create mode 100644 PointCloudWeb.Server/Models/PointCloud.cs create mode 100644 PointCloudWeb.Server/Models/ScanData.cs rename PointCloudWeb.Server/{ => Models}/WeatherForecast.cs (100%) create mode 100644 PointCloudWeb.Server/Services/IPointCloudRegistration.cs create mode 100644 PointCloudWeb.Server/Services/PointCloudService.cs create mode 100644 PointCloudWeb.Server/Services/ScanConverterService.cs create mode 100644 PointCloudWeb.Server/Services/ScanDataService.cs diff --git a/PointCloudWeb.Server/Controllers/ScanDataController.cs b/PointCloudWeb.Server/Controllers/ScanDataController.cs new file mode 100644 index 0000000..20b2154 --- /dev/null +++ b/PointCloudWeb.Server/Controllers/ScanDataController.cs @@ -0,0 +1,24 @@ +using Microsoft.AspNetCore.Mvc; +using PointCloudWeb.Server.Models; +using PointCloudWeb.Server.Services; + +namespace PointCloudWeb.Server.Controllers +{ + [ApiController] + [Route("[controller]")] + public class DataController : ControllerBase + { + private readonly DataService _scanDataService; + + public DataController(DataService scanDataService) + { + _scanDataService = scanDataService; + } + + [HttpPost] + public void PostScanData([FromBody] ScanDataList data) + { + _scanDataService.AddScan(data); + } + } +} diff --git a/PointCloudWeb.Server/Models/PointCloud.cs b/PointCloudWeb.Server/Models/PointCloud.cs new file mode 100644 index 0000000..0c80d77 --- /dev/null +++ b/PointCloudWeb.Server/Models/PointCloud.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PointCloudWeb.Server.Models +{ + public class Point + { + public double X { get; set; } + public double Y { get; set; } + public double Z { get; set; } + + + public Point() : this(0, 0, 0) { } + public Point(double x, double y, double z) + { + X = x; + Y = y; + Z = z; + } + + + public override string ToString() => (X.ToString() + " " + Y.ToString() + " " + Z.ToString()); + } + + + public class PointCloud + { + public Guid Id { get; private set; } + public string Name { get; set; } + public IList Points { get; private set; } + + /// + /// Function ScaleFactor defines relation between X/Y/Z distances in mm + /// So, Point A(0,0,0) is 1mm from B(1,0,0) apart + /// + public static int ScaleFactor() => 1; + + public PointCloud(String name, Guid id) + { + Points = new List(); + Id = id; + Name = name; + } + } + + public class PointCloudCollection : List + { + public PointCloud GetById(Guid id) + { + return this.First(pc => pc.Id == id); + } + + public PointCloud AddNew() + { + var id = Guid.NewGuid(); + var pc = new PointCloud(id.ToString(), id); + Add(pc); + return pc; + } + + public bool Contains(Guid id) + { + return this.Any(pc => pc.Id == id); + } + + public void RemoveById(Guid id) + { + Remove(GetById(id)); + } + } + +} \ No newline at end of file diff --git a/PointCloudWeb.Server/Models/ScanData.cs b/PointCloudWeb.Server/Models/ScanData.cs new file mode 100644 index 0000000..28b2644 --- /dev/null +++ b/PointCloudWeb.Server/Models/ScanData.cs @@ -0,0 +1,21 @@ + +using System; +using System.Collections.Generic; + +namespace PointCloudWeb.Server.Models +{ + public class ScanDataPoint + { + //RotationAngle on {Y,Z,X} Axis + public double RAY { get; set; } + public double RAZ { get; set; } + public double RAX { get; set; } + public double DistanceMM { get; set; } + } + + public class ScanDataList + { + public Guid Id { get; set; } + public IList List { get; set; } + } +} \ No newline at end of file diff --git a/PointCloudWeb.Server/WeatherForecast.cs b/PointCloudWeb.Server/Models/WeatherForecast.cs similarity index 100% rename from PointCloudWeb.Server/WeatherForecast.cs rename to PointCloudWeb.Server/Models/WeatherForecast.cs diff --git a/PointCloudWeb.Server/Services/IPointCloudRegistration.cs b/PointCloudWeb.Server/Services/IPointCloudRegistration.cs new file mode 100644 index 0000000..d0929be --- /dev/null +++ b/PointCloudWeb.Server/Services/IPointCloudRegistration.cs @@ -0,0 +1,14 @@ +using PointCloudWeb.Server.Models; + +namespace PointCloudWeb.Server.Services +{ + public interface IPointCloudRegistation + { + class TransformationMatrix { } + + public TransformationMatrix RegisterPointCloud(PointCloud pc1, PointCloud pc2) + { + return null; + } + } +} \ No newline at end of file diff --git a/PointCloudWeb.Server/Services/PointCloudService.cs b/PointCloudWeb.Server/Services/PointCloudService.cs new file mode 100644 index 0000000..76f86fd --- /dev/null +++ b/PointCloudWeb.Server/Services/PointCloudService.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using PointCloudWeb.Server.Models; + +namespace PointCloudWeb.Server.Services +{ + public class PointCloudService + { + private readonly PointCloudCollection _pointClouds; + + public PointCloudService() + { + _pointClouds = new PointCloudCollection(); + } + + public void AddPoints(Guid id, IList points) + { + if (!_pointClouds.Contains(id)) + throw new ArgumentOutOfRangeException("The Id {0} was not found!", id.ToString()); + + var pc = _pointClouds.GetById(id); + + foreach (var point in points) + pc.Points.Add(point); + } + } +} \ No newline at end of file diff --git a/PointCloudWeb.Server/Services/ScanConverterService.cs b/PointCloudWeb.Server/Services/ScanConverterService.cs new file mode 100644 index 0000000..5b7ba9e --- /dev/null +++ b/PointCloudWeb.Server/Services/ScanConverterService.cs @@ -0,0 +1,66 @@ +using System; +using System.Numerics; +using PointCloudWeb.Server.Models; + +namespace PointCloudWeb.Server.Services +{ + public class ScanConverterService + { + private enum RotationAxis { X, Y, Z }; + + private Matrix4x4 GetTransformationMatrix(ScanDataPoint scan, RotationAxis type) + { + var angle = type switch + { + RotationAxis.X => scan.RAX, + RotationAxis.Y => scan.RAY, + RotationAxis.Z => scan.RAZ, + _ => throw new NotImplementedException(), + }; + + if (angle == 0) + return new Matrix4x4( + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + ); + + var sin = (float)Math.Sin(angle); + var cos = (float)Math.Cos(angle); + + return type switch + { + RotationAxis.X => new Matrix4x4( + 1, 0, 0, 0, + 0, sin, -sin, 0, + 0, sin, cos, 0, + 0, 0, 0, 1 + ), + RotationAxis.Y => new Matrix4x4( + cos, 0, sin, 0, + 0, 1, 0, 0, + -sin, 0, cos, 0, + 0, 0, 0, 1 + ), + RotationAxis.Z => new Matrix4x4( + cos, -sin, 0, 0, + sin, cos, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + ), + _ => throw new NotImplementedException(), + }; + } + + public Point Transform(ScanDataPoint scan) + { + Vector3 v = new Vector3(0, 0, (int)scan.DistanceMM); + Vector3.Transform(v, GetTransformationMatrix(scan, RotationAxis.X)); + Vector3.Transform(v, GetTransformationMatrix(scan, RotationAxis.Z)); + Vector3.Transform(v, GetTransformationMatrix(scan, RotationAxis.Y)); + + return new Point(v.X, v.Y, v.Z); + } + } +} \ No newline at end of file diff --git a/PointCloudWeb.Server/Services/ScanDataService.cs b/PointCloudWeb.Server/Services/ScanDataService.cs new file mode 100644 index 0000000..92b887c --- /dev/null +++ b/PointCloudWeb.Server/Services/ScanDataService.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using PointCloudWeb.Server.Models; + +namespace PointCloudWeb.Server.Services +{ + public class DataService + { + private readonly PointCloudService _pointCloudService; + private readonly ScanConverterService _scanConverterService; + + public DataService(PointCloudService pointCloudService, ScanConverterService scanConverterService) + { + _pointCloudService = pointCloudService; + _scanConverterService = scanConverterService; + } + + public void AddScan(ScanDataList scanData) + { + _pointCloudService.AddPoints(scanData.Id, ConvertToPoints(scanData)); + } + + private IList ConvertToPoints(ScanDataList scanData) + { + var list = new List(); + + foreach (var scan in scanData.List) + { + list.Add(_scanConverterService.Transform(scan)); + } + + return list; + } + } +} \ No newline at end of file