Search code examples
c++boostcgalpoint-cloudsassimp

How do I use a class other than a CGAL Point_3 for point set processing?


I have an array of points that have been loaded by an external library, Assimp, in its own aiVector3D class (which doesn't have component accessor functions, just public access to the member variables), and I want to process these points using CGAL's Point Set Processing library.

As I have 10s of millions of these points (and could one day be billions), I don't want to create a new array of CGAL Point_3s if I can help it.

The documentation says:

Users of this package may use other types to represent positions and normals if they implement the corresponding property maps.

Which seems to imply I can achieve what I want by creating a property map that maps aiVector3D to Point_3, but after reading both CGAL's and Boost's documentation it's not clear to me how I would go about this.

Am I right in thinking this is the way to go? If so, how do I do it?


Solution

  • Whether or not this is more or less efficient (for some meaning of efficient), here's what I came up with to map aiVector3D to CGAL::Point_3 (using a CGAL::Simple_cartesian<double> kernel), including transformations.

    template <typename T>
    struct AItoP {
        AItoP(const aiScene* scene, const aiNode* node) :
                _scene(scene),
                _node(node),
                _mesh(0)
        {
            _mesh = _scene->mMeshes[node->mMeshes[0]];
            _xform = _node->mTransformation * _scene->mRootNode->mTransformation;
        }
    
        T operator()(const size_t& x) const {
            aiVector3t<double> v(_mesh->mVertices[x].x, _mesh->mVertices[x].y, _mesh->mVertices[x].z);
            v *= _xform;
    
            return T(v.x, v.y, v.z);
        }
    private:
        const aiScene* _scene;
        const aiNode* _node;
        const aiMesh* _mesh;
        aiMatrix4x4t<double> _xform;
    };
    

    ...

    #include <boost/property_map/function_property_map.hpp>
    
    void my_processing_function() {
        std::vector<std::size_t> indices(mesh->mNumVertices);
        for(std::size_t i = 0; i < mesh->mNumVertices; ++i){
            indices[i] = i;
        }
    
        double cell_size = 0.05;
        std::vector<std::size_t>::iterator end;
        end = CGAL::grid_simplify_point_set(indices.begin(),
                indices.end(),
                make_function_property_map<const size_t&, Point, AItoP<Point> >(AItoP<Point>(_scene, node)),
                cell_size);
    }