59 createStrip(iStrokeVertices);
61 setVertexColor(iStrokeVertices);
65 computeTexCoord(iStrokeVertices, texStep);
66 computeTexCoordWithTips(iStrokeVertices, tipBegin, tipEnd, texStep);
73 for (vertex_container::const_iterator
v = iBrother.
_vertices.begin(),
85 if (!_vertices.empty()) {
86 for (vertex_container::iterator
v = _vertices.begin(), vend = _vertices.end();
v != vend;
98 #define EPS_SINGULARITY_RENDERER 0.05
100 #define MAX_RATIO_LENGTH_SINGU 2
101 #define HUGE_COORD 1.0e4
105 return (p[0] != p[0]) || (p[1] != p[1]) || (
fabs(p[0]) >
HUGE_COORD) ||
112 return A[0] *
B[1] -
A[1] *
B[0];
116 void Strip::createStrip(
const vector<StrokeVertex *> &iStrokeVertices)
119 if (iStrokeVertices.size() < 2) {
121 cout <<
"Warning: strip has less than 2 vertices" << endl;
125 _vertices.reserve(2 * iStrokeVertices.size());
126 if (!_vertices.empty()) {
127 for (vertex_container::iterator
v = _vertices.begin(), vend = _vertices.end();
v != vend;
133 _averageThickness = 0.0;
135 vector<StrokeVertex *>::const_iterator
v, vend,
v2, vPrev;
137 int orientationErrors = 0;
140 v2 =
v = iStrokeVertices.begin();
146 Vec2r orthDir(-dir[1], dir[0]);
150 Vec2r stripDir(orthDir);
154 if (userDir.
norm() > 1
e-6) {
156 real dp = userDir * orthDir;
158 userDir = userDir * (-1.0f);
171 Vec2r userDir = _stroke->getBeginningOrientation();
172 if (userDir !=
Vec2r(0, 0)) {
174 real o1 = (orthDir * userDir);
175 real o2 = crossP(orthDir, userDir);
176 real orientation = o1 * o2;
177 if (orientation > 0) {
180 _vertex[0] = _vertex[1] + userDir;
183 _vertex[0] = _vertex[1] - userDir;
186 if (orientation < 0) {
189 _vertex[1] = _vertex[0] + userDir;
192 _vertex[1] = _vertex[0] - userDir;
200 for (vend = iStrokeVertices.end(), ++
v, ++
v2;
v2 != vend; vPrev =
v++, ++
v2) {
208 float dirNorm = dir.
norm();
210 Vec2r orthDir(-dir[1], dir[0]);
211 Vec2r stripDir = orthDir;
214 if (userDir.
norm() > 1
e-6) {
216 real dp = userDir * orthDir;
218 userDir = userDir * (-1.0f);
228 Vec2r dirPrev(p - pPrev);
229 float dirPrevNorm = dirPrev.
norm();
231 Vec2r orthDirPrev(-dirPrev[1], dirPrev[0]);
232 Vec2r stripDirPrev = orthDirPrev;
235 if (userDir.
norm() > 1
e-6) {
237 real dp = userDir * orthDir;
239 userDir = userDir * (-1.0f);
241 stripDirPrev = userDir;
249 _averageThickness += thickness[0] + thickness[1];
254 Vec2r(p + thickness[1] * stripDirPrev),
255 Vec2r(p + thickness[1] * stripDir),
256 Vec2r(p2 + thickness[1] * stripDir),
267 Vec2r(p - thickness[0] * stripDirPrev),
268 Vec2r(p - thickness[0] * stripDir),
269 Vec2r(p2 - thickness[0] * stripDir),
280 stripDir = stripDir + stripDirPrev;
289 Vec2r vec_tmp(_vertices[i - 2]->point2d() - p);
291 (dirPrevNorm <
ZERO) ||
notValid(_vertices[i - 2]->point2d()) ||
293 _vertices[i - 2]->setPoint2d(p + thickness[1] * stripDir);
296 vec_tmp = _vertices[i - 1]->point2d() - p;
298 (dirPrevNorm <
ZERO) ||
notValid(_vertices[i - 1]->point2d()) ||
300 _vertices[i - 1]->setPoint2d(p - thickness[0] * stripDir);
308 orthDir =
Vec2r(-dir[1], dir[0]);
312 Vec2r stripDirLast(orthDir);
316 if (userDir.
norm() > 1
e-6) {
318 real dp = userDir * orthDir;
320 userDir = userDir * (-1.0f);
322 stripDirLast = userDir;
337 userDir = _stroke->getEndingOrientation();
338 if (userDir !=
Vec2r(0, 0)) {
340 real o1 = (orthDir * userDir);
341 real o2 = crossP(orthDir, userDir);
342 real orientation = o1 * o2;
343 if (orientation > 0) {
346 _vertex[n] = _vertex[n - 1] + userDir;
349 _vertex[n] = _vertex[n - 1] - userDir;
352 if (orientation < 0) {
355 _vertex[n - 1] = _vertex[n] + userDir;
358 _vertex[n - 1] = _vertex[n] - userDir;
364 _averageThickness /=
float(iStrokeVertices.size() - 2);
366 if (iStrokeVertices.size() < 3) {
367 _averageThickness = 0.5 * (thicknessLast[1] + thicknessLast[0] + thickness[0] + thickness[1]);
370 if (orientationErrors > 0) {
372 cout <<
"Warning: " << orientationErrors
373 <<
" invalid zero-length orientation vector(s) found.\n";
377 if (i != 2 * (
int)iStrokeVertices.size()) {
379 cout <<
"Warning: problem with stripe size\n";
383 cleanUpSingularities(iStrokeVertices);
389 void Strip::cleanUpSingularities(
const vector<StrokeVertex *> &iStrokeVertices)
392 int sizeStrip = _vertices.size();
394 for (k = 0; k < sizeStrip; k++) {
395 if (
notValid(_vertices[k]->point2d())) {
397 cout <<
"Warning: strip vertex " << k <<
" non valid" << endl;
404 if (iStrokeVertices.size() < 2) {
408 vector<StrokeVertex *>::const_iterator
v, vend,
v2;
411 bool singu1 =
false, singu2 =
false;
412 int timeSinceSingu1 = 0, timeSinceSingu2 = 0;
415 v = iStrokeVertices.begin();
416 for (vend = iStrokeVertices.end();
v != vend;
v++) {
431 dir1 = _vertices[2 * i + 2]->point2d() - _vertices[2 * i]->point2d();
432 dir2 = _vertices[2 * i + 3]->point2d() - _vertices[2 * i + 1]->point2d();
434 if ((dir1 * dir) < -
ZERO) {
440 int toto = i - timeSinceSingu1;
442 cerr <<
"Stephane dit \"Toto\"" << endl;
446 for (j = i - timeSinceSingu1; j <= i; j++) {
447 avP =
Vec2r(avP + _vertices[2 * j]->point2d());
449 avP =
Vec2r(1.0 /
float(timeSinceSingu1 + 1) * avP);
450 for (j = i - timeSinceSingu1; j <= i; j++) {
451 _vertices[2 * j]->setPoint2d(avP);
458 if ((dir2 * dir) < -
ZERO) {
464 int toto = i - timeSinceSingu2;
466 cerr <<
"Stephane dit \"Toto\"" << endl;
470 for (j = i - timeSinceSingu2; j <= i; j++) {
471 avP =
Vec2r(avP + _vertices[2 * j + 1]->point2d());
473 avP =
Vec2r(1.0 /
float(timeSinceSingu2 + 1) * avP);
474 for (j = i - timeSinceSingu2; j <= i; j++) {
475 _vertices[2 * j + 1]->setPoint2d(avP);
488 for (j = i - timeSinceSingu1; j < i; j++) {
489 avP =
Vec2r(avP + _vertices[2 * j]->point2d());
491 avP =
Vec2r(1.0 /
float(timeSinceSingu1) * avP);
492 for (j = i - timeSinceSingu1; j < i; j++) {
493 _vertices[2 * j]->setPoint2d(avP);
499 for (j = i - timeSinceSingu2; j < i; j++) {
500 avP =
Vec2r(avP + _vertices[2 * j + 1]->point2d());
502 avP =
Vec2r(1.0 /
float(timeSinceSingu2) * avP);
503 for (j = i - timeSinceSingu2; j < i; j++) {
504 _vertices[2 * j + 1]->setPoint2d(avP);
508 for (k = 0; k < sizeStrip; k++) {
509 if (
notValid(_vertices[k]->point2d())) {
511 cout <<
"Warning: strip vertex " << k <<
" non valid after cleanup" << endl;
521 void Strip::setVertexColor(
const vector<StrokeVertex *> &iStrokeVertices)
523 vector<StrokeVertex *>::const_iterator
v, vend;
526 for (
v = iStrokeVertices.begin(), vend = iStrokeVertices.end();
v != vend;
v++) {
544 void Strip::computeTexCoord(
const vector<StrokeVertex *> &iStrokeVertices,
float texStep)
546 vector<StrokeVertex *>::const_iterator
v, vend;
549 for (
v = iStrokeVertices.begin(), vend = iStrokeVertices.end();
v != vend;
v++) {
551 _vertices[i]->setTexCoord(
554 _vertices[i]->setTexCoord(
560 void Strip::computeTexCoordWithTips(
const vector<StrokeVertex *> &iStrokeVertices,
565 vector<StrokeVertex *>::const_iterator
v, vend;
570 float u = 0, uPrev = 0;
573 float spacedThickness = _averageThickness * texStep;
575 v = iStrokeVertices.begin();
576 vend = iStrokeVertices.end();
577 l = (*v)->strokeLength() / spacedThickness;
578 tiles = std::roundf(
l);
579 fact = (
float(tiles) + 0.5) /
l;
582 cerr <<
"l=" <<
l <<
" tiles=" << tiles <<
" _averageThicnkess=" << _averageThickness
583 <<
" strokeLength=" << (*v)->strokeLength() << endl;
586 vector<StrokeVertexRep *>::iterator currentSV = _vertices.begin();
589 for (;
v != vend;
v++) {
608 if (
v != vend && i >= 2) {
611 t = (0.25 - uPrev) / (u - uPrev);
616 for (
int k = 0; k < 2; k++) {
618 t * _vertices[i]->point2d());
619 tvRep[k]->
setTexCoord((1 -
t) * _vertices[i - 2]->texCoord() +
620 t * _vertices[i]->texCoord());
623 tvRep[k]->
setColor((1 -
t) * _vertices[i - 2]->color() +
628 for (
int k = 0; k < 2; k++) {
629 currentSV = _vertices.insert(currentSV, tvRep[k]);
634 for (
int k = 0; k < 2; k++) {
640 for (
int k = 0; k < 2; k++) {
641 currentSV = _vertices.insert(currentSV, tvRep[k]);
649 for (;
v != vend;
v++) {
670 if (
v != vend && i >= 2) {
673 t = (
float(tiles) - uPrev) / (u - uPrev);
678 for (
int k = 0; k < 2; k++) {
680 t * _vertices[i]->point2d());
681 tvRep[k]->
setTexCoord((1 -
t) * _vertices[i - 2]->texCoord() +
682 t * _vertices[i]->texCoord());
685 tvRep[k]->
setColor((1 -
t) * _vertices[i - 2]->color() +
690 for (
int k = 0; k < 2; k++) {
691 currentSV = _vertices.insert(currentSV, tvRep[k]);
696 for (
int k = 0; k < 2; k++) {
702 for (
int k = 0; k < 2; k++) {
703 currentSV = _vertices.insert(currentSV, tvRep[k]);
709 for (;
v != vend;
v++) {
726 cerr <<
"u=" << u <<
" i=" << i <<
"/" << _sizeStrip << endl;
728 for (i = 0; i < _sizeStrip; i++) {
732 for (i = 0; i < _sizeStrip; i++) {
733 cerr <<
"(" << _texCoord[i][0] <<
", " << _texCoord[i][1] <<
") ";
738 for (i = 0; i < _sizeStrip / 2; i++) {
739 vec_tmp = _vertex[2 * i] - _vertex[2 * i + 1];
741 if (vec_tmp.
norm() > 4 * _averageThickness) {
742 cerr <<
"Warning (from Fredo): There is a pb in the texture coordinates computation" << endl;
751 StrokeRep::StrokeRep()
754 _strokeType = Stroke::OPAQUE_MEDIUM;
766 _averageTextureAlpha = 0.5;
767 if (_strokeType == OIL_STROKE) {
768 _averageTextureAlpha = 0.75;
770 if (_strokeType >= NO_BLEND_STROKE) {
771 _averageTextureAlpha = 1.0;
781 _hasTex = iStroke->
hasTex();
792 if (_textureId == 0) {
800 _averageTextureAlpha = 0.5;
801 if (_strokeType == OIL_STROKE) {
802 _averageTextureAlpha = 0.75;
804 if (_strokeType >= NO_BLEND_STROKE) {
805 _averageTextureAlpha = 1.0;
828 for (vector<Strip *>::const_iterator s = iBrother.
_strips.begin(), send = iBrother.
_strips.end();
831 _strips.push_back(
new Strip(**s));
835 StrokeRep::~StrokeRep()
837 if (!_strips.empty()) {
838 for (vector<Strip *>::iterator s = _strips.begin(), send = _strips.end(); s != send; ++s) {
845 void StrokeRep::create()
847 vector<StrokeVertex *> strip;
854 while ((
v != vend) && (!(*v).attribute().isVisible())) {
858 while ((
v != vend) && ((*v).attribute().isVisible())) {
859 strip.push_back(&(*
v));
864 strip.push_back(&(*
v));
869 if ((!strip.empty()) && (strip.size() > 1)) {
870 _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
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()
static CCL_NAMESPACE_BEGIN const double alpha
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)
ccl_device_inline float2 fabs(const float2 &a)