-- Selection Toolkit -- Jason Hayes -- Rockstar San Diego -- June 2012 -- Random Function added by Allan Hayburn Sept 2012 -- Oct 2012 --Allan Hayburn Fairly major ui overhaul. no functionality changes -- 17 Oct 2012 --Allan Hayburn Added the select collision script -- 19 Oct 2012 --Allan Hayburn ui formatted as tabs ( try (cui.UnRegisterDialogBar RsSelectionTools_Rollout) catch() try (destroyDialog RsSelectionTools_Rollout) catch () callbacks.removeScripts id:#alpha_test_1 ) -- This line loads the custom header if (not gRsIsOutsource) do ( filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms") ) -- Generic selection-functions: filein (RsConfigGetWildWestDir() + "script/3dsMax/General_tools/Selection_Funcs.ms") ------------------------------------------------------------------------------------------------------------------------- rollout GeometrySelection "Geometry Selection" ( -- Local defines local cbOnSelectionChanged = undefined -- Icons local selectBorderEdgeIcon = #( "rs_selectiontools_i.bmp", "rs_selectiontools_a.bmp", 20, 1, 1, 2, 2, true ) local selectBorderVertIcon = #( "rs_selectiontools_i.bmp", "rs_selectiontools_a.bmp", 20, 3, 3, 4, 4, true ) local randomlySelectVertIcon = #( "rs_selectiontools_i.bmp", "rs_selectiontools_a.bmp", 20, 5, 5, 6, 6, true ) local growSelectionIcon = #( "rs_selectiontools_i.bmp", "rs_selectiontools_a.bmp", 20, 7, 7, 8, 8, true ) local vertexAlphaSelectorIcon = #( "rs_selectiontools_i.bmp", "rs_selectiontools_a.bmp", 20, 9, 9, 10, 10, true ) local snapBothIcon = #( "rs_selectiontools_i.bmp", "rs_selectiontools_a.bmp", 20, 11, 11, 12, 12, true ) local snapAtoBIcon = #( "rs_selectiontools_i.bmp", "rs_selectiontools_a.bmp", 20, 13, 13, 14, 14, true ) local snapBtoAIcon = #( "rs_selectiontools_i.bmp", "rs_selectiontools_a.bmp", 20, 15, 15, 16, 16, true ) local selectAlphaDecalIcon = #( "rs_selectiontools_i.bmp", "rs_selectiontools_a.bmp", 20, 17, 17, 18, 18, true ) local convertTexVertSelectionIcon = #( "rs_selectiontools_i.bmp", "rs_selectiontools_a.bmp", 20, 19, 19, 20, 20, true ) fn meshFilter obj = classOf obj == Editable_Poly local selectAllBordersTooltip = "When enabled, will select all borders of the material id. Otherwise, it will select the material border based on the current selection. This only works if 'By Face Selection' is used." --Controls button btnGrowSelectionByMatId "" offset:[0,10] width:32 height:32 tooltip:"Grow face selection by material id. Requires Editable Poly." images:growSelectionIcon across:2 button btnConvertTexVertSelection "" offset:[0,10] width:32 height:32 images:convertTexVertSelectionIcon border:false tooltip:"Convert current vertex selection in the 'Unwrap UVW' modifier to geometry vertex selection." label lbSpacer02 "" group "Select Material Border" ( radiobuttons rbSelectionType "" labels:#( "By Face Selection", "By Material ID" ) across:3 offset:[ 16, 0 ] button btnSelectBorderEdges "" width:32 height:32 tooltip:"Select edges" images:selectBorderEdgeIcon offset:[ 40, 0 ] button btnSelectBorderVerts "" width:32 height:32 tooltip:"Select verts" images:selectBorderVertIcon offset:[ 14, 0 ] checkbox btnSelectAllBorders "Select All Borders" offset:[ -5, -2 ] tooltip:selectAllBordersTooltip dropDownList ddlMaterialId "" range:[ 1, 9999, 1 ] type:#integer enabled:false width:64 offset:[ -5, 0 ] across:2 button btnRefreshMaterialIdList "R" width:22 height:22 offset:[ -72, -1 ] enabled:false tooltip:"Refresh material id list" border:false ) group "Randomly Deselect Vertices" ( spinner spRandomDeselectVertPct "Percentage:" range:[ 1, 100, 50 ] type:#integer width:110 align:#left offset:[ 0, 8 ] across:2 button btnRandomlyDeselectVert "" width:32 height:32 offset:[ -10, 0 ] images:randomlySelectVertIcon tooltip:"Deselect random vertices using percentage" ) group "Snap Verts" ( spinner spSnapTolerance "Tolerance:" range:[ 0.0, 100.0, 0.05 ] scale:0.01 width:150 align:#left offset:[ -2, 10 ] across:4 button btnSnapAtoB "A > B" width:32 height:32 tooltip:"Snap verts from object A to object B\n**Requires Editable Poly**" offset:[ 45, 0 ] images:snapAtoBIcon border:false button btnSnapBtoA "B > A" width:32 height:32 tooltip:"Snap verts from object B to object A\n**Requires Editable Poly**" offset:[ 30, 0 ] images:snapBtoAIcon border:false button btnSnapBoth "" width:32 height:32 tooltip:"Snap verts to midpoint of gap\n**Requires Editable Poly**" offset:[ 15, 0 ] images:snapBothIcon border:false pickbutton pbObjA "Pick Object A" width:96 height:24 tooltip:"Object A\n**Requires Editable Poly**" filter:meshFilter autoDisplay:true align:#left across:2 pickbutton pbObjB "Pick Object B" width:96 height:24 tooltip:"Object B\n**Requires Editable Poly**" filter:meshFilter autoDisplay:true align:#right offset:[4,0] ) group "Reset Vert Position" ( button btnStoreVertPos "Store Vert Positions" width:200 height:24 button btnRestoreVertPos "Restore Vert Positions" width:200 height:24 ) group "Random Select" ( checkbox chk_selectSpin "Select while spinning:" checked:false across:2 offset:[0,2] spinner spr_Percent "%:" range:[0.0, 100.0, 50.0] type:#float width:65 offset:[0,2] button btn_select "Select:" width:80 offset:[-1,0] align:#left across:2 dropdownlist lst_ObjType "" width:100 offset:[-3,0] items:#("Geometry","Vertex","Face") align:#right ) group "Select by Face/Element Size" ( radioButtons rdoSizeMethod "Sizing Method:" labels:#("Face Area (m^2)", "Element Box-Dimensions (m)") align:#left button btnSelectByFaceSize "Select:" width:80 align:#left across:2 tooltip:"Selects all faces who are equal to or less than the specified size." spinner spFaceSize "Size:" offset:[ 0, 3 ] range:[ 0.0, 9999.0, 1.0 ] radioButtons rdoGtLtSize "" labels:#("< Size", "> Size") columns:2 align:#right offset:[0,-4] checkbox cbFaceSizeSelectWhileSpinning "Select while spinning" align:#right offset:[0,-2] ) group "Select duplicate faces" ( button btnSelectDuplicateFaces "Select" width:80 align:#left across:2 tooltip:"Selects all duplicate faces within the given threshold." spinner spDuplicateThreshold "Threshold:" offset:[ 0, 3 ] range:[ 0.0, 0.05, 0.001 ] ) groupbox gbx1 "" width:GeometrySelection.width height:5 pos:[0,62] -- Functions fn setEnabledState state = ( btnGrowSelectionByMatId.enabled = state btnSelectBorderEdges.enabled = state btnSelectBorderVerts.enabled = state btnRandomlyDeselectVert.enabled = state rbSelectionType.enabled = state btnConvertTexVertSelection.enabled = state ) fn refresh = ( obj = ( selection as array )[ 1 ] case of ( (not isValidNode obj): ( setEnabledState false btnConvertTexVertSelection.enabled = false ) (isKindOf obj PolyMeshObject): ( btnConvertTexVertSelection.enabled = True ) (isKindOf obj Editable_Poly): ( btnConvertTexVertSelection.enabled = False local matIds = gRsSelectionTools.getMaterialIds obj if matIds != undefined then ( ddlMaterialId.items = for i in matIds collect ( i as string ) ) if ( subObjectLevel == 1 ) then ( btnGrowSelectionByMatId.enabled = false btnSelectBorderEdges.enabled = true btnSelectBorderVerts.enabled = true btnRandomlyDeselectVert.enabled = true rbSelectionType.enabled = true ) else if ( subObjectLevel == 2 ) then ( btnGrowSelectionByMatId.enabled = false btnSelectBorderEdges.enabled = true btnSelectBorderVerts.enabled = true btnRandomlyDeselectVert.enabled = false rbSelectionType.enabled = true ) else if ( subObjectLevel == 4 ) then ( btnGrowSelectionByMatId.enabled = true btnSelectBorderEdges.enabled = true btnSelectBorderVerts.enabled = true btnRandomlyDeselectVert.enabled = false rbSelectionType.enabled = true ) else ( setEnabledState false ) ) (isKindOf obj Editable_Mesh): ( setEnabledState false btnConvertTexVertSelection.enabled = true ) ) ) fn onSelectionChanged event node = ( refresh() ) fn randomSelect thePercentage theClass = ( local theClass = (theClass as name) setCommandPanelTaskMode #modify local theObj, objOp local candidatesArray = undefined if theClass == #Geometry then ( -- collects all geometry objects, excluding target objects clearselection() candidatesArray = for o in Geometry where (not o.ishidden) and (not isKindOf o TargetObject) collect o subobjectLevel = 0 ) else ( if ((selection.count == 1) and ((isKindOf selection[1] Editable_Mesh) or (isKindOf selection[1] Editable_Poly))) then ( subobjectLevel = case theClass of ( #Vertex:1 #Face:4 default:0 ) theObj = selection[1] objOp = (RsMeshPolyOp theObj) local theSubLevelOp = case theClass of ( #Vertex:objOp.getNumVerts #Face:objOp.getNumFaces ) candidatesArray = (for n = 1 to theObj.numVerts collect n) ) else ( messagebox "Object must be editable poly or editable mesh." title:"Error" ) ) try ( local numberToSelect = (thePercentage / 100.0 * candidatesArray.count) as integer -- Calculate the number of objects to select local randomiserList = for item in candidatesArray collect (dataPair num:(random 0 100000) item:item) fn listSorter v1 v2 = (v1.num - v2.num) qsort randomiserList listSorter local selectArray = for n = 1 to numberToSelect collect randomiserList[n].item if theClass == #Geometry then ( select selectArray ) else ( case of ( (isKindOf theObj Editable_Poly): ( local theSubLevelSelectionOp = case theClass of ( #Vertex:polyOp.setVertSelection #Face:polyOp.setFaceSelection ) theSubLevelSelectionOp theObj (selectArray as bitarray) ) (isKindOf theObj Editable_mesh): ( case theSubLevel of ( 1:(theobj.selectedVerts = (selectArray as bitarray)) 4:(theobj.selectedFaces = (selectArray as bitarray)) ) ) ) ) redrawViews() ) catch() ) fn doSelectByFaceSizes quiet:False = ( local elemWidth = (rdoSizeMethod.state == 2) local inverted = (rdoGtLtSize.state == 2) gRsSelectionTools.SelectFacesBySize Selection spFaceSize.value elements:elemWidth inverted:inverted ) -- Event Handlers: on rdoGtLtSize changed state do ( doSelectByFaceSizes quiet:True ) on btnSelectByFaceSize pressed do ( doSelectByFaceSizes() ) on spFaceSize changed val do ( if cbFaceSizeSelectWhileSpinning.checked do ( doSelectByFaceSizes quiet:True ) ) on lst_ObjType selected val do ( randomSelect spr_Percent.value lst_ObjType.items[val] ) on btn_select pressed do ( randomSelect spr_Percent.value lst_ObjType.selected ) on spr_Percent changed val do ( if chk_selectSpin.checked ==true then randomSelect val lst_ObjType.selected ) on btnGrowSelectionByMatId pressed do ( undo "Grow Selection by Material Id" on ( gRsSelectionTools.growSelectionByMatId $ ) ) on btnVertexAlphaSelector pressed do ( fileIn ( ::RsConfigGetWildwestDir() + "script/max/rockstar_north/maps/vertexalphaselector.ms" ) ) on btnSelectAlphaDecal pressed do ( filein (::RsConfigGetWildwestDir() + "script/max/rockstar_north/maps/select_alphadecal.ms") ) on btnConvertTexVertSelection pressed do ( undo "Convert Unwrap Vert Selection" on ( obj = $selection[ 1 ] gRsSelectionTools.convertMapVertSelectionToMeshVertSelection obj ) ) -- Reset Vert Position on btnStoreVertPos pressed do ( obj = $selection[ 1 ] if obj != undefined do ( gRsSelectionTools.storeVertexPositions obj ) ) on btnRestoreVertPos pressed do ( obj = $selection[ 1 ] if obj != undefined do ( gRsSelectionTools.restoreVertexPositions obj ) ) -- Select Material Border on btnRefreshMaterialIdList pressed do ( refresh() ) on btnSelectBorderEdges pressed do ( obj = $selection[ 1 ] if obj != undefined do ( undo "Select Border Edges" on ( if rbSelectionType.state == 1 then ( gRsSelectionTools.selectMaterialBorderFromFaceSelection obj type:#edges selectAllBorders:btnSelectAllBorders.state ) else ( gRsSelectionTools.selectMaterialBorderEdges obj ( ddlMaterialId.selected as integer ) selectAllBorders:true ) ) ) redrawViews() ) on btnSelectBorderVerts pressed do ( undo "Select Border Verts" on ( if rbSelectionType.state == 1 then ( gRsSelectionTools.selectMaterialBorderFromFaceSelection $ type:#verts selectAllBorders:btnSelectAllBorders.state ) else ( gRsSelectionTools.selectMaterialBorderVerts $ ( ddlMaterialId.selected as integer ) selectAllBorders:true ) ) redrawViews() ) on rbSelectionType changed sel do ( if sel == 1 then ( ddlMaterialId.enabled = false btnRefreshMaterialIdList.enabled = false btnSelectAllBorders.enabled = true ) else ( ddlMaterialId.enabled = true btnRefreshMaterialIdList.enabled = true btnSelectAllBorders.enabled = false ) ) -- Randomly Deselect Vertices on btnRandomlyDeselectVert pressed do ( undo "Randomly Deselect Verts" on ( gRsSelectionTools.randomlyDeselectVerts $ spRandomDeselectVertPct.value ) redrawViews() ) -- Snap Verts on btnSnapAtoB pressed do ( if pbObjA.object != undefined and pbObjB.object != undefined then ( undo "Snap Verts A to B" on ( local objA = pbObjA.object local objB = pbObjB.object gRsSelectionTools.snapVertsToTarget objA objB tolerance:spSnapTolerance.value ) completeRedraw() ) ) on btnSnapBtoA pressed do ( if pbObjA.object != undefined and pbObjB.object != undefined then ( undo "Snap Verts B to A" on ( local objA = pbObjA.object local objB = pbObjB.object gRsSelectionTools.snapVertsToTarget objB objA tolerance:spSnapTolerance.value ) completeRedraw() ) ) on btnSnapBoth pressed do ( if pbObjA.object != undefined and pbObjB.object != undefined then ( undo "Snap Verts to Midpoint" on ( local objA = pbObjA.object local objB = pbObjB.object gRsSelectionTools.snapVertsToMidpoint objA objB tolerance:spSnapTolerance.value ) completeRedraw() ) ) on btnSelectDuplicateFaces pressed do ( if( Selection.Count != 1 or ClassOf Selection[1] != Editable_Mesh ) then ( MessageBox "Please select one editable_mesh to find duplicate faces." return() ) TargetMesh = Selection[1] RSPushPrompt "Searching for duplicate faces..." DuplicateFaceList = RSMesh_GetFaceList_Duplicated TargetMesh Threshold:spDuplicateThreshold.Value RSPopPrompt() setFaceSelection TargetMesh DuplicateFaceList ) -- Rollout on GeometrySelection open do ( cbOnSelectionChanged = NodeEventCallback mouseUp:true selectionChanged:onSelectionChanged subObjectSelectionChanged:onSelectionChanged modelStructured:onSelectionChanged refresh() ) on GeometrySelection close do ( AllVertexDataLists = #() cbOnSelectionChanged = undefined gc light:true ) ) ------------------------------------------------------------------------------------------------------------------------- rollout VertexAlphaSelection "Vertex Alpha Selector" ( group "Display" ( Checkbox btnAlpha "A" checked:false tooltip:"display vertex Alpha" across:3 Checkbox btnColour "C" checked:false tooltip:"display vertex Color" Checkbox btnNormal "none" checked:false tooltip:"display normal" ) group "Selection" ( multiListBox lbx_1 button btnSelect "Select" width:80 toolTip:"Select vertices" align:#left across:2 colorpicker cpPick "Pick:" color:[255, 255, 255] align:#right ) group "Adjust" ( spinner spn_1 "Value: " fieldWidth:50 range:[0.0,100.0,0.0] type:#float scale:1.0 align:#left across:2 offset:[0,15] --button btn5 "integer" pos:[76,120] width:42 height:32 toolTip:"Integer alpha, 12.2563 --> 12.0" dropdownList dd_1 "object : " width:90 height:15 items:#("") align:#right offset:[0,-5] ) --########################################################################################## fn My_alpha_select_verts item_number = ( setwaitcursor() max modify mode if selection.count == 0 then ( VertexAlphaSelection.lbx_1.items =#() VertexAlphaSelection.dd_1.items =#(" ") VertexAlphaSelection.dd_1.caption="" ) else ( current_alpha_array = #() item_content = #() --convertToPoly selection for g = 1 to item_number.count do ( if item_number[g] == true then ( append item_content (VertexAlphaSelection.lbx_1.items[g] as float) ) ) --subobjectLevel = 1 ------------------------------------------------- for nn = 1 to selection.count do ( current_alpha_array = #() all_vertexs = 0 case (classOf selection[nn].baseobject ) of ( Editable_Poly: ( polyOp.setMapSupport selection[nn] -2 true all_vertexs=polyop.getNumMapVerts selection[nn] -2 ) Editable_mesh: ( meshOp.setMapSupport selection[nn] -2 true all_vertexs=meshOp.getNumMapVerts selection[nn] -2 ) ) must_select_verts = #{} must_select_verts[all_vertexs] = false xx = #{} --the selected verts array for h =1 to item_content.count do ( vv= ( item_content[h] ) * 2.55 case (classOf selection[nn].baseobject ) of ( Editable_Poly: ( xx+=polyop.getVertsByColor selection[nn] (color vv vv vv) 0.01 0.01 0.01 channel:-2 ) Editable_mesh: ( --selectMapVerts = #() --each map face --test mapverts against colour --pass test then find geo vert --append to array numMapFaces = meshOp.getNumMapFaces selection[nn] -2 for mf = 1 to numMapFaces do ( mv = meshOp.getMapFace selection[nn] -2 mf mv = #(mv.x as Integer, mv.y as Integer, mv.z as Integer) --check colour for v = 1 to mv.count do ( col = (meshOp.getMapVert selection[nn] -2 mv[v])[1] diff = abs (col - (0.01 * item_content[h])) --if diff < 0.25 then format "v: % col: % item: % diff: % \n" v col (0.01 * item_content[h]) diff if diff < 0.003921 then ( --find its geo vert counterpart --v is the mapvert index face = getFace selection[nn] mf face = #(face.x as Integer, face.y as Integer, face.z as Integer) append xx face[v] ) ) ) --xx+=meshop.getVertsByColor selection[nn] (color vv vv vv) 0.01 0.01 0.01 channel:-2 ) ) ) select selection[nn].verts[xx] )--for nn --modPanel.addModToSelection (Edit_Mesh ()) ui:on --subobjectLevel = 1 )--else completeRedraw() ) fn My_alpha_test = ( alpha_array=#() uniqueAlphaValues = #() --print $selection[1].name sel = $selection --check for no selection if sel.count == 0 then ( VertexAlphaSelection.lbx_1.items =#() VertexAlphaSelection.dd_1.items =#(" ") VertexAlphaSelection.dd_1.caption="" ) else ( --Add the object names to the ui dropdown obj_name = #() for i =1 to $selection.count do ( obj_name[i] = selection[i].name ) VertexAlphaSelection.dd_1.items = obj_name VertexAlphaSelection.dd_1.caption = ($selection.count as string)+" Obj" current_alpha_array=#() --diffent_alpha=#() for nn in sel do ( current_alpha_array=#() case (classOf nn.baseobject) of ( Editable_Poly: ( polyOp.setMapSupport nn -2 true numMapVerts = polyop.getNumMapVerts nn -2 polyOp_getMapVert = polyOp.getMapVert current_alpha_array = for i = 1 to numMapVerts collect (( polyOp_getMapVert nn -2 i)[1] * 100.0) --get the alpha as a percentag sort current_alpha_array ) Editable_mesh: ( meshOp.setMapSupport nn -2 true all_vertexs=meshop.getNumMapVerts nn -2 for i = 1 to all_vertexs do ( current_alpha_array[i] = ( meshOp.getMapVert nn -2 i)[1] * 100.0 ) sort current_alpha_array ) default: ( --all_vertexs=0 current_alpha_array=#() ) )--end case for a in current_alpha_array do appendIfUnique uniqueAlphaValues (a as String) --sort uniqueAlphaValues --alpha_array += sss )--for VertexAlphaSelection.lbx_1.items = uniqueAlphaValues --My_alpha_select_verts( VertexAlphaSelection.lbx_1.selection ) )--else ) on VertexAlphaSelection open do ( callbacks.removeScripts id:#alpha_test_1 callbacks.addScript #selectionSetChanged "VertexAlphaSelection.My_alpha_test()" id:#alpha_test_1 try (select selection)catch() ) on VertexAlphaSelection close do ( AllVertexDataLists = #() callbacks.removeScripts id:#alpha_test_1 ) on btnSelect pressed do ( -- if classOf selection[1] != Editable_poly then -- ( -- q = queryBox "Needs to be Editable_Poly, convert?" title:"Object Type" -- if q == true then -- ( -- addModifier selection[1] (Edit_Poly()) -- collapseStack selection[1] -- ) -- else if q == false then -- ( -- return false -- ) -- ) subobjectLevel = 1 setwaitcursor() --set the value spinner to the current selection if one item selected aSel = lbx_1.selection as array items = lbx_1.items as array if aSel.count == 1 then ( spn_1.value = items[aSel[1]] as float ) --do the do My_alpha_select_verts lbx_1.selection ) on btnAlpha changed checked do ( btnAlpha.checked = btnColour.checked = btnNormal.checked = false btnAlpha.checked = true selection.vertexColorType = 2 selection.showVertexColors=on selection.vertexColorsShaded=false completeredraw() ) on btnColour changed checked do ( btnAlpha.checked = btnColour.checked = btnNormal.checked = false -- btn3.checked = true selection.vertexColorType = 0 selection.showVertexColors=on selection.vertexColorsShaded=false completeredraw() ) on btnNormal changed checked do ( btnAlpha.checked = btnColour.checked = btnNormal.checked = false btn4.checked = true selection.vertexColorType = 0 selection.showVertexColors=off selection.vertexColorsShaded=false completeredraw() ) on btn5 pressed do ( for nn=1 to selection.count do ( for tt=1 to selection[nn].verts.count do ( alpha_integer=(polyOp.getMapVert selection[nn] -2 tt )[1] alpha_integer=(alpha_integer * 100.0) as integer alpha_integer=alpha_integer/100.0 polyOp.setMapVert selection[nn] -2 tt [alpha_integer,alpha_integer,alpha_integer] ) ) select selection -- messagebox "alpha_integer complete!!" ) --ColorPicker Change Event on cpPick changed arg do ( --take first component of arg as alpha only --find the closest match in the list picked = arg.r as Integer items = lbx_1.items as array idx = findItem items picked -- if idx != 0 then -- ( -- lbx_1.selection = #{idx} -- ) --find closest match minDiff = 9999 idx = 99 for i=1 to items.count do ( ItemInt = (items[i] as float * 2.55) as Integer --Find the diff and check against closest diff = abs(ItemInt - picked) if diff < minDiff then ( minDiff = diff idx = i ) ) --Now we have the closest lbx_1.selection = #{idx} --set the value to the selection val spn_1.value = items[idx] as float ) --*************************************************************************************** --apply new values on spn_1 entered do ( setwaitcursor() new_alpha_value = spn_1.value * 0.01 new_alpha_value = [new_alpha_value, new_alpha_value, new_alpha_value] for nn in selection do ( --go through mapverts checking aginst value apply new cvalue to matches case (classOf nn) of ( Editable_Poly: ( polyOp_getMapVert = polyOp.getMapVert currentAlpha = for i = 1 to (polyop.getNumMapVerts nn -2) collect (( polyOp_getMapVert nn -2 i)[1] * 100.0) listValuesCount = lbx_1.selection.count listSelection = lbx_1.selection as array for lv = 1 to listSelection.count do ( listValue = lbx_1.items[listSelection[lv]] as Float for v = 1 to currentAlpha.count do ( diff = abs (currentAlpha[v] - listValue) if diff < 0.3921 then ( --format "listValue: % currentAlpha: % diff: %\n " listValue currentAlpha[v] diff polyOp.setMapVert nn -2 v new_alpha_value ) ) ) --polyOp.setVertColor nn -2 (nn.selectedVerts) new_alpha_value ) Editable_Mesh: ( meshOp_getMapVert = meshOp.getMapVert currentAlpha = for i = 1 to (meshop.getNumMapVerts nn -2) collect (( meshOp_getMapVert nn -2 i)[1] * 100.0) listValuesCount = lbx_1.selection.count listSelection = lbx_1.selection as array for lv = 1 to listSelection.count do ( listValue = lbx_1.items[listSelection[lv]] as Float for v = 1 to currentAlpha.count do ( diff = abs (currentAlpha[v] - listValue) if diff < 0.3921 then -- 100 / 255 = 0.3921 ( --format "listValue: % currentAlpha: % diff: %\n " listValue currentAlpha[v] diff meshOp.setMapVert nn -2 v new_alpha_value ) ) ) ) ) ) --Clear list selection lbx_1.selection = #() My_alpha_test() --re-select verts of new value idx = findItem lbx_1.items (spn_1.value as String) lbx_1.selection = idx ba = #{} if idx != 0 then append ba idx My_alpha_select_verts ba for ii in selection do update ii ) -- on --*************************************************************************************** on dd_1 selected i do ( try ( select selection[i] ) catch() ) ) ------------------------------------------------------------------------------------------------------------------------- rollout AlphaDecalSelection "Alpha Poly Selector" ( local mapAlphaShaderList = #( #("alpha",true,true), #("decal",true,true), #("decal_amb_only",false,false), #("decal_dirt",false,false), #("decal_glue",false,false), #("decal_normal_only",false,false), #("decal_spec_only",false,false), #("decal_tnt",false,false), #("normal_alpha",false,false), #("normal_decal",false,false), #("normal_decal_tnt",false,false), #("normal_reflect_alpha",false,false), #("normal_reflect_decal",false,false), #("normal_reflect_screendooralpha",false,false), #("normal_screendooralpha",false,false), #("normal_spec_alpha",false,false), #("normal_spec_decal",false,false), #("normal_spec_decal_tnt",false,false), #("normal_spec_reflect_alpha",false,false), #("normal_spec_reflect_decal",false,false), #("normal_spec_reflect_emmisive_alpha",false,false), #("normal_spec_reflect_emmisivenight_alpha",false,false), #("normal_spec_screendooralpha",false,false), #("reflect_alpha",false,false), #("reflect_decal",false,false), #("spec_alpha",false,false), #("spec_decal",false,false), #("spec_reflect_alpha",false,false), #("spec_reflect_decal",false,false), #("spec_screendooralpha",false,false), #("water_decal",false,false) ) -- This function will select polygons that use a chosen shader fn findpolygons = ( -- Parse the array of shaders and look for the select ones chosenArray = #() for shaderindex = 1 to mapAlphaShaderList.count do ( if mapAlphaShaderList[shaderindex][3] == true then append chosenArray shaderindex ) -- chosenArray now holds the index of the shaders we are looking for. -- With an object selected foundShaderIndex=#() theSelection = getcurrentselection() if (theSelection.count == 1) do ( selObj = theSelection[1] -- Get the shader that is applied to the object if superclassof selObj == GeometryClass then ( appliedMaterial = selObj.material matcount = 1 try (matcount = appliedmaterial.count) catch() if matcount > 1 then ( --loop through the materials and get the shader names for submat = 1 to matcount do ( theMat = appliedmaterial[submat] -- Add a catch for standard materials RageShaderType = undefined try ( RageShaderType = RstGetShaderName theMat RageShaderType = (filterstring RageShaderType ".")[1] )catch() RageShaderType = RageShaderType as string -- Now look to see if that shader is in our list of ones we want to find. -- We have a list of indices to search for for shaderindex = 1 to chosenArray.count do ( searchIndex = chosenArray[shaderindex] if mapAlphaShaderList[searchindex][1] == RageShaderType then append foundShaderIndex submat ) ) --end subloop )-- end material list loop ) -- end is valid geo ) -- end selection -- foundShaderIndex now holds a list of materials IDs -- select them on the model if (theSelection.count == 1) do ( max modify mode subobjectLevel = 4 newFaceSel = #() for f = 1 to selObj.numfaces do ( for mat = 1 to foundShaderIndex.count do ( if classof selObj == Editable_mesh then ( if getFaceMatID selObj f == foundShaderIndex[mat] do append newFaceSel f ) if classof selObj == Editable_Poly then ( if polyop.getFaceMatID selObj f == foundShaderIndex[mat] do append newFaceSel f ) ) ) setFaceSelection selObj newFaceSel ) ) local ctrlOffset = [0,-2] checkbox chk_shader_alpha "Alpha" width:180 checked:true offset:ctrlOffset on chk_shader_alpha changed thestate do (mapAlphaShaderList[1][3] = chk_shader_alpha.checked) checkbox chk_shader_decal "Decal" width:180 checked:true offset:ctrlOffset on chk_shader_decal changed thestate do (mapAlphaShaderList[2][3] = chk_shader_decal.checked) checkbox chk_shader_decal_amb_only "Decal amb only" width:180 checked:false offset:ctrlOffset on chk_shader_decal_amb_only changed thestate do (mapAlphaShaderList[3][3] = chk_shader_decal_amb_only.checked) checkbox chk_shader_decal_dirt "Decal dirt" width:180 checked:false offset:ctrlOffset on chk_shader_decal_dirt changed thestate do (mapAlphaShaderList[4][3] = chk_shader_decal_dirt.checked) checkbox chk_shader_decal_glue "Decal glue" width:180 checked:false offset:ctrlOffset on chk_shader_decal_glue changed thestate do (mapAlphaShaderList[5][3] = chk_shader_decal_glue.checked) checkbox chk_shader_decal_normal_only "Decal normal only" width:180 checked:false offset:ctrlOffset on chk_shader_decal_normal_only changed thestate do (mapAlphaShaderList[6][3] = chk_shader_decal_normal_only.checked) checkbox chk_shader_decal_spec_only "Decal spec only" width:180 checked:false offset:ctrlOffset on chk_shader_decal_spec_only changed thestate do (mapAlphaShaderList[7][3] = chk_shader_decal_spec_only.checked) checkbox chk_shader_decal_tnt "Decal tnt" width:180 checked:false offset:ctrlOffset on chk_shader_decal_tnt changed thestate do (mapAlphaShaderList[8][3] = chk_shader_decal_tnt.checked) checkbox chk_shader_normal_alpha "Normal alpha" width:180 checked:false offset:ctrlOffset on chk_shader_normal_alpha changed thestate do (mapAlphaShaderList[9][3] = chk_shader_normal_alpha.checked) checkbox chk_shader_normal_decal "Normal decal" width:180 checked:false offset:ctrlOffset on chk_shader_normal_decal changed thestate do (mapAlphaShaderList[10][3] = chk_shader_normal_decal.checked) checkbox chk_shader_normal_decal_tnt "Normal decal tnt" width:180 checked:false offset:ctrlOffset on chk_shader_normal_decal_tnt changed thestate do (mapAlphaShaderList[11][3] = chk_shader_normal_decal_tnt.checked) checkbox chk_shader_normal_reflect_alpha "Normal reflect alpha" width:180 checked:false offset:ctrlOffset on chk_shader_normal_reflect_alpha changed thestate do (mapAlphaShaderList[12][3] = chk_shader_normal_reflect_alpha.checked) checkbox chk_shader_normal_reflect_decal "Normal reflect decal" width:180 checked:false offset:ctrlOffset on chk_shader_normal_reflect_decal changed thestate do (mapAlphaShaderList[13][3] = chk_shader_normal_reflect_decal.checked) checkbox chk_shader_normal_reflect_screendooralpha "Normal reflect screendooralpha" width:180 checked:false offset:ctrlOffset on chk_shader_normal_reflect_screendooralpha changed thestate do (mapAlphaShaderList[14][3] = chk_shader_normal_reflect_screendooralpha.checked) checkbox chk_shader_normal_screendooralpha "Normal screendooralpha" width:180 checked:false offset:ctrlOffset on chk_shader_normal_screendooralpha changed thestate do (mapAlphaShaderList[15][3] = chk_shader_normal_screendooralpha.checked) checkbox chk_shader_normal_spec_alpha "Normal spec alpha" width:180 checked:false offset:ctrlOffset on chk_shader_normal_spec_alpha changed thestate do (mapAlphaShaderList[16][3] = chk_shader_normal_spec_alpha.checked) checkbox chk_shader_normal_spec_decal "Normal spec decal" width:180 checked:false offset:ctrlOffset on chk_shader_normal_spec_decal changed thestate do (mapAlphaShaderList[17][3] = chk_shader_normal_spec_decal.checked) checkbox chk_shader_normal_spec_decal_tnt "Normal spec decal tnt" width:180 checked:false offset:ctrlOffset on chk_shader_normal_spec_decal_tnt changed thestate do (mapAlphaShaderList[18][3] = chk_shader_normal_spec_decal_tnt.checked) checkbox chk_shader_normal_spec_reflect_alpha "Normal spec reflect alpha" width:180 checked:false offset:ctrlOffset on chk_shader_normal_spec_reflect_alpha changed thestate do (mapAlphaShaderList[19][3] = chk_shader_normal_spec_reflect_alpha.checked) checkbox chk_shader_normal_spec_reflect_decal "Normal spec reflect decal" width:180 checked:false offset:ctrlOffset on chk_shader_normal_spec_reflect_decal changed thestate do (mapAlphaShaderList[20][3] = chk_shader_normal_spec_reflect_decal.checked) checkbox chk_shader_normal_spec_reflect_emmisive_alpha "Normal spec reflect emmisive alpha" width:180 checked:false offset:ctrlOffset on chk_shader_normal_spec_reflect_emmisive_alpha changed thestate do (mapAlphaShaderList[21][3] = chk_shader_normal_spec_reflect_emmisive_alpha.checked) checkbox chk_shader_normal_spec_reflect_emmisivenight_alpha "Normal spec reflect emmisivenight alpha" width:180 checked:false offset:ctrlOffset on chk_shader_normal_spec_reflect_emmisivenight_alpha changed thestate do (mapAlphaShaderList[22][3] = chk_shader_normal_spec_reflect_emmisivenight_alpha.checked) checkbox chk_shader_normal_spec_screendooralpha "Normal spec screendooralpha" width:180 checked:false offset:ctrlOffset on chk_shader_normal_spec_screendooralpha changed thestate do (mapAlphaShaderList[23][3] = chk_shader_normal_spec_screendooralpha.checked) checkbox chk_shader_reflect_alpha "Reflect alpha" width:180 checked:false offset:ctrlOffset on chk_shader_reflect_alpha changed thestate do (mapAlphaShaderList[24][3] = chk_shader_reflect_alpha.checked) checkbox chk_shader_reflect_decal "Reflect decal" width:180 checked:false offset:ctrlOffset on chk_shader_reflect_decal changed thestate do (mapAlphaShaderList[25][3] = chk_shader_reflect_decal.checked) checkbox chk_shader_spec_alpha "Spec alpha" width:180 checked:false offset:ctrlOffset on chk_shader_spec_alpha changed thestate do (mapAlphaShaderList[26][3] = chk_shader_spec_alpha.checked) checkbox chk_shader_spec_decal "Spec decal" width:180 checked:false offset:ctrlOffset on chk_shader_spec_decal changed thestate do (mapAlphaShaderList[27][3] = chk_shader_spec_decal.checked) checkbox chk_shader_spec_reflect_alpha "Spec reflect alpha" width:180 checked:false offset:ctrlOffset on chk_shader_spec_reflect_alpha changed thestate do (mapAlphaShaderList[28][3] = chk_shader_spec_reflect_alpha.checked) checkbox chk_shader_spec_reflect_decal "Spec reflect decal" width:180 checked:false offset:ctrlOffset on chk_shader_spec_reflect_decal changed thestate do (mapAlphaShaderList[29][3] = chk_shader_spec_reflect_decal.checked) checkbox chk_shader_spec_screendooralpha "Spec screendooralpha" width:180 checked:false offset:ctrlOffset on chk_shader_spec_screendooralpha changed thestate do (mapAlphaShaderList[30][3] = chk_shader_spec_screendooralpha.checked) checkbox chk_shader_water_decal "Water decal" width:180 checked:false offset:ctrlOffset on chk_shader_water_decal changed thestate do (mapAlphaShaderList[31][3] = chk_shader_water_decal.checked) -- Update the UI based on the Select All checkbox fn updateChoices togglestate mapAlphaShaderList= ( for shaderindex = 1 to mapAlphaShaderList.count do ( if togglestate == true then ( execute ("AlphaDecalSelection.chk_shader_" + mapAlphaShaderList[shaderindex][1] + ".state = true") mapAlphaShaderList[shaderindex][3] = true ) if togglestate == false then ( execute ("AlphaDecalSelection.chk_shader_" + mapAlphaShaderList[shaderindex][1] + ".state = " + (mapAlphaShaderList[shaderindex][2] as string)) mapAlphaShaderList[shaderindex][3] = mapAlphaShaderList[shaderindex][2] ) ) ) checkbox chk_shader_all "*Select All/Reset to Defaults*" width:180 on chk_shader_all changed thestate do (updateChoices thestate mapAlphaShaderList) button btn_SelectPolygons "Select Polygons" width:140 height:30 on btn_SelectPolygons pressed do findpolygons() on AlphaDecalSelection open do ( ) ) ------------------------------------------------------------------------------------------------------------------------- rollout MaterialSelection "Material Selector" ( --------------------------------------------------------- -- USER INTERFACE --------------------------------------------------------- group "Select Poly by Shader Type" ( dropdownlist ddl_shader "" width:210 button btn_shaderAddPoly "Select Polys" width:100 across:2 button btn_shaderRemovePoly "Deselect Polys" width:100 checkbox cxb_ShaderClearSelection "Clear Selected Polys First" width:210 checked:true ) group "Mat ID Add/Remove To/From Selection" ( Spinner spn_mapID "" width:50 across:3 offset:[-25,3] type:#integer button btn_ID_add "Select" width:75 offset:[-10,0] button btn_ID_remove "Deselect" width:75 checkbox cxb_IdClearSelection "Clear Selected Polys First" width:210 checked:true button btn_GrowID "Select All Matching ID Faces" width:210 ) --------------------------------------------------------- -- FUNCTIONS --------------------------------------------------------- fn populateShaderList = ( local materials = #() local items = #() for obj in selection where ( GetAttrClass obj == "Gta Object" ) do join materials (RsGetMaterialsOnObjFaces obj) materials = makeUniqueArray materials for mat in materials where (ClassOf mat == Rage_Shader) do appendIfUnique items (RstGetShaderName mat) sort items ddl_shader.items = items ) --------------------------------------------------------- fn selectFaceByID obj ID switch = ( currentSel = getFaceSelection obj newFaceSel = #() for f = 1 to obj.numfaces do ( if (classof obj == Editable_poly) AND (polyop.getFaceMatID obj f) == ID do append newFaceSel f if (classof obj == Editable_mesh) AND (getFaceMatID obj f) == ID do append newFaceSel f ) ------------------------- if (switch == #add) do newSel = (currentSel) as bitArray + (newFaceSel) as bitArray if (switch == #remove) do newSel = (currentSel) as bitArray - (newFaceSel) as bitArray ------------------------- setFaceSelection obj newSel ) --------------------------------------------------------- fn addRemovePolyByID switch = ( for obj in selection where ( GetAttrClass obj == "Gta Object" ) do ( if (cxb_IdClearSelection.state) do setFaceSelection obj #{} selectFaceByID obj spn_mapID.value switch ) ) --------------------------------------------------------- fn selectPolyByMaterial switch = ( local selObjs = for obj in selection where (GetAttrClass obj == "Gta Object") collect obj if (selObjs.count != 0) do for obj in selObjs do ( if (cxb_ShaderClearSelection.state) do setFaceSelection obj #{} local mat = obj.material if (isKindOf mat Multimaterial) then ( local matIDArray = #() for i=1 to mat.materialIDList.count where (isKindOf mat.materialList[i] Rage_Shader) do ( if ((RstGetShaderName mat.materialList[i]) == ddl_shader.selected) do append matIDArray mat.materialIDList[i] ) for ID in matIDArray do selectFaceByID obj ID switch ) else if (isKindOf mat Rage_Shader) do ( (rsmeshpolyop obj).setFaceSelection obj #{1..(obj.numfaces)} ) ) ) --------------------------------------------------------- fn growMaterialID = ( if (selection.count == 1) then ( local uniqueSelectedFaceIDSet = #() local obj = selection[1] local isMesh = (classof obj == Editable_Mesh) local isPoly = (classof obj == Editable_Poly) local faceIndexSelectionArray = if (isMesh) then (for i in obj.selectedFaces collect i.index) else if (isPoly) then (polyop.getFaceSelection obj as array) for faceIndex in faceIndexSelectionArray do ( local selectedFaceID = if (isMesh) then (getFaceMatID obj faceIndex) else if (isPoly) then ( polyop.getFaceMatID obj faceIndex) appendIfUnique uniqueSelectedFaceIDSet selectedFaceID ) newFaceSel = #() for f = 1 to obj.numfaces do ( local faceID = if (isMesh) then (getFaceMatID obj f) else if (isPoly) then (polyop.getFaceMatID obj f) for toBeSelectedID in uniqueSelectedFaceIDSet where (faceID == toBeSelectedID) do append newFaceSel f ) setFaceSelection obj newFaceSel completeRedraw() ) else ( if (selection.count == 0) then messagebox "Select an object first" title:"Error" else messagebox "Select only 1 object" title:"Error" ) ) --------------------------------------------------------- -- EVENTS --------------------------------------------------------- on btn_shaderAddPoly pressed do selectPolyByMaterial #add on btn_shaderRemovePoly pressed do selectPolyByMaterial #remove on btn_ID_add pressed do addRemovePolyByID #add on btn_ID_remove pressed do addRemovePolyByID #remove on btn_GrowID pressed do growMaterialID() --------------------------------------------------------- on MaterialSelection open do ( callbacks.addScript #selectionSetChanged "MaterialSelection.populateShaderList()" id:#MaterialSelection populateShaderList() ) --------------------------------------------------------- on MaterialSelection close do ( callbacks.removeScripts id:#MaterialSelection ) ) ------------------------------------------------------------------------------------------------------------------------- rollout RsSelectionTools_Rollout "R* Selection Tools" ( dotNetControl rsBannerPanel "Panel" pos:[0,0] height:32 width:(RsSelectionTools_Rollout.width) local banner = makeRsBanner versionNum:1.11 versionName:"Wilty Pigeon" dn_Panel:rsBannerPanel dotNetControl dn_tabs "System.Windows.Forms.TabControl" height:20 width:(RsSelectionTools_Rollout.width) align:#center pos:[-1, (RsBannerPanel.height + 2)] subRollout theSubRollout height:750 align:#center width:(RsSelectionTools_Rollout.width) pos:[0, dn_tabs.pos.y + dn_tabs.height] local lastClickNum local maxAutoHeight = 900 local keepWidth local tabRollouts = #( dataPair name:"Geometry" rollouts:#(GeometrySelection), dataPair name:"Vert Alpha" rollouts:#(VertexAlphaSelection), dataPair name:"Alpha Decal" rollouts:#(AlphaDecalSelection), dataPair name:"Material" rollouts:#(MaterialSelection) ) fn setSubrollSize = ( theSubRollout.height = (RsSelectionTools_Rollout.height - theSubRollout.pos.y) ) fn showTab clickNum = ( if (lastClickNum != clickNum) do --do not update if the same tab clicked twice ( lastClickNum = clickNum for subRoll in theSubRollout.rollouts do ( removeSubRollout theSubRollout subroll ) local setHeight = theSubRollout.pos.y + 6 for subRoll in tabRollouts[clickNum].rollouts do ( addSubRollout theSubRollout subRoll setHeight += (subRoll.height + 24) ) if (setHeight > maxAutoHeight) do ( setHeight = maxAutoHeight ) RsSelectionTools_Rollout.height = setHeight setSubrollSize() ) ) on dn_tabs Selected itm do ( local clickNum = (itm.TabPageIndex + 1) showTab clickNum RsSettingWrite "RsSelectionTools" "lastTab" tabRollouts[clickNum].name ) on RsSelectionTools_Rollout resized newSize do ( if (newSize.x != keepWidth) and (keepWidth != undefined) do ( RsSelectionTools_Rollout.width = keepWidth ) setSubrollSize() ) on RsSelectionTools_Rollout open do ( banner.setup() keepWidth = RsSelectionTools_Rollout.width local savedTabName = RsSettingsReadString "RsSelectionTools" "lastTab" undefined local savedTabNum = 1 for tabNum = 1 to tabRollouts.count do ( local tabName = tabRollouts[tabNum].name dn_tabs.TabPages.add tabName if (tabName == savedTabName) do ( savedTabNum = tabNum ) ) dn_tabs.SelectedIndex = (savedTabNum - 1) showTab savedTabNum ) ) createDialog RsSelectionTools_Rollout 250 400 style:#(#style_resizing,#style_titlebar, #style_toolwindow, #style_sysmenu)