static double eval_point_wn(DMesh3 mesh, Vector3d q) { SpinLock locker = new SpinLock(); double sum = 0; gParallel.ForEach(mesh.TriangleIndices(), (tid) => { Vector3d n, c; double area; mesh.GetTriInfo(tid, out n, out area, out c); Triangle3d tri = new Triangle3d(); mesh.GetTriVertices(tid, ref tri.V0, ref tri.V1, ref tri.V2); //double pt_wn = pointwn_order1(ref c, ref n, ref area, ref q); Vector3d evalPt = c - n * 0.001; //double pt_wn = pointwn_order2(ref c, ref evalPt, ref n, ref area, ref q); //double pt_wn = triwn_order1(ref tri, ref evalPt, ref n, ref area, ref q); double pt_wn = triwn_order2(ref tri, ref evalPt, ref n, ref area, ref q); bool entered = false; locker.Enter(ref entered); sum += pt_wn; locker.Exit(); }); return(sum); }
IEnumerable <Vector3d> offset_seeds(DMesh3 meshIn, double offset) { foreach (int tid in meshIn.TriangleIndices()) { Vector3d n, c; double a; meshIn.GetTriInfo(tid, out n, out a, out c); yield return(c + offset * n); } }
public static Vector3d QuickCompute(DMesh3 mesh, int vid, NormalsTypes type = NormalsTypes.Vertex_OneRingFaceAverage_AreaWeighted) { Vector3d sum = Vector3d.Zero; Vector3d n, c; double a; foreach (int tid in mesh.VtxTrianglesItr(vid)) { mesh.GetTriInfo(tid, out n, out a, out c); sum += a * n; } return(sum.Normalized); }
void compute_statistics(Component c) { int NC = c.triangles.Count; c.inFacing = c.outFacing = 0; double dist = 2 * Mesh.CachedBounds.DiagonalLength; // only want to raycast triangles in this HashSet <int> tris = new HashSet <int>(c.triangles); spatial.TriangleFilterF = tris.Contains; // We want to try to figure out what is 'outside' relative to the world. // Assumption is that faces we can hit from far away should be oriented outwards. // So, for each triangle we construct far-away points in positive and negative normal // direction, then raycast back towards the triangle. If we hit the triangle from // one side and not the other, that is evidence we should keep/reverse that triangle. // If it is not hit, or hit from both, that does not provide any evidence. // We collect up this keep/reverse evidence and use the larger to decide on the global orientation. SpinLock count_lock = new SpinLock(); gParallel.BlockStartEnd(0, NC - 1, (a, b) => { for (int i = a; i <= b; ++i) { int ti = c.triangles[i]; Vector3d normal, centroid; double area; Mesh.GetTriInfo(ti, out normal, out area, out centroid); if (area < MathUtil.ZeroTolerancef) { continue; } // construct far away points Vector3d pos_pt = centroid + dist * normal; Vector3d neg_pt = centroid - dist * normal; // raycast towards triangle from far-away point int hit_pos = spatial.FindNearestHitTriangle(new Ray3d(pos_pt, -normal)); int hit_neg = spatial.FindNearestHitTriangle(new Ray3d(neg_pt, normal)); if (hit_pos != ti && hit_neg != ti) { continue; // no evidence } if (hit_pos == ti && hit_neg == ti) { continue; // no evidence (?) } bool taken = false; count_lock.Enter(ref taken); if (hit_neg == ti) { c.inFacing += area; } else if (hit_pos == ti) { c.outFacing += area; } count_lock.Exit(); } }); spatial.TriangleFilterF = null; }
protected void do_flatten(DMesh3 mesh) { double BAND_HEIGHT = flatten_band_height; Vector3d down_axis = -Vector3d.AxisY; double dot_thresh = 0.2; AxisAlignedBox3d bounds = mesh.CachedBounds; DMeshAABBTree3 spatial = new DMeshAABBTree3(mesh, true); Ray3d ray = new Ray3d(bounds.Center - 2 * bounds.Height * Vector3d.AxisY, Vector3d.AxisY); int hit_tid = spatial.FindNearestHitTriangle(ray); Frame3f hitF; MeshQueries.RayHitPointFrame(mesh, spatial, ray, out hitF); Vector3d basePt = hitF.Origin; Frame3f basePlane = new Frame3f(basePt, Vector3f.AxisY); MeshConnectedComponents components = new MeshConnectedComponents(mesh) { FilterF = (tid) => { if (mesh.GetTriangleGroup(tid) != LastExtrudeOuterGroupID) { return(false); } Vector3d n, c; double a; mesh.GetTriInfo(tid, out n, out a, out c); double h = Math.Abs(c.y - basePt.y); if (h > BAND_HEIGHT) { return(false); } if (n.Dot(down_axis) < dot_thresh) { return(false); } return(true); }, SeedFilterF = (tid) => { return(tid == hit_tid); } }; components.FindConnectedT(); MeshFaceSelection all_faces = new MeshFaceSelection(mesh); foreach (var comp in components) { MeshVertexSelection vertices = new MeshVertexSelection(mesh); vertices.SelectTriangleVertices(comp.Indices); foreach (int vid in vertices) { Vector3d v = mesh.GetVertex(vid); v = basePlane.ProjectToPlane((Vector3f)v, 2); mesh.SetVertex(vid, v); } all_faces.SelectVertexOneRings(vertices); } all_faces.ExpandToOneRingNeighbours(3, (tid) => { return(mesh.GetTriangleGroup(tid) == LastExtrudeOuterGroupID); }); RegionRemesher r = new RegionRemesher(mesh, all_faces); r.SetProjectionTarget(MeshProjectionTarget.Auto(mesh)); r.SetTargetEdgeLength(2.0f); r.SmoothSpeedT = 1.0f; for (int k = 0; k < 10; ++k) { r.BasicRemeshPass(); } r.SetProjectionTarget(null); r.SmoothSpeedT = 1.0f; for (int k = 0; k < 10; ++k) { r.BasicRemeshPass(); } r.BackPropropagate(); }