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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp')
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp378
1 files changed, 311 insertions, 67 deletions
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
index d47f4e5d910..47b0c9b1e48 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
@@ -30,26 +30,35 @@
extern "C" {
#include "MEM_guardedalloc.h"
+#include "RNA_access.h"
+
#include "DNA_camera_types.h"
#include "DNA_listBase.h"
+#include "DNA_linestyle_types.h"
+#include "DNA_material_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
+#include "DNA_scene_types.h"
#include "BKE_customdata.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_library.h" /* free_libblock */
-#include "BKE_main.h" /* struct Main */
#include "BKE_material.h"
#include "BKE_mesh.h"
+#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_scene.h"
+#include "BLI_ghash.h"
+#include "BLI_listbase.h"
#include "BLI_utildefines.h"
#include "RE_pipeline.h"
+
+#include "render_types.h"
}
#include <limits.h>
@@ -133,6 +142,15 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : Str
// Reset serial mesh ID (used for BlenderStrokeRenderer::NewMesh())
_mesh_id = 0xffffffff;
+
+ // Check if the rendering engine uses new shading nodes
+ _use_shading_nodes = BKE_scene_use_new_shading_nodes(freestyle_scene);
+
+ // Create a bNodeTree-to-Material hash table
+ if (_use_shading_nodes)
+ _nodetree_hash = BLI_ghash_ptr_new("BlenderStrokeRenderer::_nodetree_hash");
+ else
+ _nodetree_hash = NULL;
}
BlenderStrokeRenderer::~BlenderStrokeRenderer()
@@ -186,6 +204,9 @@ BlenderStrokeRenderer::~BlenderStrokeRenderer()
lnk = lnk->next;
BKE_libblock_free(freestyle_bmain, ma);
}
+
+ if (_use_shading_nodes)
+ BLI_ghash_free(_nodetree_hash, NULL, NULL);
}
float BlenderStrokeRenderer::get_stroke_vertex_z(void) const
@@ -206,55 +227,283 @@ unsigned int BlenderStrokeRenderer::get_stroke_mesh_id(void) const
return mesh_id;
}
-void BlenderStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const
+Material* BlenderStrokeRenderer::GetStrokeShader(Main *bmain, bNodeTree *iNodeTree, bool do_id_user)
{
- 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;
+ Material *ma = BKE_material_add(bmain, "stroke_shader");
+ bNodeTree *ntree;
+ bNode *output_linestyle = NULL;
+ bNodeSocket *fromsock, *tosock;
+ PointerRNA fromptr, toptr;
+ NodeShaderAttribute *storage;
+
+ if (iNodeTree) {
+ // make a copy of linestyle->nodetree
+ ntree = ntreeCopyTree_ex(iNodeTree, bmain, do_id_user);
+
+ // find the active Output Line Style node
+ for (bNode *node = (bNode *)ntree->nodes.first; node; node = node->next) {
+ if (node->type == SH_NODE_OUTPUT_LINESTYLE && (node->flag & NODE_DO_OUTPUT)) {
+ output_linestyle = node;
break;
}
}
+ }
+ else {
+ ntree = ntreeAddTree(NULL, "stroke_shader", "ShaderNodeTree");
+ }
+ ma->nodetree = ntree;
+ ma->use_nodes = 1;
+
+ bNode *input_attr_color = nodeAddStaticNode(NULL, ntree, SH_NODE_ATTRIBUTE);
+ input_attr_color->locx = 0.0f;
+ input_attr_color->locy = -200.0f;
+ storage = (NodeShaderAttribute *)input_attr_color->storage;
+ BLI_strncpy(storage->name, "Color", sizeof(storage->name));
+
+ bNode *mix_rgb_color = nodeAddStaticNode(NULL, ntree, SH_NODE_MIX_RGB);
+ mix_rgb_color->custom1 = MA_RAMP_BLEND; // Mix
+ mix_rgb_color->locx = 200.0f;
+ mix_rgb_color->locy = -200.0f;
+ tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_color->inputs, 0); // Fac
+ RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, tosock, &toptr);
+ RNA_float_set(&toptr, "default_value", 0.0f);
+
+ bNode *input_attr_alpha = nodeAddStaticNode(NULL, ntree, SH_NODE_ATTRIBUTE);
+ input_attr_alpha->locx = 400.0f;
+ input_attr_alpha->locy = 300.0f;
+ storage = (NodeShaderAttribute *)input_attr_alpha->storage;
+ BLI_strncpy(storage->name, "Alpha", sizeof(storage->name));
+
+ bNode *mix_rgb_alpha = nodeAddStaticNode(NULL, ntree, SH_NODE_MIX_RGB);
+ mix_rgb_alpha->custom1 = MA_RAMP_BLEND; // Mix
+ mix_rgb_alpha->locx = 600.0f;
+ mix_rgb_alpha->locy = 300.0f;
+ tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_alpha->inputs, 0); // Fac
+ RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, tosock, &toptr);
+ RNA_float_set(&toptr, "default_value", 0.0f);
+
+ bNode *shader_emission = nodeAddStaticNode(NULL, ntree, SH_NODE_EMISSION);
+ shader_emission->locx = 400.0f;
+ shader_emission->locy = -200.0f;
+
+ bNode *input_light_path = nodeAddStaticNode(NULL, ntree, SH_NODE_LIGHT_PATH);
+ input_light_path->locx = 400.0f;
+ input_light_path->locy = 100.0f;
+
+ bNode *mix_shader_color = nodeAddStaticNode(NULL, ntree, SH_NODE_MIX_SHADER);
+ mix_shader_color->locx = 600.0f;
+ mix_shader_color->locy = -100.0f;
+
+ bNode *shader_transparent = nodeAddStaticNode(NULL, ntree, SH_NODE_BSDF_TRANSPARENT);
+ shader_transparent->locx = 600.0f;
+ shader_transparent->locy = 100.0f;
+
+ bNode *mix_shader_alpha = nodeAddStaticNode(NULL, ntree, SH_NODE_MIX_SHADER);
+ mix_shader_alpha->locx = 800.0f;
+ mix_shader_alpha->locy = 100.0f;
+
+ bNode *output_material = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_MATERIAL);
+ output_material->locx = 1000.0f;
+ output_material->locy = 100.0f;
+
+ fromsock = (bNodeSocket *)BLI_findlink(&input_attr_color->outputs, 0); // Color
+ tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_color->inputs, 1); // Color1
+ nodeAddLink(ntree, input_attr_color, fromsock, mix_rgb_color, tosock);
+
+ fromsock = (bNodeSocket *)BLI_findlink(&mix_rgb_color->outputs, 0); // Color
+ tosock = (bNodeSocket *)BLI_findlink(&shader_emission->inputs, 0); // Color
+ nodeAddLink(ntree, mix_rgb_color, fromsock, shader_emission, tosock);
+
+ fromsock = (bNodeSocket *)BLI_findlink(&shader_emission->outputs, 0); // Emission
+ tosock = (bNodeSocket *)BLI_findlink(&mix_shader_color->inputs, 2); // Shader (second)
+ nodeAddLink(ntree, shader_emission, fromsock, mix_shader_color, tosock);
+
+ fromsock = (bNodeSocket *)BLI_findlink(&input_light_path->outputs, 0); // In Camera Ray
+ tosock = (bNodeSocket *)BLI_findlink(&mix_shader_color->inputs, 0); // Fac
+ nodeAddLink(ntree, input_light_path, fromsock, mix_shader_color, tosock);
+
+ fromsock = (bNodeSocket *)BLI_findlink(&mix_rgb_alpha->outputs, 0); // Color
+ tosock = (bNodeSocket *)BLI_findlink(&mix_shader_alpha->inputs, 0); // Fac
+ nodeAddLink(ntree, mix_rgb_alpha, fromsock, mix_shader_alpha, tosock);
+
+ fromsock = (bNodeSocket *)BLI_findlink(&input_attr_alpha->outputs, 0); // Color
+ tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_alpha->inputs, 1); // Color1
+ nodeAddLink(ntree, input_attr_alpha, fromsock, mix_rgb_alpha, tosock);
+
+ fromsock = (bNodeSocket *)BLI_findlink(&shader_transparent->outputs, 0); // BSDF
+ tosock = (bNodeSocket *)BLI_findlink(&mix_shader_alpha->inputs, 1); // Shader (first)
+ nodeAddLink(ntree, shader_transparent, fromsock, mix_shader_alpha, tosock);
+
+ fromsock = (bNodeSocket *)BLI_findlink(&mix_shader_color->outputs, 0); // Shader
+ tosock = (bNodeSocket *)BLI_findlink(&mix_shader_alpha->inputs, 2); // Shader (second)
+ nodeAddLink(ntree, mix_shader_color, fromsock, mix_shader_alpha, tosock);
+
+ fromsock = (bNodeSocket *)BLI_findlink(&mix_shader_alpha->outputs, 0); // Shader
+ tosock = (bNodeSocket *)BLI_findlink(&output_material->inputs, 0); // Surface
+ nodeAddLink(ntree, mix_shader_alpha, fromsock, output_material, tosock);
+
+ if (output_linestyle) {
+ bNodeSocket *outsock;
+ bNodeLink *link;
+
+ mix_rgb_color->custom1 = output_linestyle->custom1; // blend_type
+ mix_rgb_color->custom2 = output_linestyle->custom2; // use_clamp
+
+ outsock = (bNodeSocket *)BLI_findlink(&output_linestyle->inputs, 0); // Color
+ tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_color->inputs, 2); // Color2
+ link = (bNodeLink *)BLI_findptr(&ntree->links, outsock, offsetof(bNodeLink, tosock));
+ if (link) {
+ nodeAddLink(ntree, link->fromnode, link->fromsock, mix_rgb_color, tosock);
+ }
+ else {
+ float color[4];
+ RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, outsock, &fromptr);
+ RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, tosock, &toptr);
+ RNA_float_get_array(&fromptr, "default_value", color);
+ RNA_float_set_array(&toptr, "default_value", color);
+ }
- if (texs_are_good) {
- iStrokeRep->setMaterial(ma);
- has_mat = true;
- break; // if textures are good, no need to search anymore
+ outsock = (bNodeSocket *)BLI_findlink(&output_linestyle->inputs, 1); // Color Fac
+ tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_color->inputs, 0); // Fac
+ link = (bNodeLink *)BLI_findptr(&ntree->links, outsock, offsetof(bNodeLink, tosock));
+ if (link) {
+ nodeAddLink(ntree, link->fromnode, link->fromsock, mix_rgb_color, tosock);
+ }
+ else {
+ RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, outsock, &fromptr);
+ RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, tosock, &toptr);
+ RNA_float_set(&toptr, "default_value", RNA_float_get(&fromptr, "default_value"));
+ }
+
+ outsock = (bNodeSocket *)BLI_findlink(&output_linestyle->inputs, 2); // Alpha
+ tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_alpha->inputs, 2); // Color2
+ link = (bNodeLink *)BLI_findptr(&ntree->links, outsock, offsetof(bNodeLink, tosock));
+ if (link) {
+ nodeAddLink(ntree, link->fromnode, link->fromsock, mix_rgb_alpha, tosock);
+ }
+ else {
+ float color[4];
+ RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, outsock, &fromptr);
+ RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, tosock, &toptr);
+ color[0] = color[1] = color[2] = RNA_float_get(&fromptr, "default_value");
+ color[3] = 1.0f;
+ RNA_float_set_array(&toptr, "default_value", color);
+ }
+
+ outsock = (bNodeSocket *)BLI_findlink(&output_linestyle->inputs, 3); // Alpha Fac
+ tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_alpha->inputs, 0); // Fac
+ link = (bNodeLink *)BLI_findptr(&ntree->links, outsock, offsetof(bNodeLink, tosock));
+ if (link) {
+ nodeAddLink(ntree, link->fromnode, link->fromsock, mix_rgb_alpha, tosock);
+ }
+ else {
+ RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, outsock, &fromptr);
+ RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, tosock, &toptr);
+ RNA_float_set(&toptr, "default_value", RNA_float_get(&fromptr, "default_value"));
+ }
+
+ for (bNode *node = (bNode *)ntree->nodes.first; node; node = node->next) {
+ if (node->type == SH_NODE_UVALONGSTROKE) {
+ // UV output of the UV Along Stroke node
+ bNodeSocket *sock = (bNodeSocket *)BLI_findlink(&node->outputs, 0);
+
+ // add new UV Map node
+ bNode *input_uvmap = nodeAddStaticNode(NULL, ntree, SH_NODE_UVMAP);
+ input_uvmap->locx = node->locx - 200.0f;
+ input_uvmap->locy = node->locy;
+ NodeShaderUVMap *storage = (NodeShaderUVMap *)input_uvmap->storage;
+ if (node->custom1 & 1) { // use_tips
+ BLI_strncpy(storage->uv_map, "along_stroke_tips", sizeof(storage->uv_map));
+ }
+ else {
+ BLI_strncpy(storage->uv_map, "along_stroke", sizeof(storage->uv_map));
+ }
+ fromsock = (bNodeSocket *)BLI_findlink(&input_uvmap->outputs, 0); // UV
+
+ // replace links from the UV Along Stroke node by links from the UV Map node
+ for (bNodeLink *link = (bNodeLink *)ntree->links.first; link; link = link->next) {
+ if (link->fromnode == node && link->fromsock == sock) {
+ nodeAddLink(ntree, input_uvmap, fromsock, link->tonode, link->tosock);
+ }
+ }
+ nodeRemSocketLinks(ntree, sock);
+ }
}
}
- // If still no material, create one
- if (!has_mat) {
- Material *ma = BKE_material_add(freestyle_bmain, "stroke_material");
+ nodeSetActive(ntree, output_material);
+ ntreeUpdateTree(bmain, ntree);
- ma->mode |= MA_VERTEXCOLP;
- ma->mode |= MA_TRANSP;
- ma->mode |= MA_SHLESS;
- ma->vcol_alpha = 1;
+ return ma;
+}
- // Textures
- //for (int a = 0; a < MAX_MTEX; a++) {
- while (iStrokeRep->getMTex(a)) {
- ma->mtex[a] = (MTex *) iStrokeRep->getMTex(a);
+void BlenderStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const
+{
+ if (_use_shading_nodes) {
+ bNodeTree *nt = iStrokeRep->getNodeTree();
+ Material *ma = (Material *)BLI_ghash_lookup(_nodetree_hash, nt);
+ if (!ma) {
+ ma = BlenderStrokeRenderer::GetStrokeShader(freestyle_bmain, nt, false);
+ BLI_ghash_insert(_nodetree_hash, nt, ma);
+ }
+
+ if (strcmp(freestyle_scene->r.engine, "CYCLES") == 0) {
+ PointerRNA scene_ptr;
+ RNA_pointer_create(NULL, &RNA_Scene, freestyle_scene, &scene_ptr);
+ PointerRNA cycles_ptr = RNA_pointer_get(&scene_ptr, "cycles");
+ RNA_boolean_set(&cycles_ptr, "film_transparent", 1);
+ }
- // 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));
+ iStrokeRep->setMaterial(ma);
+ }
+ else {
+ 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;
+ }
}
- else {
- BLI_strncpy(ma->mtex[a]->uvname, "along_stroke", sizeof(ma->mtex[a]->uvname));
+
+ if (texs_are_good) {
+ iStrokeRep->setMaterial(ma);
+ has_mat = true;
+ break; // if textures are good, no need to search anymore
}
- a++;
}
- iStrokeRep->setMaterial(ma);
+
+ // 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
+ 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);
@@ -318,7 +567,7 @@ void BlenderStrokeRenderer::test_strip_visibility(Strip::vertex_container& strip
void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
{
vector<Strip*>& strips = iStrokeRep->getStrips();
- const bool hasTex = iStrokeRep->getMTex(0) != NULL;
+ const bool hasTex = iStrokeRep->hasTex();
Strip::vertex_container::iterator v[3];
StrokeVertexRep *svRep[3];
unsigned int vertex_index, edge_index, loop_index;
@@ -355,22 +604,35 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
// vertices allocation
mesh->totvert = totvert; // visible_faces + visible_segments * 2;
- mesh->mvert = (MVert *)CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CALLOC, NULL, mesh->totvert);
+ CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CALLOC, NULL, mesh->totvert);
// edges allocation
mesh->totedge = totedge; // visible_faces * 2 + visible_segments;
- mesh->medge = (MEdge *)CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_CALLOC, NULL, mesh->totedge);
+ CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_CALLOC, NULL, mesh->totedge);
// faces allocation
mesh->totpoly = totpoly; // visible_faces;
- mesh->mpoly = (MPoly *)CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_CALLOC, NULL, mesh->totpoly);
+ CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_CALLOC, NULL, mesh->totpoly);
// loops allocation
mesh->totloop = totloop; // visible_faces * 3;
- mesh->mloop = (MLoop *)CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_CALLOC, NULL, mesh->totloop);
+ CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_CALLOC, NULL, mesh->totloop);
- // colors allocation
- mesh->mloopcol = (MLoopCol *)CustomData_add_layer(&mesh->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, mesh->totloop);
+ // uv maps
+ MLoopUV *loopsuv[2] = { NULL };
+ if (hasTex) {
+ loopsuv[0] = (MLoopUV *)CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_CALLOC, NULL, mesh->totloop, "along_stroke");
+ loopsuv[1] = (MLoopUV *)CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_CALLOC, NULL, mesh->totloop, "along_stroke_tips");
+
+ CustomData_add_layer_named(&mesh->pdata, CD_MTEXPOLY, CD_CALLOC, NULL, mesh->totpoly, "along_stroke");
+ CustomData_add_layer_named(&mesh->pdata, CD_MTEXPOLY, CD_CALLOC, NULL, mesh->totpoly, "along_stroke_tips");
+ }
+
+ // colors and transparency (the latter represented by grayscale colors)
+ MLoopCol *colors = (MLoopCol *)CustomData_add_layer_named(&mesh->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, mesh->totloop, "Color");
+ MLoopCol *transp = (MLoopCol *)CustomData_add_layer_named(&mesh->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, mesh->totloop, "Alpha");
+
+ BKE_mesh_update_customdata_pointers(mesh, true);
////////////////////
// Data copy
@@ -380,28 +642,6 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
MEdge *edges = mesh->medge;
MPoly *polys = mesh->mpoly;
MLoop *loops = mesh->mloop;
- MLoopCol *colors = mesh->mloopcol;
- MLoopUV *loopsuv[2] = {NULL};
-
- if (hasTex) {
- // 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;
- }
vertex_index = edge_index = loop_index = 0;
@@ -540,7 +780,7 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
}
}
- // colors
+ // colors and alpha transparency
if (is_odd) {
colors[0].r = (short)(255.0f * svRep[2]->color()[0]);
colors[0].g = (short)(255.0f * svRep[2]->color()[1]);
@@ -556,7 +796,7 @@ 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]);
@@ -573,7 +813,11 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
colors[2].b = (short)(255.0f * svRep[0]->color()[2]);
colors[2].a = (short)(255.0f * svRep[0]->alpha());
}
+ transp[0].r = transp[0].g = transp[0].b = colors[0].a;
+ transp[1].r = transp[1].g = transp[1].b = colors[1].a;
+ transp[2].r = transp[2].g = transp[2].b = colors[2].a;
colors += 3;
+ transp += 3;
}
} // loop over strip vertices
} // loop over strips