/Scripts/rhinoscript/surface.py

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

Large files are truncated click here to view the full 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. R