option explicit

' conditional surface louver example (c) axel kilian 2003 akilian@mit.edu
' feel free to use this code as a starting point  but please leave this note in it if you use it

sub uvTest
	'variable to hold the ID of selected surface   
       Dim strObject     

       'array to hold u count (0) and v count (1) of selected surface 
       redim arrUVcount(1)  

       ' variable to hold normal 
       redim arrUVcountNorm(1) 
                                                                                                            
       ' variable to hold u count 
       dim arrDomainU, arrDomainV            
       dim arrNorm 
       dim j,i     
       strObject = Rhino.GetObject("Select a surface")  


	If Rhino.IsSurface(strObject) Then
		
		' temporary point at UV  
               redim ptUV(1)
                                                                                                  
               ' query surface for u an v point count and store in arrDomainU and arrDomainV var 
               arrDomainU = Rhino.SurfaceDomain(strObject, 0)
               arrDomainV = Rhino.SurfaceDomain(strObject, 1)
                  
		   ' extract the U and V value from the domain
		   arrUVcount(0) = arrDomainU(1) 
		   arrUVcount(1) = arrDomainV(1)
			  
		   Rhino.MessageBox  arrUVcount(0)
    
		   ' array to store the points 3d coordinate at each uv coord
		   redim arrPoints(1,((arrUVcount(0)+1) * (arrUVcount(1)+1)))                                                                                     
               ' array to store the normal at each point      
               redim arrNormal((arrUVcount(0)+1) * (arrUVcount(1)+1))
		                                                                                             
		   ' nested loops store 2 layers of points - offset by height of normal (1 unit)
		   ' points are stored in arrPoints 
               for j=0 to arrUVcount(1)           
                       ' U dimension  
                       for i=0 to arrUVcount(0)       
                               ' variable holding the current total point number  
                               dim pointNum   
					 ' current point count
                               pointNum = (j*(arrUVcount(0)+1))+i   
					
					 ' assign current u an v value (in this case i an j - could be anything else
					 ptUV(0) = i
					 ptUV(1) = j
					 'Rhino.MessageBox  i

					 ' assign the 3d value of uv point to point array var (0=lower points)
					 arrPoints(0,pointNum) = Rhino.EvaluateSurface(strObject, ptUV)
					 
					 ' draw points for debugging
					 Rhino.AddPoint arrPoints(0,pointNUm)

					 ' store the normal at that uv point				
					 arrNorm = Rhino.SurfaceNormal(strObject, ptUV)
					 ' draw the normal for debugging
					 Rhino.AddLine arrNorm(0),arrNorm(1)
					 ' store the toppoint of the normal in point array (1=top points)
					 arrPoints(1,pointNum) = arrNorm(1)
				next
		   next

		' create 8 (4 on top - 4 on bottom) temp point variables for tube drawing
		dim pt1,pt5
		dim pt2,pt6
		dim pt3,pt7
		dim pt4,pt8
		dim hp
		hp = Array(1,1,1)
		hp = Array 
		' nested loops - subtracting 1 von u and v dimension since we are stepping 
		' one point ahead in both u and v from current point to draw tube to
		' pt1 i j  	   -> pt2 i+1 j
		'   |			   |
		'  \ /		  \ /
		'pt3 j+1 i    ->  pt4 j+1 i+1
		' pt5-pt8 same on top of the normals of pt1-pt4
			
		redim poly1(3),poly2(3)

		for j=0 to (arrUVcount(1)-1)
				for i=0 to (arrUVcount(0)-1) 
					pt1 = arrPoints(0,(j*(arrUVcount(0) +1 ))+i)
					pt2 = arrPoints(0,(j*(arrUVcount(0)+1  ))+i+1)
					pt3 = arrPoints(0,((j+1)*(arrUVcount(0)+1  ))+i)
					pt4 = arrPoints(0,((j+1)*(arrUVcount(0)+1 ))+i+1)
					pt5 = arrPoints(1,(j*(arrUVcount(0)+1 ))+i)
					pt6 = arrPoints(1,(j*(arrUVcount(0)+1  ))+i+1)
					pt7 = arrPoints(1,((j+1)*(arrUVcount(0)+1 ))+i)
					pt8 = arrPoints(1,((j+1)*(arrUVcount(0)+1 ))+i+1)
					dim testx,testy,testz,testx2,testy2,testz2  
					testx = pt1(0)+1
					testy = pt1(1)-2
					testz = pt1(2)+1
					hp = Array(testx,testy,testz)

					testx2 = pt4(0)
					testy2 = pt4(1)

					' simple test case for the orientation of the louver in relation to the surface normal
					testz2 = pt4(2)-testz
					
					'in one case the louver is drawn flat - for the other connecting to the direction of the light
					if (testz2<0) then 
					
						poly1(0) = pt2
						poly1(1) = hp
						poly1(2) = pt1
						poly1(3) = pt1

						poly2(0) = pt3
						poly2(1) = hp
						poly2(2) = pt1
						poly2(3) = pt1

					else 
						poly1(0) = pt2
						poly1(1) = pt1
						poly1(2) = pt3
						poly1(3) = pt3

						poly2(0) = pt2
						poly2(1) = pt4
						poly2(2) = pt3
						poly2(3) = pt3
					end if
					
					Rhino.AddSrfPt poly1
					Rhino.AddSrfPt poly2

					Rhino.AddLine pt1,pt2
					Rhino.AddLine pt2,pt4
					Rhino.AddLine pt4,pt3
					Rhino.AddLine pt3,pt1
					Rhino.AddLine pt1,hp	
				next
		next
	End If
end sub	

' call the uv subroutine to draw tubes as spaceframe over a UV plane with as many grid cells as 
' there are u an v dimensions (routine queries the nurbs surface
uvTest