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/stroke/StrokeRep.cpp')
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeRep.cpp1384
1 files changed, 711 insertions, 673 deletions
diff --git a/source/blender/freestyle/intern/stroke/StrokeRep.cpp b/source/blender/freestyle/intern/stroke/StrokeRep.cpp
index 91f9d866c86..e69b4dab712 100644
--- a/source/blender/freestyle/intern/stroke/StrokeRep.cpp
+++ b/source/blender/freestyle/intern/stroke/StrokeRep.cpp
@@ -1,652 +1,689 @@
-
-//
-// Copyright (C) : Please refer to the COPYRIGHT file distributed
-// with this source distribution.
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/stroke/StrokeRep.cpp
+ * \ingroup freestyle
+ * \brief Class to define the representation of a stroke (for display purpose)
+ * \author Stephane Grabli
+ * \date 05/03/2003
+ */
#include "Stroke.h"
-#include "StrokeRep.h"
-#include "StrokeRenderer.h"
#include "StrokeAdvancedIterators.h"
#include "StrokeIterators.h"
+#include "StrokeRenderer.h"
+#include "StrokeRep.h"
using namespace std;
//
// STROKE VERTEX REP
/////////////////////////////////////
-StrokeVertexRep::StrokeVertexRep(const StrokeVertexRep& iBrother){
- _point2d = iBrother._point2d;
- _texCoord = iBrother._texCoord;
- _color = iBrother._color;
- _alpha = iBrother._alpha;
+
+StrokeVertexRep::StrokeVertexRep(const StrokeVertexRep& iBrother)
+{
+ _point2d = iBrother._point2d;
+ _texCoord = iBrother._texCoord;
+ _color = iBrother._color;
+ _alpha = iBrother._alpha;
}
//
// STRIP
/////////////////////////////////////
-Strip::Strip(const vector<StrokeVertex*>& iStrokeVertices, bool hasTips, bool beginTip, bool endTip){
- createStrip(iStrokeVertices);
- if (!hasTips)
- computeTexCoord (iStrokeVertices);
- else
- computeTexCoordWithTips (iStrokeVertices, beginTip, endTip);
+Strip::Strip(const vector<StrokeVertex*>& iStrokeVertices, bool hasTips, bool beginTip, bool endTip)
+{
+ createStrip(iStrokeVertices);
+ if (!hasTips)
+ computeTexCoord (iStrokeVertices);
+ else
+ computeTexCoordWithTips (iStrokeVertices, beginTip, endTip);
}
-Strip::Strip(const Strip& iBrother){
- if(!iBrother._vertices.empty()){
- for(vertex_container::const_iterator v=iBrother._vertices.begin(), vend=iBrother._vertices.end();
- v!=vend;
- ++v){
- _vertices.push_back(new StrokeVertexRep(**v));
- }
- }
- _averageThickness = iBrother._averageThickness;
+
+Strip::Strip(const Strip& iBrother)
+{
+ if (!iBrother._vertices.empty()) {
+ for (vertex_container::const_iterator v = iBrother._vertices.begin(), vend = iBrother._vertices.end();
+ v != vend;
+ ++v)
+ {
+ _vertices.push_back(new StrokeVertexRep(**v));
+ }
+ }
+ _averageThickness = iBrother._averageThickness;
}
-Strip::~Strip(){
- if(!_vertices.empty()){
- for(vertex_container::iterator v=_vertices.begin(), vend=_vertices.end();
- v!=vend;
- ++v){
- delete (*v);
- }
- _vertices.clear();
- }
+Strip::~Strip()
+{
+ if (!_vertices.empty()) {
+ for (vertex_container::iterator v = _vertices.begin(), vend = _vertices.end(); v != vend; ++v) {
+ delete (*v);
+ }
+ _vertices.clear();
+ }
}
//////////////////////////
// Strip creation
//////////////////////////
+
#define EPS_SINGULARITY_RENDERER 0.05
#define ZERO 0.00001
#define MAX_RATIO_LENGTH_SINGU 2
-#define HUGE_COORD 1e4
+#define HUGE_COORD 1.0e4
static bool notValid (Vec2r p)
{
- return (p[0]!=p[0]) || (p[1]!=p[1]) || (fabs(p[0])>HUGE_COORD) || (fabs(p[1])>HUGE_COORD)
- || (p[0] <-HUGE_COORD) || (p[1]<-HUGE_COORD);
+ return (p[0] != p[0]) || (p[1] != p[1]) || (fabs(p[0]) > HUGE_COORD) || (fabs(p[1]) > HUGE_COORD) ||
+ (p[0] < -HUGE_COORD) || (p[1] < -HUGE_COORD);
}
-static real crossP(const Vec2r& A, const Vec2r& B){
- return A[0]*B[1] - A[1]*B[0];
+static real crossP(const Vec2r& A, const Vec2r& B)
+{
+ return A[0] * B[1] - A[1] * B[0];
}
-void
-Strip::createStrip (const vector<StrokeVertex*>& iStrokeVertices)
+void Strip::createStrip (const vector<StrokeVertex*>& iStrokeVertices)
{
- //computeParameterization();
- if (iStrokeVertices.size() <2)
- {
- cerr << "Warning: strip has less than 2 vertices" << endl;
- return;
- }
- _vertices.reserve(2*iStrokeVertices.size());
- if(!_vertices.empty()){
- for(vertex_container::iterator v=_vertices.begin(), vend=_vertices.end();
- v!=vend;
- ++v){
- delete (*v);
- }
- _vertices.clear();
- }
- _averageThickness=0.0;
-
- vector<StrokeVertex*>::const_iterator v ,vend, v2, vPrev;
- StrokeVertex *sv, *sv2, *svPrev;
-
- //special case of first vertex
- v=iStrokeVertices.begin();
- sv=*v;
- vPrev=v; //in case the stroke has only 2 vertices;
- ++v; sv2=*v;
- Vec2r dir(sv2->getPoint()-sv->getPoint());
- Vec2r orthDir(-dir[1], dir[0]);
- if (orthDir.norm() > ZERO)
- orthDir.normalize();
- Vec2r stripDir(orthDir);
- // check whether the orientation was user defined
- if(sv->attribute().isAttributeAvailableVec2f("orientation")){
- Vec2r userDir = sv->attribute().getAttributeVec2f("orientation");
- userDir.normalize();
- real dp = userDir*orthDir;
- if(dp<0)
- userDir = userDir*(-1.f);
- stripDir = userDir;
- }
- const float *thickness = sv->attribute().getThickness();
- _vertices.push_back(new StrokeVertexRep(sv->getPoint()+thickness[1]*stripDir));
- _vertices.push_back(new StrokeVertexRep(sv->getPoint()-thickness[0]*stripDir));
-
- // Vec2r userDir = _stroke->getBeginningOrientation();
- // if(userDir != Vec2r(0,0)){
- // userDir.normalize();
- // real o1 = (orthDir*userDir);
- // real o2 = crossP(orthDir,userDir);
- // real orientation = o1 * o2;
- // if(orientation > 0){
- // // then the vertex to move is v0
- // if(o1 > 0)
- // _vertex[0]=_vertex[1]+userDir;
- // else
- // _vertex[0]=_vertex[1]-userDir;
- // }
- // if(orientation < 0){
- // // then we must move v1
- // if(o1 < 0)
- // _vertex[1]=_vertex[0]+userDir;
- // else
- // _vertex[1]=_vertex[0]-userDir;
- // }
- // }
-
- int i=2; //2 because we have already processed the first vertex
-
- for(vend=iStrokeVertices.end();
- v!=vend;
- v++){
- v2=v; ++v2;
- if (v2==vend) break;
- sv= (*v); sv2 = (*v2); svPrev=(*vPrev);
- Vec2r p(sv->getPoint()), p2(sv2->getPoint()), pPrev(svPrev->getPoint());
-
- //direction and orthogonal vector to the next segment
- Vec2r dir(p2-p);
- float dirNorm=dir.norm();
- dir.normalize();
- Vec2r orthDir(-dir[1], dir[0]);
- Vec2r stripDir = orthDir;
- if(sv->attribute().isAttributeAvailableVec2f("orientation")){
- Vec2r userDir = sv->attribute().getAttributeVec2f("orientation");
- userDir.normalize();
- real dp = userDir*orthDir;
- if(dp<0)
- userDir = userDir*(-1.f);
- stripDir = userDir;
- }
-
- //direction and orthogonal vector to the previous segment
- Vec2r dirPrev(p-pPrev);
- float dirPrevNorm=dirPrev.norm();
- dirPrev.normalize();
- Vec2r orthDirPrev(-dirPrev[1], dirPrev[0]);
- Vec2r stripDirPrev = orthDirPrev;
- if(svPrev->attribute().isAttributeAvailableVec2f("orientation")){
- Vec2r userDir = svPrev->attribute().getAttributeVec2f("orientation");
- userDir.normalize();
- real dp = userDir*orthDir;
- if(dp<0)
- userDir = userDir*(-1.f);
- stripDirPrev = userDir;
- }
-
- const float *thickness = sv->attribute().getThickness();
- _averageThickness+=thickness[0]+thickness[1];
- Vec2r pInter;
- int interResult;
-
- interResult=GeomUtils::intersect2dLine2dLine(Vec2r(pPrev+thickness[1]*stripDirPrev), Vec2r(p+thickness[1]*stripDirPrev),
- Vec2r(p+thickness[1]*stripDir), Vec2r(p2+thickness[1]*stripDir),
- pInter);
-
- if (interResult==GeomUtils::DO_INTERSECT)
- _vertices.push_back(new StrokeVertexRep(pInter));
- else
- _vertices.push_back(new StrokeVertexRep(p+thickness[1]*stripDir));
- ++i;
-
- interResult=GeomUtils::intersect2dLine2dLine(Vec2r(pPrev-thickness[0]*stripDirPrev), Vec2r(p-thickness[0]*stripDirPrev),
- Vec2r(p-thickness[0]*stripDir), Vec2r(p2-thickness[0]*stripDir),
- pInter);
- if (interResult==GeomUtils::DO_INTERSECT)
- _vertices.push_back(new StrokeVertexRep(pInter));
- else
- _vertices.push_back(new StrokeVertexRep(p-thickness[0]*stripDir));
- ++i;
-
- // if the angle is obtuse, we simply average the directions to avoid the singularity
- stripDir=stripDir+stripDirPrev;
- if ((dirNorm<ZERO) || (dirPrevNorm<ZERO) || (stripDir.norm() < ZERO)) {
- stripDir[0] = 0;
- stripDir[1] = 0;
- }else
- stripDir.normalize();
-
- Vec2r vec_tmp(_vertices[i-2]->point2d()-p);
- if ((vec_tmp.norm() > thickness[1]*MAX_RATIO_LENGTH_SINGU) ||
- (dirNorm<ZERO) || (dirPrevNorm<ZERO) ||
- notValid(_vertices[i-2]->point2d())
- || (fabs(stripDir * dir) < EPS_SINGULARITY_RENDERER))
- _vertices[i-2]->setPoint2d(p+thickness[1]*stripDir);
-
- vec_tmp = _vertices[i-1]->point2d()-p;
- if ((vec_tmp.norm() > thickness[0]*MAX_RATIO_LENGTH_SINGU) ||
- (dirNorm<ZERO) || (dirPrevNorm<ZERO) ||
- notValid(_vertices[i-1]->point2d())
- || (fabs(stripDir * dir)<EPS_SINGULARITY_RENDERER))
- _vertices[i-1]->setPoint2d(p-thickness[0]*stripDir);
-
- vPrev=v;
- } // end of for
-
- //special case of last vertex
- sv=*v;
- sv2=*vPrev;
- dir=Vec2r (sv->getPoint()-sv2->getPoint());
- orthDir=Vec2r(-dir[1], dir[0]);
- if (orthDir.norm() > ZERO)
- orthDir.normalize();
- Vec2r stripDirLast(orthDir);
- // check whether the orientation was user defined
- if(sv->attribute().isAttributeAvailableVec2f("orientation")){
- Vec2r userDir = sv->attribute().getAttributeVec2f("orientation");
- userDir.normalize();
- real dp = userDir*orthDir;
- if(dp<0)
- userDir = userDir*(-1.f);
- stripDirLast = userDir;
- }
- const float *thicknessLast = sv->attribute().getThickness();
- _vertices.push_back(new StrokeVertexRep(sv->getPoint()+thicknessLast[1]*stripDirLast));
- ++i;
- _vertices.push_back(new StrokeVertexRep(sv->getPoint()-thicknessLast[0]*stripDirLast));
- int n = i;
- ++i;
-
- // check whether the orientation of the extremity
- // was user defined
- // userDir = _stroke->getEndingOrientation();
- // if(userDir != Vec2r(0,0)){
- // userDir.normalize();
- // real o1 = (orthDir*userDir);
- // real o2 = crossP(orthDir,userDir);
- // real orientation = o1 * o2;
- // if(orientation > 0){
- // // then the vertex to move is vn
- // if(o1 < 0)
- // _vertex[n]=_vertex[n-1]+userDir;
- // else
- // _vertex[n]=_vertex[n-1]-userDir;
- // }
- // if(orientation < 0){
- // // then we must move vn-1
- // if(o1 > 0)
- // _vertex[n-1]=_vertex[n]+userDir;
- // else
- // _vertex[n-1]=_vertex[n]-userDir;
- // }
- // }
-
- _averageThickness/=float(iStrokeVertices.size()-2);
- //I did not use the first and last vertex for the average
- if (iStrokeVertices.size()<3)
- _averageThickness=0.5*(thicknessLast[1]+thicknessLast[0]+thickness[0]+thickness[1]);
-
- if (i != 2*(int)iStrokeVertices.size())
- cerr << "Warning: problem with stripe size\n";
-
- cleanUpSingularities (iStrokeVertices);
-}
+ //computeParameterization();
+ if (iStrokeVertices.size() < 2) {
+ cerr << "Warning: strip has less than 2 vertices" << endl;
+ return;
+ }
+ _vertices.reserve(2 * iStrokeVertices.size());
+ if (!_vertices.empty()) {
+ for (vertex_container::iterator v = _vertices.begin(), vend = _vertices.end(); v != vend; ++v) {
+ delete (*v);
+ }
+ _vertices.clear();
+ }
+ _averageThickness = 0.0;
+
+ vector<StrokeVertex*>::const_iterator v ,vend, v2, vPrev;
+ StrokeVertex *sv, *sv2, *svPrev;
+
+ //special case of first vertex
+ v = iStrokeVertices.begin();
+ sv = *v;
+ vPrev = v; //in case the stroke has only 2 vertices;
+ ++v;
+ sv2 = *v;
+ Vec2r dir(sv2->getPoint() - sv->getPoint());
+ Vec2r orthDir(-dir[1], dir[0]);
+ if (orthDir.norm() > ZERO)
+ orthDir.normalize();
+ Vec2r stripDir(orthDir);
+ // check whether the orientation was user defined
+ if (sv->attribute().isAttributeAvailableVec2f("orientation")) {
+ Vec2r userDir = sv->attribute().getAttributeVec2f("orientation");
+ userDir.normalize();
+ real dp = userDir * orthDir;
+ if (dp < 0)
+ userDir = userDir * (-1.0f);
+ stripDir = userDir;
+ }
+ const float *thickness = sv->attribute().getThickness();
+ _vertices.push_back(new StrokeVertexRep(sv->getPoint() + thickness[1] * stripDir));
+ _vertices.push_back(new StrokeVertexRep(sv->getPoint() - thickness[0] * stripDir));
+
+#if 0
+ Vec2r userDir = _stroke->getBeginningOrientation();
+ if (userDir != Vec2r(0, 0)) {
+ userDir.normalize();
+ real o1 = (orthDir * userDir);
+ real o2 = crossP(orthDir, userDir);
+ real orientation = o1 * o2;
+ if (orientation > 0) {
+ // then the vertex to move is v0
+ if (o1 > 0)
+ _vertex[0] = _vertex[1] + userDir;
+ else
+ _vertex[0] = _vertex[1] - userDir;
+ }
+ if (orientation < 0) {
+ // then we must move v1
+ if (o1 < 0)
+ _vertex[1] = _vertex[0] + userDir;
+ else
+ _vertex[1] = _vertex[0] - userDir;
+ }
+ }
+#endif
+
+ int i = 2; // 2 because we have already processed the first vertex
+
+ for (vend = iStrokeVertices.end(); v != vend; ++v) {
+ v2 = v;
+ ++v2;
+ if (v2 == vend)
+ break;
+ sv = (*v);
+ sv2 = (*v2);
+ svPrev = (*vPrev);
+ Vec2r p(sv->getPoint()), p2(sv2->getPoint()), pPrev(svPrev->getPoint());
+
+ //direction and orthogonal vector to the next segment
+ Vec2r dir(p2 - p);
+ float dirNorm = dir.norm();
+ dir.normalize();
+ Vec2r orthDir(-dir[1], dir[0]);
+ Vec2r stripDir = orthDir;
+ if (sv->attribute().isAttributeAvailableVec2f("orientation")) {
+ Vec2r userDir = sv->attribute().getAttributeVec2f("orientation");
+ userDir.normalize();
+ real dp = userDir * orthDir;
+ if (dp < 0)
+ userDir = userDir * (-1.0f);
+ stripDir = userDir;
+ }
+
+ //direction and orthogonal vector to the previous segment
+ Vec2r dirPrev(p - pPrev);
+ float dirPrevNorm = dirPrev.norm();
+ dirPrev.normalize();
+ Vec2r orthDirPrev(-dirPrev[1], dirPrev[0]);
+ Vec2r stripDirPrev = orthDirPrev;
+ if (svPrev->attribute().isAttributeAvailableVec2f("orientation")) {
+ Vec2r userDir = svPrev->attribute().getAttributeVec2f("orientation");
+ userDir.normalize();
+ real dp = userDir * orthDir;
+ if (dp < 0)
+ userDir = userDir * (-1.0f);
+ stripDirPrev = userDir;
+ }
+
+ const float *thickness = sv->attribute().getThickness();
+ _averageThickness += thickness[0] + thickness[1];
+ Vec2r pInter;
+ int interResult;
+
+ interResult = GeomUtils::intersect2dLine2dLine(Vec2r(pPrev + thickness[1] * stripDirPrev),
+ Vec2r(p + thickness[1] * stripDirPrev),
+ Vec2r(p + thickness[1] * stripDir),
+ Vec2r(p2 + thickness[1] * stripDir),
+ pInter);
+ if (interResult == GeomUtils::DO_INTERSECT)
+ _vertices.push_back(new StrokeVertexRep(pInter));
+ else
+ _vertices.push_back(new StrokeVertexRep(p + thickness[1] * stripDir));
+ ++i;
+
+ interResult = GeomUtils::intersect2dLine2dLine(Vec2r(pPrev - thickness[0] * stripDirPrev),
+ Vec2r(p - thickness[0] * stripDirPrev),
+ Vec2r(p - thickness[0] * stripDir),
+ Vec2r(p2 - thickness[0] * stripDir),
+ pInter);
+ if (interResult == GeomUtils::DO_INTERSECT)
+ _vertices.push_back(new StrokeVertexRep(pInter));
+ else
+ _vertices.push_back(new StrokeVertexRep(p - thickness[0] * stripDir));
+ ++i;
+
+ // if the angle is obtuse, we simply average the directions to avoid the singularity
+ stripDir = stripDir + stripDirPrev;
+ if ((dirNorm < ZERO) || (dirPrevNorm < ZERO) || (stripDir.norm() < ZERO)) {
+ stripDir[0] = 0;
+ stripDir[1] = 0;
+ }
+ else {
+ stripDir.normalize();
+ }
+
+ Vec2r vec_tmp(_vertices[i - 2]->point2d() - p);
+ if ((vec_tmp.norm() > thickness[1] * MAX_RATIO_LENGTH_SINGU) || (dirNorm < ZERO) || (dirPrevNorm < ZERO) ||
+ notValid(_vertices[i - 2]->point2d()) || (fabs(stripDir * dir) < EPS_SINGULARITY_RENDERER))
+ {
+ _vertices[i - 2]->setPoint2d(p + thickness[1] * stripDir);
+ }
+
+ vec_tmp = _vertices[i - 1]->point2d() - p;
+ if ((vec_tmp.norm() > thickness[0] * MAX_RATIO_LENGTH_SINGU) || (dirNorm < ZERO) || (dirPrevNorm < ZERO) ||
+ notValid(_vertices[i - 1]->point2d()) || (fabs(stripDir * dir) < EPS_SINGULARITY_RENDERER))
+ {
+ _vertices[i - 1]->setPoint2d(p - thickness[0] * stripDir);
+ }
+
+ vPrev = v;
+ } // end of for
+
+ //special case of last vertex
+ sv = *v;
+ sv2 = *vPrev;
+ dir = Vec2r(sv->getPoint() - sv2->getPoint());
+ orthDir = Vec2r(-dir[1], dir[0]);
+ if (orthDir.norm() > ZERO)
+ orthDir.normalize();
+ Vec2r stripDirLast(orthDir);
+ // check whether the orientation was user defined
+ if (sv->attribute().isAttributeAvailableVec2f("orientation")) {
+ Vec2r userDir = sv->attribute().getAttributeVec2f("orientation");
+ userDir.normalize();
+ real dp = userDir * orthDir;
+ if (dp < 0)
+ userDir = userDir * (-1.0f);
+ stripDirLast = userDir;
+ }
+ const float *thicknessLast = sv->attribute().getThickness();
+ _vertices.push_back(new StrokeVertexRep(sv->getPoint() + thicknessLast[1] * stripDirLast));
+ ++i;
+ _vertices.push_back(new StrokeVertexRep(sv->getPoint() - thicknessLast[0] * stripDirLast));
+ int n = i;
+ ++i;
+
+#if 0
+ // check whether the orientation of the extremity was user defined
+ userDir = _stroke->getEndingOrientation();
+ if (userDir != Vec2r(0, 0)) {
+ userDir.normalize();
+ real o1 = (orthDir * userDir);
+ real o2 = crossP(orthDir, userDir);
+ real orientation = o1 * o2;
+ if (orientation > 0) {
+ // then the vertex to move is vn
+ if (o1 < 0)
+ _vertex[n] = _vertex[n - 1] + userDir;
+ else
+ _vertex[n] = _vertex[n - 1] - userDir;
+ }
+ if (orientation < 0) {
+ // then we must move vn-1
+ if (o1 > 0)
+ _vertex[n - 1] = _vertex[n] + userDir;
+ else
+ _vertex[n - 1] = _vertex[n] - userDir;
+ }
+ }
+#endif
+
+ _averageThickness /= float(iStrokeVertices.size() - 2);
+ //I did not use the first and last vertex for the average
+ if (iStrokeVertices.size() < 3)
+ _averageThickness = 0.5 * (thicknessLast[1] + thicknessLast[0] + thickness[0] + thickness[1]);
+
+ if (i != 2 * (int)iStrokeVertices.size())
+ cerr << "Warning: problem with stripe size\n";
+
+ cleanUpSingularities (iStrokeVertices);
+}
// CLEAN UP
/////////////////////////
-void
-Strip::cleanUpSingularities (const vector<StrokeVertex*>& iStrokeVertices)
+void Strip::cleanUpSingularities (const vector<StrokeVertex*>& iStrokeVertices)
{
- int k;
- int sizeStrip = _vertices.size();
-
- for (k=0; k<sizeStrip; k++)
- if (notValid(_vertices[k]->point2d()))
- {
- cerr << "Warning: strip vertex " << k << " non valid" << endl;
- return;
- }
-
- //return;
- if (iStrokeVertices.size()<2) return;
- int i=0, j;
- vector<StrokeVertex*>::const_iterator v ,vend, v2, vPrev;
-StrokeVertex *sv, *sv2; //soc unused - *svPrev;
-
- bool singu1=false, singu2=false;
- int timeSinceSingu1=0, timeSinceSingu2=0;
-
- //special case of first vertex
- v=iStrokeVertices.begin();
- for(vend=iStrokeVertices.end();
- v!=vend;
- v++)
- {
- v2=v; ++v2;
- if (v2==vend) break;
- sv= (*v); sv2 = (*v2);
- Vec2r p(sv->getPoint()), p2(sv2->getPoint());
-
- Vec2r dir(p2-p);
- if (dir.norm() > ZERO)
- dir.normalize();
- Vec2r dir1, dir2;
- dir1=_vertices[2*i+2]->point2d()-_vertices[2*i]->point2d();
- dir2=_vertices[2*i+3]->point2d()-_vertices[2*i+1]->point2d();
-
- if ((dir1 * dir) < -ZERO)
- {
- singu1=true;
- timeSinceSingu1++;
+ int k;
+ int sizeStrip = _vertices.size();
+
+ for (k = 0; k < sizeStrip; k++) {
+ if (notValid(_vertices[k]->point2d())) {
+ cerr << "Warning: strip vertex " << k << " non valid" << endl;
+ return;
+ }
}
- else
- {
- if (singu1)
- {
- int toto=i-timeSinceSingu1;
- if (toto<0)
- cerr << "Stephane dit \"Toto\"" << endl;
- //traverse all the vertices of the singularity and average them
- Vec2r avP(0.0,0.0);
- for (j=i-timeSinceSingu1; j<i+1; j++)
- avP=Vec2r(avP+_vertices[2*j]->point2d());
- avP=Vec2r(1.0/float(timeSinceSingu1+1)*avP);
- for (j=i-timeSinceSingu1; j<i+1; j++)
- _vertices[2*j]->setPoint2d(avP);
- //_vertex[2*j]=_vertex[2*i];
- singu1=false; timeSinceSingu1=0;
- }
+
+ //return;
+ if (iStrokeVertices.size() < 2)
+ return;
+ int i = 0, j;
+ vector<StrokeVertex*>::const_iterator v ,vend, v2, vPrev;
+ StrokeVertex *sv, *sv2; //soc unused - *svPrev;
+
+ bool singu1 = false, singu2 = false;
+ int timeSinceSingu1 = 0, timeSinceSingu2 = 0;
+
+ //special case of first vertex
+ v = iStrokeVertices.begin();
+ for (vend = iStrokeVertices.end(); v != vend; v++) {
+ v2 = v;
+ ++v2;
+ if (v2 == vend)
+ break;
+ sv = (*v);
+ sv2 = (*v2);
+ Vec2r p(sv->getPoint()), p2(sv2->getPoint());
+
+ Vec2r dir(p2-p);
+ if (dir.norm() > ZERO)
+ dir.normalize();
+ Vec2r dir1, dir2;
+ dir1 = _vertices[2 * i + 2]->point2d() - _vertices[2 * i]->point2d();
+ dir2 = _vertices[2 * i + 3]->point2d() - _vertices[2 * i + 1]->point2d();
+
+ if ((dir1 * dir) < -ZERO) {
+ singu1 = true;
+ timeSinceSingu1++;
+ }
+ else {
+ if (singu1) {
+ int toto = i - timeSinceSingu1;
+ if (toto < 0)
+ cerr << "Stephane dit \"Toto\"" << endl;
+ //traverse all the vertices of the singularity and average them
+ Vec2r avP(0.0, 0.0);
+ for (j = i - timeSinceSingu1; j < i + 1; j++)
+ avP=Vec2r(avP + _vertices[2 * j]->point2d());
+ avP = Vec2r( 1.0 / float(timeSinceSingu1 + 1) * avP);
+ for (j = i - timeSinceSingu1; j < i + 1; j++)
+ _vertices[2 * j]->setPoint2d(avP);
+ //_vertex[2 * j] = _vertex[2 * i];
+ singu1 = false;
+ timeSinceSingu1 = 0;
+ }
+ }
+ if ((dir2 * dir) < -ZERO) {
+ singu2 = true;
+ timeSinceSingu2++;
+ }
+ else {
+ if (singu2) {
+ int toto = i - timeSinceSingu2;
+ if (toto < 0)
+ cerr << "Stephane dit \"Toto\"" << endl;
+ //traverse all the vertices of the singularity and average them
+ Vec2r avP(0.0, 0.0);
+ for (j = i - timeSinceSingu2; j < i + 1; j++)
+ avP = Vec2r(avP + _vertices[2 * j + 1]->point2d());
+ avP = Vec2r(1.0 / float(timeSinceSingu2 + 1) * avP);
+ for (j = i - timeSinceSingu2; j < i + 1; j++)
+ _vertices[2 * j + 1]->setPoint2d(avP);
+ //_vertex[2 * j + 1] = _vertex[2 * i + 1];
+ singu2 = false;
+ timeSinceSingu2 = 0;
+ }
+ }
+ i++;
}
- if ((dir2 * dir) < -ZERO)
- {
- singu2=true;
- timeSinceSingu2++;
+
+ if (singu1) {
+ //traverse all the vertices of the singularity and average them
+ Vec2r avP(0.0, 0.0);
+ for (j = i - timeSinceSingu1; j < i; j++)
+ avP = Vec2r(avP + _vertices[2 * j]->point2d());
+ avP = Vec2r(1.0 / float(timeSinceSingu1) * avP);
+ for (j = i - timeSinceSingu1; j < i; j++)
+ _vertices[2 * j]->setPoint2d(avP);
+ }
+ if (singu2) {
+ //traverse all the vertices of the singularity and average them
+ Vec2r avP(0.0, 0.0);
+ for (j = i - timeSinceSingu2; j < i; j++)
+ avP = Vec2r(avP + _vertices[2 * j + 1]->point2d());
+ avP = Vec2r(1.0 / float(timeSinceSingu2) * avP);
+ for (j = i - timeSinceSingu2; j < i; j++)
+ _vertices[2 * j + 1]->setPoint2d(avP);
+ }
+
+ for (k=0; k<sizeStrip; k++) {
+ if (notValid(_vertices[k]->point2d())) {
+ cerr << "Warning: strip vertex " << k << " non valid after cleanup" << endl;
+ return;
+ }
}
- else
- {
- if (singu2)
- {
- int toto=i-timeSinceSingu2;
- if (toto<0)
- cerr << "Stephane dit \"Toto\"" << endl;
- //traverse all the vertices of the singularity and average them
- Vec2r avP(0.0,0.0);
- for (j=i-timeSinceSingu2; j<i+1; j++)
- avP=Vec2r(avP+_vertices[2*j+1]->point2d());
- avP=Vec2r(1.0/float(timeSinceSingu2+1)*avP);
- for (j=i-timeSinceSingu2; j<i+1; j++)
- _vertices[2*j+1]->setPoint2d(avP);
- //_vertex[2*j+1]=_vertex[2*i+1];
- singu2=false; timeSinceSingu2=0;
- }
- }
- i++;
- }
-
- if (singu1)
- {
- //traverse all the vertices of the singularity and average them
- Vec2r avP(0.0,0.0);
- for (j=i-timeSinceSingu1; j<i; j++)
- avP=Vec2r(avP+_vertices[2*j]->point2d());
- avP=Vec2r(1.0/float(timeSinceSingu1)*avP);
- for (j=i-timeSinceSingu1; j<i; j++)
- _vertices[2*j]->setPoint2d(avP);
- }
- if (singu2)
- {
- //traverse all the vertices of the singularity and average them
- Vec2r avP(0.0,0.0);
- for (j=i-timeSinceSingu2; j<i; j++)
- avP=Vec2r(avP+_vertices[2*j+1]->point2d());
- avP=Vec2r(1.0/float(timeSinceSingu2)*avP);
- for (j=i-timeSinceSingu2; j<i; j++)
- _vertices[2*j+1]->setPoint2d(avP);
- }
-
-
- for (k=0; k<sizeStrip; k++)
- if (notValid(_vertices[k]->point2d()))
- {
- cerr << "Warning: strip vertex " << k << " non valid after cleanup"<<endl;
- return;
- }
}
// Texture coordinates
////////////////////////////////
-void
-Strip::computeTexCoord (const vector<StrokeVertex*>& iStrokeVertices)
+void Strip::computeTexCoord (const vector<StrokeVertex*>& iStrokeVertices)
{
- 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]->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]->setAlpha(sv->attribute().getAlpha());
- i++;
- // cerr<<"col=("<<sv->attribute().getColor()[0]<<", "
- // <<sv->attribute().getColor()[1]<<", "<<sv->attribute().getColor()[2]<<")"<<endl;
- }
+ 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]->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]->setAlpha(sv->attribute().getAlpha());
+ i++;
+#if 0
+ cerr << "col=("<<sv->attribute().getColor()[0] << ", "
+ << sv->attribute().getColor()[1] << ", " << sv->attribute().getColor()[2] << ")" << endl;
+#endif
+ }
}
-void
-Strip::computeTexCoordWithTips (const vector<StrokeVertex*>& iStrokeVertices, bool tipBegin, bool tipEnd)
+void Strip::computeTexCoordWithTips (const vector<StrokeVertex*>& iStrokeVertices, bool tipBegin, bool tipEnd)
{
- //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 = 0;
-
- 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;
-
- // cerr<<"l="<<l<<" tiles="<<tiles<<" _averageThicnkess="
- // <<_averageThickness<<" strokeLength="<<(*v)->strokeLength()<<endl;
- //
- vector<StrokeVertexRep*>::iterator currentSV = _vertices.begin();
- StrokeVertexRep *svRep;
- if(tipBegin){
- for(;v!=vend; v++)
- {
- sv= (*v);
- svRep = *currentSV;
- u=sv->curvilinearAbscissa()/_averageThickness*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());
- 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());
- i++;
- ++currentSV;
- uPrev=u;
- }
- //first transition vertex
-
- if (fabs(u-uPrev)>ZERO)
- t= (0.25-uPrev)/(u-uPrev);
- else t=0;
- //if (!tiles) t=0.5;
- 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;
-
- //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;
- }
- uPrev=0;
-
- //body of the stroke
- for(;v!=vend; v++)
- {
- sv= (*v);
- svRep = *currentSV;
- u=sv->curvilinearAbscissa()/_averageThickness*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());
- 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());
- i++;
- ++currentSV;
-
- uPrev=u;
- }
- if(tipEnd){
- //second transition vertex
- if ((fabs(u-uPrev)>ZERO))
- t= (float(tiles)-uPrev)/(u-uPrev);
- else t=0;
-
- 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;
-
- //end tip
- for(;v!=vend; v++)
- {
- sv= (*v);
- svRep = *currentSV;
- u=0.75+sv->curvilinearAbscissa()/_averageThickness*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());
- 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());
- i++;
- ++currentSV;
- }
- }
- //cerr<<"u="<<u<<" i="<<i<<"/"<<_sizeStrip<<endl;;
-
- // for (i=0; i<_sizeStrip; i++)
- // _alpha[i]=1.0;
-
- // for (i=0; i<_sizeStrip; i++)
- // cerr<<"("<<_texCoord[i][0]<<", "<<_texCoord[i][1]<<") ";
- // cerr<<endl;
-
-
- // Vec2r vec_tmp;
- // for (i=0; i<_sizeStrip/2; i++)
- // vec_tmp = _vertex[2*i] - _vertex[2*i+1];
- // if (vec_tmp.norm() > 4*_averageThickness)
- // cerr << "Warning (from Fredo): There is a pb in the texture coordinates computation" << endl;
+ //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;
+
+ 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;
+
+#if 0
+ cerr << "l=" << l << " tiles=" << tiles << " _averageThicnkess="
+ << _averageThickness << " strokeLength=" << (*v)->strokeLength() << endl;
+#endif
+
+ vector<StrokeVertexRep*>::iterator currentSV = _vertices.begin();
+ StrokeVertexRep *svRep;
+ if (tipBegin) {
+ for (; v != vend; v++) {
+ sv = (*v);
+ svRep = *currentSV;
+ u = sv->curvilinearAbscissa() / _averageThickness * 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());
+ 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());
+ i++;
+ ++currentSV;
+ uPrev = u;
+ }
+ //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;
+
+ // 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;
+ }
+ uPrev = 0;
+
+ //body of the stroke
+ for (; v != vend; v++) {
+ sv = (*v);
+ svRep = *currentSV;
+ u = sv->curvilinearAbscissa() / _averageThickness * 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());
+ 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());
+ i++;
+ ++currentSV;
+
+ uPrev = u;
+ }
+ if (tipEnd) {
+ //second transition vertex
+ if ((fabs(u - uPrev) > ZERO))
+ t = (float(tiles) - uPrev) / (u - uPrev);
+ else
+ t = 0;
+
+ 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;
+
+ //end tip
+ for (; v != vend; v++) {
+ sv = (*v);
+ svRep = *currentSV;
+ u = 0.75 + sv->curvilinearAbscissa() / _averageThickness * 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());
+ 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());
+ i++;
+ ++currentSV;
+ }
+ }
+
+#if 0
+ cerr << "u=" << u << " i=" << i << "/" << _sizeStrip << endl;
+
+ for (i = 0; i < _sizeStrip; i++)
+ _alpha[i] = 1.0;
+
+ for (i = 0; i < _sizeStrip; i++)
+ cerr << "(" << _texCoord[i][0] << ", " << _texCoord[i][1] << ") ";
+ cerr << endl;
+
+ Vec2r vec_tmp;
+ for (i = 0; i < _sizeStrip / 2; i++)
+ vec_tmp = _vertex[2 * i] - _vertex[2 * i + 1];
+ if (vec_tmp.norm() > 4 * _averageThickness)
+ cerr << "Warning (from Fredo): There is a pb in the texture coordinates computation" << endl;
+#endif
}
//
@@ -655,97 +692,98 @@ Strip::computeTexCoordWithTips (const vector<StrokeVertex*>& iStrokeVertices, bo
StrokeRep::StrokeRep()
{
- _stroke = 0;
- _strokeType=Stroke::OPAQUE_MEDIUM;
- TextureManager * ptm = TextureManager::getInstance();
- if(ptm)
- _textureId = ptm->getDefaultTextureId();
- // _averageTextureAlpha=0.5; //default value
- // if (_strokeType==OIL_STROKE)
- // _averageTextureAlpha=0.75;
- // if (_strokeType>=NO_BLEND_STROKE)
- // _averageTextureAlpha=1.0
-}
+ _stroke = 0;
+ _strokeType = Stroke::OPAQUE_MEDIUM;
+ TextureManager *ptm = TextureManager::getInstance();
+ if (ptm)
+ _textureId = ptm->getDefaultTextureId();
+#if 0
+ _averageTextureAlpha = 0.5; //default value
+ if (_strokeType == OIL_STROKE)
+ _averageTextureAlpha = 0.75;
+ if (_strokeType >= NO_BLEND_STROKE)
+ _averageTextureAlpha = 1.0
+#endif
+}
StrokeRep::StrokeRep(Stroke *iStroke)
{
- _stroke = iStroke;
- _strokeType = iStroke->getMediumType();
- _textureId = iStroke->getTextureId();
- if(_textureId == 0){
- TextureManager * ptm = TextureManager::getInstance();
- if(ptm)
- _textureId = ptm->getDefaultTextureId();
- }
-
- // _averageTextureAlpha=0.5; //default value
- // if (_strokeType==OIL_STROKE)
- // _averageTextureAlpha=0.75;
- // if (_strokeType>=NO_BLEND_STROKE)
- // _averageTextureAlpha=1.0;
- create();
+ _stroke = iStroke;
+ _strokeType = iStroke->getMediumType();
+ _textureId = iStroke->getTextureId();
+ if (_textureId == 0) {
+ TextureManager *ptm = TextureManager::getInstance();
+ if (ptm)
+ _textureId = ptm->getDefaultTextureId();
+ }
+
+#if 0
+ _averageTextureAlpha = 0.5; //default value
+ if (_strokeType == OIL_STROKE)
+ _averageTextureAlpha = 0.75;
+ if (_strokeType >= NO_BLEND_STROKE)
+ _averageTextureAlpha = 1.0;
+#endif
+ create();
}
StrokeRep::StrokeRep(const StrokeRep& iBrother)
{
- //soc unused - int i=0;
- _stroke = iBrother._stroke;
- _strokeType=iBrother._strokeType;
- _textureId = iBrother._textureId;
- for(vector<Strip*>::const_iterator s=iBrother._strips.begin(), send=iBrother._strips.end();
- s!=send;
- ++s){
- _strips.push_back(new Strip(**s));
- }
+ //soc unused - int i = 0;
+ _stroke = iBrother._stroke;
+ _strokeType = iBrother._strokeType;
+ _textureId = iBrother._textureId;
+ for (vector<Strip*>::const_iterator s = iBrother._strips.begin(), send = iBrother._strips.end();
+ s != send;
+ ++s)
+ {
+ _strips.push_back(new Strip(**s));
+ }
}
-
StrokeRep::~StrokeRep()
{
- if(!_strips.empty()){
- for(vector<Strip*>::iterator s=_strips.begin(), send=_strips.end();
- s!=send;
- ++s){
- delete (*s);
- }
- _strips.clear();
- }
+ if (!_strips.empty()) {
+ for (vector<Strip*>::iterator s = _strips.begin(), send = _strips.end(); s != send; ++s) {
+ delete (*s);
+ }
+ _strips.clear();
+ }
}
-void StrokeRep::create(){
- vector<StrokeVertex*> strip;
- StrokeInternal::StrokeVertexIterator v = _stroke->strokeVerticesBegin();
- StrokeInternal::StrokeVertexIterator vend = _stroke->strokeVerticesEnd();
-
- bool first=true;
- bool end=false;
- while(v!=vend){
- while((v!=vend) && (!(*v).attribute().isVisible())){
- ++v;
- first = false;
- }
- while( (v!=vend) && ((*v).attribute().isVisible()) ) {
- strip.push_back(&(*v));
- ++v;
- }
- if(v!=vend){
- // add the last vertex and create
- strip.push_back(&(*v));
- }else{
- end=true;
- }
- if((!strip.empty()) && (strip.size()>1) ){
- _strips.push_back(new Strip(strip, _stroke->hasTips(), first, end));
- strip.clear();
- }
- first = false;
- }
-}
+void StrokeRep::create()
+{
+ vector<StrokeVertex*> strip;
+ StrokeInternal::StrokeVertexIterator v = _stroke->strokeVerticesBegin();
+ StrokeInternal::StrokeVertexIterator vend = _stroke->strokeVerticesEnd();
+
+ bool first = true;
+ bool end = false;
+ while (v != vend) {
+ while ((v != vend) && (!(*v).attribute().isVisible())) {
+ ++v;
+ first = false;
+ }
+ while ((v != vend) && ((*v).attribute().isVisible())) {
+ strip.push_back(&(*v));
+ ++v;
+ }
+ if (v != vend) {
+ // add the last vertex and create
+ strip.push_back(&(*v));
+ }
+ else {
+ end = true;
+ }
+ if ((!strip.empty()) && (strip.size() > 1)) {
+ _strips.push_back(new Strip(strip, _stroke->hasTips(), first, end));
+ strip.clear();
+ }
+ first = false;
+ }
+}
void StrokeRep::Render(const StrokeRenderer *iRenderer)
{
- iRenderer->RenderStrokeRep(this);
+ iRenderer->RenderStrokeRep(this);
}
-
-
-