Hello, this issue is a bit related to the sweep geometry post, as it is my current workaround for this.
I have a table which defines a bunch of cylinders (or circular profiles depending on how you look at it):
As you can see, there are somehow three groups of cylinders which are rotated around their main axis relative to the other groups. I think this results in this undesirable behaviour when I loft the cross-sections with ThruSections:
Do you have an idea what causes this rotation of some of the cylinders or how it could be controlled? I generated hundreds of cylinder tables like this with their overall curve following different parabolas but could not find a relationship between how the cylinders are generated and where the twists occur, this seems random to me.
This is my code (files attached below):
from netgen.occ import *
from netgen.webgui import Draw as DrawGeo
import pandas as pd
def make_smooth_solid(segments):
radii = segments['raw_radius'].tolist()
# Create lists of points and normals for each circular profile
pnts = list()
normals = list()
for index, row in segments.iterrows():
if index == segments.index.min():
pnts.append(Pnt(row['start_x'], row['start_y'], row['start_z']))
normals.append(Vec(row['end_x'] - row['start_x'], row['end_y'] - row['start_y'], row['end_z'] - row['start_z']))
pnts.append(Pnt(row['end_x'], row['end_y'], row['end_z']))
normals.append(Vec(row['end_x'] - row['start_x'], row['end_y'] - row['start_y'], row['end_z'] - row['start_z']))
# Create list of profiles
profiles = list()
for pnt, normal, r in zip(pnts, normals, radii):
circle = Circle(pnt, normal, r)
profiles.append(Wire([circle]))
# Create lofted shape connecting the profiles
solid = ThruSections(profiles, solid=True)
return(solid)
def make_cylinders(segments):
# Initial Cylinder to add to
cylinders = Cylinder(Pnt(segments['start_x'].iloc[0], segments['start_y'].iloc[0], segments['start_z'].iloc[0]),
Vec(segments['end_x'].iloc[0] - segments['start_x'].iloc[0], segments['end_y'].iloc[0] - segments['start_y'].iloc[0], segments['end_z'].iloc[0] - segments['start_z'].iloc[0]),
segments['raw_radius'].iloc[0],
segments['length'].iloc[0])
# Add every cylinder one by one
for index, row in segments.iterrows():
if index > segments.index.min():
cylinder = Cylinder(Pnt(row['start_x'], row['start_y'], row['start_z']),
Vec(row['end_x'] - row['start_x'], row['end_y'] - row['start_y'], row['end_z'] - row['start_z']),
row['raw_radius'],
row['length'])
cylinders = cylinders + cylinder
return(cylinders)
cly_table = pd.read_csv('data/clys_example.csv')
DrawGeo(make_cylinders(cly_table))
DrawGeo(make_smooth_solid(cly_table))
cylinder_twisting_example.ipynb (4.5 KB)
clys_example.csv (10.6 KB)