def main(): print("") print( "Move each vertex in set A to match the position of the closest vertex in set B" ) print("") ######################## mode selection ####################### # promt vertex CSV name # input: vertex CSV file with all the vertexes that I want to modify print( "Please enter name of vertex CSV input file with the vertices to be moved:" ) input_filename_vertex_source = core.prompt_user_filename(".csv") rawlist_vertex_source = core.read_file_to_csvlist( input_filename_vertex_source, use_jis_encoding=True) # verify that these are the correct kind of CSVs if rawlist_vertex_source[0] != core.pmxe_vertex_csv_header: core.pause_and_quit("Err: '{}' is not a valid vertex CSV".format( input_filename_vertex_source)) # promt vertex CSV name # input: vertex CSV file with all the vertexes that I want to modify print( "Please enter name of vertex CSV input file with the destination geometry:" ) input_filename_vertex_dest = core.prompt_user_filename(".csv") rawlist_vertex_dest = core.read_file_to_csvlist(input_filename_vertex_dest, use_jis_encoding=True) # verify that these are the correct kind of CSVs if rawlist_vertex_dest[0] != core.pmxe_vertex_csv_header: core.pause_and_quit("Err: '{}' is not a valid vertex CSV".format( input_filename_vertex_dest)) ########################################################## # for each vertex in vertex_source, find the closest vertex in vertex_dest and move the source vertex to that dest position for v in rawlist_vertex_source: if v[0] != core.pmxe_vertex_csv_tag: continue # calculate the dist from this v to all d, and store the minimum min_coord = [0, 0, 0] min_val = 100 for d in rawlist_vertex_dest: if d[0] != core.pmxe_vertex_csv_tag: continue dist = (v[2] - d[2])**2 + (v[3] - d[3])**2 + (v[4] - d[4])**2 if dist < min_val: min_val = dist min_coord = d[2:5] # found the minimum # now apply it to v v[2:5] = min_coord # write out # build the output file name and ensure it is free output_filename = input_filename_vertex_source[:-4] + "_aligned.csv" output_filename = core.get_unused_file_name(output_filename) print("Writing aligned result to '" + output_filename + "'...") # export modified CSV core.write_csvlist_to_file(output_filename, rawlist_vertex_source, use_jis_encoding=True) core.pause_and_quit("Done with everything! Goodbye!") return None
def main(): # print info to explain the purpose of this file print( "This tool will rotate the given geometry such that the two 'prime vertices' specified have equal values along the desired axis" ) print("Choose from 6 modes to pick axis of alignment and axis of rotation") print("Also choose whether to force their position to 0 or their average") # print info to explain what inputs it needs print( "Inputs: vertex CSV 'whatever.csv' containing all the geometry that will be rotated" ) # print info to explain what outputs it creates print( "Outputs: vertex CSV 'whatever_aligned.csv' where all the input geometry has been rotated" ) print("") ######################## mode selection ####################### print( "Choose an axis to align the points on, and an axis to rotate around:") print( " 1 = X-align, Y-rotate: create left-right symmetry by rotating left/right" ) # DONE print( " 2 = X-align, Z-rotate: create left-right symmetry by tilting left/right" ) # DONE print( " 3 = Y-align, X-rotate: create front-back level by tilting front/back" ) # DONE print( " 4 = Y-align, Z-rotate: create left-right level by tilting left/right" ) # DONE print(" 5 = Z-align, X-rotate: create vertical by tilting front/back" ) # DONE print( " 6 = Z-align, Y-rotate: create left-right symmetry by rotating left/right" ) # DONE mode = core.prompt_user_choice((1, 2, 3, 4, 5, 6)) if mode == 1: # DEFAULT CASE axis = "X" Xidx = 2 Zidx = 4 elif mode == 2: axis = "X" Xidx = 2 Zidx = 3 elif mode == 3: axis = "Y" Xidx = 3 Zidx = 4 elif mode == 4: axis = "Y" Xidx = 3 Zidx = 2 elif mode == 5: axis = "Z" Xidx = 4 Zidx = 3 elif mode == 6: axis = "Z" Xidx = 4 Zidx = 2 else: axis = "wtf" Xidx = 9999 Zidx = 9999 print("congrats you somehow broke it") # choose whether to align to axis=0 or align to axis=avg print("After rotate, shift prime points to " + axis + "=0 or leave at " + axis + "=avg?") print(" 1 = " + axis + "=0") print(" 2 = " + axis + "=avg") useavg = core.prompt_user_choice((1, 2)) useavg = bool(useavg - 1) # promt vertex CSV name # input: vertex CSV file with all the vertexes that I want to modify print("Please enter name of vertex CSV input file:") input_filename_vertex = core.prompt_user_filename(".csv") rawlist_vertex = core.read_file_to_csvlist(input_filename_vertex, use_jis_encoding=True) # verify that these are the correct kind of CSVs if rawlist_vertex[0] != core.pmxe_vertex_csv_header: core.pause_and_quit("Err: '{}' is not a valid vertex CSV".format( input_filename_vertex)) # i plan to re-write this out as a csv file, so let's maintain as much of the input formatting as possible header = rawlist_vertex.pop(0) ########################################################## # prompt for the two prime points: # text input 2 point IDs, to indicate the two points to align to x=0 prime_vertex_one = input("Prime vertex ID #1: ") prime_points = [] v1 = core.my_list_search(rawlist_vertex, lambda x: x[1] == int(prime_vertex_one), getitem=True) if v1 is None: core.pause_and_quit("Err: unable to find '" + prime_vertex_one + "' in vertex CSV, unable to operate") prime_points.append(copy.copy(v1)) prime_vertex_two = input("Prime vertex ID #2: ") v2 = core.my_list_search(rawlist_vertex, lambda x: x[1] == int(prime_vertex_two), getitem=True) if v2 is None: core.pause_and_quit("Err: unable to find '" + prime_vertex_two + "' in vertex CSV, unable to operate") prime_points.append(copy.copy(v2)) # CALCULATE THE AVERAGE # position of the two prime points... rotate around this point avgx = (prime_points[0][2] + prime_points[1][2]) / 2.0 avgy = (prime_points[0][3] + prime_points[1][3]) / 2.0 avgz = (prime_points[0][4] + prime_points[1][4]) / 2.0 avg = [avgx, avgy, avgz] # note: rotating around Y-axis, so Y never ever comes into it. Z is my effective Y. # CALCULATE THE ANGLE: # first shift both prime points so that prime0 is on 0/0/0 prime_points[1][2] -= prime_points[0][2] prime_points[1][3] -= prime_points[0][3] prime_points[1][4] -= prime_points[0][4] prime_points[0][2:5] = [0.0, 0.0, 0.0] # then calculate the angle between the two prime points # ensure deltaZ is positive: calculate the angle to whichever point has the greater z if prime_points[0][Zidx] < prime_points[1][Zidx]: vpx = prime_points[1][Xidx] vpz = prime_points[1][Zidx] else: vpx = -prime_points[1][Xidx] vpz = -prime_points[1][Zidx] # then use atan to calculate angle in radians angle = math.atan2(vpx, vpz) print("Angle = " + str(math.degrees(angle))) # APPLY THE ROTATION # horizontally rotate all points around the average point origin = (avg[Xidx - 2], avg[Zidx - 2]) origin_nrm = (0.0, 0.0) for i, v in enumerate(rawlist_vertex): point = (v[Xidx], v[Zidx]) newpoint = core.rotate2d(origin, angle, point) v[Xidx], v[Zidx] = newpoint # also rotate each normal! point_nrm = (v[Xidx + 3], v[Zidx + 3]) newnrm = core.rotate2d(origin_nrm, angle, point_nrm) v[Xidx + 3], v[Zidx + 3] = newnrm # progress printout core.print_progress_oneline(i / len(rawlist_vertex)) print("done rotating ") # FORCE TO ZERO if not useavg: # first shift all geometry so that one of the prime points is on the x=0 # choose to shift by prime0 shift = avg[Xidx - 2] for v in rawlist_vertex: v[Xidx] -= shift # # anything extremely close to 0 becomes set to exactly 0 if -0.000000001 < v[Xidx] < 0.000000001: v[Xidx] = 0.0 print("done shifting to zero ") # write out # re-add the header line rawlist_vertex = [header] + rawlist_vertex # build the output file name and ensure it is free output_filename = input_filename_vertex[:-4] + "_aligned.csv" output_filename = core.get_unused_file_name(output_filename) print("Writing aligned result to '" + output_filename + "'...") # export modified CSV core.write_csvlist_to_file(output_filename, rawlist_vertex, use_jis_encoding=True) core.pause_and_quit("Done with everything! Goodbye!") return None
# build the output file name and ensure it is free output_filename = input_filename_vertex_source[:-4] + "_aligned.csv" output_filename = core.get_unused_file_name(output_filename) print("Writing aligned result to '" + output_filename + "'...") # export modified CSV core.write_csvlist_to_file(output_filename, rawlist_vertex_source, use_jis_encoding=True) core.pause_and_quit("Done with everything! Goodbye!") return None if __name__ == '__main__': print("Nuthouse01 - 10/10/2020 - v5.03") if DEBUG: main() else: try: main() except (KeyboardInterrupt, SystemExit): # this is normal and expected, do nothing and die normally pass except Exception as ee: # if an unexpected error occurs, catch it and print it and call pause_and_quit so the window stays open for a bit print(ee) core.pause_and_quit( "ERROR: something truly strange and unexpected has occurred, sorry, good luck figuring out what tho" )
all_rigidbody_indices.append(bodyindex) pmx.rigidbodies.append(newbody_obj) pass # JOINTS # if there is only one body per fragment then this is okay without any joints # if there are several bodies then we need to create joints from the "center" rigidbody to the others # even if you try to limit the joint to 0 rotation and 0 slide it still has some wiggle in it :( not perfectly rigid # TODO: i'll deal with this if and only if an algorithm for filling fragments with rigidbodies is created for fragnum in range(len(all_vert_sets)): pass core.MY_PRINT_FUNC("") # write out output_filename_pmx = input_filename_pmx[0:-4] + "_fragfix.pmx" output_filename_pmx = core.get_unused_file_name(output_filename_pmx) pmxlib.write_pmx(output_filename_pmx, pmx, moreinfo=moreinfo) core.MY_PRINT_FUNC("Done!") return None if __name__ == '__main__': print(_SCRIPT_VERSION) # print info to explain the purpose of this file core.MY_PRINT_FUNC(helptext) core.MY_PRINT_FUNC("") main() core.pause_and_quit("Done with everything! Goodbye!")