Exemplo n.º 1
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
Exemplo n.º 2
0
def getGeoInfoAtFaceId(face_list, obj):
    '''
    returned dict:
    { faceid:{'vertex':[[3 float list],...],
              'vertexid':[int,...]
              'center:[3 float list]'},
      ... 
    }
    '''
    if obj and isinstance(obj, list):
        obj = obj[0]
    root_producer = kcf.getRootProducer()
    geo_p = kcf.getLocationProducer(obj, root_producer)
    # collect datas
    point_P = geo_p.getAttribute('geometry.point.P').getData()
    p_tuple_size = geo_p.getAttribute('geometry.point.P').getTupleSize()
    face_index = geo_p.getAttribute('geometry.poly.startIndex').getData()
    face_index_length = len(face_index)
    vertex_index = geo_p.getAttribute('geometry.poly.vertexList').getData()

    info = {}
    for f_id in face_list:
        f_id = int(f_id)
        if f_id >= face_index_length - 1:
            continue
        face_index_range = range(face_index[f_id], face_index[f_id+1])
        vertex_index_list = [vertex_index[i] for i in face_index_range]
        point_list = [point_P[i*p_tuple_size:i*p_tuple_size+3] for i in vertex_index_list]
        info.update({f_id:{'vertex':point_list, \
                    'vertexid':vertex_index_list, \
                    'center':calculateCenterOfFace(point_list)}})
    return info
Exemplo 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
Exemplo n.º 4
0
def getCameraData(cam_location):
    data = {}
    root_producer = kcf.getRootProducer()
    data['producer'] = root_producer.getProducerByPath(cam_location)
    data['xform'] = data['producer'].getFlattenedGlobalXform()
    # in katana, fov is vertical angle of view
    data['fov_vertical'] = data['producer'].getAttribute('geometry.fov').getData()[-1]
    data['left'] = data['producer'].getAttribute('geometry.left').getData()[-1]
    data['right'] = data['producer'].getAttribute('geometry.right').getData()[-1]
    data['bottom'] = data['producer'].getAttribute('geometry.bottom').getData()[-1]
    data['top'] = data['producer'].getAttribute('geometry.top').getData()[-1]
    data['ratio'] = (abs(data['left']) + abs(data['right'])) / (abs(data['bottom']) + abs(data['top']))
    data['fov_horizontal'] = data['fov_vertical'] * data['ratio']
    data['position'] = [data['xform'][-4], data['xform'][-3], data['xform'][-2]]
    cam_matrix = km.list_to_matrix( list(data['xform']) )
    cam_y = km.vector_unit( km.matrix_mul( km.list_to_matrix([0,1,0,0]), cam_matrix )[0][:-1] )
    cam_z = km.vector_unit( km.matrix_mul( km.list_to_matrix([0,0,1,0]), cam_matrix )[0][:-1] )
    data['up'] = [cam_y[0], cam_y[1], cam_y[2]]
    data['forward'] = [-cam_z[0], -cam_z[1], -cam_z[2]]
    return data
Exemplo n.º 5
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
Exemplo n.º 6
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
Exemplo n.º 7
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)