diff --git a/Ara3D.sln b/Ara3D.sln
index 9391558..05b951a 100644
--- a/Ara3D.sln
+++ b/Ara3D.sln
@@ -1,4 +1,5 @@
+
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28010.2016
@@ -15,9 +16,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ara3D.G3SharpBridge", "dotn
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ara3D.ScriptEditor", "dotnet\AraScriptEditor\Ara3D.ScriptEditor.csproj", "{E52B90C6-9F2F-4C5F-BAFF-BF4F46E9C6A0}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ara3D.3dsMaxBridge", "dotnet\3dsMaxBridge\Ara3D.3dsMaxBridge.csproj", "{64860EC8-B0EB-44BB-B5BB-039200ADA53E}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ara3D.3dsMaxBridge", "..\revit-dev\3dsMaxBridge\Ara3D.3dsMaxBridge.csproj", "{64860EC8-B0EB-44BB-B5BB-039200ADA53E}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ara3D.3dsMaxSamples", "dotnet\3dsMaxSamples\Ara3D.3dsMaxSamples.csproj", "{BCF10249-713C-46AD-97EF-BA62A123FBD7}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ara3D.3dsMaxSamples", "..\revit-dev\3dsMaxSamples\Ara3D.3dsMaxSamples.csproj", "{BCF10249-713C-46AD-97EF-BA62A123FBD7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ara3D.Parakeet", "dotnet\Parakeet\Ara3D.Parakeet.csproj", "{DEB3F735-979F-4C1C-819D-85E48E23BF52}"
EndProject
diff --git a/MigrationBackup/64c67db1/StlImport/NuGetUpgradeLog.html b/MigrationBackup/64c67db1/StlImport/NuGetUpgradeLog.html
new file mode 100644
index 0000000..900817d
--- /dev/null
+++ b/MigrationBackup/64c67db1/StlImport/NuGetUpgradeLog.html
@@ -0,0 +1,163 @@
+
+
+
+
+ NuGetMigrationLog
+
+ NuGet Migration Report - StlImport
Overview
Migration to PackageReference was completed successfully. Please build and run your solution to verify that all packages are available.
+ If you run into any problems, have feedback, questions, or concerns, please
+
file an issue on the NuGet GitHub repository.
+ Changed files and this report have been backed up here:
+
C:\dev\repos\ara3d-dev\MigrationBackup\64c67db1\StlImportPackages processed
Top-level dependencies:
| Package Id | Version |
|---|
| QuantumConcepts.Common |
+ v1.0.0.1 |
| QuantumConcepts.Formats.STL |
+ v1.1.0 |
Transitive dependencies:
| Package Id | Version |
|---|
|
+ No transitive dependencies found.
+ | |
Package compatibility issues
| Description |
|---|
|
+ No issues were found.
+ |
\ No newline at end of file
diff --git a/MigrationBackup/64c67db1/StlImport/StlImport.csproj b/MigrationBackup/64c67db1/StlImport/StlImport.csproj
new file mode 100644
index 0000000..837d55c
--- /dev/null
+++ b/MigrationBackup/64c67db1/StlImport/StlImport.csproj
@@ -0,0 +1,88 @@
+
+
+
+
+ None
+
+
+
+
+ Debug
+ AnyCPU
+
+
+
+
+ {4E97B36B-56AD-458C-9DB3-F26D376D3A4D}
+ Library
+ Properties
+ StlImport
+ v4.5
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ Program
+ $(ProgramW6432)\Autodesk\Revit 2015\Revit.exe
+ false
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ Program
+ $(ProgramW6432)\Autodesk\Revit 2015\Revit.exe
+ false
+
+
+
+
+ ..\packages\QuantumConcepts.Common.1.0.0.1\lib\net40\QuantumConcepts.Common.dll
+
+
+ ..\packages\QuantumConcepts.Formats.STL.1.1.0.0\lib\net40\QuantumConcepts.Formats.STL.dll
+
+
+ $(ProgramW6432)\Autodesk\Revit 2015\RevitAPI.dll
+ False
+
+
+ $(ProgramW6432)\Autodesk\Revit 2015\RevitAPIUI.dll
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ copy "$(ProjectDir)StlImport.addin" "$(AppData)\Autodesk\REVIT\Addins\2015"
+copy "$(ProjectDir)bin\debug\StlImport.dll" "$(AppData)\Autodesk\REVIT\Addins\2015"
+copy "$(ProjectDir)bin\debug\QuantumConcepts*.dll" "$(AppData)\Autodesk\REVIT\Addins\2015"
+
+
\ No newline at end of file
diff --git a/MigrationBackup/64c67db1/StlImport/packages.config b/MigrationBackup/64c67db1/StlImport/packages.config
new file mode 100644
index 0000000..543ecd4
--- /dev/null
+++ b/MigrationBackup/64c67db1/StlImport/packages.config
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/dotnet/3dsMaxBridge/Ara3D.3dsMaxBridge.csproj b/dotnet/3dsMaxBridge/Ara3D.3dsMaxBridge.csproj
deleted file mode 100644
index 6e2387b..0000000
--- a/dotnet/3dsMaxBridge/Ara3D.3dsMaxBridge.csproj
+++ /dev/null
@@ -1,96 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- {64860EC8-B0EB-44BB-B5BB-039200ADA53E}
- Library
- Properties
- Ara3D._3dsMaxBridge
- Ara3D.3dsMaxBridge
- v4.7.1
- 512
- true
-
-
-
- true
- full
- false
- $(ProgramData)\Ara3D\3dsMaxBridge
- DEBUG;TRACE
- prompt
- 4
- x64
- 7.3
-
-
- pdbonly
- true
- $(ProgramData)\Ara3D\3dsMaxBridge
- TRACE
- prompt
- 4
- 7.3
-
-
- true
-
-
-
- $(ADSK_3DSMAX_x64_2019)\MaxPlusDotNet.dll
-
-
-
-
-
- True
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {e89008fa-6d3f-48de-900a-be5a9d79f4ae}
- Ara3D.Geometry
-
-
- {e52b90c6-9f2f-4c5f-baff-bf4f46e9c6a0}
- Ara3D.ScriptEditor
-
-
- {4007804A-598F-495F-84F3-F2CF3136797D}
- Ara3D.G3D
-
-
- {81718218-f3e7-4d54-8552-2a65fbebee85}
- Ara3D.LinqArray
-
-
- {25330241-4c82-4c17-8027-ff882b91640e}
- Ara3D.DotNetUtilities
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/dotnet/3dsMaxBridge/Ara3D_Startup.ms b/dotnet/3dsMaxBridge/Ara3D_Startup.ms
deleted file mode 100644
index d7431ad..0000000
--- a/dotnet/3dsMaxBridge/Ara3D_Startup.ms
+++ /dev/null
@@ -1,57 +0,0 @@
-
--- Creare Environment class (cannot create an object of this class)
--- This class does not have a constructor (it's a static class)
--- Environment = dotNetClass "System.Environment"
--- appData = Environment.GetEnvironmentVariable "AppData"
-sysEn = dotNetClass "System.Environment"
-speFo = dotNetClass "System.Environment+specialFolder"
-programDataPath = sysEn.getfolderPath speFo.commonApplicationData
-bridgePath = programDataPath + @"\Ara3D\3dsMaxBridge\Ara3D.3dsMaxBridge.dll"
-
--- showProperties speFo --There are a tonne of folders to choose from
--- showProperties sysEn --Lots of useful info here too
-
-global Ara3DMaxBridgeAsm = dotNet.loadAssembly bridgePath
-global AraAPI = dotNetClass "Ara3D.API"
-
-macroCode = "macroScript Ara3D_CSharpScriptEditor
-category: \"Ara 3D\"
-buttonText: \"Ara C# Editor\"
-tooltip: \"Ara 3D C# Script Editor\"
-(
- AraAPI.ShowEditor ()
-)
-"
-execute macroCode
-
--- Register an Ara 3D Menu if need be
-if menuMan.registerMenuContext 0x572418f3 then
-(
- -- Get the main menu bar
- local mainMenuBar = menuMan.getMainMenuBar()
- -- Create a new menu
- local subMenu = menuMan.createMenu "Ara 3D"
- -- create a menu item that calls the sample macroScript
- local testItem = menuMan.createActionItem "Ara3D_CSharpScriptEditor" "Ara 3D"
- -- Add the item to the menu
- subMenu.addItem testItem -1
- -- Create a new menu item with the menu as it's sub-menu
- local subMenuItem = menuMan.createSubMenuItem "Ara 3D" subMenu
- -- compute the index of the next-to-last menu item in the main menu bar
- local subMenuIndex = mainMenuBar.numItems()
- -- Add the sub-menu just at the second to last slot
- mainMenuBar.addItem subMenuItem subMenuIndex
- -- redraw the menu bar with the new item
- menuMan.updateMenuBar()
-)
-
-araGeometryPath = programDataPath + @"\Ara3D\3dsMaxBridge\Ara3D.Geometry.dll"
-araGeometryAsm = dotNet.loadAssembly araGeometryPath
-
-araLinqPath = programDataPath + @"\Ara3D\3dsMaxBridge\Ara3D.LinqArray.dll"
-araLinqAsm = dotNet.loadAssembly araLinqPath
-
-
-AraAPI.ShowEditor ()
--- f = dotNetObject "Ara3D.ScriptEditorForm"
--- f.ShowDialog ()
diff --git a/dotnet/3dsMaxBridge/Ara3dsMaxAPI.cs b/dotnet/3dsMaxBridge/Ara3dsMaxAPI.cs
deleted file mode 100644
index 20f8b6f..0000000
--- a/dotnet/3dsMaxBridge/Ara3dsMaxAPI.cs
+++ /dev/null
@@ -1,304 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Numerics;
-using System.Text;
-using Autodesk.Max;
-using Autodesk.Max.MaxPlus;
-using Object = Autodesk.Max.MaxPlus.Object;
-
-namespace Ara3D
-{
- /*
- asm = dotNet.loadAssembly @"C:\dev\repos\AraGeometry\3dsMaxBridge\bin\Debug\3dsMaxBridge.dll"
- bridgeClass = dotNetClass "Ara3D.AraGeometryBridge"
- */
- public static class API
- {
- public static Vector3 ToVector(this Point3 pt)
- => new Vector3(pt.X, pt.Y, pt.Z);
-
- public static Matrix4x4 ToMatrix(this Matrix3 mat)
- {
- var row0 = mat.GetRow(0);
- var row1 = mat.GetRow(1);
- var row2 = mat.GetRow(2);
- var tr = mat.GetTranslation();
- return new Matrix4x4(
- row0.X, row0.Y, row0.Z, 0,
- row1.X, row1.Y, row1.Z, 0,
- row2.X, row2.Y, row2.Z, 0,
- tr.X, tr.Y, tr.Z, 1);
- }
-
- public static Matrix3 ToMatrix3(this Matrix4x4 m)
- => new Matrix3(
- new Point3(m.M11, m.M12, m.M13),
- new Point3(m.M21, m.M22, m.M23),
- new Point3(m.M31, m.M32, m.M33),
- new Point3(m.M41, m.M42, m.M43));
-
- public static IGeometry ToTransformedIGeometry(this INode node)
- => node.ToIGeometry()?.Transform(node.GetWorldTM().ToMatrix());
-
- public static IGeometry AllGeometry
- => AllNodes.ToIGeometry();
-
- public static IEnumerable GetDescendants(this INode node)
- {
- foreach (var child in node.Children)
- foreach (var d in GetDescendants(child))
- yield return d;
- yield return node;
- }
-
- public static IEnumerable AllNodes
- => GetDescendants(Core.GetRootNode());
-
- public static IArray SelectedNodes
- => SelectionManager.GetCount().Select(SelectionManager.GetNode);
-
- public static bool AreAnyNodesSelected
- => SelectedNodes.Count > 0;
-
- public static IEnumerable AllNodesOrJustSelected
- => AreAnyNodesSelected ? SelectedNodes.ToEnumerable() : AllNodes;
-
- public static IGeometry ToIGeometry(this IEnumerable nodes)
- => nodes.Select(ToTransformedIGeometry).WhereNotNull().ToIArray().Merge();
-
- public static IGeometry AllGeometryOrJustSelected
- => AllNodesOrJustSelected.ToIGeometry();
-
- public static INode FirstSelectedNode
- => SelectionManager.GetCount() > 0 ? SelectionManager.GetNode(0) : null;
-
- public static string GetNodeInfo(this INode node)
- {
- if (node == null) return "null";
- if (!node._IsValidWrapper()) return "Invalid node wrapper";
- var sb = new StringBuilder();
- sb.AppendFormat("Node {0} {1}", node.Name, node.AnimHandle).AppendLine();
- var g = node.ToTransformedIGeometry();
- sb.AppendLine(g?.GetStats() ?? "no geometry");
- return sb.ToString();
- }
-
- public static IGeometry ToIGeometry(this INode node)
- {
- if (node == null || !node._IsValidWrapper()) return null;
-
- var orig = node.EvalWorldState().Getobj();
- if (!orig._IsValidWrapper())
- return null;
-
- var obj = orig;
- try
- {
- // Check if we have to convert the node to a TriObject (EditMesh)
- var triObjectID = ClassIds.TriMeshGeometry; // new Class_ID(0x0009, 0);
- if (!obj.IsSubClassOf(triObjectID))
- {
- if (obj.CanConvertToType(ClassIds.TriMeshGeometry) == 0)
- return null;
- obj = obj.ConvertToType(triObjectID).Validate();
- }
- var tri = TriObject._CastFrom(obj).Validate();
- var mesh = tri.GetMesh();
- return mesh.ToIGeometry();
- }
- finally
- {
- // If we converted, we have to delete the TriObject we created, it is a temporary
- if (obj != orig)
- {
- if (obj != null && obj._IsValidWrapper())
- obj.DeleteMe();
- obj._SetValue(System.IntPtr.Zero);
- }
- }
- }
-
- public static IGeometry ToIGeometry(this Mesh mesh)
- {
- if (!mesh._IsValidWrapper())
- return null;
-
- var numVerts = mesh.GetNumVertices();
- var numFaces = mesh.GetNumFaces();
-
- // Important: we have to copy the data by evaluating the arrays immediately
- var verts = numVerts.Select(v => mesh.GetVertex(v).ToVector()).Evaluate();
- var indices = (numFaces * 3).Select(f => mesh.GetFaceVertexIndex(f / 3, f % 3)).Evaluate();
-
- return Geometry.TriMesh(verts, indices);
- }
-
- public static T Validate(this T x) where T: Wrapper
- {
- if (x == null) throw new System.Exception("Null pointer exception for type " + typeof(T).Name);
- if (!x._IsValidWrapper()) throw new System.Exception("Not a valid wrapper of type " + typeof(T).Name);
- return x;
- }
-
- public static void CopyToNode(this IGeometry g, INode node)
- {
- // TODO: this muse be defined somewhere
- var orig = node.Validate().EvalWorldState().Getobj().Validate();
- var obj = orig;
-
- // Check if we have to convert the node to a TriObject (EditMesh)
- if (!obj.IsSubClassOf(ClassIds.TriMeshGeometry))
- throw new System.Exception("Expected node to have a TriObject attached to it.");
- var tri = TriObject._CastFrom(obj).Validate();
- var mesh = tri.GetMesh();
- CopyToMesh(g, mesh);
- }
-
- public static INode TransformNode(this INode node, Matrix3 m)
- {
- node.Transform = m;
- return node;
- }
-
- public static INode InstanceNode(this INode node, Matrix4x4 m)
- => node.CreateInstance().TransformNode(m.ToMatrix3());
-
- public static void CopyToMesh(this IGeometry g, Mesh mesh)
- {
- var triMesh = g.ToTriMesh();
- var numVerts = g.Vertices.Count;
- var numFaces = triMesh.GetFaces().Count;
- mesh.SetNumVerts(numVerts);
- mesh.SetNumFaces(numFaces);
-
- for (var i=0; i < numVerts; ++i)
- {
- var vert = g.Vertices[i];
- mesh.SetVert(i, vert.X, vert.Y, vert.Z);
- }
-
- for (var i=0; i < numFaces; ++i)
- {
- var e = triMesh.GetFaces()[i];
- mesh.SetFaceVertexIndexes(i, e[0], e[1], e[2]);
- // TODO: edge visibility
- // TODO: smoothing group, material id
- }
-
- // TODO: map channels
-
- // TODO: normals
-
- // TODO: what invalidating do I actually need
- mesh.InvalidateGeomCache();
- mesh.InvalidateTopologyCache();
- }
-
- public static GeometryPluginHost CreatePluginInstance()
- => new GeometryPluginHost();
-
- public static INode CreateNode(this Object obj)
- => Factory.CreateNode(obj).Validate();
-
- public static TriObject CreateTriObject()
- => TriObject._CastFrom(Factory.CreateGeomObject(ClassIds.TriMeshGeometry)).Validate();
-
- public static INode CreateNodeWithEmptyGeometry()
- => CreateTriObject().CreateNode();
-
- public static Layer CreateLayer(string name)
- => LayerManager.CreateLayer(new WStr(name));
-
- public static void LoadScene(IScene scene)
- {
- var nodeTable = new Dictionary();
- var layers = new Dictionary();
- foreach (var obj in scene.Objects.ToEnumerable())
- {
- INode node;
- if (nodeTable.ContainsKey(obj.Node.GeometryId))
- node = nodeTable[obj.Node.GeometryId].InstanceNode(obj.Node.Transform);
- else
- nodeTable.Add(obj.Node.GeometryId, node = obj.ToNode());
-
- var layer = layers.GetOrCompute(obj.Node.CategoryId, id => CreateLayer($"Category {id}"));
- layer.AddToLayer(node);
- }
- }
-
- public static void LoadG3DFiles(string folder)
- => LoadScene(GeometryReader.ReadScene(folder));
-
- public static void LoadBFastScene(string filePath)
- => LoadScene(GeometryReader.ReadSceneFromBFast(filePath));
-
- public static INode ToNode(this IGeometry g)
- {
- var tri = CreateTriObject().Validate();
- g.CopyToMesh(tri.GetMesh());
- return CreateNode(tri);
- }
-
- public static INode ToNode(this IGeometry g, Matrix4x4 m)
- => ToNode(g).TransformNode(m.ToMatrix3());
-
- public static INode ToNode(this ISceneObject obj)
- => ToNode(obj.Geometry(), obj.Node.Transform);
-
- public static string NewScript()
- {
- return
- @"
-using Autodesk.Max;
-using Autodesk.Max.MaxPlus;
-using System.Text;
-
-namespace Ara3D
-{
- public class SamplePlugin : IUtilityPlugin
- {
- public void Evaluate()
- {
- // TODO: this is where the magic happens
- }
- }
-}
-";
- }
-
- public static Process ShowEditor()
- {
- // Launch the executable
- var process = ServiceLauncher.LaunchProcess();
-
- // Connect to the service using our local callback
- ServiceConfig.OpenClientChannel(EditorClient.Instance);
-
- return process;
- }
-
- public class MAXScriptConsoleWriter : TextWriter
- {
- public override Encoding Encoding
- => Encoding.Default;
-
- public override void Write(char value)
- => Core.Write(value.ToString());
-
- public override void Write(string s)
- => Core.Write(s);
-
- public override void WriteLine()
- => Core.WriteLine("");
-
- public override void WriteLine(string s)
- => base.WriteLine(s);
- }
-
- public static void ConsoleToMAXScriptListener()
- => Console.SetOut(new MAXScriptConsoleWriter());
- }
-}
diff --git a/dotnet/3dsMaxBridge/EditorClient.cs b/dotnet/3dsMaxBridge/EditorClient.cs
deleted file mode 100644
index 7a8f094..0000000
--- a/dotnet/3dsMaxBridge/EditorClient.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using Ara3D.DotNetUtilities;
-using System.Collections.Generic;
-
-namespace Ara3D
-{
- public class EditorClient : SingletonRemotingObject, IEditorClientCallback
- {
- public Dictionary Scripts
- = new Dictionary();
-
- public UtilityPluginScript GetScript(string fileName)
- => Scripts.GetOrCompute(fileName, f => new UtilityPluginScript(f));
-
- public IList Compile(string fileName)
- => GetScript(fileName).Compile();
-
- public bool Run(string fileName)
- => GetScript(fileName).Run();
-
- public string NewSnippet()
- => API.NewScript();
- }
-}
diff --git a/dotnet/3dsMaxBridge/GeometryPluginHost.cs b/dotnet/3dsMaxBridge/GeometryPluginHost.cs
deleted file mode 100644
index 9e0815d..0000000
--- a/dotnet/3dsMaxBridge/GeometryPluginHost.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using Autodesk.Max.MaxPlus;
-
-namespace Ara3D
-{
- // Provides data to the IGeometryPlugin and calls it when necessary
- public class GeometryPluginHost : PluginHost, IGeometryPluginHost
- {
- // The plug-in host parameters
- public object[] Args { get; set; }
- public int Time { get; set; }
- public int LastTime { get; set; }
- public IGeometry LastValue { get; set; }
-
- public void UpdateMesh(int time, Mesh mesh, string script, object[] args)
- {
- Compile(script);
- if (Plugin != null)
- {
- Args = args;
- Time = time;
- LastValue = Plugin.Evaluate(this);
- LastTime = time;
- LastValue.CopyToMesh(mesh);
- }
- else
- {
- LastValue = null;
- LastTime = time;
- }
- }
- }
-}
diff --git a/dotnet/3dsMaxBridge/MAXScript/Ara3D_CustomAttributesLister.ms b/dotnet/3dsMaxBridge/MAXScript/Ara3D_CustomAttributesLister.ms
deleted file mode 100644
index 0e1b0e5..0000000
--- a/dotnet/3dsMaxBridge/MAXScript/Ara3D_CustomAttributesLister.ms
+++ /dev/null
@@ -1,4 +0,0 @@
-objCustAttribs = custAttributes.get $ 1 baseobject:false
-showproperties objCustAttribs
-for p in getPropNames objCustAttribs do
- format "% = %\n" p (getProperty $ p)
\ No newline at end of file
diff --git a/dotnet/3dsMaxBridge/MAXScript/Ara3D_Startup.ms b/dotnet/3dsMaxBridge/MAXScript/Ara3D_Startup.ms
deleted file mode 100644
index d7431ad..0000000
--- a/dotnet/3dsMaxBridge/MAXScript/Ara3D_Startup.ms
+++ /dev/null
@@ -1,57 +0,0 @@
-
--- Creare Environment class (cannot create an object of this class)
--- This class does not have a constructor (it's a static class)
--- Environment = dotNetClass "System.Environment"
--- appData = Environment.GetEnvironmentVariable "AppData"
-sysEn = dotNetClass "System.Environment"
-speFo = dotNetClass "System.Environment+specialFolder"
-programDataPath = sysEn.getfolderPath speFo.commonApplicationData
-bridgePath = programDataPath + @"\Ara3D\3dsMaxBridge\Ara3D.3dsMaxBridge.dll"
-
--- showProperties speFo --There are a tonne of folders to choose from
--- showProperties sysEn --Lots of useful info here too
-
-global Ara3DMaxBridgeAsm = dotNet.loadAssembly bridgePath
-global AraAPI = dotNetClass "Ara3D.API"
-
-macroCode = "macroScript Ara3D_CSharpScriptEditor
-category: \"Ara 3D\"
-buttonText: \"Ara C# Editor\"
-tooltip: \"Ara 3D C# Script Editor\"
-(
- AraAPI.ShowEditor ()
-)
-"
-execute macroCode
-
--- Register an Ara 3D Menu if need be
-if menuMan.registerMenuContext 0x572418f3 then
-(
- -- Get the main menu bar
- local mainMenuBar = menuMan.getMainMenuBar()
- -- Create a new menu
- local subMenu = menuMan.createMenu "Ara 3D"
- -- create a menu item that calls the sample macroScript
- local testItem = menuMan.createActionItem "Ara3D_CSharpScriptEditor" "Ara 3D"
- -- Add the item to the menu
- subMenu.addItem testItem -1
- -- Create a new menu item with the menu as it's sub-menu
- local subMenuItem = menuMan.createSubMenuItem "Ara 3D" subMenu
- -- compute the index of the next-to-last menu item in the main menu bar
- local subMenuIndex = mainMenuBar.numItems()
- -- Add the sub-menu just at the second to last slot
- mainMenuBar.addItem subMenuItem subMenuIndex
- -- redraw the menu bar with the new item
- menuMan.updateMenuBar()
-)
-
-araGeometryPath = programDataPath + @"\Ara3D\3dsMaxBridge\Ara3D.Geometry.dll"
-araGeometryAsm = dotNet.loadAssembly araGeometryPath
-
-araLinqPath = programDataPath + @"\Ara3D\3dsMaxBridge\Ara3D.LinqArray.dll"
-araLinqAsm = dotNet.loadAssembly araLinqPath
-
-
-AraAPI.ShowEditor ()
--- f = dotNetObject "Ara3D.ScriptEditorForm"
--- f.ShowDialog ()
diff --git a/dotnet/3dsMaxBridge/MAXScript/Ara3D_TestFbxImport.ms b/dotnet/3dsMaxBridge/MAXScript/Ara3D_TestFbxImport.ms
deleted file mode 100644
index 849bc59..0000000
--- a/dotnet/3dsMaxBridge/MAXScript/Ara3D_TestFbxImport.ms
+++ /dev/null
@@ -1,3 +0,0 @@
-start = timeStamp()
-importfile "C:\Users\ara3d\AppData\Local\Ara3D\RevitDevPlugin\2019-03-05_03-12-28-main\main.fbx" #noPrompt using:FBXIMP
-end = timeStamp()
\ No newline at end of file
diff --git a/dotnet/3dsMaxBridge/MAXScript/AraManualScriptedObject.ms b/dotnet/3dsMaxBridge/MAXScript/AraManualScriptedObject.ms
deleted file mode 100644
index f0bce78..0000000
--- a/dotnet/3dsMaxBridge/MAXScript/AraManualScriptedObject.ms
+++ /dev/null
@@ -1,134 +0,0 @@
--- A scripted geometry plug-in that executes arbitrary C# code.
--- Custom Attributes: https://help.autodesk.com/view/3DSMAX/2017/ENU/?guid=__files_GUID_ADFD29E4_9751_4F55_98CC_F7C721C9AEE2_htm
--- Scripted plug-in clauses: https://help.autodesk.com/view/3DSMAX/2017/ENU/?guid=__files_GUID_461915FA_31A2_49CE_84AF_2544B782ACA3_htm
-
--- There is going to be a bunch of assemblies to load.
-asm = dotNet.loadAssembly @"C:\dev\repos\AraGeometry\3dsMaxBridge\bin\Debug\3dsMaxBridge.dll"
-
-plugin simpleObject AraScriptedObject
- name:"C# Script"
- classID:#(0x56880e2a, 0x8323dbe)
- category:"Ara 3D"
- usePBValidity:true
-(
- local pluginDefinitionFile -- the plugin definition file
- local pluginInstance -- the plugin instance created from the plugin definition
- local _meshWrapper -- the dotnet wrapper around our mesh pointer
- local argsType = dotNetClass "System.Object[]" -- used when creating args array
- local dotnet_ValueToDotNetObject = dotnet.ValueToDotNetObject
- local tmHandler
- local owningNode
-
- -- function wrappers
- local _meshWrapper_SetValue
- local pluginInstance_UpdateMesh
-
- -- value wrapper local and function wrapper declarations
-
- local bridgeClass
-
- parameters main rollout:params
- (
- script ui:Script type:#string default:"Hello world!"
- _dummy type:#boolean invisibleInTV:true -- this exists to enable easy invalidation of the object
- )
-
- fn initialize =
- (
- print "Initializing Ara 3D C# Object"
-
- -- TODO: Create a .NET instance of a reference maker class that corresponds to this plug-in
- -- RefMakerWrapperClass = dotnetclass "Autodesk.Max.MaxPlus.ReferenceMaker"
- -- _pluginOwner = refMakerWrapperClass._CreateWrapper this
-
- -- Create a .NET instance of a "GeometryPluginInstanceBridge" which allows interfacing with Ara 3D system
- bridgeClass = dotNetClass "Ara3D.Ara"
- pluginInstance = bridgeClass.CreatePluginInstance ()
- local meshWrapperClass = dotnetclass "Autodesk.Max.MaxPlus.Mesh"
-
- -- Create a .NET instance of a Autodesk.Max.MaxPlus.Mesh so that meshes can be easily passed to the plug-in instance
- _meshWrapper = meshWrapperClass._CreateWrapper undefined
- _meshWrapper_SetValue = _meshWrapper._SetValue
- )
-
- on create do
- (
- initialize()
- )
-
- on clone fromObj do
- (
- initialize()
- )
-
- on load do
- (
- initialize()
- )
-
- on update do
- (
- initialize()
- )
-
- fn installTMHandler theNode =
- (
- -- Force updating the plug-in when the transform is updated on the owning node and track what node this plug-in is associated with.
- -- Cloned instances of the plug-in are ignored.
- owningNode = theNode
-
- if (tmHandler == undefined and owningNode != undefined) then ( tmHandler = when transform owningNode changes do ( _dummy = not _dummy ))
- -- TODO: Create a .NET instance of an INode class that corresponds to the owner INode (well we really want the Matrix)
- -- INodeWrapperClass = dotnetclass "Autodesk.Max.MaxPlus.INode"
- -- _inode = INodeWrapperClass._CreateWrapper owningNode
- )
-
- on postload do
- (
- installTMHandler(refs.dependentnodes this firstonly:true)
- )
-
- on attachedToNode theNode do
- (
- installTMHandler(theNode)
- )
-
- tool create
- (
- on mousePoint click do
- (
- #stop
- )
- )
-
- fn updateMesh =
- (
- print "Building mesh"
- _meshWrapper_SetValue mesh
-
- try (
- local args = dotnet_ValueToDotNetObject #() argsType
- pluginInstance.UpdateMesh (currentTime as integer) _meshWrapper script args
- )
- catch (
- print ( getCurrentException() )
- )
-
- _meshWrapper_SetValue undefined
- )
-
- rollout params "Parameters"
- (
- edittext Script "Script" height:48 labelOnTop:true
- edittext Errors "Errors" height:48 labelOnTop:true
- button Run "Run" width:45 height:20
- on Run pressed do ( updateMesh () )
- )
-
- on buildMesh do
- (
- -- TODO: if you want to automatically build the mesh whenever the parameters are updated call recreateMesh
- ok
- )
-
-)
diff --git a/dotnet/3dsMaxBridge/MAXScript/ScriptTemplate.ms b/dotnet/3dsMaxBridge/MAXScript/ScriptTemplate.ms
deleted file mode 100644
index 159d5a2..0000000
--- a/dotnet/3dsMaxBridge/MAXScript/ScriptTemplate.ms
+++ /dev/null
@@ -1,196 +0,0 @@
--- A scripted geometry plug-in that executes arbitrary C# code.
--- Custom Attributes: https://help.autodesk.com/view/3DSMAX/2017/ENU/?guid=__files_GUID_ADFD29E4_9751_4F55_98CC_F7C721C9AEE2_htm
--- Scripted plug-in clauses: https://help.autodesk.com/view/3DSMAX/2017/ENU/?guid=__files_GUID_461915FA_31A2_49CE_84AF_2544B782ACA3_htm
-
--- There is going to be a bunch of assemblies to load.
--- asm = dotNet.loadAssembly @"C:\dev\repos\AraGeometry\3dsMaxBridge\bin\Debug\3dsMaxBridge.dll"
-
-plugin simpleObject AraScriptedObject
- name:"Ara Object"
- classID:#(0x56880e2a, 0x8323dbe)
- category:"Ara 3D"
- usePBValidity:true
-(
- local pluginDefinitionFile -- the plugin definition file
- local pluginInstance -- the plugin instance created from the plugin definition
- local _meshWrapper -- the dotnet wrapper around our mesh pointer
- local argsType = dotNetClass "System.Object[]" -- used when creating args array
- local dotnet_ValueToDotNetObject = dotnet.ValueToDotNetObject
- local tmHandler
- local owningNode
-
- -- function wrappers
- local _meshWrapper_SetValue
- local pluginInstance_UpdateMesh
-
- -- value wrapper local and function wrapper declarations
-
- local bridgeClass
-
- parameters main rollout:args
- (
- Size ui:Size default:10 type:#float animatable:true
- )
-
- parameters main2 rollout:params
- (
- script ui:Script type:#string default:"Hello world!"
- _dummy type:#boolean invisibleInTV:true -- this exists to enable easy invalidation of the object
- -- pluginGraph type:#filename assettype:#MaxCreationGraph readOnly:true enumAsAsset:true
- -- pluginGraphDependencies type:#filenametab assettype:#MaxCreationGraph readOnly:true enumAsAsset:true tabSize:0 tabSizeVariable:true
- )
-
- fn initialize =
- (
- print "initializing"
-
- -- TODO: I suspect that initialize gets called too often, and that I will have to optimize the creation of plugin instance to avoid
- -- over creating the thing.
-
- -- TODO: this will get removed
- -- pluginDefinitionFile = @"C:\Users\ara3d\Autodesk\3ds Max 2019\Max Creation Graph\Tools\Object_Name.maxtool"
-
- -- This is the class used to communicate with the Ara 3D geometry system
- bridgeClass = dotNetClass "Ara3D.AraGeometryBridge"
-
- -- Create a .NET instance of a reference maker class that corresponds to this plug-in
- -- TODO: this used to be an important argument for an MCG plug-in, but it isn't anymore.
- -- local refMakerWrapperClass = dotnetclass "Autodesk.Max.MaxPlus.ReferenceMaker"
- -- local _pluginOwner = refMakerWrapperClass._CreateWrapper this
-
- -- Create a .NET instance of a "GeometryPluginInstanceBridge" which allows
- pluginInstance = bridgeClass.CreatePluginInstance ()
- local meshWrapperClass = dotnetclass "Autodesk.Max.MaxPlus.Mesh"
-
- -- Create a .NET instance of a Autodesk.Max.MaxPlus.Mesh so that meshes can be easily passed to the plug-in instance
- _meshWrapper = meshWrapperClass._CreateWrapper undefined
- _meshWrapper_SetValue = _meshWrapper._SetValue
-
- -- TODO: this will get removed
- pluginGraph = pluginDefinitionFile
- pluginGraphDependencies = #()
-
- -- value wrapper local initializations
- )
-
- on create do
- (
- initialize()
- )
-
- on clone fromObj do
- (
- initialize()
- )
-
- on load do
- (
- initialize()
- )
-
- on update do
- (
- initialize()
- )
-
- fn installTMHandler theNode =
- (
- -- Force updating the plug-in when the transform is updated on the owning node
-
- -- TODO: this should only happen if one of the arguments is a scene node, otherwise it should no impact on the mesh. SO.... I am commenting it out for now
- -- owningNode = theNode
- -- if (tmHandler == undefined and owningNode != undefined) then ( tmHandler = when transform owningNode changes do ( _dummy = not _dummy ))
- )
-
- on postload do
- (
- installTMHandler(refs.dependentnodes this firstonly:true)
- )
-
- on attachedToNode theNode do
- (
- installTMHandler(theNode)
- )
-
- tool create
- (
- on mousePoint click do
- (
- case click of
- (
- 1: nodeTM.translation = gridPoint
- 2: #stop
- )
- )
- )
-
- rollout args "Arguments"
- (
- spinner Size "Size" range:[0, 100, 10] type:#float
- )
-
- rollout params "Parameters"
- (
- edittext Script "Script" height:48 labelOnTop:true
- edittext Errors "Errors" height:48 labelOnTop:true
- )
-
- -- TODO: remove this
- /*
- rollout MCG_Editor "MCG Editor"(
- button MCG_Editor_btn "Open in MCG Editor"
- on MCG_Editor_btn pressed do
- (
- if (doesFileExist pluginDefinitionFile) then
- (
- geBridge = dotNetClass "ProceduralContentActions.PCGraphEditorBridge"
- geBridge.LoadGraph pluginDefinitionFile
- )
- else (
- local msgStream = stringstream ""
- format "File '%' is missing.\n" pluginDefinitionFile to:msgStream
- local msgStr = msgStream as string
- if GetQuietMode() then
- format msgStr
- else
- MessageBox msgStr title: "Missing maxtool file" beep:false
- )
- )
- )
- */
-
- fn transformGetter =
- (
- if(isValidNode(owningNode)) then owningNode.Transform else matrix3 1
- )
-
- fn updateMesh =
- (
- if (pluginInstance == undefined) then ( return undefined )
- local args = dotnet_ValueToDotNetObject #(Size) argsType
- pluginInstance.UpdateMesh (currentTime as integer) _meshWrapper script args
- ok
- )
-
- on buildMesh do
- (
- print "building mesh"
- -- if (PreInvokeMethod != undefined ) then PreInvokeMethod()
- _meshWrapper_SetValue mesh
-
- -- TODO: I'm not sure that catching all exceptions is the right thing to do.
- try (
- result = updateMesh ()
- if (result == undefined) then ( print "Undefined result from updateMesh" )
- )
- catch (
- print ( getCurrentException() )
- )
-
- _meshWrapper_SetValue undefined
-
- -- if (PostInvokeMethod != undefined ) then PostInvokeMethod()
- ok
- )
-
-)
diff --git a/dotnet/3dsMaxBridge/MAXScript/TestCompiler.ms b/dotnet/3dsMaxBridge/MAXScript/TestCompiler.ms
deleted file mode 100644
index 76f1966..0000000
--- a/dotnet/3dsMaxBridge/MAXScript/TestCompiler.ms
+++ /dev/null
@@ -1,25 +0,0 @@
-asm = dotNet.loadAssembly @"C:\dev\repos\AraGeometry\3dsMaxBridge\bin\Debug\3dsMaxBridge.dll"
-ara = dotNetClass "Ara3D.Ara"
--- g = ara.MergeAllGeometry ()
-host = dotNetObject "Ara3D.GeometryPluginHost"
-host.Compile "namespace Ara3D
-{
- public class SamplePlugin : IGeometryPlugin
- {
- public IGeometry Evaluate(IGeometryPluginHost host)
- {
- // TODO: this is where the magic happens
- //return QuadMesh.Empty;
- var mesh = TriMesh.Empty;
- //var node = Ara.ToNode(mesh);
- Ara.MergeAllGeometry().ToNode();
- return mesh;
- }
- }
-}"
-if host.plugin == undefined then (
- print "Errors = " + host.ErrorText
-)
-else (
- host.plugin.Evaluate undefined
-)
\ No newline at end of file
diff --git a/dotnet/3dsMaxBridge/MAXScript/TestCompiler2.ms b/dotnet/3dsMaxBridge/MAXScript/TestCompiler2.ms
deleted file mode 100644
index b265244..0000000
--- a/dotnet/3dsMaxBridge/MAXScript/TestCompiler2.ms
+++ /dev/null
@@ -1,31 +0,0 @@
--- Box pos:[-33.1377,42.8053,0] isSelected:on width:13.642 length:32.2585 height:16.0751
--- Cone radius1:14.5439 radius2:5.62667 height:17.174 pos:[62.4749,-36.1697,0] isSelected:on
-
-asm = dotNet.loadAssembly @"C:\dev\repos\AraGeometry\3dsMaxBridge\bin\Debug\3dsMaxBridge.dll"
-ara = dotNetClass "Ara3D.Ara"
--- g = ara.MergeAllGeometry ()
-host = dotNetObject "Ara3D.GeometryPluginHost"
-host.Compile "using Autodesk.Max.MaxPlus;
-
-namespace Ara3D
-{
- public class SamplePlugin : IGeometryPlugin
- {
- public IGeometry Evaluate(IGeometryPluginHost host)
- {
- // TODO: this is where the magic happens
- //var node = Ara.GetFirstSelectedNode();
- //Core.WriteLine(Ara.GetNodeInfo(node));
- //node.GetTransformedGeometry().ToNode();
- Ara.MergeAllGeometry().ToNode();
- return null;
- }
-
- }
-}"
-if host.plugin == undefined then (
- print "Errors = " + host.ErrorText
-)
-else (
- host.plugin.Evaluate undefined
-)
\ No newline at end of file
diff --git a/dotnet/3dsMaxBridge/MAXScript/TestCustAttr.ms b/dotnet/3dsMaxBridge/MAXScript/TestCustAttr.ms
deleted file mode 100644
index 5eb21e4..0000000
--- a/dotnet/3dsMaxBridge/MAXScript/TestCustAttr.ms
+++ /dev/null
@@ -1,20 +0,0 @@
-weaponDataCA= attributes weaponData
-(
-parameters main rollout:params
-(
-hitPoints type:#float ui:hits default:10
-cost type:#float ui:cost default:100
-sound type:#string default:"boom"
-on Cost set val do ( print "cost changed" )
-)
-
-
-rollout params "Weapon Parameters"
-(
-spinner hits "Hit Points" type: #float
-spinner cost "Cost" type: #float
-dropdownlist sound_dd "Sound" items:# ("boom","sparkle","zap","fizzle")
-
-on sound_dd selected i do sound = sound_dd.items [i]
-)
-)
\ No newline at end of file
diff --git a/dotnet/3dsMaxBridge/MAXScript/WIP_ScriptTemplate.ms b/dotnet/3dsMaxBridge/MAXScript/WIP_ScriptTemplate.ms
deleted file mode 100644
index 5a01192..0000000
--- a/dotnet/3dsMaxBridge/MAXScript/WIP_ScriptTemplate.ms
+++ /dev/null
@@ -1,198 +0,0 @@
--- TODO: This is a WIP, and not currently supported.
-
--- A scripted geometry plug-in that executes arbitrary C# code.
--- Custom Attributes: https://help.autodesk.com/view/3DSMAX/2017/ENU/?guid=__files_GUID_ADFD29E4_9751_4F55_98CC_F7C721C9AEE2_htm
--- Scripted plug-in clauses: https://help.autodesk.com/view/3DSMAX/2017/ENU/?guid=__files_GUID_461915FA_31A2_49CE_84AF_2544B782ACA3_htm
-
--- There is going to be a bunch of assemblies to load.
--- asm = dotNet.loadAssembly @"%programdata%\Ara3D\3dsMaxBridge\3dsMaxBridge.dll"
-
-plugin simpleObject AraScriptedObject
- name:"Ara Object"
- classID:#(0x56880e2a, 0x8323dbe)
- category:"Ara 3D"
- usePBValidity:true
-(
- local pluginDefinitionFile -- the plugin definition file
- local pluginInstance -- the plugin instance created from the plugin definition
- local _meshWrapper -- the dotnet wrapper around our mesh pointer
- local argsType = dotNetClass "System.Object[]" -- used when creating args array
- local dotnet_ValueToDotNetObject = dotnet.ValueToDotNetObject
- local tmHandler
- local owningNode
-
- -- function wrappers
- local _meshWrapper_SetValue
- local pluginInstance_UpdateMesh
-
- -- value wrapper local and function wrapper declarations
-
- local bridgeClass
-
- parameters main rollout:args
- (
- Size ui:Size default:10 type:#float animatable:true
- )
-
- parameters main2 rollout:params
- (
- script ui:Script type:#string default:"Hello world!"
- _dummy type:#boolean invisibleInTV:true -- this exists to enable easy invalidation of the object
- -- pluginGraph type:#filename assettype:#MaxCreationGraph readOnly:true enumAsAsset:true
- -- pluginGraphDependencies type:#filenametab assettype:#MaxCreationGraph readOnly:true enumAsAsset:true tabSize:0 tabSizeVariable:true
- )
-
- fn initialize =
- (
- print "initializing"
-
- -- TODO: I suspect that initialize gets called too often, and that I will have to optimize the creation of plugin instance to avoid
- -- over creating the thing.
-
- -- TODO: this will get removed
- -- pluginDefinitionFile = @"C:\Users\ara3d\Autodesk\3ds Max 2019\Max Creation Graph\Tools\Object_Name.maxtool"
-
- -- This is the class used to communicate with the Ara 3D geometry system
- bridgeClass = dotNetClass "Ara3D.AraGeometryBridge"
-
- -- Create a .NET instance of a reference maker class that corresponds to this plug-in
- -- TODO: this used to be an important argument for an MCG plug-in, but it isn't anymore.
- -- local refMakerWrapperClass = dotnetclass "Autodesk.Max.MaxPlus.ReferenceMaker"
- -- local _pluginOwner = refMakerWrapperClass._CreateWrapper this
-
- -- Create a .NET instance of a "GeometryPluginInstanceBridge" which allows
- pluginInstance = bridgeClass.CreatePluginInstance ()
- local meshWrapperClass = dotnetclass "Autodesk.Max.MaxPlus.Mesh"
-
- -- Create a .NET instance of a Autodesk.Max.MaxPlus.Mesh so that meshes can be easily passed to the plug-in instance
- _meshWrapper = meshWrapperClass._CreateWrapper undefined
- _meshWrapper_SetValue = _meshWrapper._SetValue
-
- -- TODO: this will get removed
- pluginGraph = pluginDefinitionFile
- pluginGraphDependencies = #()
-
- -- value wrapper local initializations
- )
-
- on create do
- (
- initialize()
- )
-
- on clone fromObj do
- (
- initialize()
- )
-
- on load do
- (
- initialize()
- )
-
- on update do
- (
- initialize()
- )
-
- fn installTMHandler theNode =
- (
- -- Force updating the plug-in when the transform is updated on the owning node
-
- -- TODO: this should only happen if one of the arguments is a scene node, otherwise it should no impact on the mesh. SO.... I am commenting it out for now
- -- owningNode = theNode
- -- if (tmHandler == undefined and owningNode != undefined) then ( tmHandler = when transform owningNode changes do ( _dummy = not _dummy ))
- )
-
- on postload do
- (
- installTMHandler(refs.dependentnodes this firstonly:true)
- )
-
- on attachedToNode theNode do
- (
- installTMHandler(theNode)
- )
-
- tool create
- (
- on mousePoint click do
- (
- case click of
- (
- 1: nodeTM.translation = gridPoint
- 2: #stop
- )
- )
- )
-
- rollout args "Arguments"
- (
- spinner Size "Size" range:[0, 100, 10] type:#float
- )
-
- rollout params "Parameters"
- (
- edittext Script "Script" height:48 labelOnTop:true
- edittext Errors "Errors" height:48 labelOnTop:true
- )
-
- -- TODO: remove this
- /*
- rollout MCG_Editor "MCG Editor"(
- button MCG_Editor_btn "Open in MCG Editor"
- on MCG_Editor_btn pressed do
- (
- if (doesFileExist pluginDefinitionFile) then
- (
- geBridge = dotNetClass "ProceduralContentActions.PCGraphEditorBridge"
- geBridge.LoadGraph pluginDefinitionFile
- )
- else (
- local msgStream = stringstream ""
- format "File '%' is missing.\n" pluginDefinitionFile to:msgStream
- local msgStr = msgStream as string
- if GetQuietMode() then
- format msgStr
- else
- MessageBox msgStr title: "Missing maxtool file" beep:false
- )
- )
- )
- */
-
- fn transformGetter =
- (
- if(isValidNode(owningNode)) then owningNode.Transform else matrix3 1
- )
-
- fn updateMesh =
- (
- if (pluginInstance == undefined) then ( return undefined )
- local args = dotnet_ValueToDotNetObject #(Size) argsType
- pluginInstance.UpdateMesh (currentTime as integer) _meshWrapper script args
- ok
- )
-
- on buildMesh do
- (
- print "building mesh"
- -- if (PreInvokeMethod != undefined ) then PreInvokeMethod()
- _meshWrapper_SetValue mesh
-
- -- TODO: I'm not sure that catching all exceptions is the right thing to do.
- try (
- result = updateMesh ()
- if (result == undefined) then ( print "Undefined result from updateMesh" )
- )
- catch (
- print ( getCurrentException() )
- )
-
- _meshWrapper_SetValue undefined
-
- -- if (PostInvokeMethod != undefined ) then PostInvokeMethod()
- ok
- )
-
-)
diff --git a/dotnet/3dsMaxBridge/PluginHost.cs b/dotnet/3dsMaxBridge/PluginHost.cs
deleted file mode 100644
index 69cb41f..0000000
--- a/dotnet/3dsMaxBridge/PluginHost.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-
-using System.Collections.Generic;
-using System.IO;
-using System.Reflection;
-using System.Linq;
-
-namespace Ara3D
-{
- public class PluginHost where InterfaceType : class
- {
- public Assembly Assembly { get; set; }
- public InterfaceType Plugin { get; set; }
- public List Errors { get; } = new List();
- public string ErrorText => string.Join("\n", Errors);
- public bool CompiledSuccessfully => Plugin != null;
-
- public void Compile(string scriptFile)
- {
- Plugin = null;
-
- if (!File.Exists(scriptFile))
- throw new System.Exception("File does not exist");
-
- // TODO: rename my DLLs to start with "Ara3D"
- var asmShortNames = new[] {
- "System.Numerics.dll",
- "Ara3D.3dsMaxBridge.dll",
- "Ara3D.Geometry.dll",
- "Ara3D.LinqArray.dll",
- "Ara3D.Math.dll",
- "Ara3D.DotNetUtilities.dll",
- "Ara3D.G3SharpBridge.dll",
- "vib3.dll",
- "VimTools.exe",
- "geometry3Sharp.dll",
- "Newtonsoft.Json.dll",
- };
-
- // TODO: maybe iterate over all assemblies in the output folder?
-
- var asmMaxShortNames = new[] {
- "Autodesk.Max.dll",
- "Geometry3D.dll",
- "CSharpUtilities.dll",
- "ImmutableArray.dll",
- "BulletSharp.dll",
- "ManagedOpenVDB.dll",
- "ManagedServices.dll",
- "MaxPlusDotNet.dll",
- "Autodesk.Max.dll",
- "MaxPlusDotNet.dll",
- "MonoGame.Framework.dll",
- "RevitAPI.dll",
- "RevitAPIIFC.dll",
- "UiViewModels.dll",
- "Viper3dsMaxBridge.dll",
- "ViperEngine.dll",
- "ViperExtension.dll",
- "ViperGeometry3D.dll",
- };
-
- var systemDlls = new[]
- {
- "System.dll",
- "System.Core.dll",
- "System.Data.dll",
- "System.Data.DataSetExtensions.dll"
- };
-
- var allAsmNames = asmShortNames.Concat(asmMaxShortNames);
- var dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
- var asmNames = allAsmNames.Select((name) => Path.Combine(dir, name)).Concat(systemDlls).ToList();
-
- // Remove duplicates
- asmNames = asmNames.Distinct().ToList();
-
- Assembly = null;
- Errors.Clear();
- Assembly = Compiler.CompileFile(scriptFile, asmNames, Errors, true);
- if (Assembly != null)
- Plugin = Compiler.ActivateClassImplementingInterface(Assembly);
- }
- }
-}
diff --git a/dotnet/3dsMaxBridge/Plugins.cs b/dotnet/3dsMaxBridge/Plugins.cs
deleted file mode 100644
index 1663ca7..0000000
--- a/dotnet/3dsMaxBridge/Plugins.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- Ara 3D Geometry Plugin
- Copyright 2018, Ara 3D, Inc.
- Usage licensed under terms of MIT Licenese
-*/
-namespace Ara3D
-{
- public interface IPluginDescriptor
- {
- string Name { get; }
- string Author { get; }
- string Url { get; }
- string Tooltip { get; }
- string Description { get; }
- int MajorVersion { get; }
- int MinorVersion { get; }
- int BuildVersion { get; }
- IParameterDescriptor[] Parameters { get; }
- }
-
- public interface IParameterDescriptor
- {
- IPluginDescriptor Descriptor { get; }
- string Label { get; }
- string Tooltip { get; }
- string Guid { get; }
- string Name { get; }
- string Description{ get; }
- int Index { get; }
- string Help { get; }
- object Default { get; }
- }
-
- public interface IGeometryPlugin
- {
- IGeometry Evaluate(IGeometryPluginHost host);
- }
-
- public interface IParameter
- {
- object Value { get; }
- IParameterDescriptor Descriptor { get; }
- }
-
- public interface IGeometryPluginHost
- {
- object[] Args { get; }
- int Time { get; }
- int LastTime { get; }
- IGeometry LastValue { get; }
- }
-
- public interface IUtilityPlugin
- {
- void Evaluate();
- }
-}
diff --git a/dotnet/3dsMaxBridge/Properties/AssemblyInfo.cs b/dotnet/3dsMaxBridge/Properties/AssemblyInfo.cs
deleted file mode 100644
index 471c659..0000000
--- a/dotnet/3dsMaxBridge/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("3dsMaxBridge")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("3dsMaxBridge")]
-[assembly: AssemblyCopyright("Copyright © 2018")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("64860ec8-b0eb-44bb-b5bb-039200ada53e")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/dotnet/3dsMaxBridge/UtilityPluginScript.cs b/dotnet/3dsMaxBridge/UtilityPluginScript.cs
deleted file mode 100644
index da79e28..0000000
--- a/dotnet/3dsMaxBridge/UtilityPluginScript.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-
-using System.Collections.Generic;
-
-namespace Ara3D
-{
- public class UtilityPluginScript
- {
- PluginHost Host = new PluginHost();
- public string FileName { get; }
- public UtilityPluginScript(string fileName)
- {
- FileName = fileName;
- }
- public IList Compile()
- {
- Host.Compile(FileName);
- return Host.Errors;
- }
- public bool Run()
- {
- if (!Host.CompiledSuccessfully)
- return false;
- Host.Plugin.Evaluate();
- return true;
- }
- }
-}
diff --git a/dotnet/3dsMaxBridge/app.config b/dotnet/3dsMaxBridge/app.config
deleted file mode 100644
index b90af84..0000000
--- a/dotnet/3dsMaxBridge/app.config
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/dotnet/3dsMaxBridge/readme.md b/dotnet/3dsMaxBridge/readme.md
deleted file mode 100644
index e3a33c1..0000000
--- a/dotnet/3dsMaxBridge/readme.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# AraGeometry.3dsMaxBridge
-
-This is a set of tools for bridging between 3ds Max and the various Ara3D libraries.
-It is used by the Ara Script editor.
-
-The output path of this project is `%programdata%\Ara3D\3dsMaxBridge` so that it is
-accessible to all users and easily accessed from scripts.
-
-Setting an output location with environment variables has to be done in the project file
-manually.
-
-There is some sample code for loading the 3ds Max bridge in Ara3D_Startup.ms. This file
-has to be executed at the
-
diff --git a/dotnet/3dsMaxSamples/Ara3D.3dsMaxSamples.csproj b/dotnet/3dsMaxSamples/Ara3D.3dsMaxSamples.csproj
deleted file mode 100644
index 1f14f02..0000000
--- a/dotnet/3dsMaxSamples/Ara3D.3dsMaxSamples.csproj
+++ /dev/null
@@ -1,100 +0,0 @@
-
-
-
-
-
- Debug
- AnyCPU
- {BCF10249-713C-46AD-97EF-BA62A123FBD7}
- Library
- Properties
- Ara3D._3dsMaxSamples
- Ara3D.3dsMaxSamples
- v4.7.1
- 512
- true
-
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- x64
- true
- 7.3
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- 7.3
-
-
-
-
-
- true
-
-
-
- $(ADSK_3DSMAX_x64_2019)\MaxPlusDotNet.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {64860ec8-b0eb-44bb-b5bb-039200ada53e}
- Ara3D.3dsMaxBridge
-
-
- {e89008fa-6d3f-48de-900a-be5a9d79f4ae}
- Ara3D.Geometry
-
-
- {4007804a-598f-495f-84f3-f2cf3136797d}
- Ara3D.G3D
-
-
- {81718218-f3e7-4d54-8552-2a65fbebee85}
- Ara3D.LinqArray
-
-
- {f9430261-9426-4d6b-a1b8-9d3f2bfbb501}
- Ara3D.Math
-
-
- {25330241-4c82-4c17-8027-ff882b91640e}
- Ara3D.DotNetUtilities
-
-
-
-
-
-
-
- mkdir "%25userprofile%25\Ara3D\Scripts\CSharp"
-copy $(ProjectDir)\*.cs "%25userprofile%25\Ara3D\Scripts\CSharp"
-
-
-
\ No newline at end of file
diff --git a/dotnet/3dsMaxSamples/Properties/AssemblyInfo.cs b/dotnet/3dsMaxSamples/Properties/AssemblyInfo.cs
deleted file mode 100644
index 38879a4..0000000
--- a/dotnet/3dsMaxSamples/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("3dsMaxSamples")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("3dsMaxSamples")]
-[assembly: AssemblyCopyright("Copyright © 2018")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("bcf10249-713c-46ad-97ef-ba62a123fbd7")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/dotnet/3dsMaxSamples/UtilityHelloWorld.cs b/dotnet/3dsMaxSamples/UtilityHelloWorld.cs
deleted file mode 100644
index cbaaef9..0000000
--- a/dotnet/3dsMaxSamples/UtilityHelloWorld.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-
-using Autodesk.Max.MaxPlus;
-
-namespace Ara3D
-{
- public class UtilityLayerPlugin : IUtilityPlugin
- {
- public void Evaluate()
- {
- var obj = Factory.CreateDummyObject();
- var node = Factory.CreateNode(obj, "My node");
- var layer = LayerManager.CreateLayer();
- layer.AddToLayer(node);
- }
- }
-}
diff --git a/dotnet/3dsMaxSamples/UtilityLoadInstances.cs b/dotnet/3dsMaxSamples/UtilityLoadInstances.cs
deleted file mode 100644
index c4ffe8f..0000000
--- a/dotnet/3dsMaxSamples/UtilityLoadInstances.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Ara3D
-{
- public class UtilityLoadInstances : IUtilityPlugin
- {
- public void Evaluate()
- {
- API.LoadBFastScene(@"C:\Users\ara3d\AppData\Local\Ara3D\RevitDevPlugin\2019-03-05_01-24-32-main\output.vim");
- }
- }
-}
\ No newline at end of file
diff --git a/dotnet/3dsMaxSamples/UtilityMergeAllGeometry.cs b/dotnet/3dsMaxSamples/UtilityMergeAllGeometry.cs
deleted file mode 100644
index b898357..0000000
--- a/dotnet/3dsMaxSamples/UtilityMergeAllGeometry.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Ara3D
-{
- public class UtilityMergeAllGeometry : IUtilityPlugin
- {
- public void Evaluate()
- {
- API.AllGeometry.ToNode();
- }
- }
-}
\ No newline at end of file
diff --git a/dotnet/3dsMaxSamples/UtilitySplitGeometry.cs b/dotnet/3dsMaxSamples/UtilitySplitGeometry.cs
deleted file mode 100644
index 4aabf5e..0000000
--- a/dotnet/3dsMaxSamples/UtilitySplitGeometry.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using Autodesk.Max.MaxPlus;
-using System;
-
-namespace Ara3D
-{
- public class UtilitySplitGeometry : IUtilityPlugin
- {
- public void Evaluate()
- {
- if (SelectionManager.GetCount() == 0)
- throw new Exception("One node must be selected");
- if (SelectionManager.GetCount() > 1)
- throw new Exception("Only one node must be selected");
- var g = SelectionManager.GetNode(0).ToIGeometry();
-
- // Create nodes from the even and the odd
- //g.CopyFaces(MathOps.Even).ToNode();
- //g.CopyFaces(MathOps.Odd).ToNode();
-
- // Create a new mesh and node for every 50 faces
- var grps = g.CopyFaceGroups(50);
- foreach (var grp in grps.ToEnumerable())
- grp.ToNode();
- }
- }
-}
\ No newline at end of file
diff --git a/dotnet/3dsMaxSamples/UtilitySurfaceArea.cs b/dotnet/3dsMaxSamples/UtilitySurfaceArea.cs
deleted file mode 100644
index 9b4befd..0000000
--- a/dotnet/3dsMaxSamples/UtilitySurfaceArea.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Autodesk.Max.MaxPlus;
-using System.Linq;
-
-namespace Ara3D
-{
- public class UtilitySurfaceArea : IUtilityPlugin
- {
- public void Evaluate()
- {
- var tris = API.AllGeometryOrJustSelected.Triangles();
- var areas = tris.ToEnumerable().Select(t => t.Area);
- var report = areas.StatisticsSummaryReport();
- Core.WriteLine("Triangle areas: " + report);
- }
- }
-}
diff --git a/dotnet/3dsMaxSamples/app.config b/dotnet/3dsMaxSamples/app.config
deleted file mode 100644
index b90af84..0000000
--- a/dotnet/3dsMaxSamples/app.config
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/dotnet/AraGeometry/G3DBridge.cs b/dotnet/AraGeometry/G3DBridge.cs
index 8a89e73..0a12387 100644
--- a/dotnet/AraGeometry/G3DBridge.cs
+++ b/dotnet/AraGeometry/G3DBridge.cs
@@ -22,20 +22,22 @@ public G3DAdapter(IG3D g3D)
Indices = g3D.CornerVertexIndices();
NumFaces = g3D.FaceCount();
FaceIndices = g3D.FaceIndices();
+ MaterialIds = g3D.MaterialIds();
}
public int NumFaces { get; }
public int PointsPerFace { get; }
public IArray Vertices { get; }
public IArray Indices { get; }
-
public IArray FaceSizes { get; }
public IArray FaceIndices { get; }
+ public IArray MaterialIds { get; }
public IAttribute VertexAttribute => G3D.VertexAttribute;
public IAttribute IndexAttribute => G3D.IndexAttribute;
public IAttribute FaceSizeAttribute => G3D.FaceSizeAttribute;
public IAttribute FaceIndexAttribute => G3D.FaceIndexAttribute;
+ public IAttribute MaterialIdAttribute => G3D.MaterialIdAttribute;
public IEnumerable Attributes => G3D.Attributes;
}
}
diff --git a/dotnet/AraGeometry/Geometry.cs b/dotnet/AraGeometry/Geometry.cs
index 393bac0..387ce23 100644
--- a/dotnet/AraGeometry/Geometry.cs
+++ b/dotnet/AraGeometry/Geometry.cs
@@ -213,14 +213,14 @@ public static bool Coplanar(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, floa
public static Vector3 Normal(this Face self)
=> Vector3.Normalize(Vector3.Cross(self.Binormal(), self.Tangent()));
- public static IGeometry Mesh(int sidesPerFace, IArray vertices, IArray indices = null)
- => G3DExtensions.ToG3D(sidesPerFace, vertices, indices).ToIGeometry();
+ public static IGeometry Mesh(int sidesPerFace, IArray vertices, IArray indices = null, IArray uvs = null, IArray materialIds = null)
+ => G3DExtensions.ToG3D(sidesPerFace, vertices, indices, uvs, materialIds).ToIGeometry();
- public static IGeometry QuadMesh(this IArray vertices, IArray indices = null)
- => Mesh(4, vertices, indices);
+ public static IGeometry QuadMesh(this IArray vertices, IArray indices = null, IArray uvs = null, IArray materialIds = null)
+ => Mesh(4, vertices, indices, uvs, materialIds);
- public static IGeometry TriMesh(this IArray vertices, IArray indices = null)
- => Mesh(3, vertices, indices);
+ public static IGeometry TriMesh(this IArray vertices, IArray indices = null, IArray uvs = null, IArray materialIds = null)
+ => Mesh(3, vertices, indices, uvs, materialIds);
/* TODO: finish
public static IGeometry PolyMesh(this IArray vertices, IArray faces)
@@ -384,6 +384,7 @@ public static IGeometry ToTriMesh(this IGeometry self)
public static IGeometry Merge(this IEnumerable geometries)
=> geometries.ToIArray().Merge();
+ // TODO: optimize this function
public static IGeometry Merge(this IArray geometries)
{
var triMeshes = geometries.Select(g => g.ToTriMesh());
diff --git a/dotnet/AraGeometry/GeometryReader.cs b/dotnet/AraGeometry/GeometryReader.cs
index 0138964..c13c5fd 100644
--- a/dotnet/AraGeometry/GeometryReader.cs
+++ b/dotnet/AraGeometry/GeometryReader.cs
@@ -11,13 +11,23 @@ public static class GeometryReader
public static IGeometry ReadG3D(string filePath)
=> G3DExtensions.ReadFromFile(filePath).ToIGeometry();
+ public static List LoadGeometriesFromBFast(string filePath)
+ => BFastExtensions.ReadBFast(filePath).LoadGeometries();
+
+ public static List LoadGeometries(this BFast bfast)
+ => bfast.Buffers
+ .AsParallel().AsOrdered()
+ .Select(b => G3D.Create(b).ToIGeometry())
+ .ToList();
+
+ /*
public static IList ReadManifest(string filePath)
=> Util.LoadJsonArray(filePath).ToObject>();
public static IArray ManifestNodesToSceneNodes(this IList manifest)
=> manifest.Select(
node => new SceneNode(node.ElementId.ToString(), node.GeometryId, node.Transform.ToMatrix(),
- node.ElementId, node.MaterialId, node.CategoryId) as ISceneNode).ToIArray();
+ node.ElementId, node.MaterialId) as ISceneNode).ToIArray();
///
/// Loads a scene from a folder containing G3D files and a manifest.
@@ -74,5 +84,12 @@ public static IScene ReadSceneFromBFast(string filePath)
// Creates a scene API
return new Scene(geometries.ToIArray(), manifest.ManifestNodesToSceneNodes());
}
+ */
+
+ public static IScene ReadScene(string folder)
+ => throw new NotImplementedException("See commented out code");
+
+ public static IScene ReadSceneFromBFast(string filePath)
+ => throw new NotImplementedException("See commented out code");
}
}
diff --git a/dotnet/AraGeometry/Scene.cs b/dotnet/AraGeometry/Scene.cs
index 0173502..8f0083a 100644
--- a/dotnet/AraGeometry/Scene.cs
+++ b/dotnet/AraGeometry/Scene.cs
@@ -1,15 +1,13 @@
-using System;
+ using System;
using System.Numerics;
namespace Ara3D
{
public interface ISceneNode
{
+ string Name { get; }
Matrix4x4 Transform { get; }
int GeometryId { get; }
- int ElementId { get; }
- int MaterialId { get; }
- int CategoryId { get; }
}
public interface ISceneObject
@@ -26,22 +24,16 @@ public interface IScene
public class SceneNode : ISceneNode
{
- public SceneNode(string name, int geometryId, Matrix4x4 transform, int elementId, int materialId, int categoryId)
+ public SceneNode(string name, int geometryId, Matrix4x4 transform)
{
Name = name;
GeometryId = geometryId;
Transform = transform;
- ElementId = elementId;
- MaterialId = materialId;
- CategoryId = categoryId;
}
- public int GeometryId { get; }
public string Name { get; }
+ public int GeometryId { get; }
public Matrix4x4 Transform { get; }
- public int MaterialId { get; set; }
- public int CategoryId { get; set; }
- public int ElementId { get; set; }
}
public class Scene : IScene
@@ -66,16 +58,6 @@ public SceneObject(IScene scene, ISceneNode node)
public ISceneNode Node { get; }
}
- // TODO: throw this out eventually, only exists for simplification of JSON serialization.
- public class ManifestSceneNode
- {
- public float[] Transform { get; set; }
- public int ElementId { get; set; }
- public int GeometryId { get; set; }
- public int MaterialId { get; set; }
- public int CategoryId { get; set; }
- }
-
public static class SceneExtensions
{
public static IGeometry Geometry(this ISceneObject obj)
diff --git a/dotnet/BFast/BFast.cs b/dotnet/BFast/BFast.cs
index 1b57c9e..9e8671c 100644
--- a/dotnet/BFast/BFast.cs
+++ b/dotnet/BFast/BFast.cs
@@ -236,7 +236,7 @@ public static IEnumerable GetBuffers(this IBFast bf)
yield return bf.GetBuffer(i);
}
- public static BFast ToBFast(this IEnumerable buffers)
+ public static BFast AsBFast(this IEnumerable buffers)
=> new BFast(buffers.Select(b => b.Pin() as IBytes).ToList());
public static void WritePadding(BinaryWriter bw)
@@ -282,9 +282,14 @@ public static byte[] ToBytes(this IBFast bf)
}
}
+ public static BFast AsBFast(this byte[] bytes)
+ => new BFast(bytes);
+
public static BFast ReadBFast(string file)
- => new BFast(File.ReadAllBytes(file));
-
+ => File.ReadAllBytes(file).AsBFast();
+
+ public static void ReadBFast(Stream stream)
+ => stream.ReadAllBytes().AsBFast();
}
/*
diff --git a/cpp/include/ara3d/bfast/README.md b/dotnet/BFast/README.md
similarity index 100%
rename from cpp/include/ara3d/bfast/README.md
rename to dotnet/BFast/README.md
diff --git a/dotnet/G3D/Ara3D.G3D.csproj b/dotnet/G3D/Ara3D.G3D.csproj
index 3105403..44e85f8 100644
--- a/dotnet/G3D/Ara3D.G3D.csproj
+++ b/dotnet/G3D/Ara3D.G3D.csproj
@@ -79,5 +79,8 @@
4.5.2
+
+
+
\ No newline at end of file
diff --git a/dotnet/G3D/AttributeDescriptor.cs b/dotnet/G3D/AttributeDescriptor.cs
index 4922877..be32465 100644
--- a/dotnet/G3D/AttributeDescriptor.cs
+++ b/dotnet/G3D/AttributeDescriptor.cs
@@ -3,15 +3,17 @@
namespace Ara3D
{
- [StructLayout(LayoutKind.Sequential, Pack = 0, Size = 32)]
+ [StructLayout(LayoutKind.Explicit, Pack = 0, Size = 32)]
public struct AttributeDescriptor
{
- public int _association; // Indicates the part of the geometry that this attribute is associated with
- public int _attribute_type; // n integer values
- public int _attribute_type_index; // each attribute type should have it's own index ( you can have uv0, uv1, etc. )
- public int _data_arity; // how many values associated with each element (e.g. UVs might be 2, geometry might be 3, quaternions 4, matrices 9 or 16)
- public int _data_type; // the type of individual values (e.g. int32, float64)
- public int _pad0, _pad1, _pad2; // ignored, used to bring the alignment up to a power of two.
+ [FieldOffset(0)] public int _association; // Indicates the part of the geometry that this attribute is associated with
+ [FieldOffset(4)] public int _attribute_type; // n integer values
+ [FieldOffset(8)] public int _attribute_type_index; // each attribute type should have it's own index ( you can have uv0, uv1, etc. )
+ [FieldOffset(12)] public int _data_arity; // how many values associated with each element (e.g. UVs might be 2, geometry might be 3, quaternions 4, matrices 9 or 16)
+ [FieldOffset(16)] public int _data_type; // the type of individual values (e.g. int32, float64)
+ [FieldOffset(20)] public int _pad0; // ignored, used to bring the alignment up to a power of two.
+ [FieldOffset(24)] public int _pad1; // ignored, used to bring the alignment up to a power of two.
+ [FieldOffset(28)] public int _pad2; // ignored, used to bring the alignment up to a power of two.
public int ItemSize => DataTypeSize(_data_type) * _data_arity;
diff --git a/dotnet/G3D/G3DExtensions.cs b/dotnet/G3D/G3DExtensions.cs
index 5d6226b..4f9fde6 100644
--- a/dotnet/G3D/G3DExtensions.cs
+++ b/dotnet/G3D/G3DExtensions.cs
@@ -63,10 +63,10 @@ public static IAttribute ToIndexAttribute(this IArray data)
=> data.ToAttribute(Association.assoc_corner, AttributeType.attr_index);
public static IAttribute ToUvAttribute(this Vector2[] data, int index = 0)
- => data.ToAttribute(Association.assoc_corner, AttributeType.attr_uv, index);
+ => data.ToAttribute(Association.assoc_vertex, AttributeType.attr_uv, index);
public static IAttribute ToUvAttribute(this IArray data, int index = 0)
- => data.ToAttribute(Association.assoc_corner, AttributeType.attr_uv, index);
+ => data.ToAttribute(Association.assoc_vertex, AttributeType.attr_uv, index);
public static IAttribute ToUvwAttribute(this Vector3[] data, int index = 0)
=> data.ToAttribute(Association.assoc_vertex, AttributeType.attr_uv, index);
@@ -77,6 +77,9 @@ public static IAttribute ToUvwAttribute(this IArray data, int index = 0
public static IAttribute ToVertexNormalAttribute(this Vector3[] data, int index = 0)
=> data.ToAttribute(Association.assoc_vertex, AttributeType.attr_normal, index);
+ public static IAttribute ToMaterialIdsAttribute(this IArray data, int index = 0)
+ => data.ToAttribute(Association.assoc_face, AttributeType.attr_materialid, index);
+
public static IAttribute ToVertexNormalAttribute(this IArray data, int index = 0)
=> data.ToAttribute(Association.assoc_vertex, AttributeType.attr_normal, index);
@@ -212,11 +215,11 @@ public static IG3D ToG3D(int sidesPerFaces, params IAttribute[] attributes)
public static IG3D ToG3D(params IAttribute[] attributes)
=> attributes.ToG3D();
- public static IG3D ToG3D(int sidesPerFaces, IArray vertices, IArray indices = null)
- => ToG3D(sidesPerFaces, vertices.ToVertexAttribute(), indices?.ToIndexAttribute());
+ public static IG3D ToG3D(int sidesPerFaces, IArray vertices, IArray indices = null, IArray uvs = null, IArray materialIds = null)
+ => ToG3D(sidesPerFaces, vertices.ToVertexAttribute(), indices?.ToIndexAttribute(), uvs?.ToUvAttribute(), materialIds?.ToMaterialIdsAttribute());
- public static IG3D ToG3D(int sidesPerFaces, Vector3[] vertices, int[] indices = null)
- => ToG3D(sidesPerFaces, vertices.ToVertexAttribute(), indices?.ToIndexAttribute());
+ public static IG3D ToG3D(int sidesPerFaces, Vector3[] vertices, int[] indices = null, IArray uvs = null)
+ => ToG3D(sidesPerFaces, vertices.ToVertexAttribute(), indices?.ToIndexAttribute(), uvs?.ToUvAttribute());
public static BFast ToBFast(this IEnumerable attributes)
=> attributes.ToG3D().ToBFast();
@@ -317,6 +320,10 @@ public static int FaceCount(this IG3D g3d)
? g3d.CornerVertexIndices().Count / g3d.FirstFaceSize()
: g3d.FaceSizeAttribute.ToInts().Count;
+ public static IArray MaterialIds(this IG3D g3d)
+ => g3d.MaterialIdAttribute?.ToInts()
+ ?? (-1).Repeat(g3d.FaceCount());
+
public static IArray FaceIndices(this IG3D g3d)
=> g3d.FaceIndexAttribute?.ToInts()
?? (g3d.HasFixedFaceSize()
@@ -482,7 +489,7 @@ public static void Validate(this IG3D g3d)
g3d.Attributes(AttributeType.attr_facesize).ToList()
.ValidateArity(1)
.ValidateDataType(DataType.dt_int32)
- .ValidateAssociation(Association.assoc_face, Association.assoc_corner, Association.assoc_object)
+ .ValidateAssociation(Association.assoc_face, Association.assoc_object)
.ValidateMaxOne();
g3d.Attributes(AttributeType.attr_index).ToList()
diff --git a/dotnet/G3D/G3d.cs b/dotnet/G3D/G3d.cs
index 5e91960..daba983 100644
--- a/dotnet/G3D/G3d.cs
+++ b/dotnet/G3D/G3d.cs
@@ -49,6 +49,11 @@ public interface IG3D
/// indicates that the face-size attribute is present and per-face.
///
IAttribute FaceIndexAttribute { get; }
+
+ ///
+ /// The material id attribute is optional: it returns a material id for each face.
+ ///
+ IAttribute MaterialIdAttribute { get; }
}
///
@@ -67,6 +72,7 @@ public class G3D : IG3D
public IAttribute IndexAttribute { get; }
public IAttribute FaceSizeAttribute { get; }
public IAttribute FaceIndexAttribute { get; }
+ public IAttribute MaterialIdAttribute { get; }
public string Header { get; }
@@ -85,8 +91,10 @@ public G3D(IEnumerable attributes, BFast buffer = null, string heade
IndexAttribute = this.FindAttribute(AttributeType.attr_index, false);
FaceSizeAttribute = this.FindAttribute(AttributeType.attr_facesize, false);
FaceIndexAttribute = this.FindAttribute(AttributeType.attr_faceindex, false);
+ MaterialIdAttribute = this.FindAttribute(AttributeType.attr_materialid, false);
// Check that everything is kosher
+ // TODO: this is a long process, only do it in specific circumstances.
//this.Validate();
}
diff --git a/cpp/include/ara3d/g3d/README.md b/dotnet/G3D/README.md
similarity index 100%
rename from cpp/include/ara3d/g3d/README.md
rename to dotnet/G3D/README.md
diff --git a/dotnet/Math3D/MathOpsPartial.cs b/dotnet/Math3D/MathOpsPartial.cs
index c6d8f35..46d24d4 100644
--- a/dotnet/Math3D/MathOpsPartial.cs
+++ b/dotnet/Math3D/MathOpsPartial.cs
@@ -335,5 +335,12 @@ public static float[] ToFloats(this Matrix4x4 m)
public static Matrix4x4 ToMatrix(this float[] m)
=> new Matrix4x4(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11], m[12], m[13],
m[14], m[15]);
+
+ public static Matrix4x4 Inverse(this Matrix4x4 m)
+ {
+ if (!Matrix4x4.Invert(m, out Matrix4x4 r))
+ throw new Exception("No inversion of matrix available");
+ return r;
+ }
}
}
diff --git a/dotnet/Tests/Ara3D.Tests.csproj b/dotnet/Tests/Ara3D.Tests.csproj
index d470f58..dad657c 100644
--- a/dotnet/Tests/Ara3D.Tests.csproj
+++ b/dotnet/Tests/Ara3D.Tests.csproj
@@ -65,7 +65,6 @@
-
@@ -92,10 +91,6 @@
-
- {64860ec8-b0eb-44bb-b5bb-039200ada53e}
- Ara3D.3dsMaxBridge
-
{e89008fa-6d3f-48de-900a-be5a9d79f4ae}
Ara3D.Geometry
diff --git a/dotnet/Tests/InstancedTests.cs b/dotnet/Tests/InstancedTests.cs
deleted file mode 100644
index addd8b7..0000000
--- a/dotnet/Tests/InstancedTests.cs
+++ /dev/null
@@ -1,146 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using NUnit.Framework;
-
-namespace Ara3D.Tests
-{
- [TestFixture]
- public static class InstancedTests
- {
- public static string InputFolderEnvVariable = "ARA3D_TEST_INPUT_PATH";
- public static string InputFolder = Environment.GetEnvironmentVariable(InputFolderEnvVariable);
- public static string OutputFolder = Path.Combine(Path.GetTempPath(), "ara3d", "test_output");
-
- [SetUp]
- public static void SetUp()
- {
- if (string.IsNullOrEmpty(InputFolder))
- throw new Exception($"Could not find environment variable {InputFolderEnvVariable}.");
- if (!Directory.Exists(InputFolder))
- throw new Exception($"No input folder could be found: {InputFolder}");
- Directory.CreateDirectory(OutputFolder);
- }
-
- [Test, Explicit("Hard coded paths")]
- public static void TestBFastLoading()
- {
- var sw = new Stopwatch();
-
- //var inputFile = @"C:\Users\ara3d\AppData\Local\Ara3D\RevitDevPlugin\2019-03-04_19-47-52\output.vim";
- var inputFile =
- @"C:\Users\ara3d\AppData\Local\Ara3D\RevitDevPlugin\2019-03-04_23-12-13-main\output.vim";
-
- var scene = GeometryReader.ReadSceneFromBFast(inputFile);
- sw.OutputTimeElapsed($"Loaded file {inputFile}");
-
- var d = new DictionaryOfLists();
- foreach (var obj in scene.Objects.ToEnumerable())
- d.Add(obj.Node.GeometryId, obj);
-
- var uninstancedObjects = d.Where(kv => kv.Value.Count == 1).Select(kv => kv.Value[0]).ToList();
- Console.WriteLine($"Total object count = {scene.Objects.Count}");
- Console.WriteLine($"Uninstanced object count = {uninstancedObjects.Count}");
-
- var unreferencedObjectsCount = scene.Geometries.Indices().CountWhere(i => !d.ContainsKey(i));
- Console.WriteLine($"Unreferenced object count = {unreferencedObjectsCount}");
-
- var emptyGeos = scene.Geometries.CountWhere(g => g.NumFaces == 0);
- Console.WriteLine($"Empty geometry count = {emptyGeos}");
- }
-
- [Test]
- public static void TestBFastToObj()
- {
- var inputFile =
- @"C:\Users\ara3d\AppData\Local\Ara3D\RevitDevPlugin\2019-03-05_00-47-15-rac_basic_sample_project\output.vim";
- var scene = GeometryReader.ReadSceneFromBFast(inputFile);
- scene.ToIGeometry().WriteObj(@"C:\Users\ara3d\AppData\Local\Ara3D\RevitDevPlugin\test.obj");
- }
-
- ///
- /// Generates a BFAST from a directory containing G3D files and a manifest.json
- ///
- [Test]
- public static void CreateBFast()
- {
- /*
- var sw = new Stopwatch();
- sw.Start();
-
- var folder = Path.Combine(InputFolder, "revit_g3d_list");
-
- sw.OutputTimeElapsed("Reading JSON manifest");
- var manifestFile = Path.Combine(folder, "manifest.json");
- var manifest = Util.LoadJsonArray(manifestFile);
-
- sw.OutputTimeElapsed("Converting JSON array to nodes");
- var nodes = manifest.ToObject>();
-
- var files = Directory.GetFiles(folder, @"*.g3d");
-
- sw.OutputTimeElapsed($"Loading {files.Length} G3D files");
- var geometries = files.AsParallel().ToDictionary(
- f => int.Parse(Path.GetFileNameWithoutExtension(f)),
- File.ReadAllBytes);
-
- sw.OutputTimeElapsed("Remapping geometry indices in manifest");
- var geometryIndexLookup = new Dictionary();
- var buffers = new List();
-
- var n = 0;
- foreach (var kv in geometries)
- {
- geometryIndexLookup[kv.Key] = n++;
- buffers.Add(kv.Value);
- }
-
- // Remap the indices
- foreach (var node in nodes)
- node. = geometryIndexLookup[node.Geometry];
-
- sw.OutputTimeElapsed("Creating a new manifest");
- var newManifest = nodes.ToJArray().ToString();
- buffers.Insert(0, newManifest.ToBytesUtf8());
-
- sw.OutputTimeElapsed("Generating BFAST buffer");
- var bfast = buffers.ToBFast();
-
- sw.OutputTimeElapsed("Writing the bfast");
- var outputFile = Path.Combine(OutputFolder, "instanced.bfast");
- bfast.WriteToFile(outputFile);
- sw.OutputTimeElapsed($"Finished writing BFast to {outputFile}");
-
- sw.OutputTimeElapsed("Reading BFast and generating OBJ");
- ReadBFastAndGenerateObj(outputFile);
- */
- }
-
- /*
- public static void ReadBFastAndGenerateObj(string filePath)
- {
- // TODO: I don't like ReadBFast on BFastExtensions it is not discoverable
- var bFast = BFastExtensions.ReadBFast(filePath);
- var manifestBuffer = bFast.Buffers[0];
-
- // TODO: converting to a string from a span would be more efficient
- var manifestText = manifestBuffer.ToBytes().ToUtf8();
-
- // TODO: the G3D create here is doing a copy under the hood, which sucks
- var geometries = bFast.Buffers.Skip(1).AsParallel().Select(b => G3D.Create(b).ToIGeometry()).ToList();
-
- // Get the scene nodes from the manifest
- var manifest = JArray.Parse(manifestText).ToObject>();
-
- // Transform all of the geometries and merge them together
- var g = manifest.Select(node => geometries[node.Geometry].Transform(node.Transform.ToMatrix())).Merge();
-
- // Output the merged OBJ
- var outputFile = filePath + ".obj";
- g.WriteObj(outputFile);
- }
- */
- }
-}
diff --git a/dotnet/UnityBridge/UnityConverters.cs b/dotnet/UnityBridge/UnityConverters.cs
index b4da9f1..59a5c8e 100644
--- a/dotnet/UnityBridge/UnityConverters.cs
+++ b/dotnet/UnityBridge/UnityConverters.cs
@@ -10,7 +10,7 @@
namespace UnityBridge
{
// TODO: add an IGeometry wrapper around "Unity"
- public static class UnitYConverters
+ public static class UnityConverters
{
// When translating G3D faces to unity we need
// to reverse the triangle winding.
@@ -20,6 +20,7 @@ public static int PolyFaceToUnity(int index, int faceSize)
var vertIdx = index % faceSize;
return (vertIdx == 0) ? index : (faceIdx * faceSize) + (faceSize - vertIdx);
}
+
// Remaps 1, 2, 3 to 1, 3, 2
public static int TriFaceToUnity(int index)
=> PolyFaceToUnity(index, 3);
@@ -30,13 +31,70 @@ public static int QuadFaceToUnity(int index)
public static Mesh ToUnity(this IGeometry g)
{
var r = new Mesh();
-
+
var indices = g.IndexAttribute.ToInts();
var vertexFloats = g.VertexAttribute.ToFloats();
var unityVertices = vertexFloats.SelectTriplets((x, y, z) => new UnityEngine.Vector3(-x, z, -y));
r.vertices = unityVertices.ToArray();
- r.indexFormat = unityVertices.Count > ushort.MaxValue ? IndexFormat.UInt32 : IndexFormat.UInt16;
+ r.indexFormat = unityVertices.Count > ushort.MaxValue
+ ? IndexFormat.UInt32
+ : IndexFormat.UInt16;
+ switch (g.PointsPerFace)
+ {
+ case 3:
+ {
+ var unityIndices = indices.MapIndices(TriFaceToUnity);
+ r.SetIndices(unityIndices.ToArray(), MeshTopology.Triangles, 0);
+ break;
+ }
+ case 4:
+ {
+ var unityIndices = indices.MapIndices(QuadFaceToUnity);
+ r.SetIndices(unityIndices.ToArray(), MeshTopology.Quads, 0);
+ break;
+ }
+ case 2:
+ r.SetIndices(g.Indices.ToArray(), MeshTopology.Lines, 0);
+ break;
+ case 1:
+ r.SetIndices(g.Indices.ToArray(), MeshTopology.Points, 0);
+ break;
+ default:
+ {
+ var triMesh = g.ToTriMesh();
+ var unityIndices = triMesh.Indices.MapIndices(TriFaceToUnity);
+ r.SetIndices(unityIndices.ToArray(), MeshTopology.Triangles, 0);
+ break;
+ }
+ }
+
+
+ r.RecalculateNormals();
+ return r;
+
+ // TODO: copy colors, normals, uvs1 through 8, tangents, and boneWeights
+ //r.colors = g.VertexColors.Select();
+ //r.normals = g.VertexNormals.Select();
+ // r.uv(8) = g.UV.Select();
+ //r.tangents;
+ //https://docs.unity3d.com/ScriptReference/BoneWeight.html
+ // r.boneWeights
+ //return r;
+ }
+
+ /*
+ public static Mesh ToUnity(this IGeometry g)
+ {
+ var r = new Mesh();
+
+ var indices = g.IndexAttribute.ToInts();
+ var vertexFloats = g.VertexAttribute.ToFloats();
+ var unityVertices = vertexFloats.SelectTriplets((x, y, z) => new UnityEngine.Vector3(-x, z, -y));
+ r.vertices = unityVertices.ToArray();
+ r.indexFormat = unityVertices.Count > ushort.MaxValue
+ ? IndexFormat.UInt32
+ : IndexFormat.UInt16;
switch (g.PointsPerFace)
{
@@ -79,6 +137,7 @@ public static Mesh ToUnity(this IGeometry g)
// r.boneWeights
//return r;
}
+ */
// TODO: support matrices once we have our own math classes
//public static void SetAra3DMatrix(this Transform transform, System.Numerics.Matrix4x4 mat)
@@ -91,24 +150,17 @@ public static void SetAra3DMatrix(this Transform transform, float[] mtx)
// TODO: Mat to quat
}
- // TODO: support matrices once we have our own math classes
public static void SetFromNode(this Transform transform, ISceneNode node)
{
- if (!System.Numerics.Matrix4x4.Decompose(node.Transform,
- out var scale,
- out var rotation,
- out var position)
- )
- {
- return;
- }
-
+ if (!System.Numerics.Matrix4x4.Decompose(node.Transform, out var scl, out var rot, out var pos))
+ throw new Exception("Can't decompose matrix");
+
// Transform space is mirrored on X, and then rotated 90 degrees around X
- transform.position = new UnityEngine.Vector3(-position.X, position.Z, -position.Y);
+ transform.position = new UnityEngine.Vector3(-pos.X, pos.Z, -pos.Y);
// Quat is mirrored the same way, but then negated via W = -W because that's just easier to read
- transform.rotation = new UnityEngine.Quaternion(rotation.X, -rotation.Z, rotation.Y, rotation.W);
- // Note, scale is completely untested
- transform.localScale = new UnityEngine.Vector3(scale.X, scale.Z, scale.Y);
+ transform.rotation = new UnityEngine.Quaternion(rot.X, -rot.Z, rot.Y, rot.W);
+ // TODO: test this, current scale is completely untested
+ transform.localScale = new UnityEngine.Vector3(scl.X, scl.Z, scl.Y);
}
}
}
diff --git a/dotnet/Utilities/DictionaryOfLists.cs b/dotnet/Utilities/DictionaryOfLists.cs
index 4df5d6e..0815dca 100644
--- a/dotnet/Utilities/DictionaryOfLists.cs
+++ b/dotnet/Utilities/DictionaryOfLists.cs
@@ -13,14 +13,9 @@ public void Add(K k, V v)
}
public IEnumerable AllValues
- {
- get
- {
- return Values.SelectMany(xs => xs);
- }
- }
+ => Values.SelectMany(xs => xs);
- public List GetValueOrDefault(K k) {
+ public List GetOrDefault(K k) {
if (!ContainsKey(k))
return new List();
return this[k];
diff --git a/dotnet/Utilities/Logger.cs b/dotnet/Utilities/Logger.cs
index 2dfa7cf..edeb40e 100644
--- a/dotnet/Utilities/Logger.cs
+++ b/dotnet/Utilities/Logger.cs
@@ -62,16 +62,29 @@ public override string ToString()
public class StdLogger : ILogger
{
public List Events = new List();
+ public readonly bool EchoToConsole;
+
+ public StdLogger(bool echoToConsole = false)
+ {
+ EchoToConsole = echoToConsole;
+ }
public ILogger Log(string message = "", LogLevel level = LogLevel.None, int eventId = 0)
{
- Events.Add(new LogEvent
+
+ var e = new LogEvent
{
EventId = eventId,
Index = Events.Count,
Message = message,
When = DateTime.Now
- });
+ };
+ Events.Add(e);
+ if (EchoToConsole)
+ Console.WriteLine(e);
+ #if DEBUG
+ Debug.WriteLine(e);
+ #endif
return this;
}
diff --git a/dotnet/Utilities/Util.cs b/dotnet/Utilities/Util.cs
index 7b40dda..bd34f57 100644
--- a/dotnet/Utilities/Util.cs
+++ b/dotnet/Utilities/Util.cs
@@ -689,9 +689,21 @@ public static MemoryStream ToMemoryStream(this byte[] self)
}
///
- /// Writes raw bytes to the stream by creating a memory stream around it.
+ /// Reads all bytes from a stream
+ /// https://stackoverflow.com/questions/1080442/how-to-convert-an-stream-into-a-byte-in-c
///
- public static void Write(this BinaryWriter self, IBytes bytes)
+ public static byte[] ReadAllBytes(this Stream stream)
+ {
+ using (var memoryStream = new MemoryStream()) {
+ stream.CopyTo(memoryStream);
+ return memoryStream.ToArray();
+ }
+ }
+
+ ///
+ /// Writes raw bytes to the stream by creating a memory stream around it.
+ ///
+ public static void Write(this BinaryWriter self, IBytes bytes)
{
self.Write(bytes.ToBytes());
}
@@ -1049,9 +1061,12 @@ public static string ToJson(this object o)
public static void ToJsonFile(this object o, string filePath)
{
- File.Delete(filePath);
using (var tw = File.CreateText(filePath))
- new JsonSerializer { Formatting = Formatting.Indented }.Serialize(tw, o);
+ new JsonSerializer
+ {
+ Formatting = Formatting.Indented,
+ DefaultValueHandling = DefaultValueHandling.Ignore
+ }.Serialize(tw, o);
}
public static string PrettifyJson(this string s)
@@ -1075,22 +1090,27 @@ public static void TestWrite(string folder)
File.Delete(fileName);
}
- public static JObject LoadJson(string filePath)
- {
- return JObject.Parse(File.ReadAllText(filePath));
- }
+ public static JObject LoadJson(string filePath)
+ => JObject.Parse(File.ReadAllText(filePath));
- public static JArray LoadJsonArray(string filePath)
- {
- return JArray.Parse(File.ReadAllText(filePath));
- }
+ public static JArray LoadJsonArray(string filePath)
+ => JArray.Parse(File.ReadAllText(filePath));
public static T LoadJsonFromFile(string filePath)
{
using (var file = File.OpenText(filePath))
- return (T)(new JsonSerializer()).Deserialize(file, typeof(T));
+ return LoadJsonFromStream(file);
+ }
+
+ public static T LoadJsonFromStream(Stream stream)
+ {
+ using (var reader = new StreamReader(stream))
+ return LoadJsonFromStream(reader);
}
+ public static T LoadJsonFromStream(StreamReader streamReader)
+ => (T)(new JsonSerializer()).Deserialize(streamReader, typeof(T));
+
// File size reporting
static readonly string[] ByteSuffixes = { "B", "KB", "MB", "GB", "TB", "PB", "EB" }; //Longs run out around EB
@@ -1133,9 +1153,15 @@ public static string TotalFileSizeAsString(IEnumerable files, int numPla
///
/// Returns the most recently written to sub-folder
///
- //public static string GetMostRecentSubFolder(string folderPath)
- // => Directory.GetDirectories(folderPath).OrderByDescending(f => new DirectoryInfo(f).LastWriteTime)
- // .FirstOrDefault();
+ public static string GetMostRecentSubFolder(string folderPath)
+ => Directory.GetDirectories(folderPath).OrderByDescending(f => new DirectoryInfo(f).LastWriteTime)
+ .FirstOrDefault();
+
+ ///
+ /// Adds an item to the referenced list, creating it if needed
+ ///
+ public static void AddToList(ref IList xs, T x)
+ => (xs ?? (xs = new List())).Add(x);
}
}