예제 #1
0
        public static void WriteObj(FileInfo file, IGeometryData geo)
        {
            var meshes = new List <WriteMesh>();
            var mesh   = new SimpleMesh();

            var map     = new Dictionary <Vector3, int>();
            var indeces = new List <int>();

            for (var index = 0; index < geo.Positions.Length; index++)
            {
                var v = geo.Positions[index];
                if (!map.ContainsKey(v))
                {
                    map.Add(v, map.Count);
                }
            }
            for (var index = 0; index < geo.Indices.Length; index++)
            {
                var i = geo.Indices[index];
                var v = geo.Positions[i];
                indeces.Add(map[v]);
            }


            var points = map.Keys.ToArray();
            var pcount = points.Length * 3;
            var pp     = new double[pcount];
            var pindex = 0;

            for (var index = 0; index < points.Length; index++)
            {
                var v = points[index];
                pp[pindex++] = v.X;
                pp[pindex++] = v.Y;
                pp[pindex++] = v.Z;
            }
            mesh.Initialize(new VectorArray3d(pp), new VectorArray3i(indeces.ToArray()));

            meshes.Add(new WriteMesh(mesh, $"d3dlab export"));

            StandardMeshWriter.WriteFile(file.FullName, meshes, WriteOptions.Defaults);
        }
예제 #2
0
        public virtual SimpleMesh RestoreSimpleMesh(TypedAttribSet attributes, bool bSwapRightLeft)
        {
            bool           bBinary  = true;
            TypedAttribSet meshAttr = find_struct(attributes, IOStrings.BinaryMeshStruct);

            if (meshAttr == null)
            {
                meshAttr = find_struct(attributes, IOStrings.AsciiMeshStruct);
                bBinary  = false;
            }
            if (meshAttr == null)
            {
                throw new Exception("SOFactory.RestoreSimpleMesh: Mesh ascii/binary struct not found!");
            }


            VectorArray3d v = null;
            VectorArray3i t = null;
            VectorArray3f n = null, c = null;
            VectorArray2f uv = null;

            if (bBinary)
            {
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshVertices3Binary))
                {
                    v = meshAttr[IOStrings.AMeshVertices3Binary] as VectorArray3d;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshTrianglesBinary))
                {
                    t = meshAttr[IOStrings.AMeshTrianglesBinary] as VectorArray3i;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshNormals3Binary))
                {
                    n = meshAttr[IOStrings.AMeshNormals3Binary] as VectorArray3f;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshColors3Binary))
                {
                    c = meshAttr[IOStrings.AMeshColors3Binary] as VectorArray3f;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshUVs2Binary))
                {
                    uv = meshAttr[IOStrings.AMeshUVs2Binary] as VectorArray2f;
                }
            }
            else
            {
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshVertices3))
                {
                    v = meshAttr[IOStrings.AMeshVertices3] as VectorArray3d;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshTriangles))
                {
                    t = meshAttr[IOStrings.AMeshTriangles] as VectorArray3i;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshNormals3))
                {
                    n = meshAttr[IOStrings.AMeshNormals3] as VectorArray3f;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshColors3))
                {
                    c = meshAttr[IOStrings.AMeshColors3] as VectorArray3f;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshUVs2))
                {
                    uv = meshAttr[IOStrings.AMeshUVs2] as VectorArray2f;
                }
            }

            if (v == null || t == null)
            {
                return(null);
            }

            if (bSwapRightLeft)
            {
                int N = v.Count;
                for (int i = 0; i < N; ++i)
                {
                    Vector3d vv = v[i];
                    v.Set(i, -vv.x, vv.y, -vv.z);
                }
                if (n != null && n.Count == N)
                {
                    for (int i = 0; i < N; ++i)
                    {
                        Vector3f nn = n[i];
                        n.Set(i, -nn.x, nn.y, -nn.z);
                    }
                }
            }

            SimpleMesh m = new SimpleMesh();

            m.Initialize(v, t, n, c, uv);
            return(m);
        }
예제 #3
0
        public virtual ExportStatus Export(FScene scene, string filename)
        {
            int[]            vertexMap = new int[2048]; // temp
            List <WriteMesh> vMeshes   = new List <WriteMesh>();

            if (WriteFaceGroups)
            {
                throw new Exception("SceneMeshExporter.Export: writing face groups has not yet been implemented!");
            }

            // extract all the mesh data we want to export
            foreach (SceneObject so in scene.SceneObjects)
            {
                if (so.IsTemporary || so.IsSurface == false || SceneUtil.IsVisible(so) == false)
                {
                    continue;
                }
                if (SOFilterF != null && SOFilterF(so) == false)
                {
                    continue;
                }

                // if this SO has an internal mesh we can just copy, use it
                if (so is DMeshSO)
                {
                    DMeshSO meshSO = so as DMeshSO;

                    // todo: flags

                    // make a copy of mesh
                    DMesh3 m = new DMesh3(meshSO.Mesh, true);

                    // transform to scene coords and swap left/right
                    foreach (int vid in m.VertexIndices())
                    {
                        Vector3f v = (Vector3f)m.GetVertex(vid);
                        v = SceneTransforms.ObjectToScene(meshSO, v);
                        v = UnityUtil.SwapLeftRight(v);
                        m.SetVertex(vid, v);
                    }
                    m.ReverseOrientation();

                    vMeshes.Add(new WriteMesh(m, so.Name));
                }


                // Look for lower-level fGameObject items to export. By default
                // this is anything with a MeshFilter, override CollectGOChildren
                // or use GOFilterF to add restrictions
                List <fGameObject> vExports = CollectGOChildren(so);
                if (vExports.Count > 0)
                {
                    SimpleMesh m = new SimpleMesh();
                    m.Initialize(WriteNormals, WriteVertexColors, WriteUVs, WriteFaceGroups);
                    int groupCounter = 1;

                    foreach (fGameObject childgo in vExports)
                    {
                        if (GOFilterF != null && GOFilterF(so, childgo) == false)
                        {
                            continue;
                        }

                        if (AppendGOMesh(childgo, m, vertexMap, scene, groupCounter))
                        {
                            groupCounter++;
                        }
                    }

                    vMeshes.Add(new WriteMesh(m, so.Name));
                }
            }


            // ok, we are independent of Scene now and can write in bg thread
            if (WriteInBackgroundThreads)
            {
                ExportStatus status = new ExportStatus()
                {
                    Exporter = this, IsComputing = true
                };
                WriteOptions useOptions = Options;
                useOptions.ProgressFunc = (cur, max) => {
                    status.Progress    = cur;
                    status.MaxProgress = max;
                };
                BackgroundWriteThread t = new BackgroundWriteThread()
                {
                    Meshes      = vMeshes, options = useOptions, Filename = filename,
                    CompletionF = (result) => {
                        LastWriteStatus         = result.code;
                        LastErrorMessage        = result.message;
                        status.LastErrorMessage = result.message;
                        status.Ok          = (result.code == IOCode.Ok);
                        status.IsComputing = false;
                        if (BackgroundWriteCompleteF != null)
                        {
                            BackgroundWriteCompleteF(this, status);
                        }
                    }
                };
                t.Start();
                return(status);
            }
            else
            {
                IOWriteResult result = StandardMeshWriter.WriteFile(filename, vMeshes, Options);
                LastWriteStatus  = result.code;
                LastErrorMessage = result.message;
                return(new ExportStatus()
                {
                    Exporter = this, IsComputing = false,
                    Ok = (result.code == IOCode.Ok),
                    LastErrorMessage = result.message
                });
            }
        }
예제 #4
0
        public static SimpleMesh UnityMeshToSimpleMesh(UnityEngine.Mesh mesh, bool bSwapLeftright)
        {
            SimpleMesh smesh = new SimpleMesh();

            Vector3[] vertices = mesh.vertices;
            Vector3[] normals  = mesh.normals;
            Color32[] colors32 = mesh.colors32;
            Color[]   colors   = mesh.colors;
            Vector2[] uv       = mesh.uv;

            bool bNormals    = (normals.Length == mesh.vertexCount);
            bool bColors     = (colors.Length == mesh.vertexCount || colors32.Length == mesh.vertexCount);
            bool bByteColors = (colors32.Length == mesh.vertexCount);
            bool bUVs        = (uv.Length == mesh.vertexCount);

            smesh.Initialize(bNormals, bColors, bUVs, false);


            for (int i = 0; i < mesh.vertexCount; ++i)
            {
                Vector3d v = vertices[i];
                if (bSwapLeftright)
                {
                    v.x = -v.x;
                    v.z = -v.z;
                }
                NewVertexInfo vInfo = new NewVertexInfo(v);
                if (bNormals)
                {
                    vInfo.bHaveN = true;
                    vInfo.n      = normals[i];
                    if (bSwapLeftright)
                    {
                        vInfo.n.x = -vInfo.n.x;
                        vInfo.n.z = -vInfo.n.z;
                    }
                }
                if (bColors)
                {
                    vInfo.bHaveC = true;
                    if (bByteColors)
                    {
                        vInfo.c = new Colorf(colors32[i].r, colors32[i].g, colors32[i].b, 255);
                    }
                    else
                    {
                        vInfo.c = colors[i];
                    }
                }
                if (bUVs)
                {
                    vInfo.bHaveUV = true;
                    vInfo.uv      = uv[i];
                }

                int vid = smesh.AppendVertex(vInfo);
                if (vid != i)
                {
                    throw new InvalidOperationException("UnityUtil.UnityMeshToSimpleMesh: indices weirdness...");
                }
            }

            int[] triangles = mesh.triangles;
            for (int i = 0; i < triangles.Length / 3; ++i)
            {
                smesh.AppendTriangle(triangles[3 * i], triangles[3 * i + 1], triangles[3 * i + 2]);
            }

            return(smesh);
        }
예제 #5
0
        public ExportStatus Export(FScene s, string filename)
        {
            List <WriteMesh> vMeshes = new List <WriteMesh>();

            if (WriteFaceGroups)
            {
                throw new Exception("SceneMeshExporter.Export: writing face groups has not yet been implemented!");
            }

            foreach (SceneObject so in s.SceneObjects)
            {
                if (so.IsTemporary)
                {
                    continue;
                }

                SimpleMesh m = new SimpleMesh();
                m.Initialize(WriteNormals, WriteVertexColors, WriteUVs, WriteFaceGroups);
                int groupCounter = 1;

                GameObject rootgo = so.RootGameObject;

                int[] vertexMap = new int[2048];
                foreach (GameObject childgo in rootgo.Children())
                {
                    MeshFilter filter = childgo.GetComponent <MeshFilter>();
                    if (filter == null || filter.mesh == null)
                    {
                        continue;
                    }
                    if (GOFilterF != null && GOFilterF(so, childgo) == false)
                    {
                        continue;
                    }

                    Mesh      curMesh  = filter.sharedMesh;
                    Vector3[] vertices = curMesh.vertices;
                    Vector3[] normals  = (WriteNormals) ? curMesh.normals : null;
                    Color[]   colors   = (WriteVertexColors) ? curMesh.colors : null;
                    Vector2[] uvs      = (WriteUVs) ? curMesh.uv : null;

                    if (vertexMap.Length < curMesh.vertexCount)
                    {
                        vertexMap = new int[curMesh.vertexCount * 2];
                    }

                    for (int i = 0; i < curMesh.vertexCount; ++i)
                    {
                        NewVertexInfo vi = new NewVertexInfo();
                        vi.bHaveN = WriteNormals; vi.bHaveC = WriteVertexColors; vi.bHaveUV = WriteUVs;

                        Vector3 v = vertices[i];
                        // local to world
                        v = filter.gameObject.transform.TransformPoint(v);
                        // world back to scene
                        vi.v = UnityUtil.SwapLeftRight(s.RootGameObject.transform.InverseTransformPoint(v));

                        if (WriteNormals)
                        {
                            Vector3 n = normals[i];
                            n    = filter.gameObject.transform.TransformDirection(n);
                            vi.n = UnityUtil.SwapLeftRight(s.RootGameObject.transform.InverseTransformDirection(n));
                        }
                        if (WriteVertexColors)
                        {
                            vi.c = colors[i];
                        }
                        if (WriteUVs)
                        {
                            vi.uv = uvs[i];
                        }

                        vertexMap[i] = m.AppendVertex(vi);
                    }

                    int[] triangles  = curMesh.triangles;
                    int   nTriangles = triangles.Length / 3;
                    for (int i = 0; i < nTriangles; ++i)
                    {
                        int a = vertexMap[triangles[3 * i]];
                        int b = vertexMap[triangles[3 * i + 1]];
                        int c = vertexMap[triangles[3 * i + 2]];
                        m.AppendTriangle(a, c, b, groupCounter);  // TRI ORIENTATION IS REVERSED HERE!!
                    }
                    groupCounter++;
                }

                vMeshes.Add(new WriteMesh(m, so.Name));
            }


            if (WriteInBackgroundThreads)
            {
                ExportStatus status = new ExportStatus()
                {
                    Exporter = this, IsComputing = true
                };
                WriteOptions useOptions = Options;
                useOptions.ProgressFunc = (cur, max) => {
                    status.Progress    = cur;
                    status.MaxProgress = max;
                };
                BackgroundWriteThread t = new BackgroundWriteThread()
                {
                    Meshes      = vMeshes, options = useOptions, Filename = filename,
                    CompletionF = (result) => {
                        LastWriteStatus         = result.code;
                        LastErrorMessage        = result.message;
                        status.LastErrorMessage = result.message;
                        status.Ok          = (result.code == IOCode.Ok);
                        status.IsComputing = false;
                    }
                };
                t.Start();
                return(status);
            }
            else
            {
                IOWriteResult result = StandardMeshWriter.WriteFile(filename, vMeshes, Options);
                LastWriteStatus  = result.code;
                LastErrorMessage = result.message;
                return(new ExportStatus()
                {
                    Exporter = this, IsComputing = false,
                    Ok = (result.code == IOCode.Ok),
                    LastErrorMessage = result.message
                });
            }
        }
예제 #6
0
        public static void WriteObj(FileInfo file, IEnumerable <IFileGeometry3D> geometries)
        {
            var meshes = new List <WriteMesh>();
            var mesh   = new SimpleMesh();

            var map     = new Dictionary <Vector3, int>();
            var indeces = new List <int>();

            foreach (var geo in geometries)
            {
                //var pcount = geo.Positions.Count * 3;
                //var pp = new double[pcount];
                //var pindex = 0;
                //for(var index =0; index < geo.Positions.Count; index++) {
                //    var v = geo.Positions[index];
                //    pp[pindex++] = v.X;
                //    pp[pindex++] = v.Y;
                //    pp[pindex++] = v.Z;
                //}
                //mesh.Initialize(new VectorArray3d(pp), new VectorArray3i(geo.Indices.ToArray()));
                for (var index = 0; index < geo.Positions.Count; index++)
                {
                    var v = geo.Positions[index];
                    if (!map.ContainsKey(v))
                    {
                        map.Add(v, map.Count);
                    }
                }
                for (var index = 0; index < geo.Indices.Count; index++)
                {
                    var i = geo.Indices[index];
                    var v = geo.Positions[i];
                    indeces.Add(map[v]);
                }
            }

            var points = map.Keys.ToArray();
            var pcount = points.Length * 3;
            var pp     = new double[pcount];
            var pindex = 0;

            for (var index = 0; index < points.Length; index++)
            {
                var v = points[index];
                pp[pindex++] = v.X;
                pp[pindex++] = v.Y;
                pp[pindex++] = v.Z;
            }
            mesh.Initialize(new VectorArray3d(pp), new VectorArray3i(indeces.ToArray()));

            meshes.Add(new WriteMesh(mesh, $"d3dlab export"));

            StandardMeshWriter.WriteFile(file.FullName, meshes, WriteOptions.Defaults);

            //var obj = new OBJWriter();
            //System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
            //using (var stream = File.Open(file.FullName, FileMode.Create)) {
            //    using (var writer = new StreamWriter(stream, Encoding.UTF8)) {
            //        obj.Write(writer, meshes, WriteOptions.Defaults);
            //    }
            //}
        }