void cAppliApero::SimuleOneLiaison
     (
         const cGenerateLiaisons & aGL,
	 const std::list<Pt3dr>  & aLP3,
         cPoseCam & aCam1,
         cPoseCam & aCam2
     )
{
   const CamStenope * aCS1 = aCam1.CurCam();
   const CamStenope * aCS2 = aCam2.CurCam();

   ElPackHomologue aPack;

   for(std::list<Pt3dr>::const_iterator itP3=aLP3.begin();itP3!=aLP3.end();itP3++)
   {
      Pt2dr aPIm1 = aCS1->R3toF2(*itP3)+Pt2dr(NRrandC(),NRrandC())*aGL.BruitIm1();
      Pt2dr aPIm2 = aCS2->R3toF2(*itP3)+Pt2dr(NRrandC(),NRrandC())*aGL.BruitIm2();

      aPack.Cple_Add(ElCplePtsHomologues(aPIm1,aPIm2));
   }

   std::string aName = mDC+mICNM->Assoc1To2(aGL.KeyAssoc(),aCam1.Name(),aCam2.Name(),true);
   cElXMLFileIn aFileXML(aName);
   aFileXML.PutPackHom(aPack);
}
void cModeleAnalytiqueComp::SauvHomologues(const ElPackHomologue & aPack)
{


   TifSauvHomologues(aPack);

   if (mModele.AutomNamesExportHomXml().IsInit())
   {
       AssertAutomSelExportOriIsInit(mModele);
       std::string aNameXML = StdNameFromCple
                              (
                                  mAutomExport,
                                  mModele.AutomSelExportOri().Val(),
                                  mModele.AutomNamesExportHomXml().Val(),
                                  "@",
                                  mAppli.PDV1()->Name(),
                                  mAppli.PDV2()->Name()
                              );
       cElXMLFileIn aFileXML(mAppli.FullDirResult()+aNameXML);
       aFileXML.PutPackHom(aPack);
   }
   if (mModele.KeyNamesExportHomXml().IsInit())
   {
         std::string aNameXML = mAppli.ICNM()->Assoc1To2
	                        (
				    mModele.KeyNamesExportHomXml().Val(),
                                    mAppli.PDV1()->Name(),
                                    mAppli.PDV2()->Name(),
				    true
				);
         // cElXMLFileIn aFileXML(mAppli.WorkDir()+aNameXML);
         // aFileXML.PutPackHom(aPack);
         aPack.StdPutInFile(mAppli.WorkDir()+aNameXML);
   }
   if (mModele.AutomNamesExportHomBin().IsInit())
   {
       AssertAutomSelExportOriIsInit(mModele);
       std::string aNameBin = mAppli.FullDirResult()
                            + StdNameFromCple
                              (
                                  mAutomExport,
                                  mModele.AutomSelExportOri().Val(),
                                  mModele.AutomNamesExportHomBin().Val(),
                                  "@",
                                  mAppli.PDV1()->Name(),
                                  mAppli.PDV2()->Name()
                              );
        ELISE_fp aFP (aNameBin.c_str(),ELISE_fp::WRITE);
        aPack.write(aFP);
        aFP.close();
   }
}
void cModeleAnalytiqueComp::SolveHomographie(const ElPackHomologue &  aPackHom)
{
   mHomogr = cElHomographie(aPackHom,mModele.HomographieL2().Val());

   mBoxPoly = Box2dr(Pt2dr(0,0),Pt2dr(0,0));
   if (mDegrPolAdd >0)
   {
      ElPackHomologue aPck2 = aPackHom;
      Pt2dr aPMin(1e5,1e5);
      Pt2dr aPMax(-1e5,-1e5);
      for 
      (
         ElPackHomologue::iterator iT = aPck2.begin();
         iT != aPck2.end();
         iT++
      )
      {
           iT->P1() = mHomogr.Direct(iT->P1());
           aPMin.SetInf(iT->P1());
           aPMax.SetSup(iT->P1());
      }
      double anAmpl = ElMax(dist8(aPMin),dist8(aPMax));
      mBoxPoly = Box2dr(aPMin,aPMax);
      bool aPL2 = mModele.PolynomeL2().Val();
      mPolX = aPck2.FitPolynome(aPL2,mDegrPolAdd,anAmpl,true);
      mPolY = aPck2.FitPolynome(aPL2,mDegrPolAdd,anAmpl,false);

   }
// Polynome2dReal  ElPackHomologue::FitPolynome

   {
      cElXMLFileIn aFileXML(mNameXML);
      aFileXML.PutElHomographie(mHomogr,"Homographie");

      if (mDegrPolAdd >0)
      {
         cElXMLFileIn::cTag aTag(aFileXML,"PolynomeCompl"); aTag.NoOp();
         
         aFileXML.PutPoly(mPolX,"XPoly");
         aFileXML.PutPoly(mPolY,"YPoly");
         
         aFileXML.PutPt2dr(mBoxPoly._p0,"PMinBox");
         aFileXML.PutPt2dr(mBoxPoly._p1,"PMaxBox");
      }
   } 
   MakeInverseModele();

   // Verification de la correction du calcul  de l'inverse
    if (0)
   {
      int aNb=10;
      double aEps = 0.05;
      for (int aKx=0 ; aKx<= aNb ; aKx++)
      {
          double aPdsX = ElMax(aEps,ElMin(1-aEps,aKx/double(aNb)));
          for (int aKy=0 ; aKy<= aNb ; aKy++)
          {
              
              double aPdsY = ElMax(aEps,ElMin(1-aEps,aKy/double(aNb)));
              Pt2dr aPRas = Pt2dr (mSzGl.x*aPdsX, mSzGl.x*aPdsY);
              Pt2dr aPTer = mGeoTer.RDiscToR2(aPRas);
              Pt2dr aP1 = Direct(Pt2dr(aPTer));

              Pt2dr aQ2 =  Inverse(aP1);
              double anEr = euclid(aPTer,aQ2);
              if (anEr>0.05)
              {
                 std::cout << "Erreur = " << anEr << "\n";
                 std::cout <<  aPRas <<  aPTer << "\n";
                 
                 Pt2dr aP0 = aPTer;
                 Pt2dr aP1 = mGeom2.CorrigeDist1(aP0);
                 Pt2dr aP2 = CorrecDirecte(aP1);
                 Pt2dr aP3 = mGeom2.InvCorrDist2(aP2);

                 Pt2dr aQ0 = mGeom2.InvCorrDist1(aP1);
                 std::cout << "pq0= " << euclid(aP0,aQ0) << aP0 << aQ0 << "\n";

                 Pt2dr aQ1 = CorrecInverse(aP2);
                 std::cout << "pq1= " << euclid(aP1,aQ1) << aP1 << aQ1 << "\n";

                 Pt2dr aQ2 =  mGeom2.CorrigeDist2(aP3);
                 std::cout << "pq2= " << euclid(aP2,aQ2) << aP2 << aQ2 << "\n";
                 std::cout << "P3 " << aP3 << "\n";

                  ELISE_ASSERT(false,"MakeInverseModele Pb!!");
              }
         }
     }
   }

   if (mModele.ExportImage().Val() || mModele.ReuseResiduelle().Val() )
   {
      Im2D_REAL4 anImX(mSzGl.x,mSzGl.y);
      TIm2D<REAL4,REAL8> aTImX(anImX);
      Im2D_REAL4 anImY(mSzGl.x,mSzGl.y);
      TIm2D<REAL4,REAL8> aTImY(anImY);

      Pt2di aPRas;
      double aPX0[2] = {0.0,0.0};
      for (aPRas.x=0 ; aPRas.x<mSzGl.x ; aPRas.x++)
      {
          for (aPRas.y=0 ; aPRas.y<mSzGl.y ; aPRas.y++)
          {
              Pt2dr aPTer = mGeoTer.DiscToR2(aPRas);
              Pt2dr aP1 = Direct(Pt2dr(aPTer));


              Pt2dr aP2 ;
              if (mModele.ReuseResiduelle().Val())
                 aP2 = mGeom2.Objet2ImageInit_Euclid(Pt2dr(aPTer),aPX0);
              else
                 aP2 = mGeom2.InvCorrDist2(mGeom2.CorrigeDist1(aPTer));
              double aPx[2];
              aPx[0] = aP1.x- aP2.x;
              aPx[1] = aP1.y- aP2.y;
              mGeoTer.PxReel2PxDisc(aPx,aPx);
              
               
              aTImX.oset(aPRas,aPx[0]);
              aTImY.oset(aPRas,aPx[1]);
          }
      }
      if (mModele.ExportImage().Val())
      {
         Tiff_Im::Create8BFromFonc(mNameImX,mSzGl,ToUC(anImX.in()));
         Tiff_Im::Create8BFromFonc(mNameImY,mSzGl,ToUC(anImY.in()));
      }
      if (mModele.ReuseResiduelle().Val())
      {
         Tiff_Im::Create8BFromFonc(mNameResX,mSzGl,ToUC(anImX.in()-ImPx(0)));
         Tiff_Im::Create8BFromFonc(mNameResY,mSzGl,ToUC(anImY.in()-ImPx(1)));
      }
  } 
  if (mExpModeleGlobal)
  {

      const cGeomDiscFPx &  aG = mAppli.GeomDFPxInit() ;
      Box2dr aBox = aG.BoxEngl();
      double aME =mModele.MailleExport().Val();


      cDbleGrid  aGrid
                 (
                     true, // P0P1 Direct par defaut maintien du comp actuel
                     true,
                     aBox._p0,aBox._p1,
                     Pt2dr(aME,aME),
                     *this,
                     "toto"
                 );


     std::string aNameXML =  mAppli.ICNM()->Assoc1To2
                             (
			        mModele.FCND_ExportModeleGlobal().Val(),
                                mAppli.PDV1()->Name(),
                                mAppli.PDV2()->Name(),
				true
			     );
     aGrid.SaveXML(mAppli.FullDirResult() + aNameXML);
  }

}