public float GetValue(Vector3i idx) { float f = grid[idx]; if (f == UpperBoundDistance || f == -UpperBoundDistance) { Vector3d p = cell_center(idx); float sign = Math.Sign(f); double dsqr; int near_tid = Spatial.FindNearestTriangle(p, out dsqr, MaxDistQueryDist); //int near_tid = Spatial.FindNearestTriangle(p, out dsqr); if (near_tid == DMesh3.InvalidID) { f += 0.0001f; } else { f = sign * (float)Math.Sqrt(dsqr); } grid[idx] = f; if (closest_tri_grid != null) { closest_tri_grid[idx] = near_tid; } } return(f); }
// for each From[i], find closest point on TargetSurface void update_to() { double max_dist = double.MaxValue; bool bNormals = (UseNormals && Source.HasVertexNormals); var range = Interval1i.Range(From.Length); gParallel.ForEach(range, (vi) => { int tid = TargetSurface.FindNearestTriangle(From[vi], max_dist); if (tid == 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) { Vector3d fromN = Rotation * Source.GetVertexNormal(vi); Vector3d toN = TargetSurface.Mesh.GetTriNormal(tid); double fDot = fromN.Dot(toN); Debug.Assert(MathUtil.IsFinite(fDot)); if (fDot < 0) { Weights[vi] = 0; } else { Weights[vi] += Math.Sqrt(fDot); } } }); }
public virtual bool Trim() { if (Spatial == null) { Spatial = new DMeshAABBTree3(new DMesh3(Mesh, false, MeshComponents.None)); Spatial.Build(); } if (seed_tri == -1) { seed_tri = Spatial.FindNearestTriangle(seed_pt); } var loop = new MeshFacesFromLoop(Mesh, TrimLine, Spatial, seed_tri); MeshFaceSelection selection = loop.ToSelection(); selection.LocalOptimize(true, true); var editor = new MeshEditor(Mesh); editor.RemoveTriangles(selection, true); var components = new MeshConnectedComponents(Mesh); components.FindConnectedT(); if (components.Count > 1) { int keep = components.LargestByCount; for (int i = 0; i < components.Count; ++i) { if (i != keep) { editor.RemoveTriangles(components[i].Indices, true); } } } editor.RemoveAllBowtieVertices(true); var loops = new MeshBoundaryLoops(Mesh); bool loopsOK = false; try { loopsOK = loops.Compute(); } catch (Exception) { return(false); } if (!loopsOK) { return(false); } // [TODO] to support trimming mesh w/ existing holes, we need to figure out which // loop we created in RemoveTriangles above! if (loops.Count > 1) { return(false); } int[] loopVerts = loops[0].Vertices; var borderTris = new MeshFaceSelection(Mesh); borderTris.SelectVertexOneRings(loopVerts); borderTris.ExpandToOneRingNeighbours(RemeshBorderRings); var remesh = new RegionRemesher(Mesh, borderTris.ToArray()); remesh.Region.MapVerticesToSubmesh(loopVerts); double target_len = TargetEdgeLength; if (target_len <= 0) { double mine, maxe, avge; MeshQueries.EdgeLengthStatsFromEdges(Mesh, loops[0].Edges, out mine, out maxe, out avge); target_len = avge; } var meshTarget = new MeshProjectionTarget(Spatial.Mesh, Spatial); remesh.SetProjectionTarget(meshTarget); remesh.SetTargetEdgeLength(target_len); remesh.SmoothSpeedT = SmoothingAlpha; var curveTarget = new DCurveProjectionTarget(TrimLine); var multiTarget = new SequentialProjectionTarget(curveTarget, meshTarget); int set_id = 3; MeshConstraintUtil.ConstrainVtxLoopTo(remesh, loopVerts, multiTarget, set_id); for (int i = 0; i < RemeshRounds; ++i) { remesh.BasicRemeshPass(); } remesh.BackPropropagate(); // [TODO] output loop somehow...use MeshConstraints.FindConstrainedEdgesBySetID(set_id)... return(true); } // Trim()