示例#1
0
        /// <summary>
        /// Takes two transforms and transforms the control grid of this section into the control grid space of the passed transfrom. Requires control section
        /// of this transform to match mapped section of adding transform
        /// </summary>
        public void Add(GridTransform transform)
        {
            //We can't map if we don't have a triangle
            if (transform.mapPoints.Length < 3)
                return;

            //Temp: Ensure we know the edges
            this.CalculateEdges();
            transform.BuildDataStructures();

            //Reset boundaries since they will be changed
            _CachedControlBounds = new GridRectangle(double.MinValue, double.MinValue, 0, 0);
            _CachedMappedBounds = new GridRectangle(double.MinValue, double.MinValue, 0, 0);

            List<AddTransformThreadObj> threadObjList = new List<AddTransformThreadObj>();
            List<ManualResetEvent> doneEvents = new List<ManualResetEvent>();

            List<MappingGridVector2> newPoints = new List<MappingGridVector2>(mapPoints.Length);

            #if DEBUG
            List<GridVector2> mapPointList = new List<GridVector2>(newPoints.Count);
            #endif

            //            Trace.WriteLine("Starting with " + mapPoints.Length + " points", "Geometry");

            //    List<MappingGridVector2> newPoints = new List<MappingGridVector2>();

            //           Trace.WriteLine("Started GridTransform.Add with " + mapPoints.Length.ToString() + " points", "Geometry");

            //Search all mapping triangles and update control points, if they fall outside the grid then discard the triangle
            const int PointsPerThread = 4;
            for (int iPoint = 0; iPoint < this.mapPoints.Length; iPoint += PointsPerThread )
            {
                //Create a series of points for the thread to process so they aren't constantly hitting the queue lock looking for new work.
                List<int> listPoints = new List<int>(PointsPerThread);
                for (int iAddPoint = iPoint; iAddPoint < iPoint + PointsPerThread; iAddPoint++)
                {
                    //Don't add if the point is out of range
                    if (iAddPoint >= this.mapPoints.Length)
                        break;

                    listPoints.Add(iAddPoint);
                }

                //MappingGridVector2 mapPoint = mapPoints[iPoint];
                AddTransformThreadObj AddThreadObj = new AddTransformThreadObj(listPoints.ToArray(), this, transform);
                doneEvents.Add(AddThreadObj.DoneEvent);
                threadObjList.Add(AddThreadObj);

                /*
                MappingGridVector2 UnmappedPoint = mapPoints[iPoint];
                MappingGridTriangle mapTri = transform.GetTransform(mapPoints[iPoint].ControlPoint);

                if (mapTri != null)
                {
                    GridVector2 newControl = mapTri.Transform(UnmappedPoint.ControlPoint);
                    newPoints.AddRange(new MappingGridVector2[] { new MappingGridVector2(newControl, UnmappedPoint.MappedPoint) });

                    List<MappingGridVector2> sortPoints = new List<MappingGridVector2>(newPoints);
                    sortPoints.Sort();
                    for (int i = 1; i < sortPoints.Count; i++)
                    {
                        Debug.Assert(sortPoints[i - 1].ControlPoint != sortPoints[i].ControlPoint);
                    }
                }
                else
                {
                    //In this case we need to test each edge connecting this point to other points.
                    //newPoints = new MappingGridVector2[0];
                    for(int i = 0; i < TriangleIndicies.Length; i += 3)
                    {
                        if(TriangleIndicies[i] == iPoint)
                        {

                    int[] EdgesIndicies = Array.Find<int>(this.TriangleIndicies, iPoint);
                }
                */

                //For single threaded debug, comment out threadpool and uncomment AddThreadObj.ThreadPoolCallback line
                ThreadPool.QueueUserWorkItem(AddThreadObj.ThreadPoolCallback);
            //                AddThreadObj.ThreadPoolCallback(null);

                //newPoints.AddRange(AddThreadObj.newPoints);

                //newPoints.Sort();

            #if false
                for (int iTest = 1; iTest < newPoints.Count; iTest++)
                {
                    Debug.Assert(newPoints[iTest - 1].ControlPoint != newPoints[iTest].ControlPoint);
                }

                for (int iMap = 0; iMap < AddThreadObj.newPoints.Length; iMap++)
                {
                    mapPointList.Add(AddThreadObj.newPoints[iMap].MappedPoint);
                }

                mapPointList.Sort();

                for (int iMap = 1; iMap < mapPointList.Count; iMap++)
                {
                    Debug.Assert(GridVector2.Distance(mapPointList[iMap], mapPointList[iMap - 1]) > Global.epsilon);
                }
            #endif
            }

            //Wait for the threads to finish processing.  There is a 64 handle limit for WaitAll so we wait on one at a time
            foreach (ManualResetEvent doneEvent in doneEvents)
                doneEvent.WaitOne();

            newPoints.Clear();

            foreach(AddTransformThreadObj obj in threadObjList)
            {
                if(obj.newPoints != null)
                    newPoints.AddRange(obj.newPoints);
            }

            //            Trace.WriteLine("Mapped " + newPoints.Count + " points", "Geometry");

            #if false

            mapPointList.Clear();
            for (int iMap = 0; iMap < newPoints.Count; iMap++)
            {
                mapPointList.Add(newPoints[iMap].MappedPoint);
            }

            mapPointList.Sort();

            for (int iMap = 1; iMap < mapPointList.Count; iMap++)
            {
                Debug.Assert(GridVector2.Distance(mapPointList[iMap], mapPointList[iMap - 1]) > Global.epsilon);
            }
            #endif

            //Remove duplicates: In the case that a line on the warpingGrid passes through a point on the fixedGrid then both ends of the line will map the point and we will get a duplicate
            newPoints.Sort();
            int iCompareStart = 0;
            for (int iTest = 1; iTest < newPoints.Count; iTest++)
            {
            //   Debug.Assert(newPoints[iTest - 1].ControlPoint != newPoints[iTest].ControlPoint);
                //This is slow, but even though we sort on the X axis it doesn't mean a point that is not adjacent to the point on the list isn't too close
                for (int jTest = iCompareStart; jTest < iTest; jTest++)
                {
                    if (GridVector2.Distance(newPoints[jTest].ControlPoint, newPoints[iTest].ControlPoint) <= Global.Epsilon)
                    {
                        newPoints.RemoveAt(iTest);
                        iTest--;
                        break;
                    }

                    //Optimization, since the array is sorted we don't need to compare points once a point is distant enough
                    if (newPoints[iTest].ControlPoint.X - newPoints[jTest].ControlPoint.X > Global.Epsilon)
                    {
                        iCompareStart = jTest;
                    }
                }
            }

            //            Trace.WriteLine("Ended with " + newPoints.Count + " points", "Geometry");
            this.mapPoints = newPoints.ToArray();

            //Edges are build on mapPoints, so we need to remove them so they'll be recalculates
            _edges = null;
            //Other datastructures are dependent on edges, so minimize memory will delete them
            MinimizeMemory();

            //            Trace.WriteLine("Finished GridTransform.Add with " + newPoints.Count.ToString() + " points", "Geometry");

            //Check whether these have been set yet or if I don't need to clear them again
            this.ControlSection = transform.ControlSection;
        }
示例#2
0
        object ICloneable.Clone()
        {
            GridTransform newObj = new GridTransform();
            newObj = this.MemberwiseClone() as GridTransform;

            List<MappingGridVector2> TempList = new List<MappingGridVector2>();

            foreach (MappingGridVector2 pt in mapPoints)
            {
                TempList.Add((MappingGridVector2)pt.Copy());
            }

            //Setting the mapPoints will sort and recalculate triangles
            newObj.mapPoints = TempList.ToArray();

            return newObj;
        }
示例#3
0
        public static GridRectangle CalculateBounds(GridTransform[] transforms)
        {
            double minX = double.MaxValue;
            double minY = double.MaxValue;
            double maxX = double.MinValue;
            double maxY = double.MinValue;

            foreach (GridTransform T in transforms)
            {
                GridRectangle R = T.CachedControlBounds;

                if (R.Left < minX)
                    minX = R.Left;
                if (R.Right > maxX)
                    maxX = R.Right;
                if (R.Bottom < minY)
                    minY = R.Bottom;
                if (R.Top > maxY)
                    maxY = R.Top;
            }

            return new GridRectangle(minX, maxX, minY, maxY);
        }