/Scripts/rhinoscript/surface.py

http://github.com/mcneel/rhinopython · Python · 3346 lines · 2528 code · 8 blank · 810 comment · 255 complexity · f807e40fc8ae9ef505581397f8f1e264 MD5 · raw file

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