ply.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /**
  2. * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Schäfer, Marco <marco.schaefer@uni-tuebingen.de>
  5. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  6. */
  7. import { RuntimeContext, Task } from 'mol-task';
  8. import { addTriangle } from 'mol-geo/geometry/mesh/builder/triangle';
  9. import { ShapeProvider } from 'mol-model/shape/provider';
  10. import { Color } from 'mol-util/color';
  11. import { PlyData, PlyFile } from 'mol-io/reader/ply/schema';
  12. import { MeshBuilder } from 'mol-geo/geometry/mesh/mesh-builder';
  13. import { Mesh } from 'mol-geo/geometry/mesh/mesh';
  14. import { Shape } from 'mol-model/shape';
  15. interface PlyShapeData {
  16. centers: number[],
  17. normals: number[],
  18. faces: number[],
  19. colors: Color[],
  20. labels: string[],
  21. }
  22. function collectData_for_Shape(parsedData: PlyData): PlyShapeData {
  23. // parsedData.data.PLY_File. to access So.format.Ply
  24. console.log('parsedData', parsedData)
  25. const { vertices, colors, faces, normals } = parsedData
  26. const data: PlyShapeData = {
  27. centers: vertices,
  28. normals: normals,
  29. faces: faces,
  30. colors: [],
  31. labels: [],
  32. }
  33. for (let i = 0; i<parsedData.faceCount; i++) {
  34. data.colors[i] = Color.fromRgb(colors[faces[4*i+1]*3+0], colors[faces[4*i+1]*3+1], colors[faces[4*i+1]*3+2]);
  35. data.labels[i] = parsedData.properties[parsedData.propertyCount * faces[4*i+1] + 10].toString();
  36. // i.toString();
  37. // data.transforms[i] = 0;
  38. }
  39. console.log('data', data);
  40. return data;
  41. }
  42. async function getPlyMesh(ctx: RuntimeContext, centers: number[], normals: number[], faces: number[], mesh?: Mesh) {
  43. const builderState = MeshBuilder.createState(faces.length, faces.length, mesh)
  44. builderState.currentGroup = 0
  45. for (let i = 0, il = faces.length/4; i < il; ++i) {
  46. if (i % 10000 === 0 && ctx.shouldUpdate) await ctx.update({ current: i, max: il, message: `adding triangle ${i}` })
  47. builderState.currentGroup = i
  48. let triangle_vertices: number[];
  49. let triangle_normals: number[];
  50. let triangle_indices: number[];
  51. triangle_vertices = [centers[faces[4*i+1]*3], centers[faces[4*i+1]*3+1], centers[faces[4*i+1]*3+2],
  52. centers[faces[4*i+2]*3], centers[faces[4*i+2]*3+1], centers[faces[4*i+2]*3+2],
  53. centers[faces[4*i+3]*3], centers[faces[4*i+3]*3+1], centers[faces[4*i+3]*3+2]];
  54. triangle_normals = [ normals[faces[4*i+1]*3], normals[faces[4*i+1]*3+1], normals[faces[4*i+1]*3+2],
  55. normals[faces[4*i+2]*3], normals[faces[4*i+2]*3+1], normals[faces[4*i+2]*3+2],
  56. normals[faces[4*i+3]*3], normals[faces[4*i+3]*3+1], normals[faces[4*i+3]*3+2]];
  57. triangle_indices = [0, 1, 2];
  58. // console.log(triangle_vertices)
  59. addTriangle(builderState, triangle_vertices, triangle_normals, triangle_indices)
  60. }
  61. let a = MeshBuilder.getMesh(builderState);
  62. console.log(a);
  63. return a
  64. }
  65. async function getShape(ctx: RuntimeContext, parsedData: PlyData, props: {}, shape?: Shape<Mesh>) {
  66. const data = collectData_for_Shape(parsedData)
  67. await ctx.update('async creation of shape from myData')
  68. const { centers, normals, faces, colors, labels } = data
  69. const mesh = await getPlyMesh(ctx, centers, normals, faces, shape && shape.geometry)
  70. const groupCount = centers.length / 3
  71. return shape || Shape.create(
  72. 'test', mesh,
  73. (groupId: number) => colors[groupId], // color: per group, same for instances
  74. () => 1, // size: constant
  75. (groupId: number, instanceId: number) => labels[instanceId * groupCount + groupId] // label: per group and instance
  76. )
  77. }
  78. export const PlyShapeParams = {
  79. ...Mesh.Params
  80. }
  81. export type PlyShapeParams = typeof PlyShapeParams
  82. export function shapeFromPly(source: PlyFile, params?: {}) {
  83. return Task.create<ShapeProvider<PlyData, Mesh, PlyShapeParams>>('Parse Shape Data', async ctx => {
  84. console.log('source', source)
  85. return {
  86. label: 'Mesh',
  87. data: source.PLY_File,
  88. getShape,
  89. geometryUtils: Mesh.Utils
  90. }
  91. })
  92. }