#pragma once
#include "manifold/manifold.h"
#include "utils.h"
namespace manifold {
enum class CsgNodeType { Union, Intersection, Difference, Leaf };
class CsgLeafNode;
class CsgNode : public std::enable_shared_from_this<CsgNode> {
public:
virtual std::shared_ptr<CsgLeafNode> ToLeafNode() const = 0;
virtual std::shared_ptr<CsgNode> Transform(const mat3x4& m) const = 0;
virtual CsgNodeType GetNodeType() const = 0;
virtual std::shared_ptr<CsgNode> Boolean(
const std::shared_ptr<CsgNode>& second, OpType op);
std::shared_ptr<CsgNode> Translate(const vec3& t) const;
std::shared_ptr<CsgNode> Scale(const vec3& s) const;
std::shared_ptr<CsgNode> Rotate(double xDegrees = 0, double yDegrees = 0,
double zDegrees = 0) const;
};
class CsgLeafNode final : public CsgNode {
public:
CsgLeafNode();
CsgLeafNode(std::shared_ptr<const Manifold::Impl> pImpl_);
CsgLeafNode(std::shared_ptr<const Manifold::Impl> pImpl_, mat3x4 transform_);
std::shared_ptr<const Manifold::Impl> GetImpl() const;
std::shared_ptr<CsgLeafNode> ToLeafNode() const override;
std::shared_ptr<CsgNode> Transform(const mat3x4& m) const override;
CsgNodeType GetNodeType() const override;
static std::shared_ptr<CsgLeafNode> Compose(
const std::vector<std::shared_ptr<CsgLeafNode>>& nodes);
private:
mutable std::shared_ptr<const Manifold::Impl> pImpl_;
mutable mat3x4 transform_ = la::identity;
};
class CsgOpNode final : public CsgNode {
public:
CsgOpNode();
CsgOpNode(const std::vector<std::shared_ptr<CsgNode>>& children, OpType op);
std::shared_ptr<CsgNode> Boolean(const std::shared_ptr<CsgNode>& second,
OpType op) override;
std::shared_ptr<CsgNode> Transform(const mat3x4& m) const override;
std::shared_ptr<CsgLeafNode> ToLeafNode() const override;
CsgNodeType GetNodeType() const override;
~CsgOpNode();
private:
mutable ConcurrentSharedPtr<std::vector<std::shared_ptr<CsgNode>>> impl_ =
ConcurrentSharedPtr<std::vector<std::shared_ptr<CsgNode>>>({});
OpType op_;
mat3x4 transform_ = la::identity;
mutable std::shared_ptr<CsgLeafNode> cache_ = nullptr;
};
}