예제 #1
0
        /// <summary>
        /// Reads the model in ASCII format from the specified stream.
        /// </summary>
        private ImportedModelContainer TryReadAscii(Stream stream, StlImportOptions importOptions)
        {
            using (var reader = new StreamReader(stream, ENCODING, false, 128, true))
            {
                VertexStructure newStructure = new VertexStructure();
                while (!reader.EndOfStream)
                {
                    var line = reader.ReadLine();
                    if (line == null)
                    {
                        continue;
                    }

                    line = line.Trim();
                    if (line.Length == 0 || line.StartsWith("\0") || line.StartsWith("#") || line.StartsWith("!") ||
                        line.StartsWith("$"))
                    {
                        continue;
                    }

                    string id, values;
                    ParseLine(line, out id, out values);
                    switch (id)
                    {
                    // Header.. not needed here
                    case "solid":
                        break;

                    // Geometry data
                    case "facet":
                        this.ReadFacet(reader, values, newStructure, importOptions);
                        break;

                    // End of file
                    case "endsolid":
                        break;
                    }
                }

                // Generate result container
                ImportedModelContainer result         = new ImportedModelContainer(importOptions);
                NamedOrGenericKey      geoResourceKey = result.GetResourceKey(
                    RES_KEY_GEO_CLASS, RES_KEY_GEO_NAME);
                result.ImportedResources.Add(new ImportedResourceInfo(
                                                 geoResourceKey,
                                                 () => new GeometryResource(newStructure)));
                GenericObject geoObject = new GenericObject(geoResourceKey);
                result.Objects.Add(geoObject);

                // Append an object which transform the whole coordinate system
                ScenePivotObject rootObject = result.CreateAndAddRootObject();
                result.ParentChildRelationships.Add(new Tuple <SceneObject, SceneObject>(rootObject, geoObject));

                return(result);
            }
        }
예제 #2
0
        /// <summary>
        /// Reads the model from the specified binary stream.
        /// </summary>
        private ImportedModelContainer TryReadBinary(Stream stream, StlImportOptions importOptions)
        {
            // Check length
            long length = stream.Length;

            if (length < 84)
            {
                throw new SeeingSharpException("Incomplete file (smaller that 84 bytes)");
            }

            // Read number of triangles
            uint numberTriangles = 0;

            using (var reader = new BinaryReader(stream, Encoding.GetEncoding("us-ascii"), true))
            {
                // Read header (is not needed)
                //  (solid stands for Ascii format)
                string header = ENCODING.GetString(reader.ReadBytes(80), 0, 80).Trim();
                if (header.StartsWith("solid", StringComparison.OrdinalIgnoreCase))
                {
                    return(null);
                }

                // Read and check number of triangles
                numberTriangles = ReadUInt32(reader);
                if (length - 84 != numberTriangles * 50)
                {
                    throw new SeeingSharpException("Incomplete file (smaller that expected byte count)");
                }

                // Read geometry data
                VertexStructure newStructure = new VertexStructure((int)numberTriangles * 3);
                newStructure.CreateSurface((int)numberTriangles);
                for (int loop = 0; loop < numberTriangles; loop++)
                {
                    this.ReadTriangle(reader, newStructure, importOptions);
                }

                // Generate result container
                ImportedModelContainer result         = new ImportedModelContainer(importOptions);
                NamedOrGenericKey      geoResourceKey = result.GetResourceKey(
                    RES_KEY_GEO_CLASS, RES_KEY_GEO_NAME);
                result.ImportedResources.Add(new ImportedResourceInfo(
                                                 geoResourceKey,
                                                 () => new GeometryResource(newStructure)));
                GenericObject geoObject = new GenericObject(geoResourceKey);
                result.Objects.Add(geoObject);

                // Append an object which transform the whole coordinate system
                ScenePivotObject rootObject = result.CreateAndAddRootObject();
                result.ParentChildRelationships.Add(new Tuple <SceneObject, SceneObject>(rootObject, geoObject));

                return(result);
            }
        }
예제 #3
0
        /// <summary>
        /// Imports a model from the given file.
        /// </summary>
        /// <param name="sourceFile">The source file to be loaded.</param>
        /// <param name="importOptions">Some configuration for the importer.</param>
        public ImportedModelContainer ImportModel(ResourceLink sourceFile, ImportOptions importOptions)
        {
            // Get import options
            XglImportOptions xglImportOptions = importOptions as XglImportOptions;

            if (xglImportOptions == null)
            {
                throw new SeeingSharpException("Invalid import options for ACImporter!");
            }

            ImportedModelContainer result = new ImportedModelContainer(importOptions);

            // Append an object which transform the whole coordinate system
            ScenePivotObject rootObject = result.CreateAndAddRootObject();

            // Load current model by walking through xml nodes
            using (Stream inStream = sourceFile.OpenInputStream())
            {
                // Handle compressed xgl files (extension zgl)
                Stream nextStream = inStream;
                if (sourceFile.FileExtension.Equals("zgl", StringComparison.OrdinalIgnoreCase))
                {
                    // Skip the first bytes in case of compression
                    //  see https://github.com/assimp/assimp/blob/master/code/XGLLoader.cpp
                    inStream.ReadByte();
                    inStream.ReadByte();
                    nextStream = new System.IO.Compression.DeflateStream(inStream, CompressionMode.Decompress);
                }

                // Read all xml data
                try
                {
                    using (XmlReader inStreamXml = XmlReader.Create(nextStream, new XmlReaderSettings()
                    {
                        CloseInput = false
                    }))
                    {
                        while (inStreamXml.Read())
                        {
                            try
                            {
                                if (inStreamXml.NodeType != XmlNodeType.Element)
                                {
                                    continue;
                                }

                                switch (inStreamXml.Name)
                                {
                                case NODE_NAME_DATA:
                                    break;

                                case NODE_NAME_BACKGROUND:
                                    break;

                                case NODE_NAME_LIGHTING:
                                    break;

                                case NODE_NAME_TEXTURE:
                                    ImportTexture(inStreamXml, result);
                                    break;

                                case NODE_NAME_MESH:
                                    ImportMesh(inStreamXml, result, xglImportOptions);
                                    break;

                                case NODE_NAME_OBJECT:
                                    ImportObject(inStreamXml, result, rootObject, xglImportOptions);
                                    break;

                                default:
                                    break;
                                }
                            }
                            catch (Exception ex)
                            {
                                // Get current line and column
                                int          currentLine   = 0;
                                int          currentColumn = 0;
                                IXmlLineInfo lineInfo      = inStreamXml as IXmlLineInfo;
                                if (lineInfo != null)
                                {
                                    currentLine   = lineInfo.LineNumber;
                                    currentColumn = lineInfo.LinePosition;
                                }

                                // Throw an exception with more detail where the error was raised originally
                                throw new SeeingSharpGraphicsException(string.Format(
                                                                           "Unable to read file {0} because of an error while reading xml at {1}",
                                                                           sourceFile,
                                                                           currentLine + ", " + currentColumn), ex);
                            }
                        }
                    }
                }
                finally
                {
                    if (inStream != nextStream)
                    {
                        nextStream.Dispose();
                    }
                }
            }

            return(result);
        }