Note: Binary VTK works with big endianness. */
| 177 | Note: Binary VTK works with big endianness. |
| 178 | */ |
| 179 | void saveParticleCloudVTK(const std::string & path, const Partio::ParticlesDataMutable * partioData) |
| 180 | { |
| 181 | const unsigned int numParticles = partioData->numParticles(); |
| 182 | if (0 == numParticles) |
| 183 | return; |
| 184 | |
| 185 | START_TIMING("Writing VTK file"); |
| 186 | // Open the file |
| 187 | std::ofstream outfile{ path, std::ios::binary }; |
| 188 | if (!outfile.is_open()) { |
| 189 | LOG_ERR << "Cannot open a file to save a VTK mesh."; |
| 190 | exit(-1); |
| 191 | } |
| 192 | |
| 193 | outfile << "# vtk DataFile Version 4.1\n"; |
| 194 | outfile << "\n"; |
| 195 | outfile << "BINARY\n"; |
| 196 | outfile << "DATASET UNSTRUCTURED_GRID\n"; |
| 197 | |
| 198 | ////////////////////////////////////////////////////////////////////////// |
| 199 | // find indices of position and ID attribute |
| 200 | unsigned int posIndex = 0xffffffff; |
| 201 | unsigned int idIndex = 0xffffffff; |
| 202 | for (int i = 0; i < partioData->numAttributes(); i++) |
| 203 | { |
| 204 | Partio::ParticleAttribute attr; |
| 205 | partioData->attributeInfo(i, attr); |
| 206 | if (attr.name == "position") |
| 207 | posIndex = i; |
| 208 | else if (attr.name == "id") |
| 209 | idIndex = i; |
| 210 | |
| 211 | LOG_INFO << "Found attribute: " << attr.name; |
| 212 | } |
| 213 | |
| 214 | ////////////////////////////////////////////////////////////////////////// |
| 215 | // export position attribute as POINTS |
| 216 | if (0xffffffff != posIndex) |
| 217 | { |
| 218 | // copy from partio data |
| 219 | std::vector<Vector3f> positions; |
| 220 | positions.reserve(numParticles); |
| 221 | Partio::ParticleAttribute attr; |
| 222 | partioData->attributeInfo(posIndex, attr); |
| 223 | for (unsigned int i = 0u; i < numParticles; i++) |
| 224 | positions.emplace_back(partioData->data<float>(attr, i)); |
| 225 | // swap endianess |
| 226 | for (unsigned int i = 0; i < numParticles; i++) |
| 227 | for (unsigned int c = 0; c < 3; c++) |
| 228 | swapByteOrder(&positions[i][c]); |
| 229 | // export to vtk |
| 230 | outfile << "POINTS " << numParticles << " float\n"; |
| 231 | outfile.write(reinterpret_cast<char*>(positions[0].data()), 3 * numParticles * sizeof(float)); |
| 232 | outfile << "\n"; |
| 233 | } |
| 234 | else |
| 235 | { |
| 236 | LOG_ERR << "No particle positions found!"; |