public BezierSurface(BezierSurface copy)
            : base(copy.Name, copy.ImageUri)
        {
            ControlPoints = new Vector3D[numControlPoints * numControlPoints];
            for (int i = 0; i < copy.ControlPoints.Length; i++)
            {
                ControlPoints[i] = new Vector3D(copy.ControlPoints[i].x,
                                                copy.ControlPoints[i].y,
                                                copy.ControlPoints[i].z);
            }

            n = copy.n;
            if (copy.OutputPoints != null)
            {
                {
                }
                OutputPoints = new Vector3D[copy.OutputPoints.Length];
                for (int i = 0; i < copy.OutputPoints.Length; i++)
                {
                    OutputPoints[i] = new Vector3D(copy.OutputPoints[i].x,
                                                   copy.OutputPoints[i].y,
                                                   copy.OutputPoints[i].z);
                }
                triangles = new List <Triangle>(copy.triangles.Count);
                for (int i = 0; i < copy.triangles.Count; i++)
                {
                    triangles.Add(new Triangle(copy.triangles[i].p1,
                                               copy.triangles[i].p2,
                                               copy.triangles[i].p3));
                }

                selectedPointIdx = copy.selectedPointIdx;
            }
        }
        public BezierSurface(BezierSurface copy)
            : base(copy.Name, copy.ImageUri)
        {
            ControlPoints = new Vector3D[numControlPoints*numControlPoints];
            for (int i = 0; i < copy.ControlPoints.Length; i++)
            {
                ControlPoints[i] = new Vector3D(copy.ControlPoints[i].x,
                                                copy.ControlPoints[i].y,
                                                copy.ControlPoints[i].z);
            }

            n = copy.n;
            if (copy.OutputPoints != null)
            {
                {
                }
                OutputPoints = new Vector3D[copy.OutputPoints.Length];
                for (int i = 0; i < copy.OutputPoints.Length; i++)
                {
                    OutputPoints[i] = new Vector3D(copy.OutputPoints[i].x,
                                                   copy.OutputPoints[i].y,
                                                   copy.OutputPoints[i].z);
                }
                triangles = new List<Triangle>(copy.triangles.Count);
                for (int i = 0; i < copy.triangles.Count; i++)
                {
                    triangles.Add(new Triangle(copy.triangles[i].p1,
                                               copy.triangles[i].p2,
                                               copy.triangles[i].p3));
                }

                selectedPointIdx = copy.selectedPointIdx;
            }
        }
        public BezierSurface Undo(BezierSurface bezier)
        {
            if (first != null)
            {
                Element secondRedo = firstRedo;
                firstRedo = new Element();
                firstRedo.next = secondRedo;
                firstRedo.bezier = new BezierSurface(bezier);

                bezier = first.bezier;
                first = first.next;
            }
            return bezier;
        }
        public static BezierSurface ReadFromFile(string file)
        {
            BezierSurface bezier = new BezierSurface("", "");

            try
            {
                List <string> text    = FileSystem.File.ReadFileLines(file);
                int           pointer = 0;

                string[] bezierName = FileSystem.File.GetAttributes(text[pointer]);
                if (bezierName[0] != "name")
                {
                    return(null);
                }
                string name = FileSystem.File.CutFirstString(text[pointer]);
                ++pointer;
                bezier.Name = name;

                string numCtrlPointsLabel = FileSystem.File.GetAttribute(text[pointer], 0);
                if (numCtrlPointsLabel != "num_control_points")
                {
                    return(null);
                }

                if (numControlPoints != int.Parse(FileSystem.File.GetAttribute(text[pointer++], 1)))
                {
                    return(null);
                }

                for (int i = 0; i < numControlPoints; i++)
                {
                    for (int j = 0; j < numControlPoints; j++)
                    {
                        string[] attsPoint = FileSystem.File.GetAttributes(text[pointer++]);
                        bezier.ControlPoints[i * numControlPoints + j] =
                            new Vector3D(float.Parse(attsPoint[0], CultureInfo.InvariantCulture),
                                         float.Parse(attsPoint[1], CultureInfo.InvariantCulture),
                                         float.Parse(attsPoint[2], CultureInfo.InvariantCulture));
                    }
                }
            }
            catch (Exception)
            {
                return(null);
            }

            return(bezier);
        }
        public void Save(BezierSurface bezier)
        {
            Element second = first;
            first = new Element();
            first.next = second;
            first.bezier = new BezierSurface(bezier);

            firstRedo = null;
            int m = 0;
            for (Element el = first; el != null; el = el.next)
            {
                //m += el.scene.EstimatedMemory();
                m += el.bezier.EstimatedMemory();
                if (m > MAX_MEMORY) el.next = null;
            }
        }
        /// <summary>
        /// Działa tylko dla widoków ortogonalnych.
        /// </summary>
        /// <param name="bezierSurface"></param>
        /// <param name="bezierCam"></param>
        /// <param name="viewportType"></param>
        /// <param name="pos"></param>
        /// <param name="size"></param>
        /// <param name="orthoSize"></param>
        /// <param name="orthoPos"></param>
        /// <param name="orthoLookAt"></param>
        public static void SelectBezierControlPoint(BezierSurface bezierSurface, Camera bezierCam, ViewportType viewportType, 
            Point pos, Point size, Vector2 orthoSize, Vector3 orthoPos, Vector3 orthoLookAt)
        {
            Vector3 outCamPos = new Vector3(), outSurfPos = new Vector3();

            switch (viewportType)
            {
                case ViewportType.Perspective:
                    CalcPerspCoords(pos, size, bezierCam.fovAngle, bezierCam.rotateAngle,
                                    bezierCam.position, bezierCam.lookAt, out outCamPos, out outSurfPos);
                    break;

                case ViewportType.Orto:
                    CalcOrthoCoords(pos, size, orthoSize, orthoPos, orthoLookAt, out outCamPos, out outSurfPos);
                    break;
            }

            Vector3 rayDir = Vector3.Normalize(outSurfPos - outCamPos);

            SlimDX.Ray ray = new SlimDX.Ray(outCamPos + 0.01f * rayDir, rayDir);
            float dist = float.PositiveInfinity;
            float tmpDist = -1;
            BoundingBox bb;

            for (int i = 0; i < bezierSurface.ControlPoints.Length; i++)
            {
                bb = new BoundingBox(new Vector3(bezierSurface.ControlPoints[i].x - 0.05f,
                                                 bezierSurface.ControlPoints[i].y - 0.05f,
                                                 bezierSurface.ControlPoints[i].z - 0.05f),
                                     new Vector3(bezierSurface.ControlPoints[i].x + 0.05f,
                                                 bezierSurface.ControlPoints[i].y + 0.05f,
                                                 bezierSurface.ControlPoints[i].z + 0.05f));

                if (SlimDX.Ray.Intersects(ray, bb, out tmpDist))
                {
                    if (tmpDist < dist)
                    {
                        dist = tmpDist;
                        bezierSurface.selectedPointIdx = i;
                    }
                }
            }

            if (dist == float.PositiveInfinity)
            {
                bezierSurface.selectedPointIdx = -1;
            }
        }
 private void bezierContextMenuNewSurface(object sender, System.EventArgs e)
 {
     bezierSurface = new BezierSurface("new surface", "");
     bezierSurface.Triangulate((float)triang_Slider.Value);
     bezierUndo = new BezierUndoStack();
     RenderBezier();
 }
        private void undoClick(object sender, RoutedEventArgs e)
        {
            if (tabWidok.SelectedIndex == 0)
            {
                currScene = undo.Undo(currScene);
                //cameraPan.newSceneLoaded();
                Renderer.RecalculateData(currScene);
                RenderViews();
            } else if (tabWidok.SelectedIndex == 1)
            {
                bezierSurface = bezierUndo.Undo(bezierSurface);
                //bezierSurface.Triangulate((float)triang_Slider.Value);
                RenderBezier();
            }
            currScene.selectedHierObj = null;
            trNumTBG1.Text = currScene.triangles.Count().ToString();
            trNumTBG2.Text = currScene.triangles.Count().ToString();
            trNumTBG3.Text = currScene.triangles.Count().ToString();
            trNumTBG4.Text = currScene.triangles.Count().ToString();

            //sceneChange = true;
        }
        private void redoClick(object sender, RoutedEventArgs e)
        {
            if (tabWidok.SelectedIndex == 0)
            {
                currScene = undo.Redo(currScene);
                Renderer.RecalculateData(currScene);
                RenderViews();
            }
            else
            {
                bezierSurface = bezierUndo.Redo(bezierSurface);
                RenderBezier();
            }
            currScene.selectedHierObj = null;
            trNumTBG1.Text = currScene.triangles.Count().ToString();
            trNumTBG2.Text = currScene.triangles.Count().ToString();
            trNumTBG3.Text = currScene.triangles.Count().ToString();
            trNumTBG4.Text = currScene.triangles.Count().ToString();

            //sceneChange = true;
        }
        private void podstawoweTab_Drop(object sender, System.Windows.DragEventArgs e)
        {
            if (e.Data.GetDataPresent("Bezier"))
            {
                //Modeler.DialogBoxes.BezierNameDialog dialog = new BezierNameDialog();
                object data = e.Data.GetData("Bezier");
                //Console.WriteLine(data.GetType());
                bool replace = false;
                if (data is BezierSurface)
                {
                    BezierSurface bezier = new BezierSurface((BezierSurface)data);
                    //bezier.Name = "Def";
                    if (String.Compare(bezier.Name, "default", true) == 0 ||
                        String.Compare(bezier.Name, "new surface", true) == 0)
                    {
                        Modeler.DialogBoxes.NameDialog newName = new NameDialog();
                        bool res = (bool)newName.Show("Podaj nową nazwę powierzchni", "");
                        if (!res)
                            return;
                        bezier.Name = newName.Result;

                    }
                    while (_shapesGallery.GetNames().Contains(bezier.Name, StringComparer.OrdinalIgnoreCase) && !replace)
                    {
                        bool result;
                        Modeler.DialogBoxes.NameDialog dialog = new NameDialog();
                        string name;
                        if (ShapeGallery.ReservedNames.Contains(bezier.Name, StringComparer.OrdinalIgnoreCase))
                        {
                            dialog.Owner = this;
                            result = (bool)dialog.Show("Nazwa powierzchni jest zarezerwowana dla podstawowego kształtu.", bezier.Name);
                            name = dialog.Result;
                            if (!result)
                                return;
                            bezier.Name = name;
                            dialog.Close();
                        }
                        else
                        {
                            dialog.Owner = this;
                            result = (bool) dialog.Show(bezierMessage, bezier.Name);
                            name = dialog.Result;
                            if (!result)
                                return;
                            if (bezier.Name == name)
                                replace = true;
                            bezier.Name = name;
                            dialog.Close();
                        }
                    }

                    bezier.Triangulate(1);
                    if (replace)
                    {
                        int idx = _shapesGallery.GetNameIndex(bezier.Name);
                        _shapesGallery.RemoveAt(idx);
                        _shapesGallery.SaveBezierToGallery(bezier, renderer.GetBezierImage(bezier));
                        _shapesGallery.Insert(idx, bezier);
                    }
                    else
                    {
                        _shapesGallery.SaveBezierToGallery(bezier, renderer.GetBezierImage(bezier));
                        _shapesGallery.Add(bezier);
                    }
                }
            }
        }
        // Koniec sekcji
        ////////////////////////////////////////////////////////////////////////////////////
        private void objectToScene_Drop(object sender, System.Windows.DragEventArgs e)
        {
            // Wciąganie obiektów do sceny
            if (tabWidok.SelectedIndex == 0)
            {
                if (e.Data.GetDataPresent("Object"))
                {
                    object data = e.Data.GetData("Object");
                    //Console.WriteLine(data.GetType());
                    //ViewportInfo coords = GetViewCoords(tabWidok.SelectedIndex);
                    Vector3 translation;
                    if (data is Shape_)
                    {
                        Shape_ shape = (Shape_)data;
                        undo.Save(currScene);
                        // przekształcenie współrzędnych
                        float x = (float)e.GetPosition(this).X - xOffset;
                        float y = (float)e.GetPosition(this).Y - yOffset;

                        translation = CalculateTranslation(x, y);
                        currScene.AddObject(shape.Triangulate((float)triang_Slider.Value), shape.Name, translation);
                        currScene.hierarchyChange = false;
                        initializeTreeView();

                        //sceneChange = true;
                    }
                    else if (data is PreparedElement)
                    {
                        undo.Save(currScene);
                        PreparedElement element = (PreparedElement)data;

                        // przekształcenie współrzędnych
                        float x = (float)e.GetPosition(this).X - xOffset;
                        float y = (float)e.GetPosition(this).Y - yOffset;

                        translation = CalculateTranslation(x, y);
                        //for (int i = 0; i < element.Scene.cams.Count; i++)
                        //{
                        //    cameraPan.comboBox1.Items.Add("Kamera " + (currScene.cams.Count() + 1 + i));
                        //}
                        currScene.AddPreparedElement(element, translation);
                        currScene.hierarchyChange = false;
                        initializeTreeView();

                        //sceneChange = true;
                    }
                    else if (data is Surface)
                    {
                        Surface surface = (Surface)data;
                        undo.Save(currScene);
                        bool zazn = true;

                        if (currScene.selTriangles.Count == 0)
                        {
                            zazn = false;
                            ViewportInfo views = GetViewCoords(tabWidok.SelectedIndex);
                            int x = (int)e.GetPosition(this).X - xOffset;
                            int y = (int)e.GetPosition(this).Y - yOffset;

                            ViewportOrientation viewport = GetViewportType(x, y);

                            if (viewport != ViewportOrientation.None)
                            {
                                ViewportType viewportType = viewport == ViewportOrientation.Perspective ? ViewportType.Perspective : ViewportType.Orto;
                                int rect = (int)viewport;
                                int orthoRect = rect == 3 ? 0 : rect;

                                SelectingElems.SelectElems(currScene, renderer.GetCamsPoints(), renderer.GetLightsPoints(), viewportType, new System.Drawing.Point(x - views.posX[rect], y - views.posY[rect]),
                                    new System.Drawing.Point(views.sizeX[rect], views.sizeY[rect]), new Vector2(renderer.OrthoWidth[orthoRect], (float)views.sizeY[rect] / views.sizeX[rect] * renderer.OrthoWidth[orthoRect]),
                                    renderer.OrthoPos[orthoRect], renderer.OrthoLookAt[orthoRect], false);
                            }
                        }

                        if (String.Compare(surface.Material.Name, "default", true) == 0)
                        {
                            Modeler.DialogBoxes.NameDialog newName = new NameDialog();
                            bool res = (bool)newName.Show("Podaj nową nazwę materiału", "");
                            if (!res)
                                return;
                            surface.Material.name = newName.Result;

                        }
                        bool replace = false;
                        while (currScene.ContainsMaterialName(surface.Material.Name) && !replace)
                        {
                            Modeler.DialogBoxes.NameDialog dialog = new NameDialog();
                            dialog.Owner = this;

                            bool result = (bool)dialog.Show(materialSceneMessage, surface.Material.Name);
                            string name = dialog.Result;
                            if (!result)
                                return;
                            if (surface.Material.Name == name)
                                replace = true;
                            surface.Material.name = name;
                            dialog.Close();
                        }

                        currScene.AddMaterial(surface.Material);
                        currScene.hierarchyChange = false;

                        if (!zazn) currScene.ClearSelectedTriangles();
                        //Console.WriteLine("Przypisanie atrybutów powierzchniowych");

                        //sceneChange = true;
                    }
                    else if (data is Material_)
                    {
                        Material_ material = new Material_((Material_)data);
                        material.colorR = material.colorR / 255;
                        material.colorG = material.colorG / 255;
                        material.colorB = material.colorB / 255;
                        undo.Save(currScene);
                        bool zazn = true;

                        if (currScene.selTriangles.Count == 0)
                        {
                            zazn = false;
                            ViewportInfo views = GetViewCoords(tabWidok.SelectedIndex);
                            int x = (int)e.GetPosition(this).X - xOffset;
                            int y = (int)e.GetPosition(this).Y - yOffset;

                            ViewportOrientation viewport = GetViewportType(x, y);

                            if (viewport != ViewportOrientation.None)
                            {
                                ViewportType viewportType = viewport == ViewportOrientation.Perspective ? ViewportType.Perspective : ViewportType.Orto;
                                int rect = (int)viewport;
                                int orthoRect = rect == 3 ? 0 : rect;

                                SelectingElems.SelectElems(currScene, renderer.GetCamsPoints(), renderer.GetLightsPoints(), viewportType, new System.Drawing.Point(x - views.posX[rect], y - views.posY[rect]),
                                    new System.Drawing.Point(views.sizeX[rect], views.sizeY[rect]), new Vector2(renderer.OrthoWidth[orthoRect], (float)views.sizeY[rect] / views.sizeX[rect] * renderer.OrthoWidth[orthoRect]),
                                    renderer.OrthoPos[orthoRect], renderer.OrthoLookAt[orthoRect], false);
                            }
                        }

                        if (String.Compare(material.Name, "default", true) == 0)
                        {
                            Modeler.DialogBoxes.NameDialog newName = new NameDialog();
                            bool res = (bool)newName.Show("Podaj nową nazwę materiału", "");
                            if (!res)
                                return;
                            material.name = newName.Result;

                        }
                        bool replace = false;
                        while (currScene.ContainsMaterialName(material.Name) && !replace)
                        {
                            Modeler.DialogBoxes.NameDialog dialog = new NameDialog();
                            dialog.Owner = this;

                            bool result = (bool)dialog.Show(materialSceneMessage, material.Name);
                            string name = dialog.Result;
                            if (!result)
                                return;
                            if (material.Name == name)
                                replace = true;
                            material.name = name;
                            dialog.Close();
                        }

                        currScene.AddMaterial(material);

                        if (!zazn) currScene.ClearSelectedTriangles();
                        //Console.WriteLine("Przypisanie atrybutów powierzchniowych");

                        //sceneChange = true;
                    }
                    else if (data is LightObj)
                    {
                        if (currScene.selLights.Count > 0)  //objętnie ile ich jest zaznaczonych zmienia tylko 1 sprawdzająć nazwe
                        {
                            undo.Save(currScene);
                            Light_ sceneLight = currScene.lights[currScene.selLights[0]];
                            Light_ dataLight = ((LightObj)data).Light;
                            sceneLight.colorR = dataLight.colorR;
                            sceneLight.colorG = dataLight.colorG;
                            sceneLight.colorB = dataLight.colorB;
                            sceneLight.enabled = dataLight.enabled;
                            sceneLight.goniometric = dataLight.goniometric;
                            sceneLight.innerAngle = dataLight.innerAngle;
                            sceneLight.name = dataLight.name;
                            sceneLight.outerAngle = dataLight.outerAngle;
                            sceneLight.power = dataLight.power;
                            sceneLight.type = dataLight.type;

                            //sceneChange = true;
                        }
                        else
                        {
                            LightObj light = (LightObj)data;
                            undo.Save(currScene);
                            Light_ sceneLight = new Light_(light.Light);

                            // przekształcenie współrzędnych
                            float x = (float)e.GetPosition(this).X - xOffset;
                            float y = (float)e.GetPosition(this).Y - yOffset;

                            translation = CalculateTranslation(x, y);

                            currScene.AddLight(sceneLight, translation);
                            currScene.hierarchyChange = false;
                            initializeTreeView();

                            //sceneChange = true;
                        }
                    }

                    else if (data is Light_)
                    {
                        if (currScene.selLights.Count > 0)
                        {
                            undo.Save(currScene);
                            Light_ sceneLight = currScene.lights[currScene.selLights[0]];
                            Light_ dataLight = (Light_)data;
                            sceneLight.colorR = dataLight.colorR;
                            sceneLight.colorG = dataLight.colorG;
                            sceneLight.colorB = dataLight.colorB;
                            sceneLight.enabled = dataLight.enabled;
                            sceneLight.goniometric = dataLight.goniometric;
                            sceneLight.innerAngle = dataLight.innerAngle;
                            sceneLight.name = dataLight.name;
                            sceneLight.outerAngle = dataLight.outerAngle;
                            sceneLight.power = dataLight.power;
                            sceneLight.type = dataLight.type;

                            //currScene.hierarchyChange = true;
                            currScene.hierarchyChange = false;
                            initializeTreeView();

                            //sceneChange = true;
                        }
                        else
                        {
                            Light_ light = (Light_)data;
                            undo.Save(currScene);
                            Light_ sceneLight = new Light_(light);

                            // przekształcenie współrzędnych
                            float x = (float)e.GetPosition(this).X - xOffset;
                            float y = (float)e.GetPosition(this).Y - yOffset;

                            translation = CalculateTranslation(x, y);

                            currScene.AddLight(sceneLight, translation);
                            //TO DO sprawdzenie czy nazwa jest unikatowa
                            //currScene.hierarchyChange = true;
                            currScene.hierarchyChange = false;
                            initializeTreeView();

                            //sceneChange = true;
                        }

                    }
                    else if (data is Camera)
                    {
                        Camera cam = (Camera)data;
                        undo.Save(currScene);

                        float x = (float)e.GetPosition(this).X - xOffset;
                        float y = (float)e.GetPosition(this).Y - yOffset;

                        translation = CalculateTranslation(x, y);

                        currScene.AddCamera(cam, translation);
                        cameraPan.comboBox1.Items.Add("Kamera " + (currScene.cams.Count()));
                        cameraPan.comboBox1.SelectedIndex = currScene.activeCamera;

                        //sceneChange = true;
                    }
                }
            }
            // Wciąganie obiektów do edytora powierzchni beziera.
            else if (tabWidok.SelectedIndex == 1)
            {
                if (e.Data.GetDataPresent("Object"))
                {
                    object data = e.Data.GetData("Object");

                    if (data is BezierSurface)
                    {
                        bezierSurface = new BezierSurface((BezierSurface)data);
                        bezierSurface.Triangulate((float)triang_Slider.Value);
                        RenderBezier();
                    }
                }
            }

            e.Handled = true;

            trNumTBG1.Text = currScene.triangles.Count().ToString();
            trNumTBG2.Text = currScene.triangles.Count().ToString();
            trNumTBG3.Text = currScene.triangles.Count().ToString();
            trNumTBG4.Text = currScene.triangles.Count().ToString();

            Renderer.RecalculateData(currScene);

            RenderViews();
            currScene.selectedHierObj = null;
        }
        public MainWindow()
        {
            try
            {
                InitializeComponent();
            }
            catch (Exception e)
            {
            }

            bezierSurface = new BezierSurface("new surface", "");
            bezierSurface.Triangulate(0.5f);

            renderer = new Renderer(Views.Handle, ViewsBezier.Handle);
            maxViewport = ViewportOrientation.None;
            mouseDownHandled = false;
            shiftingViewport = ViewportOrientation.None;
            shiftingBezierViewport = ViewportOrientation.None;
            //currScene = Scene.GetExampleScene();
            currScene = new Scene();

            // Tworzenie kolekcji obiektów i dodawanie jej do kontrolki ItemsControl
            // galerii ksztaltow.
            _shapesGallery = new ShapeGallery();
            // Wczytywanie powierzchni beziera
            ksztalty_ListView.ItemsSource = _shapesGallery;

            // Tworzenie kolekcji gotowych obiektów i dodawanie jej do kontrolki ItemsControl
            // galerii gotowych obiektów.
            _elementsGallery = new PreparedObjectsGallery();
            gotowe_ListView.ItemsSource = _elementsGallery;

            _surfaceGallery = new SurfaceGallery();
            materialy_ListView.ItemsSource = _surfaceGallery;

            _lightGallery = new LightGallery();
            swiatla_ListView.ItemsSource = _lightGallery;

            //Menu kontekstowe
            contextMenu = new System.Windows.Forms.ContextMenu();
            contextMenu.MenuItems.Add("Przenieś", contextMenuClick);
            contextMenu.MenuItems.Add("Obróć", contextMenuClick);
            contextMenu.MenuItems.Add("Skaluj", contextMenuClick);
            contextMenu.MenuItems.Add("Skaluj wzdłuż osi", contextMenuClick);
            contextMenu.MenuItems.Add("Powiększ widok", contextViewport);
            contextMenu.MenuItems.Add("Zapisz gotowy element", contextSave);
            System.Windows.Forms.MenuItem[] subMenu = new System.Windows.Forms.MenuItem[4];
            System.Windows.Forms.MenuItem subLeft = new System.Windows.Forms.MenuItem("Lewej", subLeftClick);
            System.Windows.Forms.MenuItem subRight = new System.Windows.Forms.MenuItem("Prawej", subRightClick);
            System.Windows.Forms.MenuItem subUp = new System.Windows.Forms.MenuItem("Góry", subUpClick);
            System.Windows.Forms.MenuItem subDown = new System.Windows.Forms.MenuItem("Dołu", subDownClick);
            subMenu[0] = subLeft;
            subMenu[1] = subRight;
            subMenu[2] = subUp;
            subMenu[3] = subDown;
            contextMenu.MenuItems.Add("Dosuń do", subMenu);
            contextMenu.MenuItems.Add("Kopiuj", contextCopy);
            contextMenu.MenuItems.Add("Wklej", contextPaste);
            contextMenu.MenuItems.Add("Usuń", contextDelete);
            contextMenu.MenuItems[0].Checked = true;
            Views.ContextMenu = contextMenu;

            //Menu kontekstowe dla płatów beziera
            bezierContextMenu = new ContextMenu();
            bezierContextMenu.MenuItems.Add("Zresetuj punkty", bezierContextMenuClick);
            bezierContextMenu.MenuItems.Add("Nowa powierzchnia", bezierContextMenuNewSurface);
            ViewsBezier.ContextMenu = bezierContextMenu;

            copyPaste = new CopyPaste.CopyPaste();
        }
        public void RenderBezier(ViewportInfo viewportInfo, BezierSurface bezier)
        {
            if (bezierPp.BackBufferWidth != viewportInfo.resX || bezierPp.BackBufferHeight != viewportInfo.resY || bezierImageCreated)
            {
                bezierPp = new PresentParameters();
                bezierPp.SwapEffect = SwapEffect.Discard;
                bezierPp.Windowed = true;
                bezierPp.BackBufferWidth = viewportInfo.resX;
                bezierPp.BackBufferHeight = viewportInfo.resY;
                bezierPp.BackBufferFormat = Format.A8R8G8B8;

                if (d3dBezier != null)
                {
                    d3dBezier.Dispose();
                }
                if (deviceBezier != null)
                {
                    deviceBezier.Dispose();
                }

                bezierImageCreated = false;

                d3dBezier = new Direct3D();
                deviceBezier = new Device(d3dBezier, 0, DeviceType.Hardware, handleBezier, CreateFlags.HardwareVertexProcessing, bezierPp);

                if(font2 != null)
                {
                    font2.Dispose();
                }
                font2 = new SlimDX.Direct3D9.Font(deviceBezier, new System.Drawing.Font(FontFamily.GenericSansSerif, 7));
            }

            if (top.X != viewportInfo.posX[2] || top.Y != viewportInfo.posY[2] || top.Width != viewportInfo.sizeX[2] ||
                top.Height != viewportInfo.sizeY[2])
            {
                top = new Viewport();
                top.X = viewportInfo.posX[2];
                top.Y = viewportInfo.posY[2];
                top.Width = viewportInfo.sizeX[2];
                top.Height = viewportInfo.sizeY[2];
                top.MinZ = 0;
                top.MaxZ = 1;
            }

            if (front.X != viewportInfo.posX[0] || front.Y != viewportInfo.posY[0] || front.Width != viewportInfo.sizeX[0] ||
                front.Height != viewportInfo.sizeY[0])
            {
                front = new Viewport();
                front.X = viewportInfo.posX[0];
                front.Y = viewportInfo.posY[0];
                front.Width = viewportInfo.sizeX[0];
                front.Height = viewportInfo.sizeY[0];
                front.MinZ = 0;
                front.MaxZ = 1;
            }

            if (side.X != viewportInfo.posX[1] || side.Y != viewportInfo.posY[1] || side.Width != viewportInfo.sizeX[1] ||
                side.Height != viewportInfo.sizeY[1])
            {
                side = new Viewport();
                side.X = viewportInfo.posX[1];
                side.Y = viewportInfo.posY[1];
                side.Width = viewportInfo.sizeX[1];
                side.Height = viewportInfo.sizeY[1];
                side.MinZ = 0;
                side.MaxZ = 1;
            }

            if(perspective.X != viewportInfo.posX[3] || perspective.Y != viewportInfo.posY[3] || perspective.Width != viewportInfo.sizeX[3] ||
                perspective.Height != viewportInfo.sizeY[3])
            {
                perspective = new Viewport();
                perspective.X = viewportInfo.posX[3];
                perspective.Y = viewportInfo.posY[3];
                perspective.Width = viewportInfo.sizeX[3];
                perspective.Height = viewportInfo.sizeY[3];
                perspective.MinZ = 0;
                perspective.MaxZ = 1;
            }

            deviceBezier.SetRenderState(RenderState.Lighting, true);

            deviceBezier.SetLight(0, defLight);
            deviceBezier.EnableLight(0, true);

            deviceBezier.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid);
            deviceBezier.SetRenderState(RenderState.CullMode, Cull.None);

            deviceBezier.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0);

            Vertex[] gridVertices = new Vertex[bezier.OutputPoints.Length];
            Vertex[] controlVertices = new Vertex[bezier.ControlPoints.Length];

            List<int>[] vertexTriangle = new List<int>[bezier.OutputPoints.Length];
            Parallel.For(0, vertexTriangle.Length, index => vertexTriangle[index] = new List<int>());
            /*for(int i = 0; i < vertexTriangle.Length; ++i)
            {
                vertexTriangle[i] = new List<int>();
            }*/

            int[] indices = new int[3 * bezier.triangles.Count];
            //int[] selIndices = new int[3 * scene.triangles.Count];
            uint numIndices = 0;
            //uint numSelIndices = 0;

            //bool[] selPoints = new bool[scene.points.Count];
            //Parallel.For(0, selPoints.Length, index => selPoints[index] = false);

            for (int i = 0; i < bezier.triangles.Count; i++)
            {
                indices[numIndices++] = (int)bezier.triangles[i].p1;
                indices[numIndices++] = (int)bezier.triangles[i].p2;
                indices[numIndices++] = (int)bezier.triangles[i].p3;

                vertexTriangle[bezier.triangles[i].p1].Add(i);
                vertexTriangle[bezier.triangles[i].p2].Add(i);
                vertexTriangle[bezier.triangles[i].p3].Add(i);
            }

            // Liczenie normalnych siatki trojkątów
            for (int i = 0; i < bezier.OutputPoints.Length; i++)
            {
                Vector3 normal = new Vector3();
                foreach (int face in vertexTriangle[i])
                {
                    normal += Utilities.CalculateNormal(bezier.OutputPoints[(int)bezier.triangles[face].p3], bezier.OutputPoints[(int)bezier.triangles[face].p2],
                            bezier.OutputPoints[(int)bezier.triangles[face].p1]);
                }
                normal.Normalize();

                gridVertices[i].Position = new Vector3(bezier.OutputPoints[i].x, bezier.OutputPoints[i].y, bezier.OutputPoints[i].z);
                gridVertices[i].Normal = normal;
                gridVertices[i].Color = Color.Beige.ToArgb();

            }

            Mesh gridMesh = numIndices > 2 ? new Mesh(deviceBezier, (int)numIndices / 3, bezier.OutputPoints.Length, MeshFlags.Managed | MeshFlags.Use32Bit,
                                                        vertexElems): null;
            VertexBuffer vb = gridMesh != null ? gridMesh.VertexBuffer : null;
            IndexBuffer ib = gridMesh != null ? gridMesh.IndexBuffer : null;

            if (gridMesh != null)
            {
                vb.Lock(0, 0, LockFlags.None).WriteRange(gridVertices);
                vb.Unlock();

                ib.Lock(0, 0, LockFlags.None).WriteRange(indices, 0, (int)numIndices);
                ib.Unlock();
            }

            Mesh controlPointsMesh = Mesh.CreateSphere(deviceBezier, 0.05f, 12, 12);

            if (perspective.Width > 0 && perspective.Height > 0)
            {
                deviceBezier.Viewport = perspective;
                float aspect = (float)perspective.Width / perspective.Height;

                deviceBezier.SetTransform(TransformState.View, Matrix.LookAtRH(
                    bezierCam.position,
                    bezierCam.lookAt,
                    Utilities.RotatePointAroundVector(new Vector3(0, 1, 0),
                    Vector3.Normalize(bezierCam.lookAt - bezierCam.position), bezierCam.rotateAngle)));

                deviceBezier.SetTransform(TransformState.Projection, Matrix.PerspectiveFovRH(
                    bezierCam.fovAngle,
                    aspect,
                    0.01f,
                    110000));

                deviceBezier.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.FromArgb(230, 230, 230), 1.0f, 0);
                deviceBezier.BeginScene();

                if (gridMesh != null)
                {
                    gridMesh.DrawSubset(0);
                    deviceBezier.SetRenderState(RenderState.FillMode, FillMode.Solid);

                    for (int i = 0; i < bezier.ControlPoints.Length; i++)
                    {
                        deviceBezier.SetTransform(TransformState.World, Matrix.Translation(
                                                                        bezier.ControlPoints[i].x,
                                                                        bezier.ControlPoints[i].y,
                                                                        bezier.ControlPoints[i].z));
                        if (i == bezier.selectedPointIdx)
                        {
                            deviceBezier.Material = selectedControlPointMaterial;
                            deviceBezier.SetRenderState(RenderState.Lighting, false);
                            controlPointsMesh.DrawSubset(0);
                            deviceBezier.Material = controlPointMaterial;
                            deviceBezier.SetRenderState(RenderState.Lighting, true);
                        }
                        else
                        {
                            controlPointsMesh.DrawSubset(0);
                        }
                    }
                    deviceBezier.SetTransform(TransformState.World, Matrix.Identity);
                    deviceBezier.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid);

                }

                deviceBezier.EndScene();
            }
            if (top.Width > 0 && top.Height > 0)
            {
                deviceBezier.Viewport = top;

                deviceBezier.SetTransform(TransformState.View, Matrix.LookAtRH(
                   bezierOrthoPos[2],
                   bezierOrthoLookAt[2],
                   new Vector3(0, 1, 0)));

                deviceBezier.SetTransform(TransformState.Projection, Matrix.OrthoRH(
                    bezierOrthoWidth[2],
                    (float)(top.Height) / top.Width * bezierOrthoWidth[2],
                    0.01f,
                    110000));

                deviceBezier.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.FromArgb(230, 230, 230), 1.0f, 0);
                deviceBezier.BeginScene();

                string text1 = " -z\n/|\\\n |\n";
                font2.DrawString(null, text1, viewportInfo.posX[2] + 15, viewportInfo.posY[2], Color.Blue);
                string text2 = "\n\n\n  -----> x";
                font2.DrawString(null, text2, viewportInfo.posX[2] + 15, viewportInfo.posY[2], Color.Red);

                if (gridMesh != null)
                {
                    gridMesh.DrawSubset(0);
                    deviceBezier.SetRenderState(RenderState.FillMode, FillMode.Solid);

                    for (int i = 0; i < bezier.ControlPoints.Length; i++)
                    {
                        deviceBezier.SetTransform(TransformState.World, Matrix.Translation(
                                                                        bezier.ControlPoints[i].x,
                                                                        bezier.ControlPoints[i].y,
                                                                        bezier.ControlPoints[i].z));
                        if (i == bezier.selectedPointIdx)
                        {
                            deviceBezier.Material = selectedControlPointMaterial;
                            deviceBezier.SetRenderState(RenderState.Lighting, false);
                            controlPointsMesh.DrawSubset(0);
                            deviceBezier.Material = controlPointMaterial;
                            deviceBezier.SetRenderState(RenderState.Lighting, true);
                        }
                        else
                        {
                            controlPointsMesh.DrawSubset(0);
                        }
                    }
                    deviceBezier.SetTransform(TransformState.World, Matrix.Identity);
                    deviceBezier.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid);
                }

                deviceBezier.EndScene();
            }

            if (front.Width > 0 && front.Height > 0)
            {
                deviceBezier.Viewport = front;

                deviceBezier.SetTransform(TransformState.View, Matrix.LookAtRH(
                   bezierOrthoPos[0],
                   bezierOrthoLookAt[0],
                   new Vector3(0, 1, 0)));

                deviceBezier.SetTransform(TransformState.Projection, Matrix.OrthoRH(
                    bezierOrthoWidth[0],
                    (float)(front.Height) / front.Width * bezierOrthoWidth[0],
                    0.01f,
                    110000));

                deviceBezier.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.FromArgb(230, 230, 230), 1.0f, 0);
                deviceBezier.BeginScene();

                string text1 = " y\n/|\\\n |\n";
                font2.DrawString(null, text1, viewportInfo.posX[0] + 15, viewportInfo.posY[0], Color.Green);
                string text2 = "\n\n\n  -----> x";
                font2.DrawString(null, text2, viewportInfo.posX[0] + 15, viewportInfo.posY[0], Color.Red);

                if (gridMesh != null)
                {
                    gridMesh.DrawSubset(0);
                    deviceBezier.SetRenderState(RenderState.FillMode, FillMode.Solid);

                    for (int i = 0; i < bezier.ControlPoints.Length; i++)
                    {
                        deviceBezier.SetTransform(TransformState.World, Matrix.Translation(
                                                                        bezier.ControlPoints[i].x,
                                                                        bezier.ControlPoints[i].y,
                                                                        bezier.ControlPoints[i].z));
                        if (i == bezier.selectedPointIdx)
                        {
                            deviceBezier.Material = selectedControlPointMaterial;
                            deviceBezier.SetRenderState(RenderState.Lighting, false);
                            controlPointsMesh.DrawSubset(0);
                            deviceBezier.Material = controlPointMaterial;
                            deviceBezier.SetRenderState(RenderState.Lighting, true);
                        }
                        else
                        {
                            controlPointsMesh.DrawSubset(0);
                        }
                    }
                    deviceBezier.SetTransform(TransformState.World, Matrix.Identity);
                    deviceBezier.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid);

                }

                deviceBezier.EndScene();
            }

            if (side.Width > 0 && side.Height > 0)
            {
                deviceBezier.Viewport = side;

                deviceBezier.SetTransform(TransformState.View, Matrix.LookAtRH(
                   bezierOrthoPos[1],
                   bezierOrthoLookAt[1],
                   new Vector3(0, 1, 0)));

                deviceBezier.SetTransform(TransformState.Projection, Matrix.OrthoRH(
                    bezierOrthoWidth[1],
                    (float)(side.Height) / side.Width * bezierOrthoWidth[1],
                    0.01f,
                    110000));

                deviceBezier.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.FromArgb(230, 230, 230), 1.0f, 0);
                deviceBezier.BeginScene();

                string text1 = " y\n/|\\\n |\n";
                font2.DrawString(null, text1, viewportInfo.posX[1] + 15, viewportInfo.posY[1], Color.Green);
                string text2 = "\n\n\n  -----> -z";
                font2.DrawString(null, text2, viewportInfo.posX[1] + 15, viewportInfo.posY[1], Color.Blue);

                if (gridMesh != null)
                {
                    gridMesh.DrawSubset(0);
                    deviceBezier.SetRenderState(RenderState.FillMode, FillMode.Solid);

                    for (int i = 0; i < bezier.ControlPoints.Length; i++)
                    {
                        deviceBezier.SetTransform(TransformState.World, Matrix.Translation(
                                                                        bezier.ControlPoints[i].x,
                                                                        bezier.ControlPoints[i].y,
                                                                        bezier.ControlPoints[i].z));
                        if (i == bezier.selectedPointIdx)
                        {
                            deviceBezier.Material = selectedControlPointMaterial;
                            deviceBezier.SetRenderState(RenderState.Lighting, false);
                            controlPointsMesh.DrawSubset(0);
                            deviceBezier.Material = controlPointMaterial;
                            deviceBezier.SetRenderState(RenderState.Lighting, true);
                        }
                        else
                        {
                            controlPointsMesh.DrawSubset(0);
                        }
                    }
                    deviceBezier.SetTransform(TransformState.World, Matrix.Identity);
                    deviceBezier.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid);

                }

                deviceBezier.EndScene();
            }

            deviceBezier.Present();

            gridMesh.Dispose();
            controlPointsMesh.Dispose();

            //d3dBezier.Dispose();
            //deviceBezier.Dispose();
        }
        public Image GetBezierImage(BezierSurface bezier)
        {
            pp = new PresentParameters();
            pp.SwapEffect = SwapEffect.Discard;
            pp.Windowed = true;
            pp.BackBufferWidth = 512;
            pp.BackBufferHeight = 512;
            pp.BackBufferFormat = Format.A8R8G8B8;

            if (d3dBezier != null)
            {
                d3dBezier.Dispose();
            }
            if (deviceBezier != null)
            {
                deviceBezier.Dispose();
            }

            d3dBezier = new Direct3D();
            deviceBezier = new Device(d3d, 0, DeviceType.Hardware, handle, CreateFlags.HardwareVertexProcessing, pp);

            deviceBezier.SetRenderState(RenderState.Lighting, true);

            deviceBezier.SetLight(0, defLight);
            deviceBezier.EnableLight(0, true);

            deviceBezier.SetRenderState(RenderState.FillMode, FillMode.Solid);
            deviceBezier.SetRenderState(RenderState.CullMode, Cull.None);
            deviceBezier.SetRenderState(RenderState.ShadeMode, ShadeMode.Gouraud);

            Vertex[] gridVertices = new Vertex[bezier.OutputPoints.Length];
            Vertex[] controlVertices = new Vertex[bezier.ControlPoints.Length];

            List<int>[] vertexTriangle = new List<int>[bezier.OutputPoints.Length];
            Parallel.For(0, vertexTriangle.Length, index => vertexTriangle[index] = new List<int>());
            /*for(int i = 0; i < vertexTriangle.Length; ++i)
            {
                vertexTriangle[i] = new List<int>();
            }*/

            int[] indices = new int[3 * bezier.triangles.Count];
            //int[] selIndices = new int[3 * scene.triangles.Count];
            uint numIndices = 0;
            //uint numSelIndices = 0;

            //bool[] selPoints = new bool[scene.points.Count];
            //Parallel.For(0, selPoints.Length, index => selPoints[index] = false);

            for (int i = 0; i < bezier.triangles.Count; i++)
            {
                indices[numIndices++] = (int)bezier.triangles[i].p1;
                indices[numIndices++] = (int)bezier.triangles[i].p2;
                indices[numIndices++] = (int)bezier.triangles[i].p3;

                vertexTriangle[bezier.triangles[i].p1].Add(i);
                vertexTriangle[bezier.triangles[i].p2].Add(i);
                vertexTriangle[bezier.triangles[i].p3].Add(i);
            }

            // Liczenie normalnych siatki trojkątów
            for (int i = 0; i < bezier.OutputPoints.Length; i++)
            {
                Vector3 normal = new Vector3();
                foreach (int face in vertexTriangle[i])
                {
                    normal += Utilities.CalculateNormal(bezier.OutputPoints[(int)bezier.triangles[face].p3], bezier.OutputPoints[(int)bezier.triangles[face].p2],
                            bezier.OutputPoints[(int)bezier.triangles[face].p1]);
                }
                normal.Normalize();

                gridVertices[i].Position = new Vector3(bezier.OutputPoints[i].x, bezier.OutputPoints[i].y, bezier.OutputPoints[i].z);
                gridVertices[i].Normal = normal;
                gridVertices[i].Color = Color.Beige.ToArgb();

            }

            Mesh gridMesh = numIndices > 2 ? new Mesh(deviceBezier, (int)numIndices / 3, bezier.OutputPoints.Length, MeshFlags.Managed | MeshFlags.Use32Bit,
                                                        vertexElems) : null;
            VertexBuffer vb = gridMesh != null ? gridMesh.VertexBuffer : null;
            IndexBuffer ib = gridMesh != null ? gridMesh.IndexBuffer : null;

            if (gridMesh != null)
            {
                vb.Lock(0, 0, LockFlags.None).WriteRange(gridVertices);
                vb.Unlock();

                ib.Lock(0, 0, LockFlags.None).WriteRange(indices, 0, (int)numIndices);
                ib.Unlock();
            }

            Viewport viewport = new Viewport(0, 0, 512, 512, 0, 1);

            Texture texture = new Texture(deviceBezier, 64, 64, 0, Usage.RenderTarget, Format.A8R8G8B8, Pool.Default);
            deviceBezier.SetRenderTarget(0, texture.GetSurfaceLevel(0));

            float aspect = (float)perspective.Width / perspective.Height;

            deviceBezier.SetTransform(TransformState.View, Matrix.LookAtRH(
                bezierCam.position,
                bezierCam.lookAt,
                Utilities.RotatePointAroundVector(new Vector3(0, 1, 0),
                Vector3.Normalize(bezierCam.lookAt - bezierCam.position), bezierCam.rotateAngle)));

            deviceBezier.SetTransform(TransformState.Projection, Matrix.PerspectiveFovRH(
                bezierCam.fovAngle,
                aspect,
                0.01f,
                110000));

            deviceBezier.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.White, 1.0f, 0);
            deviceBezier.BeginScene();

            if (gridMesh != null)
            {
                gridMesh.DrawSubset(0);
            }

            deviceBezier.EndScene();

            Image image = Bitmap.FromStream(Texture.ToStream(texture, ImageFileFormat.Png));

            texture.Dispose();

            bezierImageCreated = true;

            return image;
        }
        public static BezierSurface ReadFromFile(string file)
        {
            BezierSurface bezier = new BezierSurface("", "");

            try
            {
                List<string> text = FileSystem.File.ReadFileLines(file);
                int pointer = 0;

                string[] bezierName = FileSystem.File.GetAttributes(text[pointer]);
                if (bezierName[0] != "name")
                {
                    return null;
                }
                string name = FileSystem.File.CutFirstString(text[pointer]);
                ++pointer;
                bezier.Name = name;

                string numCtrlPointsLabel = FileSystem.File.GetAttribute(text[pointer], 0);
                if (numCtrlPointsLabel != "num_control_points")
                {
                    return null;
                }

                if (numControlPoints != int.Parse(FileSystem.File.GetAttribute(text[pointer++], 1)))
                {
                    return null;
                }

                for (int i = 0; i<numControlPoints; i++)
                {
                    for (int j = 0; j < numControlPoints; j++)
                    {
                        string[] attsPoint = FileSystem.File.GetAttributes(text[pointer++]);
                        bezier.ControlPoints[i*numControlPoints + j] =
                            new Vector3D(float.Parse(attsPoint[0], CultureInfo.InvariantCulture),
                                         float.Parse(attsPoint[1], CultureInfo.InvariantCulture),
                                         float.Parse(attsPoint[2], CultureInfo.InvariantCulture));
                    }
                }
            }
            catch (Exception)
            {
                return null;
            }

            return bezier;
        }