Custom Procedural Primitives (with example)


#1

I’ve been really inspired by this fence primitive, and I would really like to create some procedural primitives of my own. I’m pretty sure this isn’t purely done by scripting, but that are there are some methods to make it a bit easier to work with.

I am pretty capable at maxscript, I do a lot of it, but these scripted plugins usually have a lot of references to numbers which isn’t really intuitive to work with. Looking at these plugins it doesn’t look like they were written manually (at least not entirely). And to honest, looking at other peoples scripted plugins doesn’t bring me many aha-moments.

I’ve seen that Max Creation Craph (MCG) recently has been used to this kind of stuff, but in my case I would rather to use the “old” way (because of the 3ds max version at mye office).

So I was hoping someone would give me a rough step by step in creating “primitive” that lets you customize them, or direct me to some good tutorials (which I haven’t been able to find).


#2

I wonder what you mean by that :slight_smile: Anyway, looking at samples and trying to deconstruct them should eventually get you there, if you look under the heading MAXScript Primitives here, you will find a variety of them. Not included but one I recommend looking a first is Star, it’s the simplest one and should be easy to comprehend.


#3

learn how create objects procedurally out of tri meshes. Laying the vertices down is the easy bit connecting them together into sensible faces in the right order and orientation is the knack (pretty disappointed that the fence script linked to doesn’t handle the mapping as it’s easier to do in script than it is for the artist/user to do after :wink: )


#4

Swordslayer: Wow, in that case I’m extremely inpressed by all of the writers of these scripts. Even though I’ve written a lot of maxscripts, I really struggle to find structure in these scripted plugins. I’ve mainly looked through the different scripts of Vojtěch Čada, and I just realized that he has the same avatar as you, is that you? In that case, I’d love to know your workflow when creating these scripts (which are aresome).

Edit: Just realized you linked to your own page, you do awesome work mister! :slight_smile:

Klnk: Thank you, do you think you could point me in the right direction for learning this stuff?


#5

I’ve created a commented version of the meshStar-plugin, and prefixed those things I don’t understand with “NOT SURE”. Here’s the link to the pastebin https://pastebin.com/KsLwv4aP. There wasn’t a maxscript highlighter there, so you should probably copy it over to your maxscript editor for easier reading.

Anyway, I’d greatly appreciate comments on my own comments on the file, especially on the NOT SURE portions. It would also be great to know if something of what I’ve written is wrong :slight_smile:

In general I feel like you’re totally working in the blind when generating the mesh data in scripted plugins.


#6

Yup, that’s me, glad that you like it :slight_smile: And well done on the star breakdown! Here are the missing pieces:

setMesh mesh vertices:vertList faces:faceList

The first argument, mesh, is a variable supplied by the simpleObject and modifying it modifies the object mesh. This makes it use the supplied vertex positions and faces defined by indices that point to the vertices in the vertList.

local vertList = #([0, 0, height / 2], [0, 0, -height / 2])

These are the first two verts,the center points. Zero x coord, zero y coord, height halved once as negative z coord, once as a positive one.

for angle = 0 to 360 by 2 * angleStep do
(
	append vertList [radius1 * sin angle, radius1 * cos angle, 0]
	append vertList [radius2 * sin (angle + angleStep), radius2 * cos (angle + angleStep), 0]
)

You might have noticed that the angleStep was calculated as 360 divided by twice the number of points. That’s because there are outer points and inner points. Here the stepping is angleStep doubled and in each step, a circle point is created with radius1 at the current angle, and another is created at circle of the radius2 at current angle plus the angleStep. A formula used here for point at circle is x = sin angle, y = cos angle. The calculated positions are added to the vertList.

for i = 1 to maxPoints do
(
	append faceList [1, 3 + mod i maxPoints, i + 2]
	append faceList [2, i + 2, 3 + mod i maxPoints]
)

Now it’s time to collect the faces. A mesh face is defined by three vert indices. Since this is a very simple star, all the top faces will share the top center vertex and all the bottom faces will share the bottom center vert - that’s why for each segment, there’s one face that starts with vertex index one, and one face that starts with vertex index 2. The other two points are the inner radius vertex and the outer radius vertex, alternating with each iteration, in the order they were created (it helps if you make a three-point star and go through the indices, maybe insert some print statements too). In the last iteration, the desired behavior is to use the starting radius vert, that’s why there’s the modulo to cut off the extreme value.


#7

That er ekstremely helpful, thank you! :slight_smile: I really gotta say, kudos to the people that makes these, it involves a lot more thinking than I figured when starting out on this.

Just setting up rules (typically with math) for the vertex positions could be challenging in itself, it’s basicly algorithms, but the way I se it it’s even harder to figure out how to define the rules for generating the face array wind correct indexes (might just be me being stupid).

Are there some “unwritten” rules, or common ways of doing this? Say you have an array of vertex positions, is it possible to generate an array of faceindexes always working with the set of vert positions you have?

I guess when prototyping plugins you would do something like this: https://pastebin.com/VS3AjQjt?


#8

There’s no universal approach but for quad based meshes, it’s handy to have a few functions to abstract the most frequent tasks, functions like addQuad, addRow etc (see the quad Cylinder primitive for a good example). It all depends on how you organize the data.

For me, writing the scripted plugin is prototyping itself, it’s just that I start with a minimum viable feature set and expand upon that (the gear for example started pretty limited and with fixed tooth profile). I’m also too lazy to add the uv coords and often even smoothing groups so there’s that :slight_smile:


#9

Awesome, appreciate it! I’ll definitely snoop around you other scripts and see if I can make some sense of them, thanks again man :slight_smile: Oh well, you can’t have it all, the stuff you’ve made has definitely already helped a lot of people!


#10

well if you think MCG is Maya Creation Graph then you’re looking in the wrong place.


#11

theres an example of one of mine on this thread called picframe


#12

vusta: Considering I’ve already have gotten helpful answers I think most people got that I meant Max Creation Graph (MCG). And as you can see, MCG doesn’t stand for one thing :wink:

Klvnk: Thank you, I’ll check that out :slight_smile:


#13

I’m starting to understand that there’s different ways of creating a scripted geometry plugin. One way is to specify every vertex positions, and then create faces matching the vertex positions you have. This is the way I’m currently trying to figure out.

The other method seems to be that you actually create max objects (like a box), and then position them in relation to each other. They should still behave in a way that lets you parametrize them (as these elements are within the plugin).
But, as Klvnk said, it can some times be easier creating the mesh from scratch than trying to edit existing meshes because you risk loosing control trying to keep track of everything.

I really appreciate your help, and I’m sorry for not just getting it, I’m obviously a slow one. So I’ve basicly ripped Vojtěch’s star-plugin into pieces (really hope you don’t mind), and restructured everything to make it easier for me to understand.
I’ve realised that the thing I really don’t understand is how you know how to create the faceList, I seriously don’t get it! So Vojtěch, could you be bothered to have a look at a new pastebin? I’ve tried to comment in my questions as detailed as I could: https://pastebin.com/hhXnbtJx

I promise I’ll stop bothering you if you answer, and I’m still lost :wink:


#14

Sure, that’s the intent. As I said before, best would be if you added edit mesh modifier on top and went through selecting vertices one by one and see how they create faces. The three corners of the face are the indices of the verts (pretty much indices to the array of the positions at this point). The indexing depends entirely on how you create those and in which order. I go two center points first, radius points two at a time. Connecting those to faces is then simple since all the top faces connect to top vert, all the bottom ones to bottom vert - that’s the 1 and 2. You only have to figure the other two indices now - best when you draw it (for a 3-point star, it’s just a few points and lines). Another thing to keep in mind is the order of the face verts. CCW will be facig you, CW will be facing away. You can see that one sequence goes 3,4 4,5 5,6 6,7 and the other 4,3 5,4 6,4 7,6 because of that:

#([1,4,3], [1,5,4], [1,6,5], [1,7,6], [1,8,7], [1,9,8], [1,10,9], [1,11,10], [1,12,11], [1,13,12], [1,14,13], [1,3,14])
#([2,3,4], [2,4,5], [2,5,6], [2,6,7], [2,7,8], [2,8,9], [2,9,10], [2,10,11], [2,11,12], [2,12,13], [2,13,14], [2,14,3])

#15

Aaaaah, I finally get it (I wouldn’t admit it if I didn’t, but I actually did get it now) ! Thank you sensei, really! :smiley:


#16

JimmyVera
11h
1

vusta: Considering I’ve already have gotten helpful answers I think most people got that I meant Max Creation Graph (MCG)2. And as you can see, MCG doesn’t stand for one thing :wink:

Yes MCG (in Autodesk app speak) does stand for one thing…Max Creation Graph not Maya as you incorrectly stated in your original post that you’ve edited after I pointed it out for you. Anyway, if you already knew that then, ok my bad…


#17

I’m not sure if you trolled me the first time, or if you’re just trolling me now? :face_with_raised_eyebrow:

I did initially write Maya Creation Graph in my first post, you then pointed it out to me that I had actually written Maya (instead of Max). I thought, this guy doesn’t miss a beat, so I’m sure he’s aware that this was posted in the 3dsMax section, and had actually read that all responses (including mine) was Max-related - so how could it be?

The irony, I got help understanding my original questions with this thread (from Vojtěch and Klvnk), but you are really confusing me mister. I almost wish it was intentional, but I doubt it :slightly_frowning_face:


#18

I never said MCS…I clearly said MCG

If there is such a thing as Maya Creation Graph…then definitely I’ve missed that boat…never seen one…

Good that you got help from others, I’m not a scripter so can’t help you there, if you think I’m a troll…doesn’t worry me one bit.