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\StlImport
Help me rollback to packages.config

Packages processed

Top-level dependencies:

Package IdVersion
QuantumConcepts.Common + v1.0.0.1
QuantumConcepts.Formats.STL + v1.1.0

Transitive dependencies:

Package IdVersion
+ 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); } }