Пример #1
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            m_escape_key_pressed = false;

            // Add our escape key event handler
            RhinoApp.EscapeKeyPressed += RhinoApp_EscapeKeyPressed;

            for (var i = 0; i < 10000; i++)
            {
                // Pauses to keep Windows message pump alive
                RhinoApp.Wait();

                // Check out cancel flag
                if (m_escape_key_pressed)
                {
                    break;
                }

                RhinoApp.WriteLine(string.Format("Hello {0}", i));
            }

            // Remove it when finished
            RhinoApp.EscapeKeyPressed -= RhinoApp_EscapeKeyPressed;

            return(Result.Success);
        }
Пример #2
0
            /// <summary>
            /// Hides a form, calls a provided function, and then shows the form. This works for
            /// modal forms. Useful for selecting objects or getting points while a modal dialog
            /// is running.
            /// </summary>
            /// <param name="form">A form window.</param>
            /// <param name="pickFunction">A picking delegate.</param>
            public static void PushPickButton(System.Windows.Forms.Form form, System.EventHandler <EventArgs> pickFunction)
            {
                if (form == null || pickFunction == null)
                {
                    return;
                }

                IntPtr handle = form.Handle;

                if (IntPtr.Zero == handle)
                {
                    return;
                }
                if (form.Modal)
                {
                    IntPtr pList = UnsafeNativeMethods.RHC_PushPickButtonHide(handle);
                    if (IntPtr.Zero != pList)
                    {
                        RhinoApp.Wait();
                        RhinoApp.SetFocusToMainWindow();
                        pickFunction(form, EventArgs.Empty);
                        UnsafeNativeMethods.RHC_PushPickButtonShow(pList);
                    }
                }
                else
                {
                    form.Visible = false;
                    RhinoApp.Wait();
                    RhinoApp.SetFocusToMainWindow();
                    pickFunction(form, EventArgs.Empty);
                    form.Visible = true;
                }
            }
Пример #3
0
        private void StackButton_Click(object sender, RoutedEventArgs e)
        {
            if (previousClickedButtonIndex != -1)
            {
                (stackPanel.Children[previousClickedButtonIndex] as Button).Background = previousClickedButtonBrush;
            }

            this.previousClickedButtonIndex = stackPanel.Children.IndexOf(sender as Button);
            this.previousClickedButtonBrush = (sender as Button).Background;

            (sender as Button).Background = new SolidColorBrush(Color.FromArgb(255, 255, 204, 0));
            this.preview(tempOutput[stackPanel.Children.IndexOf(sender as Button)]);

            UpdateSummary(tempOutput[stackPanel.Children.IndexOf(sender as Button)]);

            RhinoDoc.ActiveDoc.Views.Redraw();
            RhinoApp.Wait();



            /*
             *
             * List<Brep> tempBreps = DrawBuildingOutLine.simpleBuildings(tempOutput[stackPanel.Children.IndexOf(sender as Button)]);
             *
             * building3DPreview.BrepToDisplay = tempBreps;
             * building3DPreview.Enabled = true;
             *
             * RhinoDoc.ActiveDoc.Views.Redraw();*/
        }
Пример #4
0
 //
 // Performs a single step of the active component
 // 1. Collect Data
 // 2. Recalculate Solution
 // 3. Update Boolean State
 //
 // After this function finishes, the solution must
 // be in a complete new state.
 //
 public void Step()
 {
     P.collectVolatileData_Silent();
     cStep++;
     ExpireSolution(true);
     B.collectVolatileData_Silent();
     RhinoApp.Wait();
 }
Пример #5
0
    public void Run(RhinoDoc _doc, bool refresh = true)
    {
        doc = _doc;


        //Rhino.Display.DisplayPipeline.DrawForeground +=

        // make dialog to stop iteration
        window = new Window
        {
            Title  = "stop loop",
            Width  = 100,
            Height = 50
        };

        StackPanel stack_panel = new StackPanel();

        Button stop_button = new Button();

        stop_button.Content = "stop";
        stop_button.Click  += Exit;

        stack_panel.Children.Add(stop_button);
        window.Content = stack_panel;

        new System.Windows.Interop.WindowInteropHelper(window).Owner = Rhino.RhinoApp.MainWindowHandle();
        window.Show();

        // iteration starts here
        DateTime time_start = DateTime.Now;

        Setup();

        while (is_Running)
        {
            if (refresh)
            {
                Refresh();
            }

            frame_no++;
            Draw();

            doc.Views.Redraw();
            RhinoApp.Wait();
        }

        Finish();

        TimeSpan duration = DateTime.Now - time_start;

        double frames_per_second = Math.Truncate(frame_no / duration.TotalSeconds * 100.0) / 100.0;

        RhinoApp.WriteLine("fps: " + frames_per_second);

        frame_no = 0;
    }
        public List <Point3d> GetRoadPoints()
        {
            ButtonStateCheck(ButtonState.None);
            RhinoApp.SendKeystrokes("Cancel", true);
            RhinoApp.Wait();
            bool           newPoint  = true;
            List <Point3d> newpoints = new List <Point3d>();
            List <Rhino.DocObjects.PointObject> newpointobjects = new List <Rhino.DocObjects.PointObject>();

            while (newPoint)
            {
                newPoint = RhinoApp.RunScript("Point", false);
                var guid = RhinoDoc.ActiveDoc.Objects.ElementAt(0).Id;

                Rhino.DocObjects.PointObject pointobject = RhinoDoc.ActiveDoc.Objects.Find(guid) as Rhino.DocObjects.PointObject;

                newpointobjects.Add(pointobject);

                Rhino.Geometry.Point point = pointobject.PointGeometry;
                Point3d point3d            = point.Location;
                newpoints.Add(point3d);



                if (!newPoint)
                {
                    var result = MessageBox.Show("Yes = 끝내기  No = 이전 취소  Cancle = 취소", "도로 선택 완료", MessageBoxButton.YesNoCancel);

                    if (result == MessageBoxResult.Cancel)
                    {
                        foreach (var pobj in newpointobjects)
                        {
                            Rhino.RhinoDoc.ActiveDoc.Objects.Delete(pobj, true);
                        }

                        Rhino.RhinoDoc.ActiveDoc.Views.Redraw();
                    }

                    else if (result == MessageBoxResult.No)
                    {
                        var lastguid = RhinoDoc.ActiveDoc.Objects.ElementAt(0).Id;
                        RhinoDoc.ActiveDoc.Objects.Delete(lastguid, true);

                        Rhino.RhinoDoc.ActiveDoc.Views.Redraw();

                        newPoint = true;
                    }
                }

                ////show/hide작업
            }

            return(newpoints);
        }
        private void CancelIfEscapePressed()
        {
            if (EscapeKeyCheckDelaySeconds <= EscapeKeyStopwatch.Elapsed.TotalSeconds)
            {
                EscapeKeyStopwatch.Restart();

                // We need to call Wait() in order to allow the OnEscapePressed event to fire.
                RhinoApp.Wait();
                if (bEscapedKeyPressed)
                {
                    throw new DatasmithExportCancelledException();
                }
            }
        }
Пример #8
0
 // dont wait 150 milliseonds before show progress - show it imideatelly
 public static void DisableWait150millisecondsBeforeShowAnyProgress()
 {
     if (Window == null)
     {
         log.warn(g.Temp, "ColoredProgress.ForceToShowProgress - window is not allocated");
     }
     if (Window != null)
     {
         Window.Wait150millisecondsBeforeShowAnyProgress = false;
         lock (Shared.RhinoLock)
         {
             RhinoApp.Wait(); // process mouse event. also show progress window
         }
     }
 }
Пример #9
0
        public void UpdateProgressGUIonly()
        {
            //labelTimeElapsed.Text = StartOperation.Elapsed.ToString("mm\\:ss\\.ff");
            //log.temp("progress={0}  elapsedFromLastUpdate={1}", progressCurrent, elapsedFromLastUpdate);
            labelTimeElapsed.Text = StartOperation.Elapsed.ToString("mm\\:ss");
            //Application.DoEvents();
            //this.Update();
            //this.Refresh();

            lock (Shared.RhinoLock)
            {
                //RhinoApp.SetFocusToMainWindow();
                RhinoApp.Wait(); // process mouse event. also show first time our form
                //RhinoApp.ReleaseMouseCapture();
            }
        }
Пример #10
0
        /// <summary>
        /// Deletes the currently selected layouts
        /// </summary>
        private void DoDeleteLayout()
        {
            var count = m_list.SelectedItems.Count;

            if (0 == count)
            {
                return;
            }

            var message = 1 == count
        ? "Permanently deleted the selected layout?"
        : "Permanently deleted the selected layouts?";

            var title = 1 == count
        ? "Delete Layout"
        : "Delete Layouts";

            var rc = Dialogs.ShowMessage(message, title, ShowMessageButton.YesNo, ShowMessageIcon.Warning);

            if (rc == ShowMessageResult.No)
            {
                return;
            }

            m_current_event = LayoutEvent.Delete;

            foreach (ListViewItem item in m_list.SelectedItems)
            {
                DoActiveLayout((uint)item.Tag);
                RhinoApp.Wait();
                RhinoApp.RunScript("_-CloseViewport _Yes", false);
                RhinoApp.Wait();
            }

            FillListView();

            m_current_event = LayoutEvent.None;
        }
Пример #11
0
        private void Play_Click(object sender, EventArgs e)
        {
            //Get max frames from panel label
            maxFrame = (int)MaxFrameBox.Value;
            FrameTrackBar.Maximum    = (int)MaxFrameBox.Value - 1;
            FrameProgressBar.Maximum = FrameTrackBar.Maximum;
            MaxFrameBox.Enabled      = false;
            //I focuse on pause beacuse when I run Play the button Play remain focused.
            //With this command I remove the focus on the Play button
            Pause.Focus();
            pause                 = false;
            Restart.Enabled       = pause;
            Play.Enabled          = pause;
            Pause.Enabled         = !pause;
            FrameTrackBar.Enabled = false;

            if (restarted)
            {
                //If user delete some obects, remove them from lists
                for (int i = 0; i < RigidBodyManager.World.RigidBodies.Count; i++)
                {
                    Guid        currentGuid        = RigidBodyManager.GuidList[i];
                    RhinoObject currentRhinoObject = RhinoDoc.ActiveDoc.Objects.Find(currentGuid);
                    if (currentRhinoObject == null)
                    {
                        DeleteJitterObject(i);
                        i--;
                    }
                }
            }

            if (RigidBodyManager.World.RigidBodies.Count != 0)
            {
                for (int f = FrameTrackBar.Value; f < maxFrame && !pause; f++)
                {
                    FrameTrackBar.Value = f;
                    ActualFrame.Text    = "Frame " + f;
                    // If it is the first time, it saves the frames otherwise read them
                    if (restarted)
                    {
                        //Array of rigid bodies in this single frame
                        List <RigidBody> rigidBodyFrame = new List <RigidBody>(RigidBodyManager.World.RigidBodies.Count);
                        for (int i = 0; i < RigidBodyManager.World.RigidBodies.Count; i++)//for every rigid body in the world
                        {
                            RigidBody body = RigidBodyManager.RigidBodies[i];
                            DrawGeometry(i, body);

                            //Add the rigidBody form into the array that contains every rigidBody of a frame
                            rigidBodyFrame.Add(RigidBodyManager.DuplicateRigidBody(body, body.IsStatic));
                        }
                        //you can interact with the doc during the simulation
                        RhinoApp.Wait();
                        RhinoDoc.ActiveDoc.Views.Redraw();
                        RigidBodyManager.World.Step(1.0f / 25.0f, true);

                        //Add the RigidBody array of this single frame to the list that contains all frames
                        RigidBodyManager.FramesRigidBodies.Add(rigidBodyFrame);
                    }
                    else
                    {                                                                      //Only read frames and not save them
                        for (int i = 0; i < RigidBodyManager.World.RigidBodies.Count; i++) //The number of rigid bodies in the world is equal to the lenght of the array in every frame (frames are rappresented by framesRigidBodies)
                        {
                            RigidBody bodyOfFrame = RigidBodyManager.FramesRigidBodies[f][i];
                            DrawGeometry(i, bodyOfFrame);
                        }
                        RhinoApp.Wait();
                        RhinoDoc.ActiveDoc.Views.Redraw();
                    }
                }

                if (Pause.Enabled)
                {
                    Pause_Click(null, null);
                }

                if (FrameTrackBar.Value == maxFrame - 1)
                {
                    Play.Enabled          = false;
                    restarted             = false;
                    FrameTrackBar.Enabled = true;
                }
            }
        }
Пример #12
0
        public static ForeachParallelResultEnum ExecuteParallelMethodInDialogWindow(string progressCaption, Func <ForeachParallelResultEnum> foreachFunc, bool wait150millisecondsBeforeShowAnyProgress = true)
        {
            //return foreachFunc();
            //if (Shared.FILEGROUPOPERATIONS_ENABLED)
            //{
            //    return foreachFunc();
            //}
            //log.temp("Progress: " + progressCaption);

            //
            // allocate window
            //
            AlocateOrReuseWindow();

            //
            // Add progress item
            //
            var addProgress = !String.IsNullOrEmpty(progressCaption);

            if (addProgress)
            {
                Window.AddProgress(progressCaption);
                //log.temp("added");
            }

            //
            // run foreach method
            //
            try
            {
                if (!Window.Visible) // if ColoredProgress window is not opened - open if as dialog and execute method inside dialog itself
                {
                    if (!wait150millisecondsBeforeShowAnyProgress)
                    {
                        DisableWait150millisecondsBeforeShowAnyProgress();
                    }
                    using (new WaitCursor())
                    {
                        Window.ForeachFuncSavedBeforeShowModal = foreachFunc;
                        lock (Shared.RhinoLock)
                        {
                            RhinoApp.Wait();
                        }
                        var h   = RhinoApp.MainWindow();
                        var res = Window.ShowDialog(h); // here we will execute 'ForeachFuncSavedBeforeShowModal'
                        return(res == DialogResult.OK ? ForeachParallelResultEnum.Ok : ForeachParallelResultEnum.Terminated);
                    }
                }
                else
                {
                    return(foreachFunc());
                }
            }
            finally
            {
                if (addProgress)
                {
                    Window.CurrentProgress.Status = StatusItem.CurrentStatus.Complete;
                }
            }
        }
        private void Btn_SetWidth_Click(object sender, RoutedEventArgs e)
        {
            ButtonStateCheck(ButtonState.GetWidth);
            RhinoApp.SendKeystrokes("Cancel", true);

            RhinoApp.Wait();

            UIManager.getInstance().SnapSetter(UIManager.SnapMode.OffAll);



            if (TuringAndCorbusierPlugIn.InstanceClass.plot == null)
            {
                MessageBox.Show("먼저 커브를 선택하세요");

                return;
            }

            if (TuringAndCorbusierPlugIn.InstanceClass.plot.Boundary.ClosedCurveOrientation(Plane.WorldXY) == CurveOrientation.Clockwise)
            {
                TuringAndCorbusierPlugIn.InstanceClass.plot.Boundary.Reverse();
            }

            List <Curve>       inputList       = TuringAndCorbusierPlugIn.InstanceClass.plot.Boundary.DuplicateSegments().ToList();
            List <ConduitLine> tempConduitLine = new List <ConduitLine>();

            if (inputList.Count == TuringAndCorbusierPlugIn.InstanceClass.plot.Surroundings.Length)
            {
                foreach (Curve i in inputList)
                {
                    Rhino.Geometry.Line tempLine            = new Rhino.Geometry.Line(i.PointAt(i.Domain.T0), i.PointAt(i.Domain.T1));
                    ConduitLine         tempTempConduitLine = new ConduitLine(tempLine, TuringAndCorbusierPlugIn.InstanceClass.plot.Surroundings[inputList.IndexOf(i)]);

                    tempConduitLine.Add(tempTempConduitLine);
                }
            }
            else
            {
                TuringAndCorbusierPlugIn.InstanceClass.plot.Surroundings = new int[inputList.Count];

                foreach (Curve i in inputList)
                {
                    Rhino.Geometry.Line tempLine            = new Rhino.Geometry.Line(i.PointAt(i.Domain.T0), i.PointAt(i.Domain.T1));
                    ConduitLine         tempTempConduitLine = new ConduitLine(tempLine);
                    TuringAndCorbusierPlugIn.InstanceClass.plot.Surroundings[inputList.IndexOf(i)] = 4;

                    tempConduitLine.Add(tempTempConduitLine);
                }
            }

            Corbusier.conduitLines.Clear();
            Corbusier.conduitLines = tempConduitLine;

            Corbusier.conduitLineDisplay         = new LinesConduit(Corbusier.conduitLines);
            Corbusier.conduitLineDisplay.Enabled = true;
            RhinoDoc.ActiveDoc.Views.Redraw();

            var gcl = new GetConduitLine(Corbusier.conduitLines);

            RhinoApp.WriteLine("늘리거나 줄일 도로 선택 ( 클릭 = 늘리기 , Ctrl + 클릭 = 줄이기 , Shift + 클릭 = 전체 늘리기 , Shift + Ctrl + 클릭 = 전체 줄이기 , ESC = 마침");

            while (!endWhileLoop)
            {
                gcl.AcceptNothing(true);
                gcl.Get(true);
                RhinoDoc.ActiveDoc.Views.Redraw();

                if (gcl.CommandResult() != Rhino.Commands.Result.Success)
                {
                    break;
                }
            }


            if (TuringAndCorbusierPlugIn.InstanceClass.kdgInfoSet.boundary.ClosedCurveOrientation(Plane.WorldXY) == CurveOrientation.CounterClockwise)
            {
                TuringAndCorbusierPlugIn.InstanceClass.kdgInfoSet.boundary.Reverse();
            }



            Curve[] boundarysegs = TuringAndCorbusierPlugIn.InstanceClass.kdgInfoSet.boundary.DuplicateSegments();


            /////대지경계선후퇴적용
            //for (int i = 0; i < Corbusier.RoadWidth.Count; i++)
            //{

            //    if (Corbusier.RoadWidth[i] < 4 && Corbusier.RoadWidth[i] >= 0)
            //    {

            //        Vector3d curvev = boundarysegs[i].PointAtEnd - boundarysegs[i].PointAtStart;
            //        curvev.Rotate(RhinoMath.ToRadians(-90), Vector3d.ZAxis);
            //        curvev.Unitize();

            //        boundarysegs[i].Translate(curvev * ((Corbusier.RoadWidth[i] - 4) * 500));
            //        boundarysegs[i].Extend(CurveEnd.Both, 1000, CurveExtensionStyle.Line);

            //        LoadManager.getInstance().DrawObjectWithSpecificLayer(boundarysegs[i], LoadManager.NamedLayer.Guide);


            //    }
            //}

            //for (int i = 0; i < boundarysegs.Length; i++)
            //{
            //    int i2 = (i + 1) % boundarysegs.Length;
            //    var intersection = Rhino.Geometry.Intersect.Intersection.CurveCurve(boundarysegs[i], boundarysegs[i2], 0, 0);
            //    foreach (var x in intersection)
            //    {
            //        if (x.ParameterA != 1)
            //            boundarysegs[i] = boundarysegs[i].Split(x.ParameterA)[0];

            //        if (x.ParameterB != 1)
            //            boundarysegs[i2] = boundarysegs[i2].Split(x.ParameterB)[1];
            //    }

            //}


            //List<Curve> tojoin = new List<Curve>();

            //for (int i = 0; i < boundarysegs.Length; i++)
            //{


            //}

            //Curve[] joined = Curve.JoinCurves(boundarysegs);



            //TuringAndCorbusierPlugIn.InstanceClass.kdgInfoSet.setbackBoundary = joined[0];
            //대지경계선후퇴 끝
            //kdginfoset 의 setbackBoundary에 저장.

            //LoadManager.getInstance().DrawObjectWithSpecificLayer(TuringAndCorbusierPlugIn.InstanceClass.kdgInfoSet.setbackBoundary, LoadManager.NamedLayer.Model);

            Corbusier.conduitLineDisplay.Enabled = false;
            TuringAndCorbusierPlugIn.InstanceClass.plot.Surroundings = Corbusier.conduitLines.Select(n => n.RoadWidth * 1000).ToArray();      //    .RoadWidth.Select(n=>n*1000).ToArray();
            TuringAndCorbusierPlugIn.InstanceClass.plot.UpdateSimplifiedSurroundings();
            //TuringAndCorbusierPlugIn.InstanceClass.plot.Adjust();
            UIManager.getInstance().SnapSetter(UIManager.SnapMode.Current);
            ButtonStateCheck(ButtonState.None);
            RhinoDoc.ActiveDoc.Views.Redraw();
        }
Пример #14
0
        private void Btn_Calculate_Click(object sender, RoutedEventArgs e)
        {
            currentProgressFactor = 0;

            //building3DPreview.BrepToDisplay = new List<Brep>();
            Rhino.RhinoDoc.ActiveDoc.Views.Redraw();
            RhinoApp.Wait();

            GC.Collect();

            List <ApartmentGeneratorBase> agSet = new List <ApartmentGeneratorBase>();

            agSet.Add(new AG1());
            agSet.Add(new AG3());
            agSet.Add(new AG4());

            if (TuringAndCorbusierPlugIn.InstanceClass.plot == null)
            {
                return;
            }

            Plot   tempPlot   = TuringAndCorbusierPlugIn.InstanceClass.plot;
            Target tempTarget = TuringAndCorbusierPlugIn.InstanceClass.page2Settings.Target;

            List <ApartmentGeneratorBase> usingAGSet = new List <ApartmentGeneratorBase>();

            for (int i = 0; i < agSet.Count(); i++)
            {
                if (TuringAndCorbusierPlugIn.InstanceClass.page2Settings.WhichAGToUse[i])
                {
                    if (i > 0 && !TuringAndCorbusierPlugIn.InstanceClass.page2.isAG34Valid)
                    {
                        return;
                    }
                    usingAGSet.Add(agSet[i]);
                }
            }

            if (usingAGSet.Count() == 0)
            {
                usingAGSet.Add(new AG1());
            }

            this.calcWorkQuantity(usingAGSet);


            if (TuringAndCorbusierPlugIn.InstanceClass.page2Settings.WhichAGToUse.IndexOf(true) == -1)
            {
                try
                {
                    AG1 tempAG = new AG1();

                    List <Apartment> tempTempOutputs = GiantAnteater.giantAnteater(tempPlot, tempAG, tempTarget, !this.Preview_Toggle.IsChecked.Value);

                    string tempAGname = GetConvertedAGName(tempAG);

                    for (int i = 0; i < tempTempOutputs.Count; i++)
                    {
                        bool addResult = this.AddButtonToStackPanel(tempTempOutputs[i]);
                        if (addResult)
                        {
                            this.tempOutput.Add(tempTempOutputs[i]);
                            this.tempAGName.Add(tempAGname);
                        }
                    }
                }
                catch (Exception ex)
                {
                    RhinoApp.WriteLine(ex.Message);
                }
            }


            for (int i = 0; i < agSet.Count(); i++)
            {
                if (TuringAndCorbusierPlugIn.InstanceClass.page2Settings.WhichAGToUse[i])
                {
                    //try
                    //{
                    List <Apartment> tempTempOutputs = GiantAnteater.giantAnteater(tempPlot, agSet[i], tempTarget, !this.Preview_Toggle.IsChecked.Value);



                    string tempAGname = GetConvertedAGName(agSet[i]);

                    if (tempTempOutputs == null)
                    {
                        continue;
                    }

                    for (int k = 0; k < tempTempOutputs.Count; k++)
                    {
                        bool addResult = this.AddButtonToStackPanel(tempTempOutputs[k]);
                        if (addResult)
                        {
                            this.tempOutput.Add(tempTempOutputs[k]);
                            this.tempAGName.Add(tempAGname);
                        }
                    }


                    Rhino.RhinoApp.Wait();
                    GC.Collect();
                    //}
                    //catch (Exception ex)
                    //{
                    //    RhinoApp.WriteLine(ex.Message);
                    //}
                }
            }
        }
Пример #15
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            var     pack_algorithm    = PackingAlgorithm.Fast;
            Point3d base_point        = new Point3d();
            var     option_count      = new OptionInteger(100, true, 2);
            var     option_min_radius = new OptionDouble(0.1, true, 0.001);
            var     option_max_radius = new OptionDouble(1.0, true, 0.001);
            var     option_iterations = new OptionInteger(10000, false, 100);

            bool done_looping = false;

            while (!done_looping)
            {
                var gp = new GetPoint();
                gp.SetCommandPrompt("Center of fitting solution");
                gp.AddOptionInteger("Count", ref option_count);
                gp.AddOptionDouble("MinRadius", ref option_min_radius);
                gp.AddOptionDouble("MaxRadius", ref option_max_radius);
                gp.AddOptionInteger("IterationLimit", ref option_iterations);
                int index_option_packing = gp.AddOption("Packing", pack_algorithm.ToString());
                gp.AcceptNumber(true, true);

                switch (gp.Get())
                {
                case GetResult.Point:
                    base_point   = gp.Point();
                    done_looping = true;
                    break;

                case GetResult.Option:
                    if (index_option_packing == gp.OptionIndex())
                    {
                        var get_algorithm = new GetOption();
                        get_algorithm.SetCommandPrompt("Packing");
                        get_algorithm.SetDefaultString(pack_algorithm.ToString());
                        var opts          = new string[] { "Fast", "Double", "Random", "Simple" };
                        int current_index = 0;
                        switch (pack_algorithm)
                        {
                        case PackingAlgorithm.Fast:
                            current_index = 0;
                            break;

                        case PackingAlgorithm.Double:
                            current_index = 1;
                            break;

                        case PackingAlgorithm.Random:
                            current_index = 2;
                            break;

                        case PackingAlgorithm.Simple:
                            current_index = 3;
                            break;
                        }
                        int index_list = get_algorithm.AddOptionList("algorithm", opts, current_index);
                        get_algorithm.AddOption("Help");
                        while (get_algorithm.Get() == GetResult.Option)
                        {
                            if (index_list == get_algorithm.OptionIndex())
                            {
                                int index = get_algorithm.Option().CurrentListOptionIndex;
                                if (0 == index)
                                {
                                    pack_algorithm = PackingAlgorithm.Fast;
                                }
                                if (1 == index)
                                {
                                    pack_algorithm = PackingAlgorithm.Double;
                                }
                                if (2 == index)
                                {
                                    pack_algorithm = PackingAlgorithm.Simple;
                                }
                                if (3 == index)
                                {
                                    pack_algorithm = PackingAlgorithm.Random;
                                }
                                break;
                            }
                            // if we get here, the user selected help
                            const string help =
                                @"Fast: fast packing prevents collisions by moving one
circle away from all its intersectors. After every collision
iteration, all circles are moved towards the centre of the
packing to reduce the amount of wasted space. Collision
detection proceeds from the center outwards.

Double: similar to Fast, except that both circles are moved
in case of a collision.

Random: similar to Fast, except that collision detection is
randomized rather than sorted.

Simple: similar to Fast, but without a contraction pass
after every collision iteration.";
                            Rhino.UI.Dialogs.ShowMessageBox(help, "Packing algorithm description", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information);
                        }
                    }
                    break;

                default:
                    return(Result.Cancel);
                }
            }
            int    count      = option_count.CurrentValue;
            double min_radius = option_min_radius.CurrentValue;
            double max_radius = option_max_radius.CurrentValue;
            int    iterations = option_iterations.CurrentValue;

            // TODO: try setting up a background worker thread and
            // communicate with the GetString through messages
            //GetString gs = new GetString();
            //gs.SetCommandPrompt("Press escape to cancel");

            using (var all_circles = new PackCircles(base_point, count, min_radius, max_radius))
            {
                double damping = 0.1;
                for (int i = 1; i <= iterations; i++)
                {
                    RhinoApp.SetCommandPrompt(string.Format("Performing circle packing iteration {0}...  (Press Shift+Ctrl to abort)", i));

                    if (System.Windows.Forms.Control.ModifierKeys == (System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift))
                    {
                        RhinoApp.WriteLine("Circle fitting process aborted at iteration {0}...", i);
                        break;
                    }

                    if (!all_circles.Pack(pack_algorithm, damping, doc.ModelAbsoluteTolerance))
                    {
                        RhinoApp.WriteLine("Circle fitting process completed at iteration {0}...", i);
                        break;
                    }

                    damping *= 0.98;
                    doc.Views.Redraw();
                    RhinoApp.Wait();
                }
                all_circles.Add(doc);
            }
            doc.Views.Redraw();
            return(Result.Success);
        }