| 1085 | |
| 1086 | |
| 1087 | bool PLYReader::extract_triangles(uint32_t propIdx, const float pos[], uint32_t numVerts, PLYPropertyType destType, void *dest) const |
| 1088 | { |
| 1089 | if (!requires_triangulation(propIdx)) { |
| 1090 | return extract_list_property(propIdx, destType, dest); |
| 1091 | } |
| 1092 | |
| 1093 | const PLYElement* elem = element(); |
| 1094 | const PLYProperty& prop = elem->properties[propIdx]; |
| 1095 | |
| 1096 | const uint32_t* counts = prop.rowCount.data(); |
| 1097 | const uint8_t* data = prop.listData.data(); |
| 1098 | |
| 1099 | uint8_t* to = reinterpret_cast<uint8_t*>(dest); |
| 1100 | |
| 1101 | bool convertSrc = !compatible_types(elem->properties[propIdx].type, PLYPropertyType::Int); |
| 1102 | bool convertDst = !compatible_types(PLYPropertyType::Int, destType); |
| 1103 | |
| 1104 | size_t srcValBytes = kPLYPropertySize[uint32_t(prop.type)]; |
| 1105 | size_t destValBytes = kPLYPropertySize[uint32_t(destType)]; |
| 1106 | |
| 1107 | if (convertSrc && convertDst) { |
| 1108 | std::vector<int> faceIndices, triIndices; |
| 1109 | faceIndices.reserve(32); |
| 1110 | triIndices.reserve(64); |
| 1111 | const uint8_t* face = data; |
| 1112 | for (uint32_t faceIdx = 0; faceIdx < elem->count; faceIdx++) { |
| 1113 | const uint8_t* faceEnd = face + srcValBytes * counts[faceIdx]; |
| 1114 | faceIndices.clear(); |
| 1115 | faceIndices.reserve(counts[faceIdx]); |
| 1116 | for (; face < faceEnd; face += srcValBytes) { |
| 1117 | int idx = -1; |
| 1118 | copy_and_convert_to(&idx, face, prop.type); |
| 1119 | faceIndices.push_back(idx); |
| 1120 | } |
| 1121 | |
| 1122 | triIndices.resize((counts[faceIdx] - 2) * 3); |
| 1123 | triangulate_polygon(counts[faceIdx], pos, numVerts, faceIndices.data(), triIndices.data()); |
| 1124 | for (int idx : triIndices) { |
| 1125 | copy_and_convert(to, destType, reinterpret_cast<const uint8_t*>(&idx), PLYPropertyType::Int); |
| 1126 | to += destValBytes; |
| 1127 | } |
| 1128 | } |
| 1129 | } |
| 1130 | else if (convertSrc) { |
| 1131 | std::vector<int> faceIndices; |
| 1132 | faceIndices.reserve(32); |
| 1133 | const uint8_t* face = data; |
| 1134 | for (uint32_t faceIdx = 0; faceIdx < elem->count; faceIdx++) { |
| 1135 | const uint8_t* faceEnd = face + srcValBytes * counts[faceIdx]; |
| 1136 | faceIndices.clear(); |
| 1137 | faceIndices.reserve(counts[faceIdx]); |
| 1138 | for (; face < faceEnd; face += srcValBytes) { |
| 1139 | int idx = -1; |
| 1140 | copy_and_convert_to(&idx, face, prop.type); |
| 1141 | faceIndices.push_back(idx); |
| 1142 | } |
| 1143 | |
| 1144 | uint32_t numTris = triangulate_polygon(counts[faceIdx], pos, numVerts, faceIndices.data(), reinterpret_cast<int*>(to)); |
no test coverage detected