Render.ru

Python scripting

Lemieux

Знаток
Рейтинг
58
#1
Нужно получить список полигонов вокруг вертекса, но команда connectedfaces выдаёт вот такой результат - # Result: MeshFace(u'pSphereShape1.f[ххх:ххх,ууу:ууу]') #
Размер всего этого показывает 4, но если обращаться по индексу, то пишет - "Indexing only allowed on an incompletely specified component (ie, 'cube.vtx')". Это и понятно, ведь запись равносильна тому, что если поочерёдно выделять фейсы, а потом выполнить команду "ls".
Решил я эту проблему так
Код:
from pymel.core import *

cv = ls(sl=1)[0].connectedFaces()
select(cv)
lsfc = ls(sl=1, fl=1)
Но хотелось бы как-то покороче, может быть у кого-нибудь будут идеи?
 

4i4ikov

Знаток
Рейтинг
37
#3
Нужно получить список полигонов вокруг вертекса, но команда connectedfaces выдаёт вот такой результат - # Result: MeshFace(u'pSphereShape1.f[ххх:ххх,ууу:ууу]') #
Размер всего этого показывает 4, но если обращаться по индексу, то пишет - "Indexing only allowed on an incompletely specified component (ie, 'cube.vtx')". Это и понятно, ведь запись равносильна тому, что если поочерёдно выделять фейсы, а потом выполнить команду "ls".
Потому что это класс, cv - пимеловский класс, он выдает то что в классе прописано на перегрузку принта через __repr__. Смотри описание класса, какие нужные тебе методы там есть.
Что-то типа
list(cv.indicesIter())
даст индексы фейсов
Смотри что в классе ещё есть.

И ls у тебя стал не питоновским а пимеловским, ты же перегрузил все имена,
луше так делать
import pymel.core as pm
pm.ls...

А на меле-питоне фейсы от верт берутся через polyListComponentConversion или polyInfo.
 
Последнее редактирование:

4i4ikov

Знаток
Рейтинг
37
#7
Функция list помогла
Код:
cv = list(ls(sl=1)[0].connectedFaces())
Да, метод __iter__ есть у класса и list его раскрывает,
значит его и как итератор можно заюзать:

import pymel.core as pm
cv = pm.ls(sl=1)[0].connectedFaces()
for f in cv: print f

И если ничего не выбрано будет ошибка индекса из-за [0], тогда ещё добавлять или try или if
 

Andots

Знаток
Рейтинг
66
#8
Кстате, а никто не в курсе какого нибудь оптимального алгоритма отслеживания минимального расстояния между 2-я полигональными объектами? Пока мне видится только так, берем координаты 1-го вертекса одного из объектов и считаем расстояние до каждого вертекса второго объета, далее берем след вертекс и делаем тоже самое, и так для каждого. В итоге получаем огромедный массив в котором уже находим мин значение. Работать то будет но уж больно ресурсоемко, особенно если полигонаж не совсем маленький.
 

Andots

Знаток
Рейтинг
66
#10
Например между сферой и сферой?
Да нее. Тут было бы все просто, можно было бы фейкануть. Между двумя объектами произвольной формы. Грубо говоря нужно отследить все коллизии (или когда объекты близки к этому) и получить индекс вертексов которые эту коллизию производят (там понятно что вертексы не колизятся, но не суть). Как это сделать то я знаю, вот тока алгоритм поиска расстояния вызывает неприятные эмоции в виду ресурсоемкости.
 
Последнее редактирование:

maiden666

Мастер
Рейтинг
112
#11
а что если геометрию сконвертить в баундинг бокс, и танцевать уже от этого?
 

Andots

Знаток
Рейтинг
66
#12
а что если геометрию сконвертить в баундинг бокс, и танцевать уже от этого?
Ну это ничего не даст, это просто по сути костыль. Можно и лоу польную геометрию прицепить, или локаторов нацеплять в тех местах где ты знаешь что будет коллизия и следить за ними. Суть в том ,что есть ли еще какие нить методы расчетов кроме как считать расстояние между всеми вершинами одного объекта со всеми вершинами другова. Там не важно боундиг бокс это, сфера, буква ЗЮ или еще что то в этом роде. Не знаю, как то вектора на объект рассчитаь и исключить из расчетов удаленные или развернутые в другую сторону нормали, хотя чтоб получить нормали тоже придется получать доступ ко всем элементам, что никак не ускорит дело. Да наверно не вариант иначе, комп не человек, как ему объяснишь что не надо просчитывать вершины на пятке если объект находиться у уха, если только сам не исключишь их из расчета.

Интересно как shrinkwrap работает. Также считает все вершины на объекте или как-то обходит это беря только те которые в непосредственной близости.
 
Последнее редактирование:

4i4ikov

Знаток
Рейтинг
37
#13
есть ли еще какие нить методы расчетов кроме как считать расстояние между всеми вершинами одного объекта со всеми вершинами другова.
Посмотри на апишную allIntersections()
Видел несколько скриптов с определением попадания точки вовнутрь,
у китайца например http://maya-tricks.blogspot.ru/2009/04/python.html


И твой любимый jlCollisionDeformer.py тоже делает через allIntersections:
gotHit = colliderFn.allIntersections( raySource,rayDirection, faceIds, triIds, idsSorted, space, maxParam, testBothDirs, accelParams,sortHits, hitPoints1, hitRayParams, hitFaces, hitTriangles, hitBary1s, hitBary2s )
 

Andots

Знаток
Рейтинг
66
#14
Посмотри на апишную allIntersections()
Видел несколько скриптов с определением попадания точки вовнутрь,
у китайца например http://maya-tricks.blogspot.ru/2009/04/python.html


И твой любимый jlCollisionDeformer.py тоже делает через allIntersections:
gotHit = colliderFn.allIntersections( raySource,rayDirection, faceIds, triIds, idsSorted, space, maxParam, testBothDirs, accelParams,sortHits, hitPoints1, hitRayParams, hitFaces, hitTriangles, hitBary1s, hitBary2s )
Ага, спасибки посмотрю colliderFn.allIntersection. jlCollisionDeformer.py этот зверь тормозит безбожно, причем не сказать что на тяжелых моделях. Я на досуге начал cpp ковырять, не скажу что написание нод на нем сильно отличается от нод на питон Api. Думаю через недельку что то не дюже сложное смогу и на нем ваять.

Интересно как colliderFn.allIntersection работает. Это всетаки процедура, мож она тоже самое делает, считает каждую вершину, выдает просто необходимое. Хотелось бы принцип понять, дабы использовать в своих корыстных целях. Да и не совсем прям интерсекция нужна, больше надо подключить некий тригер при сближении компонентов шейпов на определенное рассояние.
 
Последнее редактирование:

4i4ikov

Знаток
Рейтинг
37
#15
Оказывается allIntersection не оптимизирована, если объекты развести друг от друга, она всё равно будет фигачить на полную, проверяя все точки. Очевидно что сперва можно проверить пересечение по Б-Боксам, а потом уже кидать на allIntersection, или не кидать

а по ББ вообще шустро проверяется
Код:
import maya.cmds as mc
sel = mc.ls(sl=1) # выбрать два объекта
bb1 = mc.exactWorldBoundingBox(sel[0])
bb2 = mc.exactWorldBoundingBox(sel[1])
if ( (bb1[0]>bb2[3]) or (bb2[0]>bb1[3]) or (bb1[1]>bb2[4]) or (bb2[1]>bb1[4]) or (bb1[2]>bb2[5]) or (bb2[2]>bb1[5]) ):
    print "not intersects"
else:
    print "aga! intersects"
Может у allIntersection оптимизация каким-то параметром включается, я смотрел на китайском примере, там нет.
 
Последнее редактирование:

4i4ikov

Знаток
Рейтинг
37
#16
Интересно как colliderFn.allIntersection работает. Это всетаки процедура, мож она тоже самое делает, считает каждую вершину, выдает просто необходимое. Хотелось бы принцип понять, дабы использовать в своих корыстных целях. Да и не совсем прям интерсекция нужна, больше надо подключить некий тригер при сближении компонентов шейпов на определенное рассояние.
Так тригер всеравно по тому же принципу будет считать, перебирая все точки. А математика там примерно такая - для 2d например https://habrahabr.ru/post/125356/ , математика там вроде сложная, но конечный код выглядит простым.
 

Andots

Знаток
Рейтинг
66
#17
Так тригер всеравно по тому же принципу будет считать, перебирая все точки. А математика там примерно такая - для 2d например https://habrahabr.ru/post/125356/ , математика там вроде сложная, но конечный код выглядит простым.
Вот в том то и дело что будет все точки считать, потому и задал вопрос как оптимизировать. Я тут просто покумекал и придумал такой вид оптимизации, (ну чтоб не заморачиваться с ББ, бб можно оставить как самое первое включение) .. К примеру есть 2 модели каждая по 20к поликов. Изначально считаем не каждый вертекс а каждый сотый (ну или 1000, не суть) к примеру и находим расстояние до каждого сотого ветекса второго объекта, как только расстояние уменьшается до определенного значения включаем в расчет остальные вертексы вокруг того который приблизился. Это конечно фейчек, но ускорить должен в разы. Как только быстро получить индексы фейсов или вертексов в определенном радиусе. Ну мы конечно не берем сейчас костыли вроде разбивки модели на несколько кусков и соответственно исключения из расчетов ненужных частей. Тут то понятно.
 
Последнее редактирование:

4i4ikov

Знаток
Рейтинг
37
#18
Это ты сейчас прокси объект придумал)
При хорошей оптимизации и будет несколько уровней упрощений, начиная с ББ, потом прокси, потом ещё что-то.
Можно ещё учитывать предыдущее положение...

+
если хочешь на сырой код глянуть - открываешь PolyEngine.dll в IDA, ищешь allIntersections, жмешь F5 и любуешься почти сишным кодом, он не сложный.
Заметил интересное в коде, активно используется SSE!, ну хоть и на этом спасибо, но плохо что на одном ядре(
Вот кстати мощная оптимизация - распараллеливание!
 
Последнее редактирование:

Andots

Знаток
Рейтинг
66
#19
Это ты сейчас прокси объект придумал)
При хорошей оптимизации и будет несколько уровней упрощений, начиная с ББ, потом прокси, потом ещё что-то.
Можно ещё учитывать предыдущее положение...
Ну да, судя по всему это единственный вариант, делать многоуровневые логичные оптимизации. Максимально упростить и выкинуть совсем ненужные вертексы наверно не вариант, чтоб машина поняла что они не нужны, ей надо их посчитать ненужными, т.е опять же просчитать.
 
Сверху