Pt3dr cMEPCoCentrik::ComputeBase()
{
    Pt3dr aBest(0,0,0);
    double aScoreMin = 1e20;

    for (int aK1=0 ; aK1<int(mVPlanBase.size()); aK1++)
    {
         Pt3dr aCdtBase = mVPlanBase[aK1];
         double aScore = 0;
         for (int aK2=0 ; aK2<int(mVPlanBase.size()); aK2++)
         {
               Pt3dr aP2 = mVPlanBase[aK2];
               if (scal(aP2,aCdtBase) < 0) aP2 = -aP2;
               double aDist = euclid(aP2-aCdtBase);
               aDist =  CoutAttenueTetaMax(aDist,0.3);
               aScore += aDist;
         }
         if (aScore < aScoreMin)
         {
              aScoreMin = aScore;
              aBest = aCdtBase;
         }
    }
    return aBest;
}
void cAppliOptimTriplet::Execute()
{
   ElTimer aChrono;
   if (! EAMIsInit(&mNbMaxSel))
   {
        mNbMaxSel = mQuick ? QuickDefNbMaxSel : StdDefNbMaxSel;
   }

   if (mShow) 
      mQuitExist = false;


   mNbMaxInit = mQuick ? QuickNbMaxInit   : StdNbMaxInit ;


   if (! EAMIsInit(&mShow))
       mShow  = EAMIsInit(&mSzShow);


   if (MMVisualMode) return;
   

   cNewO_OneIm * mNoIm3 = new cNewO_OneIm(*mNM,m3S.mV2);

   std::string aNameSauveXml = mNM->NameOriOptimTriplet(false,mNoIm1,mNoIm2,mNoIm3,false);
   std::string aNameSauveBin = mNM->NameOriOptimTriplet(true ,mNoIm1,mNoIm2,mNoIm3,false);

   if (ELISE_fp::exist_file(aNameSauveXml) && ELISE_fp::exist_file(aNameSauveBin) && mQuitExist)
      return ;

   std::string  aName3R = mNM->NameOriInitTriplet(true,mNoIm1,mNoIm2,mNoIm3);
   cXml_Ori3ImInit aXml3Ori = StdGetFromSI(aName3R,Xml_Ori3ImInit);

   mIms.push_back(new  cImOfTriplet(0,*this,mNoIm1,ElRotation3D::Id));
   mIms.push_back(new  cImOfTriplet(1,*this,mNoIm2,Xml2El(aXml3Ori.Ori2On1())));
   mIms.push_back(new  cImOfTriplet(2,*this,mNoIm3,Xml2El(aXml3Ori.Ori3On1())));

   mIm1 = mIms[0];
   mIm2 = mIms[1];
   mIm3 = mIms[2];
   mFoc =  1/ (  (1.0/mIm1->Foc()+1.0/mIm2->Foc()+1.0/mIm3->Foc()) / 3.0 ) ;


   // mP12 = new cPairOfTriplet(mIm1,mIm2,mIm3);
   // mP13 = new cPairOfTriplet(mIm1,mIm3,mIm2);
   // mP23 = new cPairOfTriplet(mIm2,mIm3,mIm1);
   mPairs.push_back(new cPairOfTriplet(mIm1,mIm2,mIm3));
   mPairs.push_back(new cPairOfTriplet(mIm1,mIm3,mIm2));
   mPairs.push_back(new cPairOfTriplet(mIm2,mIm3,mIm1));
   mP12 = mPairs[0];
   mP13 = mPairs[1];
   mP23 = mPairs[2];

   mNM->LoadTriplet(mIm1->Im(),mIm2->Im(),mIm3->Im(),&mIm1->VFullPtOf3(),&mIm2->VFullPtOf3(),&mIm3->VFullPtOf3());


   if (EAMIsInit(&mSzShow) && (!EAMIsInit(&mNbMaxSel)))
   {
      mNbMaxSel = ModeShowNbMaxSel;
   }

   if (mShow) 
      std::cout << "Time load " << aChrono.uval() << "\n";
   int aNb3 = round_up(CoutAttenueTetaMax(mIm2->VFullPtOf3().size() ,mNbMaxSel));
   

   mNbMaxSel = aNb3;

  //  mSel3 = IndPackReduit(mIm2->VFullPtOf3(),mNbMaxInit,mNbMaxSel);

   mSel3 = IndPackReduit(mIm2->VFullPtOf3(),mNbMaxInit,mNbMaxSel);

   for (int aK=0 ; aK<3 ; aK++)
   {
        mIms[aK]->SetReduce(mSel3);
        mFullH123.push_back(&(mIms[aK]->VFullPtOf3()));
        mRedH123.push_back(&(mIms[aK]->VRedPtOf3()));
   }

   mP12->SetPackRed(false,mNbMaxInit,mNbMaxSel,mSel3,*mFullH123[1]);
   mP23->SetPackRed(true ,mNbMaxInit,mNbMaxSel,mSel3,*mFullH123[1]);
   mP13->SetPackRed(true ,mNbMaxInit,mNbMaxSel,mSel3,*mFullH123[0]);
   mPds3 = ElMin(MaxSurPond3,(mP12->NbR()+mP13->NbR()+mP23->NbR())/double(mIm1->NbR()));


   mBestResidu =  ResiduGlob();
/*
   TestOPA(*mP12);
*/

   if (mShow) 
   {
      std::cout << "Time reduc " << aChrono.uval()   << "  Pds3=" << mPds3 << "\n";
   }

   for (int aKP=0 ; aKP<int(mPairs.size()) ; aKP++)
   {
       TestOPA(*(mPairs[aKP]));
   }

   if (mShow) 
   {
      std::cout << "Time opa " << aChrono.uval()   << "\n";
   }



   if (mShow)
   {
      std::cout << "NB TRIPLE " << mIm2->VFullPtOf3().size()  << " Resi3: " <<  ResiduTriplet() << " F " << mFoc << "\n";
      std::cout << "RESIDU/PAIRES " << mP12->ResiduMoy() << " " << mP13->ResiduMoy() << " " << mP23->ResiduMoy() << " " << "\n";
      std::cout << "R Glob " << ResiduGlob() << "\n";
   }

#if (ELISE_X11)

   if (EAMIsInit(&mSzShow))
   {
      mIm2->InitW(mSzShow);
      ShowPoints(mIm2,mP12->FullVP2(),P8COL::cyan,2);
      ShowPoints(mIm2,mP23->FullVP1(),P8COL::yellow,2);

      ShowPointSel(mIm2,mP12->VRedP2(),P8COL::cyan);
      ShowPointSel(mIm2,mP23->VRedP1(),P8COL::yellow);
      std::cout << "NB 12 " << mP12->VRedP2().size() << "\n";
      // ShowPoints(mIm2,mIm2->VFullPtOf3(),P8COL::blue,4);
      // ShowPointSel(mSel3.mVSel,mIm2,mIm2->VFullPtOf3(),P8COL::red);

      // 
      ShowPoints(mIm2,mIm2->VFullPtOf3(),P8COL::blue,2);
      ShowPointSel(mIm2,mIm2->VRedPtOf3(),P8COL::blue);


      //==================================
      mIm1->InitW(mSzShow);
      ShowPoints(mIm1,mP13->FullVP1(),P8COL::cyan,2);
      ShowPointSel(mIm1,mP13->VRedP1(),P8COL::cyan);

      ShowPoints(mIm1,mIm1->VFullPtOf3(),P8COL::blue,2);
      ShowPointSel(mIm1,mIm1->VRedPtOf3(),P8COL::blue);

      mIm2->W()->clik_in();
   }

#endif

/*
   SolveBundle3Image
   (
        mFoc,
        mIm2->Rot(),
        mIm3->Rot(),
        mFullH123,
        mP12->FullHoms(),
        mP13->FullHoms(),
        mP23->FullHoms()
   );
*/
   int aNbIterBundle = mQuick ? QuickNbIterBundle : StdNbIterBundle;
   double aBOnH;
   Pt3dr aPMed;
   SolveBundle3Image
   (
        mFoc,
        mIm2->Ori(),
        mIm3->Ori(),
        aPMed,
        aBOnH,
        mRedH123,
        mP12->RedHoms(),
        mP13->RedHoms(),
        mP23->RedHoms(),
        mPds3,
        aNbIterBundle
   );


   cXml_Ori3ImInit aXml;
   aXml.Ori2On1() = El2Xml(mIm2->Ori());
   aXml.Ori3On1() = El2Xml(mIm3->Ori());
   aXml.ResiduTriplet() = ResiduGlob();
   aXml.NbTriplet() = (int)mRedH123[0]->size();
   aXml.BSurH() = aBOnH;
   aXml.PMed() = aPMed;

   MakeFileXML(aXml,aNameSauveXml);
   MakeFileXML(aXml,aNameSauveBin);



   if (mShow)
   {
      std::cout << "NB TRIPLE " << mIm2->VFullPtOf3().size()  << " Resi3: " <<  ResiduTriplet() << " F " << mFoc << "\n";
      std::cout << "RESIDU/PAIRES " << mP12->ResiduMoy() << " " << mP13->ResiduMoy() << " " << mP23->ResiduMoy() << " " << "\n";
      std::cout << "R Glob " << ResiduGlob() << "\n";
      std::cout << "Time bundle " << aChrono.uval() << "\n";
   }


    for (int aK=0 ; aK<3 ; aK++)
    {
        delete  mPairs[aK];
        delete  mIms[aK];
    }
    mPairs.clear();
    mIms.clear();
    mFullH123.clear();
    mRedH123.clear();
}