mergenode_collada.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 # Copyright (c) 2019, 2020 Naoki Hiraoka
4 # All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions are met:
8 #
9 # 1. Redistributions of source code must retain the above copyright notice,
10 # this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 # notice, this list of conditions and the following disclaimer in the
13 # documentation and/or other materials provided with the distribution.
14 # 3. Neither the name of the Kei Okada nor the names of its
15 # contributors may be used to endorse or promote products derived from
16 # this software without specific prior written permission.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 # POSSIBILITY OF SUCH DAMAGE.
29 
30 from collada import *
31 from urdf_parser_py.urdf import *
32 from tf.transformations import *
33 import copy
34 import os
35 import sys
36 import math
37 import numpy
38 import argparse
39 
40 
41 def mergenode(parentnode, childnode):
42  if isinstance(parentnode, scene.Node) and isinstance(childnode, scene.Node):
43  # merge childnode into parentnode
44  parentnode.children.remove(childnode)
45  child_mat = childnode.matrix
46  for child in childnode.children:
47  if isinstance(child, scene.Node):
48  child.transforms = copy.deepcopy(childnode.transforms) + child.transforms
49  for t in reversed(childnode.transforms):
50  child.matrix = numpy.dot(t.matrix, child.matrix)
51  parentnode.children.append(child)
52  elif isinstance(child, scene.GeometryNode):
53  position_ids = set()
54  normal_ids = set()
55  for primitive in child.geometry.primitives:
56  for _input in primitive.getInputList().getList():
57  if _input[1] == "VERTEX":
58  position_ids.add(_input[2][1:]) # remove '#'
59  elif _input[1] == "NORMAL":
60  normal_ids.add(_input[2][1:]) # remove '#'
61  for position_id in position_ids:
62  child.geometry.sourceById[position_id].data = ((child_mat[:3, :3].astype("float64").dot(child.geometry.sourceById[position_id].data.transpose())).transpose() + child_mat[:3, 3]).copy()
63  for normal_id in normal_ids:
64  child.geometry.sourceById[normal_id].data = (child_mat[:3, :3].astype("float64").dot(child.geometry.sourceById[normal_id].data.transpose())).transpose().copy()
65  for primitive in child.geometry.primitives:
66  primitive._vertex = primitive.sources['VERTEX'][0][4].data
67  primitive._normal = primitive.sources['NORMAL'][0][4].data
68  parentnode.children.append(child)
69 
70 
71 def get_merged(node, joints_dict):
72  if isinstance(node, scene.Node):
73  # merge nodes below this node unless joint exists
74  for child in node.children[:]:
75  if isinstance(child, scene.Node):
76  if child.id in joints_dict:
77  get_merged(child, joints_dict)
78  else:
79  mergenode(node, get_merged(child, joints_dict))
80  return node
81 
82 
83 def find_parent_node(node, name):
84  for child in node.children:
85  if isinstance(child, scene.Node):
86  if child.id == name:
87  return node, child
88  else:
89  ret = find_parent_node(child, name)
90  if ret:
91  return ret
92  return False
93 
94 
95 def mergenode_collada(mesh_, joints_, root_offset):
96  # apply root_offset
97  node = mesh_.scene.nodes[0]
98  node.transforms = [scene.MatrixTransform(root_offset.copy().reshape(16, 1))] + node.transforms
99  node.matrix = numpy.dot(root_offset, node.matrix)
100  newnode = scene.Node("offset_link", children=[node])
101  newnode.xmlnode.set("sid", "offset_link")
102  newnode.transforms = [scene.MatrixTransform(numpy.identity(4, dtype=numpy.float32).reshape(16, 1))]
103  mesh_.scene.nodes = [newnode]
104 
105  # merge nodes into one node if no joints exist between them.
106  joints_dict = dict(joints_)
107  get_merged(mesh_.scene.nodes[0], joints_dict)
108  mesh_.save()
109 
110  # add additional nodes if multiple joints exist for one childnode
111  joints_new = copy.deepcopy(joints_)
112  childlink_count = dict()
113  for joint in joints_:
114  if joint[0] in childlink_count.keys():
115  childlink_count[joint[0]] += 1
116  else:
117  childlink_count[joint[0]] = 1
118 
119  for childlinkid, count in childlink_count.items():
120  if count > 1:
121  parentnode, childnode = find_parent_node(mesh_.scenes[0].nodes[0], childlinkid)
122  for i in range(count - 1):
123  parentnode.children.remove(childnode)
124  newnode = scene.Node(childnode.id + "_addition_null" + str(i), children=[childnode])
125  newnode.xmlnode.set("sid", childnode.id + "_addition_null" + str(i))
126  newnode.transforms = childnode.transforms
127  newnode.matrix = childnode.matrix
128  childnode.transforms = []
129  childnode.matrix = numpy.identity(4, dtype=numpy.float32)
130  parentnode.children.append(newnode)
131  parentnode = newnode
132  j = [s for s in joints_new if s[0] == childlinkid][0]
133  j[0] += "_addition_null" + str(i)
134 
135  # add root link
136  if len(mesh_.scene.nodes[0].children) == 1:
137  mesh_.scene.nodes[0].id = "visual0"
138  mesh_.scene.nodes[0].xmlnode.set("sid", "visual0")
139  else:
140  node = mesh_.scene.nodes[0]
141  newnode = scene.Node("visual0", children=[node])
142  newnode.xmlnode.set("sid", "visual0")
143  mesh_.scene.nodes = [newnode]
144  mesh_.scene.nodes[0].children[0].id = "base_link"
145  mesh_.scene.nodes[0].children[0].xmlnode.set("sid", "base_link")
146  mesh_.scene.nodes[0].children[0].transforms = [scene.MatrixTransform(numpy.identity(4, dtype=numpy.float32).reshape(16, 1))]
147  mesh_.scene.nodes[0].children[0].matrix = numpy.identity(4, dtype=numpy.float32)
148 
149  mesh_.save()
150  joints_[:] = joints_new
def find_parent_node(node, name)
def get_merged(node, joints_dict)
def mergenode_collada(mesh_, joints_, root_offset)
def mergenode(parentnode, childnode)


gundam_rx78_description
Author(s): Association GUNDAM GLOBAL CHALLENGE, Kei Okada , Naoki Hiraoka
autogenerated on Wed Sep 2 2020 03:33:36