/*** POM under IP removal tool load the data maps for IP and combine them to get a 1-bit pixel map marking where any IP is apply to a world map sized plane and place in the scene now for any container meshes of interest fire a ray from the face centre up into the IP plane where we find a hit then the face needs to be markd for change Once all the faces for a particular mesh are collected swap the material for a non POM version. Look at the surrounding faces. If any of them are POM materials, then we need to fade out that border ***/ filein (RsConfigGetWildWestDir() + "script/3dsmax/_config_files/wildwest_header.ms") filein (RsConfigGetToolsDir() + "dcc/current/max2012/scripts/pipeline/helpers/terrain/terrain_funcs.ms") struct POMUnderIP ( __DEBUG__ = false, IPMaskPath = (RsConfigGetWildWestDir() + "assets/image_files/IP_Distribution_FINAL.png"), IPMask, worldMapSize = [9150, 12450], worldOffset = [4050, 4050], worldBottomCorner = [-4050, -4050], bitmapOrigin = [4050, 8400], --selectionBounds = #([0, 0, 0], [0, 0, 0]), xPixelPitch, yPixelPitch, pxmMapPath = ( RsConfigGetWildWestDir() + "script/3dsMax/maps/PxmMap.ini"), cs_PolyClip = undefined, coverageThreshold = 0.95, --maskCache = #{}, maskCoverageValues= #(), coverageList = #(), pixelCoordsList = #(), mapChannel = 4, getVertsUsingFaceOp, facesUsingVertOp, mainProgress, /*** return the mask value from a given pixel coord black pixel is masked, white is not ***/ fn getMaskValue coords = ( if __DEBUG__ then ( format "pixelmask: % \n" coords appendifunique pixelCoordsList coords ) masked = false --check coords are within image range if (coords.x < 0) or (coords.x > IPMask.width) or (coords.y < 0) or (coords.y > IPMask.height) then ( return undefined ) local pixelValue = (getPixels IPMask coords 1)[1] if (pixelValue == (color 0 0 0)) then ( masked = true appendifunique pixelCoordsList coords ) --return masked ), /*** ***/ fn getMaskCacheValue coords = ( masked = false --check coords are within image range if (coords.x < 0) or (coords.x > IPMask.width) or (coords.y < 0) or (coords.y > IPMask.height) then ( return undefined ) --build coord lookup into maskCache local cacheCoord = (coords.y * IPMask.width) + coords.x --retval maskCache[cacheCoord] ), /*** Get the 2d bounds of the face using it vertex positions return a datapair min:Point2 max:Point2 ***/ fn get2DFaceBounds vertPosList = ( local bounds = DataPair min:Point2 max:Point2 --initial values local minX = worldMapSize.x local minY = worldMapSize.y local maxX = -worldOffset.x local maxY = -worldOffset.y for pos in vertPosList do ( if pos.x < minX then minX = pos.x if pos.x > maxX then maxX = pos.x if pos.y < minY then minY = pos.y if pos.y > maxY then maxY = pos.y ) bounds.min = [minX, minY] bounds.max = [maxX, maxY] if __DEBUG__ do ( box pos:[(minX + (0.5 * (maxX - minX))), (minY + (0.5 * (maxY- minY))), 0] length:(maxY - minY) width:(maxX - minX) height:10 ) --return bounds ), /*** ***/ fn getWPosFromPixel pixelLoc debug:false = ( --local x = worldBottomCorner.x + pixelLoc.x local x = pixelLoc.x - bitmapOrigin.x --local y = worldBottomCorner.y + pixelLoc.y --local y = pixelLoc.y - worldBottomCorner.y local y = worldBottomCorner.y + (worldMapSize.y - pixelLoc.y) local transformPt = [x, y] if __DEBUG__ then ( box name:"WPosFromPixel" pos:[transformPt.x, transformPt.y, 0] length:1.0 width:1.0 height:1.0 ) --return transformPt ), /*** with a supplied DataPair min: max: object return the corresponding pixel bounds ***/ fn get2DPixelBounds faceBounds = ( local bounds = DataPair min:Point2 max:Point2 /* local minX = (worldOffset.x + faceBounds.min.x + 1.0) as Integer local maxX = (worldOffset.x + faceBounds.max.x + 1.0) as Integer local minY = (worldOffset.y + faceBounds.min.y + 1.0) as Integer local maxY = (worldOffset.y + faceBounds.max.y + 1.0) as Integer */ local minX = (worldOffset.x + faceBounds.min.x) as Integer local maxX = (worldOffset.x + faceBounds.max.x) as Integer local minY = (worldMapSize.y - worldOffset.y - faceBounds.min.y) as Integer local maxY = (worldMapSize.y - worldOffset.y - faceBounds.max.y) as Integer if maxY < minY then ( swap minY maxY ) --Dilate the bounds by 1 pixel minX -= 1 minY -= 1 maxX += 1 maxY += 1 bounds.min = [minX, minY] bounds.max = [maxX, maxY] if __DEBUG__ then ( local boxPos = getWPosFromPixel [(minX + (0.5 * (maxX - minX))), (minY + (0.5 * (maxY- minY))), 0] box name:"2DPixelBounds" pos:[boxPos.x, boxPos.y, 0] length:(maxY - minY) width:(maxX - minX) height:10 ) --return bounds ), /*** ***/ fn getPixelFromWPos wPos = ( [((bitmapOrigin.x + wPos.x) as Integer), ((bitmapOrigin.y - wPos.y) as Integer)] --[((worldOffset.x + wPos.x) as Integer), ((worldOffset.y + wPos.y) as Integer)] ), fn wedge a b = ( (a.x as Double) * (b.y as Double) - (a.y as Double) * (b.x as Double) ), fn getPolyArea2D pts = ( local polyArea = 0.0 for i=1 to pts.count do ( local nextPoint = if ((i+1) > pts.count) then pts[1] else pts[i+1] polyArea += wedge pts[i] nextPoint ) polyArea / 2.0 ), /*** __DEBUG__ function to build spline representation of clipped polygons ***/ fn makeDebugSpline centre pts = ( debugSpline = splineShape pos:centre addNewSpline debugSpline for pt in pts do ( addKnot debugSpline 1 #corner #line pt ) updateShape debugSpline ), /*** Work out which pixels the poly edge will pass through ***/ fn walkTheLine pixels start end = ( local edgeLength = distance start end local step = 0.05 local walk = 0.0 while (walk < (edgeLength + step)) do ( local curPos = start + (walk * ((end - start) / (edgeLength + step))) local pixelPos = getPixelFromWPos [curPos.x, curPos.y] appendifunique pixels pixelPos walk += step ) if __DEBUG__ then ( for item in pixels do ( local debugPos = getWPosFromPixel item --local debugPos = item box name:"pixelPos" pos:[(debugPos.x + 0.5), (debugPos.y + 0.5), 0] length:1 width:1 height:1 ) ) --return pixels ), /*** determine how much of the face is covered by mask pixels using the face vertex positions of the pixels it covers get the ones that are set to mask get a ratio between the pixels that mask and those that dont and use that as a basis to decide if the face should have a shader switch ***/ fn getMaskCoverage vPosList = ( local coverage = 0.0 local faceBounds = get2DFaceBounds vPosList --debug:__DEBUG__ --we need the 2d face area local faceArea = abs(getPolyArea2D vPosList) if __DEBUG__ do format "faceArea: % \n" faceArea --get pixels within bounds local pixelBounds = get2DPixelBounds faceBounds --debug:__DEBUG__ --for poly edge testing later local polyPoints = for vPos in vPosList collect (dotNetObject "System.Windows.Point" vPos.x vPos.y) --find the poly edge pixel intersections local polyEdgeSamples = #() for pt=1 to vPosList.count do ( local thisPoint = vPosList[pt] local nextPoint = if ((pt+1) > vPosList.count) then vPosList[1] else vPosList[pt+1] --local nextPixel = nextPoint --format "thisPixel: % nextPixel: % \n" thisPixel nextPixel local samples = #() walkTheLine samples thisPoint nextPoint join polyEdgeSamples samples ) polyEdgeSamples = makeUniqueArray polyEdgeSamples --format "polyEdgeSamples: % \n" polyEdgeSamples if __DEBUG__ then ( for samp in polyEdgeSamples do ( local pos = getWPosFromPixel samp box name:"edgesample" pos:[(pos.x + 0.5), (pos.y - 0.5), 0] length:1.0 width:1.0 height:1.0 ) ) --Process the pixels in the pixelBounds local pixelBoundsX = if ((pixelBounds.max.x - pixelBounds.min.x) - 1) < 1 then 1 else ((pixelBounds.max.x - pixelBounds.min.x) - 1) local pixelBoundsY = if ((pixelBounds.max.y - pixelBounds.min.y) - 1) < 1 then 1 else ((pixelBounds.max.y - pixelBounds.min.y) - 1) for x=0 to pixelBoundsX do ( for y=0 to pixelBoundsY do ( local thisPixel = [(pixelBounds.min.x + x), (pixelBounds.min.y + y)] --we can save time by only calculating coverage for mask pixels(black) --assume the rest of the tri area is unmasked --so get the pixel value first local isMaskPixel = getMaskValue thisPixel --local isMaskPixel = getMaskCacheValue thisPixel --format "isMaskPixel: % pixel: % \n" isMaskPixel thisPixel --Check if this pixel within the pixel bounds is already marked to be dealt with from the earlier polyEdgeSamples list local isEdgePixel = if (findItem polyEdgeSamples thisPixel !=0) then true else false --is the pixel outside the poly, partially, or completely inside --test the pixel corners against the polygon. --test the 4 corners of the pixel against the triangle local pixelSamplesCovered = #{} --corner coords built clockwise starting top left local pixelSamples = #() --corners append pixelSamples [thisPixel.x, thisPixel.y, 0] append pixelSamples [(thisPixel.x + 1), thisPixel.y, 0] append pixelSamples [(thisPixel.x + 1), (thisPixel.y + 1), 0] append pixelSamples [thisPixel.x, (thisPixel.y + 1), 0] --convert sample pixel locations back into world coords local samples = for pixel in pixelSamples collect getWPosFromPixel pixel --debug:__DEBUG__ /* if __DEBUG__ then ( for samp in samples do ( Dummy pos:[(samp.x - 0.5), (samp.y - 0.5), 0] boxsize:[1,1,1] ) ) */ --Point name:"samplePoint" pos:[samples[5].x, samples[5].y, 0] size:1.0 --break() --if its out, its not important --if its partial calculate the partial coverage --iff its full just add the full pixel are to the coverage if isEdgePixel then ( if __DEBUG__ do print "Edge Pixel" local pixelPoints = #( (dotNetObject "System.Windows.Point" samples[1].x samples[1].y), (dotNetObject "System.Windows.Point" samples[2].x samples[2].y), (dotNetObject "System.Windows.Point" samples[3].x samples[3].y), (dotNetObject "System.Windows.Point" samples[4].x samples[4].y) ) local clippedPoly local clippedPolyPts = #() try ( clippedPoly = cs_PolyClip.GetIntersectedPolygon pixelPoints polyPoints clippedPolyPts = for pt in clippedPoly collect [(pt.x as Double), (pt.y as Double)] ) catch ( print "GetIntersectedPolygon Error" print samples if __DEBUG__ then ( for item in samples do ( Point name:"Error" pos:[item.x, item.y, 0] size:1 ) ) ) --__DEBUG__ draw the clipped polygons if __DEBUG__ and clippedPolyPts.count != 0 then ( local splinePts = #() for pt=1 to clippedPolyPts.count do ( local thisPoint = clippedPolyPts[pt] local nextPoint = if ((pt+1) > clippedPolyPts.count) then clippedPolyPts[1] else clippedPolyPts[pt+1] append splinePts [thisPoint.x, thisPoint.y, 0] append splinePts [nextPoint.x, nextPoint.y, 0] ) makeDebugSpline [0,0,0] splinePts ) --Collect up the area that the poly gives if clippedPolyPts.count != 0 then ( local clippedPolyArea = abs(getPolyArea2D clippedPolyPts) if __DEBUG__ do format "clippedPolyArea: % \n" clippedPolyArea if isMaskPixel then ( coverage += clippedPolyArea ) ) ) else ( --Check which pixels intersect the polygon for pt=1 to samples.count do ( local insidePoly = RSGeom_PointInPolygon samples[pt] vPosList if insidePoly then ( pixelSamplesCovered[pt] = true ) ) if __DEBUG__ do format "pixelSamplesCovered: %\n" pixelSamplesCovered.numberSet if (pixelSamplesCovered.numberSet == 0) then --this pixel contributes nothing ( if __DEBUG__ do print "Excluded pixel" --continue ) else if (pixelSamplesCovered.numberSet == samples.count) and isMaskPixel then --its fully within the poly ( if __DEBUG__ do print "Included pixel" coverage += 1.0 --continue ) ) ) ) --using what we've got work out how much of the face area is covered by mask pixels --return local retval = 0.0 if (coverage > 0.0) then ( retval = (1.0 / faceArea) * coverage ) if __DEBUG__ do format "Coverage: % \n" retVal --format "Coverage: % \n" retVal append coverageList retVal --break() retval ), /*** Check the face against the IPMask to see if it needs a shader swap ***/ fn checkFaceIPMask theMesh face = ( --print face local faceVerts = polyop.getFaceVerts theMesh face --check the positions of the verts in relation to the IPMask local vPosList = for vert in faceVerts collect polyop.getvert theMesh vert --local faceArea = polyop.getFaceArea theMesh face --get the trinagle bounds in pixel space --now test each pixel centre against the face --for pixels in the face find any that are mask local maskCoverage = getMaskCoverage vPosList --faceArea --break() --format "maskCoverage: % \n" maskCoverage append maskCoverageValues maskCoverage local needsSwap = if (maskCoverage > coverageThreshold) then true else false --return needsSwap ), /*** Check for t-vert faces ***/ fn findTVertFaces obj = ( local tVertFaces = #{} for face in obj.faces where ((polyop.getFaceDeg $ face.index) > 3) do ( --get the verts for the face local faceVerts = polyop.getFaceVerts $ face.index for vtx = 1 to faceVerts.count do ( local thisVtx = faceVerts[vtx] local midVtx = if (vtx+1) > faceVerts.count then faceVerts[1] else faceVerts[(vtx+1)] local nextVtx = if (vtx+2) > faceVerts.count then faceVerts[2] else faceVerts[(vtx+2)] --compare the dot between the two edges local thisVertPos = polyop.getvert obj thisVtx local midVertPos = polyop.getvert obj midVtx local nextVertPos = polyop.getvert obj nextVtx local diff = abs(dot (normalize(midVertPos - thisVertPos)) (normalize(nextVertPos - thisVertPos))) --print diff if diff > 0.99 then append tVertFaces face.index ) ) obj.selectedFaces = tVertFaces --return (tVertFaces.numberSet > 0) ), /*** ***/ fn findBorderVerts obj faces = ( local faceBitArray = faces as BitArray local faceVerts = getVertsUsingFaceOp obj faceBitArray local borderVerts = #() for vert in faceVerts do ( vertFaces = facesUsingVertOp obj vert --if all the faces are not in selected faces then its a border vert local diff = (faceBitArray * vertFaces).numberSet if diff < vertFaces.numberSet then ( append borderVerts vert ) ) --return borderVerts ), /*** ***/ fn getMapVertLookup objNode = ( local getMapFaceOp = RsGetMapFaceFunc objNode local getFaceVerts = RsGetFaceFunc objNode local mapVertLookup = for n = 1 to objNode.verts.count collect #{} -- Build geometry-to-UV vertex-lookup list, to allow us to find equivalent indexes quickly... subProgress = mainProgress.StartSubProgress 0 objNode.faces.count SubTitle:"Build vertex lookup.." subProgress.Start() for FaceNum = 1 to objNode.Faces.count do ( --local faceIdx = objNode.selectedFaces[FaceNum].index local GeomFaceVerts = getFaceVerts objNode FaceNum --NEED TO CHECK MAP SUPPORT FOR CHANNEL 4 local MapFaceVerts = getMapFaceOp objNode mapChannel FaceNum for n = 1 to GeomFaceVerts.Count do ( mapVertLookup[GeomFaceVerts[n]][MapFaceVerts[n]] = True ) subProgress.PostProgressStep() ) subProgress.End() --return mapVertLookup ), /*** ***/ fn paintOutPOMFaces objNode facesOfInterest = ( getMapVertFunc = undefined setMapVertFunc = undefined getVertsUsingFaceOp = undefined facesUsingVertOp = undefined setFaceColorOp = undefined faceMapFunc = meshop.getMapFace if (classOf objNode == Editable_mesh) then ( getMapVertFunc = meshop.getMapVert setMapVertFunc = meshop.setMapVert getVertsUsingFaceOp = meshop.getVertsUsingFace setFaceColorOp = meshop.setFaceColor facesUsingVertOp = meshop.getFacesUsingVert --meshop.getMapSupport ) else if (classof objNode == Editable_Poly) or (classOf objNode == PolyMeshObject) then ( getMapVertFunc = polyop.getMapVert setMapVertFunc = polyop.setMapVert getVertsUsingFaceOp = polyop.getVertsUsingFace setFaceColorOp = polyop.setFaceColor faceMapFunc = polyop.getMapFace facesUsingVertOp = polyop.getFacesUsingVert --polyop.getMapSupport ) /*** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! preserve green and flush red ***/ --flush with black --polyop.setFaceColor objNode 4 (objNode.faces as BitArray) (color 0 0 0 ) --flip the face selection --facesOfInterest = (objNode.faces as BitArray) - facesOfInterest --paint those verts white on channel 4 --subProgress = mainProgress.StartSubProgress 0 meshPOMFaceList.count SubTitle:"Painting POM Faces.." --progressStart ("Stage (2 of 2) " + objNode.name + "...") with undo off ( --first fast fill all the faces red channel only subProgress = mainProgress.StartSubProgress 0 facesOfInterest.count SubTitle:"Painting POM Faces.." subProgress.Start() for face in facesOfInterest do ( local faceVerts = faceMapFunc objNode mapChannel face for mv in faceVerts do ( local currentColour = getMapVertFunc objNode mapChannel mv setMapVertFunc objNode mapChannel mv [1.0, currentColour.y, currentColour.z] ) subProgress.PostProgressStep() ) subProgress.End() --setFaceColorOp objNode mapChannel facesOfInterest (color 255 255 255) --then get the border ones and do the fade local borderVerts = findBorderVerts objNode facesOfInterest local mapVertLookup = getMapVertLookup objNode local mapVerts = #() for vtx in borderVerts do ( join mapVerts mapVertLookup[vtx] ) /* subProgress = mainProgress.StartSubProgress 0 borderVerts.count SubTitle:"Collecting POM Faces Borders.." subProgress.Start() for vtx in borderVerts do ( -- Get all faces using the vert as array local faceArray = facesUsingVertOp objMesh #{vtx} --iterate over the faces for f in faceArray do ( --Get geometry face local geoFace = getFace objMesh f local mapFace = meshop.getMapFace objMesh mapChannel f -- Find order inside the mesh face - vertex (component) order will be the same in both mapVert = case of ( (geoFace.x == vtx): mapFace.x (geoFace.y == vtx): mapFace.y (geoFace.z == vtx): mapFace.z ) --collect the mapVert values found append mapVerts mapVert ) subProgress.PostProgressStep() ) subProgress.End() */ --set to white /*** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ONLY SET RED CHANNEL ***/ subProgress = mainProgress.StartSubProgress 0 borderVerts.count SubTitle:"Painting POM Faces Borders.." subProgress.Start() local mapVertsDone = #{} for mv in mapVerts where (not mapVertsDone[mv]) do ( local currentColour = getMapVertFunc objNode mapChannel mv setMapVertFunc objNode mapChannel mv [1.0, currentColour.y, currentColour.z] mapVertsDone[mv] = true subProgress.PostProgressStep() ) subProgress.End() update objNode polyop.collapseDeadStructs objNode ) --progressEnd() ), /*** ***/ fn smoothSelection obj faceSel = ( obj.selectedFaces = faceSel subobjectLevel = 4 obj.growSelection() obj.shrinkSelection() subobjectLevel = 0 ), /*** EXPERIMENTAL ***/ fn buildMaskCache = ( --clear the cache maskCache = #{} --use selection bounds to get a pixelbounds local pixelBounds = get2DPixelBounds (DataPair min:[selectionBounds[1].x, selectionBounds[1].y] max:[selectionBounds[2].x, selectionBounds[2].y]) --scan the ipmask and build a mask lookup using the pixelbounds local x = pixelBounds.min.x for y=0 to ((pixelBounds.max.y - pixelBounds.min.y) - 1) do --each line ( local pxLine = getPixels IPMask [x, (pixelBounds.min.y + y)] (pixelBounds.max.x - pixelBounds.min.x) for px = 1 to pxLine.count do ( if (pxLine[px] == (color 0 0 0)) then ( local offset = (pixelBounds.min.y * IPMask.width) + (y * IPMask.width) + px maskCache[offset] = true ) ) ) ), /*** Process the terrain shaded faces of the selected meshes ***/ fn processSelectedMeshes = ( escapeEnable = true --local st = timeStamp() local meshes = for item in selection where (getAttrClass item == "Gta Object") collect item mainProgress = RSProgressWindow Title:"Processing Meshes..." StartStep:1 EndStep:meshes.count mainProgress.Start() for item in meshes do ( --find the POM shadeed faces local meshShaders = RsGetShaderListForObjects item local hasPOMShaders = false for shd in meshShaders where ((matchPattern shd pattern:"*_pxm*.sps") == true) do ( hasPOMShaders = true ) if not hasPOMShaders then ( print "no POM shaders on this object" continue ) --might be worth making a cache of the face vert position to speed up lookup time --as there will be multiple hits on a vert per face -- in fact cache the vert, position and IPMask hit --only worth doing if there is a pxm shader to mess with, so check that first local swapFaces = #{} local meshPOMFaceList = #() for shd in meshShaders where ((matchPattern shd pattern:"*_pxm*.sps") == true) do ( local shdPOMFaceList = #() RsGetObjFacesUsingShader item (getfilenamefile shd) shdPOMFaceList join meshPOMFaceList shdPOMFaceList ) --gather positions from POMFaces to check against the IPMask item.selectedFaces = meshPOMFaceList subProgress = mainProgress.StartSubProgress 0 meshPOMFaceList.count SubTitle:"Checking POM Faces.." subProgress.Start() for face in meshPOMFaceList do ( local needsSwap = checkFaceIPMask item face if needsSwap then ( --format "face: % needsSwap\n" face swapFaces[face] = true ) subProgress.PostProgressStep() windows.processPostedMessages() ) subProgress.End() item.selectedFaces = swapFaces local avg = 0.0 for mc in maskCoverageValues do avg += mc avg /= maskCoverageValues.count format "maskCoverageValues: min: % max: % avg: % \n" (amin maskCoverageValues) (amax maskCoverageValues) avg --smooth out the selection smoothSelection item swapFaces --paint the height weight blend paintOutPOMFaces item swapFaces swapFaces mainProgress.PostProgressStep() ) mainProgress.End() true ), /*** Process container meshes iterate through all the meshes identify POM shaded faces use POM face position (multisample) to look for IP coverage ... ***/ fn processContainerMeshes = ( escapeEnable = true if (classOf selection[1] != Container) then ( messageBox "Please Select a Container" title:"Selection Error" return false ) local meshes = for item in selection[1].children where (getAttrClass item == "Gta Object") collect item clearSelection() select meshes processSelectedMeshes() clearSelection() true ), /*** Initialise the mask and pixelPitch ***/ fn init = ( if (doesFileExist IPMaskPath) then ( IPMask = openBitmap IPMaskPath xPixelPitch = worldMapSize.x / IPMask.width yPixelPitch = worldMapSize.y / IPMask.height ) else ( format "Cant load IPMask: % \n" IPMaskPath ) ) ) --///////////////////////////////////////// -- UI --///////////////////////////////////////// --try(destroyDialog POMUnderIP_UI)catch() rollout POMUnderIP_UI "Remove POM under IP" width:400 height:100 ( --///////////////////////////////////////// -- VARIABLES --///////////////////////////////////////// local sPOMIP = POMUnderIP() --///////////////////////////////////////// -- CONTROLS --///////////////////////////////////////// --dotNetControl rsBannerPanel "Panel" pos:[0,0] height:32 width:(POMUnderIP_UI.width) --local banner = makeRsBanner dn_Panel:rsBannerPanel wiki:"CHANGEME" versionNum:0.1 versionName:"Mumbo Jumbo" filename:(getThisScriptFilename()) timer ctrlState interval:5000 active:false dotNetControl btnProcess "Button" text:"Process Container" width:(POMUnderIP_UI.width - 10) height:dnStyle.stdButtonHeight offset:[-10, 0] dotNetControl btnSelMesh "Button" text:"Process Selected Meshes" width:(POMUnderIP_UI.width - 10) height:dnStyle.stdButtonHeight offset:[-10, 0] --///////////////////////////////////////// -- FUNCTIONS --///////////////////////////////////////// --///////////////////////////////////////// -- EVENTS --///////////////////////////////////////// --///////////////////////////////////////// -- --///////////////////////////////////////// on btnSelMesh click do ( local keepGoing = true for item in selection where (isKindOf item EditablePolyMesh) do ( if (querybox ("This object " + item.name + " has faces with T-Verts, this could give incorrect results,\n do you want to proceed?")) then ( continue ) else ( return false ) ) dnStyle.setExecuteStyle btnSelMesh local success = sPOMIP.processSelectedMeshes() ctrlState.active = true if success then dnStyle.setSuccessStyle btnSelMesh else dnStyle.setErrorStyle btnSelMesh ) --///////////////////////////////////////// -- --///////////////////////////////////////// on btnProcess click do ( dnStyle.setExecuteStyle btnProcess local success = sPOMIP.processContainerMeshes() ctrlState.active = true if success then dnStyle.setSuccessStyle btnProcess else dnStyle.setErrorStyle btnProcess ) --///////////////////////////////////////// -- --///////////////////////////////////////// on ctrlState tick do ( dnStyle.setDormantStyle btnProcess dnStyle.setDormantStyle btnSelMesh ctrlState.active = false ) --///////////////////////////////////////// -- --///////////////////////////////////////// on POMUnderIP_UI open do ( --banner.setup() --make sure the mask is synced --gRsPerforce.sync #(sPOMIP.IPMaskPath) sPOMIP.init() --build c# assembly CSharp.CompileToMemory #(RsConfigGetWildWestDir() + "script/3dsMax/Maps/Materials/polyclip.cs") sPOMIP.cs_PolyClip = dotNetClass "Sutherland.SutherlandHodgman" --set styles dnStyle.initButtonStyle btnProcess dnStyle.initButtonStyle btnSelMesh ) ) --createDialog POMUnderIP_UI