added IsParallelTo relation for vectors

added IsParallelTo relation for vectors

--- src/Aardvark.Base/Geometry/Relations.cs
+++ src/Aardvark.Base/Geometry/Relations.cs
@@ -1,905 +1,935 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Aardvark.Base
-{
-    /// <summary>
-    /// Provides various methods determining parallelism
-    /// </summary>
-    public static class Parallelism
-    {
-        // 2-Dimensional
-
-        #region V2d - V2d
-
-        public static bool IsParallelTo(this V2d u, V2d v)
-        {
-            return Fun.IsTiny(u.X * v.Y - u.Y * v.X);
-        }
-
-        #endregion
-
-        #region Ray2d - V2d
-
-        public static bool IsParallelTo(this Ray2d ray, V2d v)
-        {
-            return ray.Direction.IsParallelTo(v);
-        }
-
-        #endregion
-
-        #region Ray2d - Ray2d
-
-        public static bool IsParallelTo(this Ray2d r0, Ray2d r1)
-        {
-            return r0.Direction.IsParallelTo(r1.Direction);
-        }
-
-        #endregion
-
-        // 3-Dimensional
-
-        #region V3d - V3d
-
-        public static bool IsParallelTo(this V3d u, V3d v)
-        {
-            return Fun.IsTiny(u.Cross(v).Norm1);
-        }
-
-        #endregion
-
-        #region Ray3d - V3d
-
-        public static bool IsParallelTo(this Ray3d ray, V3d vec)
-        {
-            return ray.Direction.IsParallelTo(vec);
-        }
-
-        #endregion
-
-        #region Ray3d - Ray3d
-
-        public static bool IsParallelTo(this Ray3d r0, Ray3d r1)
-        {
-            return r0.Direction.IsParallelTo(r1.Direction);
-        }
-
-        #endregion
-
-        #region Plane3d - Plane3d
-
-        public static bool IsParallelTo(this Plane3d p0, Plane3d p1)
-        {
-            return p0.Normal.IsParallelTo(p1.Normal);
-        }
-
-        #endregion
-
-        #region Ray3d - Plane3d
-
-        public static bool IsParallelTo(this Ray3d ray, Plane3d plane)
-        {
-            return ray.Direction.IsOrthogonalTo(plane.Normal);
-        }
-
-        public static bool IsParallelTo(this Plane3d plane , Ray3d ray)
-        {
-            return ray.Direction.IsOrthogonalTo(plane.Normal);
-        }
-
-        #endregion
-
-        #region Line3d - Line3d
-
-        public static bool IsParallelTo(this Line3d l0, Line3d l1)
-        {
-            return l0.Direction.IsParallelTo(l1.Direction);
-        }
-
-        #endregion
-    }
-
-    /// <summary>
-    /// Provides various methods determining normalism
-    /// </summary>
-    public static class Otrthogonalism
-    {
-        // 2-Dimensional
-
-        #region V2d - V2d
-
-        public static bool IsOrthogonalTo(this V2d u, V2d v)
-        {
-            return Fun.IsTiny(u.Dot(v));
-        }
-
-        #endregion
-
-        #region Ray2d - V2d
-
-        public static bool IsOrthogonalTo(this Ray2d ray, V2d v)
-        {
-            return ray.Direction.IsOrthogonalTo(v);
-        }
-
-        #endregion
-
-        #region Ray2d - Ray2d
-
-        public static bool IsOrthogonalTo(this Ray2d r0, Ray2d r1)
-        {
-            return r0.Direction.IsOrthogonalTo(r1.Direction);
-        }
-
-        #endregion
-
-        // 3-Dimensional
-
-        #region V3d - V3d
-
-        public static bool IsOrthogonalTo(this V3d u, V3d v)
-        {
-            return Fun.IsTiny(u.Dot(v));
-        }
-
-        #endregion
-
-        #region Ray3d - V3d
-
-        public static bool IsOrthogonalTo(this Ray3d ray, V3d vec)
-        {
-            return ray.Direction.IsOrthogonalTo(vec);
-        }
-
-        #endregion
-
-        #region Ray3d - Ray3d
-
-        public static bool IsOrthogonalTo(this Ray3d r0, Ray3d r1)
-        {
-            return r0.Direction.IsOrthogonalTo(r1.Direction);
-        }
-
-        #endregion
-
-        #region Plane3d - Plane3d
-
-        public static bool IsOrthogonalTo(this Plane3d p0, Plane3d p1)
-        {
-            return p0.Normal.IsOrthogonalTo(p1.Normal);
-        }
-
-        #endregion
-
-        #region Ray3d - Plane3d
-
-        public static bool IsOrthogonalTo(this Ray3d ray, Plane3d plane)
-        {
-            return ray.Direction.IsParallelTo(plane.Normal);
-        }
-
-        public static bool IsNormalTo(this Plane3d plane, Ray3d ray)
-        {
-            return ray.Direction.IsParallelTo(plane.Normal);
-        }
-
-        #endregion
-    }
-
-    public static class LinearCombination
-    {
-        #region V3d - V3d
-
-        public static bool IsLinearCombinationOf(this V3d x, V3d u, V3d v)
-        {
-            V3d n = u.Cross(v);
-            return n.IsOrthogonalTo(x);
-        }
-
-        public static bool IsLinearCombinationOf(this V3d x, V3d u)
-        {
-            return x.IsParallelTo(u);
-        }
-
-        public static bool IsLinearCombinationOf(this V3d x, V3d u, V3d v, out double t0, out double t1)
-        {
-            //x == t2*u + t1*v
-            V3d n = u.Cross(v);
-
-            double[,] mat = new double[3, 3]
-            {
-                {u.X,v.X,n.X},
-                {u.Y,v.Y,n.Y},
-                {u.Z,v.Z,n.Z}
-            };
-
-            double[] result = new double[3]{x.X,x.Y,x.Z};
-
-            int[] perm = mat.LuFactorize();
-            V3d t = new V3d(mat.LuSolve(perm,result));
-
-            if (Fun.IsTiny(t.Z))
-            {
-                t0 = t.X;
-                t1 = t.Y;
-
-                return true;
-            }
-            else
-            {
-                t0 = double.NaN;
-                t1 = double.NaN;
-
-                return false;
-            }
-
-            //x ==
-        }
-
-        #endregion
-    }
-
-    public static class GeometricProperties
-    {
-        #region Degenerated parts of a Polygon2d
-
-        #region Polygon2d-Extensions
-
-        /// <summary>
-        /// Returns true if the Polygon contains a degenerated part
-        /// </summary>
-        public static bool HasDegeneratedPart(this Polygon2d poly)
-        {
-            return poly.PolygonHasDegeneratedPart();
-        }
-
-        /// <summary>
-        /// Returns true if the Polygon contains a degenerated part
-        /// </summary>
-        public static bool HasDegeneratedPart(this Polygon2d poly, double absoluteEpsilon)
-        {
-            return poly.PolygonHasDegeneratedPart(absoluteEpsilon);
-        }
-
-        /// <summary>
-        /// Returns true if the Polygon contains a degenerated part
-        /// NonDegenerated holds the Non-Degenerated part of the polygon
-        /// </summary>
-        public static bool HasDegeneratedPart(this Polygon2d poly, out Polygon2d NonDegenerated)
-        {
-            int[] temp;
-            bool result = poly.PolygonHasDegeneratedPart(out temp);
-
-            NonDegenerated = new Polygon2d((from i in temp select poly[i]).ToArray<V2d>());
-            return result;
-        }
-
-        /// <summary>
-        /// Returns true if the Polygon contains a degenerated part
-        /// NonDegenerated holds the Non-Degenerated part of the polygon
-        /// </summary>
-        public static bool HasDegeneratedPart(this Polygon2d poly, out int[] NonDegenerated)
-        {
-            return poly.PolygonHasDegeneratedPart(out NonDegenerated);
-        }
-
-        /// <summary>
-        /// Returns true if the Polygon contains a degenerated part
-        /// NonDegenerated holds the Non-Degenerated part of the polygon
-        /// </summary>
-        public static bool HasDegeneratedPart(this Polygon2d poly, double absoluteEpsilon, out int[] NonDegenerated)
-        {
-            return poly.PolygonHasDegeneratedPart(absoluteEpsilon, out NonDegenerated);
-        }
-
-        #endregion
-
-        #region V2d[]-Extension
-
-        /// <summary>
-        /// Returns true if the Polygon contains a degenerated part
-        /// </summary>
-        public static bool PolygonHasDegeneratedPart(this Polygon2d poly)
-        {
-            return poly.PolygonHasDegeneratedPart(4.0 * double.Epsilon);
-        }
-
-        /// <summary>
-        /// Returns true if the Polygon contains a degenerated part
-        /// </summary>
-        public static bool PolygonHasDegeneratedPart(this Polygon2d poly, double absoluteEpsilon)
-        {
-            if (absoluteEpsilon < 0.0) throw new ArgumentOutOfRangeException();
-
-            int i = 0;
-            int count = poly.PointCount;
-
-            V2d e0;
-            V2d e1;
-
-            double l0 = 0.0;
-            double l1 = 0.0;
-
-            while (i < count - 1)
-            {
-                if ((poly[i + 1] - poly[i]).Length < absoluteEpsilon) return true;
-
-                e0 = (poly[i + 1] - poly[i]);
-                e1 = (poly[(i + 2) % count] - poly[i + 1]);
-
-                l0 = e0.Length;
-                l1 = e1.Length;
-
-                e0 = e0 / l0;
-                //e1 = e1 / l1;
-
-                if ((e0.X*e1.Y - e0.Y*e1.X).Abs() > absoluteEpsilon) return true;
-            }
-
-            return false;
-        }
-
-        /// <summary>
-        /// Returns true if the Polygon contains a degenerated part
-        /// NonDegenerated holds the Non-Degenerated part of the polygon
-        /// </summary>
-        public static bool PolygonHasDegeneratedPart(this Polygon2d poly, out int[] NonDegenerated)
-        {
-            return poly.PolygonHasDegeneratedPart(4.0 * double.Epsilon, out NonDegenerated);
-        }
-
-        /// <summary>
-        /// Returns true if the Polygon contains a degenerated part
-        /// NonDegenerated holds the Non-Degenerated part of the polygon
-        /// </summary>
-        public static bool PolygonHasDegeneratedPart(this Polygon2d poly, double absoluteEpsilon, out int[] NonDegenerated)
-        {
-            if (absoluteEpsilon < 0.0) throw new ArgumentOutOfRangeException();
-
-            int i = 0;
-            int u = 1;
-            int start = 0;
-            V2d e0;
-            V2d e1;
-            bool found = false;
-            int count = poly.PointCount;
-
-            List<int> newPoints = new List<int>();
-            newPoints.Add(0);
-
-            double l0 = 0.0;
-
-
-            while (i < count - 1)
-            {
-                e0 = (poly[i + 1] - poly[i]);
-                l0 = e0.Length;
-
-                e0 = e0 / l0;
-
-
-
-                u = i + 1;
-                V2d e = poly[(u + 1) % count] - poly[u];
-                while (
-                    (((e0.X*e.Y - e0.Y*e.X).Abs() < absoluteEpsilon && e.Dot(e0) > 0.0) ||
-                    (poly[(u + 1) % count] - poly[i + 1]).Length < absoluteEpsilon)
-                    && u < count - 1)
-                {
-                    if ((poly[(u + 1) % count] - poly[i + 1]).Length < absoluteEpsilon) found = true;
-
-                    u++;
-                    e0 = (poly[u] - poly[i]).Normalized;
-                    e = poly[(u + 1) % count] - poly[u];
-                }
-                u--;
-
-                start = u;
-
-                do
-                {
-                    u++;
-                    e1 = (poly[(u + 1) % count] - poly[u]);
-                }
-                while (u < count && ((e0.X * e1.Y - e0.Y * e1.X).Abs() < absoluteEpsilon && e.Dot(e0) < 0.0));
-
-                if (u != start + 1) found = true;
-
-                newPoints.Add(u);
-
-                i = u;
-            }
-
-            NonDegenerated = newPoints.ToArray();
-            return found;
-        }
-
-        #endregion
-
-        #endregion
-    }
-
-    public static class SubPrimitives
-    {
-        #region Triangulation of Convex Polygons
-
-        /// <summary>
-        /// Compute a simple triangulation starting from the first point of
-        /// the polygon. Note that the indices are twice indirect (once over
-        /// pia, once over via). Returns the number of triangles (ie. two
-        /// less than the length of the array pia).
-        /// </summary>
-        public static int ComputeSimpleTriangulation(
-                this int[] pia, int[] via, int tvi, int[] tia, int[] pvibm, int[] tibm)
-        {
-            int fi = pia[0], fvi = via[fi];
-            int i1 = pia[1], vi1 = via[i1];
-            int count = pia.Length;
-            for (int ii = 2; ii < count; ii++)
-            {
-                int vi0 = vi1, i0 = i1;
-                vi1 = via[i1 = pia[ii]];
-                tia[tvi] = fvi;
-                tia[tvi + 1] = vi0;
-                tia[tvi + 2] = vi1;
-                if (tibm != null)
-                {
-                    tibm[tvi] = pvibm[fi];
-                    tibm[tvi + 1] = pvibm[i0];
-                    tibm[tvi + 2] = pvibm[i1];
-                }
-                tvi += 3;
-            }
-            return count - 2;
-        }
-
-        #endregion
-
-        #region Non-Concave Sub-Polygons of a Polygon2d
-
-        private static int[] ComputeNonConcaveSubPolygon(
-                this Polygon2d poly, ref int[] indices, double absoluteEpsilon)
-        {
-            int count = indices.Length;
-
-            if (count <= 3)
-            {
-                var result = indices;
-                indices = new int[0];
-                return result;
-            }
-
-            Func<int, int> addFun = i => (i + 1) % count;
-            Func<int, int> subFun = i => (i + count - 1) % count;
-
-            for (int vi = 0; vi < count; vi++) // we possibly have to try all vertices
-            {
-                int nowMinIndex = vi, nowMaxIndex = vi;
-                var nowMinPoint = poly[indices[nowMinIndex]];
-                var nowMaxPoint = poly[indices[nowMaxIndex]];
-                var oldMinPoint = poly[indices[addFun(nowMinIndex)]];
-                var oldMaxPoint = poly[indices[subFun(nowMinIndex)]];
-                var subCount = 1;
-
-                bool add = true;
-
-                for (int pass = 0, goodPass = 0; pass - goodPass < 3; pass++, add = !add)
-                {
-                    // alternate between adding a point at the two ends
-                    var nextFun = add ? addFun : subFun;
-                    int lastIndex = add ? nowMinIndex : nowMaxIndex;
-
-                    int newIndex = add ? addFun(nowMaxIndex) : subFun(nowMinIndex);
-                    if (newIndex == lastIndex)
-                    {
-                        var finalIndices = indices;
-                        indices = new int[0];
-                        return finalIndices;
-                    }
-
-                    var newPoint = poly[indices[newIndex]];
-                    var pMax = new Line2d(oldMaxPoint, nowMaxPoint).Plane2d;
-                    var pMin = new Line2d(oldMinPoint, nowMinPoint).Plane2d;
-
-                    var npMax = pMax.Normalized;
-                    var npMin = pMin.Normalized;
-
-                    var hMax = new Line2d(oldMaxPoint, nowMaxPoint).Plane2d.Normalized.Height(newPoint);
-                    var hMin = new Line2d(oldMinPoint, nowMinPoint).Plane2d.Normalized.Height(newPoint);
-
-                    if (hMax >= -absoluteEpsilon && hMin <= absoluteEpsilon)
-                    {
-                        bool good = true;
-                        if (nowMinIndex != nowMaxIndex)
-                        {
-                            var plane0 = new Line2d(nowMinPoint, nowMaxPoint).Plane2d.Normalized;
-                            var plane1 = new Line2d(nowMaxPoint, newPoint).Plane2d.Normalized;
-                            var plane2 = new Line2d(newPoint, nowMinPoint).Plane2d.Normalized;
-
-                            // check if new triangle does not contain any other points of the polygon
-                            for (int i = nextFun(newIndex); i != lastIndex; i = nextFun(i))
-                            {
-                                var point = poly[indices[i]];
-                                if (plane0.Height(point) > -absoluteEpsilon
-                                    && plane1.Height(point) >= absoluteEpsilon
-                                    && plane2.Height(point) >= absoluteEpsilon)
-                                { good = false; break; }
-                            }
-                        }
-                        if (good)
-                        {
-                            if (add)
-                            {
-                                nowMaxIndex = newIndex; oldMaxPoint = nowMaxPoint; nowMaxPoint = newPoint;
-                            }
-                            else
-                            {
-                                nowMinIndex = newIndex; oldMinPoint = nowMinPoint; nowMinPoint = newPoint;
-                            }
-                            goodPass = pass;
-                            ++subCount;
-                        }
-                    }
-                }
-                if (subCount < 3) continue;
-
-                // build new arrays here
-
-                var subIndices = new int[subCount];
-                for (int i = 0, ni = nowMinIndex; i < subCount; i++, ni = addFun(ni))
-                    subIndices[i] = indices[ni];
-                int newCount = 2 + count - subCount;
-                var newIndices = new int[newCount];
-                for (int i = 0, ni = nowMaxIndex; i < newCount; i++, ni = addFun(ni))
-                    newIndices[i] = indices[ni];
-
-                indices = newIndices;
-                return subIndices;
-            }
-            return null;
-        }
-
-        public static void AddNonConcaveSubPolygons(
-                this List<int[]> polygonList, Polygon2d poly,
-                double absoluteEpsilon)
-        {
-            var indices = new int[poly.PointCount].SetByIndex(i => i);
-            while (indices.Length > 0)
-            {
-                var subPoly = poly.ComputeNonConcaveSubPolygon(
-                                    ref indices, absoluteEpsilon);
-                if (subPoly.Length < 3)
-                {
-                    Console.WriteLine("encountered invalid subpolygon");
-                    continue;
-                }
-                polygonList.Add(subPoly);
-            }
-        }
-
-        public static List<int[]> ComputeNonConcaveSubPolygons(
-                this Polygon2d polygon, double absoluteEpsilon)
-        {
-            var polygonList = new List<int[]>();
-            polygonList.AddNonConcaveSubPolygons(polygon, absoluteEpsilon);
-            return polygonList;
-        }
-
-        #endregion
-
-        #region Non-Concave Sub-Polygons of Polygons in 3d
-
-        public static List<int[]> ComputeNonConcaveSubPolygons(
-                this Polygon3d polygon, double absoluteEpsilon)
-        {
-            V3d normal = polygon.ComputeDoubleAreaNormal();
-            double len2 = normal.LengthSquared;
-
-            if (len2 < absoluteEpsilon * absoluteEpsilon)
-                return new int[polygon.PointCount].SetByIndex(i => i).IntoList();
-
-            M44d local2global, global2local;
-            M44d.NormalFrame(V3d.Zero, normal * (1.0/Fun.Sqrt(len2)), out local2global, out global2local);
-            var polygon2d = polygon.ToPolygon2d(p => global2local.TransformPos(p).XY);
-            return polygon2d.ComputeNonConcaveSubPolygons(absoluteEpsilon);
-        }
-
-        public static List<int[]> ComputeNonConcaveSubPolygons(
-                this V3d[] vertexArray, int polyCount,
-                V3d[] normalArray, int[] firstIndices, int[] vertexIndices,
-                List<int> faceBackMap,
-                double absoluteEpsilon)
-        {
-            var polyList = new List<int[]>();
-            var eps2 = absoluteEpsilon * absoluteEpsilon;
-
-            for (int fvi = 0, fi = 0; fi < polyCount; fi++)
-            {
-                int fve = firstIndices[fi+1], fvc = fve - fvi;
-                var n = normalArray[fi];
-                var l2 = n.LengthSquared;
-                if (l2 < eps2)
-                {
-                    polyList.Add(new int[fvc].SetByIndex(i => vertexIndices[fvi + i]));
-                    continue;
-                }
-                M44d local2global, global2local;
-                M44d.NormalFrame(V3d.Zero, n, out local2global, out global2local);
-                var polygon = new Polygon2d(fvc,
-                        i => global2local.TransformPos(vertexArray[vertexIndices[fvi + i]]).XY);
-                var subPolyList = polygon.ComputeNonConcaveSubPolygons(absoluteEpsilon);
-                foreach (var poly in subPolyList)
-                    polyList.Add(poly.Copy(i => fvi + i));
-                if (faceBackMap != null)
-                    for (int i = 0; i < subPolyList.Count; i++)
-                        faceBackMap.Add(fi);
-                fvi = fve;
-            }
-
-            return polyList;
-        }
-
-        #endregion
-
-        #region Triangulation of Non-Concave Polygons in 3d
-
-        /// <summary>
-        ///
-        /// </summary>
-        /// <returns>Triangle count.</returns>
-        public static int ComputeTriangulationOfNonConcavePolygon(
-                this int[] ia, int[] via, V3d[] va, V3d[] edgeArray, bool[] straightArray,
-                int tvi, int[] tia, int[] pvibm, int[] tibm)
-        {
-            int count = ia.Length;
-
-            if (count < 3) throw new ArgumentOutOfRangeException();
-
-            if (count == 3)
-            {
-                tia[tvi] = via[ia[0]];
-                tia[tvi + 1] = via[ia[1]];
-                tia[tvi + 2] = via[ia[2]];
-                if (tibm != null)
-                {
-                    tibm[tvi] = pvibm[ia[0]];
-                    tibm[tvi + 1] = pvibm[ia[1]];
-                    tibm[tvi + 2] = pvibm[ia[2]];
-                }
-                return 1;
-            }
-
-            int ii = 0;
-
-            // search for the first non-straight corner
-            while (ii < ia.Length && straightArray[ia[ii]]) ii++;
-
-            int bii = ii; ii = (ii + 1) % count;
-
-            // search for first straight corner afterwards
-            while (ii != bii && !straightArray[ia[ii]]) ii = (ii + 1) % count;
-
-            if (ii == bii) // if there is no straight corner
-                return ia.ComputeSimpleTriangulation(via, tvi, tia, pvibm, tibm);
-            bii = ii; // first
-            int eii = ii;
-            int straightCount = 0;
-            while (straightArray[ia[ii]])
-            {
-                eii = ii; ii = (ii + 1) % count;
-                ++straightCount;
-            }
-
-            if (count - straightCount < 3) // numeric problem, cop out
-                return ia.ComputeSimpleTriangulation(via, tvi, tia, pvibm, tibm);
-
-            var hii = ii; double height = 0.0;
-            var li = ia[eii];
-            var edge = edgeArray[li];
-            var vertex = va[via[li]];
-
-            int rightCount = 2;
-            int rc = 2;
-            ii = (ii + 1) % count;
-            while (ii != bii)
-            {
-                int i = ia[ii];
-                var h = edge.Cross(va[via[i]] - vertex).LengthSquared;
-                ++rc;
-                if (h > height)
-                {
-                    height = h;
-                    hii = ii;
-                    rightCount = rc;
-                }
-                ii = (ii + 1) % count;
-            }
-
-            straightArray[ia[bii]] = false;
-            straightArray[ia[eii]] = false;
-            straightArray[ia[hii]] = false;
-
-            int leftCount = count - straightCount - rightCount + 3;
-
-            var lia = new int[leftCount];
-            ii = hii;
-            for (int lii = 0; lii < leftCount; lii++, ii = (ii + 1) % count)
-                lia[lii] = ia[ii];
-
-            if (leftCount > 2)
-                lia.ComputeTriangulationOfNonConcavePolygon(via, va, edgeArray, straightArray,
-                        tvi, tia, pvibm, tibm);
-
-            tvi += 3 * (leftCount - 2);
-
-            if (straightCount > 1)
-            {
-                int hi = ia[hii], hvi = via[hi];
-                int i1 = ia[bii], vi1 = via[i1];
-                ii = bii;
-                for (int sii = 0; sii < straightCount - 1; sii++)
-                {
-                    ii = (ii + 1) % count;
-                    int vi0 = vi1, i0 = i1;
-                    vi1 = via[i1 = ia[ii]];
-                    tia[tvi] = hvi;
-                    tia[tvi + 1] = vi0;
-                    tia[tvi + 2] = vi1;
-
-                    if (tibm != null)
-                    {
-                        tibm[tvi] = pvibm[hi];
-                        tibm[tvi + 1] = pvibm[i0];
-                        tibm[tvi + 2] = pvibm[i1];
-                    }
-                    tvi += 3;
-                }
-            }
-
-            var ria = new int[rightCount];
-            ii = eii;
-            for (int rii = 0; rii < rightCount; rii++, ii = (ii + 1) % count)
-                ria[rii] = ia[ii];
-
-            if (rightCount > 2)
-                ria.ComputeTriangulationOfNonConcavePolygon(via, va, edgeArray, straightArray,
-                        tvi, tia, pvibm, tibm);
-
-            return count - 2;
-        }
-
-        public static void ComputeStraightVertices(
-                this int[] via, V3d[] va, double absoluteEpsilon,
-                V3d[] normalizedEdgeArray, bool[] straightArray)
-        {
-            int count = via.Length;
-            if (straightArray == null) throw new ArgumentNullException();
-            if (count <= 2) throw new ArgumentException();
-            if (straightArray.Length != count) throw new ArgumentException();
-            if (normalizedEdgeArray != null && normalizedEdgeArray.Length != count) throw new ArgumentException();
-
-            double eps2 = absoluteEpsilon * absoluteEpsilon;
-
-            V3d[] ea = new V3d[count];
-            int oi = count - 1;
-            var oldVertex = va[via[oi]];
-
-            for (int i = 0; i < count; i++)
-            {
-                var vertex = va[via[i]];
-                ea[oi] = vertex - oldVertex;
-                oi = i; oldVertex = vertex;
-            }
-
-            oi = count - 1;
-            var oldEdge = ea[oi];
-
-            for (int i = 0; i < count; i++)
-            {
-                var edge = ea[i];
-                var normalizedEdge = oldEdge.Normalized;
-                if (normalizedEdgeArray != null)
-                    normalizedEdgeArray[oi] = normalizedEdge;
-                straightArray[i] = normalizedEdge.Cross(edge).LengthSquared < eps2;
-                oi = i; oldEdge = edge;
-            }
-        }
-
-        /// <summary>
-        ///
-        /// </summary>
-        /// <returns>Triangle count.</returns>
-        public static int ComputeTriangulationOfNonConcavePolygon(
-                this V3d[] va, int[] via, double absoluteEpsilon,
-                int ftvi, int[] tia, int[] pvibm = null, int[] tibm = null)
-        {
-            int count = via.Length;
-            var straightArray = new bool[count];
-            var normalizedEdgeArray = new V3d[count];
-
-            via.ComputeStraightVertices(va, absoluteEpsilon,
-                    normalizedEdgeArray, straightArray);
-
-            var ia = new int[count].SetByIndex(i => i);
-
-            return ia.ComputeTriangulationOfNonConcavePolygon(
-                    via, va, normalizedEdgeArray, straightArray,
-                    ftvi, tia, pvibm, tibm);
-        }
-
-        public static int[] ComputeTriangulationOfNonConcavePolygons(
-                this V3d[] vertexArray, List<int[]> nonConcavePolyList,
-                double absoluteEpsilon)
-        {
-            int tc = nonConcavePolyList.Sum(p => p.Length - 2);
-            var tia = new int[tc];
-            tc = 0;
-            foreach (var pia in nonConcavePolyList)
-            {
-                tc += 3 * vertexArray.ComputeTriangulationOfNonConcavePolygon(
-                                        pia, absoluteEpsilon, tc, tia);
-            }
-            return tia;
-        }
-
-        #endregion
-
-        #region Triangulation of Concave Polygons
-
-        /// <summary>
-        /// Compute the triangulation of the supplied concave polygon and put
-        /// the triangle vertex indices into the supplied array starting at
-        /// the supplied triangle vertex index.
-        /// </summary>
-        /// <returns>the number of triangles in the triangulation</returns>
-        private static int ComputeTriangulationOfConcavePolygon(
-                this Polygon3d polygon, double absoluteEpsilon,
-                int triangleVertexIndex, int[] triangleIndexArray)
-        {
-            var polyList = polygon.ComputeNonConcaveSubPolygons(absoluteEpsilon);
-
-            foreach (var pia in polyList)
-            {
-                int tc = polygon.GetPointArray().ComputeTriangulationOfNonConcavePolygon(
-                                            pia, absoluteEpsilon, triangleVertexIndex,
-                    triangleIndexArray);
-                triangleVertexIndex += 3 * tc;
-            }
-            return polygon.PointCount - 2;
-        }
-
-        /// <summary>
-        /// Compute the triangulation of the supplied concave polygon and
-        /// return the resulting triangle index array.
-        /// </summary>
-        public static int[] ComputeTriangulationOfConcavePolygon(
-                this Polygon3d polygon, double absoluteEpsilon)
-        {
-            int[] triangleIndexArray = new int[3 * (polygon.PointCount - 2)];
-            polygon.ComputeTriangulationOfConcavePolygon(
-                        absoluteEpsilon, 0, triangleIndexArray);
-            return triangleIndexArray;
-        }
-
-        /// <summary>
-        /// Compute the triangulation of the concave polygons supplied in
-        /// the arrays with PolyMesh layout, and return the resulting
-        /// triangle index array.
-        /// </summary>
-        public static int[] ComputeTriangulationOfConcavePolygons(
-                this V3d[] vertexArray, int polyCount,
-                V3d[] normalArray, int[] firstIndices, int[] vertexIndices,
-                double absoluteEpsilon)
-        {
-            var polyList = vertexArray.ComputeNonConcaveSubPolygons(
-                                polyCount, normalArray, firstIndices,
-                                vertexIndices, null, absoluteEpsilon);
-            return vertexArray.ComputeTriangulationOfNonConcavePolygons(
-                                polyList, absoluteEpsilon);
-        }
-
-        #endregion
-    }
-
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Aardvark.Base
+{
+    /// <summary>
+    /// Provides various methods determining parallelism
+    /// </summary>
+    public static class Parallelism
+    {
+        // 2-Dimensional
+
+        #region V2d - V2d
+
+        public static bool IsParallelTo(this V2d u, V2d v)
+        {
+            return Fun.IsTiny(u.X * v.Y - u.Y * v.X);
+        }
+
+        public static bool IsParallelTo(this V2d u, V2d v, double epsilon = 0.01)
+        {
+            var dirDifference = (u.Normalized - v.Normalized).Length;
+            return (dirDifference < epsilon || dirDifference > (2 - epsilon)) ? true : false;
+        }
+
+        #endregion
+
+        #region Ray2d - V2d
+
+        public static bool IsParallelTo(this Ray2d ray, V2d v)
+        {
+            return ray.Direction.IsParallelTo(v);
+        }
+
+        public static bool IsParallelTo(this Ray2d ray, V2d v, double epsilon = 0.01)
+        {
+            return ray.Direction.IsParallelTo(v, epsilon);
+        }
+
+        #endregion
+
+        #region Ray2d - Ray2d
+
+        public static bool IsParallelTo(this Ray2d r0, Ray2d r1)
+        {
+            return r0.Direction.IsParallelTo(r1.Direction);
+        }
+
+        public static bool IsParallelTo(this Ray2d r0, Ray2d r1, double epsilon = 0.01)
+        {
+            return r0.Direction.IsParallelTo(r1.Direction, epsilon);
+        }
+
+        #endregion
+
+        #region Line2d - Line2d
+
+        public static bool IsParallelTo(this Line2d l0, Line2d l1)
+        {
+            return l0.Direction.IsParallelTo(l1.Direction);
+        }
+
+        public static bool IsParallelTo(this Line2d l0, Line2d l1, double epsilon = 0.01)
+        {
+            return l0.Direction.IsParallelTo(l1.Direction, epsilon);
+        }
+
+        #endregion
+
+        // 3-Dimensional
+
+        #region V3d - V3d
+
+        public static bool IsParallelTo(this V3d u, V3d v)
+        {
+            return Fun.IsTiny(u.Cross(v).Norm1);
+        }
+
+        #endregion
+
+        #region Ray3d - V3d
+
+        public static bool IsParallelTo(this Ray3d ray, V3d vec)
+        {
+            return ray.Direction.IsParallelTo(vec);
+        }
+
+        #endregion
+
+        #region Ray3d - Ray3d
+
+        public static bool IsParallelTo(this Ray3d r0, Ray3d r1)
+        {
+            return r0.Direction.IsParallelTo(r1.Direction);
+        }
+
+        #endregion
+
+        #region Plane3d - Plane3d
+
+        public static bool IsParallelTo(this Plane3d p0, Plane3d p1)
+        {
+            return p0.Normal.IsParallelTo(p1.Normal);
+        }
+
+        #endregion
+
+        #region Ray3d - Plane3d
+
+        public static bool IsParallelTo(this Ray3d ray, Plane3d plane)
+        {
+            return ray.Direction.IsOrthogonalTo(plane.Normal);
+        }
+
+        public static bool IsParallelTo(this Plane3d plane , Ray3d ray)
+        {
+            return ray.Direction.IsOrthogonalTo(plane.Normal);
+        }
+
+        #endregion
+
+        #region Line3d - Line3d
+
+        public static bool IsParallelTo(this Line3d l0, Line3d l1)
+        {
+            return l0.Direction.IsParallelTo(l1.Direction);
+        }
+
+        #endregion
+    }
+
+    /// <summary>
+    /// Provides various methods determining normalism
+    /// </summary>
+    public static class Otrthogonalism
+    {
+        // 2-Dimensional
+
+        #region V2d - V2d
+
+        public static bool IsOrthogonalTo(this V2d u, V2d v)
+        {
+            return Fun.IsTiny(u.Dot(v));
+        }
+
+        #endregion
+
+        #region Ray2d - V2d
+
+        public static bool IsOrthogonalTo(this Ray2d ray, V2d v)
+        {
+            return ray.Direction.IsOrthogonalTo(v);
+        }
+
+        #endregion
+
+        #region Ray2d - Ray2d
+
+        public static bool IsOrthogonalTo(this Ray2d r0, Ray2d r1)
+        {
+            return r0.Direction.IsOrthogonalTo(r1.Direction);
+        }
+
+        #endregion
+
+        // 3-Dimensional
+
+        #region V3d - V3d
+
+        public static bool IsOrthogonalTo(this V3d u, V3d v)
+        {
+            return Fun.IsTiny(u.Dot(v));
+        }
+
+        #endregion
+
+        #region Ray3d - V3d
+
+        public static bool IsOrthogonalTo(this Ray3d ray, V3d vec)
+        {
+            return ray.Direction.IsOrthogonalTo(vec);
+        }
+
+        #endregion
+
+        #region Ray3d - Ray3d
+
+        public static bool IsOrthogonalTo(this Ray3d r0, Ray3d r1)
+        {
+            return r0.Direction.IsOrthogonalTo(r1.Direction);
+        }
+
+        #endregion
+
+        #region Plane3d - Plane3d
+
+        public static bool IsOrthogonalTo(this Plane3d p0, Plane3d p1)
+        {
+            return p0.Normal.IsOrthogonalTo(p1.Normal);
+        }
+
+        #endregion
+
+        #region Ray3d - Plane3d
+
+        public static bool IsOrthogonalTo(this Ray3d ray, Plane3d plane)
+        {
+            return ray.Direction.IsParallelTo(plane.Normal);
+        }
+
+        public static bool IsNormalTo(this Plane3d plane, Ray3d ray)
+        {
+            return ray.Direction.IsParallelTo(plane.Normal);
+        }
+
+        #endregion
+    }
+
+    public static class LinearCombination
+    {
+        #region V3d - V3d
+
+        public static bool IsLinearCombinationOf(this V3d x, V3d u, V3d v)
+        {
+            V3d n = u.Cross(v);
+            return n.IsOrthogonalTo(x);
+        }
+
+        public static bool IsLinearCombinationOf(this V3d x, V3d u)
+        {
+            return x.IsParallelTo(u);
+        }
+
+        public static bool IsLinearCombinationOf(this V3d x, V3d u, V3d v, out double t0, out double t1)
+        {
+            //x == t2*u + t1*v
+            V3d n = u.Cross(v);
+
+            double[,] mat = new double[3, 3]
+            {
+                {u.X,v.X,n.X},
+                {u.Y,v.Y,n.Y},
+                {u.Z,v.Z,n.Z}
+            };
+
+            double[] result = new double[3]{x.X,x.Y,x.Z};
+
+            int[] perm = mat.LuFactorize();
+            V3d t = new V3d(mat.LuSolve(perm,result));
+
+            if (Fun.IsTiny(t.Z))
+            {
+                t0 = t.X;
+                t1 = t.Y;
+
+                return true;
+            }
+            else
+            {
+                t0 = double.NaN;
+                t1 = double.NaN;
+
+                return false;
+            }
+
+            //x ==
+        }
+
+        #endregion
+    }
+
+    public static class GeometricProperties
+    {
+        #region Degenerated parts of a Polygon2d
+
+        #region Polygon2d-Extensions
+
+        /// <summary>
+        /// Returns true if the Polygon contains a degenerated part
+        /// </summary>
+        public static bool HasDegeneratedPart(this Polygon2d poly)
+        {
+            return poly.PolygonHasDegeneratedPart();
+        }
+
+        /// <summary>
+        /// Returns true if the Polygon contains a degenerated part
+        /// </summary>
+        public static bool HasDegeneratedPart(this Polygon2d poly, double absoluteEpsilon)
+        {
+            return poly.PolygonHasDegeneratedPart(absoluteEpsilon);
+        }
+
+        /// <summary>
+        /// Returns true if the Polygon contains a degenerated part
+        /// NonDegenerated holds the Non-Degenerated part of the polygon
+        /// </summary>
+        public static bool HasDegeneratedPart(this Polygon2d poly, out Polygon2d NonDegenerated)
+        {
+            int[] temp;
+            bool result = poly.PolygonHasDegeneratedPart(out temp);
+
+            NonDegenerated = new Polygon2d((from i in temp select poly[i]).ToArray<V2d>());
+            return result;
+        }
+
+        /// <summary>
+        /// Returns true if the Polygon contains a degenerated part
+        /// NonDegenerated holds the Non-Degenerated part of the polygon
+        /// </summary>
+        public static bool HasDegeneratedPart(this Polygon2d poly, out int[] NonDegenerated)
+        {
+            return poly.PolygonHasDegeneratedPart(out NonDegenerated);
+        }
+
+        /// <summary>
+        /// Returns true if the Polygon contains a degenerated part
+        /// NonDegenerated holds the Non-Degenerated part of the polygon
+        /// </summary>
+        public static bool HasDegeneratedPart(this Polygon2d poly, double absoluteEpsilon, out int[] NonDegenerated)
+        {
+            return poly.PolygonHasDegeneratedPart(absoluteEpsilon, out NonDegenerated);
+        }
+
+        #endregion
+
+        #region V2d[]-Extension
+
+        /// <summary>
+        /// Returns true if the Polygon contains a degenerated part
+        /// </summary>
+        public static bool PolygonHasDegeneratedPart(this Polygon2d poly)
+        {
+            return poly.PolygonHasDegeneratedPart(4.0 * double.Epsilon);
+        }
+
+        /// <summary>
+        /// Returns true if the Polygon contains a degenerated part
+        /// </summary>
+        public static bool PolygonHasDegeneratedPart(this Polygon2d poly, double absoluteEpsilon)
+        {
+            if (absoluteEpsilon < 0.0) throw new ArgumentOutOfRangeException();
+
+            int i = 0;
+            int count = poly.PointCount;
+
+            V2d e0;
+            V2d e1;
+
+            double l0 = 0.0;
+            double l1 = 0.0;
+
+            while (i < count - 1)
+            {
+                if ((poly[i + 1] - poly[i]).Length < absoluteEpsilon) return true;
+
+                e0 = (poly[i + 1] - poly[i]);
+                e1 = (poly[(i + 2) % count] - poly[i + 1]);
+
+                l0 = e0.Length;
+                l1 = e1.Length;
+
+                e0 = e0 / l0;
+                //e1 = e1 / l1;
+
+                if ((e0.X*e1.Y - e0.Y*e1.X).Abs() > absoluteEpsilon) return true;
+            }
+
+            return false;
+        }
+
+        /// <summary>
+        /// Returns true if the Polygon contains a degenerated part
+        /// NonDegenerated holds the Non-Degenerated part of the polygon
+        /// </summary>
+        public static bool PolygonHasDegeneratedPart(this Polygon2d poly, out int[] NonDegenerated)
+        {
+            return poly.PolygonHasDegeneratedPart(4.0 * double.Epsilon, out NonDegenerated);
+        }
+
+        /// <summary>
+        /// Returns true if the Polygon contains a degenerated part
+        /// NonDegenerated holds the Non-Degenerated part of the polygon
+        /// </summary>
+        public static bool PolygonHasDegeneratedPart(this Polygon2d poly, double absoluteEpsilon, out int[] NonDegenerated)
+        {
+            if (absoluteEpsilon < 0.0) throw new ArgumentOutOfRangeException();
+
+            int i = 0;
+            int u = 1;
+            int start = 0;
+            V2d e0;
+            V2d e1;
+            bool found = false;
+            int count = poly.PointCount;
+
+            List<int> newPoints = new List<int>();
+            newPoints.Add(0);
+
+            double l0 = 0.0;
+
+
+            while (i < count - 1)
+            {
+                e0 = (poly[i + 1] - poly[i]);
+                l0 = e0.Length;
+
+                e0 = e0 / l0;
+
+
+
+                u = i + 1;
+                V2d e = poly[(u + 1) % count] - poly[u];
+                while (
+                    (((e0.X*e.Y - e0.Y*e.X).Abs() < absoluteEpsilon && e.Dot(e0) > 0.0) ||
+                    (poly[(u + 1) % count] - poly[i + 1]).Length < absoluteEpsilon)
+                    && u < count - 1)
+                {
+                    if ((poly[(u + 1) % count] - poly[i + 1]).Length < absoluteEpsilon) found = true;
+
+                    u++;
+                    e0 = (poly[u] - poly[i]).Normalized;
+                    e = poly[(u + 1) % count] - poly[u];
+                }
+                u--;
+
+                start = u;
+
+                do
+                {
+                    u++;
+                    e1 = (poly[(u + 1) % count] - poly[u]);
+                }
+                while (u < count && ((e0.X * e1.Y - e0.Y * e1.X).Abs() < absoluteEpsilon && e.Dot(e0) < 0.0));
+
+                if (u != start + 1) found = true;
+
+                newPoints.Add(u);
+
+                i = u;
+            }
+
+            NonDegenerated = newPoints.ToArray();
+            return found;
+        }
+
+        #endregion
+
+        #endregion
+    }
+
+    public static class SubPrimitives
+    {
+        #region Triangulation of Convex Polygons
+
+        /// <summary>
+        /// Compute a simple triangulation starting from the first point of
+        /// the polygon. Note that the indices are twice indirect (once over
+        /// pia, once over via). Returns the number of triangles (ie. two
+        /// less than the length of the array pia).
+        /// </summary>
+        public static int ComputeSimpleTriangulation(
+                this int[] pia, int[] via, int tvi, int[] tia, int[] pvibm, int[] tibm)
+        {
+            int fi = pia[0], fvi = via[fi];
+            int i1 = pia[1], vi1 = via[i1];
+            int count = pia.Length;
+            for (int ii = 2; ii < count; ii++)
+            {
+                int vi0 = vi1, i0 = i1;
+                vi1 = via[i1 = pia[ii]];
+                tia[tvi] = fvi;
+                tia[tvi + 1] = vi0;
+                tia[tvi + 2] = vi1;
+                if (tibm != null)
+                {
+                    tibm[tvi] = pvibm[fi];
+                    tibm[tvi + 1] = pvibm[i0];
+                    tibm[tvi + 2] = pvibm[i1];
+                }
+                tvi += 3;
+            }
+            return count - 2;
+        }
+
+        #endregion
+
+        #region Non-Concave Sub-Polygons of a Polygon2d
+
+        private static int[] ComputeNonConcaveSubPolygon(
+                this Polygon2d poly, ref int[] indices, double absoluteEpsilon)
+        {
+            int count = indices.Length;
+
+            if (count <= 3)
+            {
+                var result = indices;
+                indices = new int[0];
+                return result;
+            }
+
+            Func<int, int> addFun = i => (i + 1) % count;
+            Func<int, int> subFun = i => (i + count - 1) % count;
+
+            for (int vi = 0; vi < count; vi++) // we possibly have to try all vertices
+            {
+                int nowMinIndex = vi, nowMaxIndex = vi;
+                var nowMinPoint = poly[indices[nowMinIndex]];
+                var nowMaxPoint = poly[indices[nowMaxIndex]];
+                var oldMinPoint = poly[indices[addFun(nowMinIndex)]];
+                var oldMaxPoint = poly[indices[subFun(nowMinIndex)]];
+                var subCount = 1;
+
+                bool add = true;
+
+                for (int pass = 0, goodPass = 0; pass - goodPass < 3; pass++, add = !add)
+                {
+                    // alternate between adding a point at the two ends
+                    var nextFun = add ? addFun : subFun;
+                    int lastIndex = add ? nowMinIndex : nowMaxIndex;
+
+                    int newIndex = add ? addFun(nowMaxIndex) : subFun(nowMinIndex);
+                    if (newIndex == lastIndex)
+                    {
+                        var finalIndices = indices;
+                        indices = new int[0];
+                        return finalIndices;
+                    }
+
+                    var newPoint = poly[indices[newIndex]];
+                    var pMax = new Line2d(oldMaxPoint, nowMaxPoint).Plane2d;
+                    var pMin = new Line2d(oldMinPoint, nowMinPoint).Plane2d;
+
+                    var npMax = pMax.Normalized;
+                    var npMin = pMin.Normalized;
+
+                    var hMax = new Line2d(oldMaxPoint, nowMaxPoint).Plane2d.Normalized.Height(newPoint);
+                    var hMin = new Line2d(oldMinPoint, nowMinPoint).Plane2d.Normalized.Height(newPoint);
+
+                    if (hMax >= -absoluteEpsilon && hMin <= absoluteEpsilon)
+                    {
+                        bool good = true;
+                        if (nowMinIndex != nowMaxIndex)
+                        {
+                            var plane0 = new Line2d(nowMinPoint, nowMaxPoint).Plane2d.Normalized;
+                            var plane1 = new Line2d(nowMaxPoint, newPoint).Plane2d.Normalized;
+                            var plane2 = new Line2d(newPoint, nowMinPoint).Plane2d.Normalized;
+
+                            // check if new triangle does not contain any other points of the polygon
+                            for (int i = nextFun(newIndex); i != lastIndex; i = nextFun(i))
+                            {
+                                var point = poly[indices[i]];
+                                if (plane0.Height(point) > -absoluteEpsilon
+                                    && plane1.Height(point) >= absoluteEpsilon
+                                    && plane2.Height(point) >= absoluteEpsilon)
+                                { good = false; break; }
+                            }
+                        }
+                        if (good)
+                        {
+                            if (add)
+                            {
+                                nowMaxIndex = newIndex; oldMaxPoint = nowMaxPoint; nowMaxPoint = newPoint;
+                            }
+                            else
+                            {
+                                nowMinIndex = newIndex; oldMinPoint = nowMinPoint; nowMinPoint = newPoint;
+                            }
+                            goodPass = pass;
+                            ++subCount;
+                        }
+                    }
+                }
+                if (subCount < 3) continue;
+
+                // build new arrays here
+
+                var subIndices = new int[subCount];
+                for (int i = 0, ni = nowMinIndex; i < subCount; i++, ni = addFun(ni))
+                    subIndices[i] = indices[ni];
+                int newCount = 2 + count - subCount;
+                var newIndices = new int[newCount];
+                for (int i = 0, ni = nowMaxIndex; i < newCount; i++, ni = addFun(ni))
+                    newIndices[i] = indices[ni];
+
+                indices = newIndices;
+                return subIndices;
+            }
+            return null;
+        }
+
+        public static void AddNonConcaveSubPolygons(
+                this List<int[]> polygonList, Polygon2d poly,
+                double absoluteEpsilon)
+        {
+            var indices = new int[poly.PointCount].SetByIndex(i => i);
+            while (indices.Length > 0)
+            {
+                var subPoly = poly.ComputeNonConcaveSubPolygon(
+                                    ref indices, absoluteEpsilon);
+                if (subPoly.Length < 3)
+                {
+                    Console.WriteLine("encountered invalid subpolygon");
+                    continue;
+                }
+                polygonList.Add(subPoly);
+            }
+        }
+
+        public static List<int[]> ComputeNonConcaveSubPolygons(
+                this Polygon2d polygon, double absoluteEpsilon)
+        {
+            var polygonList = new List<int[]>();
+            polygonList.AddNonConcaveSubPolygons(polygon, absoluteEpsilon);
+            return polygonList;
+        }
+
+        #endregion
+
+        #region Non-Concave Sub-Polygons of Polygons in 3d
+
+        public static List<int[]> ComputeNonConcaveSubPolygons(
+                this Polygon3d polygon, double absoluteEpsilon)
+        {
+            V3d normal = polygon.ComputeDoubleAreaNormal();
+            double len2 = normal.LengthSquared;
+
+            if (len2 < absoluteEpsilon * absoluteEpsilon)
+                return new int[polygon.PointCount].SetByIndex(i => i).IntoList();
+
+            M44d local2global, global2local;
+            M44d.NormalFrame(V3d.Zero, normal * (1.0/Fun.Sqrt(len2)), out local2global, out global2local);
+            var polygon2d = polygon.ToPolygon2d(p => global2local.TransformPos(p).XY);
+            return polygon2d.ComputeNonConcaveSubPolygons(absoluteEpsilon);
+        }
+
+        public static List<int[]> ComputeNonConcaveSubPolygons(
+                this V3d[] vertexArray, int polyCount,
+                V3d[] normalArray, int[] firstIndices, int[] vertexIndices,
+                List<int> faceBackMap,
+                double absoluteEpsilon)
+        {
+            var polyList = new List<int[]>();
+            var eps2 = absoluteEpsilon * absoluteEpsilon;
+
+            for (int fvi = 0, fi = 0; fi < polyCount; fi++)
+            {
+                int fve = firstIndices[fi+1], fvc = fve - fvi;
+                var n = normalArray[fi];
+                var l2 = n.LengthSquared;
+                if (l2 < eps2)
+                {
+                    polyList.Add(new int[fvc].SetByIndex(i => vertexIndices[fvi + i]));
+                    continue;
+                }
+                M44d local2global, global2local;
+                M44d.NormalFrame(V3d.Zero, n, out local2global, out global2local);
+                var polygon = new Polygon2d(fvc,
+                        i => global2local.TransformPos(vertexArray[vertexIndices[fvi + i]]).XY);
+                var subPolyList = polygon.ComputeNonConcaveSubPolygons(absoluteEpsilon);
+                foreach (var poly in subPolyList)
+                    polyList.Add(poly.Copy(i => fvi + i));
+                if (faceBackMap != null)
+                    for (int i = 0; i < subPolyList.Count; i++)
+                        faceBackMap.Add(fi);
+                fvi = fve;
+            }
+
+            return polyList;
+        }
+
+        #endregion
+
+        #region Triangulation of Non-Concave Polygons in 3d
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <returns>Triangle count.</returns>
+        public static int ComputeTriangulationOfNonConcavePolygon(
+                this int[] ia, int[] via, V3d[] va, V3d[] edgeArray, bool[] straightArray,
+                int tvi, int[] tia, int[] pvibm, int[] tibm)
+        {
+            int count = ia.Length;
+
+            if (count < 3) throw new ArgumentOutOfRangeException();
+
+            if (count == 3)
+            {
+                tia[tvi] = via[ia[0]];
+                tia[tvi + 1] = via[ia[1]];
+                tia[tvi + 2] = via[ia[2]];
+                if (tibm != null)
+                {
+                    tibm[tvi] = pvibm[ia[0]];
+                    tibm[tvi + 1] = pvibm[ia[1]];
+                    tibm[tvi + 2] = pvibm[ia[2]];
+                }
+                return 1;
+            }
+
+            int ii = 0;
+
+            // search for the first non-straight corner
+            while (ii < ia.Length && straightArray[ia[ii]]) ii++;
+
+            int bii = ii; ii = (ii + 1) % count;
+
+            // search for first straight corner afterwards
+            while (ii != bii && !straightArray[ia[ii]]) ii = (ii + 1) % count;
+
+            if (ii == bii) // if there is no straight corner
+                return ia.ComputeSimpleTriangulation(via, tvi, tia, pvibm, tibm);
+            bii = ii; // first
+            int eii = ii;
+            int straightCount = 0;
+            while (straightArray[ia[ii]])
+            {
+                eii = ii; ii = (ii + 1) % count;
+                ++straightCount;
+            }
+
+            if (count - straightCount < 3) // numeric problem, cop out
+                return ia.ComputeSimpleTriangulation(via, tvi, tia, pvibm, tibm);
+
+            var hii = ii; double height = 0.0;
+            var li = ia[eii];
+            var edge = edgeArray[li];
+            var vertex = va[via[li]];
+
+            int rightCount = 2;
+            int rc = 2;
+            ii = (ii + 1) % count;
+            while (ii != bii)
+            {
+                int i = ia[ii];
+                var h = edge.Cross(va[via[i]] - vertex).LengthSquared;
+                ++rc;
+                if (h > height)
+                {
+                    height = h;
+                    hii = ii;
+                    rightCount = rc;
+                }
+                ii = (ii + 1) % count;
+            }
+
+            straightArray[ia[bii]] = false;
+            straightArray[ia[eii]] = false;
+            straightArray[ia[hii]] = false;
+
+            int leftCount = count - straightCount - rightCount + 3;
+
+            var lia = new int[leftCount];
+            ii = hii;
+            for (int lii = 0; lii < leftCount; lii++, ii = (ii + 1) % count)
+                lia[lii] = ia[ii];
+
+            if (leftCount > 2)
+                lia.ComputeTriangulationOfNonConcavePolygon(via, va, edgeArray, straightArray,
+                        tvi, tia, pvibm, tibm);
+
+            tvi += 3 * (leftCount - 2);
+
+            if (straightCount > 1)
+            {
+                int hi = ia[hii], hvi = via[hi];
+                int i1 = ia[bii], vi1 = via[i1];
+                ii = bii;
+                for (int sii = 0; sii < straightCount - 1; sii++)
+                {
+                    ii = (ii + 1) % count;
+                    int vi0 = vi1, i0 = i1;
+                    vi1 = via[i1 = ia[ii]];
+                    tia[tvi] = hvi;
+                    tia[tvi + 1] = vi0;
+                    tia[tvi + 2] = vi1;
+
+                    if (tibm != null)
+                    {
+                        tibm[tvi] = pvibm[hi];
+                        tibm[tvi + 1] = pvibm[i0];
+                        tibm[tvi + 2] = pvibm[i1];
+                    }
+                    tvi += 3;
+                }
+            }
+
+            var ria = new int[rightCount];
+            ii = eii;
+            for (int rii = 0; rii < rightCount; rii++, ii = (ii + 1) % count)
+                ria[rii] = ia[ii];
+
+            if (rightCount > 2)
+                ria.ComputeTriangulationOfNonConcavePolygon(via, va, edgeArray, straightArray,
+                        tvi, tia, pvibm, tibm);
+
+            return count - 2;
+        }
+
+        public static void ComputeStraightVertices(
+                this int[] via, V3d[] va, double absoluteEpsilon,
+                V3d[] normalizedEdgeArray, bool[] straightArray)
+        {
+            int count = via.Length;
+            if (straightArray == null) throw new ArgumentNullException();
+            if (count <= 2) throw new ArgumentException();
+            if (straightArray.Length != count) throw new ArgumentException();
+            if (normalizedEdgeArray != null && normalizedEdgeArray.Length != count) throw new ArgumentException();
+
+            double eps2 = absoluteEpsilon * absoluteEpsilon;
+
+            V3d[] ea = new V3d[count];
+            int oi = count - 1;
+            var oldVertex = va[via[oi]];
+
+            for (int i = 0; i < count; i++)
+            {
+                var vertex = va[via[i]];
+                ea[oi] = vertex - oldVertex;
+                oi = i; oldVertex = vertex;
+            }
+
+            oi = count - 1;
+            var oldEdge = ea[oi];
+
+            for (int i = 0; i < count; i++)
+            {
+                var edge = ea[i];
+                var normalizedEdge = oldEdge.Normalized;
+                if (normalizedEdgeArray != null)
+                    normalizedEdgeArray[oi] = normalizedEdge;
+                straightArray[i] = normalizedEdge.Cross(edge).LengthSquared < eps2;
+                oi = i; oldEdge = edge;
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <returns>Triangle count.</returns>
+        public static int ComputeTriangulationOfNonConcavePolygon(
+                this V3d[] va, int[] via, double absoluteEpsilon,
+                int ftvi, int[] tia, int[] pvibm = null, int[] tibm = null)
+        {
+            int count = via.Length;
+            var straightArray = new bool[count];
+            var normalizedEdgeArray = new V3d[count];
+
+            via.ComputeStraightVertices(va, absoluteEpsilon,
+                    normalizedEdgeArray, straightArray);
+
+            var ia = new int[count].SetByIndex(i => i);
+
+            return ia.ComputeTriangulationOfNonConcavePolygon(
+                    via, va, normalizedEdgeArray, straightArray,
+                    ftvi, tia, pvibm, tibm);
+        }
+
+        public static int[] ComputeTriangulationOfNonConcavePolygons(
+                this V3d[] vertexArray, List<int[]> nonConcavePolyList,
+                double absoluteEpsilon)
+        {
+            int tc = nonConcavePolyList.Sum(p => p.Length - 2);
+            var tia = new int[tc];
+            tc = 0;
+            foreach (var pia in nonConcavePolyList)
+            {
+                tc += 3 * vertexArray.ComputeTriangulationOfNonConcavePolygon(
+                                        pia, absoluteEpsilon, tc, tia);
+            }
+            return tia;
+        }
+
+        #endregion
+
+        #region Triangulation of Concave Polygons
+
+        /// <summary>
+        /// Compute the triangulation of the supplied concave polygon and put
+        /// the triangle vertex indices into the supplied array starting at
+        /// the supplied triangle vertex index.
+        /// </summary>
+        /// <returns>the number of triangles in the triangulation</returns>
+        private static int ComputeTriangulationOfConcavePolygon(
+                this Polygon3d polygon, double absoluteEpsilon,
+                int triangleVertexIndex, int[] triangleIndexArray)
+        {
+            var polyList = polygon.ComputeNonConcaveSubPolygons(absoluteEpsilon);
+
+            foreach (var pia in polyList)
+            {
+                int tc = polygon.GetPointArray().ComputeTriangulationOfNonConcavePolygon(
+                                            pia, absoluteEpsilon, triangleVertexIndex,
+                    triangleIndexArray);
+                triangleVertexIndex += 3 * tc;
+            }
+            return polygon.PointCount - 2;
+        }
+
+        /// <summary>
+        /// Compute the triangulation of the supplied concave polygon and
+        /// return the resulting triangle index array.
+        /// </summary>
+        public static int[] ComputeTriangulationOfConcavePolygon(
+                this Polygon3d polygon, double absoluteEpsilon)
+        {
+            int[] triangleIndexArray = new int[3 * (polygon.PointCount - 2)];
+            polygon.ComputeTriangulationOfConcavePolygon(
+                        absoluteEpsilon, 0, triangleIndexArray);
+            return triangleIndexArray;
+        }
+
+        /// <summary>
+        /// Compute the triangulation of the concave polygons supplied in
+        /// the arrays with PolyMesh layout, and return the resulting
+        /// triangle index array.
+        /// </summary>
+        public static int[] ComputeTriangulationOfConcavePolygons(
+                this V3d[] vertexArray, int polyCount,
+                V3d[] normalArray, int[] firstIndices, int[] vertexIndices,
+                double absoluteEpsilon)
+        {
+            var polyList = vertexArray.ComputeNonConcaveSubPolygons(
+                                polyCount, normalArray, firstIndices,
+                                vertexIndices, null, absoluteEpsilon);
+            return vertexArray.ComputeTriangulationOfNonConcavePolygons(
+                                polyList, absoluteEpsilon);
+        }
+
+        #endregion
+    }
+
+}


format using block

format using block

--- src/Abp/Runtime/Caching/AbpCacheBase.cs
+++ src/Abp/Runtime/Caching/AbpCacheBase.cs
@@ -43,7 +43,7 @@

             if (item == null)
             {
-                using(AsyncLock.Lock())
+                using (AsyncLock.Lock())
                 {
                     try
                     {


Fix to ScaledELU in benchmarks project.

Fix to ScaledELU in benchmarks project.

--- src/ActivationFnBenchmarks/Functions.cs
+++ src/ActivationFnBenchmarks/Functions.cs
@@ -229,7 +229,7 @@
             double scale = 1.0507009873554804934193349852946;

             double y;
-            if(x > 0) {
+            if(x >= 0) {
                 y = scale*x;
             }
             else {


Fix multidimensional slicing setting with specified endpoint

--- src/Boo.Lang/Runtime/RuntimeServices.cs
+++ src/Boo.Lang/Runtime/RuntimeServices.cs
@@ -594,78 +594,91 @@

 			for (int i = 0; i < dest.Rank; i++)
 			{
-				if (ranges[2 * i] > 0 ||
-					ranges[2 * i] > dest.GetLength(i) ||
+				if (ranges[2 * i] < 0 ||
+					ranges[2 * i] >= dest.GetLength(i) ||
 					ranges[2 * i + 1] > dest.GetLength(i) ||
-					ranges[2 * i + 1] < ranges[2 * i])
+					ranges[2 * i + 1] <= ranges[2 * i])
 				{
 					// FIXME: Better error reporting
 					throw new ApplicationException("Invalid array.");
 				}
 			}

-			int sourceRank = 0;
+			int destSubsetRank = 0;
 			foreach (bool val in collapse)
 			{
 				if (!val)
 				{
-					sourceRank++;
-				}
-			}
-
-			if (source.Rank != sourceRank)
-			{
-				// FIXME: Better error reporting
-				throw new ApplicationException("Invalid array.");
-			}
-
-			int[] lensDest = new int[dest.Rank];
-			int[] lensSrc = new int[sourceRank];
+					destSubsetRank++;
+				}
+			}
+            if (destSubsetRank == 0)
+                destSubsetRank = 1;
+
+			if (source.Rank != destSubsetRank)
+			{
+				throw new ApplicationException(String.Format("Cannot assign array of rank {0} into an array subset of rank {1}.",source.Rank,destSubsetRank));
+			}
+
+            int[] lensDest = new int[dest.Rank];
+			int[] lensDestSubset = new int[destSubsetRank];
+			int[] lensSrc = new int[source.Rank];
 			int rankIndex = 0;
+            bool length_mismatch = false;
 			for (int i = 0; i < dest.Rank; i++)
 			{
 				lensDest[i] = ranges[2 * i + 1] - ranges[2 * i];
 				if (!collapse[i])
 				{
-					lensSrc[rankIndex] = lensDest[i] - ranges[2 * i];
-					if (lensSrc[rankIndex] != source.GetLength(rankIndex))
+                    lensDestSubset[rankIndex] = lensDest[i];
+                    lensSrc[rankIndex] = source.GetLength(rankIndex);
+					if (lensSrc[rankIndex] != lensDest[i])
 					{
-						// FIXME: Better error reporting
-						throw new ApplicationException("Invalid array.");
+                        length_mismatch = true;
 					}
 					rankIndex++;
 				}
 			}

-			int[] modInd = new int[dest.Rank];
-			for (int i = 0; i < dest.Rank; i++)
-			{
-				if (i == 0)
-				{
-					modInd[i] = source.Length / lensDest[lensDest.Length - 1];
-				}
-				else
-				{
-					modInd[i] = modInd[i - 1] / lensDest[i - 1];
-				}
-			}
+            if (length_mismatch)
+            {
+                StringBuilder source_dims = new StringBuilder(lensSrc[0]);
+                StringBuilder dest_subset_dims = new StringBuilder(lensDestSubset[0]);
+                for (int i = 1; i < source.Rank; i++)
+                {
+                    source_dims.Append(" x ");
+                    source_dims.Append(lensSrc[i]);
+
+                    dest_subset_dims.Append(" x ");
+                    dest_subset_dims.Append(lensDestSubset[i]);
+                }
+                throw new ApplicationException(String.Format("Cannot assign array with dimensions {0} into array subset of dimensions {1}.",source_dims.ToString(),dest_subset_dims.ToString()));
+            }
+
+			int[] prodInd = new int[source.Rank];
+            prodInd[0] = lensSrc[0];
+			for (int i = 1; i < source.Rank; i++)
+				prodInd[i] = prodInd[i - 1]*lensSrc[i];

 			int[] indexDest = new int[dest.Rank];
-			int[] indexSrc = new int[sourceRank];
+			int[] indexSrc = new int[source.Rank];
 			for (int i = 0; i < source.Length; i++)
 			{
 				int counter = 0;
 				for (int j = 0; j < dest.Rank; j++)
 				{
-					int index = (i % modInd[j]) / (modInd[j] / lensDest[j]);
-					indexDest[j] = index;
-					if (!collapse[j])
+                    if (collapse[j])
+                    {
+                        indexDest[j] = ranges[2 * j];
+                    }
+					else
 					{
-						indexSrc[counter] = indexDest[j] + ranges[2 * j];
+                        indexSrc[counter] = i % prodInd[counter];
+                        indexDest[j] = indexSrc[counter] + ranges[2 * j];
 						counter++;
 					}
-					dest.SetValue(source.GetValue(indexSrc), indexDest);
-				}
+				}
+                dest.SetValue(source.GetValue(indexSrc), indexDest);
 			}
 		}


Form1:Tooltip:Recalculate the position thats poping out

--- kagv/Form1.cs
+++ kagv/Form1.cs
@@ -213,20 +213,26 @@

                                 clickedBox = m_rectangles[widthTrav][heightTrav];
                             }
-
+                            tp.ToolTipIcon = ToolTipIcon.Info;
                             if (isPathBlock && pos != null)
+                            {
                                 isPath = "Is part of path:Yes\r\n";
+                                tp.Show(currentBoxType + currentBoxCoords + currentBoxIndex + isPath
+                                    , this
+                                    , clickedBox.boxRec.X
+                                    , clickedBox.boxRec.Y - topBarOffset + 17);
+                                isBorder = false;
+                            }
                             else
                             {
                                 isPath = "Is part of path:No\r\n";
-                                clickedBox = new GridBox(e.X - 10, e.Y - 7, BoxType.Normal);
-                            }
-                            tp.ToolTipIcon = ToolTipIcon.Info;
-                            tp.Show(currentBoxType + currentBoxCoords + currentBoxIndex + isPath
-                            , this
-                            , clickedBox.boxRec.X
-                            , clickedBox.boxRec.Y - topBarOffset - 7);
-                            isBorder = false;
+                                clickedBox = new GridBox(e.X, e.Y, BoxType.Normal);
+                                tp.Show(currentBoxType + currentBoxCoords + currentBoxIndex + isPath
+                                    , this
+                                    , clickedBox.boxRec.X - 10
+                                    , clickedBox.boxRec.Y - topBarOffset + 12);
+                                isBorder = false;
+                            }
                         }
                     }
                 }
@@ -237,7 +243,7 @@
                     tp.Show(currentBoxType + currentBoxCoords + currentBoxIndex + isPath
                                , this
                                , e.X - 8
-                               , e.Y - topBarOffset - 14);
+                               , e.Y - topBarOffset + 14);
                 }

             }


Update flag for XSetWMNormalHints

Update flag for XSetWMNormalHints

That small change can fix bug with StartupLocation on Ubuntu. (https://stackoverflow.com/questions/11069666/cannot-get-xcreatesimplewindow-to-open-window-at-the-right-position)


Update demo.

Update demo.


構造体メンバ定義

構造体メンバ定義


removed unneeded intialization

removed unneeded intialization

--- TCC.Core/WindowManager.cs
+++ TCC.Core/WindowManager.cs
@@ -184,7 +184,6 @@
             {
                 SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher));
                 BossGauge = new BossGageWindow();
-                BossGageWindowViewModel.Instance.CurrentNPCs = new SynchronizedObservableCollection<Data.Boss>(BossGauge.Dispatcher);
                 BossGauge.Show();
                 waiting = false;


Initial check-in.

Initial check-in.

--- TDAmeritrade/TDAClient.cs
+++ TDAmeritrade/TDAClient.cs
@@ -8,18 +8,16 @@
 namespace TDAmeritrade
 {
     using System;
+    using System.Collections.ObjectModel;
     using System.Diagnostics.Contracts;
     using System.Linq;
     using System.Net;
-    using System.Reflection;
-    using System.Runtime.Serialization;
     using System.Text;
     using System.Threading.Tasks;
     using System.Xml.Linq;

     using TDAmeritrade.Infrastructure;
     using TDAmeritrade.Models;
-    using System.Collections.ObjectModel;

     /// <summary>
     /// TD Ameritrade client library which provides methods for sending data to and


The bottom thing should be a comma, not a period

--- TGS.ControlPanel/Login.cs
+++ TGS.ControlPanel/Login.cs
@@ -50,13 +50,13 @@
 			switch (start) {
 				case 1:
 					IPComboBox.Text = "";
-					goto case 2:
+					goto case 2;
 				case 2:
 					PortSelector.Value = 38607;
-					goto case 3:
+					goto case 3;
 				case 3:
 					UsernameTextBox.Text = "";
-					goto case 4:
+					goto case 4;
 				case 4:
 					if (currentLoginInfo.HasPassword)
 						PasswordTextBox.Text = "";


Free the returned value from leveldb_get

This fixes #2

--- Native.cs
+++ Native.cs
@@ -139,6 +139,7 @@
                 return null;
             }
             var value = Marshal.PtrToStringAnsi(valuePtr, (int) valueLength);
+            leveldb_free(valuePtr);
             return value;
         }


chg: mark as obsolete

chg: mark as obsolete

--- Visma.net/VismaNet.cs
+++ Visma.net/VismaNet.cs
@@ -25,20 +25,24 @@
         public readonly InventoryData Inventory;
         public readonly FinAccountData Account;
         public readonly EmployeeData Employee;
-        public readonly CreditNoteData CreditNote;
+
         public readonly ShipmentData Shipment;
         public readonly ContactData Contact;
         public readonly ProjectData Project;
         public readonly SalesOrderData SalesOrder;
         public readonly JournalTransactionData JournalTransaction;
-        [Obsolete("Payment is deprecated, please use CustomerPayment instead.")]
-        public readonly PaymentData Payment;
+
         public readonly BranchData Branch;
         public readonly WarehouseData Warehouse;
         public readonly LocationData Location;
         public readonly SubaccountData Subaccount;
+        public readonly CustomerPaymentData CustomerPayment;

-        public readonly CustomerPaymentData CustomerPayment;
+        // Obsolete endpoints
+        [Obsolete("Payment is deprecated, please use CustomerPayment instead.")]
+        public readonly PaymentData Payment;
+        [Obsolete("Method is deprecated start using the new method in endpoint Customer Credit Note")]
+        public readonly CreditNoteData CreditNote;

         /// <summary>
         ///     Creates a connection using token.


Use specified API key for symbol server.
Work items: 959

--HG--
branch : 1.2oob

--- src/CommandLine/Commands/PushCommand.cs
+++ src/CommandLine/Commands/PushCommand.cs
@@ -47,7 +47,7 @@
                     source = GalleryServer.DefaultSymbolServerUrl;

                     // See if the api key exists
-                    string apiKey = GetApiKey(source, configOnly: true, throwIfNotFound: false);
+                    string apiKey = GetApiKey(source, throwIfNotFound: false);

                     if (String.IsNullOrEmpty(apiKey)) {
                         Console.WriteWarning(NuGetResources.Warning_SymbolServerNotConfigured, Path.GetFileName(symbolPackagePath), NuGetResources.DefaultSymbolServer);
@@ -96,14 +96,12 @@
             }
         }

-        private string GetApiKey(string source, bool configOnly = false, bool throwIfNotFound = true) {
+        private string GetApiKey(string source, bool throwIfNotFound = true) {
             string apiKey = null;

-            if (!configOnly) {
-                // Second argument, if present, should be the API Key
-                if (Arguments.Count > 1) {
-                    apiKey = Arguments[1];
-                }
+            // Second argument, if present, should be the API Key
+            if (Arguments.Count > 1) {
+                apiKey = Arguments[1];
             }

             // If the user did not pass an API Key look in the config file


Switch back to more performant and portable Marvin implementation

Signed-off-by: dotnet-bot <03c4cb6107ae99956a7681f2c97ff7104809a2bd@microsoft.com>
Signed-off-by: dotnet-bot-corefx-mirror <03c4cb6107ae99956a7681f2c97ff7104809a2bd@microsoft.com>

--- src/Common/src/CoreLib/System/Marvin.cs
+++ src/Common/src/CoreLib/System/Marvin.cs
@@ -5,62 +5,86 @@
 using System.Diagnostics;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
+using Internal.Runtime.CompilerServices;
+
+#if BIT64
+using nuint = System.UInt64;
+#else
+using nuint = System.UInt32;
+#endif

 namespace System
 {
     internal static class Marvin
     {
         /// <summary>
-        /// Convenience method to compute a Marvin hash and collapse it into a 32-bit hash.
+        /// Compute a Marvin hash and collapse it into a 32-bit hash.
         /// </summary>
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public static int ComputeHash32(ReadOnlySpan<byte> data, ulong seed)
-        {
-            long hash64 = ComputeHash(data, seed);
-            return ((int)(hash64 >> 32)) ^ (int)hash64;
-        }
+        public static int ComputeHash32(ReadOnlySpan<byte> data, ulong seed) => ComputeHash32(ref MemoryMarshal.GetReference(data), data.Length, seed);

         /// <summary>
-        /// Computes a 64-hash using the Marvin algorithm.
+        /// Compute a Marvin hash and collapse it into a 32-bit hash.
         /// </summary>
-        public static long ComputeHash(ReadOnlySpan<byte> data, ulong seed)
+        public static int ComputeHash32(ref byte data, int count, ulong seed)
         {
+            nuint ucount = (nuint)count;
             uint p0 = (uint)seed;
             uint p1 = (uint)(seed >> 32);

-            if (data.Length >= sizeof(uint))
+            nuint byteOffset = 0;
+
+            while (ucount >= 8)
             {
-                ReadOnlySpan<uint> uData = MemoryMarshal.Cast<byte, uint>(data);
+                p0 += Unsafe.ReadUnaligned<uint>(ref Unsafe.AddByteOffset(ref data, byteOffset));
+                Block(ref p0, ref p1);

-                for (int i = 0; i < uData.Length; i++)
-                {
-                    p0 += uData[i];
-                    Block(ref p0, ref p1);
-                }
+                p0 += Unsafe.ReadUnaligned<uint>(ref Unsafe.AddByteOffset(ref data, byteOffset + 4));
+                Block(ref p0, ref p1);

-                // byteOffset = data.Length - data.Length % 4
-                // is equivalent to clearing last 2 bits of length
-                // Using it directly gives a perf hit for short strings making it at least 5% or more slower.
-                int byteOffset = data.Length & (~3);
-                data = data.Slice(byteOffset);
+                byteOffset += 8;
+                ucount -= 8;
             }

-            switch (data.Length)
+            switch (ucount)
             {
+                case 4:
+                    p0 += Unsafe.ReadUnaligned<uint>(ref Unsafe.AddByteOffset(ref data, byteOffset));
+                    Block(ref p0, ref p1);
+                    goto case 0;
+
                 case 0:
                     p0 += 0x80u;
                     break;

+                case 5:
+                    p0 += Unsafe.ReadUnaligned<uint>(ref Unsafe.AddByteOffset(ref data, byteOffset));
+                    byteOffset += 4;
+                    Block(ref p0, ref p1);
+                    goto case 1;
+
                 case 1:
-                    p0 += 0x8000u | data[0];
+                    p0 += 0x8000u | Unsafe.AddByteOffset(ref data, byteOffset);
                     break;

+                case 6:
+                    p0 += Unsafe.ReadUnaligned<uint>(ref Unsafe.AddByteOffset(ref data, byteOffset));
+                    byteOffset += 4;
+                    Block(ref p0, ref p1);
+                    goto case 2;
+
                 case 2:
-                    p0 += 0x800000u | MemoryMarshal.Cast<byte, ushort>(data)[0];
+                    p0 += 0x800000u | Unsafe.ReadUnaligned<ushort>(ref Unsafe.AddByteOffset(ref data, byteOffset));
                     break;

+                case 7:
+                    p0 += Unsafe.ReadUnaligned<uint>(ref Unsafe.AddByteOffset(ref data, byteOffset));
+                    byteOffset += 4;
+                    Block(ref p0, ref p1);
+                    goto case 3;
+
                 case 3:
-                    p0 += 0x80000000u | (((uint)data[2]) << 16) | (uint)(MemoryMarshal.Cast<byte, ushort>(data)[0]);
+                    p0 += 0x80000000u | (((uint)(Unsafe.AddByteOffset(ref data, byteOffset + 2))) << 16)| (uint)(Unsafe.ReadUnaligned<ushort>(ref Unsafe.AddByteOffset(ref data, byteOffset)));
                     break;

                 default:
@@ -71,7 +95,7 @@
             Block(ref p0, ref p1);
             Block(ref p0, ref p1);

-            return (((long)p1) << 32) | p0;
+            return (int)(p1 ^ p0);
         }

         [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -107,9 +131,9 @@

         private static unsafe ulong GenerateSeed()
         {
-            ulong result;
-            Interop.GetRandomBytes((byte*)&result, sizeof(ulong));
-            return result;
+            ulong seed;
+            Interop.GetRandomBytes((byte*)&seed, sizeof(ulong));
+            return seed;
         }
     }
 }


Adding virtual CreateChildContentPresenter method

With this consumers are able to modify the created ContentPresenter to meet their needs

--- src/ControlzEx/Controls/TabControlEx.cs
+++ src/ControlzEx/Controls/TabControlEx.cs
@@ -470,6 +470,12 @@
                 return;
             }

+            var contentPresenter = this.CreateChildContentPresenter(item, tabItem);
+            this.itemsHolder?.Children.Add(contentPresenter);
+        }
+
+        protected virtual ContentPresenter CreateChildContentPresenter(object? item, TabItem tabItem)
+        {
             // the actual child to be added
             var contentPresenter = new ContentPresenter
             {
@@ -487,7 +493,7 @@
             SetOwningItem(contentPresenter, item);
             SetOwningTabItem(contentPresenter, owningTabItem);

-            this.itemsHolder?.Children.Add(contentPresenter);
+            return contentPresenter;
         }

         /// <summary>


Added some logging when the fastest time is found

--- src/DeveMazeGeneratorConsole/Program.cs
+++ src/DeveMazeGeneratorConsole/Program.cs
@@ -27,6 +27,7 @@
         public static void ActualBenchmark()
         {
             int size = 16384;
+            var fastestElapsed = TimeSpan.MaxValue;

             var alg = new AlgorithmBacktrack();

@@ -38,7 +39,15 @@
                 var w = Stopwatch.StartNew();
                 var maze = alg.Generate<BitArreintjeFastInnerMap, XorShiftRandom>(size, size, seed, null);
                 w.Stop();
-                Console.WriteLine($"Generation time: {w.Elapsed}");
+
+                bool foundFastest = false;
+                if (w.Elapsed < fastestElapsed)
+                {
+                    foundFastest = true;
+                    fastestElapsed = w.Elapsed;
+                }
+
+                Console.WriteLine($"Generation time: {w.Elapsed}" + (foundFastest ? " <<<<<<<< new fastest time" : ""));
                 seed++;
             }
         }
@@ -46,6 +55,7 @@
         public static void ActualBenchmark2()
         {
             int size = 16384;
+            var fastestElapsed = TimeSpan.MaxValue;

             var alg = new AlgorithmBacktrack3();

@@ -63,7 +73,15 @@

                 var maze = alg.GoGenerate2(innerMapFactory, randomFactory, actionThing);
                 w.Stop();
-                Console.WriteLine($"Generation time: {w.Elapsed}");
+
+                bool foundFastest = false;
+                if (w.Elapsed < fastestElapsed)
+                {
+                    foundFastest = true;
+                    fastestElapsed = w.Elapsed;
+                }
+
+                Console.WriteLine($"Generation time: {w.Elapsed}" + (foundFastest ? " <<<<<<<< new fastest time" : ""));
                 seed++;


Fixed GetGuildMembers endpoint

Fixed GetGuildMembers endpoint

--- src/Discord.Net/API/DiscordRawClient.cs
+++ src/Discord.Net/API/DiscordRawClient.cs
@@ -488,7 +488,7 @@
             while (true)
             {
                 int runLimit = (limit >= DiscordConfig.MaxUsersPerBatch) ? DiscordConfig.MaxUsersPerBatch : limit;
-                string endpoint = $"guild/{guildId}/members?limit={runLimit}&offset={offset}";
+                string endpoint = $"guilds/{guildId}/members?limit={runLimit}&offset={offset}";
                 var models = await Send<GuildMember[]>("GET", endpoint).ConfigureAwait(false);

                 //Was this an empty batch?


Use ImmutableArray.Empty instead of creating a new one

--- src/Dotnet.Script/RemoteFileResolver.cs
+++ src/Dotnet.Script/RemoteFileResolver.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
 using System.Collections.Generic;
 using System.Collections.Immutable;
 using System.IO;
@@ -13,16 +13,11 @@
         private readonly Dictionary<string, string> _remoteFiles = new Dictionary<string, string>();
         private readonly SourceFileResolver _fileBasedResolver;

-        public RemoteFileResolver() : this(ImmutableArray.Create(new string[0]),
-            AppContext.BaseDirectory)
-        {
-        }
+        public RemoteFileResolver() :
+            this(ImmutableArray<string>.Empty, AppContext.BaseDirectory) {}

-        public RemoteFileResolver(string baseDir): this(ImmutableArray.Create(new string[0]),
-            baseDir)
-        {
-
-        }
+        public RemoteFileResolver(string baseDir) :
+            this(ImmutableArray<string>.Empty, baseDir) {}

         public RemoteFileResolver(ImmutableArray<string> searchPaths, string baseDirectory)
         {


fixed typo

fixed typo

--- WolframAlpha/Query.cs
+++ WolframAlpha/Query.cs
@@ -3,7 +3,7 @@
 {
     public class Query
     {
-        private const string BaseUrl = "http://blablabla/";a
+        private const string BaseUrl = "http://blablabla/";
         private string _queryString;
         private string _requestUrl;
         public string ApiKey { get; set; }


fixed path issues in the versionutility.

--- test/Core.Test/VersionUtilityTest.cs
+++ test/Core.Test/VersionUtilityTest.cs
@@ -1,3 +1,4 @@
+using NuGet.Test.Utility;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -15,6 +16,9 @@
         [InlineData("netum\\who\\bar.dll", "who\\bar.dll")]
         public void ParseFrameworkFolderNameStrictReturnsUnsupportedFxIfParsingFails(string path, string expectedEffectivePath)
         {
+            path = PathFixUtility.FixPath(path);
+            expectedEffectivePath = PathFixUtility.FixPath(expectedEffectivePath);
+
             // Act
             string effectivePath;
             var frameworkName = VersionUtility.ParseFrameworkFolderName(
@@ -39,6 +43,9 @@
         public void TestParseFrameworkFolderNameFromFilePath(
             string filePath, string expectedVersion, string expectedIdentifier, string expectedEffectivePath)
         {
+            filePath = PathFixUtility.FixPath(filePath);
+            expectedEffectivePath = PathFixUtility.FixPath(expectedEffectivePath);
+
             // Act
             string effectivePath;
             var frameworkName = VersionUtility.ParseFrameworkNameFromFilePath(filePath, out effectivePath);
@@ -73,6 +80,10 @@
         public void TestParseFrameworkFolderNameWithStrickParsing(
             string filePath, string expectedVersion, string expectedIdentifier, string expectedEffectivePath)
         {
+            filePath = PathFixUtility.FixPath(filePath);
+            expectedEffectivePath = PathFixUtility.FixPath(expectedEffectivePath);
+
+
             // Act
             string effectivePath;
             var frameworkName = VersionUtility.ParseFrameworkFolderName(filePath, strictParsing: true, effectivePath: out effectivePath);
@@ -107,6 +118,9 @@
         public void TestParseFrameworkFolderNameWithNonStrickParsing(
             string filePath, string expectedVersion, string expectedIdentifier, string expectedEffectivePath)
         {
+            filePath = PathFixUtility.FixPath(filePath);
+            expectedEffectivePath = PathFixUtility.FixPath(expectedEffectivePath);
+
             // Act
             string effectivePath;
             var frameworkName = VersionUtility.ParseFrameworkFolderName(filePath, strictParsing: false, effectivePath: out effectivePath);
@@ -131,6 +145,9 @@
         [InlineData("content\\-world\\x.dll", "-world\\x.dll")]
         public void ParseFrameworkNameFromFilePathDoesNotThrowIfPathHasADash(string path, string expectedPath)
         {
+            path = PathFixUtility.FixPath(path);
+            expectedPath = PathFixUtility.FixPath(expectedPath);
+
             // Act
             string effectivePath;
             var framework = VersionUtility.ParseFrameworkNameFromFilePath(path, out effectivePath);
@@ -477,13 +494,13 @@
             // {FrameworkName}{Version}\foo.dll
             // {FrameworkName}{Version}\sub1\foo.dll
             // {FrameworkName}{Version}\sub1\sub2\foo.dll
-            var f1 = VersionUtility.ParseFrameworkFolderName(@"foo.dll");
-            var f2 = VersionUtility.ParseFrameworkFolderName(@"sub\foo.dll");
-            var f3 = VersionUtility.ParseFrameworkFolderName(@"SL4\foo.dll");
-            var f4 = VersionUtility.ParseFrameworkFolderName(@"SL3\sub1\foo.dll");
-            var f5 = VersionUtility.ParseFrameworkFolderName(@"SL20\sub1\sub2\foo.dll");
-            var f6 = VersionUtility.ParseFrameworkFolderName(@"net\foo.dll");
-            var f7 = VersionUtility.ParseFrameworkFolderName(@"winrt45\foo.dll");
+            var f1 = VersionUtility.ParseFrameworkFolderName(PathFixUtility.FixPath(@"foo.dll"));
+            var f2 = VersionUtility.ParseFrameworkFolderName(PathFixUtility.FixPath(@"sub\foo.dll"));
+            var f3 = VersionUtility.ParseFrameworkFolderName(PathFixUtility.FixPath(@"SL4\foo.dll"));
+            var f4 = VersionUtility.ParseFrameworkFolderName(PathFixUtility.FixPath(@"SL3\sub1\foo.dll"));
+            var f5 = VersionUtility.ParseFrameworkFolderName(PathFixUtility.FixPath(@"SL20\sub1\sub2\foo.dll"));
+            var f6 = VersionUtility.ParseFrameworkFolderName(PathFixUtility.FixPath(@"net\foo.dll"));
+            var f7 = VersionUtility.ParseFrameworkFolderName(PathFixUtility.FixPath(@"winrt45\foo.dll"));

             Assert.Null(f1);
             Assert.Equal("Unsupported", f2.Identifier);


Call ConfigureAwait(false) whenever possible

--- src/DropboxRestAPI/LargeFileUploader.cs
+++ src/DropboxRestAPI/LargeFileUploader.cs
@@ -32,9 +32,9 @@
                 {
                     endPosition = _dataSource.Length;
                 }
-                var count = await _dataSource.ReadAsync(fragmentBuffer, 0, (int) Math.Max(0, endPosition - currentPosition));
+                var count = await _dataSource.ReadAsync(fragmentBuffer, 0, (int) Math.Max(0, endPosition - currentPosition)).ConfigureAwait(false);

-                var response = await _client.Core.Metadata.ChunkedUploadAsync(fragmentBuffer, count, uploadId, currentPosition, asTeamMember);
+                var response = await _client.Core.Metadata.ChunkedUploadAsync(fragmentBuffer, count, uploadId, currentPosition, asTeamMember).ConfigureAwait(false);
                 uploadId = response.upload_id;

                 currentPosition = endPosition;
@@ -43,7 +43,7 @@
             if (uploadId == null)
                 return null;

-            var uploadedItem = await _client.Core.Metadata.CommitChunkedUploadAsync(path, uploadId, locale, overwrite, parent_rev, autorename, asTeamMember);
+            var uploadedItem = await _client.Core.Metadata.CommitChunkedUploadAsync(path, uploadId, locale, overwrite, parent_rev, autorename, asTeamMember).ConfigureAwait(false);
             return uploadedItem;
         }
     }


Allowed Resharper to change spacing.

Allowed Resharper to change spacing.

--- TestMeMaybe/MaybeTests.cs
+++ TestMeMaybe/MaybeTests.cs
@@ -288,12 +288,12 @@
         {
             Assert.IsFalse(Maybe.From(1).Is(2));
             Assert.IsTrue(Maybe.From(1).Is(1));
-            Assert.IsFalse(Maybe.From((int?)null).Is(1));
+            Assert.IsFalse(Maybe.From((int?) null).Is(1));
             Assert.IsFalse(Maybe.From("hi").Is("bye"));
             Assert.IsTrue(Maybe.From("hi").Is("hi"));
-            Assert.IsFalse(Maybe.From((string)null).Is("hi"));
-            Assert.IsFalse(Maybe.From("hi").Is((string)null));
-            Assert.IsFalse(Maybe.From((string)null).Is((string)null));
+            Assert.IsFalse(Maybe.From((string) null).Is("hi"));
+            Assert.IsFalse(Maybe.From("hi").Is((string) null));
+            Assert.IsFalse(Maybe.From((string) null).Is((string) null));
             Assert.IsFalse(ReferenceEquals("hi", new StringBuilder("hi").ToString()),
                 "Assumption: StringBuilder allows us to avoid using an interned string reference.");
             Assert.IsTrue(Maybe.From("hi").Is(new StringBuilder("hi").ToString()),


some test changes

some test changes

--- test/acceptance-tests/TestService.cs
+++ test/acceptance-tests/TestService.cs
@@ -1786,6 +1786,11 @@
             using (var service = await SdkHelper.CreateService())
             {
                 const string search = "search index=_internal| head 3";
+                // do some trivial search to make sure _internal have some records
+                await service.SearchOneShotAsync(search);
+                await service.SearchOneShotAsync(search);
+                await service.SearchOneShotAsync(search);
+
                 var args = new SearchExportArgs { Count = 0 };

                 using (SearchResultStream stream = await service.ExportSearchResultsAsync(search, args))
@@ -1824,8 +1829,13 @@
             using (var service = await SdkHelper.CreateService())
             {
                 var args = new SearchExportArgs { Count = 0 };
-
-                using (SearchResultStream stream = await service.ExportSearchResultsAsync("search index=_internal | head 3", args))
+                const string search = "search index=_internal| head 3";
+                // do some trivial search to make sure _internal have some records
+                await service.SearchOneShotAsync(search);
+                await service.SearchOneShotAsync(search);
+                await service.SearchOneShotAsync(search);
+
+                using (SearchResultStream stream = await service.ExportSearchResultsAsync(search, args))
                 {
                     var manualResetEvent = new ManualResetEvent(true);
                     var results = new List<SearchResult>();


use EndsWith instead of IndexOf in ContinueCollectSeparator

improves performance on large file from 290sec to 262sec

--- src/EtlGate.Core/DelimitedDataReader.cs
+++ src/EtlGate.Core/DelimitedDataReader.cs
@@ -157,12 +157,12 @@
 			var capture = parseContext.Capture;
 			capture.Append(token.Value);
 			var potentialSeparator = capture.ToString(capture.Length - parseContext.SeparatorLength, parseContext.SeparatorLength);
-			var fieldSeparatorIndex = parseContext.FieldSeparator.Length > 0
-				                          ? potentialSeparator.IndexOf(parseContext.FieldSeparator, StringComparison.Ordinal)
-				                          : -1;
-			var recordSeparatorIndex = parseContext.RecordSeparator.Length > 0
-				                           ? potentialSeparator.IndexOf(parseContext.RecordSeparator, StringComparison.Ordinal)
-				                           : -1;
+			var fieldSeparatorIndex = parseContext.FieldSeparator.Length > 0 &&
+				potentialSeparator.EndsWith(parseContext.FieldSeparator, StringComparison.Ordinal)
+				? potentialSeparator.Length - parseContext.FieldSeparator.Length : -1;
+			var recordSeparatorIndex = parseContext.RecordSeparator.Length > 0 &&
+				potentialSeparator.EndsWith(parseContext.RecordSeparator, StringComparison.Ordinal)
+				? potentialSeparator.Length - parseContext.RecordSeparator.Length : -1;

 			if (fieldSeparatorIndex != -1 && recordSeparatorIndex != -1)
 			{


add filter

add filter

--- src/Firehose.Web/Authors/DaveCarroll.cs
+++ src/Firehose.Web/Authors/DaveCarroll.cs
@@ -21,6 +21,10 @@
         public Uri WebSite => new Uri("https://powershell.anovelidea.org/");
         public IEnumerable<Uri> FeedUris { get { yield return new Uri("https://powershell.anovelidea.org/feed.xml"); } }

+        public bool Filter(SyndicationItem item)
+        {
+            return item.Categories.Where(i => i.Name.Equals("powershell", StringComparison.OrdinalIgnoreCase)).Any();
+        }

     }
 }


Kinda need to set the IsOpen flag...

Kinda need to set the IsOpen flag...

--- src/GitHub.App/Services/ModelService.cs
+++ src/GitHub.App/Services/ModelService.cs
@@ -262,7 +262,8 @@
                 prCacheItem.CreatedAt,
                 prCacheItem.UpdatedAt)
             {
-                CommentCount = prCacheItem.CommentCount
+                CommentCount = prCacheItem.CommentCount,
+                IsOpen = prCacheItem.IsOpen
             };
         }


Activate the debugger window when the debugger breaks

--- source/TildeApp/Manager.cs
+++ source/TildeApp/Manager.cs
@@ -1059,6 +1059,7 @@
 		public void FlashMainWindow()
 		{
 			Win32.FlashWindow(mMainWindow.Handle);
+			mMainWindow.Activate();
 		}

 		public void ShowMessages(string type)


Added NearestNode method to Graph.cs

Added NearestNode method to Graph.cs

--- Game/Collections/Graph.cs
+++ Game/Collections/Graph.cs
@@ -1,4 +1,6 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
+using ISGPAI.Game.Maths;

 namespace ISGPAI.Game.Collections
 {
@@ -20,5 +22,27 @@
 		{
 			_edges.Add(edge);
 		}
+
+		public GraphNode NearestNode(Vector2 position)
+		{
+			if (_edges.Count == 0)
+			{
+				throw new InvalidOperationException(
+					"Cannot get a node in an empty graph."
+				);
+			}
+			GraphNode nearest = null;
+			double shortestLength = float.PositiveInfinity;
+			foreach (GraphEdge current in _edges)
+			{
+				double currentLength = (current.Source.Position - position).Length;
+				if (currentLength < shortestLength)
+				{
+					shortestLength = currentLength;
+					nearest = current.Source;
+				}
+			}
+			return nearest;
+		}
 	}
 }


Removed the LAST compiler warning

Removed the LAST compiler warning

--- src/LeadPipe.Net.Domain/IDomainEvent.cs
+++ src/LeadPipe.Net.Domain/IDomainEvent.cs
@@ -19,7 +19,9 @@
     /// </summary>
     public interface IDomainEventWithId : IDomainEvent
     {
-        // The domain event id.
+        /// <summary>
+        /// Gets the domain event it.
+        /// </summary>
         Guid DomainEventId { get; }
     }
 }


Fix lfmergeqm not getting right settings (#219)

The LfMergeSettings class needs to be initialized before it's used, and
the queue manager wasn't calling Initialize(). Fixed now.

--- src/LfMergeQueueManager/QueueManager.cs
+++ src/LfMergeQueueManager/QueueManager.cs
@@ -33,6 +33,7 @@
 			Sldr.Initialize();

 			var settings = MainClass.Container.Resolve<LfMergeSettings>();
+			settings.Initialize();
 			var fileLock = SimpleFileLock.CreateFromFilePath(settings.LockFile);
 			try
 			{


Changing IModelValidatorProvider DI to be transient for now

--- src/Microsoft.AspNet.Mvc/MvcServices.cs
+++ src/Microsoft.AspNet.Mvc/MvcServices.cs
@@ -66,8 +66,8 @@
             yield return describe.Transient<INestedProviderManager<FilterProviderContext>, NestedProviderManager<FilterProviderContext>>();
             yield return describe.Transient<INestedProvider<FilterProviderContext>, DefaultFilterProvider>();

-            yield return describe.Singleton<IModelValidatorProvider, DataAnnotationsModelValidatorProvider>();
-            yield return describe.Singleton<IModelValidatorProvider, DataMemberModelValidatorProvider>();
+            yield return describe.Transient<IModelValidatorProvider, DataAnnotationsModelValidatorProvider>();
+            yield return describe.Transient<IModelValidatorProvider, DataMemberModelValidatorProvider>();
         }
     }
 }