/// <summary>
        /// Calculate extents of mesh along an axis, with optional transform
        /// </summary>
        public static Interval1d ExtentsOnAxis(IMesh mesh, Vector3d axis, Func <Vector3d, Vector3d> TransformF = null)
        {
            Interval1d extent = Interval1d.Empty;

            if (TransformF == null)
            {
                foreach (int vid in mesh.VertexIndices())
                {
                    extent.Contain(mesh.GetVertex(vid).Dot(ref axis));
                }
            }
            else
            {
                foreach (int vid in mesh.VertexIndices())
                {
                    Vector3d vT = TransformF(mesh.GetVertex(vid));
                    extent.Contain(vT.Dot(ref axis));
                }
            }
            return(extent);
        }
        /// <summary>
        /// Calculate extents of mesh along an axis, with optional transform
        /// </summary>
        public static Interval1d ExtentsOnAxis(DMesh3 mesh, Vector3d axis, Func <Vector3d, Vector3d> TransformF = null)
        {
            Interval1d extent = Interval1d.Empty;

            if (TransformF == null)
            {
                foreach (Vector3d v in mesh.Vertices())
                {
                    extent.Contain(v.Dot(ref axis));
                }
            }
            else
            {
                foreach (Vector3d v in mesh.Vertices())
                {
                    Vector3d vT = TransformF(v);
                    extent.Contain(vT.Dot(ref axis));
                }
            }
            return(extent);
        }
Beispiel #3
0
        public void AddPoint(float t, Colorf c)
        {
            var cp = new ColorPoint()
            {
                t = t, c = c
            };

            if (points.Count == 0)
            {
                points.Add(cp);
                validRange.Contain(t);
            }
            else if (t < points[0].t)
            {
                points.Insert(0, cp);
                validRange.Contain(t);
            }
            else
            {
                for (int k = 0; k < points.Count; ++k)
                {
                    if (points[k].t == t)
                    {
                        points[k] = cp;
                        return;
                    }
                    else if (points[k].t > t)
                    {
                        points.Insert(k, cp);
                        return;
                    }
                }
                points.Add(cp);
                validRange.Contain(t);
            }
        }
Beispiel #4
0
        public void AddPoint(double t, double value)
        {
            var cp = new Sample()
            {
                t = t, value = value
            };

            if (points.Count == 0)
            {
                points.Add(cp);
                validRange.Contain(t);
            }
            else if (t < points[0].t)
            {
                points.Insert(0, cp);
                validRange.Contain(t);
            }
            else
            {
                for (int k = 0; k < points.Count; ++k)
                {
                    if (points[k].t == t)
                    {
                        points[k] = cp;
                        return;
                    }
                    else if (points[k].t > t)
                    {
                        points.Insert(k, cp);
                        return;
                    }
                }
                points.Add(cp);
                validRange.Contain(t);
            }
        }
Beispiel #5
0
        int split_tri_set_midpoint(int[] triangles, Vector3d[] centers, int iStart, int iCount, int depth, int minTriCount,
                                   boxes_set tris, boxes_set nodes, out AxisAlignedBox3f box)
        {
            box = AxisAlignedBox3f.Empty;
            int iBox = -1;

            if (iCount < minTriCount)
            {
                // append new triangles box
                iBox = tris.iBoxCur++;
                tris.box_to_index.insert(tris.iIndicesCur, iBox);

                tris.index_list.insert(iCount, tris.iIndicesCur++);
                for (int i = 0; i < iCount; ++i)
                {
                    tris.index_list.insert(triangles[iStart + i], tris.iIndicesCur++);
                    box.Contain(mesh.GetTriBounds(triangles[iStart + i]));
                }

                tris.box_centers.insert(box.Center, iBox);
                tris.box_extents.insert(box.Extents, iBox);

                return(-(iBox + 1));
            }

            //compute interval along an axis and find midpoint
            int        axis     = depth % 3;
            Interval1d interval = Interval1d.Empty;

            for (int i = 0; i < iCount; ++i)
            {
                interval.Contain(centers[iStart + i][axis]);
            }
            double midpoint = interval.Center;

            int n0, n1;

            if (Math.Abs(interval.a - interval.b) > MathUtil.ZeroTolerance)
            {
                // we have to re-sort the centers & triangles lists so that centers < midpoint
                // are first, so that we can recurse on the two subsets. We walk in from each side,
                // until we find two out-of-order locations, then we swap them.
                int l = 0;
                int r = iCount - 1;
                while (l < r)
                {
                    // [RMS] is <= right here? if v.axis == midpoint, then this loop
                    //   can get stuck unless one of these has an equality test. But
                    //   I did not think enough about if this is the right thing to do...
                    while (centers[iStart + l][axis] <= midpoint)
                    {
                        l++;
                    }
                    while (centers[iStart + r][axis] > midpoint)
                    {
                        r--;
                    }
                    if (l >= r)
                    {
                        break;      //done!
                    }
                    //swap
                    Vector3d tmpc = centers[iStart + l]; centers[iStart + l] = centers[iStart + r];  centers[iStart + r] = tmpc;
                    int      tmpt = triangles[iStart + l]; triangles[iStart + l] = triangles[iStart + r]; triangles[iStart + r] = tmpt;
                }

                n0 = l;
                n1 = iCount - n0;
                Debug.Assert(n0 >= 1 && n1 >= 1);
            }
            else
            {
                // interval is near-empty, so no point trying to do sorting, just split half and half
                n0 = iCount / 2;
                n1 = iCount - n0;
            }

            // create child boxes
            AxisAlignedBox3f box1;
            int child0 = split_tri_set_midpoint(triangles, centers, iStart, n0, depth + 1, minTriCount, tris, nodes, out box);
            int child1 = split_tri_set_midpoint(triangles, centers, iStart + n0, n1, depth + 1, minTriCount, tris, nodes, out box1);

            box.Contain(box1);

            // append new box
            iBox = nodes.iBoxCur++;
            nodes.box_to_index.insert(nodes.iIndicesCur, iBox);

            nodes.index_list.insert(child0, nodes.iIndicesCur++);
            nodes.index_list.insert(child1, nodes.iIndicesCur++);

            nodes.box_centers.insert(box.Center, iBox);
            nodes.box_extents.insert(box.Extents, iBox);

            return(iBox);
        }
        public override DeformInfo Apply(Frame3f vNextPos)
        {
            Interval1d edgeRangeSqr = Interval1d.Empty;

            int N = Curve.VertexCount;

            if (N > NewV.size)
            {
                NewV.resize(N);
            }
            if (N > ModifiedV.Length)
            {
                ModifiedV = new BitArray(2 * N);
            }

            // clear modified
            ModifiedV.SetAll(false);

            bool   bSmooth = (SmoothAlpha > 0 && SmoothIterations > 0);
            double r2      = Radius * Radius;

            // deform pass
            if (DeformF != null)
            {
                for (int i = 0; i < N; ++i)
                {
                    Vector3d v  = Curve[i];
                    double   d2 = (v - vPreviousPos.Origin).LengthSquared;
                    if (d2 < r2)
                    {
                        double t = WeightFunc(Math.Sqrt(d2), Radius);

                        Vector3d vNew = DeformF(i, t);

                        if (bSmooth == false)
                        {
                            if (i > 0)
                            {
                                edgeRangeSqr.Contain(vNew.DistanceSquared(Curve[i - 1]));
                            }
                            if (i < N - 1)
                            {
                                edgeRangeSqr.Contain(vNew.DistanceSquared(Curve[i + 1]));
                            }
                        }

                        NewV[i]      = vNew;
                        ModifiedV[i] = true;
                    }
                }
            }
            else
            {
                // anything?
            }

            // smooth pass
            if (bSmooth)
            {
                for (int j = 0; j < SmoothIterations; ++j)
                {
                    int iStart = (Curve.Closed) ? 0 : 1;
                    int iEnd   = (Curve.Closed) ? N : N - 1;
                    for (int i = iStart; i < iEnd; ++i)
                    {
                        Vector3d v  = (ModifiedV[i]) ? NewV[i] : Curve[i];
                        double   d2 = (v - vPreviousPos.Origin).LengthSquared;
                        if (ModifiedV[i] || d2 < r2)            // always smooth any modified verts
                        {
                            double a = SmoothAlpha * WeightFunc(Math.Sqrt(d2), Radius);

                            int      iPrev = (i == 0) ? N - 1 : i - 1;
                            int      iNext = (i + 1) % N;
                            Vector3d vPrev = (ModifiedV[iPrev]) ? NewV[iPrev] : Curve[iPrev];
                            Vector3d vNext = (ModifiedV[iNext]) ? NewV[iNext] : Curve[iNext];
                            Vector3d c     = (vPrev + vNext) * 0.5f;
                            NewV[i]      = (1 - a) * v + (a) * c;
                            ModifiedV[i] = true;

                            if (i > 0)
                            {
                                edgeRangeSqr.Contain(NewV[i].DistanceSquared(Curve[i - 1]));
                            }
                            if (i < N - 1)
                            {
                                edgeRangeSqr.Contain(NewV[i].DistanceSquared(Curve[i + 1]));
                            }
                        }
                    }
                }
            }

            // bake
            for (int i = 0; i < N; ++i)
            {
                if (ModifiedV[i])
                {
                    Curve[i] = NewV[i];
                }
            }

            return(new DeformInfo()
            {
                minEdgeLenSqr = edgeRangeSqr.a, maxEdgeLenSqr = edgeRangeSqr.b
            });
        }