Assembly: Adds a dragger object to the assembly, so that assembly tools can access a dragger.

This commit is contained in:
PaddleStroke
2024-03-08 09:53:24 +01:00
committed by Yorik van Havre
parent 136d73ec1e
commit 6a834422e7
4 changed files with 182 additions and 1 deletions

View File

@@ -28,19 +28,29 @@
#include <vector>
#include <sstream>
#include <iostream>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/draggers/SoDragger.h>
#include <Inventor/events/SoKeyboardEvent.h>
#include <Inventor/nodes/SoSwitch.h>
#include <Inventor/nodes/SoTransform.h>
#include <Inventor/sensors/SoFieldSensor.h>
#include <Inventor/sensors/SoSensor.h>
#endif
#include <App/Link.h>
#include <App/Document.h>
#include <App/DocumentObject.h>
#include <App/Part.h>
#include <Gui/Application.h>
#include <Gui/BitmapFactory.h>
#include <Gui/CommandT.h>
#include <Gui/MDIView.h>
#include <Gui/SoFCCSysDragger.h>
#include <Gui/View3DInventor.h>
#include <Gui/View3DInventorViewer.h>
#include <Gui/ViewParams.h>
#include <Mod/Assembly/App/AssemblyObject.h>
#include <Mod/Assembly/App/AssemblyUtils.h>
#include <Mod/Assembly/App/JointGroup.h>
@@ -177,6 +187,7 @@ bool ViewProviderAssembly::canDragObject(App::DocumentObject* obj) const
bool ViewProviderAssembly::setEdit(int ModNum)
{
Q_UNUSED(ModNum);
// Set the part as 'Activated' ie bold in the tree.
Gui::Command::doCommand(Gui::Command::Gui,
"Gui.ActiveDocument.ActiveView.setActiveObject('%s', "
@@ -185,6 +196,8 @@ bool ViewProviderAssembly::setEdit(int ModNum)
this->getObject()->getDocument()->getName(),
this->getObject()->getNameInDocument());
setDragger();
return true;
}
@@ -195,6 +208,8 @@ void ViewProviderAssembly::unsetEdit(int ModNum)
partMoving = false;
docsToMove = {};
unsetDragger();
// Check if the view is still active before trying to deactivate the assembly.
auto doc = getDocument();
if (!doc) {
@@ -213,6 +228,42 @@ void ViewProviderAssembly::unsetEdit(int ModNum)
PARTKEY);
}
void ViewProviderAssembly::setDragger()
{
// Create the dragger coin object
assert(!asmDragger);
asmDragger = new Gui::SoFCCSysDragger();
asmDragger->setAxisColors(Gui::ViewParams::instance()->getAxisXColor(),
Gui::ViewParams::instance()->getAxisYColor(),
Gui::ViewParams::instance()->getAxisZColor());
asmDragger->draggerSize.setValue(0.05f);
asmDraggerSwitch = new SoSwitch(SO_SWITCH_NONE);
asmDraggerSwitch->addChild(asmDragger);
pcRoot->insertChild(asmDraggerSwitch, 0);
asmDraggerSwitch->ref();
asmDragger->ref();
}
void ViewProviderAssembly::unsetDragger()
{
pcRoot->removeChild(asmDraggerSwitch);
asmDragger->unref();
asmDragger = nullptr;
asmDraggerSwitch->unref();
asmDraggerSwitch = nullptr;
}
void ViewProviderAssembly::setEditViewer(Gui::View3DInventorViewer* viewer, int ModNum)
{
ViewProviderPart::setEditViewer(viewer, ModNum);
if (asmDragger && viewer) {
asmDragger->setUpAutoScale(viewer->getSoRenderManager()->getCamera());
}
}
bool ViewProviderAssembly::isInEditMode() const
{
App::DocumentObject* activePart = getActivePart();
@@ -240,6 +291,7 @@ App::DocumentObject* ViewProviderAssembly::getActivePart() const
bool ViewProviderAssembly::keyPressed(bool pressed, int key)
{
Q_UNUSED(pressed);
if (key == SoKeyboardEvent::ESCAPE) {
if (isInEditMode()) {
@@ -383,6 +435,7 @@ bool ViewProviderAssembly::mouseButtonPressed(int Button,
{
Q_UNUSED(cursorPos);
Q_UNUSED(viewer);
// Left Mouse button ****************************************************
if (Button == 1) {
if (pressed) {
@@ -757,6 +810,45 @@ bool ViewProviderAssembly::onDelete(const std::vector<std::string>& subNames)
return ViewProviderPart::onDelete(subNames);
}
void ViewProviderAssembly::setDraggerVisibility(bool val)
{
asmDraggerSwitch->whichChild = val ? SO_SWITCH_ALL : SO_SWITCH_NONE;
}
bool ViewProviderAssembly::getDraggerVisibility()
{
return asmDraggerSwitch->whichChild.getValue() == SO_SWITCH_ALL;
}
void ViewProviderAssembly::setDraggerPlacement(Base::Placement plc)
{
double q0, q1, q2, q3;
plc.getRotation().getValue(q0, q1, q2, q3);
Base::Vector3d pos = plc.getPosition();
asmDragger->rotation.setValue(q0, q1, q2, q3);
asmDragger->translation.setValue(pos.x, pos.y, pos.z);
}
Base::Placement ViewProviderAssembly::getDraggerPlacement()
{
Base::Placement plc;
SbVec3f pos = asmDragger->translation.getValue();
plc.setPosition(Base::Vector3d(pos[0], pos[1], pos[2]));
SbVec3f axis;
float angle;
asmDragger->rotation.getValue(axis, angle);
Base::Vector3d axisV = Base::Vector3d(axis[0], axis[1], axis[2]);
Base::Rotation rot(axisV, angle);
plc.setRotation(rot);
return plc;
}
Gui::SoFCCSysDragger* ViewProviderAssembly::getDragger()
{
return asmDragger;
}
PyObject* ViewProviderAssembly::getPyObject()
{
if (!pyViewObject) {

View File

@@ -31,10 +31,16 @@
#include <Gui/Selection.h>
#include <Gui/ViewProviderPart.h>
class SoSwitch;
class SoSensor;
class SoDragger;
class SoFieldSensor;
namespace Gui
{
class SoFCCSysDragger;
class View3DInventorViewer;
}
} // namespace Gui
namespace AssemblyGui
{
@@ -71,6 +77,7 @@ public:
//@{
bool setEdit(int ModNum) override;
void unsetEdit(int ModNum) override;
void setEditViewer(Gui::View3DInventorViewer*, int ModNum) override;
bool isInEditMode() const;
/// Ask the view provider if it accepts object deletions while in edit
@@ -120,6 +127,15 @@ public:
void onSelectionChanged(const Gui::SelectionChanges& msg) override;
// Dragger controls:
void setDragger();
void unsetDragger();
void setDraggerVisibility(bool val);
bool getDraggerVisibility();
void setDraggerPlacement(Base::Placement plc);
Base::Placement getDraggerPlacement();
Gui::SoFCCSysDragger* getDragger();
DragMode dragMode;
bool canStartDragging;
bool partMoving;
@@ -136,6 +152,11 @@ public:
std::vector<std::pair<App::DocumentObject*, double>> objectMasses;
std::vector<std::pair<App::DocumentObject*, Base::Placement>> docsToMove;
Gui::SoFCCSysDragger* asmDragger = nullptr;
SoSwitch* asmDraggerSwitch = nullptr;
SoFieldSensor* translationSensor = nullptr;
SoFieldSensor* rotationSensor = nullptr;
};
} // namespace AssemblyGui

View File

@@ -13,11 +13,35 @@
<Author Licence="LGPL" Name="Ondsel" EMail="development@ondsel.com" />
<UserDocu>This is the ViewProviderAssembly class</UserDocu>
</Documentation>
<Methode Name="getDragger">
<Documentation>
<UserDocu>
Return the assembly dragger coin object.
getDragger() -> SoFCCSysDragger
Returns: dragger coin object of the assembly
</UserDocu>
</Documentation>
</Methode>
<Attribute Name="EnableMovement">
<Documentation>
<UserDocu>Enable moving the parts by clicking and dragging.</UserDocu>
</Documentation>
<Parameter Name="EnableMoving" Type="Boolean" />
</Attribute>
<Attribute Name="DraggerVisibility">
<Documentation>
<UserDocu>Show or hide the assembly dragger.</UserDocu>
</Documentation>
<Parameter Name="DraggerVisibility" Type="Boolean" />
</Attribute>
<Attribute Name="DraggerPlacement" ReadOnly="false">
<Documentation>
<UserDocu>Placement of the assembly dragger object.</UserDocu>
</Documentation>
<Parameter Name="Placement" Type="Object" />
</Attribute>
</PythonExport>
</GenerateModel>

View File

@@ -22,6 +22,10 @@
#include "PreCompiled.h"
#include <Base/Interpreter.h>
#include <Base/PlacementPy.h>
#include <Base/GeometryPyCXX.h>
// inclusion of the generated files (generated out of ViewProviderAssemblyPy.xml)
#include "ViewProviderAssemblyPy.h"
#include "ViewProviderAssemblyPy.cpp"
@@ -48,6 +52,46 @@ void ViewProviderAssemblyPy::setEnableMovement(Py::Boolean arg)
getViewProviderAssemblyPtr()->setEnableMovement(arg);
}
Py::Boolean ViewProviderAssemblyPy::getDraggerVisibility() const
{
return {getViewProviderAssemblyPtr()->getDraggerVisibility()};
}
void ViewProviderAssemblyPy::setDraggerVisibility(Py::Boolean arg)
{
getViewProviderAssemblyPtr()->setDraggerVisibility(arg);
}
PyObject* ViewProviderAssemblyPy::getDragger(PyObject* args)
{
if (!PyArg_ParseTuple(args, "")) {
return nullptr;
}
Gui::SoFCCSysDragger* asmDragger = getViewProviderAssemblyPtr()->getDragger();
return Base::Interpreter().createSWIGPointerObj("pivy.coin", "SoDragger *", asmDragger, 0);
}
Py::Object ViewProviderAssemblyPy::getDraggerPlacement() const
{
return Py::Placement(getViewProviderAssemblyPtr()->getDraggerPlacement());
}
void ViewProviderAssemblyPy::setDraggerPlacement(Py::Object arg)
{
PyObject* p = arg.ptr();
if (PyObject_TypeCheck(p, &(Base::PlacementPy::Type))) {
Base::Placement* trf = static_cast<Base::PlacementPy*>(p)->getPlacementPtr();
getViewProviderAssemblyPtr()->setDraggerPlacement(*trf);
}
else {
std::string error = std::string("type must be 'Placement', not ");
error += p->ob_type->tp_name;
throw Py::TypeError(error);
}
}
PyObject* ViewProviderAssemblyPy::getCustomAttributes(const char* /*attr*/) const
{
return nullptr;