Render.ru

Создание меша из множества сплайнов.

hammerhl

Пользователь сайта
Рейтинг
2
#1
Здравствуйте!
Начал изучать maxscript буквально на днях и не могу решить следующую задачу:
скриптом создаю множество линий (пример из хелпа по соединению двух точек), описывающих определенные траектории, в итоге эти линии формируют некий контур, который я хочу вырезать из куба. Так вот, как мне сформировать меш, что бы потом его можно было вырезать из куба?
 

Вложения

Рейтинг
82
#3
Если не получится при помощи Surface то можно попробовать до применения Surface использовать с начала CrossSection и уже потом "поверхность". Также имеет смысл попробовать Compoud объект " Terrain"(можно даже и не объединять сплайны а только выделить ).
 

hammerhl

Пользователь сайта
Рейтинг
2
#5
Большое спасибо за ответы!
Без скрипта вы можете создать меш из сплайнов (например с помощью модификатора Surface)?
С помощью surface не получилось, результата нет вообще.
Если не получится при помощи Surface то можно попробовать до применения Surface использовать с начала CrossSection и уже потом "поверхность". Также имеет смысл попробовать Compoud объект " Terrain"(можно даже и не объединять сплайны а только выделить ).
Опять же, crosssection не помог, а terrain сгенерировал нечто ужасное :)
А статья How To ... Create Custom Mesh Object не спасёт отца русской демократии?
читал эту статью, но очень надеялся на то, что есть какая-нибудь волшебная функция, в которую передаешь массив сплайнов, а она переваривает его в меш. Но теперь буду пробовать метод из статьи.

Еще хотел поинтересоваться, если ли какая специальная функция, что бы определить принадлежит ли точка (находится на грани или внутри) мешу? Если специальной функции нет, посоветуйте пожалуйста какой-нибудь метод.
 

igorznag

Мастер
Рейтинг
103
#6
читал эту статью, но очень надеялся на то, что есть какая-нибудь волшебная функция, в которую передаешь массив сплайнов, а она переваривает его в меш.
Попробуйте построить поверхность с помощью программы Surfer.
Как построить 3D плоскость (Рельеф) по точкам(3000штук), у них координаты x,y,z? Сообщение 10, 13.
Еще хотел поинтересоваться, если ли какая специальная функция, что бы определить принадлежит ли точка (находится на грани или внутри) мешу? Если специальной функции нет, посоветуйте пожалуйста какой-нибудь метод.
Для каких целей вым нужна эта функция? Я бы попробовал создать маленький Box (или Plane), потом выделить его грани с помощью модификатора Volume Select. В качестве Mesh Object используем нужный меш. Потом проверяем если были выделены грани маленького Box-a или нет.
 
Рейтинг
31
#7
Кстати интересно, а почему не получилась поверхность при использовании CrossSection+Surface?.. Может надо по-другому сплайны генерировать?

На сколько я понял, ты вычисляешь пару точек и строишь между ними сплайн. Т.е. получаешь кучу односегментных сплайнов. А вычисленные точки образуют некую сетку, у которой есть "строки" и "столбцы". Правильно?

А если скриптом сразу строить один сложный сплайн (шейп)? Т.е. сначала в шейпе создаёшь первый сплайн, вычисляешь точки по первой "строке" и добавляешь их к первому сплайну, потом добавляешь второй сплайн и вычисляешь/добавляешь точки по второй строке, и т.д. до конца сетки. При этом количество точек в "строках" должно быть одинаковым.

Если на получившейся шейп последовательно натравить CrossSection и Surface, должна получиться очень аккуратная поверхность. Потом, для правильной работы булевых операций, придать объекту объём (EditPoly тебе в помощь).

Ы?
 
Рейтинг
82
#8
"Кстати интересно, а почему не получилась поверхность при использовании CrossSection+Surface?.. Может надо по-другому сплайны генерировать? "
Необходимо соблюдать очерёдность соединения сплайнов а также их начало и завершение.В CrossSection (как и terrain(е)) есть возможность принудительно соединять те сплайны которые необходимы,но здесь не маловажным является положение присоединяемого сплайна в пространстве.
В данном случае имеется в виду CrossSection(Editable Spline).
 
Рейтинг
82
#9
"Кстати интересно, а почему не получилась поверхность при использовании CrossSection+Surface?.. Может надо по-другому сплайны генерировать? "
Необходимо соблюдать очерёдность соединения сплайнов а также их начало и завершение.В CrossSection (как и terrain(е)) есть возможность принудительно соединять те сплайны которые необходимы,но здесь не маловажным является положение присоединяемого сплайна в пространстве.
В данном случае имеется в виду CrossSection(Editable Spline).
 

hammerhl

Пользователь сайта
Рейтинг
2
#10
Цитата hammerhl #5:читал эту статью, но очень надеялся на то, что есть какая-нибудь волшебная функция, в которую передаешь массив сплайнов, а она переваривает его в меш.
Попробуйте построить поверхность с помощью программы Surfer.
Как построить 3D плоскость (Рельеф) по точкам(3000штук), у них координаты x,y,z? Сообщение 10, 13.
Спасибо за наводку, но сторонний софт уже на крайний случай, в идеале мне бы хотелось делать все операции одним максовским скриптом.

Цитата hammerhl #5:Еще хотел поинтересоваться, если ли какая специальная функция, что бы определить принадлежит ли точка (находится на грани или внутри) мешу? Если специальной функции нет, посоветуйте пожалуйста какой-нибудь метод.
Для каких целей вым нужна эта функция? Я бы попробовал создать маленький Box (или Plane), потом выделить его грани с помощью модификатора Volume Select. В качестве Mesh Object используем нужный меш. Потом проверяем если были выделены грани маленького Box-a или нет.
Посмотрите в моем первом посте картинки. сплайны, составляющие сетку, у меня должны генерироваться только внутри объекта (в данном случае куба с фасками), в первой итерации это просто, но далее описанный контур будет из объекта вырезаться и сплайны в последующих итерациях необходимо строить с учетом этого. В идеале алгоритм скрипта должен быть таким: если искомая точка внутри некоторого меша - строим к ней сплайн от предыдущей точки. Сейчас у меня на концах резцов просто мелкие сферы и я проверяю пересечение вот так:
int_point = intersects cObj trackObj
, где cObj - сфера, а trackObj - куб.
но ведь intersects определяет пересечения по bounding box'ам, а после изменения меша куба (удаление оттуда куска), bounding box не изменится и я буду получать неоправданно длинные сплайны.
а ваш метод с вольюм селектом можно из скрипта использовать?

Кстати интересно, а почему не получилась поверхность при использовании CrossSection+Surface?.. Может надо по-другому сплайны генерировать?

На сколько я понял, ты вычисляешь пару точек и строишь между ними сплайн. Т.е. получаешь кучу односегментных сплайнов. А вычисленные точки образуют некую сетку, у которой есть "строки" и "столбцы". Правильно?

А если скриптом сразу строить один сложный сплайн (шейп)? Т.е. сначала в шейпе создаёшь первый сплайн, вычисляешь точки по первой "строке" и добавляешь их к первому сплайну, потом добавляешь второй сплайн и вычисляешь/добавляешь точки по второй строке, и т.д. до конца сетки. При этом количество точек в "строках" должно быть одинаковым.

Если на получившейся шейп последовательно натравить CrossSection и Surface, должна получиться очень аккуратная поверхность. Потом, для правильной работы булевых операций, придать объекту объём (EditPoly тебе в помощь).

Ы?
Да именно так, куча односегментных сплайнов. Может я неправильно понял, но думаю, что количество точек в строках будет неодинаковым (добавил в аттач типовой получаемый сегмент для выреза). сейчас у меня вычисляется последовательно каждая линия, но могу вычислять и параллельно, но тогда получится, что для некоторых линий точек пока что нет, так как линии все разной длины.
пожалуй надо бы мне покурить хелп на предмет построения сложных сплайнов (если ссылку подкините буду признателен, а то пока не шибко в максовском хелпе ориентируюсь).
 

Вложения

Рейтинг
31
#11
Не надо строить вырезаемый объект точно внутри бокса. Это при вычитании породит глюки там, где будут совпадать (почти совпадать!) поверхности. Вычитаемый объект должен ощутимо пересекать поверхность первого объекта. Это во-первых.

Во-вторых, если я правильно проинтуичил общий замысел, в качестве вычитаемого объекта можно использовать тор (примитив Torus), или некий объект, полученный из сплайна (пути) с помощью Loft или Sweep (в сечении - круг). Или я ошибаюсь?

В-третьих, если уж дело пошло на принцип и надо обязательно скриптом, то я накидал скриптик, иллюстрирующий мою идею из поста #7. Это эскиз, но вполне рабочий. Создаёт поверхность, определяемую функцией fsurf. Руками надо только допилить объект, придав ему объём. Думаю, с параметрами разберёшься.
Код:
-- Parameters
numStepAxis = 25
startValueX = 0
stepValueX = 20
startValueY = 0
stepValueY = 20

fn fsurf x y = (
	100 * ((sin x) * (sin y))
)

-- end of parameters

struct fsWrapper (
	startx, stepx,
	starty, stepy,
	funcSurf,
	fn get nx ny = (
		local x = stepx * nx + startx
		local y = stepy * ny + starty
		[x, y, (funcSurf x y)]
	)
)

fn createFuncShape = (

	local fs = fsWrapper startValueX stepValueX startValueY stepValueY fsurf

	local ss = splineShape()
	for nx = 0 to numStepAxis do (
		addNewSpline ss
		for ny = 0 to numStepAxis do (
			addKnot ss (nx + 1) #corner #line (fs.get nx ny)
		)
	)
	updateShape ss
	ss
)

-- execute frome here

obj = createFuncShape()
addModifier obj (CrossSection())
addModifier obj (Surface())
select obj
 

hammerhl

Пользователь сайта
Рейтинг
2
#13
Что-то я подзакрутился и все не мог найти время ответить.
Не надо строить вырезаемый объект точно внутри бокса. Это при вычитании породит глюки там, где будут совпадать (почти совпадать!) поверхности. Вычитаемый объект должен ощутимо пересекать поверхность первого объекта. Это во-первых.

Во-вторых, если я правильно проинтуичил общий замысел, в качестве вычитаемого объекта можно использовать тор (примитив Torus), или некий объект, полученный из сплайна (пути) с помощью Loft или Sweep (в сечении - круг). Или я ошибаюсь?
проинтуичили правильно, в итоге я сделал тор, который с некоторыми допущениями описывает мою поверхность, его и вычитаю на каждой итерации.
планирую это дело вынести в отдельную самописную софтинку, а по скольку сходу в максе не получилось все как хотел, решил на принцип не идти и не заморачиваться со скриптовой генерацией поверхности.

кстати, нашел простой, но довольно медленный способ искать пересечение мешей по реальной сетке, а не по боундинг боксам:

Код:
fn intersect sourseObj interObj = 
( 
inter = (copy sourseObj) * interObj 
if inter==undefined then (
	return false
)
c = GetTriMeshFaceCount inter
delete inter 
res = true;
if c[1]==0	then (
	res= false
)
gc()
return res
)
то есть получается, что детектируется пересечение, если один объект внутри другого или при любых пересечениях их сеток.
долго не мог понять, почему макс отъедает всю память и валится, оказалось, что сборщик мусора надо руками запускать.

всем большое спасибо за советы!
 
Сверху