Notifications
Clear all

[Closed] SDK Attaching PolyObjects

Hi, I have been trying to get a Poly Attach code going, but the samples are a bit weird as it starts to use their own classes. I have taken what I believe I needed, but the second Object isn’t showing up. Any idea whats missing ??

void PolyTools::PolyAttach(){
 	ip = GetCOREInterface();
 	t = ip->GetTime();
 	int attachMat = ATTACHMAT_IDTOMAT;
 	INodeTab nodeTab;
 	Object *Obj;
 	for (auto i = 0; i < ip->GetSelNodeCount(); i++){
 		Obj = ip->GetSelNode(i)->EvalWorldState(TimeValue(0)).obj;
 		if(Obj->SuperClassID() == GEOMOBJECT_CLASS_ID){
 	
 		nodeTab.AppendNode(ip->GetSelNode(i));
 		CollapseStack(nodeTab[i]);
 		}
 
 		Obj = NULL;
 	}
 		
 	if(nodeTab.Count() != 0){
 		PolyObject* firstobj = PolyObjectFromNode(nodeTab[0], t);
 		if(firstobj == NULL)return;
 		nodeTab[0]->SetObjectRef(firstobj);
 		nodeTab[0]->SetNodeTM(ip->GetTime(),nodeTab[0]->GetNodeTM(TimeValue(0)));
 		nodeTab[0]->SetMtl(nodeTab[0]->GetMtl());
 		MNMesh mm = firstobj->GetMesh();
 		for (int i=1; i<nodeTab.Count(); i++) {
 			INode *node = nodeTab[i];
 			PolyObject* Newobj = PolyObjectFromNode(node, t);
 			if(Newobj == NULL)return;
 			node->SetObjectRef(Newobj);
 			node->SetNodeTM(ip->GetTime(),node->GetNodeTM(TimeValue(0)));
 			node->SetMtl(node->GetMtl());
 			MNMesh Objmm = Newobj->GetMesh();
 
 			int mat2Offset=0;
 			
 			Mtl *m1 = nodeTab[0]->GetMtl();
 			Mtl *m2 = node->GetMtl();
 					
 			if (m1 && m2 && (m1 != m2)) {
 			if (attachMat==ATTACHMAT_IDTOMAT) {
 				FitPolyMeshIDsToMaterial (mm, m1);
 				FitPolyMeshIDsToMaterial (Objmm, m2);}
 			}
 			if (!m1 && m2) {
 	
 			// This material operation seems safe.
 			// We can't be in face subobject mode, else we screw up the materials:
 			DWORD oldSL = selLevel;
 			if (oldSL>SL_EDGE) selLevel = SL_OBJECT;
 			nodeTab[0]->SetMtl (m2);
 			if (oldSL>SL_EDGE) selLevel = oldSL;
 			m1 = m2;
 			}
 			else if(!m2 && m1){
 
 			// This material operation seems safe.
 			// We can't be in face subobject mode, else we screw up the materials:
 			DWORD oldSL = selLevel;
 			if (oldSL>SL_EDGE) selLevel = SL_OBJECT;
 			node->SetMtl (m1);
 			if (oldSL>SL_EDGE) selLevel = oldSL;
 			m2 = m1;
 			}
 
 			if(m1 && m2){
 		
 			Mtl *multi = CombineMaterials(m1, m2, mat2Offset);
 
 			DWORD oldSL = selLevel;
 			if (oldSL>SL_EDGE) selLevel = SL_OBJECT;
 			nodeTab[0]->SetMtl(multi);
 			if (oldSL>SL_EDGE) selLevel = oldSL;
 			m1 = multi;
 
 			}
 	
 			Matrix3 relativeTransform = node->GetObjectTM(ip->GetTime()) *
 			Inverse(nodeTab[0]->GetObjectTM(ip->GetTime()));
 
 			int ovnum = mm.numv;
 			int oenum = mm.nume;
 			int ofnum = mm.numf;
 			mm += Objmm;
 
 			for (int i=ovnum; i<mm.numv; i++) mm.v[i].p = relativeTransform * mm.v[i].p;
 			if (relativeTransform.Parity()) {
 				mm.ClearFFlags (MN_USER);	// Luna task 748Z: code cleanup - don't use WHATEVER.
 				for (int i=ofnum; i<mm.numf; i++) {
 					if (!mm.f[i].GetFlag (MN_DEAD)) mm.f[i].SetFlag (MN_USER);
 				}
 				mm.FlipElementNormals (MN_USER);
 			}
 			if (mat2Offset) {
 				for (int i=ofnum; i<mm.numf; i++) mm.f[i].material += mat2Offset;
 			}
 
 			ip->DeleteNode(node);
 
 		}
 		ip->FlushUndoBuffer();
 		ip->RedrawViews(ip->GetTime());
 	}
 }

For the most part, most of it looks the same as the TriObject Attach, so I know I’m not far off, but must be missing something. Thanks

3 Replies

there is an example code in sdk. also it might be easier to use EPoly::EpfnAttach in your case

Ok, I have got it working and it works even better than I thought it would although, it is super slow. Trying to attach 750 Objects takes about 1 minute … Any ways I can speed this up ?? I have tried the MultiAttach as well but its just as slow …
Code is below :

ip = GetCOREInterface();
  	t = ip->GetTime();
  	INodeTab nodeTab;
  	Object *Obj;
  	for (auto i = 0; i < ip->GetSelNodeCount(); i++){
  		Obj = ip->GetSelNode(i)->EvalWorldState(TimeValue(0)).obj;
  		if(Obj->SuperClassID() == GEOMOBJECT_CLASS_ID){
  			nodeTab.AppendNode(ip->GetSelNode(i));
  			CollapseStack(nodeTab[i]);
  		}
  
  		Obj = NULL;
  	}
  
  	int j = 0;
  	while (nodeTab.Count() > 1){
  		PolyObject* firstobj = PolyObjectFromNode(nodeTab[j], t);
  		nodeTab[j]->SetObjectRef(firstobj);
  		EPoly *cd= (EPoly *)(firstobj->GetInterface(EPOLY_INTERFACE));
  		bool canUndo = FALSE;
  		cd->EpfnAttach(nodeTab[j+1], canUndo, nodeTab[j], t);
  		nodeTab.Delete(j+1, 1);
  		j++;
  		if(j+1 > nodeTab.Count()-1){ j = 0;}
  	}
  	ip->FlushUndoBuffer();
  	ip->RedrawViews(ip->GetTime());

search this forum for “fastattach”. you should find a mxs code for this trick and explanation of why it’s faster than ‘linear’ attaching