예제 #1
0
        private void RestoreOptions(ref GetOption go, int ResolutionIndex)
        {
            Size size = RhinoHelpers.CalculateSize(
                ResolutionIndex,
                widthOpt.CurrentValue,
                heightOpt.CurrentValue,
                dpiOpt.CurrentValue,
                portraitToggle.CurrentValue
                );

            if (size.IsEmpty)
            {
                size = RhinoDoc.ActiveDoc.Views.ActiveView.ActiveViewport.Bounds.Size;
            }

            go.SetCommandPrompt("Screenshot (" + size.Width + "x" + size.Height + ")");
            go.ClearCommandOptions();
            go.AddOptionList("Resolution", new string[] { "FullHD", "4K", "A4", "A3", "View", "Custom" }, ResolutionIndex);

            // Show option width and height only if "Custom" is selected.
            if (ResolutionIndex == 5)
            {
                go.AddOptionInteger("Width", ref this.widthOpt);
                go.AddOptionInteger("Height", ref this.heightOpt);

                go.AddOptionToggle("KeepRatio", ref this.ratioToggle);
            }
            else if (ResolutionIndex >= 2 && ResolutionIndex <= 3)
            {
                go.AddOptionToggle("Orientation", ref this.portraitToggle);
                go.AddOptionInteger("DPI", ref this.dpiOpt);
            }

            // Show option Grid And Axes
            go.AddOptionToggle("GridAndAxes", ref this.gridAxesToggle);
        }
예제 #2
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            Rhino.Input.Custom.GetOption go = new GetOption();
            go.SetCommandPrompt("Set Faro scan settings");

            Rhino.Input.Custom.GetString gs = new GetString();
            gs.SetCommandPrompt("Set Faro IP address.");
            gs.SetDefaultString("127.0.0.1");

            gs.AddOption("Scanner IP");

            gs.Get();

            string val = gs.StringResult();

            Rhino.RhinoApp.WriteLine("IP: " + val);

            // set up the options
            Rhino.Input.Custom.OptionInteger intOption  = new Rhino.Input.Custom.OptionInteger(1, 1, 99);
            Rhino.Input.Custom.OptionDouble  dblOption  = new Rhino.Input.Custom.OptionDouble(2.2, 0, 99.9);
            Rhino.Input.Custom.OptionToggle  boolOption = new Rhino.Input.Custom.OptionToggle(true, "Off", "On");
            string[] resolutionValues  = new string[] { "Full", "Half", "Quarter", "Eighth", "Sixsteenth" };
            string[] measurementValues = new string[] { "Low", "Medium", "High" };
            string[] noiseValues       = new string[] { "Low", "Medium", "High" };


            go.AddOptionInteger("Integer", ref intOption);
            go.AddOptionDouble("Double", ref dblOption);
            go.AddOptionToggle("Boolean", ref boolOption);

            int resolutionIndex  = 2;
            int measurementIndex = 1;
            int noiseIndex       = 1;

            int resolutionList  = go.AddOptionList("Resolution", resolutionValues, resolutionIndex);
            int measurementList = go.AddOptionList("MeasurementRate", measurementValues, measurementIndex);
            int noiseList       = go.AddOptionList("NoiseCompression", noiseValues, noiseIndex);

            while (true)
            {
                // perform the get operation. This will prompt the user to input a point, but also
                // allow for command line options defined above
                Rhino.Input.GetResult get_rc = go.Get();
                Rhino.RhinoApp.WriteLine(get_rc.ToString());

                if (go.CommandResult() != Rhino.Commands.Result.Success)
                {
                    return(go.CommandResult());
                }

                if (get_rc == Rhino.Input.GetResult.Nothing)
                {
                    //doc.Objects.AddPoint(go.Point());
                    doc.Views.Redraw();
                    Rhino.RhinoApp.WriteLine("Command line option values are");
                    Rhino.RhinoApp.WriteLine(" Integer = {0}", intOption.CurrentValue);
                    Rhino.RhinoApp.WriteLine(" Double = {0}", dblOption.CurrentValue);
                    Rhino.RhinoApp.WriteLine(" Boolean = {0}", boolOption.CurrentValue);
                    Rhino.RhinoApp.WriteLine(" Measurement rate = {0}", measurementValues[measurementIndex]);
                    Rhino.RhinoApp.WriteLine(" Resolution = {0}", resolutionValues[resolutionIndex]);
                }
                else if (get_rc == Rhino.Input.GetResult.Option)
                {
                    if (go.OptionIndex() == resolutionList)
                    {
                        resolutionIndex = go.Option().CurrentListOptionIndex;
                    }
                    else if (go.OptionIndex() == measurementList)
                    {
                        measurementIndex = go.Option().CurrentListOptionIndex;
                    }

                    continue;
                }
                break;
            }

            return(Rhino.Commands.Result.Success);
        }
예제 #3
0
        /// <summary>
        /// Command.RunCommand override
        /// </summary>
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            Potrace.Clear();

            // Prompt the user for the name of the image file to vectorize.
            string path = GetImageFileName(mode);

            if (string.IsNullOrEmpty(path))
            {
                return(Result.Cancel);
            }

            // Creates a bitmap from the specified file.
            var bitmap = Image.FromFile(path) as Bitmap;

            if (null == bitmap)
            {
                RhinoApp.WriteLine("The specified file cannot be identifed as a supported type.");
                return(Result.Failure);
            }

            // Verify bitmap size
            if (0 == bitmap.Width || 0 == bitmap.Height)
            {
                RhinoApp.WriteLine("Error reading the specified file.");
                return(Result.Failure);
            }

            // Calculate scale factor so curves of a reasonable size are added to Rhino
            var unit_scale = (doc.ModelUnitSystem != UnitSystem.Inches)
        ? RhinoMath.UnitScale(UnitSystem.Inches, doc.ModelUnitSystem)
        : 1.0;
            var scale = (double)(1.0 / bitmap.HorizontalResolution * unit_scale);

            // I'm not convinced this is useful...
            if (true)
            {
                var format = $"F{doc.DistanceDisplayPrecision}";

                // Print image size in pixels
                RhinoApp.WriteLine("Image size in pixels: {0} x {1}",
                                   bitmap.Width,
                                   bitmap.Height
                                   );

                // Print image size in inches
                var width  = (double)(bitmap.Width / bitmap.HorizontalResolution);
                var height = (double)(bitmap.Height / bitmap.VerticalResolution);
                RhinoApp.WriteLine("Image size in inches: {0} x {1}",
                                   width.ToString(format, CultureInfo.InvariantCulture),
                                   height.ToString(format, CultureInfo.InvariantCulture)
                                   );

                // Image size in in model units, if needed
                if (doc.ModelUnitSystem != UnitSystem.Inches)
                {
                    width  = (double)(bitmap.Width / bitmap.HorizontalResolution * unit_scale);
                    height = (double)(bitmap.Height / bitmap.VerticalResolution * unit_scale);
                    RhinoApp.WriteLine("Image size in {0}: {1} x {2}",
                                       doc.ModelUnitSystem.ToString().ToLower(),
                                       width.ToString(format, CultureInfo.InvariantCulture),
                                       height.ToString(format, CultureInfo.InvariantCulture)
                                       );
                }
            }

            // Convert the bitmap to an Eto bitmap
            var eto_bitmap = ConvertBitmapToEto(bitmap);

            if (null == eto_bitmap)
            {
                RhinoApp.WriteLine("Unable to convert image to Eto bitmap.");
                return(Result.Failure);
            }

            // 12-Jan-2021 Dale Fugier
            // This should prevent Eto.Drawing.BitmapData.GetPixels() from throwing an exception
            if (!IsCompatibleBitmap(eto_bitmap))
            {
                RhinoApp.WriteLine("The image has an incompatible pixel format. Please select an image with 24 or 32 bits per pixel, or 8 bit indexed.");
                return(Result.Failure);
            }

            // This bitmap is not needed anymore, so dispose of it
            bitmap.Dispose();

            // Gets the Potrace settings from the plug-in settings file
            GetPotraceSettings();

            // Create the conduit, which does most of the work
            var conduit = new VectorizeConduit(
                eto_bitmap,
                scale,
                doc.ModelAbsoluteTolerance,
                m_select_output
          ? Rhino.ApplicationSettings.AppearanceSettings.SelectedObjectColor
          : doc.Layers.CurrentLayer.Color
                )
            {
                Enabled = true
            };

            if (mode == RunMode.Interactive)
            {
                // Show the interactive dialog box
                var dialog = new VectorizeDialog(doc, conduit);
                dialog.RestorePosition();
                var result = dialog.ShowSemiModal(doc, RhinoEtoApp.MainWindow);
                dialog.SavePosition();
                if (result != Result.Success)
                {
                    conduit.Enabled = false;
                    Potrace.Clear();
                    doc.Views.Redraw();
                    return(Result.Cancel);
                }
            }
            else
            {
                // Show the command line options
                var go = new GetOption();
                go.SetCommandPrompt("Vectorization options. Press Enter when done");
                go.AcceptNothing(true);
                while (true)
                {
                    conduit.TraceBitmap();
                    doc.Views.Redraw();

                    go.ClearCommandOptions();

                    // IgnoreArea
                    var turdsize_opt = new OptionInteger(Potrace.turdsize, 2, 100);
                    var turdsize_idx = go.AddOptionInteger("FilterSize", ref turdsize_opt, "Filter speckles of up to this size in pixels");

                    // TurnPolicy
                    var turnpolicy_idx = go.AddOptionEnumList("TurnPolicy", Potrace.turnpolicy);

                    // Optimizing
                    var curveoptimizing_opt = new OptionToggle(Potrace.curveoptimizing, "No", "Yes");
                    var curveoptimizing_idx = go.AddOptionToggle("Optimizing", ref curveoptimizing_opt);

                    // Tolerance
                    var opttolerance_opt = new OptionDouble(Potrace.opttolerance, 0.0, 1.0);
                    var opttolerance_idx = go.AddOptionDouble("Tolerance", ref opttolerance_opt, "Optimizing tolerance");

                    // CornerThreshold
                    var alphamax_opt = new OptionDouble(Potrace.alphamax, 0.0, 100.0);
                    var alphamax_idx = go.AddOptionDouble("CornerRounding", ref alphamax_opt, "Corner rounding threshold");

                    // Threshold
                    var threshold_opt = new OptionDouble(Potrace.Treshold, 0.0, 100.0);
                    var threshold_idx = go.AddOptionDouble("Threshold", ref threshold_opt, "Threshold");

                    // RestoreDefaults
                    var defaults_idx = go.AddOption("RestoreDefaults");

                    var res = go.Get();

                    if (res == GetResult.Option)
                    {
                        var option = go.Option();
                        if (null != option)
                        {
                            if (turdsize_idx == option.Index)
                            {
                                Potrace.turdsize = turdsize_opt.CurrentValue;
                            }

                            if (turnpolicy_idx == option.Index)
                            {
                                var list = Enum.GetValues(typeof(TurnPolicy)).Cast <TurnPolicy>().ToList();
                                Potrace.turnpolicy = list[option.CurrentListOptionIndex];
                            }

                            if (curveoptimizing_idx == option.Index)
                            {
                                Potrace.curveoptimizing = curveoptimizing_opt.CurrentValue;
                            }

                            if (opttolerance_idx == option.Index)
                            {
                                Potrace.opttolerance = opttolerance_opt.CurrentValue;
                            }

                            if (alphamax_idx == option.Index)
                            {
                                Potrace.alphamax = alphamax_opt.CurrentValue;
                            }

                            if (threshold_idx == option.Index)
                            {
                                Potrace.Treshold = threshold_opt.CurrentValue;
                            }

                            if (defaults_idx == option.Index)
                            {
                                Potrace.RestoreDefaults();
                            }
                        }
                        continue;
                    }

                    if (res != GetResult.Nothing)
                    {
                        conduit.Enabled = false;
                        doc.Views.Redraw();
                        Potrace.Clear();
                        return(Result.Cancel);
                    }

                    break;
                }
            }

            // Group curves
            var attributes = doc.CreateDefaultAttributes();

            attributes.AddToGroup(doc.Groups.Add());
            for (var i = 0; i < conduit.OutlineCurves.Count; i++)
            {
                var rhobj_id = doc.Objects.AddCurve(conduit.OutlineCurves[i], attributes);
                if (m_select_output)
                {
                    var rhobj = doc.Objects.Find(rhobj_id);
                    if (null != rhobj)
                    {
                        rhobj.Select(true);
                    }
                }
            }

            conduit.Enabled = false;
            Potrace.Clear();
            doc.Views.Redraw();

            // Set the Potrace settings to the plug -in settings file.
            SetPotraceSettings();

            return(Result.Success);
        }
예제 #4
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            var cities         = new OptionInteger(50, 3, 1000);
            var time           = new OptionInteger(10, 5, 120);
            var algorithmIndex = 0;

            var get = new GetOption();

            get.SetCommandPrompt("Optimize TSP");
            get.AddOptionInteger("Cities", ref cities);
            get.AddOptionInteger("Time", ref time);
            get.AddOptionList("Algorithm", new[] { "RandomSearch", "HillClimbing", "SimulatedAnnealing" }, 0);
            get.AddOption("Run");

            while (true)
            {
                get.Get();

                if (get.CommandResult() != Result.Success)
                {
                    return(get.CommandResult());
                }

                if (get.Option().EnglishName == "Algorithm")
                {
                    algorithmIndex = get.Option().CurrentListOptionIndex;
                }

                if (get.Option().EnglishName == "Run")
                {
                    RhinoApp.WriteLine("Optimization started...");
                    break;
                }
            }

            var optimizer = new Optimizer(cities.CurrentValue, time.CurrentValue);
            var conduit   = new OptimizeConduit(optimizer.Path)
            {
                Enabled = true
            };

            Task updateTask = null;

            optimizer.UpdatedCandidate += (o, e) =>
            {
                conduit.Path = optimizer.Path;
                conduit.Info = optimizer.Info;

                //doc.Views.Redraw();

                if (updateTask?.IsCompleted != false)
                {
                    updateTask = Task.Run(() => doc.Views.Redraw());
                }
            };

            optimizer.Finished += (o, e) =>
            {
                conduit.Enabled = false;
                doc.Objects.AddPolyline(optimizer.Path);
                doc.Views.Redraw();
                RhinoApp.WriteLine($"Optimization finished ({optimizer.Info}).");
            };

            var algorithms = new Action[]
            {
                optimizer.RandomSearch,
                optimizer.HillClimbing,
                optimizer.SimulatedAnnealing
            };

            Task.Run(algorithms[algorithmIndex]);

            return(Result.Success);
        }
예제 #5
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            if (!(RhinoApp.GetPlugInObject("Grasshopper") is GH_RhinoScriptInterface Grasshopper))
            {
                return(Result.Cancel);
            }

            GetOption go = null;

            while (true)
            {
                var port     = new OptionInteger(Port, 1024, 65535);
                var toggle   = new OptionToggle(ShowEditor, "Hide", "Show");
                var debugger = new OptionToggle(Debug, "Off", "On");

                go = new GetOption();

                go.SetCommandPrompt("Noah Server");
                go.AddOption("Connect");
                go.AddOption("Stop");
                go.AddOption("Observer");
                go.AddOptionInteger("Port", ref port);
                go.AddOptionToggle("Editor", ref toggle);
                go.AddOptionToggle("Debug", ref debugger);
                go.AddOption("Workspace");

                GetResult result = go.Get();
                if (result != GetResult.Option)
                {
                    break;
                }

                ShowEditor = toggle.CurrentValue;
                Debug      = debugger.CurrentValue;

                string whereToGo = go.Option().EnglishName;

                if (whereToGo == "Connect")
                {
                    if (Port == 0)
                    {
                        RhinoApp.WriteLine("Please set Port you want to connect!");
                        continue;
                    }

                    if (WorkDir == null)
                    {
                        RhinoApp.WriteLine("Noah can not work without workspace!");
                        continue;
                    }

                    if (Client == null)
                    {
                        try
                        {
                            Grasshopper.DisableBanner();

                            if (!Grasshopper.IsEditorLoaded())
                            {
                                Grasshopper.LoadEditor();
                            }

                            Client               = new NoahClient(Port, WorkDir);
                            Client.InfoEvent    += Client_MessageEvent;
                            Client.ErrorEvent   += Client_ErrorEvent;
                            Client.WarningEvent += Client_WarningEvent;
                            Client.DebugEvent   += Client_DebugEvent;
                        }
                        catch (Exception ex)
                        {
                            RhinoApp.WriteLine("Error: " + ex.Message);
                        }

                        Client.Connect();
                    }
                    else
                    {
                        Client.Reconnect();
                    }

                    if (Debug)
                    {
                        try
                        {
                            if (Logger == null)
                            {
                                Panels.OpenPanel(LoggerPanel.PanelId);
                            }
                            Logger = Panels.GetPanel <LoggerPanel>(doc);
                        }
                        catch (Exception ex)
                        {
                            RhinoApp.WriteLine("Error: " + ex.Message);
                        }
                    }

                    if (ShowEditor)
                    {
                        Grasshopper.ShowEditor();
                    }

                    break;
                }

                if (whereToGo == "Stop")
                {
                    if (Port == 0)
                    {
                        continue;
                    }

                    if (Client != null)
                    {
                        Client.Close();
                    }
                    break;
                }

                if (whereToGo == "Workspace")
                {
                    RhinoGet.GetString("Noah Workspace", false, ref WorkDir);
                }

                if (whereToGo == "Observer")
                {
                    if (Port == 0)
                    {
                        RhinoApp.WriteLine("Server connecting need a port!");
                        continue;
                    }

                    Process.Start("http://localhost:" + Port + "/data/center");
                    break;
                }

                if (whereToGo == "Port")
                {
                    Port = port.CurrentValue;
                    RhinoApp.WriteLine("Port is set to " + Port.ToString());
                    continue;
                }
            }

            return(Result.Nothing);
        }
예제 #6
0
파일: PFPerp.cs 프로젝트: worbit/PolyFrame
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            var           primal = new PFoam();
            var           dual   = new PFoam();
            ContainerType container;

            try
            {
                var guids = LoadData.LoadPrimalDual(out primal, out dual, out container);

                if (dual.Cells.Count < 1)
                {
                    RhinoApp.WriteLine("No dual data retrieved from the container!");
                    return(Result.Failure);
                }

                // Primal ( the perping geometry )
                // load the foam from the geometry option to update from the geometry if any changes occured
                // select the structure to be perped - if dual not present raise error

                // show a set of options
                // Max steps 10 000
                // maximum deviation in degrees from dual direction
                // Update dual data from geometry
                // set edge legth constraint
                // set point position constraint

                var averageLen = primal.Edges.Select(x => x.GetLength()).Average();

                var getOptions = new GetOption();
                getOptions.SetDefaultString("enter");

                getOptions.SetCommandPrompt("Set max number of steps and perping options");

                var  optionSteps      = new OptionInteger(1000, true, 0);
                var  optionMaxDev     = new OptionDouble(0.1, 0.0, 10.0);
                var  optionMinLen     = new OptionDouble(averageLen / 4, true, averageLen / 100);
                var  optionSetEdge    = new OptionToggle(false, "setE", "E_set");
                var  optionSetVert    = new OptionToggle(false, "setV", "V_set");
                var  optionSetDualGeo = new OptionToggle(false, "setG", "G_set");
                var  storedSteps      = 1000.0;
                var  storedMaxDev     = 0.1;
                var  storedMinLen     = averageLen / 4;
                bool storedEdgeSet    = false;
                bool storedVertSet    = false;
                bool storedDualGeoSet = false;

                getOptions.AddOptionInteger("MaxIterations", ref optionSteps);
                getOptions.AddOptionDouble("MaxDeviation", ref optionMaxDev);
                getOptions.AddOptionDouble("MinEdgeLenght", ref optionMinLen);
                getOptions.AddOptionToggle("SetEdgeLen", ref optionSetEdge);
                getOptions.AddOptionToggle("SetVertPos", ref optionSetVert);
                getOptions.AddOptionToggle("UpdatePrimalGeo", ref optionSetDualGeo);

                while (true)
                {
                    var preres = getOptions.Get();
                    var res    = getOptions.CommandResult();
                    //var numres = getOptions.

                    if (res == Result.Success)
                    {
                        if (optionSetEdge.CurrentValue != storedEdgeSet)
                        {
                            primal.PickEdges();
                        }
                        if (optionSetVert.CurrentValue != storedVertSet)
                        {
                            primal.PickVertex();
                        }
                        if (optionSetDualGeo.CurrentValue != storedDualGeoSet)
                        {
                            var updatedDual = new PFoam();



                            LoadData.LoadPrimalDual(out updatedDual, out PFoam notUsedPrimal, out ContainerType dummyContainer, false);
                            // get the container geometry from a dual from the document
                            // check to see if the id matches
                            // load the point geometry, centroids, meshes and update data in the dual

                            // transform the primal/dual getter into a method to reuse it more easily

                            if (updatedDual.Dual.Id == primal.Id)
                            {
                                dual = updatedDual;
                                Util.ConnectDuals(ref primal, ref updatedDual);
                            }
                        }



                        if (optionSetEdge.CurrentValue == storedEdgeSet &&
                            optionSetVert.CurrentValue == storedVertSet &&
                            optionSetDualGeo.CurrentValue == storedDualGeoSet &&
                            optionSteps.CurrentValue == storedSteps &&
                            optionMaxDev.CurrentValue == storedMaxDev &&
                            optionMinLen.CurrentValue == storedMinLen
                            )
                        {
                            break;
                        }


                        storedEdgeSet    = optionSetEdge.CurrentValue;
                        storedVertSet    = optionSetVert.CurrentValue;
                        storedDualGeoSet = optionSetDualGeo.CurrentValue;
                        storedSteps      = optionSteps.CurrentValue;
                        storedMaxDev     = optionMaxDev.CurrentValue;
                        storedMinLen     = optionMinLen.CurrentValue;
                    }
                    else
                    {
                        return(Result.Cancel);
                    }
                }
                //Util.ConnectDuals(ref primal, ref dual);
                foreach (var edge in primal.Edges)
                {
                    edge.MinLength = optionMinLen.CurrentValue;
                }

                // delete the input objects
                doc.Objects.Delete(guids, true);

                primal.PerpSoft(optionSteps.CurrentValue, optionMaxDev.CurrentValue / 180 * Math.PI);

                //primal.ParaPerp(optionSteps.CurrentValue, 0, optionMaxDev.CurrentValue / 180 * Math.PI, null, 1);


                primal.Show(true, true, false);



                var pepedPrimalJsonString = primal.SerializeJson();

                if (!primal.SaveToDocument(container))
                {
                    primal.Hide();
                    return(Result.Cancel);
                }
                primal.Hide();

                return(Result.Success);
            }
            catch (PolyFrameworkException pfE)
            {
                RhinoApp.WriteLine(pfE.Message);
                primal.Hide();
                dual.Hide();
                return(Result.Failure);
            }
            // TODO: complete command.
        }
예제 #7
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            //Pick curve for chain
            GetObject getCurve = new GetObject();

            getCurve.GeometryFilter = Rhino.DocObjects.ObjectType.Curve;
            getCurve.SetCommandPrompt("Select curve for chain");
            var res = getCurve.Get();

            Rhino.DocObjects.ObjRef      objref = getCurve.Object(0);
            Rhino.DocObjects.RhinoObject obj    = objref.Object();
            if (obj == null)
            {
                return(Result.Failure);
            }
            curve = objref.Curve();
            if (curve == null)
            {
                return(Result.Failure);
            }
            obj.Select(false);

            //Pick object for chain (instance)
            //pick objekt to orient
            GetObject go = new GetObject();

            go.SetCommandPrompt("Select chain element.");
            go.SubObjectSelect             = true;
            go.DeselectAllBeforePostSelect = false;
            //go.GroupSelect = true;
            //go.GetMultiple(1, -1);
            go.Get();
            if (go.CommandResult() != Result.Success)
            {
                return(go.CommandResult());
            }
            Rhino.DocObjects.ObjRef      objref1 = go.Object(0);
            Rhino.DocObjects.RhinoObject obj1    = objref1.Object();
            GeometryBase obj1Base = obj1.Geometry;


            int    obCount      = go.ObjectCount;
            string instDefCount = DateTime.Now.ToString("ddMMyyyyHHmmss");

            //create block instance and plane for instance
            Rhino.Input.Custom.GetPoint gp1 = new Rhino.Input.Custom.GetPoint();
            gp1.SetCommandPrompt("Center point to orient from");
            gp1.Get();
            if (gp1.CommandResult() != Rhino.Commands.Result.Success)
            {
                return(gp1.CommandResult());
            }
            Point3d pt1 = gp1.Point();

            Rhino.Input.Custom.GetPoint gp2 = new Rhino.Input.Custom.GetPoint();
            gp2.SetCommandPrompt("Point for orientation");
            gp2.DrawLineFromPoint(pt1, false);
            gp2.Get();
            if (gp2.CommandResult() != Rhino.Commands.Result.Success)
            {
                return(gp2.CommandResult());
            }
            Point3d pt2 = gp2.Point();

            Vector3d vt1 = pt2 - pt1;

            sourcePlane = new Plane(pt1, vt1);
            Plane     originPlane = new Plane(Point3d.Origin, vt1);
            Transform bform       = Rhino.Geometry.Transform.PlaneToPlane(sourcePlane, originPlane);

            obj1Base.Transform(bform);

            GeometryBase[] obj1List = new GeometryBase[1] {
                obj1Base
            };

            var orientBlock = doc.InstanceDefinitions.Add("Block" + instDefCount, "OrientBlock", Point3d.Origin, obj1List);


            //orient instances along curve

            List <Guid> chainBlocks = new List <Guid>();
            Guid        chainBlock;

            while (true)
            {
                foreach (var block in chainBlocks)
                {
                    doc.Objects.Delete(block, false);
                }
                chainBlocks = new List <Guid>();
                double curveLength    = curve.GetLength();
                double curveDivide    = curveLength / chainDis;
                int    curveDivideInt = Convert.ToInt32(curveDivide);

                for (int ic = 0; ic < curveDivideInt; ic++)
                {
                    Point3d  insertPoint = curve.PointAtLength(chainDis * ic);
                    Vector3d insertVec   = curve.PointAtLength(chainDis * ic + 1) - curve.PointAtLength(chainDis * ic - 1);
                    Plane    targetPlane = new Plane(insertPoint, insertVec);

                    var xvec = targetPlane.XAxis;
                    if (xvec.Z != 0)
                    {
                        targetPlane.Rotate(Math.PI / 2, insertVec);
                    }

                    var yvec = targetPlane.YAxis;
                    if (yvec.Z < 0)
                    {
                        targetPlane.Rotate(Math.PI, insertVec);
                    }

                    if (ic % 2 == 0)
                    {
                        targetPlane.Rotate(Math.PI / 2, insertVec);
                    }
                    targetPlane.Rotate(axisOffsetRadiant, insertVec);
                    Rhino.Geometry.Transform xform = Rhino.Geometry.Transform.PlaneToPlane(originPlane, targetPlane);
                    chainBlock = doc.Objects.AddInstanceObject(orientBlock, xform);
                    chainBlocks.Add(chainBlock);
                }

                doc.Views.Redraw();
                GetOption gd = new GetOption();
                gd.SetCommandPrompt("Set distance between element centers in mm and rotation offset in degree. Press enter to accept.");
                var dis        = new Rhino.Input.Custom.OptionDouble(chainDis);
                var axisOffset = new Rhino.Input.Custom.OptionInteger(chainAxisOffset);
                gd.AddOptionDouble("distance", ref dis);
                gd.AddOptionInteger("rotation", ref axisOffset);
                gd.AcceptNothing(true);
                var resdis = gd.Get();
                if (resdis == GetResult.Nothing)
                {
                    break;
                }

                chainDis          = dis.CurrentValue;
                chainAxisOffset   = axisOffset.CurrentValue;
                axisOffsetRadiant = chainAxisOffset * (Math.PI / 180);
            }

            int index = doc.Groups.Add(chainBlocks);

            return(Result.Success);
        }