Option Explicit '------------------------------------------------------------------------------ 'Subroutine: Roof 'Purpose: an example of parametric design 'Pablo Miranda Carranza, code released under GNU General Public License (www.gnu.org/licenses/gpl.txt) '------------------------------------------------------------------------------ Sub Roof() Dim strObject Dim arrPoints Dim arrCount Dim u,v Dim pt1,pt2,pt3,pt4 Dim ctrface Dim ctrcirc Dim uvparam Dim tropdir Dim normp Dim normsize Dim vec1,vec2 Dim d1,d2,d3,d4 Dim base1,base2,base3,base4 Dim basepts(4) Dim toppts(4) Dim surfacegen Dim scval strObject = Rhino.GetObject("Pick a surface", 8) arrPoints = Rhino.SurfacePoints(strObject) arrCount = Rhino.SurfacePointCount(strObject) Rhino.Print "Point count in U direction: " & CStr(ArrCount(0)) Rhino.Print "Point count in V direction: " & CStr(ArrCount(1)) ctrface=array(0,0,0) ctrcirc=array(0,0,0) normp=array(0,0,0) tropdir=array(1,0.5,-0.5) For u = 0 To arrCount(1) - 2 For v = 0 To arrCount(0) - 2 'these are the indexes, or the 'adresses' of the four points in each rectangular 'patch' of the surface pt1= u*arrCount(0)+v pt2= (u+1)*arrCount(0)+v pt3= (u+1)*arrCount(0)+v+1 pt4= u*arrCount(0)+v+1 'calculate centroid, average position of the four vertices of the surface ctrface(0)=arrPoints(pt1)(0)+arrPoints(pt2)(0)+arrPoints(pt3)(0)+arrPoints(pt4)(0) ctrface(1)=arrPoints(pt1)(1)+arrPoints(pt2)(1)+arrPoints(pt3)(1)+arrPoints(pt4)(1) ctrface(2)=arrPoints(pt1)(2)+arrPoints(pt2)(2)+arrPoints(pt3)(2)+arrPoints(pt4)(2) ctrface(0)=ctrface(0)/4 ctrface(1)=ctrface(1)/4 ctrface(2)=ctrface(2)/4 'calculate normal. Since we are using the control points, this won't exactly be the normal to the surface... vec1=array(arrPoints(pt2)(0)-arrPoints(pt1)(0),arrPoints(pt2)(1)-arrPoints(pt1)(1),arrPoints(pt2)(2)-arrPoints(pt1)(2)) vec2=array(arrPoints(pt3)(0)-arrPoints(pt1)(0),arrPoints(pt3)(1)-arrPoints(pt1)(1),arrPoints(pt3)(2)-arrPoints(pt1)(2)) normp(0) = vec1(1)*vec2(2) - vec1(2)*vec2(1) normp(1) = vec1(2)*vec2(0) - vec1(0)*vec2(2) normp(2) = vec1(0)*vec2(1) - vec1(1)*vec2(0) normsize=sqr(normp(0)*normp(0)+ normp(1)*normp(1)+normp(2)*normp(2)) normp(0)=normp(0)/normsize normp(1)=normp(1)/normsize normp(2)=normp(2)/normsize 'and now put the circle, its centre in the centre of the square (calculated above) 'and a normal direction added, to give some distance from it ctrcirc(0)=ctrface(0)- normp(0) ctrcirc(1)=ctrface(1)- normp(1) ctrcirc(2)=ctrface(2)- normp(2) d1= array(arrPoints(pt1)(0)-ctrface(0),arrPoints(pt1)(1)-ctrface(1),arrPoints(pt1)(2)-ctrface(2)) d2= array(arrPoints(pt2)(0)-ctrface(0),arrPoints(pt2)(1)-ctrface(1),arrPoints(pt2)(2)-ctrface(2)) d3= array(arrPoints(pt3)(0)-ctrface(0),arrPoints(pt3)(1)-ctrface(1),arrPoints(pt3)(2)-ctrface(2)) d4= array(arrPoints(pt4)(0)-ctrface(0),arrPoints(pt4)(1)-ctrface(1),arrPoints(pt4)(2)-ctrface(2)) basepts(0)=arrPoints(pt4) basepts(1)=arrPoints(pt3) basepts(2)=arrPoints(pt2) basepts(3)=arrPoints(pt1) basepts(4)=arrPoints(pt4) base1=Rhino.AddCurve (basepts ,1) ctrcirc(0)=ctrface(0)- 2*normp(0)+0.5*tropdir(0) ctrcirc(1)=ctrface(1)- 2*normp(1)+0.5*tropdir(1) ctrcirc(2)=ctrface(2)- 2*normp(2)+0.5*tropdir(2) scval=0.6 basepts(0)=array(ctrcirc(0)+scval*d3(0),ctrcirc(1)+scval*d3(1),ctrcirc(2)+scval*d3(2)) basepts(1)=array(ctrcirc(0)+scval*d4(0),ctrcirc(1)+scval*d4(1),ctrcirc(2)+scval*d4(2)) basepts(2)=array(ctrcirc(0)+scval*d1(0),ctrcirc(1)+scval*d1(1),ctrcirc(2)+scval*d1(2)) basepts(3)=array(ctrcirc(0)+scval*d2(0),ctrcirc(1)+scval*d2(1),ctrcirc(2)+scval*d2(2)) basepts(4)=array(ctrcirc(0)+scval*d3(0),ctrcirc(1)+scval*d3(1),ctrcirc(2)+scval*d3(2)) base2=Rhino.AddCurve (basepts ,3) ctrcirc(0)=ctrcirc(0)- normp(0)+tropdir(0) ctrcirc(1)=ctrcirc(1)- normp(1)+tropdir(1) ctrcirc(2)=ctrcirc(2)- normp(2)+tropdir(2) scval=0.4 basepts(0)=array(ctrcirc(0)+scval*d1(0),ctrcirc(1)+scval*d1(1),ctrcirc(2)+scval*d1(2)) basepts(1)=array(ctrcirc(0)+scval*d4(0),ctrcirc(1)+scval*d4(1),ctrcirc(2)+scval*d4(2)) basepts(2)=array(ctrcirc(0)+scval*d3(0),ctrcirc(1)+scval*d3(1),ctrcirc(2)+scval*d3(2)) basepts(3)=array(ctrcirc(0)+scval*d2(0),ctrcirc(1)+scval*d2(1),ctrcirc(2)+scval*d2(2)) basepts(4)=array(ctrcirc(0)+scval*d1(0),ctrcirc(1)+scval*d1(1),ctrcirc(2)+scval*d1(2)) base3=Rhino.AddCurve (basepts ,3) Rhino.command ("-loft selID " & base1 & " selID " & base2 & " selID " & base3 & " enter enter enter") Next Next End Sub Roof()