/* Grid Slice Author: Jason Hayes (jason.hayes@rockstarsandiego.com) Description: Slices the selected objects based on the specified grid dimensions. */ filein "pipeline/util/rect.ms" try( destroyDialog RsGridSliceUI ) catch () struct RsGridSlicePreset ( name = "Default", isDefault = false, gridMin = Point2 -4096 -4096, gridMax = Point2 4096 4096, gridSize = Point2 512 512 ) struct RsGridSlice ( --public presets = dotNetObject "System.Collections.Hashtable", activePreset = undefined, deleteOriginals = false, --private virtualGrid = #(), fn generateVirtualGrid = ( this.virtualGrid = #() local numRows = ( ( this.activePreset.gridMax.x - this.activePreset.gridMin.x ) / this.activePreset.gridSize.x ) as integer local numColumns = ( ( this.activePreset.gridMax.y - this.activePreset.gridMin.y ) / this.activePreset.gridSize.y ) as integer local x = this.activePreset.gridMin.x local y = this.activePreset.gridMin.y for row = 1 to numRows do ( for column = 1 to numColumns do ( local rect = RsRect() rect.bbox_min = [ x, y ] rect.bbox_max = [ x + this.activePreset.gridSize.x, y + this.activePreset.gridSize.y ] append this.virtualGrid rect x += this.activePreset.gridSize.x ) x = this.activePreset.gridMin.x y += this.activePreset.gridSize.y ) ), --public fn loadPresets = ( local presetsFile = RSMakeSafeSlashes ( RsConfigGetWildWestDir() + "etc/config/general/gridSliceSettings.xml" ) if ( doesFileExist presetsFile ) then ( local stream = dotNetObject "System.IO.StreamReader" presetsFile local doc = dotNetObject "System.Xml.XmlDocument" doc.load stream root = doc.documentElement presetNodes = ( root.SelectNodes ".//preset" ) for idx = 0 to ( presetNodes.count - 1 ) do ( local preset = RsGridSlicePreset() local presetNode = presetNodes.item[ idx ] preset.name = presetNode.attributes.itemOf[ 0 ].value preset.isDefault = ( presetNode.attributes.itemOf[ 1 ].value ) as BooleanClass local minRaw = ( presetNode.SelectNodes ".//min" ).Item[ 0 ].InnerXml local maxRaw = ( presetNode.SelectNodes ".//max" ).Item[ 0 ].InnerXml local sizeRaw = ( presetNode.SelectNodes ".//size" ).Item[ 0 ].InnerXml local minData = filterString minRaw "," local maxData = filterString maxRaw "," local sizeData = filterString sizeRaw "," preset.gridMin = Point2 ( minData[ 1 ] as Double ) ( minData[ 2 ] as Double ) preset.gridMax = Point2 ( maxData[ 1 ] as Double ) ( maxData[ 2 ] as Double ) preset.gridSize = Point2 ( sizeData[ 1 ] as Double ) ( sizeData[ 2 ] as Double ) this.presets.Add preset.name ( dotNetMXSValue preset ) if preset.isDefault == True then ( this.activePreset = preset ) ) doc = undefined ) else ( messageBox ( "Could not locate gridSliceSettings.xml! Was expecting it here:\n\n" + presetsFiles + "\n\nUsing default settings." ) title:"Grid Slice" local preset = RsGridSlicePreset() preset.activePreset = preset preset.isDefault = True this.presets.Add preset.name ( dotNetMXSValue preset ) ) ), fn addSlice obj posX posY orientation = ( undo off ( local objTM = obj.objectTransform local sliceMod = SliceModifier() addModifier obj sliceMod local modTM = getModContextTM obj sliceMod sliceMod.Slice_Type = 2 --remove top case orientation of ( #left:sliceMod.Slice_Plane.Rotation = (quat 0 -0.707107 0 0.707107) #right:sliceMod.Slice_Plane.Rotation = (quat 0 0.707107 0 0.707107) #up:sliceMod.Slice_Plane.Rotation = (quat -0.707107 0 0 0.707107) #down:sliceMod.Slice_Plane.Rotation = (quat 0.707107 0 0 0.707107) ) sliceMod.Slice_Plane.Position = [posX, posY, 0] * modTM * (inverse objTM) ) ), fn slice objs = ( if objs.count > 0 then ( max hold suspendEditing() local slicedObjs = #() --undo "Grid Slice" on ( this.generateVirtualGrid() for obj in objs do ( if ( superClassOf obj ) == GeometryClass then ( local objRect = RsRect() objRect.createFromObject obj -- TODO: Checking for intersections will not scale very well with this method. -- Doing this brute force just to get it in and working. local ixRects = #() for gridRect in this.virtualGrid do ( if ( objRect.intersects gridRect ) then ( append ixRects gridRect ) ) -- Create a copy of the object so that we can slice it up instead of the original. local slicedObj = copy obj slicedObj.name = obj.name + "_sliced" local objTM = obj.objectTransform -- Slice the object for each grid cell that it intersected. for ixRect in ixRects do ( -- North local northSliceMod = SliceModifier() addModifier slicedObj northSliceMod local modTM = getModContextTM slicedObj northSliceMod local offsetNorth = ( ixRect.top() ) -- obj.pos.y northSliceMod.Slice_Plane.rotation = Quat 1 0 0 1 northSliceMod.Slice_Plane.position = [slicedObj.pos.x, offsetNorth, 0] * modTM * (inverse objTM) northSliceMod.Slice_Type = 1 -- East local eastSliceMod = SliceModifier() addModifier slicedObj eastSliceMod local modTM = getModContextTM slicedObj eastSliceMod local offsetEast = ( ixRect.left() ) -- obj.pos.x eastSliceMod.Slice_Plane.rotation = Quat 0 1 0 1 eastSliceMod.Slice_Plane.position = [offsetEast, slicedObj.pos.y, 0] * modTM * (inverse objTM) eastSliceMod.Slice_Type = 1 -- South local southSliceMod = SliceModifier() addModifier slicedObj southSliceMod local modTM = getModContextTM slicedObj southSliceMod local offsetSouth = ( ixRect.bottom() ) -- obj.pos.y southSliceMod.Slice_Plane.rotation = Quat -1 0 0 1 southSliceMod.Slice_Plane.position = [slicedObj.pos.x, offsetSouth, 0] * modTM * (inverse objTM) southSliceMod.Slice_Type = 1 -- West local westSliceMod = SliceModifier() addModifier slicedObj westSliceMod local modTM = getModContextTM slicedObj westSliceMod local offsetWest = ( ixRect.right() ) -- obj.pos.x westSliceMod.Slice_Plane.rotation = Quat 0 -1 0 1 westSliceMod.Slice_Plane.position = [offsetWest, slicedObj.pos.y, 0] * modTM * (inverse objTM) westSliceMod.Slice_Type = 1 collapseStack slicedObj ) append slicedObjs slicedObj if deleteOriginals then ( delete obj ) else ( slicedObj.parent = obj obj.isHidden = true ) ) --) ) resumeEditing() slicedObjs ) else ( messageBox "You must supply at least one object to slice!" title:"Grid Slice" ) ) ) rollout RsGridSliceUI "Grid Slice" ( local gridSlice = RsGridSlice() dropDownList ddlPresets "Presets:" width:190 offset:[ -7, 0 ] button btnSliceSelected "Slice Selected" width:190 height:24 checkbox chkDeleteOriginal "Delete Original" group "Grid Dimensions" ( spinner spGridMinX "Min X:" range:[ -99999.0, 99999.0, 0 ] type:#float spinner spGridMinY "Min Y:" range:[ -99999.0, 99999.0, 0 ] type:#float spinner spGridMaxX "Max X:" range:[ -99999.0, 99999.0, 0 ] type:#float spinner spGridMaxY "Max Y:" range:[ -99999.0, 99999.0, 0 ] type:#float spinner spGridCellWidth "Cell Width:" range:[ -99999.0, 99999.0, 0 ] type:#float spinner spGridCellHeight "Cell Height:" range:[ -99999.0, 99999.0, 0 ] type:#float ) -- Functions fn refresh = ( local presetNames = #() local presetEnum = gridSlice.presets.GetEnumerator() while ( presetEnum.MoveNext() ) do ( append presetNames presetEnum.Key ) ddlPresets.items = presetNames local activePreset = gridSlice.activePreset if activePreset != undefined then ( spGridMinX.value = activePreset.gridMin.x spGridMinY.value = activePreset.gridMin.y spGridMaxX.value = activePreset.gridMax.x spGridMaxY.value = activePreset.gridMax.y spGridCellWidth.value = activePreset.gridSize.x spGridCellHeight.value = activePreset.gridSize.y ) else ( messageBox "There is no default preset defined for this tool! You really shouldn't see this. Please contact your local Technical Artist." title:"Grid Slice" ) ) -- Event Handlers on RsGridSliceUI open do ( gridSlice.loadPresets() refresh() -- Set drop down list to default preset on load. The initial active preset wil be the default. idx = 1 for presetName in ddlPresets.items do ( if presetName == gridSlice.activePreset.name then ( ddlPresets.selection = idx ) idx += 1 ) ) on btnSliceSelected pressed do ( local objs = selection as array if objs.count > 0 then ( gridSlice.deleteOriginals = chkDeleteOriginal.checked gridSlice.slice objs ) else ( messageBox "Please select at least one object!" title:"Grid Slice" ) ) on ddlPresets selected val do ( local preset = gridSlice.presets.Item[ ddlPresets.Selected ].value gridSlice.activePreset = preset refresh() ) on spGridMinX changed val do ( gridSlice.activePreset.gridMin.x = val ) on spGridMinY changed val do ( gridSlice.activePreset.gridMin.y = val ) on spGridMaxX changed val do ( gridSlice.activePreset.gridMax.x = val ) on spGridMaxY changed val do ( gridSlice.activePreset.gridMax.y = val ) on spGridCellWidth changed val do ( gridSlice.activePreset.gridSize.x = val ) on spGridCellHeight changed val do ( gridSlice.activePreset.gridSize.y = val ) ) createDialog RsGridSliceUI width:200 height:250