Exemple #1
0
 public IOReadResult Read(TextReader reader, ReadOptions options, IMeshBuilder builder)
 {
     return(new IOReadResult(IOCode.FormatNotSupportedError, "text read not supported for 3DS format"));
 }
Exemple #2
0
        private bool is3ds;      // usd to shwo that the 4D4D magic number has been found


        public IOReadResult Read(BinaryReader reader, ReadOptions options, IMeshBuilder builder)
        {
            ushort ChunkID;
            String ChnkID = "";
            UInt32 Clength;

            MeshName = "";
            hasMesh  = false;
            is3ds    = false;

            // Process the file - fails very politely when there is no more data
            while (true)
            {
                //Get the Id of the next Chunk
                try {
                    ChunkID = reader.ReadUInt16();
                } catch {
                    break;
                }
                ChnkID = ChunkID.ToString("X");

                //Get the size of the next chunk in chars
                Clength = reader.ReadUInt32();

                //Process based on Chunk ID
                switch (ChnkID)
                {
                case "4D4D":
                    //This is a new file header
                    is3ds = true;
                    reader.ReadChars(10);
                    break;

                case "3D3D":
                    //This is a new Object Header
                    reader.ReadChars(10);
                    break;

                case "4000":
                    //This is an object Block. Store the name temporarily in case it is a mesh
                    List <char> name = new List <char>();
                    while (true)
                    {
                        char next = reader.ReadChar();
                        if (next == 0)
                        {
                            break;
                        }
                        name.Add(next);
                    }
                    MeshName = new String(name.ToArray <char>());
                    break;

                case "4100":
                    // This is a new Mesh. Retrieve the name and add if the builder supports Metadata
                    builder.AppendNewMesh(false, false, false, false);
                    if (builder.SupportsMetaData)
                    {
                        builder.AppendMetaData("name", MeshName);
                    }
                    break;

                case "4110":
                    // List of Vertexes
                    ushort VertexCount = reader.ReadUInt16();
                    for (int x = 0; x < VertexCount; x++)
                    {
                        double X = reader.ReadSingle();
                        double Y = reader.ReadSingle();
                        double Z = reader.ReadSingle();
                        builder.AppendVertex(X, Y, Z);
                    }
                    break;

                case "4120":
                    // List of Triangles
                    ushort PolygonCount = reader.ReadUInt16();
                    for (int j = 0; j < PolygonCount; j++)
                    {
                        int a     = reader.ReadInt16();
                        int b     = reader.ReadInt16();
                        int c     = reader.ReadInt16();
                        int flags = reader.ReadUInt16();
                        builder.AppendTriangle(a, b, c);
                    }
                    break;

                case "4130":
                    // Mapping from Vertex to Material - retrieved but not currently used
                    List <char> mname = new List <char>();
                    while (true)
                    {
                        char next = reader.ReadChar();
                        if (next == 0)
                        {
                            break;
                        }
                        mname.Add(next);
                    }
                    string MatName = new String(mname.ToArray <char>());
                    ushort entries = reader.ReadUInt16();
                    for (int i = 0; i < entries; i++)
                    {
                        ushort face = reader.ReadUInt16();
                    }
                    break;

                case "4140":
                    // List of UVs per vertex
                    ushort uvCount = reader.ReadUInt16();
                    for (ushort y = 0; y < uvCount; y++)
                    {
                        Vector2f UV = new Vector2f(reader.ReadSingle(), reader.ReadSingle());
                        builder.SetVertexUV(y, UV);
                    }
                    break;

                default:
                    // Any other chunk - retrieved and not used - held in dump temporarily for debug
                    char[] dump = reader.ReadChars((int)Clength - 6);
                    break;
                }
            }
            if (!is3ds)
            {
                return(new IOReadResult(IOCode.FileAccessError, "File is not in .3DS format"));
            }
            else if (!hasMesh)
            {
                return(new IOReadResult(IOCode.FileParsingError, "no mesh found in file"));
            }
            else
            {
                return(new IOReadResult(IOCode.Ok, ""));
            }
        }
Exemple #3
0
        public IOReadResult Read(TextReader reader, ReadOptions options, IMeshBuilder builder)
        {
            if (options.CustomFlags != null)
            {
                ParseArguments(options.CustomFlags);
            }

            // format is just this, with facet repeated N times:
            //solid "stl_ascii"
            //  facet normal 0.722390830517 -0.572606861591 0.387650430202
            //    outer loop
            //      vertex 0.00659640412778 4.19127035141 -0.244179025292
            //      vertex -0.0458636470139 4.09951019287 -0.281960010529
            //      vertex 0.0286951716989 4.14693021774 -0.350856184959
            //    endloop
            //  endfacet
            //endsolid

            bool in_solid = false;

            //bool in_facet = false;
            //bool in_loop = false;
            //int vertices_in_loop = 0;

            Objects = new List <STLSolid>();

            int nLines = 0;

            while (reader.Peek() >= 0)
            {
                string line = reader.ReadLine();
                nLines++;
                string[] tokens = line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);
                if (tokens.Length == 0)
                {
                    continue;
                }

                if (tokens[0].Equals("vertex", StringComparison.OrdinalIgnoreCase))
                {
                    float x = (tokens.Length > 1) ? Single.Parse(tokens[1]) : 0;
                    float y = (tokens.Length > 2) ? Single.Parse(tokens[2]) : 0;
                    float z = (tokens.Length > 3) ? Single.Parse(tokens[3]) : 0;
                    append_vertex(x, y, z);

                    // [RMS] we don't really care about these lines...
                    //} else if (tokens[0].Equals("outer", StringComparison.OrdinalIgnoreCase)) {
                    //    in_loop = true;
                    //    vertices_in_loop = 0;

                    //} else if (tokens[0].Equals("endloop", StringComparison.OrdinalIgnoreCase)) {
                    //    in_loop = false;
                }
                else if (tokens[0].Equals("facet", StringComparison.OrdinalIgnoreCase))
                {
                    if (in_solid == false)          // handle bad STL
                    {
                        Objects.Add(new STLSolid()
                        {
                            Name = "unknown_solid"
                        });
                        in_solid = true;
                    }
                    //in_facet = true;
                    // ignore facet normal

                    // [RMS] also don't really need to do anything for this one
                    //} else if (tokens[0].Equals("endfacet", StringComparison.OrdinalIgnoreCase)) {
                    //in_facet = false;
                }
                else if (tokens[0].Equals("solid", StringComparison.OrdinalIgnoreCase))
                {
                    STLSolid newObj = new STLSolid();
                    if (tokens.Length == 2)
                    {
                        newObj.Name = tokens[1];
                    }
                    else
                    {
                        newObj.Name = "object_" + Objects.Count;
                    }
                    Objects.Add(newObj);
                    in_solid = true;
                }
                else if (tokens[0].Equals("endsolid", StringComparison.OrdinalIgnoreCase))
                {
                    // do nothing, done object
                    in_solid = false;
                }
            }

            foreach (STLSolid solid in Objects)
            {
                BuildMesh(solid, builder);
            }

            return(new IOReadResult(IOCode.Ok, ""));
        }
Exemple #4
0
        public IOReadResult Read(TextReader reader, ReadOptions options, IMeshBuilder builder)
        {
            // format is:
            //
            // OFF
            // VCOUNT TCOUNT     (2 ints)
            // x y z
            // ...
            // 3 va vb vc
            // ...
            //

            string first_line = reader.ReadLine();

            if (first_line.StartsWith("OFF") == false)
            {
                return(new IOReadResult(IOCode.FileParsingError, "ascii OFF file must start with OFF header"));
            }

            int nVertexCount   = 0;
            int nTriangleCount = 0;

            int nLines = 0;

            while (reader.Peek() >= 0)
            {
                string line = reader.ReadLine();
                nLines++;
                string[] tokens = line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);
                if (tokens.Length == 0)
                {
                    continue;
                }

                if (tokens[0].StartsWith("#"))
                {
                    continue;
                }

                if (tokens.Length != 3)
                {
                    return(new IOReadResult(IOCode.FileParsingError, "first non-comment line of OFF must be vertex/tri/edge counts, found: " + line));
                }

                nVertexCount   = int.Parse(tokens[0]);
                nTriangleCount = int.Parse(tokens[1]);
                //int nEdgeCount = int.Parse(tokens[2]);
                break;
            }


            builder.AppendNewMesh(false, false, false, false);

            int vi = 0;

            while (vi < nVertexCount && reader.Peek() > 0)
            {
                string line = reader.ReadLine();
                nLines++;
                string[] tokens = line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);
                if (tokens.Length == 0)
                {
                    continue;
                }

                if (tokens[0].StartsWith("#"))
                {
                    continue;
                }

                if (tokens.Length != 3)
                {
                    emit_warning("found invalid OFF vertex line: " + line);
                }

                double x = Double.Parse(tokens[0]);
                double y = Double.Parse(tokens[1]);
                double z = Double.Parse(tokens[2]);
                builder.AppendVertex(x, y, z);
                vi++;
            }
            if (vi < nVertexCount)
            {
                return(new IOReadResult(IOCode.FileParsingError,
                                        string.Format("File specified {0} vertices but only found {1}", nVertexCount, vi)));
            }

            int ti = 0;

            while (ti < nTriangleCount && reader.Peek() > 0)
            {
                string line = reader.ReadLine();
                nLines++;
                string[] tokens = line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);
                if (tokens.Length == 0)
                {
                    continue;
                }

                if (tokens[0].StartsWith("#"))
                {
                    continue;
                }

                if (tokens.Length < 4)
                {
                    emit_warning("found invalid OFF triangle line: " + line);
                }

                int nV = int.Parse(tokens[0]);
                if (nV != 3)
                {
                    emit_warning("found non-triangle polygon in OFF, currently unsupported: " + line);
                }

                int a = int.Parse(tokens[1]);
                int b = int.Parse(tokens[2]);
                int c = int.Parse(tokens[3]);

                builder.AppendTriangle(a, b, c);
                ti++;
            }
            if (ti < nTriangleCount)
            {
                emit_warning(string.Format("File specified {0} triangles but only found {1}", nTriangleCount, ti));
            }

            return(new IOReadResult(IOCode.Ok, ""));
        }
Exemple #5
0
 public IOReadResult Read(BinaryReader reader, ReadOptions options, IMeshBuilder builder)
 {
     return(new IOReadResult(IOCode.FormatNotSupportedError, "binary read not supported for OFF format"));
 }
Exemple #6
0
        /// <summary>
        /// Read mesh file at path, with given Options. Result is stored in MeshBuilder parameter
        /// </summary>
        public IOReadResult Read(string sFilename, ReadOptions options)
        {
            if (MeshBuilder == null)
            {
                return(new IOReadResult(IOCode.GenericReaderError, "MeshBuilder is null!"));
            }

            string sExtension = Path.GetExtension(sFilename);

            if (sExtension.Length < 2)
            {
                return(new IOReadResult(IOCode.InvalidFilenameError, "filename " + sFilename + " does not contain valid extension"));
            }
            sExtension = sExtension.Substring(1);

            MeshFormatReader useReader = null;

            foreach (var reader in Readers)
            {
                foreach (string ext in reader.SupportedExtensions)
                {
                    if (ext.Equals(sExtension, StringComparison.OrdinalIgnoreCase))
                    {
                        useReader = reader;
                    }
                }
                if (useReader != null)
                {
                    break;
                }
            }
            if (useReader == null)
            {
                return(new IOReadResult(IOCode.UnknownFormatError, "format " + sExtension + " is not supported"));
            }

            // save current culture
            var current_culture = Thread.CurrentThread.CurrentCulture;

            try {
                // push invariant culture for write
                if (ReadInvariantCulture)
                {
                    Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
                }

                var result = useReader.ReadFile(sFilename, MeshBuilder, options, on_warning);

                // restore culture
                if (ReadInvariantCulture)
                {
                    Thread.CurrentThread.CurrentCulture = current_culture;
                }

                return(result);
            } catch (Exception e) {
                // restore culture
                if (ReadInvariantCulture)
                {
                    Thread.CurrentThread.CurrentCulture = current_culture;
                }

                return(new IOReadResult(IOCode.GenericReaderError, "Unknown error : exception : " + e.Message));
            }
        }
 public IOReadResult Read(TextReader reader, ReadOptions options, IMeshBuilder builder)
 {
     throw new NotSupportedException("BinaryG3Reader Writer does not support ascii mode");
 }