45 createStrip(iStrokeVertices);
47 setVertexColor(iStrokeVertices);
51 computeTexCoord(iStrokeVertices, texStep);
52 computeTexCoordWithTips(iStrokeVertices, tipBegin, tipEnd, texStep);
59 for (vertex_container::const_iterator
v = iBrother.
_vertices.begin(),
71 if (!_vertices.empty()) {
72 for (vertex_container::iterator
v = _vertices.begin(), vend = _vertices.end();
v != vend;
84 #define EPS_SINGULARITY_RENDERER 0.05
86 #define MAX_RATIO_LENGTH_SINGU 2
87 #define HUGE_COORD 1.0e4
91 return (p[0] != p[0]) || (p[1] != p[1]) || (
fabs(p[0]) >
HUGE_COORD) ||
98 return A[0] *
B[1] -
A[1] *
B[0];
102 void Strip::createStrip(
const vector<StrokeVertex *> &iStrokeVertices)
105 if (iStrokeVertices.size() < 2) {
107 cout <<
"Warning: strip has less than 2 vertices" << endl;
111 _vertices.reserve(2 * iStrokeVertices.size());
112 if (!_vertices.empty()) {
113 for (vertex_container::iterator
v = _vertices.begin(), vend = _vertices.end();
v != vend;
119 _averageThickness = 0.0;
121 vector<StrokeVertex *>::const_iterator
v, vend,
v2, vPrev;
123 int orientationErrors = 0;
126 v2 =
v = iStrokeVertices.begin();
132 Vec2r orthDir(-dir[1], dir[0]);
136 Vec2r stripDir(orthDir);
140 if (userDir.
norm() > 1
e-6) {
142 real dp = userDir * orthDir;
144 userDir = userDir * (-1.0f);
157 Vec2r userDir = _stroke->getBeginningOrientation();
158 if (userDir !=
Vec2r(0, 0)) {
160 real o1 = (orthDir * userDir);
161 real o2 = crossP(orthDir, userDir);
162 real orientation = o1 * o2;
163 if (orientation > 0) {
166 _vertex[0] = _vertex[1] + userDir;
169 _vertex[0] = _vertex[1] - userDir;
172 if (orientation < 0) {
175 _vertex[1] = _vertex[0] + userDir;
178 _vertex[1] = _vertex[0] - userDir;
186 for (vend = iStrokeVertices.end(), ++
v, ++
v2;
v2 != vend; vPrev =
v++, ++
v2) {
194 float dirNorm = dir.
norm();
196 Vec2r orthDir(-dir[1], dir[0]);
197 Vec2r stripDir = orthDir;
200 if (userDir.
norm() > 1
e-6) {
202 real dp = userDir * orthDir;
204 userDir = userDir * (-1.0f);
214 Vec2r dirPrev(p - pPrev);
215 float dirPrevNorm = dirPrev.
norm();
217 Vec2r orthDirPrev(-dirPrev[1], dirPrev[0]);
218 Vec2r stripDirPrev = orthDirPrev;
221 if (userDir.
norm() > 1
e-6) {
223 real dp = userDir * orthDir;
225 userDir = userDir * (-1.0f);
227 stripDirPrev = userDir;
235 _averageThickness += thickness[0] + thickness[1];
240 Vec2r(p + thickness[1] * stripDirPrev),
241 Vec2r(p + thickness[1] * stripDir),
242 Vec2r(p2 + thickness[1] * stripDir),
253 Vec2r(p - thickness[0] * stripDirPrev),
254 Vec2r(p - thickness[0] * stripDir),
255 Vec2r(p2 - thickness[0] * stripDir),
266 stripDir = stripDir + stripDirPrev;
275 Vec2r vec_tmp(_vertices[i - 2]->point2d() - p);
277 (dirPrevNorm <
ZERO) ||
notValid(_vertices[i - 2]->point2d()) ||
279 _vertices[i - 2]->setPoint2d(p + thickness[1] * stripDir);
282 vec_tmp = _vertices[i - 1]->point2d() - p;
284 (dirPrevNorm <
ZERO) ||
notValid(_vertices[i - 1]->point2d()) ||
286 _vertices[i - 1]->setPoint2d(p - thickness[0] * stripDir);
294 orthDir =
Vec2r(-dir[1], dir[0]);
298 Vec2r stripDirLast(orthDir);
302 if (userDir.
norm() > 1
e-6) {
304 real dp = userDir * orthDir;
306 userDir = userDir * (-1.0f);
308 stripDirLast = userDir;
323 userDir = _stroke->getEndingOrientation();
324 if (userDir !=
Vec2r(0, 0)) {
326 real o1 = (orthDir * userDir);
327 real o2 = crossP(orthDir, userDir);
328 real orientation = o1 * o2;
329 if (orientation > 0) {
332 _vertex[n] = _vertex[n - 1] + userDir;
335 _vertex[n] = _vertex[n - 1] - userDir;
338 if (orientation < 0) {
341 _vertex[n - 1] = _vertex[n] + userDir;
344 _vertex[n - 1] = _vertex[n] - userDir;
350 _averageThickness /=
float(iStrokeVertices.size() - 2);
352 if (iStrokeVertices.size() < 3) {
353 _averageThickness = 0.5 * (thicknessLast[1] + thicknessLast[0] + thickness[0] + thickness[1]);
356 if (orientationErrors > 0) {
358 cout <<
"Warning: " << orientationErrors
359 <<
" invalid zero-length orientation vector(s) found.\n";
363 if (i != 2 * (
int)iStrokeVertices.size()) {
365 cout <<
"Warning: problem with stripe size\n";
369 cleanUpSingularities(iStrokeVertices);
375 void Strip::cleanUpSingularities(
const vector<StrokeVertex *> &iStrokeVertices)
378 int sizeStrip = _vertices.size();
380 for (k = 0; k < sizeStrip; k++) {
381 if (
notValid(_vertices[k]->point2d())) {
383 cout <<
"Warning: strip vertex " << k <<
" non valid" << endl;
390 if (iStrokeVertices.size() < 2) {
394 vector<StrokeVertex *>::const_iterator
v, vend,
v2;
397 bool singu1 =
false, singu2 =
false;
398 int timeSinceSingu1 = 0, timeSinceSingu2 = 0;
401 v = iStrokeVertices.begin();
402 for (vend = iStrokeVertices.end();
v != vend;
v++) {
417 dir1 = _vertices[2 * i + 2]->point2d() - _vertices[2 * i]->point2d();
418 dir2 = _vertices[2 * i + 3]->point2d() - _vertices[2 * i + 1]->point2d();
420 if ((dir1 * dir) < -
ZERO) {
426 int toto = i - timeSinceSingu1;
428 cerr <<
"Stephane dit \"Toto\"" << endl;
432 for (j = i - timeSinceSingu1; j <= i; j++) {
433 avP =
Vec2r(avP + _vertices[2 * j]->point2d());
435 avP =
Vec2r(1.0 /
float(timeSinceSingu1 + 1) * avP);
436 for (j = i - timeSinceSingu1; j <= i; j++) {
437 _vertices[2 * j]->setPoint2d(avP);
444 if ((dir2 * dir) < -
ZERO) {
450 int toto = i - timeSinceSingu2;
452 cerr <<
"Stephane dit \"Toto\"" << endl;
456 for (j = i - timeSinceSingu2; j <= i; j++) {
457 avP =
Vec2r(avP + _vertices[2 * j + 1]->point2d());
459 avP =
Vec2r(1.0 /
float(timeSinceSingu2 + 1) * avP);
460 for (j = i - timeSinceSingu2; j <= i; j++) {
461 _vertices[2 * j + 1]->setPoint2d(avP);
474 for (j = i - timeSinceSingu1; j < i; j++) {
475 avP =
Vec2r(avP + _vertices[2 * j]->point2d());
477 avP =
Vec2r(1.0 /
float(timeSinceSingu1) * avP);
478 for (j = i - timeSinceSingu1; j < i; j++) {
479 _vertices[2 * j]->setPoint2d(avP);
485 for (j = i - timeSinceSingu2; j < i; j++) {
486 avP =
Vec2r(avP + _vertices[2 * j + 1]->point2d());
488 avP =
Vec2r(1.0 /
float(timeSinceSingu2) * avP);
489 for (j = i - timeSinceSingu2; j < i; j++) {
490 _vertices[2 * j + 1]->setPoint2d(avP);
494 for (k = 0; k < sizeStrip; k++) {
495 if (
notValid(_vertices[k]->point2d())) {
497 cout <<
"Warning: strip vertex " << k <<
" non valid after cleanup" << endl;
507 void Strip::setVertexColor(
const vector<StrokeVertex *> &iStrokeVertices)
509 vector<StrokeVertex *>::const_iterator
v, vend;
512 for (
v = iStrokeVertices.begin(), vend = iStrokeVertices.end();
v != vend;
v++) {
530 void Strip::computeTexCoord(
const vector<StrokeVertex *> &iStrokeVertices,
float texStep)
532 vector<StrokeVertex *>::const_iterator
v, vend;
535 for (
v = iStrokeVertices.begin(), vend = iStrokeVertices.end();
v != vend;
v++) {
537 _vertices[i]->setTexCoord(
540 _vertices[i]->setTexCoord(
546 void Strip::computeTexCoordWithTips(
const vector<StrokeVertex *> &iStrokeVertices,
551 vector<StrokeVertex *>::const_iterator
v, vend;
556 float u = 0, uPrev = 0;
559 float spacedThickness = _averageThickness * texStep;
561 v = iStrokeVertices.begin();
562 vend = iStrokeVertices.end();
563 l = (*v)->strokeLength() / spacedThickness;
568 cerr <<
"l=" <<
l <<
" tiles=" <<
tiles <<
" _averageThicnkess=" << _averageThickness
569 <<
" strokeLength=" << (*v)->strokeLength() << endl;
572 vector<StrokeVertexRep *>::iterator currentSV = _vertices.begin();
575 for (;
v != vend;
v++) {
594 if (
v != vend && i >= 2) {
597 t = (0.25 - uPrev) / (u - uPrev);
602 for (
int k = 0; k < 2; k++) {
604 t * _vertices[i]->point2d());
605 tvRep[k]->
setTexCoord((1 -
t) * _vertices[i - 2]->texCoord() +
606 t * _vertices[i]->texCoord());
614 for (
int k = 0; k < 2; k++) {
615 currentSV = _vertices.insert(currentSV, tvRep[k]);
620 for (
int k = 0; k < 2; k++) {
626 for (
int k = 0; k < 2; k++) {
627 currentSV = _vertices.insert(currentSV, tvRep[k]);
635 for (;
v != vend;
v++) {
656 if (
v != vend && i >= 2) {
664 for (
int k = 0; k < 2; k++) {
666 t * _vertices[i]->point2d());
667 tvRep[k]->
setTexCoord((1 -
t) * _vertices[i - 2]->texCoord() +
668 t * _vertices[i]->texCoord());
676 for (
int k = 0; k < 2; k++) {
677 currentSV = _vertices.insert(currentSV, tvRep[k]);
682 for (
int k = 0; k < 2; k++) {
688 for (
int k = 0; k < 2; k++) {
689 currentSV = _vertices.insert(currentSV, tvRep[k]);
695 for (;
v != vend;
v++) {
712 cerr <<
"u=" << u <<
" i=" << i <<
"/" << _sizeStrip << endl;
714 for (i = 0; i < _sizeStrip; i++) {
718 for (i = 0; i < _sizeStrip; i++) {
719 cerr <<
"(" << _texCoord[i][0] <<
", " << _texCoord[i][1] <<
") ";
724 for (i = 0; i < _sizeStrip / 2; i++) {
725 vec_tmp = _vertex[2 * i] - _vertex[2 * i + 1];
727 if (vec_tmp.
norm() > 4 * _averageThickness) {
728 cerr <<
"Warning (from Fredo): There is a pb in the texture coordinates computation" << endl;
737 StrokeRep::StrokeRep()
740 _strokeType = Stroke::OPAQUE_MEDIUM;
752 _averageTextureAlpha = 0.5;
753 if (_strokeType == OIL_STROKE) {
754 _averageTextureAlpha = 0.75;
756 if (_strokeType >= NO_BLEND_STROKE) {
757 _averageTextureAlpha = 1.0;
767 _hasTex = iStroke->
hasTex();
778 if (_textureId == 0) {
786 _averageTextureAlpha = 0.5;
787 if (_strokeType == OIL_STROKE) {
788 _averageTextureAlpha = 0.75;
790 if (_strokeType >= NO_BLEND_STROKE) {
791 _averageTextureAlpha = 1.0;
814 for (vector<Strip *>::const_iterator s = iBrother.
_strips.begin(), send = iBrother.
_strips.end();
817 _strips.push_back(
new Strip(**s));
821 StrokeRep::~StrokeRep()
823 if (!_strips.empty()) {
824 for (vector<Strip *>::iterator s = _strips.begin(), send = _strips.end(); s != send; ++s) {
833 vector<StrokeVertex *> strip;
840 while ((
v != vend) && (!(*v).attribute().isVisible())) {
844 while ((
v != vend) && ((*v).attribute().isVisible())) {
845 strip.push_back(&(*
v));
850 strip.push_back(&(*
v));
855 if ((!strip.empty()) && (strip.size() > 1)) {
856 _strips.push_back(
new Strip(strip, _hasTex, first, end, _textureStep));
typedef float(TangentPoint)[2]
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
Iterators used to iterate over the elements of the Stroke. Can't be used in python.
Iterators used to iterate over the elements of the Stroke.
Classes to render a stroke with OpenGL.
#define EPS_SINGULARITY_RENDERER
#define MAX_RATIO_LENGTH_SINGU
Class to define the representation of a stroke (for display purpose)
Classes to define a stroke.
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
vertex_container _vertices
Vec3f getColorRGB() const
const float * getThickness() const
bool isAttributeAvailableVec2f(const char *iName) const
const float * getColor() const
Vec2f getAttributeVec2f(const char *iName) const
virtual void RenderStrokeRep(StrokeRep *iStrokeRep) const =0
Stroke::MediumType _strokeType
vector< Strip * > _strips
void setTexCoord(const Vec2r &p, bool tips=false)
void setColor(const Vec3r &p)
float curvilinearAbscissa() const
const StrokeAttribute & attribute() const
bNodeTree * getNodeTree()
MediumType getMediumType() const
unsigned int getTextureId()
unsigned int getDefaultTextureId() const
Vec< T, N > & normalize()
ccl_gpu_kernel_postfix ccl_global KernelWorkTile * tiles
ccl_device_inline float2 fabs(const float2 &a)
intersection_test intersect2dLine2dLine(const Vec2r &p1, const Vec2r &p2, const Vec2r &p3, const Vec2r &p4, Vec2r &res)
VecMat::Vec2< real > Vec2r
VecMat::Vec3< real > Vec3r
static bool notValid(Vec2r p)
std::unique_ptr< IDProperty, IDPropertyDeleter > create(StringRefNull prop_name, int32_t value)
Allocate a new IDProperty of type IDP_INT, set its name and value.