Pcx icon indicating copy to clipboard operation
Pcx copied to clipboard

How to load a PLY via script?

Open dblatner opened this issue 5 years ago • 20 comments

I have PLY files in the correct format that work in the editor, but how can I load them via script during runtime?

I searched the available issues here, but didn't find a solution yet.

dblatner avatar Jan 30 '20 11:01 dblatner

The ply importer only supports Editor; There is no runtime support.

I didn't implement it because I thought it's too slow and memory-intensive to use in a practical application. Do you think it could be a useful feature?

keijiro avatar Jan 30 '20 14:01 keijiro

Yes, in my opinion this is an important feature. I want to do it especially for mobile devices and point clouds with around 10k-1M points. (static point clouds, no streaming)

Analogy: Google is successfully doing runtime imports of Tiltbrush and other content via Poly database for almost all platforms.

In another issue you mention that the most time consuming part is the Initialize method, right?

dblatner avatar Jan 30 '20 15:01 dblatner

I managed to load the PLY files during runtime. The point shader works for deployment on Android, but not on iOS. I created a runtime method based on the the mesh import.

@keijiro : do you know how create a iOS compatible shader?

dblatner avatar Jan 30 '20 23:01 dblatner

The point shader should work on iOS, the point size property doesn't work though.

keijiro avatar Feb 02 '20 05:02 keijiro

@keijiro : Can you explain how did you achieve to load the PLY file during runtime?

Charles-HL avatar Feb 18 '20 20:02 Charles-HL

@keijiro thanks for the importer, great work.

Could you or @dblatner please share how to import a PLY on runtime?

maradanovic avatar Jun 16 '20 04:06 maradanovic

@keijiro I'll join the others to thank you for this great tool. I also would like to know how one can load ply files via script. @dblatner any suggestions?

Embalzan avatar Aug 12 '20 07:08 Embalzan

@keijiro I'll join the others to thank you for this great tool. I also would like to know how one can load ply files via script. @dblatner any suggestions?

I managed to do it using almost all of the code in PlyImporter.cs, Thanks again!

Embalzan avatar Aug 12 '20 13:08 Embalzan

Here an example on how to lazy-load PLY files:

  1. Make PlyImporter and it's import methods (ImportAsPointCloudData, ImportAsMesh) public:
public class PlyImporter : ScriptedImporter
    ...
    public PointCloudData ImportAsPointCloudData(string path) {
        ...
  1. Add a Point Cloud Renderer component to a gameobject and use the following custom script:
void Start()
{
    var pclRenderer = gameObject.GetComponent<PointCloudRenderer>();
    var importer = new PlyImporter();

    var cloud = importer.ImportAsPointCloudData("path/to/my/file.ply");
    pclRenderer.sourceData = cloud;
}

@keijiro It is a nice feature for an exhibition where you have a realtime-scanning device.

cansik avatar Jun 30 '21 09:06 cansik

Just seconding everyone else on this thread in regards to being able to do all this in runtime, I think it will be a very useful feature.

I am personally trying to download a .ply file from the web and visualising it in realtime. Exposing the ImportAsMesh as a public method and using it with the downloaded file path allows me to do it pretty easily.

  var importer = new PlyImporter();
  Mesh mesh = importer.ImportAsMesh(path);
  // Then you can use the mesh to change exisiting Mesh filters

@keijiro thank you again for creating this incredibly useful package

septianrazi avatar Jul 09 '21 07:07 septianrazi

Thanks @keijiro for the awesome library, I was able to get the runtime import working using @cansik's method. However, when I try to build to the UWP, I get a bunch of errors of the type

error CS0115: 'PointCloudDataInspector.OnInspectorGUI()': no suitable method found to override
error CS0234: The type or namespace name 'AssetImporters' does not exist in the namespace 'UnityEditor' (are you missing an assembly reference?)
error CS0246: The type or namespace name 'ShaderGUI' could not be found (are you missing a using directive or an assembly reference?)

Is there something else that needs to be done or somewhere the files need to be moved for the runtime import build to work?

rishabhaggarwal2 avatar Sep 23 '21 23:09 rishabhaggarwal2

Hey. I'm having the same issue as everyone else. I'm working with a teacher who hopes to use this to have her students be able to import their own point clouds and visualize them. I got everything working using this

        var importer = new PlyImporter();
        Mesh mesh = importer.ImportAsMesh(destinationPath);
        var meshfilter = pointCloud.GetComponent<MeshFilter>().mesh = mesh;

but when I build i get errors. What i can tell the issue is, is that "UnityEditor.AssetImporters.ScriptedImporter" in plyimporter isn't made to work anywhere outside of the editor, so when building i get a nullreference exception. I'm hoping for some quick assistance here so i can assure her that we will get to where we need to be.

Fantastic work by the way. Thanks

Blabab avatar Jan 24 '22 05:01 Blabab

Hey @Blabab

So the way I got around this issue was to essentially to make a copy of the pcx package and import it in manually in the Assets folder (instead of it being in the package manifest as was the recommended installation method on the README of this repo) - this will allow us to edit the code within the Pcx package.

Once that is done, all you will need to do is find the ImportAsMesh function (in the PlyImporter.cs file) and expose it as a public method. I would recommend creating a new file and class (eg PlyImporterRuntime) as to not interfere with the editor version of the PlyImporter files.

public Mesh ImportAsMesh(string path)

Hope that helps!

septianrazi avatar Jan 24 '22 08:01 septianrazi

@septianrazi Hey. Thanks for getting back to me. I tried your method but I still run into the same issue. This is my process.

-I import (one way or the other) the PCX project into unity

  • I create a duplicate of PlyImporter and call it PlyImporterRuntime
  • I expose PlyImporterRuntime and ImportAsMesh in runtime. public class PlyImporterRuntime : ScriptedImporter public Mesh ImportAsMesh(string path)

-I prepare a gameobject with a meshfilter that i reference in the script below, where I also write the following: var importer = new PlyImporterRuntime(); Mesh mesh = importer.ImportAsMesh(destinationPath); var meshfilter = pointCloud.GetComponent<MeshFilter>().mesh = mesh;

It works perfectly in play mode in the editor, but as soon as i build i get "the type of namespace "PlyImporterRuntime" name could not be found"

If I change PCX.Editor to also work at windows(64) builds, i get a host of other errors instead.

Could you perhaps take me through the process or let me know where I'm missing something. My assumption lies with how ScriptedImporters seem to be something that's for editor use only.

Thanks again.

Blabab avatar Jan 25 '22 07:01 Blabab

@Blabab Hello, did you solve the problems? I have exactly identical problems with you.... I build it on Android and got the error he type of namespace "PlyImporterRuntime" name could not be found" could you tell me how I can solve this?

Thank you again

101kyul avatar Mar 22 '22 06:03 101kyul

@septianrazi Hello I'm trying to build run-time by following your process. However, there are several errors in my project..

  1. import the entire package into Asset folders
  2. Find the file PlyImporter
  3. follow the process @septianrazi proposed. " public class PlyImporterRuntime : ScriptedImporter "
  4. In my private script, I use "var importer = new Pcx.PlyImporter();"
  5. I also tried to make the copy of PLyImporter but it doesn't work.

Assets\Scripts\ARManager.cs(130,36): error CS0234: The type or namespace name 'PlyImporter' does not exist in the namespace 'Pcx' (are you missing an assembly reference?) 2. Build completed with a result of 'Failed' UnityEditor.BuildPlayerWindow:BuildPlayerAndRun() 3. Error building Player because scripts had compiler errors

Could you help me by explaining your method again..?

Thanks again.

101kyul avatar Mar 22 '22 07:03 101kyul

So I'm not entirely sure what these issues are unfortunately

Best thing I can offer is the project that ive made public in which i did use this technique, feel free to have a look at it and see if you can find out the issue/just copy the technique:

https://gitlab.com/appf-anu/APPF-ANU-VR-Projects/xr-pointclouds/-/tree/main/Unity-XR-Pointclouds/Assets/Packages/jp.keijiro.pcx

septianrazi avatar Apr 01 '22 02:04 septianrazi

Hello. Thanks to you! I was able to make a lot of progress. However, I was faced with a big problem because I couldn't catch an error when I loaded the file saved by HTTP. I am sorry to ask you a question again because I am so eager to see PointCloud on my Android.

These are the errors. It seems to be the streamreader can't read the header of the point cloud data. It was confirmed that the file was well stored in the storage location. The same error came out when I tried another Ply file (for example, all-basil) file in your project, so I'd like to ask you again if there's a way to solve it. Thank you for your help.

There's an error message ' Error Unity NullReferenceException: Object reference not set to an instance of an object.'

`Error Unity at Pcx.PlyImporterRuntime.ReadDataHeader (System.IO.StreamReader reader) [0x00000] in <00000000000000000000000000000000>:0 '

` Error Unity at Pcx.PlyImporterRuntime.ImportAsMesh (System.String path) [0x00000] in <00000000000000000000000000000000>:0 '

101kyul avatar Apr 24 '22 04:04 101kyul

I found way how to build it, issue is that you need UnityEditor.AssetImporters in PlyImporter but that is only avilible in editor, not in builded version. BUT you dont need all of the PlyImporter. So you can remove parts requiring inaccesible namespaces. Granted, it works only on Mesh import, but better then nothing.

DarthKirtap avatar May 03 '22 14:05 DarthKirtap