<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>






<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 6.0">
<meta name="ProgId" content="FrontPage.Editor.Document"><title>jpeg editor</title>

<style>
<!--
	table td.head{ 
		background-color: #3a6ba5;
		border: 1px #000000 solid;
		font-family: Verdana;
		font-weight: bold;
		font-size: 14px;
		color: #f79c19;
		padding: 6px;
	}

	table td.body{ 
		border-bottom: 1px #6699CC dotted;
		text-align: left;
		font-family: Verdana, sans-serif, Arial;
		font-weight: normal;
		font-size: 14px;
		color: #3A6BA5;
		background-color: #fafafa;
		padding: 6px;
	}
	
-->
</style></head><body>



<p align="left"><font color="#ff0000" size="6"><span lang="en-ca"><b>&nbsp; 
 
</b></span><b>&nbsp;&nbsp;&nbsp; <span lang="en-ca">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Try to use CPU affinity to allow threads to run in different CPU<br>
</span></b></font></p>
  <b><font color="#ff0000" size="5"><span lang="en-ca"></span><span lang="en-ca">The problem</span></font></b><div align="left">This
is a FAKE problem as it is not necessary! I tried to improve the thread
code of blender as its main thread is not only in charge of display
rendered "parts", but also is responsible for creating new
threads/assigning<br>
jobs to newly created threads. Also the thread simply quit after one
job is finished, and I think it is "inefficient" as it is easy to allow
thread to retrieve next job from the "part_list". I expected this
modification can improve the performance at least to some exent.
However, can you believe it? It makes no difference! Even slower in
some cases, for example when running in GUI. <br>
So, this is a futile approach! Trust me, I wasted a whole day for
profiling/testing to see if it indeed improve or not. Just make a
record here.<br>
<br>
At bottom, you will find another futile efforts for me to try to put
multiple threads when creating raytree. It is even slower as the
operation is not very suitable for concurrent operation. More mutex op
than actual <br>
working!<br>

<span style="font-weight: bold;"></span></div><br>
<br>
<big style="font-weight: bold; color: red;">filename: source/blender/render/intern/source/pipeline.c</big><br><p>/*<br>
&nbsp;*<br>
&nbsp;* ***** BEGIN GPL LICENSE BLOCK *****<br>
&nbsp;*<br>
&nbsp;* This program is free software; you can redistribute it and/or<br>
&nbsp;* modify it under the terms of the GNU General Public License<br>
&nbsp;* as published by the Free Software Foundation; either version 2<br>
&nbsp;* of the License, or (at your option) any later version.<br>
&nbsp;*<br>
&nbsp;* This program is distributed in the hope that it will be useful,<br>
&nbsp;* but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
&nbsp;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&nbsp; See the<br>
&nbsp;* GNU General Public License for more details.<br>
&nbsp;*<br>
&nbsp;* You should have received a copy of the GNU General Public License<br>
&nbsp;* along with this program; if not, write to the Free Software Foundation,<br>
&nbsp;* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.<br>
&nbsp;*<br>
&nbsp;* The Original Code is Copyright (C) 2006 Blender Foundation.<br>
&nbsp;* All rights reserved.<br>
&nbsp;*<br>
&nbsp;* The Original Code is: all of this file.<br>
&nbsp;*<br>
&nbsp;* Contributor(s): none yet.<br>
&nbsp;*<br>
&nbsp;* ***** END GPL LICENSE BLOCK *****<br>
&nbsp;*/<br>
<br>
/** \file blender/render/intern/source/pipeline.c<br>
&nbsp;*&nbsp; \ingroup render<br>
&nbsp;*/<br>
<br>
<br>
#include &lt;math.h&gt;<br>
#include &lt;limits.h&gt;<br>
#include &lt;string.h&gt;<br>
#include &lt;stdlib.h&gt;<br>
#include &lt;stddef.h&gt;<br>
<br>
#include "DNA_group_types.h"<br>
#include "DNA_image_types.h"<br>
#include "DNA_node_types.h"<br>
#include "DNA_object_types.h"<br>
#include "DNA_scene_types.h"<br>
#include "DNA_sequence_types.h"<br>
#include "DNA_userdef_types.h"<br>
<br>
#include "MEM_guardedalloc.h"<br>
<br>
#include "BKE_animsys.h"&nbsp;&nbsp;&nbsp; /* &lt;------ should this be here?, needed for sequencer update */<br>
#include "BKE_global.h"<br>
#include "BKE_image.h"<br>
#include "BKE_main.h"<br>
#include "BKE_node.h"<br>
#include "BKE_object.h"<br>
#include "BKE_pointcache.h"<br>
#include "BKE_report.h"<br>
#include "BKE_scene.h"<br>
#include "BKE_sequencer.h"<br>
#include "BKE_utildefines.h"<br>
#include "BKE_writeavi.h"&nbsp;&nbsp;&nbsp; /* &lt;------ should be replaced once with generic movie module */<br>
<br>
#include "BLI_math.h"<br>
#include "BLI_blenlib.h"<br>
#include "BLI_rand.h"<br>
#include "BLI_threads.h"<br>
#include "BLI_utildefines.h"<br>
<br>
#include "PIL_time.h"<br>
#include "IMB_imbuf.h"<br>
#include "IMB_imbuf_types.h"<br>
<br>
#include "intern/openexr/openexr_multi.h"<br>
<br>
#include "RE_pipeline.h"<br>
<br>
/* internal */<br>
#include "render_types.h"<br>
#include "renderpipeline.h"<br>
#include "renderdatabase.h"<br>
#include "rendercore.h"<br>
#include "envmap.h"<br>
#include "initrender.h"<br>
#include "shadbuf.h"<br>
#include "pixelblending.h"<br>
#include "zbuf.h"<br>
</p>
<p><br>
<span style="background-color: rgb(255, 153, 0);">#define NICK_EDIT</span><br>
<br>
/* render flow<br>
<br>
1) Initialize state<br>
- state data, tables<br>
- movie/image file init<br>
- everything that doesn't change during animation<br>
<br>
2) Initialize data<br>
- camera, world, matrices<br>
- make render verts, faces, halos, strands<br>
- everything can change per frame/field<br>
<br>
3) Render Processor<br>
- multiple layers<br>
- tiles, rect, baking<br>
- layers/tiles optionally to disk or directly in Render Result<br>
<br>
4) Composite Render Result<br>
- also read external files etc<br>
<br>
5) Image Files<br>
- save file or append in movie<br>
<br>
*/<br>
<br>
<br>
/* ********* globals ******** */<br>
<br>
/* here we store all renders */<br>
static struct {<br>
&nbsp;&nbsp;&nbsp; ListBase renderlist;<br>
<br>
&nbsp;&nbsp;&nbsp; /* commandline thread override */<br>
&nbsp;&nbsp;&nbsp; int threads;<br>
} RenderGlobal = {{NULL, NULL}, -1};<br>
<br>
/* hardcopy of current render, used while rendering for speed */<br>
Render R;<br>
static int counter= 1;<br>
/* ********* alloc and free ******** */<br>
<br>
static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, ReportList *reports, const char *name_override);<br>
static RenderPart *find_next_pano_slice(Render *re, int *minx, rctf *viewplane);<br>
static RenderPart *find_next_part(Render *re, int minx);<br>
<br>
<br>
static volatile int g_break= 0;<br>
static int thread_break(void *UNUSED(arg))<br>
{<br>
&nbsp;&nbsp;&nbsp; return g_break;<br>
}<br>
<br>
/* default callbacks, set in each new render */<br>
static void result_nothing(void *UNUSED(arg), RenderResult *UNUSED(rr)) {}<br>
static void result_rcti_nothing(void *UNUSED(arg), RenderResult *UNUSED(rr), volatile struct rcti *UNUSED(rect)) {}<br>
static void stats_nothing(void *UNUSED(arg), RenderStats *UNUSED(rs)) {}<br>
static void float_nothing(void *UNUSED(arg), float UNUSED(val)) {}<br>
static void print_error(void *UNUSED(arg), const char *str) {printf("ERROR: %s\n", str);}<br>
static int default_break(void *UNUSED(arg)) {return G.afbreek == 1;}<br>
<br>
static void stats_background(void *UNUSED(arg), RenderStats *rs)<br>
{<br>
&nbsp;&nbsp;&nbsp; uintptr_t mem_in_use, mmap_in_use, peak_memory;<br>
&nbsp;&nbsp;&nbsp; float megs_used_memory, mmap_used_memory, megs_peak_memory;<br>
<br>
&nbsp;&nbsp;&nbsp; mem_in_use= MEM_get_memory_in_use();<br>
&nbsp;&nbsp;&nbsp; mmap_in_use= MEM_get_mapped_memory_in_use();<br>
&nbsp;&nbsp;&nbsp; peak_memory = MEM_get_peak_memory();<br>
<br>
&nbsp;&nbsp;&nbsp; megs_used_memory= (mem_in_use-mmap_in_use)/(1024.0*1024.0);<br>
&nbsp;&nbsp;&nbsp; mmap_used_memory= (mmap_in_use)/(1024.0*1024.0);<br>
&nbsp;&nbsp;&nbsp; megs_peak_memory = (peak_memory)/(1024.0*1024.0);<br>
<br>
&nbsp;&nbsp;&nbsp; fprintf(stdout, "Fra:%d Mem:%.2fM (%.2fM, peak %.2fM) ", rs-&gt;cfra,<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; megs_used_memory, mmap_used_memory,
megs_peak_memory);<br>
<br>
&nbsp;&nbsp;&nbsp; if(rs-&gt;curfield)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fprintf(stdout, "Field %d ", rs-&gt;curfield);<br>
&nbsp;&nbsp;&nbsp; if(rs-&gt;curblur)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fprintf(stdout, "Blur %d ", rs-&gt;curblur);<br>
<br>
&nbsp;&nbsp;&nbsp; if(rs-&gt;infostr) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fprintf(stdout, "| %s", rs-&gt;infostr);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rs-&gt;tothalo)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
fprintf(stdout, "Sce: %s Ve:%d Fa:%d Ha:%d La:%d", rs-&gt;scenename,
rs-&gt;totvert, rs-&gt;totface, rs-&gt;tothalo, rs-&gt;totlamp);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
fprintf(stdout, "Sce: %s Ve:%d Fa:%d La:%d", rs-&gt;scenename,
rs-&gt;totvert, rs-&gt;totface, rs-&gt;totlamp);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; fputc('\n', stdout);<br>
&nbsp;&nbsp;&nbsp; fflush(stdout);<br>
}<br>
<br>
void RE_FreeRenderResult(RenderResult *res)<br>
{<br>
&nbsp;&nbsp;&nbsp; if(res==NULL) return;<br>
<br>
&nbsp;&nbsp;&nbsp; while(res-&gt;layers.first) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderLayer *rl= res-&gt;layers.first;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rl-&gt;rectf) MEM_freeN(rl-&gt;rectf);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* acolrect and scolrect are
optionally allocated in shade_tile, only free here since it can be used
for drawing */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rl-&gt;acolrect) MEM_freeN(rl-&gt;acolrect);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rl-&gt;scolrect) MEM_freeN(rl-&gt;scolrect);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while(rl-&gt;passes.first) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderPass *rpass= rl-&gt;passes.first;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rpass-&gt;rect) MEM_freeN(rpass-&gt;rect);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_remlink(&amp;rl-&gt;passes, rpass);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MEM_freeN(rpass);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_remlink(&amp;res-&gt;layers, rl);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MEM_freeN(rl);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if(res-&gt;rect32)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MEM_freeN(res-&gt;rect32);<br>
&nbsp;&nbsp;&nbsp; if(res-&gt;rectz)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MEM_freeN(res-&gt;rectz);<br>
&nbsp;&nbsp;&nbsp; if(res-&gt;rectf)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MEM_freeN(res-&gt;rectf);<br>
&nbsp;&nbsp;&nbsp; if(res-&gt;text)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MEM_freeN(res-&gt;text);<br>
<br>
&nbsp;&nbsp;&nbsp; MEM_freeN(res);<br>
}<br>
<br>
/* version that's compatible with fullsample buffers */<br>
static void free_render_result(ListBase *lb, RenderResult *rr)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderResult *rrnext;<br>
<br>
&nbsp;&nbsp;&nbsp; for(; rr; rr= rrnext) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rrnext= rr-&gt;next;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(lb &amp;&amp; lb-&gt;first)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_remlink(lb, rr);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_FreeRenderResult(rr);<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
<br>
/* all layers except the active one get temporally pushed away */<br>
static void push_render_result(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_WRITE);<br>
<br>
&nbsp;&nbsp;&nbsp; /* officially pushed result should be NULL... error can happen with do_seq */<br>
&nbsp;&nbsp;&nbsp; RE_FreeRenderResult(re-&gt;pushedresult);<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;pushedresult= re-&gt;result;<br>
&nbsp;&nbsp;&nbsp; re-&gt;result= NULL;<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);<br>
}<br>
<br>
/* if scemode is R_SINGLE_LAYER, at end of rendering, merge the both render results */<br>
static void pop_render_result(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;result==NULL) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("pop render result error; no current result!\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;pushedresult) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_WRITE);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
if(re-&gt;pushedresult-&gt;rectx==re-&gt;result-&gt;rectx &amp;&amp;
re-&gt;pushedresult-&gt;recty==re-&gt;result-&gt;recty) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* find which layer in pushedresult should be replaced */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; SceneRenderLayer *srl;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderLayer *rlpush;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderLayer *rl= re-&gt;result-&gt;layers.first;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int nr;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* render result should be empty after this */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_remlink(&amp;re-&gt;result-&gt;layers, rl);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* reconstruct render result layers */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(nr=0, srl=
re-&gt;scene-&gt;r.layers.first; srl; srl= srl-&gt;next, nr++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(nr==re-&gt;r.actlay)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
BLI_addtail(&amp;re-&gt;result-&gt;layers, rl);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rlpush=
RE_GetRenderLayer(re-&gt;pushedresult, srl-&gt;name);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rlpush) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
BLI_remlink(&amp;re-&gt;pushedresult-&gt;layers, rlpush);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
BLI_addtail(&amp;re-&gt;result-&gt;layers, rlpush);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_FreeRenderResult(re-&gt;pushedresult);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;pushedresult= NULL;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
/* NOTE: OpenEXR only supports 32 chars for layer+pass names<br>
&nbsp;&nbsp; In blender we now use max 10 chars for pass, max 20 for layer */<br>
static const char *get_pass_name(int passtype, int channel)<br>
{<br>
<br>
&nbsp;&nbsp;&nbsp; if(passtype == SCE_PASS_COMBINED) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==-1) return "Combined";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==0) return "Combined.R";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==1) return "Combined.G";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==2) return "Combined.B";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return "Combined.A";<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(passtype == SCE_PASS_Z) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==-1) return "Depth";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return "Depth.Z";<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(passtype == SCE_PASS_VECTOR) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==-1) return "Vector";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==0) return "Vector.X";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==1) return "Vector.Y";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==2) return "Vector.Z";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return "Vector.W";<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(passtype == SCE_PASS_NORMAL) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==-1) return "Normal";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==0) return "Normal.X";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==1) return "Normal.Y";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return "Normal.Z";<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(passtype == SCE_PASS_UV) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==-1) return "UV";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==0) return "UV.U";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==1) return "UV.V";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return "UV.A";<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(passtype == SCE_PASS_RGBA) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==-1) return "Color";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==0) return "Color.R";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==1) return "Color.G";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==2) return "Color.B";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return "Color.A";<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(passtype == SCE_PASS_EMIT) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==-1) return "Emit";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==0) return "Emit.R";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==1) return "Emit.G";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return "Emit.B";<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(passtype == SCE_PASS_DIFFUSE) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==-1) return "Diffuse";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==0) return "Diffuse.R";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==1) return "Diffuse.G";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return "Diffuse.B";<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(passtype == SCE_PASS_SPEC) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==-1) return "Spec";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==0) return "Spec.R";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==1) return "Spec.G";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return "Spec.B";<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(passtype == SCE_PASS_SHADOW) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==-1) return "Shadow";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==0) return "Shadow.R";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==1) return "Shadow.G";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return "Shadow.B";<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(passtype == SCE_PASS_AO) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==-1) return "AO";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==0) return "AO.R";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==1) return "AO.G";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return "AO.B";<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(passtype == SCE_PASS_ENVIRONMENT) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==-1) return "Env";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==0) return "Env.R";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==1) return "Env.G";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return "Env.B";<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(passtype == SCE_PASS_INDIRECT) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==-1) return "Indirect";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==0) return "Indirect.R";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==1) return "Indirect.G";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return "Indirect.B";<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(passtype == SCE_PASS_REFLECT) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==-1) return "Reflect";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==0) return "Reflect.R";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==1) return "Reflect.G";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return "Reflect.B";<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(passtype == SCE_PASS_REFRACT) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==-1) return "Refract";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==0) return "Refract.R";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==1) return "Refract.G";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return "Refract.B";<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(passtype == SCE_PASS_INDEXOB) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==-1) return "IndexOB";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return "IndexOB.X";<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(passtype == SCE_PASS_MIST) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==-1) return "Mist";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return "Mist.Z";<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(passtype == SCE_PASS_RAYHITS)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==-1) return "Rayhits";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==0) return "Rayhits.R";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(channel==1) return "Rayhits.G";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return "Rayhits.B";<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; return "Unknown";<br>
}<br>
<br>
static int passtype_from_name(char *str)<br>
{<br>
<br>
&nbsp;&nbsp;&nbsp; if(strcmp(str, "Combined")==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return SCE_PASS_COMBINED;<br>
<br>
&nbsp;&nbsp;&nbsp; if(strcmp(str, "Depth")==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return SCE_PASS_Z;<br>
<br>
&nbsp;&nbsp;&nbsp; if(strcmp(str, "Vector")==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return SCE_PASS_VECTOR;<br>
<br>
&nbsp;&nbsp;&nbsp; if(strcmp(str, "Normal")==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return SCE_PASS_NORMAL;<br>
<br>
&nbsp;&nbsp;&nbsp; if(strcmp(str, "UV")==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return SCE_PASS_UV;<br>
<br>
&nbsp;&nbsp;&nbsp; if(strcmp(str, "Color")==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return SCE_PASS_RGBA;<br>
<br>
&nbsp;&nbsp;&nbsp; if(strcmp(str, "Emit")==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return SCE_PASS_EMIT;<br>
<br>
&nbsp;&nbsp;&nbsp; if(strcmp(str, "Diffuse")==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return SCE_PASS_DIFFUSE;<br>
<br>
&nbsp;&nbsp;&nbsp; if(strcmp(str, "Spec")==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return SCE_PASS_SPEC;<br>
<br>
&nbsp;&nbsp;&nbsp; if(strcmp(str, "Shadow")==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return SCE_PASS_SHADOW;<br>
<br>
&nbsp;&nbsp;&nbsp; if(strcmp(str, "AO")==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return SCE_PASS_AO;<br>
<br>
&nbsp;&nbsp;&nbsp; if(strcmp(str, "Env")==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return SCE_PASS_ENVIRONMENT;<br>
<br>
&nbsp;&nbsp;&nbsp; if(strcmp(str, "Indirect")==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return SCE_PASS_INDIRECT;<br>
<br>
&nbsp;&nbsp;&nbsp; if(strcmp(str, "Reflect")==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return SCE_PASS_REFLECT;<br>
<br>
&nbsp;&nbsp;&nbsp; if(strcmp(str, "Refract")==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return SCE_PASS_REFRACT;<br>
<br>
&nbsp;&nbsp;&nbsp; if(strcmp(str, "IndexOB")==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return SCE_PASS_INDEXOB;<br>
<br>
&nbsp;&nbsp;&nbsp; if(strcmp(str, "Mist")==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return SCE_PASS_MIST;<br>
<br>
&nbsp;&nbsp;&nbsp; if(strcmp(str, "RayHits")==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return SCE_PASS_RAYHITS;<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static void scene_unique_exr_name(Scene *scene, char *str, int sample)<br>
{<br>
&nbsp;&nbsp;&nbsp; char di[FILE_MAX], name[FILE_MAXFILE+MAX_ID_NAME+100], fi[FILE_MAXFILE];<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_strncpy(di, G.main-&gt;name, FILE_MAX);<br>
&nbsp;&nbsp;&nbsp; BLI_splitdirstring(di, fi);<br>
<br>
&nbsp;&nbsp;&nbsp; if(sample==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_snprintf(name, sizeof(name), "%s_%s.exr", fi, scene-&gt;id.name+2);<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_snprintf(name, sizeof(name), "%s_%s%d.exr", fi, scene-&gt;id.name+2, sample);<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_make_file_string("/", str, btempdir, name);<br>
}<br>
<br>
static void render_unique_exr_name(Render *re, char *str, int sample)<br>
{<br>
&nbsp;&nbsp;&nbsp; scene_unique_exr_name(re-&gt;scene, str, sample);<br>
}<br>
<br>
static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype)<br>
{<br>
&nbsp;&nbsp;&nbsp; const char *typestr= get_pass_name(passtype, 0);<br>
&nbsp;&nbsp;&nbsp; RenderPass *rpass= MEM_callocN(sizeof(RenderPass), typestr);<br>
&nbsp;&nbsp;&nbsp; int rectsize= rr-&gt;rectx*rr-&gt;recty*channels;<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_addtail(&amp;rl-&gt;passes, rpass);<br>
&nbsp;&nbsp;&nbsp; rpass-&gt;passtype= passtype;<br>
&nbsp;&nbsp;&nbsp; rpass-&gt;channels= channels;<br>
&nbsp;&nbsp;&nbsp; rpass-&gt;rectx= rl-&gt;rectx;<br>
&nbsp;&nbsp;&nbsp; rpass-&gt;recty= rl-&gt;recty;<br>
<br>
&nbsp;&nbsp;&nbsp; if(rr-&gt;exrhandle) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int a;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(a=0; a&lt;channels; a++)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
IMB_exr_add_channel(rr-&gt;exrhandle, rl-&gt;name,
get_pass_name(passtype, a), 0, 0, NULL);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float *rect;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int x;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rpass-&gt;rect= MEM_mapallocN(sizeof(float)*rectsize, typestr);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(passtype==SCE_PASS_VECTOR) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* initialize to max speed */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rect= rpass-&gt;rect;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(x= rectsize-1; x&gt;=0; x--)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rect[x]= PASS_VECTOR_MAX;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if(passtype==SCE_PASS_Z) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rect= rpass-&gt;rect;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(x= rectsize-1; x&gt;=0; x--)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rect[x]= 10e10;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
float *RE_RenderLayerGetPass(RenderLayer *rl, int passtype)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderPass *rpass;<br>
<br>
&nbsp;&nbsp;&nbsp; for(rpass=rl-&gt;passes.first; rpass; rpass= rpass-&gt;next)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rpass-&gt;passtype== passtype)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return rpass-&gt;rect;<br>
&nbsp;&nbsp;&nbsp; return NULL;<br>
}<br>
<br>
RenderLayer *RE_GetRenderLayer(RenderResult *rr, const char *name)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderLayer *rl;<br>
<br>
&nbsp;&nbsp;&nbsp; if(rr==NULL) return NULL;<br>
<br>
&nbsp;&nbsp;&nbsp; for(rl= rr-&gt;layers.first; rl; rl= rl-&gt;next)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(strncmp(rl-&gt;name, name, RE_MAXNAME)==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return rl;<br>
&nbsp;&nbsp;&nbsp; return NULL;<br>
}<br>
<br>
#define RR_USEMEM&nbsp;&nbsp;&nbsp; 0<br>
/* called by main render as well for parts */<br>
/* will read info from Render *re to define layers */<br>
/* called in threads */<br>
/* re-&gt;winx,winy is coordinate space of entire image, partrct the part within */<br>
static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int savebuffers)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderResult *rr;<br>
&nbsp;&nbsp;&nbsp; RenderLayer *rl;<br>
&nbsp;&nbsp;&nbsp; SceneRenderLayer *srl;<br>
&nbsp;&nbsp;&nbsp; int rectx, recty, nr;<br>
<br>
&nbsp;&nbsp;&nbsp; rectx= partrct-&gt;xmax - partrct-&gt;xmin;<br>
&nbsp;&nbsp;&nbsp; recty= partrct-&gt;ymax - partrct-&gt;ymin;<br>
<br>
&nbsp;&nbsp;&nbsp; if(rectx&lt;=0 || recty&lt;=0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return NULL;<br>
<br>
&nbsp;&nbsp;&nbsp; rr= MEM_callocN(sizeof(RenderResult), "new render result");<br>
&nbsp;&nbsp;&nbsp; rr-&gt;rectx= rectx;<br>
&nbsp;&nbsp;&nbsp; rr-&gt;recty= recty;<br>
&nbsp;&nbsp;&nbsp; rr-&gt;renrect.xmin= 0; rr-&gt;renrect.xmax= rectx-2*crop;<br>
&nbsp;&nbsp;&nbsp; /* crop is one or two extra pixels rendered for filtering, is used for merging and display too */<br>
&nbsp;&nbsp;&nbsp; rr-&gt;crop= crop;<br>
<br>
&nbsp;&nbsp;&nbsp; /* tilerect is relative coordinates within render disprect. do not subtract crop yet */<br>
&nbsp;&nbsp;&nbsp; rr-&gt;tilerect.xmin= partrct-&gt;xmin - re-&gt;disprect.xmin;<br>
&nbsp;&nbsp;&nbsp; rr-&gt;tilerect.xmax= partrct-&gt;xmax - re-&gt;disprect.xmax;<br>
&nbsp;&nbsp;&nbsp; rr-&gt;tilerect.ymin= partrct-&gt;ymin - re-&gt;disprect.ymin;<br>
&nbsp;&nbsp;&nbsp; rr-&gt;tilerect.ymax= partrct-&gt;ymax - re-&gt;disprect.ymax;<br>
<br>
&nbsp;&nbsp;&nbsp; if(savebuffers) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rr-&gt;exrhandle= IMB_exr_get_handle();<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* check renderdata for amount of layers */<br>
&nbsp;&nbsp;&nbsp; for(nr=0, srl= re-&gt;r.layers.first; srl; srl= srl-&gt;next, nr++) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if((re-&gt;r.scemode &amp; R_SINGLE_LAYER) &amp;&amp; nr!=re-&gt;r.actlay)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; continue;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(srl-&gt;layflag &amp; SCE_LAY_DISABLE)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; continue;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl= MEM_callocN(sizeof(RenderLayer), "new render layer");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_addtail(&amp;rr-&gt;layers, rl);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_strncpy(rl-&gt;name, srl-&gt;name, sizeof(rl-&gt;name));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl-&gt;lay= srl-&gt;lay;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl-&gt;lay_zmask= srl-&gt;lay_zmask;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl-&gt;layflag= srl-&gt;layflag;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl-&gt;passflag= srl-&gt;passflag; // for debugging: srl-&gt;passflag|SCE_PASS_RAYHITS;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl-&gt;pass_xor= srl-&gt;pass_xor;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl-&gt;light_override= srl-&gt;light_override;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl-&gt;mat_override= srl-&gt;mat_override;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl-&gt;rectx= rectx;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl-&gt;recty= recty;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rr-&gt;exrhandle) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
IMB_exr_add_channel(rr-&gt;exrhandle, rl-&gt;name, "Combined.R", 0, 0,
NULL);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
IMB_exr_add_channel(rr-&gt;exrhandle, rl-&gt;name, "Combined.G", 0, 0,
NULL);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
IMB_exr_add_channel(rr-&gt;exrhandle, rl-&gt;name, "Combined.B", 0, 0,
NULL);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
IMB_exr_add_channel(rr-&gt;exrhandle, rl-&gt;name, "Combined.A", 0, 0,
NULL);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl-&gt;rectf=
MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba");<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(srl-&gt;passflag&nbsp; &amp; SCE_PASS_Z)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_layer_add_pass(rr, rl, 1, SCE_PASS_Z);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(srl-&gt;passflag&nbsp; &amp; SCE_PASS_VECTOR)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_layer_add_pass(rr, rl, 4, SCE_PASS_VECTOR);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(srl-&gt;passflag&nbsp; &amp; SCE_PASS_NORMAL)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_layer_add_pass(rr, rl, 3, SCE_PASS_NORMAL);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(srl-&gt;passflag&nbsp; &amp; SCE_PASS_UV)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_layer_add_pass(rr, rl, 3, SCE_PASS_UV);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(srl-&gt;passflag&nbsp; &amp; SCE_PASS_RGBA)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_layer_add_pass(rr, rl, 4, SCE_PASS_RGBA);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(srl-&gt;passflag&nbsp; &amp; SCE_PASS_EMIT)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_layer_add_pass(rr, rl, 3, SCE_PASS_EMIT);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(srl-&gt;passflag&nbsp; &amp; SCE_PASS_DIFFUSE)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(srl-&gt;passflag&nbsp; &amp; SCE_PASS_SPEC)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_layer_add_pass(rr, rl, 3, SCE_PASS_SPEC);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(srl-&gt;passflag&nbsp; &amp; SCE_PASS_AO)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_layer_add_pass(rr, rl, 3, SCE_PASS_AO);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(srl-&gt;passflag&nbsp; &amp; SCE_PASS_ENVIRONMENT)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_layer_add_pass(rr, rl, 3, SCE_PASS_ENVIRONMENT);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(srl-&gt;passflag&nbsp; &amp; SCE_PASS_INDIRECT)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_layer_add_pass(rr, rl, 3, SCE_PASS_INDIRECT);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(srl-&gt;passflag&nbsp; &amp; SCE_PASS_SHADOW)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(srl-&gt;passflag&nbsp; &amp; SCE_PASS_REFLECT)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_layer_add_pass(rr, rl, 3, SCE_PASS_REFLECT);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(srl-&gt;passflag&nbsp; &amp; SCE_PASS_REFRACT)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_layer_add_pass(rr, rl, 3, SCE_PASS_REFRACT);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(srl-&gt;passflag&nbsp; &amp; SCE_PASS_INDEXOB)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXOB);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(srl-&gt;passflag&nbsp; &amp; SCE_PASS_MIST)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_layer_add_pass(rr, rl, 1, SCE_PASS_MIST);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rl-&gt;passflag &amp; SCE_PASS_RAYHITS)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_layer_add_pass(rr, rl, 4, SCE_PASS_RAYHITS);<br>
<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; /* sss, previewrender and envmap don't do layers, so we make a default one */<br>
&nbsp;&nbsp;&nbsp; if(rr-&gt;layers.first==NULL) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl= MEM_callocN(sizeof(RenderLayer), "new render layer");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_addtail(&amp;rr-&gt;layers, rl);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl-&gt;rectx= rectx;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl-&gt;recty= recty;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* duplicate code... */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rr-&gt;exrhandle) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
IMB_exr_add_channel(rr-&gt;exrhandle, rl-&gt;name, "Combined.R", 0, 0,
NULL);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
IMB_exr_add_channel(rr-&gt;exrhandle, rl-&gt;name, "Combined.G", 0, 0,
NULL);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
IMB_exr_add_channel(rr-&gt;exrhandle, rl-&gt;name, "Combined.B", 0, 0,
NULL);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
IMB_exr_add_channel(rr-&gt;exrhandle, rl-&gt;name, "Combined.A", 0, 0,
NULL);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl-&gt;rectf=
MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba");<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* note, this has to be in sync with scene.c */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl-&gt;lay= (1&lt;&lt;20) -1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl-&gt;layflag= 0x7FFF;&nbsp;&nbsp;&nbsp; /* solid ztra halo strand */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl-&gt;passflag= SCE_PASS_COMBINED;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;r.actlay= 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* border render; calculate offset for use in compositor. compo is centralized coords */<br>
&nbsp;&nbsp;&nbsp; rr-&gt;xof= re-&gt;disprect.xmin + (re-&gt;disprect.xmax - re-&gt;disprect.xmin)/2 - re-&gt;winx/2;<br>
&nbsp;&nbsp;&nbsp; rr-&gt;yof= re-&gt;disprect.ymin + (re-&gt;disprect.ymax - re-&gt;disprect.ymin)/2 - re-&gt;winy/2;<br>
<br>
&nbsp;&nbsp;&nbsp; return rr;<br>
}<br>
<br>
static int render_scene_needs_vector(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; SceneRenderLayer *srl;<br>
<br>
&nbsp;&nbsp;&nbsp; for(srl= re-&gt;scene-&gt;r.layers.first; srl; srl= srl-&gt;next)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!(srl-&gt;layflag &amp; SCE_LAY_DISABLE))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(srl-&gt;passflag &amp; SCE_PASS_VECTOR)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target, float *tile, int pixsize)<br>
{<br>
&nbsp;&nbsp;&nbsp; int y, ofs, copylen, tilex, tiley;<br>
<br>
&nbsp;&nbsp;&nbsp; copylen= tilex= rrpart-&gt;rectx;<br>
&nbsp;&nbsp;&nbsp; tiley= rrpart-&gt;recty;<br>
<br>
&nbsp;&nbsp;&nbsp; if(rrpart-&gt;crop) {&nbsp;&nbsp;&nbsp; /* filters add pixel extra */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tile+= pixsize*(rrpart-&gt;crop + rrpart-&gt;crop*tilex);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; copylen= tilex - 2*rrpart-&gt;crop;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tiley -= 2*rrpart-&gt;crop;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ofs= (rrpart-&gt;tilerect.ymin +
rrpart-&gt;crop)*rr-&gt;rectx +
(rrpart-&gt;tilerect.xmin+rrpart-&gt;crop);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; target+= pixsize*ofs;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ofs= (rrpart-&gt;tilerect.ymin*rr-&gt;rectx + rrpart-&gt;tilerect.xmin);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; target+= pixsize*ofs;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; copylen *= sizeof(float)*pixsize;<br>
&nbsp;&nbsp;&nbsp; tilex *= pixsize;<br>
&nbsp;&nbsp;&nbsp; ofs= pixsize*rr-&gt;rectx;<br>
<br>
&nbsp;&nbsp;&nbsp; for(y=0; y&lt;tiley; y++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memcpy(target, tile, copylen);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; target+= ofs;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tile+= tilex;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
/* used when rendering to a full buffer, or when reading the exr part-layer-pass file */<br>
/* no test happens here if it fits... we also assume layers are in sync */<br>
/* is used within threads */<br>
static void merge_render_result(RenderResult *rr, RenderResult *rrpart)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderLayer *rl, *rlp;<br>
&nbsp;&nbsp;&nbsp; RenderPass *rpass, *rpassp;<br>
<br>
&nbsp;&nbsp;&nbsp; for(rl= rr-&gt;layers.first, rlp=
rrpart-&gt;layers.first; rl &amp;&amp; rlp; rl= rl-&gt;next, rlp=
rlp-&gt;next) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* combined */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rl-&gt;rectf &amp;&amp; rlp-&gt;rectf)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do_merge_tile(rr, rrpart, rl-&gt;rectf, rlp-&gt;rectf, 4);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* passes are allocated in sync */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(rpass= rl-&gt;passes.first,
rpassp= rlp-&gt;passes.first; rpass &amp;&amp; rpassp; rpass=
rpass-&gt;next, rpassp= rpassp-&gt;next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
do_merge_tile(rr, rrpart, rpass-&gt;rect, rpassp-&gt;rect,
rpass-&gt;channels);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
<br>
static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderLayer *rlp;<br>
&nbsp;&nbsp;&nbsp; RenderPass *rpassp;<br>
&nbsp;&nbsp;&nbsp; int offs, partx, party;<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_lock_thread(LOCK_IMAGE);<br>
<br>
&nbsp;&nbsp;&nbsp; for(rlp= rrpart-&gt;layers.first; rlp; rlp= rlp-&gt;next) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rrpart-&gt;crop) {&nbsp;&nbsp;&nbsp; /* filters add pixel extra */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; offs= (rrpart-&gt;crop + rrpart-&gt;crop*rrpart-&gt;rectx);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; offs= 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* combined */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rlp-&gt;rectf) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int a, xstride= 4;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(a=0; a&lt;xstride; a++)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; IMB_exr_set_channel(rr-&gt;exrhandle, rlp-&gt;name,
get_pass_name(SCE_PASS_COMBINED, a),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; xstride,
xstride*rrpart-&gt;rectx, rlp-&gt;rectf+a + xstride*offs);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* passes are allocated in sync */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(rpassp= rlp-&gt;passes.first; rpassp; rpassp= rpassp-&gt;next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int a, xstride= rpassp-&gt;channels;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(a=0; a&lt;xstride; a++)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; IMB_exr_set_channel(rr-&gt;exrhandle, rlp-&gt;name,
get_pass_name(rpassp-&gt;passtype, a),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; xstride,
xstride*rrpart-&gt;rectx, rpassp-&gt;rect+a + xstride*offs);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; party= rrpart-&gt;tilerect.ymin + rrpart-&gt;crop;<br>
&nbsp;&nbsp;&nbsp; partx= rrpart-&gt;tilerect.xmin + rrpart-&gt;crop;<br>
&nbsp;&nbsp;&nbsp; IMB_exrtile_write_channels(rr-&gt;exrhandle, partx, party, 0);<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_unlock_thread(LOCK_IMAGE);<br>
<br>
}<br>
<br>
static void save_empty_result_tiles(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderPart *pa;<br>
&nbsp;&nbsp;&nbsp; RenderResult *rr;<br>
<br>
&nbsp;&nbsp;&nbsp; for(rr= re-&gt;result; rr; rr= rr-&gt;next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_exrtile_clear_channels(rr-&gt;exrhandle);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(pa= re-&gt;parts.first; pa; pa= pa-&gt;next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(pa-&gt;ready==0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; int party= pa-&gt;disprect.ymin -
re-&gt;disprect.ymin + pa-&gt;crop;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; int partx= pa-&gt;disprect.xmin -
re-&gt;disprect.xmin + pa-&gt;crop;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; IMB_exrtile_write_channels(rr-&gt;exrhandle, partx,
party, 0);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
<br>
/* for passes read from files, these have names stored */<br>
static char *make_pass_name(RenderPass *rpass, int chan)<br>
{<br>
&nbsp;&nbsp;&nbsp; static char name[16];<br>
&nbsp;&nbsp;&nbsp; int len;<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_strncpy(name, rpass-&gt;name, EXR_PASS_MAXNAME);<br>
&nbsp;&nbsp;&nbsp; len= strlen(name);<br>
&nbsp;&nbsp;&nbsp; name[len]= '.';<br>
&nbsp;&nbsp;&nbsp; name[len+1]= rpass-&gt;chan_id[chan];<br>
&nbsp;&nbsp;&nbsp; name[len+2]= 0;<br>
<br>
&nbsp;&nbsp;&nbsp; return name;<br>
}<br>
<br>
/* filename already made absolute */<br>
/* called from within UI, saves both rendered result as a file-read result */<br>
void RE_WriteRenderResult(RenderResult *rr, const char *filename, int compress)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderLayer *rl;<br>
&nbsp;&nbsp;&nbsp; RenderPass *rpass;<br>
&nbsp;&nbsp;&nbsp; void *exrhandle= IMB_exr_get_handle();<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_make_existing_file(filename);<br>
<br>
&nbsp;&nbsp;&nbsp; /* composite result */<br>
&nbsp;&nbsp;&nbsp; if(rr-&gt;rectf) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_exr_add_channel(exrhandle,
"Composite", "Combined.R", 4, 4*rr-&gt;rectx, rr-&gt;rectf);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_exr_add_channel(exrhandle,
"Composite", "Combined.G", 4, 4*rr-&gt;rectx, rr-&gt;rectf+1);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_exr_add_channel(exrhandle,
"Composite", "Combined.B", 4, 4*rr-&gt;rectx, rr-&gt;rectf+2);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_exr_add_channel(exrhandle,
"Composite", "Combined.A", 4, 4*rr-&gt;rectx, rr-&gt;rectf+3);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* add layers/passes and assign channels */<br>
&nbsp;&nbsp;&nbsp; for(rl= rr-&gt;layers.first; rl; rl= rl-&gt;next) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* combined */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rl-&gt;rectf) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int a, xstride= 4;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(a=0; a&lt;xstride; a++)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; IMB_exr_add_channel(exrhandle, rl-&gt;name,
get_pass_name(SCE_PASS_COMBINED, a),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; xstride,
xstride*rr-&gt;rectx, rl-&gt;rectf+a);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* passes are allocated in sync */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(rpass= rl-&gt;passes.first; rpass; rpass= rpass-&gt;next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int a, xstride= rpass-&gt;channels;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(a=0; a&lt;xstride; a++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rpass-&gt;passtype)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_exr_add_channel(exrhandle,
rl-&gt;name, get_pass_name(rpass-&gt;passtype, a),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; xstride, xstride*rr-&gt;rectx, rpass-&gt;rect+a);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_exr_add_channel(exrhandle,
rl-&gt;name, make_pass_name(rpass, a),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; xstride, xstride*rr-&gt;rectx, rpass-&gt;rect+a);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; IMB_exr_begin_write(exrhandle, filename, rr-&gt;rectx, rr-&gt;recty, compress);<br>
<br>
&nbsp;&nbsp;&nbsp; IMB_exr_write_channels(exrhandle);<br>
&nbsp;&nbsp;&nbsp; IMB_exr_close(exrhandle);<br>
}<br>
<br>
/* callbacks for RE_MultilayerConvert */<br>
static void *ml_addlayer_cb(void *base, char *str)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderResult *rr= base;<br>
&nbsp;&nbsp;&nbsp; RenderLayer *rl;<br>
<br>
&nbsp;&nbsp;&nbsp; rl= MEM_callocN(sizeof(RenderLayer), "new render layer");<br>
&nbsp;&nbsp;&nbsp; BLI_addtail(&amp;rr-&gt;layers, rl);<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_strncpy(rl-&gt;name, str, EXR_LAY_MAXNAME);<br>
&nbsp;&nbsp;&nbsp; return rl;<br>
}<br>
static void ml_addpass_cb(void *UNUSED(base), void *lay, char *str, float *rect, int totchan, char *chan_id)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderLayer *rl= lay;<br>
&nbsp;&nbsp;&nbsp; RenderPass *rpass= MEM_callocN(sizeof(RenderPass), "loaded pass");<br>
&nbsp;&nbsp;&nbsp; int a;<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_addtail(&amp;rl-&gt;passes, rpass);<br>
&nbsp;&nbsp;&nbsp; rpass-&gt;channels= totchan;<br>
<br>
&nbsp;&nbsp;&nbsp; rpass-&gt;passtype= passtype_from_name(str);<br>
&nbsp;&nbsp;&nbsp; if(rpass-&gt;passtype==0) printf("unknown pass %s\n", str);<br>
&nbsp;&nbsp;&nbsp; rl-&gt;passflag |= rpass-&gt;passtype;<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_strncpy(rpass-&gt;name, str, EXR_PASS_MAXNAME);<br>
&nbsp;&nbsp;&nbsp; /* channel id chars */<br>
&nbsp;&nbsp;&nbsp; for(a=0; a&lt;totchan; a++)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rpass-&gt;chan_id[a]= chan_id[a];<br>
<br>
&nbsp;&nbsp;&nbsp; rpass-&gt;rect= rect;<br>
}<br>
<br>
/* from imbuf, if a handle was returned we convert this to render result */<br>
RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderResult *rr= MEM_callocN(sizeof(RenderResult), "loaded render result");<br>
&nbsp;&nbsp;&nbsp; RenderLayer *rl;<br>
&nbsp;&nbsp;&nbsp; RenderPass *rpass;<br>
<br>
&nbsp;&nbsp;&nbsp; rr-&gt;rectx= rectx;<br>
&nbsp;&nbsp;&nbsp; rr-&gt;recty= recty;<br>
<br>
&nbsp;&nbsp;&nbsp; IMB_exr_multilayer_convert(exrhandle, rr, ml_addlayer_cb, ml_addpass_cb);<br>
<br>
&nbsp;&nbsp;&nbsp; for(rl=rr-&gt;layers.first; rl; rl=rl-&gt;next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl-&gt;rectx= rectx;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl-&gt;recty= recty;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(rpass=rl-&gt;passes.first; rpass; rpass=rpass-&gt;next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rpass-&gt;rectx= rectx;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rpass-&gt;recty= recty;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; return rr;<br>
}<br>
<br>
/* called in end of render, to add names to passes... for UI only */<br>
static void renderresult_add_names(RenderResult *rr)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderLayer *rl;<br>
&nbsp;&nbsp;&nbsp; RenderPass *rpass;<br>
<br>
&nbsp;&nbsp;&nbsp; for(rl= rr-&gt;layers.first; rl; rl= rl-&gt;next)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(rpass= rl-&gt;passes.first; rpass; rpass= rpass-&gt;next)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
BLI_strncpy(rpass-&gt;name, get_pass_name(rpass-&gt;passtype, -1),
sizeof(rpass-&gt;name));<br>
}<br>
<br>
/* called for reading temp files, and for external engines */<br>
static int read_render_result_from_file(const char *filename, RenderResult *rr)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderLayer *rl;<br>
&nbsp;&nbsp;&nbsp; RenderPass *rpass;<br>
&nbsp;&nbsp;&nbsp; void *exrhandle= IMB_exr_get_handle();<br>
&nbsp;&nbsp;&nbsp; int rectx, recty;<br>
<br>
&nbsp;&nbsp;&nbsp; if(IMB_exr_begin_read(exrhandle, filename, &amp;rectx, &amp;recty)==0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("failed being read %s\n", filename);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_exr_close(exrhandle);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if(rr == NULL || rectx!=rr-&gt;rectx || recty!=rr-&gt;recty) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rr)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("error in reading render result: dimensions don't match\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("error in reading render result: NULL result pointer\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_exr_close(exrhandle);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(rl= rr-&gt;layers.first; rl; rl= rl-&gt;next) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* combined */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rl-&gt;rectf) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int a, xstride= 4;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(a=0; a&lt;xstride; a++)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_exr_set_channel(exrhandle,
rl-&gt;name, get_pass_name(SCE_PASS_COMBINED, a),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; xstride, xstride*rectx, rl-&gt;rectf+a);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* passes are allocated in sync */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(rpass= rl-&gt;passes.first; rpass; rpass= rpass-&gt;next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int a, xstride= rpass-&gt;channels;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(a=0; a&lt;xstride; a++)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_exr_set_channel(exrhandle,
rl-&gt;name, get_pass_name(rpass-&gt;passtype, a),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; xstride, xstride*rectx, rpass-&gt;rect+a);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_exr_read_channels(exrhandle);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; renderresult_add_names(rr);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; IMB_exr_close(exrhandle);<br>
<br>
&nbsp;&nbsp;&nbsp; return 1;<br>
}<br>
<br>
/* only for temp buffer files, makes exact copy of render result */<br>
static void read_render_result(Render *re, int sample)<br>
{<br>
&nbsp;&nbsp;&nbsp; char str[FILE_MAX];<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_WRITE);<br>
<br>
&nbsp;&nbsp;&nbsp; RE_FreeRenderResult(re-&gt;result);<br>
&nbsp;&nbsp;&nbsp; re-&gt;result= new_render_result(re, &amp;re-&gt;disprect, 0, RR_USEMEM);<br>
<br>
&nbsp;&nbsp;&nbsp; render_unique_exr_name(re, str, sample);<br>
&nbsp;&nbsp;&nbsp; printf("read exr tmp file: %s\n", str);<br>
<br>
&nbsp;&nbsp;&nbsp; if(!read_render_result_from_file(str, re-&gt;result))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("cannot read: %s\n", str);<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);<br>
}<br>
<br>
/* *************************************************** */<br>
<br>
Render *RE_GetRender(const char *name)<br>
{<br>
&nbsp;&nbsp;&nbsp; Render *re;<br>
<br>
&nbsp;&nbsp;&nbsp; /* search for existing renders */<br>
&nbsp;&nbsp;&nbsp; for(re= RenderGlobal.renderlist.first; re; re= re-&gt;next)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(strncmp(re-&gt;name, name, RE_MAXNAME)==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
<br>
&nbsp;&nbsp;&nbsp; return re;<br>
}<br>
<br>
/* if you want to know exactly what has been done */<br>
RenderResult *RE_AcquireResultRead(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; if(re) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_READ);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return re-&gt;result;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; return NULL;<br>
}<br>
<br>
RenderResult *RE_AcquireResultWrite(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; if(re) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_WRITE);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return re-&gt;result;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; return NULL;<br>
}<br>
<br>
void RE_SwapResult(Render *re, RenderResult **rr)<br>
{<br>
&nbsp;&nbsp;&nbsp; /* for keeping render buffers */<br>
&nbsp;&nbsp;&nbsp; if(re) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; SWAP(RenderResult*, re-&gt;result, *rr);<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
<br>
void RE_ReleaseResult(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; if(re)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);<br>
}<br>
<br>
/* displist.c util.... */<br>
Scene *RE_GetScene(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; if(re)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return re-&gt;scene;<br>
&nbsp;&nbsp;&nbsp; return NULL;<br>
}<br>
<br>
RenderLayer *render_get_active_layer(Render *re, RenderResult *rr)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderLayer *rl= BLI_findlink(&amp;rr-&gt;layers, re-&gt;r.actlay);<br>
<br>
&nbsp;&nbsp;&nbsp; if(rl)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return rl;<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return rr-&gt;layers.first;<br>
}<br>
<br>
<br>
/* fill provided result struct with what's currently active or done */<br>
void RE_AcquireResultImage(Render *re, RenderResult *rr)<br>
{<br>
&nbsp;&nbsp;&nbsp; memset(rr, 0, sizeof(RenderResult));<br>
<br>
&nbsp;&nbsp;&nbsp; if(re) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_READ);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;result) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderLayer *rl;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rr-&gt;rectx= re-&gt;result-&gt;rectx;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rr-&gt;recty= re-&gt;result-&gt;recty;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rr-&gt;rectf= re-&gt;result-&gt;rectf;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rr-&gt;rectz= re-&gt;result-&gt;rectz;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rr-&gt;rect32= re-&gt;result-&gt;rect32;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* active layer */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rl= render_get_active_layer(re, re-&gt;result);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rl) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rr-&gt;rectf==NULL)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rr-&gt;rectf= rl-&gt;rectf;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rr-&gt;rectz==NULL)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rr-&gt;rectz=
RE_RenderLayerGetPass(rl, SCE_PASS_Z);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rr-&gt;have_combined= (re-&gt;result-&gt;rectf != NULL);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rr-&gt;layers= re-&gt;result-&gt;layers;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
void RE_ReleaseResultImage(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; if(re)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);<br>
}<br>
<br>
/* caller is responsible for allocating rect in correct size! */<br>
void RE_ResultGet32(Render *re, unsigned int *rect)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderResult rres;<br>
<br>
&nbsp;&nbsp;&nbsp; RE_AcquireResultImage(re, &amp;rres);<br>
<br>
&nbsp;&nbsp;&nbsp; if(rres.rect32)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memcpy(rect, rres.rect32, sizeof(int)*rres.rectx*rres.recty);<br>
&nbsp;&nbsp;&nbsp; else if(rres.rectf) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float *fp= rres.rectf;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int tot= rres.rectx*rres.recty;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; char *cp= (char *)rect;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (re-&gt;r.color_mgt_flag &amp; R_COLOR_MANAGEMENT) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Finally convert back to sRGB rendered image */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(;tot&gt;0; tot--, cp+=4, fp+=4) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cp[0] = FTOCHAR(linearrgb_to_srgb(fp[0]));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cp[1] = FTOCHAR(linearrgb_to_srgb(fp[1]));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cp[2] = FTOCHAR(linearrgb_to_srgb(fp[2]));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cp[3] = FTOCHAR(fp[3]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Color management is off : no conversion necessary */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(;tot&gt;0; tot--, cp+=4, fp+=4) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cp[0] = FTOCHAR(fp[0]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cp[1] = FTOCHAR(fp[1]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cp[2] = FTOCHAR(fp[2]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cp[3] = FTOCHAR(fp[3]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* else fill with black */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memset(rect, 0, sizeof(int)*re-&gt;rectx*re-&gt;recty);<br>
<br>
&nbsp;&nbsp;&nbsp; RE_ReleaseResultImage(re);<br>
}<br>
<br>
RenderStats *RE_GetStats(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; return &amp;re-&gt;i;<br>
}<br>
<br>
Render *RE_NewRender(const char *name)<br>
{<br>
&nbsp;&nbsp;&nbsp; Render *re;<br>
<br>
&nbsp;&nbsp;&nbsp; /* only one render per name exists */<br>
&nbsp;&nbsp;&nbsp; re= RE_GetRender(name);<br>
&nbsp;&nbsp;&nbsp; if(re==NULL) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* new render data struct */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re= MEM_callocN(sizeof(Render), "new render");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_addtail(&amp;RenderGlobal.renderlist, re);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; strncpy(re-&gt;name, name, RE_MAXNAME);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_rw_mutex_init(&amp;re-&gt;resultmutex);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; RE_InitRenderCB(re);<br>
<br>
&nbsp;&nbsp;&nbsp; /* init some variables */<br>
&nbsp;&nbsp;&nbsp; re-&gt;ycor= 1.0f;<br>
<br>
&nbsp;&nbsp;&nbsp; return re;<br>
}<br>
<br>
/* called for new renders and when finishing rendering so<br>
&nbsp;* we calways have valid callbacks on a render */<br>
void RE_InitRenderCB(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; /* set default empty callbacks */<br>
&nbsp;&nbsp;&nbsp; re-&gt;display_init= result_nothing;<br>
&nbsp;&nbsp;&nbsp; re-&gt;display_clear= result_nothing;<br>
&nbsp;&nbsp;&nbsp; re-&gt;display_draw= result_rcti_nothing;<br>
&nbsp;&nbsp;&nbsp; re-&gt;progress= float_nothing;<br>
&nbsp;&nbsp;&nbsp; re-&gt;test_break= default_break;<br>
&nbsp;&nbsp;&nbsp; re-&gt;error= print_error;<br>
&nbsp;&nbsp;&nbsp; if(G.background)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;stats_draw= stats_background;<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;stats_draw= stats_nothing;<br>
&nbsp;&nbsp;&nbsp; /* clear callback handles */<br>
&nbsp;&nbsp;&nbsp; re-&gt;dih= re-&gt;dch= re-&gt;ddh= re-&gt;sdh= re-&gt;prh= re-&gt;tbh= re-&gt;erh= NULL;<br>
}<br>
<br>
/* only call this while you know it will remove the link too */<br>
void RE_FreeRender(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_end(&amp;re-&gt;resultmutex);<br>
<br>
&nbsp;&nbsp;&nbsp; free_renderdata_tables(re);<br>
&nbsp;&nbsp;&nbsp; free_sample_tables(re);<br>
<br>
&nbsp;&nbsp;&nbsp; RE_FreeRenderResult(re-&gt;result);<br>
&nbsp;&nbsp;&nbsp; RE_FreeRenderResult(re-&gt;pushedresult);<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_remlink(&amp;RenderGlobal.renderlist, re);<br>
&nbsp;&nbsp;&nbsp; MEM_freeN(re);<br>
}<br>
<br>
/* exit blender */<br>
void RE_FreeAllRender(void)<br>
{<br>
&nbsp;&nbsp;&nbsp; while(RenderGlobal.renderlist.first) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_FreeRender(RenderGlobal.renderlist.first);<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
/* ********* initialize state ******** */<br>
<br>
<br>
/* what doesn't change during entire render sequence */<br>
/* disprect is optional, if NULL it assumes full window render */<br>
void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *srl, int winx, int winy, rcti *disprect)<br>
{<br>
&nbsp;&nbsp;&nbsp; re-&gt;ok= TRUE;&nbsp;&nbsp;&nbsp; /* maybe flag */<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;i.starttime= PIL_check_seconds_timer();<br>
&nbsp;&nbsp;&nbsp; re-&gt;r= *rd;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* hardcopy */<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;winx= winx;<br>
&nbsp;&nbsp;&nbsp; re-&gt;winy= winy;<br>
&nbsp;&nbsp;&nbsp; if(disprect) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;disprect= *disprect;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;rectx= disprect-&gt;xmax-disprect-&gt;xmin;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;recty= disprect-&gt;ymax-disprect-&gt;ymin;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;disprect.xmin= re-&gt;disprect.ymin= 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;disprect.xmax= winx;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;disprect.ymax= winy;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;rectx= winx;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;recty= winy;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;rectx &lt; 2 || re-&gt;recty &lt; 2 || (BKE_imtype_is_movie(rd-&gt;imtype) &amp;&amp;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp; (re-&gt;rectx &lt; 16 || re-&gt;recty &lt;
16) )) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;error(re-&gt;erh, "Image too small");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;ok= 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if((re-&gt;r.mode &amp; (R_OSA))==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;r.scemode &amp;= ~R_FULL_SAMPLE;<br>
<br>
#ifdef WITH_OPENEXR<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;r.scemode &amp; R_FULL_SAMPLE)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;r.scemode |= R_EXR_TILE_FILE;&nbsp;&nbsp;&nbsp; /* enable automatic */<br>
<br>
&nbsp;&nbsp;&nbsp; /* Until use_border is made compatible with
save_buffers/full_sample, render without the later instead of not
rendering at all.*/<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;r.mode &amp; R_BORDER)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;r.scemode &amp;= ~(R_EXR_TILE_FILE|R_FULL_SAMPLE);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
#else<br>
&nbsp;&nbsp;&nbsp; /* can't do this without openexr support */<br>
&nbsp;&nbsp;&nbsp; re-&gt;r.scemode &amp;= ~(R_EXR_TILE_FILE|R_FULL_SAMPLE);<br>
#endif<br>
<br>
&nbsp;&nbsp;&nbsp; /* fullsample wants uniform osa levels */<br>
&nbsp;&nbsp;&nbsp; if(source &amp;&amp; (re-&gt;r.scemode &amp; R_FULL_SAMPLE)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* but, if source has no full sample we disable it */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if((source-&gt;r.scemode &amp; R_FULL_SAMPLE)==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;r.scemode &amp;= ~R_FULL_SAMPLE;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;r.osa= re-&gt;osa= source-&gt;osa;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* check state variables, osa? */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;r.mode &amp; (R_OSA)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;osa= re-&gt;r.osa;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;osa&gt;16) re-&gt;osa= 16;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else re-&gt;osa= 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if (srl) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int index = BLI_findindex(&amp;re-&gt;r.layers, srl);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (index != -1) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;r.actlay = index;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;r.scemode |= R_SINGLE_LAYER;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* always call, checks for gamma, gamma tables and jitter too */<br>
&nbsp;&nbsp;&nbsp; make_sample_tables(re);<br>
<br>
&nbsp;&nbsp;&nbsp; /* if preview render, we try to keep old result */<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_WRITE);<br>
<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;r.scemode &amp; R_PREVIEWBUTS) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;result &amp;&amp;
re-&gt;result-&gt;rectx==re-&gt;rectx &amp;&amp;
re-&gt;result-&gt;recty==re-&gt;recty);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_FreeRenderResult(re-&gt;result);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result= NULL;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* make empty render result, so display callbacks can initialize */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_FreeRenderResult(re-&gt;result);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result= MEM_callocN(sizeof(RenderResult), "new render result");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result-&gt;rectx= re-&gt;rectx;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result-&gt;recty= re-&gt;recty;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);<br>
<br>
&nbsp;&nbsp;&nbsp; /* we clip faces with a minimum of 2 pixel boundary outside of image border. see zbuf.c */<br>
&nbsp;&nbsp;&nbsp; re-&gt;clipcrop= 1.0f + 2.0f/(float)(re-&gt;winx&gt;re-&gt;winy?re-&gt;winy:re-&gt;winx);<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;mblur_offs = re-&gt;field_offs = 0.f;<br>
<br>
&nbsp;&nbsp;&nbsp; RE_init_threadcount(re);<br>
}<br>
<br>
/* part of external api, not called for regular render pipeline */<br>
void RE_SetDispRect (struct Render *re, rcti *disprect)<br>
{<br>
&nbsp;&nbsp;&nbsp; re-&gt;disprect= *disprect;<br>
&nbsp;&nbsp;&nbsp; re-&gt;rectx= disprect-&gt;xmax-disprect-&gt;xmin;<br>
&nbsp;&nbsp;&nbsp; re-&gt;recty= disprect-&gt;ymax-disprect-&gt;ymin;<br>
<br>
&nbsp;&nbsp;&nbsp; /* initialize render result */<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_WRITE);<br>
<br>
&nbsp;&nbsp;&nbsp; RE_FreeRenderResult(re-&gt;result);<br>
&nbsp;&nbsp;&nbsp; re-&gt;result= new_render_result(re, &amp;re-&gt;disprect, 0, RR_USEMEM);<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);<br>
}<br>
<br>
void RE_SetWindow(Render *re, rctf *viewplane, float clipsta, float clipend)<br>
{<br>
&nbsp;&nbsp;&nbsp; /* re-&gt;ok flag? */<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;viewplane= *viewplane;<br>
&nbsp;&nbsp;&nbsp; re-&gt;clipsta= clipsta;<br>
&nbsp;&nbsp;&nbsp; re-&gt;clipend= clipend;<br>
&nbsp;&nbsp;&nbsp; re-&gt;r.mode &amp;= ~R_ORTHO;<br>
<br>
&nbsp;&nbsp;&nbsp; perspective_m4( re-&gt;winmat,re-&gt;viewplane.xmin,
re-&gt;viewplane.xmax, re-&gt;viewplane.ymin, re-&gt;viewplane.ymax,
re-&gt;clipsta, re-&gt;clipend);<br>
<br>
}<br>
<br>
void RE_SetOrtho(Render *re, rctf *viewplane, float clipsta, float clipend)<br>
{<br>
&nbsp;&nbsp;&nbsp; /* re-&gt;ok flag? */<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;viewplane= *viewplane;<br>
&nbsp;&nbsp;&nbsp; re-&gt;clipsta= clipsta;<br>
&nbsp;&nbsp;&nbsp; re-&gt;clipend= clipend;<br>
&nbsp;&nbsp;&nbsp; re-&gt;r.mode |= R_ORTHO;<br>
<br>
&nbsp;&nbsp;&nbsp; orthographic_m4(
re-&gt;winmat,re-&gt;viewplane.xmin, re-&gt;viewplane.xmax,
re-&gt;viewplane.ymin, re-&gt;viewplane.ymax, re-&gt;clipsta,
re-&gt;clipend);<br>
}<br>
<br>
void RE_SetView(Render *re, float mat[][4])<br>
{<br>
&nbsp;&nbsp;&nbsp; /* re-&gt;ok flag? */<br>
&nbsp;&nbsp;&nbsp; copy_m4_m4(re-&gt;viewmat, mat);<br>
&nbsp;&nbsp;&nbsp; invert_m4_m4(re-&gt;viewinv, re-&gt;viewmat);<br>
}<br>
<br>
/* image and movie output has to move to either imbuf or kernel */<br>
void RE_display_init_cb(Render *re, void *handle, void (*f)(void *handle, RenderResult *rr))<br>
{<br>
&nbsp;&nbsp;&nbsp; re-&gt;display_init= f;<br>
&nbsp;&nbsp;&nbsp; re-&gt;dih= handle;<br>
}<br>
void RE_display_clear_cb(Render *re, void *handle, void (*f)(void *handle, RenderResult *rr))<br>
{<br>
&nbsp;&nbsp;&nbsp; re-&gt;display_clear= f;<br>
&nbsp;&nbsp;&nbsp; re-&gt;dch= handle;<br>
}<br>
void RE_display_draw_cb(Render *re, void *handle, void (*f)(void *handle, RenderResult *rr, volatile rcti *rect))<br>
{<br>
&nbsp;&nbsp;&nbsp; re-&gt;display_draw= f;<br>
&nbsp;&nbsp;&nbsp; re-&gt;ddh= handle;<br>
}<br>
void RE_stats_draw_cb(Render *re, void *handle, void (*f)(void *handle, RenderStats *rs))<br>
{<br>
&nbsp;&nbsp;&nbsp; re-&gt;stats_draw= f;<br>
&nbsp;&nbsp;&nbsp; re-&gt;sdh= handle;<br>
}<br>
void RE_progress_cb(Render *re, void *handle, void (*f)(void *handle, float))<br>
{<br>
&nbsp;&nbsp;&nbsp; re-&gt;progress= f;<br>
&nbsp;&nbsp;&nbsp; re-&gt;prh= handle;<br>
}<br>
<br>
void RE_draw_lock_cb(Render *re, void *handle, void (*f)(void *handle, int i))<br>
{<br>
&nbsp;&nbsp;&nbsp; re-&gt;draw_lock= f;<br>
&nbsp;&nbsp;&nbsp; re-&gt;tbh= handle;<br>
}<br>
<br>
void RE_test_break_cb(Render *re, void *handle, int (*f)(void *handle))<br>
{<br>
&nbsp;&nbsp;&nbsp; re-&gt;test_break= f;<br>
&nbsp;&nbsp;&nbsp; re-&gt;tbh= handle;<br>
}<br>
void RE_error_cb(Render *re, void *handle, void (*f)(void *handle, const char *str))<br>
{<br>
&nbsp;&nbsp;&nbsp; re-&gt;error= f;<br>
&nbsp;&nbsp;&nbsp; re-&gt;erh= handle;<br>
}<br>
<br>
<br>
/* ********* add object data (later) ******** */<br>
<br>
/* object is considered fully prepared on correct time etc */<br>
/* includes lights */<br>
void RE_AddObject(Render *UNUSED(re), Object *UNUSED(ob))<br>
{<br>
<br>
}<br>
<br>
/* *************************************** */<br>
<br>
static int render_display_draw_enabled(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; /* don't show preprocess for previewrender sss */<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;sss_points)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return !(re-&gt;r.scemode &amp; R_PREVIEWBUTS);<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
}<br>
<br>
/* allocate osa new results for samples */<br>
static RenderResult *new_full_sample_buffers(Render *re, ListBase *lb, rcti *partrct, int crop)<br>
{<br>
&nbsp;&nbsp;&nbsp; int a;<br>
<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;osa==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return new_render_result(re, partrct, crop, RR_USEMEM);<br>
<br>
&nbsp;&nbsp;&nbsp; for(a=0; a&lt;re-&gt;osa; a++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderResult *rr= new_render_result(re, partrct, crop, RR_USEMEM);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_addtail(lb, rr);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rr-&gt;sample_nr= a;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; return lb-&gt;first;<br>
}<br>
<br>
<br>
/* the main thread call, renders an entire part */<br>
static void *do_part_thread(void *pa_v)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderPart *pa= pa_v;<br>
<br>
&nbsp;&nbsp;&nbsp; /* need to return nicely all parts on esc */<br>
&nbsp;&nbsp;&nbsp; if(R.test_break(R.tbh)==0) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!R.sss_points &amp;&amp; (R.r.scemode &amp; R_FULL_SAMPLE))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pa-&gt;result=
new_full_sample_buffers(&amp;R, &amp;pa-&gt;fullresult,
&amp;pa-&gt;disprect, pa-&gt;crop);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pa-&gt;result=
new_render_result(&amp;R, &amp;pa-&gt;disprect, pa-&gt;crop, RR_USEMEM);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(R.sss_points)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; zbufshade_sss_tile(pa);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if(R.osa)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; zbufshadeDA_tile(pa);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; zbufshade_tile(pa);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* merge too on break! */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(R.result-&gt;exrhandle) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderResult *rr, *rrpart;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(rr=
R.result, rrpart= pa-&gt;result; rr &amp;&amp; rrpart; rr= rr-&gt;next,
rrpart= rrpart-&gt;next)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; save_render_result_tile(rr, rrpart);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if(render_display_draw_enabled(&amp;R)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* on break, don't merge in result for preview renders, looks nicer */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(R.test_break(R.tbh) &amp;&amp; (R.r.scemode &amp; R_PREVIEWBUTS));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else merge_render_result(R.result, pa-&gt;result);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; pa-&gt;ready= 1;<br>
<br>
&nbsp;&nbsp;&nbsp; return NULL;<br>
}<br>
<br>
static void *do_part_thread_wrapper(void* re_v)<br>
{<br>
&nbsp;&nbsp;&nbsp; Render* re = (Render*)re_v;<br>
&nbsp;&nbsp;&nbsp; RenderPart *pa = NULL;<br>
&nbsp;&nbsp;&nbsp; rctf viewplane= re-&gt;viewplane;<br>
&nbsp;&nbsp;&nbsp; int minx = 0;<br>
&nbsp;&nbsp;&nbsp; int mycounter;<br>
<br>
&nbsp;&nbsp;&nbsp; while (re &amp;&amp; !re-&gt;test_break(re-&gt;tbh))<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_lock_thread(LOCK_RENDER);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;r.mode &amp; R_PANORAMA)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pa= find_next_pano_slice(re, &amp;minx, &amp;viewplane);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pa= find_next_part(re, minx);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (pa)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mycounter = counter;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pa-&gt;nr = mycounter;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; counter ++;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_unlock_thread(LOCK_RENDER);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CreateTiming("render thread[%d] begins new part...", mycounter);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (pa &amp;&amp; !re-&gt;test_break(re-&gt;tbh))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do_part_thread(pa);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // we need to quit... since no next part available...<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CreateTiming("render thread[%d] ends new part...", mycounter);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; return NULL;<br>
}<br>
<br>
/* calculus for how much 1 pixel rendered should rotate the 3d geometry */<br>
/* is not that simple, needs to be corrected for errors of larger viewplane sizes */<br>
/* called in initrender.c, initparts() and convertblender.c, for speedvectors */<br>
float panorama_pixel_rot(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; float psize, phi, xfac;<br>
&nbsp;&nbsp;&nbsp; float borderfac= (float)(re-&gt;disprect.xmax - re-&gt;disprect.xmin) / (float)re-&gt;winx;<br>
<br>
&nbsp;&nbsp;&nbsp; /* size of 1 pixel mapped to viewplane coords */<br>
&nbsp;&nbsp;&nbsp; psize= (re-&gt;viewplane.xmax-re-&gt;viewplane.xmin)/(float)(re-&gt;winx);<br>
&nbsp;&nbsp;&nbsp; /* angle of a pixel */<br>
&nbsp;&nbsp;&nbsp; phi= atan(psize/re-&gt;clipsta);<br>
<br>
&nbsp;&nbsp;&nbsp; /* correction factor for viewplane shifting, first calculate how much the viewplane angle is */<br>
&nbsp;&nbsp;&nbsp; xfac= borderfac*((re-&gt;viewplane.xmax-re-&gt;viewplane.xmin))/(float)re-&gt;xparts;<br>
&nbsp;&nbsp;&nbsp; xfac= atan(0.5f*xfac/re-&gt;clipsta);<br>
&nbsp;&nbsp;&nbsp; /* and how much the same viewplane angle is wrapped */<br>
&nbsp;&nbsp;&nbsp; psize= 0.5f*phi*((float)re-&gt;partx);<br>
<br>
&nbsp;&nbsp;&nbsp; /* the ratio applied to final per-pixel angle */<br>
&nbsp;&nbsp;&nbsp; phi*= xfac/psize;<br>
<br>
&nbsp;&nbsp;&nbsp; return phi;<br>
}<br>
<br>
/* call when all parts stopped rendering, to find the next Y slice */<br>
/* if slice found, it rotates the dbase */<br>
static RenderPart *find_next_pano_slice(Render *re, int *minx, rctf *viewplane)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderPart *pa, *best= NULL;<br>
<br>
&nbsp;&nbsp;&nbsp; *minx= re-&gt;winx;<br>
<br>
&nbsp;&nbsp;&nbsp; /* most left part of the non-rendering parts */<br>
&nbsp;&nbsp;&nbsp; for(pa= re-&gt;parts.first; pa; pa= pa-&gt;next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(pa-&gt;ready==0 &amp;&amp; pa-&gt;nr==0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(pa-&gt;disprect.xmin &lt; *minx) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; best= pa;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *minx= pa-&gt;disprect.xmin;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if(best) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float phi= panorama_pixel_rot(re);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; R.panodxp= (re-&gt;winx - (best-&gt;disprect.xmin + best-&gt;disprect.xmax) )/2;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; R.panodxv= ((viewplane-&gt;xmax-viewplane-&gt;xmin)*R.panodxp)/(float)(re-&gt;winx);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* shift viewplane */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; R.viewplane.xmin = viewplane-&gt;xmin + R.panodxv;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; R.viewplane.xmax = viewplane-&gt;xmax + R.panodxv;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_SetWindow(re, &amp;R.viewplane, R.clipsta, R.clipend);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; copy_m4_m4(R.winmat, re-&gt;winmat);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* rotate database according to part coordinates */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; project_renderdata(re, projectverto, 1, -R.panodxp*phi, 1);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; R.panosi= sin(R.panodxp*phi);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; R.panoco= cos(R.panodxp*phi);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; return best;<br>
}<br>
<br>
<br>
<br>
<span style="background-color: rgb(255, 153, 0);">#ifdef NICK_EDIT</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">static RenderPart *find_next_part(Render *re, int minx)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">{</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; RenderPart *pa = NULL;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; /* find center of rendered parts, image center counts for 1 too */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; for(pa= re-&gt;parts.first; pa; pa= pa-&gt;next)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(pa-&gt;nr == 0 &amp;&amp; !pa-&gt;ready)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; return pa;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">}</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">#else</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">static RenderPart *find_next_part(Render *re, int minx)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">{</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; RenderPart *pa, *best= NULL;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; /* long long int's needed because of overflow [#24414] */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; long long int centx=re-&gt;winx/2, centy=re-&gt;winy/2, tot=1;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; long long int mindist= (long long int)re-&gt;winx * (long long int)re-&gt;winy;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; /* find center of rendered parts, image center counts for 1 too */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; for(pa= re-&gt;parts.first; pa; pa= pa-&gt;next) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(pa-&gt;ready) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; centx+= (pa-&gt;disprect.xmin+pa-&gt;disprect.xmax)/2;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; centy+= (pa-&gt;disprect.ymin+pa-&gt;disprect.ymax)/2;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tot++;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; centx/=tot;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; centy/=tot;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; /* closest of the non-rendering parts */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; for(pa= re-&gt;parts.first; pa; pa= pa-&gt;next) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(pa-&gt;ready==0 &amp;&amp; pa-&gt;nr==0) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; long long int distx= centx -
(pa-&gt;disprect.xmin+pa-&gt;disprect.xmax)/2;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; long long int disty= centy -
(pa-&gt;disprect.ymin+pa-&gt;disprect.ymax)/2;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; distx= (long long int)sqrt(distx*distx + disty*disty);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(distx&lt;mindist) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;r.mode &amp; R_PANORAMA) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(pa-&gt;disprect.xmin==minx) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; best= pa;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mindist= distx;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; best= pa;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mindist= distx;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; return best;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">}</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">#endif</span><br>
<br>
static void print_part_stats(Render *re, RenderPart *pa)<br>
{<br>
&nbsp;&nbsp;&nbsp; char str[64];<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_snprintf(str, sizeof(str), "%s, Part %d-%d", re-&gt;scene-&gt;id.name+2, pa-&gt;nr, re-&gt;i.totpart);<br>
&nbsp;&nbsp;&nbsp; re-&gt;i.infostr= str;<br>
&nbsp;&nbsp;&nbsp; re-&gt;stats_draw(re-&gt;sdh, &amp;re-&gt;i);<br>
&nbsp;&nbsp;&nbsp; re-&gt;i.infostr= NULL;<br>
}<br>
<br>
/* make osa new results for samples */<br>
static RenderResult *new_full_sample_buffers_exr(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; int a;<br>
<br>
&nbsp;&nbsp;&nbsp; for(a=0; a&lt;re-&gt;osa; a++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderResult *rr= new_render_result(re, &amp;re-&gt;disprect, 0, 1);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_addtail(&amp;re-&gt;fullresult, rr);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rr-&gt;sample_nr= a;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; return re-&gt;fullresult.first;<br>
}<br>
<br>
<span style="background-color: rgb(255, 153, 0);">#ifdef NICK_EDIT</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">static void threaded_tile_processor(Render *re)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">{</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; ListBase threads;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; RenderPart *pa, *nextpa;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; rctf viewplane= re-&gt;viewplane;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; int rendering=1, drawtimer=0, hasdrawn, minx=0;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; CreateTiming("begin comparison new:....");</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_WRITE);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; /* first step; free the entire render result, make new, and/or prepare exr buffer saving */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; if(re-&gt;result==NULL || !(re-&gt;r.scemode &amp; R_PREVIEWBUTS)) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_FreeRenderResult(re-&gt;result);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;sss_points &amp;&amp; render_display_draw_enabled(re))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result= new_render_result(re, &amp;re-&gt;disprect, 0, 0);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if(re-&gt;r.scemode &amp; R_FULL_SAMPLE)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result= new_full_sample_buffers_exr(re);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result=
new_render_result(re, &amp;re-&gt;disprect, 0, re-&gt;r.scemode &amp;
(R_EXR_TILE_FILE|R_FULL_SAMPLE));</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; if(re-&gt;result==NULL)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; /* warning; no return here without closing exr file */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; initparts(re);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; if(re-&gt;result-&gt;exrhandle) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderResult *rr;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; char str[FILE_MAX];</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(rr= re-&gt;result; rr; rr= rr-&gt;next) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_unique_exr_name(re, str, rr-&gt;sample_nr);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("write exr tmp file,
%dx%d, %s\n", rr-&gt;rectx, rr-&gt;recty, str);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
IMB_exrtile_begin_write(rr-&gt;exrhandle, str, 0, rr-&gt;rectx,
rr-&gt;recty, re-&gt;partx, re-&gt;party);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; BLI_init_threads(&amp;threads, do_part_thread_wrapper, re-&gt;r.threads);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; /* assuming no new data gets added to dbase... */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; R= *re;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; /* set threadsafe break */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; R.test_break= thread_break;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; /* timer loop demands to sleep when no parts are left, so we enter loop with a part */</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; counter = 1;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; int i;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; re-&gt;r.threads; i ++)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_insert_thread(&amp;threads, re);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; while(rendering)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* on break, wait for all slots to get freed */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(g_break = re-&gt;test_break(re-&gt;tbh))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; PIL_sleep_ms(50);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // we don't want to draw anything at all.</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hasdrawn= 1;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hasdrawn= 0;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* check for ready ones to display, and if we need to continue */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; // but even all parts are ready, we still have to
wait for all threads to exit gracefully...</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // so, we just</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rendering = 0;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(pa= re-&gt;parts.first; pa; pa= pa-&gt;next)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(pa-&gt;ready)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(pa-&gt;result)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; //&nbsp; a newly finished one will be drawn
immediately</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(render_display_draw_enabled(re) &amp;&amp;
!hasdrawn)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;display_draw(re-&gt;ddh,
pa-&gt;result, NULL);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; print_part_stats(re, pa);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; free_render_result(&amp;pa-&gt;fullresult,
pa-&gt;result);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pa-&gt;result= NULL;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;i.partsdone++;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; re-&gt;progress(re-&gt;prh, re-&gt;i.partsdone /
(float)re-&gt;i.totpart);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hasdrawn= 1;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // keep rendering...</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rendering = 1;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(pa-&gt;nr
&amp;&amp; pa-&gt;result &amp;&amp; drawtimer&gt;20 &amp;&amp;
!hasdrawn)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(render_display_draw_enabled(re))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;display_draw(re-&gt;ddh,
pa-&gt;result, &amp;pa-&gt;result-&gt;renrect);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hasdrawn= 1;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(hasdrawn)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; drawtimer= 0;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; drawtimer ++;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; if(re-&gt;result-&gt;exrhandle)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderResult *rr;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_WRITE);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; save_empty_result_tiles(re);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(rr= re-&gt;result; rr; rr= rr-&gt;next)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_exr_close(rr-&gt;exrhandle);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rr-&gt;exrhandle= NULL;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; free_render_result(&amp;re-&gt;fullresult, re-&gt;result);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result= NULL;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; read_render_result(re, 0);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; /* unset threadsafety */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; g_break= 0;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; BLI_end_threads(&amp;threads);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; freeparts(re);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; re-&gt;viewplane= viewplane; /* restore viewplane, modified by pano render */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; CreateTiming("end comparison new:....");</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">}</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">#else</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">static void threaded_tile_processor(Render *re)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">{</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; ListBase threads;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; RenderPart *pa, *nextpa;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; rctf viewplane= re-&gt;viewplane;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; int rendering=1, counter= 1, drawtimer=0, hasdrawn, minx=0;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; CreateTiming("begin comparison old:....");</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_WRITE);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; /* first step; free the entire render result, make new, and/or prepare exr buffer saving */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; if(re-&gt;result==NULL || !(re-&gt;r.scemode &amp; R_PREVIEWBUTS)) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_FreeRenderResult(re-&gt;result);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;sss_points &amp;&amp; render_display_draw_enabled(re))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result= new_render_result(re, &amp;re-&gt;disprect, 0, 0);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if(re-&gt;r.scemode &amp; R_FULL_SAMPLE)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result= new_full_sample_buffers_exr(re);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result=
new_render_result(re, &amp;re-&gt;disprect, 0, re-&gt;r.scemode &amp;
(R_EXR_TILE_FILE|R_FULL_SAMPLE));</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; if(re-&gt;result==NULL)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; /* warning; no return here without closing exr file */</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; initparts(re);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; if(re-&gt;result-&gt;exrhandle) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderResult *rr;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; char str[FILE_MAX];</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(rr= re-&gt;result; rr; rr= rr-&gt;next) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_unique_exr_name(re, str, rr-&gt;sample_nr);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("write exr tmp file,
%dx%d, %s\n", rr-&gt;rectx, rr-&gt;recty, str);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
IMB_exrtile_begin_write(rr-&gt;exrhandle, str, 0, rr-&gt;rectx,
rr-&gt;recty, re-&gt;partx, re-&gt;party);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; BLI_init_threads(&amp;threads, do_part_thread, re-&gt;r.threads);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; /* assuming no new data gets added to dbase... */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; R= *re;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; /* set threadsafe break */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; R.test_break= thread_break;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; /* timer loop demands to sleep when no parts are left, so we enter loop with a part */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; if(re-&gt;r.mode &amp; R_PANORAMA)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; nextpa= find_next_pano_slice(re, &amp;minx, &amp;viewplane);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; else</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; nextpa= find_next_part(re, 0);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; while(rendering) {</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;test_break(re-&gt;tbh))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; PIL_sleep_ms(50);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if(nextpa &amp;&amp; BLI_available_threads(&amp;threads)) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; drawtimer= 0;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; nextpa-&gt;nr=
counter++;&nbsp;&nbsp;&nbsp; /* for nicest part, and for stats */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; nextpa-&gt;thread=
BLI_available_thread_index(&amp;threads);&nbsp;&nbsp;&nbsp; /* sample
index */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_insert_thread(&amp;threads, nextpa);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; nextpa= find_next_part(re, minx);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if(re-&gt;r.mode &amp; R_PANORAMA) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(nextpa==NULL &amp;&amp;
BLI_available_threads(&amp;threads)==re-&gt;r.threads)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; nextpa=
find_next_pano_slice(re, &amp;minx, &amp;viewplane);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; PIL_sleep_ms(50);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; drawtimer++;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; PIL_sleep_ms(50);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; drawtimer++;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* check for ready ones to display, and if we need to continue */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rendering= 0;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hasdrawn= 0;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(pa= re-&gt;parts.first; pa; pa= pa-&gt;next) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(pa-&gt;ready) {</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_remove_thread(&amp;threads, pa);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(pa-&gt;result) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(render_display_draw_enabled(re))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;display_draw(re-&gt;ddh,
pa-&gt;result, NULL);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; print_part_stats(re, pa);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; free_render_result(&amp;pa-&gt;fullresult,
pa-&gt;result);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pa-&gt;result= NULL;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;i.partsdone++;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; re-&gt;progress(re-&gt;prh, re-&gt;i.partsdone /
(float)re-&gt;i.totpart);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hasdrawn= 1;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rendering= 1;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(pa-&gt;nr
&amp;&amp; pa-&gt;result &amp;&amp; drawtimer&gt;20) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(render_display_draw_enabled(re))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;display_draw(re-&gt;ddh,
pa-&gt;result, &amp;pa-&gt;result-&gt;renrect);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hasdrawn= 1;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(hasdrawn)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; drawtimer= 0;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* on break, wait for all slots to get freed */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if( (g_break=re-&gt;test_break(re-&gt;tbh))
&amp;&amp; BLI_available_threads(&amp;threads)==re-&gt;r.threads)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rendering= 0;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; if(re-&gt;result-&gt;exrhandle) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderResult *rr;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_WRITE);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; save_empty_result_tiles(re);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(rr= re-&gt;result; rr; rr= rr-&gt;next) {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_exr_close(rr-&gt;exrhandle);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rr-&gt;exrhandle= NULL;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; free_render_result(&amp;re-&gt;fullresult, re-&gt;result);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result= NULL;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; read_render_result(re, 0);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; /* unset threadsafety */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; g_break= 0;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; BLI_end_threads(&amp;threads);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; freeparts(re);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; re-&gt;viewplane= viewplane; /* restore viewplane, modified by pano render */</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; CreateTiming("end comparison old:....");</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">}</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">#endif</span><br>
<br>
<br>
/* currently only called by preview renders and envmap */<br>
void RE_TileProcessor(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; threaded_tile_processor(re);<br>
}<br>
<br>
/* ************&nbsp; This part uses API, for rendering Blender scenes ********** */<br>
<br>
static int external_render_3d(Render *re, int do_all);<br>
<br>
static void do_render_3d(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; /* try external */<br>
&nbsp;&nbsp;&nbsp; if(external_render_3d(re, 0))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return;<br>
<br>
&nbsp;&nbsp;&nbsp; /* internal */<br>
<br>
//&nbsp;&nbsp;&nbsp; re-&gt;cfra= cfra;&nbsp;&nbsp;&nbsp; /* &lt;- unused! */<br>
&nbsp;&nbsp;&nbsp; re-&gt;scene-&gt;r.subframe = re-&gt;mblur_offs + re-&gt;field_offs;<br>
<br>
&nbsp;&nbsp;&nbsp; /* lock drawing in UI during data phase */<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;draw_lock)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;draw_lock(re-&gt;dlh, 1);<br>
<br>
&nbsp;&nbsp;&nbsp; /* make render verts/faces/halos/lamps */<br>
&nbsp;&nbsp;&nbsp; if(render_scene_needs_vector(re))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_Database_FromScene_Vectors(re, re-&gt;main, re-&gt;scene, re-&gt;lay);<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; RE_Database_FromScene(re, re-&gt;main, re-&gt;scene, re-&gt;lay, 1);<br>
<br>
&nbsp;&nbsp;&nbsp; /* clear UI drawing locks */<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;draw_lock)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;draw_lock(re-&gt;dlh, 0);<br>
<br>
&nbsp;&nbsp;&nbsp; threaded_tile_processor(re);<br>
&nbsp;&nbsp;&nbsp; /* do left-over 3d post effects (flares) */<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;flag &amp; R_HALO)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!re-&gt;test_break(re-&gt;tbh))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; add_halo_flare(re);<br>
<br>
&nbsp;&nbsp;&nbsp; /* free all render verts etc */<br>
&nbsp;&nbsp;&nbsp; RE_Database_Free(re);<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;scene-&gt;r.subframe = 0.f;<br>
}<br>
<br>
/* called by blur loop, accumulate RGBA key alpha */<br>
static void addblur_rect_key(RenderResult *rr, float *rectf, float *rectf1, float blurfac)<br>
{<br>
&nbsp;&nbsp;&nbsp; float mfac= 1.0f - blurfac;<br>
&nbsp;&nbsp;&nbsp; int a, b, stride= 4*rr-&gt;rectx;<br>
&nbsp;&nbsp;&nbsp; int len= stride*sizeof(float);<br>
<br>
&nbsp;&nbsp;&nbsp; for(a=0; a&lt;rr-&gt;recty; a++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(blurfac==1.0f) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memcpy(rectf, rectf1, len);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float *rf= rectf, *rf1= rectf1;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for( b= rr-&gt;rectx; b&gt;0; b--, rf+=4, rf1+=4) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rf1[3]&lt;0.01f)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rf[3]= mfac*rf[3];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if(rf[3]&lt;0.01f) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rf[0]= rf1[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rf[1]= rf1[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rf[2]= rf1[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rf[3]= blurfac*rf1[3];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rf[0]= mfac*rf[0] +
blurfac*rf1[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rf[1]= mfac*rf[1] +
blurfac*rf1[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rf[2]= mfac*rf[2] +
blurfac*rf1[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rf[3]= mfac*rf[3] +
blurfac*rf1[3];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rectf+= stride;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rectf1+= stride;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
/* called by blur loop, accumulate renderlayers */<br>
static void addblur_rect(RenderResult *rr, float *rectf, float *rectf1, float blurfac, int channels)<br>
{<br>
&nbsp;&nbsp;&nbsp; float mfac= 1.0f - blurfac;<br>
&nbsp;&nbsp;&nbsp; int a, b, stride= channels*rr-&gt;rectx;<br>
&nbsp;&nbsp;&nbsp; int len= stride*sizeof(float);<br>
<br>
&nbsp;&nbsp;&nbsp; for(a=0; a&lt;rr-&gt;recty; a++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(blurfac==1.0f) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memcpy(rectf, rectf1, len);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float *rf= rectf, *rf1= rectf1;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for( b= rr-&gt;rectx*channels; b&gt;0; b--, rf++, rf1++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rf[0]= mfac*rf[0] + blurfac*rf1[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rectf+= stride;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rectf1+= stride;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
<br>
/* called by blur loop, accumulate renderlayers */<br>
static void merge_renderresult_blur(RenderResult *rr, RenderResult *brr, float blurfac, int key_alpha)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderLayer *rl, *rl1;<br>
&nbsp;&nbsp;&nbsp; RenderPass *rpass, *rpass1;<br>
<br>
&nbsp;&nbsp;&nbsp; rl1= brr-&gt;layers.first;<br>
&nbsp;&nbsp;&nbsp; for(rl= rr-&gt;layers.first; rl &amp;&amp; rl1; rl= rl-&gt;next, rl1= rl1-&gt;next) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* combined */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rl-&gt;rectf &amp;&amp; rl1-&gt;rectf) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(key_alpha)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; addblur_rect_key(rr, rl-&gt;rectf, rl1-&gt;rectf,
blurfac);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; addblur_rect(rr, rl-&gt;rectf, rl1-&gt;rectf,
blurfac, 4);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* passes are allocated in sync */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rpass1= rl1-&gt;passes.first;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(rpass= rl-&gt;passes.first;
rpass &amp;&amp; rpass1; rpass= rpass-&gt;next, rpass1=
rpass1-&gt;next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
addblur_rect(rr, rpass-&gt;rect, rpass1-&gt;rect, blurfac,
rpass-&gt;channels);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
/* main blur loop, can be called by fields too */<br>
static void do_render_blur_3d(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderResult *rres;<br>
&nbsp;&nbsp;&nbsp; float blurfac;<br>
&nbsp;&nbsp;&nbsp; int blur= re-&gt;r.mblur_samples;<br>
<br>
&nbsp;&nbsp;&nbsp; /* create accumulation render result */<br>
&nbsp;&nbsp;&nbsp; rres= new_render_result(re, &amp;re-&gt;disprect, 0, RR_USEMEM);<br>
<br>
&nbsp;&nbsp;&nbsp; /* do the blur steps */<br>
&nbsp;&nbsp;&nbsp; while(blur--) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;mblur_offs =
re-&gt;r.blurfac*((float)(re-&gt;r.mblur_samples-blur))/(float)re-&gt;r.mblur_samples;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;i.curblur= re-&gt;r.mblur_samples-blur;&nbsp;&nbsp;&nbsp; /* stats */<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do_render_3d(re);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; blurfac= 1.0f/(float)(re-&gt;r.mblur_samples-blur);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; merge_renderresult_blur(rres,
re-&gt;result, blurfac, re-&gt;r.alphamode &amp; R_ALPHAKEY);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;test_break(re-&gt;tbh)) break;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* swap results */<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_WRITE);<br>
&nbsp;&nbsp;&nbsp; RE_FreeRenderResult(re-&gt;result);<br>
&nbsp;&nbsp;&nbsp; re-&gt;result= rres;<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;mblur_offs = 0.0f;<br>
&nbsp;&nbsp;&nbsp; re-&gt;i.curblur= 0;&nbsp;&nbsp;&nbsp; /* stats */<br>
<br>
&nbsp;&nbsp;&nbsp; /* weak... the display callback wants an active renderlayer pointer... */<br>
&nbsp;&nbsp;&nbsp; re-&gt;result-&gt;renlay= render_get_active_layer(re, re-&gt;result);<br>
&nbsp;&nbsp;&nbsp; re-&gt;display_draw(re-&gt;ddh, re-&gt;result, NULL);<br>
}<br>
<br>
<br>
/* function assumes rectf1 and rectf2 to be half size of rectf */<br>
static void interleave_rect(RenderResult *rr, float *rectf, float *rectf1, float *rectf2, int channels)<br>
{<br>
&nbsp;&nbsp;&nbsp; int a, stride= channels*rr-&gt;rectx;<br>
&nbsp;&nbsp;&nbsp; int len= stride*sizeof(float);<br>
<br>
&nbsp;&nbsp;&nbsp; for(a=0; a&lt;rr-&gt;recty; a+=2) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memcpy(rectf, rectf1, len);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rectf+= stride;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rectf1+= stride;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memcpy(rectf, rectf2, len);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rectf+= stride;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rectf2+= stride;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
/* merge render results of 2 fields */<br>
static void merge_renderresult_fields(RenderResult *rr, RenderResult *rr1, RenderResult *rr2)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderLayer *rl, *rl1, *rl2;<br>
&nbsp;&nbsp;&nbsp; RenderPass *rpass, *rpass1, *rpass2;<br>
<br>
&nbsp;&nbsp;&nbsp; rl1= rr1-&gt;layers.first;<br>
&nbsp;&nbsp;&nbsp; rl2= rr2-&gt;layers.first;<br>
&nbsp;&nbsp;&nbsp; for(rl= rr-&gt;layers.first; rl &amp;&amp; rl1
&amp;&amp; rl2; rl= rl-&gt;next, rl1= rl1-&gt;next, rl2= rl2-&gt;next) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* combined */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rl-&gt;rectf &amp;&amp; rl1-&gt;rectf &amp;&amp; rl2-&gt;rectf)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; interleave_rect(rr, rl-&gt;rectf, rl1-&gt;rectf, rl2-&gt;rectf, 4);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* passes are allocated in sync */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rpass1= rl1-&gt;passes.first;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rpass2= rl2-&gt;passes.first;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(rpass= rl-&gt;passes.first;
rpass &amp;&amp; rpass1 &amp;&amp; rpass2; rpass= rpass-&gt;next,
rpass1= rpass1-&gt;next, rpass2= rpass2-&gt;next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
interleave_rect(rr, rpass-&gt;rect, rpass1-&gt;rect, rpass2-&gt;rect,
rpass-&gt;channels);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
<br>
/* interleaves 2 frames */<br>
static void do_render_fields_3d(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderResult *rr1, *rr2= NULL;<br>
<br>
&nbsp;&nbsp;&nbsp; /* no render result was created, we can safely halve render y */<br>
&nbsp;&nbsp;&nbsp; re-&gt;winy /= 2;<br>
&nbsp;&nbsp;&nbsp; re-&gt;recty /= 2;<br>
&nbsp;&nbsp;&nbsp; re-&gt;disprect.ymin /= 2;<br>
&nbsp;&nbsp;&nbsp; re-&gt;disprect.ymax /= 2;<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;i.curfield= 1;&nbsp;&nbsp;&nbsp; /* stats */<br>
<br>
&nbsp;&nbsp;&nbsp; /* first field, we have to call camera routine for correct aspect and subpixel offset */<br>
&nbsp;&nbsp;&nbsp; RE_SetCamera(re, re-&gt;scene-&gt;camera);<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;r.mode &amp; R_MBLUR &amp;&amp; (re-&gt;r.scemode &amp; R_FULL_SAMPLE)==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do_render_blur_3d(re);<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do_render_3d(re);<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_WRITE);<br>
&nbsp;&nbsp;&nbsp; rr1= re-&gt;result;<br>
&nbsp;&nbsp;&nbsp; re-&gt;result= NULL;<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);<br>
<br>
&nbsp;&nbsp;&nbsp; /* second field */<br>
&nbsp;&nbsp;&nbsp; if(!re-&gt;test_break(re-&gt;tbh)) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;i.curfield= 2;&nbsp;&nbsp;&nbsp; /* stats */<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;flag |= R_SEC_FIELD;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if((re-&gt;r.mode &amp; R_FIELDSTILL)==0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;field_offs = 0.5f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_SetCamera(re, re-&gt;scene-&gt;camera);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;r.mode &amp; R_MBLUR &amp;&amp; (re-&gt;r.scemode &amp; R_FULL_SAMPLE)==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do_render_blur_3d(re);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do_render_3d(re);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;flag &amp;= ~R_SEC_FIELD;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;field_offs = 0.0f;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rr2= re-&gt;result;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* allocate original height new buffers */<br>
&nbsp;&nbsp;&nbsp; re-&gt;winy *= 2;<br>
&nbsp;&nbsp;&nbsp; re-&gt;recty *= 2;<br>
&nbsp;&nbsp;&nbsp; re-&gt;disprect.ymin *= 2;<br>
&nbsp;&nbsp;&nbsp; re-&gt;disprect.ymax *= 2;<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_WRITE);<br>
&nbsp;&nbsp;&nbsp; re-&gt;result= new_render_result(re, &amp;re-&gt;disprect, 0, RR_USEMEM);<br>
<br>
&nbsp;&nbsp;&nbsp; if(rr2) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;r.mode &amp; R_ODDFIELD)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; merge_renderresult_fields(re-&gt;result, rr2, rr1);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; merge_renderresult_fields(re-&gt;result, rr1, rr2);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_FreeRenderResult(rr2);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; RE_FreeRenderResult(rr1);<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;i.curfield= 0;&nbsp;&nbsp;&nbsp; /* stats */<br>
<br>
&nbsp;&nbsp;&nbsp; /* weak... the display callback wants an active renderlayer pointer... */<br>
&nbsp;&nbsp;&nbsp; re-&gt;result-&gt;renlay= render_get_active_layer(re, re-&gt;result);<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;display_draw(re-&gt;ddh, re-&gt;result, NULL);<br>
}<br>
<br>
static void load_backbuffer(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;r.alphamode == R_ADDSKY) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ImBuf *ibuf;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; char name[256];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_strncpy(name, re-&gt;r.backbuf, sizeof(name));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_path_abs(name, re-&gt;main-&gt;name);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_path_frame(name, re-&gt;r.cfra, 0);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;backbuf) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;backbuf-&gt;id.us--;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;backbuf-&gt;id.us&lt;1)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; BKE_image_signal(re-&gt;backbuf, NULL,
IMA_SIGNAL_RELOAD);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;backbuf= BKE_add_image_file(name);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ibuf= BKE_image_get_ibuf(re-&gt;backbuf, NULL);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(ibuf==NULL) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // error() doesnt work with render window open<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //error("No backbuf there!");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("Error: No backbuf %s\n", name);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (re-&gt;r.mode &amp; R_FIELDS)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; image_de_interlace(re-&gt;backbuf, re-&gt;r.mode
&amp; R_ODDFIELD);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
/* main render routine, no compositing */<br>
static void do_render_fields_blur_3d(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; /* also check for camera here */<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;scene-&gt;camera==NULL) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("ERROR: Cannot render, no camera\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; G.afbreek= 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* backbuffer initialize */<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;r.bufflag &amp; 1)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; load_backbuffer(re);<br>
<br>
&nbsp;&nbsp;&nbsp; /* now use renderdata and camera to set viewplane */<br>
&nbsp;&nbsp;&nbsp; RE_SetCamera(re, re-&gt;scene-&gt;camera);<br>
<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;r.mode &amp; R_FIELDS)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do_render_fields_3d(re);<br>
&nbsp;&nbsp;&nbsp; else if(re-&gt;r.mode &amp; R_MBLUR &amp;&amp; (re-&gt;r.scemode &amp; R_FULL_SAMPLE)==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do_render_blur_3d(re);<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do_render_3d(re);<br>
<br>
&nbsp;&nbsp;&nbsp; /* when border render, check if we have to insert it in black */<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;result) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;r.mode &amp; R_BORDER) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if((re-&gt;r.mode &amp; R_CROP)==0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderResult *rres;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex,
THREAD_LOCK_WRITE);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* sub-rect for merge call later on */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result-&gt;tilerect= re-&gt;disprect;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* this copying sequence could become function? */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* weak is: it chances disprect from border */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;disprect.xmin= re-&gt;disprect.ymin= 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;disprect.xmax= re-&gt;winx;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;disprect.ymax= re-&gt;winy;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;rectx= re-&gt;winx;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;recty= re-&gt;winy;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; rres= new_render_result(re, &amp;re-&gt;disprect, 0,
RR_USEMEM);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; merge_render_result(rres, re-&gt;result);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_FreeRenderResult(re-&gt;result);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result= rres;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; /* weak... the display callback wants an active
renderlayer pointer... */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; re-&gt;result-&gt;renlay=
render_get_active_layer(re, re-&gt;result);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;display_init(re-&gt;dih, re-&gt;result);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; re-&gt;display_draw(re-&gt;ddh, re-&gt;result, NULL);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; /* set offset (again) for use in compositor,
disprect was manipulated. */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result-&gt;xof= 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result-&gt;yof= 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
<br>
/* within context of current Render *re, render another scene.<br>
&nbsp;&nbsp; it uses current render image size and disprect, but doesn't execute composite<br>
*/<br>
static void render_scene(Render *re, Scene *sce, int cfra)<br>
{<br>
&nbsp;&nbsp;&nbsp; Render *resc= RE_NewRender(sce-&gt;id.name);<br>
&nbsp;&nbsp;&nbsp; int winx= re-&gt;winx, winy= re-&gt;winy;<br>
<br>
&nbsp;&nbsp;&nbsp; sce-&gt;r.cfra= cfra;<br>
<br>
&nbsp;&nbsp;&nbsp; scene_camera_switch_update(sce);<br>
<br>
&nbsp;&nbsp;&nbsp; /* exception: scene uses own size (unfinished code) */<br>
&nbsp;&nbsp;&nbsp; if(0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; winx= (sce-&gt;r.size*sce-&gt;r.xsch)/100;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; winy= (sce-&gt;r.size*sce-&gt;r.ysch)/100;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* initial setup */<br>
&nbsp;&nbsp;&nbsp; RE_InitState(resc, re, &amp;sce-&gt;r, NULL, winx, winy, &amp;re-&gt;disprect);<br>
<br>
&nbsp;&nbsp;&nbsp; /* still unsure entity this... */<br>
&nbsp;&nbsp;&nbsp; resc-&gt;main= re-&gt;main;<br>
&nbsp;&nbsp;&nbsp; resc-&gt;scene= sce;<br>
&nbsp;&nbsp;&nbsp; resc-&gt;lay= sce-&gt;lay;<br>
<br>
&nbsp;&nbsp;&nbsp; /* ensure scene has depsgraph, base flags etc OK */<br>
&nbsp;&nbsp;&nbsp; set_scene_bg(re-&gt;main, sce);<br>
<br>
&nbsp;&nbsp;&nbsp; /* copy callbacks */<br>
&nbsp;&nbsp;&nbsp; resc-&gt;display_draw= re-&gt;display_draw;<br>
&nbsp;&nbsp;&nbsp; resc-&gt;ddh= re-&gt;ddh;<br>
&nbsp;&nbsp;&nbsp; resc-&gt;test_break= re-&gt;test_break;<br>
&nbsp;&nbsp;&nbsp; resc-&gt;tbh= re-&gt;tbh;<br>
&nbsp;&nbsp;&nbsp; resc-&gt;stats_draw= re-&gt;stats_draw;<br>
&nbsp;&nbsp;&nbsp; resc-&gt;sdh= re-&gt;sdh;<br>
<br>
&nbsp;&nbsp;&nbsp; do_render_fields_blur_3d(resc);<br>
}<br>
<br>
static void tag_scenes_for_render(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; bNode *node;<br>
&nbsp;&nbsp;&nbsp; Scene *sce;<br>
<br>
&nbsp;&nbsp;&nbsp; for(sce= re-&gt;main-&gt;scene.first; sce; sce= sce-&gt;id.next)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sce-&gt;id.flag &amp;= ~LIB_DOIT;<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;scene-&gt;id.flag |= LIB_DOIT;<br>
<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;scene-&gt;nodetree==NULL) return;<br>
<br>
&nbsp;&nbsp;&nbsp; /* check for render-layers nodes using other scenes, we tag them LIB_DOIT */<br>
&nbsp;&nbsp;&nbsp; for(node= re-&gt;scene-&gt;nodetree-&gt;nodes.first; node; node= node-&gt;next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(node-&gt;type==CMP_NODE_R_LAYERS) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(node-&gt;id) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(node-&gt;id != (ID *)re-&gt;scene)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; node-&gt;id-&gt;flag |= LIB_DOIT;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
}<br>
<br>
static void ntree_render_scenes(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; bNode *node;<br>
&nbsp;&nbsp;&nbsp; int cfra= re-&gt;scene-&gt;r.cfra;<br>
&nbsp;&nbsp;&nbsp; int restore_scene= 0;<br>
<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;scene-&gt;nodetree==NULL) return;<br>
<br>
&nbsp;&nbsp;&nbsp; tag_scenes_for_render(re);<br>
<br>
&nbsp;&nbsp;&nbsp; /* now foreach render-result node tagged we do a full render */<br>
&nbsp;&nbsp;&nbsp; /* results are stored in a way compisitor will find it */<br>
&nbsp;&nbsp;&nbsp; for(node= re-&gt;scene-&gt;nodetree-&gt;nodes.first; node; node= node-&gt;next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(node-&gt;type==CMP_NODE_R_LAYERS) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(node-&gt;id &amp;&amp; node-&gt;id != (ID *)re-&gt;scene) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(node-&gt;id-&gt;flag &amp; LIB_DOIT) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Scene *scene =
(Scene*)node-&gt;id;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_scene(re, scene, cfra);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; restore_scene= (scene !=
re-&gt;scene);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; node-&gt;id-&gt;flag &amp;=
~LIB_DOIT;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* restore scene if we rendered another last */<br>
&nbsp;&nbsp;&nbsp; if(restore_scene)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; set_scene_bg(re-&gt;main, re-&gt;scene);<br>
}<br>
<br>
/* helper call to detect if theres a composite with render-result node */<br>
static int composite_needs_render(Scene *sce)<br>
{<br>
&nbsp;&nbsp;&nbsp; bNodeTree *ntree= sce-&gt;nodetree;<br>
&nbsp;&nbsp;&nbsp; bNode *node;<br>
<br>
&nbsp;&nbsp;&nbsp; if(ntree==NULL) return 1;<br>
&nbsp;&nbsp;&nbsp; if(sce-&gt;use_nodes==0) return 1;<br>
&nbsp;&nbsp;&nbsp; if((sce-&gt;r.scemode &amp; R_DOCOMP)==0) return 1;<br>
<br>
&nbsp;&nbsp;&nbsp; for(node= ntree-&gt;nodes.first; node; node= node-&gt;next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(node-&gt;type==CMP_NODE_R_LAYERS)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(node-&gt;id==NULL || node-&gt;id==&amp;sce-&gt;id)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
/* bad call... need to think over proper method still */<br>
static void render_composit_stats(void *UNUSED(arg), char *str)<br>
{<br>
&nbsp;&nbsp;&nbsp; R.i.infostr= str;<br>
&nbsp;&nbsp;&nbsp; R.stats_draw(R.sdh, &amp;R.i);<br>
&nbsp;&nbsp;&nbsp; R.i.infostr= NULL;<br>
}<br>
<br>
<br>
/* reads all buffers, calls optional composite, merges in first result-&gt;rectf */<br>
static void do_merge_fullsample(Render *re, bNodeTree *ntree)<br>
{<br>
&nbsp;&nbsp;&nbsp; float *rectf, filt[3][3];<br>
&nbsp;&nbsp;&nbsp; int sample;<br>
<br>
&nbsp;&nbsp;&nbsp; /* filtmask needs it */<br>
&nbsp;&nbsp;&nbsp; R= *re;<br>
<br>
&nbsp;&nbsp;&nbsp; /* we accumulate in here */<br>
&nbsp;&nbsp;&nbsp; rectf= MEM_mapallocN(re-&gt;rectx*re-&gt;recty*sizeof(float)*4, "fullsample rgba");<br>
<br>
&nbsp;&nbsp;&nbsp; for(sample=0; sample&lt;re-&gt;r.osa; sample++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderResult rres;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int x, y, mask;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* set all involved renders on the samplebuffers (first was done by render itself) */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* also function below assumes this */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(sample) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Render *re1;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tag_scenes_for_render(re);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(re1= RenderGlobal.renderlist.first; re1; re1= re1-&gt;next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re1-&gt;scene-&gt;id.flag &amp; LIB_DOIT) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re1-&gt;r.scemode &amp;
R_FULL_SAMPLE) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
read_render_result(re1, sample);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
ntreeCompositTagRender(re1-&gt;scene); /* ensure node gets exec to put
buffers on stack */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* composite */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(ntree) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntreeCompositTagRender(re-&gt;scene);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntreeCompositTagAnimated(ntree);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntreeCompositExecTree(ntree, &amp;re-&gt;r, G.background==0);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* ensure we get either composited result or the active layer */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_AcquireResultImage(re, &amp;rres);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* accumulate with filter, and clip */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mask= (1&lt;&lt;sample);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mask_array(mask, filt);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(y=0; y&lt;re-&gt;recty; y++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float *rf= rectf + 4*y*re-&gt;rectx;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float *col= rres.rectf + 4*y*re-&gt;rectx;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(x=0; x&lt;re-&gt;rectx; x++, rf+=4, col+=4) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* clamping to 1.0 is needed for correct AA */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(col[0]&lt;0.0f) col[0]=0.0f; else if(col[0] &gt;
1.0f) col[0]= 1.0f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(col[1]&lt;0.0f) col[1]=0.0f; else if(col[1] &gt;
1.0f) col[1]= 1.0f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(col[2]&lt;0.0f) col[2]=0.0f; else if(col[2] &gt;
1.0f) col[2]= 1.0f;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; add_filt_fmask_coord(filt, col, rf, re-&gt;rectx,
re-&gt;recty, x, y);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_ReleaseResultImage(re);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* show stuff */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(sample!=re-&gt;osa-1) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* weak... the
display callback wants an active renderlayer pointer... */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result-&gt;renlay= render_get_active_layer(re, re-&gt;result);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;display_draw(re-&gt;ddh, re-&gt;result, NULL);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;test_break(re-&gt;tbh))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_WRITE);<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;result-&gt;rectf)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MEM_freeN(re-&gt;result-&gt;rectf);<br>
&nbsp;&nbsp;&nbsp; re-&gt;result-&gt;rectf= rectf;<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);<br>
}<br>
<br>
/* called externally, via compositor */<br>
void RE_MergeFullSample(Render *re, Main *bmain, Scene *sce, bNodeTree *ntree)<br>
{<br>
&nbsp;&nbsp;&nbsp; Scene *scene;<br>
&nbsp;&nbsp;&nbsp; bNode *node;<br>
<br>
&nbsp;&nbsp;&nbsp; /* default start situation */<br>
&nbsp;&nbsp;&nbsp; G.afbreek= 0;<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;main= bmain;<br>
&nbsp;&nbsp;&nbsp; re-&gt;scene= sce;<br>
<br>
&nbsp;&nbsp;&nbsp; /* first call RE_ReadRenderResult on every renderlayer scene. this creates Render structs */<br>
<br>
&nbsp;&nbsp;&nbsp; /* tag scenes unread */<br>
&nbsp;&nbsp;&nbsp; for(scene= re-&gt;main-&gt;scene.first; scene; scene= scene-&gt;id.next)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; scene-&gt;id.flag |= LIB_DOIT;<br>
<br>
&nbsp;&nbsp;&nbsp; for(node= ntree-&gt;nodes.first; node; node= node-&gt;next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(node-&gt;type==CMP_NODE_R_LAYERS) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Scene *nodescene= (Scene *)node-&gt;id;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(nodescene==NULL) nodescene= sce;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(nodescene-&gt;id.flag &amp; LIB_DOIT) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; nodescene-&gt;r.mode |= R_OSA;&nbsp;&nbsp;&nbsp; /*
render struct needs tables */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_ReadRenderResult(sce, nodescene);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; nodescene-&gt;id.flag &amp;= ~LIB_DOIT;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* own render result should be read/allocated */<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;scene-&gt;id.flag &amp; LIB_DOIT)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_ReadRenderResult(re-&gt;scene, re-&gt;scene);<br>
<br>
&nbsp;&nbsp;&nbsp; /* and now we can draw (result is there) */<br>
&nbsp;&nbsp;&nbsp; re-&gt;display_init(re-&gt;dih, re-&gt;result);<br>
&nbsp;&nbsp;&nbsp; re-&gt;display_clear(re-&gt;dch, re-&gt;result);<br>
<br>
&nbsp;&nbsp;&nbsp; do_merge_fullsample(re, ntree);<br>
}<br>
<br>
/* returns fully composited render-result on given time step (in RenderData) */<br>
static void do_render_composite_fields_blur_3d(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; bNodeTree *ntree= re-&gt;scene-&gt;nodetree;<br>
&nbsp;&nbsp;&nbsp; int update_newframe=0;<br>
<br>
&nbsp;&nbsp;&nbsp; /* INIT seeding, compositor can use random texture */<br>
&nbsp;&nbsp;&nbsp; BLI_srandom(re-&gt;r.cfra);<br>
<br>
&nbsp;&nbsp;&nbsp; if(composite_needs_render(re-&gt;scene)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* save memory... free all cached images */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntreeFreeCache(ntree);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do_render_fields_blur_3d(re);<br>
&nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* scene render process already updates animsys */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; update_newframe = 1;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* swap render result */<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;r.scemode &amp; R_SINGLE_LAYER)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pop_render_result(re);<br>
<br>
&nbsp;&nbsp;&nbsp; if(!re-&gt;test_break(re-&gt;tbh)) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(ntree) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntreeCompositTagRender(re-&gt;scene);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntreeCompositTagAnimated(ntree);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(ntree &amp;&amp; re-&gt;r.scemode &amp; R_DOCOMP) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* checks if there are render-result nodes that need scene */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if((re-&gt;r.scemode &amp; R_SINGLE_LAYER)==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntree_render_scenes(re);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!re-&gt;test_break(re-&gt;tbh)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntree-&gt;stats_draw= render_composit_stats;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntree-&gt;test_break= re-&gt;test_break;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntree-&gt;progress= re-&gt;progress;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntree-&gt;sdh= re-&gt;sdh;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntree-&gt;tbh= re-&gt;tbh;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntree-&gt;prh= re-&gt;prh;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* in case it was never initialized */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; R.sdh= re-&gt;sdh;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; R.stats_draw= re-&gt;stats_draw;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (update_newframe)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
scene_update_for_newframe(re-&gt;main, re-&gt;scene, re-&gt;lay);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;r.scemode &amp; R_FULL_SAMPLE)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do_merge_fullsample(re, ntree);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntreeCompositExecTree(ntree,
&amp;re-&gt;r, G.background==0);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntree-&gt;stats_draw= NULL;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntree-&gt;test_break= NULL;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntree-&gt;progress= NULL;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntree-&gt;tbh= ntree-&gt;sdh= ntree-&gt;prh= NULL;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if(re-&gt;r.scemode &amp; R_FULL_SAMPLE)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do_merge_fullsample(re, NULL);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* weak... the display callback wants an active renderlayer pointer... */<br>
&nbsp;&nbsp;&nbsp; re-&gt;result-&gt;renlay= render_get_active_layer(re, re-&gt;result);<br>
&nbsp;&nbsp;&nbsp; re-&gt;display_draw(re-&gt;ddh, re-&gt;result, NULL);<br>
}<br>
<br>
static void renderresult_stampinfo(Scene *scene)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderResult rres;<br>
&nbsp;&nbsp;&nbsp; Render *re= RE_GetRender(scene-&gt;id.name);<br>
<br>
&nbsp;&nbsp;&nbsp; /* this is the basic trick to get the displayed float or char rect from render result */<br>
&nbsp;&nbsp;&nbsp; RE_AcquireResultImage(re, &amp;rres);<br>
&nbsp;&nbsp;&nbsp; BKE_stamp_buf(scene, (unsigned char *)rres.rect32, rres.rectf, rres.rectx, rres.recty, 4);<br>
&nbsp;&nbsp;&nbsp; RE_ReleaseResultImage(re);<br>
}<br>
<br>
static int seq_render_active(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; Editing *ed;<br>
&nbsp;&nbsp;&nbsp; Sequence *seq;<br>
<br>
&nbsp;&nbsp;&nbsp; ed = re-&gt;scene-&gt;ed;<br>
<br>
&nbsp;&nbsp;&nbsp; if (!(re-&gt;r.scemode &amp; R_DOSEQ) || !ed || !ed-&gt;seqbase.first)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
<br>
&nbsp;&nbsp;&nbsp; for (seq= ed-&gt;seqbase.first; seq; seq= seq-&gt;next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (seq-&gt;type != SEQ_SOUND)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static void do_render_seq(Render * re)<br>
{<br>
&nbsp;&nbsp;&nbsp; static int recurs_depth = 0;<br>
&nbsp;&nbsp;&nbsp; struct ImBuf *ibuf;<br>
&nbsp;&nbsp;&nbsp; RenderResult *rr; /* don't assign re-&gt;result here as it might change during give_ibuf_seq */<br>
&nbsp;&nbsp;&nbsp; int cfra = re-&gt;r.cfra;<br>
&nbsp;&nbsp;&nbsp; SeqRenderData context;<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;i.cfra= cfra;<br>
<br>
&nbsp;&nbsp;&nbsp; if(recurs_depth==0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* otherwise sequencer animation isnt updated */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
BKE_animsys_evaluate_all_animation(re-&gt;main, (float)cfra); // XXX,
was BKE_curframe(re-&gt;scene)<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; recurs_depth++;<br>
<br>
&nbsp;&nbsp;&nbsp; context = seq_new_render_data(re-&gt;main, re-&gt;scene,<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
re-&gt;result-&gt;rectx, re-&gt;result-&gt;recty,<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100);<br>
<br>
&nbsp;&nbsp;&nbsp; ibuf = give_ibuf_seq(context, cfra, 0);<br>
<br>
&nbsp;&nbsp;&nbsp; recurs_depth--;<br>
<br>
&nbsp;&nbsp;&nbsp; rr = re-&gt;result;<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_WRITE);<br>
<br>
&nbsp;&nbsp;&nbsp; if(ibuf) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(ibuf-&gt;rect_float) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (!rr-&gt;rectf)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; rr-&gt;rectf=
MEM_mallocN(4*sizeof(float)*rr-&gt;rectx*rr-&gt;recty, "render_seq
rectf");<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* color
management: when off ensure rectf is non-lin, since thats what the
internal<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* render engine delivers */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;r.color_mgt_flag &amp; R_COLOR_MANAGEMENT) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(ibuf-&gt;profile == IB_PROFILE_LINEAR_RGB)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memcpy(rr-&gt;rectf,
ibuf-&gt;rect_float, 4*sizeof(float)*rr-&gt;rectx*rr-&gt;recty);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
srgb_to_linearrgb_rgba_rgba_buf(rr-&gt;rectf, ibuf-&gt;rect_float,
rr-&gt;rectx*rr-&gt;recty);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(ibuf-&gt;profile != IB_PROFILE_LINEAR_RGB)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memcpy(rr-&gt;rectf,
ibuf-&gt;rect_float, 4*sizeof(float)*rr-&gt;rectx*rr-&gt;recty);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
linearrgb_to_srgb_rgba_rgba_buf(rr-&gt;rectf, ibuf-&gt;rect_float,
rr-&gt;rectx*rr-&gt;recty);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* TSK! Since
sequence render doesn't free the *rr render result, the old rect32<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
can hang around when sequence render has rendered a 32 bits one before
*/<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rr-&gt;rect32) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MEM_freeN(rr-&gt;rect32);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rr-&gt;rect32= NULL;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if(ibuf-&gt;rect) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (!rr-&gt;rect32)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; rr-&gt;rect32=
MEM_mallocN(sizeof(int)*rr-&gt;rectx*rr-&gt;recty, "render_seq rect");<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memcpy(rr-&gt;rect32, ibuf-&gt;rect, 4*rr-&gt;rectx*rr-&gt;recty);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* if (ibuf-&gt;zbuf) { */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* &nbsp;&nbsp;&nbsp; if (R.rectz) freeN(R.rectz); */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* &nbsp;&nbsp;&nbsp; R.rectz = BLI_dupallocN(ibuf-&gt;zbuf); */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* } */<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Same things
as above, old rectf can hang around from previous render. */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rr-&gt;rectf) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MEM_freeN(rr-&gt;rectf);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rr-&gt;rectf= NULL;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (recurs_depth == 0) { /* with nested scenes, only free on toplevel... */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Editing * ed = re-&gt;scene-&gt;ed;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (ed) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; free_imbuf_seq(re-&gt;scene, &amp;ed-&gt;seqbase,
TRUE, TRUE);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_freeImBuf(ibuf);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* render result is delivered empty in most cases, nevertheless we handle all cases */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (rr-&gt;rectf)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memset(rr-&gt;rectf, 0, 4*sizeof(float)*rr-&gt;rectx*rr-&gt;recty);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (rr-&gt;rect32)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memset(rr-&gt;rect32, 0, 4*rr-&gt;rectx*rr-&gt;recty);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rr-&gt;rect32=
MEM_callocN(sizeof(int)*rr-&gt;rectx*rr-&gt;recty, "render_seq rect");<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);<br>
<br>
&nbsp;&nbsp;&nbsp; /* just in case this flag went missing at some point */<br>
&nbsp;&nbsp;&nbsp; re-&gt;r.scemode |= R_DOSEQ;<br>
}<br>
<br>
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */<br>
<br>
/* main loop: doing sequence + fields + blur + 3d render + compositing */<br>
static void do_render_all_options(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; scene_camera_switch_update(re-&gt;scene);<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;i.starttime= PIL_check_seconds_timer();<br>
<br>
&nbsp;&nbsp;&nbsp; /* ensure no images are in memory from previous animated sequences */<br>
&nbsp;&nbsp;&nbsp; BKE_image_all_free_anim_ibufs(re-&gt;r.cfra);<br>
<br>
&nbsp;&nbsp;&nbsp; if(external_render_3d(re, 1)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* in this case external render overrides all */<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else if(seq_render_active(re)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* note: do_render_seq() frees rect32 when sequencer returns float images */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!re-&gt;test_break(re-&gt;tbh))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do_render_seq(re);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;stats_draw(re-&gt;sdh, &amp;re-&gt;i);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;display_draw(re-&gt;ddh, re-&gt;result, NULL);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do_render_composite_fields_blur_3d(re);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* for UI only */<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_WRITE);<br>
&nbsp;&nbsp;&nbsp; renderresult_add_names(re-&gt;result);<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;i.lastframetime= PIL_check_seconds_timer()- re-&gt;i.starttime;<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;stats_draw(re-&gt;sdh, &amp;re-&gt;i);<br>
<br>
&nbsp;&nbsp;&nbsp; /* stamp image info here */<br>
&nbsp;&nbsp;&nbsp; if((re-&gt;r.stamp &amp; R_STAMP_ALL) &amp;&amp; (re-&gt;r.stamp &amp; R_STAMP_DRAW)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; renderresult_stampinfo(re-&gt;scene);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;display_draw(re-&gt;ddh, re-&gt;result, NULL);<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
static int check_valid_camera(Scene *scene)<br>
{<br>
&nbsp;&nbsp;&nbsp; int check_comp= 1;<br>
<br>
&nbsp;&nbsp;&nbsp; if (scene-&gt;camera == NULL)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; scene-&gt;camera= scene_find_camera(scene);<br>
<br>
&nbsp;&nbsp;&nbsp; if(scene-&gt;r.scemode&amp;R_DOSEQ) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(scene-&gt;ed) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Sequence *seq= scene-&gt;ed-&gt;seqbase.first;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; check_comp= 0;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while(seq) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(seq-&gt;type == SEQ_SCENE) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!seq-&gt;scene_camera) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
if(!seq-&gt;scene-&gt;camera &amp;&amp;
!scene_find_camera(seq-&gt;scene)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(seq-&gt;scene == scene) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* for current scene camera could
be unneeded due to compisite nodes */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; check_comp= 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* for other scenes camera is
necessary */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; seq= seq-&gt;next;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if(check_comp) { /* no sequencer or sequencer depends on compositor */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(scene-&gt;r.scemode&amp;R_DOCOMP &amp;&amp; scene-&gt;use_nodes) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bNode *node= scene-&gt;nodetree-&gt;nodes.first;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while(node) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(node-&gt;type == CMP_NODE_R_LAYERS) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Scene *sce= node-&gt;id ?
(Scene*)node-&gt;id : scene;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!sce-&gt;camera &amp;&amp;
!scene_find_camera(sce)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* all render
layers nodes need camera */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; node= node-&gt;next;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else return scene-&gt;camera != NULL;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; return 1;<br>
}<br>
<br>
int RE_is_rendering_allowed(Scene *scene, void *erh, void (*error)(void *handle, const char *str))<br>
{<br>
&nbsp;&nbsp;&nbsp; SceneRenderLayer *srl;<br>
<br>
&nbsp;&nbsp;&nbsp; if(scene-&gt;r.mode &amp; R_BORDER) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(scene-&gt;r.border.xmax &lt;= scene-&gt;r.border.xmin ||<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; scene-&gt;r.border.ymax &lt;= scene-&gt;r.border.ymin) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; error(erh, "No border area selected.");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if(scene-&gt;r.scemode &amp; (R_EXR_TILE_FILE|R_FULL_SAMPLE)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; char str[FILE_MAX];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; scene_unique_exr_name(scene, str, 0);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (BLI_is_writable(str)==0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; error(erh, "Can not save render buffers, check the temp default path");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* no fullsample and edge */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if((scene-&gt;r.scemode &amp; R_FULL_SAMPLE) &amp;&amp; (scene-&gt;r.mode &amp; R_EDGE)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; error(erh, "Full Sample doesn't support Edge Enhance");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; scene-&gt;r.scemode &amp;= ~R_FULL_SAMPLE;&nbsp;&nbsp;&nbsp; /* clear to be sure */<br>
<br>
&nbsp;&nbsp;&nbsp; if(scene-&gt;r.scemode &amp; R_DOCOMP) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(scene-&gt;use_nodes) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bNodeTree *ntree= scene-&gt;nodetree;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bNode *node;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(ntree==NULL) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; error(erh, "No Nodetree in Scene");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(node= ntree-&gt;nodes.first; node; node= node-&gt;next)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(node-&gt;type==CMP_NODE_COMPOSITE)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(node==NULL) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; error(erh, "No Render Output Node in Scene");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(scene-&gt;r.scemode &amp; R_FULL_SAMPLE) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(composite_needs_render(scene)==0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; error(erh, "Full Sample AA not
supported without 3d rendering");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;/* check valid camera, without camera render is OK (compo, seq) */<br>
&nbsp;&nbsp;&nbsp; if(!check_valid_camera(scene)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; error(erh, "No camera");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* get panorama &amp; ortho, only after camera is set */<br>
&nbsp;&nbsp;&nbsp; object_camera_mode(&amp;scene-&gt;r, scene-&gt;camera);<br>
<br>
&nbsp;&nbsp;&nbsp; /* forbidden combinations */<br>
&nbsp;&nbsp;&nbsp; if(scene-&gt;r.mode &amp; R_PANORAMA) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(scene-&gt;r.mode &amp; R_ORTHO) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; error(erh, "No Ortho render possible for Panorama");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* layer flag tests */<br>
&nbsp;&nbsp;&nbsp; if(scene-&gt;r.scemode &amp; R_SINGLE_LAYER) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; srl= BLI_findlink(&amp;scene-&gt;r.layers, scene-&gt;r.actlay);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* force layer to be enabled */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; srl-&gt;layflag &amp;= ~SCE_LAY_DISABLE;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; for(srl= scene-&gt;r.layers.first; srl; srl= srl-&gt;next)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!(srl-&gt;layflag &amp; SCE_LAY_DISABLE))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp; if(srl==NULL) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; error(erh, "All RenderLayers are disabled");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* renderer */<br>
&nbsp;&nbsp;&nbsp; if(!ELEM(scene-&gt;r.renderer, R_INTERN, R_YAFRAY)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; error(erh, "Unknown render engine set");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; return 1;<br>
}<br>
<br>
static void validate_render_settings(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;r.scemode &amp; (R_EXR_TILE_FILE|R_FULL_SAMPLE)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* no osa + fullsample won't work... */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;r.osa==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;r.scemode &amp;= ~R_FULL_SAMPLE;<br>
&nbsp;&nbsp;&nbsp; } else re-&gt;r.scemode &amp;= ~R_FULL_SAMPLE;&nbsp;&nbsp;&nbsp; /* clear to be sure */<br>
}<br>
<br>
static void update_physics_cache(Render *re, Scene *scene, int UNUSED(anim_init))<br>
{<br>
&nbsp;&nbsp;&nbsp; PTCacheBaker baker;<br>
<br>
&nbsp;&nbsp;&nbsp; baker.main = re-&gt;main;<br>
&nbsp;&nbsp;&nbsp; baker.scene = scene;<br>
&nbsp;&nbsp;&nbsp; baker.pid = NULL;<br>
&nbsp;&nbsp;&nbsp; baker.bake = 0;<br>
&nbsp;&nbsp;&nbsp; baker.render = 1;<br>
&nbsp;&nbsp;&nbsp; baker.anim_init = 1;<br>
&nbsp;&nbsp;&nbsp; baker.quick_step = 1;<br>
&nbsp;&nbsp;&nbsp; baker.break_test = re-&gt;test_break;<br>
&nbsp;&nbsp;&nbsp; baker.break_data = re-&gt;tbh;<br>
&nbsp;&nbsp;&nbsp; baker.progressbar = NULL;<br>
<br>
&nbsp;&nbsp;&nbsp; BKE_ptcache_bake(&amp;baker);<br>
}<br>
/* evaluating scene options for general Blender render */<br>
static int render_initialize_from_main(Render *re, Main *bmain, Scene
*scene, SceneRenderLayer *srl, unsigned int lay, int anim, int
anim_init)<br>
{<br>
&nbsp;&nbsp;&nbsp; int winx, winy;<br>
&nbsp;&nbsp;&nbsp; rcti disprect;<br>
<br>
&nbsp;&nbsp;&nbsp; /* r.xsch and r.ysch has the actual view window size<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; r.border is the clipping rect */<br>
<br>
&nbsp;&nbsp;&nbsp; /* calculate actual render result and display size */<br>
&nbsp;&nbsp;&nbsp; winx= (scene-&gt;r.size*scene-&gt;r.xsch)/100;<br>
&nbsp;&nbsp;&nbsp; winy= (scene-&gt;r.size*scene-&gt;r.ysch)/100;<br>
<br>
&nbsp;&nbsp;&nbsp; /* we always render smaller part, inserting it in larger image is compositor bizz, it uses disprect for it */<br>
&nbsp;&nbsp;&nbsp; if(scene-&gt;r.mode &amp; R_BORDER) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; disprect.xmin= scene-&gt;r.border.xmin*winx;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; disprect.xmax= scene-&gt;r.border.xmax*winx;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; disprect.ymin= scene-&gt;r.border.ymin*winy;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; disprect.ymax= scene-&gt;r.border.ymax*winy;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; disprect.xmin= disprect.ymin= 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; disprect.xmax= winx;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; disprect.ymax= winy;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;main= bmain;<br>
&nbsp;&nbsp;&nbsp; re-&gt;scene= scene;<br>
&nbsp;&nbsp;&nbsp; re-&gt;lay= lay;<br>
<br>
&nbsp;&nbsp;&nbsp; /* not too nice, but it survives anim-border render */<br>
&nbsp;&nbsp;&nbsp; if(anim) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;disprect= disprect;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* check all scenes involved */<br>
&nbsp;&nbsp;&nbsp; tag_scenes_for_render(re);<br>
<br>
&nbsp;&nbsp;&nbsp; /*<br>
&nbsp;&nbsp;&nbsp; &nbsp;* Disabled completely for now,<br>
&nbsp;&nbsp;&nbsp; &nbsp;* can be later set as render profile option<br>
&nbsp;&nbsp;&nbsp; &nbsp;* and default for background render.<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; if(0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* make sure dynamics are up to date */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; update_physics_cache(re, scene, anim_init);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if(srl || scene-&gt;r.scemode &amp; R_SINGLE_LAYER)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; push_render_result(re);<br>
<br>
&nbsp;&nbsp;&nbsp; RE_InitState(re, NULL, &amp;scene-&gt;r, srl, winx, winy, &amp;disprect);<br>
&nbsp;&nbsp;&nbsp; if(!re-&gt;ok)&nbsp; /* if an error was printed, abort */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
<br>
&nbsp;&nbsp;&nbsp; /* initstate makes new result, have to send changed tags around */<br>
&nbsp;&nbsp;&nbsp; ntreeCompositTagRender(re-&gt;scene);<br>
<br>
&nbsp;&nbsp;&nbsp; validate_render_settings(re);<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;display_init(re-&gt;dih, re-&gt;result);<br>
&nbsp;&nbsp;&nbsp; re-&gt;display_clear(re-&gt;dch, re-&gt;result);<br>
<br>
&nbsp;&nbsp;&nbsp; return 1;<br>
}<br>
<br>
/* general Blender frame render call */<br>
void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene,
SceneRenderLayer *srl, unsigned int lay, int frame, const short
write_still)<br>
{<br>
<br>
&nbsp;&nbsp;&nbsp; /* ugly global still... is to prevent preview events and signal subsurfs etc to make full resol */<br>
&nbsp;&nbsp;&nbsp; G.rendering= 1;<br>
<br>
&nbsp;&nbsp;&nbsp; scene-&gt;r.cfra= frame;<br>
<br>
&nbsp;&nbsp;&nbsp; if(render_initialize_from_main(re, bmain, scene, srl, lay, 0, 0)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MEM_reset_peak_memory();<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do_render_all_options(re);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(write_still &amp;&amp; !G.afbreek) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(BKE_imtype_is_movie(scene-&gt;r.imtype)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; /* operator checks this but incase its called from
elsewhere */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; printf("Error: cant write single images with a movie
format!\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; char name[FILE_MAX];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; BKE_makepicstring(name, scene-&gt;r.pic,
scene-&gt;r.cfra, scene-&gt;r.imtype, scene-&gt;r.scemode &amp;
R_EXTENSION, FALSE);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* reports only used for Movie */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; do_write_image_or_movie(re, scene, NULL, NULL, name);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* UGLY WARNING */<br>
&nbsp;&nbsp;&nbsp; G.rendering= 0;<br>
<br>
}<br>
<br>
static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, ReportList *reports, const char *name_override)<br>
{<br>
&nbsp;&nbsp;&nbsp; char name[FILE_MAX];<br>
&nbsp;&nbsp;&nbsp; RenderResult rres;<br>
&nbsp;&nbsp;&nbsp; int ok= 1;<br>
<br>
&nbsp;&nbsp;&nbsp; RE_AcquireResultImage(re, &amp;rres);<br>
<br>
&nbsp;&nbsp;&nbsp; /* write movie or image */<br>
&nbsp;&nbsp;&nbsp; if(BKE_imtype_is_movie(scene-&gt;r.imtype)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int dofree = 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* note; the way it gets 32 bits rects is weak... */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(rres.rect32==NULL) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rres.rect32=
MEM_mapallocN(sizeof(int)*rres.rectx*rres.recty, "temp 32 bits rect");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dofree = 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_ResultGet32(re, (unsigned int *)rres.rect32);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ok=
mh-&gt;append_movie(&amp;re-&gt;r, scene-&gt;r.cfra, rres.rect32,
rres.rectx, rres.recty, reports);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(dofree) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MEM_freeN(rres.rect32);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("Append frame %d", scene-&gt;r.cfra);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(name_override)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_strncpy(name, name_override, sizeof(name));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
BKE_makepicstring(name, scene-&gt;r.pic, scene-&gt;r.cfra,
scene-&gt;r.imtype, scene-&gt;r.scemode &amp; R_EXTENSION, TRUE);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;r.imtype==R_MULTILAYER) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;result) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; RE_WriteRenderResult(re-&gt;result, name,
scene-&gt;r.quality);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("Saved: %s", name);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ImBuf *ibuf=
IMB_allocImBuf(rres.rectx, rres.recty, scene-&gt;r.planes, 0);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* if not exists, BKE_write_ibuf makes one */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ibuf-&gt;rect= (unsigned int *)rres.rect32;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ibuf-&gt;rect_float= rres.rectf;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ibuf-&gt;zbuf_float= rres.rectz;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* float factor for random dither, imbuf takes care of it */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ibuf-&gt;dither= scene-&gt;r.dither_intensity;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* prepare to gamma correct to sRGB color space */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (scene-&gt;r.color_mgt_flag &amp; R_COLOR_MANAGEMENT) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; /* sequence editor can generate 8bpc render buffers
*/<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (ibuf-&gt;rect) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ibuf-&gt;profile =
IB_PROFILE_SRGB;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (ELEM(scene-&gt;r.imtype,
R_OPENEXR, R_RADHDR))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
IMB_float_from_rect(ibuf);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ibuf-&gt;profile =
IB_PROFILE_LINEAR_RGB;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ok=
BKE_write_ibuf(scene, ibuf, name, scene-&gt;r.imtype,
scene-&gt;r.subimtype, scene-&gt;r.quality);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(ok==0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("Render error: cannot save %s\n", name);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else printf("Saved: %s", name);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* optional preview images for exr */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(ok
&amp;&amp; scene-&gt;r.imtype==R_OPENEXR &amp;&amp;
(scene-&gt;r.subimtype &amp; R_PREVIEW_JPG)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(BLI_testextensie(name, ".exr"))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; name[strlen(name)-4]= 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BKE_add_image_extension(name, R_JPEG90);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ibuf-&gt;depth= 24;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; BKE_write_ibuf(scene, ibuf, name, R_JPEG90,
scene-&gt;r.subimtype, scene-&gt;r.quality);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\nSaved: %s", name);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* imbuf knows which rects are
not part of ibuf */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_freeImBuf(ibuf);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; RE_ReleaseResultImage(re);<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_timestr(re-&gt;i.lastframetime, name);<br>
&nbsp;&nbsp;&nbsp; printf(" Time: %s\n", name);<br>
&nbsp;&nbsp;&nbsp; fflush(stdout); /* needed for renderd !! (not anymore... (ton)) */<br>
<br>
&nbsp;&nbsp;&nbsp; return ok;<br>
}<br>
<br>
/* saves images to disk */<br>
void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, unsigned int lay, int sfra, int efra, int tfra, ReportList *reports)<br>
{<br>
&nbsp;&nbsp;&nbsp; bMovieHandle *mh= BKE_get_movie_handle(scene-&gt;r.imtype);<br>
&nbsp;&nbsp;&nbsp; int cfrao= scene-&gt;r.cfra;<br>
&nbsp;&nbsp;&nbsp; int nfra;<br>
<br>
&nbsp;&nbsp;&nbsp; /* do not fully call for each frame, it initializes &amp; pops output window */<br>
&nbsp;&nbsp;&nbsp; if(!render_initialize_from_main(re, bmain, scene, NULL, lay, 0, 1))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return;<br>
<br>
&nbsp;&nbsp;&nbsp; /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */<br>
&nbsp;&nbsp;&nbsp; /* is also set by caller renderwin.c */<br>
&nbsp;&nbsp;&nbsp; G.rendering= 1;<br>
<br>
&nbsp;&nbsp;&nbsp; if(BKE_imtype_is_movie(scene-&gt;r.imtype))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!mh-&gt;start_movie(scene, &amp;re-&gt;r, re-&gt;rectx, re-&gt;recty, reports))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; G.afbreek= 1;<br>
<br>
&nbsp;&nbsp;&nbsp; if (mh-&gt;get_next_frame) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while (!(G.afbreek == 1)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int nf = mh-&gt;get_next_frame(&amp;re-&gt;r, reports);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (nf &gt;= 0
&amp;&amp; nf &gt;= scene-&gt;r.sfra &amp;&amp; nf &lt;=
scene-&gt;r.efra) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; scene-&gt;r.cfra = re-&gt;r.cfra = nf;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do_render_all_options(re);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;test_break(re-&gt;tbh) == 0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!do_write_image_or_movie(re,
scene, mh, reports, NULL))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; G.afbreek= 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;test_break(re-&gt;tbh))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; G.afbreek= 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(nfra= sfra, scene-&gt;r.cfra= sfra; scene-&gt;r.cfra&lt;=efra; scene-&gt;r.cfra++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; char name[FILE_MAX];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* only border now, todo: camera lens. (ton) */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; render_initialize_from_main(re, bmain, scene, NULL, lay, 1, 0);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(nfra!=scene-&gt;r.cfra) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /*<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;* Skip this frame, but update for physics and
particles system.<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* From convertblender.c:<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;* in localview, lamps are using normal layers,
objects only local bits.<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;*/<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; unsigned int updatelay;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;lay &amp; 0xFF000000)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; updatelay= re-&gt;lay &amp;
0xFF000000;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; updatelay= re-&gt;lay;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; scene_update_for_newframe(bmain, scene, updatelay);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; continue;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; nfra+= tfra;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Touch/NoOverwrite options are only valid for image's */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(BKE_imtype_is_movie(scene-&gt;r.imtype) == 0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(scene-&gt;r.mode &amp; (R_NO_OVERWRITE | R_TOUCH))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BKE_makepicstring(name,
scene-&gt;r.pic, scene-&gt;r.cfra, scene-&gt;r.imtype,
scene-&gt;r.scemode &amp; R_EXTENSION, TRUE);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(scene-&gt;r.mode &amp; R_NO_OVERWRITE &amp;&amp;
BLI_exist(name)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("skipping existing frame
\"%s\"\n", name);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; continue;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(scene-&gt;r.mode &amp; R_TOUCH &amp;&amp;
!BLI_exist(name)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_make_existing_file(name); /*
makes the dir if its not there */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_touch(name);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;r.cfra=
scene-&gt;r.cfra;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; /* weak.... */<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do_render_all_options(re);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;test_break(re-&gt;tbh) == 0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!G.afbreek)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!do_write_image_or_movie(re,
scene, mh, reports, NULL))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; G.afbreek= 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; G.afbreek= 1;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(G.afbreek==1) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* remove touched file */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(BKE_imtype_is_movie(scene-&gt;r.imtype) == 0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (scene-&gt;r.mode &amp;
R_TOUCH &amp;&amp; BLI_exist(name) &amp;&amp; BLI_filepathsize(name) ==
0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
BLI_delete(name, 0, 0);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* end movie */<br>
&nbsp;&nbsp;&nbsp; if(BKE_imtype_is_movie(scene-&gt;r.imtype))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mh-&gt;end_movie();<br>
<br>
&nbsp;&nbsp;&nbsp; scene-&gt;r.cfra= cfrao;<br>
<br>
&nbsp;&nbsp;&nbsp; /* UGLY WARNING */<br>
&nbsp;&nbsp;&nbsp; G.rendering= 0;<br>
}<br>
<br>
void RE_PreviewRender(Render *re, Main *bmain, Scene *sce)<br>
{<br>
&nbsp;&nbsp;&nbsp; int winx, winy;<br>
<br>
&nbsp;&nbsp;&nbsp; winx= (sce-&gt;r.size*sce-&gt;r.xsch)/100;<br>
&nbsp;&nbsp;&nbsp; winy= (sce-&gt;r.size*sce-&gt;r.ysch)/100;<br>
<br>
&nbsp;&nbsp;&nbsp; RE_InitState(re, NULL, &amp;sce-&gt;r, NULL, winx, winy, NULL);<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;main = bmain;<br>
&nbsp;&nbsp;&nbsp; re-&gt;scene = sce;<br>
&nbsp;&nbsp;&nbsp; re-&gt;lay = sce-&gt;lay;<br>
<br>
&nbsp;&nbsp;&nbsp; RE_SetCamera(re, sce-&gt;camera);<br>
<br>
&nbsp;&nbsp;&nbsp; do_render_3d(re);<br>
}<br>
<br>
/* note; repeated win/disprect calc... solve that nicer, also in compo */<br>
<br>
/* only the temp file! */<br>
void RE_ReadRenderResult(Scene *scene, Scene *scenode)<br>
{<br>
&nbsp;&nbsp;&nbsp; Render *re;<br>
&nbsp;&nbsp;&nbsp; int winx, winy;<br>
&nbsp;&nbsp;&nbsp; rcti disprect;<br>
<br>
&nbsp;&nbsp;&nbsp; /* calculate actual render result and display size */<br>
&nbsp;&nbsp;&nbsp; winx= (scene-&gt;r.size*scene-&gt;r.xsch)/100;<br>
&nbsp;&nbsp;&nbsp; winy= (scene-&gt;r.size*scene-&gt;r.ysch)/100;<br>
<br>
&nbsp;&nbsp;&nbsp; /* only in movie case we render smaller part */<br>
&nbsp;&nbsp;&nbsp; if(scene-&gt;r.mode &amp; R_BORDER) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; disprect.xmin= scene-&gt;r.border.xmin*winx;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; disprect.xmax= scene-&gt;r.border.xmax*winx;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; disprect.ymin= scene-&gt;r.border.ymin*winy;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; disprect.ymax= scene-&gt;r.border.ymax*winy;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; disprect.xmin= disprect.ymin= 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; disprect.xmax= winx;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; disprect.ymax= winy;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if(scenode)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; scene= scenode;<br>
<br>
&nbsp;&nbsp;&nbsp; /* get render: it can be called from UI with draw callbacks */<br>
&nbsp;&nbsp;&nbsp; re= RE_GetRender(scene-&gt;id.name);<br>
&nbsp;&nbsp;&nbsp; if(re==NULL)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re= RE_NewRender(scene-&gt;id.name);<br>
&nbsp;&nbsp;&nbsp; RE_InitState(re, NULL, &amp;scene-&gt;r, NULL, winx, winy, &amp;disprect);<br>
&nbsp;&nbsp;&nbsp; re-&gt;scene= scene;<br>
<br>
&nbsp;&nbsp;&nbsp; read_render_result(re, 0);<br>
}<br>
<br>
void RE_set_max_threads(int threads)<br>
{<br>
&nbsp;&nbsp;&nbsp; if (threads==0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderGlobal.threads = BLI_system_thread_count();<br>
&nbsp;&nbsp;&nbsp; } else if(threads&gt;=1 &amp;&amp; threads&lt;=BLENDER_MAX_THREADS) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderGlobal.threads= threads;<br>
&nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("Error, threads has to be in range 0-%d\n", BLENDER_MAX_THREADS);<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
void RE_init_threadcount(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; if(RenderGlobal.threads &gt;= 1) { /* only set as an arg in background mode */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;r.threads= MIN2(RenderGlobal.threads, BLENDER_MAX_THREADS);<br>
&nbsp;&nbsp;&nbsp; } else if ((re-&gt;r.mode &amp; R_FIXED_THREADS)==0 || RenderGlobal.threads == 0) { /* Automatic threads */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;r.threads = BLI_system_thread_count();<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
/************************** External Engines ***************************/<br>
<br>
RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h)<br>
{<br>
&nbsp;&nbsp;&nbsp; Render *re= engine-&gt;re;<br>
&nbsp;&nbsp;&nbsp; RenderResult *result;<br>
&nbsp;&nbsp;&nbsp; rcti disprect;<br>
<br>
&nbsp;&nbsp;&nbsp; /* ensure the coordinates are within the right limits */<br>
&nbsp;&nbsp;&nbsp; CLAMP(x, 0, re-&gt;result-&gt;rectx);<br>
&nbsp;&nbsp;&nbsp; CLAMP(y, 0, re-&gt;result-&gt;recty);<br>
&nbsp;&nbsp;&nbsp; CLAMP(w, 0, re-&gt;result-&gt;rectx);<br>
&nbsp;&nbsp;&nbsp; CLAMP(h, 0, re-&gt;result-&gt;recty);<br>
<br>
&nbsp;&nbsp;&nbsp; if(x + w &gt; re-&gt;result-&gt;rectx)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; w= re-&gt;result-&gt;rectx - x;<br>
&nbsp;&nbsp;&nbsp; if(y + h &gt; re-&gt;result-&gt;recty)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; h= re-&gt;result-&gt;recty - y;<br>
<br>
&nbsp;&nbsp;&nbsp; /* allocate a render result */<br>
&nbsp;&nbsp;&nbsp; disprect.xmin= x;<br>
&nbsp;&nbsp;&nbsp; disprect.xmax= x+w;<br>
&nbsp;&nbsp;&nbsp; disprect.ymin= y;<br>
&nbsp;&nbsp;&nbsp; disprect.ymax= y+h;<br>
<br>
&nbsp;&nbsp;&nbsp; if(0) { // XXX (re-&gt;r.scemode &amp; R_FULL_SAMPLE)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; result= new_full_sample_buffers(re, &amp;engine-&gt;fullresult, &amp;disprect, 0);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; result= new_render_result(re, &amp;disprect, 0, RR_USEMEM);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_addtail(&amp;engine-&gt;fullresult, result);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; return result;<br>
}<br>
<br>
void RE_engine_update_result(RenderEngine *engine, RenderResult *result)<br>
{<br>
&nbsp;&nbsp;&nbsp; Render *re= engine-&gt;re;<br>
<br>
&nbsp;&nbsp;&nbsp; if(result &amp;&amp; render_display_draw_enabled(re)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; result-&gt;renlay= result-&gt;layers.first; // weak<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;display_draw(re-&gt;ddh, result, NULL);<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
void RE_engine_end_result(RenderEngine *engine, RenderResult *result)<br>
{<br>
&nbsp;&nbsp;&nbsp; Render *re= engine-&gt;re;<br>
<br>
&nbsp;&nbsp;&nbsp; if(!result)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return;<br>
<br>
&nbsp;&nbsp;&nbsp; /* merge */<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;result-&gt;exrhandle) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderResult *rr, *rrpart;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // XXX crashes, exr expects very particular part sizes<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(rr= re-&gt;result, rrpart=
result; rr &amp;&amp; rrpart; rr= rr-&gt;next, rrpart= rrpart-&gt;next)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; save_render_result_tile(rr, rrpart);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else if(render_display_draw_enabled(re)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* on break, don't merge in result for preview renders, looks nicer */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;test_break(re-&gt;tbh) &amp;&amp; (re-&gt;r.scemode &amp; R_PREVIEWBUTS));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else merge_render_result(re-&gt;result, result);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* draw */<br>
&nbsp;&nbsp;&nbsp; if(!re-&gt;test_break(re-&gt;tbh) &amp;&amp; render_display_draw_enabled(re)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; result-&gt;renlay= result-&gt;layers.first; // weak<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;display_draw(re-&gt;ddh, result, NULL);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* free */<br>
&nbsp;&nbsp;&nbsp; free_render_result(&amp;engine-&gt;fullresult, result);<br>
}<br>
<br>
int RE_engine_test_break(RenderEngine *engine)<br>
{<br>
&nbsp;&nbsp;&nbsp; Render *re= engine-&gt;re;<br>
<br>
&nbsp;&nbsp;&nbsp; return re-&gt;test_break(re-&gt;tbh);<br>
}<br>
<br>
void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char *info)<br>
{<br>
&nbsp;&nbsp;&nbsp; Render *re= engine-&gt;re;<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;i.statstr= stats;<br>
&nbsp;&nbsp;&nbsp; re-&gt;i.infostr= info;<br>
&nbsp;&nbsp;&nbsp; re-&gt;stats_draw(re-&gt;sdh, &amp;re-&gt;i);<br>
&nbsp;&nbsp;&nbsp; re-&gt;i.infostr= NULL;<br>
&nbsp;&nbsp;&nbsp; re-&gt;i.statstr= NULL;<br>
}<br>
<br>
/* loads in image into a result, size must match<br>
&nbsp;* x/y offsets are only used on a partial copy when dimensions dont match */<br>
void RE_layer_load_from_file(RenderLayer *layer, ReportList *reports, const char *filename, int x, int y)<br>
{<br>
&nbsp;&nbsp;&nbsp; ImBuf *ibuf = IMB_loadiffname(filename, IB_rect);<br>
<br>
&nbsp;&nbsp;&nbsp; if(ibuf&nbsp; &amp;&amp; (ibuf-&gt;rect || ibuf-&gt;rect_float)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (ibuf-&gt;x == layer-&gt;rectx &amp;&amp; ibuf-&gt;y == layer-&gt;recty) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(ibuf-&gt;rect_float==NULL)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_float_from_rect(ibuf);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
memcpy(layer-&gt;rectf, ibuf-&gt;rect_float,
sizeof(float)*4*layer-&gt;rectx*layer-&gt;recty);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if
((ibuf-&gt;x - x &gt;= layer-&gt;rectx) &amp;&amp; (ibuf-&gt;y - y
&gt;= layer-&gt;recty)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ImBuf *ibuf_clip;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(ibuf-&gt;rect_float==NULL)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_float_from_rect(ibuf);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; ibuf_clip = IMB_allocImBuf(layer-&gt;rectx,
layer-&gt;recty, 32, IB_rectfloat);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(ibuf_clip) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_rectcpy(ibuf_clip, ibuf, 0,0,
x,y, layer-&gt;rectx, layer-&gt;recty);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memcpy(layer-&gt;rectf,
ibuf_clip-&gt;rect_float,
sizeof(float)*4*layer-&gt;rectx*layer-&gt;recty);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_freeImBuf(ibuf_clip);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BKE_reportf(reports, RPT_ERROR,
"RE_result_rect_from_file: failed to allocate clip buffer '%s'\n",
filename);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; BKE_reportf(reports, RPT_ERROR,
"RE_result_rect_from_file: incorrect dimensions for partial copy
'%s'\n", filename);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_freeImBuf(ibuf);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BKE_reportf(reports, RPT_ERROR,
"RE_result_rect_from_file: failed to load '%s'\n", filename);<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
void RE_result_load_from_file(RenderResult *result, ReportList *reports, const char *filename)<br>
{<br>
&nbsp;&nbsp;&nbsp; if(!read_render_result_from_file(filename, result)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BKE_reportf(reports, RPT_ERROR,
"RE_result_rect_from_file: failed to load '%s'\n", filename);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
static int external_render_3d(Render *re, int do_all)<br>
{<br>
&nbsp;&nbsp;&nbsp; RenderEngineType *type= BLI_findstring(&amp;R_engines, re-&gt;r.engine, offsetof(RenderEngineType, idname));<br>
&nbsp;&nbsp;&nbsp; RenderEngine engine;<br>
<br>
&nbsp;&nbsp;&nbsp; if(!(type &amp;&amp; type-&gt;render))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; if((re-&gt;r.scemode &amp; R_PREVIEWBUTS) &amp;&amp; !(type-&gt;flag &amp; RE_DO_PREVIEW))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; if(do_all &amp;&amp; !(type-&gt;flag &amp; RE_DO_ALL))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; if(!do_all &amp;&amp; (type-&gt;flag &amp; RE_DO_ALL))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_WRITE);<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;result==NULL || !(re-&gt;r.scemode &amp; R_PREVIEWBUTS)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_FreeRenderResult(re-&gt;result);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(0) // XXX re-&gt;r.scemode &amp; R_FULL_SAMPLE)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result= new_full_sample_buffers_exr(re);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result=
new_render_result(re, &amp;re-&gt;disprect, 0, 0); // XXX
re-&gt;r.scemode &amp; (R_EXR_TILE_FILE|R_FULL_SAMPLE));<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);<br>
<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;result==NULL)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
<br>
&nbsp;&nbsp;&nbsp; /* external */<br>
&nbsp;&nbsp;&nbsp; memset(&amp;engine, 0, sizeof(engine));<br>
&nbsp;&nbsp;&nbsp; engine.type= type;<br>
&nbsp;&nbsp;&nbsp; engine.re= re;<br>
<br>
&nbsp;&nbsp;&nbsp; type-&gt;render(&amp;engine, re-&gt;scene);<br>
<br>
&nbsp;&nbsp;&nbsp; free_render_result(&amp;engine.fullresult, engine.fullresult.first);<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_lock(&amp;re-&gt;resultmutex, THREAD_LOCK_WRITE);<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;result-&gt;exrhandle) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderResult *rr;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; save_empty_result_tiles(re);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(rr= re-&gt;result; rr; rr= rr-&gt;next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IMB_exr_close(rr-&gt;exrhandle);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rr-&gt;exrhandle= NULL;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; free_render_result(&amp;re-&gt;fullresult, re-&gt;result);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;result= NULL;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; read_render_result(re, 0);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; BLI_rw_mutex_unlock(&amp;re-&gt;resultmutex);<br>
<br>
&nbsp;&nbsp;&nbsp; return 1;<br>
}<br>
<br>
<br>
<br><big style="font-weight: bold; color: red;">filename: source/creator/creator.c</big>
กก</p>

<p>/*<br>
&nbsp;* $Id: creator.c 36276 2011-04-21 15:53:30Z campbellbarton $<br>
&nbsp;*<br>
&nbsp;* ***** BEGIN GPL LICENSE BLOCK *****<br>
&nbsp;*<br>
&nbsp;* This program is free software; you can redistribute it and/or<br>
&nbsp;* modify it under the terms of the GNU General Public License<br>
&nbsp;* as published by the Free Software Foundation; either version 2<br>
&nbsp;* of the License, or (at your option) any later version.<br>
&nbsp;*<br>
&nbsp;* This program is distributed in the hope that it will be useful,<br>
&nbsp;* but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
&nbsp;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&nbsp; See the<br>
&nbsp;* GNU General Public License for more details.<br>
&nbsp;*<br>
&nbsp;* You should have received a copy of the GNU General Public License<br>
&nbsp;* along with this program; if not, write to the Free Software Foundation,<br>
&nbsp;* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.<br>
&nbsp;*<br>
&nbsp;* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.<br>
&nbsp;* All rights reserved.<br>
&nbsp;*<br>
&nbsp;* The Original Code is: all of this file.<br>
&nbsp;*<br>
&nbsp;* Contributor(s): none yet.<br>
&nbsp;*<br>
&nbsp;* ***** END GPL LICENSE BLOCK *****<br>
&nbsp;*/<br>
<br>
/** \file creator/creator.c<br>
&nbsp;*&nbsp; \ingroup creator<br>
&nbsp;*/<br>
<br>
<br>
#if defined(__linux__) &amp;&amp; defined(__GNUC__)<br>
#define _GNU_SOURCE<br>
#include &lt;fenv.h&gt;<br>
#endif<br>
<br>
#if (defined(__APPLE__) &amp;&amp; (defined(__i386__) || defined(__x86_64__)))<br>
#define OSX_SSE_FPE<br>
#include &lt;xmmintrin.h&gt;<br>
#endif<br>
<br>
#include &lt;stdlib.h&gt;<br>
#include &lt;stddef.h&gt;<br>
#include &lt;string.h&gt;<br>
<br>
/* for setuid / getuid */<br>
#ifdef __sgi<br>
#include &lt;sys/types.h&gt;<br>
#include &lt;unistd.h&gt;<br>
#endif<br>
<br>
/* This little block needed for linking to Blender... */<br>
<br>
#include "MEM_guardedalloc.h"<br>
<br>
#ifdef WIN32<br>
#include "BLI_winstuff.h"<br>
#endif<br>
<br>
#include "BLI_args.h"<br>
#include "BLI_threads.h"<br>
#include "BLI_scanfill.h" // for BLI_setErrorCallBack, TODO, move elsewhere<br>
#include "BLI_utildefines.h"<br>
<br>
#include "DNA_ID.h"<br>
#include "DNA_scene_types.h"<br>
<br>
#include "BLI_blenlib.h"<br>
<br>
#include "BKE_utildefines.h"<br>
#include "BKE_blender.h"<br>
#include "BKE_context.h"<br>
#include "BKE_depsgraph.h" // for DAG_on_visible_update<br>
#include "BKE_font.h"<br>
#include "BKE_global.h"<br>
#include "BKE_main.h"<br>
#include "BKE_material.h"<br>
#include "BKE_packedFile.h"<br>
#include "BKE_scene.h"<br>
#include "BKE_node.h"<br>
#include "BKE_report.h"<br>
#include "BKE_sound.h"<br>
<br>
#include "IMB_imbuf.h"&nbsp;&nbsp;&nbsp; // for IMB_init<br>
<br>
#ifdef WITH_PYTHON<br>
#include "BPY_extern.h"<br>
#endif<br>
<br>
#include "RE_pipeline.h"<br>
<br>
//XXX #include "playanim_ext.h"<br>
#include "ED_datafiles.h"<br>
<br>
#include "WM_api.h"<br>
<br>
#include "RNA_define.h"<br>
<br>
#include "GPU_draw.h"<br>
#include "GPU_extensions.h"<br>
<br>
#ifdef WITH_BUILDINFO_HEADER<br>
#define BUILD_DATE<br>
#endif<br>
<br>
/* for passing information between creator and gameengine */<br>
#ifdef WITH_GAMEENGINE<br>
#include "GEN_messaging.h"<br>
#include "SYS_System.h"<br>
#else /* dummy */<br>
#define SYS_SystemHandle int<br>
#endif<br>
<br>
#include &lt;signal.h&gt;<br>
<br>
#ifdef __FreeBSD__<br>
# include &lt;sys/types.h&gt;<br>
# include &lt;floatingpoint.h&gt;<br>
# include &lt;sys/rtprio.h&gt;<br>
#endif<br>
<br>
#ifdef WITH_BINRELOC<br>
#include "binreloc.h"<br>
#endif<br>
<br>
// from buildinfo.c<br>
#ifdef BUILD_DATE<br>
extern char build_date[];<br>
extern char build_time[];<br>
extern char build_rev[];<br>
extern char build_platform[];<br>
extern char build_type[];<br>
extern char build_cflags[];<br>
extern char build_cxxflags[];<br>
extern char build_linkflags[];<br>
extern char build_system[];<br>
#endif<br>
<br>
/*&nbsp;&nbsp;&nbsp; Local Function prototypes */<br>
static int print_help(int argc, const char **argv, void *data);<br>
static int print_version(int argc, const char **argv, void *data);<br>
<br>
/* for the callbacks: */<br>
<br>
extern int pluginapi_force_ref(void);&nbsp; /* from blenpluginapi:pluginapi.c */<br>
<br>
char bprogname[FILE_MAX]; /* from blenpluginapi:pluginapi.c */<br>
char btempdir[FILE_MAX];<br>
<br>
#define BLEND_VERSION_STRING_FMT "Blender %d.%02d (sub %d)\n", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION<br>
<br>
/* Initialise callbacks for the modules that need them */<br>
static void setCallbacks(void);<br>
<br>
/* set breakpoints here when running in debug mode, useful to catch floating point errors */<br>
#if defined(__sgi) || defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)<br>
static void fpe_handler(int UNUSED(sig))<br>
{<br>
&nbsp;&nbsp;&nbsp; // printf("SIGFPE trapped\n");<br>
}<br>
#endif<br>
<br>
#ifndef WITH_PYTHON_MODULE<br>
/* handling ctrl-c event in console */<br>
static void blender_esc(int sig)<br>
{<br>
&nbsp;&nbsp;&nbsp; static int count = 0;<br>
<br>
&nbsp;&nbsp;&nbsp; G.afbreek = 1;&nbsp;&nbsp;&nbsp; /* forces render loop to read queue, not sure if its needed */<br>
<br>
&nbsp;&nbsp;&nbsp; if (sig == 2) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (count) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\nBlender killed\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; exit(2);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\nSent an internal break event. Press ^C again to kill Blender\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; count++;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
#endif<br>
<br>
/* buildinfo can have quotes */<br>
#ifdef BUILD_DATE<br>
static void strip_quotes(char *str)<br>
{<br>
&nbsp;&nbsp;&nbsp; if(str[0] == '"') {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int len= strlen(str) - 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memmove(str, str+1, len);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(str[len-1] == '"') {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; str[len-1]= '\0';<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
#endif<br>
<br>
static int print_version(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))<br>
{<br>
&nbsp;&nbsp;&nbsp; printf (BLEND_VERSION_STRING_FMT);<br>
#ifdef BUILD_DATE<br>
&nbsp;&nbsp;&nbsp; printf ("\tbuild date: %s\n", build_date);<br>
&nbsp;&nbsp;&nbsp; printf ("\tbuild time: %s\n", build_time);<br>
&nbsp;&nbsp;&nbsp; printf ("\tbuild revision: %s\n", build_rev);<br>
&nbsp;&nbsp;&nbsp; printf ("\tbuild platform: %s\n", build_platform);<br>
&nbsp;&nbsp;&nbsp; printf ("\tbuild type: %s\n", build_type);<br>
&nbsp;&nbsp;&nbsp; printf ("\tbuild c flags: %s\n", build_cflags);<br>
&nbsp;&nbsp;&nbsp; printf ("\tbuild c++ flags: %s\n", build_cxxflags);<br>
&nbsp;&nbsp;&nbsp; printf ("\tbuild link flags: %s\n", build_linkflags);<br>
&nbsp;&nbsp;&nbsp; printf ("\tbuild system: %s\n", build_system);<br>
#endif<br>
&nbsp;&nbsp;&nbsp; exit(0);<br>
<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)<br>
{<br>
&nbsp;&nbsp;&nbsp; bArgs *ba = (bArgs*)data;<br>
<br>
&nbsp;&nbsp;&nbsp; printf (BLEND_VERSION_STRING_FMT);<br>
&nbsp;&nbsp;&nbsp; printf ("Usage: blender [args ...] [file] [args ...]\n\n");<br>
<br>
&nbsp;&nbsp;&nbsp; printf ("Render Options:\n");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--background");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--render-anim");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--scene");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--render-frame");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--frame-start");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--frame-end");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--frame-jump");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--render-output");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--engine");<br>
<br>
&nbsp;&nbsp;&nbsp; printf("\n");<br>
&nbsp;&nbsp;&nbsp; printf ("Format Options:\n");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--render-format");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--use-extension");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--threads");<br>
<br>
&nbsp;&nbsp;&nbsp; printf("\n");<br>
&nbsp;&nbsp;&nbsp; printf ("Animation Playback Options:\n");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "-a");<br>
<br>
&nbsp;&nbsp;&nbsp; printf("\n");<br>
&nbsp;&nbsp;&nbsp; printf ("Window Options:\n");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--window-border");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--window-borderless");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--window-geometry");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--start-console");<br>
<br>
&nbsp;&nbsp;&nbsp; printf("\n");<br>
&nbsp;&nbsp;&nbsp; printf ("Game Engine Specific Options:\n");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "-g");<br>
<br>
&nbsp;&nbsp;&nbsp; printf("\n");<br>
&nbsp;&nbsp;&nbsp; printf ("Misc Options:\n");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--debug");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--debug-fpe");<br>
&nbsp;&nbsp;&nbsp; printf("\n");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--factory-startup");<br>
&nbsp;&nbsp;&nbsp; printf("\n");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--env-system-config");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--env-system-datafiles");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--env-system-scripts");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--env-system-plugins");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--env-system-python");<br>
&nbsp;&nbsp;&nbsp; printf("\n");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "-nojoystick");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "-noglsl");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "-noaudio");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "-setaudio");<br>
<br>
&nbsp;&nbsp;&nbsp; printf("\n");<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--help");<br>
<br>
&nbsp;&nbsp;&nbsp; printf("\n");<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--enable-autoexec");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--disable-autoexec");<br>
<br>
&nbsp;&nbsp;&nbsp; printf("\n");<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--python");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--python-console");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--addons");<br>
<br>
#ifdef WIN32<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "-R");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "-r");<br>
#endif<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--version");<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintArgDoc(ba, "--");<br>
<br>
&nbsp;&nbsp;&nbsp; printf ("Other Options:\n");<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrintOtherDoc(ba);<br>
<br>
&nbsp;&nbsp;&nbsp; printf ("Argument Parsing:\n");<br>
&nbsp;&nbsp;&nbsp; printf ("\targuments must be separated by white space. eg\n");<br>
&nbsp;&nbsp;&nbsp; printf ("\t\t\"blender -ba test.blend\"\n");<br>
&nbsp;&nbsp;&nbsp; printf ("\t...will ignore the 'a'\n");<br>
&nbsp;&nbsp;&nbsp; printf ("\t\t\"blender -b test.blend -f8\"\n");<br>
&nbsp;&nbsp;&nbsp; printf ("\t...will ignore 8 because there is no space between the -f and the frame value\n\n");<br>
<br>
&nbsp;&nbsp;&nbsp; printf ("Argument Order:\n");<br>
&nbsp;&nbsp;&nbsp; printf ("Arguments are executed in the order they are given. eg\n");<br>
&nbsp;&nbsp;&nbsp; printf ("\t\t\"blender --background test.blend --render-frame 1 --render-output /tmp\"\n");<br>
&nbsp;&nbsp;&nbsp; printf ("\t...will not render to /tmp because '--render-frame 1' renders before the output path is set\n");<br>
&nbsp;&nbsp;&nbsp; printf ("\t\t\"blender --background --render-output /tmp test.blend --render-frame 1\"\n");<br>
&nbsp;&nbsp;&nbsp; printf ("\t...will not render to /tmp because
loading the blend file overwrites the render output that was set\n");<br>
&nbsp;&nbsp;&nbsp; printf ("\t\t\"blender --background test.blend
--render-output /tmp --render-frame 1\" works as expected.\n\n");<br>
<br>
&nbsp;&nbsp;&nbsp; printf ("\nEnvironment Variables:\n");<br>
&nbsp;&nbsp;&nbsp; printf ("&nbsp;
$BLENDER_USER_CONFIG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Directory for user
configuration files.\n");<br>
&nbsp;&nbsp;&nbsp; printf ("&nbsp; $BLENDER_SYSTEM_CONFIG&nbsp;&nbsp;&nbsp; Directory for system wide configuration files.\n");<br>
&nbsp;&nbsp;&nbsp; printf ("&nbsp; $BLENDER_USER_SCRIPTS&nbsp;&nbsp;&nbsp;&nbsp; Directory for user scripts.\n");<br>
&nbsp;&nbsp;&nbsp; printf ("&nbsp; $BLENDER_SYSTEM_SCRIPTS&nbsp;&nbsp; Directory for system wide scripts.\n");<br>
&nbsp;&nbsp;&nbsp; printf ("&nbsp; $BLENDER_USER_DATAFILES&nbsp;&nbsp;
Directory for user data files (icons, translations, ..).\n");<br>
&nbsp;&nbsp;&nbsp; printf ("&nbsp; $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");<br>
&nbsp;&nbsp;&nbsp; printf ("&nbsp; $BLENDER_SYSTEM_PYTHON&nbsp;&nbsp;&nbsp; Directory for system python libraries.\n");<br>
#ifdef WIN32<br>
&nbsp;&nbsp;&nbsp; printf ("&nbsp;
$TEMP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Store temporary files here.\n");<br>
#else<br>
&nbsp;&nbsp;&nbsp; printf ("&nbsp; $TMP or
$TMPDIR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Store temporary files here.\n");<br>
#endif<br>
#ifndef DISABLE_SDL<br>
&nbsp;&nbsp;&nbsp; printf ("&nbsp;
$SDL_AUDIODRIVER&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
LibSDL audio driver - alsa, esd, dma.\n");<br>
#endif<br>
&nbsp;&nbsp;&nbsp; printf ("&nbsp;
$PYTHONHOME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Path to the python directory, eg. /usr/lib/python.\n\n");<br>
<br>
&nbsp;&nbsp;&nbsp; exit(0);<br>
<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
<br>
double PIL_check_seconds_timer(void);<br>
<br>
/* XXX This was here to fix a crash when running python scripts<br>
&nbsp;* with -P that used the screen.<br>
&nbsp;*<br>
&nbsp;* static void main_init_screen( void )<br>
{<br>
&nbsp;&nbsp;&nbsp; setscreen(G.curscreen);<br>
<br>
&nbsp;&nbsp;&nbsp; if(G.main-&gt;scene.first==0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; set_scene( add_scene("1") );<br>
&nbsp;&nbsp;&nbsp; }<br>
}*/<br>
<br>
static int end_arguments(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))<br>
{<br>
&nbsp;&nbsp;&nbsp; return -1;<br>
}<br>
<br>
static int enable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))<br>
{<br>
&nbsp;&nbsp;&nbsp; G.f |= G_SCRIPT_AUTOEXEC;<br>
&nbsp;&nbsp;&nbsp; G.f |= G_SCRIPT_OVERRIDE_PREF;<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static int disable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))<br>
{<br>
&nbsp;&nbsp;&nbsp; G.f &amp;= ~G_SCRIPT_AUTOEXEC;<br>
&nbsp;&nbsp;&nbsp; G.f |= G_SCRIPT_OVERRIDE_PREF;<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))<br>
{<br>
&nbsp;&nbsp;&nbsp; G.background = 1;<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static int debug_mode(int UNUSED(argc), const char **UNUSED(argv), void *data)<br>
{<br>
&nbsp;&nbsp;&nbsp; G.f |= G_DEBUG;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* std output printf's */<br>
&nbsp;&nbsp;&nbsp; printf(BLEND_VERSION_STRING_FMT);<br>
&nbsp;&nbsp;&nbsp; MEM_set_memory_debug();<br>
<br>
#ifdef NAN_BUILDINFO<br>
&nbsp;&nbsp;&nbsp; printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);<br>
#endif // NAN_BUILDINFO<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_argsPrint(data);<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))<br>
{<br>
#if defined(__sgi) || defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)<br>
&nbsp;&nbsp;&nbsp; /* zealous but makes float issues a heck of a lot easier to find!<br>
&nbsp;&nbsp;&nbsp; &nbsp;* set breakpoints on fpe_handler */<br>
&nbsp;&nbsp;&nbsp; signal(SIGFPE, fpe_handler);<br>
<br>
# if defined(__linux__) &amp;&amp; defined(__GNUC__)<br>
&nbsp;&nbsp;&nbsp; feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );<br>
# endif&nbsp;&nbsp;&nbsp; /* defined(__linux__) &amp;&amp; defined(__GNUC__) */<br>
# if defined(OSX_SSE_FPE)<br>
&nbsp;&nbsp;&nbsp; /* OSX uses SSE for floating point by default, so here<br>
&nbsp;&nbsp;&nbsp; &nbsp;* use SSE instructions to throw floating point exceptions */<br>
&nbsp;&nbsp;&nbsp; _MM_SET_EXCEPTION_MASK(_MM_MASK_MASK &amp;~<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (_MM_MASK_OVERFLOW|_MM_MASK_INVALID|_MM_MASK_DIV_ZERO));<br>
# endif&nbsp;&nbsp;&nbsp; /* OSX_SSE_FPE */<br>
# if defined(_WIN32) &amp;&amp; defined(_MSC_VER)<br>
&nbsp;&nbsp;&nbsp; _controlfp_s(NULL, 0, _MCW_EM); /* enables all fp exceptions */<br>
&nbsp;&nbsp;&nbsp; _controlfp_s(NULL, _EM_DENORMAL | _EM_UNDERFLOW |
_EM_INEXACT, _MCW_EM); /* hide the ones we don't care about */<br>
# endif /* _WIN32 &amp;&amp; _MSC_VER */<br>
#endif<br>
<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))<br>
{<br>
&nbsp;&nbsp;&nbsp; G.factory_startup= 1;<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static int set_env(int argc, const char **argv, void *UNUSED(data))<br>
{<br>
&nbsp;&nbsp;&nbsp; /* "--env-system-scripts" --&gt; "BLENDER_SYSTEM_SCRIPTS" */<br>
<br>
&nbsp;&nbsp;&nbsp; char env[64]= "BLENDER";<br>
&nbsp;&nbsp;&nbsp; char *ch_dst= env + 7; /* skip BLENDER */<br>
&nbsp;&nbsp;&nbsp; const char *ch_src= argv[0] + 5; /* skip --env */<br>
<br>
&nbsp;&nbsp;&nbsp; if (argc &lt; 2) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("%s requires one argument\n", argv[0]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; exit(1);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; for(; *ch_src; ch_src++, ch_dst++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *ch_dst= (*ch_src == '-') ? '_' : (*ch_src)-32; /* toupper() */<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; *ch_dst= '\0';<br>
&nbsp;&nbsp;&nbsp; BLI_setenv(env, argv[1]);<br>
&nbsp;&nbsp;&nbsp; return 1;<br>
}<br>
<br>
static int playback_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))<br>
{<br>
&nbsp;&nbsp;&nbsp; /* not if -b was given first */<br>
&nbsp;&nbsp;&nbsp; if (G.background == 0) {<br>
<br>
// XXX&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; playanim(argc, argv); /* not the same argc and argv
as before */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; exit(0);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; return -2;<br>
}<br>
<br>
static int prefsize(int argc, const char **argv, void *UNUSED(data))<br>
{<br>
&nbsp;&nbsp;&nbsp; int stax, stay, sizx, sizy;<br>
<br>
&nbsp;&nbsp;&nbsp; if (argc &lt; 5) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf ("-p requires four arguments\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; exit(1);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; stax= atoi(argv[1]);<br>
&nbsp;&nbsp;&nbsp; stay= atoi(argv[2]);<br>
&nbsp;&nbsp;&nbsp; sizx= atoi(argv[3]);<br>
&nbsp;&nbsp;&nbsp; sizy= atoi(argv[4]);<br>
<br>
&nbsp;&nbsp;&nbsp; WM_setprefsize(stax, stay, sizx, sizy);<br>
<br>
&nbsp;&nbsp;&nbsp; return 4;<br>
}<br>
<br>
static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))<br>
{<br>
&nbsp;&nbsp;&nbsp; WM_setinitialstate_normal();<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static int without_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))<br>
{<br>
&nbsp;&nbsp;&nbsp; WM_setinitialstate_fullscreen();<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
extern int wm_start_with_console; // blender/windowmanager/intern/wm_init_exit.c<br>
static int start_with_console(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))<br>
{<br>
&nbsp;&nbsp;&nbsp; wm_start_with_console = 1;<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static int register_extension(int UNUSED(argc), const char **UNUSED(argv), void *data)<br>
{<br>
#ifdef WIN32<br>
&nbsp;&nbsp;&nbsp; if (data)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; G.background = 1;<br>
&nbsp;&nbsp;&nbsp; RegisterBlendExtension();<br>
#else<br>
&nbsp;&nbsp;&nbsp; (void)data; /* unused */<br>
#endif<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static int no_joystick(int UNUSED(argc), const char **UNUSED(argv), void *data)<br>
{<br>
#ifndef WITH_GAMEENGINE<br>
&nbsp;&nbsp;&nbsp; (void)data;<br>
#else<br>
&nbsp;&nbsp;&nbsp; SYS_SystemHandle *syshandle = data;<br>
<br>
&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; don't initialize joysticks if user doesn't want to use joysticks<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; failed joystick initialization delays over 5 seconds, before game engine start<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; SYS_WriteCommandLineInt(*syshandle, "nojoystick",1);<br>
&nbsp;&nbsp;&nbsp; if (G.f &amp; G_DEBUG) printf("disabling nojoystick\n");<br>
#endif<br>
<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static int no_glsl(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))<br>
{<br>
&nbsp;&nbsp;&nbsp; GPU_extensions_disable();<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static int no_audio(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))<br>
{<br>
&nbsp;&nbsp;&nbsp; sound_force_device(0);<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static int set_audio(int argc, const char **argv, void *UNUSED(data))<br>
{<br>
&nbsp;&nbsp;&nbsp; if (argc &lt; 1) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("-setaudio require one argument\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; exit(1);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; sound_force_device(sound_define_from_str(argv[1]));<br>
&nbsp;&nbsp;&nbsp; return 1;<br>
}<br>
<br>
static int set_output(int argc, const char **argv, void *data)<br>
{<br>
&nbsp;&nbsp;&nbsp; bContext *C = data;<br>
&nbsp;&nbsp;&nbsp; if (argc &gt;= 1){<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (CTX_data_scene(C)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Scene *scene= CTX_data_scene(C);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_strncpy(scene-&gt;r.pic, argv[1], FILE_MAXDIR);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
printf("\nError: no blend loaded. cannot use '-o /
--render-output'.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\nError: you must specify a path after '-o&nbsp; / --render-output'.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
static int set_engine(int argc, const char **argv, void *data)<br>
{<br>
&nbsp;&nbsp;&nbsp; bContext *C = data;<br>
&nbsp;&nbsp;&nbsp; if (argc &gt;= 1)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (!strcmp(argv[1],"help"))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderEngineType *type = NULL;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for( type = R_engines.first; type; type = type-&gt;next )<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\t%s\n", type-&gt;idname);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; exit(0);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (CTX_data_scene(C)==NULL)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; printf("\nError: no blend loaded. order the
arguments so '-E&nbsp; / --engine ' is after a blend is loaded.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Scene *scene= CTX_data_scene(C);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RenderData *rd = &amp;scene-&gt;r;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(BLI_findstring(&amp;R_engines, argv[1],
offsetof(RenderEngineType, idname))) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_strncpy(rd-&gt;engine,
argv[1], sizeof(rd-&gt;engine));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\nEngine not specified.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
static int set_image_type(int argc, const char **argv, void *data)<br>
{<br>
&nbsp;&nbsp;&nbsp; bContext *C = data;<br>
&nbsp;&nbsp;&nbsp; if (argc &gt;= 1){<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; const char *imtype = argv[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (CTX_data_scene(C)==NULL) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
printf("\nError: no blend loaded. order the arguments so '-F&nbsp; /
--render-format' is after the blend is loaded.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Scene *scene= CTX_data_scene(C);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
if&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (!strcmp(imtype,"TGA"))
scene-&gt;r.imtype = R_TARGA;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (!strcmp(imtype,"IRIS")) scene-&gt;r.imtype = R_IRIS;<br>
#ifdef WITH_DDS<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (!strcmp(imtype,"DDS")) scene-&gt;r.imtype = R_DDS;<br>
#endif<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (!strcmp(imtype,"JPEG")) scene-&gt;r.imtype = R_JPEG90;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (!strcmp(imtype,"IRIZ")) scene-&gt;r.imtype = R_IRIZ;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (!strcmp(imtype,"RAWTGA")) scene-&gt;r.imtype = R_RAWTGA;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (!strcmp(imtype,"AVIRAW")) scene-&gt;r.imtype = R_AVIRAW;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (!strcmp(imtype,"AVIJPEG")) scene-&gt;r.imtype = R_AVIJPEG;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (!strcmp(imtype,"PNG")) scene-&gt;r.imtype = R_PNG;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (!strcmp(imtype,"AVICODEC")) scene-&gt;r.imtype = R_AVICODEC;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (!strcmp(imtype,"QUICKTIME")) scene-&gt;r.imtype = R_QUICKTIME;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (!strcmp(imtype,"BMP")) scene-&gt;r.imtype = R_BMP;<br>
#ifdef WITH_HDR<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (!strcmp(imtype,"HDR")) scene-&gt;r.imtype = R_RADHDR;<br>
#endif<br>
#ifdef WITH_TIFF<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (!strcmp(imtype,"TIFF")) scene-&gt;r.imtype = R_TIFF;<br>
#endif<br>
#ifdef WITH_OPENEXR<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (!strcmp(imtype,"EXR")) scene-&gt;r.imtype = R_OPENEXR;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if
(!strcmp(imtype,"MULTILAYER")) scene-&gt;r.imtype = R_MULTILAYER;<br>
#endif<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (!strcmp(imtype,"MPEG")) scene-&gt;r.imtype = R_FFMPEG;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if
(!strcmp(imtype,"FRAMESERVER")) scene-&gt;r.imtype = R_FRAMESERVER;<br>
#ifdef WITH_CINEON<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (!strcmp(imtype,"CINEON")) scene-&gt;r.imtype = R_CINEON;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (!strcmp(imtype,"DPX")) scene-&gt;r.imtype = R_DPX;<br>
#endif<br>
#if WITH_OPENJPEG<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (!strcmp(imtype,"JP2")) scene-&gt;r.imtype = R_JP2;<br>
#endif<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else
printf("\nError: Format from '-F / --render-format' not known or not
compiled in this release.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\nError: you must specify a format after '-F&nbsp; / --render-foramt'.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
static int set_threads(int argc, const char **argv, void *UNUSED(data))<br>
{<br>
&nbsp;&nbsp;&nbsp; if (argc &gt;= 1) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(G.background) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_set_max_threads(atoi(argv[1]));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("Warning: threads can only be set in background mode\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\nError: you must specify
a number of threads between 0 and 8 '-t&nbsp; / --threads'.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
static int set_extension(int argc, const char **argv, void *data)<br>
{<br>
&nbsp;&nbsp;&nbsp; bContext *C = data;<br>
&nbsp;&nbsp;&nbsp; if (argc &gt;= 1) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (CTX_data_scene(C)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Scene *scene= CTX_data_scene(C);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (argv[1][0] == '0') {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; scene-&gt;r.scemode &amp;= ~R_EXTENSION;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else if (argv[1][0] == '1') {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; scene-&gt;r.scemode |= R_EXTENSION;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; printf("\nError: Use '-x 1 / -x 0' To set the
extension option or '--use-extension'\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
printf("\nError: no blend loaded. order the arguments so '-o ' is after
'-x '.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\nError: you must specify a path after '- '.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
static int set_ge_parameters(int argc, const char **argv, void *data)<br>
{<br>
&nbsp;&nbsp;&nbsp; int a = 0;<br>
#ifdef WITH_GAMEENGINE<br>
&nbsp;&nbsp;&nbsp; SYS_SystemHandle syshandle = *(SYS_SystemHandle*)data;<br>
#else<br>
&nbsp;&nbsp;&nbsp; (void)data;<br>
#endif<br>
<br>
/**<br>
gameengine parameters are automaticly put into system<br>
-g [paramname = value]<br>
-g [boolparamname]<br>
example:<br>
-g novertexarrays<br>
-g maxvertexarraysize = 512<br>
*/<br>
<br>
&nbsp;&nbsp;&nbsp; if(argc &gt;= 1)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; const char *paramname = argv[a];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* check for single value versus assignment */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (a+1 &lt; argc &amp;&amp; (*(argv[a+1]) == '='))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; a++;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (a+1 &lt; argc)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; a++;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* assignment */<br>
#ifdef WITH_GAMEENGINE<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;
SYS_WriteCommandLineString(syshandle,paramname,argv[a]);<br>
#endif<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; printf("error: argument assignment (%s) without
value.\n",paramname);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* name arg eaten */<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
#ifdef WITH_GAMEENGINE<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; SYS_WriteCommandLineInt(syshandle,argv[a],1);<br>
#endif<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* doMipMap */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (!strcmp(argv[a],"nomipmap"))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; GPU_set_mipmap(0); //doMipMap = 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* linearMipMap */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (!strcmp(argv[a],"linearmipmap"))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; GPU_set_linear_mipmap(1); //linearMipMap = 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } /* if (*(argv[a+1]) == '=') */<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; return a;<br>
}<br>
<br>
static int render_frame(int argc, const char **argv, void *data)<br>
{<br>
&nbsp;&nbsp;&nbsp; bContext *C = data;<br>
&nbsp;&nbsp;&nbsp; if (CTX_data_scene(C)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Main *bmain= CTX_data_main(C);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Scene *scene= CTX_data_scene(C);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (argc &gt; 1) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Render *re = RE_NewRender(scene-&gt;id.name);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int frame;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ReportList reports;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; switch(*argv[1]) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; case '+':<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; frame= scene-&gt;r.sfra + atoi(argv[1]+1);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; case '-':<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; frame= (scene-&gt;r.efra - atoi(argv[1]+1)) + 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; default:<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; frame= atoi(argv[1]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BKE_reports_init(&amp;reports, RPT_PRINT);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; frame = MIN2(MAXFRAME, MAX2(MINAFRAME, frame));<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
RE_BlenderAnim(re, bmain, scene, scene-&gt;lay, frame, frame,
scene-&gt;r.frame_step, &amp;reports);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\nError: frame number must follow '-f / --render-frame'.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
static int render_animation(int UNUSED(argc), const char **UNUSED(argv), void *data)<br>
{<br>
&nbsp;&nbsp;&nbsp; bContext *C = data;<br>
&nbsp;&nbsp;&nbsp; if (CTX_data_scene(C)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Main *bmain= CTX_data_main(C);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Scene *scene= CTX_data_scene(C);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Render *re= RE_NewRender(scene-&gt;id.name);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ReportList reports;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BKE_reports_init(&amp;reports, RPT_PRINT);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_BlenderAnim(re, bmain, scene,
scene-&gt;lay, scene-&gt;r.sfra, scene-&gt;r.efra,
scene-&gt;r.frame_step, &amp;reports);<br>
&nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\nError: no blend loaded. cannot use '-a'.\n");<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static int set_scene(int argc, const char **argv, void *data)<br>
{<br>
&nbsp;&nbsp;&nbsp; if(argc &gt; 1) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bContext *C= data;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Scene *sce= set_scene_name(CTX_data_main(C), argv[1]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(sce) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CTX_data_scene_set(C, sce);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\nError: Scene name must follow '-S / --scene'.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
static int set_start_frame(int argc, const char **argv, void *data)<br>
{<br>
&nbsp;&nbsp;&nbsp; bContext *C = data;<br>
&nbsp;&nbsp;&nbsp; if (CTX_data_scene(C)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Scene *scene= CTX_data_scene(C);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (argc &gt; 1) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int frame = atoi(argv[1]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (scene-&gt;r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\nError: frame number must follow '-s / --frame-start'.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
static int set_end_frame(int argc, const char **argv, void *data)<br>
{<br>
&nbsp;&nbsp;&nbsp; bContext *C = data;<br>
&nbsp;&nbsp;&nbsp; if (CTX_data_scene(C)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Scene *scene= CTX_data_scene(C);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (argc &gt; 1) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int frame = atoi(argv[1]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (scene-&gt;r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\nError: frame number must follow '-e / --frame-end'.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
static int set_skip_frame(int argc, const char **argv, void *data)<br>
{<br>
&nbsp;&nbsp;&nbsp; bContext *C = data;<br>
&nbsp;&nbsp;&nbsp; if (CTX_data_scene(C)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Scene *scene= CTX_data_scene(C);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (argc &gt; 1) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int frame = atoi(argv[1]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (scene-&gt;r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
printf("\nError: number of frames to step must follow '-j /
--frame-jump'.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
/* macro for ugly context setup/reset */<br>
#ifdef WITH_PYTHON<br>
#define BPY_CTX_SETUP(_cmd) \<br>
{ \<br>
&nbsp;&nbsp;&nbsp; wmWindowManager *wm= CTX_wm_manager(C); \<br>
&nbsp;&nbsp;&nbsp; wmWindow *prevwin= CTX_wm_window(C); \<br>
&nbsp;&nbsp;&nbsp; Scene *prevscene= CTX_data_scene(C); \<br>
&nbsp;&nbsp;&nbsp; if(wm-&gt;windows.first) { \<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CTX_wm_window_set(C, wm-&gt;windows.first); \<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _cmd; \<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CTX_wm_window_set(C, prevwin); \<br>
&nbsp;&nbsp;&nbsp; } \<br>
&nbsp;&nbsp;&nbsp; else { \<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fprintf(stderr, "Python script \"%s\" running with missing context data.\n", argv[1]); \<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _cmd; \<br>
&nbsp;&nbsp;&nbsp; } \<br>
&nbsp;&nbsp;&nbsp; CTX_data_scene_set(C, prevscene); \<br>
} \<br>
<br>
#endif /* WITH_PYTHON */<br>
<br>
static int run_python(int argc, const char **argv, void *data)<br>
{<br>
#ifdef WITH_PYTHON<br>
&nbsp;&nbsp;&nbsp; bContext *C = data;<br>
<br>
&nbsp;&nbsp;&nbsp; /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */<br>
&nbsp;&nbsp;&nbsp; if (argc &gt; 1) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Make the path absolute because its needed for relative linked blends to be found */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; char filename[FILE_MAXDIR + FILE_MAXFILE];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_strncpy(filename, argv[1], sizeof(filename));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_path_cwd(filename);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BPY_CTX_SETUP(BPY_filepath_exec(C, filename, NULL))<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\nError: you must specify a Python script after '-P / --python'.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
#else<br>
&nbsp;&nbsp;&nbsp; (void)argc; (void)argv; (void)data; /* unused */<br>
&nbsp;&nbsp;&nbsp; printf("This blender was built without python support\n");<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
#endif /* WITH_PYTHON */<br>
}<br>
<br>
static int run_python_console(int UNUSED(argc), const char **argv, void *data)<br>
{<br>
#ifdef WITH_PYTHON<br>
&nbsp;&nbsp;&nbsp; bContext *C = data;<br>
<br>
&nbsp;&nbsp;&nbsp; BPY_CTX_SETUP(BPY_string_exec(C, "__import__('code').interact()"))<br>
<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
#else<br>
&nbsp;&nbsp;&nbsp; (void)argv; (void)data; /* unused */<br>
&nbsp;&nbsp;&nbsp; printf("This blender was built without python support\n");<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
#endif /* WITH_PYTHON */<br>
}<br>
<br>
static int set_addons(int argc, const char **argv, void *data)<br>
{<br>
&nbsp;&nbsp;&nbsp; /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */<br>
&nbsp;&nbsp;&nbsp; if (argc &gt; 1) {<br>
#ifdef WITH_PYTHON<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; const int slen= strlen(argv[1]) + 128;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; char *str= malloc(slen);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bContext *C= data;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_snprintf(str, slen,
"[__import__('addon_utils').enable(i, default_set=False) for i in
'%s'.split(',')]", argv[1]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BPY_CTX_SETUP(BPY_string_exec(C, str));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; free(str);<br>
#else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (void)argv; (void)data; /* unused */<br>
#endif /* WITH_PYTHON */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("\nError: you must specify a comma separated list after '--addons'.\n");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
<br>
static int load_file(int UNUSED(argc), const char **argv, void *data)<br>
{<br>
&nbsp;&nbsp;&nbsp; bContext *C = data;<br>
<br>
&nbsp;&nbsp;&nbsp; /* Make the path absolute because its needed for relative linked blends to be found */<br>
&nbsp;&nbsp;&nbsp; char filename[FILE_MAXDIR + FILE_MAXFILE];<br>
&nbsp;&nbsp;&nbsp; BLI_strncpy(filename, argv[0], sizeof(filename));<br>
&nbsp;&nbsp;&nbsp; BLI_path_cwd(filename);<br>
<br>
&nbsp;&nbsp;&nbsp; if (G.background) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int retval = BKE_read_file(C, filename, NULL);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /*we successfully loaded a blend file, get sure that<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pointcache works */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (retval != BKE_READ_FILE_FAIL) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; wmWindowManager *wm= CTX_wm_manager(C);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* special case, 2.4x files */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(wm==NULL &amp;&amp; CTX_data_main(C)-&gt;wm.first==NULL) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; extern void wm_add_default(bContext *C);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* wm_add_default() needs the screen to be set. */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; CTX_wm_screen_set(C,
CTX_data_main(C)-&gt;screen.first);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; wm_add_default(C);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CTX_wm_manager_set(C, NULL); /* remove wm to force check */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WM_check(C);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; G.relbase_valid = 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if
(CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; DAG_on_visible_update(CTX_data_main(C), TRUE);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* WM_read_file() runs normally but since we're in background mode do here */<br>
#ifdef WITH_PYTHON<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* run any texts that were loaded in and flagged as modules */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BPY_driver_reset();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BPY_modules_load_user(C);<br>
#endif<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* happens for the UI on file reading too (huh? (ton))*/<br>
&nbsp;&nbsp;&nbsp; // XXX&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BKE_reset_undo();<br>
&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
BKE_write_undo("original");&nbsp;&nbsp;&nbsp; /* save current state */<br>
&nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* we are not running in background mode here, but start blender in UI mode with<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; a file - this should do everything a 'load file' does */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ReportList reports;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BKE_reports_init(&amp;reports, RPT_PRINT);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WM_read_file(C, filename, &amp;reports);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BKE_reports_clear(&amp;reports);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; G.file_loaded = 1;<br>
<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)<br>
{<br>
&nbsp;&nbsp;&nbsp; static char output_doc[] = "&lt;path&gt;"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\tSet the render path and file name."<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\tUse // at the start of the path to"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t\trender relative to the blend file."<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\tThe # characters are replaced by the frame number, and used to define zero padding."<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t\tani_##_test.png becomes ani_01_test.png"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t\ttest-######.png becomes test-000001.png"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\tThe frame number will be added at the end of the filename."<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";<br>
<br>
&nbsp;&nbsp;&nbsp; static char format_doc[] = "&lt;format&gt;"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\tSet the render format, Valid options are..."<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t(formats that can be compiled into blender, not available on all systems)"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";<br>
<br>
&nbsp;&nbsp;&nbsp; static char playback_doc[] = "&lt;options&gt; &lt;file(s)&gt;"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\tPlayback &lt;file(s)&gt;, only operates this way when not running in background."<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t\t-p &lt;sx&gt; &lt;sy&gt;\tOpen with lower left corner at &lt;sx&gt;, &lt;sy&gt;"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t\t-m\t\tRead from disk (Don't buffer)"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t\t-f &lt;fps&gt; &lt;fps-base&gt;\t\tSpecify FPS to start with"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t\t-j &lt;frame&gt;\tSet frame step to &lt;frame&gt;";<br>
<br>
&nbsp;&nbsp;&nbsp; static char game_doc[] = "Game Engine specific options"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t-g vertexarrays\t\tUse Vertex Arrays for rendering (usually faster)"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t-g nomipmap\t\tNo Texture Mipmapping"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t-g linearmipmap\t\tLinear Texture Mipmapping instead of Nearest (default)";<br>
<br>
&nbsp;&nbsp;&nbsp; static char debug_doc[] = "\n\tTurn debugging on\n"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t* Prints every operator call and their arguments"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t* Disables mouse grab (to interact with a debugger in some cases)"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\t* Keeps python sys.stdin rather then setting it to None";<br>
<br>
&nbsp;&nbsp;&nbsp; //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);<br>
<br>
&nbsp;&nbsp;&nbsp; /* end argument processing after -- */<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option
processing, following arguments passed unchanged. Access via python's
sys.argv", end_arguments, NULL);<br>
<br>
&nbsp;&nbsp;&nbsp; /* first pass: background mode, disable python and commands that exit after usage */<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);<br>
&nbsp;&nbsp;&nbsp; /* Windows only */<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 1, "-y", "--enable-autoexec",
"\n\tEnable automatic python script execution (default)",
enable_python, NULL);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec",
"\n\tDisable automatic python script execution (pydrivers,
pyconstraints, pynodes)", disable_python, NULL);<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 1, "-b", "--background",
"&lt;file&gt;\n\tLoad &lt;file&gt; in background (often used for
UI-less rendering)", background_mode, NULL);<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 1, NULL, "--factory-startup",
"\n\tSkip reading the "STRINGIFY(BLENDER_STARTUP_FILE)" in the users
home directory", set_factory_startup, NULL);<br>
<br>
&nbsp;&nbsp;&nbsp; /* TODO, add user env vars? */<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 1, NULL,
"--env-system-config",&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\tSet
the "STRINGIFY_ARG(BLENDER_SYSTEM_CONFIG)" environment variable",
set_env, NULL);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 1, NULL,
"--env-system-datafiles",&nbsp;&nbsp;&nbsp; "\n\tSet the
"STRINGIFY_ARG(BLENDER_SYSTEM_DATAFILES)" environment variable",
set_env, NULL);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 1, NULL,
"--env-system-scripts",&nbsp;&nbsp;&nbsp; "\n\tSet the
"STRINGIFY_ARG(BLENDER_SYSTEM_SCRIPTS)" environment variable", set_env,
NULL);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 1, NULL,
"--env-system-plugins",&nbsp;&nbsp;&nbsp; "\n\tSet the
"STRINGIFY_ARG(BLENDER_SYSTEM_PLUGINS)" environment variable", set_env,
NULL);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 1, NULL,
"--env-system-python",&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "\n\tSet
the "STRINGIFY_ARG(BLENDER_SYSTEM_PYTHON)" environment variable",
set_env, NULL);<br>
<br>
&nbsp;&nbsp;&nbsp; /* second pass: custom window stuff */<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 2, "-p", "--window-geometry",
"&lt;sx&gt; &lt;sy&gt; &lt;w&gt; &lt;h&gt;\n\tOpen with lower left
corner at &lt;sx&gt;, &lt;sy&gt; and width and height as &lt;w&gt;,
&lt;h&gt;", prefsize, NULL);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening without borders", without_borders, NULL);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 2, "-con", "--start-console",
"\n\tStart with the console window open (ignored if -b is set)",
start_with_console, NULL);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend
extension, then exit (Windows only)", register_extension, NULL);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 2, "-r", NULL, "\n\tSilently
register .blend extension, then exit (Windows only)",
register_extension, ba);<br>
<br>
&nbsp;&nbsp;&nbsp; /* third pass: disabling things and forcing settings */<br>
&nbsp;&nbsp;&nbsp; BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, "\n\tDisable GLSL shading", no_glsl, NULL);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, "\n\tForce sound system to None", no_audio, NULL);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0,
"\n\tForce sound system to a specific device\n\tNULL SDL OPENAL JACK",
set_audio, NULL);<br>
<br>
&nbsp;&nbsp;&nbsp; /* fourth pass: processing arguments */<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 4, "-g", NULL, game_doc, set_ge_parameters, syshandle);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 4, "-f", "--render-frame",
"&lt;frame&gt;\n\tRender frame &lt;frame&gt; and save
it.\n\t+&lt;frame&gt; start frame relative, -&lt;frame&gt; end frame
relative.", render_frame, C);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 4, "-a", "--render-anim",
"\n\tRender frames from start to end (inclusive)", render_animation, C);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 4, "-S", "--scene",
"&lt;name&gt;\n\tSet the active scene &lt;name&gt; for rendering",
set_scene, C);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 4, "-s", "--frame-start",
"&lt;frame&gt;\n\tSet start to frame &lt;frame&gt; (use before the -a
argument)", set_start_frame, C);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 4, "-e", "--frame-end",
"&lt;frame&gt;\n\tSet end to frame &lt;frame&gt; (use before the -a
argument)", set_end_frame, C);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 4, "-j", "--frame-jump",
"&lt;frames&gt;\n\tSet number of frames to step forward after each
rendered frame", set_skip_frame, C);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 4, "-P", "--python",
"&lt;filename&gt;\n\tRun the given Python script (filename or Blender
Text)", run_python, C);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 4, NULL, "--python-console",
"\n\tRun blender with an interactive console", run_python_console, C);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 4, NULL, "--addons", "\n\tComma separated list of addons (no spaces)", set_addons, C);<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 4, "-o", "--render-output", output_doc, set_output, C);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 4, "-E", "--engine",
"&lt;engine&gt;\n\tSpecify the render engine\n\tuse -E help to list
available engines", set_engine, C);<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 4, "-F", "--render-format", format_doc, set_image_type, C);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 4, "-t", "--threads",
"&lt;threads&gt;\n\tUse amount of &lt;threads&gt; for rendering in
background\n\t[1-" STRINGIFY(BLENDER_MAX_THREADS) "], 0 for systems
processor count.", set_threads, NULL);<br>
&nbsp;&nbsp;&nbsp; BLI_argsAdd(ba, 4, "-x", "--use-extension",
"&lt;bool&gt;\n\tSet option to add the file extension to the end of the
file", set_extension, C);<br>
<br>
}<br>
<br>
#ifdef WITH_PYTHON_MODULE<br>
/* allow python module to call main */<br>
#define main main_python<br>
#endif<br>
<br>
<span style="background-color: rgb(255, 153, 0);">void CreateTiming(char* name, ...)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">{</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">#include &lt;time.h&gt;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">#include &lt;stdarg.h&gt;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; static time_t nStartTime = 0;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; static FILE* stream = NULL;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; char buffer[256];</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; if (nStartTime == 0)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stream = fopen("timing.txt", "w");</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nStartTime = time(NULL);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; if (name != NULL)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; va_list argptr;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; va_start(argptr, name);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; vsprintf(buffer, name, argptr);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sprintf(buffer + strlen(buffer), ": %d\n", time(NULL) - nStartTime);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; va_end(argptr);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(stream, "%s", buffer);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; else</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(stream, "The end of program: %d\n", time(NULL) - nStartTime);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fclose(stream);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">}</span><br style="background-color: rgb(255, 153, 0);">
<br>
<br>
int main(int argc, const char **argv)<br>
{<br>
&nbsp;&nbsp;&nbsp; SYS_SystemHandle syshandle;<br>
&nbsp;&nbsp;&nbsp; bContext *C= CTX_create();<br>
&nbsp;&nbsp;&nbsp; bArgs *ba;<br>
<br>
&nbsp;&nbsp;&nbsp; CreateTiming("Start program...");<br>
<br>
<br>
#ifdef WITH_PYTHON_MODULE<br>
#undef main<br>
#endif<br>
<br>
#ifdef WITH_BINRELOC<br>
&nbsp;&nbsp;&nbsp; br_init( NULL );<br>
#endif<br>
<br>
&nbsp;&nbsp;&nbsp; setCallbacks();<br>
#ifdef __APPLE__<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* patch to ignore argument finder gives us (pid?) */<br>
&nbsp;&nbsp;&nbsp; if (argc==2 &amp;&amp; strncmp(argv[1], "-psn_", 5)==0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; extern int GHOST_HACK_getFirstFile(char buf[]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; static char firstfilebuf[512];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; argc= 1;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (GHOST_HACK_getFirstFile(firstfilebuf)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; argc= 2;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; argv[1]= firstfilebuf;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
#endif<br>
<br>
#ifdef __FreeBSD__<br>
&nbsp;&nbsp;&nbsp; fpsetmask(0);<br>
#endif<br>
<br>
&nbsp;&nbsp;&nbsp; // copy path to executable in bprogname. playanim and creting runtimes<br>
&nbsp;&nbsp;&nbsp; // need this.<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_where_am_i(bprogname, sizeof(bprogname), argv[0]);<br>
<br>
#ifdef BUILD_DATE<br>
&nbsp;&nbsp;&nbsp; strip_quotes(build_date);<br>
&nbsp;&nbsp;&nbsp; strip_quotes(build_time);<br>
&nbsp;&nbsp;&nbsp; strip_quotes(build_rev);<br>
&nbsp;&nbsp;&nbsp; strip_quotes(build_platform);<br>
&nbsp;&nbsp;&nbsp; strip_quotes(build_type);<br>
&nbsp;&nbsp;&nbsp; strip_quotes(build_cflags);<br>
&nbsp;&nbsp;&nbsp; strip_quotes(build_cxxflags);<br>
&nbsp;&nbsp;&nbsp; strip_quotes(build_linkflags);<br>
&nbsp;&nbsp;&nbsp; strip_quotes(build_system);<br>
#endif<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_threadapi_init();<br>
<br>
&nbsp;&nbsp;&nbsp; RNA_init();<br>
&nbsp;&nbsp;&nbsp; RE_engines_init();<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Hack - force inclusion of the plugin api functions,<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* see blenpluginapi:pluginapi.c<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;*/<br>
&nbsp;&nbsp;&nbsp; pluginapi_force_ref();<br>
<br>
&nbsp;&nbsp;&nbsp; init_nodesystem();<br>
<br>
&nbsp;&nbsp;&nbsp; initglobals();&nbsp;&nbsp;&nbsp; /* blender.c */<br>
<br>
&nbsp;&nbsp;&nbsp; IMB_init();<br>
<br>
#ifdef WITH_GAMEENGINE<br>
&nbsp;&nbsp;&nbsp; syshandle = SYS_GetSystem();<br>
&nbsp;&nbsp;&nbsp; GEN_init_messaging_system();<br>
#else<br>
&nbsp;&nbsp;&nbsp; syshandle= 0;<br>
#endif<br>
<br>
&nbsp;&nbsp;&nbsp; /* first test for background */<br>
&nbsp;&nbsp;&nbsp; ba = BLI_argsInit(argc, argv); /* skip binary path */<br>
&nbsp;&nbsp;&nbsp; setupArguments(C, ba, &amp;syshandle);<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_argsParse(ba, 1, NULL, NULL);<br>
<br>
#ifdef __sgi<br>
&nbsp;&nbsp;&nbsp; setuid(getuid()); /* end superuser */<br>
#endif<br>
<br>
#ifdef WITH_PYTHON_MODULE<br>
&nbsp;&nbsp;&nbsp; G.background= 1; /* python module mode ALWAYS runs in background mode (for now) */<br>
#else<br>
&nbsp;&nbsp;&nbsp; /* for all platforms, even windos has it! */<br>
&nbsp;&nbsp;&nbsp; if(G.background) signal(SIGINT, blender_esc);&nbsp;&nbsp;&nbsp; /* ctrl c out bg render */<br>
#endif<br>
<br>
&nbsp;&nbsp;&nbsp; /* background render uses this font too */<br>
&nbsp;&nbsp;&nbsp; BKE_font_register_builtin(datatoc_Bfont, datatoc_Bfont_size);<br>
<br>
&nbsp;&nbsp;&nbsp; /* Initialiaze ffmpeg if built in, also needed for bg mode if videos are<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; rendered via ffmpeg */<br>
&nbsp;&nbsp;&nbsp; sound_init_once();<br>
<br>
&nbsp;&nbsp;&nbsp; init_def_material();<br>
<br>
&nbsp;&nbsp;&nbsp; if(G.background==0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_argsParse(ba, 2, NULL, NULL);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_argsParse(ba, 3, NULL, NULL);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WM_init(C, argc, argv);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* this is properly initialized with user defs, but this is default */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_where_is_temp(btempdir,
FILE_MAX, 1); /* call after loading the startup.blend so we can read
U.tempdir */<br>
<br>
#ifndef DISABLE_SDL<br>
&nbsp;&nbsp;&nbsp; BLI_setenv("SDL_VIDEODRIVER", "dummy");<br>
#endif<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_argsParse(ba, 3, NULL, NULL);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WM_init(C, argc, argv);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_where_is_temp(btempdir,
FILE_MAX, 0); /* call after loading the startup.blend so we can read
U.tempdir */<br>
&nbsp;&nbsp;&nbsp; }<br>
#ifdef WITH_PYTHON<br>
&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; &nbsp;* NOTE: the U.pythondir string is NULL until WM_init() is executed,<br>
&nbsp;&nbsp;&nbsp; &nbsp;* so we provide the BPY_ function below to append the user defined<br>
&nbsp;&nbsp;&nbsp; &nbsp;* pythondir to Python's sys.path at this point.&nbsp; Simply putting<br>
&nbsp;&nbsp;&nbsp; &nbsp;* WM_init() before BPY_python_start() crashes Blender at startup.<br>
&nbsp;&nbsp;&nbsp; &nbsp;* Update: now this function also inits the bpymenus, which also depend<br>
&nbsp;&nbsp;&nbsp; &nbsp;* on U.pythondir.<br>
&nbsp;&nbsp;&nbsp; &nbsp;*/<br>
<br>
&nbsp;&nbsp;&nbsp; // TODO - U.pythondir<br>
#else<br>
&nbsp;&nbsp;&nbsp; printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");<br>
#endif<br>
<br>
&nbsp;&nbsp;&nbsp; CTX_py_init_set(C, 1);<br>
&nbsp;&nbsp;&nbsp; WM_keymap_init(C);<br>
<br>
&nbsp;&nbsp;&nbsp; CreateTiming("Setup program...");<br>
&nbsp;&nbsp;&nbsp; /* OK we are ready for it */<br>
&nbsp;&nbsp;&nbsp; BLI_argsParse(ba, 4, load_file, C);<br>
&nbsp;&nbsp;&nbsp; CreateTiming("Finish rendering program...");<br>
&nbsp;&nbsp;&nbsp; BLI_argsFree(ba);<br>
<br>
#ifdef WITH_PYTHON_MODULE<br>
&nbsp;&nbsp;&nbsp; return 0; /* keep blender in background mode running */<br>
#endif<br>
<br>
&nbsp;&nbsp;&nbsp; if(G.background) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* actually incorrect, but works for now (ton) */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CreateTiming(NULL);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WM_exit(C);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if((G.fileflags &amp; G_FILE_AUTOPLAY) &amp;&amp; (G.f &amp; G_SCRIPT_AUTOEXEC))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(WM_init_game(C))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if(!G.file_loaded)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WM_init_splash(C);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; WM_main(C);<br>
<br>
<br>
&nbsp;&nbsp;&nbsp; /*XXX if (scr_init==0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; main_init_screen();<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; screenmain();*/ /* main display loop */<br>
<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
} /* end of int main(argc,argv)&nbsp;&nbsp;&nbsp; */<br>
<br>
static void error_cb(const char *err)<br>
{<br>
<br>
&nbsp;&nbsp;&nbsp; printf("%s\n", err);&nbsp;&nbsp;&nbsp; /* XXX do this in WM too */<br>
}<br>
<br>
static void mem_error_cb(const char *errorStr)<br>
{<br>
&nbsp;&nbsp;&nbsp; fputs(errorStr, stderr);<br>
&nbsp;&nbsp;&nbsp; fflush(stderr);<br>
}<br>
<br>
static void setCallbacks(void)<br>
{<br>
&nbsp;&nbsp;&nbsp; /* Error output from the alloc routines: */<br>
&nbsp;&nbsp;&nbsp; MEM_set_error_callback(mem_error_cb);<br>
<br>
<br>
&nbsp;&nbsp;&nbsp; /* BLI_blenlib: */<br>
<br>
&nbsp;&nbsp;&nbsp; BLI_setErrorCallBack(error_cb); /* */<br>
// XXX&nbsp;&nbsp;&nbsp; BLI_setInterruptCallBack(blender_test_break);<br>
<br>
}<br></p>
<p><big style="font-weight: bold; color: red;"><br>
</big></p>
<p><big style="font-weight: bold; color: red;">////////////////////////////////////////////////////<br>
The below is another futile efforts as I tried to put multiple thread
in procedure of raytree creating. However, it seems there is very
little concurrency as <br>
I have to use multiple "critical-section" to synchronize threads.
Therefore it turns out the multiple-threaded version is even 30% slower
than original single<br>
threaded one. (original say 35sec, threaded is 45sec)<br>
</big></p>
<p><big style="font-weight: bold; color: red;">filename: source/blender/render/intern/source/rayshade.c<br>
</big>&nbsp;กก

</p>
<p>/*<br>
&nbsp;* $Id: rayshade.c 36282 2011-04-22 14:47:35Z campbellbarton $<br>
&nbsp;*<br>
&nbsp;* ***** BEGIN GPL LICENSE BLOCK *****<br>
&nbsp;*<br>
&nbsp;* This program is free software; you can redistribute it and/or<br>
&nbsp;* modify it under the terms of the GNU General Public License<br>
&nbsp;* as published by the Free Software Foundation; either version 2<br>
&nbsp;* of the License, or (at your option) any later version.<br>
&nbsp;*<br>
&nbsp;* This program is distributed in the hope that it will be useful,<br>
&nbsp;* but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
&nbsp;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&nbsp; See the<br>
&nbsp;* GNU General Public License for more details.<br>
&nbsp;*<br>
&nbsp;* You should have received a copy of the GNU General Public License<br>
&nbsp;* along with this program; if not, write to the Free Software Foundation,<br>
&nbsp;* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.<br>
&nbsp;*<br>
&nbsp;* The Original Code is Copyright (C) 1990-1998 NeoGeo BV.<br>
&nbsp;* All rights reserved.<br>
&nbsp;*<br>
&nbsp;* Contributors: 2004/2005 Blender Foundation, full recode<br>
&nbsp;*<br>
&nbsp;* ***** END GPL LICENSE BLOCK *****<br>
&nbsp;*/<br>
<br>
/** \file blender/render/intern/source/rayshade.c<br>
&nbsp;*&nbsp; \ingroup render<br>
&nbsp;*/<br>
<br>
<br>
#include &lt;stdio.h&gt;<br>
#include &lt;math.h&gt;<br>
#include &lt;string.h&gt;<br>
#include &lt;stdlib.h&gt;<br>
#include &lt;float.h&gt;<br>
#include &lt;assert.h&gt;<br>
<br>
#include "MEM_guardedalloc.h"<br>
<br>
#include "DNA_material_types.h"<br>
#include "DNA_lamp_types.h"<br>
<br>
#include "BLI_blenlib.h"<br>
#include "BLI_cpu.h"<br>
#include "BLI_jitter.h"<br>
#include "BLI_math.h"<br>
#include "BLI_rand.h"<br>
#include "BLI_utildefines.h"<br>
<br>
#include "BKE_global.h"<br>
#include "BKE_node.h"<br>
<br>
<br>
#include "PIL_time.h"<br>
<br>
#include "render_types.h"<br>
#include "renderpipeline.h"<br>
#include "rendercore.h"<br>
#include "renderdatabase.h"<br>
#include "pixelblending.h"<br>
#include "pixelshading.h"<br>
#include "shading.h"<br>
#include "texture.h"<br>
#include "volumetric.h"<br>
<br>
#include "rayintersection.h"<br>
#include "rayobject.h"<br>
#include "raycounter.h"<br>
<br>
<br>
#define RAY_TRA&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 1<br>
#define RAY_INSIDE&nbsp;&nbsp;&nbsp; 2<br>
<br>
#define DEPTH_SHADOW_TRA&nbsp; 10<br>
<br>
<br>
<br>
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */<br>
/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */<br>
/* only to be used here in this file, it's for speed */<br>
extern struct Render R;<br>
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */<br>
static int test_break(void *data)<br>
{<br>
&nbsp;&nbsp;&nbsp; Render *re = (Render*)data;<br>
&nbsp;&nbsp;&nbsp; return re-&gt;test_break(re-&gt;tbh);<br>
}<br>
<br>
static void RE_rayobject_config_control(RayObject *r, Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; if(RE_rayobject_isRayAPI(r))<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; r = RE_rayobject_align( r );<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; r-&gt;control.data = re;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; r-&gt;control.test_break = test_break;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
RayObject*&nbsp; RE_rayobject_create(Render *re, int type, int size)<br>
{<br>
&nbsp;&nbsp;&nbsp; RayObject * res = NULL;<br>
<br>
&nbsp;&nbsp;&nbsp; if(type == R_RAYSTRUCTURE_AUTO)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //TODO<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //if(detect_simd())<br>
#ifdef __SSE__<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; type = BLI_cpu_support_sse2()? R_RAYSTRUCTURE_SIMD_SVBVH: R_RAYSTRUCTURE_VBVH;<br>
#else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; type = R_RAYSTRUCTURE_VBVH;<br>
#endif<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
#ifndef __SSE__<br>
&nbsp;&nbsp;&nbsp; if(type == R_RAYSTRUCTURE_SIMD_SVBVH || type == R_RAYSTRUCTURE_SIMD_QBVH)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; puts("Warning: Using VBVH (SSE was disabled at compile time)");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; type = R_RAYSTRUCTURE_VBVH;<br>
&nbsp;&nbsp;&nbsp; }<br>
#endif<br>
<br>
<br>
&nbsp;&nbsp;&nbsp; if(type == R_RAYSTRUCTURE_OCTREE) //TODO dynamic ocres<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; res = RE_rayobject_octree_create(re-&gt;r.ocres, size);<br>
&nbsp;&nbsp;&nbsp; else if(type == R_RAYSTRUCTURE_BLIBVH)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; res = RE_rayobject_blibvh_create(size);<br>
&nbsp;&nbsp;&nbsp; else if(type == R_RAYSTRUCTURE_VBVH)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; res = RE_rayobject_vbvh_create(size);<br>
&nbsp;&nbsp;&nbsp; else if(type == R_RAYSTRUCTURE_SIMD_SVBVH)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; res = RE_rayobject_svbvh_create(size);<br>
&nbsp;&nbsp;&nbsp; else if(type == R_RAYSTRUCTURE_SIMD_QBVH)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; res = RE_rayobject_qbvh_create(size);<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; res = RE_rayobject_vbvh_create(size);&nbsp;&nbsp;&nbsp; //Fallback<br>
<br>
<br>
&nbsp;&nbsp;&nbsp; if(res)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_rayobject_config_control( res, re );<br>
<br>
&nbsp;&nbsp;&nbsp; return res;<br>
}<br>
<br>
#ifdef RE_RAYCOUNTER<br>
RayCounter re_rc_counter[BLENDER_MAX_THREADS];<br>
#endif<br>
<br>
<br>
void freeraytree(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; ObjectInstanceRen *obi;<br>
<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;raytree)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_rayobject_free(re-&gt;raytree);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;raytree = NULL;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;rayfaces)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MEM_freeN(re-&gt;rayfaces);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;rayfaces = NULL;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;rayprimitives)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MEM_freeN(re-&gt;rayprimitives);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;rayprimitives = NULL;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; for(obi=re-&gt;instancetable.first; obi; obi=obi-&gt;next)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ObjectRen *obr = obi-&gt;obr;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(obr-&gt;raytree)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_rayobject_free(obr-&gt;raytree);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; obr-&gt;raytree = NULL;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(obr-&gt;rayfaces)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MEM_freeN(obr-&gt;rayfaces);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; obr-&gt;rayfaces = NULL;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(obi-&gt;raytree)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_rayobject_free(obi-&gt;raytree);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; obi-&gt;raytree = NULL;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
#ifdef RE_RAYCOUNTER<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RayCounter sum;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memset( &amp;sum, 0, sizeof(sum) );<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int i;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(i=0; i&lt;BLENDER_MAX_THREADS; i++)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_RC_MERGE(&amp;sum, re_rc_counter+i);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_RC_INFO(&amp;sum);<br>
&nbsp;&nbsp;&nbsp; }<br>
#endif<br>
}<br>
<br>
static int is_raytraceable_vlr(Render *re, VlakRen *vlr)<br>
{<br>
&nbsp;&nbsp;&nbsp; /* note: volumetric must be tracable, wire must not */<br>
&nbsp;&nbsp;&nbsp; if((re-&gt;flag &amp; R_BAKE_TRACE) || (vlr-&gt;flag
&amp; R_TRACEBLE) || (vlr-&gt;mat-&gt;material_type == MA_TYPE_VOLUME))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(vlr-&gt;mat-&gt;material_type != MA_TYPE_WIRE)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static int is_raytraceable(Render *re, ObjectInstanceRen *obi)<br>
{<br>
&nbsp;&nbsp;&nbsp; int v;<br>
&nbsp;&nbsp;&nbsp; ObjectRen *obr = obi-&gt;obr;<br>
<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;excludeob &amp;&amp; obr-&gt;ob == re-&gt;excludeob)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
<br>
&nbsp;&nbsp;&nbsp; for(v=0;v&lt;obr-&gt;totvlak;v++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VlakRen *vlr = obr-&gt;vlaknodes[v&gt;&gt;8].vlak + (v&amp;255);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(is_raytraceable_vlr(re, vlr))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)<br>
{<br>
&nbsp;&nbsp;&nbsp; //TODO<br>
&nbsp;&nbsp;&nbsp; // out-of-memory safeproof<br>
&nbsp;&nbsp;&nbsp; // break render<br>
&nbsp;&nbsp;&nbsp; // update render stats<br>
&nbsp;&nbsp;&nbsp; ObjectRen *obr = obi-&gt;obr;<br>
<br>
&nbsp;&nbsp;&nbsp; if(obr-&gt;raytree == NULL)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RayObject *raytree;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RayFace *face = NULL;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VlakPrimitive *vlakprimitive = NULL;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int v;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //Count faces<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int faces = 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(v=0;v&lt;obr-&gt;totvlak;v++)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VlakRen *vlr = obr-&gt;vlaknodes[v&gt;&gt;8].vlak + (v&amp;255);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(is_raytraceable_vlr(re, vlr))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; faces++;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (faces == 0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return NULL;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //Create Ray cast accelaration structure<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; raytree = RE_rayobject_create( re,&nbsp; re-&gt;r.raytrace_structure, faces );<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(&nbsp; (re-&gt;r.raytrace_options &amp; R_RAYTRACE_USE_LOCAL_COORDS) )<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; vlakprimitive
= obr-&gt;rayprimitives =
(VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "ObjectRen
primitives");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; face =
obr-&gt;rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace),
"ObjectRen faces");<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; obr-&gt;rayobi = obi;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(v=0;v&lt;obr-&gt;totvlak;v++)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VlakRen *vlr = obr-&gt;vlaknodes[v&gt;&gt;8].vlak + (v&amp;255);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(is_raytraceable_vlr(re, vlr))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(&nbsp; (re-&gt;r.raytrace_options &amp;
R_RAYTRACE_USE_LOCAL_COORDS) )<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_rayobject_add( raytree,
RE_vlakprimitive_from_vlak( vlakprimitive, obi, vlr ) );<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; vlakprimitive++;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_rayface_from_vlak( face, obi,
vlr );<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_rayobject_add( raytree,
RE_rayobject_unalignRayFace(face) );<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; face++;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_rayobject_done( raytree );<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* in case of cancel during build, raytree is not usable */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(test_break(re))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_rayobject_free(raytree);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; obr-&gt;raytree= raytree;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if(obr-&gt;raytree) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if((obi-&gt;flag &amp; R_TRANSFORMED) &amp;&amp; obi-&gt;raytree == NULL)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; obi-&gt;transform_primitives = 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
obi-&gt;raytree = RE_rayobject_instance_create( obr-&gt;raytree,
obi-&gt;mat, obi, obi-&gt;obr-&gt;rayobi );<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if(obi-&gt;raytree) return obi-&gt;raytree;<br>
&nbsp;&nbsp;&nbsp; return obi-&gt;obr-&gt;raytree;<br>
}<br>
<br>
<br>
static int has_special_rayobject(Render *re, ObjectInstanceRen *obi)<br>
{<br>
&nbsp;&nbsp;&nbsp; if( (obi-&gt;flag &amp; R_TRANSFORMED) &amp;&amp;
(re-&gt;r.raytrace_options &amp; R_RAYTRACE_USE_INSTANCES) )<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ObjectRen *obr = obi-&gt;obr;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int v, faces = 0;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(v=0;v&lt;obr-&gt;totvlak;v++)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VlakRen *vlr = obr-&gt;vlaknodes[v&gt;&gt;8].vlak + (v&amp;255);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(is_raytraceable_vlr(re, vlr))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; faces++;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(faces &gt; 4)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
<span style="background-color: rgb(255, 153, 0);">#ifdef NICK_EDIT</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">typedef struct MakeRayTreeThreadData</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">{</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; Render *re;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; ObjectInstanceRen *obi;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; RayFace *face;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; VlakPrimitive *vlakprimitive;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; int finishedCount;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">} MakeRayTreeThreadData;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">static void* do_make_raytree_single(void* ptr)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">{</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; MakeRayTreeThreadData* threadData = (MakeRayTreeThreadData*)ptr;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; Render *re;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; RayObject *raytree = NULL;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; ObjectInstanceRen *obi = NULL;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; RayFace *face = NULL;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; VlakPrimitive *vlakprimitive = NULL;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; // we assume threadData is valid pointer</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; re = threadData-&gt;re;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; raytree = re-&gt;raytree;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; while (1)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ///////////////////////////</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // sync retrieve next obi</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_lock_thread(LOCK_RAYTREE_READ);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; obi = threadData-&gt;obi;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (obi)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; threadData-&gt;obi = obi-&gt;next;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_unlock_thread(LOCK_RAYTREE_READ);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /////////////////////////////////</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (obi == NULL || test_break(re))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(is_raytraceable(re, obi))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(has_special_rayobject(re, obi))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RayObject *obj = makeraytree_object(re, obi);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(test_break(re))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (obj)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; BLI_lock_thread(LOCK_RAYTREE_WRITE);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; RE_rayobject_add( re-&gt;raytree, obj );</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; BLI_unlock_thread(LOCK_RAYTREE_WRITE);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int v;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ObjectRen *obr = obi-&gt;obr;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(obi-&gt;flag &amp; R_TRANSFORMED)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; obi-&gt;transform_primitives = 1;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(v=0;v&lt;obr-&gt;totvlak;v++)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; VlakRen *vlr = obr-&gt;vlaknodes[v&gt;&gt;8].vlak +
(v&amp;255);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(is_raytraceable_vlr(re, vlr))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
BLI_lock_thread(LOCK_RAYTREE_WRITE);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // REMEMBER WE NOW READ THE
POINTER!</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; face = threadData-&gt;face;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; vlakprimitive =
threadData-&gt;vlakprimitive;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if( (re-&gt;r.raytrace_options
&amp; R_RAYTRACE_USE_LOCAL_COORDS) )</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RayObject *obj
= RE_vlakprimitive_from_vlak( vlakprimitive, obi, vlr );</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
RE_rayobject_add( raytree, obj );</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
vlakprimitive++;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
RE_rayface_from_vlak(face, obi, vlr);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
if((obi-&gt;flag &amp; R_TRANSFORMED))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; mul_m4_v3(obi-&gt;mat, face-&gt;v1);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; mul_m4_v3(obi-&gt;mat, face-&gt;v2);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; mul_m4_v3(obi-&gt;mat, face-&gt;v3);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(RE_rayface_isQuad(face))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mul_m4_v3(obi-&gt;mat,
face-&gt;v4);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
RE_rayobject_add( raytree, RE_rayobject_unalignRayFace(face) );</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; face++;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; threadData-&gt;face = face;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; threadData-&gt;vlakprimitive =
vlakprimitive;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
BLI_unlock_thread(LOCK_RAYTREE_WRITE);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; // lets assume read lock is relatively less used than write lock</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; BLI_lock_thread(LOCK_RAYTREE_READ);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; threadData-&gt;finishedCount ++;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; BLI_unlock_thread(LOCK_RAYTREE_READ);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; return NULL;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">}</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">/*</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;* create a single raytrace structure with all faces</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;*/</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">static void makeraytree_single(Render *re)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">{</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; ListBase threads;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; ObjectInstanceRen *obi;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; RayObject *raytree;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; RayFace *face = NULL;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; VlakPrimitive *vlakprimitive = NULL;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; int faces = 0, obs = 0, special = 0;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; MakeRayTreeThreadData makeRayTreeThreadData;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; CreateTiming("makeraytree_single new begins...");</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; for(obi=re-&gt;instancetable.first; obi; obi=obi-&gt;next)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(is_raytraceable(re, obi))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int v;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ObjectRen *obr = obi-&gt;obr;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; obs++;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(has_special_rayobject(re, obi))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; special++;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(v=0;v&lt;obr-&gt;totvlak;v++)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; VlakRen *vlr = obr-&gt;vlaknodes[v&gt;&gt;8].vlak +
(v&amp;255);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(is_raytraceable_vlr(re, vlr))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; faces++;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; if(faces + special == 0)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;raytree = RE_rayobject_empty_create();</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; //Create raytree</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; raytree = re-&gt;raytree = RE_rayobject_create( re, re-&gt;r.raytrace_structure, faces+special );</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; if( (re-&gt;r.raytrace_options &amp; R_RAYTRACE_USE_LOCAL_COORDS) )</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; vlakprimitive = re-&gt;rayprimitives =
(VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "Raytrace
vlak-primitives");</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; else</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; face = re-&gt;rayfaces&nbsp;&nbsp;&nbsp; =
(RayFace*)MEM_callocN(faces*sizeof(RayFace), "Render ray faces");</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; // here we start threading...</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; BLI_init_threads(&amp;threads, do_make_raytree_single, re-&gt;r.threads);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; // initialize the global data for threads...</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; makeRayTreeThreadData.re = re;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; makeRayTreeThreadData.obi = re-&gt;instancetable.first;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; makeRayTreeThreadData.face = face;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; makeRayTreeThreadData.vlakprimitive = vlakprimitive;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; makeRayTreeThreadData.finishedCount = 0;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; int i;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; re-&gt;r.threads; i ++)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_insert_thread(&amp;threads, &amp;makeRayTreeThreadData);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; while (makeRayTreeThreadData.finishedCount != R.r.threads)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; PIL_sleep_ms(50);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; BLI_end_threads(&amp;threads);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; if(!test_break(re))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;i.infostr= "Raytree.. building";</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;stats_draw(re-&gt;sdh, &amp;re-&gt;i);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_rayobject_done( raytree );</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; CreateTiming("makeraytree_single new ends...");</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">}</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">#else</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">/*</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;* create a single raytrace structure with all faces</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;*/</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">static void makeraytree_single(Render *re)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">{</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; ObjectInstanceRen *obi;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; RayObject *raytree;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; RayFace *face = NULL;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; VlakPrimitive *vlakprimitive = NULL;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; int faces = 0, obs = 0, special = 0;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; CreateTiming("makeraytree_single old begins...");</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; for(obi=re-&gt;instancetable.first; obi; obi=obi-&gt;next)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(is_raytraceable(re, obi))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int v;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ObjectRen *obr = obi-&gt;obr;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; obs++;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(has_special_rayobject(re, obi))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; special++;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(v=0;v&lt;obr-&gt;totvlak;v++)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; VlakRen *vlr = obr-&gt;vlaknodes[v&gt;&gt;8].vlak +
(v&amp;255);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(is_raytraceable_vlr(re, vlr))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; faces++;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; if(faces + special == 0)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;raytree = RE_rayobject_empty_create();</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; //Create raytree</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; raytree = re-&gt;raytree = RE_rayobject_create( re, re-&gt;r.raytrace_structure, faces+special );</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; if( (re-&gt;r.raytrace_options &amp; R_RAYTRACE_USE_LOCAL_COORDS) )</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; vlakprimitive = re-&gt;rayprimitives =
(VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "Raytrace
vlak-primitives");</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; else</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; face = re-&gt;rayfaces&nbsp;&nbsp;&nbsp; =
(RayFace*)MEM_callocN(faces*sizeof(RayFace), "Render ray faces");</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; for(obi=re-&gt;instancetable.first; obi; obi=obi-&gt;next)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(is_raytraceable(re, obi))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(test_break(re))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(has_special_rayobject(re, obi))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RayObject *obj = makeraytree_object(re, obi);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(test_break(re))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (obj)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; RE_rayobject_add( re-&gt;raytree, obj );</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int v;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ObjectRen *obr = obi-&gt;obr;</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(obi-&gt;flag &amp; R_TRANSFORMED)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; obi-&gt;transform_primitives = 1;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(v=0;v&lt;obr-&gt;totvlak;v++)</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; VlakRen *vlr = obr-&gt;vlaknodes[v&gt;&gt;8].vlak +
(v&amp;255);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(is_raytraceable_vlr(re, vlr))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if( (re-&gt;r.raytrace_options
&amp; R_RAYTRACE_USE_LOCAL_COORDS) )</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RayObject *obj
= RE_vlakprimitive_from_vlak( vlakprimitive, obi, vlr );</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
RE_rayobject_add( raytree, obj );</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
vlakprimitive++;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
RE_rayface_from_vlak(face, obi, vlr);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
if((obi-&gt;flag &amp; R_TRANSFORMED))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; mul_m4_v3(obi-&gt;mat, face-&gt;v1);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; mul_m4_v3(obi-&gt;mat, face-&gt;v2);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; mul_m4_v3(obi-&gt;mat, face-&gt;v3);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(RE_rayface_isQuad(face))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mul_m4_v3(obi-&gt;mat,
face-&gt;v4);</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
RE_rayobject_add( raytree, RE_rayobject_unalignRayFace(face) );</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; face++;</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; if(!test_break(re))</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; {</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;i.infostr= "Raytree.. building";</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;stats_draw(re-&gt;sdh, &amp;re-&gt;i);</span><br style="background-color: rgb(255, 153, 0);">
<br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_rayobject_done( raytree );</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; }</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">&nbsp;&nbsp;&nbsp; CreateTiming("makeraytree_single old ends...");</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">}</span><br style="background-color: rgb(255, 153, 0);">
<span style="background-color: rgb(255, 153, 0);">#endif</span><br>
<br>
void makeraytree(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; float min[3], max[3], sub[3];<br>
&nbsp;&nbsp;&nbsp; int i;<br>
<br>
<br>
&nbsp;&nbsp;&nbsp; re-&gt;i.infostr= "Raytree.. preparing";<br>
&nbsp;&nbsp;&nbsp; re-&gt;stats_draw(re-&gt;sdh, &amp;re-&gt;i);<br>
<br>
&nbsp;&nbsp;&nbsp; /* disable options not yet supported by octree,<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; they might actually never be supported (unless people really need it) */<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;r.raytrace_structure == R_RAYSTRUCTURE_OCTREE)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;r.raytrace_options &amp;=
~( R_RAYTRACE_USE_INSTANCES | R_RAYTRACE_USE_LOCAL_COORDS);<br>
<br>
&nbsp;&nbsp;&nbsp; makeraytree_single(re);<br>
<br>
&nbsp;&nbsp;&nbsp; if(test_break(re))<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; freeraytree(re);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;i.infostr= "Raytree building canceled";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;stats_draw(re-&gt;sdh, &amp;re-&gt;i);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //Calculate raytree max_size<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //This is ONLY needed to kept a bogus behaviour of SUN and HEMI lights<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; INIT_MINMAX(min, max);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_rayobject_merge_bb( re-&gt;raytree, min, max );<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(i=0; i&lt;3; i++)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; min[i] += 0.01f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; max[i] += 0.01f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sub[i] = max[i]-min[i];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;maxdist= sub[0]*sub[0] + sub[1]*sub[1] + sub[2]*sub[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(re-&gt;maxdist &gt; 0.0f) re-&gt;maxdist= sqrt(re-&gt;maxdist);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;i.infostr= "Raytree finished";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;stats_draw(re-&gt;sdh, &amp;re-&gt;i);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
#ifdef RE_RAYCOUNTER<br>
&nbsp;&nbsp;&nbsp; memset( re_rc_counter, 0, sizeof(re_rc_counter) );<br>
#endif<br>
}<br>
<br>
/* &nbsp;&nbsp;&nbsp; if(shi-&gt;osatex)&nbsp; */<br>
static void shade_ray_set_derivative(ShadeInput *shi)<br>
{<br>
&nbsp;&nbsp;&nbsp; float detsh, t00, t10, t01, t11, xn, yn, zn;<br>
&nbsp;&nbsp;&nbsp; int axis1, axis2;<br>
<br>
&nbsp;&nbsp;&nbsp; /* find most stable axis to project */<br>
&nbsp;&nbsp;&nbsp; xn= fabs(shi-&gt;facenor[0]);<br>
&nbsp;&nbsp;&nbsp; yn= fabs(shi-&gt;facenor[1]);<br>
&nbsp;&nbsp;&nbsp; zn= fabs(shi-&gt;facenor[2]);<br>
<br>
&nbsp;&nbsp;&nbsp; if(zn&gt;=xn &amp;&amp; zn&gt;=yn) { axis1= 0; axis2= 1; }<br>
&nbsp;&nbsp;&nbsp; else if(yn&gt;=xn &amp;&amp; yn&gt;=zn) { axis1= 0; axis2= 2; }<br>
&nbsp;&nbsp;&nbsp; else { axis1= 1; axis2= 2; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* compute u,v and derivatives */<br>
&nbsp;&nbsp;&nbsp; if(shi-&gt;obi-&gt;flag &amp; R_TRANSFORMED) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float v1[3], v2[3], v3[3];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mul_v3_m3v3(v1, shi-&gt;obi-&gt;nmat, shi-&gt;v1-&gt;co);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mul_v3_m3v3(v2, shi-&gt;obi-&gt;nmat, shi-&gt;v2-&gt;co);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mul_v3_m3v3(v3, shi-&gt;obi-&gt;nmat, shi-&gt;v3-&gt;co);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* same as below */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; t00= v3[axis1]-v1[axis1]; t01= v3[axis2]-v1[axis2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; t10= v3[axis1]-v2[axis1]; t11= v3[axis2]-v2[axis2];<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float *v1= shi-&gt;v1-&gt;co;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float *v2= shi-&gt;v2-&gt;co;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float *v3= shi-&gt;v3-&gt;co;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* same as above */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; t00= v3[axis1]-v1[axis1]; t01= v3[axis2]-v1[axis2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; t10= v3[axis1]-v2[axis1]; t11= v3[axis2]-v2[axis2];<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; detsh= 1.0f/(t00*t11-t10*t01);<br>
&nbsp;&nbsp;&nbsp; t00*= detsh; t01*=detsh;<br>
&nbsp;&nbsp;&nbsp; t10*=detsh; t11*=detsh;<br>
<br>
&nbsp;&nbsp;&nbsp; shi-&gt;dx_u=&nbsp; shi-&gt;dxco[axis1]*t11- shi-&gt;dxco[axis2]*t10;<br>
&nbsp;&nbsp;&nbsp; shi-&gt;dx_v=&nbsp; shi-&gt;dxco[axis2]*t00- shi-&gt;dxco[axis1]*t01;<br>
&nbsp;&nbsp;&nbsp; shi-&gt;dy_u=&nbsp; shi-&gt;dyco[axis1]*t11- shi-&gt;dyco[axis2]*t10;<br>
&nbsp;&nbsp;&nbsp; shi-&gt;dy_v=&nbsp; shi-&gt;dyco[axis2]*t00- shi-&gt;dyco[axis1]*t01;<br>
<br>
}<br>
<br>
<br>
void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)<br>
{<br>
&nbsp;&nbsp;&nbsp; ObjectInstanceRen *obi= (ObjectInstanceRen*)is-&gt;hit.ob;<br>
&nbsp;&nbsp;&nbsp; VlakRen *vlr= (VlakRen*)is-&gt;hit.face;<br>
<br>
&nbsp;&nbsp;&nbsp; /* set up view vector */<br>
&nbsp;&nbsp;&nbsp; VECCOPY(shi-&gt;view, is-&gt;dir);<br>
<br>
&nbsp;&nbsp;&nbsp; /* render co */<br>
&nbsp;&nbsp;&nbsp; shi-&gt;co[0]= is-&gt;start[0]+is-&gt;dist*(shi-&gt;view[0]);<br>
&nbsp;&nbsp;&nbsp; shi-&gt;co[1]= is-&gt;start[1]+is-&gt;dist*(shi-&gt;view[1]);<br>
&nbsp;&nbsp;&nbsp; shi-&gt;co[2]= is-&gt;start[2]+is-&gt;dist*(shi-&gt;view[2]);<br>
<br>
&nbsp;&nbsp;&nbsp; normalize_v3(shi-&gt;view);<br>
<br>
&nbsp;&nbsp;&nbsp; shi-&gt;obi= obi;<br>
&nbsp;&nbsp;&nbsp; shi-&gt;obr= obi-&gt;obr;<br>
&nbsp;&nbsp;&nbsp; shi-&gt;vlr= vlr;<br>
&nbsp;&nbsp;&nbsp; shi-&gt;mat= vlr-&gt;mat;<br>
&nbsp;&nbsp;&nbsp; shade_input_init_material(shi);<br>
<br>
&nbsp;&nbsp;&nbsp; if(is-&gt;isect==2)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);<br>
<br>
&nbsp;&nbsp;&nbsp; shi-&gt;u= is-&gt;u;<br>
&nbsp;&nbsp;&nbsp; shi-&gt;v= is-&gt;v;<br>
&nbsp;&nbsp;&nbsp; shi-&gt;dx_u= shi-&gt;dx_v= shi-&gt;dy_u= shi-&gt;dy_v=&nbsp; 0.0f;<br>
<br>
&nbsp;&nbsp;&nbsp; if(shi-&gt;osatex)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shade_ray_set_derivative(shi);<br>
&nbsp;&nbsp;&nbsp; shade_input_set_normals(shi);<br>
<br>
&nbsp;&nbsp;&nbsp; shade_input_set_shade_texco(shi);<br>
&nbsp;&nbsp;&nbsp; if (shi-&gt;mat-&gt;material_type == MA_TYPE_VOLUME) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(ELEM(is-&gt;mode, RE_RAY_SHADOW, RE_RAY_SHADOW_TRA)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shade_volume_shadow(shi, shr, is);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shade_volume_outside(shi, shr);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else if(is-&gt;mode==RE_RAY_SHADOW_TRA) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* temp hack to prevent recursion */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(shi-&gt;nodes==0 &amp;&amp;
shi-&gt;mat-&gt;nodetree &amp;&amp; shi-&gt;mat-&gt;use_nodes) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntreeShaderExecTree(shi-&gt;mat-&gt;nodetree, shi, shr);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi-&gt;mat=
vlr-&gt;mat;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* shi-&gt;mat is
being set in nodetree */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shade_color(shi, shr);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(shi-&gt;mat-&gt;nodetree &amp;&amp; shi-&gt;mat-&gt;use_nodes) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntreeShaderExecTree(shi-&gt;mat-&gt;nodetree, shi, shr);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi-&gt;mat=
vlr-&gt;mat;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* shi-&gt;mat is
being set in nodetree */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shade_material_loop(shi, shr);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* raytrace likes to separate the spec color */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECSUB(shr-&gt;diff, shr-&gt;combined, shr-&gt;spec);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
}<br>
<br>
static int refraction(float *refract, float *n, float *view, float index)<br>
{<br>
&nbsp;&nbsp;&nbsp; float dot, fac;<br>
<br>
&nbsp;&nbsp;&nbsp; VECCOPY(refract, view);<br>
<br>
&nbsp;&nbsp;&nbsp; dot= view[0]*n[0] + view[1]*n[1] + view[2]*n[2];<br>
<br>
&nbsp;&nbsp;&nbsp; if(dot&gt;0.0f) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; index = 1.0f/index;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fac= 1.0f - (1.0f - dot*dot)*index*index;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(fac&lt;= 0.0f) return 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fac= -dot*index + sqrt(fac);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fac= 1.0f - (1.0f - dot*dot)*index*index;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(fac&lt;= 0.0f) return 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fac= -dot*index - sqrt(fac);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; refract[0]= index*view[0] + fac*n[0];<br>
&nbsp;&nbsp;&nbsp; refract[1]= index*view[1] + fac*n[1];<br>
&nbsp;&nbsp;&nbsp; refract[2]= index*view[2] + fac*n[2];<br>
<br>
&nbsp;&nbsp;&nbsp; return 1;<br>
}<br>
<br>
/* orn = original face normal */<br>
static void reflection(float *ref, float *n, float *view, float *orn)<br>
{<br>
&nbsp;&nbsp;&nbsp; float f1;<br>
<br>
&nbsp;&nbsp;&nbsp; f1= -2.0f*(n[0]*view[0]+ n[1]*view[1]+ n[2]*view[2]);<br>
<br>
&nbsp;&nbsp;&nbsp; ref[0]= (view[0]+f1*n[0]);<br>
&nbsp;&nbsp;&nbsp; ref[1]= (view[1]+f1*n[1]);<br>
&nbsp;&nbsp;&nbsp; ref[2]= (view[2]+f1*n[2]);<br>
<br>
&nbsp;&nbsp;&nbsp; if(orn) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* test phong normals, then we should prevent vector going to the back */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; f1= ref[0]*orn[0]+ ref[1]*orn[1]+ ref[2]*orn[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(f1&gt;0.0f) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; f1+= .01f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ref[0]-= f1*orn[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ref[1]-= f1*orn[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ref[2]-= f1*orn[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
#if 0<br>
static void color_combine(float *result, float fac1, float fac2, float *col1, float *col2)<br>
{<br>
&nbsp;&nbsp;&nbsp; float col1t[3], col2t[3];<br>
<br>
&nbsp;&nbsp;&nbsp; col1t[0]= sqrt(col1[0]);<br>
&nbsp;&nbsp;&nbsp; col1t[1]= sqrt(col1[1]);<br>
&nbsp;&nbsp;&nbsp; col1t[2]= sqrt(col1[2]);<br>
&nbsp;&nbsp;&nbsp; col2t[0]= sqrt(col2[0]);<br>
&nbsp;&nbsp;&nbsp; col2t[1]= sqrt(col2[1]);<br>
&nbsp;&nbsp;&nbsp; col2t[2]= sqrt(col2[2]);<br>
<br>
&nbsp;&nbsp;&nbsp; result[0]= (fac1*col1t[0] + fac2*col2t[0]);<br>
&nbsp;&nbsp;&nbsp; result[0]*= result[0];<br>
&nbsp;&nbsp;&nbsp; result[1]= (fac1*col1t[1] + fac2*col2t[1]);<br>
&nbsp;&nbsp;&nbsp; result[1]*= result[1];<br>
&nbsp;&nbsp;&nbsp; result[2]= (fac1*col1t[2] + fac2*col2t[2]);<br>
&nbsp;&nbsp;&nbsp; result[2]*= result[2];<br>
}<br>
#endif<br>
<br>
static float shade_by_transmission(Isect *is, ShadeInput *shi, ShadeResult *shr)<br>
{<br>
&nbsp;&nbsp;&nbsp; float dx, dy, dz, d, p;<br>
<br>
&nbsp;&nbsp;&nbsp; if (0 == (shi-&gt;mat-&gt;mode &amp; MA_TRANSP))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return -1;<br>
<br>
&nbsp;&nbsp;&nbsp; if (shi-&gt;mat-&gt;tx_limit &lt;= 0.0f) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; d= 1.0f;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* shi.co[] calculated by shade_ray() */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dx= shi-&gt;co[0] - is-&gt;start[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dy= shi-&gt;co[1] - is-&gt;start[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dz= shi-&gt;co[2] - is-&gt;start[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; d= sqrt(dx*dx+dy*dy+dz*dz);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (d &gt; shi-&gt;mat-&gt;tx_limit)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; d= shi-&gt;mat-&gt;tx_limit;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; p = shi-&gt;mat-&gt;tx_falloff;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(p &lt; 0.0f) p= 0.0f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (p &gt; 10.0f) p= 10.0f;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shr-&gt;alpha *= pow(d, p);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (shr-&gt;alpha &gt; 1.0f)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shr-&gt;alpha= 1.0f;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; return d;<br>
}<br>
<br>
static void ray_fadeout_endcolor(float *col, ShadeInput *origshi, ShadeInput *shi, ShadeResult *shr, Isect *isec, float *vec)<br>
{<br>
&nbsp;&nbsp;&nbsp; /* un-intersected rays get either rendered material color or sky color */<br>
&nbsp;&nbsp;&nbsp; if (origshi-&gt;mat-&gt;fadeto_mir == MA_RAYMIR_FADETOMAT) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(col, shr-&gt;combined);<br>
&nbsp;&nbsp;&nbsp; } else if (origshi-&gt;mat-&gt;fadeto_mir == MA_RAYMIR_FADETOSKY) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(shi-&gt;view, vec);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; normalize_v3(shi-&gt;view);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadeSkyView(col, isec-&gt;start, shi-&gt;view, NULL, shi-&gt;thread);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadeSunView(col, shi-&gt;view);<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
static void ray_fadeout(Isect *is, ShadeInput *shi, float *col, float *blendcol, float dist_mir)<br>
{<br>
&nbsp;&nbsp;&nbsp; /* if fading out, linear blend against fade color */<br>
&nbsp;&nbsp;&nbsp; float blendfac;<br>
<br>
&nbsp;&nbsp;&nbsp; blendfac = 1.0 - len_v3v3(shi-&gt;co, is-&gt;start)/dist_mir;<br>
<br>
&nbsp;&nbsp;&nbsp; col[0] = col[0]*blendfac + (1.0 - blendfac)*blendcol[0];<br>
&nbsp;&nbsp;&nbsp; col[1] = col[1]*blendfac + (1.0 - blendfac)*blendcol[1];<br>
&nbsp;&nbsp;&nbsp; col[2] = col[2]*blendfac + (1.0 - blendfac)*blendcol[2];<br>
}<br>
<br>
/* the main recursive tracer itself<br>
&nbsp;* note: 'col' must be initialized */<br>
static void traceray(ShadeInput *origshi, ShadeResult *origshr, short
depth, float *start, float *dir, float *col, ObjectInstanceRen *obi,
VlakRen *vlr, int traflag)<br>
{<br>
&nbsp;&nbsp;&nbsp; ShadeInput shi= {0};<br>
&nbsp;&nbsp;&nbsp; Isect isec;<br>
&nbsp;&nbsp;&nbsp; float dist_mir = origshi-&gt;mat-&gt;dist_mir;<br>
<br>
&nbsp;&nbsp;&nbsp; VECCOPY(isec.start, start);<br>
&nbsp;&nbsp;&nbsp; VECCOPY(isec.dir, dir );<br>
&nbsp;&nbsp;&nbsp; isec.dist = dist_mir &gt; 0 ? dist_mir : RE_RAYTRACE_MAXDIST;<br>
&nbsp;&nbsp;&nbsp; isec.mode= RE_RAY_MIRROR;<br>
&nbsp;&nbsp;&nbsp; isec.check = RE_CHECK_VLR_RENDER;<br>
&nbsp;&nbsp;&nbsp; isec.skip = RE_SKIP_VLR_NEIGHBOUR;<br>
&nbsp;&nbsp;&nbsp; isec.hint = 0;<br>
<br>
&nbsp;&nbsp;&nbsp; isec.orig.ob&nbsp;&nbsp; = obi;<br>
&nbsp;&nbsp;&nbsp; isec.orig.face = vlr;<br>
&nbsp;&nbsp;&nbsp; RE_RC_INIT(isec, shi);<br>
<br>
&nbsp;&nbsp;&nbsp; if(RE_rayobject_raycast(R.raytree, &amp;isec)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ShadeResult shr= {{0}};<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float d= 1.0f;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* for as long we don't have proper dx/dy transform for rays we copy over original */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(shi.dxco, origshi-&gt;dxco);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(shi.dyco, origshi-&gt;dyco);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.mask= origshi-&gt;mask;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.osatex= origshi-&gt;osatex;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.depth= origshi-&gt;depth +
1;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* only used to indicate tracing
*/<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.thread= origshi-&gt;thread;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //shi.sample= 0; // memset above, so dont need this<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.xs= origshi-&gt;xs;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.ys= origshi-&gt;ys;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.lay= origshi-&gt;lay;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.passflag= SCE_PASS_COMBINED; /* result of tracing needs no pass info */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.combinedflag=
0xFFFFFF;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;/* ray trace does
all options */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //shi.do_preview= 0; // memset above, so dont need this<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.light_override= origshi-&gt;light_override;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.mat_override= origshi-&gt;mat_override;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shade_ray(&amp;isec, &amp;shi, &amp;shr);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* ray has traveled inside the material, so shade by transmission */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (traflag &amp; RAY_INSIDE)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; d= shade_by_transmission(&amp;isec, &amp;shi, &amp;shr);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(depth&gt;0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float fr, fg, fb, f, f1;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
if((shi.mat-&gt;mode_l &amp; MA_TRANSP) &amp;&amp; shr.alpha &lt; 1.0f
&amp;&amp; (shi.mat-&gt;mode_l &amp; (MA_ZTRANSP | MA_RAYTRANSP))) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float nf, f, refract[3], tracol[4];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tracol[0]= shi.r;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tracol[1]= shi.g;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tracol[2]= shi.b;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; tracol[3]= col[3];&nbsp;&nbsp;&nbsp; // we pass on
and accumulate alpha<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if((shi.mat-&gt;mode &amp; MA_TRANSP) &amp;&amp;
(shi.mat-&gt;mode &amp; MA_RAYTRANSP)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(traflag &amp; RAY_INSIDE) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* inside the
material, so use inverse normal */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float norm[3];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; norm[0]= -
shi.vn[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; norm[1]= -
shi.vn[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; norm[2]= -
shi.vn[2];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if
(refraction(refract, norm, shi.view, shi.ang)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; /* ray comes out from the material into air */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; traflag &amp;= ~RAY_INSIDE;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; /* total internal reflection (ray stays inside the
material) */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; reflection(refract, norm, shi.view, shi.vn);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if
(refraction(refract, shi.vn, shi.view, shi.ang)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; /* ray goes in to the material from air */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; traflag |= RAY_INSIDE;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; /* total external reflection (ray doesn't enter the
material) */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; reflection(refract, shi.vn, shi.view, shi.vn);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; traceray(origshi, origshr,
depth-1, shi.co, refract, tracol, shi.obi, shi.vlr, traflag);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; traceray(origshi, origshr,
depth-1, shi.co, shi.view, tracol, shi.obi, shi.vlr, 0);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; f= shr.alpha; f1= 1.0f-f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; nf= d * shi.mat-&gt;filter;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fr= 1.0f+ nf*(shi.r-1.0f);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fg= 1.0f+ nf*(shi.g-1.0f);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fb= 1.0f+ nf*(shi.b-1.0f);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shr.diff[0]= f*shr.diff[0] + f1*fr*tracol[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shr.diff[1]= f*shr.diff[1] + f1*fg*tracol[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shr.diff[2]= f*shr.diff[2] + f1*fb*tracol[2];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shr.spec[0] *=f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shr.spec[1] *=f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shr.spec[2] *=f;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; col[3]= f1*tracol[3] + f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; col[3]= 1.0f;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(shi.mat-&gt;mode_l &amp; MA_RAYMIRROR) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; f= shi.ray_mirror;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(f!=0.0f) f*= fresnel_fac(shi.view, shi.vn,
shi.mat-&gt;fresnel_mir_i, shi.mat-&gt;fresnel_mir);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else f= 0.0f;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(f!=0.0f) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float mircol[4];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float ref[3];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; reflection(ref, shi.vn, shi.view, NULL);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; traceray(origshi, origshr, depth-1, shi.co, ref,
mircol, shi.obi, shi.vlr, 0);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; f1= 1.0f-f;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* combine */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; //color_combine(col, f*fr*(1.0f-shr.spec[0]), f1,
col, shr.diff);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //col[0]+= shr.spec[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //col[1]+= shr.spec[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //col[2]+= shr.spec[2];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fr= shi.mirr;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fg= shi.mirg;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fb= shi.mirb;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; col[0]= f*fr*(1.0f-shr.spec[0])*mircol[0] +
f1*shr.diff[0] + shr.spec[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; col[1]= f*fg*(1.0f-shr.spec[1])*mircol[1] +
f1*shr.diff[1] + shr.spec[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; col[2]= f*fb*(1.0f-shr.spec[2])*mircol[2] +
f1*shr.diff[2] + shr.spec[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; col[0]= shr.diff[0] + shr.spec[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; col[1]= shr.diff[1] + shr.spec[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; col[2]= shr.diff[2] + shr.spec[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (dist_mir &gt; 0.0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float blendcol[3];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; /* max ray distance set, but found an intersection,
so fade this color<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;* out towards the sky/material color for a
smooth transition */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; ray_fadeout_endcolor(blendcol, origshi, &amp;shi,
origshr, &amp;isec, dir);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; ray_fadeout(&amp;isec, &amp;shi, col, blendcol,
dist_mir);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; col[0]= shr.diff[0] + shr.spec[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; col[1]= shr.diff[1] + shr.spec[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; col[2]= shr.diff[2] + shr.spec[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ray_fadeout_endcolor(col, origshi, &amp;shi, origshr, &amp;isec, dir);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; RE_RC_MERGE(&amp;origshi-&gt;raycounter, &amp;shi.raycounter);<br>
}<br>
<br>
/* **************** jitter blocks ********** */<br>
<br>
/* calc distributed planar energy */<br>
<br>
static void DP_energy(float *table, float *vec, int tot, float xsize, float ysize)<br>
{<br>
&nbsp;&nbsp;&nbsp; int x, y, a;<br>
&nbsp;&nbsp;&nbsp; float *fp, force[3], result[3];<br>
&nbsp;&nbsp;&nbsp; float dx, dy, dist, min;<br>
<br>
&nbsp;&nbsp;&nbsp; min= MIN2(xsize, ysize);<br>
&nbsp;&nbsp;&nbsp; min*= min;<br>
&nbsp;&nbsp;&nbsp; result[0]= result[1]= 0.0f;<br>
<br>
&nbsp;&nbsp;&nbsp; for(y= -1; y&lt;2; y++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dy= ysize*y;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(x= -1; x&lt;2; x++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dx= xsize*x;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fp= table;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(a=0; a&lt;tot; a++, fp+= 2) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; force[0]= vec[0] - fp[0]-dx;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; force[1]= vec[1] - fp[1]-dy;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dist= force[0]*force[0] + force[1]*force[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(dist &lt; min &amp;&amp; dist&gt;0.0f) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; result[0]+= force[0]/dist;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; result[1]+= force[1]/dist;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; vec[0] += 0.1*min*result[0]/(float)tot;<br>
&nbsp;&nbsp;&nbsp; vec[1] += 0.1*min*result[1]/(float)tot;<br>
&nbsp;&nbsp;&nbsp; // cyclic clamping<br>
&nbsp;&nbsp;&nbsp; vec[0]= vec[0] - xsize*floor(vec[0]/xsize + 0.5);<br>
&nbsp;&nbsp;&nbsp; vec[1]= vec[1] - ysize*floor(vec[1]/ysize + 0.5);<br>
}<br>
<br>
// random offset of 1 in 2<br>
static void jitter_plane_offset(float *jitter1, float *jitter2, int tot, float sizex, float sizey, float ofsx, float ofsy)<br>
{<br>
&nbsp;&nbsp;&nbsp; float dsizex= sizex*ofsx;<br>
&nbsp;&nbsp;&nbsp; float dsizey= sizey*ofsy;<br>
&nbsp;&nbsp;&nbsp; float hsizex= 0.5*sizex, hsizey= 0.5*sizey;<br>
&nbsp;&nbsp;&nbsp; int x;<br>
<br>
&nbsp;&nbsp;&nbsp; for(x=tot; x&gt;0; x--, jitter1+=2, jitter2+=2) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; jitter2[0]= jitter1[0] + dsizex;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; jitter2[1]= jitter1[1] + dsizey;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(jitter2[0] &gt; hsizex) jitter2[0]-= sizex;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(jitter2[1] &gt; hsizey) jitter2[1]-= sizey;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
/* called from convertBlenderScene.c */<br>
/* we do this in advance to get consistent random, not alter the render seed, and be threadsafe */<br>
void init_jitter_plane(LampRen *lar)<br>
{<br>
&nbsp;&nbsp;&nbsp; float *fp;<br>
&nbsp;&nbsp;&nbsp; int x, iter=12, tot= lar-&gt;ray_totsamp;<br>
<br>
&nbsp;&nbsp;&nbsp; /* test if already initialized */<br>
&nbsp;&nbsp;&nbsp; if(lar-&gt;jitter) return;<br>
<br>
&nbsp;&nbsp;&nbsp; /* at least 4, or max threads+1 tables */<br>
&nbsp;&nbsp;&nbsp; if(BLENDER_MAX_THREADS &lt; 4) x= 4;<br>
&nbsp;&nbsp;&nbsp; else x= BLENDER_MAX_THREADS+1;<br>
&nbsp;&nbsp;&nbsp; fp= lar-&gt;jitter= MEM_callocN(x*tot*2*sizeof(float), "lamp jitter tab");<br>
<br>
&nbsp;&nbsp;&nbsp; /* if 1 sample, we leave table to be zero's */<br>
&nbsp;&nbsp;&nbsp; if(tot&gt;1) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* set per-lamp fixed seed */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BLI_srandom(tot);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* fill table with random locations, area_size large */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(x=0; x&lt;tot; x++, fp+=2) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fp[0]= (BLI_frand()-0.5)*lar-&gt;area_size;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fp[1]= (BLI_frand()-0.5)*lar-&gt;area_sizey;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while(iter--) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fp= lar-&gt;jitter;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(x=tot; x&gt;0; x--, fp+=2) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; DP_energy(lar-&gt;jitter, fp, tot,
lar-&gt;area_size, lar-&gt;area_sizey);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; /* create the dithered tables (could just check lamp type!) */<br>
&nbsp;&nbsp;&nbsp; jitter_plane_offset(lar-&gt;jitter,
lar-&gt;jitter+2*tot, tot, lar-&gt;area_size, lar-&gt;area_sizey, 0.5f,
0.0f);<br>
&nbsp;&nbsp;&nbsp; jitter_plane_offset(lar-&gt;jitter,
lar-&gt;jitter+4*tot, tot, lar-&gt;area_size, lar-&gt;area_sizey, 0.5f,
0.5f);<br>
&nbsp;&nbsp;&nbsp; jitter_plane_offset(lar-&gt;jitter,
lar-&gt;jitter+6*tot, tot, lar-&gt;area_size, lar-&gt;area_sizey, 0.0f,
0.5f);<br>
}<br>
<br>
/* table around origin, -0.5*size to 0.5*size */<br>
static float *give_jitter_plane(LampRen *lar, int thread, int xs, int ys)<br>
{<br>
&nbsp;&nbsp;&nbsp; int tot;<br>
<br>
&nbsp;&nbsp;&nbsp; tot= lar-&gt;ray_totsamp;<br>
<br>
&nbsp;&nbsp;&nbsp; if(lar-&gt;ray_samp_type &amp; LA_SAMP_JITTER) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* made it threadsafe */<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(lar-&gt;xold[thread]!=xs || lar-&gt;yold[thread]!=ys) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
jitter_plane_offset(lar-&gt;jitter, lar-&gt;jitter+2*(thread+1)*tot,
tot, lar-&gt;area_size, lar-&gt;area_sizey, BLI_thread_frand(thread),
BLI_thread_frand(thread));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lar-&gt;xold[thread]= xs;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lar-&gt;yold[thread]= ys;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return lar-&gt;jitter+2*(thread+1)*tot;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if(lar-&gt;ray_samp_type &amp; LA_SAMP_DITHER) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return lar-&gt;jitter + 2*tot*((xs &amp; 1)+2*(ys &amp; 1));<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; return lar-&gt;jitter;<br>
}<br>
<br>
<br>
/* **************** QMC sampling *************** */<br>
<br>
static void halton_sample(double *ht_invprimes, double *ht_nums, double *v)<br>
{<br>
&nbsp;&nbsp;&nbsp; // incremental halton sequence generator, from:<br>
&nbsp;&nbsp;&nbsp; // "Instant Radiosity", Keller A.<br>
&nbsp;&nbsp;&nbsp; unsigned int i;<br>
<br>
&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; 2; i++)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; double r = fabs((1.0 - ht_nums[i]) - 1e-10);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (ht_invprimes[i] &gt;= r)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; double lasth;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; double h = ht_invprimes[i];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lasth = h;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; h *= ht_invprimes[i];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } while (h &gt;= r);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ht_nums[i] += ((lasth + h) - 1.0);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ht_nums[i] += ht_invprimes[i];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; v[i] = (float)ht_nums[i];<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
/* Generate Hammersley points in [0,1)^2<br>
&nbsp;* From Lucille renderer */<br>
static void hammersley_create(double *out, int n)<br>
{<br>
&nbsp;&nbsp;&nbsp; double p, t;<br>
&nbsp;&nbsp;&nbsp; int k, kk;<br>
<br>
&nbsp;&nbsp;&nbsp; for (k = 0; k &lt; n; k++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; t = 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for (p = 0.5, kk = k; kk; p *= 0.5, kk &gt;&gt;= 1) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (kk &amp;
1) {&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* kk mod 2 =
1&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; t += p;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; out[2 * k + 0] = (double)k / (double)n;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; out[2 * k + 1] = t;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
static struct QMCSampler *QMC_initSampler(int type, int tot)<br>
{<br>
&nbsp;&nbsp;&nbsp; QMCSampler *qsa = MEM_callocN(sizeof(QMCSampler), "qmc sampler");<br>
&nbsp;&nbsp;&nbsp; qsa-&gt;samp2d = MEM_callocN(2*sizeof(double)*tot, "qmc sample table");<br>
<br>
&nbsp;&nbsp;&nbsp; qsa-&gt;tot = tot;<br>
&nbsp;&nbsp;&nbsp; qsa-&gt;type = type;<br>
<br>
&nbsp;&nbsp;&nbsp; if (qsa-&gt;type==SAMP_TYPE_HAMMERSLEY)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hammersley_create(qsa-&gt;samp2d, qsa-&gt;tot);<br>
<br>
&nbsp;&nbsp;&nbsp; return qsa;<br>
}<br>
<br>
static void QMC_initPixel(QMCSampler *qsa, int thread)<br>
{<br>
&nbsp;&nbsp;&nbsp; if (qsa-&gt;type==SAMP_TYPE_HAMMERSLEY)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* hammersley sequence is fixed, already created in QMCSampler init.<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* per pixel, gets a random
offset. We create separate offsets per thread, for write-safety */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; qsa-&gt;offs[thread][0] = 0.5 * BLI_thread_frand(thread);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; qsa-&gt;offs[thread][1] = 0.5 * BLI_thread_frand(thread);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else { &nbsp;&nbsp;&nbsp; /* SAMP_TYPE_HALTON */<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* generate a new randomised halton sequence per pixel<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* to alleviate qmc artifacts and make it reproducable<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* between threads/frames */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; double ht_invprimes[2], ht_nums[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; double r[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int i;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ht_nums[0] = BLI_thread_frand(thread);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ht_nums[1] = BLI_thread_frand(thread);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ht_invprimes[0] = 0.5;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ht_invprimes[1] = 1.0/3.0;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for (i=0; i&lt; qsa-&gt;tot; i++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; halton_sample(ht_invprimes, ht_nums, r);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; qsa-&gt;samp2d[2*i+0] = r[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; qsa-&gt;samp2d[2*i+1] = r[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
static void QMC_freeSampler(QMCSampler *qsa)<br>
{<br>
&nbsp;&nbsp;&nbsp; MEM_freeN(qsa-&gt;samp2d);<br>
&nbsp;&nbsp;&nbsp; MEM_freeN(qsa);<br>
}<br>
<br>
static void QMC_getSample(double *s, QMCSampler *qsa, int thread, int num)<br>
{<br>
&nbsp;&nbsp;&nbsp; if (qsa-&gt;type == SAMP_TYPE_HAMMERSLEY) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; s[0] = fmod(qsa-&gt;samp2d[2*num+0] + qsa-&gt;offs[thread][0], 1.0f);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; s[1] = fmod(qsa-&gt;samp2d[2*num+1] + qsa-&gt;offs[thread][1], 1.0f);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else { /* SAMP_TYPE_HALTON */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; s[0] = qsa-&gt;samp2d[2*num+0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; s[1] = qsa-&gt;samp2d[2*num+1];<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
/* phong weighted disc using 'blur' for exponent, centred on 0,0 */<br>
static void QMC_samplePhong(float *vec, QMCSampler *qsa, int thread, int num, float blur)<br>
{<br>
&nbsp;&nbsp;&nbsp; double s[2];<br>
&nbsp;&nbsp;&nbsp; float phi, pz, sqr;<br>
<br>
&nbsp;&nbsp;&nbsp; QMC_getSample(s, qsa, thread, num);<br>
<br>
&nbsp;&nbsp;&nbsp; phi = s[0]*2*M_PI;<br>
&nbsp;&nbsp;&nbsp; pz = pow(s[1], blur);<br>
&nbsp;&nbsp;&nbsp; sqr = sqrt(1.0f-pz*pz);<br>
<br>
&nbsp;&nbsp;&nbsp; vec[0] = cos(phi)*sqr;<br>
&nbsp;&nbsp;&nbsp; vec[1] = sin(phi)*sqr;<br>
&nbsp;&nbsp;&nbsp; vec[2] = 0.0f;<br>
}<br>
<br>
/* rect of edge lengths sizex, sizey, centred on 0.0,0.0 i.e. ranging from -sizex/2 to +sizey/2 */<br>
static void QMC_sampleRect(float *vec, QMCSampler *qsa, int thread, int num, float sizex, float sizey)<br>
{<br>
&nbsp;&nbsp;&nbsp; double s[2];<br>
<br>
&nbsp;&nbsp;&nbsp; QMC_getSample(s, qsa, thread, num);<br>
<br>
&nbsp;&nbsp;&nbsp; vec[0] = (s[0] - 0.5) * sizex;<br>
&nbsp;&nbsp;&nbsp; vec[1] = (s[1] - 0.5) * sizey;<br>
&nbsp;&nbsp;&nbsp; vec[2] = 0.0f;<br>
}<br>
<br>
/* disc of radius 'radius', centred on 0,0 */<br>
static void QMC_sampleDisc(float *vec, QMCSampler *qsa, int thread, int num, float radius)<br>
{<br>
&nbsp;&nbsp;&nbsp; double s[2];<br>
&nbsp;&nbsp;&nbsp; float phi, sqr;<br>
<br>
&nbsp;&nbsp;&nbsp; QMC_getSample(s, qsa, thread, num);<br>
<br>
&nbsp;&nbsp;&nbsp; phi = s[0]*2*M_PI;<br>
&nbsp;&nbsp;&nbsp; sqr = sqrt(s[1]);<br>
<br>
&nbsp;&nbsp;&nbsp; vec[0] = cos(phi)*sqr* radius/2.0;<br>
&nbsp;&nbsp;&nbsp; vec[1] = sin(phi)*sqr* radius/2.0;<br>
&nbsp;&nbsp;&nbsp; vec[2] = 0.0f;<br>
}<br>
<br>
/* uniform hemisphere sampling */<br>
static void QMC_sampleHemi(float *vec, QMCSampler *qsa, int thread, int num)<br>
{<br>
&nbsp;&nbsp;&nbsp; double s[2];<br>
&nbsp;&nbsp;&nbsp; float phi, sqr;<br>
<br>
&nbsp;&nbsp;&nbsp; QMC_getSample(s, qsa, thread, num);<br>
<br>
&nbsp;&nbsp;&nbsp; phi = s[0]*2.f*M_PI;<br>
&nbsp;&nbsp;&nbsp; sqr = sqrt(s[1]);<br>
<br>
&nbsp;&nbsp;&nbsp; vec[0] = cos(phi)*sqr;<br>
&nbsp;&nbsp;&nbsp; vec[1] = sin(phi)*sqr;<br>
&nbsp;&nbsp;&nbsp; vec[2] = 1.f - s[1]*s[1];<br>
}<br>
<br>
#if 0 /* currently not used */<br>
/* cosine weighted hemisphere sampling */<br>
static void QMC_sampleHemiCosine(float *vec, QMCSampler *qsa, int thread, int num)<br>
{<br>
&nbsp;&nbsp;&nbsp; double s[2];<br>
&nbsp;&nbsp;&nbsp; float phi, sqr;<br>
<br>
&nbsp;&nbsp;&nbsp; QMC_getSample(s, qsa, thread, num);<br>
<br>
&nbsp;&nbsp;&nbsp; phi = s[0]*2.f*M_PI;<br>
&nbsp;&nbsp;&nbsp; sqr = s[1]*sqrt(2-s[1]*s[1]);<br>
<br>
&nbsp;&nbsp;&nbsp; vec[0] = cos(phi)*sqr;<br>
&nbsp;&nbsp;&nbsp; vec[1] = sin(phi)*sqr;<br>
&nbsp;&nbsp;&nbsp; vec[2] = 1.f - s[1]*s[1];<br>
<br>
}<br>
#endif<br>
<br>
/* called from convertBlenderScene.c */<br>
void init_render_qmcsampler(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; re-&gt;qmcsamplers= MEM_callocN(sizeof(ListBase)*BLENDER_MAX_THREADS, "QMCListBase");<br>
}<br>
<br>
static QMCSampler *get_thread_qmcsampler(Render *re, int thread, int type, int tot)<br>
{<br>
&nbsp;&nbsp;&nbsp; QMCSampler *qsa;<br>
<br>
&nbsp;&nbsp;&nbsp; /* create qmc samplers as needed, since recursion makes it hard to<br>
&nbsp;&nbsp;&nbsp; &nbsp;* predict how many are needed */<br>
<br>
&nbsp;&nbsp;&nbsp; for(qsa=re-&gt;qmcsamplers[thread].first; qsa; qsa=qsa-&gt;next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(qsa-&gt;type == type &amp;&amp; qsa-&gt;tot == tot &amp;&amp; !qsa-&gt;used) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; qsa-&gt;used= 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return qsa;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; qsa= QMC_initSampler(type, tot);<br>
&nbsp;&nbsp;&nbsp; qsa-&gt;used= 1;<br>
&nbsp;&nbsp;&nbsp; BLI_addtail(&amp;re-&gt;qmcsamplers[thread], qsa);<br>
<br>
&nbsp;&nbsp;&nbsp; return qsa;<br>
}<br>
<br>
static void release_thread_qmcsampler(Render *re, int thread, QMCSampler *qsa)<br>
{<br>
&nbsp;&nbsp;&nbsp; qsa-&gt;used= 0;<br>
}<br>
<br>
void free_render_qmcsampler(Render *re)<br>
{<br>
&nbsp;&nbsp;&nbsp; QMCSampler *qsa, *next;<br>
&nbsp;&nbsp;&nbsp; int a;<br>
<br>
&nbsp;&nbsp;&nbsp; if(re-&gt;qmcsamplers) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(a=0; a&lt;BLENDER_MAX_THREADS; a++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(qsa=re-&gt;qmcsamplers[a].first; qsa; qsa=next) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; next= qsa-&gt;next;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; QMC_freeSampler(qsa);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;qmcsamplers[a].first= re-&gt;qmcsamplers[a].last= NULL;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MEM_freeN(re-&gt;qmcsamplers);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; re-&gt;qmcsamplers= NULL;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
static int adaptive_sample_variance(int samples, float *col, float *colsq, float thresh)<br>
{<br>
&nbsp;&nbsp;&nbsp; float var[3], mean[3];<br>
<br>
&nbsp;&nbsp;&nbsp; /* scale threshold just to give a bit more precision in input rather than dealing with<br>
&nbsp;&nbsp;&nbsp; &nbsp;* tiny tiny numbers in the UI */<br>
&nbsp;&nbsp;&nbsp; thresh /= 2;<br>
<br>
&nbsp;&nbsp;&nbsp; mean[0] = col[0] / (float)samples;<br>
&nbsp;&nbsp;&nbsp; mean[1] = col[1] / (float)samples;<br>
&nbsp;&nbsp;&nbsp; mean[2] = col[2] / (float)samples;<br>
<br>
&nbsp;&nbsp;&nbsp; var[0] = (colsq[0] / (float)samples) - (mean[0]*mean[0]);<br>
&nbsp;&nbsp;&nbsp; var[1] = (colsq[1] / (float)samples) - (mean[1]*mean[1]);<br>
&nbsp;&nbsp;&nbsp; var[2] = (colsq[2] / (float)samples) - (mean[2]*mean[2]);<br>
<br>
&nbsp;&nbsp;&nbsp; if ((var[0] * 0.4 &lt; thresh) &amp;&amp; (var[1] * 0.3 &lt; thresh) &amp;&amp; (var[2] * 0.6 &lt; thresh))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static int adaptive_sample_contrast_val(int samples, float prev, float val, float thresh)<br>
{<br>
&nbsp;&nbsp;&nbsp; /* if the last sample's contribution to the total value was below a small threshold<br>
&nbsp;&nbsp;&nbsp; &nbsp;* (i.e. the samples taken are very similar), then taking more samples that are probably<br>
&nbsp;&nbsp;&nbsp; &nbsp;* going to be the same is wasting effort */<br>
&nbsp;&nbsp;&nbsp; if (fabs( prev/(float)(samples-1) - val/(float)samples ) &lt; thresh) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; } else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
static float get_avg_speed(ShadeInput *shi)<br>
{<br>
&nbsp;&nbsp;&nbsp; float pre_x, pre_y, post_x, post_y, speedavg;<br>
<br>
&nbsp;&nbsp;&nbsp; pre_x = (shi-&gt;winspeed[0] == PASS_VECTOR_MAX)?0.0:shi-&gt;winspeed[0];<br>
&nbsp;&nbsp;&nbsp; pre_y = (shi-&gt;winspeed[1] == PASS_VECTOR_MAX)?0.0:shi-&gt;winspeed[1];<br>
&nbsp;&nbsp;&nbsp; post_x = (shi-&gt;winspeed[2] == PASS_VECTOR_MAX)?0.0:shi-&gt;winspeed[2];<br>
&nbsp;&nbsp;&nbsp; post_y = (shi-&gt;winspeed[3] == PASS_VECTOR_MAX)?0.0:shi-&gt;winspeed[3];<br>
<br>
&nbsp;&nbsp;&nbsp; speedavg = (sqrt(pre_x*pre_x + pre_y*pre_y) + sqrt(post_x*post_x + post_y*post_y)) / 2.0;<br>
<br>
&nbsp;&nbsp;&nbsp; return speedavg;<br>
}<br>
<br>
/* ***************** main calls ************** */<br>
<br>
<br>
static void trace_refract(float *col, ShadeInput *shi, ShadeResult *shr)<br>
{<br>
&nbsp;&nbsp;&nbsp; QMCSampler *qsa=NULL;<br>
&nbsp;&nbsp;&nbsp; int samp_type;<br>
&nbsp;&nbsp;&nbsp; int traflag=0;<br>
<br>
&nbsp;&nbsp;&nbsp; float samp3d[3], orthx[3], orthy[3];<br>
&nbsp;&nbsp;&nbsp; float v_refract[3], v_refract_new[3];<br>
&nbsp;&nbsp;&nbsp; float sampcol[4], colsq[4];<br>
<br>
&nbsp;&nbsp;&nbsp; float blur = pow(1.0 - shi-&gt;mat-&gt;gloss_tra, 3);<br>
&nbsp;&nbsp;&nbsp; short max_samples = shi-&gt;mat-&gt;samp_gloss_tra;<br>
&nbsp;&nbsp;&nbsp; float adapt_thresh = shi-&gt;mat-&gt;adapt_thresh_tra;<br>
<br>
&nbsp;&nbsp;&nbsp; int samples=0;<br>
<br>
&nbsp;&nbsp;&nbsp; colsq[0] = colsq[1] = colsq[2] = 0.0;<br>
&nbsp;&nbsp;&nbsp; col[0] = col[1] = col[2] = 0.0;<br>
&nbsp;&nbsp;&nbsp; col[3]= shr-&gt;alpha;<br>
<br>
&nbsp;&nbsp;&nbsp; if (blur &gt; 0.0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (adapt_thresh != 0.0) samp_type = SAMP_TYPE_HALTON;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else samp_type = SAMP_TYPE_HAMMERSLEY;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* all samples are generated per pixel */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; qsa = get_thread_qmcsampler(&amp;R, shi-&gt;thread, samp_type, max_samples);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; QMC_initPixel(qsa, shi-&gt;thread);<br>
&nbsp;&nbsp;&nbsp; } else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; max_samples = 1;<br>
<br>
<br>
&nbsp;&nbsp;&nbsp; while (samples &lt; max_samples) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(refraction(v_refract, shi-&gt;vn, shi-&gt;view, shi-&gt;ang)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; traflag |= RAY_INSIDE;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* total
external reflection can happen for materials with IOR &lt; 1.0 */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if((shi-&gt;vlr-&gt;flag &amp; R_SMOOTH))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; reflection(v_refract, shi-&gt;vn, shi-&gt;view,
shi-&gt;facenor);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; reflection(v_refract, shi-&gt;vn, shi-&gt;view,
NULL);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* can't blur total external reflection */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; max_samples = 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (max_samples &gt; 1) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* get a quasi-random vector from a phong-weighted disc */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; QMC_samplePhong(samp3d, qsa, shi-&gt;thread, samples, blur);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ortho_basis_v3v3_v3( orthx, orthy,v_refract);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mul_v3_fl(orthx, samp3d[0]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mul_v3_fl(orthy, samp3d[1]);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* and perturb the refraction vector in it */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; add_v3_v3v3(v_refract_new, v_refract, orthx);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; add_v3_v3(v_refract_new, orthy);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; normalize_v3(v_refract_new);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* no blurriness, use the original normal */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(v_refract_new, v_refract);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sampcol[0]= sampcol[1]= sampcol[2]= sampcol[3]= 0.0f;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //CreateTiming("Raytracing begins...");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; traceray(shi, shr,
shi-&gt;mat-&gt;ray_depth_tra, shi-&gt;co, v_refract_new, sampcol,
shi-&gt;obi, shi-&gt;vlr, traflag);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //CreateTiming("Raytracing ends...");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; col[0] += sampcol[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; col[1] += sampcol[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; col[2] += sampcol[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; col[3] += sampcol[3];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* for variance calc */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; colsq[0] += sampcol[0]*sampcol[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; colsq[1] += sampcol[1]*sampcol[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; colsq[2] += sampcol[2]*sampcol[2];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; samples++;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* adaptive sampling */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (adapt_thresh &lt; 1.0 &amp;&amp; samples &gt; max_samples/2)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (adaptive_sample_variance(samples, col, colsq, adapt_thresh))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* if the
pixel so far is very dark, we can get away with less samples */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if ( (col[0] + col[1] + col[2])/3.0/(float)samples &lt; 0.01 )<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; max_samples--;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; col[0] /= (float)samples;<br>
&nbsp;&nbsp;&nbsp; col[1] /= (float)samples;<br>
&nbsp;&nbsp;&nbsp; col[2] /= (float)samples;<br>
&nbsp;&nbsp;&nbsp; col[3] /= (float)samples;<br>
<br>
&nbsp;&nbsp;&nbsp; if (qsa)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; release_thread_qmcsampler(&amp;R, shi-&gt;thread, qsa);<br>
}<br>
<br>
static void trace_reflect(float *col, ShadeInput *shi, ShadeResult *shr, float fresnelfac)<br>
{<br>
&nbsp;&nbsp;&nbsp; QMCSampler *qsa=NULL;<br>
&nbsp;&nbsp;&nbsp; int samp_type;<br>
<br>
&nbsp;&nbsp;&nbsp; float samp3d[3], orthx[3], orthy[3];<br>
&nbsp;&nbsp;&nbsp; float v_nor_new[3], v_reflect[3];<br>
&nbsp;&nbsp;&nbsp; float sampcol[4], colsq[4];<br>
<br>
&nbsp;&nbsp;&nbsp; float blur = pow(1.0 - shi-&gt;mat-&gt;gloss_mir, 3);<br>
&nbsp;&nbsp;&nbsp; short max_samples = shi-&gt;mat-&gt;samp_gloss_mir;<br>
&nbsp;&nbsp;&nbsp; float adapt_thresh = shi-&gt;mat-&gt;adapt_thresh_mir;<br>
&nbsp;&nbsp;&nbsp; float aniso = 1.0 - shi-&gt;mat-&gt;aniso_gloss_mir;<br>
<br>
&nbsp;&nbsp;&nbsp; int samples=0;<br>
<br>
&nbsp;&nbsp;&nbsp; col[0] = col[1] = col[2] = 0.0;<br>
&nbsp;&nbsp;&nbsp; colsq[0] = colsq[1] = colsq[2] = 0.0;<br>
<br>
&nbsp;&nbsp;&nbsp; if (blur &gt; 0.0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (adapt_thresh != 0.0) samp_type = SAMP_TYPE_HALTON;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else samp_type = SAMP_TYPE_HAMMERSLEY;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* all samples are generated per pixel */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; qsa = get_thread_qmcsampler(&amp;R, shi-&gt;thread, samp_type, max_samples);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; QMC_initPixel(qsa, shi-&gt;thread);<br>
&nbsp;&nbsp;&nbsp; } else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; max_samples = 1;<br>
<br>
&nbsp;&nbsp;&nbsp; while (samples &lt; max_samples) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (max_samples &gt; 1) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* get a quasi-random vector from a phong-weighted disc */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; QMC_samplePhong(samp3d, qsa, shi-&gt;thread, samples, blur);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* find the normal's perpendicular plane, blurring along tangents<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* if tangent shading enabled */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (shi-&gt;mat-&gt;mode &amp; (MA_TANGENT_V)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; cross_v3_v3v3(orthx, shi-&gt;vn,
shi-&gt;tang);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // bitangent<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(orthy, shi-&gt;tang);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mul_v3_fl(orthx, samp3d[0]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mul_v3_fl(orthy, samp3d[1]*aniso);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ortho_basis_v3v3_v3( orthx, orthy,shi-&gt;vn);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mul_v3_fl(orthx, samp3d[0]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mul_v3_fl(orthy, samp3d[1]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* and perturb the normal in it */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; add_v3_v3v3(v_nor_new, shi-&gt;vn, orthx);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; add_v3_v3(v_nor_new, orthy);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; normalize_v3(v_nor_new);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* no blurriness, use the original normal */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(v_nor_new, shi-&gt;vn);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if((shi-&gt;vlr-&gt;flag &amp; R_SMOOTH))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; reflection(v_reflect, v_nor_new, shi-&gt;view, shi-&gt;facenor);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; reflection(v_reflect, v_nor_new, shi-&gt;view, NULL);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sampcol[0]= sampcol[1]= sampcol[2]= sampcol[3]= 0.0f;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; traceray(shi, shr,
shi-&gt;mat-&gt;ray_depth, shi-&gt;co, v_reflect, sampcol, shi-&gt;obi,
shi-&gt;vlr, 0);<br>
<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; col[0] += sampcol[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; col[1] += sampcol[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; col[2] += sampcol[2];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* for variance calc */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; colsq[0] += sampcol[0]*sampcol[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; colsq[1] += sampcol[1]*sampcol[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; colsq[2] += sampcol[2]*sampcol[2];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; samples++;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* adaptive sampling */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (adapt_thresh &gt; 0.0 &amp;&amp; samples &gt; max_samples/3)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (adaptive_sample_variance(samples, col, colsq, adapt_thresh))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* if the
pixel so far is very dark, we can get away with less samples */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if ( (col[0] + col[1] + col[2])/3.0/(float)samples &lt; 0.01 )<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; max_samples--;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* reduce
samples when reflection is dim due to low ray mirror blend value or
fresnel factor<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* and when reflection is blurry */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (fresnelfac &lt; 0.1 * (blur+1)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; max_samples--;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* even more for very dim */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (fresnelfac &lt; 0.05 * (blur+1))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; max_samples--;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; col[0] /= (float)samples;<br>
&nbsp;&nbsp;&nbsp; col[1] /= (float)samples;<br>
&nbsp;&nbsp;&nbsp; col[2] /= (float)samples;<br>
<br>
&nbsp;&nbsp;&nbsp; if (qsa)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; release_thread_qmcsampler(&amp;R, shi-&gt;thread, qsa);<br>
}<br>
<br>
/* extern call from render loop */<br>
void ray_trace(ShadeInput *shi, ShadeResult *shr)<br>
{<br>
&nbsp;&nbsp;&nbsp; float i, f, f1, fr, fg, fb;<br>
&nbsp;&nbsp;&nbsp; float mircol[4], tracol[4];<br>
&nbsp;&nbsp;&nbsp; float diff[3];<br>
&nbsp;&nbsp;&nbsp; int do_tra, do_mir;<br>
<br>
&nbsp;&nbsp;&nbsp; do_tra= ((shi-&gt;mode &amp; MA_TRANSP) &amp;&amp;
(shi-&gt;mode &amp; MA_RAYTRANSP) &amp;&amp; shr-&gt;alpha!=1.0f
&amp;&amp; (shi-&gt;depth &lt;= shi-&gt;mat-&gt;ray_depth_tra));<br>
&nbsp;&nbsp;&nbsp; do_mir= ((shi-&gt;mat-&gt;mode &amp; MA_RAYMIRROR)
&amp;&amp; shi-&gt;ray_mirror!=0.0f &amp;&amp; (shi-&gt;depth &lt;=
shi-&gt;mat-&gt;ray_depth));<br>
<br>
&nbsp;&nbsp;&nbsp; /* raytrace mirror amd refract like to separate the spec color */<br>
&nbsp;&nbsp;&nbsp; if(shi-&gt;combinedflag &amp; SCE_PASS_SPEC)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECSUB(diff, shr-&gt;combined, shr-&gt;spec) /* no ; */<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(diff, shr-&gt;combined);<br>
<br>
&nbsp;&nbsp;&nbsp; if(do_tra) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float olddiff[3];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; trace_refract(tracol, shi, shr);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; f= shr-&gt;alpha; f1= 1.0f-f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fr= 1.0f+ shi-&gt;mat-&gt;filter*(shi-&gt;r-1.0f);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fg= 1.0f+ shi-&gt;mat-&gt;filter*(shi-&gt;g-1.0f);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fb= 1.0f+ shi-&gt;mat-&gt;filter*(shi-&gt;b-1.0f);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* for refract pass */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(olddiff, diff);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; diff[0]= f*diff[0] + f1*fr*tracol[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; diff[1]= f*diff[1] + f1*fg*tracol[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; diff[2]= f*diff[2] + f1*fb*tracol[2];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(shi-&gt;passflag &amp; SCE_PASS_REFRACT)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECSUB(shr-&gt;refr, diff, olddiff);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!(shi-&gt;combinedflag &amp; SCE_PASS_REFRACT))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECSUB(diff, diff, shr-&gt;refr);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shr-&gt;alpha= MIN2(1.0f, tracol[3]);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if(do_mir) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; i=
shi-&gt;ray_mirror*fresnel_fac(shi-&gt;view, shi-&gt;vn,
shi-&gt;mat-&gt;fresnel_mir_i, shi-&gt;mat-&gt;fresnel_mir);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(i!=0.0f) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; trace_reflect(mircol, shi, shr, i);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fr= i*shi-&gt;mirr;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fg= i*shi-&gt;mirg;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fb= i*shi-&gt;mirb;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(shi-&gt;passflag &amp; SCE_PASS_REFLECT) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* mirror pass is not blocked out with spec */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shr-&gt;refl[0]= fr*mircol[0] - fr*diff[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shr-&gt;refl[1]= fg*mircol[1] - fg*diff[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shr-&gt;refl[2]= fb*mircol[2] - fb*diff[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(shi-&gt;combinedflag &amp; SCE_PASS_REFLECT) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* values in shr-&gt;spec can be greater then 1.0.<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;* In this case the mircol uses a zero blending
factor, so ignoring it is ok.<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;* Fixes bug #18837 - when the spec is higher
then 1.0,<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;* diff can become a negative color -
Campbell&nbsp; */<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; f1= 1.0f-i;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; diff[0] *= f1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; diff[1] *= f1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; diff[2] *= f1;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(shr-&gt;spec[0]&lt;1.0f)&nbsp;&nbsp;&nbsp;
diff[0] += mircol[0] * (fr*(1.0f-shr-&gt;spec[0]));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(shr-&gt;spec[1]&lt;1.0f)&nbsp;&nbsp;&nbsp;
diff[1] += mircol[1] * (fg*(1.0f-shr-&gt;spec[1]));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(shr-&gt;spec[2]&lt;1.0f)&nbsp;&nbsp;&nbsp;
diff[2] += mircol[2] * (fb*(1.0f-shr-&gt;spec[2]));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; /* put back together */<br>
&nbsp;&nbsp;&nbsp; if(shi-&gt;combinedflag &amp; SCE_PASS_SPEC)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECADD(shr-&gt;combined, diff, shr-&gt;spec) /* no ; */<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(shr-&gt;combined, diff);<br>
}<br>
<br>
/* color 'shadfac' passes through 'col' with alpha and filter */<br>
/* filter is only applied on alpha defined transparent part */<br>
static void addAlphaLight(float *shadfac, float *col, float alpha, float filter)<br>
{<br>
&nbsp;&nbsp;&nbsp; float fr, fg, fb;<br>
<br>
&nbsp;&nbsp;&nbsp; fr= 1.0f+ filter*(col[0]-1.0f);<br>
&nbsp;&nbsp;&nbsp; fg= 1.0f+ filter*(col[1]-1.0f);<br>
&nbsp;&nbsp;&nbsp; fb= 1.0f+ filter*(col[2]-1.0f);<br>
<br>
&nbsp;&nbsp;&nbsp; shadfac[0]= alpha*col[0] + fr*(1.0f-alpha)*shadfac[0];<br>
&nbsp;&nbsp;&nbsp; shadfac[1]= alpha*col[1] + fg*(1.0f-alpha)*shadfac[1];<br>
&nbsp;&nbsp;&nbsp; shadfac[2]= alpha*col[2] + fb*(1.0f-alpha)*shadfac[2];<br>
<br>
&nbsp;&nbsp;&nbsp; shadfac[3]= (1.0f-alpha)*shadfac[3];<br>
}<br>
<br>
static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int traflag, float col[4])<br>
{<br>
&nbsp;&nbsp;&nbsp; /* ray to lamp, find first face that intersects, check alpha properties,<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; if it has col[3]&gt;0.0f&nbsp; continue. so exit when alpha is full */<br>
&nbsp;&nbsp;&nbsp; ShadeInput shi;<br>
&nbsp;&nbsp;&nbsp; ShadeResult shr;<br>
&nbsp;&nbsp;&nbsp; float initial_dist = is-&gt;dist;<br>
<br>
&nbsp;&nbsp;&nbsp; if(RE_rayobject_raycast(R.raytree, is)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float d= 1.0f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* we got a face */<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Warning, This is not that nice, and possibly a bit slow for every ray,<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; however some variables were not
initialized properly in, unless using shade_input_initialize(...), we
need to do a memset */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memset(&amp;shi, 0, sizeof(ShadeInput));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* end warning! - Campbell */<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.depth= origshi-&gt;depth +
1;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* only used to indicate tracing
*/<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.mask= origshi-&gt;mask;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.thread= origshi-&gt;thread;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.passflag= SCE_PASS_COMBINED;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.combinedflag=
0xFFFFFF;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;/* ray trace does
all options */<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.xs= origshi-&gt;xs;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.ys= origshi-&gt;ys;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.lay= origshi-&gt;lay;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shi.nodes= origshi-&gt;nodes;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shade_ray(is, &amp;shi, &amp;shr);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (shi.mat-&gt;material_type == MA_TYPE_SURFACE) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (traflag &amp; RAY_TRA)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; d= shade_by_transmission(is, &amp;shi, &amp;shr);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* mix colors based on shadfac (rgb + amount of light factor) */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; addAlphaLight(col, shr.diff, shr.alpha, d*shi.mat-&gt;filter);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else if (shi.mat-&gt;material_type == MA_TYPE_VOLUME) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; const float a = col[3];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; col[0] = a*col[0] + shr.alpha*shr.combined[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; col[1] = a*col[1] + shr.alpha*shr.combined[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; col[2] = a*col[2] + shr.alpha*shr.combined[2];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; col[3] = (1.0 - shr.alpha)*a;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(depth&gt;0 &amp;&amp; col[3]&gt;0.0f) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* adapt isect struct */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(is-&gt;start, shi.co);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; is-&gt;dist = initial_dist-is-&gt;dist;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; is-&gt;orig.ob&nbsp;&nbsp; = shi.obi;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; is-&gt;orig.face = shi.vlr;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ray_trace_shadow_tra(is, origshi, depth-1, traflag | RAY_TRA, col);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RE_RC_MERGE(&amp;origshi-&gt;raycounter, &amp;shi.raycounter);<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
/* not used, test function for ambient occlusion (yaf: pathlight) */<br>
/* main problem; has to be called within shading loop, giving unwanted recursion */<br>
int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr)<br>
{<br>
&nbsp;&nbsp;&nbsp; static int counter=0, only_one= 0;<br>
&nbsp;&nbsp;&nbsp; extern float hashvectf[];<br>
&nbsp;&nbsp;&nbsp; Isect isec;<br>
&nbsp;&nbsp;&nbsp; ShadeInput shi;<br>
&nbsp;&nbsp;&nbsp; ShadeResult shr_t;<br>
&nbsp;&nbsp;&nbsp; float vec[3], accum[3], div= 0.0f;<br>
&nbsp;&nbsp;&nbsp; int a;<br>
<br>
&nbsp;&nbsp;&nbsp; assert(0);<br>
<br>
&nbsp;&nbsp;&nbsp; if(only_one) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; only_one= 1;<br>
<br>
&nbsp;&nbsp;&nbsp; accum[0]= accum[1]= accum[2]= 0.0f;<br>
&nbsp;&nbsp;&nbsp; isec.mode= RE_RAY_MIRROR;<br>
&nbsp;&nbsp;&nbsp; isec.orig.ob&nbsp;&nbsp; = ship-&gt;obi;<br>
&nbsp;&nbsp;&nbsp; isec.orig.face = ship-&gt;vlr;<br>
&nbsp;&nbsp;&nbsp; isec.hint = 0;<br>
<br>
&nbsp;&nbsp;&nbsp; VECCOPY(isec.start, ship-&gt;co);<br>
<br>
&nbsp;&nbsp;&nbsp; RE_RC_INIT(isec, shi);<br>
<br>
&nbsp;&nbsp;&nbsp; for(a=0; a&lt;8*8; a++) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; counter+=3;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; counter %= 768;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(vec, hashvectf+counter);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(ship-&gt;vn[0]*vec[0]+ship-&gt;vn[1]*vec[1]+ship-&gt;vn[2]*vec[2]&gt;0.0f) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; vec[0]-= vec[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; vec[1]-= vec[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; vec[2]-= vec[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(isec.dir, vec );<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec.dist = RE_RAYTRACE_MAXDIST;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(RE_rayobject_raycast(R.raytree, &amp;isec)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float fac;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Warning,
This is not that nice, and possibly a bit slow for every ray,<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; however some
variables were not initialized properly in, unless using
shade_input_initialize(...), we need to do a memset */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memset(&amp;shi, 0, sizeof(ShadeInput));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* end warning! - Campbell */<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shade_ray(&amp;isec, &amp;shi, &amp;shr_t);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fac= isec.dist*isec.dist;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fac= 1.0f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; accum[0]+= fac*(shr_t.diff[0]+shr_t.spec[0]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; accum[1]+= fac*(shr_t.diff[1]+shr_t.spec[1]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; accum[2]+= fac*(shr_t.diff[2]+shr_t.spec[2]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; div+= fac;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else div+= 1.0f;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if(div!=0.0f) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shr-&gt;diff[0]+= accum[0]/div;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shr-&gt;diff[1]+= accum[1]/div;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shr-&gt;diff[2]+= accum[2]/div;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; shr-&gt;alpha= 1.0f;<br>
<br>
&nbsp;&nbsp;&nbsp; only_one= 0;<br>
&nbsp;&nbsp;&nbsp; return 1;<br>
}<br>
<br>
/* aolight: function to create random unit sphere vectors for total random sampling */<br>
static void RandomSpherical(float *v)<br>
{<br>
&nbsp;&nbsp;&nbsp; float r;<br>
&nbsp;&nbsp;&nbsp; v[2] = 2.f*BLI_frand()-1.f;<br>
&nbsp;&nbsp;&nbsp; if ((r = 1.f - v[2]*v[2])&gt;0.f) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float a = 6.283185307f*BLI_frand();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; r = sqrt(r);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; v[0] = r * cos(a);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; v[1] = r * sin(a);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else v[2] = 1.f;<br>
}<br>
<br>
/* calc distributed spherical energy */<br>
static void DS_energy(float *sphere, int tot, float *vec)<br>
{<br>
&nbsp;&nbsp;&nbsp; float *fp, fac, force[3], res[3];<br>
&nbsp;&nbsp;&nbsp; int a;<br>
<br>
&nbsp;&nbsp;&nbsp; res[0]= res[1]= res[2]= 0.0f;<br>
<br>
&nbsp;&nbsp;&nbsp; for(a=0, fp=sphere; a&lt;tot; a++, fp+=3) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sub_v3_v3v3(force, vec, fp);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fac= force[0]*force[0] + force[1]*force[1] + force[2]*force[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(fac!=0.0f) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fac= 1.0f/fac;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; res[0]+= fac*force[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; res[1]+= fac*force[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; res[2]+= fac*force[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; mul_v3_fl(res, 0.5);<br>
&nbsp;&nbsp;&nbsp; add_v3_v3(vec, res);<br>
&nbsp;&nbsp;&nbsp; normalize_v3(vec);<br>
<br>
}<br>
<br>
/* called from convertBlenderScene.c */<br>
/* creates an equally distributed spherical sample pattern */<br>
/* and allocates threadsafe memory */<br>
void init_ao_sphere(World *wrld)<br>
{<br>
&nbsp;&nbsp;&nbsp; float *fp;<br>
&nbsp;&nbsp;&nbsp; int a, tot, iter= 16;<br>
<br>
&nbsp;&nbsp;&nbsp; /* we make twice the amount of samples, because only a hemisphere is used */<br>
&nbsp;&nbsp;&nbsp; tot= 2*wrld-&gt;aosamp*wrld-&gt;aosamp;<br>
<br>
&nbsp;&nbsp;&nbsp; wrld-&gt;aosphere= MEM_mallocN(3*tot*sizeof(float), "AO sphere");<br>
<br>
&nbsp;&nbsp;&nbsp; /* fixed random */<br>
&nbsp;&nbsp;&nbsp; BLI_srandom(tot);<br>
<br>
&nbsp;&nbsp;&nbsp; /* init */<br>
&nbsp;&nbsp;&nbsp; fp= wrld-&gt;aosphere;<br>
&nbsp;&nbsp;&nbsp; for(a=0; a&lt;tot; a++, fp+= 3) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RandomSpherical(fp);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; while(iter--) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(a=0, fp= wrld-&gt;aosphere; a&lt;tot; a++, fp+= 3) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; DS_energy(wrld-&gt;aosphere, tot, fp);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* tables */<br>
&nbsp;&nbsp;&nbsp; wrld-&gt;aotables= MEM_mallocN(BLENDER_MAX_THREADS*3*tot*sizeof(float), "AO tables");<br>
}<br>
<br>
/* give per thread a table, we have to compare xs ys because of way OSA works... */<br>
static float *threadsafe_table_sphere(int test, int thread, int xs, int ys, int tot)<br>
{<br>
&nbsp;&nbsp;&nbsp; static int xso[BLENDER_MAX_THREADS], yso[BLENDER_MAX_THREADS];<br>
&nbsp;&nbsp;&nbsp; static int firsttime= 1;<br>
<br>
&nbsp;&nbsp;&nbsp; if(firsttime) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memset(xso, 255, sizeof(xso));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memset(yso, 255, sizeof(yso));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; firsttime= 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if(xs==xso[thread] &amp;&amp; ys==yso[thread]) return R.wrld.aotables+ thread*tot*3;<br>
&nbsp;&nbsp;&nbsp; if(test) return NULL;<br>
&nbsp;&nbsp;&nbsp; xso[thread]= xs; yso[thread]= ys;<br>
&nbsp;&nbsp;&nbsp; return R.wrld.aotables+ thread*tot*3;<br>
}<br>
<br>
static float *sphere_sampler(int type, int resol, int thread, int xs, int ys, int reset)<br>
{<br>
&nbsp;&nbsp;&nbsp; int tot;<br>
&nbsp;&nbsp;&nbsp; float *vec;<br>
<br>
&nbsp;&nbsp;&nbsp; tot= 2*resol*resol;<br>
<br>
&nbsp;&nbsp;&nbsp; if (type &amp; WO_AORNDSMP) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float *sphere;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int a;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // always returns table<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sphere= threadsafe_table_sphere(0, thread, xs, ys, tot);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* total random sampling. NOT THREADSAFE! (should be removed, is not useful) */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; vec= sphere;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for (a=0; a&lt;tot; a++, vec+=3) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RandomSpherical(vec);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return sphere;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float *sphere;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float cosfi, sinfi, cost, sint;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float ang, *vec1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int a;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // returns table if xs and ys were equal to last call, and not resetting<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sphere= (reset)? NULL: threadsafe_table_sphere(1, thread, xs, ys, tot);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(sphere==NULL) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sphere= threadsafe_table_sphere(0, thread, xs, ys, tot);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // random rotation<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ang= BLI_thread_frand(thread);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sinfi= sin(ang); cosfi= cos(ang);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ang= BLI_thread_frand(thread);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sint= sin(ang); cost= cos(ang);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; vec= R.wrld.aosphere;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; vec1= sphere;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for (a=0; a&lt;tot; a++, vec+=3, vec1+=3) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; vec1[0]= cost*cosfi*vec[0] - sinfi*vec[1] +
sint*cosfi*vec[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; vec1[1]= cost*sinfi*vec[0] + cosfi*vec[1] +
sint*sinfi*vec[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; vec1[2]= -sint*vec[0] + cost*vec[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return sphere;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
static void ray_ao_qmc(ShadeInput *shi, float *ao, float *env)<br>
{<br>
&nbsp;&nbsp;&nbsp; Isect isec;<br>
&nbsp;&nbsp;&nbsp; RayHint point_hint;<br>
&nbsp;&nbsp;&nbsp; QMCSampler *qsa=NULL;<br>
&nbsp;&nbsp;&nbsp; float samp3d[3];<br>
&nbsp;&nbsp;&nbsp; float up[3], side[3], dir[3], nrm[3];<br>
<br>
&nbsp;&nbsp;&nbsp; float maxdist = R.wrld.aodist;<br>
&nbsp;&nbsp;&nbsp; float fac=0.0f, prev=0.0f;<br>
&nbsp;&nbsp;&nbsp; float adapt_thresh = R.wrld.ao_adapt_thresh;<br>
&nbsp;&nbsp;&nbsp; float adapt_speed_fac = R.wrld.ao_adapt_speed_fac;<br>
<br>
&nbsp;&nbsp;&nbsp; int samples=0;<br>
&nbsp;&nbsp;&nbsp; int max_samples = R.wrld.aosamp*R.wrld.aosamp;<br>
<br>
&nbsp;&nbsp;&nbsp; float dxyview[3], skyadded=0;<br>
&nbsp;&nbsp;&nbsp; int envcolor;<br>
<br>
&nbsp;&nbsp;&nbsp; RE_RC_INIT(isec, *shi);<br>
&nbsp;&nbsp;&nbsp; isec.orig.ob&nbsp;&nbsp; = shi-&gt;obi;<br>
&nbsp;&nbsp;&nbsp; isec.orig.face = shi-&gt;vlr;<br>
&nbsp;&nbsp;&nbsp; isec.check = RE_CHECK_VLR_NON_SOLID_MATERIAL;<br>
&nbsp;&nbsp;&nbsp; isec.skip = RE_SKIP_VLR_NEIGHBOUR;<br>
&nbsp;&nbsp;&nbsp; isec.hint = 0;<br>
<br>
&nbsp;&nbsp;&nbsp; isec.hit.ob&nbsp;&nbsp; = 0;<br>
&nbsp;&nbsp;&nbsp; isec.hit.face = 0;<br>
<br>
&nbsp;&nbsp;&nbsp; isec.last_hit = NULL;<br>
<br>
&nbsp;&nbsp;&nbsp; isec.mode= (R.wrld.aomode &amp; WO_AODIST)?RE_RAY_SHADOW_TRA:RE_RAY_SHADOW;<br>
&nbsp;&nbsp;&nbsp; isec.lay= -1;<br>
<br>
&nbsp;&nbsp;&nbsp; VECCOPY(isec.start, shi-&gt;co);<br>
&nbsp;&nbsp;&nbsp; RE_rayobject_hint_bb( R.raytree, &amp;point_hint, isec.start, isec.start );<br>
&nbsp;&nbsp;&nbsp; isec.hint = &amp;point_hint;<br>
<br>
&nbsp;&nbsp;&nbsp; zero_v3(ao);<br>
&nbsp;&nbsp;&nbsp; zero_v3(env);<br>
<br>
&nbsp;&nbsp;&nbsp; /* prevent sky colors to be added for only shadow (shadow becomes alpha) */<br>
&nbsp;&nbsp;&nbsp; envcolor= R.wrld.aocolor;<br>
&nbsp;&nbsp;&nbsp; if(shi-&gt;mat-&gt;mode &amp; MA_ONLYSHADOW)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; envcolor= WO_AOPLAIN;<br>
<br>
&nbsp;&nbsp;&nbsp; if(envcolor == WO_AOSKYTEX) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dxyview[0]= 1.0f/(float)R.wrld.aosamp;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dxyview[1]= 1.0f/(float)R.wrld.aosamp;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dxyview[2]= 0.0f;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if(shi-&gt;vlr-&gt;flag &amp; R_SMOOTH) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(nrm, shi-&gt;vn);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(nrm, shi-&gt;facenor);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; ortho_basis_v3v3_v3( up, side,nrm);<br>
<br>
&nbsp;&nbsp;&nbsp; /* sampling init */<br>
&nbsp;&nbsp;&nbsp; if (R.wrld.ao_samp_method==WO_AOSAMP_HALTON) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float speedfac;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; speedfac = get_avg_speed(shi) * adapt_speed_fac;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CLAMP(speedfac, 1.0, 1000.0);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; max_samples /= speedfac;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (max_samples &lt; 5) max_samples = 5;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; qsa = get_thread_qmcsampler(&amp;R, shi-&gt;thread, SAMP_TYPE_HALTON, max_samples);<br>
&nbsp;&nbsp;&nbsp; } else if (R.wrld.ao_samp_method==WO_AOSAMP_HAMMERSLEY)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; qsa = get_thread_qmcsampler(&amp;R, shi-&gt;thread, SAMP_TYPE_HAMMERSLEY, max_samples);<br>
<br>
&nbsp;&nbsp;&nbsp; QMC_initPixel(qsa, shi-&gt;thread);<br>
<br>
&nbsp;&nbsp;&nbsp; while (samples &lt; max_samples) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* sampling, returns quasi-random vector in unit hemisphere */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; QMC_sampleHemi(samp3d, qsa, shi-&gt;thread, samples);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dir[0] = (samp3d[0]*up[0] + samp3d[1]*side[0] + samp3d[2]*nrm[0]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dir[1] = (samp3d[0]*up[1] + samp3d[1]*side[1] + samp3d[2]*nrm[1]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dir[2] = (samp3d[0]*up[2] + samp3d[1]*side[2] + samp3d[2]*nrm[2]);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; normalize_v3(dir);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec.dir[0] = -dir[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec.dir[1] = -dir[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec.dir[2] = -dir[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec.dist = maxdist;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; prev = fac;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(RE_rayobject_raycast(R.raytree, &amp;isec)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if
(R.wrld.aomode &amp; WO_AODIST) fac+= exp(-isec.dist*R.wrld.aodistfac);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else fac+= 1.0f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if(envcolor!=WO_AOPLAIN) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float skycol[4];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float skyfac, view[3];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; view[0]= -dir[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; view[1]= -dir[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; view[2]= -dir[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; normalize_v3(view);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(envcolor==WO_AOSKYCOL) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; skyfac= 0.5*(1.0f+view[0]*R.grvec[0]+
view[1]*R.grvec[1]+ view[2]*R.grvec[2]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; env[0]+= (1.0f-skyfac)*R.wrld.horr +
skyfac*R.wrld.zenr;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; env[1]+= (1.0f-skyfac)*R.wrld.horg +
skyfac*R.wrld.zeng;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; env[2]+= (1.0f-skyfac)*R.wrld.horb +
skyfac*R.wrld.zenb;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {&nbsp;&nbsp;&nbsp; /* WO_AOSKYTEX */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; shadeSkyView(skycol, isec.start, view, dxyview,
shi-&gt;thread);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadeSunView(skycol, shi-&gt;view);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; env[0]+= skycol[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; env[1]+= skycol[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; env[2]+= skycol[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; skyadded++;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; samples++;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (qsa-&gt;type == SAMP_TYPE_HALTON) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* adaptive
sampling - consider samples below threshold as in shadow (or vice
versa) and exit early */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (adapt_thresh &gt; 0.0 &amp;&amp; (samples &gt; max_samples/2) ) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if (adaptive_sample_contrast_val(samples, prev, fac,
adapt_thresh)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* average color times distances/hits formula */<br>
&nbsp;&nbsp;&nbsp; ao[0]= ao[1]= ao[2]= 1.0f - fac/(float)samples;<br>
<br>
&nbsp;&nbsp;&nbsp; if(envcolor!=WO_AOPLAIN &amp;&amp; skyadded)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mul_v3_fl(env, (1.0f - fac/(float)samples)/((float)skyadded));<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; copy_v3_v3(env, ao);<br>
<br>
&nbsp;&nbsp;&nbsp; if (qsa)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; release_thread_qmcsampler(&amp;R, shi-&gt;thread, qsa);<br>
}<br>
<br>
/* extern call from shade_lamp_loop, ambient occlusion calculus */<br>
static void ray_ao_spheresamp(ShadeInput *shi, float *ao, float *env)<br>
{<br>
&nbsp;&nbsp;&nbsp; Isect isec;<br>
&nbsp;&nbsp;&nbsp; RayHint point_hint;<br>
&nbsp;&nbsp;&nbsp; float *vec, *nrm, bias, sh=0.0f;<br>
&nbsp;&nbsp;&nbsp; float maxdist = R.wrld.aodist;<br>
&nbsp;&nbsp;&nbsp; float dxyview[3];<br>
&nbsp;&nbsp;&nbsp; int j= -1, tot, actual=0, skyadded=0, envcolor, resol= R.wrld.aosamp;<br>
<br>
&nbsp;&nbsp;&nbsp; RE_RC_INIT(isec, *shi);<br>
&nbsp;&nbsp;&nbsp; isec.orig.ob&nbsp;&nbsp; = shi-&gt;obi;<br>
&nbsp;&nbsp;&nbsp; isec.orig.face = shi-&gt;vlr;<br>
&nbsp;&nbsp;&nbsp; isec.check = RE_CHECK_VLR_RENDER;<br>
&nbsp;&nbsp;&nbsp; isec.skip = RE_SKIP_VLR_NEIGHBOUR;<br>
&nbsp;&nbsp;&nbsp; isec.hint = 0;<br>
<br>
&nbsp;&nbsp;&nbsp; isec.hit.ob&nbsp;&nbsp; = 0;<br>
&nbsp;&nbsp;&nbsp; isec.hit.face = 0;<br>
<br>
&nbsp;&nbsp;&nbsp; isec.last_hit = NULL;<br>
<br>
&nbsp;&nbsp;&nbsp; isec.mode= (R.wrld.aomode &amp; WO_AODIST)?RE_RAY_SHADOW_TRA:RE_RAY_SHADOW;<br>
&nbsp;&nbsp;&nbsp; isec.lay= -1;<br>
<br>
&nbsp;&nbsp;&nbsp; VECCOPY(isec.start, shi-&gt;co);<br>
&nbsp;&nbsp;&nbsp; RE_rayobject_hint_bb( R.raytree, &amp;point_hint, isec.start, isec.start );<br>
&nbsp;&nbsp;&nbsp; isec.hint = &amp;point_hint;<br>
<br>
&nbsp;&nbsp;&nbsp; zero_v3(ao);<br>
&nbsp;&nbsp;&nbsp; zero_v3(env);<br>
<br>
&nbsp;&nbsp;&nbsp; /* bias prevents smoothed faces to appear flat */<br>
&nbsp;&nbsp;&nbsp; if(shi-&gt;vlr-&gt;flag &amp; R_SMOOTH) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bias= R.wrld.aobias;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; nrm= shi-&gt;vn;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bias= 0.0f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; nrm= shi-&gt;facenor;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* prevent sky colors to be added for only shadow (shadow becomes alpha) */<br>
&nbsp;&nbsp;&nbsp; envcolor= R.wrld.aocolor;<br>
&nbsp;&nbsp;&nbsp; if(shi-&gt;mat-&gt;mode &amp; MA_ONLYSHADOW)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; envcolor= WO_AOPLAIN;<br>
<br>
&nbsp;&nbsp;&nbsp; if(resol&gt;32) resol= 32;<br>
<br>
&nbsp;&nbsp;&nbsp; /* get sphere samples. for faces we get the same samples for sample x/y values,<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; for strand render we always require a new sampler because x/y are not set */<br>
&nbsp;&nbsp;&nbsp; vec= sphere_sampler(R.wrld.aomode, resol, shi-&gt;thread, shi-&gt;xs, shi-&gt;ys, shi-&gt;strand != NULL);<br>
<br>
&nbsp;&nbsp;&nbsp; // warning: since we use full sphere now, and dotproduct is below, we do twice as much<br>
&nbsp;&nbsp;&nbsp; tot= 2*resol*resol;<br>
<br>
&nbsp;&nbsp;&nbsp; if(envcolor == WO_AOSKYTEX) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dxyview[0]= 1.0f/(float)resol;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dxyview[1]= 1.0f/(float)resol;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dxyview[2]= 0.0f;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; while(tot--) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if ((vec[0]*nrm[0] + vec[1]*nrm[1] + vec[2]*nrm[2]) &gt; bias) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* only ao samples for mask */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(R.r.mode &amp; R_OSA) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; j++;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(j==R.osa) j= 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!(shi-&gt;mask &amp; (1&lt;&lt;j))) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; vec+=3;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; continue;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; actual++;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* always set start/vec/dist */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec.dir[0] = -vec[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec.dir[1] = -vec[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec.dir[2] = -vec[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec.dist = maxdist;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* do the trace */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(RE_rayobject_raycast(R.raytree, &amp;isec)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if (R.wrld.aomode &amp; WO_AODIST) sh+=
exp(-isec.dist*R.wrld.aodistfac);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else sh+= 1.0f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if(envcolor!=WO_AOPLAIN) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float skycol[4];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float fac, view[3];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; view[0]= -vec[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; view[1]= -vec[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; view[2]= -vec[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; normalize_v3(view);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(envcolor==WO_AOSKYCOL) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fac=
0.5*(1.0f+view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; env[0]+= (1.0f-fac)*R.wrld.horr +
fac*R.wrld.zenr;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; env[1]+= (1.0f-fac)*R.wrld.horg +
fac*R.wrld.zeng;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; env[2]+= (1.0f-fac)*R.wrld.horb +
fac*R.wrld.zenb;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {&nbsp;&nbsp;&nbsp; /* WO_AOSKYTEX */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadeSkyView(skycol, isec.start,
view, dxyview, shi-&gt;thread);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadeSunView(skycol,
shi-&gt;view);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; env[0]+= skycol[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; env[1]+= skycol[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; env[2]+= skycol[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; skyadded++;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // samples<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; vec+= 3;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if(actual==0) sh= 1.0f;<br>
&nbsp;&nbsp;&nbsp; else sh = 1.0f - sh/((float)actual);<br>
<br>
&nbsp;&nbsp;&nbsp; /* average color times distances/hits formula */<br>
&nbsp;&nbsp;&nbsp; ao[0]= ao[1]= ao[2]= sh;<br>
<br>
&nbsp;&nbsp;&nbsp; if(envcolor!=WO_AOPLAIN &amp;&amp; skyadded)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mul_v3_fl(env, sh/((float)skyadded));<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; copy_v3_v3(env, ao);<br>
}<br>
<br>
void ray_ao(ShadeInput *shi, float *ao, float *env)<br>
{<br>
&nbsp;&nbsp;&nbsp; /* Unfortunately, the unusual way that the sphere sampler calculates roughly twice as many<br>
&nbsp;&nbsp;&nbsp; &nbsp;* samples as are actually traced, and skips them based on bias and OSA settings makes it very difficult<br>
&nbsp;&nbsp;&nbsp; &nbsp;* to reuse code between these two functions. This is the easiest way I can think of to do it<br>
&nbsp;&nbsp;&nbsp; &nbsp;* --broken */<br>
&nbsp;&nbsp;&nbsp; if (ELEM(R.wrld.ao_samp_method, WO_AOSAMP_HAMMERSLEY, WO_AOSAMP_HALTON))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ray_ao_qmc(shi, ao, env);<br>
&nbsp;&nbsp;&nbsp; else if (R.wrld.ao_samp_method == WO_AOSAMP_CONSTANT)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ray_ao_spheresamp(shi, ao, env);<br>
}<br>
<br>
static void ray_shadow_jittered_coords(ShadeInput *shi, int max, float jitco[RE_MAX_OSA][3], int *totjitco)<br>
{<br>
&nbsp;&nbsp;&nbsp; /* magic numbers for reordering sample positions to give better<br>
&nbsp;&nbsp;&nbsp; &nbsp;* results with adaptive sample, when it usually only takes 4 samples */<br>
&nbsp;&nbsp;&nbsp; int order8[8] = {0, 1, 5, 6, 2, 3, 4, 7};<br>
&nbsp;&nbsp;&nbsp; int order11[11] = {1, 3, 8, 10, 0, 2, 4, 5, 6, 7, 9};<br>
&nbsp;&nbsp;&nbsp; int order16[16] = {1, 3, 9, 12, 0, 6, 7, 8, 13, 2, 4, 5, 10, 11, 14, 15};<br>
&nbsp;&nbsp;&nbsp; int count = count_mask(shi-&gt;mask);<br>
<br>
&nbsp;&nbsp;&nbsp; /* for better antialising shadow samples are distributed over the subpixel<br>
&nbsp;&nbsp;&nbsp; &nbsp;* sample coordinates, this only works for raytracing depth 0 though */<br>
&nbsp;&nbsp;&nbsp; if(!shi-&gt;strand &amp;&amp; shi-&gt;depth == 0 &amp;&amp; count &gt; 1 &amp;&amp; count &lt;= max) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float xs, ys, zs, view[3];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int samp, ordsamp, tot= 0;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(samp=0; samp&lt;R.osa; samp++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(R.osa == 8) ordsamp = order8[samp];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if(R.osa == 11) ordsamp = order11[samp];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if(R.osa == 16) ordsamp = order16[samp];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else ordsamp = samp;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(shi-&gt;mask &amp; (1&lt;&lt;ordsamp)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; /* zbuffer has this inverse corrected, ensures xs,ys
are inside pixel */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; xs= (float)shi-&gt;scanco[0] + R.jit[ordsamp][0] +
0.5f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; ys= (float)shi-&gt;scanco[1] + R.jit[ordsamp][1] +
0.5f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; zs= shi-&gt;scanco[2];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; shade_input_calc_viewco(shi, xs, ys, zs, view, NULL,
jitco[tot], NULL, NULL);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tot++;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *totjitco= tot;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(jitco[0], shi-&gt;co);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *totjitco= 1;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *shadfac, Isect *isec)<br>
{<br>
&nbsp;&nbsp;&nbsp; QMCSampler *qsa=NULL;<br>
&nbsp;&nbsp;&nbsp; int samples=0;<br>
&nbsp;&nbsp;&nbsp; float samp3d[3];<br>
<br>
&nbsp;&nbsp;&nbsp; float fac=0.0f, vec[3], end[3];<br>
&nbsp;&nbsp;&nbsp; float colsq[4];<br>
&nbsp;&nbsp;&nbsp; float adapt_thresh = lar-&gt;adapt_thresh;<br>
&nbsp;&nbsp;&nbsp; int min_adapt_samples=4, max_samples = lar-&gt;ray_totsamp;<br>
&nbsp;&nbsp;&nbsp; float *co;<br>
&nbsp;&nbsp;&nbsp; int do_soft=1, full_osa=0, i;<br>
<br>
&nbsp;&nbsp;&nbsp; float min[3], max[3];<br>
&nbsp;&nbsp;&nbsp; RayHint bb_hint;<br>
<br>
&nbsp;&nbsp;&nbsp; float jitco[RE_MAX_OSA][3];<br>
&nbsp;&nbsp;&nbsp; int totjitco;<br>
<br>
&nbsp;&nbsp;&nbsp; colsq[0] = colsq[1] = colsq[2] = 0.0;<br>
&nbsp;&nbsp;&nbsp; if(isec-&gt;mode==RE_RAY_SHADOW_TRA) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 0.0f;<br>
&nbsp;&nbsp;&nbsp; } else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[3]= 1.0f;<br>
<br>
&nbsp;&nbsp;&nbsp; if (lar-&gt;ray_totsamp &lt; 2) do_soft = 0;<br>
&nbsp;&nbsp;&nbsp; if ((R.r.mode &amp; R_OSA) &amp;&amp; (R.osa &gt; 0)
&amp;&amp; (shi-&gt;vlr-&gt;flag &amp; R_FULL_OSA)) full_osa = 1;<br>
<br>
&nbsp;&nbsp;&nbsp; if (full_osa) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (do_soft) max_samples&nbsp; = max_samples/R.osa + 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else max_samples = 1;<br>
&nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (do_soft) max_samples = lar-&gt;ray_totsamp;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (shi-&gt;depth == 0) max_samples = (R.osa &gt; 4)?R.osa:5;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else max_samples = 1;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; ray_shadow_jittered_coords(shi, max_samples, jitco, &amp;totjitco);<br>
<br>
&nbsp;&nbsp;&nbsp; /* sampling init */<br>
&nbsp;&nbsp;&nbsp; if (lar-&gt;ray_samp_method==LA_SAMP_HALTON)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; qsa = get_thread_qmcsampler(&amp;R, shi-&gt;thread, SAMP_TYPE_HALTON, max_samples);<br>
&nbsp;&nbsp;&nbsp; else if (lar-&gt;ray_samp_method==LA_SAMP_HAMMERSLEY)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; qsa = get_thread_qmcsampler(&amp;R, shi-&gt;thread, SAMP_TYPE_HAMMERSLEY, max_samples);<br>
<br>
&nbsp;&nbsp;&nbsp; QMC_initPixel(qsa, shi-&gt;thread);<br>
<br>
&nbsp;&nbsp;&nbsp; INIT_MINMAX(min, max);<br>
&nbsp;&nbsp;&nbsp; for(i=0; i&lt;totjitco; i++)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; DO_MINMAX(jitco[i], min, max);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; RE_rayobject_hint_bb( R.raytree, &amp;bb_hint, min, max);<br>
<br>
&nbsp;&nbsp;&nbsp; isec-&gt;hint = &amp;bb_hint;<br>
&nbsp;&nbsp;&nbsp; isec-&gt;check = RE_CHECK_VLR_RENDER;<br>
&nbsp;&nbsp;&nbsp; isec-&gt;skip = RE_SKIP_VLR_NEIGHBOUR;<br>
&nbsp;&nbsp;&nbsp; VECCOPY(vec, lampco);<br>
<br>
&nbsp;&nbsp;&nbsp; while (samples &lt; max_samples) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec-&gt;orig.ob&nbsp;&nbsp; = shi-&gt;obi;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec-&gt;orig.face = shi-&gt;vlr;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* manually jitter the start shading co-ord per sample<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* based on the pre-generated OSA texture sampling offsets,<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* for anti-aliasing sharp shadow edges. */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; co = jitco[samples % totjitco];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (do_soft) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* sphere shadow source */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (lar-&gt;type == LA_LOCAL) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float ru[3], rv[3], v[3], s[3];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* calc tangent plane vectors */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; v[0] = co[0] - lampco[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; v[1] = co[1] - lampco[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; v[2] = co[2] - lampco[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; normalize_v3(v);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ortho_basis_v3v3_v3( ru, rv,v);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; /* sampling, returns quasi-random vector in
area_size disc */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; QMC_sampleDisc(samp3d, qsa, shi-&gt;thread,
samples,lar-&gt;area_size);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; /* distribute disc samples across the tangent plane
*/<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; s[0] = samp3d[0]*ru[0] + samp3d[1]*rv[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; s[1] = samp3d[0]*ru[1] + samp3d[1]*rv[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; s[2] = samp3d[0]*ru[2] + samp3d[1]*rv[2];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(samp3d, s);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; /* sampling, returns quasi-random vector in
[sizex,sizey]^2 plane */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; QMC_sampleRect(samp3d, qsa, shi-&gt;thread, samples,
lar-&gt;area_size, lar-&gt;area_sizey);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* align samples to lamp vector */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mul_m3_v3(lar-&gt;mat, samp3d);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; end[0] = vec[0]+samp3d[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; end[1] = vec[1]+samp3d[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; end[2] = vec[2]+samp3d[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(end, vec);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(shi-&gt;strand) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* bias away somewhat to avoid self intersection */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float jitbias= 0.5f*(len_v3(shi-&gt;dxco) + len_v3(shi-&gt;dyco));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float v[3];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECSUB(v, co, end);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; normalize_v3(v);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; co[0] -= jitbias*v[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; co[1] -= jitbias*v[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; co[2] -= jitbias*v[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(isec-&gt;start, co);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec-&gt;dir[0] = end[0]-isec-&gt;start[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec-&gt;dir[1] = end[1]-isec-&gt;start[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec-&gt;dir[2] = end[2]-isec-&gt;start[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec-&gt;dist = normalize_v3(isec-&gt;dir);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* trace the ray */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(isec-&gt;mode==RE_RAY_SHADOW_TRA) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float col[4] = {1.0f, 1.0f, 1.0f, 1.0f};<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ray_trace_shadow_tra(isec, shi, DEPTH_SHADOW_TRA, 0, col);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[0] += col[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[1] += col[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[2] += col[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[3] += col[3];<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* for variance calc */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; colsq[0] += col[0]*col[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; colsq[1] += col[1]*col[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; colsq[2] += col[2]*col[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if( RE_rayobject_raycast(R.raytree, isec) ) fac+= 1.0f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; samples++;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (lar-&gt;ray_samp_method == LA_SAMP_HALTON) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* adaptive
sampling - consider samples below threshold as in shadow (or vice
versa) and exit early */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if
((max_samples &gt; min_adapt_samples) &amp;&amp; (adapt_thresh &gt;
0.0) &amp;&amp; (samples &gt; max_samples / 3)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (isec-&gt;mode==RE_RAY_SHADOW_TRA) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if ((shadfac[3] / samples &gt;
(1.0-adapt_thresh)) || (shadfac[3] / samples &lt; adapt_thresh))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if
(adaptive_sample_variance(samples, shadfac, colsq, adapt_thresh))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if ((fac / samples &gt;
(1.0-adapt_thresh)) || (fac / samples &lt; adapt_thresh))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if(isec-&gt;mode==RE_RAY_SHADOW_TRA) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[0] /= samples;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[1] /= samples;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[2] /= samples;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[3] /= samples;<br>
&nbsp;&nbsp;&nbsp; } else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[3]= 1.0f-fac/samples;<br>
<br>
&nbsp;&nbsp;&nbsp; if (qsa)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; release_thread_qmcsampler(&amp;R, shi-&gt;thread, qsa);<br>
}<br>
<br>
static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, float *shadfac, Isect *isec)<br>
{<br>
&nbsp;&nbsp;&nbsp; /* area soft shadow */<br>
&nbsp;&nbsp;&nbsp; float *jitlamp;<br>
&nbsp;&nbsp;&nbsp; float fac=0.0f, div=0.0f, vec[3];<br>
&nbsp;&nbsp;&nbsp; int a, j= -1, mask;<br>
&nbsp;&nbsp;&nbsp; RayHint point_hint;<br>
<br>
&nbsp;&nbsp;&nbsp; if(isec-&gt;mode==RE_RAY_SHADOW_TRA) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 0.0f;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else shadfac[3]= 1.0f;<br>
<br>
&nbsp;&nbsp;&nbsp; fac= 0.0f;<br>
&nbsp;&nbsp;&nbsp; jitlamp= give_jitter_plane(lar, shi-&gt;thread, shi-&gt;xs, shi-&gt;ys);<br>
<br>
&nbsp;&nbsp;&nbsp; a= lar-&gt;ray_totsamp;<br>
<br>
&nbsp;&nbsp;&nbsp; /* this correction to make sure we always take at least 1 sample */<br>
&nbsp;&nbsp;&nbsp; mask= shi-&gt;mask;<br>
&nbsp;&nbsp;&nbsp; if(a==4) mask |= (mask&gt;&gt;4)|(mask&gt;&gt;8);<br>
&nbsp;&nbsp;&nbsp; else if(a==9) mask |= (mask&gt;&gt;9);<br>
<br>
&nbsp;&nbsp;&nbsp; VECCOPY(isec-&gt;start, shi-&gt;co);<br>
&nbsp;&nbsp;&nbsp; isec-&gt;orig.ob&nbsp;&nbsp; = shi-&gt;obi;<br>
&nbsp;&nbsp;&nbsp; isec-&gt;orig.face = shi-&gt;vlr;<br>
&nbsp;&nbsp;&nbsp; RE_rayobject_hint_bb( R.raytree, &amp;point_hint, isec-&gt;start, isec-&gt;start );<br>
&nbsp;&nbsp;&nbsp; isec-&gt;hint = &amp;point_hint;<br>
<br>
&nbsp;&nbsp;&nbsp; while(a--) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(R.r.mode &amp; R_OSA) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; j++;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(j&gt;=R.osa) j= 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!(mask &amp; (1&lt;&lt;j))) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; jitlamp+= 2;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; continue;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; vec[0]= jitlamp[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; vec[1]= jitlamp[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; vec[2]= 0.0f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mul_m3_v3(lar-&gt;mat, vec);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* set start and vec */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec-&gt;dir[0] = vec[0]+lampco[0]-isec-&gt;start[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec-&gt;dir[1] = vec[1]+lampco[1]-isec-&gt;start[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec-&gt;dir[2] = vec[2]+lampco[2]-isec-&gt;start[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec-&gt;dist = 1.0f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec-&gt;check = RE_CHECK_VLR_RENDER;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec-&gt;skip = RE_SKIP_VLR_NEIGHBOUR;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(isec-&gt;mode==RE_RAY_SHADOW_TRA) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* isec.col is
like shadfac, so defines amount of light (0.0 is full shadow) */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float col[4] = {1.0f, 1.0f, 1.0f, 1.0f};<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ray_trace_shadow_tra(isec, shi, DEPTH_SHADOW_TRA, 0, col);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[0] += col[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[1] += col[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[2] += col[2];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[3] += col[3];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if( RE_rayobject_raycast(R.raytree, isec) ) fac+= 1.0f;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; div+= 1.0f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; jitlamp+= 2;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if(isec-&gt;mode==RE_RAY_SHADOW_TRA) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[0] /= div;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[1] /= div;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[2] /= div;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[3] /= div;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // sqrt makes nice umbra effect<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(lar-&gt;ray_samp_type &amp; LA_SAMP_UMBRA)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[3]= sqrt(1.0f-fac/div);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[3]= 1.0f-fac/div;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
/* extern call from shade_lamp_loop */<br>
void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)<br>
{<br>
&nbsp;&nbsp;&nbsp; Isect isec;<br>
&nbsp;&nbsp;&nbsp; float lampco[3];<br>
<br>
&nbsp;&nbsp;&nbsp; /* setup isec */<br>
&nbsp;&nbsp;&nbsp; RE_RC_INIT(isec, *shi);<br>
&nbsp;&nbsp;&nbsp; if(shi-&gt;mat-&gt;mode &amp; MA_SHADOW_TRA) isec.mode= RE_RAY_SHADOW_TRA;<br>
&nbsp;&nbsp;&nbsp; else isec.mode= RE_RAY_SHADOW;<br>
&nbsp;&nbsp;&nbsp; isec.hint = 0;<br>
<br>
&nbsp;&nbsp;&nbsp; if(lar-&gt;mode &amp; (LA_LAYER|LA_LAYER_SHADOW))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec.lay= lar-&gt;lay;<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec.lay= -1;<br>
<br>
&nbsp;&nbsp;&nbsp; /* only when not mir tracing, first hit optimm */<br>
&nbsp;&nbsp;&nbsp; if(shi-&gt;depth==0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec.last_hit = lar-&gt;last_hit[shi-&gt;thread];<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec.last_hit = NULL;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if(lar-&gt;type==LA_SUN || lar-&gt;type==LA_HEMI) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* jitter and QMC sampling add a displace vector to the lamp position<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* that's incorrect because a SUN lamp does not has an exact position<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* and the displace should be done at the ray vector instead of the<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* lamp position.<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* This is easily verified by noticing that shadows of SUN lights change<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* with the scene BB.<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;*<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* This was detected during SoC 2009 - Raytrace Optimization, but to keep<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* consistency with older render code it wasn't removed.<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;*<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* If the render code goes through some recode/serious bug-fix then this<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* is something to consider!<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;*/<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lampco[0]= shi-&gt;co[0] - R.maxdist*lar-&gt;vec[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lampco[1]= shi-&gt;co[1] - R.maxdist*lar-&gt;vec[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lampco[2]= shi-&gt;co[2] - R.maxdist*lar-&gt;vec[2];<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(lampco, lar-&gt;co);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if (ELEM(lar-&gt;ray_samp_method, LA_SAMP_HALTON, LA_SAMP_HAMMERSLEY)) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ray_shadow_qmc(shi, lar, lampco, shadfac, &amp;isec);<br>
<br>
&nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(lar-&gt;ray_totsamp&lt;2) {<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec.orig.ob&nbsp;&nbsp; = shi-&gt;obi;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec.orig.face = shi-&gt;vlr;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[3]= 1.0f; // 1.0=full light<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* set up isec.dir */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(isec.start, shi-&gt;co);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECSUB(isec.dir, lampco, isec.start);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isec.dist = normalize_v3(isec.dir);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(isec.mode==RE_RAY_SHADOW_TRA) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; /* isec.col is like shadfac, so defines amount of
light (0.0 is full shadow) */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; float col[4] = {1.0f, 1.0f, 1.0f, 1.0f};<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; ray_trace_shadow_tra(&amp;isec, shi,
DEPTH_SHADOW_TRA, 0, col);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; QUATCOPY(shadfac, col);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if(RE_rayobject_raycast(R.raytree, &amp;isec))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shadfac[3]= 0.0f;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ray_shadow_jitter(shi, lar, lampco, shadfac, &amp;isec);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; /* for first hit optim, set last interesected shadow face */<br>
&nbsp;&nbsp;&nbsp; if(shi-&gt;depth==0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lar-&gt;last_hit[shi-&gt;thread] = isec.last_hit;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
}<br>
<br>
#if 0<br>
/* only when face points away from lamp, in direction of lamp, trace ray and find first exit point */<br>
static void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float *co)<br>
{<br>
&nbsp;&nbsp;&nbsp; Isect isec;<br>
&nbsp;&nbsp;&nbsp; float lampco[3];<br>
<br>
&nbsp;&nbsp;&nbsp; assert(0);<br>
<br>
&nbsp;&nbsp;&nbsp; /* setup isec */<br>
&nbsp;&nbsp;&nbsp; RE_RC_INIT(isec, *shi);<br>
&nbsp;&nbsp;&nbsp; isec.mode= RE_RAY_SHADOW_TRA;<br>
&nbsp;&nbsp;&nbsp; isec.hint = 0;<br>
<br>
&nbsp;&nbsp;&nbsp; if(lar-&gt;mode &amp; LA_LAYER) isec.lay= lar-&gt;lay; else isec.lay= -1;<br>
<br>
&nbsp;&nbsp;&nbsp; if(lar-&gt;type==LA_SUN || lar-&gt;type==LA_HEMI) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lampco[0]= shi-&gt;co[0] - RE_RAYTRACE_MAXDIST*lar-&gt;vec[0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lampco[1]= shi-&gt;co[1] - RE_RAYTRACE_MAXDIST*lar-&gt;vec[1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lampco[2]= shi-&gt;co[2] - RE_RAYTRACE_MAXDIST*lar-&gt;vec[2];<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VECCOPY(lampco, lar-&gt;co);<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; isec.orig.ob&nbsp;&nbsp; = shi-&gt;obi;<br>
&nbsp;&nbsp;&nbsp; isec.orig.face = shi-&gt;vlr;<br>
<br>
&nbsp;&nbsp;&nbsp; /* set up isec.dir */<br>
&nbsp;&nbsp;&nbsp; VECCOPY(isec.start, shi-&gt;co);<br>
&nbsp;&nbsp;&nbsp; VECCOPY(isec.end, lampco);<br>
<br>
&nbsp;&nbsp;&nbsp; if(RE_rayobject_raycast(R.raytree, &amp;isec)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* we got a face */<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* render co */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; co[0]= isec.start[0]+isec.dist*(isec.dir[0]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; co[1]= isec.start[1]+isec.dist*(isec.dir[1]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; co[2]= isec.start[2]+isec.dist*(isec.dir[2]);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *distfac= len_v3(isec.dir);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *distfac= 0.0f;<br>
}<br>
<br>
#endif<br>
<br>
<br>
</p>
<p>กก</p>


<pre></pre>

<pre></pre>

<pre></pre>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; <a href="PocketRuler.htm">                  







                       <img src="picture/back.gif" style="border: medium none ;" alt="back.gif (341 bytes)" height="35" width="32"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<a href="index.htm">
<img src="picture/up.gif" style="border: medium none ;" alt="up.gif (335 bytes)" height="32" width="35"></a>       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                         
<img src="picture/next.gif" style="border: medium none ;" alt="next.gif (337 bytes)" height="35" width="32">          


</p>

</body></html>