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 Vector3D Project(Vector3D vPoint, int identifier = -1) { int tNearestID = Spatial.FindNearestTriangle(vPoint); DistPoint3Triangle3 q = MeshQueries.TriangleDistance(Mesh, tNearestID, vPoint); return(q.TriangleClosest); }
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 }; }); }
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); } }
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); }
// 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); }
// 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); } } }); }
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); }
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); }
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); }