Community
3ds Max Programming
Welcome to Autodesk’s 3ds Max Forums. Share your knowledge, ask questions, and explore popular 3ds Max SDK, Maxscript and Python topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Best way of subdividing cylinder based on dummy points

10 REPLIES 10
SOLVED
Reply
Message 1 of 11
petecmartin
742 Views, 10 Replies

Best way of subdividing cylinder based on dummy points

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




10 REPLIES 10
Message 2 of 11

 

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).

 

 

Message 3 of 11

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 🙂

Message 4 of 11
petecmartin
in reply to: petecmartin

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? 

Message 5 of 11

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)
Message 6 of 11

Thank you denisT.MaxDoctor, much appreciated. 

This has really helped me out 😊

Message 7 of 11

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

Message 8 of 11

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

Message 9 of 11

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...

 

 

 

Message 10 of 11

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. 

Message 11 of 11


@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)

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report