3 Commits

Author SHA1 Message Date
Paolo Andreetto
e4d1e6af63 Minor changed in beam tracing 2021-02-23 14:54:35 +01:00
Paolo Andreetto
3cea59bc67 3D beam 2020-12-27 17:18:56 +01:00
Paolo Andreetto
a2bd38fc2c Beam tracer: draft implementation 2020-12-26 12:01:36 +01:00
2 changed files with 135 additions and 49 deletions

View File

@@ -25,12 +25,11 @@
#include <iostream> #include <iostream>
#include <unordered_map>
#include "VoxRaytracer.h" #include "VoxRaytracer.h"
#include "Utils.h" #include "Utils.h"
#define unlikely(expr) __builtin_expect(!!(expr), 0)
inline float fast_sign(float f) { return 1 - 2 * (f < 0); } inline float fast_sign(float f) { return 1 - 2 * (f < 0); }
namespace uLib { namespace uLib {
@@ -49,16 +48,17 @@ void VoxRaytracer::RayData::AddElement(Id_t id, float L)
void VoxRaytracer::RayData::AppendRay(const VoxRaytracer::RayData &in) void VoxRaytracer::RayData::AppendRay(const VoxRaytracer::RayData &in)
{ {
if (unlikely(!in.m_Data.size())) { if (!in.m_Data.size())
{
std::cout << "Warinig: PoCA on exit border!\n"; std::cout << "Warinig: PoCA on exit border!\n";
return;
} }
else if (unlikely(!m_Data.size())) { else if (!m_Data.size())
{
m_Data = in.m_Data; m_Data = in.m_Data;
std::cout << "Warinig: PoCA on entrance border!\n"; std::cout << "Warinig: PoCA on entrance border!\n";
return;
} }
else { else
{
// Opzione 1) un voxel in piu' // // Opzione 1) un voxel in piu' //
m_Data.reserve(m_Data.size() + in.m_Data.size()); m_Data.reserve(m_Data.size() + in.m_Data.size());
m_Data.insert(m_Data.end(), in.m_Data.begin(), in.m_Data.end()); m_Data.insert(m_Data.end(), in.m_Data.begin(), in.m_Data.end());
@@ -82,16 +82,22 @@ void VoxRaytracer::RayData::AppendRay(const VoxRaytracer::RayData &in)
void VoxRaytracer::RayData::PrintSelf(std::ostream &o) void VoxRaytracer::RayData::PrintSelf(std::ostream &o)
{ {
o << "Ray: total lenght " << m_TotalLength << "\n"; o << "Ray: total lenght " << m_TotalLength << "\n";
std::vector<Element>::iterator it; for(std::vector<Element>::iterator it = m_Data.begin(); it < m_Data.end(); ++it)
for(it = m_Data.begin(); it < m_Data.end(); ++it) {
o << "[ " << (*it).vox_id << ", " << (*it).L << "] \n"; o << "[ " << (*it).vox_id << ", " << (*it).L << "] \n";
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//// RAY TRACER //////////////////////////////////////////////////////////////// //// RAY TRACER ////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
VoxRaytracer::VoxRaytracer(StructuredGrid &image) : m_Image(&image)
{
m_scale << (m_Image->GetWorldMatrix() * Vector4f(1,0,0,0)).norm(),
(m_Image->GetWorldMatrix() * Vector4f(0,1,0,0)).norm(),
(m_Image->GetWorldMatrix() * Vector4f(0,0,1,0)).norm();
}
bool VoxRaytracer::GetEntryPoint(const HLine3f &line, HPoint3f &pt) bool VoxRaytracer::GetEntryPoint(const HLine3f &line, HPoint3f &pt)
{ {
@@ -150,9 +156,7 @@ bool VoxRaytracer::GetExitPoint(const HLine3f &line, HPoint3f &pt)
} }
VoxRaytracer::RayData VoxRaytracer::TraceBetweenPoints(const HPoint3f &in, VoxRaytracer::RayData VoxRaytracer::TraceBetweenPoints(const HPoint3f &in, const HPoint3f &out) const
const HPoint3f &out)
const
{ {
RayData ray; RayData ray;
Vector4f pt1 = m_Image->GetLocalPoint(in); Vector4f pt1 = m_Image->GetLocalPoint(in);
@@ -162,53 +166,138 @@ const
float l = s.head(3).norm(); float l = s.head(3).norm();
Vector3f L(l/s(0), l/s(1), l/s(2)); Vector3f L(l/s(0), l/s(1), l/s(2));
// Vector3f scale; // FIXXX
// scale << (m_Image->GetWorldMatrix() * Vector4f(1,0,0,0)).norm(),
// (m_Image->GetWorldMatrix() * Vector4f(0,1,0,0)).norm(),
// (m_Image->GetWorldMatrix() * Vector4f(0,0,1,0)).norm();
Vector3f offset; Vector3f offset;
for(int i=0;i<3;++i) offset(i) = (s(i)>=0) - (pt1(i)-floor(pt1(i))) ; for(int i=0;i<3;++i)
{
offset(i) = (s(i)>=0) - (pt1(i)-floor(pt1(i)));
}
offset = offset.cwiseProduct(L).cwiseAbs(); offset = offset.cwiseProduct(L).cwiseAbs();
L = L.cwiseAbs(); L = L.cwiseAbs();
//---- Check if the ray only crosses one voxel //---- Check if the ray only crosses one voxel
Vector3i vid = m_Image->Find(in); Vector3i vid = m_Image->Find(in);
if(vid == m_Image->Find(out)){ if (vid == m_Image->Find(out))
ray.AddElement(m_Image->Map(vid),s.norm()); {
return ray; ray.AddElement(m_Image->Map(vid),s.norm());
return ray;
} }
//---- Otherwise, loop until ray is finished //---- Otherwise, loop until ray is finished
int id; float d; int id; float d;
while(l>0){ while (l>0)
{
d = offset.minCoeff(&id);
d = offset.minCoeff(&id); if (m_Image->IsInsideGrid(vid))
{
ray.AddElement(m_Image->Map(vid), d * m_scale(id));
}
if(m_Image->IsInsideGrid(vid)){ vid(id) += (int)fast_sign(s(id));
ray.AddElement(m_Image->Map(vid), d * m_scale(id) );
}
// nan check // l -= d;
// if(unlikely(!isFinite(d * scale(id)))) { offset.array() -= d;
// std:: cout << "NAN in raytracer\n"; offset(id) = fmin(L(id),l);
// exit(1);
// }
vid(id) += (int)fast_sign(s(id));
l -= d;
offset.array() -= d;
offset(id) = fmin(L(id),l);
} }
return ray; return ray;
} }
static int encode_v(Vector3i in)
{
return ((in[0] + 1) << 4) + ((in[1] + 1) << 2) + in[2] + 1;
}
static Vector3i decode_v(int in)
{
Vector3i result {
((in & 48) >> 4) - 1,
((in & 12) >> 2) - 1,
(in & 3) - 1
};
return result;
}
VoxRaytracer::RayData VoxRaytracer::BeamBetweenPoints(const HPoint3f &in, const HPoint3f &out, Vector3i thickness) const
{
if (thickness[0] < 0) thickness[0] = 0;
if (thickness[1] < 0) thickness[1] = 0;
if (thickness[2] < 0) thickness[2] = 0;
Vector3i zero_v { 0, 0, 0 };
RayData ray = TraceBetweenPoints(in, out);
if (thickness == zero_v || ray.Data().size() == 0) return ray;
/*
* Calculate the forbidden relocations
*/
std::unordered_map<int, int> ban_points(26);
Vector3i prevPos = m_Image->UnMap(ray.Data()[0].vox_id);
Vector3i currDir = zero_v;
int currLen = 1;
for (int k = 1; k < ray.Data().size(); k++)
{
Vector3i currPos = m_Image->UnMap(ray.Data()[k].vox_id);
Vector3i offset = currPos - prevPos;
prevPos = currPos;
if (k == 1) currDir = offset;
if (offset == currDir)
{
currLen++;
continue;
}
int enc_v = encode_v(currDir);
if (ban_points.find(enc_v) == ban_points.end())
{
ban_points.emplace(enc_v, currLen);
}
else if (currLen > ban_points[enc_v])
{
ban_points[enc_v] = currLen;
}
currDir = offset;
currLen = 2;
}
/*
* Calculate the beam section
*/
std::vector<Vector3i> relocs;
relocs.push_back(zero_v);
/*
* Compose the beam
*/
RayData beam;
for (auto iter : ray.Data())
{
Vector3i rPos = m_Image->UnMap(iter.vox_id);
for (Vector3i reloc : relocs)
{
Vector3i cPos = rPos + reloc;
if (!m_Image->IsInsideGrid(cPos)) continue;
beam.AddElement(m_Image->Map(cPos), iter.L);
}
}
return beam;
}
// 20150528 SV for absorbed muons // 20150528 SV for absorbed muons
VoxRaytracer::RayData VoxRaytracer::TraceLine(const HLine3f &line) const VoxRaytracer::RayData VoxRaytracer::TraceLine(const HLine3f &line) const
{ {
RayData ray; RayData ray;
Vector4f pt = m_Image->GetLocalPoint(line.origin); Vector4f pt = m_Image->GetLocalPoint(line.origin);
Vector4f s = m_Image->GetLocalPoint(line.direction); Vector4f s = m_Image->GetLocalPoint(line.direction);
@@ -250,4 +339,4 @@ VoxRaytracer::RayData VoxRaytracer::TraceLine(const HLine3f &line) const
return ray; return ray;
} }
} } //end of namespace uLib

View File

@@ -38,7 +38,8 @@ namespace uLib {
class VoxRaytracer { class VoxRaytracer {
public: public:
class RayData { class RayData
{
public: public:
RayData() : m_TotalLength(0) {} RayData() : m_TotalLength(0) {}
@@ -62,14 +63,8 @@ public:
Scalarf m_TotalLength; Scalarf m_TotalLength;
}; };
public:
public: VoxRaytracer(StructuredGrid &image);
VoxRaytracer(StructuredGrid &image) : m_Image(&image) {
m_scale <<
(m_Image->GetWorldMatrix() * Vector4f(1,0,0,0)).norm(),
(m_Image->GetWorldMatrix() * Vector4f(0,1,0,0)).norm(),
(m_Image->GetWorldMatrix() * Vector4f(0,0,1,0)).norm();
}
bool GetEntryPoint(const HLine3f &line, HPoint3f &pt); bool GetEntryPoint(const HLine3f &line, HPoint3f &pt);
@@ -77,6 +72,8 @@ public:
RayData TraceBetweenPoints(const HPoint3f &in, const HPoint3f &out) const; RayData TraceBetweenPoints(const HPoint3f &in, const HPoint3f &out) const;
RayData BeamBetweenPoints(const HPoint3f &in, const HPoint3f &out, Vector3i thickness) const;
RayData TraceLine(const HLine3f &line) const; RayData TraceLine(const HLine3f &line) const;
inline StructuredGrid* GetImage() const { return this->m_Image; } inline StructuredGrid* GetImage() const { return this->m_Image; }