00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00030 #include <Inventor/misc/SoChildList.h>
00031 #include <Inventor/nodes/SoCone.h>
00032 #include <Inventor/nodes/SoCylinder.h>
00033 #include <Inventor/nodes/SoSeparator.h>
00034 #include <Inventor/nodes/SoTransform.h>
00035 #include <Inventor/nodes/SoTranslation.h>
00036
00037 #include <assert.h>
00038 #include <math.h>
00039
00040 #include "SoArrow.h"
00041
00042
00043
00044 #define HAS_PART(arrowHeads, part) (((arrowHeads) & (part)) != 0)
00045
00046 SO_NODE_SOURCE(SoArrow);
00047
00053 void
00054 SoArrow::initClass()
00055 {
00056
00057 SO_NODE_INIT_CLASS(SoArrow, SoComplexShape, "SoComplexShape");
00058 }
00059
00063 SoArrow::SoArrow()
00064 {
00065
00066 children = new SoChildList(this);
00067
00068 SO_NODE_CONSTRUCTOR(SoArrow);
00069 SO_NODE_ADD_FIELD(arrowHeads,(END));
00070 SO_NODE_ADD_FIELD(cylRadius, (0.5));
00071 SO_NODE_ADD_FIELD(height, (4.0));
00072 SO_NODE_ADD_FIELD(coneHeight,(2.0));
00073 SO_NODE_ADD_FIELD(coneRadius,(1.0));
00074
00075
00076
00077 SO_NODE_DEFINE_ENUM_VALUE(Part, NONE);
00078 SO_NODE_DEFINE_ENUM_VALUE(Part, BEGIN);
00079 SO_NODE_DEFINE_ENUM_VALUE(Part, END);
00080 SO_NODE_DEFINE_ENUM_VALUE(Part, BOTH);
00081
00082
00083
00084 SO_NODE_SET_SF_ENUM_TYPE(arrowHeads, Part);
00085 }
00086
00091 SoArrow::~SoArrow()
00092 {
00093 delete children;
00094 }
00095
00099 void
00100 SoArrow::addPart(Part part)
00101 {
00102 arrowHeads.setValue(arrowHeads.getValue() | part);
00103
00104 if (HAS_PART(arrowHeads.getValue(),SoArrow::BEGIN)) {
00105 calEngine->c.setValue(1);
00106 beginSw->whichChild.setValue(SO_SWITCH_ALL);
00107 }
00108 else {
00109 calEngine->c.setValue(0);
00110 beginSw->whichChild.setValue(SO_SWITCH_NONE);
00111 }
00112
00113 if (HAS_PART(arrowHeads.getValue(),SoArrow::END)) {
00114 calEngine->d.setValue(1);
00115 endSw->whichChild.setValue(SO_SWITCH_ALL);
00116 }
00117 else {
00118 calEngine->d.setValue(0);
00119 endSw->whichChild.setValue(SO_SWITCH_NONE);
00120 }
00121
00122 }
00123
00127 void
00128 SoArrow::removePart(Part part)
00129 {
00130 arrowHeads.setValue(arrowHeads.getValue() & ~part);
00131
00132 if (HAS_PART(arrowHeads.getValue(),SoArrow::BEGIN)) {
00133 calEngine->c.setValue(1);
00134 beginSw->whichChild.setValue(SO_SWITCH_ALL);
00135 }
00136 else {
00137 calEngine->c.setValue(0);
00138 beginSw->whichChild.setValue(SO_SWITCH_NONE);
00139 }
00140
00141 if (HAS_PART(arrowHeads.getValue(),SoArrow::END)) {
00142 calEngine->d.setValue(1);
00143 endSw->whichChild.setValue(SO_SWITCH_ALL);
00144 }
00145 else {
00146 calEngine->d.setValue(0);
00147 endSw->whichChild.setValue(SO_SWITCH_NONE);
00148 }
00149
00150 }
00151
00155 SbBool
00156 SoArrow::hasPart(Part part) const
00157 {
00158 return HAS_PART(arrowHeads.getValue(), part);
00159 }
00160
00161
00168 void
00169 SoArrow::generateChildren()
00170 {
00171
00172
00173 assert (children->getLength() == 0);
00174
00175
00176 SoCone *cne = new SoCone;
00177 cne->height.connectFrom(&coneHeight);
00178 cne->bottomRadius.connectFrom(&coneRadius);
00179
00180 SoTransform *beginTran = new SoTransform;
00181 beginTran->rotation.setValue(SbVec3f(1,0,0),(float)M_PI);
00182
00183 SoSeparator *beginSep = new SoSeparator;
00184 beginSep->addChild(beginTran);
00185 beginSep->addChild(cne);
00186 beginSw = new SoSwitch;
00187 beginSw->addChild(beginSep);
00188
00189
00190 SoTranslation *endTran = new SoTranslation;
00191
00192 SoSeparator *endSep = new SoSeparator;
00193 endSep->addChild(endTran);
00194 endSep->addChild(cne);
00195 endSw = new SoSwitch;
00196 endSw->addChild(endSep);
00197
00198
00199 calEngine = new SoCalculator;
00200 calEngine->a.connectFrom(&height);
00201 calEngine->b.connectFrom(&coneHeight);
00202
00203 if (HAS_PART(arrowHeads.getValue(),SoArrow::BEGIN)) {
00204 calEngine->c.setValue(1);
00205 beginSw->whichChild.setValue(SO_SWITCH_ALL);
00206 }
00207 else {
00208 calEngine->c.setValue(0);
00209 beginSw->whichChild.setValue(SO_SWITCH_NONE);
00210 }
00211
00212 if (HAS_PART(arrowHeads.getValue(),SoArrow::END)) {
00213 calEngine->d.setValue(1);
00214 endSw->whichChild.setValue(SO_SWITCH_ALL);
00215 }
00216 else {
00217 calEngine->d.setValue(0);
00218 endSw->whichChild.setValue(SO_SWITCH_NONE);
00219 }
00220
00221
00222 calEngine->expression.set1Value(0, "oa = a - c*b - d*b");
00223
00224
00225 calEngine->expression.set1Value(1, "oA = vec3f(0.0, b/2.0, 0.0)");
00226
00227 calEngine->expression.set1Value(2, "oB = vec3f(0.0, a - b/2.0, 0.0)");
00228
00229 calEngine->expression.set1Value(3, "oC = vec3f(0.0, oa/2.0 + c*b, 0.0)");
00230
00231 beginTran->translation.connectFrom(&calEngine->oA);
00232 endTran->translation.connectFrom(&calEngine->oB);
00233
00234 SoCylinder *shaft = new SoCylinder;
00235 shaft->radius.connectFrom(&cylRadius);
00236 shaft->height.connectFrom(&calEngine->oa);
00237
00238 SoTranslation *shaftTran = new SoTranslation;
00239 shaftTran->translation.connectFrom(&calEngine->oC);
00240
00241 SoSeparator *root = new SoSeparator;
00242 root->addChild(beginSw);
00243 root->addChild(endSw);
00244 root->addChild(shaftTran);
00245 root->addChild(shaft);
00246
00247 children->append(root);
00248 }
00249
00250
00251
00252
00253
00254
00255