///<summary> This gets called when when the user runs this command.</summary>
        public override IRhinoCommand.result RunCommand(IRhinoCommandContext context)
        {
            // Select a curve object
            MRhinoGetObject go = new MRhinoGetObject();

            go.SetCommandPrompt("Select curve");
            go.SetGeometryFilter(IRhinoGetObject.GEOMETRY_TYPE_FILTER.curve_object);
            go.GetObjects(1, 1);
            if (go.CommandResult() != IRhinoCommand.result.success)
            {
                return(go.CommandResult());
            }

            // Validate the selection
            IRhinoObject obj = go.Object(0).Object();

            if (null == obj)
            {
                return(IRhinoCommand.result.failure);
            }

            // Get the active view
            MRhinoView view = RhUtil.RhinoApp().ActiveView();

            if (null == view)
            {
                return(IRhinoCommand.result.failure);
            }

            // Get the construction plane from the active view
            OnPlane plane = new OnPlane(view.ActiveViewport().ConstructionPlane().m_plane);

            // Create a construction plane aligned bounding box
            OnBoundingBox bbox = new OnBoundingBox();

            IRhinoObject[] objs = new IRhinoObject[1] {
                obj
            };
            bool rc = RhUtil.RhinoGetTightBoundingBox(objs, ref bbox, false, plane);

            if (rc == false)
            {
                return(IRhinoCommand.result.failure);
            }

            // Validate bounding box
            if (0 != bbox.IsDegenerate())
            {
                RhUtil.RhinoApp().Print("Curve's tight bounding box is degenerate.\n");
                return(IRhinoCommand.result.nothing);
            }

            // ON_BrepBox wants 8 points defining the box corners
            // arranged in this order:
            //
            //          v7______________v6
            //           |\             |\
            //           | \            | \
            //           |  \ _____________\ 
            //           |   v4         |   v5
            //           |   |          |   |
            //           |   |          |   |
            //          v3---|---------v2   |
            //           \   |          \   |
            //            \  |           \  |
            //             \ |            \ |
            //              \v0____________\v1
            //
            On3dPoint[] box_corners = new On3dPoint[8];
            box_corners[0] = bbox.Corner(0, 0, 0);
            box_corners[1] = bbox.Corner(1, 0, 0);
            box_corners[2] = bbox.Corner(1, 1, 0);
            box_corners[3] = bbox.Corner(0, 1, 0);
            box_corners[4] = bbox.Corner(0, 0, 1);
            box_corners[5] = bbox.Corner(1, 0, 1);
            box_corners[6] = bbox.Corner(1, 1, 1);
            box_corners[7] = bbox.Corner(0, 1, 1);

            // Transform points to the world-xy plane
            OnXform p2w = new OnXform();

            p2w.ChangeBasis(plane, OnUtil.On_xy_plane);
            for (int i = 0; i < 8; i++)
            {
                box_corners[i].Transform(p2w);
            }

            // Make a brep box
            OnBrep brep = OnUtil.ON_BrepBox(box_corners);

            if (null != brep)
            {
                context.m_doc.AddBrepObject(brep);
                context.m_doc.Redraw();
            }

            return(IRhinoCommand.result.success);
        }
        /// <summary>
        /// The one and only MakeBox
        /// </summary>
        static OnBrep MakeBox()
        {
            /*
             * This example demonstrates how to construct a OnBrep
             * with the topology shown below.
             *
             * v7_______e6_____v6
             |\             |\
             | e7           | e5
             |  \ ______e4_____\
             | e11  v4         |   v5
             |   |        e10   |
             |   |          |   |
             | v3---|---e2----v2   e9
             \   e8         \   |
             \ e3 |           e1 |
             \ |            \ |
             \  \v0_____e0_____\v1
             \
             */

            On3dPoint[] points = new On3dPoint[8];
            points[0] = new On3dPoint(0.0, 0.0, 0.0);
            points[1] = new On3dPoint(10.0, 0.0, 0.0);
            points[2] = new On3dPoint(10.0, 10.0, 0.0);
            points[3] = new On3dPoint(0.0, 10.0, 0.0);
            points[4] = new On3dPoint(0.0, 0.0, 10.0);
            points[5] = new On3dPoint(10.0, 0.0, 10.0);
            points[6] = new On3dPoint(10.0, 10.0, 10.0);
            points[7] = new On3dPoint(0.0, 10.0, 10.0);

            OnBrep brep = new OnBrep();

            int vi = 0, ei = 0, fi = 0, si = 0, c2i = 0;

            for (vi = 0; vi < 8; vi++)
            {
                brep.NewVertex(points[vi], 0.0);
            }

            for (ei = 0; ei < 4; ei++)
            {
                OnBrepVertex v0 = brep.m_V[ei];
                OnBrepVertex v1 = brep.m_V[(ei + 1) % 4];
                brep.m_C3.Append(new OnLineCurve(v0.point, v1.point));
                brep.NewEdge(ref v0, ref v1, ei, null, 0.0);
            }
            for (ei = 4; ei < 8; ei++)
            {
                OnBrepVertex v0 = brep.m_V[ei];
                OnBrepVertex v1 = brep.m_V[ei == 7 ? 4 : (ei + 1)];
                brep.m_C3.Append(new OnLineCurve(v0.point, v1.point));
                brep.NewEdge(ref v0, ref v1, ei, null, 0.0);
            }
            for (ei = 8; ei < 12; ei++)
            {
                OnBrepVertex v0 = brep.m_V[ei - 8];
                OnBrepVertex v1 = brep.m_V[ei - 4];
                brep.m_C3.Append(new OnLineCurve(v0.point, v1.point));
                brep.NewEdge(ref v0, ref v1, ei, null, 0.0);
            }

            OnBrepBoxFaceInfo[] f = new OnBrepBoxFaceInfo[6];
            f[0] = new OnBrepBoxFaceInfo(0, 9, 4, 8, false, false, true, true);
            f[1] = new OnBrepBoxFaceInfo(1, 10, 5, 9, false, false, true, true);
            f[2] = new OnBrepBoxFaceInfo(2, 11, 6, 10, false, false, true, true);
            f[3] = new OnBrepBoxFaceInfo(3, 8, 7, 11, false, false, true, true);
            f[4] = new OnBrepBoxFaceInfo(3, 2, 1, 0, true, true, true, true);
            f[5] = new OnBrepBoxFaceInfo(4, 5, 6, 7, false, false, false, false);

            for (fi = 0; fi < 6; fi++)
            {
                OnBrepEdge   e0 = brep.m_E[f[fi].e[0]];
                OnBrepEdge   e1 = brep.m_E[f[fi].e[1]];
                OnBrepEdge   e2 = brep.m_E[f[fi].e[2]];
                OnBrepEdge   e3 = brep.m_E[f[fi].e[3]];
                OnBrepVertex v0 = brep.m_V[e0.get_m_vi(f[fi].bRev[0] ? 1 : 0)];
                OnBrepVertex v1 = brep.m_V[e1.get_m_vi(f[fi].bRev[1] ? 1 : 0)];
                OnBrepVertex v2 = brep.m_V[e2.get_m_vi(f[fi].bRev[2] ? 1 : 0)];
                OnBrepVertex v3 = brep.m_V[e3.get_m_vi(f[fi].bRev[3] ? 1 : 0)];

                si = brep.AddSurface(OnUtil.ON_NurbsSurfaceQuadrilateral(v0.point, v1.point, v2.point, v3.point));
                OnInterval s  = brep.m_S[si].Domain(0);
                OnInterval t  = brep.m_S[si].Domain(1);
                On2dPoint  p0 = new On2dPoint(s[0], t[0]);
                On2dPoint  p1 = new On2dPoint(s[1], t[0]);
                On2dPoint  p2 = new On2dPoint(s[1], t[1]);
                On2dPoint  p3 = new On2dPoint(s[0], t[1]);

                OnBrepFace face = brep.NewFace(si);
                OnBrepLoop loop = brep.NewLoop(IOnBrepLoop.TYPE.outer, ref face);

                loop.m_pbox.m_min.x = s[0];
                loop.m_pbox.m_min.y = t[0];
                loop.m_pbox.m_min.z = 0.0;

                loop.m_pbox.m_max.x = s[1];
                loop.m_pbox.m_max.y = t[1];
                loop.m_pbox.m_max.z = 0.0;

                // south side of surface
                c2i = brep.AddTrimCurve(new OnLineCurve(p0, p1));
                OnBrepTrim trim0 = brep.NewTrim(ref e0, f[fi].bRev[0], ref loop, c2i);
                trim0.set_m_tolerance(0, 0.0);
                trim0.set_m_tolerance(1, 0.0);
                trim0.m_type = (trim0.get_m_vi(0) != trim0.get_m_vi(1)) ? IOnBrepTrim.TYPE.mated : IOnBrepTrim.TYPE.singular;
                trim0.m_iso  = IOnSurface.ISO.S_iso;

                // east side of surface
                c2i = brep.AddTrimCurve(new OnLineCurve(p1, p2));
                OnBrepTrim trim1 = brep.NewTrim(ref e1, f[fi].bRev[1], ref loop, c2i);
                trim1.set_m_tolerance(0, 0.0);
                trim1.set_m_tolerance(1, 0.0);
                trim1.m_type = (trim1.get_m_vi(0) != trim1.get_m_vi(1)) ? IOnBrepTrim.TYPE.mated : IOnBrepTrim.TYPE.singular;
                trim1.m_iso  = IOnSurface.ISO.E_iso;

                // north side of surface
                c2i = brep.AddTrimCurve(new OnLineCurve(p2, p3));
                OnBrepTrim trim2 = brep.NewTrim(ref e2, f[fi].bRev[2], ref loop, c2i);
                trim2.set_m_tolerance(0, 0.0);
                trim2.set_m_tolerance(1, 0.0);
                trim2.m_type = (trim2.get_m_vi(0) != trim2.get_m_vi(1)) ? IOnBrepTrim.TYPE.mated : IOnBrepTrim.TYPE.singular;
                trim2.m_iso  = IOnSurface.ISO.N_iso;

                // west side of surface
                c2i = brep.AddTrimCurve(new OnLineCurve(p3, p0));
                OnBrepTrim trim3 = brep.NewTrim(ref e3, f[fi].bRev[3], ref loop, c2i);
                trim3.set_m_tolerance(0, 0.0);
                trim3.set_m_tolerance(1, 0.0);
                trim3.m_type = (trim3.get_m_vi(0) != trim3.get_m_vi(1)) ? IOnBrepTrim.TYPE.mated : IOnBrepTrim.TYPE.singular;
                trim3.m_iso  = IOnSurface.ISO.W_iso;
            }

            if (!brep.IsValid())
            {
                return(null);
            }

            return(brep);
        }