void Plotter2DObj::detach() { if ((pnot)_ownercb == nullptr) return; // do nothing if not inserted _makecallback(_REQUEST_DETACH); MTOOLS_ASSERT(((Drawable2DInterface*)_di) == nullptr); // did we really get our call to _removed() ? MTOOLS_ASSERT(((pnot)_ownercb) == nullptr); // if so, these should already be set to nullptr. _di = nullptr; _ownercb = nullptr; _data = nullptr; _data2 = nullptr; _rm = nullptr; _optionWin = nullptr; _extOptionWin = nullptr; }
/** * Insert a generalized Boltzmann Triangulation (of type II) inside a given face of a map using the * peeling algorithm. * * This method only add new darts/vertices/faces inside the map but does not change the numbering * of the vertices/darts/other faces already present. * * * @param [in,out] CM The map. * @param peeldart a dart that identifies the face inside which the FBT should be constructed. * 0param theta Parameter of the boltzman in (0,1/6] (cf peelinglaw.hpp for details). * @param avoiddoubleedges true to avoid double edges whenever possible. This means that when the peeling * algorithm encounters a face of size two, it collapse the two edges together. * This is useful for creating a type III free Boltzman triangulation BUT even * if avoiddoubleedges = true, the resulting map may still contain double edges! * Use collapseToTypeII() after this method to create a 'real' type III map. * * @param [in,out] gen random number generator. */ template<typename random_t> void generalBoltzmannTriangulation(CombinatorialMap & CM, int peeldart, double theta, bool avoiddoubleedges, random_t & gen) { CM.boltzmannPeelingAlgo(peeldart, [&](int peeledge, int facesize)-> int { MTOOLS_ASSERT((facesize >= 2)); // face must have size at least 2 MTOOLS_ASSERT((facesize >= 3) || (!avoiddoubleedges)); // if we avoid double edges, then all faces must have size >= 3. int m = facesize - 2; int k = (int)generalBoltzmanTriangulationLaw(m, theta, gen); if (k == -1) return -1; // new vertex discovered. if ((m == 0) && (k == 0)) return -2; // stop peeling this face of size 2 MTOOLS_ASSERT((k >= 1) && (k <= m)); for (int i = 0; i < k + 1; i++) { peeledge = CM.phi(peeledge); } return peeledge; }, true); }
void Plotter2DObj::autorangeXY() { if ((pnot)_ownercb == nullptr) return; // do nothing if not inserted if (_suspended) return; // or not enabled MTOOLS_ASSERT(((Drawable2DInterface*)_di) != nullptr); _makecallback(_REQUEST_USERANGEXY); }
/** * Merge two clusters and add the resulting cluster in the set of active clusters **/ inline void merge(cmpit<T> C1, cmpit<T> C2) { MTOOLS_ASSERT(C1 != C2); clusterActiveSet.erase(C1); // remove both clusters from the active set clusterActiveSet.erase(C2); // if (C1->size > C2->size) { C1->last->_cmp_next = C2->first; // chain C2 after C1 C2->first->_cmp_prev = C1->last; // T * p = C2->first; while (p != nullptr) { p->_cmp_cluster = C1; p = p->_cmp_next; } // and update the cluster pointers C1->weight = C1->weight + C2->weight; // update info C1->size = C1->size + C2->size; // C1->last = C2->last; // clusterList.erase(C2); // erase the cluster who disapeared clusterActiveSet.insert(C1); // and put back the new cluster in the active set return; } C2->last->_cmp_next = C1->first; // chain C1 after C2 C1->first->_cmp_prev = C2->last; // T * p = C1->first; while (p != nullptr) { p->_cmp_cluster = C2; p = p->_cmp_next; } // and update the cluster pointers C2->weight = C1->weight + C2->weight; // update info C2->size = C1->size + C2->size; // C2->last = C1->last; // clusterList.erase(C1); // erase the cluster who disapeared clusterActiveSet.insert(C2); // and put back the new cluster in the active set return; }
void CImgWidget::setImage32(cimg_library::CImg<uint32> * im,int nbRounds) { std::lock_guard<std::recursive_mutex> lock(_mutim); if ((nbRounds<=0)||(im == nullptr) || (im->width() == 0) || (im->height() == 0) || (im->spectrum()<3)) { if (_offbuf != ((Fl_Offscreen)0)) { fl_delete_offscreen((Fl_Offscreen)(_offbuf)); } _offbuf = (Fl_Offscreen)0; _ox = 0; _oy = 0; redraw(); return; } if (!_initdraw) // prevent FLTK bug on linux { delete _saved_im; _saved_im = nullptr; delete _saved_im32; _saved_im32 = nullptr; _saved_im32 = new cimg_library::CImg<uint32>(*im, false); _saved_nbRounds = nbRounds; return; } const int nox = im->width(); const int noy = im->height(); if ((nox != _ox) || (noy != _oy)) { if (_offbuf != ((Fl_Offscreen)0)) { fl_delete_offscreen((Fl_Offscreen)(_offbuf)); } _offbuf = fl_create_offscreen(nox, noy); _ox = nox; _oy = noy; MTOOLS_ASSERT(_offbuf != ((Fl_Offscreen)0)); } fl_begin_offscreen((Fl_Offscreen)(_offbuf)); auto data = std::pair<cimg_library::CImg<uint32>*, int>(im, nbRounds); fl_draw_image(_drawLine_callback32, &data, 0, 0, (int)_ox, (int)_oy, 3); fl_end_offscreen(); return; }
int Plotter2DObj::quality() const { if ((pnot)_ownercb == nullptr) return 0; // 0 if not inserted if (!_drawOn) return 100; // and 100 if not enabled. if (_suspended) return 0; // and 0 if enabled but suspended MTOOLS_ASSERT(((Drawable2DInterface*)_di) != nullptr); return(((Drawable2DInterface*)_di)->quality()); }
int Plotter2DObj::drawOnto(Image & im) { if ((pnot)_ownercb == nullptr) return 0; // do nothing if not inserted MTOOLS_ASSERT(((Drawable2DInterface*)_di) != nullptr); if (!_drawOn) return 100; // 100 if disabled if (_suspended) return 0; // 0 if suspended return ((Drawable2DInterface*)_di)->drawOnto(im,_opacity); // reset the drawing }
void Plotter2DObj::resetDrawing(bool refresh) { if ((pnot)_ownercb == nullptr) return; // do nothing if not inserted if (_suspended) return; // or suspended MTOOLS_ASSERT(((Drawable2DInterface*)_di) != nullptr); ((Drawable2DInterface*)_di)->resetDrawing(); // reset the drawing if (refresh) _makecallback(_REQUEST_REFRESH); }
/* called by the owner when detached */ void Plotter2DObj::_removed() { MTOOLS_ASSERT(isFltkThread()); // we should be in the fltk thread MTOOLS_ASSERT(((pnot)_ownercb) != nullptr); // check that we are indeed inserted. MTOOLS_ASSERT(((Fl_Group *)_extOptionWin) != nullptr); // cannnot be null Fl::remove_timeout(_timerCB_static, this); // remove the timer for the progress bar if there is one. ((Drawable2DInterface*)_di)->enableThreads(false); _di = nullptr; _insertOptionWin(false); // make the optionWin group stand alone. removed(_optionWin); // call the virtual function that takes care of deleting _optionWin _optionWin = nullptr; // mark as deleted Fl::delete_widget(_extOptionWin); // send widget deletion request _extOptionWin = nullptr; // mark as deleted. _rm = nullptr; // remove obsolete info about the previous owner. _data = nullptr; // _data2 = nullptr; // _ownercb = nullptr; // officially not inserted anymore }
void Plotter2DObj::setParam(mtools::fBox2 range, mtools::iVec2 imageSize) { if ((pnot)_ownercb == nullptr) return; // do nothing if not inserted MTOOLS_ASSERT(((Drawable2DInterface*)_di) != nullptr); _crange = range; // save the range; _cwinSize = imageSize; // save the image size if (_suspended) { _missedSetParam = true; return; } // disabled so we do not call the underlying object but we remember to update the range when enabled. _missedSetParam = false; ((Drawable2DInterface*)_di)->setParam(range,imageSize); // set the parameters }
/** * Compute the factorial for n in [0,170] * Taken from numerical recipes, (well, this one I could have written myself :-)) **/ inline double factrl(int64 n) { static double a[171]; static bool init = true; if (init) { init = false; a[0] = 1.; for (int i = 1; i < 171; i++) a[i] = i*a[i - 1]; } MTOOLS_ASSERT((n >= 0 || n <= 170)); return a[n]; }
/** * Compute the logarithm of the gamma function. * Taken from numerical recipes. **/ inline double gammln(const double xx) { int j; double x, tmp, y, ser; static const double cof[14] = { 57.1562356658629235,-59.5979603554754912,14.1360979747417471,-0.491913816097620199,.339946499848118887e-4,.465236289270485756e-4,-.983744753048795646e-4,.158088703224912494e-3,-.210264441724104883e-3,.217439618115212643e-3,-.164318106536763890e-3,.844182239838527433e-4,-.261908384015814087e-4,.368991826595316234e-5 }; MTOOLS_ASSERT(xx > 0); y = x = xx; tmp = x + 5.24218750000000000; tmp = (x + 0.5)*log(tmp) - tmp; ser = 0.999999999999997092; for (j = 0; j < 14; j++) ser += cof[j] / ++y; return tmp + log(2.5066282746310005*ser / x); }
/** * Compute the logarithm of a factorial. * Taken from numerical recipes. **/ inline double factln(int64 n) { static const int64 NTOP = 2000; static double a[NTOP]; static bool init = true; if (init) { init = false; for (int64 i = 0; i < NTOP; i++) a[i] = gammln(i + 1.); } MTOOLS_ASSERT(n >= 0); if (n < NTOP) return a[n]; return gammln(n + 1.); }
void Plotter2DObj::enable(bool status) { if (!isFltkThread()) // run the method in FLTK if not in it { IndirectMemberProc<Plotter2DObj, bool> proxy(*this, &Plotter2DObj::enable, status); // registers the call runInFltkThread(proxy); return; } _drawOn = status; _suspended = (_drawOn) ? false : true; // override the suspended flag if ((pnot)_ownercb == nullptr) return; // return if not inserted MTOOLS_ASSERT(((Drawable2DInterface*)_di) != nullptr); _onOffButton->value(_drawOn); if (_drawOn) { if (_missedSetParam) { ((Drawable2DInterface*)_di)->setParam(_crange, _cwinSize); _missedSetParam = false; } _nameBox->activate(); if (!hasFavouriteRangeX()) { _useRangeX->deactivate(); } else { _useRangeX->activate(); } if (!hasFavouriteRangeY()) { _useRangeY->deactivate(); } else { _useRangeY->activate(); } if (!((hasFavouriteRangeX())&&(hasFavouriteRangeY()))) { _useRangeXY->deactivate(); } else { _useRangeXY->activate(); } _opacitySlider->activate(); if (_progBar != nullptr) _progBar->activate(); if (_nbthl != nullptr) _nbthl->activate(); if (_optionWin != nullptr) _optionWin->activate(); } else { _nameBox->deactivate(); _useRangeX->deactivate(); _useRangeY->deactivate(); _useRangeXY->deactivate(); _opacitySlider->deactivate(); if (_progBar != nullptr) _progBar->deactivate(); if (_nbthl != nullptr) _nbthl->deactivate(); if (_optionWin != nullptr) _optionWin->deactivate(); } ((Drawable2DInterface*)_di)->enableThreads(_drawOn); refresh(); yieldFocus(); }
void Plotter2DObj::_timerCB() { MTOOLS_ASSERT(((Drawable2DInterface*)_di) != nullptr); // check that the auto drawer still exist bool thron = ((Drawable2DInterface*)_di)->enableThreads(); // thread status int nn = ((Drawable2DInterface*)_di)->nbThreads(); if (nn != _nbth) { // update the number of thread is different from the last query _nbth = nn; _nbthl->copy_label(mtools::toString(nn).c_str()); } if (thron == 0) // thread is off { if (_progVal != -1) { _progVal = -1; _progBar->selection_color(FL_DARK_RED); _progBar->labelsize(11); _progBar->value(100); _progBar->copy_label("stopped"); _progBar->redraw(); } } else { int q = ((Drawable2DInterface*)_di)->quality(); if (_progVal != q) { _progVal = q; _progBar->selection_color((q<100) ? FL_DARK_BLUE : FL_DARK_GREEN); _progBar->labelsize(11); _progBar->value((float)q); auto progText = mtools::toString(q) + "%"; _progBar->copy_label(progText.c_str()); _progBar->redraw(); } } Fl::repeat_timeout(0.1, _timerCB_static, this); // repeat the timer }
void Plotter2DObj::suspend(bool status) { if (!isFltkThread()) // run the method in FLTK if not in it { IndirectMemberProc<Plotter2DObj,bool> proxy(*this, &Plotter2DObj::suspend,status); // registers the call runInFltkThread(proxy); return; } if ((_drawOn == false)||(_suspended == status)) return; // nothing to do _suspended = status; if ((pnot)_ownercb == nullptr) return; // return if not inserted MTOOLS_ASSERT(((Drawable2DInterface*)_di) != nullptr); ((Drawable2DInterface*)_di)->enableThreads(!status); if (!status) { // we resume activites if (_missedSetParam) { ((Drawable2DInterface*)_di)->setParam(_crange, _cwinSize); _missedSetParam = false; } refresh(); yieldFocus(); } }
/* callback for the "white" check button */ static void _checkWhiteCB_static(Fl_Widget * W, void * data) { MTOOLS_ASSERT(data != nullptr); ((Plot2DLattice*)data)->_checkWhiteCB(W); }
/* callback for the opacify slider */ static void _opacifySliderCB_static(Fl_Widget * W, void * data) { MTOOLS_ASSERT(data != nullptr); ((Plot2DLattice*)data)->_opacifySliderCB(W); }
/* callback for the round buttons */ static void _roundButtonCB_static(Fl_Widget * W, void * data) { MTOOLS_ASSERT(data != nullptr); ((Plot2DLattice*)data)->_roundButtonCB(W); }
/** * Return invperm[index]. **/ int inv(size_t index) const { MTOOLS_ASSERT((index >= 0) && (index < _perm.size())); return _invperm[index]; }
/** * Return perm[index]. **/ int operator[](size_t index) const { MTOOLS_ASSERT((index >= 0) && (index < _perm.size())); return _perm[index]; }
void Plot2DAxes::_scaleSliderCB_static(Fl_Widget * W, void * data) { MTOOLS_ASSERT(data != nullptr); ((Plot2DAxes*)data)->_scaleSliderCB(W); }
/* timer callback update the progress for for the quality */ void Plotter2DObj::_timerCB_static(void * data) { MTOOLS_ASSERT(data != nullptr); ((Plotter2DObj*)data)->_timerCB(); }
/** * Compute the binomial coefficient (n,k) * Taken from numerical recipes. **/ inline double bico(const int64 n, const int64 k) { MTOOLS_ASSERT((n >= 0) || (k >= 0) || (k <= n)); if (n < 171) return floor(0.5 + factrl(n) / (factrl(k)*factrl(n - k))); return floor(0.5 + exp(factln(n) - factln(k) - factln(n - k))); }
void Plotter2DObj::_opacitySliderCB_static(Fl_Widget * W, void * data) { MTOOLS_ASSERT(data != nullptr); ((Plotter2DObj*)data)->_opacitySliderCB(W); }
void Plotter2DObj::_nameColorCB_static(Fl_Widget * W, void * data) { MTOOLS_ASSERT(data != nullptr); ((Plotter2DObj*)data)->_nameColorCB(W); }
/** * Delete the T object and set the adress to nullptr. **/ virtual void destroy() { MTOOLS_ASSERT((T*)_adr != nullptr); delete((T*)_adr); _adr = (T*)nullptr; }
void Plot2DAxes::_numColorButtonCB_static(Fl_Widget * W, void * data) { MTOOLS_ASSERT(data != nullptr); ((Plot2DAxes*)data)->_numColorButtonCB(W); }
/** * Construct the object. the adress of the object may be queried via adress(). * Should be called only once ! **/ virtual void construct() { MTOOLS_ASSERT((T*)_res == nullptr); _res = _call(typename internals_indirectcall::gens<sizeof...(Params)>::type()); }
void Plotter2DObj::_unrollButtonCB_static(Fl_Widget * W, void * data) { MTOOLS_ASSERT(data != nullptr); ((Plotter2DObj*)data)->_unrollButtonCB(W); }