Не попадался ли кому скрипт для UV редактора, который находит overlap части и сдвигает их на соседние UV-setы? Кпримеру есть UV-мар дома и его UV окон одинакового размера лежат все одно поверх другого. Нужен скрипт который находит эти overlap части и сдвигает по U и V на 1,2 и т.д. не меняя положения фрагмента, ну или хотябы просто сдвигает заданную выделенную группу. Что-то подобное обсуждалось здесь: http://forums.cgsociety.org/archive/index.php/t-599382.html
Нет не встречал. И написать такой будет сложно если объекты составные как например; Окно где есть рама и стекло отдельно, придется определять кому что принадлежит чтобы сдвинуть UV вместе.
Вы видимо не совсем поняли, определять там вообще ничего не надо. UV-развертка уже сделана, все определено и разложено, нужно только одинаковые части с одинаковыми координатоми просто сместить по u и v координатам на соседние сеты, чтобы на каждом сете лежала только одна такая часть. Можно это и в ручную делать (тупо щелкунв на фрагмент и задав офсет), просто если окон, к примеру, много, то муторно каждое сдвигать поотдельности.
Поидее там простой совсем алгоритм типа if (какая-то часть лежит сверху другой), then offset (этой части) u=1 или v=1 и так пока не будет overlap частей. Ну или хотябы чтобы выбранные части просто сдвигались по горизонтали на соседние сеты, кроме одной, соответственно на u=1, u=2 u= n, где n=выбранному количеству частей минус одна.
Может быть этот способ чем-то поможет:
1. Выделяем нужные части развертки.
2. В окне Edit UVWs в меню Tools выбираем пункт Pack UVs.
3. В окне Pack отключяем Normalize Clusters и нажимаем кнопку OK.
Поскольку сама задача интересная для разминки
набросал небольшой скрипт.
На кубиках в рамках задачи вполне себе работает, на реальной геометрии сомневаюсь что особо поможет.
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
...ну или хотябы просто сдвигает заданную выделенную группу...
...Ну или хотябы чтобы выбранные части просто сдвигались по горизонтали на соседние сеты, кроме одной...
Простой пример:
1. В новой сцене создаем 3 объекта Plane и конвертируем объекты в Editable Poly.
2. Выделяем один объект и присоединяем (Attach) к нему остальные объекты. Название объекта = "окна".
3. Выделяем объект "окна" и добавляем модификатор Unwrap UVW.
Объект "окна" (Editable Poly) состоит из 3 элементов.
Развертка каждого элемента в данном случае состоит из одного куска-Cluster.
Модификатор Unwrap UVW должен быть активным в режиме Face (на панели Modify).
4. Выделяем нужную группу развертки (одинаковые части-Cluster с одинаковыми координатами).
Можно выделять не всю часть-Cluster, а только один полигон-Face из соответствующей части-Cluster.
5. Запускаем скрипт:
Супер! Спасибо! Как раз то что надо! Оба скрипта работают, у Дениса только он расширенный, как раз по начальному варианту - одним запуском скрипта все сразу делается. Единственно, Денис, если не сложно, то можно еще добавить чтобы 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 модификатор, но он там получается не нужным, так как все оффсеты сколлапсены до этого получаются, т.е. его можно убрать или тогда (что лучше) не коллапсить оффсеты, чтобы они на этом модификаторе оставались.
Поправил выше код.
Коллапсить или неколлапсить там нечего, поскольку напрямую работает с координатами.
Unwrap UVW добавлялся чтоб быстро оценить работу скрипта.
Доступ к резюме доступен только по пакетному доступу HR менеджерам зарегистрированных компаний. Узнать о вариантах корпоративных пакетов можно по ссылке.
Анатолий Меймухин
Savin Denis
Анатолий Меймухин
Анатолий Меймухин
igorznag
1. Выделяем нужные части развертки.
2. В окне Edit UVWs в меню Tools выбираем пункт Pack UVs.
3. В окне Pack отключяем Normalize Clusters и нажимаем кнопку OK.
Анатолий Меймухин
Savin Denis
набросал небольшой скрипт.
На кубиках в рамках задачи вполне себе работает, на реальной геометрии сомневаюсь что особо поможет.
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Вложения
igorznag
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 (Отмена).
Анатолий Меймухин
Savin Denis
Коллапсить или неколлапсить там нечего, поскольку напрямую работает с координатами.
Unwrap UVW добавлялся чтоб быстро оценить работу скрипта.
Анатолий Меймухин