Beispiel #1
0
        public static DMeshAABBTree3 AABBTree(this DMesh3 mesh)
        {
            var tree = new DMeshAABBTree3(mesh);

            tree.Build();
            return(tree);
        }
Beispiel #2
0
    internal bool CheckIntersection(DMesh3 mesh, Triangle3d triangle)
    {
        var spatial = new DMeshAABBTree3(mesh);

        spatial.Build();
        return(spatial.TestIntersection(triangle));
    }
Beispiel #3
0
        public static void test_AABBTree_TriDist(int meshCase = 0)
        {
            DMesh3         mesh = MakeSpatialTestMesh(meshCase);
            DMeshAABBTree3 tree = new DMeshAABBTree3(mesh);

            tree.Build();

            AxisAlignedBox3d bounds = mesh.CachedBounds;
            Vector3d         ext    = bounds.Extents;
            Vector3d         c      = bounds.Center;

            Random rand = new Random(316136327);

            int N = 10000;

            for (int ii = 0; ii < N; ++ii)
            {
                Vector3d p = new Vector3d(
                    c.x + (4 * ext.x * (2 * rand.NextDouble() - 1)),
                    c.y + (4 * ext.y * (2 * rand.NextDouble() - 1)),
                    c.z + (4 * ext.z * (2 * rand.NextDouble() - 1)));

                int tNearBrute = MeshQueries.FindNearestTriangle_LinearSearch(mesh, p);
                int tNearTree  = tree.FindNearestTriangle(p);

                DistPoint3Triangle3 qBrute = MeshQueries.TriangleDistance(mesh, tNearBrute, p);
                DistPoint3Triangle3 qTree  = MeshQueries.TriangleDistance(mesh, tNearTree, p);

                if (Math.Abs(qBrute.DistanceSquared - qTree.DistanceSquared) > MathUtil.ZeroTolerance)
                {
                    Util.gBreakToDebugger();
                }
            }
        }
        public static void test_basic_closed_reduce()
        {
            //DMesh3 mesh = TestUtil.MakeCappedCylinder(false);
            //DMesh3 mesh = TestUtil.LoadTestInputMesh("sphere_bowtie_groups.obj");
            DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_solid.obj");

            //MeshUtil.ScaleMesh(mesh, Frame3f.Identity, new Vector3f(1,2,1));
            //DMesh3 mesh = TestUtil.MakeOpenCylinder(false);
            mesh.CheckValidity();

            if (WriteDebugMeshes)
            {
                TestUtil.WriteTestOutputMesh(mesh, "basic_closed_reduce_before.obj");
            }

            Reducer r = new Reducer(mesh);

            DMeshAABBTree3 tree = new DMeshAABBTree3(new DMesh3(mesh));

            tree.Build();
            //r.SetProjectionTarget(new MeshProjectionTarget() { Mesh = tree.Mesh, Spatial = tree });

            r.ReduceToTriangleCount(3000);
            //r.ReduceToEdgeLength(2.0);

            double mine, maxe, avge;

            MeshQueries.EdgeLengthStats(mesh, out mine, out maxe, out avge);
            System.Console.WriteLine("Edge length stats: {0} {1} {2}", mine, maxe, avge);

            if (WriteDebugMeshes)
            {
                TestUtil.WriteTestOutputMesh(mesh, "basic_closed_reduce_after.obj");
            }
        }
Beispiel #5
0
        public static void test_AABBTree_basic()
        {
            List <int> cases = new List <int>()
            {
                0, 1, 2, 3, 4, 7, 8
            };

            foreach (int meshCase in cases)
            {
                DMesh3         mesh       = MakeSpatialTestMesh(meshCase);
                DMeshAABBTree3 treeMedian = new DMeshAABBTree3(mesh);
                treeMedian.Build(DMeshAABBTree3.BuildStrategy.TopDownMedian);
                treeMedian.TestCoverage();
                treeMedian.TotalVolume();

                DMeshAABBTree3 treeMidpoint = new DMeshAABBTree3(mesh);
                treeMidpoint.Build(DMeshAABBTree3.BuildStrategy.TopDownMidpoint);
                treeMidpoint.TestCoverage();
                treeMidpoint.TotalVolume();

                DMeshAABBTree3 treeUpFast = new DMeshAABBTree3(mesh);
                treeUpFast.Build(DMeshAABBTree3.BuildStrategy.BottomUpFromOneRings, DMeshAABBTree3.ClusterPolicy.Fastest);
                treeUpFast.TestCoverage();
                treeUpFast.TotalVolume();

                DMeshAABBTree3 treeUpN = new DMeshAABBTree3(mesh);
                treeUpN.Build(DMeshAABBTree3.BuildStrategy.BottomUpFromOneRings, DMeshAABBTree3.ClusterPolicy.FastVolumeMetric);
                treeUpN.TestCoverage();
                treeUpN.TotalVolume();
            }
        }
Beispiel #6
0
    void Start()
    {
        if (model != null)
        {
            mesh          = model.sharedMesh;
            meshVertices  = mesh.vertices;
            meshTriangles = mesh.triangles;
            for (int i = 0; i < meshVertices.Length; i++)
            {
                meshVertices[i] = model.transform.TransformPoint(meshVertices[i]);
            }
            binarySpacePartition = new BSP(mesh, 14);

#if G3_USING_UNITY
            DMesh3Builder dMeshBuilder = new DMesh3Builder();
            dMeshBuilder.AppendNewMesh(false, false, false, false);
            foreach (Vector3 vertex in meshVertices)
            {
                dMeshBuilder.AppendVertex(vertex.x, vertex.y, vertex.z);
            }
            for (int i = 0; i < meshTriangles.Length; i += 3)
            {
                dMeshBuilder.AppendTriangle(meshTriangles[i], meshTriangles[i + 1], meshTriangles[i + 2]);
            }
            g3MeshTree = new DMeshAABBTree3(dMeshBuilder.Meshes[0]);
            g3MeshTree.Build();
#endif
        }
    }
Beispiel #7
0
        DMesh3 GenerateRemesh(DMesh3 mesh)
        {
            DMesh3 remeshed = new DMesh3(mesh);

            DMeshAABBTree3 project = new DMeshAABBTree3(mesh);

            project.Build();
            MeshProjectionTarget Target = new MeshProjectionTarget(project.Mesh, project);

            double minlen, maxlen, avglen;

            MeshQueries.EdgeLengthStats(mesh, out minlen, out maxlen, out avglen);
            double edge_len = (TargetEdgeLength == 0) ? Loop.AverageEdgeLength : avglen;

            Remesher r = new Remesher(remeshed);

            r.SetTargetEdgeLength(edge_len);
            r.SetProjectionTarget(Target);
            MeshConstraintUtil.FixAllBoundaryEdges(r);

            for (int k = 0; k < 20; ++k)
            {
                r.BasicRemeshPass();
            }

            return(remeshed);
        }
Beispiel #8
0
 void validate_spatial()
 {
     if (enable_spatial && spatial == null)
     {
         spatial = new DMeshAABBTree3(mesh);
         spatial.Build();
     }
 }
Beispiel #9
0
        /// <summary>
        /// Checks if a point is inside of a mesh. This function is slow due to the need to build a spatial data structure using geometry3Sharp.
        /// </summary>
        /// <param name="mesh">The mesh to be checked.</param>
        /// <param name="point">The point in question.</param>
        /// <returns>Whether the point is inside the mesh.</returns>
        public static bool IsPointInside(this Mesh mesh, Vector3 point)
        {
            var mesh3   = GenerateDynamicMesh(mesh.vertices, mesh.triangles, mesh.normals);
            var spatial = new DMeshAABBTree3(mesh3);

            spatial.Build();
            return(spatial.IsInside(new Vector3d(point.x, point.y, point.z)));
        }
Beispiel #10
0
        public DMesh3 remesh_constraints_fixedverts(int iterations, DMesh3 mesh, double min, double max, double angle)
        {
            AxisAlignedBox3d bounds = mesh.CachedBounds;

            // construct mesh projection target
            DMesh3 meshCopy = new DMesh3(mesh);

            meshCopy.CheckValidity();
            DMeshAABBTree3 tree = new DMeshAABBTree3(meshCopy);

            tree.Build();
            MeshProjectionTarget target = new MeshProjectionTarget()
            {
                Mesh = meshCopy, Spatial = tree
            };

            // construct constraint set
            MeshConstraints cons = new MeshConstraints();

            //EdgeRefineFlags useFlags = EdgeRefineFlags.NoFlip | EdgeRefineFlags.NoCollapse;
            EdgeRefineFlags useFlags = EdgeRefineFlags.NoFlip;

            foreach (int eid in mesh.EdgeIndices())
            {
                double fAngle = MeshUtil.OpeningAngleD(mesh, eid);
                if (fAngle > angle)
                {
                    cons.SetOrUpdateEdgeConstraint(eid, new EdgeConstraint(useFlags));
                    Index2i ev      = mesh.GetEdgeV(eid);
                    int     nSetID0 = (mesh.GetVertex(ev[0]).y > bounds.Center.y) ? 1 : 2;
                    int     nSetID1 = (mesh.GetVertex(ev[1]).y > bounds.Center.y) ? 1 : 2;
                    cons.SetOrUpdateVertexConstraint(ev[0], new VertexConstraint(true, nSetID0));
                    cons.SetOrUpdateVertexConstraint(ev[1], new VertexConstraint(true, nSetID1));
                }
            }

            Remesher r = new Remesher(mesh);

            r.Precompute();
            r.SetExternalConstraints(cons);
            r.SetProjectionTarget(target);
            r.EnableFlips     = r.EnableSplits = r.EnableCollapses = true;
            r.MinEdgeLength   = min;
            r.MaxEdgeLength   = max;
            r.EnableSmoothing = true;
            r.SmoothSpeedT    = 1;


            for (int k = 0; k < iterations; ++k)
            {
                r.BasicRemeshPass();
                mesh.CheckValidity();
            }


            return(mesh);
        }
 public ConstantMeshSourceOp(DMesh3 meshIn, bool buildSpatial, bool bTakeOwnership)
 {
     mesh = (bTakeOwnership) ? meshIn : new DMesh3(meshIn);
     if (buildSpatial)
     {
         spatial = new DMeshAABBTree3(mesh);
         spatial.Build();
     }
 }
Beispiel #12
0
        /// <summary>
        /// Generates a mesh for the ground that we can work with.
        /// </summary>
        private void LoadGroundMesh()
        {
            var vertices  = _data.Vertices.Select(a => new Vector3f(a.X, a.Z, a.Y));
            var triangles = _data.Triangles.Select(a => new Index3i(a.Indices[0], a.Indices[1], a.Indices[2]));

            _mesh = DMesh3Builder.Build <Vector3f, Index3i, Vector3f>(vertices, triangles, null, null);

            _spatial = new DMeshAABBTree3(_mesh);
            _spatial.Build();
        }
Beispiel #13
0
 public void UpdateCollision()
 {
     for (int i = 0; i < numXVerts * numXVerts; i++)
     {
         if (vertNeedsCollisionUpdate[i])
         {
             dMesh.SetVertex(i, new Vector3d(vertices[i].x, vertices[i].y, vertices[i].z));
             vertNeedsCollisionUpdate[i] = false;
         }
     }
     dMeshAABB.Build();
 }
Beispiel #14
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 void SetMesh(DMesh3 meshIn, bool buildSpatial, bool bTakeOwnership)
        {
            mesh = (bTakeOwnership) ? meshIn : new DMesh3(meshIn);

            spatial = null;
            if (buildSpatial)
            {
                spatial = new DMeshAABBTree3(mesh);
                spatial.Build();
            }

            PostOnOperatorModified();
        }
Beispiel #16
0
        public static DMesh3 MakeRemeshedCappedCylinder(double fResFactor = 1.0)
        {
            DMesh3 mesh = MakeCappedCylinder(false, 128);

            MeshUtil.ScaleMesh(mesh, Frame3f.Identity, new g3.Vector3f(1, 2, 1));

            // construct mesh projection target
            DMesh3         meshCopy = new DMesh3(mesh);
            DMeshAABBTree3 tree     = new DMeshAABBTree3(meshCopy);

            tree.Build();
            MeshProjectionTarget target = new MeshProjectionTarget()
            {
                Mesh    = meshCopy,
                Spatial = tree
            };
            MeshConstraints cons     = new MeshConstraints();
            EdgeRefineFlags useFlags = EdgeRefineFlags.NoFlip;

            foreach (int eid in mesh.EdgeIndices())
            {
                double fAngle = MeshUtil.OpeningAngleD(mesh, eid);
                if (fAngle > 30.0f)
                {
                    cons.SetOrUpdateEdgeConstraint(eid, new EdgeConstraint(useFlags));
                    Index2i ev      = mesh.GetEdgeV(eid);
                    int     nSetID0 = (mesh.GetVertex(ev[0]).y > 1) ? 1 : 2;
                    int     nSetID1 = (mesh.GetVertex(ev[1]).y > 1) ? 1 : 2;
                    cons.SetOrUpdateVertexConstraint(ev[0], new VertexConstraint(true, nSetID0));
                    cons.SetOrUpdateVertexConstraint(ev[1], new VertexConstraint(true, nSetID1));
                }
            }
            Remesher r = new Remesher(mesh);

            r.SetExternalConstraints(cons);
            r.SetProjectionTarget(target);
            r.Precompute();
            r.EnableFlips     = r.EnableSplits = r.EnableCollapses = true;
            r.MinEdgeLength   = 0.1f * fResFactor;
            r.MaxEdgeLength   = 0.2f * fResFactor;
            r.EnableSmoothing = true;
            r.SmoothSpeedT    = 0.5f;
            for (int k = 0; k < 20; ++k)
            {
                r.BasicRemeshPass();
            }
            return(mesh);
        }
Beispiel #17
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;
            }));
        }
Beispiel #18
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();
        }
Beispiel #19
0
    internal bool CheckPositionValid(DMesh3 mesh, Vector3d position, int colorToExclude)
    {
        var spatial = new DMeshAABBTree3(mesh);

        spatial.Build();

        spatial.TriangleFilterF = i => mesh.GetTriangleGroup(i) != colorToExclude;

        int near_tid = spatial.FindNearestTriangle(position, 9f);

        if (near_tid != DMesh3.InvalidID)
        {
            return(false);
        }

        return(true);
    }
Beispiel #20
0
        public Mesh Reduce(Mesh inMesh, int targetCount)
        {
            var mesh    = inMesh.ToDMesh3();
            var reducer = new Reducer(mesh);

            if (MaintainSurface)
            {
                var tree = new DMeshAABBTree3(new DMesh3(mesh));
                tree.Build();
                var target = new MeshProjectionTarget(tree.Mesh, tree);
                reducer.SetProjectionTarget(target);
                reducer.ProjectionMode = Reducer.TargetProjectionMode.Inline;
            }

            reducer.ReduceToTriangleCount(Math.Max(4, targetCount));

            return(reducer.Mesh.ToMesh());
        }
Beispiel #21
0
    void Start()
    {
        if (model != null)
        {
            mesh          = model.sharedMesh;
            meshVertices  = mesh.vertices;
            meshTriangles = mesh.triangles;
            for (int i = 0; i < meshVertices.Length; i++)
            {
                meshVertices[i] = model.transform.TransformPoint(meshVertices[i]);
            }
            binarySpacePartition = new BSP(mesh, 14);

            if (diskMaterial)
            {
                int numDisksToDraw = Mathf.Min(binarySpacePartition.splittingDisks.Length, 15);
                diskMatrices = new Matrix4x4[numDisksToDraw];
                for (int i = 0; i < numDisksToDraw; i++)
                {
                    diskMatrices[i] = Matrix4x4.TRS(
                        binarySpacePartition.splittingDisks[i].average,
                        Quaternion.LookRotation(binarySpacePartition.splittingDisks[i].plane),
                        new Vector3(1f, 1f, 0.0001f) * Mathf.Sqrt(binarySpacePartition.splittingDisks[i].sqRadius));
                }
            }

#if G3_USING_UNITY
            DMesh3Builder dMeshBuilder = new DMesh3Builder();
            dMeshBuilder.AppendNewMesh(false, false, false, false);
            foreach (Vector3 vertex in meshVertices)
            {
                dMeshBuilder.AppendVertex(vertex.x, vertex.y, vertex.z);
            }
            for (int i = 0; i < meshTriangles.Length; i += 3)
            {
                dMeshBuilder.AppendTriangle(meshTriangles[i], meshTriangles[i + 1], meshTriangles[i + 2]);
            }
            g3MeshTree = new DMeshAABBTree3(dMeshBuilder.Meshes[0]);
            g3MeshTree.Build();
#endif
        }
    }
Beispiel #22
0
        public virtual bool FindNearest(Vector3d point, double maxDist, out SORayHit nearest, CoordSpace eInCoords)
        {
            nearest = null;
            if (enable_spatial == false)
            {
                return(false);
            }

            if (spatial == null)
            {
                spatial = new DMeshAABBTree3(mesh);
                spatial.Build();
            }

            // convert to local
            Vector3f local_pt = SceneTransforms.TransformTo((Vector3f)point, this, eInCoords, CoordSpace.ObjectCoords);

            if (mesh.CachedBounds.Distance(local_pt) > maxDist)
            {
                return(false);
            }

            int tid = spatial.FindNearestTriangle(local_pt);

            if (tid != DMesh3.InvalidID)
            {
                DistPoint3Triangle3 dist = MeshQueries.TriangleDistance(mesh, tid, local_pt);

                nearest          = new SORayHit();
                nearest.fHitDist = (float)Math.Sqrt(dist.DistanceSquared);

                Frame3f f_local = new Frame3f(dist.TriangleClosest, mesh.GetTriNormal(tid));
                Frame3f f       = SceneTransforms.TransformTo(f_local, this, CoordSpace.ObjectCoords, eInCoords);

                nearest.hitPos    = f.Origin;
                nearest.hitNormal = f.Z;
                nearest.hitGO     = RootGameObject;
                nearest.hitSO     = this;
                return(true);
            }
            return(false);
        }
Beispiel #23
0
        /// <summary>
        /// Find intersection of *WORLD* ray with Mesh
        /// </summary>
        override public bool FindRayIntersection(Ray3f rayW, out SORayHit hit)
        {
            hit = null;
            if (enable_spatial == false)
            {
                return(false);
            }

            if (spatial == null)
            {
                spatial = new DMeshAABBTree3(mesh);
                spatial.Build();
            }

            // convert ray to local
            Frame3f f = new Frame3f(rayW.Origin, rayW.Direction);

            f = SceneTransforms.TransformTo(f, this, CoordSpace.WorldCoords, CoordSpace.ObjectCoords);
            Ray3d local_ray = new Ray3d(f.Origin, f.Z);

            int hit_tid = spatial.FindNearestHitTriangle(local_ray);

            if (hit_tid != DMesh3.InvalidID)
            {
                IntrRay3Triangle3 intr = MeshQueries.TriangleIntersection(mesh, hit_tid, local_ray);

                Frame3f hitF = new Frame3f(local_ray.PointAt(intr.RayParameter), mesh.GetTriNormal(hit_tid));
                hitF = SceneTransforms.TransformTo(hitF, this, CoordSpace.ObjectCoords, CoordSpace.WorldCoords);

                hit           = new SORayHit();
                hit.hitPos    = hitF.Origin;
                hit.hitNormal = hitF.Z;
                hit.hitIndex  = hit_tid;
                hit.fHitDist  = hit.hitPos.Distance(rayW.Origin);   // simpler than transforming!
                hit.hitGO     = RootGameObject;
                hit.hitSO     = this;
                return(true);
            }
            return(false);
        }
Beispiel #24
0
        // [RMS] this is not working right now...
        override public bool FindRayIntersection(Ray3f ray, out SORayHit hit)
        {
            hit = null;
            if (enable_spatial == false)
            {
                return(false);
            }

            if (spatial == null)
            {
                spatial = new DMeshAABBTree3(mesh);
                spatial.Build();
            }

            Transform xform = ((GameObject)RootGameObject).transform;

            // convert ray to local
            Ray3d local_ray = new Ray3d();

            local_ray.Origin    = xform.InverseTransformPoint(ray.Origin);
            local_ray.Direction = xform.InverseTransformDirection(ray.Direction);
            local_ray.Direction.Normalize();

            int hit_tid = spatial.FindNearestHitTriangle(local_ray);

            if (hit_tid != DMesh3.InvalidID)
            {
                IntrRay3Triangle3 intr = MeshQueries.TriangleIntersection(mesh, hit_tid, local_ray);

                hit           = new SORayHit();
                hit.fHitDist  = (float)intr.RayParameter;
                hit.hitPos    = xform.TransformPoint((Vector3f)local_ray.PointAt(intr.RayParameter));
                hit.hitNormal = xform.TransformDirection((Vector3f)mesh.GetTriNormal(hit_tid));
                hit.hitGO     = RootGameObject;
                hit.hitSO     = this;
                return(true);
            }
            return(false);
        }
        public static bool ReduceMesh(DMesh3 mesh, float edgeLength, int triangleCount)
        {
            Reducer r = new Reducer(mesh);

            DMeshAABBTree3 tree = new DMeshAABBTree3(new DMesh3(mesh));

            tree.Build();


            /*
             * MeshConstraints cons = new MeshConstraints();
             * EdgeRefineFlags useFlags = EdgeRefineFlags.NoFlip;
             * foreach (int eid in mesh.EdgeIndices())
             * {
             *  double fAngle = MeshUtil.OpeningAngleD(mesh, eid);
             *  if (fAngle > contraintAngle)
             *  {
             *      cons.SetOrUpdateEdgeConstraint(eid, new EdgeConstraint(useFlags));
             *      Index2i ev = mesh.GetEdgeV(eid);
             *      int nSetID0 = (mesh.GetVertex(ev[0]).y > 1) ? 1 : 2;
             *      int nSetID1 = (mesh.GetVertex(ev[1]).y > 1) ? 1 : 2;
             *      cons.SetOrUpdateVertexConstraint(ev[0], new VertexConstraint(true, nSetID0));
             *      cons.SetOrUpdateVertexConstraint(ev[1], new VertexConstraint(true, nSetID1));
             *  }
             * }
             */

            if (triangleCount > 0)
            {
                r.ReduceToTriangleCount(3000);
            }
            else
            {
                r.ReduceToEdgeLength(edgeLength);
            }


            return(true);
        }
Beispiel #26
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            DMesh3_goo dMsh_goo = null;
            int        numF     = 0;
            bool       fixB     = false;
            bool       projBack = false;

            DA.GetData(0, ref dMsh_goo);
            DA.GetData(1, ref numF);
            DA.GetData(2, ref fixB);
            DA.GetData(3, ref projBack);

            DMesh3  dMsh_copy = new DMesh3(dMsh_goo.Value);
            Reducer r         = new Reducer(dMsh_copy);

            if (fixB)
            {
                r.SetExternalConstraints(new MeshConstraints());
                MeshConstraintUtil.PreserveBoundaryLoops(r.Constraints, dMsh_copy);
            }
            if (projBack)
            {
                DMeshAABBTree3 tree = new DMeshAABBTree3(new DMesh3(dMsh_copy));
                tree.Build();
                MeshProjectionTarget target = new MeshProjectionTarget(tree.Mesh, tree);
                r.SetProjectionTarget(target);
            }

            r.ReduceToTriangleCount(numF);
            bool isValid = dMsh_copy.CheckValidity();

            if (!isValid)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Mesh seems to have been corrupted during reduction. Please check...");
            }

            DA.SetData(0, dMsh_copy);
        }
Beispiel #27
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;
            }));
        }
Beispiel #28
0
        public static void test_AABBTree_profile()
        {
            System.Console.WriteLine("Building test meshes");
            DMesh3[] meshes = new DMesh3[NumTestCases];
            for (int i = 0; i < NumTestCases; ++i)
            {
                meshes[i] = MakeSpatialTestMesh(i);
            }
            System.Console.WriteLine("done!");


            int N = 10;

            // avoid garbage collection
            List <DMeshAABBTree3> trees = new List <DMeshAABBTree3>();
            DMeshAABBTree3        tree  = null;



            for (int i = 0; i < NumTestCases; ++i)
            {
                Stopwatch w = new Stopwatch();
                for (int j = 0; j < N; ++j)
                {
                    tree = new DMeshAABBTree3(meshes[i]);
                    w.Start();
                    tree.Build(DMeshAABBTree3.BuildStrategy.TopDownMidpoint);
                    //tree.Build(DMeshAABBTree3.BuildStrategy.TopDownMedian);
                    //tree.Build(DMeshAABBTree3.BuildStrategy.BottomUpFromOneRings, DMeshAABBTree3.ClusterPolicy.FastVolumeMetric);
                    w.Stop();
                    trees.Add(tree);
                }
                double avg_time = w.ElapsedTicks / (double)N;
                System.Console.WriteLine(string.Format("Case {0}: time {1}  tris {2} vol {3}  len {4}", i, avg_time, tree.Mesh.TriangleCount, tree.TotalVolume(), tree.TotalExtentSum()));
            }
        }
Beispiel #29
0
        public static void test_AABBTree_RayHit(int meshCase = 8)
        {
            DMesh3         mesh = MakeSpatialTestMesh(meshCase);
            DMeshAABBTree3 tree = new DMeshAABBTree3(mesh);

            tree.Build();
            tree.TestCoverage();

            AxisAlignedBox3d bounds = mesh.CachedBounds;
            Vector3d         ext    = bounds.Extents;
            Vector3d         c      = bounds.Center;
            double           r      = bounds.DiagonalLength / 4;

            Random rand = new Random(316136327);


            tree.FindNearestHitTriangle(
                new Ray3f(100 * Vector3f.One, Vector3f.One));


            // test rays out from center of box, and rays in towards it
            // (should all hit for standard test cases)
            int hits = 0;
            int N    = (meshCase > 7) ? 1000 : 10000;

#if true
            for (int ii = 0; ii < N; ++ii)
            {
                if (ii % 100 == 0)
                {
                    System.Console.WriteLine("{0} / {1}", ii, N);
                }

                Vector3d p   = (ii < N / 2) ? c : c + 2 * r * rand.Direction();
                Vector3d d   = (ii < N / 2) ? rand.Direction() : (c - p).Normalized;
                Ray3d    ray = new Ray3d(p, d);

                int tNearBrute = MeshQueries.FindHitTriangle_LinearSearch(mesh, ray);
                int tNearTree  = tree.FindNearestHitTriangle(ray);

                //System.Console.WriteLine("{0} - {1}", tNearBrute, tree.TRI_TEST_COUNT);

                if (tNearBrute == DMesh3.InvalidID)
                {
                    Debug.Assert(tNearBrute == tNearTree);
                    continue;
                }
                ++hits;

                IntrRay3Triangle3 qBrute = MeshQueries.TriangleIntersection(mesh, tNearBrute, ray);
                IntrRay3Triangle3 qTree  = MeshQueries.TriangleIntersection(mesh, tNearTree, ray);

                double dotBrute = mesh.GetTriNormal(tNearBrute).Dot(ray.Direction);
                double dotTree  = mesh.GetTriNormal(tNearTree).Dot(ray.Direction);

                Debug.Assert(Math.Abs(qBrute.RayParameter - qTree.RayParameter) < MathUtil.ZeroTolerance);
            }
            Debug.Assert(hits == N);
            System.Console.WriteLine("in/out rays: {0} hits out of {1} rays", hits, N);
#endif



            // random rays
            hits = 0;
            for (int ii = 0; ii < N; ++ii)
            {
                if (ii % 100 == 0)
                {
                    System.Console.WriteLine("{0} / {1}", ii, N);
                }

                Vector3d target = c + rand.PointInRange(r);
                Vector3d o      = c + rand.PointInRange(10 * r);
                Ray3d    ray    = new Ray3d(o, (target - o).Normalized);

                int tNearBrute = MeshQueries.FindHitTriangle_LinearSearch(mesh, ray);
                int tNearTree  = tree.FindNearestHitTriangle(ray);

                //System.Console.WriteLine("{0} - {1}", tNearBrute, tree.TRI_TEST_COUNT);

                if (tNearBrute == DMesh3.InvalidID)
                {
                    Debug.Assert(tNearBrute == tNearTree);
                    continue;
                }
                ++hits;

                IntrRay3Triangle3 qBrute = MeshQueries.TriangleIntersection(mesh, tNearBrute, ray);
                IntrRay3Triangle3 qTree  = MeshQueries.TriangleIntersection(mesh, tNearTree, ray);

                double dotBrute = mesh.GetTriNormal(tNearBrute).Dot(ray.Direction);
                double dotTree  = mesh.GetTriNormal(tNearTree).Dot(ray.Direction);

                Debug.Assert(Math.Abs(qBrute.RayParameter - qTree.RayParameter) < MathUtil.ZeroTolerance);
            }

            System.Console.WriteLine("random rays: hit {0} of {1} rays", hits, N);
        }
        public static void test_reduce_constraints_fixedverts()
        {
            int    Slices = 128;
            DMesh3 mesh   = TestUtil.MakeCappedCylinder(false, Slices);

            MeshUtil.ScaleMesh(mesh, Frame3f.Identity, new Vector3f(1, 2, 1));
            mesh.CheckValidity();
            AxisAlignedBox3d bounds = mesh.CachedBounds;

            // construct mesh projection target
            DMesh3 meshCopy = new DMesh3(mesh);

            meshCopy.CheckValidity();
            DMeshAABBTree3 tree = new DMeshAABBTree3(meshCopy);

            tree.Build();
            MeshProjectionTarget target = new MeshProjectionTarget()
            {
                Mesh = meshCopy, Spatial = tree
            };

            if (WriteDebugMeshes)
            {
                TestUtil.WriteTestOutputMesh(mesh, "reduce_fixed_constraints_test_before.obj");
            }

            // construct constraint set
            MeshConstraints cons = new MeshConstraints();

            //EdgeRefineFlags useFlags = EdgeRefineFlags.NoCollapse;
            EdgeRefineFlags useFlags = EdgeRefineFlags.PreserveTopology;

            foreach (int eid in mesh.EdgeIndices())
            {
                double fAngle = MeshUtil.OpeningAngleD(mesh, eid);
                if (fAngle > 30.0f)
                {
                    cons.SetOrUpdateEdgeConstraint(eid, new EdgeConstraint(useFlags)
                    {
                        TrackingSetID = 1
                    });
                    Index2i ev      = mesh.GetEdgeV(eid);
                    int     nSetID0 = (mesh.GetVertex(ev[0]).y > bounds.Center.y) ? 1 : 2;
                    int     nSetID1 = (mesh.GetVertex(ev[1]).y > bounds.Center.y) ? 1 : 2;
                    cons.SetOrUpdateVertexConstraint(ev[0], new VertexConstraint(true, nSetID0));
                    cons.SetOrUpdateVertexConstraint(ev[1], new VertexConstraint(true, nSetID1));
                }
            }

            Reducer r = new Reducer(mesh);

            r.SetExternalConstraints(cons);
            r.SetProjectionTarget(target);

            r.ReduceToTriangleCount(50);
            mesh.CheckValidity();

            if (WriteDebugMeshes)
            {
                TestUtil.WriteTestOutputMesh(mesh, "reduce_fixed_constraints_test_after.obj");
            }
        }