void MolecularEditorApp::draw(){
    glClearColor( 0.5f, 0.5f, 0.5f, 0.0f );
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	//glDisable( GL_DEPTH_TEST );

    //converged = true;
    //delay = 100; world.optimizer->dt_max = 0.00001; world.optimizer->dt_max = 0.00001; perFrame=1;
    //delay = 1000; perFrame=1;
    //perFrame=1;  // world.optimizer->dt_max = 0.01;
    //world.optimizer->dt_max = 0.01;
    //world.nonCovalent  = false;
	if( !converged ){
        long tick1 = getCPUticks();
        int iter;
        for(iter=0; iter<perFrame; iter++){
            world.rigidOptStep( );
            printf(" opt step %i fmax %g \n", world.optimizer->stepsDone, world.fmax );
            if( world.fmax < fmaxConverg ){
                converged = true;
                printf(" converged after %i step \n", world.optimizer->stepsDone );
                if(fout_xyz){ fclose(fout_xyz); fout_xyz = NULL; }
                fout_xyz = fopen("relaxed.xyz", "w");
                char str[256];
                sprintf(str,"# fmax = %g", world.fmax );
                world.exportAtomsXYZ( fout_xyz, str );
                fclose(fout_xyz); fout_xyz = NULL;
                break;
            }
            if( (getCPUticks()-tick1)>4e+8 ) break;
        }
        double ticks = (getCPUticks() - tick1)/((double)perFrame);
        printf("======= %i %5.2f Mticks/iter %5.2f tick/atom %5.2f ticks/interaction \n", iter, ticks*1.0e-6, ticks/world.nAtomTot, ticks/world.nInteractions );

        world.saveInstances( "instances_lastStep.ini" );
        if(fout_xyz){
            char str[256];
            sprintf(str,"# fmax = %g", world.fmax );
            world.exportAtomsXYZ( fout_xyz, str );
        }
    }
    //exit(0);

    //world.nonBondingFroces_buf(); return;

	glMatrixMode(GL_MODELVIEW);
	//glMatrixMode(GL_PROJECTION);
	glEnable(GL_LIGHTING);
    for (int i=0; i<world.nmols; i++){
        if( world.instances[i]->viewlist > 0 ){
            Mat3d rotmat;
            float glMat[16];
            //rot[i].toMatrix_unitary2( rotmat );
            //rot[i].toMatrix_unitary( rotmat );
            //printf( "%i   (%3.3f,%3.3f,%3.3f) (%3.3f,%3.3f,%3.3f,%3.3f)\n", i,  world.pos[i].x,world.pos[i].y,world.pos[i].z,   world.rot[i].x,world.rot[i].y,world.rot[i].z,world.rot[i].w  );
            world.rot[i].toMatrix( rotmat );
            glColor3f(0.0f,0.0f,0.0f); Draw3D::drawPointCross(world.pos[i],1.0);
            Draw3D::toGLMat( world.pos[i], rotmat, glMat ); // somehow not working
            //Draw3D::toGLMat( {0.0,0.0,0.0}, rotmat, glMat );
            glPushMatrix();
            glMultMatrixf( glMat );
            //glTranslatef( world.pos[i].x,world.pos[i].y,world.pos[i].z );
            //glMultTransposeMatrixf( glMat );
            //glLoadMatrixf( glMat );
            glCallList   ( world.instances[i]->viewlist );
            glPopMatrix();
        }
    };

    //printf(" nLinkers %i &linkers %i \n" , world.nLinkers,  world.linkers );
    glDisable(GL_LIGHTING);
    glColor3f(0.0f,1.0f,0.0f);
    if( world.linkers ){
        for (int il=0; il<world.nLinkers; il++){
            Mat3d T;
            Vec3d gpi,gpj;
            MolecularLink& li =  world.linkers[il];
            int i = li.i;
            world.rot[i].toMatrix( T);
            T.dot_to( li.posi, gpi );
            gpi.add( world.pos[i] );

            int j = li.j;
            world.rot[j].toMatrix(T);
            T.dot_to( li.posj, gpj );
            gpj.add( world.pos[j] );

            Draw3D::drawLine(  gpi, gpj );
            Draw3D::drawPointCross(gpi,0.5);
            Draw3D::drawPointCross(gpj,0.5);

            //printf( "%i (%i,%i)  (%3.3f,%3.3f,%3.3f)   (%3.3f,%3.3f,%3.3f)\n" , il, i,j,   li.posi.x, li.posi.y, li.posi.z, li.posj.x, li.posj.y, li.posj.z );
            //printf( "%i          (%3.3f,%3.3f,%3.3f)   (%3.3f,%3.3f,%3.3f)\n" , il, gpi.x, gpi.y, gpi.z,   gpj.x,gpj.y,gpj.z);
        }
    }

    if( world.bonds ){
        for (int il=0; il<world.nBonds; il++){
            Mat3d T;
            Vec3d lpi,lpj,gpi,gpj;
            MolecularBond& bi =  world.bonds[il];
            int i = bi.imol;
            world.rot[i].toMatrix( T);
            lpi = world.instances[i]->xyzs[bi.iatom];
            T.dot_to( lpi, gpi );
            gpi.add( world.pos[i] );

            int j = bi.jmol;
            world.rot[j].toMatrix(T);
            lpj = world.instances[j]->xyzs[bi.jatom];
            T.dot_to( lpj, gpj );
            gpj.add( world.pos[j] );

            Draw3D::drawLine(  gpi, gpj );

            //printf( "%i (%i,%i)  (%3.3f,%3.3f,%3.3f)   (%3.3f,%3.3f,%3.3f)\n" , il, i,j,   li.posi.x, li.posi.y, li.posi.z, li.posj.x, li.posj.y, li.posj.z );
            //printf( "%i          (%3.3f,%3.3f,%3.3f)   (%3.3f,%3.3f,%3.3f)\n" , il, gpi.x, gpi.y, gpi.z,   gpj.x,gpj.y,gpj.z);
        }
    }

    //exit(0);

};