Skip to content

Commit 10c0512

Browse files
committed
Improved plotly funcions.
1 parent 43fe29a commit 10c0512

File tree

7 files changed

+236
-159
lines changed

7 files changed

+236
-159
lines changed

examples/SharpGLTF.Plotly/Extensions.cs

Lines changed: 0 additions & 63 deletions
This file was deleted.

examples/SharpGLTF.Plotly/PlotlyFactory.cs

Lines changed: 0 additions & 70 deletions
This file was deleted.
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Numerics;
5+
using System.Text;
6+
7+
using Plotly;
8+
using Plotly.Types;
9+
10+
using TRACES = Plotly.Box<Plotly.Types.ITracesProperty>;
11+
12+
using VERTEX = SharpGLTF.Geometry.IVertexBuilder;
13+
14+
namespace SharpGLTF
15+
{
16+
public class PlotlyScene
17+
{
18+
#region data
19+
20+
private readonly List<TRACES> _Traces = new List<TRACES>();
21+
private readonly Dictionary<Object, int> mats = new Dictionary<Object, int>(); // materials to color mapping
22+
23+
#endregion
24+
25+
#region API
26+
27+
public void AppendTriangles<TMaterial>(IEnumerable<(VERTEX A, VERTEX B, VERTEX C, TMaterial Material)> tris, Matrix4x4 xform, Func<TMaterial, int> materialColorFunc)
28+
{
29+
var trace = _CreateTrace(tris, xform, materialColorFunc);
30+
31+
_Traces.Add(trace);
32+
}
33+
34+
public Box<IPlotProperty> ToPlotProperties() { return Plot.traces(_Traces.ToArray()); }
35+
36+
public Plot ToPlot()
37+
{
38+
var plot = ToPlotProperties();
39+
var layout = _CreateLayoutProperties();
40+
41+
var document = new Plot(plot, layout);
42+
return document;
43+
}
44+
45+
public string ToHtml()
46+
{
47+
Plot document = ToPlot();
48+
return document.Render().ToString();
49+
}
50+
51+
#endregion
52+
53+
#region core
54+
55+
private static Box<IPlotProperty> _CreateLayoutProperties()
56+
{
57+
var xaxis = Scene.xaxis(Xaxis.color("red"));
58+
var yaxis = Scene.yaxis(Yaxis.color("green"));
59+
var zaxis = Scene.zaxis(Zaxis.color("blue"));
60+
var camera = Camera.up(Up.x(0), Up.y(1), Up.z(0));
61+
var scene = Layout.scene(Scene.Aspectmode.data(), Scene.camera(camera), xaxis, yaxis, zaxis);
62+
63+
return Plot.layout
64+
(Layout.autosize(true)
65+
// , Layout.width(0)
66+
, Layout.height(920)
67+
// , Layout.margin(Margin.autoexpand(true))
68+
// , Layout.margin(Margin.pad(5))
69+
// , Layout.margin(Margin.t(5), Margin.b(5))
70+
, scene
71+
);
72+
}
73+
74+
private TRACES _CreateTrace<TMaterial>(IEnumerable<(VERTEX A, VERTEX B, VERTEX C, TMaterial Material)> tris, Matrix4x4 xform, Func<TMaterial, int> materialColorFunc)
75+
{
76+
var vrts = new List<(Vector3 p, Vector3 n)>(); // vertex list
77+
var vrtm = new Dictionary<(Vector3 p, Vector3 n), int>(); // vertex sharing map
78+
79+
var idxs = new List<(int, int, int)>(); // triangle indices
80+
var tric = new List<int>(); // face colors
81+
82+
int _useSharedVertex(VERTEX v)
83+
{
84+
var g = v.GetGeometry();
85+
86+
g.TryGetNormal(out Vector3 n);
87+
var item = (g.GetPosition(), n);
88+
if (vrtm.TryGetValue(item, out int idx)) return idx;
89+
idx = vrts.Count;
90+
vrts.Add(item);
91+
vrtm.Add(item, idx);
92+
return idx;
93+
}
94+
95+
foreach (var (A, B, C, Material) in tris)
96+
{
97+
if (!mats.TryGetValue(Material, out int color))
98+
{
99+
mats[Material] = color = materialColorFunc(Material);
100+
}
101+
102+
var ap = _useSharedVertex(A);
103+
var bp = _useSharedVertex(B);
104+
var cp = _useSharedVertex(C);
105+
106+
idxs.Add((ap, bp, cp));
107+
tric.Add(color);
108+
}
109+
110+
// create a Plotly Mesh3D from the previously filled lists.
111+
112+
var mx = Mesh3d.x(vrts.Select(item => item.p.X));
113+
var my = Mesh3d.y(vrts.Select(item => item.p.Y));
114+
var mz = Mesh3d.z(vrts.Select(item => item.p.Z));
115+
116+
var mi = Mesh3d.i(idxs.Select(item => item.Item1).ToArray());
117+
var mj = Mesh3d.j(idxs.Select(item => item.Item2).ToArray());
118+
var mk = Mesh3d.k(idxs.Select(item => item.Item3).ToArray());
119+
120+
var mo = Mesh3d.opacity(1);
121+
var mc = Mesh3d.facecolor(tric.ToArray());
122+
123+
return Traces.mesh3d(mx, my, mz, mi, mj, mk, mo, mc);
124+
}
125+
126+
#endregion
127+
}
128+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Numerics;
5+
using System.Text;
6+
7+
using SharpGLTF.Geometry;
8+
using SharpGLTF.Materials;
9+
using SharpGLTF.Schema2;
10+
11+
using TRACES = Plotly.Box<Plotly.Types.ITracesProperty>;
12+
13+
namespace SharpGLTF
14+
{
15+
public static class PlotlyToolkit
16+
{
17+
public static PlotlyScene ToPlotly(this Schema2.Scene srcScene, Animation animation = null, float time = 0)
18+
{
19+
// create an instantiable scene.
20+
var sceneInstance = Runtime.SceneTemplate
21+
.Create(srcScene, false)
22+
.CreateInstance();
23+
24+
// set the node animations for our scene instance-
25+
if (animation == null) { sceneInstance.SetPoseTransforms(); }
26+
else { sceneInstance.SetAnimationFrame(animation.Name, time); }
27+
28+
// keep source meshes.
29+
var meshes = srcScene.LogicalParent.LogicalMeshes;
30+
31+
// get the drawable instances.
32+
var instances = sceneInstance
33+
.DrawableInstances
34+
.Where(item => item.Transform.Visible);
35+
36+
// prepare the PlotlyScene.
37+
var dstScene = new PlotlyScene();
38+
39+
// enumerate and "render" the instances.
40+
foreach (var instance in instances)
41+
{
42+
var mesh = meshes[instance.Template.LogicalMeshIndex];
43+
var tris = mesh.EvaluateTriangles(instance.Transform);
44+
45+
dstScene.AppendTriangles(tris, Matrix4x4.Identity, GetMaterialColor);
46+
}
47+
48+
return dstScene;
49+
}
50+
51+
public static PlotlyScene ToPlotly(this Schema2.Mesh mesh)
52+
{
53+
var dstScene = new PlotlyScene();
54+
dstScene.AppendTriangles(mesh.EvaluateTriangles(), Matrix4x4.Identity, GetMaterialColor);
55+
return dstScene;
56+
}
57+
58+
public static PlotlyScene ToPlotly(this IMeshBuilder<MaterialBuilder> mesh)
59+
{
60+
IEnumerable<(IVertexBuilder, IVertexBuilder, IVertexBuilder, MaterialBuilder)> _enumTris()
61+
{
62+
foreach (var p in mesh.Primitives)
63+
{
64+
foreach (var (A, B, C) in p.Triangles)
65+
{
66+
var va = p.Vertices[A];
67+
var vb = p.Vertices[B];
68+
var vc = p.Vertices[C];
69+
70+
yield return (va, vb, vc, p.Material);
71+
}
72+
}
73+
}
74+
75+
var scene = new PlotlyScene();
76+
scene.AppendTriangles(_enumTris(), Matrix4x4.Identity, GetMaterialColor);
77+
return scene;
78+
}
79+
80+
private static int GetMaterialColor(Schema2.Material material)
81+
{
82+
var mb = new MaterialBuilder();
83+
material.CopyTo(mb);
84+
return GetMaterialColor(mb);
85+
}
86+
87+
private static int GetMaterialColor(MaterialBuilder material)
88+
{
89+
var color = (material.GetChannel(KnownChannel.BaseColor) ?? material.GetChannel(KnownChannel.Diffuse))?.Parameter ?? Vector4.One * 0.8f;
90+
91+
color *= 255;
92+
93+
var ccc = color.X * 65536 + color.Y * 256 + color.Z;
94+
95+
return (int)ccc;
96+
}
97+
}
98+
}

tests/SharpGLTF.NUnit/NUnitGltfUtils.cs

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -79,31 +79,11 @@ public static string AttachToCurrentTest(this Schema2.ModelRoot model, string fi
7979
{
8080
fileName = fileName.Replace(".plotly", ".html");
8181

82-
83-
84-
var trace = model.DefaultScene.ToTrace();
85-
var plot = Plotly.Plot.traces(trace);
86-
87-
var xaxis = Plotly.Scene.xaxis(Plotly.Xaxis.color("red"));
88-
var yaxis = Plotly.Scene.yaxis(Plotly.Yaxis.color("green"));
89-
var zaxis = Plotly.Scene.zaxis(Plotly.Zaxis.color("blue"));
90-
var camera = Plotly.Camera.up(Plotly.Up.x(0), Plotly.Up.y(1), Plotly.Up.z(0));
91-
var scene = Plotly.Layout.scene(Plotly.Scene.Aspectmode.data(), Plotly.Scene.camera(camera) ,xaxis,yaxis,zaxis );
92-
93-
var layout = Plotly.Plot.layout
94-
( Plotly.Layout.autosize(true)
95-
// , Plotly.Layout.width(0)
96-
, Plotly.Layout.height(920)
97-
// , Plotly.Layout.margin(Plotly.Margin.autoexpand(true))
98-
// , Plotly.Layout.margin(Plotly.Margin.pad(5))
99-
// , Plotly.Layout.margin(Plotly.Margin.t(5), Plotly.Margin.b(5))
100-
, scene
101-
);
102-
103-
var document = new Plotly.Plot(plot, layout);
104-
var render = document.Render().ToString();
105-
106-
System.IO.File.WriteAllText(fileName, render);
82+
var html = model.DefaultScene
83+
.ToPlotly()
84+
.ToHtml();
85+
86+
System.IO.File.WriteAllText(fileName, html);
10787
}
10888

10989
// Attach the saved file to the current test

0 commit comments

Comments
 (0)