importnumpyasnpimportiglimportmeshplotasmpfromscipy.spatial.transformimportRotationimportipywidgetsasiwimporttimefrommathimportexpimportquaternionimportpicklefromjoblibimportParallel,delayedimportcontextlibimportjoblibfromtqdmimporttqdm@contextlib.contextmanagerdeftqdm_joblib(tqdm_object):"""Context manager to patch joblib to report into tqdm progress bar given as argument"""classTqdmBatchCompletionCallback(joblib.parallel.BatchCompletionCallBack):def__call__(self,*args,**kwargs):tqdm_object.update(n=self.batch_size)returnsuper().__call__(*args,**kwargs)old_batch_callback=joblib.parallel.BatchCompletionCallBackjoblib.parallel.BatchCompletionCallBack=TqdmBatchCompletionCallbacktry:yieldtqdm_objectfinally:joblib.parallel.BatchCompletionCallBack=old_batch_callbacktqdm_object.close()
V,F=igl.read_triangle_mesh('data/arm.obj')C,BE,_,_,_,_=igl.read_tgf('data/arm.tgf')W=igl.read_dmat('data/arm-weights.dmat')# labels = np.load('data/hand.label.npy').astype(int)# v -= v.min(axis=0)# v /= v.max()# mp.plot(V,F)
# V, F = igl.read_triangle_mesh('data/untitled.obj')# mp.plot(V,F)F
defcircle_sum(q1,q2):returnq1+q2ifnp.dot(quaternion.as_float_array(q1),quaternion.as_float_array(q2))>=0elseq1-q2defapply_weighted_rotation(vertices,wgts,quat,CoR,translation):#vertices, weights, rot (as quat), CoR, translation array vnew=vertices.copy()foriinrange(vertices.shape[0]):vi=vertices[i]wi=wgts[i]q=quaternion.as_quat_array([0,0,0,0])forjinrange(BE.shape[0]):# #BEqj=quat[j]wij=wi[j]q=circle_sum(q,wij*qj)# wqi = np.sum(qi, axis=0)q/=np.linalg.norm(quaternion.as_float_array(q))R=quaternion.as_rotation_matrix(q)Rtilda=np.zeros((3,3))ttilda=np.zeros((3,1))forjinrange(BE.shape[0]):Rj=quaternion.as_rotation_matrix(quat[j])#3 x 3tj=translation[j]# 1 x 3wij=wi[j]Rtilda+=wij*Rjttilda+=wij*tj.reshape((3,1))t=Rtilda@CoR[i].reshape((3,1))+ttilda-R@CoR[i].reshape((3,1))vnew[i]=(R@vi.reshape((3,1))+t).reshape(3)returnvnew
defsimilarity(Wp,Wv,sigma=0.1):#BE shapeWp=Wpiflen(Wp.shape)==1elseWp.reshape(-1)Wv=Wviflen(Wv.shape)==1elseWv.reshape(-1)tot=0forjinrange(Wp.shape[0]):forkinrange(j+1,Wv.shape[0]):tot+=Wp[j]*Wp[k]*Wv[j]*Wv[k]*exp(-(Wp[j]*Wv[k]-Wp[k]*Wv[j])**2/sigma**2)returntotdefCoR(i,weights,vertices,faces,omega=0.1,pb=None):num=np.zeros([1,3])denom=np.zeros([1,3])fortinrange(faces.shape[0]):# cmp = [i for i in range(3) if np.linalg.norm(weights[i] - weights[faces[t,i]]) < omega]cmp=[0,1,2]ifnotcmp:continues=similarity(weights[i],np.mean([weights[faces[t,c]]forcincmp],axis=0))v=np.mean([vertices[faces[t,c]]forcincmp],axis=0)a=igl.doublearea(vertices,faces[[t]])/2num+=s*v*adenom+=s*api=num/denomifpb:pb.value=ireturnpi
# P = np.zeros(V.shape)# with tqdm_joblib(tqdm(desc="My calculation", total=P.shape[0])) as progress_bar:# P = np.array(Parallel(n_jobs=10)(delayed(CoR)(i, W, V, F) for i in range(P.shape[0])))
# pickle.dump(P, open("data/CoR.p", "wb"))
P=pickle.load(open('data/CoR.p','rb'))mp.plot(P)
Renderer(camera=PerspectiveCamera(children=(DirectionalLight(color='white', intensity=0.6, position=(0.0007487…
<meshplot.Viewer.Viewer at 0x7fa1990936a0>
defwidgets_wrapper():# segment_widget = iw.Dropdown(options=np.arange(labels.max()) + 1)segment_widget=iw.SelectMultiple(options=np.arange(labels.max()+1))translate_widget={i:iw.FloatSlider(min=-1,max=1,value=0)foriin'xyz'}# rotate_widget = {a:iw.FloatSlider(min=-90, max=90, value=0, step=1) # for a in 'αβγ'}real_widget={a:iw.FloatSlider(min=-2,max=2,value=1,step=.25)forain'w'}imag_widget={a:iw.FloatSlider(min=-1,max=1,value=0,step=.1)forain'αβγ'}defupdate_seg(*args):(translate_widget['x'].value,translate_widget['y'].value,translate_widget['z'].value,real_widget['w'].value,imag_widget['α'].value,imag_widget['β'].value,imag_widget['γ'].value)=pos_f_saver[segment_widget.value]segment_widget.observe(update_seg,'value')widgets_dict=dict(s=segment_widget)widgets_dict.update(translate_widget)widgets_dict.update(real_widget)widgets_dict.update(imag_widget)returnwidgets_dict
defposition_deformer(target_pos):'''Fill in this function to change positions'''returntarget_pos''' (Optional) Register this function to perform interactive deformation
pos_f.deformer = position_deformer
'''
' (Optional) Register this function to perform interactive deformation\npos_f.deformer = position_deformer\n'
# Map the vertex colors into the 'color' slot of the facesfaces=[f+[None,[vertexcolors[i]foriinf],None]forfinfaces]# Create the geometry:cubeGeometry=Geometry(vertices=vertices,faces=faces,colors=vertexcolors)# Calculate normals per face, for nice crisp edges:cubeGeometry.exec_three_obj_method('computeFaceNormals')
# Create a mesh. Note that the material need to be told to use the vertex colors.myobjectCube=Mesh(geometry=cubeGeometry,material=MeshLambertMaterial(vertexColors='VertexColors'),position=[-0.5,-0.5,-0.5],# Center the cube)
# Set up a scene and render it:cCube=PerspectiveCamera(position=[3,3,3],fov=20,children=[DirectionalLight(color='#ffffff',position=[-3,5,1],intensity=0.5)])sceneCube=Scene(children=[myobjectCube,cCube,AmbientLight(color='#dddddd')])rendererCube=Renderer(camera=cCube,background='black',background_opacity=1,scene=sceneCube,controls=[OrbitControls(controlling=cCube)])display(rendererCube)
V,F=igl.read_triangle_mesh('data/arm.obj')C,BE,_,_,_,_=igl.read_tgf('data/arm.tgf')W=igl.read_dmat('data/arm-weights.dmat')labels=np.array(range(BE.shape[0])).astype(int)defapply_ocor(s,x,y,z,w,α,β,γ):clicked_edges=BE[np.isin(labels,s)]slices=[]foreinclicked_edges:forvine:ifvnotinslices:slices.append(v)r=Rotation.from_quat([α,β,γ,w])v_slice=C[slices]+np.array([[x,y,z]])C1=C.copy()C1[slices]=r.apply(v_slice)q=np.repeat([[w,α,β,γ]],BE.shape[0],axis=0)t=np.repeat([[x,y,z]],BE.shape[0],axis=0)# t = np.zeros((BE.shape[0], 3))# for i in range(BE.shape[0]):# xi,yi,zi,wi,αi,βi,γi = pos_f_saver[i]# q[i,:] = [wi,αi,βi,γi]# t[i,:] = [xi, yi, zi]Q=quaternion.as_quat_array(q)OCoR=apply_weighted_rotation(V,W,Q,P,t)returnOCoR