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

UV offset

Тема в разделе "MAXScript", создана пользователем Анатолий Меймухин, 25 июн 2011.

Модераторы: Savin Denis
  1. Анатолий Меймухин

    Анатолий Меймухин Мастер

    С нами с:
    23.10.2000
    Сообщения:
    63
    Симпатии:
    0
    Баллы:
    986
    Не попадался ли кому скрипт для UV редактора, который находит overlap части и сдвигает их на соседние UV-setы? Кпримеру есть UV-мар дома и его UV окон одинакового размера лежат все одно поверх другого. Нужен скрипт который находит эти overlap части и сдвигает по U и V на 1,2 и т.д. не меняя положения фрагмента, ну или хотябы просто сдвигает заданную выделенную группу. Что-то подобное обсуждалось здесь: http://forums.cgsociety.org/archive/index.php/t-599382.html
     
  2. Savin Denis vip

    Savin Denis Moderator Команда форума

    С нами с:
    05.05.2005
    Сообщения:
    1.633
    Симпатии:
    0
    Баллы:
    210
    Нет не встречал. И написать такой будет сложно если объекты составные как например; Окно где есть рама и стекло отдельно, придется определять кому что принадлежит чтобы сдвинуть UV вместе.
     
  3. Анатолий Меймухин

    Анатолий Меймухин Мастер

    С нами с:
    23.10.2000
    Сообщения:
    63
    Симпатии:
    0
    Баллы:
    986
    Вы видимо не совсем поняли, определять там вообще ничего не надо. UV-развертка уже сделана, все определено и разложено, нужно только одинаковые части с одинаковыми координатоми просто сместить по u и v координатам на соседние сеты, чтобы на каждом сете лежала только одна такая часть. Можно это и в ручную делать (тупо щелкунв на фрагмент и задав офсет), просто если окон, к примеру, много, то муторно каждое сдвигать поотдельности.
     
  4. Анатолий Меймухин

    Анатолий Меймухин Мастер

    С нами с:
    23.10.2000
    Сообщения:
    63
    Симпатии:
    0
    Баллы:
    986
    Поидее там простой совсем алгоритм типа if (какая-то часть лежит сверху другой), then offset (этой части) u=1 или v=1 и так пока не будет overlap частей. Ну или хотябы чтобы выбранные части просто сдвигались по горизонтали на соседние сеты, кроме одной, соответственно на u=1, u=2 u= n, где n=выбранному количеству частей минус одна.
     
  5. igorznag

    igorznag Знаток

    С нами с:
    23.04.2010
    Сообщения:
    1.256
    Симпатии:
    173
    Баллы:
    65
    Может быть этот способ чем-то поможет:
    1. Выделяем нужные части развертки.
    2. В окне Edit UVWs в меню Tools выбираем пункт Pack UVs.
    3. В окне Pack отключяем Normalize Clusters и нажимаем кнопку OK.
     
  6. Анатолий Меймухин

    Анатолий Меймухин Мастер

    С нами с:
    23.10.2000
    Сообщения:
    63
    Симпатии:
    0
    Баллы:
    986
    2 igorznag: еще раз повторю: мне НЕ нужно паковать или перепаковать - нужен именно оффсет на целые числа
     
  7. Savin Denis vip

    Savin Denis Moderator Команда форума

    С нами с:
    05.05.2005
    Сообщения:
    1.633
    Симпатии:
    0
    Баллы:
    210
    Поскольку сама задача интересная для разминки
    набросал небольшой скрипт.
    На кубиках в рамках задачи вполне себе работает, на реальной геометрии сомневаюсь что особо поможет.

    Код:
    fn SubArray array1 array2 = 
    (
    	delIndex = for f in array2 where (ind = findItem array1 f) != 0 collect ind
    	sort delIndex
    	for i = delIndex .count to 1 by -1 do deleteItem array1 delIndex[i]
    	return array1
    )
    
    fn comparePoint p1 p2  epsilon = (distance p1 p2) <= epsilon
    	
    fn compareOverlapUVElements obj channel element1 element2 epsilon  =
    (
    	 local theVertsEl1 = meshop.getMapVertsUsingMapFace obj channel element1
    	 local theVertsEl2 = meshop.getMapVertsUsingMapFace obj channel element2
    	
    	 for v1 in theVertsEl1 do 
    	 (
    		 p1 = meshop.getMapVert obj channel v1
    		 local fFind = true		
    		 for v2 in theVertsEl2 where fFind do 
    		 ( 
    		    p2 = meshop.getMapVert obj channel v2
    		    fFind =  not comparePoint  p1 p2  epsilon 
    		 )
    		 if fFind do return false
    	 )
    	 
    	 return true
    )
    
    fn findOverlap elemets_overlap index =
    (
    	for i = 1 to elemets_overlap.count where findItem elemets_overlap[i] index != 0 do return i
    	return 0
    )
    
    fn skipOverlap elemets_overlap index =
    (
    	i = findOverlap elemets_overlap index
    	if i > 1 do return false	return true
    )
    
    
    fn appendOverlap elemets_overlap elemets_array index new_index =
    (
    	i = findOverlap elemets_overlap index
    	if i == 0 then append elemets_overlap #(index, new_index)
    	else append elemets_overlap[i] new_index
    )
    
    fn offsetElement obj channel elemet1 offset =
    (
    	local theVertsEl1 = (meshop.getMapVertsUsingMapFace obj channel elemet1 )
    	 for v in theVertsEl1 do 
    	 (
    		p = meshop.getMapVert obj channel v
    		p += offset
    		meshop.setMapVert obj channel v p
    	 )
    )
    
    
    fn offsetOverlap obj channel elemets_overlap elemets_array offset vstep =
    (
        
        for elemets in elemets_overlap do 
        (
            if vstep == 0 then vstep = elemets.count
            for i = 1 to elemets.count do 
            (
                ind = elemets[i]
                cnt = i - 1
                cntU = mod cnt vstep
                cntV = floor (cnt / vstep)
                offsetUVW = offset * [ cntU, cntV, cnt]
                offsetElement obj channel elemets_array[ind] offsetUVW
            )
        )
    )
    
    
    fn shiftOverlapUVElements mesh channel:1 offset:[1,1,0]  vstep:10 epsilon:0.001 =	
    (
    local obj = copy mesh 
    convertToMesh obj 
    	
    free_faces = #{1 .. obj.numfaces}	 as array
    elemets_array	= #()
    elemets_overlap = #()	
    
    while free_faces.count > 0 do
    (
     face_array = #(free_faces[free_faces.count])
     cnt = 0 
    
    
     while cnt < face_array.count do 
     (
      cnt += 1
    	 
    
      theVerts = meshop.getMapVertsUsingMapFace obj channel #(face_array[cnt])
      theFaces = meshop.getMapFacesUsingMapVert obj channel theVerts 
    
      for f in theFaces do appendIfUnique face_array f
    
     )--end while cnt
    
      append elemets_array face_array
     
     fFind = true
     for i = 1 to elemets_array.count - 1 while fFind do --where skipOverlap elemets_overlap i do 
    (
    	if compareOverlapUVElements obj channel elemets_array[i] face_array epsilon then 
    	(
    		appendOverlap elemets_overlap elemets_array i (elemets_array.count)
    		fFind = false
    	)
    )
     
    
    SubArray  free_faces  face_array
    
    
    )--end while numfaces
    
    offsetOverlap obj channel elemets_overlap elemets_array offset vstep
    
    obj
    )
    
     
    --Example usage:
    obj = shiftOverlapUVElements $ channel:1 offset:[1,1,0]  vstep:10 epsilon:0.001
    select obj
    --modPanel.addModToSelection (Unwrap_UVW ()) ui:on
    
     

    Вложения:

    • 2352012.jpg
      2352012.jpg
      Размер файла:
      44,2 КБ
      Просмотров:
      73
  8. igorznag

    igorznag Знаток

    С нами с:
    23.04.2010
    Сообщения:
    1.256
    Симпатии:
    173
    Баллы:
    65
    Простой пример:
    1. В новой сцене создаем 3 объекта Plane и конвертируем объекты в Editable Poly.
    2. Выделяем один объект и присоединяем (Attach) к нему остальные объекты. Название объекта = "окна".
    3. Выделяем объект "окна" и добавляем модификатор Unwrap UVW.
    Объект "окна" (Editable Poly) состоит из 3 элементов.
    Развертка каждого элемента в данном случае состоит из одного куска-Cluster.
    Модификатор Unwrap UVW должен быть активным в режиме Face (на панели Modify).
    4. Выделяем нужную группу развертки (одинаковые части-Cluster с одинаковыми координатами).
    Можно выделять не всю часть-Cluster, а только один полигон-Face из соответствующей части-Cluster.
    5. Запускаем скрипт:
    Код:
    if($selection.count==1)then
    (
    obj=$selection[1];
    if(obj.modifiers.count>0)then
    (
    uvw=modPanel.getCurrentObject();
    if(classof uvw==Unwrap_UVW)then
    (
    if(uvw.getTVSubObjectMode()==3)then
    (
    sf_bit_array=uvw.getSelectedFaces(); sf_array=sf_bit_array as array;
    cluster_count=0;
    while (sf_array.count>0)do
    (
    cluster_count=cluster_count+1;
    uvw.selectFaces #{sf_array[1]}; uvw.selectElement();
    offset_vector=[cluster_count-1,0,0];
    if(cluster_count>1)then uvw.moveSelected offset_vector;
    sf_bit_array=sf_bit_array-uvw.getSelectedFaces(); sf_array=sf_bit_array as array;
    
    if(cluster_count==200)then exit;
    )--loop
    )--SubObjectMode=Face
    )--Unwrap_UVW
    )--have modifiers
    )--select one object
    Максимальное количество кусков из группы которые сдвигаются сейчас установленно 200.
    Скрипт не имеет фунцию Undo (Отмена).
     
  9. Анатолий Меймухин

    Анатолий Меймухин Мастер

    С нами с:
    23.10.2000
    Сообщения:
    63
    Симпатии:
    0
    Баллы:
    986
    Супер! Спасибо! Как раз то что надо! Оба скрипта работают, у Дениса только он расширенный, как раз по начальному варианту - одним запуском скрипта все сразу делается. Единственно, Денис, если не сложно, то можно еще добавить чтобы offset не только по U шел но и по V вверх на 1 смещался с приращение, когда кол-во всех сетов будет 10, т.е. чтобы десятками шли - максимальный сдвиг по U тогда 9 будет равен, так как 10ый - базовый, нулевой , а потом соответственно U=0 V=1;U=1 V=1; U=2 V=1 и так до U=9, потом тоже но с v=2 и т.д. (Если надо, могу модельку простую кинуть, чтоб опробовать). И еще вообщем совершенно несущественная деталь, но просто обращаю внимание, так сказать для завершености логической: скрипт добавляет Unwrap UVW модификатор, но он там получается не нужным, так как все оффсеты сколлапсены до этого получаются, т.е. его можно убрать или тогда (что лучше) не коллапсить оффсеты, чтобы они на этом модификаторе оставались.
     
  10. Savin Denis vip

    Savin Denis Moderator Команда форума

    С нами с:
    05.05.2005
    Сообщения:
    1.633
    Симпатии:
    0
    Баллы:
    210
    Поправил выше код.
    Коллапсить или неколлапсить там нечего, поскольку напрямую работает с координатами.
    Unwrap UVW добавлялся чтоб быстро оценить работу скрипта.
     
  11. Анатолий Меймухин

    Анатолий Меймухин Мастер

    С нами с:
    23.10.2000
    Сообщения:
    63
    Симпатии:
    0
    Баллы:
    986
    Все отлично, Денис! Еще раз огромное спасибо!
     
Модераторы: Savin Denis

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