Render.ru

Помогите в написании скрипта (разделение Mesh объектов по его matID)

Castello

Активный участник
Рейтинг
5
#1
Хочу написать скрипт который будет делать следующее:
в сцене имеется несколько объектов (Editable Mesh), среди них есть такие у которых количество под материалов (matID) около 50, мне необходимо чтобы matID у объектов в сцене не превышал 32, т.е. для объектов у которых matID > 32 необходимо выполнить разделение. К примеру имеем объект с 40 matID, необходимо разделить его на два - у первого будет 32, у второго 8 matID, и также разделить материалы (и при этом к имени первого объекта добавить "_0", а к имени второго "_1", аналогично с именами материалов). Я хочу не просто получить скрипт который будет это реализовывать, но и мне важно разобраться как все в нем работает.

Я накидал план действий, помогите пожалуйста это реализовать:
Что касается геометрии:
1) Для объектов у которых matID > 32, реализовать разделение функцией meshop.detachFaces (при этом к имени первого объекта добавить "_0", а к имени второго "_1")
2) Перебрать ID у второго объекта чтобы они начинались не с 33, а с 1
Что касается материалов:
3) Для первого объекта удалить под материалы > 32 и присвоить имени материала имя объекта
4) Для второго объекта создать и назначить материал основанный на оставшихся matID которые были > 32 и присвоить имени материала имя объекта

Вроде все, помогите с написанием кода и с комментариями пожалуйста
 

Castello

Активный участник
Рейтинг
5
#2
основное тело скрипта я написал так:

Код:
for obj in objects where classOf obj == Editable_Mesh do
(
	if obj.Material.MaterialList.Count > 32 then
	(
		
	)
)
 

igorznag

Мастер
Рейтинг
103
#3
Хочу написать скрипт который будет делать следующее:
Для чего вам нужен этот скрипт?
Почему вы хотите разделить объекты по его matID?
Почему объект должен иметь максимум 32 материала, а не 33 или 1 материал?
Вроде все, помогите с написанием кода и с комментариями пожалуйста
основное тело скрипта я написал так:
Где ваши коментарии к основному коду скрипта?
Почему вы не использовали в вашем коде функцию meshop.detachFaces?
Почему вы работаете с объектами Editable Mesh, а не Editable Poly?
 

Castello

Активный участник
Рейтинг
5
#4
Скрипт нужен для обработки объектов сцены перед экспортом.
Экспортер который я использую, требует чтобы matID у объекта не превышал 32, следовательно если я хочу экспортировать объекты с matID > 32, то мне нужно разделять их на два, в первом будет максимальное разрешенное кол-во matID (32), а во втором остальные.

работаю с Editable Mesh, потому что экспортер требует их, да и исходные у меня тоже Editable Mesh, по этому не хочу лишний раз конвертировать их в другой тип, а потом обратно. Мне опытный макс скриптер советовал использовать для этих целей Editable Mesh, да и я больше с объектами этого типа работаю.

Кароче, что касается скрипта, я не могу использовать первую функцию meshop.detachFaces, т.к. не знаю как во второй её аргумент <facelist> направить face' ы matID которых в пределах от 1 до 32.
 

Castello

Активный участник
Рейтинг
5
#5
Кароче, что касается скрипта, я не могу использовать первую функцию meshop.detachFaces, т.к. не знаю как во второй её аргумент <facelist> направить face' ы matID которых в пределах от 1 до 32
точнее в <facelist> направить face' ы matID которых от 32 и выше, мне же необходимо отсоеденить сначала эти фейсы и потом с помощью asMesh:true создать новый объект
 

igorznag

Мастер
Рейтинг
103
#6
Кароче, что касается face'ов matID которых от 32 и выше, в цикле перебираем все фейсы и проверяем matID каждого фейса с помощью функции getFaceMatID. Если matID фейсов больше 32, тогда собираем их в массив face_list_by_id. Потом устанавливаем массив face_list_by_id в качестве аргумента <facelist> для функции meshop.detachFaces.
Код:
face_list_by_id=#(); for i=1 to (getNumFaces obj) do 
if(getFaceMatID obj i>32)then append face_list_by_id i
newMesh = meshop.detachFaces obj face_list_by_id delete:true asMesh:true
Проверьте, если правильно работает полная версия скрипта.
Создаем копию сцены перед тем, как использовать скрипт.
Код:
objs=objects as array
for obj in objs where classOf obj == Editable_Mesh do 
(
obj_mat_list_count=obj.Material.MaterialList.Count
if obj_mat_list_count>32 and obj_mat_list_count<=64 then 
( 
face_list_by_id=#(); for i=1 to (getNumFaces obj) do 
if(getFaceMatID obj i>32)then append face_list_by_id i
newMesh = meshop.detachFaces obj face_list_by_id delete:true asMesh:true
update obj --update the mesh
obj_new = Editable_mesh() --create an empty Editable_mesh
obj_new.name=obj.name+"_1"; obj.name+="_0"
obj_new.mesh = newMesh --assign the detached faces to the new mesh
obj_new.transform=obj.transform; obj_new.parent=obj.parent
update obj_new--update the mesh
-----------
m1=multimaterial(); m1_mat_count=0; m2=multimaterial(); m2_mat_count=0; 
m1.name=obj.name; m2.name=obj_new.name
for i=1 to obj.material.materialList.count do 
( 
mat_id=obj.material.materialIDList[i] 
if(mat_id>32)then 
( 
m2_mat_count+=1; 
for k=1 to (getNumFaces obj_new) do 
if(getFaceMatID obj_new k == mat_id)then
setFaceMatID obj_new k m2_mat_count 
m2.materialList.count=m2_mat_count; 
m2.materialList[m2_mat_count]=copy obj.material.materialList[i]; 
)--if(obj.material.materialIDList[i]>32)then
else 
( 
m1_mat_count+=1; m1.materialList.count=m1_mat_count; 
m1.materialList[m1_mat_count]=copy obj.material.materialList[i]; 
m1.materialIDList[m1_mat_count]=obj.material.materialIDList[i]; 
)--else if(mat_id>32)then
)--for i=1 to obj.material.materialList[i].count do
obj.material=m1;obj_new.material=m2;
)--if obj.Material.MaterialList.Count > 32 then 
)--for obj in objs where classOf obj == Editable_Mesh do
 

Castello

Активный участник
Рейтинг
5
#7
Скрипт работает, спасибо.
Что касается объектов все понятно, кстати накопление фейсов я реализовал в одну строчку так:
Код:
for i = 1 to obj.NumFaces where (GetFaceMatID obj i) > 32 collect i
Насчет материалов не все понял, буду разбираться.
 

Castello

Активный участник
Рейтинг
5
#8
objs=objects as array
for obj in objs where classOf obj == Editable_Mesh do
(
obj_mat_list_count=obj.Material.MaterialList.Count
if obj_mat_list_count>32 and obj_mat_list_count<=64 then
(
face_list_by_id=#(); for i=1 to (getNumFaces obj) do
if(getFaceMatID obj i>32)then append face_list_by_id i
newMesh = meshop.detachFaces obj face_list_by_id delete:true asMesh:true
update obj --update the mesh
obj_new = Editable_mesh() --create an empty Editable_mesh
obj_new.name=obj.name+"_1"; obj.name+="_0"
obj_new.mesh = newMesh --assign the detached faces to the new mesh
obj_new.transform=obj.transform; obj_new.parent=obj.parent
update obj_new--update the mesh
Нашел одну ошибку - после того как фейсы были отсоединены, у нового объекта ID полигонов нумеруется с 33 и дальше, а надо чтоб с одного
 

Castello

Активный участник
Рейтинг
5
#9
Хотел попробовать так, но не получилось:
Код:
j = 1
		for i = 33 to obj_1.numfaces
		(
			setFaceMatID obj_1 i j
			j+=1
		)
как правильно это реализовать?
 

Castello

Активный участник
Рейтинг
5
#10
все разобрался -
obj_1 - второй объект получившийся после разделения
Код:
for i = 1 to obj_1.numfaces do
			SetFaceMatID obj_1 i ((GetFaceMatID obj_1 i) - 32)
 
Сверху