Saturday, June 28, 2008

Finite Element Analysis

Creating geometry for Finite Element Analysis (FEA). FEA is a computer simulation
technique used in engineering analysis (straight from Wiki...) It requires all the line geometries to be meeting at points. If you are Osnap-ing manually, there is high chance that you miss a couple. So, here it is. Out of spline and two offset splines, this script creates basic structure for a bridge.

User has to provide with manually-built normals at each division point. Length doesn't matter. It is to show direction only, and will be deleted by the end of the script.

_Confusion between stringPt and arrPt
_Playing with Layer method
_In Loop, lines require to refer a point from previous round

Option Explicit
'Author: YukiukiH
'Date: 06/28/2008
'compatibility: Rhino4
'memo: watch arrPt and strPt

'before run...
'1. given spline.
'2. divide spline.
'3. draw normal at each points. (use perpendicular to curve/ from first point)

Sub bridgeSt

'first things first...
Rhino.AddLayer "splineCenter", RGB(255,0,0) 'black
Rhino.AddLayer "centerPt", RGB(0,0,0) 'black
Rhino.AddLayer "normalAxis", RGB(0,0,0) 'black
Rhino.AddLayer "normal01", RGB(255,161,0) 'gold
Rhino.AddLayer "normal02", RGB(255,127,0) 'orange
Rhino.AddLayer "side01", RGB(0,0,0) 'black
Rhino.AddLayer "side02", RGB(0,0,0) 'black
Rhino.AddLayer "Pt", RGB(0,0,0) 'black

Rhino.AddLayer "Line011", RGB(63,191,191) 'turquoise
Rhino.AddLayer "Line022", RGB(63,191,191) 'turquoise
Rhino.AddLayer "Line033", RGB(0,0,0) 'black
Rhino.AddLayer "Line044", RGB(0,0,0) 'black
Rhino.AddLayer "Line055", RGB(255,0,0) 'red

'organizing object layers
Dim strSpline, arrstrCenPt, arrstrNormalAxis
Dim arrPt, arrPts, strCenPt, dblLength

strSpline = Rhino.GetObject ("select a spline curve", 4)
Rhino.ObjectLayer strSpline , "splineCenter"
Rhino.LayerVisible "splineCenter", False

arrstrCenPt = Rhino.GetObjects ("select center points", 1)
Rhino.ObjectLayer arrstrCenPt , "centerPt"
Rhino.CurrentLayer ("CenterPt")
Rhino.DeleteObjects arrstrCenPt

'by length segment
dblLength = 1500
arrPts = Rhino.DivideCurveLength(strSpline, dblLength)

'by segments
'intSegments = 130
'arrPoints = Rhino.DivideCurve(strSpline, intSegments)

For Each arrPt In arrPts
strCenPt = Rhino.AddPoint (arrPt)

arrstrNormalAxis = Rhino.GetObjects ("select normal lines IN ORDER", 4)
Rhino.ObjectLayer arrstrNormalAxis , "normalAxis"

'at each point...

Dim i, arrNormalAxisStPt, arrNormalAxisEdPt
Dim strLine01, strLine02, arrSt(2), arrEd(2), arrReference(1), arrTarget(1)

arrSt(0) = 0
arrSt(1) = 0
arrSt(2) = 0
arrEd(0) = 2000 'bridge width
arrEd(1) = 0
arrEd(2) = 0

For i = 0 To UBound (arrstrNormalAxis)

'create vector out of string normal, and orient lines
arrNormalAxisStPt = Rhino.CurveStartPoint (arrstrNormalAxis(i))
arrNormalAxisEdPt = Rhino.CurveEndPoint (arrstrNormalAxis(i))
Rhino.LayerVisible "normalAxis", False

arrReference(0) = arrSt
arrReference(1) = arrEd
arrTarget(0) = arrNormalAxisStPt
arrTarget(1) = arrNormalAxisEdPt

Rhino.CurrentLayer ("normal01")
strLine01 = Rhino.AddLine (arrSt, arrEd)
Rhino.OrientObject strLine01, arrReference, arrTarget

Rhino.CurrentLayer ("normal02")
strLine02 = Rhino.AddLine (arrSt, arrEd)
Rhino.OrientObject strLine02, arrReference, arrTarget
Rhino.RotateObject strLine02, arrNormalAxisStPt, 180

'prepare vector for 3d rotation
Dim arrLine01EdPt, arrLine02EdPt
Dim strLine01axis, strLine02axis
Dim arrLine01StPt, arrLine02StPt, arrAxis01, arrAxis02
Dim strLine01vrt, strLine02vrt

arrLine01EdPt = Rhino.CurveEndPoint (strLine01)
arrLine02EdPt = Rhino.CurveEndPoint (strLine02)

strLine01axis = Rhino.RotateObject (strLine01, arrLine01EdPt, 90,, True)
strLine02axis = Rhino.RotateObject (strLine02, arrLine02EdPt, 90,, True)

arrLine01StPt = Rhino.CurveStartPoint (strLine01axis)
arrLine02StPt = Rhino.CurveStartPoint (strLine02axis)

arrAxis01= Rhino.VectorCreate (arrLine01EdPt, arrLine01StPt)
arrAxis02= Rhino.VectorCreate (arrLine02EdPt, arrLine02StPt)

strLine01vrt = Rhino.CopyObject(strLine01)
Rhino.ObjectLayer strLine01vrt, "side01"
Rhino.RotateObject strLine01vrt, arrLine01EdPt, 100, arrAxis01

strLine02vrt = Rhino.CopyObject(strLine02)
Rhino.ObjectLayer strLine02vrt, "side02"
Rhino.RotateObject strLine02vrt, arrLine02EdPt, 100, arrAxis02

Rhino.DeleteObject (strLine01axis)
Rhino.DeleteObject (strLine02axis)

'add string points
Dim arrStPtLine01vrt, arrStPtLine02vrt, arrEdPtLine01vrt, arrEdPtLine02vrt
Dim strStPtLine01vrt, strStPtLine02vrt, strEdPtLine01vrt, strEdPtLine02vrt

Rhino.CurrentLayer ("Pt")

arrStPtLine01vrt = Rhino.CurveStartPoint (strLine01vrt)
arrStPtLine02vrt = Rhino.CurveStartPoint (strLine02vrt)
strStPtLine01vrt = Rhino.AddPoint (arrStPtLine01vrt)
strStPtLine02vrt = Rhino.AddPoint (arrStPtLine02vrt)

arrEdPtLine01vrt = Rhino.CurveEndPoint (strLine01vrt)
arrEdPtLine02vrt = Rhino.CurveEndPoint (strLine02vrt)
strEdPtLine01vrt = Rhino.AddPoint (arrEdPtLine01vrt)
strEdPtLine02vrt = Rhino.AddPoint (arrEdPtLine02vrt)

'create lines between current(B) and previous(A)
Dim strLine011, arrLine011PtA, arrLine011PtB, arrpt011PtAtemp
Dim strLine022, arrLine022PtA, arrLine022PtB, arrpt022PtAtemp
Dim strLine033, arrLine033PtA, arrLine033PtB, arrpt033PtAtemp
Dim strLine044, arrLine044PtA, arrLine044PtB, arrpt044PtAtemp
Dim strLine055, arrLine055PtA, arrLine055PtB, arrpt055PtAtemp
Dim strEdPtVrt03, strEdPtVrt04

'prepare current(B) and previous(A)points
If i = 0 Then

'BTM line (Line011, 022)
arrLine011PtA = arrLine01EdPt
arrLine022PtA = arrLine02EdPt

'TP line (Line 033, 044)
arrLine033PtA = Rhino.CurveStartPoint (strLine01vrt)
arrLine044PtA = Rhino.CurveStartPoint (strLine02vrt)

'MD line (Line 055)
arrLine055PtA = arrPts(i)


'BTM line (Line011, 022)
arrpt011PtAtemp = arrLine01EdPt
arrpt022PtAtemp = arrLine02EdPt
arrLine011PtB = arrpt011PtAtemp
arrLine022PtB = arrpt022PtAtemp

'TP line (Line 033, 044)
arrpt033PtAtemp = Rhino.CurveStartPoint (strLine01vrt)
arrpt044PtAtemp = Rhino.CurveStartPoint (strLine02vrt)
arrLine033PtB = arrpt033PtAtemp
arrLine044PtB = arrpt044PtAtemp

'MD line (Line 055)
arrpt055PtAtemp = arrPts(i)
arrLine055PtB = arrpt055PtAtemp

'add line (Line 011, 022, 033, 044, 055)
Rhino.CurrentLayer ("Line011")
strLine011 = Rhino.AddLine (arrLine011PtA, arrLine011PtB)

Rhino.CurrentLayer ("Line022")
strLine022 = Rhino.AddLine (arrLine022PtA, arrLine022PtB)

Rhino.CurrentLayer ("Line033")
strLine033 = Rhino.AddLine (arrLine033PtA, arrLine033PtB)

Rhino.CurrentLayer ("Line044")
strLine044 = Rhino.AddLine (arrLine044PtA, arrLine044PtB)

Rhino.CurrentLayer ("Line055")
strLine055 = Rhino.AddLine (arrLine055PtA, arrLine055PtB)

' prepare for next round
'BTM line (Line011, 022)
arrLine011PtA = arrLine011PtB
arrLine022PtA = arrLine022PtB

'TP line (Line033, 044)
arrLine033PtA = arrLine033PtB
arrLine044PtA = arrLine044PtB

'MD line (Line055)
arrLine055PtA = arrLine055PtB

End If

End Sub