NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

cosmeticsManager.py (23767B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\environment\spaceObject\cosmeticsManager.py
      2 from __future__ import print_function
      3 from __future__ import absolute_import
      4 import logging
      5 import blue
      6 import evegraphics.effects as gfx
      7 import evegraphics.utils as gfxutils
      8 import evetypes
      9 import trinity
     10 from cosmetics.common.ships.skins.static_data.component import ComponentsDataLoader, PatternProjectionType
     11 from cosmetics.common.ships.skins.static_data.pattern_blend_mode import PatternBlendMode
     12 from cosmetics.common.ships.skins.static_data.slot_name import SlotID, PATTERN_SLOT_IDS
     13 from trinity import EveSOFDataAreaType
     14 from .cosmeticsConst import AREA_MAPS, BLEND_MODE, DARKHULL_TEXTURE_MAP, PATTERN_INDEX_MAP
     15 logger = logging.getLogger(__name__)
     16 RESOURCE_NAME_BY_INDEX = {0: 'PatternMask1Map',
     17  1: 'PatternMask2Map'}
     18 INDEX_BY_SLOT_ID = {SlotID.PATTERN: 0,
     19  SlotID.SECONDARY_PATTERN: 1}
     20 
     21 class CosmeticsManager:
     22 
     23     def __init__(self):
     24         self.sofService = sm.GetService('sofService')
     25         self.model = None
     26         self.faction_id = None
     27         self.pattern = None
     28         self.targetMaterials = [1.0,
     29          1.0,
     30          1.0,
     31          1.0]
     32         self.hull_name = 'gc3_t1'
     33         self.mat1 = str()
     34         self.mat2 = str()
     35         self.mat3 = str()
     36         self.mat4 = str()
     37         self.pmat1 = str()
     38         self.pmat2 = str()
     39         self.selected_materials = dict()
     40         self.projection_texture = ''
     41         self.projection_texture_secondary = ''
     42 
     43     @property
     44     def sofDB(self):
     45         return self.sofService.spaceObjectFactory.GetSofDB()
     46 
     47     def apply_design(self, skin_design):
     48         if not skin_design:
     49             return
     50         for slot_id, component_instance in skin_design.slot_layout.slots.items():
     51             self.apply_component(slot_id, component_instance)
     52 
     53         self.UpdatePatternProjectionParametersFromSkinState(skin_design, self.model)
     54         blend_mode = skin_design.slot_layout.pattern_blend_mode
     55         if blend_mode is not None:
     56             CosmeticsManager.SetBlendMode(self.model, blendMode=blend_mode)
     57 
     58     def apply_component(self, slot_id, component_instance):
     59         if not component_instance:
     60             self.selected_materials.pop(slot_id, None)
     61             path = ''
     62         else:
     63             component_data = component_instance.get_component_data()
     64             path = component_data.resource_file_path if component_data else None
     65         if slot_id in PATTERN_SLOT_IDS:
     66             self.SetProjectionTexture(path, slot_id)
     67             if component_instance:
     68                 component_instance.ellipsoid_center = self.model.shapeEllipsoidCenter
     69                 component_instance.ellipsoid_radii = self.model.shapeEllipsoidRadius
     70                 CosmeticsManager.ConfigurePatternBorderSettings(self.model, component_instance.projection_type_u, component_instance.projection_type_v, slot_id)
     71                 self.ApplyScaling(slot_id, component_instance.scaling)
     72                 self.ApplyTranslation(slot_id, component_instance.position)
     73                 self.ApplyRotation(slot_id, component_instance.rotation)
     74                 self.SetMirroredState(slot_id, component_instance.mirrored)
     75         elif slot_id == SlotID.SECONDARY_PATTERN_MATERIAL:
     76             self.SetMaterialOnArea(path, slot_id)
     77         else:
     78             self.SetMaterialOnArea(path, slot_id)
     79 
     80     def get_all_pattern_texture_names(self):
     81         pass
     82 
     83     def get_pattern_texture_name(self):
     84         pass
     85 
     86     def SetModel(self, model):
     87         self.model = model
     88         dna_parts = model.dna.split(':')
     89         self.hull_name = dna_parts[0]
     90         self.faction = dna_parts[1]
     91         self.race = dna_parts[2]
     92         factionID = evetypes.GetFactionID(self.typeID)
     93         self.SetFaction(factionID)
     94         hull = [ hull for hull in self.sofDB.hull if hull.name == self.hull_name ][0]
     95         darkhullAreas = [ area for area in hull.opaqueAreas if area.areaType == EveSOFDataAreaType.Darkhull ]
     96         if len(darkhullAreas) < 1:
     97             return
     98         darkuhull_indices = [ area.index for area in darkhullAreas ]
     99         darkhull_effects = [ area.effect for area in self.model.mesh.opaqueAreas if area.index in darkuhull_indices ]
    100         for fx in darkhull_effects:
    101             areaMap = AREA_MAPS[self.faction_id]
    102             targetIndex = areaMap[SlotID.TECH_AREA]
    103             texturePath = DARKHULL_TEXTURE_MAP[targetIndex]
    104             fxResource = [ res for res in fx.resources if res.name == 'MaterialMap' ][0]
    105             fxResource.resourcePath = texturePath
    106 
    107     def SetTypeID(self, type_id):
    108         self.typeID = type_id
    109 
    110     def SetFaction(self, factionID):
    111         self.faction_id = factionID
    112 
    113     def ApplyTranslation(self, slot_id, pos):
    114         if not self.model:
    115             return
    116         self._get_custom_mask(slot_id).position = pos
    117 
    118     def ApplyRotation(self, slot_id, rot):
    119         if not self.model:
    120             return
    121         self._get_custom_mask(slot_id).rotation = rot
    122 
    123     def _get_custom_mask(self, slot_id):
    124         mask_index = INDEX_BY_SLOT_ID[slot_id]
    125         return self.model.customMasks[mask_index]
    126 
    127     def ApplyScaling(self, slot_id, scaling):
    128         if not self.model:
    129             return
    130         self._get_custom_mask(slot_id).scaling = scaling
    131 
    132     def SetTargetMaterialArea(self, slot_id, area_id, is_active):
    133         if not self.model:
    134             return
    135         self.targetMaterials = list(self.targetMaterials)
    136         remapped_slot_id = AREA_MAPS[self.faction_id][area_id]
    137         self.targetMaterials[remapped_slot_id - 1] = float(is_active)
    138         mask = self.model.customMasks[INDEX_BY_SLOT_ID[slot_id]]
    139         mask.targetMaterials = self.targetMaterials
    140 
    141     def SetProjectionTexture(self, texturePath, slot_id = SlotID.PATTERN):
    142         attributeName = 'PatternMask1Map'
    143         if slot_id == SlotID.PATTERN:
    144             self.projection_texture = texturePath
    145         elif slot_id == SlotID.SECONDARY_PATTERN:
    146             attributeName = 'PatternMask2Map'
    147             self.projection_texture_secondary = texturePath
    148         for area in self.model.mesh.opaqueAreas:
    149             for each in area.effect.resources:
    150                 if each.name == attributeName:
    151                     each.resourcePath = texturePath
    152 
    153     @staticmethod
    154     def SetBlendMode(model, blendMode = PatternBlendMode.OVERLAY):
    155         if not model:
    156             return
    157         effects = [ area.effect for area in model.mesh.opaqueAreas ]
    158         for each in effects:
    159             gfx.SetEffectOption(each, 'BLEND_MODE', BLEND_MODE[blendMode])
    160 
    161     def SetMirroredState(self, slot_id, is_mirrored):
    162         if self.model:
    163             self._get_custom_mask(slot_id).isMirrored = is_mirrored
    164 
    165     def GetDefaultMaterialForSlot(self, slot_id):
    166         factionData = [ faction for faction in self.sofDB.faction if faction.name == self.faction ][0].areaTypes.Primary
    167         try:
    168             targetSlot = AREA_MAPS[self.faction_id][slot_id]
    169         except KeyError:
    170             return
    171 
    172         if targetSlot == 1:
    173             return factionData.material1
    174         if targetSlot == 2:
    175             return factionData.material2
    176         if targetSlot == 3:
    177             return factionData.material3
    178         if targetSlot == 4:
    179             return factionData.material4
    180 
    181     @staticmethod
    182     def GetDefaultMaterialForSlotStatic(slot_id, factionName, factionID):
    183         sofDB = sm.GetService('sofService').spaceObjectFactory.GetSofDB()
    184         if sofDB is None:
    185             return
    186         factionData = [ faction for faction in sofDB.faction if faction.name == factionName ][0].areaTypes.Primary
    187         targetSlot = AREA_MAPS[factionID][slot_id]
    188         if targetSlot == 1:
    189             return factionData.material1
    190         if targetSlot == 2:
    191             return factionData.material2
    192         if targetSlot == 3:
    193             return factionData.material3
    194         if targetSlot == 4:
    195             return factionData.material4
    196 
    197     def SetMaterialOnDarkhull(self, material, hull):
    198         darkhullAreas = [ area for area in hull.opaqueAreas if area.areaType == EveSOFDataAreaType.Darkhull ]
    199         if len(darkhullAreas) < 1:
    200             return
    201         prefix = ''
    202         indices = ['1',
    203          '2',
    204          '3',
    205          '4']
    206         for idx in indices:
    207             index_string = prefix + 'Mtl' + idx
    208             diffuseName = index_string + 'DiffuseColor'
    209             dustDiffuseName = index_string + 'DustDiffuseColor'
    210             fresnelName = index_string + 'FresnelColor'
    211             glossName = index_string + 'Gloss'
    212             darkuhull_indices = [ area.index for area in darkhullAreas ]
    213             darkhull_effects = [ area.effect for area in self.model.mesh.opaqueAreas if area.index in darkuhull_indices ]
    214             for fx in darkhull_effects:
    215                 gfx.SetParameterValue(fx, diffuseName, material.parameters[0].value)
    216                 gfx.SetParameterValue(fx, dustDiffuseName, material.parameters[1].value)
    217                 gfx.SetParameterValue(fx, fresnelName, material.parameters[2].value)
    218                 gfx.SetParameterValue(fx, glossName, material.parameters[3].value)
    219 
    220     def SetMaterialOnArea(self, resPath, slot_id):
    221         if not resPath:
    222             material_name = self.GetDefaultMaterialForSlot(slot_id)
    223             if material_name is None:
    224                 return
    225             material_path = 'res:/dx9/model/SpaceObjectFactory/materials/' + material_name + '.red'
    226         else:
    227             material_path = resPath
    228         material = blue.resMan.LoadObject(material_path)
    229         self.selected_materials[slot_id] = resPath
    230         dna = self.model.dna
    231         hullName = dna.split(':')[0]
    232         hull = [ hull for hull in self.sofDB.hull if hull.name == hullName ][0]
    233         allowedShaders = ['quad/quaddetailv5.fx',
    234          'quad/quadv5.fx',
    235          'quad/skinned_quadheatv5.fx',
    236          'skinned_quaddetailv5.fx']
    237         if slot_id == SlotID.PATTERN_MATERIAL or slot_id == SlotID.SECONDARY_PATTERN_MATERIAL:
    238             primaryAreas = [ area for area in hull.opaqueAreas ]
    239             decalAreas = [ area for area in hull.decalAreas ]
    240             for each in decalAreas:
    241                 primaryAreas.append(each)
    242 
    243         else:
    244             primaryAreas = [ area for area in hull.opaqueAreas if area.areaType == EveSOFDataAreaType.Primary or area.areaType == EveSOFDataAreaType.SimplePrimary or area.areaType == EveSOFDataAreaType.Reactor or area.areaType == EveSOFDataAreaType.Ornament or 'area_hull' in area.name and area.shader in allowedShaders ]
    245         prefix = ''
    246         index_sting = str()
    247         if self.faction_id in AREA_MAPS.keys():
    248             index_string = str(AREA_MAPS[self.faction_id][slot_id])
    249         else:
    250             index_string = str(AREA_MAPS[500003])
    251             print('area map missing for faction_id')
    252             print(self.faction_id)
    253         if slot_id is SlotID.PATTERN_MATERIAL:
    254             prefix = 'P'
    255             index_string = '1'
    256         if slot_id is SlotID.SECONDARY_PATTERN_MATERIAL:
    257             prefix = 'P'
    258             index_string = '2'
    259         index_string = prefix + 'Mtl' + index_string
    260         diffuseName = index_string + 'DiffuseColor'
    261         dustDiffuseName = index_string + 'DustDiffuseColor'
    262         fresnelName = index_string + 'FresnelColor'
    263         glossName = index_string + 'Gloss'
    264         indices = [ area.index for area in primaryAreas ]
    265         effects = [ area.effect for area in self.model.mesh.opaqueAreas if area.index in indices ]
    266         diffuseValue = filter(lambda obj: obj.name == 'DiffuseColor', material.parameters)
    267         diffuseValue = diffuseValue[0].value if diffuseValue else material.parameters[0].value
    268         dustDiffuseValue = filter(lambda obj: obj.name == 'DustDiffuseColor', material.parameters)
    269         dustDiffuseValue = dustDiffuseValue[0].value if dustDiffuseValue else material.parameters[1].value
    270         fresnelValue = filter(lambda obj: obj.name == 'FresnelColor', material.parameters)
    271         fresnelValue = fresnelValue[0].value if fresnelValue else material.parameters[2].value
    272         glossValue = filter(lambda obj: obj.name == 'Gloss', material.parameters)
    273         glossValue = glossValue[0].value if glossValue else material.parameters[3].value
    274         for fx in effects:
    275             gfx.SetParameterValue(fx, fresnelName, fresnelValue)
    276             gfx.SetParameterValue(fx, dustDiffuseName, dustDiffuseValue)
    277             gfx.SetParameterValue(fx, diffuseName, diffuseValue)
    278             gfx.SetParameterValue(fx, glossName, glossValue)
    279 
    280         if slot_id is SlotID.TECH_AREA:
    281             self.SetMaterialOnDarkhull(material, hull)
    282 
    283     @staticmethod
    284     def GetSlotComponentFromSkinState(skin_state, slotIndex):
    285         slots, slot = (None, None)
    286         if hasattr(skin_state, 'skin_data'):
    287             if skin_state.skin_data is not None and hasattr(skin_state.skin_data, 'slot_layout'):
    288                 if skin_state.skin_data.slot_layout is not None and hasattr(skin_state.skin_data.slot_layout, 'slots'):
    289                     slots = skin_state.skin_data.slot_layout.slots
    290         if skin_state is not None and hasattr(skin_state, 'slot_layout'):
    291             if skin_state.slot_layout is not None and hasattr(skin_state.slot_layout, 'slots'):
    292                 slots = skin_state.slot_layout.slots
    293         if slots is not None:
    294             slot = slots.get(slotIndex)
    295         return slot
    296 
    297     @staticmethod
    298     def CreateSOFDNAfromSkinState(skinState, typeID):
    299         baseDNA = gfxutils.BuildSOFDNAFromTypeID(typeID)
    300         try:
    301             primaryMaterial = CosmeticsManager.GetSlotComponentFromSkinState(skinState, SlotID.PRIMARY_NANOCOATING)
    302             secondaryMaterial = CosmeticsManager.GetSlotComponentFromSkinState(skinState, SlotID.SECONDARY_NANOCOATING)
    303             tertiaryMaterial = CosmeticsManager.GetSlotComponentFromSkinState(skinState, SlotID.TERTIARY_NANOCOATING)
    304             techMaterial = CosmeticsManager.GetSlotComponentFromSkinState(skinState, SlotID.TECH_AREA)
    305             patternComponent = CosmeticsManager.GetSlotComponentFromSkinState(skinState, SlotID.PATTERN)
    306             patternMaterial = CosmeticsManager.GetSlotComponentFromSkinState(skinState, SlotID.PATTERN_MATERIAL)
    307             secondaryPatternComponent = CosmeticsManager.GetSlotComponentFromSkinState(skinState, SlotID.SECONDARY_PATTERN)
    308             secondaryPatternMaterial = CosmeticsManager.GetSlotComponentFromSkinState(skinState, SlotID.SECONDARY_PATTERN_MATERIAL)
    309             dna_parts = baseDNA.split(':')
    310             faction = dna_parts[1]
    311             materialString = ':material?'
    312             materialSlots = [SlotID.PRIMARY_NANOCOATING,
    313              SlotID.SECONDARY_NANOCOATING,
    314              SlotID.TERTIARY_NANOCOATING,
    315              SlotID.TECH_AREA]
    316             materialComponents = [primaryMaterial,
    317              secondaryMaterial,
    318              tertiaryMaterial,
    319              techMaterial]
    320             materials = ['',
    321              '',
    322              '',
    323              '']
    324             for materialIndex in range(4):
    325                 component = materialComponents[materialIndex]
    326                 componentID = None
    327                 if component is not None:
    328                     if hasattr(component, 'component_id'):
    329                         componentID = component.component_id
    330                 if componentID is None:
    331                     defaultFactionID = evetypes.GetFactionID(typeID)
    332                     materialSOFName = CosmeticsManager.GetDefaultMaterialForSlotStatic(materialSlots[materialIndex], faction, defaultFactionID)
    333                 else:
    334                     component_data = ComponentsDataLoader.get_component_data(componentID)
    335                     filePath = component_data.resource_file_path
    336                     material = trinity.Load(filePath)
    337                     materialSOFName = material.name
    338                 defaultFactionID = evetypes.GetFactionID(typeID)
    339                 materialMappedIndex = AREA_MAPS[defaultFactionID][materialSlots[materialIndex]]
    340                 materials[materialMappedIndex - 1] = materialSOFName
    341 
    342             for each in materials:
    343                 materialString += each + ';'
    344 
    345             if None not in materials:
    346                 baseDNA += materialString[:-1]
    347             if patternComponent is not None:
    348                 componentID = None
    349                 if patternComponent is not None:
    350                     if hasattr(patternComponent, 'component_id'):
    351                         componentID = patternComponent.component_id
    352                 if componentID is not None:
    353                     patternString = ':pattern?'
    354                     filePath = 'res:/dx9/model/SpaceObjectFactory/patterns/cosm_blank_projection.red'
    355                     pattern = trinity.Load(filePath)
    356                     patternName = pattern.name
    357                     patternString += patternName
    358                     materialComponentID = None
    359                     if patternMaterial is not None:
    360                         if hasattr(patternMaterial, 'component_id'):
    361                             materialComponentID = patternMaterial.component_id
    362                     if materialComponentID is not None:
    363                         component_data = ComponentsDataLoader.get_component_data(materialComponentID)
    364                         filePath = component_data.resource_file_path
    365                         patternMaterial = trinity.Load(filePath)
    366                         patternMaterialName = patternMaterial.name
    367                         patternString += ';' + patternMaterialName
    368                     secondaryMaterialComponentID = None
    369                     if secondaryPatternMaterial is not None:
    370                         if hasattr(secondaryPatternMaterial, 'component_id'):
    371                             secondaryMaterialComponentID = secondaryPatternMaterial.component_id
    372                     if secondaryMaterialComponentID is not None:
    373                         component_data = ComponentsDataLoader.get_component_data(secondaryMaterialComponentID)
    374                         filePath = component_data.resource_file_path
    375                         secondaryPatternMaterial = trinity.Load(filePath)
    376                         secondaryPatternMaterialName = secondaryPatternMaterial.name
    377                         patternString += ';' + secondaryPatternMaterialName
    378                     baseDNA += patternString
    379         except Exception as exc:
    380             logger.exception('Failed to create DNA from SKIN state: %s', exc)
    381 
    382         return baseDNA
    383 
    384     @staticmethod
    385     def ClearPatternProjections(model):
    386         for area in model.mesh.opaqueAreas:
    387             for each in area.effect.resources:
    388                 if each.name == 'PatternMask1Map' or each.name == 'PatternMask2Map':
    389                     each.resourcePath = 'res:/texture/Global/black.dds'
    390 
    391     @staticmethod
    392     def UpdatePatternProjectionParametersFromSkinState(skin_state, model, typeID = None):
    393         try:
    394             CosmeticsManager.ClearPatternProjections(model)
    395             if hasattr(skin_state, 'ship_type_id'):
    396                 typeID = skin_state.ship_type_id
    397             for slot_id in PATTERN_SLOT_IDS:
    398                 CosmeticsManager._apply_pattern_projection_parameters(slot_id, skin_state, model, typeID)
    399 
    400             sofDB = sm.GetService('sofService').spaceObjectFactory.GetSofDB()
    401             hull_name = model.dna.split(':')[0]
    402             hull = [ hull for hull in sofDB.hull if hull.name == hull_name ][0]
    403             darkhullAreas = [ area for area in hull.opaqueAreas if area.areaType == EveSOFDataAreaType.Darkhull ]
    404             if len(darkhullAreas) < 1:
    405                 return
    406             darkuhull_indices = [ area.index for area in darkhullAreas ]
    407             darkhull_effects = [ area.effect for area in model.mesh.opaqueAreas if area.index in darkuhull_indices ]
    408             if typeID:
    409                 for fx in darkhull_effects:
    410                     faction_id = evetypes.GetFactionID(typeID)
    411                     areaMap = AREA_MAPS[faction_id]
    412                     targetIndex = areaMap[SlotID.TECH_AREA]
    413                     texturePath = DARKHULL_TEXTURE_MAP[targetIndex]
    414                     fxResource = [ res for res in fx.resources if res.name == 'MaterialMap' ][0]
    415                     fxResource.resourcePath = texturePath
    416 
    417         except Exception as exc:
    418             logger.exception('Failed to create DNA from SKIN state: %s', exc)
    419 
    420     @staticmethod
    421     def _apply_pattern_projection_parameters(slot_id, skin_state, model, typeID):
    422         custom_mask_index = INDEX_BY_SLOT_ID[slot_id]
    423         component_instance = CosmeticsManager.GetSlotComponentFromSkinState(skin_state, slot_id)
    424         try:
    425             if component_instance is not None:
    426                 patternMask = model.customMasks[custom_mask_index]
    427                 patternMask.position = component_instance.position
    428                 patternMask.rotation = component_instance.rotation
    429                 patternMask.scaling = component_instance.scaling
    430                 selectedSlots = (float(component_instance.projection_area1),
    431                  float(component_instance.projection_area2),
    432                  float(component_instance.projection_area3),
    433                  float(component_instance.projection_area4))
    434                 materialSlots = [SlotID.PRIMARY_NANOCOATING,
    435                  SlotID.SECONDARY_NANOCOATING,
    436                  SlotID.TERTIARY_NANOCOATING,
    437                  SlotID.TECH_AREA]
    438                 if typeID is not None:
    439                     slots = [1.0,
    440                      1.0,
    441                      1.0,
    442                      1.0]
    443                     for index in range(4):
    444                         defaultFactionID = evetypes.GetFactionID(typeID)
    445                         materialMappedIndex = AREA_MAPS[defaultFactionID][materialSlots[index]]
    446                         slots[materialMappedIndex - 1] = selectedSlots[index]
    447 
    448                     selectedSlots = tuple(slots)
    449                 patternMask.targetMaterials = selectedSlots
    450                 patternMask.isMirrored = component_instance.mirrored
    451                 patternComponentID = component_instance.component_id
    452                 component_data = ComponentsDataLoader.get_component_data(patternComponentID)
    453                 CosmeticsManager.ConfigurePatternBorderSettings(model, component_instance.projection_type_u, component_instance.projection_type_v, slot_id)
    454                 texturePath = component_data.resource_file_path
    455                 for area in model.mesh.opaqueAreas:
    456                     for each in area.effect.resources:
    457                         if each.name == RESOURCE_NAME_BY_INDEX[custom_mask_index]:
    458                             each.resourcePath = texturePath
    459 
    460         except Exception as exc:
    461             logger.exception('Failed to apply projection parameters: %s', exc)
    462 
    463     @staticmethod
    464     def ConfigurePatternBorderSettings(model, projection_type_u, projection_type_v, slot_id):
    465         projection_type_to_address = {PatternProjectionType.CLAMP: 4,
    466          PatternProjectionType.REPEAT: 1,
    467          PatternProjectionType.BORDER: 3}
    468         pattern_index = PATTERN_INDEX_MAP[slot_id]
    469         targetTextureName = 'PatternMask' + str(pattern_index) + 'MapSampler'
    470         for area in model.mesh.opaqueAreas:
    471             populateParameters = False
    472             for i, each in enumerate(area.effect.samplerOverrides):
    473                 if len(each) < 3:
    474                     continue
    475                 if each[0] == targetTextureName:
    476                     mutableObj = list(each)
    477                     mutableObj[1] = projection_type_to_address.get(projection_type_u, 4)
    478                     mutableObj[2] = projection_type_to_address.get(projection_type_v, 4)
    479                     area.effect.samplerOverrides[i] = tuple(mutableObj)
    480                     populateParameters = True
    481 
    482             if populateParameters:
    483                 area.effect.PopulateParameters()