2727)
2828from bpy .utils import register_class , unregister_class
2929
30+ import cProfile , pstats , io
31+ from pstats import SortKey
32+
3033import os , sys , math , re , typing
3134from array import array
3235from struct import *
4346# from SM64classes import *
4447
4548from ..f3d .f3d_import import *
49+ from ..f3d .f3d_material import update_node_values_of_material
4650from ..panels import SM64_Panel
4751from ..utility_importer import *
4852from ..utility import (
@@ -277,7 +281,7 @@ def link_bpy_obj_to_empty(
277281 child .select_set (True )
278282 model_obj .select_set (True )
279283 bpy .context .view_layer .objects .active = model_obj
280- bpy .ops .object .duplicate ()
284+ bpy .ops .object .duplicate_move ()
281285 new_obj = bpy .context .active_object
282286 bpy .ops .object .transform_apply (location = False , rotation = True , scale = True , properties = False )
283287 # unlink from col, add to area col
@@ -815,8 +819,12 @@ def apply_material_settings(self, mat: bpy.types.Material, textures: dict, tex_p
815819 f3d .draw_layer .sm64 = layer
816820 self .set_register_settings (mat , f3d )
817821 self .set_textures (f3d , textures , tex_path )
818- with bpy .context .temp_override (material = mat ):
819- bpy .ops .material .update_f3d_nodes ()
822+
823+ # manually call node update for speed
824+ mat .f3d_update_flag = True
825+ update_node_values_of_material (mat , bpy .context )
826+ mat .f3d_mat .presetName = "Custom"
827+ mat .f3d_update_flag = False
820828
821829 def set_textures (self , f3d : F3DMaterialProperty , textures : dict , tex_path : Path ):
822830 self .set_tex_scale (f3d )
@@ -909,8 +917,6 @@ def parse_tri(self, Tri: list[int]):
909917 return [a + L - self .LastLoad for a in Tri ]
910918
911919 def apply_mesh_data (self , obj : bpy .types .Object , mesh : bpy .types .Mesh , layer : int , tex_path : Path ):
912- # bpy.app.version >= (3, 5, 0)
913-
914920 bpy .context .view_layer .objects .active = obj
915921 ind = - 1
916922 new = - 1
@@ -954,24 +960,27 @@ def apply_mesh_data(self, obj: bpy.types.Object, mesh: bpy.types.Mesh, layer: in
954960 new = len (mesh .materials ) - 1
955961 # if somehow there is no material assigned to the triangle or something is lost
956962 if new != - 1 :
957- t .material_index = new
958- # Get texture size or assume 32, 32 otherwise
959- i = mesh .materials [new ].f3d_mat .tex0 .tex
960- if not i :
961- WH = (32 , 32 )
962- else :
963- WH = i .size
964- # Set UV data and Vertex Color Data
965- for v , l in zip (t .verts , t .loops ):
966- uv = self .UVs [v .index ]
967- vcol = self .VCs [v .index ]
968- # scale verts
969- l [uv_map ].uv = [a * (1 / (32 * b )) if b > 0 else a * 0.001 * 32 for a , b in zip (uv , WH )]
970- # idk why this is necessary. N64 thing or something?
971- l [uv_map ].uv [1 ] = l [uv_map ].uv [1 ] * - 1 + 1
972- l [v_color ] = [a / 255 for a in vcol ]
963+ self .apply_loop_data (new , mesh , t , uv_map , v_color , v_alpha )
973964 b_mesh .to_mesh (mesh )
974965
966+ def apply_loop_data (self , mat : bpy .Types .Material , mesh : bpy .Types .Mesh , tri , uv_map , v_color , v_alpha ):
967+ tri .material_index = mat
968+ # Get texture size or assume 32, 32 otherwise
969+ i = mesh .materials [mat ].f3d_mat .tex0 .tex
970+ if not i :
971+ WH = (32 , 32 )
972+ else :
973+ WH = i .size
974+ # Set UV data and Vertex Color Data
975+ for v , l in zip (tri .verts , tri .loops ):
976+ uv = self .UVs [v .index ]
977+ vcol = self .VCs [v .index ]
978+ # scale verts
979+ l [uv_map ].uv = [a * (1 / (32 * b )) if b > 0 else a * 0.001 * 32 for a , b in zip (uv , WH )]
980+ # idk why this is necessary. N64 thing or something?
981+ l [uv_map ].uv [1 ] = l [uv_map ].uv [1 ] * - 1 + 1
982+ l [v_color ] = [a / 255 for a in vcol ]
983+
975984 # create a new f3d_mat given an SM64_Material class but don't create copies with same props
976985 def create_new_f3d_mat (self , mat : SM64_Material , mesh : bpy .types .Mesh ):
977986 if not self .props .force_new_tex :
@@ -982,11 +991,14 @@ def create_new_f3d_mat(self, mat: SM64_Material, mesh: bpy.types.Mesh):
982991 dupe = mat .mat_hash_f3d (F3Dmat .f3d_mat )
983992 if dupe :
984993 return F3Dmat
985- if mesh .materials :
986- mat = mesh .materials [- 1 ]
987- new = mat .id_data .copy () # make a copy of the data block
994+ f3d_mat = None
995+ for mat in bpy .data .materials :
996+ if mat .is_f3d :
997+ f3d_mat = mat
998+ if f3d_mat :
999+ new_mat = f3d_mat .id_data .copy () # make a copy of the data block
9881000 # add a mat slot and add mat to it
989- mesh .materials .append (new )
1001+ mesh .materials .append (new_mat )
9901002 else :
9911003 if self .props .as_obj :
9921004 NewMat = bpy .data .materials .new (f"sm64 { mesh .name .replace ('Data' , 'material' )} " )
@@ -1900,7 +1912,7 @@ def write_armature_to_bpy(
19001912
19011913
19021914def apply_mesh_data (
1903- f3d_dat : SM64_F3D , obj : bpy .types .Object , mesh : bpy .types .Mesh , layer : int , root_path : Path , cleanup : bool = True
1915+ f3d_dat : SM64_F3D , obj : bpy .types .Object , mesh : bpy .types .Mesh , layer : int , root_path : Path , cleanup : bool = False
19041916):
19051917 f3d_dat .apply_mesh_data (obj , mesh , layer , root_path )
19061918 if cleanup :
@@ -2005,7 +2017,7 @@ def write_geo_to_bpy(
20052017
20062018
20072019# write the gfx for a level given the level data, and f3d data
2008- def write_level_to_bpy (lvl : Level , scene : bpy .types .Scene , root_path : Path , f3d_dat : SM64_F3D , cleanup : bool = True ):
2020+ def write_level_to_bpy (lvl : Level , scene : bpy .types .Scene , root_path : Path , f3d_dat : SM64_F3D , cleanup : bool = False ):
20092021 for area in lvl .areas .values ():
20102022 write_geo_to_bpy (area .geo , scene , f3d_dat , root_path , dict (), cleanup = cleanup )
20112023 return lvl
@@ -2186,7 +2198,7 @@ def import_level_graphics(
21862198 scene : bpy .types .Scene ,
21872199 root_path : Path ,
21882200 aggregates : list [Path ],
2189- cleanup : bool = True ,
2201+ cleanup : bool = False ,
21902202 col_name : str = None ,
21912203) -> Level :
21922204 lvl = find_level_models_from_geo (geo_paths , lvl , scene , root_path , col_name = col_name )
@@ -2360,9 +2372,11 @@ class SM64_LvlImport(Operator):
23602372 bl_label = "Import Level"
23612373 bl_idname = "wm.sm64_import_level"
23622374
2363- cleanup = True
2375+ cleanup = False
23642376
23652377 def execute (self , context ):
2378+ pr = cProfile .Profile ()
2379+ pr .enable ()
23662380 scene = context .scene
23672381 props = scene .fast64 .sm64 .importer
23682382
@@ -2423,14 +2437,20 @@ def execute(self, context):
24232437 lvl = import_level_graphics (
24242438 [geo_path ], lvl , scene , decomp_path , [level_data_path ], cleanup = self .cleanup , col_name = gfx_col
24252439 )
2440+ pr .disable ()
2441+ s = io .StringIO ()
2442+ sortby = SortKey .CUMULATIVE
2443+ ps = pstats .Stats (pr , stream = s ).sort_stats (sortby )
2444+ ps .print_stats (20 )
2445+ print (s .getvalue ())
24262446 return {"FINISHED" }
24272447
24282448
24292449class SM64_LvlGfxImport (Operator ):
24302450 bl_label = "Import Gfx"
24312451 bl_idname = "wm.sm64_import_level_gfx"
24322452
2433- cleanup = True
2453+ cleanup = False
24342454
24352455 def execute (self , context ):
24362456 scene = context .scene
0 commit comments