示例#1
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();
                }
            }
        }
示例#2
0
        public Vector3D Project(Vector3D vPoint, int identifier = -1)
        {
            int tNearestID        = Spatial.FindNearestTriangle(vPoint);
            DistPoint3Triangle3 q = MeshQueries.TriangleDistance(Mesh, tNearestID, vPoint);

            return(q.TriangleClosest);
        }
示例#3
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
                };
            });
        }
示例#4
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);
                }
            }
示例#5
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);
            }
示例#6
0
        // convenience function to construct a DistPoint3Triangle3 object for a mesh triangle
        public static DistPoint3Triangle3 TriangleDistance(NGonsCore.geometry3Sharp.mesh.DMesh3 mesh, int ti, Vector3D point)
        {
            if (!mesh.IsTriangle(ti))
            {
                return(null);
            }
            Triangle3d tri = new Triangle3d();

            mesh.GetTriVertices(ti, ref tri.V0, ref tri.V1, ref tri.V2);
            DistPoint3Triangle3 q = new DistPoint3Triangle3(point, tri);

            q.GetSquared();
            return(q);
        }
示例#7
0
        // for each From[i], find closest point on TargetSurface
        void update_to()
        {
            double max_dist = double.MaxValue;

            bool bNormals = (UseNormals && Source.HasVertexNormals);

            Interval1i range = Interval1i.Range(From.Length);

            gParallel.ForEach(range, (vi) => {
                int tid = TargetSurface.FindNearestTriangle(From[vi], max_dist);
                if (tid == NGonsCore.geometry3Sharp.mesh.DMesh3.InvalidID)
                {
                    Weights[vi] = 0;
                    return;
                }

                DistPoint3Triangle3 d = MeshQueries.TriangleDistance(TargetSurface.Mesh, tid, From[vi]);
                if (d.DistanceSquared > MaxAllowableDistance * MaxAllowableDistance)
                {
                    Weights[vi] = 0;
                    return;
                }

                To[vi]      = d.TriangleClosest;
                Weights[vi] = 1.0f;

                if (bNormals)
                {
                    Vector3F fromN = Rotation * Source.GetVertexNormal(vi);
                    Vector3F toN   = (Vector3F)TargetSurface.Mesh.GetTriNormal(tid);
                    float fDot     = fromN.Dot(toN);
                    Debug.Assert(math.MathUtil.IsFinite(fDot));
                    if (fDot < 0)
                    {
                        Weights[vi] = 0;
                    }
                    else
                    {
                        Weights[vi] += Math.Sqrt(fDot);
                    }
                }
            });
        }
示例#8
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);
        }
示例#9
0
            public Vector3d Project(Vector3d vPoint, int identifier = -1)
            {
                int tNearestID        = Spatial.FindNearestTriangle(vPoint);
                DistPoint3Triangle3 q = MeshQueries.TriangleDistance(Mesh, tNearestID, vPoint);

                double curAmount = 1 - amount;

                if (maxDistance < float.MaxValue && maxDistance > 0)
                {
                    var distance = vPoint.Distance(q.TriangleClosest);

                    if (distance < maxDistance)
                    {
                        double distanceAmount        = distance / maxDistance;
                        double projectDistanceAmount = 1 - distanceAmount;

                        return(((vPoint * curAmount) + (q.TriangleClosest * amount)) * projectDistanceAmount + (vPoint * distanceAmount));
                    }
                }

                return(q.TriangleClosest);
            }
示例#10
0
            internal bool RandomAdjust(g3.DMesh3 mesh, DMeshAABBTree3 tree, Random r, double max, double moveTries, double targetArea)
            {
                bool moved = false;

                if (this.locked)
                {
                    return(false);
                }

                for (int i = 0; i < moveTries; i++)
                {
                    var v0 = mesh.GetVertex(vertex_index.a);
                    var v1 = mesh.GetVertex(vertex_index.b);
                    var v2 = mesh.GetVertex(vertex_index.c);

                    var v0_old = mesh.GetVertex(vertex_index.a);
                    var v1_old = mesh.GetVertex(vertex_index.b);
                    var v2_old = mesh.GetVertex(vertex_index.c);

                    v0.x += (r.NextDouble() * max * 2 - max);
                    v0.y += (r.NextDouble() * max * 2 - max);
                    v0.z += (r.NextDouble() * max * 2 - max);

                    v1.x += (r.NextDouble() * max * 2 - max);
                    v1.y += (r.NextDouble() * max * 2 - max);
                    v1.z += (r.NextDouble() * max * 2 - max);

                    v2.x += (r.NextDouble() * max * 2 - max);
                    v2.y += (r.NextDouble() * max * 2 - max);
                    v2.z += (r.NextDouble() * max * 2 - max);

                    int tNearestID        = tree.FindNearestTriangle(v0);
                    DistPoint3Triangle3 q = MeshQueries.TriangleDistance(tree.Mesh, tNearestID, v0);
                    v0 = q.TriangleClosest;

                    tNearestID = tree.FindNearestTriangle(v1);
                    q          = MeshQueries.TriangleDistance(tree.Mesh, tNearestID, v1);
                    v1         = q.TriangleClosest;

                    tNearestID = tree.FindNearestTriangle(v2);
                    q          = MeshQueries.TriangleDistance(tree.Mesh, tNearestID, v2);
                    v2         = q.TriangleClosest;

                    double oldArea = (HowCloseToTargetArea(mesh, targetArea, 2) / targetArea) * 3;

                    double oldAngleQuality = GetTriangleTotalAnglesQualityHelper(mesh, 2);

                    var n = mesh.GetTriNormal(meshIndex);

                    double oldNormalQuality = GetNormalQuality(mesh, n, 2) * 6;

                    mesh.SetVertex(vertex_index.a, v0);
                    mesh.SetVertex(vertex_index.b, v1);
                    mesh.SetVertex(vertex_index.c, v2);

                    double newArea          = (HowCloseToTargetArea(mesh, targetArea, 2) / targetArea) * 3;
                    double newAngleQuality  = GetTriangleTotalAnglesQualityHelper(mesh, 2);
                    double newNormalQuality = GetNormalQuality(mesh, n, 2) * 6;

                    if ((oldArea + oldAngleQuality + oldNormalQuality) < (newArea + newAngleQuality + newNormalQuality))
                    {
                        mesh.SetVertex(vertex_index.a, v0_old);
                        mesh.SetVertex(vertex_index.b, v1_old);
                        mesh.SetVertex(vertex_index.c, v2_old);
                    }
                    else
                    {
                        moved = true;
                    }
                }

                return(moved);
            }