00001
00003
00004
00005
00006
00007
00008
00010
00011 #include "VP1GuideLineSystems/VP1CoordinateAxes.h"
00012 #include <Inventor/nodes/SoMaterial.h>
00013 #include <Inventor/nodes/SoSeparator.h>
00014 #include <Inventor/nodes/SoCylinder.h>
00015 #include <Inventor/nodes/SoCone.h>
00016 #include <Inventor/nodes/SoTranslation.h>
00017 #include <Inventor/nodes/SoRotationXYZ.h>
00018
00019
00020 class VP1CoordinateAxes::Imp {
00021 public:
00022 Imp(VP1CoordinateAxes *,
00023 SoMaterial * xmat,
00024 SoMaterial * ymat,
00025 SoMaterial * zmat,
00026 SoSeparator * attachsep);
00027 VP1CoordinateAxes * theclass;
00028 SoMaterial * materialXAxis;
00029 SoMaterial * materialYAxis;
00030 SoMaterial * materialZAxis;
00031 SoSeparator * attachSep;
00032
00033 bool shown;
00034 SbVec3f origo;
00035 double axislength;
00036 double relaxisthick;
00037
00038 SoSeparator * sep;
00039 SoTranslation * overall_translation;
00040 SoSeparator * singleaxis_sep;
00041 SoCylinder * singleaxis_cyl;
00042 SoCone * singleaxis_cone;
00043 SoTranslation * singleaxis_cyltranslation;
00044 SoTranslation * singleaxis_conetranslation;
00045
00046 void updateFields();
00047 void ensureInit3DObjects();
00048 };
00049
00050
00051 VP1CoordinateAxes::VP1CoordinateAxes(SoMaterial * xmat,SoMaterial * ymat,SoMaterial * zmat,
00052 SoSeparator * attachsep,
00053 IVP1System * sys,QObject * parent)
00054 : QObject(parent), VP1HelperClassBase(sys,"VP1CoordinateAxes"), d(new Imp(this,xmat,ymat,zmat,attachsep))
00055 {
00056 }
00057
00058
00059 VP1CoordinateAxes::~VP1CoordinateAxes()
00060 {
00061 setShown(false);
00062 if (d->sep)
00063 d->sep->unref();
00064 if (d->singleaxis_sep)
00065 d->singleaxis_sep->unref();
00066 d->materialXAxis->unref();
00067 d->materialYAxis->unref();
00068 d->materialZAxis->unref();
00069 d->attachSep->unref();
00070 delete d;
00071 }
00072
00073
00074 VP1CoordinateAxes::Imp::Imp(VP1CoordinateAxes *tc,SoMaterial * xmat,SoMaterial * ymat,SoMaterial * zmat,SoSeparator * as)
00075 : theclass(tc), materialXAxis(xmat), materialYAxis(ymat), materialZAxis(zmat), attachSep(as), shown(false),
00076 origo(SbVec3f(0,0,0)), axislength(1), relaxisthick(0.1),
00077 sep(0), overall_translation(0), singleaxis_sep(0), singleaxis_cyl(0),
00078 singleaxis_cone(0), singleaxis_cyltranslation(0), singleaxis_conetranslation(0)
00079 {
00080 materialXAxis->ref();
00081 materialYAxis->ref();
00082 materialZAxis->ref();
00083 attachSep->ref();
00084 }
00085
00086
00087 void VP1CoordinateAxes::Imp::ensureInit3DObjects()
00088 {
00089 if (sep)
00090 return;
00091 theclass->messageVerbose("Building 3D objects");
00092 sep = new SoSeparator; sep->ref();
00093
00094 singleaxis_sep = new SoSeparator; singleaxis_sep->ref();
00095 singleaxis_cyltranslation = new SoTranslation; singleaxis_sep->addChild(singleaxis_cyltranslation);
00096 singleaxis_cyl = new SoCylinder; singleaxis_sep->addChild(singleaxis_cyl);
00097 singleaxis_conetranslation = new SoTranslation; singleaxis_sep->addChild(singleaxis_conetranslation);
00098 singleaxis_cone = new SoCone; singleaxis_sep->addChild(singleaxis_cone);
00099
00100 overall_translation = new SoTranslation;
00101
00102 sep->addChild(overall_translation);
00103 sep->addChild(materialYAxis);
00104 sep->addChild(singleaxis_sep);
00105
00106 SoRotationXYZ * rotx = new SoRotationXYZ;
00107 rotx->axis.setValue(SoRotationXYZ::Z);
00108 rotx->angle.setValue(-0.5*M_PI);
00109 sep->addChild(rotx);
00110
00111 sep->addChild(materialXAxis);
00112 sep->addChild(singleaxis_sep);
00113
00114
00115 SoRotationXYZ * rotz = new SoRotationXYZ;
00116 rotz->axis.setValue(SoRotationXYZ::X);
00117 rotz->angle.setValue(0.5*M_PI);
00118 sep->addChild(rotz);
00119
00120 sep->addChild(materialZAxis);
00121 sep->addChild(singleaxis_sep);
00122
00123 singleaxis_cyl->parts.setValue(SoCylinder::SIDES|SoCylinder::BOTTOM);
00124 }
00125
00126
00127 void VP1CoordinateAxes::Imp::updateFields()
00128 {
00129 ensureInit3DObjects();
00130 theclass->messageVerbose("Updating fields");
00131
00132 const bool save = sep->enableNotify(false);
00133
00134 const double cylradius = relaxisthick*fabs(axislength);
00135 const double coneradius = 1.5*cylradius;
00136 const double coneheight = 2.0*coneradius;
00137 overall_translation->translation.setValue(origo);
00138
00139 singleaxis_cyltranslation->translation.setValue(0.0,(axislength<0?0.0:0.5*fabs(axislength))-0.5*coneheight,0.0);
00140 singleaxis_cyl->radius.setValue(cylradius);
00141 singleaxis_cyl->height.setValue( (axislength<0 ? 2.0 : 1.0) * fabs(axislength) - coneheight );
00142 singleaxis_conetranslation->translation.setValue(0.0,(axislength<0?1.0:0.5)*fabs(axislength),0.0);
00143 singleaxis_cone->bottomRadius.setValue(coneradius);
00144 singleaxis_cone->height.setValue(coneheight);
00145
00146 if (save) {
00147 sep->enableNotify(true);
00148 sep->touch();
00149 }
00150 }
00151
00152
00153 void VP1CoordinateAxes::setShown(bool b)
00154 {
00155 messageVerbose("Signal received: setShown("+str(b)+")");
00156 if (d->shown==b)
00157 return;
00158 d->shown=b;
00159 if (d->shown) {
00160 d->updateFields();
00161 if (d->attachSep->findChild(d->sep)<0)
00162 d->attachSep->addChild(d->sep);
00163 } else {
00164 if (d->sep&&d->attachSep->findChild(d->sep)>=0)
00165 d->attachSep->removeChild(d->sep);
00166 }
00167 }
00168
00169
00170 void VP1CoordinateAxes::setPosition(const SbVec3f& o)
00171 {
00172 messageVerbose("Signal received: setPosition("+str(o)+")");
00173 if (d->origo==o)
00174 return;
00175 d->origo=o;
00176 if (d->shown)
00177 d->updateFields();
00178 }
00179
00180
00181
00182 void VP1CoordinateAxes::setLength(const double&l)
00183 {
00184 messageVerbose("Signal received: setLength("+str(l)+")");
00185 if (d->axislength==l)
00186 return;
00187 d->axislength=l;
00188 if (d->shown)
00189 d->updateFields();
00190 }
00191
00192
00193 void VP1CoordinateAxes::setRelativeAxisThickness(const double& t)
00194 {
00195 messageVerbose("Signal received: setRelativeAxisThickness("+str(t)+")");
00196 if (d->relaxisthick==t)
00197 return;
00198 d->relaxisthick=t;
00199 if (d->shown)
00200 d->updateFields();
00201 }