<commit_before>"""
reader

Contains the central EDM->Blender conversion code
"""

import bpy
import bmesh

from .utils import chdir, print_edm_graph
from .edm import EDMFile
from .edm.mathtypes import *
from .edm.types import *

from .translation import TranslationGraph, TranslationNode

import re
import glob
import fnmatch
import os
import itertools

FRAME_SCALE = 100

def iterate_renderNodes(edmFile):
  """Iterates all renderNodes in an edmFile - whilst ignoring any nesting
  due to e.g. renderNode splitting"""
  for node in edmFile.renderNodes:
    if hasattr(node, "children") and node.children:
      for child in node.children:
        yield child
    else:
      yield node

def iterate_all_objects(edmFile):
  for node in itertools.chain(iterate_renderNodes(edmFile), edmFile.connectors, edmFile.shellNodes, edmFile.lightNodes):
    yield node

def build_graph(edmFile):
  "Build a translation graph object from an EDM file"
  graph = TranslationGraph()
  # The first node is ALWAYS the root ndoe
  graph.root.transform = edmFile.nodes[0]
  nodeLookup = {edmFile.nodes[0]: graph.root}

  # Add an entry for every other transform node
  for tfnode in edmFile.nodes[1:]:
    newNode = TranslationNode()
    newNode.transform = tfnode
    nodeLookup[tfnode] = newNode
    graph.nodes.append(newNode)

  # Make the parent/child links
  for node in graph.nodes:
    if node.transform.parent:
      node.parent = nodeLookup[node.transform.parent]
      node.parent.children.append(node)

  # Verify we only have one root
  assert len([x for x in graph.nodes if not x.parent]) == 1, "More than one root node after reading EDM"

  # Connect every renderNode to it's place in the chain
  for node in iterate_all_objects(edmFile):
    if not hasattr(node, "parent"):
      print("Warning: Node {} has no parent attribute; skipping".format(node))
      continue
    owner = nodeLookup[node.parent]
    newNode = TranslationNode()
    newNode.render = node
    graph.attach_node(newNode, owner)

  # Postprocessing: Any transform node with only one child, and that child
  # is a renderNode ONLY, absorbs the rendernode
  def _absorb_rendernode_child(node):
    # Check for an uncomplicated single child that isn't a parent and is a 
    # rendernode, where this node is ONLY a transformnode, and has no other data
    # - some of these might be automatic, but we might have done other tree
    # work between construction and now, so better to be safe

    # Addition: Only count Render children in child count
    renderChildren = [x for x in node.children if x.type == "RENDER"]
    if not node.type == "TRANSFORM" or len(renderChildren) != 1:
      return
    child = renderChildren[0]
    if not child.type == "RENDER" or child.children:
      return
    node.render = child.render
    # Rename the child render node if the parent has one; it may have lost it
    # if it was merged with others
    if node.transform.name:
      node.render.name = node.transform.name<commit_msg>Be more intelligent merging nodes whilst reading<commit_after>"""
reader

Contains the central EDM->Blender conversion code
"""

import bpy
import bmesh

from .utils import chdir, print_edm_graph
from .edm import EDMFile
from .edm.mathtypes import *
from .edm.types import *

from .translation import TranslationGraph, TranslationNode

import re
import glob
import fnmatch
import os
import itertools

FRAME_SCALE = 100

def iterate_renderNodes(edmFile):
  """Iterates all renderNodes in an edmFile - whilst ignoring any nesting
  due to e.g. renderNode splitting"""
  for node in edmFile.renderNodes:
    if hasattr(node, "children") and node.children:
      for child in node.children:
        yield child
    else:
      yield node

def iterate_all_objects(edmFile):
  for node in itertools.chain(iterate_renderNodes(edmFile), edmFile.connectors, edmFile.shellNodes, edmFile.lightNodes):
    yield node

def build_graph(edmFile):
  "Build a translation graph object from an EDM file"
  graph = TranslationGraph()
  # The first node is ALWAYS the root ndoe
  graph.root.transform = edmFile.nodes[0]
  nodeLookup = {edmFile.nodes[0]: graph.root}

  # Add an entry for every other transform node
  for tfnode in edmFile.nodes[1:]:
    newNode = TranslationNode()
    newNode.transform = tfnode
    nodeLookup[tfnode] = newNode
    graph.nodes.append(newNode)

  # Make the parent/child links
  for node in graph.nodes:
    if node.transform.parent:
      node.parent = nodeLookup[node.transform.parent]
      node.parent.children.append(node)

  # Verify we only have one root
  assert len([x for x in graph.nodes if not x.parent]) == 1, "More than one root node after reading EDM"

  # Connect every renderNode to it's place in the chain
  for node in iterate_all_objects(edmFile):
    if not hasattr(node, "parent"):
      print("Warning: Node {} has no parent attribute; skipping".format(node))
      continue
    owner = nodeLookup[node.parent]
    newNode = TranslationNode()
    newNode.render = node
    graph.attach_node(newNode, owner)

  # Postprocessing: Any transform node with only one child, and that child
  # is a renderNode ONLY, absorbs the rendernode
  def _absorb_rendernode_child(node):
    # Check for an uncomplicated single child that isn't a parent and is a 
    # rendernode, where this node is ONLY a transformnode, and has no other data
    # - some of these might be automatic, but we might have done other tree
    # work between construction and now, so better to be safe

    if not node.type == "TRANSFORM":
      return

    # Addition: Only count Render children in child count
    renderChildren = [x for x in node.children if x.type == "RENDER"]
    # If we have multiple children, allow a merge IF we have a name AND a child
    # has the same name
    if len(renderChildren) != 1:
      nameMatch = [x for x in renderChildren if x.render.name == node.transform.name]
      if node.transform.name and len(nameMatch) == 1:
        child = nameMatch[0]
      else:
        return
    else:
      child = renderChildren[0]
    if not child.type == "RENDER" or child.children:
      return
    node.render = child.render
    # Rename the child render node if the parent has one; it may have lost it
    # if it was merged with others
    if node.transform.name:
      node.render.name = node.transform.name
{'fraction_non_alphanumeric': 0.07699604743083004, 'fraction_numerical': 0.0031620553359683794, 'mean_word_length': 3.4643613267466478, 'pattern_counts': {'":': 1, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '458844', 'n_tokens_mistral': 1905, 'n_tokens_neox': 1857, 'n_words': 714}