This is page 3 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/pointvector.py:
--------------------------------------------------------------------------------
```python
1 | import math
2 |
3 | import Rhino
4 |
5 | import scriptcontext
6 |
7 | from rhinoscript import utility as rhutil
8 |
9 |
10 | def IsVectorParallelTo(vector1, vector2):
11 | """Compares two vectors to see if they are parallel
12 | Parameters:
13 | vector1, vector2 (vector): the vectors to compare
14 | Returns:
15 | number: the value represents
16 | -1 = the vectors are anti-parallel
17 | 0 = the vectors are not parallel
18 | 1 = the vectors are parallel
19 | Example:
20 | import rhinoscriptsyntax as rs
21 | vector1 = (1,0,0)
22 | vector2 = (0,1,0)
23 | print(rs.IsVectorParallelTo( vector1, vector2 ))
24 | See Also:
25 | IsVectorPerpendicularTo
26 | IsVectorTiny
27 | IsVectorZero
28 | """
29 | vector1 = rhutil.coerce3dvector(vector1, True)
30 | vector2 = rhutil.coerce3dvector(vector2, True)
31 | return vector1.IsParallelTo(vector2)
32 |
33 |
34 | def IsVectorPerpendicularTo(vector1, vector2):
35 | """Compares two vectors to see if they are perpendicular
36 | Parameters:
37 | vector1, vector2 (vector): the vectors to compare
38 | Returns:
39 | bool: True if vectors are perpendicular, otherwise False
40 | Example:
41 | import rhinoscriptsyntax as rs
42 | vector1 = (1,0,0)
43 | vector2 = (0,1,0)
44 | print(rs.IsVectorPerpendicularTo( vector1, vector2 ))
45 | See Also:
46 | IsVectorParallelTo
47 | IsVectorTiny
48 | IsVectorZero
49 | """
50 | vector1 = rhutil.coerce3dvector(vector1, True)
51 | vector2 = rhutil.coerce3dvector(vector2, True)
52 | return vector1.IsPerpendicularTo(vector2)
53 |
54 |
55 | def IsVectorTiny(vector):
56 | """Verifies that a vector is very short. The X,Y,Z elements are <= 1.0e-12
57 | Parameters:
58 | vector (vector): the vector to check
59 | Returns:
60 | bool: True if the vector is tiny, otherwise False
61 | Example:
62 | import rhinoscriptsyntax as rs
63 | pt1 = rs.GetPoint("First point")
64 | pt2 = rs.GetPoint("Next point")
65 | vector = pt2 - pt1
66 | if rs.IsVectorTiny(vector):
67 | print("The vector is tiny.")
68 | else:
69 | print("The vector is not tiny.")
70 | See Also:
71 | IsVectorZero
72 | VectorCreate
73 | """
74 | vector = rhutil.coerce3dvector(vector, True)
75 | return vector.IsTiny( 1.0e-12 )
76 |
77 |
78 | def IsVectorZero(vector):
79 | """Verifies that a vector is zero, or tiny. The X,Y,Z elements are equal to 0.0
80 | Parameters:
81 | vector (vector): the vector to check
82 | Returns:
83 | bool: True if the vector is zero, otherwise False
84 | Example:
85 | import rhinoscriptsyntax as rs
86 | pt1 = rs.GetPoint("First point")
87 | pt2 = rs.GetPoint("Next point")
88 | vector = pt2 - pt1
89 | if rs.IsVectorZero(vector):
90 | print("The vector is zero.")
91 | else:
92 | print("The vector is not zero.")
93 | See Also:
94 | IsVectorTiny
95 | VectorCreate
96 | """
97 | vector = rhutil.coerce3dvector(vector, True)
98 | return vector.IsZero
99 |
100 |
101 | def PointAdd(point1, point2):
102 | """Adds a 3D point or a 3D vector to a 3D point
103 | Parameters:
104 | point1, point2 (point): the points to add
105 | Returns:
106 | point: the resulting 3D point if successful
107 | Example:
108 | import rhinoscriptsyntax as rs
109 | point1 = (1,1,1)
110 | point2 = (2,2,2)
111 | point = rs.PointAdd(point1, point2)
112 | print(point)
113 | See Also:
114 | PointCompare
115 | PointDivide
116 | PointScale
117 | PointSubtract
118 | PointTransform
119 | """
120 | point1 = rhutil.coerce3dpoint(point1, True)
121 | point2 = rhutil.coerce3dpoint(point2, True)
122 | return point1+point2
123 |
124 |
125 | def PointArrayClosestPoint(points, test_point):
126 | """Finds the point in a list of 3D points that is closest to a test point
127 | Parameters:
128 | points ([point, ...]): list of points
129 | test_point (point): the point to compare against
130 | Returns:
131 | number: index of the element in the point list that is closest to the test point
132 | Example:
133 | import rhinoscriptsyntax as rs
134 | cloud = rs.GetObject("Select point cloud")
135 | if cloud:
136 | point = rs.GetPoint("Point to test")
137 | if point:
138 | cloud = rs.PointCloudPoints(cloud)
139 | index = rs.PointArrayClosestPoint(cloud, point)
140 | if index is not None:
141 | point_id = rs.AddPoint(cloud[index])
142 | rs.SelectObject( point_id )
143 | See Also:
144 | CurveClosestPoint
145 | SurfaceClosestPoint
146 | """
147 | points = rhutil.coerce3dpointlist(points, True)
148 | test_point = rhutil.coerce3dpoint(test_point, True)
149 | index = Rhino.Collections.Point3dList.ClosestIndexInList(points, test_point)
150 | if index>=0: return index
151 |
152 |
153 | def PointArrayTransform(points, xform):
154 | """Transforms a list of 3D points
155 | Parameters:
156 | points ([point, ...]): list of 3D points
157 | xform (transform): transformation to apply
158 | Returns:
159 | list(point, ...): transformed points on success
160 | Example:
161 | import rhinoscriptsyntax as rs
162 | obj = rs.GetObject("Select object")
163 | points = rs.BoundingBox(obj)
164 | xform = rs.XformRotation2(45.0, (0,0,1), (0,0,0))
165 | points = rs.PointArrayTransform(points, xform)
166 | rs.AddPoints(points)
167 | See Also:
168 | PointArrayClosestPoint
169 | """
170 | points = rhutil.coerce3dpointlist(points, True)
171 | xform = rhutil.coercexform(xform, True)
172 | return [xform*point for point in points]
173 |
174 |
175 | def PointClosestObject(point, object_ids):
176 | """Finds the object that is closest to a test point
177 | Parameters:
178 | point (point): point to test
179 | object_id ([guid, ...]): identifiers of one or more objects
180 | Returns:
181 | list(guid, point): closest [0] object_id and [1] point on object on success
182 | None: on failure
183 | Example:
184 | import rhinoscriptsyntax as rs
185 | objs = rs.GetObjects("Select target objects for closest point", 63)
186 | if objs:
187 | point = rs.GetPoint("Test point")
188 | if point:
189 | results = rs.PointClosestObject(point, objs)
190 | if results:
191 | print("Object id:{}".format(results[0]))
192 | rs.AddPoint( results[1] )
193 | See Also:
194 | CurveClosestObject
195 | """
196 | object_ids = rhutil.coerceguidlist(object_ids)
197 | point = rhutil.coerce3dpoint(point, True)
198 | closest = None
199 | for id in object_ids:
200 | geom = rhutil.coercegeometry(id, True)
201 | point_geometry = geom
202 | if isinstance(point_geometry, Rhino.Geometry.Point):
203 | distance = point.DistanceTo( point_geometry.Location )
204 | if closest is None or distance<closest[0]:
205 | closest = distance, id, point_geometry.Location
206 | continue
207 | point_cloud = geom
208 | if isinstance(point_cloud, Rhino.Geometry.PointCloud):
209 | index = point_cloud.ClosestPoint(point)
210 | if index>=0:
211 | distance = point.DistanceTo( point_cloud[index].Location )
212 | if closest is None or distance<closest[0]:
213 | closest = distance, id, point_cloud[index].Location
214 | continue
215 | curve = geom
216 | if isinstance(curve, Rhino.Geometry.Curve):
217 | rc, t = curve.ClosestPoint(point)
218 | if rc:
219 | distance = point.DistanceTo( curve.PointAt(t) )
220 | if closest is None or distance<closest[0]:
221 | closest = distance, id, curve.PointAt(t)
222 | continue
223 | brep = geom
224 | if isinstance(brep, Rhino.Geometry.Brep):
225 | brep_closest = brep.ClosestPoint(point)
226 | distance = point.DistanceTo( brep_closest )
227 | if closest is None or distance<closest[0]:
228 | closest = distance, id, brep_closest
229 | continue
230 | mesh = geom
231 | if isinstance(mesh, Rhino.Geometry.Mesh):
232 | mesh_closest = mesh.ClosestPoint(point)
233 | distance = point.DistanceTo( mesh_closest )
234 | if closest is None or distance<closest[0]:
235 | closest = distance, id, mesh_closest
236 | continue
237 | if closest: return closest[1], closest[2]
238 |
239 |
240 | def PointCompare(point1, point2, tolerance=None):
241 | """Compares two 3D points
242 | Parameters:
243 | point1, point2 (point): the points to compare
244 | tolerance (number, optional): tolerance to use for comparison. If omitted,
245 | Rhino's internal zero tolerance is used
246 | Returns:
247 | bool: True or False
248 | Example:
249 | import rhinoscriptsyntax as rs
250 | point1 = (1,1,1)
251 | point2 = (2,2,2)
252 | print(rs.PointCompare(point1, point2))
253 | See Also:
254 | PointAdd
255 | PointDivide
256 | PointScale
257 | PointSubtract
258 | PointTransform
259 | """
260 | point1 = rhutil.coerce3dpoint(point1, True)
261 | point2 = rhutil.coerce3dpoint(point2, True)
262 | if tolerance is None: tolerance = Rhino.RhinoMath.ZeroTolerance
263 | vector = point2-point1
264 | return vector.IsTiny(tolerance)
265 |
266 |
267 | def PointDivide(point, divide):
268 | """Divides a 3D point by a value
269 | Parameters:
270 | point (point): the point to divide
271 | divide (number): a non-zero value to divide
272 | Returns:
273 | point: resulting point
274 | Example:
275 | import rhinoscriptsyntax as rs
276 | point = rs.PointDivide([5,5,0], 5)
277 | print(point)
278 | See Also:
279 | PointAdd
280 | PointCompare
281 | PointScale
282 | PointSubtract
283 | PointTransform
284 | """
285 | point = rhutil.coerce3dpoint(point, True)
286 | return point/divide
287 |
288 |
289 | def PointsAreCoplanar(points, tolerance=1.0e-12):
290 | """Verifies that a list of 3D points are coplanar
291 | Parameters:
292 | points ([point, ...]): 3D points to test
293 | tolerance (number, optional): tolerance to use when verifying
294 | Returns:
295 | bool: True or False
296 | Example:
297 | import rhinoscriptsyntax as rs
298 | def SurfacesAreCoplanar(srf1, srf2):
299 | if( not rs.IsSurface(srf1) or not rs.IsSurface(srf2) ): return False
300 | if( not rs.IsSurfacePlanar(srf1) or not rs.IsSurfacePlanar(srf2) ): return False
301 | pts1 = rs.SurfacePoints(srf1)
302 | pts2 = rs.SurfacePoints(srf2)
303 | if( pts1==None or pts2==None ): return False
304 | pts1.extend(pts2)
305 | return rs.PointsAreCoplanar(pts1)
306 |
307 | x = rs.GetObject( "First surface to test", rs.filter.surface)
308 | y = rs.GetObject( "Second surface to test", rs.filter.surface)
309 | print(SurfacesAreCoplanar(x, y))
310 | See Also:
311 | IsPoint
312 | IsPointCloud
313 | PointCoordinates
314 | """
315 | points = rhutil.coerce3dpointlist(points, True)
316 | return Rhino.Geometry.Point3d.ArePointsCoplanar(points, tolerance)
317 |
318 |
319 | def PointScale(point, scale):
320 | """Scales a 3D point by a value
321 | Parameters:
322 | point (point): the point to divide
323 | scale (number): scale factor to apply
324 | Returns:
325 | point: resulting point on success
326 | Example:
327 | import rhinoscriptsyntax as rs
328 | point = rs.PointScale([1,0,0], 5)
329 | print(point)
330 | See Also:
331 | PointAdd
332 | PointCompare
333 | PointDivide
334 | PointSubtract
335 | PointTransform
336 | """
337 | point = rhutil.coerce3dpoint(point, True)
338 | return point*scale
339 |
340 |
341 | def PointSubtract(point1, point2):
342 | """Subtracts a 3D point or a 3D vector from a 3D point
343 | Parameters:
344 | point1, point2 (point): the points to subtract
345 | Returns:
346 | point: the resulting 3D point if successful
347 | Example:
348 | import rhinoscriptsyntax as rs
349 | point1 = (1,1,1)
350 | point2 = (2,2,2)
351 | point = rs.PointSubtract(point1, point2)
352 | print(point)
353 | See Also:
354 | PointAdd
355 | PointCompare
356 | PointDivide
357 | PointScale
358 | PointTransform
359 | """
360 | point1 = rhutil.coerce3dpoint(point1, True)
361 | point2 = rhutil.coerce3dpoint(point2, True)
362 | v = point1-point2
363 | return Rhino.Geometry.Point3d(v)
364 |
365 |
366 | def PointTransform(point, xform):
367 | """Transforms a 3D point
368 | Parameters:
369 | point (point): the point to transform
370 | xform (transform): a valid 4x4 transformation matrix
371 | Returns:
372 | point: transformed point on success
373 | Example:
374 | # Translate (move) objects by (10,10,0)
375 | import rhinoscriptsyntax as rs
376 | point = 5,5,0
377 | matrix = rs.XformTranslation((10,10,0))
378 | result = rs.PointTransform(point, matrix)
379 | print(result)
380 | See Also:
381 | PointAdd
382 | PointCompare
383 | PointDivide
384 | PointScale
385 | PointSubtract
386 | """
387 | point = rhutil.coerce3dpoint(point, True)
388 | xform = rhutil.coercexform(xform, True)
389 | return xform*point
390 |
391 |
392 | def ProjectPointToMesh(points, mesh_ids, direction):
393 | """Projects one or more points onto one or more meshes
394 | Parameters:
395 | points ([point, ...]): one or more 3D points
396 | mesh_ids ([guid, ...]): identifiers of one or more meshes
397 | direction (vector): direction vector to project the points
398 | Returns:
399 | list(point, ...): projected points on success
400 | Example:
401 | import rhinoscriptsyntax as rs
402 | mesh = rs.GetObject("Select mesh to project onto", rs.filter.mesh)
403 | objects = rs.GetObjects("Select points to project", rs.filter.point)
404 | points = [rs.PointCoordinates(obj) for obj in objects]
405 | # project down...
406 | results = rs.ProjectPointToMesh(points, mesh, (0,0,-1))
407 | rs.AddPoints( results )
408 | See Also:
409 | ProjectCurveToMesh
410 | ProjectCurveToSurface
411 | ProjectPointToSurface
412 | """
413 | pts = rhutil.coerce3dpointlist(points, False)
414 | if pts is None:
415 | pts = [rhutil.coerce3dpoint(points, True)]
416 | direction = rhutil.coerce3dvector(direction, True)
417 | id = rhutil.coerceguid(mesh_ids, False)
418 | if id: mesh_ids = [id]
419 | meshes = [rhutil.coercemesh(id, True) for id in mesh_ids]
420 | tolerance = scriptcontext.doc.ModelAbsoluteTolerance
421 | rc = Rhino.Geometry.Intersect.Intersection.ProjectPointsToMeshes(meshes, pts, direction, tolerance)
422 | return rc
423 |
424 |
425 | def ProjectPointToSurface(points, surface_ids, direction):
426 | """Projects one or more points onto one or more surfaces or polysurfaces
427 | Parameters:
428 | points ([point, ...]): one or more 3D points
429 | surface_ids ([guid, ...]): identifiers of one or more surfaces/polysurfaces
430 | direction (vector): direction vector to project the points
431 | Returns:
432 | list(point, ...): projected points on success
433 | Example:
434 | import rhinoscriptsyntax as rs
435 | surface = rs.GetObject("Select surface to project onto", rs.filter.surface)
436 | objects = rs.GetObjects("Select points to project", rs.filter.point)
437 | points = [rs.PointCoordinates(obj) for obj in objects]
438 | # Project down...
439 | results = rs.ProjectPointToSurface(points, surface, (0,0,-1))
440 | rs.AddPoints(results)
441 | See Also:
442 | ProjectCurveToMesh
443 | ProjectCurveToSurface
444 | ProjectPointToMesh
445 | """
446 | pts = rhutil.coerce3dpointlist(points)
447 | if pts is None:
448 | pts = [rhutil.coerce3dpoint(points, True)]
449 | direction = rhutil.coerce3dvector(direction, True)
450 | id = rhutil.coerceguid(surface_ids, False)
451 | if id: surface_ids = [id]
452 | breps = [rhutil.coercebrep(id, True) for id in surface_ids]
453 | tolerance = scriptcontext.doc.ModelAbsoluteTolerance
454 | return Rhino.Geometry.Intersect.Intersection.ProjectPointsToBreps(breps, pts, direction, tolerance)
455 |
456 |
457 | def PullPoints(object_id, points):
458 | """Pulls an array of points to a surface or mesh object. For more
459 | information, see the Rhino help file Pull command
460 | Parameters:
461 | object_id (guid): the identifier of the surface or mesh object that pulls
462 | points ([point, ...]): list of 3D points
463 | Returns:
464 | list(point, ...): 3D points pulled onto surface or mesh
465 | Example:
466 | import rhinoscriptsyntax as rs
467 | surface = rs.GetObject("Select surface that pulls", rs.filter.surface)
468 | objects = rs.GetObjects("Select points to pull", rs.filter.point)
469 | points = [rs.PointCoordinates(obj) for obj in objects]
470 | results = rs.PullPoints( surface, points )
471 | rs.AddPoints( results )
472 | See Also:
473 | PullCurve
474 | """
475 | id = rhutil.coerceguid(object_id, True)
476 | points = rhutil.coerce3dpointlist(points, True)
477 | mesh = rhutil.coercemesh(id, False)
478 | if mesh:
479 | points = mesh.PullPointsToMesh(points)
480 | return list(points)
481 | brep = rhutil.coercebrep(id, False)
482 | if brep and brep.Faces.Count==1:
483 | tolerance = scriptcontext.doc.ModelAbsoluteTolerance
484 | points = brep.Faces[0].PullPointsToFace(points, tolerance)
485 | return list(points)
486 | return []
487 |
488 |
489 | def VectorAdd(vector1, vector2):
490 | """Adds two 3D vectors
491 | Parameters:
492 | vector1, vector2 (vector): the vectors to add
493 | Returns:
494 | vector: the resulting 3D vector if successful
495 | Example:
496 | import rhinoscriptsyntax as rs
497 | vector1 = (1,0,0)
498 | vector2 = (0,1,0)
499 | vector = rs.VectorAdd(vector1, vector2)
500 | print(vector)
501 | See Also:
502 | VectorCreate
503 | VectorScale
504 | VectorSubtract
505 | """
506 | vector1 = rhutil.coerce3dvector(vector1, True)
507 | vector2 = rhutil.coerce3dvector(vector2, True)
508 | return vector1+vector2
509 |
510 |
511 | def VectorAngle(vector1, vector2):
512 | """Returns the angle, in degrees, between two 3-D vectors
513 | Parameters:
514 | vector1 (vector): The first 3-D vector.
515 | vector2 (vector): The second 3-D vector.
516 | Returns:
517 | number: The angle in degrees if successful
518 | None: if not successful
519 | Example:
520 | import rhinoscriptsyntax as rs
521 | s0 = rs.GetObject("Surface 0", rs.filter.surface)
522 | s1 = rs.GetObject("Surface 1", rs.filter.surface)
523 | du0 = rs.SurfaceDomain(s0, 0)
524 | dv0 = rs.SurfaceDomain(s0, 1)
525 | du1 = rs.SurfaceDomain(s1, 0)
526 | dv1 = rs.SurfaceDomain(s1, 1)
527 | n0 = rs.SurfaceNormal(s0, (du0[0], dv0[0]))
528 | n1 = rs.SurfaceNormal(s1, (du1[0], dv1[0]))
529 | print(rs.VectorAngle(n0, n1))
530 | print(rs.VectorAngle(n0, rs.VectorReverse(n1)))
531 | See Also:
532 | Angle
533 | Angle2
534 | """
535 | vector1 = rhutil.coerce3dvector(vector1, True)
536 | vector2 = rhutil.coerce3dvector(vector2, True)
537 | vector1 = Rhino.Geometry.Vector3d(vector1.X, vector1.Y, vector1.Z)
538 | vector2 = Rhino.Geometry.Vector3d(vector2.X, vector2.Y, vector2.Z)
539 | if not vector1.Unitize() or not vector2.Unitize():
540 | raise ValueError("unable to unitize vector")
541 | dot = vector1 * vector2
542 | dot = rhutil.clamp(-1,1,dot)
543 | radians = math.acos(dot)
544 | return math.degrees(radians)
545 |
546 |
547 | def VectorCompare(vector1, vector2):
548 | """Compares two 3D vectors
549 | Parameters:
550 | vector1, vector2 (vector): the two vectors to compare
551 | Returns:
552 | number: result of comparing the vectors.
553 | -1 if vector1 is less than vector2
554 | 0 if vector1 is equal to vector2
555 | 1 if vector1 is greater than vector2
556 | Example:
557 | import rhinoscriptsyntax as rs
558 | vector1 = (1,0,0)
559 | vector2 = (0,1,0)
560 | rc = rs.VectorCompare(vector1 , vector2)
561 | print(rc)
562 | See Also:
563 | IsVectorTiny
564 | IsVectorZero
565 | VectorCreate
566 | """
567 | vector1 = rhutil.coerce3dvector(vector1, True)
568 | vector2 = rhutil.coerce3dvector(vector2, True)
569 | return vector1.CompareTo(vector2)
570 |
571 |
572 | def VectorCreate(to_point, from_point):
573 | """Creates a vector from two 3D points
574 | Parameters:
575 | to_point, from_point (point): the points defining the vector
576 | Returns:
577 | vector: the resulting vector if successful
578 | Example:
579 | import rhinoscriptsyntax as rs
580 | point1 = rs.GetPoint("First point")
581 | point2 = rs.GetPoint("Next point")
582 | vector = rs.VectorCreate(point2, point1)
583 | print(vector)
584 | See Also:
585 | IsVectorTiny
586 | IsVectorZero
587 | VectorCompare
588 | VectorUnitize
589 | """
590 | to_point = rhutil.coerce3dpoint(to_point, True)
591 | from_point = rhutil.coerce3dpoint(from_point, True)
592 | return to_point-from_point
593 |
594 |
595 | def VectorCrossProduct(vector1, vector2):
596 | """Calculates the cross product of two 3D vectors
597 | Parameters:
598 | vector1, vector2 (vector): the vectors to perform cross product on
599 | Returns:
600 | vector: the resulting cross product direction if successful
601 | Example:
602 | import rhinoscriptsyntax as rs
603 | vector1 = (1,0,0)
604 | vector2 = (0,1,0)
605 | vector = rs.VectorCrossProduct(vector1, vector2)
606 | print(vector)
607 | See Also:
608 | VectorDotProduct
609 | VectorUnitize
610 | """
611 | vector1 = rhutil.coerce3dvector(vector1, True)
612 | vector2 = rhutil.coerce3dvector(vector2, True)
613 | return Rhino.Geometry.Vector3d.CrossProduct( vector1, vector2 )
614 |
615 |
616 | def VectorDivide(vector, divide):
617 | """Divides a 3D vector by a value
618 | Parameters:
619 | vector (vector): the vector to divide
620 | divide (number): a non-zero value to divide
621 | Returns:
622 | vector: resulting vector on success
623 | Example:
624 | import rhinoscriptsyntax as rs
625 | vector = rs.VectorDivide((5,5,0), 5)
626 | print(vector)
627 | See Also:
628 | VectorAdd
629 | VectorCreate
630 | VectorSubtract
631 | """
632 | vector = rhutil.coerce3dvector(vector, True)
633 | return vector/divide
634 |
635 |
636 | def VectorDotProduct(vector1, vector2):
637 | """Calculates the dot product of two 3D vectors
638 | Parameters:
639 | vector1, vector2 (vector): the vectors to perform the dot product on
640 | Returns:
641 | vector: the resulting dot product if successful
642 | Example:
643 | import rhinoscriptsyntax as rs
644 | vector1 = [1,0,0]
645 | vector2 = [0,1,0]
646 | dblDotProduct = rs.VectorDotProduct(vector1, vector2)
647 | print(dblDotProduct)
648 | See Also:
649 | VectorCrossProduct
650 | VectorUnitize
651 | """
652 | vector1 = rhutil.coerce3dvector(vector1, True)
653 | vector2 = rhutil.coerce3dvector(vector2, True)
654 | return vector1*vector2
655 |
656 |
657 | def VectorLength(vector):
658 | """Returns the length of a 3D vector
659 | Parameters:
660 | vector (vector): The 3-D vector.
661 | Returns:
662 | number: The length of the vector if successful, otherwise None
663 | Example:
664 | import rhinoscriptsyntax as rs
665 | point1 = rs.GetPoint("First point")
666 | point2 = rs.GetPoint("Next point")
667 | vector = rs.VectorCreate(point1, point2)
668 | print(rs.VectorLength(vector))
669 | See Also:
670 | VectorAdd
671 | VectorCreate
672 | VectorSubtract
673 | VectorUnitize
674 | """
675 | vector = rhutil.coerce3dvector(vector, True)
676 | return vector.Length
677 |
678 |
679 | def VectorMultiply(vector1, vector2):
680 | """Multiplies two 3D vectors
681 | Parameters:
682 | vector1, vector2 (vector): the vectors to multiply
683 | Returns:
684 | vector: the resulting inner (dot) product if successful
685 | Example:
686 | import rhinoscriptsyntax as rs
687 | product = rs.VectorMultiply( [2,2,2], [3,3,3] )
688 | print(product)
689 | See Also:
690 | VectorAdd
691 | VectorCreate
692 | VectorSubtract
693 | """
694 | return VectorDotProduct(vector1, vector2)
695 |
696 |
697 | def VectorReverse(vector):
698 | """Reverses the direction of a 3D vector
699 | Parameters:
700 | vector (vector): the vector to reverse
701 | Returns:
702 | vector: reversed vector on success
703 | Example:
704 | import rhinoscriptsyntax as rs
705 | vector = rs.VectorReverse([1,0,0])
706 | print(vector)
707 | See Also:
708 | VectorCreate
709 | VectorUnitize
710 | """
711 | vector = rhutil.coerce3dvector(vector, True)
712 | rc = Rhino.Geometry.Vector3d(vector.X, vector.Y, vector.Z)
713 | rc.Reverse()
714 | return rc
715 |
716 |
717 | def VectorRotate(vector, angle_degrees, axis):
718 | """Rotates a 3D vector
719 | Parameters:
720 | vector (vector): the vector to rotate
721 | angle_degrees (number): rotation angle
722 | axis (vector): axis of rotation
723 | Returns:
724 | vector: rotated vector on success
725 | Example:
726 | import rhinoscriptsyntax as rs
727 | vector = rs.VectorRotate([1,0,0], 90.0, [0,0,1])
728 | print(vector)
729 | See Also:
730 | VectorCreate
731 | VectorScale
732 | """
733 | vector = rhutil.coerce3dvector(vector, True)
734 | axis = rhutil.coerce3dvector(axis, True)
735 | angle_radians = Rhino.RhinoMath.ToRadians(angle_degrees)
736 | rc = Rhino.Geometry.Vector3d(vector.X, vector.Y, vector.Z)
737 | if rc.Rotate(angle_radians, axis): return rc
738 |
739 |
740 | def VectorScale(vector, scale):
741 | """Scales a 3-D vector
742 | Parameters:
743 | vector (vector): the vector to scale
744 | scale (number): scale factor to apply
745 | Returns:
746 | vector: resulting vector on success
747 | Example:
748 | import rhinoscriptsyntax as rs
749 | vector = rs.VectorScale([1,0,0], 5)
750 | print(vector)
751 | See Also:
752 | VectorAdd
753 | VectorCreate
754 | VectorSubtract
755 | """
756 | vector = rhutil.coerce3dvector(vector, True)
757 | return vector*scale
758 |
759 |
760 | def VectorSubtract(vector1, vector2):
761 | """Subtracts two 3D vectors
762 | Parameters:
763 | vector1 (vector): the vector to subtract from
764 | vector2 (vector): the vector to subtract
765 | Returns:
766 | vector: the resulting 3D vector
767 | Example:
768 | import rhinoscriptsyntax as rs
769 | vector1 = [1,0,0]
770 | vector2 = [0,1,0]
771 | vector = rs.VectorSubtract(vector1, vector2)
772 | print(vector)
773 | See Also:
774 | VectorAdd
775 | VectorCreate
776 | VectorScale
777 | """
778 | vector1 = rhutil.coerce3dvector(vector1, True)
779 | vector2 = rhutil.coerce3dvector(vector2, True)
780 | return vector1-vector2
781 |
782 |
783 | def VectorTransform(vector, xform):
784 | """Transforms a 3D vector
785 | Parameters:
786 | vector (vector): the vector to transform
787 | xform (transform): a valid 4x4 transformation matrix
788 | Returns:
789 | vector: transformed vector on success
790 | Example:
791 | import rhinoscriptsyntax as rs
792 | vector = (1,0,0) #world x-axis
793 | xform = rs.XformRotation2(90.0, (0,0,1), (0,0,0))
794 | vector = rs.VectorTransform(vector, xform)
795 | print(vector)
796 | See Also:
797 | IsVectorZero
798 | VectorCreate
799 | VectorUnitize
800 | """
801 | vector = rhutil.coerce3dvector(vector, True)
802 | xform = rhutil.coercexform(xform, True)
803 | return xform*vector
804 |
805 |
806 | def VectorUnitize(vector):
807 | """Unitizes, or normalizes a 3D vector. Note, zero vectors cannot be unitized
808 | Parameters:
809 | vector (vector): the vector to unitize
810 | Returns:
811 | vector: unitized vector on success
812 | None: on error
813 | Example:
814 | import rhinoscriptsyntax as rs
815 | vector = rs.VectorUnitize( [1.5,-4.1,3.6] )
816 | print(vector)
817 | See Also:
818 | IsVectorZero
819 | VectorCreate
820 | """
821 | vector = rhutil.coerce3dvector(vector, True)
822 | rc = Rhino.Geometry.Vector3d(vector.X, vector.Y, vector.Z)
823 | if rc.Unitize(): return rc
824 |
825 |
826 | def PointArrayBoundingBox(points, view_or_plane=None, in_world_coords=True):
827 | """Returns either a world axis-aligned or a construction plane axis-aligned
828 | bounding box of an array of 3-D point locations.
829 | Parameters:
830 | points ([point, ...]): A list of 3-D points
831 | view_or_plane (str|plane, optional): Title or id of the view that contains the
832 | construction plane to which the bounding box should be aligned -or-
833 | user defined plane. If omitted, a world axis-aligned bounding box
834 | will be calculated
835 | in_world_coords (bool, optional): return the bounding box as world coordinates or
836 | construction plane coordinates. Note, this option does not apply to
837 | world axis-aligned bounding boxes.
838 | Returns:
839 | list(point, ....): Eight points that define the bounding box. Points returned in counter-
840 | clockwise order starting with the bottom rectangle of the box.
841 | None: on error
842 | Example:
843 |
844 | See Also:
845 | BoundingBox
846 | """
847 | points = rhutil.coerce3dpointlist(points)
848 | if not points:
849 | return None
850 | bbox = Rhino.Geometry.BoundingBox(points)
851 |
852 | xform = None
853 | plane = rhutil.coerceplane(view_or_plane)
854 | if plane is None and view_or_plane:
855 | view = view_or_plane
856 | modelviews = scriptcontext.doc.Views.GetStandardRhinoViews()
857 | for item in modelviews:
858 | viewport = item.MainViewport
859 | if type(view) is str and viewport.Name==view:
860 | plane = viewport.ConstructionPlane()
861 | break
862 | elif type(view) is System.Guid and viewport.Id==view:
863 | plane = viewport.ConstructionPlane()
864 | break
865 | if plane is None: return scriptcontext.errorhandler()
866 | if plane:
867 | xform = Rhino.Geometry.Transform.ChangeBasis(Rhino.Geometry.Plane.WorldXY, plane)
868 | bbox = xform.TransformBoundingBox(bbox)
869 | if not bbox.IsValid: return scriptcontext.errorhandler()
870 |
871 | corners = list(bbox.GetCorners())
872 | if in_world_coords and plane is not None:
873 | plane_to_world = Rhino.Geometry.Transform.ChangeBasis(plane, Rhino.Geometry.Plane.WorldXY)
874 | for pt in corners: pt.Transform(plane_to_world)
875 | return corners
876 |
```
--------------------------------------------------------------------------------
/rhino_mcp_server/static/layer.py:
--------------------------------------------------------------------------------
```python
1 | import System
2 |
3 | import Rhino
4 | from Rhino.DocObjects import Layer
5 | from Rhino import RhinoMath
6 |
7 | import scriptcontext
8 |
9 | from rhinoscript import utility as rhutil
10 |
11 |
12 | def __getlayer(name_or_id, raise_if_missing):
13 | if not name_or_id: raise TypeError("Parameter must be a string or Guid")
14 | id = rhutil.coerceguid(name_or_id)
15 | if id:
16 | layer = scriptcontext.doc.Layers.FindId(id)
17 | else:
18 | name = name_or_id
19 | layer_index = scriptcontext.doc.Layers.FindByFullPath(name, RhinoMath.UnsetIntIndex)
20 | if layer_index != RhinoMath.UnsetIntIndex: return scriptcontext.doc.Layers[layer_index]
21 | layer = scriptcontext.doc.Layers.FindName(name)
22 | if layer: return layer
23 | if raise_if_missing: raise ValueError("%s does not exist in LayerTable" % name_or_id)
24 |
25 |
26 | def AddLayer(name=None, color=None, visible=True, locked=False, parent=None):
27 | """Add a new layer to the document
28 | Parameters:
29 | name (str, optional): The name of the new layer. If omitted, Rhino automatically
30 | generates the layer name.
31 | color (color): A Red-Green-Blue color value. If omitted, the color Black is assigned.
32 | visible (bool optional): layer's visibility
33 | locked (bool, optional): layer's locked state
34 | parent (str, optional): name of the new layer's parent layer. If omitted, the new
35 | layer will not have a parent layer.
36 | Returns:
37 | str: The full name of the new layer if successful.
38 | Example:
39 | import rhinoscriptsyntax as rs
40 | from System.Drawing import Color
41 | print("New layer:{}".format(rs.AddLayer()))
42 | print("New layer:{}".format(rs.AddLayer("MyLayer1")))
43 | print("New layer:{}".format(rs.AddLayer("MyLayer2", Color.DarkSeaGreen)))
44 | print("New layer:{}".format(rs.AddLayer("MyLayer3", Color.Cornsilk)))
45 | print("New layer:{}".format(rs.AddLayer("MyLayer4",parent="MyLayer3")))
46 | See Also:
47 | CurrentLayer
48 | DeleteLayer
49 | RenameLayer
50 | """
51 | names = ['']
52 | if name:
53 | if not isinstance(name, str): name = str(name)
54 | names = [n for n in name.split("::") if name]
55 |
56 | last_parent_index = -1
57 | last_parent = None
58 | for idx, name in enumerate(names):
59 | layer = Rhino.DocObjects.Layer.GetDefaultLayerProperties()
60 |
61 | if idx == 0:
62 | if parent:
63 | last_parent = __getlayer(parent, True)
64 | else:
65 | if last_parent_index != -1:
66 | last_parent = scriptcontext.doc.Layers[last_parent_index]
67 |
68 | if last_parent:
69 | layer.ParentLayerId = last_parent.Id
70 | if name:
71 | layer.Name = name
72 |
73 | color = rhutil.coercecolor(color)
74 | if color: layer.Color = color
75 | layer.IsVisible = visible
76 | layer.IsLocked = locked
77 |
78 | last_parent_index = scriptcontext.doc.Layers.Add(layer)
79 | if last_parent_index == -1:
80 | full_path = layer.Name
81 | if last_parent:
82 | full_path = last_parent.FullPath + "::" + full_path
83 | last_parent_index = scriptcontext.doc.Layers.FindByFullPath(full_path, RhinoMath.UnsetIntIndex)
84 | return scriptcontext.doc.Layers[last_parent_index].FullPath
85 |
86 |
87 | def CurrentLayer(layer=None):
88 | """Returns or changes the current layer
89 | Parameters:
90 | layer (guid): the name or Guid of an existing layer to make current
91 | Returns:
92 | str: If a layer name is not specified, the full name of the current layer
93 | str: If a layer name is specified, the full name of the previous current layer
94 | Example:
95 | import rhinoscriptsyntax as rs
96 | rs.AddLayer("MyLayer")
97 | rs.CurrentLayer("MyLayer")
98 | See Also:
99 | AddLayer
100 | DeleteLayer
101 | RenameLayer
102 | """
103 | rc = scriptcontext.doc.Layers.CurrentLayer.FullPath
104 | if layer:
105 | layer = __getlayer(layer, True)
106 | scriptcontext.doc.Layers.SetCurrentLayerIndex(layer.LayerIndex, True)
107 | return rc
108 |
109 |
110 | def DeleteLayer(layer):
111 | """Removes an existing layer from the document. The layer to be removed
112 | cannot be the current layer. Unlike the PurgeLayer method, the layer must
113 | be empty, or contain no objects, before it can be removed. Any layers that
114 | are children of the specified layer will also be removed if they are also
115 | empty.
116 | Parameters:
117 | layer (str|guid): the name or id of an existing empty layer
118 | Returns:
119 | bool: True or False indicating success or failure
120 | Example:
121 | import rhinoscriptsyntax as rs
122 | layer = rs.GetString("Layer to remove")
123 | if layer: rs.DeleteLayer(layer)
124 | See Also:
125 | AddLayer
126 | CurrentLayer
127 | PurgeLayer
128 | RenameLayer
129 | """
130 | layer = __getlayer(layer, True)
131 | return scriptcontext.doc.Layers.Delete( layer.LayerIndex, True)
132 |
133 |
134 | def ExpandLayer( layer, expand ):
135 | """Expands a layer. Expanded layers can be viewed in Rhino's layer dialog
136 | Parameters:
137 | layer (str): name of the layer to expand
138 | expand (bool): True to expand, False to collapse
139 | Returns:
140 | bool: True or False indicating success or failure
141 | Example:
142 | import rhinoscriptsyntax as rs
143 | if rs.IsLayerExpanded("Default"):
144 | rs.ExpandLayer( "Default", False )
145 | See Also:
146 | IsLayerExpanded
147 | """
148 | layer = __getlayer(layer, True)
149 | if layer.IsExpanded==expand: return False
150 | layer.IsExpanded = expand
151 | return True
152 |
153 |
154 | def IsLayer(layer):
155 | """Verifies the existance of a layer in the document
156 | Parameters:
157 | layer (str|guid): the name or id of a layer to search for
158 | Returns:
159 | bool: True on success otherwise False
160 | Example:
161 | import rhinoscriptsyntax as rs
162 | layer = rs.GetString("Layer name")
163 | if rs.IsLayer(layer):
164 | print("The layer exists.")
165 | else:
166 | print("The layer does not exist.")
167 | See Also:
168 | IsLayerChangeable
169 | IsLayerEmpty
170 | IsLayerLocked
171 | IsLayerOn
172 | IsLayerReference
173 | IsLayerSelectable
174 | IsLayerVisible
175 | """
176 | layer = __getlayer(layer, False)
177 | return layer is not None
178 |
179 |
180 | def IsLayerChangeable(layer):
181 | """Verifies that the objects on a layer can be changed (normal)
182 | Parameters:
183 | layer (str|guid): the name or id of an existing layer
184 | Returns:
185 | bool: True on success otherwise False
186 | Example:
187 | import rhinoscriptsyntax as rs
188 | layer = rs.GetString("Layer name")
189 | if rs.IsLayer(layer):
190 | if rs.IsLayerChangeable(layer): print("The layer is changeable.")
191 | else: print("The layer is not changeable.")
192 | else:
193 | print("The layer does not exist.")
194 | See Also:
195 | IsLayer
196 | IsLayerEmpty
197 | IsLayerLocked
198 | IsLayerOn
199 | IsLayerReference
200 | IsLayerSelectable
201 | IsLayerVisible
202 | """
203 | layer = __getlayer(layer, True)
204 | rc = layer.IsVisible and not layer.IsLocked
205 | return rc
206 |
207 |
208 | def IsLayerChildOf(layer, test):
209 | """Verifies that a layer is a child of another layer
210 | Parameters:
211 | layer (str|guid): the name or id of the layer to test against
212 | test (str|guid): the name or id to the layer to test
213 | Returns:
214 | bool: True on success otherwise False
215 | Example:
216 | import rhinoscriptsyntax as rs
217 | rs.AddLayer("MyLayer1")
218 | rs.AddLayer("MyLayer2", parent="MyLayer1")
219 | rs.AddLayer("MyLayer3", parent="MyLayer2")
220 | rs.MessageBox( rs.IsLayerChildOf("MyLayer1", "MyLayer3") )
221 | See Also:
222 | IsLayerParentOf
223 | """
224 | layer = __getlayer(layer, True)
225 | test = __getlayer(test, True)
226 | return test.IsChildOf(layer)
227 |
228 |
229 | def IsLayerCurrent(layer):
230 | """Verifies that a layer is the current layer
231 | Parameters:
232 | layer (str|guid): the name or id of an existing layer
233 | Returns:
234 | bool: True on success otherwise False
235 | Example:
236 | import rhinoscriptsyntax as rs
237 | layer = rs.GetString("Layer name")
238 | if rs.IsLayer(layer):
239 | if rs.IsLayerCurrent(layer): print("The layer is current.")
240 | else: print("The layer is not current.")
241 | else:
242 | print("The layer does not exist.")
243 | See Also:
244 | IsLayer
245 | IsLayerEmpty
246 | IsLayerLocked
247 | IsLayerOn
248 | IsLayerReference
249 | IsLayerSelectable
250 | IsLayerVisible
251 | """
252 | layer = __getlayer(layer, True)
253 | return layer.LayerIndex == scriptcontext.doc.Layers.CurrentLayerIndex
254 |
255 |
256 | def IsLayerEmpty(layer):
257 | """Verifies that an existing layer is empty, or contains no objects
258 | Parameters:
259 | layer (str|guid): the name or id of an existing layer
260 | Returns:
261 | bool: True on success otherwise False
262 | Example:
263 | import rhinoscriptsyntax as rs
264 | layer = rs.GetString("Layer name")
265 | if rs.IsLayer(layer):
266 | if rs.IsLayerEmpty(layer): print("The layer is empty.")
267 | else: print("The layer is not empty.")
268 | else:
269 | print("The layer does not exist.")
270 | See Also:
271 | IsLayerChangeable
272 | IsLayerLocked
273 | IsLayerOn
274 | IsLayerReference
275 | IsLayerSelectable
276 | IsLayerVisible
277 | """
278 | layer = __getlayer(layer, True)
279 | rhobjs = scriptcontext.doc.Objects.FindByLayer(layer)
280 | if not rhobjs: return True
281 | return False
282 |
283 |
284 | def IsLayerExpanded(layer):
285 | """Verifies that a layer is expanded. Expanded layers can be viewed in
286 | Rhino's layer dialog
287 | Parameters:
288 | layer (str|guid): the name or id of an existing layer
289 | Returns:
290 | bool: True on success otherwise False
291 | Example:
292 | import rhinoscriptsyntax as rs
293 | if rs.IsLayerExpanded("Default"):
294 | rs.ExpandLayer( "Default", False )
295 | See Also:
296 | ExpandLayer
297 | """
298 | layer = __getlayer(layer, True)
299 | return layer.IsExpanded
300 |
301 |
302 | def IsLayerLocked(layer):
303 | """Verifies that a layer is locked.
304 | Parameters:
305 | layer (str|guid): the name or id of an existing layer
306 | Returns:
307 | cool: True on success otherwise False
308 | Example:
309 | import rhinoscriptsyntax as rs
310 | layer = rs.GetString("Layer name")
311 | if rs.IsLayer(layer):
312 | if rs.IsLayerLocked(layer): print("The layer is locked.")
313 | else: print("The layer is not locked.")
314 | else:
315 | print("The layer does not exist.")
316 | See Also:
317 | IsLayer
318 | IsLayerChangeable
319 | IsLayerEmpty
320 | IsLayerOn
321 | IsLayerReference
322 | IsLayerSelectable
323 | IsLayerVisible
324 | """
325 | layer = __getlayer(layer, True)
326 | return layer.IsLocked
327 |
328 |
329 | def IsLayerOn(layer):
330 | """Verifies that a layer is on.
331 | Parameters:
332 | layer (str|guid): the name or id of an existing layer
333 | Returns:
334 | bool: True on success otherwise False
335 | Example:
336 | import rhinoscriptsyntax as rs
337 | layer = rs.GetString("Layer name")
338 | if rs.IsLayer(layer):
339 | if rs.IsLayerOn(layer): print("The layer is on.")
340 | else: print("The layer is not on.")
341 | else:
342 | print("The layer does not exist.")
343 | See Also:
344 | IsLayer
345 | IsLayerChangeable
346 | IsLayerEmpty
347 | IsLayerLocked
348 | IsLayerReference
349 | IsLayerSelectable
350 | IsLayerVisible
351 | """
352 | layer = __getlayer(layer, True)
353 | return layer.IsVisible
354 |
355 |
356 | def IsLayerSelectable(layer):
357 | """Verifies that an existing layer is selectable (normal and reference)
358 | Parameters:
359 | layer (str|guid): the name or id of an existing layer
360 | Returns:
361 | bool: True on success otherwise False
362 | Example:
363 | import rhinoscriptsyntax as rs
364 | layer = rs.GetString("Layer name")
365 | if rs.IsLayer(layer):
366 | if rs.IsLayerSelectable(layer): print("The layer is selectable.")
367 | else: print("The layer is not selectable.")
368 | else:
369 | print("The layer does not exist.")
370 | See Also:
371 | IsLayer
372 | IsLayerChangeable
373 | IsLayerEmpty
374 | IsLayerLocked
375 | IsLayerOn
376 | IsLayerReference
377 | IsLayerVisible
378 | """
379 | layer = __getlayer(layer, True)
380 | return layer.IsVisible and not layer.IsLocked
381 |
382 |
383 | def IsLayerParentOf(layer, test):
384 | """Verifies that a layer is a parent of another layer
385 | Parameters:
386 | layer (str|guid): the name or id of the layer to test against
387 | test (str|guid): the name or id to the layer to test
388 | Returns:
389 | bool: True on success otherwise False
390 | Example:
391 | import rhinoscriptsyntax as rs
392 | rs.AddLayer("MyLayer1")
393 | rs.AddLayer("MyLayer2", parent="MyLayer1")
394 | rs.AddLayer("MyLayer3", parent="MyLayer2")
395 | rs.MessageBox( rs.IsLayerParentOf("MyLayer3", "MyLayer1") )
396 | See Also:
397 | IsLayerChildOf
398 | """
399 | layer = __getlayer(layer, True)
400 | test = __getlayer(test, True)
401 | return test.IsParentOf(layer)
402 |
403 |
404 | def IsLayerReference(layer):
405 | """Verifies that a layer is from a reference file.
406 | Parameters:
407 | layer (str|guid): the name or id of an existing layer
408 | Returns:
409 | bool: True on success otherwise False
410 | Example:
411 | import rhinoscriptsyntax as rs
412 | layer = rs.GetString("Layer name")
413 | if rs.IsLayer(layer):
414 | if rs.IsLayerReference(layer): print("The layer is a reference layer.")
415 | else: print("The layer is not a reference layer.")
416 | else:
417 | print("The layer does not exist.")
418 | See Also:
419 | IsLayer
420 | IsLayerChangeable
421 | IsLayerEmpty
422 | IsLayerLocked
423 | IsLayerOn
424 | IsLayerSelectable
425 | IsLayerVisible
426 | """
427 | layer = __getlayer(layer, True)
428 | return layer.IsReference
429 |
430 |
431 | def IsLayerVisible(layer):
432 | """Verifies that a layer is visible (normal, locked, and reference)
433 | Parameters:
434 | layer (str|guid): the name or id of an existing layer
435 | Returns:
436 | bool: True on success otherwise False
437 | Example:
438 | import rhinoscriptsyntax as rs
439 | layer = rs.GetString("Layer name")
440 | if rs.IsLayer(layer):
441 | if rs.IsLayerVisible(layer): print("The layer is visible")
442 | else: print("The layer is not visible")
443 | else:
444 | print("The layer does not exist.")
445 | See Also:
446 | IsLayer
447 | IsLayerChangeable
448 | IsLayerEmpty
449 | IsLayerLocked
450 | IsLayerOn
451 | IsLayerReference
452 | IsLayerSelectable
453 | """
454 | layer = __getlayer(layer, True)
455 | return layer.IsVisible
456 |
457 |
458 | def LayerChildCount(layer):
459 | """Returns the number of immediate child layers of a layer
460 | Parameters:
461 | layer (str|guid): the name or id of an existing layer
462 | Returns:
463 | number: the number of immediate child layers if successful
464 | Example:
465 | import rhinoscriptsyntax as rs
466 | children = rs.LayerChildCount("Default")
467 | if children: rs.ExpandLayer("Default", True)
468 | See Also:
469 | LayerChildren
470 | """
471 | layer = __getlayer(layer, True)
472 | children = layer.GetChildren()
473 | if children: return len(children)
474 | return 0
475 |
476 |
477 | def LayerChildren(layer):
478 | """Returns the immediate child layers of a layer
479 | Parameters:
480 | layer (str|guid): the name or id of an existing layer
481 | Returns:
482 | list(str, ...): List of children layer names
483 | Example:
484 | import rhinoscriptsyntax as rs
485 | children = rs.LayerChildren("Default")
486 | if children:
487 | for child in children: print(child)
488 | See Also:
489 | LayerChildCount
490 | ParentLayer
491 | """
492 | layer = __getlayer(layer, True)
493 | children = layer.GetChildren()
494 | if children: return [child.FullPath for child in children]
495 | return [] #empty list
496 |
497 |
498 | def LayerColor(layer, color=None):
499 | """Returns or changes the color of a layer.
500 | Parameters:
501 | layer (str|guid): name or id of an existing layer
502 | color (color): the new color value. If omitted, the current layer color is returned.
503 | Returns:
504 | color: If a color value is not specified, the current color value on success
505 | color: If a color value is specified, the previous color value on success
506 | Example:
507 | import rhinoscriptsyntax as rs
508 | import random
509 | from System.Drawing import Color
510 |
511 | def randomcolor():
512 | red = int(255*random.random())
513 | green = int(255*random.random())
514 | blue = int(255*random.random())
515 | return Color.FromArgb(red,green,blue)
516 |
517 | layerNames = rs.LayerNames()
518 | if layerNames:
519 | for name in layerNames: rs.LayerColor(name, randomcolor())
520 | See Also:
521 |
522 | """
523 | layer = __getlayer(layer, True)
524 | rc = layer.Color
525 | if color:
526 | color = rhutil.coercecolor(color)
527 | if color is not None:
528 | layer.Color = color
529 | scriptcontext.doc.Views.Redraw()
530 | return rc
531 |
532 |
533 | def LayerCount():
534 | """Returns the number of layers in the document
535 | Returns:
536 | number: the number of layers in the document
537 | Example:
538 | import rhinoscriptsyntax as rs
539 | count = rs.LayerCount()
540 | print("There are {} layers".format(count))
541 | See Also:
542 | LayerNames
543 | """
544 | return scriptcontext.doc.Layers.ActiveCount
545 |
546 |
547 | def LayerIds():
548 | """Return identifiers of all layers in the document
549 | Returns:
550 | list(guid, ...): the identifiers of all layers in the document
551 | Example:
552 | import rhinoscriptsyntax as rs
553 | layers = rs.LayerIds()
554 | for layer in layers: print(layer)
555 | See Also:
556 | LayerCount
557 | LayerNames
558 | """
559 | return [layer.Id for layer in scriptcontext.doc.Layers if not layer.IsDeleted]
560 |
561 |
562 | def LayerLinetype(layer, linetype=None):
563 | """Returns or changes the linetype of a layer
564 | Parameters:
565 | layer (str): name of an existing layer
566 | linetype (str, optional): name of a linetype
567 | Returns:
568 | str: If linetype is not specified, name of the current linetype
569 | str: If linetype is specified, name of the previous linetype
570 | Example:
571 | import rhinoscriptsyntax as rs
572 | layers = rs.LayerNames()
573 | if layers:
574 | for layer in layers:
575 | if rs.LayerLinetype(layer)!="Continuous":
576 | rs.LayerLinetype(layer,"Continuous")
577 | See Also:
578 | LayerPrintColor
579 | LayerPrintWidth
580 | """
581 | layer = __getlayer(layer, True)
582 | index = layer.LinetypeIndex
583 | rc = scriptcontext.doc.Linetypes[index].Name
584 | if linetype:
585 | if not isinstance(linetype, str): linetype = str(linetype)
586 | if linetype == scriptcontext.doc.Linetypes.ContinuousLinetypeName:
587 | index = -1
588 | else:
589 | lt = scriptcontext.doc.Linetypes.FindName(linetype)
590 | if lt == None: return scriptcontext.errorhandler()
591 | index = lt.LinetypeIndex
592 | layer.LinetypeIndex = index
593 | scriptcontext.doc.Views.Redraw()
594 | return rc
595 |
596 |
597 | def LayerLocked(layer, locked=None):
598 | """Returns or changes the locked mode of a layer
599 | Parameters:
600 | layer (str): name of an existing layer
601 | locked (bool, optional): new layer locked mode
602 | Returns:
603 | bool: If locked is not specified, the current layer locked mode
604 | bool: If locked is specified, the previous layer locked mode
605 | Example:
606 | import rhinoscriptsyntax as rs
607 | layers = rs.LayerNames()
608 | if layers:
609 | for layer in layers:
610 | if rs.LayerLocked(layer): rs.LayerLocked(layer, False)
611 | See Also:
612 | LayerVisible
613 | """
614 | layer = __getlayer(layer, True)
615 | rc = layer.IsLocked
616 | if locked!=None and locked!=layer.GetPersistentLocking():
617 | layer.IsLocked = locked
618 | layer.SetPersistentLocking(locked)
619 | scriptcontext.doc.Views.Redraw()
620 | return rc
621 |
622 |
623 | def LayerMaterialIndex(layer,index=None):
624 | """Returns or changes the material index of a layer. A material index of -1
625 | indicates that no material has been assigned to the layer. Thus, the layer
626 | will use Rhino's default layer material
627 | Parameters:
628 | layer (str): name of existing layer
629 | index (number, optional): the new material index
630 | Returns:
631 | number: a zero-based material index if successful
632 | Example:
633 | import rhinoscriptsyntax as rs
634 | index = rs.LayerMaterialIndex("Default")
635 | if index is not None:
636 | if index==-1:
637 | print("The default layer does not have a material assigned.")
638 | else:
639 | print("The default layer has a material assigned.")
640 | See Also:
641 |
642 | """
643 | layer = __getlayer(layer, True)
644 | rc = layer.RenderMaterialIndex
645 | if index is not None and index>=-1:
646 | layer.RenderMaterialIndex = index
647 | scriptcontext.doc.Views.Redraw()
648 | return rc
649 |
650 |
651 | def LayerId(layer):
652 | """Returns the identifier of a layer given the layer's name.
653 | Parameters:
654 | layer (str): name of existing layer
655 | Returns:
656 | guid (str): The layer's identifier if successful.
657 | None: If not successful, or on error.
658 | Example:
659 | import rhinoscriptsyntax as rs
660 | id = rs.LayerId('Layer 01')
661 | See Also:
662 | LayerName
663 | """
664 | idx = scriptcontext.doc.Layers.FindByFullPath(layer, RhinoMath.UnsetIntIndex)
665 | return str(scriptcontext.doc.Layers[idx].Id) if idx != RhinoMath.UnsetIntIndex else None
666 |
667 |
668 | def LayerName(layer_id, fullpath=True):
669 | """Return the name of a layer given it's identifier
670 | Parameters:
671 | layer_id (guid): layer identifier
672 | fullpath (bool, optional): return the full path name `True` or short name `False`
673 | Returns:
674 | str: the layer's name if successful
675 | None: if not successful
676 | Example:
677 | import rhinoscriptsyntax as rs
678 | layers = rs.LayerIds()
679 | if layers:
680 | for layer in layers: print(rs.LayerName(layer))
681 | See Also:
682 | LayerId
683 | """
684 | layer = __getlayer(layer_id, True)
685 | if fullpath: return layer.FullPath
686 | return layer.Name
687 |
688 |
689 | def LayerNames(sort=False):
690 | """Returns the names of all layers in the document.
691 | Parameters:
692 | sort (bool, optional): return a sorted list of the layer names
693 | Returns:
694 | list(str, ...): list of layer names
695 | Example:
696 | import rhinoscriptsyntax as rs
697 | layers = rs.LayerNames()
698 | if layers:
699 | for layer in layers: print(layer)
700 | See Also:
701 | LayerCount
702 | """
703 | rc = []
704 | for layer in scriptcontext.doc.Layers:
705 | if not layer.IsDeleted: rc.append(layer.FullPath)
706 | if sort: rc.sort()
707 | return rc
708 |
709 |
710 | def LayerOrder(layer):
711 | """Returns the current display order index of a layer as displayed in Rhino's
712 | layer dialog box. A display order index of -1 indicates that the current
713 | layer dialog filter does not allow the layer to appear in the layer list
714 | Parameters:
715 | layer (str): name of existing layer
716 | Returns:
717 | number: 0 based index of layer
718 | Example:
719 | import rhinoscriptsyntax as rs
720 | index = rs.LayerOrder("Default")
721 | if index is not None:
722 | if index==-1: print("The layer does not display in the Layer dialog.")
723 | else: print("The layer does display in the Layer dialog.")
724 | See Also:
725 |
726 | """
727 | layer = __getlayer(layer, True)
728 | return layer.SortIndex
729 |
730 |
731 | def LayerPrintColor(layer, color=None):
732 | """Returns or changes the print color of a layer. Layer print colors are
733 | represented as RGB colors.
734 | Parameters:
735 | layer (str): name of existing layer
736 | color (color): new print color
737 | Returns:
738 | color: if color is not specified, the current layer print color
739 | color: if color is specified, the previous layer print color
740 | None: on error
741 | Example:
742 | import rhinoscriptsyntax as rs
743 | layers = rs.LayerNames()
744 | if layers:
745 | for layer in layers:
746 | black = rs.CreateColor((0,0,0))
747 | if rs.LayerPrintColor(layer)!=black:
748 | rs.LayerPrintColor(layer, black)
749 | See Also:
750 | LayerLinetype
751 | LayerPrintWidth
752 | """
753 | layer = __getlayer(layer, True)
754 | rc = layer.PlotColor
755 | if color:
756 | color = rhutil.coercecolor(color)
757 | layer.PlotColor = color
758 | scriptcontext.doc.Views.Redraw()
759 | return rc
760 |
761 |
762 | def LayerPrintWidth(layer, width=None):
763 | """Returns or changes the print width of a layer. Print width is specified
764 | in millimeters. A print width of 0.0 denotes the "default" print width.
765 | Parameters:
766 | layer (str): name of existing layer
767 | width (number, optional): new print width
768 | Returns:
769 | number: if width is not specified, the current layer print width
770 | number: if width is specified, the previous layer print width
771 | Example:
772 | import rhinoscriptsyntax as rs
773 | layers = rs.LayerNames()
774 | if layers:
775 | for layer in layers:
776 | if rs.LayerPrintWidth(layer)!=0:
777 | rs.LayerPrintWidth(layer, 0)
778 | See Also:
779 | LayerLinetype
780 | LayerPrintColor
781 | """
782 | layer = __getlayer(layer, True)
783 | rc = layer.PlotWeight
784 | if width is not None and width!=rc:
785 | layer.PlotWeight = width
786 | scriptcontext.doc.Views.Redraw()
787 | return rc
788 |
789 |
790 | def LayerVisible(layer, visible=None, forcevisible_or_donotpersist=False):
791 | """Returns or changes the visible property of a layer.
792 | Parameters:
793 | layer (str): name of existing layer
794 | visible (bool, optional): new visible state
795 | forcevisible_or_donotpersist (bool, optional): if visible is True then turn parent layers on if True. If visible is False then do not persist if True
796 | Returns:
797 | bool: if visible is not specified, the current layer visibility
798 | bool: if visible is specified, the previous layer visibility
799 | Example:
800 | import rhinoscriptsyntax as rs
801 | layers = rs.LayerNames()
802 | if layers:
803 | for layer in layers:
804 | if rs.LayerVisible(layer)==False:
805 | rs.LayerVisible(layer,True)
806 | See Also:
807 | LayerLocked
808 | """
809 | layer = __getlayer(layer, True)
810 | rc = layer.IsVisible
811 | if visible is not None:
812 | layer.IsVisible = visible
813 | if visible and forcevisible_or_donotpersist:
814 | scriptcontext.doc.Layers.ForceLayerVisible(layer.Id)
815 | if not visible and not forcevisible_or_donotpersist:
816 | if layer.ParentLayerId != System.Guid.Empty:
817 | layer.SetPersistentVisibility(visible)
818 | scriptcontext.doc.Views.Redraw()
819 | return rc
820 |
821 |
822 | def ParentLayer(layer, parent=None):
823 | """Return or modify the parent layer of a layer
824 | Parameters:
825 | layer (str): name of an existing layer
826 | parent (str, optional): name of new parent layer. To remove the parent layer,
827 | thus making a root-level layer, specify an empty string
828 | Returns:
829 | str: If parent is not specified, the name of the current parent layer
830 | str: If parent is specified, the name of the previous parent layer
831 | None: if the layer does not have a parent
832 | Example:
833 | import rhinoscriptsyntax as rs
834 | layers = rs.LayerNames()
835 | for layer in layers:
836 | parent = rs.ParentLayer(layer)
837 | print("Layer: {}, Parent: {}".format(layer, parent))
838 | See Also:
839 | LayerChildren
840 | """
841 | layer = __getlayer(layer, True)
842 | parent_id = layer.ParentLayerId
843 | oldparent = None
844 | if parent_id!=System.Guid.Empty:
845 | oldparentlayer = scriptcontext.doc.Layers.Find(parent_id, True, -1)
846 | if oldparentlayer is not None:
847 | oldparentlayer = scriptcontext.doc.Layers[oldparentlayer]
848 | oldparent = oldparentlayer.FullPath
849 | if parent is None: return oldparent
850 | if parent=="":
851 | layer.ParentLayerId = System.Guid.Empty
852 | else:
853 | parent = __getlayer(parent, True)
854 | layer.ParentLayerId = parent.Id
855 | return oldparent
856 |
857 |
858 | def PurgeLayer(layer):
859 | """Removes an existing layer from the document. The layer will be removed
860 | even if it contains geometry objects. The layer to be removed cannot be the
861 | current layer
862 | empty.
863 | Parameters:
864 | layer (str|guid): the name or id of an existing empty layer
865 | Returns:
866 | bool: True or False indicating success or failure
867 | Example:
868 | import rhinoscriptsyntax as rs
869 | layer = rs.GetString("Layer to purge")
870 | if layer: rs.PurgeLayer(layer)
871 | See Also:
872 | AddLayer
873 | CurrentLayer
874 | DeleteLayer
875 | RenameLayer
876 | """
877 | layer = __getlayer(layer, True)
878 | rc = scriptcontext.doc.Layers.Purge( layer.LayerIndex, True)
879 | scriptcontext.doc.Views.Redraw()
880 | return rc
881 |
882 |
883 | def RenameLayer(oldname, newname):
884 | """Renames an existing layer
885 | Parameters:
886 | oldname (str): original layer name
887 | newname (str): new layer name
888 | Returns:
889 | str: The new layer name if successful otherwise None
890 | Example:
891 | import rhinoscriptsyntax as rs
892 | oldname = rs.GetString("Old layer name")
893 | if oldname:
894 | newname = rs.GetString("New layer name")
895 | if newname: rs.RenameLayer(oldname, newname)
896 | See Also:
897 | AddLayer
898 | CurrentLayer
899 | DeleteLayer
900 | """
901 | if oldname and newname:
902 | layer = __getlayer(oldname, True)
903 | layer.Name = newname
904 | return newname
905 |
```
--------------------------------------------------------------------------------
/rhino_mcp_server/static/utility.py:
--------------------------------------------------------------------------------
```python
1 | import time
2 | import math
3 | import string
4 | import numbers
5 | from operator import attrgetter
6 |
7 | import System
8 | import System.Drawing
9 | import System.Windows.Forms
10 |
11 | import Rhino
12 |
13 | import rhinocompat as compat
14 | import scriptcontext
15 |
16 |
17 | def ContextIsRhino():
18 | """Return True if the script is being executed in the context of Rhino
19 | Returns:
20 | bool: True if the script is being executed in the context of Rhino
21 | Example:
22 | import rhinoscriptsyntax as rs
23 | print(rs.ContextIsRhino())
24 | See Also:
25 | ContextIsGrasshopper
26 | """
27 | return scriptcontext.id == 1
28 |
29 |
30 | def ContextIsGrasshopper():
31 | """Return True if the script is being executed in a grasshopper component
32 | Returns:
33 | bool: True if the script is being executed in a grasshopper component
34 | Example:
35 | import rhinoscriptsyntax as rs
36 | print(rs.ContextIsGrasshopper())
37 | See Also:
38 | ContextIsRhino
39 | """
40 | return scriptcontext.id == 2
41 |
42 |
43 | def Angle(point1, point2, plane=True):
44 | """Measures the angle between two points
45 | Parameters:
46 | point1, point2 (point): the input points
47 | plane (bool, optional): Boolean or Plane
48 | If True, angle calculation is based on the world coordinate system.
49 | If False, angle calculation is based on the active construction plane
50 | If a plane is provided, angle calculation is with respect to this plane
51 | Returns:
52 | tuple(tuple(number, number), number, number, number, number): containing the following elements if successful
53 | element 0 = the X,Y angle in degrees
54 | element 1 = the elevation
55 | element 2 = delta in the X direction
56 | element 3 = delta in the Y direction
57 | element 4 = delta in the Z direction
58 | None: if not successful
59 | Example:
60 | import rhinoscriptsyntax as rs
61 | point1 = rs.GetPoint("First point")
62 | if point1:
63 | point2 = rs.GetPoint("Second point")
64 | if point2:
65 | angle = rs.Angle(point1, point2)
66 | if angle: print("Angle: {}".format(angle[0]))
67 | See Also:
68 | Angle2
69 | Distance
70 | """
71 | pt1 = coerce3dpoint(point1)
72 | if pt1 is None:
73 | pt1 = coercerhinoobject(point1)
74 | if isinstance(pt1, Rhino.DocObjects.PointObject): pt1 = pt1.Geometry.Location
75 | else: pt1=None
76 | pt2 = coerce3dpoint(point2)
77 | if pt2 is None:
78 | pt2 = coercerhinoobject(point2)
79 | if isinstance(pt2, Rhino.DocObjects.PointObject): pt2 = pt2.Geometry.Location
80 | else: pt2=None
81 | point1 = pt1
82 | point2 = pt2
83 | if point1 is None or point2 is None: return scriptcontext.errorhandler()
84 | vector = point2 - point1
85 | x = vector.X
86 | y = vector.Y
87 | z = vector.Z
88 | if plane!=True:
89 | plane = coerceplane(plane)
90 | if plane is None:
91 | plane = scriptcontext.doc.Views.ActiveView.ActiveViewport.ConstructionPlane()
92 | vfrom = point1 - plane.Origin
93 | vto = point2 - plane.Origin
94 | x = vto * plane.XAxis - vfrom * plane.XAxis
95 | y = vto * plane.YAxis - vfrom * plane.YAxis
96 | z = vto * plane.ZAxis - vfrom * plane.ZAxis
97 | h = math.sqrt( x * x + y * y)
98 | angle_xy = math.degrees( math.atan2( y, x ) )
99 | elevation = math.degrees( math.atan2( z, h ) )
100 | return angle_xy, elevation, x, y, z
101 |
102 |
103 | def Angle2(line1, line2):
104 | """Measures the angle between two lines
105 | Parameters:
106 | line1 (line): List of 6 numbers or 2 Point3d.
107 | line2 (line): List of 6 numbers or 2 Point3d.
108 | Returns:
109 | tuple(number, number): containing the following elements if successful.
110 | 0 The angle in degrees.
111 | 1 The reflex angle in degrees.
112 | None: If not successful, or on error.
113 | Example:
114 | import rhinoscriptsyntax as rs
115 | point1 = rs.GetPoint("Start of first line")
116 | point2 = rs.GetPoint("End of first line", point1)
117 | point3 = rs.GetPoint("Start of second line")
118 | point4 = rs.GetPoint("End of second line", point3)
119 | angle = rs.Angle2( (point1, point2), (point3, point4))
120 | if angle: print("Angle: {}".format(angle))
121 | See Also:
122 | Angle
123 | Distance
124 | """
125 | line1 = coerceline(line1, True)
126 | line2 = coerceline(line2, True)
127 | vec0 = line1.To - line1.From
128 | vec1 = line2.To - line2.From
129 | if not vec0.Unitize() or not vec1.Unitize(): return scriptcontext.errorhandler()
130 | dot = vec0 * vec1
131 | dot = clamp(-1,1,dot)
132 | angle = math.acos(dot)
133 | reflex_angle = 2.0*math.pi - angle
134 | angle = math.degrees(angle)
135 | reflex_angle = math.degrees(reflex_angle)
136 | return angle, reflex_angle
137 |
138 |
139 | def ClipboardText(text=None):
140 | """Returns or sets a text string to the Windows clipboard
141 | Parameters:
142 | text (str, optional): text to set
143 | Returns:
144 | str: if text is not specified, the current text in the clipboard
145 | str: if text is specified, the previous text in the clipboard
146 | None: if not successful
147 | Example:
148 | import rhinoscriptsyntax as rs
149 | txt = rs.ClipboardText("Hello Rhino!")
150 | if txt: rs.MessageBox(txt, 0, "Clipboard Text")
151 | See Also:
152 |
153 | """
154 | rc = None
155 | if System.Windows.Forms.Clipboard.ContainsText():
156 | rc = System.Windows.Forms.Clipboard.GetText()
157 | if text:
158 | if not isinstance(text, str): text = str(text)
159 | System.Windows.Forms.Clipboard.SetText(text)
160 | return rc
161 |
162 |
163 | def ColorAdjustLuma(rgb, luma, scale=False):
164 | """Changes the luminance of a red-green-blue value. Hue and saturation are
165 | not affected
166 | Parameters:
167 | rgb (color): initial rgb value
168 | luma (number): The luminance in units of 0.1 percent of the total range. A
169 | value of luma = 50 corresponds to 5 percent of the maximum luminance
170 | scale (bool, optional): if True, luma specifies how much to increment or decrement the
171 | current luminance. If False, luma specified the absolute luminance.
172 | Returns:
173 | color: modified rgb value if successful
174 | Example:
175 | import rhinoscriptsyntax as rs
176 | rgb = rs.ColorAdjustLuma((128, 128, 128), 50)
177 | print("Red = {}".format(rs.ColorRedValue(rgb)))
178 | print("Green = {}".format(rs.ColorGreenValue(rgb)))
179 | print("Blue = {}".format(rs.ColorBlueValue(rgb)))
180 | See Also:
181 | ColorHLSToRGB
182 | ColorRGBToHLS
183 | """
184 | rgb = coercecolor(rgb, True)
185 | hsl = Rhino.Display.ColorHSL(rgb)
186 | luma = luma / 1000.0
187 | if scale: luma = hsl.L + luma
188 | hsl.L = luma
189 | return hsl.ToArgbColor()
190 |
191 |
192 | def ColorBlueValue(rgb):
193 | """Retrieves intensity value for the blue component of an RGB color
194 | Parameters:
195 | rgb (color): the RGB color value
196 | Returns:
197 | number: The blue component if successful, otherwise None
198 | Example:
199 | import rhinoscriptsyntax as rs
200 | rgb = rs.LayerColor("Default")
201 | print("Red = {}".format(rs.ColorRedValue(rgb)))
202 | print("Green = {}".format(rs.ColorGreenValue(rgb)))
203 | print("Blue = {}".format(rs.ColorBlueValue(rgb)))
204 | See Also:
205 | ColorGreenValue
206 | ColorRedValue
207 | """
208 | return coercecolor(rgb, True).B
209 |
210 |
211 | def ColorGreenValue(rgb):
212 | """Retrieves intensity value for the green component of an RGB color
213 | Parameters:
214 | rgb (color): the RGB color value
215 | Returns:
216 | number: The green component if successful, otherwise None
217 | Example:
218 | import rhinoscriptsyntax as rs
219 | rgb = rs.LayerColor("Default")
220 | print("Red = {}".format(rs.ColorRedValue(rgb)))
221 | print("Green = {}".format(rs.ColorGreenValue(rgb)))
222 | print("Blue = {}".format(rs.ColorBlueValue(rgb)))
223 | See Also:
224 | ColorBlueValue
225 | ColorRedValue
226 | """
227 | return coercecolor(rgb, True).G
228 |
229 |
230 | def ColorHLSToRGB(hls):
231 | """Converts colors from hue-lumanence-saturation to RGB
232 | Parameters:
233 | hls (color): the HLS color value
234 | Returns:
235 | color: The RGB color value if successful, otherwise False
236 | Example:
237 | import rhinoscriptsyntax as rs
238 | rgb = rs.ColorHLSToRGB( (160, 120, 0) )
239 | print("Red = {}".format(rs.ColorRedValue(rgb)))
240 | print("Green = {}".format(rs.ColorGreenValue(rgb)))
241 | print("Blue = {}".format(rs.ColorBlueValue(rgb)))
242 | See Also:
243 | ColorAdjustLuma
244 | ColorRGBToHLS
245 | """
246 | if len(hls)==3:
247 | hls = Rhino.Display.ColorHSL(hls[0]/240.0, hls[2]/240.0, hls[1]/240.0)
248 | elif len(hls)==4:
249 | hls = Rhino.Display.ColorHSL(hls[3]/240.0, hls[0]/240.0, hls[2]/240.0, hls[1]/240.0)
250 | return hls.ToArgbColor()
251 |
252 |
253 | def ColorRedValue(rgb):
254 | """Retrieves intensity value for the red component of an RGB color
255 | Parameters:
256 | hls (color): the HLS color value
257 | Returns:
258 | color: The red color value if successful, otherwise False
259 | Example:
260 | import rhinoscriptsyntax as rs
261 | rgb = rs.LayerColor("Default")
262 | print("Red = {}".format(rs.ColorRedValue(rgb)))
263 | print("Green = {}".format(rs.ColorGreenValue(rgb)))
264 | print("Blue = {}".format(rs.ColorBlueValue(rgb)))
265 | See Also:
266 | ColorBlueValue
267 | ColorGreenValue
268 | """
269 | return coercecolor(rgb, True).R
270 |
271 |
272 | def ColorRGBToHLS(rgb):
273 | """Convert colors from RGB to HLS
274 | Parameters:
275 | rgb (color): the RGB color value
276 | Returns:
277 | color: The HLS color value if successful, otherwise False
278 | Example:
279 | import rhinoscriptsyntax as rs
280 | hls = rs.ColorRGBToHLS((128, 128, 128))
281 | print("Hue = {}".format(hls[0]))
282 | print("Luminance = {}".format(hls[1]))
283 | print("Saturation = {}".format(hls[2]))
284 | See Also:
285 | ColorAdjustLuma
286 | ColorHLSToRGB
287 | """
288 | rgb = coercecolor(rgb, True)
289 | hsl = Rhino.Display.ColorHSL(rgb)
290 | return hsl.H, hsl.S, hsl.L
291 |
292 |
293 | def CullDuplicateNumbers(numbers, tolerance=None):
294 | """Removes duplicates from an array of numbers.
295 | Parameters:
296 | numbers ([number, ...]): list or tuple
297 | tolerance (number, optional): The minimum distance between numbers. Numbers that fall within this tolerance will be discarded. If omitted, Rhino's internal zero tolerance is used.
298 | Returns:
299 | list(number, ...): numbers with duplicates removed if successful.
300 | Example:
301 | import rhinoscriptsyntax as rs
302 | arr = [1,1,2,2,3,3,4,4,5,5]
303 | arr = rs.CullDuplicateNumbers(arr)
304 | for n in arr: print(n)
305 | See Also:
306 | CullDuplicatePoints
307 | """
308 | count = len(numbers)
309 | if count < 2: return numbers
310 | if tolerance is None: tolerance = scriptcontext.doc.ModelAbsoluteTolerance
311 | numbers = sorted(numbers)
312 | d = numbers[0]
313 | index = 1
314 | for step in range(1,count):
315 | test_value = numbers[index]
316 | if math.fabs(d-test_value)<=tolerance:
317 | numbers.pop(index)
318 | else:
319 | d = test_value
320 | index += 1
321 | return numbers
322 |
323 |
324 | def CullDuplicatePoints(points, tolerance=-1):
325 | """Removes duplicates from a list of 3D points.
326 | Parameters:
327 | points ([point, ...]): A list of 3D points.
328 | tolerance (number): Minimum distance between points. Points within this
329 | tolerance will be discarded. If omitted, Rhino's internal zero tolerance
330 | is used.
331 | Returns:
332 | list(point, ...): of 3D points with duplicates removed if successful.
333 | None: if not successful
334 | Example:
335 | import rhinoscriptsyntax as rs
336 | points = rs.GetPoints(,,"First point", "Next point")
337 | if points:
338 | points= rs.CullDuplicatePoints(points)
339 | for p in points: print(p)
340 | See Also:
341 | CullDuplicateNumbers
342 | """
343 | points = coerce3dpointlist(points, True)
344 | if tolerance is None or tolerance < 0:
345 | tolerance = Rhino.RhinoMath.ZeroTolerance
346 | return list(Rhino.Geometry.Point3d.CullDuplicates(points, tolerance))
347 |
348 |
349 | def Distance(point1, point2):
350 | """Measures distance between two 3D points, or between a 3D point and
351 | an array of 3D points.
352 | Parameters:
353 | point1 (point): The first 3D point.
354 | point2 (point): The second 3D point or list of 3-D points.
355 | Returns:
356 | point: If point2 is a 3D point then the distance if successful.
357 | point: If point2 is a list of points, then an list of distances if successful.
358 | None: if not successful
359 | Example:
360 | import rhinoscriptsyntax as rs
361 | point1 = rs.GetPoint("First point")
362 | if point1:
363 | point2 = rs.GetPoint("Second point")
364 | if point2:
365 | print("Distance: {}".format(rs.Distance(point1, point2)))
366 | See Also:
367 | Angle
368 | Angle2
369 | """
370 | from_pt = coerce3dpoint(point1, True)
371 | to_pt = coerce3dpoint(point2)
372 | if to_pt: return (to_pt - from_pt).Length
373 | # check if we have a list of points
374 | to_pt = coerce3dpointlist(point2, True)
375 | distances = [(point - from_pt).Length for point in to_pt]
376 | if distances: return distances
377 |
378 |
379 | def GetSettings(filename, section=None, entry=None):
380 | """Returns string from a specified section in a initialization file.
381 | Parameters:
382 | filename (str): name of the initialization file
383 | section (str, optional): section containing the entry
384 | entry (str, optional): entry whose associated string is to be returned
385 | Returns:
386 | list(str, ...): If section is not specified, a list containing all section names
387 | list:(str, ...): If entry is not specified, a list containing all entry names for a given section
388 | str: If section and entry are specified, a value for entry
389 | None: if not successful
390 | Example:
391 | import rhinoscriptsyntax as rs
392 | filename = rs.OpenFileName("Open", "Initialization Files (*.ini)|*.ini||")
393 | if filename:
394 | sections = rs.GetSettings(filename)
395 | if sections:
396 | section = rs.ListBox(sections, "Select a section", filename)
397 | if section:
398 | entries = rs.GetSettings(filename, section)
399 | if entries:
400 | entry = rs.ListBox(entries, "Select an entry", section)
401 | if entry:
402 | value = rs.GetSettings(filename, section, entry)
403 | if value: rs.MessageBox( value, 0, entry )
404 | See Also:
405 |
406 | """
407 | CP = compat.GET_IMPORT_CONFIG_PARSER()
408 | try:
409 | cp = CP.ConfigParser()
410 | cp.read(filename)
411 | if not section: return cp.sections()
412 | section = string.lower(section)
413 | if not entry: return cp.options(section)
414 | entry = string.lower(entry)
415 | return cp.get(section, entry)
416 | except IOError:
417 | return scriptcontext.errorhander()
418 | return scriptcontext.errorhandler()
419 |
420 |
421 | def Polar(point, angle_degrees, distance, plane=None):
422 | """Returns 3D point that is a specified angle and distance from a 3D point
423 | Parameters:
424 | point (point): the point to transform
425 | plane (plane, optional): plane to base the transformation. If omitted, the world
426 | x-y plane is used
427 | Returns:
428 | point: resulting point is successful
429 | None: on error
430 | Example:
431 | import rhinoscriptsyntax as rs
432 | point = (1.0, 1.0, 0.0)
433 | result = rs.Polar(point, 45.0, 1.414214)
434 | print(result)
435 | See Also:
436 | PointAdd
437 | PointCompare
438 | PointDivide
439 | PointScale
440 | PointSubtract
441 | """
442 | point = coerce3dpoint(point, True)
443 | angle = math.radians(angle_degrees)
444 | if plane: plane = coerceplane(plane)
445 | else: plane = Rhino.Geometry.Plane.WorldXY
446 | offset = plane.XAxis
447 | offset.Unitize()
448 | offset *= distance
449 | rc = point+offset
450 | xform = Rhino.Geometry.Transform.Rotation(angle, plane.ZAxis, point)
451 | rc.Transform(xform)
452 | return rc
453 |
454 |
455 | def SimplifyArray(points):
456 | """Flattens an array of 3-D points into a one-dimensional list of real numbers. For example, if you had an array containing three 3-D points, this method would return a one-dimensional array containing nine real numbers.
457 | Parameters:
458 | points ([point, ...]): Points to flatten
459 | Returns:
460 | list(number, ...): A one-dimensional list containing real numbers, if successful, otherwise None
461 | Example:
462 | import rhinoscriptsyntax as rs
463 | points = rs.GetPoints()
464 | if points:
465 | numbers = rs.SimplifyArray(points)
466 | for n in numbers: print(n)
467 | See Also:
468 |
469 | """
470 | rc = []
471 | for point in points:
472 | point = coerce3dpoint(point, True)
473 | rc.append(point.X)
474 | rc.append(point.Y)
475 | rc.append(point.Z)
476 | return rc
477 |
478 |
479 | def Sleep(milliseconds):
480 | """Suspends execution of a running script for the specified interval
481 | Parameters:
482 | milliseconds (number): thousands of a second
483 | Returns:
484 | None
485 | Example:
486 | import rhinoscriptsyntax as rs
487 | print("This")
488 | rs.Sleep(2000)
489 | print("is")
490 | rs.Sleep(2000)
491 | print("a")
492 | rs.Sleep(2000)
493 | print("slow")
494 | rs.Sleep(2000)
495 | print("message!")
496 | See Also:
497 |
498 | """
499 | time.sleep( milliseconds / 1000.0 )
500 | Rhino.RhinoApp.Wait() #keep the message pump alive
501 |
502 | def SortPointList(points, tolerance=None):
503 | """Sorts list of points so they will be connected in a "reasonable" polyline order
504 | Parameters:
505 | points ({point, ...])the points to sort
506 | tolerance (number, optional): minimum distance between points. Points that fall within this tolerance
507 | will be discarded. If omitted, Rhino's internal zero tolerance is used.
508 | Returns:
509 | list(point, ...): of sorted 3D points if successful
510 | None: on error
511 | Example:
512 | import rhinoscriptsyntax as rs
513 | points = rs.GetPointCoordinates()
514 | if points:
515 | sorted = rs.SortPointList(points)
516 | rs.AddPolyline(sorted)
517 | See Also:
518 | SortPoints
519 | """
520 | points = coerce3dpointlist(points, True)
521 | if tolerance is None: tolerance = Rhino.RhinoMath.ZeroTolerance
522 | return list(Rhino.Geometry.Point3d.SortAndCullPointList(points, tolerance))
523 |
524 |
525 | def SortPoints(points, ascending=True, order=0):
526 | """Sorts the components of an array of 3D points
527 | Parameters:
528 | points ([point, ...]): points to sort
529 | ascending (bool, optional: ascending if omitted (True) or True, descending if False.
530 | order (number, optional): the component sort order
531 | Value Component Sort Order
532 | 0 (default) X, Y, Z
533 | 1 X, Z, Y
534 | 2 Y, X, Z
535 | 3 Y, Z, X
536 | 4 Z, X, Y
537 | 5 Z, Y, X
538 | Returns:
539 | list(point, ...): sorted 3-D points if successful
540 | None: if not successful
541 | Example:
542 | import rhinoscriptsyntax as rs
543 | points = rs.GetPoints()
544 | if points:
545 | points = rs.SortPoints(points)
546 | for p in points: print(p)
547 | See Also:
548 |
549 | """
550 | __attrXYZ = attrgetter('X', 'Y', 'Z')
551 | __attrXZY = attrgetter('X', 'Z', 'Y')
552 | __attrYXZ = attrgetter('Y', 'X', 'Z')
553 | __attrYZX = attrgetter('Y', 'Z', 'X')
554 | __attrZXY = attrgetter('Z', 'X', 'Y')
555 | __attrZYX = attrgetter('Z', 'Y', 'X')
556 | __attrgetter = (__attrXYZ, __attrXZY, __attrYXZ, __attrYZX, __attrZXY, __attrZYX)[order]
557 | return sorted(points, key=__attrgetter, reverse=not ascending)
558 |
559 |
560 | def Str2Pt(point):
561 | """convert a formatted string value into a 3D point value
562 | Parameters:
563 | point (str): A string that contains a delimited point like "1,2,3".
564 | Returns:
565 | point: Point structure from the input string.
566 | None: error on invalid format
567 | Example:
568 | import rhinoscriptsyntax as rs
569 | point = rs.Str2Pt("1,2,3")
570 | if point: rs.AddPoint( point )
571 | See Also:
572 |
573 | """
574 | return coerce3dpoint(point, True)
575 |
576 |
577 | def clamp(lowvalue, highvalue, value):
578 | if lowvalue>=highvalue: raise Exception("lowvalue must be less than highvalue")
579 | if value<lowvalue: return lowvalue
580 | if value>highvalue: return highvalue
581 | return value
582 |
583 |
584 | def fxrange(start, stop, step):
585 | "float version of the xrange function"
586 | if step==0: raise ValueError("step must not equal 0")
587 | x = start
588 | if start<stop:
589 | if step<0: raise ValueError("step must be greater than 0")
590 | while x<=stop:
591 | yield x
592 | x+=step
593 | else:
594 | if step>0: raise ValueError("step must be less than 0")
595 | while x>=stop:
596 | yield x
597 | x+=step
598 |
599 |
600 | def frange(start, stop, step):
601 | "float version of the range function"
602 | return [x for x in fxrange(start, stop, step)]
603 |
604 |
605 | def coerce3dpoint(point, raise_on_error=False):
606 | """Converts input into a Rhino.Geometry.Point3d if possible.
607 | Parameters:
608 | point = Point3d, Vector3d, Point3f, Vector3f, str, uuid
609 | raise_on_error [opt] = True or False
610 | Returns:
611 | a Rhino.Geometry.Point3d
612 | Example:
613 | See Also:
614 | """
615 | if type(point) is Rhino.Geometry.Point3d: return point
616 | enumerable = compat.GET_HOST().Coerce3dPointFromEnumerables(point)
617 | if enumerable is not None: return enumerable
618 | if type(point) is System.Guid:
619 | found, pt = scriptcontext.doc.Objects.TryFindPoint(point)
620 | if found: return pt
621 | if hasattr(point, "__len__") and len(point)==3 and hasattr(point, "__getitem__"):
622 | try:
623 | return Rhino.Geometry.Point3d(float(point[0]), float(point[1]), float(point[2]))
624 | except:
625 | if raise_on_error: raise
626 | if type(point) is Rhino.Geometry.Vector3d or type(point) is Rhino.Geometry.Point3f or type(point) is Rhino.Geometry.Vector3f:
627 | return Rhino.Geometry.Point3d(point.X, point.Y, point.Z)
628 | if type(point) is str:
629 | point = point.split(',')
630 | return Rhino.Geometry.Point3d( float(point[0]), float(point[1]), float(point[2]) )
631 | if hasattr(point, "__len__") and len(point)==2 and hasattr(point, "__getitem__"):
632 | try:
633 | return Rhino.Geometry.Point3d(float(point[0]), float(point[1]), 0.0)
634 | except:
635 | if raise_on_error: raise
636 | if raise_on_error: raise ValueError("Could not convert %s to a Point3d" % point)
637 |
638 |
639 | def CreatePoint(point, y=None, z=None):
640 | """Converts 'point' into a Rhino.Geometry.Point3d if possible.
641 | If the provided object is already a point, it value is copied.
642 | In case the conversion fails, an error is raised.
643 | Alternatively, you can also pass two coordinates singularly for a
644 | point on the XY plane, or three for a 3D point.
645 | Parameters:
646 | point (Point3d|Vector3d|Point3f|Vector3f|str|guid|[number, number, number])
647 | Returns:
648 | point: a Rhino.Geometry.Point3d. This can be seen as an object with three indices:
649 | [0] X coordinate
650 | [1] Y coordinate
651 | [2] Z coordinate.
652 | Example:
653 | See Also:
654 | """
655 | if y is not None: return Rhino.Geometry.Point3d(float(point), float(y), float(z or 0.0))
656 | if type(point) is System.Drawing.Color: return Rhino.Geometry.Point3d(point)
657 | return coerce3dpoint(point, True)
658 |
659 |
660 | def coerce2dpoint(point, raise_on_error=False):
661 | """Convert input into a Rhino.Geometry.Point2d if possible.
662 | Parameters:
663 | point = Point2d, list, tuple, Vector3d, Point3d, str
664 | raise_on_error [opt] = True or False
665 | Returns:
666 | a Rhino.Geometry.Point2d
667 | Example:
668 | See Also:
669 | """
670 | if type(point) is Rhino.Geometry.Point2d: return point
671 | if type(point) is list or type(point) is tuple:
672 | length = len(point)
673 | if length==2 and type(point[0]) is not list and type(point[0]) is not Rhino.Geometry.Point2d:
674 | return Rhino.Geometry.Point2d(point[0], point[1])
675 | if type(point) is Rhino.Geometry.Vector3d or type(point) is Rhino.Geometry.Point3d:
676 | return Rhino.Geometry.Point2d(point.X, point.Y)
677 | if type(point) is str:
678 | point = point.split(',')
679 | return Rhino.Geometry.Point2d( float(point[0]), float(point[1]) )
680 | if raise_on_error: raise ValueError("Could not convert %s to a Point2d" % point)
681 |
682 |
683 | def coerce3dvector(vector, raise_on_error=False):
684 | """Convert input into a Rhino.Geometry.Vector3d if possible.
685 | Parameters:
686 | vector = Vector3d, Point3d, list, Point3f, Vector3f, str, uuid
687 | raise_on_error [opt] = True or False
688 | Returns:
689 | a Rhino.Geometry.Vector3d
690 | Example:
691 | See Also:
692 | """
693 | if type(vector) is Rhino.Geometry.Vector3d: return vector
694 | point = coerce3dpoint(vector, False)
695 | if point: return Rhino.Geometry.Vector3d(point.X, point.Y, point.Z)
696 | if raise_on_error: raise ValueError("Could not convert %s to a Vector3d" % vector)
697 |
698 |
699 | def CreateVector(vector, y=None, z=None):
700 | """Converts 'vector' into a Rhino.Geometry.Vector3d if possible.
701 | If the provided object is already a vector, it value is copied.
702 | If the conversion fails, an error is raised.
703 | Alternatively, you can also pass two coordinates singularly for a
704 | vector on the XY plane, or three for a 3D vector.
705 | Parameters:
706 | vector (Vector3d|Point3d|Point3f|Vector3f\str|guid|[number, number, number])
707 | raise_on_error (bool, optionals): True or False
708 | Returns:
709 | a Rhino.Geometry.Vector3d. This can be seen as an object with three indices:
710 | result[0]: X component, result[1]: Y component, and result[2] Z component.
711 | Example:
712 | See Also:
713 | """
714 | if y is not None: return Rhino.Geometry.Vector3d(float(vector), float(y), float(z or 0.0))
715 | if type(vector) is Rhino.Geometry.Vector3d: return Rhino.Geometry.Vector3d(vector)
716 | return coerce3dvector(vector, True)
717 |
718 |
719 | def coerce3dpointlist(points, raise_on_error=False):
720 | if isinstance(points, System.Array[Rhino.Geometry.Point3d]):
721 | return list(points)
722 | if isinstance(points, Rhino.Collections.Point3dList): return list(points)
723 | if type(points) is list or type(points) is tuple:
724 | count = len(points)
725 | if count>10 and type(points[0]) is Rhino.Geometry.Point3d: return points
726 | if count>0 and (coerce3dpoint(points[0]) is not None):
727 | return [coerce3dpoint(points[i], raise_on_error) for i in compat.RANGE(count)]
728 | elif count>2 and type(points[0]) is not list:
729 | point_count = count/3
730 | rc = []
731 | for i in compat.RANGE(point_count):
732 | pt = Rhino.Geometry.Point3d(points[i*3], points[i*3+1], points[i*3+2])
733 | rc.append(pt)
734 | return rc
735 | if hasattr(points, '__iter__'):
736 | return [coerce3dpoint(pt, raise_on_error) for pt in points]
737 | if raise_on_error: raise ValueError("Could not convert %s to a list of points" % points)
738 |
739 |
740 | def coerce2dpointlist(points):
741 | if points is None or isinstance(points, System.Array[Rhino.Geometry.Point2d]):
742 | return points
743 | if type(points) is list or type(points) is tuple:
744 | count = len(points)
745 | if count>0 and type(points[0]) is Rhino.Geometry.Point2d:
746 | rc = System.Array.CreateInstance(Rhino.Geometry.Point2d, count)
747 | for i in compat.RANGE(count): rc[i] = points[i]
748 | return rc
749 | elif count>1 and type(points[0]) is not list:
750 | point_count = count/2
751 | rc = System.Array.CreateInstance(Rhino.Geometry.Point2d,point_count)
752 | for i in compat.RANGE(point_count):
753 | rc[i] = Rhino.Geometry.Point2d(points[i*2], points[i*2+1])
754 | return rc
755 | elif count>0 and type(points[0]) is list:
756 | point_count = count
757 | rc = System.Array.CreateInstance(Rhino.Geometry.Point2d,point_count)
758 | for i in compat.RANGE(point_count):
759 | pt = points[i]
760 | rc[i] = Rhino.Geometry.Point2d(pt[0],pt[1])
761 | return rc
762 | return None
763 | return None
764 |
765 |
766 | def coerceplane(plane, raise_on_bad_input=False):
767 | """Convert input into a Rhino.Geometry.Plane if possible.
768 | Parameters:
769 | plane = Plane, list, tuple
770 | Returns:
771 | a Rhino.Geometry.Plane
772 | Example:
773 | See Also:
774 | """
775 | if type(plane) is Rhino.Geometry.Plane: return plane
776 | if type(plane) is list or type(plane) is tuple:
777 | length = len(plane)
778 | if length == 1:
779 | point = coerce3dpoint(plane, False)
780 | if point: plane = point; length = 3
781 | elif plane[0] is list or plane[0] is tuple: return coerceplane(plane[0])
782 | if length==3 and type(plane[0]) is not list:
783 | rc = Rhino.Geometry.Plane.WorldXY
784 | rc.Origin = Rhino.Geometry.Point3d(plane[0],plane[1],plane[2])
785 | return rc
786 | if length==9 and type(plane[0]) is not list:
787 | origin = Rhino.Geometry.Point3d(plane[0],plane[1],plane[2])
788 | xpoint = Rhino.Geometry.Point3d(plane[3],plane[4],plane[5])
789 | ypoint = Rhino.Geometry.Point3d(plane[6],plane[7],plane[8])
790 | rc = Rhino.Geometry.Plane(origin, xpoint, ypoint)
791 | return rc
792 | if (length==3 or length==4) and (type(plane[0]) is list or type(plane[0]) is tuple):
793 | origin = Rhino.Geometry.Point3d(plane[0][0],plane[0][1],plane[0][2])
794 | xpoint = Rhino.Geometry.Point3d(plane[1][0],plane[1][1],plane[1][2])
795 | ypoint = Rhino.Geometry.Point3d(plane[2][0],plane[2][1],plane[2][2])
796 | rc = Rhino.Geometry.Plane(origin, xpoint, ypoint)
797 | return rc
798 | if raise_on_bad_input: raise TypeError("%s can not be converted to a Plane"%plane)
799 |
800 |
801 | def CreatePlane(plane_or_origin, x_axis=None, y_axis=None, ignored=None):
802 | """Converts input into a Rhino.Geometry.Plane object if possible.
803 | If the provided object is already a plane, its value is copied.
804 | The returned data is accessible by indexing[origin, X axis, Y axis, Z axis], and that is the suggested method to interact with the type.
805 | The Z axis is in any case computed from the X and Y axes, so providing it is possible but not required.
806 | If the conversion fails, an error is raised.
807 | Parameters:
808 | plane (plane|point|point, vector, vector|[point, vector, vector])
809 | Returns:
810 | plane: A Rhino.Geometry.plane.
811 | Example:
812 | See Also:
813 | """
814 | if type(plane_or_origin) is Rhino.Geometry.Plane: return plane_or_origin.Clone()
815 | if x_axis != None:
816 | if y_axis == None: raise Exception("A value for the Y axis is expected if the X axis is specified.")
817 | origin = coerce3dpoint(plane_or_origin, True)
818 | x_axis = coerce3dvector(x_axis, True)
819 | y_axis = coerce3dvector(y_axis, True)
820 | return Rhino.Geometry.Plane(origin, x_axis, y_axis)
821 | return coerceplane(plane_or_origin, True)
822 |
823 |
824 | def coercexform(xform, raise_on_bad_input=False):
825 | """Convert input into a Rhino.Transform if possible.
826 | Parameters:
827 | xform = the xform
828 | raise_on_bad_input [opt] = True or False
829 | Example:
830 | See Also:
831 | """
832 | t = type(xform)
833 | if t is Rhino.Geometry.Transform: return xform
834 | if( (t is list or t is tuple) and len(xform)==4 and len(xform[0])==4):
835 | xf = Rhino.Geometry.Transform()
836 | for i in range(4):
837 | for j in range(4):
838 | xf[i,j] = xform[i][j]
839 | return xf
840 | if raise_on_bad_input: raise TypeError("%s can not be converted to a Transform"%xform)
841 |
842 |
843 | def CreateXform(xform):
844 | """Converts input into a Rhino.Geometry.Transform object if possible.
845 | If the provided object is already a transform, its value is copied.
846 | The returned data is accessible by indexing[row, column], and that is the suggested method to interact with the type.
847 | If the conversion fails, an error is raised.
848 | Parameters:
849 | xform (list): the transform. This can be seen as a 4x4 matrix, given as nested lists or tuples.
850 | Returns:
851 | transform: A Rhino.Geometry.Transform. result[0,3] gives access to the first row, last column.
852 | Example:
853 | See Also:
854 | """
855 | if type(xform) is Rhino.Geometry.Transform: return xform.Clone()
856 | return coercexform(xform, True)
857 |
858 |
859 | def coerceguid(id, raise_exception=False):
860 | if type(id) is System.Guid: return id
861 | if type(id) is str and len(id)>30:
862 | try:
863 | id = System.Guid(id)
864 | return id
865 | except:
866 | pass
867 | if (type(id) is list or type(id) is tuple) and len(id)==1:
868 | return coerceguid(id[0], raise_exception)
869 | if type(id) is Rhino.DocObjects.ObjRef: return id.ObjectId
870 | if isinstance(id,Rhino.DocObjects.RhinoObject): return id.Id
871 | if raise_exception: raise TypeError("Parameter must be a Guid or string representing a Guid")
872 |
873 |
874 | def coerceguidlist(ids):
875 | if ids is None: return None
876 | rc = []
877 | if( type(ids) is list or type(ids) is tuple ): pass
878 | else: ids = [ids]
879 | for id in ids:
880 | id = coerceguid(id)
881 | if id: rc.append(id)
882 | if rc: return rc
883 |
884 |
885 | def coerceboundingbox(bbox, raise_on_bad_input=False):
886 | if type(bbox) is Rhino.Geometry.BoundingBox: return bbox
887 | points = coerce3dpointlist(bbox)
888 | if points: return Rhino.Geometry.BoundingBox(points)
889 | if raise_on_bad_input: raise TypeError("%s can not be converted to a BoundingBox"%bbox)
890 |
891 |
892 | def coercecolor(c, raise_if_bad_input=False):
893 | if type(c) is System.Drawing.Color: return c
894 | if type(c) is list or type(c) is tuple:
895 | if len(c)==3: return System.Drawing.Color.FromArgb(c[0], c[1], c[2])
896 | elif len(c)==4: return System.Drawing.Color.FromArgb(c[3], c[0], c[1], c[2])
897 | if type(c)==type(1): return System.Drawing.Color.FromArgb(c)
898 | if raise_if_bad_input: raise TypeError("%s can not be converted to a Color"%c)
899 |
900 |
901 | def CreateColor(color, g=None, b=None, a=None):
902 | """Converts 'color' into a native color object if possible.
903 | The returned data is accessible by indexing, and that is the suggested method to interact with the type.
904 | Red index is [0], Green index is [1], Blue index is [2] and Alpha index is [3].
905 | If the provided object is already a color, its value is copied.
906 | Alternatively, you can also pass three coordinates singularly for an RGB color, or four
907 | for an RGBA color point.
908 | Parameters:
909 | color ([number, number, number]): list or 3 or 4 items. Also, a single int can be passed and it will be bitwise-parsed.
910 | Returns:
911 | color: An object that can be indexed for red, green, blu, alpha. Item[0] is red.
912 | Example:
913 | See Also:
914 | """
915 | if g is not None and b is not None: return System.Drawing.Color.FromArgb(int(a or 255), int(color), int(g), int(b))
916 | if type(color) is System.Drawing.Color: return System.Drawing.Color.FromArgb(color.A, color.R, color.G, color.B)
917 | return coercecolor(color, True)
918 |
919 |
920 | def coerceline(line, raise_if_bad_input=False):
921 | if type(line) is Rhino.Geometry.Line: return line
922 | guid = coerceguid(line, False)
923 | if guid: line = scriptcontext.doc.Objects.Find(guid).Geometry
924 | if isinstance(line, Rhino.Geometry.Curve) and line.IsLinear:
925 | return Rhino.Geometry.Line(line.PointAtStart, line.PointAtEnd)
926 | points = coerce3dpointlist(line, raise_if_bad_input)
927 | if points and len(points)>1: return Rhino.Geometry.Line(points[0], points[1])
928 | if raise_if_bad_input: raise TypeError("%s can not be converted to a Line"%line)
929 |
930 |
931 | def coercegeometry(id, raise_if_missing=False):
932 | """attempt to get GeometryBase class from given input
933 | Parameters:
934 | id = geometry identifier
935 | raise_if_missing [opt] = True or False
936 | Example:
937 | See Also:
938 | """
939 | if isinstance(id, Rhino.Geometry.GeometryBase): return id
940 | if type(id) is Rhino.DocObjects.ObjRef: return id.Geometry()
941 | if isinstance(id, Rhino.DocObjects.RhinoObject): return id.Geometry
942 | id = coerceguid(id, raise_if_missing)
943 | if id:
944 | rhobj = scriptcontext.doc.Objects.Find(id)
945 | if rhobj: return rhobj.Geometry
946 | if raise_if_missing: raise ValueError("unable to convert %s into geometry"%id)
947 |
948 |
949 | def coercebrep(id, raise_if_missing=False):
950 | """attempt to get polysurface geometry from the document with a given id
951 | Parameters:
952 | id = id to be coerced into a brep
953 | raise_if_missing [opt] = True or False
954 | Returns:
955 | a Rhino.Geometry.Brep
956 | Example:
957 | See Also:
958 | """
959 | geom = coercegeometry(id, False)
960 | if isinstance(geom, Rhino.Geometry.Brep): return geom
961 | if isinstance(geom, Rhino.Geometry.Extrusion): return geom.ToBrep(True)
962 | if raise_if_missing: raise ValueError("unable to convert %s into Brep geometry"%id)
963 |
964 |
965 | def coercecurve(id, segment_index=-1, raise_if_missing=False):
966 | """attempt to get curve geometry from the document with a given id
967 | Parameters:
968 | id = id to be coerced into a curve
969 | segment_index [opt] = index of segment to retrieve
970 | raise_if_missing [opt] = True or False
971 | Example:
972 | See Also:
973 | """
974 | if isinstance(id, Rhino.Geometry.Curve): return id
975 | if type(id) is Rhino.DocObjects.ObjRef: return id.Curve()
976 | id = coerceguid(id, True)
977 | crvObj = scriptcontext.doc.Objects.Find(id)
978 | if crvObj:
979 | curve = crvObj.Geometry
980 | if curve and segment_index>=0 and type(curve) is Rhino.Geometry.PolyCurve:
981 | curve = curve.SegmentCurve(segment_index)
982 | if isinstance(curve, Rhino.Geometry.Curve): return curve
983 | if raise_if_missing: raise ValueError("unable to convert %s into Curve geometry"%id)
984 |
985 |
986 | def coercesurface(object_id, raise_if_missing=False):
987 | """attempt to get surface geometry from the document with a given id
988 | Parameters:
989 | object_id = the object's identifier
990 | raise_if_missing [opt] = True or False
991 | Returns:
992 | a Rhino.Geometry.Surface
993 | Example:
994 | See Also:
995 | """
996 | if isinstance(object_id, Rhino.Geometry.Surface): return object_id
997 | if isinstance(object_id, Rhino.Geometry.Brep) and object_id.Faces.Count==1: return object_id.Faces[0]
998 | if type(object_id) is Rhino.DocObjects.ObjRef: return object_id.Face()
999 | object_id = coerceguid(object_id, True)
1000 | srfObj = scriptcontext.doc.Objects.Find(object_id)
1001 | if srfObj:
1002 | srf = srfObj.Geometry
1003 | if isinstance(srf, Rhino.Geometry.Surface): return srf
1004 | #single face breps are considered surfaces in the context of scripts
1005 | if isinstance(srf, Rhino.Geometry.Brep) and srf.Faces.Count==1:
1006 | return srf.Faces[0]
1007 | if raise_if_missing: raise ValueError("unable to convert %s into Surface geometry"%object_id)
1008 |
1009 |
1010 | def coercemesh(object_id, raise_if_missing=False):
1011 | """attempt to get mesh geometry from the document with a given id
1012 | Parameters:
1013 | object_id = object identifier
1014 | raise_if_missing [opt] = True or False
1015 | Returns:
1016 | a Rhino.Geometry.Mesh
1017 | Example:
1018 | See Also:
1019 | """
1020 | if type(object_id) is Rhino.DocObjects.ObjRef: return object_id.Mesh()
1021 | if isinstance(object_id, Rhino.Geometry.Mesh): return object_id
1022 | object_id = coerceguid(object_id, raise_if_missing)
1023 | if object_id:
1024 | meshObj = scriptcontext.doc.Objects.Find(object_id)
1025 | if meshObj:
1026 | mesh = meshObj.Geometry
1027 | if isinstance(mesh, Rhino.Geometry.Mesh): return mesh
1028 | if raise_if_missing: raise ValueError("unable to convert %s into Mesh geometry"%object_id)
1029 |
1030 |
1031 | def coercerhinoobject(object_id, raise_if_bad_input=False, raise_if_missing=False):
1032 | """attempt to get RhinoObject from the document with a given id
1033 | Parameters:
1034 | object_id = object's identifier
1035 | raise_if_bad_input [opt] = True or False
1036 | raise_if_missing [opt] = True or False
1037 | Returns:
1038 | a RhinoObject
1039 | Example:
1040 | See Also:
1041 | """
1042 | if isinstance(object_id, Rhino.DocObjects.RhinoObject): return object_id
1043 | object_id = coerceguid(object_id, raise_if_bad_input)
1044 | if object_id is None: return None
1045 | rc = scriptcontext.doc.Objects.Find(object_id)
1046 | if not rc and raise_if_missing: raise ValueError("%s does not exist in ObjectTable" % object_id)
1047 | return rc
1048 |
1049 | def CreateInterval(interval, y=None):
1050 | """Converts 'interval' into a Rhino.Geometry.Interval.
1051 | If the provided object is already an interval, its value is copied.
1052 | In case the conversion fails, an error is raised.
1053 | In case a single number is provided, it will be translated to an increasing interval that includes
1054 | the provided input and 0. If two values are provided, they will be used instead.
1055 | Parameters:
1056 | interval ([number, number]): or any item that can be accessed at index 0 and 1; an Interval
1057 | Returns:
1058 | interval: a Rhino.Geometry.Interval. This can be seen as an object made of two items:
1059 | [0] start of interval
1060 | [1] end of interval
1061 | Example:
1062 | See Also:
1063 | """
1064 | if y is not None: return Rhino.Geometry.Interval(float(interval), float(y))
1065 | if isinstance(interval, numbers.Number):
1066 | return Rhino.Geometry.Interval(interval if interval < 0 else 0, interval if interval > 0 else 0)
1067 | try:
1068 | return Rhino.Geometry.Interval(interval[0], interval[1])
1069 | except:
1070 | raise ValueError("unable to convert %s into an Interval: it cannot be indexed."%interval)
1071 |
```
--------------------------------------------------------------------------------
/rhino_mcp_server/static/document.py:
--------------------------------------------------------------------------------
```python
1 | import math
2 |
3 | import System
4 | import System.Drawing
5 | import System.IO
6 |
7 | import Rhino
8 |
9 | import scriptcontext
10 |
11 | from rhinoscript import utility as rhutil
12 |
13 |
14 | def _SetRenderMeshAndUpdateStyle(current):
15 | scriptcontext.doc.SetCustomMeshingParameters(current)
16 | scriptcontext.doc.MeshingParameterStyle = Rhino.Geometry.MeshingParameterStyle.Custom
17 |
18 |
19 | def CreatePreviewImage(filename, view=None, size=None, flags=0, wireframe=False):
20 | """Create a bitmap preview image of the current model
21 | Parameters:
22 | filename (str): name of the bitmap file to create
23 | view (str, optional): title of the view. If omitted, the active view is used
24 | size (number, optional): two integers that specify width and height of the bitmap
25 | flags (number, optional): Bitmap creation flags. Can be the combination of:
26 | 1 = honor object highlighting
27 | 2 = draw construction plane
28 | 4 = use ghosted shading
29 | wireframe (bool, optional): If True then a wireframe preview image. If False,
30 | a rendered image will be created
31 | Returns:
32 | bool: True or False indicating success or failure
33 | Example:
34 | import rhinoscriptsyntax as rs
35 | result = rs.CreatePreviewImage("test.jpg")
36 | if result:
37 | print( "test.jpg created successfully.")
38 | else:
39 | print( "Unable to create preview image.")
40 | See Also:
41 | ExtractPreviewImage
42 | """
43 | rhview = scriptcontext.doc.Views.ActiveView
44 | if view is not None:
45 | rhview = scriptcontext.doc.Views.Find(view, False)
46 | if rhview is None: return False
47 | rhsize = rhview.ClientRectangle.Size
48 | if size: rhsize = System.Drawing.Size(size[0], size[1])
49 | ignore_highlights = (flags&1)!=1
50 | drawcplane = (flags&2)==2
51 | useghostedshading = (flags&4)==4
52 | if wireframe:
53 | return rhview.CreateWireframePreviewImage(filename, rhsize, ignore_highlights, drawcplane)
54 | else:
55 | return rhview.CreateShadedPreviewImage(filename, rhsize, ignore_highlights, drawcplane, useghostedshading)
56 |
57 |
58 | def DocumentModified(modified=None):
59 | """Returns or sets the document's modified flag. This flag indicates whether
60 | or not any changes to the current document have been made. NOTE: setting the
61 | document modified flag to False will prevent the "Do you want to save this
62 | file..." from displaying when you close Rhino.
63 | Parameters:
64 | modified (bool): the modified state, either True or False
65 | Returns:
66 | bool: if no modified state is specified, the current modified state
67 | bool: if a modified state is specified, the previous modified state
68 | Example:
69 | import rhinoscriptsyntax as rs
70 | modified = rs.IsDocumentModified()
71 | if not modified: rs.DocumentModified(True)
72 | See Also:
73 | IsDocumentModified
74 | """
75 | oldstate = scriptcontext.doc.Modified
76 | if modified is not None and modified!=oldstate:
77 | scriptcontext.doc.Modified = modified
78 | return oldstate
79 |
80 |
81 | def DocumentName():
82 | """Returns the name of the currently loaded Rhino document (3DM file)
83 | Returns:
84 | str: the name of the currently loaded Rhino document (3DM file)
85 | Example:
86 | import rhinoscriptsyntax as rs
87 | name = rs.DocumentName()
88 | print(name)
89 | See Also:
90 | DocumentPath
91 | """
92 | return scriptcontext.doc.Name or None
93 |
94 |
95 | def DocumentPath():
96 | """Returns path of the currently loaded Rhino document (3DM file)
97 | Returns:
98 | str: the path of the currently loaded Rhino document (3DM file)
99 | Example:
100 | import rhinoscriptsyntax as rs
101 | path = rs.DocumentPath()
102 | print(path)
103 | See Also:
104 | DocumentName
105 | """
106 | # GetDirectoryName throws an exception if an empty string is passed hence the 'or None'
107 | path = System.IO.Path.GetDirectoryName(scriptcontext.doc.Path or None)
108 | # add \ or / at the end to be consistent with RhinoScript
109 | if path and not path.endswith(str(System.IO.Path.DirectorySeparatorChar)):
110 | path += System.IO.Path.DirectorySeparatorChar
111 | return path
112 |
113 |
114 | def EnableRedraw(enable=True):
115 | """Enables or disables screen redrawing
116 | Parameters:
117 | enable (bool, optional): True to enable, False to disable
118 | Returns:
119 | bool: previous screen redrawing state
120 | Example:
121 | import rhinoscriptsyntax as rs
122 | redraw = rs.EnableRedraw(True)
123 | See Also:
124 | Redraw
125 | """
126 | old = scriptcontext.doc.Views.RedrawEnabled
127 | if old!=enable: scriptcontext.doc.Views.RedrawEnabled = enable
128 | return old
129 |
130 |
131 | def ExtractPreviewImage(filename, modelname=None):
132 | """Extracts the bitmap preview image from the specified model (.3dm)
133 | Parameters:
134 | filename (str): name of the bitmap file to create. The extension of
135 | the filename controls the format of the bitmap file created.
136 | (.bmp, .tga, .jpg, .jpeg, .pcx, .png, .tif, .tiff)
137 | modelname (str, optional): The model (.3dm) from which to extract the
138 | preview image. If omitted, the currently loaded model is used.
139 | Returns:
140 | bool: True or False indicating success or failure
141 | Example:
142 | import rhinoscriptsyntax as rs
143 | result = rs.ExtractPreviewImage("test.jpg")
144 | if result:
145 | print("Test.jpg created successfully.")
146 | else:
147 | print("Unable to extract preview image.")
148 | See Also:
149 | CreatePreviewImage
150 | """
151 | return scriptcontext.doc.ExtractPreviewImage(filename, modelname)
152 |
153 |
154 | def IsDocumentModified():
155 | """Verifies that the current document has been modified in some way
156 | Returns:
157 | bool: True or False. None on error
158 | Example:
159 | import rhinoscriptsyntax as rs
160 | modified = rs.IsDocumentModified()
161 | if not modified: rs.DocumentModified(True)
162 | See Also:
163 | DocumentModified
164 | """
165 | return scriptcontext.doc.Modified
166 |
167 |
168 | def Notes(newnotes=None):
169 | """Returns or sets the document's notes. Notes are generally created
170 | using Rhino's Notes command
171 | Parameters:
172 | newnotes (str): new notes to set
173 | Returns:
174 | str: if `newnotes` is omitted, the current notes if successful
175 | str: if `newnotes` is specified, the previous notes if successful
176 | Example:
177 | import rhinoscriptsyntax as rs
178 | notes = rs.Notes()
179 | if notes: rs.MessageBox(notes)
180 | See Also:
181 |
182 | """
183 | old = scriptcontext.doc.Notes
184 | if newnotes is not None: scriptcontext.doc.Notes = newnotes
185 | return old
186 |
187 |
188 | def ReadFileVersion():
189 | """Returns the file version of the current document. Use this function to
190 | determine which version of Rhino last saved the document. Note, this
191 | function will not return values from referenced or merged files.
192 | Returns:
193 | str: the file version of the current document
194 | Example:
195 | import rhinoscriptsyntax as rs
196 | print("ReadFileVersion = {}".format(rs.ReadFileVersion()))
197 | See Also:
198 | DocumentName
199 | DocumentPath
200 | """
201 | return scriptcontext.doc.ReadFileVersion()
202 |
203 |
204 | def Redraw():
205 | """Redraws all views
206 | Returns:
207 | None
208 | Example:
209 | import rhinoscriptsyntax as rs
210 | rs.Redraw()
211 | See Also:
212 | EnableRedraw
213 | """
214 | old = scriptcontext.doc.Views.RedrawEnabled
215 | scriptcontext.doc.Views.RedrawEnabled = True
216 | scriptcontext.doc.Views.Redraw()
217 | Rhino.RhinoApp.Wait()
218 | scriptcontext.doc.Views.RedrawEnabled = old
219 |
220 |
221 | def RenderAntialias(style=None):
222 | """Returns or sets render antialiasing style
223 | Parameters:
224 | style (number, optional): level of antialiasing (0=none, 1=normal, 2=best)
225 | Returns:
226 | number: if style is not specified, the current antialiasing style
227 | number: if style is specified, the previous antialiasing style
228 | Example:
229 | import rhinoscriptsyntax as rs
230 | rs.RenderAntialias(1)
231 | See Also:
232 | RenderColor
233 | RenderResolution
234 | RenderSettings
235 | """
236 | rc = scriptcontext.doc.RenderSettings.AntialiasLevel
237 | if style==0 or style==1 or style==2:
238 | settings = scriptcontext.doc.RenderSettings
239 | settings.AntialiasLevel = style
240 | scriptcontext.doc.RenderSettings = settings
241 | return rc
242 |
243 |
244 | def RenderColor(item, color=None):
245 | """Returns or sets the render ambient light or background color
246 | Parameters:
247 | item (number): 0=ambient light color, 1=background color
248 | color (color, optional): the new color value. If omitted, the current item color is returned
249 | Returns:
250 | color: if color is not specified, the current item color
251 | color: if color is specified, the previous item color
252 | Example:
253 | import rhinoscriptsyntax as rs
254 | render_background_color = 1
255 | rs.RenderColor( render_background_color, (0,0,255) )
256 | See Also:
257 | RenderAntialias
258 | RenderResolution
259 | RenderSettings
260 | """
261 | if item!=0 and item!=1: raise ValueError("item must be 0 or 1")
262 | if item==0: rc = scriptcontext.doc.RenderSettings.AmbientLight
263 | else: rc = scriptcontext.doc.RenderSettings.BackgroundColorTop
264 | if color is not None:
265 | color = rhutil.coercecolor(color, True)
266 | settings = scriptcontext.doc.RenderSettings
267 | if item==0: settings.AmbientLight = color
268 | else: settings.BackgroundColorTop = color
269 | scriptcontext.doc.RenderSettings = settings
270 | scriptcontext.doc.Views.Redraw()
271 | return rc
272 |
273 |
274 | def RenderResolution(resolution=None):
275 | """Returns or sets the render resolution
276 | Parameters:
277 | resolution ([number, number], optional): width and height of render
278 | Returns:
279 | tuple(number, number): if resolution is not specified, the current resolution width,height
280 | tuple(number, number): if resolution is specified, the previous resolution width, height
281 | Example:
282 | import rhinoscriptsyntax as rs
283 | sizex, sizey = rs.Viewsize()
284 | resolution = sizex/2 , sizey/2
285 | rs.RenderResolution( resolution )
286 | See Also:
287 | RenderAntialias
288 | RenderColor
289 | RenderSettings
290 | """
291 | rc = scriptcontext.doc.RenderSettings.ImageSize
292 | if resolution:
293 | settings = scriptcontext.doc.RenderSettings
294 | settings.ImageSize = System.Drawing.Size(resolution[0], resolution[1])
295 | scriptcontext.doc.RenderSettings = settings
296 | return rc.Width, rc.Height
297 |
298 |
299 | def RenderMeshDensity(density=None):
300 | """Returns or sets the render mesh density property of the active document.
301 | For more information on render meshes, see the Document Properties: Mesh topic in the Rhino help file.
302 | Parameters:
303 | density (number, optional): the new render mesh density, which is a number between 0.0 and 1.0.
304 | Returns:
305 | number: if density is not specified, the current render mesh density if successful.
306 | number: if density is specified, the previous render mesh density if successful.
307 | Example:
308 | import rhinoscriptsyntax as rs
309 | print("Quality: %s" % rs.RenderMeshQuality())
310 | print("Mesh density: %s" % rs.RenderMeshDensity())
311 | print("Maximum angle: %s" % rs.RenderMeshMaxAngle())
312 | print("Maximum aspect ratio: %s" % rs.RenderMeshMaxAspectRatio())
313 | print("Minimun edge length: %s" % rs.RenderMeshMinEdgeLength())
314 | print("Maximum edge length: %s" % rs.RenderMeshMaxEdgeLength())
315 | print("Maximum distance, edge to surface: %s" % rs.RenderMeshMaxDistEdgeToSrf())
316 | print("Minumum initial grid quads: %s" % rs.RenderMeshMinInitialGridQuads())
317 | print("Other settings: %s" % rs.RenderMeshSettings())
318 | See Also:
319 | RenderMeshDensity
320 | RenderMeshMaxAngle
321 | RenderMeshMaxAspectRatio
322 | RenderMeshMaxDistEdgeToSrf
323 | RenderMeshMaxEdgeLength
324 | RenderMeshMinEdgeLength
325 | RenderMeshMinInitialGridQuads
326 | RenderMeshQuality
327 | RenderMeshSettings
328 | """
329 | current = scriptcontext.doc.GetCurrentMeshingParameters()
330 | rc = current.RelativeTolerance
331 | if density is not None:
332 | if Rhino.RhinoMath.Clamp(density, 0.0, 1.0) != density: return None
333 | current.RelativeTolerance = density
334 | _SetRenderMeshAndUpdateStyle(current)
335 | return rc
336 |
337 |
338 | def RenderMeshMaxAngle(angle_degrees=None):
339 | """Returns or sets the render mesh maximum angle property of the active document.
340 | For more information on render meshes, see the Document Properties: Mesh topic in the Rhino help file.
341 | Parameters:
342 | angle_degrees (number, optional): the new maximum angle, which is a positive number in degrees.
343 | Returns:
344 | number: if angle_degrees is not specified, the current maximum angle if successful.
345 | number: if angle_degrees is specified, the previous maximum angle if successful.
346 | None: if not successful, or on error.
347 | Example:
348 | import rhinoscriptsyntax as rs
349 | print("Quality: %s" % rs.RenderMeshQuality())
350 | print("Mesh density: %s" % rs.RenderMeshDensity())
351 | print("Maximum angle: %s" % rs.RenderMeshMaxAngle())
352 | print("Maximum aspect ratio: %s" % rs.RenderMeshMaxAspectRatio())
353 | print("Minimun edge length: %s" % rs.RenderMeshMinEdgeLength())
354 | print("Maximum edge length: %s" % rs.RenderMeshMaxEdgeLength())
355 | print("Maximum distance, edge to surface: %s" % rs.RenderMeshMaxDistEdgeToSrf())
356 | print("Minumum initial grid quads: %s" % rs.RenderMeshMinInitialGridQuads())
357 | print("Other settings: %s" % rs.RenderMeshSettings())
358 | See Also:
359 | RenderMeshDensity
360 | RenderMeshMaxAngle
361 | RenderMeshMaxAspectRatio
362 | RenderMeshMaxDistEdgeToSrf
363 | RenderMeshMaxEdgeLength
364 | RenderMeshMinEdgeLength
365 | RenderMeshMinInitialGridQuads
366 | RenderMeshQuality
367 | RenderMeshSettings
368 | """
369 | current = scriptcontext.doc.GetCurrentMeshingParameters()
370 | rc = math.degrees(current.RefineAngle)
371 | if angle_degrees is not None:
372 | if angle_degrees < 0: return None
373 | current.RefineAngle = math.radians(angle_degrees)
374 | _SetRenderMeshAndUpdateStyle(current)
375 | return rc
376 |
377 |
378 | def RenderMeshMaxAspectRatio(ratio=None):
379 | """Returns or sets the render mesh maximum aspect ratio property of the active document.
380 | For more information on render meshes, see the Document Properties: Mesh topic in the Rhino help file.
381 | Parameters:
382 | ratio (number, optional): the render mesh maximum aspect ratio. The suggested range, when not zero, is from 1 to 100.
383 | Returns:
384 | number: if ratio is not specified, the current render mesh maximum aspect ratio if successful.
385 | number: if ratio is specified, the previous render mesh maximum aspect ratio if successful.
386 | None: if not successful, or on error.
387 | Example:
388 | import rhinoscriptsyntax as rs
389 | print("Quality: %s" % rs.RenderMeshQuality())
390 | print("Mesh density: %s" % rs.RenderMeshDensity())
391 | print("Maximum angle: %s" % rs.RenderMeshMaxAngle())
392 | print("Maximum aspect ratio: %s" % rs.RenderMeshMaxAspectRatio())
393 | print("Minimun edge length: %s" % rs.RenderMeshMinEdgeLength())
394 | print("Maximum edge length: %s" % rs.RenderMeshMaxEdgeLength())
395 | print("Maximum distance, edge to surface: %s" % rs.RenderMeshMaxDistEdgeToSrf())
396 | print("Minumum initial grid quads: %s" % rs.RenderMeshMinInitialGridQuads())
397 | print("Other settings: %s" % rs.RenderMeshSettings())
398 | See Also:
399 | RenderMeshDensity
400 | RenderMeshMaxAngle
401 | RenderMeshMaxAspectRatio
402 | RenderMeshMaxDistEdgeToSrf
403 | RenderMeshMaxEdgeLength
404 | RenderMeshMinEdgeLength
405 | RenderMeshMinInitialGridQuads
406 | RenderMeshQuality
407 | RenderMeshSettings
408 | """
409 | current = scriptcontext.doc.GetCurrentMeshingParameters()
410 | rc = current.GridAspectRatio
411 | if ratio is not None:
412 | current.GridAspectRatio = ratio
413 | _SetRenderMeshAndUpdateStyle(current)
414 | return rc
415 |
416 |
417 | def RenderMeshMaxDistEdgeToSrf(distance=None):
418 | """Returns or sets the render mesh maximum distance, edge to surface parameter of the active document.
419 | For more information on render meshes, see the Document Properties: Mesh topic in the Rhino help file.
420 | Parameters:
421 | distance (number, optional): the render mesh maximum distance, edge to surface.
422 | Returns:
423 | number: if distance is not specified, the current render mesh maximum distance, edge to surface if successful.
424 | number: if distance is specified, the previous render mesh maximum distance, edge to surface if successful.
425 | None: if not successful, or on error.
426 | Example:
427 | import rhinoscriptsyntax as rs
428 | print("Quality: %s" % rs.RenderMeshQuality())
429 | print("Mesh density: %s" % rs.RenderMeshDensity())
430 | print("Maximum angle: %s" % rs.RenderMeshMaxAngle())
431 | print("Maximum aspect ratio: %s" % rs.RenderMeshMaxAspectRatio())
432 | print("Minimun edge length: %s" % rs.RenderMeshMinEdgeLength())
433 | print("Maximum edge length: %s" % rs.RenderMeshMaxEdgeLength())
434 | print("Maximum distance, edge to surface: %s" % rs.RenderMeshMaxDistEdgeToSrf())
435 | print("Minumum initial grid quads: %s" % rs.RenderMeshMinInitialGridQuads())
436 | print("Other settings: %s" % rs.RenderMeshSettings())
437 | See Also:
438 | RenderMeshDensity
439 | RenderMeshMaxAngle
440 | RenderMeshMaxAspectRatio
441 | RenderMeshMaxDistEdgeToSrf
442 | RenderMeshMaxEdgeLength
443 | RenderMeshMinEdgeLength
444 | RenderMeshMinInitialGridQuads
445 | RenderMeshQuality
446 | RenderMeshSettings
447 | """
448 | current = scriptcontext.doc.GetCurrentMeshingParameters()
449 | rc = current.Tolerance
450 | if distance is not None:
451 | current.Tolerance = distance
452 | _SetRenderMeshAndUpdateStyle(current)
453 | return rc
454 |
455 |
456 | def RenderMeshMaxEdgeLength(distance=None):
457 | """Returns or sets the render mesh maximum edge length parameter of the active document.
458 | For more information on render meshes, see the Document Properties: Mesh topic in the Rhino help file.
459 | Parameters:
460 | distance (number, optional): the render mesh maximum edge length.
461 | Returns:
462 | number: if distance is not specified, the current render mesh maximum edge length if successful.
463 | number: if distance is specified, the previous render mesh maximum edge length if successful.
464 | None: if not successful, or on error.
465 | Example:
466 | import rhinoscriptsyntax as rs
467 | print("Quality: %s" % rs.RenderMeshQuality())
468 | print("Mesh density: %s" % rs.RenderMeshDensity())
469 | print("Maximum angle: %s" % rs.RenderMeshMaxAngle())
470 | print("Maximum aspect ratio: %s" % rs.RenderMeshMaxAspectRatio())
471 | print("Minimun edge length: %s" % rs.RenderMeshMinEdgeLength())
472 | print("Maximum edge length: %s" % rs.RenderMeshMaxEdgeLength())
473 | print("Maximum distance, edge to surface: %s" % rs.RenderMeshMaxDistEdgeToSrf())
474 | print("Minumum initial grid quads: %s" % rs.RenderMeshMinInitialGridQuads())
475 | print("Other settings: %s" % rs.RenderMeshSettings())
476 | See Also:
477 | RenderMeshDensity
478 | RenderMeshMaxAngle
479 | RenderMeshMaxAspectRatio
480 | RenderMeshMaxDistEdgeToSrf
481 | RenderMeshMaxEdgeLength
482 | RenderMeshMinEdgeLength
483 | RenderMeshMinInitialGridQuads
484 | RenderMeshQuality
485 | RenderMeshSettings
486 | """
487 | current = scriptcontext.doc.GetCurrentMeshingParameters()
488 | rc = current.MaximumEdgeLength
489 | if distance is not None:
490 | current.MaximumEdgeLength = distance
491 | _SetRenderMeshAndUpdateStyle(current)
492 | return rc
493 |
494 |
495 | def RenderMeshMinEdgeLength(distance=None):
496 | """Returns or sets the render mesh minimum edge length parameter of the active document.
497 | For more information on render meshes, see the Document Properties: Mesh topic in the Rhino help file.
498 | Parameters:
499 | distance (number, optional): the render mesh minimum edge length.
500 | Returns:
501 | number: if distance is not specified, the current render mesh minimum edge length if successful.
502 | number: if distance is specified, the previous render mesh minimum edge length if successful.
503 | None: if not successful, or on error.
504 | Example:
505 | import rhinoscriptsyntax as rs
506 | print("Quality: %s" % rs.RenderMeshQuality())
507 | print("Mesh density: %s" % rs.RenderMeshDensity())
508 | print("Maximum angle: %s" % rs.RenderMeshMaxAngle())
509 | print("Maximum aspect ratio: %s" % rs.RenderMeshMaxAspectRatio())
510 | print("Minimun edge length: %s" % rs.RenderMeshMinEdgeLength())
511 | print("Maximum edge length: %s" % rs.RenderMeshMaxEdgeLength())
512 | print("Maximum distance, edge to surface: %s" % rs.RenderMeshMaxDistEdgeToSrf())
513 | print("Minumum initial grid quads: %s" % rs.RenderMeshMinInitialGridQuads())
514 | print("Other settings: %s" % rs.RenderMeshSettings())
515 | See Also:
516 | RenderMeshDensity
517 | RenderMeshMaxAngle
518 | RenderMeshMaxAspectRatio
519 | RenderMeshMaxDistEdgeToSrf
520 | RenderMeshMaxEdgeLength
521 | RenderMeshMinEdgeLength
522 | RenderMeshMinInitialGridQuads
523 | RenderMeshQuality
524 | RenderMeshSettings
525 | """
526 | current = scriptcontext.doc.GetCurrentMeshingParameters()
527 | rc = current.MinimumEdgeLength
528 | if distance is not None:
529 | current.MinimumEdgeLength = distance
530 | _SetRenderMeshAndUpdateStyle(current)
531 | return rc
532 |
533 |
534 | def RenderMeshMinInitialGridQuads(quads=None):
535 | """Returns or sets the render mesh minimum initial grid quads parameter of the active document.
536 | For more information on render meshes, see the Document Properties: Mesh topic in the Rhino help file.
537 | Parameters:
538 | quads (number, optional): the render mesh minimum initial grid quads. The suggested range is from 0 to 10000.
539 | Returns:
540 | number: if quads is not specified, the current render mesh minimum initial grid quads if successful.
541 | number: if quads is specified, the previous render mesh minimum initial grid quads if successful.
542 | None: if not successful, or on error.
543 | Example:
544 | import rhinoscriptsyntax as rs
545 | print("Quality: %s" % rs.RenderMeshQuality())
546 | print("Mesh density: %s" % rs.RenderMeshDensity())
547 | print("Maximum angle: %s" % rs.RenderMeshMaxAngle())
548 | print("Maximum aspect ratio: %s" % rs.RenderMeshMaxAspectRatio())
549 | print("Minimun edge length: %s" % rs.RenderMeshMinEdgeLength())
550 | print("Maximum edge length: %s" % rs.RenderMeshMaxEdgeLength())
551 | print("Maximum distance, edge to surface: %s" % rs.RenderMeshMaxDistEdgeToSrf())
552 | print("Minumum initial grid quads: %s" % rs.RenderMeshMinInitialGridQuads())
553 | print("Other settings: %s" % rs.RenderMeshSettings())
554 | See Also:
555 | RenderMeshDensity
556 | RenderMeshMaxAngle
557 | RenderMeshMaxAspectRatio
558 | RenderMeshMaxDistEdgeToSrf
559 | RenderMeshMaxEdgeLength
560 | RenderMeshMinEdgeLength
561 | RenderMeshMinInitialGridQuads
562 | RenderMeshQuality
563 | RenderMeshSettings
564 | """
565 | current = scriptcontext.doc.GetCurrentMeshingParameters()
566 | rc = current.GridMinCount
567 | if quads is not None:
568 | current.GridMinCount = quads
569 | _SetRenderMeshAndUpdateStyle(current)
570 | return rc
571 |
572 |
573 | def RenderMeshQuality(quality=None):
574 | """Returns or sets the render mesh quality of the active document.
575 | For more information on render meshes, see the Document Properties: Mesh topic in the Rhino help file.
576 | Parameters:
577 | quality (number, optional): the render mesh quality, either:
578 | 0: Jagged and faster. Objects may look jagged, but they should shade and render relatively quickly.
579 | 1: Smooth and slower. Objects should look smooth, but they may take a very long time to shade and render.
580 | 2: Custom.
581 | Returns:
582 | number: if quality is not specified, the current render mesh quality if successful.
583 | number: if quality is specified, the previous render mesh quality if successful.
584 | None: if not successful, or on error.
585 | Example:
586 | import rhinoscriptsyntax as rs
587 | print("Quality: %s" % rs.RenderMeshQuality())
588 | print("Mesh density: %s" % rs.RenderMeshDensity())
589 | print("Maximum angle: %s" % rs.RenderMeshMaxAngle())
590 | print("Maximum aspect ratio: %s" % rs.RenderMeshMaxAspectRatio())
591 | print("Minimun edge length: %s" % rs.RenderMeshMinEdgeLength())
592 | print("Maximum edge length: %s" % rs.RenderMeshMaxEdgeLength())
593 | print("Maximum distance, edge to surface: %s" % rs.RenderMeshMaxDistEdgeToSrf())
594 | print("Minumum initial grid quads: %s" % rs.RenderMeshMinInitialGridQuads())
595 | print("Other settings: %s" % rs.RenderMeshSettings())
596 | See Also:
597 | RenderMeshDensity
598 | RenderMeshMaxAngle
599 | RenderMeshMaxAspectRatio
600 | RenderMeshMaxDistEdgeToSrf
601 | RenderMeshMaxEdgeLength
602 | RenderMeshMinEdgeLength
603 | RenderMeshMinInitialGridQuads
604 | RenderMeshQuality
605 | RenderMeshSettings
606 | """
607 | current = scriptcontext.doc.MeshingParameterStyle
608 | if current == Rhino.Geometry.MeshingParameterStyle.Fast:
609 | rc = 0
610 | elif current == Rhino.Geometry.MeshingParameterStyle.Quality:
611 | rc = 1
612 | elif current == Rhino.Geometry.MeshingParameterStyle.Custom:
613 | rc = 2
614 | else:
615 | rc = None
616 | if quality is not None:
617 | if quality == 0:
618 | new_value = Rhino.Geometry.MeshingParameterStyle.Fast
619 | elif quality == 1:
620 | new_value = Rhino.Geometry.MeshingParameterStyle.Quality
621 | elif quality == 2:
622 | new_value = Rhino.Geometry.MeshingParameterStyle.Custom
623 | else:
624 | return None
625 | scriptcontext.doc.MeshingParameterStyle = new_value
626 | return rc
627 |
628 |
629 | def RenderMeshSettings(settings=None):
630 | """Returns or sets the render mesh settings of the active document.
631 | For more information on render meshes, see the Document Properties: Mesh topic in the Rhino help file.
632 | Parameters:
633 | settings (number, optional): the render mesh settings, which is a bit-coded number that allows or disallows certain features.
634 | The bits can be added together in any combination to form a value between 0 and 7. The bit values are as follows:
635 | 0: No settings enabled.
636 | 1: Refine mesh enabled.
637 | 2: Jagged seams enabled.
638 | 4: Simple planes enabled.
639 | 8: Texture is packed, scaled and normalized; otherwise unpacked, unscaled and normalized.
640 | Returns:
641 | number: if settings is not specified, the current render mesh settings if successful.
642 | number: if settings is specified, the previous render mesh settings if successful.
643 | None: if not successful, or on error.
644 | Example:
645 | import rhinoscriptsyntax as rs
646 | print("Quality: %s" % rs.RenderMeshQuality())
647 | print("Mesh density: %s" % rs.RenderMeshDensity())
648 | print("Maximum angle: %s" % rs.RenderMeshMaxAngle())
649 | print("Maximum aspect ratio: %s" % rs.RenderMeshMaxAspectRatio())
650 | print("Minimun edge length: %s" % rs.RenderMeshMinEdgeLength())
651 | print("Maximum edge length: %s" % rs.RenderMeshMaxEdgeLength())
652 | print("Maximum distance, edge to surface: %s" % rs.RenderMeshMaxDistEdgeToSrf())
653 | print("Minumum initial grid quads: %s" % rs.RenderMeshMinInitialGridQuads())
654 | print("Other settings: %s" % rs.RenderMeshSettings())
655 | See Also:
656 | RenderMeshDensity
657 | RenderMeshMaxAngle
658 | RenderMeshMaxAspectRatio
659 | RenderMeshMaxDistEdgeToSrf
660 | RenderMeshMaxEdgeLength
661 | RenderMeshMinEdgeLength
662 | RenderMeshMinInitialGridQuads
663 | RenderMeshQuality
664 | RenderMeshSettings
665 | """
666 | current = scriptcontext.doc.GetCurrentMeshingParameters()
667 | rc = 0
668 | if current.RefineGrid: rc += 1
669 | if current.JaggedSeams: rc += 2
670 | if current.SimplePlanes: rc += 4
671 | if current.TextureRange == Rhino.Geometry.MeshingParameterTextureRange.PackedScaledNormalized: rc += 8
672 | if settings is not None:
673 | current.RefineGrid = (settings & 1)
674 | current.JaggedSeams = (settings & 2)
675 | current.SimplePlanes = (settings & 4)
676 | current.TextureRange = Rhino.Geometry.MeshingParameterTextureRange.PackedScaledNormalized if (settings & 8) else Rhino.Geometry.MeshingParameterTextureRange.UnpackedUnscaledNormalized
677 | _SetRenderMeshAndUpdateStyle(current)
678 | return rc
679 |
680 |
681 | def RenderSettings(settings=None):
682 | """Returns or sets render settings
683 | Parameters:
684 | settings (number, optional): bit-coded flags of render settings to modify.
685 | 0=none,
686 | 1=create shadows,
687 | 2=use lights on layers that are off,
688 | 4=render curves and isocurves,
689 | 8=render dimensions and text
690 | Returns:
691 | number: if settings are not specified, the current render settings in bit-coded flags
692 | number: if settings are specified, the previous render settings in bit-coded flags
693 | Example:
694 | import rhinoscriptsyntax as rs
695 | render_annotations = 8
696 | settings = rs.RenderSettings()
697 | if settings & render_annotations:
698 | settings = settings - render_annotations
699 | rs.RenderSettings( settings )
700 | See Also:
701 | RenderAntialias
702 | RenderColor
703 | RenderResolution
704 | """
705 | rc = 0
706 | rendersettings = scriptcontext.doc.RenderSettings
707 | if rendersettings.ShadowmapLevel: rc+=1
708 | if rendersettings.UseHiddenLights: rc+=2
709 | if rendersettings.RenderCurves: rc+=4
710 | if rendersettings.RenderAnnotations: rc+=8
711 | if settings is not None:
712 | rendersettings.ShadowmapLevel = (settings & 1)
713 | rendersettings.UseHiddenLights = (settings & 2)==2
714 | rendersettings.RenderCurves = (settings & 4)==4
715 | rendersettings.RenderAnnotations = (settings & 8)==8
716 | scriptcontext.doc.RenderSettings = rendersettings
717 | return rc
718 |
719 |
720 | def UnitAbsoluteTolerance(tolerance=None, in_model_units=True):
721 | """Resturns or sets the document's absolute tolerance. Absolute tolerance
722 | is measured in drawing units. See Rhino's document properties command
723 | (Units and Page Units Window) for details
724 | Parameters:
725 | tolerance (number, optional): the absolute tolerance to set
726 | in_model_units (bool, optional): Return or modify the document's model units (True)
727 | or the document's page units (False)
728 | Returns:
729 | number: if tolerance is not specified, the current absolute tolerance
730 | number: if tolerance is specified, the previous absolute tolerance
731 | Example:
732 | import rhinoscriptsyntax as rs
733 | tol = rs.UnitAbsoluteTolerance()
734 | if tol<0.01:
735 | rs.UnitAbsoluteTolerance( 0.01 )
736 | See Also:
737 | UnitAngleTolerance
738 | UnitDistanceDisplayPrecision
739 | UnitRelativeTolerance
740 | UnitSystem
741 | """
742 | if in_model_units:
743 | rc = scriptcontext.doc.ModelAbsoluteTolerance
744 | if tolerance is not None:
745 | scriptcontext.doc.ModelAbsoluteTolerance = tolerance
746 | else:
747 | rc = scriptcontext.doc.PageAbsoluteTolerance
748 | if tolerance is not None:
749 | scriptcontext.doc.PageAbsoluteTolerance = tolerance
750 | return rc
751 |
752 |
753 | def UnitAngleTolerance(angle_tolerance_degrees=None, in_model_units=True):
754 | """Return or set the document's angle tolerance. Angle tolerance is
755 | measured in degrees. See Rhino's DocumentProperties command
756 | (Units and Page Units Window) for details
757 | Parameters:
758 | angle_tolerance_degrees (number, optional): the angle tolerance to set
759 | in_model_units (number, optional): Return or modify the document's model units (True)
760 | or the document's page units (False)
761 | Returns:
762 | number: if angle_tolerance_degrees is not specified, the current angle tolerance
763 | number: if angle_tolerance_degrees is specified, the previous angle tolerance
764 | Example:
765 | import rhinoscriptsyntax as rs
766 | tol = rs.UnitAngleTolerance()
767 | if tol<3.0:
768 | rs.UnitAngleTolerance(3.0)
769 | See Also:
770 | UnitAbsoluteTolerance
771 | UnitDistanceDisplayPrecision
772 | UnitRelativeTolerance
773 | UnitSystem
774 | """
775 | if in_model_units:
776 | rc = scriptcontext.doc.ModelAngleToleranceDegrees
777 | if angle_tolerance_degrees is not None:
778 | scriptcontext.doc.ModelAngleToleranceDegrees = angle_tolerance_degrees
779 | else:
780 | rc = scriptcontext.doc.PageAngleToleranceDegrees
781 | if angle_tolerance_degrees is not None:
782 | scriptcontext.doc.PageAngleToleranceDegrees = angle_tolerance_degrees
783 | return rc
784 |
785 |
786 | def UnitDistanceDisplayPrecision(precision=None, model_units=True):
787 | """Return or set the document's distance display precision
788 | Parameters:
789 | precision (number, optional): The distance display precision. If the current distance display mode is Decimal, then precision is the number of decimal places.
790 | If the current distance display mode is Fractional (including Feet and Inches), then the denominator = (1/2)^precision.
791 | Use UnitDistanceDisplayMode to get the current distance display mode.
792 | model_units (bool, optional): Return or modify the document's model units (True) or the document's page units (False). The default is True.
793 | Returns:
794 | number: If precision is not specified, the current distance display precision if successful. If precision is specified, the previous distance display precision if successful. If not successful, or on error.
795 | Example:
796 | import rhinoscriptsyntax as rs
797 | precision = 3
798 | rs.UnitDistanceDisplayPrecision( precision )
799 | See Also:
800 | UnitAbsoluteTolerance
801 | UnitAngleTolerance
802 | UnitRelativeTolerance
803 | UnitSystem
804 | """
805 | if model_units:
806 | rc = scriptcontext.doc.ModelDistanceDisplayPrecision
807 | if precision: scriptcontext.doc.ModelDistanceDisplayPrecision = precision
808 | return rc
809 | rc = scriptcontext.doc.PageDistanceDisplayPrecision
810 | if precision: scriptcontext.doc.PageDistanceDisplayPrecision = precision
811 | return rc
812 |
813 |
814 | def UnitRelativeTolerance(relative_tolerance=None, in_model_units=True):
815 | """Return or set the document's relative tolerance. Relative tolerance
816 | is measured in percent. See Rhino's DocumentProperties command
817 | (Units and Page Units Window) for details
818 | Parameters:
819 | relative_tolerance (number, optional) the relative tolerance in percent
820 | in_model_units (bool, optional): Return or modify the document's model units (True)
821 | or the document's page units (False)
822 | Returns:
823 | number: if relative_tolerance is not specified, the current tolerance in percent
824 | number: if relative_tolerance is specified, the previous tolerance in percent
825 | Example:
826 | import rhinoscriptsyntax as rs
827 | tol = rs.UnitRelativeTolerance()
828 | if tol<1.0:
829 | rs.UnitRelativeTolerance(1.0)
830 | See Also:
831 | UnitAbsoluteTolerance
832 | UnitAngleTolerance
833 | UnitDistanceDisplayPrecision
834 | UnitSystem
835 | """
836 | if in_model_units:
837 | rc = scriptcontext.doc.ModelRelativeTolerance
838 | if relative_tolerance is not None:
839 | scriptcontext.doc.ModelRelativeTolerance = relative_tolerance
840 | else:
841 | rc = scriptcontext.doc.PageRelativeTolerance
842 | if relative_tolerance is not None:
843 | scriptcontext.doc.PageRelativeTolerance = relative_tolerance
844 | return rc
845 |
846 |
847 | def UnitScale(to_system, from_system=None):
848 | """Return the scale factor for changing between unit systems.
849 | Parameters:
850 | to_system (number): The unit system to convert to. The unit systems are are:
851 | 0 - No unit system
852 | 1 - Microns (1.0e-6 meters)
853 | 2 - Millimeters (1.0e-3 meters)
854 | 3 - Centimeters (1.0e-2 meters)
855 | 4 - Meters
856 | 5 - Kilometers (1.0e+3 meters)
857 | 6 - Microinches (2.54e-8 meters, 1.0e-6 inches)
858 | 7 - Mils (2.54e-5 meters, 0.001 inches)
859 | 8 - Inches (0.0254 meters)
860 | 9 - Feet (0.3408 meters, 12 inches)
861 | 10 - Miles (1609.344 meters, 5280 feet)
862 | 11 - *Reserved for custom Unit System*
863 | 12 - Angstroms (1.0e-10 meters)
864 | 13 - Nanometers (1.0e-9 meters)
865 | 14 - Decimeters (1.0e-1 meters)
866 | 15 - Dekameters (1.0e+1 meters)
867 | 16 - Hectometers (1.0e+2 meters)
868 | 17 - Megameters (1.0e+6 meters)
869 | 18 - Gigameters (1.0e+9 meters)
870 | 19 - Yards (0.9144 meters, 36 inches)
871 | 20 - Printer point (1/72 inches, computer points)
872 | 21 - Printer pica (1/6 inches, (computer picas)
873 | 22 - Nautical mile (1852 meters)
874 | 23 - Astronomical (1.4959787e+11)
875 | 24 - Lightyears (9.46073e+15 meters)
876 | 25 - Parsecs (3.08567758e+16)
877 | from_system (number, optional): the unit system to convert from (see above). If omitted,
878 | the document's current unit system is used
879 | Returns:
880 | number: scale factor for changing between unit systems
881 | Example:
882 | import rhinoscriptsyntax as rs
883 | print(rs.UnitScale(3, 4)) # 100.0
884 | print(rs.UnitScale(3, 8)) # 2.54
885 | print(rs.UnitScale(8, 9)) # 12.0
886 | See Also:
887 | UnitSystem
888 | UnitSystemName
889 | """
890 | if from_system is None:
891 | from_system = scriptcontext.doc.ModelUnitSystem
892 | if type(from_system) is int:
893 | from_system = System.Enum.ToObject(Rhino.UnitSystem, from_system)
894 | if type(to_system) is int:
895 | to_system = System.Enum.ToObject(Rhino.UnitSystem, to_system)
896 | return Rhino.RhinoMath.UnitScale(from_system, to_system)
897 |
898 |
899 | def UnitSystem(unit_system=None, scale=False, in_model_units=True):
900 | """Return or set the document's unit system. See Rhino's DocumentProperties
901 | command (Units and Page Units Window) for details
902 | Parameters:
903 | unit_system (number, optional): The unit system to set the document to. The unit systems are:
904 | 0 - No unit system
905 | 1 - Microns (1.0e-6 meters)
906 | 2 - Millimeters (1.0e-3 meters)
907 | 3 - Centimeters (1.0e-2 meters)
908 | 4 - Meters
909 | 5 - Kilometers (1.0e+3 meters)
910 | 6 - Microinches (2.54e-8 meters, 1.0e-6 inches)
911 | 7 - Mils (2.54e-5 meters, 0.001 inches)
912 | 8 - Inches (0.0254 meters)
913 | 9 - Feet (0.3048 meters, 12 inches)
914 | 10 - Miles (1609.344 meters, 5280 feet)
915 | 11 - *Reserved for custom Unit System*
916 | 12 - Angstroms (1.0e-10 meters)
917 | 13 - Nanometers (1.0e-9 meters)
918 | 14 - Decimeters (1.0e-1 meters)
919 | 15 - Dekameters (1.0e+1 meters)
920 | 16 - Hectometers (1.0e+2 meters)
921 | 17 - Megameters (1.0e+6 meters)
922 | 18 - Gigameters (1.0e+9 meters)
923 | 19 - Yards (0.9144 meters, 36 inches)
924 | 20 - Printer point (1/72 inches, computer points)
925 | 21 - Printer pica (1/6 inches, (computer picas)
926 | 22 - Nautical mile (1852 meters)
927 | 23 - Astronomical (1.4959787e+11)
928 | 24 - Lightyears (9.46073e+15 meters)
929 | 25 - Parsecs (3.08567758e+16)
930 | scale (bool, optional): Scale existing geometry based on the new unit system.
931 | If not specified, any existing geometry is not scaled (False)
932 | in_model_units (number, optional): Return or modify the document's model units (True)
933 | or the document's page units (False). The default is True.
934 | Returns:
935 | number: if unit_system is not specified, the current unit system
936 | number: if unit_system is specified, the previous unit system
937 | None: on error
938 | Example:
939 | import rhinoscriptsyntax as rs
940 | rhUnitMillimeters = 2
941 | rhUnitInches = 8
942 | current_system = rs.UnitSystem()
943 | if current_system==rhUnitMillimeters:
944 | rs.UnitSystem(rhUnitInches, True)
945 | See Also:
946 | UnitAbsoluteTolerance
947 | UnitAngleTolerance
948 | UnitDistanceDisplayPrecision
949 | UnitRelativeTolerance
950 | """
951 | if (unit_system is not None and (unit_system<1 or unit_system>25)):
952 | raise ValueError("unit_system value of %s is not valid"%unit_system)
953 | if in_model_units:
954 | rc = int(scriptcontext.doc.ModelUnitSystem)
955 | if unit_system is not None:
956 | unit_system = System.Enum.ToObject(Rhino.UnitSystem, unit_system)
957 | scriptcontext.doc.AdjustModelUnitSystem(unit_system, scale)
958 | else:
959 | rc = int(scriptcontext.doc.PageUnitSystem)
960 | if unit_system is not None:
961 | unit_system = System.Enum.ToObject(Rhino.UnitSystem, unit_system)
962 | scriptcontext.doc.AdjustPageUnitSystem(unit_system, scale)
963 | return rc
964 |
965 |
966 | def UnitSystemName(capitalize=False, singular=True, abbreviate=False, model_units=True):
967 | """Returns the name of the current unit system
968 | Parameters:
969 | capitalize (bool, optional): Capitalize the first character of the units system name (e.g. return "Millimeter" instead of "millimeter"). The default is not to capitalize the first character (false).
970 | singular (bool, optional): Return the singular form of the units system name (e.g. "millimeter" instead of "millimeters"). The default is to return the singular form of the name (true).
971 | abbreviate (bool, optional): Abbreviate the name of the units system (e.g. return "mm" instead of "millimeter"). The default is not to abbreviate the name (false).
972 | model_units (bool, optional): Return the document's model units (True) or the document's page units (False). The default is True.
973 | Returns:
974 | str: The name of the current units system if successful.
975 | Example:
976 | import rhinoscriptsyntax as rs
977 | system = rs.UnitSystemName(False, False, False)
978 | print("The units system is set to{}".format(system))
979 | See Also:
980 | UnitSystem
981 | """
982 | return scriptcontext.doc.GetUnitSystemName(model_units, capitalize, singular, abbreviate)
983 |
```