ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/RtraceSimulManager.cpp
(Generate patch)

Comparing ray/src/rt/RtraceSimulManager.cpp (file contents):
Revision 2.12 by greg, Sat Aug 3 01:54:46 2024 UTC vs.
Revision 2.24 by greg, Wed Nov 20 17:46:25 2024 UTC

# Line 26 | Line 26 | RadSimulManager::LoadOctree(const char *octn)
26          if (!octn)              // don't support stdin octree
27                  return false;
28  
29 <        NewHeader(octn);        // load header if we can
29 >        NewHeader(octn);        // get octree header
30          ray_init((char *)octn);
31          return true;
32   }
# Line 46 | Line 46 | add2header(char *str, void *p)
46   // Prepare header from previous input (or clear)
47   // Normally called during octree load
48   bool
49 < RadSimulManager::NewHeader(const char *fname)
49 > RadSimulManager::NewHeader(const char *inspec)
50   {
51 <        if (header) {
52 <                free(header); header = NULL;
51 >        if (hlen) {
52 >                free(header); header = NULL; hlen = 0;
53          }
54 <        if (!fname || fname[0] == '!')
54 >        if (!inspec || !*inspec)
55                  return false;
56 <        FILE    *fp = fopen(fname, "rb");
56 >        if (inspec[0] == '!')           // save command as header?
57 >                return AddHeader(inspec+1);
58 >                                        // attempt to read from file
59 >        FILE    *fp = fopen(inspec, "rb");
60 >        if (!fp) return false;
61          bool    ok = (getheader(fp, add2header, this) >= 0);
62          fclose(fp);
63          return ok;
64   }
65  
66 < // Add a string to header (adds newline if none)
66 > // Add a string to header (adds newline if missing)
67   bool
68   RadSimulManager::AddHeader(const char *str)
69   {
70          if (!str) return false;
71          int     len = strlen(str);
72 <        if (!len || str[0] == '\n') return false;
73 <        int     olen = 0;
74 <        if (header) {
75 <                olen = strlen(header);
76 <                header = (char *)realloc(header, olen+len+2);
77 <        } else
72 >        while (len && (str[len-1] == '\n') | (str[len-1] == '\r'))
73 >                --len;                  // don't copy EOL(s)
74 >        if (!len)
75 >                return false;
76 >        if (hlen)
77 >                header = (char *)realloc(header, hlen+len+2);
78 >        else
79                  header = (char *)malloc(len+2);
80 <        if (!header) return false;
81 <        strcpy(header+olen, str);
82 <        if (str[len-1] != '\n') {
78 <                header[olen+len++] = '\n';
79 <                header[olen+len] = '\0';
80 >        if (!header) {
81 >                hlen = 0;               // XXX should report?
82 >                return false;
83          }
84 +        memcpy(header+hlen, str, len);
85 +        hlen += len;
86 +        header[hlen++] = '\n';          // add single EOL
87 +        header[hlen] = '\0';
88          return true;
89   }
90  
# Line 99 | Line 106 | check_special(const char *s)
106  
107   // Append program line to header
108   bool
109 < RadSimulManager::AddHeader(int ac, const char *av[])
109 > RadSimulManager::AddHeader(int ac, char *av[])
110   {
111          if ((ac <= 0) | !av) return false;
112          int     len = 0;
# Line 108 | Line 115 | RadSimulManager::AddHeader(int ac, const char *av[])
115                  if (!av[n]) return false;
116                  len += strlen(av[n]) + 3;
117          }
118 <        int     hlen = 0;
112 <        if (header) {                   // add to header
113 <                hlen = strlen(header);
118 >        if (hlen)                       // add to header
119                  header = (char *)realloc(header, hlen+len+1);
120 <        } else
120 >        else
121                  header = (char *)malloc(len+1);
122 +
123          for (n = 0; n < ac; n++) {
124                  int     c = check_special(av[n]);
125 <                if (c) {                // need to quote argument?
126 <                        if (c == '"') c = '\'';
125 >                len = strlen(av[n]);
126 >                if (c | !len) {         // need to quote argument?
127 >                        if ((c == '"') | (c == '\n')) c = '\'';
128                          else c = '"';
129                          header[hlen++] = c;
130                          strcpy(header+hlen, av[n]);
131 <                        hlen += strlen(av[n]);
131 >                        hlen += len;
132                          header[hlen++] = c;
133                  } else {
134                          strcpy(header+hlen, av[n]);
135 <                        hlen += strlen(av[n]);
135 >                        hlen += len;
136                  }
137                  header[hlen++] = ' ';
138          }
# Line 134 | Line 141 | RadSimulManager::AddHeader(int ac, const char *av[])
141          return true;
142   }
143  
144 + // Look for specific header keyword, return value
145 + const char *
146 + RadSimulManager::GetHeadStr(const char *key, bool inOK) const
147 + {
148 +        if (!key | !hlen || strchr(key, '\n'))
149 +                return NULL;
150 +        if (inOK)                       // skip leading spaces?
151 +                while (isspace(*key)) key++;
152 +
153 +        const int       klen = strlen(key);
154 +        if (!klen)
155 +                return NULL;
156 +        const char *    cp = header;
157 +        while (*cp) {
158 +                if (inOK) {             // skip leading spaces?
159 +                        while (isspace(*cp) && *cp++ != '\n')
160 +                                ;
161 +                        if (cp[-1] == '\n')
162 +                                continue;
163 +                }
164 +                if (!strncmp(cp, key, klen))
165 +                        return cp+klen; // found it!
166 +
167 +                while (*cp && *cp++ != '\n')
168 +                        ;
169 +        }
170 +        return NULL;
171 + }
172 +
173   // How many processors are available?
174   int
175   RadSimulManager::GetNCores()
# Line 145 | Line 181 | RadSimulManager::GetNCores()
181   int
182   RadSimulManager::SetThreadCount(int nt)
183   {
184 <        if (!Ready())
149 <                return 0;
184 >        if (!Ready()) return 0;
185  
186          if (nt <= 0) nt = castonly ? 1 : GetNCores();
187  
# Line 160 | Line 195 | RadSimulManager::SetThreadCount(int nt)
195          return NThreads();
196   }
197  
163 // Assign ray to subthread (fails if NThreads()<2)
164 bool
165 RadSimulManager::SplitRay(RAY *r)
166 {
167        if (!ray_pnprocs || ThreadsAvailable() < 1)
168                return false;
169
170        return (ray_psend(r) > 0);
171 }
172
198   // Process a ray (in subthread), optional result
199 < bool
199 > int
200   RadSimulManager::ProcessRay(RAY *r)
201   {
202 <        if (!Ready()) return false;
202 >        if (!Ready()) return -1;
203  
204          if (!ray_pnprocs) {     // single-threaded mode?
205                  samplendx++;
206                  rayvalue(r);
207 <                return true;
207 >                return 1;
208          }
209 <        int     rv = ray_pqueue(r);
185 <        if (rv < 0) {
186 <                error(WARNING, "ray tracing process(es) died");
187 <                return false;
188 <        }
189 <        return (rv > 0);
209 >        return ray_pqueue(r);
210   }
211  
212   // Wait for next result (or fail)
# Line 203 | Line 223 | RadSimulManager::WaitResult(RAY *r)
223   int
224   RadSimulManager::Cleanup(bool everything)
225   {
226 +        if (ray_pnprocs < 0)
227 +                return 0;               // skip in child process
228 +        NewHeader();
229          if (!ray_pnprocs)
230                  ray_done(everything);
231          else
# Line 210 | Line 233 | RadSimulManager::Cleanup(bool everything)
233          return 0;
234   }
235  
213 // How many threads are currently unoccupied?
214 int
215 RadSimulManager::ThreadsAvailable() const
216 {
217        if (!ray_pnprocs) return 1;
218
219        return ray_pnidle;
220 }
221
236   // Global pointer to simulation manager for trace call-back (only one)
237   static const RtraceSimulManager *       ourRTsimMan = NULL;
238  
# Line 240 | Line 254 | RtraceSimulManager::Rfifout(RAY *r)
254   bool
255   RtraceSimulManager::UpdateMode()
256   {
243        rtFlags &= RTmask;
257          if (!cookedCall)
258                  rtFlags &= ~RTdoFIFO;
259          if (!traceCall)
# Line 248 | Line 261 | RtraceSimulManager::UpdateMode()
261          if (rtFlags & RTimmIrrad)
262                  rtFlags &= ~RTlimDist;
263  
264 <        int     misMatch = rtFlags ^ curFlags;
264 >        int     misMatch = (rtFlags ^ curFlags) & RTmask;
265                                  // updates based on toggled flags
266 <        if (misMatch & RTtraceSources) {
266 >        if (((misMatch & RTtraceSources) != 0) & (nsources > 0)) {
267 >                int     nt = NThreads();
268 >                if (nt > 1) {
269 >                        if (FlushQueue() < 0)
270 >                                return false;
271 >                        SetThreadCount(1);
272 >                }
273 >                int     sn = nsources;
274                  if (rtFlags & RTtraceSources) {
275 <                        for (int sn = 0; sn < nsources; sn++)
275 >                        srcFollowed.NewBitMap(nsources);
276 >                        while (sn--) {
277 >                                if (source[sn].sflags & SFOLLOW)
278 >                                        continue;
279                                  source[sn].sflags |= SFOLLOW;
280 <                } else          // cannot undo this...
281 <                        rtFlags |= RTtraceSources;
280 >                                srcFollowed.Set(sn);
281 >                        }
282 >                } else {
283 >                        while (sn--)
284 >                                if (srcFollowed.Check(sn))
285 >                                        source[sn].sflags &= ~SFOLLOW;
286 >                        srcFollowed.NewBitMap(0);
287 >                }
288 >                if (nt > 1) SetThreadCount(nt);
289          }
290          if (misMatch & RTdoFIFO && FlushQueue() < 0)
291                  return false;
# Line 285 | Line 315 | extern "C" int m_normal(OBJREC *m, RAY *r);
315   static void
316   rayirrad(RAY *r)
317   {
318 <                                        /* pretend we hit surface */
319 <        r->rxt = r->rot = 1e-5;
320 <        VSUM(r->rop, r->rorg, r->rdir, r->rot);
321 <        r->ron[0] = -r->rdir[0];
322 <        r->ron[1] = -r->rdir[1];
323 <        r->ron[2] = -r->rdir[2];
318 >                                        /* orientation -> normal */
319 >        VCOPY(r->ron, r->rdir);
320 >                                        /* pretend normal incidence */
321 >        r->rdir[0] = -r->ron[0];
322 >        r->rdir[1] = -r->ron[1];
323 >        r->rdir[2] = -r->ron[2];
324          r->rod = 1.0;
325 +                                        /* counterfeit other params */
326 +        r->rxt = r->rot = 1e-4;
327 +                                        /* move comfortably above sample pos. */
328 +        VSUM(r->rop, r->rorg, r->ron, r->rot);
329 +                                        /* leap-frog for pretend origin */
330 +        VSUM(r->rorg, r->rop, r->ron, r->rot);
331                                          /* compute result */
332          r->revf = raytrace;
333          m_normal(&Lamb, r);
# Line 318 | Line 354 | RtraceSimulManager::EnqueueBundle(const FVECT orig_dir
354          int     nqueued = 0;
355          RAY     res;
356  
357 <        if (!Ready())
322 <                return -1;
357 >        if (!Ready()) return -1;
358  
359          if (castonly && !cookedCall)
360                  error(INTERNAL, "EnqueueBundle() called in castonly mode without cookedCall");
# Line 333 | Line 368 | RtraceSimulManager::EnqueueBundle(const FVECT orig_dir
368          while (n-- > 0) {               // queue each ray
369                  VCOPY(res.rorg, orig_direc[0]);
370                  VCOPY(res.rdir, orig_direc[1]);
371 +                res.rmax = .0;
372                  orig_direc += 2;
373                  rayorigin(&res, PRIMARY, NULL, NULL);
374                  res.rno = rID0 ? (lastRayID = rID0++) : ++lastRayID;
# Line 349 | Line 385 | RtraceSimulManager::EnqueueBundle(const FVECT orig_dir
385                                  if (ray_fifo_in(&res) < 0)
386                                          return -1;
387                                  sendRes = false;
388 <                        } else
389 <                                sendRes &= ProcessRay(&res);
388 >                        } else {
389 >                                int     rv = ProcessRay(&res);
390 >                                if (rv < 0)
391 >                                        return -1;
392 >                                sendRes &= (rv > 0);
393 >                        }
394                  } else if (ThreadsAvailable() < NThreads() &&
395                                  FlushQueue() < 0)
396                          return -1;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines