Render.ru

Editable poly, выравнивание вершины

Сергей Попов 144982

Пользователь сайта
Рейтинг
2
#1
Всем доброго времени. Давно мучает один вопрос и никак не могу на него найти ответа, надеюсь что здесь мне помогут. В общем есть такая ситуация (см. картинку). Editable poly. Полигон перестает быть планарным. т.е. одна из точек уходит с плоскости, на которой остаются 3 других вершины. Можно ли как-то вернуть точку на плоскость? Сразу скажу, что либо я не понял всю мощь функции make planar, либо ей нельзя сделать полигон планарным переместив только одну из точек.
Заранее спасибо за ответы
 

Вложения

Сергей Попов 144982

Пользователь сайта
Рейтинг
2
#3
В этом конкретном случае просто переместить с активной 2,5D привязкой на виде сбоку.[/quo
Селена [url=/forum/viewtopic.php?post_id=1053559#1053559 сказал(а):
#2[/url]]В этом конкретном случае просто переместить с активной 2,5D привязкой на виде сбоку.
Ну тут-то всё и дело, что мне нужно для общего случая. Вот нарисовал общий случай. Модель относительно координат повернута на произвольный угол. В любом случае спасибо Вам за ответ.
 

Вложения

Рейтинг
22
#4
Сергей Попов, мое мнение не истина в последней инстанции конечно, но по моему не бывает
никаких "общих случаев". Это все равно универсальный рецепт, который врач выпишет всем
больным, не вникая, чем они болеют.
В общем я могу сказать, что работал и работаю в разных 3D-пакетах и считаю, что в MAX-е
самая совершенная и интуитивно понятная система привязок, изучи досконально и используй ее.
В сочетании со вспомогательной геометрией твоя проблема решаема в 100% случаев.
Если нужно на примере, то давай конкретную модель и конкретную проблему.
 

igorznag

Мастер
Рейтинг
103
#5
Можно ли как-то вернуть точку на плоскость?
Попробуйте такой вариант:
Выделяем один непланарный полигон, который состоит из 4 вершин.
Выделяем одну вершину, которую нужно вернуть на плоскость.
Запускаем скрипт. В новом окне нажимаем кнопку "Make Planar".
Код:
rollout igorznag_make_planar "Make planar"
( 
button bnt_make_planar "Make planar"
on bnt_make_planar pressed do
(
if(selection.count==1)then
(
obj=selection[1].baseobject
if(classof obj==Editable_Poly)then
(
vs_ba=polyop.getVertSelection obj; vs_a=vs_ba as array
fs_ba=polyop.getFaceSelection obj; fs_a=fs_ba as array
if(vs_a.count==1 and fs_a.count==1)then
(
vuf_ba=polyop.getVertsUsingFace obj fs_ba;
if(vuf_ba.NumberSet==4 and (vuf_ba*vs_ba).NumberSet==1)then
(
ps=(vuf_ba-vs_ba) as array 
p1=polyop.getVert obj ps[1] node:selection[1];
p2=polyop.getVert obj ps[2] node:selection[1]; 
p3=polyop.getVert obj ps[3] node:selection[1]; 
v1 = normalize (p2 - p1)
v3 = normalize (cross v1 (normalize (p3 - p1)))
v2 = normalize (cross v3 v1); m=matrix3 v1 v2 v3 p1;
in coordsys m 
(
p=polyop.getVert obj vs_a[1] node:selection[1];
ct=obj.constrainType;obj.constrainType=0;
undo on 
(polyop.setVert obj vs_a[1] [p.x,p.y,0] node:selection[1])
obj.constrainType=ct;
)--in coordsys m 
)--if(vuf_ba.NumberSet==4 and (vuf_ba*vs_ba).NumberSet==1)then
)--if(va_a.count==1 and fs_a.count==1)then
)--if(classof $==Editable_Poly)then
)--if(selection.count==1)then
)--on bnt_make_planar pressed do
); createdialog igorznag_make_planar
Чтобы запустить скрипт нужно:
1. Создаем текстовый файл (NotePad) и копируем код (текст) скрипта.
2. Сохраняем текстовый файл с названием "test.ms"
3. В главное меню MaxScript выбираем пункт Run Script. Выбираем файл "test.ms"
 

=TARAS_=

Знаток
Рейтинг
32
#6
Можно так-берем вершину, задаем ей координаты любой другой вершины этого полигона. Выбираем локальную систему координат и двигаем эту вершину, все они будут в одной плоскости.
 
Рейтинг
22
#7
Хороший способ, но не всегда работает, в п.1 примитивная форма, а реальная модель часто будет
состоять из гораздо более сложных поверхностей. Хотя довольно часто решается именно так, перемещением
точек в локальной системе координат.
igorznag, скрипт проверял в своем MAX-е? У меня не работает.
 

igorznag

Мастер
Рейтинг
103
#8
igorznag, скрипт проверял в своем MAX-е? У меня не работает.
Да. Вы имеете в виду, что ничего не происходит после нажатия кнопки "Make planar"?
Скрипт работает только для базового объекта Editable Poly. Выделенная вершина, которую нужно вернуть на плоскость, должна принадлежать выделенному непланарному полигону.
 

maiden666

Мастер
Рейтинг
112
#9
добавлю угольку - иногда случается что обьект и его пивот ориентированы абсолютно случайным образом, и приходится много времени тратить на то чтобы выронять как тебе нужно, нашлась бы добрая душа и написала скриптик , чтобы можно было выбрать 2 точки и развернуть обьект так, чтобы они были парралельны данному виду ( если вы понимаете. что я имею в виду)
 

igorznag

Мастер
Рейтинг
103
#10
если вы понимаете. что я имею в виду
Объясните подробнее. Сделайте один пример вручную и предоставьте картинки.
Пример. Есть 2 объекта Box: Box01 и Box02.
Объект Box01 и его пивот ориентированы по мировым осям или по виду.
Объект Box02 и его пивот ориентированы абсолютно случайным образом.
Включаем привязку Vertex. Запускаем скрипт 3-Point-Align.
Выбираем 3 точки объекта Box02 и 3 точки объекта Box01.
 

maiden666

Мастер
Рейтинг
112
#11
наверное я слишком туп, так не понял, как работать с тем скриптом, ну да ладно, вот чего мне хочется - на обьекте выбраны 3 точки, которые, как известно. образуют плоскость, надо повернуть обьект так, чтобы эта плоскость была парралельна плоскости данного вида (топ\лефт..)
 

Вложения

igorznag

Мастер
Рейтинг
103
#12
Попробуйте такой вариант:
Выделяем 3 вершины базового объекта Editable Poly.
Запускаем скрипт. В новом окне нажимаем кнопку Align.
Если активирован вид Perspective, тогда нужно выбрать XY,YZ,ZX.
Код:
rollout igorznag_align_to_world "Align"
(
checkbox ckb_flip "Flip" pos:[5,5]
radiobuttons rb_view labels:#("XY", "YZ", "ZX") pos:[55,5]
button btn_align "Align" pos:[60,25]
on btn_align pressed do
(
if selection.count==1 then
(
obj=selection[1]; objbo=obj.baseobject
if(classof objbo==Editable_Poly)then
(
vs_ba=polyop.getVertSelection objbo;vs_a=vs_ba as array
if vs_a.count==3 then
(
p1=polyop.getVert objbo vs_a[1] node:obj
p2=polyop.getVert objbo vs_a[2] node:obj
p3=polyop.getVert objbo vs_a[3] node:obj
v1 = normalize (p2 - p1)
v3 = normalize (cross v1 (normalize (p3 - p1)))
v2 = normalize (cross v3 v1); mo=matrix3 v1 v2 v3 p1
mt=transmatrix p1;; vt=viewport.getType()
if(vt==#view_right or vt==#view_left)then mt=matrix3 [0,-1,0] [0,0,1] [-1,0,0] p1
if(vt==#view_front or vt==#view_back )then mt=matrix3 [1,0,0] [0,0,1] [0,-1,0] p1
views_a=#(#view_top,#view_bottom,#view_right,#view_left,#view_front,#view_back)
if(finditem views_a vt==0)then
(
if(rb_view.state==2)then mt=matrix3 [0,-1,0] [0,0,1] [-1,0,0] p1
if(rb_view.state==3)then mt=matrix3 [1,0,0] [0,0,1] [0,-1,0] p1
)--if(finditem views_a vt==0)then
obj_scale=1;if(ckb_flip.checked)then obj_scale=-1
undo on (obj.transform*=(inverse mo)*scaleMatrix[1,1,obj_scale]*mt)
redrawViews()
)--if vs_a.count==3 then
)--if(classof objbo==Editable_Poly)then
)--if selection.coutn==1 then
)--on btn_align pressed do
);createDialog igorznag_align_to_world 170 50
 

Сергей Попов 144982

Пользователь сайта
Рейтинг
2
#14
maiden666 У вас получилось повернуть обьект с помощью скрипта из поста 12?
Вот сижу пытаюсь сделать как написано, только ничего не получается. скрипт просто крутит объект, то не выравнивает ничего.
 

Сергей Попов 144982

Пользователь сайта
Рейтинг
2
#15
Еще 2 вопроса сюда же до кучи, чтобы не создавать новую тему.
1. Есть такой пример. См рисунок1. Можно ли как то в editable poly перетянуть верхнее ребро так, чтобы два других (которые ниже остались на одной линии. Сразу скажу что мне интересно, как делают другие и насколько быстрые методы есть для этого. Не интересует применение додификатора FFD и скрипта для выравнивания вершин между 2мя выбранными.
2.Есть такой пример. См рисунок2. Я заметил, что при использовании локальной системы координат крайние ребра с зажатым Shift выдавливаются не так как хотелось бы. т.е. это сделать можно, но нужно попробовать потянуть по всем 3 осям. Короче это трудно объяснить, но если попробуете, то поймете о чем я.

Большое спасибо за Ваши ответы.
 

Вложения

maiden666

Мастер
Рейтинг
112
#16
igorznaq, дико извиняюсь, сразу не заглянул сюда, скрипт прекрасно работает, спасибо!
 

igorznag

Мастер
Рейтинг
103
#17
Сергей Попов У вас получилось вернуть точку на плоскость с помощью скрипта из поста 5?
 
Рейтинг
22
#18
Сергей Попов, мне кажется ты занят решением каких-то абстрактных проблем, не имеющих
практического применения. По вопросу 1: зачем изобретать как оставить 2 средних ребра на
одной линии, если можно просто убрать их Chamfer-ом или точки слить с крайними с 3D-привязкой,
после чего перемещать свое верхнее ребро куда угодно. Если нужны после этого опять 2 средних ребра,
сделать их не проблема, Polygon - Cut все с той же активной 3D-привязкой.
Вопрос 2 перечитал раз десять, но все равно не понял в чем проблема.
 

igorznag

Мастер
Рейтинг
103
#19
Не интересует применение додификатора FFD и скрипта для выравнивания вершин между 2мя выбранными.
Почему вас не интересует применение додификатора FFD и скрипта для выравнивания вершин между 2мя выбранными?
Вы тратите много времени или результат вас не устраивает?
Я заметил, что при использовании локальной системы координат крайние ребра с зажатым Shift выдавливаются не так как хотелось бы.
Попробуйте такой вариант:
Выделяем открытое-крайнее ребро базового объекта Editable Poly.
Запускаем скрипт. В новом окне нажимаем кнопку Apply.
Удерживая клавишу Shift, выдавливаем ребро.
Кнопку Apply нужно нажимать каждый раз, когда выделяется открытое ребро.
Код:
rollout igorznag_open_edge_coord "Open Edge Coord" 
( 
button btn_apply "Apply"; on btn_apply pressed do
(  
undo off
(
if(selection.count==1)then
(
obj=selection[1].baseobject
if(classof obj==Editable_Poly)then
(
es_ba=polyop.getEdgeSelection obj
es_open_a=(es_ba*(polyOp.getOpenEdges obj)) as array
if(es_open_a.count>0)then
(
edge_index=es_open_a[1]
edge_faces=polyOp.getEdgeFaces obj edge_index
edge_verts=polyOp.getEdgeVerts obj edge_index
p1=polyop.getVert obj edge_verts[1] node:selection[1]
p2=polyop.getVert obj edge_verts[2] node:selection[1]
v2=normalize (p2-p1); c=(p1+p2)/2
v3=polyop.getFaceNormal obj edge_faces[1] node:selection[1]
fc=polyop.getFaceCenter obj edge_faces[1] node:selection[1]
v1=normalize (cross v3 v2)
fc_p1=normalize(fc-p1); if(dot fc_p1 v1 > 0)then v1=-v1
m=matrix3 v1 v2 v3 c
try delete $shift_plane_igorznag catch ()
sp=plane name:"shift_plane_igorznag" length:0 width:0 
sp.lengthsegs=1; sp.widthsegs=1;sp.transform=m
sp.renderable=off;freeze sp; hide sp; toolmode.coordsys sp
)--if(es_open_a.count>0)then
)--if(classof obj=Editable_Poly)then
)--if(selection.count==1)then
)--undo off
)--on btn_apply pressed do
); createDialog igorznag_open_edge_coord
 

Сергей Попов 144982

Пользователь сайта
Рейтинг
2
#20
Цитата Сергей Попов #15:Не интересует применение додификатора FFD и скрипта для выравнивания вершин между 2мя выбранными.
Почему вас не интересует применение додификатора FFD и скрипта для выравнивания вершин между 2мя выбранными?
Вы тратите много времени или результат вас не устраивает?
Цитата Сергей Попов #15:Я заметил, что при использовании локальной системы координат крайние ребра с зажатым Shift выдавливаются не так как хотелось бы.
Попробуйте такой вариант:
Выделяем открытое-крайнее ребро базового объекта Editable Poly.
Запускаем скрипт. В новом окне нажимаем кнопку Apply.
Удерживая клавишу Shift, выдавливаем ребро.
Кнопку Apply нужно нажимать каждый раз, когда выделяется открытое ребро.
rollout igorznag_open_edge_coord "Open Edge Coord"
(
button btn_apply "Apply"; on btn_apply pressed do
(
undo off
(
if(selection.count==1)then
(
obj=selection[1].baseobject
if(classof obj==Editable_Poly)then
(
es_ba=polyop.getEdgeSelection obj
es_open_a=(es_ba*(polyOp.getOpenEdges obj)) as array
if(es_open_a.count>0)then
(
edge_index=es_open_a[1]
edge_faces=polyOp.getEdgeFaces obj edge_index
edge_verts=polyOp.getEdgeVerts obj edge_index
p1=polyop.getVert obj edge_verts[1] node:selection[1]
p2=polyop.getVert obj edge_verts[2] node:selection[1]
v2=normalize (p2-p1); c=(p1+p2)/2
v3=polyop.getFaceNormal obj edge_faces[1] node:selection[1]
fc=polyop.getFaceCenter obj edge_faces[1] node:selection[1]
v1=normalize (cross v3 v2)
fc_p1=normalize(fc-p1); if(dot fc_p1 v1 > 0)then v1=-v1
m=matrix3 v1 v2 v3 c
try delete $shift_plane_igorznag catch ()
sp=plane name:"shift_plane_igorznag" length:0 width:0
sp.lengthsegs=1; sp.widthsegs=1;sp.transform=m
sp.renderable=off;freeze sp; hide sp; toolmode.coordsys sp
)--if(es_open_a.count>0)then
)--if(classof obj=Editable_Poly)then
)--if(selection.count==1)then
)--undo off
)--on btn_apply pressed do
); createDialog igorznag_open_edge_coord
По поводу того, почему не пользоваться модификатором. Да , мне кажется, что тратится много времени, когда делаю модельку, очень отвлекает выделять и накладывать сверху модификатор, а потом опять жать convert to editable poly. Я просто исхожу из того, что возможно кто-то знает альтернативный путь решения стандартными средствами макса и не выходя за рамки функционала editable poly. Кстати за скрипт отдельное спасибо. А можно немного теории по поводу этого скрипта, хотелось бы узнать что он делает. И почему без него работает именно так, как оно работает. В скриптах я не разбираюсь совсем.
 
Сверху