예제 #1
0
def blendcorners(polyline_id, radius):
    # Fillets the corners of a polyline (from the McNeel website)
    if not polyline_id: return

    vertices = rs.PolylineVertices(polyline_id)
    if not vertices: return

    if radius is None: return

    between = lambda a, b: (a + b) / 2.0
    newverts = []
    for i in range(len(vertices) - 1):
        a = vertices[i]
        b = vertices[i + 1]
        segmentlength = rs.Distance(a, b)
        vec_segment = rs.PointSubtract(b, a)
        vec_segment = rs.VectorUnitize(vec_segment)

        if radius < (0.5 * segmentlength):
            vec_segment = rs.VectorScale(vec_segment, radius)
        else:
            vec_segment = rs.VectorScale(vec_segment, 0.5 * segmentlength)

        w1 = rs.PointAdd(a, vec_segment)
        w2 = rs.PointSubtract(b, vec_segment)
        newverts.append(a)
        newverts.append(between(a, w1))
        newverts.append(w1)
        newverts.append(between(w1, w2))
        newverts.append(w2)
        newverts.append(between(w2, b))
    newverts.append(vertices[len(vertices) - 1])
    CrvId = rs.AddCurve(newverts, 5)
    rs.DeleteObject(polyline_id)
    return CrvId
def blendcorners():
    polyline_id = rs.GetObject("Polyline to blend", 4, True, True)
    if not polyline_id: return

    vertices = rs.PolylineVertices(polyline_id)
    if not vertices: return

    radius = rs.GetReal("Blend radius", 1.0, 0.0)
    if radius is None: return

    between = lambda a, b: (a + b) / 2.0
    newverts = []
    for i in range(len(vertices) - 1):
        a = vertices[i]
        b = vertices[i + 1]
        segmentlength = rs.Distance(a, b)
        vec_segment = rs.PointSubtract(b, a)
        vec_segment = rs.VectorUnitize(vec_segment)

        if radius < (0.5 * segmentlength):
            vec_segment = rs.VectorScale(vec_segment, radius)
        else:
            vec_segment = rs.VectorScale(vec_segment, 0.5 * segmentlength)

        w1 = rs.PointAdd(a, vec_segment)
        w2 = rs.PointSubtract(b, vec_segment)
        newverts.append(a)
        newverts.append(between(a, w1))
        newverts.append(w1)
        newverts.append(between(w1, w2))
        newverts.append(w2)
        newverts.append(between(w2, b))
    newverts.append(vertices[len(vertices) - 1])
    rs.AddCurve(newverts, 5)
    rs.DeleteObject(polyline_id)
예제 #3
0
def draw(p0, p1, n=4):
    if n == 0:
        rs.AddLine(p0, p1)
    elif n >= 1:
        p01 = rs.PointAdd(p0, rs.PointScale(rs.PointSubtract(p1, p0), 1 / 3))
        p10 = rs.PointAdd(p0, rs.PointScale(rs.PointSubtract(p1, p0), 2 / 3))
        p2 = rs.PointAdd(
            p01, rs.VectorRotate(rs.PointSubtract(p10, p01), 60, (0, 0, 1)))
        draw(p0, p01, n - 1)
        draw(p01, p2, n - 1)
        draw(p2, p10, n - 1)
        draw(p10, p1, n - 1)
예제 #4
0
def DistributeCirclesOnSphere():
    sphere_radius = rs.GetReal("Radius of sphere", 10.0, 0.01)
    if not sphere_radius: return

    circle_radius = rs.GetReal("Radius of packing circles",
                               0.05 * sphere_radius, 0.001,
                               0.5 * sphere_radius)
    if not circle_radius: return

    vertical_count = int((math.pi * sphere_radius) / (2 * circle_radius))

    rs.EnableRedraw(False)
    phi = -0.5 * math.pi
    phi_step = math.pi / vertical_count
    while phi < 0.5 * math.pi:
        horizontal_count = int((2 * math.pi * math.cos(phi) * sphere_radius) /
                               (2 * circle_radius))
        if horizontal_count == 0: horizontal_count = 1
        theta = 0
        theta_step = 2 * math.pi / horizontal_count
        while theta < 2 * math.pi - 1e-8:
            circle_center = (sphere_radius * math.cos(theta) * math.cos(phi),
                             sphere_radius * math.sin(theta) * math.cos(phi),
                             sphere_radius * math.sin(phi))
            circle_normal = rs.PointSubtract(circle_center, (0, 0, 0))
            circle_plane = rs.PlaneFromNormal(circle_center, circle_normal)
            rs.AddCircle(circle_plane, circle_radius)
            theta += theta_step
        phi += phi_step
    rs.EnableRedraw(True)
예제 #5
0
def main():
    counts = [0, 0, 0]
    spacings = [10, 10, 10]
    rotations = [0, 0, 0]

    counts[0] = rs.GetInteger("number in x direction", minimum=1)
    # counts[1] = rs.GetInteger("number in y direction", minimum=1)
    # counts[2] = rs.GetInteger("number in z direction", minimum=1)

    spacings[0] = rs.GetReal("x spacing")
    # spacings[1] = rs.GetReal("y spacing")
    # spacings[2] = rs.GetReal("z spacing")

    rotations[0] = rs.GetReal("rotation of each object along x axis")
    # rotations[1] = rs.GetReal("y spacing")
    # rotations[2] = rs.GetReal("z spacing")

    print "count", counts
    print "spacing", spacings
    print "rotation", rotations

    for ix in range(counts[0]):
        newobj = rs.CopyObject(obj, [spacings[0] * ix, 0, 0])
        bbox = rs.BoundingBox(newobj)
        if bbox:
            centroid = rs.PointSubtract(bbox[0], bbox[6])
            print bbox[6], bbox[0]
            print centroid
            rs.AddPoint(centroid)
        else:
            print "no bbox"
예제 #6
0
def quad_rotate_point(point, center_point=(0, 0, 0), axis=(0, 0, 1)):
    _vec = rss.PointSubtract(point, center_point)
    return [
        point,
        rss.PointAdd(center_point, rss.VectorRotate(_vec, 90.0, axis)),
        rss.PointAdd(center_point, rss.VectorRotate(_vec, 180.0, axis)),
        rss.PointAdd(center_point, rss.VectorRotate(_vec, -90.0, axis)),
    ]
예제 #7
0
def AddArcDir(ptStart, ptEnd, vecDir):
    vecBase = rs.PointSubtract(ptEnd, ptStart)
    if rs.VectorLength(vecBase)==0.0: return
    if rs.IsVectorParallelTo(vecBase, vecDir): return
    vecBase = rs.VectorUnitize(vecBase)
    vecDir = rs.VectorUnitize(vecDir)
    vecBisector = rs.VectorAdd(vecDir, vecBase)
    vecBisector = rs.VectorUnitize(vecBisector)
    dotProd = rs.VectorDotProduct(vecBisector, vecDir)
    midLength = (0.5*rs.Distance(ptStart, ptEnd))/dotProd
    vecBisector = rs.VectorScale(vecBisector, midLength)
    return rs.AddArc3Pt(ptStart, rs.PointAdd(ptStart, vecBisector), ptEnd)
예제 #8
0
def ConvertToUVW(srf_id, xyz_points):
    uvw_points = []
    for point in xyz_points:
        Suv = rs.SurfaceClosestPoint(srf_id, point)
        Sxyz = rs.EvaluateSurface(srf_id, Suv)
        Snormal = rs.SurfaceNormal(srf_id, Suv)
        dirPos = rs.PointAdd(Sxyz, Snormal)
        dirNeg = rs.PointSubtract(Sxyz, Snormal)
        Sdist = rs.Distance(Sxyz, point)
        if rs.Distance(point, dirPos) > rs.Distance(point, dirNeg):
            Sdist = -Sdist
        uvw_points.append((Suv(0), Suv(1), Sdist))
    return uvw_points
def DrawArcSED():
    ptA = rs.GetPoint("Start of arc")
    if not ptA: return

    ptB = rs.GetPoint("End of arc")
    if not ptB: return

    ptD = rs.GetPoint("Direction of arc at start", ptA)
    if not ptD: return

    vecD = rs.PointSubtract(ptD, ptA)
    if rs.VectorLength(vecD) == 0.0: return
    AddArcDir(ptA, ptB, vecD)
예제 #10
0
def XYZ_To_UVW(srf_id, pXYZ):
    pUVW = []
    for point in pXYZ:
        uvClosest = rs.SurfaceClosestPoint(srf_id, point)
        ptClosest = rs.EvaluateSurface(srf_id, uvClosest)
        srfNormal = rs.SurfaceNormal(srf_id, uvClosest)
        pPositive = rs.PointAdd(ptClosest, srfNormal)
        pNegative = rs.PointSubtract(ptClosest, srfNormal)
        fDistance = rs.Distance(ptClosest, point)
        if rs.Distance(point,pPositive) > rs.Distance(point, pNegative):
            fDistance = -fDistance
        pUVW.append( (uvClosest[0], uvClosest[1], fDistance) )
    return pUVW
예제 #11
0
 def draw_lpoint_triple(text, tail, head):
     """Receives label text and a list of point triples:
         str
         [<iter>, ...]
     Draws text dots with <text>-a, -b, -c
     """
     line_vector = rs.PointSubtract(head, tail)
     offset_vector = line_vector * offset
     offset_tail = rs.VectorAdd(tail, offset_vector)
     offset_head = rs.VectorSubtract(head, offset_vector)
     axis = [0, 0, 1]
     angle = 90
     rotated_offset_vector = rs.VectorRotate(offset_vector, angle, axis)
     offset_side = rs.VectorAdd(offset_tail, rotated_offset_vector)
     rs.AddTextDot(('%s-a' % text), offset_tail)
     rs.AddTextDot(('%s-b' % text), offset_head)
     rs.AddTextDot(('%s-c' % text), offset_side)
예제 #12
0
def addArc(startPt, endPt, vecDir):
    vecBase = rs.PointSubtract(endPt, startPt)
    if rs.VectorLength(vecBase) == 0.0:
        return
    if rs.IsVectorParallelTo(vecBase, vecDir):
        return

    vecBase = rs.VectorUnitize(vecBase)
    vecDir = rs.VectorUnitize(vecDir)

    vecBisector = rs.VectorAdd(vecDir, vecBase)
    vecBisector = rs.VectorUnitize(vecBisector)

    midlength = (0.5*rs.Distance(startPt, endPt)) / (rs.VectorDotProduct(vecBisector, vecDir))

    vecBisector = rs.VectorScale(vecBisector, midlength)
    return rs.AddArc3Pt(startPt, endPt, rs.PointAdd(startPt, vecBisector))
예제 #13
0
def addArcDiv(ptStart, ptEnd, vecDir):
    vecBase = rs.PointSubtract(ptEnd, ptStart)
    # error handling
    if rs.VectorLength(vecBase) == 0.0: return
    if rs.IsVectorParallelTo(vecBase, vecDir): return

    vecBase = rs.VectorUnitize(
        vecBase
    )  # normalize vector == force magnitude to 1 to just compare direction
    vecDir = rs.VectorUnitize(vecDir)
    vecBisector = rs.VectorAdd(vecDir, vecBase)
    vecBisector = rs.VectorUnitize(vecBisector)

    dotProd = rs.VectorDotProduct(vecBisector, vecDir)
    midLength = (0.5 * rs.Distance(ptStart, ptEnd)) / dotProd

    vecBisector = rs.VectorScale(vecBisector, midLength)
    return rs.AddArc3Pt(ptStart, rs.PointAdd(pt.Start, vecBisector), ptEnd)
예제 #14
0
__author__ = "billpower"
__version__ = "2020.01.15"

import rhinoscriptsyntax as rs

point = LocationPoint
file = File
x = []
y = []
z = []
xyz = []
rexyz = []
repoint = []
orpoint = []
f = open(file,'r')  #使用open打开文件,r为只读模式
firstpoint = f.readline()   #使用方法读取行,读到第一个换行符
subdistance = rs.PointSubtract(rs.AddPoint(firstpoint),point)   #读取第一个行点坐标,建立点并与输入的定位点差,获取两点之间坐标的插值
for line in f.readlines():  #对文件内容进行迭代,读取所有行
    lst = line.split(',')
    x.append(float(lst[0]))
    y.append(float(lst[1]))
    z.append(float(lst[2]))
    xyz.append((float(lst[0]),float(lst[1]),float(lst[2])))     #字符串坐标浮点数化,形成坐标值列表
    orpoint.append(rs.AddPoint(float(lst[0]),float(lst[1]),float(lst[2])))  #根据原数据值建立点
    rexyz.append(((float(lst[0])-subdistance[0]),(float(lst[1])-subdistance[1]),(float(lst[2])-subdistance[2])))    #计算新坐标,形成列表
    repoint.append(rs.AddPoint((float(lst[0])-subdistance[0]),(float(lst[1])-subdistance[1]),(float(lst[2])-subdistance[2])))   #根据新坐标增加点
f.close()   #关闭文件
                arrBoxPoints = [[offsetX, offsetY, offsetZ],[offsetX + panelData[i][0].GetPanelProperty("PanelWidth"), offsetY, offsetZ],\
                    [offsetX, offsetY, offsetZ+panelData[i][0].GetPanelProperty("PanelHeight")],\
                    [offsetX + panelData[i][0].GetPanelProperty("PanelWidth"), offsetY, offsetZ+panelData[i][0].GetPanelProperty("PanelHeight")]]

                blockCount = len(
                    panelData[i][0].GetPanelProperty("BlockInstances"))
                panelCounter += blockCount
                #create text info
                if drawGeometry:
                    panelName = panelName.replace(" ", "\n\r", 1)
                    prevLayer = rs.CurrentLayer()
                    if not rs.IsLayer("GEO::_Canvas"):
                        rs.AddLayer("GEO::_Canvas")
                    rs.CurrentLayer("GEO::_Canvas")
                    txtPlane = rs.PlaneFromFrame(
                        rs.PointSubtract(arrBoxPoints[0],
                                         [0, 0, rowSeparation / 2]), (1, 0, 0),
                        (0, 0, 1))
                    textTypes.append(
                        rs.AddText(panelName + "\n\rCount: " + str(blockCount),
                                   txtPlane,
                                   fontHeight,
                                   font_style=fontStyle))
                    rs.CurrentLayer(prevLayer)
                #create panel copy
                Mockup_Bay.append(SGLibPanel())
                Mockup_Bay[len(Mockup_Bay) - 1].Copy(panelData[i][0])
                panelPoints = Mockup_Bay[len(Mockup_Bay) - 1].GetPanelProperty(
                    "PanelCornerPoints")
                alignXform = rc.Geometry.Transform.Translation(
                    -min(panelPoints[0].X, panelPoints[2].X), 0, 0)
                tmpBoxPts = rs.PointArrayTransform(arrBoxPoints, alignXform)
                        continue  #skip custom panel if showCustom off
                else:
                    fontHeight = .6
                    fontStyle = 1

                arrBoxPoints = [[offsetX, offsetY, offsetZ],[offsetX + panelData[i][0].GetPanelProperty("PanelWidth"), offsetY, offsetZ],\
                    [offsetX, offsetY, offsetZ+panelData[i][0].GetPanelProperty("PanelHeight")],\
                    [offsetX + panelData[i][0].GetPanelProperty("PanelWidth"), offsetY, offsetZ+panelData[i][0].GetPanelProperty("PanelHeight")]]

                #create text info
                if drawGeometry:
                    blockCount = len(
                        panelData[i][0].GetPanelProperty("BlockInstances"))
                    textTypes.append(
                        rs.AddText(panelName + "   Count: " + str(blockCount),
                                   rs.PointSubtract(arrBoxPoints[0],
                                                    [0, 1, 0]),
                                   fontHeight,
                                   font_style=fontStyle))
                    rs.RotateObject(
                        textTypes[len(textTypes) - 1],
                        rs.TextObjectPoint(textTypes[len(textTypes) - 1]), 270)

                #create panel copy
                Mockup_Bay.append(SGLibPanel())
                Mockup_Bay[len(Mockup_Bay) - 1].Copy(panelData[i][0])
                Mockup_Bay[len(Mockup_Bay) - 1].MorphPanel(arrBoxPoints)
                #print i; print panelData

                Mockup_Bay[len(Mockup_Bay) - 1].Draw(drawGeometry)
                if drawBreps:
                    Breps += Mockup_Bay[len(Mockup_Bay) - 1].GetBreps()
예제 #17
0
 def _get_ordered_line_and_labeled_point_specs(cls, element_guids):
     """Receives:
         element_guids   [guid, ...]. A list of the guids of (first) the 
                         frame instance and (then) the lines and labeled 
                         points
     Returns:
         ordered_line_and_labeled_point_specs
                         ([line_spec, ...], [labeled_point_spec, ...]). A 
                         list of line specs 
                             (   (num, num, num), 
                                 (num, num, num)) 
                         and a list of labeled point specs
                             (   str,
                                 (num, num, num))
                         where the specs are relative to the frame 
                         instance, if successful
         None            otherwise
     """
     method_name = '_get_ordered_line_and_labeled_point_specs'
     try:
         if element_guids == []:
             raise ValueError
     except ValueError:
         message = "There is no frame instance"
         print("%s.%s\n    %s" % (cls.__name__, method_name, message))
         return_value = None
     else:
         line_specs, labeled_point_specs = [], []
         frame_instance = element_guids.pop(0)
         frame_position = rs.BlockInstanceInsertPoint(frame_instance)
         curve_type, textdot_type = 4, 8192
         for element_guid in element_guids:
             if rs.ObjectType(element_guid) == curve_type:
                 p1_absolute = rs.CurveStartPoint(element_guid)
                 p2_absolute = rs.CurveEndPoint(element_guid)
                 p1_relative = rs.PointSubtract(p1_absolute, frame_position)
                 p2_relative = rs.PointSubtract(p2_absolute, frame_position)
                 p1_spec = tuple(p1_relative)
                 p2_spec = tuple(p2_relative)
                 if p1_spec < p2_spec:
                     tail = p1_spec
                     head = p2_spec
                 elif p1_spec > p2_spec:
                     tail = p2_spec
                     head = p1_spec
                 line_spec = (tail, head)
                 line_specs.append(line_spec)
             elif rs.ObjectType(element_guid) == textdot_type:
                 label = rs.TextDotText(element_guid)
                 p_absolute = rs.TextDotPoint(element_guid)
                 p_relative = rs.PointSubtract(p_absolute, frame_position)
                 p_spec = tuple(p_relative)
                 labeled_point_spec = (label, p_spec)
                 labeled_point_specs.append(labeled_point_spec)
             else:
                 pass
         ordered_line_and_labeled_point_specs = (
             sorted(line_specs), sorted(labeled_point_specs))
         return_value = ordered_line_and_labeled_point_specs
     finally:
         return return_value
예제 #18
0
def DistributeCirclesOnSphere():

    #get a bunch of stuff from the user
    center_point = rs.GetPoint("Center of Sphere", (0, 0, 0))
    if not center_point:
        print("Center Point Needed!")
        return

    sphere_radius = rs.GetReal("Radius of Sphere", 10.0, 0.01)
    if not sphere_radius:
        print("Sphere Radius Needed!")
        return

    circle_radius = rs.GetReal("Radius of Circles", 0.05 * sphere_radius,
                               0.001, 0.5 * sphere_radius)
    if not circle_radius:
        print("Circle Radius Needed!")
        return

    #this gives the number of circles that will fit along the seam. The centers of the seam
    #circles will also be the "bands" of circles around the sphere.  The length of the seam
    #is half of the circumference (1/2C = pi * r).  Divide that space by the diameter of the
    #circles we want to lay along it.  Casting as INT drops the decimal (round down).
    vertical_count = int((math.pi * sphere_radius) / (2 * circle_radius))

    rs.EnableRedraw(False)

    #phi is the variable that will set the elevation of the bands above and below
    #the equator.  The domain of this space will be -0.5 pi to 0.5 pi.  Each step
    #will be in an increment determined by the number of circles that fit along the seam.
    phi = -0.5 * math.pi
    phi_step = math.pi / vertical_count

    #step throught the "bands" around the sphere until we reach the bottom
    while phi < 0.5 * math.pi:

        #the number of circles we can fit in each "band" is the diameter of the sphere at each
        #angle of phi divided by the diameter of a single circle.  Casting as an INT will drop
        #the decimals (round down)
        horizontal_count = int((2 * math.pi * math.cos(phi) * sphere_radius) /
                               (2 * circle_radius))
        #the only case to round UP is if we accidentially rounded down to 0 (we can't have 0 circles)
        if horizontal_count == 0:
            horizontal_count = 1
        #theta is the angle around the center of the circle at the equator.  We intitalize
        #for each "band" and determine the step increment based on the number of circles
        #we can fit in each band
        theta = 0
        theta_step = 2 * math.pi / horizontal_count

        #this is where we look through all the positions on each "band"
        #the origianl author of this script subtracts a small value from 2 PI
        #to keep there from being an overlapped circle at the end.  I am not
        #sure that it is needed here, but I am leaving it in as I have not
        #tested the script that much
        while theta < 2 * math.pi - 1e-8:

            #convert our spherical coordinates into cartesion that Rhino understands
            #this is 3D Pythagorean Theorum
            circle_center = (sphere_radius * math.cos(theta) * math.cos(phi) +
                             center_point[0],
                             sphere_radius * math.sin(theta) * math.cos(phi) +
                             center_point[1],
                             sphere_radius * math.sin(phi) + center_point[2])
            #subtracting the point coordinates from the origin give us a vector that points
            #away from the center
            circle_normal = rs.PointSubtract(circle_center, center_point)
            #proxy place to place the circle, we don't care about orientation
            circle_plane = rs.PlaneFromNormal(circle_center, circle_normal)
            rs.AddCircle(circle_plane, circle_radius)
            #increment Theta angle
            theta += theta_step
        #increment Phi angle
        phi += phi_step
    rs.EnableRedraw(True)