Exemplo n.º 1
0
        virtual public void CutMesh()
        {
            Frame3f frameL = SceneTransforms.SceneToObject(target, cut_plane);

            Action <DMesh3> editF = (mesh) => {
                MeshPlaneCut cut = new MeshPlaneCut(mesh, frameL.Origin, frameL.Y);
                cut.Cut();

                PlaneProjectionTarget planeTarget = new PlaneProjectionTarget()
                {
                    Origin = frameL.Origin, Normal = frameL.Y
                };

                if (GenerateFillSurface)
                {
                    double min, max, avg;
                    MeshQueries.EdgeLengthStats(mesh, out min, out max, out avg);

                    cut.FillHoles();

                    MeshFaceSelection selection = new MeshFaceSelection(mesh);
                    foreach (var tris in cut.LoopFillTriangles)
                    {
                        selection.Select(tris);
                    }
                    RegionRemesher.QuickRemesh(mesh, selection.ToArray(), 2 * avg, 1.0f, 25, planeTarget);

                    MeshNormals normals = new MeshNormals(mesh);
                    normals.Compute();
                    normals.CopyTo(mesh);
                }
            };

            target.EditAndUpdateMesh(editF, GeometryEditTypes.ArbitraryEdit);
        }
        /// <summary>
        /// compute offset meshes as simple extrusions
        /// </summary>
        void compute_offset_meshes_nosdf()
        {
            if (cached_inner_sdf_offset != inner_offset)
            {
                InnerOffsetMesh = new DMesh3(cachedInputMesh);
                MeshTransforms.FromFrame(InnerOffsetMesh, cachedInputsTransform);

                MeshNormals.QuickCompute(InnerOffsetMesh);
                MeshTransforms.VertexNormalOffset(InnerOffsetMesh, inner_offset);
                Reducer reducer = new Reducer(InnerOffsetMesh);
                reducer.ReduceToTriangleCount(5000);
                InnerOffsetMeshSpatial  = new DMeshAABBTree3(InnerOffsetMesh, true);
                cached_inner_sdf_offset = inner_offset;
            }

            double max_offset = inner_offset + thickness;

            if (cached_outer_sdf_offset != max_offset)
            {
                OuterOffsetMesh = new DMesh3(cachedInputMesh);
                MeshTransforms.FromFrame(OuterOffsetMesh, cachedInputsTransform);

                MeshNormals.QuickCompute(OuterOffsetMesh);
                MeshTransforms.VertexNormalOffset(OuterOffsetMesh, max_offset);
                Reducer reducer = new Reducer(OuterOffsetMesh);
                reducer.ReduceToTriangleCount(5000);
                OuterOffsetMeshSpatial  = new DMeshAABBTree3(OuterOffsetMesh, true);
                cached_outer_sdf_offset = max_offset;
            }

            //Util.WriteDebugMesh(MeshSource.GetIMesh(), "c:\\scratch\\__OFFESTS_orig.obj");
            //Util.WriteDebugMesh(InnerOffsetMesh, "c:\\scratch\\__OFFESTS_inner.obj");
            //Util.WriteDebugMesh(OuterOffsetMesh, "c:\\scratch\\__OFFESTS_outer.obj");
        }
Exemplo n.º 3
0
        private static DMesh3 BooleanIntersection(DMesh3 mesh1, DMesh3 mesh2)
        {
            BoundedImplicitFunction3d meshA = meshToImplicitF(mesh1, 64, 0.2f);
            BoundedImplicitFunction3d meshB = meshToImplicitF(mesh2, 64, 0.2f);

            //take the intersection of the meshes minus the tools
            ImplicitIntersection3d mesh = new ImplicitIntersection3d()
            {
                A = meshA, B = meshB
            };

            //calculate the boolean mesh
            MarchingCubes c = new MarchingCubes();

            c.Implicit      = mesh;
            c.RootMode      = MarchingCubes.RootfindingModes.LerpSteps;
            c.RootModeSteps = 5;
            c.Bounds        = mesh.Bounds();
            c.CubeSize      = c.Bounds.MaxDim / 128;
            c.Bounds.Expand(3 * c.CubeSize);
            c.Generate();
            MeshNormals.QuickCompute(c.Mesh);

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

            r.ReduceToTriangleCount(triangleCount);
            return(c.Mesh);
        }
Exemplo n.º 4
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            List <DMesh3_goo> goo = new List <DMesh3_goo>();
            int numCells          = 64;

            DA.GetDataList(0, goo);
            DA.GetData(1, ref numCells);

            ImplicitNaryUnion3d diff2 = new ImplicitNaryUnion3d();

            diff2.Children = goo.Select(x => g3ghUtil.MeshToImplicit(x.Value, numCells, 0.2f)).ToList();

            g3.MarchingCubes c = new g3.MarchingCubes();
            c.Implicit      = diff2;
            c.RootMode      = g3.MarchingCubes.RootfindingModes.Bisection;
            c.RootModeSteps = 5;
            c.Bounds        = diff2.Bounds();
            c.CubeSize      = c.Bounds.MaxDim / numCells;
            c.Bounds.Expand(3 * c.CubeSize);
            c.Generate();

            MeshNormals.QuickCompute(c.Mesh);

            DA.SetData(0, c.Mesh);
        }
Exemplo n.º 5
0
        void update_warp()
        {
            if (warp_dirty == false)
            {
                return;
            }

            DMesh3 mesh = PreviewSO.Mesh;

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

            Frame3f f = bendPlaneGizmoSO.GetLocalFrame(CoordSpace.SceneCoords);

            f = SceneTransforms.SceneToObject(PreviewSO, f);
            BendWarp warp = new BendWarp()
            {
                Mesh      = mesh,
                BendPlane = f,
                BendAngle = bend_angle
            };

            warp.Apply();

            MeshNormals.QuickCompute(mesh);

            PreviewSO.NotifyMeshEdited(true);

            warp_dirty = false;
        }
Exemplo n.º 6
0
        private UnityMesh CreateMesh(List <Vector3d> lPath)
        {
            DMesh3 dMesh = meshGen.CreateMesh(lPath, qPoly.ToList(), tmpSeam);

            // Defer normal calculation if we reduce smoothing later.
            if (triangleReductionFactor > 1f)
            {
                dMesh.ReduceTriangles(triangleReductionFactor, !reduceSmoothing);
            }
            else if (!reduceSmoothing)
            {
                MeshNormals.QuickCompute(dMesh);
            }

            UnityMesh uMesh = dMesh.ToUnityMesh();

            uMesh.seam = meshGen.Seam; // TODO

            if (reduceSmoothing)
            {
                uMesh.IncreaseVertexCount(smoothingThresholdAngle);
            }

            return(uMesh);
        }
Exemplo n.º 7
0
        public virtual void Update()
        {
            base.begin_update();

            if (MeshSource == null)
            {
                throw new Exception("MeshDeformationOp: must set valid MeshSource to compute!");
            }

            IMesh meshIn = MeshSource.GetIMesh();

            DMesh3 mesh = new DMesh3(meshIn, MeshHints.None);

            MeshNormals.QuickCompute(mesh);

            foreach (int vid in mesh.VertexIndices())
            {
                Vector3d v      = mesh.GetVertex(vid);
                Vector3f n      = mesh.GetVertexNormal(vid);
                Vector3d newPos = deformF(v, n, vid);
                mesh.SetVertex(vid, newPos);
            }

            MeshNormals.QuickCompute(mesh);

            DisplacedMesh = mesh;

            base.complete_update();
        }
Exemplo n.º 8
0
            public override fMesh MakeGeometry(AxisGizmoFlags widget)
            {
                switch (widget)
                {
                case AxisGizmoFlags.AxisTranslateY:
                    if (MyAxisTranslateY == null)
                    {
                        Radial3DArrowGenerator arrowGen = new Radial3DArrowGenerator()
                        {
                            HeadLength = 2.0f, TipRadius = 0.1f, StickLength = 1.5f, Clockwise = true
                        };
                        DMesh3 mesh = arrowGen.Generate().MakeDMesh();
                        MeshNormals.QuickCompute(mesh);
                        MeshTransforms.Translate(mesh, 0.5 * Vector3d.AxisY);
                        DMesh3 flip = new DMesh3(mesh);
                        MeshTransforms.Rotate(flip, Vector3d.Zero, Quaterniond.AxisAngleD(Vector3d.AxisX, 180));
                        MeshEditor.Append(mesh, flip);
                        MyAxisTranslateY = new fMesh(mesh);
                    }
                    return(MyAxisTranslateY);

                default:
                    return(null);
                }
            }
Exemplo n.º 9
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);
        }
Exemplo n.º 10
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            DMesh3_goo        gooA = null;
            List <DMesh3_goo> gooB = new List <DMesh3_goo>();
            int numCells           = 64;

            DA.GetData(0, ref gooA);
            DA.GetDataList(1, gooB);
            DA.GetData(2, ref numCells);

            DMesh3        A = new DMesh3(gooA.Value);
            List <DMesh3> B = gooB.Select(x => x.Value).ToList();

            ImplicitNaryDifference3d diff2 = new ImplicitNaryDifference3d();

            diff2.A    = g3ghUtil.MeshToImplicit(A, numCells, 0.2f);
            diff2.BSet = B.Select(x => g3ghUtil.MeshToImplicit(x, numCells, 0.2f)).ToList();

            g3.MarchingCubes c = new g3.MarchingCubes();
            c.Implicit      = diff2;
            c.RootMode      = g3.MarchingCubes.RootfindingModes.Bisection;
            c.RootModeSteps = 5;
            c.Bounds        = diff2.Bounds();
            c.CubeSize      = c.Bounds.MaxDim / numCells;
            c.Bounds.Expand(3 * c.CubeSize);
            c.Generate();

            MeshNormals.QuickCompute(c.Mesh);

            DA.SetData(0, c.Mesh);
        }
Exemplo n.º 11
0
        public DMesh3 BooleanUnion(DMesh3 mesh1, DMesh3 mesh2)
        {
            BoundedImplicitFunction3d meshA = meshToImplicitF(mesh1, 128, 0.2f);
            BoundedImplicitFunction3d meshB = meshToImplicitF(mesh2, 128, 0.2f);

            //take the difference of the bolus mesh minus the tools
            var mesh = new ImplicitUnion3d()
            {
                A = meshA, B = meshB
            };

            //calculate the boolean mesh
            MarchingCubes c = new MarchingCubes();

            c.Implicit      = mesh;
            c.RootMode      = MarchingCubes.RootfindingModes.LerpSteps;
            c.RootModeSteps = 5;
            c.Bounds        = mesh.Bounds();
            c.CubeSize      = c.Bounds.MaxDim / 96;
            c.Bounds.Expand(3 * c.CubeSize);
            c.Generate();
            MeshNormals.QuickCompute(c.Mesh);

            //int triangleCount = c.Mesh.TriangleCount / 2;
            //Reducer r = new Reducer(c.Mesh);
            //r.ReduceToTriangleCount(triangleCount);
            return(c.Mesh);
        }
Exemplo n.º 12
0
    // Use this for initialization
    void Start()
    {
        meshGO = GameObject.Find("sample_mesh");
        Mesh unityMesh = meshGO.GetComponent <MeshFilter>().mesh;

        startMesh = g3UnityUtils.UnityMeshToDMesh(unityMesh);
        double height = startMesh.CachedBounds.Height;

        // find path to sample file
        if (LoadSampleMesh)
        {
            string curPath  = Application.dataPath;
            string filePath = Path.Combine(curPath, Path.Combine("..\\sample_files", SampleFileName));

            // load sample file, convert to unity coordinate system, translate and scale to origin
            startMesh = StandardMeshReader.ReadMesh(filePath);
            if (startMesh == null)
            {
                startMesh = new Sphere3Generator_NormalizedCube().Generate().MakeDMesh();
            }

            if (FlipLeftRight)
            {
                MeshTransforms.FlipLeftRightCoordSystems(startMesh);
            }
            MeshTransforms.Scale(startMesh, height / startMesh.CachedBounds.Height);
            MeshTransforms.Translate(startMesh, -startMesh.CachedBounds.Center);
            MeshNormals.QuickCompute(startMesh);
            g3UnityUtils.SetGOMesh(meshGO, startMesh);
        }
    }
        void compute_inner_wall()
        {
            if (DebugStep <= 0)
            {
                SocketMesh = new DMesh3(TrimmedMesh);
                return;
            }

            InnerMesh = new DMesh3(TrimmedMesh);

            // compute flare band
            Func <int, double> flareOffsetF = (vid) => { return(0); };

            if (flare_offset > 0 && flare_band_width > 0)
            {
                MeshBoundaryLoops loops = new MeshBoundaryLoops(InnerMesh);
                if (loops.Count != 1)
                {
                    goto done_inner_wall;
                }

                DijkstraGraphDistance dist = DijkstraGraphDistance.MeshVertices(InnerMesh);
                dist.TrackOrder = true;
                foreach (int vid in loops[0].Vertices)
                {
                    dist.AddSeed(vid, 0);
                }
                dist.ComputeToMaxDistance(1.25f * (float)flare_band_width);

                flareOffsetF = (viD) => {
                    float d = dist.GetDistance(viD);
                    if (d < flare_band_width)
                    {
                        double t = d / flare_band_width;
                        t = 1 - t * t;
                        t = t * t * t;
                        return(t * flare_offset);
                    }
                    return(0);
                };
            }


            gParallel.ForEach(InnerMesh.VertexIndices(), (vid) => {
                Vector3d v    = InnerMesh.GetVertex(vid);
                Vector3d n    = InnerMesh.GetVertexNormal(vid);
                double offset = inner_offset + flareOffsetF(vid);
                InnerMesh.SetVertex(vid, v + offset * n);
            });


done_inner_wall:
            MeshNormals.QuickCompute(InnerMesh);
        }
Exemplo n.º 14
0
 public virtual void BakeDisplacements(DMeshSO so, VertexChangeBuilder changeBuilder)
 {
     so.EditAndUpdateMesh((mesh) => {
         foreach (int vid in ModifiedV)
         {
             changeBuilder.SetPosition(vid, Displacements[vid]);
         }
         gParallel.ForEach(ModifiedV, (vid) => {
             MeshNormals.QuickCompute(Mesh, vid);
         });
     }, GeometryEditTypes.VertexDeformation);
 }
Exemplo n.º 15
0
        private DMesh3 GenerateMeshBase(BoundedImplicitFunction3d root, AxisAlignedBox3d filterBox)
        {
            MarchingCubes c = new MarchingCubes();

            c.Implicit      = root;
            c.RootMode      = MarchingCubes.RootfindingModes.LerpSteps; // cube-edge convergence method
            c.RootModeSteps = 5;                                        // number of iterations
            c.Bounds        = filterBox;                                //_sideFilterBox;
            c.CubeSize      = _cubeSize / 4.0;
            c.Generate();
            MeshNormals.QuickCompute(c.Mesh);                           // generate normals

            return(c.Mesh);
        }
Exemplo n.º 16
0
        // generateMeshF() meshes the input implicit function at
        // the given cell resolution, and writes out the resulting mesh
        DMesh3 generatMeshF(BoundedImplicitFunction3d root, int numcells)
        {
            MarchingCubes c = new MarchingCubes();

            c.Implicit      = root;
            c.RootMode      = MarchingCubes.RootfindingModes.LerpSteps; // cube-edge convergence method
            c.RootModeSteps = 5;                                        // number of iterations
            c.Bounds        = root.Bounds();
            c.CubeSize      = c.Bounds.MaxDim / numcells;
            c.Bounds.Expand(3 * c.CubeSize);  // leave a buffer of cells
            c.Generate();
            MeshNormals.QuickCompute(c.Mesh); // generate normals
            return(c.Mesh);                   // write mesh
        }
Exemplo n.º 17
0
        public override Task Rebuild()
        {
            this.DebugDepth("Rebuild");

            return(Task.Run(() =>
            {
                using (RebuildLock())
                {
                    using (new CenterAndHeightMaintainer(this))
                    {
#if true
                        ISdf shape = new Sphere()
                        {
                            Radius = Size
                        };

                        if (Shape == Shapes.Box)
                        {
                            shape = new Box()
                            {
                                Size = new Vector3(Size, Size, Size)
                            };
                        }

                        var bounds = shape.Bounds;
                        bounds.Expand(.1);
                        if (Iterations > 7)
                        {
                            Iterations = 7;
                        }
                        var root = Octree.BuildOctree(shape.Sdf, bounds.MinXYZ, bounds.Size, Iterations, Threshold);

                        Mesh = Octree.GenerateMeshFromOctree(root);
#else
                        var c = new MarchingCubes();
                        c.Generate();
                        MeshNormals.QuickCompute(c.Mesh);                         // generate normals
                        Mesh = c.Mesh.ToMesh();
#endif
                    }
                }

                Invalidate(InvalidateType.DisplayValues);

                Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh));
                return Task.CompletedTask;
            }));
        }
Exemplo n.º 18
0
        public static void test_normals()
        {
            // check that frames are ok
            DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_solid.obj");

            foreach (int tid in mesh.TriangleIndices())
            {
                Vector3f n = (Vector3f)mesh.GetTriNormal(tid);
                for (int j = 0; j < 3; ++j)
                {
                    Frame3f f = mesh.GetTriFrame(tid, j);
                    if (Math.Abs(f.X.Dot(f.Y)) > MathUtil.ZeroTolerancef ||
                        Math.Abs(f.X.Dot(f.Z)) > MathUtil.ZeroTolerancef ||
                        Math.Abs(f.Y.Dot(f.Z)) > MathUtil.ZeroTolerancef)
                    {
                        throw new Exception("argh");
                    }
                    Vector3f fn = f.Z;
                    if (fn.Dot(n) < 0.99)
                    {
                        throw new Exception("shit");
                    }
                }
            }

            MeshNormals.QuickCompute(mesh);

            foreach (int vid in mesh.VertexIndices())
            {
                Vector3f n = mesh.GetVertexNormal(vid);
                for (int j = 1; j <= 2; ++j)
                {
                    Frame3f  f  = mesh.GetVertexFrame(vid, (j == 1) ? true : false);
                    Vector3f fn = f.GetAxis(j);
                    if (Math.Abs(f.X.Dot(f.Y)) > MathUtil.ZeroTolerancef ||
                        Math.Abs(f.X.Dot(f.Z)) > MathUtil.ZeroTolerancef ||
                        Math.Abs(f.Y.Dot(f.Z)) > MathUtil.ZeroTolerancef)
                    {
                        throw new Exception("argh");
                    }
                    if (fn.Dot(n) < 0.99)
                    {
                        throw new Exception("shit2");
                    }
                }
            }
        }
Exemplo n.º 19
0
        public static DMesh3 GenerateMeshF(BoundedImplicitFunction3d mesh, int num_cells)
        {
            MarchingCubes c = new MarchingCubes();

            c.Implicit      = mesh;
            c.RootMode      = MarchingCubes.RootfindingModes.LerpSteps; // cube-edge convergence method
            c.RootModeSteps = 5;                                        // number of iterations
            c.Bounds        = mesh.Bounds();
            c.CubeSize      = c.Bounds.MaxDim / num_cells;
            c.Bounds.Expand(3 * c.CubeSize);                            // leave a buffer of cells
            c.Generate();
            MeshNormals.QuickCompute(c.Mesh);                           // generate normals

            DMesh3 outputMesh = c.Mesh;

            return(outputMesh);
        }
Exemplo n.º 20
0
        protected override void on_curve_validated()
        {
            if (previewGO != null)
            {
                RemoveGO((fGameObject)previewGO);
                previewGO.Destroy();
            }


            if (EnableRegionOverlay)
            {
                if (TargetModelSO == null)
                {
                    throw new InvalidOperationException("EnclosedPatchSO.on_curve_validated: curve is not connected to a Target");
                }
                if (TransformMode != OutputCurveTransform.ToTargetSO)
                {
                    throw new InvalidOperationException("EnclosedPatchSO.on_curve_validated: curve is not transformed to TargetSO");
                }

                DCurve3           target_curve = RequestCurveCopyFromMainThread();
                MeshFacesFromLoop loop         = new MeshFacesFromLoop(TargetModel.SourceMesh,
                                                                       target_curve, TargetModel.SourceSpatial);
                MeshFaceSelection face_selection = loop.ToSelection();

                DSubmesh3 submesh = new DSubmesh3(TargetModel.SourceMesh, face_selection, face_selection.Count);

                MeshNormals normals = new MeshNormals(submesh.SubMesh);
                normals.Compute();
                foreach (int vid in submesh.SubMesh.VertexIndices())
                {
                    Vector3d n = normals.Normals[vid];
                    Vector3d v = submesh.SubMesh.GetVertex(vid);
                    v += 0.1 * n;
                    v  = SceneTransforms.TransformTo(v, TargetModelSO, this);
                    submesh.SubMesh.SetVertex(vid, v);
                }

                previewGO = GameObjectFactory.CreateMeshGO("patch",
                                                           new fMesh(submesh.SubMesh), false, true);
                previewGO.SetMaterial(previewMaterial, true);
                previewGO.SetLayer(FPlatform.WidgetOverlayLayer);
                previewGO.SetIgnoreMaterialChanges();
                AppendNewGO(previewGO, root, false);
            }
        }
        protected override void Recompute(DGArguments args)
        {
            OffsetMesh.Copy(CachedValue <DMesh3>(0, args));
            double dist = CachedValue <double>(1, args);

            if (!OffsetMesh.HasVertexNormals)
            {
                MeshNormals.QuickCompute(OffsetMesh);
            }

            foreach (int vid in OffsetMesh.VertexIndices())
            {
                Vector3d v = OffsetMesh.GetVertex(vid);
                Vector3d n = OffsetMesh.GetVertexNormal(vid);
                v += dist * n;
                OffsetMesh.SetVertex(vid, v);
            }
        }
Exemplo n.º 22
0
        public bool Compute()
        {
            DMesh3 copy = new DMesh3(Mesh);

            //Frame3f PlaneO = SceneTransforms.SceneToObject(TargetSO, PlaneS);
            Vector3f PlaneNormal = Plane.GetAxis(nPlaneAxis);

            MeshPlaneCut cut = new MeshPlaneCut(copy, Plane.Origin, PlaneNormal);

            cut.Cut();

            Loops = new DCurve3[cut.CutLoops.Count];
            for (int li = 0; li < cut.CutLoops.Count; ++li)
            {
                EdgeLoop edgeloop = cut.CutLoops[li];
                DCurve3  loop     = MeshUtil.ExtractLoopV(copy, edgeloop.Vertices);

                // [TODO] collapse degenerate points...

                if (NormalOffset > 0)
                {
                    for (int i = 0; i < loop.VertexCount; ++i)
                    {
                        Vector3f n = Vector3f.Zero;
                        if (copy.HasVertexNormals)
                        {
                            n = (Vector3f)copy.GetVertexNormal(edgeloop.Vertices[i]);
                        }
                        else
                        {
                            n = (Vector3f)MeshNormals.QuickCompute(Mesh, edgeloop.Vertices[i]);
                        }

                        n -= n.Dot(PlaneNormal) * PlaneNormal;
                        n.Normalize();
                        loop[i] += NormalOffset * (Vector3d)n;
                    }
                }

                Loops[li] = loop;
            }

            return(Loops.Length > 0);
        }
Exemplo n.º 23
0
    void MeshReplace()
    {
        Mesh newMesh = new Mesh();

        //The triangles tend to come out reversed, so we need to fix them
        DMesh3 dmesh3 = DMesh3Builder.Build <float, int, float>(verticies, faces);

        MeshNormals.QuickCompute(dmesh3);
        dmesh3.ReverseOrientation(false);

        newMesh.vertices  = verticies.ToVectors().ToArray();
        newMesh.triangles = dmesh3.TrianglesBuffer.ToArray();
        for (int i = 0; i < mesh.uv.Length; i++)
        {
            newMesh.uv[i] = mesh.uv[i];
        }
        newMesh.MarkDynamic();
        GetComponent <MeshFilter>().mesh = newMesh;
    }
Exemplo n.º 24
0
        private static DMesh3 GenerateMeshF(BoundedImplicitFunction3d root, int numcells)
        {
            var bounds = root.Bounds();

            var c = new MarchingCubes()
            {
                Implicit      = root,
                RootMode      = MarchingCubes.RootfindingModes.LerpSteps,                 // cube-edge convergence method
                RootModeSteps = 5,                                                        // number of iterations
                Bounds        = bounds,
                CubeSize      = bounds.MaxDim / numcells,
            };

            c.Bounds.Expand(3 * c.CubeSize);                                        // leave a buffer of cells
            c.Generate();

            MeshNormals.QuickCompute(c.Mesh);                                       // generate normals
            return(c.Mesh);
        }
Exemplo n.º 25
0
        public static void TestMarchingCubes()
        {
            MarchingCubes mc = new MarchingCubes();

            LocalProfiler p = new LocalProfiler();

            p.Start("GENERATE");
            mc.ParallelCompute = true;
            mc.Generate();
            p.Stop("GENERATE");
            DebugUtil.Log(2, p.AllTimes());

            MeshNormals.QuickCompute(mc.Mesh);

            DebugUtil.WriteDebugMesh(mc.Mesh, "c:\\scratch\\MARCHING_CUBES.obj");

            DMeshSO meshSO = new DMeshSO();

            meshSO.Create(mc.Mesh, CC.ActiveScene.DefaultMeshSOMaterial);
            CC.ActiveScene.AddSceneObject(meshSO, false);
        }
Exemplo n.º 26
0
        public static DMesh3 ReduceTriangles(this DMesh3 dMesh,
                                             int triangleCount,
                                             bool computeNormals      = true,
                                             bool fixAllBoundaryEdges = true)
        {
            Reducer reducer = new Reducer(dMesh);

            if (fixAllBoundaryEdges)
            {
                reducer.SetExternalConstraints(meshConstraints);
                MeshConstraintUtil.FixAllBoundaryEdges(reducer.Constraints, dMesh);
            }
            reducer.ReduceToTriangleCount(triangleCount);

            if (computeNormals)
            {
                MeshNormals.QuickCompute(dMesh);
            }

            return(dMesh);
        }
Exemplo n.º 27
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            DMesh3_goo goo = null;

            DA.GetData(0, ref goo);

            DMesh3 mesh = new DMesh3(goo.Value);

            List <Rhino.Geometry.Vector3d> vecs = new List <Rhino.Geometry.Vector3d>();

            if (!mesh.HasVertexNormals)
            {
                var normals = new MeshNormals(mesh);
                normals.Compute();
            }

            foreach (var ind in mesh.VertexIndices())
            {
                vecs.Add(mesh.GetVertexNormal(ind).ToRhinoVec());
            }

            DA.SetDataList(0, vecs);
        }
Exemplo n.º 28
0
        public static void test_marching_cubes()
        {
            MarchingCubes c = new MarchingCubes();

            LocalProfiler profiler = new LocalProfiler();

            profiler.Start("Generate");

            c.ParallelCompute = true;
            c.Generate();

            profiler.Stop("Generate");

            System.Console.WriteLine("Tris: {0} Times: {1}", c.Mesh.TriangleCount, profiler.AllTimes());

            Reducer r = new Reducer(c.Mesh);

            r.ReduceToEdgeLength(c.CubeSize * 0.25);

            System.Console.WriteLine("after reduce: {0}", c.Mesh.TriangleCount);

            MeshNormals.QuickCompute(c.Mesh);
            TestUtil.WriteTestOutputMesh(c.Mesh, "marching_cubes.obj");
        }
Exemplo n.º 29
0
        public virtual bool Apply()
        {
            DMesh3 testAgainstMesh = Mesh;

            if (InsideMode == CalculationMode.RayParity)
            {
                MeshBoundaryLoops loops = new MeshBoundaryLoops(testAgainstMesh);
                if (loops.Count > 0)
                {
                    testAgainstMesh = new DMesh3(Mesh);
                    foreach (var loop in loops)
                    {
                        if (Cancelled())
                        {
                            return(false);
                        }
                        SimpleHoleFiller filler = new SimpleHoleFiller(testAgainstMesh, loop);
                        filler.Fill();
                    }
                }
            }

            DMeshAABBTree3 spatial = (Spatial != null && testAgainstMesh == Mesh) ?
                                     Spatial : new DMeshAABBTree3(testAgainstMesh, true);

            if (InsideMode == CalculationMode.AnalyticWindingNumber)
            {
                spatial.WindingNumber(Vector3d.Zero);
            }
            else if (InsideMode == CalculationMode.FastWindingNumber)
            {
                spatial.FastWindingNumber(Vector3d.Zero);
            }

            if (Cancelled())
            {
                return(false);
            }

            // ray directions
            List <Vector3d> ray_dirs = null; int NR = 0;

            if (InsideMode == CalculationMode.SimpleOcclusionTest)
            {
                ray_dirs = new List <Vector3d>();
                ray_dirs.Add(Vector3d.AxisX); ray_dirs.Add(-Vector3d.AxisX);
                ray_dirs.Add(Vector3d.AxisY); ray_dirs.Add(-Vector3d.AxisY);
                ray_dirs.Add(Vector3d.AxisZ); ray_dirs.Add(-Vector3d.AxisZ);
                NR = ray_dirs.Count;
            }

            Func <Vector3d, bool> isOccludedF = (pt) => {
                if (InsideMode == CalculationMode.RayParity)
                {
                    return(spatial.IsInside(pt));
                }
                else if (InsideMode == CalculationMode.AnalyticWindingNumber)
                {
                    return(spatial.WindingNumber(pt) > WindingIsoValue);
                }
                else if (InsideMode == CalculationMode.FastWindingNumber)
                {
                    return(spatial.FastWindingNumber(pt) > WindingIsoValue);
                }
                else
                {
                    for (int k = 0; k < NR; ++k)
                    {
                        int hit_tid = spatial.FindNearestHitTriangle(new Ray3d(pt, ray_dirs[k]));
                        if (hit_tid == DMesh3.InvalidID)
                        {
                            return(false);
                        }
                    }
                    return(true);
                }
            };

            bool cancel = false;

            BitArray vertices = null;

            if (PerVertex)
            {
                vertices = new BitArray(Mesh.MaxVertexID);

                MeshNormals normals = null;
                if (Mesh.HasVertexNormals == false)
                {
                    normals = new MeshNormals(Mesh);
                    normals.Compute();
                }

                gParallel.ForEach(Mesh.VertexIndices(), (vid) => {
                    if (cancel)
                    {
                        return;
                    }
                    if (vid % 10 == 0)
                    {
                        cancel = Cancelled();
                    }

                    Vector3d c    = Mesh.GetVertex(vid);
                    Vector3d n    = (normals == null) ? Mesh.GetVertexNormal(vid) : normals[vid];
                    c            += n * NormalOffset;
                    vertices[vid] = isOccludedF(c);
                });
            }
            if (Cancelled())
            {
                return(false);
            }

            RemovedT = new List <int>();
            SpinLock removeLock = new SpinLock();

            gParallel.ForEach(Mesh.TriangleIndices(), (tid) => {
                if (cancel)
                {
                    return;
                }
                if (tid % 10 == 0)
                {
                    cancel = Cancelled();
                }

                bool inside = false;
                if (PerVertex)
                {
                    Index3i tri = Mesh.GetTriangle(tid);
                    inside      = vertices[tri.a] || vertices[tri.b] || vertices[tri.c];
                }
                else
                {
                    Vector3d c = Mesh.GetTriCentroid(tid);
                    Vector3d n = Mesh.GetTriNormal(tid);
                    c         += n * NormalOffset;
                    inside     = isOccludedF(c);
                }

                if (inside)
                {
                    bool taken = false;
                    removeLock.Enter(ref taken);
                    RemovedT.Add(tid);
                    removeLock.Exit();
                }
            });

            if (Cancelled())
            {
                return(false);
            }

            if (RemovedT.Count > 0)
            {
                MeshEditor editor = new MeshEditor(Mesh);
                bool       bOK    = editor.RemoveTriangles(RemovedT, true);
                RemoveFailed = (bOK == false);
            }

            return(true);
        }
Exemplo n.º 30
0
        public static void test_marching_cubes_demos()
        {
            // generateMeshF() meshes the input implicit function at
            // the given cell resolution, and writes out the resulting mesh
            Action <BoundedImplicitFunction3d, int, string> generateMeshF = (root, numcells, path) => {
                MarchingCubes c = new MarchingCubes();
                c.Implicit      = root;
                c.RootMode      = MarchingCubes.RootfindingModes.LerpSteps; // cube-edge convergence method
                c.RootModeSteps = 5;                                        // number of iterations
                c.Bounds        = root.Bounds();
                c.CubeSize      = c.Bounds.MaxDim / numcells;
                c.Bounds.Expand(3 * c.CubeSize);                                   // leave a buffer of cells
                c.Generate();
                MeshNormals.QuickCompute(c.Mesh);                                  // generate normals
                StandardMeshWriter.WriteMesh(path, c.Mesh, WriteOptions.Defaults); // write mesh
            };

            // meshToImplicitF() generates a narrow-band distance-field and
            // returns it as an implicit surface, that can be combined with other implicits
            Func <DMesh3, int, double, BoundedImplicitFunction3d> meshToImplicitF = (meshIn, numcells, max_offset) => {
                double meshCellsize             = meshIn.CachedBounds.MaxDim / numcells;
                MeshSignedDistanceGrid levelSet = new MeshSignedDistanceGrid(meshIn, meshCellsize);
                levelSet.ExactBandWidth = (int)(max_offset / meshCellsize) + 1;
                levelSet.Compute();
                return(new DenseGridTrilinearImplicit(levelSet.Grid, levelSet.GridOrigin, levelSet.CellSize));
            };

            // meshToBlendImplicitF() computes the full distance-field grid for the input
            // mesh. The bounds are expanded quite a bit to allow for blending,
            // probably more than necessary in most cases
            Func <DMesh3, int, BoundedImplicitFunction3d> meshToBlendImplicitF = (meshIn, numcells) => {
                double meshCellsize             = meshIn.CachedBounds.MaxDim / numcells;
                MeshSignedDistanceGrid levelSet = new MeshSignedDistanceGrid(meshIn, meshCellsize);
                levelSet.ExpandBounds = meshIn.CachedBounds.Diagonal * 0.25;        // need some values outside mesh
                levelSet.ComputeMode  = MeshSignedDistanceGrid.ComputeModes.FullGrid;
                levelSet.Compute();
                return(new DenseGridTrilinearImplicit(levelSet.Grid, levelSet.GridOrigin, levelSet.CellSize));
            };



            // generate union/difference/intersection of sphere and cube

            ImplicitSphere3d sphere = new ImplicitSphere3d()
            {
                Origin = Vector3d.Zero, Radius = 1.0
            };
            ImplicitBox3d box = new ImplicitBox3d()
            {
                Box = new Box3d(new Frame3f(Vector3f.AxisX), 0.5 * Vector3d.One)
            };

            generateMeshF(new ImplicitUnion3d()
            {
                A = sphere, B = box
            }, 128, "c:\\demo\\union.obj");
            generateMeshF(new ImplicitDifference3d()
            {
                A = sphere, B = box
            }, 128, "c:\\demo\\difference.obj");
            generateMeshF(new ImplicitIntersection3d()
            {
                A = sphere, B = box
            }, 128, "c:\\demo\\intersection.obj");


            // generate bunny offset surfaces

            //double offset = 0.2f;
            //DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_solid.obj");
            //MeshTransforms.Scale(mesh, 3.0 / mesh.CachedBounds.MaxDim);
            //BoundedImplicitFunction3d meshImplicit = meshToImplicitF(mesh, 64, offset);

            //generateMeshF(meshImplicit, 128, "c:\\demo\\mesh.obj");
            //generateMeshF(new ImplicitOffset3d() { A = meshImplicit, Offset = offset }, 128, "c:\\demo\\mesh_outset.obj");
            //generateMeshF(new ImplicitOffset3d() { A = meshImplicit, Offset = -offset }, 128, "c:\\demo\\mesh_inset.obj");


            // compare offset of sharp and smooth union

            //var smooth_union = new ImplicitSmoothDifference3d() { A = sphere, B = box };
            //generateMeshF(smooth_union, 128, "c:\\demo\\smooth_union.obj");
            //generateMeshF(new ImplicitOffset3d() { A = smooth_union, Offset = 0.2 }, 128, "c:\\demo\\smooth_union_offset.obj");

            //var union = new ImplicitUnion3d() { A = sphere, B = box };
            //generateMeshF(new ImplicitOffset3d() { A = union, Offset = offset }, 128, "c:\\demo\\union_offset.obj");


            // blending

            //ImplicitSphere3d sphere1 = new ImplicitSphere3d() {
            //    Origin = Vector3d.Zero, Radius = 1.0
            //};
            //ImplicitSphere3d sphere2 = new ImplicitSphere3d() {
            //    Origin = 1.5 * Vector3d.AxisX, Radius = 1.0
            //};
            //generateMeshF(new ImplicitBlend3d() { A = sphere1, B = sphere2, Blend = 1.0 }, 128, "c:\\demo\\blend_1.obj");
            //generateMeshF(new ImplicitBlend3d() { A = sphere1, B = sphere2, Blend = 4.0 }, 128, "c:\\demo\\blend_4.obj");
            //generateMeshF(new ImplicitBlend3d() { A = sphere1, B = sphere2, Blend = 16.0 }, 128, "c:\\demo\\blend_16.obj");
            //generateMeshF(new ImplicitBlend3d() { A = sphere1, B = sphere2, Blend = 64.0 }, 128, "c:\\demo\\blend_64.obj");
            //sphere1.Radius = sphere2.Radius = 2.0f;
            //sphere2.Origin = 1.5 * sphere1.Radius * Vector3d.AxisX;
            //generateMeshF(new ImplicitBlend3d() { A = sphere1, B = sphere2, Blend = 1.0 }, 128, "c:\\demo\\blend_2x_1.obj");
            //generateMeshF(new ImplicitBlend3d() { A = sphere1, B = sphere2, Blend = 4.0 }, 128, "c:\\demo\\blend_2x_4.obj");
            //generateMeshF(new ImplicitBlend3d() { A = sphere1, B = sphere2, Blend = 16.0 }, 128, "c:\\demo\\blend_2x_16.obj");
            //generateMeshF(new ImplicitBlend3d() { A = sphere1, B = sphere2, Blend = 64.0 }, 128, "c:\\demo\\blend_2x_64.obj");


            // mesh blending

            //DMesh3 mesh1 = TestUtil.LoadTestInputMesh("bunny_solid.obj");
            //MeshTransforms.Scale(mesh1, 3.0 / mesh1.CachedBounds.MaxDim);
            //DMesh3 mesh2 = new DMesh3(mesh1);
            //MeshTransforms.Rotate(mesh2, mesh2.CachedBounds.Center, Quaternionf.AxisAngleD(Vector3f.OneNormalized, 45.0f));

            //var meshImplicit1 = meshToImplicitF(mesh1, 64, 0);
            //var meshImplicit2 = meshToImplicitF(mesh2, 64, 0);
            //generateMeshF(new ImplicitBlend3d() { A = meshImplicit1, B = meshImplicit2, Blend = 0.0 }, 256, "c:\\demo\\blend_mesh_union.obj");
            //generateMeshF(new ImplicitBlend3d() { A = meshImplicit1, B = meshImplicit2, Blend = 10.0 }, 256, "c:\\demo\\blend_mesh_bad.obj");

            //var meshFullImplicit1 = meshToBlendImplicitF(mesh1, 64);
            //var meshFullImplicit2 = meshToBlendImplicitF(mesh2, 64);
            //generateMeshF(new ImplicitBlend3d() { A = meshFullImplicit1, B = meshFullImplicit2, Blend = 0.0 }, 256, "c:\\demo\\blend_mesh_union.obj");
            //generateMeshF(new ImplicitBlend3d() { A = meshFullImplicit1, B = meshFullImplicit2, Blend = 1.0 }, 256, "c:\\demo\\blend_mesh_1.obj");
            //generateMeshF(new ImplicitBlend3d() { A = meshFullImplicit1, B = meshFullImplicit2, Blend = 10.0 }, 256, "c:\\demo\\blend_mesh_10.obj");
            //generateMeshF(new ImplicitBlend3d() { A = meshFullImplicit1, B = meshFullImplicit2, Blend = 50.0 }, 256, "c:\\demo\\blend_mesh_100.obj");


            //DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_solid.obj");
            //MeshTransforms.Scale(mesh, 3.0 / mesh.CachedBounds.MaxDim);
            //MeshTransforms.Translate(mesh, -mesh.CachedBounds.Center);
            //Reducer r = new Reducer(mesh);
            //r.ReduceToTriangleCount(100);

            //double radius = 0.1;
            //List<BoundedImplicitFunction3d> Lines = new List<BoundedImplicitFunction3d>();
            //foreach (Index4i edge_info in mesh.Edges()) {
            //    var segment = new Segment3d(mesh.GetVertex(edge_info.a), mesh.GetVertex(edge_info.b));
            //    Lines.Add(new ImplicitLine3d() { Segment = segment, Radius = radius });
            //}
            //ImplicitNaryUnion3d unionN = new ImplicitNaryUnion3d() { Children = Lines };
            //generateMeshF(unionN, 128, "c:\\demo\\mesh_edges.obj");

            //radius = 0.05;
            //List<BoundedImplicitFunction3d> Elements = new List<BoundedImplicitFunction3d>();
            //foreach (int eid in mesh.EdgeIndices()) {
            //    var segment = new Segment3d(mesh.GetEdgePoint(eid, 0), mesh.GetEdgePoint(eid, 1));
            //    Elements.Add(new ImplicitLine3d() { Segment = segment, Radius = radius });
            //}
            //foreach (Vector3d v in mesh.Vertices())
            //    Elements.Add(new ImplicitSphere3d() { Origin = v, Radius = 2 * radius });
            //generateMeshF(new ImplicitNaryUnion3d() { Children = Elements }, 256, "c:\\demo\\mesh_edges_and_vertices.obj");


            //double lattice_radius = 0.05;
            //double lattice_spacing = 0.4;
            //double shell_thickness = 0.05;
            //int mesh_resolution = 64;   // set to 256 for image quality

            //var shellMeshImplicit = meshToImplicitF(mesh, 128, shell_thickness);
            //double max_dim = mesh.CachedBounds.MaxDim;
            //AxisAlignedBox3d bounds = new AxisAlignedBox3d(mesh.CachedBounds.Center, max_dim / 2);
            //bounds.Expand(2 * lattice_spacing);
            //AxisAlignedBox2d element = new AxisAlignedBox2d(lattice_spacing);
            //AxisAlignedBox2d bounds_xy = new AxisAlignedBox2d(bounds.Min.xy, bounds.Max.xy);
            //AxisAlignedBox2d bounds_xz = new AxisAlignedBox2d(bounds.Min.xz, bounds.Max.xz);
            //AxisAlignedBox2d bounds_yz = new AxisAlignedBox2d(bounds.Min.yz, bounds.Max.yz);

            //List<BoundedImplicitFunction3d> Tiling = new List<BoundedImplicitFunction3d>();
            //foreach (Vector2d uv in TilingUtil.BoundedRegularTiling2(element, bounds_xy, 0)) {
            //    Segment3d seg = new Segment3d(new Vector3d(uv.x, uv.y, bounds.Min.z), new Vector3d(uv.x, uv.y, bounds.Max.z));
            //    Tiling.Add(new ImplicitLine3d() { Segment = seg, Radius = lattice_radius });
            //}
            //foreach (Vector2d uv in TilingUtil.BoundedRegularTiling2(element, bounds_xz, 0)) {
            //    Segment3d seg = new Segment3d(new Vector3d(uv.x, bounds.Min.y, uv.y), new Vector3d(uv.x, bounds.Max.y, uv.y));
            //    Tiling.Add(new ImplicitLine3d() { Segment = seg, Radius = lattice_radius });
            //}
            //foreach (Vector2d uv in TilingUtil.BoundedRegularTiling2(element, bounds_yz, 0)) {
            //    Segment3d seg = new Segment3d(new Vector3d(bounds.Min.x, uv.x, uv.y), new Vector3d(bounds.Max.x, uv.x, uv.y));
            //    Tiling.Add(new ImplicitLine3d() { Segment = seg, Radius = lattice_radius });
            //}
            //ImplicitNaryUnion3d lattice = new ImplicitNaryUnion3d() { Children = Tiling };
            //generateMeshF(lattice, 128, "c:\\demo\\lattice.obj");

            //ImplicitIntersection3d lattice_clipped = new ImplicitIntersection3d() { A = lattice, B = shellMeshImplicit };
            //generateMeshF(lattice_clipped, mesh_resolution, "c:\\demo\\lattice_clipped.obj");

            //var shell = new ImplicitDifference3d() {
            //    A = shellMeshImplicit, B = new ImplicitOffset3d() { A = shellMeshImplicit, Offset = -shell_thickness }
            //};
            //var shell_cut = new ImplicitDifference3d() {
            //    A = shell, B = new ImplicitAxisAlignedBox3d() { AABox = new AxisAlignedBox3d(Vector3d.Zero, max_dim / 2, 0.4, max_dim / 2) }
            //};
            //generateMeshF(new ImplicitUnion3d() { A = lattice_clipped, B = shell_cut }, mesh_resolution, "c:\\demo\\lattice_result.obj");
        }