예제 #1
0
        private void floorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            List <SlopeVertexGroup> svgs = ((SlopeMode)General.Editing.Mode).GetSelectedSlopeVertexGroups();

            // Can only add sectors to one slope vertex group
            if (svgs.Count != 1)
            {
                return;
            }

            foreach (Sector s in (List <Sector>)addsectorscontextmenu.Tag)
            {
                SlopeVertexGroup rsvg = BuilderPlug.Me.GetSlopeVertexGroup(s);

                if (rsvg != null)
                {
                    rsvg.RemoveSector(s, PlaneType.Floor);
                }

                svgs[0].AddSector(s, PlaneType.Floor);
                BuilderPlug.Me.UpdateSlopes(s);
            }

            General.Interface.RedrawDisplay();
        }
예제 #2
0
        private void updateOverlaySurfaces()
        {
            string[]             fieldnames               = new string[] { "user_floorplane_id", "user_ceilingplane_id" };
            ICollection <Sector> orderedselection         = General.Map.Map.GetSelectedSectors(true);
            List <FlatVertex>    vertslist                = new List <FlatVertex>();
            List <Sector>        highlightedsectors       = new List <Sector>();
            List <Sector>        highlightedtaggedsectors = new List <Sector>();

            // Highlighted slope
            if (highlightedslope != null)
            {
                SlopeVertexGroup svg = BuilderPlug.Me.GetSlopeVertexGroup(highlightedslope);

                // All sectors the slope applies to
                foreach (Sector s in svg.Sectors)
                {
                    if (s != null && !s.IsDisposed)
                    {
                        vertslist.AddRange(s.FlatVertices);
                        highlightedsectors.Add(s);
                    }
                }

                overlaygeometry = vertslist.ToArray();

                // All sectors that are tagged because of 3D floors
                vertslist = new List <FlatVertex>();

                foreach (Sector s in svg.TaggedSectors)
                {
                    if (s != null && !s.IsDisposed)
                    {
                        vertslist.AddRange(s.FlatVertices);
                        highlightedtaggedsectors.Add(s);
                    }
                }

                overlaytaggedgeometry = vertslist.ToArray();
            }
            else
            {
                overlaygeometry       = new FlatVertex[0];
                overlaytaggedgeometry = new FlatVertex[0];
            }

            // Selected sectors
            vertslist = new List <FlatVertex>();

            foreach (Sector s in orderedselection)
            {
                if (!highlightedsectors.Contains(s))
                {
                    vertslist.AddRange(s.FlatVertices);
                }
            }

            selectedsectorgeometry = vertslist.ToArray();
        }
예제 #3
0
        public void AddSlopeVertexGroup(PlaneType pt, SlopeVertexGroup svg)
        {
            if (!slopevertexgroups[pt].Contains(svg))
            {
                slopevertexgroups[pt].Add(svg);
            }

            planetypes |= pt;
        }
예제 #4
0
        private void removeSlopeFromCeilingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Sector s in (List <Sector>)addsectorscontextmenu.Tag)
            {
                SlopeVertexGroup svg = BuilderPlug.Me.GetSlopeVertexGroup(s);

                if (svg != null)
                {
                    svg.RemoveSector(s, PlaneType.Ceiling);
                }
            }

            General.Interface.RedrawDisplay();
        }
예제 #5
0
        public List <SlopeVertexGroup> GetSelectedSlopeVertexGroups()
        {
            List <SlopeVertexGroup> svgs = new List <SlopeVertexGroup>();

            foreach (SlopeVertex sv in GetSelectedSlopeVertices())
            {
                SlopeVertexGroup svg = BuilderPlug.Me.GetSlopeVertexGroup(sv);

                if (!svgs.Contains(svg))
                {
                    svgs.Add(svg);
                }
            }

            return(svgs);
        }
예제 #6
0
        public void DeleteItem()
        {
            // Make list of selected things
            List <SlopeVertex> selected = new List <SlopeVertex>(GetSelectedSlopeVertices());

            if (highlightedslope != null)
            {
                selected.Add(highlightedslope);
            }

            // Anything to do?
            if (selected.Count > 0)
            {
                List <SlopeVertexGroup> groups = new List <SlopeVertexGroup>();

                General.Map.UndoRedo.CreateUndo("Delete slope");

                foreach (SlopeVertex sv in selected)
                {
                    SlopeVertexGroup svg = BuilderPlug.Me.GetSlopeVertexGroup(sv);

                    if (!groups.Contains(svg))
                    {
                        groups.Add(svg);
                    }
                }

                foreach (SlopeVertexGroup svg in groups)
                {
                    svg.RemoveFromSectors();
                    svg.RemoveUndoRedoUDMFFields(BuilderPlug.Me.SlopeDataSector);

                    BuilderPlug.Me.SlopeVertexGroups.Remove(svg);
                }

                General.Map.IsChanged = true;

                // Invoke a new mousemove so that the highlighted item updates
                MouseEventArgs e = new MouseEventArgs(MouseButtons.None, 0, (int)mousepos.x, (int)mousepos.y, 0);
                OnMouseMove(e);

                // Redraw screen
                General.Interface.RedrawDisplay();
            }
        }
예제 #7
0
        public SlopeVertexGroup AddSlopeVertexGroup(List <SlopeVertex> vertices, out int id)
        {
            for (int i = 1; i < int.MaxValue; i++)
            {
                if (!slopevertexgroups.Exists(x => x.Id == i))
                {
                    SlopeVertexGroup svg = new SlopeVertexGroup(i, (List <SlopeVertex>)vertices);

                    slopevertexgroups.Add(svg);

                    id = i;

                    return(svg);
                }
            }

            throw new Exception("No free slope vertex group ids");
        }
예제 #8
0
        public void UpdateSlopes(Sector s)
        {
            string[] fieldnames = new string[] { "user_floorplane_id", "user_ceilingplane_id" };

            foreach (string fn in fieldnames)
            {
                int id = s.Fields.GetValue(fn, -1);

                if (id == -1)
                {
                    if (fn == "user_floorplane_id")
                    {
                        s.FloorSlope       = new Vector3D();
                        s.FloorSlopeOffset = 0;
                    }
                    else
                    {
                        s.CeilSlope       = new Vector3D();
                        s.CeilSlopeOffset = 0;
                    }

                    continue;
                }

                List <Vector3D>  sp  = new List <Vector3D>();
                SlopeVertexGroup svg = GetSlopeVertexGroup(id);

                // If the SVG does not exist unbind the SVG info from this sector
                if (svg == null)
                {
                    s.Fields.Remove(fn);
                    continue;
                }

                if (svg.Spline)
                {
                    Vector2D        center      = new Vector2D(s.BBox.Width / 2 + s.BBox.X, s.BBox.Height / 2 + s.BBox.Y);
                    List <Line3D>   splinelines = new List <Line3D>();
                    List <Vector3D> tangents    = new List <Vector3D>();

                    sp.Add(new Vector3D(svg.Vertices[1].Pos.x, svg.Vertices[1].Pos.y, svg.Vertices[1].Z));
                    sp.Add(new Vector3D(svg.Vertices[0].Pos.x, svg.Vertices[0].Pos.y, svg.Vertices[0].Z));
                    sp.Add(new Vector3D(svg.Vertices[2].Pos.x, svg.Vertices[2].Pos.y, svg.Vertices[2].Z));

                    sp.Add(new Vector3D(sp[2].x - 96, sp[2].y, sp[2].z - 64));
                    sp.Insert(0, new Vector3D(sp[0].x + 96, sp[0].y, sp[0].z - 64));
                    //sp.Add(new Vector3D(sp[2] + (sp[2] - sp[1])));
                    //sp.Insert(0, new Vector3D(sp[0] + (sp[0] - sp[1])));


                    // Create tangents
                    tangents.Add(new Vector3D());

                    for (int i = 1; i <= 3; i++)
                    {
                        tangents.Add(new Vector3D((sp[i + 1] - sp[i - 1]) / 2.0f));
                    }

                    tangents.Add(new Vector3D());

                    Debug.Print("----- tangents -----");
                    for (int i = 0; i < tangents.Count; i++)
                    {
                        Debug.Print(tangents[i].ToString());
                    }

                    for (float u = 0.0f; u < 1.0f; u += 0.1f)
                    {
                        splinelines.Add(new Line3D(
                                            CRS(sp[0], sp[1], sp[2], sp[3], u),
                                            CRS(sp[0], sp[1], sp[2], sp[3], u + 0.1f)
                                            ));

                        /*
                         * splinelines.Add(new Line3D(
                         *              Tools.HermiteSpline(sp[1], tangents[1], sp[2], tangents[2], u),
                         *              Tools.HermiteSpline(sp[1], tangents[1], sp[2], tangents[2], u+0.1f)
                         *      )
                         * );
                         */
                    }

                    for (float u = 0.0f; u < 1.0f; u += 0.1f)
                    {
                        splinelines.Add(new Line3D(
                                            CRS(sp[1], sp[2], sp[3], sp[4], u),
                                            CRS(sp[1], sp[2], sp[3], sp[4], u + 0.1f)
                                            ));

                        /*
                         * splinelines.Add(new Line3D(
                         *              Tools.HermiteSpline(sp[2], tangents[2], sp[3], tangents[3], u),
                         *              Tools.HermiteSpline(sp[2], tangents[2], sp[3], tangents[3], u + 0.1f)
                         *      )
                         * );
                         */
                    }

                    drawlines.Clear();
                    drawlines.AddRange(splinelines);

                    drawpoints.Clear();
                    drawpoints.AddRange(sp);

                    Line2D          sl1    = new Line2D(sp[1], sp[2]);
                    Line2D          sl2    = new Line2D(sp[2], sp[3]);
                    List <Vector3D> points = new List <Vector3D>();

                    Debug.Print("----- spline lines -----");
                    foreach (Line3D l in splinelines)
                    {
                        Debug.Print(l.Start.ToString() + " / " + l.End.ToString());
                    }

                    foreach (Sidedef sd in s.Sidedefs)
                    {
                        double u       = 0.0f;
                        Plane  ldplane = new Plane(sd.Line.Start.Position, sd.Line.End.Position, new Vector3D(sd.Line.Start.Position.x, sd.Line.Start.Position.y, 128), true);

                        foreach (Line3D l in splinelines)
                        {
                            if (ldplane.GetIntersection(l.Start, l.End, ref u))
                            {
                                if (u < 0.0f || u > 1.0f)
                                {
                                    continue;
                                }

                                Vector3D v = (l.End - l.Start) * u + l.Start;
                                points.Add(v);
                            }
                        }

                        /*
                         * if(sd.Line.Line.GetIntersection(sl1, out u))
                         *      points.Add(Tools.HermiteSpline(sp[1], tangents[1], sp[2], tangents[2], u));
                         *
                         * if (sd.Line.Line.GetIntersection(sl2, out u))
                         *      points.Add(Tools.HermiteSpline(sp[2], tangents[2], sp[3], tangents[3], u));
                         */
                    }


                    if (fn == "user_floorplane_id")
                    {
                        /*
                         * s.FloorSlope = new Vector3D(p.a, p.b, p.c);
                         * s.FloorSlopeOffset = p.d;
                         */
                    }
                    else
                    {
                        List <Vector3D> ps = new List <Vector3D>();

                        if (points.Count > 2)
                        {
                            points.RemoveAt(0);
                        }

                        Vector2D perp = new Line2D(points[0], points[1]).GetPerpendicular();

                        ps.Add(points[0]);
                        ps.Add(points[1]);
                        ps.Add(new Vector3D(points[0].x + perp.x, points[0].y + perp.y, points[0].z));

                        Debug.Print("----- points -----");
                        for (int i = 0; i < ps.Count; i++)
                        {
                            Debug.Print(ps[i].ToString());
                        }

                        /*
                         * for(int i=0; i < ps.Count; i++)
                         * {
                         *      ps[i] = new Vector3D(ps[i].x, ps[i].z, ps[i].y);
                         * }
                         */

                        Debug.Print("-----");
                        for (int i = 0; i < ps.Count; i++)
                        {
                            Debug.Print(ps[i].ToString());
                        }

                        Plane p = new Plane(ps[0], ps[1], ps[2], false);

                        s.CeilSlope       = new Vector3D(p.a, p.b, p.c);
                        s.CeilSlopeOffset = p.d;
                    }
                }
                else                 // No spline
                {
                    for (int i = 0; i < svg.Vertices.Count; i++)
                    {
                        sp.Add(new Vector3D(svg.Vertices[i].Pos.x, svg.Vertices[i].Pos.y, svg.Vertices[i].Z));
                    }

                    if (svg.Vertices.Count == 2)
                    {
                        double   z             = sp[0].z;
                        Line2D   line          = new Line2D(sp[0], sp[1]);
                        Vector3D perpendicular = line.GetPerpendicular();

                        Vector2D v = sp[0] + perpendicular;

                        sp.Add(new Vector3D(v.x, v.y, z));
                    }

                    if (fn == "user_floorplane_id")
                    {
                        Plane p = new Plane(sp[0], sp[1], sp[2], true);

                        s.FloorSlope       = new Vector3D(p.a, p.b, p.c);
                        s.FloorSlopeOffset = p.d;
                        s.FloorHeight      = svg.Height;
                        svg.Height         = s.FloorHeight;
                    }
                    else
                    {
                        Plane p = new Plane(sp[0], sp[1], sp[2], false);

                        s.CeilSlope       = new Vector3D(p.a, p.b, p.c);
                        s.CeilSlopeOffset = p.d;
                        s.CeilHeight      = svg.Height;
                        svg.Height        = s.CeilHeight;
                    }
                }
            }
        }
예제 #9
0
        public void UpdateSlopes(Sector s)
        {
            string[] fieldnames = new string[] { "user_floorplane_id", "user_ceilingplane_id" };

            foreach (string fn in fieldnames)
            {
                int id = s.Fields.GetValue(fn, -1);

                if (id == -1)
                {
                    if (fn == "user_floorplane_id")
                    {
                        s.FloorSlope       = new Vector3D();
                        s.FloorSlopeOffset = 0;
                    }
                    else
                    {
                        s.CeilSlope       = new Vector3D();
                        s.CeilSlopeOffset = 0;
                    }

                    continue;
                }

                List <Vector3D>  sp  = new List <Vector3D>();
                SlopeVertexGroup svg = GetSlopeVertexGroup(id);

                // If the SVG does not exist unbind the SVG info from this sector
                if (svg == null)
                {
                    s.Fields.Remove(fn);
                    continue;
                }

                for (int i = 0; i < svg.Vertices.Count; i++)
                {
                    sp.Add(new Vector3D(svg.Vertices[i].Pos.x, svg.Vertices[i].Pos.y, svg.Vertices[i].Z));
                }

                if (svg.Vertices.Count == 2)
                {
                    float    z             = sp[0].z;
                    Line2D   line          = new Line2D(sp[0], sp[1]);
                    Vector3D perpendicular = line.GetPerpendicular();

                    Vector2D v = sp[0] + perpendicular;

                    sp.Add(new Vector3D(v.x, v.y, z));
                }

                if (fn == "user_floorplane_id")
                {
                    Plane p = new Plane(sp[0], sp[1], sp[2], true);

                    s.FloorSlope       = new Vector3D(p.a, p.b, p.c);
                    s.FloorSlopeOffset = p.d;
                    s.FloorHeight      = svg.Height;
                    svg.Height         = s.FloorHeight;
                }
                else
                {
                    Plane p = new Plane(sp[0], sp[1], sp[2], false);

                    s.CeilSlope       = new Vector3D(p.a, p.b, p.c);
                    s.CeilSlopeOffset = p.d;
                    s.CeilHeight      = svg.Height;
                    svg.Height        = s.CeilHeight;
                }
            }
        }
        public void Setup(List <SlopeVertex> vertices)
        {
            this.vertices = vertices;

            SlopeVertex      fv   = vertices[0];
            SlopeVertexGroup fsvg = BuilderPlug.Me.GetSlopeVertexGroup(fv);

            sectors = new List <Sector>();

            undodescription = "Edit slope vertex";

            if (vertices.Count > 1)
            {
                undodescription = "Edit " + vertices.Count + " slope vertices";
            }

            positionx.Text = fv.Pos.x.ToString();
            positiony.Text = fv.Pos.y.ToString();
            positionz.Text = fv.Z.ToString();

            foreach (Sector s in fsvg.Sectors)
            {
                if (!sectors.Contains(s))
                {
                    sectors.Add(s);
                }
            }

            reposition.Checked = fsvg.Reposition;
            spline.Checked     = fsvg.Spline;

            canaddsectors    = true;
            canremovesectors = true;

            if (vertices.Count > 1)
            {
                List <SlopeVertexGroup> listsvgs = new List <SlopeVertexGroup>();

                this.Text = "Edit slope vertices (" + vertices.Count.ToString() + ")";

                foreach (SlopeVertex sv in vertices)
                {
                    SlopeVertexGroup svg = BuilderPlug.Me.GetSlopeVertexGroup(sv);

                    if (!listsvgs.Contains(svg))
                    {
                        listsvgs.Add(svg);
                    }

                    if (sv.Pos.x.ToString() != positionx.Text)
                    {
                        positionx.Text = "";
                    }

                    if (sv.Pos.y.ToString() != positiony.Text)
                    {
                        positiony.Text = "";
                    }

                    if (sv.Z.ToString() != positionz.Text)
                    {
                        positionz.Text = "";
                    }

                    if (svg.Reposition != reposition.Checked)
                    {
                        reposition.CheckState = CheckState.Indeterminate;
                    }

                    if (svg.Spline)
                    {
                        spline.Enabled = true;
                    }

                    if (svg.Spline != spline.Checked)
                    {
                        spline.CheckState = CheckState.Indeterminate;
                    }

                    foreach (Sector s in svg.Sectors)
                    {
                        if (!sectors.Contains(s))
                        {
                            sectors.Add(s);
                        }
                    }
                }

                if (listsvgs.Count > 2)
                {
                    canaddsectors    = false;
                    canremovesectors = false;
                }
            }

            foreach (Sector s in sectors.OrderBy(x => x.Index))
            {
                checkedListBoxSectors.Items.Add(s);
            }

            if (General.Map.Map.SelectedSectorsCount == 0)
            {
                addselectedsectorsceiling.Enabled    = false;
                removeselectedsectorsceiling.Enabled = false;
                addselectedsectorsfloor.Enabled      = false;
                removeselectedsectorsfloor.Enabled   = false;
            }
            else
            {
                addselectedsectorsceiling.Enabled    = canaddsectors;
                removeselectedsectorsceiling.Enabled = canremovesectors;
                addselectedsectorsfloor.Enabled      = canaddsectors;
                removeselectedsectorsfloor.Enabled   = canremovesectors;
            }
        }
        private void apply_Click(object sender, EventArgs e)
        {
            List <SlopeVertexGroup> groups = new List <SlopeVertexGroup>();

            // undodescription was set in the Setup method
            General.Map.UndoRedo.CreateUndo(undodescription);

            foreach (SlopeVertex sv in vertices)
            {
                SlopeVertexGroup svg = BuilderPlug.Me.GetSlopeVertexGroup(sv);
                float            x   = positionx.GetResultFloat(sv.Pos.x);
                float            y   = positiony.GetResultFloat(sv.Pos.y);

                sv.Pos = new Vector2D(x, y);

                sv.Z = positionz.GetResultFloat(sv.Z);

                if (!groups.Contains(svg))
                {
                    groups.Add(svg);
                }
            }

            foreach (SlopeVertexGroup svg in groups)
            {
                if (reposition.CheckState != CheckState.Indeterminate)
                {
                    svg.Reposition = reposition.Checked;
                }

                if (spline.CheckState != CheckState.Indeterminate && svg.Vertices.Count == 3)
                {
                    svg.Spline = spline.Checked;
                }

                // Ceiling
                if (addselectedsectorsceiling.Checked)
                {
                    foreach (Sector s in General.Map.Map.GetSelectedSectors(true).ToList())
                    {
                        svg.AddSector(s, PlaneType.Ceiling);
                    }
                }

                if (removeselectedsectorsceiling.Checked)
                {
                    foreach (Sector s in General.Map.Map.GetSelectedSectors(true).ToList())
                    {
                        if (svg.Sectors.Contains(s))
                        {
                            svg.RemoveSector(s, PlaneType.Ceiling);
                        }
                    }
                }

                // Floor
                if (addselectedsectorsfloor.Checked)
                {
                    foreach (Sector s in General.Map.Map.GetSelectedSectors(true).ToList())
                    {
                        svg.AddSector(s, PlaneType.Floor);
                    }
                }

                if (removeselectedsectorsfloor.Checked)
                {
                    foreach (Sector s in General.Map.Map.GetSelectedSectors(true).ToList())
                    {
                        if (svg.Sectors.Contains(s))
                        {
                            svg.RemoveSector(s, PlaneType.Floor);
                        }
                    }
                }

                foreach (Sector s in checkedListBoxSectors.CheckedItems)
                {
                    if (svg.Sectors.Contains(s))
                    {
                        svg.RemoveSector(s, PlaneType.Floor);
                        svg.RemoveSector(s, PlaneType.Ceiling);
                    }
                }

                svg.ApplyToSectors();
            }

            BuilderPlug.Me.StoreSlopeVertexGroupsInSector();

            this.DialogResult = DialogResult.OK;
        }
예제 #12
0
        public override bool OnPasteBegin(PasteOptions options)
        {
            if (copyslopevertexgroups == null || copyslopevertexgroups.Count == 0)
            {
                return(false);
            }

            // Unselect all slope vertices, so the pasted vertices can be selected
            foreach (SlopeVertexGroup svg in BuilderPlug.Me.SlopeVertexGroups)
            {
                svg.SelectVertices(false);
            }

            float l = copyslopevertexgroups[0].Vertices[0].Pos.x;
            float r = copyslopevertexgroups[0].Vertices[0].Pos.x;
            float t = copyslopevertexgroups[0].Vertices[0].Pos.y;
            float b = copyslopevertexgroups[0].Vertices[0].Pos.y;

            // Find the outer dimensions of all SVGs to paste
            foreach (SlopeVertexGroup svg in copyslopevertexgroups)
            {
                foreach (SlopeVertex sv in svg.Vertices)
                {
                    if (sv.Pos.x < l)
                    {
                        l = sv.Pos.x;
                    }
                    if (sv.Pos.x > r)
                    {
                        r = sv.Pos.x;
                    }
                    if (sv.Pos.y > t)
                    {
                        t = sv.Pos.y;
                    }
                    if (sv.Pos.y < b)
                    {
                        b = sv.Pos.y;
                    }
                }
            }

            Vector2D center = new Vector2D(l + ((r - l) / 2), b + ((t - b) / 2));
            Vector2D diff   = center - General.Map.Grid.SnappedToGrid(mousemappos);

            foreach (SlopeVertexGroup svg in copyslopevertexgroups)
            {
                int id;
                List <SlopeVertex> newsv = new List <SlopeVertex>();

                foreach (SlopeVertex sv in svg.Vertices)
                {
                    newsv.Add(new SlopeVertex(new Vector2D(sv.Pos.x - diff.x, sv.Pos.y - diff.y), sv.Z));
                }

                SlopeVertexGroup newsvg = BuilderPlug.Me.AddSlopeVertexGroup(newsv, out id);
                newsvg.SelectVertices(true);
            }

            // Redraw the display, so that pasted SVGs are shown immediately
            General.Interface.RedrawDisplay();

            // Don't go into the standard process for pasting, so tell the core that
            // pasting should not proceed
            return(false);
        }
        // Accepted
        public override void OnAccept()
        {
            Cursor.Current = Cursors.AppStarting;

            General.Settings.FindDefaultDrawSettings();

            // When points have been drawn
            if (points.Count > 1)
            {
                // Make undo for the draw
                General.Map.UndoRedo.CreateUndo("Draw slope");

                List <SlopeVertex> sv_floor   = new List <SlopeVertex>();
                List <SlopeVertex> sv_ceiling = new List <SlopeVertex>();

                // Fills the slope vertex list for both floor and ceiling slopes. Alos tried
                // to determine the default z position of the vertex
                List <Sector> selected = (List <Sector>)General.Map.Map.GetSelectedSectors(true);
                if (selected.Count == 1 && IsControlSector(selected[0]))
                {
                    //If a 3D floor control sector is selected, then just use the height of it directly
                    float zf = selected[0].FloorHeight;
                    float zc = selected[0].CeilHeight;
                    for (int i = 0; i < points.Count; i++)
                    {
                        sv_floor.Add(new SlopeVertex(points[i].pos, zf));
                        sv_ceiling.Add(new SlopeVertex(points[i].pos, zc));
                    }
                }
                else
                {
                    //For normal sectors, grab the height of the sector each control handle lies within
                    for (int i = 0; i < points.Count; i++)
                    {
                        float  zf = 0;
                        float  zc = 0;
                        Sector s  = General.Map.Map.GetSectorByCoordinates(points[i].pos);

                        if (s != null)
                        {
                            foreach (Sidedef sd in s.Sidedefs)
                            {
                                if (sd.Line.Line.GetSideOfLine(points[i].pos) == 0)
                                {
                                    if (sd.Line.Back != null && !selected.Contains(sd.Line.Back.Sector))
                                    {
                                        zf = sd.Line.Back.Sector.FloorHeight;
                                        zc = sd.Line.Back.Sector.CeilHeight;
                                    }
                                    else
                                    {
                                        zf = sd.Line.Front.Sector.FloorHeight;
                                        zc = sd.Line.Front.Sector.CeilHeight;
                                    }
                                }
                            }
                        }

                        sv_floor.Add(new SlopeVertex(points[i].pos, zf));
                        sv_ceiling.Add(new SlopeVertex(points[i].pos, zc));
                    }
                }

                // Create the floor slope vertex group and add it to all selected sectors
                if (slopedrawingmode == SlopeDrawingMode.Floor || slopedrawingmode == SlopeDrawingMode.FloorAndCeiling)
                {
                    int id = -1;
                    SlopeVertexGroup svg = BuilderPlug.Me.AddSlopeVertexGroup(sv_floor, out id);

                    svg.Sectors.Clear();

                    foreach (Sector s in selected)
                    {
                        // Make sure the field work with undo/redo
                        s.Fields.BeforeFieldsChange();

                        if (s.Fields.ContainsKey("user_floorplane_id"))
                        {
                            s.Fields.Remove("user_floorplane_id");
                        }

                        s.Fields.Add("user_floorplane_id", new UniValue(UniversalType.Integer, id));

                        // svg.Sectors.Add(s);

                        svg.AddSector(s, PlaneType.Floor);
                    }
                }

                // Create the ceiling slope vertex group and add it to all selected sectors
                if (slopedrawingmode == SlopeDrawingMode.Ceiling || slopedrawingmode == SlopeDrawingMode.FloorAndCeiling)
                {
                    int id = -1;
                    SlopeVertexGroup svg = BuilderPlug.Me.AddSlopeVertexGroup(sv_ceiling, out id);

                    svg.Sectors.Clear();

                    foreach (Sector s in selected)
                    {
                        // Make sure the field work with undo/redo
                        s.Fields.BeforeFieldsChange();

                        if (s.Fields.ContainsKey("user_ceilingplane_id"))
                        {
                            s.Fields.Remove("user_ceilingplane_id");
                        }

                        s.Fields.Add("user_ceilingplane_id", new UniValue(UniversalType.Integer, id));

                        // svg.Sectors.Add(s);
                        svg.AddSector(s, PlaneType.Ceiling);
                    }
                }

                BuilderPlug.Me.StoreSlopeVertexGroupsInSector();

                // BuilderPlug.Me.UpdateSlopes();

                // Clear selection
                General.Map.Map.ClearAllSelected();

                // Update cached values
                General.Map.Map.Update();

                // Map is changed
                General.Map.IsChanged = true;
            }

            // Done
            Cursor.Current = Cursors.Default;

            // Return to original mode
            General.Editing.ChangeMode(General.Editing.PreviousStableMode.Name);
        }