00001
00003
00004
00005
00006
00007
00008
00010
00011 #include "VP1GuideLineSystems/VP1Letters.h"
00012 #include "VP1HEPVis/SbPolyhedron.h"
00013 #include "VP1HEPVis/nodes/SoPolyhedron.h"
00014 #include <Inventor/nodes/SoMaterial.h>
00015 #include <Inventor/nodes/SoCube.h>
00016 #include <Inventor/nodes/SoSeparator.h>
00017 #include <Inventor/nodes/SoTranslation.h>
00018 #include <Inventor/nodes/SoRotationXYZ.h>
00019 #include <algorithm>
00020 #include <vector>
00021
00022 #include "CLHEP/Units/SystemOfUnits.h"
00023
00024
00025 class VP1Letters::Imp {
00026 public:
00027 Imp(VP1Letters *,
00028 SoMaterial * mat,
00029 SoSeparator * attachsep);
00030 VP1Letters * theclass;
00031 SoMaterial * material;
00032 SoSeparator * attachSep;
00033
00034 void createLetterAData(std::vector<double>& x, std::vector<double>&y);
00035 void createLetterCData(std::vector<double>& x, std::vector<double>&y);
00036 void normalizeLetterData(std::vector<double>& x, std::vector<double>&y,double yheight);
00037 SoNode * createLetter(const std::vector<double>& x, const std::vector<double>y);
00038
00039 bool shown;
00040 double zpos;
00041 double vertpos;
00042
00043 SoSeparator * sep;
00044 SoTranslation * transA;
00045 SoTranslation * transC;
00046
00047 void updateFields();
00048 void ensureInit3DObjects();
00049 };
00050
00051
00052 VP1Letters::VP1Letters(SoMaterial * mat,SoSeparator * attachsep,
00053 IVP1System * sys,QObject * parent)
00054 : QObject(parent), VP1HelperClassBase(sys,"VP1Letters"), d(new Imp(this,mat,attachsep))
00055 {
00056 }
00057
00058
00059 VP1Letters::~VP1Letters()
00060 {
00061 setShown(false);
00062 if (d->sep)
00063 d->sep->unref();
00064 if (d->transA)
00065 d->transA->unref();
00066 if (d->transC)
00067 d->transC->unref();
00068 d->material->unref();
00069 d->attachSep->unref();
00070 delete d;
00071 }
00072
00073
00074 VP1Letters::Imp::Imp(VP1Letters *tc,SoMaterial * mat,SoSeparator * as)
00075 : theclass(tc), material(mat), attachSep(as), shown(false),
00076 zpos(0),vertpos(0), sep(0), transA(0), transC(0)
00077 {
00078 material->ref();
00079 attachSep->ref();
00080 }
00081
00082
00083
00084 void VP1Letters::Imp::createLetterAData(std::vector<double>& x, std::vector<double>&y) {
00085
00086 x.clear();
00087 y.clear();
00088 x.push_back(294.15418); y.push_back(175.81259);
00089 x.push_back(230.15085); y.push_back(349.36906);
00090 x.push_back(358.39109); y.push_back(349.36906);
00091 x.push_back(294.15418); y.push_back(175.81259);
00092 x.push_back(267.52506); y.push_back(129.32842);
00093 x.push_back(321.01689); y.push_back(129.32842);
00094 x.push_back(453.92891); y.push_back(478.07648);
00095 x.push_back(404.87526); y.push_back(478.07648);
00096 x.push_back(373.10719); y.push_back(388.61197);
00097 x.push_back(215.90194); y.push_back(388.61197);
00098 x.push_back(184.13386); y.push_back(478.07648);
00099 x.push_back(134.37945); y.push_back(478.07648);
00100 x.push_back(267.52506); y.push_back(129.32842);
00101 }
00102
00103
00104 void VP1Letters::Imp::createLetterCData(std::vector<double>& x, std::vector<double>&y) {
00105
00106 x.clear();
00107 y.clear();
00108 x.push_back(666.70068); y.push_back(278.58533);
00109 x.push_back(668.72098); y.push_back(165.44825);
00110 x.push_back(591.94939); y.push_back(127.06245);
00111 x.push_back(496.99505); y.push_back(98.77818);
00112 x.push_back(400.02041); y.push_back(94.73757);
00113 x.push_back(299.00515); y.push_back(108.87971);
00114 x.push_back(224.25386); y.push_back(145.2452);
00115 x.push_back(149.50258); y.push_back(201.81374);
00116 x.push_back(92.934034); y.push_back(280.60564);
00117 x.push_back(56.568543); y.push_back(379.60059);
00118 x.push_back(46.467017); y.push_back(486.67676);
00119 x.push_back(52.527932); y.push_back(591.73262);
00120 x.push_back(76.771593); y.push_back(682.64635);
00121 x.push_back(109.09647); y.push_back(741.2352);
00122 x.push_back(145.46197); y.push_back(783.66161);
00123 x.push_back(189.90868); y.push_back(830.12862);
00124 x.push_back(248.49753); y.push_back(864.47381);
00125 x.push_back(327.28942); y.push_back(886.69717);
00126 x.push_back(406.08132); y.push_back(898.819);
00127 x.push_back(454.56865); y.push_back(898.819);
00128 x.push_back(523.25902); y.push_back(886.69717);
00129 x.push_back(600.03061); y.push_back(858.41289);
00130 x.push_back(646.49763); y.push_back(838.20984);
00131 x.push_back(668.72098); y.push_back(818.00679);
00132 x.push_back(666.70068); y.push_back(710.93062);
00133 x.push_back(616.19305); y.push_back(751.33672);
00134 x.push_back(555.5839); y.push_back(785.68191);
00135 x.push_back(484.87322); y.push_back(807.90527);
00136 x.push_back(430.32498); y.push_back(809.92557);
00137 x.push_back(379.81736); y.push_back(807.90527);
00138 x.push_back(317.1879); y.push_back(791.74283);
00139 x.push_back(280.82241); y.push_back(775.58039);
00140 x.push_back(248.49753); y.push_back(749.31642);
00141 x.push_back(214.15234); y.push_back(710.93062);
00142 x.push_back(175.76654); y.push_back(652.34177);
00143 x.push_back(159.6041); y.push_back(565.46866);
00144 x.push_back(155.56349); y.push_back(480.61584);
00145 x.push_back(161.62441); y.push_back(401.82394);
00146 x.push_back(189.90868); y.push_back(314.95082);
00147 x.push_back(242.43661); y.push_back(242.21984);
00148 x.push_back(301.02546); y.push_back(203.83404);
00149 x.push_back(361.63461); y.push_back(181.61069);
00150 x.push_back(426.28437); y.push_back(177.57008);
00151 x.push_back(511.13719); y.push_back(187.6716);
00152 x.push_back(587.90878); y.push_back(217.97618);
00153 x.push_back(644.47732); y.push_back(258.38228);
00154
00155 std::reverse(x.begin(), x.end());
00156 std::reverse(y.begin(), y.end());
00157 }
00158
00159
00160 void VP1Letters::Imp::normalizeLetterData(std::vector<double>& x, std::vector<double>&y,double yheight)
00161 {
00162
00163 if (x.size()!=y.size()) {
00164 theclass->message("normalizeLetterData Error: Input vectors have different length!");
00165 return;
00166 }
00167
00168 unsigned n = x.size();
00169
00170 double xmin(1e20),xmax(-1e20),ymin(1e20),ymax(-1e20);
00171 for (unsigned i = 0; i<n;++i) {
00172 if (x.at(i)<xmin) xmin = x.at(i);
00173 if (x.at(i)>xmax) xmax = x.at(i);
00174 if (y.at(i)<ymin) ymin = y.at(i);
00175 if (y.at(i)>ymax) ymax = y.at(i);
00176 }
00177
00178 assert(ymax>ymin&&xmax>xmin);
00179
00180 double scale=yheight/(ymax-ymin);
00181 double xoffset=-xmin-0.5*(xmax-xmin);
00182 for (unsigned i = 0; i<n;++i) {
00183 x.at(i) = (x.at(i)+xoffset)*scale;
00184 y.at(i) = (y.at(i)-ymin)*scale-0.5*yheight;
00185 }
00186
00187 }
00188
00189
00190 SoNode * VP1Letters::Imp::createLetter(const std::vector<double>& x, const std::vector<double>y) {
00191 if (x.size()!=y.size()) {
00192 theclass->message("createLetter Error: Input vectors have different length!");
00193 return new SoCube;
00194 }
00195
00196 SoPolyhedron::initClass();
00197
00198
00199 SoPolyhedron * poly = new SoPolyhedron(SbPolyhedronPolygonXSect(x,y,0.3*m));
00200 return poly;
00201 }
00202
00203
00204 void VP1Letters::Imp::ensureInit3DObjects()
00205 {
00206 if (sep)
00207 return;
00208 theclass->messageVerbose("Building 3D objects");
00209 sep = new SoSeparator; sep->ref();
00210 sep->addChild(material);
00211
00212
00213 std::vector<double> x,y;
00214 createLetterAData(x,y);
00215 normalizeLetterData(x,y,2*m);
00216 SoNode * letterA = createLetter(x,y);
00217 createLetterCData(x,y);
00218 normalizeLetterData(x,y,2*m);
00219 SoNode * letterC = createLetter(x,y);
00220
00221 transA = new SoTranslation;
00222 transA->ref();
00223 transC = new SoTranslation;
00224 transC->ref();
00225
00226 SoRotationXYZ * xf = new SoRotationXYZ();
00227 xf->axis=SoRotationXYZ::Z;
00228 xf->angle = 180*deg;
00229
00230 sep->addChild(transC);
00231 sep->addChild(letterC);
00232 sep->addChild(transA);
00233 sep->addChild(xf);
00234 sep->addChild(letterA);
00235 }
00236
00237
00238 void VP1Letters::Imp::updateFields()
00239 {
00240 ensureInit3DObjects();
00241 theclass->messageVerbose("Updating fields");
00242 transA->translation.setValue(0, 0, 2*zpos);
00243 transC->translation.setValue(0, vertpos, -zpos);
00244 }
00245
00246
00247 void VP1Letters::setShown(bool b)
00248 {
00249 messageVerbose("Signal received: setShown("+str(b)+")");
00250 if (d->shown==b)
00251 return;
00252 d->shown=b;
00253 if (d->shown) {
00254 d->updateFields();
00255 if (d->attachSep->findChild(d->sep)<0)
00256 d->attachSep->addChild(d->sep);
00257 } else {
00258 if (d->sep&&d->attachSep->findChild(d->sep)>=0)
00259 d->attachSep->removeChild(d->sep);
00260 }
00261 }
00262
00263
00264 void VP1Letters::setZPos(const double&p)
00265 {
00266 messageVerbose("Signal received: setZPos("+str(p)+")");
00267 if (d->zpos==p)
00268 return;
00269 d->zpos=p;
00270 if (d->shown)
00271 d->updateFields();
00272 }
00273
00274
00275 void VP1Letters::setVerticalPosition(const double&p)
00276 {
00277 messageVerbose("Signal received: setVerticalPosition("+str(p)+")");
00278 if (d->vertpos==p)
00279 return;
00280 d->vertpos=p;
00281 if (d->shown)
00282 d->updateFields();
00283 }