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/Stroke.cpp')
-rw-r--r--source/blender/freestyle/intern/stroke/Stroke.cpp1609
1 files changed, 801 insertions, 808 deletions
diff --git a/source/blender/freestyle/intern/stroke/Stroke.cpp b/source/blender/freestyle/intern/stroke/Stroke.cpp
index b42e673b4be..477092f2e7a 100644
--- a/source/blender/freestyle/intern/stroke/Stroke.cpp
+++ b/source/blender/freestyle/intern/stroke/Stroke.cpp
@@ -1,947 +1,940 @@
-
-//
-// 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/Stroke.cpp
+ * \ingroup freestyle
+ * \brief Classes to define a stroke
+ * \author Stephane Grabli
+ * \date 09/09/2002
+ */
#include "Stroke.h"
-#include "StrokeRenderer.h"
-#include "StrokeIterators.h"
#include "StrokeAdvancedIterators.h"
+#include "StrokeIterators.h"
+#include "StrokeRenderer.h"
- /**********************************/
- /* */
- /* */
- /* StrokeAttribute */
- /* */
- /* */
- /**********************************/
+/**********************************/
+/* */
+/* */
+/* StrokeAttribute */
+/* */
+/* */
+/**********************************/
StrokeAttribute::StrokeAttribute()
{
- int i;
- _alpha = 1.f;
- _thickness[0] = 1.f;
- _thickness[1] = 1.f;
- for(i=0; i<3; ++i)
- _color[i] = 0.2f;
- _color[0]=0.8;
- _userAttributesReal = 0;
- _userAttributesVec2f = 0;
- _userAttributesVec3f = 0;
- _visible = true;
+ int i;
+ _alpha = 1.0f;
+ _thickness[0] = 1.0f;
+ _thickness[1] = 1.0f;
+ for (i = 0; i < 3; ++i)
+ _color[i] = 0.2f;
+ _color[0] = 0.8f;
+ _userAttributesReal = NULL;
+ _userAttributesVec2f = NULL;
+ _userAttributesVec3f = NULL;
+ _visible = true;
}
+
StrokeAttribute::StrokeAttribute(const StrokeAttribute& iBrother)
{
- _alpha = iBrother._alpha;
- _thickness[0] = iBrother._thickness[0];
- _thickness[1] = iBrother._thickness[1];
- for(int i=0; i<3; ++i)
- _color[i] = iBrother._color[i];
- _visible = iBrother._visible;
- if(iBrother._userAttributesReal)
- _userAttributesReal = new realMap(*iBrother._userAttributesReal);
- else
- _userAttributesReal = 0;
- if(iBrother._userAttributesVec2f)
- _userAttributesVec2f = new Vec2fMap(*iBrother._userAttributesVec2f);
- else
- _userAttributesVec2f = 0;
- if(iBrother._userAttributesVec3f)
- _userAttributesVec3f = new Vec3fMap(*iBrother._userAttributesVec3f);
- else
- _userAttributesVec3f = 0;
-}
-StrokeAttribute::StrokeAttribute( float iRColor, float iGColor, float iBColor,
- float iAlpha,
- float iRThickness, float iLThickness)
-{
- _color[0] = iRColor;
- _color[1] = iGColor;
- _color[2] = iBColor;
-
- _alpha = iAlpha;
-
- _thickness[0] = iRThickness;
- _thickness[1] = iLThickness;
-
- _visible = true;
-
- _userAttributesReal = 0;
- _userAttributesVec2f = 0;
- _userAttributesVec3f = 0;
+ _alpha = iBrother._alpha;
+ _thickness[0] = iBrother._thickness[0];
+ _thickness[1] = iBrother._thickness[1];
+ for (int i = 0; i < 3; ++i)
+ _color[i] = iBrother._color[i];
+ _visible = iBrother._visible;
+ if (iBrother._userAttributesReal)
+ _userAttributesReal = new realMap(*iBrother._userAttributesReal);
+ else
+ _userAttributesReal = NULL;
+ if (iBrother._userAttributesVec2f)
+ _userAttributesVec2f = new Vec2fMap(*iBrother._userAttributesVec2f);
+ else
+ _userAttributesVec2f = NULL;
+ if (iBrother._userAttributesVec3f)
+ _userAttributesVec3f = new Vec3fMap(*iBrother._userAttributesVec3f);
+ else
+ _userAttributesVec3f = NULL;
+}
+
+StrokeAttribute::StrokeAttribute(float iRColor, float iGColor, float iBColor, float iAlpha,
+ float iRThickness, float iLThickness)
+{
+ _color[0] = iRColor;
+ _color[1] = iGColor;
+ _color[2] = iBColor;
+
+ _alpha = iAlpha;
+
+ _thickness[0] = iRThickness;
+ _thickness[1] = iLThickness;
+
+ _visible = true;
+
+ _userAttributesReal = NULL;
+ _userAttributesVec2f = NULL;
+ _userAttributesVec3f = NULL;
}
-StrokeAttribute::StrokeAttribute(const StrokeAttribute& a1, const StrokeAttribute& a2, float t)
+StrokeAttribute::StrokeAttribute(const StrokeAttribute& a1, const StrokeAttribute& a2, float t)
{
-
- _alpha = (1-t)*a1._alpha + t*a2._alpha;
- _thickness[0] = (1-t)*a1._thickness[0] + t*a2._thickness[0];
- _thickness[1] = (1-t)*a1._thickness[1] + t*a2._thickness[1];
- for(int i=0; i<3; ++i)
- _color[i] = (1-t)*a1._color[i] + t*a2._color[i];
-
- _visible = true;
-
- // FIXME: a verifier (et a ameliorer)
- if((a1._userAttributesReal) && (a2._userAttributesReal)){
- if(a1._userAttributesReal->size() == a2._userAttributesReal->size()){
- _userAttributesReal = new realMap;
- realMap::iterator it1=a1._userAttributesReal->begin(), it1end=a1._userAttributesReal->end();
- realMap::iterator it2=a2._userAttributesReal->begin(), it2end=a2._userAttributesReal->end();
- for(; (it1!=it1end); ++it1){
- (*_userAttributesReal)[(*it1).first] = ((1-t)*(*it1).second+t*(*it2).second);
- }
- }
- }else{
- _userAttributesReal = 0;
- }
- if((a1._userAttributesVec2f) && (a2._userAttributesVec2f)){
- if(a1._userAttributesVec2f->size() == a2._userAttributesVec2f->size()){
- _userAttributesVec2f = new Vec2fMap;
- Vec2fMap::iterator it1=a1._userAttributesVec2f->begin(), it1end=a1._userAttributesVec2f->end();
- Vec2fMap::iterator it2=a2._userAttributesVec2f->begin(), it2end=a2._userAttributesVec2f->end();
- for(; (it1!=it1end); ++it1){
- (*_userAttributesVec2f)[(*it1).first] = ((1-t)*(*it1).second+t*(*it2).second);
- }
- }
- }else{
- _userAttributesVec2f = 0;
- }
- if((a1._userAttributesVec3f) && (a2._userAttributesVec3f)){
- if(a1._userAttributesVec3f->size() == a2._userAttributesVec3f->size()){
- _userAttributesVec3f = new Vec3fMap;
- Vec3fMap::iterator it1=a1._userAttributesVec3f->begin(), it1end=a1._userAttributesVec3f->end();
- Vec3fMap::iterator it2=a2._userAttributesVec3f->begin(), it2end=a2._userAttributesVec3f->end();
- for(; (it1!=it1end); ++it1){
- (*_userAttributesVec3f)[(*it1).first] = ((1-t)*(*it1).second+t*(*it2).second);
- }
- }
- }else{
- _userAttributesVec3f = 0;
- }
+ _alpha = (1 - t) * a1._alpha + t * a2._alpha;
+ _thickness[0] = (1 - t) * a1._thickness[0] + t * a2._thickness[0];
+ _thickness[1] = (1 - t) * a1._thickness[1] + t * a2._thickness[1];
+ for (int i = 0; i < 3; ++i)
+ _color[i] = (1 - t) * a1._color[i] + t * a2._color[i];
+
+ _visible = true;
+
+ // FIXME: to be checked (and enhanced)
+ if ((a1._userAttributesReal) && (a2._userAttributesReal)) {
+ if (a1._userAttributesReal->size() == a2._userAttributesReal->size()) {
+ _userAttributesReal = new realMap;
+ realMap::iterator it1 = a1._userAttributesReal->begin(), it1end = a1._userAttributesReal->end();
+ realMap::iterator it2 = a2._userAttributesReal->begin(), it2end = a2._userAttributesReal->end();
+ for (; it1 != it1end; ++it1) {
+ (*_userAttributesReal)[(*it1).first] = ((1 - t) * (*it1).second + t * (*it2).second);
+ }
+ }
+ }
+ else {
+ _userAttributesReal = NULL;
+ }
+ if ((a1._userAttributesVec2f) && (a2._userAttributesVec2f)) {
+ if (a1._userAttributesVec2f->size() == a2._userAttributesVec2f->size()) {
+ _userAttributesVec2f = new Vec2fMap;
+ Vec2fMap::iterator it1 = a1._userAttributesVec2f->begin(), it1end = a1._userAttributesVec2f->end();
+ Vec2fMap::iterator it2 = a2._userAttributesVec2f->begin(), it2end = a2._userAttributesVec2f->end();
+ for (; it1 != it1end; ++it1) {
+ (*_userAttributesVec2f)[(*it1).first] = ((1 - t) * (*it1).second + t * (*it2).second);
+ }
+ }
+ }
+ else {
+ _userAttributesVec2f = NULL;
+ }
+ if ((a1._userAttributesVec3f) && (a2._userAttributesVec3f)) {
+ if (a1._userAttributesVec3f->size() == a2._userAttributesVec3f->size()) {
+ _userAttributesVec3f = new Vec3fMap;
+ Vec3fMap::iterator it1 = a1._userAttributesVec3f->begin(), it1end = a1._userAttributesVec3f->end();
+ Vec3fMap::iterator it2 = a2._userAttributesVec3f->begin(), it2end = a2._userAttributesVec3f->end();
+ for (; it1 != it1end; ++it1) {
+ (*_userAttributesVec3f)[(*it1).first] = ((1 - t) * (*it1).second + t * (*it2).second);
+ }
+ }
+ }
+ else {
+ _userAttributesVec3f = NULL;
+ }
}
StrokeAttribute::~StrokeAttribute()
{
- if(_userAttributesReal){
- _userAttributesReal->clear();
- delete _userAttributesReal;
- }
- if(_userAttributesVec2f){
- _userAttributesVec2f->clear();
- delete _userAttributesVec2f;
- }
- if(_userAttributesVec3f){
- _userAttributesVec3f->clear();
- delete _userAttributesVec3f;
- }
+ if (_userAttributesReal) {
+ _userAttributesReal->clear();
+ delete _userAttributesReal;
+ }
+ if (_userAttributesVec2f) {
+ _userAttributesVec2f->clear();
+ delete _userAttributesVec2f;
+ }
+ if (_userAttributesVec3f) {
+ _userAttributesVec3f->clear();
+ delete _userAttributesVec3f;
+ }
}
StrokeAttribute& StrokeAttribute::operator=(const StrokeAttribute& iBrother)
-{
- int i;
- _alpha = iBrother._alpha;
- _thickness[0] = iBrother._thickness[0];
- _thickness[1] = iBrother._thickness[1];
- for(i=0; i<3; ++i)
- _color[i] = iBrother._color[i];
- _visible = iBrother._visible;
- if(iBrother._userAttributesReal){
- if(!_userAttributesReal)
- _userAttributesReal = new realMap;
- _userAttributesReal = new realMap(*(iBrother._userAttributesReal));
- }else{
- _userAttributesReal = 0;
- }
- if(iBrother._userAttributesVec2f){
- if(!_userAttributesVec2f)
- _userAttributesVec2f = new Vec2fMap;
- _userAttributesVec2f = new Vec2fMap(*(iBrother._userAttributesVec2f));
- }else{
- _userAttributesVec2f = 0;
- }
- if(iBrother._userAttributesVec3f){
- if(!_userAttributesVec3f)
- _userAttributesVec3f = new Vec3fMap;
- _userAttributesVec3f = new Vec3fMap(*(iBrother._userAttributesVec3f));
- }else{
- _userAttributesVec3f = 0;
- }
- return *this;
-}
-
-float StrokeAttribute::getAttributeReal(const char *iName) const{
- if(!_userAttributesReal){
- cout << "StrokeAttribute warning: no real attribute was defined"<< endl;
- return 0;
- }
- realMap::iterator a = _userAttributesReal->find(iName);
- if(a ==_userAttributesReal->end()){
- cout << "StrokeAttribute warning: no real attribute was added with the name " << iName << endl;
- return 0;
- }
- return (*a).second;
-}
-Vec2f StrokeAttribute::getAttributeVec2f(const char *iName) const{
- if(!_userAttributesVec2f){
- cout << "StrokeAttribute warning: no Vec2f attribute was defined "<< endl;
- return 0;
- }
- Vec2fMap::iterator a = _userAttributesVec2f->find(iName);
- if(a ==_userAttributesVec2f->end()){
- cout << "StrokeAttribute warning: no Vec2f attribute was added with the name " << iName << endl;
- return 0;
- }
- return (*a).second;
-}
-Vec3f StrokeAttribute::getAttributeVec3f(const char *iName) const{
- if(!_userAttributesVec3f){
- cout << "StrokeAttribute warning: no Vec3f attribute was defined"<< endl;
- return 0;
- }
- Vec3fMap::iterator a = _userAttributesVec3f->find(iName);
- if(a ==_userAttributesVec3f->end()){
- cout << "StrokeAttribute warning: no Vec3f attribute was added with the name " << iName << endl;
- return 0;
- }
- return (*a).second;
-}
-bool StrokeAttribute::isAttributeAvailableReal(const char *iName) const{
- if(!_userAttributesReal){
- return false;
- }
- realMap::iterator a = _userAttributesReal->find(iName);
- if(a ==_userAttributesReal->end()){
- return false;
- }
- return true;
-}
-bool StrokeAttribute::isAttributeAvailableVec2f(const char *iName) const{
- if(!_userAttributesVec2f){
- return false;
- }
- Vec2fMap::iterator a = _userAttributesVec2f->find(iName);
- if(a ==_userAttributesVec2f->end()){
- return false;
- }
- return true;
-}
-bool StrokeAttribute::isAttributeAvailableVec3f(const char *iName) const{
- if(!_userAttributesVec3f){
- return false;
- }
- Vec3fMap::iterator a = _userAttributesVec3f->find(iName);
- if(a ==_userAttributesVec3f->end()){
- return false;
- }
- return true;
-}
-void StrokeAttribute::setAttributeReal(const char *iName, float att){
- if(!_userAttributesReal)
- _userAttributesReal = new realMap;
- (*_userAttributesReal)[iName] = att;
-}
-void StrokeAttribute::setAttributeVec2f(const char *iName, const Vec2f& att){
- if(!_userAttributesVec2f)
- _userAttributesVec2f = new Vec2fMap;
- (*_userAttributesVec2f)[iName] = att;
+{
+ int i;
+ _alpha = iBrother._alpha;
+ _thickness[0] = iBrother._thickness[0];
+ _thickness[1] = iBrother._thickness[1];
+ for (i = 0; i < 3; ++i)
+ _color[i] = iBrother._color[i];
+ _visible = iBrother._visible;
+ if (iBrother._userAttributesReal) {
+ if (!_userAttributesReal)
+ _userAttributesReal = new realMap;
+ _userAttributesReal = new realMap(*(iBrother._userAttributesReal));
+ }
+ else {
+ _userAttributesReal = NULL;
+ }
+ if (iBrother._userAttributesVec2f) {
+ if (!_userAttributesVec2f)
+ _userAttributesVec2f = new Vec2fMap;
+ _userAttributesVec2f = new Vec2fMap(*(iBrother._userAttributesVec2f));
+ }
+ else {
+ _userAttributesVec2f = NULL;
+ }
+ if (iBrother._userAttributesVec3f) {
+ if (!_userAttributesVec3f)
+ _userAttributesVec3f = new Vec3fMap;
+ _userAttributesVec3f = new Vec3fMap(*(iBrother._userAttributesVec3f));
+ }
+ else {
+ _userAttributesVec3f = NULL;
+ }
+ return *this;
+}
+
+float StrokeAttribute::getAttributeReal(const char *iName) const
+{
+ if (!_userAttributesReal) {
+ cout << "StrokeAttribute warning: no real attribute was defined" << endl;
+ return 0.0f;
+ }
+ realMap::iterator a = _userAttributesReal->find(iName);
+ if (a == _userAttributesReal->end()) {
+ cout << "StrokeAttribute warning: no real attribute was added with the name " << iName << endl;
+ return 0.0f;
+ }
+ return (*a).second;
+}
+
+Vec2f StrokeAttribute::getAttributeVec2f(const char *iName) const
+{
+ if (!_userAttributesVec2f) {
+ cout << "StrokeAttribute warning: no Vec2f attribute was defined" << endl;
+ return 0;
+ }
+ Vec2fMap::iterator a = _userAttributesVec2f->find(iName);
+ if (a == _userAttributesVec2f->end()) {
+ cout << "StrokeAttribute warning: no Vec2f attribute was added with the name " << iName << endl;
+ return 0;
+ }
+ return (*a).second;
+}
+
+Vec3f StrokeAttribute::getAttributeVec3f(const char *iName) const
+{
+ if (!_userAttributesVec3f) {
+ cout << "StrokeAttribute warning: no Vec3f attribute was defined" << endl;
+ return 0;
+ }
+ Vec3fMap::iterator a = _userAttributesVec3f->find(iName);
+ if (a == _userAttributesVec3f->end()) {
+ cout << "StrokeAttribute warning: no Vec3f attribute was added with the name " << iName << endl;
+ return 0;
+ }
+ return (*a).second;
+}
+
+bool StrokeAttribute::isAttributeAvailableReal(const char *iName) const
+{
+ if (!_userAttributesReal) {
+ return false;
+ }
+ realMap::iterator a = _userAttributesReal->find(iName);
+ if (a == _userAttributesReal->end()) {
+ return false;
+ }
+ return true;
}
-void StrokeAttribute::setAttributeVec3f(const char *iName, const Vec3f& att){
- if(!_userAttributesVec3f)
- _userAttributesVec3f = new Vec3fMap;
- (*_userAttributesVec3f)[iName] = att;
+
+bool StrokeAttribute::isAttributeAvailableVec2f(const char *iName) const
+{
+ if (!_userAttributesVec2f) {
+ return false;
+ }
+ Vec2fMap::iterator a = _userAttributesVec2f->find(iName);
+ if (a == _userAttributesVec2f->end()) {
+ return false;
+ }
+ return true;
}
- /**********************************/
- /* */
- /* */
- /* StrokeVertex */
- /* */
- /* */
- /**********************************/
-StrokeVertex::StrokeVertex()
+bool StrokeAttribute::isAttributeAvailableVec3f(const char *iName) const
+{
+ if (!_userAttributesVec3f) {
+ return false;
+ }
+ Vec3fMap::iterator a = _userAttributesVec3f->find(iName);
+ if (a == _userAttributesVec3f->end()) {
+ return false;
+ }
+ return true;
+}
-:CurvePoint()
+void StrokeAttribute::setAttributeReal(const char *iName, float att)
{
+ if (!_userAttributesReal)
+ _userAttributesReal = new realMap;
+ (*_userAttributesReal)[iName] = att;
+}
- _CurvilignAbscissa = 0.f;
+void StrokeAttribute::setAttributeVec2f(const char *iName, const Vec2f& att)
+{
+ if (!_userAttributesVec2f)
+ _userAttributesVec2f = new Vec2fMap;
+ (*_userAttributesVec2f)[iName] = att;
+}
- _StrokeLength = 0.f;
+void StrokeAttribute::setAttributeVec3f(const char *iName, const Vec3f& att)
+{
+ if (!_userAttributesVec3f)
+ _userAttributesVec3f = new Vec3fMap;
+ (*_userAttributesVec3f)[iName] = att;
}
+/**********************************/
+/* */
+/* */
+/* StrokeVertex */
+/* */
+/* */
+/**********************************/
-StrokeVertex::StrokeVertex(const StrokeVertex& iBrother)
+StrokeVertex::StrokeVertex() : CurvePoint()
+{
+ _CurvilignAbscissa = 0.0f;
+ _StrokeLength = 0.0f;
+}
-:CurvePoint(iBrother)
+StrokeVertex::StrokeVertex(const StrokeVertex& iBrother) : CurvePoint(iBrother)
{
- _Attribute = iBrother._Attribute;
+ _Attribute = iBrother._Attribute;
+ _CurvilignAbscissa = 0.0f;
+ _StrokeLength = 0.0f;
+}
- _CurvilignAbscissa = 0.f;
+StrokeVertex::StrokeVertex(SVertex *iSVertex) : CurvePoint(iSVertex, 0, 0.0f)
+{
+ _CurvilignAbscissa = 0.0f;
+ _StrokeLength = 0.0f;
+}
- _StrokeLength = 0.f;
+StrokeVertex::StrokeVertex(CurvePoint *iPoint) : CurvePoint(*iPoint)
+{
+ _CurvilignAbscissa = 0.0f;
+ _StrokeLength = 0.0f;
}
-StrokeVertex::StrokeVertex(SVertex *iSVertex)
-:CurvePoint(iSVertex,0,0.f)
+StrokeVertex::StrokeVertex(StrokeVertex *iA, StrokeVertex *iB, float t3) : CurvePoint(iA, iB, t3)
+{
+ // interpolate attributes:
+ _Attribute = StrokeAttribute(iA->attribute(), iB->attribute(), t3);
+ _CurvilignAbscissa = (1 - t3) * iA->curvilinearAbscissa() + t3 * iB->curvilinearAbscissa();
+ _StrokeLength = iA->strokeLength();
+}
+StrokeVertex::StrokeVertex(SVertex *iSVertex, const StrokeAttribute& iAttribute) : CurvePoint(iSVertex, 0, 0.0f)
{
+ _Attribute = iAttribute;
+ _CurvilignAbscissa = 0.0f;
+ _StrokeLength = 0.0f;
+}
- _CurvilignAbscissa = 0.f;
+StrokeVertex::~StrokeVertex() {}
- _StrokeLength = 0.f;
+StrokeVertex& StrokeVertex::operator=(const StrokeVertex& iBrother)
+{
+ ((CurvePoint*)this)->operator=(iBrother);
+ _Attribute = iBrother._Attribute;
-}
+ _CurvilignAbscissa = 0.0f;
+ _StrokeLength = 0.0f;
+ return *this;
+}
-StrokeVertex::StrokeVertex(CurvePoint *iPoint)
-:CurvePoint(*iPoint)
+/**********************************/
+/* */
+/* */
+/* Stroke */
+/* */
+/* */
+/**********************************/
+Stroke::Stroke()
{
+ _Length = 0;
+ _id = 0;
+ _sampling = FLT_MAX;
+ //_mediumType = DEFAULT_STROKE;
+ _mediumType = OPAQUE_MEDIUM;
+ _textureId = 0;
+ _tips = false;
+ _rep = NULL;
+}
- _CurvilignAbscissa = 0.f;
+Stroke::Stroke(const Stroke& iBrother)
+{
+ for (vertex_container::const_iterator v = iBrother._Vertices.begin(), vend = iBrother._Vertices.end();
+ v != vend;
+ v++)
+ {
+ _Vertices.push_back(*v);
+ }
+ _Length = 0;
+ _id = iBrother._id;
+ _ViewEdges = iBrother._ViewEdges;
+ _sampling = iBrother._sampling;
+ _mediumType = iBrother._mediumType;
+ _textureId = iBrother._textureId;
+ _tips = iBrother._tips;
+ if (iBrother._rep)
+ _rep = new StrokeRep(*(iBrother._rep));
+ else
+ _rep = NULL;
+}
- _StrokeLength = 0.f;
+Stroke::~Stroke()
+{
+ if (!_Vertices.empty()) {
+ for (vertex_container::iterator v = _Vertices.begin(), vend = _Vertices.end(); v != vend; v++) {
+ delete (*v);
+ }
+ _Vertices.clear();
+ }
+ _ViewEdges.clear();
+ if (_rep) {
+ delete _rep;
+ _rep = NULL;
+ }
}
+Stroke& Stroke::operator=(const Stroke& iBrother)
+{
+ if (!_Vertices.empty())
+ _Vertices.clear();
+
+ for (vertex_container::const_iterator v = iBrother._Vertices.begin(), vend = iBrother._Vertices.end();
+ v != vend;
+ v++)
+ {
+ _Vertices.push_back(*v);
+ }
+ _Length = iBrother._Length;
+ _id = iBrother._id;
+ _ViewEdges = iBrother._ViewEdges;
+ _sampling = iBrother._sampling;
+ if (_rep)
+ delete _rep;
+ if (iBrother._rep)
+ _rep = new StrokeRep(*(iBrother._rep));
+ return *this;
+}
+void Stroke::setLength(float iLength)
+{
+ _Length = iLength;
+ for (vertex_container::iterator v = _Vertices.begin(), vend = _Vertices.end(); v != vend; ++v) {
+ (*v)->setStrokeLength(iLength);
+ }
+}
-StrokeVertex::StrokeVertex(StrokeVertex *iA, StrokeVertex *iB, float t3)
+float Stroke::ComputeSampling(int iNVertices)
+{
+ if (iNVertices <= (int)_Vertices.size()) //soc
+ return _sampling;
-:CurvePoint(iA,iB,t3)
+ float sampling = _Length / (float)(iNVertices - _Vertices.size() + 1);
+ return sampling;
+}
+class StrokeSegment
{
+public:
+ StrokeInternal::StrokeVertexIterator _begin;
+ StrokeInternal::StrokeVertexIterator _end;
+ float _length;
+ int _n;
+ float _sampling;
+ bool _resampled;
+
+ StrokeSegment(StrokeInternal::StrokeVertexIterator ibegin, StrokeInternal::StrokeVertexIterator iend,
+ float ilength, int in, float isampling)
+ {
+ _begin = ibegin;
+ _end = iend;
+ _length = ilength;
+ _n = in;
+ _sampling = isampling;
+ _resampled = false;
+ }
+};
- // interpolate attributes:
+void Stroke::Resample(int iNPoints)
+{
+ int vertsize = strokeVerticesSize();
+ if (iNPoints <= vertsize)
+ return;
+
+ StrokeInternal::StrokeVertexIterator it = strokeVerticesBegin();
+ StrokeInternal::StrokeVertexIterator next = it;
+ ++next;
+ StrokeInternal::StrokeVertexIterator itend = strokeVerticesEnd();
+
+ vertex_container newVertices;
+ real t = 0.0f;
+ StrokeVertex *newVertex = NULL;
+ vector<StrokeSegment> strokeSegments;
+ int N = 0;
+ float meanlength = 0;
+ int nsegments = 0;
+ while ((it != itend) && (next != itend)) {
+ Vec2r a((it)->getPoint());
+ Vec2r b((next)->getPoint());
+ Vec2r vec_tmp(b - a);
+ real norm_var = vec_tmp.norm();
+ int numberOfPointsToAdd = (int)floor((iNPoints - strokeVerticesSize()) * norm_var / _Length);
+ float csampling = norm_var / (float)(numberOfPointsToAdd + 1);
+ strokeSegments.push_back(StrokeSegment(it, next, norm_var, numberOfPointsToAdd, csampling));
+ N += numberOfPointsToAdd;
+ meanlength += norm_var;
+ ++nsegments;
+ ++it;
+ ++next;
+ }
+ meanlength /= (float)nsegments;
+
+ // if we don't have enough points let's resample finer some segments
+ int NPointsToAdd = iNPoints - vertsize;
+ bool checkEveryone = false;
+ while (N < NPointsToAdd) {
+ for (vector<StrokeSegment>::iterator s = strokeSegments.begin(), send = strokeSegments.end(); s != send; ++s) {
+ if (s->_sampling == 0.0f)
+ continue;
+
+ if (s->_resampled == false) {
+ if ((!checkEveryone) && (s->_length < meanlength))
+ continue;
+ //resample
+ s->_n = s->_n + 1;
+ s->_sampling = s->_length / (float)(s->_n + 1);
+ s->_resampled = true;
+ N++;
+ if (N == NPointsToAdd)
+ break;
+ }
+ }
+ checkEveryone = true;
+ }
+ //actually resample:
+ for (vector<StrokeSegment>::iterator s = strokeSegments.begin(), send = strokeSegments.end(); s != send; ++s) {
+ newVertices.push_back(&(*(s->_begin)));
+ if (s->_sampling < _sampling)
+ _sampling = s->_sampling;
+
+ t = s->_sampling / s->_length;
+ for (int i = 0; i < s->_n; ++i) {
+ newVertex = new StrokeVertex(&(*(s->_begin)), &(*(s->_end)), t);
+ newVertices.push_back(newVertex);
+ t += s->_sampling / s->_length;
+ }
+ it = s->_begin;
+ next = s->_end;
+ }
+
+ // add last:
+ ++it;
+ ++next;
+ if ((it != itend) && (next == itend)/* && (t == 0.0f)*/)
+ newVertices.push_back(&(*it));
+
+ int newsize = newVertices.size();
+ if (newsize != iNPoints)
+ cerr << "Warning: incorrect points number" << endl;
+
+ _Vertices.clear();
+ _Vertices = newVertices;
+ newVertices.clear();
+
+ if (_rep) {
+ delete _rep;
+ _rep = new StrokeRep(this);
+ }
+}
- _Attribute = StrokeAttribute(iA->attribute(), iB->attribute(), t3);
- _CurvilignAbscissa = (1-t3)*iA->curvilinearAbscissa()+t3*iB->curvilinearAbscissa();
- _StrokeLength = iA->strokeLength();
+void Stroke::Resample(float iSampling)
+{
+ //cerr << "old size :" << strokeVerticesSize() << endl;
+ if (iSampling == 0)
+ return;
+ if (iSampling >= _sampling)
+ return;
+
+ _sampling = iSampling;
+ // Resample...
+ //real curvilinearLength = 0.0f;
+ vertex_container newVertices;
+ real t = 0.0f;
+ StrokeVertex *newVertex = NULL;
+ StrokeInternal::StrokeVertexIterator it = strokeVerticesBegin();
+ StrokeInternal::StrokeVertexIterator next = it;
+ ++next;
+ StrokeInternal::StrokeVertexIterator itend = strokeVerticesEnd();
+ while ((it != itend) && (next != itend)) {
+ newVertices.push_back(&(*it));
+ Vec3r a((it)->point2d());
+ Vec3r b((next)->point2d());
+ Vec3r vec_tmp(b - a);
+ real norm_var = vec_tmp.norm();
+ if (norm_var <= _sampling) {
+ //curvilinearLength += norm_var;
+ ++it;
+ ++next;
+ continue;
+ }
+
+ //curvilinearLength += _sampling;
+ t = _sampling / norm_var;
+ float limit = 0.99f;
+ while (t < limit) {
+ newVertex = new StrokeVertex(&(*it), &(*next), t);
+ //newVertex->setCurvilinearAbscissa(curvilinearLength);
+ newVertices.push_back(newVertex);
+ t = t + _sampling / norm_var;
+ }
+ ++it;
+ ++next;
+ }
+ // add last:
+ if ((it != itend) && (next == itend)/* && (t == 0.f)*/)
+ newVertices.push_back(&(*it));
+
+ _Vertices.clear();
+ _Vertices = newVertices;
+ newVertices.clear();
+
+ if (_rep) {
+ delete _rep;
+ _rep = new StrokeRep(this);
+ }
+}
+void Stroke::RemoveVertex(StrokeVertex *iVertex)
+{
+ vertex_container::iterator it = _Vertices.begin(), itend = _Vertices.end();
+ for (; it != itend; ++it) {
+ if ((*it) == iVertex) {
+ delete iVertex;
+ it = _Vertices.erase(it); // it is now the element just after the erased element
+ break;
+ }
+ }
+ UpdateLength();
}
-
+void Stroke::InsertVertex(StrokeVertex *iVertex, StrokeInternal::StrokeVertexIterator next)
+{
+ vertex_container::iterator it = _Vertices.begin(), itend = _Vertices.end();
-StrokeVertex::StrokeVertex(SVertex *iSVertex, const StrokeAttribute& iAttribute)
+ vertex_container::iterator itnext = next.getIt();
+ _Vertices.insert(itnext, iVertex);
+ UpdateLength();
+}
-:CurvePoint(iSVertex,0,0.f)
+void Stroke::UpdateLength()
+{
+ // recompute various values (length, curvilign abscissa)
+ float curvabsc = 0.0f;
+ vertex_container::iterator it = _Vertices.begin(), itend = _Vertices.end();
+ vertex_container::iterator previous = it;
+ for (; it != itend; ++it) {
+ curvabsc += ((*it)->point2d() - (*previous)->point2d()).norm();
+ (*it)->setCurvilinearAbscissa(curvabsc);
+ previous = it;
+ }
+ _Length = curvabsc;
+ for (; it != itend; ++it) {
+ (*it)->setStrokeLength(_Length);
+ }
+}
+//! embedding vertex iterator
+Stroke::const_vertex_iterator Stroke::vertices_begin() const
{
+ return const_vertex_iterator(_Vertices.begin(), _Vertices.begin(), _Vertices.end());
+}
- _Attribute = iAttribute;
+Stroke::const_vertex_iterator Stroke::vertices_end() const
+{
+ return const_vertex_iterator(_Vertices.end(), _Vertices.begin(), _Vertices.end());
+}
- _CurvilignAbscissa = 0.f;
+Stroke::vertex_iterator Stroke::vertices_end()
+{
+ return vertex_iterator(_Vertices.end(), _Vertices.begin(), _Vertices.end());
+}
- _StrokeLength = 0.f;
+StrokeInternal::StrokeVertexIterator Stroke::strokeVerticesBegin(float t)
+{
+ if ((t != 0) && (t < _sampling))
+ Resample(t);
+ return StrokeInternal::StrokeVertexIterator(this->_Vertices.begin(), this->_Vertices.begin(),
+ this->_Vertices.end());
+}
+StrokeInternal::StrokeVertexIterator Stroke::strokeVerticesEnd()
+{
+ return StrokeInternal::StrokeVertexIterator(this->_Vertices.end(), this->_Vertices.begin(), this->_Vertices.end());
}
-StrokeVertex::~StrokeVertex()
+
+Interface0DIterator Stroke::verticesBegin()
{
+Interface0DIterator ret(new StrokeInternal::StrokeVertexIterator(this->_Vertices.begin(), this->_Vertices.begin(),
+ this->_Vertices.end()));
+return ret;
}
-StrokeVertex& StrokeVertex::operator=(const StrokeVertex& iBrother)
-{
- ((CurvePoint*)this)->operator=(iBrother);
- _Attribute = iBrother._Attribute;
+Interface0DIterator Stroke::verticesEnd()
+{
+ Interface0DIterator ret(new StrokeInternal::StrokeVertexIterator(this->_Vertices.end(), this->_Vertices.begin(),
+ this->_Vertices.end()));
+ return ret;
+}
- _CurvilignAbscissa = 0.f;
+Interface0DIterator Stroke::pointsBegin(float t)
+{
+ return verticesBegin(); // FIXME
+}
- _StrokeLength = 0.f;
- return *this;
+Interface0DIterator Stroke::pointsEnd(float t)
+{
+ return verticesEnd();
}
- /**********************************/
- /* */
- /* */
- /* Stroke */
- /* */
- /* */
- /**********************************/
+void Stroke::ScaleThickness(float iFactor)
+{
+ for (vertex_container::iterator it = _Vertices.begin(), itend = _Vertices.end(); it != itend; ++it) {
+ StrokeAttribute& attr = (*it)->attribute();
+ attr.setThickness(iFactor * attr.getThicknessR(), iFactor * attr.getThicknessL());
+ }
+}
-Stroke::Stroke()
+void Stroke::Render(const StrokeRenderer *iRenderer)
{
- _Length = 0;
- _id = 0;
- _sampling = FLT_MAX;
- //_mediumType = DEFAULT_STROKE;
- _mediumType = OPAQUE_MEDIUM;
- _textureId = 0;
- _tips = false;
- _rep = 0;
+ if (!_rep)
+ _rep = new StrokeRep(this);
+ iRenderer->RenderStrokeRep(_rep);
}
-Stroke::Stroke(const Stroke& iBrother)
+void Stroke::RenderBasic(const StrokeRenderer *iRenderer)
{
- for(vertex_container::const_iterator v=iBrother._Vertices.begin(), vend=iBrother._Vertices.end();
- v!=vend;
- v++)
- {
- _Vertices.push_back(*v);
- }
- _Length = 0;
- _id = iBrother._id;
- _ViewEdges = iBrother._ViewEdges;
- _sampling = iBrother._sampling;
- _mediumType = iBrother._mediumType;
- _textureId = iBrother._textureId;
- _tips = iBrother._tips;
- if(iBrother._rep)
- _rep = new StrokeRep(*(iBrother._rep));
- else
- _rep = 0;
+ if (!_rep)
+ _rep = new StrokeRep(this);
+ iRenderer->RenderStrokeRepBasic(_rep);
+}
+Stroke::vertex_iterator Stroke::vertices_begin(float sampling)
+{
+ // Resample if necessary
+ if ((sampling != 0) && (sampling < _sampling))
+ Resample(sampling);
+ return vertex_iterator(_Vertices.begin(), _Vertices.begin(), _Vertices.end());
+ //return _Vertices.begin();
}
-Stroke::~Stroke()
+#if 0
+Stroke::vertex_iterator Stroke::vertices_last()
{
- if(!_Vertices.empty())
- {
- for(vertex_container::iterator v=_Vertices.begin(), vend=_Vertices.end();
- v!=vend;
- v++)
- {
- delete (*v);
- }
- _Vertices.clear();
- }
-
- _ViewEdges.clear();
- if(_rep != 0)
- {
- delete _rep;
- _rep = 0;
- }
+ vertex_iterator res = vertices_begin();
+ vertex_iterator next = res;
+ ++next;
+ while (!next.end()) {
+ ++next;
+ ++res;
+ }
+ return res;
}
-Stroke& Stroke::operator=(const Stroke& iBrother)
-{
- if(!_Vertices.empty())
- _Vertices.clear();
-
- for(vertex_container::const_iterator v=iBrother._Vertices.begin(), vend=iBrother._Vertices.end();
- v!=vend;
- v++)
- {
- _Vertices.push_back(*v);
- }
- _Length = iBrother._Length;
- _id = iBrother._id;
- _ViewEdges = iBrother._ViewEdges;
- _sampling = iBrother._sampling;
- if(_rep) delete _rep;
- if(iBrother._rep)
- _rep = new StrokeRep(*(iBrother._rep));
- return *this;
+Stroke::const_vertex_iterator Stroke::vertices_last() const
+{
+ const_vertex_iterator res = vertices_begin();
+ const_vertex_iterator next = res;
+ ++next;
+ while (!next.end()) {
+ ++next;
+ ++res;
+ }
+ return res;
}
+Stroke::vertex_container::reverse_iterator Stroke::vertices_last(float sampling)
+{
+ // Resample if necessary
+ if (sampling < _sampling)
+ Resample(sampling);
+ return _Vertices.rbegin();
+}
-void Stroke::setLength(float iLength)
+
+inline Vec3r shaded_color(int iCombination = 0) const;
+
+inline Vec<3, real> Stroke::orientation2d(const_vertex_iterator it) const
{
- _Length = iLength;
- for(vertex_container::iterator v=_Vertices.begin(), vend=_Vertices.end();
- v!=vend;
- ++v)
- {
- (*v)->setStrokeLength(iLength);
- }
+ return iterator_edge_orientation2d_function<Stroke, const_vertex_iterator>(this, it);
}
-float Stroke::ComputeSampling(int iNVertices)
+Vec3r Stroke::orientation2d(int iCombination) const
{
- if(iNVertices <= (int)_Vertices.size()) //soc
- return _sampling;
+ return edge_orientation2d_function<Stroke>(*this, iCombination);
+}
- float sampling = _Length/(float)(iNVertices-_Vertices.size()+1);
- return sampling;
+inline Vec3r Stroke::orientation3d(const_vertex_iterator it) const
+{
+ return iterator_edge_orientation3d_function<Stroke, const_vertex_iterator>(*this, it);
}
-class StrokeSegment
+Vec3r Stroke::orientation3d(int iCombination) const
{
-public:
- StrokeInternal::StrokeVertexIterator _begin;
- StrokeInternal::StrokeVertexIterator _end;
- float _length;
- int _n;
- float _sampling;
- bool _resampled;
-
- StrokeSegment(StrokeInternal::StrokeVertexIterator ibegin,
- StrokeInternal::StrokeVertexIterator iend,
- float ilength,
- int in,
- float isampling)
- {
- _begin=ibegin;
- _end=iend;
- _length=ilength;
- _n=in;
- _sampling = isampling;
- _resampled = false;
- }
-};
+ return edge_orientation3d_function<Stroke>(*this, iCombination);
+}
-void Stroke::Resample(int iNPoints)
+Material Stroke::material() const
{
- int vertsize = strokeVerticesSize();
- if(iNPoints <= vertsize)
- return;
-
- StrokeInternal::StrokeVertexIterator it = strokeVerticesBegin();
- StrokeInternal::StrokeVertexIterator next = it;++next;
- StrokeInternal::StrokeVertexIterator itend = strokeVerticesEnd();
-
- vertex_container newVertices;
- real t=0.f;
- StrokeVertex * newVertex = 0;
- vector<StrokeSegment> strokeSegments;
- int N=0;
- float meanlength = 0;
- int nsegments = 0;
- while(((it!=itend)&&(next!=itend)))
- {
- Vec2r a((it)->getPoint());
- Vec2r b((next)->getPoint());
- Vec2r vec_tmp(b - a);
- real norm_var = vec_tmp.norm();
- int numberOfPointsToAdd = (int)floor((iNPoints-strokeVerticesSize())*norm_var/_Length);
- float csampling = norm_var/(float)(numberOfPointsToAdd+1);
- strokeSegments.push_back(StrokeSegment(it,next,norm_var,numberOfPointsToAdd, csampling));
- N+=numberOfPointsToAdd;
- meanlength += norm_var;
- ++nsegments;
- ++it; ++next;
- }
- meanlength /= (float)nsegments;
-
- // if we don't have enough points let's resample
- // finer some segments
- int NPointsToAdd = iNPoints-vertsize;
- bool checkEveryone = false;
- while(N < NPointsToAdd)
- {
- for(vector<StrokeSegment>::iterator s=strokeSegments.begin(), send=strokeSegments.end();
- s!=send;
- ++s)
- {
- if(s->_sampling == 0.f)
- continue;
-
- if(s->_resampled == false)
- {
- if((!checkEveryone) && (s->_length < meanlength))
- continue;
- //resample
- s->_n = s->_n+1;
- s->_sampling = s->_length/(float)(s->_n+1);
- s->_resampled = true;
- N++;
- if(N == NPointsToAdd)
- break;
- }
- }
- checkEveryone = true;
- }
- //actually resample:
- for(vector<StrokeSegment>::iterator s=strokeSegments.begin(), send=strokeSegments.end();
- s!=send;
- ++s)
- {
- newVertices.push_back(&(*(s->_begin)));
- if(s->_sampling < _sampling)
- _sampling = s->_sampling;
-
- t = s->_sampling/s->_length;
- for(int i=0; i<s->_n; ++i)
- {
- newVertex = new StrokeVertex(&(*(s->_begin)),&(*(s->_end)),t);
- newVertices.push_back(newVertex);
- t += s->_sampling/s->_length;
- }
- it=s->_begin;
- next=s->_end;
- }
-
- // add last:
- ++it;++next;
- if((it != itend) && (next == itend))// && (t == 0.f))
- newVertices.push_back(&(*it));
-
- int newsize = newVertices.size();
- if(newsize != iNPoints)
- cerr << "Warning: incorrect points number" << endl;
-
- _Vertices.clear();
- _Vertices = newVertices;
- newVertices.clear();
-
- if(_rep)
- {
- delete _rep;
- _rep = new StrokeRep(this);
- }
+ const_vertex_iterator v = vertices_begin(), vend = strokeVerticesEnd();
+ Material mat = (*v)->material();
+ for (; v != vend; ++v) {
+ if (mat != (*v)->material())
+ Exception::raiseException();
+ }
+ return mat;
}
+int Stroke::qi() const
+{
+ const_vertex_iterator v = vertices_begin(), vend = vertices_end();
+ int qi_= (*v)->qi();
+ for (; v != vend; ++v) {
+ if ((*v)->qi() != qi_)
+ Exception::raiseException();
+ }
+ return qi_;
+}
-void Stroke::Resample(float iSampling)
+inline occluder_container::const_iterator occluders_begin() const
{
- // cerr<<"old size :"<<strokeVerticesSize()<<endl;
- if(iSampling == 0)
-
- return;
- if(iSampling >= _sampling)
- return ;
-
- _sampling = iSampling;
- // Resample...
- //real curvilinearLength = 0.f;
- vertex_container newVertices;
- real t=0.f;
- StrokeVertex * newVertex = 0;
- StrokeInternal::StrokeVertexIterator it = strokeVerticesBegin();
- StrokeInternal::StrokeVertexIterator next = it;++next;
- StrokeInternal::StrokeVertexIterator itend = strokeVerticesEnd();
- while(((it!=itend)&&(next!=itend)))
- {
- newVertices.push_back(&(*it));
- Vec3r a((it)->point2d());
- Vec3r b((next)->point2d());
- Vec3r vec_tmp(b - a);
- real norm_var = vec_tmp.norm();
- if(norm_var <= _sampling)
- {
- //curvilinearLength += norm_var;
- ++it; ++next;
- continue;
- }
-
- //curvilinearLength += _sampling;
- t = _sampling/norm_var;
- float limit = 0.99f;
- while(t<limit)
- {
- newVertex = new StrokeVertex(&(*it),&(*next),t);
- //newVertex->setCurvilinearAbscissa(curvilinearLength);
- newVertices.push_back(newVertex);
- t = t + _sampling/norm_var;
- }
- ++it; ++next;
- }
- // add last:
- if((it != itend) && (next == itend))// && (t == 0.f))
- newVertices.push_back(&(*it));
-
- _Vertices.clear();
- _Vertices = newVertices;
- newVertices.clear();
-
- if(_rep)
- {
- delete _rep;
- _rep = new StrokeRep(this);
- }
+ return _FEdgeA->occluders().begin();
}
-void Stroke::RemoveVertex(StrokeVertex *iVertex)
+inline occluder_container::const_iterator occluders_end() const
{
- vertex_container::iterator it=_Vertices.begin(), itend=_Vertices.end();
- for(;
- it!=itend;
- ++it)
- {
- if((*it) == iVertex)
- {
- delete iVertex;
- it = _Vertices.erase(it); // it is now the element just after the erased element
- break;
- }
- }
- UpdateLength();
+ return _FEdgeA->occluders().end();
}
-void Stroke::InsertVertex(StrokeVertex *iVertex, StrokeInternal::StrokeVertexIterator next)
+int Stroke::occluders_size() const
{
- vertex_container::iterator it=_Vertices.begin(), itend=_Vertices.end();
+ return qi();
+}
- vertex_container::iterator itnext = next.getIt();
- _Vertices.insert(itnext, iVertex);
- UpdateLength();
+bool Stroke::occluders_empty() const
+{
+ const_vertex_iterator v = vertices_begin(), vend = vertices_end();
+ bool empty = (*v)->occluders_empty();
+ for (; v != vend; ++v) {
+ if ((*v)->occluders_empty() != empty)
+ Exception::raiseException();
+ }
+ return empty;
}
-void Stroke::UpdateLength()
+#if 0
+inline const polygon3d& occludee() const
{
- // recompute various values (length, curvilign abscissa)
- float curvabsc = 0.f;
- vertex_container::iterator it=_Vertices.begin(), itend=_Vertices.end();
- vertex_container::iterator previous=it;
- for(;
- (it!=itend);
- ++it)
- {
- curvabsc += ((*it)->point2d()-(*previous)->point2d()).norm();
- (*it)->setCurvilinearAbscissa(curvabsc);
- previous = it;
- }
- _Length = curvabsc;
- for(;
- (it!=itend);
- ++it)
- {
- (*it)->setStrokeLength(_Length);
- }
+ return *(_FEdgeA->aFace());
}
+#endif
-//! embedding vertex iterator
-Stroke::const_vertex_iterator Stroke::vertices_begin() const { return const_vertex_iterator(_Vertices.begin(),_Vertices.begin(), _Vertices.end()); }
-Stroke::const_vertex_iterator Stroke::vertices_end() const { return const_vertex_iterator(_Vertices.end(),_Vertices.begin(), _Vertices.end()); }
-Stroke::vertex_iterator Stroke::vertices_end() { return vertex_iterator(_Vertices.end(),_Vertices.begin(), _Vertices.end()); }
+const SShape * Stroke::occluded_shape() const
+{
+ const_vertex_iterator v = vertices_begin(), vend = vertices_end();
+ const SShape *sshape = (*v)->occluded_shape();
+ for (; v != vend; ++v) {
+ if ((*v)->occluded_shape() != sshape)
+ Exception::raiseException();
+ }
+ return sshape;
+}
-StrokeInternal::StrokeVertexIterator Stroke::strokeVerticesBegin(float t) {
- if((t!=0) && (t < _sampling))
- Resample(t);
- return StrokeInternal::StrokeVertexIterator(this->_Vertices.begin(), this->_Vertices.begin(), this->_Vertices.end());
+const bool Stroke::occludee_empty() const
+{
+ const_vertex_iterator v = vertices_begin(), vend = vertices_end();
+ bool empty = (*v)->occludee_empty();
+ for (; v != vend; ++v) {
+ if ((*v)->occludee_empty() != empty)
+ Exception::raiseException();
+ }
+ return empty;
}
-StrokeInternal::StrokeVertexIterator Stroke::strokeVerticesEnd() {
- return StrokeInternal::StrokeVertexIterator(this->_Vertices.end(), this->_Vertices.begin(), this->_Vertices.end());
+const SShape * Stroke::shape() const
+{
+ const_vertex_iterator v = vertices_begin(), vend = vertices_end();
+ const SShape *sshape = (*v)->shape();
+ for (; v != vend; ++v) {
+ if ((*v)->shape() != sshape)
+ Exception::raiseException();
+ }
+ return sshape;
}
-Interface0DIterator Stroke::verticesBegin() {
- Interface0DIterator ret(new StrokeInternal::StrokeVertexIterator(this->_Vertices.begin(),
- this->_Vertices.begin(),
- this->_Vertices.end()));
- return ret;
+real Stroke::z_discontinuity(int iCombination) const
+{
+ return z_discontinuity_edge_function<Stroke>(*this, iCombination);
}
-Interface0DIterator Stroke::verticesEnd() {
- Interface0DIterator ret(new StrokeInternal::StrokeVertexIterator(this->_Vertices.end(),
- this->_Vertices.begin(),
- this->_Vertices.end()));
- return ret;
+Vec3r Stroke::curvature2d_as_vector(int iCombination) const
+{
+ return curvature2d_as_vector_edge_function<Stroke>(*this, iCombination);
}
-Interface0DIterator Stroke::pointsBegin(float t) {
- return verticesBegin(); // FIXME
+real Stroke::curvature2d_as_angle(int iCombination) const
+{
+ return curvature2d_as_angle_edge_function<Stroke>(*this, iCombination);
}
-Interface0DIterator Stroke::pointsEnd(float t) {
- return verticesEnd();
+float Stroke::shape_importance(int iCombination) const
+{
+ return shape_importance_edge_function<Stroke>(*this, iCombination);
}
-void Stroke::ScaleThickness(float iFactor)
+
+float Stroke::local_average_depth(int iCombination ) const
{
- for(vertex_container::iterator it=_Vertices.begin(), itend=_Vertices.end();
- it!=itend;
- ++it)
- {
- StrokeAttribute& attr = (*it)->attribute();
- attr.setThickness(iFactor * attr.getThicknessR(), iFactor * attr.getThicknessL());
- }
+ return local_average_depth_edge_function<Stroke >(*this, iCombination);
}
-void Stroke::Render(const StrokeRenderer *iRenderer)
+float Stroke::local_depth_variance(int iCombination) const
{
- if(!_rep)
- _rep = new StrokeRep(this);
- iRenderer->RenderStrokeRep(_rep);
+ return local_depth_variance_edge_function<Stroke>(*this, iCombination);
}
-void Stroke::RenderBasic(const StrokeRenderer *iRenderer)
+real Stroke::local_average_density(float sigma , int iCombination ) const
{
- if(!_rep)
- _rep = new StrokeRep(this);
- iRenderer->RenderStrokeRepBasic(_rep);
-}
-
-Stroke::vertex_iterator Stroke::vertices_begin(float sampling)
-{
- // Resample if necessary
- if((sampling != 0) && (sampling < _sampling))
- Resample(sampling);
- return vertex_iterator(_Vertices.begin(),_Vertices.begin(),_Vertices.end());
- //return _Vertices.begin();
-}
-//
-//Stroke::vertex_iterator Stroke::vertices_last()
-//{
-// vertex_iterator res = vertices_begin();
-// vertex_iterator next = res;++next;
-// while(!next.end())
-// {
-// ++next;
-// ++res;
-// }
-// return res;
-//}
-//
-//Stroke::const_vertex_iterator Stroke::vertices_last() const
-//{
-// const_vertex_iterator res = vertices_begin();
-// const_vertex_iterator next = res;++next;
-// while(!next.end())
-// {
-// ++next;
-// ++res;
-// }
-// return res;
-//}
-
-//Stroke::vertex_container::reverse_iterator Stroke::vertices_last(float sampling)
-//{
-// // Resample if necessary
-// if(sampling < _sampling)
-// Resample(sampling);
-// return _Vertices.rbegin();
-//}
-
-
-//inline Vec3r shaded_color(int iCombination = 0) const ;
-//inline Vec<3,real> Stroke::orientation2d(const_vertex_iterator it) const
-//{
-// return iterator_edge_orientation2d_function<Stroke, const_vertex_iterator>(this, it);
-//}
-// Vec3r Stroke::orientation2d(int iCombination) const
-// {
-// return edge_orientation2d_function<Stroke>(*this, iCombination);
-// }
-//inline Vec3r Stroke::orientation3d(const_vertex_iterator it) const
-//{
-// return iterator_edge_orientation3d_function<Stroke, const_vertex_iterator>(*this, it);
-//}
-// Vec3r Stroke::orientation3d(int iCombination) const
-// {
-// return edge_orientation3d_function<Stroke>(*this, iCombination);
-// }
-
-//Material Stroke::material() const
-//{
-// const_vertex_iterator v=vertices_begin(), vend=strokeVerticesEnd();
-// Material mat = (*v)->material();
-// for(;v!=vend;++v)
-// {
-// if(mat != (*v)->material())
-// Exception::raiseException();
-// }
-// return mat;
-//}
-
-//int Stroke::qi() const
-//{
-// const_vertex_iterator v=vertices_begin(), vend=vertices_end();
-// int qi_= (*v)->qi();
-// for(;v!=vend;++v)
-// {
-// if((*v)->qi() != qi_)
-// Exception::raiseException();
-// }
-// return qi_;
-//}
-//inline occluder_container::const_iterator occluders_begin() const {return _FEdgeA->occluders().begin();}
-//inline occluder_container::const_iterator occluders_end() const {return _FEdgeA->occluders().end();}
-
-//int Stroke::occluders_size() const
-//{
-// return qi();
-//}
-//
-//bool Stroke::occluders_empty() const
-//{
-// const_vertex_iterator v=vertices_begin(), vend=vertices_end();
-// bool empty = (*v)->occluders_empty();
-// for(;v!=vend;++v)
-// {
-// if((*v)->occluders_empty() != empty)
-// Exception::raiseException();
-// }
-// return empty;
-//}
-////inline const polygon3d& occludee() const {return *(_FEdgeA->aFace());}
-//const SShape * Stroke::occluded_shape() const
-//{
-// const_vertex_iterator v=vertices_begin(), vend=vertices_end();
-// const SShape *sshape = (*v)->occluded_shape();
-// for(;v!=vend;++v)
-// {
-// if((*v)->occluded_shape() != sshape)
-// Exception::raiseException();
-// }
-// return sshape;
-//}
-//
-//const bool Stroke::occludee_empty() const
-//{
-// const_vertex_iterator v=vertices_begin(), vend=vertices_end();
-// bool empty = (*v)->occludee_empty();
-// for(;v!=vend;++v)
-// {
-// if((*v)->occludee_empty() != empty)
-// Exception::raiseException();
-// }
-// return empty;
-//}
-
-//const SShape * Stroke::shape() const
-//{
-// const_vertex_iterator v=vertices_begin(), vend=vertices_end();
-// const SShape *sshape = (*v)->shape();
-// for(;v!=vend;++v)
-// {
-// if((*v)->shape() != sshape)
-// Exception::raiseException();
-// }
-// return sshape;
-//}
-
-// real Stroke::z_discontinuity(int iCombination) const
-// {
-// return z_discontinuity_edge_function<Stroke>(*this, iCombination);
-// }
-
-// Vec3r Stroke::curvature2d_as_vector(int iCombination) const
-// {
-// return curvature2d_as_vector_edge_function<Stroke>(*this, iCombination);
-// }
-
-// real Stroke::curvature2d_as_angle(int iCombination) const
-// {
-// return curvature2d_as_angle_edge_function<Stroke>(*this, iCombination);
-// }
-
-// float Stroke::shape_importance(int iCombination) const
-// {
-// return shape_importance_edge_function<Stroke>(*this, iCombination);
-// }
-
-
-// float Stroke::local_average_depth(int iCombination ) const
-// {
-// return local_average_depth_edge_function<Stroke >(*this, iCombination);
-// }
-
-// float Stroke::local_depth_variance(int iCombination) const
-// {
-// return local_depth_variance_edge_function<Stroke>(*this, iCombination);
-// }
-
-// real Stroke::local_average_density(float sigma , int iCombination ) const
-// {
-// return density_edge_function<Stroke>(*this, iCombination);
-// }
+ return density_edge_function<Stroke>(*this, iCombination);
+}
+#endif