Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.

Best way of subdividing cylinder based on dummy points

petecmartin
Advocate

Best way of subdividing cylinder based on dummy points

petecmartin
Advocate
Advocate

Hi, 
Say i've created a cylinder between two end points points and I have two middle points where I want to subdivide the cylinder.  What is the best way of going about this?
I would also like to do this regardless of how the cylinder is orientated (vertical, diagonal or horizontal)  Cheers.

So far I have this to create the cylinder:

point01 = getnodebyname "point001"
point02 = getnodebyname "point002"

fn drawCylinderBetweenTwoPoints pt1 pt2=
	cylinder radius:2 pos:pt1 dir:(pt2-pt1) height:(distance pt1 pt2)

drawCylinderBetweenTwoPoints point01.pos point02.pos




0 Likes
Reply
Accepted solutions (1)
861 Views
10 Replies
Replies (10)

denisT.MaxDoctor
Advisor
Advisor

 

fn makeTwoPointCylinder p0 p1 radius:10 sides:8 cuts:#() = 
(
	dir = normalize (p1 - p0)
	height = distance p0 p1
	
	c = cylinder radius:radius pos:p0 dir:dir height:height sides:sides heightsegs:(cuts.count+1)
	m = converttomesh c 
	
	sort cuts
	num = cuts.count
	local vv
	
	for k=1.0 to num do
	(
		v = (sides+1) + (k-1)*sides + 1	
		vv = #{v..(v + sides - 1)}
		meshop.movevert m.mesh vv (height * (cuts[k] - k/(num+1)) * z_axis)  
	)
	m
)

delete objects 
gc()

p0 = point pos:(random -[100,100,100] [100,100,100]) wirecolor:green
p1 = point pos:(random -[100,100,100] [100,100,100]) wirecolor:orange

m0 = makeTwoPointCylinder p0.pos p1.pos radius:10 cuts:#(0.5)
m1 = makeTwoPointCylinder p0.pos p1.pos radius:15 cuts:#(0.25, 0.66)
m3 = makeTwoPointCylinder p0.pos p1.pos radius:20 cuts:#(0.15, 0.33, 0.75)

 

 

where cuts are values from 0 to 1 

 

since you want to move the vertices of the height segments, it can no longer be a cylinder, and we have to convert it to something editable (an editable mesh in my example).

 

 

0 Likes

petecmartin
Advocate
Advocate

Many thanks @denisT.MaxDoctor,

Just another question.  How could I get the cuts to be in the same places as a series of dummies (imagine between the two start and end points there's 2 other dummies - not necessarily evenly spaced)

 

Many thanks 🙂

0 Likes

petecmartin
Advocate
Advocate

I cracked the splitting at dummy locations part.

The only thing that's bugging me is that when the cylinder gets converted to an editable mesh, a single vert gets put in the centre of the end caps!  How does one avoid this? 

0 Likes

denisT.MaxDoctor
Advisor
Advisor
Accepted solution

The cylinder creates two additional vertices in the center of the top and bottom caps. This is how the geometry of the cylinder works. A possible solution is to delete cap's center vertices and use the Cap modifier to close the cylinder with a new one:

fn makeTwoPointCylinder p0 p1 radius:10 sides:8 cuts:#() = 
(
	dir = normalize (p1 - p0)
	height = distance p0 p1
	
	c = cylinder radius:radius pos:p0 dir:dir height:height sides:sides heightsegs:(cuts.count+1)
	m = converttomesh c 
	
	sort cuts
	num = cuts.count
	local vv
	
	for k=1.0 to num do
	(
		v = (sides+1) + (k-1)*sides + 1	
		vv = #{v..(v + sides - 1)}
		meshop.movevert m.mesh vv (height * (cuts[k] - k/(num+1)) * z_axis)  
	)
	meshop.deleteverts m #{1, m.numverts} -- delete caps
	addmodifier m (Cap_Holes())
	converttomesh m
)

delete objects 
gc()

p0 = point pos:(random -[100,100,100] [100,100,100]) wirecolor:green
p1 = point pos:(random -[100,100,100] [100,100,100]) wirecolor:orange

m0 = makeTwoPointCylinder p0.pos p1.pos radius:10 cuts:#(0.5)
m1 = makeTwoPointCylinder p0.pos p1.pos radius:15 cuts:#(0.25, 0.66)
m3 = makeTwoPointCylinder p0.pos p1.pos radius:20 cuts:#(0.15, 0.33, 0.75)
0 Likes

petecmartin
Advocate
Advocate

Thank you denisT.MaxDoctor, much appreciated. 

This has really helped me out 😊

0 Likes

denisT.MaxDoctor
Advisor
Advisor

don't forget to mark the issue as resolved if so.

0 Likes

petecmartin
Advocate
Advocate

Will do, once I'm back on my PC 😊

0 Likes

denisT.MaxDoctor
Advisor
Advisor

this is another way to do it:

 fn makeTwoPointLine p0 p1 radius:10 sides:24 cuts:#() = 
(
	dir = normalize (p1 - p0)
	height = distance p0 p1 
	
	sp = line pos:p0 dir:dir render_displayRenderMesh:on \
		render_thickness:(radius*2) render_sides:sides render_viewport_rectangular:off  
	tm = sp.transform
	addnewspline sp 
	in coordsys sp
	(
		addknot sp 1 #corner #line [0,0,0]
		for k=1 to cuts.count do
		(
			addknot sp 1 #corner #line [0,0,cuts[k]*height]
		)
		addknot sp 1 #corner #line [0,0,height]
	)
	--meshop.deleteverts m #{1, m.numverts}
	addmodifier sp (Cap_Holes())
	converttomesh sp
)

delete objects 
gc()

p0 = point pos:(random -[100,100,100] [100,100,100]) wirecolor:green
p1 = point pos:(random -[100,100,100] [100,100,100]) wirecolor:orange

m0 = makeTwoPointLine p0.pos p1.pos radius:10 cuts:#(0.5)
m1 = makeTwoPointLine p0.pos p1.pos radius:15 cuts:#(0.25, 0.66)
m3 = makeTwoPointLine p0.pos p1.pos radius:20 cuts:#(0.15, 0.33, 0.75)

 

what I like more...

 

 

 

0 Likes

petecmartin
Advocate
Advocate

Thank you for that too 😊

I tried a spline solution but got stuck on the knot part. I realised that the order in which you added the knots was crucial and abandonned it!

I guess once the initial spline vert  is defined, its a matter of creating the knots in increasing numerical order and then adding the final vert. 

0 Likes

denisT.MaxDoctor
Advisor
Advisor

@petecmartin wrote:

I tried a spline solution but got stuck on the knot part. I realised that the order in which you added the knots was crucial and abandonned it!

I guess once the initial spline vert  is defined, its a matter of creating the knots in increasing numerical order and then adding the final vert. 


here it is:

fn makeTwoPointLine p0 p1 radius:10 sides:24 cuts:#() = 
(
	dir = normalize (p1 - p0)
	height = distance p0 p1 
	
	sp = line pos:p0 dir:dir render_displayRenderMesh:on \
		render_thickness:(radius*2) render_sides:sides render_viewport_rectangular:off  
	tm = sp.transform
	addnewspline sp 
	in coordsys sp
	(
		addknot sp 1 #corner #line [0,0,0]
		addknot sp 1 #corner #line [0,0,height]

		p = 0.0
		h = 1.0
		for k=1 to cuts.count do
		(
			seg = numsegments sp 1 
			
			t = (cuts[k] - p)/h
			refinesegment sp 1 seg t
			h *= (1 - t)
			p = cuts[k]
		)
	)
)

delete objects 
gc()

p0 = point pos:(random -[100,0,100] [100,0,100]) wirecolor:green
p1 = point pos:(random -[100,0,100] [100,0,100]) wirecolor:orange

m0 = makeTwoPointLine p0.pos p1.pos radius:10 cuts:#(0.5)
m1 = makeTwoPointLine p0.pos p1.pos radius:15 cuts:#(0.25, 0.65)
m3 = makeTwoPointLine p0.pos p1.pos radius:20 cuts:#(0.15, 0.33, 0.75)
0 Likes