PDA

View Full Version : material ID script. how to?


metamesh
03-02-2012, 05:31 PM
hey guys,
I have no idea whatsoever about maxscript, and I wanted to try something but I don't even know where to start:

The idea is to uv an object, and assign different material ID's to the faces of that object according to the position of the poligons in the UV space, just taking into account the V position, so if a poligon is within the 0-1 range in the V, assign the ID 1, if its in the 1-2 range, assign the 2, and so on...

any idea how to do that? is that even possible to do?

cheers!

3ak
03-02-2012, 05:42 PM
hey guys,
I have no idea whatsoever about maxscript, and I wanted to try something but I don't even know where to start:

The idea is to uv an object, and assign different material ID's to the faces of that object according to the position of the poligons in the UV space, just taking into account the V position, so if a poligon is within the 0-1 range in the V, assign the ID 1, if its in the 1-2 range, assign the 2, and so on...

any idea how to do that? is that even possible to do?

cheers!I think you could find corresponding tex face for every geo face. Check UVs in that tex face and according to UVs set mat ID of the geo face with setFaceMatID

PiniO
03-02-2012, 08:57 PM
You can try using my simple tool from this (http://forums.cgsociety.org/showpost.php?p=7202232&postcount=3) post. There you must select maually faces in UnwrapUVW window and assingn them proper material ID via tool. This way should by enough for couple ID.
Of course it not what you exactly need, but can by helpfull partially.

metamesh
03-03-2012, 12:38 AM
but I don't want to select manually all the uvs etc etc, I just want to select the object, run the script, done. I have a big ammount of objects that need to tweak in this way, with lots of uv's and I don't want to go 1 by 1 doing it by hand...

thanks for the suggestion tho!

any other ideas on how to script that ?

cheers!

3ak
03-03-2012, 12:49 AM
)
you don't need to do it manually. i mean find faces in a loop)
i'll give it a try.
But how compute UVs for the face? cause some of 3 certices of a face could be in differen coords (i mean one in 0-1 range, another in 1-2 for example)
maybe face center?

denisT
03-03-2012, 01:18 AM
hey guys,
I have no idea whatsoever about maxscript, and I wanted to try something but I don't even know where to start...
because you are not a tech guy there is the rule for you... before asking how to do anything please tell why you need it.
the answer to the main question might differ.

metamesh
03-03-2012, 01:25 AM
because you are not a tech guy there is the rule for you... before asking how to do anything please tell why you need it.
the answer to the main question might differ.

I just said it before, I have a lot of objects and each object has their uv's separated in the uv space so the region that goes from 0-1 in V needs to be material 1, the poligons within the region from 1-2 go need to be material 2, and so on... there's lots ob objects and lots of materials to be assigned to each object so i don't want to do it by hand

cheers!

Ruramuq
03-03-2012, 01:28 AM
I have another rule, that many times I've break:
First try, show your code, then ask for orientation.. not for answer..

But Anyway, next test averages the uvs of faceverts and calculates the matID 'V only'
change: gradients | chn
http://forums.cgsociety.org/attachment.php?attachmentid=166761&stc=1

(
o = selection[1]
chn = 1
gradients = 10

for f = 1 to polyop.getNumMapFaces o chn collect
(
sum = 0.0
face = polyop.getMapFace $ chn f
count = face.count
for v = 1 to count do sum += (polyop.getMapVert $ chn face[v]).y
sum /= count
sum = (sum*gradients+.5) as integer + 1
polyop.setFaceMatID o f sum
)
/* test */
mat = multiSubMaterial numsubs:0
col = red
for n = 1 to gradients do
(
mat.materialList[n] = standard diffuseColor:(col.hue = (255./gradients)*n;col)
mat.materialIDlist[n] = n
)
o.material = mat
)

3ak
03-03-2012, 01:40 AM
for g in selection do
(
numfaces = getnumfaces g.mesh
for i = 1 to numfaces do
(
vi = getTVface g.mesh i
v1 = getTvert g.mesh vi.x
v2 = getTvert g.mesh vi.y
v3 = getTvert g.mesh vi.z
averageUV = (v1+v2+v3)/3
matid = (floor (averageUV.y+1)) as integer
m1 = getfacematid g.mesh i
polyop.setfacematid g i matid
m2 = getfacematid g.mesh i
)
update g
)


..oops. i'm late. btw, does anybody know why SetFaceMatID doesn't work? only one of polyop struct really set ID.

denisT
03-03-2012, 02:10 AM
I just said it before, I have a lot of objects and each object has their uv's separated in the uv space so the region that goes from 0-1 in V needs to be material 1, the poligons within the region from 1-2 go need to be material 2, and so on... there's lots ob objects and lots of materials to be assigned to each object so i don't want to do it by hand

cheers!

your question is technically incorrect.
are you asking about the center of a polygon?
are we talking about the mesh or the poly?
do you have the world space mapping?

so... if you want to get an answer you have to clearly explain the problem...
the mxs solution might be (will be) only one line of code, but I (I'm sorry) don't see a clear picture.

denisT
03-03-2012, 02:19 AM
for g in selection do
(
numfaces = getnumfaces g.mesh
for i = 1 to numfaces do
(
vi = getTVface g.mesh i
v1 = getTvert g.mesh vi.x
v2 = getTvert g.mesh vi.y
v3 = getTvert g.mesh vi.z
averageUV = (v1+v2+v3)/3
matid = (floor (averageUV.y+1)) as integer
m1 = getfacematid g.mesh i
polyop.setfacematid g i matid
m2 = getfacematid g.mesh i
)
update g
)


..oops. i'm late. btw, does anybody know why SetFaceMatID doesn't work? only one of polyop struct really set ID.

stop... slow down. your idea is right, but the code solution is ... hmm...
every time when you call node's trimesh using <node>.mesh calling the mxs creates the instance of trimesh...
we discussed this issue on this forum.
so... make a copy of trimesh and use it for the getting uv data

3ak
03-03-2012, 02:22 AM
stop... slow down. your idea is right, but the code solution is ... hmm...
every time when you call node's trimesh using <node>.mesh calling the mxs creates the instance of trimesh...
we discussed this issue on this forum.
so... make a copy of trimesh and use it for the getting uv data

thanks) i'm not a programmer so my code needs your attention)

so i need snapshotasmesh and at the end just make obj.mesh = mySnapshotMesh?

Ruramuq
03-03-2012, 02:44 AM
let's understand that the OP is not a tech guy, he's an artist,
Explaining things in a technical way its not usual or easy for those who are starting to learn mxs.

there are 3 options:

1. ignore the thread (something I tend to do alot)
2. explain your point of view, and give an example somehow like in post #10
3. play for fun, with the most logical meaning:

he says polygons = must be the center
99% of modelers use editable_poly
it's rare to use world space

and indeed a good clear explanation is the ideal.
but forums like this tend to be very far from the 'ideal'

denisT
03-03-2012, 02:45 AM
thanks) i'm not a programmer so my code needs your attention)

so i need snapshotasmesh and at the end just make obj.mesh = mySnapshotMesh?
you are a mxs scripter. your code needs a little tweaking only.
i benchmarked copy mesh vs snapshotasmesh ... the snapshotasmesh wins.

denisT
03-03-2012, 02:52 AM
let's understand that the OP is not a tech guy, he's an artist,
Explaining things in a technical way its not usual or easy for those who are starting to learn mxs.

wait a sec. the guy is not learning the mxs. he is looking for solution. to get an answer you have to ask the proper question.

Ruramuq
03-03-2012, 03:12 AM
Not even with a proper question, people on this forum should get the answer.

The answer should always come from them.
Otherwise there are professionals waiting for paid work..

But as i said, I break that rule.. because I don't really take the answer seriously in the sense of what is best for the person who ask. So I can easily criticize myself and everybody who is giving direct solutions for others to copy/paste.

metamesh
03-03-2012, 03:17 AM
all right here is an screenshot,
there's a teapot and the uv's of the teapot, all the poligons within the range from 0 to 1 in V should get ID material 1, all the polygons within the range from 1 to 2 in V should get ID mat =2 and so on when running the script, does that make any sense now?
thanks for the help, appreciated!

3ak
03-03-2012, 03:36 AM
all right here is an screenshot,
there's a teapot and the uv's of the teapot, all the poligons within the range from 0 to 1 in V should get ID material 1, all the polygons within the range from 1 to 2 in V should get ID mat =2 and so on when running the script, does that make any sense now?
thanks for the help, appreciated!
one question is how sort faces - by their centers, by all their vertices?

my little script may be not very memory friendly as denisT said but it works (slightly updated). Just select your objects (they must be poly and have UVs). And assign multimat to see result. It sorts faces by their center. If center point has V in 1 to 2 then matID of the face will be 2:

see post #20.
Ruramuq has the same in post#8. even brighter)

denisT
03-03-2012, 03:57 AM
one question is how sort faces - by their centers, by all their vertices?

my little script may be not very memory friendly as denisT said but it works (slightly updated). Just select your objects (they must be poly and have UVs). And assign multimat to see result. It sorts faces by their center. If center point has V in 1 to 2 then matID of the face will be 1:

for obj in selection do
(
g = snapshotasmesh obj
numfaces = polyop.getnumfaces obj
for i = 1 to numfaces do
(
vi = getTVface g i
v1 = getTvert g vi.x
v2 = getTvert g vi.y
v3 = getTvert g vi.z
averageUV = (v1+v2+v3)/3
matid = (floor (averageUV.y+1)) as integer
polyop.setfacematid obj i matid

)
free g
update obj
)

i like how you do it. almost everything is right. but there are some details...
all your calcs made in mesh space, but the face ID your apply is in poly space. you have to understand that mesh face index and poly face index are different.
another thing...
floor ... blah ... to integer works, but there is the mod function to do the same.

3ak
03-03-2012, 04:03 AM
yes. updated ver)

for g in selection do
(
--g = snapshotasmesh obj
numfaces = polyop.getnummapfaces g 1
for i = 1 to numfaces do
(

vi = polyop.getmapface g 1 i
averageUV = 0.0
for j = 1 to vi.count do averageUV +=(polyop.getmapvert g 1 vi[j]).y
averageUV/=vi.count
matid = (floor (averageUV+1)) as integer
format "face: % id: % center: % \n" i matid averageuv
polyop.setfacematid g i matid

)

)


and i don't know how to do it in mesh space cause setmapdaceid does nothing (only polyop's func works) - mat id stays the same. don't know why.

as for mod and floor - mod returns fraction so let's say our V = 2.53 - mod() returns 0.53 and floor() - 2. i need last one.

denisT
03-03-2012, 04:07 AM
floor ... blah ... to integer works, but there is the mod function to do the same.
hey! my bad. just apply the float and mxs will cast the number to integer ...

denisT
03-03-2012, 04:26 AM
and i don't know how to do it in mesh space cause setmapdaceid does nothing (only polyop's func works) - mat id stays the same. don't know why.

forget about original question. as i said - not clear question can't get the complete answer.
so let's play yourself.

i don't have the max open but the idea has to be:
# do everything in mesh space
# get a uv face center averaging tverts coordinates. it's the same as you do (getTVFace, getTVert...)
# apply face ID (setFaceMatID) using just float of center's v ... (or v+1)

denisT
03-03-2012, 05:06 AM
well... one line solution... blind test:

for f=1 to mesh.numfaces do setFaceMatID f mesh (vv = gettvface mesh f; (((gettvert mesh vv[1]) + (gettvert mesh vv[2]) + (gettvert mesh vv[3]))/3).y +1)

:) does it work?

denisT
03-03-2012, 05:10 AM
sorry for any possible mistake... it was sent from my phone. :)

3ak
03-03-2012, 12:35 PM
no. it will not work. change "setfacematID mesh f" and what is more important setfacematID doesn't work. matIDs of the faces don't change.

denisT
03-03-2012, 01:57 PM
no. it will not work.
yes. of course it works.

(
delete objects
mesh = plane name:"ID_Mesh" length:100 width:100 lengthsegs:10 widthsegs:10 realWorldMapSize:on realWorldMapSize:on mapcoords:on
converttomesh mesh
for f=1 to mesh.numfaces do setFaceMatID mesh f (vv = gettvface mesh f; (((gettvert mesh vv[1]) + (gettvert mesh vv[2]) + (gettvert mesh vv[3]))/3).y +1)
for f=1 to mesh.numfaces do format "face:% id:%\n" f (getFaceMatID mesh f)
)


the question is what to do with negative numbers...
probably the best way if to collect all tverts to get the bounds first and shift IDs to avoid the negative values:

(
delete objects
mesh = plane name:"ID_Mesh" length:100 width:100 lengthsegs:10 widthsegs:10 realWorldMapSize:on realWorldMapSize:on mapcoords:on
converttomesh mesh

min = 1e9
tverts = for v=1 to mesh.numtverts collect
(
p = gettvert mesh v
if p.y < min do min = p.y
p.y/3
)
min = if min >= 1 the 0 else (1 - min)
for f=1 to mesh.numfaces do
(
vv = gettvface mesh f
setFaceMatID mesh f (tverts[vv[1]] + tverts[vv[2]] + tverts[vv[3]] + min)
)
for f=1 to mesh.numfaces do format "face:% id:%\n" f (getFaceMatID mesh f)
)

metamesh
03-03-2012, 09:19 PM
thanks everyone for the replies, I just tried the script and it does work, it does exactly what i was hoping, so thanks a lot for the time spent, 3ak.

I'll see if i manage to understand what you did in there, is a fairly short script but as i said I don't have scripting or programming experience whatsoever and i go really slow whit these scripting thing.. :banghead:

thanks again

denisT
03-03-2012, 10:47 PM
... I don't have scripting or programming experience whatsoever and i go really slow whit these scripting thing.. :banghead:

use somebody else's script but pick the right one...

CGTalk Moderation
03-03-2012, 10:47 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.