CompuServe Thread

#Select/Deselect

10 messages in this thread
#155547From: MARK A. MEIERFeb 24, 1995 5:19 PM
I have a question about how to select or deselect an object using a PXP. It seems that three things need to happen: – All the objects verticies must be selected – All the objects faces must be selected – The objects selected flag must be set. I have written the code below to try to do this. It does not work however. I can select an object, but I cannot deselect it. If anyone has done something similiar, I'd appreciate if you could review the code below and offer any suggestions. It is assumed a global ItemData structure called item_data exists and is properly loaded with a mesh object… Thanks, Mark int do_toggle_selection(void) { int index, status; // Save the function address for re-execution get_function_index(do_toggle_selection, &last_function); if (! item_loaded("Toggle Selection", last_function)) return(0); if (item_index) { if (item_type == ITEM_MESH) { if (item_data.item.m.flags & MESH_SELECTED) { status = set_object_selected_state(0); // Toggle Off } else { status = set_object_selected_state(1); // Toggle On } if (status) { pxp_erase_item(item_name); pxp_change_item(&item_data, status); pxp_draw_item(item_name); } else { fmsg("Error: Could not Toggle object \"%s\" Selected state", item_name); } } } return(1); } // This function selects/deselects all the objects verticies and faces // and sets/clears the objects selected flag based on the state passed. // Note: The object is selected/deselected in the 'current' // 3ds selection set (A, B or C). // The object to be modified should be loaded into the global item_data. int set_object_selected_state(int select_it) { int i, faces, verts, status; XFData2 *fdata = NULL; XVData *vdata = NULL; // Allocate temp space for the objects verts/faces verts = item_data.item.m.verts; faces = item_data.item.m.faces; if (! (vdata = (XVData *)malloc(faces*sizeof(XVData)))) { return(0); } if (! (fdata = (XFData2 *)malloc(faces*sizeof(XFData2)))) { free(vdata); return(0); } // Set all the verticies pxp_get_verts(item_data.name, 0, verts, vdata, status); if (status == 0) { free(vdata); free(fdata); fmsg("Could not get Vertex Info for object \"%s\"", item_data.name); return(0); } for (i = 0; i < verts; i++) { if (select_it) { // vdata[i].flags |= (unsigned short) (XV_SELECTED | XV_SEL_A); vdata[i].flags |= (unsigned short) XV_SELECTED; } else { // vdata[i].flags &= (unsigned short) ~(XV_SELECTED | XV_SEL_A); vdata[i].flags &= (unsigned short) ~XV_SELECTED; } } pxp_put_verts(item_data.name, 0, verts, vdata, status); // Set all the faces pxp_get_faces2(item_data.name, 0, faces, fdata, status); if (status == 0) { free(vdata); free(fdata); fmsg("Could not get Face Info for object \"%s\"", item_data.name); return(0); } for (i = 0; i < faces; i++) { if (select_it) { // fdata[i].flags |= (unsigned short) (XF_SELECTED | XF_SEL_A); fdata[i].flags |= (unsigned short) XF_SELECTED; } else { // fdata[i].flags &= (unsigned short) ~(XF_SELECTED | XF_SEL_A); fdata[i].flags &= (unsigned short) ~XF_SELECTED; } } pxp_put_faces2(item_data.name, 0, faces, fdata, status); // Set/Clear the object selected flag if (select_it) { item_data.item.m.flags |= (unsigned short) MESH_SELECTED; } else { item_data.item.m.flags &= (unsigned short) ~MESH_SELECTED; } free(vdata); free(fdata); return(status); }
#155612From: MARK A. MEIERFeb 25, 1995 6:22 AM
Looks like the last message got truncated…here goes again. I have a question about how to select or deselect an object using a PXP. It seems that three things need to happen: – All the objects verticies must be selected – All the objects faces must be selected – The objects selected flag must be set. I have written the code below to try to do this. It does not work however. I can select an object, but I cannot deselect it. If anyone has done something similiar, I'd appreciate if you could review the code below and offer any suggestions. It is assumed a global ItemData structure called item_data exists and is properly loaded with a mesh object… Thanks, Mark int do_toggle_selection(void) { int index, status; // Save the function address for re-execution get_function_index(do_toggle_selection, &last_function); if (! item_loaded("Toggle Selection", last_function)) return(0); if (item_index) { if (item_type == ITEM_MESH) { if (item_data.item.m.flags & MESH_SELECTED) { status = set_object_selected_state(0); // Toggle Off } else { status = set_object_selected_state(1); // Toggle On } if (status) { pxp_erase_item(item_name); pxp_change_item(&item_data, status); pxp_draw_item(item_name); } else { fmsg("Error: Could not Toggle object \"%s\" Selected state", item_name); } } } return(1); } // This function selects/deselects all the objects verticies and faces // and sets/clears the objects selected flag based on the state passed. // Note: The object is selected/deselected in the 'current' // 3ds selection set (A, B or C). // The object to be modified should be loaded into the global item_data. int set_object_selected_state(int select_it) { int i, faces, verts, status; XFData2 *fdata = NULL; XVData *vdata = NULL; // Allocate temp space for the objects verts/faces verts = item_data.item.m.verts; faces = item_data.item.m.faces; if (! (vdata = (XVData *)malloc(faces*sizeof(XVData)))) { return(0); } if (! (fdata = (XFData2 *)malloc(faces*sizeof(XFData2)))) { free(vdata); return(0); } // All the verticies pxp_get_verts(item_data.name, 0, verts, vdata, status); if (status == 0) { free(vdata); free(fdata); fmsg("Could not get Vertex Info for object \"%s\"", item_data.name); return(0); } for(i = 0; i < verts; i++) { if (select_it) { // vdata[i].flags |= (unsigned short) (XV_SELECTED | XV_SEL_A); vdata[i].flags |= (unsigned short) XV_SELECTED; } else { // vdata[i].flags &= (unsigned short) ~(XV_SELECTED | XV_SEL_A); vdata[i].flags &= (unsigned short) ~XV_SELECTED; } } pxp_put_verts(item_data.name, 0, verts, vdata, status); // All the faces pxp_get_faces2(item_data.name, 0, faces, fdata, status); if (status == 0) { free(vdata); free(fdata); fmsg("Could not get Face Info for object \"%s\"", item_data.name); return(0); } for(i = 0; i < faces; i++) { if (select_it) { // fdata[i].flags |= (unsigned short) (XF_SELECTED | XF_SEL_A); fdata[i].flags |= (unsigned short) XF_SELECTED; } else { // fdata[i].flags &= (unsigned short) ~(XF_SELECTED | XF_SEL_A); fdata[i].flags &= (unsigned short) ~XF_SELECTED; } } pxp_put_faces2(item_data.name, 0, faces, fdata, status); // Set/Clear the object selected flag if (select_it) { item_data.item.m.flags |= (unsigned short) MESH_SELECTED; } else { item_data.item.m.flags &= (unsigned short) ~MESH_SELECTED; } free(vdata); free(fdata); return(status); }
#155628From: Jonas Ruikis [ADESK]Feb 25, 1995 10:33 AM
Hi Mark, << code.. >> I'll put some time into this over the weekend. I may not be able to do a lot of testing til monday though. Danny's done a lot of select/deselection, maybe he'll jump in too.
#155646From: MARK A. MEIERFeb 25, 1995 1:19 PM
Thanks Jonas Mark
#155666From: Danny MercurioFeb 25, 1995 4:49 PM
I sent Mark a simple PXP that does what he's looking for. If you're interested, I can post the complete source and PXP here for anyone who might make use of it.
#155667From: Danny MercurioFeb 25, 1995 4:49 PM
Hi Mark, I took a look at your problem and played around a bit. Here's a program that correctly selects/deselects objects in the 3D Editor and is selection-set sensitive. I hope it helps. Take care, Danny… /*________________________________________________________________________*/ /* Dialog description */ DlgEntry cdialog[]={ 0, "TITLE=\"Selection Test IPAS\"", 0, "TITLE=\"by Danny Mercurio\"", 0, "TITLE=\"Details, Inc.\"", 0, "TITLE=\"\"", 0, NULL }; /*_______________________________________________________________________ */ #define VERSION 0x0507 typedef struct{ ulong version; } State; ItemData data; static State init_state = {VERSION}; static State state = {VERSION}; int count = 0, counter = 0, status = 0; int verts = 0, faces = 0, result = 0, sel = 0; /*_______________________________________________________________________ */ /* declare global subroutines */ int selection_set(void); int set_object_selected_state(int select_it, int sel); int do_toggle_selection(int index); /*_______________________________________________________________________ */ int ClientUsesInitDialog(void){ return(1); } void ClientSetStateVar(int id, void *ptr){ OVL o; ulong *ul; char *s; ul = (ulong *)ptr; s = (char *)ptr; o.ul = *ul; switch(id){ } } ulong ClientGetStateVar(int id){ OVL o; switch(id){ } return(o.ul); } int ClientVarSize(int id){ switch(id){ default: return(1); } } char *ClientGetState(int *size){ *size = sizeof(State); return((char *)&state); } void ClientResetState(){ state = init_state; } void ClientStartup(EXPbuf *buf){ int result; /* requires version 3.0 */ if(studio_version() < 300){ gfx_alert(0, "[Resource Test PXP Plug-in requires 3D Studio Release 3 or later.][OK]", result); buf->opcode = buf->usercode = EXP_TERMINATE; return; } /* how many objects are in the editor? */ pxp_get_item_count(count); if(count == 1){ gfx_alert(0, "[No objects in editor.][OK]", result); buf->opcode = buf->usercode = EXP_TERMINATE; return; } /* kicks things down to ClientUserCode */ buf->opcode = EXP_NOP; buf->usercode = 0x0200; buf->status = 1; } void ClientUserCode(EXPbuf *buf){ int n; switch(buf->usercode){ case 0x0200: counter = 0; for(n = 1; n < count; n++){ if(!do_toggle_selection(n)){ gfx_alert(0, "[Unknown problem occurred][OK]", result); buf->opcode = buf->usercode = EXP_TERMINATE; break; } } buf->opcode = EXP_NOP; buf->usercode = 0x0210; buf->status = 1; break; case 0x0210: buf->opcode = buf->usercode = EXP_TERMINATE; buf->status = 0; break; default: buf->opcode = buf->usercode = EXP_TERMINATE; buf->status = 0; break; } } void ClientTerminate(void){ /* free any data structures, etc. */ } DlgEntry *ClientDialog(int n){ return(&cdialog[n]); } int ClientIsUniversal(void){ return(0); } /*________________________________________________________________________*/ int do_toggle_selection(int index){ int status; pxp_get_item(index, &data, status); if(status && data.type == PXPMESH){ if (data.item.m.flags & MESH_SELECTED) { if(counter == 0) sel = selection_set(); // Which set are we in? status = set_object_selected_state(0, sel); // Toggle Off counter++; } else { status = set_object_selected_state(1, sel); // Toggle On } if (status) { pxp_erase_item(data.name); pxp_change_item(&data, status); pxp_draw_item(data.name); } else { sprintf(gp_buffer, "Error: Could not Toggle object \"%s\" Selected state", data.name); gfx_continu_line(gp_buffer); } } return(1); } int set_object_selected_state(int select_it, int sel){ int i, faces, verts, status, result; XFData2 *fdata = NULL; XVData *vdata = NULL; // Allocate temp space for the objects verts/faces verts = data.item.m.verts; faces = data.item.m.faces; vdata = (XVData *)malloc(verts*sizeof(XVData)); if (!vdata) { gfx_alert(0, "[Insufficient memory for vertices.][OK]", result); return(0); } fdata = (XFData2 *)malloc(faces*sizeof(XFData2)); if (!fdata) { free(vdata); gfx_alert(0, "[Insufficient memory for faces.][OK]", result); return(0); } // All the verticies pxp_get_verts(data.name, 0, verts, vdata, status); if (status == 0) { free(vdata); free(fdata); sprintf(gp_buffer, "Could not get Vertex Info for object \"%s\"", data.name); gfx_continu_line(gp_buffer); return(0); } for(i = 0; i < verts; i++) { if (select_it) { // vdata[i].flags |= (unsigned short) (XV_SELECTED | XV_SEL_A); vdata[i].flags |= (unsigned short) XV_SELECTED; } else { // vdata[i].flags &= (unsigned short) ~(XV_SELECTED | XV_SEL_A); // vdata[i].flags &= (unsigned short) ~XV_SELECTED; switch(sel){ case 1: vdata[i].flags &= (unsigned short) ~(XV_SELECTED | XV_SEL_A); break; case 2: vdata[i].flags &= (unsigned short) ~(XV_SELECTED | XV_SEL_B); break; case 3: vdata[i].flags &= (unsigned short) ~(XV_SELECTED | XV_SEL_C); break; } } } pxp_put_verts(data.name, 0, verts, vdata, status); // All the faces pxp_get_faces2(data.name, 0, faces, fdata, status); if (status == 0) { free(vdata); free(fdata); sprintf(gp_buffer, "Could not get Face Info for object \"%s\"", data.name); gfx_continu_line(gp_buffer); return(0); } for(i = 0; i < faces; i++) { if (select_it) { // fdata[i].flags |= (unsigned short) (XF_SELECTED | XF_SEL_A); fdata[i].flags |= (unsigned short) XF_SELECTED; } else { // fdata[i].flags &= (unsigned short) ~(XF_SELECTED | XF_SEL_A); // fdata[i].flags &= (unsigned short) ~XF_SELECTED; switch(sel){ case 1: fdata[i].flags &= (unsigned short) ~(XF_SELECTED | XF_SEL_A); break; case 2: fdata[i].flags &= (unsigned short) ~(XF_SELECTED | XF_SEL_B); break; case 3: fdata[i].flags &= (unsigned short) ~(XF_SELECTED | XF_SEL_C); break; } } } pxp_put_faces2(data.name, 0, faces, fdata, status); // Set/Clear the object selected flag if (select_it) { data.item.m.flags |= (unsigned short) MESH_SELECTED; } else { data.item.m.flags &= (unsigned short) ~MESH_SELECTED; } free(vdata); free(fdata); return(status); } int selection_set(void){ int status, result, sel = 0, temp = 0; XVData *vdata = NULL; // Allocate temp space for the objects verts vdata = (XVData *)malloc(sizeof(XVData)); if (!vdata) { gfx_alert(0, "[Insufficient memory for vertices.][OK]", result); return(0); } // Get a vertex pxp_get_verts(data.name, 0, 1, vdata, status); if (status == 0) { free(vdata); sprintf(gp_buffer, "Could not get Selection Info for object \"%s\"", data.name); gfx_continu_line(gp_buffer); return(0); } // where are we? pxp_get_verts(data.name, 0, 1, vdata, status); if(status){ // save current selection info temp = vdata[0].flags; // reset selection info vdata[0].flags = 0; // set selection flag to see which set we're in vdata[0].flags |= (unsigned short) XV_SELECTED; pxp_put_verts(data.name, 0, 1, vdata, status); } if(status){ pxp_get_verts(data.name, 0, 1, vdata, status); // set the selection flag accordingly switch(vdata[0].flags){ case (XV_SELECTED | XV_SEL_A): sel = 1; break; case (XV_SELECTED | XV_SEL_B): sel = 2; break; case (XV_SELECTED | XV_SEL_C): sel = 3; break; } // put things back the way they were vdata[0].flags = temp; pxp_put_verts(data.name, 0, 1, vdata, status); } // free things up and return free(vdata); return(sel); }
#155678From: Jonas Ruikis [ADESK]Feb 25, 1995 6:19 PM
Thanks alot Danny!
#155700From: Danny MercurioFeb 25, 1995 10:58 PM
My pleasure. I had fun writing it.
#155739From: MARK A. MEIERFeb 26, 1995 1:13 PM
>> I've tried to send you the source to a small PXP that'll do what you need, but I'm not sure if ASOFT messages can handle the number of lines of source. << It came thru fine via email. Its been 45 minutes since I got the code. I patched it into my program and it works perfectly. Thanks a lot! I like the way you've handled finding the current selection set. Clever. >> I hope it helps. << Saved me hours (days?) and the frustration reduction has added a few months to my life <g>. Thanks again Danny,
#155740From: Danny MercurioFeb 26, 1995 1:16 PM
I'm glad it worked for you Mark. Take care, Danny…