示例#1
0
void
SoHandleBoxDragger::updateArrows(void)
{
  int i;
  SbString str;
  SoSwitch *sw;

  if (this->constraintState >= CONSTRAINT_X) {
    int onval = -1;
    switch (this->constraintState) {
    case CONSTRAINT_X:
      onval = 3;
      break;
    case CONSTRAINT_Y:
      onval = 1;
      break;
    case CONSTRAINT_Z:
      onval = 5;
      break;
    }
    for (i = 1; i <= 6; i++) {
      str.sprintf("arrow%dSwitch", i);
      sw = SO_GET_ANY_PART(this, str.getString(), SoSwitch);
      if (i == onval || i == onval + 1) {
        SoInteractionKit::setSwitchValue(sw, 0);
      }
      else {
        SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
      }
    }
  }
  else if (this->whatkind == WHATKIND_TRANSLATOR) {
    int num = (this->whatnum-1) & ~1;
    for (i = 0; i < 6; i++) {
      str.sprintf("arrow%dSwitch", i+1);
      sw = SO_GET_ANY_PART(this, str.getString(), SoSwitch);
      if (i == num || i == num+1) {
        SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
      }
      else {
        SoInteractionKit::setSwitchValue(sw, 0);
      }
    }
  }
  else {
    for (i = 1; i <= 6; i++) {
      str.sprintf("arrow%dSwitch", i);
      sw = SO_GET_ANY_PART(this, str.getString(), SoSwitch);
      SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
    }
  }
}
void TranslateRadialDragger::
dragFinish()
{
  // Display inactive versions of parts...
  SoSwitch *sw;
  sw = SO_GET_ANY_PART(this, "translatorSwitch", SoSwitch);
  setSwitchValue(sw, 0);
  sw = SO_GET_ANY_PART(this, "feedbackSwitch", SoSwitch);
  setSwitchValue(sw, 0);

  // Get rid of the "feedbackRotate" part.  We don't need
  // it since we aren't showing the feedback any more.
  setAnyPart("feedbackRotate", NULL);
}
/*!
  \DRAGGER_CONSTRUCTOR

  \NODEKIT_PRE_DIAGRAM

  \verbatim
  CLASS SoRotateSphericalDragger
  -->"this"
        "callbackList"
        "topSeparator"
           "motionMatrix"
           "geomSeparator"
  -->         "rotatorSwitch"
  -->            "rotator"
  -->            "rotatorActive"
  -->         "feedbackSwitch"
  -->            "feedback"
  -->            "feedbackActive"
  \endverbatim

  \NODEKIT_POST_DIAGRAM


  \NODEKIT_PRE_TABLE

  \verbatim
  CLASS SoRotateSphericalDragger
  PVT   "this",  SoRotateSphericalDragger  ---
        "callbackList",  SoNodeKitListPart [ SoCallback, SoEventCallback ]
  PVT   "topSeparator",  SoSeparator  ---
  PVT   "motionMatrix",  SoMatrixTransform  ---
  PVT   "geomSeparator",  SoSeparator  ---
  PVT   "rotatorSwitch",  SoSwitch  ---
        "rotator",  SoSeparator  ---
        "rotatorActive",  SoSeparator  ---
  PVT   "feedbackSwitch",  SoSwitch  ---
        "feedback",  SoSeparator  ---
        "feedbackActive",  SoSeparator  ---
  \endverbatim

  \NODEKIT_POST_TABLE
*/
SoRotateSphericalDragger::SoRotateSphericalDragger(void)
{
  SO_KIT_INTERNAL_CONSTRUCTOR(SoRotateSphericalDragger);

  SO_KIT_ADD_CATALOG_ENTRY(rotatorSwitch, SoSwitch, TRUE, geomSeparator, feedbackSwitch, FALSE);
  SO_KIT_ADD_CATALOG_ENTRY(rotator, SoSeparator, TRUE, rotatorSwitch, rotatorActive, TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(rotatorActive, SoSeparator, TRUE, rotatorSwitch, "", TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(feedbackSwitch, SoSwitch, TRUE, geomSeparator, "", FALSE);
  SO_KIT_ADD_CATALOG_ENTRY(feedback, SoSeparator, TRUE, feedbackSwitch, feedbackActive, TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(feedbackActive, SoSeparator, TRUE, feedbackSwitch, "", TRUE);

  if (SO_KIT_IS_FIRST_INSTANCE()) {
    SoInteractionKit::readDefaultParts("rotateSphericalDragger.iv",
                                       ROTATESPHERICALDRAGGER_draggergeometry,
                                       static_cast<int>(strlen(ROTATESPHERICALDRAGGER_draggergeometry)));
  }

  SO_KIT_ADD_FIELD(rotation, (SbRotation(SbVec3f(0.0f, 0.0f, 1.0f), 0.0f)));
  SO_KIT_INIT_INSTANCE();

  // initialize default parts
  this->setPartAsDefault("rotator", "rotateSphericalRotator");
  this->setPartAsDefault("rotatorActive", "rotateSphericalRotatorActive");
  this->setPartAsDefault("feedback", "rotateSphericalFeedback");
  this->setPartAsDefault("feedbackActive", "rotateSphericalFeedbackActive");

  // initialize swich values
  SoSwitch *sw;
  sw = SO_GET_ANY_PART(this, "rotatorSwitch", SoSwitch);
  SoInteractionKit::setSwitchValue(sw, 0);
  sw = SO_GET_ANY_PART(this, "feedbackSwitch", SoSwitch);
  SoInteractionKit::setSwitchValue(sw, 0);

  // setup projector
  this->sphereProj = new SbSpherePlaneProjector();
  this->userProj = FALSE;
  this->addStartCallback(SoRotateSphericalDragger::startCB);
  this->addMotionCallback(SoRotateSphericalDragger::motionCB);
  this->addFinishCallback(SoRotateSphericalDragger::doneCB);

  this->addValueChangedCallback(SoRotateSphericalDragger::valueChangedCB);

  this->fieldSensor = new SoFieldSensor(SoRotateSphericalDragger::fieldSensorCB, this);
  this->fieldSensor->setPriority(0);

  this->setUpConnections(TRUE, TRUE);
}
示例#4
0
/*!
  \DRAGGER_CONSTRUCTOR

  \NODEKIT_PRE_DIAGRAM

  \verbatim
  CLASS SoScale2Dragger
  -->"this"
        "callbackList"
        "topSeparator"
           "motionMatrix"
           "geomSeparator"
  -->         "scalerSwitch"
  -->            "scaler"
  -->            "scalerActive"
  -->         "feedbackSwitch"
  -->            "feedback"
  -->            "feedbackActive"
  \endverbatim

  \NODEKIT_POST_DIAGRAM


  \NODEKIT_PRE_TABLE

  \verbatim
  CLASS SoScale2Dragger
  PVT   "this",  SoScale2Dragger  --- 
        "callbackList",  SoNodeKitListPart [ SoCallback, SoEventCallback ] 
  PVT   "topSeparator",  SoSeparator  --- 
  PVT   "motionMatrix",  SoMatrixTransform  --- 
  PVT   "geomSeparator",  SoSeparator  --- 
  PVT   "scalerSwitch",  SoSwitch  --- 
        "scaler",  SoSeparator  --- 
        "scalerActive",  SoSeparator  --- 
  PVT   "feedbackSwitch",  SoSwitch  --- 
        "feedback",  SoSeparator  --- 
        "feedbackActive",  SoSeparator  --- 
  \endverbatim

  \NODEKIT_POST_TABLE
*/
SoScale2Dragger::SoScale2Dragger(void)
{
  SO_KIT_INTERNAL_CONSTRUCTOR(SoScale2Dragger);

  SO_KIT_ADD_CATALOG_ENTRY(scalerSwitch, SoSwitch, TRUE, geomSeparator, feedbackSwitch, FALSE);
  SO_KIT_ADD_CATALOG_ENTRY(scaler, SoSeparator, TRUE, scalerSwitch, scalerActive, TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(scalerActive, SoSeparator, TRUE, scalerSwitch, "", TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(feedbackSwitch, SoSwitch, TRUE, geomSeparator, "", FALSE);
  SO_KIT_ADD_CATALOG_ENTRY(feedback, SoSeparator, TRUE, feedbackSwitch, feedbackActive, TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(feedbackActive, SoSeparator, TRUE, feedbackSwitch, "", TRUE);

  if (SO_KIT_IS_FIRST_INSTANCE()) {
    SoInteractionKit::readDefaultParts("scale2Dragger.iv",
                                       SCALE2DRAGGER_draggergeometry,
                                       static_cast<int>(strlen(SCALE2DRAGGER_draggergeometry)));
  }

  SO_KIT_ADD_FIELD(scaleFactor, (1.0f, 1.0f, 1.0f));
  SO_KIT_INIT_INSTANCE();

  // initialize default parts
  this->setPartAsDefault("scaler", "scale2Scaler");
  this->setPartAsDefault("scalerActive", "scale2ScalerActive");
  this->setPartAsDefault("feedback", "scale2Feedback");
  this->setPartAsDefault("feedbackActive", "scale2FeedbackActive");

  // initialize swich values
  SoSwitch *sw;
  sw = SO_GET_ANY_PART(this, "scalerSwitch", SoSwitch);
  SoInteractionKit::setSwitchValue(sw, 0);
  sw = SO_GET_ANY_PART(this, "feedbackSwitch", SoSwitch);
  SoInteractionKit::setSwitchValue(sw, 0);

  // setup projector
  this->planeProj = new SbPlaneProjector();
  this->addStartCallback(SoScale2Dragger::startCB);
  this->addMotionCallback(SoScale2Dragger::motionCB);
  this->addFinishCallback(SoScale2Dragger::finishCB);

  this->addValueChangedCallback(SoScale2Dragger::valueChangedCB);

  this->fieldSensor = new SoFieldSensor(SoScale2Dragger::fieldSensorCB, this);
  this->fieldSensor->setPriority(0);

  this->setUpConnections(TRUE, TRUE);
}
示例#5
0
void
SoHandleBoxDragger::updateSwitches(void)
{
  int i;
  SbString str;
  SoSwitch *sw;

  if (this->whatkind == WHATKIND_UNIFORM) {
    if (this->ctrlDown) {
      const int *ptr = uniform_ctrl_lookup[this->whatnum-1];
      for (i = 0; i < 6; i++) {
        str.sprintf("extruder%dSwitch", ptr[i]);
        sw = SO_GET_ANY_PART(this, str.getString(), SoSwitch);
        SoInteractionKit::setSwitchValue(sw, i < 3 ? 1 : 0);
      }
    }
    else {
      for (i = 1; i <= 6; i++) {
        str.sprintf("extruder%dSwitch", i);
        sw = SO_GET_ANY_PART(this, str.getString(), SoSwitch);
        SoInteractionKit::setSwitchValue(sw, 1);
      }
    }
    str.sprintf("uniform%dSwitch", this->whatnum);
    sw = SO_GET_ANY_PART(this, str.getString(), SoSwitch);
    SoInteractionKit::setSwitchValue(sw, 1);
  }
  else if (this->whatkind == WHATKIND_EXTRUDER) {
    int othernum = ((this->whatnum-1) & ~1) + 1;
    if (othernum == this->whatnum) othernum++;

    str.sprintf("extruder%dSwitch", this->whatnum);
    sw = SO_GET_ANY_PART(this, str.getString(), SoSwitch);
    SoInteractionKit::setSwitchValue(sw, 1);
    str.sprintf("extruder%dSwitch", othernum);
    sw = SO_GET_ANY_PART(this, str.getString(), SoSwitch);
    SoInteractionKit::setSwitchValue(sw, this->ctrlDown ? 0 : 1);
  }
  else {
    this->setAllPartsActive(TRUE);
    this->updateArrows();
  }
}
void TranslateRadialDragger::
dragStart()
{
  // Display the 'active' parts...
  SoSwitch *sw;
  sw = SO_GET_ANY_PART(this, "translatorSwitch", SoSwitch);
  setSwitchValue(sw, 1);
  sw = SO_GET_ANY_PART(this, "feedbackSwitch", SoSwitch);
  setSwitchValue(sw, 1);

  // Establish the projector line.
  // The direction of translation goes from the center of the
  // dragger toward the point that was hit, in local space.
  // For the center, use (0,0,0).
  SbVec3f startLocalHitPt = getLocalStartingPoint();
  lineProj->setLine(SbLine(SbVec3f(0, 0, 0), startLocalHitPt));

  // orient the feedback geometry.
  orientFeedbackGeometry(startLocalHitPt);
}
示例#7
0
/*!
  Sets values for the internal SoSwitch parts. If \a activechild ==
  \c NULL, all feedback is deactivated.
*/
void
SoCenterballDragger::setSwitches(SoDragger * activechild)
{
  SoSwitch *sw;

  if (activechild == NULL || coin_safe_cast<SoNode *>(activechild) == rotator.getValue()) {
    // special feedback when rotator is activated/deactiveated
    int switchval = activechild != NULL ? 1 : 0;
    sw = SO_GET_ANY_PART(this, "XCenterChanger.translatorSwitch", SoSwitch);
    SoInteractionKit::setSwitchValue(sw, switchval);;
    sw = SO_GET_ANY_PART(this, "YCenterChanger.translatorSwitch", SoSwitch);
    SoInteractionKit::setSwitchValue(sw, switchval);;
    sw = SO_GET_ANY_PART(this, "ZCenterChanger.translatorSwitch", SoSwitch);
    SoInteractionKit::setSwitchValue(sw, switchval);;
    sw = SO_GET_ANY_PART(this, "XRotator.rotatorSwitch", SoSwitch);
    SoInteractionKit::setSwitchValue(sw, switchval);;
    sw = SO_GET_ANY_PART(this, "YRotator.rotatorSwitch", SoSwitch);
    SoInteractionKit::setSwitchValue(sw, switchval);;
    sw = SO_GET_ANY_PART(this, "ZRotator.rotatorSwitch", SoSwitch);
    SoInteractionKit::setSwitchValue(sw, switchval);;
  }

  // internal feedback
  int vals[3] = { SO_SWITCH_NONE, SO_SWITCH_NONE, SO_SWITCH_NONE };

  if (coin_safe_cast<SoNode *>(activechild) == XRotator.getValue()) {
    vals[0] = 0;
  }
  else if (coin_safe_cast<SoNode *>(activechild) == YRotator.getValue()) {
    vals[1] = 0;
  }
  else if (coin_safe_cast<SoNode *>(activechild) == ZRotator.getValue()) {
    vals[2] = 0;
  }
  else if (activechild != NULL) {
    vals[0] = vals[1] = vals[2] = 0;
  }

  sw = SO_GET_ANY_PART(this, "XAxisSwitch", SoSwitch);
  SoInteractionKit::setSwitchValue(sw, vals[0]);
  sw = SO_GET_ANY_PART(this, "YAxisSwitch", SoSwitch);
  SoInteractionKit::setSwitchValue(sw, vals[1]);
  sw = SO_GET_ANY_PART(this, "ZAxisSwitch", SoSwitch);
  SoInteractionKit::setSwitchValue(sw, vals[2]);

}
void TranslateRadialDragger::
orientFeedbackGeometry(
  const SbVec3f &localDir)
{
  // By default, feedback geometry aligns with the x axis.
  // Rotate so that it points in the given direction.
  SbRotation rotXToDir = SbRotation(SbVec3f(1, 0, 0), localDir);

  // Give this rotation to the "feedbackRotate" part.
  SoRotation *myPart = SO_GET_ANY_PART(this, "feedbackRotate", SoRotation);
  myPart->rotation.setValue(rotXToDir);
}
示例#9
0
/*!
  Activate or deactive all dragger geometry parts.
*/
void
SoHandleBoxDragger::setAllPartsActive(SbBool onoroff)
{
  int i;
  int val = onoroff ? 1 : 0;
  SoSwitch *sw;
  SbString str;
  for (i = 1; i <= 6; i++) {
    str.sprintf("translator%dSwitch", i);
    sw = SO_GET_ANY_PART(this, str.getString(), SoSwitch);
    SoInteractionKit::setSwitchValue(sw, val);
  }
  for (i = 1; i <= 6; i++) {
    str.sprintf("extruder%dSwitch", i);
    sw = SO_GET_ANY_PART(this, str.getString(), SoSwitch);
    SoInteractionKit::setSwitchValue(sw, val);
  }
  for (i = 1; i <= 8; i++) {
    str.sprintf("uniform%dSwitch", i);
    sw = SO_GET_ANY_PART(this, str.getString(), SoSwitch);
    SoInteractionKit::setSwitchValue(sw, val);
  }
  this->updateArrows();
}
示例#10
0
/*! \COININTERNAL */
void
SoCenterballDragger::fieldSensorCB(void * d, SoSensor *)
{
  SoCenterballDragger * thisp = static_cast<SoCenterballDragger *>(d);

  // Save center variable and translate dragger to correct position
  thisp->savedcenter = thisp->center.getValue();
  SbMatrix centermat;
  centermat.setTranslate(thisp->savedcenter);
  SoMatrixTransform * mt =
    SO_GET_ANY_PART(thisp, "translateToCenter", SoMatrixTransform);
  mt->matrix = centermat;

  SbMatrix matrix = thisp->getMotionMatrix();
  thisp->workFieldsIntoTransform(matrix);
  thisp->setMotionMatrix(matrix);
}
示例#11
0
/*!
  Should be called after motion matrix has been updated by a child
  dragger.
*/
void
SoCenterballDragger::transferCenterDraggerMotion(SoDragger * childdragger)
{
  if (coin_assert_cast<SoNode *>(childdragger) == XCenterChanger.getValue() ||
      coin_assert_cast<SoNode *>(childdragger) == YCenterChanger.getValue() ||
      coin_assert_cast<SoNode *>(childdragger) == ZCenterChanger.getValue()) {
    // translate part of matrix should not change. Move motion
    // into center instead.

    SbVec3f transl;
    SbMatrix matrix = this->getMotionMatrix();
    transl[0] = matrix[3][0];
    transl[1] = matrix[3][1];
    transl[2] = matrix[3][2];

    SbVec3f difftransl = transl - this->savedtransl;
    { // consider rotation before translating
      SbRotation rot = this->rotation.getValue();
      SbMatrix tmp;
      tmp.setRotate(rot.inverse());
      tmp.multVecMatrix(difftransl, difftransl);
    }

    this->centerFieldSensor->detach();
    this->center = difftransl + this->savedcenter;
    this->centerFieldSensor->attach(&this->center);

    matrix[3][0] = this->savedtransl[0];
    matrix[3][1] = this->savedtransl[1];
    matrix[3][2] = this->savedtransl[2];

    SbBool oldval = this->enableValueChangedCallbacks(FALSE);
    this->setMotionMatrix(matrix);
    this->enableValueChangedCallbacks(oldval);

    SoMatrixTransform *mt = SO_GET_ANY_PART(this, "translateToCenter", SoMatrixTransform);
    matrix.setTranslate(this->center.getValue());
    mt->matrix = matrix;
  }
}
void SoFileSubgraph::readFile(const char *fileName){

    // open the input file
    SoInput sceneInput;
    if (!sceneInput.openFile(fileName)) {
		SoDebugError::post("SoFileSubgraph::readFile()",
				"Cannot open file '%s'",
				fileName);
        return;
    }
    if (!sceneInput.isValidFile()){
		SoDebugError::post("SoFileSubgraph::readFile()",
				"file '%s' is not a valid Inventor file",
				fileName);
       return;
    }
    else{
		SoDebugError::postInfo("SoFileSubgraph::readFile()",
				"file '%s' read successfully",
				fileName);
    }

    // read the whole file into the database
    SoSeparator *subgraph=SoDB::readAll(&sceneInput);
    subgraph->ref();
    if (subgraph ==NULL) {
		SoDebugError::post("SoFileSubgraph::readFile()",
				"problem reading contents of file '%s'",
				fileName);
        return;
    }
    SoSeparator *graphRoot=SO_GET_ANY_PART(this,"root",SoSeparator);
    graphRoot->addChild(subgraph);

    sceneInput.closeFile();
}
////////////////////////////////////////////////////////////////////////
//
// Description:
//   This routine sets the limitBox. 
// The limit box is defined in a space aligned and scaled as 
// LOCAL space, but with it's center remaining fixed in WORLD 
// space.
//
// Use: static private
//
void
SoDragPointDragger::updateLimitBoxAndFeedback()
//
////////////////////////////////////////////////////////////////////////
{
    // This gets called in the constructor, while the ref count is still 0.
    // Since there will be some ref'ing and unref'ing done inside here,
    // add a temporary ref and undo it at the end.
    ref();

    if ( xFeedback.getValue() != oldXAxisNode ||
	 yFeedback.getValue() != oldYAxisNode ||
	 zFeedback.getValue() != oldZAxisNode ) {

	oldXAxisNode = SO_GET_ANY_PART(this,"xFeedback",SoSeparator);
	oldYAxisNode = SO_GET_ANY_PART(this,"yFeedback",SoSeparator);
	oldZAxisNode = SO_GET_ANY_PART(this,"zFeedback",SoSeparator);

	// Get the bounds of the axis parts. 
	static SoGetBoundingBoxAction *bba = NULL;
	if (bba == NULL)
	    bba = new SoGetBoundingBoxAction(getViewportRegion());
	else
	    bba->setViewportRegion(getViewportRegion());

	float   xMin, yMin, zMin, xMax, yMax, zMax;
	SbVec3f min, max;

	bba->apply(xFeedback.getValue());
	bba->getBoundingBox().getBounds( xMin, yMin, zMin, xMax, yMax, zMax );
	min[0] = xMin;
	max[0] = xMax;

	bba->apply(yFeedback.getValue());
	bba->getBoundingBox().getBounds( xMin, yMin, zMin, xMax, yMax, zMax );
	min[1] = yMin; 
	max[1] = yMax; 

	bba->apply(zFeedback.getValue());
	bba->getBoundingBox().getBounds( xMin, yMin, zMin, xMax, yMax, zMax );
	min[2] = zMin;
	max[2] = zMax;

	// The limit box is defined in a space aligned and scaled as 
	// LOCAL space, but with it's center remaining fixed in WORLD 
	// space.

	SbVec3f newDiag = (max - min) / 2.0;

	// Give a default size of 1, in case no axis parts exist.
	for (int i = 0; i < 3; i++) {
	    if (newDiag[i] <= getMinScale())
		newDiag[i] = 1.0;
	}

	SbVec3f oldDiag = limitBox.getMax() - 
			  limitBox.getCenter();

	// If the size of the boundingBox has changed...
	if ( newDiag != oldDiag ) {

	    // curEdit point needs to be the current origin expressed in world
	    // space (i.e., this bizarro space).
	    SbMatrix localToWorld = getLocalToWorldMatrix();

	    SbVec3f zeroPt(0,0,0);
	    localToWorld.multVecMatrix( zeroPt, zeroPt );

	    limitBox.setBounds(zeroPt - newDiag, zeroPt + newDiag );
	}
    }

    setFeedbackGeometry();

    // undo the temporary ref.
    unrefNoDelete();
}
示例#14
0
SbBool
SoXipPlot2Columns::setUpConnections( SbBool onOff, SbBool doItAlways )
{
    if( !doItAlways && connectionsSetUp == onOff )
        return onOff;

    try
    {
        if ( onOff )
        {
            // We connect AFTER base class.
            SoBaseKit::setUpConnections( onOff, FALSE );

            SoMaterial* faceMaterial = SO_GET_ANY_PART( this, "mFaceMaterial", SoMaterial );
            if( faceMaterial )
            {
                faceMaterial->diffuseColor.connectFrom( &faceColor );
                faceMaterial->transparency.connectFrom( &faceTransparency );
            }

            SoBaseColor* borderBaseColor = SO_GET_ANY_PART( this, "mBorderColor", SoBaseColor );
            if( borderBaseColor )
            {
                borderBaseColor->rgb.connectFrom( &borderColor );
            }

            SoDrawStyle* borderStyle = SO_GET_ANY_PART( this, "mBorderStyle", SoDrawStyle );
            if( borderStyle )
            {
                borderStyle->lineWidth.connectFrom( &borderWidth );
            }
        }
        else
        {
            SoMaterial* faceMaterial = SO_GET_ANY_PART( this, "mFaceMaterial", SoMaterial );
            if( faceMaterial )
            {
                faceMaterial->diffuseColor.disconnect();
                faceMaterial->transparency.disconnect();
            }

            SoBaseColor* borderBaseColor = SO_GET_ANY_PART( this, "mBorderColor", SoBaseColor );
            if( borderBaseColor )
            {
                borderBaseColor->rgb.disconnect();
            }

            SoDrawStyle* borderStyle = SO_GET_ANY_PART( this, "mBorderStyle", SoDrawStyle );
            if( borderStyle )
            {
                borderStyle->lineWidth.disconnect();
            }

            SoBaseKit::setUpConnections( onOff, FALSE );
        }
    }
    catch(...)
    {
        SoDebugError::post( __FILE__, "Cannot setup connections" );
        return true;
    }

    return !( connectionsSetUp = onOff );
}
示例#15
0
/*! \COININTERNAL
  Called when dragger is selected (picked) by the user.
*/
void
SoHandleBoxDragger::dragStart(void)
{
  SoHandleBoxDragger_invalidate_surroundscale(this);

  static const char translatorname[] = "translator";
  static const char extrudername[] = "extruder";
  static const char uniformname[] = "uniform";

  const SoPath *pickpath = this->getPickPath();

  SbBool found = FALSE;
  this->whatkind = WHATKIND_NONE;
  this->whatnum = 0;

  int i;
  SbString str;
  if (!found) {
    for (i = 1; i <= 6; i++) {
      str.sprintf("%s%d", translatorname, i);
      if (pickpath->findNode(this->getNodeFieldNode(str.getString())) >= 0||
          this->getSurrogatePartPickedName() == str.getString()) break;
    }
    if (i <= 6) {
      found = TRUE;
      this->whatkind = WHATKIND_TRANSLATOR;
      this->whatnum = i;
    }
  }

  if (!found) {
    for (i = 1; i <= 6; i++) {
      str.sprintf("%s%d", extrudername, i);
      if (pickpath->findNode(this->getNodeFieldNode(str.getString()))>= 0 ||
          this->getSurrogatePartPickedName() == str.getString()) break;
    }
    if (i <= 6) {
      found = TRUE;
      this->whatkind = WHATKIND_EXTRUDER;
      this->whatnum = i;
    }
  }
  if (!found) {
    for (i = 1; i <= 8; i++) {
      str.sprintf("%s%d", uniformname, i);
      if (pickpath->findNode(this->getNodeFieldNode(str.getString()))>= 0 ||
          this->getSurrogatePartPickedName() == str.getString()) break;
    }
    if (i <= 8) {
      found = TRUE;
      this->whatkind = WHATKIND_UNIFORM;
      this->whatnum = i;
    }
  }
  assert(found);
  if (!found) return;

  SbVec3f startPt = this->getLocalStartingPoint();

  switch(this->whatkind) {
  case WHATKIND_TRANSLATOR:
    {
      SbVec3f n;
      if (this->whatnum <= 2) {
        n = SbVec3f(0.0f, 1.0f, 0.0f);
      }
      else if (this->whatnum <= 4) {
        n = SbVec3f(1.0f, 0.0f, 0.0f);
      }
      else {
        n = SbVec3f(0.0f, 0.0f, 1.0f);
      }
      SbVec3f localPt;
      {
        SbMatrix mat, inv;
        this->getSurroundScaleMatrices(mat, inv);
        inv.multVecMatrix(startPt, localPt);
      }
      this->planeProj->setPlane(SbPlane(n, startPt));
      SbLine myline(SbVec3f(0.0f, 0.0f, 0.0f), n);
      SoTranslation *t = SO_GET_ANY_PART(this, "arrowTranslation", SoTranslation);
      t->translation = myline.getClosestPoint(localPt);
      if (this->getEvent()->wasShiftDown()) {
        this->getLocalToWorldMatrix().multVecMatrix(startPt, this->worldRestartPt);
        this->constraintState = CONSTRAINT_WAIT;
      }
    }
    break;
  case WHATKIND_EXTRUDER:
    this->lineProj->setLine(SbLine(this->getDraggerCenter(), startPt));
    this->ctrlOffset = this->calcCtrlOffset(startPt);
    break;
  case WHATKIND_UNIFORM:
    this->lineProj->setLine(SbLine(this->getDraggerCenter(), startPt));
    this->ctrlOffset = this->calcCtrlOffset(startPt);
    break;
  }
  this->ctrlDown = this->getEvent()->wasCtrlDown();
  this->updateSwitches();
}
////////////////////////////////////////////////////////////////////////
//
// Description:
//    Constructor
//
SoDragPointDragger::SoDragPointDragger()
//
////////////////////////////////////////////////////////////////////////
{
    SO_KIT_CONSTRUCTOR(SoDragPointDragger);

    isBuiltIn = TRUE;

    SO_KIT_ADD_CATALOG_ENTRY(noRotSep, SoSeparator, FALSE,
				topSeparator, geomSeparator,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(xTranslatorSwitch, SoSwitch, FALSE, 
				noRotSep,\x0,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(xTranslator, SoTranslate1Dragger, TRUE, 
				xTranslatorSwitch,\x0,TRUE);
    SO_KIT_ADD_CATALOG_ENTRY(xyTranslatorSwitch, SoSwitch, FALSE, 
				noRotSep,\x0,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(xyTranslator, SoTranslate2Dragger, TRUE, 
				xyTranslatorSwitch,\x0,TRUE);

    SO_KIT_ADD_CATALOG_ENTRY(rotXSep, SoSeparator, FALSE,
				topSeparator, geomSeparator,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(rotX, SoRotation, TRUE, 
				rotXSep,\x0,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(xzTranslatorSwitch, SoSwitch, FALSE, 
				rotXSep,\x0,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(xzTranslator, SoTranslate2Dragger, TRUE, 
				xzTranslatorSwitch,\x0,TRUE);

    SO_KIT_ADD_CATALOG_ENTRY(rotYSep, SoSeparator, FALSE,
				topSeparator, geomSeparator,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(rotY, SoRotation, TRUE, 
				rotYSep,\x0,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(zTranslatorSwitch, SoSwitch, FALSE, 
				rotYSep,\x0,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(zTranslator, SoTranslate1Dragger, TRUE, 
				zTranslatorSwitch,\x0,TRUE);
    SO_KIT_ADD_CATALOG_ENTRY(yzTranslatorSwitch, SoSwitch, FALSE, 
				rotYSep,\x0,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(yzTranslator, SoTranslate2Dragger, TRUE, 
				yzTranslatorSwitch,\x0,TRUE);

    SO_KIT_ADD_CATALOG_ENTRY(rotZSep, SoSeparator, FALSE,
				topSeparator, geomSeparator,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(rotZ, SoRotation, TRUE, 
				rotZSep,\x0,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(yTranslatorSwitch, SoSwitch, FALSE, 
				rotZSep,\x0,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(yTranslator, SoTranslate1Dragger, TRUE, 
				yTranslatorSwitch,\x0,TRUE);

    SO_KIT_ADD_CATALOG_ENTRY(xFeedbackSwitch, SoSwitch, FALSE, 
				topSeparator, geomSeparator,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(xFeedbackSep, SoSeparator, FALSE,
				xFeedbackSwitch,\x0,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(xFeedbackTranslation, SoTranslation, FALSE,
				xFeedbackSep,\x0,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(xFeedback, SoSeparator, TRUE,
				xFeedbackSep,\x0,TRUE);

    SO_KIT_ADD_CATALOG_ENTRY(yFeedbackSwitch, SoSwitch, FALSE, 
				topSeparator, geomSeparator,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(yFeedbackSep, SoSeparator, FALSE,
				yFeedbackSwitch,\x0,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(yFeedbackTranslation, SoTranslation, FALSE,
				yFeedbackSep,\x0,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(yFeedback, SoSeparator, TRUE,
				yFeedbackSep,\x0,TRUE);

    SO_KIT_ADD_CATALOG_ENTRY(zFeedbackSwitch, SoSwitch, FALSE, 
				topSeparator, geomSeparator,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(zFeedbackSep, SoSeparator, FALSE,
				zFeedbackSwitch,\x0,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(zFeedbackTranslation, SoTranslation, FALSE,
				zFeedbackSep,\x0,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(zFeedback, SoSeparator, TRUE,
				zFeedbackSep,\x0,TRUE);

    SO_KIT_ADD_CATALOG_ENTRY(planeFeedbackSep, SoSeparator, FALSE,
				topSeparator, geomSeparator,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(planeFeedbackTranslation, SoTranslation, FALSE,
				planeFeedbackSep,\x0,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(planeFeedbackSwitch, SoSwitch, FALSE, 
				planeFeedbackSep,\x0,FALSE);
    SO_KIT_ADD_CATALOG_ENTRY(yzFeedback, SoSeparator, TRUE,
				planeFeedbackSwitch,\x0,TRUE);
    SO_KIT_ADD_CATALOG_ENTRY(xzFeedback, SoSeparator, TRUE,
				planeFeedbackSwitch,\x0,TRUE);
    SO_KIT_ADD_CATALOG_ENTRY(xyFeedback, SoSeparator, TRUE,
				planeFeedbackSwitch,\x0,TRUE);

    // read geometry for shared parts
    if (SO_KIT_IS_FIRST_INSTANCE())
	readDefaultParts("dragPointDragger.iv",geomBuffer,sizeof(geomBuffer) );

    // The field that reflects where the dragger has been translated to
    SO_KIT_ADD_FIELD(translation, (0.0, 0.0, 0.0));

    SO_KIT_INIT_INSTANCE();

    // Cached values to make updating the feedback geometry more efficient
    oldXAxisNode = NULL;
    oldYAxisNode = NULL;
    oldZAxisNode = NULL;

    //******************
    // Set up the parts.
    //******************

    // Set up the rotations to orient the draggers correctly.
    SoRotation *myRotX = new SoRotation;
    SoRotation *myRotY = new SoRotation;
    SoRotation *myRotZ = new SoRotation;
    myRotX->rotation = SbRotation( SbVec3f(1,0,0), 1.57079 );
    myRotY->rotation = SbRotation( SbVec3f(0,1,0), 1.57079 );
    myRotZ->rotation = SbRotation( SbVec3f(0,0,1), 1.57079 );
    setAnyPartAsDefault("rotX", myRotX );
    setAnyPartAsDefault("rotY", myRotY );
    setAnyPartAsDefault("rotZ", myRotZ );

    // CREATE THE CHILD DRAGGERS.
    // Create the translate1Draggers...
    SoTranslate1Dragger *myXTrans, *myYTrans, *myZTrans;
    myXTrans = SO_GET_ANY_PART(this,"xTranslator",SoTranslate1Dragger);
    myYTrans = SO_GET_ANY_PART(this,"yTranslator",SoTranslate1Dragger);
    myZTrans = SO_GET_ANY_PART(this,"zTranslator",SoTranslate1Dragger);

    // Create the translate2Draggers...
    SoTranslate2Dragger *myYZTrans, *myXZTrans, *myXYTrans;
    myYZTrans = SO_GET_ANY_PART(this,"yzTranslator",SoTranslate2Dragger);
    myXZTrans = SO_GET_ANY_PART(this,"xzTranslator",SoTranslate2Dragger);
    myXYTrans = SO_GET_ANY_PART(this,"xyTranslator",SoTranslate2Dragger);

    //******************
    // The feedback parts jump around as the limit box changes. That is, they
    // stay fixed in space while the dragger moves around.
    // However, they jump to a new location when the dragger nears the edge.
    // These parts a separate translation node, since they move differently
    // than the dragger itself.
    //******************

    //******************
    // The feedback parts jump around as the limit box changes. That is, they
    // stay fixed in space while the dragger moves around.
    // However, they jump to a new location when the dragger nears the edge.
    // These parts a separate translation node, since they move differently
    // than the dragger itself.
    //
    // Only one plane or one axis is shown at a time, depending on which
    // translator has initiated the dragging.
    //******************

   setPartAsDefault("xFeedback",      "dragPointXFeedback");
   setPartAsDefault("yFeedback",      "dragPointYFeedback");
   setPartAsDefault("zFeedback",      "dragPointZFeedback");

   setPartAsDefault("yzFeedback", "dragPointYZFeedback");
   setPartAsDefault("xzFeedback", "dragPointXZFeedback");
   setPartAsDefault("xyFeedback", "dragPointXYFeedback");

    //********************
    // initialize state, limitbox, gesture variables
    //********************

    // To begin with, only the yTranslator and xzTranslators are turned on.
    // You can switch between pairs of line/plane draggers by hitting the 
    // CONTROL key
    setSwitchValue(xTranslatorSwitch.getValue(),   SO_SWITCH_NONE );
    setSwitchValue(yTranslatorSwitch.getValue(),   0 );
    setSwitchValue(zTranslatorSwitch.getValue(),   SO_SWITCH_NONE );
    setSwitchValue(yzTranslatorSwitch.getValue(),   SO_SWITCH_NONE );
    setSwitchValue(xzTranslatorSwitch.getValue(),   0 );
    setSwitchValue(xyTranslatorSwitch.getValue(),  SO_SWITCH_NONE );

    // ??? Would be cool to be able to choose a free
    // axis, rotate it around to whatever direction, maybe even
    // have it snap to things in the scene, then constrain
    // dragging to that line.

    // Start off inactive
    currentDragger = NULL;

    // The state of the modifier keys
    shftDown = FALSE;

    // Need to initialize since checkBoxLimits will look at it...
    startLocalHitPt.setValue(0,0,0);

    // The jump axes will jump when the edit point gets within
    // 10% of their ends
    jumpLimit = .1;

    // makes the offsetWorkLimit box
    limitBox.makeEmpty();

    updateLimitBoxAndFeedback();

    // These will be called by the child draggers after they call
    // their own callbacks...
    addStartCallback( &SoDragPointDragger::startCB );
    addMotionCallback( &SoDragPointDragger::motionCB );
    addFinishCallback( &SoDragPointDragger::finishCB );

    // When modify keys are released, we need to turn off any constraints.
    addOtherEventCallback( &SoDragPointDragger::metaKeyChangeCB );

    // Updates the translation field when the motionMatrix is set.
    addValueChangedCallback( &SoDragPointDragger::valueChangedCB );

    // Updates the motionMatrix when the translation field is set.
    fieldSensor = new SoFieldSensor( &SoDragPointDragger::fieldSensorCB, this);
    fieldSensor->setPriority( 0 );

    setUpConnections( TRUE, TRUE );
}
示例#17
0
/*!
  \DRAGGER_CONSTRUCTOR

  \NODEKIT_PRE_DIAGRAM

  \verbatim
  CLASS SoCenterballDragger
  -->"this"
        "callbackList"
        "topSeparator"
           "motionMatrix"
  -->      "translateToCenter"
  -->      "surroundScale"
  -->      "antiSquish"
  -->      "lightModel"
           "geomSeparator"
  -->         "XAxisSwitch"
  -->            "XAxis"
  -->         "YAxisSwitch"
  -->            "YAxis"
  -->         "ZAxisSwitch"
  -->            "ZAxis"
  -->      "rotator"
  -->      "YRotator"
  -->      "ZCenterChanger"
  -->      "rotX90"
  -->      "ZRotator"
  -->      "YCenterChanger"
  -->      "rotY90"
  -->      "XCenterChanger"
  -->      "rot2X90"
  -->      "XRotator"
  \endverbatim

  \NODEKIT_POST_DIAGRAM


  \NODEKIT_PRE_TABLE

  \verbatim
  CLASS SoCenterballDragger
  PVT   "this",  SoCenterballDragger  ---
        "callbackList",  SoNodeKitListPart [ SoCallback, SoEventCallback ]
  PVT   "topSeparator",  SoSeparator  ---
  PVT   "motionMatrix",  SoMatrixTransform  ---
        "translateToCenter",  SoMatrixTransform  ---
        "surroundScale",  SoSurroundScale  ---
        "antiSquish",  SoAntiSquish  ---
        "lightModel",  SoLightModel  ---
  PVT   "geomSeparator",  SoSeparator  ---
        "rotator",  SoRotateSphericalDragger  ---
        "YRotator",  SoRotateCylindricalDragger  ---
        "ZCenterChanger",  SoTranslate2Dragger  ---
  PVT   "rotX90",  SoRotation  ---
        "ZRotator",  SoRotateCylindricalDragger  ---
        "YCenterChanger",  SoTranslate2Dragger  ---
  PVT   "rotY90",  SoRotation  ---
        "XCenterChanger",  SoTranslate2Dragger  ---
  PVT   "rot2X90",  SoRotation  ---
  PVT   "XAxisSwitch",  SoSwitch  ---
        "XAxis",  SoSeparator  ---
  PVT   "YAxisSwitch",  SoSwitch  ---
        "YAxis",  SoSeparator  ---
  PVT   "ZAxisSwitch",  SoSwitch  ---
        "ZAxis",  SoSeparator  ---
        "XRotator",  SoRotateCylindricalDragger  ---
  \endverbatim

  \NODEKIT_POST_TABLE
 */
SoCenterballDragger::SoCenterballDragger(void)
{
  SO_KIT_INTERNAL_CONSTRUCTOR(SoCenterballDragger);
  SO_KIT_ADD_CATALOG_ENTRY(XAxis, SoSeparator, TRUE, XAxisSwitch, "", TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(XAxisSwitch, SoSwitch, TRUE, geomSeparator, YAxisSwitch, FALSE);
  SO_KIT_ADD_CATALOG_ENTRY(XCenterChanger, SoTranslate2Dragger, TRUE, topSeparator, rot2X90, TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(XRotator, SoRotateCylindricalDragger, TRUE, topSeparator, "", TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(YAxis, SoSeparator, TRUE, YAxisSwitch, "", TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(YAxisSwitch, SoSwitch, TRUE, geomSeparator, ZAxisSwitch, FALSE);
  SO_KIT_ADD_CATALOG_ENTRY(YCenterChanger, SoTranslate2Dragger, TRUE, topSeparator, rotY90, TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(YRotator, SoRotateCylindricalDragger, TRUE, topSeparator, ZCenterChanger, TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(ZAxis, SoSeparator, TRUE, ZAxisSwitch, "", TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(ZAxisSwitch, SoSwitch, TRUE, geomSeparator, "", FALSE);
  SO_KIT_ADD_CATALOG_ENTRY(ZCenterChanger, SoTranslate2Dragger, TRUE, topSeparator, rotX90, TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(ZRotator, SoRotateCylindricalDragger, TRUE, topSeparator, YCenterChanger, TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(antiSquish, SoAntiSquish, FALSE, topSeparator, lightModel, TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(lightModel, SoLightModel, TRUE, topSeparator, geomSeparator, TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(rot2X90, SoRotation, TRUE, topSeparator, XRotator, FALSE);
  SO_KIT_ADD_CATALOG_ENTRY(rotX90, SoRotation, TRUE, topSeparator, ZRotator, FALSE);
  SO_KIT_ADD_CATALOG_ENTRY(rotY90, SoRotation, TRUE, topSeparator, XCenterChanger, FALSE);
  SO_KIT_ADD_CATALOG_ENTRY(rotator, SoRotateSphericalDragger, TRUE, topSeparator, YRotator, TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(surroundScale, SoSurroundScale, TRUE, topSeparator, antiSquish, TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(translateToCenter, SoMatrixTransform, TRUE, topSeparator, surroundScale, TRUE);

  if (SO_KIT_IS_FIRST_INSTANCE()) {
    SoInteractionKit::readDefaultParts("centerballDragger.iv",
                                       CENTERBALLDRAGGER_draggergeometry,
                                       static_cast<int>(strlen(CENTERBALLDRAGGER_draggergeometry)));
  }

  SO_KIT_ADD_FIELD(rotation, (SbRotation(SbVec3f(0.0f, 0.0f, 1.0f), 0.0f)));
  SO_KIT_ADD_FIELD(center, (0.0f, 0.0f, 0.0f));

  SO_KIT_INIT_INSTANCE();

  // create subdraggers
  SO_GET_ANY_PART(this, "XCenterChanger", SoTranslate2Dragger);
  SO_GET_ANY_PART(this, "YCenterChanger", SoTranslate2Dragger);
  SO_GET_ANY_PART(this, "ZCenterChanger", SoTranslate2Dragger);
  SO_GET_ANY_PART(this, "XRotator", SoRotateCylindricalDragger);
  SO_GET_ANY_PART(this, "YRotator", SoRotateCylindricalDragger);
  SO_GET_ANY_PART(this, "ZRotator", SoRotateCylindricalDragger);
  SO_GET_ANY_PART(this, "rotator", SoRotateSphericalDragger);

  // create default parts
  this->setPartAsDefault("XAxis", "centerballXAxis");
  this->setPartAsDefault("YAxis", "centerballYAxis");
  this->setPartAsDefault("ZAxis", "centerballZAxis");

  // initialize some nodes
  SoRotation *rot;
  rot = SO_GET_ANY_PART(this, "rot2X90", SoRotation);
  rot->rotation = SbRotation(SbVec3f(1.0f, 0.0f, 0.0f), (static_cast<float>(M_PI))*0.5f);
  rot = SO_GET_ANY_PART(this, "rotX90", SoRotation);
  rot->rotation = SbRotation(SbVec3f(1.0f, 0.0f, 0.0f), (static_cast<float>(M_PI))*0.5f);
  rot = SO_GET_ANY_PART(this, "rotY90", SoRotation);
  rot->rotation = SbRotation(SbVec3f(0.0f, 1.0f, 0.0f), (static_cast<float>(M_PI))*0.5f);

  // reset default flags for parts we set to a default value
  this->rot2X90.setDefault(TRUE);
  this->rotX90.setDefault(TRUE);
  this->rotY90.setDefault(TRUE);

  SoAntiSquish *squish = SO_GET_ANY_PART(this, "antiSquish", SoAntiSquish);
  squish->sizing = SoAntiSquish::LONGEST_DIAGONAL;
  squish->recalcAlways = FALSE;

  SoMatrixTransform *mt = SO_GET_ANY_PART(this, "translateToCenter", SoMatrixTransform);
  mt->matrix = SbMatrix::identity();

  this->addValueChangedCallback(SoCenterballDragger::valueChangedCB);

  this->rotFieldSensor = new SoFieldSensor(SoCenterballDragger::fieldSensorCB, this);
  this->centerFieldSensor = new SoFieldSensor(SoCenterballDragger::fieldSensorCB, this);
  this->setUpConnections(TRUE, TRUE);
}
TranslateRadialDragger::
TranslateRadialDragger()
{
  SO_KIT_CONSTRUCTOR(TranslateRadialDragger);

  SO_KIT_ADD_CATALOG_ENTRY(validitySwitch, SoBlinker, TRUE,
                           geomSeparator, , FALSE);

  SO_KIT_ADD_CATALOG_ENTRY(materialSwitch, SoSwitch, TRUE,
                           validitySwitch, , FALSE);

  // Put this under geomSeparator so it draws efficiently.
  SO_KIT_ADD_CATALOG_ENTRY(translatorSwitch, SoSwitch, TRUE,
                           geomSeparator, , FALSE);
  SO_KIT_ADD_CATALOG_ENTRY(translator, SoSeparator, TRUE,
                           translatorSwitch, , TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(translatorActive, SoSeparator, TRUE,
                           translatorSwitch, , TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(feedbackRotate, SoRotation, TRUE,
                           geomSeparator, , TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(feedbackSwitch, SoSwitch, TRUE,
                           geomSeparator, , FALSE);
  SO_KIT_ADD_CATALOG_ENTRY(feedback, SoSeparator, TRUE,
                           feedbackSwitch, , TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(feedbackActive, SoSeparator, TRUE,
                           feedbackSwitch, , TRUE);


  SO_KIT_ADD_CATALOG_ENTRY(materialPlaced, SoMaterial, TRUE,
                           materialSwitch, , TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(materialNormal, SoMaterial, TRUE,
                           materialSwitch, , TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(materialActive, SoMaterial, TRUE,
                           materialSwitch, , TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(materialInvalid, SoMaterial, TRUE,
                           validitySwitch, , TRUE);

  // Read geometry resources. Only do this the first time we
  // construct one.  'geomBuffer' contains our compiled in
  // defaults. The user can override these by specifying new
  // scene graphs in the file:
  // $(SO_DRAGGER_DIR)/translateRadialDragger.iv
  if(SO_KIT_IS_FIRST_INSTANCE())
    readDefaultParts("translateRadialDragger.iv", geomBuffer,
                     sizeof(geomBuffer) - 1);

  // Field that always shows current position of the dragger.
  SO_KIT_ADD_FIELD(translation, (0.0, 0.0, 0.0));

  // Creates the parts list for this nodekit
  SO_KIT_INIT_INSTANCE();

  // Create the parts of the dragger. This dragger has five
  // parts that we need to create: "translator",
  // "translatorActive", "feedback," and "feedbackActive" will
  // be created using the resource mechanism. They are looked
  // up in the global dictionary.
  // "rotator," used to position the feedback so it points in
  // the direction selected by the user, will just be a plain
  // old SoRotation node.
  // We call 'setPartAsDefault' because we are installing
  // default geometries from the resource files. By calling
  // 'setPartAsDefault' instead of 'setPart', we insure that
  // these parts will not write to file unless they are
  // changed later.
  setPartAsDefault("translator",
                   "translateRadialTranslator");
  setPartAsDefault("translatorActive",
                   "translateRadialTranslatorActive");
  setPartAsDefault("feedback",
                   "translateRadialFeedback");
  setPartAsDefault("feedbackActive",
                   "translateRadialFeedbackActive");
  setPartAsDefault("materialNormal",
                   "translateNormalMaterial");
  setPartAsDefault("materialActive",
                   "translateActiveMaterial");
  setPartAsDefault("materialPlaced",
                   "translatePlacedMaterial");
  setPartAsDefault("materialInvalid",
                   "translateInvalidMaterial");

  // Set the switch parts to 0 to display the inactive parts.
  // The parts "translatorSwitch" and "feedbackSwitch"
  // are not public parts. (i.e., when making the catalog, the
  // isPublic flag was set FALSE, so users cannot access them)
  // To retrieve the parts we must use the SO_GET_ANY_PART
  // macro which calls the protected method getAnyPart().
  SoSwitch *sw;
  sw = SO_GET_ANY_PART(this, "translatorSwitch", SoSwitch);
  setSwitchValue(sw, 0);
  sw = SO_GET_ANY_PART(this, "feedbackSwitch", SoSwitch);
  setSwitchValue(sw, 0);
  sw = SO_GET_ANY_PART(this, "materialSwitch", SoSwitch);
  setSwitchValue(sw, 0);
  sw = SO_GET_ANY_PART(this, "validitySwitch", SoBlinker);
  setSwitchValue(sw, 0);

  // This dragger does motion along a line,
  // so we create a line projector.
  lineProj = new SbLineProjector();

  // Add the callback functions that will be called when
  // the user clicks, drags, and releases.
  addStartCallback(&TranslateRadialDragger::startCB);
  addMotionCallback(&TranslateRadialDragger::motionCB);
  addFinishCallback(&TranslateRadialDragger::finishCB);

  // Updates the translation field when the dragger moves.
  addValueChangedCallback(&TranslateRadialDragger::valueChangedCB);

  // Updates the motionMatrix (and thus moves the dragger
  // through space) to a new location whenever the translation
  // field is changed from the outside.
  fieldSensor = new SoFieldSensor(
      &TranslateRadialDragger::fieldSensorCB, this);
  fieldSensor->setPriority(0);
  setUpConnections(TRUE, TRUE);
}