<commit_before># :coding: utf-8
# :copyright: Copyright (c) 2013 <NAME>
# :license: See LICENSE.txt.

import os
import re
try:
    import json
except ImportError:
    import simplejson as json

import hou

from .base import Host


SHAPE_REGEX = re.compile('Shape(\d*)$')


class HoudiniHost(Host):
    '''Represent Houdini application.'''
    
    def get_python_prefix(self):
        '''Return Python executable prefix as a list.'''
        return ['hython']
    
    def load_package(self, package, target=None):
        '''Load *package* onto *target*.
        
        If *target* not specified create an appropriate parent node.

        Return target node.

        '''
        if target is None:
            target = hou.node('/obj').createNode('Segue')
            target.parm('package').set(str(package))
        
        # Clear children
        for child in target.children():
            child.destroy()
        
        # Load package file
        package_path = target.evalParm('package')
        if not os.path.isfile(package_path):
            raise ValueError('Not a valid package: {0}'.format(package_path))

        with open(package_path, 'r') as package_file:
            package = json.load(package_file)

        package_root_path = os.path.abspath(os.path.dirname(package_path))

        # Create final output geometry node.
        output_geometry_node = target.createNode('geo', 'output')
        output_geometry_node.node('file1').destroy()
        switch_node = output_geometry_node.createNode(
            'switch', 'implementation'
        )

        # Construct default 'unoptimised' implementation.
        cache_relative_path = package.get('cache')
        if not cache_relative_path:
            raise ValueError('No cache specified in package.')
        
        reference_relative_path = package.get('reference')
        if not reference_relative_path:
            raise ValueError('No reference specified in package.')
        
        cache_path = os.path.join(package_root_path, cache_relative_path)
        reference_path = os.path.join(package_root_path,
                                      reference_relative_path)

        # Create unoptimised output container
        unoptimised_geometry_node = target.createNode('geo', 'unoptimised')

        # Read in reference object
        reference_node = unoptimised_geometry_node.node('file1')
        reference_node.setName('reference')
        reference_node.parm('file').set(str(reference_path))

        # Create Alembic archive
        alembic_node = target.createNode('alembicarchive', 'cache')
        alembic_node.parm('fileName').set(str(cache_path))
        alembic_node.parm('loadmode').set('houdini')
        alembic_node.parm('buildHierarchy').pressButton()
        
        # Merge Alembic geometry in order to map onto reference object.
        geometry_nodes = []
        for child in alembic_node.allSubChildren():
            if child.type().name() == 'geo':
                geometry_nodes.append(child)
        
        merge_node = unoptimised_geometry_node.createNode(
            'object_merge', 'cache'
        )
        merge_node.parm('xformtype').set(1) # Into This Object
        merge_node.parm('numobj').set(len(geometry_nodes))

        # Merge must happen in same order as reference object setup.
        # TODO: Is there a better way rather than relying on brittle naming?
        primitive_groups = []
        for primitive_group in reference_node.geometry().primGroups():
            primitive_name = primitive_group.name()
            if primitive_name != 'default':
                primitive_groups.append(primitive_name)

        for candidate_geometry_node in geometry_nodes:
            candidate_name = candidate_geometry_node.name()
            candidate_name = SHAPE_REGEX.sub('\g<1>', candidate_name)
            index = primitive_groups.index(candidate_name)
            parameter_name = 'objpath{0}'.format(index + 1)
            merge_node.parm(parameter_name).set(candidate_geometry_node.path())

        # Map Alembic animation onto reference geometry
        point_node = reference_node.createOutputNode('point', 'map_points')
        point_node.setInput(1, merge_node)
        
        # Point positions
        point_node.parm('tx').setExpression('$TX2')
        point_node.parm('ty').setExpression('$TY2')
        point_node.parm('tz').setExpression('$TZ2')
        
        # Point normals
        point_node.parm('donml').set(1)
        point_node.parm('nx').setExpression('$NX2')
        point_node.parm('ny').setExpression('$NY2')
        point_node.parm('nz').setExpression('$NZ2')
        
        # Vertex normals
        vertex_node = point_node.createOutputNode('vertex',
                                                  'map_vertex_normals')
        vertex_node.setInput(1, merge_node)
        
        vertex_node.parm('donormal').set(1)
        vertex_node.parm('normalx').setExpression('$NX2')
        vertex_node.parm('normaly').setExpression('$NY2')
        vertex_node.parm('normalz').setExpression('$NZ2')
        
        # Fix normals
        facet_node = vertex_node.createOutputNode('facet', 'fix_normals')
        facet_node.parm('prenml').set(1)
        
        # Group
        group_node = facet_node.createOutputNode('group', 'output')

        # Flags
        reference_node.setRenderFlag(0)
        alembic_node.setDisplayFlag(0)
        group_node.setDisplayFlag(1)
        unoptimised_geometry_node.setDisplayFlag(0)

        # Layout
        unoptimised_geometry_node.layoutChildren()

        # Connect to switch.
        unoptimised_merge_node = output_geometry_node.createNode(
            'object_merge', 'unoptimised'
        )
        unoptimised_merge_node.parm('xformtype').set(1)  # Into This Object
        unoptimised_merge_node.parm('numobj').set(1)
        unoptimised_merge_node.parm('objpath1').set(
            unoptimised_geometry_node.path()
        )

        switch_node.setNextInput(unoptimised_merge_node)

        # Load and switch to optimised version if available.
        if 'houdini' in package:
            bgeo_path = os.path.join(package_root_path, package['houdini'])

            optimised_geometry_node = target.createNode('geo', 'optimised')
            file_node = optimised_geometry_node.node('file1')
            file_node.setName('output')
            file_node.parm('file').set(str(bgeo_path))

            # Flags
            optimised_geometry_node.setDisplayFlag(0)

            # Layout
            optimised_geometry_node.layoutChildren()

            # Connect to switch.
            optimised_merge_node = output_geometry_node.createNode(
                'object_merge', 'optimised'
            )
            optimised_merge_node.parm('xformtype').set(1)  # Into This Object
            optimised_merge_node.parm('numobj').set(1)
            optimised_merge_node.parm('objpath1').set(
                optimised_geometry_node.path()
            )

            switch_node.setNextInput(optimised_merge_node)
            switch_node.parm('input').set(1)

        # Layout
        output_geometry_node.layoutChildren()
        target.layoutChildren()
        return target<commit_msg>[#14] Rename nodes (and variables) to more appropriate names.<commit_after># :coding: utf-8
# :copyright: Copyright (c) 2013 <NAME>
# :license: See LICENSE.txt.

import os
import re
try:
    import json
except ImportError:
    import simplejson as json

import hou

from .base import Host


SHAPE_REGEX = re.compile('Shape(\d*)$')


class HoudiniHost(Host):
    '''Represent Houdini application.'''
    
    def get_python_prefix(self):
        '''Return Python executable prefix as a list.'''
        return ['hython']
    
    def load_package(self, package, target=None):
        '''Load *package* onto *target*.
        
        If *target* not specified create an appropriate parent node.

        Return target node.

        '''
        if target is None:
            target = hou.node('/obj').createNode('Segue')
            target.parm('package').set(str(package))
        
        # Clear children
        for child in target.children():
            child.destroy()
        
        # Load package file
        package_path = target.evalParm('package')
        if not os.path.isfile(package_path):
            raise ValueError('Not a valid package: {0}'.format(package_path))

        with open(package_path, 'r') as package_file:
            package = json.load(package_file)

        package_root_path = os.path.abspath(os.path.dirname(package_path))

        # Create final output geometry node.
        output_geometry_node = target.createNode('geo', 'output')
        output_geometry_node.node('file1').destroy()
        switch_node = output_geometry_node.createNode(
            'switch', 'implementation'
        )

        # Construct default obj + abc implementation.
        cache_relative_path = package.get('cache')
        if not cache_relative_path:
            raise ValueError('No cache specified in package.')
        
        reference_relative_path = package.get('reference')
        if not reference_relative_path:
            raise ValueError('No reference specified in package.')
        
        cache_path = os.path.join(package_root_path, cache_relative_path)
        reference_path = os.path.join(package_root_path,
                                      reference_relative_path)

        # Create obj + abc output container
        obj_abc_geometry_node = target.createNode('geo', 'obj-abc')

        # Read in reference object
        reference_node = obj_abc_geometry_node.node('file1')
        reference_node.setName('reference')
        reference_node.parm('file').set(str(reference_path))

        # Create Alembic archive
        alembic_node = target.createNode('alembicarchive', 'cache')
        alembic_node.parm('fileName').set(str(cache_path))
        alembic_node.parm('loadmode').set('houdini')
        alembic_node.parm('buildHierarchy').pressButton()
        
        # Merge Alembic geometry in order to map onto reference object.
        geometry_nodes = []
        for child in alembic_node.allSubChildren():
            if child.type().name() == 'geo':
                geometry_nodes.append(child)
        
        merge_node = obj_abc_geometry_node.createNode(
            'object_merge', 'cache'
        )
        merge_node.parm('xformtype').set(1) # Into This Object
        merge_node.parm('numobj').set(len(geometry_nodes))

        # Merge must happen in same order as reference object setup.
        # TODO: Is there a better way rather than relying on brittle naming?
        primitive_groups = []
        for primitive_group in reference_node.geometry().primGroups():
            primitive_name = primitive_group.name()
            if primitive_name != 'default':
                primitive_groups.append(primitive_name)

        for candidate_geometry_node in geometry_nodes:
            candidate_name = candidate_geometry_node.name()
            candidate_name = SHAPE_REGEX.sub('\g<1>', candidate_name)
            index = primitive_groups.index(candidate_name)
            parameter_name = 'objpath{0}'.format(index + 1)
            merge_node.parm(parameter_name).set(candidate_geometry_node.path())

        # Map Alembic animation onto reference geometry
        point_node = reference_node.createOutputNode('point', 'map_points')
        point_node.setInput(1, merge_node)
        
        # Point positions
        point_node.parm('tx').setExpression('$TX2')
        point_node.parm('ty').setExpression('$TY2')
        point_node.parm('tz').setExpression('$TZ2')
        
        # Point normals
        point_node.parm('donml').set(1)
        point_node.parm('nx').setExpression('$NX2')
        point_node.parm('ny').setExpression('$NY2')
        point_node.parm('nz').setExpression('$NZ2')
        
        # Vertex normals
        vertex_node = point_node.createOutputNode('vertex',
                                                  'map_vertex_normals')
        vertex_node.setInput(1, merge_node)
        
        vertex_node.parm('donormal').set(1)
        vertex_node.parm('normalx').setExpression('$NX2')
        vertex_node.parm('normaly').setExpression('$NY2')
        vertex_node.parm('normalz').setExpression('$NZ2')
        
        # Fix normals
        facet_node = vertex_node.createOutputNode('facet', 'fix_normals')
        facet_node.parm('prenml').set(1)
        
        # Group
        group_node = facet_node.createOutputNode('group', 'output')

        # Flags
        reference_node.setRenderFlag(0)
        alembic_node.setDisplayFlag(0)
        group_node.setDisplayFlag(1)
        obj_abc_geometry_node.setDisplayFlag(0)

        # Layout
        obj_abc_geometry_node.layoutChildren()

        # Connect to switch.
        obj_abc_merge_node = output_geometry_node.createNode(
            'object_merge', 'obj-abc'
        )
        obj_abc_merge_node.parm('xformtype').set(1)  # Into This Object
        obj_abc_merge_node.parm('numobj').set(1)
        obj_abc_merge_node.parm('objpath1').set(
            obj_abc_geometry_node.path()
        )

        switch_node.setNextInput(obj_abc_merge_node)

        # Load and switch to bgeo version if available.
        if 'houdini' in package:
            bgeo_path = os.path.join(package_root_path, package['houdini'])

            bgeo_geometry_node = target.createNode('geo', 'bgeo')
            file_node = bgeo_geometry_node.node('file1')
            file_node.setName('output')
            file_node.parm('file').set(str(bgeo_path))

            # Flags
            bgeo_geometry_node.setDisplayFlag(0)

            # Layout
            bgeo_geometry_node.layoutChildren()

            # Connect to switch.
            bgeo_merge_node = output_geometry_node.createNode(
                'object_merge', 'bgeo'
            )
            bgeo_merge_node.parm('xformtype').set(1)  # Into This Object
            bgeo_merge_node.parm('numobj').set(1)
            bgeo_merge_node.parm('objpath1').set(
                bgeo_geometry_node.path()
            )

            switch_node.setNextInput(bgeo_merge_node)
            switch_node.parm('input').set(1)

        # Layout
        output_geometry_node.layoutChildren()
        target.layoutChildren()
        return target
{'fraction_non_alphanumeric': 0.10458702785729247, 'fraction_numerical': 0.005585422048453536, 'mean_word_length': 2.38949361097965, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3382011', 'n_tokens_mistral': 4144, 'n_tokens_neox': 4079, 'n_words': 733}