예제 #1
0
        private static MODEL _Read(TextReader textReader, ReadSettings settings)
        {
            Guard.NotNull(textReader, nameof(textReader));
            Guard.NotNull(settings, nameof(settings));

            using (var reader = new JsonTextReader(textReader))
            {
                var root = new MODEL();

                reader.Read();
                root.Deserialize(reader);

                var ex = root.Validate().FirstOrDefault();
                if (ex != null)
                {
                    throw ex;
                }

                foreach (var buffer in root._buffers)
                {
                    buffer._ResolveUri(settings.FileReader);
                }

                foreach (var image in root._images)
                {
                    image._ResolveUri(settings.FileReader);
                }

                return(root);
            }
        }
        public static Validation.ValidationResult Validate(string filePath)
        {
            Guard.FilePathMustExist(filePath, nameof(filePath));

            var settings = new ReadSettings(filePath);

            using (var stream = File.OpenRead(filePath))
            {
                bool binaryFile = glb._Identify(stream);

                if (binaryFile)
                {
                    return(_ReadGLB(stream, settings).Validation);
                }

                string content = null;

                using (var streamReader = new StreamReader(stream))
                {
                    content = streamReader.ReadToEnd();
                }

                return(_ParseGLTF(content, settings).Validation);
            }
        }
 public void CopyTo(ReadSettings other)
 {
     Guard.NotNull(other, nameof(other));
     other.Validation = this.Validation;
     other.ImageDecoder = this.ImageDecoder;
     other.JsonPreprocessor = this.JsonPreprocessor;
 }
        /// <summary>
        /// Parses a <see cref="MODEL"/> instance from a <see cref="byte"/> array representing a GLB file
        /// </summary>
        /// <param name="glb">A <see cref="byte"/> array representing a GLB file</param>
        /// <param name="settings">Optional settings.</param>
        /// <returns>A <see cref="MODEL"/> instance.</returns>
        public static MODEL ParseGLB(BYTES glb, ReadSettings settings = null)
        {
            Guard.NotNull(glb, nameof(glb));

            using (var m = new MemoryStream(glb.Array, glb.Offset, glb.Count, false))
            {
                return(ReadGLB(m, settings));
            }
        }
예제 #5
0
        /// <summary>
        /// Parses a <see cref="MODEL"/> instance from a <see cref="String"/> JSON content representing a GLTF file.
        /// </summary>
        /// <param name="jsonContent">A <see cref="String"/> JSON content representing a GLTF file.</param>
        /// <param name="settings">A <see cref="ReadSettings"/> instance defining the reading options.</param>
        /// <returns>A <see cref="MODEL"/> instance.</returns>
        public static MODEL ParseGLTF(String jsonContent, ReadSettings settings)
        {
            Guard.NotNullOrEmpty(jsonContent, nameof(jsonContent));
            Guard.NotNull(settings, nameof(settings));

            using (var tr = new StringReader(jsonContent))
            {
                return(_Read(tr, settings));
            }
        }
        /// <summary>
        /// Reads a <see cref="MODEL"/> instance from a path pointing to a GLB or a GLTF file
        /// </summary>
        /// <param name="filePath">A valid file path.</param>
        /// <returns>A <see cref="MODEL"/> instance.</returns>
        public static MODEL Load(string filePath)
        {
            Guard.FilePathMustExist(filePath, nameof(filePath));

            var settings = new ReadSettings(filePath);

            using (var s = File.OpenRead(filePath))
            {
                return(Read(s, settings));
            }
        }
        /// <summary>
        /// Parses a <see cref="MODEL"/> instance from a <see cref="byte"/> array representing a GLB file
        /// </summary>
        /// <param name="glb">A <see cref="byte"/> array representing a GLB file</param>
        /// <param name="settings">Optional settings.</param>
        /// <returns>A <see cref="MODEL"/> instance.</returns>
        public static MODEL ParseGLB(BYTES glb, ReadSettings settings = null)
        {
            System.Diagnostics.Debug.Assert(!(settings is ReadContext), "Use Load method.");

            Guard.NotNull(glb, nameof(glb));

            using (var m = new MemoryStream(glb.Array, glb.Offset, glb.Count, false))
            {
                return ReadGLB(m, settings);
            }
        }
        /// <summary>
        /// Reads a <see cref="MODEL"/> instance from a <see cref="Stream"/> representing a GLB file
        /// </summary>
        /// <param name="stream">The source <see cref="Stream"/>.</param>
        /// <param name="settings">Optional settings.</param>
        /// <returns>A <see cref="MODEL"/> instance.</returns>
        public static MODEL ReadGLB(Stream stream, ReadSettings settings = null)
        {
            Guard.NotNull(stream, nameof(stream));
            Guard.IsTrue(stream.CanRead, nameof(stream));

            var context = ReadContext
                          .Create(f => throw new NotSupportedException())
                          .WithSettingsFrom(settings);

            return(context.ReadBinarySchema2(stream));
        }
        /// <summary>
        /// Parses a <see cref="MODEL"/> instance from a <see cref="String"/> JSON content representing a GLTF file.
        /// </summary>
        /// <param name="jsonContent">A <see cref="String"/> JSON content representing a GLTF file.</param>
        /// <param name="settings">A <see cref="ReadSettings"/> instance defining the reading options.</param>
        /// <returns>A <see cref="MODEL"/> instance.</returns>
        public static MODEL ParseGLTF(String jsonContent, ReadSettings settings)
        {
            var mv = _ParseGLTF(jsonContent, settings);

            if (mv.Validation.HasErrors)
            {
                throw mv.Validation.Errors.FirstOrDefault();
            }

            return(mv.Model);
        }
        /// <summary>
        /// Reads a <see cref="MODEL"/> instance from a path pointing to a GLB or a GLTF file
        /// </summary>
        /// <param name="filePath">A valid file path.</param>
        /// <param name="settings">Optional settings.</param>
        /// <returns>A <see cref="MODEL"/> instance.</returns>
        public static MODEL Load(string filePath, ReadSettings settings = null)
        {
            Guard.FilePathMustExist(filePath, nameof(filePath));

            var context = ReadContext
                          .CreateFromFile(filePath)
                          .WithSettingsFrom(settings);

            using (var s = File.OpenRead(filePath))
            {
                return(context.ReadSchema2(s));
            }
        }
예제 #11
0
        /// <summary>
        /// Reads a <see cref="MODEL"/> instance from a <see cref="Stream"/> representing a GLB file
        /// </summary>
        /// <param name="stream">The source <see cref="Stream"/>.</param>
        /// <param name="settings">Optional settings.</param>
        /// <returns>A <see cref="MODEL"/> instance.</returns>
        public static MODEL ReadGLB(Stream stream, ReadSettings settings = null)
        {
            System.Diagnostics.Debug.Assert(!(settings is ReadContext), "Use Load method.");

            Guard.NotNull(stream, nameof(stream));
            Guard.IsTrue(stream.CanRead, nameof(stream));

            var context = ReadContext
                .Create(f => throw new NotSupportedException())
                .WithSettingsFrom(settings);

            return context.ReadBinarySchema2(stream);
        }
예제 #12
0
        /// <summary>
        /// Reads a <see cref="MODEL"/> instance from a <see cref="Stream"/> containing a GLB or a GLTF file.
        /// </summary>
        /// <param name="stream">A <see cref="Stream"/> to read from.</param>
        /// <param name="settings">A <see cref="ReadSettings"/> instance defining the reading options.</param>
        /// <returns>A <see cref="MODEL"/> instance.</returns>
        public static MODEL Read(Stream stream, ReadSettings settings)
        {
            bool binaryFile = glb._Identify(stream);

            if (binaryFile)
            {
                return(ReadGLB(stream, settings));
            }
            else
            {
                return(ReadGLTF(stream, settings));
            }
        }
        /// <summary>
        /// Reads a <see cref="MODEL"/> instance from a <see cref="Stream"/> containing a GLB file.
        /// </summary>
        /// <param name="stream">A <see cref="Stream"/> to read from.</param>
        /// <param name="settings">A <see cref="ReadSettings"/> instance defining the reading options.</param>
        /// <returns>A <see cref="MODEL"/> instance.</returns>
        public static MODEL ReadGLB(Stream stream, ReadSettings settings)
        {
            Guard.NotNull(stream, nameof(stream));
            Guard.NotNull(settings, nameof(settings));

            var mv = _ReadGLB(stream, settings);

            if (mv.Validation.HasErrors)
            {
                throw mv.Validation.Errors.FirstOrDefault();
            }

            return(mv.Model);
        }
예제 #14
0
        public static MODEL ReadFromDictionary(Dictionary <string, BYTES> files, string fileName)
        {
            var jsonBytes = files[fileName];

            var settings = new ReadSettings(fn => files[fn]);

            using (var m = new MemoryStream(jsonBytes.Array, jsonBytes.Offset, jsonBytes.Count))
            {
                using (var s = new StreamReader(m))
                {
                    return(_Read(s, settings));
                }
            }
        }
        /// <summary>
        /// Reads a <see cref="MODEL"/> instance from a <see cref="Stream"/> containing a GLTF file.
        /// </summary>
        /// <param name="stream">A <see cref="Stream"/> to read from.</param>
        /// <param name="settings">A <see cref="ReadSettings"/> instance defining the reading options.</param>
        /// <returns>A <see cref="MODEL"/> instance.</returns>
        public static MODEL ReadGLTF(Stream stream, ReadSettings settings)
        {
            Guard.NotNull(stream, nameof(stream));
            Guard.NotNull(settings, nameof(settings));

            string content = null;

            using (var streamReader = new StreamReader(stream))
            {
                content = streamReader.ReadToEnd();
            }

            return(ParseGLTF(content, settings));
        }
예제 #16
0
        /// <summary>
        /// Reads a <see cref="MODEL"/> instance from a path pointing to a GLB or a GLTF file
        /// </summary>
        /// <param name="filePath">A valid file path.</param>
        /// <param name="settings">Optional settings.</param>
        /// <returns>A <see cref="MODEL"/> instance.</returns>
        public static MODEL Load(string filePath, ReadSettings settings = null)
        {
            Guard.FilePathMustExist(filePath, nameof(filePath));

            var context = IO.ReadContext.CreateFromFile(filePath);

            if (settings != null)
            {
                settings.CopyTo(context);
            }

            using (var s = File.OpenRead(filePath))
            {
                return(context.ReadSchema2(s));
            }
        }
예제 #17
0
        /// <summary>
        /// Reads a <see cref="MODEL"/> instance from a <see cref="Stream"/> containing a GLB file.
        /// </summary>
        /// <param name="stream">A <see cref="Stream"/> to read from.</param>
        /// <param name="settings">A <see cref="ReadSettings"/> instance defining the reading options.</param>
        /// <returns>A <see cref="MODEL"/> instance.</returns>
        public static MODEL ReadGLB(Stream stream, ReadSettings settings)
        {
            Guard.NotNull(stream, nameof(stream));
            Guard.NotNull(settings, nameof(settings));

            var chunks = glb.ReadBinaryFile(stream);

            var dom = Encoding.UTF8.GetString(chunks[glb.CHUNKJSON]);

            if (chunks.ContainsKey(glb.CHUNKBIN))
            {
                settings.FileReader = key => string.IsNullOrEmpty(key) ? new BYTES(chunks[glb.CHUNKBIN]) : settings.FileReader.Invoke(key);
            }

            return(ParseGLTF(dom, settings));
        }
예제 #18
0
        /// <summary>
        /// Reads a <see cref="MODEL"/> instance from a path pointing to a GLB or a GLTF file
        /// </summary>
        /// <param name="filePath">A valid file path.</param>
        /// <param name="settings">Optional settings.</param>
        /// <returns>A <see cref="MODEL"/> instance.</returns>
        /// <remarks>
        /// <paramref name="settings"/> can be either a plain <see cref="ReadSettings"/> instance,
        /// or a <see cref="ReadContext"/>, in which case, the context will be used to read the
        /// files from it.
        /// </remarks>
        public static MODEL Load(string filePath, ReadSettings settings = null)
        {
            Guard.NotNull(filePath, nameof(filePath));

            if (!(settings is ReadContext context))
            {
                Guard.FilePathMustExist(filePath, nameof(filePath));

                var dir = Path.GetDirectoryName(filePath);
                filePath = System.IO.Path.GetFileName(filePath);

                context = ReadContext
                    .CreateFromDirectory(dir)
                    .WithSettingsFrom(settings);
            }

            return context.ReadSchema2(filePath);
        }
        public static MODEL ReadFromDictionary(Dictionary <string, BYTES> files, string fileName)
        {
            Guard.NotNull(files, nameof(files));

            var jsonBytes = files[fileName];

            var settings = new ReadSettings(fn => files[fn]);

            using (var m = new MemoryStream(jsonBytes.Array, jsonBytes.Offset, jsonBytes.Count))
            {
                using (var tr = new StreamReader(m))
                {
                    var mv = _Read(tr, settings);

                    if (mv.Validation.HasErrors)
                    {
                        throw mv.Validation.Errors.FirstOrDefault();
                    }

                    return(mv.Model);
                }
            }
        }
 public ReadSettings(ReadSettings other)
 {
     Guard.NotNull(other, nameof(other));
     other.CopyTo(this);
 }
예제 #21
0
 public ReadContext WithSettingsFrom(ReadSettings settings)
 {
     settings?.CopyTo(this);
     return(this);
 }
예제 #22
0
 public void CopyTo(ReadSettings other)
 {
     Guard.NotNull(other, nameof(other));
     other.Validation  = this.Validation;
     other.ImageReader = this.ImageReader;
 }
        private static (MODEL Model, Validation.ValidationResult Validation) _Read(TextReader textReader, ReadSettings settings)
        {
            Guard.NotNull(textReader, nameof(textReader));
            Guard.NotNull(settings, nameof(settings));

            using (var reader = new JsonTextReader(textReader))
            {
                var root     = new MODEL();
                var vcontext = new Validation.ValidationResult(root);

                if (!reader.Read())
                {
                    vcontext.AddError(new Validation.ModelException(root, "Json is empty"));
                    return(null, vcontext);
                }

                try
                {
                    root.Deserialize(reader);
                }
                catch (JsonReaderException rex)
                {
                    vcontext.AddError(new Validation.SchemaException(root, rex));
                    return(null, vcontext);
                }

                // schema validation

                root.ValidateReferences(vcontext.GetContext(root));
                var ex = vcontext.Errors.FirstOrDefault();
                if (ex != null)
                {
                    return(null, vcontext);
                }

                // resolve external references

                foreach (var buffer in root._buffers)
                {
                    buffer._ResolveUri(settings.FileReader);
                }

                foreach (var image in root._images)
                {
                    image._ResolveUri(settings.FileReader);
                }

                // full validation

                if (!settings.SkipValidation)
                {
                    root.Validate(vcontext.GetContext(root));
                    ex = vcontext.Errors.FirstOrDefault();
                    if (ex != null)
                    {
                        return(null, vcontext);
                    }
                }

                return(root, vcontext);
            }
        }
        private static (MODEL Model, Validation.ValidationResult Validation) _ParseGLTF(String jsonContent, ReadSettings settings)
        {
            Guard.NotNullOrEmpty(jsonContent, nameof(jsonContent));
            Guard.NotNull(settings, nameof(settings));

            using (var tr = new StringReader(jsonContent))
            {
                return(_Read(tr, settings));
            }
        }
        private static (MODEL Model, Validation.ValidationResult Validation) _ReadGLB(Stream stream, ReadSettings settings)
        {
            Guard.NotNull(stream, nameof(stream));
            Guard.NotNull(settings, nameof(settings));

            var chunks = glb.ReadBinaryFile(stream);

            var dom = Encoding.UTF8.GetString(chunks[glb.CHUNKJSON]);

            if (chunks.ContainsKey(glb.CHUNKBIN))
            {
                var sourceReader = settings.FileReader;

                settings.FileReader =
                    key =>
                    string.IsNullOrEmpty(key)
                    ?
                    new BYTES(chunks[glb.CHUNKBIN])
                    :
                    sourceReader.Invoke(key);
            }

            return(_ParseGLTF(dom, settings));
        }