// SCWSS_PointScan_FindSets(): EDError SCWSS_PointScan_FindSets( void *_op, const EDPointInfo *point ) { MeshEditOp *op = (MeshEditOp *)_op; float val; if( point->flags & EDDF_SELECT ) { for( int v=0; v < vmap_count; v++ ) { const char *set_name = object_funcs->vmapName( LWVMAP_PICK, v ); void *set_id = op->pointVSet( op->state, NULL, LWVMAP_PICK, set_name ); if( op->pointVGet( op->state, point->pnt, &val) != 0 ) { unsigned long i; for( i=0; i < selection_set_ids.NumElements(); i++ ) { if( selection_set_ids[i] == set_id ) break; } if( i == selection_set_ids.NumElements() ) { selection_set_ids.Add( set_id ); selection_set_names.Add( StringTools::strdup( set_name ) ); } } } } return EDERR_NONE; }
// FindPaletteIndex() // Returns the palette index that most closely matches the given // RGB value. This only works in Indexed mode. The optional low // and high values specify the low and hight palette indices to // to search (inclusive). This is similar to the other // FindPaletteIndex() functions, but also takes a pointer to a // DynArray of palette indices to match against. IMG_BYTE ImageClass::FindPaletteIndex( IMG_BYTE r, IMG_BYTE g, IMG_BYTE b, DynArray<int> &array ) { if( type != IMAGE_INDEXED ) return 0; if( array.NumElements() == 0 ) return 0; IMG_BYTE closest = 0; // Closest index to the target color int how_close = 1000; // 0 == perfect match int this_try; int step = sizeof( IMG_BYTE ) * 3; IMG_BYTE * rgb = &(palette[ (array[0]) ]); for( unsigned int i=0; i < array.NumElements(); i++ ) { rgb = GetPaletteColor( array[i] ); if( r > rgb[0] ) this_try = r - rgb[0]; // Find the red difference else this_try = rgb[0] - r; if( g > rgb[1] ) this_try += g - rgb[1]; // Find the green difference else this_try += rgb[1] - g; if( b > rgb[2] ) this_try += b - rgb[2]; // Find the blue difference else this_try += rgb[2] - b; if( this_try < how_close ) { // See if this is closer than the last match closest = array[i]; how_close = this_try; } } return closest; }
// SCWP_PolyScan_FindParts(): EDError SCWP_PolyScan_FindParts( void *_op, const EDPolygonInfo *poly ) { MeshEditOp *op = (MeshEditOp *)_op; if( poly->flags & EDDF_SELECT ) { const char *part = op->polyTag( op->state, poly->pol, LWPTAG_PART ); if( part != NULL ) { unsigned long i; for( i=0; i < parts.NumElements(); i++ ) { if( strcmp( parts[i], part ) == 0 ) break; } if( i == parts.NumElements() ) parts.Add( StringTools::strdup( part ) ); } } return EDERR_NONE; }
// SCWP_PolyScan_Select(): EDError SCWP_PolyScan_Select( void *_op, const EDPolygonInfo *poly ) { MeshEditOp *op = (MeshEditOp *)_op; if( !(poly->flags & EDDF_SELECT) ) { for( unsigned long i=0; i < parts.NumElements(); i++ ) { const char *part = op->polyTag( op->state, poly->pol, LWPTAG_PART ); if( part != NULL ) { if( strcmp( parts[i], part ) == 0 ) return (*op->polSelect)( op->state, poly->pol, 1 ); } } } return EDERR_NONE; }
// SCWSS_PointScan_Select(): EDError SCWSS_PointScan_Select( void *_op, const EDPointInfo *point ) { MeshEditOp *op = (MeshEditOp *)_op; float val; for( unsigned long i=0; i < selection_set_ids.NumElements(); i++ ) { if( !(point->flags & EDDF_SELECT) ) { op->pointVSet( op->state, selection_set_ids[i], NULL, NULL ); if( op->pointVGet( op->state, point->pnt, &val) != 0 ) { return (*op->pntSelect)( op->state, point->pnt, 1 ); } } } return EDERR_NONE; }
// ParticleCloud_Evaluate(): void ParticleCloud_Evaluate( LWInstance _inst, const LWCustomObjAccess *access ) { ParticleCloud_Instance *inst = (ParticleCloud_Instance *)_inst; LWObjectInfo *object_info = (LWObjectInfo *)inst->global( LWOBJECTINFO_GLOBAL, GFUSE_TRANSIENT ); LWItemInfo *item_info = (LWItemInfo *)inst->global( LWITEMINFO_GLOBAL, GFUSE_TRANSIENT ); LWMeshInfoID mesh = object_info->meshInfo( inst->GetItems()[0], (inst->GetUseFrozen() ? 1 : 0) ); ParticleCloud_Point::mesh = mesh; // Get the point positions DynArray< ParticleCloud_Point * > points; mesh->scanPoints( mesh, PointScan_GetPositions, &points ); // Get the item's transformation matrix LWDVector item_position, item_right, item_up, item_forward; LWFMatrix4 M; item_info->param( inst->GetItems()[0], LWIP_POSITION, inst->GetTime(), item_position ); item_info->param( inst->GetItems()[0], LWIP_RIGHT, inst->GetTime(), item_right ); item_info->param( inst->GetItems()[0], LWIP_UP, inst->GetTime(), item_up ); item_info->param( inst->GetItems()[0], LWIP_FORWARD, inst->GetTime(), item_forward ); unsigned long i; for ( i = 0; i < 3; i++ ) { M[ 0 ][ i ] = ( float ) item_right[ i ]; M[ 1 ][ i ] = ( float ) item_up[ i ]; M[ 2 ][ i ] = ( float ) item_forward[ i ]; M[ 3 ][ i ] = ( float ) item_position[ i ]; M[ i ][ 3 ] = 0.0f; } M[ 3 ][ 3 ] = 1.0f; // Display each point LWFVector local, world; double position[3]; char buffer[10]; float color[4] = { 0.75, 1.0, 0.75, 1.0 }; access->setColor( access->dispData, color ); for( i=0; i < points.NumElements(); i++ ) { // Convert from local to world space local[0] = points[i]->position[0]; local[1] = points[i]->position[1]; local[2] = points[i]->position[2]; LWVecMath::transformp( local, M, world ); // Convert to doubles position[0] = world[0]; position[1] = world[1]; position[2] = world[2]; // Draw the point access->point( access->dispData, position, LWCSYS_WORLD ); // Draw the point index if( inst->GetShowIndices() ) { sprintf( buffer, "%d", i ); access->text( access->dispData, position, buffer, 0, LWCSYS_WORLD ); } } }
// SCWSS_Activate XCALL_ (int) SCWSS_Activate( long version, GlobalFunc *global, void *local, void *serverData ) { if ( version != LWMODCOMMAND_VERSION ) return AFUNC_BADVERSION; LWModCommand * command = (LWModCommand *)local; if( command == NULL ) return AFUNC_BADLOCAL; // Setup object_funcs = (LWObjectFuncs *)global( LWOBJECTFUNCS_GLOBAL, GFUSE_TRANSIENT ); vmap_count = object_funcs->numVMaps( LWVMAP_PICK ); // Build a list of selection_set_ids for the selected polygons MeshEditOp *op = (command->editBegin)( 0, 0, OPSEL_DIRECT | OPSEL_MODIFY ); selection_set_ids.Flush(); EDError err = op->pointScan( op->state, SCWSS_PointScan_FindSets, (void *)op, OPLYR_FG ); if( err != EDERR_NONE ) { op->done( op->state, err, 0 ); } else { // If there are multiple selection sets, ask the user which one(s) they want bool do_select = true; if( selection_set_ids.NumElements() > 1 ) { // Get some globals ContextMenuFuncs *context_funcs = (ContextMenuFuncs *)global( LWCONTEXTMENU_GLOBAL, GFUSE_TRANSIENT ); LWPanelFuncs *panel_funcs = (LWPanelFuncs *)global( LWPANELFUNCS_GLOBAL, GFUSE_TRANSIENT ); // Set up te context menu LWPanPopupDesc menu_desc; menu_desc.type = LWT_POPUP; menu_desc.width = 200; menu_desc.countFn = SelSetCount; menu_desc.nameFn = SelSetName; // Set up the panel, open the menu and clean up LWPanelID panel = panel_funcs->create( "Selection Sets", panel_funcs ); LWContextMenuID menu = context_funcs->cmenuCreate( &menu_desc, NULL ); int index = context_funcs->cmenuDeploy( menu, panel, 0 ); context_funcs->cmenuDestroy( menu ); panel_funcs->destroy( panel ); // Limit to a single selection set or abort, if applicable if( index == -1 ) { do_select = false; } else if( index != (int)selection_set_names.NumElements() ) { void *id = selection_set_ids[ index ]; selection_set_ids.Reset(); selection_set_ids.Add( id ); } } if( do_select ) { // Select points belonging to the selected selection sets err = op->pointScan( op->state, SCWSS_PointScan_Select, (void *)op, OPLYR_FG ); op->done( op->state, err, 0 ); } } // Clean up selection_set_ids.Reset(); selection_set_names.Flush(); return CSERR_NONE; }
char * SelSetName( void *userdata, int index ) { if( index == (int)selection_set_names.NumElements() ) return "< All Sets >"; else return selection_set_names[ index ]; }
// Context Menu Callbacks int SelSetCount( void *userdata ) { return selection_set_names.NumElements() + 1; }