pro create_standalone resolve_all save, /ROUTINES, FILENAME='xcamerapath.sav' END pro add_point, ncpp, cp, tf, ntf=ntf for i=0,N_elements(ncpp)-1 do begin ncp = ncpp[i] < (max(cp) -1 ) igap = max(where(cp lt ncp)) ; linear interp nntf = interpol( tf[igap:(igap+1)], cp[igap:(igap+1)], ncp) cp = [cp[0:igap], ncp, cp[igap+1:*]] if N_elements(ntf) gt 0 then nntf = ntf[i] tf = [tf[0:igap], nntf, tf[igap+1:*]] endfor return end pro delete_cps, cp @xcpe_common.inc keep = where(kf_cps ne cp) kf_cps = kf_cps[keep] keep = where(cps ne cp) cps = cps[keep] tfun = tfun[keep] keep = where(d_cps ne cp) d_cps = d_cps[keep] d_tfun = d_tfun[keep] keep = where(t_cps ne cp) t_cps = t_cps[keep] t_tfun = t_tfun[keep] keep = where(r_cps ne cp) r_cps = r_cps[keep] r_tfun = r_tfun[keep] keep = where(p_cps ne cp) p_cps = p_cps[keep] p_tfun = p_tfun[keep] keep = where(y_cps ne cp) y_cps = y_cps[keep] y_tfun = y_tfun[keep] keep = where(cx_cps ne cp) cx_cps = cx_cps[keep] cx_tfun = cx_tfun[keep] keep = where(cy_cps ne cp) cy_cps = cy_cps[keep] cy_tfun = cy_tfun[keep] keep = where(cz_cps ne cp) cz_cps = cz_cps[keep] cz_tfun = cz_tfun[keep] keep = where(ss_cps ne cp) ss_cps = ss_cps[keep] ss_tfun = ss_tfun[keep] keep = where(min_cps ne cp) min_cps = min_cps[keep] min_tfun = min_tfun[keep] keep = where(max_cps ne cp) max_cps = max_cps[keep] max_tfun = max_tfun[keep] return end function cps_from_var_index, vi @xcpe_common.inc case vi OF 0: cp = d_cps 1: cp = p_cps 2: cp = r_cps 3: cp = y_cps 4: cp = t_cps 5: cp = cx_cps 6: cp = cy_cps 7: cp = cz_cps 8: cp = ss_cps 9: cp = min_cps 10:cp = max_cps ENDCASE return, cp end function tfun_from_var_index, vi @xcpe_common.inc case vi OF 0: tf = d_tfun 1: tf = p_tfun 2: tf = r_tfun 3: tf = y_tfun 4: tf = t_tfun 5: tf = cx_tfun 6: tf = cy_tfun 7: tf = cz_tfun 8: tf = ss_tfun 9: tf = min_tfun 10:tf = max_tfun ENDCASE return, tf end pro initialize_path_variables @xcpe_common.inc var_min = [0.01, 0., 0., 0., 0., 0., 0., 0., 0.,0.,0.] var_max = [1.1, 360, 360., 360., 1., 1., 1., 1., 0.,1.,1.] ; using splines for all as default spl = intarr(11) + 1 splstrength = FLTARR(11) + 5. splstrength[5:7] = 10 ; tough spline for position tl = strarr(2) locids = -1 lrise = 1.*[0, 1] flat = 1.*[0,0] d_cps = [0, Nframetimes-1] d_tfun = replicate((var_max[0]+var_min[0])/2, 2) p_cps = [0, Nframetimes-1] p_tfun = flat r_cps = [0, Nframetimes-1] r_tfun = flat y_cps = [0, Nframetimes-1] y_tfun = flat t_cps = [0, Nframetimes-1] t_tfun = lrise kf_cps = [0, Nframetimes-1] ; keyframe locations nfh = (Float(Nheight)/2-1) cx_cps = [0, Nframetimes-1] cx_tfun = [0.5, 0.5] cy_cps = [0, Nframetimes-1] cy_tfun = [0.5, 0.5] cz_cps = [0, Nframetimes-1] cz_tfun = [0.5, 0.5] ss_cps = [0, Nframetimes-1] ss_tfun = flat min_cps = [0, Nframetimes-1] min_tfun = [0., 0.] max_cps = [0, Nframetimes-1] max_tfun = [1., 1.] return end pro save_state, FILE=save_name @xcpe_common.inc if N_elements(save_name) eq 0 then $ save_name = DIALOG_PICKFILE(FILTER = '*.sav', $ TITLE = 'select a .sav file to save current xcamerapath session.' , $ /WRITE) if (save_name ne '') then begin if (NOT strmatch(save_name, '*.sav')) then save_name += '.sav' save, d_cps, d_tfun, p_cps, p_tfun, r_cps, r_tfun, $ y_cps, y_tfun, t_cps, t_tfun, ss_cps, ss_tfun, $ cx_cps, cx_tfun, cy_cps, cy_tfun, cz_cps, cz_tfun, $ min_cps, min_tfun, max_cps, max_tfun, $ spl, splstrength, logdist, tl, locids, kf_cps, $ tfun, cps, psave, pnt, NFrames, NCoarseFrames, $ color, NframeTimes, Nheight, var_index, var_min, var_max, $ FILENAME=save_name print, 'wrote current state to :', save_name endif return end function check_cancel stopit = 0 if N_ELEMENTS(stit) eq 0 then stit = 0 a = get_kbrd(0) if N_elements(a) gt 0 then $ if (a[0] ne '') then begin stopit = 1 endif return, stopit end function convert_xyz, ixyz nl = (size(ixyz))[2] ones = ixyz[0,*] ones[*] = 1. v= ([[!X.S[0] + !X.S[1] *reform(ixyz[0,*])], $ [!Y.S[0] + !Y.S[1] *reform(ixyz[1,*])], $ [!Z.S[0] + !Z.S[1] *reform(ixyz[2,*])], [ones[*]]]) xyz=transpose(v # !p.t) return, xyz[0:2,*] end function xy_of_visible_points_in_view, td, maximagedim, PIXELS=pixels, xy=xy scale = min(1./(convert_xyz([1,1,1])-convert_xyz([0,0,0]))) onepix = scale/maximagedim levpix = ((td.dx_level)[*])/onepix vlevels= where(levpix ge pixels) pflag = where_is_in((*td.level_ptr), vlevels) ; index of visible points xyz = convert_xyz(transpose([[(*td.x_ptr)[*]], $ ; convert those to current coords [(*td.y_ptr)[*]], [(*td.z_ptr)[*]]])) print, 'xyz:', size(xyz) ind = where(((xyz[0,*] le 1.) and (xyz[0,*] ge 0.)) and $ ((xyz[1,*] le 1.) and (xyz[1,*] ge 0.)) and $ ((xyz[2,*] le 1.) and (xyz[2,*] ge 0.)) and pflag) xy = [xyz[0,ind], xyz[1,ind]] print, 'ind,xy', size(ind), size(xy) return, ind end ; xcamerapath ; FUNCTION Rvalue, Eid WIDGET_CONTROL,Eid,GET_VALUE=value RETURN, value END function dc,r,g,b return, R + 256L * (G + 256L * B) end function rotx, v, an, radian=d f = 180./!pi if N_elements(d) ne 0 then f=1D a=-an/f r = double([[1.,0. ,0.],$ [0., cos(a),sin(a)], $ [0.,-sin(a),cos(a)]]) u = r # v return, u end function roty, v, an, radian=d ; counter clockwise rotation around y axis when looking at -y direction f = 180./!pi if N_elements(d) ne 0 then f=1D a=-an/f r = double([[cos(a),0. ,-sin(a)],$ [0., 1. , 0. ], $ [sin(a), 0., cos(a)]]) u = r # v return, (u) end function rotz, v, an, radian=d f = 180./!pi if N_elements(d) ne 0 then f=1D a=-an/f r = double([[cos(a),sin(a) ,0.],$ [-sin(a),cos(a),0], $ [0. , 0. ,1.]]) u = r # v return, (u) end pro scale_points, vec, N, nN factor = DOUBLE(N)/(nn) vec = ROUND(1./factor*vec) < nN-1 return end pro scale_all_points, nN @xcpe_common.inc scale_points, kf_cps, Nframetimes, nN scale_points, cps, Nframetimes, nN scale_points, d_cps, Nframetimes, nN scale_points, p_cps, Nframetimes, nN scale_points, r_cps, Nframetimes, nN scale_points, y_cps, Nframetimes, nN scale_points, t_cps, Nframetimes, nN scale_points, cx_cps, Nframetimes, nN scale_points, cy_cps, Nframetimes, nN scale_points, cz_cps, Nframetimes, Nn scale_points, ss_cps, Nframetimes, nN scale_points, min_cps, Nframetimes, nNs cale_points, max_cps, Nframetimes, nN return end pro move_all_kf, x @xcpe_common.inc ind = where(kf_cps eq movingcp) if ind[0] ge 0 then begin kf_cps[ind] = x endif else begin print, movingcp, ' is not a keyframe ..' return endelse ind = where(d_cps eq movingcp) if ind[0] ge 1 then d_cps[ind] = x ind = where(t_cps eq movingcp) if ind[0] ge 1 then t_cps[ind] = x ind = where(r_cps eq movingcp) if ind[0] ge 1 then r_cps[ind] = x ind = where(p_cps eq movingcp) if ind[0] ge 1 then p_cps[ind] = x ind = where(y_cps eq movingcp) if ind[0] ge 1 then y_cps[ind] = x ind = where(cx_cps eq movingcp) if ind[0] ge 1 then cx_cps[ind] = x ind = where(cy_cps eq movingcp) if ind[0] ge 1 then cy_cps[ind] = x ind = where(cz_cps eq movingcp) if ind[0] ge 1 then cz_cps[ind] = x ind = where(min_cps eq movingcp) if ind[0] ge 1 then min_cps[ind] = x ind = where(max_cps eq movingcp) if ind[0] ge 1 then max_cps[ind] = x movingcp = x return end pro sort_all @xcpe_common.inc ind = sort(d_cps) d_cps = d_cps[ind] d_tfun = d_tfun[ind] ind = sort(t_cps) t_cps = t_cps[ind] t_tfun = t_tfun[ind] ind = sort(r_cps) r_cps = r_cps[ind] r_tfun = r_tfun[ind] ind = sort(y_cps) y_cps = y_cps[ind] y_tfun = y_tfun[ind] ind = sort(cx_cps) cx_cps = cx_cps[ind] cx_tfun = cx_tfun[ind] ind = sort(cy_cps) cy_cps = cy_cps[ind] cy_tfun = cy_tfun[ind] ind = sort(cz_cps) cz_cps = cz_cps[ind] cz_tfun = cz_tfun[ind] ind = sort(min_cps) min_cps = min_cps[ind] min_tfun = min_tfun[ind] ind = sort(max_cps) max_cps = max_cps[ind] max_tfun = max_tfun[ind] ind = sort(ss_cps) ss_cps = ss_cps[ind] ss_tfun = ss_tfun[ind] return end pro adjust_min_max @xcpe_common.inc for i=0,10 do begin tf = tfun_from_var_index(i) var_max[i] = var_max[i] > max(tf) var_min[i] = var_min[i] < min(tf) endfor return end pro write_frame_file, file_name, pa, NframeTimes, WF_FORMAT=wf_format openw, lun, file_name, /GET_LUN lines = (size(pa))[2] ; for i=0,lines-1 do printf, lun, pa[0,i], pa[1,i], pa[2,i], pa[3,i], ; pa[4,i], pa[5,i], pa[6,i], pa[7,i], format='(8G12.6)' for i=0L,lines-1 do begin setup_view, pa[*,i], NplayW, NplayW pos = convert_xyz(pa[5:7,i]) if N_elements(wf_format) eq 0 then begin printf, lun, strtrim(string( $ pos[0], pos[1],pos[2]+pa[0,i], $ -pa[1,i], pa[2,i], pa[3,i], $ 30., pa[0,i], format='(9G12.6)'), 2) endif else begin ; .wf format for partiview o1 = rotz([0.,0., pa[0,i]], -pa[3,i]) o2 = rotx(o1, -pa[1,i]) offs = roty(o2, -pa[2,i]) pos = pa[5:7,i]+offs[*] printf, lun, pos[0], pos[1], pos[2], pa[1,i], pa[2,i], pa[3,i], 90, pa[0,i], pa[4,i], format='(9g20.12)' ; if i lt 30 then print, pos[0], pos[1], pos[2], -pa[1,i], ; -pa[2,i], -pa[3,i], 90, pa[0,i], pa[4,i], format='(9g20.14)' if i lt 30 then print, pa[5,i], pa[6,i],pa[7,i], pa[0,i], pa[4,i] ; if i lt 30 then print, pa[0:7,i] , format='(8g9.4)' endelse endfor setup_view, 1, NframeTimes, Nheight, /reset close, lun free_lun, lun if lines lt 30 then for i=0,lines-1 do print, pa[0,i], pa[1,i], pa[2,i], pa[3,i], pa[4,i], pa[5,i], pa[6,i], pa[7,i], pa[8,i], pa[9,i], pa[10,i], format='(12g9.4)' print, 'wrote ', file_name save_state, FILE='~/currentpath.sav' return end function intfunction, cps, tfun, nf, spl, splstrength, NframeTimes, POINT=point ; returns interpoalted function with a range from 0..1 if (N_ELEMENTS(POINT) eq 1) THEN a = [point] $ else a = findgen(nf)/(FLOAT(nf)-1)*(Nframetimes-1) if ((spl eq 1) and (N_elements(cps) gt 2) and (N_elements(tfun) gt 2)) then $ iff = (SPLINE(float(cps), float(tfun), a, splstrength)) $ ELSE iff = (INTERPOL( float(tfun), float(cps), a)) return, iff end function normalize_func, tfun, vmin, vmax ; sets function to from vmin - vmax inmin = min(tfun, max=inmax) nf = vmin + tfun*(vmax-vmin) ; now goes from vmin to vmax RETURN, nf END function screen_to_range, y, vi @xcpe_common.inc v = DOUBLE(y)/(Nheight-1)*(var_max[vi]-var_min[vi]) + var_min[vi] if vi eq 0 and logdist then $ v = 10^(DOUBLE(y)/(Nheight-1)* $ (alog10(var_max[vi])-alog10(var_min[vi])) + alog10(var_min[vi])) return, v end function value, icp, vi @xcpe_common.inc c = cps_from_var_index(vi) tf= tfun_from_var_index(vi) v = ((intfunction(c, tf, Nframetimes, spl[vi], splstrength[vi], NFrameTimes)))[icp] if vi eq 0 and logdist then $ v = 10.^((intfunction(c, alog10(tf), Nframetimes, spl[vi], splstrength[vi], NFrameTimes)))[icp] return, v > var_min(vi) < var_max(vi) end FUNCTION make_path, nf @xcpe_common.inc pa = dblarr(11, nf) a = fix(findgen(nf)/(FLOAT(nf)-1)*(Nframetimes-1)) for i=0,10 do pa[i,*] = value(a, i) RETURN, pa END PRO XCPE_PSAVE ;Save/Restore our plotting state. ; Swaps our state with the current state each time its called. COMPILE_OPT hidden @xcpe_common.inc tmp = { XCPE_psave, win: !d.window, x: !x.s, y: !y.s , xtype: !x.type, $ ytype: !y.type, clip: !p.clip } wset, psave.win ;!x.type = psave.xtype ;!y.type = psave.ytype ;!x.s = psave.x ;!y.s = psave.y !p.clip = psave.clip psave = tmp end pro XCPE_alert_caller COMPILE_OPT hidden @xcpe_common.inc ErrorStatus = 0 CATCH, ErrorStatus if (ErrorStatus NE 0) then begin CATCH, /CANCEL v = DIALOG_MESSAGE(['Unexpected error in XCameraPath:', $ !ERROR_STATE.msg], $ /ERROR) return endif if (STRLEN(updt_callback) gt 0) then begin if (PTR_VALID(p_updt_cb_data)) then begin CALL_PROCEDURE, updt_callback, DATA=*(p_updt_cb_data) endif else begin CALL_PROCEDURE, updt_callback endelse endif end pro store_current_values @xcpe_common.inc ind = uniq(cps, sort(cps)) cps = cps[ind] tfun = tfun[ind] case var_index OF 0: BEGIN d_cps = cps d_tfun = tfun END 1: BEGIN p_cps = cps p_tfun = tfun END 2: BEGIN r_cps = cps r_tfun = tfun END 3: BEGIN y_cps = cps y_tfun = tfun END 4: BEGIN t_cps = cps t_tfun = tfun END 5: BEGIN cx_cps = cps cx_tfun = tfun END 6: BEGIN cy_cps = cps cy_tfun = tfun END 7: BEGIN cz_cps = cps cz_tfun = tfun END 8: BEGIN ss_cps = cps ss_tfun = tfun END 9: BEGIN min_cps = cps min_tfun = tfun END 10: BEGIN max_cps = cps max_tfun = tfun END ENDCASE return end PRO XCPE_draw_cps, i, c ;COMPILE_OPT hidden @xcpe_common.inc color = mycolors[var_index] tc = color ;if i[0] eq -1 then j = indgen(n_elements(cps)) else j = i j = indgen(n_elements(cps)) WIDGET_CONTROL, state.draw, GET_VALUE=win wset, win erase, color=0 setup_view, 0, NFrameTimes, Nheight, /reset t3d, /reset !p.t3d = 0 plot, [0, Nframetimes-1], [0, Nheight-1], xstyle=1, $ ystyle=1, xmargin = [0,0], ymargin=[0,0], ticklen = 0.01*Nwidth/Nframetimes, $ /NODATA, xtickname = replicate(' ', 10), ytickname = replicate(' ', 10) pfun = (tfun-var_min[var_index])/(var_max[var_index]-var_min[var_index])*(Nheight-1) if logdist and var_index eq 0 then pfun = ((alog10(tfun) - alog10(var_min[var_index]))$ /(alog10(var_max[var_index])-alog10(var_min[var_index])))*(Nheight-1) pfun = pfun < (Nheight-1) > 0 plots, cps[j], pfun[j], /noclip, color = tc, linestyle=1 plots, cps[j], pfun[j], /noclip, psym=6, color = tc, thick=2 points = [kf_cps] ; [cx_cps, cy_cps, cz_cps, d_cps, t_cps, r_cps, y_cps, p_cps] ind = sort(points) upoints = points[uniq(points, ind)] Nlocs = N_elements(upoints) thick = 0 for i=0,Nlocs-1 do begin ; plot dotted lines where there are control points in any field ; thick = 1 - thick plots, [upoints[i],upoints[i]], [0, Nheight], linestyle=1+thick xyouts, upoints[i], 10, strcompress(string(fix(float(upoints[i])/Nframetimes*(Nframes-1)))), size=1 endfor a = findgen(Nframetimes);*max(cps)/Nframetimes if ((N_elements(j) gt 2) and spl[var_index] ne 0) then $ oplot, a, SPLINE(float(cps[j]), float(pfun[j]), a, splstrength[var_index]) > 0 < Nheight, /noclip, color = tc, thick=2 $ ELSE oplot, a, INTERPOL(float(pfun[j]), float(cps[j]), a) > 0 < Nheight, /noclip, color = tc, thick=2 ; print, cy_cps, cy_tfun END function check_cancel stopit = 0 a = get_kbrd(0) if N_elements(a) gt 0 then $ if (a[0] eq 'c' or a[0] eq 'C') then begin stopit = 1 endif return, stopit end pro send_to_partiview, x, y=ypo @xcpe_common.inc pa = make_path(Nframetimes) x = LONG(x) > 0 < (Nframetimes-1) pa = pa[*,x] if N_elements(ypo) gt 0 then pa[var_index] = ypo print, 'distance, etc:', pa o1 = rotz([0.,0., pa[0]], -pa[3]) o2 = rotx(o1, -pa[1]) offs = roty(o2, -pa[2]) pos = pa[5:7]+offs[*] print, 'jump', strcompress(string([pos[0], pos[1], pos[2], pa[1], pa[2], pa[3]])) print, 'center', strcompress(string([pa[5:7], pa[0]/50.])) print, 'clip '+ string(pa[0]/10) return end PRO xcamerapath_event, event COMPILE_OPT hidden @xcpe_common.inc WIDGET_CONTROL, event.id, GET_UVALUE = eventval if N_elements(eventval) eq 0 then begin case tag_names(event, /structure_name) of 'WIDGET_BASE': BEGIN ; resize event WIDGET_CONTROL, event.top, TLB_GET_SIZE = newSize Nwidth = newSize[0] widget_control, state.draw, scr_xsize=Nwidth print, 'resize', newsize goto, interp_cps END ELSE: ENDCASE END ELSE BEGIN CASE eventval OF "DRAW_REGION": BEGIN widget_control, w_text_line, get_value=ct ; print, event.x, event.y x = event.x fr = strmid(ct, strpos(ct, 'y')-1) widget_control, w_text_line, $ set_value="frame ="+strcompress(string(ROUND(float(x)/Nframetimes*Nframes)))+ $ fr if event.press ne 0 then begin ;Pressed button? dmin = 1.0e8 ;Find closest control pnt p = convert_coord(event.x, event.y, /TO_DATA, /DEVICE) x = fix(p[0]) y = fix(p[1]) movingcp = -2 movingkf = 0 for i=0, n_elements(cps)-1 do begin d = (p[0]-cps[i])^2 ; + (p[1]-tfun[i])^2 ; dist ^ 2 if d lt dmin then begin dmin = d pnt = i endif endfor ; print, pnt, 'kf:', kf_cps, 'cps', cps[pnt] if total(cps[pnt] eq kf_cps) gt 0 then begin movingkf = 1 movingcp = cps[pnt] print, 'moving keyframe', movingcp endif if event.press eq 1 then ypnt = p[1] else ypnt = -1 if event.press eq 4 then xpnt = cps[pnt] else xpnt=-1 print, event.press, event.release print, xpnt, ypnt return endif if event.release ne 0 then begin ;Released button? pnt = -1 ; copy function into the correct container store_current_values if movingkf then sort_all movingkf = 0 send_to_partiview, x if xpnt ge 0 then goto, show_track ; right click on canvas updates POI and camera endif if pnt lt 0 then return ;Don't care here... p = convert_coord(event.x, event.y, /TO_DATA, /DEVICE) ;Coord of mouse n = Nframetimes -1 ;Into range.... if xpnt lt 0 then x = fix(p[0]) > 0 < n else x = xpnt ; if pnt eq 0 then x = 0 else $ ;1st & last are fixed ; if pnt eq m then x = n cps[pnt] = x if movingkf then begin move_all_kf, x endif if ypnt lt 0 then tfun[pnt] = screen_to_range(p[1], var_index) XCPE_draw_cps, -1 ypo = tfun[pnt] widget_control, w_text_line, $ set_value="frame ="+strcompress(string(ROUND(float(x)/Nframetimes*Nframes)))+ $ " y ="+strcompress(string(ypo)) if withinpartiview then send_to_partiview, x, y=ypo return END 'BGROUP_VAR': BEGIN ov = var_index var_index = Event.value selected_field: nv = var_index widget_control, w_var, SET_VALUE=var_index widget_control, w_min_value, SET_VALUE=var_min[nv] widget_control, w_max_value, SET_VALUE=var_max[nv] widget_control, w_SPLSTRENGTH, SET_VALUE=[0.1, splstrength[nv],10] if logdist eq 0 then widget_control, w_logdist, set_value = 'lin dist.' if logdist eq 1 then widget_control, w_logdist, set_value = 'log dist.' cps = cps_from_var_index(var_index) tfun = tfun_from_var_index(var_index) goto, interp_cps END "LOGDIST": BEGIN if logdist eq 0 then logdist = 1 else logdist = 0 if logdist eq 0 then widget_control, w_logdist, set_value = 'lin dist.' if logdist eq 1 then widget_control, w_logdist, set_value = 'log dist.' if ((logdist eq 1) and (var_min[0] le 0.)) then var_min[0] = 1e-6 print, 'now interpreting distance y-axis as ' if logdist eq 1 then print, 'logarithmic' $ else print, 'linear axis' goto, interp_cps END "NEWPATH": BEGIN initialize_path_variables goto, selected_field END "READ LOCATIONS" : BEGIN location_name = DIALOG_PICKFILE(FILTER = '*.label', $ DIALOG_PARENT=state.bases[0], $ TITLE = 'select a position files (same as partiview .label)' , $ /NOCONFIRM, /READ) if location_name eq '' then break openr, lun, location_name, /get_lun line = '' max_number_of_locations = 8000 xl = dblarr(3, max_number_of_locations) ; positions tl = strarr(max_number_of_locations) ; names are optional cntl = 0L cnte = 0L while not EOF(lun) DO BEGIN readf, lun, line sp = strsplit(line, /extract) Nparts = N_elements(sp) cntl++ ; count how many lines we read if line ne '' then $ if (Nparts ge 3) and (strmid(line, 0,1) ne '#') then begin ; should be a valid entry for i=0,1 do begin ; add to points for every location xl[*,cnte] = DOUBLE(sp[0:2]) if Nparts gt 4 then tl[cnte] = strjoin(sp[4:*]) ; this is the label cnte++ ; count how many entries we found endfor endif ENDWHILE close , lun free_lun, lun print, 'read ', cnte/2, ' locations from ', cntl, ' lines in ', location_name locids = [-1, INDGEN(cnte)] ; remember the indices xl = xl[*,0:cnte-1] ; just keep nonzero entries tl = tl[0:cnte-1] adjust_min_max ; times times = FIX(FLOAT(Nframetimes-1)/(cnte+1)*(INDGEN(cnte)+1)) print, times, 'times' add_point, times, cx_cps, cx_tfun, ntf=xl[0,*] add_point, times, cy_cps, cy_tfun, ntf=xl[1,*] add_point, times, cz_cps, cz_tfun, ntf=xl[2,*] add_point, times, d_cps, d_tfun add_point, times, r_cps, r_tfun add_point, times, p_cps, p_tfun add_point, times, y_cps, y_tfun add_point, times, t_cps, t_tfun add_point, times, ss_cps, ss_tfun add_point, times, min_cps, min_tfun add_point, times, max_cps, max_tfun kf_cps =[kf_cps, times] widget_control, w_min_value, SET_VALUE=var_min[var_index] widget_control, w_max_value, SET_VALUE=var_max[var_index] goto, selected_field END "PLAY": BEGIN cnt = 0L ; loop over frames while cnt lt Ncoarseframes-1 do begin tcp = LONG(float(cnt)/(Nframes-1)*(Nframetimes-1)) print, cnt, tcp send_to_partiview, tcp wait, .05 cnt += 1 if check_cancel() then break endwhile goto, interp_cps END 'SHOWTRACK': BEGIN show_track: pa = make_path(Nframes) openw, lun, '~/deleteme.speck', /get_lun printf, lun, 'datavar 0 index' printf, lun, 'datavar 1 time' for i=0, Nframes-1,1 do begin printf, lun, strcompress(strjoin(string([pa[5:7,i], i, pa[4,i]]) )) endfor close, lun free_lun, lun wait, .9 ; camera position openw, lun, '~/deleteme2.speck', /get_lun printf, lun, 'datavar 0 index' printf, lun, 'datavar 1 time' for i=0, Nframes-1,1 do begin pos = pa[5:7,i]+roty(rotx(rotz([0.,0.,pa[0,i]],-pa[3,i]),-pa[1,i]),-pa[2,i]) ; printf, lun, 'mesh -c '+string(i) + ' -s wire {' ; ; connect camera and poi ; printf, lun, '1 2' ; printf, lun, strcompress(strjoin(string(pa[5:7,i]))) ; printf, lun, strcompress(strjoin(string(pos))) ; printf, lun, '}' printf, lun, strcompress(strjoin(string([pos[0:2], i, pa[4,i]]) )) endfor close, lun free_lun, lun print, 'read camera_path.cf' ; p = spawn('\rm ~/deleteme.speck') END "MINIMUM": BEGIN var_min[var_index] = (Rvalue(Event.id))[0] if ((logdist eq 1) and (var_min[0] le 0.)) then var_min[0] = 1e-6 if (var_max[var_index] le var_min[var_index]) then $ var_min[var_index] = var_max[var_index] goto, selected_field END "MAXIMUM": BEGIN var_max[var_index] = (Rvalue(Event.id))[0] if (var_max[var_index] le var_min[var_index]) then $ var_max[var_index] = var_min[var_index] goto, selected_field END "HELP" : XDisplayFile, "xcamerapath.txt", $ TITLE = "XCameraPath Help", $ GROUP = event.top, $ WIDTH = 80, $ HEIGHT = 46 "HELPPARTI": XDisplayFile, "withpartiview.txt", $ TITLE = "XCameraPath Help", $ GROUP = event.top, $ WIDTH = 80, $ HEIGHT = 46 "DONE": BEGIN save_state WIDGET_CONTROL, event.top, /DESTROY r0 = 0 & g0 = 0 & b0 = 0 ;Free common if PTR_VALID(p_updt_cb_data) then PTR_FREE, p_updt_cb_data if withinpartiview then exit ENDCASE "WRITE_FRAMES": BEGIN pa = make_path(Nframes) write_frame_file, '~/frames.wf', pa, nFrameTimes, WF_FORMAT=wf_format if withinpartiview then begin wait, .5 print, 'readpath ~/frames.wf' endif END "WRITE_COARSE_FRAMES": BEGIN pa = make_path(NCoarseFrames) write_frame_file, '~/frames.wf', pa, nFrameTimes, WF_FORMAT=wf_format if withinpartiview then begin wait, .5 print, 'readpath ~/frames.wf' endif END "WRITE_FRAGMENT_FRAMES": BEGIN pa = make_path(NFrames) device, /cursor_crosshair cursor, x, y device, /cursor_original ci = (float(x)/Nframetimes*Nframes) cm = round(ci - NcoarseFrames/2) > 0 cma= round(ci + NcoarseFrames/2) < Nframes-1 write_frame_file, '~/frames.wf', pa[*,cm:cma], nFrameTimes, WF_FORMAT=wf_format if withinpartiview then begin wait, .5 print, 'readpath ~/frames.wf' endif END 'NFRAMETIMES': BEGIN widget_control, event.id, GET_VALUE = nNFrametimes print, 'event for NFRAMETIMES', nNframetimes nNframetimes = nNframetimes > 10 scale_all_points, nNframetimes Nframetimes = nNframetimes widget_control, state.draw, draw_xsize=Nframetimes widget_control, state.draw, draw_ysize=Nheight-1 goto, selected_field END "SAVE_STATE": BEGIN save_state END "RESTORE_STATE":BEGIN restore_name = DIALOG_PICKFILE(FILTER = '*.sav', $ DIALOG_PARENT=state.bases[0], $ TITLE = 'select an existing .sav file to restore previous xcamerapath session' , $ /NOCONFIRM, /READ) if (restore_name ne '') then BEGIN restore, restore_name, /VERBOSE widget_control, state.draw, draw_xsize=Nframetimes widget_control, state.draw, draw_ysize=Nheight-1 goto, selected_field endif END "SPLBUTTON": BEGIN if spl[var_index] eq 0 then spl[var_index] = 1 $ else spl[var_index] = 0 goto, interp_cps End 'SPLSTRENGTH': BEGIN splstrength[var_index] = (Rvalue(Event.id))(1) goto, interp_cps END "NFRAMES": BEGIN widget_control, event.id, GET_VALUE = NFrames print, nframes END "NCOARSEFRAMES": BEGIN widget_control, event.id, GET_VALUE = NCoarseFrames print, ncoarseframes END "TFUNR": BEGIN reset_tfun: XCPE_psave XCPE_draw_cps, -1, 0 ;Erase all tfun = cps ;Linear ramp goto, interp_cps END "REMCP": BEGIN n = n_elements(cps) if n gt 2 then begin XCPE_psave XCPE_draw_cps, -1, 0 igap = 0 device, /cursor_crosshair cursor, x, y device, /cursor_original ind = sort(abs(x-cps)) igap = ind[0] tcp = cps[igap] if tcp ne 0 and tcp ne Nframetimes-1 then delete_cps, cps[igap > 1] goto, interp_cps ENDIF END "ADDCP": BEGIN XCPE_psave XCPE_draw_cps, -1, 0 igap = 0 ;Find largest gap ; for i=0, n_elements(cps)-2 do $ ; if (cps[i+1] - cps[i]) gt (cps[igap+1]-cps[igap]) then $ ; igap = i ; newcps = (cps[igap]+cps[igap+1])/2 ; newtfun=(tfun[igap]+tfun[igap+1])/2 device, /cursor_crosshair cursor, x, y igap = max(where(cps le x)) device, /cursor_original newcps = fix(x) newtfun = screen_to_range(y, var_index) cps = [ cps[0:igap], newcps, cps[igap+1:*]] ind = where(locids gt igap, count) if count gt 0 and var_index ge 5 and var_index le 7 then $ locids[ind] += 1 ; shift the location markers print, newtfun print, tfun tfun = [ tfun[0:igap], newtfun, tfun[igap+1:*]] print, tfun interp_cps: XCPE_draw_cps, -1 ;Redraw new ; XCPE_transfer, /update XCPE_psave ;Restore old points ; if n_elements(reset_all) then goto, reset_all END "ADDLOCCP": BEGIN XCPE_psave XCPE_draw_cps, -1, 0 device, /cursor_crosshair cursor, x, y device, /cursor_original newcps = fix(x) a = fltarr(4) a[0] = newcps a[1] = value(newcps, 5) a[2] = value(newcps, 6) a[3] = value(newcps, 7) xvaredit, a, NAME='Enter x, y, z of location', group=event.top add_point, newcps, cx_cps, cx_tfun, ntf=a[1] add_point, newcps, cy_cps, cy_tfun, ntf=a[2] add_point, newcps, cz_cps, cz_tfun, ntf=a[3] kf_cps = [kf_cps, newcps] locids = [locids, newcps] goto, selected_field END "ADDKFCP": BEGIN XCPE_psave XCPE_draw_cps, -1, 0 igap = 0 device, /cursor_crosshair cursor, x, y igap = max(where(cps le x)) device, /cursor_original newcps = FIX(x) st = '' if withinpartiview then for i=0,4 do print, 'jump' wait, .2 read, st, prompt='Enter camera: x y z Rx Ry Rz or whole response from jump command in partiview: ' stc = strsplit(st,/extract) if stc[0] eq 'jump' then stc = stc[1:*] if N_elements(stc) lt 6 then begin print, 'not enough inormation from ', st return endif kfs = double(stc[0:5]) ; compute center from camera position and orientation dis = value(newcps, 0) o1 = rotz([0.,0.,dis], -stc[5]) o1 = rotx(o1, -stc[3]) o1 = roty(o1, -stc[4]) pos = stc[0:2] - o1 printf,-2, 'pos, stc, o1', pos, stc, o1, dis add_point, newcps, d_cps, d_tfun add_point, newcps, t_cps, t_tfun add_point, newcps, cx_cps, cx_tfun, ntf=pos[0] add_point, newcps, cy_cps, cy_tfun, ntf=pos[1] add_point, newcps, cz_cps, cz_tfun, ntf=pos[2] add_point, newcps, p_cps, p_tfun, ntf=stc[3] add_point, newcps, r_cps, r_tfun, ntf=stc[4] add_point, newcps, y_cps, y_tfun, ntf=stc[5] adjust_min_max kf_cps = [kf_cps, newcps] ; add point to list of keyframes ind = where(locids gt igap, count) if count gt 0 then $ locids[ind] += 1 ; shift the location markers send_to_partiview, newcps goto, selected_field END "EDIT": BEGIN a = fltarr(2,N_elements(tfun)) a[1,*] = normalize_func(tfun/(Nheight-1), var_min[var_index], var_max[var_index]) a[1,*] = tfun a[0,*] = float(cps) if var_index ge 5 and var_index le 7 then a[1,*] = tfun xvaredit, a, NAME='Edit Control Points', group=event.top cps = ROUND(a[0,*]) ; tfun = (a[1,*]-var_min[var_index])/(var_max[var_index]-var_min[var_index])*(Nheight-1) tfun = a[1,*] if var_index ge 5 and var_index le 7 then tfun = a[1,*] goto, interp_cps END "EQUALPOINTS": BEGIN ; wait for click and select nearest (in time) control point from which ; to copy igap = 0 device, /cursor_crosshair cursor, x, y igap = max(where(cps le x)) device, /cursor_original oldcps = FIX(x) ; click on next control point to copy values to igap2 = 0 device, /cursor_crosshair cursor, x, y igap = max(where(cps le x)) device, /cursor_original newcps = FIX(x) copy_all_values, oldcps, newcps goto, interp_cps END ELSE: BEGIN print, 'unrecognized event', event END END ; case eventval of ; if N_elements(eventval) eq 0 then if eventval ne "DONE" then XCPE_draw_cps, -1 ENDELSE ; if N_elements(eventval) END ;+ ; NAME: ; XCameraPath ; PURPOSE: ; A graphical interface to creating intuitive camerapaths ; ; CATEGORY: ; Widgets ; CALLING SEQUENCE: ; Xcamerapath, distance, Rx, Ry, Rz, time, Nframes ; INPUTS: ; None. ; KEYWORDS: ; UPDATECALLBACK: Set this keyword to a string containing the name of ; a user-supplied procedure that will be called when the color ; table is updated by XLOADCT. The procedure may optionally ; accept a keyword called DATA, which will be automatically ; set to the value specified by the optional UPDATECBDATA ; keyword. ; UPDATECBDATA: Set this keyword to a value of any type. It will be ; passed via the DATA keyword to the user-supplied procedure ; specified via the UPDATECALLBACK keyword, if any. If the ; UPDATECBDATA keyword is not set the value accepted by the ; DATA keyword to the procedure specified by UPDATECALLBACK ; will be undefined. ; ; OUTPUTS: ; distance, Rx, Ry, Rz, time, Nframes PRO XCameraPath, SILENT=silent_f, GROUP=group, FILE=file, $ MODAL=modal, BLOCK=block, UPDATECALLBACK=updt_cb_name, $ UPDATECBDATA=updt_cb_data_in, WF_FORMAT=wf, $ withinpartiview=wip COMPILE_OPT idl2 @xcpe_common.inc device, RETAIN=2 Nheight = 800 ; height of editor draw wideget Nwidth = 1050 ; its width NplayW = 600 ; size of play window withinpartiview = 1 ; make this default so things work with IDL -vm if N_elements(wip) gt 0 then if wip ne 0 then withinpartiview = 1 else $ withinpartiview = 0 Nframetimes = Nwidth locids = [-1] movingkf = 0 if N_elements(wf) eq 0 then wf = 1 ; .wf path format is default wf_format = wf ; wf_format = 0 is a format that has been tested to work with amira ; (using a particular amira script ... so should not be useful in general) ; only switch to distance should the rest of the state already be determined: var_index = 0 !p.t3d = 0 if (N_ELEMENTS(logdist) lt 1) then logdist = 0 if (N_ELEMENTS(NFrames) lt 1) then Nframes = 2700 if (N_ELEMENTS(NcoarseFrames) lt 1) then NcoarseFrames = 30 initialize_path_variables IF N_ELEMENTS(mid) lt 2 then begin Nh =Nframes/2-1 ns = 10L & npo = ns * 600 r = rebin(findgen(ns)/(ns-1), npo, /SAMPLE) if logdist then r = $ 10.^(alog10(var_min[0])+ r*(alog10(0.5)-alog10(var_min[0]))) $ else r = r+var_min[0] mid = dblarr(3, npo) seed = 3 mid[0,*] = randomu(seed, npo) - 0.5 mid[1,*] = randomu(seed, npo) - 0.5 mid[2,*] = randomu(seed, npo) - 0.5 midv = sqrt(mid[0,*]^2+mid[1,*]^2+mid[2,*]^2)/r mid[0,*] = mid[0,*]/midv mid[1,*] = mid[1,*]/midv mid[2,*] = (abs(mid[2,*]))/midv end MYCOLORS = [dc(255,255,255), dc(255,0,0), dc(0,255,0), dc(0,0,255),$ dc(200,200,200), dc(200,0,0), dc(0,200,0), dc(0,0,200), $ dc(155,155,155), dc(155,0,0), dc(0,155,0), dc(0,0,155), dc(155,155,155)] IF(XRegistered("xcamerapath") NE 0) THEN return IF N_ELEMENTS(block) EQ 0 THEN block=0 IF N_ELEMENTS(updt_cb_name) EQ 0 THEN updt_callback="" $ ELSE updt_callback=updt_cb_name IF N_ELEMENTS(updt_cb_data) GT 0 THEN p_updt_cb_data=PTR_NEW(updt_cb_data) $ ELSE p_updt_cb_data=PTR_NEW() values_button = lonarr(2) IF KEYWORD_SET(SILENT_f) THEN silent = SILENT_F ELSE silent = 1 ; Bases: ; 0 = transfer function drawable + buttons state = { bases: lonarr(4), draw: 0L, name_list: 0L } ; DJC - Added modal keyword. ; Moved "group_leader" keyword from XMANAGER to WIDGET_BASE. ; Ignore modal keyword if a group leader is not supplied. if (N_ELEMENTS(group) GT 0L) then $ base = WIDGET_BASE(TITLE="XCameraPath", /COLUMN, GROUP_LEADER=group, $ MODAL=KEYWORD_SET(modal), /TLB_SIZE_EVENTS) $ else $ base = WIDGET_BASE(TITLE="XCameraPath", /COLUMN, MBAR=wmbar, /TLB_SIZE_EVENTS) ; Setting the managed attribute indicates our intention to put this app ; under the control of XMANAGER, and prevents our draw widgets from ; becoming candidates for becoming the default window on WSET, -1. XMANAGER ; sets this, but doing it here prevents our own WSETs at startup from ; having that problem. WIDGET_CONTROL, /MANAGED, base fileb = WIDGET_BUTTON(wmbar, VALUE='File', UVALUE = "FILE", /MENU) done = WIDGET_BUTTON(fileb, VALUE='New Path', UVALUE = "NEWPATH", ACCELERATOR='Ctrl+N') done = WIDGET_BUTTON(fileb, VALUE='Read Locations', UVALUE = "READ LOCATIONS", ACCELERATOR='Ctrl+O') done = WIDGET_BUTTON(fileb, VALUE='Write frames', UVALUE = "WRITE_FRAMES", ACCELERATOR='Ctrl+Shift+S') done = WIDGET_BUTTON(fileb, VALUE='Write coarse frames', UVALUE = "WRITE_COARSE_FRAMES", ACCELERATOR='Ctrl+S') done = WIDGET_BUTTON(fileb, VALUE='Write fragment frames', UVALUE = "WRITE_FRAGMENT_FRAMES", ACCELERATOR='Ctrl+F') done = WIDGET_BUTTON(fileb, VALUE='Save current state', UVALUE = "SAVE_STATE", ACCELERATOR='Alt+S') done = WIDGET_BUTTON(fileb, VALUE='Restore previous state', UVALUE = "RESTORE_STATE", ACCELERATOR='Ctrl+Shift+O') done = WIDGET_BUTTON(fileb, VALUE=' Done ', UVALUE = "DONE", ACCELERATOR='Ctrl+Q') toolb = WIDGET_BUTTON(wmbar, VALUE='Tools', UVALUE = "TOOLS", /MENU) w_spline_check = WIDGET_BUTTON(toolb, VALUE='Toggle Spline', UVALUE="SPLBUTTON", ACCELERATOR='Ctrl+L') junk1 = WIDGET_BUTTON(toolb, VALUE='Reset Function', UVALUE='TFUNR', ACCELERATOR='Ctrl+R') junk1 = WIDGET_BUTTON(toolb, VALUE='Add Control Point', UVALUE='ADDCP', ACCELERATOR='Ctrl+A') junk1 = WIDGET_BUTTON(toolb, VALUE='Add Location Point', UVALUE='ADDLOCCP', ACCELERATOR='Ctrl+Shift+A') junk1 = WIDGET_BUTTON(toolb, VALUE='Add Keyframe Point', UVALUE='ADDKFCP', ACCELERATOR='Ctrl+Shift+K') junk1 = WIDGET_BUTTON(toolb, VALUE='Remove Control Point', UVALUE='REMCP', ACCELERATOR='Ctrl+D') junk1 = WIDGET_BUTTON(toolb, VALUE='Edit Variables', UVALUE='EDIT', ACCELERATOR='Ctrl+E') junk1 = WIDGET_BUTTON(toolb, VALUE='Copy point', UVALUE='EQUALPOINTS', ACCELERATOR='Ctrl+Shift+E') w_playb = WIDGET_BUTTON(toolb, VALUE = 'Play', UVALUE='PLAY', ACCELERATOR="Ctrl+P") if withinpartiview then junk1 = WIDGET_BUTTON(toolb, VALUE='Show Track', UVALUE='SHOWTRACK', ACCELERATOR='Ctrl+T') help = WIDGET_BUTTON(wmbar, VALUE='Help', UVALUE = "HELPIT", /MENU, /help) about = WIDGET_BUTTON(help, VALUE='Introduction', UVALUE = "HELP") about = WIDGET_BUTTON(help, VALUE='Interact with Partiview', UVALUE = "HELPPARTI") junk = WIDGET_BASE(base, /ROW) junk = widget_base(base) for i=0,1 do state.bases[i] = WIDGET_BASE(junk, /COLUMN) sbase=WIDGET_BASE(state.bases[0], /ROW) ; Drawable for transfer function Btns123 = ['dist.', 'Rx', 'Ry', 'Rz', 'time', 'x','y','z', 'stereo', 'min', 'max'] w_var = CW_BGROUP(sbase, Btns123, $ SET_VALUE = var_index, $ ROW=1, /EXCLUSIVE, /NO_RELEASE,$ UVALUE='BGROUP_VAR') w_logdist = WIDGET_BUTTON(sbase, VALUE = 'log dist.', UVALUE='LOGDIST', $ TOOLTIP='Shows lin dist. when the distance is linear and log dist. when the distance axis is interpreted logarithmically.') if logdist eq 0 then widget_control, w_logdist, set_value = 'lin dist.' if logdist eq 1 then widget_control, w_logdist, set_value = 'log dist.' sbase=WIDGET_BASE(state.bases[0], /ROW) nsbase=WIDGET_BASE(sbase, /COLUMN) w_MIN_VALUE = CW_FIELD(nsbase, $ UVALUE = 'MINIMUM', $ TITLE='Min', $ VALUE=var_min[var_index], /FLOATING, /RETURN_EVENTS) w_MAX_VALUE = CW_FIELD(nsbase, $ UVALUE = 'MAXIMUM', $ TITLE='Max', $ VALUE=var_max[var_index], /FLOATING, /RETURN_EVENTS) w_SPLSTRENGTH = CW_MYFSLIDER(sbase, $ MAXIMUM=10., $ MINIMUM=0.1, TITLE='Spline Tension', $ UVALUE='SPLSTRENGTH', $ FORMAT='(F7.2)', /DRAG, $ VALUE=splstrength[var_index], /EDIT) nsbase=WIDGET_BASE(sbase, /COLUMN) w_NFRAMES = CW_FIELD(nsbase, $ UVALUE = 'NFRAMES', $ TITLE='# frames', $ VALUE=Nframes, /INTEGER, /ALL_EVENTS) w_NcoarseFRAMES = CW_FIELD(nsbase, $ UVALUE = 'NCOARSEFRAMES', $ TITLE='# coarse', $ VALUE=Ncoarseframes, /INTEGER, /ALL_EVENTS) nsbase=WIDGET_BASE(sbase, /COLUMN) w_width = CW_FIELD(nsbase, $ UVALUE = 'NFRAMETIMES', $ TITLE='Window width', $ VALUE=Nframetimes, /INTEGER, /RETURN_EVENTS) w_text_line = WIDGET_TEXT(state.bases[0], VALUE='x and y of points', $ UVALUE="TEXTWIDGET") state.draw = WIDGET_DRAW(state.bases[0], xsize = Nwidth, ysize = Nheight, $ X_SCROLL_SIZE=NFrameTimes, Y_SCROLL_SIZE=Nheight, $ /BUTTON_EVENTS,/MOTION_EVENTS, UVALUE="DRAW_REGION") WIDGET_CONTROL, state.bases[0], MAP=1 ;Tfun is not visible WIDGET_CONTROL, base, /REALIZE WIDGET_CONTROL, state.draw, GET_VALUE=tmp if n_elements(nc) gt 0 then Nframetimes = Nframetimes < nc if Nframetimes le 0 then message,'Number of frame times is 0 or negative' wset, tmp ;Initial graph psave = { XCPE_psave, win: !d.window, x: !x.s, y: !y.s , xtype: !x.type, $ ytype: !y.type, clip: !p.clip } ;Our initial state XCPE_psave ;Save original scaling & window ;plot, [0, Nframetimes-1], [0, Nframetimes-1], xstyle=3, ystyle=3, $ ; xmargin = [1,1], ymargin=[1,1], ticklen = -0.03, /NODATA XCPE_psave ;Restore original scaling & window color = 255L*255L*(var_index+1)*20 cps = d_cps tfun = d_tfun pnt = -1 XCPE_draw_cps, -1 ;Redraw new device, /cursor_original XManager, "xcamerapath", base, NO_BLOCK=(NOT(FLOAT(block))) END