def convert_nodes_to_marker_data_list(cam_tfm, cam_shp, nodes, start_frame, end_frame): cur_time = maya.cmds.currentTime(query=True) mkr_data_list = [] frames = range(start_frame, end_frame + 1) for node in nodes: image_width = maya.cmds.getAttr(cam_shp + '.horizontalFilmAperture') image_height = maya.cmds.getAttr(cam_shp + '.verticalFilmAperture') image_width *= 1000.0 image_height *= 1000.0 values = maya.cmds.mmReprojection(node, time=frames, imageResolution=(image_width, image_height), camera=(cam_tfm, cam_shp), asNormalizedCoordinate=True) assert (len(frames) * 3) == len(values) mkr_data = loadmkr_interface.MarkerData() mkr_data.set_name(node) mkr_data.weight.set_value(start_frame, 1.0) iterator_u = itertools.islice(values, 0, len(values), 3) iterator_v = itertools.islice(values, 1, len(values), 3) for frame, mkr_u, mkr_v in zip(frames, iterator_u, iterator_v): mkr_data.enable.set_value(frame, True) # TODO: The values calculated are slightly wrong in Y (V # axis), this looks like an aspect ratio problem overall. mkr_data.x.set_value(frame, mkr_u) mkr_data.y.set_value(frame, mkr_v) mkr_data_list.append(mkr_data) maya.cmds.currentTime(cur_time, edit=True, update=True) return mkr_data_list
def convert_nodes_to_marker_data_list(cam_tfm, cam_shp, nodes, start_frame, end_frame): # Create nodes and objects for loop. node_pairs = [] reproj_nodes = [] mkr_data_list = [] for node in nodes: reproj = reproject_utils.create_reprojection_on_camera( cam_tfm, cam_shp) reproject_utils.connect_transform_to_reprojection(node, reproj) reproj_nodes.append(reproj) mkr_data = loadmkr_interface.MarkerData() mkr_data.set_name(node) mkr_data_list.append(mkr_data) node_pairs.append((node, reproj, mkr_data)) # Query Screen-space coordinates across time for all nodes cur_time = maya.cmds.currentTime(query=True) for f in xrange(start_frame, end_frame + 1): maya.cmds.currentTime(f, edit=True, update=True) for node, reproj, mkr_data in node_pairs: node_attr = reproj + '.outNormCoord' mkr_u = maya.cmds.getAttr(node_attr + 'X') mkr_v = maya.cmds.getAttr(node_attr + 'Y') mkr_enable = True mkr_weight = 1.0 mkr_data.weight.set_value(f, mkr_weight) mkr_data.enable.set_value(f, mkr_enable) mkr_data.x.set_value(f, mkr_u) mkr_data.y.set_value(f, mkr_v) if len(reproj_nodes) > 0: maya.cmds.delete(reproj_nodes) maya.cmds.currentTime(cur_time, edit=True, update=True) return mkr_data_list
def parse_v1(file_path): """ Parse the UV file format or 3DEqualizer .txt format. :param file_path: :return: """ f = open(file_path, 'r') lines = f.readlines() f.close() if len(lines) == 0: raise OSError('No contents in the file: %s' % file_path) mkr_data_list = [] num_points = int(lines[0]) if num_points < 1: raise interface.ParserError('No points exist.') idx = 1 # Skip the first line for i in xrange(num_points): mkr_name = lines[idx] mkr_name = mkr_name.strip() # Create marker mkr_data = interface.MarkerData() mkr_data.set_name(mkr_name) idx += 1 num_frames = int(lines[idx]) if num_frames <= 0: idx += 1 msg = 'Point has no data: mkr_name=%r line_num=%r' LOG.warning(msg, mkr_name, idx) continue # Frame data parsing frames = [] j = num_frames while j > 0: idx += 1 line = lines[idx] line = line.strip() if len(line) == 0: # Have we reached the end of the file? break j = j - 1 split = line.split() if len(split) != 4: # We should not get here msg = ( 'File invalid, there must be 4 numbers in a line' ' (separated by spaces): line=%r line_num=%r' ) raise interface.ParserError(msg % (line, idx)) frame = int(split[0]) mkr_u = float(split[1]) mkr_v = float(split[2]) mkr_weight = float(split[3]) mkr_data.weight.set_value(frame, mkr_weight) mkr_data.x.set_value(frame, mkr_u) mkr_data.y.set_value(frame, mkr_v) frames.append(frame) # Fill in occluded point frames all_frames = list(range(min(frames), max(frames)+1)) for frame in all_frames: mkr_enable = int(frame in frames) mkr_data.enable.set_value(frame, mkr_enable) if mkr_enable is False: mkr_data.weight.set_value(frame, 0.0) mkr_data_list.append(mkr_data) idx += 1 return mkr_data_list
def parse_v2(file_path): """ Parse the UV file format, using JSON. :param file_path: File path to read. :return: List of MarkerData objects. """ mkr_data_list = [] f = open(file_path) data = json.load(f) f.close() msg = ( 'Per-frame tracking data was not found on marker, skipping. ' 'name=%r' ) points = data.get('points', []) for point_data in points: mkr_data = interface.MarkerData() # Static point information. name = point_data.get('name') set_name = point_data.get('set_name') id_ = point_data.get('id') assert isinstance(name, basestring) assert set_name is None or isinstance(set_name, basestring) assert id_ is None or isinstance(id_, int) mkr_data.set_name(name) mkr_data.set_group_name(set_name) mkr_data.set_id(id_) per_frame = point_data.get('per_frame', []) if len(per_frame) == 0: LOG.warning(msg, name) continue # Create marker frames = [] for frame_data in per_frame: frame_num = frame_data.get('frame') assert frame_num is not None frames.append(frame_num) pos = frame_data.get('pos') assert pos is not None mkr_u, mkr_v = pos mkr_weight = frame_data.get('weight') # Set Marker Data mkr_data.x.set_value(frame_num, mkr_u) mkr_data.y.set_value(frame_num, mkr_v) mkr_data.weight.set_value(frame_num, mkr_weight) mkr_data.enable.set_value(frame_num, True) # Fill in occluded point frames all_frames = list(range(min(frames), max(frames)+1)) for frame in all_frames: mkr_enable = int(frame in frames) mkr_data.enable.set_value(frame, mkr_enable) if mkr_enable is False: mkr_data.weight.set_value(frame, 0.0) mkr_data_list.append(mkr_data) return mkr_data_list
def parse(self, file_path, **kwargs): """ Parse the file path as a 3DEqualizer .txt file. :param file_path: File path to parse. :type file_path: str :param kwargs: expected to contain 'image_width' and 'image_height'. :return: List of MarkerData. """ # If the image width/height is not given we raise an error immediately. image_width = kwargs.get('image_width') image_height = kwargs.get('image_height') if isinstance(image_width, (int, float)): ValueError('image_width must be float or int.') if isinstance(image_height, (int, float)): ValueError('image_height must be float or int.') if image_width is None: image_width = 1.0 if image_height is None: image_height = 1.0 inv_image_width = 1.0 / image_width inv_image_height = 1.0 / image_height f = open(file_path, 'r') lines = f.readlines() f.close() if len(lines) == 0: raise OSError('No contents in the file: %s' % file_path) mkr_data_list = [] line = lines[0] line = line.strip() num_points = int(line) if num_points < 1: raise interface.ParserError('No points exist.') idx = 1 # Skip the first line for i in xrange(num_points): line = lines[idx] mkr_name = line.strip() # Create marker mkr_data = interface.MarkerData() mkr_data.set_name(mkr_name) # Get point color idx += 1 line = lines[idx] line = line.strip() mkr_color = int(line) mkr_data.set_color(mkr_color) idx += 1 line = lines[idx] line = line.strip() num_frames = int(line) if num_frames <= 0: idx += 1 msg = 'point has no data: %r' LOG.warning(msg, mkr_name) continue # Frame data parsing frames = [] j = num_frames while j > 0: idx += 1 line = lines[idx] line = line.strip() if len(line) == 0: # Have we reached the end of the file? break j = j - 1 split = line.split() if len(split) != 3: # We should not get here msg = 'File invalid, there must be 3 numbers in line: %r' raise interface.ParserError(msg % line) frame = int(split[0]) mkr_u = float(split[1]) * inv_image_width mkr_v = float(split[2]) * inv_image_height mkr_weight = 1.0 mkr_data.weight.set_value(frame, mkr_weight) mkr_data.x.set_value(frame, mkr_u) mkr_data.y.set_value(frame, mkr_v) frames.append(frame) # Fill in occluded point frames all_frames = list(range(min(frames), max(frames) + 1)) for frame in all_frames: mkr_enable = int(frame in frames) mkr_data.enable.set_value(frame, mkr_enable) if mkr_enable is False: mkr_data.weight.set_value(frame, 0.0) mkr_data_list.append(mkr_data) idx += 1 file_info = interface.create_file_info() return file_info, mkr_data_list
def _parse_v2_and_v3(file_path, undistorted=None, with_3d_pos=None): """ Parse the UV file format, using JSON. :param file_path: File path to read. :type file_path: str :param undistorted: Should we choose the undistorted or distorted marker data? :type undistorted: bool or None :param with_3d_pos: Try to parse 3D position bundle data from the file path? None means False. with_3d_pos is only accepted on uvtrack version 3+. :type with_3d_pos: bool or None :return: List of MarkerData objects. """ if with_3d_pos is None: with_3d_pos = False pos_key = 'pos_dist' if undistorted is None: undistorted = True if undistorted is True: pos_key = 'pos' mkr_data_list = [] f = open(file_path) data = json.load(f) f.close() msg = ('Per-frame tracking data was not found on marker, skipping. ' 'name=%r') points = data.get('points', []) for point_data in points: mkr_data = interface.MarkerData() # Static point information. mkr_data = _parse_point_info_v2_v3(mkr_data, point_data) # 3D point data if with_3d_pos is True: mkr_data = _parse_point_3d_data_v3(mkr_data, point_data) per_frame = point_data.get('per_frame', []) if len(per_frame) == 0: name = mkr_data.get_name() LOG.warning(msg, name) continue # Create marker per-frame data mkr_data, frames = _parse_per_frame_v2_v3(mkr_data, per_frame, pos_key=pos_key) # Fill in occluded point frames mkr_data = _parse_marker_occluded_frames_v1_v2_v3( mkr_data, frames, ) mkr_data_list.append(mkr_data) return mkr_data_list
def parse(self, file_path, **kwargs): """ Parse the file path as a PFTrack .2dt/.txt file. :param file_path: File path to parse. :type file_path: str :param kwargs: expected to contain 'image_width' and 'image_height'. :return: List of MarkerData. """ # If the image width/height is not given we raise an error immediately. image_width = kwargs.get('image_width') image_height = kwargs.get('image_height') if image_width is None: image_width = 1.0 if image_height is None: image_height = 1.0 inv_image_width = 1.0 / image_width inv_image_height = 1.0 / image_height lines = [] with open(file_path, 'r') as f: lines = f.readlines() if len(lines) == 0: raise OSError('No contents in the file: %s' % file_path) mkr_data_list = [] i = 0 lines = _remove_comments_from_lines(lines) while i < len(lines): line = lines[i] mkr_name = None # Tracker Name if line.startswith('"') and line.endswith('"'): mkr_name = line[1:-1] i += 1 else: i += 1 continue # Clip number or Camera name. # # PFTrack 5 used a camera name, but future versions of # PFTrack use clip numbers. # # Either way, this value is parsed by never used by the # importer because I don't know how the clip number or # camera name should be used in mmSolver. cam_name = None line = lines[i] clip_number = parse_int_or_none(line) if clip_number is not None: i += 1 elif line.startswith('"') and line.endswith('"'): cam_name = line[1:-1] i += 1 else: msg = ('File invalid, ' 'expecting a camera name (string) in line: %r') raise interface.ParserError(msg % line) # Create marker mkr_data = interface.MarkerData() mkr_data.set_name(mkr_name) # Number of frames. line = lines[i] number_of_frames = parse_int_or_none(line) if number_of_frames is None: msg = ('File invalid, ' 'expecting a number of frames (integer) in line: %r') raise interface.ParserError(msg % line) i += 1 # Parse per-frame data. frames = [] for frame_index in range(number_of_frames): line = lines[i] line_split = line.split(' ') frame = None mkr_u = 0.0 mkr_v = 0.0 residual = None zdepth = None if len(line_split) not in [4, 5]: msg = ('File invalid, ' 'there must be 4 or 5 numbers in line: %r') raise interface.ParserError(msg % line) frame = parse_int_or_none(line_split[0]) pos_x = parse_float_or_none(line_split[1]) pos_y = parse_float_or_none(line_split[2]) if frame is None or pos_x is None or pos_y is None: raise interface.ParserError('Invalid file format.') # PFTrack treats the center of the pixel as "0.0", # which is different from other matchmove # software. mkr_u = (pos_x + 0.5) * inv_image_width mkr_v = (pos_y + 0.5) * inv_image_height # # There is no need for residual or the Z-depth for now. # residual = parse_float_or_none(line_split[3]) # if len(line_split) == 5: # zdepth = parse_float_or_none(line_split[4]) mkr_weight = 1.0 mkr_data.weight.set_value(frame, mkr_weight) mkr_data.x.set_value(frame, mkr_u) mkr_data.y.set_value(frame, mkr_v) frames.append(frame) i += 1 # Fill in occluded frames all_frames = list(range(min(frames), max(frames) + 1)) for frame in all_frames: mkr_enable = int(frame in frames) mkr_data.enable.set_value(frame, mkr_enable) if mkr_enable is False: mkr_data.weight.set_value(frame, 0.0) mkr_data_list.append(mkr_data) file_info = interface.create_file_info() return file_info, mkr_data_list
def parse_v1(file_path, **kwargs): """ Parse the UV file format or 3DEqualizer .txt format. :param file_path: :return: """ with open(file_path, 'r') as f: lines = f.readlines() if len(lines) == 0: raise OSError('No contents in the file: %s' % file_path) mkr_data_list = [] num_points = int(lines[0]) if num_points < 1: raise interface.ParserError('No points exist.') idx = 1 # Skip the first line for _ in xrange(num_points): mkr_name = lines[idx] mkr_name = mkr_name.strip() # Create marker mkr_data = interface.MarkerData() mkr_data.set_name(mkr_name) idx += 1 num_frames = int(lines[idx]) if num_frames <= 0: idx += 1 msg = 'Point has no data: mkr_name=%r line_num=%r' LOG.warning(msg, mkr_name, idx) continue # Frame data parsing frames = [] j = num_frames while j > 0: idx += 1 line = lines[idx] line = line.strip() if len(line) == 0: # Have we reached the end of the file? break j = j - 1 split = line.split() if len(split) != 4: # We should not get here msg = ('File invalid, there must be 4 numbers in a line' ' (separated by spaces): line=%r line_num=%r') raise interface.ParserError(msg % (line, idx)) frame = int(split[0]) mkr_u = float(split[1]) mkr_v = float(split[2]) mkr_weight = float(split[3]) mkr_data.weight.set_value(frame, mkr_weight) mkr_data.x.set_value(frame, mkr_u) mkr_data.y.set_value(frame, mkr_v) frames.append(frame) # Fill in occluded point frames mkr_data = _parse_marker_occluded_frames_v1_v2_v3( mkr_data, frames, ) mkr_data_list.append(mkr_data) idx += 1 file_info = interface.create_file_info(marker_undistorted=True) return file_info, mkr_data_list
def parse(self, file_path, **kwargs): if not isinstance(file_path, basestring): raise TypeError('file_path is not a string: %r' % file_path) if not os.path.isfile(file_path): raise OSError('File path does not exist: %s' % file_path) mkr_data_list = [] f = open(file_path, 'r') text = f.read() f.close() idx = text.find('imageSequence') if idx == -1: msg = "Could not get 'imageSequence' index from: %r" raise interface.ParserError(msg % text) start_idx = text.find('{', idx + 1) if start_idx == -1: msg = 'Could not get the starting index from: %r' raise interface.ParserError(msg % text) end_idx = text.find('}', start_idx + 1) if end_idx == -1: msg = 'Could not get the ending index from: %r' raise interface.ParserError(msg % text) imgseq = text[start_idx + 1:end_idx] imgseq = imgseq.strip() splt = imgseq.split() x_res = int(splt[0]) y_res = int(splt[1]) # Get path imgseq_path = re.search(r'.*f\(\s\"(.*)\"\s\).*', imgseq) if imgseq_path is None: msg = 'Could not get the image sequence path from: %r' raise interface.ParserError(msg % imgseq) imgseq_path = imgseq_path.groups() # Get frame range range_regex = re.search(r'.*b\(\s(\d*)\s(\d*)\s(\d*)\s\)', imgseq) if range_regex is None: msg = 'Could not get the frame range from: %r' raise interface.ParserError(msg % imgseq) range_grps = range_regex.groups() start_frame = int(range_grps[0]) end_frame = int(range_grps[1]) by_frame = int(range_grps[2]) frames = xrange(start_frame, end_frame, by_frame) idx = end_idx while True: idx = text.find('pointTrack', idx + 1) if idx == -1: break start_idx = text.find('{', idx + 1) if start_idx == -1: break end_idx = text.find('}', start_idx + 1) if end_idx == -1: break # Get point track name point_track_header = text[idx:start_idx] track_regex = re.search(r'pointTrack\s*\"(.*)\".*', point_track_header) if track_regex is None: continue track_grps = track_regex.groups() if len(track_grps) == 0: continue mkr_name = track_grps[0] # create marker mkr_data = interface.MarkerData() mkr_data.set_name(mkr_name) mkr_data.weight.set_value(start_frame, 1.0) for frame in frames: mkr_data.enable.set_value(frame, 0) point_track = text[start_idx + 1:end_idx] for line in point_track.splitlines(): splt = line.split() if len(splt) == 0: continue frame = int(splt[0]) # NOTE: In MatchMover, top-left is (0,0), but we want # bottom-left to be (0,0). x = float(splt[1]) / x_res y = ((float(splt[2]) / y_res) * -1) + 1.0 enable_value = int(frame in frames) mkr_data.enable.set_value(frame, enable_value) mkr_data.x.set_value(frame, x) mkr_data.y.set_value(frame, y) mkr_data_list.append(mkr_data) file_info = interface.create_file_info() return file_info, mkr_data_list