-
Notifications
You must be signed in to change notification settings - Fork 9
/
lattice2SubstituteObject.py
139 lines (122 loc) · 7.34 KB
/
lattice2SubstituteObject.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#***************************************************************************
#* *
#* Copyright (c) 2015 - Victor Titov (DeepSOIC) *
#* <[email protected]> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
__title__="Lattice SubstituteObject command module"
__author__ = "DeepSOIC"
import FreeCAD as App
from replaceobj import replaceobj #from OpenSCAD wb, the code that drives replaceChild
from lattice2Common import *
def getAllDependencies(feat):
'''getAllDependencies(feat): gets all features feat depends on, directly or indirectly. Returns a list, with deepest dependencies last.'''
list_traversing_now = [feat]
set_of_deps = set()
list_of_deps = []
while len(list_traversing_now) > 0:
list_to_be_traversed_next = []
for feat in list_traversing_now:
for dep in feat.OutList:
if not (dep in set_of_deps):
set_of_deps.add(dep)
list_of_deps.append(dep)
list_to_be_traversed_next.append(dep)
list_traversing_now = list_to_be_traversed_next
return list_of_deps
def substituteobj(oldobj, newobj):
'''Replaces all links to oldobj in the document with links to newobj.
Returns a tuple (list_replaced, list_not_replaced)'''
deps_of_new = getAllDependencies(newobj) + [newobj]
list_not_replaced = []
list_replaced = []
for dep in oldobj.InList:
if dep in deps_of_new:
#we are about to make an object newobj depends on, to depend on newobj.
#This will create a circular graph, so we must skip this.
print ("not replacing "+oldobj.Name+" with " + newobj.Name +" in " + dep.Name)
list_not_replaced.append(dep)
else:
print ("replacing "+oldobj.Name+" with " + newobj.Name +" in " + dep.Name)
list_replaced.append(dep)
replaceobj(dep, oldobj, newobj)
return (list_replaced, list_not_replaced)
class CommandSubstituteObject:
"Command to substitute object"
def GetResources(self):
return {'Pixmap' : getIconPath("Lattice2_SubstituteObject.svg"),
'MenuText': QtCore.QT_TRANSLATE_NOOP("Lattice2_SubstituteObject","Substitute object"),
'Accel': "",
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Lattice2_SubstituteObject","Substitute Object: find all links to one of the selected objects, and rediret them all to another object")}
def Activated(self):
sel = FreeCADGui.Selection.getSelectionEx()
if len(sel) == 2 :
App.ActiveDocument.openTransaction("Substitute "+sel[0].ObjectName+" with "+sel[1].ObjectName)
try:
#do it
if len(sel[0].Object.InList) == 0:
raise ValueError("First selected object isn't referenced by anything; nothing to do.")
dummy, list_not_replaced = substituteobj(sel[0].Object, sel[1].Object)
App.ActiveDocument.commitTransaction()
#verify results: oldobject should not be referenced by anything anymore.
if len(sel[0].Object.InList) != 0:
set_failed = set(sel[0].Object.InList).difference(set(list_not_replaced))
mb = QtGui.QMessageBox()
if len(set_failed) > 0:
mb.setIcon(mb.Icon.Warning)
msg = translate("Lattice2_SubstituteObject", "Some of the links couldn't be redirected, because they are not supported by the tool. Link redirection failed for: \n%1\nTo redirect these links, the objects have to be edited manually. Sorry!", None)
rem_links = [lnk.Label for lnk in set_failed]
else:
mb.setIcon(mb.Icon.Information)
msg = translate("Lattice2_SubstituteObject", "The following objects still link to old object: \n%1\nReplacing those links would have caused loops in dependency graph, so they were skipped.", None)
rem_links = [lnk.Label for lnk in sel[0].Object.InList]
mb.setText(msg.replace(u"%1", u"\n".join(rem_links)))
mb.setWindowTitle(translate("Lattice2_SubstituteObject","Error", None))
mb.exec_()
except Exception as err:
mb = QtGui.QMessageBox()
mb.setIcon(mb.Icon.Warning)
mb.setText(translate("Lattice2_SubstituteObject", "An error occurred while substituting object:", None)+ u"\n"
+ str(err))
mb.setWindowTitle(translate("Lattice2_SubstituteObject","Error", None))
mb.exec_()
App.ActiveDocument.abortTransaction()
return
#hide/unhide
try:
old_was_visible = sel[0].Object.ViewObject.Visibility
new_was_visible = sel[1].Object.ViewObject.Visibility
sel[0].Object.ViewObject.Visibility = True
sel[1].Object.ViewObject.Visibility = old_was_visible
except Exception as err:
App.Console.PrintError("SubstituteFeature: error when changing visibilities: "+str(err)+"\n")
else:
mb = QtGui.QMessageBox()
mb.setIcon(mb.Icon.Warning)
mb.setText(translate("Lattice2_SubstituteObject", "Select two objects, first! The first one is the one to be substituted, and the second one is the object to redirect all links to.", None))
mb.setWindowTitle(translate("Lattice2_SubstituteObject","Bad selection", None))
mb.exec_()
def IsActive(self):
if FreeCAD.ActiveDocument:
return True
else:
return False
if FreeCAD.GuiUp:
FreeCADGui.addCommand('Lattice2_SubstituteObject', CommandSubstituteObject())
exportedCommands = ['Lattice2_SubstituteObject']