2. Loading clouds and other entities from files

2.1. Known formats

Entities known by CloudComPy are mainly PointClouds, triangular meshes, polylines…

CloudComPy can read a lot of formats of point clouds and meshes. The .bin binary format is the native format of CloudCompare and can store several entities of all types. Take a look at the details of the formats supported by CloudCompare on wiki.

For clouds, the extensions known by CloudComPy are: .asc .bin .drc .dxf .E57 .las .laz .pcd .ply .pv .sbf .shp .vtk .xyz

For meshes: .dxf .bin .fbx .obj .off .ply .stl .vtk

For polylines: .dxf .poly .sx .shp

See test020.py for an example.

2.2. Load without explicit shift parameters

By default, CloudCompare applies an automatic coordinates shift to recenter the objects and avoid a loss of precision. This is transparent for the user, and is the best option unless you need to load several entities while keeping the same shift. In that case, see Load with explicit shift parameters below.

If you want to know if a coordinate shift has been applied when loading an object, and the value of the shift, see Getting the shift value below.

For all the examples below, we can use the files generated by autotests (see here for Linux or there for Windows or there for macOs. These files are, by default, in the subdirectory CloudComPy/Data of your Home. Let’s start by changing the working directory for your HOME.

os.chdir(os.path.expanduser("~"))

2.2.1. Loading a point cloud

The cloudComPy.loadPointCloud() returns only the first point cloud found in the file.

cloud = cc.loadPointCloud("CloudComPy/Data/dataSample_1.0.xyz")
print(cloud.getName())

2.2.2. Loading a mesh

The cloudComPy.loadMesh() returns only the first mesh found in the file.

mesh = cc.loadMesh("CloudComPy/Data/mesh.stl")
print(mesh.getName())

2.2.3. Loading a polyline

The cloudComPy.loadPolyline() returns the first polyline found in the file.

poly = cc.loadPolyline("CloudComPy/Data/poly1.poly")
print(poly.getName())

2.2.4. Loading a file containing several entities

The cloudComPy.importFile() returns a tuple (list(mesh), list(cloud), list(facets), list(polylines), file structure). The lists can be empty, depending on the content of the file. See Loading the file structure below for file structure. For now, CloudComPy detects only 4 types of entities (meshes, clouds, facets, polylines) in a .bin file. For instance, primitives are imported as meshes.

When an entity depends on another entity, for instance a mesh obtained by a cloud triangulation, the second entity will be loaded as a child of the first, even if it has been saved explicitely with cloudComPy.SaveEntities().

Lets save several entities: 2 clouds, a polyline, 4 facets and the the 4 clouds (vertices) associated to the facets.


cc.SaveEntities([cloud, cloudCropZ, poly, polygon1, polygon2, polygon3, polygon4, vert1, vert2, vert3, vert4], os.path.join(dataDir, "polygons2D.bin"))

Then load the file:


entities = cc.importFile(os.path.join(dataDir, "polygons2D.bin"))
meshes = entities[0]
clouds = entities[1]
facets = entities[2]
polylines = entities[3]
structure = entities[4]

The 4 clouds associated to the facets are not listed in the clouds, they can be retrieved as children of the facets, as indicated in the file structure (see Loading the file structure below).

The above code snippets are from test021.py.

2.3. Select the scans to load in a .E57 file

The cloudComPy.importFile() accept an optional parameter, extraData which a regular expression (see Qt RegExp) used to filter the scans to load in a .E57 file.

In the example below, the file contains 5 scans named ‘sp2_1’, ‘sp2_2’, ‘sp26_1’, ‘sp25_2’, ‘sp26_2’ The regular expression sp2.*_1 allows to select ‘sp2_1’ and ‘sp26_1’ (. means any character, * means 0 occurence or more of the previous).


entities = cc.importFile(os.path.join(dataExtDir,"manitouNoInvalidPoints.e57"), extraData="sp2.*_1")

With the .E57 file, you always get the structure of the file. You can load the structure first (see Loading the file structure below), with an extraData pattern excluding all the scans, to get the scan names, then select a pattern to load the scans you want, one or more at a time…

2.3.1. Loading the file structure

The cloudComPy.importFile() returns the file structure as last item of the return tuple. For instance, .E57 files contains a rich structured set of information. The file structure is given here as an array of strings, the first item of the string is the depth level.

For the test, we need a data file available here.


# example data available here: http://sourceforge.net/projects/e57-3d-imgfmt/files/E57Example-data/manitouNoInvalidPoints.e57/download
if not os.path.isfile(os.path.join(dataExtDir,"manitouNoInvalidPoints.e57")):
    if not os.path.exists(dataExtDir):
        os.makedirs(dataExtDir)
    url = "https://www.simulation.openfields.fr/phocadownload/manitouNoInvalidPoints.e57"
    r = requests.get(url)
    with open(os.path.join(dataExtDir,"manitouNoInvalidPoints.e57"), 'wb') as f:
        f.write(r.content)
        
entities = cc.importFile(os.path.join(dataExtDir,"manitouNoInvalidPoints.e57"))

In this example, there are several point clouds in the example, with one sensor per cloud. To get the structure as a list of strings:


    structure = entities[-1]

The above code snippets are from test041.py.

2.4. Getting the shift value

By default, CloudCompare applies an automatic coordinates shift to recenter the objects and avoid a loss of precision.

To know if a shift has been applied on an object, use the method isShifted().

The three components of the shift are given with the method getGlobalShift().

2.5. Load with explicit shift parameters

when you need to load several entities and apply the same shift, the best solution is to use the option mode=cc.CC_SHIFT_MODE.XYZ followed by the x,y and/or z non null shifts.

cloud1 = cc.loadPointCloud(filename="CloudComPy/Data/dataSample_5.0.xyz",
                           mode=cc.CC_SHIFT_MODE.XYZ, x=3, z=10)
res = cc.importFile(filename="CloudComPy/Data/dataSample_1.0.xyz",
                    mode=cc.CC_SHIFT_MODE.XYZ, x=3, z=10)
cloud2 = res[1][0]
mesh = cc.loadMesh(filename="CloudComPy/Data/mesh.stl",
                   mode=cc.CC_SHIFT_MODE.XYZ, x=3, z=10)

NOTE If you don’t know the value of the shift to apply, load the first entity without shift parameters, and use the methods isShifted() and getGlobalShift() to get a valid shift value.

WARNING Shift parameters are not always taken into account, depending on the type of file, shift values, following the internal rules of CloudCompare: when using the CloudCompare GUI, shift dialog at import is not always available. When the shift dialog is not proposed in the GUI, shift parameters are likely not taken into account in CloudCompare.