public void Project2Mesh()
        {
            if (this.strokeScreenPos.Count < 1) return;

            Rectangle viewport = new Rectangle(0, 0, this.Width, this.Height);
            OpenGLProjector projector = new OpenGLProjector();
            Mesh m = currMeshRecord.Mesh;
            bool laser = Program.toolsProperty.Laser;
            double eps = Program.toolsProperty.DepthTolerance;

            foreach (Vector2d pos in this.strokeScreenPos)
            {
                double minDis = double.MaxValue;
                int minIndex = -1;
                for (int i = 0, j = 0; i < m.VertexCount; i++, j += 3)
                {
                    Vector3d v = projector.Project(m.VertexPos, j);
                    Vector2d u = new Vector2d(v.x, v.y);
                    if (!viewport.Contains((int)v.x, (int)v.y)) continue;
                    if (projector.GetDepthValue((int)v.x, (int)v.y) - v.z < eps) continue;

                    double dis = (u - pos).Length();
                    if (dis < minDis)
                    {
                        minIndex = i;
                        minDis = dis;
                    }
                }
                if (minIndex != -1)
                {
                    this.curr_v_stroke.Add(minIndex);
                }

                minIndex = -1;
                for (int i = 0, j = 0; i < m.FaceCount; i++, j += 3)
                {
                    int c0 = m.FaceIndex[j]*3;
                    int c1 = m.FaceIndex[j + 1]*3;
                    int c2 = m.FaceIndex[j + 2]*3;
                    Vector3d v0 = projector.Project(m.VertexPos, c0);
                    Vector3d v1 = projector.Project(m.VertexPos, c1);
                    Vector3d v2 = projector.Project(m.VertexPos, c2);
                    Vector2d u0 = new Vector2d(v0.x, v0.y);
                    Vector2d u1 = new Vector2d(v1.x, v1.y);
                    Vector2d u2 = new Vector2d(v2.x, v2.y);

                    if (!viewport.Contains((int)v0.x, (int)v0.y)) continue;
                    if (projector.GetDepthValue((int)v0.x, (int)v0.y) - v0.z < eps) continue;
                    if (PointInTriangle(pos, u0, u1, u2))
                    {
                        minIndex = i;
                        this.curr_f_stroke.Add(minIndex);
                        break;
                    }
                }
            }
        }
        private int SelectVertexByPoint(Vector2d currPos)
        {
            Rectangle viewport = new Rectangle(0, 0, this.Width, this.Height);
            OpenGLProjector projector = new OpenGLProjector();
            Mesh m = currMeshRecord.Mesh;
            bool laser = Program.toolsProperty.Laser;
            double eps = Program.toolsProperty.DepthTolerance;

            double minDis = double.MaxValue;
            int minIndex = -1;
            for (int i = 0, j = 0; i < m.VertexCount; i++, j += 3)
            {
                Vector3d v = projector.Project(m.VertexPos, j);
                Vector2d u = new Vector2d(v.x, v.y);
                if (!viewport.Contains((int)v.x, (int)v.y)) continue;
                if (projector.GetDepthValue((int)v.x, (int)v.y) - v.z < eps) continue;

                double dis = (u - currPos).Length();
                if (dis < minDis)
                {
                    minIndex = i;
                    minDis = dis;
                }
            }
            if (minIndex == -1) return -1;
            //FormMain.CurrForm.OutputText("selected vertex: " + minIndex.ToString());

            if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)
                m.Flag[minIndex] = (byte)1;
            else if ((Control.ModifierKeys & Keys.Control) == Keys.Control)
                m.Flag[minIndex] = (byte)0;
            else
            {
                for (int i = 0; i < m.VertexCount; i++) m.Flag[i] = (byte)0;
                m.Flag[minIndex] = (byte)1;
            }

            return minIndex;
        }
        private void SelectVertexByRect()
        {
            Vector2d minV = Vector2d.Min(mouseDownPosition, currMousePosition);
            Vector2d size = Vector2d.Max(mouseDownPosition, currMousePosition) - minV;
            Rectangle rect = new Rectangle((int)minV.x, (int)minV.y, (int)size.x, (int)size.y);
            Rectangle viewport = new Rectangle(0, 0, this.Width, this.Height);
            OpenGLProjector projector = new OpenGLProjector();
            Mesh m = currMeshRecord.Mesh;
            bool laser = Program.toolsProperty.Laser;
            double eps = Program.toolsProperty.DepthTolerance;

            if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)
                for (int i = 0, j = 0; i < m.VertexCount; i++, j += 3)
                {
                    Vector3d v = projector.Project(m.VertexPos, j);
                    if (viewport.Contains((int)v.x, (int)v.y))
                    {
                        bool flag = rect.Contains((int)v.x, (int)v.y);
                        flag &= (laser || projector.GetDepthValue((int)v.x, (int)v.y) - v.z >= eps);
                        if (flag) m.Flag[i] = (byte)1;
                    }
                }

            else if ((Control.ModifierKeys & Keys.Control) == Keys.Control)
                for (int i = 0, j = 0; i < m.VertexCount; i++, j += 3)
                {
                    Vector3d v = projector.Project(m.VertexPos, j);
                    if (viewport.Contains((int)v.x, (int)v.y))
                    {
                        bool flag = rect.Contains((int)v.x, (int)v.y);
                        flag &= (laser || projector.GetDepthValue((int)v.x, (int)v.y) - v.z >= eps);
                        if (flag) m.Flag[i] = (byte)0;
                    }
                }

            else
                for (int i = 0, j = 0; i < m.VertexCount; i++, j += 3)
                {
                    Vector3d v = projector.Project(m.VertexPos, j);
                    if (viewport.Contains((int)v.x, (int)v.y))
                    {
                        bool flag = rect.Contains((int)v.x, (int)v.y);
                        flag &= (laser || projector.GetDepthValue((int)v.x, (int)v.y) - v.z >= eps);
                        m.Flag[i] = (byte)((flag) ? 1 : 0);
                    }
                }
        }
        private int SelectFaceByPoint(Vector2d screen_pos)
        {
            Rectangle viewport = new Rectangle(0, 0, this.Width, this.Height);
            OpenGLProjector projector = new OpenGLProjector();
            Mesh m = currMeshRecord.Mesh;
            bool laser = Program.toolsProperty.Laser;
            double eps = Program.toolsProperty.DepthTolerance;

            int minIndex = -1;
            for (int i = 0, j = 0; i < m.FaceCount; i++, j += 3)
            {
                int c0 = m.FaceIndex[j]*3;
                int c1 = m.FaceIndex[j + 1]*3;
                int c2 = m.FaceIndex[j + 2]*3;
                Vector3d v0 = projector.Project(m.VertexPos, c0);
                Vector3d v1 = projector.Project(m.VertexPos, c1);
                Vector3d v2 = projector.Project(m.VertexPos, c2);
                Vector2d u0 = new Vector2d(v0.x, v0.y);
                Vector2d u1 = new Vector2d(v1.x, v1.y);
                Vector2d u2 = new Vector2d(v2.x, v2.y);

                if (!viewport.Contains((int)v0.x, (int)v0.y)) continue;
                if (projector.GetDepthValue((int)v0.x, (int)v0.y) - v0.z < eps) continue;
                if (PointInTriangle(screen_pos, u0, u1, u2))
                {
                    minIndex = i;
                    break;
                }
            }
            return minIndex;
        }