#
tokens: 30209/50000 2/82 files (page 5/7)
lines: off (toggle) GitHub
raw markdown copy
This is page 5 of 7. Use http://codebase.md/jingcheng-chen/rhinomcp?lines=false&page={x} to view the full context.

# Directory Structure

```
├── .github
│   └── workflows
│       ├── mcp-server-publish.yml
│       └── rhino-plugin-publish.yml
├── .gitignore
├── assets
│   ├── claude_enable_instruction.jpg
│   ├── cursor_enable_instruction.jpg
│   ├── cursor_usage_instruction.jpg
│   ├── demo1.jpg
│   ├── demo2.jpg
│   ├── rhino_plugin_instruction.jpg
│   └── rhinomcp_logo.svg
├── demo_chats
│   ├── create_6x6x6_boxes.txt
│   └── create_rhinoceros_lego_blocks.txt
├── LICENSE
├── README.md
├── rhino_mcp_plugin
│   ├── .gitignore
│   ├── Commands
│   │   ├── MCPStartCommand.cs
│   │   ├── MCPStopCommand.cs
│   │   └── MCPVersionCommand.cs
│   ├── EmbeddedResources
│   │   └── plugin-utility.ico
│   ├── Functions
│   │   ├── _utils.cs
│   │   ├── CreateLayer.cs
│   │   ├── CreateObject.cs
│   │   ├── CreateObjects.cs
│   │   ├── DeleteLayer.cs
│   │   ├── DeleteObject.cs
│   │   ├── ExecuteRhinoscript.cs
│   │   ├── GetDocumentInfo.cs
│   │   ├── GetObjectInfo.cs
│   │   ├── GetOrSetCurrentLayer.cs
│   │   ├── GetSelectedObjectsInfo.cs
│   │   ├── ModifyObject.cs
│   │   ├── ModifyObjects.cs
│   │   └── SelectObjects.cs
│   ├── manifest.yml
│   ├── Properties
│   │   ├── AssemblyInfo.cs
│   │   └── launchSettings.json
│   ├── rhinomcp.csproj
│   ├── rhinomcp.sln
│   ├── RhinoMCPPlugin.cs
│   ├── RhinoMCPServer.cs
│   ├── RhinoMCPServerController.cs
│   └── Serializers
│       └── Serializer.cs
└── rhino_mcp_server
    ├── .gitignore
    ├── dev.sh
    ├── main.py
    ├── pyproject.toml
    ├── README.md
    ├── src
    │   └── rhinomcp
    │       ├── __init__.py
    │       ├── prompts
    │       │   └── assert_general_strategy.py
    │       ├── server.py
    │       ├── static
    │       │   └── rhinoscriptsyntax.py
    │       └── tools
    │           ├── create_layer.py
    │           ├── create_object.py
    │           ├── create_objects.py
    │           ├── delete_layer.py
    │           ├── delete_object.py
    │           ├── execute_rhinoscript_python_code.py
    │           ├── get_document_info.py
    │           ├── get_object_info.py
    │           ├── get_or_set_current_layer.py
    │           ├── get_rhinoscript_python_code_guide.py
    │           ├── get_rhinoscript_python_function_names.py
    │           ├── get_selected_objects_info.py
    │           ├── modify_object.py
    │           ├── modify_objects.py
    │           └── select_objects.py
    ├── static
    │   ├── application.py
    │   ├── block.py
    │   ├── compat.py
    │   ├── curve.py
    │   ├── dimension.py
    │   ├── document.py
    │   ├── geometry.py
    │   ├── grips.py
    │   ├── group.py
    │   ├── hatch.py
    │   ├── layer.py
    │   ├── light.py
    │   ├── line.py
    │   ├── linetype.py
    │   ├── material.py
    │   ├── mesh.py
    │   ├── object.py
    │   ├── plane.py
    │   ├── pointvector.py
    │   ├── selection.py
    │   ├── surface.py
    │   ├── toolbar.py
    │   ├── transformation.py
    │   ├── userdata.py
    │   ├── userinterface.py
    │   ├── utility.py
    │   └── view.py
    └── uv.lock
```

# Files

--------------------------------------------------------------------------------
/rhino_mcp_server/static/view.py:
--------------------------------------------------------------------------------

```python
import math

import System

import Rhino

import scriptcontext

from rhinoscript import utility as rhutil


def __viewhelper(view):
    if view is None: return scriptcontext.doc.Views.ActiveView
    allviews = scriptcontext.doc.Views.GetViewList(True, True)
    view_id = rhutil.coerceguid(view, False)
    for item in allviews:
        if view_id:
            if item.MainViewport.Id == view_id: return item
        elif item.MainViewport.Name == view:
            return item
    raise ValueError("unable to coerce %s into a view"%view)


def AddDetail(layout_id, corner1, corner2, title=None, projection=1):
    """Add new detail view to an existing layout view
    Parameters:
      layout_id (guid): identifier of an existing layout
      corner1, corner2 (point): 2d corners of the detail in the layout's unit system
      title (str, optional): title of the new detail
      projection (number, optional): type of initial view projection for the detail
          1 = parallel top view
          2 = parallel bottom view
          3 = parallel left view
          4 = parallel right view
          5 = parallel front view
          6 = parallel back view
          7 = perspective view
    Returns:
      guid: identifier of the newly created detail on success
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      layout = rs.AddLayout("Portrait", (8.5,11))
      if layout:
          rs.AddDetail(layout, (0.5,0.5), (8,10.5), None, 7)
    See Also:
      DeleteNamedView
      NamedViews
      RestoreNamedView
    """
    layout_id = rhutil.coerceguid(layout_id, True)
    corner1 = rhutil.coerce2dpoint(corner1, True)
    corner2 = rhutil.coerce2dpoint(corner2, True)
    if projection<1 or projection>7: raise ValueError("projection must be a value between 1-7")
    layout = scriptcontext.doc.Views.Find(layout_id)
    if not layout: raise ValueError("no layout found for given layout_id")
    projection = System.Enum.ToObject(Rhino.Display.DefinedViewportProjection, projection)
    detail = layout.AddDetailView(title, corner1, corner2, projection)
    if not detail: return scriptcontext.errorhandler()
    scriptcontext.doc.Views.Redraw()
    return detail.Id


def AddLayout(title=None, size=None):
    """Adds a new page layout view
    Parameters:
      title (str, optional): title of new layout
      size ([number, number], optional): width and height of paper for the new layout
    Returns:
      guid: id of new layout
    Example:
      import rhinoscriptsyntax as rs
      rs.AddLayout("Portrait")
    See Also:
      DeleteNamedView
      NamedViews
      RestoreNamedView
    """
    page = None
    if size is None: page = scriptcontext.doc.Views.AddPageView(title)
    else: page = scriptcontext.doc.Views.AddPageView(title, size[0], size[1])
    if page: return page.MainViewport.Id


def AddNamedCPlane(cplane_name, view=None):
    """Adds new named construction plane to the document
    Parameters:
      cplane_name (str): the name of the new named construction plane
      view (guid|str): Title or identifier of the view from which to save
               the construction plane. If omitted, the current active view is used.
    Returns:
      atr: name of the newly created construction plane if successful
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      views = rs.ViewNames()
      if views:
          for view in views:
              name = view + "_cplane"
              rs.AddNamedCPlane( name, view )
    See Also:
      DeleteNamedCPlane
      NamedCPlane
      NamedCPlanes
      RestoreNamedCPlane
    """
    view = __viewhelper(view)
    if not cplane_name: raise ValueError("cplane_name is empty")
    plane = view.MainViewport.ConstructionPlane()
    index = scriptcontext.doc.NamedConstructionPlanes.Add(cplane_name, plane)
    if index<0: return scriptcontext.errorhandler()
    return cplane_name


def AddNamedView(name, view=None):
    """Adds a new named view to the document
    Parameters:
      name (str): the name of the new named view
      view: (guid|str): the title or identifier of the view to save. If omitted, the current
            active view is saved
    Returns:
      str: name fo the newly created named view if successful
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      views = rs.ViewNames()
      if views:
          for view in views:
              name = view + "_view"
              rs.AddNamedView( name, view )
    See Also:
      DeleteNamedView
      NamedViews
      RestoreNamedView
    """
    view = __viewhelper(view)
    if not name: raise ValueError("name is empty")
    viewportId = view.MainViewport.Id
    index = scriptcontext.doc.NamedViews.Add(name, viewportId)
    if index<0: return scriptcontext.errorhandler()
    return name


def CurrentDetail(layout, detail=None, return_name=True):
    """Returns or changes the current detail view in a page layout view
    Parameters:
      layout (str|guid): title or identifier of an existing page layout view
      detail (str|guid, optional): title or identifier the the detail view to set
      return_name (bool, optional): return title if True, else return identifier
    Returns:
      str: if detail is not specified, the title or id of the current detail view
      str: if detail is specified, the title or id of the previous detail view
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      layout = rs.CurrentView(return_name=False)
      if rs.IsLayout(layout):
          rs.CurrentDetail( layout, layout )
    See Also:
      IsDetail
      IsLayout
    """
    layout_id = rhutil.coerceguid(layout)
    page = None
    if layout_id is None: page = scriptcontext.doc.Views.Find(layout, False)
    else: page = scriptcontext.doc.Views.Find(layout_id)
    if page is None: return scriptcontext.errorhandler()
    rc = None
    active_viewport = page.ActiveViewport
    if return_name: rc = active_viewport.Name
    else: rc = active_viewport.Id
    if detail:
        id = rhutil.coerceguid(detail)
        if( (id and id==page.MainViewport.Id) or (id is None and detail==page.MainViewport.Name) ):
            page.SetPageAsActive()
        else:
            if id: page.SetActiveDetail(id)
            else: page.SetActiveDetail(detail, False)
    scriptcontext.doc.Views.Redraw()
    return rc


def CurrentView(view=None, return_name=True):
    """Returns or sets the currently active view
    Parameters:
      view (str|guid): Title or id of the view to set current.
        If omitted, only the title or identifier of the current view is returned
      return_name (bool, optional): If True, then the name, or title, of the view is returned.
        If False, then the identifier of the view is returned
    Returns:
      str: if the title is not specified, the title or id of the current view
      str: if the title is specified, the title or id of the previous current view
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      previous = rs.CurrentView("Perspective")
      print("The previous current view was {}".format(previous))
      viewId = rs.CurrentView( return_name=False )
      print("The identifier of the current view is {}".format(viewId))
    See Also:
      IsViewCurrent
      ViewNames
    """
    rc = None
    if return_name: rc = scriptcontext.doc.Views.ActiveView.MainViewport.Name
    else: rc = scriptcontext.doc.Views.ActiveView.MainViewport.Id
    if view:
        id = rhutil.coerceguid(view)
        rhview = None
        if id: rhview = scriptcontext.doc.Views.Find(id)
        else: rhview = scriptcontext.doc.Views.Find(view, False)
        if rhview is None: return scriptcontext.errorhandler()
        scriptcontext.doc.Views.ActiveView = rhview
    return rc


def DeleteNamedCPlane(name):
    """Removes a named construction plane from the document
    Parameters:
      name (str): name of the construction plane to remove
    Returns:
      bool: True or False indicating success or failure
    Example:
      import rhinoscriptsyntax as rs
      cplanes = rs.NamedCplanes()
      if cplanes:
          for cplane in cplanes: rs.DeleteNamedCPlane(cplane)
    See Also:
      AddNamedCPlane
      NamedCPlane
      NamedCPlanes
      RestoreNamedCPlane
    """
    return scriptcontext.doc.NamedConstructionPlanes.Delete(name)


def DeleteNamedView(name):
    """Removes a named view from the document
    Parameters:
      name (str): name of the named view to remove
    Returns:
      bool: True or False indicating success or failure
    Example:
      import rhinoscriptsyntax as rs
      views = rs.NamedViews()
      if views:
          for view in views: rs.DeleteNamedView(view)
    See Also:
      AddNamedView
      NamedViews
      RestoreNamedView
    """
    return scriptcontext.doc.NamedViews.Delete(name)


def DetailLock(detail_id, lock=None):
    """Returns or modifies the projection locked state of a detail
    Parameters:
      detail_id (guid): identifier of a detail object
      lock (bool, optional) the new lock state
    Returns:
      bool: if lock==None, the current detail projection locked state
      bool: if lock is True or False, the previous detail projection locked state
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      detail = rs.GetObject("select a detail", rs.filter.detail)
      if detail: rs.DetailLock(detail,True)
    See Also:
      IsDetail
      IsLayout
    """
    detail_id = rhutil.coerceguid(detail_id, True)
    detail = scriptcontext.doc.Objects.Find(detail_id)
    if not detail: return scriptcontext.errorhandler()
    rc = detail.DetailGeometry.IsProjectionLocked
    if lock is not None and lock!=rc:
        detail.DetailGeometry.IsProjectionLocked = lock
        detail.CommitChanges()
    return rc


def DetailScale(detail_id, model_length=None, page_length=None):
    """Returns or modifies the scale of a detail object
    Parameters:
      detail_id (guid): identifier of a detail object
      model_length (number, optional): a length in the current model units
      page_length (number, optional): a length in the current page units
    Returns:
      number: current page to model scale ratio if model_length and page_length are both None
      number: previous page to model scale ratio if model_length and page_length are values
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      detail = rs.GetObject("select a detail", rs.filter.detail)
      if detail: rs.DetailScale(detail,1,1)
    See Also:
      IsDetail
      IsLayout
    """
    detail_id = rhutil.coerceguid(detail_id, True)
    detail = scriptcontext.doc.Objects.Find(detail_id)
    if detail is None: return scriptcontext.errorhandler()
    rc = detail.DetailGeometry.PageToModelRatio
    if model_length or page_length:
        if model_length is None or page_length is None:
            return scriptcontext.errorhandler()
        model_units = scriptcontext.doc.ModelUnitSystem
        page_units = scriptcontext.doc.PageUnitSystem
        if detail.DetailGeometry.SetScale(model_length, model_units, page_length, page_units):
            detail.CommitChanges()
            scriptcontext.doc.Views.Redraw()
    return rc


def IsDetail(layout, detail):
    """Verifies that a detail view exists on a page layout view
    Parameters:
      layout (str|guid): title or identifier of an existing page layout
      detail (str|guid): title or identifier of an existing detail view
    Returns:
      bool: True if detail is a detail view
      bool: False if detail is not a detail view
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      view = rs.CurrentView()
      if rs.IsLayout(view):
          isdetail = rs.IsDetail(view, "Top")
          if isdetail:
              print("Top is a detail view.")
          else:
              print("Top is not a detail view.")
    See Also:
      IsLayout
      CurrentDetail
    """
    layout_id = rhutil.coerceguid(layout)
    views = scriptcontext.doc.Views.GetViewList(False, True)
    found_layout = None
    for view in views:
        if layout_id:
            if view.MainViewport.Id==layout_id:
                found_layout = view
                break
        elif view.MainViewport.Name==layout:
            found_layout = view
            break
    # if we couldn't find a layout, this is an error
    if found_layout is None: return scriptcontext.errorhandler()
    detail_id = rhutil.coerceguid(detail)
    details = view.GetDetailViews()
    if not details: return False
    for detail_view in details:
        if detail_id:
            if detail_view.Id==detail_id: return True
        else:
            if detail_view.Name==detail: return True
    return False


def IsLayout(layout):
    """Verifies that a view is a page layout view
    Parameters:
      layout (guid|str): title or identifier of an existing page layout view
    Returns:
      bool: True if layout is a page layout view
      bool: False is layout is a standard, model view
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      view = rs.CurrentView()
      if rs.IsLayout(view):
          print("The current view is a page layout view.")
      else:
          print("The current view is standard, model view.")
    See Also:
      IsLayout
      CurrentDetail
    """
    layout_id = rhutil.coerceguid(layout)
    alllayouts = scriptcontext.doc.Views.GetViewList(False, True)
    for layoutview in alllayouts:
        if layout_id:
            if layoutview.MainViewport.Id==layout_id: return True
        elif layoutview.MainViewport.Name==layout: return True
    allmodelviews = scriptcontext.doc.Views.GetViewList(True, False)
    for modelview in allmodelviews:
        if layout_id:
          if modelview.MainViewport.Id==layout_id: return False
        elif modelview.MainViewport.Name==layout: return False
    return scriptcontext.errorhandler()


def IsView(view):
    """Verifies that the specified view exists
    Parameters:
      view (str|guid): title or identifier of the view
    Returns:
      bool: True of False indicating success or failure
    Example:
      import rhinoscriptsyntax as rs
      title = "Perspective"
      result = rs.IsView(title)
      if result:
          print("The {} view exists.".format(title))
      else:
          print("The {} view does not exist.".format(title))
    See Also:
      ViewNames
    """
    view_id = rhutil.coerceguid(view)
    if view_id is None and view is None: return False
    allviews = scriptcontext.doc.Views.GetViewList(True, True)
    for item in allviews:
        if view_id:
            if item.MainViewport.Id==view_id: return True
        elif item.MainViewport.Name==view: return True
    return False


def IsViewCurrent(view):
    """Verifies that the specified view is the current, or active view
    Parameters:
      view (str|guid): title or identifier of the view
    Returns:
      bool: True of False indicating success or failure
    Example:
      import rhinoscriptsyntax as rs
      title = "Perspective"
      result = rs.IsViewCurrent(title)
      if result:
          print("The {} view is current".format(title))
      else:
          print("The {} view is not current".format(title))
    See Also:
      CurrentView
    """
    activeview = scriptcontext.doc.Views.ActiveView
    view_id = rhutil.coerceguid(view)
    if view_id: return view_id==activeview.MainViewport.Id
    return view==activeview.MainViewport.Name


def IsViewMaximized(view=None):
    """Verifies that the specified view is maximized (enlarged so as to fill
    the entire Rhino window)
    Parameters:
      view: (str|guid): title or identifier of the view. If omitted, the current
            view is used
    Returns:
      bool: True of False
    Example:
      import rhinoscriptsyntax as rs
      title = rs.CurrentView()
      result = rs.IsViewMaximized(title)
      if result:
          print("The {} view is maximized".format(title))
      else:
          print("The {} view is not maximized".format(title))
    See Also:
      MaximizeRestoreView
    """
    view = __viewhelper(view)
    return view.Maximized


def IsViewPerspective(view):
    """Verifies that the specified view's projection is set to perspective
    Parameters:
      view (str|guid): title or identifier of the view
    Returns:
      bool: True of False
    Example:
      import rhinoscriptsyntax as rs
      title = rs.CurrentView()
      result = rs.IsViewPerspective(title)
      if result:
          print("The {} view is set to perspective projection".format(title))
      else:
          print("The {} view is set to parallel projection".format(title))
    See Also:
      ViewProjection
    """
    view = __viewhelper(view)
    return view.MainViewport.IsPerspectiveProjection


def IsViewTitleVisible(view=None):
    """Verifies that the specified view's title window is visible
    Parameters:
      view: (str|guid, optional): The title or identifier of the view. If omitted, the current
            active view is used
    Returns:
      bool: True of False
    Example:
      import rhinoscriptsyntax as rs
      title = rs.CurrentView()
      vis = rs.IsViewTitleVisible(title)
      if vis:
          print("The {} view's title is visible".format(title))
      else:
          print("The {} view's title is not visible".format(title))
    See Also:
      ShowViewTitle
    """
    view = __viewhelper(view)
    return view.MainViewport.TitleVisible


def IsWallpaper(view):
    """Verifies that the specified view contains a wallpaper image
    Parameters:
      view (str|guid): view to verify
    Returns:
      bool: True or False
    Example:
      import rhinoscriptsyntax as rs
      view = rs.CurrentView()
      filename = rs.OpenFileName()
      if filename and not rs.IsWallpaper(view):
          rs.Wallpaper(view, filename)
    See Also:
      Wallpaper
    """
    view = __viewhelper(view)
    return len(view.MainViewport.WallpaperFilename)>0


def MaximizeRestoreView(view=None):
    """Toggles a view's maximized/restore window state of the specified view
    Parameters:
      view: (str|guid, optional): the title or identifier of the view. If omitted, the current
            active view is used
    Returns:
      None
    Example:
      import rhinoscriptsyntax as rs
      title = rs.CurrentView()
      if rs.IsViewMaximized(title):
          rs.MaximizeRestoreView( title )
    See Also:
      IsViewMaximized
    """
    view = __viewhelper(view)
    view.Maximized = not view.Maximized


def NamedCPlane(name):
    """Returns the plane geometry of the specified named construction plane
    Parameters:
      name (str): the name of the construction plane
    Returns:
      plane: a plane on success
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      names = rs.NamedCPlanes()
      if names:
          for name in names:
              plane = rs.NamedCPlane(name)
              print("CPlane name:" + name)
              print("CPlane origin:" + plane.Origin)
              print("CPlane x-axis:" + plane.Xaxis)
              print("CPlane y-axis:" + plane.Yaxis)
              print("CPlane z-axis:" + plane.Zaxis)
    See Also:
      AddNamedCPlane
      DeleteNamedCPlane
      NamedCPlanes
      RestoreNamedCPlane
    """
    index = scriptcontext.doc.NamedConstructionPlanes.Find(name)
    if index<0: return scriptcontext.errorhandler()
    return scriptcontext.doc.NamedConstructionPlanes[index].Plane


def NamedCPlanes():
    """Returns the names of all named construction planes in the document
    Returns:
      list(str, ...): the names of all named construction planes in the document
    Example:
      import rhinoscriptsyntax as rs
      cplanes = rs.NamedCPlanes()
      if cplanes:
          for cplane in cplanes: print(cplane)
    See Also:
      AddNamedCPlane
      DeleteNamedCPlane
      NamedCPlane
      RestoreNamedCPlane
    """
    count = scriptcontext.doc.NamedConstructionPlanes.Count
    rc = [scriptcontext.doc.NamedConstructionPlanes[i].Name for i in range(count)]
    return rc


def NamedViews():
    """Returns the names of all named views in the document
    Returns:
      list(str, ...): the names of all named views in the document
    Example:
      import rhinoscriptsyntax as rs
      views = rs.NamedViews()
      if views:
          for view in views: print(view)
    See Also:
      AddNamedView
      DeleteNamedView
      RestoreNamedView
    """
    count = scriptcontext.doc.NamedViews.Count
    return [scriptcontext.doc.NamedViews[i].Name for i in range(count)]


def RenameView(old_title, new_title):
    """Changes the title of the specified view
    Parameters:
      old_title (str|guid): the title or identifier of the view to rename
      new_title (str): the new title of the view
    Returns:
      str: the view's previous title if successful
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      oldtitle = rs.CurrentView()
      rs.renameview( oldtitle, "Current" )
    See Also:
      ViewNames
    """
    if not old_title or not new_title: return scriptcontext.errorhandler()
    old_id = rhutil.coerceguid(old_title)
    foundview = None
    allviews = scriptcontext.doc.Views.GetViewList(True, True)
    for view in allviews:
        if old_id:
            if view.MainViewport.Id==old_id:
                foundview = view
                break
        elif view.MainViewport.Name==old_title:
            foundview = view
            break
    if foundview is None: return scriptcontext.errorhandler()
    old_title = foundview.MainViewport.Name
    foundview.MainViewport.Name = new_title
    return old_title


def RestoreNamedCPlane(cplane_name, view=None):
    """Restores a named construction plane to the specified view.
    Parameters:
      cplane_name (str): name of the construction plane to restore
      view: (str|guid, optional): the title or identifier of the view. If omitted, the current
            active view is used
    Returns:
      str: name of the restored named construction plane if successful
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      cplanes = rs.NamedCplanes()
      if cplanes: rs.RestoreNamedCPlane( cplanes[0] )
    See Also:
      AddNamedCPlane
      DeleteNamedCPlane
      NamedCPlane
      NamedCPlanes
    """
    view = __viewhelper(view)
    index = scriptcontext.doc.NamedConstructionPlanes.Find(cplane_name)
    if index<0: return scriptcontext.errorhandler()
    cplane = scriptcontext.doc.NamedConstructionPlanes[index]
    view.MainViewport.PushConstructionPlane(cplane)
    view.Redraw()
    return cplane_name


def RestoreNamedView(named_view, view=None, restore_bitmap=False):
    """Restores a named view to the specified view
    Parameters:
      named_view (str): name of the named view to restore
      view (str|guid, optional):  title or id of the view to restore the named view.
           If omitted, the current active view is used
      restore_bitmap: (bool, optional): restore the named view's background bitmap
    Returns:
      str: name of the restored view if successful
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      views = rs.NamedViews()
      if views: rs.RestoreNamedView(views[0])
    See Also:
      AddNamedView
      DeleteNamedView
      NamedViews
    """
    view = __viewhelper(view)
    index = scriptcontext.doc.NamedViews.FindByName(named_view)
    if index<0: return scriptcontext.errorhandler()
    viewinfo = scriptcontext.doc.NamedViews[index]
    if view.MainViewport.PushViewInfo(viewinfo, restore_bitmap):
        view.Redraw()
        return view.MainViewport.Name
    return scriptcontext.errorhandler()


def RotateCamera(view=None, direction=0, angle=None):
    """Rotates a perspective-projection view's camera. See the RotateCamera
    command in the Rhino help file for more details
    Parameters:
      view (str|guid, optional):  title or id of the view. If omitted, current active view is used
      direction(number, optional): the direction to rotate the camera where
        0=right
        1=left
        2=down
        3=up
      angle: (number, optional): the angle to rotate. If omitted, the angle of rotation
            is specified by the "Increment in divisions of a circle" parameter
            specified in Options command's View tab
    Returns:
      bool: True or False indicating success or failure
    Example:
      import rhinoscriptsyntax as rs
      rs.RotateCamera( angle=15 )
    See Also:
      RotateView
      TiltView
    """
    view = __viewhelper(view)
    viewport = view.ActiveViewport
    if angle is None:
        angle = 2.0*math.pi/Rhino.ApplicationSettings.ViewSettings.RotateCircleIncrement
    else:
        angle = Rhino.RhinoMath.ToRadians( abs(angle) )
    target_distance = (viewport.CameraLocation-viewport.CameraTarget)*viewport.CameraZ
    axis = viewport.CameraY
    if direction==0 or direction==2: angle=-angle
    if direction==0 or direction==1:
        if Rhino.ApplicationSettings.ViewSettings.RotateToView:
            axis = viewport.CameraY
        else:
            axis = Rhino.Geometry.Vector3d.ZAxis
    elif direction==2 or direction==3:
        axis = viewport.CameraX
    else:
        return False
    if Rhino.ApplicationSettings.ViewSettings.RotateReverseKeyboard: angle=-angle
    rot = Rhino.Geometry.Transform.Rotation(angle, axis, Rhino.Geometry.Point3d.Origin)
    camUp = rot * viewport.CameraY
    camDir = -(rot * viewport.CameraZ)
    target = viewport.CameraLocation + target_distance*camDir
    viewport.SetCameraLocations(target, viewport.CameraLocation)
    viewport.CameraUp = camUp
    view.Redraw()
    return True


def RotateView(view=None, direction=0, angle=None):
    """Rotates a view. See RotateView command in Rhino help for more information
    Parameters:
      view (str|guid, optional): title or id of the view. If omitted, the current active view is used
      direction (number, optional): the direction to rotate the view where
            0=right
            1=left
            2=down
            3=up
      angle (number): angle to rotate. If omitted, the angle of rotation is specified
            by the "Increment in divisions of a circle" parameter specified in
            Options command's View tab
    Returns:
      bool: True or False indicating success or failure
    Example:
      import rhinoscriptsyntax as rs
      rs.RotateView( angle=90.0 )
    See Also:
      RotateCamera
      TiltView
    """
    view = __viewhelper(view)
    viewport = view.ActiveViewport
    if angle is None:
        angle = 2.0*math.pi/Rhino.ApplicationSettings.ViewSettings.RotateCircleIncrement
    else:
        angle = Rhino.RhinoMath.ToRadians( abs(angle) )
    if Rhino.ApplicationSettings.ViewSettings.RotateReverseKeyboard: angle = -angle
    if direction==0: viewport.KeyboardRotate(True, angle)
    elif direction==1: viewport.KeyboardRotate(True, -angle)
    elif direction==2: viewport.KeyboardRotate(False, -angle)
    elif direction==3: viewport.KeyboardRotate(False, angle)
    else: return False
    view.Redraw()
    return True


def ShowGrid(view=None, show=None):
    """Shows or hides a view's construction plane grid
    Parameters:
      view (str|guid, optional): title or id of the view. If omitted, the current active view is used
      show (bool, optional): The grid state to set. If omitted, the current grid display state is returned
    Returns:
      bool: If show is not specified, then the grid display state if successful
      bool: If show is specified, then the previous grid display state if successful
    Example:
      import rhinoscriptsyntax as rs
      view = rs.CurrentView()
      if rs.ShowGrid(view)==False:
          rs.ShowGrid( view, True )
    See Also:
      ShowGridAxes
      ShowWorldAxes
    """
    view = __viewhelper(view)
    viewport = view.ActiveViewport
    rc = viewport.ConstructionGridVisible
    if show is not None and rc!=show:
        viewport.ConstructionGridVisible = show
        view.Redraw()
    return rc


def ShowGridAxes(view=None, show=None):
    """Shows or hides a view's construction plane grid axes.
    Parameters:
      view (str|guid, optional): title or id of the view. If omitted, the current active view is used
      show (bool, optional): The state to set. If omitted, the current grid axes display state is returned
    Returns:
      bool: If show is not specified, then the grid axes display state
      bool: If show is specified, then the previous grid axes display state
    Example:
      import rhinoscriptsyntax as rs
      view = rs.CurrentView()
      if rs.ShowGridAxes(view)==False:
          rs.ShowGridAxes( view, True )
    See Also:
      ShowGrid
      ShowWorldAxes
    """
    view = __viewhelper(view)
    viewport = view.ActiveViewport
    rc = viewport.ConstructionAxesVisible
    if show is not None and rc!=show:
        viewport.ConstructionAxesVisible = show
        view.Redraw()
    return rc


def ShowViewTitle(view=None, show=True):
    """Shows or hides the title window of a view
    Parameters:
      view (str|guid, optional): title or id of the view. If omitted, the current active view is used
      show (bool, optional): The state to set.
    Returns:
      None
    Example:
      import rhinoscriptsyntax as rs
      view = rs.CurrentView()
      if rs.IsViewTitleVisible(view)==False:
          rs.ShowViewTitle( view, True )
    See Also:
      IsViewTitleVisible
    """
    view = __viewhelper(view)
    if view is None: return scriptcontext.errorhandler()
    view.TitleVisible = show


def ShowWorldAxes(view=None, show=None):
    """Shows or hides a view's world axis icon
    Parameters:
      view (str|guid, optional):  title or id of the view. If omitted, the current active view is used
      show: (bool, optional): The state to set.
    Returns:
      bool: If show is not specified, then the world axes display state
      bool: If show is specified, then the previous world axes display state
    Example:
      import rhinoscriptsyntax as rs
      view = rs.CurrentView()
      if rs.ShowWorldAxes(view)==False:
          rs.ShowWorldAxes( view, True )
    See Also:
      ShowGrid
      ShowGridAxes
    """
    view = __viewhelper(view)
    viewport = view.ActiveViewport
    rc = viewport.WorldAxesVisible
    if show is not None and rc!=show:
        viewport.WorldAxesVisible = show
        view.Redraw()
    return rc


def TiltView(view=None, direction=0, angle=None):
    """Tilts a view by rotating the camera up vector. See the TiltView command in
    the Rhino help file for more details.
    Parameters:
      view (str|guid, optional):  title or id of the view. If omitted, the current active view is used
      direction (number, optional): the direction to rotate the view where
        0=right
        1=left
      angle (number, optional): the angle to rotate. If omitted, the angle of rotation is
        specified by the "Increment in divisions of a circle" parameter specified
        in Options command's View tab
    Returns:
      bool: True or False indicating success or failure
    Example:
      import rhinoscriptsyntax as rs
      rs.TiltView( angle=15 )
    See Also:
      RotateCamera
    """
    view = __viewhelper(view)
    viewport = view.ActiveViewport
    if angle is None:
        angle = 2.0*math.pi/Rhino.ApplicationSettings.ViewSettings.RotateCircleIncrement
    else:
        angle = Rhino.RhinoMath.ToRadians( abs(angle) )
    
    if Rhino.ApplicationSettings.ViewSettings.RotateReverseKeyboard: angle = -angle
    axis = viewport.CameraLocation - viewport.CameraTarget
    if direction==0: viewport.Rotate(angle, axis, viewport.CameraLocation)
    elif direction==1: viewport.Rotate(-angle, axis, viewport.CameraLocation)
    else: return False
    view.Redraw()
    return True


def ViewCamera(view=None, camera_location=None):
    """Returns or sets the camera location of the specified view
    Parameters:
      view (str|guid, optional): title or id of the view. If omitted, the current active view is used
      camera_location (point, optional): a 3D point identifying the new camera location.
        If omitted, the current camera location is returned
    Returns:
      point: If camera_location is not specified, the current camera location
      point: If camera_location is specified, the previous camera location
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      view = rs.CurrentView()
      camera = rs.GetPoint("Select new camera location")
      if camera: rs.ViewCamera(view,camera)
    See Also:
      ViewCameraTarget
      ViewTarget
    """
    view = __viewhelper(view)
    rc = view.ActiveViewport.CameraLocation
    if camera_location is None: return rc
    camera_location = rhutil.coerce3dpoint(camera_location)
    if camera_location is None: return scriptcontext.errorhandler()
    view.ActiveViewport.SetCameraLocation(camera_location, True)
    view.Redraw()
    return rc


def ViewCameraLens(view=None, length=None):
    """Returns or sets the 35mm camera lens length of the specified perspective
    projection view.
    Parameters:
      view (str|guid, optional): title or id of the view. If omitted, the current active view is used
      length (number, optional): the new 35mm camera lens length. If omitted, the previous
        35mm camera lens length is returned
    Returns:
      number: If lens length is not specified, the current lens length
      number: If lens length is specified, the previous lens length
    Example:
      import rhinoscriptsyntax as rs
      view = rs.CurrentView()
      if rs.IsViewPerspective(view):
          length = rs.ViewCameraLens(view, 100)
    See Also:
      ViewCameraTarget
      ViewCPlane
      ViewDisplayModes
      ViewProjection
      ViewSize
    """
    view = __viewhelper(view)
    rc = view.ActiveViewport.Camera35mmLensLength
    if not length: return rc
    view.ActiveViewport.Camera35mmLensLength = length
    view.Redraw()
    return rc


def ViewCameraPlane(view=None):
    """Returns the orientation of a view's camera.
    Parameters:
      view (str|guid, optional): title or id of the view. If omitted, the current active view is used
    Returns:
      plane: the view's camera plane if successful
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      view = rs.CurrentView()
      target = rs.ViewTarget(view)
      camplane = rs.ViewCameraPlane(view)
      plane = rs.MovePlane(camplane, target)
      rs.ViewCPlane( view, plane )
    See Also:
      ViewCamera
      ViewTarget
    """
    view = __viewhelper(view)
    rc, frame = view.ActiveViewport.GetCameraFrame()
    if not rc: return scriptcontext.errorhandler()
    return frame


def ViewCameraTarget(view=None, camera=None, target=None):
    """Returns or sets the camera and target positions of the specified view
    Parameters:
      view (str|guid, optional): title or id of the view. If omitted, current active view is used
      camera (point): 3d point identifying the new camera location. If camera and
         target are not specified, current camera and target locations are returned
      target (point): 3d point identifying the new target location. If camera and
         target are not specified, current camera and target locations are returned
    Returns:
      list(point, point): if both camera and target are not specified, then the 3d points containing
        the current camera and target locations is returned
      point: if either camera or target are specified, then the 3d points containing the
        previous camera and target locations is returned
    Example:
      import rhinoscriptsyntax as rs
      view = rs.CurrentView()
      camera = rs.GetPoint("Select new camera location")
      target = rs.GetPoint("Select new target location")
      if camera and target:
          rs.ViewCameraTarget( view, camera, target )
    See Also:
      ViewCamera
      ViewTarget
    """
    view = __viewhelper(view)
    rc = view.ActiveViewport.CameraLocation, view.ActiveViewport.CameraTarget
    if not camera and not target: return rc
    if camera: camera = rhutil.coerce3dpoint(camera, True)
    if target: target = rhutil.coerce3dpoint(target, True)
    if camera and target: view.ActiveViewport.SetCameraLocations(target, camera)
    elif camera is None: view.ActiveViewport.SetCameraTarget(target, True)
    else: view.ActiveViewport.SetCameraLocation(camera, True)
    view.Redraw()
    return rc


def ViewCameraUp(view=None, up_vector=None):
    """Returns or sets the camera up direction of a specified
    Parameters:
      view (str|guid, optional): title or id of the view. If omitted, the current active view is used
      up_vector (vector): 3D vector identifying the new camera up direction
    Returns:
      vector: if up_vector is not specified, then the current camera up direction
      vector: if up_vector is specified, then the previous camera up direction
    Example:
      import rhinoscriptsyntax as rs
      view = rs.CurrentView()
      upVector = rs.ViewCameraUp(view)
      print(up_vector)
    See Also:
      ViewCamera
      ViewTarget
    """
    view = __viewhelper(view)
    rc = view.ActiveViewport.CameraUp
    if up_vector:
        view.ActiveViewport.CameraUp = rhutil.coerce3dvector(up_vector, True)
        view.Redraw()
    return rc


def ViewCPlane(view=None, plane=None):
    """Return or set a view's construction plane
    Parameters:
      view (str|guid, optional): title or id of the view. If omitted, current active view is used.
      plane (plane): the new construction plane if setting
    Returns:
      plane: If a construction plane is not specified, the current construction plane
      plane: If a construction plane is specified, the previous construction plane
    Example:
      import rhinoscriptsyntax as rs
      origin = rs.GetPoint("CPlane origin")
      if origin:
          plane = rs.ViewCPlane()
          plane = rs.MovePlane(plane,origin)
          rs.ViewCPlane(None, plane)
    See Also:
      ViewCameraLens
      ViewCameraTarget
      ViewDisplayModes
      ViewProjection
      ViewSize
    """
    view = __viewhelper(view)
    cplane = view.ActiveViewport.ConstructionPlane()
    if plane:
        plane = rhutil.coerceplane(plane, True)
        view.ActiveViewport.SetConstructionPlane(plane)
        view.Redraw()
    return cplane


def ViewDisplayMode(view=None, mode=None, return_name=True):
    """Return or set a view display mode
    Parameters:
      view (str|guid, optional): Title or id of a view. If omitted, active view is used
      mode (str|guid, optional): Name or id of a display mode
      return_name (bool, optional): If true, return display mode name. If False, display mode id
    Returns:
      str: If mode is specified, the previous mode
      str: If mode is not specified, the current mode
    Example:
      import rhinoscriptsyntax as rs
      views = rs.ViewNames()
      for view in views:
          rs.ViewDisplayMode(view, 'Ghosted')
    See Also:
      CurrentView
      ViewNames
    """
    view = __viewhelper(view)
    current = view.ActiveViewport.DisplayMode
    if return_name: rc = current.EnglishName
    else: rc = current.Id
    if mode:
        mode_id = rhutil.coerceguid(mode)
        if mode_id:
            desc = Rhino.Display.DisplayModeDescription.GetDisplayMode(mode_id)
        else:
            desc = Rhino.Display.DisplayModeDescription.FindByName(mode)
        if desc: view.ActiveViewport.DisplayMode = desc
        scriptcontext.doc.Views.Redraw()
    return rc


def ViewDisplayModeId(name):
    """Return id of a display mode given it's name
    Parameters:
      name (str): name of the display mode
    Returns:
      guid: The id of the display mode if successful, otherwise None
    Example:
      import rhinoscriptsyntax as rs
      modes = rs.ViewDisplayModes(True)
      for mode in modes: print("{} = {}".format(mode, rs.ViewDisplayModeId(mode)))
    See Also:
      ViewDisplayMode
      ViewDisplayModes
    """
    desc = Rhino.Display.DisplayModeDescription.FindByName(name)
    if desc: return desc.Id


def ViewDisplayModeName(mode_id):
    """Return name of a display mode given it's id
    Parameters:
      mode_id (guid): The identifier of the display mode obtained from the ViewDisplayModes method.
    Returns:
      str: The name of the display mode if successful, otherwise None
    Example:
      import rhinoscriptsyntax as rs
      modes = rs.ViewDisplayModes(False)
      for mode in modes: print("{} = {}".format(mode, rs.ViewDisplayModeName(mode)))
    See Also:
      ViewDisplayMode
      ViewDisplayModes
    """
    mode_id = rhutil.coerceguid(mode_id, True)
    desc = Rhino.Display.DisplayModeDescription.GetDisplayMode(mode_id)
    if desc: return desc.EnglishName


def ViewDisplayModes(return_names=True):
    """Return list of display modes
    Parameters:
      return_name (bool, otpional): If True, return mode names. If False, return ids
    Returns:
      list(str|guid, ...): strings identifying the display mode names or identifiers if successful
    Example:
      import rhinoscriptsyntax as rs
      modes = rs.ViewDisplayModes(False)
      for mode in modes: print("{} = {}".format(mode, rs.ViewDisplayModeName(mode)))
    See Also:
      ViewDisplayMode
      ViewDisplayModeName
    """
    modes = Rhino.Display.DisplayModeDescription.GetDisplayModes()
    if return_names:
        return [mode.EnglishName for mode in modes]
    return [mode.Id for mode in modes]


def ViewNames(return_names=True, view_type=0):
    """Return the names, titles, or identifiers of all views in the document
    Parameters:
      return_names (bool, optional): if True then the names of the views are returned.
        If False, then the identifiers of the views are returned
      view_type: (number, optional): the type of view to return
                       0 = standard model views
                       1 = page layout views
                       2 = both standard and page layout views
    Returns:
      list(str|guid, ...): of the view names or identifiers on success
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      # Print view names
      views = rs.ViewNames()
      if views:
          for view in views: print(view)
      # Print view identifiers
      view_ids = rs.ViewNames(False)
      if view_ids:
          for id in view_ids:
              print("{} = {}".format(id, rs.ViewTitle(id)))
    See Also:
      IsView
      ViewTitle
    """
    views = scriptcontext.doc.Views.GetViewList(view_type!=1, view_type>0)
    if views is None: return scriptcontext.errorhandler()
    if return_names: return [view.MainViewport.Name for view in views]
    return [view.MainViewport.Id for view in views]


def ViewNearCorners(view=None):
    """Return 3d corners of a view's near clipping plane rectangle. Useful
    in determining the "real world" size of a parallel-projected view
    Parameters:
      view (str|guid, optional): title or id of the view. If omitted, current active view is used
    Returns:
      list(point, point, point, point): Four Point3d that define the corners of the rectangle (counter-clockwise order)
    Example:
      import rhinoscriptsyntax as rs
      rect = rs.ViewNearCorners()
      if rect:
          for i in range(4): rs.AddTextDot( i, rect[i] )
    See Also:
      CurrentView
    """
    view = __viewhelper(view)
    rc = view.ActiveViewport.GetNearRect()
    return rc[0], rc[1], rc[3], rc[2]


def ViewProjection(view=None, mode=None):
    """Return or set a view's projection mode.
    Parameters:
      view (str|guid, optional): title or id of the view. If omitted, current active view is used
      mode (number, optional): the projection mode
        1 = parallel
        2 = perspective
        3 = two point perspective
    Returns:
      number: if mode is not specified, the current projection mode for the specified view
      number: if mode is specified, the previous projection mode for the specified view
    Example:
      import rhinoscriptsyntax as rs
      views = rs.ViewNames()
      if views:
          for view in views: rs.ViewProjection(view,1)
    See Also:
      IsViewPerspective
    """
    view = __viewhelper(view)
    viewport = view.ActiveViewport
    rc = 2
    if viewport.IsParallelProjection: rc = 1
    elif viewport.IsTwoPointPerspectiveProjection: rc = 3
    if mode is None or mode==rc: return rc
    if mode==1: viewport.ChangeToParallelProjection(True)
    elif mode==2: viewport.ChangeToPerspectiveProjection(True, 50)
    elif mode==3: viewport.ChangeToTwoPointPerspectiveProjection(50)
    else: return
    view.Redraw()
    return rc


def ViewRadius(view=None, radius=None, mode=False):
    """Returns or sets the radius of a parallel-projected view. Useful
    when you need an absolute zoom factor for a parallel-projected view
    Parameters:
      view (str|guid, optional): title or id of the view. If omitted, current active view is used
      radius (number): the view radius
      mode (bool, optional): perform a "dolly" magnification by moving the camera
        towards/away from the target so that the amount of the screen 
        subtended by an object changes.  true = perform a "zoom" 
        magnification by adjusting the "lens" angle
    Returns:
      number: if radius is not specified, the current view radius for the specified view
      number: if radius is specified, the previous view radius for the specified view
    Example:
      import rhinoscriptsyntax as rs
      rhParallelView = 1
      views = rs.ViewNames()
      if views:
          for view in views:
              if rs.ViewProjection(view)==rhParallelView:
                  rs.ViewRadius(view, 10.0)
    See Also:
      IsViewPerspective
      ViewProjection
    """
    view = __viewhelper(view)
    viewport = view.ActiveViewport
    if not viewport.IsParallelProjection: return scriptcontext.errorhandler()
    fr = viewport.GetFrustum()
    frus_right = fr[2]
    frus_top = fr[4]
    old_radius = min(frus_top, frus_right)
    if radius is None: return old_radius
    magnification_factor = radius / old_radius
    d = 1.0 / magnification_factor
    viewport.Magnify(d, mode)
    view.Redraw()
    return old_radius


def ViewSize(view=None):
    """Returns the width and height in pixels of the specified view
    Parameters:
      view (str|guid): title or id of the view. If omitted, current active view is used
    Returns:
      tuple(number, number): of two numbers identifying width and height
    Example:
      import rhinoscriptsyntax as rs
      size = rs.ViewSize()
      if size:
          print("Width: {} pixels".format(size[0]))
          print("Height: {} pixels".format(size[1]))
    See Also:
      ViewCameraLens
      ViewCameraTarget
      ViewCPlane
      ViewDisplayModes
      ViewProjection
    """
    view = __viewhelper(view)
    cr = view.ClientRectangle
    return cr.Width, cr.Height


def ViewSpeedTest(view=None, frames=100, freeze=True, direction=0, angle_degrees=5):
    """Test's Rhino's display performance
    Parameters:
      view (str|guid, optional): The title or identifier of the view.  If omitted, the current active view is used
      frames (number, optional): The number of frames, or times to regenerate the view. If omitted, the view will be regenerated 100 times.
      freeze (bool, optional): If True (Default), then Rhino's display list will not be updated with every frame redraw. If False, then Rhino's display list will be updated with every frame redraw.
      direction (number, optional): The direction to rotate the view. The default direction is Right (0). Modes:
        0 = Right
        1 = Left
        2 = Down
        3 = Up.
      angle_degrees (number, optional): The angle to rotate. If omitted, the rotation angle of 5.0 degrees will be used.
    Returns:
      number: The number of seconds it took to regenerate the view frames number of times, if successful
      None: if not successful
    Example:
      import rhinoscriptsyntax as rs
      view = "Perspective"
      seconds = rs.ViewSpeedTest(view, 100)
      if seconds:
          print("Time to regen viewport 100 times = {} secords".format(seconds))
    See Also:
      
    """
    view = __viewhelper(view)
    angle_radians = math.radians(angle_degrees)
    return view.SpeedTest(frames, freeze, direction, angle_radians)


def ViewTarget(view=None, target=None):
    """Returns or sets the target location of the specified view
    Parameters:
      view (str|guid, optional): title or id of the view. If omitted, current active view is used
      target (point, optional): 3d point identifying the new target location. If omitted,
        the current target location is returned
    Returns:
      point: is target is not specified, then the current target location
      point: is target is specified, then the previous target location
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      view = rs.CurrentView()
      target = rs.GetPoint("Select new target location")
      if target: rs.ViewTarget( view, target )
    See Also:
      ViewCamera
      ViewCameraTarget
    """
    view = __viewhelper(view)
    viewport = view.ActiveViewport
    old_target = viewport.CameraTarget
    if target is None: return old_target
    target = rhutil.coerce3dpoint(target)
    if target is None: return scriptcontext.errorhandler()
    viewport.SetCameraTarget(target, True)
    view.Redraw()
    return old_target


def ViewTitle(view_id):
    """Returns the name, or title, of a given view's identifier
    Parameters:
      view_id (str|guid): The identifier of the view
    Returns:
      str: name or title of the view on success
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      view_ids = rs.ViewNames(False)
      for id in view_ids:
          print(id + " = " + rs.ViewTitle(id))
    See Also:
      CurrentView
      ViewNames
    """
    view_id = rhutil.coerceguid(view_id)
    if view_id is None: return scriptcontext.errorhandler()
    view = scriptcontext.doc.Views.Find(view_id)
    if view is None: return scriptcontext.errorhandler()
    return view.MainViewport.Name


def Wallpaper(view=None, filename=None):
    """Returns or sets the wallpaper bitmap of the specified view. To remove a
    wallpaper bitmap, pass an empty string ""
    Parameters:
      view (str|guid, optional): The identifier of the view. If omitted, the
        active view is used
      filename (str): Name of the bitmap file to set as wallpaper
    Returns:
      str: If filename is not specified, the current wallpaper bitmap filename
      str: If filename is specified, the previous wallpaper bitmap filename
    Example:
      import rhinoscriptsyntax as rs
      view = rs.CurrentView()
      filename = rs.OpenFileName()
      if filename and not rs.IsWallpaper(view):
          rs.Wallpaper(view, filename)
    See Also:
      IsWallpaper
      WallpaperGrayScale
      WallpaperHidden
    """
    view = __viewhelper(view)
    rc = view.ActiveViewport.WallpaperFilename
    if filename is not None and filename!=rc:
        view.ActiveViewport.SetWallpaper(filename, False)
        view.Redraw()
    return rc


def WallpaperGrayScale(view=None, grayscale=None):
    """Returns or sets the grayscale display option of the wallpaper bitmap in a
    specified view
    Parameters:
      view (str|guid, optional):  The identifier of the view. If omitted, the
        active view is used
      grayscale (bool, optional): Display the wallpaper in gray(True) or color (False)
    Returns:
      bool: If grayscale is not specified, the current grayscale display option
      bool: If grayscale is specified, the previous grayscale display option
    Example:
      import rhinoscriptsyntax as rs
      view = rs.CurrentView()
      if rs.WallpaperGrayScale(view)==False: rs.WallpaperGrayScale(view, True)
    See Also:
      Wallpaper
      WallpaperHidden
    """
    view = __viewhelper(view)
    rc = view.ActiveViewport.WallpaperGrayscale
    if grayscale is not None and grayscale!=rc:
        filename = view.ActiveViewport.WallpaperFilename
        view.ActiveViewport.SetWallpaper(filename, grayscale)
        view.Redraw()
    return rc


def WallpaperHidden(view=None, hidden=None):
    """Returns or sets the visibility of the wallpaper bitmap in a specified view
    Parameters:
      view (str|guid, optional): The identifier of the view. If omitted, the
        active view is used
      hidden (bool, optional): Show or hide the wallpaper
    Returns:
      bool: If hidden is not specified, the current hidden state
      bool: If hidden is specified, the previous hidden state
    Example:
      import rhinoscriptsyntax as rs
      view = rs.CurrentView()
      if rs.WallpaperHidden(view) == False: rs.WallpaperHidden(view, True)
    See Also:
      Wallpaper
      WallpaperGrayScale
    """
    view = __viewhelper(view)
    rc = not view.ActiveViewport.WallpaperVisible
    if hidden is not None and hidden!=rc:
        filename = view.ActiveViewport.WallpaperFilename
        gray = view.ActiveViewport.WallpaperGrayscale
        view.ActiveViewport.SetWallpaper(filename, gray, not hidden)
        view.Redraw()
    return rc


def ZoomBoundingBox(bounding_box, view=None, all=False):
    """Zooms to the extents of a specified bounding box in the specified view
    Parameters:
      bounding_box ([point, point, point ,point, point, point, point, point]): eight points that define the corners
        of a bounding box or a BoundingBox class instance
      view  (str|guid, optional): title or id of the view. If omitted, current active view is used
      all (bool, optional): zoom extents in all views
    Returns:
      None
    Example:
      import rhinoscriptsyntax as rs
      obj = rs.GetObject()
      if obj:
          bbox = rs.BoundingBox(obj)
          rs.ZoomBoundingBox( bbox )
    See Also:
      ZoomExtents
      ZoomSelected
    """
    bbox = rhutil.coerceboundingbox(bounding_box)
    if bbox:
      if all:
          views = scriptcontext.doc.Views.GetViewList(True, True)
          for view in views: view.ActiveViewport.ZoomBoundingBox(bbox)
      else:
          view = __viewhelper(view)
          view.ActiveViewport.ZoomBoundingBox(bbox)
      scriptcontext.doc.Views.Redraw()


def ZoomExtents(view=None, all=False):
    """Zooms to extents of visible objects in the specified view
    Parameters:
      view  (str|guid, optional): title or id of the view. If omitted, current active view is used
      all (bool, optional): zoom extents in all views
    Returns:
      None
    Example:
      import rhinoscriptsyntax as rs
      rs.ZoomExtents()
    See Also:
      ZoomBoundingBox
      ZoomSelected
    """
    if all:
        views = scriptcontext.doc.Views.GetViewList(True, True)
        for view in views: view.ActiveViewport.ZoomExtents()
    else:
        view = __viewhelper(view)
        view.ActiveViewport.ZoomExtents()
    scriptcontext.doc.Views.Redraw()


def ZoomSelected(view=None, all=False):
    """Zoom to extents of selected objects in a view
    Parameters:
      view  (str|guid, optional): title or id of the view. If omitted, active view is used
      all (bool, optional): zoom extents in all views
    Returns:
      None
    Example:
      import rhinocriptsyntax as rs
      obj = rs.GetObject("Select object", select=True)
      if obj: rs.ZoomSelected()
    See Also:
      ZoomBoundingBox
      ZoomExtents
    """
    if all:
        views = scriptcontext.doc.Views.GetViewList(True, True)
        for view in views: view.ActiveViewport.ZoomExtentsSelected()
    else:
        view = __viewhelper(view)
        view.ActiveViewport.ZoomExtentsSelected()
    scriptcontext.doc.Views.Redraw()

```

--------------------------------------------------------------------------------
/rhino_mcp_server/static/object.py:
--------------------------------------------------------------------------------

```python
import math

import System

import Rhino

import scriptcontext

from rhinoscript import utility as rhutil
from rhinoscript.layer import __getlayer
from rhinoscript.view import __viewhelper


__ALLOWED_TRANSFORM_TYPES = [
    Rhino.Geometry.Point3d,
    Rhino.Geometry.Line,
    Rhino.Geometry.Rectangle3d,
    Rhino.Geometry.Circle,
    Rhino.Geometry.Ellipse,
    Rhino.Geometry.Arc,
    Rhino.Geometry.Polyline,
    Rhino.Geometry.Box,
    Rhino.Geometry.Sphere
]


def CopyObject(object_id, translation=None):
    """Copies object from one location to another, or in-place.
    Parameters:
      object_id (guid): object to copy
      translation (vector, optional): translation vector to apply
    Returns:
      guid: id for the copy if successful
      None: if not able to copy
    Example:
      import rhinoscriptsyntax as rs
      id = rs.GetObject("Select object to copy")
      if id:
          start = rs.GetPoint("Point to copy from")
          if start:
              end = rs.GetPoint("Point to copy to", start)
              if end:
                  translation = end-start
                  rs.CopyObject( id, translation )
    See Also:
      CopyObjects
    """
    rc = CopyObjects(object_id, translation)
    if rc: return rc[0]


def CopyObjects(object_ids, translation=None):
    """Copies one or more objects from one location to another, or in-place.
    Parameters:
      object_ids ([guid, ...])list of objects to copy
      translation (vector, optional): list of three numbers or Vector3d representing
                         translation vector to apply to copied set
    Returns:
      list(guid, ...): identifiers for the copies if successful
    Example:
      import rhinoscriptsyntax as rs
      objectIds = rs.GetObjects("Select objects to copy")
      if objectIds:
          start = rs.GetPoint("Point to copy from")
          if start:
              end = rs.GetPoint("Point to copy to", start)
              if end:
                  translation = end-start
                  rs.CopyObjects( objectIds, translation )
    See Also:
      CopyObject
    """
    if translation:
        translation = rhutil.coerce3dvector(translation, True)
        translation = Rhino.Geometry.Transform.Translation(translation)
    else:
        translation = Rhino.Geometry.Transform.Identity
    return TransformObjects(object_ids, translation, True)


def DeleteObject(object_id):
    """Deletes a single object from the document
    Parameters:
      object_id (guid): identifier of object to delete
    Returns:
      bool: True of False indicating success or failure
    Example:
      import rhinoscriptsyntax as rs
      id = rs.GetObject("Select object to delete")
      if id: rs.DeleteObject(id)
    See Also:
      DeleteObjects
    """
    object_id = rhutil.coerceguid(object_id, True)
    rc = scriptcontext.doc.Objects.Delete(object_id, True)
    if rc: scriptcontext.doc.Views.Redraw()
    return rc


def DeleteObjects(object_ids):
    """Deletes one or more objects from the document
    Parameters:
      object_ids ([guid, ...]): identifiers of objects to delete
    Returns:
      number: Number of objects deleted
    Example:
      import rhinoscriptsyntax as rs
      object_ids = rs.GetObjects("Select objects to delete")
      if object_ids: rs.DeleteObjects(object_ids)
    See Also:
      DeleteObject
    """
    rc = 0
    id = rhutil.coerceguid(object_ids, False)
    if id: object_ids = [id]
    for id in object_ids:
        id = rhutil.coerceguid(id, True)
        if scriptcontext.doc.Objects.Delete(id, True): rc+=1
    if rc: scriptcontext.doc.Views.Redraw()
    return rc


def FlashObject(object_ids, style=True):
    """Causes the selection state of one or more objects to change momentarily
    so the object appears to flash on the screen
    Parameters:
      object_ids ([guid, ...]) identifiers of objects to flash
      style (bool, optional): If True, flash between object color and selection color.
        If False, flash between visible and invisible
    Returns:
      None
    Example:
      import rhinoscriptsyntax as rs
      objs = rs.ObjectsByLayer("Default")
      if objs: rs.FlashObject(objs)
    See Also:
      HideObjects
      SelectObjects
      ShowObjects
      UnselectObjects
    """
    id = rhutil.coerceguid(object_ids, False)
    if id: object_ids = [id]
    rhobjs = [rhutil.coercerhinoobject(id, True, True) for id in object_ids]
    if rhobjs: scriptcontext.doc.Views.FlashObjects(rhobjs, style)


def HideObject(object_id):
    """Hides a single object
    Parameters:
      object_id (guid): id of object to hide
    Returns:
      bool: True of False indicating success or failure
    Example:
      import rhinoscriptsyntax as rs
      id = rs.GetObject("Select object to hide")
      if id: rs.HideObject(id)
    See Also:
      HideObjects
      IsObjectHidden
      ShowObject
      ShowObjects
    """
    return HideObjects(object_id)==1


def HideObjects(object_ids):
    """Hides one or more objects
    Parameters:
      object_ids ([guid, ...]): identifiers of objects to hide
    Returns:
      number: Number of objects hidden
    Example:
      import rhinoscriptsyntax as rs
      ids = rs.GetObjects("Select objects to hide")
      if ids: rs.HideObjects(ids)
    See Also:
      HideObjects
      IsObjectHidden
      ShowObject
      ShowObjects
    """
    id = rhutil.coerceguid(object_ids, False)
    if id: object_ids = [id]
    rc = 0
    for id in object_ids:
        id = rhutil.coerceguid(id, True)
        if scriptcontext.doc.Objects.Hide(id, False): rc += 1
    if rc: scriptcontext.doc.Views.Redraw()
    return rc


def IsLayoutObject(object_id):
    """Verifies that an object is in either page layout space or model space
    Parameters:
      object_id (guid): id of an object to test
    Returns:
      bool: True if the object is in page layout space
      bool: False if the object is in model space
    Example:
      import rhinoscriptsyntax as rs
      id = rs.GetObject("Select object")
      if id:
          if rs.IsLayoutObject(id):
              print("The object is in page layout space.")
          else:
              print("The object is in model space.")
    See Also:
      IsObject
      IsObjectReference
    """
    rhobj = rhutil.coercerhinoobject(object_id, True, True)
    return rhobj.Attributes.Space == Rhino.DocObjects.ActiveSpace.PageSpace


def IsObject(object_id):
    """Verifies the existence of an object
    Parameters:
      object_id (guid): an object to test
    Returns:
      bool: True if the object exists
      bool: False if the object does not exist
    Example:
      import rhinoscriptsyntax as rs
      #Do something here...
      if rs.IsObject(id):
          print("The object exists.")
      else:
          print("The object does not exist.")
    See Also:
      IsObjectHidden
      IsObjectInGroup
      IsObjectLocked
      IsObjectNormal
      IsObjectReference
      IsObjectSelectable
      IsObjectSelected
      IsObjectSolid
    """
    return rhutil.coercerhinoobject(object_id, True, False) is not None


def IsObjectHidden(object_id):
    """Verifies that an object is hidden. Hidden objects are not visible, cannot
    be snapped to, and cannot be selected
    Parameters:
      object_id (guid): The identifier of an object to test
    Returns:
      bool: True if the object is hidden
      bool: False if the object is not hidden
    Example:
      import rhinoscriptsyntax as rs
      # Do something here...
      if rs.IsObjectHidden(id):
          print("The object is hidden.")
      else:
          print("The object is not hidden.")
    See Also:
      IsObject
      IsObjectInGroup
      IsObjectLocked
      IsObjectNormal
      IsObjectReference
      IsObjectSelectable
      IsObjectSelected
      IsObjectSolid
    """
    rhobj = rhutil.coercerhinoobject(object_id, True, True)
    return rhobj.IsHidden


def IsObjectInBox(object_id, box, test_mode=True):
    """Verifies an object's bounding box is inside of another bounding box
    Parameters:
      object_id (guid): identifier of an object to be tested
      box ([point, point, point, point, point, point, point, point]): bounding box to test for containment
      test_mode (bool, optional): If True, the object's bounding box must be contained by box
        If False, the object's bounding box must be contained by or intersect box
    Returns:
      bool: True if object is inside box
      bool: False is object is not inside box
    Example:
      import rhinoscriptsyntax as rs
      box = rs.GetBox()
      if box:
          rs.EnableRedraw(False)
          object_list = rs.AllObjects()
          for obj in object_list:
              if rs.IsObjectInBox(obj, box, False):
                  rs.SelectObject( obj )
          rs.EnableRedraw( True )
    See Also:
      BoundingBox
      GetBox
    """
    rhobj = rhutil.coercerhinoobject(object_id, True, True)
    box = rhutil.coerceboundingbox(box, True)
    objbox = rhobj.Geometry.GetBoundingBox(True)
    if test_mode: return box.Contains(objbox)
    union = Rhino.Geometry.BoundingBox.Intersection(box, objbox)
    return union.IsValid


def IsObjectInGroup(object_id, group_name=None):
    """Verifies that an object is a member of a group
    Parameters:
      object_id (guid): The identifier of an object
      group_name (str, optional): The name of a group. If omitted, the function
        verifies that the object is a member of any group
    Returns:
      bool: True if the object is a member of the specified group. If a group_name
        was not specified, the object is a member of some group.
      bool: False if the object is not a member of the specified group. If a
        group_name was not specified, the object is not a member of any group
    Example:
      import rhinoscriptsyntax as rs
      id = rs.GetObject("Select object")
      if id:
          name = rs.GetString("Group name")
          if name:
              result = rs.IsObjectInGroup(id, name)
              if result:
                  print("The object belongs to the group.")
              else:
                  print("The object does not belong to the group.")
    See Also:
      IsObject
      IsObjectHidden
      IsObjectLocked
      IsObjectNormal
      IsObjectReference
      IsObjectSelectable
      IsObjectSelected
      IsObjectSolid
    """
    rhobj = rhutil.coercerhinoobject(object_id, True, True)
    count = rhobj.GroupCount
    if count<1: return False
    if not group_name: return True
    index = scriptcontext.doc.Groups.Find(group_name)
    if index<0: raise ValueError("%s group does not exist"%group_name)
    group_ids = rhobj.GetGroupList()
    for id in group_ids:
        if id==index: return True
    return False


def IsObjectLocked(object_id):
    """Verifies that an object is locked. Locked objects are visible, and can
    be snapped to, but cannot be selected
    Parameters:
      object_id (guid): The identifier of an object to be tested
    Returns:
      bool: True if the object is locked
      bool: False if the object is not locked
    Example:
      import rhinoscriptsyntax as rs
      # Do something here...
      if rs.IsObjectLocked(object):
          print("The object is locked.")
      else:
          print("The object is not locked.")
    See Also:
      IsObject
      IsObjectHidden
      IsObjectInGroup
      IsObjectNormal
      IsObjectReference
      IsObjectSelectable
      IsObjectSelected
      IsObjectSolid
    """
    rhobj = rhutil.coercerhinoobject(object_id, True, True)
    return rhobj.IsLocked


def IsObjectNormal(object_id):
    """Verifies that an object is normal. Normal objects are visible, can be
    snapped to, and can be selected
    Parameters:
      object_id (guid): The identifier of an object to be tested
    Returns:
      bool: True if the object is normal
      bool: False if the object is not normal
    Example:
      import rhinoscriptsyntax as rs
      #Do something here...
      if rs.IsObjectNormal(object):
          print("The object is normal.")
      else:
          print("The object is not normal.")
    See Also:
      IsObject
      IsObjectHidden
      IsObjectInGroup
      IsObjectLocked
      IsObjectReference
      IsObjectSelectable
      IsObjectSelected
      IsObjectSolid
    """
    rhobj = rhutil.coercerhinoobject(object_id, True, True)
    return rhobj.IsNormal


def IsObjectReference(object_id):
    """Verifies that an object is a reference object. Reference objects are
    objects that are not part of the current document
    Parameters:
      object_id (guid): The identifier of an object to test
    Returns:
      bool: True if the object is a reference object
      bool: False if the object is not a reference object
    Example:
      import rhinoscriptsyntax as rs
      id = rs.GetObject("Select object")
      if rs.IsObjectReference(id):
          print("The object is a reference object.")
      else:
          print("The object is not a reference object.")
    See Also:
      IsObject
      IsObjectHidden
      IsObjectInGroup
      IsObjectLocked
      IsObjectNormal
      IsObjectSelectable
      IsObjectSelected
      IsObjectSolid
    """
    rhobj = rhutil.coercerhinoobject(object_id, True, True)
    return rhobj.IsReference


def IsObjectSelectable(object_id):
    """Verifies that an object can be selected
    Parameters:
      object_id (guid): The identifier of an object to test
    Returns:
      bool: True or False
    Example:
      import rhinoscriptsyntax as rs
      # Do something here...
      if rs.IsObjectSelectable(object):
      rs.SelectObject( object )
    See Also:
      IsObject
      IsObjectHidden
      IsObjectInGroup
      IsObjectLocked
      IsObjectNormal
      IsObjectReference
      IsObjectSelected
      IsObjectSolid
    """
    rhobj = rhutil.coercerhinoobject(object_id, True, True)
    return rhobj.IsSelectable(True,False,False,False)


def IsObjectSelected(object_id):
    """Verifies that an object is currently selected.
    Parameters:
      object_id (guid): The identifier of an object to test
    Returns:
      int: 0, the object is not selected
      int: 1, the object is selected
      int: 2, the object is entirely persistently selected
      int: 3, one or more proper sub-objects are selected
    Example:
      import rhinoscriptsyntax as rs
      object = rs.GetObject()
      if rs.IsObjectSelected(object):
          print("The object is selected.")
      else:
          print("The object is not selected.")
    See Also:
      IsObject
      IsObjectHidden
      IsObjectInGroup
      IsObjectLocked
      IsObjectNormal
      IsObjectReference
      IsObjectSelectable
      IsObjectSolid
    """
    rhobj = rhutil.coercerhinoobject(object_id, True, True)
    return rhobj.IsSelected(False)


def IsObjectSolid(object_id):
    """Determines if an object is closed, solid
    Parameters:
      object_id (guid): The identifier of an object to test
    Returns:
      bool: True if the object is solid, or a mesh is closed.
      bool: False otherwise.
    Example:
      import rhinoscriptsyntax as rs
      id = rs.GetObject("Select object")
      if rs.IsObjectSolid(id):
          print("The object is solid.")
      else:
          print("The object is not solid.")
    See Also:
      IsObject
      IsObjectHidden
      IsObjectInGroup
      IsObjectLocked
      IsObjectNormal
      IsObjectReference
      IsObjectSelectable
      IsObjectSelected
    """
    rhobj = rhutil.coercerhinoobject(object_id, True, True)
    return rhobj.IsSolid


def IsObjectValid(object_id):
    """Verifies an object's geometry is valid and without error
    Parameters:
      object_id (guid): The identifier of an object to test
    Returns:
      bool: True if the object is valid
    Example:
      import rhinoscriptsyntax as rs
      id = rs.GetObject("Select object")
      if rs.IsObjectValid(id):
          print("The object is valid.")
      else:
          print("The object is not valid.")
    See Also:
      IsObject
    """
    rhobj = rhutil.coercerhinoobject(object_id, True, True)
    return rhobj.IsValid


def IsVisibleInView(object_id, view=None):
    """Verifies an object is visible in a view
    Parameters:
      object_id (guid): the identifier of an object to test
      view (str, optional): he title of the view.  If omitted, the current active view is used.
    Returns:
      bool: True if the object is visible in the specified view, otherwise False.  None on error
    Example:
      import rhinoscriptsyntax as rs
      obj = rs.GetObject("Select object")
      if rs.IsObject(obj):
          view = rs.CurrentView()
          if rs.IsVisibleInView(obj, view):
              print("The object is visible in {}.".format(view))
          else:
              print("The object is not visible in {}.".format(view))
    See Also:
      IsObject
      IsView
    """
    rhobj = rhutil.coercerhinoobject(object_id, True, True)
    viewport = __viewhelper(view).MainViewport
    bbox = rhobj.Geometry.GetBoundingBox(True)
    return rhobj.Visible and viewport.IsVisible(bbox)


def LockObject(object_id):
    """Locks a single object. Locked objects are visible, and they can be
    snapped to. But, they cannot be selected.
    Parameters:
      object_id (guid): The identifier of an object
    Returns:
      bool: True or False indicating success or failure
    Example:
      import rhinoscriptsyntax as rs
      id = rs.GetObject("Select object to lock")
      if id: rs.LockObject(id)
    See Also:
      IsObjectLocked
      LockObjects
      UnlockObject
      UnlockObjects
    """
    return LockObjects(object_id)==1


def LockObjects(object_ids):
    """Locks one or more objects. Locked objects are visible, and they can be
    snapped to. But, they cannot be selected.
    Parameters:
      object_ids ([guid, ...]): list of Strings or Guids. The identifiers of objects
    Returns:
      number: number of objects locked
    Example:
      import rhinoscriptsyntax as rs
      ids = rs.GetObjects("Select objects to lock")
      if ids: rs.LockObjects(ids)
    See Also:
      IsObjectLocked
      LockObject
      UnlockObject
      UnlockObjects
    """
    id = rhutil.coerceguid(object_ids, False)
    if id: object_ids = [id]
    rc = 0
    for id in object_ids:
        id = rhutil.coerceguid(id, True)
        if scriptcontext.doc.Objects.Lock(id, False): rc += 1
    if rc: scriptcontext.doc.Views.Redraw()
    return rc


def MatchObjectAttributes(target_ids, source_id=None):
    """Matches, or copies the attributes of a source object to a target object
    Parameters:
      target_ids ([guid, ...]): identifiers of objects to copy attributes to
      source_id (guid, optional): identifier of object to copy attributes from. If None,
        then the default attributes are copied to the target_ids
    Returns:
      number: number of objects modified
    Example:
      import rhinoscriptsyntax as rs
      targets = rs.GetObjects("Select objects")
      if targets:
          source = rs.GetObject("Select object to match")
          if source: rs.MatchObjectAttributes( targets, source )
    See Also:
      GetObject
      GetObjects
    """
    id = rhutil.coerceguid(target_ids, False)
    if id: target_ids = [id]
    source_attr = Rhino.DocObjects.ObjectAttributes()
    if source_id:
        source = rhutil.coercerhinoobject(source_id, True, True)
        source_attr = source.Attributes.Duplicate()
    rc = 0
    for id in target_ids:
        id = rhutil.coerceguid(id, True)
        if scriptcontext.doc.Objects.ModifyAttributes(id, source_attr, True):
            rc += 1
    if rc: scriptcontext.doc.Views.Redraw()
    return rc


def MirrorObject(object_id, start_point, end_point, copy=False):
    """Mirrors a single object
    Parameters:
      object_id (guid): The identifier of an object to mirror
      start_point (point): start of the mirror plane
      end_point (point): end of the mirror plane
      copy (bool, optional): copy the object
    Returns:
      guid: Identifier of the mirrored object if successful
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      obj = rs.GetObject("Select object to mirror")
      if obj:
          start = rs.GetPoint("Start of mirror plane")
          end = rs.GetPoint("End of mirror plane")
          if start and end:
              rs.MirrorObject( obj, start, end, True )
    See Also:
      MirrorObjects
    """
    rc = MirrorObjects(object_id, start_point, end_point, copy)
    if rc: return rc[0]


def MirrorObjects(object_ids, start_point, end_point, copy=False):
    """Mirrors a list of objects
    Parameters:
      object_ids ([guid, ...]): identifiers of objects to mirror
      start_point (point): start of the mirror plane
      end_point (point): end of the mirror plane
      copy (bool, optional): copy the objects
    Returns:
      list(guid, ...): List of identifiers of the mirrored objects if successful
    Example:
      import rhinoscriptsyntax as rs
      objs = rs.GetObjects("Select objects to mirror")
      if objs:
          start = rs.GetPoint("Start of mirror plane")
          end = rs.GetPoint("End of mirror plane")
          if start and end:
              rs.MirrorObjects( objs, start, end, True )
    See Also:
      MirrorObject
    """
    start_point = rhutil.coerce3dpoint(start_point, True)
    end_point = rhutil.coerce3dpoint(end_point, True)
    vec = end_point-start_point
    if vec.IsTiny(0): raise Exception("start and end points are too close to each other")
    normal = scriptcontext.doc.Views.ActiveView.ActiveViewport.ConstructionPlane().Normal
    vec = Rhino.Geometry.Vector3d.CrossProduct(vec, normal)
    vec.Unitize()
    xf = Rhino.Geometry.Transform.Mirror(start_point, vec)
    rc = TransformObjects(object_ids, xf, copy)
    return rc


def MoveObject(object_id, translation):
    """Moves a single object
    Parameters:
      object_id (guid): The identifier of an object to move
      translation (vector): list of 3 numbers or Vector3d
    Returns:
      guid: Identifier of the moved object if successful
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      id = rs.GetObject("Select object to move")
      if id:
          start = rs.GetPoint("Point to move from")
          if start:
              end = rs.GetPoint("Point to move to")
              if end:
                  translation = end-start
                  rs.MoveObject(id, translation)
    See Also:
      MoveObjects
    """
    rc = MoveObjects(object_id, translation)
    if rc: return rc[0]


def MoveObjects(object_ids, translation):
    """Moves one or more objects
    Parameters:
      object_ids ([guid, ...]): The identifiers objects to move
      translation (vector): list of 3 numbers or Vector3d
    Returns:
      list(guid, ...): identifiers of the moved objects if successful
    Example:
      import rhinoscriptsyntax as rs
      ids = rs.GetObjects("Select objects to move")
      if ids:
          start = rs.GetPoint("Point to move from")
          if start:
              end = rs.GetPoint("Point to move to")
              if end:
                  translation = end-start
                  rs.MoveObjects( ids, translation )
    See Also:
      MoveObject
    """
    translation = rhutil.coerce3dvector(translation, True)
    xf = Rhino.Geometry.Transform.Translation(translation)
    rc = TransformObjects(object_ids, xf)
    return rc


def ObjectColor(object_ids, color=None):
    """Returns of modifies the color of an object. Object colors are represented
    as RGB colors. An RGB color specifies the relative intensity of red, green,
    and blue to cause a specific color to be displayed
    Parameters:
        object_ids ([guid, ...]): id or ids of object(s)
        color (color, optional): the new color value. If omitted, then current object
            color is returned. If object_ids is a list, color is required
    Returns:
        color: If color value is not specified, the current color value
        color: If color value is specified, the previous color value
        number: If object_ids is a list, then the number of objects modified
    Example:
      import rhinoscriptsyntax as rs
      objs = rs.GetObjects("Select objects to change color")
      if objs:
          color = rs.GetColor(0)
          if color:
              for obj in objs: rs.ObjectColor( obj, color )
    See Also:
      ObjectColorSource
      ObjectsByColor
    """
    id = rhutil.coerceguid(object_ids, False)
    rhino_object = None
    rhino_objects = None
    if id:
        rhino_object = rhutil.coercerhinoobject(id, True, True)
    else:
        rhino_objects = [rhutil.coercerhinoobject(id, True, True) for id in object_ids]
        if len(rhino_objects)==1:
            rhino_object = rhino_objects[0]
            rhino_objects = None
    if color is None:
        #get the color
        if rhino_objects: raise ValueError("color must be specified when a list of rhino objects is provided")
        return rhino_object.Attributes.DrawColor(scriptcontext.doc)
    color = rhutil.coercecolor(color, True)
    if rhino_objects is not None:
        for rh_obj in rhino_objects:
            attr = rh_obj.Attributes
            attr.ObjectColor = color
            attr.ColorSource = Rhino.DocObjects.ObjectColorSource.ColorFromObject
            scriptcontext.doc.Objects.ModifyAttributes( rh_obj, attr, True)
        scriptcontext.doc.Views.Redraw()
        return len(rhino_objects)
    rc = rhino_object.Attributes.DrawColor(scriptcontext.doc)
    attr = rhino_object.Attributes
    attr.ObjectColor = color
    attr.ColorSource = Rhino.DocObjects.ObjectColorSource.ColorFromObject
    scriptcontext.doc.Objects.ModifyAttributes( rhino_object, attr, True )
    scriptcontext.doc.Views.Redraw()
    return rc


def ObjectColorSource(object_ids, source=None):
    """Returns of modifies the color source of an object.
    Parameters:
      object_ids ([guid, ...]): single identifier of list of identifiers
      source (number, optional) = new color source
          0 = color from layer
          1 = color from object
          2 = color from material
          3 = color from parent
    Returns:
      if color source is not specified, the current color source
      is color source is specified, the previous color source
      if color_ids is a list, then the number of objects modifief
    Example:
      import rhinoscriptsyntax as rs
      objs = rs.GetObjects("Select objects to reset color source")
      if objs:
          for obj In objs: rs.ObjectColorSource(obj, 0)
    See Also:
      ObjectColor
    """
    id = rhutil.coerceguid(object_ids, False)
    if id:
        rhobj = rhutil.coercerhinoobject(id, True, True)
        rc = int(rhobj.Attributes.ColorSource)
        if source is not None:
            rhobj.Attributes.ColorSource = System.Enum.ToObject(Rhino.DocObjects.ObjectColorSource, source)
            rhobj.CommitChanges()
            scriptcontext.doc.Views.Redraw()
        return rc
    else:
        rc = 0
        source = System.Enum.ToObject(Rhino.DocObjects.ObjectColorSource, source)
        for id in object_ids:
            rhobj = rhutil.coercerhinoobject(id, True, True)
            rhobj.Attributes.ColorSource = source
            rhobj.CommitChanges()
            rc += 1
        if rc: scriptcontext.doc.Views.Redraw()
        return rc


def ObjectDescription(object_id):
    """Returns a short text description of an object
    Parameters:
      object_id = identifier of an object
    Returns:
      A short text description of the object if successful.
    Example:
      import rhinoscriptsyntax as rs
      obj = rs.GetObject("Select object")
      if obj:
          description = rs.ObjectDescription(obj)
          print("Object description:"{} .format(description))
    See Also:
      ObjectType
    """
    rhobj = rhutil.coercerhinoobject(object_id, True, True)
    return rhobj.ShortDescription(False)


def ObjectGroups(object_id):
    """Returns all of the group names that an object is assigned to
    Parameters:
      object_id ([guid, ...]): identifier of an object(s)
    Returns:
      list(str, ...): list of group names on success
    Example:
      import rhinoscriptsyntax as rs
      obj = rs.GetObject("Select object")
      if obj:
          groups = rs.ObjectGroups(obj)
          if groups:
              for group in groups: print("Object group: {}".format(group))
          else:
              print("No groups.")
    See Also:
      ObjectsByGroup
    """
    rhino_object = rhutil.coercerhinoobject(object_id, True, True)
    if rhino_object.GroupCount<1: return []
    group_indices = rhino_object.GetGroupList()
    rc = [scriptcontext.doc.Groups.GroupName(index) for index in group_indices]
    return rc


def ObjectLayer(object_id, layer=None):
    """Returns or modifies the layer of an object
    Parameters:
      object_id ([guid, ...]) the identifier of the object(s)
      layer (str, optional):  name of an existing layer
    Returns:
      str: If a layer is not specified, the object's current layer
      str: If a layer is specified, the object's previous layer
      number: If object_id is a list or tuple, the number of objects modified
    Example:
      import rhinoscriptsyntax as rs
      id = rs.GetObject("Select object")
      if id: rs.ObjectLayer(id, "Default")
    See Also:
      ObjectsByLayer
    """
    if type(object_id) is not str and hasattr(object_id, "__len__"):
        layer = __getlayer(layer, True)
        index = layer.LayerIndex
        for id in object_id:
            obj = rhutil.coercerhinoobject(id, True, True)
            obj.Attributes.LayerIndex = index
            obj.CommitChanges()
        scriptcontext.doc.Views.Redraw()
        return len(object_id)
    obj = rhutil.coercerhinoobject(object_id, True, True)
    if obj is None: return scriptcontext.errorhandler()
    index = obj.Attributes.LayerIndex
    rc = scriptcontext.doc.Layers[index].FullPath
    if layer:
        layer = __getlayer(layer, True)
        index = layer.LayerIndex
        obj.Attributes.LayerIndex = index
        obj.CommitChanges()
        scriptcontext.doc.Views.Redraw()
    return rc


def ObjectLayout(object_id, layout=None, return_name=True):
    """Returns or changes the layout or model space of an object
    Parameters:
      object_id (guid): identifier of the object
      layout (str|guid, optional): to change, or move, an object from model space to page
        layout space, or from one page layout to another, then specify the
        title or identifier of an existing page layout view. To move an object
        from page layout space to model space, just specify None
      return_name[opt] = If True, the name, or title, of the page layout view
        is returned. If False, the identifier of the page layout view is returned
    Returns:
      str: if layout is not specified, the object's current page layout view
      str: if layout is specified, the object's previous page layout view
      None: if not successful
    Example:
      import rhinoscriptsyntax as rs
      obj = rs.GetObject("Select object")
      if obj: rs.ObjectLayout(obj, "Page 1")
    See Also:
      IsLayoutObject
      IsLayout
      ViewNames
    """
    rhobj = rhutil.coercerhinoobject(object_id, True, True)
    rc = None
    if rhobj.Attributes.Space==Rhino.DocObjects.ActiveSpace.PageSpace:
        page_id = rhobj.Attributes.ViewportId
        pageview = scriptcontext.doc.Views.Find(page_id)
        if return_name: rc = pageview.MainViewport.Name
        else: rc = pageview.MainViewport.Id
        if layout is None: #move to model space
            rhobj.Attributes.Space = Rhino.DocObjects.ActiveSpace.ModelSpace
            rhobj.Attributes.ViewportId = System.Guid.Empty
            rhobj.CommitChanges()
            scriptcontext.doc.Views.Redraw()
    else:
        if layout:
            layout = scriptcontext.doc.Views.Find(layout, False)
            if layout is not None and isinstance(layout, Rhino.Display.RhinoPageView):
                rhobj.Attributes.ViewportId = layout.MainViewport.Id
                rhobj.Attributes.Space = Rhino.DocObjects.ActiveSpace.PageSpace
                rhobj.CommitChanges()
                scriptcontext.doc.Views.Redraw()
    return rc


def ObjectLinetype(object_ids, linetype=None):
    """Returns of modifies the linetype of an object
    Parameters:
      object_ids ({guid, ...]): identifiers of object(s)
      linetype (str, optional): name of an existing linetype. If omitted, the current
        linetype is returned. If object_ids is a list of identifiers, this parameter
        is required
    Returns:
      str: If a linetype is not specified, the object's current linetype
      str: If linetype is specified, the object's previous linetype
      number: If object_ids is a list, the number of objects modified
    Example:
      import rhinoscriptsyntax as rs
      obj = rs.GetObject("Select object")
      if obj: rs.ObjectLinetype(obj, "Continuous")
    See Also:
      ObjectLinetypeSource
    """
    id = rhutil.coerceguid(object_ids, False)
    if id:
        rhino_object = rhutil.coercerhinoobject(id, True, True)
        oldindex = scriptcontext.doc.Linetypes.LinetypeIndexForObject(rhino_object)
        if linetype:
            newindex = scriptcontext.doc.Linetypes.Find(linetype)
            rhino_object.Attributes.LinetypeSource = Rhino.DocObjects.ObjectLinetypeSource.LinetypeFromObject
            rhino_object.Attributes.LinetypeIndex = newindex
            rhino_object.CommitChanges()
            scriptcontext.doc.Views.Redraw()
        return scriptcontext.doc.Linetypes[oldindex].Name

    newindex = scriptcontext.doc.Linetypes.Find(linetype)
    if newindex<0: raise Exception("%s does not exist in LineTypes table"%linetype)
    for id in object_ids:
        rhino_object = rhutil.coercerhinoobject(id, True, True)
        rhino_object.Attributes.LinetypeSource = Rhino.DocObjects.ObjectLinetypeSource.LinetypeFromObject
        rhino_object.Attributes.LinetypeIndex = newindex
        rhino_object.CommitChanges()
    scriptcontext.doc.Views.Redraw()
    return len(object_ids)


def ObjectLinetypeSource(object_ids, source=None):
    """Returns of modifies the linetype source of an object
    Parameters:
      object_ids ([guid, ...]): identifiers of object(s)
      source (number, optional): new linetype source. If omitted, the current source is returned.
        If object_ids is a list of identifiers, this parameter is required
          0 = By Layer
          1 = By Object
          3 = By Parent
    Returns:
      number: If a source is not specified, the object's current linetype source
      number: If source is specified, the object's previous linetype source
      number: If object_ids is a list, the number of objects modified
    Example:
      import rhinoscriptsyntax as rs
      objects = rs.GetObjects("Select objects to reset linetype source")
      if objects:
          for obj in objects: rs.ObjectLinetypeSource( obj, 0 )
    See Also:
      ObjectLinetype
    """
    id = rhutil.coerceguid(object_ids, False)
    if id:
        rhino_object = rhutil.coercerhinoobject(id, True, True)
        oldsource = rhino_object.Attributes.LinetypeSource
        if source is not None:
            source = System.Enum.ToObject(Rhino.DocObjects.ObjectLinetypeSource, source)
            rhino_object.Attributes.LinetypeSource = source
            rhino_object.CommitChanges()
            scriptcontext.doc.Views.Redraw()
        return int(oldsource)
    source = System.Enum.ToObject(Rhino.DocObjects.ObjectLinetypeSource, source)
    for id in object_ids:
        rhino_object = rhutil.coercerhinoobject(id, True, True)
        rhino_object.Attributes.LinetypeSource = source
        rhino_object.CommitChanges()
    scriptcontext.doc.Views.Redraw()
    return len(object_ids)


def ObjectMaterialIndex(object_id, material_index=None):
    """Returns or changes the material index of an object. Rendering materials are stored in
    Rhino's rendering material table. The table is conceptually an array. Render
    materials associated with objects and layers are specified by zero based
    indices into this array.
    Parameters:
      object_id (guid): identifier of an object
      index (number, optional): the new material index
    Returns:
      number: If the return value of ObjectMaterialSource is "material by object", then
          the return value of this function is the index of the object's rendering
          material. A material index of -1 indicates no material has been assigned,
          and that Rhino's internal default material has been assigned to the object.
      None: on failure
    Example:
      import rhinoscriptsyntax as rs
      obj = rs.GetObject("Select object")
      if obj:
          source = rs.ObjectMaterialSource(obj)
          if source==0:
              print("The material source is by layer")
          else:
              print("The material source is by object")
              index = rs.ObjectMaterialIndex(obj)
              if index==-1: print("The material is default.")
              else: print("The material is custom.")
    See Also:
      ObjectMaterialSource
    """
    rhino_object = rhutil.coercerhinoobject(object_id, True, True)
    if material_index is not None and material_index < scriptcontext.doc.Materials.Count:
      attrs = rhino_object.Attributes
      attrs.MaterialIndex = material_index
      scriptcontext.doc.Objects.ModifyAttributes(rhino_object, attrs, True)
    return rhino_object.Attributes.MaterialIndex


def ObjectMaterialSource(object_ids, source=None):
    """Returns or modifies the rendering material source of an object.
    Parameters:
      object_ids ([guid, ...]): one or more object identifiers
      source (number, optional): The new rendering material source. If omitted and a single
        object is provided in object_ids, then the current material source is
        returned. This parameter is required if multiple objects are passed in
        object_ids
        0 = Material from layer
        1 = Material from object
        3 = Material from parent
    Returns:
      number: If source is not specified, the current rendering material source
      number: If source is specified, the previous rendering material source
      number: If object_ids refers to multiple objects, the number of objects modified
    Example:
      import rhinoscriptsyntax as rs
      objects = rs.GetObjects("Select objects to reset rendering material source")
      if objects:
          [rs.ObjectMaterialSource(obj, 0) for obj in objects]
    See Also:
      ObjectMaterialIndex
    """
    id = rhutil.coerceguid(object_ids, False)
    if id: # working with single object
        rhino_object = rhutil.coercerhinoobject(id, True, True)
        rc = int(rhino_object.Attributes.MaterialSource)
        if source is not None:
            rhino_object.Attributes.MaterialSource = System.Enum.ToObject(Rhino.DocObjects.ObjectMaterialSource, source)
            rhino_object.CommitChanges()
        return rc
    # else working with multiple objects
    if source is None: raise Exception("source is required when object_ids represents multiple objects")
    source = System.Enum.ToObject(Rhino.DocObjects.ObjectMaterialSource, source)
    for id in object_ids:
        rhino_object = rhutil.coercerhinoobject(id, True, True)
        rhino_object.Attributes.MaterialSource = source
        rhino_object.CommitChanges()
    return len(object_ids)


def ObjectName(object_id, name=None):
    """Returns or modifies the name of an object
    Parameters:
      object_id ([guid, ...]): id or ids of object(s)
      name (str, optional): the new object name. If omitted, the current name is returned
    Returns:
      str: If name is not specified, the current object name
      str: If name is specified, the previous object name
      number: If object_id is a list, the number of objects changed
    Example:
      import rhinoscriptsyntax as rs
      points = rs.GetPoints(message1="Pick some points")
      if points:
          count = 0
          for point in points:
              obj = rs.AddPoint(point)
              if obj:
                  rs.ObjectName( obj, "Point"+str(count) )
                  count += 1
    See Also:
      ObjectsByName
    """
    id = rhutil.coerceguid(object_id, False)
    rhino_object = None
    rhino_objects = None
    if id:
        rhino_object = rhutil.coercerhinoobject(id, True, True)
    else:
        rhino_objects = [rhutil.coercerhinoobject(id, True, True) for id in object_id]
        if not rhino_objects: return 0
        if len(rhino_objects)==1:
            rhino_object = rhino_objects[0]
            rhino_objects = None
    if name is None: #get the name
        if rhino_objects: raise Exception("name required when object_id represents multiple objects")
        return rhino_object.Name
    if rhino_objects:
        for rh_obj in rhino_objects:
            attr = rh_obj.Attributes
            attr.Name = name
            scriptcontext.doc.Objects.ModifyAttributes(rh_obj, attr, True)
        return len(rhino_objects)
    rc = rhino_object.Name
    if not type(name) is str: name = str(name)
    rhino_object.Attributes.Name = name
    rhino_object.CommitChanges()
    return rc


def ObjectPrintColor(object_ids, color=None):
    """Returns or modifies the print color of an object
    Parameters:
      object_ids ([guid, ...]): identifiers of object(s)
      color (color, optional): new print color. If omitted, the current color is returned.
    Returns:
      color: If color is not specified, the object's current print color
      color: If color is specified, the object's previous print color
      number: If object_ids is a list or tuple, the number of objects modified
    Example:
      import rhinoscriptsyntax as rs
      objects = rs.GetObjects("Select objects to change print color")
      if objects:
          color = rs.GetColor()
          if color:
              for object in objects: rs.ObjectPrintColor(object, color)
    See Also:
      ObjectPrintColorSource
    """
    id = rhutil.coerceguid(object_ids, False)
    if id:
        rhino_object = rhutil.coercerhinoobject(id, True, True)
        rc = rhino_object.Attributes.PlotColor
        if color:
            rhino_object.Attributes.PlotColorSource = Rhino.DocObjects.ObjectPlotColorSource.PlotColorFromObject
            rhino_object.Attributes.PlotColor = rhutil.coercecolor(color, True)
            rhino_object.CommitChanges()
            scriptcontext.doc.Views.Redraw()
        return rc
    for id in object_ids:
        color = rhutil.coercecolor(color, True)
        rhino_object = rhutil.coercerhinoobject(id, True, True)
        rhino_object.Attributes.PlotColorSource = Rhino.DocObjects.ObjectPlotColorSource.PlotColorFromObject
        rhino_object.Attributes.PlotColor = color
        rhino_object.CommitChanges()
    scriptcontext.doc.Views.Redraw()
    return len(object_ids)


def ObjectPrintColorSource(object_ids, source=None):
    """Returns or modifies the print color source of an object
    Parameters:
      object_ids ([guid, ...]): identifiers of object(s)
      source (number, optional): new print color source
        0 = print color by layer
        1 = print color by object
        3 = print color by parent
    Returns:
      number: If source is not specified, the object's current print color source
      number: If source is specified, the object's previous print color source
      number: If object_ids is a list or tuple, the number of objects modified
    Example:
      import rhinoscriptsyntax as rs
      objects = rs.GetObjects("Select objects to reset print color source")
      if objects:
          for object in objects: rs.ObjectPrintColorSource(object, 0)
    See Also:
      ObjectPrintColor
    """
    id = rhutil.coerceguid(object_ids, False)
    if id:
        rhino_object = rhutil.coercerhinoobject(id, True, True)
        rc = int(rhino_object.Attributes.PlotColorSource)
        if source is not None:
            rhino_object.Attributes.PlotColorSource = System.Enum.ToObject(Rhino.DocObjects.ObjectPlotColorSource, source)
            rhino_object.CommitChanges()
            scriptcontext.doc.Views.Redraw()
        return rc
    for id in object_ids:
        rhino_object = rhutil.coercerhinoobject(id, True, True)
        rhino_object.Attributes.PlotColorSource = System.Enum.ToObject(Rhino.DocObjects.ObjectPlotColorSource, source)
        rhino_object.CommitChanges()
    scriptcontext.doc.Views.Redraw()
    return len(object_ids)


def ObjectPrintWidth(object_ids, width=None):
    """Returns or modifies the print width of an object
    Parameters:
      object_ids ([guid, ...]): identifiers of object(s)
      width (number, optional): new print width value in millimeters, where width=0 means use
        the default width, and width<0 means do not print (visible for screen display,
        but does not show on print). If omitted, the current width is returned.
    Returns:
      number: If width is not specified, the object's current print width
      number: If width is specified, the object's previous print width
      number: If object_ids is a list or tuple, the number of objects modified
    Example:
      import rhinoscriptsyntax as rs
      objs = rs.GetObjects("Select objects to change print width")
      if objs:
          for obj in objs: rs.ObjectPrintWidth(obj,0.5)
    See Also:
      ObjectPrintWidthSource
    """
    id = rhutil.coerceguid(object_ids, False)
    if id:
        rhino_object = rhutil.coercerhinoobject(id, True, True)
        rc = rhino_object.Attributes.PlotWeight
        if width is not None:
            rhino_object.Attributes.PlotWeightSource = Rhino.DocObjects.ObjectPlotWeightSource.PlotWeightFromObject
            rhino_object.Attributes.PlotWeight = width
            rhino_object.CommitChanges()
            scriptcontext.doc.Views.Redraw()
        return rc
    for id in object_ids:
        rhino_object = rhutil.coercerhinoobject(id, True, True)
        rhino_object.Attributes.PlotWeightSource = Rhino.DocObjects.ObjectPlotWeightSource.PlotWeightFromObject
        rhino_object.Attributes.PlotWeight = width
        rhino_object.CommitChanges()
    scriptcontext.doc.Views.Redraw()
    return len(object_ids)


def ObjectPrintWidthSource(object_ids, source=None):
    """Returns or modifies the print width source of an object
    Parameters:
      object_ids ([guid, ...]): identifiers of object(s)
      source (number, optional): new print width source
        0 = print width by layer
        1 = print width by object
        3 = print width by parent
    Returns:
      number: If source is not specified, the object's current print width source
      number: If source is specified, the object's previous print width source
      number: If object_ids is a list or tuple, the number of objects modified
    Example:
      import rhinoscriptsyntax as rs
      objects = rs.GetObjects("Select objects to reset print width source")
      if objects:
          for obj in objects: rs.ObjectPrintWidthSource(obj,0)
    See Also:
      ObjectPrintColor
    """
    id = rhutil.coerceguid(object_ids, False)
    if id:
        rhino_object = rhutil.coercerhinoobject(id, True, True)
        rc = int(rhino_object.Attributes.PlotWeightSource)
        if source is not None:
            rhino_object.Attributes.PlotWeightSource = System.Enum.ToObject(Rhino.DocObjects.ObjectPlotWeightSource, source)
            rhino_object.CommitChanges()
            scriptcontext.doc.Views.Redraw()
        return rc
    for id in object_ids:
        rhino_object = rhutil.coercerhinoobject(id, True, True)
        rhino_object.Attributes.PlotWeightSource = System.Enum.ToObject(Rhino.DocObjects.ObjectPlotWeightSource, source)
        rhino_object.CommitChanges()
    scriptcontext.doc.Views.Redraw()
    return len(object_ids)


def ObjectType(object_id):
    """Returns the object type
    Parameters:
      object_id (guid): identifier of an object
    Returns:
      number: The object type if successful.
        The valid object types are as follows:
        Value   Description
          0           Unknown object
          1           Point
          2           Point cloud
          4           Curve
          8           Surface or single-face brep
          16          Polysurface or multiple-face
          32          Mesh
          256         Light
          512         Annotation
          4096        Instance or block reference
          8192        Text dot object
          16384       Grip object
          32768       Detail
          65536       Hatch
          131072      Morph control
          262144      SubD
          134217728   Cage
          268435456   Phantom
          536870912   Clipping plane
          1073741824  Extrusion
    Example:
      import rhinoscriptsyntax as rs
      obj = rs.GetObject("Select object")
      if obj:
          objtype = rs.ObjectType(obj)
          print("Object type:{}".format(objtype))
    See Also:
      ObjectsByType
    """
    rhobj = rhutil.coercerhinoobject(object_id, True, True)
    geom = rhobj.Geometry
    if isinstance(geom, Rhino.Geometry.Brep) and geom.Faces.Count==1:
        return 8 #surface
    return int(geom.ObjectType)


def OrientObject(object_id, reference, target, flags=0):
    """Orients a single object based on input points.  

    If two 3-D points are specified, then this method will function similar to Rhino's Orient command.  If more than two 3-D points are specified, then the function will orient similar to Rhino's Orient3Pt command.

    The orient flags values can be added together to specify multiple options.
        Value   Description
        1       Copy object.  The default is not to copy the object.
        2       Scale object.  The default is not to scale the object.  Note, the scale option only applies if both reference and target contain only two 3-D points.

    Parameters:
        object_id (guid): The identifier of an object
        reference ([point, point, ...]): list of 3-D reference points.
        target  ([point, point, ...]): list of 3-D target points
        flags (number):  1 = copy object
                         2 = scale object
                         3 = copy and scale
    Returns:
      guid: The identifier of the oriented object if successful.
    Example:
      import rhinoscriptsyntax as rs
      obj = rs.GetObject("Select object to orient")
      if obj:
          reference = rs.GetPoints(message1="First reference point")
          if reference and len(reference)>0:
              target = rs.GetPoints(message1="First target point")
              if target and len(target)>0:
                  rs.OrientObject( obj, reference, target )
    See Also:
      
    """
    object_id = rhutil.coerceguid(object_id, True)
    from_array = rhutil.coerce3dpointlist(reference)
    to_array = rhutil.coerce3dpointlist(target)
    if from_array is None or to_array is None:
        raise ValueError("Could not convert reference or target to point list")
    from_count = len(from_array)
    to_count = len(to_array)
    if from_count<2 or to_count<2: raise Exception("point lists must have at least 2 values")

    copy = ((flags & 1) == 1)
    scale = ((flags & 2) == 2)
    xform_final = None
    if from_count>2 and to_count>2:
        #Orient3Pt
        from_plane = Rhino.Geometry.Plane(from_array[0], from_array[1], from_array[2])
        to_plane = Rhino.Geometry.Plane(to_array[0], to_array[1], to_array[2])
        if not from_plane.IsValid or not to_plane.IsValid:
            raise Exception("unable to create valid planes from point lists")
        xform_final = Rhino.Geometry.Transform.PlaneToPlane(from_plane, to_plane)
    else:
        #Orient2Pt
        xform_move = Rhino.Geometry.Transform.Translation( to_array[0]-from_array[0] )
        xform_scale = Rhino.Geometry.Transform.Identity
        v0 = from_array[1] - from_array[0]
        v1 = to_array[1] - to_array[0]
        if scale:
            len0 = v0.Length
            len1 = v1.Length
            if len0<0.000001 or len1<0.000001: raise Exception("vector lengths too short")
            scale = len1 / len0
            if abs(1.0-scale)>=0.000001:
                plane = Rhino.Geometry.Plane(from_array[0], v0)
                xform_scale = Rhino.Geometry.Transform.Scale(plane, scale, scale, scale)
        v0.Unitize()
        v1.Unitize()
        xform_rotate = Rhino.Geometry.Transform.Rotation(v0, v1, from_array[0])
        xform_final = xform_move * xform_scale * xform_rotate
    rc = scriptcontext.doc.Objects.Transform(object_id, xform_final, not copy)
    if rc==System.Guid.Empty: return scriptcontext.errorhandler()
    scriptcontext.doc.Views.Redraw()
    return rc


def RotateObject(object_id, center_point, rotation_angle, axis=None, copy=False):
    """Rotates a single object
    Parameters:
      object_id (guid): The identifier of an object to rotate
      center_point (point): the center of rotation
      rotation_angle (number): in degrees
      axis (plane, optional): axis of rotation, If omitted, the Z axis of the active
        construction plane is used as the rotation axis
      copy (bool, optional): copy the object
    Returns:
      guid: Identifier of the rotated object if successful
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      obj = rs.GetObject("Select object to rotate")
      if obj:
          point = rs.GetPoint("Center point of rotation")
          if point: rs.RotateObject(obj, point, 45.0, None, copy=True)
    See Also:
      RotateObjects
    """
    rc = RotateObjects(object_id, center_point, rotation_angle, axis, copy)
    if rc: return rc[0]
    return scriptcontext.errorhandler()


def RotateObjects( object_ids, center_point, rotation_angle, axis=None, copy=False):
    """Rotates multiple objects
    Parameters:
      object_ids ([guid, ...]): Identifiers of objects to rotate
      center_point (point): the center of rotation
      rotation_angle (number): in degrees
      axis (plane, optional): axis of rotation, If omitted, the Z axis of the active
        construction plane is used as the rotation axis
      copy (bool, optional): copy the object
    Returns:
      list(guid, ...): identifiers of the rotated objects if successful
    Example:
      import rhinoscriptsyntax as rs
      objs = rs.GetObjects("Select objects to rotate")
      if objs:
          point = rs.GetPoint("Center point of rotation")
          if point:
              rs.RotateObjects( objs, point, 45.0, None, True )
    See Also:
      RotateObject
    """
    center_point = rhutil.coerce3dpoint(center_point, True)
    if not axis:
        viewTable = scriptcontext.doc.Views
        activeView = None
        if viewTable is not None:
            activeView = viewTable.ActiveView
        if activeView is not None:
            axis = scriptcontext.doc.Views.ActiveView.ActiveViewport.ConstructionPlane().Normal
        else:
            axis = Rhino.Geometry.Vector3d(0,0,1)
    axis = rhutil.coerce3dvector(axis, True)
    rotation_angle = Rhino.RhinoMath.ToRadians(rotation_angle)
    xf = Rhino.Geometry.Transform.Rotation(rotation_angle, axis, center_point)
    rc = TransformObjects(object_ids, xf, copy)
    return rc


def ScaleObject(object_id, origin, scale, copy=False):
    """Scales a single object. Can be used to perform a uniform or non-uniform
    scale transformation. Scaling is based on the active construction plane.
    Parameters:
      object_id (guid): The identifier of an object
      origin (point): the origin of the scale transformation
      scale ([number, number, number]): three numbers that identify the X, Y, and Z axis scale factors to apply
      copy (bool, optional): copy the object
    Returns:
      guid: Identifier of the scaled object if successful
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      obj = rs.GetObject("Select object to scale")
      if obj:
          origin = rs.GetPoint("Origin point")
          if origin:
              rs.ScaleObject( obj, origin, (1,2,3), True )
    See Also:
      ScaleObjects
    """
    rc = ScaleObjects(object_id, origin, scale, copy )
    if rc: return rc[0]
    return scriptcontext.errorhandler()


def ScaleObjects(object_ids, origin, scale, copy=False):
    """Scales one or more objects. Can be used to perform a uniform or non-
    uniform scale transformation. Scaling is based on the active construction plane.
    Parameters:
      object_ids ([guid, ...]): Identifiers of objects to scale
      origin (point): the origin of the scale transformation
      scale ([number, number, number]): three numbers that identify the X, Y, and Z axis scale factors to apply
      copy (bool, optional): copy the objects
    Returns:
      list(guid, ...): identifiers of the scaled objects if successful
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      objs = rs.GetObjects("Select objects to scale")
      if objs:
          origin = rs.GetPoint("Origin point")
          if origin:
              rs.ScaleObjects( objs, origin, (2,2,2), True )
    See Also:
      ScaleObject
    """
    origin = rhutil.coerce3dpoint(origin, True)
    scale = rhutil.coerce3dpoint(scale, True)
    plane = scriptcontext.doc.Views.ActiveView.ActiveViewport.ConstructionPlane()
    plane.Origin = origin
    xf = Rhino.Geometry.Transform.Scale(plane, scale.X, scale.Y, scale.Z)
    rc = TransformObjects(object_ids, xf, copy)
    return rc


def SelectObject(object_id, redraw=True):
    """Selects a single object
    Parameters:
      object_id (guid): the identifier of the object to select
    Returns:
      bool: True on success
    Example:
      import rhinoscriptsyntax as rs
      rs.Command( "Line 0,0,0 5,5,0" )
      id = rs.FirstObject()
      if id: rs.SelectObject(id)
      # Do something here...
      rs.UnselectObject(id)
    See Also:
      IsObjectSelectable
      IsObjectSelected
      SelectObjects
      UnselectObject
      UnselectObjects
    """
    rhobj = rhutil.coercerhinoobject(object_id, True, True)
    rhobj.Select(True)
    if redraw: scriptcontext.doc.Views.Redraw()
    return True


def SelectObjects( object_ids):
    """Selects one or more objects
    Parameters:
      object_ids ([guid, ...]): identifiers of the objects to select
    Returns:
      number: number of selected objects
    Example:
      import rhinoscriptsyntax as rs
      ids = rs.GetObjects("Select object to copy in-place")
      if ids:
          rs.UnselectObjects(ids)
          copies = rs.CopyObjects(ids)
          if copies: rs.SelectObjects(copies)
    See Also:
      IsObjectSelectable
      IsObjectSelected
      SelectObject
      UnselectObject
      UnselectObjects
    """
    id = rhutil.coerceguid(object_ids, False)
    if id: object_ids = [id]
    rc = 0
    for id in object_ids:
        if SelectObject(id, False)==True: rc += 1
    if rc > 0: scriptcontext.doc.Views.Redraw()
    return rc


def ShearObject(object_id, origin, reference_point, angle_degrees, copy=False):
    """Perform a shear transformation on a single object
    Parameters:
      object_id (guid, ...): The identifier of an object
      origin, reference_point (point) origin/reference point of the shear transformation
      copy (bool, optional): copy the objects
    Returns:
      guid: Identifier of the sheared object if successful
      None: on error
    Example:
      import rhinoscriptsyntax as rs
      obj = rs.GetObject("Select object to shear")
      if obj:
          origin = rs.GetPoint("Origin point")
          refpt = rs.GetPoint("Reference point")
          if origin and refpt:
              rs.ShearObject(obj, origin, refpt, 45.0, True)
    See Also:
      ShearObjects
    """
    rc = ShearObjects(object_id, origin, reference_point, angle_degrees, copy)
    if rc: return rc[0]


def ShearObjects(object_ids, origin, reference_point, angle_degrees, copy=False):
    """Shears one or more objects
    Parameters:
      object_ids ([guid, ...]): The identifiers objects to shear
      origin, reference_point (point): origin/reference point of the shear transformation
      copy (bool, optional): copy the objects
    Returns:
      list(guid, ...]): identifiers of the sheared objects if successful
    Example:
      import rhinoscriptsyntax as rs
      object_ids = rs.GetObjects("Select objects to shear")
      if object_ids:
          origin = rs.GetPoint("Origin point")
          refpt = rs.GetPoint("Reference point")
          if origin and refpt:
              rs.ShearObjects( object_ids, origin, refpt, 45.0, True )
    See Also:
      ShearObject
    """
    origin = rhutil.coerce3dpoint(origin, True)
    reference_point = rhutil.coerce3dpoint(reference_point, True)
    if (origin-reference_point).IsTiny(): return None
    plane = scriptcontext.doc.Views.ActiveView.MainViewport.ConstructionPlane()
    frame = Rhino.Geometry.Plane(plane)
    frame.Origin = origin
    frame.ZAxis = plane.Normal
    yaxis = reference_point-origin
    yaxis.Unitize()
    frame.YAxis = yaxis
    xaxis = Rhino.Geometry.Vector3d.CrossProduct(frame.ZAxis, frame.YAxis)
    xaxis.Unitize()
    frame.XAxis = xaxis

    world_plane = Rhino.Geometry.Plane.WorldXY
    cob = Rhino.Geometry.Transform.ChangeBasis(world_plane, frame)
    shear2d = Rhino.Geometry.Transform.Identity
    shear2d[0,1] = math.tan(math.radians(angle_degrees))
    cobinv = Rhino.Geometry.Transform.ChangeBasis(frame, world_plane)
    xf = cobinv * shear2d * cob
    rc = TransformObjects(object_ids, xf, copy)
    return rc


def ShowObject(object_id):
    """Shows a previously hidden object. Hidden objects are not visible, cannot
    be snapped to and cannot be selected
    Parameters:
      object_id (guid): representing id of object to show
    Returns:
      bool: True of False indicating success or failure
    Example:
      import rhinoscriptsyntax as rs
      obj = rs.GetObject("Select object to hide")
      if obj: rs.HideObject(obj)
      # Do something here...
      rs.ShowObject( obj )
    See Also:
      HideObject
      HideObjects
      IsObjectHidden
      ShowObjects
    """
    return ShowObjects(object_id)==1


def ShowObjects(object_ids):
    """Shows one or more objects. Hidden objects are not visible, cannot be
    snapped to and cannot be selected
    Parameters:
      object_ids ([guid, ...]): ids of objects to show
    Returns:
      number: Number of objects shown
    Example:
      import rhinoscriptsyntax as rs
      objs = rs.GetObjects("Select objects to hide")
      if objs: rs.HideObjects(objs)
      #Do something here...
      rs.ShowObjects( objs )
    See Also:
      HideObject
      HideObjects
      IsObjectHidden
      ShowObject
    """
    id = rhutil.coerceguid(object_ids, False)
    if id: object_ids = [id]
    rc = 0
    for id in object_ids:
        id = rhutil.coerceguid(id, True)
        if scriptcontext.doc.Objects.Show(id, False): rc += 1
    if rc: scriptcontext.doc.Views.Redraw()
    return rc


def TransformObject(object_id, matrix, copy=False):
    """Moves, scales, or rotates an object given a 4x4 transformation matrix.
    The matrix acts on the left.
    Parameters:
      object (guid): The identifier of the object.
      matrix (transform): The transformation matrix (4x4 array of numbers).
      copy (bool, optional): Copy the object.
    Returns:
      (guid): The identifier of the transformed object
      None: if not successful, or on error
    Example:
      # Rotate an object by theta degrees about the world Z axis
      import math
      import rhinoscriptsyntax as rs
      degrees = 90.0 # Some angle
      radians = math.radians(degrees)
      c = math.cos(radians)
      s = math.sin(radians)
      matrix = []
      matrix.append( [c,-s, 0, 0] )
      matrix.append( [s, c, 0, 0] )
      matrix.append( [0, 0, 1, 0] )
      matrix.append( [0, 0, 0, 1] )
      obj = rs.GetObject("Select object to rotate")
      if obj: rs.TransformObject( obj, matrix )
    See Also:
      TransformObjects
    """
    rc = TransformObjects(object_id, matrix, copy)
    if rc: return rc[0]
    return scriptcontext.errorhandler()


# this is also called by Copy, Scale, Mirror, Move, and Rotate functions defined above
def TransformObjects(object_ids, matrix, copy=False):
    """Moves, scales, or rotates a list of objects given a 4x4 transformation
    matrix. The matrix acts on the left.
    Parameters:
      object_ids [(guid, ...}): List of object identifiers.
      matrix (transform): The transformation matrix (4x4 array of numbers).
      copy (bool, optional): Copy the objects
    Returns:
      list(guid, ...): ids identifying the newly transformed objects
    Example:
      import rhinoscriptsyntax as rs
      # Translate (move) objects by (10,10,0)
      xform = rs.XformTranslation([10,10,0])
      objs = rs.GetObjects("Select objects to translate")
      if objs: rs.TransformObjects(objs, xform)
    See Also:
      TransformObject
    """
    xform = rhutil.coercexform(matrix, True)
    id = rhutil.coerceguid(object_ids, False)
    if id: object_ids = [id]
    elif isinstance(object_ids, Rhino.Geometry.GeometryBase): object_ids = [object_ids]
    elif type(object_ids) in __ALLOWED_TRANSFORM_TYPES: object_ids = [object_ids]
    rc = []
    for object_id in object_ids:
        id = System.Guid.Empty
        old_id = rhutil.coerceguid(object_id, False)
        if old_id:
            id = scriptcontext.doc.Objects.Transform(old_id, xform, not copy)
        elif isinstance(object_id, Rhino.Geometry.GeometryBase):
            if copy: object_id = object_id.Duplicate()
            if not object_id.Transform(xform): raise Exception("Cannot apply transform to geometry.")
            id = scriptcontext.doc.Objects.Add(object_id)
        else:
            type_of_id = type(object_id)
            if type_of_id in __ALLOWED_TRANSFORM_TYPES:
                if copy: object_id = System.ICloneable.Clone(object_id)
                if object_id.Transform(xform) == False: #some of the Transform methods return bools, others have no return
                    raise Exception("Cannot apply transform to geometry.")
                ot = scriptcontext.doc.Objects
                fs = [ot.AddPoint,ot.AddLine,ot.AddRectangle,ot.AddCircle,ot.AddEllipse,ot.AddArc,ot.AddPolyline,ot.AddBox,ot.AddSphere]
                t_index = __ALLOWED_TRANSFORM_TYPES.index(type_of_id)
                id = fs[t_index](object_id)
            else:
                raise Exception("The {0} cannot be tranformed. A Guid or geometry types are expected.".format(type_of_id))
        if id!=System.Guid.Empty: rc.append(id)
    if rc: scriptcontext.doc.Views.Redraw()
    return rc


def UnlockObject(object_id):
    """Unlocks an object. Locked objects are visible, and can be snapped to,
    but they cannot be selected.
    Parameters:
      object_id (guid): The identifier of an object
    Returns:
      bool: True or False indicating success or failure
    Example:
      import rhinoscriptsyntax as rs
      obj = rs.GetObject("Select object to lock")
      if obj: rs.LockObject(obj)
      #Do something here...
      rs.UnlockObject( obj )
    See Also:
      IsObjectLocked
      LockObject
      LockObjects
      UnlockObjects
    """
    return UnlockObjects(object_id)==1


def UnlockObjects(object_ids):
    """Unlocks one or more objects. Locked objects are visible, and can be
    snapped to, but they cannot be selected.
    Parameters:
      object_ids ([guid, ...]): The identifiers of objects
    Returns:
      number: number of objects unlocked
    Example:
      import rhinoscriptsyntax as rs
      objs = rs.GetObjects("Select objects to lock")
      if objs: rs.LockObjects(objs)
      #Do something here...
      rs.UnlockObjects( objs )
    See Also:
      IsObjectLocked
      LockObject
      LockObjects
      UnlockObject
    """
    id = rhutil.coerceguid(object_ids, False)
    if id: object_ids = [id]
    rc = 0
    for id in object_ids:
        id = rhutil.coerceguid(id, True)
        if scriptcontext.doc.Objects.Unlock(id, False): rc += 1
    if rc: scriptcontext.doc.Views.Redraw()
    return rc


def UnselectObject(object_id):
    """Unselects a single selected object
    Parameters:
      object_id: (guid): id of object to unselect
    Returns:
      bool: True of False indicating success or failure
    Example:
      import rhinoscriptsyntax as rs
      rs.Command("Line 0,0,0 5,5,0")
      obj = rs.FirstObject()
      if obj: rs.SelectObject(obj)
      #Do something here...
      rs.UnselectObject( obj )
    See Also:
      IsObjectSelected
      SelectObject
      SelectObjects
      UnselectObjects
    """
    return UnselectObjects(object_id)==1


def UnselectObjects(object_ids):
    """Unselects one or more selected objects.
    Parameters:
      object_ids ([guid, ...]): identifiers of the objects to unselect.
    Returns:
      number: The number of objects unselected
    Example:
      import rhinoscriptsyntax as rs
      objects = rs.GetObjects("Select object to copy in-place")
      if objects:
          rs.UnselectObjects(objects)
          copies= rs.CopyObjects(objects)
          if copies: rs.SelectObjects(copies)
    See Also:
      IsObjectSelected
      SelectObject
      SelectObjects
      UnselectObject
    """
    id = rhutil.coerceguid(object_ids, False)
    if id: object_ids = [id]
    count = len(object_ids)
    for id in object_ids:
        obj = rhutil.coercerhinoobject(id, True, True)
        obj.Select(False)
    if count: scriptcontext.doc.Views.Redraw()
    return count

```
Page 5/7FirstPrevNextLast