GLS.FilePLY.pas 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. //
  2. // The multimedia graphics platform GLScene https://github.com/glscene
  3. //
  4. unit GLS.FilePLY;
  5. (* PLY (Stanford Triangle Format) vector file format implementation *)
  6. interface
  7. {$I GLScene.inc}
  8. uses
  9. System.Classes,
  10. System.SysUtils,
  11. GLS.VectorGeometry,
  12. GLS.VectorLists,
  13. GLS.VectorFileObjects,
  14. GLS.ApplicationFileIO,
  15. GLS.Utils;
  16. type
  17. (* The PLY vector file aka Stanford Triangle Format.
  18. This is a format for storing graphical objects that are described as a
  19. collection of polygons. The format is extensible, supports variations and
  20. subformats. This importer only works for the simplest variant (triangles
  21. without specified normals, and will ignore most header specifications. *)
  22. TGLPLYVectorFile = class(TGLVectorFile)
  23. public
  24. class function Capabilities: TGLDataFileCapabilities; override;
  25. procedure LoadFromStream(aStream: TStream); override;
  26. end;
  27. // ------------------------------------------------------------------
  28. implementation
  29. // ------------------------------------------------------------------
  30. // ------------------
  31. // ------------------ TGLPLYVectorFile ------------------
  32. // ------------------
  33. class function TGLPLYVectorFile.Capabilities: TGLDataFileCapabilities;
  34. begin
  35. Result := [dfcRead];
  36. end;
  37. procedure TGLPLYVectorFile.LoadFromStream(aStream: TStream);
  38. var
  39. i, nbVertices, nbFaces: Integer;
  40. sl: TStringList;
  41. mesh: TGLMeshObject;
  42. fg: TFGVertexIndexList;
  43. p: PChar;
  44. begin
  45. sl := TStringList.Create;
  46. try
  47. sl.LoadFromStream(aStream{$IFDEF Unicode}, TEncoding.ASCII{$ENDIF});
  48. mesh := TGLMeshObject.CreateOwned(Owner.MeshObjects);
  49. mesh.Mode := momFaceGroups;
  50. if sl[0] <> 'ply' then
  51. raise Exception.Create('Not a valid ply file !');
  52. nbVertices := 0;
  53. nbFaces := 0;
  54. i := 0;
  55. while i < sl.Count do
  56. begin
  57. if sl[i] = 'end_header' then
  58. Break;
  59. if Copy(sl[i], 1, 14) = 'element vertex' then
  60. nbVertices := StrToIntDef(Copy(sl[i], 16, MaxInt), 0);
  61. if Copy(sl[i], 1, 12) = 'element face' then
  62. nbFaces := StrToIntDef(Copy(sl[i], 14, MaxInt), 0);
  63. Inc(i);
  64. end;
  65. Inc(i);
  66. // vertices
  67. mesh.Vertices.Capacity := nbVertices;
  68. while (i < sl.Count) and (nbVertices > 0) do
  69. begin
  70. p := PChar(sl[i]);
  71. mesh.Vertices.Add(ParseFloat(p), ParseFloat(p), ParseFloat(p));
  72. // AffineVectorMake(GLStrToFloatDef(tl[0]), GLStrToFloatDef(tl[1]), GLStrToFloatDef(tl[2])));}
  73. Dec(nbVertices);
  74. Inc(i);
  75. end;
  76. // faces
  77. fg := TFGVertexIndexList.CreateOwned(mesh.FaceGroups);
  78. fg.Mode := fgmmTriangles;
  79. fg.VertexIndices.Capacity := nbFaces * 3;
  80. while (i < sl.Count) and (nbFaces > 0) do
  81. begin
  82. p := PChar(sl[i]);
  83. ParseInteger(p); // skip index
  84. fg.VertexIndices.Add(ParseInteger(p), ParseInteger(p), ParseInteger(p));
  85. Dec(nbFaces);
  86. Inc(i);
  87. end;
  88. mesh.BuildNormals(fg.VertexIndices, momTriangles);
  89. finally
  90. sl.Free;
  91. end;
  92. end;
  93. // ------------------------------------------------------------------
  94. initialization
  95. // ------------------------------------------------------------------
  96. RegisterVectorFileFormat('ply', 'Stanford triangle format', TGLPLYVectorFile);
  97. end.