| 271 | |
| 272 | |
| 273 | PointViewSet PoissonFilter::run(PointViewPtr view) |
| 274 | { |
| 275 | if (!m_normalsProvided) |
| 276 | { |
| 277 | NormalFilter f; |
| 278 | f.setLog(log()); |
| 279 | f.doFilter(*view); |
| 280 | } |
| 281 | |
| 282 | std::unique_ptr<PointSource> source; |
| 283 | if (m_doColor) |
| 284 | source.reset(new ColorPointViewSource(*view)); |
| 285 | else |
| 286 | source.reset(new PointViewSource(*view)); |
| 287 | |
| 288 | PoissonOpts<double> opts; |
| 289 | |
| 290 | opts.m_depth = m_depth; |
| 291 | opts.m_density = m_density; |
| 292 | opts.m_solveDepth = m_depth; |
| 293 | opts.m_kernelDepth = m_depth - 2; |
| 294 | if (m_doColor) |
| 295 | { |
| 296 | opts.m_color = 16; |
| 297 | opts.m_hasColor = true; |
| 298 | } |
| 299 | |
| 300 | OctNode<TreeNodeData>::SetAllocator(MEMORY_ALLOCATOR_BLOCK_SIZE); |
| 301 | PoissonRecon<double> recon(opts, *source); |
| 302 | if (!recon.execute()) |
| 303 | throwError("Failure executing poisson algorithm."); |
| 304 | recon.evaluate(); |
| 305 | |
| 306 | PointViewSet s; |
| 307 | PointViewPtr outView = view->makeNew(); |
| 308 | s.insert(outView); |
| 309 | PointViewMesh mesh(*outView, m_doColor); |
| 310 | recon.extractMesh(mesh); |
| 311 | |
| 312 | // Note here that we're transforming the matrix in the traditional |
| 313 | // sense (rows become columns) because the transformation filter does |
| 314 | // right multiplication instead of left. |
| 315 | TransformationFilter::Transform transform; |
| 316 | auto xform = recon.inverseTransform(); |
| 317 | size_t i = 0; |
| 318 | for (size_t c = 0; c < 4; ++c) |
| 319 | for (size_t r = 0; r < 4; ++r) |
| 320 | transform[i++] = xform.coords[r][c]; |
| 321 | |
| 322 | TransformationFilter().doFilter(*outView, transform); |
| 323 | |
| 324 | // Rerun normals as they may be expected. |
| 325 | { |
| 326 | NormalFilter f; |
| 327 | f.setLog(log()); |
| 328 | f.doFilter(*outView); |
| 329 | } |
| 330 | |