Assembly: Enable moving objects while making joints.
This commit is contained in:
@@ -528,7 +528,7 @@ std::vector<App::DocumentObject*> AssemblyObject::getJoints(bool updateJCS, bool
|
||||
|
||||
// add sub assemblies joints.
|
||||
for (auto& assembly : getSubAssemblies()) {
|
||||
auto subJoints = assembly->getJoints(updateJCS);
|
||||
auto subJoints = assembly->getJoints(updateJCS, delBadJoints);
|
||||
joints.insert(joints.end(), subJoints.begin(), subJoints.end());
|
||||
}
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ public:
|
||||
void jointParts(std::vector<App::DocumentObject*> joints);
|
||||
JointGroup* getJointGroup();
|
||||
ViewGroup* getExplodedViewGroup();
|
||||
std::vector<App::DocumentObject*> getJoints(bool updateJCS = true, bool delBadJoints = true);
|
||||
std::vector<App::DocumentObject*> getJoints(bool updateJCS = true, bool delBadJoints = false);
|
||||
std::vector<App::DocumentObject*> getGroundedJoints();
|
||||
std::vector<App::DocumentObject*> getJointsOfObj(App::DocumentObject* obj);
|
||||
std::vector<App::DocumentObject*> getJointsOfPart(App::DocumentObject* part);
|
||||
|
||||
@@ -92,6 +92,8 @@ ViewProviderAssembly::ViewProviderAssembly()
|
||||
, canStartDragging(false)
|
||||
, partMoving(false)
|
||||
, enableMovement(true)
|
||||
, moveOnlyPreselected(false)
|
||||
, moveInCommand(true)
|
||||
, jointVisibilityBackup(false)
|
||||
, ctrlPressed(false)
|
||||
, docsToMove({})
|
||||
@@ -139,7 +141,6 @@ bool ViewProviderAssembly::canDragObject(App::DocumentObject* obj) const
|
||||
// else if a solid is removed, remove associated joints if any.
|
||||
bool prompted = false;
|
||||
auto* assemblyPart = static_cast<AssemblyObject*>(getObject());
|
||||
std::vector<App::DocumentObject*> joints = assemblyPart->getJoints();
|
||||
|
||||
// Combine the joints and groundedJoints vectors into one for simplicity.
|
||||
std::vector<App::DocumentObject*> allJoints = assemblyPart->getJoints();
|
||||
@@ -505,30 +506,33 @@ bool ViewProviderAssembly::getSelectedObjectsWithinAssembly(bool addPreselection
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto& selObj : Gui::Selection().getSelectionEx("",
|
||||
App::DocumentObject::getClassTypeId(),
|
||||
Gui::ResolveMode::NoResolve)) {
|
||||
// getSubNames() returns ["Body001.Pad.Face14", "Body002.Pad.Face7"]
|
||||
// if you have several objects within the same assembly selected.
|
||||
if (!moveOnlyPreselected) {
|
||||
for (auto& selObj : Gui::Selection().getSelectionEx("",
|
||||
App::DocumentObject::getClassTypeId(),
|
||||
Gui::ResolveMode::NoResolve)) {
|
||||
// getSubNames() returns ["Body001.Pad.Face14", "Body002.Pad.Face7"]
|
||||
// if you have several objects within the same assembly selected.
|
||||
|
||||
std::vector<std::string> objsSubNames = selObj.getSubNames();
|
||||
for (auto& subNamesStr : objsSubNames) {
|
||||
std::vector<std::string> subNames = parseSubNames(subNamesStr);
|
||||
if (subNames.empty()) {
|
||||
continue;
|
||||
std::vector<std::string> objsSubNames = selObj.getSubNames();
|
||||
for (auto& subNamesStr : objsSubNames) {
|
||||
std::vector<std::string> subNames = parseSubNames(subNamesStr);
|
||||
if (subNames.empty()) {
|
||||
continue;
|
||||
}
|
||||
if (onlySolids && subNames.back() != "") {
|
||||
continue;
|
||||
}
|
||||
|
||||
App::DocumentObject* obj = getObjectFromSubNames(subNames);
|
||||
|
||||
if (!canDragObjectIn3d(obj)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto* pPlc =
|
||||
dynamic_cast<App::PropertyPlacement*>(obj->getPropertyByName("Placement"));
|
||||
docsToMove.emplace_back(obj, pPlc->getValue());
|
||||
}
|
||||
if (onlySolids && subNames.back() != "") {
|
||||
continue;
|
||||
}
|
||||
|
||||
App::DocumentObject* obj = getObjectFromSubNames(subNames);
|
||||
|
||||
if (!canDragObjectIn3d(obj)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto* pPlc = dynamic_cast<App::PropertyPlacement*>(obj->getPropertyByName("Placement"));
|
||||
docsToMove.emplace_back(obj, pPlc->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -557,7 +561,7 @@ bool ViewProviderAssembly::getSelectedObjectsWithinAssembly(bool addPreselection
|
||||
if (!alreadyIn) {
|
||||
auto* pPlc =
|
||||
dynamic_cast<App::PropertyPlacement*>(obj->getPropertyByName("Placement"));
|
||||
if (!ctrlPressed) {
|
||||
if (!ctrlPressed && !moveOnlyPreselected) {
|
||||
Gui::Selection().clearSelection();
|
||||
docsToMove.clear();
|
||||
}
|
||||
@@ -772,8 +776,9 @@ void ViewProviderAssembly::initMove(const SbVec2s& cursorPos, Gui::View3DInvento
|
||||
prevPosition = initialPosition;
|
||||
}
|
||||
|
||||
|
||||
Gui::Command::openCommand(tr("Move part").toStdString().c_str());
|
||||
if (moveInCommand) {
|
||||
Gui::Command::openCommand(tr("Move part").toStdString().c_str());
|
||||
}
|
||||
partMoving = true;
|
||||
|
||||
// prevent selection while moving
|
||||
@@ -825,7 +830,9 @@ void ViewProviderAssembly::endMove()
|
||||
assemblyPart->setObjMasses({});
|
||||
}
|
||||
|
||||
Gui::Command::commitCommand();
|
||||
if (moveInCommand) {
|
||||
Gui::Command::commitCommand();
|
||||
}
|
||||
}
|
||||
|
||||
void ViewProviderAssembly::initMoveDragger()
|
||||
|
||||
@@ -114,6 +114,22 @@ public:
|
||||
{
|
||||
return enableMovement;
|
||||
}
|
||||
virtual void setMoveOnlyPreselected(bool enable = true)
|
||||
{
|
||||
moveOnlyPreselected = enable;
|
||||
}
|
||||
virtual bool getMoveOnlyPreselected() const
|
||||
{
|
||||
return moveOnlyPreselected;
|
||||
}
|
||||
virtual void setMoveInCommand(bool enable = true)
|
||||
{
|
||||
moveInCommand = enable;
|
||||
}
|
||||
virtual bool getMoveInCommand() const
|
||||
{
|
||||
return moveInCommand;
|
||||
}
|
||||
|
||||
|
||||
bool canDragObjectIn3d(App::DocumentObject* obj) const;
|
||||
@@ -150,6 +166,8 @@ public:
|
||||
bool canStartDragging;
|
||||
bool partMoving;
|
||||
bool enableMovement;
|
||||
bool moveOnlyPreselected;
|
||||
bool moveInCommand;
|
||||
bool jointVisibilityBackup;
|
||||
bool ctrlPressed;
|
||||
int numberOfSel;
|
||||
|
||||
@@ -31,6 +31,18 @@
|
||||
</Documentation>
|
||||
<Parameter Name="EnableMoving" Type="Boolean" />
|
||||
</Attribute>
|
||||
<Attribute Name="MoveOnlyPreselected">
|
||||
<Documentation>
|
||||
<UserDocu>If enabled, only the preselected object will move.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="MoveOnlyPreselected" Type="Boolean" />
|
||||
</Attribute>
|
||||
<Attribute Name="MoveInCommand">
|
||||
<Documentation>
|
||||
<UserDocu>If enabled, each move will be wrapped in a command.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="MoveInCommand" Type="Boolean" />
|
||||
</Attribute>
|
||||
<Attribute Name="DraggerVisibility">
|
||||
<Documentation>
|
||||
<UserDocu>Show or hide the assembly dragger.</UserDocu>
|
||||
|
||||
@@ -52,6 +52,26 @@ void ViewProviderAssemblyPy::setEnableMovement(Py::Boolean arg)
|
||||
getViewProviderAssemblyPtr()->setEnableMovement(arg);
|
||||
}
|
||||
|
||||
Py::Boolean ViewProviderAssemblyPy::getMoveOnlyPreselected() const
|
||||
{
|
||||
return {getViewProviderAssemblyPtr()->getMoveOnlyPreselected()};
|
||||
}
|
||||
|
||||
void ViewProviderAssemblyPy::setMoveOnlyPreselected(Py::Boolean arg)
|
||||
{
|
||||
getViewProviderAssemblyPtr()->setMoveOnlyPreselected(arg);
|
||||
}
|
||||
|
||||
Py::Boolean ViewProviderAssemblyPy::getMoveInCommand() const
|
||||
{
|
||||
return {getViewProviderAssemblyPtr()->getMoveInCommand()};
|
||||
}
|
||||
|
||||
void ViewProviderAssemblyPy::setMoveInCommand(Py::Boolean arg)
|
||||
{
|
||||
getViewProviderAssemblyPtr()->setMoveInCommand(arg);
|
||||
}
|
||||
|
||||
Py::Boolean ViewProviderAssemblyPy::getDraggerVisibility() const
|
||||
{
|
||||
return {getViewProviderAssemblyPtr()->getDraggerVisibility()};
|
||||
|
||||
@@ -1223,14 +1223,6 @@ class MakeJointSelGate:
|
||||
# Only objects within the assembly.
|
||||
return False
|
||||
|
||||
if Gui.Selection.isSelected(obj, sub, Gui.Selection.ResolveMode.NoResolve):
|
||||
# If it's to deselect then it's ok
|
||||
return True
|
||||
|
||||
if len(self.taskbox.current_selection) >= 2:
|
||||
# No more than 2 elements can be selected for basic joints.
|
||||
return False
|
||||
|
||||
full_obj_name = ".".join(objs_names)
|
||||
full_element_name = full_obj_name + "." + element_name
|
||||
selected_object = UtilsAssembly.getObject(full_element_name)
|
||||
@@ -1247,15 +1239,6 @@ class MakeJointSelGate:
|
||||
else:
|
||||
return False
|
||||
|
||||
part_containing_selected_object = UtilsAssembly.getContainingPart(
|
||||
full_element_name, selected_object, self.assembly
|
||||
)
|
||||
|
||||
for selection_dict in self.taskbox.current_selection:
|
||||
if selection_dict["part"] == part_containing_selected_object:
|
||||
# Can't join a solid to itself. So the user need to select 2 different parts.
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@@ -1285,7 +1268,8 @@ class TaskAssemblyCreateJoint(QtCore.QObject):
|
||||
return
|
||||
|
||||
if self.activeType == "Assembly":
|
||||
self.assembly.ViewObject.EnableMovement = False
|
||||
self.assembly.ViewObject.MoveOnlyPreselected = True
|
||||
self.assembly.ViewObject.MoveInCommand = False
|
||||
|
||||
self.form = Gui.PySideUic.loadUi(":/panels/TaskAssemblyCreateJoint.ui")
|
||||
|
||||
@@ -1358,6 +1342,8 @@ class TaskAssemblyCreateJoint(QtCore.QObject):
|
||||
|
||||
self.form.featureList.installEventFilter(self)
|
||||
|
||||
self.addition_rejected = False
|
||||
|
||||
def accept(self):
|
||||
if len(self.current_selection) != 2:
|
||||
App.Console.PrintWarning(
|
||||
@@ -1389,7 +1375,8 @@ class TaskAssemblyCreateJoint(QtCore.QObject):
|
||||
|
||||
if self.activeType == "Assembly":
|
||||
self.assembly.clearUndo()
|
||||
self.assembly.ViewObject.EnableMovement = True
|
||||
self.assembly.ViewObject.MoveOnlyPreselected = False
|
||||
self.assembly.ViewObject.MoveInCommand = True
|
||||
|
||||
Gui.Selection.removeSelectionGate()
|
||||
Gui.Selection.removeObserver(self)
|
||||
@@ -1831,6 +1818,23 @@ class TaskAssemblyCreateJoint(QtCore.QObject):
|
||||
element_name = UtilsAssembly.getElementName(full_element_name)
|
||||
part_containing_selected_object = self.getContainingPart(full_element_name, selected_object)
|
||||
|
||||
# Check if the addition is acceptable (we are not doing this in selection gate to let user move objects)
|
||||
acceptable = True
|
||||
if len(self.current_selection) >= 2:
|
||||
# No more than 2 elements can be selected for basic joints.
|
||||
acceptable = False
|
||||
|
||||
for selection_dict in self.current_selection:
|
||||
if selection_dict["part"] == part_containing_selected_object:
|
||||
# Can't join a solid to itself. So the user need to select 2 different parts.
|
||||
acceptable = False
|
||||
|
||||
if not acceptable:
|
||||
self.addition_rejected = True
|
||||
Gui.Selection.removeSelection(doc_name, obj_name, sub_name)
|
||||
return
|
||||
|
||||
# Selection is acceptable so add it
|
||||
selection_dict = {
|
||||
"object": selected_object,
|
||||
"part": part_containing_selected_object,
|
||||
@@ -1851,6 +1855,10 @@ class TaskAssemblyCreateJoint(QtCore.QObject):
|
||||
self.joint.ViewObject.Proxy.showPreviewJCS(False)
|
||||
|
||||
def removeSelection(self, doc_name, obj_name, sub_name, mousePos=None):
|
||||
if self.addition_rejected:
|
||||
self.addition_rejected = False
|
||||
return
|
||||
|
||||
full_element_name = UtilsAssembly.getFullElementName(obj_name, sub_name)
|
||||
selected_object = UtilsAssembly.getObject(full_element_name)
|
||||
element_name = UtilsAssembly.getElementName(full_element_name)
|
||||
|
||||
Reference in New Issue
Block a user