1 try: 2 import poser 3 except ImportError: 4 from PoserLibs import POSER_FAKE as poser 5 6 import WXtools 7 8 reload(WXtools) 9 from WXtools import * 10 11 SCENE = poser.Scene() 12 13 14 class Deformer(object): 15 __slots__ = ("mag", # the magnet - 16 "base", # its base - 17 "zones", # and the zones. 18 ) 19 20 def __init__(self, mag, base, zones): 21 self.mag = mag 22 self.base = base 23 self.zones = zones 24 25 26 def getMagnetSet(ac_or_name): 27 if isinstance(ac_or_name, basestring): 28 ac = SCENE.actor(ac_or_name) 29 else: 30 ac = ac_or_name 31 32 base = mag = zone = None 33 if ac.IsBase(): 34 base = ac 35 mag = base.Children()[0] 36 elif ac.IsDeformer(): 37 mag = ac 38 base = mag.Parent() 39 elif ac.IsZone(): 40 zone = ac 41 common_name = zone.Name()[:-1] 42 for p in ac.Parent().Children(): 43 if p.Name().startwith(common_name): 44 if p.Name()[-1] == "B": 45 base = p 46 elif p.Name()[-1] == "M": 47 mag = p 48 49 return mag, base 50 51 52 def collectMagnets(base=SCENE): 53 ar = list() 54 for ac in base.Actors(): 55 if ac.IsDeformer(): 56 ar.append(ac.InternalName()) 57 58 59 def CreateMagnet(name, parent=None): 60 for ac in SCENE.Actors(): # type: poser.ActorType 61 if ac.IsDeformer() and ac.Name() == name: 62 return getMagnetSet(ac) 63 64 ac = SCENE.CurrentActor() 65 66 if isinstance(parent, poser.ActorType): 67 SCENE.SelectActor(parent) 68 else: 69 parent = ac 70 71 mag = SCENE.CreateMagnet() # type: poser.ActorType 72 oldname = mag.Name() 73 zone = mag.Zones()[0] 74 base = mag.Parent() 75 76 mag.SetName(name + "_Mag") 77 base.SetName(name + "_Base") 78 if len(mag.Zones()) > 1: 79 for idx, z in enumerate(mag.Zones()): 80 zone.SetName(name + "_(%d)Zone" % idx) 81 else: 82 mag.Zones()[0].SetName(name + "_Zone") 83 for p in parent.Parameters(): # type: poser.ParmType 84 if (not p.Name().strip()) or p.Name().startswith(oldname): 85 p.SetName(name) 86 87 SCENE.SelectActor(ac) 88 return mag, base 89 90 91 def getActorList(unfiltered=False, withgeometry=False, isbodypart=False): 92 def excluded(ac): 93 if unfiltered: 94 return False 95 if withgeometry: 96 if ac.Geometry() is None \ 97 or ac.Geometry().NumVertices() == 0: 98 return True 99 if isbodypart and not ac.IsBodyPart(): 100 return True 101 return ac.IsDeformer() or ac.IsBase() or ac.IsZone() or \ 102 ac.IsCamera() or ac.IsControlProp() or ac.IsLight() or \ 103 ac.IsMeasurement() 104 105 return sorted([ac.Name() for ac in SCENE.Actors() 106 if not excluded(ac)], 107 key=lambda a: a[0].upper() + a[1:]) 108 109 110 class MagnetDialog(wx.Dialog): 111 def __init__(self, *args, **kwargs): 112 wx.Dialog.__init__(self, *args, **kwargs) 113 self.gb_manager = GridBagManager(parent=self, 114 sizer=wx.GridBagSizer(0, 0), 115 flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 116 border=2 117 ) 118 self.SetBackgroundColour(BG_COLOR) 119 self.SetForegroundColour(FG_COLOR) 120 121 self.dialogitems = self.gb_manager.widgets 122 123 f = wx.Font(SYS_FONT.GetPointSize() + 2, family=SYS_FONT.GetFamily(), 124 style=SYS_FONT.GetStyle(), weight=wx.BOLD) 125 headline = PrepCtrl(wx.StaticText, id=-1, label="Magnet Utility", font=f) 126 127 self.InitUI(self.gb_manager) 128 129 main_sizer = wx.BoxSizer(wx.VERTICAL) 130 main_sizer.Add(headline, 0, wx.ALL | wx.ALIGN_LEFT, 5) 131 main_sizer.AddStretchSpacer(0) 132 main_sizer.Add(self.gb_manager.sizer, 1, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, 5) 133 btn_sizer = ButtonRow(wx.Button(self, id=wx.ID_OK), 134 wx.Button(self, id=wx.ID_CANCEL)) 135 main_sizer.Add(btn_sizer, 0, wx.ALL | wx.ALIGN_CENTER, 5) 136 137 self.SetAutoLayout(True) 138 self.SetSizer(main_sizer) 139 main_sizer.Fit(self) 140 141 self.Bind(wx.EVT_WINDOW_DESTROY, self.onClose) 142 self.Bind(wx.EVT_SIZE, self.onSize) 143 144 def get_item_by_name(self, *args): 145 return self.gb_manager.get_item_by_name(*args) 146 147 def onClose(self, ev): 148 ev.Skip() 149 150 def onSize(self, ev): 151 ev.Skip() 152 153 def onCheckBox(self, ev): 154 ev.Skip() 155 156 def onChoice(self, ev): 157 ev.Skip() 158 return 159 160 obj = ev.GetEventObject() # type: wx.Choice 161 idx = obj.GetSelection() 162 name = str(obj.GetString(idx)) 163 c = name[0] 164 comp = "LR" if c.isupper() else "lr" 165 opposite = comp[c[0].lower() == "l"] + name[1:] 166 try: 167 idx = getActorList().index(opposite) 168 except IndexError: 169 idx = None 170 171 print("OPPOSITE", opposite if idx is not None else "None") 172 173 obj = self.FindWindowByName("makepair") 174 if obj: 175 obj.SetValue(idx is not None) 176 177 def InitUI(self, gbm): 178 actorlist = getActorList(unfiltered=True) 179 actoridx = actorlist.index(SCENE.CurrentActor().Name()) 180 181 # Attribute "key" is actually exchanged with "name". 182 # Using "key" makes clear it is the key used in the 183 # dictionary with results (after dialog is closed). 184 gbm.addrows( 185 Labeled(wx.Choice, label="Actor", key="actor", 186 choices=actorlist, index=actoridx, 187 tooltip="Create new magnet in this actor", 188 bind=(wx.EVT_CHOICE, self.onChoice)), 189 Labeled(wx.TextCtrl, label="Name", key="Magname", 190 tooltip="New magnets name"), 191 Labeled(wx.TextCtrl, label="Base Size %", key="b_size", style=wx.TE_RIGHT, 192 value="15", tooltip="Size of base control in percent"), 193 Labeled(wx.TextCtrl, label="Zone Size %", key="z_size", style=wx.TE_RIGHT, 194 value="10", tooltip="Size of Zone control in percent"), 195 Labeled(wx.CheckBox, label="Zone Wireframe", key="wframe", style=wx.ALIGN_RIGHT, 196 value=True, tooltip="Check to set zones displaystyle to wireframe"), 197 None, # an empty row 198 Labeled(wx.CheckListBox, label="Affected Actors", key="affected", 199 choices=getActorList(withgeometry=True), 200 tooltip="Select actors affected by this deformer."), 201 # Labeled(wx.CheckBox, label="Create Pair", key="makepair", style=wx.ALIGN_RIGHT, 202 # value=False, tooltip="Make another magnet at the other side"), 203 204 ) 205 206 gbm.bindCtrls(wx.CheckBox, wx.EVT_CHECKBOX, self.onCheckBox) 207 208 209 with MagnetDialog(None, -1, style=wx.DEFAULT_DIALOG_STYLE) as dlg: 210 res = dlg.ShowModal() 211 if res == wx.ID_OK: 212 data = dlg.gb_manager.items_as_dict() 213 magname = data["Magname"] 214 #print("Mag Name:", magname) 215 #print("Actor:", data["actor"]) 216 #print("Affected:", data["affected"]) 217 218 if magname.strip() and SCENE.Actor(data["actor"]): 219 ac = SCENE.Actor(data["actor"]) 220 SCENE.SelectActor(ac) 221 mag, base = CreateMagnet(name=magname) 222 if data["wframe"]: 223 [z.SetDisplayStyle(poser.kDisplayCodeWIREFRAME) for z in mag.Zones()] 224 v = int(data["b_size"]) 225 if v: 226 base.SetParameter("Scale", v / 100.0) 227 v = int(data["z_size"]) 228 if v: 229 [z.SetParameter("Scale", v / 100.0) for z in mag.Zones()] 230 231 mag.SetMagnetAffectedObjects([SCENE.Actor(objname) 232 for objname in data.get("affected", [])] + [ac,]) 233 234 # rename Parameter names in affected actors 235 for actor in mag.MagnetAffectedObjects(): 236 for p in actor.Parameters(): 237 if p.Name().startswith(mag.Name()): 238 p.SetName(magname) 239 break 240