ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/RtraceSimulManager.h
Revision: 2.22
Committed: Thu Jan 9 17:25:37 2025 UTC (3 months, 3 weeks ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.21: +2 -1 lines
Log Message:
fix(rxpiece,rxpict): Make sure child processes are waited for

File Contents

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