Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Atraxus committed Dec 20, 2024
1 parent 125b543 commit ca453a7
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 16 deletions.
25 changes: 16 additions & 9 deletions Intern/rayx-core/src/Beamline/Beamline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,35 @@
#include "Debug/Instrumentor.h"

namespace RAYX {
Beamline::Beamline() = default;
Beamline::~Beamline() = default;

std::vector<Ray> Beamline::getInputRays(int thread_count) const {
RAYX_PROFILE_FUNCTION_STDOUT();

if (m_DesignSources.size() == 0) {
std::vector<DesignSource> sources = m_RootGroup.getAllSources();

if (sources.size() == 0) {
return {};
}

// count number of rays.
uint32_t raycount = 0;

for (DesignSource dSource : m_DesignSources) {
for (DesignSource dSource : sources) {
raycount += (uint32_t)dSource.getNumberOfRays();
}

// We add all remaining rays into the rays of the first light source.
// This is efficient because in most cases there is just one light source, and hence copying them again is unnecessary.
std::vector<Ray> list = m_DesignSources[0].compile(thread_count);
std::vector<Ray> list = sources[0].compile(thread_count);
for (Ray& r : list) {
r.m_sourceID = 0; // the first light source has ID 0.
}

if (m_DesignSources.size() > 1) {
if (sources.size() > 1) {
list.reserve(raycount);

for (size_t i = 1; i < m_DesignSources.size(); i++) {
std::vector<Ray> sub = m_DesignSources[i].compile(thread_count);
for (size_t i = 1; i < sources.size(); i++) {
std::vector<Ray> sub = sources[i].compile(thread_count);
for (Ray& r : sub) {
r.m_sourceID = static_cast<double>(i);
}
Expand All @@ -44,10 +44,12 @@ std::vector<Ray> Beamline::getInputRays(int thread_count) const {
}

MaterialTables Beamline::calcMinimalMaterialTables() const {
std::vector<DesignElement> elements = m_RootGroup.getAllElements();

std::array<bool, 92> relevantMaterials{};
relevantMaterials.fill(false);

for (const auto& e : m_DesignElements) {
for (const auto& e : elements) {
int material = static_cast<int>(e.getMaterial()); // in [1, 92]
if (1 <= material && material <= 92) {
relevantMaterials[material - 1] = true;
Expand All @@ -57,4 +59,9 @@ MaterialTables Beamline::calcMinimalMaterialTables() const {
return loadMaterialTables(relevantMaterials);
}

void Beamline::addNodeToRoot(BeamlineNode&& node) {
// Add to the root group
m_RootGroup.addChild(std::move(node));
}

} // namespace RAYX
21 changes: 14 additions & 7 deletions Intern/rayx-core/src/Beamline/Beamline.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,21 @@
#include "Core.h"
#include "Design/DesignElement.h"
#include "Design/DesignSource.h"
#include "Design/Group.h"
#include "Material/Material.h"
#include "Shader/Ray.h"

namespace RAYX {
class LightSource;

/*
* The Beamline class is a container for OpticalElements and LightSources.
* The Beamline class is a container for a hierarchical tree of OpticalElements and LightSources.
* It represents a central structure in our simulation process.
*/
class RAYX_API Beamline {
public:
Beamline();
~Beamline();

// iterates over the m_LightSources, and collects the rays they emit.
// Iterates over the m_DesignSources, and collects the rays they emit.
std::vector<Ray> getInputRays(int thread_count = 1) const;

/**
Expand All @@ -33,8 +32,16 @@ class RAYX_API Beamline {
*/
MaterialTables calcMinimalMaterialTables() const;

std::vector<DesignElement> m_DesignElements;
std::vector<DesignSource> m_DesignSources;
/**
* @brief Adds a node to the root Group of the beamline hierarchy.
* @param node The BeamlineNode to add (can be a DesignElement, DesignSource, or nested Group).
*/
void addNodeToRoot(
BeamlineNode&& node); // TODO: Adding only to root note seems good practice but means we need to create nested structures during parsing

private:
// Root node of the beamline hierarchy. This group will always be positioned at 0,0,0 with an identity matrix for the orientation
Group m_RootGroup; // TODO: Should the group just be the new beamline? Both are the same thing conceptually
};

} // namespace RAYX
} // namespace RAYX
73 changes: 73 additions & 0 deletions Intern/rayx-core/src/Design/Group.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#include "Group.h"
#include <stdexcept>

#include "DesignSource.h"
#include "DesignElement.h"

namespace RAYX {

// Implementation of Group's getNodeType
NodeType Group::getNodeType() const {
// A Group is inherently of NodeType::Group
return NodeType::Group;
}

// Implementation of getNode to access a child node by index
const BeamlineNode& Group::getNode(size_t index) const {
if (index >= children.size()) {
throw std::out_of_range("Index out of range in Group::getNode");
}
return children[index];
}

void Group::traverse(const std::function<void(const BeamlineNode&)>& callback) const {
// Apply the callback to each child
for (const auto& child : children) {
callback(child);
// If the child is a Group, recursively traverse it
if (std::holds_alternative<Group>(child)) {
std::get<Group>(child).traverse(callback);
}
}
}

// Add a child node (move semantics)
void Group::addChild(BeamlineNode&& child) { children.push_back(std::move(child)); }

// Add a child node (copy semantics)
void Group::addChild(const BeamlineNode& child) { children.push_back(child); }

// Retrieve all DesignElements (deep)
std::vector<DesignElement> Group::getAllElements() const {
std::vector<DesignElement> elements;
traverse([&elements](const BeamlineNode& node) {
if (std::holds_alternative<DesignElement>(node)) {
elements.push_back(std::get<DesignElement>(node));
}
});
return elements;
}

// Retrieve all DesignSources (deep)
std::vector<DesignSource> Group::getAllSources() const {
std::vector<DesignSource> sources;
traverse([&sources](const BeamlineNode& node) {
if (std::holds_alternative<DesignSource>(node)) {
sources.push_back(std::get<DesignSource>(node));
}
});
return sources;
}

// Retrieve all Groups (deep)
std::vector<Group> Group::getAllGroups() const {
std::vector<Group> groups;
traverse([&groups](const BeamlineNode& node) {
if (std::holds_alternative<Group>(node)) {
groups.push_back(std::get<Group>(node));
}
});
return groups;
}

} // namespace RAYX
52 changes: 52 additions & 0 deletions Intern/rayx-core/src/Design/Group.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#pragma once

#include <functional>
#include <memory>
#include <variant>
#include <vector>

namespace RAYX {

class Group;
class DesignElement;
class DesignSource;

using BeamlineNode = std::variant<DesignElement, DesignSource, Group>;

enum class NodeType { OpticalElement, LightSource, Group };

// Utility function to determine node type
inline NodeType getNodeType(const BeamlineNode& node) {
return std::visit(
[](auto&& element) -> NodeType {
using T = std::decay_t<decltype(element)>;
if constexpr (std::is_same_v<T, DesignElement>) {
return NodeType::OpticalElement;
} else if constexpr (std::is_same_v<T, DesignSource>) {
return NodeType::LightSource;
} else if constexpr (std::is_same_v<T, Group>) {
return NodeType::Group;
}
},
node);
}

class Group {
public:
NodeType getNodeType() const;
const BeamlineNode& getNode(size_t index) const;

void traverse(const std::function<void(const BeamlineNode&)>& callback) const;

void addChild(BeamlineNode&& child);
void addChild(const BeamlineNode& child);

// New methods for retrieving elements, sources, and groups
std::vector<DesignElement> getAllElements() const;
std::vector<DesignSource> getAllSources() const;
std::vector<Group> getAllGroups() const;

private:
std::vector<BeamlineNode> children; // Children of the node
};
} // namespace RAYX

0 comments on commit ca453a7

Please sign in to comment.