Files

202 lines
7.4 KiB
C++

/*
* Copyright (c) <2017> Side Effects Software Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Produced by:
* Mykola Konyk
* Side Effects Software Inc
* 123 Front Street West, Suite 1401
* Toronto, Ontario
* Canada M5J 2M2
* 416-504-9876
*
*/
#include "HoudiniEngineSubstance.h"
#include "HoudiniApi.h"
#include "HoudiniEngine.h"
#include "HoudiniEngineRuntimePrivatePCH.h"
#include "HoudiniEngineUtils.h"
#include "HoudiniEngineString.h"
bool
FHoudiniEngineSubstance::GetSubstanceMaterialName(
const HAPI_MaterialInfo & MaterialInfo,
FString & SubstanceMaterialName )
{
SubstanceMaterialName = TEXT( "" );
// Get the node info
HAPI_NodeInfo NodeInfo;
FHoudiniApi::NodeInfo_Init(&NodeInfo);
HOUDINI_CHECK_ERROR_RETURN( FHoudiniApi::GetNodeInfo(
FHoudiniEngine::Get().GetSession(), MaterialInfo.nodeId, &NodeInfo ), false );
// Get the parm infos
TArray< HAPI_ParmInfo > ParmInfos;
if ( NodeInfo.parmCount > 0 )
{
ParmInfos.SetNumZeroed(NodeInfo.parmCount);
if (FHoudiniApi::GetParameters( FHoudiniEngine::Get().GetSession(),
MaterialInfo.nodeId, &ParmInfos[0], 0, NodeInfo.parmCount ) != HAPI_RESULT_SUCCESS )
{
return false;
}
}
// Look for the substance filename parameter on the material node
for (int32 Idx = 0, Num = ParmInfos.Num(); Idx < Num; ++Idx)
{
// Get the param name
FHoudiniEngineString HoudiniEngineString( ParmInfos[ Idx ].nameSH );
FString ParamName;
HoudiniEngineString.ToFString( ParamName );
// Check the param name
if ( !ParamName.Equals( HAPI_UNREAL_PARAM_SUBSTANCE_FILENAME ) )
continue;
// Check the param is a path parameter
if ( ParmInfos[ Idx ].type < HAPI_PARMTYPE_PATH_START || ParmInfos[ Idx ].type > HAPI_PARMTYPE_PATH_END )
continue;
// Get the substance filename parameter string value
HAPI_StringHandle StringHandle = -1;
if ( FHoudiniApi::GetParmStringValues( FHoudiniEngine::Get().GetSession(),
MaterialInfo.nodeId, false, &StringHandle, ParmInfos[ Idx ].stringValuesIndex, 1 ) != HAPI_RESULT_SUCCESS )
{
continue;
}
FHoudiniEngineString StringValue = FHoudiniEngineString( StringHandle );
if ( !StringValue.ToFString( SubstanceMaterialName ) )
continue;
// We found the substance material name
return true;
}
return false;
}
#if WITH_EDITOR
UObject *
FHoudiniEngineSubstance::LoadSubstanceInstanceFactory(
UClass * InstanceFactoryClass,
const FString & SubstanceMaterialName )
{
UObject * SubstanceInstanceFactory = nullptr;
TArray< FAssetData > SubstanceInstaceFactories;
FAssetRegistryModule & AssetRegistryModule =
FModuleManager::LoadModuleChecked< FAssetRegistryModule >( TEXT( "AssetRegistry" ) );
AssetRegistryModule.Get().GetAssetsByClass( InstanceFactoryClass->GetFName(), SubstanceInstaceFactories );
for ( int32 FactoryIdx = 0, FactoryNum = SubstanceInstaceFactories.Num(); FactoryIdx < FactoryNum; ++FactoryIdx )
{
const FAssetData & AssetData = SubstanceInstaceFactories[ FactoryIdx ];
const FString & AssetName = AssetData.AssetName.ToString();
if ( AssetName.Equals( SubstanceMaterialName ) )
{
const FString & AssetObjectPath = AssetData.ObjectPath.ToString();
SubstanceInstanceFactory = StaticLoadObject(
InstanceFactoryClass, nullptr, *AssetObjectPath, nullptr,
LOAD_None, nullptr );
if ( SubstanceInstanceFactory )
break;
}
}
return SubstanceInstanceFactory;
}
UObject *
FHoudiniEngineSubstance::LoadSubstanceGraphInstance( UClass * GraphInstanceClass, UObject * InstanceFactory )
{
UObject * MatchedSubstanceGraphInstance = nullptr;
TArray< FAssetData > SubstanceGraphInstances;
// Get Substance instance factory pointer property.
FObjectProperty * FactoryParentProperty =
CastField< FObjectProperty >( GraphInstanceClass->FindPropertyByName( HAPI_UNREAL_SUBSTANCE_PROPERTY_FACTORY_PARENT ) );
if ( !FactoryParentProperty )
return nullptr;
FAssetRegistryModule & AssetRegistryModule =
FModuleManager::LoadModuleChecked< FAssetRegistryModule >( TEXT( "AssetRegistry" ) );
AssetRegistryModule.Get().GetAssetsByClass( GraphInstanceClass->GetFName(), SubstanceGraphInstances );
for ( int32 GraphInstanceIdx = 0, GraphInstanceNum = SubstanceGraphInstances.Num();
GraphInstanceIdx < GraphInstanceNum; ++GraphInstanceIdx )
{
const FAssetData & AssetData = SubstanceGraphInstances[GraphInstanceIdx];
const FString & AssetObjectPath = AssetData.ObjectPath.ToString();
UObject * GraphInstanceObject =
StaticLoadObject( GraphInstanceClass, nullptr, *AssetObjectPath, nullptr, LOAD_None, nullptr );
if ( GraphInstanceObject )
{
void * FactoryParentPropertyValue = FactoryParentProperty->ContainerPtrToValuePtr< void >( GraphInstanceObject );
UObject * InstanceFactoryObject = FactoryParentProperty->GetObjectPropertyValue( FactoryParentPropertyValue );
if ( InstanceFactory == InstanceFactoryObject )
{
MatchedSubstanceGraphInstance = GraphInstanceObject;
break;
}
}
}
return MatchedSubstanceGraphInstance;
}
#endif
bool
FHoudiniEngineSubstance::RetrieveSubstanceRTTIClasses(
UClass *& InstanceFactoryClass,
UClass *& GraphInstanceClass,
UClass *& UtilityClass )
{
InstanceFactoryClass = nullptr;
GraphInstanceClass = nullptr;
UtilityClass = nullptr;
UClass * SubstanceInstaceFactoryClass = FindObject< UClass >(
ANY_PACKAGE, HAPI_UNREAL_SUBSTANCE_CLASS_INSTANCE_FACTORY );
if ( !SubstanceInstaceFactoryClass )
return false;
UClass * SubstanceGraphInstanceClass =
FindObject< UClass >( ANY_PACKAGE, HAPI_UNREAL_SUBSTANCE_CLASS_GRAPH_INSTANCE );
if ( !SubstanceGraphInstanceClass )
return false;
UClass * SubstanceUtilityClass = FindObject< UClass >( ANY_PACKAGE, HAPI_UNREAL_SUBSTANCE_CLASS_UTILITY );
if ( !SubstanceUtilityClass )
return false;
InstanceFactoryClass = SubstanceInstaceFactoryClass;
GraphInstanceClass = SubstanceGraphInstanceClass;
UtilityClass = SubstanceUtilityClass;
return true;
}