babylon.stlFileLoader.ts 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. module BABYLON {
  2. export class STLFileLoader implements ISceneLoaderPlugin {
  3. public solidPattern = /solid (\S*)([\S\s]*)endsolid (\S*)/g;
  4. public facetsPattern = /facet([\s\S]*?)endfacet/g;
  5. public normalPattern = /normal[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
  6. public vertexPattern = /vertex[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
  7. public extensions = ".stl";
  8. public importMesh(meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]): boolean {
  9. var matches;
  10. while (matches = this.solidPattern.exec(data)) {
  11. var meshName = matches[1];
  12. var meshNameFromEnd = matches[3];
  13. if (meshName != meshNameFromEnd) {
  14. console.log("error in stl, solid name != endsolid name");
  15. }
  16. //check meshesNames
  17. if (meshesNames && meshName) {
  18. if (meshesNames instanceof Array) {
  19. if (!meshesNames.indexOf(meshName)) {
  20. continue;
  21. }
  22. } else {
  23. if (meshName !== meshesNames) {
  24. continue;
  25. }
  26. }
  27. }
  28. //stl mesh name can be empty as well
  29. meshName = meshName || "stlmesh";
  30. var babylonMesh = new Mesh(meshName, scene);
  31. this.parseSolid(babylonMesh, matches[2]);
  32. }
  33. return true;
  34. }
  35. public load(scene: Scene, data: string, rootUrl: string): boolean {
  36. var result = this.importMesh(null, scene, data, rootUrl, null, null, null);
  37. if (result) {
  38. scene.createDefaultCameraOrLight();
  39. }
  40. return result;
  41. }
  42. private parseSolid(mesh: Mesh, solidData: string) {
  43. var normals = [];
  44. var positions = [];
  45. var indices = [];
  46. var indicesCount = 0;
  47. //load facets, ignoring loop as the standard doesn't define it can contain more than vertices
  48. var matches;
  49. while (matches = this.facetsPattern.exec(solidData)) {
  50. var facet = matches[1];
  51. //one normal per face
  52. var normalMatches = this.normalPattern.exec(facet);
  53. this.normalPattern.lastIndex = 0;
  54. if (!normalMatches) {
  55. continue;
  56. }
  57. var normal = [Number(normalMatches[1]), Number(normalMatches[5]), Number(normalMatches[3])];
  58. var vertexMatch;
  59. while (vertexMatch = this.vertexPattern.exec(facet)) {
  60. positions.push(Number(vertexMatch[1]), Number(vertexMatch[5]), Number(vertexMatch[3]));
  61. normals.push(normal[0], normal[1], normal[2]);
  62. }
  63. indices.push(indicesCount++, indicesCount++, indicesCount++);
  64. this.vertexPattern.lastIndex = 0;
  65. }
  66. this.facetsPattern.lastIndex = 0;
  67. mesh.setVerticesData(VertexBuffer.PositionKind, positions);
  68. mesh.setVerticesData(VertexBuffer.NormalKind, normals);
  69. mesh.setIndices(indices);
  70. mesh.computeWorldMatrix(true);
  71. }
  72. }
  73. BABYLON.SceneLoader.RegisterPlugin(new STLFileLoader());
  74. }