Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
 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);
     }
 }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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;
        }
Ejemplo n.º 5
0
        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();
        }