Saturday, April 28, 2012

Lofting Problem In Python

I mentioned this problem during my presentation the other day, and thought I would show a quick fix to get around it if anyone has the same problem in the future.

The issue is that if you want to loft (for example) a polygon and a circle together, python has problems aligning the start points of the curves which can lead to unexpected results(see Fig.1).
Fig.1

import rhinoscriptsyntax as rs
import math
import random

hex = rs.GetObject()
circ = rs.GetObject()
loftL = [hex,circ]
loft = rs.AddLoftSrf(loftL)


So what I did is wrote a function that will align the seams of the curves and then loft them together so that a python loft will match a rhino loft(Fig.2)
Fig.2
import rhinoscriptsyntax as rs
import math
import random

def loft(_crvList):
    crvList = _crvList
    for i in range (0,len(crvList)-1):
        rs.CurveSeam(crvList[i+1],rs.CurveClosestPoint(crvList[i+1],rs.CurveStartPoint(crvList[0])))
    srf = rs.AddLoftSrf(crvList)
    return srf

crvs = rs.GetObjects('select curves',4)
loft(crvs)



Very easy little function(only 6 lines of code) that will save a lot of headache if you have problems with your lofts.  It can be copied and pasted into any script and just use that instead of the rs.AddLoftSrf  command and it will work no matter how many curves you are trying to loft together
Fig.3






Friday, April 27, 2012

[Hexa-spatial effects on a surface]_v1.0






import rhinoscriptsyntax as rs

crv = rs.GetObjects("Select curves in order")
att_pt1 = rs.GetObject("Select attractor pt 1")
#att_pt2 = rs.GetObject("Select attractor pt 2")

#CREATE LOFTED SURFACE FROM CURVES 
#(Curves should be of same degree and to be selected IN ORDER)
srf = rs.AddLoftSrf(crv)


ud=rs.SurfaceDomain(srf,0)
vd=rs.SurfaceDomain(srf,1)

print ud
print vd

lenu=ud[1]-ud[0]
lenv=vd[1]-vd[0]

print lenu
print lenv


#if rs.IsSurface(srf):

#u = ud[1]/2.0
#v = vd[1]/2.0
#point = rs.EvaluateSurface(srf, u, v)
#
#rs.AddPoints(point)


pts=[]
for i in rs.frange(ud[0],ud[1]+1,lenu/40):
    plist=[]
    for j in rs.frange(vd[0],vd[1]+lenv/40,lenv/40):
        plist.append(rs.EvaluateSurface(srf,i,j))
    pts.append(plist)
    #rs.DeleteDocumentData(pts)
#rlist=[]
#rlist.append(plist)
#for i in range(0,len(rlist)):
#    for j in range(0,len(rlist[i])):
#        rs.AddPoint(rlist[i][j])

pline=[]
cpts=[]



def CP(p):
    for i in range(0,len(p)):
        x=(p[0][0]+p[1][0]+p[2][0]+p[3][0]+p[4][0]+p[5][0])/6
        y=(p[0][1]+p[1][1]+p[2][1]+p[3][1]+p[4][1]+p[5][1])/6
        z=(p[0][2]+p[1][2]+p[2][2]+p[3][2]+p[4][2]+p[5][2])/6
        fakesrf = rs.AddSrfPt([p[0],p[1],p[2],p[3]])
        ud=rs.SurfaceDomain(fakesrf,0)
        vd=rs.SurfaceDomain(fakesrf,1)
        n=rs.SurfaceNormal(fakesrf,[ud[1],vd[1]])
        n=rs.VectorUnitize(n)
        rs.DeleteObject(fakesrf)
        return [[x,y,z],n]


for i in range(0,(len(pts)-2),2):
    for j in range(1,(len(pts[i])-3),4):
        p=[pts[i+1][j+0],pts[i+2][j+1],pts[i+2][j+2],pts[i+1][j+3],pts[i+0][j+2],pts[i+0][j+1],pts[i+1][j+0]]
        pline=rs.AddPolyline(p)
        retlist = CP(p)
        dist = rs.Distance(att_pt1,retlist[0])
        v=rs.VectorScale(retlist[1],(dist*100))
        midpt=retlist[0]
        newpline=rs.CopyObject(pline,-(retlist[1]*dist)/3)
        newpline=rs.RotateObject(newpline,midpt,30)
        newpline=rs.ScaleObject(newpline,midpt,(.2,.2,.2))
        rs.AddLoftSrf([pline,newpline])
        #rs.CopyObject(pline,
        #npt = nf(midpt)
        #normals.append(rs.SurfaceNormal(srf,midpt)
        #cpts.append(rs.AddPoints(CP))
        #extracted_pts.append(rs.CurvePoints(pline))
        #rs.CurvePoints(
#print extracted_pts

pline_two=[]
for i in range(1,(len(pts)-2),2):
    for j in range(3,(len(pts[i])-3),4):
        p=[pts[i+1][j+0],pts[i+2][j+1],pts[i+2][j+2],pts[i+1][j+3],pts[i+0][j+2],pts[i+0][j+1],pts[i+1][j+0]]
        pline=rs.AddPolyline(p)
        retlist = CP(p)
        midpt=retlist[0]
        newpline=rs.CopyObject(pline,-(retlist[1]*dist)/3)
        newpline=rs.RotateObject(newpline,midpt,30)
        newpline=rs.ScaleObject(newpline,midpt,(.2,.2,.2))
        rs.AddLoftSrf([pline,newpline])



Fibonacci spiral with respect to the Nautilus Shell


import rhinoscriptsyntax as rs
from math import *
import math as m

a = 1
b = 0.2
pts1 = []
pts2 = []
pts3 = []

for t in range(0, 30):
    x = a * m.exp(b*t) * m.cos(t)
    y = a * m.exp(b*t) * m.sin(t)
    pts1.append(rs.AddPoint(x/4,y/4,0))
    pts2.append(rs.AddPoint(x/1.3,y/1.3,15))
    pts3.append(rs.AddPoint(x,y,30))

curve1 = rs.AddInterpCurve(pts1)
curve2 = rs.AddInterpCurve(pts2)
curve3 = rs.AddInterpCurve(pts3)


# LOFTING SURFACE
strSurf = rs.AddLoftSrf([curve1, curve2, curve3])

listcurves = []
for i in range(0, 23):
    pointcoord1=rs.PointCoordinates(pts3[i])
    pointcoord1a=rs.PointCoordinates(pts3[i+1])
    
    pointcoord2=rs.PointCoordinates(pts3[i+6])
    pointcoord2a=rs.PointCoordinates(pts3[i+7])
    
    pointcoord3=rs.PointCoordinates(pts1[i])
    pointcoord3a=rs.PointCoordinates(pts1[i+1])
    
    pointcoord4=rs.PointCoordinates(pts1[i+6])
    pointcoord4a=rs.PointCoordinates(pts1[i+7])
    
    topcrv = rs.AddCurve([pointcoord2a, pointcoord2, pointcoord1, pointcoord1a])
    
    interpolcrv1 = rs.AddInterpCrvOnSrf(strSurf, [pointcoord1, pointcoord3])
    rs.ObjectColor(interpolcrv1,[255,0,0])
    interpolcrv2 = rs.AddInterpCrvOnSrf(strSurf, [pointcoord4, pointcoord3])
    rs.ObjectColor(interpolcrv2,[0,0,255])
   rs.AddLoftSrf([interpolcrv1, topcrv])

Techno Tulips on surface and development of tail




 import rhinoscriptsyntax as rs
import math as m 
import random as r

surf = rs.GetObject("surface",8) # parameter 1

# DIVIDE THE SURFACE INTO GRID POINTS

d_u = rs.SurfaceDomain(surf,0)
d_v = rs.SurfaceDomain(surf,1)

d_u_len = (d_u[1] - d_u[0])/10
d_v_len = (d_v[1] - d_v[0])/20

# CALLING THE SURFACE TO POPULATE

cntrl_pts_surf = []
listofnormals = []
listofperp = []

attractor_pt1 = rs.GetPoint("attractor point 1") # parameter 2

for i in rs.frange(d_u[0],d_u[1],d_u_len):
    row_list = []
    normaltemplist = []
    perp_line = []
    vector_scale = 0.1
    for j in rs.frange(d_v[0],d_v[1],d_v_len):
        pt = rs.EvaluateSurface(surf,i,j)
        vector_scale = (rs.Distance(attractor_pt1, pt) + vector_scale)/8 # parameter 3
        normal_vector = rs.SurfaceNormal(surf,[i,j])
        normal_vector = rs.VectorUnitize(normal_vector)
        normal_vector = rs.VectorScale(normal_vector,vector_scale)
        normal_vector_pt = rs.VectorAdd(pt,normal_vector)
        normaltemplist.append(normal_vector_pt)
        row_list.append(pt)
        perp_line.append(rs.AddLine(normal_vector_pt, pt))
        row_list.append(pt)
    listofperp.append(perp_line)
    cntrl_pts_surf.append(row_list)
    listofnormals.append(normaltemplist)
rs.DeleteObject(surf)
curve = []

for i in range(0, len(listofperp)):
    for m in range(0, len(listofperp[i])):
        divisions = 20
        circle = []
        val = 1
        for j in range(divisions+1):
            parameter = j/divisions
            val = (val + j)
            radius = (rs.CurveLength(listofperp[i][m])/(2*val)) # parameter 4
            eval_param = rs.CurveParameter(listofperp[i][m],parameter)
            perp_frame = rs.CurvePerpFrame(listofperp[i][m], eval_param)
            circle.append(rs.AddCircle(perp_frame, radius))
        rs.AddLoftSrf(circle)




Techno Tulips on a curve


import rhinoscriptsyntax as rs
import math as m 


curve = rs.GetObject("curve")


domain = rs.CurveDomain(curve)
domain_length = domain[1]-domain[0]
divisions = 20
step = domain_length / divisions
pt_crv = []


for i in rs.frange(domain[0], domain[1], step):
    pt_crv.append(rs.AddPoint(rs.EvaluateCurve(curve, i)))


line = []
mid_pt = []
list_normal_pts = []
perp_line = []


attractor_pt1 = rs.GetPoint("select attractor")


for i in range(0,len(pt_crv)-1):
    p = []
    p = [pt_crv[i], pt_crv[i+1]]
    
    line.append(rs.AddPolyline(p))
    mid_pt.append(rs.CurveMidPoint(line[i]))
    scale = (rs.Distance(mid_pt[i], attractor_pt1))/2
    curve_length = rs.CurveLength(line[i])
    normal_vector = rs.CurveNormal(line[i])
    normal_vector = rs.VectorUnitize(normal_vector)
    normal_vector = rs.VectorScale(normal_vector, scale)
    
    normal_pt = rs.VectorAdd(mid_pt[i], normal_vector)
#    normal_pt = rs.VectorRotate(normal_pt, 180/scale ,pt_crv[i])
    normal_pt = rs.AddPoint(normal_pt)
    perp_line.append(rs.AddCurve([normal_pt, mid_pt[i]],1))
    
    list_normal_pts.append(normal_pt)


rs.DeleteObject(curve)


pt = []
main_ptlist = []
div = []


for i in range(0, len(perp_line)):
    divisions = 10
    circle = []
    val = 1
    for j in range(divisions+1):
        parameter = j/divisions
        val = (val + j)
        radius = rs.CurveLength(line[i])/(2*val)
        eval_param = rs.CurveParameter(perp_line[i],parameter)
        perp_frame = rs.CurvePerpFrame(perp_line[i], eval_param)
        circle.append(rs.AddCircle(perp_frame, radius))
    rs.AddLoftSrf(circle)
    for k in range(0,len(circle)):
        div_circle = rs.DivideCurve(circle[k], divisions/2)
    div.append(div_circle)
    rs.DeleteObjects(circle)

Techo Tulips Along a Helix

The surface input is copied to the divisions on the helix, and the tulips with tail is created on each surface to achieve the above. 


import rhinoscriptsyntax as rs
import math as m 
import random as r


surf = rs.GetObject("surface",8)


# CREEPERS


a = 15
points = []


for i in range(0, 20):
    x = a*m.sin(m.pi/4*i)
    y = a*m.cos(m.pi/4*i)
    z = i * 2
    points.append([x,y,z])


distance = rs.Distance(points[0],points[1])


# DIVIDE THE SURFACE INTO GRID POINTS


d_u = rs.SurfaceDomain(surf,0)
d_v = rs.SurfaceDomain(surf,1)


d_u_len = (d_u[1] - d_u[0])/5
d_v_len = (d_v[1] - d_v[0])/5


# SCALED SURFACE


scale_surf = 2/((d_u[1] - d_u[0])/distance)
origin = rs.GetPointCoordinates("select a point on the surface")
surf = rs.ScaleObject(surf,origin[0],(scale_surf,scale_surf,scale_surf))


# MOVE SURFACE TO THE CURVE


surface = []


for i in range(0, len(points)):
    attractor_pt2 = points[i]
    translation = rs.VectorSubtract(points[i],origin[0])
    surface.append(rs.CopyObject(surf,translation))


# CALLING THE SURFACE TO POPULATE


for i in range(0,len(surface)):
    surf  = surface[i]
    d_u = rs.SurfaceDomain(surf,0)
    d_v = rs.SurfaceDomain(surf,1)
    
    d_u_len = (d_u[1] - d_u[0])/5
    d_v_len = (d_v[1] - d_v[0])/5
    
    cntrl_pts_surf = []
    listofnormals = []
    listofperp = []
    
    attractor_pt1 = points[i]
    attractor_pt2 = [0,0,0]
    
    for i in rs.frange(d_u[0],d_u[1],d_u_len):
        row_list = []
        normaltemplist = []
        perp_line = []
        vector_scale = 0.1
        for j in rs.frange(d_v[0],d_v[1],d_v_len):
            pt = rs.EvaluateSurface(surf,i,j)
            vector_scale = 1/(((rs.Distance(attractor_pt1, pt))/50) + vector_scale)
            normal_vector = rs.SurfaceNormal(surf,[i,j])
            normal_vector = rs.VectorUnitize(normal_vector)
            normal_vector = rs.VectorScale(normal_vector,vector_scale)
            normal_vector_pt = rs.VectorAdd(pt,normal_vector)
            normaltemplist.append(normal_vector_pt)
            row_list.append(pt)
            perp_line.append(rs.AddLine (normal_vector_pt, pt))
            row_list.append(pt)
        listofperp.append(perp_line)
        cntrl_pts_surf.append(row_list)
        listofnormals.append(normaltemplist)
    rs.DeleteObject(surf)
    curve = []


    arc_tot = []
    for i in range(0,len(cntrl_pts_surf)):
        arc = []
        for j in range(0, len(listofnormals[i])):
            line = rs.AddLine(attractor_pt2, listofnormals[i][j])
            mid_pt = rs.AddPoint(rs.CurveMidPoint(line))
            normal = rs.CurveNormal(line)
            rs.DeleteObject(line)
            normal = rs.VectorUnitize(normal)
            normal = rs.VectorScale(normal, 20)
            arc_mid_pt = rs.MoveObject(mid_pt,normal)
            arc.append(rs.AddCurve([listofnormals[i][j],cntrl_pts_surf[i][j],arc_mid_pt,attractor_pt2]))
            rs.DeleteObject(arc_mid_pt)
        arc_tot.append(arc)
    
    for i in range(0, len(arc_tot)):
        for m in range(0, len(arc_tot[i])):
            divisions = 20
            circle = []
            val = 1
            for j in range(divisions+1):
                parameter = j/divisions
                val = (val + j)
                radius = (rs.CurveLength(listofperp[i][m])/(2*val))*4
                eval_param = rs.CurveParameter(arc_tot[i][m],parameter)
                perp_frame = rs.CurvePerpFrame(arc_tot[i][m], eval_param)
                circle.append(rs.AddCircle(perp_frame, radius))
            rs.AddLoftSrf(circle)

Thursday, April 26, 2012

BubbleTree



import rhinoscriptsyntax as rs
import random
import math as mth


surface=rs.GetObject("get surface",8)

Udivisions=2
Vdivisions=20

domainU=rs.SurfaceDomain(surface,0)
domainV=rs.SurfaceDomain(surface,1)
floatUdivisions=(domainU[1]-domainU[0])/Udivisions
floatVdivisions=(domainV[1]-domainV[0])/Vdivisions

normalscale=10

leafList=[]
normallist=[]
templist0=[] 
ptList=[]
srf=[]


def centerPts(ptList):
    xList=[]
    yList=[]
    zList=[]
    for i in range(0,len(ptList)):
        pts=rs.PointCoordinates(ptList[i])
        x=pts[0]
        xList.append(x)
        y=pts[1]
        yList.append(y)
        z=pts[2]
        zList.append(z)
    centerPts=rs.AddPoint(mth.fsum(xList)/len(xList),mth.fsum(yList)/len(yList),mth.fsum(zList)/len(zList))
    return centerPts

rs.EnableRedraw(False)
for f in range(0,14):
    rotateSurface=rs.RotateObject(surface,[0,0,0],30*f,None,copy=True)
    vct=rs.VectorCreate([mth.sin(((2*mth.pi)/14)*f),mth.cos(((2*mth.pi)/14)*f),0],[0,0,0])
    rotateSurface=rs.RotateObject(rotateSurface,[0,0,0],random.randint(0,30)*f,vct,copy=False)
    leafList.append(rotateSurface)
    
    
for k in range(0,len(leafList)):
    leafPoints=[]
    normalList=[]
    centerPts0=[]
    centerPts1=[]
    crvList=[]
    for i in rs.frange(domainU[0],domainU[1]+0.001,floatUdivisions):
        templist=[]
        normaltemplist=[]
        for j in rs.frange(domainV[0],domainV[1]+0.001,floatVdivisions):
            pt=rs.EvaluateSurface(leafList[k],i,j)
            normalvector=rs.SurfaceNormal(leafList[k],[i,j])
            normalvector=rs.VectorUnitize(normalvector)
            normalvector=rs.VectorScale(normalvector,normalscale)
            normalpt=rs.VectorAdd(pt,normalvector)
            templist.append(pt)
            normaltemplist.append(normalpt)
            normalList.append(normalpt)
            leafPoints.append(pt)
    for a in range(0,len(leafPoints)-43):
        rs.AddSrfPt([leafPoints[a],leafPoints[a+21],leafPoints[a+1],leafPoints[a+22]])
        vector1=rs.VectorCreate(leafPoints[a],leafPoints[a+1])
        vector1=rs.VectorScale(vector1,-0.5)
        vector1=rs.VectorAdd(vector1,leafPoints[a])
        vector2=rs.VectorCreate(leafPoints[a+1],leafPoints[a+22])
        vector2=rs.VectorScale(vector2,-0.5)
        vector2=rs.VectorAdd(vector2,leafPoints[a+1])
        vector3=rs.VectorCreate(leafPoints[a+22],leafPoints[a+21])
        vector3=rs.VectorScale(vector3,-0.5)
        vector3=rs.VectorAdd(vector3,leafPoints[a+22])
        vector4=rs.VectorCreate(leafPoints[a+21],leafPoints[a])
        vector4=rs.VectorScale(vector4,-0.5)
        vector4=rs.VectorAdd(vector4,leafPoints[a+21])
        pt1=rs.AddPoint(vector1)
        pt2=rs.AddPoint(vector2)
        pt3=rs.AddPoint(vector3)
        pt4=rs.AddPoint(vector4)
        srf0=rs.AddSrfPt([pt1,pt2,pt3,pt4])
        srf.append(srf0)
        centerPoints=centerPts([pt1,pt2,pt3,pt4])
        crv2=rs.AddPolyline([pt1,pt2,pt3,pt4,pt1])
        centerPts0.append(centerPoints)
        crvList.append(crv2)
    for b in range(0,len(normalList)-43):
        pt5=rs.AddPoint(normalList[b])
        pt6=rs.AddPoint(normalList[b+21])
        pt7=rs.AddPoint(normalList[b+1])
        pt8=rs.AddPoint(normalList[b+22])
        srf1=rs.AddSrfPt([normalList[b],normalList[b+21],normalList[b+1],normalList[b+22]])
        centerPoints1=centerPts([pt5,pt6,pt7,pt8])
        centerPts1.append(centerPoints1)
    for c in range(0,len(centerPts0)):
        line=rs.AddLine(centerPts0[c],centerPts1[c])
        circle=rs.AddCircle(centerPts0[c],0.5)
        crv1=rs.ExtrudeCurve(circle,line)
        eval=rs.SurfaceClosestPoint(srf[c],centerPts0[c])
        normalvector1=rs.SurfaceNormal(srf[c],eval)
        normalvector1=rs.VectorUnitize(normalvector1)
        normalvector1=rs.VectorScale(normalvector1,random.randint(0,60))
        normalpt1=rs.VectorAdd(centerPts0[c],normalvector1)
        crv2=rs.AddPolyline([pt1,pt2,pt3,pt4,pt1])
        crv2=rs.ExtrudeCurvePoint(crvList[c],normalpt1)
        spheres=rs.AddSphere(normalpt1,random.random()*3)
    templist0.append(templist)
    normallist.append(normaltemplist)
rs.EnableRedraw(True)

More uneven surface tiling




Some nice pics showing effects of uneven surface tiling, lower one is with randomised heights (made solid for 3D-print).
Below are some happy accidents...



Fake Reaction Diffusion Pattern


This is a super easy script that fakes the turing pattern that guy did


### Super Easy Fake Turing Pattern
### Dennis Goff, 2012.04.26
### Please reference properly when using (parts of) this script :P

import rhinoscriptsyntax as rs
import math
import random

srf = rs.GetObject('select srf')
uDom = rs.SurfaceDomain(srf,0)
vDom = rs.SurfaceDomain(srf,1)

rs.EnableRedraw(False)
uStep = 30
vStep = 30
srfPts = []
normPts = []
for i in rs.frange(uDom[0],uDom[1],(uDom[1]-uDom[0])/uStep):
    for j in rs.frange(vDom[0],vDom[1],(vDom[1]-vDom[0])/vStep):
        pt = rs.EvaluateSurface(srf,i,j)
        norm = rs.SurfaceNormal(srf,(i,j))
        norm = rs.VectorUnitize(norm)
        norm = rs.VectorScale(norm,random.random()*15)
        norm = rs.VectorAdd(norm,pt)
        normPt = rs.AddPoint(norm)
        normPts.append(normPt)
        srfPts.append(pt)
rs.AddPoints(srfPts)
print len(normPts)
count = uStep, vStep+1
rs.AddSrfPtGrid(count,normPts)
rs.EnableRedraw(True)

Parabolic UV Subdivision


import rhinoscriptsyntax as rs

srf = rs.GetObject("Pick Surface",8)

du = rs.SurfaceDomain(srf,0)
dv = rs.SurfaceDomain(srf,1)
dumid =(du[1]-du[0])/2
dvmid =(dv[1]-dv[0])/2
udiv = 20
vdiv = 20
ustep =(du[1]-du[0])/udiv
vstep =(dv[1]-dv[0])/vdiv
print du,dv

rs.EnableRedraw(False)

centroid = rs.SurfaceAreaCentroid(srf)
coordcentroid = centroid[0]


ulist = []
for xu in rs.frange (-dumid,dumid,ustep):
    if xu<0:
        yu = -xu**2
    if xu>=0:
        yu = xu**2
    ulist.append(yu)
#ulist.sort()
umax = ulist[-1]
remapulist = []
for i in ulist:
    remapu = (i/((du[1]-du[0])/2))+((du[1]-du[0])/2)
#    print "i = ", i
#    print "du[1]-du[0] = ", du[1]-du[0]
#    print "remapu = " , remapu
    remapulist.append(remapu)
print remapulist



vlist = []
for xv in rs.frange (-dvmid,dvmid,vstep):
    if xv<0:
        yv = -xv**2
    if xv>=0:
        yv = xv**2
    vlist.append(yv)
vmax = vlist[-1]
remapvlist = []
for i in vlist:
    remapv = (i/((dv[1]-dv[0])/2))+((dv[1]-dv[0])/2)
#    print "i = ", i
#    print "dv[1]-dv[0] = ", dv[1]-dv[0]
#    print "remapv = " , remapv
    remapvlist.append(remapv)
print remapvlist

norlist = []
rowlist = []

for i in remapulist:
    columnlist = []
    colnorlist = []
    for j in remapvlist:
        pt = rs.EvaluateSurface(srf,i,j)
        columnlist.append(pt)
       
        norvect = rs.SurfaceNormal(srf,[i,j])
        norvect = rs.VectorUnitize(norvect)
        norpt = rs.VectorAdd(pt,norvect)
        colnorlist.append(norpt)
       
    rowlist.append(columnlist)
    norlist.append(colnorlist)



for i in range (0,len(rowlist)):
    for j in range (0,len(rowlist[i])):
        pts = rs.AddPoint(rowlist[i][j])
       
       
for i in range (0,len(norlist)):
    for j in range (0,len(norlist[i])):
        norpts = rs.AddPoint(norlist[i][j])
       



attpt = rs.GetPoint ("attractor point",1)
ratio = 0.02



for i in range (0,len(rowlist)-1):
    for j in range (0,len(rowlist[i])-1):
        rs.AddLine(rowlist[i][j],rowlist[i+1][j])
        rs.AddLine(rowlist[i+1][j],rowlist[i+1][j+1])
        rs.AddLine(rowlist[i+1][j+1],rowlist[i][j+1])
        rs.AddLine(rowlist[i][j+1],rowlist[i][j])
       
        vect = rs.VectorCreate(rowlist[i][j],rowlist[i+1][j])*(-1)
        dist = rs.Distance(rowlist[i][j],attpt)
        factor = dist*ratio
        scalevect = rs.VectorScale(vect,factor)
        pt1 = rs.VectorAdd(scalevect,rowlist[i][j])
        pt = rs.AddPoint(pt)
       
        vect = rs.VectorCreate(rowlist[i+1][j],rowlist[i+1][j+1])*(-1)
        dist = rs.Distance(rowlist[i+1][j],attpt)
        factor = dist*ratio
        scalevect = rs.VectorScale(vect,factor)
        pt2 = rs.VectorAdd(scalevect,rowlist[i+1][j])
        pt = rs.AddPoint(pt)
       
        vect = rs.VectorCreate(rowlist[i+1][j+1],rowlist[i][j+1])*(-1)
        dist = rs.Distance(rowlist[i+1][j+1],attpt)
        factor = dist*ratio
        scalevect = rs.VectorScale(vect,factor)
        pt3 = rs.VectorAdd(scalevect,rowlist[i+1][j+1])
        pt = rs.AddPoint(pt)
        
        vect = rs.VectorCreate(rowlist[i][j+1],rowlist[i][j])
        scalevect = rs.VectorScale(vect,0.2)
        pt4 = rs.VectorAdd(scalevect,rowlist[i][j+1])
        pt = rs.AddPoint(pt)
       
        l1 = rs.AddLine(pt1,pt2)
        l2 = rs.AddLine(pt2,pt3)
        l3 = rs.AddLine(pt3,pt4)
        l4 = rs.AddLine(pt4,pt1)
       
        l = rs.JoinCurves([l1,l2,l3,l4],delete_input=True, tolerance=None)
       
        rs.ExtrudeCurvePoint(l,(norlist[i][j]))
       
rs.EnableRedraw(True)