What's the interface function for Select from Scene in 3ds max (or selected object manually)?


#1

I dont find in the GetCoreInterface() documentation which function would retrieve the node number I have selected, I am going to try select a node from Select from scene (or manually selecting the object) and then getting the node to pass to GetCOREInterface()->GetSelNode(); with the node pointer then retrieve the bones inside the skin (Some suggestion which functions could give me each bone in the skin) ? to later pass each bone weight value into a list of float, so whats your suggestion?


#2

Get the ISkin interface from the skin modifier and get the bones from that. There is plenty of stuff showing you how in skintools.cpp in the samples


#3

I see that the iskin.h file isnt included unlike the sample project, I checked and both projects have additional includes set exactly the same is there something else I can do to include it? I might just add the include folder

Edit: it seems it works now

but I dont understand how you obtain the INode for skin and bones

if I selected the mesh would this function work? if not how can I get the INode?

void CopySkin::GetSelectedNode() {
Tab<INode*> nodes;
for (int i = 0; i < nodes.Count(); i++)
{
	if (nodes[i]->Selected)
	{
		this->node = nodes[i];
		break;
	}
}
nodes.Delete(0, nodes.Count());

}

#4

not tested, something like this will collect all bones being used by all skin modifiers in a scene shouldn’t be too difficult to target it as you see fit

Modifier* GetSkinModifier(INode *node)
{
	Object* pObj = node->GetObjectRef();
	if (!pObj) return NULL;

	while (pObj->SuperClassID() == GEN_DERIVOB_CLASS_ID)
	{
		IDerivedObject* pDerObj = (IDerivedObject *)(pObj);	
		int Idx = 0;
		while (Idx < pDerObj->NumModifiers())
		{
			Modifier* mod = pDerObj->GetModifier(Idx);
			if (mod->ClassID() == SKIN_CLASSID)
				return mod;
			Idx++;
		}
		pObj = pDerObj->GetObjRef();
	}
	return NULL;
}

void EnumerateScene(INode* currentNode, INodeTab& skinbonenodes)
{
	Modifier* mod = GetSkinModifier(currentNode);
	if(mod)
	{
		ISkin* skin = (ISkin *)mod->GetInterface(I_SKIN);
		if(skin)
		{
			int boneCount = skin->GetNumBones();
			int ct = 0;
			for (int i = 0; i < boneCount; i++)
			{
				INode *boneNode = skin->GetBone(i);
				skinbonenodes.Append(1,&boneNode);
			}
		}
	}
	for (i = 0; i < currentNode->NumberOfChildren(); i++)
		EnumerateScene(currentNode->GetChildNode(i), skinbonenodes);
)

INodeTab allskinnedbones;
EnumerateScene(GetCOREInterface()->GetRootNode(), allskinnedbones);

#5

oh I supose my code wasnt going to work

Modifier* CopySkin::GetSkinModifier()
{
	Object* pObj = meshObject->SkinNode->GetObjectRef();

	if (!pObj) return NULL;

	FindSkinOnStack pipeEnumProc;
	EnumGeomPipeline(&pipeEnumProc, pObj);
	if (pipeEnumProc.mFound)
	{
		return pipeEnumProc.mMod;
	}
	return NULL;

}
void CopySkin::GetSelectedNode() {
	Tab<INode*> nodes;
	for (int i = 0; i < nodes.Count(); i++)
	{
		if (nodes[i]->Selected)
		{
			meshObject->SkinNode = nodes[i];
			
			break;
		}
	}
	nodes.Delete(0, nodes.Count());
}

ISkinImportData* CopySkin::GetSkinImportData(Modifier* SkinModifier,Matrix3 time,INode*& skinNode,INode*& boneNode)
{

    ISkinImportData* skin = (ISkinImportData*)SkinModifier->GetInterface(I_SKINIMPORTDATA);
	
	if (skin)
	{
		if (skinNode && boneNode)
			skin->SetBoneTm(boneNode, time, time);
	}
	return skin;
}
void CopySkin::GetBonesNodes(int& numBones,ISkin*& skinInterface,Modifier*& mod,Matrix3& time)
{
	int ct = 0;
	BoneData* data = nullptr;
	INode* tempBoneNode = nullptr;
	for (int i = 0; i < numBones; i++)
	{
		tempBoneNode = skinInterface->GetBone(i);
		data = new BoneData();
		data->node = tempBoneNode;
		TSTR name;
		name.printf(_T("%s"), tempBoneNode->GetName());
		data->SetOriginalName(name);
		data->mapID = ct++;
		data->subID = -50;

		meshObject->BoneNodes.Append(i, tempBoneNode);
		meshObject->BonesData.Append(i,data);
		meshObject->SkinImportData.Append(i, GetSkinImportData(mod, time, meshObject->SkinNode, tempBoneNode));
	}
	free(tempBoneNode);
	free(data);
}
void CopySkin::CopyWeightsVertices()
{
	GetSelectedNode();
	Modifier* mod = GetSkinModifier();
	Matrix3 time(0);
	auto skinInterface = (ISkin*)meshObject->SkinNode->GetInterface(I_SKIN);
	int numBones = skinInterface->GetNumBones();
	GetBonesNodes(numBones,skinInterface,mod,time);
	


	
}