Skip to content

Commit 6cb01bb

Browse files
committed
Houdini Engine for 3ds Max:
Added support for multi selection inputs, which besides the main functionality also includes support for: * Persistence to scene files, loading from scene files * Modifier and Geometry support * Cloning, Copying, Reloading support
1 parent a62f4a4 commit 6cb01bb

16 files changed

+952
-1093
lines changed

src/HEMAX_3dsmaxHda.cpp

Lines changed: 96 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,10 @@ HEMAX_3dsmaxHda::UpdateParameterInputNode(HAPI_ParmId ParamId)
8383
HEMAX_InputInstance* ParameterInput = FindParameterInput(ParamId);
8484
HEMAX_Parameter* Parameter = Hda.MainNode.GetParameter(ParamId);
8585

86-
if (ParameterInput)
86+
if (ParameterInput && ParameterInput->MergeNode)
8787
{
88-
InputNode = ParameterInput->MaxInput->GetInputNode();
89-
90-
if (ParameterInput->MergeNode)
91-
{
92-
Parameter->UpdateInputNode(ParameterInput->MergeNode->GetMergedInputs().Info.id);
93-
}
88+
Parameter->UpdateInputNode(
89+
ParameterInput->MergeNode->GetMergedInputs().Info.id);
9490
}
9591
}
9692

@@ -135,7 +131,6 @@ HEMAX_3dsmaxHda::UpdateSubnetworkInput(int Subnetwork)
135131
{
136132
if (SubnetworkNodeInputs[Subnetwork]->MergeNode)
137133
{
138-
InputNode = SubnetworkNodeInputs[Subnetwork]->MaxInput->GetInputNode();
139134
HEMAX_Node HapiInputNode = SubnetworkNodeInputs[Subnetwork]->MergeNode->GetMergedInputs();
140135
Hda.MainNode.ConnectInputNode(HapiInputNode.Info.id, Subnetwork);
141136
}
@@ -323,7 +318,8 @@ HEMAX_3dsmaxHda::InitializeParameterCustomAttributes()
323318
} break;
324319
case (HAPI_PARMTYPE_NODE):
325320
{
326-
HEMAX_NodeParameterAttrib* ParamCustAttrib = new HEMAX_NodeParameterAttrib;
321+
HEMAX_NodeListParameterAttrib* ParamCustAttrib =
322+
new HEMAX_NodeListParameterAttrib;
327323
ParamCustAttrib->SetParameterName(Parameter->GetName());
328324
CustAttribContainer->AppendCustAttrib(ParamCustAttrib);
329325
CustAttribMap->insert({ Parameter->GetName(), ParamCustAttrib });
@@ -355,7 +351,13 @@ HEMAX_3dsmaxHda::UpdateAllCustomAttributes()
355351
if (InputIter->second)
356352
{
357353
HEMAX_Parameter* TheParameter = Hda.MainNode.GetParameter(InputIter->first);
358-
UpdateInputNodeCustomAttribute(*TheParameter, InputIter->second->MaxInput->GetInputNode());
354+
INodeTab InputNodes;
355+
for (auto&& Input : InputIter->second->MaxInputs)
356+
{
357+
InputNodes.AppendNode(GetCOREInterface()->GetINodeByHandle(
358+
Input->Get3dsMaxNodeHandle()));
359+
}
360+
UpdateInputNodeCustomAttribute(*TheParameter, InputNodes);
359361
}
360362
}
361363

@@ -559,84 +561,95 @@ HEMAX_3dsmaxHda::UpdateToggleCustomAttribute(HEMAX_Parameter& Parameter, std::ve
559561
}
560562

561563
void
562-
HEMAX_3dsmaxHda::UpdateInputNodeCustomAttribute(HEMAX_Parameter& Parameter, HEMAX_Input* InputNode)
564+
HEMAX_3dsmaxHda::UpdateInputNodeCustomAttribute(
565+
HEMAX_Parameter& Parameter,
566+
const INodeTab& InputNodes)
563567
{
564-
std::unordered_map<std::string, HEMAX_ParameterAttrib*>* CustomAttributeMap = GetCustAttribMap();
565-
std::string ParameterName = Parameter.GetName();
566-
auto Search = CustomAttributeMap->find(ParameterName);
568+
std::unordered_map<std::string, HEMAX_ParameterAttrib*>* CustAttribMap =
569+
GetCustAttribMap();
570+
std::string ParmName = Parameter.GetName();
571+
572+
auto Search = CustAttribMap->find(ParmName);
567573

568-
if (Search != CustomAttributeMap->end())
574+
if (Search == CustAttribMap->end())
575+
return;
576+
577+
HEMAX_NodeListParameterAttrib* Attrib =
578+
dynamic_cast<HEMAX_NodeListParameterAttrib*>(Search->second);
579+
580+
if (!Attrib)
581+
return;
582+
583+
Attrib->SetMessagesBlocked(true);
584+
Attrib->PBlock->ZeroCount(0);
585+
586+
for (int i = 0; i < InputNodes.Count(); ++i)
569587
{
570-
if (InputNode)
571-
{
572-
INode* MaxInputNode = GetCOREInterface()->GetINodeByHandle(InputNode->GetMaxNodeHandle());
573-
HEMAX_NodeParameterAttrib* NodeParameterAttribute = (HEMAX_NodeParameterAttrib*)Search->second;
574-
NodeParameterAttribute->SetMessagesBlocked(true);
575-
NodeParameterAttribute->PBlock->SetValue(0, GetCOREInterface()->GetTime(), MaxInputNode);
576-
NodeParameterAttribute->SetMessagesBlocked(false);
577-
}
578-
else
579-
{
580-
INode* NullNode = nullptr;
581-
HEMAX_NodeParameterAttrib* NodeParameterAttribute = (HEMAX_NodeParameterAttrib*)Search->second;
582-
NodeParameterAttribute->SetMessagesBlocked(true);
583-
NodeParameterAttribute->PBlock->SetValue(0, GetCOREInterface()->GetTime(), NullNode);
584-
NodeParameterAttribute->SetMessagesBlocked(false);
585-
}
588+
Attrib->PBlock->Append(0, 1, &InputNodes[i]);
586589
}
590+
591+
Attrib->SetMessagesBlocked(false);
587592
}
588593

589594
void
590-
HEMAX_3dsmaxHda::UpdateSubnetworkCustomAttribute(int Subnetwork, HEMAX_Input* InputNode)
595+
HEMAX_3dsmaxHda::UpdateSubnetworkCustomAttribute(
596+
int Subnetwork,
597+
const INodeTab& InputNodes)
591598
{
592-
std::unordered_map<std::string, HEMAX_ParameterAttrib*>* CustomAttributeMap = GetCustAttribMap();
599+
std::unordered_map<std::string, HEMAX_ParameterAttrib*>* CustAttribMap =
600+
GetCustAttribMap();
593601
std::string SubnetworkName = "subnetwork_" + std::to_string(Subnetwork);
594-
auto Search = CustomAttributeMap->find(SubnetworkName);
602+
auto Search = CustAttribMap->find(SubnetworkName);
603+
604+
if (Search == CustAttribMap->end())
605+
return;
595606

596-
if (Search != CustomAttributeMap->end())
607+
HEMAX_NodeListParameterAttrib* Attrib =
608+
dynamic_cast<HEMAX_NodeListParameterAttrib*>(Search->second);
609+
610+
if (!Attrib)
611+
return;
612+
613+
Attrib->SetMessagesBlocked(true);
614+
Attrib->PBlock->ZeroCount(0);
615+
616+
for (int i = 0; i < InputNodes.Count(); ++i)
597617
{
598-
if (InputNode)
599-
{
600-
INode* MaxInputNode = GetCOREInterface()->GetINodeByHandle(InputNode->GetMaxNodeHandle());
601-
HEMAX_NodeParameterAttrib* NodeParameterAttribute = (HEMAX_NodeParameterAttrib*)Search->second;
602-
NodeParameterAttribute->SetMessagesBlocked(true);
603-
NodeParameterAttribute->PBlock->SetValue(0, GetCOREInterface()->GetTime(), MaxInputNode);
604-
NodeParameterAttribute->SetMessagesBlocked(false);
605-
}
606-
else
607-
{
608-
INode* NullNode = nullptr;
609-
HEMAX_NodeParameterAttrib* NodeParameterAttribute = (HEMAX_NodeParameterAttrib*)Search->second;
610-
NodeParameterAttribute->SetMessagesBlocked(true);
611-
NodeParameterAttribute->PBlock->SetValue(0, GetCOREInterface()->GetTime(), NullNode);
612-
NodeParameterAttribute->SetMessagesBlocked(false);
613-
}
618+
Attrib->PBlock->Append(0, 1, &InputNodes[i]);
614619
}
620+
621+
Attrib->SetMessagesBlocked(false);
615622
}
616623

617624
std::vector<HEMAX_SubnetworkInputMapping>
618625
HEMAX_3dsmaxHda::ReloadSubnetworkInputsFromCustomAttributes()
619626
{
620-
ICustAttribContainer* CustAttribContainer = GetCustAttribContainer();
621-
std::unordered_map<std::string, HEMAX_ParameterAttrib*>* CustomAttributeMap = GetCustAttribMap();
622-
623627
std::vector<HEMAX_SubnetworkInputMapping> Mapping;
624628

629+
std::unordered_map<std::string, HEMAX_ParameterAttrib*>* CustAttribMap =
630+
GetCustAttribMap();
631+
625632
for (int z = 0; z < Hda.MainNode.Info.inputCount; z++)
626633
{
627-
std::string SubnetworkSearch = "subnetwork_" + std::to_string(z);
628-
auto Search = CustomAttributeMap->find(SubnetworkSearch);
634+
HEMAX_SubnetworkInputMapping Entry;
635+
Entry.Subnetwork = z;
629636

630-
if (Search != CustomAttributeMap->end())
631-
{
632-
INode* InputNode = Search->second->PBlock->GetINode(0);
637+
std::string SubnetworkSearch = "subnetwork_" + std::to_string(z);
638+
auto Search = CustAttribMap->find(SubnetworkSearch);
633639

634-
HEMAX_SubnetworkInputMapping Entry;
635-
Entry.Subnetwork = z;
636-
Entry.Node = InputNode;
640+
if (Search != CustAttribMap->end())
641+
{
642+
for (int i = 0; i < Search->second->PBlock->Count(0); ++i)
643+
{
644+
INode* Node = nullptr;
645+
Interval ValidityInterval;
646+
Search->second->PBlock->GetValue(0, 0, Node,
647+
ValidityInterval, i);
648+
Entry.Nodes.push_back(Node);
649+
}
650+
}
637651

638-
Mapping.push_back(Entry);
639-
}
652+
Mapping.push_back(Entry);
640653
}
641654

642655
return Mapping;
@@ -646,7 +659,8 @@ std::vector<HEMAX_ParameterInputMapping>
646659
HEMAX_3dsmaxHda::ReloadParametersFromCustomAttributes()
647660
{
648661
std::vector<HEMAX_ParameterInputMapping> InputMap;
649-
std::unordered_map<std::string, HEMAX_ParameterAttrib*>* CustomAttributeMap = GetCustAttribMap();
662+
std::unordered_map<std::string, HEMAX_ParameterAttrib*>*
663+
CustomAttributeMap = GetCustAttribMap();
650664

651665
bool AnotherPassRequired = false;
652666
std::unordered_map<std::string, bool> CompletionMap;
@@ -698,8 +712,9 @@ HEMAX_3dsmaxHda::ReloadParametersFromCustomAttributes()
698712
}
699713
case (HAPI_PARMTYPE_NODE):
700714
{
701-
HEMAX_ParameterInputMapping InputEntry = RemakeInputParameterFromCustAttrib(Parameter, *CustomAttributeMap);
702-
if (InputEntry.Node)
715+
HEMAX_ParameterInputMapping InputEntry =
716+
RemakeInputParameterFromCustAttrib(Parameter, *CustomAttributeMap);
717+
if (InputEntry.Nodes.size() > 0)
703718
{
704719
InputMap.push_back(InputEntry);
705720
}
@@ -894,22 +909,27 @@ HEMAX_3dsmaxHda::RemakeToggleParameterFromCustAttrib(HEMAX_Parameter Parameter,
894909
}
895910

896911
HEMAX_ParameterInputMapping
897-
HEMAX_3dsmaxHda::RemakeInputParameterFromCustAttrib(HEMAX_Parameter Parameter, std::unordered_map<std::string, HEMAX_ParameterAttrib*>& CustomAttributeMap)
912+
HEMAX_3dsmaxHda::RemakeInputParameterFromCustAttrib(HEMAX_Parameter Parameter,
913+
std::unordered_map<std::string,
914+
HEMAX_ParameterAttrib*>& CustomAttributeMap)
898915
{
899916
HEMAX_ParameterInputMapping Entry;
900-
Entry.Node = nullptr;
901-
Entry.ParameterName = "";
902917

903918
std::string ParameterName = Parameter.GetName();
904919
auto Search = CustomAttributeMap.find(ParameterName);
905920

906-
if (Search != CustomAttributeMap.end())
907-
{
908-
INode* InputNode = Search->second->PBlock->GetINode(0);
921+
if (Search == CustomAttributeMap.end())
922+
return Entry;
909923

910-
Entry.Node = InputNode;
911-
Entry.ParameterName = ParameterName;
912-
}
924+
Entry.ParameterName = ParameterName;
925+
926+
for (int i = 0; i < Search->second->PBlock->Count(0); ++i)
927+
{
928+
INode* Node = nullptr;
929+
Interval ValidityInterval;
930+
Search->second->PBlock->GetValue(0, 0, Node, ValidityInterval, i);
931+
Entry.Nodes.push_back(Node);
932+
}
913933

914934
return Entry;
915935
}
@@ -1027,15 +1047,3 @@ HEMAX_3dsmaxHda::SetCustomAttributeContainer(ICustAttribContainer* Container)
10271047
{
10281048
CustomAttributes = Container;
10291049
}
1030-
1031-
ICustAttribContainer*
1032-
HEMAX_3dsmaxHda::GetCustAttribContainer()
1033-
{
1034-
return CustomAttributes;
1035-
}
1036-
1037-
std::unordered_map<std::string, HEMAX_ParameterAttrib*>*
1038-
HEMAX_3dsmaxHda::GetCustAttribMap()
1039-
{
1040-
return &CustomAttributeMap;
1041-
}

src/HEMAX_3dsmaxHda.h

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,18 @@
1111
#pragma warning(pop)
1212

1313
#include <unordered_map>
14+
#include <vector>
1415

1516
struct HEMAX_SubnetworkInputMapping
1617
{
1718
int Subnetwork;
18-
INode* Node;
19+
std::vector<INode*> Nodes;
1920
};
2021

2122
struct HEMAX_ParameterInputMapping
2223
{
23-
std::string ParameterName;
24-
INode* Node;
24+
std::string ParameterName = "";
25+
std::vector<INode*> Nodes;
2526
};
2627

2728
class HEMAX_3dsmaxHda
@@ -54,21 +55,26 @@ class HEMAX_3dsmaxHda
5455
void UpdateAllCustomAttributes();
5556
void ClearParameterCustomAttributes();
5657

57-
void UpdateIntCustomAttribute(HEMAX_Parameter& Parameter, std::vector<int>& IntValues);
58-
59-
void UpdateFloatCustomAttribute(HEMAX_Parameter& Parameter, std::vector<float>& FloatValues);
60-
61-
void UpdateStringCustomAttribute(HEMAX_Parameter& Parameter, std::vector<std::string>& StringValues);
62-
63-
void UpdateToggleCustomAttribute(HEMAX_Parameter& Parameter, std::vector<int>& ToggleValues);
64-
65-
void UpdateInputNodeCustomAttribute(HEMAX_Parameter& Parameter, HEMAX_Input* InputNode);
66-
67-
void UpdateSubnetworkCustomAttribute(int Subnetwork, HEMAX_Input* InputNode);
68-
69-
std::vector<HEMAX_SubnetworkInputMapping> ReloadSubnetworkInputsFromCustomAttributes();
70-
71-
std::vector<HEMAX_ParameterInputMapping> ReloadParametersFromCustomAttributes();
58+
void UpdateIntCustomAttribute(
59+
HEMAX_Parameter& Parameter, std::vector<int>& IntValues);
60+
void UpdateFloatCustomAttribute(
61+
HEMAX_Parameter& Parameter, std::vector<float>& FloatValues);
62+
void UpdateStringCustomAttribute(
63+
HEMAX_Parameter& Parameter,
64+
std::vector<std::string>& StringValues);
65+
void UpdateToggleCustomAttribute(
66+
HEMAX_Parameter& Parameter, std::vector<int>& ToggleValues);
67+
void UpdateInputNodeCustomAttribute(
68+
HEMAX_Parameter& Parameter,
69+
const INodeTab& InputNodes);
70+
void UpdateSubnetworkCustomAttribute(
71+
int Subnetwork,
72+
const INodeTab& InputNodes);
73+
74+
std::vector<HEMAX_SubnetworkInputMapping>
75+
ReloadSubnetworkInputsFromCustomAttributes();
76+
std::vector<HEMAX_ParameterInputMapping>
77+
ReloadParametersFromCustomAttributes();
7278

7379
std::string GetHardcodedHdaAssetPath();
7480

@@ -88,21 +94,36 @@ class HEMAX_3dsmaxHda
8894

8995
void InitializeSubnetworks();
9096

91-
void RemakeIntParameterFromCustAttrib(HEMAX_Parameter Parameter, std::unordered_map<std::string, HEMAX_ParameterAttrib*>& CustomAttributeMap);
92-
93-
void RemakeStringParameterFromCustAttrib(HEMAX_Parameter Parameter, std::unordered_map<std::string, HEMAX_ParameterAttrib*>& CustomAttributeMap);
94-
95-
void RemakeFloatParameterFromCustAttrib(HEMAX_Parameter Parameter, std::unordered_map<std::string, HEMAX_ParameterAttrib*>& CustomAttributeMap);
96-
97-
void RemakeToggleParameterFromCustAttrib(HEMAX_Parameter Parameter, std::unordered_map<std::string, HEMAX_ParameterAttrib*>& CustomAttributeMap);
98-
99-
HEMAX_ParameterInputMapping RemakeInputParameterFromCustAttrib(HEMAX_Parameter Parameter, std::unordered_map<std::string, HEMAX_ParameterAttrib*>& CustomAttributeMap);
100-
101-
void RemakeMultiParameter(HEMAX_Parameter Parameter, std::unordered_map<std::string, HEMAX_ParameterAttrib*>& CustomAttributeMap);
102-
103-
ICustAttribContainer* GetCustAttribContainer();
104-
105-
std::unordered_map<std::string, HEMAX_ParameterAttrib*>* GetCustAttribMap();
97+
void RemakeIntParameterFromCustAttrib(
98+
HEMAX_Parameter Parameter,
99+
std::unordered_map<
100+
std::string, HEMAX_ParameterAttrib*>& CustomAttributeMap);
101+
void RemakeStringParameterFromCustAttrib(
102+
HEMAX_Parameter Parameter,
103+
std::unordered_map<
104+
std::string, HEMAX_ParameterAttrib*>& CustomAttributeMap);
105+
void RemakeFloatParameterFromCustAttrib(
106+
HEMAX_Parameter Parameter,
107+
std::unordered_map<
108+
std::string, HEMAX_ParameterAttrib*>& CustomAttributeMap);
109+
void RemakeToggleParameterFromCustAttrib(
110+
HEMAX_Parameter Parameter,
111+
std::unordered_map<
112+
std::string, HEMAX_ParameterAttrib*>& CustomAttributeMap);
113+
HEMAX_ParameterInputMapping RemakeInputParameterFromCustAttrib(
114+
HEMAX_Parameter Parameter,
115+
std::unordered_map<
116+
std::string, HEMAX_ParameterAttrib*>& CustomAttributeMap);
117+
void RemakeMultiParameter(
118+
HEMAX_Parameter Parameter,
119+
std::unordered_map<
120+
std::string, HEMAX_ParameterAttrib*>& CustomAttributeMap);
121+
122+
ICustAttribContainer* GetCustAttribContainer()
123+
{ return CustomAttributes; }
124+
125+
std::unordered_map<std::string, HEMAX_ParameterAttrib*>*
126+
GetCustAttribMap() { return &CustomAttributeMap; }
106127

107128
ICustAttribContainer* CustomAttributes;
108129
std::unordered_map<std::string, HEMAX_ParameterAttrib*> CustomAttributeMap;

0 commit comments

Comments
 (0)