00001
00003
00004
00005
00006
00007
00008
00010
00011 #include "VP1GuideLineSystems/VP1EtaCone.h"
00012 #include <Inventor/nodes/SoMaterial.h>
00013 #include <Inventor/nodes/SoCone.h>
00014 #include <Inventor/nodes/SoSeparator.h>
00015 #include <Inventor/nodes/SoTranslation.h>
00016 #include <Inventor/nodes/SoRotationXYZ.h>
00017 #include "CLHEP/Units/SystemOfUnits.h"
00018
00019
00020 class VP1EtaCone::Imp {
00021 public:
00022 Imp(VP1EtaCone *,
00023 SoMaterial * mat,
00024 SoSeparator * attachsep);
00025 VP1EtaCone * theclass;
00026 SoMaterial * material;
00027 SoSeparator * attachSep;
00028
00029 bool shown;
00030 double etaval;
00031 double extent;
00032
00033 SoSeparator * sep;
00034 SoCone * cone1;
00035 SoTranslation * trans1;
00036 SoCone * innercone1;
00037 SoTranslation * innertrans1;
00038 SoCone * cone2;
00039 SoTranslation * trans2;
00040 SoCone * innercone2;
00041 SoTranslation * innertrans2;
00042
00043 void updateFields();
00044 void ensureInit3DObjects();
00045 };
00046
00047
00048 VP1EtaCone::VP1EtaCone(SoMaterial * mat,SoSeparator * attachsep,
00049 IVP1System * sys,QObject * parent)
00050 : QObject(parent), VP1HelperClassBase(sys,"VP1EtaCone"), d(new Imp(this,mat,attachsep))
00051 {
00052 }
00053
00054
00055 VP1EtaCone::~VP1EtaCone()
00056 {
00057 setShown(false);
00058 if (d->sep)
00059 d->sep->unref();
00060 d->material->unref();
00061 d->attachSep->unref();
00062 delete d;
00063 }
00064
00065
00066 VP1EtaCone::Imp::Imp(VP1EtaCone *tc,SoMaterial * mat,SoSeparator * as)
00067 : theclass(tc), material(mat), attachSep(as), shown(false),
00068 etaval(1), extent(1), sep(0),
00069 cone1(0), trans1(0), innercone1(0), innertrans1(0),
00070 cone2(0), trans2(0), innercone2(0), innertrans2(0)
00071 {
00072 material->ref();
00073 attachSep->ref();
00074 }
00075
00076
00077 void VP1EtaCone::Imp::ensureInit3DObjects()
00078 {
00079 if (sep)
00080 return;
00081 theclass->messageVerbose("Building 3D objects");
00082 sep = new SoSeparator;
00083 sep->ref();
00084 sep->addChild(material);
00085
00086 SoSeparator * sepfirst = new SoSeparator;
00087 SoSeparator * sepsecond = new SoSeparator;
00088
00089 for ( int i = 0;i<2;++i){
00090 SoRotationXYZ * xf = new SoRotationXYZ();
00091 xf->axis=SoRotationXYZ::X;
00092 xf->angle = i==0 ? 90.0*deg : -90*deg;
00093 SoTranslation * xl = new SoTranslation();
00094 SoCone * cone = new SoCone();
00095 SoTranslation * innerxl = new SoTranslation();
00096 SoCone * innercone = new SoCone();
00097
00098 if (i==0) {
00099 cone1 = cone;
00100 trans1 = xl;
00101 innercone1 = innercone;
00102 innertrans1 = innerxl;
00103 } else {
00104 cone2 = cone;
00105 trans2 = xl;
00106 innercone2 = innercone;
00107 innertrans2 = innerxl;
00108 }
00109
00110 cone->removePart(SoCone::BOTTOM);
00111 innercone->removePart(SoCone::BOTTOM);
00112
00113 SoSeparator * s(i==0?sepfirst:sepsecond);
00114 s->addChild(xf);
00115 s->addChild(xl);
00116 s->addChild(cone);
00117 s->addChild(innerxl);
00118 s->addChild(innercone);
00119 sep->addChild(s);
00120 }
00121 }
00122
00123
00124 void VP1EtaCone::Imp::updateFields()
00125 {
00126 ensureInit3DObjects();
00127 theclass->messageVerbose("Updating fields");
00128
00129 double theta = 2*atan(exp(-fabs(etaval)));
00130 double tanfact = tan(theta);
00131 bool etaconeextentisz = (extent<0);
00132 double absextent = fabs(extent);
00133 double coneHeight,bottomRadius;
00134 if (etaconeextentisz) {
00135 coneHeight = absextent;
00136 bottomRadius = coneHeight*tanfact;
00137 } else {
00138 bottomRadius = absextent;
00139 coneHeight=bottomRadius/tanfact;
00140 }
00141
00142 theclass->messageVerbose("etaval = "+str(etaval));
00143 theclass->messageVerbose("extent = "+str(extent));
00144 theclass->messageVerbose("absextent = "+str(absextent));
00145 theclass->messageVerbose("tanfact = "+str(tanfact));
00146 theclass->messageVerbose("bottomRadius = "+str(bottomRadius));
00147 theclass->messageVerbose("coneHeight = "+str(coneHeight));
00148
00149 cone1->bottomRadius = bottomRadius;
00150 cone1->height = coneHeight;
00151 cone2->bottomRadius = bottomRadius;
00152 cone2->height = coneHeight;
00153 trans1->translation.setValue(0, -coneHeight/2, 0);
00154 trans2->translation.setValue(0, -coneHeight/2, 0);
00155
00156 innercone1->bottomRadius = bottomRadius;
00157 innercone1->height = -coneHeight;
00158 innercone2->bottomRadius = bottomRadius;
00159 innercone2->height = -coneHeight;
00160
00161 const double epsilon = 0.50*mm;
00162 innertrans1->translation.setValue(0, coneHeight/2+1.001*coneHeight/2+epsilon, 0);
00163 innertrans2->translation.setValue(0, coneHeight/2+1.001*coneHeight/2+epsilon, 0);
00164
00165 }
00166
00167
00168 void VP1EtaCone::setShown(bool b)
00169 {
00170 messageVerbose("Signal received: setShown("+str(b)+")");
00171 if (d->shown==b)
00172 return;
00173 d->shown=b;
00174 if (d->shown) {
00175 d->updateFields();
00176 if (d->attachSep->findChild(d->sep)<0)
00177 d->attachSep->addChild(d->sep);
00178 } else {
00179 if (d->sep&&d->attachSep->findChild(d->sep)>=0)
00180 d->attachSep->removeChild(d->sep);
00181 }
00182 }
00183
00184
00185 void VP1EtaCone::setExtent(const double&p)
00186 {
00187 messageVerbose("Signal received: setExtent("+str(p)+")");
00188 if (d->extent==p)
00189 return;
00190 d->extent=p;
00191 if (d->shown)
00192 d->updateFields();
00193 }
00194
00195
00196 void VP1EtaCone::setEtaValue(const double&p)
00197 {
00198 messageVerbose("Signal received: setEtaValue("+str(p)+")");
00199 if (d->etaval==p)
00200 return;
00201 d->etaval=p;
00202 if (d->shown)
00203 d->updateFields();
00204 }