Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/render')
-rw-r--r--source/blender/render/CMakeLists.txt7
-rw-r--r--source/blender/render/SConscript4
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h3
-rw-r--r--source/blender/render/intern/include/render_types.h16
-rw-r--r--source/blender/render/intern/source/convertblender.c88
-rw-r--r--source/blender/render/intern/source/pipeline.c103
-rw-r--r--source/blender/render/intern/source/render_result.c7
-rw-r--r--source/blender/render/intern/source/shadeoutput.c8
8 files changed, 234 insertions, 2 deletions
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt
index eb81e7f2049..effc564fdc9 100644
--- a/source/blender/render/CMakeLists.txt
+++ b/source/blender/render/CMakeLists.txt
@@ -144,6 +144,13 @@ if(WITH_MOD_SMOKE)
add_definitions(-DWITH_SMOKE)
endif()
+if(WITH_FREESTYLE)
+ list(APPEND INC
+ ../freestyle
+ )
+ add_definitions(-DWITH_FREESTYLE)
+endif()
+
if(WITH_CODEC_QUICKTIME)
list(APPEND INC
../quicktime
diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript
index 992dd8c8262..c4309577ae9 100644
--- a/source/blender/render/SConscript
+++ b/source/blender/render/SConscript
@@ -83,6 +83,10 @@ if env['WITH_BF_QUICKTIME']:
if env['WITH_BF_OPENEXR']:
defs.append('WITH_OPENEXR')
+if env['WITH_BF_FREESTYLE']:
+ incs += ' ../freestyle'
+ defs.append('WITH_FREESTYLE')
+
if env['WITH_BF_GAMEENGINE']:
defs.append('WITH_GAMEENGINE')
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index f97e5ac3c59..020fa57cf94 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -219,6 +219,9 @@ void RE_TileProcessor(struct Render *re);
/* only RE_NewRender() needed, main Blender render calls */
void RE_BlenderFrame(struct Render *re, struct Main *bmain, struct Scene *scene, struct SceneRenderLayer *srl, struct Object *camera_override, unsigned int lay, int frame, const short write_still);
void RE_BlenderAnim(struct Render *re, struct Main *bmain, struct Scene *scene, struct Object *camera_override, unsigned int lay, int sfra, int efra, int tfra);
+#ifdef WITH_FREESTYLE
+void RE_RenderFreestyleStrokes(struct Render *re, struct Main *bmain, struct Scene *scene);
+#endif
/* error reporting */
void RE_SetReports(struct Render *re, struct ReportList *reports);
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index d65da586b9a..deba6d165f2 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -235,6 +235,10 @@ struct Render
ListBase volumes;
ListBase volume_precache_parts;
+#ifdef WITH_FREESTYLE
+ ListBase freestyle_renders;
+#endif
+
/* arena for allocating data for use during render, for
* example dynamic TFaces to go in the VlakRen structure.
*/
@@ -390,6 +394,9 @@ typedef struct VlakRen {
struct Material *mat;
char puno;
char flag, ec;
+#ifdef WITH_FREESTYLE
+ char freestyle_edge_mark;
+#endif
int index;
} VlakRen;
@@ -622,6 +629,15 @@ typedef struct LampRen {
#define R_TANGENT 64
#define R_TRACEBLE 128
+/* vlakren->freestyle_edge_mark */
+#ifdef WITH_FREESTYLE
+# define R_EDGE_V1V2 1
+# define R_EDGE_V2V3 2
+# define R_EDGE_V3V4 4
+# define R_EDGE_V3V1 4
+# define R_EDGE_V4V1 8
+#endif
+
/* strandbuffer->flag */
#define R_STRAND_BSPLINE 1
#define R_STRAND_B_UNITS 2
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 0dc6492fad1..9e9dff63c04 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -42,6 +42,9 @@
#include "BLI_memarena.h"
#include "BLI_ghash.h"
#include "BLI_linklist.h"
+#ifdef WITH_FREESTYLE
+# include "BLI_edgehash.h"
+#endif
#include "DNA_armature_types.h"
#include "DNA_camera_types.h"
@@ -2694,7 +2697,11 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr,
v2= mface->v2;
v3= mface->v3;
v4= mface->v4;
- flag= mface->flag & ME_SMOOTH;
+#ifdef WITH_FREESTYLE
+ flag = mface->flag & (ME_SMOOTH | ME_FREESTYLE_FACE);
+#else
+ flag = mface->flag & ME_SMOOTH;
+#endif
vlr= RE_findOrAddVlak(obr, obr->totvlak++);
vlr->v1= RE_findOrAddVert(obr, vertofs+v1);
@@ -3219,6 +3226,26 @@ static void add_volume(Render *re, ObjectRen *obr, Material *ma)
BLI_addtail(&re->volumes, vo);
}
+#ifdef WITH_FREESTYLE
+static EdgeHash *make_freestyle_edge_mark_hash(MEdge *medge, int totedge)
+{
+ EdgeHash *edge_hash= BLI_edgehash_new();
+ int a;
+
+ for(a=0; a<totedge; a++) {
+ if(medge[a].flag & ME_FREESTYLE_EDGE)
+ BLI_edgehash_insert(edge_hash, medge[a].v1, medge[a].v2, medge+a);
+ }
+ return edge_hash;
+}
+
+static int has_freestyle_edge_mark(EdgeHash *edge_hash, int v1, int v2)
+{
+ MEdge *medge= BLI_edgehash_lookup(edge_hash, v1, v2);
+ return (!medge) ? 0 : 1;
+}
+#endif
+
static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
{
Object *ob= obr->ob;
@@ -3363,6 +3390,17 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
}
if (!timeoffset) {
+#ifdef WITH_FREESTYLE
+ EdgeHash *edge_hash;
+ MEdge *medge;
+ int totedge;
+
+ /* create a hash table of Freestyle edge marks */
+ medge = dm->getEdgeArray(dm);
+ totedge = dm->getNumEdges(dm);
+ edge_hash = make_freestyle_edge_mark_hash(medge, totedge);
+#endif
+
/* store customdata names, because DerivedMesh is freed */
RE_set_customdata_names(obr, &dm->faceData);
@@ -3411,7 +3449,11 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
v2= mface->v2;
v3= reverse_verts==0 ? mface->v3 : mface->v1;
v4= mface->v4;
- flag= mface->flag & ME_SMOOTH;
+#ifdef WITH_FREESTYLE
+ flag = mface->flag & (ME_SMOOTH | ME_FREESTYLE_FACE);
+#else
+ flag = mface->flag & ME_SMOOTH;
+#endif
vlr= RE_findOrAddVlak(obr, obr->totvlak++);
vlr->v1= RE_findOrAddVert(obr, vertofs+v1);
@@ -3420,6 +3462,23 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
if (v4) vlr->v4= RE_findOrAddVert(obr, vertofs+v4);
else vlr->v4= 0;
+#ifdef WITH_FREESTYLE
+ /* Freestyle edge marks */
+ {
+ int edge_mark = 0;
+
+ if(has_freestyle_edge_mark(edge_hash, v1, v2)) edge_mark |= R_EDGE_V1V2;
+ if(has_freestyle_edge_mark(edge_hash, v2, v3)) edge_mark |= R_EDGE_V2V3;
+ if (!v4) {
+ if(has_freestyle_edge_mark(edge_hash, v3, v1)) edge_mark |= R_EDGE_V3V1;
+ } else {
+ if(has_freestyle_edge_mark(edge_hash, v3, v4)) edge_mark |= R_EDGE_V3V4;
+ if(has_freestyle_edge_mark(edge_hash, v4, v1)) edge_mark |= R_EDGE_V4V1;
+ }
+ vlr->freestyle_edge_mark= edge_mark;
+ }
+#endif
+
/* render normals are inverted in render */
if (use_original_normals) {
MFace *mf= me->mface+a;
@@ -3501,6 +3560,11 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
}
}
}
+
+#ifdef WITH_FREESTYLE
+ /* release the hash table of Freestyle edge marks */
+ BLI_edgehash_free(edge_hash, NULL);
+#endif
/* exception... we do edges for wire mode. potential conflict when faces exist... */
end= dm->getNumEdges(dm);
@@ -4300,6 +4364,26 @@ static void check_non_flat_quads(ObjectRen *obr)
/* new normals */
normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co);
normal_tri_v3(vlr1->n, vlr1->v3->co, vlr1->v2->co, vlr1->v1->co);
+
+#ifdef WITH_FREESTYLE
+ /* Freestyle edge marks */
+ if (vlr->flag & R_DIVIDE_24) {
+ vlr1->freestyle_edge_mark=
+ ((vlr->freestyle_edge_mark & R_EDGE_V2V3) ? R_EDGE_V1V2 : 0) |
+ ((vlr->freestyle_edge_mark & R_EDGE_V3V4) ? R_EDGE_V2V3 : 0);
+ vlr->freestyle_edge_mark=
+ ((vlr->freestyle_edge_mark & R_EDGE_V1V2) ? R_EDGE_V1V2 : 0) |
+ ((vlr->freestyle_edge_mark & R_EDGE_V4V1) ? R_EDGE_V3V1 : 0);
+ }
+ else {
+ vlr1->freestyle_edge_mark=
+ ((vlr->freestyle_edge_mark & R_EDGE_V3V4) ? R_EDGE_V2V3 : 0) |
+ ((vlr->freestyle_edge_mark & R_EDGE_V4V1) ? R_EDGE_V3V1 : 0);
+ vlr->freestyle_edge_mark=
+ ((vlr->freestyle_edge_mark & R_EDGE_V1V2) ? R_EDGE_V1V2 : 0) |
+ ((vlr->freestyle_edge_mark & R_EDGE_V2V3) ? R_EDGE_V2V3 : 0);
+ }
+#endif
}
/* clear the flag when not divided */
else vlr->flag &= ~R_DIVIDE_24;
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 3e9f5996ddc..866932632c2 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -75,6 +75,11 @@
#include "RE_engine.h"
#include "RE_pipeline.h"
+#ifdef WITH_FREESTYLE
+# include "BKE_library.h"
+# include "FRS_freestyle.h"
+#endif
+
/* internal */
#include "render_result.h"
#include "render_types.h"
@@ -942,6 +947,10 @@ void RE_TileProcessor(Render *re)
/* ************ This part uses API, for rendering Blender scenes ********** */
+#ifdef WITH_FREESTYLE
+static void add_freestyle(Render *re);
+#endif
+
static void do_render_3d(Render *re)
{
float cfra;
@@ -982,6 +991,13 @@ static void do_render_3d(Render *re)
if (!re->test_break(re->tbh))
add_halo_flare(re);
+#ifdef WITH_FREESTYLE
+ /* Freestyle */
+ if( re->r.mode & R_EDGE_FRS)
+ if(!re->test_break(re->tbh))
+ add_freestyle(re);
+#endif
+
/* free all render verts etc */
RE_Database_Free(re);
@@ -1421,6 +1437,74 @@ static void render_composit_stats(void *UNUSED(arg), char *str)
R.i.infostr = NULL;
}
+#ifdef WITH_FREESTYLE
+/* invokes Freestyle stroke rendering */
+static void add_freestyle(Render *re)
+{
+ SceneRenderLayer *srl, *actsrl;
+ LinkData *link;
+
+ actsrl = BLI_findlink(&re->r.layers, re->r.actlay);
+
+ FRS_init_stroke_rendering(re);
+
+ for (srl= (SceneRenderLayer *)re->r.layers.first; srl; srl= srl->next) {
+
+ link = (LinkData *)MEM_callocN(sizeof(LinkData), "LinkData to Freestyle render");
+ BLI_addtail(&re->freestyle_renders, link);
+
+ if ((re->r.scemode & R_SINGLE_LAYER) && srl != actsrl)
+ continue;
+ if (FRS_is_freestyle_enabled(srl)) {
+ link->data = (void *)FRS_do_stroke_rendering(re, srl);
+ }
+ }
+
+ FRS_finish_stroke_rendering(re);
+}
+
+/* merges the results of Freestyle stroke rendering into a given render result */
+static void composite_freestyle_renders(Render *re, int sample)
+{
+ Render *freestyle_render;
+ SceneRenderLayer *srl, *actsrl;
+ LinkData *link;
+
+ actsrl = BLI_findlink(&re->r.layers, re->r.actlay);
+
+ link = (LinkData *)re->freestyle_renders.first;
+ for (srl= (SceneRenderLayer *)re->r.layers.first; srl; srl= srl->next) {
+ if ((re->r.scemode & R_SINGLE_LAYER) && srl != actsrl)
+ continue;
+ if (FRS_is_freestyle_enabled(srl)) {
+ freestyle_render = (Render *)link->data;
+ render_result_exr_file_read(freestyle_render, sample);
+ FRS_composite_result(re, srl, freestyle_render);
+ RE_FreeRenderResult(freestyle_render->result);
+ freestyle_render->result = NULL;
+ }
+ link = link->next;
+ }
+}
+
+/* releases temporary scenes and renders for Freestyle stroke rendering */
+static void free_all_freestyle_renders(Scene *scene)
+{
+ Render *re1, *freestyle_render;
+ LinkData *link;
+
+ for (re1= RenderGlobal.renderlist.first; re1; re1= re1->next) {
+ for (link = (LinkData *)re1->freestyle_renders.first; link; link = link->next) {
+ if (link->data) {
+ freestyle_render = (Render *)link->data;
+ BKE_scene_unlink(G.main, freestyle_render->scene, scene);
+ RE_FreeRender(freestyle_render);
+ }
+ }
+ BLI_freelistN( &re1->freestyle_renders );
+ }
+}
+#endif
/* reads all buffers, calls optional composite, merges in first result->rectf */
static void do_merge_fullsample(Render *re, bNodeTree *ntree)
@@ -1462,6 +1546,10 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
if (sample) {
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
render_result_exr_file_read(re1, sample);
+#ifdef WITH_FREESTYLE
+ if( re1->r.mode & R_EDGE_FRS)
+ composite_freestyle_renders(re1, sample);
+#endif
BLI_rw_mutex_unlock(&re->resultmutex);
}
ntreeCompositTagRender(re1->scene); /* ensure node gets exec to put buffers on stack */
@@ -1664,6 +1752,10 @@ static void do_render_composite_fields_blur_3d(Render *re)
do_merge_fullsample(re, NULL);
}
+#ifdef WITH_FREESTYLE
+ free_all_freestyle_renders(re->scene);
+#endif
+
/* weak... the display callback wants an active renderlayer pointer... */
re->result->renlay = render_get_active_layer(re, re->result);
re->display_draw(re->ddh, re->result, NULL);
@@ -2140,6 +2232,17 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr
G.is_rendering = FALSE;
}
+#ifdef WITH_FREESTYLE
+void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene)
+{
+ re->result_ok= 0;
+ if(render_initialize_from_main(re, bmain, scene, NULL, NULL, scene->lay, 0, 0)) {
+ do_render_fields_blur_3d(re);
+ }
+ re->result_ok= 1;
+}
+#endif
+
static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovieHandle *mh, const char *name_override)
{
char name[FILE_MAX];
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index 35b06385ae6..62919297e73 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -57,6 +57,10 @@
#include "render_result.h"
#include "render_types.h"
+#ifdef WITH_FREESTYLE
+# include "FRS_freestyle_config.h"
+#endif
+
/********************************** Free *************************************/
void render_result_free(RenderResult *res)
@@ -564,6 +568,9 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
rl->lay = (1 << 20) - 1;
rl->layflag = 0x7FFF; /* solid ztra halo strand */
rl->passflag = SCE_PASS_COMBINED;
+#ifdef WITH_FREESTYLE
+ FRS_add_freestyle_config( srl );
+#endif
re->r.actlay = 0;
}
diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c
index 2d26ebe2b91..003e74bd69a 100644
--- a/source/blender/render/intern/source/shadeoutput.c
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -1713,6 +1713,14 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
if (ma->mode & (MA_FACETEXTURE_ALPHA))
shi->alpha= shi->vcol[3];
}
+#ifdef WITH_FREESTYLE
+ else if (ma->vcol_alpha) {
+ shi->r= shi->vcol[0];
+ shi->g= shi->vcol[1];
+ shi->b= shi->vcol[2];
+ shi->alpha= shi->vcol[3];
+ }
+#endif
else if (ma->mode & (MA_VERTEXCOLP)) {
float neg_alpha = 1.0f - shi->vcol[3];
shi->r= shi->r*neg_alpha + shi->vcol[0]*shi->vcol[3];