コード例 #1
0
ファイル: Ground.cs プロジェクト: macmillaninc/melia
        /// <summary>
        /// Returns the height of the ground at the given 2D position via
        /// out. Returns false if there is no ground at the position.
        /// </summary>
        /// <remarks>
        /// Only X and Z are used by this function.
        /// </remarks>
        /// <param name="pos"></param>
        /// <returns></returns>
        public bool TryGetHeightAt(Position pos, out float height)
        {
            if (_spatial == null)
            {
                height = -1;
                return(false);
            }

            var origin = new Vector3f(pos.X, 1000, pos.Z);
            var ray    = new Ray3f(origin, new Vector3f(0, -1, 0));

            var hitId = _spatial.FindNearestHitTriangle(ray);

            if (hitId == DMesh3.InvalidID)
            {
                height = float.NaN;
                return(false);
            }

            var intersection = MeshQueries.TriangleIntersection(_mesh, hitId, ray);
            var hitDistance  = origin.Distance(ray.PointAt((float)intersection.RayParameter));

            height = (1000 - hitDistance);
            return(true);
        }
コード例 #2
0
        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");
            }
        }
コード例 #3
0
        public void Initialize_AutoFitBox()
        {
            DMeshSO TargetMeshSO = TargetSO as DMeshSO;

            // initialize w/ auto-fit box
            DMesh3         mesh    = TargetMeshSO.Mesh;
            DMeshAABBTree3 spatial = TargetMeshSO.Spatial;

            meshBounds = mesh.CachedBounds;

            create_preview_so();

            ContOrientedBox3 boxFitter = new ContOrientedBox3(
                new RemapItr <Vector3d, int>(mesh.TriangleIndices(), (tid) => { return(mesh.GetTriCentroid(tid)); }),
                new RemapItr <double, int>(mesh.TriangleIndices(), (tid) => { return(mesh.GetTriArea(tid)); }));
            //DebugUtil.EmitDebugBox("fitbox", boxFitter.Box, Colorf.Red, TargetSO.RootGameObject, false);
            Box3d fitBox  = boxFitter.Box;
            int   longest = 0;

            if (fitBox.Extent.y > fitBox.Extent.x)
            {
                longest = 1;
            }
            if (fitBox.Extent.z > fitBox.Extent[longest])
            {
                longest = 2;
            }
            Vector3d vTop    = fitBox.Center + fitBox.Extent[longest] * fitBox.Axis(longest);
            Vector3d vBottom = fitBox.Center - fitBox.Extent[longest] * fitBox.Axis(longest);

            int base_tid = spatial.FindNearestTriangle(vBottom);
            int top_tid  = spatial.FindNearestTriangle(vTop);

            if (vTop.y < vBottom.y)
            {
                int tmp = base_tid; base_tid = top_tid; top_tid = tmp;
            }
            Vector3d vBasePt = mesh.GetTriCentroid(base_tid);
            Vector3d vTopPt  = mesh.GetTriCentroid(top_tid);


            int      other1 = (longest + 1) % 3, other2 = (longest + 2) % 3;
            int      front_tid = spatial.FindNearestHitTriangle(new Ray3d(fitBox.Center, fitBox.Axis(other1)));
            Vector3d vFrontPt  = mesh.GetTriCentroid(front_tid);

            int      back_tid = spatial.FindNearestHitTriangle(new Ray3d(fitBox.Center, -fitBox.Axis(other1)));
            Vector3d vBackPt  = mesh.GetTriCentroid(back_tid);

            int      right_tid = spatial.FindNearestHitTriangle(new Ray3d(fitBox.Center, fitBox.Axis(other2)));
            Vector3d vRightPt  = mesh.GetTriCentroid(right_tid);

            int      left_tid = spatial.FindNearestHitTriangle(new Ray3d(fitBox.Center, -fitBox.Axis(other2)));
            Vector3d vLeftPt  = mesh.GetTriCentroid(left_tid);

            initialFrontPt = (Vector3f)vFrontPt;

            SetPointPosition_Internal(BasePointID, MeshQueries.SurfaceFrame(mesh, base_tid, vBasePt), CoordSpace.ObjectCoords);
            SetPointPosition_Internal(FrontPointID, MeshQueries.SurfaceFrame(mesh, front_tid, vFrontPt), CoordSpace.ObjectCoords);
            SetPointPosition(TopPointID, MeshQueries.SurfaceFrame(mesh, top_tid, vTopPt), CoordSpace.ObjectCoords);
        }
コード例 #4
0
ファイル: MeshEditorTool.cs プロジェクト: tomleetv/gsTools
        public bool FindHitTriangle(Ray3f sceneRay, bool snap_to_center, ref Frame3f hitFrameS, ref int hitTID)
        {
            Ray3f objRay = SceneTransforms.SceneToObject(Target, sceneRay);

            hitTID = PreviewSpatial.FindNearestHitTriangle(objRay);
            if (hitTID == DMesh3.InvalidID)
            {
                return(false);
            }
            if (allow_backface_hits == false && is_back_facing(hitTID))
            {
                return(false);
            }

            var intr = MeshQueries.TriangleIntersection(PreviewMesh, hitTID, objRay);

            if (snap_to_center)
            {
                Frame3f hitFrameL = new Frame3f(PreviewMesh.GetTriCentroid(hitTID), PreviewMesh.GetTriNormal(hitTID));
                hitFrameS = SceneTransforms.ObjectToScene(previewSO, hitFrameL);
            }
            else
            {
                Vector3f hitPoint  = objRay.PointAt((float)intr.RayParameter);
                Frame3f  hitFrameL = new Frame3f(hitPoint, PreviewMesh.GetTriNormal(hitTID));
                hitFrameS = SceneTransforms.ObjectToScene(previewSO, hitFrameL);
            }

            return(true);
        }
コード例 #5
0
        public static void test_planar_fill()
        {
            //DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_solid.obj");
            //DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_hollow.obj");
            DMesh3 mesh = TestUtil.LoadTestInputMesh("local\\__LAST_FAILED_CUT_MESH.obj");
            double mine, maxe, avge;

            MeshQueries.EdgeLengthStats(mesh, out mine, out maxe, out avge);

            AxisAlignedBox3d bounds    = mesh.CachedBounds;
            Vector3d         origin    = bounds.Center;
            Vector3d         axis      = Vector3d.AxisY;
            double           targetLen = avge;

            origin    = new Vector3d(-7.53203300, -39.50826000, -4.22260500);
            axis      = new Vector3d(0.00000007, 0.00000007, -0.99999960);
            targetLen = 3.0;

            MeshPlaneCut cut = new MeshPlaneCut(mesh, origin, axis);

            cut.Cut();

            PlanarHoleFiller fill = new PlanarHoleFiller(cut)
            {
                FillTargetEdgeLen = targetLen
            };

            if (fill.Fill() == false)
            {
                System.Console.WriteLine("test_meshEdits.test_planar_fill: Fill() failed!");
            }

            TestUtil.WriteTestOutputMesh(mesh, "planar_filled.obj");
        }
コード例 #6
0
        public Vector3D Project(Vector3D vPoint, int identifier = -1)
        {
            int tNearestID        = Spatial.FindNearestTriangle(vPoint);
            DistPoint3Triangle3 q = MeshQueries.TriangleDistance(Mesh, tNearestID, vPoint);

            return(q.TriangleClosest);
        }
コード例 #7
0
    InteractiveRemesher make_remesher(DMesh3 mesh)
    {
        var m = new InteractiveRemesher(mesh);

        m.PreventNormalFlips = true;

        double mine, maxe, avge;

        MeshQueries.EdgeLengthStats(mesh, out mine, out avge, out maxe);
        m.SetTargetEdgeLength(avge * EdgeLengthMultiplier);

        m.SmoothSpeedT = SmoothSpeed;

        if (Reproject)
        {
            m.SetProjectionTarget(MeshProjectionTarget.Auto(mesh));
        }

        if (RemeshBoundary)
        {
            MeshBoundaryLoops loops = new MeshBoundaryLoops(mesh);
            int k = 1;
            foreach (var loop in loops)
            {
                MeshConstraintUtil.ConstrainVtxLoopTo(m, loop.Vertices, new DCurveProjectionTarget(loop.ToCurve()), k++);
            }
        }
        else if (PreserveBoundary)
        {
            MeshConstraintUtil.FixAllBoundaryEdges(m);
        }

        return(m);
    }
コード例 #8
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);
        }
コード例 #9
0
ファイル: FillHolesTool.cs プロジェクト: tomleetv/gsTools
        public AddTrianglesMeshChange fill_smooth(DMesh3 mesh, EdgeLoop loop)
        {
            AddTrianglesMeshChange addChange = null;
            SmoothedHoleFill       filler    = new SmoothedHoleFill(mesh, loop);

            filler.ConstrainToHoleInterior = true;
            if (this.AutoTargetEdgeLength)
            {
                double mine, maxe, avge;
                MeshQueries.EdgeLengthStatsFromEdges(mesh, loop.Edges, out mine, out maxe, out avge);
                filler.TargetEdgeLength = avge;
            }
            else
            {
                filler.TargetEdgeLength = this.TargetEdgeLength;
            }
            filler.SmoothSolveIterations = this.SmoothOptimizeRounds;

            bool fill_ok = filler.Apply();

            if (fill_ok)
            {
                addChange = new AddTrianglesMeshChange();
                addChange.InitializeFromExisting(mesh,
                                                 filler.FillVertices, filler.FillTriangles);
            }
            return(addChange);
        }
コード例 #10
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);
        }
コード例 #11
0
        public int FindNearestHitTriangle(Ray3d ray, double fMaxDist = double.MaxValue)
        {
            var save_filter = SourceSpatial.TriangleFilterF;

            SourceSpatial.TriangleFilterF = source_filter;
            int hit_source_tid = SourceSpatial.FindNearestHitTriangle(ray);

            SourceSpatial.TriangleFilterF = save_filter;

            int hit_edit_tid;
            IntrRay3Triangle3 edit_hit = find_added_hit(ref ray, out hit_edit_tid);

            if (hit_source_tid == DMesh3.InvalidID && hit_edit_tid == DMesh3.InvalidID)
            {
                return(DMesh3.InvalidID);
            }
            else if (hit_source_tid == DMesh3.InvalidID)
            {
                return(hit_edit_tid);
            }
            else if (hit_edit_tid == DMesh3.InvalidID)
            {
                return(hit_source_tid);
            }

            IntrRay3Triangle3 source_hit = (hit_source_tid != -1) ?
                                           MeshQueries.TriangleIntersection(SourceMesh, hit_source_tid, ray) : null;

            return((edit_hit.RayParameter < source_hit.RayParameter) ?
                   hit_edit_tid : hit_source_tid);
        }
コード例 #12
0
        public void Precompute_SingleVectorBarycentric()
        {
            int N = DisplaceMesh.MaxTriangleID;

            BaryFaceDisplacements = new BaryDisplace[N];

            //foreach ( int vid in DisplaceMesh.VertexIndices() ) {
            gParallel.ForEach <int>(DisplaceMesh.VertexIndices(), (vid) => {
                Vector3d pos             = DisplaceMesh.GetVertex(vid);
                int tid                  = BaseSpatial.FindNearestTriangle(pos);
                DistPoint3Triangle3 dist = MeshQueries.TriangleDistance(BaseMesh, tid, pos);
                Vector3f dv              = (Vector3f)(pos - dist.TriangleClosest);
                Frame3f triFrame         = BaseMesh.GetTriFrame(tid);
                Vector3f relVec          = triFrame.ToFrameV(dv);


                BaryFaceDisplacements[vid] = new BaryDisplace()
                {
                    tID = tid,
                    a   = (float)dist.TriangleBaryCoords.x,
                    b   = (float)dist.TriangleBaryCoords.y,
                    c   = (float)dist.TriangleBaryCoords.z,
                    dv  = relVec
                };
            });
        }
コード例 #13
0
            public Vector3d Project(Vector3d vSourcePt, int identifier = -1)
            {
                Vector3d vTargetPt = SourceToTargetXForm.TransformP(vSourcePt);

                int tNearestID                  = TargetSpatial.FindNearestTriangle(vTargetPt);
                DistPoint3Triangle3 q           = MeshQueries.TriangleDistance(Target, tNearestID, vTargetPt);
                double   d                      = q.DistanceSquared;
                Vector3d vTargetNearestInSource = TargetToSourceXForm.TransformP(q.TriangleClosest);

                if (MaxDistance == double.MaxValue)
                {
                    return(vTargetNearestInSource);
                }

                if (TargetSpatial.IsInside(vTargetPt))
                {
                    return(vTargetNearestInSource);
                }

                tNearestID = SourceSpatial.FindNearestTriangle(vSourcePt);
                DistPoint3Triangle3 qSource = MeshQueries.TriangleDistance(Source, tNearestID, vSourcePt);

                d = Math.Sqrt(d);
                if (d < MaxDistance)
                {
                    double min = (1.0 - Smoothness) * MaxDistance;
                    double t   = MathUtil.WyvillFalloff(d, min, MaxDistance);
                    t = 1.0 - t;
                    return(Vector3d.Lerp(vTargetNearestInSource, qSource.TriangleClosest, t));
                }
                else
                {
                    return(qSource.TriangleClosest);
                }
            }
コード例 #14
0
        public Vector3d GetHitLocationFromRay(Ray3d ray)
        {
            Vector3d vout = new Vector3d(0, 0, 0);

            int currHitTri = -1;
            IntrRay3Triangle3 hitInfo;
            int x = 0, y = 0;

            foreach (TerrainChunk t in terrainChunks)
            {
                currHitTri = t.dMeshAABB.FindNearestHitTriangle(ray);
                if (currHitTri != -1)
                {
                    x = t.arrayX;
                    y = t.arrayY;
                    break;
                }
            }

            if (currHitTri != -1)
            {
                hitInfo = MeshQueries.TriangleIntersection(terrainChunks[x, y].dMesh, currHitTri, ray);
                vout    = hitInfo.Ray.PointAt(hitInfo.RayParameter);
            }

            return(vout);
        }
コード例 #15
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();
                }
            }
        }
コード例 #16
0
    internal void MoveAllPointsDepthDependant(CuttingInfo info, DMesh3 newMesh, Dictionary <int, BacksideAlgorithm.PeprStatusVert> stati)
    {
        var tree = new DMeshAABBTree3(info.oldMesh, true);

        tree.TriangleFilterF = i => tree.Mesh.GetTriangleGroup(i) != info.data.ColorNum;
        foreach (var status in stati)
        {
            var   shellPoint = newMesh.GetVertex(status.Value.idNewMeshOuter.Value);
            var   normal     = info.oldMesh.CalcVertexNormal(status.Value.idOldMeshOuter);
            var   position   = shellPoint + info.data.minDepth * normal;
            Ray3d ray        = new Ray3d(shellPoint - normal * info.data.minDepth, -normal); //tiny shift to make sure it's not hitting itself
            int   hit_tid    = tree.FindNearestHitTriangle(ray);
            Debug.Log("Hit " + hit_tid);
            if (hit_tid != DMesh3.InvalidID)
            {
                IntrRay3Triangle3 intr     = MeshQueries.TriangleIntersection(info.oldMesh, hit_tid, ray);
                double            hit_dist = shellPoint.Distance(ray.PointAt(intr.RayParameter));
                position = shellPoint - normal * hit_dist * (info.data.depth / 100);
                Debug.Log($"Hit Dist: {hit_dist}");
            }
            else
            {
                StaticFunctions.ErrorMessage("Depth Dependant Calculation has encountered an error");
            }
            info.mesh.SetVertex(status.Value.idOldMeshInner.Value, position);
            newMesh.SetVertex(status.Value.idNewMeshInner.Value, position);
        }
    }
コード例 #17
0
        public static void test_auto_fill()
        {
            DMesh3 mesh = TestUtil.LoadTestInputMesh("autofill_cases.obj");
            //DMesh3 mesh = TestUtil.LoadTestInputMesh("autofill_tempcase1.obj");
            //DMesh3 mesh = TestUtil.LoadTestInputMesh("autofill_planarcase.obj");
            //DMesh3 mesh = TestUtil.LoadTestInputMesh("autofill_box_edge_strip.obj");
            //DMesh3 mesh = TestUtil.LoadTestInputMesh("autofill_box_edge_strip_2.obj");
            //DMesh3 mesh = TestUtil.LoadTestInputMesh("crazyhole.obj");

            double mine, maxe, avge;

            MeshQueries.EdgeLengthStats(mesh, out mine, out maxe, out avge);

            int ROUNDS = 1;

            for (int k = 0; k < ROUNDS; ++k)
            {
                MeshBoundaryLoops loops = new MeshBoundaryLoops(mesh);
                foreach (EdgeLoop loop in loops)
                {
                    AutoHoleFill fill = new AutoHoleFill(mesh, loop);
                    fill.TargetEdgeLength = avge;
                    fill.Apply();
                }
                if (k == ROUNDS - 1)
                {
                    continue;
                }

                RemesherPro r = new RemesherPro(mesh);
                r.SetTargetEdgeLength(avge);
                for (int j = 0; j < 10; ++j)
                {
                    r.FastSplitIteration();
                }

                MergeCoincidentEdges merge = new MergeCoincidentEdges(mesh);
                merge.Apply();
            }

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

            //DMesh3 mesh = new DMesh3();
            //SphericalFibonacciPointSet ps = new SphericalFibonacciPointSet();
            //for (int k = 0; k < ps.N; ++k) {
            //    MeshEditor.AppendBox(mesh, ps[k], ps[k], 0.05f);
            //}
            //Random r = new Random(31337);
            //Vector3d[] pts = TestUtil.RandomPoints3(10000, r, Vector3d.Zero);
            //foreach ( Vector3d pt in pts ) {
            //    pt.Normalize();
            //    int nearest = ps.NearestPoint(pt, true);
            //    Vector3d p = ps[nearest];
            //    MeshEditor.AppendLine(mesh, new Segment3d(p, p + 0.25f * pt), 0.01f);
            //}
            //TestUtil.WriteTestOutputMesh(mesh, "fibonacci.obj");
        }
コード例 #18
0
ファイル: MeshEditorTool.cs プロジェクト: tomleetv/gsTools
        public bool FindHitEdge(Ray3f sceneRay, MeshEditorOpType.BoundaryType boundaryMode, bool snap_to_center, ref Frame3f hitFrameS, ref int hitEID)
        {
            Ray3f objRay = SceneTransforms.SceneToObject(Target, sceneRay);

            int hit_tri = PreviewSpatial.FindNearestHitTriangle(objRay);

            if (hit_tri == DMesh3.InvalidID)
            {
                return(false);
            }
            if (allow_backface_hits == false && is_back_facing(hit_tri))
            {
                return(false);
            }

            var intr = MeshQueries.TriangleIntersection(PreviewMesh, hit_tri, objRay);
            int e_idx = -1; double near_sqr = double.MaxValue; DistRay3Segment3 near_dist = null;

            for (int j = 0; j < 3; ++j)
            {
                Segment3d        seg  = new Segment3d(intr.Triangle[j], intr.Triangle[(j + 1) % 3]);
                DistRay3Segment3 dist = new DistRay3Segment3(objRay, seg);
                if (dist.GetSquared() < near_sqr)
                {
                    near_sqr  = dist.GetSquared();
                    near_dist = dist;
                    e_idx     = j;
                }
            }
            int eid = PreviewMesh.GetTriEdge(hit_tri, e_idx);

            if (boundaryMode != MeshEditorOpType.BoundaryType.Any)
            {
                bool is_boundary = PreviewMesh.IsBoundaryEdge(eid);
                if ((is_boundary && boundaryMode == MeshEditorOpType.BoundaryType.OnlyInternal) ||
                    (is_boundary == false && boundaryMode == MeshEditorOpType.BoundaryType.OnlyBoundary))
                {
                    return(false);
                }
            }

            if (snap_to_center)
            {
                Frame3f hitFrameL = new Frame3f(PreviewMesh.GetEdgePoint(eid, 0.5), PreviewMesh.GetTriNormal(hit_tri));
                hitFrameS = SceneTransforms.ObjectToScene(previewSO, hitFrameL);
            }
            else
            {
                Frame3f hitFrameL = new Frame3f(near_dist.SegmentClosest, PreviewMesh.GetTriNormal(hit_tri));
                hitFrameS = SceneTransforms.ObjectToScene(previewSO, hitFrameL);
            }

            hitEID = eid;
            return(true);
        }
コード例 #19
0
 public Vector3d Project(Vector3d vPoint, int identifier)
 {
     if (Spatial.IsInside(vPoint))
     {
         return(MeshQueries.NearestPointFrame(Spatial.Mesh, Spatial, vPoint).Origin);
     }
     else
     {
         return(vPoint);
     }
 }
コード例 #20
0
            public Vector3D FindNearestAndOffset(Vector3D pos)
            {
                int tNearestID                 = Spatial.FindNearestTriangle(pos);
                DistPoint3Triangle3 q          = MeshQueries.TriangleDistance(Mesh, tNearestID, pos);
                Vector3D            vHitNormal =
                    (UseFaceNormal == false && Mesh.HasVertexNormals) ?
                    Mesh.GetTriBaryNormal(tNearestID, q.TriangleBaryCoords.x, q.TriangleBaryCoords.y, q.TriangleBaryCoords.z)
                        : Mesh.GetTriNormal(tNearestID);

                return(q.TriangleClosest + Distance * vHitNormal);
            }
コード例 #21
0
        public static double?DistanceToTree(this DMeshAABBTree3 tree, Ray3d ray)
        {
            var hit_tid = tree.FindNearestHitTriangle(ray);

            if (hit_tid == DMesh3.InvalidID)
            {
                return(null);
            }
            var intr = MeshQueries.TriangleIntersection(tree.Mesh, hit_tid, ray);

            return(ray.Origin.Distance(ray.PointAt(intr.RayParameter)));
        }
コード例 #22
0
        public static void test_AABBTree_TriTriDist()
        {
            System.Console.WriteLine("test_AABBTree_TriTriDist()");

            Sphere3Generator_NormalizedCube gen = new Sphere3Generator_NormalizedCube()
            {
                Radius = 1, EdgeVertices = 6
            };
            DMesh3  sphereMesh = gen.Generate().MakeDMesh();
            Reducer reducer    = new Reducer(sphereMesh); reducer.ReduceToTriangleCount(77);


            Random r = new Random(31337);

            for (int iter = 0; iter < 1000; ++iter)
            {
                DMesh3     sphere1 = new DMesh3(sphereMesh), sphere2 = new DMesh3(sphereMesh);
                Vector3d[] pts = TestUtil.RandomPoints3(3, r, Vector3d.Zero, 100);
                Vector3d   p1 = pts[0], p2 = pts[1];
                double     r1 = 5, r2 = 10;
                MeshTransforms.Scale(sphere1, r1);
                MeshTransforms.Translate(sphere1, p1);
                MeshTransforms.Scale(sphere2, r2);
                MeshTransforms.Translate(sphere2, p2);

                DMeshAABBTree3 tree1 = new DMeshAABBTree3(sphere1, true);
                DMeshAABBTree3 tree2 = new DMeshAABBTree3(sphere2, true);

                double sphere_dist = p1.Distance(p2) - (r1 + r2);

                double  distBrute             = double.MaxValue;
                Index2i nearestBrute          = MeshQueries.FindNearestTriangles_LinearSearch(sphere1, sphere2, out distBrute);
                DistTriangle3Triangle3 qBrute = MeshQueries.TrianglesDistance(sphere1, nearestBrute.a, sphere2, nearestBrute.b);

                double  distTree             = double.MaxValue;
                Index2i nearestTree          = tree1.FindNearestTriangles(tree2, null, out distTree);
                DistTriangle3Triangle3 qTree = MeshQueries.TrianglesDistance(sphere1, nearestTree.a, sphere2, nearestTree.b);

                double  distTree2    = double.MaxValue;
                Index2i nearestTree2 = tree2.FindNearestTriangles(tree1, null, out distTree2);

                // pairs are unstable if we are on an edge
                if (qBrute.Triangle0BaryCoords.x < 0.99 && qBrute.Triangle0BaryCoords.y < 0.99 && qBrute.Triangle0BaryCoords.z < 0.99 &&
                    qBrute.Triangle1BaryCoords.x < 0.99 && qBrute.Triangle1BaryCoords.y < 0.99 && qBrute.Triangle1BaryCoords.z < 0.99)
                {
                    Util.gDevAssert(nearestBrute.a == nearestTree.a && nearestBrute.b == nearestTree.b);
                    Util.gDevAssert(nearestBrute.b == nearestTree2.a && nearestBrute.a == nearestTree.b);
                }

                Util.gDevAssert(Math.Abs(distBrute - distTree) < MathUtil.Epsilonf &&
                                Math.Abs(distBrute - distTree2) < MathUtil.Epsilonf);
            }
        }
コード例 #23
0
        public static void test_AABBTree_TriTriIntr()
        {
            System.Console.WriteLine("test_AABBTree_TriTriIntr()");

            Sphere3Generator_NormalizedCube gen = new Sphere3Generator_NormalizedCube()
            {
                Radius = 1, EdgeVertices = 25
            };
            DMesh3  sphereMesh = gen.Generate().MakeDMesh();
            Reducer reducer    = new Reducer(sphereMesh); reducer.ReduceToTriangleCount(77);

            int    hit_count = 0;
            Random r         = new Random(31337);

            for (int iter = 0; iter < 5000; ++iter)
            {
                DMesh3     sphere1 = new DMesh3(sphereMesh), sphere2 = new DMesh3(sphereMesh);
                Vector3d[] pts = TestUtil.RandomPoints3(3, r, Vector3d.Zero, 10);   // at 10, about half of the spheres intersect
                Vector3d   p1 = pts[0], p2 = pts[1];
                double     r1 = 5, r2 = 10;
                double     eps = (r1 + r2) * 0.5 * 0.001;
                MeshTransforms.Scale(sphere1, r1);
                MeshTransforms.Translate(sphere1, p1);
                MeshTransforms.Scale(sphere2, r2);
                MeshTransforms.Translate(sphere2, p2);

                DMeshAABBTree3 tree1 = new DMeshAABBTree3(sphere1, true);
                DMeshAABBTree3 tree2 = new DMeshAABBTree3(sphere2, true);

                bool spheres_intersect = p1.Distance(p2) < (r1 + r2 + 2 * eps);
                if (spheres_intersect && p1.Distance(p2) + Math.Min(r1, r2) < Math.Max(r1, r2) * 0.9)
                {
                    spheres_intersect = false;
                }

                Index2i hitBrute  = MeshQueries.FindIntersectingTriangles_LinearSearch(sphere1, sphere2);
                bool    bHitBrute = hitBrute != Index2i.Max;
                if (bHitBrute)
                {
                    hit_count++;
                }

                // [RMS] not reliable because of tesselation
                //Util.gDevAssert(bHitBrute == spheres_intersect);

                bool bHitTree1 = tree1.TestIntersection(tree2);
                bool bHitTree2 = tree2.TestIntersection(tree1);

                Util.gDevAssert(bHitBrute == bHitTree1 && bHitTree1 == bHitTree2);
            }

            System.Console.WriteLine(hit_count.ToString());
        }
コード例 #24
0
        public virtual void Update()
        {
            base.begin_update();
            int start_timestamp = this.CurrentInputTimestamp;

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

            try {
                ResultMesh = null;

                DMesh3 meshIn = MeshSource.GetDMeshUnsafe();
                input_spatial = MeshSource.GetSpatial() as DMeshAABBTree3;
                if (meshIn.ShapeTimestamp != input_mesh_cache_timestamp)
                {
                    cached_is_closed = meshIn.IsClosed();
                    MeshQueries.EdgeLengthStats(meshIn, out input_mesh_edge_stats.x, out input_mesh_edge_stats.y, out input_mesh_edge_stats.z);
                    if (input_spatial == null)
                    {
                        input_spatial = new DMeshAABBTree3(meshIn, false);
                    }
                    input_mesh_cache_timestamp = meshIn.ShapeTimestamp;
                }

                if (closing_type == ClosingTypes.LevelSet)
                {
                    update_level_set();
                }
                else if (closing_type == ClosingTypes.WindingNumberGrid)
                {
                    if (cached_is_closed)
                    {
                        update_winding();
                    }
                    else
                    {
                        update_winding_fast();
                    }
                }
                else
                {
                    update_winding_exact();
                }

                base.complete_update();
            } catch (Exception e) {
                PostOnOperatorException(e);
                ResultMesh = base.make_failure_output(MeshSource.GetDMeshUnsafe());
                base.complete_update();
            }
        }
コード例 #25
0
        public virtual void Setup()
        {
            // turn on xform gizmo
            Scene.Context.TransformManager.PushOverrideGizmoType(BendPlanePivotGizmo.DefaultTypeName);


            Vector3d ctrPt    = TargetSO.Mesh.CachedBounds.Center;
            Frame3f  nearestF = MeshQueries.NearestPointFrame(TargetSO.Mesh, TargetSO.Spatial, ctrPt, true);

            BendPlaneOriginS = SceneTransforms.ObjectToSceneP(TargetSO, nearestF.Origin);
            BendPlaneNormalS = Vector3d.AxisY;

            bendPlaneGizmoSO = new BendPlanePivotSO();
            bendPlaneGizmoSO.Create(Scene.PivotSOMaterial, Scene.FrameSOMaterial);
            bendPlaneGizmoSO.OnTransformModified += OnBendPlaneTransformModified;
            Scene.AddSceneObject(bendPlaneGizmoSO);

            Frame3f cutFrameS = new Frame3f(BendPlaneOriginS); cutFrameS.AlignAxis(1, (Vector3f)BendPlaneNormalS);

            bendPlaneGizmoSO.SetLocalFrame(cutFrameS, CoordSpace.SceneCoords);

            allow_selection_changes = true;
            Scene.Select(bendPlaneGizmoSO, true);
            allow_selection_changes = false;


            StandardIndicatorFactory factory   = new StandardIndicatorFactory();
            SectionPlaneIndicator    bendPlane = factory.MakeSectionPlaneIndicator(
                100, "bendPlane",
                fDimension.Scene(100),
                () => { return(new Frame3f(BendPlaneOriginS, BendPlaneNormalS)); },
                () => { return(new Colorf(Colorf.LightGreen, 0.5f)); },
                () => { return(true); }
                );

            Indicators.AddIndicator(bendPlane);

            // save initial vtx positions
            VertexPositions = new Vector3d[TargetSO.Mesh.MaxVertexID];
            foreach (int vid in TargetSO.Mesh.VertexIndices())
            {
                VertexPositions[vid] = TargetSO.Mesh.GetVertex(vid);
            }

            PreviewSO = TargetSO.Duplicate() as DMeshSO;
            Scene.AddSceneObject(PreviewSO);
            //PreviewSO.AssignSOMaterial(Scene.TransparentNewSOMaterial);

            fMaterial transMat = MaterialUtil.CreateTransparentMaterial(Colorf.BlueMetal.SetAlpha(0.1f));

            TargetSO.PushOverrideMaterial(transMat);
            TargetSO.SetLayer(FPlatform.WidgetOverlayLayer);
        }
コード例 #26
0
        public static Vector3d NearestPoint(this DMeshAABBTree3 tree, Vector3d point)
        {
            var tid = tree.FindNearestTriangle(point);

            if (tid == DMesh3.InvalidID)
            {
                return(new Vector3d());
            }

            var dist = MeshQueries.TriangleDistance(tree.Mesh, tid, point);

            return(dist.TriangleClosest);
        }
コード例 #27
0
ファイル: AddHoleTool.cs プロジェクト: tomleetv/gsTools
        protected override void OnPointUpdated(ControlPoint pt, Frame3f prevFrameS, bool isFirst)
        {
            DMesh3         mesh    = InputMeshSO.Mesh;
            DMeshAABBTree3 spatial = InputMeshSO.Spatial;

            Vector3f ptO    = SceneTransforms.SceneToObjectP(InputMeshSO, pt.currentFrameS.Origin);
            Frame3f  frameO = MeshQueries.NearestPointFrame(mesh, spatial, ptO, true);

            Vector3d dir = -frameO.Z;

            if (hole_direction != HoleDirections.Normal)
            {
                Vector3f axis = Vector3f.AxisX;
                if (hole_direction == HoleDirections.AxisY)
                {
                    axis = Vector3f.AxisY;
                }
                else if (hole_direction == HoleDirections.AxisZ)
                {
                    axis = Vector3f.AxisZ;
                }
                axis = SceneTransforms.SceneToObjectN(InputMeshSO, axis);
                dir  = (dir.Dot(axis) < 0) ? -axis : axis;
            }
            //dir.Normalize();

            LastUpdateRay = new Ray3d(frameO.Origin, dir);

            List <int> hitTris  = new List <int>();
            int        hit_tris = spatial.FindAllHitTriangles(LastUpdateRay, hitTris);
            double     max_t    = 0;

            foreach (int tid in hitTris)
            {
                Vector3d n = mesh.GetTriNormal(tid);
                if (n.Dot(LastUpdateRay.Direction) < 0)
                {
                    continue;
                }
                IntrRay3Triangle3 rayhit = MeshQueries.TriangleIntersection(InputMeshSO.Mesh, tid, LastUpdateRay);
                max_t = rayhit.RayParameter;
                break;
            }
            if (max_t <= 0)
            {
                return;
            }

            LastThroughDepth = max_t;
            update_current_hole_type();
        }
コード例 #28
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            DMesh3_goo goo = null;

            DA.GetData(0, ref goo);

            DMesh3 mesh = new DMesh3(goo.Value);

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

            DA.SetData(0, max);
            DA.SetData(1, min);
            DA.SetData(2, avg);
        }
コード例 #29
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");
        }
コード例 #30
0
    void remove_old_vertices(int[] MapV, DMesh3 mesh)
    {
        HashSet <int> keepV = new HashSet <int>();

        for (int k = 0; k < MapV.Length; ++k)
        {
            if (MapV[k] != DMesh3.InvalidID)
            {
                keepV.Add(MapV[k]);
            }
        }

        Remesher r = new Remesher(mesh);

        //r.EnableCollapses = false;
        //r.EnableSplits = false;
        //r.EnableFlips = false;
        r.SmoothSpeedT = 1.0;
        //r.EnableSmoothing = false;
        r.PreventNormalFlips = true;
        r.SetTargetEdgeLength(1.0);
        //r.EnableSmoothing = false;
        MeshConstraints c = new MeshConstraints();

        foreach (int vid in keepV)
        {
            c.SetOrUpdateVertexConstraint(vid, VertexConstraint.Pinned);
        }
        r.SetExternalConstraints(c);

        double minE, maxE, avgE;

        MeshQueries.EdgeLengthStats(mesh, out minE, out maxE, out avgE);
        r.SetTargetEdgeLength(avgE * .3);

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

        //int iter = 0;
        //while (iter++ < 10) {
        //    r.SetTargetEdgeLength(iter * 1.0);
        //    for (int k = 0; k < 10; ++k)
        //        r.BasicRemeshPass();
        //}
    }