If you been following this blog then you're probably aware of my work on the cantilevered roller coaster concept model. I recently created a new track to simulate the motion capability of the vehicle. I needed a quick and easy way to create all of the cross-ties which hold the two running rails together in order to create a CAD model which is as realistic as possible. At first, I was using patterns for each section of track: rectangular pattern for straight sections and circular patterns for turns and hills. This was a very time consuming process. My model contains two track that are currently around a thousand feet long. With a little bit of help from a CATIA forum, I was able to put together a CATScript which quickly and easily creates all of the cross-ties at once.
In order to get this work there are a few things that needed to be done. The rails had to be in their own separate part file. There had to be a geometrical set named "Rollercoaster." You have to select the guide curves for each rail before running the VBA code.
Here is the procedure used in the CATScript:
1. Place point1 on guidecurve1 and point2 on guidecurve2 each at equal distance from their start points.
2. Create plane normal to guidecurve1 through point1.
3. Find an intersection between normal plane and guidecurve2
4. Use near operation to select element from intersection that lie on guidecurve2 (in case if there are multiple intersections). Use point2 as reference element. Then redefine point2 to point found.
5. Place a tangent line to guidecurve1 at point1 using AddNewLineTangency method with length limits -1.5'' and 1.5'' (tangentline1)
6. Place a tangent line to guidecurve2 at point2 using AddNewLineTangency method with length limits -1.5'' and 1.5'' (tangentline2)
7. Look for points at ends of tangentline1 with AddNewPointOnCurveFromPercent method using 0% and 100% values.
8. Look for points at ends of tangentline2 with AddNewPointOnCurveFromPercent method using 0% and 100% values.
9. Connect points from 3 and 4 with lines using AddNewLinePtPt method.
10. Create new fill object using AddNewFill method and add tangent lines and lines from 5 to it using it's AddBound method.
11. Create a pad using AddNewPad method of ShapeFactory object of root part of active document.
Pictured is the track before and after the macro is ran. Here is the complete code:
Automatically Create Cross-ties for a Roller Coaster
Option Explicit
Private Const ONE_FOOT_MM = 30 ' define number of millimiteres in one foot
Private Const STEP_LENGTH = 48 ' length between cross-ties, in feet
Private Const PAD_SIDE = 3 ' length of single cross-tie side, in feet
Sub CATMain()
' accessing part object
Dim RootPart As Part
Set RootPart = CATIA.ActiveDocument.Part
' retrieving target geometrical set named "Rollercoaster"
Dim TargetGeoSet As HybridBody
Set TargetGeoSet = RootPart.HybridBodies.Item("
' define partbody as work object
Dim PartBody As Body
Set PartBody = RootPart.MainBody
RootPart.InWorkObject = PartBody
' accessing selection object for current document
Dim objSelection As Selection
Set objSelection = CATIA.ActiveDocument.Selection
' retrieving reference for first curve
Dim GuideCurve1 As AnyObject
Set GuideCurve1 = objSelection.Item2(1).Value
Dim refCurve1 As Reference
If (TypeName(GuideCurve1) = "CATIAReference") Or (TypeName(GuideCurve1) = "MonoDimFeatEdge") Then
Set refCurve1 = GuideCurve1
Else
Set refCurve1 = RootPart.
End If
' retrieving reference for second curve
Dim GuideCurve2 As Object
Set GuideCurve2 = objSelection.Item2(2).Value
Dim refCurve2 As Reference
If (TypeName(GuideCurve2) = "CATIAReference") Or (TypeName(GuideCurve2) = "MonoDimFeatEdge") Then
Set refCurve2 = GuideCurve2
Else
Set refCurve2 = RootPart.
End If
' Retrieving guides' lengths
Dim PartProd As Product
Set PartProd = CATIA.ActiveDocument.Product
Dim SPAWbench As SPAWorkbench
Set SPAWbench = CATIA.ActiveDocument.
Dim objMeasurable As Measurable
Set objMeasurable = SPAWbench.GetMeasurable(
Dim GuideLength1 As Double
GuideLength1 = SPAWbench.GetMeasurable(
Dim GuideLength2 As Double
GuideLength2 = SPAWbench.GetMeasurable(
' Equidistance points
Dim PointOnCurve1 As HybridShapePointOnCurve
Dim PointOnCurve2 As HybridShapePointOnCurve
Dim refPOC1 As Reference
Dim refPOC2 As Reference
' Normal plane
Dim NormalPlane As HybridShapePlaneNormal
Dim refNPlane As Reference
Dim objIntersection As HybridShapeIntersection
Dim refIntersection As Reference
Dim objNear As HybridShapeNear
Dim refNear As Reference
' Tangent lines
Dim TangentLine1 As HybridShapeLineTangency
Dim TangentLine2 As HybridShapeLineTangency
Dim refTLine1 As Reference
Dim refTLine2 As Reference
' endpoints for tangetnt lines
Dim TLine1EndPoint1 As HybridShapePointOnCurve
Dim TLine1EndPoint2 As HybridShapePointOnCurve
Dim TLine2EndPoint1 As HybridShapePointOnCurve
Dim TLine2EndPoint2 As HybridShapePointOnCurve
Dim refTL1EPoint1 As Reference
Dim refTL1EPoint2 As Reference
Dim refTL2EPoint1 As Reference
Dim refTL2EPoint2 As Reference
' lines, that connect endpoints of tangent lines
Dim BoundLine1 As HybridShapeLinePtPt
Dim BoundLine2 As HybridShapeLinePtPt
Dim refBLine1 As Reference
Dim refBLine2 As Reference
' fill object
Dim objFill As HybridShapeFill
Dim refFill As Reference
' direction line
Dim DirectionLine As Line
Dim refDLine As Reference
' pad object
Dim objPad As Pad
Dim refPad As Pad
' construction parameters
Dim StepLength As Double
StepLength = STEP_LENGTH * ONE_FOOT_MM
Dim PadSideLength As Double
PadSideLength = PAD_SIDE * ONE_FOOT_MM
Dim curDistance As Double
curDistance = StepLength
' accessing factory for creating shape objects
Dim objHSF As HybridShapeFactory
Set objHSF = RootPart.HybridShapeFactory
' accessing factory for creating solid objects
Dim objHF As ShapeFactory
Set objHF = RootPart.ShapeFactory
' define correct direction for second curve
Dim SecondCurveDirection As Boolean
Dim NormalDirectionDistance As Double
Dim InvertDirectionDistance As Double
' get distance for normal direction
Set PointOnCurve1 = objHSF.
Set PointOnCurve2 = objHSF.
Set refPOC1 = RootPart.
Set refPOC2 = RootPart.
TargetGeoSet.AppendHybridShape PointOnCurve1
TargetGeoSet.AppendHybridShape PointOnCurve2
RootPart.Update
Set objMeasurable = SPAWbench.GetMeasurable(
NormalDirectionDistance = objMeasurable.
objSelection.Clear
objSelection.Add PointOnCurve2
objSelection.Delete
' get distance for invert direction
Set PointOnCurve2 = objHSF.
Set refPOC2 = RootPart.
TargetGeoSet.AppendHybridShape PointOnCurve2
RootPart.Update
InvertDirectionDistance = objMeasurable.
If (NormalDirectionDistance < InvertDirectionDistance) Then
SecondCurveDirection = True
Else
SecondCurveDirection = False
End If
objSelection.Clear
objSelection.Add PointOnCurve1
objSelection.Add PointOnCurve2
objSelection.Delete
' start constructing pads
Do While (curDistance < GuideLength1)
' place point on first curve at specified distance
Set PointOnCurve1 = objHSF.
Set refPOC1 = RootPart.
' create plane normal to first curve at initially created point
Set NormalPlane = objHSF.AddNewPlaneNormal(
Set refNPlane = RootPart.
' define second point as intersection of normal plane and second curve
Set objIntersection = objHSF.AddNewIntersection(
Set refIntersection = RootPart.
Set PointOnCurve2 = objHSF.
Set refPOC2 = RootPart.
Set objNear = objHSF.AddNewNear(
Set refNear = RootPart.
Set refPOC2 = refNear
'Set refPOC2 = RootPart.
' construct tangent lines
Set TangentLine1 = objHSF.AddNewLineTangency(
Set TangentLine2 = objHSF.AddNewLineTangency(
TargetGeoSet.AppendHybridShape TangentLine1
TargetGeoSet.AppendHybridShape TangentLine2
' get reference objects for tangent lines
Set refTLine1 = RootPart.
Set refTLine2 = RootPart.
' Get endpoints for tangent lines
Set TLine1EndPoint1 = objHSF.
Set TLine1EndPoint2 = objHSF.
Set TLine2EndPoint1 = objHSF.
Set TLine2EndPoint2 = objHSF.
TargetGeoSet.AppendHybridShape TLine1EndPoint1
TargetGeoSet.AppendHybridShape TLine1EndPoint2
TargetGeoSet.AppendHybridShape TLine2EndPoint1
TargetGeoSet.AppendHybridShape TLine2EndPoint2
' get reference objects for endpoints
Set refTL1EPoint1 = RootPart.
Set refTL1EPoint2 = RootPart.
Set refTL2EPoint1 = RootPart.
Set refTL2EPoint2 = RootPart.
' construct bound lines
Set BoundLine1 = objHSF.AddNewLinePtPt(
Set BoundLine2 = objHSF.AddNewLinePtPt(
TargetGeoSet.AppendHybridShape BoundLine1
TargetGeoSet.AppendHybridShape BoundLine2
Set refBLine1 = RootPart.
Set refBLine2 = RootPart.
' create fill with contour
Set objFill = objHSF.AddNewFill()
objFill.AddBound refTLine1
objFill.AddBound refBLine1
objFill.AddBound refTLine2
objFill.AddBound refBLine2
TargetGeoSet.AppendHybridShape objFill
Set refFill = RootPart.
' create direction
Set DirectionLine = objHSF.AddNewLineNormal(
Set refDLine = RootPart.
TargetGeoSet.AppendHybridShape DirectionLine
' create pad
Set objPad = objHF.AddNewPadFromRef(
' define pad limits
objPad.FirstLimit.Dimension.
objPad.SecondLimit.Dimension.
' set direction
objPad.SetDirection refDLine
' move to construction of the next pad
curDistance = curDistance + StepLength
Loop
' Update part to see added objects
RootPart.Update
End Sub



No comments:
Post a Comment
I'd love to hear from you!