ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/RtraceSimulManager.h
Revision: 2.19
Committed: Tue Nov 19 20:50:36 2024 UTC (5 months, 2 weeks ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.18: +2 -5 lines
Log Message:
fix: Improved last change for case of same callback with different data

File Contents

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