Я пытаюсь реализовать свой маленький САПР и удивляться, как организовать данные для примитивов Безье с кубической поверхностью. Мои примитивы, например коробка, будут содержать шесть кубических патчей Бези, которые для удобства конструируют друг друга по собственным данным. Любой патч имеет 16 очков. Мои примитивы будут сшиты для любой итерации (выбор точек): например, любая точка на краю патчей будет иметь собственную позицию с соответствующей точкой соседних патчей. Я мог бы удалить дублированные точки, но для рендеринга и обновления примитивов мне нужно оставить данные нетронутыми, и в то же время мне нужен надежный алгоритм выбора мыши, который выбирает эти точки по краям и позволяет перемещать одну точку вместе с соответствующими точками соседних патчей.
И я думаю, что у меня есть два варианта:
Какой общий способ решить эту проблему? Спасибо за любой совет.
Одним из распространенных и относительно простых способов является структура данных на основе указателя или индекса. Пример для последнего:
std::vector<Vector3> vertices;
struct Patch
{
// Zero-based indices of the 16 control points in the vertices vector
uint32_t indices[4][4];
}
std::vector<Patch> patches;
Один недостаток — стереть вершины дорого, потому что исправления должны быть исправлены, регулируя эти индексы. Другой недостаток — перечислять патчи, которые ссылаются на определенную вершину, дорого, но если вам нужно делать это часто, вы можете создать & поддерживать отдельный индекс для этого, например, std::unordered_multimap<uint32_t, uint32_t> lookupPatches
;
Это имеет преимущество, если вы тестируете эти патчи Безье на GPU, очень эффективно загружать как вершины (буфер вершин), так и патчи (буфер индекса). Например. для D3d11 это Map, memcpy, Unmap.
Других решений пока нет …