Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Я только начинаю изучать Maxscript
Форум .:3DCenter.ru:. > Пакеты 3D моделирования > 3ds Max > Maxscript
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24
C00PER
Раз уж появилась традиция создавать такие темы, создадим её и тут, а то всякие шарики да стекляшки уже заезжены до дыр, а столь важный аспект Макса, как Скриптинг, особого интереса у населения не вызывает. Надо это упущение исправлять dry.gif

Вообщем, предлагаю здесь высказыать различные идеи, бредовые и не очень, а также методы их реализации. Новичкоф не обижать! RTFM - тоже дело нелёгкое и не сразу всем даётся tongue.gif

Ну и для начала выложу своё сегодняшнее творение - творение, которое появилось на свет после нескольких лет повторения одной и той же процедуры. Обычная ситуация - нам надо простому плоскому объекту назначить материал с текстурой. После создания материала и выбора битмапки, нам надо, чтобы текстура легла в соответствии со своими пропорциями, а не растягивалась по размеру объекта. Для этого, мы идём в UVW Map, и там жмём Bitmap Fit, там открывается окно выбора файла, там мы ищем этот файл, и хорошо если мы в редакторе материалов, при выборе битмапки воспользовались максовской листалкой, тогда она битмапка сразу видна в окне Bitmap Fit, а если мы битмапку закинули драг-н-дропом, например из ACDSee, то листать придётся с чёрт знает какого места. Вощем целая история. Ну вот, этот скрипт ставит большую и жирную точку в этом занятии, он автоматически ставит размер гизмы равный размеру битмапки. Всё бы замечательно, но мне хотелось бы добавить ещё одну функцию - чтобы он анализировал, по какой из осей объект шире всего, и применял UVWMap на эту ось. Я хотел считать размеры объекта командами $.min и $.max, но столкнулся с каким-то непредсказуемым поведением - они как-то странно ведут себя в локальных коорднатах (или я чего проглядел): по идее in coordsys local $.min должен показывать минимальное значение боундинг бокса, независимо от угла наклона объекта, однако стоит только чуть повернуть объект, как он выдаёт какие-то немыслимые значения.

Вот и скрипт. Самое разумное ему место - в менюхе Utilities в Редакторе материалов wink.gif
C00PER
Сделал проверку габаритов. cool.gif Теперь плоскость гизмы параллельна оси самого большого габарита объекта, но стандартными средствами макса мне сделать это не удалось, поэтому нужны Avguard Extensions
Desead
Тема интересная, но глядя на подобные форумы понимаешь, что максскрипт мало кого интересует по разным соображениям ,а жаль, можно значительно упростить себе жизнь. Вообщем развивать тему надо. Рано или поздно допишу скрипт который ищет нужный битмап по всем материалам, и ещё умеет искать объект с нужным ID, если кого заинтересует то выкину, говорите. Нужно конечно это гейм девелоперам в первую очередь
DIA-Doca
По-моему гей мекерам в первую очередь нужны скрипты, переводящие модели и анимации во внешние, открытые файлы.
Именно этим я щаз и занимаюсь.

Нас тут четверо собралось, игру делать будем. Вот я и взялся за это дело.
Desead
QUOTE(DIA-Doca @ Jun 25 2004, 18:23)
По-моему гей мекерам в первую очередь нужны скрипты, переводящие модели и анимации во внешние, открытые файлы.
Именно этим я щаз и занимаюсь.

Нас тут четверо собралось, игру делать будем. Вот я и взялся за это дело.

это тоже надо, но это самая первая и очевидная проблема, а в период работы их ещё гора возникнет
Desead
а кто-нить знает как скриптом нажать утилитку reset xform, я так понял можно воспользоваться $.transform но вот пока не понял как
или я всё таки не туда двигаюсь ?
C00PER
Desead, вот тебе улучшенный ResetXform, который сохраняет информацию о вращении, то бишь обнуляет только масштаб.

http://scriptspot.com/download.asp?ID=1937

Или просто напиши ResetXForm $ , но это только для макса 6

А у меня появился ламерский вопрос: Как можно назначить одному Эррею в качестве цвета другой Эррей.
Например у меня есть:

CODE
sel = selection as array
col = for s in sel collect s.wirecolor


затем я например всем объектам назначаю один общий цвет, а потом мне надо для каждого объекта, находящегося в Эррее Sel назначить его исходный цвет, который лежит в Эррее Col

Вот что находится в первом Эррее:
CODE
#($Teapot:Teapot02 @ [15.607554,34.097706,0.000000], $Teapot:Teapot03 @ [-26.646317,-26.881655,0.000000], $Teapot:Teapot01 @ [-55.240364,7.516488,0.000000])


Вот что во втором:
CODE
#((color 223 189 154), (color 27 33 248), (color 4 230 216))


Как второе назначить первому ну никак не могу въехать smile.gif Пожалуйста не оставляйте без внимания сей пост, ибо в качестве благодарности вы получите довольно забавный скрипт
rolleyes.gif
Desead
to COOPER: благодарю за помощь, вечером погляжу как там с цветом обстоят дела, чего если получится, то напишу
C00PER
Ещё вопрос, совсем простенький lamer.gif
Есть две Point3... Как из них получить Matrix3? Пдразумевается что Scale будет равным 1 unsure.gif

edit: Свою ошибку понял, конечно сморозил полную херню, нужна ещё одна Point3. Будем копать дальше..
pepper
QUOTE
для каждого объекта, находящегося в Эррее Sel назначить его исходный цвет, который лежит в Эррее Col
.........
Как второе назначить первому ну никак не могу въехать

Сам ответил на свой вопрос и не заметил: rolleyes.gif

for j=1 to col.count do sel[j].wirecolor=col[j]

ЗЫ:Моделил дом для игрушки и в результате чего я тоже написал пару скриптиков по UVW mapping'y.Есть: применение для каждого полигона одного UVW, перестановка(обмен) 2-х UVW координат (с 2-х полигонов)...были еще идеи только сейчас не вспомню...
DIA-Doca
QUOTE(pepper @ Jun 28 2004, 23:45)
ЗЫ:Моделил дом для игрушки и в результате чего я тоже написал пару скриптиков по UVW mapping'y.

О, так мы коллеги? Тоже гейм мекер?
Так вот почему ты UVW мэппингу так помог быстро?! Кстате спасибо ещё раз!
Shiva
У меня другая идея...
Как насчет продолжить доброе дело мешьтулз??
У меня есть идеи инструменов, которых мне не хватает...
например все наверно знаете Grow и Shrink?!
И наверно знаете Ring и Loop?!
так вот.. очень часто мне надо Совмещенная команда.. т.е. чтобы Ring не окутывал кольцем всю модель а выделял лишь ближайшие 2е грани...
Смогете?..
а то у меня всейчас времени нету разбираться и вспоминать максскрипт..
Desead
to COOPER: ну вот, тебе уже ответили, а я ещё даже не посмотрел :-)

по поводу выделений loop тоже вопрос у меня есть. Кто нибудь занет сам алгоритм по которому происходит выделение, на глаз понятно что там последовательные рёбра. Есть некоторые мысли но чтобы не изобретать с нуля велосипед, лучше его апгрейдить так сказать.

to Shiva: а мештулз автор больше не изменяет ??? я как то не задавался просто этим вопросом. Я давно пытался поглядеть алгоритм с помощью которого он реализует свои функции, но либо мне в тот момент знаний скрипта не хватало, либо моего образования, вообщем я понял только поверхностно. И с твоим выделением тоже разберёмся :-) мне 2 дня осталось до сдачи этапа, и постараюсь тебе помочь, если никто другой не опередит конечно.
C00PER
QUOTE
Сам ответил на свой вопрос и не заметил:

Дык, ламер-с rolleyes.gif Спасибо! Ура! Работает! Ждите прикольную феньку cool.gif

QUOTE
У меня есть идеи инструменов, которых мне не хватает...
например все наверно знаете Grow и Shrink?!
И наверно знаете Ring и Loop?!
так вот.. очень часто мне надо Совмещенная команда.. т.е. чтобы Ring не окутывал кольцем всю модель а выделял лишь ближайшие 2е грани...

Хехе, мне тоже этого нехватает dry.gif

QUOTE
Я давно пытался поглядеть алгоритм с помощью которого он реализует свои функции, но либо мне в тот момент знаний скрипта не хватало, либо моего образования, вообщем я понял только поверхностно. И с твоим выделением тоже разберёмся

да, самый лучший выход это попытаться разобраться в готовом скрипте, как я и делаю tongue.gif
C00PER
А можно-ли каким-нибудь образом сохранить материалы нескольких объектов для того чтобы назначить их им же в дальнейшем? Ну наподобие вот того примера с цветами.
C00PER
Что за фигня? Или где я туплю?

Пишу функцию, которая бы реагировала на смену выделения на уровне подобъекта. Пользуюсь Change Handler'ом. Функция:
CODE

when select $.Poly_Select change handleAt:#redrawViews do print "shit"

Получаем, что когда к объекту применён модификатор Poly_Select, и в нём меняется выделение, пишется текст. Вроде всё работает.

Но когда вместо print "shit" я пишу getfaceselection $ $.Poly_Select, то почему то не работает! Хотя если эту функцию просто ввести в командной строке, то всё нормально, а вот на смену выделения никак не хочет цепляться, и главное - даже не выдаёт никакой ошибки, просто ничего не происходит...
Desead
QUOTE(Shiva @ Jun 29 2004, 10:46)
У меня другая идея...
Как насчет продолжить доброе дело мешьтулз??
У меня есть идеи инструменов, которых мне не хватает...
например все наверно знаете Grow и Shrink?!
И наверно знаете Ring и Loop?!
так вот.. очень часто мне надо Совмещенная команда.. т.е. чтобы Ring не окутывал кольцем всю модель а выделял лишь ближайшие 2е грани...
Смогете?..
а то у меня всейчас времени нету разбираться и вспоминать максскрипт..

вообщем скрипт вот, размещаю и файлом и в теле, чтоб если у кого вопрос возникнет, не спрашивал, а что ты сделал в 17 строчке :-), а более конкретно

------------------------------------------
macroScript Ring_2
category:"D_script"
toolTip:""
(
if (selection.count==1) and
(classof $ == editable_poly) and
(subobjectlevel==2) then
(--1
edge_s = polyop.getedgeselection $
final_edge=edge_s
i_end = (edge_s as array).count
for i=1 to i_end do
(--2
temp=polyop.getfacesusingedge $ (finditem edge_s (edge_s as array)[i])
vert1=(polyop.getvertsusingedge $ (finditem edge_s (edge_s as array)[i])) as array
temp=(polyop.getedgesusingface $ temp) - edge_s
y_end=(temp as array).count
for y=1 to y_end do
(--3
vert2=(polyop.getvertsusingedge $ (finditem temp (temp as array)[y])) as array

if (vert2[1] != vert1[1]) and
(vert2[1] != vert1[2]) and
(vert2[2] != vert1[1]) and
(vert2[2] != vert1[2]) then
(--4
new_edge=polyop.setedgeselection $ (finditem temp (temp as array)[y])
new_edge=getedgeselection $
final_edge=final_edge+new_edge
)--4
)--3
)--2
polyop.setedgeselection $ final_edge
update $
)--1

)
------------------------------------------
ставить его так - копируем в папочку Х:\3dsmax6\UI\MacroScripts\
после этого он появиться, при перезагрузке макса, в настройке хоткеев, квад меню, это уж куда тебе удобнее, можно и в бар вынести. Вопросы лучше здесь, но можно и в асю.

Пока писал столько идей о возможных выделениях в голову пришло !!!, если когда-нибудь всё-таки напишу модификатор edit_poly, то объязательно всё это туда вставлю, хотя лениво....жуть как :-)))

ps. кстати про выделять 2 соседних ребра, а само выделение считается ? я исходил из того что считается, то есть выделяется получается один ринг вокруг
...ну ежели не точно понял, то могу дополнить. Обратил внимание только что на это условие просто :-)
Desead
QUOTE(C00PER @ Jun 30 2004, 12:36)
А можно-ли каким-нибудь образом сохранить материалы нескольких объектов для того чтобы назначить их им же в дальнейшем? Ну наподобие вот того примера с цветами.

берёш нужный материал, создаешь библиотеку материалов, и добавляеш туда нужный, ну а уж с библиотекой проблем не будет, только обрати внимание что ещё можно создавать виртуальную бибилиотеку, то есть в неё и из неё ты сможешь материал добавить/взять, но сохранить её не сможешь, то есть это для работы в одном сеансе.
C00PER
спасиб, я уже понял что материалы - это дохлый номер. тогда остаётся только Vertex Colors..
C00PER
Ого! Круто! Работает smile.gif Но ринг это хорошо, а вот если бы ещё в ширину росло (луп) это былоб вообще замечательно!
Кстати модификатор Едит Поли наконец-то БУДЕТ в 7 максе wink.gif
pepper
QUOTE
так вот.. очень часто мне надо Совмещенная команда.. т.е. чтобы Ring не окутывал кольцем всю модель а выделял лишь ближайшие 2е грани...

Вот мой скриптик:

ind1=polyop.getedgeselection $ as array
$.SelectEdgeRing()
ind_a=polyop.getedgeselection $ as array

polyop.setedgeselection $ ind1

$.EditablePoly.ConvertSelection subobjectLevel #Face
subobjectLevel = 4
$.EditablePoly.ConvertSelection subobjectLevel #Edge
subobjectLevel = 2

zz=polyop.getedgeselection $ as array
sel_ar=#()

i=1
for i=1 to ind_a.count do
(
for j=1 to zz.count do
(
if zz[j]==ind_a[i] then append sel_ar zz[j]
)
)
polyop.setedgeselection $ sel_ar
update $
C00PER
о, мастера, помогите тёмному! как заставить макс реагировать на выделение на уровне подобъекта! например при выделении фейса выполнять команду!

попробую поковырять PainterInterface rolleyes.gif
Desead
to pepper
QUOTE(pepper @ Jun 30 2004, 22:51)
QUOTE
так вот.. очень часто мне надо Совмещенная команда.. т.е. чтобы Ring не окутывал кольцем всю модель а выделял лишь ближайшие 2е грани...

Вот мой скриптик:

попроще у тебя скрипт будет, чё то наверное я намудрил у себя, надо твой попробовать :-)

в двух словах об используемом алгоритме можно ?
тоже изначально пробовал реализовать через стандартный Shrink, но при крестообразном выделении работало некорректно, пришлось напрямую всё прописывать.
я смотрю ты вообще не стал использовать bitarray, а мне пришлось конвертить то его в аррэй, то интеджер в битаррэй, намучился с этим.

QUOTE
о, мастера, помогите тёмному! как заставить макс реагировать на выделение на уровне подобъекта! например при выделении фейса выполнять команду!

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

QUOTE
Ого! Круто! Работает  Но ринг это хорошо, а вот если бы ещё в ширину росло (луп) это былоб вообще замечательно!
Кстати модификатор Едит Поли наконец-то БУДЕТ в 7 максе


ээээ..поподробней тогда, а то не понял, то есть нужен такой же вариант, то есть на выделение только двух соседних рёбер, но лооп, так ?

ну всё, если поли наконец то будет в 7 максе, то теперь я себя уж точно не заставлю сесть за его написание :-)


QUOTE
спасиб, я уже понял что материалы - это дохлый номер. тогда остаётся только Vertex Colors.


ну почему, в принципе там всё понятно, только вот доступ есть не ко всем функциям, допустим простецкая вроде кнопочка - Put material to scene, а через скрипт этого не так просто реализовать, прямой функции нет.
C00PER
Ура! У меня получилось!!!! Я сделал ПОЛИГОНАЛЬНУЮ СИСТЕМУ КООРДИНАТ! Причем, независимую от класса объекта - будь то Меш, Поли, Примитив и даже Нурбс. При старте она запросит сначала выделить объет, а затем выделить на нём Полигон. И всё! готова новая система координат smile.gif Ну и намучался же я с этим Painterinterface smile.gif На данный момент, это самое сложное из всего что я сделал за время изучения Максскрипта, а изучаю я его меньше недели rolleyes.gif

Вот сие творение, прошу любить и жаловать, а также не возмущаться в случае багов, а докладывать сюда

http://alexcooper.nm.ru/stuff/Cooper-PolyC...inateSystem.zip

Апдейт - теперь, после создания системы координат, возвращает на тот уровень выделения, на котором был до начала функции cool.gif
111
ну вы ребяты монcтры просто какие то. я тоже скриптом балуюсь помаленьку, по надобности...

кстати, объясните алгоритм Loop select и ring select
Desead
to pepper: посмотрел скрипт, всё просто и понятно, и чего спрашивается я не стал использовать готовое решение - ring, а написал его заново, не понятно.
кстати здесь :
$.EditablePoly.ConvertSelection subobjectLevel #Face
subobjectLevel = 4
$.EditablePoly.ConvertSelection subobjectLevel #Edge
subobjectLevel = 2
можно было и не ходить по уровням, убрать их вообще и во второй строчке написать $.EditablePoly.ConvertSelection #face #Edge
ну это я так, мысли вслух :-)))

QUOTE
ну вы ребяты монcтры просто какие то. я тоже скриптом балуюсь помаленьку, по надобности...
кстати, объясните алгоритм Loop select и ring select


я ринг реализовал так:
текущее выделение рёбер преобразовал в фейсы а их опять в рёбра,
получился контур рёбер вокруг выделения. Этот контур и начальное выделение пораздельности преобразовал в вертексы ,т.е. каждому ребру соответствовало 2 вершины, и вот их то и сравнивал. Если одна из вершин первого ребра совпадает с любой из вершин начального выделенного ребра, значит первое ребро нам не подходит, иначе - оно нужное, и.т.д, перебирая все рёбра и сравнивая вершины с начальным выделением. правда есть маленькое отличие от стандартного ринга, при работе с фейсам имеющими 5 и более рёбер ,стандартный ринг ничего не выделяет, а этот алгоритм выделит те рёбра которые не соприкасаються с выделенным, но это скорее расширение чем недостаток, т.к. можно сделать просто ещё одно условие работы скрипта- если у фейса более 4 ребёр то я вообще не работаю - т.е. будет стандартный ринг :-)

а с лупом тоже самое думаю, только выбираешь рёбра по совпадающим вершинам , а не по разным, и то же самое изменение от стандартного лупа будет.
ну вот собственно и всё :-)))
pepper
QUOTE
$.EditablePoly.ConvertSelection #face #Edge

буду знать. спасибо.

мой ринг похож на ринг Desead'а: я тоже брал выделенный(е) едж конвертил в полигон затем в эдж. Полученные еджи сравнивал с еджами, полученными через ринг первоначально выделенного(ых) эджей.

с лупом(мой вариант):выделенному еджу делаем Grow и сравниваем полученные еджи с еджеми полученными от лупа.
Desead
тут поступило предложение дополнить всё это дело ещё и лупом, и подобным шринком...забацаем ! :-)

to pepper:
дальше буду делать как ты, через стандартные средства, так меньше работы получается :-)
pepper
QUOTE
тут поступило предложение дополнить всё это дело ещё и лупом, и подобным шринком...забацаем ! :-)


вот луп:

ind1=polyop.getedgeselection $ as array
$.SelectEdgeLoop()
ind_a=polyop.getedgeselection $ as array

polyop.setedgeselection $ ind1
$.EditablePoly.growselection()
zz=polyop.getedgeselection $ as array
sel_ar=#()

i=1
for i=1 to ind_a.count do
(
for j=1 to zz.count do
(
if zz[j]==ind_a[i] then append sel_ar zz[j]
)
)
polyop.setedgeselection $ sel_ar

update $

QUOTE
дальше буду делать как ты, через стандартные средства, так меньше работы получается :-)


Ну и зря. Простой вариант не всегда лучше сложного. Мой алгоритм переберает все эджи полученные от ринга или лупа, т.е. чем больше плотность сетки, тем дольше будет происходить сравнение. В твоем алгоритме сравнивается фиксированное число точек и число сравнений не зависит от сложности сетки модели, что и сказывается(положительно) на производительности wink.gif
C00PER
здорово! приятно видеть мастеров за работой %) уже добавил оба скрипта в набор полезных тулзов. Pepper, вставь в начало кода disablesceneredraw() а перед update $ enablesceneredraw()
Desead
луп я уже смотрю готов, эх неуспел я, ну да это и хорошо, остался подобный шринк сделать.
QUOTE
Ну и зря. Простой вариант не всегда лучше сложного. Мой алгоритм переберает все эджи полученные от ринга или лупа, т.е. чем больше плотность сетки, тем дольше будет происходить сравнение. В твоем алгоритме сравнивается фиксированное число точек и число сравнений не зависит от сложности сетки модели, что и сказывается(положительно) на производительности

согласен, но думаю современные машины с выделением рёбер справяться без проблем вне зависимости от тяжести модели...хотя это было бы неплохо проверить, мало ли какой будет результат :-)))
Shiva
pepper и Desead - молодцы! yes.gif
Только хорошо бы все скрипты доводить до полезной завершенности.
Loop я так понял тоже работет только в одну сторону?!..
Давайте все таки соберем этот набор из Selection Tool в нечто полноценное и отдадим народу в пользование. )
Сам с удовольствием буду пользоваться. laugh.gif
я это вижу как 4е инструмента - 4е иконки на тулзбаре..
иконки могу нарисовать..
1) Grow Ring
2) Shrink Ring
3) Grow Loop
4) Shrink Loop
Но не забывайте, это инструмет, а инструмент должен быть быстрым и надежным!
Если он будет тормозить работу или глючить - толку тогда от него?..
Вспоминаю (да именно вспоминаю) CleanCut... замечательный удобный инструмент... если бы не вылетал раз в 5 минут!! mad.gif
Eraser
Странно что у тебя с клинкатом проблемы - у меня все путем, не знаю даже как без него сейчас было бы smile.gif
pepper
QUOTE
Loop я так понял тоже работет только в одну сторону?!..

Что значит "тоже" и в одну сторону?
Все работает как и просили: выделяется по 2 эджа смежных с выделенными эджами.

QUOTE
1) Grow Ring
2) Shrink Ring
3) Grow Loop
4) Shrink Loop

А что каждый должен выполнять?
C00PER
имеется ввиду что неплохо бы иметь возможность как увеличивать выделение, так и уменьшать его
Shiva
Именнно! )
каждый из них должен выполнять свою аналогию..
1) Grow Ring - выделение увеличиваеться по кольцу <IIII>
2) Shrink Ring - выделение уменьшаеться по кольцу >IIII<
3) Увеличиваетьяс по "Смежным"??? <---->
4) уменьшаетсья по смежным. >----<
Desead
QUOTE(Shiva @ Jul 5 2004, 23:05)
Именнно! )
каждый из них должен выполнять свою аналогию..
1) Grow Ring - выделение увеличиваеться по кольцу   <IIII>
2) Shrink Ring  - выделение уменьшаеться по кольцу   >IIII<
3) Увеличиваетьяс по "Смежным"???   <---->
4) уменьшаетсья по смежным.  >----<

я вроде наконец то понял как должен работат shrink ring и shrink loop, на выходных если получиться со временем то попробую написать :-)))
pepper
А я вроде уже сделал. cool.gif tongue.gif
С шринк лупом проблем почти нет.
А вот шринк ринг не работает только если веделенны ВСЕ грани рига(от одного края объекта до другого).....короче, тестим!
Если всё устроит, то заверну все скрипты, чтобы можно было хоткеи назначить
Desead
2 pepper: ...качаем, тестим, щас чё нить скажу :-)))

слегка глянул, при не 4 угольных полигонах работает loop странно, остальное пока не глядел :-)
Desead
пока не забыл, есть пару вопросов к общественности интересующейся скриптами :

1. на discreet есть документ - maxscript referense version four от января 2001 г, кто-нить встречал версию поновее ?

2. кто-нить знает насколько аккуратно скрипт работает с оперативной памятью, а то возникает ощущение что он всё очень сильно засоряет и за собой не убирает

3. кто-нить делал аналог майковского append polygon- а то строить полигоны по вертексам достало, по рёбрам быстрее.

4. в unwrap есть 2 очень полезные тулзы - stitch selected и pack uvs, но как и многое в максе до ума не доведённые. Кто нибудь их переделывал ? а то мне сейчас предстоит это делать. Проблема в следующем: при упаковке остаётся много свободного места, наверняка можно использовать более продуктивный алгоритм сортировки, а при склеивании(stitch) макс масштабирует только ребро, а не весь элемент - но ведь это же глупо, намного быстрей можно было раскладывать всё при наличии нормального ститча.

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

уххх... ну вроде всё, надеюсь хоть кто-то с чем-нить сталивался
111
ага, посмотрим как вы shrink победите smile.gif
Desead
2 pepper: вообщем просидел я с твоим шринком 2 дня, ничего не понял как ты пытался его реализовать, понял только что ищешь бордюры, и их удаляешь, что происходит дальше, то есть для чего ты сравниваешь одни и теже фейсы в циклах while я не понял. Если оттолкнуться от того что в обычном массиве номера фэйсов будут повторяться, то это можно как-то использовать и кроме определения бордюра, что наверное ты и старался сделать, вообщем если ты объяснишь суть вот этого кусочка, то был бы рад. И кстати на мой взгляд просто удалять бордюр нельзя не ссылаясь на соседние рёбра, так можно и лишнего наубирать, но это уже зависит от того как мы понимаем алгоритм работы шринка.

а вот и непонятный кусочек:

i=1
while i<=pa.count-1 do
(
j=i+1
b=0
clearlistener()
format "i=% j=% b=%\n" i j b
while j<=pa.count do
( ----- while 2
if pa[i]==pa[j] then
(
deleteItem pa j

b=1
j-=1 --cause we deleting 1 element
)
j+=1
) ----- end while 2
if b==1 then
(
deleteItem pa i
i-=1
)
i+=1
)

и ещё чуть не забыл, если выделено всё, то шринк и не должен работать, ему не отчего отнимать :-)

чё то все молчат....и в аськах тоже

to 111: а почему ты думаешь что со шринком могут быть проблемы?
это вроде обычный алгоритм поиска решений
pepper
Алгоритм едж шринка:
1.выделенные ребра преобразуем в полигоны
2.создаем массивчик в который записываем полигоны, пренадлежащие данному еджу
Если выделенны 2 соседних еджа, то полигон в таком массиве встретится 2 раза.
Если полигон встречается 1 раз, то он являлется "крайним"(из которого мы получим крайние еджи))

Теперь непонятный кусок:
3.елси полигоны совпадют(их может быть >2) удаляем их из массива
(т.к. нам нужны полигоны, которые встречаются 1 раз)
CODE

i=1
while i<=pa.count-1 do--перебираем до предпоследнего елемента
(
j=i+1--наинаем сравнивать с позиции следующего элемента
b=0 --а было ли совпадение
clearlistener()
format "i=% j=% b=%\n" i j b
while j<=pa.count do --перебор до последнего елемента
( ----- while 2
if pa[i]==pa[j] then--совпали
(
deleteItem pa j--удаляем

b=1--отмечаем что совпали
j-=1 --массив уменьшился,значит счетчик тоже уменьшаем
)
j+=1--следующий елемент
) ----- end while 2
if b==1 then --если было совпадение
(
deleteItem pa i--удаляем елемент
i-=1--уменьшаем счетчик
)
i+=1 --следующий елемент
)

Я не использовал цикл for т.к. он не позволяет уменьшать счетчик.
Поэтому выбрал while.

4.выделяем полученные "крайние" полигоны
(их можно увидеть перейдя на уровень полигонов после выполнения скрипта)
5.конвертим их в еджи
6.вычитаем: (первоначально выделенные еджи)-(еджи от "крайних" полигонов)

Особенность конвертации еджей в полигоны(пункт 1) состоит в том, что
если едж крайний, то один из его полигонов будет с индексом 0!
Значит 4 пункт не работает(в объектах нет полигона с индексом 0).
То есть он работает(я удаляю 0 элементы), но не учитывается
.............
.............
у-у-у....появилась идея....
если едж крайний и он выделенный, то он однозначно должен быть не выделенным(после шринка)
.....надо замутить.....
111
так изложите алгоритм шринка на человеческом языке
pepper
QUOTE
так изложите алгоритм шринка на человеческом языке

Это на каком? blink.gif biggrin.gif

Короче вот. Теперь шринк ринг роботает как надо!
Лип шринк в предыдущем файле.
Desead
to pepper: сам код то ясен, и про индексы полигонов 1 и 2 тоже понятно, мне именно алгоритм не понятен используемый тобой, без привязки к конкретному языку.

to 111: Конкретно алгоритм шринка, в моём понимании, я опишу тебе в понедельник, когда всё допишу и выложу.
pepper
Алгоритм такой:
Каждому еджу соответствует только 2 полигона.
(на рисунке стрелками показано соответствие эджа полигону)
Эти полигоны записываем в массив. Если их >2(на рисунке указано число повторений полигона в массиве), значит выделены соседние эджи.
Если полигон в массиве встречается один раз, значит он крайний и эдж его тоже крайний.
Desead
ммм.. а мне показалось что ты только для бордюров его используешь, понятно, в принципе я также размышляю :-)
Desead
to pepper:
вообщем мы немного по разному представляем себе алгоритм работы шринка и поэтому скрипты работают по разному. Я исходил из следующих соображений: от выделенных рёбер нужно получить такое выделение, которе при использовании ринга на 1 ребро(ну то что мы раньше написали) даст начальное выделение. хотя мне кажется в некоторых моментах ты не до конца прав rolleyes.gif
вообщем скрипт вот:
-----------------------
macroScript Srink_ring
category:"D_script"
(
if (selection.count==1) and
(classof $ == editable_poly) and
(subobjectlevel==2) then
(--1
edge_selection = polyop.getedgeselection $
if (edge_selection as array).count < 3 then
(--2
polyop.setedgeselection $ #{}
update $
)--2
else
if edge_selection.numberset != edge_selection.count then
(--3
$.shrinkselection ()
shrink_edge=getedgeselection $
temp_edge=edge_selection
del_edge=#{}

while not(temp_edge.isempty) do
(--4
i_edge=(temp_edge as array)[1]
setedgeselection $ #{i_edge}
$.selectedgering ()
i_edge=getedgeselection $
i_edge*=temp_edge
setedgeselection $ i_edge

if i_edge.numberset < 3 then del_edge+=i_edge
else
(--5
temp_face=#()
for j=1 to i_edge.numberset do
(--6
append temp_face ($.getedgeface (i_edge as array)[j] 1)
append temp_face ($.getedgeface (i_edge as array)[j] 2)
)--6
for j=1 to temp_face.count do
(--7
x=temp_face[j]
temp_face[j]=0
df=finditem temp_face x
if df != 0 then temp_face[df]=0
else temp_face[j]=x
)--7
for j=1 to temp_face.count do
if temp_face[j] != 0 then
(--8
te=polyop.getedgesusingface $ (temp_face[j])
del_edge=del_edge+te*i_edge
)--8
)--5
temp_edge=temp_edge-del_edge-i_edge
)--4
setedgeselection $ (edge_selection-del_edge+shrink_edge)
update $
)--3
)--1
)
-----------------------

с лупом проще, это точно. В нём у меня теже различия с тобой что и в шринке, но так как ещё не известно что Shiv'e больше подойдёт пока луп не стал делать, может и вовсе не придётся :-)))

2 Shiva: ну собсна смотри, то что ты хотел или как ?

to 111: Алгоритм шринка в моём понимании(тот который в максе а не тот который используется скриптом) независимо от подуровня, переводим выделение в рёбра, и если ребро является бордюром то соотвествующее ему начальное выделение удаляем, повторяем для всех рёбер. вот и всё
pepper
2 Desead:
QUOTE
Я исходил из следующих соображений: от выделенных рёбер нужно получить такое выделение, которе при использовании ринга на 1 ребро(ну то что мы раньше написали) даст начальное выделение...

Я уже писал: простой алгоритм не всегда эффективный по быстродействию.
Сравни время своего и моего скриптов:
start=timeStamp()
-----------
script
-----------
end=timeStamp()
format "time=%" ((end-start)/1000.0)
Причем у меня учитываются бордеры(borders) объектов(на которые тратится бОльшая часть времени),а у тебя - нет.

QUOTE
хотя мне кажется в некоторых моментах ты не до конца прав

В каких?blink.gif

QUOTE
но так как ещё не известно что Shiv'e больше подойдёт пока луп не стал делать, может и вовсе не придётся :-)))

По-моему они все дружно забили на эти скрипты, а говорили очень надо....wacko.gif

QUOTE
to 111: Алгоритм шринка в моём понимании(тот который в максе а не тот который используется скриптом) независимо от подуровня, переводим выделение в рёбра, и если ребро является бордюром то соотвествующее ему начальное выделение удаляем, повторяем для всех рёбер. вот и всё


Ну а другого алгоритма быть и не может. Главное - как найти этот "бордюр".
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2017 IPS, Inc.