1

I want to update my import .fbx, so it would replace and remove all duplicate materials. I have found how to do the action at: link

However, I don't really want to create my whole custom import .fbx that would basically do the same thing as the regular import, but also execute this at the end.

Is there a way I could piggyback my custom code onto existing functions? Meaning my addon script would only be:

def at_import_fbx_end():
    do_my_stuff()

Or something similar to this.

Mahrkeenerh
  • 139
  • 10
  • Is it possible to locate and reuse Blender's own code for importing FBX files? It's all open source and - with UI elements at least - it's often quite easy to find the source code for it. EDIT: I've found something that might help so I'll write an answer. – Onyx Feb 08 '22 at 13:04
  • Great suggestion. I was able to locate the files, and this will make the whole ordeal easier, and it will work, but it will be a separate import. Checking the code, I wasn't able to locate a function called, or event, or something, so I don't think I can just piggyback off of it – Mahrkeenerh Feb 08 '22 at 13:16
  • You can override operators to add logic before or after calling it. It's a bit hacky but could work – Gorgious Feb 08 '22 at 13:25
  • You mean directly editing the source code to include my custom decorator? I don't see any other way to do this, and I would very much like to avoid editing source code, as that's not really ideal, I'd rather just make the new import button. – Mahrkeenerh Feb 08 '22 at 13:27

2 Answers2

1

You can piggyback on an operator by declaring another operator that uses the same bl_idname. It's a common gotcha that we can use to our advantage. It's a hack and it might mess up things when you unregister, but nothing that you can't repair in a few minutes by replacing the script files.

This script will for instance apply a translation to all imported objects :

import bpy
from bpy_extras.io_utils import ImportHelper

import io_scene_fbx

class SimpleOperator(bpy.types.Operator, ImportHelper): bl_idname = "import_scene.fbx" # Overwrite the base operator bl_label = "FBX override"

def execute(self, context):
    # You can do things before importing
    io_scene_fbx.ImportFBX.execute(self, context)
    # You can do things after importing
    bpy.ops.transform.translate(value=(0, 0, 5))
    return {"FINISHED"}

We steal the importer settings. However the display will be messed up :

SimpleOperator.annotations.update(io_scene_fbx.ImportFBX.annotations)

def register(): bpy.utils.register_class(SimpleOperator)

def unregister(): bpy.utils.unregister_class(SimpleOperator) bpy.utils.register_class(io_scene_fbx.ImportFBX)

if name == "main": register()

Gorgious
  • 30,723
  • 2
  • 44
  • 101
  • LEGEN-dary. Exactly what I asked for, thank you. Any chance I can also add custom stuff to the existing import panel? BoopProperty to turn on or off this extra custom stuff? – Mahrkeenerh Feb 08 '22 at 14:08
  • And yes, when I was messing up with the original io_import_fbx, after unregistering it, I had to re-register the included FBX for it to work again. – Mahrkeenerh Feb 08 '22 at 14:15
  • Did some testing, and while I was able to add the check box into the import settings, I wasn't able to ignore it later on - it always got passed as keyword, and since it was extra, it threw an error – Mahrkeenerh Feb 08 '22 at 14:54
  • 1
    You can add properties to the operator and they will be displayed and work as they would normally. But In this case I couldn't do it specifically because of this line https://github.com/blender/blender-addons/blob/master/io_scene_fbx/init.py#L216 which dumbly relies on an exact sequence of argument names... https://github.com/blender/blender-addons/blob/master/io_scene_fbx/import_fbx.py#L2348-L2368 because when you add a property to the operator, it will also be added to self.as_keywords dictionary – Gorgious Feb 08 '22 at 14:55
  • One solution is to change this line in your blender install folder's scripts https://github.com/blender/blender-addons/blob/master/io_scene_fbx/init.py#L206-L207 and add your property name(s) to the list. I didn't test but I assume it would stop throwing errors – Gorgious Feb 08 '22 at 14:56
  • Yes, I assume that would solve the issue, but I'd rather avoid that, since it's not just for me. – Mahrkeenerh Feb 08 '22 at 14:57
  • You can also completely copy/paste the execute in your operator and fix the error there. You'd have to redo it if the base code ever changed if you want to be up to date. And you'd need to from io_scene_fbx.import_fbx import load – Gorgious Feb 08 '22 at 15:00
  • At this moment, I could just completely copy paste the import part inside io_import_fbx, replace parts I like, and it would not break the menu as well. I think we've reached the end here, with multiple options and some tradeoffs. Thanks for your contribution – Mahrkeenerh Feb 08 '22 at 15:11
  • Happy to help ! Cheers – Gorgious Feb 08 '22 at 15:21
0

I just had a quick look and if you right click on any menu operator you can access certain shortcuts, including the Python command for it. See image: as described

(To enable this function, you need to enable Python tooltips in Interface preferences > Display > Python Tooltips)

So for this example, your script could start with bpy.ops.import_scene.fbx(), then you add do_my_stuff() afterwards. (I clicked the copy command from the shown UI button for that code)

It may be that in order to combine these in a way that works, you'll need to add a custom UI panel or something where you can choose which file to import and then let your code run, removing duplicate materials once you've imported it.

As far as I know, Blender does not contain any signals for finishing things like file imports or other processes.

Onyx
  • 1,661
  • 1
  • 7
  • 17
  • (To enable this function, you need to enable Python tooltips in Interface preferences) – Mahrkeenerh Feb 08 '22 at 13:17
  • Thanks, I'll add that as a quick disclaimer just in case! – Onyx Feb 08 '22 at 13:17
  • Just using the bpy.ops.import_scene.fbx() doesn't help much, as that's importing the files on your own. The issues is, that the existing importer already has plenty of presets, but is missing some (in this case, the duplicate materials).

    That means I still have to copy the whole code of the import (as I want to keep all the possible import settings), and add my stuff on top of that. https://github.com/blender/blender-addons/blob/master/io_scene_fbx/init.py

    – Mahrkeenerh Feb 08 '22 at 13:19