def __getitem__(self, index): path = self.paths[index] mesh = Mesh(file=path, opt=self.opt, hold_history=True, export_folder=self.opt.export_folder) meta = {} meta['mesh'] = mesh if self.opt.edge_split: path_index = os.path.join( os.path.dirname(self.seg_paths[index]), 'cache\\' + os.path.basename(self.seg_paths[index])) label = read_seg(path_index) - self.offset else: label = read_seg(self.seg_paths[index]) - self.offset label = pad(label, self.opt.ninput_edges, val=-1, dim=0) meta['label'] = label if self.opt.edge_split: path_index = os.path.join( os.path.dirname(self.sseg_paths[index]), 'cache\\' + os.path.basename(self.sseg_paths[index])) soft_label = read_sseg(path_index) else: soft_label = read_sseg(self.sseg_paths[index]) meta['soft_label'] = pad(soft_label, self.opt.ninput_edges, val=-1, dim=0) # get edge features edge_features = mesh.extract_features() edge_features = pad(edge_features, self.opt.ninput_edges) meta['edge_features'] = (edge_features - self.mean) / self.std return meta
def __getitem__(self, index): path = self.paths[index][0] label = self.paths[index][1] mesh = Mesh(file=path, opt=self.opt, hold_history=False, export_folder=self.opt.export_folder) meta = {'mesh': mesh, 'label': label} # get edge features face_features = mesh.extract_features() face_features = pad(face_features, self.opt.ninput_faces) meta['face_features'] = (face_features - self.mean) / self.std return meta
def __getitem__(self, index): path = self.paths[index] mesh = Mesh(file=path, opt=self.opt, hold_history=True, export_folder=self.opt.export_folder) meta = {} meta['mesh'] = mesh # get edge features face_features = mesh.extract_features() meta['num_triangle'] = mesh.faces_count face_features = pad(face_features, self.opt.ninput_faces) meta['face_features'] = (face_features - self.mean) / self.std return meta
def color_obj(): """coloring mesh with the given seg file""" path = "E:/3ds_intern/meshcnn/datasets/coseg_aliens/labels_aliens/5.obj" path2 = "E:/3ds_intern/meshcnn/datasets/coseg_aliens/labels_aliens/5.eseg" opt = TestOptions().parse() mesh = Mesh(file=path, opt=opt, hold_history=False, export_folder= "E:/3ds_intern/meshcnn/datasets/coseg_aliens/labels_aliens") seg = read_seg(path2).astype(int) mesh.export_segments(seg)
def __getitem__(self, index): path = self.paths[index] mesh = Mesh(file=path, opt=self.opt, hold_history=True, export_folder=self.opt.export_folder) # get edge features edge_features = mesh.extract_features() edge_features = pad(edge_features, self.opt.ninput_edges) meta = {'mesh': mesh, 'label': edge_features} meta['edge_features'] = (edge_features - self.mean) / self.std return meta
def __getitem__(self, index): path = self.paths[index] mesh = Mesh(file=path, opt=self.opt, hold_history=True, export_folder=self.opt.export_folder) meta = {} meta['mesh'] = mesh label = read_seg(self.seg_paths[index]) - self.offset label = pad(label, self.opt.ninput_edges, val=-1, dim=0) meta['label'] = label soft_label = read_sseg(self.sseg_paths[index]) meta['soft_label'] = pad(soft_label, self.opt.ninput_edges, val=-1, dim=0) # get edge features edge_features = mesh.extract_features() edge_features = pad(edge_features, self.opt.ninput_edges) meta['edge_features'] = (edge_features - self.mean) / self.std return meta
def __getitem__(self, index): path = self.paths[index][0] #print(path) mesh = Mesh(file=path, opt=self.opt, hold_history=True, export_folder=self.opt.export_folder) meta = {} mesh.vs = (mesh.vs - np.mean(mesh.vs, 0)) / np.std(mesh.vs, 0) meta['mesh'] = mesh meta['export_folder'] = mesh.export_folder meta['filename'] = mesh.filename # get edge features edge_features = mesh.extract_features() edge_features = pad(edge_features, self.opt.ninput_edges) vs, pad_iter = pad_vertices(mesh.vs, 1402) meta['edge_features'] = (edge_features - self.mean) / self.std meta['label'] = vs.astype(np.float) meta['init_faces'] = mesh.init_faces meta['pad_iter'] = pad_iter return meta
def __getitem__(self, index): path = self.paths[index] # print("opt: {}, export_folder: {}, phase: {}".format(self.opt, self.opt.export_folder, self.opt.phase)) mesh = Mesh(file=path, opt=self.opt, hold_history=True, export_folder=self.opt.export_folder, phase=self.opt.phase) meta = {} meta["filename"] = mesh.filename meta['mesh'] = mesh if self.opt.phase != "test": label = read_seg(self.seg_paths[index]) - self.offset # print("label: ", label.shape, type(label), label) # if len(label) > self.opt.ninput_edges: # label = label[mesh.e_masks] if len(label) <= self.opt.ninput_edges: label = pad(label, self.opt.ninput_edges, val=-1, dim=0) meta['label'] = label soft_label = read_sseg(self.sseg_paths[index]) # if len(soft_label) > self.opt.ninput_edges: # soft_label = soft_label[mesh.e_masks] if len(soft_label) <= self.opt.ninput_edges: soft_label = pad(soft_label, self.opt.ninput_edges, val=-1, dim=0) meta['soft_label'] = soft_label # get edge features edge_features = mesh.extract_features() if edge_features.shape[1] <= self.opt.ninput_edges: edge_features = pad(edge_features, self.opt.ninput_edges) meta['edge_features'] = (edge_features - self.mean) / self.std else: meta["edge_features"] = np.array([]) # print("edge_features: ", type(meta["edge_features"]), meta["edge_features"].shape) return meta
import utils import numpy as np from models.losses import chamfer_distance from options import Options import time import os options = Options() opts = options.args torch.manual_seed(opts.torch_seed) device = torch.device('cuda:{}'.format(opts.gpu) if torch.cuda.is_available() else torch.device('cpu')) print('device: {}'.format(device)) # initial mesh mesh = Mesh(opts.initial_mesh, device=device, hold_history=True) # input point cloud input_xyz, input_normals = utils.read_pts(opts.input_pc) # normalize point cloud based on initial mesh input_xyz /= mesh.scale input_xyz += mesh.translations[None, :] input_xyz = torch.Tensor(input_xyz).type(options.dtype()).to(device)[None, :, :] input_normals = torch.Tensor(input_normals).type(options.dtype()).to(device)[None, :, :] part_mesh = PartMesh(mesh, num_parts=options.get_num_parts(len(mesh.faces)), bfs_depth=opts.overlap) print(f'number of parts {part_mesh.n_submeshes}') net, optimizer, rand_verts, scheduler = init_net(mesh, part_mesh, device, opts) for i in range(opts.iterations): num_samples = options.get_num_samples(i % opts.upsamp)
polydata = reader.GetOutput() #Network parameter down_convs = [5, 32, 64, 128, 256] up_convs = [256, 128, 64, 32, 8] pool_res = [2250, 1800, 1350, 600] resblocks = 3 net = MeshEncoderDecoder(pool_res, down_convs, up_convs, resblocks) #Try to get pretrained mesh state_dict = torch.load('./data/latest_net.pth') net.load_state_dict(state_dict) net.eval() #Import sample mesh mesh = Mesh(polydata) mesh_feature = mesh.extract_features() # mesh_gemm = mesh.extract_gemm_edges() # print(mesh_gemm.shape) sample_input = torch.tensor(mesh_feature).unsqueeze(0).float() print(sample_input.size()) y = net.forward(sample_input, [mesh]) y_value, y_index = y.max(-2) #Get Predicted Class predict = y_index[0] print(predict.size()) #Visualize
def __init__(self, mesh_original_filename, mesh_filename, num_classes, edge_soft_labels_file, print_warnings=False): self.__print_warnings = print_warnings # Allow to call recursive function the needed number of times. sys.setrecursionlimit(5000) self.__num_classes = num_classes # Read the mesh data. # Read mesh. opt = OptClass() mesh_pymesh = pymesh.load_mesh(mesh_filename) for color in ['green', 'red', 'blue']: if (not mesh_pymesh.has_attribute(f'face_{color}')): mesh_pymesh.add_attribute(f'face_{color}') mesh_pymesh.set_attribute( f'face_{color}', mesh_pymesh.get_attribute(f'vertex_{color}')) mesh_pymesh.remove_attribute(f'vertex_{color}') face_labels = np.empty(mesh_pymesh.num_faces, dtype=np.long) face_red = mesh_pymesh.get_attribute('face_red') face_green = mesh_pymesh.get_attribute('face_green') face_blue = mesh_pymesh.get_attribute('face_blue') for face_idx, (blue, green, red) in enumerate(zip(face_blue, face_green, face_red)): assigned_label = False for label_idx in range(len(seg_colors)): if (np.all([blue, green, red] == seg_colors[label_idx])): face_labels[face_idx] = label_idx assigned_label = True assert (assigned_label), [blue, green, red] mesh = Mesh(file=mesh_original_filename, opt=opt, hold_history=False) # Map vertices in MeshCNN to pymesh vertices. meshcnn_vertex_idx_to_pymesh_vertex_idx = np.empty( [mesh_pymesh.num_vertices]) pymesh_vertex_to_assign = [r for r in range(mesh_pymesh.num_vertices)] for meshcnn_vertex_idx, meshcnn_vertex in enumerate(mesh.vs): found_match = None for pymesh_vertex_idx in pymesh_vertex_to_assign: pymesh_vertex = mesh_pymesh.vertices[pymesh_vertex_idx] if (np.isclose(meshcnn_vertex[0], pymesh_vertex[0]) and np.isclose(meshcnn_vertex[1], pymesh_vertex[1]) and np.isclose(meshcnn_vertex[2], pymesh_vertex[2])): found_match = pymesh_vertex_idx pymesh_vertex_to_assign.remove(pymesh_vertex_idx) meshcnn_vertex_idx_to_pymesh_vertex_idx[ meshcnn_vertex_idx] = pymesh_vertex_idx break assert (found_match is not None) face_vertex_indices = mesh_pymesh.get_attribute( 'face_vertex_indices').astype(np.long).reshape(-1, 3) vertex_to_faces = { vertex: [] for vertex in range(mesh_pymesh.num_vertices) } for face_idx, vertices_in_face in enumerate(face_vertex_indices): for pymesh_vertex_idx in vertices_in_face: meshcnn_vertex_idx = meshcnn_vertex_idx_to_pymesh_vertex_idx[ pymesh_vertex_idx] vertex_to_faces[meshcnn_vertex_idx].append(face_idx) # Read vertices. self.__vertices = mesh.vs self.__num_vertices = self.__vertices.shape[0] assert (self.__num_vertices == mesh_pymesh.num_vertices ), f"{self.__num_vertices}, {mesh_pymesh.num_vertices}" # Edges. if (hasattr(mesh, 'original_edges')): self.__edges = np.array(mesh.original_edges).squeeze() else: self.__edges = mesh.edges self.__num_edges = self.__edges.shape[0] self.__halfedge_to_halfedge_idx = {} for halfedge_idx, halfedge in enumerate(self.__edges): self.__halfedge_to_halfedge_idx[(halfedge[0], halfedge[1])] = halfedge_idx assert (num_classes in [3, 4, 8]) edge_soft_labels = np.zeros([self.__num_edges, num_classes]) # For each (half)-edge, see the face to which the edge belongs and form # edge soft-labels from the hard labels of these faces. for halfedge_idx, halfedge in enumerate(self.__edges): vertex_1, vertex_2 = halfedge faces_halfedge = list( set(vertex_to_faces[vertex_1]) & set(vertex_to_faces[vertex_2])) assert (len(faces_halfedge) in [1, 2]) for face_idx in faces_halfedge: # Get face label. face_lab = face_labels[face_idx] # Update edge soft label. edge_soft_labels[halfedge_idx, face_lab] += 0.5 # Create the output folder if non-existent. output_folder = os.path.dirname(edge_soft_labels_file) if (not os.path.exists(output_folder)): os.makedirs(output_folder) # Save soft label to file. np.savetxt(edge_soft_labels_file, edge_soft_labels, fmt="%.6f")
def run_test(dataset_name, meshcnn_root, soft_labels_folder, verbose): opt = Opt(dataset_name) # Initialize counter. accuracy_counter = PdMeshNetAccuracyCounter() accuracy_counter.reset_counter() folder_original_meshes = os.path.join(meshcnn_root, f'datasets/{dataset_name}/test/') mesh_filenames = glob.glob(os.path.join(folder_original_meshes, '*.obj')) for mesh_filename in mesh_filenames: # Load original mesh. mesh = Mesh(file=mesh_filename, opt=opt, hold_history=False) mesh_name = mesh_filename.rsplit('.')[0].rpartition('/')[-1] mesh_name = f'{mesh_name}_aug_0_clusterized' if (verbose): print(f"Original mesh filename = '{mesh_filename}'.") # Load predicted soft labels. pred_soft_labels_file = os.path.join( soft_labels_folder, f'{dataset_name}/sseg/{mesh_name}.seseg') predicted_soft_labels = np.loadtxt(open(pred_soft_labels_file, 'r'), dtype='float64') num_edges = len(predicted_soft_labels) # Pad with zero the last class of coseg `chairs` (MeshCNN provides an # empty column for the 4th class, although the classes are 3). predicted_soft_labels_new = np.zeros([num_edges, opt.nclasses]) predicted_soft_labels_new[:, :predicted_soft_labels. shape[1]] = predicted_soft_labels predicted_soft_labels = predicted_soft_labels_new assert (mesh.edges_count == num_edges) assert (predicted_soft_labels.ndim == 2 and predicted_soft_labels.shape[1] == opt.nclasses) num_predictions = predicted_soft_labels.shape[0] # Create two versions (cf. Supplementary Material `.pdf`), in each of # which one of the two predicted soft labels of each edge is considered # as 'hard label'. predicted_versions = np.empty([num_predictions, 2], dtype=np.long) for prediction_idx, prediction in enumerate(predicted_soft_labels): nonzero_pred = [b.item() for b in np.argwhere(prediction > 0)] assert (len(nonzero_pred) in [1, 2]) if (len(nonzero_pred) == 1): nonzero_pred = 2 * nonzero_pred predicted_versions[prediction_idx] = nonzero_pred short_mesh_name = mesh_name.split('_aug')[0] # Load ground-truth softlabels. gt_soft_labels_file = os.path.join( meshcnn_root, f'datasets/{dataset_name}/sseg/{short_mesh_name}.seseg') gt_soft_labels = read_sseg(gt_soft_labels_file) # Load ground-truth hard labels. gt_hard_labels_file = os.path.join( meshcnn_root, f'datasets/{dataset_name}/seg/{short_mesh_name}.eseg') gt_hard_labels = read_seg(gt_hard_labels_file) - 1 edge_labels = np.empty([num_edges], dtype=np.float) # Compute accuracy based on soft edge labels. correct = 0.5 * seg_accuracy( torch.from_numpy(predicted_versions[:, 0].reshape(1, -1)), torch.from_numpy(gt_soft_labels.reshape( 1, -1, opt.nclasses)), [mesh]) + 0.5 * seg_accuracy( torch.from_numpy(predicted_versions[:, 1].reshape(1, -1)), torch.from_numpy(gt_soft_labels.reshape( 1, -1, opt.nclasses)), [mesh]) # Compute accuracy based on hard edge labels. correct_hard = 0.5 * (( np.nonzero(predicted_versions[:, 0] == gt_hard_labels)[0].shape[0] + np.nonzero(predicted_versions[:, 1] == gt_hard_labels)[0].shape[0]) ) / num_edges if (verbose): print( "\tThe percentage of the mesh that was correct labelled " f"according to ground-truth soft labels is {correct * 100:.4}%." ) print("\tThe percentage of the mesh that was correct labelled " "according to ground-truth hard labels is " f"{correct_hard * 100:.4}%.") accuracy_counter.update_counter(ncorrect=correct, ncorrect_hard=correct_hard, nexamples=1) accuracy_counter.print_acc(accuracy_counter.acc, accuracy_counter.acc_hard)