#
tokens: 47221/50000 3/82 files (page 5/8)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 5 of 8. Use http://codebase.md/jingcheng-chen/rhinomcp?lines=true&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/selection.py:
--------------------------------------------------------------------------------

```python
   1 | import System.Drawing
   2 | 
   3 | import Rhino
   4 | 
   5 | import scriptcontext
   6 | 
   7 | import rhinocompat as compat
   8 | from rhinoscript import utility as rhutil
   9 | from rhinoscript import application as rhapp
  10 | from rhinoscript.layer import __getlayer
  11 | from rhinoscript.view import __viewhelper
  12 | 
  13 | 
  14 | class filter:
  15 |     allobjects = 0
  16 |     point = 1
  17 |     pointcloud = 2
  18 |     curve = 4
  19 |     surface = 8
  20 |     polysurface = 16
  21 |     mesh = 32
  22 |     light = 256
  23 |     annotation = 512
  24 |     instance = 4096
  25 |     textdot = 8192
  26 |     grip = 16384
  27 |     detail = 32768
  28 |     hatch = 65536
  29 |     morph = 131072
  30 |     subd = 262144
  31 |     cage = 134217728
  32 |     phantom = 268435456
  33 |     clippingplane = 536870912
  34 |     extrusion = 1073741824
  35 | 
  36 | 
  37 | def AllObjects(select=False, include_lights=False, include_grips=False, include_references=False):
  38 |     """Returns identifiers of all objects in the document.
  39 |     Parameters:
  40 |       select(bool, optional): Select the objects
  41 |       include_lights (bool, optional): Include light objects
  42 |       include_grips (bool, optional): Include grips objects
  43 |     Returns:
  44 |       list(guid, ...): identifiers for all the objects in the document
  45 |     Example:
  46 |       import rhinoscriptsyntax as rs
  47 |       objs = rs.AllObjects()
  48 |       for obj in objs: print("Object identifier: {}".format(obj))
  49 |     See Also:
  50 |       HiddenObjects
  51 |       LockedObjects
  52 |       NormalObjects
  53 |     """
  54 |     it = Rhino.DocObjects.ObjectEnumeratorSettings()
  55 |     it.IncludeLights = include_lights
  56 |     it.IncludeGrips = include_grips
  57 |     it.NormalObjects = True
  58 |     it.LockedObjects = True
  59 |     it.HiddenObjects = True
  60 |     it.ReferenceObjects = include_references
  61 |     e = scriptcontext.doc.Objects.GetObjectList(it)
  62 |     object_ids = []
  63 |     for object in e:
  64 |         if select: object.Select(True)
  65 |         object_ids.append(object.Id)
  66 |     if object_ids and select: scriptcontext.doc.Views.Redraw()
  67 |     return object_ids
  68 | 
  69 | 
  70 | def FirstObject(select=False, include_lights=False, include_grips=False):
  71 |     """Returns identifier of the first object in the document. The first
  72 |     object is the last object created by the user.
  73 |     Parameters:
  74 |       select (bool, optional): Select the object.  If omitted (False), the object is not selected.
  75 |       include_lights (bool, optional): Include light objects.  If omitted (False), light objects are not returned.
  76 |       include_grips (bool, optional): Include grips objects.  If omitted (False), grips objects are not returned.
  77 |     Returns:
  78 |       guid: The identifier of the object if successful.
  79 |     Example:
  80 |       import rhinoscriptsyntax as rs
  81 |       rs.AddLine( (0,0,0), (5,5,0) )
  82 |       rs.AddLine( (0,0,0), (5,0,0) )
  83 |       rs.AddLine( (0,0,0), (0,5,0) )
  84 |       objectId = rs.FirstObject()
  85 |       print("Object identifier: {}".format(objectId))
  86 |       rs.SelectObject(objectId)
  87 |     See Also:
  88 |       LastObject
  89 |       NextObject
  90 |     """
  91 |     it = Rhino.DocObjects.ObjectEnumeratorSettings()
  92 |     it.IncludeLights = include_lights
  93 |     it.IncludeGrips = include_grips
  94 |     e = scriptcontext.doc.Objects.GetObjectList(it).GetEnumerator()
  95 |     if not e.MoveNext(): return None
  96 |     object = e.Current
  97 |     if object:
  98 |         if select: object.Select(True)
  99 |         return object.Id
 100 | 
 101 | 
 102 | def __FilterHelper(input_filter):
 103 |     geometry_filter = compat.ENUM_NONE(Rhino.DocObjects.ObjectType)
 104 |     if input_filter & 1:
 105 |         geometry_filter |= Rhino.DocObjects.ObjectType.Point
 106 |     if input_filter & 16384:
 107 |         geometry_filter |= Rhino.DocObjects.ObjectType.Grip
 108 |     if input_filter & 2:
 109 |         geometry_filter |= Rhino.DocObjects.ObjectType.PointSet
 110 |     if input_filter & 4:
 111 |         geometry_filter |= Rhino.DocObjects.ObjectType.Curve
 112 |     if input_filter & 8:
 113 |         geometry_filter |= Rhino.DocObjects.ObjectType.Surface
 114 |     if input_filter & 16:
 115 |         geometry_filter |= Rhino.DocObjects.ObjectType.Brep
 116 |     if input_filter & 32:
 117 |         geometry_filter |= Rhino.DocObjects.ObjectType.Mesh
 118 |     if input_filter & 512:
 119 |         geometry_filter |= Rhino.DocObjects.ObjectType.Annotation
 120 |     if input_filter & 256:
 121 |         geometry_filter |= Rhino.DocObjects.ObjectType.Light
 122 |     if input_filter & 4096:
 123 |         geometry_filter |= Rhino.DocObjects.ObjectType.InstanceReference
 124 |     if input_filter & 134217728:
 125 |         geometry_filter |= Rhino.DocObjects.ObjectType.Cage
 126 |     if input_filter & 65536:
 127 |         geometry_filter |= Rhino.DocObjects.ObjectType.Hatch
 128 |     if input_filter & 131072:
 129 |         geometry_filter |= Rhino.DocObjects.ObjectType.MorphControl
 130 |     if input_filter & 262144:
 131 |         geometry_filter |= Rhino.DocObjects.ObjectType.SubD
 132 |     if input_filter & 2097152:
 133 |         geometry_filter |= Rhino.DocObjects.ObjectType.PolysrfFilter
 134 |     if input_filter & 268435456:
 135 |         geometry_filter |= Rhino.DocObjects.ObjectType.Phantom
 136 |     if input_filter & 8192:
 137 |         geometry_filter |= Rhino.DocObjects.ObjectType.TextDot
 138 |     if input_filter & 32768:
 139 |         geometry_filter |= Rhino.DocObjects.ObjectType.Detail
 140 |     if input_filter & 536870912:
 141 |         geometry_filter |= Rhino.DocObjects.ObjectType.ClipPlane
 142 |     if input_filter & 1073741824:
 143 |         geometry_filter |= Rhino.DocObjects.ObjectType.Extrusion
 144 |     return geometry_filter
 145 | 
 146 | 
 147 | def GetCurveObject(message=None, preselect=False, select=False):
 148 |     """Prompts user to pick or select a single curve object
 149 |     Parameters:
 150 |       message (str, optional): a prompt or message.
 151 |       preselect (bool,, optional): Allow for the selection of pre-selected objects.
 152 |       select (bool, optional): Select the picked objects. If False, objects that
 153 |         are picked are not selected.
 154 |     Returns:
 155 |       Tuple containing the following information
 156 |         [0]  guid     identifier of the curve object
 157 |         [1]  bool     True if the curve was preselected, otherwise False
 158 |         [2]  number   selection method
 159 |                          0 = selected by non-mouse method (SelAll, etc.).
 160 |                          1 = selected by mouse click on the object.
 161 |                          2 = selected by being inside of a mouse window.
 162 |                          3 = selected by intersecting a mouse crossing window.
 163 |         [3]  point    selection point
 164 |         [4]  number   the curve parameter of the selection point
 165 |         [5]  str      name of the view selection was made
 166 |       None: if no object picked
 167 |     Example:
 168 |       import rhinoscriptsyntax as rs
 169 |       select_result = rs.GetCurveObject("Select curve")
 170 |       if select_result:
 171 |           print("Curve identifier: {}".format(select_result[0]))
 172 |     See Also:
 173 |       GetObject
 174 |       GetObjects
 175 |       GetSurfaceObject
 176 |     """
 177 |     if not preselect:
 178 |         scriptcontext.doc.Objects.UnselectAll()
 179 |         scriptcontext.doc.Views.Redraw()
 180 |     go = Rhino.Input.Custom.GetObject()
 181 |     if message: go.SetCommandPrompt(message)
 182 |     go.GeometryFilter = Rhino.DocObjects.ObjectType.Curve
 183 |     go.SubObjectSelect = False
 184 |     go.GroupSelect = False
 185 |     go.AcceptNothing(True)
 186 |     if go.Get()!=Rhino.Input.GetResult.Object: return None
 187 |  
 188 |     objref = go.Object(0)
 189 |     id = objref.ObjectId
 190 |     presel = go.ObjectsWerePreselected
 191 |     selmethod = 0
 192 |     sm = objref.SelectionMethod()
 193 |     if Rhino.DocObjects.SelectionMethod.MousePick==sm: selmethod = 1
 194 |     elif Rhino.DocObjects.SelectionMethod.WindowBox==sm: selmethod = 2
 195 |     elif Rhino.DocObjects.SelectionMethod.CrossingBox==sm: selmethod = 3
 196 |     point = objref.SelectionPoint()
 197 |     crv, curve_parameter = objref.CurveParameter()
 198 |     viewname = go.View().ActiveViewport.Name
 199 |     obj = go.Object(0).Object()
 200 |     go.Dispose()
 201 |     if not select and not presel:
 202 |         scriptcontext.doc.Objects.UnselectAll()
 203 |         scriptcontext.doc.Views.Redraw()
 204 |     obj.Select(select)
 205 |     return id, presel, selmethod, point, curve_parameter, viewname
 206 | 
 207 | 
 208 | def GetObject(message=None, filter=0, preselect=False, select=False, custom_filter=None, subobjects=False):
 209 |     """Prompts user to pick, or select, a single object.
 210 |     Parameters:
 211 |       message(str, optional): a prompt or message.
 212 |       filter (number, optional): The type(s) of geometry (points, curves, surfaces, meshes,...)
 213 |           that can be selected. Object types can be added together to filter
 214 |           several different kinds of geometry. use the filter class to get values
 215 |       preselect (bool, optional): Allow for the selection of pre-selected objects.
 216 |       select (bool, optional): Select the picked objects.  If False, the objects that are
 217 |           picked are not selected.
 218 |       subobjects (bool, optional): If True, subobjects can be selected. When this is the
 219 |           case, an ObjRef is returned instead of a Guid to allow for tracking
 220 |           of the subobject when passed into other functions
 221 |     Returns:
 222 |       guid: Identifier of the picked object
 223 |       None: if user did not pick an object
 224 |     Example:
 225 |       import rhinoscriptsyntax as rs
 226 |       objectId = rs.GetObject("Pick any object")
 227 |       if objectId:
 228 |           print("Object identifier: {}".format(objectId))
 229 |       objectId = rs.GetObject("Pick a curve or surface", rs.filter.curve | rs.filter.surface)
 230 |       if objectId:
 231 |           print("Object identifier: {}".format(objectId))
 232 |     See Also:
 233 |       GetCurveObject
 234 |       GetObjectEx
 235 |       GetObjects
 236 |       GetSurfaceObject
 237 |     """
 238 |     if not preselect:
 239 |         scriptcontext.doc.Objects.UnselectAll()
 240 |         scriptcontext.doc.Views.Redraw()
 241 |     
 242 |     class CustomGetObject(Rhino.Input.Custom.GetObject):
 243 |         def __init__(self, filter_function):
 244 |             super(CustomGetObject, self).__init__()
 245 |             self.m_filter_function = filter_function
 246 |         def CustomGeometryFilter( self, rhino_object, geometry, component_index ):
 247 |             rc = True
 248 |             if self.m_filter_function is not None:
 249 |                 try:
 250 |                     rc = self.m_filter_function(rhino_object, geometry, component_index)
 251 |                 except:
 252 |                     rc = True
 253 |             return rc
 254 |     go = CustomGetObject(custom_filter)
 255 |     if message: go.SetCommandPrompt(message)
 256 |     geometry_filter = __FilterHelper(filter)
 257 |     if filter>0: go.GeometryFilter = geometry_filter
 258 |     go.SubObjectSelect = subobjects
 259 |     go.GroupSelect = False
 260 |     go.AcceptNothing(True)      
 261 |     if go.Get()!=Rhino.Input.GetResult.Object: return None
 262 |     objref = go.Object(0)
 263 |     obj = objref.Object()
 264 |     presel = go.ObjectsWerePreselected
 265 |     go.Dispose()
 266 |     if not select and not presel:
 267 |         scriptcontext.doc.Objects.UnselectAll()
 268 |         scriptcontext.doc.Views.Redraw()
 269 |     if subobjects: return objref
 270 |     obj.Select(select)
 271 |     return obj.Id
 272 | 
 273 | 
 274 | class CustomGetObjectEx(Rhino.Input.Custom.GetObject):
 275 |     def __init__(self, allowable_geometry):
 276 |         super(CustomGetObjectEx, self).__init__()
 277 |         self.m_allowable = allowable_geometry
 278 |     def CustomGeometryFilter(self, rhino_object, geometry, component_index):
 279 |         for id in self.m_allowable:
 280 |             if id==rhino_object.Id: return True
 281 |         return False
 282 | 
 283 | 
 284 | def GetObjectEx(message=None, filter=0, preselect=False, select=False, objects=None):
 285 |     """Prompts user to pick, or select a single object
 286 |     Parameters:
 287 |       message (str, optional): a prompt or message.
 288 |       filter (number, optional): The type(s) of geometry (points, curves, surfaces, meshes,...)
 289 |           that can be selected. Object types can be added together to filter
 290 |           several different kinds of geometry. use the filter class to get values
 291 |       preselect (bool, optional):  Allow for the selection of pre-selected objects.
 292 |       select (bool, optional): Select the picked objects.  If False, the objects that are
 293 |           picked are not selected.
 294 |       objects ([guid, ...]): list of object identifiers specifying objects that are
 295 |           allowed to be selected
 296 |     Returns:
 297 |       tuple(guid, bool, number, point, str): containing the following information
 298 |           [0] identifier of the object
 299 |           [1] True if the object was preselected, otherwise False
 300 |           [2] selection method (see help)
 301 |           [3] selection point
 302 |           [4] name of the view selection was made
 303 |       None: if no object selected
 304 |     Example:
 305 |       import rhinoscriptsyntax as rs
 306 |       obj = rs.GetObjectEx("Select object", 0, True)
 307 |       if obj:
 308 |           print("Object id = {}".format(obj[0]))
 309 |           print("Object was preselected = {}".format(obj[1]))
 310 |           if obj[2]==0:
 311 |               print("Selection method = 0 (non-mouse)")
 312 |           elif obj[2]==1:
 313 |               print("Selection method = 1 (mouse)")
 314 |               print("Pick point = {}".format(obj[3]))
 315 |           elif obj[2]==2:
 316 |               print("Selection method = 2 (window)")
 317 |           elif obj[2]==3:
 318 |               print("Selection method = 3 (crossing)")
 319 |           print("Active view = {}".format(obj[4]))
 320 |     See Also:
 321 |       GetCurveObject
 322 |       GetObject
 323 |       GetObjects
 324 |       GetObjectsEx
 325 |       GetSurfaceObject
 326 |     """
 327 |     if not preselect:
 328 |         scriptcontext.doc.Objects.UnselectAll()
 329 |         scriptcontext.doc.Views.Redraw()
 330 |     go = None
 331 |     if objects:
 332 |         ids = [rhutil.coerceguid(id, True) for id in objects]
 333 |         if ids: go = CustomGetObjectEx(ids)
 334 |     if not go: go = Rhino.Input.Custom.GetObject()
 335 |     if message: go.SetCommandPrompt(message)
 336 |     geometry_filter = __FilterHelper(filter)
 337 |     if filter>0: go.GeometryFilter = geometry_filter
 338 |     go.SubObjectSelect = False
 339 |     go.GroupSelect = False
 340 |     go.AcceptNothing(True)      
 341 |     if go.Get()!=Rhino.Input.GetResult.Object: return None
 342 |     objref = go.Object(0)
 343 |     id = objref.ObjectId
 344 |     presel = go.ObjectsWerePreselected
 345 |     selmethod = 0
 346 |     sm = objref.SelectionMethod()
 347 |     if Rhino.DocObjects.SelectionMethod.MousePick==sm: selmethod = 1
 348 |     elif Rhino.DocObjects.SelectionMethod.WindowBox==sm: selmethod = 2
 349 |     elif Rhino.DocObjects.SelectionMethod.CrossingBox==sm: selmethod = 3
 350 |     point = objref.SelectionPoint()
 351 |     viewname = go.View().ActiveViewport.Name
 352 |     obj = go.Object(0).Object()
 353 |     go.Dispose()
 354 |     if not select and not presel:
 355 |         scriptcontext.doc.Objects.UnselectAll()
 356 |         scriptcontext.doc.Views.Redraw()
 357 |     obj.Select(select)
 358 |     return id, presel, selmethod, point, viewname
 359 | 
 360 | 
 361 | def GetObjects(message=None, filter=0, group=True, preselect=False, select=False, objects=None, minimum_count=1, maximum_count=0, custom_filter=None):
 362 |     """Prompts user to pick or select one or more objects.
 363 |     Parameters:
 364 |       message (str, optional): a prompt or message.
 365 |       filter (number, optional): The type(s) of geometry (points, curves, surfaces, meshes,...)
 366 |           that can be selected. Object types can be added together to filter
 367 |           several different kinds of geometry. use the filter class to get values
 368 |               Value         Description
 369 |               0             All objects (default)
 370 |               1             Point
 371 |               2             Point cloud
 372 |               4             Curve
 373 |               8             Surface or single-face brep
 374 |               16            Polysurface or multiple-face
 375 |               32            Mesh
 376 |               256           Light
 377 |               512           Annotation
 378 |               4096          Instance or block reference
 379 |               8192          Text dot object
 380 |               16384         Grip object
 381 |               32768         Detail
 382 |               65536         Hatch
 383 |               131072        Morph control
 384 |               262144        SubD
 385 |               134217728     Cage
 386 |               268435456     Phantom
 387 |               536870912     Clipping plane
 388 |               1073741824    Extrusion
 389 |       group (bool, optional): Honor object grouping.  If omitted and the user picks a group,
 390 |           the entire group will be picked (True). Note, if filter is set to a
 391 |           value other than 0 (All objects), then group selection will be disabled.
 392 |       preselect (bool, optional):  Allow for the selection of pre-selected objects.
 393 |       select (bool, optional): Select the picked objects.  If False, the objects that are
 394 |           picked are not selected.
 395 |       objects ([guid, ...]): list of objects that are allowed to be selected
 396 |       minimum_count, maximum_count(number): limits on number of objects allowed to be selected
 397 |       custom_filter (str, optional): Calls a custom function in the script and passes the Rhino Object, Geometry, and component index and returns true or false indicating if the object can be selected
 398 |     Returns:
 399 |       list(guid, ...): identifiers of the picked objects
 400 |     Example:
 401 |       import rhinoscriptsyntax as rs
 402 |       objectIds = rs.GetObjects("Pick some curves", rs.filter.curve)
 403 |       for id in objectIds: print("Object identifier:{}".format(id))
 404 |     See Also:
 405 |       GetCurveObject
 406 |       GetObject
 407 |       GetSurfaceObject
 408 |     """
 409 |     if not preselect:
 410 |         scriptcontext.doc.Objects.UnselectAll()
 411 |         scriptcontext.doc.Views.Redraw()
 412 | 
 413 |     objects = rhutil.coerceguidlist(objects)
 414 |     class CustomGetObject(Rhino.Input.Custom.GetObject):
 415 |         def __init__(self, filter_function):
 416 |             super(CustomGetObject, self).__init__()
 417 |             self.m_filter_function = filter_function
 418 |         def CustomGeometryFilter( self, rhino_object, geometry, component_index ):
 419 |             if objects and not rhino_object.Id in objects: return False
 420 |             rc = True
 421 |             if self.m_filter_function is not None:
 422 |                 try:
 423 |                     rc = self.m_filter_function(rhino_object, geometry, component_index)
 424 |                 except:
 425 |                     rc = True
 426 |             return rc
 427 |     go = CustomGetObject(custom_filter)
 428 |     go.SetCommandPrompt(message or "Select objects")
 429 |     geometry_filter = __FilterHelper(filter)
 430 |     if filter>0: go.GeometryFilter = geometry_filter
 431 |     go.SubObjectSelect = False
 432 |     go.GroupSelect = group
 433 |     go.AcceptNothing(True)
 434 |     if go.GetMultiple(minimum_count,maximum_count)!=Rhino.Input.GetResult.Object: return None
 435 |     if not select and not go.ObjectsWerePreselected:
 436 |         scriptcontext.doc.Objects.UnselectAll()
 437 |         scriptcontext.doc.Views.Redraw()
 438 |     rc = []
 439 |     count = go.ObjectCount
 440 |     for i in compat.RANGE(count):
 441 |         objref = go.Object(i)
 442 |         rc.append(objref.ObjectId)
 443 |         obj = objref.Object()
 444 |         if select and obj is not None: obj.Select(select)
 445 |     go.Dispose()
 446 |     return rc
 447 | 
 448 | 
 449 | def GetObjectsEx(message=None, filter=0, group=True, preselect=False, select=False, objects=None):
 450 |     """Prompts user to pick, or select one or more objects
 451 |     Parameters:
 452 |       message (str, optional):  a prompt or message.
 453 |       filter (number, optional): The type(s) of geometry (points, curves, surfaces, meshes,...)
 454 |           that can be selected. Object types can be added together to filter
 455 |           several different kinds of geometry. use the filter class to get values
 456 |       group (bool, optional): Honor object grouping.  If omitted and the user picks a group,
 457 |           the entire group will be picked (True). Note, if filter is set to a
 458 |           value other than 0 (All objects), then group selection will be disabled.
 459 |       preselect (bool, optional):  Allow for the selection of pre-selected objects.
 460 |       select (bool, optional): Select the picked objects. If False, the objects that are
 461 |           picked are not selected.
 462 |       objects ([guid, ...]): list of object identifiers specifying objects that are
 463 |           allowed to be selected
 464 |     Returns:
 465 |       list(tuple(guid, bool, number, point, str), ...): containing the following information
 466 |         [n][0]  identifier of the object
 467 |         [n][1]  True if the object was preselected, otherwise False
 468 |         [n][2]  selection method (see help)
 469 |         [n][3]  selection point
 470 |         [n][4]  name of the view selection was made
 471 |     Example:
 472 |       import rhinoscriptsyntax as rs
 473 |       objects = rs.GetObjectsEx("Select objects", 0, True)
 474 |       for obj in objects:
 475 |           print("Object id = {}".format(obj[0]))
 476 |           print("Object was preselected = {}".format(obj[1]))
 477 |           if obj[2]==0:
 478 |               print("Selection method = 0 (non-mouse)")
 479 |           elif obj[2]==1:
 480 |               print("Selection method = 1 (mouse)")
 481 |               print("Pick point = {}".format(obj[3]))
 482 |           elif obj[2]==2:
 483 |               print("Selection method = 2 (window)")
 484 |           elif obj[2]==3:
 485 |               print("Selection method = 3 (crossing)")
 486 |           print("Active view = {}".format(obj[4]))
 487 |     See Also:
 488 |       GetCurveObject
 489 |       GetObject
 490 |       GetObjectEx
 491 |       GetObjects
 492 |       GetSurfaceObject
 493 |     """
 494 |     if not preselect:
 495 |         scriptcontext.doc.Objects.UnselectAll()
 496 |         scriptcontext.doc.Views.Redraw()
 497 |     go = None
 498 |     if objects:
 499 |         ids = [rhutil.coerceguid(id) for id in objects]
 500 |         if ids: go = CustomGetObjectEx(ids)
 501 |     if not go: go = Rhino.Input.Custom.GetObject()
 502 |     go.SetCommandPrompt(message or "Select objects")
 503 |     geometry_filter = __FilterHelper(filter)
 504 |     if filter>0: go.GeometryFilter = geometry_filter
 505 |     go.SubObjectSelect = False
 506 |     go.GroupSelect = group
 507 |     go.AcceptNothing(True)      
 508 |     if go.GetMultiple(1,0)!=Rhino.Input.GetResult.Object: return []
 509 |     if not select and not go.ObjectsWerePreselected:
 510 |         scriptcontext.doc.Objects.UnselectAll()
 511 |         scriptcontext.doc.Views.Redraw()
 512 |     rc = []
 513 |     count = go.ObjectCount
 514 |     for i in compat.RANGE(count):
 515 |         objref = go.Object(i)
 516 |         id = objref.ObjectId
 517 |         presel = go.ObjectsWerePreselected
 518 |         selmethod = 0
 519 |         sm = objref.SelectionMethod()
 520 |         if Rhino.DocObjects.SelectionMethod.MousePick==sm: selmethod = 1
 521 |         elif Rhino.DocObjects.SelectionMethod.WindowBox==sm: selmethod = 2
 522 |         elif Rhino.DocObjects.SelectionMethod.CrossingBox==sm: selmethod = 3
 523 |         point = objref.SelectionPoint()
 524 |         viewname = go.View().ActiveViewport.Name
 525 |         rc.append( (id, presel, selmethod, point, viewname) )
 526 |         obj = objref.Object()
 527 |         if select and obj is not None: obj.Select(select)
 528 |     go.Dispose()
 529 |     return rc
 530 | 
 531 | 
 532 | def GetPointCoordinates(message="Select points", preselect=False):
 533 |     """Prompts the user to select one or more point objects.
 534 |     Parameters:
 535 |       message (str, optional): a prompt message.
 536 |       preselect (bool, optional): Allow for the selection of pre-selected objects.  If omitted (False), pre-selected objects are not accepted.
 537 |     Returns:
 538 |       list(point, ...): 3d coordinates of point objects on success
 539 |     Example:
 540 |       import rhinoscriptsyntax as rs
 541 |       points = rs.GetPointCoordinates()
 542 |       for point in points: print(point)
 543 |     See Also:
 544 |       GetObject
 545 |       GetObjects
 546 |       GetPoint
 547 |       GetPoints
 548 |       PointCoordinates
 549 |     """
 550 |     ids = GetObjects(message, filter.point, preselect=preselect)
 551 |     rc = []
 552 |     for id in ids:
 553 |         rhobj = scriptcontext.doc.Objects.Find(id)
 554 |         rc.append(rhobj.Geometry.Location)
 555 |     return rc
 556 | 
 557 | 
 558 | def GetSurfaceObject(message="Select surface", preselect=False, select=False):
 559 |     """Prompts the user to select a single surface
 560 |     Parameters:
 561 |       message(str, optional): prompt displayed
 562 |       preselect (bool, optional): allow for preselected objects
 563 |       select (bool, optional):  select the picked object
 564 |     Returns:
 565 |       tuple(guid, bool, number, point, (number, number), str): of information on success
 566 |         [0]  identifier of the surface
 567 |         [1]  True if the surface was preselected, otherwise False
 568 |         [2]  selection method ( see help )
 569 |         [3]  selection point
 570 |         [4]  u,v surface parameter of the selection point
 571 |         [5]  name of the view in which the selection was made
 572 |       None: on error
 573 |     Example:
 574 |       import rhinoscriptsyntax as rs
 575 |       select = rs.GetSurfaceObject("Select surface")
 576 |       if select:
 577 |           print("Surface identifier: {}".format(select[0]))
 578 |     See Also:
 579 |       GetCurveObject
 580 |       GetObject
 581 |       GetObjects
 582 |     """
 583 |     if not preselect:
 584 |         scriptcontext.doc.Objects.UnselectAll()
 585 |         scriptcontext.doc.Views.Redraw()
 586 |     go = Rhino.Input.Custom.GetObject()
 587 |     go.SetCommandPrompt(message)
 588 |     go.GeometryFilter = Rhino.DocObjects.ObjectType.Surface
 589 |     go.SubObjectSelect = False
 590 |     go.GroupSelect = False
 591 |     go.AcceptNothing(True)
 592 |     if go.Get()!=Rhino.Input.GetResult.Object:
 593 |         return scriptcontext.errorhandler()
 594 |     objref = go.Object(0)
 595 |     rhobj = objref.Object()
 596 |     rhobj.Select(select)
 597 |     scriptcontext.doc.Views.Redraw()
 598 | 
 599 |     id = rhobj.Id
 600 |     prepicked = go.ObjectsWerePreselected
 601 |     selmethod = objref.SelectionMethod()
 602 |     point = objref.SelectionPoint()
 603 |     surf, u, v = objref.SurfaceParameter()
 604 |     uv = (u,v)
 605 |     if not point.IsValid:
 606 |         point = None
 607 |         uv = None
 608 |     view = go.View()
 609 |     name = view.ActiveViewport.Name
 610 |     go.Dispose()
 611 |     if not select and not prepicked:
 612 |       scriptcontext.doc.Objects.UnselectAll()
 613 |       scriptcontext.doc.Views.Redraw()
 614 |     return id, prepicked, selmethod, point, uv, name
 615 | 
 616 | 
 617 | def LockedObjects(include_lights=False, include_grips=False, include_references=False):
 618 |     """Returns identifiers of all locked objects in the document. Locked objects
 619 |     cannot be snapped to, and cannot be selected
 620 |     Parameters:
 621 |       include_lights (bool, optional): include light objects
 622 |       include_grips (bool, optional): include grip objects
 623 |     Returns:
 624 |       list(guid, ...): identifiers the locked objects if successful.
 625 |     Example:
 626 |       import rhinoscriptsyntax as  rs
 627 |       objs = rs.LockedObjects()
 628 |       for obj in objs: print("Object  identifier:{}".format(obj))
 629 |     See Also:
 630 |       AllObjects
 631 |       HiddenObjects
 632 |       NormalObjects
 633 |     """
 634 |     settings = Rhino.DocObjects.ObjectEnumeratorSettings()
 635 |     settings.ActiveObjects = True
 636 |     settings.NormalObjects = True
 637 |     settings.LockedObjects = True
 638 |     settings.HiddenObjects = True
 639 |     settings.IncludeLights = include_lights
 640 |     settings.IncludeGrips = include_grips
 641 |     settings.ReferenceObjects = include_references
 642 |     return [i.Id for i in scriptcontext.doc.Objects.GetObjectList(settings)
 643 |         if i.IsLocked or (scriptcontext.doc.Layers[i.Attributes.LayerIndex]).IsLocked]
 644 | 
 645 | 
 646 | def HiddenObjects(include_lights=False, include_grips=False, include_references=False):
 647 |     """Returns identifiers of all hidden objects in the document. Hidden objects
 648 |     are not visible, cannot be snapped to, and cannot be selected
 649 |     Parameters:
 650 |       include_lights (bool, optional): include light objects
 651 |       include_grips (bool, optional): include grip objects
 652 |     Returns:
 653 |       list(guid, ...): identifiers of the hidden objects if successful.
 654 |     Example:
 655 |       import rhinoscriptsyntax as rs
 656 |       hidden = rs.HiddenObjects()
 657 |       for obj in hidden: print("Object identifier{}".format(obj))
 658 |     See Also:
 659 |       AllObjects
 660 |       LockedObjects
 661 |       NormalObjects
 662 |     """
 663 |     settings = Rhino.DocObjects.ObjectEnumeratorSettings()
 664 |     settings.ActiveObjects = True
 665 |     settings.NormalObjects = True
 666 |     settings.LockedObjects = True
 667 |     settings.HiddenObjects = True
 668 |     settings.IncludeLights = include_lights
 669 |     settings.IncludeGrips = include_grips
 670 |     settings.ReferenceObjects = include_references
 671 |     return [i.Id for i in scriptcontext.doc.Objects.GetObjectList(settings)
 672 |         if i.IsHidden or not (scriptcontext.doc.Layers[i.Attributes.LayerIndex]).IsVisible]
 673 | 
 674 | 
 675 | def InvertSelectedObjects(include_lights=False, include_grips=False, include_references=False):
 676 |     """Inverts the current object selection. The identifiers of the newly
 677 |     selected objects are returned
 678 |     Parameters:
 679 |       include_lights (bool, optional): Include light objects.  If omitted (False), light objects are not returned.
 680 |       include_grips (bool, optional): Include grips objects.  If omitted (False), grips objects are not returned.
 681 |       include_references (bool, optional): Include reference objects.  If omitted (False), reference objects are not returned.
 682 |     Returns:
 683 |       list(guid, ...): identifiers of the newly selected objects if successful.
 684 |     Example:
 685 |       import rhinoscriptsyntax as rs
 686 |       rs.GetObjects("Select some objects", select=True)
 687 |       objs = rs.InvertSelectedObjects()
 688 |       for id in objs: print("Object identifier:{}".format(id))
 689 |     See Also:
 690 |       SelectedObjects
 691 |       UnselectAllObjects
 692 |     """
 693 |     settings = Rhino.DocObjects.ObjectEnumeratorSettings()
 694 |     settings.IncludeLights = include_lights
 695 |     settings.IncludeGrips = include_grips
 696 |     settings.IncludePhantoms = True
 697 |     settings.ReferenceObjects = include_references
 698 |     rhobjs = scriptcontext.doc.Objects.GetObjectList(settings)
 699 |     rc = []
 700 |     for obj in rhobjs:
 701 |         if not obj.IsSelected(False) and obj.IsSelectable():
 702 |             rc.append(obj.Id)
 703 |             obj.Select(True)
 704 |         else:
 705 |             obj.Select(False)
 706 |     scriptcontext.doc.Views.Redraw()
 707 |     return rc
 708 | 
 709 | 
 710 | def LastCreatedObjects(select=False):
 711 |     """Returns identifiers of the objects that were most recently created or changed
 712 |     by scripting a Rhino command using the Command function. It is important to
 713 |     call this function immediately after calling the Command function as only the
 714 |     most recently created or changed object identifiers will be returned
 715 |     Parameters:
 716 |       select (bool, optional): Select the object.  If omitted (False), the object is not selected.
 717 |     Returns:
 718 |       list(guid, ...): identifiers of the most recently created or changed objects if successful.
 719 |     Example:
 720 |       import rhinoscriptsyntax as rs
 721 |       rs.Command( "_-Circle 0,0,0 10" )
 722 |       rs.Command( "_-Circle 10,0,0 10" )
 723 |       rs.Command( "_-Circle 20,0,0 10" )
 724 |       objs = rs.LastCreatedObjects()
 725 |       if objs:
 726 |           # Only the last circle will be selected
 727 |           rs.SelectObjects( objs )
 728 |     See Also:
 729 |       Command
 730 |     """
 731 |     serial_numbers = rhapp.__command_serial_numbers
 732 |     if serial_numbers is None: return scriptcontext.errorhandler()
 733 |     serial_number = serial_numbers[0]
 734 |     end = serial_numbers[1]
 735 |     rc = []
 736 |     while serial_number<end:
 737 |         obj = scriptcontext.doc.Objects.Find(serial_number)
 738 |         if obj and not obj.IsDeleted:
 739 |             rc.append(obj.Id)
 740 |             if select: obj.Select(True)
 741 |         serial_number += 1
 742 |     if select==True and rc: scriptcontext.doc.Views.Redraw()
 743 |     return rc
 744 | 
 745 | 
 746 | def LastObject(select=False, include_lights=False, include_grips=False):
 747 |     """Returns the identifier of the last object in the document. The last object
 748 |     in the document is the first object created by the user
 749 |     Parameters:
 750 |       select (bool, optional): select the object
 751 |       include_lights (bool, optional): include lights in the potential set
 752 |       include_grips (bool, optional): include grips in the potential set
 753 |     Returns:
 754 |       guid: identifier of the object on success
 755 |     Example:
 756 |       import rhinoscriptsyntax as rs
 757 |       rs.AddLine((0,0,0), (5,5,0))
 758 |       rs.AddCircle((0,0,0), 5)
 759 |       print("Object identifier: {}".format(rs.LastObject()))
 760 |     See Also:
 761 |       FirstObject
 762 |       NextObject
 763 |     """
 764 |     settings = Rhino.DocObjects.ObjectEnumeratorSettings()
 765 |     settings.IncludeLights = include_lights
 766 |     settings.IncludeGrips = include_grips
 767 |     settings.DeletedObjects = False
 768 |     rhobjs = scriptcontext.doc.Objects.GetObjectList(settings)
 769 |     firstobj = None
 770 |     for obj in rhobjs: firstobj = obj
 771 |     if firstobj is None: return scriptcontext.errorhandler()
 772 |     rc = firstobj.Id
 773 |     if select:
 774 |         firstobj.Select(True)
 775 |         scriptcontext.doc.Views.Redraw()
 776 |     return rc
 777 | 
 778 | 
 779 | def NextObject(object_id, select=False, include_lights=False, include_grips=False):
 780 |     """Returns the identifier of the next object in the document
 781 |     Parameters:
 782 |       object_id (guid): the identifier of the object from which to get the next object
 783 |       select (bool, optional): select the object
 784 |       include_lights (bool, optional): include lights in the potential set
 785 |       include_grips (bool, optional): include grips in the potential set
 786 |     Returns:
 787 |       guid: identifier of the object on success
 788 |     Example:
 789 |       import rhinoscriptsyntax as rs
 790 |       obj = rs.FirstObject()
 791 |       while obj:
 792 |           print("Object identifier:{}".format(obj))
 793 |           obj = rs.NextObject(obj)
 794 |     See Also:
 795 |       FirstObject
 796 |       LastObject
 797 |     """
 798 |     current_obj = rhutil.coercerhinoobject(object_id, True)
 799 |     settings = Rhino.DocObjects.ObjectEnumeratorSettings()
 800 |     settings.IncludeLights = include_lights
 801 |     settings.IncludeGrips = include_grips
 802 |     settings.DeletedObjects = False
 803 |     rhobjs = scriptcontext.doc.Objects.GetObjectList(settings)
 804 |     found = False
 805 |     for obj in rhobjs:
 806 |         if found and obj: 
 807 |             if select: obj.Select(True)
 808 |             return obj.Id
 809 |         if obj.Id == current_obj.Id: found = True
 810 | 
 811 | 
 812 | def NormalObjects(include_lights=False, include_grips=False):
 813 |     """Returns identifiers of all normal objects in the document. Normal objects
 814 |     are visible, can be snapped to, and are independent of selection state
 815 |     Parameters:
 816 |       include_lights (bool, optional): Include light objects.  If omitted (False), light objects are not returned.
 817 |       include_gripts (bool, optional): Include grips objects.  If omitted (False), grips objects are not returned.
 818 |     Returns:
 819 |       list(guid, ...): identifier of normal objects if successful.
 820 |     Example:
 821 |       import rhinoscriptsyntax as rs
 822 |       objs = rs.NormalObjects()
 823 |       for obj in objs: print("Object identifier:{}".format(obj))
 824 |     See Also:
 825 |       AllObjects
 826 |       HiddenObjects
 827 |       LockedObjects
 828 |     """
 829 |     iter = Rhino.DocObjects.ObjectEnumeratorSettings()
 830 |     iter.NormalObjects = True
 831 |     iter.LockedObjects = False
 832 |     iter.IncludeLights = include_lights
 833 |     iter.IncludeGrips = include_grips
 834 |     return [obj.Id for obj in scriptcontext.doc.Objects.GetObjectList(iter)]
 835 | 
 836 | 
 837 | def ObjectsByColor(color, select=False, include_lights=False):
 838 |     """Returns identifiers of all objects based on color
 839 |     Parameters:
 840 |       color (color): color to get objects by
 841 |       select (bool, optional): select the objects
 842 |       include_lights (bool, optional): include lights in the set
 843 |     Returns:
 844 |       list(guid, ...): identifiers of objects of the selected color.
 845 |     Example:
 846 |       import rhinoscriptsyntax as rs
 847 |       obj = rs.GetObject("Pick any object")
 848 |       if obj:
 849 |           color = rs.ObjectColor(obj)
 850 |           rs.ObjectsByColor(color, True)
 851 |     See Also:
 852 |       
 853 |     """
 854 |     color = rhutil.coercecolor(color, True)
 855 |     rhino_objects = scriptcontext.doc.Objects.FindByDrawColor(color, include_lights)
 856 |     if select:
 857 |         for obj in rhino_objects: obj.Select(True)
 858 |         scriptcontext.doc.Views.Redraw()
 859 |     return [obj.Id for obj in rhino_objects]
 860 | 
 861 | 
 862 | def ObjectsByGroup(group_name, select=False):
 863 |     """Returns identifiers of all objects based on the objects' group name
 864 |     Parameters:
 865 |       group_name (str): name of the group
 866 |       select (bool, optional): select the objects
 867 |     Returns:
 868 |       list(guid, ...):identifiers for objects in the group on success
 869 |     Example:
 870 |       import rhinoscriptsyntax as rs
 871 |       group = rs.GetString("Group to select")
 872 |       if group: rs.ObjectsByGroup( group, True )
 873 |     See Also:
 874 |       
 875 |     """
 876 |     group_instance = scriptcontext.doc.Groups.FindName(group_name)
 877 |     if group_instance is None: raise ValueError("%s does not exist in GroupTable"%group_name)
 878 |     rhino_objects = scriptcontext.doc.Groups.GroupMembers(group_instance.Index)
 879 |     if not rhino_objects: return []
 880 |     if select:
 881 |         for obj in rhino_objects: obj.Select(True)
 882 |         scriptcontext.doc.Views.Redraw()
 883 |     return [obj.Id for obj in rhino_objects]
 884 | 
 885 | 
 886 | def ObjectsByLayer(layer_name, select=False):
 887 |     """Returns identifiers of all objects based on the objects' layer name
 888 |     Parameters:
 889 |       layer_name (str): name of the layer
 890 |       select (bool, optional): select the objects
 891 |     Returns:
 892 |       list(guid, ...): identifiers for objects in the specified layer
 893 |     Example:
 894 |       import rhinoscriptsyntax as rs
 895 |       obj = rs.GetObject("Pick any object")
 896 |       if obj:
 897 |           layer = rs.ObjectLayer(obj)
 898 |           rs.ObjectsByLayer(layer, True)
 899 |     See Also:
 900 |       
 901 |     """
 902 |     layer = __getlayer(layer_name, True)
 903 |     rhino_objects = scriptcontext.doc.Objects.FindByLayer(layer)
 904 |     if not rhino_objects: return []
 905 |     if select:
 906 |         for rhobj in rhino_objects: rhobj.Select(True)
 907 |         scriptcontext.doc.Views.Redraw()
 908 |     return [rhobj.Id for rhobj in rhino_objects]
 909 | 
 910 | 
 911 | def ObjectsByName(name, select=False, include_lights=False, include_references=False):
 912 |     """Returns identifiers of all objects based on user-assigned name
 913 |     Parameters:
 914 |       name (str): name of the object or objects
 915 |       select (bool, optional): select the objects
 916 |       include_lights (bool, optional): include light objects
 917 |     Returns:
 918 |       list(guid, ...): identifiers for objects with the specified name.
 919 |     Example:
 920 |       import rhinoscriptsyntax as rs
 921 |       name = rs.GetString("Name to select")
 922 |       if name: rs.ObjectsByName(name,True)
 923 |     See Also:
 924 |       
 925 |     """
 926 |     settings = Rhino.DocObjects.ObjectEnumeratorSettings()
 927 |     settings.HiddenObjects = True
 928 |     settings.DeletedObjects = False
 929 |     settings.IncludeGrips = False
 930 |     settings.IncludePhantoms = True
 931 |     settings.IncludeLights = include_lights
 932 |     settings.NameFilter = name
 933 |     settings.ReferenceObjects = include_references
 934 |     objects = scriptcontext.doc.Objects.GetObjectList(settings)
 935 |     ids = [rhobj.Id for rhobj in objects]
 936 |     if ids and select:
 937 |         objects = scriptcontext.doc.Objects.GetObjectList(settings)
 938 |         for rhobj in objects: rhobj.Select(True)
 939 |         scriptcontext.doc.Views.Redraw()
 940 |     return ids
 941 |    
 942 | 
 943 | def ObjectsByType(geometry_type, select=False, state=0):
 944 |     """Returns identifiers of all objects based on the objects' geometry type.
 945 |     Parameters:
 946 |       geometry_type (number): The type(s) of geometry objects (points, curves, surfaces,
 947 |              meshes, etc.) that can be selected. Object types can be
 948 |              added together as bit-coded flags to filter several different kinds of geometry.
 949 |               Value        Description
 950 |                0           All objects
 951 |                1           Point
 952 |                2           Point cloud
 953 |                4           Curve
 954 |                8           Surface or single-face brep
 955 |                16          Polysurface or multiple-face
 956 |                32          Mesh
 957 |                256         Light
 958 |                512         Annotation
 959 |                4096        Instance or block reference
 960 |                8192        Text dot object
 961 |                16384       Grip object
 962 |                32768       Detail
 963 |                65536       Hatch
 964 |                131072      Morph control
 965 |                262144      SubD
 966 |                134217728   Cage
 967 |                268435456   Phantom
 968 |                536870912   Clipping plane
 969 |                1073741824  Extrusion
 970 |       select (bool, optional): Select the objects
 971 |       state (bool, optional): The object state (normal, locked, and hidden). Object states can be 
 972 |         added together to filter several different states of geometry.
 973 |               Value     Description
 974 |               0         All objects
 975 |               1         Normal objects
 976 |               2         Locked objects
 977 |               4         Hidden objects
 978 |     Returns:
 979 |       list(guid, ...): identifiers of object that fit the specified type(s).
 980 |     Example:
 981 |       import rhinoscriptsyntax as rs
 982 |       objs = rs.ObjectsByType(4 | 8, True)
 983 |     See Also:
 984 |       
 985 |     """
 986 |     if not state: state = 7
 987 |     bSurface = False
 988 |     bPolySurface = False
 989 |     bLights = False
 990 |     bGrips = False
 991 |     bPhantoms = False
 992 |     geometry_filter = __FilterHelper(geometry_type)
 993 |     if type(geometry_type) is int and geometry_type==0:
 994 |         geometry_filter = Rhino.DocObjects.ObjectType.AnyObject
 995 |     if geometry_filter & Rhino.DocObjects.ObjectType.Surface: bSurface = True
 996 |     if geometry_filter & Rhino.DocObjects.ObjectType.Brep: bPolySurface = True
 997 |     if geometry_filter & Rhino.DocObjects.ObjectType.Light: bLights = True
 998 |     if geometry_filter & Rhino.DocObjects.ObjectType.Grip: bGrips = True
 999 |     if geometry_filter & Rhino.DocObjects.ObjectType.Phantom: bPhantoms = True
1000 | 
1001 |     it = Rhino.DocObjects.ObjectEnumeratorSettings()
1002 |     it.DeletedObjects = False
1003 |     it.ActiveObjects = True
1004 |     it.ReferenceObjects = True
1005 |     it.IncludeLights = bLights
1006 |     it.IncludeGrips = bGrips
1007 |     it.IncludePhantoms = bPhantoms
1008 | 
1009 |     if state:
1010 |         it.NormalObjects = False
1011 |         it.LockedObjects = False
1012 |     if state & 1: it.NormalObjects = True
1013 |     if state & 2: it.LockedObjects = True
1014 |     if state & 4: it.HiddenObjects = True
1015 | 
1016 |     object_ids = []
1017 |     e = scriptcontext.doc.Objects.GetObjectList(it)
1018 |     for object in e:
1019 |         bFound = False
1020 |         object_type = object.ObjectType
1021 |         if object_type==Rhino.DocObjects.ObjectType.Brep and (bSurface or bPolySurface):
1022 |             brep = rhutil.coercebrep(object.Id)
1023 |             if brep:
1024 |                 if brep.Faces.Count==1:
1025 |                     if bSurface: bFound = True
1026 |                 else:
1027 |                     if bPolySurface: bFound = True
1028 |         elif object_type==Rhino.DocObjects.ObjectType.Extrusion and (bSurface or bPolySurface):
1029 |             extrusion = object.Geometry
1030 |             profile_count = extrusion.ProfileCount
1031 |             cap_count = extrusion.CapCount
1032 |             if profile_count==1 and cap_count==0 and bSurface:
1033 |                 bFound = True
1034 |             elif profile_count>0 and cap_count>0 and bPolySurface:
1035 |                 bFound = True
1036 |         elif object_type & geometry_filter:
1037 |             bFound = True
1038 | 
1039 |         if bFound:
1040 |             if select: object.Select(True)
1041 |             object_ids.append(object.Id)
1042 | 
1043 |     if object_ids and select: scriptcontext.doc.Views.Redraw()
1044 |     return object_ids
1045 |   
1046 | 
1047 | def SelectedObjects(include_lights=False, include_grips=False):
1048 |     """Returns the identifiers of all objects that are currently selected
1049 |     Parameters:
1050 |       include_lights (bool, optional): include light objects
1051 |       include_grips (bool, optional): include grip objects
1052 |     Returns:
1053 |       list(guid, ...) identifiers of selected objects
1054 |     Example:
1055 |       import rhinoscriptsyntax as rs
1056 |       objects = rs.SelectedObjects()
1057 |       for obj in objects: print("Object identifier: {}".format(obj))
1058 |     See Also:
1059 |       InvertSelectedObjects
1060 |       UnselectAllObjects
1061 |     """
1062 |     selobjects = scriptcontext.doc.Objects.GetSelectedObjects(include_lights, include_grips)
1063 |     return [obj.Id for obj in selobjects]
1064 | 
1065 | 
1066 | def UnselectAllObjects():
1067 |     """Unselects all objects in the document
1068 |     Returns:
1069 |       number: the number of objects that were unselected
1070 |     Example:
1071 |       import rhinoscriptsyntax as rs
1072 |       count = rs.UnselectAllObjects()
1073 |       print("{} objects were unselected".format(count))
1074 |     See Also:
1075 |       InvertSelectedObjects
1076 |       SelectedObjects
1077 |     """
1078 |     rc = scriptcontext.doc.Objects.UnselectAll()
1079 |     if rc>0: scriptcontext.doc.Views.Redraw()
1080 |     return rc
1081 | 
1082 | 
1083 | def VisibleObjects(view=None, select=False, include_lights=False, include_grips=False):
1084 |     """Return identifiers of all objects that are visible in a specified view
1085 |     Parameters:
1086 |       view (bool, optional): the view to use. If omitted, the current active view is used
1087 |       select (bool, optional): Select the objects
1088 |       include_lights (bool, optional): include light objects
1089 |       include_grips (bool, optional): include grip objects
1090 |     Returns:
1091 |       list(guid, ...): identifiers of the visible objects
1092 |     Example:
1093 |       import rhinoscriptsyntax as rs
1094 |       object_ids = rs.VisibleObjects("Top")
1095 |       if object_ids:
1096 |           for id in object_ids: print("Object identifier:{}".format(id))
1097 |     See Also:
1098 |       IsView
1099 |       IsVisibleInView
1100 |     """
1101 |     it = Rhino.DocObjects.ObjectEnumeratorSettings()
1102 |     it.DeletedObjects = False
1103 |     it.ActiveObjects = True
1104 |     it.ReferenceObjects = True
1105 |     it.IncludeLights = include_lights
1106 |     it.IncludeGrips = include_grips
1107 |     it.VisibleFilter = True
1108 |     viewport = __viewhelper(view).MainViewport
1109 |     it.ViewportFilter = viewport
1110 | 
1111 |     object_ids = []
1112 |     e = scriptcontext.doc.Objects.GetObjectList(it)
1113 |     for object in e:
1114 |         bbox = object.Geometry.GetBoundingBox(True)
1115 |         if viewport.IsVisible(bbox):
1116 |             if select: object.Select(True)
1117 |             object_ids.append(object.Id)
1118 | 
1119 |     if object_ids and select: scriptcontext.doc.Views.Redraw()
1120 |     return object_ids
1121 | 
1122 | 
1123 | def WindowPick(corner1, corner2, view=None, select=False, in_window=True):
1124 |     """Picks objects using either a window or crossing selection
1125 |     Parameters:
1126 |       corner1, corner2 (point): corners of selection window
1127 |       view (bool, optional): view to perform the selection in
1128 |       select (bool, optional): select picked objects
1129 |       in_window (bool, optional): if False, then a crossing window selection is performed
1130 |     Returns:
1131 |       list(guid, ...): identifiers of selected objects on success
1132 |     Example:
1133 |       import rhinoscriptsyntax as  rs
1134 |       rs.WindowPick((0,0,0), (0,0,0),  None, True)
1135 |     See Also:
1136 |       
1137 |     """
1138 |     view = __viewhelper(view)
1139 |     viewport = view.MainViewport
1140 | 
1141 |     screen1 = rhutil.coerce3dpoint(corner1, True)
1142 |     screen2 = rhutil.coerce3dpoint(corner2, True)
1143 |     xf = viewport.GetTransform(Rhino.DocObjects.CoordinateSystem.World, Rhino.DocObjects.CoordinateSystem.Screen)
1144 |     screen1.Transform(xf)
1145 |     screen2.Transform(xf)
1146 | 
1147 |     pc = Rhino.Input.Custom.PickContext()
1148 |     pc.View = view
1149 |     pc.PickStyle = Rhino.Input.Custom.PickStyle.WindowPick if in_window else Rhino.Input.Custom.PickStyle.CrossingPick
1150 |     pc.PickGroupsEnabled = True if in_window else False
1151 |     _, frustumLine = viewport.GetFrustumLine((screen1.X + screen2.X) / 2.0, (screen1.Y + screen2.Y) / 2.0)
1152 |     pc.PickLine = frustumLine
1153 |     
1154 |     leftX = min(screen1.X, screen2.X)
1155 |     topY = min(screen1.Y, screen2.Y)
1156 |     w = abs(screen1.X - screen2.X)
1157 |     h = abs(screen1.Y - screen2.Y)
1158 |     rec = System.Drawing.Rectangle(leftX, topY, w, h)
1159 |  
1160 |     pc.SetPickTransform(viewport.GetPickTransform(rec))
1161 |     pc.UpdateClippingPlanes()
1162 |     
1163 |     objects = scriptcontext.doc.Objects.PickObjects(pc)
1164 | 
1165 |     if objects:
1166 |         rc = []
1167 |         for rhobj in objects:
1168 |             o = rhobj.Object()
1169 |             rc.append(o.Id)
1170 |             if select: o.Select(True)
1171 |         if select: scriptcontext.doc.Views.Redraw()
1172 |         return rc
1173 | 
```

--------------------------------------------------------------------------------
/rhino_mcp_server/static/mesh.py:
--------------------------------------------------------------------------------

```python
   1 | import System
   2 | import System.Drawing
   3 | 
   4 | import Rhino
   5 | 
   6 | import scriptcontext
   7 | 
   8 | import rhinocompat as compat
   9 | from rhinoscript import utility as rhutil
  10 | from rhinoscript.view import __viewhelper
  11 | 
  12 | 
  13 | def AddMesh(vertices, face_vertices, vertex_normals=None, texture_coordinates=None, vertex_colors=None):
  14 |     """Add a mesh object to the document
  15 |     Parameters:
  16 |       vertices ([point, ...]) list of 3D points defining the vertices of the mesh
  17 |       face_vertices ([[number, number, number], [number, number, number, number], ...]) list containing lists of 3 or 4 numbers that define the
  18 |                     vertex indices for each face of the mesh. If the third a fourth vertex
  19 |                      indices of a face are identical, a triangular face will be created.
  20 |       vertex_normals ([vector, ...], optional) list of 3D vectors defining the vertex normals of
  21 |         the mesh. Note, for every vertex, there must be a corresponding vertex
  22 |         normal
  23 |       texture_coordinates ([[number, number], [number, number], [number, number]], ...], optional): list of 2D texture coordinates. For every
  24 |         vertex, there must be a corresponding texture coordinate
  25 |       vertex_colors ([color, ...]) a list of color values. For every vertex,
  26 |         there must be a corresponding vertex color
  27 |     Returns:
  28 |       guid: Identifier of the new object if successful
  29 |       None: on error
  30 |     Example:
  31 |       import rhinoscriptsyntax as rs
  32 |       vertices = []
  33 |       vertices.append((0.0,0.0,0.0))
  34 |       vertices.append((5.0, 0.0, 0.0))
  35 |       vertices.append((10.0, 0.0, 0.0))
  36 |       vertices.append((0.0, 5.0, 0.0))
  37 |       vertices.append((5.0, 5.0, 0.0))
  38 |       vertices.append((10.0, 5.0, 0.0))
  39 |       vertices.append((0.0, 10.0, 0.0))
  40 |       vertices.append((5.0, 10.0, 0.0))
  41 |       vertices.append((10.0, 10.0, 0.0))
  42 |       faceVertices = []
  43 |       faceVertices.append((0,1,4,4))
  44 |       faceVertices.append((2,4,1,1))
  45 |       faceVertices.append((0,4,3,3))
  46 |       faceVertices.append((2,5,4,4))
  47 |       faceVertices.append((3,4,6,6))
  48 |       faceVertices.append((5,8,4,4))
  49 |       faceVertices.append((6,4,7,7))
  50 |       faceVertices.append((8,7,4,4))
  51 |       rs.AddMesh( vertices, faceVertices )
  52 |     See Also:
  53 |       MeshFaces
  54 |       MeshFaceVertices
  55 |       MeshVertexNormals
  56 |       MeshVertices
  57 |     """
  58 |     mesh = Rhino.Geometry.Mesh()
  59 |     for a, b, c in vertices: mesh.Vertices.Add(a, b, c)
  60 |     for face in face_vertices:
  61 |         if len(face)<4:
  62 |             mesh.Faces.AddFace(face[0], face[1], face[2])
  63 |         else:
  64 |             mesh.Faces.AddFace(face[0], face[1], face[2], face[3])
  65 |     if vertex_normals:
  66 |         count = len(vertex_normals)
  67 |         normals = System.Array.CreateInstance(Rhino.Geometry.Vector3f, count)
  68 |         for i, normal in enumerate(vertex_normals):
  69 |             normals[i] = Rhino.Geometry.Vector3f(normal[0], normal[1], normal[2])
  70 |         mesh.Normals.SetNormals(normals)
  71 |     if texture_coordinates:
  72 |         count = len(texture_coordinates)
  73 |         tcs = System.Array.CreateInstance(Rhino.Geometry.Point2f, count)
  74 |         for i, tc in enumerate(texture_coordinates):
  75 |             tcs[i] = Rhino.Geometry.Point2f(tc[0], tc[1])
  76 |         mesh.TextureCoordinates.SetTextureCoordinates(tcs)
  77 |     if vertex_colors:
  78 |         count = len(vertex_colors)
  79 |         colors = System.Array.CreateInstance(System.Drawing.Color, count)
  80 |         for i, color in enumerate(vertex_colors):
  81 |             colors[i] = rhutil.coercecolor(color)
  82 |         mesh.VertexColors.SetColors(colors)
  83 |     rc = scriptcontext.doc.Objects.AddMesh(mesh)
  84 |     if rc==System.Guid.Empty: raise Exception("unable to add mesh to document")
  85 |     scriptcontext.doc.Views.Redraw()
  86 |     return rc
  87 | 
  88 | 
  89 | def AddPlanarMesh(object_id, delete_input=False):
  90 |     """Creates a planar mesh from a closed, planar curve
  91 |     Parameters:
  92 |       object_id (guid): identifier of a closed, planar curve
  93 |       delete_input (bool, optional) if True, delete the input curve defined by object_id
  94 |     Returns:
  95 |       guid: id of the new mesh on success
  96 |       None: on error
  97 |     Example:
  98 |       import rhinoscriptsyntax as rs
  99 |       obj = rs.GetObject("Select planar curves to build mesh", rs.filter.curve)
 100 |       if obj: rs.AddPlanarMesh(obj)
 101 |     See Also:
 102 |       IsCurveClosed
 103 |       IsCurvePlanar
 104 |     """
 105 |     curve = rhutil.coercecurve(object_id, -1, True)
 106 |     tolerance = scriptcontext.doc.ModelAbsoluteTolerance
 107 |     mesh = Rhino.Geometry.Mesh.CreateFromPlanarBoundary(curve, Rhino.Geometry.MeshingParameters.Default, tolerance)
 108 |     if not mesh: return scriptcontext.errorhandler()
 109 |     if delete_input:
 110 |         id = rhutil.coerceguid(object_id, True)
 111 |         rc = scriptcontext.doc.Objects.Replace(id, mesh)
 112 |     else:
 113 |         rc = scriptcontext.doc.Objects.AddMesh(mesh)
 114 |     if rc==System.Guid.Empty: raise Exception("unable to add mesh to document")
 115 |     scriptcontext.doc.Views.Redraw()
 116 |     return rc
 117 | 
 118 | 
 119 | def CurveMeshIntersection(curve_id, mesh_id, return_faces=False):
 120 |     """Calculates the intersection of a curve object and a mesh object
 121 |     Parameters:
 122 |       curve_id (guid): identifier of a curve object
 123 |       mesh_id (guid): identifier or a mesh object
 124 |       return_faces (bool, optional): return both intersection points and face indices.
 125 |         If False, then just the intersection points are returned
 126 |     Returns:
 127 |       list(point, ...): if return_false is omitted or False, then a list of intersection points
 128 |       list([point, number], ...): if return_false is True, the a one-dimensional list containing information
 129 |         about each intersection. Each element contains the following two elements
 130 |           [0] = point of intersection
 131 |           [1] = mesh face index where intersection lies
 132 |       None: on error
 133 |     Example:
 134 |       import rhinoscriptsyntax as rs
 135 |       curve = rs.GetObject("Select curve to intersect", rs.filter.curve)
 136 |       if curve:
 137 |           mesh = rs.GetObject("Select mesh to intersect", rs.filter.mesh)
 138 |           if mesh:
 139 |               cmx = rs.CurveMeshIntersection(curve, mesh, True)
 140 |               if cmx:
 141 |                   for element in cmx:
 142 |                       print("{}, Face index = {}".format(element[0], element[1]))
 143 |                       rs.AddPoint(element[0])
 144 |     See Also:
 145 |       MeshClosestPoint
 146 |       MeshMeshIntersection
 147 |     """
 148 |     curve = rhutil.coercecurve(curve_id, -1, True)
 149 |     mesh = rhutil.coercemesh(mesh_id, True)
 150 |     tolerance = scriptcontext.doc.ModelAbsoluteTolerance
 151 |     polylinecurve = curve.ToPolyline(0,0,0,0,0.0,tolerance,0.0,0.0,True)
 152 |     pts, faceids = Rhino.Geometry.Intersect.Intersection.MeshPolyline(mesh, polylinecurve)
 153 |     if not pts: return scriptcontext.errorhandler()
 154 |     pts = list(pts)
 155 |     if return_faces:
 156 |         faceids = list(faceids)
 157 |         return compat.ITERATOR2LIST(zip(pts, faceids))
 158 |     return pts
 159 | 
 160 | 
 161 | def DisjointMeshCount(object_id):
 162 |     """Returns number of meshes that could be created by calling SplitDisjointMesh
 163 |     Parameters:
 164 |       object_id (guid): identifier of a mesh object
 165 |     Returns:
 166 |       number: The number of meshes that could be created
 167 |     Example:
 168 |       import rhinoscriptsyntax as rs
 169 |       obj = rs.GetObject("Select mesh", rs.filter.mesh)
 170 |       if rs.DisjointMeshCount(obj)>1: rs.SplitDisjointMesh(obj)
 171 |     See Also:
 172 |       IsMesh
 173 |       SplitDisjointMesh
 174 |     """
 175 |     mesh = rhutil.coercemesh(object_id, True)
 176 |     return mesh.DisjointMeshCount
 177 | 
 178 | 
 179 | def DuplicateMeshBorder(mesh_id):
 180 |     """Creates curves that duplicates a mesh border
 181 |     Parameters:
 182 |       mesh_id (guid): identifier of a mesh object
 183 |     Returns:
 184 |       list(guid, ...): list of curve ids on success
 185 |       None: on error
 186 |     Example:
 187 |       import rhinoscriptsyntax as rs
 188 |       obj = rs.GetObject("Select mesh", rs.filter.mesh)
 189 |       if obj: rs.DuplicateMeshBorder(obj)
 190 |     See Also:
 191 |       DuplicateEdgeCurves
 192 |       DuplicateSurfaceBorder
 193 |     """
 194 |     mesh = rhutil.coercemesh(mesh_id, True)
 195 |     polylines = mesh.GetNakedEdges()
 196 |     rc = []
 197 |     if polylines:
 198 |         for polyline in polylines:
 199 |             id = scriptcontext.doc.Objects.AddPolyline(polyline)
 200 |             if id!=System.Guid.Empty: rc.append(id)
 201 |     if rc: scriptcontext.doc.Views.Redraw()
 202 |     return rc
 203 | 
 204 | 
 205 | def ExplodeMeshes(mesh_ids, delete=False):
 206 |     """Explodes a mesh object, or mesh objects int submeshes. A submesh is a
 207 |     collection of mesh faces that are contained within a closed loop of
 208 |     unwelded mesh edges. Unwelded mesh edges are where the mesh faces that
 209 |     share the edge have unique mesh vertices (not mesh topology vertices)
 210 |     at both ends of the edge
 211 |     Parameters:
 212 |       mesh_ids ([guid, ...]): list of mesh identifiers
 213 |       delete (bool, optional): delete the input meshes
 214 |     Returns:
 215 |       list(guid, ...): List of resulting objects after explode.
 216 |     Example:
 217 |       import rhinoscriptsyntax as rs
 218 |       obj = rs.GetObject("Select mesh to explode", rs.filter.mesh)
 219 |       if rs.IsMesh(obj): rs.ExplodeMeshes(obj)
 220 |     See Also:
 221 |       IsMesh
 222 |     """
 223 |     id = rhutil.coerceguid(mesh_ids)
 224 |     if id: mesh_ids = [mesh_ids]
 225 |     rc = []
 226 |     for mesh_id in mesh_ids:
 227 |         mesh = rhutil.coercemesh(mesh_id, True)
 228 |         if mesh:
 229 |             submeshes = mesh.ExplodeAtUnweldedEdges()
 230 |             if submeshes:
 231 |                 for submesh in submeshes:
 232 |                     id = scriptcontext.doc.Objects.AddMesh(submesh)
 233 |                     if id!=System.Guid.Empty: rc.append(id)
 234 |             if delete:
 235 |                 scriptcontext.doc.Objects.Delete(mesh_id, True)
 236 |                 
 237 |     if rc: scriptcontext.doc.Views.Redraw()
 238 |     return rc
 239 | 
 240 | 
 241 | def IsMesh(object_id):
 242 |     """Verifies if an object is a mesh
 243 |     Parameters:
 244 |       object_id (guid): the object's identifier
 245 |     Returns:
 246 |       bool: True if successful, otherwise False
 247 |     Example:
 248 |       import rhinoscriptsyntax as rs
 249 |       obj = rs.GetObject("Select a mesh")
 250 |       if rs.IsMesh(obj):
 251 |           print("The object is a mesh.")
 252 |       else:
 253 |           print("The object is not a mesh.")
 254 |     See Also:
 255 |       IsMeshClosed
 256 |       MeshFaceCount
 257 |       MeshFaces
 258 |       MeshVertexCount
 259 |       MeshVertices
 260 |     """
 261 |     mesh = rhutil.coercemesh(object_id)
 262 |     return mesh is not None
 263 | 
 264 | 
 265 | def IsMeshClosed(object_id):
 266 |     """Verifies a mesh object is closed
 267 |     Parameters:
 268 |       object_id (guid): identifier of a mesh object
 269 |     Returns:
 270 |       bool: True if successful, otherwise False.
 271 |     Example:
 272 |       import rhinoscriptsyntax as rs
 273 |       obj = rs.GetObject("Select a mesh", rs.filter.mesh)
 274 |       if rs.IsMeshClosed(obj):
 275 |           print("The mesh is closed.")
 276 |       else:
 277 |           print("The mesh is not closed.")
 278 |     See Also:
 279 |       IsMesh
 280 |     """
 281 |     mesh = rhutil.coercemesh(object_id, True)
 282 |     return mesh.IsClosed
 283 | 
 284 | 
 285 | def IsMeshManifold(object_id):
 286 |     """Verifies a mesh object is manifold. A mesh for which every edge is shared
 287 |     by at most two faces is called manifold. If a mesh has at least one edge
 288 |     that is shared by more than two faces, then that mesh is called non-manifold
 289 |     Parameters:
 290 |       object_id (guid): identifier of a mesh object
 291 |     Returns:
 292 |       bool: True if successful, otherwise False.
 293 |     Example:
 294 |       import rhinoscriptsyntax as rs
 295 |       obj = rs.GetObject("Select a mesh", rs.filter.mesh)
 296 |       if rs.IsMeshClosed(obj):
 297 |           print("The mesh is manifold.")
 298 |       else:
 299 |           print("The mesh is non-manifold.")
 300 |     See Also:
 301 |       IsMesh
 302 |       IsMeshClosed
 303 |     """
 304 |     mesh = rhutil.coercemesh(object_id, True)
 305 |     rc = mesh.IsManifold(True)
 306 |     return rc[0]
 307 | 
 308 | 
 309 | def IsPointOnMesh(object_id, point):
 310 |     """Verifies a point is on a mesh
 311 |     Parameters:
 312 |       object_id (guid): identifier of a mesh object
 313 |       point (point): test point
 314 |     Returns:
 315 |       bool: True if successful, otherwise False.
 316 |       None: on error.
 317 |     Example:
 318 |       import rhinoscriptsyntax as rs
 319 |       obj = rs.GetObject("Select a mesh")
 320 |       if rs.IsMesh(obj):
 321 |           point = rs.GetPointOnMesh(strObject, "Pick a test point")
 322 |           if point:
 323 |               if rs.IsPointOnMesh(obj, point):
 324 |                   print("The point is on the mesh")
 325 |               else:
 326 |                   print("The point is not on the mesh")
 327 |     See Also:
 328 |       IsMesh
 329 |       MeshClosestPoint
 330 |     """
 331 |     mesh = rhutil.coercemesh(object_id, True)
 332 |     point = rhutil.coerce3dpoint(point, True)
 333 |     max_distance = Rhino.RhinoMath.SqrtEpsilon
 334 |     face, pt = mesh.ClosestPoint(point, max_distance)
 335 |     return face>=0
 336 | 
 337 | 
 338 | def JoinMeshes(object_ids, delete_input=False):
 339 |     """Joins two or or more mesh objects together
 340 |     Parameters:
 341 |       object_ids ([guid, ...]): identifiers of two or more mesh objects
 342 |       delete_input (bool, optional): delete input after joining
 343 |     Returns:
 344 |       guid: identifier of newly created mesh on success
 345 |     Example:
 346 |       import rhinoscriptsyntax as rs
 347 |       objs = rs.GetObjects("Select meshes to join", rs.filter.mesh)
 348 |       if objs and len(objs)>1: rs.JoinMeshes(objs, True)
 349 |     See Also:
 350 |       JoinCurves
 351 |       JoinSurfaces
 352 |     """
 353 |     meshes = [rhutil.coercemesh(id,True) for id in object_ids]
 354 |     joined_mesh = Rhino.Geometry.Mesh()
 355 |     joined_mesh.Append(meshes)
 356 |     rc = scriptcontext.doc.Objects.AddMesh(joined_mesh)
 357 |     if delete_input:
 358 |         for id in object_ids:
 359 |             guid = rhutil.coerceguid(id)
 360 |             scriptcontext.doc.Objects.Delete(guid,True)
 361 |     scriptcontext.doc.Views.Redraw()
 362 |     return rc
 363 | 
 364 | 
 365 | def MeshArea(object_ids):
 366 |     """Returns approximate area of one or more mesh objects
 367 |     Parameters:
 368 |       object_ids ([guid, ...]): identifiers of one or more mesh objects
 369 |     Returns:
 370 |       list(number, number, number): if successful where
 371 |         [0] = number of meshes used in calculation
 372 |         [1] = total area of all meshes
 373 |         [2] = the error estimate
 374 |       None: if not successful
 375 |     Example:
 376 |       import rhinoscriptsyntax as rs
 377 |       obj = rs.GetObject("Select mesh", rs.filter.mesh )
 378 |       if obj:
 379 |           area_rc = rs.MeshArea(obj)
 380 |           if area_rc: print("Mesh area:{}".format(area_rc[1]))
 381 |     See Also:
 382 |       MeshVolume
 383 |     """
 384 |     id = rhutil.coerceguid(object_ids)
 385 |     if id: object_ids = [object_ids]
 386 |     meshes_used = 0
 387 |     total_area = 0.0
 388 |     error_estimate = 0.0
 389 |     for id in object_ids:
 390 |         mesh = rhutil.coercemesh(id, True)
 391 |         if mesh:
 392 |             mp = Rhino.Geometry.AreaMassProperties.Compute(mesh)
 393 |             if mp:
 394 |                 meshes_used += 1
 395 |                 total_area += mp.Area
 396 |                 error_estimate += mp.AreaError
 397 |     if meshes_used==0: return scriptcontext.errorhandler()
 398 |     return meshes_used, total_area, error_estimate
 399 | 
 400 | 
 401 | def MeshAreaCentroid(object_id):
 402 |     """Calculates the area centroid of a mesh object
 403 |     Parameters:
 404 |       object_id (guid): identifier of a mesh object
 405 |     Returns:
 406 |       point: representing the area centroid if successful
 407 |       None: on error
 408 |     Example:
 409 |       import rhinoscriptsyntax as rs
 410 |       obj = rs.GetObject("Select mesh", rs.filter.mesh )
 411 |       rs.AddPoint( rs.MeshAreaCentroid(obj) )
 412 |     See Also:
 413 |       IsMesh
 414 |       MeshArea
 415 |       MeshVolume
 416 |       MeshVolumeCentroid
 417 |     """
 418 |     mesh = rhutil.coercemesh(object_id, True)
 419 |     mp = Rhino.Geometry.AreaMassProperties.Compute(mesh)
 420 |     if mp is None: return scriptcontext.errorhandler()
 421 |     return mp.Centroid
 422 | 
 423 | 
 424 | def MeshBooleanDifference(input0, input1, delete_input=True, tolerance=None):
 425 |     """Performs boolean difference operation on two sets of input meshes
 426 |     Parameters:
 427 |       input0, input1 (guid): identifiers of meshes
 428 |       delete_input (bool, optional): delete the input meshes
 429 |       tolerance (float, optional): this value is ignored. 
 430 |           The parameter is only there to keep the function signature the same, 
 431 |           The build in tolerenace always is used.
 432 |     Returns:
 433 |       list(guid, ...): identifiers of newly created meshes
 434 |     Example:
 435 |       import rhinoscriptsyntax as rs
 436 |       input0 = rs.GetObjects("Select first set of meshes", rs.filter.mesh)
 437 |       if input0:
 438 |           input1 = rs.GetObjects("Select second set of meshes", rs.filter.mesh)
 439 |           if input1: rs.MeshBooleanDifference(input0, input1)
 440 |     See Also:
 441 |       MeshBooleanIntersection
 442 |       MeshBooleanSplit
 443 |       MeshBooleanUnion
 444 |     """
 445 |     id = rhutil.coerceguid(input0)
 446 |     if id: input0 = [id]
 447 |     id = rhutil.coerceguid(input1)
 448 |     if id: input1 = [id]
 449 |     meshes0 = [rhutil.coercemesh(id, True) for id in input0]
 450 |     meshes1 = [rhutil.coercemesh(id, True) for id in input1]
 451 |     if not meshes0 or not meshes1: raise ValueError("no meshes to work with")
 452 |     newmeshes = Rhino.Geometry.Mesh.CreateBooleanDifference(meshes0, meshes1)
 453 |     rc = []
 454 |     for mesh in newmeshes:
 455 |         id = scriptcontext.doc.Objects.AddMesh(mesh)
 456 |         if id!=System.Guid.Empty: rc.append(id)
 457 |     if rc and delete_input:
 458 |         input = input0 + input1
 459 |         for id in input:
 460 |             id = rhutil.coerceguid(id, True)
 461 |             scriptcontext.doc.Objects.Delete(id, True)
 462 |     scriptcontext.doc.Views.Redraw()
 463 |     return rc
 464 | 
 465 | 
 466 | def MeshBooleanIntersection(input0, input1, delete_input=True):
 467 |     """Performs boolean intersection operation on two sets of input meshes
 468 |     Parameters:
 469 |       input0, input1 (guid): identifiers of meshes
 470 |       delete_input (bool, optional): delete the input meshes
 471 |     Returns:
 472 |       list(guid, ...): identifiers of new meshes on success
 473 |     Example:
 474 |       import rhinoscriptsyntax as rs
 475 |       input0 = rs.GetObjects("Select first set of meshes", rs.filter.mesh)
 476 |       if input0:
 477 |           input1 = rs.GetObjects("Select second set of meshes", rs.filter.mesh)
 478 |           if input1: rs.MeshBooleanIntersection(input0, input1)
 479 |     See Also:
 480 |       MeshBooleanDifference
 481 |       MeshBooleanSplit
 482 |       MeshBooleanUnion
 483 |     """
 484 |     id = rhutil.coerceguid(input0)
 485 |     if id: input0 = [id]
 486 |     id = rhutil.coerceguid(input1)
 487 |     if id: input1 = [id]
 488 |     meshes0 = [rhutil.coercemesh(id, True) for id in input0]
 489 |     meshes1 = [rhutil.coercemesh(id, True) for id in input1]
 490 |     if not meshes0 or not meshes1: raise ValueError("no meshes to work with")
 491 |     newmeshes = Rhino.Geometry.Mesh.CreateBooleanIntersection(meshes0, meshes1)
 492 |     rc = []
 493 |     for mesh in newmeshes:
 494 |         id = scriptcontext.doc.Objects.AddMesh(mesh)
 495 |         if id!=System.Guid.Empty: rc.append(id)
 496 |     if rc and delete_input:
 497 |         input = input0 + input1
 498 |         for id in input:
 499 |             id = rhutil.coerceguid(id, True)
 500 |             scriptcontext.doc.Objects.Delete(id, True)
 501 |     scriptcontext.doc.Views.Redraw()
 502 |     return rc
 503 | 
 504 | 
 505 | def MeshBooleanSplit(input0, input1, delete_input=True):
 506 |     """Performs boolean split operation on two sets of input meshes
 507 |     Parameters:
 508 |       input0, input1 (guid): identifiers of meshes
 509 |       delete_input (bool, optional): delete the input meshes
 510 |     Returns:
 511 |       list(guid, ...): identifiers of new meshes on success
 512 |       None: on error
 513 |     Example:
 514 |       import rhinoscriptsyntax as rs
 515 |       input0 = rs.GetObjects("Select first set of meshes", rs.filter.mesh)
 516 |       if input0:
 517 |           input1 = rs.GetObjects("Select second set of meshes", rs.filter.mesh)
 518 |           if input1: rs.MeshBooleanSplit(input0, input1)
 519 |     See Also:
 520 |       MeshBooleanDifference
 521 |       MeshBooleanIntersection
 522 |       MeshBooleanUnion
 523 |     """
 524 |     id = rhutil.coerceguid(input0)
 525 |     if id: input0 = [id]
 526 |     id = rhutil.coerceguid(input1)
 527 |     if id: input1 = [id]
 528 |     meshes0 = [rhutil.coercemesh(id, True) for id in input0]
 529 |     meshes1 = [rhutil.coercemesh(id, True) for id in input1]
 530 |     if not meshes0 or not meshes1: raise ValueError("no meshes to work with")
 531 |     newmeshes = Rhino.Geometry.Mesh.CreateBooleanSplit(meshes0, meshes1)
 532 |     rc = []
 533 |     for mesh in newmeshes:
 534 |         id = scriptcontext.doc.Objects.AddMesh(mesh)
 535 |         if id!=System.Guid.Empty: rc.append(id)
 536 |     if rc and delete_input:
 537 |         input = input0 + input1
 538 |         for id in input:
 539 |             id = rhutil.coerceguid(id, True)
 540 |             scriptcontext.doc.Objects.Delete(id, True)
 541 |     scriptcontext.doc.Views.Redraw()
 542 |     return rc
 543 | 
 544 | 
 545 | def MeshBooleanUnion(mesh_ids, delete_input=True):
 546 |     """Performs boolean union operation on a set of input meshes
 547 |     Parameters:
 548 |       mesh_ids ([guid, ...]): identifiers of meshes
 549 |       delete_input (bool, optional): delete the input meshes
 550 |     Returns:
 551 |       list(guid, ...): identifiers of new meshes
 552 |     Example:
 553 |       import rhinoscriptsyntax as rs
 554 |       input = rs.GetObjects("Select meshes to union", rs.filter.mesh)
 555 |       if input: rs.MeshBooleanUnion(input)
 556 |     See Also:
 557 |       MeshBooleanDifference
 558 |       MeshBooleanIntersection
 559 |       MeshBooleanSplit
 560 |     """
 561 |     if len(mesh_ids)<2: raise ValueError("mesh_ids must contain at least 2 meshes")
 562 |     meshes = [rhutil.coercemesh(id, True) for id in mesh_ids]
 563 |     newmeshes = Rhino.Geometry.Mesh.CreateBooleanUnion(meshes)
 564 |     rc = []
 565 |     for mesh in newmeshes:
 566 |         id = scriptcontext.doc.Objects.AddMesh(mesh)
 567 |         if id!=System.Guid.Empty: rc.append(id)
 568 |     if rc and delete_input:
 569 |         for id in mesh_ids:
 570 |             id = rhutil.coerceguid(id, True)
 571 |             scriptcontext.doc.Objects.Delete(id, True)
 572 |     scriptcontext.doc.Views.Redraw()
 573 |     return rc
 574 | 
 575 | 
 576 | def MeshClosestPoint(object_id, point, maximum_distance=None):
 577 |     """Returns the point on a mesh that is closest to a test point
 578 |     Parameters:
 579 |       object_id (guid): identifier of a mesh object
 580 |       point (point): point to test
 581 |       maximum_distance (number, optional): upper bound used for closest point calculation.
 582 |         If you are only interested in finding a point Q on the mesh when
 583 |         point.DistanceTo(Q) < maximum_distance, then set maximum_distance to
 584 |         that value
 585 |     Returns:
 586 |       tuple(point, number): containing the results of the calculation where
 587 |                             [0] = the 3-D point on the mesh
 588 |                             [1] = the index of the mesh face on which the 3-D point lies
 589 |       None: on error
 590 |     Example:
 591 |       import rhinocriptsyntax as rs
 592 |       obj = rs.GetObject("Select mesh", rs.filter.mesh)
 593 |       point = rs.GetPoint("Pick test point")
 594 |       intersect = rs.MeshClosestPoint(obj, point)
 595 |       if intersect: rs.AddPoint(intersect)
 596 |     See Also:
 597 |       MeshFaceCount
 598 |       MeshFaces
 599 |     """
 600 |     mesh = rhutil.coercemesh(object_id, True)
 601 |     point = rhutil.coerce3dpoint(point, True)
 602 |     tolerance=maximum_distance if maximum_distance else 0.0
 603 |     face, closest_point = mesh.ClosestPoint(point, tolerance)
 604 |     if face<0: return scriptcontext.errorhandler()
 605 |     return closest_point, face
 606 | 
 607 | 
 608 | def MeshFaceCenters(mesh_id):
 609 |     """Returns the center of each face of the mesh object
 610 |     Parameters:
 611 |       mesh_id (guid): identifier of a mesh object
 612 |     Returns:
 613 |       list(point, ...): points defining the center of each face
 614 |     Example:
 615 |       import rhinoscriptsyntax as rs
 616 |       obj = rs.GetObject("Select mesh", rs.filter.mesh)
 617 |       centers = rs.MeshFaceCenters(obj)
 618 |       if centers:
 619 |           for point in centers: rs.AddPoint(point)
 620 |     See Also:
 621 |       IsMesh
 622 |       MeshFaceCount
 623 |       MeshFaces
 624 |     """
 625 |     mesh = rhutil.coercemesh(mesh_id, True)
 626 |     return [mesh.Faces.GetFaceCenter(i) for i in range(mesh.Faces.Count)]
 627 | 
 628 | 
 629 | def MeshFaceCount(object_id):
 630 |     """Returns total face count of a mesh object
 631 |     Parameters:
 632 |       object_id (guid): identifier of a mesh object
 633 |     Returns:
 634 |       number: the number of mesh faces if successful
 635 |     Example:
 636 |       import rhinoscriptsyntax as rs
 637 |       obj = rs.GetObject("Select mesh", rs.filter.mesh )
 638 |       print("Quad faces:{}".format(rs.MeshQuadCount(obj)))
 639 |       print("Triangle faces:{}".format(rs.MeshTriangleCount(obj)))
 640 |       print("Total faces:{}".format(rs.MeshFaceCount(obj)))
 641 |     See Also:
 642 |       IsMesh
 643 |       MeshFaces
 644 |       MeshVertexCount
 645 |       MeshVertices
 646 |     """
 647 |     mesh = rhutil.coercemesh(object_id, True)
 648 |     return mesh.Faces.Count
 649 | 
 650 | 
 651 | def MeshFaceNormals(mesh_id):
 652 |     """Returns the face unit normal for each face of a mesh object
 653 |     Parameters:
 654 |       mesh_id (guid): identifier of a mesh object
 655 |     Returns:
 656 |       list(vector, ...): 3D vectors that define the face unit normals of the mesh
 657 |       None: on error
 658 |     Example:
 659 |       import rhinoscriptsyntax as rs
 660 |       obj = rs.GetObject("Select mesh", rs.filter.mesh)
 661 |       normals = rs.MeshFaceNormals(obj)
 662 |       if normals:
 663 |           for vector in normals: print(vector)
 664 |     See Also:
 665 |       MeshHasFaceNormals
 666 |       MeshFaceCount
 667 |       MeshFaces
 668 |     """
 669 |     mesh = rhutil.coercemesh(mesh_id, True)
 670 |     if mesh.FaceNormals.Count != mesh.Faces.Count:
 671 |         mesh.FaceNormals.ComputeFaceNormals()
 672 |     rc = []
 673 |     for i in compat.RANGE(mesh.FaceNormals.Count):
 674 |         normal = mesh.FaceNormals[i]
 675 |         rc.append(Rhino.Geometry.Vector3d(normal))
 676 |     return rc
 677 | 
 678 | 
 679 | def MeshFaces(object_id, face_type=True):
 680 |     """Returns face vertices of a mesh
 681 |     Parameters:
 682 |       object_id (guid): identifier of a mesh object
 683 |       face_type (bool, optional): The face type to be returned. True = both triangles
 684 |         and quads. False = only triangles
 685 |     Returns:
 686 |       list([point, point, point, point], ...): 3D points that define the face vertices of the mesh. If
 687 |       face_type is True, then faces are returned as both quads and triangles
 688 |       (4 3D points). For triangles, the third and fourth vertex will be
 689 |       identical. If face_type is False, then faces are returned as only
 690 |       triangles(3 3D points). Quads will be converted to triangles.
 691 |     Example:
 692 |       import rhinoscriptsyntax as rs
 693 |       obj = rs.GetObject("Select mesh", rs.filter.mesh)
 694 |       faces = rs.MeshFaces(obj, False)
 695 |       if faces:
 696 |           rs.EnableRedraw(False)
 697 |           i = 0
 698 |           while( i<=len(faces) ):
 699 |               face = faces[i], faces[i+1], faces[i+2], faces[i]
 700 |               rs.AddPolyline( face )
 701 |               i += 3
 702 |       rs.EnableRedraw(True)
 703 |     See Also:
 704 |       IsMesh
 705 |       MeshFaceCount
 706 |       MeshVertexCount
 707 |       MeshVertices
 708 |     """
 709 |     mesh = rhutil.coercemesh(object_id, True)
 710 |     rc = []
 711 |     for i in compat.RANGE(mesh.Faces.Count):
 712 |         getrc, p0, p1, p2, p3 = mesh.Faces.GetFaceVertices(i)
 713 |         p0 = Rhino.Geometry.Point3d(p0)
 714 |         p1 = Rhino.Geometry.Point3d(p1)
 715 |         p2 = Rhino.Geometry.Point3d(p2)
 716 |         p3 = Rhino.Geometry.Point3d(p3)
 717 |         rc.append( p0 )
 718 |         rc.append( p1 )
 719 |         rc.append( p2 )
 720 |         if face_type:
 721 |             rc.append(p3)
 722 |         else:
 723 |             if p2!=p3:
 724 |                 rc.append( p2 )
 725 |                 rc.append( p3 )
 726 |                 rc.append( p0 )
 727 |     return rc
 728 | 
 729 | 
 730 | def MeshFaceVertices(object_id):
 731 |     """Returns the vertex indices of all faces of a mesh object
 732 |     Parameters:
 733 |       object_id (guid): identifier of a mesh object
 734 |     Returns:
 735 |       list((number, number, number, number), ...): containing tuples of 4 numbers that define the vertex indices for
 736 |       each face of the mesh. Both quad and triangle faces are returned. If the
 737 |       third and fourth vertex indices are identical, the face is a triangle.
 738 |     Example:
 739 |       import rhinoscriptsyntax as rs
 740 |       obj = rs.GetObject("Select mesh", rs.filter.mesh)
 741 |       faceVerts = rs.MeshFaceVertices( obj )
 742 |       if faceVerts:
 743 |           for count, face in enumerate(faceVerts):
 744 |               print("face({}) = ({}, {}, {}, {})".format(count, face[0], face[1], face[2], face[3]))
 745 |     See Also:
 746 |       IsMesh
 747 |       MeshFaceCount
 748 |       MeshFaces
 749 |     """
 750 |     mesh = rhutil.coercemesh(object_id, True)
 751 |     rc = []
 752 |     for i in compat.RANGE(mesh.Faces.Count):
 753 |         face = mesh.Faces.GetFace(i)
 754 |         rc.append( (face.A, face.B, face.C, face.D) )
 755 |     return rc
 756 | 
 757 | 
 758 | def MeshHasFaceNormals(object_id):
 759 |     """Verifies a mesh object has face normals
 760 |     Parameters:
 761 |       object_id (guid): identifier of a mesh object
 762 |     Returns:
 763 |       bool: True if successful, otherwise False.
 764 |     Example:
 765 |       import rhinoscriptsyntax as rs
 766 |       obj = rs.GetObject("Select a mesh", rs.filter.mesh)
 767 |       if rs.MeshHasFaceNormals(obj):
 768 |           print("The mesh has face normal.")
 769 |       else:
 770 |           print("The mesh does not have face normals.")
 771 |     See Also:
 772 |       MeshFaceNormals
 773 |     """
 774 |     mesh = rhutil.coercemesh(object_id, True)
 775 |     return mesh.FaceNormals.Count>0
 776 | 
 777 | 
 778 | def MeshHasTextureCoordinates(object_id):
 779 |     """Verifies a mesh object has texture coordinates
 780 |     Parameters:
 781 |       object_id (guid): identifier of a mesh object
 782 |     Returns:
 783 |       bool: True if successful, otherwise False.
 784 |     Example:
 785 |       import rhinoscriptsyntax as rs
 786 |       obj = rs.GetObject("Select a mesh", rs.filter.mesh)
 787 |       if rs.MeshHasTextureCoordinates(obj):
 788 |           print("The mesh has texture coordinates.")
 789 |       else:
 790 |           print("The mesh does not have texture coordinates.")
 791 |     See Also:
 792 |       
 793 |     """
 794 |     mesh = rhutil.coercemesh(object_id, True)
 795 |     return mesh.TextureCoordinates.Count>0
 796 | 
 797 | 
 798 | def MeshHasVertexColors(object_id):
 799 |     """Verifies a mesh object has vertex colors
 800 |     Parameters:
 801 |       object_id (guid): identifier of a mesh object
 802 |     Returns:
 803 |       bool: True if successful, otherwise False.
 804 |     Example:
 805 |       import rhinoscriptsyntax as rs
 806 |       obj = rs.GetObject("Select a mesh", rs.filter.mesh)
 807 |       if rs.mesh.MeshHasVertexColors(obj):
 808 |           print("The mesh has vertex colors.")
 809 |       else:
 810 |           print("The mesh does not have vertex colors.")
 811 |     See Also:
 812 |       MeshVertexColors
 813 |     """
 814 |     mesh = rhutil.coercemesh(object_id, True)
 815 |     return mesh.VertexColors.Count>0
 816 | 
 817 | 
 818 | def MeshHasVertexNormals(object_id):
 819 |     """Verifies a mesh object has vertex normals
 820 |     Parameters:
 821 |       object_id (guid): identifier of a mesh object
 822 |     Returns:
 823 |       bool: True if successful, otherwise False.
 824 |     Example:
 825 |       import rhinoscriptsyntax as rs
 826 |       obj = rs.GetObject("Select a mesh", rs.filter.mesh)
 827 |       if rs.MeshHasVertexNormals(obj):
 828 |           print("The mesh has vertex normals.")
 829 |       else:
 830 |           print("The mesh does not have vertex normals.")
 831 |     See Also:
 832 |       MeshVertexNormals
 833 |     """
 834 |     mesh = rhutil.coercemesh(object_id, True)
 835 |     return mesh.Normals.Count>0
 836 | 
 837 | 
 838 | def MeshMeshIntersection(mesh1, mesh2, tolerance=None):
 839 |     """Calculates the intersections of a mesh object with another mesh object
 840 |     Parameters:
 841 |       mesh1, mesh2 (guid): identifiers of meshes
 842 |       tolerance (number, optional): the intersection tolerance. Defaults to ModelAbsoluteTolerance * MeshIntersectionsTolerancesCoefficient
 843 |     Returns:
 844 |       list(point, ...): of points that define the vertices of the intersection curves
 845 |     Example:
 846 |       import rhinoscriptsyntax as rs
 847 |       mesh1 = rs.GetObject("Select first mesh to intersect", rs.filter.mesh)
 848 |       mesh2 = rs.GetObject("Select second mesh to intersect", rs.filter.mesh)
 849 |       results = rs.MeshMeshIntersection(mesh1, mesh2)
 850 |       if results:
 851 |           for points in results: rs.AddPolyline(points)
 852 |     See Also:
 853 |       CurveMeshIntersection
 854 |       MeshClosestPoint
 855 |     """
 856 |     mesh1 = rhutil.coercemesh(mesh1, True)
 857 |     mesh2 = rhutil.coercemesh(mesh2, True)
 858 |     if tolerance is None:
 859 |       tolerance = scriptcontext.doc.ModelAbsoluteTolerance * Rhino.Geometry.Intersect.Intersection.MeshIntersectionsTolerancesCoefficient
 860 |     polylines = Rhino.Geometry.Intersect.Intersection.MeshMeshAccurate(mesh1, mesh2, tolerance)
 861 |     if polylines: return list(polylines)
 862 | 
 863 | 
 864 | def MeshNakedEdgePoints(object_id):
 865 |     """Identifies the naked edge points of a mesh object. This function shows
 866 |     where mesh vertices are not completely surrounded by faces. Joined
 867 |     meshes, such as are made by MeshBox, have naked mesh edge points where
 868 |     the sub-meshes are joined
 869 |     Parameters:
 870 |       object_id (guid): identifier of a mesh object
 871 |     Returns:
 872 |       list(bool, ...): of boolean values that represent whether or not a mesh vertex is
 873 |       naked or not. The number of elements in the list will be equal to
 874 |       the value returned by MeshVertexCount. In which case, the list will
 875 |       identify the naked status for each vertex returned by MeshVertices
 876 |       None: on error
 877 |     Example:
 878 |       import rhinoscriptsyntax as rs
 879 |       obj = rs.GetObject("Select mesh", rs.filter.mesh)
 880 |       vertices = rs.MeshVertices( obj )
 881 |       naked = rs.MeshNakedEdgePoints( obj )
 882 |       for i, vertex in enumerate(vertices):
 883 |           if naked[i]: rs.AddPoint(vertex)
 884 |     See Also:
 885 |       IsMesh
 886 |       MeshVertexCount
 887 |       MeshVertices
 888 |     """
 889 |     mesh = rhutil.coercemesh(object_id, True)
 890 |     rc = mesh.GetNakedEdgePointStatus()
 891 |     return rc
 892 | 
 893 | 
 894 | def MeshOffset(mesh_id, distance):
 895 |     """Makes a new mesh with vertices offset at a distance in the opposite
 896 |     direction of the existing vertex normals
 897 |     Parameters:
 898 |       mesh_id (guid): identifier of a mesh object
 899 |       distance (number, optional): the distance to offset
 900 |     Returns:
 901 |       guid: identifier of the new mesh object if successful
 902 |       None: on error
 903 |     Example:
 904 |       import rhinoscriptsyntax as rs
 905 |       mesh = rs.GetObject("Select mesh to offset", rs.filter.mesh)
 906 |       rs.MeshOffset( mesh, 10.0 )
 907 |     See Also:
 908 |       IsMesh
 909 |     """
 910 |     mesh = rhutil.coercemesh(mesh_id, True)
 911 |     offsetmesh = mesh.Offset(distance)
 912 |     if offsetmesh is None: return scriptcontext.errorhandler()
 913 |     rc = scriptcontext.doc.Objects.AddMesh(offsetmesh)
 914 |     if rc==System.Guid.Empty: raise Exception("unable to add mesh to document")
 915 |     scriptcontext.doc.Views.Redraw()
 916 |     return rc
 917 | 
 918 | 
 919 | def MeshOutline(object_ids, view=None):
 920 |     """Creates polyline curve outlines of mesh objects
 921 |     Parameters:
 922 |       objects_ids ([guid, ...]): identifiers of meshes to outline
 923 |       view (str, optional): view to use for outline direction
 924 |     Returns:
 925 |       list(guid, ...): polyline curve identifiers on success
 926 |     Example:
 927 |       import rhinoscriptsyntax as rs
 928 |       objs = rs.GetObjects("Select mesh objects to outline", rs.filter.mesh)
 929 |       if objs: rs.MeshOutline(objs)
 930 |     See Also:
 931 |       IsMesh
 932 |     """
 933 |     viewport = __viewhelper(view).MainViewport
 934 |     meshes = []
 935 |     mesh = rhutil.coercemesh(object_ids, False)
 936 |     if mesh: meshes.append(mesh)
 937 |     else: meshes = [rhutil.coercemesh(id,True) for id in object_ids]
 938 |     rc = []
 939 |     for mesh in meshes:
 940 |         polylines = mesh.GetOutlines(viewport)
 941 |         if not polylines: continue
 942 |         for polyline in polylines:
 943 |             id = scriptcontext.doc.Objects.AddPolyline(polyline)
 944 |             rc.append(id)
 945 |     scriptcontext.doc.Views.Redraw()
 946 |     return rc
 947 | 
 948 | 
 949 | def MeshQuadCount(object_id):
 950 |     """Returns the number of quad faces of a mesh object
 951 |     Parameters:
 952 |       object_id (guid): identifier of a mesh object
 953 |     Returns:
 954 |       number: the number of quad mesh faces if successful
 955 |     Example:
 956 |       import rhinoscriptsyntax as rs
 957 |       obj = rs.GetObject("Select mesh", rs.filter.mesh )
 958 |       print("Quad faces:{}".format(rs.MeshQuadCount(obj)))
 959 |       print("Triangle faces:{}".format(rs.MeshTriangleCount(obj)))
 960 |       print("Total faces:{}".format(rs.MeshFaceCount(obj)))
 961 |     See Also:
 962 |       MeshQuadCount
 963 |     """
 964 |     mesh = rhutil.coercemesh(object_id, True)
 965 |     return mesh.Faces.QuadCount
 966 | 
 967 | 
 968 | def MeshQuadsToTriangles(object_id):
 969 |     """Converts a mesh object's quad faces to triangles
 970 |     Parameters:
 971 |       object_id (guid): identifier of a mesh object
 972 |     Returns:
 973 |       bool: True or False indicating success or failure
 974 |     Example:
 975 |       import rhinoscriptsyntax as rs
 976 |       obj = rs.GetObject("Select mesh", rs.filter.mesh )
 977 |       if rs.MeshQuadCount(obj)>0:
 978 |           rs.MeshQuadsToTriangles(obj)
 979 |     See Also:
 980 |       
 981 |     """
 982 |     mesh = rhutil.coercemesh(object_id, True)
 983 |     rc = True
 984 |     if mesh.Faces.QuadCount>0:
 985 |         rc = mesh.Faces.ConvertQuadsToTriangles()
 986 |         if rc:
 987 |             id = rhutil.coerceguid(object_id, True)
 988 |             scriptcontext.doc.Objects.Replace(id, mesh)
 989 |             scriptcontext.doc.Views.Redraw()
 990 |     return rc
 991 | 
 992 | 
 993 | def MeshToNurb(object_id, trimmed_triangles=True, delete_input=False):
 994 |     """Duplicates each polygon in a mesh with a NURBS surface. The resulting
 995 |     surfaces are then joined into a polysurface and added to the document
 996 |     Parameters:
 997 |       object_id (guid): identifier of a mesh object
 998 |       trimmed_triangles (bool, optional): if True, triangles in the mesh will be
 999 |         represented by a trimmed plane
1000 |       delete_input (bool, optional): delete input object
1001 |     Returns:
1002 |       list(guid, ...): identifiers for the new breps on success
1003 |     Example:
1004 |       import rhinoscriptsyntax as rs
1005 |       obj = rs.GetObject("Select mesh", rs.filter.mesh)
1006 |       if obj: rs.MeshToNurb(obj)
1007 |     See Also:
1008 |       IsMesh
1009 |       MeshFaces
1010 |       MeshVertices
1011 |     """
1012 |     mesh = rhutil.coercemesh(object_id, True)
1013 |     pieces = mesh.SplitDisjointPieces()
1014 |     breps = [Rhino.Geometry.Brep.CreateFromMesh(piece,trimmed_triangles) for piece in pieces]
1015 |     rhobj = rhutil.coercerhinoobject(object_id, True, True)
1016 |     attr = rhobj.Attributes
1017 |     ids = [scriptcontext.doc.Objects.AddBrep(brep, attr) for brep in breps]
1018 |     if delete_input: scriptcontext.doc.Objects.Delete(rhobj, True)
1019 |     scriptcontext.doc.Views.Redraw()
1020 |     return ids
1021 | 
1022 | 
1023 | def MeshTriangleCount(object_id):
1024 |     """Returns number of triangular faces of a mesh
1025 |     Parameters:
1026 |       object_id (guid): identifier of a mesh object
1027 |     Returns:
1028 |       number: The number of triangular mesh faces if successful
1029 |     Example:
1030 |       import rhinoscriptsyntax as rs
1031 |       obj = rs.GetObject("Select mesh", rs.filter.mesh )
1032 |       print("Quad faces:{}".format(rs.MeshQuadCount(obj)))
1033 |       print("Triangle faces:{}".format(rs.MeshTriangleCount(obj)))
1034 |       print("Total faces:{}".format(rs.MeshFaceCount(obj)))
1035 |     See Also:
1036 |       IsMesh
1037 |     """
1038 |     mesh = rhutil.coercemesh(object_id, True)
1039 |     return mesh.Faces.TriangleCount
1040 | 
1041 | 
1042 | def MeshVertexColors(mesh_id, colors=0):
1043 |     """Returns of modifies vertex colors of a mesh
1044 |     Parameters:
1045 |       mesh_id (guid): identifier of a mesh object
1046 |       colors 9{color, ...], optional) A list of color values. Note, for each vertex, there must
1047 |         be a corresponding vertex color. If the value is None, then any
1048 |         existing vertex colors will be removed from the mesh
1049 |     Returns:
1050 |       color: if colors is not specified, the current vertex colors
1051 |       color: if colors is specified, the previous vertex colors
1052 |     Example:
1053 |       import rhinoscriptsyntax as rs
1054 |       import random
1055 |        
1056 |       def randomcolor():
1057 |           r = random.randint(0,255)
1058 |           g = random.randint(0,255)
1059 |           b = random.randint(0,255)
1060 |           return r,g,b
1061 |        
1062 |       obj = rs.GetObject("Select mesh", rs.filter.mesh)
1063 |       if obj:
1064 |           colors = []
1065 |           for i in range(rs.MeshVertexCount(obj)): colors.append( randomcolor() )
1066 |           rs.MeshVertexColors( obj, colors )
1067 |     See Also:
1068 |       MeshHasVertexColors
1069 |       MeshVertexCount
1070 |       MeshVertices
1071 |     """
1072 |     mesh = rhutil.coercemesh(mesh_id, True)
1073 |     rc = [mesh.VertexColors[i] for i in range(mesh.VertexColors.Count)]
1074 |     if colors==0: return rc
1075 |     if colors is None:
1076 |         mesh.VertexColors.Clear()
1077 |     else:
1078 |         color_count = len(colors)
1079 |         if color_count!=mesh.Vertices.Count:
1080 |             raise ValueError("length of colors must match vertex count")
1081 |         colors = [rhutil.coercecolor(c) for c in colors]
1082 |         mesh.VertexColors.Clear()
1083 |         for c in colors: mesh.VertexColors.Add(c)
1084 |     id = rhutil.coerceguid(mesh_id, True)
1085 |     scriptcontext.doc.Objects.Replace(id, mesh)
1086 |     scriptcontext.doc.Views.Redraw()
1087 |     return rc
1088 | 
1089 | 
1090 | def MeshVertexCount(object_id):
1091 |     """Returns the vertex count of a mesh
1092 |     Parameters:
1093 |       object_id (guid): identifier of a mesh object
1094 |     Returns:
1095 |       number: The number of mesh vertices if successful.
1096 |     Example:
1097 |       import rhinoscriptsyntax as rs
1098 |       obj = rs.GetObject("Select mesh", rs.filter.mesh )
1099 |       print("Vertex count: {}".format(rs.MeshVertexCount(obj)))
1100 |     See Also:
1101 |       IsMesh
1102 |       MeshFaceCount
1103 |       MeshFaces
1104 |       MeshVertices
1105 |     """
1106 |     mesh = rhutil.coercemesh(object_id, True)
1107 |     return mesh.Vertices.Count
1108 | 
1109 | 
1110 | def MeshVertexFaces(mesh_id, vertex_index):
1111 |     """Returns the mesh faces that share a specified mesh vertex
1112 |     Parameters:
1113 |       mesh_id (guid): identifier of a mesh object
1114 |       vertex_index (number): index of the mesh vertex to find faces for
1115 |     Returns:
1116 |       list(number, ...): face indices on success
1117 |       None: on error
1118 |     Example:
1119 |       import rhinoscriptsyntax as rs
1120 |       import random
1121 |       def TestMeshVertexFaces():
1122 |           mesh = rs.GetObject("Select mesh", rs.filter.mesh)
1123 |           vertices = rs.MeshVertices(mesh)
1124 |           meshfaces = rs.MeshFaceVertices(mesh)
1125 |           vertex = random.randint(0, len(vertices)-1) #some random vertex
1126 |           vertex_faces = rs.MeshVertexFaces(mesh, vertex )
1127 |           if vertex_faces:
1128 |               rs.AddPoint( vertices[vertex] )
1129 |               for face_index in vertex_faces:
1130 |                   face = meshfaces[face_index]
1131 |                   polyline = []
1132 |                   polyline.append( vertices[face[0]] )
1133 |                   polyline.append( vertices[face[1]] )
1134 |                   polyline.append( vertices[face[2]] )
1135 |                   if face[2]!=face[3]:
1136 |                       polyline.append( vertices[face[3]] )
1137 |                   polyline.append( polyline[0] )
1138 |                   rs.AddPolyline(polyline)
1139 |        
1140 |       TestMeshVertexFaces()
1141 |     See Also:
1142 |       MeshFaces
1143 |       MeshFaceVertices
1144 |       MeshVertices
1145 |     """
1146 |     mesh = rhutil.coercemesh(mesh_id, True)
1147 |     return mesh.Vertices.GetVertexFaces(vertex_index)
1148 | 
1149 | 
1150 | def MeshVertexNormals(mesh_id):
1151 |     """Returns the vertex unit normal for each vertex of a mesh
1152 |     Parameters:
1153 |       mesh_id (guid): identifier of a mesh object
1154 |     Returns:
1155 |       list(vector, ...): of vertex normals, (empty list if no normals exist)
1156 |     Example:
1157 |       import rhinoscriptsyntax as rs
1158 |       obj = rs.GetObject("Select mesh", rs.filter.mesh)
1159 |       normals = rs.MeshVertexNormals(obj)
1160 |       if normals:
1161 |           for normal in normals: print(normal)
1162 |     See Also:
1163 |       MeshHasVertexNormals
1164 |       MeshVertexCount
1165 |       MeshVertices
1166 |     """
1167 |     mesh = rhutil.coercemesh(mesh_id, True)
1168 |     count = mesh.Normals.Count
1169 |     if count<1: return []
1170 |     return [Rhino.Geometry.Vector3d(mesh.Normals[i]) for i in compat.RANGE(count)]
1171 | 
1172 | 
1173 | def MeshVertices(object_id):
1174 |     """Returns the vertices of a mesh
1175 |     Parameters:
1176 |       object_id (guid): identifier of a mesh object
1177 |     Returns:
1178 |       list(point, ...): vertex points in the mesh
1179 |     Example:
1180 |       import rhinoscriptsyntax as rs
1181 |       obj = rs.GetObject("Select mesh", rs.filter.mesh)
1182 |       vertices = rs.MeshVertices(obj)
1183 |       if vertices: rs.AddPointCloud(vertices)
1184 |     See Also:
1185 |       IsMesh
1186 |       MeshFaceCount
1187 |       MeshFaces
1188 |       MeshVertexCount
1189 |     """
1190 |     mesh = rhutil.coercemesh(object_id, True)
1191 |     count = mesh.Vertices.Count
1192 |     rc = []
1193 |     for i in compat.RANGE(count):
1194 |         vertex = mesh.Vertices.Point3dAt(i)
1195 |         rc.append(vertex)
1196 |     return rc
1197 | 
1198 | 
1199 | def MeshVolume(object_ids):
1200 |     """Returns the approximate volume of one or more closed meshes
1201 |     Parameters:
1202 |       object_ids ([guid, ...]): identifiers of one or more mesh objects
1203 |     Returns:
1204 |       tuple(number, number, number): containing 3 velues if successful where
1205 |            [0] = number of meshes used in volume calculation
1206 |            [1] = total volume of all meshes
1207 |            [2] = the error estimate
1208 |       None: if not successful
1209 |     Example:
1210 |       import rhinoscriptsyntax as rs
1211 |       obj = rs.GetObject("Select mesh", rs.filter.mesh )
1212 |       if obj and rs.IsMeshClosed(obj):
1213 |           volume = rs.MeshVolume(obj)
1214 |           if volume: print("Mesh volume:{}".format(volume[1]))
1215 |     See Also:
1216 |       IsMeshClosed
1217 |       MeshArea
1218 |     """
1219 |     id = rhutil.coerceguid(object_ids)
1220 |     if id: object_ids = [id]
1221 |     meshes_used = 0
1222 |     total_volume = 0.0
1223 |     error_estimate = 0.0
1224 |     for id in object_ids:
1225 |         mesh = rhutil.coercemesh(id, True)
1226 |         mp = Rhino.Geometry.VolumeMassProperties.Compute(mesh)
1227 |         if mp:
1228 |             meshes_used += 1
1229 |             total_volume += mp.Volume
1230 |             error_estimate += mp.VolumeError
1231 |     if meshes_used==0: return scriptcontext.errorhandler()
1232 |     return meshes_used, total_volume, error_estimate
1233 | 
1234 | 
1235 | def MeshVolumeCentroid(object_id):
1236 |     """Calculates the volume centroid of a mesh
1237 |     Parameters:
1238 |       object_id (guid): identifier of a mesh object
1239 |     Returns:
1240 |       point: Point3d representing the volume centroid
1241 |       None: on error
1242 |     Example:
1243 |       import rhinoscriptsyntax as rs
1244 |       obj = rs.GetObject("Select mesh", rs.filter.mesh )
1245 |       centroid = rs.MeshVolumeCentroid(obj)
1246 |       rs.AddPoint( centroid )
1247 |     See Also:
1248 |       IsMesh
1249 |       MeshArea
1250 |       MeshAreaCentroid
1251 |       MeshVolume
1252 |     """
1253 |     mesh = rhutil.coercemesh(object_id, True)
1254 |     mp = Rhino.Geometry.VolumeMassProperties.Compute(mesh)
1255 |     if mp: return mp.Centroid
1256 |     return scriptcontext.errorhandler()
1257 | 
1258 | 
1259 | def PullCurveToMesh(mesh_id, curve_id):
1260 |     """Pulls a curve to a mesh. The function makes a polyline approximation of
1261 |     the input curve and gets the closest point on the mesh for each point on
1262 |     the polyline. Then it "connects the points" to create a polyline on the mesh
1263 |     Parameters:
1264 |       mesh_id (guid): identifier of mesh that pulls
1265 |       curve_id (guid): identifier of curve to pull
1266 |     Returns:
1267 |       guid: identifier new curve on success
1268 |       None: on error
1269 |     Example:
1270 |       import rhinoscriptsyntax as rs
1271 |       mesh = rs.GetObject("Select mesh that pulls", rs.filter.mesh)
1272 |       curve = rs.GetObject("Select curve to pull", rs.filter.curve)
1273 |       rs.PullCurveToMesh( mesh, curve )
1274 |     See Also:
1275 |       IsMesh
1276 |     """
1277 |     mesh = rhutil.coercemesh(mesh_id, True)
1278 |     curve = rhutil.coercecurve(curve_id, -1, True)
1279 |     tol = scriptcontext.doc.ModelAbsoluteTolerance
1280 |     polyline = curve.PullToMesh(mesh, tol)
1281 |     if not polyline: return scriptcontext.errorhandler()
1282 |     rc = scriptcontext.doc.Objects.AddCurve(polyline)
1283 |     if rc==System.Guid.Empty: raise Exception("unable to add polyline to document")
1284 |     scriptcontext.doc.Views.Redraw()
1285 |     return rc
1286 | 
1287 | 
1288 | def SplitDisjointMesh(object_id, delete_input=False):
1289 |     """Splits up a mesh into its unconnected pieces
1290 |     Parameters:
1291 |       object_id (guid): identifier of a mesh object
1292 |       delete_input (bool, optional): delete the input object
1293 |     Returns:
1294 |       list(guid, ...): identifiers for the new meshes
1295 |     Example:
1296 |       import rhinoscriptsyntax as rs
1297 |       obj = rs.GetObject("Select mesh", rs.filter.mesh)
1298 |       if rs.DisjointMeshCount(obj)>0: rs.SplitDisjointMesh(obj)
1299 |     See Also:
1300 |       IsMesh
1301 |       DisjointMeshCount
1302 |     """
1303 |     mesh = rhutil.coercemesh(object_id, True)
1304 |     pieces = mesh.SplitDisjointPieces()
1305 |     rc = [scriptcontext.doc.Objects.AddMesh(piece) for piece in pieces]
1306 |     if rc and delete_input:
1307 |         id = rhutil.coerceguid(object_id, True)
1308 |         scriptcontext.doc.Objects.Delete(id, True)
1309 |     scriptcontext.doc.Views.Redraw()
1310 |     return rc
1311 | 
1312 | 
1313 | def UnifyMeshNormals(object_id):
1314 |     """Fixes inconsistencies in the directions of faces of a mesh
1315 |     Parameters:
1316 |       object_id (guid): identifier of a mesh object
1317 |     Returns:
1318 |       number: the number of faces that were modified
1319 |     Example:
1320 |       import rhinoscriptsyntax as rs
1321 |       obj = rs.GetObject("Select mesh", rs.filter.mesh)
1322 |       if rs.IsMesh(obj): rs.UnifyMeshNormals(obj)
1323 |     See Also:
1324 |       IsMesh
1325 |     """
1326 |     mesh = rhutil.coercemesh(object_id, True)
1327 |     rc = mesh.UnifyNormals()
1328 |     if rc>0:
1329 |         id = rhutil.coerceguid(object_id, True)
1330 |         scriptcontext.doc.Objects.Replace(id, mesh)
1331 |         scriptcontext.doc.Views.Redraw()
1332 |     return rc
1333 | 
```

--------------------------------------------------------------------------------
/rhino_mcp_server/static/userinterface.py:
--------------------------------------------------------------------------------

```python
   1 | import math
   2 | 
   3 | import System
   4 | import System.Drawing
   5 | import System.Windows.Forms
   6 | 
   7 | import Eto.Forms
   8 | 
   9 | import Rhino
  10 | import Rhino.UI
  11 | 
  12 | import scriptcontext
  13 | 
  14 | import rhinocompat as compat
  15 | from rhinoscript import utility as rhutil
  16 | from rhinoscript.view import __viewhelper
  17 | 
  18 | 
  19 | def BrowseForFolder(folder=None, message=None, title=None):
  20 |     """Display browse-for-folder dialog allowing the user to select a folder
  21 |     Parameters:
  22 |       folder (str, optional): a default folder
  23 |       message (str, optional): a prompt or message
  24 |       title (str, optional): a dialog box title
  25 |     Returns:
  26 |       str: selected folder
  27 |       None: on error
  28 |     Example:
  29 |       import rhinoscriptsyntax as rs
  30 |       folder = rs.BrowseForFolder("C:\\Program Files\\" )
  31 |       if folder: print(folder)
  32 |     See Also:
  33 |       OpenFileName
  34 |       SaveFileName
  35 |     """
  36 |     dlg = Eto.Forms.SelectFolderDialog()
  37 |     if folder:
  38 |         if not isinstance(folder, str): folder = str(folder)
  39 |         dlg.Directory = folder
  40 |     if message:
  41 |         if not isinstance(message, str): message = str(message)
  42 |         dlg.Title = message
  43 |     if title:
  44 |         if not isinstance(title, str): title = str(title)
  45 |         dlg.Title = title
  46 |     if message and title:
  47 |         if not isinstance(message, str): message = str(message)
  48 |         if not isinstance(title, str): title = str(title)
  49 |         dlg.Title = title + ": " + message
  50 |     if dlg.ShowDialog(None)==Eto.Forms.DialogResult.Ok:
  51 |         return dlg.Directory
  52 | 
  53 | 
  54 | def CheckListBox(items, message=None, title=None):
  55 |     """Displays a list of items in a checkable-style list dialog box
  56 |     Parameters:
  57 |       items ([[str, bool], ...]): a list of tuples containing a string and a boolean check state
  58 |       message (str, optional):  a prompt or message
  59 |       title (str, optional):  a dialog box title
  60 |     Returns:
  61 |       list((str, bool), ...): of tuples containing the input string in items along with their new boolean check value
  62 |       None: on error
  63 |     Example:
  64 |       import rhinoscriptsyntax as  rs
  65 |       layers = rs.LayerNames()
  66 |       if layers:
  67 |           items  = [(layer, rs.IsLayerOn(layer)) for layer in layers]
  68 |           results  = rs.CheckListBox(items, "Turn layers on/off", "Layers")
  69 |           if results:
  70 |               for  layer, state in results: rs.LayerVisible(layer, state)
  71 |     See Also:
  72 |       ComboListBox
  73 |       ListBox
  74 |       MultiListBox
  75 |       PropertyListBox
  76 |     """
  77 |     checkstates = [item[1] for item in items]
  78 |     itemstrs = [str(item[0]) for item in items]
  79 |     newcheckstates = Rhino.UI.Dialogs.ShowCheckListBox(title, message, itemstrs, checkstates)
  80 |     if newcheckstates:
  81 |         rc = compat.ITERATOR2LIST(zip(itemstrs, newcheckstates))
  82 |         return rc
  83 |     return scriptcontext.errorhandler()
  84 | 
  85 | 
  86 | def ComboListBox(items, message=None, title=None):
  87 |     """Displays a list of items in a combo-style list box dialog.
  88 |     Parameters:
  89 |       items ([str, ...]): a list of string
  90 |       message (str, optional):  a prompt of message
  91 |       title (str, optional):  a dialog box title
  92 |     Returns:
  93 |       str: The selected item if successful
  94 |       None: if not successful or on error
  95 |     Example:
  96 |       import rhinoscriptsyntax as rs
  97 |       layers = rs.LayerNames()
  98 |       if layers:
  99 |           layer = rs.ComboListBox(layers, "Select current layer")
 100 |           if layer: rs.CurrentLayer(layer)
 101 |     See Also:
 102 |       CheckListBox
 103 |       ListBox
 104 |       MultiListBox
 105 |       PropertyListBox
 106 |     """
 107 |     return Rhino.UI.Dialogs.ShowComboListBox(title, message, items)
 108 | 
 109 | 
 110 | def EditBox(default_string=None, message=None, title=None):
 111 |     """Display dialog prompting the user to enter a string. The
 112 |     string value may span multiple lines
 113 |     Parameters:
 114 |       default_string  (str, optional):  a default string value.
 115 |       message (str, optional): a prompt message.
 116 |       title (str, optional): a dialog box title.
 117 |     Returns:
 118 |       str: Multiple lines that are separated by carriage return-linefeed combinations if successful
 119 |       None: if not successful
 120 |     Example:
 121 |       import rhinoscriptsyntax as rs
 122 |       text = rs.EditBox(message="Enter some text")
 123 |       print(text)
 124 |     See Also:
 125 |       GetString
 126 |       StringBox
 127 |     """
 128 |     rc, text = Rhino.UI.Dialogs.ShowEditBox(title, message, default_string, True)
 129 |     return text
 130 | 
 131 | def GetAngle(point=None, reference_point=None, default_angle_degrees=0, message=None):
 132 |     """Pause for user input of an angle
 133 |     Parameters:
 134 |       point (point): starting, or base point
 135 |       reference_point (point, optional): if specified, the reference angle is calculated
 136 |         from it and the base point
 137 |       default_angle_degrees (number, optional): a default angle value specified
 138 |       message (str, optional): a prompt to display
 139 |     Returns:
 140 |       number: angle in degree if successful
 141 |       None: on error
 142 |     Example:
 143 |       import rhinoscriptsyntax as rs
 144 |       point = rs.GetPoint("Base point")
 145 |       if point:
 146 |           reference = rs.GetPoint("Reference point", point)
 147 |           if reference:
 148 |               angle = rs.GetAngle(point, reference)
 149 |               if angle!=None: print("Angle:{}".format(angle))
 150 |     See Also:
 151 |       GetDistance
 152 |     """
 153 |     point = rhutil.coerce3dpoint(point)
 154 |     if not point: point = Rhino.Geometry.Point3d.Unset
 155 |     reference_point = rhutil.coerce3dpoint(reference_point)
 156 |     if not reference_point: reference_point = Rhino.Geometry.Point3d.Unset
 157 |     default_angle = math.radians(default_angle_degrees)
 158 |     rc, angle = Rhino.Input.RhinoGet.GetAngle(message, point, reference_point, default_angle)
 159 |     if rc==Rhino.Commands.Result.Success: return math.degrees(angle)
 160 | 
 161 | 
 162 | def GetBoolean(message, items, defaults):
 163 |     """Pauses for user input of one or more boolean values. Boolean values are
 164 |     displayed as click-able command line option toggles
 165 |     Parameters:
 166 |       message (str): a prompt
 167 |       items ([str, str, str], ...): list or tuple of options. Each option is a tuple of three strings
 168 |         [n][1]    description of the boolean value. Must only consist of letters
 169 |                   and numbers. (no characters like space, period, or dash
 170 |         [n][2]    string identifying the false value
 171 |         [n][3]    string identifying the true value
 172 |       defaults ([bool, ...]): list of boolean values used as default or starting values
 173 |     Returns:
 174 |       list(bool, ...): a list of values that represent the boolean values if successful
 175 |       None: on error
 176 |     Example:
 177 |       import rhinoscriptsyntax as rs
 178 |       items = ("Lights", "Off", "On"), ("Cameras", "Disabled", "Enabled"), ("Action", "False", "True")
 179 |       results = rs.GetBoolean("Boolean options", items, (True, True, True) )
 180 |       if results:
 181 |           for val in results: print(val)
 182 |     See Also:
 183 |       GetString
 184 |     """
 185 |     go = Rhino.Input.Custom.GetOption()
 186 |     go.AcceptNothing(True)
 187 |     go.SetCommandPrompt( message )
 188 |     if type(defaults) is list or type(defaults) is tuple: pass
 189 |     else: defaults = [defaults]
 190 |     # special case for single list. Wrap items into a list
 191 |     if len(items)==3 and len(defaults)==1: items = [items]
 192 |     count = len(items)
 193 |     if count<1 or count!=len(defaults): return scriptcontext.errorhandler()
 194 |     toggles = []
 195 |     for i in compat.RANGE(count):
 196 |         initial = defaults[i]
 197 |         item = items[i]
 198 |         offVal = item[1]
 199 |         t = Rhino.Input.Custom.OptionToggle( initial, item[1], item[2] )
 200 |         toggles.append(t)
 201 |         go.AddOptionToggle(item[0], t)
 202 |     while True:
 203 |         getrc = go.Get()
 204 |         if getrc==Rhino.Input.GetResult.Option: continue
 205 |         if getrc!=Rhino.Input.GetResult.Nothing: return None
 206 |         break
 207 |     return [t.CurrentValue for t in toggles]
 208 | 
 209 | 
 210 | def GetBox(mode=0, base_point=None, prompt1=None, prompt2=None, prompt3=None):
 211 |     """Pauses for user input of a box
 212 |     Parameters:
 213 |       mode (number): The box selection mode.
 214 |          0 = All modes
 215 |          1 = Corner. The base rectangle is created by picking two corner points
 216 |          2 = 3-Point. The base rectangle is created by picking three points
 217 |          3 = Vertical. The base vertical rectangle is created by picking three points.
 218 |          4 = Center. The base rectangle is created by picking a center point and a corner point
 219 |       base_point (point, optional): optional 3D base point
 220 |       prompt1, prompt2, prompt3 (str, optional): optional prompts to set
 221 |     Returns:
 222 |       list(point, ...): list of eight Point3d that define the corners of the box on success
 223 |       None: is not successful, or on error
 224 |     Example:
 225 |       import rhinoscriptsyntax as rs
 226 |       box = rs.GetBox()
 227 |       if box:
 228 |           for i, pt in enumerate(box): rs.AddTextDot( i, pt )
 229 |     See Also:
 230 |       GetRectangle
 231 |     """
 232 |     base_point = rhutil.coerce3dpoint(base_point)
 233 |     if base_point is None: base_point = Rhino.Geometry.Point3d.Unset
 234 |     def intToEnum(m):
 235 |       if m not in compat.RANGE(1,5):
 236 |         m = 0
 237 |       return {
 238 |         0 : Rhino.Input.GetBoxMode.All,
 239 |         1 : Rhino.Input.GetBoxMode.Corner,
 240 |         2 : Rhino.Input.GetBoxMode.ThreePoint,
 241 |         3 : Rhino.Input.GetBoxMode.Vertical,
 242 |         4 : Rhino.Input.GetBoxMode.Center
 243 |       }[m]
 244 |     rc, box = Rhino.Input.RhinoGet.GetBox(intToEnum(mode), base_point, prompt1, prompt2, prompt3)
 245 |     if rc==Rhino.Commands.Result.Success: return tuple(box.GetCorners())
 246 | 
 247 | 
 248 | def GetColor(color=[0,0,0]):
 249 |     """Display the Rhino color picker dialog allowing the user to select an RGB color
 250 |     Parameters:
 251 |       color (color, optional): default RGB value. If omitted, the default color is black
 252 |     Returns:
 253 |       color: RGB tuple of three numbers on success
 254 |       None: on error
 255 |     Example:
 256 |       import rhinoscriptsyntax as rs
 257 |       color = rs.LayerColor("Default")
 258 |       rgb = rs.GetColor(color)
 259 |       if rgb: rs.LayerColor("Default", rgb)
 260 |     See Also:
 261 |       
 262 |     """
 263 |     color = rhutil.coercecolor(color)
 264 |     if color is None: color = System.Drawing.Color.Black
 265 |     rc, color = Rhino.UI.Dialogs.ShowColorDialog(color)
 266 |     if rc: return color.R, color.G, color.B
 267 |     return scriptcontext.errorhandler()
 268 | 
 269 | 
 270 | def GetCursorPos():
 271 |     """Retrieves the cursor's position
 272 |     Returns:
 273 |       tuple(point, point, guid, point) containing the following information
 274 |         [0]  cursor position in world coordinates
 275 |         [1]  cursor position in screen coordinates
 276 |         [2]  id of the active viewport
 277 |         [3]  cursor position in client coordinates
 278 |     Example:
 279 |       import rhinoscriptsyntax as  rs
 280 |       world, screen, view, client  = rs.GetCursorPos()
 281 |     See Also:
 282 |       XformScreenToWorld
 283 |       XformWorldToScreen
 284 |     """
 285 |     view = scriptcontext.doc.Views.ActiveView
 286 |     screen_pt = Rhino.UI.MouseCursor.Location
 287 |     client_pt = view.ScreenToClient(screen_pt)
 288 |     viewport = view.ActiveViewport
 289 |     xf = viewport.GetTransform(Rhino.DocObjects.CoordinateSystem.Screen, Rhino.DocObjects.CoordinateSystem.World)
 290 |     world_pt = Rhino.Geometry.Point3d(client_pt.X, client_pt.Y, 0)
 291 |     world_pt.Transform(xf)
 292 |     return world_pt, screen_pt, viewport.Id, client_pt
 293 | 
 294 | 
 295 | def GetDistance(first_pt=None, distance=None, first_pt_msg='First distance point', second_pt_msg='Second distance point'):
 296 |     """Pauses for user input of a distance.
 297 |     Parameters:
 298 |       first_pt (point, optional): First distance point
 299 |       distance (number, optional): Default distance
 300 |       first_pt_msg (str, optional): Prompt for the first distance point
 301 |       second_pt_msg (str, optional): Prompt for the second distance point
 302 |     Returns:
 303 |       number: The distance between the two points if successful.
 304 |       None: if not successful, or on error.
 305 |     Example:
 306 |       import rhinoscriptsyntax as  rs
 307 |       dist = rs.GetDistance()
 308 |       if dist:
 309 |           print( dist)
 310 |     See Also:
 311 |       GetAngle
 312 |     """
 313 |     if distance is not None and first_pt is None: 
 314 |         raise Exception("The 'first_pt' parameter needs a value if 'distance' is not None.")
 315 |     if distance is not None and not (isinstance(distance, int) or isinstance(distance, float)): return None
 316 |     if first_pt_msg is None or not isinstance(first_pt_msg, str): return None
 317 |     if second_pt_msg is None or not isinstance(second_pt_msg, str): return None
 318 | 
 319 |     if first_pt is not None:
 320 |       if first_pt == 0: first_pt = (0,0,0)
 321 |       first_pt = rhutil.coerce3dpoint(first_pt)
 322 |       if first_pt is None: return None
 323 | 
 324 |     if first_pt is None:
 325 |       first_pt = GetPoint(first_pt_msg)
 326 |       if first_pt is None: return None
 327 | 
 328 |     # cannot use GetPoint for 2nd point because of the need do differentiate 
 329 |     # between the user accepting none vs cancelling to exactly mimic RhinoScript
 330 |     gp = Rhino.Input.Custom.GetPoint()
 331 |     if distance is not None:
 332 |       gp.AcceptNothing(True)
 333 |       second_pt_msg = "{0}<{1}>".format(second_pt_msg, distance)
 334 |     gp.SetCommandPrompt(second_pt_msg)
 335 |     gp.DrawLineFromPoint(first_pt,True)
 336 |     gp.EnableDrawLineFromPoint(True)
 337 |     r = gp.Get()
 338 |     if r not in [Rhino.Input.GetResult.Cancel, Rhino.Input.GetResult.Point,
 339 |       Rhino.Input.GetResult.Nothing]: return scriptcontext.errorHandler()
 340 |     if r == Rhino.Input.GetResult.Cancel: return None
 341 |     if r == Rhino.Input.GetResult.Point:
 342 |       second_pt = gp.Point()
 343 |       distance = second_pt.DistanceTo(first_pt)
 344 |     gp.Dispose()
 345 | 
 346 |     return distance
 347 | 
 348 | 
 349 | def GetEdgeCurves(message=None, min_count=1, max_count=0, select=False):
 350 |     """Prompt the user to pick one or more surface or polysurface edge curves
 351 |     Parameters:
 352 |       message  (str, optional):  A prompt or message.
 353 |       min_count (number, optional): minimum number of edges to select.
 354 |       max_count (number, optional): maximum number of edges to select.
 355 |       select (bool, optional): Select the duplicated edge curves.
 356 |     Returns:
 357 |       list(tuple[guid, point, point], ...): of selection prompts (curve id, parent id, selection point)
 358 |       None: if not successful
 359 |     Example:
 360 |       import rhinoscriptsyntax as rs
 361 |       edges = rs.GetEdgeCurves()
 362 |       if edges:
 363 |           for edgeinfo in edges:
 364 |               print("Curve Id ={}".format(edgeinfo[0]))
 365 |               print("Parent Id ={}".format(edgeinfo[1]))
 366 |               print("Pick point ={}".format(edgeinfo[2]))
 367 |     See Also:
 368 |       DuplicateEdgeCurves
 369 |     """
 370 |     if min_count<0 or (max_count>0 and min_count>max_count): return
 371 |     if not message: message = "Select Edges"
 372 |     go = Rhino.Input.Custom.GetObject()
 373 |     go.SetCommandPrompt(message)
 374 |     go.GeometryFilter = Rhino.DocObjects.ObjectType.Curve
 375 |     go.GeometryAttributeFilter = Rhino.Input.Custom.GeometryAttributeFilter.EdgeCurve
 376 |     go.EnablePreSelect(False, True)
 377 |     rc = go.GetMultiple(min_count, max_count)
 378 |     if rc!=Rhino.Input.GetResult.Object: return
 379 |     rc = []
 380 |     for i in compat.RANGE(go.ObjectCount):
 381 |         edge = go.Object(i).Edge()
 382 |         if not edge: continue
 383 |         edge = edge.Duplicate()
 384 |         curve_id = scriptcontext.doc.Objects.AddCurve(edge)
 385 |         parent_id = go.Object(i).ObjectId
 386 |         pt = go.Object(i).SelectionPoint()
 387 |         rc.append( (curve_id, parent_id, pt) )
 388 |     if select:
 389 |         for item in rc:
 390 |             rhobj = scriptcontext.doc.Objects.Find(item[0])
 391 |             rhobj.Select(True)
 392 |         scriptcontext.doc.Views.Redraw()
 393 |     return rc        
 394 | 
 395 | 
 396 | def GetInteger(message=None, number=None, minimum=None, maximum=None):
 397 |     """Pauses for user input of a whole number.
 398 |     Parameters:
 399 |       message (str, optional): A prompt or message.
 400 |       number (number, optional): A default whole number value.
 401 |       minimum (number, optional): A minimum allowable value.
 402 |       maximum (number, optional): A maximum allowable value.
 403 |     Returns:
 404 |        number: The whole number input by the user if successful.
 405 |        None: if not successful, or on error
 406 |     Example:
 407 |       import rhinoscriptsyntax as rs
 408 |       color = rs.LayerColor("Default")
 409 |       color = rs.GetInteger("Enter an RGB color value", color.ToArgb(), 0)
 410 |       if color: rs.LayerColor("Default", color)
 411 |     See Also:
 412 |       
 413 |     """
 414 |     gi = Rhino.Input.Custom.GetInteger()
 415 |     if message: gi.SetCommandPrompt(message)
 416 |     if number is not None: gi.SetDefaultInteger(number)
 417 |     if minimum is not None: gi.SetLowerLimit(minimum, False)
 418 |     if maximum is not None: gi.SetUpperLimit(maximum, False)
 419 |     if gi.Get()!=Rhino.Input.GetResult.Number: return scriptcontext.errorhandler()
 420 |     rc = gi.Number()
 421 |     gi.Dispose()
 422 |     return rc
 423 | 
 424 | 
 425 | def GetLayer(title="Select Layer", layer=None, show_new_button=False, show_set_current=False):
 426 |     """Displays dialog box prompting the user to select a layer
 427 |     Parameters:
 428 |       title (str, optional): dialog box title
 429 |       layer (str, optional): name of a layer to preselect. If omitted, the current layer will be preselected
 430 |       show_new_button, show_set_current (bool, optional): Optional buttons to show on the dialog
 431 |     Returns:
 432 |       str: name of selected layer if successful
 433 |       None: on error
 434 |     Example:
 435 |       import rhinoscriptsyntax as rs
 436 |       obj = rs.GetObject("Select object")
 437 |       if obj:
 438 |           layer = rs.GetLayer("Select Layer", rs.ObjectLayer(obj), True, True)
 439 |           if layer: rs.ObjectLayer( obj, layer )
 440 |     See Also:
 441 |       
 442 |     """
 443 |     layer_index = scriptcontext.doc.Layers.CurrentLayerIndex
 444 |     if layer:
 445 |         if "::" in layer:
 446 |             idx = scriptcontext.doc.Layers.FindByFullPath(layer,-1)
 447 |             if idx != -1: 
 448 |                 layer_index = idx
 449 |             else:
 450 |                 # layer name could have embedded '::'
 451 |                 layer_instance = scriptcontext.doc.Layers.FindName(layer)
 452 |                 if layer_instance is not None: layer_index = layer_instance.Index
 453 |         else:
 454 |             layer_instance = scriptcontext.doc.Layers.FindName(layer)
 455 |             if layer_instance is not None: layer_index = layer_instance.Index
 456 |     rc = Rhino.UI.Dialogs.ShowSelectLayerDialog(layer_index, title, show_new_button, show_set_current, True)
 457 |     if rc[0]!=True: return None
 458 |     layer = scriptcontext.doc.Layers[rc[1]]
 459 |     return layer.FullPath
 460 | 
 461 | 
 462 | def GetLayers(title="Select Layers", show_new_button=False):
 463 |     """Displays a dialog box prompting the user to select one or more layers
 464 |     Parameters:
 465 |       title (str, optional):  dialog box title
 466 |       show_new_button (bool, optional): Optional button to show on the dialog
 467 |     Returns:
 468 |       str: The names of selected layers if successful
 469 |     Example:
 470 |       import rhinoscriptsyntax as rs
 471 |       layers = rs.GetLayers("Select Layers")
 472 |       if layers:
 473 |           for layer in layers: print(layer)
 474 |     See Also:
 475 |       GetLayer
 476 |     """
 477 |     rc, layer_indices = Rhino.UI.Dialogs.ShowSelectMultipleLayersDialog(None, title, show_new_button)
 478 |     if rc:
 479 |         return [scriptcontext.doc.Layers[index].FullPath for index in layer_indices]
 480 | 
 481 | 
 482 | def GetLine(mode=0, point=None, message1=None, message2=None, message3=None):
 483 |     """Prompts the user to pick points that define a line
 484 |     Parameters:
 485 |       mode (number, optional): line definition mode.
 486 |         0  Default - Show all modes, start in two-point mode
 487 |         1  Two-point - Defines a line from two points.
 488 |         2  Normal - Defines a line normal to a location on a surface.
 489 |         3  Angled - Defines a line at a specified angle from a reference line.
 490 |         4  Vertical - Defines a line vertical to the construction plane.
 491 |         5  Four-point - Defines a line using two points to establish direction and two points to establish length.
 492 |         6  Bisector - Defines a line that bisects a specified angle.
 493 |         7  Perpendicular - Defines a line perpendicular to or from a curve
 494 |         8  Tangent - Defines a line tangent from a curve.
 495 |         9  Extension - Defines a line that extends from a curve.
 496 |       point (point, optional): optional starting point
 497 |       message1, message2, message3 (str, optional): optional prompts
 498 |     Returns:
 499 |       line: Tuple of two points on success
 500 |       None: on error
 501 |     Example:
 502 |       import rhinoscriptsyntax as  rs
 503 |       line = rs.GetLine()
 504 |       if line: rs.AddLine( line[0],  line[1] )
 505 |     See Also:
 506 |       GetBox
 507 |       GetPoint
 508 |       GetPolyline
 509 |       GetRectangle
 510 |     """
 511 |     gl = Rhino.Input.Custom.GetLine()
 512 |     if mode==0: gl.EnableAllVariations(True)
 513 |     else: gl.GetLineMode = System.Enum.ToObject( Rhino.Input.Custom.GetLineMode, mode-1 )
 514 |     if point:
 515 |         point = rhutil.coerce3dpoint(point)
 516 |         gl.SetFirstPoint(point)
 517 |     if message1: gl.FirstPointPrompt = message1
 518 |     if message2: gl.MidPointPrompt = message2
 519 |     if message3: gl.SecondPointPrompt = message3
 520 |     rc, line = gl.Get()
 521 |     if rc==Rhino.Commands.Result.Success: return line.From, line.To
 522 | 
 523 | 
 524 | def GetLinetype(default_linetype=None, show_by_layer=False):
 525 |     """Displays a dialog box prompting the user to select one linetype
 526 |     Parameters:
 527 |       default_linetype (str, optional):  Optional. The name of the linetype to select. If omitted, the current linetype will be selected.
 528 |       show_by_layer (bool, optional): If True, the "by Layer" linetype will show. Defaults to False.
 529 |     Returns:
 530 |       str: The names of selected linetype if successful
 531 |     Example:
 532 |       import rhinoscriptsyntax as rs
 533 |       linetype = rs.GetLinetype()
 534 |       if linetype: print(linetype)
 535 |     See Also:
 536 |       GetLayer
 537 |     """
 538 |     lt_instance = scriptcontext.doc.Linetypes.CurrentLinetype
 539 |     if default_linetype:
 540 |         lt_new = scriptcontext.doc.Linetypes.FindName(default_linetype)
 541 |         if lt_new is not None: lt_instance = lt_new
 542 |     id = Rhino.UI.Dialogs.ShowLineTypes("Select Linetype", "", scriptcontext.doc)
 543 |     if id == System.Guid.Empty: return None
 544 |     linetype = scriptcontext.doc.Linetypes.FindId(id)
 545 |     return linetype.Name
 546 | 
 547 | def GetMeshFaces(object_id, message="", min_count=1, max_count=0):
 548 |     """Prompts the user to pick one or more mesh faces
 549 |     Parameters:
 550 |       object_id (guid): the mesh object's identifier
 551 |       message (str, optional): a prompt of message
 552 |       min_count (number, optional): the minimum number of faces to select
 553 |       max_count (number, optional): the maximum number of faces to select.
 554 |         If 0, the user must press enter to finish selection.
 555 |         If -1, selection stops as soon as there are at least min_count faces selected.
 556 |     Returns:
 557 |       list(number, ...): of mesh face indices on success
 558 |       None: on error
 559 |     Example:
 560 |       import rhinoscriptsyntax as rs
 561 |       mesh = rs.GetObject("Select mesh", rs.filter.mesh)
 562 |       if mesh:
 563 |           indices = rs.GetMeshFaces(mesh)
 564 |           if indices:
 565 |               for index in indices: print(index)
 566 |     See Also:
 567 |       GetMeshVertices
 568 |       MeshFaces
 569 |       MeshFaceVertices
 570 |       MeshVertices
 571 |     """
 572 |     scriptcontext.doc.Objects.UnselectAll()
 573 |     scriptcontext.doc.Views.Redraw()
 574 |     object_id = rhutil.coerceguid(object_id, True)
 575 |     def FilterById( rhino_object, geometry, component_index ):
 576 |         return object_id == rhino_object.Id
 577 |     go = Rhino.Input.Custom.GetObject()
 578 |     go.SetCustomGeometryFilter(FilterById)
 579 |     if message: go.SetCommandPrompt(message)
 580 |     go.GeometryFilter = Rhino.DocObjects.ObjectType.MeshFace
 581 |     go.AcceptNothing(True)
 582 |     if go.GetMultiple(min_count,max_count)!=Rhino.Input.GetResult.Object: return None
 583 |     objrefs = go.Objects()
 584 |     rc = [item.GeometryComponentIndex.Index for item in objrefs]
 585 |     go.Dispose()
 586 |     return rc
 587 | 
 588 | 
 589 | def GetMeshVertices(object_id, message="", min_count=1, max_count=0):
 590 |     """Prompts the user to pick one or more mesh vertices
 591 |     Parameters:
 592 |       object_id (guid): the mesh object's identifier
 593 |       message (str, optional): a prompt of message
 594 |       min_count (number, optional): the minimum number of vertices to select
 595 |       max_count (number, optional): the maximum number of vertices to select. If 0, the user must
 596 |         press enter to finish selection. If -1, selection stops as soon as there
 597 |         are at least min_count vertices selected.
 598 |     Returns:
 599 |       list(number, ...): of mesh vertex indices on success
 600 |       None: on error
 601 |     Example:
 602 |       import rhinoscriptsyntax as rs
 603 |       mesh = rs.GetObject("Select mesh", rs.filter.mesh)
 604 |       if mesh:
 605 |           indices = rs.GetMeshVertices(mesh)
 606 |           if indices:
 607 |               for index in indices: print(index)
 608 |     See Also:
 609 |       GetMeshFaces
 610 |       MeshFaces
 611 |       MeshFaceVertices
 612 |       MeshVertices
 613 |     """
 614 |     scriptcontext.doc.Objects.UnselectAll()
 615 |     scriptcontext.doc.Views.Redraw()
 616 |     object_id = rhutil.coerceguid(object_id, True)
 617 |     class CustomGetObject(Rhino.Input.Custom.GetObject):
 618 |         def CustomGeometryFilter( self, rhino_object, geometry, component_index ):
 619 |             return object_id == rhino_object.Id
 620 |     go = CustomGetObject()
 621 |     if message: go.SetCommandPrompt(message)
 622 |     go.GeometryFilter = Rhino.DocObjects.ObjectType.MeshVertex
 623 |     go.AcceptNothing(True)
 624 |     if go.GetMultiple(min_count,max_count)!=Rhino.Input.GetResult.Object: return None
 625 |     objrefs = go.Objects()
 626 |     rc = [item.GeometryComponentIndex.Index for item in objrefs]
 627 |     go.Dispose()
 628 |     return rc
 629 | 
 630 | 
 631 | def GetPoint(message=None, base_point=None, distance=None, in_plane=False):
 632 |     """Pauses for user input of a point.
 633 |     Parameters:
 634 |       message (str, optional): A prompt or message.
 635 |       base_point (point, optional): list of 3 numbers or Point3d identifying a starting, or base point
 636 |       distance  (number, optional): constraining distance. If distance is specified, basePoint must also be specified.
 637 |       in_plane (bool, optional): constrains the point selections to the active construction plane.
 638 |     Returns:
 639 |       point: point on success
 640 |       None: if no point picked or user canceled
 641 |     Example:
 642 |       import rhinoscriptsyntax as rs
 643 |       point1 = rs.GetPoint("Pick first point")
 644 |       if point1:
 645 |           rs.AddPoint(point1)
 646 |           point2 = rs.GetPoint("Pick second point", point1)
 647 |           if point2:
 648 |               rs.AddPoint(point2)
 649 |               distance = (point1-point2).Length
 650 |               point3 = rs.GetPoint("Pick third point", point2, distance)
 651 |               if point3: rs.AddPoint(point3)
 652 |     See Also:
 653 |       GetPointOnCurve
 654 |       GetPointOnSurface
 655 |       GetPoints
 656 |       GetRectangle
 657 |     """
 658 |     gp = Rhino.Input.Custom.GetPoint()
 659 |     if message: gp.SetCommandPrompt(message)
 660 |     base_point = rhutil.coerce3dpoint(base_point)
 661 |     if base_point:
 662 |         gp.DrawLineFromPoint(base_point,True)
 663 |         gp.EnableDrawLineFromPoint(True)
 664 |         if distance: gp.ConstrainDistanceFromBasePoint(distance)
 665 |     if in_plane: gp.ConstrainToConstructionPlane(True)
 666 |     gp.Get()
 667 |     if gp.CommandResult()!=Rhino.Commands.Result.Success:
 668 |         return scriptcontext.errorhandler()
 669 |     pt = gp.Point()
 670 |     gp.Dispose()
 671 |     return pt
 672 | 
 673 | 
 674 | def GetPointOnCurve(curve_id, message=None):
 675 |     """Pauses for user input of a point constrainted to a curve object
 676 |     Parameters:
 677 |       curve_id (guid): identifier of the curve to get a point on
 678 |       message (str, optional): a prompt of message
 679 |     Returns:
 680 |       point: 3d point if successful
 681 |       None: on error
 682 |     Example:
 683 |       import rhinoscriptsyntax as rs
 684 |       obj = rs.GetObject("Pick a curve")
 685 |       if rs.IsCurve(obj):
 686 |           point = rs.GetPointOnCurve(obj, "Point on curve")
 687 |           if point: rs.AddPoint(point)
 688 |     See Also:
 689 |       GetPoint
 690 |       GetPointOnMesh
 691 |       GetPointOnSurface
 692 |       GetPoints
 693 |     """
 694 |     curve = rhutil.coercecurve(curve_id, -1, True)
 695 |     gp = Rhino.Input.Custom.GetPoint()
 696 |     if message: gp.SetCommandPrompt(message)
 697 |     gp.Constrain(curve, False)
 698 |     gp.Get()
 699 |     if gp.CommandResult()!=Rhino.Commands.Result.Success:
 700 |         return scriptcontext.errorhandler()
 701 |     pt = gp.Point()
 702 |     gp.Dispose()
 703 |     return pt
 704 | 
 705 | 
 706 | def GetPointOnMesh(mesh_id, message=None):
 707 |     """Pauses for user input of a point constrained to a mesh object
 708 |     Parameters:
 709 |       mesh_id (guid): identifier of the mesh to get a point on
 710 |       message (str, optional): a prompt or message
 711 |     Returns:
 712 |       point: 3d point if successful
 713 |       None: on error
 714 |     Example:
 715 |       import rhinoscriptsyntax as rs
 716 |       mesh = rs.GetObject("Pick a mesh", rs.filter.mesh)
 717 |       if mesh:
 718 |           point = rs.GetPointOnMesh(mesh, "Point on mesh")
 719 |           if point: rs.AddPoint( point )
 720 |     See Also:
 721 |       GetPoint
 722 |       GetPointOnCurve
 723 |       GetPointOnSurface
 724 |       GetPoints
 725 |     """
 726 |     mesh_id = rhutil.coerceguid(mesh_id, True)
 727 |     if not message: message = "Point"
 728 |     cmdrc, point = Rhino.Input.RhinoGet.GetPointOnMesh(mesh_id, message, False)
 729 |     if cmdrc==Rhino.Commands.Result.Success: return point
 730 | 
 731 | 
 732 | def GetPointOnSurface(surface_id, message=None):
 733 |     """Pauses for user input of a point constrained to a surface or polysurface
 734 |     object
 735 |     Parameters:
 736 |       surface_id (guid): identifier of the surface to get a point on
 737 |       message (str, optional): a prompt or message
 738 |     Returns:
 739 |       point: 3d point if successful
 740 |       None: on error
 741 |     Example:
 742 |       import rhinoscriptsyntax as rs
 743 |       surface = rs.GetObject("Pick a surface")
 744 |       if surface:
 745 |           point = rs.GetPointOnSurface(surface, "Point on surface")
 746 |           if point: rs.AddPoint(point)
 747 |     See Also:
 748 |       GetPoint
 749 |       GetPointOnCurve
 750 |       GetPointOnMesh
 751 |       GetPoints
 752 |     """
 753 |     surfOrBrep = rhutil.coercesurface(surface_id)
 754 |     if not surfOrBrep:
 755 |         surfOrBrep = rhutil.coercebrep(surface_id, True)
 756 |     gp = Rhino.Input.Custom.GetPoint()
 757 |     if message: gp.SetCommandPrompt(message)
 758 |     if isinstance(surfOrBrep,Rhino.Geometry.Surface):
 759 |         gp.Constrain(surfOrBrep,False)
 760 |     else:
 761 |         gp.Constrain(surfOrBrep, -1, -1, False)
 762 |     gp.Get()
 763 |     if gp.CommandResult()!=Rhino.Commands.Result.Success:
 764 |         return scriptcontext.errorhandler()
 765 |     pt = gp.Point()
 766 |     gp.Dispose()
 767 |     return pt
 768 | 
 769 | 
 770 | def GetPoints(draw_lines=False, in_plane=False, message1=None, message2=None, max_points=None, base_point=None):
 771 |     """Pauses for user input of one or more points
 772 |     Parameters:
 773 |       draw_lines (bool, optional): Draw lines between points
 774 |       in_plane (bool, optional): Constrain point selection to the active construction plane
 775 |       message1 (str, optional): A prompt or message for the first point
 776 |       message2 (str, optional): A prompt or message for the next points
 777 |       max_points (number, optional): maximum number of points to pick. If not specified, an
 778 |                         unlimited number of points can be picked.
 779 |       base_point (point, optional): a starting or base point
 780 |     Returns:
 781 |       list(point, ...): of 3d points if successful
 782 |       None: if not successful or on error
 783 |     Example:
 784 |       import rhinoscriptsyntax as rs
 785 |       points = rs.GetPoints(True)
 786 |       if points: rs.AddPointCloud(points)
 787 |     See Also:
 788 |       GetPoint
 789 |       GetPointOnCurve
 790 |       GetPointOnSurface
 791 |       GetRectangle
 792 |     """
 793 |     gp = Rhino.Input.Custom.GetPoint()
 794 |     if message1: gp.SetCommandPrompt(message1)
 795 |     gp.EnableDrawLineFromPoint( draw_lines )
 796 |     if in_plane:
 797 |         gp.ConstrainToConstructionPlane(True)
 798 |         plane = scriptcontext.doc.Views.ActiveView.ActiveViewport.ConstructionPlane()
 799 |         gp.Constrain(plane, False)
 800 |     getres = gp.Get()
 801 |     if gp.CommandResult()!=Rhino.Commands.Result.Success: return None
 802 |     prevPoint = gp.Point()
 803 |     rc = [prevPoint]
 804 |     if max_points is None or max_points>1:
 805 |         current_point = 1
 806 |         if message2: gp.SetCommandPrompt(message2)
 807 |         def GetPointDynamicDrawFunc( sender, args ):
 808 |             if len(rc)>1:
 809 |                 c = Rhino.ApplicationSettings.AppearanceSettings.FeedbackColor
 810 |                 args.Display.DrawPolyline(rc, c)
 811 |         if draw_lines: gp.DynamicDraw += GetPointDynamicDrawFunc
 812 |         while True:
 813 |             if max_points and current_point>=max_points: break
 814 |             if draw_lines: gp.DrawLineFromPoint(prevPoint, True)
 815 |             gp.SetBasePoint(prevPoint, True)
 816 |             current_point += 1
 817 |             getres = gp.Get()
 818 |             if getres==Rhino.Input.GetResult.Cancel: break
 819 |             if gp.CommandResult()!=Rhino.Commands.Result.Success: return None
 820 |             prevPoint = gp.Point()
 821 |             rc.append(prevPoint)
 822 |     return rc
 823 | 
 824 | def GetPolyline(flags=3, message1=None, message2=None, message3=None, message4=None, min=2, max=0):
 825 |   """Prompts the user to pick points that define a polyline.
 826 |   Parameters:
 827 |     flags (number, optional) The options are bit coded flags. Values can be added together to specify more than one option. The default is 3.
 828 |       value description
 829 |       1     Permit close option. If specified, then after 3 points have been picked, the user can type "Close" and a closed polyline will be returned.
 830 |       2     Permit close snap. If specified, then after 3 points have been picked, the user can pick near the start point and a closed polyline will be returned.
 831 |       4     Force close. If specified, then the returned polyline is always closed. If specified, then intMax must be 0 or >= 4.
 832 |       Note: the default is 3, or "Permit close option = True", "Permit close snap = True", and "Force close = False".
 833 |     message1 (str, optional): A prompt or message for the first point.
 834 |     message2 (str, optional): A prompt or message for the second point.
 835 |     message3 (str, optional): A prompt or message for the third point.
 836 |     message4 (str, optional): A prompt or message for the 'next' point.
 837 |     min (number, optional): The minimum number of points to require. The default is 2.
 838 |     max (number, optional): The maximum number of points to require; 0 for no limit.  The default is 0.
 839 |   Returns:
 840 |     list(point, ...): A list of 3-D points that define the polyline if successful.
 841 |     None: if not successful or on error
 842 |   Example:
 843 |     import rhinoscriptsyntax as rs
 844 |     from scriptcontext import doc
 845 |     arr = rs.GetPolyline()
 846 |     if arr is not None:
 847 |         doc.AddPolyline(arr)
 848 |   See Also:
 849 |     GetBox
 850 |     GetLine
 851 |     GetRectangle
 852 |   """
 853 |   gpl = Rhino.Input.Custom.GetPolyline()
 854 |   if message1: gpl.FirstPointPrompt = message1
 855 |   if message2: gpl.SecondPointPrompt = message2
 856 |   if message3: gpl.ThirdPointPrompt = message3
 857 |   if message4: gpl.FourthPointPrompt = message4
 858 |   if min: gpl.MinPointCount = min
 859 |   if max: gpl.MaxPointCount = max
 860 |   rc, polyline = gpl.Get()
 861 |   scriptcontext.doc.Views.Redraw()
 862 |   if rc==Rhino.Commands.Result.Success: return polyline
 863 |   return None
 864 | 
 865 | def GetReal(message="Number", number=None, minimum=None, maximum=None):
 866 |     """Pauses for user input of a number.
 867 |     Parameters:
 868 |       message (str, optional): A prompt or message.
 869 |       number (number, optional): A default number value.
 870 |       minimum (number, optional): A minimum allowable value.
 871 |       maximum (number, optional): A maximum allowable value.
 872 |     Returns:
 873 |       number: The number input by the user if successful.
 874 |       None: if not successful, or on error
 875 |     Example:
 876 |       import rhinoscriptsyntax as rs
 877 |       radius = rs.GetReal("Radius of new circle", 3.14, 1.0)
 878 |       if radius: rs.AddCircle( (0,0,0), radius )
 879 |     See Also:
 880 |       RealBox
 881 |     """
 882 |     gn = Rhino.Input.Custom.GetNumber()
 883 |     if message: gn.SetCommandPrompt(message)
 884 |     if number is not None: gn.SetDefaultNumber(number)
 885 |     if minimum is not None: gn.SetLowerLimit(minimum, False)
 886 |     if maximum is not None: gn.SetUpperLimit(maximum, False)
 887 |     if gn.Get()!=Rhino.Input.GetResult.Number: return None
 888 |     rc = gn.Number()
 889 |     gn.Dispose()
 890 |     return rc
 891 | 
 892 | 
 893 | def GetRectangle(mode=0, base_point=None, prompt1=None, prompt2=None, prompt3=None):
 894 |     """Pauses for user input of a rectangle
 895 |     Parameters:
 896 |       mode (number, optional): The rectangle selection mode. The modes are as follows
 897 |           0 = All modes
 898 |           1 = Corner - a rectangle is created by picking two corner points
 899 |           2 = 3Point - a rectangle is created by picking three points
 900 |           3 = Vertical - a vertical rectangle is created by picking three points
 901 |           4 = Center - a rectangle is created by picking a center point and a corner point
 902 |       base_point (point, optional): a 3d base point
 903 |       prompt1, prompt2, prompt3 (str, optional): optional prompts
 904 |     Returns:
 905 |       tuple(point, point, point, point): four 3d points that define the corners of the rectangle
 906 |       None: on error
 907 |     Example:
 908 |       import rhinoscriptsyntax as rs
 909 |       rect = rs.GetRectangle()
 910 |       if rect:
 911 |           for i, corner in enumerate(rect):
 912 |               rs.AddTextDot( i, corner )
 913 |     See Also:
 914 |       GetPoint
 915 |       GetPoints
 916 |     """
 917 |     mode = System.Enum.ToObject( Rhino.Input.GetBoxMode, mode )
 918 |     base_point = rhutil.coerce3dpoint(base_point)
 919 |     if( base_point==None ): base_point = Rhino.Geometry.Point3d.Unset
 920 |     prompts = ["", "", ""]
 921 |     if prompt1: prompts[0] = prompt1
 922 |     if prompt2: prompts[1] = prompt2
 923 |     if prompt3: prompts[2] = prompt3
 924 |     rc, corners = Rhino.Input.RhinoGet.GetRectangle(mode, base_point, prompts)
 925 |     if rc==Rhino.Commands.Result.Success: return corners
 926 |     return None
 927 | 
 928 | 
 929 | def GetString(message=None, defaultString=None, strings=None):
 930 |     """Pauses for user input of a string value
 931 |     Parameters:
 932 |       message (str, optional): a prompt or message
 933 |       defaultString (str, optional): a default value
 934 |       strings ([str, ...], optional): list of strings to be displayed as a click-able command options.
 935 |                                       Note, strings cannot begin with a numeric character
 936 |     Returns:
 937 |       str: The string either input or selected by the user if successful.
 938 |            If the user presses the Enter key without typing in a string, an empty string "" is returned.
 939 |       None: if not successful, on error, or if the user pressed cancel.
 940 |     Example:
 941 |       import rhinoscriptsyntax as rs
 942 |       layer = rs.CurrentLayer()
 943 |       layer = rs.GetString("Layer to set current", layer)
 944 |       if layer: rs.CurrentLayer(layer)
 945 |     See Also:
 946 |       GetBoolean
 947 |       StringBox
 948 |     """
 949 |     gs = Rhino.Input.Custom.GetString()
 950 |     gs.AcceptNothing(True)
 951 |     if message: gs.SetCommandPrompt(message)
 952 |     if defaultString: gs.SetDefaultString(defaultString)
 953 |     if strings:
 954 |         for s in strings: gs.AddOption(s)
 955 |     result = gs.Get()
 956 |     if result==Rhino.Input.GetResult.Cancel: return None
 957 |     if( result == Rhino.Input.GetResult.Option ):
 958 |         return gs.Option().EnglishName
 959 |     return gs.StringResult()
 960 | 
 961 | 
 962 | def ListBox(items, message=None, title=None, default=None):
 963 |     """Display a list of items in a list box dialog.
 964 |     Parameters:
 965 |       items ([str, ...]): a list of values to select
 966 |       message (str, optional): a prompt of message
 967 |       title (str, optional): a dialog box title
 968 |       default (str, optional): selected item in the list
 969 |     Returns:
 970 |       str: he selected item if successful
 971 |       None: if not successful or on error
 972 |     Example:
 973 |       import rhinoscriptsyntax as rs
 974 |       layers = rs.LayerNames()
 975 |       if layers:
 976 |           result = rs.ListBox(layers, "Layer to set current")
 977 |           if result: rs.CurrentLayer( result )
 978 |     See Also:
 979 |       CheckListBox
 980 |       ComboListBox
 981 |       MultiListBox
 982 |       PropertyListBox
 983 |     """
 984 |     return Rhino.UI.Dialogs.ShowListBox(title, message, items, default)
 985 | 
 986 | 
 987 | def MessageBox(message, buttons=0, title=""):
 988 |     """Displays a message box. A message box contains a message and
 989 |     title, plus any combination of predefined icons and push buttons.
 990 |     Parameters:
 991 |       message (str): A prompt or message.
 992 |       buttons (number, optional): buttons and icon to display as a bit coded flag. Can be a combination of the
 993 |         following flags. If omitted, an OK button and no icon is displayed
 994 |         0      Display OK button only.
 995 |         1      Display OK and Cancel buttons.
 996 |         2      Display Abort, Retry, and Ignore buttons.
 997 |         3      Display Yes, No, and Cancel buttons.
 998 |         4      Display Yes and No buttons.
 999 |         5      Display Retry and Cancel buttons.
1000 |         16     Display Critical Message icon.
1001 |         32     Display Warning Query icon.
1002 |         48     Display Warning Message icon.
1003 |         64     Display Information Message icon.
1004 |         0      First button is the default.
1005 |         256    Second button is the default.
1006 |         512    Third button is the default.
1007 |         768    Fourth button is the default.
1008 |         0      Application modal. The user must respond to the message box
1009 |                before continuing work in the current application.
1010 |         4096   System modal. The user must respond to the message box
1011 |                before continuing work in any application.
1012 |       title(str, optional): the dialog box title
1013 |     Returns:
1014 |       number: indicating which button was clicked:
1015 |         1      OK button was clicked.
1016 |         2      Cancel button was clicked.
1017 |         3      Abort button was clicked.
1018 |         4      Retry button was clicked.
1019 |         5      Ignore button was clicked.
1020 |         6      Yes button was clicked.
1021 |         7      No button was clicked.
1022 |     Example:
1023 |       import rhinoscriptsyntax as rs
1024 |       rs.MessageBox("Hello Rhino!")
1025 |       rs.MessageBox("Hello Rhino!", 4 | 32)
1026 |       rs.MessageBox("Hello Rhino!", 2 | 48)
1027 |     See Also:
1028 |       
1029 |     """
1030 |     buttontype = buttons & 0x00000007 #111 in binary
1031 |     btn = Rhino.UI.ShowMessageButton.OK
1032 |     if buttontype==1: btn = Rhino.UI.ShowMessageButton.OKCancel
1033 |     elif buttontype==2: btn = Rhino.UI.ShowMessageButton.AbortRetryIgnore
1034 |     elif buttontype==3: btn = Rhino.UI.ShowMessageButton.YesNoCancel
1035 |     elif buttontype==4: btn = Rhino.UI.ShowMessageButton.YesNo
1036 |     elif buttontype==5: btn = Rhino.UI.ShowMessageButton.RetryCancel
1037 |     
1038 |     icontype = buttons & 0x00000070
1039 |     icon = compat.ENUM_NONE(Rhino.UI.ShowMessageIcon)
1040 |     if icontype==16: icon = Rhino.UI.ShowMessageIcon.Error
1041 |     elif icontype==32: icon = Rhino.UI.ShowMessageIcon.Question
1042 |     elif icontype==48: icon = Rhino.UI.ShowMessageIcon.Warning
1043 |     elif icontype==64: icon = Rhino.UI.ShowMessageIcon.Information
1044 |     
1045 |     ### 15 Sep 2014 Alain - default button not supported in new version of RC 
1046 |     ### that isn't tied to Windows.Forms but it probably will so I'm commenting 
1047 |     ### the old code instead of deleting it.
1048 |     #defbtntype = buttons & 0x00000300
1049 |     #defbtn = System.Windows.Forms.MessageDefaultButton.Button1
1050 |     #if defbtntype==256:
1051 |     #    defbtn = System.Windows.Forms.MessageDefaultButton.Button2
1052 |     #elif defbtntype==512:
1053 |     #    defbtn = System.Windows.Forms.MessageDefaultButton.Button3
1054 | 
1055 |     if not isinstance(message, str): message = str(message)
1056 |     dlg_result = Rhino.UI.Dialogs.ShowMessage(message, title, btn, icon)
1057 |     if dlg_result==Rhino.UI.ShowMessageResult.OK:     return 1
1058 |     if dlg_result==Rhino.UI.ShowMessageResult.Cancel: return 2
1059 |     if dlg_result==Rhino.UI.ShowMessageResult.Abort:  return 3
1060 |     if dlg_result==Rhino.UI.ShowMessageResult.Retry:  return 4
1061 |     if dlg_result==Rhino.UI.ShowMessageResult.Ignore: return 5
1062 |     if dlg_result==Rhino.UI.ShowMessageResult.Yes:    return 6
1063 |     if dlg_result==Rhino.UI.ShowMessageResult.No:     return 7
1064 | 
1065 | 
1066 | def PropertyListBox(items, values, message=None, title=None):
1067 |     """Displays list of items and their values in a property-style list box dialog
1068 |     Parameters:
1069 |       items, values ([str, ...]): list of string items and their corresponding values
1070 |       message (str, optional): a prompt or message
1071 |       title (str, optional): a dialog box title
1072 |     Returns:
1073 |       list(str, ..): of new values on success
1074 |       None: on error
1075 |     Example:
1076 |       import rhinoscriptsyntax as rs
1077 |       objs = rs.GetObjects("Select Objects")
1078 |       if objs:
1079 |           names = []
1080 |           for obj in objs:
1081 |               name = rs.ObjectName(obj)
1082 |               if name is None: name=""
1083 |               names.append(name)
1084 |           results = rs.PropertyListBox(objs, names, "Modify object name(s)")
1085 |           if results:
1086 |               for i in compat.RANGE(len(objs)):
1087 |                   rs.ObjectName( objs[i], results[i] )
1088 |     See Also:
1089 |       CheckListBox
1090 |       ComboListBox
1091 |       ListBox
1092 |       MultiListBox
1093 |     """
1094 |     values = [str(v) for v in values]
1095 |     return Rhino.UI.Dialogs.ShowPropertyListBox(title, message, items, values)
1096 | 
1097 | 
1098 | def MultiListBox(items, message=None, title=None, defaults=None):
1099 |     """Displays a list of items in a multiple-selection list box dialog
1100 |     Parameters:
1101 |       items ([str, ...]) a zero-based list of string items
1102 |       message (str, optional): a prompt or message
1103 |       title (str, optional): a dialog box title
1104 |       defaults (str|[str,...], optional): either a string representing the pre-selected item in the list
1105 |                                           or a list if multiple items are pre-selected
1106 |     Returns:
1107 |       list(str, ...): containing the selected items if successful
1108 |       None: on error
1109 |     Example:
1110 |       import rhinoscriptsyntax as  rs
1111 |       layers = rs.LayerNames()
1112 |       if layers:
1113 |           layers  = rs.MultiListBox(layers, "Layers to lock")
1114 |       if layers:
1115 |           for  layer in layers:
1116 |               rs.LayerLocked(layer,  True)
1117 |     See Also:
1118 |       CheckListBox
1119 |       ComboListBox
1120 |       ListBox
1121 |       PropertyListBox
1122 |     """
1123 |     if isinstance(defaults, str):
1124 |       defaults = [defaults]  
1125 |     return Rhino.UI.Dialogs.ShowMultiListBox(title, message, items, defaults)
1126 | 
1127 | 
1128 | def OpenFileName(title=None, filter=None, folder=None, filename=None, extension=None):
1129 |     """Displays file open dialog box allowing the user to enter a file name.
1130 |     Note, this function does not open the file.
1131 |     Parameters:
1132 |       title (str, optional): A dialog box title.
1133 |       filter (str, optional): A filter string. The filter must be in the following form:
1134 |         "Description1|Filter1|Description2|Filter2||", where "||" terminates filter string.
1135 |         If omitted, the filter (*.*) is used.
1136 |       folder (str, optional): A default folder.
1137 |       filename (str, optional): a default file name
1138 |       extension (str, optional): a default file extension
1139 |     Returns:
1140 |       str: file name is successful
1141 |       None: if not successful, or on error
1142 |     Example:
1143 |       import rhinoscriptsyntax as rs
1144 |       filename = rs.OpenFileName()
1145 |       if filename: rs.MessageBox(filename)
1146 |       filename = rs.OpenFileName("Open", "Text Files (*.txt)|*.txt||")
1147 |       if filename: rs.MessageBox(filename)
1148 |       filename = rs.OpenFileName("Open", "Text Files (*.txt)|*.txt|All Files (*.*)|*.*||")
1149 |       if filename: rs.MessageBox(filename)
1150 |     See Also:
1151 |       BrowseForFolder
1152 |       OpenFileNames
1153 |       SaveFileName
1154 |     """
1155 |     fd = Rhino.UI.OpenFileDialog()
1156 |     if title: fd.Title = title
1157 |     if filter: fd.Filter = filter
1158 |     if folder: fd.InitialDirectory = folder
1159 |     if filename: fd.FileName = filename
1160 |     if extension: fd.DefaultExt = extension
1161 |     if fd.ShowOpenDialog(): return fd.FileName
1162 | 
1163 | 
1164 | def OpenFileNames(title=None, filter=None, folder=None, filename=None, extension=None):
1165 |     """Displays file open dialog box allowing the user to select one or more file names.
1166 |     Note, this function does not open the file.
1167 |     Parameters:
1168 |       title (str, optional): A dialog box title.
1169 |       filter (str, optional): A filter string. The filter must be in the following form:
1170 |         "Description1|Filter1|Description2|Filter2||", where "||" terminates filter string.
1171 |         If omitted, the filter (*.*) is used.
1172 |       folder (str, optional): A default folder.
1173 |       filename (str, optional): a default file name
1174 |       extension (str, optional): a default file extension
1175 |     Returns:
1176 |       list(str, ...): of selected file names
1177 |     Example:
1178 |       import rhinoscriptsyntax as rs
1179 |       filenames = rs.OpenFileNames("Open", "Text Files (*.txt)|*.txt|All Files (*.*)|*.*||")
1180 |       for filename in filenames: print(filename)
1181 |     See Also:
1182 |       BrowseForFolder
1183 |       OpenFileName
1184 |       SaveFileName
1185 |     """
1186 |     fd = Rhino.UI.OpenFileDialog()
1187 |     if title: fd.Title = title
1188 |     if filter: fd.Filter = filter
1189 |     if folder: fd.InitialDirectory = folder
1190 |     if filename: fd.FileName = filename
1191 |     if extension: fd.DefaultExt = extension
1192 |     fd.MultiSelect = True
1193 |     if fd.ShowOpenDialog(): return fd.FileNames
1194 |     return []
1195 | 
1196 | 
1197 | def PopupMenu(items, modes=None, point=None, view=None):
1198 |     """Display a context-style popup menu. The popup menu can appear almost
1199 |     anywhere, and can be dismissed by clicking the left or right mouse buttons
1200 |     Parameters:
1201 |       items ([str, ...]): list of strings representing the menu items. An empty string or None
1202 |         will create a separator
1203 |       modes ([number, ...]): List of numbers identifying the display modes. If omitted, all
1204 |         modes are enabled.
1205 |           0 = menu item is enabled
1206 |           1 = menu item is disabled
1207 |           2 = menu item is checked
1208 |           3 = menu item is disabled and checked
1209 |       point (point, optional): a 3D point where the menu item will appear. If omitted, the menu
1210 |         will appear at the current cursor position
1211 |       view (str, optional): if point is specified, the view in which the point is computed.
1212 |         If omitted, the active view is used
1213 |     Returns:
1214 |       number: index of the menu item picked or -1 if no menu item was picked
1215 |     Example:
1216 |       import rhinoscriptsyntax as rs
1217 |       items = "Line", "", "Circle", "Arc"
1218 |       modes = 2,0,0,0
1219 |       result = rs.PopupMenu(items, modes)
1220 |       if result>=0: rs.MessageBox(items[result])
1221 |     See Also:
1222 |       
1223 |     """
1224 |     screen_point = System.Windows.Forms.Cursor.Position
1225 |     if point:
1226 |         point = rhutil.coerce3dpoint(point)
1227 |         view = __viewhelper(view)
1228 |         viewport = view.ActiveViewport
1229 |         point2d = viewport.WorldToClient(point)
1230 |         screen_point = viewport.ClientToScreen(point2d)
1231 |     return Rhino.UI.Dialogs.ShowContextMenu(items, screen_point, modes);
1232 | 
1233 | 
1234 | def RealBox(message="", default_number=None, title="", minimum=None, maximum=None):
1235 |     """Display a dialog box prompting the user to enter a number
1236 |     Parameters:
1237 |       message (str, optional): a prompt message.
1238 |       default_number (number, optional):  a default number.
1239 |       title (str, optional):  a dialog box title.
1240 |       minimum (number, optional):  a minimum allowable value.
1241 |       maximum (number, optional):  a maximum allowable value.
1242 |     Returns:
1243 |       number: The newly entered number on success
1244 |       None: on error
1245 |     Example:
1246 |       import rhinoscriptsyntax as rs
1247 |       radius = rs.RealBox("Enter a radius value", 5.0 )
1248 |       if radius:
1249 |           point = (0,0,0)
1250 |           rs.AddCircle( point, radius )
1251 |     See Also:
1252 |       GetReal
1253 |     """
1254 |     if default_number is None: default_number = Rhino.RhinoMath.UnsetValue
1255 |     if minimum is None: minimum = Rhino.RhinoMath.UnsetValue
1256 |     if maximum is None: maximum = Rhino.RhinoMath.UnsetValue
1257 |     rc, number = Rhino.UI.Dialogs.ShowNumberBox(title, message, default_number, minimum, maximum)
1258 |     if rc: return number
1259 | 
1260 | 
1261 | def SaveFileName(title=None, filter=None, folder=None, filename=None, extension=None):
1262 |     """Display a save dialog box allowing the user to enter a file name.
1263 |     Note, this function does not save the file.
1264 |     Parameters:
1265 |       title (str, optional): A dialog box title.
1266 |       filter(str, optional): A filter string. The filter must be in the following form:
1267 |         "Description1|Filter1|Description2|Filter2||", where "||" terminates filter string.
1268 |         If omitted, the filter (*.*) is used.
1269 |       folder (str, optional): A default folder.
1270 |       filename (str, optional): a default file name
1271 |       extension (str, optional):  a default file extension
1272 |     Returns:
1273 |       str: the file name is successful
1274 |       None: if not successful, or on error
1275 |     Example:
1276 |       import rhinoscriptsyntax as rs
1277 |       filename = rs.SaveFileName()
1278 |       if filename: rs.MessageBox(filename)
1279 |       filename = rs.SaveFileName ("Save", "Text Files (*.txt)|*.txt||")
1280 |       if filename: rs.MessageBox(filename)
1281 |       filename = rrshui.SaveFileName ("Save", "Text Files (*.txt)|*.txt|All Files (*.*)|*.*||")
1282 |       if filename: rs.MessageBox(filename)
1283 |     See Also:
1284 |       BrowseForFolder
1285 |       OpenFileName
1286 |     """
1287 |     fd = Rhino.UI.SaveFileDialog()
1288 |     if title: fd.Title = title
1289 |     if filter: fd.Filter = filter
1290 |     if folder: fd.InitialDirectory = folder
1291 |     if filename: fd.FileName = filename
1292 |     if extension: fd.DefaultExt = extension
1293 |     if fd.ShowSaveDialog(): return fd.FileName
1294 | 
1295 | 
1296 | def StringBox(message=None, default_value=None, title=None):
1297 |     """Display a dialog box prompting the user to enter a string value.
1298 |     Parameters:
1299 |       message (str, optional): a prompt message
1300 |       default_value (str, optional): a default string value
1301 |       title (str, optional): a dialog box title
1302 |     Returns:
1303 |       str: the newly entered string value if successful
1304 |       None: if not successful
1305 |     Example:
1306 |       import rhinoscriptsyntax as rs
1307 |       layer = rs.StringBox("New layer name" )
1308 |       if layer: rs.AddLayer( layer )
1309 |     See Also:
1310 |       GetString
1311 |     """
1312 |     rc, text = Rhino.UI.Dialogs.ShowEditBox(title, message, default_value, False)
1313 |     if rc: return text
1314 | 
1315 | 
1316 | def TextOut(message=None, title=None):
1317 |     """Display a text dialog box similar to the one used by the _What command.
1318 |     Parameters:
1319 |       message (str): a message
1320 |       title (str, optional): the message title
1321 |     Returns:
1322 |       None: in any case
1323 |     Example:
1324 |       import rhinoscriptsyntax as rs
1325 |       rs.TextOut("This is a long string..." )
1326 |     See Also:
1327 |       MessagBox
1328 |     """
1329 |     Rhino.UI.Dialogs.ShowTextDialog(message, title)
1330 | 
```
Page 5/8FirstPrevNextLast