Всем доброго времени. Давно мучает один вопрос и никак не могу на него найти ответа, надеюсь что здесь мне помогут. В общем есть такая ситуация (см. картинку). Editable poly. Полигон перестает быть планарным. т.е. одна из точек уходит с плоскости, на которой остаются 3 других вершины. Можно ли как-то вернуть точку на плоскость? Сразу скажу, что либо я не понял всю мощь функции make planar, либо ей нельзя сделать полигон планарным переместив только одну из точек.
Заранее спасибо за ответы
СеленаВ этом конкретном случае просто переместить с активной 2,5D привязкой на виде сбоку.[/quo[quote=Селена [url=/forum/viewtopic.php?post_id=1053559#1053559]#2]В этом конкретном случае просто переместить с активной 2,5D привязкой на виде сбоку.
Ну тут-то всё и дело, что мне нужно для общего случая. Вот нарисовал общий случай. Модель относительно координат повернута на произвольный угол. В любом случае спасибо Вам за ответ.
Сергей Попов, мое мнение не истина в последней инстанции конечно, но по моему не бывает
никаких "общих случаев". Это все равно универсальный рецепт, который врач выпишет всем
больным, не вникая, чем они болеют.
В общем я могу сказать, что работал и работаю в разных 3D-пакетах и считаю, что в MAX-е
самая совершенная и интуитивно понятная система привязок, изучи досконально и используй ее.
В сочетании со вспомогательной геометрией твоя проблема решаема в 100% случаев.
Если нужно на примере, то давай конкретную модель и конкретную проблему.
Сергей ПоповМожно ли как-то вернуть точку на плоскость?
Попробуйте такой вариант:
Выделяем один непланарный полигон, который состоит из 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"
Можно так-берем вершину, задаем ей координаты любой другой вершины этого полигона. Выбираем локальную систему координат и двигаем эту вершину, все они будут в одной плоскости.
Хороший способ, но не всегда работает, в п.1 примитивная форма, а реальная модель часто будет
состоять из гораздо более сложных поверхностей. Хотя довольно часто решается именно так, перемещением
точек в локальной системе координат.
igorznag, скрипт проверял в своем MAX-е? У меня не работает.
Селенаigorznag, скрипт проверял в своем MAX-е? У меня не работает.
Да. Вы имеете в виду, что ничего не происходит после нажатия кнопки "Make planar"?
Скрипт работает только для базового объекта Editable Poly. Выделенная вершина, которую нужно вернуть на плоскость, должна принадлежать выделенному непланарному полигону.
добавлю угольку - иногда случается что обьект и его пивот ориентированы абсолютно случайным образом, и приходится много времени тратить на то чтобы выронять как тебе нужно, нашлась бы добрая душа и написала скриптик , чтобы можно было выбрать 2 точки и развернуть обьект так, чтобы они были парралельны данному виду ( если вы понимаете. что я имею в виду)
Объясните подробнее. Сделайте один пример вручную и предоставьте картинки.
Пример. Есть 2 объекта Box: Box01 и Box02.
Объект Box01 и его пивот ориентированы по мировым осям или по виду.
Объект Box02 и его пивот ориентированы абсолютно случайным образом.
Включаем привязку Vertex. Запускаем скрипт 3-Point-Align.
Выбираем 3 точки объекта Box02 и 3 точки объекта Box01.
наверное я слишком туп, так не понял, как работать с тем скриптом, ну да ладно, вот чего мне хочется - на обьекте выбраны 3 точки, которые, как известно. образуют плоскость, надо повернуть обьект так, чтобы эта плоскость была парралельна плоскости данного вида (топ\лефт..)
Попробуйте такой вариант:
Выделяем 3 вершины базового объекта Editable Poly.
Запускаем скрипт. В новом окне нажимаем кнопку Align.
Если активирован вид Perspective, тогда нужно выбрать XY,YZ,ZX.
Еще 2 вопроса сюда же до кучи, чтобы не создавать новую тему.
1. Есть такой пример. См рисунок1. Можно ли как то в editable poly перетянуть верхнее ребро так, чтобы два других (которые ниже остались на одной линии. Сразу скажу что мне интересно, как делают другие и насколько быстрые методы есть для этого. Не интересует применение додификатора FFD и скрипта для выравнивания вершин между 2мя выбранными.
2.Есть такой пример. См рисунок2. Я заметил, что при использовании локальной системы координат крайние ребра с зажатым Shift выдавливаются не так как хотелось бы. т.е. это сделать можно, но нужно попробовать потянуть по всем 3 осям. Короче это трудно объяснить, но если попробуете, то поймете о чем я.
Сергей Попов, мне кажется ты занят решением каких-то абстрактных проблем, не имеющих
практического применения. По вопросу 1: зачем изобретать как оставить 2 средних ребра на
одной линии, если можно просто убрать их Chamfer-ом или точки слить с крайними с 3D-привязкой,
после чего перемещать свое верхнее ребро куда угодно. Если нужны после этого опять 2 средних ребра,
сделать их не проблема, Polygon - Cut все с той же активной 3D-привязкой.
Вопрос 2 перечитал раз десять, но все равно не понял в чем проблема.
Сергей ПоповНе интересует применение додификатора FFD и скрипта для выравнивания вершин между 2мя выбранными.
Почему вас не интересует применение додификатора FFD и скрипта для выравнивания вершин между 2мя выбранными?
Вы тратите много времени или результат вас не устраивает?
Сергей ПоповЯ заметил, что при использовании локальной системы координат крайние ребра с зажатым Shift выдавливаются не так как хотелось бы.
Попробуйте такой вариант:
Выделяем открытое-крайнее ребро базового объекта Editable Poly.
Запускаем скрипт. В новом окне нажимаем кнопку Apply.
Удерживая клавишу Shift, выдавливаем ребро.
Кнопку Apply нужно нажимать каждый раз, когда выделяется открытое ребро.
igorznagЦитата Сергей Попов #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. Кстати за скрипт отдельное спасибо. А можно немного теории по поводу этого скрипта, хотелось бы узнать что он делает. И почему без него работает именно так, как оно работает. В скриптах я не разбираюсь совсем.
Доступ к резюме доступен только по пакетному доступу HR менеджерам зарегистрированных компаний. Узнать о вариантах корпоративных пакетов можно по ссылке.
Сергей Попов
Заранее спасибо за ответы
Вложения
Селена
Вложения
Сергей Попов
Вложения
Селена
никаких "общих случаев". Это все равно универсальный рецепт, который врач выпишет всем
больным, не вникая, чем они болеют.
В общем я могу сказать, что работал и работаю в разных 3D-пакетах и считаю, что в MAX-е
самая совершенная и интуитивно понятная система привязок, изучи досконально и используй ее.
В сочетании со вспомогательной геометрией твоя проблема решаема в 100% случаев.
Если нужно на примере, то давай конкретную модель и конкретную проблему.
igorznag
Выделяем один непланарный полигон, который состоит из 4 вершин.
Выделяем одну вершину, которую нужно вернуть на плоскость.
Запускаем скрипт. В новом окне нажимаем кнопку "Make Planar".
Чтобы запустить скрипт нужно:
1. Создаем текстовый файл (NotePad) и копируем код (текст) скрипта.
2. Сохраняем текстовый файл с названием "test.ms"
3. В главное меню MaxScript выбираем пункт Run Script. Выбираем файл "test.ms"
=TARAS_=
Селена
состоять из гораздо более сложных поверхностей. Хотя довольно часто решается именно так, перемещением
точек в локальной системе координат.
igorznag, скрипт проверял в своем MAX-е? У меня не работает.
igorznag
Скрипт работает только для базового объекта Editable Poly. Выделенная вершина, которую нужно вернуть на плоскость, должна принадлежать выделенному непланарному полигону.
вадим соболев (maiden666)
igorznag
Пример. Есть 2 объекта Box: Box01 и Box02.
Объект Box01 и его пивот ориентированы по мировым осям или по виду.
Объект Box02 и его пивот ориентированы абсолютно случайным образом.
Включаем привязку Vertex. Запускаем скрипт 3-Point-Align.
Выбираем 3 точки объекта Box02 и 3 точки объекта Box01.
вадим соболев (maiden666)
Вложения
igorznag
Выделяем 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 50igorznag
Сергей Попов
Сергей Попов
1. Есть такой пример. См рисунок1. Можно ли как то в editable poly перетянуть верхнее ребро так, чтобы два других (которые ниже остались на одной линии. Сразу скажу что мне интересно, как делают другие и насколько быстрые методы есть для этого. Не интересует применение додификатора FFD и скрипта для выравнивания вершин между 2мя выбранными.
2.Есть такой пример. См рисунок2. Я заметил, что при использовании локальной системы координат крайние ребра с зажатым Shift выдавливаются не так как хотелось бы. т.е. это сделать можно, но нужно попробовать потянуть по всем 3 осям. Короче это трудно объяснить, но если попробуете, то поймете о чем я.
Большое спасибо за Ваши ответы.
Вложения
вадим соболев (maiden666)
igorznag
Селена
практического применения. По вопросу 1: зачем изобретать как оставить 2 средних ребра на
одной линии, если можно просто убрать их Chamfer-ом или точки слить с крайними с 3D-привязкой,
после чего перемещать свое верхнее ребро куда угодно. Если нужны после этого опять 2 средних ребра,
сделать их не проблема, Polygon - Cut все с той же активной 3D-привязкой.
Вопрос 2 перечитал раз десять, но все равно не понял в чем проблема.
igorznag
Вы тратите много времени или результат вас не устраивает?
Попробуйте такой вариант:
Выделяем открытое-крайнее ребро базового объекта Editable Poly.
Запускаем скрипт. В новом окне нажимаем кнопку Apply.
Удерживая клавишу Shift, выдавливаем ребро.
Кнопку Apply нужно нажимать каждый раз, когда выделяется открытое ребро.
Сергей Попов