2
0

GXS.FilePLY.pas 3.1 KB

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