Assembly: Explode temporarily (#25456)
This commit is contained in:
@@ -126,6 +126,12 @@ class ExplodedView:
|
||||
|
||||
return positions
|
||||
|
||||
def explodeTemporarily(self, viewObj):
|
||||
self.initialPlcs = UtilsAssembly.saveAssemblyPartsPlacements(self.getAssembly(viewObj))
|
||||
self.applyMoves(viewObj)
|
||||
for move in viewObj.Group:
|
||||
move.Visibility = True
|
||||
|
||||
def getAssembly(self, viewObj):
|
||||
for obj in viewObj.InList:
|
||||
if obj.isDerivedFrom("Assembly::AssemblyObject"):
|
||||
@@ -162,6 +168,9 @@ class ExplodedView:
|
||||
|
||||
UtilsAssembly.restoreAssemblyPartsPlacements(self.getAssembly(viewObj), self.initialPlcs)
|
||||
|
||||
for move in viewObj.Group:
|
||||
move.Visibility = False
|
||||
|
||||
def _calculateExplodedPlacements(self, viewObj):
|
||||
"""
|
||||
Internal helper to calculate final placements for an exploded view without
|
||||
@@ -464,6 +473,7 @@ class ExplodedViewStep:
|
||||
if move.ViewObject:
|
||||
endPos = UtilsAssembly.getCenterOfBoundingBox([obj], [ref])
|
||||
positions.append([startPos, endPos])
|
||||
obj.purgeTouched()
|
||||
|
||||
if move.ViewObject:
|
||||
move.ViewObject.Proxy.redrawLines(move, positions)
|
||||
@@ -647,6 +657,8 @@ class TaskAssemblyCreateView(QtCore.QObject):
|
||||
self.currentStep = None
|
||||
self.radialExplosion = False
|
||||
|
||||
self.viewObj.purgeTouched()
|
||||
|
||||
def accept(self):
|
||||
self.deactivate()
|
||||
UtilsAssembly.restoreAssemblyPartsPlacements(self.assembly, self.initialPlcs)
|
||||
@@ -658,6 +670,8 @@ class TaskAssemblyCreateView(QtCore.QObject):
|
||||
commands = commands + more
|
||||
Gui.doCommand(commands[:-1]) # Don't use the last \n
|
||||
App.closeActiveTransaction()
|
||||
|
||||
self.viewObj.purgeTouched()
|
||||
return True
|
||||
|
||||
def reject(self):
|
||||
|
||||
@@ -1226,11 +1226,19 @@ void ViewProviderAssembly::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
isolateJointReferences(obj);
|
||||
return;
|
||||
}
|
||||
else if (explodeTemporarily(obj)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
clearIsolate();
|
||||
clearTemporaryExplosion();
|
||||
}
|
||||
}
|
||||
if (msg.Type == Gui::SelectionChanges::ClrSelection
|
||||
|| msg.Type == Gui::SelectionChanges::RmvSelection) {
|
||||
clearIsolate();
|
||||
clearTemporaryExplosion();
|
||||
}
|
||||
|
||||
if (!isInEditMode()) {
|
||||
@@ -1609,6 +1617,76 @@ void ViewProviderAssembly::slotAboutToOpenTransaction(const std::string& cmdName
|
||||
{
|
||||
Q_UNUSED(cmdName);
|
||||
this->clearIsolate();
|
||||
this->clearTemporaryExplosion();
|
||||
}
|
||||
|
||||
bool ViewProviderAssembly::explodeTemporarily(App::DocumentObject* explodedView)
|
||||
{
|
||||
if (!explodedView || temporaryExplosion == explodedView) {
|
||||
return false;
|
||||
}
|
||||
|
||||
clearTemporaryExplosion();
|
||||
|
||||
Base::PyGILStateLocker lock;
|
||||
|
||||
App::PropertyPythonObject* proxy = explodedView
|
||||
? dynamic_cast<App::PropertyPythonObject*>(explodedView->getPropertyByName("Proxy"))
|
||||
: nullptr;
|
||||
|
||||
if (!proxy) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Py::Object jointPy = proxy->getValue();
|
||||
|
||||
if (!jointPy.hasAttr("explodeTemporarily")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Py::Object attr = jointPy.getAttr("explodeTemporarily");
|
||||
if (attr.ptr() && attr.isCallable()) {
|
||||
Py::Tuple args(1);
|
||||
args.setItem(0, Py::asObject(explodedView->getPyObject()));
|
||||
Py::Callable(attr).apply(args);
|
||||
temporaryExplosion = explodedView;
|
||||
temporaryExplosion->purgeTouched();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ViewProviderAssembly::clearTemporaryExplosion()
|
||||
{
|
||||
if (!temporaryExplosion) {
|
||||
return;
|
||||
}
|
||||
|
||||
Base::PyGILStateLocker lock;
|
||||
|
||||
App::PropertyPythonObject* proxy = temporaryExplosion
|
||||
? dynamic_cast<App::PropertyPythonObject*>(temporaryExplosion->getPropertyByName("Proxy"))
|
||||
: nullptr;
|
||||
|
||||
if (!proxy) {
|
||||
return;
|
||||
}
|
||||
|
||||
Py::Object jointPy = proxy->getValue();
|
||||
|
||||
if (!jointPy.hasAttr("restoreAssembly")) {
|
||||
return;
|
||||
}
|
||||
|
||||
Py::Object attr = jointPy.getAttr("restoreAssembly");
|
||||
if (attr.ptr() && attr.isCallable()) {
|
||||
Py::Tuple args(1);
|
||||
args.setItem(0, Py::asObject(temporaryExplosion->getPyObject()));
|
||||
Py::Callable(attr).apply(args);
|
||||
temporaryExplosion->purgeTouched();
|
||||
temporaryExplosion = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// UTILS
|
||||
|
||||
@@ -217,6 +217,8 @@ public:
|
||||
void isolateComponents(std::set<App::DocumentObject*>& parts, IsolateMode mode);
|
||||
void isolateJointReferences(App::DocumentObject* joint, IsolateMode mode = IsolateMode::Transparent);
|
||||
void clearIsolate();
|
||||
bool explodeTemporarily(App::DocumentObject* explodedView);
|
||||
void clearTemporaryExplosion();
|
||||
|
||||
DragMode dragMode;
|
||||
bool canStartDragging;
|
||||
@@ -276,6 +278,7 @@ private:
|
||||
};
|
||||
|
||||
std::unordered_map<App::DocumentObject*, ComponentState> stateBackup;
|
||||
App::DocumentObject* temporaryExplosion {nullptr};
|
||||
App::DocumentObject* isolatedJoint {nullptr};
|
||||
bool isolatedJointVisibilityBackup {false};
|
||||
|
||||
|
||||
@@ -1163,6 +1163,7 @@ def restoreAssemblyPartsPlacements(assembly, initialPlcs):
|
||||
for part in assemblyParts:
|
||||
if part.Name in initialPlcs:
|
||||
part.Placement = initialPlcs[part.Name]
|
||||
part.purgeTouched()
|
||||
|
||||
|
||||
def getComAndSize(assembly):
|
||||
|
||||
Reference in New Issue
Block a user