POVRAY.C 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327
  1. /****************************************************************************
  2. * povray.c
  3. *
  4. * This module contains the entry routine for the raytracer and the code to
  5. * parse the parameters on the command line.
  6. *
  7. * from Persistence of Vision(tm) Ray Tracer
  8. * Copyright 1996,1999 Persistence of Vision Team
  9. *---------------------------------------------------------------------------
  10. * NOTICE: This source code file is provided so that users may experiment
  11. * with enhancements to POV-Ray and to port the software to platforms other
  12. * than those supported by the POV-Ray Team. There are strict rules under
  13. * which you are permitted to use this file. The rules are in the file
  14. * named POVLEGAL.DOC which should be distributed with this file.
  15. * If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  16. * Team Coordinator by email to team-coord@povray.org or visit us on the web at
  17. * http://www.povray.org. The latest version of POV-Ray may be found at this site.
  18. *
  19. * This program is based on the popular DKB raytracer version 2.12.
  20. * DKBTrace was originally written by David K. Buck.
  21. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  22. *
  23. *****************************************************************************/
  24. #include <ctype.h>
  25. #include <time.h> /* BP */
  26. #include "frame.h" /* common to ALL modules in this program */
  27. #include "povproto.h"
  28. #include "bezier.h"
  29. #include "blob.h"
  30. #include "bbox.h"
  31. #include "cones.h"
  32. #include "csg.h"
  33. #include "discs.h"
  34. #include "express.h"
  35. #include "fractal.h"
  36. #include "hfield.h"
  37. #include "lathe.h"
  38. #include "lighting.h"
  39. #include "mem.h"
  40. #include "mesh.h"
  41. #include "polysolv.h"
  42. #include "objects.h"
  43. #include "octree.h"
  44. #include "parse.h"
  45. #include "pigment.h"
  46. #include "point.h"
  47. #include "poly.h"
  48. #include "polygon.h"
  49. #include "povray.h"
  50. #include "optin.h"
  51. #include "optout.h"
  52. #include "quadrics.h"
  53. #include "pgm.h"
  54. #include "png_pov.h"
  55. #include "ppm.h"
  56. #include "prism.h"
  57. #include "radiosit.h"
  58. #include "render.h"
  59. #include "sor.h"
  60. #include "spheres.h"
  61. #include "super.h"
  62. #include "targa.h"
  63. #include "texture.h"
  64. #include "tokenize.h"
  65. #include "torus.h"
  66. #include "triangle.h"
  67. #include "truetype.h"
  68. #include "userio.h" /*Error,Warning,Init_Text_Streams*/
  69. #include "lbuffer.h"
  70. #include "vbuffer.h"
  71. /*****************************************************************************
  72. * Local preprocessor defines
  73. ******************************************************************************/
  74. /* Flags for the variable store. */
  75. #define STORE 1
  76. #define RESTORE 2
  77. /*****************************************************************************
  78. * Local typedefs
  79. ******************************************************************************/
  80. /*****************************************************************************
  81. * Local variables
  82. ******************************************************************************/
  83. /* The frame. */
  84. FRAME Frame;
  85. /* Options and display stuff. */
  86. char Color_Bits;
  87. int Display_Started;
  88. int Abort_Test_Every;
  89. int Experimental_Flag;
  90. /* Current stage of the program. */
  91. int Stage;
  92. /* Flag if -h option will show help screens. */
  93. int Help_Available;
  94. /* File and parsing stuff. */
  95. Opts opts;
  96. COUNTER stats[MaxStat];
  97. COUNTER totalstats[MaxStat];
  98. int Num_Echo_Lines; /* May make user setable later - CEY*/
  99. int Echo_Line_Length; /* May make user setable later - CEY*/
  100. int Number_Of_Files;
  101. FILE *stat_file;
  102. FILE_HANDLE *Output_File_Handle;
  103. char Actual_Output_Name[FILE_NAME_LENGTH];
  104. /* Timing stuff .*/
  105. time_t tstart, tstop;
  106. DBL tparse, trender, tparse_total, trender_total;
  107. /* Variable used by vector macros. */
  108. DBL VTemp;
  109. volatile int Stop_Flag;
  110. /* Flag if close_all() was already called. */
  111. static int closed_flag;
  112. int pre_init_flag=0;
  113. char *Option_String_Ptr;
  114. DBL Clock_Delta;
  115. /*****************************************************************************
  116. * Static functions
  117. ******************************************************************************/
  118. static void init_vars (void);
  119. static void destroy_libraries (void);
  120. static void fix_up_rendering_window (void);
  121. static void fix_up_animation_values (void);
  122. static void fix_up_scene_name (void);
  123. static void set_output_file_handle (void);
  124. static void setup_output_file_name (void);
  125. static void open_output_file (void);
  126. static void FrameRender (void);
  127. static void init_statistics (COUNTER *);
  128. static void sum_statistics (COUNTER *, COUNTER *);
  129. static void variable_store (int Flag);
  130. static int Has_Extension (char *name);
  131. static unsigned closest_power_of_2 (unsigned theNumber);
  132. static void init_shellouts (void);
  133. static void destroy_shellouts (void);
  134. /*****************************************************************************
  135. *
  136. * FUNCTION
  137. *
  138. * main
  139. *
  140. * INPUT
  141. *
  142. * OUTPUT
  143. *
  144. * RETURNS
  145. *
  146. * AUTHOR
  147. *
  148. * POV-Ray Team
  149. *
  150. * DESCRIPTION
  151. *
  152. * -
  153. *
  154. * CHANGES
  155. *
  156. * -
  157. *
  158. ******************************************************************************/
  159. #ifdef NOCMDLINE /* a main() by any other name... */
  160. #ifdef ALTMAIN
  161. MAIN_RETURN_TYPE alt_main()
  162. #else
  163. MAIN_RETURN_TYPE main()
  164. #endif
  165. #else
  166. #ifdef ALTMAIN
  167. MAIN_RETURN_TYPE alt_main(int argc, char **argv)
  168. #else
  169. MAIN_RETURN_TYPE main(int argc, char **argv)
  170. #endif
  171. #endif /* ...would be a lot less hassle!! :-) AAC */
  172. {
  173. register int i;
  174. int Diff_Frame;
  175. DBL Diff_Clock;
  176. SHELLRET Pre_Scene_Result, Frame_Result;
  177. /* Attention all ALTMAIN people! See comments attached to this function*/
  178. pre_init_povray();
  179. /* Startup povray. */
  180. Stage = STAGE_STARTUP;
  181. STARTUP_POVRAY
  182. /* Print banner and credit info. */
  183. Stage = STAGE_BANNER;
  184. PRINT_CREDITS
  185. PRINT_OTHER_CREDITS
  186. #ifndef NOCMDLINE
  187. /* Print help screens. */
  188. if (argc == 1)
  189. {
  190. Print_Help_Screens();
  191. }
  192. #endif
  193. /* Initialize variables. */
  194. init_vars();
  195. Stage = STAGE_ENVIRONMENT;
  196. READ_ENV_VAR
  197. Stage = STAGE_INI_FILE;
  198. /* Read parameters from POVRAY.INI */
  199. PROCESS_POVRAY_INI
  200. #ifndef NOCMDLINE
  201. /* Parse the command line parameters */
  202. Stage = STAGE_COMMAND_LINE;
  203. Help_Available = (argc == 2);
  204. for (i = 1 ; i < argc ; i++ )
  205. {
  206. parse_option_line(argv[i]);
  207. }
  208. #endif
  209. /* Strip path and extension off input name to create scene name */
  210. fix_up_scene_name ();
  211. /* Redirect text streams [SCD 2/95] */
  212. Open_Text_Streams();
  213. /* Write .INI file [SCD 2/95] */
  214. Write_INI_File();
  215. ALT_WRITE_INI_FILE
  216. /* Make sure clock is okay, validate animation parameters */
  217. fix_up_animation_values();
  218. /* Fix-up rendering window values if necessary. */
  219. fix_up_rendering_window();
  220. /* Set output file handle for options screen. */
  221. set_output_file_handle();
  222. /* Print options used. */
  223. Print_Options();
  224. /* BEGIN SECTION */
  225. /* VARIOUS INITIALIZATION THAT ONLY NEEDS TO BE DONE 1/EXECUTION */
  226. /* Set up noise-tables. */
  227. Initialize_Noise();
  228. Diff_Clock = opts.FrameSeq.FinalClock - opts.FrameSeq.InitialClock;
  229. if (opts.Options & CYCLIC_ANIMATION)
  230. {
  231. Diff_Frame = opts.FrameSeq.FinalFrame - opts.FrameSeq.InitialFrame + 1;
  232. }
  233. else
  234. {
  235. Diff_Frame = opts.FrameSeq.FinalFrame - opts.FrameSeq.InitialFrame;
  236. }
  237. Clock_Delta = ((Diff_Frame==0)?0:Diff_Clock/Diff_Frame);
  238. /* END SECTION */
  239. /* Execute the first shell-out command */
  240. Pre_Scene_Result=(POV_SHELLOUT_CAST)POV_SHELLOUT(PRE_SCENE_SHL);
  241. /* Loop over each frame */
  242. if (Pre_Scene_Result != ALL_SKIP_RET)
  243. {
  244. if (Pre_Scene_Result != SKIP_ONCE_RET)
  245. {
  246. for (opts.FrameSeq.FrameNumber = opts.FrameSeq.InitialFrame,
  247. opts.FrameSeq.Clock_Value = opts.FrameSeq.InitialClock;
  248. opts.FrameSeq.FrameNumber <= opts.FrameSeq.FinalFrame;
  249. opts.FrameSeq.FrameNumber++,
  250. opts.FrameSeq.Clock_Value += Clock_Delta)
  251. {
  252. setup_output_file_name();
  253. /* Execute a shell-out command before tracing */
  254. Frame_Result=(POV_SHELLOUT_CAST)POV_SHELLOUT(PRE_FRAME_SHL);
  255. if (Frame_Result == ALL_SKIP_RET)
  256. {
  257. break;
  258. }
  259. if (Frame_Result != SKIP_ONCE_RET)
  260. {
  261. FrameRender();
  262. /* Execute a shell-out command after tracing */
  263. Frame_Result = (POV_SHELLOUT_CAST)POV_SHELLOUT(POST_FRAME_SHL);
  264. if ((Frame_Result==SKIP_ONCE_RET) || (Frame_Result==ALL_SKIP_RET))
  265. {
  266. break;
  267. }
  268. }
  269. }
  270. /* Print total stats ... */
  271. if(opts.FrameSeq.FrameType==FT_MULTIPLE_FRAME)
  272. {
  273. Statistics("\nTotal Statistics");
  274. opts.FrameSeq.FrameNumber--;
  275. PRINT_STATS(totalstats);
  276. opts.FrameSeq.FrameNumber++;
  277. }
  278. }
  279. /* Execute the final shell-out command */
  280. POV_SHELLOUT(POST_SCENE_SHL);
  281. }
  282. /* And finish. */
  283. Terminate_POV(0);
  284. MAIN_RETURN_STATEMENT
  285. } /* main */
  286. /*****************************************************************************
  287. *
  288. * FUNCTION
  289. *
  290. * FrameRender
  291. *
  292. * INPUT
  293. *
  294. * OUTPUT
  295. *
  296. * RETURNS
  297. *
  298. * AUTHOR
  299. *
  300. * POV-Ray Team
  301. *
  302. * DESCRIPTION
  303. *
  304. * Do all that is necessary for rendering a single frame, including parsing
  305. *
  306. * CHANGES
  307. *
  308. * Feb 1996: Make sure we are displaying when doing a mosaic preview [AED]
  309. *
  310. ******************************************************************************/
  311. static void FrameRender()
  312. {
  313. unsigned long hours, minutes;
  314. DBL seconds, t_total;
  315. /* Store start time for parse. */
  316. START_TIME
  317. /* Parse the scene file. */
  318. Status_Info("\n\nParsing...");
  319. opts.Do_Stats=FALSE;
  320. Init_Random_Generators();
  321. Parse();
  322. Destroy_Random_Generators();
  323. opts.Do_Stats=TRUE;
  324. if (opts.Options & RADIOSITY)
  325. {
  326. Experimental_Flag |= EF_RADIOS;
  327. }
  328. if (Experimental_Flag)
  329. {
  330. Warning(0.0,"Warning: This rendering uses the following experimental features:\n");
  331. if (Experimental_Flag & EF_RADIOS)
  332. {
  333. Warning(0.0," radiosity");
  334. }
  335. Warning(0.0,".\nThe design and implementation of these features is likely to\n");
  336. Warning(0.0,"change in future versions of POV-Ray. Full backward compatibility\n");
  337. Warning(0.0,"with the current implementation is NOT guaranteed.\n");
  338. }
  339. Experimental_Flag=0;
  340. /* Switch off standard anti-aliasing. */
  341. if ((Frame.Camera->Aperture != 0.0) && (Frame.Camera->Blur_Samples > 0))
  342. {
  343. opts.Options &= ~ANTIALIAS;
  344. Warning(0.0, "Focal blur is used. Standard antialiasing is switched off.\n");
  345. }
  346. /* Create the bounding box hierarchy. */
  347. Stage = STAGE_SLAB_BUILDING;
  348. if (opts.Use_Slabs)
  349. {
  350. Status_Info("\nCreating bounding slabs.");
  351. }
  352. /* Init module specific stuff. */
  353. Initialize_Atmosphere_Code();
  354. Initialize_BBox_Code();
  355. Initialize_Lighting_Code();
  356. Initialize_Mesh_Code();
  357. Initialize_VLBuffer_Code();
  358. Initialize_Radiosity_Code();
  359. /* Always call this to print number of objects. */
  360. Build_Bounding_Slabs(&Root_Object);
  361. /* Create the vista buffer. */
  362. Build_Vista_Buffer();
  363. /* Create the light buffers. */
  364. Build_Light_Buffers();
  365. /* Create blob queue. */
  366. Init_Blob_Queue();
  367. /* Save variable values. */
  368. variable_store(STORE);
  369. /* Open output file and if we are continuing an interrupted trace,
  370. * read in the previous file settings and any data there. This has to
  371. * be done before any image-size related allocations, since the settings
  372. * in a resumed file take precedence over that specified by the user. [AED]
  373. */
  374. open_output_file();
  375. /* Start the display. */
  376. if (opts.Options & DISPLAY)
  377. {
  378. Status_Info ("\nDisplaying...");
  379. POV_DISPLAY_INIT(Frame.Screen_Width, Frame.Screen_Height);
  380. Display_Started = TRUE;
  381. /* Display vista tree. */
  382. Draw_Vista_Buffer();
  383. }
  384. /* Get things ready for ray tracing (misc init, mem alloc) */
  385. Initialize_Renderer();
  386. /* This had to be taken out of open_output_file() because we don't have
  387. * the final image size until the output file has been opened, so we can't
  388. * initialize the display until we know this, which in turn means we can't
  389. * read the rendered part before the display is initialized. [AED]
  390. */
  391. if ((opts.Options & DISKWRITE) && (opts.Options & CONTINUE_TRACE))
  392. {
  393. Read_Rendered_Part(Actual_Output_Name);
  394. if (opts.Last_Line > Frame.Screen_Height)
  395. opts.Last_Line = Frame.Screen_Height;
  396. if (opts.Last_Column > Frame.Screen_Width)
  397. opts.Last_Column = Frame.Screen_Width;
  398. }
  399. /* Get parsing time. */
  400. STOP_TIME
  401. tparse = TIME_ELAPSED
  402. /* Get total parsing time. */
  403. tparse_total += tparse;
  404. /* Store start time for trace. */
  405. START_TIME
  406. if(opts.FrameSeq.FrameType==FT_MULTIPLE_FRAME)
  407. {
  408. t_total=tparse_total+trender_total;
  409. SPLIT_TIME(t_total,&hours,&minutes,&seconds);
  410. Render_Info("\n %02ld:%02ld:%02.0f so far, ",hours,minutes,seconds);
  411. Render_Info("Rendering frame %d, going to %d.",
  412. opts.FrameSeq.FrameNumber, opts.FrameSeq.FinalFrame);
  413. }
  414. /* Start tracing. */
  415. Stage = STAGE_RENDERING;
  416. POV_PRE_RENDER
  417. Status_Info ("\nRendering...\r");
  418. /* Macro for setting up any special FP options */
  419. CONFIG_MATH
  420. /* Ok, go for it - trace the picture. */
  421. /* If radiosity preview has been done, we are continuing a trace, so it
  422. * is important NOT to do the preview, even if the user requests it, as it
  423. * will cause discontinuities in radiosity shading by (probably) calculating
  424. * a few more radiosity values.
  425. */
  426. if ( !opts.Radiosity_Preview_Done )
  427. {
  428. if ( opts.Options & RADIOSITY )
  429. {
  430. /* Note that radiosity REQUIRES a mosaic preview prior to main scan */
  431. Start_Tracing_Mosaic_Smooth(opts.PreviewGridSize_Start, opts.PreviewGridSize_End);
  432. }
  433. else
  434. {
  435. if (opts.Options & PREVIEW && opts.Options & DISPLAY)
  436. {
  437. Start_Tracing_Mosaic_Preview(opts.PreviewGridSize_Start, opts.PreviewGridSize_End);
  438. }
  439. }
  440. }
  441. switch (opts.Tracing_Method)
  442. {
  443. case 2 :
  444. Start_Adaptive_Tracing();
  445. break;
  446. case 1 :
  447. default:
  448. Start_Non_Adaptive_Tracing();
  449. }
  450. /* We're done. */
  451. /* Record time so well spent before file close so it can be in comments */
  452. STOP_TIME
  453. trender = TIME_ELAPSED
  454. /* Close out our file */
  455. if (Output_File_Handle)
  456. {
  457. Close_File(Output_File_Handle);
  458. }
  459. Stage = STAGE_SHUTDOWN;
  460. POV_PRE_SHUTDOWN
  461. /* DESTROY lots of stuff */
  462. Deinitialize_Atmosphere_Code();
  463. Deinitialize_BBox_Code();
  464. Deinitialize_Lighting_Code();
  465. Deinitialize_Mesh_Code();
  466. Deinitialize_VLBuffer_Code();
  467. Deinitialize_Radiosity_Code();
  468. Destroy_Blob_Queue();
  469. Destroy_Light_Buffers();
  470. Destroy_Vista_Buffer();
  471. Destroy_Bounding_Slabs();
  472. Destroy_Frame();
  473. Terminate_Renderer();
  474. FreeFontInfo();
  475. Free_Iteration_Stack();
  476. POV_POST_SHUTDOWN
  477. /* Get total render time. */
  478. trender_total += trender;
  479. POV_DISPLAY_FINISHED
  480. if ((opts.Options & DISPLAY) && Display_Started)
  481. {
  482. POV_DISPLAY_CLOSE
  483. Display_Started = FALSE;
  484. }
  485. if (opts.histogram_on)
  486. write_histogram (opts.Histogram_File_Name) ;
  487. Status_Info("\nDone Tracing");
  488. /* Print stats ... */
  489. PRINT_STATS(stats);
  490. if(opts.FrameSeq.FrameType==FT_MULTIPLE_FRAME)
  491. {
  492. /* Add them up */
  493. sum_statistics(totalstats, stats);
  494. /* ... and then clear them for the next frame */
  495. init_statistics(stats);
  496. }
  497. /* Restore variable values. */
  498. variable_store(RESTORE);
  499. }
  500. /*****************************************************************************
  501. *
  502. * FUNCTION
  503. *
  504. * fix_up_rendering_window
  505. *
  506. * INPUT
  507. *
  508. * OUTPUT
  509. *
  510. * RETURNS
  511. *
  512. * AUTHOR
  513. *
  514. * POV-Ray Team
  515. *
  516. * DESCRIPTION
  517. *
  518. * Fix wrong window and mosaic preview values.
  519. *
  520. * CHANGES
  521. *
  522. * -
  523. *
  524. ******************************************************************************/
  525. static void fix_up_rendering_window()
  526. {
  527. int temp;
  528. if (opts.First_Column_Percent > 0.0)
  529. opts.First_Column = (int) (Frame.Screen_Width * opts.First_Column_Percent);
  530. if (opts.First_Line_Percent > 0.0)
  531. opts.First_Line = (int) (Frame.Screen_Height * opts.First_Line_Percent);
  532. /* The decrements are a fudge factor that used to be in OPTIN.C
  533. * but it messed up Write_INI_File so its moved here.
  534. */
  535. if (opts.First_Column <= 0)
  536. opts.First_Column = 0;
  537. else
  538. opts.First_Column--;
  539. if (opts.First_Line <= 0)
  540. opts.First_Line = 0;
  541. else
  542. opts.First_Line--;
  543. if ((opts.Last_Column == -1) && (opts.Last_Column_Percent <= 1.0))
  544. opts.Last_Column = (int) (Frame.Screen_Width * opts.Last_Column_Percent);
  545. if ((opts.Last_Line == -1) && (opts.Last_Line_Percent <= 1.0))
  546. opts.Last_Line = (int) (Frame.Screen_Height * opts.Last_Line_Percent);
  547. if (opts.Last_Line == -1)
  548. opts.Last_Line = Frame.Screen_Height;
  549. if (opts.Last_Column == -1)
  550. opts.Last_Column = Frame.Screen_Width;
  551. if (opts.Last_Column < 0 || opts.Last_Column > Frame.Screen_Width)
  552. opts.Last_Column = Frame.Screen_Width;
  553. if (opts.Last_Line > Frame.Screen_Height)
  554. opts.Last_Line = Frame.Screen_Height;
  555. /* Fix up Mosaic Preview values */
  556. opts.PreviewGridSize_Start=max(1,opts.PreviewGridSize_Start);
  557. opts.PreviewGridSize_End=max(1,opts.PreviewGridSize_End);
  558. if ((temp=closest_power_of_2((unsigned)opts.PreviewGridSize_Start))!=opts.PreviewGridSize_Start)
  559. {
  560. Warning(0.0,"Preview_Start_Size must be a power of 2. Changing to %d.\n",temp);
  561. opts.PreviewGridSize_Start=temp;
  562. }
  563. if ((temp=closest_power_of_2((unsigned)opts.PreviewGridSize_End))!=opts.PreviewGridSize_End)
  564. {
  565. Warning(0.0,"Preview_End_Size must be a power of 2. Changing to %d.\n",temp);
  566. opts.PreviewGridSize_End=temp;
  567. }
  568. /* End must be less than or equal to start */
  569. if (opts.PreviewGridSize_End > opts.PreviewGridSize_Start)
  570. opts.PreviewGridSize_End = opts.PreviewGridSize_Start;
  571. if (opts.PreviewGridSize_Start > 1)
  572. {
  573. opts.PreviewGridSize_End=max(opts.PreviewGridSize_End,2);
  574. opts.Options |= PREVIEW;
  575. }
  576. else
  577. {
  578. opts.Options &= ~PREVIEW;
  579. }
  580. /* Set histogram size here so it is available for Print_Options, and
  581. * make sure that it has an integer number of pixels/bucket. */
  582. if (opts.histogram_on)
  583. {
  584. if (opts.histogram_x == 0 || opts.histogram_x > Frame.Screen_Width)
  585. opts.histogram_x = Frame.Screen_Width;
  586. else if (opts.histogram_x < Frame.Screen_Width)
  587. opts.histogram_x = Frame.Screen_Width / ((Frame.Screen_Width +
  588. opts.histogram_x - 1) / opts.histogram_x);
  589. if (opts.histogram_y == 0 || opts.histogram_y > Frame.Screen_Height)
  590. opts.histogram_y = Frame.Screen_Height;
  591. else if (opts.histogram_y < Frame.Screen_Height)
  592. opts.histogram_y = Frame.Screen_Height / ((Frame.Screen_Height +
  593. opts.histogram_y - 1) /opts.histogram_y);
  594. }
  595. }
  596. /*****************************************************************************
  597. *
  598. * FUNCTION
  599. *
  600. * fix_up_animation_values
  601. *
  602. * INPUT
  603. *
  604. * OUTPUT
  605. *
  606. * RETURNS
  607. *
  608. * AUTHOR
  609. *
  610. * POV-Ray Team
  611. *
  612. * DESCRIPTION
  613. *
  614. * Validate animation parameters, compute subset values
  615. *
  616. * CHANGES
  617. *
  618. * -
  619. *
  620. ******************************************************************************/
  621. static void fix_up_animation_values()
  622. {
  623. float ClockDiff;
  624. int FrameDiff;
  625. int FrameIncr;
  626. float ClockPerFrameIncr;
  627. int NumFrames;
  628. if (opts.FrameSeq.FinalFrame != -1)
  629. {
  630. opts.FrameSeq.FrameType = FT_MULTIPLE_FRAME;
  631. if (opts.FrameSeq.Clock_Value != 0.0)
  632. {
  633. Warning(0.0,"Attempted to set single clock value in multi frame\nanimation. Clock value overridden.\n");
  634. }
  635. }
  636. else
  637. {
  638. if (opts.FrameSeq.Clock_Value != 0.0)
  639. {
  640. opts.FrameSeq.FrameType = FT_SINGLE_FRAME;
  641. }
  642. }
  643. if (opts.FrameSeq.FrameType == FT_SINGLE_FRAME)
  644. {
  645. /*
  646. * These are dummy values that will work for single_frame,
  647. * even in an animation loop.
  648. */
  649. opts.FrameSeq.InitialFrame = 0;
  650. opts.FrameSeq.FinalFrame = 0;
  651. opts.FrameSeq.InitialClock = opts.FrameSeq.Clock_Value;
  652. opts.FrameSeq.FinalClock = 0.0;
  653. }
  654. else
  655. {
  656. /* FrameType==FT_MULTIPLE_FRAME */
  657. if(opts.FrameSeq.InitialFrame == -1)
  658. {
  659. opts.FrameSeq.InitialFrame = 1;
  660. }
  661. if (opts.FrameSeq.FinalFrame < opts.FrameSeq.InitialFrame)
  662. {
  663. Error("Final frame %d is less than Start Frame %d.\n",
  664. opts.FrameSeq.FinalFrame, opts.FrameSeq.InitialFrame);
  665. }
  666. ClockDiff = opts.FrameSeq.FinalClock-opts.FrameSeq.InitialClock;
  667. if (opts.Options & CYCLIC_ANIMATION)
  668. {
  669. FrameDiff = opts.FrameSeq.FinalFrame-opts.FrameSeq.InitialFrame+1;
  670. }
  671. else
  672. {
  673. FrameDiff = opts.FrameSeq.FinalFrame-opts.FrameSeq.InitialFrame;
  674. }
  675. ClockPerFrameIncr = (FrameDiff == 0) ? 0 : (ClockDiff/FrameDiff);
  676. /* Calculate width, which is an integer log10 */
  677. NumFrames = opts.FrameSeq.FinalFrame;
  678. opts.FrameSeq.FrameNumWidth = 1;
  679. while (NumFrames >= 10)
  680. {
  681. opts.FrameSeq.FrameNumWidth++;
  682. NumFrames = NumFrames / 10;
  683. }
  684. if (opts.FrameSeq.FrameNumWidth > POV_NAME_MAX-1)
  685. {
  686. Error("Can't render %d frames requiring %d chars with %d width filename.\n",
  687. opts.FrameSeq.FinalFrame - opts.FrameSeq.InitialFrame + 1,
  688. opts.FrameSeq.FrameNumWidth, POV_NAME_MAX);
  689. }
  690. /* STARTING FRAME SUBSET */
  691. if (opts.FrameSeq.SubsetStartPercent != DBL_VALUE_UNSET)
  692. {
  693. FrameIncr = FrameDiff * opts.FrameSeq.SubsetStartPercent + 0.5; /* w/rounding */
  694. opts.FrameSeq.SubsetStartFrame = opts.FrameSeq.InitialFrame + FrameIncr;
  695. }
  696. if (opts.FrameSeq.SubsetStartFrame != INT_VALUE_UNSET)
  697. {
  698. NumFrames = opts.FrameSeq.SubsetStartFrame - opts.FrameSeq.InitialFrame;
  699. opts.FrameSeq.InitialFrame = opts.FrameSeq.SubsetStartFrame;
  700. opts.FrameSeq.InitialClock = opts.FrameSeq.InitialClock + NumFrames * ClockPerFrameIncr;
  701. }
  702. /* ENDING FRAME SUBSET */
  703. if (opts.FrameSeq.SubsetEndPercent != DBL_VALUE_UNSET)
  704. {
  705. /*
  706. * By this time, we have possibly lost InitialFrame, so we calculate
  707. * it via FinalFrame-FrameDiff
  708. */
  709. FrameIncr = FrameDiff * opts.FrameSeq.SubsetEndPercent + 0.5; /* w/rounding */
  710. opts.FrameSeq.SubsetEndFrame = (opts.FrameSeq.FinalFrame - FrameDiff) + FrameIncr;
  711. }
  712. if (opts.FrameSeq.SubsetEndFrame != INT_VALUE_UNSET)
  713. {
  714. NumFrames = opts.FrameSeq.FinalFrame - opts.FrameSeq.SubsetEndFrame;
  715. opts.FrameSeq.FinalFrame = opts.FrameSeq.SubsetEndFrame;
  716. opts.FrameSeq.FinalClock = opts.FrameSeq.FinalClock - NumFrames * ClockPerFrameIncr;
  717. }
  718. /*
  719. * Now that we have everything calculated, we check FinalFrame
  720. * and InitialFrame one more time, in case the subsets messed them up
  721. */
  722. if (opts.FrameSeq.FinalFrame < opts.FrameSeq.InitialFrame)
  723. {
  724. Error("Final frame %d is less than Start Frame %d\ndue to bad subset specification.\n",
  725. opts.FrameSeq.FinalFrame, opts.FrameSeq.InitialFrame);
  726. }
  727. }
  728. /* Needed for pre-render shellout fixup */
  729. opts.FrameSeq.FrameNumber = opts.FrameSeq.InitialFrame;
  730. opts.FrameSeq.Clock_Value = opts.FrameSeq.InitialClock;
  731. }
  732. /*****************************************************************************
  733. *
  734. * FUNCTION
  735. *
  736. * fix_up_scene_name
  737. *
  738. * INPUT
  739. *
  740. * OUTPUT
  741. *
  742. * RETURNS
  743. *
  744. * AUTHOR
  745. *
  746. * POV-Ray Team
  747. *
  748. * DESCRIPTION
  749. *
  750. * Strip path and extention of input file to create scene name
  751. *
  752. * CHANGES
  753. *
  754. ******************************************************************************/
  755. static void fix_up_scene_name()
  756. {
  757. int i, l;
  758. char temp[FILE_NAME_LENGTH];
  759. if ((l=strlen(opts.Input_File_Name)-1)<1)
  760. {
  761. strcpy(opts.Scene_Name,opts.Input_File_Name);
  762. return;
  763. }
  764. strcpy(temp,opts.Input_File_Name);
  765. for (i=l;i>0;i--)
  766. {
  767. if (temp[i]==FILENAME_SEPARATOR)
  768. {
  769. break;
  770. }
  771. if (temp[i]=='.')
  772. {
  773. temp[i]=0;
  774. break;
  775. }
  776. }
  777. i=strlen(temp)-1;
  778. while ((i>0) && (temp[i]!=FILENAME_SEPARATOR))
  779. i--;
  780. if (temp[i]==FILENAME_SEPARATOR)
  781. i++;
  782. strcpy(opts.Scene_Name,&(temp[i]));
  783. }
  784. /*****************************************************************************
  785. *
  786. * FUNCTION
  787. *
  788. * set_output_file_handle
  789. *
  790. * INPUT
  791. *
  792. * OUTPUT
  793. *
  794. * RETURNS
  795. *
  796. * AUTHOR
  797. *
  798. * POV-Ray Team
  799. *
  800. * DESCRIPTION
  801. *
  802. * Set the output file handle according to the file type used.
  803. *
  804. * CHANGES
  805. *
  806. * Oct 95 - Removed test where the output file handle was only set if
  807. * output_to_file was TRUE. The output file handle structure
  808. * contains a pointer to read line, which is used by the continue
  809. * trace option. If you tried a continue trace with file output
  810. * manually turned OFF, then a GPF would occur due to a call to a
  811. * NULL function pointer.
  812. *
  813. ******************************************************************************/
  814. static void set_output_file_handle()
  815. {
  816. char *def_ext = NULL;
  817. char temp[FILE_NAME_LENGTH];
  818. switch (opts.OutputFormat)
  819. {
  820. case '\0':
  821. case 's' :
  822. case 'S' : Output_File_Handle = GET_SYS_FILE_HANDLE(); def_ext=SYS_DEF_EXT; break;
  823. case 't' :
  824. case 'T' :
  825. case 'c' :
  826. case 'C' : Output_File_Handle = Get_Targa_File_Handle(); def_ext=".tga"; break;
  827. case 'p' :
  828. case 'P' : Output_File_Handle = Get_PPM_File_Handle(); def_ext=".ppm"; break;
  829. case 'n' :
  830. case 'N' : Output_File_Handle = Get_Png_File_Handle(); def_ext=".png"; break;
  831. case 'd' :
  832. case 'D' : Error ("Dump format no longer supported.\n"); break;
  833. case 'r' :
  834. case 'R' : Error ("Raw format no longer supported.\n"); break;
  835. default : Error ("Unrecognized output file format %c.\n",
  836. opts.OutputFormat);
  837. }
  838. Output_File_Handle->file_type = IMAGE_FTYPE;
  839. strcpy(temp,opts.Output_File_Name);
  840. POV_SPLIT_PATH(temp,opts.Output_Path,opts.Output_File_Name);
  841. if (opts.Output_File_Name[0] == '\0')
  842. {
  843. sprintf(opts.Output_File_Name, "%s%s",opts.Scene_Name,def_ext);
  844. }
  845. else if (!(opts.Options & TO_STDOUT))
  846. {
  847. if (!Has_Extension(opts.Output_File_Name))
  848. {
  849. strcat(opts.Output_File_Name, def_ext);
  850. }
  851. }
  852. strcpy(opts.Output_Numbered_Name,opts.Output_File_Name);
  853. }
  854. /*****************************************************************************
  855. *
  856. * FUNCTION
  857. *
  858. * setup_output_file_name
  859. *
  860. * INPUT
  861. *
  862. * OUTPUT
  863. *
  864. * RETURNS
  865. *
  866. * AUTHOR
  867. *
  868. * POV-Ray Team
  869. *
  870. * DESCRIPTION
  871. *
  872. * Determine the file name for this frame. For an animation, the frame
  873. * number is inserted into the file name.
  874. *
  875. * CHANGES
  876. *
  877. * Jan-97 [esp] Added conditional after getcwd, because Metrowerks getcwd
  878. * function appends a path separator on output.
  879. *
  880. ******************************************************************************/
  881. static void setup_output_file_name()
  882. {
  883. char number_string[10];
  884. char separator_string[2] = {FILENAME_SEPARATOR, 0} ;
  885. char *plast_period;
  886. int available_characters;
  887. int ilast_period;
  888. int fname_chars;
  889. /* This will create the real name for the file */
  890. if(opts.FrameSeq.FrameType!=FT_MULTIPLE_FRAME ||
  891. opts.Options & TO_STDOUT)
  892. {
  893. strcpy(opts.Output_Numbered_Name,opts.Output_File_Name);
  894. }
  895. else
  896. {
  897. /*
  898. * This is the maximum number of characters that can be used of the
  899. * original filename. This will ensure that enough space is available
  900. * for the frame number in the filename
  901. */
  902. available_characters = POV_NAME_MAX-opts.FrameSeq.FrameNumWidth;
  903. plast_period = strrchr(opts.Output_File_Name, '.');
  904. if (plast_period == NULL)
  905. {
  906. Error("Illegal file name %s -- no extension.\n", opts.Output_File_Name);
  907. }
  908. ilast_period = plast_period - opts.Output_File_Name;
  909. fname_chars = ilast_period;
  910. if (fname_chars > available_characters)
  911. {
  912. /* Only give the warning once */
  913. if (opts.FrameSeq.FrameNumber == opts.FrameSeq.InitialFrame)
  914. {
  915. Warning(0.0, "Need to cut the output filename by %d characters.\n",
  916. ilast_period - available_characters);
  917. }
  918. fname_chars = available_characters;
  919. }
  920. /* Perform actual generation of filename */
  921. strncpy(opts.Output_Numbered_Name, opts.Output_File_Name, (unsigned)fname_chars);
  922. /* strncpy doesn't terminate if strlen(opts.Output_File_Name)<fname_chars */
  923. opts.Output_Numbered_Name[fname_chars]='\0';
  924. sprintf(number_string, "%0*d", opts.FrameSeq.FrameNumWidth, opts.FrameSeq.FrameNumber);
  925. strcat(opts.Output_Numbered_Name, number_string);
  926. strcat(opts.Output_Numbered_Name, &opts.Output_File_Name[ilast_period]);
  927. }
  928. if (strlen (opts.Output_Path) == 0)
  929. {
  930. getcwd (opts.Output_Path, sizeof (opts.Output_Path) - 1) ;
  931. /* on some systems (MacOS) getcwd adds the path separator on the end */
  932. /* so only add it if it isn't already there... [esp] */
  933. if (opts.Output_Path[strlen(opts.Output_Path)-1] != FILENAME_SEPARATOR)
  934. strcat (opts.Output_Path, separator_string) ;
  935. }
  936. strncpy (Actual_Output_Name,opts.Output_Path, sizeof (Actual_Output_Name));
  937. strncat (Actual_Output_Name,opts.Output_Numbered_Name, sizeof (Actual_Output_Name));
  938. /*
  939. Debug_Info("P='%s',O='%s',A='%s',N='%s'\n",opts.Output_Path,
  940. opts.Output_Numbered_Name, Actual_Output_Name,opts.Output_Numbered_Name);
  941. */
  942. }
  943. /*****************************************************************************
  944. *
  945. * FUNCTION
  946. *
  947. * open_output_file
  948. *
  949. * INPUT
  950. *
  951. * OUTPUT
  952. *
  953. * RETURNS
  954. *
  955. * AUTHOR
  956. *
  957. * POV-Ray Team
  958. *
  959. * DESCRIPTION
  960. *
  961. * Open file and read in previous image if continued trace is on.
  962. *
  963. * GOTCHA : This saves a POINTER to the file name, so the file
  964. * name must exist over the entire life/use of the file
  965. *
  966. * CHANGES
  967. *
  968. * -
  969. *
  970. ******************************************************************************/
  971. static void open_output_file()
  972. {
  973. int Buffer_Size;
  974. if (opts.Options & DISKWRITE)
  975. {
  976. Stage = STAGE_FILE_INIT;
  977. if (opts.Options & BUFFERED_OUTPUT)
  978. {
  979. Buffer_Size=opts.File_Buffer_Size;
  980. }
  981. else
  982. {
  983. Buffer_Size=0;
  984. }
  985. if (opts.Options & CONTINUE_TRACE)
  986. {
  987. Stage = STAGE_CONTINUING;
  988. if (Open_File(Output_File_Handle, Actual_Output_Name,
  989. &Frame.Screen_Width, &Frame.Screen_Height, Buffer_Size,
  990. READ_MODE) != 1)
  991. {
  992. Close_File(Output_File_Handle);
  993. Warning (0.0,"Error opening continue trace output file.\n");
  994. Warning (0.0,"Opening new output file %s.\n",Actual_Output_Name);
  995. /* Turn off continue trace */
  996. opts.Options &= ~CONTINUE_TRACE;
  997. if (Open_File(Output_File_Handle, Actual_Output_Name,
  998. &Frame.Screen_Width, &Frame.Screen_Height, Buffer_Size,
  999. WRITE_MODE) != 1)
  1000. {
  1001. Error ("Error opening output file.");
  1002. }
  1003. }
  1004. }
  1005. else
  1006. {
  1007. if (Open_File(Output_File_Handle, Actual_Output_Name,
  1008. &Frame.Screen_Width, &Frame.Screen_Height, Buffer_Size,
  1009. WRITE_MODE) != 1)
  1010. {
  1011. Error ("Error opening output file.");
  1012. }
  1013. }
  1014. }
  1015. }
  1016. /*****************************************************************************
  1017. *
  1018. * FUNCTION
  1019. *
  1020. * init_vars
  1021. *
  1022. * INPUT
  1023. *
  1024. * OUTPUT
  1025. *
  1026. * RETURNS
  1027. *
  1028. * AUTHOR
  1029. *
  1030. * POV-Ray Team
  1031. *
  1032. * DESCRIPTION
  1033. *
  1034. * Initialize all global variables.
  1035. *
  1036. * CHANGES
  1037. *
  1038. * -
  1039. *
  1040. ******************************************************************************/
  1041. static void init_vars()
  1042. {
  1043. Stage=STAGE_INIT;
  1044. opts.Abort_Test_Counter = Abort_Test_Every ;
  1045. Abort_Test_Every = 1;
  1046. opts.AntialiasDepth = 3;
  1047. opts.Antialias_Threshold = 0.3;
  1048. opts.BBox_Threshold = 25;
  1049. Color_Bits = 8;
  1050. opts.DisplayFormat = '0';
  1051. Display_Started = FALSE;
  1052. opts.File_Buffer_Size = 0;
  1053. opts.First_Column = 0;
  1054. opts.First_Column_Percent = 0.0;
  1055. opts.First_Line = 0;
  1056. opts.First_Line_Percent = 0.0;
  1057. Frame.Screen_Height = 100;
  1058. Frame.Screen_Width = 100;
  1059. Root_Object = NULL;
  1060. free_istack = NULL;
  1061. opts.JitterScale = 1.0;
  1062. opts.Language_Version = 3.1;
  1063. opts.Last_Column = -1;
  1064. opts.Last_Column_Percent = 1.0;
  1065. opts.Last_Line = -1;
  1066. opts.Last_Line_Percent = 1.0;
  1067. opts.PreviewGridSize_Start = 1;
  1068. opts.PreviewGridSize_End = 1;
  1069. opts.Library_Paths[0] = NULL;
  1070. opts.Library_Path_Index = 0;
  1071. Max_Intersections = 64; /*128*/
  1072. Number_Of_Files = 0;
  1073. Number_of_istacks = 0;
  1074. opts.Options = USE_VISTA_BUFFER + USE_LIGHT_BUFFER + JITTER +
  1075. DISKWRITE + REMOVE_BOUNDS;
  1076. opts.OutputFormat = DEFAULT_OUTPUT_FORMAT;
  1077. opts.OutputQuality = 8;
  1078. Output_File_Handle = NULL;
  1079. opts.Output_Numbered_Name[0]='\0';
  1080. opts.Output_File_Name[0]='\0';
  1081. opts.Output_Path[0]='\0';
  1082. opts.PaletteOption = '3';
  1083. opts.Quality = 9;
  1084. opts.Quality_Flags = QUALITY_9;
  1085. opts.DisplayGamma = DEFAULT_DISPLAY_GAMMA;
  1086. /*
  1087. * If DisplayGamma == 2.2, then GammaFactor == .45, which is what we want.
  1088. */
  1089. opts.GammaFactor = DEFAULT_ASSUMED_GAMMA/opts.DisplayGamma;
  1090. opts.FrameSeq.FrameType = FT_SINGLE_FRAME;
  1091. opts.FrameSeq.Clock_Value = 0.0;
  1092. opts.FrameSeq.InitialFrame = 1;
  1093. opts.FrameSeq.InitialClock = 0.0;
  1094. opts.FrameSeq.FinalFrame = INT_VALUE_UNSET;
  1095. opts.FrameSeq.FrameNumWidth = 0;
  1096. opts.FrameSeq.FinalClock = 1.0;
  1097. opts.FrameSeq.SubsetStartFrame = INT_VALUE_UNSET;
  1098. opts.FrameSeq.SubsetStartPercent = DBL_VALUE_UNSET;
  1099. opts.FrameSeq.SubsetEndFrame = INT_VALUE_UNSET;
  1100. opts.FrameSeq.SubsetEndPercent = DBL_VALUE_UNSET;
  1101. opts.FrameSeq.Field_Render_Flag = FALSE;
  1102. opts.FrameSeq.Odd_Field_Flag = FALSE;
  1103. opts.Radiosity_Brightness = 3.3;
  1104. opts.Radiosity_Count = 100;
  1105. opts.Radiosity_Dist_Max = 0.; /* default calculated in Radiosity_Initialize */
  1106. opts.Radiosity_Error_Bound = .4;
  1107. opts.Radiosity_Gray = .5; /* degree to which gathered light is grayed */
  1108. opts.Radiosity_Low_Error_Factor = .8;
  1109. opts.Radiosity_Min_Reuse = .015;
  1110. opts.Radiosity_Nearest_Count = 6;
  1111. opts.Radiosity_Recursion_Limit = 1;
  1112. opts.Radiosity_Quality = 6; /* Q-flag value for light gathering */
  1113. opts.Radiosity_File_ReadOnContinue = 1;
  1114. opts.Radiosity_File_SaveWhileRendering = 1;
  1115. opts.Radiosity_File_AlwaysReadAtStart = 0;
  1116. opts.Radiosity_File_KeepOnAbort = 1;
  1117. opts.Radiosity_File_KeepAlways = 0;
  1118. init_statistics(stats);
  1119. init_statistics(totalstats);
  1120. strcpy (opts.Input_File_Name, "OBJECT.POV");
  1121. opts.Scene_Name[0]='\0';
  1122. opts.Ini_Output_File_Name[0]='\0';
  1123. opts.Use_Slabs=TRUE;
  1124. Num_Echo_Lines = 5; /* May make user setable later - CEY*/
  1125. Echo_Line_Length = 180; /* May make user setable later - CEY*/
  1126. closed_flag = FALSE;
  1127. Stop_Flag = FALSE;
  1128. trender = trender_total = 0.0;
  1129. tparse = tparse_total = 0.0;
  1130. histogram_grid = NULL ;
  1131. opts.histogram_on = FALSE ;
  1132. opts.histogram_type = NONE ;
  1133. opts.Histogram_File_Name[0] = '\0';
  1134. Histogram_File_Handle = NULL ;
  1135. /*
  1136. * Note that late initialization of the histogram_x and histogram_y
  1137. * variables is done in fix_up_rendering_window, if they aren't specified
  1138. * on the command line. This is because they are based on the image
  1139. * dimensions, and we can't be certain that we have this info at the
  1140. * time we parse the histogram options in optin.c. [AED]
  1141. */
  1142. opts.histogram_x = opts.histogram_y = 0 ;
  1143. max_histogram_value = 0 ;
  1144. opts.Tracing_Method = 1;
  1145. Experimental_Flag = 0;
  1146. Make_Pigment_Entries();
  1147. }
  1148. /*****************************************************************************
  1149. *
  1150. * FUNCTION
  1151. *
  1152. * init_statistics
  1153. *
  1154. * INPUT
  1155. *
  1156. * OUTPUT
  1157. *
  1158. * RETURNS
  1159. *
  1160. * AUTHOR
  1161. *
  1162. * POV-Ray Team
  1163. *
  1164. * DESCRIPTION
  1165. *
  1166. * Initialize statistics to 0
  1167. *
  1168. * CHANGES
  1169. *
  1170. * -
  1171. *
  1172. ******************************************************************************/
  1173. static void init_statistics(COUNTER *pstats)
  1174. {
  1175. int i;
  1176. for(i=0; i<MaxStat; i++)
  1177. Init_Counter(pstats[i]);
  1178. }
  1179. /*****************************************************************************
  1180. *
  1181. * FUNCTION
  1182. *
  1183. * sum_statistics
  1184. *
  1185. * INPUT
  1186. *
  1187. * OUTPUT
  1188. *
  1189. * RETURNS
  1190. *
  1191. * AUTHOR
  1192. *
  1193. * POV-Ray Team
  1194. *
  1195. * DESCRIPTION
  1196. *
  1197. * Add current statistics to total statistics
  1198. *
  1199. * CHANGES
  1200. *
  1201. * -
  1202. *
  1203. ******************************************************************************/
  1204. static void sum_statistics(COUNTER *ptotalstats, COUNTER *pstats)
  1205. {
  1206. int i;
  1207. COUNTER tmp;
  1208. for(i=0; i<MaxStat; i++)
  1209. {
  1210. Add_Counter(tmp,pstats[i],ptotalstats[i]);
  1211. ptotalstats[i]=tmp;
  1212. }
  1213. }
  1214. /*****************************************************************************
  1215. *
  1216. * FUNCTION
  1217. *
  1218. * variable_store
  1219. *
  1220. * INPUT
  1221. *
  1222. * flag - flag telling wether to store or restore variables.
  1223. *
  1224. * OUTPUT
  1225. *
  1226. * RETURNS
  1227. *
  1228. * AUTHOR
  1229. *
  1230. * Dieter Bayer
  1231. *
  1232. * DESCRIPTION
  1233. *
  1234. * Store or restore variables whose value has to be the same for all
  1235. * frames of an animation and who are changed during every frame.
  1236. *
  1237. * CHANGES
  1238. *
  1239. * May 1995 : Creation.
  1240. *
  1241. ******************************************************************************/
  1242. static void variable_store(int Flag)
  1243. {
  1244. static int STORE_First_Line;
  1245. switch (Flag)
  1246. {
  1247. case STORE:
  1248. STORE_First_Line = opts.First_Line;
  1249. break;
  1250. case RESTORE:
  1251. opts.First_Line = STORE_First_Line;
  1252. break;
  1253. default:
  1254. Error("Unknown flag in variable_store().\n");
  1255. }
  1256. }
  1257. /*****************************************************************************
  1258. *
  1259. * FUNCTION
  1260. *
  1261. * destroy_libraries
  1262. *
  1263. * INPUT
  1264. *
  1265. * OUTPUT
  1266. *
  1267. * RETURNS
  1268. *
  1269. * AUTHOR
  1270. *
  1271. * POV-Ray Team
  1272. *
  1273. * DESCRIPTION
  1274. *
  1275. * Free library path memory.
  1276. *
  1277. * CHANGES
  1278. *
  1279. * -
  1280. *
  1281. ******************************************************************************/
  1282. static void destroy_libraries()
  1283. {
  1284. int i;
  1285. for (i = 0; i < opts.Library_Path_Index; i++)
  1286. {
  1287. POV_FREE(opts.Library_Paths[i]);
  1288. opts.Library_Paths[i] = NULL;
  1289. }
  1290. }
  1291. /*****************************************************************************
  1292. *
  1293. * FUNCTION
  1294. *
  1295. * close_all
  1296. *
  1297. * INPUT
  1298. *
  1299. * OUTPUT
  1300. *
  1301. * RETURNS
  1302. *
  1303. * AUTHOR
  1304. *
  1305. * POV-Ray Team
  1306. *
  1307. * DESCRIPTION
  1308. *
  1309. * Close all the stuff that has been opened and free all allocated memory.
  1310. *
  1311. * CHANGES
  1312. *
  1313. * -
  1314. *
  1315. ******************************************************************************/
  1316. void close_all()
  1317. {
  1318. /* Only close things once */
  1319. if (closed_flag)
  1320. {
  1321. return;
  1322. }
  1323. if (Output_File_Handle != NULL)
  1324. {
  1325. Close_File(Output_File_Handle);
  1326. POV_FREE(Output_File_Handle);
  1327. Output_File_Handle = NULL;
  1328. }
  1329. destroy_shellouts();
  1330. destroy_libraries();
  1331. Destroy_Text_Streams();
  1332. Free_Noise_Tables();
  1333. Terminate_Renderer();
  1334. Destroy_Bounding_Slabs();
  1335. Destroy_Blob_Queue();
  1336. Destroy_Vista_Buffer();
  1337. Destroy_Light_Buffers();
  1338. Destroy_Random_Generators();
  1339. Deinitialize_Radiosity_Code();
  1340. Free_Iteration_Stack();
  1341. destroy_histogram();
  1342. Deinitialize_Atmosphere_Code();
  1343. Deinitialize_BBox_Code();
  1344. Deinitialize_Lighting_Code();
  1345. Deinitialize_Mesh_Code();
  1346. Deinitialize_VLBuffer_Code();
  1347. Destroy_Frame();
  1348. Destroy_IStacks();
  1349. FreeFontInfo();
  1350. if ((opts.Options & DISPLAY) && Display_Started)
  1351. {
  1352. POV_DISPLAY_CLOSE
  1353. }
  1354. closed_flag = TRUE;
  1355. }
  1356. /*****************************************************************************
  1357. *
  1358. * FUNCTION
  1359. *
  1360. * POV_Std_Split_Time
  1361. *
  1362. * INPUT
  1363. *
  1364. * OUTPUT
  1365. *
  1366. * RETURNS
  1367. *
  1368. * AUTHOR
  1369. *
  1370. * POV-Ray Team
  1371. *
  1372. * DESCRIPTION
  1373. *
  1374. * Split time into hours, minutes and seconds.
  1375. *
  1376. * CHANGES
  1377. *
  1378. * -
  1379. *
  1380. ******************************************************************************/
  1381. void POV_Std_Split_Time(DBL time_dif, unsigned long *hrs, unsigned long *mins, DBL *secs)
  1382. {
  1383. *hrs = (unsigned long)(time_dif / 3600.0);
  1384. *mins = (unsigned long)((time_dif - (DBL)(*hrs * 3600)) / 60.0);
  1385. *secs = time_dif - (DBL)(*hrs * 3600 + *mins * 60);
  1386. }
  1387. /*****************************************************************************
  1388. *
  1389. * FUNCTION
  1390. *
  1391. * pov_stricmp
  1392. *
  1393. * INPUT
  1394. *
  1395. * OUTPUT
  1396. *
  1397. * RETURNS
  1398. *
  1399. * AUTHOR
  1400. *
  1401. * POV-Ray Team
  1402. *
  1403. * DESCRIPTION
  1404. *
  1405. * Since the stricmp function isn't available on all systems, we've
  1406. * provided a simplified version of it here.
  1407. *
  1408. * CHANGES
  1409. *
  1410. * -
  1411. *
  1412. ******************************************************************************/
  1413. int pov_stricmp (char *s1, char *s2)
  1414. {
  1415. char c1, c2;
  1416. while ((*s1 != '\0') && (*s2 != '\0'))
  1417. {
  1418. c1 = *s1++;
  1419. c2 = *s2++;
  1420. c1 = (char)toupper(c1);
  1421. c2 = (char)toupper(c2);
  1422. if (c1 < c2)
  1423. {
  1424. return(-1);
  1425. }
  1426. if (c1 > c2)
  1427. {
  1428. return(1);
  1429. }
  1430. }
  1431. if (*s1 == '\0')
  1432. {
  1433. if (*s2 == '\0')
  1434. {
  1435. return(0);
  1436. }
  1437. else
  1438. {
  1439. return(-1);
  1440. }
  1441. }
  1442. else
  1443. {
  1444. return(1);
  1445. }
  1446. }
  1447. /*****************************************************************************
  1448. *
  1449. * FUNCTION
  1450. *
  1451. * Locate_File
  1452. *
  1453. * INPUT
  1454. *
  1455. * OUTPUT
  1456. *
  1457. * RETURNS
  1458. *
  1459. * AUTHOR
  1460. *
  1461. * POV-Ray Team
  1462. *
  1463. * DESCRIPTION
  1464. *
  1465. * Find a file in the search path.
  1466. *
  1467. * CHANGES
  1468. *
  1469. * Apr 1996: Don't add trailing FILENAME_SEPARATOR if we are immediately
  1470. * following DRIVE_SEPARATOR because of Amiga probs. [AED]
  1471. *
  1472. ******************************************************************************/
  1473. FILE *Locate_File (char *filename, char *mode, char *ext1, char *ext2, char *buffer, int err_flag)
  1474. {
  1475. int i,l1,l2;
  1476. char pathname[FILE_NAME_LENGTH];
  1477. char file0[FILE_NAME_LENGTH];
  1478. char file1[FILE_NAME_LENGTH];
  1479. char file2[FILE_NAME_LENGTH];
  1480. FILE *f;
  1481. if (Has_Extension(filename))
  1482. {
  1483. l1=l2=0;
  1484. }
  1485. else
  1486. {
  1487. if ((l1 = strlen(ext1)) > 0)
  1488. {
  1489. strcpy(file1, filename);
  1490. strcat(file1, ext1);
  1491. }
  1492. if ((l2 = strlen(ext2)) > 0)
  1493. {
  1494. strcpy(file2, filename);
  1495. strcat(file2, ext2);
  1496. }
  1497. }
  1498. /* Check the current directory first. */
  1499. if (l1)
  1500. {
  1501. if ((f = fopen(file1, mode)) != NULL)
  1502. {
  1503. POV_GET_FULL_PATH(f,file1,buffer);
  1504. return(f);
  1505. }
  1506. }
  1507. if (l2)
  1508. {
  1509. if ((f = fopen(file2, mode)) != NULL)
  1510. {
  1511. POV_GET_FULL_PATH(f,file2,buffer);
  1512. return(f);
  1513. }
  1514. }
  1515. if ((f = fopen(filename, mode)) != NULL)
  1516. {
  1517. POV_GET_FULL_PATH(f,filename,buffer);
  1518. return(f);
  1519. }
  1520. for (i = 0; i < opts.Library_Path_Index; i++)
  1521. {
  1522. strcpy(file0, opts.Library_Paths[i]);
  1523. file0[strlen(file0)+1] = '\0';
  1524. if (file0[strlen(file0) - 1] != DRIVE_SEPARATOR)
  1525. file0[strlen(file0)] = FILENAME_SEPARATOR;
  1526. if (l1)
  1527. {
  1528. strcpy(pathname, file0);
  1529. strcat(pathname, file1);
  1530. if ((f = fopen(pathname, mode)) != NULL)
  1531. {
  1532. POV_GET_FULL_PATH(f,pathname,buffer);
  1533. return(f);
  1534. }
  1535. }
  1536. if (l2)
  1537. {
  1538. strcpy(pathname, file0);
  1539. strcat(pathname, file2);
  1540. if ((f = fopen(pathname, mode)) != NULL)
  1541. {
  1542. POV_GET_FULL_PATH(f,pathname,buffer);
  1543. return(f);
  1544. }
  1545. }
  1546. strcpy(pathname, file0);
  1547. strcat(pathname, filename);
  1548. if ((f = fopen(pathname, mode)) != NULL)
  1549. {
  1550. POV_GET_FULL_PATH(f,pathname,buffer);
  1551. return(f);
  1552. }
  1553. }
  1554. if (err_flag)
  1555. {
  1556. if (l1)
  1557. {
  1558. Error_Line("Could not find file '%s%s'\n",filename,ext1);
  1559. }
  1560. else
  1561. {
  1562. Error_Line("Could not find file '%s'\n",filename);
  1563. }
  1564. }
  1565. return(NULL);
  1566. }
  1567. /*****************************************************************************
  1568. *
  1569. * FUNCTION
  1570. *
  1571. * INPUT
  1572. *
  1573. * OUTPUT
  1574. *
  1575. * RETURNS
  1576. *
  1577. * AUTHOR
  1578. *
  1579. * DESCRIPTION
  1580. *
  1581. * CHANGES
  1582. *
  1583. ******************************************************************************/
  1584. static int Has_Extension (char *name)
  1585. {
  1586. char *p;
  1587. if (name!=NULL)
  1588. {
  1589. p=strrchr(name, '.');
  1590. if (p!=NULL)
  1591. {
  1592. if ((strlen(name)-(p-name))<=4)
  1593. {
  1594. return (TRUE);
  1595. }
  1596. }
  1597. }
  1598. return (FALSE);
  1599. }
  1600. /*****************************************************************************
  1601. *
  1602. * FUNCTION
  1603. *
  1604. * pov_shellout
  1605. *
  1606. * INPUT
  1607. *
  1608. * template_command - the template command string to execute
  1609. *
  1610. * OUTPUT
  1611. *
  1612. * RETURNS
  1613. *
  1614. * AUTHOR
  1615. *
  1616. * POV-Ray Team
  1617. *
  1618. * DESCRIPTION
  1619. *
  1620. * Execute the command line described by the string being passed in
  1621. *
  1622. * CHANGES
  1623. *
  1624. * -
  1625. *
  1626. ******************************************************************************/
  1627. SHELLRET pov_shellout (SHELLTYPE Type)
  1628. {
  1629. char real_command[POV_MAX_CMD_LENGTH];
  1630. int i, j, l = 0;
  1631. int length;
  1632. SHELLRET Return_Code;
  1633. char *s = NULL;
  1634. char *template_command;
  1635. if ( opts.Shellouts == NULL ) return(IGNORE_RET);
  1636. template_command=opts.Shellouts[Type].Command;
  1637. if ((length = strlen(template_command)) == 0)
  1638. {
  1639. return(IGNORE_RET);
  1640. }
  1641. switch(Type)
  1642. {
  1643. case PRE_SCENE_SHL: s="pre-scene"; break;
  1644. case PRE_FRAME_SHL: s="pre-frame"; break;
  1645. case POST_FRAME_SHL: s="post-frame"; break;
  1646. case POST_SCENE_SHL: s="post-scene"; break;
  1647. case USER_ABORT_SHL: s="user about"; break;
  1648. case FATAL_SHL: s="fatal error"; break;
  1649. case MAX_SHL: /* To remove warnings*/ break;
  1650. }
  1651. Status_Info("\nPerforming %s shell-out command",s);
  1652. /* First, find the real command */
  1653. for (i = 0, j = 0; i < length; )
  1654. {
  1655. if (template_command[i] == '%')
  1656. {
  1657. switch (toupper(template_command[i+1]))
  1658. {
  1659. case 'O':
  1660. strncpy(&real_command[j], opts.Output_Numbered_Name,
  1661. (unsigned)(l=strlen(opts.Output_Numbered_Name)));
  1662. break;
  1663. case 'P':
  1664. strncpy(&real_command[j], opts.Output_Path,(unsigned)(l=strlen(opts.Output_Path)));
  1665. break;
  1666. case 'S':
  1667. strncpy(&real_command[j], opts.Scene_Name, (unsigned)(l=strlen(opts.Scene_Name)));
  1668. break;
  1669. case 'N':
  1670. sprintf(&real_command[j],"%d",opts.FrameSeq.FrameNumber);
  1671. l = strlen(&real_command[j]);
  1672. break;
  1673. case 'K':
  1674. sprintf(&real_command[j],"%f",opts.FrameSeq.Clock_Value);
  1675. l = strlen(&real_command[j]);
  1676. break;
  1677. case 'H':
  1678. sprintf(&real_command[j],"%d",Frame.Screen_Height);
  1679. l = strlen(&real_command[j]);
  1680. break;
  1681. case 'W':
  1682. sprintf(&real_command[j],"%d",Frame.Screen_Width);
  1683. l = strlen(&real_command[j]);
  1684. break;
  1685. case '%':
  1686. real_command[j]='%';
  1687. l=1;
  1688. break;
  1689. }
  1690. j+=l;
  1691. i+=2; /* we used 2 characters of template_command */
  1692. }
  1693. else
  1694. {
  1695. real_command[j++]=template_command[i++];
  1696. }
  1697. }
  1698. real_command[j]='\0';
  1699. Return_Code=(POV_SHELLOUT_CAST)POV_SYSTEM(real_command);
  1700. if (opts.Shellouts[Type].Inverse)
  1701. {
  1702. Return_Code=(POV_SHELLOUT_CAST)(!((int)Return_Code));
  1703. }
  1704. if (Return_Code)
  1705. {
  1706. if (Type < USER_ABORT_SHL)
  1707. {
  1708. switch(opts.Shellouts[Type].Ret)
  1709. {
  1710. case FATAL_RET:
  1711. Error("Fatal error returned from shellout command.");
  1712. break;
  1713. case USER_RET:
  1714. Check_User_Abort(TRUE); /* the TRUE forces user abort */
  1715. break;
  1716. case QUIT_RET:
  1717. Terminate_POV(0);
  1718. break;
  1719. case IGNORE_RET:
  1720. case SKIP_ONCE_RET:
  1721. case ALL_SKIP_RET: /* Added to remove warnings */
  1722. break;
  1723. }
  1724. }
  1725. return(opts.Shellouts[Type].Ret);
  1726. }
  1727. return(IGNORE_RET);
  1728. }
  1729. /*****************************************************************************
  1730. *
  1731. * FUNCTION
  1732. *
  1733. * INPUT
  1734. *
  1735. * OUTPUT
  1736. *
  1737. * RETURNS
  1738. *
  1739. * AUTHOR
  1740. *
  1741. * DESCRIPTION
  1742. *
  1743. * CHANGES
  1744. *
  1745. ******************************************************************************/
  1746. static void init_shellouts()
  1747. {
  1748. int i;
  1749. opts.Shellouts=(SHELLDATA *)POV_MALLOC(sizeof(SHELLDATA)*MAX_SHL,"shellout data");
  1750. for (i=0; i < MAX_SHL; i++)
  1751. {
  1752. opts.Shellouts[i].Ret=IGNORE_RET;
  1753. opts.Shellouts[i].Inverse=FALSE;
  1754. opts.Shellouts[i].Command[0]='\0';
  1755. }
  1756. }
  1757. /*****************************************************************************
  1758. *
  1759. * FUNCTION
  1760. *
  1761. * INPUT
  1762. *
  1763. * OUTPUT
  1764. *
  1765. * RETURNS
  1766. *
  1767. * AUTHOR
  1768. *
  1769. * DESCRIPTION
  1770. *
  1771. * CHANGES
  1772. *
  1773. ******************************************************************************/
  1774. static void destroy_shellouts()
  1775. {
  1776. if (opts.Shellouts != NULL)
  1777. {
  1778. POV_FREE(opts.Shellouts);
  1779. }
  1780. opts.Shellouts=NULL;
  1781. }
  1782. /*****************************************************************************
  1783. *
  1784. * FUNCTION
  1785. *
  1786. * closest_power_of_2
  1787. *
  1788. * INPUT
  1789. *
  1790. * theNumber - the value to determine closest power of 2 for.
  1791. *
  1792. * OUTPUT
  1793. *
  1794. * RETURNS
  1795. *
  1796. * The closest power of two is returned, or zero if the
  1797. * argument is less than or equal to zero.
  1798. *
  1799. * AUTHOR
  1800. *
  1801. * Eduard Schwan
  1802. *
  1803. * DESCRIPTION
  1804. *
  1805. * Decription: Find the highest positive power of 2 that is
  1806. * less than or equal to the number passed.
  1807. *
  1808. * Input Output
  1809. * ----- ------
  1810. * 0 0
  1811. * 1 1
  1812. * 2 2
  1813. * 3 2
  1814. * 8 8
  1815. * 9 8
  1816. *
  1817. * CHANGES
  1818. *
  1819. * Aug 1994 : Created by Eduard.
  1820. *
  1821. ******************************************************************************/
  1822. static unsigned closest_power_of_2(unsigned theNumber)
  1823. {
  1824. int PowerOf2Counter;
  1825. /* do not handle zero or negative numbers for now */
  1826. if (theNumber <= 0)
  1827. {
  1828. return(0);
  1829. }
  1830. /* count the number in question down as we count up a power of 2 */
  1831. PowerOf2Counter = 1;
  1832. while (theNumber > 1)
  1833. {
  1834. /* move our power of 2 counter bit up... */
  1835. PowerOf2Counter <<= 1;
  1836. /* and reduce our test number by a factor of 2 two */
  1837. theNumber >>= 1;
  1838. }
  1839. return(PowerOf2Counter);
  1840. }
  1841. /*****************************************************************************
  1842. *
  1843. * FUNCTION
  1844. *
  1845. * pre_init_povray
  1846. *
  1847. * INPUT -- none
  1848. *
  1849. * OUTPUT
  1850. *
  1851. * RETURNS
  1852. *
  1853. * AUTHOR -- CEY
  1854. *
  1855. * DESCRIPTION
  1856. *
  1857. * This routine does essential initialization that is required before any
  1858. * POV_MALLOC-like routines may be called and before any text streams
  1859. * may be used.
  1860. *
  1861. * If you are using alt_main and need access to any part of the generic code
  1862. * before alt_main is called, you MUST call this routine first! Also note
  1863. * that it is safe to call it twice. If you don't call it, alt_main will.
  1864. * It won't hurt if you both do it.
  1865. *
  1866. * NOTE: Terminate_POV de-initializes these features. Therefore you may
  1867. * need to call it again between sucessive calls to alt_main. If you call
  1868. * pre_init_povray but for some reason you abort and don't call alt_main,
  1869. * then you should call Terminate_POV to clean up.
  1870. *
  1871. * CHANGES
  1872. * Nov 1995 : Created by CEY
  1873. *
  1874. ******************************************************************************/
  1875. void pre_init_povray()
  1876. {
  1877. if (pre_init_flag==1234)
  1878. {
  1879. return;
  1880. }
  1881. /* Initialize memory. */
  1882. POV_MEM_INIT();
  1883. /* Initialize streams. In USERIO.C */
  1884. Init_Text_Streams();
  1885. init_shellouts();
  1886. pre_init_tokenizer ();
  1887. pre_init_flag=1234;
  1888. }
  1889. void POV_Split_Path(char *s,char *p,char *f)
  1890. {
  1891. char *l;
  1892. strcpy(p,s);
  1893. if ((l=strrchr(p,FILENAME_SEPARATOR))==NULL)
  1894. {
  1895. if ((l=strrchr(p,DRIVE_SEPARATOR))==NULL)
  1896. {
  1897. strcpy(f,s);
  1898. p[0]='\0';
  1899. return;
  1900. }
  1901. }
  1902. l++;
  1903. strcpy(f,l);
  1904. *l='\0';
  1905. }