~BackgroundParserPrivate()
    {
        suspend();

        m_weaver.dequeue();
        m_weaver.requestAbort();
        m_weaver.finish();

        // Release dequeued jobs
        QHashIterator<KUrl, ParseJob*> it = m_parseJobs;
        while (it.hasNext()) {
            it.next();
            it.value()->setBackgroundParser(0);
            delete it.value();
        }

        qDeleteAll(m_delayedParseJobs);
    }
Exemplo n.º 2
0
QList<IQORMModel* > IQORMCore::allModels()
{
    QList<IQORMModel* > result;
    QHashIterator<QString, QPointer<IQORMModel> > i (IQORMCore::_models);
    while (i.hasNext())
    {
        i.next();
        result << i.value();
    }

    return result;
}
Exemplo n.º 3
0
QString Level::xml () {
  QString rv;
  rv.append(QString("<Level name=\"%1\">").arg(levelName()));
  QHashIterator<int, LevelObject*> o (this->levelObjects);
  o.toFront ();
  while (o.hasNext ()) {
      o.next ();
      LevelObject* obj = o.value ();
      int id = o.key ();
      rv.append(obj->xml (id));
    }
  rv.append("</Level>");
  return rv;

}
Exemplo n.º 4
0
//=========================================
// timerDone
//-----------------------------------------
void Notify::timerDone (void) {
	// .../
	// every time the timer expires this method is called.
	// the function will send a signal including the file
	// descriptor of the touched file and the flag whether this
	// file was created or deleted
	// ----
	QHashIterator<int, int> it (mNotifyQueue);
	while (it.hasNext()) {
		it.next();
		int fd   = it.key();
		int flag = it.value();
		sendSignal (fd,flag);
	}
	mNotifyQueue.clear();
}
Exemplo n.º 5
0
// Clear all time statistics
void Mainwindow::menuClearStatistics()
{
    QString message;
    message = i18n("Do you really want to clear the all time "
                    "statistical data?");

    if (KMessageBox::Yes == KMessageBox::questionYesNo(this,
                                                       message,
                                                       QString(),
                                                       KStandardGuiItem::clear()))
    {
        QHashIterator<int,Player *> it = mLSkatConfig->playerIterator();
        while (it.hasNext())
        {
            it.next();
            Player *player = it.value();
            player->clear();
        }
    }
}
Exemplo n.º 6
0
QtPropertyData::~QtPropertyData() 
{
	QHashIterator<QString, QtPropertyData*> i = QHashIterator<QString, QtPropertyData*>(children);
	while(i.hasNext())
	{
		i.next();

		QtPropertyData *data = i.value();
		if(NULL != data)
		{
			delete data;
		}
	}

	for (int i = 0; i < optionalWidgets.size(); i++)
	{
		if(NULL != optionalWidgets.at(i).widget)
		{
			delete optionalWidgets.at(i).widget;
		}
	}
}
Exemplo n.º 7
0
// Start a new game
void Mainwindow::startGame()
{
    // Enable game action
    QLatin1String endName(KStandardGameAction::name(KStandardGameAction::End));
    ACTION(endName)->setEnabled(true);

    // Deal cards to player - Shuffle card deck and reset pile
    mDeck->shuffle();

    // Draw Trump
    Suite trump = mDeck->randomTrump();

    // Loop all players in the game
    QHashIterator<int,Player *> it = mLSkatConfig->playerIterator();
    while (it.hasNext())
    {
        it.next();
        Player *player = it.value();
        player->setDeck(mDeck);
        // Deal cards
        player->deal(16);
        // Store trump
        player->setTrump(trump);
    }

    // Start display
    mDisplay->start();

    // Start the game engine
    mEngine->startGame(trump, mStartPlayer);

    // Start player for next game
    setStartPlayer(1-mStartPlayer);

    //  statusBar()->clearMessage();
}
Exemplo n.º 8
0
QWidget* XletQueuesConfigure::buildConfigureQueueList(QWidget *parent)
{
    QWidget *root = new QWidget(parent);
    QGridLayout *layout = new QGridLayout(root);
    root->setLayout(layout);

    layout->addWidget(new QLabel(tr("Queue"), root), 0, 0, Qt::AlignLeft);
    QLabel *label_qos = new QLabel(tr("Qos - X (s)"), root);
    label_qos->setToolTip(tr(
        "This is the threshold in seconds to consider that the answer to a "
        "call was too late to be accounted as an answer of quality."));
    layout->addWidget(label_qos, 0, 1, Qt::AlignLeft);
    QLabel *label_window = new QLabel(tr("Window (s)"), root);
    label_window->setToolTip(tr(
        "The window is the period of time used to compute the statistics"));
    layout->addWidget(label_window, 0, 2, Qt::AlignLeft);

    QCheckBox *displayQueue;
    QSpinBox *spinBox;
    int row;
    int column;
    QVariantMap statConfig = b_engine->getConfig("guioptions.queuespanel").toMap();
    QString xqueueid;

    row = 1;

    QHashIterator<QString, XInfo *> i = \
        QHashIterator<QString, XInfo *>(b_engine->iterover("queues"));

    while (i.hasNext()) {
        column = 0;
        i.next();
        QueueInfo * queueinfo = (QueueInfo *) i.value();
        xqueueid = queueinfo->xid();

        displayQueue = new QCheckBox(queueinfo->queueName(), root);
        displayQueue->setProperty("xqueueid", xqueueid);
        displayQueue->setProperty("param", "visible");
        displayQueue->setChecked(statConfig.value("visible" + xqueueid, true).toBool());
        layout->addWidget(displayQueue, row, column++);
        connect(displayQueue, SIGNAL(stateChanged(int)),
                this, SLOT(changeQueueStatParam(int)));

        spinBox = new QSpinBox(root);
        spinBox->setAlignment(Qt::AlignCenter);
        spinBox->setMaximum(240);
        spinBox->setProperty("xqueueid", xqueueid);
        spinBox->setProperty("param", "xqos");
        spinBox->setValue(statConfig.value("xqos" + xqueueid, 60).toInt());
        layout->addWidget(spinBox, row, column++);
        connect(spinBox, SIGNAL(valueChanged(int)),
                this, SLOT(changeQueueStatParam(int)));

        spinBox = new QSpinBox(root);
        spinBox->setAlignment(Qt::AlignCenter);
        spinBox->setMaximum(3600*3);
        spinBox->setProperty("xqueueid", xqueueid);
        spinBox->setProperty("param", "window");
        spinBox->setValue(statConfig.value("window" + xqueueid, 3600).toInt());
        layout->addWidget(spinBox, row, column++);
        connect(spinBox, SIGNAL(valueChanged(int)),
                this, SLOT(changeQueueStatParam(int)));

        row++;
    }

    return root;
}
Exemplo n.º 9
0
/**
 * @brief StatUtil::_calSumValue
 *  计算将各个科目下的各个币种合计后的余额及其方向
 * @param isPre true:期初,false:期末
 * @param isfst true:一级科目,false:二级科目
 */
void StatUtil::_calSumValue(bool isPre, bool isfst)
{
    QHash<int,Double> *vs,*vms,*sumvs; //未合计前的值表(其中:vs为原币值表,vms为本币值表),合计后的值表
    QHash<int,MoneyDirection> *ds,*sumds; //未合计前的方向表,合计后的方向表
    if(isPre){
        if(isfst){
            vs = &preFExa;
            vms= &preFExaM;
            ds = &preFDir;
            sumvs = &sumPreFV;
            sumds = &sumPreFD;
        }
        else{
            vs = &preSExa;
            vms= &preSExaM;
            ds = &preSDir;
            sumvs = &sumPreSV;
            sumds = &sumPreSD;
        }
    }
    else{
        if(isfst){
            vs = &endFExa;
            vms= &endFExaM;
            ds = &endFDir;
            sumvs = &sumEndFV;
            sumds = &sumEndFD;
        }
        else{
            vs = &endSExa;
            vms= &endSExaM;
            ds = &endSDir;
            sumvs = &sumEndSV;
            sumds = &sumEndSD;
        }
    }

    //基本思路是借方 - 贷方,并根据差值的符号来判断余额方向
    QHashIterator<int,Double>* it = new QHashIterator<int,Double>(*vs);
    int mt,sid;
    int mmt = masterMt->code();
    Double v;
    while(it->hasNext()){
        it->next();        
        sid = it->key()/10;
        if(sid == 0)
            continue;
        mt = it->key()%10;
        if(mt == mmt)
            v = it->value();
        else
            v = vms->value(it->key());
        if(ds->value(it->key()) == MDIR_P){
            if(sumvs->contains(sid))
                continue;
            else
                (*sumvs)[sid] = 0;
        }
        else if(ds->value(it->key()) == MDIR_J)
            (*sumvs)[sid] += v;
        else
            (*sumvs)[sid] -= v;
    }

    bool isIn ;  //是否是损益类凭证的收入类科目
    bool isFei;  //是否是损益类凭证的费用类科目
    FirstSubject* fsub; SecondSubject* ssub;
    it = new QHashIterator<int,Double>(*sumvs);
    while(it->hasNext()){
        it->next();
        sid = it->key();
        if(isfst){
            fsub = smg->getFstSubject(sid);
            if(!fsub)
                LOG_ERROR(QString("Null point exception! When request FirstSubject object point from sid=%1").arg(sid));
            ssub = NULL;
        }
        else{
            ssub = smg->getSndSubject(sid);
            if(!ssub)
                LOG_ERROR(QString("Null point exception! When request SecondSubject object point from sid=%1").arg(sid));
            fsub = ssub->getParent();
        }
        if(it->value() == 0)
            (*sumds)[sid] = MDIR_P;
        else if(it->value() > 0){
            isIn = (smg->isSySubject(fsub->getId()) && !fsub->getJdDir());
            //如果是收入类科目,要将它固定为贷方
            if(isIn){
                (*sumvs)[sid].changeSign();
                (*sumds)[sid] = MDIR_D;
            }
            else{
                (*sumds)[sid] = MDIR_J;
            }
        }
        else{
            isFei = (smg->isSySubject(fsub->getId()) && fsub->getJdDir());
            //如果是费用类科目,要将它固定为借方
            if(isFei){
                (*sumds)[sid] = MDIR_J;
                //为什么不需要更改金额符号,是因为对于一般的科目是根据符号来判断科目的余额方向
                //但对费用类科目,我们认为即使是负数也将其定为借方(因为运算法则是借方-贷方,方向仍为借方)
                //sumsR[id].changeSign();
            }
            else{
                (*sumvs)[sid].changeSign();
                (*sumds)[sid] = MDIR_D;
            }
        }
    }
}
Exemplo n.º 10
0
/**
 * @brief StatUtil::_calEndExtra
 * @param isFst true:统计的是一级科目,false:二级科目
 */
void StatUtil::_calEndExtra(bool isFst)
{
    //期末余额的计算及其方向的确定:
    //要遵循的基本原则:
    //(1)同向计算,即只有在方向相同的情况下,才进行金额的加减计算,否则在计算前要进行调整
    //(2)始终用“借方-贷方”后所得差额值的符号,来确定方向
    //(3)只有当涉及到外币项目时,才进行本币值的计算

    //变量命名约定(p:期初,v:金额,j:借方,d:贷方或方向,c:本期发生,e:期末,M:本币值)
    QHash<int,Double> *pvs,*pvMs,*cjvs,*cjMvs,*cdvs,*cdMvs,*evs,*evMs;
    QHash<int, MoneyDirection> *pds,*eds;
    if(isFst){
        pvs = &preFExa;
        pvMs = &preFExaM;
        pds = &preFDir;
        cjvs = &curJF;
        cjMvs = &curJFM;
        cdvs = &curDF;
        cdMvs = &curDFM;
        evs = &endFExa;
        evMs = &endFExaM;
        eds = &endFDir;
    }
    else{
        pvs = &preSExa;
        pvMs = &preSExaM;
        pds = &preSDir;
        cjvs = &curJS;
        cjMvs = &curJSM;
        cdvs = &curDS;
        cdMvs = &curDSM;
        evs = &endSExa;
        evMs = &endSExaM;
        eds = &endSDir;
    }

//    evs->clear(); eds->clear(); evMs->clear();

    Double vp,vm;   //原币金额、本币金额
    MoneyDirection dir;
    int sid,key,mt;
    int mmt = masterMt->code();
    QHashIterator<int,Double> it(*cjvs);
    while(it.hasNext()){
        it.next();
        key = it.key();
        sid = key/10;
        mt = key%10;
        vp = cjvs->value(key) - cdvs->value(key);
        if(mt != mmt)
            vm = cjMvs->value(key) - cdMvs->value(key);
        if(vp > 0)
            dir = MDIR_J;
        else if(vp < 0){
            dir = MDIR_D;
            vp.changeSign();
            vm.changeSign();
        }
        else if(vp==0 && vm!=0){    //这发生在结转汇兑损益的情况,原币不变本币变
            if(vm > 0)
                dir = MDIR_J;
            else{
                dir = MDIR_D;
                vm.changeSign();
            }
        }
        else
            dir = MDIR_P;
        if(dir == MDIR_P){ //本期借贷相抵(平),则余额值和方向同期初
            (*evs)[key] = pvs->value(key);
            (*eds)[key] = pds->value(key);
            if(mt != mmt){
                (*evMs)[key] = pvMs->value(key)+vm;
                //if(isFst)
                //    evRs[key] = pvRs.value(key);
                //else
                //    endSExaR = preSExaR;
            }
        }
        else if(pds->value(key) == dir){ //本期发生额借贷方向与期初相同,则直接加到同一方向
            (*evs)[key] = pvs->value(key) + vp;
            (*eds)[key] = pds->value(key);
            if(mt != mmt){
                (*evMs)[key] = pvMs->value(key) + vm;
                //if(isFst)
                //    endFExaR = preFExaR + vm;
                //else
                //    endSExaR = preSExaR + vm;
            }
        }
        else{
            Double tvp,tvm;
            bool isInSub;
            //始终用借方去减贷方,如果值为正,则余额在借方,值为负,则余额在贷方
            if(dir == MDIR_J){
                tvp = vp - pvs->value(key); //借方(当前发生借贷相抵后) - 贷方(期初余额)
                if(mt != mmt){
                    tvm = vm - pvMs->value(key);
                    //if(isFst)
                    //    tvm = vm - preFExaR;
                    //else
                    //    tvm = vm -preSExaR;
                }

            }
            else{
                tvp = pvs->value(key) - vp; //借方(期初余额) - 贷方(当前发生借贷相抵后)
                if(mt != mmt){
                    tvm = pvMs->value(key) - vm;
                    //if(isFst)
                    //    tvm = preFExaR - vm;
                    //else
                    //    tvm = preSExaR - vm;
                }
            }
            if(tvp > 0){ //余额在借方
                //如果是收入类科目,要将它固定为贷方
                if(smg->isSyClsSubject(sid,isInSub,isFst) && isInSub){
                    tvp.changeSign();
                    (*evs)[key] = tvp;
                    (*eds)[key] = MDIR_D;
                }
                else{
                    (*evs)[key] = tvp;
                    (*eds)[key] = MDIR_J;
                    if(mt != mmt){
                        (*evMs)[key] = tvm;
                        //if(isFst)
                        //    endFExaR[key] = tvm;
                        //else
                        //    endSExaR[key] = tvm;
                    }
                }
            }
            else if(tvp < 0){ //余额在贷方
                //如果是费用类科目,要将它固定为借方
                if(smg->isSyClsSubject(sid,isInSub,isFst) && !isInSub){
                    (*evs)[key] = tvp;
                    (*eds)[key] = MDIR_J;
                }
                else{
                    tvp.changeSign();
                    tvm.changeSign();
                    (*evs)[key] = tvp;
                    (*eds)[key] = MDIR_D;
                    if(mt != mmt){
                        (*evMs)[key] = tvm;
                        //if(isFst)
                        //    endFExaR[key] = tvm;
                        //else
                        //    endSExaR[key] = tvm;
                    }
                }
            }
            else{
                (*evs)[key] = 0;
                (*eds)[key] = MDIR_P;
                if(mt != mmt){
                    (*evMs)[key] = tvm;
                    //if(isFst)
                    //    endFExaR[key] = tvm;    //因为原币余额为0,并不意味着本币余额也为0
                    //else
                    //    endSExaR[key] = tvm;
                }
            }
        }
    }

    //if(!isFst)
    //    qDebug()<<QString("StatUtil::_calEndExtra===> %1").arg(evMs->value(1122).toString());

    //将存在期初值但本期未发生的科目余额拷贝到期末余额
    QHashIterator<int,Double>* ip = new QHashIterator<int,Double>(*pvs);
    while(ip->hasNext()){
        ip->next();
        int key = ip->key();
        int mt = key%10;
        if(!evs->contains(key)){
            (*evs)[key] = pvs->value(key);
            (*eds)[key] = pds->value(key);
            if(mt != mmt)
                (*evMs)[key] = pvMs->value(key);
        }
    }
    //查找并剔除那些外币的原币余额为0,但其本币值不为0的值项
    ip = new QHashIterator<int,Double>(*evMs);
    Double v;
    while(ip->hasNext()){
        ip->next();
        v = ip->value();
        if(v != 0 && evs->value(ip->key()) == 0){
            //(*evMs)[ip->key()] = 0;  //2015-7-15,以前为何要将其清零?,发现可以保存此值,但期初读取时没有读取到
            QString subName;
            int sid = ip->key()/10;

            if(isFst)
                subName = smg->getFstSubject(sid)->getName();
            else{
                SecondSubject* ssub = smg->getSndSubject(sid);
                subName = QString("%1-%2").arg(ssub->getParent()->getName()).arg(ssub->getName());
            }
            if(!isFst){
                Money* mt = account->getAllMoneys().value(ip->key()%10);
                QString info = tr("科目“%1”的%2的原币余额为0,但本币余额是:%3,需要在结转汇兑损益凭证中将其清零!")
                        .arg(subName).arg(mt->name()).arg(v.toString2());
                QMessageBox::warning(0,tr("余额误差"),info);
                LOG_WARNING(tr("%1(sid=%2) 外币余额本币值误差:%3").arg(subName).arg(sid).arg(v.toString2()));
            }
        }
    }
}
Exemplo n.º 11
0
const QList<PlastiQCandidateMethod> PlastiQMetaObject::candidates(const QByteArray &name, int argc, PlastiQMethod::Type type, PlastiQMethod::Access filter, bool ignoreCase) const
{
#ifdef PQDEBUG
    PQDBG_LVL_START(__FUNCTION__);
    PQDBGLPUP(QString("PlastiQMetaObject::d.className = %1").arg(d.className));
    PQDBGLPUP(QString("find candidates for `%1`").arg(name.constData()));
#endif

    QList<PlastiQCandidateMethod> candidateList;

    const PlastiQMetaObject *m = this;
    int offset = 0;
    bool maxArgs = argc == -1;
    QByteArray lowerName = name.toLower();

    do {
        QHashIterator<QByteArray, PlastiQMethod> *i;
        const QHash<QByteArray, PlastiQMethod> *hash;

        switch(type) {
        case PlastiQMethod::Method:
            i = new QHashIterator<QByteArray, PlastiQMethod>(*(m->d.pq_methods));
            hash = m->d.pq_methods;
            break;

        case PlastiQMethod::Constructor:
            i = new QHashIterator<QByteArray, PlastiQMethod>(*(m->d.pq_constructors));
            hash = m->d.pq_constructors;
            break;

        case PlastiQMethod::Signal:
            i = new QHashIterator<QByteArray, PlastiQMethod>(*(m->d.pq_signals));
            hash = m->d.pq_signals;
            break;

        default:
            PQDBG_LVL_DONE();
            return candidateList;
        }

        while(i->hasNext()) {
            i->next();


            if(ignoreCase) {
                if(i->value().name.toLower() != lowerName) continue;
            }
            else {
                if(i->value().name != name) continue;
            }

            int idx = i->key().indexOf("(");
            QString methodSignature = i->key().mid(idx + 1, i->key().size() - idx - 2);

            QStringList argTypes = methodSignature.split(",");
            int candidateArgc = methodSignature.length() ? argTypes.size() : 0;

            if(type == PlastiQMethod::Signal && maxArgs) {
                if(argc < candidateArgc) {
                    argc = candidateArgc;
                    candidateList.clear();
                    candidateList.append({ i->value().name, argc, argTypes, i->value().index + offset });
                    continue;
                }
            }
            else {
                if(!maxArgs && candidateArgc != argc) {
                    continue;
                }
            }

            if(filter == PlastiQMethod::None || filter == i->value().access) {
                if(maxArgs) {
                    if(argc < candidateArgc) {
                        PQDBGLPUP(QString("reappend candidate: %1(%2)").arg(name.constData()).arg(methodSignature));
                        argc = candidateArgc;
                        candidateList.clear();
                        candidateList.append({ i->value().name, argc, argTypes, i->value().index + offset });
                        continue;
                    }
                }
                else {
                    PQDBGLPUP(QString("append candidate: %1(%2)").arg(name.constData()).arg(methodSignature));
                    candidateList.append({ i->value().name, argc, argTypes, i->value().index + offset });
                }
            }
        }

        if(type == PlastiQMethod::Constructor) {
            delete i;
            break;
        }
        else {
            offset += hash->size();
            delete i;
        }
    } while(m = m->d.superdata);

    PQDBG_LVL_DONE();
    return candidateList;
}
Exemplo n.º 12
0
void PerspectiveView::glPass(GLResourceContext &ctx)
{
    glEnable(GL_DEPTH_TEST);

    QMatrix4x4 cameraProjM = _camera->getProjMatrix(width(), height());
    QMatrix4x4 cameraViewM = _camera->getViewMatrix(width(), height());
    QMatrix4x4 cameraProjViewM = cameraProjM * cameraViewM;
    QMatrix4x4 objToWorld;

    Scene* scene = Scene::activeScene();

    // render each mesh
    QHashIterator<QString,Mesh*> meshes = scene->meshes();
    while (meshes.hasNext()) {
        meshes.next();
        Mesh* mesh = meshes.value();

        // make sure a texture exists for this mesh
        if (!hasMeshTexture(mesh)) {
            std::cout << "creating mesh texture" << std::endl;

            QOpenGLFramebufferObject* transferFbo = ctx.transferFbo();

            transferFbo->bind();

            GLuint textureId;
            glGenTextures(1, &textureId);

            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, textureId);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);

            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

            glClearColor(.5,.5,.5,1);
            glClear(GL_COLOR_BUFFER_BIT);

            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            glOrtho(0,1,0,1,-1,1);
            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();

            glViewport(0, 0, 256, 256);

            glColor3f(.8,.8,.8);
            glBegin(GL_QUADS);
            {
                glVertex2f(.25,.25);
                glVertex2f(.75,.25);
                glVertex2f(.75,.75);
                glVertex2f(.25,.75);
            }
            glEnd();

            glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 256, 256, 0);


            transferFbo->release();

            //glActiveTexture(GL_TEXTURE0);
            //QImage img("/tmp/lena.jpg");
            //QImage image = QGLWidget::convertToGLFormat(img);
            //glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0 , image.width(), image.height(),  GL_RGB, GL_UNSIGNED_BYTE, image.bits() );


            glViewport(0, 0, width(), height());

            setMeshTexture(mesh, textureId);
        }

        QOpenGLFramebufferObject* paintFbo = ctx.paintFbo();

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, meshTexture(mesh));
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, paintFbo->texture());
        glActiveTexture(GL_TEXTURE0);

        QGLShaderProgram* meshShader = ctx.meshShader();
        meshShader->bind();
        meshShader->setUniformValue("objToWorld", objToWorld);
        meshShader->setUniformValue("cameraPV", cameraProjViewM);
        meshShader->setUniformValue("paintFboWidth", PAINT_FBO_WIDTH);
        meshShader->setUniformValue("brushColor", _brushColor.redF(), _brushColor.greenF(), _brushColor.blueF(), 1);
        meshShader->setUniformValue("meshTexture", 0);
        meshShader->setUniformValue("paintTexture", 1);

        renderMesh(mesh);

        meshShader->release();


    }

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glLoadMatrixf(cameraProjM.data());
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glLoadMatrixf(cameraViewM.data());

    glBegin(GL_LINES);
    for (int i = -10; i <= 10; i++) {
        glVertex3f(-10, 0, i);
        glVertex3f(10, 0, i);
    }
    glEnd();

    glDisable(GL_DEPTH_TEST);

    drawPaintStrokes(ctx);

    if (_bakePaintLayer) {
        bakePaintLayer(ctx);
    }
}