1 /*******************************************************************************
2  * scene.h
3  *
4  * ---------------------------------------------------------------------------
5  * Persistence of Vision Ray Tracer ('POV-Ray') version 3.7.
6  * Copyright 1991-2013 Persistence of Vision Raytracer Pty. Ltd.
7  *
8  * POV-Ray is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Affero General Public License as
10  * published by the Free Software Foundation, either version 3 of the
11  * License, or (at your option) any later version.
12  *
13  * POV-Ray is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Affero General Public License for more details.
17  *
18  * You should have received a copy of the GNU Affero General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  * ---------------------------------------------------------------------------
21  * POV-Ray is based on the popular DKB raytracer version 2.12.
22  * DKBTrace was originally written by David K. Buck.
23  * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
24  * ---------------------------------------------------------------------------
25  * $File: //depot/public/povray/3.x/source/backend/scene/scene.h $
26  * $Revision: #1 $
27  * $Change: 6069 $
28  * $DateTime: 2013/11/06 11:59:40 $
29  * $Author: chrisc $
30  *******************************************************************************/
31 
32 #ifndef POVRAY_BACKEND_SCENE_H
33 #define POVRAY_BACKEND_SCENE_H
34 
35 #include <vector>
36 #include <string>
37 #include <map>
38 
39 #include <boost/thread.hpp>
40 
41 #include "base/povmscpp.h"
42 #include "base/image/image.h" // TODO - this is just for the GammaCurve stuff; find a different place for that
43 #include "backend/frame.h"
44 #include "backend/povray.h"
45 #include "backend/scene/view.h"
46 #include "backend/scene/atmosph.h"
47 #include "backend/scene/camera.h"
48 #include "backend/lighting/photons.h"
49 #include "backend/lighting/radiosity.h"
50 #include "backend/control/renderbackend.h"
51 //#include "backend/support/bsptree.h"
52 
53 #include "povrayold.h" // TODO
54 
55 namespace pov
56 {
57 
58 using namespace pov_base;
59 
60 class View;
61 class Parser;
62 class FunctionVM;
63 struct FontFileInfo;
64 
65 class BSPTree;
66 
67 /**
68  *	SceneData class representing holding scene specific data.
69  *	For private use by Scene, View and Renderer classes only!
70  *	This class just provides access to scene specific data
71  *	needed in many parts of the code. Be aware that while most
72  *	data is members are public, they shall *not* be modified
73  *	carelessly. Code from POV-Ray 3.6 and earlier does depend
74  *	on simple access of this data all over the old code, so
75  *	this provides an efficient way to reuse all the old code.
76  *	By no means shall this way of data access be used for any
77  *	other newly created classes!!!
78  */
79 class SceneData
80 {
81 		// Scene needs access to the private scene data constructor!
82 		friend class Scene;
83 	public:
84 		/**
85 		 *	Destructor.
86 		 */
87 		~SceneData();
88 
89 		/// scene id
90 		RenderBackend::SceneId sceneId;
91 		/// backend address
92 		POVMSAddress backendAddress;
93 		/// frontend address
94 		POVMSAddress frontendAddress;
95 
96 		/// list of all shape objects
97 		vector<ObjectPtr> objects;
98 		/// list of all global light sources
99 		vector<LightSource *> lightSources;
100 		/// list of all lights that are part of light groups
101 		vector<LightSource *> lightGroupLightSources;
102 		/// function vm managing all functions in scene
103 		FunctionVM *functionVM;
104 		/// atmosphere index of refraction
105 		DBL atmosphereIOR;
106 		/// atmosphere dispersion
107 		DBL atmosphereDispersion;
108 		/// atmospheric media
109 		vector<Media> atmosphere;
110 		/// background color - TODO - allow pattern here (useful for background image maps) [trf]
111 		Colour backgroundColour; // may have a filter/transmit component (but filter is ignored)
112 		/// ambient light in scene
113 		RGBColour ambientLight;
114 		/// TODO - what is this again? [trf]
115 		RGBColour iridWavelengths;
116 		/// fog in scene
117 		FOG *fog;
118 		/// rainbow in scene
119 		RAINBOW *rainbow;
120 		/// skyssphere around scene
121 		SKYSPHERE *skysphere;
122 		/// language version to assume
123 		int languageVersion;
124 		/// true if a #version statement has been encountered
125 		bool languageVersionSet;
126 		/// true if the first #version statement was found after other declarations
127 		bool languageVersionLate;
128 		/// warning level
129 		int warningLevel;
130 		/// string encoding of text
131 		int stringEncoding;
132 		/// default noise generator to use
133 		int noiseGenerator;
134 		/// whether or not the noise generator was explicitly set by the scene - TODO FIXME remove [trf]
135 		bool explicitNoiseGenerator;
136 		/// bounding method selector
137 		unsigned int boundingMethod;
138 		/// What gamma mode to use.
139 		/// One of kPOVList_GammaMode_*.
140 		int gammaMode;
141 		/// Working gamma.
142 		SimpleGammaCurvePtr workingGamma;
143 		/// Working gamma to sRGB encoding/decoding.
144 		GammaCurvePtr workingGammaToSRGB;
145 		/// Whether the user has explicitly specified a default input file gamma. [will be removed in 3.7x]
146 		bool inputFileGammaSet;
147 		/// Default assumed decoding gamma of input files.
148 		SimpleGammaCurvePtr inputFileGamma;
149 
150 		/// distance scaling factor for subsurface scattering effects
151 		DBL mmPerUnit;
152 
153 		/// whether the scene should be rendered with alpha channel
154 		bool outputAlpha;
155 
156 		/// whether to use subsurface light transport
157 		bool useSubsurface;
158 		/// samples for subsurface scattering diffuse contribution
159 		int subsurfaceSamplesDiffuse;
160 		/// samples for subsurface scattering single scattering contribution
161 		int subsurfaceSamplesSingle;
162 		/// whether to compute radiosity contribution to subsurface effects
163 		bool subsurfaceUseRadiosity;
164 
165 		// ********************************************************************************
166 		// temporary variables for BSP testing ... we may or may not keep these come 3.7
167 		// release, depending on whether or not a valid need for them has been demonstrated.
168 		// ********************************************************************************
169 		unsigned int bspMaxDepth;
170 		float bspObjectIsectCost;
171 		float bspBaseAccessCost;
172 		float bspChildAccessCost;
173 		float bspMissChance;
174 
175 		// set if real-time raytracing is enabled.
176 		bool realTimeRaytracing;
177 
178 		// ********************************************************************************
179 		// Old globals from 3.6 and earlier are temporarily kept below. Please carefully
180 		// consider what is added and mark it accordingly if it needs to go away again
181 		// prior to final release! [trf]
182 		// ********************************************************************************
183 
184 		/// number of waves to use in waves and ripples pattern
185 		unsigned int numberOfWaves;
186 
187 		/// maximum trace recursion level allowed
188 		unsigned int parsedMaxTraceLevel;
189 		/// adc bailout
190 		DBL parsedAdcBailout;
191 		/// radiosity settings
192 		SceneRadiositySettings radiositySettings;
193 		RadiositySettings parsedRadiositySettings;
194 
195 		/// generated surface photon map data // TODO FIXME - technically camera-independent, but computed for every view [trf]
196 		PhotonMap surfacePhotonMap;
197 		/// generated media photon map data // TODO FIXME - technically camera-independent, but computed for every view [trf]
198 		PhotonMap mediaPhotonMap;
199 
200 		ScenePhotonSettings photonSettings; // TODO FIXME - is modified! [trf]
201 
202 		// TODO - decide if we want to keep this here
203 		FontFileInfo *TTFonts;
204 
205 		// name of the parsed file
206 		UCS2String inputFile; // TODO - handle differently
207 		UCS2String headerFile;
208 
209 		int defaultFileType;
210 
211 		FrameSettings frameSettings; // TODO - move ???
212 		std::map<string, string> declaredVariables; // TODO - move to parser
213 		Camera parsedCamera; // TODO - handle differently or move to parser
214 		bool clocklessAnimation; // TODO - this is support for an experimental feature and may be changed or removed
215 		vector<Camera> cameras; // TODO - this is support for an experimental feature and may be changed or removed
216 
217 		// this is for fractal support
218 		int Fractal_Iteration_Stack_Length; // TODO - move somewhere else
219 		int Max_Blob_Components; // TODO - move somewhere else
220 		// function pattern support
221 		unsigned int functionPatternCount; // TODO - move somewhere else
222 		// lathe and sor support (bounding cylinders)
223 		unsigned int Max_Bounding_Cylinders; // TODO - move somewhere else
224 		BBOX_TREE *boundingSlabs;
225 
226 		// TODO FIXME move to parser somehow
227 		bool splitUnions; // INI option, defaults to false
228 		bool removeBounds; // INI option, defaults to true
229 
230 		// experimental
231 		BSPTree *tree;
232 		unsigned int numberOfFiniteObjects;
233 		unsigned int numberOfInfiniteObjects;
234 
235 		// BSP statistics // TODO - not sure if this is the best place for stats
236 		unsigned int nodes, splitNodes, objectNodes, emptyNodes, maxObjects, maxDepth, aborts;
237 		float averageObjects, averageDepth, averageAborts, averageAbortObjects;
238 
239 		// ********************************************************************************
240 		// ********************************************************************************
241 
242 		/**
243 		 *  Convenience function to determine the effective SDL version.
244 		 *  Given that version 3.7 and later require the first statement in the file to be
245 		 *  a #version statement, the absence of such a statement can be presumed to
246 		 *  indicate a pre-3.7 scene; this function assumes version 3.62 in that case
247 		 *  (which was the latest 3.6 version when 3.7.0 was released).
248 		 *  @note       It is recommended to use this function only where behaviour differs
249 		 *              significantly from pre-3.7 versions.
250 		 *  @return     The current language version in integer format (e.g. 370 for 3.70)
251 		 *              if explicitly specified, or 362 otherwise.
252 		 */
EffectiveLanguageVersion()253 		inline unsigned int EffectiveLanguageVersion() const
254 		{
255 			if (languageVersionSet)
256 				return languageVersion;
257 			else
258 				return 362;
259 		}
260 
261 		/**
262 		 *	Find a file for reading.
263 		 *	If the file is not available localy, the frontend will be queried.
264 		 *	Variants of the filename with extensions matching file type will
265 		 *	be tried. Only the first file found is returned.
266 		 *	@param	ctx				POVMS message context for the current thread.
267 		 *	@param	filename		Name and optional (partial) path.
268 		 *	@param	stype			File type.
269 		 *	@return					Name of found file or empty string.
270 		 */
271 		UCS2String FindFile(POVMSContext ctx, const UCS2String& filename, unsigned int stype);
272 
273 		/**
274 		 *	Open a file for reading.
275 		 *	If the file is not available localy, the frontend will be queried.
276 		 *	If the frontend has the file, it will be assigned a local temporary
277 		 *	name that is mapped to the specified file name (so repeated access
278 		 *	does not require contacting the frontend) and the file will be
279 		 *	transferred from the frontend to the local system as necessary.
280 		 *	Note that for their first access the frontend will always be asked
281 		 *	to provide the location of the file. Local files are only accessed
282 		 *	within the system specific temporary directory. This prevents
283 		 *	access to files on local systems in case of remote rendering.
284 		 *	Returns NULL if the file could not be found.
285 		 *	@param	ctx				POVMS message context for the current thread.
286 		 *	@param  origname		The original name of the file as in the scene file (could be relative). // TODO FIXME - not needed, just a hack, the source [trf]
287 		 *	@param	filename		Name and optional (partial) path.
288 		 *	@param	stype			File type.
289 		 *	@return					Pointer to the file or NULL. The caller is
290 		 *							responsible for freeing the pointer!
291 		 */
292 		IStream *ReadFile(POVMSContext ctx, const UCS2String& origname, const UCS2String& filename, unsigned int stype); // TODO FIXME - see above and source code [trf]
293 
294 		/**
295 		 *	Open a file given by name and optional (partial) path for writing.
296 		 *	Rather than creating the file in the specified location, a temporary
297 		 *	file will be created and the specified name will be mapped to that
298 		 *	local file. Local files are only accessed within the system specific
299 		 *	temporary directory. This prevents access to fileson local systems
300 		 *  in case of remote rendering. For each neealy created file the
301 		 *	frontend is notified and after rendering the frontend can decide
302 		 *	which files to access. In addition, this allows parsing the same
303 		 *	scene simultaniously more than once as each scene manages its own
304 		 *	set of unique temporary files and thus at no time a file is written
305 		 *	to or read from by more than one scene.
306 		 *	@param	ctx				POVMS message context for the current thread.
307 		 *	@param	filename		Name and optional (partial) path.
308 		 *	@param	stype			File type.
309 		 *	@param	append			True to append data to the file, false otherwise.
310 		 *	@return					Pointer to the file or NULL. The caller is
311 		 *							responsible for freeing the pointer!
312 		 */
313 		OStream *CreateFile(POVMSContext ctx, const UCS2String& filename, unsigned int stype, bool append);
314 	private:
315 #ifdef USE_SCENE_FILE_MAPPING
316 		/// maps scene file names to local file names
317 		std::map<UCS2String, UCS2String> scene2LocalFiles;
318 		/// maps local file names to scene file names
319 		std::map<UCS2String, UCS2String> local2SceneFiles;
320 		/// maps scene file names to temporary file names
321 		std::map<UCS2String, UCS2String> scene2TempFiles;
322 		/// maps temporary file names to scene file names
323 		std::map<UCS2String, UCS2String> temp2SceneFiles;
324 #endif
325 
326 		/**
327 		 *	Create new scene specific data.
328 		 */
329 		SceneData();
330 
331 		/// not available
332 		SceneData(const SceneData&);
333 
334 		/// not available
335 		SceneData& operator=(const SceneData&);
336 };
337 
338 /**
339  *	Scene class representing a POV-Ray camera-independent scene.
340  */
341 class Scene
342 {
343 	public:
344 		/**
345 		 *	Create a new POV-Ray scene. The scene is created with all
346 		 *	default values and it empty. Only after a scene file has
347 		 *	been parsed views can be created. Each scene may only be
348 		 *	parsed once, and it is assumed that the scene structure
349 		 *	remains static after parsing is complete. However, for
350 		 *	each scene,once parsed, many views many be created, and
351 		 *	each view may specify different render quality, size and
352 		 *	camera parameters. This limitation may be lifted in the
353 		 *	future to better support animationss and for example
354 		 *	motion blur, but this can only be supported in POV-Ray
355 		 *	4.0 when all the rendering code is rewritten!
356 		 *	@param	backendAddr		Address of the backend that owns this scene.
357 		 *	@param	frontendAddr	Address of the frontend that owns this scene.
358 		 *	@param	sid				Id of this scene to include with
359 		 *							POVMS messages sent to the frontend.
360 		 */
361 		Scene(POVMSAddress backendAddr, POVMSAddress frontendAddr, RenderBackend::SceneId sid);
362 
363 		/**
364 		 *	Destructor. Parsing will be stopped as necessary.
365 		 */
366 		~Scene();
367 
368 		/**
369 		 *	Start parsing a POV-Ray scene. Be aware that this
370 		 *	method is asynchronous! Threads will be started
371 		 *	to perform the parsing and this method will return.
372 		 *	The frontend is notified by messages of the state
373 		 *	of parsing and all warnings and errors found.
374 		 *	Options shall be in a kPOVObjectClass_ParserOptions
375 		 *	POVMS obect, which is created when parsing the INI
376 		 *	file or command line in the frontend.
377 		 *	@param	parseOptions	Options to use for parsing.
378 		 */
379 		void StartParser(POVMS_Object& parseOptions);
380 
381 		/**
382 		 *	Stop parsing a POV-Ray scene. Parsing may take a few
383 		 *	seconds to stop. Internally stopping is performed by
384 		 *	throwing an exception at well-defined points.
385 		 *	Note that currently if parsing has been stopped, it
386 		 *	*cannot* be started again. Eventually this limitation
387 		 *	will be removed once we have verified that the old
388 		 *	3.6 parser code can properly handle this condition
389 		 *	without leaking memory. [trf]
390 		 *	If parsing is not in progress, no action is taken.
391 		 */
392 		void StopParser();
393 
394 		/**
395 		 *	Pause parsing. Parsing may take a few seconds to
396 		 *	pause. Internally pausing is performed by checking
397 		 *	flag at well-defined points, and if it is true, a
398 		 *	loop will repeatedly set the parser thread to sleep
399 		 *	for a few milliseconds until the pause flag is
400 		 *	cleared again or parsing is stopped.
401 		 *	If parsing is not in progress, no action is taken.
402 		 */
403 		void PauseParser();
404 
405 		/**
406 		 *	Resume parsing that has previously been stopped.
407 		 *	If parsing is not paussed, no action is taken.
408 		 */
409 		void ResumeParser();
410 
411 		/**
412 		 *	Determine if any parser thread is currently running.
413 		 *	@return					True if running, false otherwise.
414 		 */
415 		bool IsParsing();
416 
417 		/**
418 		 *	Determine if parsing is paused.
419 		 *	@return					True if paused, false otherwise.
420 		 */
421 		bool IsPaused();
422 
423 		/**
424 		 *	Determine if a previously run parser thread failed.
425 		 *	@return					True if failed, false otherwise.
426 		 */
427 		bool Failed();
428 
429 		/**
430 		 *	Create a new view of a parsed scene. Note that this method
431 		 *	may only be called after a scene has been parsed successfully.
432 		 *	Note that the view does remain valid even if the scene that
433 		 *	created it is deleted!
434 		 *	@param	width			Width of the view in pixels.
435 		 *	@param	height			Height of the view in pixels.
436 		 *	@param	vid				Id of this view to include with
437 		 *							POVMS messages sent to the frontend.
438 		 *	@return					New view bound to the scene's data.
439 		 */
440 		shared_ptr<View> NewView(unsigned int width, unsigned int height, RenderBackend::ViewId vid);
441 
442 		/**
443 		 *	Get the POVMS frontend address to send messages to the frontend.
444 		 *	@return					Frontend address.
445 		 */
GetFrontendAddress()446 		POVMSAddress GetFrontendAddress() const { return sceneData->frontendAddress; }
447 
448 		/**
449 		 *	Get the current parser statistics for the scene.
450 		 *	Note that this will query each thread, compute the total
451 		 *	and return it.
452 		 *	@param	stats			On return, the current statistics.
453 		 */
454 		void GetStatistics(POVMS_Object& stats);
455 	private:
456 		/// running and pending parser tasks for this scene
457 		TaskQueue parserTasks;
458 		/// scene thread data (i.e. statistics)
459 		vector<SceneThreadData *> sceneThreadData;
460 		/// scene data
461 		shared_ptr<SceneData> sceneData;
462 		/// stop request flag
463 		bool stopRequsted;
464 		/// parser control thread
465 		boost::thread *parserControlThread;
466 
467 		/**
468 		 *	Send the parser statistics upon completion of a parsing.
469 		 *	@param	 taskq			The task queue that executed this method.
470 		 */
471 		void SendStatistics(TaskQueue& taskq);
472 
473 		/**
474 		 *	Send done message (including compatibility data) after parsing.
475 		 *	@param	 taskq			The task queue that executed this method.
476 		 */
477 		void SendDoneMessage(TaskQueue& taskq);
478 
479 		/**
480 		 *	Thread controlling the parser task queue.
481 		 */
482 		void ParserControlThread();
483 };
484 
485 }
486 
487 #endif // POVRAY_BACKEND_SCENE_H
488