~ubuntu-branches/ubuntu/maverick/freecad/maverick

« back to all changes in this revision

Viewing changes to src/Gui/SoNavigationDragger.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Teemu Ikonen
  • Date: 2009-07-16 18:37:41 UTC
  • Revision ID: james.westby@ubuntu.com-20090716183741-oww9kcxqrk991i1n
Tags: upstream-0.8.2237
ImportĀ upstreamĀ versionĀ 0.8.2237

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *   Copyright (c) 2005 JĆ¼rgen Riegel <juergen.riegel@web.de>              *
 
3
 *                                                                         *
 
4
 *   This file is part of the FreeCAD CAx development system.              *
 
5
 *                                                                         *
 
6
 *   This library is free software; you can redistribute it and/or         *
 
7
 *   modify it under the terms of the GNU Library General Public           *
 
8
 *   License as published by the Free Software Foundation; either          *
 
9
 *   version 2 of the License, or (at your option) any later version.      *
 
10
 *                                                                         *
 
11
 *   This library  is distributed in the hope that it will be useful,      *
 
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 
14
 *   GNU Library General Public License for more details.                  *
 
15
 *                                                                         *
 
16
 *   You should have received a copy of the GNU Library General Public     *
 
17
 *   License along with this library; see the file COPYING.LIB. If not,    *
 
18
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 
19
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 
20
 *                                                                         *
 
21
 ***************************************************************************/
 
22
 
 
23
#include "PreCompiled.h"
 
24
 
 
25
#include <Inventor/nodes/SoAntiSquish.h>
 
26
#include <Inventor/nodes/SoRotation.h>
 
27
#include <Inventor/nodes/SoSeparator.h>
 
28
#include <Inventor/nodes/SoSurroundScale.h>
 
29
#include <Inventor/nodes/SoTransform.h>
 
30
#include <Inventor/sensors/SoFieldSensor.h>
 
31
 
 
32
// Include files for child dragger classes.
 
33
#include <Inventor/draggers/SoRotateCylindricalDragger.h>
 
34
//#include "TranslateRadialDragger.h"
 
35
#include <Inventor/draggers/SoTranslate1Dragger.h>
 
36
 
 
37
// Include file for our new class.
 
38
#include "SoNavigationDragger.h"
 
39
 
 
40
// This file contains RotTransDragger::geomBuffer, which 
 
41
// describes the default geometry resources for this class.
 
42
//#include "RotTransDraggerGeom.h"
 
43
 
 
44
SO_KIT_SOURCE(RotTransDragger);
 
45
 
 
46
 
 
47
//  Initializes the type ID for this dragger node. This
 
48
//  should be called once after SoInteraction::init().
 
49
void
 
50
RotTransDragger::initClass()
 
51
{
 
52
   SO_KIT_INIT_CLASS(RotTransDragger, SoDragger, "Dragger");    
 
53
}
 
54
 
 
55
RotTransDragger::RotTransDragger()
 
56
{
 
57
   SO_KIT_CONSTRUCTOR(RotTransDragger);
 
58
 
 
59
   // Don't create "surroundScale" by default. It's only put 
 
60
   // to use if this dragger is used within a manipulator.
 
61
   SO_KIT_ADD_CATALOG_ENTRY(surroundScale, SoSurroundScale, TRUE,
 
62
                            topSeparator, geomSeparator, TRUE);
 
63
   // Create an anti-squish node by default.
 
64
   SO_KIT_ADD_CATALOG_ENTRY(antiSquish, SoAntiSquish, FALSE,
 
65
                            topSeparator, geomSeparator, TRUE);
 
66
   SO_KIT_ADD_CATALOG_ENTRY(translator, SoTranslate1Dragger,
 
67
                            TRUE, topSeparator, geomSeparator,
 
68
                            TRUE);
 
69
   SO_KIT_ADD_CATALOG_ENTRY(XRotatorSep, SoSeparator, FALSE,
 
70
                            topSeparator, geomSeparator, FALSE);
 
71
   SO_KIT_ADD_CATALOG_ENTRY(XRotatorRot, SoRotation, TRUE,
 
72
                            XRotatorSep,0 , FALSE);
 
73
   SO_KIT_ADD_CATALOG_ENTRY(XRotator,SoRotateCylindricalDragger,
 
74
                            TRUE, XRotatorSep, 0,TRUE);
 
75
 
 
76
   SO_KIT_ADD_CATALOG_ENTRY(YRotator, SoRotateCylindricalDragger,
 
77
                            TRUE, topSeparator, geomSeparator, TRUE);
 
78
 
 
79
   SO_KIT_ADD_CATALOG_ENTRY(ZRotatorSep, SoSeparator, FALSE,
 
80
                            topSeparator, geomSeparator, FALSE);
 
81
   SO_KIT_ADD_CATALOG_ENTRY(ZRotatorRot, SoRotation, TRUE,
 
82
                            ZRotatorSep,0 ,FALSE);
 
83
   SO_KIT_ADD_CATALOG_ENTRY(ZRotator, SoRotateCylindricalDragger,
 
84
                            TRUE, ZRotatorSep, 0,TRUE);
 
85
 
 
86
   // Read geometry resources. Only do this the first time we
 
87
   // construct one. 'geomBuffer' contains our compiled in
 
88
   // defaults. The user can override these by specifying new
 
89
   // scene graphs in the file:
 
90
   // $(SO_DRAGGER_DIR)/rotTransDragger.iv"
 
91
   //if (SO_KIT_IS_FIRST_INSTANCE())
 
92
   //  readDefaultParts("rotTransDragger.iv", geomBuffer,
 
93
   //                    sizeof(geomBuffer));
 
94
 
 
95
   // Fields that always show current state of the dragger.
 
96
   SO_KIT_ADD_FIELD(rotation, (0.0, 0.0, 0.0, 1.0));
 
97
   SO_KIT_ADD_FIELD(translation, (0.0, 0.0, 0.0));
 
98
 
 
99
   // Creates parts list and default parts for this nodekit.
 
100
   SO_KIT_INIT_INSTANCE();
 
101
 
 
102
   // Make the anti-squish node surround the biggest dimension
 
103
   SoAntiSquish *myAntiSquish =
 
104
            SO_GET_ANY_PART(this, "antiSquish", SoAntiSquish);
 
105
   myAntiSquish->sizing = SoAntiSquish::BIGGEST_DIMENSION;
 
106
 
 
107
   // Create the simple draggers that comprise this dragger.
 
108
   // This dragger has four simple pieces:  
 
109
   //    1 TranslateRadialDragger
 
110
   //    3 RotateCylindricalDraggers
 
111
   // In the constructor, we just call SO_GET_ANY_PART to
 
112
   // build each dragger.
 
113
   // Within the setUpConnections() method, we will
 
114
   // take care of giving these draggers new geometry and 
 
115
   // establishing their callbacks.
 
116
 
 
117
   // Create the translator dragger.    
 
118
   //SoDragger *tDragger = SO_GET_ANY_PART(this, "translator", 
 
119
   //                      SoTranslate1Dragger);
 
120
 
 
121
   // Create the XRotator dragger.    
 
122
   //SoDragger *XDragger = SO_GET_ANY_PART(this, "XRotator", 
 
123
   //                      SoRotateCylindricalDragger);
 
124
 
 
125
   // Create the YRotator dragger.    
 
126
   //SoDragger *YDragger = SO_GET_ANY_PART(this, "YRotator", 
 
127
   //                      SoRotateCylindricalDragger);
 
128
 
 
129
   // Create the ZRotator dragger.    
 
130
   //SoDragger *ZDragger = SO_GET_ANY_PART(this, "ZRotator", 
 
131
   //                      SoRotateCylindricalDragger);
 
132
 
 
133
   // Set rotations in "XRotatorRot" and "ZRotatorRot" parts.
 
134
   // These parts will orient the draggers from their default 
 
135
   // (rotating about Y) to the desired configurations.
 
136
   // By calling 'setAnyPartAsDefault' instead of 'setAnyPart'
 
137
   // we ensure that they will not be written out, unless
 
138
   // they are changed later on.
 
139
   SoRotation *XRot = new SoRotation;
 
140
   XRot->rotation.setValue(
 
141
     SbRotation(SbVec3f(0,1,0), SbVec3f(1,0,0)));
 
142
   setAnyPartAsDefault("XRotatorRot", XRot);
 
143
 
 
144
   SoRotation *ZRot = new SoRotation;
 
145
   ZRot->rotation.setValue(
 
146
     SbRotation(SbVec3f(0,1,0), SbVec3f(0,0,1)));
 
147
   setAnyPartAsDefault("ZRotatorRot", ZRot);
 
148
 
 
149
   // Updates the fields when motionMatrix changes 
 
150
   addValueChangedCallback(&RotTransDragger::valueChangedCB);
 
151
 
 
152
   // Updates motionMatrix when either field changes.
 
153
   rotFieldSensor = new SoFieldSensor(
 
154
                        &RotTransDragger::fieldSensorCB, this);
 
155
   rotFieldSensor->setPriority(0);
 
156
   translFieldSensor = new SoFieldSensor(
 
157
                           &RotTransDragger::fieldSensorCB,this);
 
158
   translFieldSensor->setPriority(0);
 
159
 
 
160
   setUpConnections(TRUE, TRUE);
 
161
}
 
162
 
 
163
RotTransDragger::~RotTransDragger()
 
164
{
 
165
   if (rotFieldSensor!=NULL)
 
166
     delete rotFieldSensor;
 
167
   if (translFieldSensor!=NULL)
 
168
     delete translFieldSensor;
 
169
}
 
170
 
 
171
SbBool
 
172
RotTransDragger::setUpConnections(SbBool onOff, SbBool doItAlways)
 
173
{
 
174
   if (!doItAlways && connectionsSetUp == onOff)
 
175
     return onOff;
 
176
 
 
177
   if (onOff) {
 
178
     // We connect AFTER base class.
 
179
     SoDragger::setUpConnections(onOff, doItAlways);
 
180
 
 
181
     // For each of the simple draggers that compries this:
 
182
     // [a]Call setPart after looking up our replacement parts 
 
183
     //    in the global dictionary.
 
184
     // [b]Add the invalidateSurroundScaleCB as a start and end
 
185
     //    callback. When using a surroundScale node, these 
 
186
     //    trigger it to recalculate a bounding box at the 
 
187
     //    beginning and end of dragging.
 
188
     // [c]Register the dragger as a 'childDragger' of this 
 
189
     //    one. This has the following effects: 
 
190
     //    [1] This dragger's callbacks will be invoked 
 
191
     //        following the child manip's callbacks.  
 
192
     //    [2] When the child is dragged, the child's motion 
 
193
     //        will be transferred into motion of the entire 
 
194
     //        dragger.
 
195
      SoDragger *tD =
 
196
               (SoDragger *) getAnyPart("translator", FALSE);
 
197
      // [a] Set up the parts in the child dragger...
 
198
      tD->setPartAsDefault("translator",
 
199
                           "rotTransTranslatorTranslator");
 
200
      tD->setPartAsDefault("translatorActive",
 
201
                           "rotTransTranslatorTranslatorActive");
 
202
      tD->setPartAsDefault("feedback",
 
203
                           "rotTransTranslatorFeedback");
 
204
      tD->setPartAsDefault("feedbackActive",
 
205
                           "rotTransTranslatorFeedbackActive");
 
206
      // [b] and [c] Add the callbacks and register the child
 
207
      tD->addStartCallback(
 
208
               &RotTransDragger::invalidateSurroundScaleCB, this);
 
209
      tD->addFinishCallback(
 
210
               &RotTransDragger::invalidateSurroundScaleCB, this);
 
211
      registerChildDragger(tD);
 
212
 
 
213
      SoDragger *XD =
 
214
               (SoDragger *) getAnyPart("XRotator", FALSE);
 
215
      // [a] Set up the parts in the child dragger...
 
216
      XD->setPartAsDefault("rotator",
 
217
                           "rotTransRotatorRotator");
 
218
      XD->setPartAsDefault("rotatorActive",
 
219
                           "rotTransRotatorRotatorActive");
 
220
      XD->setPartAsDefault("feedback",
 
221
                           "rotTransRotatorFeedback");
 
222
      XD->setPartAsDefault("feedbackActive",
 
223
                           "rotTransRotatorFeedbackActive");
 
224
      // [b] and [c] Add the callbacks and register the child
 
225
      XD->addStartCallback(
 
226
               &RotTransDragger::invalidateSurroundScaleCB, this);
 
227
      XD->addFinishCallback(
 
228
               &RotTransDragger::invalidateSurroundScaleCB, this);
 
229
      registerChildDragger(XD);
 
230
 
 
231
      SoDragger *YD =
 
232
               (SoDragger *) getAnyPart("YRotator", FALSE);
 
233
      // [a] Set up the parts in the child dragger...
 
234
      YD->setPartAsDefault("rotator",
 
235
                           "rotTransRotatorRotator");
 
236
      YD->setPartAsDefault("rotatorActive",
 
237
                           "rotTransRotatorRotatorActive");
 
238
      YD->setPartAsDefault("feedback",
 
239
                           "rotTransRotatorFeedback");
 
240
      YD->setPartAsDefault("feedbackActive",
 
241
                           "rotTransRotatorFeedbackActive");
 
242
      // [b] and [c] Add the callbacks and register the child
 
243
      YD->addStartCallback(
 
244
               &RotTransDragger::invalidateSurroundScaleCB, this);
 
245
      YD->addFinishCallback(
 
246
               &RotTransDragger::invalidateSurroundScaleCB, this);
 
247
      registerChildDragger(YD);
 
248
 
 
249
      SoDragger *ZD =
 
250
               (SoDragger *) getAnyPart("ZRotator", FALSE);
 
251
      // [a] Set up the parts in the child dragger...
 
252
      ZD->setPartAsDefault("rotator",
 
253
                           "rotTransRotatorRotator");
 
254
      ZD->setPartAsDefault("rotatorActive",
 
255
                           "rotTransRotatorRotatorActive");
 
256
      ZD->setPartAsDefault("feedback",
 
257
                           "rotTransRotatorFeedback");
 
258
      ZD->setPartAsDefault("feedbackActive",
 
259
                           "rotTransRotatorFeedbackActive");
 
260
      // [b] and [c] Add the callbacks and register the child
 
261
      ZD->addStartCallback(
 
262
               &RotTransDragger::invalidateSurroundScaleCB, this);
 
263
      ZD->addFinishCallback(
 
264
               &RotTransDragger::invalidateSurroundScaleCB, this);
 
265
      registerChildDragger(ZD);
 
266
 
 
267
 
 
268
     // Call the sensor CB to make things up-to-date.
 
269
     fieldSensorCB(this, NULL);
 
270
 
 
271
     // Connect the field sensors
 
272
     if (translFieldSensor->getAttachedField() != &translation)
 
273
        translFieldSensor->attach(&translation);
 
274
     if (rotFieldSensor->getAttachedField() != &rotation)
 
275
        rotFieldSensor->attach(&rotation);
 
276
   }
 
277
   else {
 
278
     // We disconnect BEFORE base class.
 
279
 
 
280
     // Remove the callbacks from the child draggers,
 
281
     // and unregister them as children.
 
282
      SoDragger *tD =
 
283
               (SoDragger *) getAnyPart("translator", FALSE);
 
284
      tD->removeStartCallback(
 
285
               &RotTransDragger::invalidateSurroundScaleCB, this);
 
286
      tD->removeFinishCallback(
 
287
               &RotTransDragger::invalidateSurroundScaleCB, this);
 
288
      unregisterChildDragger(tD);
 
289
 
 
290
      SoDragger *XD =
 
291
               (SoDragger *) getAnyPart("XRotator", FALSE);
 
292
      XD->removeStartCallback(
 
293
               &RotTransDragger::invalidateSurroundScaleCB, this);
 
294
      XD->removeFinishCallback(
 
295
               &RotTransDragger::invalidateSurroundScaleCB, this);
 
296
      unregisterChildDragger(XD);
 
297
 
 
298
      SoDragger *YD =
 
299
               (SoDragger *) getAnyPart("YRotator", FALSE);
 
300
      YD->removeStartCallback(
 
301
               &RotTransDragger::invalidateSurroundScaleCB, this);
 
302
      YD->removeFinishCallback(
 
303
               &RotTransDragger::invalidateSurroundScaleCB, this);
 
304
      unregisterChildDragger(YD);
 
305
 
 
306
      SoDragger *ZD =
 
307
               (SoDragger *) getAnyPart("ZRotator", FALSE);
 
308
      ZD->removeStartCallback(
 
309
               &RotTransDragger::invalidateSurroundScaleCB, this);
 
310
      ZD->removeFinishCallback(
 
311
               &RotTransDragger::invalidateSurroundScaleCB, this);
 
312
      unregisterChildDragger(ZD);
 
313
 
 
314
     // Disconnect the field sensors.
 
315
     if (translFieldSensor->getAttachedField()!=NULL)
 
316
        translFieldSensor->detach();
 
317
     if (rotFieldSensor->getAttachedField()!=NULL)
 
318
        rotFieldSensor->detach();
 
319
 
 
320
     SoDragger::setUpConnections(onOff, doItAlways);
 
321
   }
 
322
 
 
323
   return !(connectionsSetUp = onOff);
 
324
}
 
325
 
 
326
// Called when the motionMatrix changes. Sets the "translation"
 
327
// and "rotation" fields based on the new motionMatrix
 
328
void
 
329
RotTransDragger::valueChangedCB(void *, SoDragger *inDragger)
 
330
{
 
331
   RotTransDragger *myself = (RotTransDragger *) inDragger;
 
332
 
 
333
   // Factor the motionMatrix into its parts
 
334
   SbMatrix motMat = myself->getMotionMatrix();
 
335
   SbVec3f   trans, scale;
 
336
   SbRotation rot, scaleOrient;
 
337
   motMat.getTransform(trans, rot, scale, scaleOrient);
 
338
 
 
339
   // Set the fields. Disconnect the sensors while doing so.
 
340
   myself->rotFieldSensor->detach();
 
341
   myself->translFieldSensor->detach();
 
342
   if (myself->rotation.getValue() != rot)
 
343
     myself->rotation = rot;
 
344
   if (myself->translation.getValue() != trans)
 
345
     myself->translation = trans;
 
346
   myself->rotFieldSensor->attach(&myself->rotation);
 
347
   myself->translFieldSensor->attach(&myself->translation);
 
348
}
 
349
 
 
350
// If the "translation" or "rotation" field changes, changes
 
351
// the motionMatrix accordingly.
 
352
void
 
353
RotTransDragger::fieldSensorCB(void *inDragger, SoSensor *)
 
354
{
 
355
   RotTransDragger *myself = (RotTransDragger *) inDragger;
 
356
 
 
357
   SbMatrix motMat = myself->getMotionMatrix();
 
358
   myself->workFieldsIntoTransform(motMat);
 
359
 
 
360
   myself->setMotionMatrix(motMat);
 
361
}
 
362
 
 
363
// When any child dragger starts or ends a drag, tell the
 
364
// "surroundScale" part (if it exists) to invalidate its 
 
365
// current bounding box value.
 
366
void 
 
367
RotTransDragger::invalidateSurroundScaleCB(void *parent, SoDragger *)
 
368
{
 
369
   RotTransDragger *myParentDragger = (RotTransDragger *) parent;
 
370
 
 
371
   // Invalidate the surroundScale, if it exists.
 
372
   SoSurroundScale *mySS = SO_CHECK_PART(
 
373
            myParentDragger, "surroundScale", SoSurroundScale);
 
374
   if (mySS != NULL)
 
375
      mySS->invalidate();
 
376
}
 
377
 
 
378
void
 
379
RotTransDragger::setDefaultOnNonWritingFields()
 
380
{
 
381
   // The nodes pointed to by these part-fields may 
 
382
   // change after construction, but we
 
383
   // don't want to write them out.
 
384
   surroundScale.setDefault(TRUE);
 
385
   antiSquish.setDefault(TRUE);
 
386
 
 
387
   SoDragger::setDefaultOnNonWritingFields();
 
388
}