~ubuntu-branches/ubuntu/trusty/blender/trusty-proposed

« back to all changes in this revision

Viewing changes to source/blender/freestyle/intern/view_map/Silhouette.h

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2013-08-14 10:43:49 UTC
  • mfrom: (14.2.19 sid)
  • Revision ID: package-import@ubuntu.com-20130814104349-t1d5mtwkphp12dyj
Tags: 2.68a-3
* Upload to unstable
* debian/: python3.3 Depends simplified
  - debian/control: python3.3 Depends dropped
    for blender-data package
  - 0001-blender_thumbnailer.patch refreshed
* debian/control: libavcodec b-dep versioning dropped

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * ***** BEGIN GPL LICENSE BLOCK *****
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License
 
6
 * as published by the Free Software Foundation; either version 2
 
7
 * of the License, or (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software Foundation,
 
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
17
 *
 
18
 * ***** END GPL LICENSE BLOCK *****
 
19
 */
 
20
 
 
21
#ifndef __FREESTYLE_SILHOUETTE_H__
 
22
#define __FREESTYLE_SILHOUETTE_H__
 
23
 
 
24
/** \file blender/freestyle/intern/view_map/Silhouette.h
 
25
 *  \ingroup freestyle
 
26
 *  \brief Classes to define a silhouette structure
 
27
 *  \author Stephane Grabli
 
28
 *  \date 25/03/2002
 
29
 */
 
30
 
 
31
#include <float.h>
 
32
#include <iostream>
 
33
#include <set>
 
34
#include <string>
 
35
#include <vector>
 
36
 
 
37
#include "Interface0D.h"
 
38
#include "Interface1D.h"
 
39
 
 
40
#include "../geometry/BBox.h"
 
41
#include "../geometry/Geom.h"
 
42
#include "../geometry/Polygon.h"
 
43
 
 
44
#include "../scene_graph/FrsMaterial.h"
 
45
 
 
46
#include "../system/Exception.h"
 
47
#include "../system/FreestyleConfig.h"
 
48
 
 
49
#include "../winged_edge/Curvature.h"
 
50
 
 
51
#ifdef WITH_CXX_GUARDEDALLOC
 
52
#include "MEM_guardedalloc.h"
 
53
#endif
 
54
 
 
55
using namespace std;
 
56
 
 
57
namespace Freestyle {
 
58
 
 
59
using namespace Geometry;
 
60
 
 
61
class ViewShape;
 
62
typedef vector<ViewShape*> occluder_container;
 
63
 
 
64
/**********************************/
 
65
/*                                */
 
66
/*                                */
 
67
/*             SVertex            */
 
68
/*                                */
 
69
/*                                */
 
70
/**********************************/
 
71
 
 
72
class FEdge;
 
73
class ViewVertex;
 
74
class SShape;
 
75
 
 
76
/*! Class to define a vertex of the embedding. */
 
77
class LIB_VIEW_MAP_EXPORT SVertex : public Interface0D
 
78
{
 
79
public: // Implementation of Interface0D
 
80
        /*! Returns the string "SVertex" .*/
 
81
        virtual string getExactTypeName() const
 
82
        {
 
83
                return "SVertex";
 
84
        }
 
85
 
 
86
        // Data access methods
 
87
        /*! Returns the 3D x coordinate of the vertex .*/
 
88
        virtual real getX() const
 
89
        {
 
90
                return _Point3D.x();
 
91
        }
 
92
 
 
93
        /*! Returns the 3D y coordinate of the vertex .*/
 
94
        virtual real getY() const
 
95
        {
 
96
                return _Point3D.y();
 
97
        }
 
98
 
 
99
        /*! Returns the 3D z coordinate of the vertex .*/
 
100
        virtual real getZ() const
 
101
        {
 
102
                return _Point3D.z();
 
103
        }
 
104
 
 
105
        /*!  Returns the 3D point. */ 
 
106
        virtual Vec3f getPoint3D() const
 
107
        {
 
108
                return _Point3D;
 
109
        }
 
110
 
 
111
        /*! Returns the projected 3D  x coordinate of the vertex .*/
 
112
        virtual real getProjectedX() const
 
113
        {
 
114
                return _Point2D.x();
 
115
        }
 
116
 
 
117
        /*! Returns the projected 3D  y coordinate of the vertex .*/
 
118
        virtual real getProjectedY() const
 
119
        {
 
120
                return _Point2D.y();
 
121
        }
 
122
 
 
123
        /*! Returns the projected 3D  z coordinate of the vertex .*/
 
124
        virtual real getProjectedZ() const
 
125
        {
 
126
                return _Point2D.z();
 
127
        }
 
128
 
 
129
        /*!  Returns the 2D point. */ 
 
130
        virtual Vec2f getPoint2D() const
 
131
        {
 
132
                return Vec2f((float)_Point2D.x(), (float)_Point2D.y());
 
133
        }
 
134
 
 
135
        /*! Returns the FEdge that lies between this Svertex and the Interface0D given as argument. */
 
136
        virtual FEdge *getFEdge(Interface0D&);
 
137
 
 
138
        /*! Returns the Id of the vertex .*/
 
139
        virtual Id getId() const
 
140
        {
 
141
                return _Id;
 
142
        }
 
143
 
 
144
        /*! Returns the nature of the vertex .*/
 
145
        virtual Nature::VertexNature getNature() const;
 
146
 
 
147
        /*! Cast the Interface0D in SVertex if it can be. */ 
 
148
        virtual SVertex *castToSVertex();
 
149
 
 
150
        /*! Cast the Interface0D in ViewVertex if it can be. */ 
 
151
        virtual ViewVertex *castToViewVertex();
 
152
 
 
153
        /*! Cast the Interface0D in NonTVertex if it can be. */ 
 
154
        virtual NonTVertex *castToNonTVertex();
 
155
 
 
156
        /*! Cast the Interface0D in TVertex if it can be. */ 
 
157
        virtual TVertex *castToTVertex();
 
158
 
 
159
public:
 
160
        typedef vector<FEdge*> fedges_container;
 
161
 
 
162
private:
 
163
        Id _Id;
 
164
        Vec3r _Point3D;
 
165
        Vec3r _Point2D;
 
166
        set<Vec3r> _Normals; 
 
167
        vector<FEdge*> _FEdges; // the edges containing this vertex
 
168
        SShape *_Shape;  // the shape to which belongs the vertex
 
169
        ViewVertex *_pViewVertex; // The associated viewvertex, in case there is one.
 
170
        real _curvatureFredo;
 
171
        Vec2r _directionFredo;
 
172
        CurvatureInfo *_curvature_info;
 
173
 
 
174
public:
 
175
        /*! A field that can be used by the user to store any data.
 
176
         *  This field must be reseted afterwards using ResetUserData().
 
177
         */
 
178
        void *userdata;
 
179
 
 
180
        /*! Default constructor.*/
 
181
        inline SVertex()
 
182
        {
 
183
                _Id = 0;
 
184
                userdata = NULL;
 
185
                _Shape = NULL;
 
186
                _pViewVertex = 0;
 
187
                _curvature_info = 0;
 
188
        }
 
189
 
 
190
        /*! Builds a SVertex from 3D coordinates and an Id. */
 
191
        inline SVertex(const Vec3r &iPoint3D, const Id& id)
 
192
        {
 
193
                _Point3D = iPoint3D;
 
194
                _Id = id;
 
195
                userdata = NULL;
 
196
                _Shape = NULL;
 
197
                _pViewVertex = 0;
 
198
                _curvature_info = 0;
 
199
        }
 
200
 
 
201
        /*! Copy constructor. */
 
202
        inline SVertex(SVertex& iBrother)
 
203
        {
 
204
                _Id = iBrother._Id;
 
205
                _Point3D =  iBrother.point3D();
 
206
                _Point2D = iBrother.point2D();
 
207
                _Normals = iBrother._Normals;
 
208
                _FEdges = iBrother.fedges();
 
209
                _Shape = iBrother.shape();
 
210
                _pViewVertex = iBrother._pViewVertex;
 
211
                if (!(iBrother._curvature_info))
 
212
                        _curvature_info = 0;
 
213
                else
 
214
                        _curvature_info = new CurvatureInfo(*(iBrother._curvature_info));
 
215
                iBrother.userdata = this;
 
216
                userdata = 0;
 
217
        }
 
218
 
 
219
        /*! Destructor. */
 
220
        virtual ~SVertex()
 
221
        {
 
222
                if (_curvature_info)
 
223
                        delete _curvature_info;
 
224
        }
 
225
 
 
226
        /*! Cloning method. */
 
227
        virtual SVertex *duplicate()
 
228
        {
 
229
                SVertex *clone = new SVertex(*this);
 
230
                return clone;
 
231
        }
 
232
 
 
233
        /*! operator == */
 
234
        virtual bool operator==(const SVertex& iBrother)
 
235
        {
 
236
                return ((_Point2D == iBrother._Point2D) && (_Point3D == iBrother._Point3D));
 
237
        }
 
238
 
 
239
        /* accessors */
 
240
        inline const Vec3r& point3D() const
 
241
        {
 
242
                return _Point3D;
 
243
        }
 
244
 
 
245
        inline const Vec3r& point2D() const
 
246
        {
 
247
                return _Point2D;
 
248
        }
 
249
 
 
250
        /*! Returns the set of normals for this Vertex.
 
251
         *  In a smooth surface, a vertex has exactly one normal.
 
252
         *  In a sharp surface, a vertex can have any number of normals.
 
253
         */
 
254
        inline set<Vec3r> normals()
 
255
        {
 
256
                return _Normals;
 
257
        }
 
258
 
 
259
        /*! Returns the number of different normals for this vertex. */
 
260
        inline unsigned normalsSize() const
 
261
        {
 
262
                return _Normals.size();
 
263
        }
 
264
 
 
265
        inline const vector<FEdge*>& fedges()
 
266
        {
 
267
                return _FEdges;
 
268
        }
 
269
 
 
270
        inline fedges_container::iterator fedges_begin()
 
271
        {
 
272
                return _FEdges.begin();
 
273
        }
 
274
 
 
275
        inline fedges_container::iterator fedges_end()
 
276
        {
 
277
                return _FEdges.end();
 
278
        }
 
279
 
 
280
        inline SShape *shape()
 
281
        {
 
282
                return _Shape;
 
283
        }
 
284
 
 
285
        inline real z() const
 
286
        {
 
287
                return _Point2D[2];
 
288
        }
 
289
 
 
290
        /*! If this SVertex is also a ViewVertex, this method returns a pointer onto this ViewVertex.
 
291
         *  0 is returned otherwise.
 
292
         */
 
293
        inline ViewVertex *viewvertex()
 
294
        {
 
295
                return _pViewVertex;
 
296
        }
 
297
 
 
298
        /*! modifiers */
 
299
        /*! Sets the 3D coordinates of the SVertex. */
 
300
        inline void setPoint3D(const Vec3r &iPoint3D)
 
301
        {
 
302
                _Point3D = iPoint3D;
 
303
        }
 
304
 
 
305
        /*! Sets the 3D projected coordinates of the SVertex. */
 
306
        inline void setPoint2D(const Vec3r &iPoint2D)
 
307
        {
 
308
                _Point2D = iPoint2D;
 
309
        }
 
310
 
 
311
        /*! Adds a normal to the Svertex's set of normals. If the same normal is already in the set, nothing changes. */
 
312
        inline void AddNormal(const Vec3r& iNormal)
 
313
        {
 
314
                _Normals.insert(iNormal); // if iNormal in the set already exists, nothing is done
 
315
        }
 
316
 
 
317
        void setCurvatureInfo(CurvatureInfo *ci)
 
318
        {
 
319
                if (_curvature_info) // Q. is this an error condition? (T.K. 02-May-2011)
 
320
                        delete _curvature_info;
 
321
                _curvature_info = ci;
 
322
        }
 
323
 
 
324
        const CurvatureInfo *getCurvatureInfo() const
 
325
        {
 
326
                return _curvature_info;
 
327
        }
 
328
 
 
329
        /* Fredo's normal and curvature*/
 
330
        void setCurvatureFredo(real c)
 
331
        {
 
332
                _curvatureFredo = c;
 
333
        }
 
334
 
 
335
        void setDirectionFredo(Vec2r d)
 
336
        {
 
337
                _directionFredo = d;
 
338
        }
 
339
 
 
340
        real curvatureFredo ()
 
341
        {
 
342
                return _curvatureFredo;
 
343
        }
 
344
 
 
345
        const Vec2r directionFredo ()
 
346
        {
 
347
                return _directionFredo;
 
348
        }
 
349
 
 
350
        /*! Sets the Id */
 
351
        inline void setId(const Id& id)
 
352
        {
 
353
                _Id = id;
 
354
        }
 
355
 
 
356
        inline void setFEdges(const vector<FEdge*>& iFEdges)
 
357
        {
 
358
                _FEdges = iFEdges;
 
359
        }
 
360
 
 
361
        inline void setShape(SShape *iShape)
 
362
        {
 
363
                _Shape = iShape;
 
364
        }
 
365
 
 
366
        inline void setViewVertex(ViewVertex *iViewVertex)
 
367
        {
 
368
                _pViewVertex = iViewVertex;
 
369
        }
 
370
 
 
371
        /*! Add an FEdge to the list of edges emanating from this SVertex. */
 
372
        inline void AddFEdge(FEdge *iFEdge)
 
373
        {
 
374
                _FEdges.push_back(iFEdge);
 
375
        }
 
376
 
 
377
        /* replaces edge 1 by edge 2 in the list of edges */
 
378
        inline void Replace(FEdge *e1, FEdge *e2)
 
379
        {
 
380
                vector<FEdge *>::iterator insertedfe;
 
381
                for (vector<FEdge *>::iterator fe = _FEdges.begin(), fend = _FEdges.end(); fe != fend; fe++) {
 
382
                        if ((*fe) == e1) {
 
383
                                insertedfe = _FEdges.insert(fe, e2);// inserts e2 before fe.
 
384
                                // returns an iterator pointing toward e2. fe is invalidated.
 
385
                                // we want to remove e1, but we can't use fe anymore:
 
386
                                ++insertedfe; // insertedfe points now to e1
 
387
                                _FEdges.erase(insertedfe);
 
388
                                return;
 
389
                        }
 
390
                }
 
391
        }
 
392
 
 
393
public:
 
394
        /* Information access interface */
 
395
        FEdge *fedge(); // for non T vertex
 
396
 
 
397
        inline const Vec3r& point2d() const
 
398
        {
 
399
                return point2D();
 
400
        }
 
401
 
 
402
        inline const Vec3r& point3d() const
 
403
        {
 
404
                return point3D();
 
405
        }
 
406
 
 
407
        inline Vec3r normal() const
 
408
        {
 
409
                if (_Normals.size() == 1)
 
410
                        return (*(_Normals.begin()));
 
411
                Exception::raiseException();
 
412
                return *(_Normals.begin());
 
413
        }
 
414
 
 
415
        //Material material() const ;
 
416
        Id shape_id() const;
 
417
        const SShape *shape() const;
 
418
        float shape_importance() const;
 
419
 
 
420
        const int qi() const;
 
421
        occluder_container::const_iterator occluders_begin() const;
 
422
        occluder_container::const_iterator occluders_end() const;
 
423
        bool occluders_empty() const;
 
424
        int occluders_size() const;
 
425
        const Polygon3r& occludee() const;
 
426
        const SShape *occluded_shape() const;
 
427
        const bool occludee_empty() const;
 
428
        real z_discontinuity() const;
 
429
#if 0
 
430
        inline float local_average_depth() const;
 
431
        inline float local_depth_variance() const;
 
432
        inline real local_average_density(float sigma = 2.3f) const;
 
433
        inline Vec3r shaded_color() const;
 
434
        inline Vec3r orientation2d() const;
 
435
        inline Vec3r orientation3d() const;
 
436
        inline Vec3r curvature2d_as_vector() const;
 
437
        /*! angle in radians */
 
438
        inline real curvature2d_as_angle() const;
 
439
#endif
 
440
};
 
441
 
 
442
/**********************************/
 
443
/*                                */
 
444
/*                                */
 
445
/*             FEdge              */
 
446
/*                                */
 
447
/*                                */
 
448
/**********************************/
 
449
 
 
450
class ViewEdge;
 
451
 
 
452
/*! Base Class for feature edges.
 
453
 *  This FEdge can represent a silhouette, a crease, a ridge/valley, a border or a suggestive contour.
 
454
 *  For silhouettes,  the FEdge is oriented such as, the visible face lies on the left of the edge.
 
455
 *  For borders, the FEdge is oriented such as, the face lies on the left of the edge.
 
456
 *  An FEdge can represent an initial edge of the mesh or runs accross a face of the initial mesh depending
 
457
 *  on the smoothness or sharpness of the mesh.
 
458
 *  This class is specialized into a smooth and a sharp version since their properties slightly vary from
 
459
 *  one to the other.
 
460
 */
 
461
class LIB_VIEW_MAP_EXPORT FEdge : public Interface1D
 
462
{
 
463
public: // Implementation of Interface0D
 
464
        /*! Returns the string "FEdge". */
 
465
        virtual string getExactTypeName() const
 
466
        {
 
467
                return "FEdge";
 
468
        }
 
469
 
 
470
        // Data access methods
 
471
 
 
472
        /*! Returns the 2D length of the FEdge. */
 
473
        virtual real getLength2D() const
 
474
        {
 
475
                if (!_VertexA || !_VertexB)
 
476
                        return 0;
 
477
                return (_VertexB->getPoint2D() - _VertexA->getPoint2D()).norm();
 
478
        }
 
479
 
 
480
        /*! Returns the Id of the FEdge. */
 
481
        virtual Id getId() const
 
482
        {
 
483
                return _Id;
 
484
        }
 
485
 
 
486
public:
 
487
        // An edge can only be of one kind (SILHOUETTE or BORDER, etc...)
 
488
        // For an multi-nature edge there must be several different FEdge.
 
489
        //  DEBUG:
 
490
        //  Vec3r A;
 
491
        //  Vec3r u;
 
492
        //  vector<Polygon3r> _Occludees;
 
493
        //  Vec3r intersection;
 
494
        //  vector<Vec3i> _Cells;
 
495
 
 
496
protected:
 
497
        SVertex *_VertexA;
 
498
        SVertex *_VertexB;
 
499
        Id _Id;
 
500
        Nature::EdgeNature _Nature;
 
501
        //vector<Polygon3r> _Occluders; // visibility // NOT HANDLED BY THE COPY CONSTRUCTOR!!
 
502
 
 
503
        FEdge *_NextEdge; // next edge on the chain
 
504
        FEdge *_PreviousEdge;
 
505
        ViewEdge *_ViewEdge;
 
506
        // Sometimes we need to deport the visibility computation onto another edge. For example the exact edges use
 
507
        // edges of the mesh to compute their visibility
 
508
 
 
509
        Polygon3r _aFace; // The occluded face which lies on the right of a silhouette edge
 
510
        Vec3r _occludeeIntersection;
 
511
        bool _occludeeEmpty;
 
512
 
 
513
        bool _isSmooth;
 
514
 
 
515
        bool _isInImage;
 
516
 
 
517
public:
 
518
        /*! A field that can be used by the user to store any data.
 
519
         *  This field must be reseted afterwards using ResetUserData().
 
520
         */
 
521
        void *userdata;
 
522
 
 
523
        /*! Default constructor */
 
524
        inline FEdge()
 
525
        {
 
526
                userdata = NULL;
 
527
                _VertexA = NULL;
 
528
                _VertexB = NULL;
 
529
                _Nature = Nature::NO_FEATURE;
 
530
                _NextEdge = NULL;
 
531
                _PreviousEdge = NULL;
 
532
                _ViewEdge = NULL;
 
533
                //_hasVisibilityPoint = false;
 
534
                _occludeeEmpty = true;
 
535
                _isSmooth = false;
 
536
                _isInImage = true;
 
537
        }
 
538
 
 
539
        /*! Builds an FEdge going from vA to vB. */
 
540
        inline FEdge(SVertex *vA, SVertex *vB)
 
541
        {
 
542
                userdata = NULL;
 
543
                _VertexA = vA;
 
544
                _VertexB = vB;
 
545
                _Nature = Nature::NO_FEATURE;
 
546
                _NextEdge = NULL;
 
547
                _PreviousEdge = NULL;
 
548
                _ViewEdge = NULL;
 
549
                //_hasVisibilityPoint = false;
 
550
                _occludeeEmpty = true;
 
551
                _isSmooth = false;
 
552
                _isInImage = true;
 
553
        }
 
554
 
 
555
        /*! Copy constructor */
 
556
        inline FEdge(FEdge& iBrother)
 
557
        {
 
558
                _VertexA = iBrother.vertexA();
 
559
                _VertexB = iBrother.vertexB();
 
560
                _NextEdge = iBrother.nextEdge();
 
561
                _PreviousEdge = iBrother._PreviousEdge;
 
562
                _Nature = iBrother.getNature();
 
563
                _Id = iBrother._Id;
 
564
                _ViewEdge = iBrother._ViewEdge;
 
565
                //_hasVisibilityPoint = iBrother._hasVisibilityPoint;
 
566
                //_VisibilityPointA = iBrother._VisibilityPointA;
 
567
                //_VisibilityPointB = iBrother._VisibilityPointB;
 
568
                _aFace = iBrother._aFace;
 
569
                _occludeeEmpty = iBrother._occludeeEmpty;
 
570
                _isSmooth = iBrother._isSmooth;
 
571
                _isInImage = iBrother._isInImage;
 
572
                iBrother.userdata = this;
 
573
                userdata = 0;
 
574
        }
 
575
 
 
576
        /*! Destructor */
 
577
        virtual ~FEdge() {}
 
578
 
 
579
        /*! Cloning method. */
 
580
        virtual FEdge *duplicate()
 
581
        {
 
582
                FEdge *clone = new FEdge(*this);
 
583
                return clone;
 
584
        }
 
585
 
 
586
        /* accessors */
 
587
        /*! Returns the first SVertex. */
 
588
        inline SVertex *vertexA()
 
589
        {
 
590
                return _VertexA;
 
591
        }
 
592
 
 
593
        /*! Returns the second SVertex. */
 
594
        inline SVertex *vertexB()
 
595
        {
 
596
                return _VertexB;
 
597
        }
 
598
 
 
599
        /*! Returns the first SVertex if i=0, the seccond SVertex if i=1. */
 
600
        inline SVertex *operator[](const unsigned short int& i) const
 
601
        {
 
602
                return (i % 2 == 0) ? _VertexA : _VertexB;
 
603
        }
 
604
 
 
605
        /*! Returns the nature of the FEdge. */
 
606
        inline Nature::EdgeNature getNature() const
 
607
        {
 
608
                return _Nature;
 
609
        }
 
610
 
 
611
        /*! Returns the FEdge following this one in the ViewEdge.
 
612
         *  If this FEdge is the last of the ViewEdge, 0 is returned.
 
613
         */
 
614
        inline FEdge *nextEdge()
 
615
        {
 
616
                return _NextEdge;
 
617
        }
 
618
 
 
619
        /*! Returns the Edge preceding this one in the ViewEdge.
 
620
         *  If this FEdge is the first one of the ViewEdge, 0 is returned.
 
621
         */
 
622
        inline FEdge *previousEdge()
 
623
        {
 
624
                return _PreviousEdge;
 
625
        }
 
626
 
 
627
        inline SShape *shape()
 
628
        {
 
629
                return _VertexA->shape();
 
630
        }
 
631
 
 
632
#if 0
 
633
        inline int invisibility() const
 
634
        {
 
635
                return _Occluders.size();
 
636
        }
 
637
#endif
 
638
 
 
639
        int invisibility() const;
 
640
 
 
641
#if 0
 
642
        inline const vector<Polygon3r>& occluders() const
 
643
        {
 
644
                return _Occluders;
 
645
        }
 
646
#endif
 
647
 
 
648
        /*! Returns a pointer to the ViewEdge to which this FEdge belongs to. */
 
649
        inline ViewEdge *viewedge() const
 
650
        {
 
651
                return _ViewEdge;
 
652
        }
 
653
 
 
654
        inline Vec3r center3d()
 
655
        {
 
656
                return Vec3r((_VertexA->point3D() + _VertexB->point3D()) / 2.0);
 
657
        }
 
658
 
 
659
        inline Vec3r center2d()
 
660
        {
 
661
                return Vec3r((_VertexA->point2D() + _VertexB->point2D()) / 2.0);
 
662
        }
 
663
 
 
664
#if 0
 
665
        inline bool hasVisibilityPoint() const
 
666
        {
 
667
                return _hasVisibilityPoint;
 
668
        }
 
669
 
 
670
        inline Vec3r visibilityPointA() const
 
671
        {
 
672
                return _VisibilityPointA;
 
673
        }
 
674
 
 
675
        inline Vec3r visibilityPointB() const
 
676
        {
 
677
                return _VisibilityPointB;
 
678
        }
 
679
#endif
 
680
 
 
681
        inline const Polygon3r& aFace() const
 
682
        {
 
683
                return _aFace;
 
684
        }
 
685
 
 
686
        inline const Vec3r& getOccludeeIntersection()
 
687
        {
 
688
                return _occludeeIntersection;
 
689
        }
 
690
 
 
691
        inline bool getOccludeeEmpty()
 
692
        {
 
693
                return _occludeeEmpty;
 
694
        }
 
695
 
 
696
        /*! Returns true if this FEdge is a smooth FEdge. */
 
697
        inline bool isSmooth() const
 
698
        {
 
699
                return _isSmooth;
 
700
        }
 
701
 
 
702
        inline bool isInImage () const
 
703
        {
 
704
                return _isInImage;
 
705
        }
 
706
 
 
707
        /* modifiers */
 
708
        /*! Sets the first SVertex. */
 
709
        inline void setVertexA(SVertex *vA)
 
710
        {
 
711
                _VertexA = vA;
 
712
        }
 
713
 
 
714
        /*! Sets the second SVertex. */
 
715
        inline void setVertexB(SVertex *vB)
 
716
        {
 
717
                _VertexB = vB;
 
718
        }
 
719
 
 
720
        /*! Sets the FEdge Id . */
 
721
        inline void setId(const Id& id)
 
722
        {
 
723
                _Id = id;
 
724
        }
 
725
 
 
726
        /*! Sets the pointer to the next FEdge. */
 
727
        inline void setNextEdge(FEdge *iEdge)
 
728
        {
 
729
                _NextEdge = iEdge;
 
730
        }
 
731
 
 
732
        /*! Sets the pointer to the previous FEdge. */
 
733
        inline void setPreviousEdge(FEdge *iEdge)
 
734
        {
 
735
                _PreviousEdge = iEdge;
 
736
        }
 
737
 
 
738
        /*! Sets the nature of this FEdge. */
 
739
        inline void setNature(Nature::EdgeNature iNature)
 
740
        {
 
741
                _Nature = iNature;
 
742
        }
 
743
 
 
744
#if 0
 
745
        inline void AddOccluder(Polygon3r& iPolygon)
 
746
        {
 
747
                _Occluders.push_back(iPolygon);
 
748
        }
 
749
#endif
 
750
 
 
751
        /*! Sets the ViewEdge to which this FEdge belongs to. */
 
752
        inline void setViewEdge(ViewEdge *iViewEdge)
 
753
        {
 
754
                _ViewEdge = iViewEdge;
 
755
        }
 
756
 
 
757
#if 0
 
758
        inline void setHasVisibilityPoint(bool iBool)
 
759
        {
 
760
                _hasVisibilityPoint = iBool;
 
761
        }
 
762
 
 
763
        inline void setVisibilityPointA(const Vec3r& iPoint)
 
764
        {
 
765
                _VisibilityPointA = iPoint;
 
766
        }
 
767
 
 
768
        inline void setVisibilityPointB(const Vec3r& iPoint)
 
769
        {
 
770
                _VisibilityPointB = iPoint;
 
771
        }
 
772
#endif
 
773
 
 
774
        inline void setaFace(Polygon3r& iFace)
 
775
        {
 
776
                _aFace = iFace;
 
777
        }
 
778
 
 
779
        inline void setOccludeeIntersection(const Vec3r& iPoint)
 
780
        {
 
781
                _occludeeIntersection = iPoint;
 
782
        }
 
783
 
 
784
        inline void setOccludeeEmpty(bool iempty)
 
785
        {
 
786
                _occludeeEmpty = iempty;
 
787
        }
 
788
 
 
789
        /*! Sets the flag telling whether this FEdge is smooth or sharp.
 
790
         *  true for Smooth, false for Sharp.
 
791
         */
 
792
        inline void setSmooth(bool iFlag)
 
793
        {
 
794
                _isSmooth = iFlag;
 
795
        }
 
796
 
 
797
        inline void setIsInImage (bool iFlag)
 
798
        {
 
799
                _isInImage = iFlag;
 
800
        }
 
801
 
 
802
        /* checks whether two FEdge have a common vertex.
 
803
         *  Returns a pointer on the common vertex if it exists, NULL otherwise.
 
804
         */
 
805
        static inline SVertex *CommonVertex(FEdge *iEdge1, FEdge *iEdge2)
 
806
        {
 
807
                if ((NULL == iEdge1) || (NULL == iEdge2))
 
808
                        return NULL;
 
809
 
 
810
                SVertex *sv1 = iEdge1->vertexA();
 
811
                SVertex *sv2 = iEdge1->vertexB();
 
812
                SVertex *sv3 = iEdge2->vertexA();
 
813
                SVertex *sv4 = iEdge2->vertexB();
 
814
 
 
815
                if ((sv1 == sv3) || (sv1 == sv4)) {
 
816
                        return sv1;
 
817
                }
 
818
                else if ((sv2 == sv3) || (sv2 == sv4)) {
 
819
                        return sv2;
 
820
                }
 
821
 
 
822
                return NULL;
 
823
        }
 
824
 
 
825
        inline const SVertex *min2d() const
 
826
        {
 
827
                if (_VertexA->point2D() < _VertexB->point2D())
 
828
                        return _VertexA;
 
829
                else
 
830
                        return _VertexB;
 
831
        }
 
832
 
 
833
        inline const SVertex *max2d() const
 
834
        {
 
835
                if (_VertexA->point2D() < _VertexB->point2D())
 
836
                        return _VertexB;
 
837
                else
 
838
                        return _VertexA;
 
839
        }
 
840
 
 
841
        /* Information access interface */
 
842
 
 
843
        //Material material() const;
 
844
        Id shape_id() const;
 
845
        const SShape *shape() const;
 
846
        float shape_importance() const;
 
847
 
 
848
        inline const int qi() const
 
849
        {
 
850
                return invisibility();
 
851
        }
 
852
 
 
853
        occluder_container::const_iterator occluders_begin() const;
 
854
        occluder_container::const_iterator occluders_end() const;
 
855
        bool occluders_empty() const;
 
856
        int occluders_size() const;
 
857
 
 
858
        inline const Polygon3r& occludee() const
 
859
        {
 
860
                return aFace();
 
861
        }
 
862
 
 
863
        const SShape *occluded_shape() const;
 
864
 
 
865
#if 0
 
866
        inline const bool  occludee_empty() const
 
867
        {
 
868
                return _occludeeEmpty;
 
869
        }
 
870
#endif
 
871
 
 
872
        const bool  occludee_empty() const;
 
873
        real z_discontinuity() const;
 
874
 
 
875
#if 0
 
876
        inline float local_average_depth(int iCombination = 0) const;
 
877
        inline float local_depth_variance(int iCombination = 0) const;
 
878
        inline real local_average_density(float sigma = 2.3f, int iCombination = 0) const;
 
879
        inline Vec3r shaded_color(int iCombination = 0) const {}
 
880
#endif
 
881
 
 
882
        int viewedge_nature() const;
 
883
 
 
884
        //float viewedge_length() const;
 
885
 
 
886
        inline Vec3r orientation2d() const
 
887
        {
 
888
                return Vec3r(_VertexB->point2d() - _VertexA->point2d());
 
889
        }
 
890
 
 
891
        inline Vec3r orientation3d() const
 
892
        {
 
893
                return Vec3r(_VertexB->point3d() - _VertexA->point3d());
 
894
        }
 
895
 
 
896
#if 0
 
897
        inline real curvature2d() const
 
898
        {
 
899
                return viewedge()->curvature2d((_VertexA->point2d() + _VertexB->point2d()) / 2.0);
 
900
        }
 
901
 
 
902
        inline Vec3r curvature2d_as_vector(int iCombination = 0) const;
 
903
 
 
904
        /* angle in degrees*/
 
905
        inline real curvature2d_as_angle(int iCombination = 0) const;
 
906
#endif
 
907
 
 
908
        // Iterator access (Interface1D)
 
909
        /*! Returns an iterator over the 2 (!) SVertex pointing to the first SVertex. */
 
910
        virtual inline Interface0DIterator verticesBegin();
 
911
 
 
912
        /*! Returns an iterator over the 2 (!) SVertex pointing after the last SVertex. */
 
913
        virtual inline Interface0DIterator verticesEnd();
 
914
 
 
915
        /*! Returns an iterator over the FEdge points, pointing to the first point. The difference with verticesBegin()
 
916
         *  is that here we can iterate over points of the FEdge at a any given sampling.
 
917
         *  Indeed, for each iteration, a virtual point is created.
 
918
         *  \param t
 
919
         *    The sampling with which we want to iterate over points of this FEdge.
 
920
         */
 
921
        virtual inline Interface0DIterator pointsBegin(float t = 0.0f);
 
922
 
 
923
        /*! Returns an iterator over the FEdge points, pointing after the last point. The difference with verticesEnd()
 
924
         * is that here we can iterate over points of the FEdge at a any given sampling.
 
925
         *  Indeed, for each iteration, a virtual point is created.
 
926
         *  \param t
 
927
         *    The sampling with which we want to iterate over points of this FEdge.
 
928
         */
 
929
        virtual inline Interface0DIterator pointsEnd(float t = 0.0f);
 
930
};
 
931
 
 
932
//
 
933
// SVertexIterator
 
934
//
 
935
/////////////////////////////////////////////////
 
936
 
 
937
namespace FEdgeInternal {
 
938
 
 
939
class SVertexIterator : public Interface0DIteratorNested
 
940
{
 
941
public:
 
942
        SVertexIterator()
 
943
        {
 
944
                _vertex = NULL;
 
945
                _edge = NULL;
 
946
        }
 
947
 
 
948
        SVertexIterator(const SVertexIterator& vi)
 
949
        {
 
950
                _vertex = vi._vertex;
 
951
                _edge = vi._edge;
 
952
        }
 
953
 
 
954
        SVertexIterator(SVertex *v, FEdge *edge)
 
955
        {
 
956
                _vertex = v;
 
957
                _edge = edge;
 
958
        }
 
959
 
 
960
        SVertexIterator& operator=(const SVertexIterator& vi)
 
961
        {
 
962
                _vertex = vi._vertex;
 
963
                _edge = vi._edge;
 
964
                return *this;
 
965
        }
 
966
 
 
967
        virtual string getExactTypeName() const
 
968
        {
 
969
                return "SVertexIterator";
 
970
        }
 
971
 
 
972
        virtual SVertex& operator*()
 
973
        {
 
974
                return *_vertex;
 
975
        }
 
976
 
 
977
        virtual SVertex *operator->()
 
978
        {
 
979
                return &(operator*());
 
980
        }
 
981
 
 
982
        virtual SVertexIterator& operator++()
 
983
        {
 
984
                increment();
 
985
                return *this;
 
986
        }
 
987
 
 
988
        virtual SVertexIterator operator++(int)
 
989
        {
 
990
                SVertexIterator ret(*this);
 
991
                increment();
 
992
                return ret;
 
993
        }
 
994
 
 
995
        virtual SVertexIterator& operator--()
 
996
        {
 
997
                decrement();
 
998
                return *this;
 
999
        }
 
1000
 
 
1001
        virtual SVertexIterator operator--(int)
 
1002
        {
 
1003
                SVertexIterator ret(*this);
 
1004
                decrement();
 
1005
                return ret;
 
1006
        }
 
1007
 
 
1008
        virtual int increment()
 
1009
        {
 
1010
                if (_vertex == _edge->vertexB()) {
 
1011
                        _vertex = 0;
 
1012
                        return 0;
 
1013
                }
 
1014
                _vertex = _edge->vertexB();
 
1015
                return 0;
 
1016
        }
 
1017
 
 
1018
        virtual int decrement()
 
1019
        {
 
1020
                if (_vertex == _edge->vertexA()) {
 
1021
                        _vertex = 0;
 
1022
                        return 0;
 
1023
                }
 
1024
                _vertex = _edge->vertexA();
 
1025
                return 0;
 
1026
        }
 
1027
 
 
1028
        virtual bool isBegin() const
 
1029
        {
 
1030
                return _vertex == _edge->vertexA();
 
1031
        }
 
1032
 
 
1033
        virtual bool isEnd() const
 
1034
        {
 
1035
                return _vertex == _edge->vertexB();
 
1036
        }
 
1037
 
 
1038
        virtual bool operator==(const Interface0DIteratorNested& it) const
 
1039
        {
 
1040
                const SVertexIterator *it_exact = dynamic_cast<const SVertexIterator*>(&it);
 
1041
                if (!it_exact)
 
1042
                        return false;
 
1043
                return ((_vertex == it_exact->_vertex) && (_edge == it_exact->_edge));
 
1044
        }
 
1045
 
 
1046
        virtual float t() const
 
1047
        {
 
1048
                if (_vertex == _edge->vertexA()) {
 
1049
                        return 0.0f;
 
1050
                }
 
1051
                return ((float)_edge->getLength2D());
 
1052
        }
 
1053
        virtual float u() const
 
1054
        {
 
1055
                if (_vertex == _edge->vertexA()) {
 
1056
                        return 0.0f;
 
1057
                }
 
1058
                return 1.0f;
 
1059
        }
 
1060
 
 
1061
        virtual SVertexIterator *copy() const
 
1062
        {
 
1063
                return new SVertexIterator(*this);
 
1064
        }
 
1065
 
 
1066
private:
 
1067
        SVertex *_vertex;
 
1068
        FEdge *_edge;
 
1069
};
 
1070
 
 
1071
} // end of namespace FEdgeInternal
 
1072
 
 
1073
// Iterator access (implementation)
 
1074
 
 
1075
Interface0DIterator FEdge::verticesBegin()
 
1076
{
 
1077
        Interface0DIterator ret(new FEdgeInternal::SVertexIterator(_VertexA, this));
 
1078
        return ret;
 
1079
}
 
1080
 
 
1081
Interface0DIterator FEdge::verticesEnd()
 
1082
{
 
1083
        Interface0DIterator ret(new FEdgeInternal::SVertexIterator(0, this));
 
1084
        return ret;
 
1085
}
 
1086
 
 
1087
Interface0DIterator FEdge::pointsBegin(float t)
 
1088
{
 
1089
        return verticesBegin();
 
1090
}
 
1091
 
 
1092
Interface0DIterator FEdge::pointsEnd(float t)
 
1093
{
 
1094
        return verticesEnd();
 
1095
}
 
1096
 
 
1097
/*! Class defining a sharp FEdge. A Sharp FEdge corresponds to an initial edge of the input mesh.
 
1098
 *  It can be a silhouette, a crease or a border. If it is a crease edge, then it is borded
 
1099
 *  by two faces of the mesh. Face a lies on its right whereas Face b lies on its left.
 
1100
 *  If it is a border edge, then it doesn't have any face on its right, and thus Face a = 0.
 
1101
 */
 
1102
class LIB_VIEW_MAP_EXPORT FEdgeSharp : public FEdge
 
1103
{
 
1104
protected:
 
1105
        Vec3r _aNormal; // When following the edge, normal of the right face
 
1106
        Vec3r _bNormal; // When following the edge, normal of the left face
 
1107
        unsigned _aFrsMaterialIndex;
 
1108
        unsigned _bFrsMaterialIndex;
 
1109
        bool _aFaceMark;
 
1110
        bool _bFaceMark;
 
1111
 
 
1112
public:
 
1113
        /*! Returns the string "FEdgeSharp" . */
 
1114
        virtual string getExactTypeName() const
 
1115
        {
 
1116
                return "FEdgeSharp";
 
1117
        }
 
1118
 
 
1119
        /*! Default constructor. */
 
1120
        inline FEdgeSharp() : FEdge()
 
1121
        {
 
1122
                _aFrsMaterialIndex = _bFrsMaterialIndex = 0;
 
1123
                _aFaceMark = _bFaceMark = false;
 
1124
        }
 
1125
 
 
1126
        /*! Builds an FEdgeSharp going from vA to vB. */
 
1127
        inline FEdgeSharp(SVertex *vA, SVertex *vB) : FEdge(vA, vB)
 
1128
        {
 
1129
                _aFrsMaterialIndex = _bFrsMaterialIndex = 0;
 
1130
                _aFaceMark = _bFaceMark = false;
 
1131
        }
 
1132
 
 
1133
        /*! Copy constructor. */
 
1134
        inline FEdgeSharp(FEdgeSharp& iBrother) : FEdge(iBrother)
 
1135
        {
 
1136
                _aNormal = iBrother._aNormal;
 
1137
                _bNormal = iBrother._bNormal;
 
1138
                _aFrsMaterialIndex = iBrother._aFrsMaterialIndex;
 
1139
                _bFrsMaterialIndex = iBrother._bFrsMaterialIndex;
 
1140
                _aFaceMark = iBrother._aFaceMark;
 
1141
                _bFaceMark = iBrother._bFaceMark;
 
1142
        }
 
1143
 
 
1144
        /*! Destructor. */
 
1145
        virtual ~FEdgeSharp() {}
 
1146
 
 
1147
        /*! Cloning method. */
 
1148
        virtual FEdge *duplicate()
 
1149
        {
 
1150
                FEdge *clone = new FEdgeSharp(*this);
 
1151
                return clone;
 
1152
        }
 
1153
 
 
1154
        /*! Returns the normal to the face lying on the right of the FEdge. If this FEdge is a border,
 
1155
         *  it has no Face on its right and therefore, no normal.
 
1156
         */
 
1157
        inline const Vec3r& normalA()
 
1158
        {
 
1159
                return _aNormal;
 
1160
        }
 
1161
 
 
1162
        /*! Returns the normal to the face lying on the left of the FEdge. */
 
1163
        inline const Vec3r& normalB()
 
1164
        {
 
1165
                return _bNormal;
 
1166
        }
 
1167
 
 
1168
        /*! Returns the index of the material of the face lying on the
 
1169
        *  right of the FEdge. If this FEdge is a border,
 
1170
        *  it has no Face on its right and therefore, no material.
 
1171
        */
 
1172
        inline unsigned aFrsMaterialIndex() const
 
1173
        {
 
1174
                return _aFrsMaterialIndex;
 
1175
        }
 
1176
 
 
1177
        /*! Returns the material of the face lying on the right of the FEdge. If this FEdge is a border,
 
1178
         *  it has no Face on its right and therefore, no material.
 
1179
         */
 
1180
        const FrsMaterial& aFrsMaterial() const;
 
1181
 
 
1182
        /*! Returns the index of the material of the face lying on the left of the FEdge. */
 
1183
        inline unsigned bFrsMaterialIndex() const
 
1184
        {
 
1185
                return _bFrsMaterialIndex;
 
1186
        }
 
1187
 
 
1188
        /*! Returns the  material of the face lying on the left of the FEdge. */
 
1189
        const FrsMaterial& bFrsMaterial() const;
 
1190
 
 
1191
        /*! Returns the face mark of the face lying on the right of the FEdge.
 
1192
         *  If this FEdge is a border, it has no Face on its right and thus false is returned.
 
1193
         */
 
1194
        inline bool aFaceMark() const
 
1195
        {
 
1196
                return _aFaceMark;
 
1197
        }
 
1198
 
 
1199
        /*! Returns the face mark of the face lying on the left of the FEdge. */
 
1200
        inline bool bFaceMark() const
 
1201
        {
 
1202
                return _bFaceMark;
 
1203
        }
 
1204
 
 
1205
        /*! Sets the normal to the face lying on the right of the FEdge. */
 
1206
        inline void setNormalA(const Vec3r& iNormal)
 
1207
        {
 
1208
                _aNormal = iNormal;
 
1209
        }
 
1210
 
 
1211
        /*! Sets the normal to the face lying on the left of the FEdge. */
 
1212
        inline void setNormalB(const Vec3r& iNormal)
 
1213
        {
 
1214
                _bNormal = iNormal;
 
1215
        }
 
1216
 
 
1217
        /*! Sets the index of the material lying on the right of the FEdge.*/
 
1218
        inline void setaFrsMaterialIndex(unsigned i)
 
1219
        {
 
1220
                _aFrsMaterialIndex = i;
 
1221
        }
 
1222
 
 
1223
        /*! Sets the index of the material lying on the left of the FEdge.*/
 
1224
        inline void setbFrsMaterialIndex(unsigned i)
 
1225
        {
 
1226
                _bFrsMaterialIndex = i;
 
1227
        }
 
1228
 
 
1229
        /*! Sets the face mark of the face lying on the right of the FEdge. */
 
1230
        inline void setaFaceMark(bool iFaceMark)
 
1231
        {
 
1232
                _aFaceMark = iFaceMark;
 
1233
        }
 
1234
 
 
1235
        /*! Sets the face mark of the face lying on the left of the FEdge. */
 
1236
        inline void setbFaceMark(bool iFaceMark)
 
1237
        {
 
1238
                _bFaceMark = iFaceMark;
 
1239
        }
 
1240
};
 
1241
 
 
1242
/*! Class defining a smooth edge. This kind of edge typically runs across a face of the input mesh. It can be
 
1243
 *  a silhouette, a ridge or valley, a suggestive contour.
 
1244
 */
 
1245
class LIB_VIEW_MAP_EXPORT FEdgeSmooth : public FEdge
 
1246
{
 
1247
protected:
 
1248
        Vec3r _Normal;
 
1249
        unsigned _FrsMaterialIndex;
 
1250
#if 0
 
1251
        bool _hasVisibilityPoint;
 
1252
        Vec3r _VisibilityPointA;  // The edge on which the visibility will be computed represented 
 
1253
        Vec3r _VisibilityPointB;  // using its 2 extremity points A and B
 
1254
#endif
 
1255
        void *_Face; // In case of exact silhouette, Face is the WFace crossed by Fedge 
 
1256
                      // NOT HANDLED BY THE COPY CONSTRUCTEUR
 
1257
        bool _FaceMark;
 
1258
 
 
1259
public:
 
1260
        /*! Returns the string "FEdgeSmooth" . */
 
1261
        virtual string getExactTypeName() const
 
1262
        {
 
1263
                return "FEdgeSmooth";
 
1264
        }
 
1265
 
 
1266
        /*! Default constructor. */
 
1267
        inline FEdgeSmooth() : FEdge()
 
1268
        {
 
1269
                _Face = NULL;
 
1270
                _FaceMark = false;
 
1271
                _FrsMaterialIndex = 0;
 
1272
                _isSmooth = true;
 
1273
        }
 
1274
 
 
1275
        /*! Builds an FEdgeSmooth going from vA to vB. */
 
1276
        inline FEdgeSmooth(SVertex *vA, SVertex *vB) : FEdge(vA, vB)
 
1277
        {
 
1278
                _Face = NULL;
 
1279
                _FaceMark = false;
 
1280
                _FrsMaterialIndex = 0;
 
1281
                _isSmooth = true;
 
1282
        }
 
1283
 
 
1284
        /*! Copy constructor. */
 
1285
        inline FEdgeSmooth(FEdgeSmooth& iBrother) : FEdge(iBrother)
 
1286
        {
 
1287
                _Normal = iBrother._Normal;
 
1288
                _Face = iBrother._Face;
 
1289
                _FaceMark = iBrother._FaceMark;
 
1290
                _FrsMaterialIndex = iBrother._FrsMaterialIndex;
 
1291
                _isSmooth = true;
 
1292
        }
 
1293
 
 
1294
        /*! Destructor. */
 
1295
        virtual ~FEdgeSmooth() {}
 
1296
 
 
1297
        /*! Cloning method. */
 
1298
        virtual FEdge *duplicate()
 
1299
        {
 
1300
                FEdge *clone = new FEdgeSmooth(*this);
 
1301
                return clone;
 
1302
        }
 
1303
 
 
1304
        inline void *face() const
 
1305
        {
 
1306
                return _Face;
 
1307
        }
 
1308
 
 
1309
        /*! Returns the face mark of the face it is running across. */
 
1310
        inline bool faceMark() const
 
1311
        {
 
1312
                return _FaceMark;
 
1313
        }
 
1314
 
 
1315
        /*! Returns the normal to the Face it is running accross. */
 
1316
        inline const Vec3r& normal()
 
1317
        {
 
1318
                return _Normal;
 
1319
        }
 
1320
 
 
1321
        /*! Returns the index of the material of the face it is running accross. */
 
1322
        inline unsigned frs_materialIndex() const
 
1323
        {
 
1324
                return _FrsMaterialIndex;
 
1325
        }
 
1326
 
 
1327
        /*! Returns the material of the face it is running accross. */
 
1328
        const FrsMaterial& frs_material() const;
 
1329
 
 
1330
        inline void setFace(void *iFace)
 
1331
        {
 
1332
                _Face = iFace;
 
1333
        }
 
1334
 
 
1335
        /*! Sets the face mark of the face it is running across. */
 
1336
        inline void setFaceMark(bool iFaceMark)
 
1337
        {
 
1338
                _FaceMark = iFaceMark;
 
1339
        }
 
1340
 
 
1341
        /*! Sets the normal to the Face it is running accross. */
 
1342
        inline void setNormal(const Vec3r& iNormal)
 
1343
        {
 
1344
                _Normal = iNormal;
 
1345
        }
 
1346
 
 
1347
        /*! Sets the index of the material of the face it is running accross. */
 
1348
        inline void setFrsMaterialIndex(unsigned i)
 
1349
        {
 
1350
                _FrsMaterialIndex = i;
 
1351
        }
 
1352
};
 
1353
 
 
1354
 
 
1355
/**********************************/
 
1356
/*                                */
 
1357
/*                                */
 
1358
/*             SShape             */
 
1359
/*                                */
 
1360
/*                                */
 
1361
/**********************************/
 
1362
 
 
1363
 
 
1364
/*! Class to define a feature shape. It is the gathering of feature elements from an identified input shape */
 
1365
class LIB_VIEW_MAP_EXPORT SShape
 
1366
{
 
1367
private:
 
1368
        vector<FEdge*> _chains;          // list of fedges that are chains starting points.
 
1369
        vector<SVertex*> _verticesList;  // list of all vertices
 
1370
        vector<FEdge*> _edgesList;       // list of all edges
 
1371
        Id _Id;
 
1372
        string _Name;
 
1373
        BBox<Vec3r> _BBox;
 
1374
        vector<FrsMaterial> _FrsMaterials;  
 
1375
 
 
1376
        float _importance;
 
1377
 
 
1378
        ViewShape *_ViewShape;
 
1379
 
 
1380
public:
 
1381
        /*! A field that can be used by the user to store any data.
 
1382
         *  This field must be reseted afterwards using ResetUserData().
 
1383
         */
 
1384
        void *userdata; // added by E.T.
 
1385
 
 
1386
        /*! Default constructor */
 
1387
        inline SShape()
 
1388
        {
 
1389
                userdata = NULL;
 
1390
                _importance = 0.0f;
 
1391
                _ViewShape = NULL;
 
1392
        }
 
1393
 
 
1394
        /*! Copy constructor */
 
1395
        inline SShape(SShape& iBrother)
 
1396
        {
 
1397
                userdata = NULL;
 
1398
                _Id = iBrother._Id;
 
1399
                _Name = iBrother._Name;
 
1400
                _BBox = iBrother.bbox();
 
1401
                _FrsMaterials = iBrother._FrsMaterials;
 
1402
                _importance = iBrother._importance;
 
1403
                _ViewShape = iBrother._ViewShape;
 
1404
 
 
1405
                //---------
 
1406
                // vertices
 
1407
                //---------
 
1408
                vector<SVertex*>::iterator sv, svend;
 
1409
                vector<SVertex*>& verticesList = iBrother.getVertexList();
 
1410
                for (sv = verticesList.begin(), svend = verticesList.end(); sv != svend; sv++) {
 
1411
                        SVertex *newv = new SVertex(*(*sv));
 
1412
                        newv->setShape(this);
 
1413
                        _verticesList.push_back(newv);
 
1414
                }
 
1415
 
 
1416
                //------
 
1417
                // edges
 
1418
                //------
 
1419
                vector<FEdge*>::iterator e, eend;
 
1420
                vector<FEdge*>& edgesList = iBrother.getEdgeList();
 
1421
                for (e = edgesList.begin(), eend = edgesList.end(); e != eend; e++) {
 
1422
                        FEdge *newe = (*e)->duplicate();
 
1423
                        _edgesList.push_back(newe);
 
1424
                }
 
1425
 
 
1426
                //-------------------------
 
1427
                // starting chain edges
 
1428
                //-------------------------
 
1429
                vector<FEdge*>::iterator fe, fend;
 
1430
                vector<FEdge*>& fedges = iBrother.getChains();
 
1431
                for (fe = fedges.begin(), fend = fedges.end(); fe != fend; fe++) {
 
1432
                        _chains.push_back((FEdge *)((*fe)->userdata));
 
1433
                }
 
1434
 
 
1435
                //-------------------------
 
1436
                // remap edges in vertices:
 
1437
                //-------------------------
 
1438
                for (sv = _verticesList.begin(), svend = _verticesList.end(); sv != svend; sv++) {
 
1439
                        const vector<FEdge*>& fedgeList = (*sv)->fedges();
 
1440
                        vector<FEdge*> newfedgelist;
 
1441
                        for (vector<FEdge*>::const_iterator fed = fedgeList.begin(), fedend = fedgeList.end();
 
1442
                             fed != fedend;
 
1443
                             fed++)
 
1444
                        {
 
1445
                                FEdge *current = *fed;
 
1446
                                newfedgelist.push_back((FEdge *)current->userdata);
 
1447
                        }
 
1448
                        (*sv)->setFEdges(newfedgelist);
 
1449
                }
 
1450
 
 
1451
                //-------------------------------------
 
1452
                // remap vertices and nextedge in edges:
 
1453
                //-------------------------------------
 
1454
                for (e = _edgesList.begin(), eend = _edgesList.end(); e != eend; e++) {
 
1455
                        (*e)->setVertexA((SVertex *)((*e)->vertexA()->userdata));
 
1456
                        (*e)->setVertexB((SVertex *)((*e)->vertexB()->userdata));
 
1457
                        (*e)->setNextEdge((FEdge *)((*e)->nextEdge()->userdata));
 
1458
                        (*e)->setPreviousEdge((FEdge *)((*e)->previousEdge()->userdata));
 
1459
                }
 
1460
 
 
1461
                // reset all brothers userdata to NULL:
 
1462
                //-------------------------------------
 
1463
                //---------
 
1464
                // vertices
 
1465
                //---------
 
1466
                for (sv = _verticesList.begin(), svend = _verticesList.end(); sv != svend; sv++) {
 
1467
                        (*sv)->userdata = NULL;
 
1468
                }
 
1469
 
 
1470
                //------
 
1471
                // edges
 
1472
                //------
 
1473
                for (e = _edgesList.begin(), eend = _edgesList.end(); e != eend; e++) {
 
1474
                        (*e)->userdata = NULL;
 
1475
                }
 
1476
        }
 
1477
 
 
1478
        /*! Cloning method. */
 
1479
        virtual SShape *duplicate()
 
1480
        {
 
1481
                SShape *clone = new SShape(*this);
 
1482
                return clone;
 
1483
        }
 
1484
 
 
1485
        /*! Destructor. */
 
1486
        virtual inline ~SShape()
 
1487
        {
 
1488
                vector<SVertex*>::iterator sv, svend;
 
1489
                vector<FEdge*>::iterator e, eend;
 
1490
                if (0 != _verticesList.size()) {
 
1491
                        for (sv = _verticesList.begin(), svend = _verticesList.end(); sv != svend; sv++) {
 
1492
                                delete (*sv);
 
1493
                        }
 
1494
                        _verticesList.clear();
 
1495
                }
 
1496
 
 
1497
                if (0 != _edgesList.size()) {
 
1498
                        for (e = _edgesList.begin(), eend = _edgesList.end(); e != eend; e++) {
 
1499
                                delete (*e);
 
1500
                        }
 
1501
                        _edgesList.clear();
 
1502
                }
 
1503
 
 
1504
                //! Clear the chains list
 
1505
                //-----------------------
 
1506
                if (0 != _chains.size()) {
 
1507
                        _chains.clear();
 
1508
                }
 
1509
        }
 
1510
 
 
1511
        /*! Adds a FEdge to the list of FEdges. */
 
1512
        inline void AddEdge(FEdge *iEdge)
 
1513
        {
 
1514
                _edgesList.push_back(iEdge);
 
1515
        }
 
1516
 
 
1517
        /*! Adds a SVertex to the list of SVertex of this Shape.
 
1518
         * The SShape attribute of the SVertex is also set to 'this'.
 
1519
         */
 
1520
        inline void AddNewVertex(SVertex *iv)
 
1521
        {
 
1522
                iv->setShape(this);
 
1523
                _verticesList.push_back(iv);
 
1524
        }
 
1525
 
 
1526
        inline void AddChain(FEdge *iEdge)
 
1527
        {
 
1528
                _chains.push_back(iEdge);
 
1529
        }
 
1530
 
 
1531
        inline SVertex *CreateSVertex(const Vec3r& P3D, const Vec3r& P2D, const Id& id)
 
1532
        {
 
1533
                SVertex *Ia = new SVertex(P3D, id);
 
1534
                Ia->setPoint2D(P2D);
 
1535
                AddNewVertex(Ia);
 
1536
                return Ia;
 
1537
        }
 
1538
 
 
1539
        /*! Splits an edge into several edges.
 
1540
         *  The edge's vertices are passed rather than the edge itself. This way, all feature edges (SILHOUETTE,
 
1541
         *  CREASE, BORDER) are splitted in the same time.
 
1542
         *  The processed edges are flagged as done (using the userdata flag).One single new vertex is created whereas
 
1543
         *  several splitted edges might created for the different kinds of edges. These new elements are added to the lists
 
1544
         *  maintained by the shape.
 
1545
         *  New chains are also created.
 
1546
         *    ioA
 
1547
         *      The first vertex for the edge that gets splitted
 
1548
         *    ioB
 
1549
         *      The second vertex for the edge that gets splitted
 
1550
         *    iParameters
 
1551
         *      A vector containing 2D real vectors indicating the parameters giving the intersections coordinates in
 
1552
         *      3D and in 2D. These intersections points must be sorted from B to A.
 
1553
         *      Each parameter defines the intersection point I as I=A+T*AB. T<0 and T>1 are then incorrect insofar as
 
1554
         *      they give intersections points that lie outside the segment.
 
1555
         *    ioNewEdges
 
1556
         *      The edges that are newly created (the initial edges are not included) are added to this list.
 
1557
         */
 
1558
        inline void SplitEdge(FEdge *fe, const vector<Vec2r>& iParameters, vector<FEdge*>& ioNewEdges)
 
1559
        {
 
1560
                SVertex *ioA = fe->vertexA();
 
1561
                SVertex *ioB = fe->vertexB();
 
1562
                Vec3r A = ioA->point3D();
 
1563
                Vec3r B = ioB->point3D();
 
1564
                Vec3r a = ioA->point2D();
 
1565
                Vec3r b = ioB->point2D();
 
1566
 
 
1567
                Vec3r newpoint3d, newpoint2d;
 
1568
                vector<SVertex*> intersections;
 
1569
                real t, T;
 
1570
                for (vector<Vec2r>::const_iterator p = iParameters.begin(), pend = iParameters.end(); p != pend; p++) {
 
1571
                        T = (*p)[0];
 
1572
                        t = (*p)[1];
 
1573
 
 
1574
                        if ((t < 0) || (t > 1))
 
1575
                                cerr << "Warning: Intersection out of range for edge " << ioA->getId() << " - " << ioB->getId() << endl;
 
1576
 
 
1577
                        // compute the 3D and 2D coordinates for the intersections points:
 
1578
                        newpoint3d = Vec3r(A + T * (B - A));
 
1579
                        newpoint2d = Vec3r(a + t * (b - a));
 
1580
 
 
1581
                        // create new SVertex:
 
1582
                        // (we keep B's id)
 
1583
                        SVertex *newVertex = new SVertex(newpoint3d, ioB->getId());
 
1584
                        newVertex->setPoint2D(newpoint2d);
 
1585
 
 
1586
                        // Add this vertex to the intersections list:
 
1587
                        intersections.push_back(newVertex);
 
1588
 
 
1589
                        // Add this vertex to this sshape:
 
1590
                        AddNewVertex(newVertex);
 
1591
                }
 
1592
 
 
1593
                for (vector<SVertex*>::iterator sv = intersections.begin(), svend = intersections.end(); sv != svend; sv++) {
 
1594
                        //SVertex *svA = fe->vertexA();
 
1595
                        SVertex *svB = fe->vertexB();
 
1596
 
 
1597
                        // We split edge AB into AA' and A'B. A' and A'B are created.
 
1598
                        // AB becomes (address speaking) AA'. B is updated.
 
1599
                        //--------------------------------------------------
 
1600
                        // The edge AB becomes edge AA'.
 
1601
                        (fe)->setVertexB((*sv));
 
1602
                        // a new edge, A'B is created.
 
1603
                        FEdge *newEdge;
 
1604
                        if (fe->isSmooth()) {
 
1605
                                newEdge = new FEdgeSmooth((*sv), svB);
 
1606
                                FEdgeSmooth *se = dynamic_cast<FEdgeSmooth*>(newEdge);
 
1607
                                FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth*>(fe);
 
1608
                                se->setFrsMaterialIndex(fes->frs_materialIndex());
 
1609
                        }
 
1610
                        else {
 
1611
                                newEdge = new FEdgeSharp((*sv), svB);
 
1612
                                FEdgeSharp *se = dynamic_cast<FEdgeSharp*>(newEdge);
 
1613
                                FEdgeSharp *fes = dynamic_cast<FEdgeSharp*>(fe);
 
1614
                                se->setaFrsMaterialIndex(fes->aFrsMaterialIndex());
 
1615
                                se->setbFrsMaterialIndex(fes->bFrsMaterialIndex());
 
1616
                        }
 
1617
 
 
1618
                        newEdge->setNature((fe)->getNature());
 
1619
 
 
1620
                        // to build a new chain:
 
1621
                        AddChain(newEdge);
 
1622
                        // add the new edge to the sshape edges list.
 
1623
                        AddEdge(newEdge);
 
1624
                        // add new edge to the list of new edges passed as argument:
 
1625
                        ioNewEdges.push_back(newEdge);
 
1626
 
 
1627
                        // update edge A'B for the next pointing edge
 
1628
                        newEdge->setNextEdge((fe)->nextEdge());
 
1629
                        fe->nextEdge()->setPreviousEdge(newEdge);
 
1630
                        Id id(fe->getId().getFirst(), fe->getId().getSecond() + 1);
 
1631
                        newEdge->setId(fe->getId());
 
1632
                        fe->setId(id);
 
1633
 
 
1634
                        // update edge AA' for the next pointing edge
 
1635
                        //ioEdge->setNextEdge(newEdge);
 
1636
                        (fe)->setNextEdge(NULL);
 
1637
 
 
1638
                        // update vertex pointing edges list:
 
1639
                        // -- vertex B --
 
1640
                        svB->Replace((fe), newEdge);
 
1641
                        // -- vertex A' --
 
1642
                        (*sv)->AddFEdge((fe));
 
1643
                        (*sv)->AddFEdge(newEdge);
 
1644
                }
 
1645
        }
 
1646
 
 
1647
        /* splits an edge into 2 edges. The new vertex and edge are added to the sshape list of vertices and edges
 
1648
         *  a new chain is also created.
 
1649
         *  returns the new edge.
 
1650
         *    ioEdge
 
1651
         *      The edge that gets splitted
 
1652
         *    newpoint
 
1653
         *      x,y,z coordinates of the new point.
 
1654
         */
 
1655
        inline FEdge *SplitEdgeIn2(FEdge *ioEdge, SVertex *ioNewVertex)
 
1656
        {
 
1657
                //soc unused - SVertex *A = ioEdge->vertexA();
 
1658
                SVertex *B = ioEdge->vertexB();
 
1659
 
 
1660
                // We split edge AB into AA' and A'B. A' and A'B are created.
 
1661
                // AB becomes (address speaking) AA'. B is updated.
 
1662
                //--------------------------------------------------
 
1663
                // a new edge, A'B is created.
 
1664
                FEdge *newEdge;
 
1665
                if (ioEdge->isSmooth()) {
 
1666
                        newEdge = new FEdgeSmooth(ioNewVertex, B);
 
1667
                        FEdgeSmooth *se = dynamic_cast<FEdgeSmooth*>(newEdge);
 
1668
                        FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth*>(ioEdge);
 
1669
                        se->setNormal(fes->normal());
 
1670
                        se->setFrsMaterialIndex(fes->frs_materialIndex());
 
1671
                        se->setFaceMark(fes->faceMark());
 
1672
                }
 
1673
                else {
 
1674
                        newEdge = new FEdgeSharp(ioNewVertex, B);
 
1675
                        FEdgeSharp *se = dynamic_cast<FEdgeSharp*>(newEdge);
 
1676
                        FEdgeSharp *fes = dynamic_cast<FEdgeSharp*>(ioEdge);
 
1677
                        se->setNormalA(fes->normalA());
 
1678
                        se->setNormalB(fes->normalB());
 
1679
                        se->setaFrsMaterialIndex(fes->aFrsMaterialIndex());
 
1680
                        se->setbFrsMaterialIndex(fes->bFrsMaterialIndex());
 
1681
                        se->setaFaceMark(fes->aFaceMark());
 
1682
                        se->setbFaceMark(fes->bFaceMark());
 
1683
                }
 
1684
                newEdge->setNature(ioEdge->getNature());
 
1685
 
 
1686
                if (ioEdge->nextEdge() != 0)
 
1687
                        ioEdge->nextEdge()->setPreviousEdge(newEdge);
 
1688
 
 
1689
                // update edge A'B for the next pointing edge
 
1690
                newEdge->setNextEdge(ioEdge->nextEdge());
 
1691
                // update edge A'B for the previous pointing edge
 
1692
                newEdge->setPreviousEdge(0); // because it is now a TVertex
 
1693
                Id id(ioEdge->getId().getFirst(), ioEdge->getId().getSecond() + 1);
 
1694
                newEdge->setId(ioEdge->getId());
 
1695
                ioEdge->setId(id);
 
1696
 
 
1697
                // update edge AA' for the next pointing edge
 
1698
                ioEdge->setNextEdge(0); // because it is now a TVertex
 
1699
 
 
1700
                // update vertex pointing edges list:
 
1701
                // -- vertex B --
 
1702
                B->Replace(ioEdge, newEdge);
 
1703
                // -- vertex A' --
 
1704
                ioNewVertex->AddFEdge(ioEdge);
 
1705
                ioNewVertex->AddFEdge(newEdge);
 
1706
 
 
1707
                // to build a new chain:
 
1708
                AddChain(newEdge);
 
1709
                AddEdge(newEdge); // FIXME ??
 
1710
 
 
1711
                // The edge AB becomes edge AA'.
 
1712
                ioEdge->setVertexB(ioNewVertex);
 
1713
 
 
1714
                if (ioEdge->isSmooth()) {
 
1715
                        ((FEdgeSmooth *)newEdge)->setFace(((FEdgeSmooth *)ioEdge)->face());
 
1716
                }
 
1717
 
 
1718
                return newEdge;
 
1719
        }
 
1720
 
 
1721
        /*! Sets the Bounding Box of the Shape */
 
1722
        inline void setBBox(const BBox<Vec3r>& iBBox)
 
1723
        {
 
1724
                _BBox = iBBox;
 
1725
        }
 
1726
 
 
1727
        /*! Compute the bbox of the sshape */
 
1728
        inline void ComputeBBox()
 
1729
        {
 
1730
                if (0 == _verticesList.size())
 
1731
                        return;
 
1732
 
 
1733
                Vec3r firstVertex = _verticesList[0]->point3D();
 
1734
                real XMax = firstVertex[0];
 
1735
                real YMax = firstVertex[1];
 
1736
                real ZMax = firstVertex[2];
 
1737
 
 
1738
                real XMin = firstVertex[0];
 
1739
                real YMin = firstVertex[1];
 
1740
                real ZMin = firstVertex[2];
 
1741
 
 
1742
                vector<SVertex*>::iterator v, vend;
 
1743
                // parse all the coordinates to find the Xmax, YMax, ZMax
 
1744
                for (v = _verticesList.begin(), vend = _verticesList.end(); v != vend; v++) {
 
1745
                        Vec3r vertex = (*v)->point3D();
 
1746
                        // X
 
1747
                        real x = vertex[0];
 
1748
                        if (x > XMax)
 
1749
                                XMax = x;
 
1750
                        else if (x < XMin)
 
1751
                                XMin = x;
 
1752
 
 
1753
                        // Y
 
1754
                        real y = vertex[1];
 
1755
                        if (y > YMax)
 
1756
                                YMax = y;
 
1757
                        else if (y < YMin)
 
1758
                                YMin = y;
 
1759
 
 
1760
                        // Z
 
1761
                        real z = vertex[2];
 
1762
                        if (z > ZMax)
 
1763
                                ZMax = z;
 
1764
                        else if (z < ZMin)
 
1765
                                ZMin = z;
 
1766
                }
 
1767
 
 
1768
                setBBox(BBox<Vec3r>(Vec3r(XMin, YMin, ZMin), Vec3r(XMax, YMax, ZMax)));
 
1769
        }
 
1770
 
 
1771
        inline void RemoveEdgeFromChain(FEdge *iEdge)
 
1772
        {
 
1773
                for (vector<FEdge*>::iterator fe = _chains.begin(), feend = _chains.end(); fe != feend; fe++) {
 
1774
                        if (iEdge == (*fe)) {
 
1775
                                _chains.erase(fe);
 
1776
                                break;
 
1777
                        }
 
1778
                }
 
1779
        }
 
1780
 
 
1781
        inline void RemoveEdge(FEdge *iEdge)
 
1782
        {
 
1783
                for (vector<FEdge*>::iterator fe = _edgesList.begin(), feend = _edgesList.end(); fe != feend; fe++) {
 
1784
                        if (iEdge == (*fe)) {
 
1785
                                _edgesList.erase(fe);
 
1786
                                break;
 
1787
                        }
 
1788
                }
 
1789
        }
 
1790
 
 
1791
        /* accessors */
 
1792
        /*! Returns the list of SVertex of the Shape. */
 
1793
        inline vector<SVertex*>& getVertexList()
 
1794
        {
 
1795
                return _verticesList;
 
1796
        }
 
1797
 
 
1798
        /*! Returns the list of FEdges of the Shape. */
 
1799
        inline vector<FEdge*>& getEdgeList()
 
1800
        {
 
1801
                return _edgesList;
 
1802
        }
 
1803
 
 
1804
        inline vector<FEdge*>& getChains()
 
1805
        {
 
1806
                return _chains;
 
1807
        }
 
1808
 
 
1809
        /*! Returns the bounding box of the shape. */
 
1810
        inline const BBox<Vec3r>& bbox()
 
1811
        {
 
1812
                return _BBox;
 
1813
        }
 
1814
 
 
1815
        /*! Returns the ith material of the shape. */
 
1816
        inline const FrsMaterial& frs_material(unsigned i) const
 
1817
        {
 
1818
                return _FrsMaterials[i];
 
1819
        }
 
1820
 
 
1821
        /*! Returns the list of materials of the Shape. */
 
1822
        inline const vector<FrsMaterial>& frs_materials() const
 
1823
        {
 
1824
                return _FrsMaterials;
 
1825
        }
 
1826
 
 
1827
        inline ViewShape *viewShape()
 
1828
        {
 
1829
                return _ViewShape;
 
1830
        }
 
1831
 
 
1832
        inline float importance() const
 
1833
        {
 
1834
                return _importance;
 
1835
        }
 
1836
 
 
1837
        /*! Returns the Id of the Shape. */
 
1838
        inline Id getId() const
 
1839
        {
 
1840
                return _Id;
 
1841
        }
 
1842
 
 
1843
        /*! Returns the name of the Shape. */
 
1844
        inline const string& getName() const
 
1845
        {
 
1846
                return _Name;
 
1847
        }
 
1848
 
 
1849
        /* Modififers */
 
1850
        /*! Sets the Id of the shape.*/
 
1851
        inline void setId(Id id)
 
1852
        {
 
1853
                _Id = id;
 
1854
        }
 
1855
 
 
1856
        /*! Sets the name of the shape.*/
 
1857
        inline void setName(const string& name)
 
1858
        {
 
1859
                _Name = name;
 
1860
        }
 
1861
 
 
1862
        /*! Sets the list of materials for the shape */
 
1863
        inline void setFrsMaterials(const vector<FrsMaterial>& iMaterials)
 
1864
        {
 
1865
                _FrsMaterials = iMaterials;
 
1866
        }
 
1867
 
 
1868
        inline void setViewShape(ViewShape *iShape)
 
1869
        {
 
1870
                _ViewShape = iShape;
 
1871
        }
 
1872
 
 
1873
        inline void setImportance(float importance)
 
1874
        {
 
1875
                _importance = importance;
 
1876
        }
 
1877
 
 
1878
#ifdef WITH_CXX_GUARDEDALLOC
 
1879
        MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SShape")
 
1880
#endif
 
1881
};
 
1882
 
 
1883
} /* namespace Freestyle */
 
1884
 
 
1885
#endif // __FREESTYLE_SILHOUETTE_H__