PlotlyFactory.cs 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Numerics;
  5. using System.Text;
  6. using Plotly;
  7. using Plotly.Types;
  8. using SharpGLTF.Geometry;
  9. namespace SharpGLTF
  10. {
  11. static class PlotlyFactory
  12. {
  13. public static Box<ITracesProperty> ToTrace<TMaterial>(IEnumerable<(IVertexBuilder A, IVertexBuilder B, IVertexBuilder C, TMaterial Material)> tris, Func<TMaterial, int> materialColorFunc)
  14. {
  15. var mats = new Dictionary<TMaterial, int>(); // materials to color mapping
  16. var vrts = new List<(Vector3 p, Vector3 n)>(); // vertex list
  17. var vrtm = new Dictionary<(Vector3 p, Vector3 n), int>(); // vertex sharing map
  18. var idxs = new List<(int, int, int)>(); // triangle indices
  19. var tric = new List<int>(); // face colors
  20. int _useSharedVertex(IVertexBuilder v)
  21. {
  22. var g = v.GetGeometry();
  23. g.TryGetNormal(out Vector3 n);
  24. var item = (g.GetPosition(), n);
  25. if (vrtm.TryGetValue(item, out int idx)) return idx;
  26. idx = vrts.Count;
  27. vrts.Add(item);
  28. vrtm.Add(item, idx);
  29. return idx;
  30. }
  31. foreach (var (A, B, C, Material) in tris)
  32. {
  33. if (!mats.TryGetValue(Material, out int color))
  34. {
  35. mats[Material] = color = materialColorFunc(Material);
  36. }
  37. var ap = _useSharedVertex(A);
  38. var bp = _useSharedVertex(B);
  39. var cp = _useSharedVertex(C);
  40. idxs.Add((ap, bp, cp));
  41. tric.Add(color);
  42. }
  43. // create a Plotly Mesh3D from the previously filled lists.
  44. var mx = Mesh3d.x(vrts.Select(item => item.p.X));
  45. var my = Mesh3d.y(vrts.Select(item => item.p.Y));
  46. var mz = Mesh3d.z(vrts.Select(item => item.p.Z));
  47. var mi = Mesh3d.i(idxs.Select(item => item.Item1).ToArray());
  48. var mj = Mesh3d.j(idxs.Select(item => item.Item2).ToArray());
  49. var mk = Mesh3d.k(idxs.Select(item => item.Item3).ToArray());
  50. var mo = Mesh3d.opacity(1);
  51. var mc = Mesh3d.facecolor(tric.ToArray());
  52. return Traces.mesh3d(mx, my, mz, mi, mj, mk, mo, mc);
  53. }
  54. }
  55. }