ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/RtraceSimulManager.h
Revision: 2.13
Committed: Wed Aug 14 20:05:23 2024 UTC (8 months, 2 weeks ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.12: +2 -2 lines
Log Message:
feat(rxpict): Added new C++ picture rendering tool with multi-processing and spectral output

File Contents

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