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/freestyle/intern
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/freestyle/intern')
-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
14 files changed, 783 insertions, 181 deletions
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