Use of text datablocks for storing Python style modules.
Suggested by Brecht Van Lommel and Campbell Barton through code review comments. Previously style modules were external Python script files whose absolute paths were kept in .blend files. Now style modules are stored in .blend files as text datablocks. Style modules are configured in three steps: 1. Open an external style module file (or create a new text datablock) in the Text Editor in Blender. 2. Add a style module to the list of style modules (by pressing the "Add" button) in the Render Layer properties window. 3. Click the name entry and select the style module from the drop-down menu.
This commit is contained in:
@@ -159,7 +159,7 @@ class RENDERLAYER_PT_freestyle(RenderLayerFreestyleButtonsPanel, Panel):
|
||||
box.context_pointer_set("freestyle_module", module)
|
||||
row = box.row(align=True)
|
||||
row.prop(module, "use", text="")
|
||||
row.prop(module, "module_path", text="")
|
||||
row.prop(module, "script", text="")
|
||||
row.operator("scene.freestyle_module_remove", icon='X', text="")
|
||||
row.operator("scene.freestyle_module_move", icon='TRIA_UP', text="").direction = 'UP'
|
||||
row.operator("scene.freestyle_module_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
|
||||
|
||||
@@ -128,18 +128,14 @@ static FreestyleModuleConfig *alloc_module(void)
|
||||
void BKE_freestyle_module_add(FreestyleConfig *config)
|
||||
{
|
||||
FreestyleModuleConfig *module_conf = alloc_module();
|
||||
const size_t maxlen = sizeof(module_conf->module_path);
|
||||
BLI_addtail(&config->modules, (void *)module_conf);
|
||||
|
||||
BLI_strncpy(module_conf->module_path, BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, "freestyle"), maxlen);
|
||||
BLI_join_dirfile(module_conf->module_path, maxlen, module_conf->module_path, "style_modules");
|
||||
BLI_join_dirfile(module_conf->module_path, maxlen, module_conf->module_path, "contour.py");
|
||||
module_conf->script = NULL;
|
||||
module_conf->is_displayed = 1;
|
||||
}
|
||||
|
||||
static void copy_module(FreestyleModuleConfig *new_module, FreestyleModuleConfig *module)
|
||||
{
|
||||
strcpy(new_module->module_path, module->module_path);
|
||||
new_module->script = module->script;
|
||||
new_module->is_displayed = module->is_displayed;
|
||||
}
|
||||
|
||||
|
||||
@@ -519,6 +519,9 @@ void BKE_text_unlink(Main *bmain, Text *text)
|
||||
bNodeTree *ntree;
|
||||
bNode *node;
|
||||
Material *mat;
|
||||
Scene *sce;
|
||||
SceneRenderLayer *srl;
|
||||
FreestyleModuleConfig *module;
|
||||
short update;
|
||||
|
||||
for (ob = bmain->object.first; ob; ob = ob->id.next) {
|
||||
@@ -608,6 +611,16 @@ void BKE_text_unlink(Main *bmain, Text *text)
|
||||
}
|
||||
}
|
||||
|
||||
/* Freestyle */
|
||||
for (sce = bmain->scene.first; sce; sce = sce->id.next) {
|
||||
for (srl = sce->r.layers.first; srl; srl = srl->next) {
|
||||
for (module = srl->freestyleConfig.modules.first; module; module= module->next) {
|
||||
if (module->script == text)
|
||||
module->script = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
text->id.us = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -5026,6 +5026,7 @@ static void lib_link_scene(FileData *fd, Main *main)
|
||||
Sequence *seq;
|
||||
SceneRenderLayer *srl;
|
||||
TimeMarker *marker;
|
||||
FreestyleModuleConfig *fmc;
|
||||
FreestyleLineSet *fls;
|
||||
|
||||
for (sce = main->scene.first; sce; sce = sce->id.next) {
|
||||
@@ -5141,6 +5142,9 @@ static void lib_link_scene(FileData *fd, Main *main)
|
||||
for (srl = sce->r.layers.first; srl; srl = srl->next) {
|
||||
srl->mat_override = newlibadr_us(fd, sce->id.lib, srl->mat_override);
|
||||
srl->light_override = newlibadr_us(fd, sce->id.lib, srl->light_override);
|
||||
for (fmc = srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) {
|
||||
fmc->script = newlibadr(fd, sce->id.lib, fmc->script);
|
||||
}
|
||||
for (fls = srl->freestyleConfig.linesets.first; fls; fls = fls->next) {
|
||||
fls->linestyle = newlibadr_us(fd, sce->id.lib, fls->linestyle);
|
||||
fls->group = newlibadr_us(fd, sce->id.lib, fls->group);
|
||||
@@ -9331,6 +9335,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
For now it is kept for backward compatibility, giving branch users time
|
||||
to migrate to the new CustomData-based edge/face marks. */
|
||||
{
|
||||
Scene *sce;
|
||||
SceneRenderLayer *srl;
|
||||
FreestyleModuleConfig *fmc;
|
||||
Mesh *me;
|
||||
MEdge *medge;
|
||||
MPoly *mpoly;
|
||||
@@ -9384,6 +9391,20 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
printf("Migrated to CustomData-based Freestyle face marks\n");
|
||||
}
|
||||
}
|
||||
for (sce = main->scene.first; sce; sce = sce->id.next) {
|
||||
for (srl = sce->r.layers.first; srl; srl = srl->next) {
|
||||
i = 1;
|
||||
for (fmc = srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) {
|
||||
if (fmc->module_path[0] != '\0' && !fmc->script) {
|
||||
fprintf(stderr, "The external style module below needs to be reconfigured using text datablock:\n");
|
||||
fprintf(stderr, " %s\n", fmc->module_path);
|
||||
fprintf(stderr, " in scene \"%s\", render layer \"%s\", style module #%d (%s)\n",
|
||||
sce->id.name+2, srl->name, i, (fmc->is_displayed) ? "enabled" : "disabled");
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
|
||||
@@ -10378,6 +10399,7 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
|
||||
{
|
||||
Base *base;
|
||||
SceneRenderLayer *srl;
|
||||
FreestyleModuleConfig *module;
|
||||
FreestyleLineSet *lineset;
|
||||
|
||||
for (base = sce->base.first; base; base = base->next) {
|
||||
@@ -10399,6 +10421,10 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
|
||||
for (srl = sce->r.layers.first; srl; srl = srl->next) {
|
||||
expand_doit(fd, mainvar, srl->mat_override);
|
||||
expand_doit(fd, mainvar, srl->light_override);
|
||||
for (module = srl->freestyleConfig.modules.first; module; module = module->next) {
|
||||
if (module->script)
|
||||
expand_doit(fd, mainvar, module->script);
|
||||
}
|
||||
for (lineset = srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) {
|
||||
if (lineset->group)
|
||||
expand_doit(fd, mainvar, lineset->group);
|
||||
|
||||
@@ -46,12 +46,6 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
virtual void close()
|
||||
{
|
||||
BKE_text_unlink(G.main, _text);
|
||||
BKE_libblock_free(&G.main->text, _text);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual int interpret()
|
||||
{
|
||||
|
||||
@@ -321,11 +321,15 @@ static void prepare(Render *re, SceneRenderLayer *srl)
|
||||
module_conf;
|
||||
module_conf = module_conf->next)
|
||||
{
|
||||
if (module_conf->is_displayed) {
|
||||
if (module_conf->script && module_conf->is_displayed) {
|
||||
const char *id_name = module_conf->script->id.name + 2;
|
||||
if (G.debug & G_DEBUG_FREESTYLE) {
|
||||
cout << " " << layer_count + 1 << ": " << module_conf->module_path << endl;
|
||||
cout << " " << layer_count + 1 << ": " << id_name;
|
||||
if (module_conf->script->name)
|
||||
cout << " (" << module_conf->script->name << ")";
|
||||
cout << endl;
|
||||
}
|
||||
controller->InsertStyleModule(layer_count, module_conf->module_path);
|
||||
controller->InsertStyleModule(layer_count, id_name, module_conf->script);
|
||||
controller->toggleLayer(layer_count, true);
|
||||
layer_count++;
|
||||
}
|
||||
@@ -537,7 +541,7 @@ static int displayed_layer_count(SceneRenderLayer *srl)
|
||||
module;
|
||||
module = module->next)
|
||||
{
|
||||
if (module->is_displayed)
|
||||
if (module->script && module->is_displayed)
|
||||
count++;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -145,10 +145,8 @@ void Canvas::Clear()
|
||||
|
||||
if (!_StyleModules.empty()) {
|
||||
for (deque<StyleModule*>::iterator s = _StyleModules.begin(), send = _StyleModules.end(); s != send; ++s) {
|
||||
if (*s) {
|
||||
(*s)->close();
|
||||
if (*s)
|
||||
delete (*s);
|
||||
}
|
||||
}
|
||||
_StyleModules.clear();
|
||||
}
|
||||
|
||||
@@ -91,8 +91,6 @@ public:
|
||||
return sl;
|
||||
}
|
||||
|
||||
virtual void close() {}
|
||||
|
||||
protected:
|
||||
virtual int interpret()
|
||||
{
|
||||
|
||||
@@ -28,9 +28,12 @@
|
||||
#ifndef __DNA_FREESTYLE_TYPES_H__
|
||||
#define __DNA_FREESTYLE_TYPES_H__
|
||||
|
||||
#include "DNA_defs.h"
|
||||
#include "DNA_listBase.h"
|
||||
|
||||
struct FreestyleLineStyle;
|
||||
struct Group;
|
||||
struct Text;
|
||||
|
||||
/* FreestyleConfig::flags */
|
||||
#define FREESTYLE_SUGGESTIVE_CONTOURS_FLAG (1 << 0)
|
||||
@@ -107,7 +110,8 @@ typedef struct FreestyleLineSet {
|
||||
typedef struct FreestyleModuleConfig {
|
||||
struct FreestyleModuleConfig *next, *prev;
|
||||
|
||||
char module_path[1024]; /* FILE_MAX */
|
||||
struct Text *script;
|
||||
char module_path[1024] DNA_DEPRECATED; /* FILE_MAX */
|
||||
short is_displayed;
|
||||
short pad[3];
|
||||
} FreestyleModuleConfig;
|
||||
|
||||
@@ -2680,10 +2680,18 @@ static void rna_def_freestyle_settings(BlenderRNA *brna)
|
||||
RNA_def_struct_sdna(srna, "FreestyleModuleConfig");
|
||||
RNA_def_struct_ui_text(srna, "Freestyle Module", "Style module configuration for specifying a style module");
|
||||
|
||||
prop = RNA_def_property(srna, "script", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "Text");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Style Module", "Python script to define a style module");
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
|
||||
#if 1 /* TO BE REMOVED when the trunk merger is done */
|
||||
prop = RNA_def_property(srna, "module_path", PROP_STRING, PROP_FILEPATH);
|
||||
RNA_def_property_string_sdna(prop, NULL, "module_path");
|
||||
RNA_def_property_ui_text(prop, "Module Path", "Path to a style module file");
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
#endif
|
||||
|
||||
prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "is_displayed", 1);
|
||||
|
||||
Reference in New Issue
Block a user