Showing posts with label RhinoScript. Show all posts
Showing posts with label RhinoScript. Show all posts

February 25, 2017

RhinoScript | Layout - Detail views sync



모델링 작업 중 4뷰를 빠르게 종이에 인쇄하여 확인하며 작업하는 경우가 종종 있습니다. 이 때 Layout 명령에서 디테일 4개를 이용하게 되는데, 각 뷰들의 크기가 달라 Top-Front-Right뷰가 서로 다른 크기로 출력되어 이 크기와 위치를 재 설정해야 합니다.

이를 쉽게 설정할 수 있는 방법으로 출력하고자하는 전체 개체 보다 조금 큰 구(Sphere)를 생성하여 Layout을 생성하게 되면 전체 뷰의 가로-세로 크기가 동일하게 설정됩니다. 레이아웃을 생성한 후에 이 구를 삭제하고 출력하면 간단히 4 뷰 포트를 동일한 크기로 설정할 수 있습니다. 물론 1:1 등 크기의 경우도 이렇게 설정한 후 각 디테일의 스케일을 조절하면 중심이 맞은 상태라 동일하게 설정됩니다.



Layout 4 details 명령에서 각 디테일 뷰가 맞지 않은 경우


구를 만들고 레이아웃을 생성한 후 다시 구를 삭제하는 과정을 라이노 스크립트로 쉽게 구현할 수 있습니다. 아래 스크립트는 전체 개체의 바운딩박스의 중심에서 모서리까지를 반지름으로 하는 구를 생성한 후 레이아웃을 생성하고 구를 삭제하는 스크립트입니다. New Layout : 4 Detail  버튼에 아래 스크립트를 대신 사용하면 아래 그림처럼 가로-세로가 맞는 4개의 디테일뷰를 쉽게 생성할 수 있습니다. 이 후 디테일의 디스플레이 모드를 변경하여 출력하면 간단히 Top-Front-Right뷰가 맞춰 인쇄할 수 있습니다.



Call Main()
Sub Main()
    Rhino.EnableRedraw False
    allObjects = Rhino.NormalObjects()
  
    Dim Objs()
    j = 0
    For Each A In allObjects
        i = Rhino.ObjectType(A)
        Select Case i
            Case 1,2,4,8,16,32,512,4096,8192,65536,1073741824
                ReDim Preserve Objs(j)
                Objs(j) = A
                j = j + 1
        End Select
    Next
  
    If j = 0 Then Exit Sub
  
    BB = Rhino.BoundingBox(Objs)
  
    C = middlePoint(BB(0), BB(6))
    R = Rhino.Distance(C, BB(0))  

    strSphere = Rhino.AddSphere(C, R)

    Rhino.Command "! _-Layout _Enter _Enter _Enter 4", False
  
    Rhino.DeleteObject strSphere
    Rhino.EnableRedraw True

End Sub

Function MiddlePoint (A, B)
    MiddlePoint = array((A(0) + B(0)) / 2, (A(1) + B(1)) / 2, (A(2) + B(2)) / 2)
End Function


스크립트를 실행한 디테일 뷰가 맞춰진 Layout

각 디테일 뷰의 디스플레이 모드를 변경한 모습


November 5, 2013

RhinoScript | Objects coverage area

개체들을 Top뷰에서 보았을 때 투영한 면적을 계산하기 위해서는 Top뷰에서 실루엣을 추출하고 이들의 합쳐진 커브의 면적을 계산하면 된다. 아래 스크립트는 건폐율 계산을 쉽게할 수 있도록 Top뷰의 실루엣 라인의 결합한 커브를 만들어준다. 스크립트는 단순히 Silhouette, CurveBoolean명령의 조합으로 작성되었다.


Option Explicit

Call Main()
Sub Main()
   
    Dim arrObjects, strView, arrBox, arrPt
    arrObjects = RHino.GetObjects("Surface or Polysurfaces", 8 + 16)
   
    If isNull(arrObjects) Then Exit Sub
   
    strView = Rhino.CurrentView
    Rhino.EnableRedraw False
    Rhino.CurrentView "Top"
   
    Rhino.SelectObjects  arrObjects
    arrBox = RHino.BoundingBox(arrObjects)
    arrPt = Rhino.PointAdd(arrBox(2), Rhino.VectorCreate(arrBox(2), arrBox(0)))
    Rhino.Command  "_Silhouette _ProjectToCPlane _Yes _CurveBoolean _DeleteInput=_All _CombineRegion=_Yes W" & RHino.Pt2Str(arrPt) & " _Enter", False
   
    Rhino.CurrentView strView
    Rhino.EnableRedraw True
   
End Sub

February 21, 2012

RhinoScript | Black&White gradient

얼마 전 MeshHighlightField 커맨드를 활용하여 타이어 패턴 디자인 이미지의 그라디언트로 부조형상을 만들어 모델링 작업을 최소화하여 3D프린팅이 가능하도록 프로세스 설정하는 교육을 진행하였다. 필요한 형상의 높이 변화에 알맞는 그라디언트 이미지를 조금 쉽게 만들 수 있는 스크립트를 만들어 사용하였는데, x,y좌표 (0,0)에서 (10,10)사이에 하나의 커브를 그려주면 y값 0-10을 밝기 0-255로 변환하여 이미지 그라디언트를 만들어 준다.

다음 스크립트는 GDI bitmap extension인 RhPicture를 사용하기에 설치되어있어야 사용가능하다. http://wiki.mcneel.com/developer/rhinoscriptimageextension 그리고 LineCurveIntersection method를 사용하기에 라이노 V5에서 사용할 수 있다. V4용으로는 일부 수정이 필요하다.

Option explicit
Call Main()
Sub Main()
    Dim strCrv    
    strCrv = Rhino.GetObject("Select a gradient curve", 4, True)
    If isNull(strCrv) Then Exit Sub
    Dim arrFace(0), arrVertices(3)
    Dim i, x, arrLine, arrCX, arrP, lngColor, H, arrC, j
    Dim RhPicture
    Set RhPicture = Rhino.GetPluginObject("RhPicture")
    Call RhPicture.CreateImage(200, 255, vbWhite)
    For i=0 To 255
        x = i / 25.5
        arrLine = array(array(x, 0, 0), array(x, 10, 0))
        arrCX = Rhino.LineCurveIntersection(arrLine, strCrv)
        If isArray(arrCX) Then
            arrP = arrCX(0, 1)
            H = round(arrP(1) * 25.5)
            lngColor = RGB(H, H, H)
            For j=0 To 200
                Call RhPicture.SetPixel(j, 255 - i, lngColor)
            Next
        End If           
    Next
    Call RhPicture.ShowImage("Black&White Gradient")           
    Set RhPicture = Nothing
End Sub


April 29, 2011

RhinoScript | Rainbow color RGB table

라이노 스크립트로 컬러 그라데이션을 나타내려고 할때 빨강에서 파랑으로 변하는 색을 제대로 표현하지 못해 애먹은 기억이 있다. Red에서 Blue로 변화되는 색상을 어레이로 출력해주는Function을 만들어 보았다.


첫번째 Fucntion은 Red Yellow Green Cyan Blue 사이를각 256단계의 색으로 만들었다. 이 경우 실제 적용시켰을 때 녹색 영역이 너무 넓어 빨강과 파란색이 조금 많이 안보이는 듯해서 Green-Cyan  , Cyan-Green을 128 단계로 수정한 것이 두번째 Function이다.  그래도 여전이 빨강과 파랑이 어둡진 않아서 빨강의 최대지점과 파란색의 최대지점을 잘 확인이 안되서 각 100 단계씩 추가한 것이 세번째 Function이다.


참고로 Function을 적용하여 메쉬 버텍스의 높이에 따라 색상을 표현한 간단한 사용 예를 함께 작성해보았다.

--------------------------------------------------------------------------------------------------

Function ColorMapRainbow1()
  Dim lngCol(1023),i
  For i=0 To 1023
      If i < 256 Then
          '(255,0,0) to (255,255,0).
          lngCol(1023-i) = RGB(255, i, 0)
      ElseIf i < 512 Then
          '(255,255,0) to (0,255,0).
          lngCol(1023-i) = RGB(255 - (i-256), 255, 0)
      ElseIf i< 768 Then
          '(0,255,0) to (0,255,255).
          lngCol(1023-i) = RGB(0, 255, i-512)
      Else
          '(0,255,255) to (0,0,255).
          lngCol(1023-i) = RGB(0, 255 - (i-768), 255)
      End If
  Next
 
  ColorMapRainbow1 = lngCol  
End Function



--------------------------------------------------------------------------------------------------
Function ColorMapRainbow2()
  Dim lngCol(767),i
  For i=0 To 767
      If i < 256 Then
          '(255,0,0) to (255,255,0).
          lngCol(767-i) = RGB(255, i, 0)
      ElseIf i < 384 Then
          '(255,255,0) to (0,255,0).
          lngCol(767-i) = RGB(255 - (i-256)*2, 255, 0)
      ElseIf i< 512 Then
          '(0,255,0) to (0,255,255).
          lngCol(767-i) = RGB(0, 255, (i-384)*2)
      Else
          '(0,255,255) to (0,0,255).
          lngCol(767-i) = RGB(0, 255 - (i-512), 255)
      End If
  Next
 
  ColorMapRainbow2 = lngCol  
End Function
   
--------------------------------------------------------------------------------------------------
Function ColorMapRainbow3()
  Dim lngCol(967),i
  For i=0 To 967
      If I<100 Then
          '(155,0,0) to (255,0,0)
          lngCol(967-i) = RGB(255-(100-i), 0, 0)
      ElseIf i < 356 Then
          '(255,0,0) to (255,255,0).
          lngCol(967-i) = RGB(255, i-100, 0)
      ElseIf i < 484 Then
          '(255,255,0) to (0,255,0).
          lngCol(967-i) = RGB(255 - (i-356)*2, 255, 0)
      ElseIf i< 612 Then
          '(0,255,0) to (0,255,255).
          lngCol(967-i) = RGB(0, 255, (i-484)*2)
      ElseIf I<868 Then
          '(0,255,255) to (0,0,255).
          lngCol(967-i) = RGB(0, 255 - (i-612), 255)
      Else
          '(0,0,255) to (0,0,155)
          lngCol(967-i) = RGB(0, 0, 255-(i-868))
      End If
  Next
 
  ColorMapRainbow3 = lngCol  
End Function

--------------------------------------------------------------------------------------------------

사용예 : 메쉬 버텍스의 Z값에 따라 색상을 표현

main
Sub main()

Dim ColMap, strObject, arrVertices, Vcount, i,j

ColMap = ColorMapRainbow3

strObject = Rhino.GetObject("Select mesh")
arrVertices = Rhino.MeshVertices(strObject)

Vcount=UBound(arrVertices)

ReDim arrColors(Vcount), arrColorIndex(Vcount)
ReDim Z(Vcount)

For i=0 To Vcount
  Z(i)=arrVertices(i)(2)
  arrColorIndex(i)=i
Next


SortByKey Z, arrColorIndex


For i=0 To Vcount
  j=Int(i/Vcount *UBound(ColMap))
  arrColors(arrColorindex(i)) = ColMap(j)
Next

Rhino.MeshVertexColors strObject, arrColors

 
 
End Sub
   
  

Sub QuickSort(ByRef A(), ByRef B(), ByVal min, ByVal max)
    Dim i : i = min: Dim k : k = max
    If (max - min) >= 1 Then
        Dim pivot : pivot = A(min)
        While (k > i)
            While (A(i) <= pivot And i <= max And k > i)
                i = i+1
            Wend
            While (A(k) > pivot And k >= min And k >= i)
                k = k-1        
            Wend       
            If (k > i) Then Call SwapElements(A, B, i, k)                  
        Wend
        Call SwapElements(A, B, min, k)
        Call QuickSort(A, B, min, k-1)
        Call QuickSort(A, B, k+1, max)
    End If
End Sub
Sub SwapElements(ByRef A(), ByRef B(), ByVal i0, ByVal i1)
    Dim loc_A : loc_A = A(i0)
    Dim loc_B : loc_B = B(i0)
    A(i0) = A(i1)
    B(i0) = B(i1)
    A(i1) = loc_A
    B(i1) = loc_B
End Sub

Function SortByKey(ByRef Keys(), ByRef Values())
    Call QuickSort(Keys, Values, 0, UBound(Keys))
End Function

December 7, 2010

RhinoScript | Recursion - Menger sponge



Rhinoscript를 이용한 Recursion의 수업 예제로 만들어본 Menger sponge인데, 개체의 수가 많이지니 라이노에서 렌더링 자체가 문제가 된다. 그래서 Block을 이용해보았으나 Rhino내에서 디스플레이나 라이노렌더 등은 문제가 없으나 V4에서 Vray로 렌더링시 Block을 이용한 경우는 그나마 괜찮긴한데 메모리 문제로 렌더링 불가.. 참고로 나의 노트북 메모리는 6GB이다. 그런데 같은 모델을 Keyshot으로 넘겨서 테스트를 해보니 너무 문제없이 잘된다. Keyshot파일로 저장하니 라이노 블럭으로 66MB이던 파일이 1.45GB로 커지긴하지만 렌더링에는 전혀 문제가 없었다. 아래는 메쉬 박스를 블럭으로 만들어 Menger sponge를 모델링하는 스크립트이다. Function 호출시 menger_sponge strBox, 0, 4 로 호출하면 위 그림과 같은 단계까지 반복한다.


Option Explicit
main
Sub main()

Dim strBox, arrCorners, arrObjects

arrCorners=Rhino.GetBox  
If IsNull(arrCorners) Then Exit Sub
 
strBox= AddMeshBox (arrCorners)
Rhino.SelectObject strBox
Rhino.Command "-NoEcho Unweld 10 enter", False
Rhino.Command "-Block 0 enter enter enter enter", False
Rhino.UnselectAllObjects
Rhino.Command "SelLast"
arrObjects=Rhino.SelectedObjects
strBox= arrObjects(0)

Rhino.EnableRedraw False

menger_sponge strBox, 0, 2

Rhino.EnableRedraw True
 
End Sub

Function menger_sponge(strBox,N, NL)
 
  Dim arrCorners, lX,lY,lZ, X,Y,Z, arrBox(2,2,2), arrPoint
  IIf N < NL Then
    arrCorners=Rhino.BoundingBox(strBox)
    lX = (arrCorners(1)(0)-arrCorners(0)(0))/3
    lY = (arrCorners(3)(1)-arrCorners(0)(1))/3
    lZ = (arrCorners(4)(2)-arrCorners(0)(2))/3

    strBox=Rhino.ScaleObject(strBox,arrCorners(0), Array(1/3,1/3,1/3))
   
    For Z=0 To 2
      For Y=0 To 2
        For X=0 To 2
          If ((Z=1 And (X+Y) Mod 2 <>0) Or (X=1 And Y=1) ) Then
            arrBox(X,Y,Z)=Null
            Else
            arrPoint= Rhino.PointAdd(arrCorners(0),Array(lX*X, lY*Y, lZ*Z) )
            arrBox(X,Y,Z) =  Rhino.CopyObject (strBox,arrCorners(0), arrPoint)          
          End If
        Next
      Next
    Next
    Rhino.DeleteObject strBox
   
    For Z=0 To 2
      For Y=0 To 2
        For X=0 To 2
          If Not IsNull(arrBox(X,Y,Z)) Then
          menger_sponge arrBox(X,Y,Z), N+1, NL
          End If     
        Next
      Next
    Next
   
 
  End If
End Function


Function AddMeshBox (arrPoints)

  Dim arrFace(5)
  arrFace(0) = Array(3,2,1,0)
  arrFace(1) = Array(0,1,5,4)
  arrFace(2) = Array(1,2,6,5)
  arrFace(3) = Array(2,3,7,6)
  arrFace(4) = Array(3,0,4,7)
  arrFace(5) = Array(4,5,6,7)
 
  AddMeshBox = Rhino.Addmesh (arrPoints, arrFace) 
 
End Function

August 27, 2010

Rhinoscript | Boy surface



http://mathworld.wolfram.com/BoySurface.html

Option Explicit
'2010년 8월 27일 금요일
'Script written by Sanghoon Yoon @ +plastic
'Script copyrighted by +plastic

main
Sub main()
 
  Dim PP, N, ST, i, u,v, X,Y,Z, A,B,C, arrPoints 
    PP=Rhino.Pi
    N=50
    ST=PP/(N-1)
 
  ReDim arrPoints(N*N-1)

    i=0
  For u=0 To PP Step ST
    For v=0 To PP Step ST
   
      A= Cos(u)*Sin(v) : B=Sin(u)*Sin(v) : C=Cos(v)

      X=0.5*(2*A^2-B^2-C^2+2*B*C*(B^2-c^2)+C*A*(A^2-C^2)+A*B*(B^2-A^2))
      Y=Sqr(3)/2*(B^2-C^2+(C*A*(C^2-A^2)+A*B*(B^2-A^2)))
      Z=(A+B+C)*((A+B+C)^3+4*(B-A)*(C-B)*(A-C))/5

      arrPoints(i) =Array(X,Y,Z)
      i=i+1
    Next
  Next

  Rhino.AddSrfPtGrid Array(N,N), arrPoints

End Sub




February 9, 2010

Let it go straight on

곡면을 하나 생성한 뒤에 그 곡면 위에서 방향을 하나 설정하여 그 방향으로 계속 이어지는 직선을 그려보면 곡면 위에 한 선으로 그려진 곡선을 얻을 수 있다. 라이노 스크립트를 이용해서 앞의 과정을 수행한 후 그 곡선에 Smooth, Fair 커맨드를 이용해 보았다. 가상의 3d 공간 상에서는 쉽게 존재하는 것들이 실제에서는 힘든 경우가 많은데 이것도 그런 경우인 듯 하다.

Farthest 2 points on a curve

라이노스크립트를 이용하여 커브 위의 가장 먼 거리에 있는 두 점을 찾는 스크립트이다.
폐곡선 위에서 가장 먼곳에 놓인 두 점을 찾는 질문이 있었는데 Recursion방법을 이용하지 않고는 힘들 것 같아 스크립트로 작성해 보았다.







라이노스크립트를 이용하여 커브위의 가장 먼거리에 있는 두 점을 찾는 스크립트입니다.
질문이 있었는데 Recursion방법을 이용하지 않고는 힘들것 같아 스크립트를 작성해보았습니다.
더 좋은 방법들도 가능할 듯 합니다.

Option Explicit
'2010년 2월 9일 화요일
'Script written by Sanghoon Yoon @ +plastic
'Script copyrighted by +plastic

main

Public S,E

Sub main()
Dim strObject, arrDomain
strObject=Rhino.GetObject("Select closed curve",4)
If isNull(strObject) Then Exit Sub
arrDomain=Rhino.CurveDomain (strObject)
S=arrDomain(0): E=arrDomain(1)
Call MaxDev ( strObject, S,E,S,E,0)
End Sub


Function MaxDev(StrObject,S1,E1,S2,E2,DmaxOld)

Dim Stp1, Stp2, arrPt1, arrPt2, Dist, Dmax, strLine,i,j
Dim NS1,NE1,NS2,NE2
Stp1=(E1-S1)/30:Stp2=(E2-S2)/30
For i=S1 To E1 Step Stp1
arrPt1=Rhino.EvaluateCurve (strObject, i)
For j=S2 To E2 Step Stp2
arrPt2=Rhino.EvaluateCurve (strObject, j)
Dist=Rhino.Distance(arrPt1, arrPt2)
If Dist > Dmax Then
Dmax=Dist
NS1=i-Stp1:NE1=i+Stp1
NS2=j-Stp2:NE2=j+Stp2
End If
Next
Next

If Abs(Dmax-DmaxOld)<0.00001 Then
i= NS1+stp1:j= NS2+stp2
If i<S Then i=S:If j>E Then j=E
strLine=Rhino.AddLine (Rhino.EvaluateCurve (strObject,i), Rhino.EvaluateCurve (strObject, j))
Rhino.SelectObject strLine
Rhino.Print "Distance:"& Round(Rhino.CurveLength (strLine),3)
Exit Function
End If
Call MaxDev (strObject, NS1, NE1,NS2,NE2, Dmax)

End Function

December 1, 2009

Rhinoscript | Linear transition


얼마전 모델하우스 프로젝트에서 두가지의 커브가 입력되면 그 두 커브사이의 중간 모양의 커브를 생성하는 스크립트를 만들었다. 프로젝트에서는 두 커브 모두 폐곡선인 경우라 간단한 스크립트로 가능하였다.
스크립트를 조금 수정하여 입력되는 커브가 폐곡선이던 열린곡선이던 Periodic이던 Non-periodic이던 상관없이 그리고 Knot의 갯수, Degree에 상관없이 사용할수 있도록 수정하였는데, 대부분 잘 작동하나 일부 오류가 발생하는 경우가 있어 조금 수정이 필요한 상태이다.

October 22, 2009

RhinoScript | Function to reparameterize

몇일전 스크립트 작업을 하던중 RhinoScript에 reparametrize 기능이 없어 Rhino.command를 이용했었는데, 아무래도 function을 만들어 두면 많이 사용 될것 같아서. . .

아래 function은 입력된 커브나 서피스를 0-1 로 reparameterize 하게된다.

Function ReparameterizeCurve(strObject)
       
    Dim intDegree, arrKnots, arrNKnots(),arrPoints, arrWeights, arrDomain,k
   
        intDegree = Rhino.CurveDegree(strObject)
        arrKnots = Rhino.CurveKnots(strObject)
        arrPoints = Rhino.CurvePoints(strObject)
        arrWeights = Rhino.CurveWeights(strObject)
        arrDomain = Rhino.CurveDomain(strObject)
       
    k=Ubound(arrKnots)
   
    ReDim arrNKnots(k)
    For i=0 To k
        arrNKnots(i)= (arrKnots(i)-arrDomain(0))/(arrDomain(1)-arrDomain(0))
    Next
   
    ReparameterizeCurve = Rhino.AddNurbsCurve (arrPoints, arrNKnots, intDegree , arrWeights)
           
End Function


Function ReparameterizeSrf (strObject)
       
    Dim arrDegree, arrKnots, arrNKnotsV(),arrNKnotsU(),arrPoints, arrWeights, arrDomainU,arrDomainV, k, arrPointCount,L
        arrPointCount = Rhino.SurfacePointCount(strObject)
        arrDegree = Rhino.surfaceDegree(strObject)
        arrKnots = Rhino.SurfaceKnots(strObject)
        arrPoints = Rhino.SurfacePoints(strObject)
        arrWeights = Rhino.SurfaceWeights(strObject)
        arrDomainU = Rhino.SurfaceDomain(strObject,0)
        arrDomainV = Rhino.SurfaceDomain(strObject,1)
       
        k=Ubound(arrKnots(0))
        L=Ubound(arrKnots(1))
   
    ReDim arrNKnotsU(k)
    For i=0 To k
        arrNKnotsU(i)= (arrKnots(0)(i)-arrDomainU(0))/(arrDomainU(1)-arrDomainU(0))
    Next
   
   
    ReDim arrNKnotsV(L)
    For i=0 To L
        arrNKnotsV(i)= (arrKnots(1)(i)-arrDomainV(0))/(arrDomainV(1)-arrDomainV(0))
    Next

    ReparameterizeSrf = Rhino.AddNurbsSurface (arrPointCount, arrPoints, arrNKnotsU, arrNKnotsV, arrDegree , arrWeights)
           
End Function

September 22, 2009

Earth with pipes - new +plastic name card image







라이노 스크립트를 이용해 구면에 대지영역만 표시하고 높이 이미지의 밝기 값에 따라 각 점의 높이를 나타내어 커브 파이프를 이용하여 렌더링해서 완성하였다. 많은 오브젝트 갯수 때문에 수차례 다운되어 꽤 시간이 소요되었다.+plastic의 새로운 로고로 새로 제작하는 명함을 위한 이미지이다.

September 3, 2009

RhinoScript | Critical draft angle



대지의 경사도에 따라 개발 제한이 있다는 사실을 이 프로젝트 시작과 더불어 알게 되었다. 개발 가능 영역의 확인을 위해 규제 제한 각도이상의 기울기를 갖는 영역을 RhinoTerrain 에서 만들어진 메쉬의 Normal Vector를 이용하여 구하였다. 물론 라이노의 DraftAnlge 커맨드로도 충분히 확인이 가능하였지만 임계각의 정확한 경계를 구분하기 위해 RhinoScript를 이용하였다. 그런데 폴리곤 메쉬의 밀도에 따라 그 영역이 정확히 가려지지 않는다는 생각이다. 물론 그 폴리곤 메쉬의 밀도가 높을 수록 정확하다고 할수 있다.

그래서 실제 등고선 라인을 나누어 그 점과 다음 레벨의 등고선의 각도를 이용할수 있도록 스크립트를 수정하였다. 법적인규제가 모두 등고라인을 기준으로 하기에 더 근접한 영역을 얻을 수 있었다. 아래 그림은 등고라인 1m 간격으로 나누어 이를 준으로 제한 각도 이상을 표시한 것이다.

August 11, 2009

Rhinoscript | CenterWall

Slab 커맨드가 벽체 모델링에 아주 유용하기는 하나 센터라인을 기준으로 그리는 경우에는 조금 불편한점이 있다. 아래는 Offset -> Loft -> ExtrudeSrf 과정의 Macro를 이용하여 센터라인을 기준으로 벽체를 만들수 있는 스크립트이다. 최근 실제 프로젝트에서는 복수의 커브를 입력으로 하는 스크립트를 제작하여 활용하여 모델링 시간을 줄일 수 있었다. VisualARQ가 완성도가 있어지면 별 필요없을듯...

Option Explicit
centerWall
Sub centerWall()

Rhino.Command "Offset Pause Bothsides"
Dim arrObjects, strObject, arrLoft, arrWall, Wall
arrObjects = Rhino.LastCreatedObjects

If IsNull(arrObjects) Then Exit Sub

For Each strObject In arrObjects
Rhino.SimplifyCurve strObject
Next

arrLoft = Rhino.AddLoftSrf (arrObjects,,,2,0)

Rhino.SelectObjects arrLoft

Rhino.Command "MergeAllFaces ExtrudeSrf DeleteInput=Yes"

Rhino.DeleteObjects arrObjects

arrWall = Rhino.LastCreatedObjects

Rhino.SurfaceIsocurveDensity arrWall(0) ,-1

End Sub

June 23, 2009

RhinoScript | Select curves by linetypes

Sub SelectbyLinetype()

Dim arrLineTypes, strLinetype, arrObjects, strObject
Dim i : i=0
Rhino.UnselectAllObjects

arrLinetypes = Rhino.LinetypeNames

strLinetype = Rhino.GetString("Linetype to select objects", arrLinetypes(0), arrLinetypes)

Rhino.EnableRedraw False

arrObjects = Rhino.ObjectsByType (4 )

Rhino.UnselectAllObjects

For Each strObject In arrObjects

If strLinetype = Rhino.ObjectLinetype (strObject) Then
  Rhino.SelectObject strObject
  i=i+1
End If

Next

Rhino.Print CStr(i)&" curves was selected."
Rhino.EnableRedraw True
End Sub


입력한 Linetype인 커브들를 선택하는 간단한스크립트를인데 라이노스 질문에 답하느라 만들었다. 도면 작업시 간혹 유용하게 쓰일 것 같다.

April 15, 2009

Technical drawing mode in page layout




Technical drawing display mode를 사용하면 간단히 은선제거를 할 수 있어 3D 모델에 바로 도면 작업을 하여 Make2D를 사용하는 것보다 훨씬 간단히 2D 도면을 작성할 수 있다.
그러나 Techincal drawing 으로 모드 변환 커맨드가 없어 여러 detail을 macro등으로 추가할때 불편한 경우가 있다. 이럴때 라이노스크립트를 이용하면 간단히 뷰전환이 가능하다.

Rhino.ViewDisplayModeEx Rhino.CurrentView(,False), "Technical"

물론 Arch Cut과 함께 사용하면 단면 드로잉도 편하게 작업이 가능하다. 이때 Section이 보이지 말아야 할 뷰에서 나타나는 경우가 있는데, HideInDetail / ShowInDetail 커맨드를 사용하면 해당 Detail에서만 오브젝트들을 숨기는 것이 가능하다.

February 15, 2009

RhinoScript | Print Layout pages to Pdf files with Bullzip Pdf printer

지난 주말 도면 작업을 할 일이 있어 Layout 기능을 활용해 쉽게 작업할 수 있었다. 그런데, 여러장의 Layout을 사용하다 보니, 일일히 프린트 하는 것이 문제가 될줄이야...
Rhino의 Print 커맨드가 여러장을 선택적으로 프린트 하는 기능이 없어, 여러가지 방법을 생각하다가 Pdf printer를 이용하는 방법을 시도해보았다.

Bullzip Pdf printer는 문서출력의 결과를 Pdf파일로 저장해주는 가상 프린터이다.여러종류의 pdf프린터가 있지만, Bullzip은 무료로 쓸수 있으면서도 많은 기능을 제공한다. COM/ActiveX interface도 제공하기에 스크립트를 이용한 자동화를 가능 하다.
http://www.bullzip.com/products/pdf/info.php

아래 스크립트를 이용하기 위해서는 Bullzip printer가 설치되어 있어야 한다. 그리고 Page Layout이 있어야 하며 모든 Layout을 pdf파일로 저장한다. 하나의 파일로 저장할지, 각각의 파일로 저장할지 선택할 수 있다. 물론 각 Layout의 프린터를 Bullzip pdf printer로 설정되어 있어야 한다. 프린트를 할때 뿐만 아니라 pdf파일을 생성하기 위한 도구로도 사용이 가능해보인다.


Option Explicit
'2009.2.15
'Script by Sanghoon Yoon @ +plastic
'http://www.byRhino3d.com | http://www.rhinos.co.kr | http://sac3.blogspot.com
'sac3yoon@gmail.com
'This script let Rhino to print all layout pages as pdf files through Bullzip pdf printer.
'Download Bullzip pdf printer @ http://www.bullzip.com/products/pdf/info.php

PrintLayoutAsPDF
Sub PrintLayoutAsPDF
Dim strSS
strSS = Rhino.GetString ("File option" , "As_one_Pdf", Array ("As_one_Pdf", "As_each_Pdf") )
If IsNull(strSS) Then Exit Sub
Select Case strSS
Case "As_one_Pdf"
SaveAsOnePdf
Case "As_each_Pdf"
SaveAsEachPdf
End Select
End Sub

Sub SaveAsEachPdf()
Dim strFile,strFolder, arrViews,fileName, strM
strM=""
strFolder = Rhino.BrowseForFolder
arrViews = Rhino.ViewNames (True ,1)
If IsNull(arrViews) Then Rhino.Print "No layout pages!" : Exit Sub
For Each fileName In arrViews
Rhino.CurrentView fileName
strFile=strFolder&fileName&".pdf"
BatchPrint strFile,strM
Rhino.Print strFile&" was created."
Next
End Sub

Sub SaveAsOnePdf()
Dim strFile,strFolder, arrViews,fileName
strFile= Rhino.SaveFileName ("Save as pdf" ,"pdf files (*.pdf)|*.pdf||" , "" , ,"pdf")
arrViews = Rhino.ViewNames (True ,1)
If IsNull(arrViews) Then Rhino.Print "No layout pages!" : Exit Sub
For Each fileName In arrViews
Rhino.CurrentView fileName
BatchPrint strFile,strFile
Next
Rhino.Print strFile&" was created."
End Sub

Function BatchPrint(strFile,strM)
Const PDF_PRINTERNAME = "Bullzip PDF Printer"
Const PRINTER_PROGID = "Bullzip.PDFPrinterSettings"
Dim prtidx, obj
'Configure the PDF print job
Set obj = CreateObject(PRINTER_PROGID)
obj.SetValue "mergefile",strM
obj.SetValue "mergeposition","bottom"
obj.SetValue "Output", strFile
obj.SetValue "ConfirmOverwrite", "no"
obj.SetValue "ShowSaveAS", "never"
obj.SetValue "ShowSettings", "never"
obj.SetValue "ShowPDF", "no"
obj.SetValue "RememberLastFileName", "no"
obj.SetValue "RememberLastFolderName", "no"
obj.WriteSettings True

Rhino.Command "-print go ",False

'Wait for runonce settings file to disappear
Dim runonce, fso
runonce = obj.GetSettingsFileName(True)
Set fso = CreateObject("Scripting.FileSystemObject")
While fso.FileExists(runonce)=True
Sleep 100
Wend
End Function

December 19, 2008

RhinoScript | Cut solids

절삭의 방법으로 형상을 디자인할때 솔리드를 평면을 기준으로 컷팅하는 방법이 아주 유용하다. 그러나 라이노에서는 평면을 생성하고 다시 불린 커맨드를 실행해야하는 불편함을 요구하는 분들이 있다.

그래서, 3점을 입력하면 그 점을 기준으로 하는 평면으로 오브젝트를 잘라주는 스크립트를 만들었다. 점을 입력할때 클릭하는 방향에 따라 생셩되는 평면의 Normal방향이 달라져 잘려나가는 부분이 바뀌게 된다.






Option Explicit
'2008.12.10
'Script by sac3@rhinos.co.kr

CutSolid
Sub CutSolid ()

Dim arrObjects, arrPoints, arrVector1, arrVector2, arrBD, strCut

arrObjects = Rhino.GetObjects ("Select Solids to Cut",8+16,vbTrue,vbTrue)
If IsNull(arrObjects) Then Exit Sub

arrPoints = Rhino.GetPoints (True, False , "Pick 3 Points",, 3 )
If IsNull(arrPoints) Then Exit Sub
If UBound(arrPoints) <2 Then Exit Sub

Rhino.EnableRedraw False

arrVector1= Rhino.VectorCreate (arrPoints(0), arrPoints(1) )
arrVector2= Rhino.VectorCreate (arrPoints(0), arrPoints(2) )
strCut = Rhino.AddCutPlane (arrObjects, arrPoints(0), arrPoints(1) , arrVector2)
arrBD = Rhino.BooleanDifference (arrObjects, Array(strCut) )

If IsArray(arrBD) Then
Rhino.ShrinkTrimmedSurface arrBD(0)
Rhino.SelectObjects arrBD
Else
Rhino.DeleteObject strCut
Rhino.Print "Failed to Cut"
End If

Rhino.EnableRedraw True

End Sub



참고로 평면들이 서로 겹친 부분들이 있는 경우, BooleanUnion을 하고나면, 그 부분의 평면이 나뉘게 되는데, 그 부분을 하나의 면으로 합쳐주기 위해서는 MergeAllFaces 커맨드를 사용하면 된다.
동영상에서는 두 커맨드를 macro를 이용하여 한번에 실행되도록 해둔 것 이다.

! _BooleanUnion Pause
_SetRedrawOff _SelLast
_MergeAllFaces _SelNone
_SetRedrawOn

December 2, 2008

RhinoScript Workshop


라이노 스크립트 워크샵

RhinoScript 는 Microsoft의 VBScript 언에에 기초한 스크립트 언어로 라이노에서 새로운 기능을 추가하거나 반복 작업을 자동화하는 것이 가능합니다. 본 워크샵은 스크립트를 처음 시작하려는 분들에게 적합한 과정으로 VBScript의 기본적인 내용(변수, 배열, 조건문, 반복문, 함수의 정의 및 사용법)은 물론 라이노에서 스크립트의 사용법을 소개합니다. 본 과정은 RhinoScript101 ( http://www.rhino3d.com/rhinoscript101 ) 을 기초로 진행됩니다.

일시 : 2008년 12월 13일 토요일 (10:00 - 18:00)

장소 : 단국대학교 미술관 (패션제품디자인과) 422호

대상 :
- RhinoScript를 사용하고자 하는 산업/실내/가구 디자이너, 건축가 및 대학(원)생
- 라이노의 기본 사용법을 알고 있는 분을 대상으로 합니다.

인원 : 25명 /선착순 마감

교재 : RhinoScript101 / 무료제공

강사 : 윤상훈
- +plastic 대표 / McNeel Asia 국내 기술지원 및 교육
- 단국대학교 패션제품디자인과 겸임교수

참가비 : 20만원

November 27, 2008

Heat map



최근에, 리서치 프로젝트에서 그래픽 작업을 맡아 참여하게 되었다. 그래픽 디자인, 렌더링과 같은 일인 줄 알고 시작했는데, 수집된 데이터에서 Heat Map을 그리는게 가장 중요한 일어였다. 여러가지 Heat Map을 구현할 방법을 찾다가, 적절한 툴을 찾지 못해, 결국 Rhino로 수집된 점 데이터를 옮겨서, RhinoScript를 이용해 거리관계에서 Mesh의 색상을 결정하는 스크립트를 만들어서 이용하였다. 개선이 필요한 방법인것 같긴한데, 너무 급하게 진행된 프로젝트라 그대로 이미지처리를 하였다. 전체 데이터의 종류도 여러가지가 있어 작업 전반에 스크립트를 활요하게 되었는데, 정말 RhinoScript의 생각지도 못한 사용이었고 많은 시간 단축이 가능했다. 다음 프로젝트가 진행된다면, 더 나은 Heat Map 처리 방법을 좀 더 고민해봐야 할 듯 하다.

위의 이미지는 임의이 이미지 파일에 데이터를 입력하여 처리한 결과이다. 입력된 데이터는 점으로 표시되었다. 라이노의 뷰포트 화면을 캡쳐한 결과이다.