====== I/O Point Cloud ====== The import formats both for files and object representation in GroIMP presented in this tutorial are mostly coming from the plugin [[https://gitlab.com/grogra/groimp-plugins/Pointcloud|Pointcloud]]. See [[dev-guide:plugins|here]] to see how install plugins in GroIMP. The wiki is up to date with the version 1.7 of the plugin. GroIMP support two ways of defining a point cloud object: - As an array: the points coordinates are stored in the array, and the object is considered as one node in the project graph. - As a graph: each point is built in a node of the project graph. This representation enables links between nodes and possible meshes imported (e.g. ply files can support point, line and faces). Other point cloud tutorials: * [[tutorials:using-point-cloud-to-validate-model|Validating growth model on measured point cloud]] * [[tutorials:using-mesh-clouds-as-organ|Using point clouds with meshes as organs]] ===== Import ===== The easiest way to add a Point cloud object in GroIMP is by importing them through the menu bar. See [[tutorials:import-object-in-groimp|here]] for more information on importing file in GroIMP. {{:groimp-platform:importgui.png?400|}} It is however also possible to import a file from the RGG code in a Java block: importNodeFromFile( "/path/to/file/leaf1.xyz", "mimeType/astext"); The file at the given path will be loaded with the filter associated with the given mimetype from GroIMP. The node created is automatically added to the scene under the root node of the project graph. The MimeTypes used for Point cloud import in GroIMP are : * "model/x-grogra-pointcloud-graph+ply" * "model/x-grogra-pointcloud-graph+xyz" * "model/x-grogra-pointcloud-array+ply" * "model/x-grogra-pointcloud-array+xyz" ==== As array ==== It is the most common approach to consider point clouds as it is the most memory efficient one. However, from an array, the XL queries and graph operations are not possible on the points of the point cloud. More over, a point cloud stored as an array can only contains "points" with x,y,z values (while a point cloud as a graph can see "points" as different objects). To import a point cloud as array you can use the GUI (make sure to select the correct mimetype - one that includes to //array// point cloud): {{:groimp-platform:import_pcarray.png?350|}} {{:groimp-platform:graph2d_pcarray.png?200|}} The two current available format are xyz and ply. Even if PLY enables to include "edges", and "faces", they are ignored when the file is imported. Only "vertexes" are included. The file could also have been imported with the RGG method (using a mimetype that contains //array//): importNodeFromFile( "/leaf1.xyz", "model/x-grogra-pointcloud-array+xyz"); In both case, the point cloud is imported behind a single graph Node linked to the root (an //Imp3dCloud// node, see the graph 2d above). //Imp3dCloud// implements de.grogra.pointcloud.groimp.PointCloud. So //PointCloud// can be used to find the Imp3dNodes with RGG queries. The point cloud's point are only accessible through RGG code, e.g. import de.grogra.pointcloud.groimp.PointCloud; [pc:PointCloud ::> println(pc.getCloud()); ] [pc:PointCloud ::> println(pc.getCloud().pointsToFloat()); ] The first command will print the //Cloud// (de.grogra.pointcloud.groimp.Cloud object), which is the class holding the knowledge of the Points. The second command will print a float array containing the coordinate of all the points. ==== As Graph ==== Point clouds can also be imported as Graph that follow the structure: * **CloudGraph**: it is the Object that implements PointCloud, i,e, it is the equivalent of the //Imp3dCloud// object. It is the first node of the Point Cloud. This is the node referred as point cloud Node for this format. * **Intermediate nodes**: these nodes are used to balance the //Points// of the point cloud to the point cloud node. * **PointCloudLeaf**: these nodes represents the //Points// of the point cloud. GroIMP support them to be other objects than simple Point with only coordinate/color. They can be any Node that extends the class PointCloudLeaf the default implementation are: * LeafPointImpl: the default Point. It contains x,y,z coordinates and color. * LeafLineImpl: the default Line. It contains x,y,z coordinates, color and an axis vector which represent both direction and lenght. * LeafMeshImpl: the default Mesh. It is a triangle mesh, i.e. 3 set of coordinates and a color. To import a point cloud file into groimp you can use the GUI, or the RGG command, (making sure the mimetype selected include //to graph pointcloud//. {{:groimp-platform:import_pcgraph.png?350|}} importNodeFromFile( "/leaf1.xyz", "model/x-grogra-pointcloud-graph+xyz"); The given example import a XYZ file, which only contains Points. So the graph created is of the structure: {{:groimp-platform:graph2d_pcgraph_point.png?400|}} If you import a PLY file that include both Vertexes and Faces (and/or Lines), GroIMP will create two (or three) point cloud nodes, one per type of object to import from the PLY file. Each of these point cloud nodes are added under a //CollectionCloud// node: {{:groimp-platform:graph2d_pcgraph_meshes.png?400|}} This very simple example of a PLY file with 3 vertexes and one face show that the face is imported as a LeafMeshImpl (which extends MeshNode - the default mesh node of GroIMP). The LeafMesh is linked to the points that defines it by //Refinement Edges//. Similarly to the point cloud as array, the cloud nodes can be accessed with RGG commands: import de.grogra.pointcloud.groimp.PointCloud; [pc:PointCloud ::> println(pc.getCloud()); ] // print the CloudGraph node for each point cloud (2 here) [pc:PointCloud ::> println(pc.getCloud().pointsToFloat()); ] // print the float array representation of all nodes (in this example it print two float array that contains the same values As the point cloud //Points// are part of the GroIMP project graph, the //Points// are accessible through XL queries for both execution and rewriting: import de.grogra.pointcloud.objects.PointCloudLeaf [p:PointCloudLeaf ::> println(p);] // the next query replace each point by a new point with the same coordinate [p:LeafPointImpl ==> { Vector3d v = p.getTranslation();} LeafPointImpl(v.x, v.y, v.z);] By creating a GroIMP module that extends LeafMeshImpl and define methods to process intercepted light, the point clouds of LeafMesh can easily be intercepting light at the //Point// level. ===== Export ===== As they are part of the GroIMP 3d scene, the point cloud object are included in the standards 3d scene exports. Point cloud can additionally be exported as point clouds of the two same format as the import: XYZ and PLY. The XYZ export only export //Points// that contains exactly 3 coordinates (the meshes and lines are ignored). The PLY format export all //Points//, including meshes and lines. Meshes and Lines are using the existing LeafPoint if they exists and they are linked by Refinement edges. Otherwise they create new point on the fly for the export. The point cloud export can be accessed from the GUI under //3d view> view> export... > pointclouds//. {{:groimp-platform:export_pc.png?400|}} There are three possible export commands: * Export all in one: All the point clouds in the scene are exported into one file. The user needs to select one file in the GUI prompt. * One per file: Each point cloud is exported to a separate file. For each point cloud a new prompt from the GUI will is required. * Selected: Export the selected point clouds (can be several). Each point cloud prompt a GUI file selection.