~ubuntu-branches/ubuntu/trusty/3depict/trusty

« back to all changes in this revision

Viewing changes to src/filters/annotation.cpp

  • Committer: Package Import Robot
  • Author(s): D Haley
  • Date: 2011-12-18 19:33:32 UTC
  • mfrom: (1.2.4)
  • Revision ID: package-import@ubuntu.com-20111218193332-1motgr3vg9xeh41b
Tags: 0.0.9-1
* Update to upstream 0.0.9 
* Close powerpc bug fixed by 0.0.8-1 (Closes: #655682) 
* Close mgl font parsing bug fixed by mathgl upstream (Closes: #623431)
* Fix unclean source package (Closes: #643039)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "annotation.h"
 
2
 
 
3
#include "../xmlHelper.h"
 
4
 
 
5
//grab size when doing convex hull calculations
 
6
const unsigned int HULL_GRAB_SIZE=4096;
 
7
 
 
8
enum
 
9
{
 
10
        KEY_POSITION=1,
 
11
        KEY_MODE,
 
12
        KEY_UPVEC,
 
13
        KEY_ACROSSVEC,
 
14
        KEY_ANNOTATE_TEXT,
 
15
        KEY_TARGET,
 
16
        KEY_COLOUR,
 
17
        KEY_ARROW_SIZE,
 
18
        KEY_TEXTSIZE,
 
19
        KEY_REFLEXIVE,
 
20
        KEY_SPHERE_ANGLE_SIZE,
 
21
        KEY_ANGLE_TEXT_VISIBLE,
 
22
        KEY_ANGLE_FORMAT_STRING,
 
23
        KEY_LINEAR_FONTSIZE,
 
24
        KEY_LINEAR_NUMTICKS,
 
25
        KEY_LINEAR_FIXED_TICKS,
 
26
        KEY_LINEAR_TICKSPACING,
 
27
};
 
28
 
 
29
enum
 
30
{
 
31
        BINDING_TEXT_ORIGIN=1,
 
32
        BINDING_ARROW_ORIGIN,
 
33
        BINDING_ARROW_VECTOR,
 
34
        BINDING_ANGLE_ORIGIN,
 
35
        BINDING_ANGLE_FIRST,
 
36
        BINDING_ANGLE_SECOND,
 
37
        BINDING_ANGLE_SPHERERADIUS,
 
38
        BINDING_LINEAR_ORIGIN,
 
39
        BINDING_LINEAR_TARGET,
 
40
        BINDING_LINEAR_SPHERERADIUS
 
41
};
 
42
 
 
43
const unsigned int NUM_ANNOTATION_MODES=5;
 
44
 
 
45
const char *annotationModeStrings[] =
 
46
{
 
47
        NTRANS("Arrow"),
 
48
        NTRANS("Text"),
 
49
        NTRANS("Arrow+Text"),
 
50
        NTRANS("Angle"),
 
51
        NTRANS("Ruler")
 
52
};
 
53
 
 
54
 
 
55
AnnotateFilter::AnnotateFilter()
 
56
{
 
57
 
 
58
        annotationMode=ANNOTATION_TEXT;
 
59
 
 
60
        position=Point3D(0,0,0);
 
61
        target=Point3D(1,0,0);
 
62
        upVec=Point3D(0,0,1);
 
63
        acrossVec=Point3D(0,1,0);
 
64
 
 
65
        anglePos[0]=Point3D(0,0,0);
 
66
        anglePos[1]=Point3D(0,5,5);
 
67
        anglePos[2]=Point3D(0,-5,5);
 
68
        
 
69
        textSize=1;
 
70
        annotateSize=1;
 
71
        sphereAngleSize=1.5;
 
72
        
 
73
        //Set the colour to default blue
 
74
        r=g=0;b=a=1.0;
 
75
 
 
76
        active=true;
 
77
        showAngleText=true;
 
78
 
 
79
        reflexAngle=false;
 
80
        fontSizeLinearMeasure=5;
 
81
        linearMeasureTicks=10;
 
82
        linearFixedTicks=true;
 
83
        linearMeasureSpacing=10.0f;
 
84
        linearMeasureMarkerSize=3.0f;
 
85
        angleFormatPreDecimal=angleFormatPostDecimal=0;
 
86
 
 
87
        cacheOK=false;
 
88
        cache=true; //By default, we should cache, but decision is made higher up
 
89
}
 
90
 
 
91
Filter *AnnotateFilter::cloneUncached() const
 
92
{
 
93
        AnnotateFilter *p=new AnnotateFilter();
 
94
 
 
95
        p->annotationMode=annotationMode;
 
96
        p->position=position;
 
97
        p->target=target;
 
98
        p->upVec=upVec;
 
99
        p->acrossVec=acrossVec;
 
100
 
 
101
        for(unsigned int ui=0;ui<3; ui++)
 
102
                p->anglePos[ui]=anglePos[ui];
 
103
 
 
104
        p->textSize=textSize;
 
105
        p->annotateSize=annotateSize;
 
106
        p->sphereAngleSize=sphereAngleSize;
 
107
 
 
108
        p->r=r;
 
109
        p->g=g;
 
110
        p->b=b;
 
111
        p->a=a;
 
112
 
 
113
        p->active=active;
 
114
        p->showAngleText=showAngleText;
 
115
 
 
116
        p->reflexAngle=reflexAngle;
 
117
 
 
118
        p->angleFormatPreDecimal=angleFormatPreDecimal;
 
119
        p->angleFormatPostDecimal=angleFormatPostDecimal;
 
120
 
 
121
 
 
122
        p->fontSizeLinearMeasure=fontSizeLinearMeasure;
 
123
        p->linearFixedTicks=linearFixedTicks;
 
124
        p->linearMeasureSpacing=linearMeasureSpacing;
 
125
        p->linearMeasureTicks=linearMeasureTicks;
 
126
        p->linearMeasureMarkerSize=linearMeasureMarkerSize;
 
127
 
 
128
        //We are copying wether to cache or not,
 
129
        //not the cache itself
 
130
        p->cache=cache;
 
131
        p->cacheOK=false;
 
132
        p->userString=userString;
 
133
        return p;
 
134
}
 
135
 
 
136
unsigned int AnnotateFilter::refresh(const std::vector<const FilterStreamData *> &dataIn,
 
137
        std::vector<const FilterStreamData *> &getOut, ProgressData &progress, bool (*callback)(void))
 
138
{
 
139
 
 
140
        //Clear devices
 
141
        devices.clear();
 
142
 
 
143
        //Pipe everything through
 
144
        getOut.resize(dataIn.size());
 
145
        for(size_t ui=0;ui<dataIn.size();ui++)
 
146
                getOut[ui] = dataIn[ui];
 
147
 
 
148
        if(!active)
 
149
                return 0;
 
150
 
 
151
        DrawStreamData *d; 
 
152
        d = new DrawStreamData;
 
153
        d->parent=this;
 
154
 
 
155
        //Draw text output as needed
 
156
        if( annotationMode == ANNOTATION_TEXT ||
 
157
                annotationMode== ANNOTATION_TEXT_WITH_ARROW)
 
158
        {
 
159
                DrawGLText *dt;
 
160
                dt = new DrawGLText(getDefaultFontFile().c_str(),FTGL_POLYGON);
 
161
 
 
162
                dt->setString(annotateText);
 
163
                dt->setOrigin(position);
 
164
                dt->setUp(upVec);
 
165
                dt->setColour(r,g,b,a);
 
166
                dt->setTextDir(acrossVec);
 
167
                dt->setSize(textSize);
 
168
 
 
169
                dt->setAlignment(DRAWTEXT_ALIGN_CENTRE);
 
170
                
 
171
                dt->canSelect=true;
 
172
                SelectionDevice<Filter> *s = new SelectionDevice<Filter>(this);
 
173
                SelectionBinding bind[1];
 
174
                
 
175
                bind[0].setBinding(SELECT_BUTTON_LEFT,0,DRAW_TEXT_BIND_ORIGIN,
 
176
                                BINDING_TEXT_ORIGIN,dt->getOrigin(),dt);
 
177
                bind[0].setInteractionMode(BIND_MODE_POINT3D_TRANSLATE);
 
178
                s->addBinding(bind[0]);
 
179
                                        
 
180
 
 
181
                devices.push_back(s);
 
182
                d->drawables.push_back(dt);
 
183
        }
 
184
        
 
185
        //Draw annnotation mode as needed
 
186
        if(annotationMode==ANNOTATION_ARROW ||
 
187
                annotationMode==ANNOTATION_TEXT_WITH_ARROW)
 
188
        {
 
189
                DrawVector *dv;
 
190
                dv = new DrawVector;
 
191
 
 
192
                dv->setOrigin(position);
 
193
                dv->setVector(target-position);
 
194
                dv->setArrowSize(annotateSize);
 
195
                dv->setColour(r,g,b,a); 
 
196
        
 
197
                dv->canSelect=true;
 
198
 
 
199
                SelectionDevice<Filter> *s = new SelectionDevice<Filter>(this);
 
200
                SelectionBinding bind[2];
 
201
                
 
202
                bind[0].setBinding(SELECT_BUTTON_LEFT,0,DRAW_VECTOR_BIND_TARGET,
 
203
                                BINDING_ARROW_VECTOR,dv->getVector(),dv);
 
204
                bind[0].setInteractionMode(BIND_MODE_POINT3D_TRANSLATE);
 
205
                s->addBinding(bind[0]);
 
206
                
 
207
                
 
208
                bind[1].setBinding(SELECT_BUTTON_LEFT,FLAG_SHIFT,DRAW_VECTOR_BIND_ORIGIN,
 
209
                                BINDING_ARROW_ORIGIN,dv->getOrigin(),dv);
 
210
                bind[1].setInteractionMode(BIND_MODE_POINT3D_TRANSLATE);
 
211
                s->addBinding(bind[1]);
 
212
                                        
 
213
 
 
214
                devices.push_back(s);
 
215
                d->drawables.push_back(dv);
 
216
        }
 
217
 
 
218
        if(annotationMode == ANNOTATION_ANGLE_MEASURE)
 
219
        {
 
220
                //Draw the three spheres that are the handles
 
221
                //for the angle motion
 
222
                for(unsigned int ui=0;ui<3;ui++)
 
223
                {
 
224
                        DrawSphere *dS;
 
225
                        SelectionDevice<Filter> *s= new SelectionDevice<Filter>(this);
 
226
                        SelectionBinding bind[2];
 
227
 
 
228
                        dS=new DrawSphere;
 
229
                        dS->setOrigin(anglePos[ui]);
 
230
                        dS->setRadius(sphereAngleSize);
 
231
                        dS->setColour(r,g,b,a);
 
232
 
 
233
                        dS->canSelect=true;
 
234
                        dS->wantsLight=true;
 
235
 
 
236
                        //Create binding for sphere translation.
 
237
                        //Note that each binding is a bit different, as it
 
238
                        //affects each sphere separately.
 
239
                        bind[0].setBinding(SELECT_BUTTON_LEFT,0,DRAW_SPHERE_BIND_ORIGIN,
 
240
                                                BINDING_ANGLE_ORIGIN+ui,anglePos[ui],dS);
 
241
                        bind[0].setInteractionMode(BIND_MODE_POINT3D_TRANSLATE);
 
242
                        s->addBinding(bind[0]);
 
243
 
 
244
                        //Create binding for sphere scaling, each binding is the same 
 
245
                        bind[1].setBinding(SELECT_BUTTON_LEFT,FLAG_SHIFT,DRAW_SPHERE_BIND_RADIUS,
 
246
                                                BINDING_ANGLE_SPHERERADIUS,dS->getRadius(),dS);
 
247
                        bind[1].setInteractionMode(BIND_MODE_FLOAT_TRANSLATE);
 
248
                        bind[1].setFloatLimits(0,std::numeric_limits<float>::max());
 
249
 
 
250
                        s->addBinding(bind[1]);
 
251
 
 
252
                        devices.push_back(s);
 
253
                        d->drawables.push_back(dS);
 
254
                }
 
255
 
 
256
                //Now draw the two lines that form the angle
 
257
                DrawVector *dv;
 
258
                dv=new DrawVector;
 
259
                dv->setOrigin(anglePos[0]);
 
260
                dv->setVector(anglePos[1]-anglePos[0]);
 
261
                dv->setColour(r,g,b,a);
 
262
                d->drawables.push_back(dv);
 
263
 
 
264
                dv=new DrawVector;
 
265
                dv->setOrigin(anglePos[0]);
 
266
                dv->setVector(anglePos[2]-anglePos[0]);
 
267
                dv->setColour(r,g,b,a);
 
268
                d->drawables.push_back(dv);
 
269
 
 
270
 
 
271
                //If required,
 
272
                //show the text that 
 
273
                //indicates the included or reflexive angle
 
274
                if(showAngleText)
 
275
                {
 
276
                        std::string angleString;
 
277
                        
 
278
                        Point3D d1,d2;
 
279
                        float angleVal;
 
280
                        
 
281
                        d1=anglePos[1]-anglePos[0];
 
282
                        d2=anglePos[2]-anglePos[0];
 
283
                        angleVal =d1.angle(d2);
 
284
 
 
285
                        if(reflexAngle)
 
286
                                angleVal=2.0*M_PI-angleVal;
 
287
                        angleVal=180.0f/M_PI*angleVal;
 
288
                        angleVal=fmod(angleVal,360.0f);
 
289
 
 
290
                        //FIXME: print specifier computation is still a bit off
 
291
                        if(angleFormatPreDecimal+angleFormatPostDecimal)
 
292
                        {
 
293
                                //One space for the decimal, one for the null
 
294
                                //and the rest for the actual integer
 
295
                                size_t num;
 
296
                                num = angleFormatPreDecimal+angleFormatPostDecimal+1;
 
297
                                char *buf = new char[num+1];
 
298
 
 
299
                                std::string tmp,formatStr;
 
300
                                formatStr="%";
 
301
                                if(angleFormatPreDecimal)
 
302
                                {
 
303
 
 
304
                                        stream_cast(tmp,angleFormatPreDecimal + angleFormatPostDecimal+2);
 
305
                                        formatStr+=std::string("0") + tmp;
 
306
                                }
 
307
 
 
308
                                if(angleFormatPostDecimal)
 
309
                                {
 
310
 
 
311
                                        stream_cast(tmp,angleFormatPostDecimal);
 
312
                                        formatStr+=".";
 
313
                                        formatStr+=tmp;
 
314
                                }
 
315
                                formatStr+="f";
 
316
 
 
317
                                snprintf(buf,num,formatStr.c_str(),angleVal);
 
318
                                angleString=buf;
 
319
                                delete[] buf;
 
320
 
 
321
                        }
 
322
                        else
 
323
                                stream_cast(angleString, angleVal);
 
324
 
 
325
                        //Place the string appropriately
 
326
                        DrawGLText *dt;
 
327
                        dt = new DrawGLText(getDefaultFontFile().c_str(),FTGL_POLYGON);
 
328
 
 
329
                        dt->setString(angleString);
 
330
                        dt->setAlignment(DRAWTEXT_ALIGN_CENTRE);
 
331
                        //Place the text using
 
332
                        //a factor of the text size in
 
333
                        //the direction of the average
 
334
                        //of the two vector components
 
335
                        Point3D averageVec;
 
336
                        averageVec = (d1+d2)*0.5f;
 
337
                        averageVec.normalise();
 
338
                        averageVec*=textSize*1.1;
 
339
                        if(reflexAngle)
 
340
                                averageVec.negate();
 
341
                        dt->setOrigin(anglePos[0]+averageVec);
 
342
 
 
343
                        //Use user-specifications for colour,
 
344
                        //size and orientation
 
345
                        dt->setUp(upVec);
 
346
                        dt->setColour(r,g,b,a);
 
347
                        dt->setTextDir(acrossVec);
 
348
                        dt->setSize(textSize);
 
349
                
 
350
 
 
351
                        d->drawables.push_back(dt);
 
352
                }
 
353
        }
 
354
 
 
355
        if(annotationMode == ANNOTATION_LINEAR_MEASURE)
 
356
        {
 
357
                DrawVector *dv;
 
358
                dv = new DrawVector;
 
359
 
 
360
                dv->setOrigin(position);
 
361
                dv->setColour(r,g,b,a);
 
362
                dv->setVector(target-position);
 
363
 
 
364
                d->drawables.push_back(dv);
 
365
 
 
366
                //Compute the tick spacings
 
367
                vector<float> tickSpacings;
 
368
                if(linearFixedTicks)
 
369
                {
 
370
                        tickSpacingsFromFixedNum(0,sqrt(target.sqrDist(position)),
 
371
                                        linearMeasureTicks,tickSpacings);
 
372
                }
 
373
                else
 
374
                {
 
375
                        tickSpacingsFromInterspace(0,sqrt(target.sqrDist(position)),
 
376
                                                linearMeasureSpacing,tickSpacings);
 
377
                }
 
378
 
 
379
                if(tickSpacings.size())
 
380
                {
 
381
 
 
382
                        Point3D measureNormal;
 
383
                        measureNormal = target-position;
 
384
                        measureNormal.normalise();
 
385
 
 
386
                        //Construct the drawable text object
 
387
                        DrawGLText *dT; 
 
388
                        for(unsigned int ui=0;ui<tickSpacings.size();ui++)
 
389
                        {
 
390
                                //Create the tick that will be added to the drawables
 
391
                                dT = new DrawGLText(getDefaultFontFile().c_str(),FTGL_POLYGON);
 
392
                                        
 
393
                                dT->setColour(r,g,b,a);
 
394
                                dT->setOrigin(measureNormal*tickSpacings[ui] + position);
 
395
                                dT->setUp(upVec);       
 
396
                                dT->setTextDir(acrossVec);
 
397
                                dT->setSize(fontSizeLinearMeasure);
 
398
 
 
399
                                string s;
 
400
                                stream_cast(s,tickSpacings[ui]);
 
401
 
 
402
                                dT->setString(s);
 
403
 
 
404
                                d->drawables.push_back(dT);
 
405
                        }
 
406
 
 
407
 
 
408
                        //Now draw the end markers
 
409
 
 
410
                        //Start marker
 
411
                        DrawSphere *dS;
 
412
                        dS = new DrawSphere;
 
413
                        dS->setRadius(linearMeasureMarkerSize);
 
414
                        dS->setOrigin(position);
 
415
                        dS->setColour(r,g,b,a);
 
416
 
 
417
                        dS->canSelect=true;
 
418
                        dS->wantsLight=true;
 
419
                        
 
420
                        SelectionDevice<Filter> *s= new SelectionDevice<Filter>(this);
 
421
                        SelectionBinding bind[4];
 
422
                        //Create binding for sphere translation.
 
423
                        //Note that each binding is a bit different, as it
 
424
                        //affects each sphere separately.
 
425
                        bind[0].setBinding(SELECT_BUTTON_LEFT,0,DRAW_SPHERE_BIND_ORIGIN,
 
426
                                                BINDING_LINEAR_ORIGIN,position,dS);
 
427
                        bind[0].setInteractionMode(BIND_MODE_POINT3D_TRANSLATE);
 
428
                        s->addBinding(bind[0]);
 
429
 
 
430
                        //Create binding for sphere scaling, each binding is the same 
 
431
                        bind[1].setBinding(SELECT_BUTTON_LEFT,FLAG_SHIFT,DRAW_SPHERE_BIND_RADIUS,
 
432
                                                BINDING_LINEAR_SPHERERADIUS,dS->getRadius(),dS);
 
433
                        bind[1].setInteractionMode(BIND_MODE_FLOAT_TRANSLATE);
 
434
                        bind[1].setFloatLimits(0,std::numeric_limits<float>::max());
 
435
 
 
436
                        s->addBinding(bind[1]);
 
437
 
 
438
                        devices.push_back(s);
 
439
                        d->drawables.push_back(dS);
 
440
                
 
441
                
 
442
                        //Now do the second sphere (end marker)
 
443
                        s= new SelectionDevice<Filter>(this);
 
444
                        dS = new DrawSphere;
 
445
                        
 
446
                        dS->setRadius(linearMeasureMarkerSize);
 
447
                        dS->setOrigin(target);
 
448
                        dS->setColour(r,g,b,a);
 
449
 
 
450
                        dS->canSelect=true;
 
451
                        dS->wantsLight=true;
 
452
 
 
453
                        bind[2].setBinding(SELECT_BUTTON_LEFT,0,DRAW_SPHERE_BIND_ORIGIN,
 
454
                                                BINDING_LINEAR_TARGET,target,dS);
 
455
                        bind[2].setInteractionMode(BIND_MODE_POINT3D_TRANSLATE);
 
456
                        s->addBinding(bind[2]);
 
457
 
 
458
                        //Create binding for sphere scaling, each binding is the same 
 
459
                        bind[3].setBinding(SELECT_BUTTON_LEFT,FLAG_SHIFT,DRAW_SPHERE_BIND_RADIUS,
 
460
                                                BINDING_LINEAR_SPHERERADIUS,dS->getRadius(),dS);
 
461
                        bind[3].setInteractionMode(BIND_MODE_FLOAT_TRANSLATE);
 
462
                        bind[3].setFloatLimits(0,std::numeric_limits<float>::max());
 
463
                        s->addBinding(bind[3]);
 
464
                
 
465
                        
 
466
                        devices.push_back(s);
 
467
                        d->drawables.push_back(dS);
 
468
 
 
469
 
 
470
                }
 
471
        }
 
472
        
 
473
        d->cached=0;
 
474
        getOut.push_back(d);
 
475
 
 
476
        return 0;
 
477
}
 
478
 
 
479
size_t AnnotateFilter::numBytesForCache(size_t nObjects) const
 
480
{
 
481
        return 0;
 
482
}
 
483
 
 
484
 
 
485
void AnnotateFilter::getProperties(FilterProperties &propertyList) const
 
486
{
 
487
        vector<unsigned int> type,keys;
 
488
        vector<pair<string,string> > s;
 
489
        string str;
 
490
 
 
491
        vector<pair<unsigned int,string> > choices;
 
492
        string tmpChoice,tmpStr;
 
493
        
 
494
        for(unsigned int ui=0;ui<ANNOTATION_MODE_END; ui++)
 
495
        {
 
496
                choices.push_back(make_pair((unsigned int)ui,
 
497
                                        TRANS(annotationModeStrings[ui])));
 
498
        }
 
499
 
 
500
        tmpStr=choiceString(choices,annotationMode);
 
501
        s.push_back(make_pair(TRANS("Mode"), tmpStr));
 
502
        keys.push_back(KEY_MODE);
 
503
        type.push_back(PROPERTY_TYPE_CHOICE);
 
504
 
 
505
        propertyList.data.push_back(s);
 
506
        propertyList.keys.push_back(keys);
 
507
        propertyList.types.push_back(type);
 
508
        s.clear();keys.clear();type.clear();
 
509
        
 
510
        switch(annotationMode)
 
511
        {
 
512
                case ANNOTATION_TEXT:
 
513
                {
 
514
                        //Note to translators, this is short for "annotation text",
 
515
                        // or similar
 
516
                        s.push_back(make_pair(TRANS("Annotation"),annotateText));
 
517
                        type.push_back(PROPERTY_TYPE_STRING);
 
518
                        keys.push_back(KEY_ANNOTATE_TEXT);
 
519
                
 
520
                        stream_cast(tmpStr,position);
 
521
                        s.push_back(make_pair(TRANS("Origin"),tmpStr));
 
522
                        type.push_back(PROPERTY_TYPE_POINT3D);
 
523
                        keys.push_back(KEY_POSITION);
 
524
                        
 
525
                        stream_cast(tmpStr,upVec);
 
526
                        s.push_back(make_pair(TRANS("Up dir"),tmpStr));
 
527
                        type.push_back(PROPERTY_TYPE_STRING);
 
528
                        keys.push_back(KEY_UPVEC);
 
529
                
 
530
                        stream_cast(tmpStr,acrossVec);
 
531
                        s.push_back(make_pair(TRANS("Across dir"),tmpStr));
 
532
                        type.push_back(PROPERTY_TYPE_STRING);
 
533
                        keys.push_back(KEY_ACROSSVEC);
 
534
 
 
535
 
 
536
                        stream_cast(tmpStr,textSize);
 
537
                        s.push_back(make_pair(TRANS("Text size"),tmpStr));
 
538
                        type.push_back(PROPERTY_TYPE_REAL);
 
539
                        keys.push_back(KEY_TEXTSIZE);
 
540
 
 
541
                        break;
 
542
                }
 
543
                case ANNOTATION_ARROW:
 
544
                {
 
545
                        stream_cast(tmpStr,position);
 
546
                        s.push_back(make_pair(TRANS("Start"),tmpStr));
 
547
                        type.push_back(PROPERTY_TYPE_POINT3D);
 
548
                        keys.push_back(KEY_POSITION);
 
549
                
 
550
                        stream_cast(tmpStr,target);
 
551
                        s.push_back(make_pair(TRANS("End"),tmpStr));
 
552
                        type.push_back(PROPERTY_TYPE_POINT3D);
 
553
                        keys.push_back(KEY_TARGET);
 
554
                        break;
 
555
                }
 
556
                case ANNOTATION_TEXT_WITH_ARROW:
 
557
                {
 
558
                        stream_cast(tmpStr,position);
 
559
                        s.push_back(make_pair(TRANS("Start"),tmpStr));
 
560
                        type.push_back(PROPERTY_TYPE_POINT3D);
 
561
                        keys.push_back(KEY_POSITION);
 
562
                        
 
563
 
 
564
                        stream_cast(tmpStr,target);
 
565
                        s.push_back(make_pair(TRANS("End"),tmpStr));
 
566
                        type.push_back(PROPERTY_TYPE_POINT3D);
 
567
                        keys.push_back(KEY_TARGET);
 
568
                        
 
569
                        //Note to translators, this is short for "annotation text",
 
570
                        // or similar
 
571
                        s.push_back(make_pair(TRANS("Annotation"),annotateText));
 
572
                        type.push_back(PROPERTY_TYPE_STRING);
 
573
                        keys.push_back(KEY_ANNOTATE_TEXT);
 
574
                        
 
575
                        stream_cast(tmpStr,textSize);
 
576
                        s.push_back(make_pair(TRANS("Text size"),tmpStr));
 
577
                        type.push_back(PROPERTY_TYPE_REAL);
 
578
                        keys.push_back(KEY_TEXTSIZE);
 
579
                        
 
580
                        stream_cast(tmpStr,upVec);
 
581
                        s.push_back(make_pair(TRANS("Up dir"),tmpStr));
 
582
                        type.push_back(PROPERTY_TYPE_STRING);
 
583
                        keys.push_back(KEY_UPVEC);
 
584
                
 
585
                        stream_cast(tmpStr,acrossVec);
 
586
                        s.push_back(make_pair(TRANS("Across dir"),tmpStr));
 
587
                        type.push_back(PROPERTY_TYPE_STRING);
 
588
                        keys.push_back(KEY_ACROSSVEC);
 
589
                        break;
 
590
                }
 
591
                case ANNOTATION_ANGLE_MEASURE:
 
592
                {
 
593
                        stream_cast(tmpStr,upVec);
 
594
                        s.push_back(make_pair(TRANS("Up dir"),tmpStr));
 
595
                        type.push_back(PROPERTY_TYPE_STRING);
 
596
                        keys.push_back(KEY_UPVEC);
 
597
                
 
598
                        stream_cast(tmpStr,acrossVec);
 
599
                        s.push_back(make_pair(TRANS("Across dir"),tmpStr));
 
600
                        type.push_back(PROPERTY_TYPE_STRING);
 
601
                        keys.push_back(KEY_ACROSSVEC);
 
602
 
 
603
 
 
604
                        keys.push_back(KEY_REFLEXIVE);
 
605
                        s.push_back(make_pair(TRANS("Reflexive"),reflexAngle? "1":"0"));
 
606
                        type.push_back(PROPERTY_TYPE_BOOL);
 
607
                
 
608
                        
 
609
                        s.push_back(make_pair(TRANS("Show Angle"),showAngleText? "1":"0"));
 
610
                        type.push_back(PROPERTY_TYPE_BOOL);
 
611
                        keys.push_back(KEY_ANGLE_TEXT_VISIBLE);
 
612
                
 
613
                        if(showAngleText)
 
614
                        {
 
615
                                stream_cast(tmpStr,textSize);
 
616
                                s.push_back(make_pair(TRANS("Text size"),tmpStr));
 
617
                                type.push_back(PROPERTY_TYPE_REAL);
 
618
                                keys.push_back(KEY_TEXTSIZE);
 
619
 
 
620
 
 
621
                                std::string tmp2;
 
622
                                tmpStr.clear();
 
623
                                if(angleFormatPreDecimal)
 
624
                                {
 
625
                                        tmp2.resize(angleFormatPreDecimal,'#');
 
626
                                        tmpStr=tmp2;
 
627
                                }
 
628
                                        
 
629
                                if(angleFormatPostDecimal)
 
630
                                {
 
631
                                        tmp2.resize(angleFormatPostDecimal,'#');
 
632
                                        tmpStr+=std::string(".") + tmp2;
 
633
                                }
 
634
 
 
635
                                s.push_back(make_pair(TRANS("Digit format"),tmpStr));
 
636
                                type.push_back(PROPERTY_TYPE_STRING);
 
637
                                keys.push_back(KEY_ANGLE_FORMAT_STRING);
 
638
 
 
639
                        }
 
640
                        
 
641
                        stream_cast(tmpStr,sphereAngleSize);
 
642
                        s.push_back(make_pair(TRANS("Sphere size"),tmpStr));
 
643
                        type.push_back(PROPERTY_TYPE_REAL);
 
644
                        keys.push_back(KEY_SPHERE_ANGLE_SIZE);
 
645
 
 
646
                
 
647
 
 
648
                        break;
 
649
                }
 
650
                case ANNOTATION_LINEAR_MEASURE:
 
651
                {
 
652
                        stream_cast(tmpStr,position);
 
653
                        s.push_back(make_pair(TRANS("Start"),tmpStr));
 
654
                        type.push_back(PROPERTY_TYPE_POINT3D);
 
655
                        keys.push_back(KEY_POSITION);
 
656
                
 
657
                        stream_cast(tmpStr,target);
 
658
                        s.push_back(make_pair(TRANS("End"),tmpStr));
 
659
                        type.push_back(PROPERTY_TYPE_POINT3D);
 
660
                        keys.push_back(KEY_TARGET);
 
661
 
 
662
                        stream_cast(tmpStr,upVec);
 
663
                        s.push_back(make_pair(TRANS("Up dir"),tmpStr));
 
664
                        type.push_back(PROPERTY_TYPE_STRING);
 
665
                        keys.push_back(KEY_UPVEC);
 
666
                
 
667
                        stream_cast(tmpStr,acrossVec);
 
668
                        s.push_back(make_pair(TRANS("Across dir"),tmpStr));
 
669
                        type.push_back(PROPERTY_TYPE_STRING);
 
670
                        keys.push_back(KEY_ACROSSVEC);
 
671
                        
 
672
                        stream_cast(tmpStr,fontSizeLinearMeasure);
 
673
                        keys.push_back(KEY_LINEAR_FONTSIZE);
 
674
                        s.push_back(make_pair(TRANS("Font Size"), tmpStr));
 
675
                        type.push_back(PROPERTY_TYPE_INTEGER);
 
676
                        
 
677
                        
 
678
                        if(linearFixedTicks)
 
679
                                tmpStr="1";
 
680
                        else
 
681
                                tmpStr="0";
 
682
                        keys.push_back(KEY_LINEAR_FIXED_TICKS);
 
683
                        s.push_back(make_pair(TRANS("Fixed ticks"), tmpStr));
 
684
                        type.push_back(PROPERTY_TYPE_BOOL);
 
685
 
 
686
                        if(linearFixedTicks)
 
687
                        {
 
688
                                stream_cast(tmpStr,linearMeasureTicks);
 
689
                                keys.push_back(KEY_LINEAR_NUMTICKS);
 
690
                                s.push_back(make_pair(TRANS("Num Ticks"), tmpStr));
 
691
                                type.push_back(PROPERTY_TYPE_INTEGER);
 
692
                        }
 
693
                        else
 
694
                        {
 
695
                                stream_cast(tmpStr,linearMeasureSpacing);
 
696
                                keys.push_back(KEY_LINEAR_TICKSPACING);
 
697
                                s.push_back(make_pair(TRANS("Tick Spacing"), tmpStr));
 
698
                                type.push_back(PROPERTY_TYPE_REAL);
 
699
                        }
 
700
 
 
701
                        break;
 
702
                }
 
703
                default:
 
704
                        ASSERT(false);
 
705
        }
 
706
 
 
707
 
 
708
        genColString((unsigned char)(r*255.0),(unsigned char)(g*255.0),
 
709
                (unsigned char)(b*255),(unsigned char)(a*255),str);
 
710
        keys.push_back(KEY_COLOUR);
 
711
        s.push_back(make_pair(TRANS("Colour"), str));
 
712
        type.push_back(PROPERTY_TYPE_COLOUR);
 
713
 
 
714
        propertyList.data.push_back(s);
 
715
        propertyList.keys.push_back(keys);
 
716
        propertyList.types.push_back(type);
 
717
 
 
718
}
 
719
 
 
720
bool AnnotateFilter::setProperty( unsigned int set, unsigned int key,
 
721
                                        const std::string &value, bool &needUpdate)
 
722
{
 
723
        string stripped=stripWhite(value);
 
724
        switch(key)
 
725
        {
 
726
                case KEY_MODE:
 
727
                {
 
728
                        unsigned int newMode;
 
729
 
 
730
                        for(newMode=0;newMode<NUM_ANNOTATION_MODES;newMode++)
 
731
                        {
 
732
                                if(stripped == annotationModeStrings[newMode])
 
733
                                        break;
 
734
                        }
 
735
 
 
736
                        if(newMode == NUM_ANNOTATION_MODES)
 
737
                                return false;
 
738
 
 
739
                        if(newMode!=annotationMode)
 
740
                        {
 
741
                                annotationMode=newMode;
 
742
                                needUpdate=true;
 
743
                        }
 
744
 
 
745
                        break;  
 
746
                
 
747
                }
 
748
                case KEY_UPVEC:
 
749
                {
 
750
                        //This sets the up direction
 
751
                        //which must be normal to the 
 
752
                        //across direction for the text.
 
753
                        //
 
754
                        //Compute the normal component of acrossVec.
 
755
                        //and override that.
 
756
                        //
 
757
                        //Be careful not to "invert" the text, so it
 
758
                        //does not show.
 
759
                        Point3D newPt;
 
760
                        if(!parsePointStr(value,newPt))
 
761
                                return false;
 
762
                        newPt.normalise();
 
763
 
 
764
                        //Use double-cross-product method
 
765
                        //to orthogonalise the two vectors
 
766
                        Point3D normVec;
 
767
                        normVec=newPt.crossProd(acrossVec);
 
768
 
 
769
                        if(normVec.sqrMag() < std::numeric_limits<float>::epsilon())
 
770
                                return false;
 
771
 
 
772
                        acrossVec=normVec.crossProd(newPt);
 
773
 
 
774
                        ASSERT(acrossVec.sqrMag() > std::numeric_limits<float>::epsilon());
 
775
                
 
776
                        if(!(upVec == newPt))
 
777
                        {
 
778
                                upVec=newPt;
 
779
                                needUpdate=true;
 
780
                        }
 
781
 
 
782
                        break;  
 
783
                }
 
784
                case KEY_ACROSSVEC:
 
785
                {
 
786
                        //This sets the up direction
 
787
                        //which must be normal to the 
 
788
                        //across direction for the text.
 
789
                        //
 
790
                        //Compute the normal component of acrossVec.
 
791
                        //and override that.
 
792
                        //
 
793
                        //Be careful not to "invert" the text, so it
 
794
                        //does not show.
 
795
                        Point3D newPt;
 
796
                        if(!parsePointStr(value,newPt))
 
797
                                return false;
 
798
                        newPt.normalise();
 
799
 
 
800
                        //Use double-cross-product method
 
801
                        //to orthogonalise the two vectors
 
802
                        Point3D normVec;
 
803
                        normVec=newPt.crossProd(upVec);
 
804
 
 
805
                        if(normVec.sqrMag() < std::numeric_limits<float>::epsilon())
 
806
                                return false;
 
807
 
 
808
                        upVec=normVec.crossProd(newPt);
 
809
 
 
810
                        ASSERT(upVec.sqrMag() > std::numeric_limits<float>::epsilon());
 
811
                
 
812
                        if(!(acrossVec == newPt))
 
813
                        {
 
814
                                acrossVec=newPt;
 
815
                                needUpdate=true;
 
816
                        }
 
817
 
 
818
                        break;  
 
819
                }
 
820
                case KEY_POSITION:
 
821
                {
 
822
                        Point3D newPt;
 
823
                        if(!parsePointStr(value,newPt))
 
824
                                return false;
 
825
 
 
826
                        if(!(acrossVec == newPt))
 
827
                        {
 
828
                                position=newPt;
 
829
                                needUpdate=true;
 
830
                        }
 
831
 
 
832
                        break;  
 
833
                }
 
834
                case KEY_TARGET:
 
835
                {
 
836
                        Point3D newPt;
 
837
                        if(!parsePointStr(value,newPt))
 
838
                                return false;
 
839
 
 
840
                        if(!(target== newPt))
 
841
                        {
 
842
                                target=newPt;
 
843
                                needUpdate=true;
 
844
                        }
 
845
 
 
846
                        break;  
 
847
                }
 
848
                case KEY_ARROW_SIZE:
 
849
                {
 
850
                        float tmp;
 
851
                        if(stream_cast(tmp,value))
 
852
                                return false;
 
853
 
 
854
                        if(tmp!=annotateSize)
 
855
                        {
 
856
                                annotateSize=tmp;
 
857
                                needUpdate=true;
 
858
                        }
 
859
                
 
860
                        break;  
 
861
                }
 
862
                case KEY_ANNOTATE_TEXT:
 
863
                {
 
864
                        if(value!=annotateText)
 
865
                        {
 
866
                                needUpdate=true;
 
867
                                annotateText=value;
 
868
                        }
 
869
 
 
870
                        break;
 
871
                }
 
872
                case KEY_COLOUR:
 
873
                {
 
874
                        unsigned char newR,newG,newB,newA;
 
875
 
 
876
                        parseColString(value,newR,newG,newB,newA);
 
877
 
 
878
                        if(newB != b || newR != r ||
 
879
                                newG !=g || newA != a)
 
880
                        {
 
881
                                r=(float)newR/255.0;
 
882
                                g=(float)newG/255.0;
 
883
                                b=(float)newB/255.0;
 
884
                                a=(float)newA/255.0;
 
885
 
 
886
                                needUpdate=true;
 
887
                        }
 
888
                        else
 
889
                                needUpdate=false;
 
890
                        break;
 
891
                }
 
892
                case KEY_TEXTSIZE:
 
893
                {
 
894
                        float tmp;
 
895
                        stream_cast(tmp,value);
 
896
                        if(fabs(tmp-textSize) > std::numeric_limits<float>::epsilon() 
 
897
                                && tmp > sqrt(std::numeric_limits<float>::epsilon()))
 
898
                        {
 
899
                                needUpdate=true;
 
900
                                textSize=tmp;
 
901
                        }
 
902
 
 
903
                        break;
 
904
                }
 
905
                case KEY_REFLEXIVE:
 
906
                {
 
907
                        bool tmp;
 
908
                        tmp=(value=="1");
 
909
 
 
910
                        if(tmp==reflexAngle)
 
911
                                return false;
 
912
                        
 
913
                        reflexAngle=tmp;
 
914
 
 
915
                        needUpdate=true;
 
916
                        break;
 
917
                }
 
918
                case KEY_SPHERE_ANGLE_SIZE:
 
919
                {
 
920
                        float tmp;
 
921
                        stream_cast(tmp,value);
 
922
 
 
923
                        if(tmp == sphereAngleSize)
 
924
                                return false;
 
925
 
 
926
                        sphereAngleSize=tmp;
 
927
                        needUpdate=true;
 
928
 
 
929
                        break;
 
930
                }
 
931
                case KEY_ANGLE_TEXT_VISIBLE:
 
932
                {
 
933
                        bool tmp;
 
934
                        tmp=(value=="1");
 
935
                        
 
936
                        if(tmp == showAngleText)
 
937
                                return false;
 
938
 
 
939
                        showAngleText=tmp;
 
940
                        needUpdate=true;
 
941
 
 
942
                        break;
 
943
                }
 
944
 
 
945
                case KEY_ANGLE_FORMAT_STRING:
 
946
                {
 
947
                        string preDecimal, postDecimal;
 
948
 
 
949
                        //Must contain only #,[0-9]
 
950
                        if(value.find_first_not_of("#,.0123456789")!=std::string::npos)
 
951
                                return false;
 
952
 
 
953
                        if(value.size())
 
954
                        {
 
955
                                //Must contain 0 or 1 separator.
 
956
                                size_t sepCount;
 
957
                                sepCount=std::count(value.begin(),value.end(),',');
 
958
                                sepCount+=std::count(value.begin(),value.end(),'.');
 
959
                                if(sepCount > 1)
 
960
                                        return false;
 
961
                        
 
962
                                //If we have a separator,
 
963
                                //split into two parts  
 
964
                                if(sepCount)
 
965
                                {       
 
966
                                        size_t decPos;
 
967
                                        decPos=value.find_first_of(",.");
 
968
                                        angleFormatPreDecimal=decPos;
 
969
                                        angleFormatPostDecimal=value.size()-(decPos+1);
 
970
                                }
 
971
                                else
 
972
                                        angleFormatPreDecimal=value.size();
 
973
 
 
974
                        }
 
975
                        else
 
976
                                angleFormatPreDecimal=angleFormatPostDecimal=0;
 
977
                        
 
978
                        needUpdate=true;
 
979
                        break;
 
980
                }
 
981
 
 
982
                case KEY_LINEAR_FONTSIZE:
 
983
                {
 
984
                        unsigned int tmp;
 
985
                        stream_cast(tmp,value);
 
986
 
 
987
                        if(tmp == fontSizeLinearMeasure)
 
988
                                return false;
 
989
 
 
990
                        fontSizeLinearMeasure=tmp;
 
991
                        needUpdate=true;
 
992
                        break;
 
993
                }
 
994
                case KEY_LINEAR_FIXED_TICKS:
 
995
                {
 
996
                        bool tmpTicks;
 
997
 
 
998
                        if(value == "0")
 
999
                                tmpTicks=false;
 
1000
                        else if(value =="1")
 
1001
                                tmpTicks=true;
 
1002
                        else
 
1003
                                return false;
 
1004
 
 
1005
                        if(tmpTicks == linearFixedTicks)
 
1006
                                return false;
 
1007
 
 
1008
                        needUpdate=true;
 
1009
                        linearFixedTicks=tmpTicks;
 
1010
                        break;
 
1011
 
 
1012
                }
 
1013
                case KEY_LINEAR_NUMTICKS:
 
1014
                {
 
1015
                        unsigned int tmp;
 
1016
                        stream_cast(tmp,value);
 
1017
 
 
1018
                        if(tmp == linearMeasureTicks)
 
1019
                                return false;
 
1020
 
 
1021
                        linearMeasureTicks=tmp;
 
1022
                        needUpdate=true;
 
1023
 
 
1024
                        break;
 
1025
                }
 
1026
                case KEY_LINEAR_TICKSPACING:
 
1027
                {
 
1028
                        float tmp;
 
1029
                        stream_cast(tmp,value);
 
1030
 
 
1031
                        if(tmp == linearMeasureSpacing)
 
1032
                                return false;
 
1033
 
 
1034
                        linearMeasureSpacing=tmp;
 
1035
                        needUpdate=true;
 
1036
 
 
1037
                        break;
 
1038
                }
 
1039
                
 
1040
                default:
 
1041
                        ASSERT(false);
 
1042
        }
 
1043
 
 
1044
        return true;
 
1045
}
 
1046
 
 
1047
std::string  AnnotateFilter::getErrString(unsigned int code) const
 
1048
{
 
1049
        ASSERT(false);
 
1050
}
 
1051
 
 
1052
bool AnnotateFilter::writeState(std::ofstream &f,unsigned int format, unsigned int depth) const
 
1053
{
 
1054
        using std::endl;
 
1055
        switch(format)
 
1056
        {
 
1057
                case STATE_FORMAT_XML:
 
1058
                {       
 
1059
                        f << tabs(depth) <<  "<" << trueName() << ">" << endl;
 
1060
                        f << tabs(depth+1) << "<userstring value=\""<<userString << "\"/>"  << endl;
 
1061
 
 
1062
                        f << tabs(depth+1) << "<position value=\""<<position<< "\"/>"  << endl;
 
1063
                        f << tabs(depth+1) << "<target value=\""<<target<< "\"/>"  << endl;
 
1064
                        f << tabs(depth+1) << "<upvec value=\""<<upVec<< "\"/>"  << endl;
 
1065
                        f << tabs(depth+1) << "<acrossvec value=\""<<acrossVec<< "\"/>"  << endl;
 
1066
 
 
1067
                        f << tabs(depth+1) << "<anglepos>" << endl;
 
1068
                        for(unsigned int ui=0;ui<3;ui++)
 
1069
                                f << tabs(depth+2) << "<position value=\""<<anglePos[ui]<< "\"/>"  << endl;
 
1070
                        f << tabs(depth+1) << "</anglepos>" << endl;
 
1071
 
 
1072
 
 
1073
                        f << tabs(depth+1) << "<annotatetext value=\""<<annotateText<< "\"/>"  << endl;
 
1074
                        f << tabs(depth+1) << "<textsize value=\""<<textSize<< "\"/>"  << endl;
 
1075
                        f << tabs(depth+1) << "<annotatesize value=\""<<annotateSize<< "\"/>"  << endl;
 
1076
                        f << tabs(depth+1) << "<sphereanglesize value=\""<<sphereAngleSize<< "\"/>"  << endl;
 
1077
                        std::string colourString;
 
1078
                        genColString((unsigned char)(r*255),(unsigned char)(g*255),
 
1079
                                (unsigned char)(b*255),(unsigned char)(a*255),colourString);
 
1080
                        f << tabs(depth+1) << "<colour value=\""<<colourString<< "\"/>"  << endl;
 
1081
 
 
1082
                        f << tabs(depth+1) << "<active value=\""<<(active? "1" : "0")<< "\"/>"  << endl;
 
1083
                        f << tabs(depth+1) << "<showangletext value=\""<<(showAngleText ? "1" : "0")<< "\"/>"  << endl;
 
1084
                        f << tabs(depth+1) << "<reflexangle value=\""<<(reflexAngle? "1" : "0")<< "\"/>"  << endl;
 
1085
                        
 
1086
                        f << tabs(depth+1) << "<angleformat predecimal=\""<< angleFormatPreDecimal 
 
1087
                                        << "\" postdecimal=\"" << angleFormatPostDecimal<< "\" />" << endl;
 
1088
 
 
1089
                        f << tabs(depth) << "</" <<trueName()<< ">" << endl;
 
1090
                        break;
 
1091
                }
 
1092
                default:
 
1093
                        ASSERT(false);
 
1094
                        return false;
 
1095
        }
 
1096
 
 
1097
        return true;
 
1098
}
 
1099
 
 
1100
bool AnnotateFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFileDir)
 
1101
{
 
1102
        using std::string;
 
1103
        string tmpStr;
 
1104
 
 
1105
        xmlChar *xmlString;
 
1106
 
 
1107
        //Retrieve user string
 
1108
        //===
 
1109
        if(XMLHelpFwdToElem(nodePtr,"userstring"))
 
1110
                return false;
 
1111
 
 
1112
        xmlString=xmlGetProp(nodePtr,(const xmlChar *)"value");
 
1113
        if(!xmlString)
 
1114
                return false;
 
1115
        userString=(char *)xmlString;
 
1116
        xmlFree(xmlString);
 
1117
        //===
 
1118
 
 
1119
        //position
 
1120
        if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"position","value"))
 
1121
                return false;
 
1122
 
 
1123
        if(!parsePointStr(tmpStr,position))
 
1124
                return false;
 
1125
 
 
1126
        if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"target","value"))
 
1127
                return false;
 
1128
 
 
1129
        if(!parsePointStr(tmpStr,target))
 
1130
                return false;
 
1131
        
 
1132
        if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"upvec","value"))
 
1133
                return false;
 
1134
 
 
1135
        if(!parsePointStr(tmpStr,target))
 
1136
                return false;
 
1137
        
 
1138
        if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"acrossvec","value"))
 
1139
                return false;
 
1140
 
 
1141
        if(!parsePointStr(tmpStr,acrossVec))
 
1142
                return false;
 
1143
        
 
1144
        //Ensure acrossVec/upvec orthogonal
 
1145
        if(!upVec.orthogonalise(acrossVec))
 
1146
                return false;
 
1147
 
 
1148
        xmlNodePtr tmpPtr;
 
1149
        tmpPtr=nodePtr;
 
1150
 
 
1151
        if(XMLHelpFwdToElem(nodePtr,"anglepos"))
 
1152
                return false;
 
1153
        
 
1154
        if(!nodePtr->xmlChildrenNode)
 
1155
                return false;
 
1156
        
 
1157
        nodePtr=nodePtr->xmlChildrenNode;
 
1158
 
 
1159
        for(unsigned int ui=0;ui<3;ui++)
 
1160
        {
 
1161
                if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"position","value"))
 
1162
                        return false;
 
1163
 
 
1164
                if(!parsePointStr(tmpStr,anglePos[ui]))
 
1165
                        return false;
 
1166
        }
 
1167
 
 
1168
        nodePtr=tmpPtr;
 
1169
 
 
1170
        //If it fails, thats OK, just use the empty string.     
 
1171
        if(!XMLGetNextElemAttrib(nodePtr,annotateText,"annotatetext","value"))
 
1172
                annotateText="";
 
1173
 
 
1174
        if(!XMLGetNextElemAttrib(nodePtr,textSize,"textsize","value"))
 
1175
                return false;
 
1176
        
 
1177
        if(!XMLGetNextElemAttrib(nodePtr,annotateSize,"annotatesize","value"))
 
1178
                return false;
 
1179
 
 
1180
        if(!XMLGetNextElemAttrib(nodePtr,sphereAngleSize,"sphereanglesize","value"))
 
1181
                return false;
 
1182
 
 
1183
        if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"colour","value"))
 
1184
                return false;
 
1185
        
 
1186
        unsigned char rc,gc,bc,ac;
 
1187
        if(!parseColString(tmpStr,rc,gc,bc,ac))
 
1188
                return false;
 
1189
        r=(float)(rc)/255.0f;
 
1190
        g=(float)(gc)/255.0f;
 
1191
        b=(float)(bc)/255.0f;
 
1192
        a=(float)(ac)/255.0f;
 
1193
 
 
1194
 
 
1195
        if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"active","value"))
 
1196
                return false;
 
1197
 
 
1198
        if(!(tmpStr=="0" || tmpStr=="1"))
 
1199
                return false;
 
1200
 
 
1201
        active = (tmpStr=="1");
 
1202
 
 
1203
        if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"showangletext","value"))
 
1204
                return false;
 
1205
 
 
1206
        if(!(tmpStr=="0" || tmpStr=="1"))
 
1207
                return false;
 
1208
 
 
1209
        showAngleText = (tmpStr=="1");
 
1210
 
 
1211
        if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"reflexangle","value"))
 
1212
                return false;
 
1213
 
 
1214
        if(!(tmpStr=="0" || tmpStr=="1"))
 
1215
                return false;
 
1216
 
 
1217
        reflexAngle = (tmpStr=="1");
 
1218
 
 
1219
        if(!XMLGetNextElemAttrib(nodePtr,angleFormatPreDecimal,"angleformat","predecimal"))
 
1220
                return false;
 
1221
 
 
1222
        if(!XMLGetAttrib(nodePtr,angleFormatPostDecimal,"predecimal"))
 
1223
                return false;
 
1224
 
 
1225
 
 
1226
        return true;
 
1227
}
 
1228
 
 
1229
unsigned int AnnotateFilter::getRefreshBlockMask() const
 
1230
{
 
1231
        return 0;
 
1232
}
 
1233
 
 
1234
unsigned int AnnotateFilter::getRefreshEmitMask() const
 
1235
{
 
1236
        return  STREAM_TYPE_DRAW;
 
1237
}
 
1238
 
 
1239
void AnnotateFilter::setPropFromBinding(const SelectionBinding &b)
 
1240
{
 
1241
        switch(b.getID())
 
1242
        {
 
1243
                case BINDING_ARROW_ORIGIN:
 
1244
                {
 
1245
                        Point3D dv;
 
1246
                        dv=target-position;
 
1247
                        b.getValue(position);
 
1248
                        target=position+dv;
 
1249
                        break;
 
1250
                }
 
1251
                case BINDING_LINEAR_ORIGIN:
 
1252
                case BINDING_TEXT_ORIGIN:
 
1253
                {
 
1254
                        b.getValue(position);
 
1255
                        break;
 
1256
                }
 
1257
                case BINDING_LINEAR_TARGET:
 
1258
                case BINDING_ARROW_VECTOR:
 
1259
                {
 
1260
                        b.getValue(target);
 
1261
                        break;
 
1262
                }
 
1263
                case BINDING_ANGLE_ORIGIN:
 
1264
                        b.getValue(anglePos[0]);
 
1265
                        break;
 
1266
                case BINDING_ANGLE_FIRST:
 
1267
                        b.getValue(anglePos[1]);
 
1268
                        break;
 
1269
                case BINDING_ANGLE_SECOND:
 
1270
                        b.getValue(anglePos[2]);
 
1271
                        break;
 
1272
                case BINDING_ANGLE_SPHERERADIUS:
 
1273
                        b.getValue(sphereAngleSize);
 
1274
                        break;
 
1275
                default:
 
1276
                        ASSERT(false);
 
1277
        }
 
1278
}