HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PDG/partitionbyparity.py
1 #
2 # Copyright (c) 2024
3 # Side Effects Software Inc. All rights reserved.
4 #
5 # Redistribution and use of Houdini Development Kit samples in source and
6 # binary forms, with or without modification, are permitted provided that the
7 # following conditions are met:
8 # 1. Redistributions of source code must retain the above copyright notice,
9 # this list of conditions and the following disclaimer.
10 # 2. The name of Side Effects Software may not be used to endorse or
11 # promote products derived from this software without specific prior
12 # written permission.
13 #
14 # THIS SOFTWARE IS PROVIDED BY SIDE EFFECTS SOFTWARE `AS IS' AND ANY EXPRESS
15 # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
17 # NO EVENT SHALL SIDE EFFECTS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
18 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20 # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 #
25 #----------------------------------------------------------------------------
26 # This script provides an example of writing a custom PDG node in Python
27 #
28 
29 """This is the Python equivalent of PDG_PartitionByParity.C which uses
30 the C++ API.
31 
32 To use this code:
33  1) Create a directory on the Houdini search path for custom PDG Python
34  nodes, if one does not already exist. For example, ~/houdini20.0/pdg/types
35  2) Save this file to that directory as partitionbyparity.py
36  3) Within Houdini the custom node will now show up in the TAB menu in
37  a TOP network
38 """
39 
40 import pdg
41 
42 from pdg.partitioner import PyPartitioner
43 
44 class PartitionByParity(PyPartitioner):
45  """
46  Partitioner implementation that groups upstream work items based on the
47  parity of an attribute value
48  """
49  def __init__(self, node):
50  """
51  __init__(self, pdg.Node) -> NoneType
52 
53  Initializes the partitioner
54  """
55  PyPartitioner.__init__(self, node)
56 
57  @classmethod
58  def templateName(cls):
59  """
60  templateName(cls) -> str
61  """
62  return "partitionbyparity"
63 
64  @classmethod
65  def templateBody(cls):
66  return """{
67  "name": "partitionbyparity",
68  "parameters" : [
69  {
70  "name" : "attributename",
71  "label" : "Attribute Name",
72  "type" : "String",
73  "value" : ""
74  }
75  ]
76  }"""
77 
78  def onPartition(self, partitions, work_items):
79  attribute_name = self['attributename'].evaluateString()
80 
81  for work_item in work_items:
82  attrib = work_item.attrib(attribute_name)
83  if not attrib:
84  self.cookWarning(
85  "'{}' has no attribute with the name '{}'",
86  work_item.name, attribute_name)
87  continue
88 
89  index = 0 if int(attrib.asNumber(0)) % 2 == 0 else 1
90  partitions.addItemToPartition(work_item, index)
91 
92  return pdg.result.Success
93 
94 def registerTypes(type_registry):
95  type_registry.registerNode(
96  PartitionByParity,
97  pdg.nodeType.Partitioner,
98  label="Partition by Parity")