internal void _ResolveSatelliteDependencies(ReadContext context)
        {
            // resolve satellite buffers

            foreach (var buffer in this._buffers)
            {
                buffer._ResolveUri(context);
            }

            // resolve satellite images

            foreach (var image in this._images)
            {
                // reads the image file into the current object.
                image._ResolveUri(context);

                // if we have a decoder hook, call the decoder, and free the memory.
                if (context.ImageDecoder != null)
                {
                    if (!context.ImageDecoder(image))
                    {
                        image._DiscardContent();
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Creates a complete clone of this <see cref="ModelRoot"/> instance.
        /// </summary>
        /// <returns>A new <see cref="ModelRoot"/> instance.</returns>
        /// <remarks>
        /// Deep cloning is performed as a brute force operation; by serializing
        /// the whole model to GLTF into memory, and then deserializing it back to DOM.
        /// </remarks>
        public ModelRoot DeepClone()
        {
            // prepare the in-memory temporary storage
            var dict     = new Dictionary <string, ArraySegment <Byte> >();
            var wcontext = WriteContext
                           .CreateFromDictionary(dict)
                           .WithDeepCloneSettings();

            System.Diagnostics.Debug.Assert(wcontext._NoCloneWatchdog, "invalid clone settings");

            // write the model to the temporary storage

            wcontext.WriteTextSchema2("deepclone", this);

            // restore the model from the temporary storage

            var rcontext = ReadContext.CreateFromDictionary(dict, wcontext._UpdateSupportedExtensions);

            rcontext.Validation = Validation.ValidationMode.Skip;
            var cloned = rcontext._ReadFromDictionary("deepclone.gltf");

            // Restore MemoryImage source URIs (they're not cloned as part of the serialization)
            foreach (var srcImg in this.LogicalImages)
            {
                var dstImg = cloned.LogicalImages[srcImg.LogicalIndex];
                var img    = dstImg.Content;
                dstImg.Content = new Memory.MemoryImage(img._GetBuffer(), srcImg.Content.SourcePath);
            }

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

            var context = ReadContext.CreateFromFile(filePath);

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

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

            var context = ReadContext.CreateFromDirectory(dir);

            return context.Validate(filePath);
        }
Пример #5
0
        private static Byte[] _LoadBinaryBufferUnchecked(string uri, ReadContext context)
        {
            var data = uri.TryParseBase64Unchecked(EMBEDDEDGLTFBUFFER, EMBEDDEDOCTETSTREAM);

            if (data != null)
            {
                return(data);
            }

            return(context
                   .ReadAllBytesToEnd(uri)
                   .ToUnderlayingArray());
        }
        /// <summary>
        /// Gets the list of satellite / dependency files for a given glTF file.
        /// This includes binary blobs and texture images.
        /// </summary>
        /// <param name="filePath">A valid file path.</param>
        /// <returns>A list of relative file paths, as found in the file.</returns>
        /// <remarks>
        /// This method is designed to be as fast as possible, and it avoids performing much
        /// of the validation and parsing of a glTf file, it just blindly looks for URI fields.
        /// </remarks>
        public static string[] GetSatellitePaths(string filePath)
        {
            Guard.FilePathMustExist(filePath, nameof(filePath));

            var json = ReadOnlyMemory <byte> .Empty;

            using (var s = File.OpenRead(filePath))
            {
                json = ReadContext.ReadJsonBytes(s);
            }

            return(ParseSatellitePaths(json));
        }
        /// <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));
            }
        }
        /// <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);
        }
Пример #9
0
        private (MODEL Model, Validation.ValidationResult Validation) _ReadGLB(Stream stream)
        {
            Guard.NotNull(stream, nameof(stream));

            IReadOnlyDictionary <uint, byte[]> chunks;

            try
            {
                chunks = _BinarySerialization.ReadBinaryFile(stream);
            }
            catch (System.IO.EndOfStreamException ex)
            {
                var vr = new Validation.ValidationResult(null, this.Validation);
                vr.SetError(new Validation.SchemaException(null, ex.Message));
                return(null, vr);
            }
            catch (Validation.SchemaException ex)
            {
                var vr = new Validation.ValidationResult(null, this.Validation);
                vr.SetError(ex);
                return(null, vr);
            }

            var context = this;

            if (chunks.ContainsKey(_BinarySerialization.CHUNKBIN))
            {
                // clone self
                var binChunk = chunks[_BinarySerialization.CHUNKBIN];
                context = new ReadContext(context);
                context._BinaryChunk = binChunk;
            }

            var jsonChunk = chunks[_BinarySerialization.CHUNKJSON];

            return(context._Read(jsonChunk));
        }
Пример #10
0
        internal void _ResolveUri(ReadContext context)
        {
            _Content = _LoadBinaryBufferUnchecked(_uri, context);

            _uri = null; // When _Data is not empty, clear URI
        }
Пример #11
0
 internal ReadContext(ReadContext other)
     : base(other)
 {
     this._FileReader  = other._FileReader;
     this.ImageDecoder = other.ImageDecoder;
 }