Browse Source

Improved plotly funcions.

Vicente Penades 5 years ago
parent
commit
10c0512d45

+ 0 - 63
examples/SharpGLTF.Plotly/Extensions.cs

@@ -1,63 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Numerics;
-using System.Transactions;
-
-using SharpGLTF.Geometry;
-using SharpGLTF.Materials;
-using SharpGLTF.Schema2;
-
-namespace SharpGLTF
-{
-    public static class PlotlyExtensions
-    {
-        public static Plotly.Box<Plotly.Types.ITracesProperty> ToTrace(this Schema2.Scene scene)
-        {
-            return PlotlyFactory.ToTrace(scene.EvaluateTriangles(), GetMaterialColor);
-        }
-
-        public static Plotly.Box<Plotly.Types.ITracesProperty> ToTrace(this Schema2.Mesh mesh)
-        {
-            return PlotlyFactory.ToTrace(mesh.EvaluateTriangles(), GetMaterialColor);
-        }
-        
-        public static Plotly.Box<Plotly.Types.ITracesProperty> ToTrace(this IMeshBuilder<MaterialBuilder> mesh)
-        {
-            IEnumerable<(IVertexBuilder, IVertexBuilder, IVertexBuilder, MaterialBuilder)> _enumTris()
-            {
-                foreach (var p in mesh.Primitives)
-                {
-                    foreach (var (A, B, C) in p.Triangles)
-                    {
-                        var va = p.Vertices[A];
-                        var vb = p.Vertices[B];
-                        var vc = p.Vertices[C];
-
-                        yield return (va, vb, vc, p.Material);
-                    }
-                }
-            }
-
-            return PlotlyFactory.ToTrace(_enumTris(), GetMaterialColor);
-        }
-
-        private static int GetMaterialColor(Schema2.Material material)
-        {
-            var mb = new MaterialBuilder();
-            material.CopyTo(mb);
-            return GetMaterialColor(mb);
-        }
-
-        private static int GetMaterialColor(MaterialBuilder material)
-        {
-            var color = (material.GetChannel(KnownChannel.BaseColor) ?? material.GetChannel(KnownChannel.Diffuse))?.Parameter ?? Vector4.One * 0.8f;
-
-            color *= 255;
-
-            var ccc = color.X * 65536 + color.Y * 256 + color.Z;
-
-            return (int)ccc;
-        }
-    }
-}

+ 0 - 70
examples/SharpGLTF.Plotly/PlotlyFactory.cs

@@ -1,70 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Numerics;
-using System.Text;
-
-using Plotly;
-using Plotly.Types;
-
-using SharpGLTF.Geometry;
-
-namespace SharpGLTF
-{
-    static class PlotlyFactory
-    {
-        public static Box<ITracesProperty> ToTrace<TMaterial>(IEnumerable<(IVertexBuilder A, IVertexBuilder B, IVertexBuilder C, TMaterial Material)> tris, Func<TMaterial, int> materialColorFunc)
-        {
-            var mats = new Dictionary<TMaterial, int>();                // materials to color mapping
-
-            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(IVertexBuilder 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 (!mats.TryGetValue(Material, out int color))
-                {
-                    mats[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);
-        }
-    }
-}

+ 128 - 0
examples/SharpGLTF.Plotly/PlotlyScene.cs

@@ -0,0 +1,128 @@
+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;
+
+namespace SharpGLTF
+{
+    public class PlotlyScene
+    {
+        #region data
+
+        private readonly List<TRACES> _Traces = new List<TRACES>();
+        private readonly Dictionary<Object, int> mats = 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, Matrix4x4 xform, Func<TMaterial, int> materialColorFunc)
+        {
+            var trace = _CreateTrace(tris, xform, 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, Matrix4x4 xform, 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 (!mats.TryGetValue(Material, out int color))
+                {
+                    mats[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
+    }
+}

+ 98 - 0
examples/SharpGLTF.Plotly/PlotlyToolkit.cs

@@ -0,0 +1,98 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Numerics;
+using System.Text;
+
+using SharpGLTF.Geometry;
+using SharpGLTF.Materials;
+using SharpGLTF.Schema2;
+
+using TRACES = Plotly.Box<Plotly.Types.ITracesProperty>;
+
+namespace SharpGLTF
+{
+    public static class PlotlyToolkit
+    {
+        public static PlotlyScene ToPlotly(this Schema2.Scene srcScene, Animation animation = null, float time = 0)
+        {
+            // create an instantiable scene.
+            var sceneInstance = Runtime.SceneTemplate
+                .Create(srcScene, false)
+                .CreateInstance();
+
+            // set the node animations for our scene instance-
+            if (animation == null) { sceneInstance.SetPoseTransforms(); }
+            else { sceneInstance.SetAnimationFrame(animation.Name, time); }
+
+            // keep source meshes.
+            var meshes = srcScene.LogicalParent.LogicalMeshes;
+
+            // get the drawable instances.
+            var instances = sceneInstance
+                .DrawableInstances
+                .Where(item => item.Transform.Visible);
+
+            // prepare the PlotlyScene.
+            var dstScene = new PlotlyScene();
+
+            // enumerate and "render" the instances.
+            foreach (var instance in instances)
+            {
+                var mesh = meshes[instance.Template.LogicalMeshIndex];
+                var tris = mesh.EvaluateTriangles(instance.Transform);
+
+                dstScene.AppendTriangles(tris, Matrix4x4.Identity, GetMaterialColor);
+            }
+
+            return dstScene;            
+        }
+
+        public static PlotlyScene ToPlotly(this Schema2.Mesh mesh)
+        {
+            var dstScene = new PlotlyScene();
+            dstScene.AppendTriangles(mesh.EvaluateTriangles(), Matrix4x4.Identity, GetMaterialColor);
+            return dstScene;
+        }
+
+        public static PlotlyScene ToPlotly(this IMeshBuilder<MaterialBuilder> mesh)
+        {
+            IEnumerable<(IVertexBuilder, IVertexBuilder, IVertexBuilder, MaterialBuilder)> _enumTris()
+            {
+                foreach (var p in mesh.Primitives)
+                {
+                    foreach (var (A, B, C) in p.Triangles)
+                    {
+                        var va = p.Vertices[A];
+                        var vb = p.Vertices[B];
+                        var vc = p.Vertices[C];
+
+                        yield return (va, vb, vc, p.Material);
+                    }
+                }
+            }
+
+            var scene = new PlotlyScene();
+            scene.AppendTriangles(_enumTris(), Matrix4x4.Identity, GetMaterialColor);
+            return scene;
+        }
+
+        private static int GetMaterialColor(Schema2.Material material)
+        {
+            var mb = new MaterialBuilder();
+            material.CopyTo(mb);
+            return GetMaterialColor(mb);
+        }
+
+        private static int GetMaterialColor(MaterialBuilder material)
+        {
+            var color = (material.GetChannel(KnownChannel.BaseColor) ?? material.GetChannel(KnownChannel.Diffuse))?.Parameter ?? Vector4.One * 0.8f;
+
+            color *= 255;
+
+            var ccc = color.X * 65536 + color.Y * 256 + color.Z;
+
+            return (int)ccc;
+        }
+    }
+}

+ 5 - 25
tests/SharpGLTF.NUnit/NUnitGltfUtils.cs

@@ -79,31 +79,11 @@ namespace SharpGLTF
             {
                 fileName = fileName.Replace(".plotly", ".html");
 
-                
-
-                var trace = model.DefaultScene.ToTrace();
-                var plot = Plotly.Plot.traces(trace);
-
-                var xaxis = Plotly.Scene.xaxis(Plotly.Xaxis.color("red"));
-                var yaxis = Plotly.Scene.yaxis(Plotly.Yaxis.color("green"));
-                var zaxis = Plotly.Scene.zaxis(Plotly.Zaxis.color("blue"));
-                var camera = Plotly.Camera.up(Plotly.Up.x(0), Plotly.Up.y(1), Plotly.Up.z(0));
-                var scene = Plotly.Layout.scene(Plotly.Scene.Aspectmode.data(), Plotly.Scene.camera(camera) ,xaxis,yaxis,zaxis );
-
-                var layout = Plotly.Plot.layout
-                    ( Plotly.Layout.autosize(true)
-                    // , Plotly.Layout.width(0)
-                    , Plotly.Layout.height(920)
-                    // , Plotly.Layout.margin(Plotly.Margin.autoexpand(true))
-                    // , Plotly.Layout.margin(Plotly.Margin.pad(5))                    
-                    // , Plotly.Layout.margin(Plotly.Margin.t(5), Plotly.Margin.b(5))                    
-                    , scene
-                    );                
-
-                var document = new Plotly.Plot(plot, layout);                
-                var render = document.Render().ToString();
-
-                System.IO.File.WriteAllText(fileName, render);
+                var html = model.DefaultScene
+                    .ToPlotly()
+                    .ToHtml();
+
+                System.IO.File.WriteAllText(fileName, html);
             }
 
             // Attach the saved file to the current test

+ 3 - 1
tests/SharpGLTF.NUnit/Plotting.cs

@@ -4,6 +4,8 @@ using System.Linq;
 using System.Numerics;
 using System.Text;
 
+using TRACES = Plotly.Box<Plotly.Types.ITracesProperty>;
+
 namespace SharpGLTF
 {
     public static class Plotting
@@ -116,7 +118,7 @@ namespace SharpGLTF
                 DrawToFile(filePath, this);
             }
 
-            private Plotly.Box<Plotly.Types.ITracesProperty> GetTrace()
+            private TRACES GetTrace()
             {
                 var x = Plotly.Scatter.x(_Points.Select(item => (float)item.X));
                 var y = Plotly.Scatter.y(_Points.Select(item => (float)item.Y));

+ 2 - 0
tests/SharpGLTF.Toolkit.Tests/Scenes/SceneBuilderTests.cs

@@ -553,6 +553,8 @@ namespace SharpGLTF.Scenes
             var srcModel = ModelRoot.Load(path, Validation.ValidationMode.TryFix);
             Assert.NotNull(srcModel);
 
+            srcModel.AttachToCurrentTest("GearBoxAssy.plotly");
+
             // convert it to a SceneBuilder so we can manipulate it:
             var srcScene = srcModel.DefaultScene.ToSceneBuilder();