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.