XPresso ports get disconnected on Undo

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 03/08/2012 at 01:36, xxxxxxxx wrote:

Hello dear MAXON support. 😉

This tiny script here opens a modal dialog and after clicking ok, it changes the color of Nodes in the XPresso Manager of the selected XPresso Tag.

Question: Why are most of the nodes being disconnected when doing an Undo?


Animated PNG

# coding: utf-8  
# author: Niklas Rosenstein <[email protected]>  
""" XPresso Node-Color Modificator  
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
  
  1. Select an XPresso Tag (just a single tag)  
  2. Execute the script  
  3. Change the parameters  
  4. Press Ok  
  5. See changes in the XPresso Manager  
  [6. Make an Undo and start from step 2 if you don't like the changes]  
  
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
  
  This software comes AS IS and the author does not give ANY WARRANTY in  
  MERCHANTIBILITY or FITNESS of the software. The author does not give ANY  
  WARRANTY that the software will not make any damages to your software or  
  hardware.  
  """  
  
import c4d  
import c4d.modules.graphview as c4dgv  
  
class Dialog(c4d.gui.GeDialog) :  
  
  EDT_MUL = 1000  
  EDT_INCLROOT = 1001  
  EDT_MODROOTCOL = 1002  
  BTN_OK  = 2000  
  BTN_CN  = 2001  
  
  def __init__(self) :  
    super(Dialog, self).__init__()  
    self.ok = False  
    self.data = {self.EDT_MUL: 0.5, self.EDT_INCLROOT: False,  
           self.EDT_MODROOTCOL: False}  
  
  def CreateLayout(self) :  
    self.SetTitle("XPresso Node-Color")  
    self.GroupBegin(0, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT)  
  
    self.AddStaticText(0, c4d.BFH_LEFT, name="Multiplier")  
    self.AddEditNumberArrows(self.EDT_MUL, c4d.BFH_SCALEFIT)  
    self.AddCheckbox(self.EDT_INCLROOT, c4d.BFH_LEFT, initw=0, inith=10, name="Include Root")  
    self.AddCheckbox(self.EDT_MODROOTCOL, c4d.BFH_LEFT, initw=0, inith=10, name="Modify Default Color")  
  
    self.AddButton(self.BTN_OK, c4d.BFH_SCALEFIT, name="Ok")  
    self.AddButton(self.BTN_CN, c4d.BFH_SCALEFIT, name="Cancel")  
    self.GroupEnd()  
    return True  
  
  def InitValues(self) :  
    self.SetReal(self.EDT_MUL, self.data[self.EDT_MUL], min=0, step=0.01)  
    self.SetBool(self.EDT_INCLROOT, self.data[self.EDT_INCLROOT])  
    self.SetBool(self.EDT_MODROOTCOL, self.data[self.EDT_MODROOTCOL])  
    return True  
  
  def Command(self, id, msg) :  
    if id == self.EDT_MUL:  
      self.data[id] = self.GetReal(id)  
    elif id in (self.EDT_INCLROOT, self.EDT_MODROOTCOL) :  
      self.data[id] = self.GetBool(id)  
    elif id == self.BTN_OK:  
      self.ok = True  
      self.Close()  
    elif id == self.BTN_CN:  
      self.ok = False  
      self.Close()  
    return True  
  
  def Open(self) :  
    super(Dialog, self).Open(c4d.DLG_TYPE_MODAL, defaultw=200)  
  
  def Succeeded(self) :  
    return self.ok  
  
  def GetResult(self) :  
    return self.data  
  
def change_colors(node, data) :  
  color = node[c4d.ID_GVBASE_COLOR]  
  if color != data['root-col'] or data[Dialog.EDT_MODROOTCOL]:  
    doc.AddUndo(c4d.UNDOTYPE_CHANGE, node)  
    node[c4d.ID_GVBASE_COLOR] = color * data[Dialog.EDT_MUL]  
    node.Message(c4d.MSG_CHANGE)  
  for child in node.GetChildren() :  
    change_colors(child, data)  
  
def main() :  
  tag = doc.GetActiveTag()  
  if not tag:  
    print "No Tag selected."  
    return  
  if not tag.CheckType(c4d.Texpresso) :  
    print "The selected Tag must be an XPresso Tag."  
    return  
  
  master = tag.GetNodeMaster()  
  root   = master.GetRoot()  
  
  dlg = Dialog()  
  dlg.Open()  
  if not dlg.Succeeded() : return  
  
  data = dlg.GetResult()  
  data['root-col'] = root[c4d.ID_GVBASE_COLOR]  
  if data[Dialog.EDT_INCLROOT]:  
    change_colors(root, data)  
  else:  
    for child in root.GetChildren() :  
      change_colors(child, data)  
  c4d.EventAdd()  
  
if __name__ == "__main__":  
  main()

Thank you very much in advance,
Nik

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 06/08/2012 at 01:48, xxxxxxxx wrote:

Ok, I got it. Instead of calling BaseDocument.AddUndo() for every change, we should call GvNodeMaster.AddUndo() at the state where the Undo-Action should lead. So, just call it before any node is manipulated and it works fine. No call to BaseDocument.AddUndo() is necessary anymore.

# coding: utf-8  
# author: Niklas Rosenstein <[email protected]>  
""" XPresso Node-Color Modificator  
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
  
  1. Select an XPresso Tag (just a single tag)  
  2. Execute the script  
  3. Change the parameters  
  4. Press Ok  
  5. See changes in the XPresso Manager  
  [6. Make an Undo and start from step 2 if you don't like the changes]  
  
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
  
  This software comes AS IS and the author does not give ANY WARRANTY in  
  MERCHANTIBILITY or FITNESS of the software. The author does not give ANY  
  WARRANTY that the software will not make any damages to your software or  
  hardware.  
  """  
  
import c4d  
import c4d.modules.graphview as c4dgv  
  
class Dialog(c4d.gui.GeDialog) :  
  
  EDT_MUL = 1000  
  EDT_INCLROOT = 1001  
  EDT_MODROOTCOL = 1002  
  BTN_OK  = 2000  
  BTN_CN  = 2001  
  
  def __init__(self) :  
    super(Dialog, self).__init__()  
    self.ok = False  
    self.data = {self.EDT_MUL: 0.5, self.EDT_INCLROOT: False,  
           self.EDT_MODROOTCOL: False}  
  
  def CreateLayout(self) :  
    self.SetTitle("XPresso Node-Color")  
    self.GroupBegin(0, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT)  
  
    self.AddStaticText(0, c4d.BFH_LEFT, name="Multiplier")  
    self.AddEditNumberArrows(self.EDT_MUL, c4d.BFH_SCALEFIT)  
    self.AddCheckbox(self.EDT_INCLROOT, c4d.BFH_LEFT, initw=0, inith=10, name="Include Root")  
    self.AddCheckbox(self.EDT_MODROOTCOL, c4d.BFH_LEFT, initw=0, inith=10, name="Modify Default Color")  
  
    self.AddButton(self.BTN_OK, c4d.BFH_SCALEFIT, name="Ok")  
    self.AddButton(self.BTN_CN, c4d.BFH_SCALEFIT, name="Cancel")  
    self.GroupEnd()  
    return True  
  
  def InitValues(self) :  
    self.SetReal(self.EDT_MUL, self.data[self.EDT_MUL], min=0, step=0.01)  
    self.SetBool(self.EDT_INCLROOT, self.data[self.EDT_INCLROOT])  
    self.SetBool(self.EDT_MODROOTCOL, self.data[self.EDT_MODROOTCOL])  
    return True  
  
  def Command(self, id, msg) :  
    if id == self.EDT_MUL:  
      self.data[id] = self.GetReal(id)  
    elif id in (self.EDT_INCLROOT, self.EDT_MODROOTCOL) :  
      self.data[id] = self.GetBool(id)  
    elif id == self.BTN_OK:  
      self.ok = True  
      self.Close()  
    elif id == self.BTN_CN:  
      self.ok = False  
      self.Close()  
    return True  
  
  def Open(self) :  
    super(Dialog, self).Open(c4d.DLG_TYPE_MODAL, defaultw=200)  
  
  def Succeeded(self) :  
    return self.ok  
  
  def GetResult(self) :  
    return self.data  
  
def change_colors(node, data) :  
  color = node[c4d.ID_GVBASE_COLOR]  
  if color != data['root-col'] or data[Dialog.EDT_MODROOTCOL]:  
    node[c4d.ID_GVBASE_COLOR] = color * data[Dialog.EDT_MUL]  
    node.Message(c4d.MSG_CHANGE)  
  for child in node.GetChildren() :  
    change_colors(child, data)  
  
def main() :  
  tag = doc.GetActiveTag()  
  if not tag:  
    print "No Tag selected."  
    return  
  if not tag.CheckType(c4d.Texpresso) :  
    print "The selected Tag must be an XPresso Tag."  
    return  
  
  master = tag.GetNodeMaster()  
  root   = master.GetRoot()  
  master.AddUndo()  
  
  dlg = Dialog()  
  dlg.Open()  
  if not dlg.Succeeded() : return  
  
  data = dlg.GetResult()  
  data['root-col'] = root[c4d.ID_GVBASE_COLOR]  
  if data[Dialog.EDT_INCLROOT]:  
    change_colors(root, data)  
  else:  
    for child in root.GetChildren() :  
      change_colors(child, data)  
  c4d.EventAdd()  
  
if __name__ == "__main__":  
  main()

Thanks goes to Sebastian (s_rath).
Niklas