ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/RtraceSimulManager.h
Revision: 2.15
Committed: Thu Oct 10 21:02:52 2024 UTC (6 months, 3 weeks ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.14: +5 -3 lines
Log Message:
fix: Allow unsetting of source-ray tracing flag

File Contents

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