ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/RtraceSimulManager.h
Revision: 2.14
Committed: Mon Sep 16 19:18:32 2024 UTC (7 months, 2 weeks ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.13: +4 -2 lines
Log Message:
feat: Added method to get a specific string from header

File Contents

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