ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/RtraceSimulManager.h
Revision: 2.9
Committed: Sat Aug 3 01:54:46 2024 UTC (9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.8: +14 -1 lines
Log Message:
feat(rxtrace): Added header manipulation to base class

File Contents

# Content
1 /* RCSid $Id: RtraceSimulManager.h,v 2.8 2024/05/02 22:10:43 greg Exp $ */
2 /*
3 * RtraceSimulManager.h
4 *
5 * Rtrace simulation manager class declaration (along with base class)
6 * Enqueuing rays will block caller iff #rays >= ThreadsAvail()
7 * Reporting call-backs made from EnqueBundle() and FlushQueue()
8 *
9 * Created by Greg Ward on 11/10/22.
10 */
11
12 #ifndef RtraceSimulManager_h
13 #define RtraceSimulManager_h
14
15 #include "ray.h"
16
17 extern char * octname; // global octree name
18
19 extern int castonly; // doing ray-casting only?
20
21 /// Ray reporting callback method -- returns # successfully reported, -1 to abort
22 typedef int RayReportCall(RAY *r, void *cd);
23
24 /// Multi-threaded simulation manager base class
25 class RadSimulManager {
26 char * header; // header (less intro and format)
27 protected:
28 // Assign ray to subthread (fails if NThreads()<2)
29 bool SplitRay(RAY *r);
30 public:
31 RadSimulManager(const char *octn = NULL) {
32 header = NULL;
33 LoadOctree(octn);
34 }
35 ~RadSimulManager() {
36 Cleanup();
37 }
38 /// Load octree and prepare renderer
39 bool LoadOctree(const char *octn);
40 /// Prepare header from previous input (or clear)
41 /// Normally called during octree load
42 bool NewHeader(const char *fname=NULL);
43 /// Add a string to header (adds newline if none)
44 bool AddHeader(const char *str);
45 /// Append program line to header
46 bool AddHeader(int ac, const char *av[]);
47 /// Get header lines if any
48 const char * GetHeader() const {
49 return header;
50 }
51 /// How many cores are available?
52 static int GetNCores();
53 /// Set number of computation threads (0 => #cores)
54 int SetThreadCount(int nt = 0);
55 /// Check thread count (1 means no multi-threading)
56 int NThreads() const {
57 return ray_pnprocs + !ray_pnprocs;
58 }
59 /// How many threads are currently unoccupied?
60 int ThreadsAvailable() const;
61 /// Are we ready?
62 bool Ready() const {
63 return (octname && nobjects > 0);
64 }
65 /// Process a ray (in subthread), optional result
66 bool ProcessRay(RAY *r);
67 /// Wait for next result (or fail)
68 bool WaitResult(RAY *r);
69 /// Close octree, free data, return status
70 int Cleanup(bool everything = false);
71 };
72
73 /// Flags to control rendering operations
74 enum {RTdoFIFO=1, RTtraceSources=2, RTlimDist=4, RTimmIrrad=8, RTmask=15};
75
76 /// rtrace-like simulation manager (at most one such object)
77 class RtraceSimulManager : public RadSimulManager {
78 RayReportCall * cookedCall; // callback for cooked primary rays
79 void * ccData; // client data for cooked primary rays
80 RayReportCall * traceCall; // call for every ray in tree
81 void * tcData; // client data for traced rays
82 int curFlags; // current operating flags
83 // Call-back for global ray-tracing context
84 static void RTracer(RAY *r);
85 // Call-back for FIFO
86 static int Rfifout(RAY *r);
87 // Check for changes to render flags, etc.
88 bool UpdateMode();
89 protected:
90 RNUMBER lastRayID; // last ray ID assigned
91 public:
92 int rtFlags; // operation (RT*) flags
93 RtraceSimulManager(RayReportCall *cb = NULL, void *cd = NULL,
94 const char *octn = NULL) : RadSimulManager(octn) {
95 lastRayID = 0;
96 rtFlags = curFlags = 0;
97 SetCookedCall(cb, cd);
98 traceCall = NULL; tcData = NULL;
99 }
100 ~RtraceSimulManager() {
101 FlushQueue();
102 }
103 /// Set number of computation threads (0 => #cores)
104 int SetThreadCount(int nt = 0) {
105 if (nt <= 0) nt = castonly ? 1 : GetNCores();
106 if (nt == NThreads()) return nt;
107 if (FlushQueue() < 0) return 0;
108 return RadSimulManager::SetThreadCount(nt);
109 }
110 /// Add ray bundle to queue w/ optional 1st ray ID
111 int EnqueueBundle(const FVECT orig_direc[], int n,
112 RNUMBER rID0 = 0);
113 /// Enqueue a single ray w/ optional ray ID
114 bool EnqueueRay(const FVECT org, const FVECT dir,
115 RNUMBER rID = 0) {
116 if (dir == org+1)
117 return(EnqueueBundle((const FVECT *)org, 1, rID) > 0);
118 FVECT orgdir[2];
119 VCOPY(orgdir[0], org); VCOPY(orgdir[1], dir);
120 return(EnqueueBundle(orgdir, 1, rID) > 0);
121 }
122 /// Set/change cooked ray callback
123 void SetCookedCall(RayReportCall *cb, void *cd = NULL) {
124 if (cookedCall && (cookedCall != cb) | (ccData != cd))
125 FlushQueue();
126 cookedCall = cb;
127 ccData = cb ? cd : NULL;
128 }
129 /// Set/change trace callback
130 void SetTraceCall(RayReportCall *cb, void *cd = NULL) {
131 traceCall = cb;
132 tcData = cb ? cd : NULL;
133 }
134 /// Are we ready?
135 bool Ready() const {
136 return (cookedCall != NULL) | (traceCall != NULL) &&
137 RadSimulManager::Ready();
138 }
139 /// Finish pending rays and complete callbacks (return #sent)
140 int FlushQueue();
141 /// Close octree, free data, return status
142 int Cleanup(bool everything = false) {
143 SetCookedCall(NULL);
144 SetTraceCall(NULL);
145 rtFlags = 0;
146 UpdateMode();
147 lastRayID = 0;
148 return RadSimulManager::Cleanup(everything);
149 }
150 };
151
152 /// Determine if vector is all zeroes
153 inline bool
154 IsZeroVec(const FVECT vec)
155 {
156 return (vec[0] == 0.0) & (vec[1] == 0.0) & (vec[2] == 0.0);
157 }
158
159 #endif /* RtraceSimulManager_h */