Hole to hole fastener mesh
Hole to hole fastener mesh
(OP)
I am brand new to FEMAP and FEA type software. I am trying to use the hole to hole fastener mesh under custom tools to create a mesh for my fastener holes. I have a lot of fasteners in my model and everytime I create a mesh it creates a new property. I really do not want to keep track of 100+ properties for my fasteners. Is there an easier way to do this or can I combine my properties somehow? Thanks for any assistance I am very new to this program.





RE: Hole to hole fastener mesh
RE: Hole to hole fastener mesh
Best regards
Diego Moreno
RE: Hole to hole fastener mesh
DMoreno's comments are correct and may be helpful. In addition, I would like to offer you an API that I created to automatically make bolt elements by selecting all the curves in an area of the model. It looks for "loops" which make up holes, so if you pick some extra curves, it shouldn't matter. This version actually asks if you want to use an existing Beam property, CBUSH property (If so, creates coincident node CBUSH elements), or enter a bolt radius. If you enter a bolt radius, all elements created will use the same Property.
Please post any questions, comments or concerns about this API on this thread and I will do my best to answer them. In addition, if you already have "hundreds" of API fastener properties, I could also write a "property consolidation" API for the fastener elements which may be helpful. Please let me know.
Thanks,
Andy - FEMAP development
Code starts here:
Sub Main
Dim App As femap.model
Set App = feFemap()
Dim Cu As femap.Curve
Set Cu = App.feCurve
Dim cuSet As femap.Set
Set cuSet = App.feSet
Dim CircSet As femap.Set
Set CircSet = App.feSet
Dim CircSubSet As femap.Set
Set CircSubSet = App.feSet
Dim FinSet As femap.Set
Set FinSet = App.feSet
Dim PointSet As femap.Set
Set PointSet = App.feSet
Dim IndNdSet As femap.Set
Set IndNdSet = App.feSet
Dim feNode As femap.Node
Set feNode = App.feNode
Dim nodeSet As femap.Set
Set nodeSet = App.feSet
Dim feElem As femap.Elem
Set feElem = App.feElem
Dim DeleteSet As femap.Set
Set DeleteSet = App.feSet
Dim El As femap.Elem
Set El = App.feElem
Dim P As femap.Prop
Set P = App.feProp
Dim pset As femap.Set
Set pset = App.feSet
Dim listtype(0) As Long
Dim entityID(0) As Long
Dim FaceID(0) As Long
Dim Expanded(0) As Long
Dim BoReg(0) As Long
Dim BoVal(0) As Double
Dim Preload As Double
Dim BeamElID As Long
Dim PropID As Long
Dim BeamID As Long
Dim RAD As Double
Dim cuCenter As Variant
Dim cuNormal As Variant
Dim cuStartPt As Variant
Dim cuEndPt As Variant
Dim cuAngle As Double
Dim cuRadius As Double
Dim nd1loc(2) As Double
Dim nd2loc(2) As Double
Dim dist As Double
Dim DistCurrent As Double
Dim pt1 As Long
Dim pt2 As Long
Dim nodeCount As Long
Dim nodeX As Double
Dim nodeY As Double
Dim nodeZ As Double
Dim nodeID As Long
Dim elemID As Long
Dim vNodeArray As Variant
Dim BeamArea As Double
Dim Vec(3) As Variant
Dim X As Double
Dim Y As Double
Dim Z As Double
Dim X1 As Double
Dim Y1 As Double
Dim Z1 As Double
Dim VecP As Variant
Dim feMatl As femap.Matl
Set feMatl = App.feMatl
Dim matID As Long
rc = App.feAppMessageBox (3, "Select Existing Beam or Spring-CBUSH Property (No=Enter Bolt Radius)")
If rc=2 Then
GoTo Done
End If
If rc=0 Then
matID = App.Info_ActiveID( FT_MATL )
If matID = 0 Then
Msg = "No active material for fastener, please activate a material and re-run."
rc = MsgBox( Msg, vbOkOnly, "No Material" )
GoTo Done
End If
rc = feMatl.Get( matID )
'Section Values A
Radagain:
rc = App.feGetReal ("Enter Bolt Radius", 0.000000001, 1000000, RAD)
If rc = 2 Then
GoTo Done
End If
PropID = P.NextEmptyID
P.title = "API Fastener"
P.type = FET_L_BEAM
P.flagI(1) = 5
P.pval (40) = RAD
P.ComputeShape (False, False, True)
P.matlID = matID
P.Put(PropID)
Proptype = P.type
Else
again:
rc = pset.SelectID (FT_PROP, "Select Beam Property for Bolt", PropID)
If rc = 2 Then
GoTo Done
End If
P.Get (PropID)
proptype = P.type
If proptype <> 5 Then
If proptype = 6 Then
isBush = P.flag(3)
If isBush = True Then
refCSYS = P.flag(0)
If refCSYS = True Then
GoTo MoveOn
Else
rc = App.feAppMessageBox (1, "Selected Spring Property does not have Orientation CSys defined. Select Different Property?")
If rc = 2 Then
GoTo Done
Else
GoTo Again
End If
End If
Else
rc = App.feAppMessageBox (1, "Selected Spring Property is not set to CBUSH. Select Different Property?")
If rc = 2 Then
GoTo Done
Else
GoTo Again
End If
End If
Else
rc = App.feAppMessageBox (1, "Selected Property is not a Beam or Spring Property. Select Different Property?")
If rc = 2 Then
GoTo Done
Else
GoTo Again
End If
End If
End If
End If
MoveOn:
cuSet.Select (FT_CURVE, True, "Select Curves for Bolts")
cuID = cuSet.First
While cuID > 0
Cu.Get(cuID)
rc = Cu.ArcCircleInfo( cuCenter, cuNormal, cuStartPt, cuEndPt, cuAngle, cuRadius )
If rc = FE_OK Then
CircSet.Add (cuID)
End If
cuID = cuSet.Next
Wend
CircID = CircSet.First
While CircID > 0
Cu.Get(CircID)
Cu.EndPoints (pt1, pt2)
CircSubSet.AddRule (pt1, FGD_CURVE_BYPOINT)
CircSubSet.AddRule (pt2, FGD_CURVE_BYPOINT)
CircSubID = CircSubSet.First
While CircSubID > 0
Cu.Get(CircSubID)
Cu.EndPoints (pt1, pt2)
CircSubSet.AddRule (pt1, FGD_CURVE_BYPOINT)
CircSubSet.AddRule (pt2, FGD_CURVE_BYPOINT)
CircSubID = CircSubSet.Next
Wend
FinSet.AddCommon (CircSet.ID, CircSubSet.ID)
CuNum = FinSet.Count
PointSet.AddSetRule (FinSet.ID, FGD_POINT_ONCURVE)
PtNum = PointSet.Count
If CuNum <> PtNum Then
GoTo Skip
End If
' Get a set of nodes for this rigid element
rc = nodeSet.AddSetRule( FinSet.ID, FGD_NODE_ATCURVE )
If nodeSet.Count = 0 Then
App.feAppMessageBox (0, "No nodes exist on a selected curve(s). Exiting...")
GoTo Jumping_Out
End If
'Lets see how many nodes were selected
nodeCount = nodeSet.Count()
If nodeCount > 0 Then
' Walk the nodes and find the average
rc = nodeSet.Reset()
nodeID = nodeSet.Next()
ReDim nodeArray(nodeCount) As Long
Dim passCount As Long
passCount = 0
Do While nodeID <> 0
nodeArray(passCount) = nodeID
passCount = passCount + 1
rc = feNode.Get(nodeID)
nodeX = nodeX + feNode.x
nodeY = nodeY + feNode.y
nodeZ = nodeZ + feNode.z
nodeID = nodeSet.Next()
Loop
vNodeArray = nodeArray
nodeID = feNode.NextEmptyID
feNode.ID = nodeID
feNode.x = nodeX / nodeCount
feNode.y = nodeY / nodeCount
feNode.z = nodeZ / nodeCount
rc = feNode.Put(nodeID)
IndNdSet.Add (nodeID)
If rc = -1 Then 'return code FE_OK
' create the element
elemID = feElem.NextEmptyID
feElem.type = FET_L_RIGID
feElem.topology = FTO_RIGIDLIST
feElem.Node(0) = nodeID 'Independent Node
feElem.release(0, 0) = 1
feElem.release(0, 1) = 1
feElem.release(0, 2) = 1
feElem.ID = elemID
rc = feElem.PutNodeList(0, nodeCount, vNodeArray, Null, Null, Null)
rc = feElem.Put(elemID)
nodeCount = 0
rc = nodeSet.Clear()
nodeX = 0#
nodeY = 0#
nodeZ = 0#
End If
End If
Skip:
PointSet.Clear
CircSet.RemoveSet (FinSet.ID)
FinSet.Clear
CircSubSet.Clear
CircID = CircSet.Next
Wend
If IndNdSet.Count = 1 Then
Nd1 = IndNdSet.First
DeleteSet.AddRule (nd1, FGD_ELEM_BYNODE)
feElem.Delete (DeleteSet.First)
feNode.Delete (Nd1)
GoTo Jumping_Out
End If
nd1 = IndNdSet.First
While nd1 > 0
feNode.Get(nd1)
nd1loc(0) = feNode.x
nd1loc(1) = feNode.y
nd1loc(2) = feNode.z
DistCurrent = 1000000.0
nd2 = IndNdSet.Next
IndNdSet.Remove (nd1)
While nd2 > 0
feNode.Get(nd2)
nd2loc(0) = feNode.x
nd2loc(1) = feNode.y
nd2loc(2) = feNode.z
App.feMeasureDistance (nd1loc, nd2loc, dist)
If DistCurrent > dist Then
DistCurrent = dist
nd2Keep = nd2
End If
nd2 = IndNdSet.Next
Wend
IndNdSet.Remove (nd2keep)
IndNdSet.Reset
BeamElID = El.NextEmptyID
If Proptype = 5 Then
El.type = FET_L_BEAM
Else
El.type = FET_L_SPRING
End If
El.Node (0) = nd1
El.Node (1) = nd2Keep
rc = feNode.Get (nd1)
X = feNode.x
Y = feNode.y
Z = feNode.z
rc = feNode.Get (nd2Keep)
X1 = feNode.x
Y1 = feNode.y
Z1 = feNode.z
Vec(0) = X - X1
Vec(1) = Y - Y1
Vec(2) = Z - Z1
rc = App.feVectorPerpendicular (Vec, VecP)
El.orient(0) = VecP(0)
El.orient(1) = VecP(1)
El.orient(2) = VecP(2)
El.propID = PropID
El.Put (BeamElID)
If proptype = 6 Then
newx = (X + X1) / 2
newy = (Y + Y1) / 2
newz = (Z + Z1) / 2
feNode.x = newx
feNode.y = newy
feNode.z = newz
rc = feNode.Put(nd1)
rc = feNode.Put(nd2Keep)
End If
If IndNdSet.Count = 1 Then
Nd1 = IndNdSet.First
DeleteSet.AddRule (nd1, FGD_ELEM_BYNODE)
feElem.Delete (DeleteSet.First)
feNode.Delete (Nd1)
GoTo Jumping_Out
End If
nd1 = IndNdSet.First
Wend
Jumping_Out:
Call App.feViewRegenerate(0)
Done:
End Sub
RE: Hole to hole fastener mesh
Best regards
RE: Hole to hole fastener mesh
RE: Hole to hole fastener mesh
A star for you!!. Very good API, after testing a few suggestions:
• After creation of the spider + bolt to continue asking for curves for bolt creation, now the API ends after the bolt creation, and again is required to answer if select existing beam properties or create a new one. Only ask for it the first time, if required a new property then the user will stop simply hitting ESC command.
• CBeam Stress recovery points are missing in the beam properties definition for bolt elements.
Best regards,
Blas.
~~~~~~~~~~~~~~~~~~~~~~
Blas Molero Hidalgo
Ingeniero Industrial
Director
IBERISA
48011 BILBAO (SPAIN)
WEB: http://www.iberisa.com
Blog de FEMAP & NX Nastran: http://iberisa.wordpress.com/