try(destroyDialog igorznag_stitch)catch() rollout igorznag_stitch "Stitch" ( button btn_stitch "Stitch"; width:90 pos:[5,5] checkbox ch_dont_overlap "Don't Overlap"pos:[5,35] --functions fn fn_vuetv m arg= ( m.selectedges arg tsubobjectlevel=subobjectlevel; subobjectlevel=1 m.edgetovertSelect() vs=m.getSelectedVertices() subobjectlevel=tsubobjectlevel vs )--fn vuetv m arg= fn fn_vuftv m arg= ( m.selectfaces arg tsubobjectlevel=subobjectlevel; subobjectlevel=1 m.facetovertSelect() vs=m.getSelectedVertices() subobjectlevel=tsubobjectlevel vs )--fn fn_vuftv m arg= fn fn_fue m arg= ( tsubobjectlevel=subobjectlevel; arg_a=arg as array faces_temp=#() for i=1 to arg_a.count do ( for j=1 to (m.numberPolygons()) do ( m.selectfaces #{j}; subobjectlevel=2; m.facetoedgeSelect() es=m.getSelectedEdges() if (es*(#{arg_a[i]})).numberset==1 then append faces_temp j )--for j=1 to (m.numberPolygons()) do )--for i=1 to arg_a.count do subobjectlevel=tsubobjectlevel faces_temp as bitarray )--fn fn_fue m arg= fn fn_edges_count m= ( tsubobjectlevel=subobjectlevel; subobjectlevel=1 n=m.NumberVertices() m.selectVertices (#{1..n}) subobjectlevel=2 es=m.getselectededges() subobjectlevel=tsubobjectlevel es.count )--fn fn_edges_count m fn fn_verts_common m arg= ( tsubobjectlevel=subobjectlevel; subobjectlevel=1 m.selectvertices arg; m.syncTVSelection(); gsv=m.getSelectedGeomVerts(); m.setSelectedGeomVerts gsv; m.syncTVSelection(); sv=m.getSelectedVertices() subobjectlevel=tsubobjectlevel sv-arg )--fn fn_verts_common m arg= fn fn_edges_common m arg= ( tsubobjectlevel=subobjectlevel; arg_a=arg as array edges_temp=#() for i=1 to arg_a.count do ( vue=fn_vuetv m #{arg_a[i]} verts_common=fn_verts_common m vue m.selectvertices verts_common subobjectlevel=2; m.verttoedgeselect() es=m.getSelectedEdges(); es_a=es as array if es_a.count==1 then append edges_temp es_a[1] )--for i=1 to arg_a do subobjectlevel=tsubobjectlevel edges_temp as bitarray )--fn fn_edges_common m arg= fn fn_edge_common_adv m arg= ( tsubobjectlevel=subobjectlevel; arg_a=arg as array if arg_a.count==1 then ( vue=fn_vuetv m arg; vue=vue as array v1s=vue[1]; v2s=vue[2]; edge_common=fn_edges_common m arg edge_common_vue=fn_vuetv m edge_common; edge_common_vue=edge_common_vue as array v1t=edge_common_vue[1]; v2t=edge_common_vue[2]; edge_common=(edge_common as array)[1] vtemps=#(arg_a[1],v1s,v2s) vtempt=#(edge_common,v1t,v2t) v1scoresp=fn_verts_common m #{v1s} if (v1scoresp*(#{v1t})).numberset==0 then vtempt=#(edge_common,v2t,v1t) )--if arg_a.count==1 then subobjectlevel=tsubobjectlevel #(vtemps,vtempt) )--fn fn_edges_common m arg= fn fn_filter_open_edges m arg= ( tsubobjectlevel=subobjectlevel; arg_a=arg as array edges_temp=#() for i=1 to arg_a.count do ( edge_common_faces_count=0 for j=1 to (m.numberPolygons()) do ( m.selectfaces #{j}; subobjectlevel=2; m.facetoedgeSelect() es=m.getSelectedEdges() if (es*(#{arg_a[i]})).numberset==1 then edge_common_faces_count+=1 )--for j=1 to (m.numberPolygons()) do if edge_common_faces_count==1 then append edges_temp arg_a[i] )--for i=1 to arg_a.count do subobjectlevel=tsubobjectlevel edges_temp as bitarray )--fn fn_filter_open_edges m arg= fn fn_filter_have_common_edges m arg= ( oec=#(); arg_a=arg as array for i=1 to arg_a.count do ( oec_temp=fn_edges_common m #{arg_a[i]} if oec_temp.numberset>0 then append oec arg_a[i] )--for i=1 to arg_a.count do oec as bitarray )--fn fn_filter_have_common_edges m arg= --handlers on btn_stitch pressed do ( if selection.count==1 then ( undo on ( try ( clearlistener() if subobjectlevel==2 then ( m=modpanel.getCurrentObject() if classof m==Unwrap_UVW then ( sel_edges=m.getselectededges(); if sel_edges.numberset>0 then ( local oe=sel_edges--fn_filter_open_edges m sel_edges -- local oe=fn_filter_open_edges m sel_edges if oe.numberset>0 then ( local oec=oe--fn_filter_have_common_edges m oe --local oec=fn_filter_have_common_edges m oe oec_a=oec as array; ignore_edges=#{}; verts_to_weld=#{} for i=1 to oec_a.count do ( --verts_to_weld_i=#{} edge_common_adv=fn_edge_common_adv m #{oec_a[i]} edge_info_t=edge_common_adv[1]; edge_info_s=edge_common_adv[2] edge_id_t=edge_info_t[1];edge_vert1_t=edge_info_t[2];edge_vert2_t=edge_info_t[3]; edge_id_s=edge_info_s[1];edge_vert1_s=edge_info_s[2];edge_vert2_s=edge_info_s[3]; subobjectlevel=2;m.selectedges #{edge_id_s}; m.selectElement()--select source cluster source_cluster_edges=m.getSelectedEdges() if (source_cluster_edges*oec).numberset==0 then--filter selected source cluster ( if (source_cluster_edges*ignore_edges).numberset==0 then --filter occupied nonselted source cluster ( ignore_edges+=source_cluster_edges--add source cluster to ignore pos1_t=m.getVertexPosition slidertime edge_vert1_t pos2_t=m.getVertexPosition slidertime edge_vert2_t pos1_s=m.getVertexPosition slidertime edge_vert1_s pos2_s=m.getVertexPosition slidertime edge_vert2_s delta_pos=pos1_t-pos1_s m.moveSelected delta_pos --move cluster dx=pos2_t.x-pos1_t.x; dy=pos2_t.y-pos1_t.y; rot_angle_t=(atan2 dy dx)*Pi/180.0 dx=pos2_s.x-pos1_s.x; dy=pos2_s.y-pos1_s.y; rot_angle_s=(atan2 dy dx)*Pi/180.0 m.RotateSelected -rot_angle_s pos1_t --rotate cluster scale_delta=1.0*(length(pos2_t-pos1_t))/(length(pos2_s-pos1_s)) --scale cluster m.scaleSelectedXY scale_delta scale_delta pos1_t m.RotateSelected rot_angle_t pos1_t --rotate cluster --orient overlapped cluster using unrotate and scale y=-1 if ch_dont_overlap.checked then ( face_center_target=[0,0,0]; face_center_source=[0,0,0]; for j=1 to (m.numberPolygons()) do ( subobjectlevel=3;m.selectfaces #{j}; sf_center=m.getselcenter() subobjectlevel=2; m.facetoedgeSelect() local es=m.getSelectedEdges() if (es*(#{edge_id_t})).numberset==1 then face_center_target=sf_center if (es*(#{edge_id_s})).numberset==1 then face_center_source=sf_center )--for j=1 to (m.numberPolygons()) do v1=normalize (pos2_t-pos1_t);v2=[0,0,1]; v=cross v1 v2 v1=normalize (face_center_target-pos1_t); v2=normalize (face_center_source-pos1_t); d1=dot v1 v; d2= dot v2 v; if not ((d1>= 0 and d2<=0) or (d1<=0 and d2>=0)) then ( subobjectlevel=2;m.selectedges #{edge_id_s}; m.selectElement()--select source cluster again m.RotateSelected -rot_angle_t pos1_t --rotate cluster m.scaleSelectedXY 1 -1 pos1_t m.RotateSelected rot_angle_t pos1_t --rotate cluster )--if not ((d1>= 0 and d2<=0) or (d1<=0 and d2>=0)) then )--if ch_dont_overlap.checked then --move other source common vertices to target subobjectlevel=1;m.selectvertices #{edge_vert1_t}; m.selectElement() target_cluster_vertices=(m.getSelectedvertices()) as array subobjectlevel=1;m.selectvertices #{edge_vert1_s}; m.selectElement() source_cluster_vertices=m.getSelectedvertices() --bitarray for j=1 to target_cluster_vertices.count do ( tocvc=fn_verts_common m #{target_cluster_vertices[j]} tocvcs=tocvc*source_cluster_vertices if tocvcs.numberset==1 then ( tocvcs_a=tocvcs as array target_vert_pos=m.getVertexPosition slidertime target_cluster_vertices[j] m.setVertexPosition slidertime tocvcs_a[1] target_vert_pos -- true true --join verts_to_weld_i #{target_cluster_vertices[j],tocvcs_a[1]} --verts_to_weld join verts_to_weld #{target_cluster_vertices[j],tocvcs_a[1]} --verts_to_weld )--if tocvcs.numberset==1 then )--for j=1 to target_cluster_vertices.count do --append verts_to_weld verts_to_weld_i )--if (source_cluster_edges*ignore_edges).numberset==0 then --choose corect source cluset )--if source_cluster_edges*oec).numberset==0 then--filter selected source cluster )--for i=1 to oec_a.count do --Weld common vertices of each pair of cluster wt=m.getWeldThreshold(); m.setWeldThreshold 0.001 --for i=1 to verts_to_weld.count do --(subobjectlevel=1;m.selectvertices verts_to_weld[i]; ) subobjectlevel=1;m.selectvertices verts_to_weld m.weldSelected(); m.setWeldThreshold wt subobjectlevel=2; m.selectedges #{} )--if oe.numberset>0 then )--if sel_vertsa.count> then )--if classof co==Unwrap_UVW then )--if subobjectlevel==2 then )catch(); )--undo on )--if selection.count==1 then )-- on btn_stitch pressed do ); createdialog igorznag_stitch 100 55