Skip to content

Commit

Permalink
+ fixes #1441: entering Transform mode degrades the Placemens rotatio…
Browse files Browse the repository at this point in the history
…n to single precision
  • Loading branch information
wwmayer committed Feb 27, 2014
1 parent daf8b1d commit a48ec3c
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
47 changes: 47 additions & 0 deletions src/Gui/ViewProviderGeometryObject.cpp
Expand Up @@ -226,12 +226,17 @@ bool ViewProviderGeometryObject::setEdit(int ModNum)
SoDragger* dragger = manip->getDragger();
dragger->addStartCallback(dragStartCallback, this);
dragger->addFinishCallback(dragFinishCallback, this);
#if 1
dragger->addMotionCallback(dragMotionCallback, this);
dragger->setUserData(manip);
#else
// Attach a sensor to the transform manipulator and set it as its user
// data to delete it when the view provider leaves the edit mode
SoNodeSensor* sensor = new SoNodeSensor(sensorCallback, this);
//sensor->setPriority(0);
sensor->attach(manip);
manip->setUserData(sensor);
#endif
return manip->replaceNode(path);
}
return false;
Expand Down Expand Up @@ -289,16 +294,20 @@ void ViewProviderGeometryObject::unsetEdit(int ModNum)

// The manipulator has a sensor as user data and this sensor contains the view provider
SoCenterballManip * manip = static_cast<SoCenterballManip*>(path->getTail());
#if 0
SoNodeSensor* sensor = reinterpret_cast<SoNodeSensor*>(manip->getUserData());
#endif
// #0000939: Pressing Escape while pivoting a box crashes
// #0000942: Crash when 2xdouble-click on part
SoDragger* dragger = manip->getDragger();
if (dragger && dragger->getHandleEventAction())
dragger->grabEventsCleanup();

#if 0
// detach sensor
sensor->detach();
delete sensor;
#endif

SoTransform* transform = this->pcTransform;
manip->replaceManip(path, transform);
Expand Down Expand Up @@ -430,6 +439,44 @@ void ViewProviderGeometryObject::sensorCallback(void * data, SoSensor * s)
#endif
}

void ViewProviderGeometryObject::dragMotionCallback(void * data, SoDragger * d)
{
SoNode* node = reinterpret_cast<SoNode*>(d->getUserData());
if (node && node->getTypeId().isDerivedFrom(SoCenterballManip::getClassTypeId())) {
// apply the transformation data to the placement
SoCenterballManip* manip = static_cast<SoCenterballManip*>(node);
float q0, q1, q2, q3;
// See also SoTransformManip::valueChangedCB
// to get translation directly from dragger
SbVec3f move = manip->translation.getValue();
SbVec3f center = manip->center.getValue();
manip->rotation.getValue().getValue(q0, q1, q2, q3);

// get the placement
ViewProviderGeometryObject* view = reinterpret_cast<ViewProviderGeometryObject*>(data);
if (view && view->pcObject && view->pcObject->getTypeId().isDerivedFrom(App::GeoFeature::getClassTypeId())) {
App::GeoFeature* geometry = static_cast<App::GeoFeature*>(view->pcObject);
// Note: If R is the rotation, c the rotation center and t the translation
// vector then Inventor applies the following transformation: R*(x-c)+c+t
// In FreeCAD a placement only has a rotation and a translation part but
// no rotation center. This means that we must divide the transformation
// in a rotation and translation part.
// R * (x-c) + c + t = R * x - R * c + c + t
// The rotation part is R, the translation part t', however, is:
// t' = t + c - R * c
Base::Placement p;
p.setRotation(Base::Rotation(q0,q1,q2,q3));
Base::Vector3d t(move[0],move[1],move[2]);
Base::Vector3d c(center[0],center[1],center[2]);
t += c;
p.getRotation().multVec(c,c);
t -= c;
p.setPosition(t);
geometry->Placement.setValue(p);
}
}
}

void ViewProviderGeometryObject::dragStartCallback(void *data, SoDragger *)
{
// This is called when a manipulator is about to manipulating
Expand Down
1 change: 1 addition & 0 deletions src/Gui/ViewProviderGeometryObject.h
Expand Up @@ -105,6 +105,7 @@ class GuiExport ViewProviderGeometryObject : public ViewProviderDocumentObject
static void sensorCallback(void * data, SoSensor * sensor);
static void dragStartCallback(void * data, SoDragger * d);
static void dragFinishCallback(void * data, SoDragger * d);
static void dragMotionCallback(void * data, SoDragger * d);

protected:
SoFCSelection * pcHighlight;
Expand Down

0 comments on commit a48ec3c

Please sign in to comment.