2013-03-06 3 views
1

Мне нужно сгладить выбор точек на их ЛОКАЛЬНОЙ нормальной оси. Я предполагаю, что если нормали правильны, эта ось всегда будет одинаковой, независимо от того, будут ли они выбирать точки с любой стороны объекта?Как сгладить выбор точек

Чтобы визуально представить то, что я пытаюсь добиться, я хотел бы, чтобы превратить это:

enter image description here

В это программно:

enter image description here

Если я могу установить масштаб инструмент для «Нормальных средних» и вручную масштабировать их, я могу сгладить точки на плоскости, однако мне нужно вычислить или сделать это с помощью кода.

Я просмотрел команду polyMoveFacet, и у нее есть флаг под названием localScaleZ, который даже имеет «Flattening», написанный в его описании, но мне не повезло. Какие-либо предложения?

+0

Я мало знаю о майя или о том, какие данные он дает вам доступ, но, учитывая определенные данные, это может быть решено как геометрическая проблема. Не могли бы вы указать, что знаете, как получить доступ? Например, у вас есть все координаты точки? У вас есть список всех самолетов, которые образуют эти точки (т. Е. Список групп по 4 балла каждый) и т. Д.?? – entropy

+0

Есть ли какая-то особая причина, почему это нужно сделать с поли-фасеткой? – joojaa

+0

@ энтропия, у меня есть координаты vactor каждой выбранной точки, нормальное направление, нормали лица, HEAPS информации, я просто не знаю, как это сделать! –

ответ

1

Проще всего просто использовать то же самое, что и вы делаете вручную. Код для этого, что в Mel будет выглядеть следующим образом:

{ // protect global namespace 
    setToolTo Scale; 
    manipScaleContext -e -mode 9 Scale; 
    $oa = `manipScaleContext -q -orientAxes Scale`; 
    $p = `manipScaleContext -q -position Scale`; 
    scale -ws -r 
      -p ($p[0]) ($p[1]) ($p[2]) 
      -oa ($oa[0]+"rad") ($oa[1]+"rad") ($oa[2]+"rad") 
      0 1 1; 
} 

И Python:

cmds.setToolTo('Scale') 
cmds.manipScaleContext("Scale", e=1, mode=9) 
p = cmds.manipScaleContext("Scale", q=1, p=1) 
oa = cmds.manipScaleContext("Scale", q=1, oa=1) 
cmds.scale(0,1,1, 
      p=(p[0],p[1],p[2]), 
      oa=("%srad"%oa[0],"%srad"%oa[1],"%srad"%oa[2])) 
+0

Почему-то ** scmh ** больше не работает с вращением и масштабированием. – joojaa

+0

Я не мог заставить это запустить @joojaa. У меня нет никакой конкретной причины использовать polyMoveFacet, это было единственное, что я мог найти, что было относительно, когда я запускаю ваш скрипт в редакторе скриптов, он не оценивает «$ p» правильно, вам удалось заставить это работать? что вы выбрали? –

+0

также, что такое режим 9? В документах он поднимается до 6? –

1

Я никогда не использовал Майю и я не знаю, что язык сценариев он использует. Поэтому этот ответ касается только математического/геометрического подхода к проблеме. Код находится на python, чтобы продемонстрировать концепцию, но вы должны уметь переводить.

Обратите внимание, что я не тестировал код, но он должен надеяться, по крайней мере, дать вам инструменты, чтобы справиться с этой проблемой.

from math import sqrt 

def point_average(points): 
    l = len(points) 
    return [(p.x/l,p.y/l,p.z/l) for p in points] 

def find_normal(points): 
    normal = point_average([p.normal for p in points]) 
    normal_length = sqrt(sum(c**2 for c in normal)) 
    normal = [c/normal_length for c in normal] 
    return normal 

def find_plane(points): 
    normal = find_average_normal(points) 
    center = point_average(points) 
    # a point and a normal are enough to uniquely identify a plane 
    # we anchor the plane to the farthest point from the center 
    # that should be one of the corners 
    dcenter = lambda p:sqrt((p.x-center.x)**2+(p.y-center.y)**2+(p.z-center.z)**2) 
    points = [(dcenter(p),p) for p in points] 
    points.sort() 
    anchor = points[-1][1] 
    return (anchor,normal) 

def project_point_onto_plane(point, plane): 
    anchor,normal = plane 
    # kudos to http://stackoverflow.com/questions/9605556/how-to-project-a-3d-point-to-a-3d-plane 
    # for the math behind this 
    v = (point.x-anchor[0], point.y-anchor[1], point.z-anchor[2]) 
    dist = v[0]*normal[0] + v[1]*normal[1] + v[2]*normal[2] 
    projected_point = (point.x-dist*normal[0], 
         point.y-dist*normal[1], 
         point.z-dist*normal[1]) 
    return projected_point 
+0

Благодарим за отправку этого !, Не могли бы вы объяснить, какие переменные, которые я должен был бы определить самостоятельно? и что они должны были бы сделать? Пример: точки, должен быть массив выбранных точек? –

+0

Да, точки должны быть массивом точек. Я предполагаю, что каждая точка имеет свойство 'normal' самой точки, а свойство' normal' имеет свойства 'x'' y' и 'z'. Как я уже сказал, я никогда не использовал майю, поэтому я не знаю, как будет выглядеть реальный формат. Является ли майя даже сценарием на питоне? – entropy

+0

По существу, если вы можете получить свои данные в этом формате (набор точек с координатами x, y, z, а также нормальный, который имеет x, y, z), то вам нужно всего лишь вызвать 'find_plane () 'в точках, а затем передать каждую точку в свою очередь с плоскостью в' project_point_onto_plane() ', а затем переместить точку туда, где она сообщает вам. – entropy

Смежные вопросы