示例#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();
        }
        void compute_trimmed_mesh()
        {
            // curve is on base leg, map to deformed leg
            // [TODO] really should be doing this via deformation, rather than nearest-point
            DCurve3 curve = new DCurve3(CurveSource.GetICurve());

            for (int i = 0; i < curve.VertexCount; ++i)
            {
                curve[i] = MeshQueries.NearestPointFrame(cachedInputMesh, cachedInputMeshSpatial, curve[i]).Origin;
            }

            TrimmedMesh = new DMesh3(cachedInputMesh);
            TrimmedMesh.EnableTriangleGroups(0);

            AxisAlignedBox3d bounds = TrimmedMesh.CachedBounds;

            // try to find seed based on raycast, which doesn't always work.
            // Note that seed is the seed for the *eroded* region, not the kept region
            Vector3d basePt  = bounds.Center + 10 * bounds.Extents.y * Vector3d.AxisY;
            int      hit_tid = cachedInputMeshSpatial.FindNearestHitTriangle(new Ray3d(basePt, -Vector3d.AxisY));
            Vector3d seed    = cachedInputMesh.GetTriCentroid(hit_tid);

            if (flip_trim_side)
            {
                basePt  = bounds.Center - 10 * bounds.Extents.y * Vector3d.AxisY;
                hit_tid = cachedInputMeshSpatial.FindNearestHitTriangle(new Ray3d(basePt, Vector3d.AxisY));
                seed    = cachedInputMesh.GetTriCentroid(hit_tid);
            }

            MeshTrimLoop trim = new MeshTrimLoop(TrimmedMesh, curve, seed, cachedInputMeshSpatial);

            trim.Trim();

            if (TrimmedMesh.HasVertexColors == false)
            {
                TrimmedMesh.EnableVertexColors(SocketVertexColor);
            }
            else
            {
                foreach (int vid in TrimmedMesh.VertexIndices())
                {
                    TrimmedMesh.SetVertexColor(vid, SocketVertexColor);
                }
            }

            MeshTransforms.FromFrame(TrimmedMesh, cachedInputsTransform);
        }
示例#3
0
        public static void test_basic_fills()
        {
            // test trivial hole-fill

            //List<int> tests = new List<int>() { 0, 1 };
            List <int> tests = new List <int>()
            {
                2
            };

            foreach (int num_test in tests)
            {
                string name;
                DMesh3 mesh = MakeEditTestMesh(num_test, out name);
                mesh.EnableTriangleGroups();

                MeshBoundaryLoops loops;
                try {
                    loops = new MeshBoundaryLoops(mesh);
                    Debug.Assert(loops.Loops.Count > 0);
                } catch (Exception) {
                    System.Console.WriteLine("failed to extract boundary loops for " + name);
                    continue;
                }

                System.Console.WriteLine("Closing " + name + " - {0} holes", loops.Loops.Count);

                bool bOK = true;
                foreach (EdgeLoop loop in loops.Loops)
                {
                    SimpleHoleFiller filler = new SimpleHoleFiller(mesh, loop);
                    Debug.Assert(filler.Validate() == ValidationStatus.Ok);
                    bOK = bOK && filler.Fill(1);
                    Debug.Assert(bOK);
                }
                System.Console.WriteLine("{0}", (bOK) ? "Ok" : "Failed");
                if (bOK)
                {
                    Debug.Assert(mesh.CachedIsClosed);
                }
                TestUtil.WriteTestOutputMesh(mesh, name + "_filled" + ".obj");
            }
        }         // test_basic_fills
示例#4
0
        List <Polygon2d> decompose_cluster_up(DMesh3 mesh)
        {
            optimize_mesh(mesh);
            mesh.CompactInPlace();
            mesh.DiscardTriangleGroups(); mesh.EnableTriangleGroups(0);

            double minLength = Settings.MaxBridgeWidthMM * 0.75;
            double minArea   = minLength * minLength;

            Dictionary <int, double>         areas   = new Dictionary <int, double>();
            Dictionary <int, HashSet <int> > trisets = new Dictionary <int, HashSet <int> >();
            HashSet <int> active_groups = new HashSet <int>();

            Action <int, int> add_tri_to_group = (tid, gid) => {
                mesh.SetTriangleGroup(tid, gid);
                areas[gid] = areas[gid] + mesh.GetTriArea(tid);
                trisets[gid].Add(tid);
            };
            Action <int, int> add_group_to_group = (gid, togid) => {
                var set = trisets[togid];
                foreach (int tid in trisets[gid])
                {
                    mesh.SetTriangleGroup(tid, togid);
                    set.Add(tid);
                }
                areas[togid] += areas[gid];
                active_groups.Remove(gid);
            };
            Func <IEnumerable <int>, int> find_min_area_group = (tri_itr) => {
                int min_gid = -1; double min_area = double.MaxValue;
                foreach (int tid in tri_itr)
                {
                    int    gid = mesh.GetTriangleGroup(tid);
                    double a   = areas[gid];
                    if (a < min_area)
                    {
                        min_area = a;
                        min_gid  = gid;
                    }
                }
                return(min_gid);
            };


            foreach (int eid in MeshIterators.InteriorEdges(mesh))
            {
                Index2i et = mesh.GetEdgeT(eid);
                if (mesh.GetTriangleGroup(et.a) != 0 || mesh.GetTriangleGroup(et.b) != 0)
                {
                    continue;
                }
                int gid = mesh.AllocateTriangleGroup();
                areas[gid]   = 0;
                trisets[gid] = new HashSet <int>();
                active_groups.Add(gid);
                add_tri_to_group(et.a, gid);
                add_tri_to_group(et.b, gid);
            }
            foreach (int tid in mesh.TriangleIndices())
            {
                if (mesh.GetTriangleGroup(tid) != 0)
                {
                    continue;
                }
                int gid = find_min_area_group(mesh.TriTrianglesItr(tid));
                add_tri_to_group(tid, gid);
            }


            IndexPriorityQueue pq = new IndexPriorityQueue(mesh.MaxGroupID);

            foreach (var pair in areas)
            {
                pq.Insert(pair.Key, (float)pair.Value);
            }
            while (pq.Count > 0)
            {
                int gid = pq.First;
                pq.Remove(gid);
                if (areas[gid] > minArea)                    // ??
                {
                    break;
                }

                List <int> nbr_groups = find_neighbour_groups(mesh, gid, trisets[gid]);
                int        min_gid = -1; double min_area = double.MaxValue;
                foreach (int ngid in nbr_groups)
                {
                    double a = areas[ngid];
                    if (a < min_area)
                    {
                        min_area = a;
                        min_gid  = ngid;
                    }
                }
                if (min_gid != -1)
                {
                    add_group_to_group(gid, min_gid);
                    pq.Remove(min_gid);
                    pq.Insert(min_gid, (float)areas[min_gid]);
                }
            }



            List <Polygon2d> result = new List <Polygon2d>();

            int[][] sets = FaceGroupUtil.FindTriangleSetsByGroup(mesh);
            foreach (var set in sets)
            {
                result.Add(make_poly(mesh, set));
            }
            return(result);
        }
示例#5
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);
        }