| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Numerics;
- using System.Text;
- using Plotly;
- using Plotly.Types;
- using TRACES = Plotly.Box<Plotly.Types.ITracesProperty>;
- using VERTEX = SharpGLTF.Geometry.IVertexBuilder;
- using VERTEXBUILDER = SharpGLTF.Geometry.VertexBuilder<SharpGLTF.Geometry.VertexTypes.VertexPositionNormal, SharpGLTF.Geometry.VertexTypes.VertexEmpty, SharpGLTF.Geometry.VertexTypes.VertexEmpty>;
- namespace SharpGLTF
- {
- public class PlotlyScene
- {
- #region data
- private readonly List<TRACES> _Traces = new List<TRACES>();
- private readonly Dictionary<Object, int> _Materials = new Dictionary<Object, int>(); // materials to color mapping
- #endregion
- #region API
- public void AppendTriangles<TMaterial>(IEnumerable<(VERTEX A, VERTEX B, VERTEX C, TMaterial Material)> tris, Func<TMaterial, int> materialColorFunc)
- {
- var trace = _CreateTrace(tris, materialColorFunc);
- _Traces.Add(trace);
- }
- public void AppendTriangles<TMaterial>(IEnumerable<(Vector3 A, Vector3 B, Vector3 C, TMaterial Material)> tris, Func<TMaterial, int> materialColorFunc)
- {
- (VERTEX A, VERTEX B, VERTEX C, TMaterial Material) _Convert((Vector3 A, Vector3 B, Vector3 C, TMaterial Material) tri)
- {
- var ab = tri.B - tri.A;
- var ac = tri.C - tri.A;
- var n = Vector3.Normalize(Vector3.Cross(ab, ac));
- var aa = new VERTEXBUILDER((tri.A, n));
- var bb = new VERTEXBUILDER((tri.B, n));
- var cc = new VERTEXBUILDER((tri.C, n));
- return (aa, bb, cc, tri.Material);
- }
- var trace = _CreateTrace(tris.Select(_Convert), materialColorFunc);
- _Traces.Add(trace);
- }
- public Box<IPlotProperty> ToPlotProperties() { return Plot.traces(_Traces.ToArray()); }
-
- public Plot ToPlot()
- {
- var plot = ToPlotProperties();
- var layout = _CreateLayoutProperties();
- var document = new Plot(plot, layout);
- return document;
- }
- public string ToHtml()
- {
- Plot document = ToPlot();
- return document.Render().ToString();
- }
- #endregion
- #region core
- private static Box<IPlotProperty> _CreateLayoutProperties()
- {
- var xaxis = Scene.xaxis(Xaxis.color("red"));
- var yaxis = Scene.yaxis(Yaxis.color("green"));
- var zaxis = Scene.zaxis(Zaxis.color("blue"));
- var camera = Camera.up(Up.x(0), Up.y(1), Up.z(0));
- var scene = Layout.scene(Scene.Aspectmode.data(), Scene.camera(camera), xaxis, yaxis, zaxis);
- return Plot.layout
- (Layout.autosize(true)
- // , Layout.width(0)
- , Layout.height(920)
- // , Layout.margin(Margin.autoexpand(true))
- // , Layout.margin(Margin.pad(5))
- // , Layout.margin(Margin.t(5), Margin.b(5))
- , scene
- );
- }
- private TRACES _CreateTrace<TMaterial>(IEnumerable<(VERTEX A, VERTEX B, VERTEX C, TMaterial Material)> tris, Func<TMaterial, int> materialColorFunc)
- {
- var vrts = new List<(Vector3 p, Vector3 n)>(); // vertex list
- var vrtm = new Dictionary<(Vector3 p, Vector3 n), int>(); // vertex sharing map
- var idxs = new List<(int, int, int)>(); // triangle indices
- var tric = new List<int>(); // face colors
- int _useSharedVertex(VERTEX v)
- {
- var g = v.GetGeometry();
- g.TryGetNormal(out Vector3 n);
- var item = (g.GetPosition(), n);
- if (vrtm.TryGetValue(item, out int idx)) return idx;
- idx = vrts.Count;
- vrts.Add(item);
- vrtm.Add(item, idx);
- return idx;
- }
- foreach (var (A, B, C, Material) in tris)
- {
- if (!_Materials.TryGetValue(Material, out int color))
- {
- _Materials[Material] = color = materialColorFunc(Material);
- }
- var ap = _useSharedVertex(A);
- var bp = _useSharedVertex(B);
- var cp = _useSharedVertex(C);
- idxs.Add((ap, bp, cp));
- tric.Add(color);
- }
- // create a Plotly Mesh3D from the previously filled lists.
- var mx = Mesh3d.x(vrts.Select(item => item.p.X));
- var my = Mesh3d.y(vrts.Select(item => item.p.Y));
- var mz = Mesh3d.z(vrts.Select(item => item.p.Z));
- var mi = Mesh3d.i(idxs.Select(item => item.Item1).ToArray());
- var mj = Mesh3d.j(idxs.Select(item => item.Item2).ToArray());
- var mk = Mesh3d.k(idxs.Select(item => item.Item3).ToArray());
- var mo = Mesh3d.opacity(1);
- var mc = Mesh3d.facecolor(tric.ToArray());
- return Traces.mesh3d(mx, my, mz, mi, mj, mk, mo, mc);
- }
- #endregion
- }
- }
|