Пример #1
0
        protected virtual DMesh3 BuildMesh_IdenticalWeld(STLSolid solid)
        {
            var builder = new DMesh3Builder();

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

            DVectorArray3f vertices = solid.Vertices;
            int            N        = vertices.Count;

            int[] mapV = new int[N];

            var uniqueV = new Dictionary <Vector3f, int>();

            for (int vi = 0; vi < N; ++vi)
            {
                Vector3f v = vertices[vi];
                int      existing_idx;
                if (uniqueV.TryGetValue(v, out existing_idx))
                {
                    mapV[vi] = existing_idx;
                }
                else
                {
                    int vid = builder.AppendVertex(v.x, v.y, v.z);
                    uniqueV[v] = vid;
                    mapV[vi]   = vid;
                }
            }

            append_mapped_triangles(solid, builder, mapV);
            return(builder.Meshes[0]);
        }
Пример #2
0
        protected virtual DMesh3 BuildMesh_TolerantWeld(STLSolid solid, double weld_tolerance)
        {
            var builder = new DMesh3Builder();

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

            DVectorArray3f vertices = solid.Vertices;
            int            N        = vertices.Count;

            int[] mapV = new int[N];


            AxisAlignedBox3d bounds = AxisAlignedBox3d.Empty;

            for (int i = 0; i < N; ++i)
            {
                bounds.Contain(vertices[i]);
            }

            // [RMS] because we are only searching within tiny radius, there is really no downside to
            // using lots of bins here, except memory usage. If we don't, and the mesh has a ton of triangles
            // very close together (happens all the time on big meshes!), then this step can start
            // to take an *extremely* long time!
            int num_bins = 256;

            if (N > 100000)
            {
                num_bins = 512;
            }

            if (N > 1000000)
            {
                num_bins = 1024;
            }

            if (N > 2000000)
            {
                num_bins = 2048;
            }

            if (N > 5000000)
            {
                num_bins = 4096;
            }

            var uniqueV = new PointHashGrid3d <int>(bounds.MaxDim / (float)num_bins, -1);
            var pos     = new Vector3f[N];

            for (int vi = 0; vi < N; ++vi)
            {
                Vector3f v = vertices[vi];

                var pair = uniqueV.FindNearestInRadius(v, weld_tolerance, (vid) =>
                {
                    return(v.Distance(pos[vid]));
                });
                if (pair.Key == -1)
                {
                    int vid = builder.AppendVertex(v.x, v.y, v.z);
                    uniqueV.InsertPoint(vid, v);
                    mapV[vi] = vid;
                    pos[vid] = v;
                }
                else
                {
                    mapV[vi] = pair.Key;
                }
            }

            append_mapped_triangles(solid, builder, mapV);
            return(builder.Meshes[0]);
        }