예제 #1
0
        public UiOptions(IHelper aHelper)
        {
            iWindowWidth     = new OptionDouble("windowwidth", "WindowWidth", "", 1024);
            iWindowHeight    = new OptionDouble("windowheight", "WindowHeight", "", 600);
            iWindowLocationX = new OptionDouble("windowx", "WindowLocationX", "", -1);
            iWindowLocationY = new OptionDouble("windowy", "WindowLocationY", "", -1);

            iBrowserSplitterLocationLeft  = new OptionInt("browsersplitterleft", "BrowserSplitterLocationLeft", "", 652);
            iBrowserSplitterLocationRight = new OptionInt("browsersplitterright", "BrowserSplitterLocationRight", "", 404);
            iFullscreen    = new OptionBool("fullscreen", "Fullscreen", "", false);
            iMiniMode      = new OptionBool("minimode", "MiniMode", "", false);
            iContainerView = new OptionUint("containerview", "ContainerView", "", 0);
            iContainerViewSizeThumbsView = new OptionDouble("containerviewsizethumbs", "ContainerViewSizeThumbs", "", 150);
            iContainerViewSizeListView   = new OptionDouble("containerviewsizelist", "ContainerViewSizeList", "", 100);

            iOptionDialogSettings = new OptionDialogSettings();

            aHelper.AddOption(iWindowWidth);
            aHelper.AddOption(iWindowHeight);
            aHelper.AddOption(iWindowLocationX);
            aHelper.AddOption(iWindowLocationY);
            aHelper.AddOption(iBrowserSplitterLocationLeft);
            aHelper.AddOption(iBrowserSplitterLocationRight);
            aHelper.AddOption(iFullscreen);
            aHelper.AddOption(iMiniMode);
            aHelper.AddOption(iContainerView);
            aHelper.AddOption(iContainerViewSizeThumbsView);
            aHelper.AddOption(iContainerViewSizeListView);
            aHelper.AddOption(iOptionDialogSettings);
        }
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            OptionDouble  amountOption = new OptionDouble(amount, 0.001, 300);
            OptionInteger triesOption  = new OptionInteger(tries, 1, 1000);

            GetObject go = new GetObject();

            go.SetCommandPrompt("Select meshes to Randomize");
            go.AddOptionDouble("Amount", ref amountOption);
            go.AddOptionInteger("Tries", ref triesOption);
            go.GeometryFilter = Rhino.DocObjects.ObjectType.Mesh;

            for (;;)
            {
                GetResult res = go.GetMultiple(1, 0);

                if (res == GetResult.Option)
                {
                    tries  = triesOption.CurrentValue;
                    amount = amountOption.CurrentValue;
                    continue;
                }

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

                break;
            }

            if (go.ObjectCount < 1)
            {
                return(Result.Failure);
            }

            foreach (var obj in go.Objects())
            {
                var rhinoMesh = obj.Mesh();

                if (rhinoMesh == null || !rhinoMesh.IsValid)
                {
                    continue;
                }

                var mesh = GopherUtil.ConvertToD3Mesh(obj.Mesh());

                g3.DMesh3 outputMeshRandom;
                GopherUtil.RandomizeMesh(mesh, out outputMeshRandom, amount, tries);

                var rhinoOutputMeshRandom = GopherUtil.ConvertToRhinoMesh(outputMeshRandom);
                doc.Objects.Replace(obj, rhinoOutputMeshRandom);
            }

            doc.Views.Redraw();

            return(Result.Success);
        }
예제 #3
0
        public GetAreaRectangle(double area, bool flip)
        {
            Area = new OptionDouble(area);

            AddOptionDouble("Area", ref Area);

            Flip = new OptionToggle(flip, "Right", "Left");
            AddOptionToggle("Side", ref Flip);
        }
예제 #4
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            const ObjectType selFilter      = ObjectType.PolysrfFilter | ObjectType.Extrusion;
            bool             value          = false;
            double           preShrinkValue = ZERO_CM;

            OptionToggle shrinkToDimensions = new OptionToggle(value, "Off", "On");
            OptionDouble preShrink          = new OptionDouble(preShrinkValue, 0.0, 1.0);
            ObjRef       boxObjRef          = null;

            GetObject go = new GetObject();

            go.SetCommandPrompt("Select the box to net-ify");
            go.AddOptionToggle("Constrain", ref shrinkToDimensions);
            go.AddOptionDouble("PreShrink", ref preShrink, "Preshrink");
            go.GeometryFilter = selFilter;

            go.EnableClearObjectsOnEntry(true);
            go.EnableUnselectObjectsOnExit(true);

            // TODO: clean up this hot mess
            for (;;)
            {
                GetResult getObjResult = go.Get();
                if (getObjResult == GetResult.Object)
                {
                    boxObjRef = go.Object(0);
                    boxObjRef.Object().Select(on: true, syncHighlight: true);
                    go.EnablePreSelect(false, true);
                    go.AcceptNothing(true);
                    continue;
                }

                else if (getObjResult == GetResult.Cancel)
                {
                    return(Result.Cancel);
                }

                // Case where user presses enter
                else if (getObjResult == GetResult.Nothing)
                {
                    if (boxObjRef != null)
                    {
                        preShrinkValue = preShrink.CurrentValue;
                        if (preShrinkValue != ZERO_CM)
                        {
                            boxObjRef = shrinkBoxObj(boxObjRef, preShrinkValue);
                        }
                        drawNetFromObjRef(boxObjRef, doc, shrinkToDimensions.CurrentValue);
                        return(Result.Success);
                    }
                }
            }
        }
예제 #5
0
 private static void ReadOptions(OptionToggle toggleVerbose,
                                 OptionDouble spotlightFactor, OptionDouble pointlightFactor, OptionDouble sunlightFactor,
                                 OptionDouble arealightFactor, OptionDouble polishFactor)
 {
     RcCore.It.EngineSettings.Verbose          = toggleVerbose.CurrentValue;
     RcCore.It.EngineSettings.SpotlightFactor  = (float)spotlightFactor.CurrentValue;
     RcCore.It.EngineSettings.PointlightFactor = (float)pointlightFactor.CurrentValue;
     RcCore.It.EngineSettings.SunlightFactor   = (float)sunlightFactor.CurrentValue;
     RcCore.It.EngineSettings.ArealightFactor  = (float)arealightFactor.CurrentValue;
     RcCore.It.EngineSettings.PolishFactor     = (float)polishFactor.CurrentValue;
 }
예제 #6
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            var getNumber = new GetInteger();

            getNumber.SetLowerLimit(0, false);
            getNumber.SetUpperLimit(500, false);
            getNumber.SetDefaultInteger(RcCore.It.EngineSettings.ThrottleMs);
            getNumber.SetCommandPrompt("Set throttle (in ms)");

            var toggleVerbose = new OptionToggle(RcCore.It.EngineSettings.Verbose, "No", "Yes");

            var spotlightFactor  = new OptionDouble(RcCore.It.EngineSettings.SpotlightFactor, 0.0, 1000000.0);
            var pointlightFactor = new OptionDouble(RcCore.It.EngineSettings.PointlightFactor, 0.0, 1000000.0);
            var sunlightFactor   = new OptionDouble(RcCore.It.EngineSettings.SunlightFactor, 0.0, 1000000.0);
            var arealightFactor  = new OptionDouble(RcCore.It.EngineSettings.ArealightFactor, 0.0, 1000000.0);
            var polishFactor     = new OptionDouble(RcCore.It.EngineSettings.PolishFactor, 0.0, 1000000.0);

            getNumber.AddOptionToggle("verbose", ref toggleVerbose);

            getNumber.AddOptionDouble("spotlight_factor", ref spotlightFactor);
            getNumber.AddOptionDouble("pointlight_factor", ref pointlightFactor);
            getNumber.AddOptionDouble("sunlight_factor", ref sunlightFactor);
            getNumber.AddOptionDouble("arealight_factor", ref arealightFactor);
            getNumber.AddOptionDouble("polish_factor", ref polishFactor);


            while (true)
            {
                var getRc = getNumber.Get();
                if (getNumber.CommandResult() != Result.Success)
                {
                    return(getNumber.CommandResult());
                }
                switch (getRc)
                {
                case GetResult.Nothing:
                case GetResult.Number:
                    RcCore.It.EngineSettings.ThrottleMs = getNumber.Number();
                    ReadOptions(toggleVerbose, spotlightFactor, pointlightFactor, sunlightFactor, arealightFactor, polishFactor);
                    break;

                case GetResult.Option:
                    ReadOptions(toggleVerbose, spotlightFactor, pointlightFactor, sunlightFactor, arealightFactor, polishFactor);
                    continue;

                default:
                    continue;
                }

                break;
            }
            return(Result.Success);
        }
예제 #7
0
        /// <summary>
        /// Initialize the values of the element
        /// </summary>
        /// <param name="absoluteTolerance">Absolute tolerance of the rhino document</param>
        /// <param name="isScripted">Are we running from a non-dynamic environment?</param>
        public void Initialize(double absoluteTolerance, bool isScripted)
        {
            EnableTransparentCommands(true);

            _tolerance            = new OptionDouble(absoluteTolerance / 10, RhinoMath.ZeroTolerance, double.MaxValue);
            _dynamicPreviewToggle = new OptionToggle(!isScripted, "Disabled", "Enabled");
            _evenOdd = new OptionToggle(true, "NonZero", "evenOdd");
            AddOptionEnum("BooleanType", BooleanType.Difference);
            AddOptionEnum("ProjectTo", ProjectToCplane.CPlane);
            AddOptionDouble("Tolerance", ref _tolerance, "Tolerance");
            AddOptionToggle("DynamicPreview", ref _dynamicPreviewToggle);
            AddOptionToggle("FillingRule", ref _evenOdd);
            AcceptNothing(true);
        }
예제 #8
0
        /// <summary>
        /// Initializes the specified absolute tolerance.
        /// </summary>
        /// <param name="absoluteTolerance">The absolute tolerance.</param>
        /// <param name="isScripted">if set to <c>true</c> [is scripted].</param>
        public void Initialize(double absoluteTolerance, bool isScripted)
        {
            EnableTransparentCommands(true);

            _offsetDistance       = new OptionDouble(10, absoluteTolerance, double.MaxValue);
            _tolerance            = new OptionDouble(absoluteTolerance / 10, RhinoMath.ZeroTolerance, double.MaxValue);
            _arcTolerance         = new OptionDouble(0.25, RhinoMath.ZeroTolerance, double.MaxValue);
            _miter                = new OptionDouble(1, RhinoMath.ZeroTolerance, double.MaxValue);
            _dynamicPreviewToggle = new OptionToggle(!isScripted, "Disabled", "Enabled");
            AddOptionDouble("Distance", ref _offsetDistance, "Distance");
            AddOptionDouble("Tolerance", ref _tolerance, "Tolerance");
            AddOptionEnum("Side", Side.Both);
            AddOptionEnum("OpenFillet", Polyline3D.OpenFilletType.Butt);
            AddOptionEnum("ClosedFillet", Polyline3D.ClosedFilletType.Square);
            AddOptionDouble("Miter", ref _miter, "Miter");
            AddOptionDouble("ArcTolerance", ref _arcTolerance, "ArcTolerance");
            AddOptionEnum("ProjectTo", ProjectToCplane.CPlane);
            AddOptionToggle("DynamicPreview", ref _dynamicPreviewToggle);
            AcceptNothing(true);
        }
        protected override Result RunCommand(Rhino.RhinoDoc doc, RunMode mode)
        {
            // TODO: start here modifying the behaviour of your command.
            // ---
            RhinoApp.WriteLine("The {0} command will select the curve with same length", EnglishName);
            double tolerance = 0.001;

            Rhino.Commands.Result rc = Rhino.Commands.Result.Failure;

            using (GetObject getObjectAction = new GetObject())
            {
                getObjectAction.GeometryFilter = ObjectType.Curve;
                getObjectAction.SetCommandPrompt("Please select curves");
                var dblOption = new OptionDouble(tolerance, true, 0);
                getObjectAction.AddOptionDouble("SelectionTolerance", ref dblOption);
                getObjectAction.EnablePreSelect(true, true);
                var    result    = getObjectAction.Get();
                double refLength = 0.0;
                if (result == GetResult.Object)
                {
                    var value = getObjectAction.Object(0);
                    var crv   = value.Curve();
                    if (crv != null)
                    {
                        refLength = crv.GetLength();
                        var objects = doc.Objects.FindByObjectType(ObjectType.Curve);
                        foreach (var obj in objects)
                        {
                            var _curve = (new ObjRef(obj)).Curve();
                            if (Rhino.RhinoMath.EpsilonEquals(_curve.GetLength(), refLength, dblOption.CurrentValue))
                            {
                                obj.Select(true);
                            }
                        }
                        rc = Rhino.Commands.Result.Success;
                    }
                }
            }
            doc.Views.Redraw();
            return(rc);
        }
예제 #10
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            toggle = !toggle;
            if (toggle)
            {
                string layername = "Heating Network";

                // Get all of the objects on the layer. If layername is bogus, you will
                // just get an empty list back
                Rhino.DocObjects.RhinoObject[] rhobjs = doc.Objects.FindByLayer(layername);
                if (rhobjs == null || rhobjs.Length < 1)
                {
                    return(Result.Cancel);
                }

                var curves = new Curve[rhobjs.Length];

                for (int i = 0; i < rhobjs.Length; i++)
                {
                    GeometryBase geom = rhobjs[i].Geometry;
                    Curve        x    = geom as Curve;
                    if (x != null && x.IsValid)
                    {
                        curves[i] = x;
                    }
                }

                OptionDouble tol = new OptionDouble(RhinoDoc.ActiveDoc.ModelAbsoluteTolerance, true, 0.0);

                CurvesTopology crvTopology = new CurvesTopology(curves, tol.CurrentValue);

                ids = CurvesTopologyPreview.Mark(crvTopology, Color.LightBlue, Color.LightCoral, Color.GreenYellow);

                return(Result.Success);
            }
            else
            {
                EndOperations(ids);
                return(Result.Success);
            }
        }
예제 #11
0
        // loads or makes a polyframe and planarizes the faces
        // load a set of geometries
        // if lines => must have PolyFrame date attached
        // if breps and data exists => reload topology data and update from geometry
        // if no data exists => make topology without cells
        // planarize and dump to the file
        // add topology data if cells are present.

        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            GetObject getObjects = new GetObject();

            getObjects.SetCommandPrompt("Pick the breps or PolyFrame container to planarize ");
            getObjects.GeometryFilter =
                Rhino.DocObjects.ObjectType.Brep |
                Rhino.DocObjects.ObjectType.Curve |
                Rhino.DocObjects.ObjectType.Mesh;
            // set up options

            getObjects.GroupSelect = true;

            OptionDouble dblOptionCollapse = new OptionDouble(0.1, true, 0.0);

            OptionToggle togOptionReplace = new OptionToggle(true, "Keep", "Replace");

            getObjects.AddOptionDouble("PointCollapseLimit", ref dblOptionCollapse);

            getObjects.AddOptionToggle("ReplaceGeo", ref togOptionReplace);
            getObjects.AcceptNothing(false);



            var primal = new PFoam();
            var dual   = new PFoam();


            while (true)
            {
                var r = getObjects.GetMultiple(1, 0);
                if (r == GetResult.Cancel)
                {
                    return(getObjects.CommandResult());
                }
                else if (r == GetResult.Object)
                {
                    break;
                }
            }



            List <Guid> ids = new List <Guid>();

            for (int i = 0; i < getObjects.ObjectCount; i++)
            {
                ids.Add(getObjects.Object(i).ObjectId);
            }


            try
            {
                ContainerType container = ContainerType.Edge;
                bool          usePFTopo = false;
                var           selGeo    = getObjects.Objects().Select(x => x.Geometry());
                if (selGeo.All(x => x.ObjectType == Rhino.DocObjects.ObjectType.Brep))
                {
                    if (selGeo.Any(y => y.UserDictionary.TryGetString("Primal", out string primalJson)))
                    {
                        Rhino.Input.RhinoGet.GetBool("PolyFrame data detected. Use topology data from there?", false, "no", "yes", ref usePFTopo);
                    }

                    if (usePFTopo)
                    {
                        //guids = LoadData.LoadPrimalDual(out primal, out dual);

                        var brepGeo = selGeo.Cast <Brep>().ToList();
                        if (brepGeo.Any(x => x.Faces.Count > 1))
                        {
                            container = ContainerType.CellBrep;
                        }
                        else
                        {
                            container = ContainerType.FaceBrep;
                        }

                        primal = LoadData.LoadFromFaces(brepGeo, out dual, true);
                    }
                    else
                    {
                        primal.ProcessBFaces(Util.DecomposeG(ids), dblOptionCollapse.CurrentValue, double.MaxValue);
                        primal.SortPartsInFaces();
                    }
                }
                else if (selGeo.All(x => x.ObjectType == Rhino.DocObjects.ObjectType.Curve))
                {
                    if (selGeo.Any(y => y.UserDictionary.TryGetString("Primal", out string primalJson)))
                    {
                        primal = LoadData.LoadFromEdges(selGeo.Cast <Curve>().ToList(), out dual, true);
                        //guids = LoadData.LoadPrimalDual(out primal, out dual);
                        container = ContainerType.Edge;
                    }
                    else
                    {
                        RhinoApp.WriteLine("No PolyFrame data detected. Planarization of raw line/curve data is not supported ");
                        return(Result.Failure);
                    }
                }
                else if (selGeo.All(x => x.ObjectType == Rhino.DocObjects.ObjectType.Mesh))
                {
                    if (selGeo.Any(y => y.UserDictionary.TryGetString("Primal", out string primalJson)))
                    {
                        var meshGeos = selGeo.Cast <Mesh>().ToList();
                        if (meshGeos.Any(x => x.Ngons.Count > 1 ||
                                         (x.Ngons.Count == 0 && x.Faces.Count > 1) ||
                                         (x.Ngons.Count == 1 && x.Faces.Count > x.Ngons[0].FaceCount)))
                        {
                            container = ContainerType.CellMesh;
                        }
                        else
                        {
                            container = ContainerType.FaceMesh;
                        }
                        primal = LoadData.LoadFromMeshes(meshGeos, out dual, true);
                    }
                    else
                    {
                        RhinoApp.WriteLine("No PolyFrame data detected. Planarization of raw mesh data is not supported ");
                        return(Result.Failure);
                    }
                }
예제 #12
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            bool bHavePreselectedObjects = false;

            const ObjectType geometryFilter = ObjectType.MeshFace;

            OptionDouble  minEdgeLengthOption     = new OptionDouble(minEdgeLength, 0.001, 200);
            OptionDouble  maxEdgeLengthOption     = new OptionDouble(maxEdgeLength, 0.001, 200);
            OptionDouble  constriantAngleOption   = new OptionDouble(constriantAngle, 0.001, 360);
            OptionInteger smoothStepsOptions      = new OptionInteger(smoothSteps, 0, 100);
            OptionDouble  smoothSpeedOption       = new OptionDouble(smoothSpeed, 0.01, 1.0);
            OptionDouble  projectAmountOption     = new OptionDouble(projectedAmount, 0.01, 1.0);
            OptionDouble  projectedDistanceOption = new OptionDouble(projectedDistance, 0.01, 100000.0);

            GetObject go = new GetObject();

            go.SetCommandPrompt("Select mesh faces to project onto another mesh");
            go.GeometryFilter = geometryFilter;

            go.AddOptionDouble("ConstraintAngle", ref constriantAngleOption);
            go.AddOptionDouble("MinEdge", ref minEdgeLengthOption);
            go.AddOptionDouble("MaxEdge", ref maxEdgeLengthOption);
            go.AddOptionInteger("SmoothSteps", ref smoothStepsOptions);
            go.AddOptionDouble("SmoothSpeed", ref smoothSpeedOption);

            go.GroupSelect     = true;
            go.SubObjectSelect = true;

            for (; ;)
            {
                GetResult faceres = go.GetMultiple(1, 0);

                if (faceres == GetResult.Option)
                {
                    go.EnablePreSelect(false, true);
                    continue;
                }

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

                if (go.ObjectsWerePreselected)
                {
                    bHavePreselectedObjects = true;
                    go.EnablePreSelect(false, true);
                    continue;
                }

                break;
            }

            minEdgeLength   = minEdgeLengthOption.CurrentValue;
            maxEdgeLength   = maxEdgeLengthOption.CurrentValue;
            constriantAngle = constriantAngleOption.CurrentValue;
            smoothSteps     = smoothStepsOptions.CurrentValue;
            smoothSpeed     = smoothSpeedOption.CurrentValue;

            //System.Collections.Generic.List<System.Guid> meshes = new System.Collections.Generic.List<System.Guid>();

            System.Guid rhinoMesh = System.Guid.Empty;

            System.Collections.Generic.List <int> removeFaces = new System.Collections.Generic.List <int>();

            g3.DMesh3 projectFaces = new g3.DMesh3(true, false, false, false);

            Rhino.Geometry.Mesh rhinoInputMesh = new Rhino.Geometry.Mesh();

            for (int i = 0; i < go.ObjectCount; i++)
            {
                ObjRef obj = go.Object(i);

                if (rhinoMesh == System.Guid.Empty)
                {
                    rhinoMesh      = obj.ObjectId;
                    rhinoInputMesh = obj.Mesh();

                    for (int j = 0; j < rhinoInputMesh.Vertices.Count; j++)
                    {
                        var vertex = new g3.NewVertexInfo();
                        vertex.n = new g3.Vector3f(rhinoInputMesh.Normals[j].X, rhinoInputMesh.Normals[j].Y, rhinoInputMesh.Normals[j].Z);
                        vertex.v = new g3.Vector3d(rhinoInputMesh.Vertices[j].X, rhinoInputMesh.Vertices[j].Y, rhinoInputMesh.Vertices[j].Z);
                        projectFaces.AppendVertex(vertex);
                    }
                }

                var m = rhinoInputMesh;

                if (rhinoMesh != obj.ObjectId)
                {
                    continue;
                }

                removeFaces.Add(obj.GeometryComponentIndex.Index);

                var mf = rhinoInputMesh.Faces[obj.GeometryComponentIndex.Index];


                if (mf.IsQuad)
                {
                    double dist1 = m.Vertices[mf.A].DistanceTo(m.Vertices[mf.C]);
                    double dist2 = m.Vertices[mf.B].DistanceTo(m.Vertices[mf.D]);
                    if (dist1 > dist2)
                    {
                        projectFaces.AppendTriangle(mf.A, mf.B, mf.D);
                        projectFaces.AppendTriangle(mf.B, mf.C, mf.D);
                    }
                    else
                    {
                        projectFaces.AppendTriangle(mf.A, mf.B, mf.C);
                        projectFaces.AppendTriangle(mf.A, mf.C, mf.D);
                    }
                }
                else
                {
                    projectFaces.AppendTriangle(mf.A, mf.B, mf.C);
                }
            }

            if (rhinoInputMesh == null)
            {
                return(Result.Failure);
            }

            removeFaces.Sort();
            removeFaces.Reverse();

            foreach (var removeFace in removeFaces)
            {
                rhinoInputMesh.Faces.RemoveAt(removeFace);
            }

            rhinoInputMesh.Compact();

            GetObject goProjected = new GetObject();

            goProjected.EnablePreSelect(false, true);
            goProjected.SetCommandPrompt("Select mesh to project to");
            goProjected.GeometryFilter = ObjectType.Mesh;
            goProjected.AddOptionDouble("ConstraintAngle", ref constriantAngleOption);
            goProjected.AddOptionDouble("MinEdge", ref minEdgeLengthOption);
            goProjected.AddOptionDouble("MaxEdge", ref maxEdgeLengthOption);
            goProjected.AddOptionInteger("SmoothSteps", ref smoothStepsOptions);
            goProjected.AddOptionDouble("SmoothSpeed", ref smoothSpeedOption);
            goProjected.AddOptionDouble("ProjectAmount", ref projectAmountOption);
            goProjected.AddOptionDouble("ProjectDistance", ref projectedDistanceOption);

            goProjected.GroupSelect     = true;
            goProjected.SubObjectSelect = false;
            goProjected.EnableClearObjectsOnEntry(false);
            goProjected.EnableUnselectObjectsOnExit(false);


            for (; ;)
            {
                GetResult resProject = goProjected.Get();

                if (resProject == GetResult.Option)
                {
                    continue;
                }
                else if (goProjected.CommandResult() != Result.Success)
                {
                    return(goProjected.CommandResult());
                }

                break;
            }


            minEdgeLength     = minEdgeLengthOption.CurrentValue;
            maxEdgeLength     = maxEdgeLengthOption.CurrentValue;
            constriantAngle   = constriantAngleOption.CurrentValue;
            smoothSteps       = smoothStepsOptions.CurrentValue;
            smoothSpeed       = smoothSpeedOption.CurrentValue;
            projectedAmount   = projectAmountOption.CurrentValue;
            projectedDistance = projectedDistanceOption.CurrentValue;

            if (bHavePreselectedObjects)
            {
                // Normally, pre-selected objects will remain selected, when a
                // command finishes, and post-selected objects will be unselected.
                // This this way of picking, it is possible to have a combination
                // of pre-selected and post-selected. So, to make sure everything
                // "looks the same", lets unselect everything before finishing
                // the command.
                for (int i = 0; i < go.ObjectCount; i++)
                {
                    RhinoObject rhinoObject = go.Object(i).Object();
                    if (null != rhinoObject)
                    {
                        rhinoObject.Select(false);
                    }
                }
                doc.Views.Redraw();
            }

            bool result = false;

            if (goProjected.ObjectCount < 1)
            {
                return(Result.Failure);
            }


            var rhinoMeshProject = goProjected.Object(0).Mesh();

            if (rhinoMeshProject == null || !rhinoMeshProject.IsValid)
            {
                return(Result.Failure);
            }

            var meshProjected = GopherUtil.ConvertToD3Mesh(rhinoMeshProject);

            var res = GopherUtil.RemeshMesh(projectFaces, (float)minEdgeLength, (float)maxEdgeLength, (float)constriantAngle, (float)smoothSpeed, smoothSteps, meshProjected, (float)projectedAmount, (float)projectedDistance);

            var newRhinoMesh = GopherUtil.ConvertToRhinoMesh(res);

            if (newRhinoMesh != null && newRhinoMesh.IsValid)
            {
                newRhinoMesh.Append(rhinoInputMesh);

                result |= doc.Objects.Replace(rhinoMesh, newRhinoMesh);
            }

            doc.Views.Redraw();

            return(Result.Success);
        }
예제 #13
0
        /// <summary>
        /// RunCommand override
        /// </summary>
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            // Get persistent settings (from Registry)
            var bool_value = Settings.GetBool("BoolValue", BOOL_DEFAULT);
            var int_value  = Settings.GetInteger("IntValue", INT_DEFAULT);
            var dbl_value  = Settings.GetDouble("DblValue", DBL_DEFAULT);
            var list_value = Settings.GetInteger("ListValue", LIST_DEFAULT);

            var gp = new GetPoint();

            gp.SetCommandPrompt("GetPoint with options");

            var rc = Result.Cancel;

            while (true)
            {
                gp.ClearCommandOptions();

                var bool_option = new OptionToggle(bool_value, "Off", "On");
                var int_option  = new OptionInteger(int_value, 1, 99);
                var dbl_option  = new OptionDouble(dbl_value, 0, 99.9);
                var list_items  = new[] { "Item0", "Item1", "Item2", "Item3", "Item4" };

                var bool_index  = gp.AddOptionToggle("Boolean", ref bool_option);
                var int_index   = gp.AddOptionInteger("Integer", ref int_option);
                var dbl_index   = gp.AddOptionDouble("Double", ref dbl_option);
                var list_index  = gp.AddOptionList("List", list_items, list_value);
                var reset_index = gp.AddOption("Reset");

                var res = gp.Get();

                if (res == Rhino.Input.GetResult.Point)
                {
                    doc.Objects.AddPoint(gp.Point());
                    doc.Views.Redraw();
                    rc = Result.Success;
                }
                else if (res == Rhino.Input.GetResult.Option)
                {
                    var option = gp.Option();
                    if (null != option)
                    {
                        if (option.Index == bool_index)
                        {
                            bool_value = bool_option.CurrentValue;
                        }
                        else if (option.Index == int_index)
                        {
                            int_value = int_option.CurrentValue;
                        }
                        else if (option.Index == dbl_index)
                        {
                            dbl_value = dbl_option.CurrentValue;
                        }
                        else if (option.Index == list_index)
                        {
                            list_value = option.CurrentListOptionIndex;
                        }
                        else if (option.Index == reset_index)
                        {
                            bool_value = BOOL_DEFAULT;
                            int_value  = INT_DEFAULT;
                            dbl_value  = DBL_DEFAULT;
                            list_value = LIST_DEFAULT;
                        }
                    }
                    continue;
                }

                break;
            }

            if (rc == Result.Success)
            {
                // Set persistent settings (to Registry)
                Settings.SetBool("BoolValue", bool_value);
                Settings.SetInteger("IntValue", int_value);
                Settings.SetDouble("DblValue", dbl_value);
                Settings.SetInteger("ListValue", list_value);
            }

            return(rc);
        }
예제 #14
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.
        }
예제 #15
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            //look at this for a summary of all the GET commands.

            // https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_Input_Custom_GetBaseClass.htm.

            /*System.Object
             * Rhino.Input.Custom.GetBaseClass
             *  Rhino.Input.Custom.GetInteger
             *  Rhino.Input.Custom.GetNumber
             *  Rhino.Input.Custom.GetObject
             *  Rhino.Input.Custom.GetOption
             *  Rhino.Input.Custom.GetPoint
             *  Rhino.Input.Custom.GetString
             *
             * */
            var gc = new GetObject();

            gc.SetCommandPrompt("Select objects");
            gc.GeometryFilter = ObjectType.AnyObject;

            OptionInteger intOption  = new OptionInteger(1, 1, 99);
            OptionDouble  dblOption  = new OptionDouble(2.2, 0, 99);
            OptionToggle  boolOption = new OptionToggle(true, "off", "on");

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

            int listIndex = 0;

            string[] listValues = new string[] { "Bran", "Bob", "Arya", "Sansa", "Rickon" };

            int optList = gc.AddOptionList("List", listValues, listIndex);

            while (true)
            {
                GetResult res = gc.GetMultiple(1, 0);

                //we can check if the user selected something
                if (gc.CommandResult() != Result.Success)
                {
                    return(gc.CommandResult());
                }

                if (res == Rhino.Input.GetResult.Object)
                {
                    RhinoApp.WriteLine("Command line option values are");
                    RhinoApp.WriteLine("Integer = {0}", intOption.CurrentValue);
                    RhinoApp.WriteLine("Double = {0}", dblOption.CurrentValue);
                    RhinoApp.WriteLine("Boolean = {0}", boolOption.CurrentValue);
                    RhinoApp.WriteLine("List = {0}", listValues[listIndex]);
                }
                else if (res == Rhino.Input.GetResult.Option)
                {
                    if (gc.OptionIndex() == optList)
                    {
                        listIndex = gc.Option().CurrentListOptionIndex; //this updates the list option to whatever index the user has picked
                    }
                    continue;
                }

                break;
            }

            return(Result.Success);
        }
예제 #16
0
        public GetDoubleLine(double width)
        {
            LineWidth = new OptionDouble(width);

            AddOptionDouble("Linewidth", ref LineWidth);
        }
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            const ObjectType geometryFilter = ObjectType.Mesh;

            OptionDouble  minEdgeLengthOption   = new OptionDouble(minEdgeLength, 0.001, 200);
            OptionDouble  maxEdgeLengthOption   = new OptionDouble(maxEdgeLength, 0.001, 200);
            OptionDouble  constriantAngleOption = new OptionDouble(constriantAngle, 0.001, 360);
            OptionInteger smoothStepsOptions    = new OptionInteger(smoothSteps, 0, 10000);
            OptionDouble  smoothSpeedOption     = new OptionDouble(smoothSpeed, 0.01, 1.0);

            GetObject go = new GetObject();

            go.SetCommandPrompt("Select meshes to remesh");
            go.GeometryFilter = geometryFilter;
            go.AddOptionDouble("ConstraintAngle", ref constriantAngleOption);
            go.AddOptionDouble("MinEdge", ref minEdgeLengthOption);
            go.AddOptionDouble("MaxEdge", ref maxEdgeLengthOption);
            go.AddOptionInteger("SmoothSteps", ref smoothStepsOptions);
            go.AddOptionDouble("SmoothSpeed", ref smoothSpeedOption);

            go.GroupSelect     = true;
            go.SubObjectSelect = false;
            go.EnableClearObjectsOnEntry(false);
            go.EnableUnselectObjectsOnExit(false);
            go.DeselectAllBeforePostSelect = false;

            bool bHavePreselectedObjects = false;

            for (;;)
            {
                GetResult res = go.GetMultiple(1, 0);

                if (res == GetResult.Option)
                {
                    go.EnablePreSelect(false, true);
                    continue;
                }

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

                if (go.ObjectsWerePreselected)
                {
                    bHavePreselectedObjects = true;
                    go.EnablePreSelect(false, true);
                    continue;
                }

                break;
            }

            minEdgeLength   = minEdgeLengthOption.CurrentValue;
            maxEdgeLength   = maxEdgeLengthOption.CurrentValue;
            constriantAngle = constriantAngleOption.CurrentValue;
            smoothSteps     = smoothStepsOptions.CurrentValue;
            smoothSpeed     = smoothSpeedOption.CurrentValue;

            if (bHavePreselectedObjects)
            {
                // Normally, pre-selected objects will remain selected, when a
                // command finishes, and post-selected objects will be unselected.
                // This this way of picking, it is possible to have a combination
                // of pre-selected and post-selected. So, to make sure everything
                // "looks the same", lets unselect everything before finishing
                // the command.
                for (int i = 0; i < go.ObjectCount; i++)
                {
                    RhinoObject rhinoObject = go.Object(i).Object();
                    if (null != rhinoObject)
                    {
                        rhinoObject.Select(false);
                    }
                }
                doc.Views.Redraw();
            }

            bool result = false;

            foreach (var obj in go.Objects())
            {
                var rhinoMesh = obj.Mesh();

                if (rhinoMesh == null || !rhinoMesh.IsValid)
                {
                    continue;
                }

                var mesh = GopherUtil.ConvertToD3Mesh(obj.Mesh());

                var res = GopherUtil.RemeshMesh(mesh, (float)minEdgeLength, (float)maxEdgeLength, (float)constriantAngle, (float)smoothSpeed, smoothSteps);

                var newRhinoMesh = GopherUtil.ConvertToRhinoMesh(mesh);

                if (newRhinoMesh != null && newRhinoMesh.IsValid)
                {
                    doc.Objects.Replace(obj, newRhinoMesh);
                }

                if (newRhinoMesh != null && newRhinoMesh.IsValid)
                {
                    result |= doc.Objects.Replace(obj, newRhinoMesh);
                }
            }

            doc.Views.Redraw();

            return(Result.Success);
        }
예제 #18
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);
        }
예제 #19
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            double tolerance  = doc.ModelAbsoluteTolerance;
            var    opt_double = new OptionDouble(Radius, true, tolerance);

            // Select first surface to fillet
            var go0 = new GetObject();

            go0.SetCommandPrompt("Select first surface to fillet");
            go0.AddOptionDouble("Radius", ref opt_double, "Fillet radius");
            go0.GeometryFilter = ObjectType.Surface;
            go0.EnablePreSelect(false, true);
            for (;;)
            {
                GetResult res = go0.Get();
                if (res == GetResult.Option)
                {
                    continue;
                }
                else if (res != GetResult.Object)
                {
                    return(Result.Cancel);
                }
                break;
            }

            var      obj_ref0 = go0.Object(0);
            BrepFace face0    = obj_ref0.Face();

            if (null == face0)
            {
                return(Result.Failure);
            }

            double u0, v0;

            if (null == obj_ref0.SurfaceParameter(out u0, out v0))
            {
                var pt = obj_ref0.SelectionPoint();
                if (!pt.IsValid || !face0.ClosestPoint(pt, out u0, out v0))
                {
                    // Make surface selection scriptable
                    u0 = face0.Domain(0).Min;
                    v0 = face0.Domain(1).Min;
                }
            }

            // Juggle the pickpoint ever so slightly towards the middle of the domain
            // to get a better chance of getting a valid chord.
            if (u0 == face0.Domain(0).Min || u0 == face0.Domain(0).Max)
            {
                u0 = 0.99 * u0 + 0.01 * face0.Domain(0).Mid;
            }
            if (v0 == face0.Domain(1).Min || v0 == face0.Domain(1).Max)
            {
                v0 = 0.99 * v0 + 0.01 * face0.Domain(1).Mid;
            }

            // Select second surface to fillet
            var go1 = new GetObject();

            go1.SetCommandPrompt("Select second surface to fillet");
            go1.AddOptionDouble("Radius", ref opt_double, "Fillet radius");
            go1.GeometryFilter = ObjectType.Surface;
            go1.EnablePreSelect(false, true);
            go1.DeselectAllBeforePostSelect = false;
            for (;;)
            {
                GetResult res = go1.Get();
                if (res == GetResult.Option)
                {
                    continue;
                }
                else if (res != GetResult.Object)
                {
                    return(Result.Cancel);
                }
                break;
            }

            var      obj_ref1 = go1.Object(0);
            BrepFace face1    = obj_ref1.Face();

            if (null == face1)
            {
                return(Result.Failure);
            }

            double u1, v1;

            if (null == obj_ref1.SurfaceParameter(out u1, out v1))
            {
                var pt = obj_ref1.SelectionPoint();
                if (!pt.IsValid || !face1.ClosestPoint(pt, out u1, out v1))
                {
                    // Make surface selection scriptable
                    u1 = face1.Domain(0).Min;
                    v1 = face1.Domain(1).Min;
                }
            }

            // Juggle the pickpoint ever so slightly towards the middle of the domain
            // to get a better chance of getting a valid chord.
            if (u1 == face1.Domain(0).Min || u1 == face1.Domain(0).Max)
            {
                u1 = 0.99 * u0 + 0.01 * face1.Domain(0).Mid;
            }
            if (v1 == face1.Domain(1).Min || v1 == face1.Domain(1).Max)
            {
                v1 = 0.99 * v0 + 0.01 * face1.Domain(1).Mid;
            }

            var p0      = new Point2d(u0, v0);
            var p1      = new Point2d(u1, v1);
            var fillets = Surface.CreateRollingBallFillet(face0, p0, face1, p1, Radius, tolerance);

            foreach (var f in fillets)
            {
                doc.Objects.AddSurface(f);
            }

            doc.Views.Redraw();

            Radius = opt_double.CurrentValue;

            return(Result.Success);
        }
예제 #20
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            SearchMode sm = SearchMode.CurveLength;

            Curve[]      curves;
            OptionToggle tog = new OptionToggle(false, "Hide", "Show");
            OptionDouble tol = new OptionDouble(RhinoDoc.ActiveDoc.ModelAbsoluteTolerance, true, 0.0);

            using (CurvesGetter getLines = new CurvesGetter("Select curves meeting at endpoints. Press Enter when done"))
            {
                for ( ; ;)
                {
                    getLines.ClearCommandOptions();
                    getLines.EnableClearObjectsOnEntry(false);
                    int showInt = getLines.AddOptionToggle("Topology", ref tog);
                    int tolInt  = getLines.AddOptionDouble("Tolerance", ref tol);
                    int modeInt = GetterExtension.AddEnumOptionList(getLines, sm);

                    if (getLines.Curves(1, 0, out curves))
                    {
                        break;
                    }
                    else
                    {
                        if (getLines.Result() == GetResult.Option)
                        {
                            if (getLines.Option().Index == modeInt)
                            {
                                sm = GetterExtension.RetrieveEnumOptionValue <SearchMode>
                                         (getLines.Option().CurrentListOptionIndex);
                            }
                            continue;
                        }
                        else
                        {
                            RhinoApp.WriteLine("Less than three lines were selected");
                            return(Result.Cancel);
                        }
                    }
                }
            }
            CurvesTopology crvTopology = new CurvesTopology(curves, tol.CurrentValue);

            Guid[] ids = null;
            if (tog.CurrentValue)
            {
                ids = CurvesTopologyPreview.Mark(crvTopology, Color.LightBlue, Color.LightCoral);
            }

            int walkFromIndex;

            using (var getStart = new TrackingPointGetter("Select the start point of the walk on the curves", crvTopology))
            {
                if (getStart.GetPointOnTopology(out walkFromIndex) != Result.Success)
                {
                    EndOperations(ids);
                    return(Result.Cancel);
                }
            }

            Result wasSuccessful = Result.Cancel;

            for (; ;)
            {
                int      walkToIndex;
                double[] distances;
                using (var getEnd = new TrackingPointGetter("Select the end point", crvTopology, walkFromIndex, sm))
                {
                    if (getEnd.GetPointOnTopology(out walkToIndex) != Result.Success)
                    {
                        break;
                    }
                    distances = getEnd.DistanceCache;
                }

                if (walkFromIndex == walkToIndex)
                {
                    RhinoApp.WriteLine("Start and end points are equal");
                    EndOperations(ids);
                    return(Result.Nothing);
                }

                PathMethod pathSearch = PathMethod.FromMode(sm, crvTopology, distances);

                int[]  nIndices, eIndices;
                bool[] eDirs;
                double totLength;
                Curve  c =
                    pathSearch.Cross(walkFromIndex, walkToIndex, out nIndices, out eIndices, out eDirs, out totLength);

                if (c != null && c.IsValid)
                {
                    if (tog.CurrentValue)
                    {
                        RhinoApp.WriteLine("Vertices: {0}", FormatNumbers(nIndices));
                        RhinoApp.WriteLine("Edges: {0}", FormatNumbers(eIndices));
                    }

                    var  a = RhinoDoc.ActiveDoc.CreateDefaultAttributes();
                    Guid g = RhinoDoc.ActiveDoc.Objects.AddCurve(c, a);

                    var obj = RhinoDoc.ActiveDoc.Objects.Find(g);
                    if (obj != null)
                    {
                        obj.Select(true);
                        wasSuccessful = Result.Success;
                        walkFromIndex = walkToIndex;
                    }
                    else
                    {
                        RhinoApp.WriteLine("An error occurred while adding the new polycurve.");
                        wasSuccessful = Result.Failure;
                        break;
                    }
                }
                else
                {
                    RhinoApp.WriteLine("No path was found. Nodes are isolated.");
                    wasSuccessful = Result.Nothing;
                }
            }

            EndOperations(ids);
            return(wasSuccessful);
        }
예제 #21
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            var ptPuffynessOption       = new OptionToggle(m_PointPuffyness, "False", "True");
            var ptOffsetOption          = new OptionDouble(m_PuffynessOffset, 0.5, double.PositiveInfinity);
            var ptBorderPuffynessOption = new OptionToggle(m_BorderPuffyness, "False", "True");
            var borderOffsetOption      = new OptionDouble(m_BorderOffset, 0.5, double.PositiveInfinity);

            var go = new GetOption();

            go.SetCommandPrompt("Get meshing properties");
            go.AcceptNothing(true);
            go.AcceptEnterWhenDone(true);

            int ptPuffyOptionIndex      = go.AddOptionToggle("PointPuffyness", ref ptPuffynessOption);
            int offsetOptionIndex       = go.AddOptionDouble("OffsetPtPuffy", ref ptOffsetOption);
            int borderPuffyOptionIndex  = go.AddOptionToggle("BorderPuffyness", ref ptBorderPuffynessOption);
            int borderOffsetOptionIndex = go.AddOptionDouble("OffsetBorderPuffy", ref borderOffsetOption);

            go.Get();
            var result = go.Result();

            while (result != GetResult.Nothing)
            {
                if (result == GetResult.Cancel)
                {
                    return(Result.Cancel);
                }

                int optionIdx = go.OptionIndex();
                if (optionIdx == ptPuffyOptionIndex)
                {
                    m_PointPuffyness = ptPuffynessOption.CurrentValue;
                }
                else if (optionIdx == offsetOptionIndex)
                {
                    m_PuffynessOffset = ptOffsetOption.CurrentValue;
                }
                else if (optionIdx == borderPuffyOptionIndex)
                {
                    m_BorderPuffyness = ptBorderPuffynessOption.CurrentValue;
                }
                else if (optionIdx == borderOffsetOptionIndex)
                {
                    m_BorderOffset = borderOffsetOption.CurrentValue;
                }

                result = go.Get();
            }

            ObjRef[] rhObjects;
            var      res = RhinoGet.GetMultipleObjects("Select planar curves and Weight points", false, Rhino.DocObjects.ObjectType.Curve | Rhino.DocObjects.ObjectType.Point, out rhObjects);

            if (res == Result.Success)
            {
                // 1. subdive in sets: Closed curves, Opened Curves, weight points;
                List <Curve> closed_crvs   = new List <Curve>();
                List <Curve> opened_crvs   = new List <Curve>();
                List <Point> weight_points = new List <Point>();

                bool   puffyness = m_PointPuffyness;
                double offset    = m_PuffynessOffset;

                bool   border_puffyness = m_BorderPuffyness;
                double border_offset    = m_BorderOffset;

                foreach (var ref_obj in rhObjects)
                {
                    RhinoObject obj = ref_obj.Object();
                    if (obj.Geometry is Curve)
                    {
                        var crv = obj.Geometry as Curve;
                        if (crv.IsPlanar())
                        {
                            if (crv.IsClosed)
                            {
                                closed_crvs.Add(crv);
                            }
                            else
                            {
                                opened_crvs.Add(crv);
                            }
                        }
                    }
                    else if (obj.Geometry is Point)
                    {
                        weight_points.Add(obj.Geometry as Point);
                    }
                }

                double space = 1;

                // 2. Insert curves into mesh
                AM_Region region = null;

                Curve border_outer_crv = null;
                Curve offset_outer_crv = null;

                if (closed_crvs.Count > 0)
                {
                    region = new AM_Region();

                    for (int i = 0; i < closed_crvs.Count; i++)
                    {
                        var crv = closed_crvs[i];

                        region.AddCurve(crv, space, false);

                        AreaMassProperties area = AreaMassProperties.Compute(crv, AM_Util.FLT_EPSILON);
                        if (area.Area > 0 && border_puffyness)
                        {
                            if (border_outer_crv == null)
                            {
                                border_outer_crv = crv;
                            }

                            var offset_Crvs = crv.Offset(Plane.WorldXY, -border_offset, AM_Util.FLT_EPSILON, CurveOffsetCornerStyle.None);

                            foreach (var c in offset_Crvs)
                            {
                                c.Reverse();
                                doc.Objects.AddCurve(c);
                                offset_outer_crv = c;

                                region.AddCurve(c, space, true);
                            }
                        }
                    }
                }
                else
                {
                    // TODO
                    Debug.Assert(false);
                    return(Result.Failure);
                }

                for (int i = 0; i < weight_points.Count; i++)
                {
                    var pt = weight_points[i];

                    region.AddWeigthPoint(pt, space / 2);
                    if (puffyness && offset > 0)
                    {
                        var circle = new ArcCurve(new Circle(pt.Location, offset));
                        var nurbs  = circle.ToNurbsCurve();
                        region.AddCurve(nurbs, space / 2, true);
                    }
                }

                for (int i = 0; i < opened_crvs.Count; i++)
                {
                    var crv = opened_crvs[i];
                    region.AddCurve(crv, space, false);

                    if (puffyness && offset > 0)
                    {
                        var     n         = Vector3d.CrossProduct(crv.TangentAtStart, Vector3d.ZAxis);
                        Curve[] offsetCrv = crv.Offset(crv.PointAtStart + offset * n, Vector3d.ZAxis, offset, AM_Util.FLT_EPSILON, CurveOffsetCornerStyle.Round);

                        foreach (var c in offsetCrv)
                        {
                            doc.Objects.AddCurve(c);
                            region.AddCurve(crv, space, false);
                        }

                        Curve[] offsetCrv2 = crv.Offset(crv.PointAtStart - offset * n, Vector3d.ZAxis, offset, AM_Util.FLT_EPSILON, CurveOffsetCornerStyle.Round);

                        foreach (var c in offsetCrv2)
                        {
                            doc.Objects.AddCurve(c);
                            region.AddCurve(crv, space, false);
                        }
                    }
                }

                // 3. Mesh della regione
                if (region != null)
                {
                    if (region.BuildMesh())
                    {
                        // Inserisce i punti del contorno
                        foreach (var loop in region.Loops)
                        {
                            for (int i = 0; i < loop.NumSegments; i++)
                            {
                                var points = loop.GetGeneratedPoints(i);

                                //if (points != null) {
                                //  foreach (var p in points) {
                                //    doc.Objects.AddPoint(new Point3d(p.X, p.Y, 0));
                                //  }
                                //}
                            }
                        }
                    }

                    // Trasforma in Mesh di Rhino
                    var mesh = region.Mesh2D;

                    if (mesh != null)
                    {
                        Mesh   rhino_mesh = new Mesh();
                        double t          = 5;
                        for (int i = 0; i < mesh.ArrayVertexes.Count; i++)
                        {
                            mesh.ArrayVertexes[i].Z = t;
                        }

                        // PostProcessa il puffyness
                        if (puffyness)
                        {
                            for (int i = 0; i < region.ArrayInnerVertex.Count; i++)
                            {
                                var iv = region.ArrayInnerVertex[i];
                                if (iv.MeshVertex != null)
                                {
                                    iv.MeshVertex.Z = (4 / 5d) * t;
                                }

                                // Ricerca i punti nell'intorno fino all'offset (molto grezza!)
                                for (int j = 0; j < mesh.ArrayVertexes.Count; j++)
                                {
                                    var    v = mesh.ArrayVertexes[j];
                                    double d = (iv.MeshVertex.Coord - v.Coord).Length;
                                    if (d < offset)
                                    {
                                        double r = d / offset;

                                        AM_Util.EInterpolation interpolation = AM_Util.EInterpolation.Parabolic;
                                        v.Z = AM_Util.Interpolation(interpolation, iv.MeshVertex.Z, t, r);
                                    }
                                }
                            }
                        }

                        // Individua i punti all'interno della zona di transizione
                        List <int> transitionVts = new List <int>();

                        if (border_puffyness && border_offset > 0)
                        {
                            // Individua i vertici di partenza e utilizza u flag di lavoro
                            List <AM_Vertex> transitionStartVts = new List <AM_Vertex>();

                            for (int i = 0; i < mesh.ArrayVertexes.Count; i++)
                            {
                                var  v = mesh.ArrayVertexes[i];
                                bool is_loop_vertex = (v.Flag & 0x1) > 0;
                                v.Flag &= ~0x02;

                                if (is_loop_vertex && BelongToBorder(v))
                                {
                                    transitionStartVts.Add(v);
                                }
                            }

                            // Si usa 0x04 come flag di lavoro
                            for (int i = 0; i < mesh.ArrayWEdges.Count; i++)
                            {
                                var e                 = mesh.ArrayWEdges[i];
                                e.Edge().Flag        &= ~0x04;
                                e.Edge().Symm().Flag &= ~0x04;
                            }

                            for (int i = 0; i < transitionStartVts.Count; i++)
                            {
                                var v = transitionStartVts[i];
                                AddTransitionVertexes(v, transitionVts);
                            }

                            if (offset_outer_crv != null)
                            {
                                foreach (var iv in transitionVts)
                                {
                                    var v = mesh.ArrayVertexes[iv];

                                    double par;
                                    if (offset_outer_crv.ClosestPoint(AM_Util.To3d(v.Coord), out par, 2 * border_offset))
                                    {
                                        Point3d cp = offset_outer_crv.PointAt(par);
                                        double  r  = ((cp - AM_Util.To3d(v.Coord)).Length) / border_offset;
                                        double  z  = AM_Util.Interpolation(AM_Util.EInterpolation.Parabolic, 0.8 * t, t, 1 - r);
                                        v.Z = z;
                                    }
                                }
                            }
                        }

                        // Facce
                        int totVtx = mesh.ArrayVertexes.Count;

                        for (int iSide = 0; iSide < 2; iSide++)
                        {
                            for (int i = 0; i < mesh.ArrayVertexes.Count; i++)
                            {
                                var     v  = mesh.ArrayVertexes[i];
                                Point3d pt = v.Coord3d;
                                if (iSide == 1)
                                {
                                    pt.Z = 0;
                                }

                                rhino_mesh.Vertices.Add(pt);
                            }

                            for (int i = 0; i < mesh.ArrayFaces.Count; i++)
                            {
                                var f = mesh.ArrayFaces[i];

                                int numEdges = f.NumEdges;
                                if (numEdges == 3)
                                {
                                    int[] vtx = { f.Vertex(0).Index, f.Vertex(1).Index, f.Vertex(2).Index };
                                    if (iSide == 1)
                                    {
                                        vtx = new int[] { f.Vertex(0).Index + totVtx, f.Vertex(2).Index + totVtx, f.Vertex(1).Index + totVtx };
                                    }
                                    rhino_mesh.Faces.AddFace(vtx[0], vtx[1], vtx[2]);
                                }
                                else if (numEdges == 4)
                                {
                                    int[] vtx = { f.Vertex(0).Index, f.Vertex(1).Index, f.Vertex(2).Index, f.Vertex(3).Index };
                                    if (iSide == 1)
                                    {
                                        vtx = new int[] { f.Vertex(0).Index + totVtx, f.Vertex(3).Index + totVtx, f.Vertex(2).Index + totVtx, f.Vertex(1).Index + totVtx };
                                    }

                                    rhino_mesh.Faces.AddFace(vtx[0], vtx[1], vtx[2], vtx[3]);
                                }
                            }
                        }

                        for (int iEdge = 0; iEdge < mesh.ArrayWEdges.Count; iEdge++)
                        {
                            var edge = mesh.ArrayWEdges[iEdge].Edge();
                            if (edge.CcwFace() == null || edge.CwFace() == null)
                            {
                                // E' uno spigolo di bordo
                                int[] vtx = { edge.Destination().Index,     edge.Origin().Index,
                                              edge.Origin().Index + totVtx, edge.Destination().Index + totVtx, };
                                rhino_mesh.Faces.AddFace(vtx[0], vtx[1], vtx[2], vtx[3]);
                            }
                        }

                        rhino_mesh.Normals.ComputeNormals();
                        rhino_mesh.Compact();
                        if (doc.Objects.AddMesh(rhino_mesh) != Guid.Empty)
                        {
                            doc.Views.Redraw();
                            return(Rhino.Commands.Result.Success);
                        }
                    }
                }

                return(Result.Success);
            }


            return(Result.Cancel);
        }
예제 #22
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            var getNumber = new GetNumber();

            getNumber.SetLowerLimit(2.0, false);
            getNumber.SetUpperLimit(uint.MaxValue, false);
            getNumber.SetDefaultInteger(RcCore.It.EngineSettings.Samples);
            getNumber.SetCommandPrompt("Set render samples");

            var showMaxPasses = new OptionToggle(RcCore.It.EngineSettings.ShowMaxPasses, "HideMaxPasses", "ShowMaxPasses");

            var maxBounce = new OptionInteger(RcCore.It.EngineSettings.MaxBounce, 0, 500);
            var tileX     = new OptionInteger(RcCore.It.EngineSettings.TileX, 0, 10000);
            var tileY     = new OptionInteger(RcCore.It.EngineSettings.TileY, 0, 10000);


            var maxDiffuseBounce      = new OptionInteger(RcCore.It.EngineSettings.MaxDiffuseBounce, 0, 200);
            var maxGlossyBounce       = new OptionInteger(RcCore.It.EngineSettings.MaxGlossyBounce, 0, 200);
            var maxTransmissionBounce = new OptionInteger(RcCore.It.EngineSettings.MaxTransmissionBounce, 0, 200);
            var maxVolumeBounce       = new OptionInteger(RcCore.It.EngineSettings.MaxVolumeBounce, 0, 200);

            var noCaustics = new OptionToggle(RcCore.It.EngineSettings.NoCaustics, "Caustics", "NoCaustics");

            var aaSamples     = new OptionInteger(RcCore.It.EngineSettings.AaSamples, 1, 100);
            var diffSamples   = new OptionInteger(RcCore.It.EngineSettings.DiffuseSamples, 1, 100);
            var glossySamples = new OptionInteger(RcCore.It.EngineSettings.GlossySamples, 1, 100);

            var seed = new OptionInteger(RcCore.It.EngineSettings.Seed, 0, int.MaxValue);

            var sensorWidth  = new OptionDouble(RcCore.It.EngineSettings.SensorWidth, 10.0, 100.0);
            var sensorHeight = new OptionDouble(RcCore.It.EngineSettings.SensorHeight, 10.0, 100.0);

            var transparentMaxBounce = new OptionInteger(RcCore.It.EngineSettings.TransparentMaxBounce, 0, 200);

            var filterGlossy            = new OptionDouble(RcCore.It.EngineSettings.FilterGlossy, 0.0, 100.0);
            var sampleClampDirect       = new OptionDouble(RcCore.It.EngineSettings.SampleClampDirect, 0.0, 100.0);
            var sampleClampIndirect     = new OptionDouble(RcCore.It.EngineSettings.SampleClampIndirect, 0.0, 100.0);
            var lightSamplingThreshold  = new OptionDouble(RcCore.It.EngineSettings.LightSamplingThreshold, 0.0, 1.0);
            var sampleAllLights         = new OptionToggle(RcCore.It.EngineSettings.SampleAllLights, "no", "yes");
            var sampleAllLightsIndirect = new OptionToggle(RcCore.It.EngineSettings.SampleAllLightsIndirect, "no", "yes");

            getNumber.AddOptionToggle("show_max_passes", ref showMaxPasses);
            getNumber.AddOptionInteger("max_bounces", ref maxBounce);
            getNumber.AddOptionInteger("tile_x", ref tileX);
            getNumber.AddOptionInteger("tile_y", ref tileY);
            getNumber.AddOptionToggle("no_caustics", ref noCaustics);

            getNumber.AddOptionInteger("max_diffuse_bounce", ref maxDiffuseBounce);
            getNumber.AddOptionInteger("max_glossy_bounce", ref maxGlossyBounce);
            getNumber.AddOptionInteger("max_transmission_bounce", ref maxTransmissionBounce);
            getNumber.AddOptionInteger("max_volume_bounce", ref maxVolumeBounce);

            getNumber.AddOptionInteger("transparent_max_bounce", ref transparentMaxBounce);

            getNumber.AddOptionInteger("aa_samples", ref aaSamples);
            getNumber.AddOptionInteger("diffuse_samples", ref diffSamples);
            getNumber.AddOptionInteger("glossy_samples", ref glossySamples);

            getNumber.AddOptionDouble("sensor_width", ref sensorWidth);
            getNumber.AddOptionDouble("sensor_height", ref sensorHeight);


            getNumber.AddOptionInteger("seed", ref seed, "Seed to use for sampling distribution");

            getNumber.AddOptionDouble("filter_glossy", ref filterGlossy);
            getNumber.AddOptionDouble("sample_clamp_direct", ref sampleClampDirect);
            getNumber.AddOptionDouble("sample_clamp_indirect", ref sampleClampIndirect);
            getNumber.AddOptionDouble("light_sampling_threshold", ref lightSamplingThreshold);
            getNumber.AddOptionToggle("sample_all_lights", ref sampleAllLights);
            getNumber.AddOptionToggle("sample_all_lights_indirect", ref sampleAllLightsIndirect);

            while (true)
            {
                var getRc = getNumber.Get();
                if (getNumber.CommandResult() != Result.Success)
                {
                    return(getNumber.CommandResult());
                }
                switch (getRc)
                {
                case GetResult.Number:
                    RhinoApp.WriteLine($"We got: {getNumber.Number()}, {maxBounce.CurrentValue}");
                    RcCore.It.EngineSettings.Samples                 = (int)getNumber.Number();
                    RcCore.It.EngineSettings.ShowMaxPasses           = showMaxPasses.CurrentValue;
                    RcCore.It.EngineSettings.Seed                    = seed.CurrentValue;
                    RcCore.It.EngineSettings.MaxBounce               = maxBounce.CurrentValue;
                    RcCore.It.EngineSettings.TileX                   = tileX.CurrentValue;
                    RcCore.It.EngineSettings.TileY                   = tileY.CurrentValue;
                    RcCore.It.EngineSettings.NoCaustics              = noCaustics.CurrentValue;
                    RcCore.It.EngineSettings.MaxDiffuseBounce        = maxDiffuseBounce.CurrentValue;
                    RcCore.It.EngineSettings.MaxGlossyBounce         = maxGlossyBounce.CurrentValue;
                    RcCore.It.EngineSettings.MaxTransmissionBounce   = maxTransmissionBounce.CurrentValue;
                    RcCore.It.EngineSettings.MaxVolumeBounce         = maxVolumeBounce.CurrentValue;
                    RcCore.It.EngineSettings.TransparentMaxBounce    = transparentMaxBounce.CurrentValue;
                    RcCore.It.EngineSettings.AaSamples               = aaSamples.CurrentValue;
                    RcCore.It.EngineSettings.DiffuseSamples          = diffSamples.CurrentValue;
                    RcCore.It.EngineSettings.GlossySamples           = glossySamples.CurrentValue;
                    RcCore.It.EngineSettings.SensorWidth             = (float)sensorWidth.CurrentValue;
                    RcCore.It.EngineSettings.SensorHeight            = (float)sensorHeight.CurrentValue;
                    RcCore.It.EngineSettings.FilterGlossy            = (float)filterGlossy.CurrentValue;
                    RcCore.It.EngineSettings.SampleClampDirect       = (float)sampleClampDirect.CurrentValue;
                    RcCore.It.EngineSettings.SampleClampIndirect     = (float)sampleClampIndirect.CurrentValue;
                    RcCore.It.EngineSettings.LightSamplingThreshold  = (float)lightSamplingThreshold.CurrentValue;
                    RcCore.It.EngineSettings.SampleAllLights         = sampleAllLights.CurrentValue;
                    RcCore.It.EngineSettings.SampleAllLightsIndirect = sampleAllLightsIndirect.CurrentValue;
                    break;

                case GetResult.Option:
                    continue;
                }

                break;
            }
            return(Result.Success);
        }
예제 #23
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            const ObjectType geometryFilter = ObjectType.Mesh;
            
            OptionDouble minEdgeLengthOption = new OptionDouble(minEdgeLength, 0.001, 200);
            OptionInteger maxTriangleCountOption = new OptionInteger(maxTriangleCount, 0, 100000000);
            
            GetObject go = new GetObject();
            go.SetCommandPrompt("Select meshes to reduce");
            go.GeometryFilter = geometryFilter;
            go.AddOptionDouble("MinEdge", ref minEdgeLengthOption);
            go.AddOptionInteger("MaxTriangle", ref maxTriangleCountOption);

            go.GroupSelect = true;
            go.SubObjectSelect = false;
            go.EnableClearObjectsOnEntry(false);
            go.EnableUnselectObjectsOnExit(false);
            go.DeselectAllBeforePostSelect = false;

            bool bHavePreselectedObjects = false;

            for (;;)
            {
                GetResult res = go.GetMultiple(1, 0);

                if (res == GetResult.Option)
                {
                    go.EnablePreSelect(false, true);
                    continue;
                }

                else if (go.CommandResult() != Result.Success)
                    return go.CommandResult();

                if (go.ObjectsWerePreselected)
                {
                    bHavePreselectedObjects = true;
                    go.EnablePreSelect(false, true);
                    continue;
                }

                break;
            }

            maxTriangleCount = maxTriangleCountOption.CurrentValue;
            minEdgeLength = minEdgeLengthOption.CurrentValue;

            if (bHavePreselectedObjects)
            {
                // Normally, pre-selected objects will remain selected, when a
                // command finishes, and post-selected objects will be unselected.
                // This this way of picking, it is possible to have a combination
                // of pre-selected and post-selected. So, to make sure everything
                // "looks the same", lets unselect everything before finishing
                // the command.
                for (int i = 0; i < go.ObjectCount; i++)
                {
                    RhinoObject rhinoObject = go.Object(i).Object();
                    if (null != rhinoObject)
                        rhinoObject.Select(false);
                }
                doc.Views.Redraw();
            }

            bool result = false;

            foreach (var obj in go.Objects())
            {
                var rhinoMesh = obj.Mesh();

                if (rhinoMesh == null || !rhinoMesh.IsValid)
                    continue;

                var mesh = GopherUtil.ConvertToD3Mesh(obj.Mesh());
                
                GopherUtil.ReduceMesh(mesh, (float)minEdgeLength, maxTriangleCount);

                double mine, maxe, avge;
                MeshQueries.EdgeLengthStats(mesh, out mine, out maxe, out avge);
                   RhinoApp.WriteLine("Edge length stats: {0} {1} {2}", mine, maxe, avge);

                var newRhinoMesh = GopherUtil.ConvertToRhinoMesh(mesh);

                if (newRhinoMesh != null && newRhinoMesh.IsValid)
                {
                    doc.Objects.Replace(obj, newRhinoMesh);
                }

                if (newRhinoMesh != null && newRhinoMesh.IsValid)
                {
                    result |= doc.Objects.Replace(obj, newRhinoMesh);
                }
            }

            doc.Views.Redraw();

            return Result.Success;
        }
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            const ObjectType geometryFilter = ObjectType.Mesh;

            OptionDouble  minEdgeLengthOption     = new OptionDouble(minEdgeLength, 0.001, 200);
            OptionDouble  maxEdgeLengthOption     = new OptionDouble(maxEdgeLength, 0.001, 200);
            OptionDouble  constriantAngleOption   = new OptionDouble(constriantAngle, 0.001, 360);
            OptionInteger smoothStepsOptions      = new OptionInteger(smoothSteps, 0, 1000);
            OptionDouble  smoothSpeedOption       = new OptionDouble(smoothSpeed, 0.01, 1.0);
            OptionDouble  projectAmountOption     = new OptionDouble(projectedAmount, 0.01, 1.0);
            OptionDouble  projectedDistanceOption = new OptionDouble(projectedDistance, 0.01, 100000.0);

            GetObject go = new GetObject();

            go.SetCommandPrompt("Select mesh to remesh");
            go.GeometryFilter = geometryFilter;
            go.AddOptionDouble("ConstraintAngle", ref constriantAngleOption);
            go.AddOptionDouble("MinEdge", ref minEdgeLengthOption);
            go.AddOptionDouble("MaxEdge", ref maxEdgeLengthOption);
            go.AddOptionInteger("SmoothSteps", ref smoothStepsOptions);
            go.AddOptionDouble("SmoothSpeed", ref smoothSpeedOption);
            go.AddOptionDouble("ProjectAmount", ref projectAmountOption);
            go.AddOptionDouble("ProjectDistance", ref projectedDistanceOption);

            go.GroupSelect     = true;
            go.SubObjectSelect = false;
            go.EnableClearObjectsOnEntry(false);
            go.EnableUnselectObjectsOnExit(false);
            go.DeselectAllBeforePostSelect = false;

            bool bHavePreselectedObjects = false;

            for (;;)
            {
                GetResult res = go.Get();

                if (res == GetResult.Option)
                {
                    go.EnablePreSelect(false, true);
                    continue;
                }

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

                if (go.ObjectsWerePreselected)
                {
                    bHavePreselectedObjects = true;
                    go.EnablePreSelect(false, true);
                    continue;
                }

                break;
            }

            GetObject goProjected = new GetObject();

            goProjected.EnablePreSelect(false, true);
            goProjected.SetCommandPrompt("Select mesh to project to");
            goProjected.GeometryFilter = geometryFilter;
            goProjected.AddOptionDouble("ConstraintAngle", ref constriantAngleOption);
            goProjected.AddOptionDouble("MinEdge", ref minEdgeLengthOption);
            goProjected.AddOptionDouble("MaxEdge", ref maxEdgeLengthOption);
            goProjected.AddOptionInteger("SmoothSteps", ref smoothStepsOptions);
            goProjected.AddOptionDouble("SmoothSpeed", ref smoothSpeedOption);
            goProjected.AddOptionDouble("ProjectAmount", ref projectAmountOption);
            goProjected.AddOptionDouble("ProjectDistance", ref projectedDistanceOption);

            goProjected.GroupSelect     = true;
            goProjected.SubObjectSelect = false;
            goProjected.EnableClearObjectsOnEntry(false);
            goProjected.EnableUnselectObjectsOnExit(false);


            for (;;)
            {
                GetResult res = goProjected.Get();

                if (res == GetResult.Option)
                {
                    continue;
                }

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

                break;
            }


            minEdgeLength     = minEdgeLengthOption.CurrentValue;
            maxEdgeLength     = maxEdgeLengthOption.CurrentValue;
            constriantAngle   = constriantAngleOption.CurrentValue;
            smoothSteps       = smoothStepsOptions.CurrentValue;
            smoothSpeed       = smoothSpeedOption.CurrentValue;
            projectedAmount   = projectAmountOption.CurrentValue;
            projectedDistance = projectedDistanceOption.CurrentValue;

            if (bHavePreselectedObjects)
            {
                // Normally, pre-selected objects will remain selected, when a
                // command finishes, and post-selected objects will be unselected.
                // This this way of picking, it is possible to have a combination
                // of pre-selected and post-selected. So, to make sure everything
                // "looks the same", lets unselect everything before finishing
                // the command.
                for (int i = 0; i < go.ObjectCount; i++)
                {
                    RhinoObject rhinoObject = go.Object(i).Object();
                    if (null != rhinoObject)
                    {
                        rhinoObject.Select(false);
                    }
                }
                doc.Views.Redraw();
            }

            bool result = false;

            if (goProjected.ObjectCount < 1)
            {
                return(Result.Failure);
            }

            foreach (var obj in go.Objects())
            {
                var rhinoMesh = obj.Mesh();

                if (rhinoMesh == null || !rhinoMesh.IsValid)
                {
                    continue;
                }

                var mesh = GopherUtil.ConvertToD3Mesh(obj.Mesh());


                var rhinoMeshProject = goProjected.Object(0).Mesh();

                if (rhinoMeshProject == null || !rhinoMeshProject.IsValid)
                {
                    continue;
                }

                var meshProjected = GopherUtil.ConvertToD3Mesh(rhinoMeshProject);

                var mesh2 = new DMesh3(mesh);
                var mesh3 = new DMesh3(mesh);

                var res3 = GopherUtil.RemeshMesh(mesh3, (float)minEdgeLength, (float)maxEdgeLength, (float)constriantAngle, (float)smoothSpeed, smoothSteps, meshProjected, (float)projectedAmount, (float)projectedDistance);

                var watch = System.Diagnostics.Stopwatch.StartNew();
                // the code that you want to measure comes here

                var res = GopherUtil.RemeshMesh(mesh, (float)minEdgeLength, (float)maxEdgeLength, (float)constriantAngle, (float)smoothSpeed, smoothSteps, meshProjected, (float)projectedAmount, (float)projectedDistance);

                watch.Stop();

                var watch2 = System.Diagnostics.Stopwatch.StartNew();

                var res2 = GopherUtil.RemeshMeshNew(mesh2, (float)minEdgeLength, (float)maxEdgeLength, (float)constriantAngle, (float)smoothSpeed, smoothSteps, meshProjected, (float)projectedAmount, (float)projectedDistance);

                watch2.Stop();


                Rhino.RhinoApp.WriteLine("Time 1: {0} Time 2: {1}", watch.ElapsedMilliseconds, watch2.ElapsedMilliseconds);

                var newRhinoMesh = GopherUtil.ConvertToRhinoMesh(res);

                var newRhinoMesh2 = GopherUtil.ConvertToRhinoMesh(mesh2);

                newRhinoMesh2.Translate(new Rhino.Geometry.Vector3d(newRhinoMesh2.GetBoundingBox(true).Diagonal.X, 0, 0));

                doc.Objects.Add(newRhinoMesh2);

                if (newRhinoMesh != null && newRhinoMesh.IsValid)
                {
                    doc.Objects.Replace(obj, newRhinoMesh);
                }

                if (newRhinoMesh != null && newRhinoMesh.IsValid)
                {
                    result |= doc.Objects.Replace(obj, newRhinoMesh);
                }
            }

            doc.Views.Redraw();

            return(Result.Success);
        }
예제 #25
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);
        }
예제 #26
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            const ObjectType geometryFilter = ObjectType.MeshEdge;

            OptionDouble  minEdgeLengthOption   = new OptionDouble(minEdgeLength, 0.001, 200);
            OptionDouble  maxEdgeLengthOption   = new OptionDouble(maxEdgeLength, 0.001, 200);
            OptionDouble  constriantAngleOption = new OptionDouble(constriantAngle, 0.001, 360);
            OptionInteger smoothStepsOptions    = new OptionInteger(smoothSteps, 0, 1000);
            OptionDouble  smoothSpeedOption     = new OptionDouble(smoothSpeed, 0.01, 1.0);

            GetObject go = new GetObject();

            go.SetCommandPrompt("Select mesh edges to constrain during remesh");
            go.GeometryFilter = geometryFilter;

            go.AddOptionDouble("ConstraintAngle", ref constriantAngleOption);
            go.AddOptionDouble("MinEdge", ref minEdgeLengthOption);
            go.AddOptionDouble("MaxEdge", ref maxEdgeLengthOption);
            go.AddOptionInteger("SmoothSteps", ref smoothStepsOptions);
            go.AddOptionDouble("SmoothSpeed", ref smoothSpeedOption);

            go.GroupSelect     = true;
            go.SubObjectSelect = true;

            for (;;)
            {
                GetResult res = go.GetMultiple(1, 0);

                if (res == GetResult.Option)
                {
                    go.EnablePreSelect(false, true);
                    continue;
                }

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

                break;
            }

            minEdgeLength   = minEdgeLengthOption.CurrentValue;
            maxEdgeLength   = maxEdgeLengthOption.CurrentValue;
            constriantAngle = constriantAngleOption.CurrentValue;
            smoothSteps     = smoothStepsOptions.CurrentValue;
            smoothSpeed     = smoothSpeedOption.CurrentValue;

            System.Collections.Generic.List <g3.Line3d>   constrain = new System.Collections.Generic.List <g3.Line3d>();
            System.Collections.Generic.List <System.Guid> meshes    = new System.Collections.Generic.List <System.Guid>();

            foreach (var obj in go.Objects())
            {
                if (!meshes.Contains(obj.ObjectId))
                {
                    meshes.Add(obj.ObjectId);
                }

                ObjRef objref = new ObjRef(obj.ObjectId);

                var mesh = objref.Mesh();

                var line = mesh.TopologyEdges.EdgeLine(obj.GeometryComponentIndex.Index);

                var dir = line.Direction;

                constrain.Add(new g3.Line3d(new Vector3d(line.FromX, line.FromY, line.FromZ), new Vector3d(dir.X, dir.Y, dir.Z)));
            }

            foreach (var guid in meshes)
            {
                var objref = new ObjRef(guid);

                var mesh    = GopherUtil.ConvertToD3Mesh(objref.Mesh());
                var res     = GopherUtil.RemeshMesh(mesh, (float)minEdgeLength, (float)maxEdgeLength, (float)constriantAngle, (float)smoothSpeed, smoothSteps, constrain);
                var newMesh = GopherUtil.ConvertToRhinoMesh(res);

                doc.Objects.Replace(objref, newMesh);
            }

            doc.Views.Redraw();

            return(Result.Success);
        }
예제 #27
0
        /// <summary>
        /// RunCommand
        /// </summary>
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            Tolerance = doc.ModelAbsoluteTolerance;

            // Get persistent settings
            var settings = Settings;
            var radius   = settings.GetDouble("Radius", RADIUS);
            var cut_type = settings.GetEnumValue("CutType", CUTTYPE);

            // Select closed,planar curve
            var go = new GetClosedPlanarPolyline(Tolerance);

            go.SetCommandPrompt("Select closed, planar polyline");
            go.Get();
            if (go.CommandResult() != Result.Success)
            {
                return(go.CommandResult());
            }

            // Get curve
            var obj_ref = go.Object(0);
            var curve   = obj_ref.Curve();

            if (null == curve || !curve.IsClosed || !curve.IsPlanar())
            {
                return(Result.Failure);
            }

            // Get polyline
            Polyline polyline;

            if (!curve.TryGetPolyline(out polyline))
            {
                return(Result.Failure);
            }

            // Since first and last point are the same, remove the last point.
            polyline.RemoveAt(polyline.Count - 1);

            // Get curve plane
            Plane plane;

            if (!curve.TryGetPlane(out plane, Tolerance))
            {
                return(Result.Failure);
            }

            // Get corner point indices
            var indices = FindInnerCornerPoints(curve, polyline, plane);

            if (0 == indices.Length)
            {
                RhinoApp.WriteLine("No inner corners found.");
                return(Result.Nothing);
            }

            // Show preview conduit
            var conduit = new SampleCsOverCutConduit
            {
                Circles = CalculateCuttingCircles(curve, polyline, indices, plane, radius, cut_type),
                Enabled = true
            };

            doc.Views.Redraw();

            Result rc;

            // Choose overcut options
            var gp = new GetOption();

            gp.SetCommandPrompt("Choose overcut option");
            gp.AcceptNothing(true);
            for (;;)
            {
                gp.ClearCommandOptions();
                var cut_type_index = gp.AddOptionEnumList("CutType", cut_type);
                var radius_option  = new OptionDouble(radius, true, Tolerance);
                var radius_index   = gp.AddOptionDouble("Radius", ref radius_option);
                var res            = gp.Get();

                if (res == GetResult.Option)
                {
                    var option = gp.Option();
                    if (null != option)
                    {
                        if (option.Index == cut_type_index)
                        {
                            var list = Enum.GetValues(typeof(CutType)).Cast <CutType>().ToList();
                            cut_type = list[option.CurrentListOptionIndex];
                        }
                        else if (option.Index == radius_index)
                        {
                            radius = radius_option.CurrentValue;
                        }

                        conduit.Circles = CalculateCuttingCircles(curve, polyline, indices, plane, radius, cut_type);
                        doc.Views.Redraw();
                    }
                    continue;
                }

                if (res == GetResult.Nothing)
                {
                    rc = Result.Success;
                    break;
                }

                rc = Result.Cancel;
                break;
            }

            conduit.Enabled = false;

            if (rc == Result.Success)
            {
                // Try differencing circles from curve
                var success   = true;
                var new_curve = curve;
                for (var i = 0; i < conduit.Circles.Count && success; i++)
                {
                    var new_curves = Curve.CreateBooleanDifference(new_curve, new ArcCurve(conduit.Circles[i]), doc.ModelAbsoluteTolerance);
                    if (1 == new_curves.Length && null != new_curves[0])
                    {
                        new_curve = new_curves[0];
                    }
                    else
                    {
                        success = false;
                    }
                }

                // Add geometry to document
                if (success && null != new_curve)
                {
                    doc.Objects.Replace(obj_ref, new_curve);
                }
                else
                {
                    for (var i = 0; i < conduit.Circles.Count; i++)
                    {
                        doc.Objects.AddCircle(conduit.Circles[i]);
                    }
                }

                // Set persistent settings
                settings.SetDouble("Radius", radius);
                settings.SetEnumValue("CutType", cut_type);
            }

            doc.Views.Redraw();

            return(rc);
        }
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            try
            {
                using (var go = new GetObject())
                {
                    var wwr = 0.6;
                    wwr = Settings.GetDouble(nameof(wwr), 0.6);
                    var optionWWR = new OptionDouble(wwr, 0.01, 0.98);

                    var optionSkipFaceExistingWindow = new OptionToggle(true, "No_CreateForAllFaces", "Yes");

                    go.SetCommandPrompt("Please select honeybee rooms for adding windows to");
                    go.GeometryFilter  = ObjectType.Brep;
                    go.GroupSelect     = false;
                    go.SubObjectSelect = false;
                    go.EnableClearObjectsOnEntry(false);
                    go.EnableUnselectObjectsOnExit(false);
                    go.DeselectAllBeforePostSelect = false;

                    while (true)
                    {
                        go.ClearCommandOptions();
                        go.AddOptionDouble("WindowWallRatio", ref optionWWR);
                        go.AddOptionToggle("SkipFacesWithWindows", ref optionSkipFaceExistingWindow);
                        var res = go.GetMultiple(1, 0);

                        if (res == Rhino.Input.GetResult.Option)
                        {
                            go.EnablePreSelect(false, true);
                            continue;
                        }
                        else if (res != Rhino.Input.GetResult.Object)
                        {
                            return(Result.Cancel);
                        }

                        if (go.ObjectsWerePreselected)
                        {
                            go.EnablePreSelect(false, true);
                            continue;
                        }

                        break;
                    }

                    if (go.CommandResult() != Result.Success)
                    {
                        throw new ArgumentException("Failed to execute command!");
                    }

                    if (go.ObjectCount == 0)
                    {
                        throw new ArgumentException("No object is selected!");
                    }

                    //get option values
                    Settings.SetDouble(nameof(wwr), optionWWR.CurrentValue);
                    var ifSkipFaceWithWindow = optionSkipFaceExistingWindow.CurrentValue;

                    //all selected room geometries
                    var solidBreps = go.Objects().Where(_ => _.Brep() != null).Where(_ => _.Brep().IsSolid);
                    var rooms      = solidBreps.Where(_ => _.IsRoom()).ToList();
                    if (solidBreps.Count() != rooms.Count())
                    {
                        doc.Objects.UnselectAll();
                        var nonRooms = solidBreps.Where(_ => !_.Brep().IsRoom());
                        foreach (var item in nonRooms)
                        {
                            doc.Objects.Select(item, true, true);
                        }

                        doc.Views.Redraw();
                        Rhino.UI.Dialogs.ShowMessage("These are not Honeybee rooms, please use MassToRoom to convert them first!", "Honeybee Rhino Plugin");
                        return(Result.Failure);
                    }


                    //Add Windows
                    AddApertureByWWR(doc, rooms, optionWWR.CurrentValue, ifSkipFaceWithWindow);

                    doc.Views.Redraw();
                    return(Result.Success);
                }
            }
            catch (Exception e)
            {
                RhinoApp.WriteLine($"ERROR: {e.Message}");
                return(Result.Failure);
            }
        }