IPAS-Multiple Selections
14-Sep-95 15:36:07
Sb: #190520-IPAS-Multiple Selections
Fm: Jonas Ruikis [ADESK] 73172,1351
To: – Visitor 102661,1456
Hi Phillipe,
<< selection sets?.. >>
in addition to my previous response, you may want to compile and analyze
Danny's following code…
/**************************************************************************/
/* */
/* Autodesk 3D Studio 4.0 Res.c */
/* Resource IPAS (PXP) */
/* */
/* Purpose: Tests selection/deselection of 3DS objects. */
/* */
/* Version: 1.0 */
/* */
/* Company: Details, Inc. */
/* Written by: Danny Mercurio */
/* Created: 02-25-95 01:12pm */
/* Modified: 02-25-95 03:03pm */
/* Notes: Metaware HighC v3.1 specific */
/* */
/**************************************************************************/
/*________________________________________________________________________*/
#ifdef __HIGHC__ /* Metaware HighC specific */
pragma Offwarn(67); /* kills "switch statement has no cases" warning */
#endif
/*________________________________________________________________________*/
#include <conio.h>
#include <math.h> /* supports sine and cosine functions */
#include <stdarg.h> /* for reading argument lists */
#include <stdio.h> /* supports the printf function */
#include <stdlib.h> /* supports several common routines */
#include <string.h> /* supports several common routines */
#include <pxp.h> /* Autodesk PXP extension file */
#define VERSION 0x0507
/*________________________________________________________________________*/
/* Dialog description */
DlgEntry cdialog[]={
0, "TITLE=\"Selection Test IPAS\"",
0, "TITLE=\"by Danny Mercurio\"",
0, "TITLE=\"Details, Inc.\"",
0, "TITLE=\"\"",
0, NULL
};
/*_______________________________________________________________________ */
typedef struct{
ulong version;
} State;
XVData *vertdata = NULL;
XFData2 *facedata = NULL;
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. */
free(vertdata);
free(facedata);
}
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){
sprintf(gp_buffer, "\"%s\" Selected state is %d", data.name,
data.item.m.flags & MESH_SELECTED);
gfx_continu_line(gp_buffer);
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);
}
// 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 data.
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);
}