diff --git a/build.sh b/build.sh index c84cc842..72c3b6e6 100755 --- a/build.sh +++ b/build.sh @@ -2,4 +2,4 @@ dotnet tool restore dotnet paket restore -dotnet build src/Aardvark.NonWindows.slnf \ No newline at end of file +dotnet build src/Aardvark.sln \ No newline at end of file diff --git a/src/Aardvark.Data.Vrml97/Aardvark.Data.Vrml97.csproj b/src/Aardvark.Data.Vrml97/Aardvark.Data.Vrml97.csproj deleted file mode 100644 index ac80d23e..00000000 --- a/src/Aardvark.Data.Vrml97/Aardvark.Data.Vrml97.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - netstandard2.0 - Aardvark.Data - true - 9.0 - 1701;1702;1705;1591 - - - ..\..\bin\Debug - - - ..\..\bin\Release - - - - - - \ No newline at end of file diff --git a/src/Aardvark.Data.Vrml97/AttributeAnnotator.cs b/src/Aardvark.Data.Vrml97/AttributeAnnotator.cs deleted file mode 100644 index c0742db7..00000000 --- a/src/Aardvark.Data.Vrml97/AttributeAnnotator.cs +++ /dev/null @@ -1,282 +0,0 @@ -using Aardvark.Base; -using System; -using System.Collections.Generic; -using System.IO; - -namespace Aardvark.Data.Vrml97 -{ - /// - /// The AttributeAnnotator is used to annotate all - /// geometry nodes with material and transform - /// attributes. - /// - /// Example: - /// - /// Parser parser = new Parser("myVrmlFile.wrl"); - /// SymMapBase parseTree = parser.Perform(); - /// - /// AttributeAnnotator resolver = new AttributeAnnotator(); - /// SymMapBase annotatedParseTree = resolver.Perform(parseTree); - /// - /// - internal class AttributeAnnotator - { - private Stack m_material; - private Stack m_texture; - private Stack m_textureTransform; - private Stack m_transform; - private string m_path = ""; - private Dictionary m_visited = new Dictionary(); - - public static Vrml97Scene Annotate(Vrml97Scene vrmlParseTree) - => new AttributeAnnotator().Perform(vrmlParseTree); - - /// - /// Takes a Vrml97 parse tree (see also ) - /// and augments all geometry nodes with material and - /// transform attributes. - /// - /// Parse tree. - /// Augmented parse tree. - public Vrml97Scene Perform(Vrml97Scene root) - { - root.ParseTree["AttributeAnnotator.Performed"] = true; // leave hint - - if (root.ParseTree.TypeName == "Vrml97") - { - string filename = root.ParseTree.Get(Vrml97Sym.filename); - m_path = Path.GetDirectoryName(filename); - } - - m_material = new Stack(); - m_texture = new Stack(); - m_textureTransform = new Stack(); - m_transform = new Stack(); - - m_transform.Push(Trafo3d.Identity); - - var trav = new SymMapBaseTraversal(SymMapBaseTraversal.Mode.Modifying, SymMapBaseTraversal.Visit.PreAndPost); - - trav.PerNameVisitors["ImageTexture"] = - delegate(SymMapBase m, SymMapBaseTraversal.Visit visit) - { - if (visit == SymMapBaseTraversal.Visit.Pre) - { - if (m_visited.ContainsKey(m)) return m; - List urls = m.Get>(Vrml97Sym.url); - if (urls != null) - { - for (int i = 0; i < urls.Count; i++) - { - urls[i] = Path.Combine(m_path, urls[i]); - } - } - m_visited[m] = m; - } - return m; - }; - - // geometry nodes - SymMapBase foo(SymMapBase m, SymMapBaseTraversal.Visit visit) - { - if (visit == SymMapBaseTraversal.Visit.Post) return m; - - if (m_material.Count == 0 - && m_texture.Count == 0 - && m_textureTransform.Count == 0 - && m_transform.Count == 0) - return m; - - var map = new SymMapBase(m); - - if (m_material.Count > 0) - { - string key = "material"; - // while (m.Contains(key)) key += "X"; - map[key] = m_material.Peek(); - } - - if (m_texture.Count > 0) - { - string key = "texture"; - // while (m.Contains(key)) key += "X"; - map[key] = m_texture.Peek(); - } - - if (m_textureTransform.Count > 0) - { - string key = "textureTransform"; - // while (m.Contains(key)) key += "X"; - var tt = m_textureTransform.Peek(); - - map[key] = tt.ExtractVrmlTextureTrafo(); - } - - if (m_transform.Count > 1) // [0] contains initial identity - { - string key = "transform"; - // while (m.Contains(key)) key += "X"; - if (m.Contains(key)) - { - Report.Warn("[Vrml97]: trying to annotate annotated node!"); - } - map[key] = m_transform.Peek(); - } - - return map; - } - - trav.PerNameVisitors["IndexedFaceSet"] = foo; - trav.PerNameVisitors["IndexedLineSet"] = foo; - - - // attributes - trav.PerNameVisitors["Shape"] = - delegate(SymMapBase m, SymMapBaseTraversal.Visit visit) - { - bool hasMaterial = false; - bool hasTexture = false; - bool hasTextureTransform = false; - SymMapBase app = null; - - if (m.Contains("appearance")) - { - app = m.Get(Vrml97Sym.appearance); - hasMaterial = app.Contains(Vrml97Sym.material); - hasTexture = app.Contains(Vrml97Sym.texture); - hasTextureTransform = app.Contains(Vrml97Sym.textureTransform); - } - - if (visit == SymMapBaseTraversal.Visit.Pre) - { - if (hasMaterial) m_material.Push(app.Get(Vrml97Sym.material)); - if (hasTexture) m_texture.Push(app.Get(Vrml97Sym.texture)); - if (hasTextureTransform) m_textureTransform.Push(app.Get(Vrml97Sym.textureTransform)); - } - else if (visit == SymMapBaseTraversal.Visit.Post) - { - if (hasMaterial) m_material.Pop(); - if (hasTexture) m_texture.Pop(); - if (hasTextureTransform) m_textureTransform.Pop(); - } - - return m; - }; - - trav.PerNameVisitors["Transform"] = - delegate(SymMapBase m, SymMapBaseTraversal.Visit visit) - { - if (visit == SymMapBaseTraversal.Visit.Pre) - { - var trafo = m.ExtractVrmlGeometryTrafo(); - - m["trafo"] = trafo; - - m_transform.Push(trafo * m_transform.Peek()); - } - else if (visit == SymMapBaseTraversal.Visit.Post) - { - m_transform.Pop(); - } - - return m; - }; - - root.ParseTree = trav.Traverse(root.ParseTree); - return root; - } - } - - /// - /// Various helper methods. - /// - public static class VrmlHelpers - { - /// - /// Build a texture coordinate transformation from the given parameters as specified in TextureTransform - /// http://gun.teipir.gr/VRML-amgem/spec/part1/nodesRef.html#TextureTransform - /// - public static Trafo2d BuildVrmlTextureTrafo(V2d center, double rotation, V2d scale, V2d translation) - { - M33d C = M33d.Translation(center), Ci = M33d.Translation(-center); - M33d R = M33d.Rotation(rotation), Ri = M33d.Rotation(-rotation); - M33d S = M33d.Scale(scale), Si = M33d.Scale(1 / scale); - M33d T = M33d.Translation(translation), Ti = M33d.Translation(-translation); - - return new Trafo2d( - Ci * S * R * C * T, - Ti * Ci * Ri * Si * C); - } - - /// - /// Extracts texture transform from given node. - /// - public static Trafo2d ExtractVrmlTextureTrafo(this SymMapBase m) - { - if (m == null) return Trafo2d.Identity; - - // get trafo parts - var c = (V2d)m.Get(Vrml97Sym.center, V2f.Zero); - var r = (double)m.Get(Vrml97Sym.rotation, 0.0f); - var s = (V2d)m.Get(Vrml97Sym.scale, new V2f(1, 1)); - var t = (V2d)m.Get(Vrml97Sym.translation, V2f.Zero); - - M33d C = M33d.Translation(c), Ci = M33d.Translation(-c); - M33d R = M33d.Rotation(r), Ri = M33d.Rotation(-r); - M33d S = M33d.Scale(s), Si = M33d.Scale(1 / s); - M33d T = M33d.Translation(t), Ti = M33d.Translation(-t); - - return new Trafo2d( - Ci * S * R * C * T, - Ti * Ci * Ri * Si * C); - } - - /// - /// Build a geometry transformation from the given parameters as specified in Transform - /// http://gun.teipir.gr/VRML-amgem/spec/part1/nodesRef.html#Transform - /// - public static Trafo3d BuildVrmlGeometryTrafo(V3d center, V4d rotation, V3d scale, V4d scaleOrientation, V3d translation) - { - // create composite trafo (naming taken from vrml97 spec) - M44d C = M44d.Translation(center), Ci = M44d.Translation(-center); - var scaleRotAxis = scaleOrientation.XYZ.Normalized; // NOTE: values in the vrml (limited number of digits) are often not normalized - M44d SR = M44d.Rotation(scaleRotAxis, scaleOrientation.W), SRi = M44d.Rotation(scaleRotAxis, -scaleOrientation.W); - M44d T = M44d.Translation(translation), Ti = M44d.Translation(-translation); - - //if (m_aveCompatibilityMode) r.W = -r.W; - var rotationAxis = rotation.XYZ.Normalized; // NOTE: values in the vrml (limited number of digits) are often not normalized - M44d R = M44d.Rotation(rotationAxis, rotation.W), Ri = M44d.Rotation(rotationAxis, -rotation.W); - - // in case some axis scales by 0 the best thing for the inverse scale is also 0 - var si = new V3d(scale.X.IsTiny() ? 0 : 1 / scale.X, - scale.Y.IsTiny() ? 0 : 1 / scale.Y, - scale.Z.IsTiny() ? 0 : 1 / scale.Z); - M44d S = M44d.Scale(scale), Si = M44d.Scale(si); - - return new Trafo3d( - T * C * R * SR * S * SRi * Ci, - C * SR * Si * SRi * Ri * Ci * Ti); - } - - /// - /// Returns geometry transform from given node. - /// - public static Trafo3d ExtractVrmlGeometryTrafo(this SymMapBase m) - { - // get trafo parts - var c = (V3d)m.Get(Vrml97Sym.center, V3f.Zero); - - var r = (V4d)m.Get(Vrml97Sym.rotation, V4f.Zero); - if (r.X == 0 && r.Y == 0 && r.Z == 0) r.Z = 1; - - var s = (V3d)m.Get(Vrml97Sym.scale, new V3f(1, 1, 1)); - - var sr = (V4d)m.Get(Vrml97Sym.scaleOrientation, V4f.Zero); - if (sr.X == 0 && sr.Y == 0 && sr.Z == 0) sr.Z = 1; - - var t = (V3d)m.Get(Vrml97Sym.translation, V3f.Zero); - - return BuildVrmlGeometryTrafo(c, r, s, sr, t); - } - } -} diff --git a/src/Aardvark.Data.Vrml97/DefUseResolver.cs b/src/Aardvark.Data.Vrml97/DefUseResolver.cs deleted file mode 100644 index ba460b46..00000000 --- a/src/Aardvark.Data.Vrml97/DefUseResolver.cs +++ /dev/null @@ -1,76 +0,0 @@ -using Aardvark.Base; -using System.Collections.Generic; - -namespace Aardvark.Data.Vrml97 -{ - /// - /// The DefUseResolver is used to resolve all - /// occurences of DEF and USE in a Vrml97 parse - /// tree. - /// If multiple USE statements reference the same - /// node, then the parse tree becomes a DAG. - /// - /// Example: - /// - /// Parser parser = new Parser("myVrmlFile.wrl"); - /// SymMapBase parseTree = parser.Perform(); - /// - /// DefUseResolver resolver = new DefUseResolver(); - /// SymMapBase resolvedParseTree = resolver.Perform(parseTree); - /// - /// - internal class DefUseResolver - { - public static Vrml97Scene Resolve(Vrml97Scene vrmlParseTree, - out Dictionary namedNodes, bool duplicateMaps = true) - => new DefUseResolver().Perform(vrmlParseTree, out namedNodes, duplicateMaps); - - /// - /// Takes a VRML97 parse tree (see also ) - /// and resolves all DEF and USE nodes. - /// - /// Parse tree. - /// - /// - /// Parse tree without DEF and USE nodes. - public Vrml97Scene Perform(Vrml97Scene root, out Dictionary namedNodes, bool duplicateMaps) - { - root.ParseTree["DefUseResolver.Performed"] = true; // leave hint - - m_defs = new Dictionary(); - SymMapBaseTraversal trav = new SymMapBaseTraversal(); - - trav.PerNameVisitors["USE"] = (map, visit) => - { - // Lookup USE name and return associated node. - var name = map.Get(Vrml97Sym.name); - SymMapBase node; - if (!m_defs.TryGetValue(name, out node)) - { - Report.Warn($"[Vrml97] DefUseResolver: USE \"{name}\" unknown!"); - return map; // keep "USE" ref node in SymMap-Tree - //throw new Exception("DefUseResolver: USE " + name + ": Unknown!"); - } - - return duplicateMaps ? new SymMapBase(node) : node; - }; - - trav.PerNameVisitors["DEF"] = (map, visit) => - { - // Register name/node pair. - string defName = map.Get(Vrml97Sym.name); - SymMapBase node = map.Get(Vrml97Sym.node); - m_defs[defName] = node; - - node["DEFname"] = defName; - return node; - }; - - trav.Traverse(root.ParseTree); - namedNodes = m_defs; - return root; - } - - private Dictionary m_defs; - } -} diff --git a/src/Aardvark.Data.Vrml97/ImageTextureFormatRenamer.cs b/src/Aardvark.Data.Vrml97/ImageTextureFormatRenamer.cs deleted file mode 100644 index f974596a..00000000 --- a/src/Aardvark.Data.Vrml97/ImageTextureFormatRenamer.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Aardvark.Base; -using System.Collections.Generic; - -namespace Aardvark.Data.Vrml97 -{ - /// - /// - public class ImageTextureFormatRenamer - { - /// - /// Takes a Vrml97 parse tree (see also ) - /// and replaces the file extension of all image texture URLs to - /// the specified extension. - /// - /// Parse tree. - /// - internal Vrml97Scene Perform(Vrml97Scene root, string newExtension) - { - var trav = new SymMapBaseTraversal(SymMapBaseTraversal.Visit.Post); - - trav.PerNameVisitors["ImageTexture"] = - delegate(SymMapBase m, SymMapBaseTraversal.Visit visit) - { - var urls = m.Get>(Vrml97Sym.url); - if (urls == null) return m; - for (int i = 0; i < urls.Count; i++) - { - int p = urls[i].LastIndexOf('.'); - urls[i] = urls[i].Substring(0, p) + "." + newExtension; - } - - return m; - }; - - trav.Traverse(root.ParseTree); - return root; - } - } -} diff --git a/src/Aardvark.Data.Vrml97/ParseException.cs b/src/Aardvark.Data.Vrml97/ParseException.cs deleted file mode 100644 index 582a4c5d..00000000 --- a/src/Aardvark.Data.Vrml97/ParseException.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; - -namespace Aardvark.Data.Vrml97 -{ - /// - /// VRML97 parse exception. - /// - public class ParseException : Exception - { - /// - /// Constructor. - /// - public ParseException(string s) - : base(s) - { - } - } -} diff --git a/src/Aardvark.Data.Vrml97/Parser.cs b/src/Aardvark.Data.Vrml97/Parser.cs deleted file mode 100644 index 4c87e39e..00000000 --- a/src/Aardvark.Data.Vrml97/Parser.cs +++ /dev/null @@ -1,1281 +0,0 @@ -using Aardvark.Base; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; - -namespace Aardvark.Data.Vrml97 -{ - /// - /// Symbol table. - /// - public static class Vrml97Sym - { -#pragma warning disable 1591 - public static readonly Symbol Vrml97 = "Vrml97"; - public static readonly Symbol url = "url"; - public static readonly Symbol texture = "texture"; - public static readonly Symbol name = "name"; - public static readonly Symbol filename = "filename"; - public static readonly Symbol node = "node"; - public static readonly Symbol root = "root"; - public static readonly Symbol appearance = "appearance"; - public static readonly Symbol material = "material"; - public static readonly Symbol textureTransform = "textureTransform"; - public static readonly Symbol center = "center"; - public static readonly Symbol rotation = "rotation"; - public static readonly Symbol scale = "scale"; - public static readonly Symbol translation = "translation"; - public static readonly Symbol scaleOrientation = "scaleOrientation"; - - public static readonly Symbol DEF = "DEF"; - public static readonly Symbol USE = "USE"; - public static readonly Symbol ROUTE = "ROUTE"; - public static readonly Symbol NULL = "NULL"; -#pragma warning restore 1591 - } - - /// - /// Table of VRML97 node names - /// - public static class Vrml97NodeName - { -#pragma warning disable 1591 - public static readonly Symbol Anchor = "Anchor"; - public static readonly Symbol Appearance = "Appearance"; - public static readonly Symbol AudioClip = "AudioClip"; - public static readonly Symbol Background = "Background"; - public static readonly Symbol Billboard = "Billboard"; - public static readonly Symbol Box = "Box"; - public static readonly Symbol Collision = "Collision"; - public static readonly Symbol Color = "Color"; - public static readonly Symbol ColorInterpolator = "ColorInterpolator"; - public static readonly Symbol Cone = "Cone"; - public static readonly Symbol Coordinate = "Coordinate"; - public static readonly Symbol CoordinateInterpolator = "CoordinateInterpolator"; - public static readonly Symbol Cylinder = "Cylinder"; - public static readonly Symbol CylinderSensor = "CylinderSensor"; - public static readonly Symbol DirectionalLight = "DirectionalLight"; - public static readonly Symbol ElevationGrid = "DirectionalLight"; - public static readonly Symbol Extrusion = "DirectionalLight"; - public static readonly Symbol Fog = "Fog"; - public static readonly Symbol FontStyle = "FontStyle"; - public static readonly Symbol Group = "Group"; - public static readonly Symbol ImageTexture = "ImageTexture"; - public static readonly Symbol IndexedFaceSet = "IndexedFaceSet"; - public static readonly Symbol IndexedLineSet = "IndexedLineSet"; - public static readonly Symbol Inline = "Inline"; - public static readonly Symbol LOD = "LOD"; - public static readonly Symbol Material = "Material"; - public static readonly Symbol MovieTexture = "MovieTexture"; - public static readonly Symbol NavigationInfo = "NavigationInfo"; - public static readonly Symbol Normal = "Normal"; - public static readonly Symbol NormalInterpolator = "NormalInterpolator"; - public static readonly Symbol OrientationInterpolator = "OrientationInterpolator"; - public static readonly Symbol PixelTexture = "PixelTexture"; - public static readonly Symbol PlaneSensor = "PlaneSensor"; - public static readonly Symbol PointLight = "PointLight"; - public static readonly Symbol PointSet = "PointSet"; - public static readonly Symbol PositionInterpolator = "PositionInterpolator"; - public static readonly Symbol ProximitySensor = "ProximitySensor"; - public static readonly Symbol ScalarInterpolator = "ScalarInterpolator"; - public static readonly Symbol Script = "Script"; - public static readonly Symbol Shape = "Shape"; - public static readonly Symbol Sound = "Sound"; - public static readonly Symbol Sphere = "Sphere"; - public static readonly Symbol SphereSensor = "SphereSensor"; - public static readonly Symbol SpotLight = "SpotLight"; - public static readonly Symbol Switch = "Switch"; - public static readonly Symbol Text = "Text"; - public static readonly Symbol TextureCoordinate = "TextureCoordinate"; - public static readonly Symbol TextureTransform = "TextureTransform"; - public static readonly Symbol TimeSensor = "TimeSensor"; - public static readonly Symbol TouchSensor = "TTouchSensorext"; - public static readonly Symbol Transform = "Transform"; - public static readonly Symbol Viewpoint = "Viewpoint"; - public static readonly Symbol VisibilitySensor = "VisibilitySensor"; - public static readonly Symbol WorldInfo = "WorldInfo"; -#pragma warning restore 1591 - } - - /// - /// Vrml97 parser. - /// - public static class Parser - { - internal class State - { - SymMapBase m_result = new SymMapBase(); - Tokenizer m_tokenizer; - - /// - /// Constructs a Parser for the given input stream. - /// In order to actually parse the data, call the - /// Perform method, which returns a SymMapBase containing - /// the parse tree. - /// - /// Input stream. - /// FileName - public State(Stream input, string fileName) - { - m_result.TypeName = Vrml97Sym.Vrml97; - m_result[Vrml97Sym.filename] = fileName; - m_tokenizer = new Tokenizer(input); - } - - /// - /// Parses the input data and returns a SymMapBase - /// containing the parse tree. - /// - /// Parse tree. - public Vrml97Scene Perform() - { - var root = new List(); - - while (true) - { - try - { - var node = ParseNode(m_tokenizer); - if (node == null) break; - root.Add(node); - Thread.Sleep(0); - } - catch (ParseException e) - { - Report.Warn("[Vrml97] Caught exception while parsing: {0}!", e.Message); - Report.Warn("[Vrml97] Result may contain partial, incorrect or invalid data!"); - break; - } - } - - m_result[Vrml97Sym.root] = root; - return new Vrml97Scene(m_result); - } - } - - #region Node specs. - - private static SymbolDict s_parseInfoMap; - - private delegate SymMapBase NodeParser(Tokenizer t); - - public delegate object FieldParser(Tokenizer t); - - public static readonly FieldParser SFBool = new FieldParser(ParseSFBool); - public static readonly FieldParser MFBool = new FieldParser(ParseMFBool); - public static readonly FieldParser SFColor = new FieldParser(ParseSFColor); - public static readonly FieldParser MFColor = new FieldParser(ParseMFColor); - public static readonly FieldParser SFFloat = new FieldParser(ParseSFFloat); - public static readonly FieldParser MFFloat = new FieldParser(ParseMFFloat); - public static readonly FieldParser SFImage = new FieldParser(ParseSFImage); - public static readonly FieldParser SFInt32 = new FieldParser(ParseSFInt32); - public static readonly FieldParser MFInt32 = new FieldParser(ParseMFInt32); - public static readonly FieldParser SFNode = new FieldParser(ParseSFNode); - public static readonly FieldParser MFNode = new FieldParser(ParseMFNode); - public static readonly FieldParser SFRotation = new FieldParser(ParseSFRotation); - public static readonly FieldParser MFRotation = new FieldParser(ParseMFRotation); - public static readonly FieldParser SFString = new FieldParser(ParseSFString); - public static readonly FieldParser MFString = new FieldParser(ParseMFString); - public static readonly FieldParser SFTime = new FieldParser(ParseSFFloat); - public static readonly FieldParser MFTime = new FieldParser(ParseMFFloat); - public static readonly FieldParser SFVec2f = new FieldParser(ParseSFVec2f); - public static readonly FieldParser MFVec2f = new FieldParser(ParseMFVec2f); - public static readonly FieldParser SFVec3f = new FieldParser(ParseSFVec3f); - public static readonly FieldParser MFVec3f = new FieldParser(ParseMFVec3f); - - /// - /// Registers a custom node attribute field parser. - /// Usage: RegisterCustomNodeField(Vrml97NodeName.Material, "doubleSided", Parser.SFBool, false); - /// - public static void RegisterCustomNodeField(Symbol nodeName, Symbol fieldName, FieldParser parser, object defaultValue) - { - if (!s_parseInfoMap.TryGetValue(nodeName, out var npi)) - throw new ArgumentException($"Failed to register \"{fieldName}\" as custom \"{nodeName}\" node field: The node name is not registered!"); - if (npi.FieldDefs == null) - throw new ArgumentException($"Failed to register \"{fieldName}\" as custom \"{nodeName}\" node field: The node does not have FieldDefs!"); - npi.FieldDefs.Add(fieldName, (parser, defaultValue)); - } - - /// - /// Static constructor. - /// - static Parser() - { - // Lookup table for Vrml97 node types. - // For each node type a NodeParseInfo entry specifies how - // to handle this kind of node. - s_parseInfoMap = new SymbolDict - { - // DEF - [Vrml97Sym.DEF] = new NodeParseInfo(new NodeParser(ParseDEF)), - - // USE - [Vrml97Sym.USE] = new NodeParseInfo(new NodeParser(ParseUSE)), - - // ROUTE - [Vrml97Sym.ROUTE] = new NodeParseInfo(new NodeParser(ParseROUTE)), - - // NULL - [Vrml97Sym.NULL] = new NodeParseInfo(new NodeParser(ParseNULL)) - }; - - var defaultBBoxCenter = (SFVec3f, (object)V3f.Zero); - var defaultBBoxSize = (SFVec3f, (object)new V3f(-1, -1, -1)); - - (FieldParser, object) fd(FieldParser fp) => (fp, null); // helper to create (FieldParser, ) tuple with null as default value - - // Anchor - s_parseInfoMap[Vrml97NodeName.Anchor] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "children", fd(MFNode) }, - { "description", fd(SFString) }, - { "parameter", fd(MFString) }, - { "url", fd(MFString) }, - { "bboxCenter", defaultBBoxCenter}, - { "bboxSize", defaultBBoxSize} - }); - - // Appearance - s_parseInfoMap[Vrml97NodeName.Appearance] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "material", fd(SFNode) }, - { "texture", fd(SFNode) }, - { "textureTransform", fd(SFNode) } - }); - - // AudioClip - s_parseInfoMap[Vrml97NodeName.AudioClip] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "description", fd(SFString) }, - { "loop", (SFBool, false) }, - { "pitch", (SFFloat, 1.0f) }, - { "startTime", (SFTime, 0.0f)}, - { "stopTime", (SFTime, 0.0f)}, - { "url", fd(MFString)} - }); - - // Background - s_parseInfoMap[Vrml97NodeName.Background] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "groundAngle", fd(MFFloat) }, - { "groundColor", fd(MFColor) }, - { "backUrl", fd(MFString) }, - { "bottomUrl", fd(MFString) }, - { "frontUrl", fd(MFString) }, - { "leftUrl", fd(MFString) }, - { "rightUrl", fd(MFString) }, - { "topUrl", fd(MFString) }, - { "skyAngle", fd(MFFloat) }, - { "skyColor", (MFColor, C3f.Black) } - }); - - // Billboard - s_parseInfoMap[Vrml97NodeName.Billboard] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "axisOfRotation", (SFVec3f, new V3f(0.0f, 1.0f, 0.0f)) }, - { "children", fd(MFNode) }, - { "bboxCenter", defaultBBoxCenter}, - { "bboxSize", defaultBBoxSize} - }); - - // Box - s_parseInfoMap[Vrml97NodeName.Box] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "size", (SFVec3f, new V3f(2.0f, 2.0f, 2.0f)) } - }); - - // Collision - s_parseInfoMap[Vrml97NodeName.Collision] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "children", fd(MFNode) }, - { "collide", (SFBool, true) }, - { "bboxCenter", defaultBBoxCenter}, - { "bboxSize", defaultBBoxSize}, - { "proxy", fd(SFNode) } - }); - - // Color - s_parseInfoMap[Vrml97NodeName.Color] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "color", fd(MFColor) } - }); - - // ColorInterpolator - s_parseInfoMap[Vrml97NodeName.ColorInterpolator] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "key", fd(MFFloat) }, - { "keyValue", fd(MFColor) } - }); - - // Cone - s_parseInfoMap[Vrml97NodeName.Cone] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "bottomRadius", (SFFloat, 1.0f) }, - { "height", (SFFloat, 2.0f) }, - { "side", (SFBool, true) }, - { "bottom", (SFBool, true) } - }); - - // Coordinate - s_parseInfoMap[Vrml97NodeName.Coordinate] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "point", fd(MFVec3f) } - }); - - // CoordinateInterpolator - s_parseInfoMap[Vrml97NodeName.CoordinateInterpolator] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "key", fd(MFFloat) }, - { "keyValue", fd(MFVec3f) } - }); - - // Cylinder - s_parseInfoMap[Vrml97NodeName.Cylinder] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "bottom", (SFBool, true) }, - { "height", (SFFloat, 2.0f) }, - { "radius", (SFFloat, 1.0f) }, - { "side", (SFBool, true) }, - { "top", (SFBool, true) } - }); - - // CylinderSensor - s_parseInfoMap[Vrml97NodeName.CylinderSensor] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "autoOffset", (SFBool, true) }, - { "diskAngle", (SFFloat, 0.262f) }, - { "enabled", (SFBool, true) }, - { "maxAngle", (SFFloat, -1.0f) }, - { "minAngle", (SFFloat, 0.0f) }, - { "offset", (SFFloat, 0.0f) } - }); - - // DirectionalLight - s_parseInfoMap[Vrml97NodeName.DirectionalLight] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "ambientIntensity", (SFFloat, 0.0f) }, - { "color", (SFColor, C3f.White) }, - { "direction", (SFVec3f, new V3f(0.0f, 0.0f, -1.0f)) }, - { "intensity", (SFFloat, 1.0f) }, - { "on", (SFBool, true) } - }); - - // ElevationGrid - s_parseInfoMap[Vrml97NodeName.ElevationGrid] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "color", fd(SFNode) }, - { "normal", fd(SFNode) }, - { "texCoord", fd(SFNode) }, - { "height", fd(MFFloat) }, - { "ccw", (SFBool, true) }, - { "colorPerVertex", (SFBool, true) }, - { "creaseAngle", (SFFloat, 0.0f) }, - { "normalPerVertex", (SFBool, true) }, - { "solid", (SFBool, true) }, - { "xDimension", (SFInt32, 0) }, - { "xSpacing", (SFFloat, 1.0f) }, - { "zDimension", (SFInt32, 0) }, - { "zSpacing", (SFFloat, 1.0f) } - }); - - // Extrusion - s_parseInfoMap[Vrml97NodeName.Extrusion] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "beginCap", (SFBool, true) }, - { "ccw", (SFBool, true) }, - { "convex", (SFBool, true) }, - { "creaseAngle", (SFFloat, 0.0f) }, - { "crossSection", (MFVec2f, new List() {new V2f(1.0f, 1.0f), new V2f(1.0f, -1.0f), new V2f(-1.0f, -1.0f), new V2f(-1.0f, 1.0f), new V2f(1.0f, 1.0f) }) }, - { "endCap", (SFBool, true) }, - { "orientation", (MFRotation, new V4f(0.0f, 0.0f, 1.0f, 0.0f)) }, - { "scale", (MFVec2f, new V2f(1.0f, 1.0f)) }, - { "solid", (SFBool, true) }, - { "spine", (MFVec3f, new List() { V3f.Zero, new V3f(0.0f, 1.0f, 0.0f) }) } - }); - - // Fog - s_parseInfoMap[Vrml97NodeName.Fog] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "color", (SFColor, C3f.White) }, - { "fogType", (SFString, "LINEAR") }, - { "visibilityRange", (SFFloat, 0.0f) } - }); - - // FontStyle - s_parseInfoMap[Vrml97NodeName.FontStyle] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "family", (MFString, "SERIF") }, - { "horizontal", (SFBool, true) }, - { "justify", (MFString, "BEGIN") }, - { "language", fd(SFString) }, - { "leftToRight", (SFBool, true) }, - { "size", (SFFloat, 1.0f) }, - { "spacing", (SFFloat, 1.0f) }, - { "style", (SFString, "PLAIN") }, - { "topToBottom", (SFBool, true) } - }); - - // Group - s_parseInfoMap[Vrml97NodeName.Group] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "children", fd(MFNode) }, - { "bboxCenter", defaultBBoxCenter }, - { "bboxSize", defaultBBoxSize } - }); - - // ImageTexture - s_parseInfoMap[Vrml97NodeName.ImageTexture] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "url", fd(MFString) }, - { "repeatS", (SFBool, true) }, - { "repeatT", (SFBool, true) } - }); - - // IndexedFaceSet - s_parseInfoMap[Vrml97NodeName.IndexedFaceSet] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "color", fd(SFNode) }, - { "coord", fd(SFNode) }, - { "normal", fd(SFNode) }, - { "texCoord", fd(SFNode) }, - { "ccw", (SFBool, true) }, - { "colorIndex", fd(MFInt32) }, - { "colorPerVertex", (SFBool, true) }, - { "convex", (SFBool, true) }, - { "coordIndex", fd(MFInt32) }, - { "creaseAngle", (SFFloat, 0.0f) }, - { "normalIndex", fd(MFInt32) }, - { "normalPerVertex", (SFBool, true) }, - { "solid", (SFBool, true) }, - { "texCoordIndex", fd(MFInt32) }, - { "edgeSharpness", fd(MFFloat) }, - { "edgeSharpnessIndex", fd(MFInt32) }, - { "neighborMesh", fd(MFString) }, - { "neighborIndex", fd(MFInt32) }, - { "neighborSide", fd(MFInt32) }, - { "neighborFace", fd(MFInt32) }, - { "meshName", fd(SFString) }, - { "topologyHoles", fd(SFInt32) } - }); - - // IndexedLineSet - s_parseInfoMap[Vrml97NodeName.IndexedLineSet] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "color", fd(SFNode) }, - { "coord", fd(SFNode) }, - { "colorIndex", fd(MFInt32) }, - { "colorPerVertex", (SFBool, true) }, - { "coordIndex", fd(MFInt32) } - }); - - // Inline - s_parseInfoMap[Vrml97NodeName.Inline] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "url", fd(MFString) }, - { "bboxCenter", defaultBBoxCenter }, - { "bboxSize", defaultBBoxSize } - }); - - // LOD - s_parseInfoMap[Vrml97NodeName.LOD] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "level", fd(MFNode) }, - { "center", defaultBBoxCenter }, - { "range", fd(MFFloat) } - }); - - // Material - s_parseInfoMap[Vrml97NodeName.Material] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "ambientIntensity", (SFFloat, 0.2f) }, - { "diffuseColor", (SFColor, new C3f(0.8f, 0.8f, 0.8f)) }, - { "emissiveColor", (SFColor, C3f.Black) }, - { "shininess", (SFFloat, 0.2f) }, - { "specularColor", (SFColor, C3f.Black) }, - { "transparency", (SFFloat, 0.0f) } - }); - - // MovieTexture - s_parseInfoMap[Vrml97NodeName.MovieTexture] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "loop", (SFBool, false) }, - { "speed", (SFFloat, 1.0f) }, - { "startTime", (SFTime, 1.0f) }, - { "stopTime", (SFTime, 1.0f) }, - { "url", fd(MFString) }, - { "repeatS", (SFBool, true) }, - { "repeatT", (SFBool, true) } - }); - - // NavigationInfo - s_parseInfoMap[Vrml97NodeName.NavigationInfo] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "avatarSize", (MFFloat, new List() {0.25f, 1.6f, 0.75f}) }, - { "headlight", (SFBool, true) }, - { "speed", (SFFloat, 1.0f) }, - { "type", (MFString, new List() {"WALK", "ANY"}) }, - { "visibilityLimit", (SFFloat, 0.0f) } - }); - - // Normal - s_parseInfoMap[Vrml97NodeName.Normal] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "vector", fd(MFVec3f) } - }); - - // NormalInterpolator - s_parseInfoMap[Vrml97NodeName.NormalInterpolator] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "key", fd(MFFloat) }, - { "keyValue", fd(MFVec3f) } - }); - - // OrientationInterpolator - s_parseInfoMap[Vrml97NodeName.OrientationInterpolator] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "key", fd(MFFloat) }, - { "keyValue", fd(MFRotation) } - }); - - // PixelTexture - s_parseInfoMap[Vrml97NodeName.PixelTexture] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "image", (SFImage, new List() {0, 0, 0}) }, - { "repeatS", (SFBool, true) }, - { "repeatT", (SFBool, true) } - }); - - // PlaneSensor - s_parseInfoMap[Vrml97NodeName.PlaneSensor] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "autoOffset", (SFBool, true) }, - { "enabled", (SFBool, true) }, - { "maxPosition", (SFVec2f, new V2f(-1.0f, -1.0f)) }, - { "minPosition", (SFVec2f, V2f.Zero) }, - { "offset", defaultBBoxCenter } - }); - - // PointLight - s_parseInfoMap[Vrml97NodeName.PointLight] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "ambientIntensity", (SFFloat, 0.0f) }, - { "attenuation", (SFVec3f, new V3f(1.0f, 0.0f, 0.0f)) }, - { "color", (SFColor, C3f.White) }, - { "intensity", (SFFloat, 1.0f) }, - { "location", defaultBBoxCenter }, - { "on", (SFBool, true) }, - { "radius", (SFFloat, 100.0f) } - }); - - // PointSet - s_parseInfoMap[Vrml97NodeName.PointSet] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "color", fd(SFNode) }, - { "coord", fd(SFNode) } - }); - - // PositionInterpolator - s_parseInfoMap[Vrml97NodeName.PositionInterpolator] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "key", fd(MFFloat) }, - { "keyValue", fd(MFVec3f) } - }); - - // ProximitySensor - s_parseInfoMap[Vrml97NodeName.ProximitySensor] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "center", defaultBBoxCenter }, - { "size", defaultBBoxCenter }, - { "enabled", (SFBool, true) } - }); - - // ScalarInterpolator - s_parseInfoMap[Vrml97NodeName.ScalarInterpolator] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "key", fd(MFFloat) }, - { "keyValue", fd(MFFloat) } - }); - - // Script - // skipped - - // Shape - s_parseInfoMap[Vrml97NodeName.Shape] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "appearance", fd(SFNode) }, - { "geometry", fd(SFNode) }, - }); - - // Sound - s_parseInfoMap[Vrml97NodeName.Sound] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "direction", (SFVec3f, new V3f(0.0f, 0.0f, 1.0f)) }, - { "intensity", (SFFloat, 1.0f) }, - { "location", defaultBBoxCenter }, - { "maxBack", (SFFloat, 10.0f) }, - { "maxFront", (SFFloat, 10.0f) }, - { "minBack", (SFFloat, 1.0f) }, - { "minFront", (SFFloat, 1.0f) }, - { "priority", (SFFloat, 0.0f) }, - { "source", fd(SFNode) }, - { "spatialize", (SFBool, true) } - }); - - // Sphere - s_parseInfoMap[Vrml97NodeName.Sphere] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "radius", (SFFloat, 1.0f) } - }); - - // SphereSensor - s_parseInfoMap[Vrml97NodeName.SphereSensor] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "autoOffset", (SFBool, true) }, - { "enabled", (SFBool, true) }, - { "offset", (SFRotation, new V4f(0.0f, 1.0f, 0.0f, 0.0f)) } - }); - - // SpotLight - s_parseInfoMap[Vrml97NodeName.SpotLight] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "ambientIntensity", (SFFloat, 0.0f) }, - { "attenuation", (SFVec3f, new V3f(1.0f, 0.0f, 0.0f)) }, - { "beamWidth", (SFFloat, 1.570796f) }, - { "color", (SFColor, C3f.White) }, - { "cutOffAngle", (SFFloat, 0.785398f) }, - { "direction", (SFVec3f, new V3f(0.0f, 0.0f, -1.0f)) }, - { "intensity", (SFFloat, 1.0f) }, - { "location", defaultBBoxCenter }, - { "on", (SFBool, true) }, - { "radius", (SFFloat, 100.0f) } - }); - - // Switch - s_parseInfoMap[Vrml97NodeName.Switch] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "choice", fd(MFNode) }, - { "whichChoice", (SFInt32, -1) } - }); - - // Text - s_parseInfoMap[Vrml97NodeName.Text] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "string", fd(MFString) }, - { "fontStyle", fd(SFNode) }, - { "length", fd(MFFloat) }, - { "maxExtent", (SFFloat, 0.0f) } - }); - - // TextureCoordinate - s_parseInfoMap[Vrml97NodeName.TextureCoordinate] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "point", fd(MFVec2f) } - }); - - // TextureTransform - s_parseInfoMap[Vrml97NodeName.TextureTransform] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "center", (SFVec2f, V2f.Zero) }, - { "rotation", (SFFloat, 0.0f) }, - { "scale", (SFVec2f, new V2f(1.0f, 1.0f)) }, - { "translation", (SFVec2f, V2f.Zero) } - }); - - // TimeSensor - s_parseInfoMap[Vrml97NodeName.TimeSensor] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "cycleInterval", (SFTime, 1.0f) }, - { "enabled", (SFBool, true) }, - { "loop", (SFBool, false) }, - { "startTime", (SFTime, 0.0f) }, - { "stopTime", (SFTime, 0.0f) } - }); - - // TouchSensor - s_parseInfoMap[Vrml97NodeName.TouchSensor] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "enabled", (SFBool, true) } - }); - - // Transform - s_parseInfoMap[Vrml97NodeName.Transform] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "center", defaultBBoxCenter }, - { "children", fd(MFNode) }, - { "rotation", (SFRotation, new V4f(0.0f, 0.0f, 1.0f, 0.0f)) }, - { "scale", (SFVec3f, new V3f(1.0f, 1.0f, 1.0f)) }, - { "scaleOrientation", (SFRotation, new V4f(0.0f, 0.0f, 1.0f, 0.0f)) }, - { "translation", defaultBBoxCenter }, - { "bboxCenter", defaultBBoxCenter }, - { "bboxSize", defaultBBoxSize } - }); - - // Viewpoint - s_parseInfoMap[Vrml97NodeName.Viewpoint] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "fieldOfView", (SFFloat, 0.785398f) }, - { "jump", (SFBool, true) }, - { "orientation", (SFRotation, new V4f(0.0f, 0.0f, 1.0f, 0.0f)) }, - { "position", (SFVec3f, new V3f(0.0f, 0.0f, 10.0f)) }, - { "description", fd(SFString) } - }); - - // VisibilitySensor - s_parseInfoMap[Vrml97NodeName.VisibilitySensor] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "center", defaultBBoxCenter }, - { "enabled", (SFBool, true) }, - { "size", defaultBBoxCenter } - }); - - // WorldInfo - s_parseInfoMap[Vrml97NodeName.WorldInfo] = new NodeParseInfo( - new SymbolDict<(FieldParser, object)>() - { - { "title", fd(SFString) }, - { "info", fd(MFString) } - }); - } - - private static SymMapBase ParseDEF(Tokenizer t) - { - var result = new SymMapBase(); - result["name"] = t.NextNameToken().ToString(); - result["node"] = ParseNode(t); - return result; - } - - private static SymMapBase ParseUSE(Tokenizer t) - { - var result = new SymMapBase(); - result["name"] = t.NextNameToken().ToString(); - return result; - } - - private static SymMapBase ParseROUTE(Tokenizer t) - { - var result = new SymMapBase(); - - // nodeNameId.eventOutId - result["out"] = t.NextNameToken().ToString(); - // "TO" - t.NextToken(); - // nodeNameId.eventInId - result["in"] = t.NextNameToken().ToString(); - - return result; - } - - private static SymMapBase ParseNULL(Tokenizer t) => null; - - #endregion - - #region Helper functions. - - private static object ParseSFBool(Tokenizer t) => t.NextToken().ToBool(); - - private static List ParseMFBool(Tokenizer t) - { - var result = new List(); - - var token = t.NextToken(); - if (token.IsBracketOpen) - { - token = t.NextToken(); - while (!token.IsBracketClose) - { - result.Add(token.ToBool()); - token = t.NextToken(); - } - } - else - { - result.Add(token.ToBool()); - } - - return result; - } - - private static object ParseSFFloat(Tokenizer t) => t.NextToken().ToFloat(); - - private static List ParseMFFloat(Tokenizer t) - { - var result = new List(); - - var token = t.NextToken(); - if (token.IsBracketOpen) - { - token = t.NextToken(); - while (!token.IsBracketClose) - { - result.Add(token.ToFloat()); - token = t.NextToken(); - } - } - else - { - result.Add(token.ToFloat()); - } - - return result; - } - - private static List ParseSFImage(Tokenizer t) - { - var result = new List - { - t.NextToken().ToUInt32(), // width - t.NextToken().ToUInt32(), // height - t.NextToken().ToUInt32() // num components - }; - - uint imax = result[0] * result[1]; - for (uint i = 0; i < imax; i++) - { - result.Add(t.NextToken().ToUInt32()); - } - - return result; - } - - private static object ParseSFInt32(Tokenizer t) => t.NextToken().ToInt32(); - - private static List ParseMFInt32(Tokenizer t) - { - var result = new List(); - - var token = t.NextToken(); - if (token.IsBracketOpen) - { - token = t.NextToken(); - while (!token.IsBracketClose) - { - result.Add(token.ToInt32()); - token = t.NextToken(); - } - } - else - { - result.Add(token.ToInt32()); - } - - return result; - } - - private static SymMapBase ParseSFNode(Tokenizer t) => ParseNode(t); - - private static List ParseMFNode(Tokenizer t) - { - var result = new List(); - - var token = t.NextToken(); - if (token.IsBracketOpen) - { - token = t.NextToken(); - while (!token.IsBracketClose) - { - t.PushBack(token); - result.Add(ParseNode(t)); - token = t.NextToken(); - } - } - else - { - t.PushBack(token); - result.Add(ParseNode(t)); - } - - return result; - } - - private static object ParseSFRotation(Tokenizer t) - { - var x = t.NextToken().ToFloat(); - var y = t.NextToken().ToFloat(); - var z = t.NextToken().ToFloat(); - var w = t.NextToken().ToFloat(); - return new V4f(x, y, z, w); - } - - private static List ParseMFRotation(Tokenizer t) - { - var result = new List(); - - var token = t.NextToken(); - if (token.IsBracketOpen) - { - token = t.NextToken(); - while (!token.IsBracketClose) - { - var x = token.ToFloat(); - var y = t.NextToken().ToFloat(); - var z = t.NextToken().ToFloat(); - var w = t.NextToken().ToFloat(); - result.Add(new V4f(x, y, z, w)); - - token = t.NextToken(); - } - } - else - { - var x = token.ToFloat(); - var y = t.NextToken().ToFloat(); - var z = t.NextToken().ToFloat(); - var w = t.NextToken().ToFloat(); - result.Add(new V4f(x, y, z, w)); - } - - return result; - } - - private static string ParseSFString(Tokenizer t) - => t.NextToken().GetCheckedUnquotedString(); - - private static List ParseMFString(Tokenizer t) - { - var result = new List(); - - var token = t.NextToken(); - if (token.IsBracketOpen) - { - token = t.NextToken(); - while (!token.IsBracketClose) - { - result.Add(token.GetCheckedUnquotedString()); - token = t.NextToken(); - } - } - else - { - result.Add(token.GetCheckedUnquotedString()); - } - - return result; - } - - private static object ParseSFVec2f(Tokenizer t) - { - var x = t.NextToken().ToFloat(); - var y = t.NextToken().ToFloat(); - return new V2f(x, y); - } - - private static List ParseMFVec2f(Tokenizer t) - { - var result = new List(); - - var token = t.NextToken(); - if (token.IsBracketOpen) - { - token = t.NextToken(); - while (!token.IsBracketClose) - { - float x = token.ToFloat(); - float y = t.NextToken().ToFloat(); - result.Add(new V2f(x, y)); - - token = t.NextToken(); - } - } - else - { - float x = token.ToFloat(); - float y = t.NextToken().ToFloat(); - result.Add(new V2f(x, y)); - } - - return result; - } - - private static object ParseSFVec3f(Tokenizer t) - { - var x = t.NextToken().ToFloat(); - var y = t.NextToken().ToFloat(); - var z = t.NextToken().ToFloat(); - return new V3f(x, y, z); - } - - private static List ParseMFVec3f(Tokenizer t) - { - var result = new List(); - - var token = t.NextToken(); - if (token.IsBracketOpen) - { - token = t.NextToken(); - while (!token.IsBracketClose) - { - var x = token.ToFloat(); - var y = t.NextToken().ToFloat(); - var z = t.NextToken().ToFloat(); - result.Add(new V3f(x, y, z)); - - token = t.NextToken(); - } - } - else - { - var x = token.ToFloat(); - var y = t.NextToken().ToFloat(); - var z = t.NextToken().ToFloat(); - result.Add(new V3f(x, y, z)); - } - - return result; - } - - private static object ParseSFColor(Tokenizer t) - { - var r = t.NextToken().ToFloat(); - var g = t.NextToken().ToFloat(); - var b = t.NextToken().ToFloat(); - return new C3f(r, g, b); - } - - private static List ParseMFColor(Tokenizer t) - { - var result = new List(); - - var token = t.NextToken(); - if (token.IsBracketOpen) - { - token = t.NextToken(); - while (!token.IsBracketClose) - { - var r = token.ToFloat(); - var g = t.NextToken().ToFloat(); - var b = t.NextToken().ToFloat(); - result.Add(new C3f(r, g, b)); - - token = t.NextToken(); - } - } - else - { - var r = token.ToFloat(); - var g = t.NextToken().ToFloat(); - var b = t.NextToken().ToFloat(); - result.Add(new C3f(r, g, b)); - } - - return result; - } - - private static void ExpectBraceOpen(Tokenizer t) - { - var token = t.NextToken(); - if (token.IsBraceOpen) return; - - throw new ParseException( - "Token '{' expected. Found " + token.ToString() + " instead!" - ); - } - - private static void ExpectBraceClose(Tokenizer t) - { - var token = t.NextToken(); - if (token.IsBraceClose) return; - - throw new ParseException( - "Token '}' expected. Found " + token.ToString() + " instead!" - ); - } - - #endregion - - #region Internal stuff. - - private static SymMapBase ParseNode(Tokenizer t) - { - // Next token is expected to be a Vrml97 node type. - var nodeType = t.NextToken().ToString(); - if (nodeType == null) return null; - - SymMapBase node; - - // If a field description is available for this type, - // then use the generic node parser, else use the custom - // parse function. - if (s_parseInfoMap.TryGetValue(nodeType, out var info)) - { - node = (info.FieldDefs == null) ? - info.NodeParser(t) : - ParseGenericNode(t, info); - } - else - { - // unknown node type - Report.Warn($"[Vrml97] ParseNode: \"{nodeType}\" unknown node type!"); - node = ParseUnknownNode(t); - } - - if (node != null) - node.TypeName = nodeType; - - return node; - } - - /// - /// Specifies how to parse a node. - /// - private struct NodeParseInfo - { - private NodeParser m_parseFunction; - public readonly SymbolDict<(FieldParser, object)> FieldDefs; - - public NodeParseInfo(NodeParser parseFunction) - : this(parseFunction, null) - { } - - public NodeParseInfo( - SymbolDict<(FieldParser, object)> fields) - : this(null, fields) - { } - - public NodeParseInfo( - NodeParser parseFunction, - SymbolDict<(FieldParser, object)> fields) - { - m_parseFunction = parseFunction; - FieldDefs = fields; - } - - public NodeParser NodeParser { get { return m_parseFunction; } } - - public FieldParser FieldParser(string fieldName) - { - if (fieldName == "ROUTE") return new FieldParser(ParseROUTE); - return FieldDefs[fieldName].Item1; - } - - public bool TryGetFieldParser(string fieldName, out FieldParser fieldParser) - { - if (fieldName == "ROUTE") - { - fieldParser = new FieldParser(ParseROUTE); - return true; - } - if (FieldDefs.TryGetValue(fieldName, out var fpDef)) - { - fieldParser = fpDef.Item1; - return true; - } - fieldParser = null; - return false; - } - - public object DefaultValue(string fieldName) - { - return FieldDefs[fieldName].Item2; - } - } - - private static SymMapBase ParseGenericNode(Tokenizer t, NodeParseInfo info) - { - var result = new SymMapBase(); - ExpectBraceOpen(t); - - // populate fields with default values - foreach (var kvp in info.FieldDefs) - { - if (kvp.Value.Item2 == null) continue; - result[kvp.Key] = kvp.Value.Item2; - } - - Tokenizer.Token token = t.NextToken(); - while (!token.IsBraceClose) - { - string fieldName = token.ToString(); - if (info.TryGetFieldParser(fieldName, out var fp)) - result[fieldName] = fp(t); - else - Report.Warn($"[Vrml97] FieldParser: \"{fieldName}\" unknown/unexpected token!"); - - token = t.NextToken(); - Thread.Sleep(0); - } - - return result; - } - - private static SymMapBase ParseUnknownNode(Tokenizer t) - { - ExpectBraceOpen(t); - var level = 1; - - var sb = new StringBuilder("{"); - - do - { - var token = t.NextToken(); - sb.Append(" " + token); - - if (token.IsBraceOpen) level++; - if (token.IsBraceClose) level--; - } - while (level > 0); - - var result = new SymMapBase(); - result["unknownNode"] = true; - result["content"] = sb.ToString(); - return result; - } - - #endregion - } -} diff --git a/src/Aardvark.Data.Vrml97/Tokenizer.cs b/src/Aardvark.Data.Vrml97/Tokenizer.cs deleted file mode 100644 index ccc09a7b..00000000 --- a/src/Aardvark.Data.Vrml97/Tokenizer.cs +++ /dev/null @@ -1,345 +0,0 @@ -using Aardvark.Base; -using System; -using System.Globalization; -using System.IO; -using System.Text; - -namespace Aardvark.Data.Vrml97 -{ - public class Tokenizer - { - public Tokenizer(Stream input) - { - m_in = input; - - m_bufferSize = 1024 * 32; - m_pos = m_bufferSize; - m_end = m_bufferSize; - - m_asyncResult = m_in.BeginRead( - m_asyncReadTarget, 0, NextBufferSize(), null, null - ); - } - - public void PushBack(Token t) - { - m_pushedBackToken = t; - m_pushedBackTokenValid = true; - } - - public Token NextNameToken() - { - var t = ""; - if (!NextNonWhiteSpaceChar(out int c)) return Token.EOF; - - // comment - while (c == '#') - { - if (!NextCharAfterEol(out c)) return Token.EOF; - if (IsWhiteSpace(c)) - { - if (!NextNonWhiteSpaceChar(out c)) return Token.EOF; - } - } - - // other token (number, etc.) - while (true) - { - t = Concat(t, c); - try - { - c = NextChar(); - } - catch (ArgumentOutOfRangeException) - { - return new Token(t); - } - - if (IsWhiteSpace(c)) return new Token(t); - } - } - - string Concat(string s, int c) - { - if (c < 0x0000ffff && (c < 0xD800 || c > 0xDFFF)) // check if single byte range with direct bit mapping - return s + (char)c; - else - return s + char.ConvertFromUtf32(c); - } - - public Token NextToken() - { - if (m_pushedBackTokenValid) - { - m_pushedBackTokenValid = false; - return m_pushedBackToken; - } - - var t = ""; - if (!NextNonWhiteSpaceChar(out int c)) return Token.EOF; - - // comment - while (c == '#') - { - if (!NextCharAfterEol(out c)) return Token.EOF; - if (IsWhiteSpace(c)) - { - if (!NextNonWhiteSpaceChar(out c)) return Token.EOF; - } - } - - // parenthesis - if (IsParenthesis(c)) return new Token(char.ConvertFromUtf32(c)); - - // string - if (c == '"') - { - t += '"'; - c = NextChar(); - while (c != '"') - { - t = Concat(t, c); - c = NextChar(); - } - t += '"'; - return new Token(t); - } - - // other token (number, etc.) - while (true) - { - t = Concat(t, c); - try - { - c = NextChar(); - } - catch (ArgumentOutOfRangeException) - { - return new Token(t); - } - - if (IsWhiteSpace(c)) return new Token(t); - - if (IsParenthesis(c) || c == '#') - { - PushBack((byte)c); - return new Token(t); - } - } - } - - public struct Token - { - public static readonly Token EOF = new Token(); - - public Token(string s) - { - m_data = s; - } - - public override string ToString() => m_data; - public Symbol ToSymbol() => m_data.ToSymbol(); - public int ToInt32() => Int32.Parse(m_data, m_format); - public uint ToUInt32() => UInt32.Parse(m_data, m_format); - public float ToFloat() => float.Parse(m_data, m_format); - public double ToDouble() => double.Parse(m_data, m_format); - public Int64 ToInt64() => Int64.Parse(m_data, m_format); - public bool ToBool() => m_data.ToUpper() == "TRUE"; - - public bool IsBraceOpen => m_data == "{"; - public bool IsBraceClose => m_data == "}"; - public bool IsBracketOpen => m_data == "["; - public bool IsBracketClose => m_data == "]"; - public bool IsQuotedString => m_data[0] == '"' && m_data[m_data.Length - 1] == '"'; - - /** - * Returns string without quotes, or - * throws exception if token is no quoted string. - **/ - public string GetCheckedUnquotedString() => IsQuotedString - ? m_data.Substring(1, m_data.Length - 2) - : throw new ParseException( - "Quoted string expected. Found " + m_data + " instead!" - ); - - private string m_data; - private static IFormatProvider m_format = new CultureInfo("en-US", false); - } - - - private bool Eof() => (m_bufferSize == 0) || (m_end < m_bufferSize && m_pos == m_end); - - private bool IsWhiteSpace(int c) - { - switch (c) - { - case ' ': - case ',': - case '\t': - case '\r': - case '\n': - return true; - default: - return false; - } - } - - private bool IsParenthesis(int c) - { - switch (c) - { - case '(': - case ')': - case '[': - case ']': - case '{': - case '}': - return true; - default: - return false; - } - } - - private Stream m_in; - - /// get next character using UTF-32 encoding - private int NextChar() - { - if (m_pushedBackValid) - { - m_pushedBackValid = false; - return m_pushedBack; - } - - int res = NextByte(); - if (res > 0x7f) // not ASCII (msb is: 1XXX XXXX) - { - // check how many surrogate bytes there are - if ((res & 0x20) != 0) // more than 2 byte (bit 6 set: XX1X XXXX) - { - if ((res & 0x10) != 0) // 4 byte (bit 5 set: XXX1 XXXX) - { - int b2 = NextByte(); - int b3 = NextByte(); - int b4 = NextByte(); - // 3 bits from first + 6 bits from second + 6 bits from third + 6 bits from fourth - res = ((res & 0x07) << 188) | ((b2 & 0x3f) << 12) | ((b3 & 0x3f) << 6) | (b4 & 0x3f); - } - else // 3 byte - { - int b2 = NextByte(); - int b3 = NextByte(); - // 4 bits from first + 6 bits from second + 6 bits from third - res = ((res & 0x0f) << 12) | ((b2 & 0x3f) << 6) | (b3 & 0x3f); - } - } - else // 2 byte - { - int b2 = NextByte(); - // 5 bits from first + 6 bits from second - res = ((res & 0x1f) << 6) | (b2 & 0x3f); - } - } - return res; - } - - private byte NextByte() - { - if (m_pos >= m_bufferSize) - { - m_end = m_in.EndRead(m_asyncResult); - m_bufferSize = m_end; - m_pos = 0; - - SwapBuffers(); - if (m_end == 0) return (byte)' '; // no more data - m_asyncResult = m_in.BeginRead( - m_asyncReadTarget, 0, s_bufferSize, null, null - ); - } - - m_streamPos++; - return m_buffer[m_pos++]; - } - - /** - * Gets next non-whitespace character from input stream. - * Returns true on success, or false on reaching eof. - **/ - private bool NextNonWhiteSpaceChar(out int c) - { - do - { - if (Eof()) - { - c = '\0'; - return false; - } - c = NextChar(); - } - while (IsWhiteSpace(c)); - return true; - } - - /** - * Gets next character after end of current line. - * Returns true on success, or false on reaching eof. - **/ - private bool NextCharAfterEol(out int c) - { - do - { - if (Eof()) - { - c = '\0'; - return false; - } - c = NextChar(); - } - while (c != '\n' && c != '\r'); - - while (c == '\n' || c == '\r') - { - if (Eof()) - { - c = '\0'; - return false; - } - c = NextChar(); - } - - return true; - } - - private void PushBack(byte c) - { - m_pushedBack = c; - m_pushedBackValid = true; - } - - private IAsyncResult m_asyncResult; - private static int s_bufferSize = 1024 * 64; - private int m_bufferSize; - private byte[] m_buffer = new byte[s_bufferSize]; - private byte[] m_asyncReadTarget = new byte[s_bufferSize]; - private int m_pushedBack; - private bool m_pushedBackValid = false; - private int m_pos; - private int m_end; - private long m_streamPos = 0; - Token m_pushedBackToken; - bool m_pushedBackTokenValid = false; - - private int NextBufferSize() => (m_bufferSize == s_bufferSize) - ? s_bufferSize - : Math.Min(m_bufferSize + m_bufferSize, s_bufferSize) - ; - - private void SwapBuffers() - { - var tmp = m_buffer; - m_buffer = m_asyncReadTarget; - m_asyncReadTarget = tmp; - } - } -} diff --git a/src/Aardvark.Data.Vrml97/Vrml97Ifs.cs b/src/Aardvark.Data.Vrml97/Vrml97Ifs.cs deleted file mode 100644 index 33ddcdfc..00000000 --- a/src/Aardvark.Data.Vrml97/Vrml97Ifs.cs +++ /dev/null @@ -1,50 +0,0 @@ -using Aardvark.Base; -using System.Collections.Generic; -using System.Linq; - -namespace Aardvark.Data.Vrml97 -{ - /// - /// IndexedFaceSet. - /// - public class Vrml97Ifs - { - /// - /// Constructor. - /// - public Vrml97Ifs(SymMapBase parseTree) => m_parseTree = parseTree; - - /// - /// Raw parse tree. - /// - public SymMapBase ParseTree => m_parseTree; - - /// - /// Single texture. - /// - public string TextureFileName - { - get - { - var texnode = m_parseTree.Get(Vrml97Sym.texture); - if (texnode == null) return null; - return texnode.Get>(Vrml97Sym.url).FirstOrDefault(); - } - } - - /// - /// Multiple textures. - /// - public List TextureFileNames - { - get - { - var texnode = m_parseTree.Get(Vrml97Sym.texture); - if (texnode == null) return null; - return texnode.Get>(Vrml97Sym.url); - } - } - - private SymMapBase m_parseTree; - } -} diff --git a/src/Aardvark.Data.Vrml97/Vrml97Ils.cs b/src/Aardvark.Data.Vrml97/Vrml97Ils.cs deleted file mode 100644 index 58fdafe8..00000000 --- a/src/Aardvark.Data.Vrml97/Vrml97Ils.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Aardvark.Base; - -namespace Aardvark.Data.Vrml97 -{ - /// - /// IndexedLineSet. - /// - public class Vrml97Ils - { - /// - /// Constructor. - /// - public Vrml97Ils(SymMapBase parseTree) => m_parseTree = parseTree; - - /// - /// Raw parse tree. - /// - public SymMapBase ParseTree => m_parseTree; - - private SymMapBase m_parseTree; - } -} diff --git a/src/Aardvark.Data.Vrml97/Vrml97Scene.cs b/src/Aardvark.Data.Vrml97/Vrml97Scene.cs deleted file mode 100644 index cc750a2d..00000000 --- a/src/Aardvark.Data.Vrml97/Vrml97Scene.cs +++ /dev/null @@ -1,175 +0,0 @@ -using Aardvark.Base; -using System.Collections.Generic; -using System.IO; -using System.IO.Compression; - -namespace Aardvark.Data.Vrml97 -{ - /// - /// A complete VRML97 scene. - /// - public class Vrml97Scene - { - private SymMapBase m_parseTree; - private Dictionary m_namedNodes; - - /// - /// Creates a Vrml97Scene from given VRML97 file. - /// Supports text based and Gzip compressed files. - /// Gzip is detected independent of the file extension by checking if the file contains a gzip header. - /// - public static Vrml97Scene FromFile(string fileName) => FromFile(fileName, true, true); - - /// - /// Creates a Vrml97Scene from given VRML97 file. - /// Supports text based and Gzip compressed files. - /// Gzip is detected independent of the file extension by checking if the file contains a gzip header. - /// - /// file name - /// - /// - /// - /// Parsed Vrml97 scene - public static Vrml97Scene FromFile(string fileName, bool resolveDefUse, bool annotate, bool duplicateDefUseMaps = true) - { - if (fileName == null) return null; - using var fileStream = new FileStream( - fileName, - FileMode.Open, FileAccess.Read, FileShare.Read, - 4096, false - ); - if (fileStream.Length < 2) - { - Report.Warn("[Vrml97] File empty or does not contain any valid Vrml97 content!"); - return null; - } - - // check if file is gzip compressed: 10 byte header starts with: 1f 8b - var h1 = fileStream.ReadByte(); - var h2 = fileStream.ReadByte(); - fileStream.Position = 0; - - var inputStream = h1 == 0x1f && h2 == 0x8b ? (Stream)new GZipStream(fileStream, CompressionMode.Decompress, true) : fileStream; - return Parse(new Parser.State(inputStream, fileName), resolveDefUse, annotate, duplicateDefUseMaps); - } - - /// - /// Creates a Vrml97Scene from given stream. - /// - /// Stream of a vrml97 file - /// Optional filename used to build absolute texture file paths - /// Parsed Vrml97 scene - public static Vrml97Scene FromStream(Stream stream, string fileName) - => Parse(new Parser.State(stream, fileName), true, true); - - /// - /// Constructor. - /// - public Vrml97Scene(SymMapBase parseTree) => m_parseTree = parseTree; - - /// - /// Raw parse tree. - /// - public SymMapBase ParseTree - { - get { return m_parseTree; } - internal set { m_parseTree = value; } - } - - /// - /// Enumerates all IndexedFaceSets in scene. - /// - public IEnumerable IndexedFaceSets - { - get - { - foreach (var x - in SymMapBaseCollectionTraversal.Collect(ParseTree, "IndexedFaceSet")) - yield return new Vrml97Ifs(x); - } - } - - /// - /// Enumerates all IndexedLineSets in scene. - /// - public IEnumerable IndexedLineSets - { - get - { - foreach (var x - in SymMapBaseCollectionTraversal.Collect(ParseTree, "IndexedLineSet")) - yield return new Vrml97Ils(x); - } - } - - /// - /// Enumerates all PositionInterpolators in scene. - /// - public IEnumerable PositionInterpolators - { - get - { - foreach (var x - in SymMapBaseCollectionTraversal.Collect(ParseTree, "PositionInterpolator")) - yield return x; - } - } - - /// - /// Enumerates all OrientationInterpolators in scene. - /// - public IEnumerable OrientationInterpolators - { - get - { - foreach (var x - in SymMapBaseCollectionTraversal.Collect(ParseTree, "OrientationInterpolator")) - yield return x; - } - } - - /// - /// Enumerates all PointSets in scene. - /// - public IEnumerable PointSets - { - get - { - foreach (var x - in SymMapBaseCollectionTraversal.Collect(ParseTree, "PointSet")) - yield return x; - } - } - - /// - /// Enumerates all TimeSensors in scene. - /// - public IEnumerable TimeSensor - { - get - { - foreach (var x - in SymMapBaseCollectionTraversal.Collect(ParseTree, "TimeSensor")) - yield return x; - } - } - - /// - /// Returns dictionary containing all named nodes in the scene. - /// - public Dictionary NamedNodes => m_namedNodes; - - private static Vrml97Scene Parse(Parser.State parser, bool resolveDefUse, bool annotate, bool duplicateMaps = true) - { - var root = parser.Perform(); - - if (resolveDefUse) - root = DefUseResolver.Resolve(root, out root.m_namedNodes, duplicateMaps); - - if (annotate) - root = AttributeAnnotator.Annotate(root); - - return root; - } - } -} diff --git a/src/Aardvark.Data.Vrml97/paket.references b/src/Aardvark.Data.Vrml97/paket.references deleted file mode 100644 index 26df63c3..00000000 --- a/src/Aardvark.Data.Vrml97/paket.references +++ /dev/null @@ -1 +0,0 @@ -Aardvark.Build \ No newline at end of file diff --git a/src/Aardvark.Data.Vrml97/paket.template b/src/Aardvark.Data.Vrml97/paket.template deleted file mode 100644 index 1d42f3fb..00000000 --- a/src/Aardvark.Data.Vrml97/paket.template +++ /dev/null @@ -1,11 +0,0 @@ -type project -id Aardvark.Data.Vrml97 -authors Aardvark Platform Team -owners Aardvark Platform Team -projectUrl http://github.com/aardvark-platform -licenseUrl http://www.apache.org/licenses/LICENSE-2.0.txt -repositoryType git -repositoryUrl https://github.com/aardvark-platform/aardvark.base -description - Aardvark is an open-source platform for visual computing, real-time graphics and visualization. -include-pdbs true \ No newline at end of file diff --git a/src/Aardvark.NonWindows.slnf b/src/Aardvark.NonWindows.slnf deleted file mode 100644 index 7c9f3119..00000000 --- a/src/Aardvark.NonWindows.slnf +++ /dev/null @@ -1,32 +0,0 @@ -{ - "solution": { - "path": "Aardvark.sln", - "projects": [ - "Aardvark.Base.Essentials\\Aardvark.Base.Essentials.csproj", - "Aardvark.Base.FSharp\\Aardvark.Base.FSharp.fsproj", - "Aardvark.Base.IO\\Aardvark.Base.IO.csproj", - "Aardvark.Base.Incremental\\Aardvark.Base.Incremental.fsproj", - "Aardvark.Base.Runtime\\Aardvark.Base.Runtime.fsproj", - "Aardvark.Base.Telemetry\\Aardvark.Base.Telemetry.csproj", - "Aardvark.Base.Tensors.CSharp\\Aardvark.Base.Tensors.CSharp.csproj", - "Aardvark.Base.Tensors\\Aardvark.Base.Tensors.fsproj", - "Aardvark.Base\\Aardvark.Base.csproj", - "Aardvark.Data.Vrml97\\Aardvark.Data.Vrml97.csproj", - "Aardvark.Geometry\\Aardvark.Geometry.fsproj", - "Aardvark.PixImage.DevIL\\Aardvark.PixImage.DevIL.csproj", - "CodeGenerator\\CodeGenerator.csproj", - "Demo\\CoreTest\\CoreTest.fsproj", - "Demo\\ExamplesCSharp\\ExamplesCSharp.csproj", - "Demo\\IncrementalDemo.CSharp\\IncrementalDemo.CSharp.csproj", - "Demo\\PixImageDemo\\PixImageDemo.csproj", - "Demo\\RandomSampleDemo\\RandomSampleDemo.csproj", - "Demo\\Scratch\\Scratch.fsproj", - "Tests\\Aardvark.Base.Benchmarks\\Aardvark.Base.Benchmarks.csproj", - "Tests\\Aardvark.Base.FSharp.Benchmarks\\Aardvark.Base.FSharp.Benchmarks.fsproj", - "Tests\\Aardvark.Base.FSharp.Tests\\Aardvark.Base.FSharp.Tests.fsproj", - "Tests\\Aardvark.Base.Runtime.Tests\\Aardvark.Base.Runtime.Tests.fsproj", - "Tests\\Aardvark.Base.Tests\\Aardvark.Base.Tests.csproj", - "Tests\\Aardvark.Geometry.Tests\\Aardvark.Geometry.Tests.fsproj" - ] - } -} \ No newline at end of file diff --git a/src/Aardvark.PixImage.DevIL/Aardvark.PixImage.DevIL.csproj b/src/Aardvark.PixImage.DevIL/Aardvark.PixImage.DevIL.csproj deleted file mode 100644 index 539dfc6b..00000000 --- a/src/Aardvark.PixImage.DevIL/Aardvark.PixImage.DevIL.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - netstandard2.0 - true - 1591 - - - - - - - \ No newline at end of file diff --git a/src/Aardvark.PixImage.DevIL/PixImageDevil.cs b/src/Aardvark.PixImage.DevIL/PixImageDevil.cs deleted file mode 100644 index c7a34fa1..00000000 --- a/src/Aardvark.PixImage.DevIL/PixImageDevil.cs +++ /dev/null @@ -1,371 +0,0 @@ -using System; -using System.Threading; -using System.Collections.Generic; -using System.IO; - -using System.Runtime.InteropServices; -using Devil = DevILSharp; -using DevILSharp; - -namespace Aardvark.Base -{ - using I = DevILSharp.IL; - - public static class PixImageDevil - { - private static readonly object s_devilLock = new object(); - private static bool s_initialized = false; - - [OnAardvarkInit] - public static void InitDevil() - { - try - { - lock (s_devilLock) - { - if (s_initialized) - return; - - Bootstrap.Init(); - I.Init(); - I.Enable(EnableCap.AbsoluteOrigin); - I.OriginFunc(OriginMode.UpperLeft); - I.Enable(EnableCap.OverwriteExistingFile); - I.Enable(EnableCap.ConvertPalette); - - PixImage.AddLoader(Loader); - - s_initialized = true; - } - } - catch(Exception e) - { - Report.Warn("[PixImageDevil] could not InitDevil: {0}", e.Message); - } - } - - static PixImageDevil() - { - InitDevil(); - } - - private static readonly Dictionary s_pixColorFormats = new Dictionary() - { - {Devil.ChannelFormat.Alpha, Col.Format.Alpha}, - {Devil.ChannelFormat.BGR, Col.Format.BGR}, - {Devil.ChannelFormat.BGRA, Col.Format.BGRA}, - {Devil.ChannelFormat.ColorIndex, Col.Format.None}, - {Devil.ChannelFormat.Luminance, Col.Format.Gray}, - {Devil.ChannelFormat.LuminanceAlpha, Col.Format.GrayAlpha}, - {Devil.ChannelFormat.RGB, Col.Format.RGB}, - {Devil.ChannelFormat.RGBA, Col.Format.RGBA}, - }; - - private static readonly Dictionary s_pixDataTypes = new Dictionary() - { - {Devil.ChannelType.Byte, typeof(sbyte)}, - {Devil.ChannelType.Short, typeof(short)}, - {Devil.ChannelType.Int, typeof(int)}, - {Devil.ChannelType.UnsignedByte, typeof(byte)}, - {Devil.ChannelType.UnsignedShort, typeof(ushort)}, - {Devil.ChannelType.UnsignedInt, typeof(uint)}, - {Devil.ChannelType.Float, typeof(float)}, - {Devil.ChannelType.Double, typeof(double)}, - }; - - private static readonly Dictionary s_devilDataTypes = new Dictionary() - { - {typeof(sbyte), Devil.ChannelType.Byte}, - {typeof(short), Devil.ChannelType.Short}, - {typeof(int), Devil.ChannelType.Int}, - {typeof(byte), Devil.ChannelType.UnsignedByte}, - {typeof(ushort), Devil.ChannelType.UnsignedShort}, - {typeof(uint), Devil.ChannelType.UnsignedInt}, - {typeof(float), Devil.ChannelType.Float}, - {typeof(double), Devil.ChannelType.Double}, - }; - - private static readonly Dictionary s_devilColorFormats = new Dictionary() - { - { Col.Format.RGB, Devil.ChannelFormat.RGB }, - { Col.Format.RGBA, Devil.ChannelFormat.RGBA }, - { Col.Format.BGR, Devil.ChannelFormat.BGR }, - { Col.Format.BGRA, Devil.ChannelFormat.BGRA }, - { Col.Format.Gray, Devil.ChannelFormat.Luminance }, - { Col.Format.GrayAlpha, Devil.ChannelFormat.LuminanceAlpha }, - }; - - private static readonly Dictionary s_fileFormats = new Dictionary() - { - {PixFileFormat.Bmp, Devil.ImageType.Bmp}, - {PixFileFormat.Cut, Devil.ImageType.Cut}, - {PixFileFormat.Dds, Devil.ImageType.Dds}, - {PixFileFormat.Exr, Devil.ImageType.Exr0}, - {PixFileFormat.Gif, Devil.ImageType.Gif}, - {PixFileFormat.Hdr, Devil.ImageType.Hdr}, - {PixFileFormat.Ico, Devil.ImageType.Ico}, - {PixFileFormat.Iff, Devil.ImageType.Iff0}, - {PixFileFormat.Jng, Devil.ImageType.Jng}, - {PixFileFormat.Jp2, Devil.ImageType.Jp20}, - {PixFileFormat.Jpeg, Devil.ImageType.Jpg}, - {PixFileFormat.Mng, Devil.ImageType.Mng}, - {PixFileFormat.Pcd, Devil.ImageType.Pcd}, - {PixFileFormat.Pcx, Devil.ImageType.Pcx}, - {PixFileFormat.Pict, Devil.ImageType.Pic}, - {PixFileFormat.Png, Devil.ImageType.Png}, - {PixFileFormat.Psd, Devil.ImageType.Psd}, - {PixFileFormat.Raw, Devil.ImageType.Raw}, - {PixFileFormat.Sgi, Devil.ImageType.Sgi}, - {PixFileFormat.Targa, Devil.ImageType.Tga}, - {PixFileFormat.Tiff, Devil.ImageType.Tif}, - {PixFileFormat.Wbmp, Devil.ImageType.WBmp}, - {PixFileFormat.Xpm, Devil.ImageType.Xpm}, - }; - - private class PixLoader : IPixLoader - { - public string Name => "DevIL"; - - private static void Fail(string call) - { - var status = I.GetError(); - throw new ImageLoadException($"IL.{call}() failed, error code = {status}."); - } - - private static T TemporaryImage(Func f) - { - var img = I.GenImage(); - I.BindImage(img); - - try - { - return f(img); - } - finally - { - I.BindImage(0); - I.DeleteImage(img); - } - } - - private static void TemporaryImage(Action f) - => TemporaryImage(img => { f(img); return 0; }); - - private static T LoadImage(Action loadData, Func parse) - { - lock (s_devilLock) - { - return TemporaryImage(img => - { - loadData(); - - var size = new V2i(I.GetInteger(IntName.ImageWidth), I.GetInteger(IntName.ImageHeight)); - var dataType = I.GetDataType(); - var format = I.GetFormat(); - var channels = I.GetInteger(IntName.ImageChannels); - - // try to get format information - if (!s_pixDataTypes.TryGetValue(dataType, out Type type)) - throw new ImageLoadException($"Unsupported channel type {dataType}."); - - if (!s_pixColorFormats.TryGetValue(format, out Col.Format fmt)) - throw new ImageLoadException($"Unsupported format {format}."); - - return parse(size, fmt, type, channels); - }); - } - } - - private static PixImage LoadPixImage(Action load) - => LoadImage(load, (size, format, type, channels) => - { - // if the image has a lower-left origin flip it - var mode = (OriginMode)I.GetInteger((IntName)0x0603); - if (mode == OriginMode.LowerLeft && !ILU.FlipImage()) - return null; - - // create an appropriate PixImage instance - var imageType = typeof(PixImage<>).MakeGenericType(type); - var pix = (PixImage)Activator.CreateInstance(imageType, format, size, channels); - - // copy the data to the PixImage - var gc = GCHandle.Alloc(pix.Data, GCHandleType.Pinned); - try - { - var ptr = I.GetData(); - ptr.CopyTo(pix.Data, 0, pix.Data.Length); - return pix; - } - finally - { - gc.Free(); - } - }); - - private static void IlLoadImage(string filename) - { - if (!I.LoadImage(filename)) - Fail("LoadImage"); - } - - private static void IlLoadStream(Stream stream) - { - if (!I.LoadStream(stream)) - Fail("LoadStream"); - } - - public PixImage LoadFromFile(string filename) - => LoadPixImage(() => IlLoadImage(filename)); - - public PixImage LoadFromStream(Stream stream) - => LoadPixImage(() => IlLoadStream(stream)); - - private static void SaveImage(PixImage image, PixSaveParams saveParams, string saveMethod, Func save) - { - if (!s_fileFormats.TryGetValue(saveParams.Format, out ImageType imageType)) - throw new NotSupportedException($"Unsupported PixImage file format {saveParams.Format}."); - - lock (s_devilLock) - { - TemporaryImage(img => - { - if (!s_devilDataTypes.TryGetValue(image.PixFormat.Type, out ChannelType type)) - throw new NotSupportedException($"Unsupported PixFormat type {image.PixFormat.Type}."); - - if (!s_devilColorFormats.TryGetValue(image.PixFormat.Format, out ChannelFormat fmt)) - throw new NotSupportedException($"Unsupported Col.Format {image.PixFormat.Format}."); - - var gc = GCHandle.Alloc(image.Data, GCHandleType.Pinned); - try - { - if (!I.TexImage(image.Size.X, image.Size.Y, 1, (byte)image.ChannelCount, fmt, type, gc.AddrOfPinnedObject())) - Fail("TexImage"); - - I.RegisterOrigin(OriginMode.UpperLeft); - - if (saveParams is PixJpegSaveParams jpeg) - I.SetInteger(IntName.JpgQuality, jpeg.Quality); - - if (saveParams is PixPngSaveParams png) - { - if (png.CompressionLevel != PixPngSaveParams.DefaultCompressionLevel) - Report.Warn("DevIL does not support setting PNG compression levels."); - } - - if (!save(imageType)) - { - var status = I.GetError(); - - if (status == ErrorCode.InvalidEnum) - throw new NotSupportedException($"DevIL does not support saving {imageType} images."); - else - throw new ImageLoadException($"IL.{saveMethod}() failed, error code = {status}."); - } - } - finally - { - gc.Free(); - } - }); - } - } - - public void SaveToFile(string filename, PixImage image, PixSaveParams saveParams) - => SaveImage(image, saveParams, "Save", imageType => I.Save(imageType, filename)); - - public void SaveToStream(Stream stream, PixImage image, PixSaveParams saveParams) - { - if (saveParams.Format == PixFileFormat.Tiff) - { - // Not sure why... - throw new NotSupportedException("DevIL does not support saving TIFF images to streams."); - } - else - { - SaveImage(image, saveParams, "SaveStream", imageType => I.SaveStream(imageType, stream)); - } - } - - private static PixImageInfo LoadPixImageInfo(Action load) - => LoadImage(load, (size, format, type, _) => - new PixImageInfo(new PixFormat(type, format), size) - ); - - public PixImageInfo GetInfoFromFile(string filename) - => LoadPixImageInfo(() => IlLoadImage(filename)); - - public PixImageInfo GetInfoFromStream(Stream stream) - => LoadPixImageInfo(() => IlLoadStream(stream)); - } - - public static readonly IPixLoader Loader = new PixLoader(); - - /// - /// Load image from stream via devil. - /// - /// If file could not be read, returns null, otherwise a Piximage. - [Obsolete("Use PixImage.LoadRaw() with DevIL.Loader")] - public static PixImage CreateRawDevil( - Stream stream, - PixLoadOptions loadFlags = PixLoadOptions.Default) - => PixImage.LoadRaw(stream, Loader); - - /// - /// Load image from stream via devil. - /// - /// If file could not be read, returns null, otherwise a Piximage. - [Obsolete("Use PixImage.LoadRaw() with DevIL.Loader")] - public static PixImage CreateRawDevil( - string fileName, - PixLoadOptions loadFlags = PixLoadOptions.Default) - => PixImage.LoadRaw(fileName, Loader); - - /// - /// Save image to stream via devil. - /// - /// True if the file was successfully saved. - [Obsolete("Use PixImage.Save() or PixImage.SaveAsJpeg() with DevIL.Loader")] - public static bool SaveAsImageDevil( - this PixImage image, - Stream stream, PixFileFormat format, - PixSaveOptions options, int qualityLevel) - { - if (format == PixFileFormat.Jpeg) - image.SaveAsJpeg(stream, qualityLevel); - else - image.Save(stream, format); - - return true; - } - - [Obsolete("Use PixImage.Save() or PixImage.SaveAsJpeg() with DevIL.Loader")] - public static bool SaveAsImageDevil( - this PixImage image, - string file, PixFileFormat format, - PixSaveOptions options, int qualityLevel) - { - var normalizeFilename = ((options & PixSaveOptions.NormalizeFilename) != 0); - - if (format == PixFileFormat.Jpeg) - image.SaveAsJpeg(file, qualityLevel, normalizeFilename); - else - image.Save(file, format, normalizeFilename); - - return true; - } - - /// - /// Gets info about a PixImage without loading the entire image into memory. - /// - /// null if the file info could not be loaded. - [Obsolete("Use PixImage.GetInfoFromFile() with DevIL.Loader")] - public static PixImageInfo InfoFromFileNameDevil( - string fileName, PixLoadOptions options) - => PixImage.GetInfoFromFile(fileName, Loader); - - - [Obsolete("Use PixImage.AddLoader with DevIL.Loader to modify priority")] - public static void AddLoaders() - => PixImage.AddLoader(Loader); - } -} diff --git a/src/Aardvark.PixImage.DevIL/paket.references b/src/Aardvark.PixImage.DevIL/paket.references deleted file mode 100644 index df5b5888..00000000 --- a/src/Aardvark.PixImage.DevIL/paket.references +++ /dev/null @@ -1,2 +0,0 @@ -Aardvark.Build -DevILSharp \ No newline at end of file diff --git a/src/Aardvark.PixImage.DevIL/paket.template b/src/Aardvark.PixImage.DevIL/paket.template deleted file mode 100644 index 6e6ac276..00000000 --- a/src/Aardvark.PixImage.DevIL/paket.template +++ /dev/null @@ -1,14 +0,0 @@ -type project -id Aardvark.PixImage.DevIL -authors Aardvark Platform Team -owners Aardvark Platform Team -projectUrl http://github.com/aardvark-platform -licenseUrl http://www.apache.org/licenses/LICENSE-2.0.txt -repositoryType git -repositoryUrl https://github.com/aardvark-platform/aardvark.base -description - Aardvark is an open-source platform for visual computing, real-time graphics and visualization. -include-pdbs true -dependencies - framework: netstandard2.0 - DevILSharp \ No newline at end of file diff --git a/src/Aardvark.PixImage.SystemDrawing/Aardvark.PixImage.SystemDrawing.csproj b/src/Aardvark.PixImage.SystemDrawing/Aardvark.PixImage.SystemDrawing.csproj deleted file mode 100644 index 1a788c4a..00000000 --- a/src/Aardvark.PixImage.SystemDrawing/Aardvark.PixImage.SystemDrawing.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - Library - netstandard2.0 - 9.0 - true - 1591 - - - ..\..\bin\Debug - - - ..\..\bin\Release - - - - - - - \ No newline at end of file diff --git a/src/Aardvark.PixImage.SystemDrawing/PixImageBitmap.cs b/src/Aardvark.PixImage.SystemDrawing/PixImageBitmap.cs deleted file mode 100644 index b96eae19..00000000 --- a/src/Aardvark.PixImage.SystemDrawing/PixImageBitmap.cs +++ /dev/null @@ -1,250 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Linq; - -namespace Aardvark.Base -{ - /// - /// Contains Windows-only extensions for converting to and from bitmaps, as well as saving images to files and streams. - /// - public static class PixImageSystemDrawing - { - #region Private - - private static readonly Dictionary s_pixFormatAndCountOfPixelFormatBitmap = - new Dictionary() - { - { PixelFormat.Format1bppIndexed, (PixFormat.ByteBW, 1) }, - { PixelFormat.Format8bppIndexed, (PixFormat.ByteBW, 1) }, - - { PixelFormat.Format16bppGrayScale, (PixFormat.UShortGray, 1) }, - - { PixelFormat.Format24bppRgb, (PixFormat.ByteBGR, 3) }, - { PixelFormat.Format32bppRgb, (PixFormat.ByteBGR, 4) }, - { PixelFormat.Format32bppArgb, (PixFormat.ByteBGRA, 4) }, - { PixelFormat.Format32bppPArgb, (PixFormat.ByteBGRP, 4) }, - - { PixelFormat.Format48bppRgb, (PixFormat.UShortBGR, 3) }, - { PixelFormat.Format64bppArgb, (PixFormat.UShortBGRA, 4) }, - { PixelFormat.Format64bppPArgb, (PixFormat.UShortBGRP, 4) }, - - }; - - private static readonly Dictionary s_bitmapLockFormats = new Dictionary() - { - { PixelFormat.Format16bppArgb1555, PixelFormat.Format32bppArgb }, - { PixelFormat.Format16bppRgb555, PixelFormat.Format24bppRgb }, - { PixelFormat.Format16bppRgb565, PixelFormat.Format24bppRgb }, - { PixelFormat.Format4bppIndexed, PixelFormat.Format8bppIndexed } - }; - - private static readonly Dictionary s_pixelFormats = - new Dictionary() - { - { PixFormat.ByteRGB, PixelFormat.Format24bppRgb }, - { PixFormat.ByteBGR, PixelFormat.Format24bppRgb }, - { PixFormat.ByteBGRA, PixelFormat.Format32bppArgb }, - { PixFormat.ByteBW, PixelFormat.Format8bppIndexed }, - { PixFormat.ByteRGBP, PixelFormat.Format32bppPArgb }, - { PixFormat.UShortGray, PixelFormat.Format16bppGrayScale }, - { PixFormat.UShortBGR, PixelFormat.Format48bppRgb }, - { PixFormat.UShortBGRA, PixelFormat.Format64bppArgb }, - { PixFormat.UShortBGRP, PixelFormat.Format64bppPArgb }, - }; - - private static readonly Dictionary s_imageFormats = - new Dictionary() - { - {PixFileFormat.Bmp, ImageFormat.Bmp}, - {PixFileFormat.Gif, ImageFormat.Gif}, - {PixFileFormat.Jpeg, ImageFormat.Jpeg}, - {PixFileFormat.Png, ImageFormat.Png}, - {PixFileFormat.Tiff, ImageFormat.Tiff}, - {PixFileFormat.Wmp, ImageFormat.Wmf}, - }; - - private static readonly Dictionary s_imageCodecInfos = - ImageCodecInfo.GetImageEncoders().ToDictionary(c => c.FormatID); - - private static PixelFormat GetLockFormat(PixelFormat format) - => s_pixFormatAndCountOfPixelFormatBitmap.ContainsKey(format) ? format : s_bitmapLockFormats[format]; - - private static PixImage CreateRawBitmap(Bitmap bitmap) - { - var sdipf = GetLockFormat(bitmap.PixelFormat); - var pfc = s_pixFormatAndCountOfPixelFormatBitmap[sdipf]; - - var sx = bitmap.Width; - var sy = bitmap.Height; - var ch = pfc.Item2; - - var pixImage = PixImage.Create(pfc.Item1, sx, sy, ch); - var array = pixImage.Array; - - if (pfc.Item1.Format == Col.Format.BW) - { - var bitImage = new PixImage(Col.Format.BW, 1 + (sx - 1) / 8, sy, 1); - - var bdata = bitmap.LockBits( - new Rectangle(0, 0, sx, sy), - ImageLockMode.ReadOnly, sdipf); - - bdata.Scan0.CopyTo(bitImage.Volume.Data); - - bitmap.UnlockBits(bdata); - PixImage.ExpandPixels(bitImage, pixImage.ToPixImage()); - } - else - { - var bdata = bitmap.LockBits( - new Rectangle(0, 0, sx, sy), - ImageLockMode.ReadOnly, sdipf); - - bdata.Scan0.CopyTo(array); - bitmap.UnlockBits(bdata); - } - return pixImage; - } - - /// - /// Creates PixImage from System.Drawing.Bitmap. - /// - private static PixImage Create(Bitmap bitmap) - { - var loadImage = CreateRawBitmap(bitmap); - return loadImage.ToPixImage(loadImage.Format); - } - - /// - /// Creates PixImage from System.Drawing.Image. - /// - private static PixImage Create(Image image) => Create((Bitmap)image); - - #endregion - - /// - /// Creates PixImage from System.Drawing.Bitmap. - /// - public static PixImage ToPixImage(this Bitmap bitmap) => Create(bitmap); - - /// - /// Creates PixImage from System.Drawing.Image. - /// - public static PixImage ToPixImage(this Image image) => Create(image); - - /// - /// Converts image to System.Drawing.Image. - /// - public static Bitmap ToSystemDrawingBitmap(this PixImage self) - => new Bitmap(self.ToMemoryStream(PixFileFormat.Png), false); - - /// - /// Saves image to stream via System.Drawing. - /// - /// The image to save. - /// The stream to save the image to. - /// The save parameters to use. - /// true on success, false otherwise. - public static bool SaveViaSystemDrawing(this PixImage self, Stream stream, PixSaveParams saveParams) - { - try - { - self = self.ToCanonicalDenseLayout(); - if (!s_pixelFormats.TryGetValue(self.PixFormat, out PixelFormat pixelFormat)) - Report.Error($"Unknown PixelFormat {self.PixFormat.Format}."); - - var imageFormat = s_imageFormats[saveParams.Format]; - - var size = self.Size; - using (var bmp = new Bitmap(size.X, size.Y, pixelFormat)) - { - var bdata = bmp.LockBits(new Rectangle(0, 0, size.X, size.Y), ImageLockMode.ReadOnly, pixelFormat); - self.Data.CopyTo(bdata.Scan0); - bmp.UnlockBits(bdata); - - int quality = - saveParams switch - { - PixJpegSaveParams jpeg => jpeg.Quality, - _ => -1 - }; - - if (quality >= 0) - { - var codec = s_imageCodecInfos[imageFormat.Guid]; - var parameters = new EncoderParameters(1); - parameters.Param[0] = new EncoderParameter(Encoder.Quality, quality); - bmp.Save(stream, codec, parameters); - parameters.Dispose(); - } - else - { - bmp.Save(stream, imageFormat); - } - } - - return true; - } - catch - { - return false; - } - } - - /// - /// Saves image to stream via System.Drawing. - /// - /// The image to save. - /// The stream to save the image to. - /// The image format of the stream. - /// true on success, false otherwise. - public static bool SaveViaSystemDrawing(this PixImage self, Stream stream, PixFileFormat fileFormat) - => self.SaveViaSystemDrawing(stream, new PixSaveParams(fileFormat)); - - /// - /// Saves image to stream via System.Drawing as JPEG. - /// - /// The image to save. - /// The stream to save the image to. - /// The quality of the JPEG file. Must be within 0 - 100. - /// true on success, false otherwise. - public static bool SaveViaSystemDrawingAsJpeg(this PixImage self, Stream stream, int quality = PixJpegSaveParams.DefaultQuality) - => self.SaveViaSystemDrawing(stream, new PixJpegSaveParams(quality)); - - /// - /// Saves image to file via System.Drawing. - /// - /// The image to save. - /// The file to save the image to. - /// The save parameters to use. - /// true on success, false otherwise. - public static bool SaveViaSystemDrawing(this PixImage self, string filename, PixSaveParams saveParams) - { - using var stream = File.OpenWrite(filename); - return SaveViaSystemDrawing(self, stream, saveParams); - } - - /// - /// Saves image to file via System.Drawing. - /// - /// The image to save. - /// The file to save the image to. - /// The image format of the stream. - /// true on success, false otherwise. - public static bool SaveViaSystemDrawing(this PixImage self, string filename, PixFileFormat fileFormat) - => self.SaveViaSystemDrawing(filename, new PixSaveParams(fileFormat)); - - /// - /// Saves image to file via System.Drawing as JPEG. - /// - /// The image to save. - /// The file to save the image to. - /// The quality of the JPEG file. Must be within 0 - 100. - /// true on success, false otherwise. - public static bool SaveViaSystemDrawingAsJpeg(this PixImage self, string filename, int quality = PixJpegSaveParams.DefaultQuality) - => self.SaveViaSystemDrawing(filename, new PixJpegSaveParams(quality)); - } -} diff --git a/src/Aardvark.PixImage.SystemDrawing/paket.references b/src/Aardvark.PixImage.SystemDrawing/paket.references deleted file mode 100644 index 81210d0d..00000000 --- a/src/Aardvark.PixImage.SystemDrawing/paket.references +++ /dev/null @@ -1,2 +0,0 @@ -Aardvark.Build -System.Drawing.Common \ No newline at end of file diff --git a/src/Aardvark.PixImage.SystemDrawing/paket.template b/src/Aardvark.PixImage.SystemDrawing/paket.template deleted file mode 100644 index d715f72e..00000000 --- a/src/Aardvark.PixImage.SystemDrawing/paket.template +++ /dev/null @@ -1,11 +0,0 @@ -type project -id Aardvark.PixImage.SystemDrawing -authors Aardvark Platform Team -owners Aardvark Platform Team -projectUrl http://github.com/aardvark-platform -licenseUrl http://www.apache.org/licenses/LICENSE-2.0.txt -repositoryType git -repositoryUrl https://github.com/aardvark-platform/aardvark.base -description - Aardvark is an open-source platform for visual computing, real-time graphics and visualization. -include-pdbs true \ No newline at end of file diff --git a/src/Aardvark.PixImage.WindowsMedia/Aardvark.PixImage.WindowsMedia.csproj b/src/Aardvark.PixImage.WindowsMedia/Aardvark.PixImage.WindowsMedia.csproj deleted file mode 100644 index 36f05787..00000000 --- a/src/Aardvark.PixImage.WindowsMedia/Aardvark.PixImage.WindowsMedia.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - - net6.0-windows7.0;net472 - 9.0 - true - true - - - ..\..\bin\Debug - - - ..\..\bin\Release - - - - - - - - - - \ No newline at end of file diff --git a/src/Aardvark.PixImage.WindowsMedia/PixImageWindowsMedia.cs b/src/Aardvark.PixImage.WindowsMedia/PixImageWindowsMedia.cs deleted file mode 100644 index e65bcd9d..00000000 --- a/src/Aardvark.PixImage.WindowsMedia/PixImageWindowsMedia.cs +++ /dev/null @@ -1,366 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using SdiPixelFormat = System.Drawing.Imaging.PixelFormat; - -namespace Aardvark.Base -{ - public static class PixImageWindowsMedia - { - [OnAardvarkInit] - public static void Init() - { - PixImage.AddLoader(Loader); - } - - #region PixelFormat extensions - - private static readonly Dictionary s_pixFormatAndCountOfPixelFormat = - new Dictionary() - { - { PixelFormats.Indexed1, (PixFormat.ByteBGRA, 4) }, - { PixelFormats.Indexed2, (PixFormat.ByteBGRA, 4) }, - { PixelFormats.Indexed4, (PixFormat.ByteBGRA, 4) }, - { PixelFormats.Indexed8, (PixFormat.ByteBGRA, 4) }, - - { PixelFormats.BlackWhite, (PixFormat.ByteBW, 1) }, - - { PixelFormats.Gray8, (PixFormat.ByteGray, 1) }, - { PixelFormats.Bgr24, (PixFormat.ByteBGR, 3) }, - { PixelFormats.Bgr32, (PixFormat.ByteBGR, 4) }, - { PixelFormats.Bgra32, (PixFormat.ByteBGRA, 4) }, - { PixelFormats.Pbgra32, (PixFormat.ByteBGRP, 4) }, - - { PixelFormats.Rgb24, (PixFormat.ByteRGB, 3) }, - - { PixelFormats.Gray16, (PixFormat.UShortGray, 1) }, - { PixelFormats.Rgb48, (PixFormat.UShortRGB, 3) }, - { PixelFormats.Rgba64, (PixFormat.UShortRGBA, 4) }, - { PixelFormats.Prgba64, (PixFormat.UShortRGBP, 4) }, - - { PixelFormats.Gray32Float, (PixFormat.FloatGray, 1) }, - { PixelFormats.Rgb128Float, (PixFormat.FloatRGB, 4) }, - { PixelFormats.Rgba128Float, (PixFormat.FloatRGBA, 4) }, - { PixelFormats.Prgba128Float, (PixFormat.FloatRGBP, 4) }, - }; - - private static (PixFormat, int) ToPixFormatAndCount(this PixelFormat pixelFormat) - { - if (s_pixFormatAndCountOfPixelFormat.TryGetValue(pixelFormat, out var result)) - return result; - - throw new ArgumentException($"Unsupported pixel format {pixelFormat}"); - } - - private static PixelFormat ToUnindexed(this PixelFormat pixelFormat) - { - if (pixelFormat == PixelFormats.Indexed1 || - pixelFormat == PixelFormats.Indexed2 || - pixelFormat == PixelFormats.Indexed4 || - pixelFormat == PixelFormats.Indexed8) - { - return PixelFormats.Bgra32; - } - else - { - return pixelFormat; - } - } - - public static PixFormat ToPixFormat(this PixelFormat pixelFormat) - => pixelFormat.ToPixFormatAndCount().Item1; - - #endregion - - #region System.Drawing.Bitmap extensions - - private static readonly Dictionary s_pixelFormatOfSdiPixelFormat = - new Dictionary() - { - { SdiPixelFormat.Format1bppIndexed, PixelFormats.BlackWhite }, - { SdiPixelFormat.Format16bppGrayScale, PixelFormats.Gray16 }, - - { SdiPixelFormat.Format24bppRgb, PixelFormats.Bgr24 }, - { SdiPixelFormat.Format32bppRgb, PixelFormats.Bgr32 }, - { SdiPixelFormat.Format32bppArgb, PixelFormats.Bgra32 }, - { SdiPixelFormat.Format32bppPArgb, PixelFormats.Pbgra32 }, - - { SdiPixelFormat.Format48bppRgb, PixelFormats.Rgb48 }, - { SdiPixelFormat.Format64bppArgb, PixelFormats.Rgba64 }, - { SdiPixelFormat.Format64bppPArgb, PixelFormats.Prgba64 }, - }; - - public static PixImage ToPixImageViaWindowsMedia(this System.Drawing.Bitmap bitmap) - { - if (!s_pixelFormatOfSdiPixelFormat.TryGetValue(bitmap.PixelFormat, out var pixelFormat)) - throw new ArgumentException($"Unsupported pixel format {bitmap.PixelFormat}"); - - var (pixFormat, ch) = pixelFormat.ToPixFormatAndCount(); - var sx = bitmap.Width; - var sy = bitmap.Height; - - var pixImage = PixImage.Create(pixFormat, sx, sy, ch); - - if (pixFormat.Format == Col.Format.BW) - { - var bitImage = new PixImage(Col.Format.BW, 1 + (sx - 1) / 8, sy, 1); - - var bdata = bitmap.LockBits( - new System.Drawing.Rectangle(0, 0, sx, sy), - System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmap.PixelFormat); - - var bmp = BitmapSource.Create( - sx, sy, - (double)bitmap.VerticalResolution, (double)bitmap.HorizontalResolution, pixelFormat, - null, bdata.Scan0, bitImage.Volume.Data.Length, bitImage.IntStride); - bmp.CopyPixels(bitImage.Array, bitImage.IntStride, 0); - bitmap.UnlockBits(bdata); - PixImage.ExpandPixels(bitImage, pixImage.ToPixImage()); - } - else - { - var bdata = bitmap.LockBits( - new System.Drawing.Rectangle(0, 0, sx, sy), - System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmap.PixelFormat); - var bmp = BitmapSource.Create( - sx, sy, - (double)bitmap.VerticalResolution, (double)bitmap.HorizontalResolution, - pixelFormat, - null, bdata.Scan0, ch * sx * sy, ch * sx); - bmp.CopyPixels(pixImage.Array, pixImage.IntStride, 0); - bitmap.UnlockBits(bdata); - } - - return pixImage; - } - - #endregion - - #region Static Tables and Methods - - private static readonly Dictionary> s_FormatEncoder = - new Dictionary>() - { - { PixFileFormat.Png, () => new PngBitmapEncoder() }, - { PixFileFormat.Bmp, () => new BmpBitmapEncoder() }, - { PixFileFormat.Jpeg, () => new JpegBitmapEncoder() }, - { PixFileFormat.Tiff, () => new TiffBitmapEncoder() }, - { PixFileFormat.Gif, () => new GifBitmapEncoder() }, - { PixFileFormat.Wmp, () => new WmpBitmapEncoder() } - }; - - private static BitmapEncoder GetEncoder(PixFileFormat format) - { - if (s_FormatEncoder.TryGetValue(format, out Func encCreator)) - return encCreator(); - - throw new ArgumentException($"Unsupported image file format {format}"); - } - - private static readonly Dictionary s_pixelFormatOfFormat = - new Dictionary() - { - { new PixFormat(typeof(byte), Col.Format.BW), (PixelFormats.BlackWhite, Col.Format.BW) }, - { new PixFormat(typeof(byte), Col.Format.Gray), (PixelFormats.Gray8, Col.Format.Gray) }, - { new PixFormat(typeof(byte), Col.Format.RGB), (PixelFormats.Bgr24, Col.Format.BGR) }, - { new PixFormat(typeof(byte), Col.Format.BGR), (PixelFormats.Bgr24, Col.Format.BGR) }, - { new PixFormat(typeof(byte), Col.Format.RGBA), (PixelFormats.Bgra32, Col.Format.BGRA) }, - { new PixFormat(typeof(byte), Col.Format.BGRA), (PixelFormats.Bgra32, Col.Format.BGRA) }, - { new PixFormat(typeof(byte), Col.Format.RGBP), (PixelFormats.Pbgra32, Col.Format.BGRP) }, - { new PixFormat(typeof(byte), Col.Format.BGRP), (PixelFormats.Pbgra32, Col.Format.BGRP) }, - - { new PixFormat(typeof(ushort), Col.Format.Gray), (PixelFormats.Gray16, Col.Format.Gray) }, - { new PixFormat(typeof(ushort), Col.Format.RGB), (PixelFormats.Rgb48, Col.Format.RGB) }, - { new PixFormat(typeof(ushort), Col.Format.BGR), (PixelFormats.Rgb48, Col.Format.RGB) }, - { new PixFormat(typeof(ushort), Col.Format.RGBA), (PixelFormats.Rgba64, Col.Format.RGBA) }, - { new PixFormat(typeof(ushort), Col.Format.BGRA), (PixelFormats.Rgba64, Col.Format.RGBA) }, - { new PixFormat(typeof(ushort), Col.Format.RGBP), (PixelFormats.Prgba64, Col.Format.RGBP) }, - { new PixFormat(typeof(ushort), Col.Format.BGRP), (PixelFormats.Prgba64, Col.Format.RGBP) }, - - { new PixFormat(typeof(float), Col.Format.Gray), (PixelFormats.Gray32Float, Col.Format.Gray) }, - { new PixFormat(typeof(float), Col.Format.RGB), (PixelFormats.Rgb128Float, Col.Format.RGBA) }, - { new PixFormat(typeof(float), Col.Format.BGR), (PixelFormats.Rgb128Float, Col.Format.RGBA) }, - { new PixFormat(typeof(float), Col.Format.RGBA), (PixelFormats.Rgba128Float, Col.Format.RGBA) }, - { new PixFormat(typeof(float), Col.Format.BGRA), (PixelFormats.Rgba128Float, Col.Format.RGBA) }, - { new PixFormat(typeof(float), Col.Format.RGBP), (PixelFormats.Prgba128Float, Col.Format.RGBP) }, - { new PixFormat(typeof(float), Col.Format.BGRP), (PixelFormats.Prgba128Float, Col.Format.RGBP) }, - }; - - private static (PixelFormat, Col.Format) GetStoreFormats(Type type, Col.Format format) - { - if (s_pixelFormatOfFormat.TryGetValue(new PixFormat(type, format), out (PixelFormat, Col.Format) formatPair)) - return formatPair; - - throw new ArgumentException($"Unsupported pixel format ({format}, {type})"); - } - - private static PixImage CreateFromBitmapSource(BitmapSource bitmapSource) - { - var pixelFormat = bitmapSource.Format.ToUnindexed(); - var fcBitmap = new FormatConvertedBitmap(bitmapSource, pixelFormat, null, 0); - var (pixFormat, channels) = pixelFormat.ToPixFormatAndCount(); - return CreateFromFormatConvertedBitmap(fcBitmap, pixFormat, channels); - } - - private static PixImage CreateFromFormatConvertedBitmap(FormatConvertedBitmap fcBitmap, PixFormat pixFormat, int channels) - { - var sx = fcBitmap.PixelWidth; - var sy = fcBitmap.PixelHeight; - if (pixFormat.Format == Col.Format.BW) - { - var bitImage = new PixImage(Col.Format.BW, 1 + (sx - 1) / 8, sy, channels); - fcBitmap.CopyPixels(bitImage.Array, bitImage.IntStride, 0); - var pixImage = new PixImage(Col.Format.BW, sx, sy, 1); - PixImage.ExpandPixels(bitImage, pixImage); - return pixImage; - } - else - { - var pixImage = PixImage.Create(pixFormat, sx, sy, channels); - fcBitmap.CopyPixels(pixImage.Array, pixImage.IntStride, 0); - return pixImage; - } - } - - #endregion - - #region Loader - - private class PixLoader : IPixLoader - { - public string Name => "Windows Media"; - - #region Load from File / Stream - - /// - /// Creates a new image from the file. Note that in this raw image the channel - /// count of the volume and the channel count of the format may be different. - /// - public PixImage LoadFromFile(string filename) - { - using var stream = new MemoryStream(File.ReadAllBytes(filename)); - - var bitmapImage = new BitmapImage(); - bitmapImage.BeginInit(); - bitmapImage.StreamSource = stream; - bitmapImage.CacheOption = BitmapCacheOption.OnLoad; - bitmapImage.CreateOptions = BitmapCreateOptions.PreservePixelFormat; - bitmapImage.EndInit(); - return CreateFromBitmapSource(bitmapImage); - } - - public PixImage LoadFromStream(Stream stream) - { - var decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.Default); - return CreateFromBitmapSource(decoder.Frames[0]); - } - - #endregion - - #region Save to File / Stream - - public void SaveToFile (string filename, PixImage pi, PixSaveParams saveParams) - { - using var stream = File.OpenWrite(filename); - SaveToStream(stream, pi, saveParams); - } - - public void SaveToStream(Stream stream, PixImage pi, PixSaveParams saveParams) - { - if (pi.Format == Col.Format.BW) - throw new ArgumentException($"Unsupported color format {pi.Format}"); - - BitmapEncoder encoder = - saveParams switch - { - PixJpegSaveParams jpeg => new JpegBitmapEncoder { QualityLevel = jpeg.Quality }, - _ => GetEncoder(saveParams.Format) - }; - - encoder.Frames.Add(pi.ToBitmapFrame()); - encoder.Save(stream); - stream.Flush(); - } - - #endregion - - #region Get info from File / Stream - - public PixImageInfo GetInfoFromFile(string fileName) - { - using var stream = File.OpenRead(fileName); - return GetInfoFromStream(stream); - } - - public PixImageInfo GetInfoFromStream(Stream stream) - { - var src0 = new BitmapImage(); - src0.BeginInit(); - src0.StreamSource = stream; - src0.CacheOption = BitmapCacheOption.None; - src0.CreateOptions = BitmapCreateOptions.DelayCreation; - src0.EndInit(); - var pixFormat = src0.Format.ToPixFormat(); - return new PixImageInfo(pixFormat, new V2i(src0.PixelWidth, src0.PixelHeight)); - } - - #endregion - } - - public static readonly IPixLoader Loader = new PixLoader(); - - #endregion - - #region Conversions - - private static BitmapFrame ToBitmapFrame(this PixImage pi) - { - return BitmapFrame.Create(pi.ToBitmapSource()); - } - - public static BitmapSource ToBitmapSource(this PixImage pi, double dpi = 96.0) - { - var t = pi.PixFormat.Type; - var mi = typeof(PixImageWindowsMedia).GetMethod("ToBitmapSourceTyped", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static).MakeGenericMethod(new[] { t }); - return (BitmapSource)mi.Invoke(null, new object[] { pi, dpi }); - } - - public static BitmapSource ToBitmapSource(this PixImage pi, double dpi = 96.0) - { - return ToBitmapSourceTyped(pi, dpi); - } - - private static BitmapSource ToBitmapSourceTyped(this PixImage pi, double dpi) - { - var storeFormats = GetStoreFormats(typeof(T), pi.Format); - var vol = pi.Volume; - - if (pi.Format == Col.Format.BW) - { - long sx = vol.SX, sy = vol.SY; - - var bitImage = new PixImage(pi.Format, 1 + (pi.Size.X - 1) / 8, pi.Size.Y, 1); - var bitData = bitImage.Volume.Data; - - PixImage.CompressPixels(pi.ToPixImage(), bitImage); - - return BitmapSource.Create( - (int)sx, (int)sy, dpi, dpi, - storeFormats.Item1, null, bitData, bitImage.IntStride); - } - else if (pi.Format != storeFormats.Item2) - { - var saveImage = new PixImage(storeFormats.Item2, pi); - vol = saveImage.Volume; - } - - return BitmapSource.Create( - (int)vol.SX, (int)vol.SY, 96, 96, - storeFormats.Item1, null, vol.Data, pi.IntStride); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Aardvark.PixImage.WindowsMedia/paket.references b/src/Aardvark.PixImage.WindowsMedia/paket.references deleted file mode 100644 index e69de29b..00000000 diff --git a/src/Aardvark.PixImage.WindowsMedia/paket.template b/src/Aardvark.PixImage.WindowsMedia/paket.template deleted file mode 100644 index 5bc57a58..00000000 --- a/src/Aardvark.PixImage.WindowsMedia/paket.template +++ /dev/null @@ -1,16 +0,0 @@ -type project -id Aardvark.PixImage.WindowsMedia -authors Aardvark Platform Team -owners Aardvark Platform Team -projectUrl http://github.com/aardvark-platform -licenseUrl http://www.apache.org/licenses/LICENSE-2.0.txt -repositoryType git -repositoryUrl https://github.com/aardvark-platform/aardvark.base -description - Aardvark is an open-source platform for visual computing, real-time graphics and visualization. -frameworkAssemblies - PresentationCore - WindowsBase - System.Xaml - System.Xml.Linq -include-pdbs true \ No newline at end of file diff --git a/src/Aardvark.sln b/src/Aardvark.sln index b355609f..60c0d8a6 100644 --- a/src/Aardvark.sln +++ b/src/Aardvark.sln @@ -31,12 +31,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".NetStandard", ".NetStandar EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CodeGenerator", "CodeGenerator\CodeGenerator.csproj", "{4B4A0898-4429-4E39-A916-50A0DE8E74E6}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aardvark.PixImage.SystemDrawing", "Aardvark.PixImage.SystemDrawing\Aardvark.PixImage.SystemDrawing.csproj", "{599BA682-70EF-4D1E-A4C1-A36359482F87}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aardvark.Base", "Aardvark.Base\Aardvark.Base.csproj", "{C90C041E-E076-4BBC-BBCD-B29367F649A2}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aardvark.Data.Vrml97", "Aardvark.Data.Vrml97\Aardvark.Data.Vrml97.csproj", "{C47CFAA4-9867-4FED-AE44-D31ACF7A4A9F}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aardvark.Base.Essentials", "Aardvark.Base.Essentials\Aardvark.Base.Essentials.csproj", "{2E887670-5BC3-44FA-97A3-389917B27BEB}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExamplesCSharp", "Demo\ExamplesCSharp\ExamplesCSharp.csproj", "{6C6850B4-FDE7-4D75-9113-DCF9779145A6}" @@ -57,14 +53,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aardvark.Base.Tensors.CShar EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Aardvark.Base.Tensors", "Aardvark.Base.Tensors\Aardvark.Base.Tensors.fsproj", "{FBB17215-CDCE-4FFA-B10A-EA1B320C8638}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aardvark.PixImage.DevIL", "Aardvark.PixImage.DevIL\Aardvark.PixImage.DevIL.csproj", "{670261E9-9898-4275-B5C0-D2AB605AF450}" -EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Aardvark.Base.FSharp.Benchmarks", "Tests\Aardvark.Base.FSharp.Benchmarks\Aardvark.Base.FSharp.Benchmarks.fsproj", "{F278A2F7-52FF-40CD-B16D-4D82F7DFA8C3}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aardvark.PixImage.WindowsMedia", "Aardvark.PixImage.WindowsMedia\Aardvark.PixImage.WindowsMedia.csproj", "{02533034-24CF-4065-B7D3-A10A4CE0FC81}" -EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Aardvark.Base.Windows.Tests", "Tests\Aardvark.Base.Windows.Tests\Aardvark.Base.Windows.Tests.fsproj", "{CE56CD59-C199-457C-9C6D-9D19D45F3940}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "._", "._", "{61D029CD-C474-4CC5-AEF6-B898F9B3D6A3}" ProjectSection(SolutionItems) = preProject ..\.gitignore = ..\.gitignore @@ -130,18 +120,10 @@ Global {4B4A0898-4429-4E39-A916-50A0DE8E74E6}.Debug|Any CPU.Build.0 = Debug|Any CPU {4B4A0898-4429-4E39-A916-50A0DE8E74E6}.Release|Any CPU.ActiveCfg = Release|Any CPU {4B4A0898-4429-4E39-A916-50A0DE8E74E6}.Release|Any CPU.Build.0 = Release|Any CPU - {599BA682-70EF-4D1E-A4C1-A36359482F87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {599BA682-70EF-4D1E-A4C1-A36359482F87}.Debug|Any CPU.Build.0 = Debug|Any CPU - {599BA682-70EF-4D1E-A4C1-A36359482F87}.Release|Any CPU.ActiveCfg = Release|Any CPU - {599BA682-70EF-4D1E-A4C1-A36359482F87}.Release|Any CPU.Build.0 = Release|Any CPU {C90C041E-E076-4BBC-BBCD-B29367F649A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C90C041E-E076-4BBC-BBCD-B29367F649A2}.Debug|Any CPU.Build.0 = Debug|Any CPU {C90C041E-E076-4BBC-BBCD-B29367F649A2}.Release|Any CPU.ActiveCfg = Release|Any CPU {C90C041E-E076-4BBC-BBCD-B29367F649A2}.Release|Any CPU.Build.0 = Release|Any CPU - {C47CFAA4-9867-4FED-AE44-D31ACF7A4A9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C47CFAA4-9867-4FED-AE44-D31ACF7A4A9F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C47CFAA4-9867-4FED-AE44-D31ACF7A4A9F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C47CFAA4-9867-4FED-AE44-D31ACF7A4A9F}.Release|Any CPU.Build.0 = Release|Any CPU {2E887670-5BC3-44FA-97A3-389917B27BEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2E887670-5BC3-44FA-97A3-389917B27BEB}.Debug|Any CPU.Build.0 = Debug|Any CPU {2E887670-5BC3-44FA-97A3-389917B27BEB}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -182,22 +164,10 @@ Global {FBB17215-CDCE-4FFA-B10A-EA1B320C8638}.Debug|Any CPU.Build.0 = Debug|Any CPU {FBB17215-CDCE-4FFA-B10A-EA1B320C8638}.Release|Any CPU.ActiveCfg = Release|Any CPU {FBB17215-CDCE-4FFA-B10A-EA1B320C8638}.Release|Any CPU.Build.0 = Release|Any CPU - {670261E9-9898-4275-B5C0-D2AB605AF450}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {670261E9-9898-4275-B5C0-D2AB605AF450}.Debug|Any CPU.Build.0 = Debug|Any CPU - {670261E9-9898-4275-B5C0-D2AB605AF450}.Release|Any CPU.ActiveCfg = Release|Any CPU - {670261E9-9898-4275-B5C0-D2AB605AF450}.Release|Any CPU.Build.0 = Release|Any CPU {F278A2F7-52FF-40CD-B16D-4D82F7DFA8C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F278A2F7-52FF-40CD-B16D-4D82F7DFA8C3}.Debug|Any CPU.Build.0 = Debug|Any CPU {F278A2F7-52FF-40CD-B16D-4D82F7DFA8C3}.Release|Any CPU.ActiveCfg = Release|Any CPU {F278A2F7-52FF-40CD-B16D-4D82F7DFA8C3}.Release|Any CPU.Build.0 = Release|Any CPU - {02533034-24CF-4065-B7D3-A10A4CE0FC81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {02533034-24CF-4065-B7D3-A10A4CE0FC81}.Debug|Any CPU.Build.0 = Debug|Any CPU - {02533034-24CF-4065-B7D3-A10A4CE0FC81}.Release|Any CPU.ActiveCfg = Release|Any CPU - {02533034-24CF-4065-B7D3-A10A4CE0FC81}.Release|Any CPU.Build.0 = Release|Any CPU - {CE56CD59-C199-457C-9C6D-9D19D45F3940}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CE56CD59-C199-457C-9C6D-9D19D45F3940}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CE56CD59-C199-457C-9C6D-9D19D45F3940}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CE56CD59-C199-457C-9C6D-9D19D45F3940}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -213,9 +183,7 @@ Global {CE9B55FF-2D3E-4E13-BA0A-69FD82F0B29B} = {A79411F9-60B3-46C8-8981-6905D9B9F74C} {97F4D5BB-9F48-454B-B6A5-536AE172CE50} = {C557CE9D-81EE-4EB3-AB94-B9F9CB2FA19A} {C2C8BA0D-992B-4BA7-8A6A-EA7A3207BBE6} = {C557CE9D-81EE-4EB3-AB94-B9F9CB2FA19A} - {599BA682-70EF-4D1E-A4C1-A36359482F87} = {C557CE9D-81EE-4EB3-AB94-B9F9CB2FA19A} {C90C041E-E076-4BBC-BBCD-B29367F649A2} = {C557CE9D-81EE-4EB3-AB94-B9F9CB2FA19A} - {C47CFAA4-9867-4FED-AE44-D31ACF7A4A9F} = {C557CE9D-81EE-4EB3-AB94-B9F9CB2FA19A} {2E887670-5BC3-44FA-97A3-389917B27BEB} = {C557CE9D-81EE-4EB3-AB94-B9F9CB2FA19A} {6C6850B4-FDE7-4D75-9113-DCF9779145A6} = {864A9013-93AC-4073-BB2A-348CE1B00010} {39EC0F23-19DF-46FD-8273-E931D26B7209} = {864A9013-93AC-4073-BB2A-348CE1B00010} @@ -226,10 +194,7 @@ Global {99C82F36-74DE-4ED1-B9D5-CE044FC517AC} = {A79411F9-60B3-46C8-8981-6905D9B9F74C} {06739A61-1B1C-4FC3-8DEF-926B10FACB28} = {C557CE9D-81EE-4EB3-AB94-B9F9CB2FA19A} {FBB17215-CDCE-4FFA-B10A-EA1B320C8638} = {C557CE9D-81EE-4EB3-AB94-B9F9CB2FA19A} - {670261E9-9898-4275-B5C0-D2AB605AF450} = {C557CE9D-81EE-4EB3-AB94-B9F9CB2FA19A} {F278A2F7-52FF-40CD-B16D-4D82F7DFA8C3} = {A79411F9-60B3-46C8-8981-6905D9B9F74C} - {02533034-24CF-4065-B7D3-A10A4CE0FC81} = {C557CE9D-81EE-4EB3-AB94-B9F9CB2FA19A} - {CE56CD59-C199-457C-9C6D-9D19D45F3940} = {A79411F9-60B3-46C8-8981-6905D9B9F74C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {1537AED0-2BB3-4EC3-B2CB-06E22C23B002} diff --git a/src/Demo/PixImageDemo/PixImageDemo.csproj b/src/Demo/PixImageDemo/PixImageDemo.csproj index d50449b2..5879f9a4 100644 --- a/src/Demo/PixImageDemo/PixImageDemo.csproj +++ b/src/Demo/PixImageDemo/PixImageDemo.csproj @@ -16,7 +16,6 @@ - \ No newline at end of file diff --git a/src/Tests/Aardvark.Base.FSharp.Tests/Aardvark.Base.FSharp.Tests.fsproj b/src/Tests/Aardvark.Base.FSharp.Tests/Aardvark.Base.FSharp.Tests.fsproj index 973118a3..fbc2f56c 100644 --- a/src/Tests/Aardvark.Base.FSharp.Tests/Aardvark.Base.FSharp.Tests.fsproj +++ b/src/Tests/Aardvark.Base.FSharp.Tests/Aardvark.Base.FSharp.Tests.fsproj @@ -38,7 +38,6 @@ - \ No newline at end of file diff --git a/src/Tests/Aardvark.Base.Windows.Tests/Aardvark.Base.Windows.Tests.fsproj b/src/Tests/Aardvark.Base.Windows.Tests/Aardvark.Base.Windows.Tests.fsproj deleted file mode 100644 index ab70acbf..00000000 --- a/src/Tests/Aardvark.Base.Windows.Tests/Aardvark.Base.Windows.Tests.fsproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - Exe - net6.0-windows - false - true - 3389;3390;3395 - - - - - - - - - - - \ No newline at end of file diff --git a/src/Tests/Aardvark.Base.Windows.Tests/PixLoaderTests.fs b/src/Tests/Aardvark.Base.Windows.Tests/PixLoaderTests.fs deleted file mode 100644 index 0e641a66..00000000 --- a/src/Tests/Aardvark.Base.Windows.Tests/PixLoaderTests.fs +++ /dev/null @@ -1,337 +0,0 @@ -namespace Aardvark.Base.Windows.Tests - -open Aardvark.Base -open System -open System.IO -open System.IO.Compression - -open NUnit.Framework -open FsUnit -open FsCheck -open FsCheck.NUnit -open Expecto - -open FSharp.Data.Adaptive - -module PixLoaderTests = - - let private rnd = RandomSystem(1) - - let private tempFile (f : string -> 'T) = - let filename = Path.GetTempFileName() - - try - f filename - finally - if File.Exists filename then - File.Delete filename - - module private PixImage = - - let private desktopPath = - Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop) - - let saveToDesktop (fileName : string) (img : #PixImage) = - let dir = Path.combine [desktopPath; "UnitTests"] - Directory.CreateDirectory(dir) |> ignore - img.Save(Path.combine [dir; fileName]) - - let checkerboard (format : Col.Format) (width : int) (height : int) = - let mutable colors = HashMap.empty - - let pi = PixImage(format, V2i(width, height)) - - for channel = 0 to pi.ChannelCount - 1 do - pi.GetChannel(int64 channel).SetByCoord(fun (c : V2l) -> - let c = c / 11L - if (c.X + c.Y) % 2L = 0L then - 255uy - else - match colors |> HashMap.tryFind c with - | Some c -> c.[channel] - | _ -> - let color = rnd.UniformC4d().ToC4b() - colors <- colors |> HashMap.add c color - color.[channel] - ) |> ignore - - pi - - let compare (input : PixImage<'T>) (output : PixImage<'T>) = - let channels = min input.ChannelCount output.ChannelCount - - for x in 0 .. output.Size.X - 1 do - for y in 0 .. output.Size.Y - 1 do - for c in 0 .. channels - 1 do - let inputData = input.GetChannel(int64 c) - let outputData = output.GetChannel(int64 c) - - let coord = V2i(x, y) - - let ref = - if Vec.allGreaterOrEqual coord V2i.Zero && Vec.allSmaller coord input.Size then - inputData.[coord] - else - Unchecked.defaultof<'T> - - let message = - let t = if c < 4 then "color" else "alpha" - $"PixImage {t} data mismatch at [{x}, {y}]" - - Expect.equal outputData.[x, y] ref message - - module private Gen = - - let colorFormat = - [ - Col.Format.RGBA - Col.Format.BGRA - Col.Format.RGB - Col.Format.BGR - ] - |> Gen.elements - - let imageFileFormat = - [ - PixFileFormat.Png - PixFileFormat.Tiff - PixFileFormat.Bmp - PixFileFormat.Jpeg - PixFileFormat.Gif - ] - |> Gen.elements - - let checkerboardPix (format : Col.Format) = - gen { - let! w = Gen.choose (64, 513) - let! h = Gen.choose (64, 513) - return PixImage.checkerboard format w h - } - - let pixLoader = - let loaders = PixImage.GetLoaders() |> Seq.filter (fun l -> l.Name <> "Aardvark PGM") - Gen.elements loaders - - let pixEncoder (useStream : bool) (format : PixFileFormat) = - pixLoader - |> Gen.filter (fun loader -> - not (loader.Name = "ImageSharp" && format = PixFileFormat.Tiff) && // ImageSharp support for TIFFs is buggy atm - not (loader.Name = "DevIL" && format = PixFileFormat.Gif) && // DevIL does not support saving GIFs - not (loader.Name = "DevIL" && format = PixFileFormat.Tiff && useStream) // DevIL does not support saving TIFFs to streams - ) - - let colorAndImageFileFormat = - gen { - let! cf = colorFormat - let! iff = imageFileFormat - - let isValid = - iff = PixFileFormat.Png || cf = Col.Format.RGB || cf = Col.Format.BGR - - return cf, iff, isValid - } - |> Gen.filter (fun (_, _, valid) -> valid) - |> Gen.map (fun (cf, iff, _) -> cf, iff) - - - type SaveLoadInput = - { - Image : PixImage - SaveParams : PixSaveParams - Encoder : IPixLoader - Decoder : IPixLoader - UseStream : bool - } - - type Generator private () = - - static member Loader = - Arb.fromGen Gen.pixLoader - - static member PixImage = - gen { - let! format = Gen.colorFormat - return! Gen.checkerboardPix format - } - |> Arb.fromGen - - static member SaveLoadInput = - gen { - let! cf, iff = Gen.colorAndImageFileFormat - let! pix = Gen.checkerboardPix cf - let! useStream = Gen.elements [false; true] - let! encoder = Gen.pixEncoder useStream iff - let! decoder = Gen.pixLoader - - let saveParams = - match iff with - | PixFileFormat.Jpeg -> PixJpegSaveParams(quality = 100) :> PixSaveParams - | fmt -> PixSaveParams fmt - - return { - Image = pix - SaveParams = saveParams - Encoder = encoder - Decoder = decoder - UseStream = useStream - } - } - |> Arb.fromGen - - [] - let setup() = - Aardvark.Init() - Report.Verbosity <- 3 - - - [ |])>] - let ``[PixLoader] Save and load`` (input : SaveLoadInput) = - printfn "encoder = %s, decoder = %s, size = %A, color format = %A, file format = %A, use stream = %b" - input.Encoder.Name input.Decoder.Name input.Image.Size input.Image.Format input.SaveParams.Format input.UseStream - - tempFile (fun file -> - let output = - if input.UseStream then - use stream = File.Open(file, FileMode.Create, FileAccess.ReadWrite) - input.Image.Save(stream, input.SaveParams, input.Encoder) - - stream.Position <- 0L - PixImage(stream, input.Decoder) - else - input.Image.Save(file, input.SaveParams, false, input.Encoder) - PixImage(file, input.Decoder) - - match input.SaveParams.Format with - | PixFileFormat.Jpeg | PixFileFormat.Gif -> - let psnr = PixImage.peakSignalToNoiseRatio input.Image output - Expect.isGreaterThan psnr 20.0 "Bad peak-signal-to-noise ratio" - - | _ -> - PixImage.compare input.Image output - ) - - - [ |])>] - let ``[PixLoader] Aardvark PGM writer`` (pi : PixImage) = - printfn "size = %A" pi.Size - - let pi = PixImage(Col.Format.Gray, pi.GetChannel 0L) - let loader = PixImage.GetLoaders() |> Seq.pick (fun l -> if l.Name = "Aardvark PGM" then Some l else None) - - tempFile (fun file -> - pi.Save(file, PixFileFormat.Pgm, false, loader) - let out = PixImage(file) - - PixImage.compare pi out - ) - - - [ |])>] - let ``[PixLoader] JPEG quality`` (loader : IPixLoader) (pi : PixImage) = - printfn "loader = %s, size = %A, format = %A" loader.Name pi.Size pi.Format - - tempFile (fun file50 -> - tempFile (fun file90 -> - pi.SaveAsJpeg(file50, 50, false, loader) - pi.SaveAsJpeg(file90, 90, false, loader) - - // check equal - let pi50 = PixImage(file50, loader) - let pi90 = PixImage(file90, loader) - let psnr = PixImage.peakSignalToNoiseRatio pi50 pi90 - psnr |> should be (greaterThan 20.0) - - // check size - let i50 = FileInfo(file50) - let i90 = FileInfo(file90) - - i50.Length |> should be (lessThan i90.Length) - ) - ) - - - [ |])>] - let ``[PixLoader] PNG compression level`` (pi : PixImage) = - printfn "size = %A, format = %A" pi.Size pi.Format - - tempFile (fun file0 -> - tempFile (fun file9 -> - pi.SaveAsPng(file0, 0, false, PixImageSharp.Loader) - pi.SaveAsPng(file9, 6, false, PixImageSharp.Loader) - - // check equal - let pi0 = PixImage(file0, PixImageSharp.Loader) - let pi9 = PixImage(file9, PixImageSharp.Loader) - - PixImage.compare pi0 pi9 - - // check size - let i0 = FileInfo(file0) - let i9 = FileInfo(file9) - - i0.Length |> should be (greaterThan i9.Length) - ) - ) - - - [] - let ``[PixLoader] Add and remove loaders``() = - let count = PixImage.GetLoaders() |> Seq.length - - PixImage.SetLoader(PixImageDevil.Loader, 1337) - PixImage.GetLoaders() |> Seq.head |> should equal PixImageDevil.Loader - - let priorities = PixImage.GetLoadersWithPriority() - priorities.Count |> should equal count - priorities.Get(PixImageDevil.Loader) |> should equal 1337 - - PixImage.AddLoader(PixImageDevil.Loader) - let priorities = PixImage.GetLoadersWithPriority() - priorities.Get(PixImageDevil.Loader) |> should equal 1338 - - PixImage.RemoveLoader(PixImageSharp.Loader) - PixImage.RemoveLoader(PixImageDevil.Loader) - PixImage.GetLoaders() |> Seq.length |> should equal (count - 2) - - [] - let ``[PixLoader] Unseekable streams``() = - - let pi = PixImage.checkerboard Col.Format.RGBA 256 256 - - let brokenLoader = - { new IPixLoader with - member x.Name = "Broken" - member x.GetInfoFromFile(filename) = null - member x.GetInfoFromStream(stream) = stream.ReadByte() |> ignore; null - member x.LoadFromFile(filename) = null - member x.LoadFromStream(stream) = stream.ReadByte() |> ignore; null - member x.SaveToFile(filename, image, saveParams) = () - member x.SaveToStream(stream, image, saveParams) = stream.WriteByte(0uy); failwith "Nope" } - - // If we fail with our first loader on an unseekable stream we're in trouble - PixImage.SetLoader(brokenLoader, 1337) - - tempFile (fun filename -> - File.Delete filename - - use archive = ZipFile.Open(filename, ZipArchiveMode.Create) - use stream = archive.CreateEntry("foo.png", CompressionLevel.Fastest).Open() - - stream.CanSeek |> should equal false - - (fun () -> pi.SaveAsPng(stream)) |> should throw typeof - ) - - // On the other hand, if the first loader succeeds it should not matter - PixImage.SetLoader(PixImageSharp.Loader, 1338) - - tempFile (fun filename -> - File.Delete filename - - use archive = ZipFile.Open(filename, ZipArchiveMode.Create) - use stream = archive.CreateEntry("foo.png", CompressionLevel.Fastest).Open() - - stream.CanSeek |> should equal false - - pi.SaveAsPng(stream) - ) \ No newline at end of file diff --git a/src/Tests/Aardvark.Base.Windows.Tests/Program.fs b/src/Tests/Aardvark.Base.Windows.Tests/Program.fs deleted file mode 100644 index b2b18037..00000000 --- a/src/Tests/Aardvark.Base.Windows.Tests/Program.fs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Aardvark.Base.Windows.Tests - -module Program = - - open BenchmarkDotNet.Running; - open BenchmarkDotNet.Configs - open BenchmarkDotNet.Jobs - open BenchmarkDotNet.Toolchains - - [] - let main argv = - - //let cfg = - // let job = Job.ShortRun.WithToolchain(InProcess.Emit.InProcessEmitToolchain.Instance) - // ManualConfig.Create(DefaultConfig.Instance).WithOptions(ConfigOptions.DisableOptimizationsValidator).AddJob(job) - - //BenchmarkSwitcher.FromAssembly(typeof.Assembly).Run(argv, cfg) |> ignore; - 0 \ No newline at end of file diff --git a/src/Tests/Aardvark.Base.Windows.Tests/paket.references b/src/Tests/Aardvark.Base.Windows.Tests/paket.references deleted file mode 100644 index 9c8a19f2..00000000 --- a/src/Tests/Aardvark.Base.Windows.Tests/paket.references +++ /dev/null @@ -1,13 +0,0 @@ -group Test - -FsCheck -FsCheck.NUnit -Expecto -Expecto.FsCheck -FSharp.Core -FsUnit -NUnit -NUnit3TestAdapter -Microsoft.NET.Test.Sdk -YoloDev.Expecto.TestSdk -BenchmarkDotNet \ No newline at end of file