Shopping Cart (0)

Automate your Meshlab workflow with MLX filter scripts

Meshlab is a great program for loading and editing XYZ point cloud data and creating polygon meshes. It also does a good job as a 3D file format converter.

After you start using Meshlab for awhile you will typically use the same filter settings over and over again for every project. Meshlab allows you to automate your workflow by creating your own Meshlab .MLX filter scripts. These filter scripts are in XML format and can be run from the Meshlab GUI or from the command line version of Meshlab called meshlabserver.

About Meshlab

If you run into trouble using Meshlab there is a SourceForge discussion forum that is quite helpful.

If you are using Windows I’ve put together the MultiMesh Scripting Tool that makes life easier with meshlabserver by automating mesh conversions, and creating a simple system for applying an MLX script to a folder of data.

I discovered Meshlab when I started processing aerial images with Bundler / PMVS and needed an opensource program to edit Stanford Triangle Format .PLY files. Each time I ran a set of aerial images through Bundler I wanted to create a new polygon mesh from the ASCII PLY file. It can become tedious after a while applying the same Meshlab filters over and over again so I started exploring the world of Meshlab .MLX filter scripts.

This blog post is probably one of the most hyperniche topics I have written about. If you are using Meshlab, or Meshlabserver along with SFM programs like Bundler I would really like to hear from you about your projects and experiences.

Creating a Meshlab MLX Filter Script

After you apply filters to a Meshlab project you can view a list of the active filters in the current filter script window. To open up the current filter script window go to the Filters menu, and select Show current filter script.

You can edit a Meshlab filter by selecting the Show Current Filter Script menu item.

You can edit a Meshlab filter by selecting the Show Current Filter Script menu item.

Your current Meshlab filters are listed in the Current Filter Script window. Using this interface you can load and save scripts, rearrange the order of the filters, and change the filter parameters.

Your current Meshlab filters are listed in the Current Filter Script window. Using this interface you can load and save scripts, rearrange the order of the filters, and change the filter parameters.

If you have an existing Meshlab .mlx script you can load it by pressing the Open Script button.

If you have an existing Meshlab .mlx script you can load it by pressing the Open Script button.

In the Open Filter Script File dialogue select your Meshlab MLX filter script text file.

In the Open Filter Script File dialogue select your Meshlab .MLX filter script text file.

After you have loaded a Meshlab mlx script you can run it by pressing the Apply Script button.

After you have loaded a Meshlab .mlx script you can run it by pressing the Apply Script button.

On Mac OS X I noticed that once the Meshlab GUI has finished running a Meshlab .MLX filter script the progress bar sometimes stays visible after the task completes. All you have to do is click in the 3D viewport to refresh the view.

If you want to create a new Meshlab MLX script file from your active filters press the Save Script button.

If you want to create a new Meshlab .MLX script file from your active filters press the Save Script button.

When you save your Meshlab filter script don't forget to add the meshlab .mlx file extension.

When you save your Meshlab filter script don’t forget to add the meshlab .mlx file extension.

 

Meshlab MLX Script Example

Here is a sample meshlab .MLX filter script I created to convert a Bundler / PVMS generated ASCII .PLY point cloud into a triangulated polygon mesh by calculating surface normals for the point set, and then using the Poisson surface reconstruction filter.

You can download the script here: PLYmesher_script.mlx

Using meshlabserver From the Command Line

You can run any meshlab .mlx script from the command line with the help of the program called meshlabserver.

Here is an example terminal command to run meshlabserver with the script called PLYmesher_script.mlx . Meshlab will run the .mlx script on the input file called option-000.ply and save the output as a binary PLY file called meshed.ply .

Example command:

meshlabserver -i ./option-0000.ply -o ./meshed.ply -s scripts/PLYmesher_script.mlx -om vc vn

Meshlab parameters:

bash-3.2$ meshlabserver

Usage:
meshlabserver arg1 arg2 …

where args can be:

-i [filename…]  mesh(s) that has to be loaded
-o [filename…]  mesh(s) where to write the result(s)
-s filename            script to be applied
-d filename       dump on a text file a list of all the filtering fucntion
-l filename       the log of the filters is ouput on a file
-om options       data to save in the output files: vc -> vertex colors, vf -> vertex flags, vq -> vertex quality, vn-> vertex normals, vt -> vertex texture coords,  fc -> face colors, ff -> face flags, fq -> face quality, fn-> face normals,  wc -> wedge colors, wn-> wedge normals, wt -> wedge texture coords

Example:
‘meshlabserver -i input.obj -o output.ply -s meshclean.mlx -om vc fq wn’

Notes:
There can be multiple meshes loaded and the order in which they are listed matters because filters that use meshes as parameters choose the mesh based on the order. The number of output meshes must be either one or equal to the number of input meshes. If the number of output meshes is one then only the first mesh in the input list is saved. The format of the output mesh is guessed by the used extension. Script is optional and must be in the format saved by MeshLab.

Download the Patched version of Meshlab 132 for Mac OS X

The current Mac OS X version of meshlabserver that comes bundled with Meshlab v132 has a QT framework linking issue. When to try to launch meshlabserver with the default version available on sourceforge you will typically get the following error :

bash-3.2$ /Applications/meshlab.app/Contents/MacOS/meshlabserver
dyld: Library not loaded: QtScript.framework/Versions/4/QtScript
Referenced from: /Applications/meshlab.app/Contents/MacOS/meshlabserver
Reason: image not found
Trace/BPT trap

I created a NEW patched version of Meshlab 132 for Mac OS X that fixes the meshlabserver framework issue and makes it easier to run .MLX scripts from the command line.

You can download the patched Mac OS X 64-bit version of Meshlab here:
MeshLabMac_v132_patched.zip (46.6 MB)

This is the new and improved meshlabserver.

This is the new and improved meshlabserver.

Note: The meshlabserver program is located inside the meshlab.app package. After you copy the meshlab.app program to your mac applications folder you can run the meshlabserver executable from the command line using the following path:

About the Meshlabserver Patch

The current Mac OS X version of meshlabserver that comes bundled with Meshlab v132 has a QT framework linking issue. When to try to launch meshlab with the default meshlabserver binary you will typically get the following error :

bash-3.2$ /Applications/meshlab.app/Contents/MacOS/meshlabserver
dyld: Library not loaded: QtScript.framework/Versions/4/QtScript
Referenced from: /Applications/meshlab.app/Contents/MacOS/meshlabserver
Reason: image not found
Trace/BPT trap

If you are curious about the problem you can use the otool -L command to find out where the frameworks were linked:

When you run otool -L on the meshlabserver executable you will see the following in your terminal:

mac-pro:~ dsi$ otool -L /Users/dsi/Desktop/meshlab.app/Contents/MacOS/meshlabserver
/Users/dsi/Desktop/meshlab.app/Contents/MacOS/meshlabserver:
@executable_path/libcommon.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/Users/robertoscopigno/QtSDK/Desktop/Qt/4.8.1/gcc/lib/QtScript.framework/Versions/4/QtScript (compatibility version 4.8.0, current version 4.8.1)
/Users/robertoscopigno/QtSDK/Desktop/Qt/4.8.1/gcc/lib/QtCore.framework/Versions/4/QtCore (compatibility version 4.8.0, current version 4.8.1)
/Users/robertoscopigno/QtSDK/Desktop/Qt/4.8.1/gcc/lib/QtXmlPatterns.framework/Versions/4/QtXmlPatterns (compatibility version 4.8.0, current version 4.8.1)
/Users/robertoscopigno/QtSDK/Desktop/Qt/4.8.1/gcc/lib/QtNetwork.framework/Versions/4/QtNetwork (compatibility version 4.8.0, current version 4.8.1)
/Users/robertoscopigno/QtSDK/Desktop/Qt/4.8.1/gcc/lib/QtXml.framework/Versions/4/QtXml (compatibility version 4.8.0, current version 4.8.1)
/Users/robertoscopigno/QtSDK/Desktop/Qt/4.8.1/gcc/lib/QtOpenGL.framework/Versions/4/QtOpenGL (compatibility version 4.8.0, current version 4.8.1)
/Users/robertoscopigno/QtSDK/Desktop/Qt/4.8.1/gcc/lib/QtGui.framework/Versions/4/QtGui (compatibility version 4.8.0, current version 4.8.1)
/System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1094.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)

This shows us the QT frameworks are linked to the wrong location. For example the QtScript.framework is currently linked to:

Users/robertoscopigno/QtSDK/Desktop/Qt/4.8.1/gcc/lib/QtScript.framework/Versions/4/QtScript

 

The correct path should be:

@executable_path/../Frameworks/QtScript.framework/Versions/4/QtScript

If you have the Apple Xcode developer tools installed you can fix the meshlabserver framework linking issues by running the install_name_tool on the meshlabserver program from the command line:

With the fix applied you can now run meshlabserver from the current working directory:

Closing notes about meshlabserver

I would like to see the next version of meshlabserver offer more control over saving files. The current version of meshlabserver doesn’t allow you to access all of the file saving options available in the Meshlab GUI. For example when I save a PLY file using meshlabserver I can only save a binary formatted PLY file.

It is possible to use other free software like RPLY to convert a binary PLY file to an ASCII PLY file but this seems like an unnecessary step.

I would love to see a new build of meshlabserver for Mac OS X that fixes the QT framework linking issue. Also the Mac OS X build of meshlabserver seems to have a problem running the filter script command Transfer Color: Vertex to Face.

<filter name=”Transfer Color: Vertex to Face” />

31 comments
  1. So far the biggest PLY file I have viewed in Meshlab was a 380 MB point set. It had 26 million vertices and was very detailed.

    I haven’t had a chance to generate a poisson surface from such a dense mesh but I suspect it would require quite a bit of RAM and a lot of patience.

  2. Hi JP.

    Today I noticed that a 99MB binary PLY file grows into a 1.4GB file when saved as an ASCII PLY file in MeshLab!

  3. Thanks! With this and a small python script I was able to automate the convex hull computation I had to do on a few meshes.

  4. Hi Peter.

    Thanks for the feedback. It’s nice to know the meshlabsever / meshlab filter scripting blog post was helpful.

  5. Hello, very helpful entry.
    I have 2 issues though in meshlab 1.2.2 in Debian 6 (Squeeze):

    1. When I try to change the parameters for the script before I save it I get a segmentation fault (alpha complex script).

    2. I change manually the parameters in the .mlx, but when I prompt it to save the fn via the -om parameter, it does not, although I get the correct number of fn’s (comparing with the output of the GUI).

    Any clues about those?
    Thanks in advance.

  6. Hi Ted.

    I really like the MeshLab software but it has a tendency to crash at the most inopportune times. I’m hopeful that the next build will focus on improving stability.

    Does your alpha complex MeshLab script work correctly if you open and apply it using the MeshLab GUI compared to running it from the command line with meshlabserver?

  7. Hi Andrew,

    I am new to MLX script and I have a simple question. Do these scripts also take as input different camera viewpoints? I want to render the loaded obj file from different viewpoints automatically from the command line instead of using the mouse. Is it possible?

    Thanking you in anticipation.

    Wajih

  8. Hi Wajih.

    Thanks for your question.

    I looked at MeshLab and it appears that since the “Save Snapshot” command isn’t a filter item it can’t be controlled from a MeshLab .mlx filter script.

  9. I love the script. I’m using it to clean up some data from blender before 3d printing. I would love to see a python example (as mentioned by Peter) as I’m just having a little trouble understanding the syntax. In python are you using os.startfile or maybe subproces.Popen. Any insight would be greatly appreciated.

  10. Hi,
    I’m a meshlab newbie. I have a laserscan of a tunnel that I would like to create a mesh from. I’m unable to access the online helpfile for some reason.

  11. Hi Kalumba.

    Here are a few MeshLab resources:

    Mr. P MeshLab tutorials on YouTube:
    http://www.youtube.com/user/MrPMeshLabTutorials

    MeshLab discussion forum on SourceForge:
    http://sourceforge.net/projects/meshlab/forums/forum/499532

    MeshLab Wiki on SourceForge (SourceForge login required):
    https://sourceforge.net/apps/mediawiki/meshlab/index.php?title=Main_Page

    Exploring Aerial Photogrammetry using Bundler and Meshlab:
    This is a tutorial I created that shows how to create a polygon mesh in MeshLab using point cloud data.
    http://www.andrewhazelden.com/blog/2012/03/exploring-aerial-photogrammetry-using-bundler-and-meshlab/

  12. Hi Chris.

    The Meshlab program can be downloaded from the SourceForge website:
    http://sourceforge.net/projects/meshlab/

    The meshlabserver program is included with the standard MeshLab installer.

    On Windows the meshlabserver program is typically located at:

    C:\Program Files\VCG\MeshLab\meshlabserver.exe

    On Mac OS X the meshlabserver program is located inside the meshlab.app folder package at:

    /Applications/meshlab.app/Contents/MacOS/meshlabserver

  13. Hi Andrew, in the example you provided

    Is it possible to set the parameter in terms of percentage instead of an absolute value like we can do in the GUI? That would make the script so much reusable. Not only it will be great for Vertex Attribute Transfer, it will also be great with other filters such us “Remove Isolated pieces (wrt Diameter)”.

  14. Hi Jason.

    I haven’t thought about customizing an existing meshlabserver MLX script to use a RichAbsPerc percent based value instead of a RichFloat value.

    From looking at the source code in meshlab/src/common/filterparameter.h I noticed Meshlab filters / scripts support the following variable data types:

    • RichBool
    • RichInt
    • RichFloat
    • RichString
    • RichMatrix44f
    • RichPoint3f
    • RichShotf
    • RichColor
    • RichAbsPerc
    • RichEnum
    • RichFloatList
    • RichDynamicFloat
    • RichOpenFile
    • RichSaveFile
    • RichMesh

    Here is an example of a percentage based MLX script value:
    <Param type=”RichAbsPerc” value=”0.19723″ min=”0″ name=”UpperBound” max=”9.86148″/>

    Regards,
    Andrew

    P.S. I would be interested in hearing how your meshlabserver tests work out.

  15. Hi Andrew,

    Thanks for the reply.

    Is it possible to replace “9.86148” with a variable? Every mesh has a different max value. That is what I mean by causing it to be non-reusable.

  16. Hi Jason.

    I put together a new bash script called replace_mlx_value.sh that lets you use placeholder values as variables in a “template” copy of a meshlab script.

    When you run the replace_mlx_value.sh script from the command line it will take your command line values and then write them into a temporary script. It is possible to modify the script to add as many placeholders as you want.

    The syntax for running the script is:
    ./replace_mlx_value.sh [mlx_script_template] [number] [number] [number]

    The current placeholder values are called: COMMAND-VALUE1, COMMAND-VALUE2, and COMMAND-VALUE3.

    After the variables have been replaced the script will increment through the .ply format meshes in your “meshes” folder and process each of them in meshlabserver. The processed meshes will be saved to a folder called “output” with the prefix “out_” added to each of the PLY meshes.

    Here is the first version of the script:
    http://www.andrewhazelden.com/projects/meshlab/replace_mlx_value.zip

    Note: I have been having issues with the latest release of Meshlab v132 (and meshlabserver) on Mac OS X so I haven’t been able to do much of anything with meshlabserver for the last few months.

    Regards,
    Andrew

    P.S. Here is an example of what the script template “script_template.mlxt” would look like with the placeholders included:


    <!DOCTYPE FilterScript>

    <!--

    PLYMesher Meshlabserver script
    This script will generate point cloud normals and then create a polygon mesh from the point cloud.

    by Andrew Hazelden

    This example uses three placeholder values of COMMAND-VALUE1, COMMAND-VALUE2, and COMMAND-VALUE3 that are replaced by a Bash script using sed.

    -->

    <FilterScript>
    <filter name="Compute normals for point sets">
    <Param type="RichInt" value="10" name="K"/>
    <Param type="RichBool" value="false" name="flipFlag"/>
    <Param x="0" y="0" z="0" type="RichPoint3f" name="viewPos"/>
    </filter>
    <filter name="Poisson-disk Sampling">
    <Param type="RichInt" value="150000" name="SampleNum"/>
    <Param type="RichAbsPerc" value="0" min="0" name="Radius" max="COMMAND-VALUE1"/>
    <Param type="RichInt" value="20" name="MontecarloRate"/>
    <Param type="RichBool" value="true" name="Subsample"/>
    <Param type="RichBool" value="false" name="RefineFlag"/>
    <Param type="RichMesh" value="0" name="RefineMesh"/>
    </filter>
    <filter name="Surface Reconstruction: Poisson">
    <Param type="RichInt" value="9" name="OctDepth"/>
    <Param type="RichInt" value="8" name="SolverDivide"/>
    <Param type="RichFloat" value="5" name="SamplesPerNode"/>
    <Param type="RichFloat" value="1" name="Offset"/>
    </filter>
    <filter name="Vertex Attribute Transfer">
    <Param type="RichMesh" value="0" name="SourceMesh"/>
    <Param type="RichMesh" value="1" name="TargetMesh"/>
    <Param type="RichBool" value="false" name="GeomTransfer"/>
    <Param type="RichBool" value="false" name="NormalTransfer"/>
    <Param type="RichBool" value="true" name="ColorTransfer"/>
    <Param type="RichBool" value="false" name="QualityTransfer"/>
    <Param type="RichBool" value="false" name="SelectionTransfer"/>
    <Param type="RichBool" value="false" name="QualityDistance"/>
    <Param type="RichAbsPerc" value="COMMAND-VALUE2" min="0" name="UpperBound" max="COMMAND-VALUE3"/>
    </filter>
    </FilterScript>

  17. Hi Andrew,

    Thanks a lot for the script. I tried it out and it works great. Is it possible to extract the “max” variable so we can assign the “value” variable to be lets say 10% of the “max” variable? The script allows as to set the “max” variable ourselves but most of the time we don’t know it. The meshlab GUI extracted this “max” variable automatically, so I was wondering if it is possible to do the same thing in meshlabserver.

    <filter name=”Remove Isolated pieces (wrt Diameter)”>
    <Param type=”RichAbsPerc” value=”0.679695″ min=”0″ name=”MinComponentDiag” max=”6.79695″/>

  18. Hey Andrew & Jason,

    I think the question was also how this percentage is computed (to be honest, I was wondering that). But finally I figured it out:
    Meshlab creates an AABB (axis aligned bounding box) around the object and computes then distance(min, max), where min,max are 2 corner of the AABB. This is the right value in the GUI (100%).
    To compute the AABB points you can easily use the vertices of your model.
    I wrote some Matlab code:

    coordinates = readTheAppropriateFile(‘/path/to/file’);

    % build bounding box
    minv=[min(coordinates(:,1)),min(coordinates(:,2)),min(coordinates(:,3))];
    maxv=[max(coordinates(:,1)),max(coordinates(:,2)),max(coordinates(:,3))];

    percentage=norm(maxv-minv); % <- 100 percent

    Now you can easily compute other percentage values and using e.g. the script of Andrew for replacing in your file.

    Perhaps this helps some people, as I had to spend a lot of time for figuring that out.

    Thanks Andrew for that script.

    Cheers
    Raphael

  19. I forgot to mention, that some filter change the bounding box (e.g. subsampling). Then you have to split your script after such a step into several small scripts that you apply sequentally. The result in between is then only a temporal file that you use as input for the next script.

    Cheers,
    Raphael

  20. Hi Raphael,

    I tried and it works! Thanks for sharing this information. Combine this with Andrew’s file makes the script very useful.

  21. Hi.

    I have updated this tutorial with new information for Mac users interested in using meshlabserver. The tutorial now has details for permanently fixing the meshlabserver QT framework linking error.

    Regards,
    Andrew

  22. Thanks for the awesome review… helped out a bunch!

    Andrew, is it possible (from a script) to delete all points below a certain Z value? I can manually select points and delete them, but the script doesn’t include any information about the bounding box. There’s probably a way to do this after the fact in Python, for example. However, I like that mesh lab can do the Poisson and the dessimation… I’d just like to remove any of the extrapolated points after it completes.

    Thanks!!

  23. Hi

    Thanks for a great meshlab page 🙂

    Do you know if it’s possible to extact the volume of a mesh from a meshlab script? I can do it manually in meshlab by: Filters -> Quality Measure and Computations -> Compute Geometric Measures, but this dont put anything in the filter script, so I dont know what to do.

  24. Hi Andrew.

    I need to write a script that will open a specific .mlp file, and apply the xray.gdp shader with the PerVertex Color option selected. I have very little experience with C++. Any help would be greatly appreciated!

    Best

    Colin

  25. You asked to hear from people working on projects in this area. I am, and I would love to connect with you by email to have a more extended discussion about your use of Meshlabserver.

    I am working on developing a 3D scanner. For reasons I won’t go into here, the technology we are using to capture our 3D model of the scanned object also winds up capturing parts of walls and floor that surround the object of interest. I wrote a little program that read the OBJ file our scanner produces and then scales the image to the proper size, and automatically crops away the walls and floor. This however leave holes on the underside of the object. And I wanted to automatically fix those two. I’ve looked into writing my own program to find and fix holes, but I would have much higher confidence in using one that uses Meshlab which has been used by thousands of users.

    I’d like to automatically find and fill all holes, so that the resulting scan is immediately ready for CAD programs and 3D Printing programs that require meshes to not have any holes.

    I am able to do scaling, cropping, finding, filling and converting MANUALLY in Meshlab, but until I saw your post I wasn’t aware that there is a Meshlabserver program that I can use to do this automatically (i.e. non-interactively).

    I would very much like to do that, but for now I don’t know how, since even though I have Meshlab installed on my Mac, I don’t see meshlabserver. The latest version of meshlab that I have won’t run on my mac, and the one that will doesn’t seem to have meshlabserver contained inside the app folder. I will need to explore this more.

    Ultimately I want meshlabserver installed on you Linux server, in any case. So i am going to look into that.

    I am guessing that once I get meshlabserver installed on LInux, and I will be able to save any .MLX scripts I work out on a Mac or PC and be able to upload them and use them on our Linux server. Is that correct?

    I’d love to learn more about how I can get meshlabserver working for me and use it to automatically scaled, crop, fill and convert to STL all the files that come from our scanner.

    If you email me your contact information, I will tell you more about what we are doing!

  26. Hi Scott.

    Thanks for your comment. Any MLX script you create on your desktop computer should run the same on any Mac/Window/Linux system.

    This morning I posted a patched version of Meshlab 132 for Mac OS X. It should fix the QT framework linking issue that stops the current Mac version of meshlabserver from working.

    You can download the patched version here:
    MeshLabMac_v132_patched.zip (46.6 MB)

    Note: The meshlabserver program is located inside the meshlab.app package. After you copy the meshlab.app program to your Mac applications folder you can run the meshlabserver executable from the command line using the following path:

    /Applications/meshlab.app/Contents/MacOS/meshlabserver

Comments are closed.