[Closed] [sdk] AttachMesh with tVerts and vertCol
hello,
I have problem with mesh attach.
I use MeshDelta for it. And the code is
Matrix3 im;
im.IdentityMatrix();
MeshDelta nmd;
nmd.AttachMesh(mesh, tempMesh, im, -1)
nmd.Apply(mesh);
mesh.InvalidateTopologyCache();
The mesh was attached with tempMesh, but data of tVerts and vertCol was gone.
So, how do I attach with map and vertex color information?
thanks
this what triops::Attach uses
MeshDelta nmd;
nmd.AttachMesh (GetMesh(), obj->GetMesh(), tm, mat2Offset);
ApplyMeshDelta (nmd, this, ip->GetTime());
and that seems to work correctly, this is the apply mesh delta function…
void EditTriObject::ApplyMeshDelta (MeshDelta & md, MeshDeltaUser *mdu, TimeValue t) {
if (AreWeKeying(t)) {
BOOL addedCont = FALSE;
for (int i=0; i<md.vMove.Count(); i++) if (PlugControl(t, md.vMove[i].vid)) addedCont = TRUE;
if (addedCont) NotifyDependents(FOREVER,0,REFMSG_SUBANIM_STRUCTURE_CHANGED);
}
MeshTopoRestore *tchange = NULL;
DWORD partsChanged = md.PartsChanged ();
if (theHold.Holding() && !TestAFlag (A_HELD)) {
if (partsChanged & (PART_TOPO|PART_TEXMAP|PART_VERTCOLOR)) {
tchange = new MeshTopoRestore (this, partsChanged);
} else {
if (partsChanged & PART_GEOM) theHold.Put (new MeshVertRestore (this));
if (partsChanged & PART_SELECT) theHold.Put (new MeshSelRestore (this));
}
}
#if defined(NEW_SOA)
GetTriObjDescriptor()->Execute(I_EXEC_EVAL_SOA_TIME, reinterpret_cast<ULONG_PTR>(&t));
#endif
for (int i=0; i<md.vMove.Count(); i++) {
DWORD j = md.vMove[i].vid;
Point3 pt = GetMesh().verts[j] + md.vMove[i].dv;
if (cont.Count() && cont[j]) cont[j]->SetValue (t, &pt);
}
int nv = md.vClone.Count();
if (nv != 0) {
SynchContArray (GetMesh().numVerts+nv);
IncreaseNamedSetSize (NS_VERTEX, GetMesh().numVerts, nv);
}
if (md.NumFCreate()) {
IncreaseNamedSetSize (NS_EDGE, GetMesh().numFaces*3, md.NumFCreate()*3);
IncreaseNamedSetSize (NS_FACE, GetMesh().numFaces, md.NumFCreate());
}
md.Apply (GetMesh());
if (md.vDelete.NumberSet()) {
DeletePointConts (md.vDelete);
NotifyDependents (FOREVER,0,REFMSG_SUBANIM_STRUCTURE_CHANGED);
DeleteNamedSetArray (NS_VERTEX, md.vDelete);
}
if (md.fDelete.NumberSet()) {
DeleteNamedSetArray (NS_EDGE, md.fDelete);
DeleteNamedSetArray (NS_FACE, md.fDelete);
}
mdu->LocalDataChanged (partsChanged);
if (tchange) {
if (tchange->After()) theHold.Put (tchange);
else delete tchange;
}
}
doesn’t seem to do anything extra to make sure mapping and vertex colors are copied
Thanks Klvnk,
But how do I reach EditTriObject class and any functions?
Do I need to implement all source of the EditableMesh from sdk sample?
thanks
I wasn’t really suggesting doing that, as that works and uses the same calls as you then it must be something else you’re doing/not doing that’s causing the issue.
also from meshop.cpp in the mxsagni project
// meshop.attach $.baseobject $sphere02 targetNode:$
// meshop.attach $box01 $box02 attachMat:#IDToMat condenseMat:true deleteSourceNode:false
Value*
meshop_attach_cf(Value** arg_list, int count)
{
// meshop.attach {<target_node> | <target_mesh>} {<source_node> | <source_mesh>}
// targetNode:<target_node> sourceNode:<source_node>
// attachMat:{#neither | #MatToID | #IDToMat = #neither} condenseMat:<boolean = true>
// deleteSourceNode:<boolean = true>
//
check_arg_count_with_keys(attach, 2, count);
ReferenceTarget *owner;
INode *node1, *node2;
Value *tmp;
bool sourceInLocalCoords = true;
Mesh* targetMesh = get_meshForValue(arg_list[0], MESH_BASE_OBJ, &owner, attach);
if (arg_list[0]->is_kind_of(class_tag(MAXNode)))
node1 = arg_list[0]->to_node();
else
node1 = node_key_arg(targetNode, tmp, NULL);
Mesh* sourceMesh = get_worldMeshForValue(arg_list[1], attach, false);
if (arg_list[1]->is_kind_of(class_tag(MAXNode))) {
sourceInLocalCoords = false;
node2 = arg_list[1]->to_node();
}
else
node2 = node_key_arg(sourceNode, tmp, NULL);
bool bothAreNodes = node1 && node2;
def_mtl_attach_types();
int attachMat = GetID(mtlAttachTypes, elements(mtlAttachTypes), key_arg_or_default(attachMat, n_neither));
BOOL condenseMat = bool_key_arg(condenseMat, tmp, TRUE);
BOOL deleteSourceNode = bool_key_arg(deleteSourceNode, tmp, TRUE);
MeshDeltaUser *mdu = (owner) ? GetMeshDeltaUserInterface(owner) : NULL;
if (mdu && mdu->Editing()) mdu->ExitCommandModes();
// Combine the materials of the two nodes.
int mat2Offset=0;
Mtl *m1 = node1 ? node1->GetMtl() : NULL;
Mtl *m2 = node2 ? node2->GetMtl() : NULL;
bool condenseMe = true;
bool canUndo = true;
if (bothAreNodes && m1 && m2 && (m1 != m2)) {
if (attachMat == ATTACHMAT_IDTOMAT) {
FitMeshIDsToMaterial (*targetMesh, m1);
FitMeshIDsToMaterial (*sourceMesh, m2);
if (condenseMat) condenseMe = true;
}
// the theHold calls here were a vain attempt to make this all undoable.
// This should be revisited in the future so we don't have to use the SYSSET_CLEAR_UNDO.
HoldSuspend theHoldSuspender (TRUE);
if (attachMat == ATTACHMAT_MATTOID) {
m1 = FitMaterialToMeshIDs (*targetMesh, m1);
m2 = FitMaterialToMeshIDs (*sourceMesh, m2);
}
Mtl *multi = CombineMaterials(m1, m2, mat2Offset);
theHoldSuspender.Resume();
canUndo = false; // Absolutely cannot undo material combinations.
if (attachMat == ATTACHMAT_NEITHER) mat2Offset = 0;
// We can't be in face subobject mode, else we screw up the materials:
if (mdu) {
DWORD oldSL = mdu->GetEMeshSelLevel();
if (oldSL>EM_SL_EDGE) mdu->SetEMeshSelLevel(EM_SL_OBJECT);
node1->SetMtl(multi);
if (oldSL>EM_SL_EDGE) mdu->SetEMeshSelLevel(oldSL);
}
else
node1->SetMtl(multi);
m1 = multi;
}
if (bothAreNodes && !m1 && m2) {
// This material operation seems safe.
// We can't be in face subobject mode, else we screw up the materials:
if (mdu) {
DWORD oldSL = mdu->GetEMeshSelLevel();
if (oldSL>EM_SL_EDGE) mdu->SetEMeshSelLevel(EM_SL_OBJECT);
node1->SetMtl(m2);
if (oldSL>EM_SL_EDGE) mdu->SetEMeshSelLevel(oldSL);
}
else
node1->SetMtl(m2);
m1 = m2;
}
// Construct a transformation that takes a vertex out of the space of
// the source node and puts it into the space of the destination node.
// mesh of source is in world space coordinates
Matrix3 node1tm = node1 ? node1->GetObjectTM(MAXScript_time()) : Matrix3(TRUE);
Matrix3 node2tm = (sourceInLocalCoords && node2) ? node2->GetObjectTM(MAXScript_time()) : Matrix3(TRUE);
Matrix3 tm = node2tm * Inverse(node1tm);
MeshDelta tmd;
tmd.AttachMesh (*targetMesh, *sourceMesh, tm, mat2Offset);
if (mdu)
GetMeshDeltaUserDataInterface(owner)->ApplyMeshDelta (tmd, mdu, MAXScript_time());
else {
tmd.Apply (*targetMesh);
// DWORD partsChanged = tmd.PartsChanged ();
// if (partsChanged & PART_TOPO) targetMesh->InvalidateTopologyCache();
// else if (partsChanged & PART_GEOM) targetMesh->InvalidateGeomCache ();
}
if (deleteSourceNode && node2) MAXScript_interface->DeleteNode (node2, FALSE);
if (m1 && condenseMe) {
// Following clears undo stack.
m1 = CondenseMatAssignments (*targetMesh, m1);
}
if (!canUndo) {
theHold.Release();
HoldSuspend hs (theHold.Holding()); // LAM - 6/13/02 - defect 306957
MAXScript_interface->FlushUndoBuffer();
}
needs_redraw_set();
return &ok;
}
again it’s not doing anything special to handle mapping and vertex colours