PDA

View Full Version : Create new TP_Group on Python


Ferrisgeneral
11-16-2012, 04:51 AM
How to create new TP_Group on Python and add to this group the particles of the other group ?

http://chicagoc4d.com/C4DPythonSDK/index.html not understand on this issue without examples.

Darter
11-16-2012, 12:51 PM
This example creates a new particle group and adds a node to the XGroup with the new group assigned. Use the node to pass particles to the new group. It may be necessary to fix the forum-trashed formatting.


# Select XPresso tag and run script
# New group inserted at end of Partcile Groups list
# PGroup node added to XGroup with new group assigned

import c4d

def GroupName(tp, all):
groups = tp.GetParticleGroups(all, c4d.TP_GETPGROUP_ALL)
suffixes = []

for grp in groups:
name = grp[c4d.PGROUP_NAME]

if name.startswith("Group."):
try: sfx = int(name[6:])
except ValueError: continue
suffixes.append(sfx)

suffixes.sort()
sfx_new = 1

for sfx in suffixes:
if sfx_new is sfx: sfx_new += 1
else: break

return "Group." + str(sfx_new)

def main():
ttag = doc.GetActiveTag()
if not ttag or ttag.GetType() != c4d.Texpresso: return

tp = doc.GetParticleSystem()
all = tp.GetRootGroup()

new = tp.AllocParticleGroup()
new[c4d.PGROUP_NAME] = GroupName(tp, all)
new[c4d.PGROUP_COLOR] = c4d.Vector(1.0, 1.0, 1.0) # set group colour
tp.SetPGroupHierarchy(all, new, c4d.TP_INSERT_UNDERLAST)

nm = ttag.GetNodeMaster()
node = nm.CreateNode(nm.GetRoot(), c4d.ID_TP_OP_PGROUP, None, 200, 200) # last 2 args set node X and Y pos
node[c4d.IN_PG_LINK] = new
nm.InsertLast(nm.GetRoot(), node)

c4d.EventAdd()

if __name__=='__main__':
main()

Ferrisgeneral
11-16-2012, 05:27 PM
thank you ... it works fine :thumbsup:

Darter
11-16-2012, 09:28 PM
Glad to help. The script has been updated so that it's only necessary to first select an XPresso tag.

Ferrisgeneral
11-17-2012, 10:05 AM
little corrected code


if name.startswith("Group."):
try: val = int(name[6:])
except ValueError: continue
if int(name[6:]) >= grp_no: grp_no = int(name[6:]) + 1

replaced by

if name.startswith("Group."):
try: val = int(name[6:])
except ValueError: continue
if val >= grp_no: grp_no = val + 1


Add - break; to

for x in active_tags:
if x.GetType() == c4d.Texpresso:
ttag = x
break; #first active only


Not understand what makes a line ???
node[c4d.IN_PG_LINK] = new

Darter
11-17-2012, 12:10 PM
Thanks for the corrections. The script is actually intended to be used with a single XPresso tag selected, so I've simplified it to:


ttag = doc.GetActiveTag()
if not ttag or ttag.GetType() != c4d.Texpresso: return

c4d.IN_PG_LINK is the PGroup parameter in the PGroup node.

Darter
11-17-2012, 02:05 PM
A couple of further changes, for consistency with native behaviour.

The script now fills in any gaps in the numbers of the existing groups, rather than always following on from the highest. Also, each new group is added to the end of the list (but will not be added as the child of a selected group).

Ferrisgeneral
11-17-2012, 03:41 PM
Is it possible to connect the ports dynamically created nodes ?

Darter
11-18-2012, 01:03 AM
This example uses explicit paths to these nodes with these positions in the X-Manager:
XGroup
- PStorm
- PGroup

The PStorm's Particle Birth port is connected to the PGroup's Particle port.

Explicit paths would not be necessary for e.g. connecting a dynamically created node to another node located by traversing the node master.


import c4d

def GetPort(main_id, ports):
res = None

for port in ports:
if port.GetMainID() == main_id:
res = port
break

return res

def main():
ttag = doc.GetActiveTag()
if not ttag or ttag.GetType() != c4d.Texpresso: return

nm = ttag.GetNodeMaster()

node_out = nm.GetRoot().GetDown() # set path to output node
ports_out = node_out.GetOutPorts()

node_in = node_out.GetNext() # set path to input node
ports_in = node_in.GetInPorts()

port_out = GetPort(c4d.OUT_ST_PARTICLE, ports_out)
port_in = GetPort(c4d.IN_PG_PARTICLE, ports_in)

if not port_out or not port_in: return

port_out.Connect(port_in)

c4d.EventAdd()

if __name__=='__main__':
main()

Ferrisgeneral
11-18-2012, 05:57 PM
How not to use explicit paths to nodes in X-Manager ?

For example, if I create a nodes in the code, how to refer to these nodes without using a hierarchy in X-managery.

Darter
11-18-2012, 10:02 PM
GvNodeMaster.InsertFirst() inserts a node at the top of the list and InsertLast() places it at the end. Use the standard GeListNode list handler functions to navigate to nodes at known positions.

A node of a given type can be located with GvNode.GetOperatorID(). For example, to get the first PStorm node in the list:


nm = ttag.GetNodeMaster()
child = nm.GetRoot().GetDown()

while child:
if child.GetOperatorID() == c4d.ID_TP_OP_STORM: break
child = child.GetNext()

if child: print child.GetName()

Ferrisgeneral
11-20-2012, 04:17 PM
And if you try to names of nodes and later search for these names.
Only I can not understand how to search by name, if the name is hidden within a node.

Darter
11-21-2012, 08:29 AM
The Python SDK doesn't support base links but you can e.g. store a string in the node's container:

import c4d

TEST_STRING = 100001 # test ID, obtain unique ID from Plugin Cafe

def main():
ttag = doc.GetActiveTag()
if not ttag or ttag.GetType() != c4d.Texpresso: return

nm = ttag.GetNodeMaster()
node = nm.CreateNode(nm.GetRoot(), c4d.ID_TP_OP_PGROUP, None, 200, 200) # last 2 args set node X and Y pos
nm.InsertLast(nm.GetRoot(), node)

bc = node.GetOperatorContainer()
bc.SetString(TEST_STRING, "PGroup_01")
node.SetOperatorContainer(bc)

c4d.EventAdd()

if __name__=='__main__':
main()


And find the node like this:

import c4d

TEST_STRING = 100001 # test ID, obtain unique ID from Plugin Cafe

def main():
ttag = doc.GetActiveTag()
if not ttag or ttag.GetType() != c4d.Texpresso: return

nm = ttag.GetNodeMaster()
child = nm.GetRoot().GetDown()

while child:
bc = child.GetOperatorContainer()

if bc.GetString(TEST_STRING) == "PGroup_01": break
child = child.GetNext()

if child: print child.GetName()

if __name__=='__main__':
main()

If the node is copied, the stored string will of course also be copied.

The node's Remark string is another way of storing a string in its container:

node[c4d.ID_GVBASE_REMARK]

CGTalk Moderation
11-21-2012, 08:29 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.