コード例 #1
0
        //
        // Order in which events occur when switching editing modes:
        //
        // - Constructor of new mode is called
        // - OnDisengage() of old mode is called
        // ----- Mode switches -----
        // - OnEngage() of new mode is called
        // - Dispose() of old mode is called
        //
        // This function is called when this editing mode is engaged
        public override void OnEngage()
        {
            base.OnEngage();

            // Here we load our image. The image is loaded from resource that is embedded
            // in this project. This is done by simply adding the PNG file to the project
            // and set the Build Action property of the image to "Embedded Resource".
            // Embedded means that the image will be compiled into your plugin .DLL file so
            // you don't have to distribute this image separately.
            exampleimage = new ResourceImage("CodeImp.DoomBuilder.Plugins.ImageDrawingExample.exampleimage.png");

            // The image is not always directly loaded. Call this to ensure that the image is loaded immediately.
            exampleimage.LoadImage();
            if (exampleimage.LoadFailed)
            {
                throw new Exception("Unable to load the exampleimage.png resource!");
            }

            // After loading, the image is usable by the GDI (GetBitmap() function) but we want to use
            // it for rendering in the working area. We must call CreateTexture to tranfer the image to
            // the vido memory as texture.
            exampleimage.CreateTexture();

            // This tells the renderer how to display the map.
            // The renderer works with several different layers, each with its own purpose
            // and features. A "presentation" defines how to combine these layers when
            // presented to the user on the display. Here I make a special presentation
            // that includes only the layer we need: the Overlay layer.
            CustomPresentation p = new CustomPresentation();

            p.AddLayer(new PresentLayer(RendererLayer.Overlay, BlendingMode.None, 1.0f, false));
            renderer.SetPresentation(p);
        }
コード例 #2
0
        // Mode engages
        public override void OnEngage()
        {
            base.OnEngage();

            General.Interface.AddButton(BuilderPlug.Me.MenusForm.ColorConfiguration);

            panel = new SoundEnvironmentPanel();
            panel.OnShowWarningsOnlyChanged += PanelOnOnShowWarningsOnlyChanged;
            docker = new Docker("soundenvironments", "Sound Environments", panel);
            General.Interface.AddDocker(docker, true);
            General.Interface.SelectDocker(docker);

            worker = new BackgroundWorker();
            worker.WorkerReportsProgress      = true;
            worker.WorkerSupportsCancellation = true;

            worker.DoWork             += BuilderPlug.Me.UpdateSoundEnvironments;
            worker.ProgressChanged    += worker_ProgressChanged;
            worker.RunWorkerCompleted += worker_RunWorkerCompleted;

            UpdateData();

            CustomPresentation presentation = new CustomPresentation();

            presentation.AddLayer(new PresentLayer(RendererLayer.Background, BlendingMode.Mask, General.Settings.BackgroundAlpha));
            presentation.AddLayer(new PresentLayer(RendererLayer.Grid, BlendingMode.Mask));
            presentation.AddLayer(new PresentLayer(RendererLayer.Overlay, BlendingMode.Alpha, 1f, true));
            presentation.AddLayer(new PresentLayer(RendererLayer.Things, BlendingMode.Alpha, 1.0f));
            presentation.AddLayer(new PresentLayer(RendererLayer.Geometry, BlendingMode.Alpha, 1f, true));
            renderer.SetPresentation(presentation);
        }
コード例 #3
0
        // Mode engages
        public override void OnEngage()
        {
            base.OnEngage();

            // Add toolbar buttons
            General.Interface.AddButton(BuilderPlug.Me.MenusForm.ViewSelectionNumbers);
            General.Interface.AddButton(BuilderPlug.Me.MenusForm.SeparatorSectors1);
            General.Interface.AddButton(BuilderPlug.Me.MenusForm.MakeGradientBrightness);

            // Make custom presentation
            CustomPresentation p = new CustomPresentation();

            p.AddLayer(new PresentLayer(RendererLayer.Background, BlendingMode.Mask, General.Settings.BackgroundAlpha));
            p.AddLayer(new PresentLayer(RendererLayer.Grid, BlendingMode.Mask));
            p.AddLayer(new PresentLayer(RendererLayer.Surface, BlendingMode.Mask));
            p.AddLayer(new PresentLayer(RendererLayer.Overlay, BlendingMode.Alpha, 1f, true));
            //p.AddLayer(new PresentLayer(RendererLayer.Things, BlendingMode.Alpha, Presentation.THINGS_BACK_ALPHA, false));
            p.AddLayer(new PresentLayer(RendererLayer.Geometry, BlendingMode.Alpha, 1f, true));
            renderer.SetPresentation(p);

            // Make text labels for sectors
            SetupLabels();

            // Convert geometry selection to sectors only
            General.Map.Map.ConvertSelection(SelectionType.Sectors);

            // Update
            General.Map.Map.SelectionType = SelectionType.Sectors;
            UpdateSelectedLabels();
            UpdateOverlay();
        }
コード例 #4
0
        // Mode engages
        public override void OnEngage()
        {
            base.OnEngage();

            // Nothing highlighted
            highlighted = null;
            hx          = -1;
            hy          = -1;

            // Custom presentation to hide the grid
            CustomPresentation p = new CustomPresentation();

            p.AddLayer(new PresentLayer(RendererLayer.Background, BlendingMode.Mask, General.Settings.BackgroundAlpha));
            p.AddLayer(new PresentLayer(RendererLayer.Surface, BlendingMode.Mask));
            p.AddLayer(new PresentLayer(RendererLayer.Overlay, BlendingMode.Alpha, 1f, true));
            p.AddLayer(new PresentLayer(RendererLayer.Things, BlendingMode.Alpha, 1.0f));
            p.AddLayer(new PresentLayer(RendererLayer.Geometry, BlendingMode.Alpha, 1f, true));
            renderer.SetPresentation(p);

            // Make the blockmap
            RectangleF area = MapSet.CreateArea(General.Map.Map.Vertices);

            area     = MapSet.IncreaseArea(area, General.Map.Map.Things);
            blockmap = new BlockMap <BlockEntry>(area);
            blockmap.AddLinedefsSet(General.Map.Map.Linedefs);
            blockmap.AddSectorsSet(General.Map.Map.Sectors);
            blockmap.AddThingsSet(General.Map.Map.Things);
        }
コード例 #5
0
		// Mode engages
		public override void OnEngage()
		{
			base.OnEngage();

			huntingThings = new List<Thing>();
			propagationdomains = new List<SoundPropagationDomain>();
			sector2domain = new Dictionary<Sector, SoundPropagationDomain>();
			BuilderPlug.Me.BlockingLinedefs = new List<Linedef>();

			UpdateData();

			General.Interface.AddButton(BuilderPlug.Me.MenusForm.ColorConfiguration);

			CustomPresentation presentation = new CustomPresentation();
			presentation.AddLayer(new PresentLayer(RendererLayer.Background, BlendingMode.Mask, General.Settings.BackgroundAlpha));
			presentation.AddLayer(new PresentLayer(RendererLayer.Grid, BlendingMode.Mask));
			presentation.AddLayer(new PresentLayer(RendererLayer.Overlay, BlendingMode.Alpha, 1.0f, true));
			presentation.AddLayer(new PresentLayer(RendererLayer.Things, BlendingMode.Alpha, 1.0f));
			presentation.AddLayer(new PresentLayer(RendererLayer.Geometry, BlendingMode.Alpha, 1.0f, true));
			renderer.SetPresentation(presentation);

			// Convert geometry selection to sectors only
			General.Map.Map.ConvertSelection(SelectionType.Sectors);

			UpdateSoundPropagation();
			General.Interface.RedrawDisplay();
		}
コード例 #6
0
        // Mode starts
        public override void OnEngage()
        {
            Cursor.Current = Cursors.WaitCursor;
            base.OnEngage();

            BuilderPlug.Me.CleanUpRejectStates();

            if (!General.Map.LumpExists("REJECT") || General.Map.IsChanged)
            {
                // Outdated or missing reject map
                bool result = General.Map.RebuildNodes(General.Map.ConfigSettings.NodebuilderSave, true);
                if (!result || !General.Map.LumpExists("REJECT"))
                {
                    MessageBox.Show("Unable to find the REJECT table. Check your nodebuilder settings and make sure you are using a nodebuilder that generates a reject table.", "Reject Editing mode", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    General.Editing.CancelMode();
                    return;
                }
            }

            // During overlay rendering, we use this list to keep track of sectors
            // we have manually set. This is only for performance optimization.
            manualsectors = new bool[General.Map.Map.Sectors.Count];

            // If the reject map was not obtained yet, try to rebuild
            // the nodes to get the latest reject map.
            if (BuilderPlug.Me.UnmodifiedTable == null)
            {
                // Invalid reject map
                bool result = General.Map.RebuildNodes(General.Map.ConfigSettings.NodebuilderSave, true);
                if (!result || (BuilderPlug.Me.UnmodifiedTable == null))
                {
                    MessageBox.Show("The nodebuilder is generating an invalid REJECT table. Check your nodebuilder settings and make sure you are using a nodebuilder that generates a proper reject table.", "Reject Editing mode", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    General.Editing.CancelMode();
                    return;
                }
            }

            // Setup presentation
            CustomPresentation presentation = new CustomPresentation();

            presentation.AddLayer(new PresentLayer(RendererLayer.Background, BlendingMode.Mask, General.Settings.BackgroundAlpha));
            presentation.AddLayer(new PresentLayer(RendererLayer.Grid, BlendingMode.Mask));
            presentation.AddLayer(new PresentLayer(RendererLayer.Surface, BlendingMode.Mask));
            presentation.AddLayer(new PresentLayer(RendererLayer.Overlay, BlendingMode.Alpha, OVERLAY_ALPHA, true));
            presentation.AddLayer(new PresentLayer(RendererLayer.Geometry, BlendingMode.Alpha, 1f, true));
            renderer.SetPresentation(presentation);

            Cursor.Current = Cursors.Default;
            General.Interface.DisplayReady();
            General.Interface.RedrawDisplay();
        }
コード例 #7
0
        // Mode engages
        public override void OnEngage()
        {
            base.OnEngage();

            // Make customized presentation
            CustomPresentation p = new CustomPresentation();

            p.AddLayer(new PresentLayer(RendererLayer.Background, BlendingMode.Mask, General.Settings.BackgroundAlpha));
            p.AddLayer(new PresentLayer(RendererLayer.Surface, BlendingMode.Mask));
            p.AddLayer(new PresentLayer(RendererLayer.Grid, BlendingMode.Mask));
            p.AddLayer(new PresentLayer(RendererLayer.Overlay, BlendingMode.Alpha, 1f, true));
            p.AddLayer(new PresentLayer(RendererLayer.Things, BlendingMode.Alpha, Presentation.THINGS_BACK_ALPHA, false));
            p.AddLayer(new PresentLayer(RendererLayer.Geometry, BlendingMode.Alpha, 1f, true));
            renderer.SetPresentation(p);
            General.Map.Map.SelectionType = SelectionType.All;
        }
コード例 #8
0
        // Mode engages
        public override void OnEngage()
        {
            base.OnEngage();
            renderer.DrawMapCenter = false;             //mxd

            // Automap presentation without the surfaces
            automappresentation = new CustomPresentation();
            automappresentation.AddLayer(new PresentLayer(RendererLayer.Overlay, BlendingMode.Mask));
            automappresentation.AddLayer(new PresentLayer(RendererLayer.Grid, BlendingMode.Mask));
            automappresentation.AddLayer(new PresentLayer(RendererLayer.Geometry, BlendingMode.Alpha, 1f, true));
            renderer.SetPresentation(automappresentation);

            UpdateValidLinedefs();
            UpdateSecretSectors();             //mxd

            //mxd. Show UI
            menusform.Register();
        }
コード例 #9
0
        // Mode starts
        public override void OnEngage()
        {
            Cursor.Current = Cursors.WaitCursor;
            base.OnEngage();
            General.Interface.DisplayStatus(StatusType.Busy, "Setting up test environment...");

            BuilderPlug.InitVPO();             //mxd

            CleanUp();

            BuilderPlug.InterfaceForm.AddToInterface();
            BuilderPlug.InterfaceForm.OnOpenDoorsChanged += OnOpenDoorsChanged;             //mxd
            lastviewstats = BuilderPlug.InterfaceForm.ViewStats;

            // Export the current map to a temporary WAD file
            tempfile = BuilderPlug.MakeTempFilename(".wad");
            if (!General.Map.ExportToFile(tempfile))
            {
                //mxd. Abort on export fail
                Cursor.Current = Cursors.Default;
                General.Interface.DisplayStatus(StatusType.Warning, "Unable to set test environment...");
                OnCancel();
                return;
            }

            // Load the map in VPO_DLL
            BuilderPlug.VPO.Start(tempfile, General.Map.Options.LevelName);

            // Determine map boundary
            mapbounds = Rectangle.Round(MapSet.CreateArea(General.Map.Map.Vertices));

            // Create tiles for all points inside the map
            CreateTiles();             //mxd

            QueuePoints(0);

            // Make an image to draw on.
            // The BitmapImage for Doom Builder's resources must be Format32bppArgb and NOT using color correction,
            // otherwise DB will make a copy of the bitmap when LoadImage() is called! This is normally not a problem,
            // but we want to keep drawing to the same bitmap.
            int width  = General.NextPowerOf2(General.Interface.Display.ClientSize.Width);
            int height = General.NextPowerOf2(General.Interface.Display.ClientSize.Height);

            canvas = new Bitmap(width, height, PixelFormat.Format32bppArgb);
            image  = new DynamicBitmapImage(canvas, "_CANVAS_");
            image.UseColorCorrection = false;
            image.MipMapLevels       = 1;
            image.LoadImageNow();

            // Make custom presentation
            CustomPresentation p = new CustomPresentation();

            p.AddLayer(new PresentLayer(RendererLayer.Overlay, BlendingMode.Mask, 1f, false));
            p.AddLayer(new PresentLayer(RendererLayer.Grid, BlendingMode.Mask));
            p.AddLayer(new PresentLayer(RendererLayer.Geometry, BlendingMode.Alpha, 1f, true));
            renderer.SetPresentation(p);

            // Setup processing
            nextupdate = Clock.CurrentTime + 100;
            General.Interface.EnableProcessing();
            processingenabled = true;

            RedrawAllTiles();
            Cursor.Current = Cursors.Default;
            General.Interface.SetCursor(Cursors.Cross);
            General.Interface.DisplayReady();
        }
コード例 #10
0
        // Mode starts
        public override void OnEngage()
        {
            Cursor.Current = Cursors.WaitCursor;
            base.OnEngage();

            //mxd
            bool haveNodes   = General.Map.LumpExists("NODES");
            bool haveZnodes  = General.Map.LumpExists("ZNODES");
            bool haveSectors = General.Map.LumpExists("SSECTORS");
            bool haveSegs    = General.Map.LumpExists("SEGS");
            bool haveVerts   = General.Map.LumpExists("VERTEXES");

            if (General.Map.IsChanged || !(haveZnodes || (haveNodes || haveSectors || haveSegs || haveVerts)))
            {
                // We need to build the nodes!
                if (!General.Map.RebuildNodes(General.Map.ConfigSettings.NodebuilderSave, true))
                {
                    return;
                }

                //mxd. Update nodes availability
                haveNodes   = General.Map.LumpExists("NODES");
                haveZnodes  = General.Map.LumpExists("ZNODES");
                haveSectors = General.Map.LumpExists("SSECTORS");
                haveSegs    = General.Map.LumpExists("SEGS");
                haveVerts   = General.Map.LumpExists("VERTEXES");
            }

            //mxd
            if (haveZnodes)
            {
                General.Interface.DisplayStatus(StatusType.Busy, "Reading map nodes...");
                if (!LoadZNodes())
                {
                    General.Interface.DisplayStatus(StatusType.Warning, "Failed to read map nodes.");
                    General.Editing.CancelMode();
                    return;
                }
            }
            else
            {
                if (!haveNodes)
                {
                    MessageBox.Show("Unable to find the NODES lump. It may be that the nodes could not be built correctly.", "Nodes Viewer mode", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    General.Editing.CancelMode();
                    return;
                }

                if (!haveSectors)
                {
                    MessageBox.Show("Unable to find the SSECTORS lump. It may be that the nodes could not be built correctly.", "Nodes Viewer mode", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    General.Editing.CancelMode();
                    return;
                }

                if (!haveSegs)
                {
                    MessageBox.Show("Unable to find the SEGS lump. It may be that the nodes could not be built correctly.", "Nodes Viewer mode", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    General.Editing.CancelMode();
                    return;
                }

                if (!haveVerts)
                {
                    MessageBox.Show("Unable to find the VERTEXES lump. It may be that the nodes could not be built correctly.", "Nodes Viewer mode", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    General.Editing.CancelMode();
                    return;
                }

                General.Interface.DisplayStatus(StatusType.Busy, "Reading map nodes...");
                if (!LoadClassicStructures())
                {
                    General.Interface.DisplayStatus(StatusType.Warning, "Failed to read map nodes.");
                    General.Editing.CancelMode();
                    return;
                }
            }

            // Setup presentation
            CustomPresentation presentation = new CustomPresentation();

            presentation.AddLayer(new PresentLayer(RendererLayer.Background, BlendingMode.Mask, General.Settings.BackgroundAlpha));
            presentation.AddLayer(new PresentLayer(RendererLayer.Grid, BlendingMode.Mask));
            presentation.AddLayer(new PresentLayer(RendererLayer.Overlay, BlendingMode.Alpha, 1f, true));
            presentation.AddLayer(new PresentLayer(RendererLayer.Geometry, BlendingMode.Alpha, 1f, true));
            renderer.SetPresentation(presentation);

            General.Interface.DisplayStatus(StatusType.Busy, "Building subsectors...");

            RecursiveBuildSubsectorPoly(nodes.Length - 1, new Stack <Split>(nodes.Length / 2 + 1));

            // Load and display dialog window
            form       = new NodesForm(this);
            form.Text += " (" + nodesformat + " format)";
            form.Show((Form)General.Interface);

            Cursor.Current = Cursors.Default;
            General.Interface.DisplayReady();
            General.Interface.RedrawDisplay();
        }
コード例 #11
0
        // Mode starts
        public override void OnEngage()
        {
            Cursor.Current = Cursors.WaitCursor;
            base.OnEngage();
            General.Interface.DisplayStatus(StatusType.Busy, "Setting up test environment...");

            CleanUp();

            BuilderPlug.InterfaceForm.AddToInterface();
            lastviewstats = BuilderPlug.InterfaceForm.ViewStats;

            // Export the current map to a temporary WAD file
            tempfile = BuilderPlug.MakeTempFilename(".wad");
            General.Map.ExportToFile(tempfile);

            // Load the map in VPO_DLL
            BuilderPlug.VPO.Start(tempfile, General.Map.Options.LevelName);

            // Determine map boundary
            mapbounds = Rectangle.Round(MapSet.CreateArea(General.Map.Map.Vertices));

            // Create tiles for all points inside the map
            Point               lt        = TileForPoint(mapbounds.Left - Tile.TILE_SIZE, mapbounds.Top - Tile.TILE_SIZE);
            Point               rb        = TileForPoint(mapbounds.Right + Tile.TILE_SIZE, mapbounds.Bottom + Tile.TILE_SIZE);
            Rectangle           tilesrect = new Rectangle(lt.X, lt.Y, rb.X - lt.X, rb.Y - lt.Y);
            NearestLineBlockmap blockmap  = new NearestLineBlockmap(tilesrect);

            for (int x = tilesrect.X; x <= tilesrect.Right; x += Tile.TILE_SIZE)
            {
                for (int y = tilesrect.Y; y <= tilesrect.Bottom; y += Tile.TILE_SIZE)
                {
                    // If the tile is obviously outside the map, don't create it
                    Vector2D pc         = new Vector2D(x + (Tile.TILE_SIZE >> 1), y + (Tile.TILE_SIZE >> 1));
                    Linedef  ld         = MapSet.NearestLinedef(blockmap.GetBlockAt(pc).Lines, pc);
                    float    distancesq = ld.DistanceToSq(pc, true);
                    if (distancesq > (Tile.TILE_SIZE * Tile.TILE_SIZE))
                    {
                        float side = ld.SideOfLine(pc);
                        if ((side > 0.0f) && (ld.Back == null))
                        {
                            continue;
                        }
                    }

                    Point tp = new Point(x, y);
                    tiles.Add(tp, new Tile(tp));
                }
            }

            QueuePoints(0);

            // Make an image to draw on.
            // The BitmapImage for Doom Builder's resources must be Format32bppArgb and NOT using color correction,
            // otherwise DB will make a copy of the bitmap when LoadImage() is called! This is normally not a problem,
            // but we want to keep drawing to the same bitmap.
            int width  = General.NextPowerOf2(General.Interface.Display.ClientSize.Width);
            int height = General.NextPowerOf2(General.Interface.Display.ClientSize.Height);

            canvas = new Bitmap(width, height, PixelFormat.Format32bppArgb);
            image  = new DynamicBitmapImage(canvas, "_CANVAS_");
            image.UseColorCorrection = false;
            image.MipMapLevels       = 1;
            image.LoadImage();
            image.CreateTexture();

            // Make custom presentation
            CustomPresentation p = new CustomPresentation();

            p.AddLayer(new PresentLayer(RendererLayer.Overlay, BlendingMode.Mask, 1f, false));
            p.AddLayer(new PresentLayer(RendererLayer.Grid, BlendingMode.Mask));
            p.AddLayer(new PresentLayer(RendererLayer.Geometry, BlendingMode.Alpha, 1f, true));
            renderer.SetPresentation(p);

            // Setup processing
            nextupdate = DateTime.Now + new TimeSpan(0, 0, 0, 0, 100);
            General.Interface.EnableProcessing();
            processingenabled = true;

            RedrawAllTiles();
            Cursor.Current = Cursors.Default;
            General.Interface.SetCursor(Cursors.Cross);
            General.Interface.DisplayReady();
        }
コード例 #12
0
ファイル: NodesViewerMode.cs プロジェクト: volte/doombuilderx
        // Mode starts
        public override void OnEngage()
        {
            Cursor.Current = Cursors.WaitCursor;
            base.OnEngage();

            if (!General.Map.LumpExists("NODES") || !General.Map.LumpExists("SSECTORS") || !General.Map.LumpExists("SEGS") || !General.Map.LumpExists("VERTEXES"))
            {
                // We need to build the nodes!
                if (!General.Map.RebuildNodes(General.Map.ConfigSettings.NodebuilderSave, true))
                {
                    return;
                }
            }

            if (!General.Map.LumpExists("NODES"))
            {
                MessageBox.Show("Unable to find the NODES lump. It may be that the nodes could not be built correctly.", "Nodes Viewer mode", MessageBoxButtons.OK, MessageBoxIcon.Error);
                General.Editing.CancelMode();
                return;
            }

            if (!General.Map.LumpExists("SSECTORS"))
            {
                MessageBox.Show("Unable to find the SSECTORS lump. It may be that the nodes could not be built correctly.", "Nodes Viewer mode", MessageBoxButtons.OK, MessageBoxIcon.Error);
                General.Editing.CancelMode();
                return;
            }

            if (!General.Map.LumpExists("SEGS"))
            {
                MessageBox.Show("Unable to find the SEGS lump. It may be that the nodes could not be built correctly.", "Nodes Viewer mode", MessageBoxButtons.OK, MessageBoxIcon.Error);
                General.Editing.CancelMode();
                return;
            }

            if (!General.Map.LumpExists("VERTEXES"))
            {
                MessageBox.Show("Unable to find the VERTEXES lump. It may be that the nodes could not be built correctly.", "Nodes Viewer mode", MessageBoxButtons.OK, MessageBoxIcon.Error);
                General.Editing.CancelMode();
                return;
            }

            General.Interface.DisplayStatus(StatusType.Busy, "Reading map nodes...");

            LoadStructures();

            // Setup presentation
            CustomPresentation presentation = new CustomPresentation();

            presentation.AddLayer(new PresentLayer(RendererLayer.Background, BlendingMode.Mask, General.Settings.BackgroundAlpha));
            presentation.AddLayer(new PresentLayer(RendererLayer.Grid, BlendingMode.Mask));
            presentation.AddLayer(new PresentLayer(RendererLayer.Overlay, BlendingMode.Alpha, 1f, true));
            presentation.AddLayer(new PresentLayer(RendererLayer.Geometry, BlendingMode.Alpha, 1f, true));
            renderer.SetPresentation(presentation);

            General.Interface.DisplayStatus(StatusType.Busy, "Building subsectors...");

            RecursiveBuildSubsectorPoly(nodes.Length - 1, new Stack <Split>(nodes.Length / 2 + 1));

            // Load and display dialog window
            form = new NodesForm(this);
            form.Show((Form)General.Interface);

            Cursor.Current = Cursors.Default;
            General.Interface.DisplayReady();
            General.Interface.RedrawDisplay();
        }