Program Listing for File tree.h

↰ Return to documentation for file (src/ifcgeom/tree.h)

/********************************************************************************
 *                                                                              *
 * This file is part of IfcOpenShell.                                           *
 *                                                                              *
 * IfcOpenShell is free software: you can redistribute it and/or modify         *
 * it under the terms of the Lesser GNU General Public License as published by  *
 * the Free Software Foundation, either version 3.0 of the License, or          *
 * (at your option) any later version.                                          *
 *                                                                              *
 * IfcOpenShell 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                 *
 * Lesser GNU General Public License for more details.                          *
 *                                                                              *
 * You should have received a copy of the Lesser GNU General Public License     *
 * along with this program. If not, see <http://www.gnu.org/licenses/>.         *
 *                                                                              *
 ********************************************************************************/

#ifndef IFCOPENSHELL_TREE_H
#define IFCOPENSHELL_TREE_H

#include "element.h"

#include <array>
#include <cstdint>
#include <string>
#include <vector>

namespace ifcopenshell {
    class file;

    namespace geom {
        class settings;
    }
}

namespace ifcopenshell::geom {
    class iterator;

    using tree_point = std::array<double, 3>;
    using tree_box = std::array<tree_point, 2>;

    struct IFC_GEOM_API ray_intersection_result {
        double distance;
        int style_index;
        express::entity instance;
        tree_point position;
        tree_point normal;
        double ray_distance;
        double dot_product;
    };

    struct IFC_GEOM_API clash {
        int clash_type;
        express::base a;
        express::base b;
        double distance;
        tree_point p1;
        tree_point p2;
    };

    class IFC_GEOM_API tree {
    public:
        tree() = default;
        virtual ~tree();

        tree(const tree& other) = delete;
        tree& operator=(const tree& other) = delete;

        // Identifier this implementation was registered with in the tree registry.
        virtual std::string backend_id() const = 0;

        // Process a file into the tree, or add already processed elements.
        virtual void add_file(ifcopenshell::file& file, const ifcopenshell::geom::settings& settings);
        void add_file(ifcopenshell::geom::iterator& iterator);
        virtual void add_element(ifcopenshell::geom::element* element);

        // Selection is only supported by backends that ingest native elements. Other
        // backends raise, as do other unsupported combinations below.
        virtual std::vector<express::base> select_box(const express::base& entity, bool completely_within = false, double extend = -1.e-5) const;
        virtual std::vector<express::base> select_box(const tree_point& point) const;
        virtual std::vector<express::base> select_box(const tree_box& bounds, bool completely_within = false) const;

        virtual std::vector<express::base> select(const express::base& entity, bool completely_within = false, double extend = 0.0) const;
        virtual std::vector<express::base> select(const ifcopenshell::geom::element* element, bool completely_within = false, double extend = -1.e-5) const;
        virtual std::vector<express::base> select(const tree_point& point, double extend = 0.0) const;
        virtual std::vector<ray_intersection_result> select_ray(const tree_point& origin, const tree_point& direction, double length = 1000.) const;

        // Clashing is only supported by backends that ingest triangulated elements.
        virtual std::vector<clash> clash_intersection_many(const std::vector<express::base>& set_a, const std::vector<express::base>& set_b, double tolerance = 0.002, bool check_all = true) const;
        virtual std::vector<clash> clash_collision_many(const std::vector<express::base>& set_a, const std::vector<express::base>& set_b, bool allow_touching = false) const;
        virtual std::vector<clash> clash_clearance_many(const std::vector<express::base>& set_a, const std::vector<express::base>& set_b, double clearance = 0.05, bool check_all = false) const;

        virtual const std::vector<double>& distances() const;
        virtual const std::vector<double>& protrusion_distances() const;

        virtual bool enable_face_styles() const;
        virtual void enable_face_styles(bool enable);
        virtual const std::vector<ifcopenshell::geom::taxonomy::style::ptr>& styles() const;

        std::string uint8_to_b64(const std::vector<uint8_t>& uuids_array) const;
        static bool is_manifold(const std::vector<int>& faces);
    };
}

#endif