1. Пользоваться форумом на планшетах и телефонах стало удобнее благодаря Tapatalk

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

Тема в разделе "MAXScript", создана пользователем hammerhl, 30 июл 2013.

Модераторы: Savin Denis
  1. hammerhl

    hammerhl Пользователь сайта

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

    Вложения:

    • 3168132.jpg
      3168132.jpg
      Размер файла:
      32,1 КБ
      Просмотров:
      109
    • 3168133.jpg
      3168133.jpg
      Размер файла:
      20,9 КБ
      Просмотров:
      116
    • 3168134.jpg
      3168134.jpg
      Размер файла:
      29,2 КБ
      Просмотров:
      113
  2. igorznag

    igorznag Знаток

    С нами с:
    23.04.2010
    Сообщения:
    1.256
    Симпатии:
    173
    Баллы:
    65
    Без скрипта вы можете создать меш из сплайнов (например с помощью модификатора Surface)?
     
  3. diwian diwian

    diwian diwian Мастер

    С нами с:
    05.06.2010
    Сообщения:
    4.742
    Симпатии:
    74
    Баллы:
    83
    Если не получится при помощи Surface то можно попробовать до применения Surface использовать с начала CrossSection и уже потом "поверхность". Также имеет смысл попробовать Compoud объект " Terrain"(можно даже и не объединять сплайны а только выделить ).
     
  4. Black Sphinx

    Black Sphinx Знаток

    С нами с:
    05.09.2003
    Сообщения:
    234
    Симпатии:
    1
    Баллы:
    29
  5. hammerhl

    hammerhl Пользователь сайта

    С нами с:
    25.07.2013
    Сообщения:
    8
    Симпатии:
    0
    Баллы:
    2
    Большое спасибо за ответы!
    С помощью surface не получилось, результата нет вообще.
    Опять же, crosssection не помог, а terrain сгенерировал нечто ужасное :)
    читал эту статью, но очень надеялся на то, что есть какая-нибудь волшебная функция, в которую передаешь массив сплайнов, а она переваривает его в меш. Но теперь буду пробовать метод из статьи.

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

    igorznag Знаток

    С нами с:
    23.04.2010
    Сообщения:
    1.256
    Симпатии:
    173
    Баллы:
    65
    Попробуйте построить поверхность с помощью программы Surfer.
    Как построить 3D плоскость (Рельеф) по точкам(3000штук), у них координаты x,y,z? Сообщение 10, 13.
    Для каких целей вым нужна эта функция? Я бы попробовал создать маленький Box (или Plane), потом выделить его грани с помощью модификатора Volume Select. В качестве Mesh Object используем нужный меш. Потом проверяем если были выделены грани маленького Box-a или нет.
     
  7. Black Sphinx

    Black Sphinx Знаток

    С нами с:
    05.09.2003
    Сообщения:
    234
    Симпатии:
    1
    Баллы:
    29
    Кстати интересно, а почему не получилась поверхность при использовании CrossSection+Surface?.. Может надо по-другому сплайны генерировать?

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

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

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

    Ы?
     
  8. diwian diwian

    diwian diwian Мастер

    С нами с:
    05.06.2010
    Сообщения:
    4.742
    Симпатии:
    74
    Баллы:
    83
    "Кстати интересно, а почему не получилась поверхность при использовании CrossSection+Surface?.. Может надо по-другому сплайны генерировать? "
    Необходимо соблюдать очерёдность соединения сплайнов а также их начало и завершение.В CrossSection (как и terrain(е)) есть возможность принудительно соединять те сплайны которые необходимы,но здесь не маловажным является положение присоединяемого сплайна в пространстве.
    В данном случае имеется в виду CrossSection(Editable Spline).
     
  9. diwian diwian

    diwian diwian Мастер

    С нами с:
    05.06.2010
    Сообщения:
    4.742
    Симпатии:
    74
    Баллы:
    83
    "Кстати интересно, а почему не получилась поверхность при использовании CrossSection+Surface?.. Может надо по-другому сплайны генерировать? "
    Необходимо соблюдать очерёдность соединения сплайнов а также их начало и завершение.В CrossSection (как и terrain(е)) есть возможность принудительно соединять те сплайны которые необходимы,но здесь не маловажным является положение присоединяемого сплайна в пространстве.
    В данном случае имеется в виду CrossSection(Editable Spline).
     
  10. hammerhl

    hammerhl Пользователь сайта

    С нами с:
    25.07.2013
    Сообщения:
    8
    Симпатии:
    0
    Баллы:
    2
    Спасибо за наводку, но сторонний софт уже на крайний случай, в идеале мне бы хотелось делать все операции одним максовским скриптом.

    Посмотрите в моем первом посте картинки. сплайны, составляющие сетку, у меня должны генерироваться только внутри объекта (в данном случае куба с фасками), в первой итерации это просто, но далее описанный контур будет из объекта вырезаться и сплайны в последующих итерациях необходимо строить с учетом этого. В идеале алгоритм скрипта должен быть таким: если искомая точка внутри некоторого меша - строим к ней сплайн от предыдущей точки. Сейчас у меня на концах резцов просто мелкие сферы и я проверяю пересечение вот так:
    int_point = intersects cObj trackObj
    , где cObj - сфера, а trackObj - куб.
    но ведь intersects определяет пересечения по bounding box'ам, а после изменения меша куба (удаление оттуда куска), bounding box не изменится и я буду получать неоправданно длинные сплайны.
    а ваш метод с вольюм селектом можно из скрипта использовать?

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

    Вложения:

    • 3169922.jpg
      3169922.jpg
      Размер файла:
      19,7 КБ
      Просмотров:
      136
    • 3169923.jpg
      3169923.jpg
      Размер файла:
      12,4 КБ
      Просмотров:
      142
  11. Black Sphinx

    Black Sphinx Знаток

    С нами с:
    05.09.2003
    Сообщения:
    234
    Симпатии:
    1
    Баллы:
    29
    Не надо строить вырезаемый объект точно внутри бокса. Это при вычитании породит глюки там, где будут совпадать (почти совпадать!) поверхности. Вычитаемый объект должен ощутимо пересекать поверхность первого объекта. Это во-первых.

    Во-вторых, если я правильно проинтуичил общий замысел, в качестве вычитаемого объекта можно использовать тор (примитив 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
    
     
  12. igorznag

    igorznag Знаток

    С нами с:
    23.04.2010
    Сообщения:
    1.256
    Симпатии:
    173
    Баллы:
    65
    Да, можно. Посмотрите пример использования в этой теме:
    Ограничение при объединении объектов. Сообщение 2.
     
  13. hammerhl

    hammerhl Пользователь сайта

    С нами с:
    25.07.2013
    Сообщения:
    8
    Симпатии:
    0
    Баллы:
    2
    Что-то я подзакрутился и все не мог найти время ответить.
    проинтуичили правильно, в итоге я сделал тор, который с некоторыми допущениями описывает мою поверхность, его и вычитаю на каждой итерации.
    планирую это дело вынести в отдельную самописную софтинку, а по скольку сходу в максе не получилось все как хотел, решил на принцип не идти и не заморачиваться со скриптовой генерацией поверхности.

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

    Код:
    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
    )
    то есть получается, что детектируется пересечение, если один объект внутри другого или при любых пересечениях их сеток.
    долго не мог понять, почему макс отъедает всю память и валится, оказалось, что сборщик мусора надо руками запускать.

    всем большое спасибо за советы!
     
Модераторы: Savin Denis

Поделиться этой страницей