Ejemplo n.º 1
0
def selectSceneGraphByBound(location=None, \
        max_height=999999, max_width=999999, max_depth=999999):
    ''' this function can be used to filter out the bounding boxes
        whose dimension is smaller than the given value '''
    root_producer = kcf.getRootRroducer()
    if not location:
        location = kcf.getSelectedLocations()
        if not location:
            print 'Please select a location in scene graph to proceed!'
            return False
    if not isinstance(location, list):
        location = [location]
    
    locations = []
    for l in location:
        location_producer = root_producer.getProducerByPath(l)
        for i in kcf.sg_iteratorByType(location_producer, type_='component', to_leaf=False):
            bounds = getBound(i)
            width = abs(bounds[1] - bounds[0])
            height = abs(bounds[3] - bounds[2])
            depth = abs(bounds[5] - bounds[4])
            if height < max_height and width < max_width and depth < max_depth:
                locations.append(i.getFullName())
    if locations:
        kcf.selectLocations(locations)
    return True
Ejemplo n.º 2
0
def findConstraintTargets(locations='', select=True):
    '''this function will try to iterate all of the children and find the constrain targets,
    then select those targets'''
    if not locations:
        locations = kcf.getSelectedLocations()
        if not locations:
            print 'Error: Please select a location in scene graph to proceed!'
            return []
    if not isinstance(locations, list):
        locations = [locations]
        
    targets = []
    root_producer = kcf.getRootProducer()
    for l in locations:
        location_producer = root_producer.getProducerByPath(l)
        for c in kcf.sg_iteratorByType(location_producer):
            xform = c.getAttribute('xform')
            if not xform:
                continue
            child_list = xform.childList()
            for attr_name, attr_obj in child_list:
                t = c.getAttribute('xform.'+attr_name+'.target')
                if t:
                    targets.append( getAbsolutePath(c.getFullName(), t.getValue()) )
    targets = list(set(targets))
    if select:
        for c in targets:
            sg_expandLocation(c)
        kcf.selectLocations(targets)
    return targets
Ejemplo n.º 3
0
def compareHierarchy(src_location='', dst_location='', type_=['subdmesh', 'polygon']):
    '''compare children of selected two locations. If any child location is identical,
    this function will return the two locations as source and destination.
    returned data: [(src1, dst1), (src2, dst2), ...]
    '''
    root_producer = kcf.getRootProducer()
    sgv = kcf.getSceneGraphView()
    if not src_location or not dst_location:
        locations = kcf.getSelectedLocations()
        if not location:
            print 'Please select source and destination location in scene graph to proceed!'
            return []
        if len(locations) < 2:
            print 'Please select both source and destination location'
            return []
        src_location = locations[0]
        dst_location = locations[1]
    src_producer = kcf.getLocationProducer(src_location, root_producer)
    dst_producer = kcf.getLocationProducer(dst_location, root_producer)
    # get full children hierarchy
    src_hierarchy = [i.getFullName().replace(src_location, '') for i in \
                     kcf.sg_iteratorByType(src_producer, type_=type_, to_leaf=False)]
    dst_hierarchy = [i.getFullName().replace(dst_location, '') for i in \
                     kcf.sg_iteratorByType(dst_producer, type_=type_, to_leaf=False)]
    # let's get the common items
    common_items = [(src_location+i, dst_location+i) for i in \
                   list(set(src_hierarchy).intersection(dst_hierarchy))]
    return common_items
Ejemplo n.º 4
0
def barndoorRmsToPxr(top=0.0, bottom=0.0, left=0.0, right=0.0, mode='expand', time=1.0):
    # this function convert barndoors attribute in RMS Light to parameters in Pxr light filter
    # note: the input angle should be greater than 0 and less than 90 degree
    # also, you should select the barn filter in scene graph of Katana to run this function
    # this function does changes the values of the selected nodes or scene graph location
    min_angle = 1.0
    top = min_angle if top<min_angle else (90.0-min_angle if top>(90.0-min_angle) else top)
    bottom = min_angle if bottom<min_angle else (90.0-min_angle if bottom>(90.0-min_angle) else bottom)
    left = min_angle if left<min_angle else (90.0-min_angle if left>(90.0-min_angle) else left)
    right = min_angle if right<min_angle else (90.0-min_angle if right>(90.0-min_angle) else right)
    max_angle = max([top, bottom, left, right])

    # get scene graph location of the selected light filters
    locations = kcf.getSelectedLocations()
    nodes = kcf.locationsToNodes(locations)

    for (l, n) in nodes.iteritems():
        if not n:
            continue
        # get parent light matrix
        light_location = os.path.dirname(l)
        lgt_matrix = tf.list_to_matrix(kcf.getWorldXform(light_location)[0])
        scale, shear, angles, trans, persp = tf.decompose_matrix(lgt_matrix)
        if scale[0]<=0 or scale[1]<=0 or scale[2]<=0:
            print 'Error: '+os.path.basename(light_location)+' has zero scale, ignored!'
            continue
        # calculate distance to the light, so that the angle between the light and filter meets the max angle
        dist_to_light_x = math.tan(max_angle/180.0*math.pi) * scale[0]
        dist_to_light_y = math.tan(max_angle/180.0*math.pi) * scale[1]
        dist_to_light = 0
        if mode=='expand':
            dist_to_light = max(dist_to_light_x, dist_to_light_y)
        else:
            dist_to_light = min(dist_to_light_x, dist_to_light_y)
        dist_to_light = 1
        # calculate refine shape of the barn door
        top_edge = (dist_to_light / math.tan(top/180.0*math.pi) - scale[1])/scale[1]
        bottom_edge = (dist_to_light / math.tan(bottom/180.0*math.pi) - scale[1])/scale[1]
        left_edge = (dist_to_light / math.tan(left/180.0*math.pi) - scale[0])/scale[0]
        right_edge = (dist_to_light / math.tan(right/180.0*math.pi) - scale[0])/scale[0]

        # let's set the parameters on the selected light filters
        # light filter is a group, so let's get their children and set the transform parameters
        light_create_nodes = [i for i in n.getChildren() if i.getType().lower()=='lightcreate']
        if not light_create_nodes:
            print 'Error: failed to find lightCreate node in '+os.path.basename(l)+"'s children, ignored!"
            continue
        param_value_dict = {'transform.translate.x':[0, time], \
                            'transform.translate.y':[0, time], \
                            'transform.translate.z':[-dist_to_light, time]}
        kcf.setParameters(param_value_dict, light_create_nodes[0])

        # set the refine edges of the barn door
        light_filter_nodes = [i for i in n.getChildren() if i.getType().lower()=='material']
        if not light_create_nodes:
            print 'Error: failed to find lightFilter material in '+os.path.basename(l)+"'s children, ignored!"
            continue
        param_value_dict = {'top.value':[top_edge, time], 'bottom.value':[bottom_edge, time], \
                            'left.value':[left_edge, time], 'right.value':[right_edge, time]}
        kcf.setParameters(param_value_dict, light_filter_nodes[0])
Ejemplo n.º 5
0
def getBounds(location_list=None):
    if not location_list:
        location_list = kcf.getSelectedLocations()
    bounds_list = []
    for l in location_list:
        bounds = getBound(l)
        width = abs(bounds[1] - bounds[0])
        height = abs(bounds[3] - bounds[2])
        depth = abs(bounds[5] - bounds[4])
        bounds_list.append((height, width, depth))
    return bounds_list
Ejemplo n.º 6
0
def getDistanceOfSelected(location=True):
    '''
    return the distance between the first two items in the selection lists
    you have to select something in the scene graph or viewer
    returned data: [(16 doubles), ...]
    By default, we get the selected location in the scene graph,
    if location is False, then we look up the node in the node graph,
    then convert the node to the location if possible
    '''
    sel = []
    if location:
        sel = kcf.getSelectedLocations()
    else:
        sel = kcf.nodesToLocations(getSelectedNodes())

    if len(sel)<2:
        print 'Error: please select two locations'
        return
    return getDistance(sel[0], sel[1])
Ejemplo n.º 7
0
def findChildLocation(locations='', type_='light', parameters=[], select=True):
    '''
    find any child under locations whose type is given type_, and
    has the given parameter and value pairs. if the value is *, then
    child will be return if the parameter name matches.
    
    attribute example:
    light or light material lightGroup -> 'material.prmanLightParams.lightGroup'
    light meshLightGeometry -> 'geometry.areaLightGeometrySource'
    '''
    if not locations:
        locations = kcf.getSelectedLocations()
        if not locations:
            print 'Error: Please select a location in scene graph to proceed!'
            return []
    if not isinstance(locations, list):
        locations = [locations]
        
    collection = []
    root_producer = kcf.getRootProducer()
    for l in locations:
        location_producer = root_producer.getProducerByPath(l)
        for c in kcf.sg_iteratorByType(location_producer, type_=type_, to_leaf=True):
            attr = c.getAttribute(parameters[0])
            if not attr:
                continue
            value = attr.getValue()
            if parameters[1] == '*' \
                    or (isinstance(value, str) and value.lower() == parameters[1].lower()) \
                    or value == parameters[1]:
                collection.append(c.getFullName))
        collection = list(set(collection))
        
    if select:
        for c in collection:
            sg_expandLocation(c)
        kcf.selectLocations(collection)
    return collection
Ejemplo n.º 8
0
def frustumSelectionIterator(location=None, filter_type='component', fov_extend_h=0, fov_extend_v=0, \
        cam_location='', inverse_selection=True, animation=False, step=5, \
        nearD=0.1, farD=99999999, debug=False):
    ''' return the list of location within the frustum of camera. The filter_type
        should be component if the component represents the bounding box.
        
        we make this function iterator(generator), so the pyqt progress bar can benefit
        from the yield statment in order to know the progress of the running function.
    '''
    root_producer = kcf.getRootProducer()
    sgv = kcf.getSceneGraphView()
    if not location:
        location = kcf.getSelectedLocations()
        if not location:
            yield 'Error: Please select a location in the scene graph to proceed!'
            return
    if not isinstance(location, list):
        location = [location]
        
    filter_type = filterTypeMap(filter_type)
    
    locations_inside_list = []
    locations_outside_list = []
    
    current_frame = NodegraphAPI.NodegraphGlobals.GetCurrentTime()
    start_frame = NodegraphAPI.NodegraphGlobals.GetInTime()
    end_frame = NodegraphAPI.NodegraphGlobals.GetOutTime()
    frames = range(start_frame, end_frame+1, step)
    if end_frame not in frames:
        frames.append(end_frame)
    if not animation:
        frames = [current_frame]
    
    progress = 0
    progress_step = 100.0 / len(frames)
    
    for f in frames:
        yield 'frame' + str(f) + '\nGet camera matrix datas...'
        NodegraphAPI.NodegraphGlobals.SetCurrentTime(f)
        cam_data = getCameraDatas(cam_location)
        if fov_extend_h != 0 or fov_extend_v != 0:
            cam_data['fov_horizontal'] += fov_extend_h
            cam_data['fov_vertical'] += fov_extend_v
            cam_data['ratio'] = cam_data['fov_horizontal'] / cam_data['fov_vertical']
        frustum = km.Frustum()
        frustum.nearD = nearD
        frustum.farD = farD
        frustum.setCamInternals(cam_data['fov_vertical'], cam_data['ratio'])
        frustum.setCamDef(cam_data['position'], cam_data['forward'], cam_data['up'])
        if debug:
            # put the sphere in the corner of frustum to visually see if we get
            # the correct frustum shape
            print(cam_data['ratio'], cam_data['fov_horizontal'], cam_data['fov_vertical'])
            nodes = kcf.getSelectedNodes()
            corners = [frustum.ntl, frustum.ntr, frustum.nbl, frustum.nbr, \
                      frustum.nc, frustum.fc]
            for i in range(6):
                if i > len(nodes) - 1:
                    break
                kcf.setTransform(nodes[i], translate=list(corners[i]), scale=[10,10,10])
            return
        sub_process = 0
        sub_process_step = progress_step / 100.0
        yield 'start to iterate scene graph locations...'
        for l in location:
            location_producer = root_producer.getProducerByPath(l)
            for i in kcf.sg_iteratorByType(location_producer, type_=filter_type, to_leaf=False):
                bounds = getBound(i)
                if type_ == 'light':
                    bounds = []
                    # if the type is mesh light without bbox, or one of the rect, sphere,
                    # disk light, we use center of point to decide the visibility in frustum
                    # instead of bbox
                    light_shader = i.getAttribute('material.prmanLightShader').getData()
                    if not light_shader:
                        # light without valid light shader, skip
                        continue
                    light_shader = light_shader[0].lower()
                    if 'mesh' not in light_shader and 'rect' not in light_shader \
                        and 'sphere' not in light_shader and 'disk' not in light_shader:
                        continue
                    if 'mesh' in light_shader:
                        # if it's mesh light, let's check the source geometry
                        src = i.getAttribute('geometry.areaLightGeometrySource').getData()
                        if src:
                            bounds = getBound(root_producer.getProducerByPath(src[0]))
                isOutside = False
                if not bounds:
                    # if bounding box info is invalid, we try to use xform instead
                    world_xform = kcf.getWorldXform(i.getFullName())
                    if not world_xform:
                        continue
                    world_xform = world_xform[0]
                    center = world_xform[-4:-1]
                    if frustum.pointInFrustum(center) == frustum.status['outside']:
                        isOutside = True
                else:
                    aabox = km.AABox( bbox_list=bounds )
                    if frustum.boxInFrustum(aabox) == frustum.status['outside']:
                        isOutside = True
                    
                if isOutside:
                    locations_outside_list.append(i.getFullName())
                else:
                    locations_inside_list.append(i.getFullName())

                if sub_process < progress_step:
                    sub_process += sub_process_step
                    yield math.floor(progress + sub_process)
                    
        progress += progress_step
        yield math.floor(progress)
    
    locations_inside_list = list(set(locations_inside_list))
    locations_outside_list = list(set(locations_outside_list))
    locations_outside_list = list(set(locations_outside_list).difference(locations_inside_list))
    
    yield 'Completed!'
    if inverse_selection:
        yield locations_outside_list
        return
    yield locations_inside_list
Ejemplo n.º 9
0
def setSelectedLightAtReflectedPosition(normal, face_center, cam_position, \
                                        invert_normal=False, time=0.0, print_log=False):
    '''
    the normal should be the returned data from getSelectedFaceNormal
    '''
    normal = np.array(normal)
    if invert_normal:
        normal = -normal
    face_center = np.array(face_center)
    cam_position = np.array(cam_position)
    cam_to_face_vector = face_center - cam_position
    reflect = km.vector_unit( km.vector_reflect(cam_to_face_vector, normal) )
    if print_log:
        print 'reflect vector'
        print reflect

    root_producer = kcf.getRootProducer()
    # get selected light
    light_locations = kcf.getSelectedLocations()
    for l in light_locations:
        # if the selected item is light?
        location_producer = root_producer.getProducerByPath(l)
        if location_producer.getType().lower() != 'light':
            continue
        light_Node = kcf.locationsToNodes(l)[l]
        # get light world matrix
        matrix_world_light = kcf.getWorldXform(l)
        if not matrix_world_light:
            print light_Node.getName()+": Failed to get light's world matrix, ignored."
            continue
        matrix_world_light = km.list_to_matrix( matrix_world_light[0] )
        if print_log:
            print 'light world matrix'
            print matrix_world_light
        # get light local matrix
        transform = kcf.getTransform(light_Node)
        if print_log:
            print 'light transform'
            print transform
        matrix_local_light = km.list_to_matrix( transform[light_Node]['matrix'] )
        if print_log:
            print 'light local matrix'
            print matrix_local_light
        # get the intermediate matrix: M_i = M_light_local_inverse * M_world
        matrix_intermediate = km.matrix_mul( km.matrix_inverse(matrix_local_light), matrix_world_light )
        if print_log:
            print 'intermediate matrix'
            print matrix_intermediate
        # compose the reflect world matrix
        distance_light_to_face = float( km.vector_norm(matrix_world_light[3][:-1] - face_center) )
        if print_log:
            print 'light to face distance'
            print distance_light_to_face
        position = reflect * distance_light_to_face + face_center
        rotation = km.vector_to_rotation(-reflect)
        if print_log:
            print 'light new position'
            print position
            print 'light new rotation'
            print rotation
            print km.rad_to_deg(rotation)
        matrix_reflect = km.matrix_compose(scale=np.array([1,1,1]), angles=rotation, translate=position)
        if print_log:
            print 'world reflect matrix'
            print matrix_reflect
        # compute the new light local matrix: M_light = M_reflect * M_intermediate_inverse
        new_matrix_light = km.matrix_mul(matrix_reflect, km.matrix_inverse(matrix_intermediate))
        if print_log:
            print 'new light local matrix'
            print new_matrix_light
        # then get the translate, rotation and scale components
        scale, shear, angles, translate, perspective = km.matrix_decompose(new_matrix_light)
        angles = km.rad_to_deg(angles)
        print (light_Node.getName()+', target transform: \ntranslate: [%f, %f, %f]\n'+\
            'rotate: [%f, %f, %f]\nscale: [%f, %f, %f]')%(translate[0], translate[1], translate[2],\
            angles[0], angles[1], angles[2], scale[0], scale[1], scale[2])
        # let's move the light!
        kcf.setTransform(light_Node, translate=list(translate), rotate=list(angles), \
                            scale=list(scale), rotation_order='XYZ')
        # change the center of interest at the face center
        kcf.setParameters({'centerOfInterest':distance_light_to_face}, light_Node)