Example #1
0
        public static void Restore(DMesh3 mesh, BinaryReader reader)
        {
            int version = reader.ReadInt32();

            if (version != DMesh3Version)
            {
                throw new Exception("gSerialization.Restore: Incorrect DMesh3Version!");
            }

            MeshComponents components = (MeshComponents)reader.ReadInt32();

            Restore(mesh.VerticesBuffer, reader);
            Restore(mesh.TrianglesBuffer, reader);
            Restore(mesh.EdgesBuffer, reader);
            Restore(mesh.EdgesRefCounts.RawRefCounts, reader);

            if ((components & MeshComponents.VertexNormals) != 0)
            {
                mesh.EnableVertexNormals(Vector3F.AxisY);
                Restore(mesh.NormalsBuffer, reader);
            }
            else
            {
                mesh.DiscardVertexNormals();
            }

            if ((components & MeshComponents.VertexColors) != 0)
            {
                mesh.EnableVertexColors(Vector3F.One);
                Restore(mesh.ColorsBuffer, reader);
            }
            else
            {
                mesh.DiscardVertexColors();
            }

            if ((components & MeshComponents.VertexUVs) != 0)
            {
                mesh.EnableVertexUVs(Vector2F.Zero);
                Restore(mesh.UVBuffer, reader);
            }
            else
            {
                mesh.DiscardVertexUVs();
            }

            if ((components & MeshComponents.FaceGroups) != 0)
            {
                mesh.EnableTriangleGroups(0);
                Restore(mesh.GroupsBuffer, reader);
            }
            else
            {
                mesh.DiscardTriangleGroups();
            }

            mesh.RebuildFromEdgeRefcounts();
        }
Example #2
0
        public static void test_local_param()
        {
            //DMesh3 mesh = TestUtil.LoadTestInputMesh("plane_250v.obj");
            //DMesh3 mesh = TestUtil.LoadTestInputMesh("hemisphere_nicemesh_3k.obj");
            DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_open_base.obj");

            mesh.EnableVertexUVs(Vector2f.Zero);

            DMeshAABBTree3 spatial = new DMeshAABBTree3(mesh);

            spatial.Build();

            //int tid = spatial.FindNearestTriangle(Vector3d.Zero);
            //Frame3f seedF = new Frame3f(Vector3d.Zero, Vector3d.AxisY);
            int     tid   = 3137;
            Frame3f seedF = mesh.GetTriFrame(tid);

            Index3i seedNbrs = mesh.GetTriangle(tid);

            MeshLocalParam param = new MeshLocalParam(mesh.MaxVertexID,
                                                      mesh.GetVertexf, mesh.GetVertexNormal, mesh.VtxVerticesItr);

            param.ComputeToMaxDistance(seedF, seedNbrs, float.MaxValue);

            float fR = param.MaxUVDistance;

            param.TransformUV(0.5f / fR, 0.5f * Vector2f.One);

            param.ApplyUVs((vid, uv) => { mesh.SetVertexUV(vid, uv); });

            TestUtil.SetColorsFromScalarF(mesh, (vid) => { return(param.GetUV(vid).Distance(0.5f * Vector2f.One)); }, new Vector2f(0, 0.5f));

            OBJWriter        writer = new OBJWriter();
            var              s      = new System.IO.StreamWriter(Program.TEST_OUTPUT_PATH + "mesh_local_param.obj", false);
            List <WriteMesh> wm     = new List <WriteMesh>()
            {
                new WriteMesh(mesh)
            };
            WriteOptions opt = new WriteOptions()
            {
                bCombineMeshes  = false, bWriteGroups = false, bPerVertexColors = true, bPerVertexUVs = true,
                AsciiHeaderFunc = () => { return("mttllib checkerboard.mtl\r\nusemtl checkerboard\r\n"); }
            };

            writer.Write(s, wm, opt);
            s.Close();
        }
Example #3
0
        public static void CalculateUVs(this DMesh3 dMesh)
        {
            dMesh.EnableVertexUVs(Vector2f.Zero);
            OrthogonalPlaneFit3 orth          = new OrthogonalPlaneFit3(dMesh.Vertices());
            Frame3f             frame         = new Frame3f(orth.Origin, orth.Normal);
            AxisAlignedBox3d    bounds        = dMesh.CachedBounds;
            AxisAlignedBox2d    boundsInFrame = new AxisAlignedBox2d();

            for (int i = 0; i < 8; i++)
            {
                boundsInFrame.Contain(frame.ToPlaneUV((Vector3f)bounds.Corner(i), 3));
            }
            Vector2f min    = (Vector2f)boundsInFrame.Min;
            float    width  = (float)boundsInFrame.Width;
            float    height = (float)boundsInFrame.Height;

            for (int i = 0; i < dMesh.VertexCount; i++)
            {
                Vector2f UV = frame.ToPlaneUV((Vector3f)dMesh.GetVertex(i), 3);
                UV.x = (UV.x - min.x) / width;
                UV.y = (UV.y - min.y) / height;
                dMesh.SetVertexUV(i, UV);
            }
        }
Example #4
0
        public virtual DMesh3 RestoreDMesh(TypedAttribSet attributes)
        {
            bool           is_compressed = false;
            TypedAttribSet meshAttr      = find_struct(attributes, IOStrings.BinaryDMeshStruct);

            if (meshAttr == null)
            {
                meshAttr      = find_struct(attributes, IOStrings.CompressedDMeshStruct);
                is_compressed = true;
            }
            if (meshAttr == null)
            {
                throw new Exception("SOFactory.RestoreDMesh: DMesh binary or compressed struct not found!");
            }

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

            VectorArray3i t = null;

            int[] g = null;

            IndexArray4i e = null;

            short[] e_ref = null;

            var storageMode = IOStrings.MeshStorageMode.EdgeRefCounts;

            if (meshAttr.ContainsKey(IOStrings.AMeshStorageMode))
            {
                storageMode = (IOStrings.MeshStorageMode)(int) meshAttr[IOStrings.AMeshStorageMode];
            }

            if (is_compressed)
            {
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshVertices3Compressed))
                {
                    v = meshAttr[IOStrings.AMeshVertices3Compressed] as VectorArray3d;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshNormals3Compressed))
                {
                    n = meshAttr[IOStrings.AMeshNormals3Compressed] as VectorArray3f;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshColors3Compressed))
                {
                    c = meshAttr[IOStrings.AMeshColors3Compressed] as VectorArray3f;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshUVs2Compressed))
                {
                    uv = meshAttr[IOStrings.AMeshUVs2Compressed] as VectorArray2f;
                }

                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshTrianglesCompressed))
                {
                    t = meshAttr[IOStrings.AMeshTrianglesCompressed] as VectorArray3i;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshTriangleGroupsCompressed))
                {
                    g = meshAttr[IOStrings.AMeshTriangleGroupsCompressed] as int[];
                }

                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshEdgesCompressed))
                {
                    e = meshAttr[IOStrings.AMeshEdgesCompressed] as IndexArray4i;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshEdgeRefCountsCompressed))
                {
                    e_ref = meshAttr[IOStrings.AMeshEdgeRefCountsCompressed] as short[];
                }
            }
            else
            {
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshVertices3Binary))
                {
                    v = meshAttr[IOStrings.AMeshVertices3Binary] as VectorArray3d;
                }
                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;
                }

                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshTrianglesBinary))
                {
                    t = meshAttr[IOStrings.AMeshTrianglesBinary] as VectorArray3i;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshTriangleGroupsBinary))
                {
                    g = meshAttr[IOStrings.AMeshTriangleGroupsBinary] as int[];
                }

                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshEdgesBinary))
                {
                    e = meshAttr[IOStrings.AMeshEdgesBinary] as IndexArray4i;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshEdgeRefCountsBinary))
                {
                    e_ref = meshAttr[IOStrings.AMeshEdgeRefCountsBinary] as short[];
                }
            }

            DMesh3 m = new DMesh3();

            if (n != null)
            {
                m.EnableVertexNormals(Vector3f.Zero);
            }
            if (c != null)
            {
                m.EnableVertexColors(Vector3f.Zero);
            }
            if (uv != null)
            {
                m.EnableVertexUVs(Vector2f.Zero);
            }
            if (g != null)
            {
                m.EnableTriangleGroups(0);
            }

            if (storageMode == IOStrings.MeshStorageMode.EdgeRefCounts)
            {
                if (v == null || t == null || e == null || e_ref == null)
                {
                    return(null);
                }

                m.VerticesBuffer = new DVector <double>(v);
                if (n != null)
                {
                    m.NormalsBuffer = new DVector <float>(n);
                }
                if (c != null)
                {
                    m.ColorsBuffer = new DVector <float>(c);
                }
                if (uv != null)
                {
                    m.UVBuffer = new DVector <float>(uv);
                }
                m.TrianglesBuffer = new DVector <int>(t);
                if (g != null)
                {
                    m.GroupsBuffer = new DVector <int>(g);
                }

                m.EdgesBuffer    = new DVector <int>(e);
                m.EdgesRefCounts = new RefCountVector(e_ref);
                m.RebuildFromEdgeRefcounts();
            }
            else if (storageMode == IOStrings.MeshStorageMode.Minimal)
            {
                if (v == null || t == null)
                {
                    return(null);
                }

                int           NV    = v.Count;
                NewVertexInfo vinfo = new NewVertexInfo();
                for (int k = 0; k < NV; ++k)
                {
                    vinfo.v = v[k];
                    if (n != null)
                    {
                        vinfo.n = n[k];
                    }
                    if (c != null)
                    {
                        vinfo.c = c[k];
                    }
                    if (uv != null)
                    {
                        vinfo.uv = uv[k];
                    }
                    m.AppendVertex(ref vinfo);
                }

                int NT = t.Count;
                for (int k = 0; k < NT; ++k)
                {
                    Vector3i tri  = t[k];
                    int      setg = (g == null) ? -1 : g[k];
                    m.AppendTriangle(tri, setg);
                }
            }
            else
            {
                throw new Exception("SOFactory.RestoreDMesh: unsupported mesh storage mode");
            }

            return(m);
        }
Example #5
0
        public static void test_uv_insert_string()
        {
            DMesh3 mesh = TestUtil.LoadTestInputMesh("plane_xy_25x25.obj");

            mesh.EnableVertexUVs(Vector2f.Zero);

            DMeshAABBTree3 spatial = new DMeshAABBTree3(mesh);

            spatial.Build();
            int tid = spatial.FindNearestTriangle(Vector3d.Zero);

            PolygonFont2d font = PolygonFont2d.ReadFont("c:\\scratch\\font.bin");

            //List<GeneralPolygon2d> letter = new List<GeneralPolygon2d>(font.Characters.First().Value.Polygons);
            //double targetWidth = 20.0f;
            List <GeneralPolygon2d> letter = font.GetCharacter('a');
            double targetWidth             = 10.0f;

            AxisAlignedBox2d bounds  = font.MaxBounds;
            Vector2d         center  = bounds.Center;
            Vector2d         scale2d = (targetWidth / font.MaxBounds.Width) * new Vector2d(1, 1);


            for (int li = 0; li < letter.Count; ++li)
            {
                GeneralPolygon2d gp = new GeneralPolygon2d(letter[li]);
                gp.Scale(scale2d, center);
                gp.Translate(-center);
                letter[li] = gp;
            }


            List <MeshFaceSelection> letter_interiors = new List <MeshFaceSelection>();

            bool bSimplify = true;

            for (int li = 0; li < letter.Count; ++li)
            {
                GeneralPolygon2d gp = letter[li];

                MeshInsertUVPolyCurve outer = new MeshInsertUVPolyCurve(mesh, gp.Outer);
                Util.gDevAssert(outer.Validate() == ValidationStatus.Ok);
                outer.Apply();
                if (bSimplify)
                {
                    outer.Simplify();
                }

                List <MeshInsertUVPolyCurve> holes = new List <MeshInsertUVPolyCurve>(gp.Holes.Count);
                for (int hi = 0; hi < gp.Holes.Count; ++hi)
                {
                    MeshInsertUVPolyCurve insert = new MeshInsertUVPolyCurve(mesh, gp.Holes[hi]);
                    Util.gDevAssert(insert.Validate() == ValidationStatus.Ok);
                    insert.Apply();
                    if (bSimplify)
                    {
                        insert.Simplify();
                    }
                    holes.Add(insert);
                }


                // find a triangle connected to loop that is inside the polygon
                //   [TODO] maybe we could be a bit more robust about this? at least
                //   check if triangle is too degenerate...
                int      seed_tri   = -1;
                EdgeLoop outer_loop = outer.Loops[0];
                for (int i = 0; i < outer_loop.EdgeCount; ++i)
                {
                    if (!mesh.IsEdge(outer_loop.Edges[i]))
                    {
                        continue;
                    }

                    Index2i  et   = mesh.GetEdgeT(outer_loop.Edges[i]);
                    Vector3d ca   = mesh.GetTriCentroid(et.a);
                    bool     in_a = gp.Outer.Contains(ca.xy);
                    Vector3d cb   = mesh.GetTriCentroid(et.b);
                    bool     in_b = gp.Outer.Contains(cb.xy);
                    if (in_a && in_b == false)
                    {
                        seed_tri = et.a;
                        break;
                    }
                    else if (in_b && in_a == false)
                    {
                        seed_tri = et.b;
                        break;
                    }
                }
                Util.gDevAssert(seed_tri != -1);

                // make list of all outer & hole edges
                HashSet <int> loopEdges = new HashSet <int>(outer_loop.Edges);
                foreach (var insertion in holes)
                {
                    foreach (int eid in insertion.Loops[0].Edges)
                    {
                        loopEdges.Add(eid);
                    }
                }

                // flood-fill inside loop from seed triangle
                MeshFaceSelection sel = new MeshFaceSelection(mesh);
                sel.FloodFill(seed_tri, null, (eid) => { return(loopEdges.Contains(eid) == false); });
                letter_interiors.Add(sel);
            }

            // extrude regions
            Func <Vector3d, Vector3f, int, Vector3d> OffsetF = (v, n, i) => {
                return(v + Vector3d.AxisZ);
            };

            foreach (var interior in letter_interiors)
            {
                MeshExtrudeFaces extrude = new MeshExtrudeFaces(mesh, interior);
                extrude.ExtrudedPositionF = OffsetF;
                extrude.Extrude();
            }

            TestUtil.WriteTestOutputMesh(mesh, "insert_uv_string.obj");
        }
Example #6
0
        public static void test_uv_insert_segment()
        {
            DMesh3 mesh = TestUtil.LoadTestInputMesh("plane_250v.obj");

            mesh.EnableVertexUVs(Vector2f.Zero);

            MeshTransforms.ConvertYUpToZUp(mesh);

            DMeshAABBTree3 spatial = new DMeshAABBTree3(mesh);

            spatial.Build();
            int tid = spatial.FindNearestTriangle(Vector3d.Zero);

            //Polygon2d poly = Polygon2d.MakeRectangle(Vector2d.Zero, 5, 5);
            Polygon2d poly = Polygon2d.MakeCircle(5, 13);
            //PolyLine2d poly = new PolyLine2d( new Vector2d[] { -5 * Vector2d.One, 5 * Vector2d.One });


            //int tri_edge0 = mesh.GetTriEdge(tid, 0);
            //Index2i edge0_tris = mesh.GetEdgeT(tri_edge0);
            //Index2i edge0_verts = mesh.GetEdgeV(tri_edge0);
            //Vector3d v0 = mesh.GetVertex(edge0_verts.a), v1 = mesh.GetVertex(edge0_verts.b);
            //Vector3d c = mesh.GetTriCentroid(tid);
            //Polygon2d poly = new Polygon2d(new Vector2d[] {
            //    Vector2d.Lerp(v0.xy, v1.xy, -0.25),
            //    Vector2d.Lerp(v0.xy, v1.xy, 1.5),
            //    c.xy
            //});

            MeshInsertUVPolyCurve insert = new MeshInsertUVPolyCurve(mesh, poly);

            insert.Apply();



            Polygon2d     test_poly = new Polygon2d();
            List <double> distances = new List <double>();
            List <int>    nearests  = new List <int>();

            for (int i = 0; i < insert.Loops[0].VertexCount; ++i)
            {
                Vector2d v = mesh.GetVertex(insert.Loops[0].Vertices[i]).xy;
                test_poly.AppendVertex(v);
                int iNear; double fNear;
                distances.Add(poly.DistanceSquared(v, out iNear, out fNear));
                nearests.Add(iNear);
            }

            System.Console.WriteLine("inserted loop poly has {0} edges", insert.Loops[0].EdgeCount);

            // find a triangle connected to loop that is inside the polygon
            //   [TODO] maybe we could be a bit more robust about this? at least
            //   check if triangle is too degenerate...
            int seed_tri = -1;

            for (int i = 0; i < insert.Loops[0].EdgeCount; ++i)
            {
                Index2i  et   = mesh.GetEdgeT(insert.Loops[0].Edges[i]);
                Vector3d ca   = mesh.GetTriCentroid(et.a);
                bool     in_a = poly.Contains(ca.xy);
                Vector3d cb   = mesh.GetTriCentroid(et.b);
                bool     in_b = poly.Contains(cb.xy);
                if (in_a && in_b == false)
                {
                    seed_tri = et.a;
                    break;
                }
                else if (in_b && in_a == false)
                {
                    seed_tri = et.b;
                    break;
                }
            }
            Util.gDevAssert(seed_tri != -1);

            // flood-fill inside loop
            HashSet <int>     loopEdges = new HashSet <int>(insert.Loops[0].Edges);
            MeshFaceSelection sel       = new MeshFaceSelection(mesh);

            sel.FloodFill(seed_tri, null, (eid) => { return(loopEdges.Contains(eid) == false); });

            // delete inside loop
            MeshEditor editor = new MeshEditor(mesh);

            editor.RemoveTriangles(sel, true);


            MeshTransforms.ConvertZUpToYUp(mesh);

            TestUtil.WriteTestOutputMesh(mesh, "insert_uv_segment.obj");



            //OBJWriter writer = new OBJWriter();
            //var s = new System.IO.StreamWriter(Program.TEST_OUTPUT_PATH + "mesh_local_param.obj", false);
            //List<WriteMesh> wm = new List<WriteMesh>() { new WriteMesh(mesh) };
            //WriteOptions opt = new WriteOptions() {
            //    bCombineMeshes = false, bWriteGroups = false, bPerVertexColors = true, bPerVertexUVs = true,
            //    AsciiHeaderFunc = () => { return "mttllib checkerboard.mtl\r\nusemtl checkerboard\r\n"; }
            //};
            //writer.Write(s, wm, opt);
            //s.Close();
        }