Как использовать PyMeshLab для уменьшения количества вершин до определенного числа

У меня есть набор треугольных сеток, каждая из которых имеет разные вершины и грани. Я хочу уменьшить количество вершин всех сеток до одного и того же числа, 10000.

Я знаю, что могу использовать simplification_quadric_edge_collapse_decimation, чтобы уменьшить номер грани, что означает, что номер вершины будет соответственно уменьшен. Но проблема в том, что мне приходится использовать этот метод несколько раз, чтобы получить номер вершины ровно до 10000.

Поэтому мне интересно, есть ли другой способ напрямую уменьшить номер вершины до 10000?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
2 278
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Хорошей новостью является то, что оба значения связаны Эйлеровой характеристикой сетки, которая примерно говорит, что количество вершин равно половине количества граней для поверхности без отверстий. Уменьшение вашей сетки до 20000 граней даст сетку примерно из 10000 вершин, но вы также можете легко попасть под 9999. Поскольку у вас есть преимущество в том, что вы программируете на python, вы можете разработать процесс, который будет медленно сходиться к желаемому количеству вершин.

Идея состоит в том, чтобы упростить вашу сетку до числа граней чуть выше 20 000, а затем постепенно улучшать решение, пока не получите ровно 10 000 вершин. Предлагаю уменьшить количество граней на каждом шаге, используя избыток вершины на текущем шаге (vertex_number - 10000).

import pymeshlab as ml
ms = ml.MeshSet()
ms.load_new_mesh('input.ply')
m = ms.current_mesh()
print('input mesh has', m.vertex_number(), 'vertex and', m.face_number(), 'faces')

#Target number of vertex
TARGET=10000

#Estimate number of faces to have 100+10000 vertex using Euler
numFaces = 100 + 2*TARGET

#Simplify the mesh. Only first simplification will be agressive
while (ms.current_mesh().vertex_number() > TARGET):
    ms.apply_filter('simplification_quadric_edge_collapse_decimation', targetfacenum=numFaces, preservenormal=True)
    print("Decimated to", numFaces, "faces mesh has", ms.current_mesh().vertex_number(), "vertex")
    #Refine our estimation to slowly converge to TARGET vertex number
    numFaces = numFaces - (ms.current_mesh().vertex_number() - TARGET)

m = ms.current_mesh()
print('output mesh has', m.vertex_number(), 'vertex and', m.face_number(), 'faces')
ms.save_current_mesh('output.ply')

Обратите внимание, что:

  • Иногда вы просто не можете сократить ровно до 10000 вершин и закончите с 9999 вершинами.
  • С этой формулой каждый шаг (после первого) будет удалять около половины вершин, превышающих 10000, что дает «мягкую посадку» в желаемое количество вершин. Типичное выполнение должно сократиться примерно до 10050 вершин, затем 10025, 10012, 10006, 10003, 10001 и, наконец, 10000 вершин. Окончательное количество граней зависит от упомянутой характеристики Эйлера входной модели.
  • Только первый шаг упрощения потребует значительного времени выполнения (в зависимости от количества треугольников во входной сетке), а следующие шаги упрощения будут очень быстрыми.
  • Если вы все еще хотите ускорить метод, вы можете сделать это numFaces = numFaces - int(1.5*(ms.current_mesh().vertex_number() - 10000)), но это увеличивает шансы завершения под вершиной 9999, и время выполнения не сильно повлияет.
  • Этот метод должен работать с любым алгоритмом прореживания, основанным на гранях, он не является исключительным для квадратичного схлопывания ребер.

Тогда я должен поблагодарить вас за этот хороший вопрос здесь. Было смешно думать об этом.

Rockcat 24.12.2020 10:11

Другие вопросы по теме