How to generate a line along a triangular solid using vertex points and neighbors? I have a solid composed of triangles, each defined by a triangle ID, three vertices (vertex1, vertex2, vertex3), and three neighboring triangles (n1, n2, n3). The data is structured as a list: [Tid, v1, v2, v3, n1, n2, n3]. n1, n2, n3 - it is neighboring points number. Below are examples of this data. Additionally, I have the coordinates of the points in the form (x, y, z). The numbers (Id number - Tid) of the triangles may not match the direction of the solid. This data is also provided below. How to do it correctly? How to generate a line along a triangular solid? The shape of the solid can be different. See the picture. Examples of the triangle and neighbor data (Tid, v1, v2, v3, n1, n2, n3): 1, 1, 78, 79, 151, 152, 2, 2, 1, 79, 80, 1, 153, 3, 3, 1, 80, 2, 2, 4, 226, 4, 2, 80, 81, 3, 157, 5, 5, 2, 81, 3, 4, 6, 230, 6, 3, 81, 82, 5, 158, 7, Examples of the point coordinates (point number, x, y, z): 1, 21686.416, 11496.370, 1081.922, 2, 21687.582, 11498.463, 1067.326, 3, 21687.582, 11498.463, 1082.489, 4, 21684.070, 11500.333, 1078.825, 5, 21681.135, 11499.179, 1076.579, 6, 21674.309, 11505.523, 1066.694, Examples picture 1. In the picture you can see that the solid consists of the triangles Examples picture 2. Inthe picture you can see that the solid consists of the triangles def compute_centroid(v1, v2, v3): return [(v1 + v2 + v3) / 3.0 for i in range(3)] # 2. Build a graph of triangle neighbors # Treat each triangle as a node, and connect it to its neighbors. from collections import defaultdict import numpy as np def read_vertices(file_path): """Parse point data into a dictionary with incremental numbering""" points = {} count = 0 # This will be our incremental counter with open(file_path, 'r') as point_lines: for line in point_lines: if not line.strip(): continue parts = [p.strip() for p in line.strip().split(',') if p.strip()] first_index = parts[0] # Skip lines that don't have at least 4 values (x, y, z needed) if len(parts) < 4: continue try: if first_index.lstrip('-').isdigit() and int(first_index) != 0: # Ignore the original point ID (parts[0]) and use our counter instead # coords = [float(x) for x in parts[1:4]] # Only get x,y,z coordinates count += 1 # Increment our counter # points[count] = np.array(coords) # Use count as the key x = float(parts[1].strip()) y = float(parts[2].strip()) z = float(parts[3].strip()) points[count] = (x, y, z) except (ValueError, IndexError): continue # Skip lines with invalid format return points def read_triangles(file_path): triangle_data = [] with open(file_path, 'r') as file: for line in file: # line = line[0] parts = line.strip().split(',') # print(len(parts), "===",parts) # print(parts) if len(parts) >= 7: first_index = parts[0].strip() if first_index.lstrip('-').isdigit() and int(first_index) != 0: Tid = int(parts[0].strip()) v1 = int(parts[1].strip()) v2 = int(parts[2].strip()) v3 = int(parts[3].strip()) n1 = int(parts[4].strip()) n2 = int(parts[5].strip()) n3 = int(parts[6].strip()) triangle_data.append([Tid, v1, v2, v3, n1, n2, n3]) return triangle_data def create_strfile(file_path, dataxyz): with open(file_path, "w") as fstr: fstr.write(",,,\n") fstr.write("0,0.000,0.000,0.000,0.000,0.000,0.000\n") for linexyz in dataxyz: x, y, z = linexyz fstr.write(f"5, {x:10.3f}, {y:10.3f}, {z:5.3f}, \n") fstr.write("0,0.000,0.000,0.000,\n") fstr.write("0,0.000,0.000,0.000,END\n") dtm_file_path = f'E:\\{filname}.dtm' str_file_path = f'E:\\{filname}.str' str_center_line = f'E:\\{filname}_center.str' point_data = read_vertices(str_file_path) triangle_data = read_triangles(dtm_file_path) print("Point Data Example:", len(point_data),"==",list(point_data.items())[:3]) print("Triangle Data Example:", triangle_data[:3]) class Triangle: def __init__(self, tid, v1, v2, v3, n1, n2, n3): self.id = tid self.vertices = [v1, v2, v3] self.neighbors = [n1, n2, n3] class Point: def __init__(self, pid, x, y, z): self.id = pid self.coords = (x, y, z) # triangle_list = triangle_data # point_list = point_data # triangle_list = [Triangle(t[0], t[1], t[2], t[3], t[4], t[5], t[6]) for t in triangle_data] triangle_list = [Triangle(t[0], t[1], t[2], t[3], t[4], t[5], t[6]) for t in triangle_data if all(v in point_data for v in [t[1], t[2], t[3]])] point_list = [Point(pid, *coords) for pid, coords in point_data.items()] triangles = {t.id: t for t in triangle_list} points = {p.id: p for p in point_list} print("points==",len(points), "point_list=",len(point_list) ) # # Build maps # triangles = {t.id: t for t in triangle_list} # points = {p.id: p for p in point_list} # Build edge map from collections import defaultdict edges = defaultdict(list) for t in triangles.values(): verts = t.vertices for i in range(3): edge = tuple(sorted((verts, verts[(i+1)%3]))) edges[edge].append(t.id) # Walk along mesh visited = set() path = [] def walk(tid=1, last_edge=None): if tid in visited: return visited.add(tid) t = triangles[tid] for i in range(3): n_tid = t.neighbors if n_tid and n_tid not in visited: edge = tuple(sorted((t.vertices, t.vertices[(i+1)%3]))) path.append(edge) walk(n_tid, edge) walk(1) # print(path) lines = [] for v1, v2 in path: print(v1, v2) p1 = points[v1].coords p2 = points[v2].coords lines.append((p1, p2)) # print(lines) # Convert line segments into ordered list of unique points path_points = [] seen = set() for p1, p2 in lines: if p1 not in seen: path_points.append(p1) seen.add(p1) if p2 not in seen: path_points.append(p2) seen.add(p2) # Now write to .str file create_strfile(str_center_line, path_points) I tried different ways but not successful. Continue reading...