diff --git a/VirtualRobot/CMakeLists.txt b/VirtualRobot/CMakeLists.txt
index 2fdd7e62fe117feb855ea599b9563ab8eebae667..32faa086c6c28d543b40ec9f5d4bbc57520b5a66 100644
--- a/VirtualRobot/CMakeLists.txt
+++ b/VirtualRobot/CMakeLists.txt
@@ -67,6 +67,8 @@ endif ()
 ##########################################
 #### VISUALIZATION Coin3D+Qt+SoQt / OSG+Qt
 
+find_package(assimp REQUIRED)
+target_link_libraries(VirtualRobot PUBLIC assimp)
 
 if (Simox_USE_COIN_VISUALIZATION)
     MESSAGE(STATUS "Searching Coin3D, Qt and SoQt...")
@@ -260,7 +262,7 @@ SET(SOURCES
     
     Import/RobotImporterFactory.cpp
     Import/SimoxXMLFactory.cpp
-    Import/MeshImport/STLReader.cpp
+    Import/MeshImport/AssimpReader.cpp
     
     math/AbstractFunctionR1R2.cpp
     math/AbstractFunctionR1R3.cpp
@@ -462,7 +464,7 @@ SET(INCLUDES
 
     Import/RobotImporterFactory.h
     Import/SimoxXMLFactory.h
-    Import/MeshImport/STLReader.h
+    Import/MeshImport/AssimpReader.h
     
     math/AbstractFunctionR1Ori.h
     math/AbstractFunctionR1R2.h
diff --git a/VirtualRobot/Import/MeshImport/AssimpReader.cpp b/VirtualRobot/Import/MeshImport/AssimpReader.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3ca0e3c99483033bb6a37126568beb9ec1f1a52a
--- /dev/null
+++ b/VirtualRobot/Import/MeshImport/AssimpReader.cpp
@@ -0,0 +1,161 @@
+#include "AssimpReader.h"
+#include <VirtualRobot/Visualization/TriMeshModel.h>
+
+#include <assimp/Importer.hpp>
+#include <assimp/scene.h>
+#include <assimp/postprocess.h>
+#include <assimp/material.h>
+
+namespace VirtualRobot
+{
+    AssimpReader::AssimpReader(float eps, float scaling) :
+        scaling{scaling}, eps{eps}
+    {}
+
+    std::string AssimpReader::get_extensions() const
+    {
+        static const auto extensions = []
+        {
+            const std::string upper =
+            "3D 3DS 3MF AC AC3D ACC AMJ ASE ASK B3D BLEND BVH CMS COB "  \
+            "DAE DXF ENFF FBX LWO LWS LXO MD2 MD3 MD5 MDC MDL MESH MOT " \
+            "MS3D NDO NFF OBJ OFF OGEX PLY PMX PRJ Q3O Q3S RAW SCN SIB " \
+            "SMD STP STL STLA STLB TER UC VTA X X3D XGL ZGL";
+            std::string both = upper + upper;
+            std::transform(
+                both.begin(), both.begin() + upper.size(), both.begin(),
+                [](unsigned char c)
+            {
+                return std::tolower(c);
+            }
+            );
+            return both;
+        }();
+        return extensions;
+    }
+
+    bool AssimpReader::read(const std::string& filename, const TriMeshModelPtr& t)
+    {
+        //code adapted from http://assimp.sourceforge.net/lib_html/usage.html
+        Assimp::Importer importer;
+        // And have it read the given file with some example postprocessing
+        // Usually - if speed is not the most important aspect for you - you'll
+        // propably to request more postprocessing than we do in this example.
+        const aiScene* scene = importer.ReadFile(
+                                   filename,
+                                   aiProcess_JoinIdenticalVertices    |
+                                   aiProcess_Triangulate              |
+                                   aiProcess_GenSmoothNormals         |
+                                   aiProcess_SortByPType
+                               );
+        return read(scene, t, filename);
+    }
+    bool AssimpReader::readFromBuffer(const std::string_view& v, const TriMeshModelPtr& t)
+    {
+        //code adapted from http://assimp.sourceforge.net/lib_html/usage.html
+        Assimp::Importer importer;
+        // And have it read the given file with some example postprocessing
+        // Usually - if speed is not the most important aspect for you - you'll
+        // propably to request more postprocessing than we do in this example.
+        const aiScene* scene = importer.ReadFileFromMemory(
+                                   v.data(), v.size(),
+                                   aiProcess_JoinIdenticalVertices    |
+                                   aiProcess_Triangulate              |
+                                   aiProcess_GenSmoothNormals         |
+                                   aiProcess_SortByPType
+                               );
+        return read(scene, t, "");
+    }
+
+    void AssimpReader::set_epsilon(float _eps)
+    {
+        eps = _eps;
+    }
+
+    float AssimpReader::epsilon() const
+    {
+        return eps;
+    }
+
+    void AssimpReader::setScaling(float s)
+    {
+        scaling = s;
+    }
+
+    bool AssimpReader::read(const aiScene* scene, const TriMeshModelPtr& t, const std::string& filename)
+    {
+        if (!t)
+        {
+            VR_ERROR << "Tri mesh is null\n";
+            return false;
+        }
+        if (!scene)
+        {
+            VR_ERROR << "unable to load the file '" << filename << "'\n";
+            return false;
+        }
+        if (!scene->mRootNode)
+        {
+            VR_ERROR << "mesh from '" << filename << "' has no root node\n";
+            return false;
+        }
+        if (scene->mNumMeshes != 1)
+        {
+            VR_ERROR << "mesh from '" << filename << "' has not exactly one mesh\n";
+            return false;
+        }
+        if (!scene->mMeshes[0])
+        {
+            VR_ERROR << "mesh from '" << filename << "' is null\n";
+            return false;
+        }
+
+        const aiMesh& m = *(scene->mMeshes[0]);
+        if (!(m.mVertices && m.mNumVertices))
+        {
+            VR_ERROR << "mesh from '" << filename << "' has no vertices\n";
+            return false;
+        }
+        if (!(m.mFaces && m.mNumFaces))
+        {
+            VR_ERROR << "mesh from '" << filename << "' has no vertices\n";
+            return false;
+        }
+        if (!m.mNormals)
+        {
+            VR_ERROR << "mesh from '" << filename << "' has no normals (and none were generated when loading it)\n";
+            return false;
+        }
+
+        t->clear();
+        for (unsigned i = 0; i < m.mNumVertices; ++i)
+        {
+            const auto& v = m.mVertices[i];
+            const auto& n = m.mNormals[i];
+            t->addVertex({v.x, v.y, v.z});
+            t->addNormal({n.x, n.y, n.z});
+        }
+        for (unsigned i = 0; i < m.mNumFaces; ++i)
+        {
+            const auto& f = m.mFaces[i];
+            if (f.mNumIndices != 3)
+            {
+                VR_ERROR << "mesh from '" << filename << "' has face (# " << i << ") with the wrong number of vertices\n";
+                return false;
+            }
+            MathTools::TriangleFace fc;
+            fc.id1 = f.mIndices[0];
+            fc.id2 = f.mIndices[1];
+            fc.id3 = f.mIndices[2];
+            fc.idNormal1 = f.mIndices[0];
+            fc.idNormal2 = f.mIndices[1];
+            fc.idNormal3 = f.mIndices[2];
+            t->addFace(fc);
+        }
+
+        t->scale(scaling);
+        t->mergeVertices(eps);
+        return true;
+    }
+}
+
diff --git a/VirtualRobot/Import/MeshImport/AssimpReader.h b/VirtualRobot/Import/MeshImport/AssimpReader.h
new file mode 100644
index 0000000000000000000000000000000000000000..8bc8549c7b28facb74aef06bac86feb5f2f1c9f8
--- /dev/null
+++ b/VirtualRobot/Import/MeshImport/AssimpReader.h
@@ -0,0 +1,44 @@
+#pragma once
+
+#include <VirtualRobot/VirtualRobot.h>
+
+#include <stdio.h>
+#include <string>
+
+struct aiScene;
+
+namespace VirtualRobot
+{
+    class VIRTUAL_ROBOT_IMPORT_EXPORT AssimpReader
+    {
+    public:
+        AssimpReader(float eps = FLT_MIN, float scaling = 1);
+        virtual ~AssimpReader() = default;
+
+        std::string get_description() const
+        {
+            return "Open Asset Import Library";
+        }
+        std::string get_extensions() const;
+
+        // read data and store it to trimesh
+        bool read(const std::string& _filename, const TriMeshModelPtr& t);
+        bool readFromBuffer(const std::string_view& v, const TriMeshModelPtr& t);
+
+        /** Set the threshold to be used for considering two point to be equal.
+            Can be used to merge small gaps */
+        void set_epsilon(float _eps);
+
+        /// Returns the threshold to be used for considering two point to be equal.
+        float epsilon() const;
+
+        void setScaling(float s);
+    private:
+        bool read(const aiScene* scene, const TriMeshModelPtr& t, const std::string& filename);
+        float scaling;
+        float eps;
+    };
+
+    typedef boost::shared_ptr<AssimpReader> AssimpReaderPtr;
+}
+
diff --git a/VirtualRobot/Import/MeshImport/STLReader.cpp b/VirtualRobot/Import/MeshImport/STLReader.cpp
deleted file mode 100644
index 39021a47214b65fffe491e3216e5156cf4236444..0000000000000000000000000000000000000000
--- a/VirtualRobot/Import/MeshImport/STLReader.cpp
+++ /dev/null
@@ -1,616 +0,0 @@
-/*===========================================================================*\
- *                                                                           *
- *                               OpenMesh                                    *
- *      Copyright (C) 2001-2014 by Computer Graphics Group, RWTH Aachen      *
- *                           www.openmesh.org                                *
- *                                                                           *
- *---------------------------------------------------------------------------*
- *  This file is part of OpenMesh.                                           *
- *                                                                           *
- *  OpenMesh is free software: you can redistribute it and/or modify         *
- *  it under the terms of the GNU Lesser General Public License as           *
- *  published by the Free Software Foundation, either version 3 of           *
- *  the License, or (at your option) any later version with the              *
- *  following exceptions:                                                    *
- *                                                                           *
- *  If other files instantiate templates or use macros                       *
- *  or inline functions from this file, or you compile this file and         *
- *  link it with other files to produce an executable, this file does        *
- *  not by itself cause the resulting executable to be covered by the        *
- *  GNU Lesser General Public License. This exception does not however       *
- *  invalidate any other reasons why the executable file might be            *
- *  covered by the GNU Lesser General Public License.                        *
- *                                                                           *
- *  OpenMesh is distributed in the hope that it will be useful,              *
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
- *  GNU Lesser General Public License for more details.                      *
- *                                                                           *
- *  You should have received a copy of the GNU LesserGeneral Public          *
- *  License along with OpenMesh.  If not,                                    *
- *  see <http://www.gnu.org/licenses/>.                                      *
- *                                                                           *
-\*===========================================================================*/
-
-
-
-#include "STLReader.h"
-#include <VirtualRobot/XML/BaseIO.h>
-#include <VirtualRobot/Visualization/TriMeshModel.h>
-
-// STL
-#include <map>
-
-#include <cfloat>
-#include <fstream>
-#include <stdexcept>
-#include <string>
-
-namespace VirtualRobot
-{
-
-
-
-    STLReader::
-    STLReader()
-        : eps_(FLT_MIN)
-    {
-        scaling = 1.0f;
-    }
-
-
-    //-----------------------------------------------------------------------------
-
-
-    bool
-    STLReader::
-    read(const std::string& _filename, TriMeshModelPtr t)
-    {
-        bool result = false;
-
-        STL_Type file_type = NONE;
-
-        if (_filename.length() >= 4)
-        {
-            std::string ending = _filename.substr(_filename.length() - 4, 4);
-            BaseIO::getLowerCase(ending);
-
-            if (ending == ".stl")
-            {
-                file_type = check_stl_type(_filename);
-            }
-            else if (ending == "stla")
-            {
-                file_type = STLA;
-            }
-            else if (ending == "stlb")
-            {
-                file_type = STLB;
-            }
-        }
-
-        switch (file_type)
-        {
-            case STLA:
-            {
-                result = read_stla(_filename, t);
-                break;
-            }
-
-            case STLB:
-            {
-                result = read_stlb(_filename, t);
-                break;
-            }
-
-            default:
-            {
-                result = false;
-                break;
-            }
-        }
-
-
-        return result;
-    }
-
-    bool
-    STLReader::read(std::istream& _is, STL_Type stltype, TriMeshModelPtr t)
-    {
-
-        bool result = false;
-
-        if (stltype == STLB)
-        {
-            result = read_stlb(_is, t);
-        }
-        else
-        {
-            result = read_stla(_is, t);
-        }
-
-        return result;
-    }
-
-
-    //-----------------------------------------------------------------------------
-
-
-#ifndef DOXY_IGNORE_THIS
-
-    class CmpVec
-    {
-    public:
-
-        CmpVec(float _eps = FLT_MIN) : eps_(_eps) {}
-
-        bool operator()(const Eigen::Vector3f& _v0, const Eigen::Vector3f& _v1) const
-        {
-            if (fabs(_v0[0] - _v1[0]) <= eps_)
-            {
-                if (fabs(_v0[1] - _v1[1]) <= eps_)
-                {
-                    return (_v0[2] < _v1[2] - eps_);
-                }
-                else
-                {
-                    return (_v0[1] < _v1[1] - eps_);
-                }
-            }
-            else
-            {
-                return (_v0[0] < _v1[0] - eps_);
-            }
-        }
-
-    private:
-        float eps_;
-    };
-
-#endif
-
-
-    //-----------------------------------------------------------------------------
-
-    void trimStdString(std::string& _string)
-    {
-        // Trim Both leading and trailing spaces
-
-        size_t start = _string.find_first_not_of(" \t\r\n");
-        size_t end   = _string.find_last_not_of(" \t\r\n");
-
-        if ((std::string::npos == start) || (std::string::npos == end))
-        {
-            _string = "";
-        }
-        else
-        {
-            _string = _string.substr(start, end - start + 1);
-        }
-    }
-
-    //-----------------------------------------------------------------------------
-
-    bool
-    STLReader::
-    read_stla(const std::string& _filename, TriMeshModelPtr t) const
-    {
-        std::fstream in(_filename.c_str(), std::ios_base::in);
-
-        if (!in)
-        {
-            VR_ERROR << "[STLReader] : cannot not open file "
-                     << _filename
-                     << std::endl;
-            return false;
-        }
-
-        bool res = read_stla(in, t);
-
-        if (in)
-        {
-            in.close();
-        }
-
-        return res;
-    }
-
-    //-----------------------------------------------------------------------------
-
-    bool
-    STLReader::
-    read_stla(std::istream& _in, TriMeshModelPtr t) const
-    {
-
-        if (!t)
-        {
-            return false;
-        }
-
-        unsigned int               i;
-        Eigen::Vector3f            v;
-        Eigen::Vector3f            n;
-        std::vector<unsigned int> vhandles;
-
-        CmpVec comp(eps_);
-        std::map<Eigen::Vector3f, unsigned int, CmpVec>            vMap(comp);
-        std::map<Eigen::Vector3f, unsigned int, CmpVec>::iterator  vMapIt;
-
-        std::string line;
-
-        bool facet_normal(false);
-
-        while (_in && !_in.eof())
-        {
-
-            // Get one line
-            std::getline(_in, line);
-
-            if (_in.bad())
-            {
-                VR_ERROR << "  Warning! Could not read stream properly!\n";
-                return false;
-            }
-
-            // Trim Both leading and trailing spaces
-            trimStdString(line);
-
-            // Normal found?
-            if (line.find("facet normal") != std::string::npos)
-            {
-                std::stringstream strstream(line);
-
-                std::string garbage;
-
-                // facet
-                strstream >> garbage;
-
-                // normal
-                strstream >> garbage;
-
-                strstream >> n[0];
-                strstream >> n[1];
-                strstream >> n[2];
-
-                facet_normal = true;
-            }
-
-            // Detected a triangle
-            if ((line.find("outer") != std::string::npos) || (line.find("OUTER") != std::string::npos))
-            {
-
-                vhandles.clear();
-
-                for (i = 0; i < 3; ++i)
-                {
-                    // Get one vertex
-                    std::getline(_in, line);
-                    trimStdString(line);
-
-                    std::stringstream strstream(line);
-
-                    std::string garbage;
-                    strstream >> garbage;
-
-                    strstream >> v[0];
-                    strstream >> v[1];
-                    strstream >> v[2];
-
-                    v *= scaling;
-
-                    // has vector been referenced before?
-                    if ((vMapIt = vMap.find(v)) == vMap.end())
-                    {
-                        // No : add vertex and remember idx/vector mapping
-                        int handle = int (t->vertices.size());
-                        t->addVertex(v);//_bi.add_vertex(v);
-                        vhandles.push_back(handle);
-                        vMap[v] = handle;
-                    }
-                    else
-                        // Yes : get index from map
-                    {
-                        vhandles.push_back(vMapIt->second);
-                    }
-                }
-
-                // Add face only if it is not degenerated
-                if ((vhandles[0] != vhandles[1]) &&
-                    (vhandles[0] != vhandles[2]) &&
-                    (vhandles[1] != vhandles[2]))
-                {
-                    MathTools::TriangleFace f;
-                    f.set(vhandles[0], vhandles[1], vhandles[2]);
-
-                    if (facet_normal)
-                    {
-                        unsigned int noId = t->normals.size();
-                        t->addNormal(n);
-                        f.setNormal(noId, noId, noId);
-                    }
-
-                    //int fh = int(t->faces.size());
-                    t->addFace(f);
-                    //_bi.add_face(vhandles);
-                    facet_normal = false;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    //-----------------------------------------------------------------------------
-
-    bool
-    STLReader::
-    read_stlb(const std::string& _filename, TriMeshModelPtr t) const
-    {
-        std::fstream in(_filename.c_str(), std::ios_base::in | std::ios_base::binary);
-
-        if (!in)
-        {
-            VR_ERROR << "[STLReader] : cannot not open file "
-                     << _filename
-                     << std::endl;
-            return false;
-        }
-
-        bool res = read_stlb(in, t);
-
-        if (in)
-        {
-            in.close();
-        }
-
-        return res;
-    }
-
-    //-----------------------------------------------------------------------------
-
-
-
-    float STLReader::read_float(std::istream& _in, bool _swap) const
-    {
-        union u3
-        {
-            float f;
-            unsigned char c[4];
-        } fc;
-        _in.read((char*)fc.c, 4);
-
-        if (_swap)
-        {
-            std::swap(fc.c[0], fc.c[3]);
-            std::swap(fc.c[1], fc.c[2]);
-        }
-
-        return fc.f;
-    }
-
-    int STLReader::read_int(std::istream& _in, bool _swap) const
-    {
-        union u2
-        {
-            int i;
-            unsigned char c[4];
-        } ic;
-        _in.read((char*)ic.c, 4);
-
-        if (_swap)
-        {
-            std::swap(ic.c[0], ic.c[3]);
-            std::swap(ic.c[1], ic.c[2]);
-        }
-
-        return ic.i;
-    }
-
-    bool
-    STLReader::
-    read_stlb(std::istream& _in, TriMeshModelPtr t) const
-    {
-        if (!t)
-        {
-            return false;
-        }
-
-        char                       dummy[100];
-        bool                       swapFlag;
-        unsigned int               i, nT;
-        Eigen::Vector3f            v, n;
-        std::vector<unsigned int> vhandles;
-
-
-        std::map<Eigen::Vector3f, unsigned int, CmpVec>  vMap;
-        std::map<Eigen::Vector3f, unsigned int, CmpVec>::iterator vMapIt;
-
-
-        // check size of types
-        if ((sizeof(float) != 4) || (sizeof(int) != 4))
-        {
-            VR_ERROR << "[STLReader] : wrong type size\n";
-            return false;
-        }
-
-        // determine endian mode
-        union
-        {
-            unsigned int i;
-            unsigned char c[4];
-        } endian_test;
-        endian_test.i = 1;
-        swapFlag = (endian_test.c[3] == 1);
-
-        // read number of triangles
-        _in.read(dummy, 80);
-        nT = read_int(_in, swapFlag);
-
-        // read triangles
-        while (nT)
-        {
-            vhandles.clear();
-
-            // read triangle normal
-            n[0] = read_float(_in, swapFlag);
-            n[1] = read_float(_in, swapFlag);
-            n[2] = read_float(_in, swapFlag);
-
-            // triangle's vertices
-            for (i = 0; i < 3; ++i)
-            {
-                v[0] = read_float(_in, swapFlag);
-                v[1] = read_float(_in, swapFlag);
-                v[2] = read_float(_in, swapFlag);
-
-                v *= scaling;
-
-                // has vector been referenced before?
-                if ((vMapIt = vMap.find(v)) == vMap.end())
-                {
-                    // No : add vertex and remember idx/vector mapping
-                    unsigned int handle = t->vertices.size();
-                    t->addVertex(v);
-                    //_bi.add_vertex(v);
-                    vhandles.push_back(handle);
-                    vMap[v] = handle;
-                }
-                else
-                    // Yes : get index from map
-                {
-                    vhandles.push_back(vMapIt->second);
-                }
-            }
-
-
-            // Add face only if it is not degenerated
-            if ((vhandles[0] != vhandles[1]) &&
-                (vhandles[0] != vhandles[2]) &&
-                (vhandles[1] != vhandles[2]))
-            {
-                MathTools::TriangleFace f;
-                f.set(vhandles[0], vhandles[1], vhandles[2]);
-                //if (facet_normal) {
-                unsigned int noId = t->normals.size();
-                t->addNormal(n);
-                f.setNormal(noId, noId, noId);
-                //}
-                //int fh = int(t->faces.size());
-                t->addFace(f);
-                //FaceHandle fh = _bi.add_face(vhandles);
-            }
-
-            _in.read(dummy, 2);
-            --nT;
-        }
-
-        return true;
-    }
-
-    //-----------------------------------------------------------------------------
-
-    int STLReader::read_int(FILE* _in, bool _swap) const
-    {
-        union u2
-        {
-            int i;
-            unsigned char c[4];
-        } ic;
-        if(4 != std::fread((char*)ic.c, 1, 4, _in))
-        {
-            throw std::runtime_error{__FILE__ " error in line " + std::to_string(__LINE__) + " failed to read 4 bytes."};
-        }
-
-        if (_swap)
-        {
-            std::swap(ic.c[0], ic.c[3]);
-            std::swap(ic.c[1], ic.c[2]);
-        }
-
-        return ic.i;
-    }
-
-    float STLReader::read_float(FILE* _in, bool _swap) const
-    {
-        union u3
-        {
-            float f;
-            unsigned char c[4];
-        } fc;
-        if(4 != std::fread((char*)fc.c, 1, 4, _in))
-        {
-            throw std::runtime_error{__FILE__ " error in line " + std::to_string(__LINE__) + " failed to read 4 bytes."};
-        }
-
-        if (_swap)
-        {
-            std::swap(fc.c[0], fc.c[3]);
-            std::swap(fc.c[1], fc.c[2]);
-        }
-
-        return fc.f;
-    }
-
-    STLReader::STL_Type
-    STLReader::
-    check_stl_type(const std::string& _filename) const
-    {
-        // assume it's binary stl, then file size is known from #triangles
-        // if size matches, it's really binary
-
-        // open file
-        FILE* in = fopen(_filename.c_str(), "rb");
-
-        if (!in)
-        {
-            return NONE;
-        }
-
-        // determine endian mode
-        union
-        {
-            unsigned int i;
-            unsigned char c[4];
-        } endian_test;
-        endian_test.i = 1;
-        bool swapFlag = (endian_test.c[3] == 1);
-
-        // read number of triangles
-        char dummy[100];
-        if(80 != std::fread(dummy, 1, 80, in))
-        {
-            throw std::runtime_error{__FILE__ " error in line " + std::to_string(__LINE__) + " failed to read 80 bytes."};
-        }
-        size_t nT = read_int(in, swapFlag);
-
-
-        // compute file size from nT
-        size_t binary_size = 84 + nT * 50;
-
-
-        // get actual file size
-        size_t file_size(0);
-        rewind(in);
-
-        while (!feof(in))
-        {
-            file_size += fread(dummy, 1, 100, in);
-        }
-
-        fclose(in);
-
-
-        // if sizes match -> it's STLB
-        return (binary_size == file_size ? STLB : STLA);
-    }
-
-    void STLReader::setScaling(float s)
-    {
-        scaling = s;
-    }
-
-
-
-    //=============================================================================
-} // namespace
-
diff --git a/VirtualRobot/Import/MeshImport/STLReader.h b/VirtualRobot/Import/MeshImport/STLReader.h
deleted file mode 100644
index 5f9ea919c1f5d7d45633b65c1d4fc4f653df6112..0000000000000000000000000000000000000000
--- a/VirtualRobot/Import/MeshImport/STLReader.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-    This code was taken from the LGPL project OpenMesh.
-    Have a look at www.openmesh.org.
-*/
-
-#pragma once
-
-
-#include "VirtualRobot/VirtualRobot.h"
-
-#include <stdio.h>
-#include <string>
-
-
-namespace VirtualRobot
-{
-
-    /**
-        Implementation of the STL format reader.
-    */
-    class VIRTUAL_ROBOT_IMPORT_EXPORT STLReader
-    {
-    public:
-        enum STL_Type { STLA, STLB, NONE };
-
-        // constructor
-        STLReader();
-
-        /// Destructor
-        virtual ~STLReader() {};
-
-
-        std::string get_description() const
-        {
-            return "Stereolithography Interface Format";
-        }
-        std::string get_extensions() const
-        {
-            return "stl stla stlb";
-        }
-
-        // read data and store it to trimesh
-        bool read(const std::string& _filename, TriMeshModelPtr t);
-
-        // read data and store it to trimesh
-        bool read(std::istream& _in, STL_Type stltype, TriMeshModelPtr t);
-
-        /** Set the threshold to be used for considering two point to be equal.
-            Can be used to merge small gaps */
-        void set_epsilon(float _eps)
-        {
-            eps_ = _eps;
-        }
-
-        /// Returns the threshold to be used for considering two point to be equal.
-        float epsilon() const
-        {
-            return eps_;
-        }
-
-        void setScaling(float s);
-
-    private:
-
-        int read_int(FILE* _in, bool _swap) const;
-        float read_float(FILE* _in, bool _swap = false) const;
-
-        float read_float(std::istream& _in, bool _swap = false) const;
-        int read_int(std::istream& _in, bool _swap = false) const;
-
-        STL_Type check_stl_type(const std::string& _filename) const;
-
-        bool read_stla(const std::string& _filename, TriMeshModelPtr t) const;
-        bool read_stla(std::istream& _in, TriMeshModelPtr t) const;
-        bool read_stlb(const std::string& _filename, TriMeshModelPtr t) const;
-        bool read_stlb(std::istream& _in, TriMeshModelPtr t) const;
-
-
-    private:
-        float scaling;
-        float eps_;
-    };
-
-    typedef boost::shared_ptr<STLReader> STLReaderPtr;
-}
-
diff --git a/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.cpp b/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.cpp
index 4a8f33be77874cd5fc187cdabb0d927c21758ae9..c43c0cafc913ad893bb76eb1d4ebc4ddf9937c85 100644
--- a/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.cpp
+++ b/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.cpp
@@ -25,7 +25,7 @@
 #include "../../Workspace/Reachability.h"
 #include "../../Workspace/WorkspaceGrid.h"
 #include "../../XML/BaseIO.h"
-#include "../../Import/MeshImport/STLReader.h"
+#include "../../Import/MeshImport/AssimpReader.h"
 #include <Inventor/SoDB.h>
 #include <Inventor/nodes/SoFile.h>
 #include <Inventor/nodes/SoNode.h>
@@ -232,24 +232,23 @@ namespace VirtualRobot
 
         filesystem::path filepath(filename);
 
-        // check for STL file (.stl, .stla, .stlb)
-        if (filename.length() >= 4)
+        if (filename.length() >= 3)
         {
             std::string extension = filepath.extension().string();
             BaseIO::getLowerCase(extension);
 
-            if (extension == ".stl" || extension == ".stla" || extension == ".stlb")
+            if (extension == ".iv")
             {
-                return getVisualizationFromSTLFile(filename, boundingBox, scaleX, scaleY, scaleZ);
-            }
-        }
+                if (scaleX != 1.0f || scaleY != 1.0f || scaleZ != 1.0f)
+                {
+                    VR_WARNING << "Scaling not yet supported for Coin3D files" << endl;
+                }
 
-        if (scaleX != 1.0f || scaleY != 1.0f || scaleZ != 1.0f)
-        {
-            VR_WARNING << "Scaling not yet supported for Coin3D files" << endl;
+                return getVisualizationFromCoin3DFile(filename, boundingBox);
+            }
         }
 
-        return getVisualizationFromCoin3DFile(filename, boundingBox);
+        return getVisualizationFromFileWithAssimp(filename, boundingBox, scaleX, scaleY, scaleZ);
     }
 
     VisualizationNodePtr CoinVisualizationFactory::getVisualizationFromCoin3DFile(const std::string& filename, bool boundingBox)
@@ -272,19 +271,19 @@ namespace VirtualRobot
         return visualizationNode;
     }
 
-    VisualizationNodePtr CoinVisualizationFactory::getVisualizationFromSTLFile(const std::string& filename, bool boundingBox, float scaleX, float scaleY, float scaleZ)
+    VisualizationNodePtr CoinVisualizationFactory::getVisualizationFromFileWithAssimp(const std::string& filename, bool boundingBox, float scaleX, float scaleY, float scaleZ)
     {
         VisualizationNodePtr visualizationNode(new VisualizationNode);
 
         // try to read from file
         TriMeshModelPtr t(new TriMeshModel());
-        STLReaderPtr r(new STLReader());
-        r->setScaling(1000.0f); // mm
-        bool readOK = r->read(filename, t);
+        AssimpReader r;
+        r.setScaling(1000.0f); // mm
+        bool readOK = r.read(filename, t);
 
         if (!readOK)
         {
-            VR_ERROR << "Could not read stl file " << filename << endl;
+            VR_ERROR << "Could not read file with assimp: " << filename << endl;
             return visualizationNode;
         }
 
diff --git a/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.h b/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.h
index 90dfc200baa5b33e59c98d79e9f01cd3c830d74e..5073b7b489669e489daa672549f60ba385d364f2 100644
--- a/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.h
+++ b/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.h
@@ -67,7 +67,7 @@ namespace VirtualRobot
 
         VisualizationNodePtr getVisualizationFromPrimitives(const std::vector<Primitive::PrimitivePtr>& primitives, bool boundingBox = false, Color color = Color::Gray()) override;
         VisualizationNodePtr getVisualizationFromFile(const std::string& filename, bool boundingBox = false, float scaleX = 1.0f, float scaleY = 1.0f, float scaleZ = 1.0f) override;
-        virtual VisualizationNodePtr getVisualizationFromSTLFile(const std::string& filename, bool boundingBox = false, float scaleX = 1.0f, float scaleY = 1.0f, float scaleZ = 1.0f);
+        virtual VisualizationNodePtr getVisualizationFromFileWithAssimp(const std::string& filename, bool boundingBox = false, float scaleX = 1.0f, float scaleY = 1.0f, float scaleZ = 1.0f);
         virtual VisualizationNodePtr getVisualizationFromCoin3DFile(const std::string& filename, bool boundingBox = false);
         VisualizationNodePtr getVisualizationFromFile(const std::ifstream& ifs, bool boundingBox = false, float scaleX = 1.0f, float scaleY = 1.0f, float scaleZ = 1.0f) override;
         virtual VisualizationNodePtr getVisualizationFromString(const std::string& modelString, bool boundingBox = false);
diff --git a/VirtualRobot/tests/VirtualRobotMeshImportTest.cpp b/VirtualRobot/tests/VirtualRobotMeshImportTest.cpp
index 45a27c38e9d5ff471abc756db9b5a058bd631a66..9b7c1f87857d4f01524005d53619cec99fcde59a 100644
--- a/VirtualRobot/tests/VirtualRobotMeshImportTest.cpp
+++ b/VirtualRobot/tests/VirtualRobotMeshImportTest.cpp
@@ -7,7 +7,7 @@
 #define BOOST_TEST_MODULE VirtualRobot_VirtualRobotMeshImportTest
 
 #include <VirtualRobot/VirtualRobotTest.h>
-#include <VirtualRobot/Import/MeshImport/STLReader.h>
+#include <VirtualRobot/Import/MeshImport/AssimpReader.h>
 #include <VirtualRobot/Visualization/TriMeshModel.h>
 #include <VirtualRobot/RuntimeEnvironment.h>
 
@@ -108,18 +108,15 @@ BOOST_AUTO_TEST_CASE(testParseSTL)
         "endloop\n"
         "endfacet\n"
         "endsolid\n";
-    std::string s(stlcontent);
-    istringstream ss(s);
-    STLReaderPtr r(new STLReader());
-    TriMeshModelPtr t(new TriMeshModel());
-    bool readSTLok = r->read(ss, STLReader::STLA, t);
-    BOOST_REQUIRE(readSTLok);
-    BOOST_REQUIRE(t);
-    BOOST_CHECK_EQUAL(t->vertices.size(), 8); // identical vertices are mapped to one vertex instance
-    BOOST_CHECK_EQUAL(t->faces.size(), 12);
-    BOOST_CHECK_EQUAL(t->vertices.at(0)[0], 0.0f);
-    BOOST_CHECK_EQUAL(t->vertices.at(0)[1], 100.0f);
-    BOOST_CHECK_EQUAL(t->vertices.at(0)[2], 100.0f);
+
+    TriMeshModelPtr t2(new TriMeshModel());
+    {
+        bool readSTLok = AssimpReader{}.readFromBuffer(stlcontent, t2);
+        BOOST_REQUIRE(readSTLok);
+        BOOST_REQUIRE(t2);
+        BOOST_CHECK_EQUAL(t2->vertices.size(), 8); // identical vertices are mapped to one vertex instance
+        BOOST_CHECK_EQUAL(t2->faces.size(), 12);
+    }
 }
 
 BOOST_AUTO_TEST_CASE(testLoadSTL)
@@ -129,13 +126,14 @@ BOOST_AUTO_TEST_CASE(testLoadSTL)
     bool fileOK = RuntimeEnvironment::getDataFileAbsolute(filename);
     BOOST_REQUIRE(fileOK);
 
-    STLReaderPtr r(new STLReader());
-    TriMeshModelPtr t(new TriMeshModel());
-    bool readSTLok = r->read(filename, t);
-    BOOST_REQUIRE(readSTLok);
-    BOOST_REQUIRE(t);
-    BOOST_CHECK_GT(int(t->vertices.size()), 20);
-    BOOST_CHECK_GT(int(t->faces.size()), 20);
+    TriMeshModelPtr t2(new TriMeshModel());
+    {
+        bool readSTLok = AssimpReader{}.read(filename, t2);
+        BOOST_REQUIRE(readSTLok);
+        BOOST_REQUIRE(t2);
+        BOOST_CHECK_GT(int(t2->vertices.size()), 20);
+        BOOST_CHECK_GT(int(t2->faces.size()), 20);
+    }
 }