Example #1
0
        /// <summary>
        /// Estimates a normal vector for each point by least-squares-fitting a plane through its k nearest neighbours.
        /// </summary>
        public static V3f[] EstimateNormals(this V3f[] points, int k)
        {
            var kd = new PointRkdTreeD <V3f[], V3f>(
                3, points.Length, points,
                (xs, i) => xs[(int)i], (v, i) => (float)v[i],
                (a, b) => V3f.Distance(a, b), (i, a, b) => b - a,
                (a, b, c) => VecFun.DistanceToLine(a, b, c), VecFun.Lerp, 0
                );

            return(EstimateNormals(points, kd, k));
        }
            public PointSetNode ToPointSetCell(Storage storage, CancellationToken ct, double kdTreeEps = 1e-6)
            {
                var center = new V3d(_centerX, _centerY, _centerZ);

                V3f[] ps = null;
                C4b[] cs = null;
                V3f[] ns = null;
                int[] js = null;
                PointRkdTreeD <V3f[], V3f> kdTree = null;

                if (_ia != null)
                {
                    var allPs = _octree.m_ps;
                    var count = _ia.Count;

                    ps = new V3f[count];
                    for (var i = 0; i < count; i++)
                    {
                        ps[i] = (V3f)(allPs[_ia[i]] - center);
                    }

                    if (_octree.m_cs != null)
                    {
                        var allCs = _octree.m_cs;
                        cs = new C4b[count];
                        for (var i = 0; i < count; i++)
                        {
                            cs[i] = allCs[_ia[i]];
                        }
                    }

                    if (_octree.m_ns != null)
                    {
                        var allNs = _octree.m_ns;
                        ns = new V3f[count];
                        for (var i = 0; i < count; i++)
                        {
                            ns[i] = allNs[_ia[i]];
                        }
                    }

                    if (_octree.m_is != null)
                    {
                        var allIs = _octree.m_is;
                        js = new int[count];
                        for (var i = 0; i < count; i++)
                        {
                            js[i] = allIs[_ia[i]];
                        }
                    }

                    kdTree = new PointRkdTreeD <V3f[], V3f>(
                        3, ps.Length, ps,
                        (xs, i) => xs[(int)i], (v, i) => (float)v[i],
                        (a, b) => V3f.Distance(a, b), (i, a, b) => b - a,
                        (a, b, c) => VecFun.DistanceToLine(a, b, c), VecFun.Lerp, kdTreeEps
                        );
                }

                Guid?psId = ps != null ? (Guid?)Guid.NewGuid() : null;
                Guid?csId = cs != null ? (Guid?)Guid.NewGuid() : null;
                Guid?nsId = ns != null ? (Guid?)Guid.NewGuid() : null;
                Guid?isId = js != null ? (Guid?)Guid.NewGuid() : null;
                Guid?kdId = kdTree != null ? (Guid?)Guid.NewGuid() : null;

                var subcells   = _subnodes?.Map(x => x?.ToPointSetCell(storage, ct, kdTreeEps));
                var subcellIds = subcells?.Map(x => x?.Id);

#if DEBUG
                if (ps != null && _subnodes != null)
                {
                    throw new InvalidOperationException();
                }
#endif
                var pointCountTree = ps != null
                    ? ps.Length
                    : subcells.Sum(n => n != null ? n.PointCountTree : 0)
                ;

                if (psId != null)
                {
                    storage.Add(psId.ToString(), ps, ct);
                }
                if (csId != null)
                {
                    storage.Add(csId.ToString(), cs, ct);
                }
                if (nsId != null)
                {
                    storage.Add(nsId.ToString(), ns, ct);
                }
                if (isId != null)
                {
                    storage.Add(isId.ToString(), js, ct);
                }
                if (kdId != null)
                {
                    storage.Add(kdId.ToString(), kdTree.Data, ct);
                }

                if (subcellIds == null) // leaf
                {
                    return(new PointSetNode(_cell, pointCountTree, psId, csId, kdId, nsId, isId, storage));
                }
                else
                {
                    return(new PointSetNode(_cell, pointCountTree, subcellIds, storage));
                }
            }
Example #3
0
 /// <summary>
 /// Estimates a normal vector for each point by least-squares-fitting a plane through its k nearest neighbours.
 /// Requires that the supplied kdtree is built from given points.
 /// </summary>
 public static V3f[] EstimateNormals(this IList <V3d> points, PointRkdTreeD <V3d[], V3d> kdtree, int k)
 => points.Map((p, i) =>