Я написал метод для разбора массива, содержащего данные вершин. Целью этого метода было создание нового массива уникальных вершин и нового индекса из этих данных.Неэффективный анализ данных вершин и индексов, поиск более эффективных методов
Это структура, которую я использовал для хранения вершин в массиве.
struct Vertex: Hashable {
var x, y, z,
nx, ny, nz,
s, t: Float
var hashValue: Int {
return "\(self.x),\(self.y),\(self.z),\(self.nx),\(self.ny),\(self.nz),\(self.s),\(self.t),".hashValue
}
static func ==(lhs: Vertex, rhs: Vertex) -> Bool {
return lhs.hashValue == rhs.hashValue
}
}
И это метод, который я использовал для создания массива уникальных вершин и нового индекса. Первый аргумент метода принимает массив с данными вершин, уже упорядоченными исходным индексом.
func makeVertexIndex(_ array: [Float]) -> ([Vertex], [Int]) {
var counter = 0
var indexCounter = 0
var holder = [Float]()
var vertices = [Vertex]()
var index = [Int]()
for i in array {
counter += 1
if counter == 8 {
counter = 0
holder.append(i)
let vertex = Vertex(x: holder[0], y: holder[1], z: holder[2],
nx: holder[3], ny: holder[4], nz: holder[5],
s: holder[6], t: holder[7])
if vertices.contains(vertex) {
guard let match = vertices.index(of: vertex) else { continue }
index.append(match)
} else {
vertices.append(vertex)
index.append(indexCounter)
indexCounter += 1
}
holder.removeAll()
} else {
holder.append(i)
}
}
return (vertices, index)
}
Я был в состоянии успешно разобрать низкий отсчет треугольник сетки, но когда я пытаюсь запустить это на более высоком счете треугольника сетках потребовалось более часа, чтобы бежать.
Я довольно новичок в кодировании, Swift - это мой первый язык, но я подозреваю, что не стоит так долго выполнять эту задачу, и я, вероятно, просто написал свой метод действительно неэффективно или, может быть, подходить к этой проблеме.
В любом случае, я был бы признателен за любую помощь, которую я мог бы получить. Спасибо за прочтение.
Update 1: Я переписал мой метод, чтобы создать массив вершин первым затем перейти к нему в набор, чтобы сделать значение уникальным и обратно в массив затем побежали через петлю vertexArray ищет матчи уникальный массив вершин. Эта версия метода сокращает время процесса с 21 секунды на моей тестовой сетке до примерно 12 секунд.
func makeVertexIndex(_ array: [Float]) -> ([Vertex], [Int]) {
var counter = 0
var holder = [Float]()
var vertexArray = [Vertex]()
var vertices = [Vertex]()
var index = [Int]()
for i in array {
counter += 1
if counter == 8 {
counter = 0
holder.append(i)
let vertex = Vertex(x: holder[0], y: holder[1], z: holder[2],
nx: holder[3], ny: holder[4], nz: holder[5],
s: holder[6], t: holder[7])
vertexArray.append(vertex)
holder.removeAll()
} else {
holder.append(i)
}
}
let vertexSet = Set(vertexArray)
vertices = Array(vertexSet)
for v in vertexArray {
guard let match = vertices.index(of: v) else { continue }
index.append(match)
}
return (vertices, index)
}
Update 2:
Вот моя обновленная структура и метод после реализации некоторых рекомендуемых решений.
Struct:
struct Vertex: Hashable {
var x, y, z,
nx, ny, nz,
s, t: Float
var hashValue: Int {
return "\(self.x),\(self.y),\(self.z),\(self.nx),\(self.ny),\(self.nz),\(self.s),\(self.t)".hashValue
}
static func ==(lhs: Vertex, rhs: Vertex) -> Bool {
return (lhs.x == rhs.x) && (lhs.y == rhs.y) && (lhs.z == rhs.z) && (lhs.nx == rhs.nx) &&
(lhs.ny == rhs.ny) && (lhs.nz == rhs.nz) && (lhs.s == rhs.s) && (lhs.t == rhs.t)
}
}
Метод:
func makeVertexIndex(_ array: [Float]) -> ([Vertex], [Int]) {
var vertexArray = [Vertex]()
vertexArray.reserveCapacity(array.count/8)
var vertices = [Vertex]()
var index = [Int]()
// Creating an array of Vertex from an array containing
// position/normal/texcoord in correct order.
for i in stride(from: 0, to: array.count, by: 8) {
let vertex = Vertex(x: array[i], y: array[i + 1], z: array[i + 2],
nx: array[i + 3], ny: array[i + 4], nz: array[i + 5],
s: array[i + 6], t: array[i + 7])
vertexArray.append(vertex)
}
// Making the Vertex array unique by converting to set and back to array.
let vertexSet = Set(vertexArray)
vertices = Array(vertexSet)
// Making new index by finding the matching vertex in the
// unique vertex array and adding that array index to the new index
for v in vertexArray {
guard let match = vertices.index(of: v) else { continue }
index.append(match)
}
return (vertices, index)
}
После попытки различных частей рекомендуемых решений метода был в состоянии обработать модель с 70K треугольников в 13 минут, ранее он принял полтора часа.
Так что это было огромное улучшение, оценили все решения до сих пор, чтобы держать это открытым, возможно, через день или два, чтобы узнать, приходят ли какие-либо другие рекомендации.
В настоящее время я тестирую ваше решение, пока только внесение изменений в func == имеет огромное значение, прошло от 12 секунд до 3 секунд. OMG Большое спасибо. – Phi
Теперь я попытаюсь реализовать вторую часть вашего сообщения, получив сообщение о том, что я не соглашаюсь на хеширование, когда пытаюсь удалить var hashValue: Int {...} часть моей структуры – Phi
Я думаю он сделал небольшую опечатку, переменную нужно называть hashValue, чтобы соответствовать Hashable. –