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

Python scripting

Тема в разделе "Maya", создана пользователем Lemieux, 31 окт 2016.

Модераторы: Dark™, Skif
  1. Lemieux

    Lemieux Знаток

    С нами с:
    08.06.2011
    Сообщения:
    1.077
    Симпатии:
    124
    Баллы:
    57
    Нужно получить список полигонов вокруг вертекса, но команда 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)
    Но хотелось бы как-то покороче, может быть у кого-нибудь будут идеи?
     
  2. Lemieux

    Lemieux Знаток

    С нами с:
    08.06.2011
    Сообщения:
    1.077
    Симпатии:
    124
    Баллы:
    57
    Уменьшил на одну строчку :D
    Код:
    cv = ls(sl=1)[0].connectedFaces()
    lsfc = filterExpand(cv, sm=34)
     
  3. 4i4ikov

    4i4ikov Знаток

    С нами с:
    07.04.2015
    Сообщения:
    247
    Симпатии:
    80
    Баллы:
    27
    Потому что это класс, cv - пимеловский класс, он выдает то что в классе прописано на перегрузку принта через __repr__. Смотри описание класса, какие нужные тебе методы там есть.
    Что-то типа
    list(cv.indicesIter())
    даст индексы фейсов
    Смотри что в классе ещё есть.

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

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

    Lemieux Знаток

    С нами с:
    08.06.2011
    Сообщения:
    1.077
    Симпатии:
    124
    Баллы:
    57
    Не, polyInfo я бомбил. Он выдаёт стринг строку, потом токен/сплит и тд.

    А вот по поводу класса, ничего нужного в описании класса не нашёл, и ни чего интересного не дала команда dir(MeshVertex)
     
  5. 4i4ikov

    4i4ikov Знаток

    С нами с:
    07.04.2015
    Сообщения:
    247
    Симпатии:
    80
    Баллы:
    27
    Ты же на питоне, питон отлично подходит для парсинга, это на меле с парсингом мутотень.
     
  6. Lemieux

    Lemieux Знаток

    С нами с:
    08.06.2011
    Сообщения:
    1.077
    Симпатии:
    124
    Баллы:
    57
    Функция list помогла
    Код:
    cv = list(ls(sl=1)[0].connectedFaces())
     
  7. 4i4ikov

    4i4ikov Знаток

    С нами с:
    07.04.2015
    Сообщения:
    247
    Симпатии:
    80
    Баллы:
    27
    Да, метод __iter__ есть у класса и list его раскрывает,
    значит его и как итератор можно заюзать:

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

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

    Andots Знаток

    С нами с:
    12.03.2009
    Сообщения:
    675
    Симпатии:
    127
    Баллы:
    42
    Кстате, а никто не в курсе какого нибудь оптимального алгоритма отслеживания минимального расстояния между 2-я полигональными объектами? Пока мне видится только так, берем координаты 1-го вертекса одного из объектов и считаем расстояние до каждого вертекса второго объета, далее берем след вертекс и делаем тоже самое, и так для каждого. В итоге получаем огромедный массив в котором уже находим мин значение. Работать то будет но уж больно ресурсоемко, особенно если полигонаж не совсем маленький.
     
  9. Lemieux

    Lemieux Знаток

    С нами с:
    08.06.2011
    Сообщения:
    1.077
    Симпатии:
    124
    Баллы:
    57
    Например между сферой и сферой?
     
  10. Andots

    Andots Знаток

    С нами с:
    12.03.2009
    Сообщения:
    675
    Симпатии:
    127
    Баллы:
    42
    Да нее. Тут было бы все просто, можно было бы фейкануть. Между двумя объектами произвольной формы. Грубо говоря нужно отследить все коллизии (или когда объекты близки к этому) и получить индекс вертексов которые эту коллизию производят (там понятно что вертексы не колизятся, но не суть). Как это сделать то я знаю, вот тока алгоритм поиска расстояния вызывает неприятные эмоции в виду ресурсоемкости.
     
    Последнее редактирование: 2 ноя 2016
  11. maiden666

    maiden666 Мастер

    С нами с:
    06.04.2010
    Сообщения:
    3.402
    Симпатии:
    151
    Баллы:
    84
    а что если геометрию сконвертить в баундинг бокс, и танцевать уже от этого?
     
  12. Andots

    Andots Знаток

    С нами с:
    12.03.2009
    Сообщения:
    675
    Симпатии:
    127
    Баллы:
    42
    Ну это ничего не даст, это просто по сути костыль. Можно и лоу польную геометрию прицепить, или локаторов нацеплять в тех местах где ты знаешь что будет коллизия и следить за ними. Суть в том ,что есть ли еще какие нить методы расчетов кроме как считать расстояние между всеми вершинами одного объекта со всеми вершинами другова. Там не важно боундиг бокс это, сфера, буква ЗЮ или еще что то в этом роде. Не знаю, как то вектора на объект рассчитаь и исключить из расчетов удаленные или развернутые в другую сторону нормали, хотя чтоб получить нормали тоже придется получать доступ ко всем элементам, что никак не ускорит дело. Да наверно не вариант иначе, комп не человек, как ему объяснишь что не надо просчитывать вершины на пятке если объект находиться у уха, если только сам не исключишь их из расчета.

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

    4i4ikov Знаток

    С нами с:
    07.04.2015
    Сообщения:
    247
    Симпатии:
    80
    Баллы:
    27
    Посмотри на апишную allIntersections()
    Видел несколько скриптов с определением попадания точки вовнутрь,
    у китайца например http://maya-tricks.blogspot.ru/2009/04/python.html
    [​IMG]

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

    Andots Знаток

    С нами с:
    12.03.2009
    Сообщения:
    675
    Симпатии:
    127
    Баллы:
    42
    Ага, спасибки посмотрю colliderFn.allIntersection. jlCollisionDeformer.py этот зверь тормозит безбожно, причем не сказать что на тяжелых моделях. Я на досуге начал cpp ковырять, не скажу что написание нод на нем сильно отличается от нод на питон Api. Думаю через недельку что то не дюже сложное смогу и на нем ваять.

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

    4i4ikov Знаток

    С нами с:
    07.04.2015
    Сообщения:
    247
    Симпатии:
    80
    Баллы:
    27
    Оказывается 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 оптимизация каким-то параметром включается, я смотрел на китайском примере, там нет.
     
    Последнее редактирование: 2 ноя 2016
  16. 4i4ikov

    4i4ikov Знаток

    С нами с:
    07.04.2015
    Сообщения:
    247
    Симпатии:
    80
    Баллы:
    27
    Так тригер всеравно по тому же принципу будет считать, перебирая все точки. А математика там примерно такая - для 2d например https://habrahabr.ru/post/125356/ , математика там вроде сложная, но конечный код выглядит простым.
     
  17. Andots

    Andots Знаток

    С нами с:
    12.03.2009
    Сообщения:
    675
    Симпатии:
    127
    Баллы:
    42
    Вот в том то и дело что будет все точки считать, потому и задал вопрос как оптимизировать. Я тут просто покумекал и придумал такой вид оптимизации, (ну чтоб не заморачиваться с ББ, бб можно оставить как самое первое включение) .. К примеру есть 2 модели каждая по 20к поликов. Изначально считаем не каждый вертекс а каждый сотый (ну или 1000, не суть) к примеру и находим расстояние до каждого сотого ветекса второго объекта, как только расстояние уменьшается до определенного значения включаем в расчет остальные вертексы вокруг того который приблизился. Это конечно фейчек, но ускорить должен в разы. Как только быстро получить индексы фейсов или вертексов в определенном радиусе. Ну мы конечно не берем сейчас костыли вроде разбивки модели на несколько кусков и соответственно исключения из расчетов ненужных частей. Тут то понятно.
     
    Последнее редактирование: 2 ноя 2016
  18. 4i4ikov

    4i4ikov Знаток

    С нами с:
    07.04.2015
    Сообщения:
    247
    Симпатии:
    80
    Баллы:
    27
    Это ты сейчас прокси объект придумал)
    При хорошей оптимизации и будет несколько уровней упрощений, начиная с ББ, потом прокси, потом ещё что-то.
    Можно ещё учитывать предыдущее положение...

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

    Andots Знаток

    С нами с:
    12.03.2009
    Сообщения:
    675
    Симпатии:
    127
    Баллы:
    42
    Ну да, судя по всему это единственный вариант, делать многоуровневые логичные оптимизации. Максимально упростить и выкинуть совсем ненужные вертексы наверно не вариант, чтоб машина поняла что они не нужны, ей надо их посчитать ненужными, т.е опять же просчитать.
     
  20. 4i4ikov

    4i4ikov Знаток

    С нами с:
    07.04.2015
    Сообщения:
    247
    Симпатии:
    80
    Баллы:
    27
    Про распараллеливание ещё вспомнил. Через OpenMP делай в cpp.
     
    Andots нравится это.
Модераторы: Dark™, Skif

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