Solve the quad mesh from the candidate quad faces. Args: face2edge (np.ndarray): [T, 3] face to edge relation edge2face (np.ndarray): [E, 2] edge to face relation quad2adj (np.ndarray): [Q, 8] adjacent quad faces of each quad face quads_distortion (np.ndarra
(
face2edge: np.ndarray,
edge2face: np.ndarray,
quad2adj: np.ndarray,
quads_distortion: np.ndarray,
quads_smoothness: np.ndarray,
quads_valid: np.ndarray,
)
| 201 | |
| 202 | |
| 203 | def sovle_quad( |
| 204 | face2edge: np.ndarray, |
| 205 | edge2face: np.ndarray, |
| 206 | quad2adj: np.ndarray, |
| 207 | quads_distortion: np.ndarray, |
| 208 | quads_smoothness: np.ndarray, |
| 209 | quads_valid: np.ndarray, |
| 210 | ): |
| 211 | """ |
| 212 | Solve the quad mesh from the candidate quad faces. |
| 213 | |
| 214 | Args: |
| 215 | face2edge (np.ndarray): [T, 3] face to edge relation |
| 216 | edge2face (np.ndarray): [E, 2] edge to face relation |
| 217 | quad2adj (np.ndarray): [Q, 8] adjacent quad faces of each quad face |
| 218 | quads_distortion (np.ndarray): [Q] distortion of each quad face |
| 219 | quads_smoothness (np.ndarray): [Q, 8] smoothness of each quad face connection |
| 220 | quads_valid (np.ndarray): [E] whether the quad corresponding to the edge is valid |
| 221 | |
| 222 | Returns: |
| 223 | weights (np.ndarray): [Q] weight of each valid quad face |
| 224 | """ |
| 225 | T = face2edge.shape[0] |
| 226 | E = edge2face.shape[0] |
| 227 | Q = quads_distortion.shape[0] |
| 228 | edge_valid = -np.ones(E, dtype=np.int32) |
| 229 | edge_valid[quads_valid] = np.arange(Q) |
| 230 | |
| 231 | quads_connection = np.stack([ |
| 232 | np.arange(Q)[:, None].repeat(8, axis=1), |
| 233 | quad2adj, |
| 234 | ], axis=-1)[quad2adj != -1] # [C, 2] |
| 235 | quads_connection = np.sort(quads_connection, axis=-1) # [C, 2] |
| 236 | quads_connection, quads_connection_idx = np.unique(quads_connection, axis=0, return_index=True) # [C, 2], [C] |
| 237 | quads_smoothness = quads_smoothness[quad2adj != -1] # [C] |
| 238 | quads_smoothness = quads_smoothness[quads_connection_idx] # [C] |
| 239 | C = quads_connection.shape[0] |
| 240 | |
| 241 | # Construct the linear programming problem |
| 242 | |
| 243 | # Variables: |
| 244 | # quads_weight: [Q] weight of each quad face |
| 245 | # tri_min_weight: [T] minimum weight of each triangle face |
| 246 | # conn_min_weight: [C] minimum weight of each quad face connection |
| 247 | # conn_max_weight: [C] maximum weight of each quad face connection |
| 248 | # Objective: |
| 249 | # mimi |
| 250 | |
| 251 | c = np.concatenate([ |
| 252 | quads_distortion - 3, |
| 253 | quads_smoothness*4 - 2, |
| 254 | quads_smoothness*4, |
| 255 | ], axis=0) # [Q+C] |
| 256 | |
| 257 | A_ub_triplet = np.concatenate([ |
| 258 | np.stack([np.arange(T), edge_valid[face2edge[:, 0]], np.ones(T)], axis=1), # [T, 3] |
| 259 | np.stack([np.arange(T), edge_valid[face2edge[:, 1]], np.ones(T)], axis=1), # [T, 3] |
| 260 | np.stack([np.arange(T), edge_valid[face2edge[:, 2]], np.ones(T)], axis=1), # [T, 3] |