Home Technical Talk

Script to select overlapping UVs?

Im doing a mechanical mesh that has a lot of overlapping uv islands that mirror or copy. When I 'select overlapping UVs' in max 2012 UV tools it does not work correctly.. it doesn't select all my overlapping faces so I can rearrange and offset and work on them.

Is there any tool or script that does this correctly?

Replies

  • Nam.Nguyen
    Offline / Send Message
    Nam.Nguyen polycounter lvl 9
    Just make sure you reset X-form ( in Utility, not the X-form modifier ) before unwrapping, that fix the problem for me
  • Mark Dygert
    Make sure you deselect everything first before running "select overlapping". If you don't, I think it only checks what you have selected for overlapping polygons.

    Since you're using max you don't have to offset them, 3dsmax has uvW, where other editors are just U(vertical) and V(horizontal), 3dsMax has W(depth). Which allows you to sort the shells in front or behind the others, determining which renders last. This way all of the shells stay in the same spot in UV space and you don't have to do the goofy offset them one tile to the right/left/top or bottom to keep them from messing up the render. You just push all but one of the shells, behind.

    What you do is...
    1) Select all of the overlapping shells and using the "W:" type in box (the lower right corner) set W (depth) to 0.
    2) Deselect one shell from each group.
    3) Use the W type-in again and set the remaining shells to .01, .5 or 1. Just something higher than 0.

    This pushes the selected shells behind the unselected, meaning they will render underneath the shells at 0.
    If you want to see the depth, change the UV editor to UW (upper right corner).
  • NautalusX
    I don't mind offsetting them. I'm baking in Xnormal so I'm not sure if this depth trick will work on them or not. Why don't normal map bakers and bakers in general just detect that a shell has already been processed and not double process it? There should just be a option for this.

    EDIT: select overlapped faces still isn't working... ive reset Xforms. It just selects random polys..I cant reset xforms before unwrapping cause its already unwrapped. Selecting inverted faces actually works pretty well.. close to perfect I think I can work with it.
  • Noors
    Offline / Send Message
    Noors greentooth
    Yeah, select overlap will select every faces that overlaps, while you'd want all shells but one. You could expand the faces to element then deselect one element, but for a lot of parts, it might be tedious.

    Renderhjs Textools has the function (found it via google), but i don't see where it stands in the UI or am i really tired ?!
    Here it is anyway.
    function fn_41__offset_overlapping_shells =(
        clearlistener();
        
        local uv = modPanel.getCurrentObject();
        if( classof(uv) == Unwrap_UVW)then(
            
            uv.unwrap2.setTVSubObjectMode 3;--face mode
            
            
            
            
            local totalFaces = uv.unwrap.numberPolygons();
            local faceElemArray = #();
            for f=1 to totalFaces do (
                faceElemArray[ f ] = 0;
            )
            local elem = #();
            --with redraw off;
            for f=1 to totalFaces do (
                if faceElemArray[ f ] == 0 then (
                    uv.unwrap2.selectFaces  #{ f };
                    uv.unwrap2.selectElement();
                    local elemFaces = uv.unwrap2.getSelectedFaces() as array;
                    append elem (uv.unwrap2.getSelectedFaces());
                    for i in elemFaces do (
                        faceElemArray[ i ] = elem.count; -- Mark these vertices with their element number in vertElemArray.
                    )
                )
            )
            
            --get the overlapping shells
            uv.unwrap2.selectFaces #{};--select none faces, otherwise selecing overlapping faces doesn't work
            uv.unwrap5.selectOverlappedFaces();
            uv.unwrap2.selectElement();--extend to element selections
            local sel = uv.unwrap2.getSelectedFaces();
            
            
            function getBBox uv fcs =(--rethrieves a bounding box array of the passed through face bit array
                uv.unwrap2.selectFaces fcs;
                uv.unwrap2.faceToVertSelect();
                local verts =  uv.unwrap.getSelectedVertices();
                local bbox = #(0,0,0,0);
                local i = 1;
                for v in verts do(
                    local pt = uv.getVertexPosition 1 v;
                    if (i == 1) then(
                        bbox[1] = bbox[2] = pt.x;
                        bbox[3] = bbox[4] = pt.y;
                    )else(
                        bbox[1] = amin #(bbox[1],pt.x);--minX
                        bbox[2] = amax #(bbox[2],pt.x);--maxX
                        bbox[3]  = amin #(bbox[3],pt.y);--minY
                        bbox[4]  = amax #(bbox[4],pt.y);--maxY
                    )
                    i+=1;
                )
                
                local x = bbox[1];
                local y = bbox[3];
                local w = bbox[2] - bbox[1];
                local h = bbox[4] - bbox[3];
                return #(x,y,w,h);--x,y,w,h
            )
            
            
            
            
            
            
            local allElemBBox = #();
            local ovrElem = #();
            for fcs in elem do(
                
                local bbox = (getBBox uv fcs);
                append allElemBBox bbox;
                
                
                local xor = sel - fcs;
                if (xor.numberset < sel.numberset)then(--this shell is part of the overlapping selection
                    
                    
                    local pt = #(bbox[1]+bbox[3]/2.0, bbox[2]+bbox[4]/2.0);
                    
                    
    
                    if (bbox[1] < 1.0 and bbox[1]+bbox[3] > 0.0)then(
                        if (bbox[3] < 1.0 and bbox[3]+bbox[4] > 0.0)then(--only if within 0.0 - 1.0 box
                            append ovrElem #(fcs,pt,bbox);
                            Print("> "+sel.numberset as string+" , "+(xor.numberSet) as string+" = "+pt as string);
                        )
                    )
                )
            )
            
            print("ovrElem "+ovrElem.count as string);
            
            if (ovrElem.count == 0)then(
                
                print("stack back ");
                
                sel = #{};
                
                for e = 1 to elem.count do(
                    local bbox = allElemBBox[e];
                    local fcs = elem[e];
                    
                    
                    
                    if (bbox[1] > 1.0 or (bbox[1]+bbox[3]) < 0.0)then(
                        sel+=fcs;
                        
                        local dir = bbox[1] / (abs bbox[1]) *-1;
                        local shift = floor ((abs bbox[1]) / 1.0);
                        if (bbox[1] < 0)then(
                            shift+=1;
                        )
                        
                        format "shift: % \n" (shift*dir)
                                            
                        uv.unwrap2.selectFaces fcs;
                        uv.unwrap2.MoveSelected [(shift*dir),0,0];
                    )
                    
                )
                
                uv.unwrap2.selectFaces sel;
                
                
                
                
                
                
            )else(
            
                
                
                grpElem = #();
                for i=1 to ovrElem.count do (
                    
                    local ovr = ovrElem[i];
                    
                    if (i == 1)then(
                        grpElem[1] = #();--store position
                        append grpElem[1] #(ovr[1],ovr[2]);--fcs, pt
                    )else(
                        local found = -1;
                        for j=1 to grpElem.count do (
                            
                        --    format "dbg %,%,%,% \n" j grpElem.count grpElem[j].count 0
                            local ptA = point2 ovrElem[i][2][1] ovrElem[i][2][2];
                            local ptB = point2 grpElem[j][1][2][1] grpElem[j][1][2][2];
                            local d = distance ptA ptB;
                            if (d < 0.01)then(
                                found = j;
                                exit;
                            )
                        )
                        if (found >0)then(--append to found group
                            append grpElem[found] #(ovr[1],ovr[2]);
                        )else(--create new group
                            append grpElem #();--store position
                            append grpElem[grpElem.count] #(ovr[1],ovr[2]);
                        )
                    )
                )
                
                sel = #{};
                for e  in grpElem do(
                    
                    if (e.count >= 2)then(
                        for i=2 to e.count do(
                            local fcs = e[i][1];
                            sel+=fcs;
                            uv.unwrap2.selectFaces fcs;
                            uv.unwrap2.MoveSelected [1.0,0,0];
                        )
                    )
                )
                uv.unwrap2.selectFaces sel;
                
                print("num overlapping groups: "+grpElem.count as string);
            )    
            
        )
    )
    
    
    fn_41__offset_overlapping_shells()
    
    Assign an unwrap and execute
Sign In or Register to comment.