This is page 7 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/surface.py:
--------------------------------------------------------------------------------
```python
1 | import math
2 |
3 | import System
4 | from System.Collections.Generic import List
5 |
6 | import Rhino
7 |
8 | import scriptcontext
9 |
10 | import rhinocompat as compat
11 | from rhinoscript import utility as rhutil
12 | from rhinoscript import object as rhobject
13 |
14 |
15 | def AddBox(corners):
16 | """Adds a box shaped polysurface to the document
17 | Parameters:
18 | corners ([point, point, point ,point, point, point ,point,point]) 8 points that define the corners of the box. Points need to
19 | be in counter-clockwise order starting with the bottom rectangle of the box
20 | Returns:
21 | guid: identifier of the new object on success
22 | Example:
23 | import rhinoscriptsyntax as rs
24 | box = rs.GetBox()
25 | if box: rs.AddBox(box)
26 | See Also:
27 | AddCone
28 | AddCylinder
29 | AddSphere
30 | AddTorus
31 | """
32 | box = rhutil.coerce3dpointlist(corners, True)
33 | brep = Rhino.Geometry.Brep.CreateFromBox(box)
34 | if not brep: raise ValueError("unable to create brep from box")
35 | rc = scriptcontext.doc.Objects.AddBrep(brep)
36 | if rc==System.Guid.Empty: raise Exception("unable to add brep to document")
37 | scriptcontext.doc.Views.Redraw()
38 | return rc
39 |
40 |
41 | def AddCone(base, height, radius, cap=True):
42 | """Adds a cone shaped polysurface to the document
43 | Parameters:
44 | base (point|plane): 3D origin point of the cone or a plane with an apex at the origin
45 | and normal along the plane's z-axis
46 | height (point|number): 3D height point of the cone if base is a 3D point. The height
47 | point defines the height and direction of the cone. If base is a
48 | plane, height is a numeric value
49 | radius (number): the radius at the base of the cone
50 | cap (bool, optional): cap base of the cone
51 | Returns:
52 | guid: identifier of the new object on success
53 | Example:
54 | import rhinoscriptsyntax as rs
55 | radius = 5.0
56 | base = rs.GetPoint("Base of cone")
57 | if base:
58 | height = rs.GetPoint("Height of cone", base)
59 | if height: rs.AddCone(base, height, radius)
60 | See Also:
61 | AddBox
62 | AddCylinder
63 | AddSphere
64 | AddTorus
65 | """
66 | plane = None
67 | height_point = rhutil.coerce3dpoint(height)
68 | if height_point is None:
69 | plane = rhutil.coerceplane(base, True)
70 | else:
71 | base_point = rhutil.coerce3dpoint(base, True)
72 | normal = base_point - height_point
73 | height = normal.Length
74 | plane = Rhino.Geometry.Plane(height_point, normal)
75 | cone = Rhino.Geometry.Cone(plane, height, radius)
76 | brep = Rhino.Geometry.Brep.CreateFromCone(cone, cap)
77 | rc = scriptcontext.doc.Objects.AddBrep(brep)
78 | scriptcontext.doc.Views.Redraw()
79 | return rc
80 |
81 |
82 | def AddCutPlane(object_ids, start_point, end_point, normal=None):
83 | """Adds a planar surface through objects at a designated location. For more
84 | information, see the Rhino help file for the CutPlane command
85 | Parameters:
86 | objects_ids ([guid, ...]): identifiers of objects that the cutting plane will
87 | pass through
88 | start_point, end_point (line): line that defines the cutting plane
89 | normal (vector, optional): vector that will be contained in the returned planar
90 | surface. In the case of Rhino's CutPlane command, this is the
91 | normal to, or Z axis of, the active view's construction plane.
92 | If omitted, the world Z axis is used
93 | Returns:
94 | guid: identifier of new object on success
95 | None: on error
96 | Example:
97 | import rhinoscriptsyntax as rs
98 | objs = rs.GetObjects("Select objects for cut plane")
99 | if objs:
100 | point0 = rs.GetPoint("Start of cut plane")
101 | if point0:
102 | point1 = rs.GetPoint("End of cut plane", point0)
103 | if point1: rs.AddCutPlane( objs, point0, point1 )
104 | See Also:
105 | AddPlaneSurface
106 | """
107 | objects = []
108 | for id in object_ids:
109 | rhobj = rhutil.coercerhinoobject(id, True, True)
110 | objects.append(rhobj)
111 |
112 | rc, bbox = Rhino.DocObjects.RhinoObject.GetTightBoundingBox(objects)
113 | if not bbox.IsValid:
114 | return scriptcontext.errorhandler()
115 |
116 | bbox_min = bbox.Min
117 | bbox_max = bbox.Max
118 | for i in range(0, 3):
119 | if (System.Math.Abs(bbox_min[i] - bbox_max[i]) < Rhino.RhinoMath.SqrtEpsilon):
120 | bbox_min[i] = bbox_min[i] - 1.0
121 | bbox_max[i] = bbox_max[i] + 1.0
122 |
123 | v = bbox_max - bbox_min
124 | v = v * 1.1
125 | p = bbox_min + v
126 | bbox_min = bbox_max - v
127 | bbox_max = p
128 | bbox = Rhino.Geometry.BoundingBox(bbox_min, bbox_max)
129 |
130 | start_point = rhutil.coerce3dpoint(start_point, True)
131 | end_point = rhutil.coerce3dpoint(end_point, True)
132 | line = Rhino.Geometry.Line(start_point, end_point)
133 | if normal:
134 | normal = rhutil.coerce3dvector(normal, True)
135 | else:
136 | normal = scriptcontext.doc.Views.ActiveView.ActiveViewport.ConstructionPlane().Normal
137 |
138 | surface = Rhino.Geometry.PlaneSurface.CreateThroughBox(line, normal, bbox)
139 | if surface is None: return scriptcontext.errorhandler()
140 | id = scriptcontext.doc.Objects.AddSurface(surface)
141 | if id==System.Guid.Empty: return scriptcontext.errorhandler()
142 | scriptcontext.doc.Views.Redraw()
143 | return id
144 |
145 |
146 | def AddCylinder(base, height, radius, cap=True):
147 | """Adds a cylinder-shaped polysurface to the document
148 | Parameters:
149 | base (point|plane): The 3D base point of the cylinder or the base plane of the cylinder
150 | height (point|number): if base is a point, then height is a 3D height point of the
151 | cylinder. The height point defines the height and direction of the
152 | cylinder. If base is a plane, then height is the numeric height value
153 | of the cylinder
154 | radius (number): radius of the cylinder
155 | cap (bool, optional): cap the cylinder
156 | Returns:
157 | guid: identifier of new object if successful
158 | None: on error
159 | Example:
160 | import rhinoscriptsyntax as rs
161 | radius = 5.0
162 | base = rs.GetPoint("Base of cylinder")
163 | if base:
164 | height = rs.GetPoint("Height of cylinder", base)
165 | if height: rs.AddCylinder( base, height, radius )
166 | See Also:
167 | AddBox
168 | AddCone
169 | AddSphere
170 | AddTorus
171 | """
172 | cylinder=None
173 | height_point = rhutil.coerce3dpoint(height)
174 | if height_point:
175 | #base must be a point
176 | base = rhutil.coerce3dpoint(base, True)
177 | normal = height_point-base
178 | plane = Rhino.Geometry.Plane(base, normal)
179 | height = normal.Length
180 | circle = Rhino.Geometry.Circle(plane, radius)
181 | cylinder = Rhino.Geometry.Cylinder(circle, height)
182 | else:
183 | #base must be a plane
184 | if type(base) is Rhino.Geometry.Point3d: base = [base.X, base.Y, base.Z]
185 | base = rhutil.coerceplane(base, True)
186 | circle = Rhino.Geometry.Circle(base, radius)
187 | cylinder = Rhino.Geometry.Cylinder(circle, height)
188 | brep = cylinder.ToBrep(cap, cap)
189 | id = scriptcontext.doc.Objects.AddBrep(brep)
190 | if id==System.Guid.Empty: return scriptcontext.errorhandler()
191 | scriptcontext.doc.Views.Redraw()
192 | return id
193 |
194 |
195 | def AddEdgeSrf(curve_ids):
196 | """Creates a surface from 2, 3, or 4 edge curves
197 | Parameters:
198 | curve_ids ([guid, ...]): list or tuple of curves
199 | Returns:
200 | guid: identifier of new object if successful
201 | None: on error
202 | Example:
203 | import rhinoscriptsyntax as rs
204 | curves = rs.GetObjects("Select 2, 3, or 4 curves", rs.filter.curve)
205 | if curves and len(curves)>1 ): rs.AddEdgeSrf(curves)
206 | See Also:
207 | AddPlanarSrf
208 | AddSrfControlPtGrid
209 | AddSrfPt
210 | AddSrfPtGrid
211 | """
212 | curves = [rhutil.coercecurve(id, -1, True) for id in curve_ids]
213 | brep = Rhino.Geometry.Brep.CreateEdgeSurface(curves)
214 | if brep is None: return scriptcontext.errorhandler()
215 | id = scriptcontext.doc.Objects.AddBrep(brep)
216 | if id==System.Guid.Empty: return scriptcontext.errorhandler()
217 | scriptcontext.doc.Views.Redraw()
218 | return id
219 |
220 |
221 | def AddNetworkSrf(curves, continuity=1, edge_tolerance=0, interior_tolerance=0, angle_tolerance=0):
222 | """Creates a surface from a network of crossing curves
223 | Parameters:
224 | curves ([guid, ...]): curves from which to create the surface
225 | continuity (number, optional): how the edges match the input geometry
226 | 0 = loose
227 | 1 = position
228 | 2 = tangency
229 | 3 = curvature
230 | Returns:
231 | guid: identifier of new object if successful
232 | Example:
233 | import rhinoscriptsyntax as rs
234 | curve_ids = rs.GetObjects("Select curves in network", 4, True, True)
235 | if len(curve_ids) > 0:
236 | rs.AddNetworkSrf(curve_ids)
237 | See Also:
238 |
239 | """
240 | curves = [rhutil.coercecurve(curve, -1, True) for curve in curves]
241 | surf, err = Rhino.Geometry.NurbsSurface.CreateNetworkSurface(curves, continuity, edge_tolerance, interior_tolerance, angle_tolerance)
242 | if surf:
243 | rc = scriptcontext.doc.Objects.AddSurface(surf)
244 | scriptcontext.doc.Views.Redraw()
245 | return rc
246 |
247 |
248 | def AddNurbsSurface(point_count, points, knots_u, knots_v, degree, weights=None):
249 | """Adds a NURBS surface object to the document
250 | Parameters:
251 | point_count ([number, number]) number of control points in the u and v direction
252 | points ({point, ...]): list of 3D points
253 | knots_u ([number, ...]): knot values for the surface in the u direction.
254 | Must contain point_count[0]+degree[0]-1 elements
255 | knots_v ([number, ...]): knot values for the surface in the v direction.
256 | Must contain point_count[1]+degree[1]-1 elements
257 | degree ([number, number]): degree of the surface in the u and v directions.
258 | weights [(number, ...]): weight values for the surface. The number of elements in
259 | weights must equal the number of elements in points. Values must be
260 | greater than zero.
261 | Returns:
262 | guid: identifier of new object if successful
263 | None on error
264 | Example:
265 | import rhinoscriptsyntax as rs
266 | obj = rs.GetObject("Pick a surface", rs.filter.surface)
267 | if obj:
268 | point_count = rs.SurfacePointCount(obj)
269 | points = rs.SurfacePoints(obj)
270 | knots = rs.SurfaceKnots(obj)
271 | degree = rs.SurfaceDegree(obj)
272 | if rs.IsSurfaceRational(obj):
273 | weights = rs.SurfaceWeights(obj)
274 | obj = rs.AddNurbsSurface(point_count, points, knots[0], knots[1], degree, weights)
275 | else:
276 | obj = rs.AddNurbsSurface(point_count, points, knots[0], knots[1], degree)
277 | if obj: rs.SelectObject(obj)
278 | See Also:
279 | IsSurfaceRational
280 | SurfaceDegree
281 | SurfaceKnotCount
282 | SurfaceKnots
283 | SurfacePointCount
284 | SurfacePoints
285 | SurfaceWeights
286 | """
287 | if len(points)<(point_count[0]*point_count[1]):
288 | return scriptcontext.errorhandler()
289 | ns = Rhino.Geometry.NurbsSurface.Create(3, weights!=None, degree[0]+1, degree[1]+1, point_count[0], point_count[1])
290 | #add the points and weights
291 | controlpoints = ns.Points
292 | index = 0
293 | for i in range(point_count[0]):
294 | for j in range(point_count[1]):
295 | if weights:
296 | cp = Rhino.Geometry.ControlPoint(points[index], weights[index])
297 | controlpoints.SetControlPoint(i,j,cp)
298 | else:
299 | cp = Rhino.Geometry.ControlPoint(points[index])
300 | controlpoints.SetControlPoint(i,j,cp)
301 | index += 1
302 | #add the knots
303 | for i in range(ns.KnotsU.Count): ns.KnotsU[i] = knots_u[i]
304 | for i in range(ns.KnotsV.Count): ns.KnotsV[i] = knots_v[i]
305 | if not ns.IsValid: return scriptcontext.errorhandler()
306 | id = scriptcontext.doc.Objects.AddSurface(ns)
307 | if id==System.Guid.Empty: return scriptcontext.errorhandler()
308 | scriptcontext.doc.Views.Redraw()
309 | return id
310 |
311 |
312 | def AddPatch(object_ids, uv_spans_tuple_OR_surface_object_id, tolerance=None, trim=True, point_spacing=0.1, flexibility=1.0, surface_pull=1.0, fix_edges=False):
313 | """Fits a surface through curve, point, point cloud, and mesh objects.
314 | Parameters:
315 | object_ids ({guid, ...]): a list of object identifiers that indicate the objects to use for the patch fitting.
316 | Acceptable object types include curves, points, point clouds, and meshes.
317 | uv_spans_tuple_OR_surface_object_id ([number, number]|guid): the U and V direction span counts for the automatically generated surface OR
318 | The identifier of the starting surface. It is best if you create a starting surface that is similar in shape
319 | to the surface you are trying to create.
320 | tolerance (number, optional): The tolerance used by input analysis functions. If omitted, Rhino's document absolute tolerance is used.
321 | trim (bool, optional): Try to find an outside curve and trims the surface to it. The default value is True.
322 | point_spacing (number, optional): The basic distance between points sampled from input curves. The default value is 0.1.
323 | flexibility (number, optional): Determines the behavior of the surface in areas where its not otherwise controlled by the input.
324 | Lower numbers make the surface behave more like a stiff material, higher, more like a flexible material.
325 | That is, each span is made to more closely match the spans adjacent to it if there is no input geometry
326 | mapping to that area of the surface when the flexibility value is low. The scale is logarithmic.
327 | For example, numbers around 0.001 or 0.1 make the patch pretty stiff and numbers around 10 or 100
328 | make the surface flexible. The default value is 1.0.
329 | surface_pull (number, optional): Similar to stiffness, but applies to the starting surface. The bigger the pull, the closer
330 | the resulting surface shape will be to the starting surface. The default value is 1.0.
331 | fix_edges (bool, optional): Clamps the edges of the starting surface in place. This option is useful if you are using a
332 | curve or points for deforming an existing surface, and you do not want the edges of the starting surface
333 | to move. The default if False.
334 | Returns:
335 | guid: Identifier of the new surface object if successful.
336 | None: on error.
337 | Example:
338 | See Also:
339 | """
340 | # System.Collections.List instead of Python list because IronPython is
341 | # having problems converting a list to an IEnumerable<GeometryBase> which
342 | # is the 1st argument for Brep.CreatePatch
343 | geometry = List[Rhino.Geometry.GeometryBase]()
344 | u_span = 10
345 | v_span = 10
346 | rc = None
347 | id = rhutil.coerceguid(object_ids, False)
348 | if id: object_ids = [id]
349 | for object_id in object_ids:
350 | rhobj = rhutil.coercerhinoobject(object_id, False, False)
351 | if not rhobj: return None
352 | geometry.Add( rhobj.Geometry )
353 | if not geometry: return None
354 |
355 | surface = None
356 | if uv_spans_tuple_OR_surface_object_id:
357 | if type(uv_spans_tuple_OR_surface_object_id) is tuple:
358 | u_span = uv_spans_tuple_OR_surface_object_id[0]
359 | v_span = uv_spans_tuple_OR_surface_object_id[1]
360 | else:
361 | surface = rhutil.coercesurface(uv_spans_tuple_OR_surface_object_id, False)
362 |
363 | if not tolerance: tolerance = scriptcontext.doc.ModelAbsoluteTolerance
364 | b = System.Array.CreateInstance(bool, 4)
365 | for i in range(4): b[i] = fix_edges
366 | brep = Rhino.Geometry.Brep.CreatePatch(geometry, surface, u_span, v_span, trim, False, point_spacing, flexibility, surface_pull, b, tolerance)
367 | if brep:
368 | rc = scriptcontext.doc.Objects.AddBrep(brep)
369 | scriptcontext.doc.Views.Redraw()
370 | return rc
371 |
372 |
373 | def AddPipe(curve_id, parameters, radii, blend_type=0, cap=0, fit=False):
374 | """Creates a single walled surface with a circular profile around a curve
375 | Parameters:
376 | curve_id (guid): identifier of rail curve
377 | parameters, radii ([number, ...]): list of radius values at normalized curve parameters
378 | blend_type (number, optional): 0(local) or 1(global)
379 | cap (number, optional): 0(none), 1(flat), 2(round)
380 | fit (bool, optional): attempt to fit a single surface
381 | Returns:
382 | list(guid, ...): identifiers of new objects created
383 | Example:
384 | import rhinoscriptsyntax as rs
385 | curve = rs.GetObject("Select curve to create pipe around", rs.filter.curve, True)
386 | if curve:
387 | domain = rs.CurveDomain(curve)
388 | rs.AddPipe(curve, 0, 4)
389 | See Also:
390 |
391 | """
392 | rail = rhutil.coercecurve(curve_id, -1, True)
393 | abs_tol = scriptcontext.doc.ModelAbsoluteTolerance
394 | ang_tol = scriptcontext.doc.ModelAngleToleranceRadians
395 | if type(parameters) is int or type(parameters) is float: parameters = [parameters]
396 | if type(radii) is int or type(radii) is float: radii = [radii]
397 | parameters = compat.ITERATOR2LIST(map(float,parameters))
398 | radii = compat.ITERATOR2LIST(map(float,radii))
399 | cap = System.Enum.ToObject(Rhino.Geometry.PipeCapMode, cap)
400 | breps = Rhino.Geometry.Brep.CreatePipe(rail, parameters, radii, blend_type==0, cap, fit, abs_tol, ang_tol)
401 | rc = [scriptcontext.doc.Objects.AddBrep(brep) for brep in breps]
402 | scriptcontext.doc.Views.Redraw()
403 | return rc
404 |
405 |
406 | def AddPlanarSrf(object_ids):
407 | """Creates one or more surfaces from planar curves
408 | Parameters:
409 | object_ids ({guid, ...]): curves to use for creating planar surfaces
410 | Returns:
411 | list(guid, ...): identifiers of surfaces created on success
412 | None: on error
413 | Example:
414 | import rhinoscriptsyntax as rs
415 | objs = rs.GetObjects("Select planar curves to build surface", rs.filter.curve)
416 | if objs: rs.AddPlanarSrf(objs)
417 | See Also:
418 | AddEdgeSrf
419 | AddSrfControlPtGrid
420 | AddSrfPt
421 | AddSrfPtGrid
422 | """
423 | id = rhutil.coerceguid(object_ids, False)
424 | if id: object_ids = [id]
425 | curves = [rhutil.coercecurve(id,-1,True) for id in object_ids]
426 | tolerance = scriptcontext.doc.ModelAbsoluteTolerance
427 | breps = Rhino.Geometry.Brep.CreatePlanarBreps(curves, tolerance)
428 | if breps:
429 | rc = [scriptcontext.doc.Objects.AddBrep(brep) for brep in breps]
430 | scriptcontext.doc.Views.Redraw()
431 | return rc
432 |
433 |
434 | def AddPlaneSurface(plane, u_dir, v_dir):
435 | """Create a plane surface and add it to the document.
436 | Parameters:
437 | plane (plane): The plane.
438 | u_dir (number): The magnitude in the U direction.
439 | v_dir (number): The magnitude in the V direction.
440 | Returns:
441 | guid: The identifier of the new object if successful.
442 | None: if not successful, or on error.
443 | Example:
444 | import rhinoscriptsyntax as rs
445 | rs.AddPlaneSurface( rs.WorldXYPlane(), 5.0, 3.0 )
446 | See Also:
447 | AddCutPlane
448 | AddEdgeSrf
449 | AddSrfControlPtGrid
450 | AddSrfPt
451 | AddSrfPtGrid
452 | IsPlaneSurface
453 | """
454 | plane = rhutil.coerceplane(plane, True)
455 | u_interval = Rhino.Geometry.Interval(0, u_dir)
456 | v_interval = Rhino.Geometry.Interval(0, v_dir)
457 | plane_surface = Rhino.Geometry.PlaneSurface(plane, u_interval, v_interval)
458 | if plane_surface is None: return scriptcontext.errorhandler()
459 | rc = scriptcontext.doc.Objects.AddSurface(plane_surface)
460 | if rc==System.Guid.Empty: return scriptcontext.errorhandler()
461 | scriptcontext.doc.Views.Redraw()
462 | return rc
463 |
464 |
465 | def AddLoftSrf(object_ids, start=None, end=None, loft_type=0, simplify_method=0, value=0, closed=False):
466 | """Adds a surface created by lofting curves to the document.
467 | - no curve sorting performed. pass in curves in the order you want them sorted
468 | - directions of open curves not adjusted. Use CurveDirectionsMatch and
469 | ReverseCurve to adjust the directions of open curves
470 | - seams of closed curves are not adjusted. Use CurveSeam to adjust the seam
471 | of closed curves
472 | Parameters:
473 | object_ids ({guid, guid, ...]): ordered list of the curves to loft through
474 | start (point, optional): starting point of the loft
475 | end (point, optional): ending point of the loft
476 | loft_type (number, optional): type of loft. Possible options are:
477 | 0 = Normal. Uses chord-length parameterization in the loft direction
478 | 1 = Loose. The surface is allowed to move away from the original curves
479 | to make a smoother surface. The surface control points are created
480 | at the same locations as the control points of the loft input curves.
481 | 2 = Straight. The sections between the curves are straight. This is
482 | also known as a ruled surface.
483 | 3 = Tight. The surface sticks closely to the original curves. Uses square
484 | root of chord-length parameterization in the loft direction
485 | 4 = Developable. Creates a separate developable surface or polysurface
486 | from each pair of curves.
487 | simplify_method (number, optional): Possible options are:
488 | 0 = None. Does not simplify.
489 | 1 = Rebuild. Rebuilds the shape curves before lofting. modified by `value` below
490 | 2 = Refit. Refits the shape curves to a specified tolerance. modified by `value` below
491 | value (number, optional): Additional value based on the specified `simplify_method`:
492 | Simplify - Description
493 | Rebuild(1) - then value is the number of control point used to rebuild
494 | Rebuild(1) - is specified and this argument is omitted, then curves will be
495 | rebuilt using 10 control points.
496 | Refit(2) - then value is the tolerance used to rebuild.
497 | Refit(2) - is specified and this argument is omitted, then the document's
498 | absolute tolerance us used for refitting.
499 | closed (bool, optional): close the loft back to the first curve
500 | Returns:
501 | list(guid, ...):Array containing the identifiers of the new surface objects if successful
502 | None: on error
503 | Example:
504 | import rhinoscriptsyntax as rs
505 | objs = rs.GetObjects("Pick curves to loft", rs.filter.curve)
506 | if objs: rs.AddLoftSrf(objs)
507 | See Also:
508 | CurveDirectionsMatch
509 | CurveSeam
510 | ReverseCurve
511 | """
512 | if loft_type<0 or loft_type>5: raise ValueError("loft_type must be 0-4")
513 | if simplify_method<0 or simplify_method>2: raise ValueError("simplify_method must be 0-2")
514 |
515 | # get set of curves from object_ids
516 | curves = [rhutil.coercecurve(id,-1,True) for id in object_ids]
517 | if len(curves)<2: return scriptcontext.errorhandler()
518 | if start is None: start = Rhino.Geometry.Point3d.Unset
519 | if end is None: end = Rhino.Geometry.Point3d.Unset
520 | start = rhutil.coerce3dpoint(start, True)
521 | end = rhutil.coerce3dpoint(end, True)
522 |
523 | lt = Rhino.Geometry.LoftType.Normal
524 | if loft_type==1: lt = Rhino.Geometry.LoftType.Loose
525 | elif loft_type==2: lt = Rhino.Geometry.LoftType.Straight
526 | elif loft_type==3: lt = Rhino.Geometry.LoftType.Tight
527 | elif loft_type==4: lt = Rhino.Geometry.LoftType.Developable
528 |
529 | breps = None
530 | if simplify_method==0:
531 | breps = Rhino.Geometry.Brep.CreateFromLoft(curves, start, end, lt, closed)
532 | elif simplify_method==1:
533 | value = abs(value)
534 | rebuild_count = int(value)
535 | breps = Rhino.Geometry.Brep.CreateFromLoftRebuild(curves, start, end, lt, closed, rebuild_count)
536 | elif simplify_method==2:
537 | refit = abs(value)
538 | if refit==0: refit = scriptcontext.doc.ModelAbsoluteTolerance
539 | breps = Rhino.Geometry.Brep.CreateFromLoftRefit(curves, start, end, lt, closed, refit)
540 | if not breps: return scriptcontext.errorhandler()
541 |
542 | idlist = []
543 | for brep in breps:
544 | id = scriptcontext.doc.Objects.AddBrep(brep)
545 | if id!=System.Guid.Empty: idlist.append(id)
546 | if idlist: scriptcontext.doc.Views.Redraw()
547 | return idlist
548 |
549 |
550 | def AddRevSrf(curve_id, axis, start_angle=0.0, end_angle=360.0):
551 | """Create a surface by revolving a curve around an axis
552 | Parameters:
553 | curve_id (guid): identifier of profile curve
554 | axis (line): line for the rail revolve axis
555 | start_angle, end_angle (number, optional): start and end angles of revolve
556 | Returns:
557 | guid: identifier of new object if successful
558 | None: on error
559 | Example:
560 | import rhinoscriptsyntax as rs
561 | curve = rs.AddLine((5,0,0), (10,0,10))
562 | rs.AddRevSrf( curve, ((0,0,0), (0,0,1)) )
563 | See Also:
564 |
565 | """
566 | curve = rhutil.coercecurve(curve_id, -1, True)
567 | axis = rhutil.coerceline(axis, True)
568 | start_angle = math.radians(start_angle)
569 | end_angle = math.radians(end_angle)
570 | srf = Rhino.Geometry.RevSurface.Create(curve, axis, start_angle, end_angle)
571 | if not srf: return scriptcontext.errorhandler()
572 | ns = srf.ToNurbsSurface()
573 | if not ns: return scriptcontext.errorhandler()
574 | rc = scriptcontext.doc.Objects.AddSurface(ns)
575 | scriptcontext.doc.Views.Redraw()
576 | return rc
577 |
578 |
579 | def AddSphere(center_or_plane, radius):
580 | """Add a spherical surface to the document
581 | Parameters:
582 | center_or_plane (point|plane): center point of the sphere. If a plane is input,
583 | the origin of the plane will be the center of the sphere
584 | radius (number): radius of the sphere in the current model units
585 | Returns:
586 | guid: identifier of the new object on success
587 | None: on error
588 | Example:
589 | import rhinoscriptsyntax as rs
590 | radius = 2
591 | center = rs.GetPoint("Center of sphere")
592 | if center: rs.AddSphere(center, radius)
593 | See Also:
594 | AddBox
595 | AddCone
596 | AddCylinder
597 | AddTorus
598 | """
599 | c_or_p = rhutil.coerce3dpoint(center_or_plane)
600 | if c_or_p is None:
601 | c_or_p = rhutil.coerceplane(center_or_plane)
602 | if c_or_p is None: return None
603 | sphere = Rhino.Geometry.Sphere(c_or_p, radius)
604 | rc = scriptcontext.doc.Objects.AddSphere(sphere)
605 | if rc==System.Guid.Empty: return scriptcontext.errorhandler()
606 | scriptcontext.doc.Views.Redraw()
607 | return rc
608 |
609 |
610 | def AddSrfContourCrvs(object_id, points_or_plane, interval=None):
611 | """Adds a spaced series of planar curves resulting from the intersection of
612 | defined cutting planes through a surface or polysurface. For more
613 | information, see Rhino help for details on the Contour command
614 | Parameters:
615 | object_id (guid): object identifier to contour
616 | points_or_plane ([point,point]|plane): either a list/tuple of two points or a plane
617 | if two points, they define the start and end points of a center line
618 | if a plane, the plane defines the cutting plane
619 | interval (number, optional): distance between contour curves.
620 | Returns:
621 | guid: ids of new contour curves on success
622 | None: on error
623 | Example:
624 | import rhinoscriptsyntax as rs
625 | obj = rs.GetObject("Select object", rs.filter.surface + rs.filter.polysurface)
626 | startpoint = rs.GetPoint("Base point of center line")
627 | endpoint = rs.GetPoint("Endpoint of center line", startpoint)
628 | rs.AddSrfContourCrvs( obj, (startpoint, endpoint) )
629 | See Also:
630 | CurveContourPoints
631 | """
632 | brep = rhutil.coercebrep(object_id)
633 | plane = rhutil.coerceplane(points_or_plane)
634 | curves = None
635 | if plane:
636 | curves = Rhino.Geometry.Brep.CreateContourCurves(brep, plane)
637 | else:
638 | start = rhutil.coerce3dpoint(points_or_plane[0], True)
639 | end = rhutil.coerce3dpoint(points_or_plane[1], True)
640 | if not interval:
641 | bbox = brep.GetBoundingBox(True)
642 | v = bbox.Max - bbox.Min
643 | interval = v.Length / 50.0
644 | curves = Rhino.Geometry.Brep.CreateContourCurves(brep, start, end, interval)
645 | rc = []
646 | for crv in curves:
647 | id = scriptcontext.doc.Objects.AddCurve(crv)
648 | if id!=System.Guid.Empty: rc.append(id)
649 | scriptcontext.doc.Views.Redraw()
650 | return rc
651 |
652 |
653 | def AddSrfControlPtGrid(count, points, degree=(3,3)):
654 | """Creates a surface from a grid of points
655 | Parameters:
656 | count ([number, number])tuple of two numbers defining number of points in the u,v directions
657 | points ([point, ...]): list of 3D points
658 | degree ([number, number]): two numbers defining degree of the surface in the u,v directions
659 | Returns:
660 | guid: The identifier of the new object if successful.
661 | None: if not successful, or on error.
662 | Example:
663 | See Also:
664 | """
665 | points = rhutil.coerce3dpointlist(points, True)
666 | surf = Rhino.Geometry.NurbsSurface.CreateFromPoints(points, count[0], count[1], degree[0], degree[1])
667 | if not surf: return scriptcontext.errorhandler()
668 | id = scriptcontext.doc.Objects.AddSurface(surf)
669 | if id!=System.Guid.Empty:
670 | scriptcontext.doc.Views.Redraw()
671 | return id
672 |
673 |
674 | def AddSrfPt(points):
675 | """Creates a new surface from either 3 or 4 corner points.
676 | Parameters:
677 | points ([point, point, point, point]): list of either 3 or 4 corner points
678 | Returns:
679 | guid: The identifier of the new object if successful.
680 | None: if not successful, or on error.
681 | Example:
682 | import rhinoscriptsyntax as rs
683 | points = rs.GetPoints(True, message1="Pick 3 or 4 corner points")
684 | if points: rs.AddSrfPt(points)
685 | See Also:
686 | AddEdgeSrf
687 | AddSrfControlPtGrid
688 | AddSrfPtGrid
689 | """
690 | points = rhutil.coerce3dpointlist(points, True)
691 | surface=None
692 | if len(points)==3:
693 | surface = Rhino.Geometry.NurbsSurface.CreateFromCorners(points[0], points[1], points[2])
694 | elif len(points)==4:
695 | surface = Rhino.Geometry.NurbsSurface.CreateFromCorners(points[0], points[1], points[2], points[3])
696 | if surface is None: return scriptcontext.errorhandler()
697 | rc = scriptcontext.doc.Objects.AddSurface(surface)
698 | if rc==System.Guid.Empty: return scriptcontext.errorhandler()
699 | scriptcontext.doc.Views.Redraw()
700 | return rc
701 |
702 |
703 | def AddSrfPtGrid(count, points, degree=(3,3), closed=(False,False)):
704 | """Creates a surface from a grid of points
705 | Parameters:
706 | count ([number, number}): tuple of two numbers defining number of points in the u,v directions
707 | points ([point, ...]): list of 3D points
708 | degree ([number, number], optional): two numbers defining degree of the surface in the u,v directions
709 | closed ([bool, bool], optional): two booleans defining if the surface is closed in the u,v directions
710 | Returns:
711 | guid: The identifier of the new object if successful.
712 | None: if not successful, or on error.
713 | Example:
714 | See Also:
715 | """
716 | points = rhutil.coerce3dpointlist(points, True)
717 | surf = Rhino.Geometry.NurbsSurface.CreateThroughPoints(points, count[0], count[1], degree[0], degree[1], closed[0], closed[1])
718 | if not surf: return scriptcontext.errorhandler()
719 | id = scriptcontext.doc.Objects.AddSurface(surf)
720 | if id!=System.Guid.Empty:
721 | scriptcontext.doc.Views.Redraw()
722 | return id
723 |
724 |
725 | def AddSweep1(rail, shapes, closed=False):
726 | """Adds a surface created through profile curves that define the surface
727 | shape and one curve that defines a surface edge.
728 | Parameters:
729 | rail (guid): identifier of the rail curve
730 | shapes ([guid, ...]): one or more cross section shape curves
731 | closed (bool, optional): If True, then create a closed surface
732 | Returns:
733 | list(guid, ...): of new surface objects if successful
734 | None: if not successful, or on error
735 | Example:
736 | import rhinoscriptsyntax as rs
737 | rail = rs.GetObject("Select rail curve", rs.filter.curve)
738 | if rail:
739 | shapes = rs.GetObjects("Select cross-section curves", rs.filter.curve)
740 | if shapes: rs.AddSweep1( rail, shapes )
741 | See Also:
742 | AddSweep2
743 | CurveDirectionsMatch
744 | ReverseCurve
745 | """
746 | rail = rhutil.coercecurve(rail, -1, True)
747 | shapes = [rhutil.coercecurve(shape, -1, True) for shape in shapes]
748 | tolerance = scriptcontext.doc.ModelAbsoluteTolerance
749 | breps = Rhino.Geometry.Brep.CreateFromSweep(rail, shapes, closed, tolerance)
750 | if not breps: return scriptcontext.errorhandler()
751 | rc = [scriptcontext.doc.Objects.AddBrep(brep) for brep in breps]
752 | scriptcontext.doc.Views.Redraw()
753 | return rc
754 |
755 |
756 | def AddSweep2(rails, shapes, closed=False):
757 | """Adds a surface created through profile curves that define the surface
758 | shape and two curves that defines a surface edge.
759 | Parameters:
760 | rails ([guid, guid]): identifiers of the two rail curve
761 | shapes ([guid, ...]): one or more cross section shape curves
762 | closed (bool, optional): If True, then create a closed surface
763 | Returns:
764 | list(guid, ...): of new surface objects if successful
765 | None: if not successful, or on error
766 | Example:
767 | import rhinoscriptsyntax as rs
768 | rails = rs.GetObjects("Select two rail curve", rs.filter.curve)
769 | if rails and len(rails)==2:
770 | shapes = rs.GetObjects("Select cross-section curves", rs.filter.curve)
771 | if shapes: rs.AddSweep2(rails, shapes)
772 | See Also:
773 | AddSweep1
774 | CurveDirectionsMatch
775 | ReverseCurve
776 | """
777 | rail1 = rhutil.coercecurve(rails[0], -1, True)
778 | rail2 = rhutil.coercecurve(rails[1], -1, True)
779 | shapes = [rhutil.coercecurve(shape, -1, True) for shape in shapes]
780 | tolerance = scriptcontext.doc.ModelAbsoluteTolerance
781 | breps = Rhino.Geometry.Brep.CreateFromSweep(rail1, rail2, shapes, closed, tolerance)
782 | if not breps: return scriptcontext.errorhandler()
783 | rc = [scriptcontext.doc.Objects.AddBrep(brep) for brep in breps]
784 | scriptcontext.doc.Views.Redraw()
785 | return rc
786 |
787 |
788 | def AddRailRevSrf(profile, rail, axis, scale_height=False):
789 | """Adds a surface created through profile curves that define the surface
790 | shape and two curves that defines a surface edge.
791 | Parameters:
792 | profile (guid): identifier of the profile curve
793 | rail (guid): identifier of the rail curve
794 | axis ([point, point]): A list of two 3-D points identifying the start point and end point of the rail revolve axis, or a Line
795 | scale_height (bool, optional): If True, surface will be locally scaled. Defaults to False
796 | Returns:
797 | guid: identifier of the new object if successful
798 | None: if not successful, or on error
799 | Example:
800 | import rhinoscriptsyntax as rs
801 | profile = rs.GetObject("Select a profile", rs.filter.curve)
802 | if profile:
803 | rail = rs.GetObject("Select a rail", rs.filter.curve)
804 | if rail:
805 | rs.AddRailRevSrf(profile, rail, ((0,0,0),(0,0,1)))
806 | See Also:
807 | AddSweep1
808 | CurveDirectionsMatch
809 | ReverseCurve
810 | """
811 | profile_inst = rhutil.coercecurve(profile, -1, True)
812 | rail_inst = rhutil.coercecurve(rail, -1, True)
813 | axis_start = rhutil.coerce3dpoint(axis[0], True)
814 | axis_end = rhutil.coerce3dpoint(axis[1], True)
815 |
816 | line = Rhino.Geometry.Line(axis_start, axis_end)
817 | surface = Rhino.Geometry.NurbsSurface.CreateRailRevolvedSurface(profile_inst, rail_inst, line, scale_height)
818 |
819 | if not surface: return scriptcontext.errorhandler()
820 | rc = scriptcontext.doc.Objects.AddSurface(surface)
821 | scriptcontext.doc.Views.Redraw()
822 | return rc
823 |
824 |
825 | def AddTorus(base, major_radius, minor_radius, direction=None):
826 | """Adds a torus shaped revolved surface to the document
827 | Parameters:
828 | base (point): 3D origin point of the torus or the base plane of the torus
829 | major_radius, minor_radius (number): the two radii of the torus
830 | directions (point): A point that defines the direction of the torus when base is a point.
831 | If omitted, a torus that is parallel to the world XY plane is created
832 | Returns:
833 | guid: The identifier of the new object if successful.
834 | None: if not successful, or on error.
835 | Example:
836 | import rhinoscriptsyntax as rs
837 | major_radius = 5.0
838 | minor_radius = major_radius - 2.0
839 | base = rs.GetPoint("Base of torus")
840 | if base:
841 | direction = rs.GetPoint("Direction of torus", base)
842 | if direction:
843 | rs.AddTorus( base, major_radius, minor_radius, direction )
844 | See Also:
845 | AddBox
846 | AddCone
847 | AddCylinder
848 | AddSphere
849 | """
850 | baseplane = None
851 | basepoint = rhutil.coerce3dpoint(base)
852 | if basepoint is None:
853 | baseplane = rhutil.coerceplane(base, True)
854 | if direction!=None: return scriptcontext.errorhandler()
855 | if baseplane is None:
856 | direction = rhutil.coerce3dpoint(direction, False)
857 | if direction: direction = direction-basepoint
858 | else: direction = Rhino.Geometry.Vector3d.ZAxis
859 | baseplane = Rhino.Geometry.Plane(basepoint, direction)
860 | torus = Rhino.Geometry.Torus(baseplane, major_radius, minor_radius)
861 | revsurf = torus.ToRevSurface()
862 | rc = scriptcontext.doc.Objects.AddSurface(revsurf)
863 | scriptcontext.doc.Views.Redraw()
864 | return rc
865 |
866 |
867 | def BooleanDifference(input0, input1, delete_input=True):
868 | """Performs a boolean difference operation on two sets of input surfaces
869 | and polysurfaces. For more details, see the BooleanDifference command in
870 | the Rhino help file
871 | Parameters:
872 | input0 ([guid, ...]): list of surfaces to subtract from
873 | input1 ([guid, ...]): list of surfaces to be subtracted
874 | delete_input (bool, optional): delete all input objects
875 | Returns:
876 | list(guid, ...): of identifiers of newly created objects on success
877 | None: on error
878 | Example:
879 | import rhinoscriptsyntax as rs
880 | filter = rs.filter.surface | rs.filter.polysurface
881 | input0 = rs.GetObjects("Select first set of surfaces or polysurfaces", filter)
882 | if input0:
883 | input1 = rs.GetObjects("Select second set of surfaces or polysurfaces", filter)
884 | if input1: rs.BooleanDifference(input0, input1)
885 | See Also:
886 | BooleanIntersection
887 | BooleanUnion
888 | """
889 | if type(input0) is list or type(input0) is tuple: pass
890 | else: input0 = [input0]
891 |
892 | if type(input1) is list or type(input1) is tuple: pass
893 | else: input1 = [input1]
894 |
895 | breps0 = [rhutil.coercebrep(id, True) for id in input0]
896 | breps1 = [rhutil.coercebrep(id, True) for id in input1]
897 | tolerance = scriptcontext.doc.ModelAbsoluteTolerance
898 | newbreps = Rhino.Geometry.Brep.CreateBooleanDifference(breps0, breps1, tolerance)
899 | if newbreps is None: return scriptcontext.errorhandler()
900 |
901 | rc = [scriptcontext.doc.Objects.AddBrep(brep) for brep in newbreps]
902 | if delete_input:
903 | for id in input0: scriptcontext.doc.Objects.Delete(id, True)
904 | for id in input1: scriptcontext.doc.Objects.Delete(id, True)
905 | scriptcontext.doc.Views.Redraw()
906 | return rc
907 |
908 |
909 | def BooleanIntersection(input0, input1, delete_input=True):
910 | """Performs a boolean intersection operation on two sets of input surfaces
911 | and polysurfaces. For more details, see the BooleanIntersection command in
912 | the Rhino help file
913 | Parameters:
914 | input0 ([guid, ...]): list of surfaces
915 | input1 ([guid, ...]): list of surfaces
916 | delete_input (bool, optional): delete all input objects
917 | Returns:
918 | list(guid, ...): of identifiers of newly created objects on success
919 | None: on error
920 | Example:
921 | import rhinoscriptsyntax as rs
922 | input0 = rs.GetObjects("Select first set of surfaces or polysurfaces", rs.filter.surface | rs.filter.polysurface)
923 | if input0:
924 | input1 = rs.GetObjects("Select second set of surfaces or polysurfaces", rs.filter.surface | rs.filter.polysurface)
925 | if input1: rs.BooleanIntersection( input0, input1 )
926 | See Also:
927 | BooleanDifference
928 | BooleanUnion
929 | """
930 | if type(input0) is list or type(input0) is tuple: pass
931 | else: input0 = [input0]
932 |
933 | if type(input1) is list or type(input1) is tuple: pass
934 | else: input1 = [input1]
935 |
936 | breps0 = [rhutil.coercebrep(id, True) for id in input0]
937 | breps1 = [rhutil.coercebrep(id, True) for id in input1]
938 | tolerance = scriptcontext.doc.ModelAbsoluteTolerance
939 | newbreps = Rhino.Geometry.Brep.CreateBooleanIntersection(breps0, breps1, tolerance)
940 | if newbreps is None: return scriptcontext.errorhandler()
941 | rc = [scriptcontext.doc.Objects.AddBrep(brep) for brep in newbreps]
942 | if delete_input:
943 | for id in input0: scriptcontext.doc.Objects.Delete(id, True)
944 | for id in input1: scriptcontext.doc.Objects.Delete(id, True)
945 | scriptcontext.doc.Views.Redraw()
946 | return rc
947 |
948 |
949 | def BooleanUnion(input, delete_input=True):
950 | """Performs a boolean union operation on a set of input surfaces and
951 | polysurfaces. For more details, see the BooleanUnion command in the
952 | Rhino help file
953 | Parameters:
954 | input ([guid, ...]): list of surfaces to union
955 | delete_input (bool, optional): delete all input objects
956 | Returns:
957 | list(guid, ...): of identifiers of newly created objects on success
958 | None on error
959 | Example:
960 | import rhinoscriptsyntax as rs
961 | input = rs.GetObjects("Select surfaces or polysurfaces to union", rs.filter.surface | rs.filter.polysurface)
962 | if input and len(input)>1: rs.BooleanUnion(input)
963 | See Also:
964 | BooleanDifference
965 | BooleanUnion
966 | """
967 | if len(input)<2: return scriptcontext.errorhandler()
968 | breps = [rhutil.coercebrep(id, True) for id in input]
969 | tolerance = scriptcontext.doc.ModelAbsoluteTolerance
970 | newbreps = Rhino.Geometry.Brep.CreateBooleanUnion(breps, tolerance)
971 | if newbreps is None: return scriptcontext.errorhandler()
972 |
973 | rc = [scriptcontext.doc.Objects.AddBrep(brep) for brep in newbreps]
974 | if delete_input:
975 | for id in input: scriptcontext.doc.Objects.Delete(id, True)
976 | scriptcontext.doc.Views.Redraw()
977 | return rc
978 |
979 |
980 | def BrepClosestPoint(object_id, point):
981 | """Returns the point on a surface or polysurface that is closest to a test
982 | point. This function works on both untrimmed and trimmed surfaces.
983 | Parameters:
984 | object_id (guid): The object's identifier.
985 | point (point): The test, or sampling point.
986 | Returns:
987 | tuple(point, [number, number], [number, number], vector): of closest point information if successful. The list will
988 | contain the following information:
989 | Element Type Description
990 | 0 Point3d The 3-D point at the parameter value of the
991 | closest point.
992 | 1 (U, V) Parameter values of closest point. Note, V
993 | is 0 if the component index type is brep_edge
994 | or brep_vertex.
995 | 2 (type, index) The type and index of the brep component that
996 | contains the closest point. Possible types are
997 | brep_face, brep_edge or brep_vertex.
998 | 3 Vector3d The normal to the brep_face, or the tangent
999 | to the brep_edge.
1000 | None: if not successful, or on error.
1001 | Example:
1002 | import rhinoscriptsyntax as rs
1003 | obj = rs.GetObject("Select a surface", rs.filter.surface)
1004 | if obj:
1005 | point = rs.GetPoint("Pick a test point")
1006 | if point:
1007 | arrCP = rs.BrepClosestPoint(obj, point)
1008 | if arrCP:
1009 | rs.AddPoint(point)
1010 | rs.AddPoint( arrCP[0] )
1011 | See Also:
1012 | EvaluateSurface
1013 | IsSurface
1014 | SurfaceClosestPoint
1015 | """
1016 | brep = rhutil.coercebrep(object_id, True)
1017 | point = rhutil.coerce3dpoint(point, True)
1018 | rc = brep.ClosestPoint(point, 0.0)
1019 | if rc[0]:
1020 | type = int(rc[2].ComponentIndexType)
1021 | index = rc[2].Index
1022 | return rc[1], (rc[3], rc[4]), (type, index), rc[5]
1023 |
1024 |
1025 | def CapPlanarHoles(surface_id):
1026 | """Caps planar holes in a surface or polysurface
1027 | Parameters:
1028 | surface_id (guid): The identifier of the surface or polysurface to cap.
1029 | Returns:
1030 | bool: True or False indicating success or failure
1031 | Example:
1032 | import rhinoscriptsyntax as rs
1033 | surface = rs.GetObject("Select surface or polysurface to cap", rs.filter.surface | rs.filter.polysurface)
1034 | if surface: rs.CapPlanarHoles( surface )
1035 | See Also:
1036 | ExtrudeCurve
1037 | ExtrudeCurvePoint
1038 | ExtrudeCurveStraight
1039 | ExtrudeSurface
1040 | """
1041 | brep = rhutil.coercebrep(surface_id, True)
1042 | tolerance = scriptcontext.doc.ModelAbsoluteTolerance
1043 | newbrep = brep.CapPlanarHoles(tolerance)
1044 | if newbrep:
1045 | if newbrep.SolidOrientation == Rhino.Geometry.BrepSolidOrientation.Inward:
1046 | newbrep.Flip()
1047 | surface_id = rhutil.coerceguid(surface_id)
1048 | if surface_id and scriptcontext.doc.Objects.Replace(surface_id, newbrep):
1049 | scriptcontext.doc.Views.Redraw()
1050 | return True
1051 | return False
1052 |
1053 |
1054 | def DuplicateEdgeCurves(object_id, select=False):
1055 | """Duplicates the edge curves of a surface or polysurface. For more
1056 | information, see the Rhino help file for information on the DupEdge
1057 | command.
1058 | Parameters:
1059 | object_id (guid): The identifier of the surface or polysurface object.
1060 | select (bool, optional): Select the duplicated edge curves. The default is not
1061 | to select (False).
1062 | Returns:
1063 | list(guid, ..): identifying the newly created curve objects if successful.
1064 | None: if not successful, or on error.
1065 | Example:
1066 | import rhinoscriptsyntax as rs
1067 | obj = rs.GetObject("Select surface or polysurface", rs.filter.surface | rs.filter.polysurface)
1068 | if obj:
1069 | rs.DuplicateEdgeCurves( obj, True )
1070 | rs.DeleteObject( obj )
1071 | See Also:
1072 | IsPolysurface
1073 | IsSurface
1074 | """
1075 | brep = rhutil.coercebrep(object_id, True)
1076 | out_curves = brep.DuplicateEdgeCurves()
1077 | curves = []
1078 | for curve in out_curves:
1079 | if curve.IsValid:
1080 | rc = scriptcontext.doc.Objects.AddCurve(curve)
1081 | curve.Dispose()
1082 | if rc==System.Guid.Empty: return None
1083 | curves.append(rc)
1084 | if select:
1085 | rhobject = rhutil.coercerhinoobject(rc)
1086 | rhobject.Select(True)
1087 | if curves: scriptcontext.doc.Views.Redraw()
1088 | return curves
1089 |
1090 |
1091 | def DuplicateSurfaceBorder(surface_id, type=0):
1092 | """Create curves that duplicate a surface or polysurface border
1093 | Parameters:
1094 | surface_id (guid): identifier of a surface
1095 | type (number, optional): the border curves to return
1096 | 0=both exterior and interior,
1097 | 1=exterior
1098 | 2=interior
1099 | Returns:
1100 | list(guid, ...): list of curve ids on success
1101 | None: on error
1102 | Example:
1103 | import rhinoscriptsyntax as rs
1104 | surface = rs.GetObject("Select surface or polysurface", rs.filter.surface | rs.filter.polysurface)
1105 | if surface: rs.DuplicateSurfaceBorder( surface )
1106 | See Also:
1107 | DuplicateEdgeCurves
1108 | DuplicateMeshBorder
1109 | """
1110 | brep = rhutil.coercebrep(surface_id, True)
1111 | inner = type==0 or type==2
1112 | outer = type==0 or type==1
1113 | curves = brep.DuplicateNakedEdgeCurves(outer, inner)
1114 | if curves is None: return scriptcontext.errorhandler()
1115 | tolerance = scriptcontext.doc.ModelAbsoluteTolerance * 2.1
1116 | curves = Rhino.Geometry.Curve.JoinCurves(curves, tolerance)
1117 | if curves is None: return scriptcontext.errorhandler()
1118 | rc = [scriptcontext.doc.Objects.AddCurve(c) for c in curves]
1119 | scriptcontext.doc.Views.Redraw()
1120 | return rc
1121 |
1122 |
1123 | def EvaluateSurface(surface_id, u, v):
1124 | """Evaluates a surface at a U,V parameter
1125 | Parameters:
1126 | surface_id (guid): the object's identifier.
1127 | u, v ({number, number]): u, v parameters to evaluate.
1128 | Returns:
1129 | point: a 3-D point if successful
1130 | None: if not successful
1131 | Example:
1132 | import rhinoscriptsyntax as rs
1133 | objectId = rs.GetObject("Select a surface")
1134 | if rs.IsSurface(objectId):
1135 | domainU = rs.SurfaceDomain(objectId, 0)
1136 | domainV = rs.SurfaceDomain(objectId, 1)
1137 | u = domainU[1]/2.0
1138 | v = domainV[1]/2.0
1139 | point = rs.EvaluateSurface(objectId, u, v)
1140 | rs.AddPoint( point )
1141 | See Also:
1142 | IsSurface
1143 | SurfaceClosestPoint
1144 | """
1145 | surface = rhutil.coercesurface(surface_id, True)
1146 | rc = surface.PointAt(u,v)
1147 | if rc.IsValid: return rc
1148 | return scriptcontext.errorhandler()
1149 |
1150 |
1151 | def ExtendSurface(surface_id, parameter, length, smooth=True):
1152 | """Lengthens an untrimmed surface object
1153 | Parameters:
1154 | surface_id (guid): identifier of a surface
1155 | parameter ([number, number}): tuple of two values definfing the U,V parameter to evaluate.
1156 | The surface edge closest to the U,V parameter will be the edge that is
1157 | extended
1158 | length (number): amount to extend to surface
1159 | smooth (bool, optional): If True, the surface is extended smoothly curving from the
1160 | edge. If False, the surface is extended in a straight line from the edge
1161 | Returns:
1162 | bool: True or False indicating success or failure
1163 | Example:
1164 | import rhinoscriptsyntax as rs
1165 | pick = rs.GetObjectEx("Select surface to extend", rs.filter.surface)
1166 | if pick:
1167 | parameter = rs.SurfaceClosestPoint(pick[0], pick[3])
1168 | rs.ExtendSurface(pick[0], parameter, 5.0)
1169 | See Also:
1170 | IsSurface
1171 | """
1172 | surface = rhutil.coercesurface(surface_id, True)
1173 | edge = surface.ClosestSide(parameter[0], parameter[1])
1174 | newsrf = surface.Extend(edge, length, smooth)
1175 | if newsrf:
1176 | surface_id = rhutil.coerceguid(surface_id)
1177 | if surface_id: scriptcontext.doc.Objects.Replace(surface_id, newsrf)
1178 | scriptcontext.doc.Views.Redraw()
1179 | return newsrf is not None
1180 |
1181 |
1182 | def ExplodePolysurfaces(object_ids, delete_input=False):
1183 | """Explodes, or unjoins, one or more polysurface objects. Polysurfaces
1184 | will be exploded into separate surfaces
1185 | Parameters:
1186 | object_ids ([guid, ...]): identifiers of polysurfaces to explode
1187 | delete_input 9bool, optional): delete input objects after exploding
1188 | Returns:
1189 | list(guid, ...): of identifiers of exploded pieces on success
1190 | Example:
1191 | import rhinoscriptsyntax as rs
1192 | obj = rs.GetObject("Select polysurface to explode", rs.filter.polysurface)
1193 | if rs.IsPolysurface(obj):
1194 | rs.ExplodePolysurfaces( obj )
1195 | See Also:
1196 | IsPolysurface
1197 | IsSurface
1198 | """
1199 | id = rhutil.coerceguid(object_ids, False)
1200 | if id: object_ids = [id]
1201 | ids = []
1202 | for id in object_ids:
1203 | brep = rhutil.coercebrep(id, True)
1204 | if brep.Faces.Count>1:
1205 | for i in range(brep.Faces.Count):
1206 | copyface = brep.Faces[i].DuplicateFace(False)
1207 | face_id = scriptcontext.doc.Objects.AddBrep(copyface)
1208 | if face_id!=System.Guid.Empty: ids.append(face_id)
1209 | if delete_input: scriptcontext.doc.Objects.Delete(id, True)
1210 | scriptcontext.doc.Views.Redraw()
1211 | return ids
1212 |
1213 |
1214 | def ExtractIsoCurve(surface_id, parameter, direction):
1215 | """Extracts isoparametric curves from a surface
1216 | Parameters:
1217 | surface_id (guid): identifier of a surface
1218 | parameter ([number, number]): u,v parameter of the surface to evaluate
1219 | direction (number): Direction to evaluate
1220 | 0 = u
1221 | 1 = v
1222 | 2 = both
1223 | Returns:
1224 | list(guid, ...): of curve ids on success
1225 | None: on error
1226 | Example:
1227 | import rhinoscriptsyntax as rs
1228 | obj = rs.GetObject("Select surface for isocurve extraction", rs.filter.surface)
1229 | point = rs.GetPointOnSurface(obj, "Select location for extraction")
1230 | parameter = rs.SurfaceClosestPoint(obj, point)
1231 | rs.ExtractIsoCurve( obj, parameter, 2 )
1232 | See Also:
1233 | IsSurface
1234 | """
1235 | surface = rhutil.coercesurface(surface_id, True)
1236 | ids = []
1237 | if direction==0 or direction==2:
1238 | curves = None
1239 | if type(surface) is Rhino.Geometry.BrepFace:
1240 | curves = surface.TrimAwareIsoCurve(0, parameter[1])
1241 | else:
1242 | curves = [surface.IsoCurve(0,parameter[1])]
1243 | if curves:
1244 | for curve in curves:
1245 | id = scriptcontext.doc.Objects.AddCurve(curve)
1246 | if id!=System.Guid.Empty: ids.append(id)
1247 | if direction==1 or direction==2:
1248 | curves = None
1249 | if type(surface) is Rhino.Geometry.BrepFace:
1250 | curves = surface.TrimAwareIsoCurve(1, parameter[0])
1251 | else:
1252 | curves = [surface.IsoCurve(1,parameter[0])]
1253 | if curves:
1254 | for curve in curves:
1255 | id = scriptcontext.doc.Objects.AddCurve(curve)
1256 | if id!=System.Guid.Empty: ids.append(id)
1257 | scriptcontext.doc.Views.Redraw()
1258 | return ids
1259 |
1260 |
1261 | def ExtractSurface(object_id, face_indices, copy=False):
1262 | """Separates or copies a surface or a copy of a surface from a polysurface
1263 | Parameters:
1264 | object_id (guid): polysurface identifier
1265 | face_indices (number, ...): one or more numbers representing faces
1266 | copy (bool, optional): If True the faces are copied. If False, the faces are extracted
1267 | Returns:
1268 | list(guid, ...): identifiers of extracted surface objects on success
1269 | Example:
1270 | import rhinoscriptsyntax as rs
1271 | obj = rs.GetObject("Select polysurface", rs.filter.polysurface, True)
1272 | if obj: rs.ExtractSurface(obj, 0)
1273 | See Also:
1274 | BrepClosestPoint
1275 | IsSurface
1276 | IsPolysurface
1277 | """
1278 | brep = rhutil.coercebrep(object_id, True)
1279 | if hasattr(face_indices, "__getitem__"): pass
1280 | else: face_indices = [face_indices]
1281 | rc = []
1282 | face_indices = sorted(face_indices, reverse=True)
1283 | for index in face_indices:
1284 | face = brep.Faces[index]
1285 | newbrep = face.DuplicateFace(True)
1286 | id = scriptcontext.doc.Objects.AddBrep(newbrep)
1287 | rc.append(id)
1288 | if not copy:
1289 | for index in face_indices: brep.Faces.RemoveAt(index)
1290 | id = rhutil.coerceguid(object_id)
1291 | scriptcontext.doc.Objects.Replace(id, brep)
1292 | scriptcontext.doc.Views.Redraw()
1293 | return rc
1294 |
1295 |
1296 | def ExtrudeCurve(curve_id, path_id):
1297 | """Creates a surface by extruding a curve along a path
1298 | Parameters:
1299 | curve_id (guid): identifier of the curve to extrude
1300 | path_id (guid): identifier of the path curve
1301 | Returns:
1302 | guid: identifier of new surface on success
1303 | None: on error
1304 | Example:
1305 | import rhinoscriptsyntax as rs
1306 | curve = rs.AddCircle(rs.WorldXYPlane(), 5)
1307 | path = rs.AddLine([5,0,0], [10,0,10])
1308 | rs.ExtrudeCurve( curve, path )
1309 | See Also:
1310 | ExtrudeCurvePoint
1311 | ExtrudeCurveStraight
1312 | ExtrudeSurface
1313 | """
1314 | curve1 = rhutil.coercecurve(curve_id, -1, True)
1315 | curve2 = rhutil.coercecurve(path_id, -1, True)
1316 | srf = Rhino.Geometry.SumSurface.Create(curve1, curve2)
1317 | rc = scriptcontext.doc.Objects.AddSurface(srf)
1318 | if rc==System.Guid.Empty: return scriptcontext.errorhandler()
1319 | scriptcontext.doc.Views.Redraw()
1320 | return rc
1321 |
1322 |
1323 | def ExtrudeCurvePoint(curve_id, point):
1324 | """Creates a surface by extruding a curve to a point
1325 | Parameters:
1326 | curve_id (guid): identifier of the curve to extrude
1327 | point (point): 3D point
1328 | Returns:
1329 | guid: identifier of new surface on success
1330 | None: on error
1331 | Example:
1332 | import rhinoscriptsyntax as rs
1333 | curve = rs.AddCircle(rs.WorldXYPlane(), 5)
1334 | point = (0,0,10)
1335 | rs.ExtrudeCurvePoint( curve, point )
1336 | See Also:
1337 | ExtrudeCurve
1338 | ExtrudeCurveStraight
1339 | ExtrudeSurface
1340 | """
1341 | curve = rhutil.coercecurve(curve_id, -1, True)
1342 | point = rhutil.coerce3dpoint(point, True)
1343 | srf = Rhino.Geometry.Surface.CreateExtrusionToPoint(curve, point)
1344 | rc = scriptcontext.doc.Objects.AddSurface(srf)
1345 | if rc==System.Guid.Empty: return scriptcontext.errorhandler()
1346 | scriptcontext.doc.Views.Redraw()
1347 | return rc
1348 |
1349 |
1350 | def ExtrudeCurveStraight(curve_id, start_point, end_point):
1351 | """Create surface by extruding a curve along two points that define a line
1352 | Parameters:
1353 | curve_id (guid): identifier of the curve to extrude
1354 | start_point, end_point (point): 3D points that specify distance and direction
1355 | Returns:
1356 | guid: identifier of new surface on success
1357 | None: on error
1358 | Example:
1359 | import rhinoscriptsyntax as rs
1360 | curve = rs.AddCircle(rs.WorldXYPlane(), 5)
1361 | rs.ExtrudeCurveStraight( curve, (0,0,0), (0, 10, 10) )
1362 | See Also:
1363 | ExtrudeCurve
1364 | ExtrudeCurvePoint
1365 | ExtrudeSurface
1366 | """
1367 | curve = rhutil.coercecurve(curve_id, -1, True)
1368 | start_point = rhutil.coerce3dpoint(start_point, True)
1369 | end_point = rhutil.coerce3dpoint(end_point, True)
1370 | vec = end_point - start_point
1371 | srf = Rhino.Geometry.Surface.CreateExtrusion(curve, vec)
1372 | rc = scriptcontext.doc.Objects.AddSurface(srf)
1373 | if rc==System.Guid.Empty: return scriptcontext.errorhandler()
1374 | scriptcontext.doc.Views.Redraw()
1375 | return rc
1376 |
1377 |
1378 | def ExtrudeSurface(surface, curve, cap=True):
1379 | """Create surface by extruding along a path curve
1380 | Parameters:
1381 | surface (guid): identifier of the surface to extrude
1382 | curve (guid): identifier of the path curve
1383 | cap (bool, optional): extrusion is capped at both ends
1384 | Returns:
1385 | guid: identifier of new surface on success
1386 | Example:
1387 | import rhinoscriptsyntax as rs
1388 | surface = rs.AddSrfPt([(0,0,0), (5,0,0), (5,5,0), (0,5,0)])
1389 | curve = rs.AddLine((5,0,0), (10,0,10))
1390 | rs.ExtrudeSurface(surface, curve)
1391 | See Also:
1392 | ExtrudeCurve
1393 | ExtrudeCurvePoint
1394 | ExtrudeCurveStraight
1395 | """
1396 | brep = rhutil.coercebrep(surface, True)
1397 | curve = rhutil.coercecurve(curve, -1, True)
1398 | newbrep = brep.Faces[0].CreateExtrusion(curve, cap)
1399 | if newbrep:
1400 | rc = scriptcontext.doc.Objects.AddBrep(newbrep)
1401 | scriptcontext.doc.Views.Redraw()
1402 | return rc
1403 |
1404 |
1405 | def FilletSurfaces(surface0, surface1, radius, uvparam0=None, uvparam1=None):
1406 | """Create constant radius rolling ball fillets between two surfaces. Note,
1407 | this function does not trim the original surfaces of the fillets
1408 | Parameters:
1409 | surface0, surface1 (guid): identifiers of first and second surface
1410 | radius (number): a positive fillet radius
1411 | uvparam0 ([number, number], optional): a u,v surface parameter of surface0 near where the fillet
1412 | is expected to hit the surface
1413 | uvparam1([number, number], optional): same as uvparam0, but for surface1
1414 | Returns:
1415 | guid: ids of surfaces created on success
1416 | None: on error
1417 | Example:
1418 | import rhinoscriptsyntax as rs
1419 | surface0 = rs.GetObject("First surface", rs.filter.surface)
1420 | surface1 = rs.GetObject("Second surface", rs.filter.surface)
1421 | rs.FilletSurfaces(surface0, surface1, 2.0)
1422 | See Also:
1423 | IsSurface
1424 | """
1425 | surface0 = rhutil.coercesurface(surface0, True)
1426 | surface1 = rhutil.coercesurface(surface1, True)
1427 | if uvparam0 is not None and uvparam1 is not None: #SR9 error: "Could not convert None to a Point2d"
1428 | uvparam0 = rhutil.coerce2dpoint(uvparam0, True)
1429 | uvparam1 = rhutil.coerce2dpoint(uvparam1, True)
1430 | surfaces = None
1431 | tol = scriptcontext.doc.ModelAbsoluteTolerance
1432 | if uvparam0 and uvparam1:
1433 | surfaces = Rhino.Geometry.Surface.CreateRollingBallFillet(surface0, uvparam0, surface1, uvparam1, radius, tol)
1434 | else:
1435 | surfaces = Rhino.Geometry.Surface.CreateRollingBallFillet(surface0, surface1, radius, tol)
1436 | if not surfaces: return scriptcontext.errorhandler()
1437 | rc = []
1438 | for surf in surfaces:
1439 | rc.append( scriptcontext.doc.Objects.AddSurface(surf) )
1440 | scriptcontext.doc.Views.Redraw()
1441 | return rc
1442 |
1443 |
1444 | def FlipSurface(surface_id, flip=None):
1445 | """Returns or changes the normal direction of a surface. This feature can
1446 | also be found in Rhino's Dir command
1447 | Parameters:
1448 | surface_id (guid): identifier of a surface object
1449 | flip (bool, optional) new normal orientation, either flipped(True) or not flipped (False).
1450 | Returns:
1451 | vector: if flipped is not specified, the current normal orientation
1452 | vector: if flipped is specified, the previous normal orientation
1453 | None: on error
1454 | Example:
1455 | import rhinoscriptsyntax as rs
1456 | surf = rs.GetObject("Select object", rs.filter.surface)
1457 | if surf:
1458 | flip = rs.FlipSurface(surf)
1459 | if flip: rs.FlipSurface(surf, False)
1460 | See Also:
1461 | IsSurface
1462 | """
1463 | brep = rhutil.coercebrep(surface_id, True)
1464 | if brep.Faces.Count>1: return scriptcontext.errorhandler()
1465 | face = brep.Faces[0]
1466 | old_reverse = face.OrientationIsReversed
1467 | if flip!=None and brep.IsSolid==False and old_reverse!=flip:
1468 | brep.Flip()
1469 | surface_id = rhutil.coerceguid(surface_id)
1470 | if surface_id: scriptcontext.doc.Objects.Replace(surface_id, brep)
1471 | scriptcontext.doc.Views.Redraw()
1472 | return old_reverse
1473 |
1474 |
1475 | def IntersectBreps(brep1, brep2, tolerance=None):
1476 | """Intersects a brep object with another brep object. Note, unlike the
1477 | SurfaceSurfaceIntersection function this function works on trimmed surfaces.
1478 | Parameters:
1479 | brep1 (guid): identifier of first brep object
1480 | brep2 (guid): identifier of second brep object
1481 | tolerance (number): Distance tolerance at segment midpoints. If omitted,
1482 | the current absolute tolerance is used.
1483 | Returns:
1484 | list(guid, ...): identifying the newly created intersection curve and point objects if successful.
1485 | None: if not successful, or on error.
1486 | Example:
1487 | import rhinoscriptsyntax as rs
1488 | brep1 = rs.GetObject("Select the first brep", rs.filter.surface | rs.filter.polysurface)
1489 | if brep1:
1490 | brep2 = rs.GetObject("Select the second", rs.filter.surface | rs.filter.polysurface)
1491 | if brep2: rs.IntersectBreps( brep1, brep2)
1492 | See Also:
1493 |
1494 | """
1495 | brep1 = rhutil.coercebrep(brep1, True)
1496 | brep2 = rhutil.coercebrep(brep2, True)
1497 | if tolerance is None or tolerance < 0.0:
1498 | tolerance = scriptcontext.doc.ModelAbsoluteTolerance
1499 | rc = Rhino.Geometry.Intersect.Intersection.BrepBrep(brep1, brep2, tolerance)
1500 | if not rc[0]: return None
1501 | out_curves = rc[1]
1502 | out_points = rc[2]
1503 | merged_curves = Rhino.Geometry.Curve.JoinCurves(out_curves, 2.1 * tolerance)
1504 |
1505 | ids = []
1506 | if merged_curves:
1507 | for curve in merged_curves:
1508 | if curve.IsValid:
1509 | rc = scriptcontext.doc.Objects.AddCurve(curve)
1510 | curve.Dispose()
1511 | if rc==System.Guid.Empty: return scriptcontext.errorhandler()
1512 | ids.append(rc)
1513 | else:
1514 | for curve in out_curves:
1515 | if curve.IsValid:
1516 | rc = scriptcontext.doc.Objects.AddCurve(curve)
1517 | curve.Dispose()
1518 | if rc==System.Guid.Empty: return scriptcontext.errorhandler()
1519 | ids.append(rc)
1520 | for point in out_points:
1521 | rc = scriptcontext.doc.Objects.AddPoint(point)
1522 | if rc==System.Guid.Empty: return scriptcontext.errorhandler()
1523 | ids.append(rc)
1524 | if ids:
1525 | scriptcontext.doc.Views.Redraw()
1526 | return ids
1527 |
1528 |
1529 | def IntersectSpheres(sphere_plane0, sphere_radius0, sphere_plane1, sphere_radius1):
1530 | """Calculates intersections of two spheres
1531 | Parameters:
1532 | sphere_plane0 (plane): an equatorial plane of the first sphere. The origin of the
1533 | plane will be the center point of the sphere
1534 | sphere_radius0 (number): radius of the first sphere
1535 | sphere_plane1 (plane): plane for second sphere
1536 | sphere_radius1 (number): radius for second sphere
1537 | Returns:
1538 | list(number, point, number): of intersection results
1539 | [0] = type of intersection (0=point, 1=circle, 2=spheres are identical)
1540 | [1] = Point of intersection or plane of circle intersection
1541 | [2] = radius of circle if circle intersection
1542 | None: on error
1543 | Example:
1544 | import rhinoscriptsyntax as rs
1545 | plane0 = rs.WorldXYPlane()
1546 | plane1 = rs.MovePlane(plane0, (10,0,0))
1547 | radius = 10
1548 | results = rs.IntersectSpheres(plane0, radius, plane1, radius)
1549 | if results:
1550 | if results[0] == 0: rs.AddPoint(results[1])
1551 | else: rs.AddCircle( results[1], results[2])
1552 | See Also:
1553 | IntersectBreps
1554 | IntersectPlanes
1555 | """
1556 | plane0 = rhutil.coerceplane(sphere_plane0, True)
1557 | plane1 = rhutil.coerceplane(sphere_plane1, True)
1558 | sphere0 = Rhino.Geometry.Sphere(plane0, sphere_radius0)
1559 | sphere1 = Rhino.Geometry.Sphere(plane1, sphere_radius1)
1560 | rc, circle = Rhino.Geometry.Intersect.Intersection.SphereSphere(sphere0, sphere1)
1561 | if rc==Rhino.Geometry.Intersect.SphereSphereIntersection.Point:
1562 | return [0, circle.Center]
1563 | if rc==Rhino.Geometry.Intersect.SphereSphereIntersection.Circle:
1564 | return [1, circle.Plane, circle.Radius]
1565 | if rc==Rhino.Geometry.Intersect.SphereSphereIntersection.Overlap:
1566 | return [2]
1567 | return scriptcontext.errorhandler()
1568 |
1569 |
1570 | def IsBrep(object_id):
1571 | """Verifies an object is a Brep, or a boundary representation model, object.
1572 | Parameters:
1573 | object_id (guid): The object's identifier.
1574 | Returns:
1575 | bool: True if successful, otherwise False.
1576 | None: on error.
1577 | Example:
1578 | import rhinoscriptsyntax as rs
1579 | obj = rs.GetObject("Select a Brep")
1580 | if rs.IsBrep(obj):
1581 | print("The object is a Brep.")
1582 | else:
1583 | print("The object is not a Brep.")
1584 | See Also:
1585 | IsPolysurface
1586 | IsPolysurfaceClosed
1587 | IsSurface
1588 | """
1589 | return rhutil.coercebrep(object_id)!=None
1590 |
1591 |
1592 | def IsCone(object_id):
1593 | """Determines if a surface is a portion of a cone
1594 | Parameters:
1595 | object_id (guid): the surface object's identifier
1596 | Returns:
1597 | bool: True if successful, otherwise False
1598 | Example:
1599 | import rhinoscriptsyntax as rs
1600 | surface = rs.GetObject("Select a surface", rs.filter.surface)
1601 | if surface:
1602 | if rs.IsCone(surface):
1603 | print("The surface is a portion of a cone.")
1604 | else:
1605 | print("The surface is not a portion of a cone.")
1606 | See Also:
1607 | IsCylinder
1608 | IsSphere
1609 | IsSurface
1610 | IsTorus
1611 | """
1612 | surface = rhutil.coercesurface(object_id, True)
1613 | return surface.IsCone()
1614 |
1615 |
1616 | def IsCylinder(object_id):
1617 | """Determines if a surface is a portion of a cone
1618 | Parameters:
1619 | object_id (guid): the cylinder object's identifier
1620 | Returns:
1621 | bool: True if successful, otherwise False
1622 | Example:
1623 | import rhinoscriptsyntax as rs
1624 | surface = rs.GetObject("Select a surface", rs.filter.surface)
1625 | if surface:
1626 | if rs.IsCylinder(surface):
1627 | print("The surface is a portion of a cylinder.")
1628 | else:
1629 | print("The surface is not a portion of a cylinder.")
1630 | See Also:
1631 | IsCone
1632 | IsSphere
1633 | IsSurface
1634 | IsTorus
1635 | """
1636 | surface = rhutil.coercesurface(object_id, True)
1637 | return surface.IsCylinder()
1638 |
1639 |
1640 | def IsPlaneSurface(object_id):
1641 | """Verifies an object is a plane surface. Plane surfaces can be created by
1642 | the Plane command. Note, a plane surface is not a planar NURBS surface
1643 | Parameters:
1644 | object_id (guid): the object's identifier
1645 | Returns:
1646 | bool: True if successful, otherwise False
1647 | Example:
1648 | import rhinoscriptsyntax as rs
1649 | surface = rs.GetObject("Select surface to trim", rs.filter.surface)
1650 | if surface and rs.IsPlaneSurface(surface):
1651 | print("got a plane surface")
1652 | else:
1653 | print("not a plane surface")
1654 | See Also:
1655 | IsBrep
1656 | IsPolysurface
1657 | IsSurface
1658 | """
1659 | face = rhutil.coercesurface(object_id, True)
1660 | if type(face) is Rhino.Geometry.BrepFace and face.IsSurface:
1661 | return type(face.UnderlyingSurface()) is Rhino.Geometry.PlaneSurface
1662 | return False
1663 |
1664 |
1665 | def IsPointInSurface(object_id, point, strictly_in=False, tolerance=None):
1666 | """Verifies that a point is inside a closed surface or polysurface
1667 | Parameters:
1668 | object_id (guid): the object's identifier
1669 | point (point): The test, or sampling point
1670 | strictly_in (bool, optional): If true, the test point must be inside by at least tolerance
1671 | tolerance (number, optional): distance tolerance used for intersection and determining
1672 | strict inclusion. If omitted, Rhino's internal tolerance is used
1673 | Returns:
1674 | bool: True if successful, otherwise False
1675 | Example:
1676 | import rhinoscriptsyntax as rs
1677 | obj = rs.GetObject("Select a polysurface", rs.filter.polysurface)
1678 | if rs.IsPolysurfaceClosed(obj):
1679 | point = rs.GetPoint("Pick a test point")
1680 | if point:
1681 | if rs.IsPointInSurface(obj, point):
1682 | print("The point is inside the polysurface.")
1683 | else:
1684 | print("The point is not inside the polysurface.")
1685 | See Also:
1686 | IsPointOnSurface
1687 | """
1688 | object_id = rhutil.coerceguid(object_id, True)
1689 | point = rhutil.coerce3dpoint(point, True)
1690 | if object_id==None or point==None: return scriptcontext.errorhandler()
1691 | obj = scriptcontext.doc.Objects.Find(object_id)
1692 | if tolerance is None: tolerance = Rhino.RhinoMath.SqrtEpsilon
1693 | brep = None
1694 | if type(obj)==Rhino.DocObjects.ExtrusionObject:
1695 | brep = obj.ExtrusionGeometry.ToBrep(False)
1696 | elif type(obj)==Rhino.DocObjects.BrepObject:
1697 | brep = obj.BrepGeometry
1698 | elif hasattr(obj, "Geometry"):
1699 | brep = obj.Geometry
1700 | return brep.IsPointInside(point, tolerance, strictly_in)
1701 |
1702 |
1703 | def IsPointOnSurface(object_id, point):
1704 | """Verifies that a point lies on a surface
1705 | Parameters:
1706 | object_id (guid): the object's identifier
1707 | point (point): The test, or sampling point
1708 | Returns:
1709 | bool: True if successful, otherwise False
1710 | Example:
1711 | import rhinoscriptsyntax as rs
1712 | surf = rs.GetObject("Select a surface")
1713 | if rs.IsSurface(surf):
1714 | point = rs.GetPoint("Pick a test point")
1715 | if point:
1716 | if rs.IsPointOnSurface(surf, point):
1717 | print("The point is on the surface.")
1718 | else:
1719 | print("The point is not on the surface.")
1720 | See Also:
1721 | IsPointInSurface
1722 | """
1723 | surf = rhutil.coercesurface(object_id, True)
1724 | point = rhutil.coerce3dpoint(point, True)
1725 | rc, u, v = surf.ClosestPoint(point)
1726 | if rc:
1727 | srf_pt = surf.PointAt(u,v)
1728 | if srf_pt.DistanceTo(point)>scriptcontext.doc.ModelAbsoluteTolerance:
1729 | rc = False
1730 | else:
1731 | rc = surf.IsPointOnFace(u,v) != Rhino.Geometry.PointFaceRelation.Exterior
1732 | return rc
1733 |
1734 |
1735 | def IsPolysurface(object_id):
1736 | """Verifies an object is a polysurface. Polysurfaces consist of two or more
1737 | surfaces joined together. If the polysurface fully encloses a volume, it is
1738 | considered a solid.
1739 | Parameters:
1740 | object_id (guid): the object's identifier
1741 | Returns:
1742 | bool: True is successful, otherwise False
1743 | Example:
1744 | import rhinoscriptsyntax as rs
1745 | obj = rs.GetObject("Select a polysurface")
1746 | if rs.IsPolysurface(obj):
1747 | print("The object is a polysurface.")
1748 | else:
1749 | print("The object is not a polysurface.")
1750 | See Also:
1751 | IsBrep
1752 | IsPolysurfaceClosed
1753 | """
1754 | brep = rhutil.coercebrep(object_id)
1755 | if brep is None: return False
1756 | return brep.Faces.Count>1
1757 |
1758 |
1759 | def IsPolysurfaceClosed(object_id):
1760 | """Verifies a polysurface object is closed. If the polysurface fully encloses
1761 | a volume, it is considered a solid.
1762 | Parameters:
1763 | object_id (guid): the object's identifier
1764 | Returns:
1765 | bool: True is successful, otherwise False
1766 | Example:
1767 | import rhinoscriptsyntax as rs
1768 | obj = rs.GetObject("Select a polysurface", rs.filter.polysurface)
1769 | if rs.IsPolysurfaceClosed(obj):
1770 | print("The polysurface is closed.")
1771 | else:
1772 | print("The polysurface is not closed.")
1773 | See Also:
1774 | IsBrep
1775 | IsPolysurface
1776 | """
1777 | brep = rhutil.coercebrep(object_id, True)
1778 | return brep.IsSolid
1779 |
1780 |
1781 | def IsSphere(object_id):
1782 | """Determines if a surface is a portion of a sphere
1783 | Parameters:
1784 | object_id (guid): the object's identifier
1785 | Returns:
1786 | bool: True if successful, otherwise False
1787 | Example:
1788 | import rhinoscriptsyntax as rs
1789 | surface = rs.GetObject("Select a surface", rs.filter.surface)
1790 | if surface:
1791 | if rs.IsSphere(surface):
1792 | print("The surface is a portion of a sphere.")
1793 | else:
1794 | print("The surface is not a portion of a sphere.")
1795 | See Also:
1796 | IsCone
1797 | IsCylinder
1798 | IsSurface
1799 | IsTorus
1800 | """
1801 | surface = rhutil.coercesurface(object_id, True)
1802 | return surface.IsSphere()
1803 |
1804 |
1805 | def IsSurface(object_id):
1806 | """Verifies an object is a surface. Brep objects with only one face are
1807 | also considered surfaces.
1808 | Parameters:
1809 | object_id (guid): the object's identifier.
1810 | Returns:
1811 | bool: True if successful, otherwise False.
1812 | Example:
1813 | import rhinoscriptsyntax as rs
1814 | objectId = rs.GetObject("Select a surface")
1815 | if rs.IsSurface(objectId):
1816 | print("The object is a surface.")
1817 | else:
1818 | print("The object is not a surface.")
1819 | See Also:
1820 | IsPointOnSurface
1821 | IsSurfaceClosed
1822 | IsSurfacePlanar
1823 | IsSurfaceSingular
1824 | IsSurfaceTrimmed
1825 | """
1826 | brep = rhutil.coercebrep(object_id)
1827 | if brep and brep.Faces.Count==1: return True
1828 | surface = rhutil.coercesurface(object_id)
1829 | return (surface!=None)
1830 |
1831 |
1832 | def IsSurfaceClosed( surface_id, direction ):
1833 | """Verifies a surface object is closed in the specified direction. If the
1834 | surface fully encloses a volume, it is considered a solid
1835 | Parameters:
1836 | surface_id (guid): identifier of a surface
1837 | direction (number): 0=U direction check, 1=V direction check
1838 | Returns:
1839 | bool: True or False
1840 | Example:
1841 | import rhinoscriptsyntax as rs
1842 | obj = rs.GetObject("Select a surface", rs.filter.surface)
1843 | if rs.IsSurfaceClosed(obj, 0):
1844 | print("The surface is closed in the U direction.")
1845 | else:
1846 | print("The surface is not closed in the U direction.")
1847 | See Also:
1848 | IsSurface
1849 | IsSurfacePlanar
1850 | IsSurfaceSingular
1851 | IsSurfaceTrimmed
1852 | """
1853 | surface = rhutil.coercesurface(surface_id, True)
1854 | return surface.IsClosed(direction)
1855 |
1856 |
1857 | def IsSurfacePeriodic(surface_id, direction):
1858 | """Verifies a surface object is periodic in the specified direction.
1859 | Parameters:
1860 | surface_id (guid): identifier of a surface
1861 | direction (number): 0=U direction check, 1=V direction check
1862 | Returns:
1863 | bool: True or False
1864 | Example:
1865 | import rhinoscriptsyntax as rs
1866 | obj = rs.GetObject("Select a surface", rs.filter.surface)
1867 | if rs.IsSurfacePeriodic(obj, 0):
1868 | print("The surface is periodic in the U direction.")
1869 | else:
1870 | print("The surface is not periodic in the U direction.")
1871 | See Also:
1872 | IsSurface
1873 | IsSurfaceClosed
1874 | IsSurfacePlanar
1875 | IsSurfaceSingular
1876 | IsSurfaceTrimmed
1877 | """
1878 | surface = rhutil.coercesurface(surface_id, True)
1879 | return surface.IsPeriodic(direction)
1880 |
1881 |
1882 | def IsSurfacePlanar(surface_id, tolerance=None):
1883 | """Verifies a surface object is planar
1884 | Parameters:
1885 | surface_id (guid): identifier of a surface
1886 | tolerance (number): tolerance used when checked. If omitted, the current absolute
1887 | tolerance is used
1888 | Returns:
1889 | bool: True or False
1890 | Example:
1891 | import rhinoscriptsyntax as rs
1892 | obj = rs.GetObject("Select a surface", rs.filter.surface)
1893 | if rs.IsSurfacePlanar(obj):
1894 | print("The surface is planar.")
1895 | else:
1896 | print("The surface is not planar.")
1897 | See Also:
1898 | IsSurface
1899 | IsSurfaceClosed
1900 | IsSurfaceSingular
1901 | IsSurfaceTrimmed
1902 | """
1903 | surface = rhutil.coercesurface(surface_id, True)
1904 | if tolerance is None:
1905 | tolerance = scriptcontext.doc.ModelAbsoluteTolerance
1906 | return surface.IsPlanar(tolerance)
1907 |
1908 |
1909 | def IsSurfaceRational(surface_id):
1910 | """Verifies a surface object is rational
1911 | Parameters:
1912 | surface_id (guid): the surface's identifier
1913 | Returns:
1914 | bool: True if successful, otherwise False
1915 | Example:
1916 | import rhinoscriptsyntax as rs
1917 | obj = rs.GetObject("Select a surface", rs.filter.surface)
1918 | if rs.IsSurfaceRational(obj):
1919 | print("The surface is rational.")
1920 | else:
1921 | print("The surface is not rational.")
1922 | See Also:
1923 | IsSurface
1924 | IsSurfaceClosed
1925 | IsSurfacePlanar
1926 | IsSurfaceTrimmed
1927 | """
1928 | surface = rhutil.coercesurface(surface_id, True)
1929 | ns = surface.ToNurbsSurface()
1930 | if ns is None: return False
1931 | return ns.IsRational
1932 |
1933 |
1934 | def IsSurfaceSingular(surface_id, direction):
1935 | """Verifies a surface object is singular in the specified direction.
1936 | Surfaces are considered singular if a side collapses to a point.
1937 | Parameters:
1938 | surface_id (guid): the surface's identifier
1939 | direction (number):
1940 | 0=south
1941 | 1=east
1942 | 2=north
1943 | 3=west
1944 | Returns:
1945 | bool: True or False
1946 | Example:
1947 | import rhinoscriptsyntax as rs
1948 | obj = rs.GetObject("Select a surface", rs.filter.surface)
1949 | if rs.IsSurfaceSingular(obj, 0):
1950 | print("The surface is singular.")
1951 | else:
1952 | print("The surface is not singular.")
1953 | See Also:
1954 | IsSurface
1955 | IsSurfaceClosed
1956 | IsSurfacePlanar
1957 | IsSurfaceTrimmed
1958 | """
1959 | surface = rhutil.coercesurface(surface_id, True)
1960 | return surface.IsSingular(direction)
1961 |
1962 |
1963 | def IsSurfaceTrimmed(surface_id):
1964 | """Verifies a surface object has been trimmed
1965 | Parameters:
1966 | surface_id (guid): the surface's identifier
1967 | Returns:
1968 | bool: True or False
1969 | Example:
1970 | import rhinoscriptsyntax as rs
1971 | obj = rs.GetObject("Select a surface", rs.filter.surface)
1972 | if rs.IsSurfaceTrimmed(obj):
1973 | print("The surface is trimmed.")
1974 | else:
1975 | print("The surface is not trimmed.")
1976 | See Also:
1977 | IsSurface
1978 | IsSurfaceClosed
1979 | IsSurfacePlanar
1980 | IsSurfaceSingular
1981 | """
1982 | brep = rhutil.coercebrep(surface_id, True)
1983 | return not brep.IsSurface
1984 |
1985 |
1986 | def IsTorus(surface_id):
1987 | """Determines if a surface is a portion of a torus
1988 | Parameters:
1989 | surface_id (guid): the surface object's identifier
1990 | Returns:
1991 | bool: True if successful, otherwise False
1992 | Example:
1993 | import rhinoscriptsyntax as rs
1994 | surface = rs.GetObject("Select a surface", rs.filter.surface)
1995 | if surface:
1996 | if rs.IsTorus(surface):
1997 | print("The surface is a portion of a torus.")
1998 | else:
1999 | print("The surface is not a portion of a torus.")
2000 | See Also:
2001 | IsCone
2002 | IsCylinder
2003 | IsSphere
2004 | IsSurface
2005 | """
2006 | surface = rhutil.coercesurface(surface_id, True)
2007 | return surface.IsTorus()
2008 |
2009 |
2010 | def SurfaceSphere(surface_id):
2011 | """Gets the sphere definition from a surface, if possible.
2012 | Parameters:
2013 | surface_id (guid): the identifier of the surface object
2014 | Returns:
2015 | (plane, number): The equatorial plane of the sphere, and its radius.
2016 | None: on error
2017 | Example:
2018 | import rhinoscriptsyntax as rs
2019 | surface = rs.GetObject("Select a surface", rs.filter.surface)
2020 | if surface:
2021 | result = rs.SurfaceSphere(surface)
2022 | if result:
2023 | print("The sphere radius is: " + str(result[1]))
2024 | See Also:
2025 | SurfaceCylinder
2026 | """
2027 | surface = rhutil.coercesurface(surface_id, True)
2028 | tol = scriptcontext.doc.ModelAbsoluteTolerance
2029 | is_sphere, sphere = surface.TryGetSphere(tol)
2030 | rc = None
2031 | if is_sphere: rc = (sphere.EquatorialPlane, sphere.Radius)
2032 | return rc
2033 |
2034 |
2035 | def JoinSurfaces(object_ids, delete_input=False, return_all=False):
2036 | """Joins two or more surface or polysurface objects together to form one
2037 | polysurface object
2038 | Parameters:
2039 | object_ids ([guid, ...]) list of object identifiers
2040 | delete_input (bool, optional): Delete the original surfaces
2041 | return_all (bool, optional): Return all surfaces in result
2042 | Returns:
2043 | guid or guid list: identifier, or list of identifiers if return_all == True, of newly created object(s) on success
2044 | None: on failure
2045 | Example:
2046 | import rhinoscriptsyntax as rs
2047 | objs = rs.GetObjects("Select surfaces in order", rs.filter.surface)
2048 | if objs and len(objs)>1: rs.JoinSurfaces(objs)
2049 | See Also:
2050 | ExplodePolysurfaces
2051 | IsPolysurface
2052 | IsPolysurfaceClosed
2053 | IsSurface
2054 | IsSurfaceClosed
2055 | """
2056 | breps = [rhutil.coercebrep(id, True) for id in object_ids]
2057 | if len(breps)<2: return scriptcontext.errorhandler()
2058 | tol = scriptcontext.doc.ModelAbsoluteTolerance * 2.1
2059 | joinedbreps = Rhino.Geometry.Brep.JoinBreps(breps, tol)
2060 | if joinedbreps is None or (len(joinedbreps)!=1 and return_all == False):
2061 | return scriptcontext.errorhandler()
2062 | rc = []
2063 | for brep in joinedbreps:
2064 | id = scriptcontext.doc.Objects.AddBrep(brep)
2065 | if id==System.Guid.Empty: return scriptcontext.errorhandler()
2066 | rc.append(id)
2067 | if delete_input:
2068 | for id in object_ids:
2069 | id = rhutil.coerceguid(id)
2070 | scriptcontext.doc.Objects.Delete(id, True)
2071 | scriptcontext.doc.Views.Redraw()
2072 | return rc if return_all else rc[0]
2073 |
2074 |
2075 | def MakeSurfacePeriodic(surface_id, direction, delete_input=False):
2076 | """Makes an existing surface a periodic NURBS surface
2077 | Parameters:
2078 | surface_id (guid): the surface's identifier
2079 | direction (number): The direction to make periodic, either 0=U or 1=V
2080 | delete_input (bool, optional): delete the input surface
2081 | Returns:
2082 | guid: if delete_input is False, identifier of the new surface
2083 | guid: if delete_input is True, identifier of the modifier surface
2084 | None: on error
2085 | Example:
2086 | import rhinoscriptsyntax as rs
2087 | obj = rs.GetObject("Select a surface", rs.filter.surface)
2088 | if not rs.IsSurfacePeriodic(obj, 0):
2089 | rs.MakeSurfacePeriodic(obj, 0)
2090 | See Also:
2091 | IsSurfacePeriodic
2092 | """
2093 | surface = rhutil.coercesurface(surface_id, True)
2094 | newsurf = Rhino.Geometry.Surface.CreatePeriodicSurface(surface, direction)
2095 | if newsurf is None: return scriptcontext.errorhandler()
2096 | id = rhutil.coerceguid(surface_id)
2097 | if delete_input:
2098 | scriptcontext.doc.Objects.Replace(id, newsurf)
2099 | else:
2100 | id = scriptcontext.doc.Objects.AddSurface(newsurf)
2101 | scriptcontext.doc.Views.Redraw()
2102 | return id
2103 |
2104 |
2105 | def OffsetSurface(surface_id, distance, tolerance=None, both_sides=False, create_solid=False):
2106 | """Offsets a trimmed or untrimmed surface by a distance. The offset surface
2107 | will be added to Rhino.
2108 | Parameters:
2109 | surface_id (guid): the surface's identifier
2110 | distance (number): the distance to offset
2111 | tolerance (number, optional): The offset tolerance. Use 0.0 to make a loose offset. Otherwise, the
2112 | document's absolute tolerance is usually sufficient.
2113 | both_sides (bool, optional): Offset to both sides of the input surface
2114 | create_solid (bool, optional): Make a solid object
2115 | Returns:
2116 | guid: identifier of the new object if successful
2117 | None: on error
2118 | Example:
2119 | import rhinoscriptsyntax as rs
2120 | surface = rs.GetObject("Select a surface", rs.filter.surface)
2121 | if rs.IsSurface(surface):
2122 | rs.OffsetSurface( surface, 10.0 )
2123 | See Also:
2124 | OffsetCurve
2125 | """
2126 | brep = rhutil.coercebrep(surface_id, True)
2127 | face = None
2128 | if (1 == brep.Faces.Count): face = brep.Faces[0]
2129 | if face is None: return scriptcontext.errorhandler()
2130 | if tolerance is None: tolerance = scriptcontext.doc.ModelAbsoluteTolerance
2131 | newbrep = Rhino.Geometry.Brep.CreateFromOffsetFace(face, distance, tolerance, both_sides, create_solid)
2132 | if newbrep is None: return scriptcontext.errorhandler()
2133 | rc = scriptcontext.doc.Objects.AddBrep(newbrep)
2134 | if rc==System.Guid.Empty: return scriptcontext.errorhandler()
2135 | scriptcontext.doc.Views.Redraw()
2136 | return rc
2137 |
2138 |
2139 | def PullCurve(surface, curve, delete_input=False):
2140 | """Pulls a curve object to a surface object
2141 | Parameters:
2142 | surface (guid): the surface's identifier
2143 | curve (guid): the curve's identifier
2144 | delete_input (bool, optional) should the input items be deleted
2145 | Returns:
2146 | list(guid, ...): of new curves if successful
2147 | None: on error
2148 | Example:
2149 | import rhinoscriptsyntax as rs
2150 | curve = rs.GetObject("Select curve to pull", rs.filter.curve )
2151 | surface = rs.GetObject("Select surface that pulls", rs.filter.surface )
2152 | rs.PullCurve(surface, curve)
2153 | See Also:
2154 | IsSurface
2155 | """
2156 | crvobj = rhutil.coercerhinoobject(curve, True, True)
2157 | brep = rhutil.coercebrep(surface, True)
2158 | curve = rhutil.coercecurve(curve, -1, True)
2159 | tol = scriptcontext.doc.ModelAbsoluteTolerance
2160 | curves = Rhino.Geometry.Curve.PullToBrepFace(curve, brep.Faces[0], tol)
2161 | rc = [scriptcontext.doc.Objects.AddCurve(curve) for curve in curves]
2162 | if rc:
2163 | if delete_input and crvobj:
2164 | scriptcontext.doc.Objects.Delete(crvobj, True)
2165 | scriptcontext.doc.Views.Redraw()
2166 | return rc
2167 |
2168 |
2169 | def RebuildSurface(object_id, degree=(3,3), pointcount=(10,10)):
2170 | """Rebuilds a surface to a given degree and control point count. For more
2171 | information see the Rhino help file for the Rebuild command
2172 | Parameters:
2173 | object_id (guid): the surface's identifier
2174 | degree ([number, number], optional): two numbers that identify surface degree in both U and V directions
2175 | pointcount ([number, number], optional): two numbers that identify the surface point count in both the U and V directions
2176 | Returns:
2177 | bool: True of False indicating success or failure
2178 | Example:
2179 | See Also:
2180 | """
2181 | surface = rhutil.coercesurface(object_id, True)
2182 | newsurf = surface.Rebuild( degree[0], degree[1], pointcount[0], pointcount[1] )
2183 | if newsurf is None: return False
2184 | object_id = rhutil.coerceguid(object_id)
2185 | rc = scriptcontext.doc.Objects.Replace(object_id, newsurf)
2186 | if rc: scriptcontext.doc.Views.Redraw()
2187 | return rc
2188 |
2189 |
2190 | def RemoveSurfaceKnot(surface, uv_parameter, v_direction):
2191 | """Deletes a knot from a surface object.
2192 | Parameters:
2193 | surface (guid): The reference of the surface object
2194 | uv_parameter (list(number, number)): An indexable item containing a U,V parameter on the surface. List, tuples and UVIntervals will work.
2195 | Note, if the parameter is not equal to one of the existing knots, then the knot closest to the specified parameter will be removed.
2196 | v_direction (bool): if True, or 1, the V direction will be addressed. If False, or 0, the U direction.
2197 | Returns:
2198 | bool: True of False indicating success or failure
2199 | Example:
2200 | import rhinoscriptsyntax as rs
2201 |
2202 | srf_info = rs.GetSurfaceObject()
2203 | if srf_info:
2204 | srf_id = srf_info[0]
2205 | srf_param = srf_info[4]
2206 | rs.RemoveSurfaceKnot(srf_id, srf_param, 1)
2207 | See Also:
2208 | RemoveSurfaceKnot
2209 | """
2210 | srf_inst = rhutil.coercesurface(surface, True)
2211 | u_param = uv_parameter[0]
2212 | v_param = uv_parameter[1]
2213 | success, n_u_param, n_v_param = srf_inst.GetSurfaceParameterFromNurbsFormParameter(u_param, v_param)
2214 | if not success: return False
2215 | n_srf = srf_inst.ToNurbsSurface()
2216 | if not n_srf: return False
2217 | knots = n_srf.KnotsV if v_direction else n_srf.KnotsU
2218 | success = knots.RemoveKnotsAt(n_u_param, n_v_param)
2219 | if not success: return False
2220 | scriptcontext.doc.Objects.Replace(surface, n_srf)
2221 | scriptcontext.doc.Views.Redraw()
2222 | return True
2223 |
2224 |
2225 | def ReverseSurface(surface_id, direction):
2226 | """Reverses U or V directions of a surface, or swaps (transposes) U and V
2227 | directions.
2228 | Parameters:
2229 | surface_id (guid): identifier of a surface object
2230 | direction (number): as a bit coded flag to swap
2231 | 1 = reverse U
2232 | 2 = reverse V
2233 | 4 = transpose U and V (values can be combined)
2234 | Returns:
2235 | bool: indicating success or failure
2236 | None: on error
2237 | Example:
2238 | import rhinoscriptsyntax as rs
2239 | obj = rs.GetObject("Select a surface to reverse")
2240 | if rs.IsSurface(obj):
2241 | rs.ReverseSurface( obj, 1 )
2242 | See Also:
2243 | FlipSurface
2244 | IsSurface
2245 | """
2246 | brep = rhutil.coercebrep(surface_id, True)
2247 | if not brep.Faces.Count==1: return scriptcontext.errorhandler()
2248 | face = brep.Faces[0]
2249 | if direction & 1:
2250 | face.Reverse(0, True)
2251 | if direction & 2:
2252 | face.Reverse(1, True)
2253 | if direction & 4:
2254 | face.Transpose(True)
2255 | scriptcontext.doc.Objects.Replace(surface_id, brep)
2256 | scriptcontext.doc.Views.Redraw()
2257 | return True
2258 |
2259 |
2260 | def ShootRay(surface_ids, start_point, direction, reflections=10):
2261 | """Shoots a ray at a collection of surfaces
2262 | Parameters:
2263 | surface_ids ([guid, ...]): one of more surface identifiers
2264 | start_point (point): starting point of the ray
2265 | direction (vector): vector identifying the direction of the ray
2266 | reflections (number, optional): the maximum number of times the ray will be reflected
2267 | Returns:
2268 | list(point, ...): of reflection points on success
2269 | None: on error
2270 | Example:
2271 | import rhinoscriptsyntax as rs
2272 | def TestRayShooter():
2273 | corners = []
2274 | corners.append((0,0,0))
2275 | corners.append((10,0,0))
2276 | corners.append((10,10,0))
2277 | corners.append((0,10,0))
2278 | corners.append((0,0,10))
2279 | corners.append((10,0,10))
2280 | corners.append((10,10,10))
2281 | corners.append((0,10,10))
2282 | box = rs.AddBox(corners)
2283 | dir = 10,7.5,7
2284 | reflections = rs.ShootRay(box, (0,0,0), dir)
2285 | rs.AddPolyline( reflections )
2286 | rs.AddPoints( reflections )
2287 | TestRayShooter()
2288 | See Also:
2289 | IsPolysurface
2290 | IsSurface
2291 | """
2292 | start_point = rhutil.coerce3dpoint(start_point, True)
2293 | direction = rhutil.coerce3dvector(direction, True)
2294 | id = rhutil.coerceguid(surface_ids, False)
2295 | if id: surface_ids = [id]
2296 | ray = Rhino.Geometry.Ray3d(start_point, direction)
2297 | breps = []
2298 | for id in surface_ids:
2299 | brep = rhutil.coercebrep(id)
2300 | if brep: breps.append(brep)
2301 | else:
2302 | surface = rhutil.coercesurface(id, True)
2303 | breps.append(surface)
2304 | if not breps: return scriptcontext.errorhandler()
2305 | points = Rhino.Geometry.Intersect.Intersection.RayShoot(ray, breps, reflections)
2306 | if points:
2307 | rc = []
2308 | rc.append(start_point)
2309 | rc = rc + list(points)
2310 | return rc
2311 | return scriptcontext.errorhandler()
2312 |
2313 |
2314 | def ShortPath(surface_id, start_point, end_point):
2315 | """Creates the shortest possible curve(geodesic) between two points on a
2316 | surface. For more details, see the ShortPath command in Rhino help
2317 | Parameters:
2318 | surface_id (guid): identifier of a surface
2319 | start_point, end_point (point): start/end points of the short curve
2320 | Returns:
2321 | guid: identifier of the new surface on success
2322 | None: on error
2323 | Example:
2324 | import rhinoscriptsyntax as rs
2325 | surface = rs.GetObject("Select surface for short path", rs.filter.surface + rs.filter.surface)
2326 | if surface:
2327 | start = rs.GetPointOnSurface(surface, "First point")
2328 | end = rs.GetPointOnSurface(surface, "Second point")
2329 | rs.ShortPath(surface, start, end)
2330 | See Also:
2331 | EvaluateSurface
2332 | SurfaceClosestPoint
2333 | """
2334 | surface = rhutil.coercesurface(surface_id, True)
2335 | start = rhutil.coerce3dpoint(start_point, True)
2336 | end = rhutil.coerce3dpoint(end_point, True)
2337 | rc_start, u_start, v_start = surface.ClosestPoint(start)
2338 | rc_end, u_end, v_end = surface.ClosestPoint(end)
2339 | if not rc_start or not rc_end: return scriptcontext.errorhandler()
2340 | start = Rhino.Geometry.Point2d(u_start, v_start)
2341 | end = Rhino.Geometry.Point2d(u_end, v_end)
2342 | tolerance = scriptcontext.doc.ModelAbsoluteTolerance
2343 | curve = surface.ShortPath(start, end, tolerance)
2344 | if curve is None: return scriptcontext.errorhandler()
2345 | id = scriptcontext.doc.Objects.AddCurve(curve)
2346 | if id==System.Guid.Empty: return scriptcontext.errorhandler()
2347 | scriptcontext.doc.Views.Redraw()
2348 | return id
2349 |
2350 |
2351 | def ShrinkTrimmedSurface(object_id, create_copy=False):
2352 | """Shrinks the underlying untrimmed surfaces near to the trimming
2353 | boundaries. See the ShrinkTrimmedSrf command in the Rhino help.
2354 | Parameters:
2355 | object_id (guid): the surface's identifier
2356 | create_copy (bool, optional): If True, the original surface is not deleted
2357 | Returns:
2358 | bool: If create_copy is False, True or False indicating success or failure
2359 | bool: If create_copy is True, the identifier of the new surface
2360 | None: on error
2361 | Example:
2362 | import rhinoscriptsyntax as rs
2363 | filter = rs.filter.surface | rs.filter.polysurface
2364 | surface = rs.GetObject("Select surface or polysurface to shrink", filter )
2365 | if surface: rs.ShrinkTrimmedSurface( surface )
2366 | See Also:
2367 | IsSurfaceTrimmed
2368 | """
2369 | brep = rhutil.coercebrep(object_id, True)
2370 | if not brep.Faces.ShrinkFaces(): return scriptcontext.errorhandler()
2371 | rc = None
2372 | object_id = rhutil.coerceguid(object_id)
2373 | if create_copy:
2374 | oldobj = scriptcontext.doc.Objects.Find(object_id)
2375 | attr = oldobj.Attributes
2376 | rc = scriptcontext.doc.Objects.AddBrep(brep, attr)
2377 | else:
2378 | rc = scriptcontext.doc.Objects.Replace(object_id, brep)
2379 | scriptcontext.doc.Views.Redraw()
2380 | return rc
2381 |
2382 |
2383 | def __GetMassProperties(object_id, area):
2384 | surface = rhutil.coercebrep(object_id)
2385 | if surface is None:
2386 | surface = rhutil.coercesurface(object_id)
2387 | if surface is None: return None
2388 | if area==True: return Rhino.Geometry.AreaMassProperties.Compute(surface)
2389 | if not surface.IsSolid: return None
2390 | return Rhino.Geometry.VolumeMassProperties.Compute(surface)
2391 |
2392 |
2393 | def SplitBrep(brep_id, cutter_id, delete_input=False):
2394 | """Splits a brep
2395 | Parameters:
2396 | brep (guid): identifier of the brep to split
2397 | cutter (guid): identifier of the brep to split with
2398 | Returns:
2399 | list(guid, ...): identifiers of split pieces on success
2400 | None: on error
2401 | Example:
2402 | import rhinoscriptsyntax as rs
2403 | filter = rs.filter.surface + rs.filter.polysurface
2404 | brep = rs.GetObject("Select brep to split", filter)
2405 | cutter = rs.GetObject("Select cutting brep", filter)
2406 | rs.SplitBrep ( brep, cutter )
2407 | See Also:
2408 | IsBrep
2409 | """
2410 | brep = rhutil.coercebrep(brep_id, True)
2411 | cutter = rhutil.coercebrep(cutter_id, True)
2412 | tol = scriptcontext.doc.ModelAbsoluteTolerance
2413 | pieces = brep.Split(cutter, tol)
2414 | if not pieces: return scriptcontext.errorhandler()
2415 | if delete_input:
2416 | brep_id = rhutil.coerceguid(brep_id)
2417 | scriptcontext.doc.Objects.Delete(brep_id, True)
2418 | rc = [scriptcontext.doc.Objects.AddBrep(piece) for piece in pieces]
2419 | scriptcontext.doc.Views.Redraw()
2420 | return rc
2421 |
2422 |
2423 | def SurfaceArea(object_id):
2424 | """Calculate the area of a surface or polysurface object. The results are
2425 | based on the current drawing units
2426 | Parameters:
2427 | object_id (guid): the surface's identifier
2428 | Returns:
2429 | list(number, number): of area information on success (area, absolute error bound)
2430 | None: on error
2431 | Example:
2432 | import rhinoscriptsyntax as rs
2433 | obj = rs.GetObject("Select a surface", rs.filter.surface)
2434 | if obj:
2435 | massprop = rs.SurfaceArea( obj )
2436 | if massprop:
2437 | print("The surface area is: {}".format(massprop[0]))
2438 | See Also:
2439 | SurfaceAreaCentroid
2440 | SurfaceAreaMoments
2441 | """
2442 | amp = __GetMassProperties(object_id, True)
2443 | if amp: return amp.Area, amp.AreaError
2444 |
2445 |
2446 | def SurfaceAreaCentroid(object_id):
2447 | """Calculates the area centroid of a surface or polysurface
2448 | Parameters:
2449 | object_id (guid): the surface's identifier
2450 | Returns:
2451 | list(point, tuple(number, number, number)): Area centroid information (Area Centroid, Error bound in X, Y, Z)
2452 | None: on error
2453 | Example:
2454 | import rhinoscriptsyntax as rs
2455 | obj = rs.GetObject("Select a surface", rs.filter.surface)
2456 | if obj:
2457 | massprop = rs.SurfaceAreaCentroid(obj)
2458 | if massprop: rs.AddPoint( massprop[0] )
2459 | See Also:
2460 | SurfaceArea
2461 | SurfaceAreaMoments
2462 | """
2463 | amp = __GetMassProperties(object_id, True)
2464 | if amp is None: return scriptcontext.errorhandler()
2465 | return amp.Centroid, amp.CentroidError
2466 |
2467 |
2468 | def __AreaMomentsHelper(surface_id, area):
2469 | mp = __GetMassProperties(surface_id, area)
2470 | if mp is None: return scriptcontext.errorhandler()
2471 | a = (mp.WorldCoordinatesFirstMoments.X, mp.WorldCoordinatesFirstMoments.Y, mp.WorldCoordinatesFirstMoments.Z)
2472 | b = (mp.WorldCoordinatesFirstMomentsError.X, mp.WorldCoordinatesFirstMomentsError.Y, mp.WorldCoordinatesFirstMomentsError.Z)
2473 | c = (mp.WorldCoordinatesSecondMoments.X, mp.WorldCoordinatesSecondMoments.Y, mp.WorldCoordinatesSecondMoments.Z)
2474 | d = (mp.WorldCoordinatesSecondMomentsError.X, mp.WorldCoordinatesSecondMomentsError.Y, mp.WorldCoordinatesSecondMomentsError.Z)
2475 | e = (mp.WorldCoordinatesProductMoments.X, mp.WorldCoordinatesProductMoments.Y, mp.WorldCoordinatesProductMoments.Z)
2476 | f = (mp.WorldCoordinatesProductMomentsError.X, mp.WorldCoordinatesProductMomentsError.Y, mp.WorldCoordinatesProductMomentsError.Z)
2477 | g = (mp.WorldCoordinatesMomentsOfInertia.X, mp.WorldCoordinatesMomentsOfInertia.Y, mp.WorldCoordinatesMomentsOfInertia.Z)
2478 | h = (mp.WorldCoordinatesMomentsOfInertiaError.X, mp.WorldCoordinatesMomentsOfInertiaError.Y, mp.WorldCoordinatesMomentsOfInertiaError.Z)
2479 | i = (mp.WorldCoordinatesRadiiOfGyration.X, mp.WorldCoordinatesRadiiOfGyration.Y, mp.WorldCoordinatesRadiiOfGyration.Z)
2480 | j = (0,0,0) # need to add error calc to RhinoCommon
2481 | k = (mp.CentroidCoordinatesMomentsOfInertia.X, mp.CentroidCoordinatesMomentsOfInertia.Y, mp.CentroidCoordinatesMomentsOfInertia.Z)
2482 | l = (mp.CentroidCoordinatesMomentsOfInertiaError.X, mp.CentroidCoordinatesMomentsOfInertiaError.Y, mp.CentroidCoordinatesMomentsOfInertiaError.Z)
2483 | m = (mp.CentroidCoordinatesRadiiOfGyration.X, mp.CentroidCoordinatesRadiiOfGyration.Y, mp.CentroidCoordinatesRadiiOfGyration.Z)
2484 | n = (0,0,0) #need to add error calc to RhinoCommon
2485 | return (a,b,c,d,e,f,g,h,i,j,k,l,m,n)
2486 |
2487 |
2488 | def SurfaceAreaMoments(surface_id):
2489 | """Calculates area moments of inertia of a surface or polysurface object.
2490 | See the Rhino help for "Mass Properties calculation details"
2491 | Parameters:
2492 | surface_id (guid): the surface's identifier
2493 | Returns:
2494 | list(tuple(number, number,number), ...): of moments and error bounds in tuple(X, Y, Z) - see help topic
2495 | Index Description
2496 | [0] First Moments.
2497 | [1] The absolute (+/-) error bound for the First Moments.
2498 | [2] Second Moments.
2499 | [3] The absolute (+/-) error bound for the Second Moments.
2500 | [4] Product Moments.
2501 | [5] The absolute (+/-) error bound for the Product Moments.
2502 | [6] Area Moments of Inertia about the World Coordinate Axes.
2503 | [7] The absolute (+/-) error bound for the Area Moments of Inertia about World Coordinate Axes.
2504 | [8] Area Radii of Gyration about the World Coordinate Axes.
2505 | [9] The absolute (+/-) error bound for the Area Radii of Gyration about World Coordinate Axes.
2506 | [10] Area Moments of Inertia about the Centroid Coordinate Axes.
2507 | [11] The absolute (+/-) error bound for the Area Moments of Inertia about the Centroid Coordinate Axes.
2508 | [12] Area Radii of Gyration about the Centroid Coordinate Axes.
2509 | [13] The absolute (+/-) error bound for the Area Radii of Gyration about the Centroid Coordinate Axes.
2510 | None: on error
2511 | Example:
2512 | import rhinoscriptsyntax as rs
2513 | obj = rs.GetObject("Select a surface", rs.filter.surface)
2514 | if obj:
2515 | massprop= rs.SurfaceAreaMoments(obj)
2516 | if massprop:
2517 | print("Area Moments of Inertia about the World Coordinate Axes: {}".format(massprop[6]))
2518 | See Also:
2519 | SurfaceArea
2520 | SurfaceAreaCentroid
2521 | """
2522 | return __AreaMomentsHelper(surface_id, True)
2523 |
2524 |
2525 | def SurfaceClosestPoint(surface_id, test_point):
2526 | """Returns U,V parameters of point on a surface that is closest to a test point
2527 | Parameters:
2528 | surface_id (guid): identifier of a surface object
2529 | test_point (point): sampling point
2530 | Returns:
2531 | list(number, number): The U,V parameters of the closest point on the surface if successful.
2532 | None: on error.
2533 | Example:
2534 | import rhinoscriptsyntax as rs
2535 | obj = rs.GetObject("Select a surface", rs.filter.surface)
2536 | if rs.IsSurface(obj):
2537 | point = rs.GetPointOnSurface(obj, "Pick a test point")
2538 | if point:
2539 | param = rs.SurfaceClosestPoint(obj, point)
2540 | if param:
2541 | print("Surface U parameter: {}".format(str(param[0])))
2542 | print("Surface V parameter: {}".format(str(param[1])))
2543 | See Also:
2544 | BrepClosestPoint
2545 | EvaluateSurface
2546 | IsSurface
2547 | """
2548 | surface = rhutil.coercesurface(surface_id, True)
2549 | point = rhutil.coerce3dpoint(test_point, True)
2550 | rc, u, v = surface.ClosestPoint(point)
2551 | if not rc: return None
2552 | return u,v
2553 |
2554 |
2555 | def SurfaceCone(surface_id):
2556 | """Returns the definition of a surface cone
2557 | Parameters:
2558 | surface_id (guid): the surface's identifier
2559 | Returns:
2560 | tuple(plane, number, number): containing the definition of the cone if successful
2561 | [0] the plane of the cone. The apex of the cone is at the
2562 | plane's origin and the axis of the cone is the plane's z-axis
2563 | [1] the height of the cone
2564 | [2] the radius of the cone
2565 | None: on error
2566 | Example:
2567 | import rhinoscriptsyntax as rs
2568 | cone = rs.AddCone(rs.WorldXYPlane(), 6, 2, False)
2569 | if rs.IsCone(cone):
2570 | cone_def = rs.SurfaceCone(cone)
2571 | rs.AddCone( cone_def[0], cone_def[1], cone_def[2], False )
2572 | See Also:
2573 |
2574 | """
2575 | surface = rhutil.coercesurface(surface_id, True)
2576 | rc, cone = surface.TryGetCone()
2577 | if not rc: return scriptcontext.errorhandler()
2578 | return cone.Plane, cone.Height, cone.Radius
2579 |
2580 |
2581 | def SurfaceCurvature(surface_id, parameter):
2582 | """Returns the curvature of a surface at a U,V parameter. See Rhino help
2583 | for details of surface curvature
2584 | Parameters:
2585 | surface_id (guid): the surface's identifier
2586 | parameter (number, number): u,v parameter
2587 | Returns:
2588 | tuple(point, vector, number, number, number, number, number): of curvature information
2589 | [0] point at specified U,V parameter
2590 | [1] normal direction
2591 | [2] maximum principal curvature
2592 | [3] maximum principal curvature direction
2593 | [4] minimum principal curvature
2594 | [5] minimum principal curvature direction
2595 | [6] gaussian curvature
2596 | [7] mean curvature
2597 | None: if not successful, or on error
2598 | Example:
2599 | import rhinoscriptsyntax as rs
2600 | srf = rs.GetObject("Select a surface", rs.filter.surface)
2601 | if rs.IsSurface(srf):
2602 | point = rs.GetPointOnSurface(srf, "Pick a test point")
2603 | if point:
2604 | param = rs.SurfaceClosestPoint(srf, point)
2605 | if param:
2606 | data = rs.SurfaceCurvature(srf, param)
2607 | if data:
2608 | print("Surface curvature evaluation at parameter {}:".format(param))
2609 | print(" 3-D Point:{}".format(data[0]))
2610 | print(" 3-D Normal:{}".format(data[1]))
2611 | print(" Maximum principal curvature: {} {}".format(data[2], data[3]))
2612 | print(" Minimum principal curvature: {} {}".format(data[4], data[5]))
2613 | print(" Gaussian curvature:{}".format(data[6]))
2614 | print(" Mean curvature:{}".format(data[7]))
2615 | See Also:
2616 | CurveCurvature
2617 | """
2618 | surface = rhutil.coercesurface(surface_id, True)
2619 | if len(parameter)<2: return scriptcontext.errorhandler()
2620 | c = surface.CurvatureAt(parameter[0], parameter[1])
2621 | if c is None: return scriptcontext.errorhandler()
2622 | return c.Point, c.Normal, c.Kappa(0), c.Direction(0), c.Kappa(1), c.Direction(1), c.Gaussian, c.Mean
2623 |
2624 |
2625 | def SurfaceCylinder(surface_id):
2626 | """Returns the definition of a cylinder surface
2627 | Parameters:
2628 | surface_id (guid): the surface's identifier
2629 | Returns:
2630 | tuple(plane, number, number): of the cylinder plane, height, radius on success
2631 | None: on error
2632 | Example:
2633 | import rhinoscriptsyntax as rs
2634 | cylinder = rs.AddCylinder(rs.WorldXYPlane(), 6, 2, False)
2635 | if rs.IsCylinder(cylinder):
2636 | plane, height, radius = rs.SurfaceCylinder(cylinder)
2637 | rs.AddCylinder(plane, height, radius, False)
2638 | See Also:
2639 | SurfaceSphere
2640 | """
2641 | surface = rhutil.coercesurface(surface_id, True)
2642 | tol = scriptcontext.doc.ModelAbsoluteTolerance
2643 | rc, cylinder = surface.TryGetFiniteCylinder(tol)
2644 | if rc:
2645 | return cylinder.BasePlane, cylinder.TotalHeight, cylinder.Radius
2646 |
2647 |
2648 | def SurfaceDegree(surface_id, direction=2):
2649 | """Returns the degree of a surface object in the specified direction
2650 | Parameters:
2651 | surface_id (guid): the surface's identifier
2652 | direction (number, optional): The degree U, V direction
2653 | 0 = U
2654 | 1 = V
2655 | 2 = both
2656 | Returns:
2657 | number: Single number if `direction` = 0 or 1
2658 | tuple(number, number): of two values if `direction` = 2
2659 | None: on error
2660 | Example:
2661 | import rhinoscriptsyntax as rs
2662 | obj = rs.GetObject("Select a surface", rs.filter.surface)
2663 | if rs.IsSurface(obj):
2664 | print("Degree in U direction: {}".format(rs.SurfaceDegree(obj, 0)))
2665 | print("Degree in V direction: {}".format(rs.SurfaceDegree(obj, 1)))
2666 | See Also:
2667 | IsSurface
2668 | SurfaceDomain
2669 | """
2670 | surface = rhutil.coercesurface(surface_id, True)
2671 | if direction==0 or direction==1: return surface.Degree(direction)
2672 | if direction==2: return surface.Degree(0), surface.Degree(1)
2673 | return scriptcontext.errorhandler()
2674 |
2675 |
2676 | def SurfaceDomain(surface_id, direction):
2677 | """Returns the domain of a surface object in the specified direction.
2678 | Parameters:
2679 | surface_id (guid): the surface's identifier
2680 | direction (number): domain direction 0 = U, or 1 = V
2681 | Returns:
2682 | list(number, number): containing the domain interval in the specified direction
2683 | None: if not successful, or on error
2684 | Example:
2685 | import rhinoscriptsyntax as rs
2686 | object = rs.GetObject("Select a surface", rs.filter.surface)
2687 | if rs.IsSurface(object):
2688 | domainU = rs.SurfaceDomain(object, 0)
2689 | domainV = rs.SurfaceDomain(object, 1)
2690 | print("Domain in U direction: {}".format(domainU))
2691 | print("Domain in V direction: {}".format(domainV))
2692 | See Also:
2693 | IsSurface
2694 | SurfaceDegree
2695 | """
2696 | if direction!=0 and direction!=1: return scriptcontext.errorhandler()
2697 | surface = rhutil.coercesurface(surface_id, True)
2698 | domain = surface.Domain(direction)
2699 | return domain.T0, domain.T1
2700 |
2701 |
2702 | def SurfaceEditPoints(surface_id, return_parameters=False, return_all=True):
2703 | """Returns the edit, or Greville points of a surface object. For each
2704 | surface control point, there is a corresponding edit point
2705 | Parameters:
2706 | surface_id (guid): the surface's identifier
2707 | return_parameters (bool, optional): If False, edit points are returned as a list of
2708 | 3D points. If True, edit points are returned as a list of U,V surface
2709 | parameters
2710 | return_all (bool, options): If True, all surface edit points are returned. If False,
2711 | the function will return surface edit points based on whether or not the
2712 | surface is closed or periodic
2713 | Returns:
2714 | list(point, ...): if return_parameters is False, a list of 3D points
2715 | list((number, number), ...): if return_parameters is True, a list of U,V parameters
2716 | None: on error
2717 | Example:
2718 | import rhinoscriptsyntax as rs
2719 | obj = rs.GetObject("Select a surface")
2720 | if rs.IsSurface(obj):
2721 | points = rs.SurfaceEditPoints(obj)
2722 | if points: rs.AddPointCloud(points)
2723 | See Also:
2724 | IsSurface
2725 | SurfacePointCount
2726 | SurfacePoints
2727 | """
2728 | surface = rhutil.coercesurface(surface_id, True)
2729 | nurb = surface.ToNurbsSurface()
2730 | if not nurb: return scriptcontext.errorhandler()
2731 | ufirst = 0
2732 | ulast = nurb.Points.CountU
2733 | vfirst = 0
2734 | vlast = nurb.Points.CountV
2735 | if not return_all:
2736 | if nurb.IsClosed(0): ulast = nurb.Points.CountU-1
2737 | if nurb.IsPeriodic(0):
2738 | degree = nurb.Degree(0)
2739 | ufirst = degree/2
2740 | ulast = nurb.Points.CountU-degree+ufirst
2741 | if nurb.IsClosed(1): vlast = nurb.Points.CountV-1
2742 | if nurb.IsPeriodic(1):
2743 | degree = nurb.Degree(1)
2744 | vfirst = degree/2
2745 | vlast = nurb.Points.CountV-degree+vfirst
2746 | rc = []
2747 | for u in range(ufirst, ulast):
2748 | for v in range(vfirst, vlast):
2749 | pt = nurb.Points.GetGrevillePoint(u,v)
2750 | if not return_parameters: pt = nurb.PointAt(pt.X, pt.Y)
2751 | rc.append(pt)
2752 | return rc
2753 |
2754 |
2755 | def SurfaceEvaluate(surface_id, parameter, derivative):
2756 | """A general purpose surface evaluator
2757 | Parameters:
2758 | surface_id (guid): the surface's identifier
2759 | parameter ([number, number]): u,v parameter to evaluate
2760 | derivative (number): number of derivatives to evaluate
2761 | Returns:
2762 | list((point, vector, ...), ...): list length (derivative+1)*(derivative+2)/2 if successful. The elements are as follows:
2763 | Element Description
2764 | [0] The 3-D point.
2765 | [1] The first derivative.
2766 | [2] The first derivative.
2767 | [3] The second derivative.
2768 | [4] The second derivative.
2769 | [5] The second derivative.
2770 | [6] etc...
2771 | None: If not successful, or on error.
2772 | Example:
2773 | import rhinoscriptsyntax as rs
2774 | def TestSurfaceEvaluate():
2775 | srf = rs.GetObject("Select surface to evaluate", rs.filter.surface, True)
2776 | if srf is None: return
2777 | point = rs.GetPointOnSurface(srf, "Point to evaluate")
2778 | if point is None: return
2779 | der = rs.GetInteger("Number of derivatives to evaluate", 1, 1)
2780 | if der is None: return
2781 | uv = rs.SurfaceClosestPoint(srf, point)
2782 | res = rs.SurfaceEvaluate(srf, uv, der)
2783 | if res is None:
2784 | print("Failed to evaluate surface.")
2785 | return
2786 | for i,r in enumerate(res):
2787 | print("{} = {}".format(i, r))
2788 | TestSurfaceEvaluate()
2789 | See Also:
2790 | EvaluateSurface
2791 | """
2792 | surface = rhutil.coercesurface(surface_id, True)
2793 | success, point, der = surface.Evaluate(parameter[0], parameter[1], derivative)
2794 | if not success: return scriptcontext.errorhandler()
2795 | rc = [point]
2796 | if der:
2797 | for d in der: rc.append(d)
2798 | return rc
2799 |
2800 |
2801 | def SurfaceFrame(surface_id, uv_parameter):
2802 | """Returns a plane based on the normal, u, and v directions at a surface
2803 | U,V parameter
2804 | Parameters:
2805 | surface_id (guid): the surface's identifier
2806 | uv_parameter ([number, number]): u,v parameter to evaluate
2807 | Returns:
2808 | plane: plane on success
2809 | None: on error
2810 | Example:
2811 | import rhinoscriptsyntax as rs
2812 | surface = rs.GetSurfaceObject("Select a surface")
2813 | if surface:
2814 | plane = rs.SurfaceFrame(surface[0], surface[4])
2815 | rs.ViewCPlane(None, plane)
2816 | See Also:
2817 | EvaluateSurface
2818 | SurfaceClosestPoint
2819 | SurfaceNormal
2820 | """
2821 | surface = rhutil.coercesurface(surface_id, True)
2822 | rc, frame = surface.FrameAt(uv_parameter[0], uv_parameter[1])
2823 | if rc: return frame
2824 |
2825 |
2826 | def SurfaceIsocurveDensity(surface_id, density=None):
2827 | """Returns or sets the isocurve density of a surface or polysurface object.
2828 | An isoparametric curve is a curve of constant U or V value on a surface.
2829 | Rhino uses isocurves and surface edge curves to visualize the shape of a
2830 | NURBS surface
2831 | Parameters:
2832 | surface_id (guid): the surface's identifier
2833 | density (number, optional): the isocurve wireframe density. The possible values are
2834 | -1: Hides the surface isocurves
2835 | 0: Display boundary and knot wires
2836 | 1: Display boundary and knot wires and one interior wire if there
2837 | are no interior knots
2838 | >=2: Display boundary and knot wires and (N+1) interior wires
2839 | Returns:
2840 | number: If density is not specified, then the current isocurve density if successful
2841 | number: If density is specified, the the previous isocurve density if successful
2842 | None: on error
2843 | Example:
2844 | import rhinoscriptsyntax as rs
2845 | obj = rs.GetObject("Select a surface", rs.filter.surface | rs.filter.polysurface)
2846 | if obj: rs.SurfaceIsocurveDensity( obj, 8 )
2847 | See Also:
2848 | IsPolysurface
2849 | IsSurface
2850 | """
2851 | rhino_object = rhutil.coercerhinoobject(surface_id, True, True)
2852 | if not isinstance(rhino_object, Rhino.DocObjects.BrepObject):
2853 | return scriptcontext.errorhandler()
2854 | rc = rhino_object.Attributes.WireDensity
2855 | if density is not None:
2856 | if density<0: density = -1
2857 | rhino_object.Attributes.WireDensity = density
2858 | rhino_object.CommitChanges()
2859 | scriptcontext.doc.Views.Redraw()
2860 | return rc
2861 |
2862 |
2863 | def SurfaceKnotCount(surface_id):
2864 | """Returns the control point count of a surface
2865 | surface_id = the surface's identifier
2866 | Parameters:
2867 | surface_id (guid): the surface object's identifier
2868 | Returns:
2869 | list(number, number): a list containing (U count, V count) on success
2870 | Example:
2871 | import rhinoscriptsyntax as rs
2872 | obj = rs.GetObject("Select a surface")
2873 | if rs.IsSurface(obj):
2874 | count = rs.SurfaceKnotCount(obj)
2875 | print("Knot count in U direction: {}".format(count[0]))
2876 | print("Knot count in V direction: {}".format(count[1]))
2877 | See Also:
2878 | IsSurface
2879 | SurfaceKnots
2880 | """
2881 | surface = rhutil.coercesurface(surface_id, True)
2882 | ns = surface.ToNurbsSurface()
2883 | return ns.KnotsU.Count, ns.KnotsV.Count
2884 |
2885 |
2886 | def SurfaceKnots(surface_id):
2887 | """Returns the knots, or knot vector, of a surface object.
2888 | Parameters:
2889 | surface_id (guid): the surface's identifier
2890 | Returns:
2891 | list(number, number): knot values of the surface if successful. The list will
2892 | contain the following information:
2893 | Element Description
2894 | [0] Knot vector in U direction
2895 | [1] Knot vector in V direction
2896 | None: if not successful, or on error.
2897 | Example:
2898 | import rhinoscriptsyntax as rs
2899 | obj = rs.GetObject("Select a surface")
2900 | if rs.IsSurface(obj):
2901 | knots = rs.SurfaceKnots(obj)
2902 | if knots:
2903 | vector = knots[0]
2904 | print("Knot vector in U direction")
2905 | for item in vector: print("Surface knot value: {}".format(item))
2906 | vector = knots[1]
2907 | print("Knot vector in V direction")
2908 | for item in vector: print("Surface knot value: {}".format(item))
2909 | See Also:
2910 | IsSurface
2911 | SurfaceKnotCount
2912 | """
2913 | surface = rhutil.coercesurface(surface_id, True)
2914 | nurb_surf = surface.ToNurbsSurface()
2915 | if nurb_surf is None: return scriptcontext.errorhandler()
2916 | s_knots = [knot for knot in nurb_surf.KnotsU]
2917 | t_knots = [knot for knot in nurb_surf.KnotsV]
2918 | if not s_knots or not t_knots: return scriptcontext.errorhandler()
2919 | return s_knots, t_knots
2920 |
2921 |
2922 | def SurfaceNormal(surface_id, uv_parameter):
2923 | """Returns 3D vector that is the normal to a surface at a parameter
2924 | Parameters:
2925 | surface_id (guid): the surface's identifier
2926 | uv_parameter ([number, number]): the uv parameter to evaluate
2927 | Returns:
2928 | vector: Normal vector on success
2929 | Example:
2930 | import rhinoscriptsyntax as rs
2931 | obj = rs.GetObject("Select a surface", rs.filter.surface)
2932 | if obj:
2933 | point = rs.GetPointOnSurface(obj)
2934 | if point:
2935 | param = rs.SurfaceClosestPoint(obj, point)
2936 | normal = rs.SurfaceNormal(obj, param)
2937 | rs.AddPoints( [point, point + normal] )
2938 | See Also:
2939 | SurfaceClosestPoint
2940 | SurfaceDomain
2941 | """
2942 | surface = rhutil.coercesurface(surface_id, True)
2943 | return surface.NormalAt(uv_parameter[0], uv_parameter[1])
2944 |
2945 |
2946 | def SurfaceNormalizedParameter(surface_id, parameter):
2947 | """Converts surface parameter to a normalized surface parameter; one that
2948 | ranges between 0.0 and 1.0 in both the U and V directions
2949 | Parameters:
2950 | surface_id (guid) the surface's identifier
2951 | parameter ([number, number]): the surface parameter to convert
2952 | Returns:
2953 | list(number, number): normalized surface parameter if successful
2954 | None: on error
2955 | Example:
2956 | import rhinoscriptsyntax as rs
2957 | obj = rs.GetObject("Select surface")
2958 | if rs.IsSurface(obj):
2959 | domain_u = rs.SurfaceDomain(obj, 0)
2960 | domain_v = rs.SurfaceDomain(obj, 1)
2961 | parameter = (domain_u[1] + domain_u[0]) / 2.0, (domain_v[1] + domain_v[0]) / 2.0
2962 | print("Surface parameter: {}".format(parameter))
2963 | normalized = rs.SurfaceNormalizedParameter(obj, parameter)
2964 | print("Normalized parameter: {}".format(normalized))
2965 | See Also:
2966 | SurfaceDomain
2967 | SurfaceParameter
2968 | """
2969 | surface = rhutil.coercesurface(surface_id, True)
2970 | u_domain = surface.Domain(0)
2971 | v_domain = surface.Domain(1)
2972 | if parameter[0]<u_domain.Min or parameter[0]>u_domain.Max:
2973 | return scriptcontext.errorhandler()
2974 | if parameter[1]<v_domain.Min or parameter[1]>v_domain.Max:
2975 | return scriptcontext.errorhandler()
2976 | u = u_domain.NormalizedParameterAt(parameter[0])
2977 | v = v_domain.NormalizedParameterAt(parameter[1])
2978 | return u,v
2979 |
2980 |
2981 | def SurfaceParameter(surface_id, parameter):
2982 | """Converts normalized surface parameter to a surface parameter; or
2983 | within the surface's domain
2984 | Parameters:
2985 | surface_id (guid): the surface's identifier
2986 | parameter ([number, number]): the normalized parameter to convert
2987 | Returns:
2988 | tuple(number, number): surface parameter on success
2989 | Example:
2990 | import rhinoscriptsyntax as rs
2991 | obj = rs.GetObject("Select surface")
2992 | if obj:
2993 | normalized = (0.5, 0.5)
2994 | print("Normalized parameter: {}".format(normalized))
2995 | parameter = rs.SurfaceParameter(obj, normalized)
2996 | print("Surface parameter: {}".format(parameter))
2997 | See Also:
2998 | SurfaceDomain
2999 | SurfaceNormalizedParameter
3000 | """
3001 | surface = rhutil.coercesurface(surface_id, True)
3002 | x = surface.Domain(0).ParameterAt(parameter[0])
3003 | y = surface.Domain(1).ParameterAt(parameter[1])
3004 | return x, y
3005 |
3006 |
3007 | def SurfacePointCount(surface_id):
3008 | """Returns the control point count of a surface
3009 | surface_id = the surface's identifier
3010 | Parameters:
3011 | surface_id (guid): the surface object's identifier
3012 | Returns:
3013 | list(number, number): THe number of control points in UV direction. (U count, V count)
3014 | Example:
3015 | import rhinoscriptsyntax as rs
3016 | obj = rs.GetObject("Select a surface")
3017 | if rs.IsSurface(obj):
3018 | count = rs.SurfacePointCount(obj)
3019 | print("Point count in U direction: {}".format(count[0]))
3020 | print("Point count in V direction: {}".format(count[1]))
3021 | See Also:
3022 | IsSurface
3023 | SurfacePoints
3024 | """
3025 | surface = rhutil.coercesurface(surface_id, True)
3026 | ns = surface.ToNurbsSurface()
3027 | return ns.Points.CountU, ns.Points.CountV
3028 |
3029 |
3030 | def SurfacePoints(surface_id, return_all=True):
3031 | """Returns the control points, or control vertices, of a surface object
3032 | Parameters:
3033 | surface_id (guid): the surface's identifier
3034 | return_all (bool, optional): If True all surface edit points are returned. If False,
3035 | the function will return surface edit points based on whether or not
3036 | the surface is closed or periodic
3037 | Returns:
3038 | list(point, ...): the control points if successful
3039 | None: on error
3040 | Example:
3041 | import rhinoscriptsyntax as rs
3042 | def PrintControlPoints():
3043 | surface = rs.GetObject("Select surface", rs.filter.surface)
3044 | points = rs.SurfacePoints(surface)
3045 | if points is None: return
3046 | count = rs.SurfacePointCount(surface)
3047 | i = 0
3048 | for u in range(count[0]):
3049 | for v in range(count[1]):
3050 | print("CV[{}".format(u, ",", v, "] = ", points[i]))
3051 | i += 1
3052 | PrintControlPoints()
3053 | See Also:
3054 | IsSurface
3055 | SurfacePointCount
3056 | """
3057 | surface = rhutil.coercesurface(surface_id, True)
3058 | ns = surface.ToNurbsSurface()
3059 | if ns is None: return scriptcontext.errorhandler()
3060 | rc = []
3061 | for u in range(ns.Points.CountU):
3062 | for v in range(ns.Points.CountV):
3063 | pt = ns.Points.GetControlPoint(u,v)
3064 | rc.append(pt.Location)
3065 | return rc
3066 |
3067 |
3068 | def SurfaceTorus(surface_id):
3069 | """Returns the definition of a surface torus
3070 | Parameters:
3071 | surface_id (guid): the surface's identifier
3072 | Returns:
3073 | tuple(plane, number, number): containing the definition of the torus if successful
3074 | [0] the base plane of the torus
3075 | [1] the major radius of the torus
3076 | [2] the minor radius of the torus
3077 | None: on error
3078 | Example:
3079 | import rhinoscriptsyntax as rs
3080 | torus = rs.AddTorus(rs.WorldXYPlane(), 6, 2)
3081 | if rs.IsTorus(torus):
3082 | torus_def = rs.SurfaceTorus(torus)
3083 | rs.AddTorus( torus_def[0], torus_def[1], torus_def[2] )
3084 | See Also:
3085 |
3086 | """
3087 | surface = rhutil.coercesurface(surface_id, True)
3088 | rc, torus = surface.TryGetTorus()
3089 | if rc: return torus.Plane, torus.MajorRadius, torus.MinorRadius
3090 |
3091 |
3092 | def SurfaceVolume(object_id):
3093 | """Calculates volume of a closed surface or polysurface
3094 | Parameters:
3095 | object_id (guid): the surface's identifier
3096 | Returns:
3097 | list(number, tuple(X, Y, Z): volume data returned (Volume, Error bound) on success
3098 | None: on error
3099 | Example:
3100 | import rhinoscriptsyntax as rs
3101 | obj = rs.GetObject("Select a surface", rs.filter.polysurface)
3102 | if rs.IsPolysurfaceClosed(obj):
3103 | massprop = rs.SurfaceVolume(obj)
3104 | if massprop:
3105 | print("The polysurface volume is: {}".format(massprop[0]))
3106 | See Also:
3107 | SurfaceVolume
3108 | SurfaceVolumeCentroid
3109 | SurfaceVolumeMoments
3110 | """
3111 | vmp = __GetMassProperties(object_id, False)
3112 | if vmp: return vmp.Volume, vmp.VolumeError
3113 |
3114 |
3115 | def SurfaceVolumeCentroid(object_id):
3116 | """Calculates volume centroid of a closed surface or polysurface
3117 | Parameters:
3118 | object_id (guid): the surface's identifier
3119 | Returns:
3120 | list(point, tuple(X, Y, Z): volume data returned (Volume Centriod, Error bound) on success
3121 | None: on error
3122 | Example:
3123 | import rhinoscriptsyntax as rs
3124 | obj = rs.GetObject("Select a surface", rs.filter.polysurface)
3125 | if rs.IsPolysurfaceClosed(obj):
3126 | massprop= rs.SurfaceVolumeCentroid(obj)
3127 | if massprop: rs.AddPoint( massprop[0] )
3128 | See Also:
3129 | SurfaceVolume
3130 | SurfaceVolumeMoments
3131 | """
3132 | vmp = __GetMassProperties(object_id, False)
3133 | if vmp: return vmp.Centroid, vmp.CentroidError
3134 |
3135 |
3136 | def SurfaceVolumeMoments(surface_id):
3137 | """Calculates volume moments of inertia of a surface or polysurface object.
3138 | For more information, see Rhino help for "Mass Properties calculation details"
3139 | Parameters:
3140 | surface_id (guid): the surface's identifier
3141 | Returns:
3142 | list(tuple(number, number,number), ...): of moments and error bounds in tuple(X, Y, Z) - see help topic
3143 | Index Description
3144 | [0] First Moments.
3145 | [1] The absolute (+/-) error bound for the First Moments.
3146 | [2] Second Moments.
3147 | [3] The absolute (+/-) error bound for the Second Moments.
3148 | [4] Product Moments.
3149 | [5] The absolute (+/-) error bound for the Product Moments.
3150 | [6] Area Moments of Inertia about the World Coordinate Axes.
3151 | [7] The absolute (+/-) error bound for the Area Moments of Inertia about World Coordinate Axes.
3152 | [8] Area Radii of Gyration about the World Coordinate Axes.
3153 | [9] The absolute (+/-) error bound for the Area Radii of Gyration about World Coordinate Axes.
3154 | [10] Area Moments of Inertia about the Centroid Coordinate Axes.
3155 | [11] The absolute (+/-) error bound for the Area Moments of Inertia about the Centroid Coordinate Axes.
3156 | [12] Area Radii of Gyration about the Centroid Coordinate Axes.
3157 | [13] The absolute (+/-) error bound for the Area Radii of Gyration about the Centroid Coordinate Axes.
3158 | None: on error
3159 | Example:
3160 | import rhinoscriptsyntax as rs
3161 | obj = rs.GetObject("Select a surface", rs.filter.polysurface)
3162 | if rs.IsPolysurfaceClosed(obj):
3163 | massprop = rs.SurfaceVolumeMoments(obj)
3164 | if massprop:
3165 | print("Volume Moments of Inertia about the World Coordinate Axes: {}".format(massprop[6]))
3166 | See Also:
3167 | SurfaceVolume
3168 | SurfaceVolumeCentroid
3169 | """
3170 | return __AreaMomentsHelper(surface_id, False)
3171 |
3172 |
3173 | def SurfaceWeights(object_id):
3174 | """Returns list of weight values assigned to the control points of a surface.
3175 | The number of weights returned will be equal to the number of control points
3176 | in the U and V directions.
3177 | Parameters:
3178 | object_id (guid): the surface's identifier
3179 | Returns:
3180 | list(number, ...): point weights.
3181 | None: on error
3182 | Example:
3183 | import rhinoscriptsyntax as rs
3184 | surf = rs.GetObject("Select a surface")
3185 | if rs.IsSurface(surf):
3186 | weights = rs.SurfaceWeights(surf)
3187 | if weights:
3188 | for w in weights:
3189 | print("Surface control point weight value:{}".format(w))
3190 | See Also:
3191 | IsSurface
3192 | SurfacePointCount
3193 | SurfacePoints
3194 | """
3195 | surface = rhutil.coercesurface(object_id, True)
3196 | ns = surface.ToNurbsSurface()
3197 | if ns is None: return scriptcontext.errorhandler()
3198 | rc = []
3199 | for u in range(ns.Points.CountU):
3200 | for v in range(ns.Points.CountV):
3201 | pt = ns.Points.GetControlPoint(u,v)
3202 | rc.append(pt.Weight)
3203 | return rc
3204 |
3205 |
3206 | def TrimBrep(object_id, cutter, tolerance=None):
3207 | """Trims a surface using an oriented cutter
3208 | Parameters:
3209 | object_id (guid): surface or polysurface identifier
3210 | cutter (guid|plane): surface, polysurface, or plane performing the trim
3211 | tolerance (number, optional): trimming tolerance. If omitted, the document's absolute
3212 | tolerance is used
3213 | Returns:
3214 | list(guid, ...): identifiers of retained components on success
3215 | Example:
3216 | import rhinoscriptsyntax as rs
3217 | filter = rs.filter.surface + rs.filter.polysurface
3218 | obj = rs.GetObject("Select surface or polysurface to trim", filter)
3219 | if obj:
3220 | cutter = rs.GetObject("Select cutting surface or polysurface", filter)
3221 | if cutter:
3222 | rs.TrimBrep(obj,cutter)
3223 | See Also:
3224 | TrimSurface
3225 | """
3226 | brep = rhutil.coercebrep(object_id, True)
3227 | brep_cutter = rhutil.coercebrep(cutter, False)
3228 | if brep_cutter: cutter = brep_cutter
3229 | else: cutter = rhutil.coerceplane(cutter, True)
3230 | if tolerance is None: tolerance = scriptcontext.doc.ModelAbsoluteTolerance
3231 | breps = brep.Trim(cutter, tolerance)
3232 | rhid = rhutil.coerceguid(object_id, False)
3233 |
3234 | attrs = None
3235 | if len(breps) > 1:
3236 | rho = rhutil.coercerhinoobject(object_id, False)
3237 | if rho: attrs = rho.Attributes
3238 |
3239 | if rhid:
3240 | rc = []
3241 | for i in range(len(breps)):
3242 | if i==0:
3243 | scriptcontext.doc.Objects.Replace(rhid, breps[i])
3244 | rc.append(rhid)
3245 | else:
3246 | rc.append(scriptcontext.doc.Objects.AddBrep(breps[i], attrs))
3247 | else:
3248 | rc = [scriptcontext.doc.Objects.AddBrep(brep) for brep in breps]
3249 | scriptcontext.doc.Views.Redraw()
3250 | return rc
3251 |
3252 |
3253 | def TrimSurface( surface_id, direction, interval, delete_input=False):
3254 | """Remove portions of the surface outside of the specified interval
3255 | Parameters:
3256 | surface_id (guid): surface identifier
3257 | direction (number, optional): 0(U), 1(V), or 2(U and V)
3258 | interval (interval): sub section of the surface to keep.
3259 | If both U and V then a list or tuple of 2 intervals
3260 | delete_input (bool, optional): should the input surface be deleted
3261 | Returns:
3262 | guid: new surface identifier on success
3263 | Example:
3264 | import rhinoscriptsyntax as rs
3265 | surface = rs.GetObject("Select surface to split", rs.filter.surface)
3266 | if surface:
3267 | domain_u = rs.SurfaceDomain(surface, 0)
3268 | domain_u[0] = (domain_u[1] - domain_u[0]) * 0.25
3269 | rs.TrimSurface( surface, 0, domain_u, True )
3270 | See Also:
3271 |
3272 | """
3273 | surface = rhutil.coercesurface(surface_id, True)
3274 | u = surface.Domain(0)
3275 | v = surface.Domain(1)
3276 | if direction==0:
3277 | u[0] = interval[0]
3278 | u[1] = interval[1]
3279 | elif direction==1:
3280 | v[0] = interval[0]
3281 | v[1] = interval[1]
3282 | else:
3283 | u[0] = interval[0][0]
3284 | u[1] = interval[0][1]
3285 | v[0] = interval[1][0]
3286 | v[1] = interval[1][1]
3287 | new_surface = surface.Trim(u,v)
3288 | if new_surface:
3289 | rc = scriptcontext.doc.Objects.AddSurface(new_surface)
3290 | if delete_input: scriptcontext.doc.Objects.Delete(rhutil.coerceguid(surface_id), True)
3291 | scriptcontext.doc.Views.Redraw()
3292 | return rc
3293 |
3294 |
3295 | def UnrollSurface(surface_id, explode=False, following_geometry=None, absolute_tolerance=None, relative_tolerance=None):
3296 | """Flattens a developable surface or polysurface
3297 | Parameters:
3298 | surface_id (guid): the surface's identifier
3299 | explode (bool, optional): If True, the resulting surfaces ar not joined
3300 | following_geometry ({guid, ...]): List of curves, dots, and points which
3301 | should be unrolled with the surface
3302 | Returns:
3303 | list(guid, ...): of unrolled surface ids
3304 | tuple((guid, ...),(guid, ...)): if following_geometry is not None, a tuple
3305 | [1] is the list of unrolled surface ids
3306 | [2] is the list of unrolled following geometry
3307 | Example:
3308 | import rhinoscriptsyntax as rs
3309 | surface = rs.GetObject("Select surface or polysurface to unroll", rs.filter.surface + rs.filter.polysurface)
3310 | if surface: rs.UnrollSurface(surface)
3311 | See Also:
3312 |
3313 | """
3314 | brep = rhutil.coercebrep(surface_id, True)
3315 | unroll = Rhino.Geometry.Unroller(brep)
3316 | unroll.ExplodeOutput = explode
3317 | if relative_tolerance is None: relative_tolerance = scriptcontext.doc.ModelRelativeTolerance
3318 | if absolute_tolerance is None: absolute_tolerance = scriptcontext.doc.ModelAbsoluteTolerance
3319 | unroll.AbsoluteTolerance = absolute_tolerance
3320 | unroll.RelativeTolerance = relative_tolerance
3321 | if following_geometry:
3322 | for id in following_geometry:
3323 | geom = rhutil.coercegeometry(id)
3324 | unroll.AddFollowingGeometry(geom)
3325 | breps, curves, points, dots = unroll.PerformUnroll()
3326 | if not breps: return None
3327 | rc = [scriptcontext.doc.Objects.AddBrep(brep) for brep in breps]
3328 | new_following = []
3329 | for curve in curves:
3330 | id = scriptcontext.doc.Objects.AddCurve(curve)
3331 | new_following.append(id)
3332 | for point in points:
3333 | id = scriptcontext.doc.Objects.AddPoint(point)
3334 | new_following.append(id)
3335 | for dot in dots:
3336 | id = scriptcontext.doc.Objects.AddTextDot(dot)
3337 | new_following.append(id)
3338 | scriptcontext.doc.Views.Redraw()
3339 | if following_geometry: return rc, new_following
3340 | return rc
3341 |
3342 |
3343 | def ChangeSurfaceDegree(object_id, degree):
3344 | """Changes the degree of a surface object. For more information see the Rhino help file for the ChangeDegree command.
3345 | Parameters:
3346 | object_id (guid): the object's identifier.
3347 | degree ([number, number]) two integers, specifying the degrees for the U V directions
3348 | Returns:
3349 | bool: True of False indicating success or failure.
3350 | None: on failure.
3351 | Example:
3352 |
3353 | See Also:
3354 | IsSurface
3355 | """
3356 | object = rhutil.coercerhinoobject(object_id)
3357 | if not object: return None
3358 | obj_ref = Rhino.DocObjects.ObjRef(object)
3359 |
3360 | surface = obj_ref.Surface()
3361 | if not surface: return None
3362 |
3363 | if not isinstance(surface, Rhino.Geometry.NurbsSurface):
3364 | surface = surface.ToNurbsSurface() # could be a Surface or BrepFace
3365 |
3366 | max_nurbs_degree = 11
3367 | if degree[0] < 1 or degree[0] > max_nurbs_degree or \
3368 | degree[1] < 1 or degree[1] > max_nurbs_degree or \
3369 | (surface.Degree(0) == degree[0] and surface.Degree(1) == degree[1]):
3370 | return None
3371 |
3372 | r = False
3373 | if surface.IncreaseDegreeU(degree[0]):
3374 | if surface.IncreaseDegreeV(degree[1]):
3375 | r = scriptcontext.doc.Objects.Replace(object_id, surface)
3376 | return r
3377 |
```