public static List<Vector2> Add(this Shape shape, Shape secondShape, Action<Shape> completed)
        {
            List<Vector2> points = new List<Vector2>();

            Clipper c = new Clipper();

            List<List<IntPoint>> subj = new List<List<IntPoint>>();
            List<List<IntPoint>> clip = new List<List<IntPoint>>();
            List<List<IntPoint>> solution = new List<List<IntPoint>>();
            List<IntPoint> p1 = new List<IntPoint>();
            List<IntPoint> p2 = new List<IntPoint>();
            int i = 0, l = shape.Points.Length;
            Vector2 pos = shape.BuiltGameObject.transform.position;
            for(;i<l;++i)
            {
                IntPoint ip = new IntPoint(shape.Points[i].x + pos.x,shape.Points[i].y + pos.y);
                p1.Add(ip);
            }
            p1.Add(p1[0]);

            pos = secondShape.BuiltGameObject.transform.position;
            i = 0; l = secondShape.Points.Length;
            for(;i<l;++i)
            {
                IntPoint ip = new IntPoint(secondShape.Points[i].x + pos.x,secondShape.Points[i].y + pos.y);
                p2.Add(ip);
            }
            p2.Add(p2[0]);

            subj.Add(p1);
            clip.Add(p2);

            c.AddPaths(subj,PolyType.ptSubject,true);
            c.AddPaths(clip,PolyType.ptClip,true);
            c.Execute(ClipType.ctUnion,solution);

            i = 0; l = solution[0].Count;
            for(;i<l;++i)
            {
                float x = System.Convert.ToSingle(solution[0][i].X);
                float y = System.Convert.ToSingle(solution[0][i].Y);
                points.Add(new Vector2(x,y));
            }

            Mesh2D.Instance.ReBuild(shape.BuiltGameObject,points,completed,shape.Col);
            return points;
        }
        private void ReassignDataToMesh()
        {
            _reusedMesh.Clear();
            _reusedMesh.vertices = _vertices;
            _reusedMesh.uv = _uvs;
            _reusedMesh.colors32 = _colors;
            _reusedMesh.triangles = _tris;
            _reusedMesh.RecalculateNormals();
            _reusedMesh.Optimize();
            _reusedMesh.RecalculateBounds();

            _reusedShape.BuiltGameObject.GetComponent<MeshRenderer>().material = _material;
            _reusedShape.BoundingBox = _boundingBox;
            _reusedShape.UVBounds = _uvBounds;
            _reusedShape.Area = _boundingBox.x * _boundingBox.y;
            _reusedShape.Points = _points.ToArray();
            _reusedShape.Polygon = _polygon;
            _reusedShape.Col = _vertexColor;

            _lastCreatedObject = _reusedShape;
        }
        private void ProcessQueue()
        {
            if (_queue.Count > 0 && !_running)
            {
                MeshBuilderVO vo = _queue [0];

                _running = true;
                _finishedAction = vo.CompletedHandler;
                _useThread = vo.Thread;
                _vertexColor = vo.Col;
                _material = vo.Mat;
                _rebuild = vo.Rebuild;
                _reusedMesh = vo.ReusedMesh;
                _reusedShape = vo.ReusedShape;
                Build(vo.Points);
            }
        }
 private void InvalidShapeCreated()
 {
     if (_lastCreatedObject != null)
     {
         Destroy(_lastCreatedObject.BuiltGameObject);
     }
     _lastCreatedObject = null;
     FinishQueue();
     //            throw new System.InvalidOperationException("Constructed points were invalid.");
 }
        private void Build(List<Vector2> points)
        {
            _lastCreatedObject = null;

            Vector2[] temp = new Vector2[points.Count];
            points.CopyTo(temp);
            _points = new List<Vector2>(temp);

            if (_points.Count < MINIMUM_ALLOWED_VERTICES)
            {
                InvalidShapeCreated();
                return;
            }

            if (_useThread)
            {
                StartCoroutine(ThreadManager.Start(StartConstruction, MeshConstructionComplete, 0));
            } else
            {
                StartConstruction(-1);
            }
        }
        private void AssignDataToMesh()
        {
            Mesh msh = new Mesh();
            msh.vertices = _vertices;
            msh.uv = _uvs;
            msh.colors32 = _colors;
            msh.triangles = _tris;
            msh.RecalculateNormals();
            msh.Optimize();
            msh.RecalculateBounds();
            GameObject go = new GameObject();
            MeshFilter filter = go.AddComponent<MeshFilter>();
            go.AddComponent<MeshRenderer>().material = _material;
            go.transform.name = "DrawnObject";
            filter.mesh = msh;
            msh.name = "DrawnObjectMesh";

            Shape shape = go.AddComponent<Shape>();
            shape.BuiltGameObject = go;
            shape.BoundingBox = _boundingBox;
            shape.UVBounds = _uvBounds;
            shape.Area = _boundingBox.x * _boundingBox.y;
            shape.Points = _points.ToArray();
            shape.Polygon = _polygon;
            shape.Col = _vertexColor;

            _lastCreatedObject = shape;
        }
        public static List<Vector2> Subtract(this Shape shape, Shape secondShape, Action<Shape> completed)
        {
            List<Vector2> points = new List<Vector2>();

            Clipper c = new Clipper();

            List<List<IntPoint>> subj = new List<List<IntPoint>>();
            List<List<IntPoint>> clip = new List<List<IntPoint>>();
            List<List<IntPoint>> solution = new List<List<IntPoint>>();
            List<IntPoint> p1 = new List<IntPoint>();
            List<IntPoint> p2 = new List<IntPoint>();
            int i = 0, l = shape.Points.Length;
            Vector2 pos = shape.BuiltGameObject.transform.position;
            for(;i<l;++i)
            {
                IntPoint ip = new IntPoint(shape.Points[i].x + pos.x,shape.Points[i].y + pos.y);
                p1.Add(ip);
            }
            p1.Add(p1[0]);

            pos = secondShape.BuiltGameObject.transform.position;
            i = 0; l = secondShape.Points.Length;
            for(;i<l;++i)
            {
                IntPoint ip = new IntPoint(secondShape.Points[i].x + pos.x,secondShape.Points[i].y + pos.y);
                p2.Add(ip);
            }
            p2.Add(p2[0]);

            subj.Add(p1);
            clip.Add(p2);

            c.AddPaths(subj,PolyType.ptSubject,true);
            c.AddPaths(clip,PolyType.ptClip,true);
            c.Execute(ClipType.ctDifference,solution);

            if(solution.Count == 0)
            {
                MonoBehaviour.Destroy(shape.BuiltGameObject);
            }

            int j = 0, k = solution.Count;
            for(;j<k;++j)
            {
                points = new List<Vector2>();
                i = 0; l = solution[j].Count;
                for(;i<l;++i)
                {
                    points.Add(new Vector2(solution[j][i].X,solution[j][i].Y));
                }

                if(j == 0)
                {
                    Mesh2D.Instance.ReBuild(shape.BuiltGameObject,points,completed,shape.Col);
                }
                else
                {
                    Mesh2D.Instance.Build(points,completed,shape.Col);
                }
            }
            return points;
        }