Projected Points On Surface (Normal From Surface)

This script takes as input a .csv file (separated with ‘;’) of the format x,y,z,f. The path to the .csv file is specified by the variable inputFile. Then, graphically select the surface to project the points on and run the script!

The length unit in Mechanical graphics is typically ‘m’. Based on the units from the .csv (unknown in the code), specify the variable coversionFactor if necessary.

Transparent

Transparent

plot_graphics = True
side = 1 # 0  = front (this is the side of a surface that gets highlighted in green when selected, 1 = back
model_type = 'shell' # 'shell' or 'solid'

## USER INPUT! ## 
inputFile = r'C:\temp\powerLoad3D.csv'

# Select a surface to project the points on 
surfaces = ExtAPI.SelectionManager.CurrentSelection

def plot_lines(node_pairs):
    with Graphics.Suspend():
        for index, entity in enumerate(node_pairs.keys()):
            #if index % 5 != 0: continue
            p_S = ExtAPI.Graphics.CreateWorldPoint(node_pairs[index][0][0],node_pairs[index][0][1],node_pairs[index][0][2])
            p_L = ExtAPI.Graphics.CreateWorldPoint(node_pairs[index][1].X,node_pairs[index][1].Y,node_pairs[index][1].Z)
            line = Graphics.Scene.Factory2D.CreatePolyline([p_S,p_L])
Graphics.Scene.Clear()

surfaces = surfaces.Entities
surface_L = surfaces[0]
meshData        = Model.Analyses[0].MeshData
surface_L_mesh = meshData.MeshRegionById(surface_L.Id)
surface_L_nodes = surface_L_mesh.Nodes

x = list()
y = list()
z = list()
p = list()

f = open(inputFile,'r') # user input path to csv file
conversionFactor = 1
for ind_, line in enumerate(f):
    if ind_ == 0: continue
    x.append(float(line.Split(';')[0])*conversionFactor)
    y.append(float(line.Split(';')[1])*conversionFactor)
    z.append(float(line.Split(';')[2])*conversionFactor)
    p.append(float(line.Split(';')[3])*conversionFactor)
f.close()
node_pairs = {}
for index, node_S in enumerate(x):
    currentDist_ = 1e99
    x_s = x[index]
    y_s = y[index]
    z_s = z[index]
    for node_L in surface_L_nodes:
        x_L = node_L.X
        y_L = node_L.Y
        z_L = node_L.Z
        dist_ = ((x_s-x_L)**2 + (y_s-y_L)**2 + (z_s-z_L)**2)**0.5
        if dist_ < currentDist_: 
            currentDist_ = dist_
            if index not in node_pairs.keys(): node_pairs.Add(index,None)
            node_pairs[index] = [[x_s,y_s,z_s],node_L]
projected_nodes_L = list()
for index, key in enumerate(node_pairs.keys()):
    projected_nodes_L.append(node_pairs[index][1].Id)
projected_L = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.MeshNodes)
projected_L.Ids = projected_nodes_L
ns_ = Model.AddNamedSelection()
ns_.Location = projected_L
ns_.Name = 'Init_NS'

namedSelStart_ = Model.AddNamedSelection()
namedSelStart_.ScopingMethod = GeometryDefineByType.Worksheet
namedSelStart_.GenerationCriteria.Add(None)
namedSelStart_.GenerationCriteria[0].EntityType = SelectionType.MeshNode
namedSelStart_.GenerationCriteria[0].Criterion = SelectionCriterionType.NamedSelection
namedSelStart_.GenerationCriteria[0].Operator = SelectionOperatorType.Equal
namedSelStart_.GenerationCriteria[0].Value = ns_
namedSelStart_.GenerationCriteria.Add(None)
namedSelStart_.GenerationCriteria[1].Action = SelectionActionType.Convert
namedSelStart_.GenerationCriteria[1].EntityType = SelectionType.MeshElementFace
namedSelStart_.GenerationCriteria[1].Criterion = SelectionCriterionType.AnyNode
namedSelStart_.Generate()
if str(namedSelStart_.ObjectState) == 'Suppressed':
    namedSelStart_.GenerationCriteria[1].EntityType = SelectionType.MeshElement
    namedSelStart_.Generate()
if model_type == 'shell':
    elemfaces = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.MeshElementFaces)
    elemfaces.Ids = namedSelStart_.Location.Ids
    elemfaces.ElementFaceIndices = [side for i in range(namedSelStart_.Ids.Count)]
    elemFaces_ns = Model.AddNamedSelection()
    elemFaces_ns.Location = elemfaces
    elemFaces_ns.Name = str(elemFaces_ns.Location.Ids.Count) +  ' Element Faces'
    namedSelStart_.Delete()
    ns_.Delete()
############## ------PLOT------ ############ 
if plot_graphics:
    with Graphics.Suspend():
        for index, key in enumerate(x):
            #if index % 5 != 0: continue
            point=ExtAPI.Graphics.CreateWorldPoint(x[index],y[index],z[index])
            sphere = ExtAPI.Graphics.Scene.Factory3D.CreateSphere(.05)
            sphere.Transformation3D.Set(point)
            sphere.Color = 0x0000ff
            sphere.Translucency = 0.75
    plot_lines(node_pairs)