PDA

View Full Version : creating a custom mesh object without triangulation?


Ojah
04-04-2008, 10:05 PM
While creating a custom mesh object in maxscript (following the excellent how-to in the reference) i found out that the created mesh has all of its edges shown. I was wondering if its possible to create a mesh without the triangulation.

ps, here is my code for a circular plane primitive.

plugin simpleObject circlePlane
name:"Circular Plane"
category:"Scripted Primitives"
classID:#(0xe293461c, 0xdf583489)

(
parameters main rollout:params
(
num_faces type:#integer ui:num_faces default:10
radius type:#float ui:radius default:10
)

rollout params "Circular Plane"
(
spinner num_faces "# Faces" range:[3,200,10] type:#integer
spinner radius "Radius" range:[0,10000,0]

)

on buildMesh do
(
vert_array = #()
face_array = #()

vert_count = 0
for a = 0 to 360 by 360/num_faces do
(
v = [radius*cos(a), radius*sin(a),0]
append vert_array v
vert_count +=1
if vert_count > 2 then
(
append face_array [1,vert_count-1,vert_count]
)
)
setMesh mesh verts:vert_array faces:face_array
)
tool create
(
on mousePoint click do
(
case click of
(
1: coordsys grid (nodeTM.translation = gridPoint)
)
)
on mouseMove click do
(
case click of
(
2: (radius = abs(gridDist.y))
3: (#stop)
)
)
)
)

Bobo
04-04-2008, 10:36 PM
Yep, you would have to set the edge visibility for each face yourself.
It is a bit of a work, but if you want it to look clean, you will have to.

In some cases (like my DIMaster script), I skipped this because it is a pain to implement and it would affect speed.

Bobo
04-04-2008, 10:51 PM
Yep, you would have to set the edge visibility for each face yourself.

Here is the relevant code:

on buildMesh do
(
vert_array = #()
face_array = #()
edge_vis = #() --new array to store edge visibility
vert_count = 0
for a = 0 to 360 by 360/num_faces do
(
v = [radius*cos(a), radius*sin(a),0]
append vert_array v
vert_count +=1
if vert_count > 2 then
(
append face_array [1,vert_count-1,vert_count]
append edge_vis #(false,true,false)
)
)
deleteItem face_array face_array.count --last face is redundant and causes shading problems - remove!
if face_array.count == 1 then
edge_vis[1] = #(true,true,true) --only one face always has three visible edges
else --otherwise first and last faces are different
(
edge_vis[1] = #(true,true,false) --first face always has two visible edges
edge_vis[face_array.count] = #(false,true,true) --last face always has two visible edges
)

setMesh mesh verts:vert_array faces:face_array

--loop through all faces and set each face to the values from the edge_vis array:
for f = 1 to face_array.count do
(
setEdgeVis mesh f 1 edge_vis[f][1]
setEdgeVis mesh f 2 edge_vis[f][2]
setEdgeVis mesh f 3 edge_vis[f][3]
)
)

Note that # Faces is actually # Vertices, as it defines the number of points around the circle, where 3 equals one face. Also, because the loop was going from 0 to 360, the last vertex doubled the first vertex and caused an additional face to be created that caused bad shading. See notes above.

Each face has 3 "edges" - these do not exist really as geometry elements like in EPoly, but they are defined as the connections from vertex 1 to vertex 2, vertex 2 to vertex 3 and vertex 3 to vertex 1 in the face definition. Thus, you need three boolean values defining the visibility of each side of the face. Except for the first and last one, all faces in your case will have first and third edge invisible and the second (on the perimeter) visible.

Bobo
04-04-2008, 10:57 PM
Btw, having the code always create faces connected to the center would simplify things as you would have ALL faces using the same edge visibility (false, true, false) and the faces would be less skinny and always the same shape. See the top of a Cylinder.

Bobo
04-04-2008, 11:11 PM
Btw, having the code always create faces connected to the center would simplify things as you would have ALL faces using the same edge visibility (false, true, false) and the faces would be less skinny and always the same shape. See the top of a Cylinder.

Here is a possible implementation of the centered mesh:

on buildMesh do
(
vert_array = #([0,0,0])
face_array = #()
vert_count = 1

--the step has to be float to end up as float after division:
for a = 0.0 to 360.0 by 360.0/num_faces do
(
v = [radius*cos(a), radius*sin(a),0]
append vert_array v
vert_count +=1
if vert_count > 2 do
append face_array [1,vert_count-1,vert_count]
)
--if the last vertex did not end up at the same position as the second vertex, close the gap.
if distance vert_array[vert_array.count] vert_array[2] > 0.0001 do
append face_array [1,vert_array.count,2]

setMesh mesh verts:vert_array faces:face_array

--loop through all faces and set each face to the same edge vis values:
for f = 1 to face_array.count do
(
setEdgeVis mesh f 1 false
setEdgeVis mesh f 2 true
setEdgeVis mesh f 3 false
)
)

As you can see, it is shorter and uses one array less than my previsous example, so it should be a bit faster and less memory intensive.

Ojah
04-04-2008, 11:12 PM
Awesome!

Very fast reply, and it works like a charm. Time to play a lot with this.
btw, i didn't want to create the vertices from the center because it seemed too easy and i wanted an optimized mesh (i wanted to create a saw-tooth patern first, but stopped when i couldnt remove the visible edges, will do that now(hmm, tempting to try creating it from squares with tri's on the edges, should provide some interesting challenge for me)).

anyway, im very grateful, thanks!

Ojah
04-04-2008, 11:19 PM
btw, i got to say you provided me with an excellent explanation (both forum and comments in the code).

Bobo
04-04-2008, 11:59 PM
btw, i got to say you provided me with an excellent explanation (both forum and comments in the code).

Thanks! It felt natural - guess who wrote the How To... code you started from ;)

CGTalk Moderation
04-04-2008, 11:59 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.