// Copyright (C) 1999-2018 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "frame3dbase.h" #include "fitsimage.h" #include "context.h" #include "marker.h" void Frame3dBase::binToFitCmd() { if (!keyContext->fits) return; Vector3d dim(keyContext->fits->getHistDim(), keyContext->binDepth()); double bf = 1/calcZoom3d(dim, Vector(options->width,options->height)); // round up to next power of 2 if (bf < 1) keyContext->setBinToFactor(Vector(1,1)); else { int p=1; while (psetBinToFactor(Vector(p,p)); } if (keyContext->fits && keyContext->fits->isHist()) { Matrix mm = keyContext->binCursor(); updateBin(mm); } } void Frame3dBase::blockToFitCmd() { if (!keyContext->fits) return; Vector3d ss(keyContext->fits->osize(),keyContext->naxis(2)); double bf = 1/calcZoom3d(ss, Vector(options->width,options->height)); // round down to next power of 2 Vector vv; if (bf < 1) vv = keyContext->setBlockToFactor(Vector(1,1)); else { int p=1; while (psetBlockToFactor(Vector(p,p)); } keyContext->block(); keyContext->analysis(); updateBlock(vv); } void Frame3dBase::crop3dBeginCmd(const Vector& vv, int which) { // which =0 (zmin) which =1 (zmax) if (!keyContext->fits) return; cropBegin = vv * Scale(zoom_).invert(); cropEnd = vv * Scale(zoom_).invert(); // params is a BBOX in DATA coords 0-n FitsZBound* zparams = keyContext->getDataParams(keyContext->secMode()); if (!which) cropsl_ = zparams->zmin; else cropsl_ = zparams->zmax; } void Frame3dBase::crop3dMotionCmd(const Vector& vv, int which) { // which =0 (zmin) which =1 (zmax) if (!keyContext->fits) return; // params is a BBOX in DATA coords 0-n FitsBound* params = keyContext->fits->getDataParams(keyContext->secMode()); FitsZBound* zparams = keyContext->getDataParams(keyContext->secMode()); Vector ss(params->xmin,params->ymin); Vector tt(params->xmax,params->ymax); // erase if (cropBegin[0]!=cropEnd[0] || cropBegin[1]!=cropEnd[1]) { Vector ll = mapFromRef3d(ss,Coord::CANVAS,cropsl_); Vector lr = mapFromRef3d(Vector(tt[0],ss[1]),Coord::CANVAS,cropsl_); Vector ur = mapFromRef3d(tt,Coord::CANVAS,cropsl_); Vector ul = mapFromRef3d(Vector(ss[0],tt[1]),Coord::CANVAS,cropsl_); BBox bb(ll); bb.bound(lr); bb.bound(ur); bb.bound(ul); redrawNow(bb.expand(2)); } cropEnd = vv * Scale(zoom_).invert(); Vector diff = cropEnd-cropBegin; if (!which) cropsl_ = diff[0]+zparams->zmin; else cropsl_ = diff[0]+zparams->zmax; // this will be incorrect for multiple ext/file cubes double depth = keyContext->naxis(2); if (!which) { if (cropsl_<0) cropsl_ = 0; if (cropsl_>zparams->zmax-1) cropsl_ = zparams->zmax-1; } else { if (cropsl_zmin+1) cropsl_ = zparams->zmin+1; if (cropsl_>depth) cropsl_ = depth; } // and draw to window { Vector ll = mapFromRef3d(ss,Coord::WINDOW,cropsl_); Vector lr = mapFromRef3d(Vector(tt[0],ss[1]),Coord::WINDOW,cropsl_); Vector ur = mapFromRef3d(tt,Coord::WINDOW,cropsl_); Vector ul = mapFromRef3d(Vector(ss[0],tt[1]),Coord::WINDOW,cropsl_); XDrawLine(display,Tk_WindowId(tkwin),selectGCXOR,ll[0],ll[1],lr[0],lr[1]); XDrawLine(display,Tk_WindowId(tkwin),selectGCXOR,lr[0],lr[1],ur[0],ur[1]); XDrawLine(display,Tk_WindowId(tkwin),selectGCXOR,ur[0],ur[1],ul[0],ul[1]); XDrawLine(display,Tk_WindowId(tkwin),selectGCXOR,ul[0],ul[1],ll[0],ll[1]); } } void Frame3dBase::crop3dEndCmd(const Vector& vv, int which) { // which =0 (zmin) which =1 (zmax) if (!keyContext->fits) return; // params is a BBOX in DATA coords 0-n FitsBound* params = keyContext->fits->getDataParams(keyContext->secMode()); FitsZBound* zparams = keyContext->getDataParams(keyContext->secMode()); Vector ss(params->xmin,params->ymin); Vector tt(params->xmax,params->ymax); // erase if (cropBegin[0]!=cropEnd[0] || cropBegin[1]!=cropEnd[1]) { Vector ll = mapFromRef3d(ss,Coord::CANVAS,cropsl_); Vector lr = mapFromRef3d(Vector(tt[0],ss[1]),Coord::CANVAS,cropsl_); Vector ur = mapFromRef3d(tt,Coord::CANVAS,cropsl_); Vector ul = mapFromRef3d(Vector(ss[0],tt[1]),Coord::CANVAS,cropsl_); BBox bb(ll); bb.bound(lr); bb.bound(ur); bb.bound(ul); redrawNow(bb.expand(2)); } cropEnd = vv * Scale(zoom_).invert(); Vector diff = cropEnd-cropBegin; if (!which) cropsl_ = diff[0]+zparams->zmin; else cropsl_ = diff[0]+zparams->zmax; // this will be incorrect for multiple ext/file cubes double depth = keyContext->naxis(2); if (!which) { if (cropsl_<0) cropsl_ = 0; if (cropsl_>zparams->zmax-1) cropsl_ = zparams->zmax-1; } else { if (cropsl_zmin+1) cropsl_ = zparams->zmin+1; if (cropsl_>depth) cropsl_ = depth; } if (cropBegin[0]!=cropEnd[0] || cropBegin[1]!=cropEnd[1]) { keyContext->setSecMode(FrScale::CROPSEC); // params is a BBOX in DATA coords 0-n if (!which) keyContext->setCrop3dParams(int(cropsl_+.5),zparams->zmax); else keyContext->setCrop3dParams(zparams->zmin,int(cropsl_+.5)); // set current slice if needed // setSlice() IMAGE (ranges 1-n) // context->slice() IMAGE (ranges 1-n) // cropsl_ ranges coords 0-n double sl = keyContext->slice(2)-.5; if (!which) { if (sl<=cropsl_) setSlice(2,int(cropsl_+1.5)); } else { if (sl>cropsl_) setSlice(2,int(cropsl_)); } } else { keyContext->resetSecMode(); keyContext->setCrop3dParams(); FitsImage* sptr = keyContext->fits; while (sptr) { sptr->setCropParams(keyContext->datasec()); sptr = sptr->nextSlice(); } } keyContext->updateClip(); updateColorScale(); update(MATRIX); updateMarkerCBs(&userMarkers); updateMarkerCBs(&catalogMarkers); } void Frame3dBase::get3dBorderCmd() { if (border_) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Frame3dBase::get3dBorderColorCmd() { Tcl_AppendResult(interp, borderColorName_, NULL); } void Frame3dBase::get3dCompassCmd() { if (compass_) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Frame3dBase::get3dCompassColorCmd() { Tcl_AppendResult(interp, compassColorName_, NULL); } void Frame3dBase::get3dHighliteCmd() { if (highlite_) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Frame3dBase::get3dHighliteColorCmd() { Tcl_AppendResult(interp, highliteColorName_, NULL); } void Frame3dBase::get3dRenderMethodCmd() { ostringstream str; switch (renderMethod_) { case MIP: str << "mip" << ends; break; case AIP: str << "aip" << ends; break; } Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Frame3dBase::get3dScaleCmd() { ostringstream str; str << zscale_ << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Frame3dBase::get3dViewCmd() { ostringstream str; str << m180To180(radToDeg(az_)) << ' ' << m180To180(radToDeg(el_)) << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Frame3dBase::get3dViewPointCmd() { ostringstream str; str << vp_ << ' ' << viewCursor_ << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Frame3dBase::get3dRenderBackgroundCmd() { switch (render_) { case NONE: Tcl_AppendResult(interp, "none", NULL); break; case AZIMUTH: Tcl_AppendResult(interp, "azimuth", NULL); break; case ELEVATION: Tcl_AppendResult(interp, "elevation", NULL); break; } } void Frame3dBase::getCursorCmd(Coord::InternalSystem sys) { Vector aa = Vector(options->width,options->height)/2.; Vector bb = mapToRef(aa,Coord::WIDGET); ostringstream str; str << mapFromRef(bb, sys) << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Frame3dBase::getCursorCmd(Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { if (keyContext->fits) { Vector aa = Vector(options->width,options->height)/2.; Vector bb = mapToRef(aa,Coord::WIDGET); printFromRef(keyContext->fits, bb, sys, sky, format); } } void Frame3dBase::gridCmd(Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, Grid::GridType type, const char* ops, const char* vars) { if (grid) delete grid; switch (type) { case Grid::ANALYSIS: grid = new Grid25d(this, sys, sky, format, type, ops, vars); break; case Grid::PUBLICATION: grid = new Grid3d(this, sys, sky, format, type, ops, vars); break; } update(PIXMAP); } void Frame3dBase::panCmd(const Vector& v1, const Vector& v2) { viewCursor_ -= (v1-v2)*Scale(1/zoom_[0],1/zoom_[1]); update(MATRIX); } void Frame3dBase::panCmd(const Vector& vv) { viewCursor_ -= vv*Scale(1/zoom_[0],1/zoom_[1]); update(MATRIX); } void Frame3dBase::panCmd(const Vector& vv, Coord::CoordSystem sys, Coord::SkyFrame sky) { if (!keyContext->fits) return; Vector cc = Vector(options->width,options->height)/2.; Vector dd = mapToRef(cc,Coord::WIDGET); Vector uu = keyContext->fits->mapFromRef(dd, sys, sky); uu += vv; Vector ee = keyContext->fits->mapToRef(uu, sys, sky); Vector ff = mapFromRef(ee,Coord::WIDGET); viewCursor_ += (cc-ff)*Scale(1/zoom_[0],1/zoom_[1]); update(MATRIX); } void Frame3dBase::panToCmd(const Vector& vv) { Vector dd = Vector(options->width,options->height)/2. - vv*canvasToWidget; viewCursor_ += dd*Scale(1/zoom_[0],1/zoom_[1]); update(MATRIX); } void Frame3dBase::panToCmd(const Vector& vv, Coord::CoordSystem sys, Coord::SkyFrame sky) { if (!keyContext->fits) return; Vector aa = keyContext->fits->mapToRef(vv, sys, sky); Vector dd = Vector(options->width,options->height)/2. - mapFromRef(aa,Coord::WIDGET); viewCursor_ += dd*Scale(1/zoom_[0],1/zoom_[1]); update(MATRIX); } void Frame3dBase::panBBoxCmd(const Vector& vv) { // vv is center of panBBox in panner coordinate Vector aa = vv*pannerToWidget3d; Vector dd = Vector(options->width,options->height)/2. - aa; viewCursor_ += dd*Scale(1/zoom_[0],1/zoom_[1]); update(MATRIX); } void Frame3dBase::panEndCmd(const Vector& vv) { if (panPM) Tk_FreePixmap(display, panPM); panPM = 0; Vector dd = vv*canvasToWidget - panCursor*canvasToWidget; viewCursor_ += dd*Scale(1/zoom_[0],1/zoom_[1]); update(MATRIX); } void Frame3dBase::rotateBeginCmd() { // save the current rotation rotateRotation = rotation; } void Frame3dBase::rotateMotionCmd(double angle) { rotation = rotateRotation + angle; update(MATRIX); } void Frame3dBase::rotateEndCmd() { update(MATRIX); } void Frame3dBase::set3dBorderCmd(int hh) { border_ = hh; update(PIXMAP); } void Frame3dBase::set3dBorderColorCmd(const char* clr) { if (borderColorName_) delete [] borderColorName_; borderColorName_ = dupstr(clr); if (threedGC) XSetForeground(display, threedGC, getColor(borderColorName_)); update(PIXMAP); } void Frame3dBase::set3dCompassCmd(int hh) { compass_ = hh; update(PIXMAP); } void Frame3dBase::set3dCompassColorCmd(const char* clr) { if (compassColorName_) delete [] compassColorName_; compassColorName_ = dupstr(clr); if (threedGC) XSetForeground(display, threedGC, getColor(compassColorName_)); update(PIXMAP); } void Frame3dBase::set3dHighliteCmd(int hh) { highlite_ = hh; update(PIXMAP); } void Frame3dBase::set3dHighliteColorCmd(const char* clr) { if (highliteColorName_) delete [] highliteColorName_; highliteColorName_ = dupstr(clr); if (threedGC) XSetForeground(display, threedGC, getColor(highliteColorName_)); update(PIXMAP); } void Frame3dBase::set3dRenderMethodCmd(int m) { RenderMethod mm = (RenderMethod)m; if (mm!=renderMethod_) { renderMethod_ = mm; update(MATRIX); } } void Frame3dBase::set3dScaleCmd(double ss) { if (zscale_ == ss) return; zscale_ = ss; // just in case if pending az/el preservecache_ =0; update(MATRIX); } void Frame3dBase::set3dViewCmd(float az, float el) { az_ = zeroTWOPI(degToRad(az)); el_ = zeroTWOPI(degToRad(el)); preservecache_ =1; update(MATRIX); } void Frame3dBase::set3dViewPointCmd(const Vector3d& vv, const Vector& cc) { vp_ = vv; viewCursor_ = cc; update(MATRIX); } void Frame3dBase::set3dRenderBackgroundCmd(int which) { if (which != render_) { render_ = (MotionType)which; cancelDetach(); preservecache_ =1; update(BASE); } } void Frame3dBase::set3dPreserveCmd() { preservecache_ =1; } void Frame3dBase::zoomAboutCmd(const Vector& zz, const Vector& vv) { Vector dd = Vector(options->width,options->height)/2. - vv*canvasToWidget; viewCursor_ += dd*Scale(1/zoom_[0],1/zoom_[1]); Vector az = ((Vector&)zz).abs(); zoom_[0] *= az[0]; zoom_[1] *= az[1]; update(MATRIX); } void Frame3dBase::zoomAboutCmd(const Vector& zz, const Vector& vv, Coord::CoordSystem sys, Coord::SkyFrame sky) { if (!keyContext->fits) return; Vector aa = keyContext->fits->mapToRef(vv, sys, sky); Vector dd = Vector(options->width,options->height)/2. - mapFromRef(aa,Coord::WIDGET); viewCursor_ += dd*Scale(1/zoom_[0],1/zoom_[1]); Vector az = ((Vector&)zz).abs(); zoom_[0] *= az[0]; zoom_[1] *= az[1]; update(MATRIX); } void Frame3dBase::zoomToAboutCmd(const Vector& zz, const Vector& vv) { Vector dd = Vector(options->width,options->height)/2. - vv*canvasToWidget; viewCursor_ += dd*Scale(1/zoom_[0],1/zoom_[1]); zoom_ = ((Vector&)zz).abs(); update(MATRIX); } void Frame3dBase::zoomToAboutCmd(const Vector& zz, const Vector& vv, Coord::CoordSystem sys, Coord::SkyFrame sky) { if (!keyContext->fits) return; Vector aa = keyContext->fits->mapToRef(vv, sys, sky); Vector dd = Vector(options->width,options->height)/2. - mapFromRef(aa,Coord::WIDGET); viewCursor_ += dd*Scale(1/zoom_[0],1/zoom_[1]); zoom_ = ((Vector&)zz).abs(); update(MATRIX); } void Frame3dBase::zoomToFitCmd(double ss) { if (!keyContext->fits) return; centerImage(); Vector3d tt = imageSize3d(keyContext->secMode()); double zz = calcZoom3d(tt,Vector(options->width,options->height)) * ss; zoom_ = Vector(zz,zz); update(MATRIX); }