[4.8] Importing FBX and combining meshes not working in promoted branch (commit 7cf4d6f26d74194c2a53fcb8fd41b8e5c6ef02d4)

It’s pretty simple to repro:

  1. Export a FBX with multiple meshes from your 3D modelling package
  2. Import (or reimport) it in UE 4.8 with the “Combine Meshes” option enabled

Opening the asset and attempt to set (or clear) a material on any but the first element (mesh) will cause a crash. Doing the same on the first element (mesh) in the LOD0 group will incorrectly affect all of the other meshes.

After importing a FBX with multiple meshes:

After setting a material ONLY to Element 0:

Notice how the same material has been applied to all other elements?

And if I attempt to clear (or set) the material of Element 1 or Element 2, I hit this assert followed by crashing back to the desktop:

Assertion failed: Info.MaterialIndex == SlotIndex [File:C:\Users\Neil\Prototype\PrototypeOC\UE4\Engine\Source\Editor\StaticMeshEditor\Private\StaticMeshEditorTools.cpp] [Line: 1257] 

UE4Editor.exe has triggered a breakpoint.

And this is the callstack:

 	KernelBase.dll!00007ffa4f15e002()	Unknown
>	UE4Editor-StaticMeshEditor.dll!FMeshSectionSettingsLayout::OnMaterialChanged(UMaterialInterface * NewMaterial, UMaterialInterface * PrevMaterial, int SlotIndex, bool bReplaceAll) Line 1257	C++
 	UE4Editor-StaticMeshEditor.dll!TBaseSPMethodDelegateInstance<0,FMeshSectionSettingsLayout,0,TTypeWrapper<void> __cdecl(UMaterialInterface * __ptr64,UMaterialInterface * __ptr64,int,bool)>::Execute(UMaterialInterface * <Params_0>, UMaterialInterface * <Params_1>, int <Params_2>, bool <Params_3>) Line 282	C++
 	UE4Editor-StaticMeshEditor.dll!TBaseSPMethodDelegateInstance<0,FMeshSectionSettingsLayout,0,void __cdecl(UMaterialInterface * __ptr64,UMaterialInterface * __ptr64,int,bool)>::ExecuteIfSafe(UMaterialInterface * <Params_0>, UMaterialInterface * <Params_1>, int <Params_2>, bool <Params_3>) Line 388	C++
 	UE4Editor-PropertyEditor.dll!FMaterialItemView::ReplaceMaterial(UMaterialInterface * NewMaterial, bool bReplaceAll) Line 750	C++
 	UE4Editor-PropertyEditor.dll!TBaseSPMethodDelegateInstance<0,FMaterialItemView,0,TTypeWrapper<void> __cdecl(FAssetData const & __ptr64)>::Execute(const FAssetData & <Params_0>) Line 282	C++
 	UE4Editor-PropertyEditor.dll!TBaseSPMethodDelegateInstance<0,FMaterialItemView,0,void __cdecl(FAssetData const & __ptr64)>::ExecuteIfSafe(const FAssetData & <Params_0>) Line 388	C++
 	UE4Editor-PropertyEditor.dll!SPropertyEditorAsset::SetValue(const FAssetData & AssetData) Line 476	C++
 	UE4Editor-PropertyEditor.dll!TBaseSPMethodDelegateInstance<0,SPropertyEditorAsset,0,TTypeWrapper<void> __cdecl(FAssetData const & __ptr64)>::Execute(const FAssetData & <Params_0>) Line 282	C++
 	UE4Editor-PropertyEditor.dll!TBaseSPMethodDelegateInstance<0,SPropertyEditorAsset,0,void __cdecl(FAssetData const & __ptr64)>::ExecuteIfSafe(const FAssetData & <Params_0>) Line 388	C++
 	UE4Editor-PropertyEditor.dll!SPropertyMenuAssetPicker::OnClear() Line 225	C++
 	UE4Editor-PropertyEditor.dll!TBaseSPMethodDelegateInstance<0,SPropertyMenuAssetPicker,0,TTypeWrapper<void> __cdecl(void)>::Execute() Line 282	C++
 	UE4Editor-PropertyEditor.dll!TBaseSPMethodDelegateInstance<0,SPropertyMenuAssetPicker,0,void __cdecl(void)>::ExecuteIfSafe() Line 388	C++
 	UE4Editor-Slate.dll!SMenuEntryBlock::OnClicked(bool bCheckBoxClicked) Line 897	C++
 	UE4Editor-Slate.dll!SMenuEntryBlock::OnMenuItemButtonClicked() Line 847	C++
 	UE4Editor-Slate.dll!TMemberFunctionCaller<SMenuEntryBlock,FReply (__cdecl SMenuEntryBlock::*)(void) __ptr64>::operator()<>() Line 161	C++
 	UE4Editor-Slate.dll!TTupleImpl<TIntegerSequence<> >::ApplyAfter_ExplicitReturnType<FReply,TMemberFunctionCaller<SMenuEntryBlock,FReply (__cdecl SMenuEntryBlock::*)(void) __ptr64> >(TMemberFunctionCaller<SMenuEntryBlock,FReply (__cdecl SMenuEntryBlock::*)(void)> && Func) Line 113	C++
 	UE4Editor-Slate.dll!TBaseSPMethodDelegateInstance<0,SMenuEntryBlock,0,FReply __cdecl(void)>::Execute() Line 282	C++
 	UE4Editor-Slate.dll!TBaseDelegate<FReply>::Execute() Line 440	C++
 	UE4Editor-Slate.dll!SButton::OnMouseButtonUp(const FGeometry & MyGeometry, const FPointerEvent & MouseEvent) Line 225	C++
 	UE4Editor-Slate.dll!FSlateApplication::ProcessMouseButtonUpEvent::__l18::<lambda>(const FArrangedWidget & TargetWidget, const FPointerEvent & Event) Line 4148	C++
 	UE4Editor-Slate.dll!FEventRouter::Route<FReply,FEventRouter::FToLeafmostPolicy,FPointerEvent,FReply <lambda>(const FArrangedWidget &, const FPointerEvent &) >(FSlateApplication * ThisApplication, FEventRouter::FToLeafmostPolicy RoutingPolicy, FPointerEvent EventCopy, const FSlateApplication::ProcessMouseButtonUpEvent::__l18::FReply <lambda>(const FArrangedWidget &, const FPointerEvent &) & Lambda) Line 210	C++
 	UE4Editor-Slate.dll!FSlateApplication::ProcessMouseButtonUpEvent(FPointerEvent & MouseEvent) Line 4151	C++
 	UE4Editor-Slate.dll!FSlateApplication::OnMouseUp(const EMouseButtons::Type Button) Line 4111	C++
 	UE4Editor-Core.dll!FWindowsApplication::ProcessDeferredMessage(const FDeferredWindowsMessage & DeferredMessage) Line 1407	C++
 	UE4Editor-Core.dll!FWindowsApplication::DeferMessage(TSharedPtr<FWindowsWindow,0> & NativeWindow, HWND__ * InHWnd, unsigned int InMessage, unsigned __int64 InWParam, __int64 InLParam, int MouseX, int MouseY, unsigned int RawInputFlags) Line 1712	C++
 	UE4Editor-Core.dll!FWindowsApplication::ProcessMessage(HWND__ * hwnd, unsigned int msg, unsigned __int64 wParam, __int64 lParam) Line 707	C++
 	UE4Editor-Core.dll!FWindowsApplication::AppWndProc(HWND__ * hwnd, unsigned int msg, unsigned __int64 wParam, __int64 lParam) Line 629	C++
 	user32.dll!00007ffa4f83250d()	Unknown
 	user32.dll!00007ffa4f832367()	Unknown
 	UE4Editor-Core.dll!FWindowsPlatformMisc::PumpMessages(bool bFromMainLoop) Line 784	C++
 	UE4Editor.exe!FEngineLoop::Tick() Line 2292	C++
 	UE4Editor.exe!GuardedMain(const wchar_t * CmdLine, HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, int nCmdShow) Line 142	C++
 	UE4Editor.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow) Line 238	C++
 	UE4Editor.exe!__tmainCRTStartup() Line 618	C
 	kernel32.dll!00007ffa4f4d13d2()	Unknown
 	ntdll.dll!00007ffa51c3eb64()	Unknown

I have a potential “fix” or workaround in UStaticMesh* UnFbx::FFbxImporter::ImportStaticMeshAsSingle()

I’ve changed the following:

		int32 NumMaterials = FMath::Min(SortedMaterials.Num(),MaxMaterialIndex+1);
		for (int32 MaterialIndex = 0; MaterialIndex < NumMaterials; ++MaterialIndex)
		{
			FMeshSectionInfo Info = StaticMesh->SectionInfoMap.Get(LODIndex, MaterialIndex);
			int32 Index = StaticMesh->Materials.Find( SortedMaterials[MaterialIndex] );
			if( Index == INDEX_NONE )
			{
				Index = StaticMesh->Materials.Num();
				StaticMesh->Materials.Add(SortedMaterials[MaterialIndex]);
			}

			Info.MaterialIndex = Index;
			StaticMesh->SectionInfoMap.Set(LODIndex, MaterialIndex, Info);
			
		}

To be this:

		int32 NumMaterials = FMath::Min(SortedMaterials.Num(),MaxMaterialIndex+1);
		for (int32 MaterialIndex = 0; MaterialIndex < NumMaterials; ++MaterialIndex)
		{
			FMeshSectionInfo Info = StaticMesh->SectionInfoMap.Get(LODIndex, MaterialIndex);
			int32 Index = StaticMesh->Materials.Find( SortedMaterials[MaterialIndex] );
			if( Index == INDEX_NONE )
			{
				Index = StaticMesh->Materials.Num();
				StaticMesh->Materials.Add(SortedMaterials[MaterialIndex]);
			}
			else
			{
				StaticMesh->Materials.Add( SortedMaterials[ Index ] );
				Index = MaterialIndex;
			}
			Info.MaterialIndex = Index;
			StaticMesh->SectionInfoMap.Set(LODIndex, MaterialIndex, Info);
			
		}

I have a theory that this problem exists for any FBX that has multiple meshes that you are combining and you are NOT importing materials.

Awesome work, Neil!!

Hi Neil -

I have entered a bug report for this crash as UE-12187.

Thank You

Eric Ketchum

Thanks Eric! The workaround I posted about in my answer seems to solve my problem (and work in the intended way) for now.