Announcements

Between mid-October and November, the content on AREA will be relocated to the Autodesk Community M&E Hub and the Autodesk Community Gallery. Learn more HERE.

Accessing the Skin modifier and removing vertex weights

Accessing the Skin modifier and removing vertex weights

Anonymous
Not applicable
493 Views
0 Replies
Message 1 of 1

Accessing the Skin modifier and removing vertex weights

Anonymous
Not applicable
Hey folks,

my question is this, I've written a little utility that allows me to view the associated vertex weights on a mesh (see included code). The problem is, I can't see any way to change vertex weights or actually remove a weight. for instance, a vertex has one too many weights assoicated with it and I'd like to drop the one with the least influence and then re-normalize. Am I missing something here? Neither ISkin nor ISkinContextData provide interfaces for doing this. And I'd rather not use maxscript for this.


// Maxscript function for checking the vertex weights on a given skin
// arg_list: expecting the iNode of the mesh to check as well as the skin modifier to use
// returns: success or failure
// Example: CheckVertexWeights $ $.modifiers maxWeightPerVertexCount
// CheckVertexWeights $ $.modifiers 2
Value* CheckVertexWeights_cf(Value** arg_list, int count)
{
check_arg_count(CheckVertexWeights, 3, count)
type_check( arg_list, MAXNode, "CheckVertexWeights ")
type_check( arg_list, MAXModifier, "CheckVertexWeights ")
type_check( arg_list, Integer, "CheckVertexWeights ")

Interface *ip = GetCOREInterface()

// Get the mesh for the first parameter
INode* skinObj = (INode*)arg_list->to_node()
if ( skinObj == NULL )
{
mprintf("Alert: unable to convert the first parameter to a INode!\n" )
return NULL;
}

// convert the second parameter to an ISkin interface
Modifier* baseMod = arg_list->to_modifier()
if ( baseMod == NULL )
{
mprintf("Alert: unable to convert the second parameter to a Modifier!\n" )
return NULL;
}

// convert the third parameter to a number
int maximumWeightCount = arg_list->to_int()

// populate the data that we'll be using
ISkin* skinMod = (ISkin*)baseMod->GetInterface(I_SKIN)

if ( skinMod == NULL )
{
mprintf("Alert: unable to convert the second parameter to a Skin Modifier!\n" )
return NULL;
}

ISkinContextData* skinData = skinMod->GetContextInterface(skinObj)

if ( skinData == NULL )
{
mprintf("Alert: unable to access the skin data!\n" )
return NULL;
}

Tab<BoneData*> boneList;

// First off, generate an list to hold our 'bones'
int boneCount = skinMod->GetNumBones&#40;&#41;
int mapIDCounter = 0;
for &#40; int index = 0; index < boneCount; ++index &#41;
{
INode* node = skinMod->GetBone&#40;index&#41;

BoneData* data = new BoneData&#40;&#41;
data->node = node;

TSTR name;
name.printf&#40; "%s", node->GetName&#40;&#41; &#41;
data->SetOriginalName&#40; name &#41;
mprintf&#40; "%s,", name.data&#40;&#41; &#41;

data->mapID = mapIDCounter++;
data->subID = -50;

boneList.Append&#40; 1, &data &#41;
}
mprintf&#40;"\n"&#41;

// Next look at all the vertices this skin modifier
int numberofPoints = skinData->GetNumPoints&#40;&#41;
for &#40; int vertexIndex =0; vertexIndex < numberofPoints; ++vertexIndex &#41;
{
int numberofWeights = skinData->GetNumAssignedBones&#40;vertexIndex&#41;

if &#40; numberofWeights >= maximumWeightCount &#41;
{
mprintf&#40;"%d vertex has too many weights assigned to it!\n", vertexIndex &#41;

Tab<VertexWeightData*> vertexWeightTable;
//mprintf&#40;"Vertex Data&colon; vertexIndex: %d, number of Weights: %d \n", vertexIndex, numberofWeights&#41;
for &#40; int weightIndex = 0; weightIndex < numberofWeights; ++weightIndex &#41;
{
int boneIndex = skinData->GetAssignedBone&#40;vertexIndex, weightIndex&#41;
float boneWeight = skinData->GetBoneWeight&#40;vertexIndex, weightIndex&#41;
//mprintf&#40;"\t\tweightIndex: %d bone: %d, weight: %f\n", weightIndex, boneIndex, boneWeight&#41;

VertexWeightData* weightData = new VertexWeightData&#40;&#41;

weightData->boneIndex = boneIndex;
weightData->vertexIndex = vertexIndex;
weightData->weight = boneWeight;

if &#40; vertexWeightTable.Count&#40;&#41; == 0 &#41;
{
vertexWeightTable.Append&#40;1, &weightData&#41;
}
else
{
int location = 0;
for &#40; ; location < vertexWeightTable.Count&#40;&#41; ++location&#41;
{
if &#40; vertexWeightTable->weight < weightData->weight&#41;
{
vertexWeightTable.Insert&#40;location, 1, &weightData &#41;
break;
}
}

if &#40; location >= vertexWeightTable.Count&#40;&#41; &#41;
{
vertexWeightTable.Append&#40;1, &weightData&#41;
}
}
}

// print out the weight table
mprintf&#40;"Vertex Weights for pruning\n"&#41;
for &#40;int index = maximumWeightCount; index < vertexWeightTable.Count&#40;&#41; ++index&#41;
{
mprintf&#40;"\tbone: index Weight: %f\n", boneList->boneIndex]->GetDisplayName&#40;&#41;, vertexWeightTable->boneIndex, vertexWeightTable->weight&#41;
INode* boneNode = skinMod->GetBone&#40;vertexWeightTable->boneIndex&#41;
Object *obj = boneNode->GetObjectRef&#40;&#41;
Class_ID id = obj->ClassID&#40;&#41;
if &#40; id == BONE_OBJ_CLASSID &#41;
{
if &#40; boneNode == NULL &#41;
{
mprintf&#40;"Can't find bone!\n"&#41;
}
}
}

// Re-normalize what's left
}

}

return NULL;
}

0 Likes
494 Views
0 Replies
Replies (0)