1. Пользоваться форумом на планшетах и телефонах стало удобнее благодаря Tapatalk

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

Тема в разделе "MAXScript", создана пользователем Castello, 7 дек 2012.

Модераторы: Savin Denis
  1. Castello

    Castello Активный участник

    С нами с:
    06.01.2012
    Сообщения:
    47
    Симпатии:
    0
    Баллы:
    5
    Хочу написать скрипт который будет делать следующее:
    в сцене имеется несколько объектов (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 и присвоить имени материала имя объекта

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

    Castello Активный участник

    С нами с:
    06.01.2012
    Сообщения:
    47
    Симпатии:
    0
    Баллы:
    5
    основное тело скрипта я написал так:

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

    igorznag Знаток

    С нами с:
    23.04.2010
    Сообщения:
    1.256
    Симпатии:
    173
    Баллы:
    65
    Для чего вам нужен этот скрипт?
    Почему вы хотите разделить объекты по его matID?
    Почему объект должен иметь максимум 32 материала, а не 33 или 1 материал?
    Где ваши коментарии к основному коду скрипта?
    Почему вы не использовали в вашем коде функцию meshop.detachFaces?
    Почему вы работаете с объектами Editable Mesh, а не Editable Poly?
     
  4. Castello

    Castello Активный участник

    С нами с:
    06.01.2012
    Сообщения:
    47
    Симпатии:
    0
    Баллы:
    5
    Скрипт нужен для обработки объектов сцены перед экспортом.
    Экспортер который я использую, требует чтобы matID у объекта не превышал 32, следовательно если я хочу экспортировать объекты с matID > 32, то мне нужно разделять их на два, в первом будет максимальное разрешенное кол-во matID (32), а во втором остальные.

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

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

    Castello Активный участник

    С нами с:
    06.01.2012
    Сообщения:
    47
    Симпатии:
    0
    Баллы:
    5
    точнее в <facelist> направить face' ы matID которых от 32 и выше, мне же необходимо отсоеденить сначала эти фейсы и потом с помощью asMesh:true создать новый объект
     
  6. igorznag

    igorznag Знаток

    С нами с:
    23.04.2010
    Сообщения:
    1.256
    Симпатии:
    173
    Баллы:
    65
    Кароче, что касается 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 
     
  7. Castello

    Castello Активный участник

    С нами с:
    06.01.2012
    Сообщения:
    47
    Симпатии:
    0
    Баллы:
    5
    Скрипт работает, спасибо.
    Что касается объектов все понятно, кстати накопление фейсов я реализовал в одну строчку так:
    Код:
    for i = 1 to obj.NumFaces where (GetFaceMatID obj i) > 32 collect i
    Насчет материалов не все понял, буду разбираться.
     
  8. Castello

    Castello Активный участник

    С нами с:
    06.01.2012
    Сообщения:
    47
    Симпатии:
    0
    Баллы:
    5
    Нашел одну ошибку - после того как фейсы были отсоединены, у нового объекта ID полигонов нумеруется с 33 и дальше, а надо чтоб с одного
     
  9. Castello

    Castello Активный участник

    С нами с:
    06.01.2012
    Сообщения:
    47
    Симпатии:
    0
    Баллы:
    5
    Хотел попробовать так, но не получилось:
    Код:
    j = 1
    		for i = 33 to obj_1.numfaces
    		(
    			setFaceMatID obj_1 i j
    			j+=1
    		)
    как правильно это реализовать?
     
  10. Castello

    Castello Активный участник

    С нами с:
    06.01.2012
    Сообщения:
    47
    Симпатии:
    0
    Баллы:
    5
    все разобрался -
    obj_1 - второй объект получившийся после разделения
    Код:
    for i = 1 to obj_1.numfaces do
    			SetFaceMatID obj_1 i ((GetFaceMatID obj_1 i) - 32)
     
Модераторы: Savin Denis

Поделиться этой страницей