public override bool BuildOnMesh(DMesh3Builder meshBuilder)
        {
            var doorCopy = new DMesh3(Mesh, bCompact: true);

            if (FrontNormal == -Vector3d.AxisZ)
            {
                // trick to prevent 180 rotation
                FrontNormal += new Vector3d(0.0000001, 0.0, 0.0);
            }

            var meshWidth  = doorCopy.GetBounds().Width;
            var meshHeight = doorCopy.GetBounds().Height;

            var widthScale  = WidthLimit / meshWidth;
            var heightScale = HeightLimit / meshHeight;

            Quaterniond orientingQuaternion = new Quaterniond(Vector3d.AxisZ, FrontNormal);

            MeshTransforms.Rotate(doorCopy, Vector3d.Zero, orientingQuaternion);
            MeshTransforms.Scale(doorCopy, Math.Min(widthScale, heightScale));
            MeshTransforms.Translate(doorCopy, Origin);

            meshBuilder.AppendNewMesh(doorCopy);
            meshBuilder.SetActiveMesh(0);
            return(true);
        }
Пример #2
0
        //experimental
        public List <DMesh3> SliceMold(DMesh3 mesh_to_slice, int number_of_slices)
        {
            var meshes = new List <MeshGeometry3D>();

            //convert mesh to DMesh
            DMesh3 mesh = mesh_to_slice;

            //create cube for slicing
            double z_height       = mesh.GetBounds().Max.z - mesh.GetBounds().Min.z;
            double slice_interval = (double)(z_height / number_of_slices);
            double x_size         = mesh.GetBounds().Depth;
            double y_size         = mesh.GetBounds().Width;
            double low_z          = mesh.GetBounds().Min.z;


            //boolean intersection each mesh
            var sliced_meshes = new List <DMesh3>();

            for (int i = 0; i < number_of_slices; i++)
            {
                //create box
                Vector3d centre = new Vector3d(0, 0, low_z + slice_interval / 2 + i * (slice_interval));
                Vector3d extend = new Vector3d(
                    x_size,
                    y_size,
                    slice_interval / 2);

                ImplicitBox3d box = new ImplicitBox3d()
                {
                    Box = new Box3d(centre, extend)
                };

                //boolean overlap
                BoundedImplicitFunction3d meshA = meshToImplicitF(mesh, 64, 0.2f);

                //take the difference of the bolus mesh minus the tools
                ImplicitIntersection3d mesh_result = new ImplicitIntersection3d {
                    A = meshA, B = box
                };

                //calculate the boolean mesh
                MarchingCubes c = new MarchingCubes();
                c.Implicit      = mesh_result;
                c.RootMode      = MarchingCubes.RootfindingModes.LerpSteps;
                c.RootModeSteps = 5;
                c.Bounds        = mesh_result.Bounds();
                c.CubeSize      = c.Bounds.MaxDim / 256;
                c.Bounds.Expand(3 * c.CubeSize);
                c.Generate();
                MeshNormals.QuickCompute(c.Mesh);

                int     triangleCount = c.Mesh.TriangleCount / 3;
                Reducer r             = new Reducer(c.Mesh);
                r.ReduceToTriangleCount(triangleCount);

                sliced_meshes.Add(c.Mesh);
            }

            return(sliced_meshes);
        }
Пример #3
0
 public void MyInit(DMesh3 mesh, bool isImported = false)
 {
     this.mesh = mesh;
     spatial   = new DMeshAABBTree3(mesh);
     spatial.Build();
     this.isImported = isImported;
     if (isImported)
     {
         originalMesh = new DMesh3(mesh);
     }
     center = transform.TransformPoint(mesh.GetBounds().Center.toVector3());
 }
        public override bool BuildOnMesh(DMesh3Builder meshBuilder)
        {
            DMesh3 windowCopy = null;

            BuildingTask = Task.Run(() =>
            {
                windowCopy = new DMesh3(Mesh, bCompact: true);
                //var windowCopy = Mesh;
                if (FrontNormal == -Vector3d.AxisZ)
                {
                    // trick to prevent 180 rotation
                    FrontNormal += new Vector3d(0.0000001, 0.0, 0.0);
                }

                var meshWidth  = windowCopy.GetBounds().Width;
                var meshHeight = windowCopy.GetBounds().Height;

                var widthScale    = WidthLimit / meshWidth;
                var heightScale   = HeightLimit / meshHeight;
                var selectedScale = Math.Min(widthScale, heightScale);

                Quaterniond orientingQuaternion = new Quaterniond(Vector3d.AxisZ, FrontNormal);
                MeshTransforms.Rotate(windowCopy, Vector3d.Zero, orientingQuaternion);

                MeshTransforms.Scale(windowCopy, selectedScale);

                MeshTransforms.Translate(windowCopy, Origin);
                //MeshTransforms.Translate(windowCopy, Origin + Vector3d.AxisY * meshHeight * selectedScale * 0.6);
            }).ContinueWith(t =>
            {
                lock (meshBuilder)
                {
                    meshBuilder.AppendNewMesh(windowCopy);
                    meshBuilder.SetActiveMesh(0);
                }
            });

            return(true);
        }
Пример #5
0
        // [RMS] this only tests some basic cases...
        public static void test_Laplacian_deformer()
        {
            // compact version
            DMesh3 mesh = new DMesh3(TestUtil.MakeRemeshedCappedCylinder(1.0), true);

            Debug.Assert(mesh.IsCompact);

            AxisAlignedBox3d bounds = mesh.GetBounds();

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

            List <IMesh> result_meshes = new List <IMesh>();

            LaplacianMeshDeformer deformer = new LaplacianMeshDeformer(mesh);


            int        ti          = MeshQueries.FindNearestTriangle_LinearSearch(mesh, new Vector3d(2, 5, 2));
            int        v_pin       = mesh.GetTriangle(ti).a;
            List <int> constraints = new List <int>()
            {
                v_pin
            };
            double consPin    = 10;
            double consBottom = 10;

            foreach (int vid in constraints)
            {
                result_meshes.Add(TestUtil.MakeMarker(mesh.GetVertex(vid), (vid == 0) ? 0.2f : 0.1f, Colorf.Red));
            }

            foreach (int vid in mesh.VertexIndices())
            {
                Vector3d v      = mesh.GetVertex(vid);
                bool     bottom = (v.y - bounds.Min.y) < 0.01f;
                if (constraints.Contains(vid))
                {
                    deformer.SetConstraint(vid, v + Vector3f.AxisY, consPin, false);
                }
                if (bottom)
                {
                    deformer.SetConstraint(vid, v, consBottom, false);
                }
            }

            deformer.SolveAndUpdateMesh();

            result_meshes.Add(mesh);
            TestUtil.WriteTestOutputMeshes(result_meshes, "laplacian_deformer_after.obj");
        }
Пример #6
0
        public Task BuildTreeAsync(Vector3[] positions, Vector3[] normals, int[] indices)
        {
            return(Task.Run(() => {
                var norm = ConvertToVector3f(normals);
                DMeshLocal = DMesh3Builder.Build(ConvertToVector3f(positions), indices, norm);

                TreeLocal = new DMeshAABBTree3(DMeshLocal);
                TreeLocal.Build();

                box = new BoundingBox(DMeshLocal.GetBounds());

                IsBuilt = true;

                return this;
            }));
        }
Пример #7
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            DMesh3           mesh   = new DMesh3(MakeRemeshedCappedCylinder(1.0), true);
            AxisAlignedBox3d bounds = mesh.GetBounds();

            List <IMesh> result_meshes = new List <IMesh>();

            LaplacianMeshDeformer deformer = new LaplacianMeshDeformer(mesh);

            // constrain bottom points
            foreach (int vid in mesh.VertexIndices())
            {
                g3.Vector3d v      = mesh.GetVertex(vid);
                bool        bottom = (v.y - bounds.Min.y) < 0.01f;
                if (bottom)
                {
                    deformer.SetConstraint(vid, v, 10);
                }
            }

            // constrain one other vtx
            int ti    = MeshQueries.FindNearestTriangle_LinearSearch(mesh, new g3.Vector3d(2, 5, 2));
            int v_pin = mesh.GetTriangle(ti).a;

            g3.Vector3d cons_pos = mesh.GetVertex(v_pin);
            cons_pos += new g3.Vector3d(0.5, 0.5, 0.5);
            deformer.SetConstraint(v_pin, cons_pos, 10);


            deformer.Initialize();
            g3.Vector3d[] resultV = new g3.Vector3d[mesh.MaxVertexID];
            deformer.Solve(resultV);

            foreach (int vid in mesh.VertexIndices())
            {
                mesh.SetVertex(vid, resultV[vid]);
            }


            var rhinoMesh = GopherUtil.ConvertToRhinoMesh(mesh);

            doc.Objects.AddMesh(rhinoMesh);

            return(Result.Success);
        }
Пример #8
0
        // [RMS] this only tests some basic cases...
        public static void test_LaplacianDeformation()
        {
            // compact version
            DMesh3 mesh = new DMesh3(TestUtil.MakeRemeshedCappedCylinder(1.0), true);

            Debug.Assert(mesh.IsCompact);
            AxisAlignedBox3d bounds = mesh.GetBounds();

            List <IMesh> result_meshes = new List <IMesh>();

            LaplacianMeshDeformer deformer = new LaplacianMeshDeformer(mesh);

            // constrain bottom points
            foreach (int vid in mesh.VertexIndices())
            {
                Vector3d v      = mesh.GetVertex(vid);
                bool     bottom = (v.y - bounds.Min.y) < 0.01f;
                if (bottom)
                {
                    deformer.SetConstraint(vid, v, 10);
                }
            }

            // constrain one other vtx
            int      ti       = MeshQueries.FindNearestTriangle_LinearSearch(mesh, new Vector3d(2, 5, 2));
            int      v_pin    = mesh.GetTriangle(ti).a;
            Vector3d cons_pos = mesh.GetVertex(v_pin);

            cons_pos += new Vector3d(0.5, 0.5, 0.5);
            deformer.SetConstraint(v_pin, cons_pos, 10);
            result_meshes.Add(TestUtil.MakeMarker(mesh.GetVertex(v_pin), 0.2f, Colorf.Red));

            deformer.Initialize();
            Vector3d[] resultV = new Vector3d[mesh.MaxVertexID];
            deformer.Solve(resultV);

            foreach (int vid in mesh.VertexIndices())
            {
                mesh.SetVertex(vid, resultV[vid]);
            }

            result_meshes.Add(mesh);
            TestUtil.WriteDebugMeshes(result_meshes, "___LAPLACIAN_result.obj");
        }
Пример #9
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            int        num_cells = 128;
            DMesh3_goo dMsh_goo  = null;

            DA.GetData(0, ref dMsh_goo);
            DA.GetData(1, ref num_cells);

            DMesh3 dMsh_copy = new DMesh3(dMsh_goo.Value);
            double cell_size = dMsh_copy.CachedBounds.MaxDim / num_cells;

            DMeshAABBTree3 spatial = new DMeshAABBTree3(dMsh_copy, autoBuild: true);

            AxisAlignedBox3d  bounds   = dMsh_copy.CachedBounds;
            double            cellsize = bounds.MaxDim / num_cells;
            ShiftGridIndexer3 indexer  = new ShiftGridIndexer3(bounds.Min, cellsize);

            Bitmap3 bmp = new Bitmap3(new Vector3i(num_cells, num_cells, num_cells));

            foreach (Vector3i idx in bmp.Indices())
            {
                g3.Vector3d v = indexer.FromGrid(idx);
                bmp.Set(idx, spatial.IsInside(v));
            }

            VoxelSurfaceGenerator voxGen = new VoxelSurfaceGenerator();

            voxGen.Voxels = bmp;
            voxGen.Generate();
            DMesh3 voxMesh = voxGen.Meshes[0];

            var vecSize = dMsh_copy.CachedBounds.Extents;
            var box     = dMsh_copy.GetBounds();

            // Scale voxel mesh
            //MeshTransforms.Scale(voxMesh,)

            DA.SetData(0, voxMesh);
        }
Пример #10
0
        public Task BuildTreeAsync(IGeometryComponent geo)
        {
            if (!geo.IsValid)
            {
                return(Task.FromResult(0));
            }
            return(Task.Run(() => {
                var norm = geo.Normals.IsDefaultOrEmpty ? null : ConvertToVector3f(geo.Normals);
                DMeshLocal = DMesh3Builder.Build(ConvertToVector3f(geo.Positions), geo.Indices, norm);
                //var sm = new LaplacianMeshSmoother(DMesh);
                //sm.Initialize();
                //sm.SolveAndUpdateMesh();

                //DMesh = sm.Mesh;
                TreeLocal = new DMeshAABBTree3(DMeshLocal);
                TreeLocal.Build();

                box = new BoundingBox(DMeshLocal.GetBounds());

                IsBuilt = true;

                return this;
            }));
        }
        // [RMS] this only tests some basic cases...
        public static void test_Laplacian()
        {
            // compact version
            DMesh3 mesh = new DMesh3(TestUtil.MakeRemeshedCappedCylinder(1.0), true);

            Debug.Assert(mesh.IsCompact);

            AxisAlignedBox3d bounds = mesh.GetBounds();

            TestUtil.WriteDebugMesh(mesh, "___CG_before.obj");

            List <IMesh> result_meshes = new List <IMesh>();

            // make uniform laplacian matrix
            int N = mesh.VertexCount;
            SymmetricSparseMatrix M = new SymmetricSparseMatrix();

            //DenseMatrix M = new DenseMatrix(N, N);
            double[] Px = new double[N], Py = new double[N], Pz = new double[N];

            int[] nbr_counts = new int[N];
            for (int vid = 0; vid < N; ++vid)
            {
                nbr_counts[vid] = mesh.GetVtxEdgeCount(vid);
            }

            int        ti          = MeshQueries.FindNearestTriangle_LinearSearch(mesh, new Vector3d(2, 5, 2));
            int        v_pin       = mesh.GetTriangle(ti).a;
            List <int> constraints = new List <int>()
            {
                v_pin
            };
            double consW      = 10;
            double consBottom = 10;

            foreach (int vid in constraints)
            {
                result_meshes.Add(TestUtil.MakeMarker(mesh.GetVertex(vid), (vid == 0) ? 0.2f : 0.1f, Colorf.Red));
            }

            for (int vid = 0; vid < N; ++vid)
            {
                int      n = nbr_counts[vid];
                Vector3d v = mesh.GetVertex(vid), c = Vector3d.Zero;

                Px[vid] = v.x; Py[vid] = v.y; Pz[vid] = v.z;

                bool bottom = (v.y - bounds.Min.y) < 0.01f;

                double sum_w = 0;
                foreach (int nbrvid in mesh.VtxVerticesItr(vid))
                {
                    int n2 = nbr_counts[nbrvid];

                    // weight options
                    //double w = -1;
                    double w = -1.0 / Math.Sqrt(n + n2);
                    //double w = -1.0 / n;

                    M.Set(vid, nbrvid, w);

                    c     += w * mesh.GetVertex(nbrvid);
                    sum_w += w;
                }
                sum_w = -sum_w;

                M.Set(vid, vid, sum_w);

                // add soft constraints
                if (constraints.Contains(vid))
                {
                    M.Set(vid, vid, sum_w + consW);
                }
                else if (bottom)
                {
                    M.Set(vid, vid, sum_w + consBottom);
                }
            }

            // compute laplacians
            double[] MLx = new double[N], MLy = new double[N], MLz = new double[N];
            M.Multiply(Px, MLx);
            M.Multiply(Py, MLy);
            M.Multiply(Pz, MLz);


            DiagonalMatrix Preconditioner = new DiagonalMatrix(N);

            for (int i = 0; i < N; i++)
            {
                Preconditioner.Set(i, i, 1.0 / M[i, i]);
            }


            MLy[v_pin] += consW * 0.5f;
            MLx[v_pin] += consW * 0.5f;
            MLz[v_pin] += consW * 0.5f;

            bool useXAsGuess = true;
            // preconditioned
            SparseSymmetricCG SolverX = new SparseSymmetricCG()
            {
                B = MLx, X = Px, MultiplyF = M.Multiply, PreconditionMultiplyF = Preconditioner.Multiply, UseXAsInitialGuess = useXAsGuess
            };
            // initial solution
            SparseSymmetricCG SolverY = new SparseSymmetricCG()
            {
                B = MLy, X = Py, MultiplyF = M.Multiply, UseXAsInitialGuess = useXAsGuess
            };
            // neither of those
            SparseSymmetricCG SolverZ = new SparseSymmetricCG()
            {
                B = MLz, MultiplyF = M.Multiply
            };

            bool bx = SolverX.Solve();
            bool by = SolverY.Solve();
            bool bz = SolverZ.Solve();

            for (int vid = 0; vid < mesh.VertexCount; ++vid)
            {
                Vector3d newV = new Vector3d(SolverX.X[vid], SolverY.X[vid], SolverZ.X[vid]);
                mesh.SetVertex(vid, newV);
            }

            result_meshes.Add(mesh);
            TestUtil.WriteDebugMeshes(result_meshes, "___CG_result.obj");
        }