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:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2014-05-03 13:51:53 +0400
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2014-05-03 13:54:59 +0400
commitb7f085d9c128f31d576c732c6439b5a71e8922ee (patch)
tree8a1fdc2e95470f61d9121b18b125dc272e87d536 /source/blender
parent6ec2d72eca618be05e9bf0723886b10e6d5efa46 (diff)
Patch D246: Texture Marks for freestyle strokes, written and contributed by Paolo Acampora.
Reviewers: brecht, kjym3, #freestyle Reviewed By: brecht, kjym3 Differential Revision: https://developer.blender.org/D246
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_context.h1
-rw-r--r--source/blender/blenkernel/BKE_node.h2
-rw-r--r--source/blender/blenkernel/BKE_texture.h3
-rw-r--r--source/blender/blenkernel/intern/context.c14
-rw-r--r--source/blender/blenkernel/intern/library.c2
-rw-r--r--source/blender/blenkernel/intern/library_query.c14
-rw-r--r--source/blender/blenkernel/intern/linestyle.c30
-rw-r--r--source/blender/blenkernel/intern/node.c8
-rw-r--r--source/blender/blenkernel/intern/texture.c43
-rw-r--r--source/blender/blenloader/intern/readfile.c33
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.c3
-rw-r--r--source/blender/blenloader/intern/writefile.c8
-rw-r--r--source/blender/editors/include/ED_buttons.h1
-rw-r--r--source/blender/editors/interface/interface_templates.c11
-rw-r--r--source/blender/editors/render/render_shading.c11
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c79
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c24
-rw-r--r--source/blender/editors/space_node/node_draw.c3
-rw-r--r--source/blender/freestyle/CMakeLists.txt4
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp187
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h1
-rw-r--r--source/blender/freestyle/intern/python/BPy_Freestyle.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_StrokeShader.cpp12
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp125
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.h57
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp114
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.h55
-rw-r--r--source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp11
-rw-r--r--source/blender/freestyle/intern/stroke/BasicStrokeShaders.h58
-rw-r--r--source/blender/freestyle/intern/stroke/Stroke.cpp13
-rw-r--r--source/blender/freestyle/intern/stroke/Stroke.h36
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeRep.cpp242
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeRep.h51
-rw-r--r--source/blender/makesdna/DNA_linestyle_types.h20
-rw-r--r--source/blender/makesdna/DNA_space_types.h2
-rw-r--r--source/blender/makesdna/DNA_texture_types.h1
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/intern/rna_linestyle.c168
-rw-r--r--source/blender/makesrna/intern/rna_space.c6
-rw-r--r--source/blender/nodes/texture/node_texture_tree.c13
40 files changed, 1279 insertions, 190 deletions
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 877e376b343..e30c8ecee2b 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -234,6 +234,7 @@ int ctx_data_list_count(const bContext *C, int (*func)(const bContext *, ListBas
struct Main *CTX_data_main(const bContext *C);
struct Scene *CTX_data_scene(const bContext *C);
struct ToolSettings *CTX_data_tool_settings(const bContext *C);
+struct FreestyleLineStyle *CTX_data_linestyle_from_scene(struct Scene *scene);
const char *CTX_data_mode_string(const bContext *C);
int CTX_data_mode_enum(const bContext *C);
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 1d76cabf78b..13a32ee1528 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -44,6 +44,7 @@
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
#include "DNA_world_types.h"
+#include "DNA_linestyle_types.h"
#include "RNA_types.h"
@@ -632,6 +633,7 @@ struct NodeTreeIterStore {
Tex *tex;
Lamp *lamp;
World *world;
+ FreestyleLineStyle *linestyle;
};
void BKE_node_tree_iter_init(struct NodeTreeIterStore *ntreeiter, struct Main *bmain);
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h
index c136a30595d..4ad84dceb53 100644
--- a/source/blender/blenkernel/BKE_texture.h
+++ b/source/blender/blenkernel/BKE_texture.h
@@ -41,6 +41,7 @@ struct bNode;
struct Brush;
struct ColorBand;
struct EnvMap;
+struct FreestyleLineStyle;
struct HaloRen;
struct Lamp;
struct LampRen;
@@ -85,6 +86,7 @@ void BKE_texture_make_local(struct Tex *tex);
struct Tex *give_current_object_texture(struct Object *ob);
struct Tex *give_current_material_texture(struct Material *ma);
struct Tex *give_current_lamp_texture(struct Lamp *la);
+struct Tex *give_current_linestyle_texture(struct FreestyleLineStyle *linestyle);
struct Tex *give_current_world_texture(struct World *world);
struct Tex *give_current_brush_texture(struct Brush *br);
struct Tex *give_current_particle_texture(struct ParticleSettings *part);
@@ -98,6 +100,7 @@ void set_current_brush_texture(struct Brush *br, struct Tex *tex);
void set_current_world_texture(struct World *wo, struct Tex *tex);
void set_current_material_texture(struct Material *ma, struct Tex *tex);
void set_current_lamp_texture(struct Lamp *la, struct Tex *tex);
+void set_current_linestyle_texture(struct FreestyleLineStyle *linestyle, struct Tex *tex);
void set_current_particle_texture(struct ParticleSettings *part, struct Tex *tex);
bool has_current_material_texture(struct Material *ma);
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index f3ee5c5440c..89ba2e9d68b 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -36,6 +36,7 @@
#include "DNA_view3d_types.h"
#include "DNA_windowmanager_types.h"
#include "DNA_object_types.h"
+#include "DNA_linestyle_types.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
@@ -47,6 +48,7 @@
#include "BKE_context.h"
#include "BKE_main.h"
#include "BKE_screen.h"
+#include "BKE_freestyle.h"
#include "RNA_access.h"
@@ -1090,3 +1092,15 @@ int CTX_data_visible_pose_bones(const bContext *C, ListBase *list)
return ctx_data_collection_get(C, "visible_pose_bones", list);
}
+FreestyleLineStyle *CTX_data_linestyle_from_scene(Scene *scene)
+{
+ SceneRenderLayer *actsrl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+ FreestyleConfig *config = &actsrl->freestyleConfig;
+ FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(config);
+
+ if (lineset) {
+ return lineset->linestyle;
+ }
+
+ return NULL;
+}
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index a899f81b0d6..6306971a612 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -52,6 +52,7 @@
#include "DNA_key_types.h"
#include "DNA_lamp_types.h"
#include "DNA_lattice_types.h"
+#include "DNA_linestyle_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meta_types.h"
@@ -1364,6 +1365,7 @@ void id_clear_lib_data(Main *bmain, ID *id)
case ID_LA: ntree = ((Lamp *)id)->nodetree; break;
case ID_WO: ntree = ((World *)id)->nodetree; break;
case ID_TE: ntree = ((Tex *)id)->nodetree; break;
+ case ID_LS: ntree = ((FreestyleLineStyle *)id)->nodetree; break;
}
if (ntree)
ntree->id.lib = NULL;
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
index b59cc74f69e..e9bdc3679c1 100644
--- a/source/blender/blenkernel/intern/library_query.c
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -39,6 +39,7 @@
#include "DNA_key_types.h"
#include "DNA_lamp_types.h"
#include "DNA_lattice_types.h"
+#include "DNA_linestyle_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meta_types.h"
@@ -450,6 +451,19 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
}
break;
}
+
+ case ID_LS:
+ {
+ FreestyleLineStyle *linestyle = (FreestyleLineStyle *) id;
+ for (i = 0; i < MAX_MTEX; i++) {
+ if (linestyle->mtex[i]) {
+ library_foreach_mtex(&data, linestyle->mtex[i]);
+ }
+ }
+ CALLBACK_INVOKE(linestyle->nodetree, IDWALK_NOP);
+ break;
+ }
+
}
#undef CALLBACK_INVOKE_ID
diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c
index 54ae0120c1b..ee55cf72419 100644
--- a/source/blender/blenkernel/intern/linestyle.c
+++ b/source/blender/blenkernel/intern/linestyle.c
@@ -46,6 +46,7 @@
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_linestyle.h"
+#include "BKE_node.h"
#include "BKE_texture.h"
#include "BKE_colortools.h"
#include "BKE_animsys.h"
@@ -80,7 +81,7 @@ static void default_linestyle_settings(FreestyleLineStyle *linestyle)
linestyle->thickness = 3.0f;
linestyle->thickness_position = LS_THICKNESS_CENTER;
linestyle->thickness_ratio = 0.5f;
- linestyle->flag = LS_SAME_OBJECT | LS_NO_SORTING;
+ linestyle->flag = LS_SAME_OBJECT | LS_NO_SORTING | LS_TEXTURE;
linestyle->chaining = LS_CHAINING_PLAIN;
linestyle->rounds = 3;
linestyle->min_angle = DEG2RADF(0.0f);
@@ -90,6 +91,7 @@ static void default_linestyle_settings(FreestyleLineStyle *linestyle)
linestyle->split_length = 100;
linestyle->sort_key = LS_SORT_KEY_DISTANCE_FROM_CAMERA;
linestyle->integration_type = LS_INTEGRATION_MEAN;
+ linestyle->texstep = 1.0f;
BLI_listbase_clear(&linestyle->color_modifiers);
BLI_listbase_clear(&linestyle->alpha_modifiers);
@@ -119,6 +121,19 @@ void BKE_free_linestyle(FreestyleLineStyle *linestyle)
{
LineStyleModifier *m;
+ MTex *mtex;
+ int a;
+
+ for (a = 0; a < MAX_MTEX; a++) {
+ mtex = linestyle->mtex[a];
+ if (mtex && mtex->tex) mtex->tex->id.us--;
+ if (mtex) MEM_freeN(mtex);
+ }
+ if (linestyle->nodetree) {
+ ntreeFreeTree(linestyle->nodetree);
+ MEM_freeN(linestyle->nodetree);
+ }
+
BKE_free_animdata(&linestyle->id);
while ((m = (LineStyleModifier *)linestyle->color_modifiers.first))
BKE_remove_linestyle_color_modifier(linestyle, m);
@@ -134,10 +149,22 @@ FreestyleLineStyle *BKE_copy_linestyle(FreestyleLineStyle *linestyle)
{
FreestyleLineStyle *new_linestyle;
LineStyleModifier *m;
+ int a;
new_linestyle = BKE_new_linestyle(linestyle->id.name + 2, NULL);
BKE_free_linestyle(new_linestyle);
+ for (a = 0; a < MAX_MTEX; a++) {
+ if (linestyle->mtex[a]) {
+ new_linestyle->mtex[a] = MEM_mallocN(sizeof(MTex), "BKE_copy_linestyle");
+ memcpy(new_linestyle->mtex[a], linestyle->mtex[a], sizeof(MTex));
+ id_us_plus((ID *)new_linestyle->mtex[a]->tex);
+ }
+ }
+ if (linestyle->nodetree) {
+ linestyle->nodetree = ntreeCopyTree(linestyle->nodetree);
+ }
+
new_linestyle->r = linestyle->r;
new_linestyle->g = linestyle->g;
new_linestyle->b = linestyle->b;
@@ -167,6 +194,7 @@ FreestyleLineStyle *BKE_copy_linestyle(FreestyleLineStyle *linestyle)
new_linestyle->dash3 = linestyle->dash3;
new_linestyle->gap3 = linestyle->gap3;
new_linestyle->panel = linestyle->panel;
+ new_linestyle->texstep = linestyle->texstep;
for (m = (LineStyleModifier *)linestyle->color_modifiers.first; m; m = m->next)
BKE_copy_linestyle_color_modifier(new_linestyle, m);
for (m = (LineStyleModifier *)linestyle->alpha_modifiers.first; m; m = m->next)
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index db65e8c30d4..38dd36b9e6a 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -44,6 +44,7 @@
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
#include "DNA_world_types.h"
+#include "DNA_linestyle_types.h"
#include "BLI_string.h"
#include "BLI_math.h"
@@ -1866,6 +1867,7 @@ bNodeTree *ntreeFromID(ID *id)
case ID_WO: return ((World *)id)->nodetree;
case ID_TE: return ((Tex *)id)->nodetree;
case ID_SCE: return ((Scene *)id)->nodetree;
+ case ID_LS: return ((FreestyleLineStyle *)id)->nodetree;
default: return NULL;
}
}
@@ -3661,6 +3663,7 @@ void BKE_node_tree_iter_init(struct NodeTreeIterStore *ntreeiter, struct Main *b
ntreeiter->tex = bmain->tex.first;
ntreeiter->lamp = bmain->lamp.first;
ntreeiter->world = bmain->world.first;
+ ntreeiter->linestyle = bmain->linestyle.first;
}
bool BKE_node_tree_iter_step(struct NodeTreeIterStore *ntreeiter,
bNodeTree **r_nodetree, struct ID **r_id)
@@ -3695,6 +3698,11 @@ bool BKE_node_tree_iter_step(struct NodeTreeIterStore *ntreeiter,
*r_id = (ID *)ntreeiter->world;
ntreeiter->world = ntreeiter->world->id.next;
}
+ else if (ntreeiter->linestyle) {
+ *r_nodetree = ntreeiter->linestyle->nodetree;
+ *r_id = (ID *)ntreeiter->linestyle;
+ ntreeiter->linestyle = ntreeiter->linestyle->id.next;
+ }
else {
return false;
}
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 75f2fd121dc..3e95da622ac 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -51,6 +51,7 @@
#include "DNA_node_types.h"
#include "DNA_color_types.h"
#include "DNA_particle_types.h"
+#include "DNA_linestyle_types.h"
#include "IMB_imbuf.h"
@@ -999,6 +1000,41 @@ void set_current_lamp_texture(Lamp *la, Tex *newtex)
}
}
+Tex *give_current_linestyle_texture(FreestyleLineStyle *linestyle)
+{
+ MTex *mtex = NULL;
+ Tex *tex = NULL;
+
+ if (linestyle) {
+ mtex = linestyle->mtex[(int)(linestyle->texact)];
+ if (mtex) tex = mtex->tex;
+ }
+
+ return tex;
+}
+
+void set_current_linestyle_texture(FreestyleLineStyle *linestyle, Tex *newtex)
+{
+ int act = linestyle->texact;
+
+ if (linestyle->mtex[act] && linestyle->mtex[act]->tex)
+ id_us_min(&linestyle->mtex[act]->tex->id);
+
+ if (newtex) {
+ if (!linestyle->mtex[act]) {
+ linestyle->mtex[act] = add_mtex();
+ linestyle->mtex[act]->texco = TEXCO_STROKE;
+ }
+
+ linestyle->mtex[act]->tex = newtex;
+ id_us_plus(&newtex->id);
+ }
+ else if (linestyle->mtex[act]) {
+ MEM_freeN(linestyle->mtex[act]);
+ linestyle->mtex[act] = NULL;
+ }
+}
+
bNode *give_current_material_texture_node(Material *ma)
{
if (ma && ma->use_nodes && ma->nodetree)
@@ -1048,6 +1084,10 @@ bool give_active_mtex(ID *id, MTex ***mtex_ar, short *act)
*mtex_ar = ((Lamp *)id)->mtex;
if (act) *act = (((Lamp *)id)->texact);
break;
+ case ID_LS:
+ *mtex_ar = ((FreestyleLineStyle *)id)->mtex;
+ if (act) *act = (((FreestyleLineStyle *)id)->texact);
+ break;
case ID_PA:
*mtex_ar = ((ParticleSettings *)id)->mtex;
if (act) *act = (((ParticleSettings *)id)->texact);
@@ -1076,6 +1116,9 @@ void set_active_mtex(ID *id, short act)
case ID_LA:
((Lamp *)id)->texact = act;
break;
+ case ID_LS:
+ ((FreestyleLineStyle *)id)->texact = act;
+ break;
case ID_PA:
((ParticleSettings *)id)->texact = act;
break;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 7dfe476ce0a..a4f26017636 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2380,6 +2380,7 @@ static bNodeTree *nodetree_from_id(ID *id)
case ID_WO: return ((World *)id)->nodetree;
case ID_LA: return ((Lamp *)id)->nodetree;
case ID_TE: return ((Tex *)id)->nodetree;
+ case ID_LS: return ((FreestyleLineStyle *)id)->nodetree;
}
return NULL;
}
@@ -6910,6 +6911,8 @@ static void lib_link_linestyle(FileData *fd, Main *main)
{
FreestyleLineStyle *linestyle;
LineStyleModifier *m;
+ MTex *mtex;
+ int a;
linestyle = main->linestyle.first;
while (linestyle) {
@@ -6950,6 +6953,17 @@ static void lib_link_linestyle(FileData *fd, Main *main)
break;
}
}
+ for (a=0; a < MAX_MTEX; a++) {
+ mtex = linestyle->mtex[a];
+ if (mtex) {
+ mtex->tex = newlibadr_us(fd, linestyle->id.lib, mtex->tex);
+ mtex->object = newlibadr(fd, linestyle->id.lib, mtex->object);
+ }
+ }
+ if (linestyle->nodetree) {
+ lib_link_ntree(fd, &linestyle->id, linestyle->nodetree);
+ linestyle->nodetree->id.lib = linestyle->id.lib;
+ }
}
linestyle = linestyle->id.next;
}
@@ -7059,6 +7073,7 @@ static void direct_link_linestyle_geometry_modifier(FileData *UNUSED(fd), LineSt
static void direct_link_linestyle(FileData *fd, FreestyleLineStyle *linestyle)
{
+ int a;
LineStyleModifier *modifier;
linestyle->adt= newdataadr(fd, linestyle->adt);
@@ -7075,6 +7090,14 @@ static void direct_link_linestyle(FileData *fd, FreestyleLineStyle *linestyle)
link_list(fd, &linestyle->geometry_modifiers);
for (modifier = linestyle->geometry_modifiers.first; modifier; modifier = modifier->next)
direct_link_linestyle_geometry_modifier(fd, modifier);
+ for (a = 0; a < MAX_MTEX; a++) {
+ linestyle->mtex[a] = newdataadr(fd, linestyle->mtex[a]);
+ }
+ linestyle->nodetree = newdataadr(fd, linestyle->nodetree);
+ if (linestyle->nodetree) {
+ direct_link_id(fd, &linestyle->nodetree->id);
+ direct_link_nodetree(fd, linestyle->nodetree);
+ }
}
/* ************** GENERAL & MAIN ******************** */
@@ -8562,8 +8585,18 @@ static void expand_mask(FileData *fd, Main *mainvar, Mask *mask)
static void expand_linestyle(FileData *fd, Main *mainvar, FreestyleLineStyle *linestyle)
{
+ int a;
LineStyleModifier *m;
+ for (a = 0; a < MAX_MTEX; a++) {
+ if (linestyle->mtex[a]) {
+ expand_doit(fd, mainvar, linestyle->mtex[a]->tex);
+ expand_doit(fd, mainvar, linestyle->mtex[a]->object);
+ }
+ }
+ if (linestyle->nodetree)
+ expand_nodetree(fd, mainvar, linestyle->nodetree);
+
if (linestyle->adt)
expand_animdata(fd, mainvar, linestyle->adt);
for (m = linestyle->color_modifiers.first; m; m = m->next) {
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index b455ef016b2..1e881eb11f9 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -60,9 +60,10 @@ void BLO_update_defaults_startup_blend(Main *main)
}
for (linestyle = main->linestyle.first; linestyle; linestyle = linestyle->id.next) {
- linestyle->flag = LS_SAME_OBJECT | LS_NO_SORTING;
+ linestyle->flag = LS_SAME_OBJECT | LS_NO_SORTING | LS_TEXTURE;
linestyle->sort_key = LS_SORT_KEY_DISTANCE_FROM_CAMERA;
linestyle->integration_type = LS_INTEGRATION_MEAN;
+ linestyle->texstep = 1.0;
}
{
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 3fd6ff7673c..45139789f1e 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -3248,6 +3248,7 @@ static void write_linestyle_geometry_modifiers(WriteData *wd, ListBase *modifier
static void write_linestyles(WriteData *wd, ListBase *idbase)
{
FreestyleLineStyle *linestyle;
+ int a;
for (linestyle = idbase->first; linestyle; linestyle = linestyle->id.next) {
if (linestyle->id.us>0 || wd->current) {
@@ -3260,6 +3261,13 @@ static void write_linestyles(WriteData *wd, ListBase *idbase)
write_linestyle_alpha_modifiers(wd, &linestyle->alpha_modifiers);
write_linestyle_thickness_modifiers(wd, &linestyle->thickness_modifiers);
write_linestyle_geometry_modifiers(wd, &linestyle->geometry_modifiers);
+ for (a=0; a<MAX_MTEX; a++) {
+ if (linestyle->mtex[a]) writestruct(wd, DATA, "MTex", 1, linestyle->mtex[a]);
+ }
+ if (linestyle->nodetree) {
+ writestruct(wd, DATA, "bNodeTree", 1, linestyle->nodetree);
+ write_nodetree(wd, linestyle->nodetree);
+ }
}
}
}
diff --git a/source/blender/editors/include/ED_buttons.h b/source/blender/editors/include/ED_buttons.h
index 5cc399fdcee..0e245c71609 100644
--- a/source/blender/editors/include/ED_buttons.h
+++ b/source/blender/editors/include/ED_buttons.h
@@ -34,6 +34,7 @@ bool ED_texture_context_check_world(const struct bContext *C);
bool ED_texture_context_check_material(const struct bContext *C);
bool ED_texture_context_check_lamp(const struct bContext *C);
bool ED_texture_context_check_particles(const struct bContext *C);
+bool ED_texture_context_check_linestyle(const bContext *C);
bool ED_texture_context_check_others(const struct bContext *C);
#endif /* __ED_BUTTONS_H__ */
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 3b2dae2b8ba..10b25420ab7 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -54,6 +54,7 @@
#include "BKE_global.h"
#include "BKE_idcode.h"
#include "BKE_library.h"
+#include "BKE_linestyle.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
@@ -1302,8 +1303,8 @@ void uiTemplatePreview(uiLayout *layout, bContext *C, ID *id, int show_buttons,
char _preview_id[UI_MAX_NAME_STR];
- if (id && !ELEM4(GS(id->name), ID_MA, ID_TE, ID_WO, ID_LA)) {
- RNA_warning("Expected ID of type material, texture, lamp or world");
+ if (id && !ELEM5(GS(id->name), ID_MA, ID_TE, ID_WO, ID_LA, ID_LS)) {
+ RNA_warning("Expected ID of type material, texture, lamp, world or line style");
return;
}
@@ -1318,6 +1319,8 @@ void uiTemplatePreview(uiLayout *layout, bContext *C, ID *id, int show_buttons,
pr_texture = &((World *)parent)->pr_texture;
else if (parent && (GS(parent->name) == ID_LA))
pr_texture = &((Lamp *)parent)->pr_texture;
+ else if (parent && (GS(parent->name) == ID_LS))
+ pr_texture = &((FreestyleLineStyle *)parent)->pr_texture;
if (pr_texture) {
if (*pr_texture == TEX_PR_OTHER)
@@ -1398,6 +1401,10 @@ void uiTemplatePreview(uiLayout *layout, bContext *C, ID *id, int show_buttons,
uiDefButS(block, ROW, B_MATPRV, IFACE_("World"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
}
+ else if (GS(parent->name) == ID_LS) {
+ uiDefButS(block, ROW, B_MATPRV, IFACE_("Line Style"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
+ pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
+ }
uiDefButS(block, ROW, B_MATPRV, IFACE_("Both"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
pr_texture, 10, TEX_PR_BOTH, 0, 0, "");
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 8babd4d32d9..73659db8910 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -1575,6 +1575,9 @@ static void copy_mtex_copybuf(ID *id)
case ID_PA:
mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]);
break;
+ case ID_LS:
+ mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]);
+ break;
}
if (mtex && *mtex) {
@@ -1608,6 +1611,9 @@ static void paste_mtex_copybuf(ID *id)
case ID_PA:
mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]);
break;
+ case ID_LS:
+ mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]);
+ break;
default:
BLI_assert("invalid id type");
return;
@@ -1674,7 +1680,8 @@ static int paste_mtex_exec(bContext *C, wmOperator *UNUSED(op))
Lamp *la = CTX_data_pointer_get_type(C, "lamp", &RNA_Lamp).data;
World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data;
ParticleSystem *psys = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data;
-
+ FreestyleLineStyle *linestyle = CTX_data_pointer_get_type(C, "line_style", &RNA_FreestyleLineStyle).data;
+
if (ma)
id = &ma->id;
else if (la)
@@ -1683,6 +1690,8 @@ static int paste_mtex_exec(bContext *C, wmOperator *UNUSED(op))
id = &wo->id;
else if (psys)
id = &psys->part->id;
+ else if (linestyle)
+ id = &linestyle->id;
if (id == NULL)
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index 895c38747c1..3f5d7de5cd0 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -45,6 +45,7 @@
#include "DNA_scene_types.h"
#include "DNA_world_types.h"
#include "DNA_brush_types.h"
+#include "DNA_linestyle_types.h"
#include "BKE_context.h"
#include "BKE_action.h"
@@ -139,6 +140,30 @@ static int buttons_context_path_world(ButsContextPath *path)
return 0;
}
+static int buttons_context_path_linestyle(ButsContextPath *path)
+{
+ Scene *scene;
+ FreestyleLineStyle *linestyle;
+ PointerRNA *ptr = &path->ptr[path->len - 1];
+
+ /* if we already have a (pinned) linestyle, we're done */
+ if (RNA_struct_is_a(ptr->type, &RNA_FreestyleLineStyle)) {
+ return 1;
+ }
+ /* if we have a scene, use the lineset's linestyle */
+ else if (buttons_context_path_scene(path)) {
+ scene = path->ptr[path->len - 1].data;
+ linestyle = CTX_data_linestyle_from_scene(scene);
+ if (linestyle) {
+ RNA_id_pointer_create(&linestyle->id, &path->ptr[path->len]);
+ path->len++;
+ return 1;
+ }
+ }
+
+ /* no path to a linestyle possible */
+ return 0;
+}
static int buttons_context_path_object(ButsContextPath *path)
{
@@ -395,6 +420,8 @@ static int buttons_context_path_texture(ButsContextPath *path, ButsContextTextur
buttons_context_path_particle(path);
else if (GS(id->name) == ID_OB)
buttons_context_path_object(path);
+ else if (GS(id->name) == ID_LS)
+ buttons_context_path_linestyle(path);
}
if (ct->texture) {
@@ -410,6 +437,7 @@ static int buttons_context_path_texture(ButsContextPath *path, ButsContextTextur
Lamp *la;
World *wo;
ParticleSystem *psys;
+ FreestyleLineStyle *ls;
Tex *tex;
PointerRNA *ptr = &path->ptr[path->len - 1];
@@ -475,12 +503,40 @@ static int buttons_context_path_texture(ButsContextPath *path, ButsContextTextur
return 1;
}
}
+ /* try linestyle */
+ else if ((path->tex_ctx == SB_TEXC_LINESTYLE) && buttons_context_path_linestyle(path)) {
+ ls = path->ptr[path->len - 1].data;
+
+ if (ls) {
+ tex = give_current_linestyle_texture(ls);
+
+ RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
+ path->len++;
+ return 1;
+ }
+ }
}
/* no path to a texture possible */
return 0;
}
+static bool buttons_context_linestyle_pinnable(const bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ SpaceButs *sbuts;
+
+ /* if Freestyle is disabled in the scene */
+ if ((scene->r.mode & R_EDGE_FRS) == 0) {
+ return false;
+ }
+ /* if the scene has already been pinned */
+ sbuts = CTX_wm_space_buts(C);
+ if (sbuts->pinid && sbuts->pinid == &scene->id) {
+ return false;
+ }
+ return true;
+}
static int buttons_context_path(const bContext *C, ButsContextPath *path, int mainb, int flag)
{
@@ -512,7 +568,17 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma
switch (mainb) {
case BCONTEXT_SCENE:
case BCONTEXT_RENDER:
+ found = buttons_context_path_scene(path);
+ break;
case BCONTEXT_RENDER_LAYER:
+#ifdef WITH_FREESTYLE
+ if (buttons_context_linestyle_pinnable(C)) {
+ found = buttons_context_path_linestyle(path);
+ if (found) {
+ break;
+ }
+ }
+#endif
found = buttons_context_path_scene(path);
break;
case BCONTEXT_WORLD:
@@ -662,7 +728,8 @@ const char *buttons_context_dir[] = {
"meta_ball", "lamp", "speaker", "camera", "material", "material_slot",
"texture", "texture_user", "texture_user_property", "bone", "edit_bone",
"pose_bone", "particle_system", "particle_system_editable", "particle_settings",
- "cloth", "soft_body", "fluid", "smoke", "collision", "brush", "dynamic_paint", NULL
+ "cloth", "soft_body", "fluid", "smoke", "collision", "brush", "dynamic_paint",
+ "line_style", NULL
};
int buttons_context(const bContext *C, const char *member, bContextDataResult *result)
@@ -860,6 +927,12 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
if (wo)
CTX_data_pointer_set(result, &wo->id, &RNA_WorldTextureSlot, wo->mtex[(int)wo->texact]);
}
+ else if ((ptr = get_pointer_type(path, &RNA_FreestyleLineStyle))) {
+ FreestyleLineStyle *ls = ptr->data;
+
+ if (ls)
+ CTX_data_pointer_set(result, &ls->id, &RNA_LineStyleTextureSlot, ls->mtex[(int)ls->texact]);
+ }
return 1;
}
@@ -972,6 +1045,10 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
return 1;
}
}
+ else if (CTX_data_equals(member, "line_style")) {
+ set_pointer_type(path, result, &RNA_FreestyleLineStyle);
+ return 1;
+ }
else {
return 0; /* not found */
}
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 7c42ea9a13b..4ba0ddaed50 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -51,6 +51,8 @@
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_world_types.h"
+#include "DNA_linestyle_types.h"
+
#include "BKE_context.h"
#include "BKE_material.h"
@@ -99,6 +101,13 @@ bool ED_texture_context_check_particles(const bContext *C)
return (ob && ob->particlesystem.first);
}
+bool ED_texture_context_check_linestyle(const bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ FreestyleLineStyle *ls = CTX_data_linestyle_from_scene(scene);
+ return (scene && (scene->r.mode & R_EDGE_FRS) && ls && (ls->flag & LS_TEXTURE));
+}
+
static void texture_context_check_modifier_foreach(void *userData, Object *UNUSED(ob), ModifierData *UNUSED(md),
const char *UNUSED(propname))
{
@@ -148,6 +157,7 @@ static void set_texture_context(const bContext *C, SpaceButs *sbuts)
bool valid_material = ED_texture_context_check_material(C);
bool valid_lamp = ED_texture_context_check_lamp(C);
bool valid_particles = ED_texture_context_check_particles(C);
+ bool valid_linestyle = ED_texture_context_check_linestyle(C);
bool valid_others = ED_texture_context_check_others(C);
/* this is similar to direct user action, no need to keep "better" ctxt in _prev */
@@ -163,6 +173,9 @@ static void set_texture_context(const bContext *C, SpaceButs *sbuts)
else if ((sbuts->mainb == BCONTEXT_PARTICLE) && valid_particles) {
sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_PARTICLES;
}
+ else if ((sbuts->mainb == BCONTEXT_RENDER_LAYER) && valid_linestyle) {
+ sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_LINESTYLE;
+ }
else if ((ELEM(sbuts->mainb, BCONTEXT_MODIFIER, BCONTEXT_PHYSICS)) && valid_others) {
sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_OTHER;
}
@@ -172,6 +185,7 @@ static void set_texture_context(const bContext *C, SpaceButs *sbuts)
((sbuts->texture_context_prev == SB_TEXC_MATERIAL) && valid_material) ||
((sbuts->texture_context_prev == SB_TEXC_LAMP) && valid_lamp) ||
((sbuts->texture_context_prev == SB_TEXC_PARTICLES) && valid_particles) ||
+ ((sbuts->texture_context_prev == SB_TEXC_LINESTYLE) && valid_linestyle) ||
((sbuts->texture_context_prev == SB_TEXC_OTHER) && valid_others)))
{
sbuts->texture_context = sbuts->texture_context_prev;
@@ -181,6 +195,7 @@ static void set_texture_context(const bContext *C, SpaceButs *sbuts)
((sbuts->texture_context == SB_TEXC_MATERIAL) && !valid_material) ||
((sbuts->texture_context == SB_TEXC_LAMP) && !valid_lamp) ||
((sbuts->texture_context == SB_TEXC_PARTICLES) && !valid_particles) ||
+ ((sbuts->texture_context == SB_TEXC_LINESTYLE) && !valid_linestyle) ||
((sbuts->texture_context == SB_TEXC_OTHER) && !valid_others))
{
/* this is default fallback, do keep "better" ctxt in _prev */
@@ -194,6 +209,9 @@ static void set_texture_context(const bContext *C, SpaceButs *sbuts)
else if (valid_particles) {
sbuts->texture_context = SB_TEXC_PARTICLES;
}
+ else if (valid_linestyle) {
+ sbuts->texture_context = SB_TEXC_LINESTYLE;
+ }
else if (valid_world) {
sbuts->texture_context = SB_TEXC_WORLD;
}
@@ -284,6 +302,7 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext *
Material *ma = NULL;
Lamp *la = NULL;
World *wrld = NULL;
+ FreestyleLineStyle *linestyle = NULL;
Brush *brush = NULL;
ID *pinid = sbuts->pinid;
bool limited_mode = (sbuts->flag & SB_TEX_USER_LIMITED) != 0;
@@ -302,6 +321,8 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext *
ma = (Material *)pinid;
else if (GS(pinid->name) == ID_BR)
brush = (Brush *)pinid;
+ else if (GS(pinid->name) == ID_LS)
+ linestyle = (FreestyleLineStyle *)pinid;
}
if (!scene)
@@ -311,6 +332,7 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext *
ob = (scene->basact) ? scene->basact->object : NULL;
wrld = scene->world;
brush = BKE_paint_brush(BKE_paint_get_active_from_context(C));
+ linestyle = CTX_data_linestyle_from_scene(scene);
}
if (ob && ob->type == OB_LAMP && !la)
@@ -327,6 +349,8 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext *
buttons_texture_users_find_nodetree(users, &la->id, la->nodetree, "Lamp");
if (wrld && !limited_mode)
buttons_texture_users_find_nodetree(users, &wrld->id, wrld->nodetree, "World");
+ if (linestyle && !limited_mode)
+ buttons_texture_users_find_nodetree(users, &linestyle->id, linestyle->nodetree, "LineStyle");
if (ob) {
ParticleSystem *psys = psys_get_current(ob);
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 55a95d34977..b3cf5ce0c81 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -36,6 +36,7 @@
#include "DNA_space_types.h"
#include "DNA_texture_types.h"
#include "DNA_world_types.h"
+#include "DNA_linestyle_types.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
@@ -106,6 +107,8 @@ static bNodeTree *node_tree_from_ID(ID *id)
return ((Scene *)id)->nodetree;
case ID_TE:
return ((Tex *)id)->nodetree;
+ case ID_LS:
+ return ((FreestyleLineStyle *)id)->nodetree;
}
}
diff --git a/source/blender/freestyle/CMakeLists.txt b/source/blender/freestyle/CMakeLists.txt
index 5edb74b89db..c786a2d5d35 100644
--- a/source/blender/freestyle/CMakeLists.txt
+++ b/source/blender/freestyle/CMakeLists.txt
@@ -185,6 +185,8 @@ set(SRC
intern/python/StrokeShader/BPy_BackboneStretcherShader.h
intern/python/StrokeShader/BPy_BezierCurveShader.cpp
intern/python/StrokeShader/BPy_BezierCurveShader.h
+ intern/python/StrokeShader/BPy_BlenderTextureShader.cpp
+ intern/python/StrokeShader/BPy_BlenderTextureShader.h
intern/python/StrokeShader/BPy_CalligraphicShader.cpp
intern/python/StrokeShader/BPy_CalligraphicShader.h
intern/python/StrokeShader/BPy_ColorNoiseShader.cpp
@@ -213,6 +215,8 @@ set(SRC
intern/python/StrokeShader/BPy_SpatialNoiseShader.h
intern/python/StrokeShader/BPy_StrokeTextureShader.cpp
intern/python/StrokeShader/BPy_StrokeTextureShader.h
+ intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp
+ intern/python/StrokeShader/BPy_StrokeTextureStepShader.h
intern/python/StrokeShader/BPy_TextureAssignerShader.cpp
intern/python/StrokeShader/BPy_TextureAssignerShader.h
intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
index 48bfe4ecdaf..93f720fc006 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
@@ -34,7 +34,6 @@ extern "C" {
#include "MEM_guardedalloc.h"
#include "DNA_camera_types.h"
-#include "DNA_customdata_types.h"
#include "DNA_listBase.h"
#include "DNA_meshdata_types.h"
#include "DNA_mesh_types.h"
@@ -137,19 +136,31 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : Str
freestyle_scene->camera = object_camera;
- // Material
- material = BKE_material_add(freestyle_bmain, "stroke_material");
- material->mode |= MA_VERTEXCOLP;
- material->mode |= MA_TRANSP;
- material->mode |= MA_SHLESS;
- material->vcol_alpha = 1;
-
// Reset serial mesh ID (used for BlenderStrokeRenderer::NewMesh())
_mesh_id = 0xffffffff;
}
BlenderStrokeRenderer::~BlenderStrokeRenderer()
{
+ // release materials
+ Link *lnk = (Link *)freestyle_bmain->mat.first;
+
+ while (lnk)
+ {
+ Material *ma = (Material*)lnk;
+ // We want to retain the linestyle mtexs, so let's detach them first
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (ma->mtex[a]) {
+ ma->mtex[a] = NULL;
+ }
+ else {
+ break; // Textures are ordered, no empty slots between two textures
+ }
+ }
+ lnk = lnk->next;
+ BKE_libblock_free(freestyle_bmain, ma);
+ }
+
if (0 != _textureManager) {
delete _textureManager;
_textureManager = NULL;
@@ -185,9 +196,6 @@ BlenderStrokeRenderer::~BlenderStrokeRenderer()
}
}
BLI_freelistN(&freestyle_scene->base);
-
- // release material
- BKE_libblock_free(freestyle_bmain, material);
}
float BlenderStrokeRenderer::get_stroke_vertex_z(void) const
@@ -210,6 +218,55 @@ unsigned int BlenderStrokeRenderer::get_stroke_mesh_id(void) const
void BlenderStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const
{
+ bool has_mat = false;
+ int a = 0;
+
+ // Look for a good existing material
+ for (Link *lnk = (Link *)freestyle_bmain->mat.first; lnk; lnk = lnk->next) {
+ Material *ma = (Material*) lnk;
+ bool texs_are_good = true;
+ // as soon as textures differ it's not the right one
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (ma->mtex[a] != iStrokeRep->getMTex(a)) {
+ texs_are_good = false;
+ break;
+ }
+ }
+
+ if (texs_are_good) {
+ iStrokeRep->setMaterial(ma);
+ has_mat = true;
+ break; // if textures are good, no need to search anymore
+ }
+ }
+
+ // If still no material, create one
+ if (!has_mat) {
+ Material *ma = BKE_material_add(freestyle_bmain, "stroke_material");
+
+ ma->mode |= MA_VERTEXCOLP;
+ ma->mode |= MA_TRANSP;
+ ma->mode |= MA_SHLESS;
+ ma->vcol_alpha = 1;
+
+ // Textures
+ //for (int a = 0; a < MAX_MTEX; a++) {
+ while (iStrokeRep->getMTex(a)) {
+ ma->mtex[a] = (MTex *) iStrokeRep->getMTex(a);
+
+ // We'll generate both with tips and without tips
+ // coordinates, on two different UV layers.
+ if (ma->mtex[a]->texflag & MTEX_TIPS) {
+ BLI_strncpy(ma->mtex[a]->uvname, "along_stroke_tips", sizeof(ma->mtex[a]->uvname));
+ }
+ else {
+ BLI_strncpy(ma->mtex[a]->uvname, "along_stroke", sizeof(ma->mtex[a]->uvname));
+ }
+ a++;
+ }
+ iStrokeRep->setMaterial(ma);
+ }
+
RenderStrokeRepBasic(iStrokeRep);
}
@@ -277,7 +334,7 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
#endif
Mesh *mesh = (Mesh *)object_mesh->data;
mesh->mat = (Material **)MEM_mallocN(1 * sizeof(Material *), "MaterialList");
- mesh->mat[0] = material;
+ mesh->mat[0] = iStrokeRep->getMaterial();
mesh->totcol = 1;
test_object_materials(freestyle_bmain, (ID *)mesh);
@@ -309,6 +366,7 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
MPoly *polys = mesh->mpoly;
MLoop *loops = mesh->mloop;
MLoopCol *colors = mesh->mloopcol;
+ MLoopUV *loopsuv[2];
v[0] = strip_vertices.begin();
v[1] = v[0] + 1;
@@ -317,6 +375,24 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
vertex_index = edge_index = loop_index = 0;
visible = false;
+ // First UV layer
+ CustomData_add_layer_named(&mesh->pdata, CD_MTEXPOLY, CD_CALLOC, NULL, mesh->totpoly, "along_stroke");
+ CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_CALLOC, NULL, mesh->totloop, "along_stroke");
+ CustomData_set_layer_active(&mesh->pdata, CD_MTEXPOLY, 0);
+ CustomData_set_layer_active(&mesh->ldata, CD_MLOOPUV, 0);
+ BKE_mesh_update_customdata_pointers(mesh, true);
+
+ loopsuv[0] = mesh->mloopuv;
+
+ // Second UV layer
+ CustomData_add_layer_named(&mesh->pdata, CD_MTEXPOLY, CD_CALLOC, NULL, mesh->totpoly, "along_stroke_tips");
+ CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_CALLOC, NULL, mesh->totloop, "along_stroke_tips");
+ CustomData_set_layer_active(&mesh->pdata, CD_MTEXPOLY, 1);
+ CustomData_set_layer_active(&mesh->ldata, CD_MLOOPUV, 1);
+ BKE_mesh_update_customdata_pointers(mesh, true);
+
+ loopsuv[1] = mesh->mloopuv;
+
// Note: Mesh generation in the following loop assumes stroke strips
// to be triangle strips.
for (n = 2; n < strip_vertex_count; n++, v[0]++, v[1]++, v[2]++) {
@@ -394,48 +470,67 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
polys->totloop = 3;
++polys;
+ // Even and odd loops connect triangles vertices differently
+ bool is_odd = n % 2;
// loops
- if (n % 2 == 0) {
+ if (is_odd) {
loops[0].v = vertex_index - 1;
- loops[0].e = edge_index - 1;
+ loops[0].e = edge_index - 2;
- loops[1].v = vertex_index - 2;
+ loops[1].v = vertex_index - 3;
loops[1].e = edge_index - 3;
- loops[2].v = vertex_index - 3;
- loops[2].e = edge_index - 2;
+ loops[2].v = vertex_index - 2;
+ loops[2].e = edge_index - 1;
}
else {
loops[0].v = vertex_index - 1;
- loops[0].e = edge_index - 2;
+ loops[0].e = edge_index - 1;
- loops[1].v = vertex_index - 3;
+ loops[1].v = vertex_index - 2;
loops[1].e = edge_index - 3;
- loops[2].v = vertex_index - 2;
- loops[2].e = edge_index - 1;
+ loops[2].v = vertex_index - 3;
+ loops[2].e = edge_index - 2;
}
loops += 3;
loop_index += 3;
- // colors
- if (n % 2 == 0) {
- colors[0].r = (short)(255.0f * svRep[2]->color()[0]);
- colors[0].g = (short)(255.0f * svRep[2]->color()[1]);
- colors[0].b = (short)(255.0f * svRep[2]->color()[2]);
- colors[0].a = (short)(255.0f * svRep[2]->alpha());
-
- colors[1].r = (short)(255.0f * svRep[1]->color()[0]);
- colors[1].g = (short)(255.0f * svRep[1]->color()[1]);
- colors[1].b = (short)(255.0f * svRep[1]->color()[2]);
- colors[1].a = (short)(255.0f * svRep[1]->alpha());
-
- colors[2].r = (short)(255.0f * svRep[0]->color()[0]);
- colors[2].g = (short)(255.0f * svRep[0]->color()[1]);
- colors[2].b = (short)(255.0f * svRep[0]->color()[2]);
- colors[2].a = (short)(255.0f * svRep[0]->alpha());
+ // UV
+ if (iStrokeRep->getMTex(0)) {
+ // First UV layer (loopsuv[0]) has no tips (texCoord(0)).
+ // Second UV layer (loopsuv[1]) has tips: (texCoord(1)).
+ for (int L = 0; L < 2; L++) {
+ if (is_odd) {
+ loopsuv[L][0].uv[0] = svRep[2]->texCoord(L).x();
+ loopsuv[L][0].uv[1] = svRep[2]->texCoord(L).y();
+
+ loopsuv[L][1].uv[0] = svRep[0]->texCoord(L).x();
+ loopsuv[L][1].uv[1] = svRep[0]->texCoord(L).y();
+
+ loopsuv[L][2].uv[0] = svRep[1]->texCoord(L).x();
+ loopsuv[L][2].uv[1] = svRep[1]->texCoord(L).y();
+ }
+ else {
+ loopsuv[L][0].uv[0] = svRep[2]->texCoord(L).x();
+ loopsuv[L][0].uv[1] = svRep[2]->texCoord(L).y();
+
+ loopsuv[L][1].uv[0] = svRep[1]->texCoord(L).x();
+ loopsuv[L][1].uv[1] = svRep[1]->texCoord(L).y();
+
+ loopsuv[L][2].uv[0] = svRep[0]->texCoord(L).x();
+ loopsuv[L][2].uv[1] = svRep[0]->texCoord(L).y();
+ }
+ /* freestyle tex-origin is upside-down */
+ for (int i = 0; i < 3; i++) {
+ loopsuv[L][i].uv[1] *= -1;
+ }
+ loopsuv[L] += 3;
+ }
}
- else {
+
+ // colors
+ if (is_odd) {
colors[0].r = (short)(255.0f * svRep[2]->color()[0]);
colors[0].g = (short)(255.0f * svRep[2]->color()[1]);
colors[0].b = (short)(255.0f * svRep[2]->color()[2]);
@@ -450,6 +545,22 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
colors[2].g = (short)(255.0f * svRep[1]->color()[1]);
colors[2].b = (short)(255.0f * svRep[1]->color()[2]);
colors[2].a = (short)(255.0f * svRep[1]->alpha());
+ }
+ else {
+ colors[0].r = (short)(255.0f * svRep[2]->color()[0]);
+ colors[0].g = (short)(255.0f * svRep[2]->color()[1]);
+ colors[0].b = (short)(255.0f * svRep[2]->color()[2]);
+ colors[0].a = (short)(255.0f * svRep[2]->alpha());
+
+ colors[1].r = (short)(255.0f * svRep[1]->color()[0]);
+ colors[1].g = (short)(255.0f * svRep[1]->color()[1]);
+ colors[1].b = (short)(255.0f * svRep[1]->color()[2]);
+ colors[1].a = (short)(255.0f * svRep[1]->alpha());
+
+ colors[2].r = (short)(255.0f * svRep[0]->color()[0]);
+ colors[2].g = (short)(255.0f * svRep[0]->color()[1]);
+ colors[2].b = (short)(255.0f * svRep[0]->color()[2]);
+ colors[2].a = (short)(255.0f * svRep[0]->alpha());
}
colors += 3;
}
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h
index 4bedffc4738..0d502a3be4a 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h
@@ -57,7 +57,6 @@ protected:
Main *freestyle_bmain;
Scene *old_scene;
Scene *freestyle_scene;
- Material *material;
float _width, _height;
float _z, _z_delta;
unsigned int _mesh_id;
diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
index 64e186b0def..f390e937aac 100644
--- a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
@@ -301,6 +301,7 @@ static char module_docstring[] =
"\n"
" - :class:`BackboneStretcherShader`\n"
" - :class:`BezierCurveShader`\n"
+" - :class:`BlenderTextureShader`\n"
" - :class:`CalligraphicShader`\n"
" - :class:`ColorNoiseShader`\n"
" - :class:`ColorVariationPatternShader`\n"
@@ -315,6 +316,7 @@ static char module_docstring[] =
" - :class:`SmoothingShader`\n"
" - :class:`SpatialNoiseShader`\n"
" - :class:`StrokeTextureShader`\n"
+" - :class:`StrokeTextureStepShader`\n"
" - :class:`TextureAssignerShader`\n"
" - :class:`ThicknessNoiseShader`\n"
" - :class:`ThicknessVariationPatternShader`\n"
diff --git a/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp b/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp
index e1d620cee1c..a6c7a40e780 100644
--- a/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp
+++ b/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp
@@ -29,6 +29,7 @@
#include "StrokeShader/BPy_BackboneStretcherShader.h"
#include "StrokeShader/BPy_BezierCurveShader.h"
+#include "StrokeShader/BPy_BlenderTextureShader.h"
#include "StrokeShader/BPy_CalligraphicShader.h"
#include "StrokeShader/BPy_ColorNoiseShader.h"
#include "StrokeShader/BPy_ColorVariationPatternShader.h"
@@ -45,6 +46,7 @@
#include "StrokeShader/BPy_SpatialNoiseShader.h"
#include "StrokeShader/BPy_streamShader.h"
#include "StrokeShader/BPy_StrokeTextureShader.h"
+#include "StrokeShader/BPy_StrokeTextureStepShader.h"
#include "StrokeShader/BPy_TextureAssignerShader.h"
#include "StrokeShader/BPy_ThicknessNoiseShader.h"
#include "StrokeShader/BPy_ThicknessVariationPatternShader.h"
@@ -77,6 +79,11 @@ int StrokeShader_Init(PyObject *module)
Py_INCREF(&BezierCurveShader_Type);
PyModule_AddObject(module, "BezierCurveShader", (PyObject *)&BezierCurveShader_Type);
+ if (PyType_Ready(&BlenderTextureShader_Type) < 0)
+ return -1;
+ Py_INCREF(&BlenderTextureShader_Type);
+ PyModule_AddObject(module, "BlenderTextureShader", (PyObject *)&BlenderTextureShader_Type);
+
if (PyType_Ready(&CalligraphicShader_Type) < 0)
return -1;
Py_INCREF(&CalligraphicShader_Type);
@@ -158,6 +165,11 @@ int StrokeShader_Init(PyObject *module)
Py_INCREF(&StrokeTextureShader_Type);
PyModule_AddObject(module, "StrokeTextureShader", (PyObject *)&StrokeTextureShader_Type);
+ if (PyType_Ready(&StrokeTextureStepShader_Type) < 0)
+ return -1;
+ Py_INCREF(&StrokeTextureStepShader_Type);
+ PyModule_AddObject(module, "StrokeTextureStepShader", (PyObject *)&StrokeTextureStepShader_Type);
+
if (PyType_Ready(&TextureAssignerShader_Type) < 0)
return -1;
Py_INCREF(&TextureAssignerShader_Type);
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp
new file mode 100644
index 00000000000..c8b9d7098e4
--- /dev/null
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp
@@ -0,0 +1,125 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp
+ * \ingroup freestyle
+ */
+
+#include "BPy_BlenderTextureShader.h"
+
+#include "../../stroke/BasicStrokeShaders.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../../../../python/generic/py_capi_utils.h"
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+//------------------------INSTANCE METHODS ----------------------------------
+
+static char BlenderTextureShader___doc__[] =
+"Class hierarchy: :class:`StrokeShader` > :class:`BlenderTextureShader`\n"
+"\n"
+"[Texture shader]\n"
+"\n"
+".. method:: __init__(LineStyleTextureSlot)\n"
+"\n"
+" Builds a BlenderTextureShader object.\n"
+"\n"
+" :arg mtex: texture slot to add to stroke shading.\n"
+" :type mtex: LineStyleTextureSlot\n"
+
+"\n"
+".. method:: shade(stroke)\n"
+"\n"
+" Assigns a blender texture slot to the stroke shading\n"
+" in order to simulate marks.\n"
+"\n"
+" :arg stroke: A Stroke object.\n"
+" :type stroke: :class:`Stroke`\n";
+
+static int BlenderTextureShader___init__(BPy_BlenderTextureShader *self, PyObject *args, PyObject *kwds)
+{
+ static const char *kwlist[] = {"LineStyleTextureSlot", NULL};
+ PyObject *py_mtex;
+ MTex *_mtex;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", (char **)kwlist, &py_mtex))
+ return -1;
+
+ _mtex = (MTex*)PyC_RNA_AsPointer(py_mtex, "LineStyleTextureSlot");
+
+ if (_mtex) {
+ self->py_ss.ss = new StrokeShaders::BlenderTextureShader(_mtex);
+ }
+
+ return 0;
+}
+
+/*-----------------------BPy_BlenderTextureShader type definition ------------------------------*/
+
+PyTypeObject BlenderTextureShader_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "BlenderTextureShader", /* tp_name */
+ sizeof(BPy_BlenderTextureShader), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ BlenderTextureShader___doc__, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ &StrokeShader_Type, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)BlenderTextureShader___init__, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.h
new file mode 100644
index 00000000000..46294c07b66
--- /dev/null
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.h
@@ -0,0 +1,57 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.h
+ * \ingroup freestyle
+ */
+
+#ifndef __FREESTYLE_PYTHON_BLENDERTEXTURESHADER_H__
+#define __FREESTYLE_PYTHON_BLENDERTEXTURESHADER_H__
+
+#include "../BPy_StrokeShader.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct MTex;
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+#include <Python.h>
+
+extern PyTypeObject BlenderTextureShader_Type;
+
+#define BPy_BlenderTextureShader_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&BlenderTextureShader_Type))
+
+/*---------------------------Python BPy_BlenderTextureShader structure definition-----------*/
+typedef struct {
+ BPy_StrokeShader py_ss;
+} BPy_BlenderTextureShader;
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __FREESTYLE_PYTHON_BLENDERTEXTURESHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp
new file mode 100644
index 00000000000..5a7657f2dad
--- /dev/null
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp
@@ -0,0 +1,114 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp
+ * \ingroup freestyle
+ */
+
+#include "BPy_StrokeTextureStepShader.h"
+
+#include "../../stroke/BasicStrokeShaders.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+//------------------------INSTANCE METHODS ----------------------------------
+
+static char StrokeTextureStepShader___doc__[] =
+"Class hierarchy: :class:`StrokeShader` > :class:`StrokeTextureStepShader`\n"
+"\n"
+"[Texture shader]\n"
+"\n"
+".. method:: __init__(step)\n"
+"\n"
+" Builds a StrokeTextureStepShader object.\n"
+"\n"
+" :arg step: The spacing along the stroke.\n"
+" :type step: float\n"
+"\n"
+".. method:: shade(stroke)\n"
+"\n"
+" Assigns a spacing factor to the texture coordinates of the Stroke.\n"
+"\n"
+" :arg stroke: A Stroke object.\n"
+" :type stroke: :class:`Stroke`\n";
+
+static int StrokeTextureStepShader___init__(BPy_StrokeTextureStepShader *self, PyObject *args, PyObject *kwds)
+{
+ static const char *kwlist[] = {"step", NULL};
+ float step = 0.1;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "f", (char **)kwlist, &step))
+ return -1;
+ self->py_ss.ss = new StrokeShaders::StrokeTextureStepShader(step);
+ return 0;
+}
+
+/*-----------------------BPy_StrokeTextureStepShader type definition ------------------------------*/
+
+PyTypeObject StrokeTextureStepShader_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "StrokeTextureStepShader", /* tp_name */
+ sizeof(BPy_StrokeTextureStepShader), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ StrokeTextureStepShader___doc__, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ &StrokeShader_Type, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)StrokeTextureStepShader___init__, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.h
new file mode 100644
index 00000000000..038d0022dec
--- /dev/null
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.h
@@ -0,0 +1,55 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.h
+ * \ingroup freestyle
+ */
+
+#ifndef __FREESTYLE_PYTHON_STROKETEXTURESTEPSHADER_H__
+#define __FREESTYLE_PYTHON_STROKETEXTURESTEPSHADER_H__
+
+#include "../BPy_StrokeShader.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+#include <Python.h>
+
+extern PyTypeObject StrokeTextureStepShader_Type;
+
+#define BPy_StrokeTextureStepShader_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&StrokeTextureStepShader_Type))
+
+/*---------------------------Python BPy_StrokeTextureStepShader structure definition----------*/
+typedef struct {
+ BPy_StrokeShader py_ss;
+} BPy_StrokeTextureStepShader;
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __FREESTYLE_PYTHON_STROKETEXTURESTEPSHADER_H__ */
diff --git a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp
index dd9464f12c3..a9138704290 100644
--- a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp
+++ b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp
@@ -449,6 +449,17 @@ int ColorNoiseShader::shade(Stroke& stroke) const
//
///////////////////////////////////////////////////////////////////////////////
+int BlenderTextureShader::shade(Stroke& stroke) const
+{
+ return stroke.setMTex(_mtex);
+}
+
+int StrokeTextureStepShader::shade(Stroke& stroke) const
+{
+ stroke.setTextureStep(_step);
+ return 0;
+}
+
int TextureAssignerShader::shade(Stroke& stroke) const
{
#if 0
diff --git a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h
index 5559613debb..9186d164e9b 100644
--- a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h
+++ b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h
@@ -36,6 +36,8 @@
#include "../geometry/Bezier.h"
#include "../geometry/Geom.h"
+struct MTex;
+
using namespace std;
namespace Freestyle {
@@ -894,6 +896,62 @@ public:
virtual int shade(Stroke& stroke) const;
};
+/*! [ Texture Shader ].
+ * Shader to assign texture to the Stroke material.
+ */
+
+class BlenderTextureShader : public StrokeShader
+{
+private:
+ MTex *_mtex;
+
+public:
+ /*! Builds the shader.
+ * \param mtex
+ * The blender texture to use.
+ */
+ BlenderTextureShader(MTex *mtex) : StrokeShader()
+ {
+ _mtex = mtex;
+ }
+
+ virtual string getName() const
+ {
+ return "BlenderTextureShader";
+ }
+
+ /*! The shading method */
+ virtual int shade(Stroke& stroke) const;
+};
+
+/*! [ Texture Shader ].
+ * Shader to assign texture to the Stroke material.
+ */
+
+class StrokeTextureStepShader : public StrokeShader
+{
+private:
+ float _step;
+
+public:
+ /*! Builds the shader.
+ * \param id
+ * The number of the preset to use.
+ */
+ StrokeTextureStepShader(float step) : StrokeShader()
+ {
+ _step = step;
+ }
+
+ virtual string getName() const
+ {
+ return "StrokeTextureStepShader";
+ }
+
+ /*! The shading method */
+ virtual int shade(Stroke& stroke) const;
+};
+
} // end of namespace StrokeShaders
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/stroke/Stroke.cpp b/source/blender/freestyle/intern/stroke/Stroke.cpp
index 86625e67405..9ed2cab8448 100644
--- a/source/blender/freestyle/intern/stroke/Stroke.cpp
+++ b/source/blender/freestyle/intern/stroke/Stroke.cpp
@@ -393,6 +393,10 @@ Stroke::Stroke()
//_mediumType = DEFAULT_STROKE;
_mediumType = OPAQUE_MEDIUM;
_textureId = 0;
+ _textureStep = 1.0;
+ for (int a = 0; a < MAX_MTEX; a++) {
+ _mtex[a] = NULL;
+ }
_tips = false;
_rep = NULL;
}
@@ -411,6 +415,15 @@ Stroke::Stroke(const Stroke& iBrother)
_sampling = iBrother._sampling;
_mediumType = iBrother._mediumType;
_textureId = iBrother._textureId;
+ _textureStep = iBrother._textureStep;
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (iBrother._mtex) {
+ _mtex[a] = iBrother._mtex[a];
+ }
+ else {
+ _mtex[a] = NULL;
+ }
+ }
_tips = iBrother._tips;
if (iBrother._rep)
_rep = new StrokeRep(*(iBrother._rep));
diff --git a/source/blender/freestyle/intern/stroke/Stroke.h b/source/blender/freestyle/intern/stroke/Stroke.h
index 66dc5a1acf4..27a105bb1cc 100644
--- a/source/blender/freestyle/intern/stroke/Stroke.h
+++ b/source/blender/freestyle/intern/stroke/Stroke.h
@@ -43,6 +43,14 @@
#include "MEM_guardedalloc.h"
#endif
+extern "C" {
+#include "DNA_material_types.h"
+}
+
+#ifndef MAX_MTEX
+#define MAX_MTEX 18
+#endif
+
namespace Freestyle {
//
@@ -528,9 +536,11 @@ private:
float _Length; // The stroke length
viewedge_container _ViewEdges;
float _sampling;
+ float _textureStep;
// StrokeRenderer *_renderer; // mark implementation OpenGL renderer
MediumType _mediumType;
unsigned int _textureId;
+ MTex *_mtex[MAX_MTEX];
bool _tips;
Vec2r _extremityOrientations[2]; // the orientations of the first and last extermity
StrokeRep *_rep;
@@ -635,6 +645,13 @@ public:
/*! Returns the id of the texture used to simulate th marks system for this Stroke */
inline unsigned int getTextureId() {return _textureId;}
+ /*! Returns the spacing of texture coordinates along the stroke lenght */
+ inline float getTextureStep() {return _textureStep;}
+
+ /*! Returns the texture used at given index to simulate the marks system for this Stroke */
+ inline MTex *getMTex(int idx) {
+ return _mtex[idx];}
+
/*! Returns true if this Stroke uses a texture with tips, false otherwise. */
inline bool hasTips() const
{
@@ -725,6 +742,25 @@ public:
_textureId = id;
}
+ /*! sets the spacing of texture coordinates along the stroke lenght. */
+ inline void setTextureStep(float step)
+ {
+ _textureStep = step;
+ }
+
+ /*! assigns a blender texture to the first available slot. */
+ inline int setMTex(MTex *mtex)
+ {
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (!_mtex[a]) {
+ _mtex[a] = mtex;
+
+ return 0;
+ }
+ }
+ return -1; /* no free slots */
+ }
+
/*! sets the flag telling whether this stroke is using a texture with tips or not. */
inline void setTips(bool iTips)
{
diff --git a/source/blender/freestyle/intern/stroke/StrokeRep.cpp b/source/blender/freestyle/intern/stroke/StrokeRep.cpp
index 1b9ab725ab9..4cfdd860d20 100644
--- a/source/blender/freestyle/intern/stroke/StrokeRep.cpp
+++ b/source/blender/freestyle/intern/stroke/StrokeRep.cpp
@@ -45,6 +45,7 @@ StrokeVertexRep::StrokeVertexRep(const StrokeVertexRep& iBrother)
{
_point2d = iBrother._point2d;
_texCoord = iBrother._texCoord;
+ _texCoord_w_tips = iBrother._texCoord_w_tips;
_color = iBrother._color;
_alpha = iBrother._alpha;
}
@@ -53,13 +54,13 @@ StrokeVertexRep::StrokeVertexRep(const StrokeVertexRep& iBrother)
// STRIP
/////////////////////////////////////
-Strip::Strip(const vector<StrokeVertex*>& iStrokeVertices, bool hasTips, bool beginTip, bool endTip)
+Strip::Strip(const vector<StrokeVertex*>& iStrokeVertices, bool hasTips, bool beginTip, bool endTip, float texStep)
{
createStrip(iStrokeVertices);
- if (!hasTips)
- computeTexCoord (iStrokeVertices);
- else
- computeTexCoordWithTips (iStrokeVertices, beginTip, endTip);
+
+ // We compute both kinds of coordinates to use different kinds of textures
+ computeTexCoord (iStrokeVertices, texStep);
+ computeTexCoordWithTips (iStrokeVertices, beginTip, endTip, texStep);
}
Strip::Strip(const Strip& iBrother)
@@ -485,21 +486,19 @@ void Strip::cleanUpSingularities (const vector<StrokeVertex*>& iStrokeVertices)
// Texture coordinates
////////////////////////////////
-void Strip::computeTexCoord (const vector<StrokeVertex *>& iStrokeVertices)
+void Strip::computeTexCoord (const vector<StrokeVertex *>& iStrokeVertices, float texStep)
{
vector<StrokeVertex *>::const_iterator v, vend;
StrokeVertex *sv;
int i = 0;
for (v = iStrokeVertices.begin(), vend = iStrokeVertices.end(); v != vend; v++) {
sv = (*v);
- _vertices[i]->setTexCoord(Vec2r((real)(sv->curvilinearAbscissa() / _averageThickness), 0));
- _vertices[i]->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2]));
+ _vertices[i]->setTexCoord(Vec2r((real)(sv->curvilinearAbscissa() / (_averageThickness * texStep)), 0));
+ _vertices[i]->setColor(Vec3r(sv->attribute().getColorRGB()));
_vertices[i]->setAlpha(sv->attribute().getAlpha());
i++;
- _vertices[i]->setTexCoord(Vec2r((real)(sv->curvilinearAbscissa() / _averageThickness), 1));
- _vertices[i]->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2]));
+ _vertices[i]->setTexCoord(Vec2r((real)(sv->curvilinearAbscissa() / (_averageThickness * texStep)), 1));
+ _vertices[i]->setColor(Vec3r(sv->attribute().getColorRGB()));
_vertices[i]->setAlpha(sv->attribute().getAlpha());
i++;
#if 0
@@ -509,23 +508,23 @@ void Strip::computeTexCoord (const vector<StrokeVertex *>& iStrokeVertices)
}
}
-void Strip::computeTexCoordWithTips (const vector<StrokeVertex*>& iStrokeVertices, bool tipBegin, bool tipEnd)
+void Strip::computeTexCoordWithTips (const vector<StrokeVertex*>& iStrokeVertices, bool tipBegin, bool tipEnd, float texStep)
{
- //soc unused - unsigned int sizeStrip = _vertices.size() + 8; //for the transition between the tip and the body
vector<StrokeVertex*>::const_iterator v, vend;
StrokeVertex *sv = NULL;
+ StrokeVertexRep *tvRep[2] = {NULL};
+
+ float l, fact, t;
+ float u = 0, uPrev = 0;
+ int tiles;
+ int i = 0;
+ float spacedThickness = _averageThickness * texStep;
v = iStrokeVertices.begin();
vend = iStrokeVertices.end();
- float l = (*v)->strokeLength() / _averageThickness;
- int tiles = int(l);
- float fact = (float(tiles) + 0.5) / l;
- //soc unused - float uTip2 = float(tiles) + 0.25;
- float u = 0;
- float uPrev = 0;
- int i = 0;
- float t;
- StrokeVertexRep *tvRep1, *tvRep2;
+ l = (*v)->strokeLength() / spacedThickness;
+ tiles = int(l + 0.5); // round to the nearest
+ fact = (float(tiles) + 0.5) / l;
#if 0
cerr << "l=" << l << " tiles=" << tiles << " _averageThicnkess="
@@ -538,166 +537,117 @@ void Strip::computeTexCoordWithTips (const vector<StrokeVertex*>& iStrokeVertice
for (; v != vend; v++) {
sv = (*v);
svRep = *currentSV;
- u = sv->curvilinearAbscissa() / _averageThickness * fact;
+ u = sv->curvilinearAbscissa() / spacedThickness * fact;
if (u > 0.25)
break;
- svRep->setTexCoord(Vec2r((real)u, 0.5));
- svRep->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2]));
- svRep->setAlpha(sv->attribute().getAlpha());
+ svRep->setTexCoord(Vec2r((real)u, 0.5), true);
i++;
++currentSV;
svRep = *currentSV;
- svRep->setTexCoord(Vec2r((real)u, 1));
- svRep->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2]));
- svRep->setAlpha(sv->attribute().getAlpha());
+ svRep->setTexCoord(Vec2r((real)u, 1), true);
i++;
++currentSV;
uPrev = u;
}
- //first transition vertex
+ // first transition vertex
if (fabs(u - uPrev) > ZERO)
t = (0.25 - uPrev) / (u - uPrev);
else
t = 0;
-#if 0
- if (!tiles)
- t = 0.5;
-#endif
- tvRep1 = new StrokeVertexRep(Vec2r((1 - t) * _vertices[i - 2]->point2d() + t * _vertices[i]->point2d()));
- tvRep1->setTexCoord(Vec2r(0.25, 0.5));
- tvRep1->setColor(Vec3r((1 - t) * _vertices[i - 2]->color() +
- t * Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2])));
- tvRep1->setAlpha((1 - t) * _vertices[i - 2]->alpha() + t * sv->attribute().getAlpha());
- i++;
-
- tvRep2 = new StrokeVertexRep(Vec2r((1 - t) * _vertices[i - 2]->point2d() + t *_vertices[i]->point2d()));
- tvRep2->setTexCoord(Vec2r(0.25, 1));
- tvRep2->setColor(Vec3r((1 - t) * _vertices[i - 2]->color() +
- t * Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2])));
- tvRep2->setAlpha((1 - t) * _vertices[i - 2]->alpha() + t * sv->attribute().getAlpha());
- i++;
-
- currentSV = _vertices.insert(currentSV, tvRep1);
- ++currentSV;
- currentSV = _vertices.insert(currentSV, tvRep2);
- ++currentSV;
+ for (int k = 0; k < 2; k++) {
+ tvRep[k] = new StrokeVertexRep((1 - t) * _vertices[i - 2]->point2d() + t * _vertices[i]->point2d());
+ tvRep[k]->setTexCoord((1 - t) * _vertices[i - 2]->texCoord() + t * _vertices[i]->texCoord());
+ // v coord is 0.5 for tvRep[0], 1.0 for tvRep[1]
+ tvRep[k]->setTexCoord(Vec2r(0.25, 0.5 * (k + 1)), true);
+ tvRep[k]->setColor((1 - t) * _vertices[i - 2]->color() + t * Vec3r(sv->attribute().getColorRGB()));
+ tvRep[k]->setAlpha((1 - t) * _vertices[i - 2]->alpha() + t * sv->attribute().getAlpha());
+ i++;
+ }
+ for (int k = 0; k < 2; k++) {
+ currentSV = _vertices.insert(currentSV, tvRep[k]);
+ ++currentSV;
+ }
// copy the vertices with different texture coordinates
- tvRep1 = new StrokeVertexRep(_vertices[i - 2]->point2d());
- tvRep1->setTexCoord(Vec2r(0.25, 0));
- tvRep1->setColor(_vertices[i - 2]->color());
- tvRep1->setAlpha(_vertices[i - 2]->alpha());
- i++;
-
- tvRep2 = new StrokeVertexRep(_vertices[i - 2]->point2d());
- tvRep2->setTexCoord(Vec2r(0.25, 0.5));
- tvRep2->setColor(_vertices[i - 2]->color());
- tvRep2->setAlpha(_vertices[i - 2]->alpha());
- i++;
-
- currentSV = _vertices.insert(currentSV, tvRep1);
- ++currentSV;
- currentSV = _vertices.insert(currentSV, tvRep2);
- ++currentSV;
+ for (int k = 0; k < 2; k++) {
+ tvRep[k] = new StrokeVertexRep(*(_vertices[i - 2]));
+ // v coord is 0.0 for tvRep[0], 0.5 for tvRep[1]
+ tvRep[k]->setTexCoord(Vec2r(0.0, 0.5 * k), true); // FIXED u coord
+ i++;
+ }
+ for (int k = 0; k < 2; k++) {
+ currentSV = _vertices.insert(currentSV, tvRep[k]);
+ ++currentSV;
+ }
}
uPrev = 0;
- //body of the stroke
+ // body of the stroke
for (; v != vend; v++) {
sv = (*v);
svRep = *currentSV;
- u = sv->curvilinearAbscissa() / _averageThickness * fact - 0.25;
+ u = sv->curvilinearAbscissa() / spacedThickness * fact - 0.25;
if (u > tiles)
break;
- svRep->setTexCoord(Vec2r((real)u, 0));
- svRep->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2]));
- svRep->setAlpha(sv->attribute().getAlpha());
+ svRep->setTexCoord(Vec2r((real)u, 0), true);
i++;
++currentSV;
svRep = *currentSV;
- svRep->setTexCoord(Vec2r((real)u, 0.5));
- svRep->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2]));
- svRep->setAlpha(sv->attribute().getAlpha());
+ svRep->setTexCoord(Vec2r((real)u, 0.5), true);
i++;
++currentSV;
uPrev = u;
}
if (tipEnd) {
- //second transition vertex
- if ((fabs(u - uPrev) > ZERO))
+ // second transition vertex
+ if (fabs(u - uPrev) > ZERO)
t = (float(tiles) - uPrev) / (u - uPrev);
else
t = 0;
+ for (int k = 0; k < 2; k++) {
+ tvRep[k] = new StrokeVertexRep((1 - t) * _vertices[i - 2]->point2d() + t * _vertices[i]->point2d());
+ tvRep[k]->setTexCoord((1 - t) * _vertices[i - 2]->texCoord() + t * _vertices[i]->texCoord());
+ // v coord is 0.0 for tvRep[0], 0.5 for tvRep[1]
+ tvRep[k]->setTexCoord(Vec2r((real)tiles, 0.5 * k), true); // FIXED u coord
+ tvRep[k]->setColor((1 - t) * _vertices[i - 2]->color() + t * Vec3r(sv->attribute().getColorRGB()));
+ tvRep[k]->setAlpha((1 - t) * _vertices[i - 2]->alpha() + t * sv->attribute().getAlpha());
+ i++;
+ }
+ for (int k = 0; k < 2; k++) {
+ currentSV = _vertices.insert(currentSV, tvRep[k]);
+ ++currentSV;
+ }
- tvRep1 = new StrokeVertexRep(Vec2r((1 - t) * _vertices[i - 2]->point2d() + t * _vertices[i]->point2d()));
- tvRep1->setTexCoord(Vec2r((real)tiles, 0));
- tvRep1->setColor(Vec3r((1 - t) * _vertices[i - 2]->color() +
- t * Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2])));
- tvRep1->setAlpha((1 - t) * _vertices[i - 2]->alpha() + t * sv->attribute().getAlpha());
- i++;
-
- tvRep2 = new StrokeVertexRep(Vec2r((1 - t) * _vertices[i - 2]->point2d() + t * _vertices[i]->point2d()));
- tvRep2->setTexCoord(Vec2r((real)tiles, 0.5));
- tvRep2->setColor(Vec3r((1 - t) * _vertices[i - 2]->color() +
- t * Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2])));
- tvRep2->setAlpha((1 - t) * _vertices[i - 2]->alpha() + t * sv->attribute().getAlpha());
- i++;
-
- currentSV = _vertices.insert(currentSV, tvRep1);
- ++currentSV;
- currentSV = _vertices.insert(currentSV, tvRep2);
- ++currentSV;
-
- //copy the vertices with different texture coordinates
- tvRep1 = new StrokeVertexRep(_vertices[i - 2]->point2d());
- tvRep1->setTexCoord(Vec2r(0.75, 0.5));
- tvRep1->setColor(_vertices[i - 2]->color());
- tvRep1->setAlpha(_vertices[i - 2]->alpha());
- i++;
-
- tvRep2 = new StrokeVertexRep(_vertices[i - 2]->point2d());
- tvRep2->setTexCoord(Vec2r(0.75, 1));
- tvRep2->setColor(_vertices[i - 2]->color());
- tvRep2->setAlpha(_vertices[i - 2]->alpha());
- i++;
-
- currentSV = _vertices.insert(currentSV, tvRep1);
- ++currentSV;
- currentSV = _vertices.insert(currentSV, tvRep2);
- ++currentSV;
+ // copy the vertices with different texture coordinates
+ for (int k = 0; k < 2; k++) {
+ tvRep[k] = new StrokeVertexRep(*(_vertices[i - 2]));
+ // v coord is 0.5 for tvRep[0], 1.0 for tvRep[1]
+ tvRep[k]->setTexCoord(Vec2r(0.75, 0.5 * (k + 1)), true);
+ i++;
+ }
+ for (int k = 0; k < 2; k++) {
+ currentSV = _vertices.insert(currentSV, tvRep[k]);
+ ++currentSV;
+ }
- //end tip
+ // end tip
for (; v != vend; v++) {
- sv = (*v);
+ sv = (*v);
svRep = *currentSV;
- u = 0.75 + sv->curvilinearAbscissa() / _averageThickness * fact - float(tiles) - 0.25;
+ u = 0.75 + sv->curvilinearAbscissa() / spacedThickness * fact - float(tiles) - 0.25;
- svRep->setTexCoord(Vec2r((real)u, 0.5));
- svRep->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2]));
- svRep->setAlpha(sv->attribute().getAlpha());
+ svRep->setTexCoord(Vec2r((real)u, 0.5), true);
i++;
++currentSV;
svRep = *currentSV;
- svRep->setTexCoord(Vec2r((real)u, 1));
- svRep->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2]));
- svRep->setAlpha(sv->attribute().getAlpha());
+ svRep->setTexCoord(Vec2r((real)u, 1), true);
i++;
++currentSV;
}
@@ -729,6 +679,10 @@ StrokeRep::StrokeRep()
{
_stroke = 0;
_strokeType = Stroke::OPAQUE_MEDIUM;
+ _textureStep = 1.0;
+ for (int a = 0; a < MAX_MTEX; a++) {
+ _mtex[a] = NULL;
+ }
TextureManager *ptm = TextureManager::getInstance();
if (ptm)
_textureId = ptm->getDefaultTextureId();
@@ -746,6 +700,15 @@ StrokeRep::StrokeRep(Stroke *iStroke)
_stroke = iStroke;
_strokeType = iStroke->getMediumType();
_textureId = iStroke->getTextureId();
+ _textureStep = iStroke->getTextureStep();
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (iStroke->getMTex(a)) {
+ _mtex[a] = iStroke->getMTex(a);
+ }
+ else {
+ _mtex[a] = NULL;
+ }
+ }
if (_textureId == 0) {
TextureManager *ptm = TextureManager::getInstance();
if (ptm)
@@ -768,6 +731,15 @@ StrokeRep::StrokeRep(const StrokeRep& iBrother)
_stroke = iBrother._stroke;
_strokeType = iBrother._strokeType;
_textureId = iBrother._textureId;
+ _textureStep = iBrother._textureStep;
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (iBrother._mtex[a]) {
+ _mtex[a] = iBrother._mtex[a];
+ }
+ else {
+ _mtex[a] = NULL;
+ }
+ }
for (vector<Strip*>::const_iterator s = iBrother._strips.begin(), send = iBrother._strips.end();
s != send;
++s)
@@ -811,7 +783,7 @@ void StrokeRep::create()
end = true;
}
if ((!strip.empty()) && (strip.size() > 1)) {
- _strips.push_back(new Strip(strip, _stroke->hasTips(), first, end));
+ _strips.push_back(new Strip(strip, _stroke->hasTips(), first, end, _stroke->getTextureStep()));
strip.clear();
}
first = false;
diff --git a/source/blender/freestyle/intern/stroke/StrokeRep.h b/source/blender/freestyle/intern/stroke/StrokeRep.h
index d01b27215fe..8bbbd9240cb 100644
--- a/source/blender/freestyle/intern/stroke/StrokeRep.h
+++ b/source/blender/freestyle/intern/stroke/StrokeRep.h
@@ -36,6 +36,10 @@
#include "MEM_guardedalloc.h"
#endif
+extern "C" {
+#include "DNA_material_types.h"
+}
+
namespace Freestyle {
using namespace Geometry;
@@ -78,9 +82,13 @@ public:
return _point2d;
}
- inline Vec2r& texCoord()
+ inline Vec2r& texCoord(bool tips=false)
{
- return _texCoord;
+ if (tips) {
+ return _texCoord_w_tips;
+ }
+ else
+ return _texCoord;
}
inline Vec3r& color()
@@ -98,9 +106,14 @@ public:
_point2d = p;
}
- inline void setTexCoord(const Vec2r& p)
+ inline void setTexCoord(const Vec2r& p, bool tips=false)
{
- _texCoord = p;
+ if (tips) {
+ _texCoord_w_tips = p;
+ }
+ else {
+ _texCoord = p;
+ }
}
inline void setColor(const Vec3r& p)
@@ -116,6 +129,7 @@ public:
protected:
Vec2r _point2d;
Vec2r _texCoord;
+ Vec2r _texCoord_w_tips;
Vec3r _color;
float _alpha;
@@ -135,15 +149,15 @@ protected:
public:
Strip(const std::vector<StrokeVertex*>& iStrokeVertices, bool hasTips = false,
- bool tipBegin = false, bool tipEnd = false);
+ bool tipBegin = false, bool tipEnd = false, float texStep = 1.0);
Strip(const Strip& iBrother);
virtual ~Strip();
protected:
void createStrip(const std::vector<StrokeVertex*>& iStrokeVertices);
void cleanUpSingularities(const std::vector<StrokeVertex*>& iStrokeVertices);
- void computeTexCoord (const std::vector<StrokeVertex*>& iStrokeVertices);
- void computeTexCoordWithTips (const std::vector<StrokeVertex*>& iStrokeVertices, bool tipBegin, bool tipEnd);
+ void computeTexCoord (const std::vector<StrokeVertex*>& iStrokeVertices, float texStep);
+ void computeTexCoordWithTips (const std::vector<StrokeVertex*>& iStrokeVertices, bool tipBegin, bool tipEnd, float texStep);
public:
inline int sizeStrip() const
@@ -168,6 +182,9 @@ protected:
vector<Strip*> _strips;
Stroke::MediumType _strokeType;
unsigned int _textureId;
+ float _textureStep;
+ MTex *_mtex[MAX_MTEX];
+ Material *_material;
// float _averageTextureAlpha;
@@ -194,6 +211,16 @@ public:
return _textureId;
}
+ inline MTex *getMTex(int idx) const
+ {
+ return _mtex[idx];
+ }
+
+ inline Material *getMaterial() const
+ {
+ return _material;
+ }
+
inline vector<Strip*>& getStrips()
{
return _strips;
@@ -220,6 +247,16 @@ public:
_textureId = textureId;
}
+ inline void setMaterial(Material *mat)
+ {
+ _material = mat;
+ }
+ /*
+ inline void setMTex(int idx, MTex *mtex_ptr)
+ {
+ _mtex[idx] = mtex_ptr;
+ }*/
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:StrokeRep")
#endif
diff --git a/source/blender/makesdna/DNA_linestyle_types.h b/source/blender/makesdna/DNA_linestyle_types.h
index 8d5f81ede5a..f7ba53c1f79 100644
--- a/source/blender/makesdna/DNA_linestyle_types.h
+++ b/source/blender/makesdna/DNA_linestyle_types.h
@@ -35,8 +35,16 @@
#include "DNA_listBase.h"
#include "DNA_ID.h"
+#ifndef MAX_MTEX
+#define MAX_MTEX 18
+#endif
+
+/* texco (also in DNA_material_types.h) */
+#define TEXCO_STROKE 16 /* actually it's UV */
+
struct ColorBand;
struct CurveMapping;
+struct MTex;
typedef struct LineStyleModifier {
struct LineStyleModifier *next, *prev;
@@ -354,7 +362,8 @@ typedef struct LineStyleThicknessModifier_Calligraphy {
#define LS_PANEL_ALPHA 3
#define LS_PANEL_THICKNESS 4
#define LS_PANEL_GEOMETRY 5
-#define LS_PANEL_MISC 6
+#define LS_PANEL_TEXTURE 6
+#define LS_PANEL_MISC 7
/* FreestyleLineStyle::flag */
#define LS_DS_EXPAND (1 << 0) /* for animation editors */
@@ -370,6 +379,7 @@ typedef struct LineStyleThicknessModifier_Calligraphy {
#define LS_SPLIT_PATTERN (1 << 10)
#define LS_NO_SORTING (1 << 11)
#define LS_REVERSE_ORDER (1 << 12) /* for sorting */
+#define LS_TEXTURE (1 << 13)
/* FreestyleLineStyle::chaining */
#define LS_CHAINING_PLAIN 1
@@ -415,10 +425,16 @@ typedef struct FreestyleLineStyle {
unsigned short split_dash2, split_gap2;
unsigned short split_dash3, split_gap3;
int sort_key, integration_type;
- int pad;
+ float texstep;
+ short texact, pr_texture;
+ short use_nodes, pad;
unsigned short dash1, gap1, dash2, gap2, dash3, gap3;
int panel; /* for UI */
+ struct MTex *mtex[18]; /* MAX_MTEX */
+ /* nodes */
+ struct bNodeTree *nodetree;
+
ListBase color_modifiers;
ListBase alpha_modifiers;
ListBase thickness_modifiers;
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 54fcb5c857b..c7a6d4809a5 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -209,6 +209,7 @@ typedef enum eSpaceButtons_Texture_Context {
SB_TEXC_LAMP = 2,
SB_TEXC_PARTICLES = 3,
SB_TEXC_OTHER = 4,
+ SB_TEXC_LINESTYLE = 5,
} eSpaceButtons_Texture_Context;
/* sbuts->align */
@@ -981,6 +982,7 @@ typedef enum eSpaceNode_TexFrom {
SNODE_TEX_OBJECT = 0,
SNODE_TEX_WORLD = 1,
SNODE_TEX_BRUSH = 2,
+ SNODE_TEX_LINESTYLE = 3,
} eSpaceNode_TexFrom;
/* snode->shaderfrom */
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index a3025a7fb31..1906f71a230 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -479,6 +479,7 @@ typedef struct ColorMapping {
#define MTEX_BUMP_OBJECTSPACE 1024
#define MTEX_BUMP_TEXTURESPACE 2048
/* #define MTEX_BUMP_FLIPPED 4096 */ /* UNUSED */
+#define MTEX_TIPS 4096 /* should use with_freestyle flag? */
#define MTEX_BICUBIC_BUMP 8192
#define MTEX_MAPTO_BOUNDS 16384
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index b231d0587dd..add59bafc3f 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -331,6 +331,7 @@ extern StructRNA RNA_LineStyleGeometryModifier_SinusDisplacement;
extern StructRNA RNA_LineStyleGeometryModifier_SpatialNoise;
extern StructRNA RNA_LineStyleGeometryModifier_TipRemover;
extern StructRNA RNA_LineStyleModifier;
+extern StructRNA RNA_LineStyleTextureSlot;
extern StructRNA RNA_LineStyleThicknessModifier;
extern StructRNA RNA_LineStyleThicknessModifier_AlongStroke;
extern StructRNA RNA_LineStyleThicknessModifier_Calligraphy;
diff --git a/source/blender/makesrna/intern/rna_linestyle.c b/source/blender/makesrna/intern/rna_linestyle.c
index 6e6f0c3e208..d6378c4da67 100644
--- a/source/blender/makesrna/intern/rna_linestyle.c
+++ b/source/blender/makesrna/intern/rna_linestyle.c
@@ -84,6 +84,8 @@ EnumPropertyItem linestyle_geometry_modifier_type_items[] = {
#ifdef RNA_RUNTIME
#include "BKE_linestyle.h"
+#include "BKE_texture.h"
+#include "BKE_depsgraph.h"
static StructRNA *rna_LineStyle_color_modifier_refine(struct PointerRNA *ptr)
{
@@ -249,10 +251,148 @@ static void rna_LineStyleGeometryModifier_name_set(PointerRNA *ptr, const char *
offsetof(LineStyleModifier, name), sizeof(m->name));
}
+static void rna_LineStyle_mtex_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ FreestyleLineStyle *linestyle = (FreestyleLineStyle *)ptr->id.data;
+ rna_iterator_array_begin(iter, (void *)linestyle->mtex, sizeof(MTex *), MAX_MTEX, 0, NULL);
+}
+
+static PointerRNA rna_LineStyle_active_texture_get(PointerRNA *ptr)
+{
+ FreestyleLineStyle *linestyle = (FreestyleLineStyle *)ptr->id.data;
+ Tex *tex;
+
+ tex = give_current_linestyle_texture(linestyle);
+ return rna_pointer_inherit_refine(ptr, &RNA_Texture, tex);
+}
+
+static void rna_LineStyle_active_texture_set(PointerRNA *ptr, PointerRNA value)
+{
+ FreestyleLineStyle *linestyle = (FreestyleLineStyle *)ptr->id.data;
+
+ set_current_linestyle_texture(linestyle, value.data);
+}
+
+static void rna_LineStyle_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ FreestyleLineStyle *linestyle = ptr->id.data;
+
+ DAG_id_tag_update(&linestyle->id, 0);
+ WM_main_add_notifier(NC_LINESTYLE, linestyle);
+}
+
#else
#include "BLI_math.h"
+static void rna_def_linestyle_mtex(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem texco_items[] = {
+ {TEXCO_WINDOW, "WINDOW", 0, "Window", "Use screen coordinates as texture coordinates"},
+ {TEXCO_GLOB, "GLOBAL", 0, "Global", "Use global coordinates for the texture coordinates"},
+ {TEXCO_STROKE, "ALONG_STROKE", 0, "Along stroke", "Use stroke lenght for texture coordinates"},
+ {TEXCO_ORCO, "ORCO", 0, "Generated", "Use the original undeformed coordinates of the object"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem prop_mapping_items[] = {
+ {MTEX_FLAT, "FLAT", 0, "Flat", "Map X and Y coordinates directly"},
+ {MTEX_CUBE, "CUBE", 0, "Cube", "Map using the normal vector"},
+ {MTEX_TUBE, "TUBE", 0, "Tube", "Map with Z as central axis"},
+ {MTEX_SPHERE, "SPHERE", 0, "Sphere", "Map with Z as central axis"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem prop_x_mapping_items[] = {
+ {0, "NONE", 0, "None", ""},
+ {1, "X", 0, "X", ""},
+ {2, "Y", 0, "Y", ""},
+ {3, "Z", 0, "Z", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem prop_y_mapping_items[] = {
+ {0, "NONE", 0, "None", ""},
+ {1, "X", 0, "X", ""},
+ {2, "Y", 0, "Y", ""},
+ {3, "Z", 0, "Z", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem prop_z_mapping_items[] = {
+ {0, "NONE", 0, "None", ""},
+ {1, "X", 0, "X", ""},
+ {2, "Y", 0, "Y", ""},
+ {3, "Z", 0, "Z", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ srna = RNA_def_struct(brna, "LineStyleTextureSlot", "TextureSlot");
+ RNA_def_struct_sdna(srna, "MTex");
+ RNA_def_struct_ui_text(srna, "LineStyle Texture Slot", "Texture slot for textures in a LineStyle datablock");
+
+ prop = RNA_def_property(srna, "mapping_x", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "projx");
+ RNA_def_property_enum_items(prop, prop_x_mapping_items);
+ RNA_def_property_ui_text(prop, "X Mapping", "");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+
+ prop = RNA_def_property(srna, "mapping_y", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "projy");
+ RNA_def_property_enum_items(prop, prop_y_mapping_items);
+ RNA_def_property_ui_text(prop, "Y Mapping", "");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+
+ prop = RNA_def_property(srna, "mapping_z", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "projz");
+ RNA_def_property_enum_items(prop, prop_z_mapping_items);
+ RNA_def_property_ui_text(prop, "Z Mapping", "");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+
+ prop = RNA_def_property(srna, "mapping", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, prop_mapping_items);
+ RNA_def_property_ui_text(prop, "Mapping", "");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+
+ /* map to */
+ prop = RNA_def_property(srna, "use_map_color_diffuse", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_COL);
+ RNA_def_property_ui_text(prop, "Diffuse Color", "The texture affects basic color of the stroke");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+
+ prop = RNA_def_property(srna, "use_map_alpha", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_ALPHA);
+ RNA_def_property_ui_text(prop, "Alpha", "The texture affects the alpha value");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+
+ prop = RNA_def_property(srna, "use_tips", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_TIPS);
+ RNA_def_property_ui_text(prop, "Use tips", "Lower half of the texture is for tips of the stroke");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+
+ prop = RNA_def_property(srna, "texture_coords", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "texco");
+ RNA_def_property_enum_items(prop, texco_items);
+ RNA_def_property_ui_text(prop, "Texture Coordinates",
+ "Texture coordinates used to map the texture onto the background");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+
+ prop = RNA_def_property(srna, "alpha_factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "alphafac");
+ RNA_def_property_ui_range(prop, -1, 1, 10, 3);
+ RNA_def_property_ui_text(prop, "Alpha Factor", "Amount texture affects alpha");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+
+ prop = RNA_def_property(srna, "diffuse_color_factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "colfac");
+ RNA_def_property_ui_range(prop, 0, 1, 10, 3);
+ RNA_def_property_ui_text(prop, "Diffuse Color Factor", "Amount texture affects diffuse color");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+}
+
static void rna_def_modifier_type_common(StructRNA *srna, EnumPropertyItem *modifier_type_items,
const char *set_name_func, const bool blend, const bool color)
{
@@ -892,6 +1032,7 @@ static void rna_def_linestyle(BlenderRNA *brna)
{LS_PANEL_ALPHA, "ALPHA", 0, "Alpha", "Show the panel for alpha transparency options"},
{LS_PANEL_THICKNESS, "THICKNESS", 0, "Thickness", "Show the panel for line thickness options"},
{LS_PANEL_GEOMETRY, "GEOMETRY", 0, "Geometry", "Show the panel for stroke geometry options"},
+ {LS_PANEL_TEXTURE, "TEXTURE", 0, "Texture", "Show the panel for stroke texture options"},
#if 0 /* hidden for now */
{LS_PANEL_MISC, "MISC", 0, "Misc", "Show the panel for miscellaneous options"},
#endif
@@ -938,6 +1079,9 @@ static void rna_def_linestyle(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Freestyle Line Style", "Freestyle line style, reusable by multiple line sets");
RNA_def_struct_ui_icon(srna, ICON_LINE_DATA);
+ rna_def_mtex_common(brna, srna, "rna_LineStyle_mtex_begin", "rna_LineStyle_active_texture_get",
+ "rna_LineStyle_active_texture_set", NULL, "LineStyleTextureSlot", "LineStyleTextureSlots", "rna_LineStyle_update");
+
prop = RNA_def_property(srna, "panel", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "panel");
RNA_def_property_enum_items(prop, panel_items);
@@ -1192,12 +1336,36 @@ static void rna_def_linestyle(BlenderRNA *brna)
RNA_def_property_range(prop, 0, USHRT_MAX);
RNA_def_property_ui_text(prop, "Gap 3", "Length of the 3rd gap for dashed lines");
RNA_def_property_update(prop, NC_LINESTYLE, NULL);
+
+ prop = RNA_def_property(srna, "use_texture", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", LS_TEXTURE);
+ RNA_def_property_ui_text(prop, "Texture", "Enable or disable textured strokes");
+ RNA_def_property_update(prop, NC_LINESTYLE, NULL);
+
+ prop = RNA_def_property(srna, "texture_spacing", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "texstep");
+ RNA_def_property_range(prop, 0.01f, 100.0f);
+ RNA_def_property_ui_text(prop, "Texture spacing", "Spacing for textures along stroke lenght");
+ RNA_def_property_update(prop, NC_LINESTYLE, NULL);
+
+ /* nodes */
+ prop = RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "nodetree");
+ RNA_def_property_ui_text(prop, "Node Tree", "Node tree for node based textures");
+
+ prop = RNA_def_property(srna, "use_nodes", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "use_nodes", 1);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_ui_text(prop, "Use Nodes", "Use texture nodes for the line style");
+ RNA_def_property_update(prop, NC_LINESTYLE, NULL);
}
void RNA_def_linestyle(BlenderRNA *brna)
{
rna_def_linestyle_modifiers(brna);
rna_def_linestyle(brna);
+ rna_def_linestyle_mtex(brna);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 1afc413d590..39d6e665077 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -166,6 +166,7 @@ static EnumPropertyItem buttons_texture_context_items[] = {
{SB_TEXC_WORLD, "WORLD", ICON_WORLD, "", "Show world textures"},
{SB_TEXC_LAMP, "LAMP", ICON_LAMP, "", "Show lamp textures"},
{SB_TEXC_PARTICLES, "PARTICLES", ICON_PARTICLES, "", "Show particles textures"},
+ {SB_TEXC_LINESTYLE, "LINESTYLE", ICON_LINE_DATA, "", "Show linestyle textures"},
{SB_TEXC_OTHER, "OTHER", ICON_TEXTURE, "", "Show other data textures"},
{0, NULL, 0, NULL, NULL}
};
@@ -983,6 +984,10 @@ static EnumPropertyItem *rna_SpaceProperties_texture_context_itemf(bContext *C,
RNA_enum_items_add_value(&item, &totitem, buttons_texture_context_items, SB_TEXC_PARTICLES);
}
+ if (ED_texture_context_check_linestyle(C)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_texture_context_items, SB_TEXC_LINESTYLE);
+ }
+
if (ED_texture_context_check_others(C)) {
RNA_enum_items_add_value(&item, &totitem, buttons_texture_context_items, SB_TEXC_OTHER);
}
@@ -3393,6 +3398,7 @@ static void rna_def_space_node(BlenderRNA *brna)
{SNODE_TEX_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Edit texture nodes from Object"},
{SNODE_TEX_WORLD, "WORLD", ICON_WORLD_DATA, "World", "Edit texture nodes from World"},
{SNODE_TEX_BRUSH, "BRUSH", ICON_BRUSH_DATA, "Brush", "Edit texture nodes from Brush"},
+ {SNODE_TEX_LINESTYLE, "LINESTYLE", ICON_LINE_DATA, "Line Style", "Edit texture nodes from Line Style"},
{0, NULL, 0, NULL, NULL}
};
diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c
index 7e9360b271c..882c843f317 100644
--- a/source/blender/nodes/texture/node_texture_tree.c
+++ b/source/blender/nodes/texture/node_texture_tree.c
@@ -92,7 +92,7 @@ static void texture_get_from_context(const bContext *C, bNodeTreeType *UNUSED(tr
}
}
}
- else {
+ else if (snode->texfrom == SNODE_TEX_BRUSH) {
struct Brush *brush = NULL;
if (ob && (ob->mode & OB_MODE_SCULPT))
@@ -109,6 +109,17 @@ static void texture_get_from_context(const bContext *C, bNodeTreeType *UNUSED(tr
}
}
}
+ else if (snode->texfrom == SNODE_TEX_LINESTYLE) {
+ FreestyleLineStyle *linestyle = CTX_data_linestyle_from_scene(scene);
+ if (linestyle) {
+ *r_from = (ID *)linestyle;
+ tx = give_current_linestyle_texture(linestyle);
+ if (tx) {
+ *r_id = &tx->id;
+ *r_ntree = tx->nodetree;
+ }
+ }
+ }
}
static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func)