14

I have about a million 3D points, say

data = Table[{1. x, 1. y, 0.}, {x, 1000}, {y, 10^3}]~Flatten~1;

I want to visualize them, but Graphics3D@Point@data or ListPointPlot3D@data are too slow.

MeshLab or CloudCompare can do it, but I need to export it in some way to get it there. It can read ".txt" files with the "Table" format that Mathematica produces, but that takes a very long time to write:

AbsoluteTiming@Export["test 1mio points.txt", data, "Table"]

{23.9979, "test 1mio points.txt"}

CSV file writing is not much faster. It doesn't look like there is a general bottleneck in converting numbers to text format, as '.m' is written quite quickly:

AbsoluteTiming@Export["test 1mio points.m", data]

{1.92666, "test 1mio points.m"}

but MeshLab cannot handle it.

Any alternatives? Is there a way I can convert a list of points to a GraphicsComplex or Mesh or so and then export that in some format (that might be faster).

masterxilo
  • 5,739
  • 17
  • 39
  • Are there any other formats that MeshLab can read? If so check these against the formats that Mathematica can export. There may be some binary formats that overlap. – Edmund Jul 04 '16 at 21:03
  • It should be trivial to write something that takes a 2D array and writes such a file in C and then integrate this via LibraryLink with WL. I am just hoping somebody has done this. – masterxilo Aug 03 '16 at 15:52
  • PLY and STL, and acutally also obj (by just specifying only 'v' elements) should support points, but Export["test.ply", Point[RandomReal[1., {10, 3}]]] fails. – masterxilo Aug 05 '16 at 23:05

3 Answers3

10

I started working on a package and LinkedLibrary achieving significant speedups with this job:

data = Table[{1. x, 1. y, 0.}, {x, 1000}, {y, 10^3}]~Flatten~1;
<< ExportTable`
AbsoluteTiming@ExportTable["test 1mio points.txt", data]

{0.0381513, Null}

You can find it here: https://github.com/Masterxilo/ExportTable

masterxilo
  • 5,739
  • 17
  • 39
  • 1
    Does not work in MMA 11.2 (Win 7 X64) as of this moment. Don't know why. Keep getting LibraryFunction::libload: The function ExportTableG was not loaded from the file ExportTable.dll. LibraryFunction::libload: The function ExportTableFixedE was not loaded from the file ExportTable.dll. and ExportTable::initfail: Failed to initialize. – Chen Stats Yu Nov 16 '17 at 23:07
  • 1
    Could not be imported on v. 11.3 (MacOS v.10.13) – Seb May 25 '18 at 00:05
6

Here's an alternative: The package https://github.com/Masterxilo/PLYExport implements exporting of Points in PLY format, and extends Export with {"PLY", "BinaryFormat" -> True} to use it, allowing to also export lots of points very quickly:

data = RandomReal[1., {10^6, 3}];
(*Graphics3D@Point[data]*)(*don't do this for large n: Use MeshLab or CloudCompare*)
AbsoluteTiming@
 Export["test 1 mio points.ply", 
  Graphics3D@Point[data], {"PLY", "BinaryFormat" -> True}]

{0.308942, Null}

masterxilo
  • 5,739
  • 17
  • 39
  • Can you provide a link to what "PLY" format is, exactly? Looks like you only use it here with a list-of-lists, and nothing more complex than that, but can it work for that? Can you please clarify this, if you are able to? – CA Trevillian May 15 '19 at 02:59
  • @CATrevillian https://en.m.wikipedia.org/wiki/PLY_(file_format) – masterxilo May 16 '19 at 06:17
3

Not very fast, but acceptable.

data = RandomReal[1, {10^5, 3}];
Export["test1.txt", data, "Table"] // AbsoluteTiming

AbsoluteTiming[
 str = Row[#, "\t"] & /@ data // Column // NumberForm[AccountingForm@#, 16] & // ToString;
 Export["test2.txt", str, "String"]
 ]

Equal @@ (ReadList[#, {Number,Number,Number}] & /@ {"test1.txt","test2.txt"}) // AbsoluteTiming

I also noticed that the same code version 11.2 more slowly than 11.1 enter image description here

chyanog
  • 15,542
  • 3
  • 40
  • 78