Jump to content

How to unwrap a head so that it matches an unwrapped head texture ?


AntoineSfx

Recommended Posts

There is a high resolution free sample  here

https://www.3d.sk/photos/show/id/949587

What method can we use to generate the UV on testmodel head so that the texture fits the head ?
It looks like it's a job for topo transfer but it's not exactly in the same attribute space. Ideally something like defining landmarks on two geometries and have topo transfer match the two topologies.

Or maybe something like UVFlatten with a seam on the back of the head, and some constraints to make it look like the texture. I have not tried this method though

Any thoughts ?

head-woman-white-textures-premade-texture_640v640.jpg

Edited by AntoineSfx
Link to comment
Share on other sites

remesh make open charachter
att create detail int -totalpt

someone in Asia forums done Using numpy to solve matrix

v@oripos=@P;
//vertices
int cur_hedge=vertexhedge(0,i@vtxnum),cur_point=hedge_srcpoint(0,cur_hedge);
int nex_hedge=hedge_next(0,cur_hedge),nex_point=hedge_srcpoint(0,nex_hedge);
int nexnex_hedge=hedge_next(0,nex_hedge),nexnex_point=hedge_srcpoint(0,nexnex_hedge);



vector i,j,k;
i=point(0,"P",cur_point);
j=point(0,"P",nex_point);
k=point(0,"P",nexnex_point);
// v@i=i;
// v@j=j;
// v@k=k;

float Kij;
Kij=0.5*dot((i-k),(j-k))/length(cross((i-k),(j-k)));
f@Kij=Kij;
int primnum=nprimitives(0);
int vtxnum=3*primnum;
int edgenum=0,bondnum=0;
vector2 edgelist[];
int boundry[],src,dst,isbound;
int bondlist[];
float temp[];


for(int i=0;i<vtxnum;i++)
{
    if(hedge_isprimary(0,i))
    {
        isbound=0;
        edgelist[edgenum].x=i;
        edgelist[edgenum].y=hedge_nextequiv(0,i);
        if(edgelist[edgenum].x==edgelist[edgenum].y)
        {
            boundry[bondnum]=i;
            bondlist[bondnum]=hedge_srcpoint(0,i);
            bondnum++;
            isbound=1;
        }        
        edgenum++;
        
    }
    
}

i@bondnum=bondnum;

int bond_list[],vertices[],min=min(bondlist),next,a,b;


int tempa;
bond_list[0]=min;

for(int i=0;i<bondnum-1;i++)
{
    vertices=pointvertices(0,bond_list[i]);
    foreach(int num;vertices)
    {
        tempa=vertexhedge(0,num);
        if(find(boundry,tempa)>=0)
        {
        bond_list[i+1]=hedge_dstpoint(0,tempa);
        break;
        }
    }
    
}

vector pos;
float length[];
length[i@totalpt-1]=0;
vector pos1,pos2;


// for(int i=0;i<i@totalpt;i++)
// {
// 
//     if(find(bond_list,i)>=0)
//     {
//         pos=point(0,"P",i);
//         pos=point(0,"P",i);
//         pos.z=0;
//         setpointattrib(0,"P",i,pos);
//         setpointattrib(0,"P",i,pos);
//     }    
// //     if(i)
// //     {
// //         for(int j=i@bondnum-1;j>=i;j--)
// //         {
// //             pos1=point(0,"P",bond_list[i]);
// //             pos2=point(0,"P",bond_list[i-1]);
// //             length[j]+=length(pos1-pos2);
// //         }
// //     }
// }

// f[]@length=length;
// pos1=point(0,"P",bond_list[0]);
// pos2=point(0,"P",bondlist[i@bondnum-1]);
// float totallength=max(length)+length(pos1-pos2),angle,radius=2;
// 
// 
// for(int i=0;i<i@bondnum;i++)
// {
//     angle=length[i]/totallength*2*3.1415926535;
//     pos=set(radius*cos(angle),radius*sin(angle),0);
//     setpointattrib(0,"P",bond_list[i],pos);
// }



for(int i=0;i<bondnum;i++)
{

//     if(find(bond_list,i)>=0)
//     {
//         pos=point(0,"P",i);
//         pos=point(0,"P",i);
//         pos.z=0;
//         setpointattrib(0,"P",i,pos);
//         setpointattrib(0,"P",i,pos);
//     }    
    if(i)
    {
        for(int j=i@bondnum-1;j>=i;j--)
        {
            pos1=point(0,"P",bond_list[i]);
            pos2=point(0,"P",bond_list[i-1]);
            length[j]+=length(pos1-pos2);
        }
    }
}

f[]@length=length;
pos1=point(0,"P",bond_list[0]);
pos2=point(0,"P",bondlist[i@bondnum-1]);
float totallength=max(length)+length(pos1-pos2),angle,radius=2;


for(int i=0;i<i@bondnum;i++)
{
    angle=length[i]/totallength*2*3.1415926535;
    pos=set(radius*cos(angle),radius*sin(angle),0);
    setpointattrib(0,"P",bond_list[i],pos);
}
int primnum=nprimitives(0);
int vtxnum=3*primnum;
int edgenum=0,bondnum=0;
vector2 edgelist[];
float KIJ[];
int boundry[],src,dst,isbound;
int bondlist[];
float temp[];


for(int i=0;i<vtxnum;i++)
{
    if(hedge_isprimary(0,i))
    {
        isbound=0;
        edgelist[edgenum].x=i;
        edgelist[edgenum].y=hedge_nextequiv(0,i);
        if(edgelist[edgenum].x!=edgelist[edgenum].y)
        {
            KIJ[edgenum]=vertex(0,"Kij",(int)edgelist[edgenum].x)+vertex(0,"Kij",(int)edgelist[edgenum].y);
        }
        else
        {
            KIJ[edgenum]=vertex(0,"Kij",(int)edgelist[edgenum].x);
            boundry[bondnum]=i;
            bondlist[bondnum]=hedge_srcpoint(0,i);
            bondnum++;
            isbound=1;
        }
        
        src=hedge_srcpoint(0,i);
        dst=hedge_dstpoint(0,i);
        temp=array(isbound,KIJ[edgenum]);
        adddetailattrib(0,"edge_"+itoa(min(src,dst))+"_"+itoa(max(src,dst)),temp);
        setdetailattrib(0,"edge_"+itoa(min(src,dst))+"_"+itoa(max(src,dst)),temp);
        edgenum++;
        
    }
    
}


i@edgenum=edgenum;
u[]@edgelist=edgelist;
f[]@KIJ=KIJ;
i[]@boundry=boundry;
i@bondnum=bondnum;

int bond_list[],vertices[],min=min(bondlist),next,a,b;


int tempa;
bond_list[0]=min;

for(int i=0;i<bondnum-1;i++)
{
    vertices=pointvertices(0,bond_list[i]);
    foreach(int num;vertices)
    {
        tempa=vertexhedge(0,num);
        if(find(boundry,tempa)>=0)
        {
        bond_list[i+1]=hedge_dstpoint(0,tempa);
        break;
        }
    }
    
}





i[]@bond_list=bond_list;
i[]@bondlist=bondlist;

int inner_list[];

for(int i=0;i<i@totalpt;i++)
{
    if(find(bond_list,i)<0)
    {
        append(inner_list,i);
    }
}


i[]@inner_list=inner_list;
i@totalfixed=len(bond_list);
i@totalinner=len(inner_list);

float innerX[],innerY[],fixedX[],fixedY[];
vector pos;

foreach(int pt;inner_list)
{
    pos=point(0,"P",pt);
    append(innerX,pos.x);
    append(innerY,pos.y);
}

foreach(int pt;bond_list)
{
    pos=point(0,"P",pt);
    append(fixedX,pos.x);
    append(fixedY,pos.y);
}

f[]@innerX=innerX;
f[]@innerY=innerY;
f[]@fixedX=fixedX;
f[]@fixedY=fixedY;
int neigh[]=neighbours(0,@ptnum);
int bondlist[]=detail(0,"bond_list");
int inner[],fixed[],temp;
float innerK[],fixedK[],ttt[];

foreach(int num;neigh)
{
    temp=find(bondlist,num); 
    if(temp>=0)
    {
        append(fixed,num);
        ttt=detail(0,"edge_"+itoa(min(@ptnum,num))+"_"+itoa(max(@ptnum,num)));
        append(fixedK,ttt[1]);
    }
    else
    {
        append(inner,num);
        ttt=detail(0,"edge_"+itoa(min(@ptnum,num))+"_"+itoa(max(@ptnum,num)));
        append(innerK,-ttt[1]);
    }
}



append(innerK,-sum(innerK));

i[]@fixed=fixed;
i[]@inner=inner;
f[]@fixedK=fixedK;
f[]@innerK=innerK;
node = hou.pwd()
geo = node.geometry()

from numpy import *

#read inner&fixed data*******************************************

totalinner=geo.intAttribValue("totalinner")
totalfixed=geo.intAttribValue("totalfixed")

inner_list=geo.intListAttribValue("inner_list")
bond_list=geo.intListAttribValue("bond_list")

innerX=geo.floatListAttribValue("innerX")
innerY=geo.floatListAttribValue("innerY")

fixedX=geo.floatListAttribValue("fixedX")
fixedY=geo.floatListAttribValue("fixedY")



#construct dictionary*********************************************

innerdict={"123456765432eeee":1234}
fixeddict={"123456765432eeee":1234}

ttt=0
for inner in inner_list:
    innerdict[inner]=ttt
    ttt=ttt+1
    
ttt=0
for bond in bond_list:
    fixeddict[bond]=ttt
    ttt=ttt+1    
    
    
#initial matrix******************************************************

K1=mat(zeros((totalinner,totalinner)))
K2=mat(zeros((totalinner,totalfixed)))

Xarray=mat(zeros((totalfixed,1)))
Yarray=mat(zeros((totalfixed,1)))


#construct matrix****************************************************

for i in inner_list:
    pt=geo.iterPoints()[i]
    
    inner=pt.intListAttribValue("inner")
    innerK=pt.floatListAttribValue("innerK")
    
    fixed=pt.intListAttribValue("fixed")
    fixedK=pt.floatListAttribValue("fixedK")
    
    K1[innerdict[i],innerdict[i]]=innerK[-1]
    
    for element,index in zip(innerK,inner):
        K1[innerdict[i],innerdict[index]]=element
        
    for element,index in zip(fixedK,fixed):
        K2[innerdict[i],fixeddict[index]]=element
        K1[innerdict[i],innerdict[i]]+=element

i=0        
for x in fixedX:
    Xarray[i,0]=x
    i+=1
    
i=0        
for y in fixedY:
    Yarray[i,0]=y
    i+=1

#computing***********************************************************

main=K1.I*K2

Xout=main*Xarray
Yout=main*Yarray

#modify geometry*****************************************************


index=0
for i in inner_list:
    pt=geo.iterPoints()[i]
    pt.setPosition((Xout[index,0], Yout[index,0], 0))
    index+=1

        
        
#test****************************************************************

#for inner in inner_list:
#    print(innerdict[inner])
# 
#    
#ttt=0
#for bond in bond_list:
#    print(fixeddict[bond])

    
#print("K1")    
#print(K1)
#print("K2")    
#print(K2)

unwrap
@P=v@oripos;
PIG
 

pig.jpg

Edited by Librarian
Link to comment
Share on other sites

It turns out, Topo Transfer' ing a high resolution sphere, with polar UV  and the original texture assigned to it to help pick the features -- is doing the job just fine

Just took 15 minutes at 1,600 % CPU usage on my trusty dual Xeon 32 cores workstation.

Now the resulting surface obviously doesn't match the original person head, but that's the point of projecting it on a geometry with a known good topology for easy tweaking

Also, a few problems exist on the back UV  seam.

 

final.png

unwrapped.pngsource.png

target.png

graph.png

backSeam.png

Edited by AntoineSfx
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...