def XformChangeBasis(initial_plane, final_plane): "Returns a change of basis transformation matrix or None on error" initial_plane = rhutil.coerceplane(initial_plane, True) final_plane = rhutil.coerceplane(final_plane, True) xform = Rhino.Geometry.Transform.ChangeBasis(initial_plane, final_plane) if not xform.IsValid: return scriptcontext.errorhandler() return xform
def PlaneCircleIntersection(plane, circle_plane, circle_radius): """Calculates the intersection of a plane and a circle Parameters: plane = the plane to intersect circle_plane = plane of the circle. origin of the plane is the center of the circle circle_radius = radius of the circle Returns: intersection type and up to two points: [0, point] for a tangent intersection [1, point1, point2] for a secant intersection [2] if the circle lies in the plane None if there is no intersection or on error """ plane = rhutil.coerceplane(plane, True) circle_plane = rhutil.coerceplane(circle_plane, True) circle = Rhino.Geometry.Circle(circle_plane, circle_radius) rc, t1, t2 = Rhino.Geometry.Intersect.Intersection.PlaneCircle( plane, circle) if rc == Rhino.Geometry.Intersect.PlaneCircleIntersection.Tangent: return (0, circle.PointAt(t1)) if rc == Rhino.Geometry.Intersect.PlaneCircleIntersection.Secant: return (1, circle.PointAt(t1), circle.PointAt(t2)) if rc == Rhino.Geometry.Intersect.PlaneCircleIntersection.Coincident: return (2)
def XformChangeBasis(initial_plane, final_plane): """Returns a change of basis transformation matrix or None on error Parameters: initial_plane = the initial plane final_plane = the final plane Returns: The 4x4 transformation matrix if successful, otherwise None Example: import rhinoscriptsyntax as rs import math objs = rs.GetObjects("Select objects to shear") if objs: cplane = rs.ViewCPlane() cob = rs.XformChangeBasis(rs.WorldXYPlane(), cplane) shear2d = rs.XformIdentity() shear2d[0,2] = math.tan(math.radians(45.0)) cob_inverse = rs.XformChangeBasis(cplane, rs.WorldXYPlane()) temp = rs.XformMultiply(shear2d, cob) xform = rs.XformMultiply(cob_inverse, temp) rs.TransformObjects( objs, xform, True ) See Also: XformCPlaneToWorld XformWorldToCPlane """ initial_plane = rhutil.coerceplane(initial_plane, True) final_plane = rhutil.coerceplane(final_plane, True) xform = Rhino.Geometry.Transform.ChangeBasis(initial_plane, final_plane) if not xform.IsValid: return scriptcontext.errorhandler() return xform
def XformChangeBasis(initial_plane, final_plane): """Returns a change of basis transformation matrix or None on error Parameters: initial_plane (plane): the initial plane final_plane (plane): the final plane Returns: transform: The 4x4 transformation matrix if successful None: if not successful Example: import rhinoscriptsyntax as rs import math objs = rs.GetObjects("Select objects to shear") if objs: cplane = rs.ViewCPlane() cob = rs.XformChangeBasis(rs.WorldXYPlane(), cplane) shear2d = rs.XformIdentity() shear2d[0,2] = math.tan(math.radians(45.0)) cob_inverse = rs.XformChangeBasis(cplane, rs.WorldXYPlane()) temp = rs.XformMultiply(shear2d, cob) xform = rs.XformMultiply(cob_inverse, temp) rs.TransformObjects( objs, xform, True ) See Also: XformCPlaneToWorld XformWorldToCPlane """ initial_plane = rhutil.coerceplane(initial_plane, True) final_plane = rhutil.coerceplane(final_plane, True) xform = Rhino.Geometry.Transform.ChangeBasis(initial_plane, final_plane) if not xform.IsValid: return scriptcontext.errorhandler() return xform
def PlaneSphereIntersection(plane, sphere_plane, sphere_radius): """Calculates the intersection of a plane and a sphere Parameters: plane = the plane to intersect sphere_plane = equitorial plane of the sphere. origin of the plane is the center of the sphere sphere_radius = radius of the sphere Returns: list of intersection results - see help None on error Example: import rhinoscriptsyntax as rs plane = rs.WorldXYPlane() radius = 10 results = rs.PlaneSphereIntersection(plane, plane, radius) if results: if results[0]==0: rs.AddPoint(results[1]) else: rs.AddCircle(results[1], results[2]) See Also: IntersectPlanes LinePlaneIntersection PlanePlaneIntersection """ plane = rhutil.coerceplane(plane, True) sphere_plane = rhutil.coerceplane(sphere_plane, True) sphere = Rhino.Geometry.Sphere(sphere_plane, sphere_radius) rc, circle = Rhino.Geometry.Intersect.Intersection.PlaneSphere(plane, sphere) if rc==Rhino.Geometry.Intersect.PlaneSphereIntersection.Point: return 0, circle.Center if rc==Rhino.Geometry.Intersect.PlaneSphereIntersection.Circle: return 1, circle.Plane, circle.Radius
def IntersectPlanes(plane1, plane2, plane3): """Calculates the intersection of three planes Parameters: plane1 = the 1st plane to intersect plane2 = the 2nd plane to intersect plane3 = the 3rd plane to intersect Returns: Point3d on success None on error Example: import rhinoscriptsyntax as rs plane1 = rs.WorldXYPlane() plane2 = rs.WorldYZPlane() plane3 = rs.WorldZXPlane() point = rs.IntersectPlanes(plane1, plane2, plane3) if point: rs.AddPoint(point) See Also: LineLineIntersection LinePlaneIntersection PlanePlaneIntersection """ plane1 = rhutil.coerceplane(plane1, True) plane2 = rhutil.coerceplane(plane2, True) plane3 = rhutil.coerceplane(plane3, True) rc, point = Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(plane1, plane2, plane3) if rc: return point
def IntersectPlanes(plane1, plane2, plane3): """Calculates the intersection of three planes Returns: Point3d on success None on error """ plane1 = rhutil.coerceplane(plane1, True) plane2 = rhutil.coerceplane(plane2, True) plane3 = rhutil.coerceplane(plane3, True) rc, point = Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(plane1, plane2, plane3) if rc: return point
def PlanePlaneIntersection(plane1, plane2): """Calculates the intersection of two planes Paramters: plane1, plane2 = two planes Returns: two 3d points identifying the starting/ending points of the intersection None on error """ plane1 = rhutil.coerceplane(plane1, True) plane2 = rhutil.coerceplane(plane2, True) rc, line = Rhino.Geometry.Intersect.Intersection.PlanePlane(plane1, plane2) if rc: return line.From, line.To
def XformRotation1(initial_plane, final_plane): """Returns a rotation transformation that maps initial_plane to final_plane. The planes should be right hand orthonormal planes. Returns: The 4x4 transformation matrix. None on error. """ initial_plane = rhutil.coerceplane(initial_plane, True) final_plane = rhutil.coerceplane(final_plane, True) xform = Rhino.Geometry.Transform.PlaneToPlane(initial_plane, final_plane) if not xform.IsValid: return scriptcontext.errorhandler() return xform
def TextObjectPlane(object_id, plane=None): """Returns or modifies the plane used by a text object Parameters: object_id = the identifier of a text object plane[opt] = the new text object plane Returns: if a plane is not specified, the current plane if successful if a plane is specified, the previous plane if successful None if not successful, or on Error Example: import rhinoscriptsyntax as rs obj = rs.GetObject("Select text") if rs.IsText(obj): plane = rs.ViewCPlane("Top") rs.TextObjectPlane( obj, plane ) See Also: AddText IsText TextObjectFont TextObjectHeight TextObjectPoint TextObjectStyle TextObjectText """ annotation = rhutil.coercegeometry(object_id, True) if not isinstance(annotation, Rhino.Geometry.TextEntity): return scriptcontext.errorhandler() rc = annotation.Plane if plane: annotation.Plane = rhutil.coerceplane(plane, True) id = rhutil.coerceguid(object_id, True) scriptcontext.doc.Objects.Replace(id, annotation) scriptcontext.doc.Views.Redraw() return rc
def LineCylinderIntersection(line, cylinder_plane, cylinder_height, cylinder_radius): """Calculates the intersection of a line and a cylinder Parameters: line = the line to intersect cylinder_plane = base plane of the cylinder cylinder_height = height of the cylinder cylinder_radius = radius of the cylinder Returns: list of intersection points (0, 1, or 2 points) Example: import rhinoscriptsyntax as rs plane = rs.WorldXYPlane() line = (-10,0,0), (10,0,10) points = rs.LineCylinderIntersection(line, plane, cylinder_height=10, cylinder_radius=5) if points: for point in points: rs.AddPoint(point) See Also: LineLineIntersection LinePlaneIntersection LineSphereIntersection """ line = rhutil.coerceline(line, True) cylinder_plane = rhutil.coerceplane(cylinder_plane, True) circle = Rhino.Geometry.Circle( cylinder_plane, cylinder_radius ) if not circle.IsValid: raise ValueError("unable to create valid circle with given plane and radius") cyl = Rhino.Geometry.Cylinder( circle, cylinder_height ) if not cyl.IsValid: raise ValueError("unable to create valid cylinder with given circle and height") rc, pt1, pt2 = Rhino.Geometry.Intersect.Intersection.LineCylinder(line, cyl) if rc==Rhino.Geometry.Intersect.LineCylinderIntersection.None: return [] if rc==Rhino.Geometry.Intersect.LineCylinderIntersection.Single: return [pt1] return [pt1, pt2]
def AddPictureFrame(plane, filename, width=0.0, height=0.0, self_illumination=True, embed=False, use_alpha=False, make_mesh=False): """Creates a picture frame and adds it to the document. Parameters: plane = The plane in which the PictureFrame will be created. The bottom-left corner of picture will be at plane's origin. The width will be in the plane's X axis direction, and the height will be in the plane's Y axis direction. filename = The path to a bitmap or image file. width = If both dblWidth and dblHeight = 0, then the width and height of the PictureFrame will be the width and height of the image. If dblWidth = 0 and dblHeight is > 0, or if dblWidth > 0 and dblHeight = 0, then the non-zero value is assumed to be an aspect ratio of the image's width or height, which ever one is = 0. If both dblWidth and dblHeight are > 0, then these are assumed to be the width and height of in the current unit system. height = If both dblWidth and dblHeight = 0, then the width and height of the PictureFrame will be the width and height of the image. If dblWidth = 0 and dblHeight is > 0, or if dblWidth > 0 and dblHeight = 0, then the non-zero value is assumed to be an aspect ratio of the image's width or height, which ever one is = 0. If both dblWidth and dblHeight are > 0, then these are assumed to be the width and height of in the current unit system. self_illumination = If True, then the image mapped to the picture frame plane always displays at full intensity and is not affected by light or shadow. embed = If True, then the function adds the image to Rhino's internal bitmap table, thus making the document self-contained. use_alpha = If False, the picture frame is created without any transparency texture. If True, a transparency texture is created with a "mask texture" set to alpha, and an instance of the diffuse texture in the source texture slot. make_mesh = If True, the function will make a PictureFrame object from a mesh rather than a plane surface. Returns: object identifier on success None on failure Example: See Also: """ plane = rhutil.coerceplane(plane, True) if type(filename) is not System.String or not System.IO.File.Exists(filename): raise Exception('\"{0}\" does not exist or is not a file name'.format(filename)) rc = scriptcontext.doc.Objects.AddPictureFrame(plane, filename, make_mesh, width, height, self_illumination, embed) if rc==System.Guid.Empty: raise Exception("unable to add picture frame to document") scriptcontext.doc.Views.Redraw() return rc
def XformShear(plane, x, y, z): """Returns a shear transformation matrix Parameters: plane (plane): plane[0] is the fixed point x,y,z (number): each axis scale vector Returns: transform: The 4x4 transformation matrix on success Example: import rhinoscriptsyntax as rs objects = rs.GetObjects("Select objects to shear") if objects: cplane = rs.ViewCPlane() xform = rs.XformShear(cplane, (1,1,0), (-1,1,0), (0,0,1)) rs.TransformObjects(objects, xform, True) See Also: XformMirror XformPlanarProjection XformRotation1 XformRotation2 XformRotation3 XformRotation4 XformScale XformTranslation """ plane = rhutil.coerceplane(plane, True) x = rhutil.coerce3dvector(x, True) y = rhutil.coerce3dvector(y, True) z = rhutil.coerce3dvector(z, True) return Rhino.Geometry.Transform.Shear(plane, x, y, z)
def PlaneEquation(plane): """Returns the equation of a plane as a tuple of four numbers. The standard equation of a plane with a non-zero vector is Ax+By+Cz+D=0 """ plane = rhutil.coerceplane(plane, True) rc = plane.GetPlaneEquation() return rc[0], rc[1], rc[2], rc[3]
def LineCylinderIntersection(line, cylinder_plane, cylinder_height, cylinder_radius): """Calculates the intersection of a line and a cylinder Parameters: line = the line to intersect cylinder_plane = base plane of the cylinder cylinder_height = height of the cylinder cylinder_radius = radius of the cylinder Returns: list of intersection points (0, 1, or 2 points) """ line = rhutil.coerceline(line, True) cylinder_plane = rhutil.coerceplane(cylinder_plane, True) circle = Rhino.Geometry.Circle(cylinder_plane, cylinder_radius) if not circle.IsValid: raise ValueError( "unable to create valid circle with given plane and radius") cyl = Rhino.Geometry.Cylinder(circle, cylinder_height) if not cyl.IsValid: raise ValueError( "unable to create valid cylinder with given circle and height") rc, pt1, pt2 = Rhino.Geometry.Intersect.Intersection.LineCylinder( line, cyl) if rc == Rhino.Geometry.Intersect.LineCylinderIntersection.None: return [] if rc == Rhino.Geometry.Intersect.LineCylinderIntersection.Single: return [pt1] return [pt1, pt2]
def TextObjectPlane(object_id, plane=None): """Returns or modifies the plane used by a text object Parameters: object_id (guid): the identifier of a text object plane (plane): the new text object plane Returns: plane: if a plane is not specified, the current plane if successful plane: if a plane is specified, the previous plane if successful None: if not successful, or on Error Example: import rhinoscriptsyntax as rs obj = rs.GetObject("Select text") if rs.IsText(obj): plane = rs.ViewCPlane("Top") rs.TextObjectPlane( obj, plane ) See Also: AddText IsText TextObjectFont TextObjectHeight TextObjectPoint TextObjectStyle TextObjectText """ annotation = rhutil.coercegeometry(object_id, True) if not isinstance(annotation, Rhino.Geometry.TextEntity): return scriptcontext.errorhandler() rc = annotation.Plane if plane: annotation.Plane = rhutil.coerceplane(plane, True) id = rhutil.coerceguid(object_id, True) scriptcontext.doc.Objects.Replace(id, annotation) scriptcontext.doc.Views.Redraw() return rc
def LineCylinderIntersection(line, cylinder_plane, cylinder_height, cylinder_radius): """Calculates the intersection of a line and a cylinder Parameters: line (guid|line): the line to intersect cylinder_plane (plane): base plane of the cylinder cylinder_height (number): height of the cylinder cylinder_radius (number): radius of the cylinder Returns: list(point, ...): list of intersection points (0, 1, or 2 points) Example: import rhinoscriptsyntax as rs plane = rs.WorldXYPlane() line = (-10,0,0), (10,0,10) points = rs.LineCylinderIntersection(line, plane, cylinder_height=10, cylinder_radius=5) if points: for point in points: rs.AddPoint(point) See Also: LineLineIntersection LinePlaneIntersection LineSphereIntersection """ line = rhutil.coerceline(line, True) cylinder_plane = rhutil.coerceplane(cylinder_plane, True) circle = Rhino.Geometry.Circle( cylinder_plane, cylinder_radius ) if not circle.IsValid: raise ValueError("unable to create valid circle with given plane and radius") cyl = Rhino.Geometry.Cylinder( circle, cylinder_height ) if not cyl.IsValid: raise ValueError("unable to create valid cylinder with given circle and height") rc, pt1, pt2 = Rhino.Geometry.Intersect.Intersection.LineCylinder(line, cyl) if rc==Rhino.Geometry.Intersect.LineCylinderIntersection.None: return [] if rc==Rhino.Geometry.Intersect.LineCylinderIntersection.Single: return [pt1] return [pt1, pt2]
def PlaneClosestPoint(plane, point, return_point=True): """Returns the point on a plane that is closest to a test point. Parameters: plane = The plane point = The 3-D point to test. return_point [opt] = If omitted or True, then the point on the plane that is closest to the test point is returned. If False, then the parameter of the point on the plane that is closest to the test point is returned. Returns: If return_point is omitted or True, then the 3-D point If return_point is False, then an array containing the U,V parameters of the point None if not successful, or on error. Example: import rhinoscriptsyntax as rs point = rs.GetPoint("Point to test") if point: plane = rs.ViewCPlane() if plane: print rs.PlaneClosestPoint(plane, point) See Also: DistanceToPlane EvaluatePlane """ plane = rhutil.coerceplane(plane, True) point = rhutil.coerce3dpoint(point, True) if return_point: return plane.ClosestPoint(point) else: rc, s, t = plane.ClosestParameter(point) if rc: return s, t
def XformPlanarProjection(plane): """Returns a transformation matrix that projects to a plane. Parameters: plane (plane): The plane to project to. Returns: transform: The 4x4 transformation matrix. Example: import rhinoscriptsyntax as rs objects = rs.GetObjects("Select objects to project") if objects: cplane = rs.ViewCPlane() xform = rs.XformPlanarProjection(cplane) rs.TransformObjects( objects, xform, True ) See Also: XformMirror XformRotation1 XformRotation2 XformRotation3 XformRotation4 XformScale XformShear XformTranslation """ plane = rhutil.coerceplane(plane, True) return Rhino.Geometry.Transform.PlanarProjection(plane)
def XformShear(plane, x, y, z): """Returns a shear transformation matrix Parameters: plane = plane[0] is the fixed point x,y,z = each axis scale factor Returns: The 4x4 transformation matrix on success Example: import rhinoscriptsyntax as rs objects = rs.GetObjects("Select objects to shear") if objects: cplane = rs.ViewCPlane() xform = rs.XformShear(cplane, (1,1,0), (-1,1,0), (0,0,1)) rs.TransformObjects(objects, xform, True) See Also: XformMirror XformPlanarProjection XformRotation XformScale XformTranslation """ plane = rhutil.coerceplane(plane, True) x = rhutil.coerce3dvector(x, True) y = rhutil.coerce3dvector(y, True) z = rhutil.coerce3dvector(z, True) return Rhino.Geometry.Transform.Shear(plane,x,y,z)
def BoundingBox(objects, view_or_plane=None, in_world_coords=True): """Returns either world axis-aligned or a construction plane axis-aligned bounding box of an object or of several objects Parameters: objects = The identifiers of the objects view_or_plane[opt] = Title or id of the view that contains the construction plane to which the bounding box should be aligned -or- user defined plane. If omitted, a world axis-aligned bounding box will be calculated in_world_coords[opt] = return the bounding box as world coordinates or construction plane coordinates. Note, this option does not apply to world axis-aligned bounding boxes. Returns: Eight 3D points that define the bounding box. Points returned in counter- clockwise order starting with the bottom rectangle of the box. None on error """ def __objectbbox(object, xform): geom = rhutil.coercegeometry(object, False) if not geom: pt = rhutil.coerce3dpoint(object, True) return Rhino.Geometry.BoundingBox(pt, pt) if xform: return geom.GetBoundingBox(xform) return geom.GetBoundingBox(True) xform = None plane = rhutil.coerceplane(view_or_plane) if plane is None and view_or_plane: view = view_or_plane modelviews = scriptcontext.doc.Views.GetStandardRhinoViews() for item in modelviews: viewport = item.MainViewport if type(view) is str and viewport.Name == view: plane = viewport.ConstructionPlane() break elif type(view) is System.Guid and viewport.Id == view: plane = viewport.ConstructionPlane() break if plane is None: return scriptcontext.errorhandler() if plane: xform = Rhino.Geometry.Transform.ChangeBasis( Rhino.Geometry.Plane.WorldXY, plane) bbox = Rhino.Geometry.BoundingBox.Empty if type(objects) is list or type(objects) is tuple: for object in objects: objectbbox = __objectbbox(object, xform) bbox = Rhino.Geometry.BoundingBox.Union(bbox, objectbbox) else: objectbbox = __objectbbox(objects, xform) bbox = Rhino.Geometry.BoundingBox.Union(bbox, objectbbox) if not bbox.IsValid: return scriptcontext.errorhandler() corners = list(bbox.GetCorners()) if in_world_coords and plane is not None: plane_to_world = Rhino.Geometry.Transform.ChangeBasis( plane, Rhino.Geometry.Plane.WorldXY) for pt in corners: pt.Transform(plane_to_world) return corners
def AddText(text, point_or_plane, height=1.0, font="Arial", font_style=0, justification=None): """Adds a text string to the document Parameters: text (str): the text to display point_or_plane (point|plane): a 3-D point or the plane on which the text will lie. The origin of the plane will be the origin point of the text height (number, optional): the text height font (str, optional): the text font font_style (number, optional): any of the following flags 0 = normal 1 = bold 2 = italic 3 = bold and italic justification (number, optional): text justification. Values may be added to create combinations. 1 = Left 2 = Center (horizontal) 4 = Right 65536 = Bottom 131072 = Middle (vertical) 262144 = Top Returns: guid: identifier for the object that was added to the doc on success None: on failure Example: import rhinoscriptsyntax as rs point = rs.GetPoint("Pick point") if point: rs.AddText("Hello Rhino!", point) See Also: IsText """ if not text: raise ValueError("text invalid") if not isinstance(text, str): text = str(text) point = rhutil.coerce3dpoint(point_or_plane) plane = None if not point: plane = rhutil.coerceplane(point_or_plane, True) if not plane: plane = scriptcontext.doc.Views.ActiveView.ActiveViewport.ConstructionPlane( ) plane.Origin = point bold = (1 == font_style or 3 == font_style) italic = (2 == font_style or 3 == font_style) id = None if justification is None: id = scriptcontext.doc.Objects.AddText(text, plane, height, font, bold, italic) else: just = System.Enum.ToObject(Rhino.Geometry.TextJustification, justification) id = scriptcontext.doc.Objects.AddText(text, plane, height, font, bold, italic, just) if id == System.Guid.Empty: raise ValueError("unable to add text to document") scriptcontext.doc.Views.Redraw() return id
def XformRotation1(initial_plane, final_plane): """Returns a rotation transformation that maps initial_plane to final_plane. The planes should be right hand orthonormal planes. Parameters: initial_plane (plane): plane to rotate from final_plane (plane): plane to rotate to Returns: transform: The 4x4 transformation matrix. None: on error. Example: See Also: """ initial_plane = rhutil.coerceplane(initial_plane, True) final_plane = rhutil.coerceplane(final_plane, True) xform = Rhino.Geometry.Transform.PlaneToPlane(initial_plane, final_plane) if not xform.IsValid: return scriptcontext.errorhandler() return xform
def XformPlanarProjection(plane): """Returns a transformation matrix that projects to a plane. Parameters plane = The plane to project to. Returns: The 4x4 transformation matrix. """ plane = rhutil.coerceplane(plane, True) return Rhino.Geometry.Transform.PlanarProjection(plane)
def BoundingBox(objects, view_or_plane=None, in_world_coords=True): """Returns either world axis-aligned or a construction plane axis-aligned bounding box of an object or of several objects Parameters: objects = The identifiers of the objects view_or_plane[opt] = Title or id of the view that contains the construction plane to which the bounding box should be aligned -or- user defined plane. If omitted, a world axis-aligned bounding box will be calculated in_world_coords[opt] = return the bounding box as world coordinates or construction plane coordinates. Note, this option does not apply to world axis-aligned bounding boxes. Returns: Eight 3D points that define the bounding box. Points returned in counter- clockwise order starting with the bottom rectangle of the box. None on error """ def __objectbbox(object, xform): geom = rhutil.coercegeometry(object, False) if not geom: pt = rhutil.coerce3dpoint(object, True) return Rhino.Geometry.BoundingBox(pt,pt) if xform: return geom.GetBoundingBox(xform) return geom.GetBoundingBox(True) xform = None plane = rhutil.coerceplane(view_or_plane) if plane is None and view_or_plane: view = view_or_plane modelviews = scriptcontext.doc.Views.GetStandardRhinoViews() for item in modelviews: viewport = item.MainViewport if type(view) is str and viewport.Name==view: plane = viewport.ConstructionPlane() break elif type(view) is System.Guid and viewport.Id==view: plane = viewport.ConstructionPlane() break if plane is None: return scriptcontext.errorhandler() if plane: xform = Rhino.Geometry.Transform.ChangeBasis(Rhino.Geometry.Plane.WorldXY, plane) bbox = Rhino.Geometry.BoundingBox.Empty if type(objects) is list or type(objects) is tuple: for object in objects: objectbbox = __objectbbox(object, xform) bbox = Rhino.Geometry.BoundingBox.Union(bbox,objectbbox) else: objectbbox = __objectbbox(objects, xform) bbox = Rhino.Geometry.BoundingBox.Union(bbox,objectbbox) if not bbox.IsValid: return scriptcontext.errorhandler() corners = list(bbox.GetCorners()) if in_world_coords and plane is not None: plane_to_world = Rhino.Geometry.Transform.ChangeBasis(plane, Rhino.Geometry.Plane.WorldXY) for pt in corners: pt.Transform(plane_to_world) return corners
def EvaluatePlane(plane, parameter): """Evaluates a plane at a U,V parameter Parameters: plane = the plane to evaluate parameter = list of two numbers defining the U,V parameter to evaluate Returns: Point3d on success """ plane = rhutil.coerceplane(plane, True) return plane.PointAt(parameter[0], parameter[1])
def PlaneSphereIntersection(plane, sphere_plane, sphere_radius): """Calculates the intersection of a plane and a sphere Parameters: plane = the plane to intersect sphere_plane = equitorial plane of the sphere. origin of the plane is the center of the sphere sphere_radius = radius of the sphere Returns: list of intersection results - see help None on error """ plane = rhutil.coerceplane(plane, True) sphere_plane = rhutil.coerceplane(sphere_plane, True) sphere = Rhino.Geometry.Sphere(sphere_plane, sphere_radius) rc, circle = Rhino.Geometry.Intersect.Intersection.PlaneSphere(plane, sphere) if rc==Rhino.Geometry.Intersect.PlaneSphereIntersection.Point: return 0, circle.Center if rc==Rhino.Geometry.Intersect.PlaneSphereIntersection.Circle: return 1, circle.Plane, circle.Radius
def PlaneTransform(plane, xform): """Transforms a plane Parameters: plane = Plane to transform xform = Transformation to apply """ plane = rhutil.coerceplane(plane, True) xform = rhutil.coercexform(xform, True) rc = Rhino.Geometry.Plane(plane) if rc.Transform(xform): return rc
def AddLeader(points, view_or_plane=None, text=None): """Adds a leader to the document. Leader objects are planar. The 3D points passed to this function should be co-planar Parameters: points = list of (at least 2) 3D points view_or_plane [opt] = If a view is specified, points will be constrained to the view's construction plane. If a view is not specified, points will be constrained to a plane fit through the list of points text [opt] = leader's text string Returns: identifier of the new leader on success None on error Example: import rhinoscriptsyntax as rs points = rs.GetPoints(True, False, "Select leader points") if points: rs.AddLeader( points ) See Also: IsLeader LeaderText """ points = rhutil.coerce3dpointlist(points) if points is None or len(points) < 2: raise ValueError("points must have at least two items") rc = System.Guid.Empty view = None if text and not isinstance(text, str): text = str(text) if not view_or_plane: if len(points) == 2: plane = scriptcontext.doc.Views.ActiveView.ActiveViewport.ConstructionPlane( ) rc = scriptcontext.doc.Objects.AddLeader( text, plane, [Rhino.Geometry.Point2d(p.X, p.Y) for p in points]) else: rc = scriptcontext.doc.Objects.AddLeader(text, points) else: plane = rhutil.coerceplane(view_or_plane) if not plane: view = __viewhelper(view_or_plane) plane = view.ActiveViewport.ConstructionPlane() points2d = [] for point in points: cprc, s, t = plane.ClosestParameter(point) if not cprc: return scriptcontext.errorhandler() points2d.append(Rhino.Geometry.Point2d(s, t)) if text is None: rc = scriptcontext.doc.Objects.AddLeader(plane, points2d) else: if not isinstance(text, str): text = str(text) rc = scriptcontext.doc.Objects.AddLeader(text, plane, points2d) if rc == System.Guid.Empty: return scriptcontext.errorhandler() scriptcontext.doc.Views.Redraw() return rc
def PlaneTransform(plane, xform): """Transforms a plane Parameters: plane = OnPlane or On3dmConstructionPlane xform = """ plane = rhutil.coerceplane(plane, True) xform = rhutil.coercexform(xform, True) rc = Rhino.Geometry.Plane(plane) if rc.Transform(xform): return rc return scriptcontext.errorhandler()
def XformCPlaneToWorld(point, plane): """Transform point from construction plane coordinates to world coordinates Parameters: point = A 3D point in construction plane coordinates. plane = The construction plane Returns: A 3D point in world coordinates """ point = rhutil.coerce3dpoint(point, True) plane = rhutil.coerceplane(plane, True) return plane.Origin + point.X * plane.XAxis + point.Y * plane.YAxis + point.Z * plane.ZAxis
def XformCPlaneToWorld(point, plane): """Transform point from construction plane coordinates to world coordinates Parameters: point = A 3D point in construction plane coordinates. plane = The construction plane Returns: A 3D point in world coordinates """ point = rhutil.coerce3dpoint(point, True) plane = rhutil.coerceplane(plane, True) return plane.Origin + point.X*plane.XAxis + point.Y*plane.YAxis + point.Z*plane.ZAxis
def XformWorldToCPlane(point, plane): """Transforms a point from world coordinates to construction plane coordinates. Parameters: point = A 3D point in world coordinates. plane = The construction plane Returns: A 3D point in construction plane coordinates """ point = rhutil.coerce3dpoint(point, True) plane = rhutil.coerceplane(plane, True) v = point - plane.Origin; return Rhino.Geometry.Point3d(v*plane.XAxis, v*plane.YAxis, v*plane.ZAxis)
def PointArrayBoundingBox(points, view_or_plane=None, in_world_coords=True): """Returns either a world axis-aligned or a construction plane axis-aligned bounding box of an array of 3-D point locations. Parameters: points = A list of 3-D points view_or_plane[opt] = Title or id of the view that contains the construction plane to which the bounding box should be aligned -or- user defined plane. If omitted, a world axis-aligned bounding box will be calculated in_world_coords[opt] = return the bounding box as world coordinates or construction plane coordinates. Note, this option does not apply to world axis-aligned bounding boxes. Returns: Eight 3D points that define the bounding box. Points returned in counter- clockwise order starting with the bottom rectangle of the box. None on error Example: See Also: BoundingBox """ points = rhutil.coerce3dpointlist(points) if not points: return None bbox = Rhino.Geometry.BoundingBox(points) xform = None plane = rhutil.coerceplane(view_or_plane) if plane is None and view_or_plane: view = view_or_plane modelviews = scriptcontext.doc.Views.GetStandardRhinoViews() for item in modelviews: viewport = item.MainViewport if type(view) is str and viewport.Name == view: plane = viewport.ConstructionPlane() break elif type(view) is System.Guid and viewport.Id == view: plane = viewport.ConstructionPlane() break if plane is None: return scriptcontext.errorhandler() if plane: xform = Rhino.Geometry.Transform.ChangeBasis( Rhino.Geometry.Plane.WorldXY, plane) bbox = xform.TransformBoundingBox(bbox) if not bbox.IsValid: return scriptcontext.errorhandler() corners = list(bbox.GetCorners()) if in_world_coords and plane is not None: plane_to_world = Rhino.Geometry.Transform.ChangeBasis( plane, Rhino.Geometry.Plane.WorldXY) for pt in corners: pt.Transform(plane_to_world) return corners
def AddText(text, point_or_plane, height=1.0, font="Arial", font_style=0, justification=None): """Adds a text string to the document Parameters: text = the text to display point_or_plane = a 3-D point or the plane on which the text will lie. The origin of the plane will be the origin point of the text height [opt] = the text height font [opt] = the text font font_style[opt] = any of the following flags 0 = normal 1 = bold 2 = italic 3 = bold and italic justification[opt] = text justification (see help for values) Returns: Guid for the object that was added to the doc on success None on failure Example: import rhinoscriptsyntax as rs point = rs.GetPoint("Pick point") if point: rs.AddText("Hello Rhino!", point) See Also: IsText """ if not text: raise ValueError("text invalid") if not isinstance(text, str): text = str(text) point = rhutil.coerce3dpoint(point_or_plane) plane = None if not point: plane = rhutil.coerceplane(point_or_plane, True) if not plane: plane = scriptcontext.doc.Views.ActiveView.ActiveViewport.ConstructionPlane( ) plane.Origin = point bold = (1 == font_style or 3 == font_style) italic = (2 == font_style or 3 == font_style) id = None if justification is None: id = scriptcontext.doc.Objects.AddText(text, plane, height, font, bold, italic) else: just = System.Enum.ToObject(Rhino.Geometry.TextJustification, justification) id = scriptcontext.doc.Objects.AddText(text, plane, height, font, bold, italic, just) if id == System.Guid.Empty: raise ValueError("unable to add text to document") scriptcontext.doc.Views.Redraw() return id
def LineSphereIntersection(line, sphere_center, sphere_radius): """Calculates the intersection of a line and a sphere Returns: list of intersection points if successful """ line = rhutil.coerceline(line, True) sphere_plane = rhutil.coerceplane(sphere_plane, True) sphere = Rhino.Geometry.Sphere(sphere_center, sphere_radius) rc, pt1, pt2 = Rhino.Geometry.Intersect.Intersection.LineSphere(line, sphere) if rc==Rhino.Geometry.Intersect.LineSphereIntersection.None: return [] if rc==Rhino.Geometry.Intersect.LineSphereIntersection.Single: return [pt1] return [pt1, pt2]
def MovePlane(plane, origin): """Moves the origin of a plane Parameters: plane = Plane or ConstructionPlane origin = Point3d or list of three numbers Returns: moved plane """ plane = rhutil.coerceplane(plane, True) origin = rhutil.coerce3dpoint(origin, True) rc = Rhino.Geometry.Plane(plane) rc.Origin = origin return rc
def PlaneSphereIntersection(plane, sphere_plane, sphere_radius): """Calculates the intersection of a plane and a sphere Parameters: plane (plane): the plane to intersect sphere_plane (plane): equatorial plane of the sphere. origin of the plane is the center of the sphere sphere_radius (number): radius of the sphere Returns: list(number, point|plane, number): of intersection results Element Type Description [0] number The type of intersection, where 0 = point and 1 = circle. [1] point or plane If a point intersection, the a Point3d identifying the 3-D intersection location. If a circle intersection, then the circle's plane. The origin of the plane will be the center point of the circle [2] number If a circle intersection, then the radius of the circle. None: on error Example: import rhinoscriptsyntax as rs plane = rs.WorldXYPlane() radius = 10 results = rs.PlaneSphereIntersection(plane, plane, radius) if results: if results[0]==0: rs.AddPoint(results[1]) else: rs.AddCircle(results[1], results[2]) See Also: IntersectPlanes LinePlaneIntersection PlanePlaneIntersection """ plane = rhutil.coerceplane(plane, True) sphere_plane = rhutil.coerceplane(sphere_plane, True) sphere = Rhino.Geometry.Sphere(sphere_plane, sphere_radius) rc, circle = Rhino.Geometry.Intersect.Intersection.PlaneSphere( plane, sphere) if rc == Rhino.Geometry.Intersect.PlaneSphereIntersection.Point: return 0, circle.Center if rc == Rhino.Geometry.Intersect.PlaneSphereIntersection.Circle: return 1, circle.Plane, circle.Radius
def XformShear(plane, x, y, z): """Returns a shear transformation matrix Parameters: plane = plane[0] is the fixed point x,y,z = each axis scale factor Returns: The 4x4 transformation matrix on success """ plane = rhutil.coerceplane(plane, True) x = rhutil.coerce3dvector(x, True) y = rhutil.coerce3dvector(y, True) z = rhutil.coerce3dvector(z, True) return Rhino.Geometry.Transform.Shear(plane,x,y,z)
def AddLeader(points, view_or_plane=None, text=None): """Adds a leader to the document. Leader objects are planar. The 3D points passed to this function should be co-planar Parameters: points = list of (at least 2) 3D points view_or_plane [opt] = If a view is specified, points will be constrained to the view's construction plane. If a view is not specified, points will be constrained to a plane fit through the list of points text [opt] = leader's text string Returns: identifier of the new leader on success None on error Example: import rhinoscriptsyntax as rs points = rs.GetPoints(True, False, "Select leader points") if points: rs.AddLeader( points ) See Also: IsLeader LeaderText """ points = rhutil.coerce3dpointlist(points) if points is None or len(points)<2: raise ValueError("points must have at least two items") rc = System.Guid.Empty view = None if text and not isinstance(text, str): text = str(text) if not view_or_plane: if len(points) == 2: plane = scriptcontext.doc.Views.ActiveView.ActiveViewport.ConstructionPlane() rc = scriptcontext.doc.Objects.AddLeader(text, plane, [Rhino.Geometry.Point2d(p.X, p.Y) for p in points]) else: rc = scriptcontext.doc.Objects.AddLeader(text, points) else: plane = rhutil.coerceplane(view_or_plane) if not plane: view = __viewhelper(view_or_plane) plane = view.ActiveViewport.ConstructionPlane() points2d = [] for point in points: cprc, s, t = plane.ClosestParameter( point ) if not cprc: return scriptcontext.errorhandler() points2d.append( Rhino.Geometry.Point2d(s,t) ) if text is None: rc = scriptcontext.doc.Objects.AddLeader(plane, points2d) else: if not isinstance(text, str): text = str(text) rc = scriptcontext.doc.Objects.AddLeader(text, plane, points2d) if rc==System.Guid.Empty: return scriptcontext.errorhandler() scriptcontext.doc.Views.Redraw() return rc
def PlanePlaneIntersection(plane1, plane2): """Calculates the intersection of two planes Parameters: plane1 = the 1st plane to intersect plane2 = the 2nd plane to intersect Returns: two 3d points identifying the starting/ending points of the intersection None on error Example: import rhinoscriptsyntax as rs plane1 = rs.WorldXYPlane() plane2 = rs.WorldYZPlane() line = rs.PlanePlaneIntersection(plane1, plane2) if line: rs.AddLine(line[0], line[1]) See Also: IntersectPlanes LineLineIntersection LinePlaneIntersection """ plane1 = rhutil.coerceplane(plane1, True) plane2 = rhutil.coerceplane(plane2, True) rc, line = Rhino.Geometry.Intersect.Intersection.PlanePlane(plane1, plane2) if rc: return line.From, line.To
def RotatePlane(plane, angle_degrees, axis): """Rotates a plane Parameters: plane = Plane to rotate angle_degrees = rotation angle in degrees axis = Vector3d or list of three numbers Returns: rotated plane on success """ plane = rhutil.coerceplane(plane, True) axis = rhutil.coerce3dvector(axis, True) angle_radians = math.radians(angle_degrees) rc = Rhino.Geometry.Plane(plane) if rc.Rotate(angle_radians, axis): return rc
def PointArrayBoundingBox(points, view_or_plane=None, in_world_coords=True): """Returns either a world axis-aligned or a construction plane axis-aligned bounding box of an array of 3-D point locations. Parameters: points = A list of 3-D points view_or_plane[opt] = Title or id of the view that contains the construction plane to which the bounding box should be aligned -or- user defined plane. If omitted, a world axis-aligned bounding box will be calculated in_world_coords[opt] = return the bounding box as world coordinates or construction plane coordinates. Note, this option does not apply to world axis-aligned bounding boxes. Returns: Eight 3D points that define the bounding box. Points returned in counter- clockwise order starting with the bottom rectangle of the box. None on error Example: See Also: BoundingBox """ points = rhutil.coerce3dpointlist(points) if not points: return None bbox = Rhino.Geometry.BoundingBox(points) xform = None plane = rhutil.coerceplane(view_or_plane) if plane is None and view_or_plane: view = view_or_plane modelviews = scriptcontext.doc.Views.GetStandardRhinoViews() for item in modelviews: viewport = item.MainViewport if type(view) is str and viewport.Name==view: plane = viewport.ConstructionPlane() break elif type(view) is System.Guid and viewport.Id==view: plane = viewport.ConstructionPlane() break if plane is None: return scriptcontext.errorhandler() if plane: xform = Rhino.Geometry.Transform.ChangeBasis(Rhino.Geometry.Plane.WorldXY, plane) bbox = xform.TransformBoundingBox(bbox) if not bbox.IsValid: return scriptcontext.errorhandler() corners = list(bbox.GetCorners()) if in_world_coords and plane is not None: plane_to_world = Rhino.Geometry.Transform.ChangeBasis(plane, Rhino.Geometry.Plane.WorldXY) for pt in corners: pt.Transform(plane_to_world) return corners
def LinePlaneIntersection(line, plane): """Calculates the intersection of a line and a plane. Parameters: line = Two 3D points identifying the starting and ending points of the line to intersect. plane = The plane to intersect. Returns: The 3D point of intersection is successful. None if not successful, or on error. """ plane = rhutil.coerceplane(plane, True) line_points = rhutil.coerce3dpointlist(line, True) line = Rhino.Geometry.Line(line_points[0], line_points[1]) rc, t = Rhino.Geometry.Intersect.Intersection.LinePlane(line, plane) if not rc: return scriptcontext.errorhandler() return line.PointAt(t)
def PlaneCircleIntersection(plane, circle_plane, circle_radius): """Calculates the intersection of a plane and a circle Parameters: plane = the plane to intersect circle_plane = plane of the circle. origin of the plane is the center of the circle circle_radius = radius of the circle Returns: intersection type and up to two points: [0, point] for a tangent intersection [1, point1, point2] for a secant intersection [2] if the circle lies in the plane None if there is no intersection or on error """ plane = rhutil.coerceplane(plane, True) circle_plane = rhutil.coerceplane(circle_plane, True) circle = Rhino.Geometry.Circle(circle_plane, circle_radius) rc, t1, t2 = Rhino.Geometry.Intersect.Intersection.PlaneCircle(plane, circle) if rc==Rhino.Geometry.Intersect.PlaneCircleIntersection.Tangent: return (0, circle.PointAt(t1)) if rc==Rhino.Geometry.Intersect.PlaneCircleIntersection.Secant: return (1, circle.PointAt(t1), circle.PointAt(t2)) if rc==Rhino.Geometry.Intersect.PlaneCircleIntersection.Coincident: return (2)