1
#include "annotation.h"
3
#include "../xmlHelper.h"
5
//grab size when doing convex hull calculations
6
const unsigned int HULL_GRAB_SIZE=4096;
20
KEY_SPHERE_ANGLE_SIZE,
21
KEY_ANGLE_TEXT_VISIBLE,
22
KEY_ANGLE_FORMAT_STRING,
25
KEY_LINEAR_FIXED_TICKS,
26
KEY_LINEAR_TICKSPACING,
31
BINDING_TEXT_ORIGIN=1,
37
BINDING_ANGLE_SPHERERADIUS,
38
BINDING_LINEAR_ORIGIN,
39
BINDING_LINEAR_TARGET,
40
BINDING_LINEAR_SPHERERADIUS
43
const unsigned int NUM_ANNOTATION_MODES=5;
45
const char *annotationModeStrings[] =
55
AnnotateFilter::AnnotateFilter()
58
annotationMode=ANNOTATION_TEXT;
60
position=Point3D(0,0,0);
61
target=Point3D(1,0,0);
63
acrossVec=Point3D(0,1,0);
65
anglePos[0]=Point3D(0,0,0);
66
anglePos[1]=Point3D(0,5,5);
67
anglePos[2]=Point3D(0,-5,5);
73
//Set the colour to default blue
80
fontSizeLinearMeasure=5;
81
linearMeasureTicks=10;
82
linearFixedTicks=true;
83
linearMeasureSpacing=10.0f;
84
linearMeasureMarkerSize=3.0f;
85
angleFormatPreDecimal=angleFormatPostDecimal=0;
88
cache=true; //By default, we should cache, but decision is made higher up
91
Filter *AnnotateFilter::cloneUncached() const
93
AnnotateFilter *p=new AnnotateFilter();
95
p->annotationMode=annotationMode;
99
p->acrossVec=acrossVec;
101
for(unsigned int ui=0;ui<3; ui++)
102
p->anglePos[ui]=anglePos[ui];
104
p->textSize=textSize;
105
p->annotateSize=annotateSize;
106
p->sphereAngleSize=sphereAngleSize;
114
p->showAngleText=showAngleText;
116
p->reflexAngle=reflexAngle;
118
p->angleFormatPreDecimal=angleFormatPreDecimal;
119
p->angleFormatPostDecimal=angleFormatPostDecimal;
122
p->fontSizeLinearMeasure=fontSizeLinearMeasure;
123
p->linearFixedTicks=linearFixedTicks;
124
p->linearMeasureSpacing=linearMeasureSpacing;
125
p->linearMeasureTicks=linearMeasureTicks;
126
p->linearMeasureMarkerSize=linearMeasureMarkerSize;
128
//We are copying wether to cache or not,
129
//not the cache itself
132
p->userString=userString;
136
unsigned int AnnotateFilter::refresh(const std::vector<const FilterStreamData *> &dataIn,
137
std::vector<const FilterStreamData *> &getOut, ProgressData &progress, bool (*callback)(void))
143
//Pipe everything through
144
getOut.resize(dataIn.size());
145
for(size_t ui=0;ui<dataIn.size();ui++)
146
getOut[ui] = dataIn[ui];
152
d = new DrawStreamData;
155
//Draw text output as needed
156
if( annotationMode == ANNOTATION_TEXT ||
157
annotationMode== ANNOTATION_TEXT_WITH_ARROW)
160
dt = new DrawGLText(getDefaultFontFile().c_str(),FTGL_POLYGON);
162
dt->setString(annotateText);
163
dt->setOrigin(position);
165
dt->setColour(r,g,b,a);
166
dt->setTextDir(acrossVec);
167
dt->setSize(textSize);
169
dt->setAlignment(DRAWTEXT_ALIGN_CENTRE);
172
SelectionDevice<Filter> *s = new SelectionDevice<Filter>(this);
173
SelectionBinding bind[1];
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]);
181
devices.push_back(s);
182
d->drawables.push_back(dt);
185
//Draw annnotation mode as needed
186
if(annotationMode==ANNOTATION_ARROW ||
187
annotationMode==ANNOTATION_TEXT_WITH_ARROW)
192
dv->setOrigin(position);
193
dv->setVector(target-position);
194
dv->setArrowSize(annotateSize);
195
dv->setColour(r,g,b,a);
199
SelectionDevice<Filter> *s = new SelectionDevice<Filter>(this);
200
SelectionBinding bind[2];
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]);
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]);
214
devices.push_back(s);
215
d->drawables.push_back(dv);
218
if(annotationMode == ANNOTATION_ANGLE_MEASURE)
220
//Draw the three spheres that are the handles
221
//for the angle motion
222
for(unsigned int ui=0;ui<3;ui++)
225
SelectionDevice<Filter> *s= new SelectionDevice<Filter>(this);
226
SelectionBinding bind[2];
229
dS->setOrigin(anglePos[ui]);
230
dS->setRadius(sphereAngleSize);
231
dS->setColour(r,g,b,a);
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]);
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());
250
s->addBinding(bind[1]);
252
devices.push_back(s);
253
d->drawables.push_back(dS);
256
//Now draw the two lines that form the angle
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);
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);
273
//indicates the included or reflexive angle
276
std::string angleString;
281
d1=anglePos[1]-anglePos[0];
282
d2=anglePos[2]-anglePos[0];
283
angleVal =d1.angle(d2);
286
angleVal=2.0*M_PI-angleVal;
287
angleVal=180.0f/M_PI*angleVal;
288
angleVal=fmod(angleVal,360.0f);
290
//FIXME: print specifier computation is still a bit off
291
if(angleFormatPreDecimal+angleFormatPostDecimal)
293
//One space for the decimal, one for the null
294
//and the rest for the actual integer
296
num = angleFormatPreDecimal+angleFormatPostDecimal+1;
297
char *buf = new char[num+1];
299
std::string tmp,formatStr;
301
if(angleFormatPreDecimal)
304
stream_cast(tmp,angleFormatPreDecimal + angleFormatPostDecimal+2);
305
formatStr+=std::string("0") + tmp;
308
if(angleFormatPostDecimal)
311
stream_cast(tmp,angleFormatPostDecimal);
317
snprintf(buf,num,formatStr.c_str(),angleVal);
323
stream_cast(angleString, angleVal);
325
//Place the string appropriately
327
dt = new DrawGLText(getDefaultFontFile().c_str(),FTGL_POLYGON);
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
336
averageVec = (d1+d2)*0.5f;
337
averageVec.normalise();
338
averageVec*=textSize*1.1;
341
dt->setOrigin(anglePos[0]+averageVec);
343
//Use user-specifications for colour,
344
//size and orientation
346
dt->setColour(r,g,b,a);
347
dt->setTextDir(acrossVec);
348
dt->setSize(textSize);
351
d->drawables.push_back(dt);
355
if(annotationMode == ANNOTATION_LINEAR_MEASURE)
360
dv->setOrigin(position);
361
dv->setColour(r,g,b,a);
362
dv->setVector(target-position);
364
d->drawables.push_back(dv);
366
//Compute the tick spacings
367
vector<float> tickSpacings;
370
tickSpacingsFromFixedNum(0,sqrt(target.sqrDist(position)),
371
linearMeasureTicks,tickSpacings);
375
tickSpacingsFromInterspace(0,sqrt(target.sqrDist(position)),
376
linearMeasureSpacing,tickSpacings);
379
if(tickSpacings.size())
382
Point3D measureNormal;
383
measureNormal = target-position;
384
measureNormal.normalise();
386
//Construct the drawable text object
388
for(unsigned int ui=0;ui<tickSpacings.size();ui++)
390
//Create the tick that will be added to the drawables
391
dT = new DrawGLText(getDefaultFontFile().c_str(),FTGL_POLYGON);
393
dT->setColour(r,g,b,a);
394
dT->setOrigin(measureNormal*tickSpacings[ui] + position);
396
dT->setTextDir(acrossVec);
397
dT->setSize(fontSizeLinearMeasure);
400
stream_cast(s,tickSpacings[ui]);
404
d->drawables.push_back(dT);
408
//Now draw the end markers
413
dS->setRadius(linearMeasureMarkerSize);
414
dS->setOrigin(position);
415
dS->setColour(r,g,b,a);
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]);
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());
436
s->addBinding(bind[1]);
438
devices.push_back(s);
439
d->drawables.push_back(dS);
442
//Now do the second sphere (end marker)
443
s= new SelectionDevice<Filter>(this);
446
dS->setRadius(linearMeasureMarkerSize);
447
dS->setOrigin(target);
448
dS->setColour(r,g,b,a);
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]);
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]);
466
devices.push_back(s);
467
d->drawables.push_back(dS);
479
size_t AnnotateFilter::numBytesForCache(size_t nObjects) const
485
void AnnotateFilter::getProperties(FilterProperties &propertyList) const
487
vector<unsigned int> type,keys;
488
vector<pair<string,string> > s;
491
vector<pair<unsigned int,string> > choices;
492
string tmpChoice,tmpStr;
494
for(unsigned int ui=0;ui<ANNOTATION_MODE_END; ui++)
496
choices.push_back(make_pair((unsigned int)ui,
497
TRANS(annotationModeStrings[ui])));
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);
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();
510
switch(annotationMode)
512
case ANNOTATION_TEXT:
514
//Note to translators, this is short for "annotation text",
516
s.push_back(make_pair(TRANS("Annotation"),annotateText));
517
type.push_back(PROPERTY_TYPE_STRING);
518
keys.push_back(KEY_ANNOTATE_TEXT);
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);
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);
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);
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);
543
case ANNOTATION_ARROW:
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);
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);
556
case ANNOTATION_TEXT_WITH_ARROW:
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);
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);
569
//Note to translators, this is short for "annotation text",
571
s.push_back(make_pair(TRANS("Annotation"),annotateText));
572
type.push_back(PROPERTY_TYPE_STRING);
573
keys.push_back(KEY_ANNOTATE_TEXT);
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);
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);
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);
591
case ANNOTATION_ANGLE_MEASURE:
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);
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);
604
keys.push_back(KEY_REFLEXIVE);
605
s.push_back(make_pair(TRANS("Reflexive"),reflexAngle? "1":"0"));
606
type.push_back(PROPERTY_TYPE_BOOL);
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);
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);
623
if(angleFormatPreDecimal)
625
tmp2.resize(angleFormatPreDecimal,'#');
629
if(angleFormatPostDecimal)
631
tmp2.resize(angleFormatPostDecimal,'#');
632
tmpStr+=std::string(".") + tmp2;
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);
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);
650
case ANNOTATION_LINEAR_MEASURE:
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);
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);
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);
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);
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);
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);
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);
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);
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);
714
propertyList.data.push_back(s);
715
propertyList.keys.push_back(keys);
716
propertyList.types.push_back(type);
720
bool AnnotateFilter::setProperty( unsigned int set, unsigned int key,
721
const std::string &value, bool &needUpdate)
723
string stripped=stripWhite(value);
728
unsigned int newMode;
730
for(newMode=0;newMode<NUM_ANNOTATION_MODES;newMode++)
732
if(stripped == annotationModeStrings[newMode])
736
if(newMode == NUM_ANNOTATION_MODES)
739
if(newMode!=annotationMode)
741
annotationMode=newMode;
750
//This sets the up direction
751
//which must be normal to the
752
//across direction for the text.
754
//Compute the normal component of acrossVec.
757
//Be careful not to "invert" the text, so it
760
if(!parsePointStr(value,newPt))
764
//Use double-cross-product method
765
//to orthogonalise the two vectors
767
normVec=newPt.crossProd(acrossVec);
769
if(normVec.sqrMag() < std::numeric_limits<float>::epsilon())
772
acrossVec=normVec.crossProd(newPt);
774
ASSERT(acrossVec.sqrMag() > std::numeric_limits<float>::epsilon());
776
if(!(upVec == newPt))
786
//This sets the up direction
787
//which must be normal to the
788
//across direction for the text.
790
//Compute the normal component of acrossVec.
793
//Be careful not to "invert" the text, so it
796
if(!parsePointStr(value,newPt))
800
//Use double-cross-product method
801
//to orthogonalise the two vectors
803
normVec=newPt.crossProd(upVec);
805
if(normVec.sqrMag() < std::numeric_limits<float>::epsilon())
808
upVec=normVec.crossProd(newPt);
810
ASSERT(upVec.sqrMag() > std::numeric_limits<float>::epsilon());
812
if(!(acrossVec == newPt))
823
if(!parsePointStr(value,newPt))
826
if(!(acrossVec == newPt))
837
if(!parsePointStr(value,newPt))
840
if(!(target== newPt))
851
if(stream_cast(tmp,value))
854
if(tmp!=annotateSize)
862
case KEY_ANNOTATE_TEXT:
864
if(value!=annotateText)
874
unsigned char newR,newG,newB,newA;
876
parseColString(value,newR,newG,newB,newA);
878
if(newB != b || newR != r ||
879
newG !=g || newA != a)
895
stream_cast(tmp,value);
896
if(fabs(tmp-textSize) > std::numeric_limits<float>::epsilon()
897
&& tmp > sqrt(std::numeric_limits<float>::epsilon()))
918
case KEY_SPHERE_ANGLE_SIZE:
921
stream_cast(tmp,value);
923
if(tmp == sphereAngleSize)
931
case KEY_ANGLE_TEXT_VISIBLE:
936
if(tmp == showAngleText)
945
case KEY_ANGLE_FORMAT_STRING:
947
string preDecimal, postDecimal;
949
//Must contain only #,[0-9]
950
if(value.find_first_not_of("#,.0123456789")!=std::string::npos)
955
//Must contain 0 or 1 separator.
957
sepCount=std::count(value.begin(),value.end(),',');
958
sepCount+=std::count(value.begin(),value.end(),'.');
962
//If we have a separator,
963
//split into two parts
967
decPos=value.find_first_of(",.");
968
angleFormatPreDecimal=decPos;
969
angleFormatPostDecimal=value.size()-(decPos+1);
972
angleFormatPreDecimal=value.size();
976
angleFormatPreDecimal=angleFormatPostDecimal=0;
982
case KEY_LINEAR_FONTSIZE:
985
stream_cast(tmp,value);
987
if(tmp == fontSizeLinearMeasure)
990
fontSizeLinearMeasure=tmp;
994
case KEY_LINEAR_FIXED_TICKS:
1000
else if(value =="1")
1005
if(tmpTicks == linearFixedTicks)
1009
linearFixedTicks=tmpTicks;
1013
case KEY_LINEAR_NUMTICKS:
1016
stream_cast(tmp,value);
1018
if(tmp == linearMeasureTicks)
1021
linearMeasureTicks=tmp;
1026
case KEY_LINEAR_TICKSPACING:
1029
stream_cast(tmp,value);
1031
if(tmp == linearMeasureSpacing)
1034
linearMeasureSpacing=tmp;
1047
std::string AnnotateFilter::getErrString(unsigned int code) const
1052
bool AnnotateFilter::writeState(std::ofstream &f,unsigned int format, unsigned int depth) const
1057
case STATE_FORMAT_XML:
1059
f << tabs(depth) << "<" << trueName() << ">" << endl;
1060
f << tabs(depth+1) << "<userstring value=\""<<userString << "\"/>" << endl;
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;
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;
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;
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;
1086
f << tabs(depth+1) << "<angleformat predecimal=\""<< angleFormatPreDecimal
1087
<< "\" postdecimal=\"" << angleFormatPostDecimal<< "\" />" << endl;
1089
f << tabs(depth) << "</" <<trueName()<< ">" << endl;
1100
bool AnnotateFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFileDir)
1107
//Retrieve user string
1109
if(XMLHelpFwdToElem(nodePtr,"userstring"))
1112
xmlString=xmlGetProp(nodePtr,(const xmlChar *)"value");
1115
userString=(char *)xmlString;
1120
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"position","value"))
1123
if(!parsePointStr(tmpStr,position))
1126
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"target","value"))
1129
if(!parsePointStr(tmpStr,target))
1132
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"upvec","value"))
1135
if(!parsePointStr(tmpStr,target))
1138
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"acrossvec","value"))
1141
if(!parsePointStr(tmpStr,acrossVec))
1144
//Ensure acrossVec/upvec orthogonal
1145
if(!upVec.orthogonalise(acrossVec))
1151
if(XMLHelpFwdToElem(nodePtr,"anglepos"))
1154
if(!nodePtr->xmlChildrenNode)
1157
nodePtr=nodePtr->xmlChildrenNode;
1159
for(unsigned int ui=0;ui<3;ui++)
1161
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"position","value"))
1164
if(!parsePointStr(tmpStr,anglePos[ui]))
1170
//If it fails, thats OK, just use the empty string.
1171
if(!XMLGetNextElemAttrib(nodePtr,annotateText,"annotatetext","value"))
1174
if(!XMLGetNextElemAttrib(nodePtr,textSize,"textsize","value"))
1177
if(!XMLGetNextElemAttrib(nodePtr,annotateSize,"annotatesize","value"))
1180
if(!XMLGetNextElemAttrib(nodePtr,sphereAngleSize,"sphereanglesize","value"))
1183
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"colour","value"))
1186
unsigned char rc,gc,bc,ac;
1187
if(!parseColString(tmpStr,rc,gc,bc,ac))
1189
r=(float)(rc)/255.0f;
1190
g=(float)(gc)/255.0f;
1191
b=(float)(bc)/255.0f;
1192
a=(float)(ac)/255.0f;
1195
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"active","value"))
1198
if(!(tmpStr=="0" || tmpStr=="1"))
1201
active = (tmpStr=="1");
1203
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"showangletext","value"))
1206
if(!(tmpStr=="0" || tmpStr=="1"))
1209
showAngleText = (tmpStr=="1");
1211
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"reflexangle","value"))
1214
if(!(tmpStr=="0" || tmpStr=="1"))
1217
reflexAngle = (tmpStr=="1");
1219
if(!XMLGetNextElemAttrib(nodePtr,angleFormatPreDecimal,"angleformat","predecimal"))
1222
if(!XMLGetAttrib(nodePtr,angleFormatPostDecimal,"predecimal"))
1229
unsigned int AnnotateFilter::getRefreshBlockMask() const
1234
unsigned int AnnotateFilter::getRefreshEmitMask() const
1236
return STREAM_TYPE_DRAW;
1239
void AnnotateFilter::setPropFromBinding(const SelectionBinding &b)
1243
case BINDING_ARROW_ORIGIN:
1247
b.getValue(position);
1251
case BINDING_LINEAR_ORIGIN:
1252
case BINDING_TEXT_ORIGIN:
1254
b.getValue(position);
1257
case BINDING_LINEAR_TARGET:
1258
case BINDING_ARROW_VECTOR:
1263
case BINDING_ANGLE_ORIGIN:
1264
b.getValue(anglePos[0]);
1266
case BINDING_ANGLE_FIRST:
1267
b.getValue(anglePos[1]);
1269
case BINDING_ANGLE_SECOND:
1270
b.getValue(anglePos[2]);
1272
case BINDING_ANGLE_SPHERERADIUS:
1273
b.getValue(sphereAngleSize);