/* ../xa/test_SUR.c

Model:  test_sur_tess1.gcad
*/

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#include "../ut/ut_geo.h"              // Point ...
// #include "../ut/ut_geo_const.h"        // UT3D_CCV_NUL
#include "../ut/ut_memTab.h"           // MemTab_..
#include "../ut/ut_itmsh.h"            // MSHIG_EDGLN_.. typedef_MemTab.. Fac3
// #include "../ut/ut_face.h"              // UFA
// #include "../ut/msh2d.h"               // TessStru
#include "../ut/ut_ox_base.h"          // OGX_SET_INDEX
#include "../db/ut_DB.h"               // DB_GetObjGX
#include "../xa/xa_mem.h"              // memspc51, mem_cbuf1


// Externals aus ../xa/xa.c:
// extern char      AP_mod_fnam[128];
// extern Plane     WC_sur_act;            // die aktive Plane
extern int       WC_modact_ind;         // -1=primary Model is active;
                                        // else subModel is being created



//=========================================================
  int gCad_fini () {
//=========================================================

  AP_User_reset ();

  return 0;

}


//=========================================================
  int gCad_main () {
//=========================================================


  TX_Print(">>>>>>>>> gCad_main test_SUR__ <<<<<<<<<<\n");

  AP_debug__ ("test_SUR__");


  // init static structs SUR__  and MSH__; do be done at gcad-startup only !
  SUR_init__ ();


  test_SUR__ ();

  // DL_Redraw ();

  gCad_fini ();

  return 0;

}


//================================================================
  int test_SUR__ () {
//================================================================
// was tst__

  printf("test_SUR__ \n");


  test_SUR_pln ();     // see INF_OGX_SUR_TPS
  // test_SUR_bsp ();

/*
// see tst__

- create DB-surf from sourceLine or atomicObjects
  // APT_decode_su_swp_cyl
  // APT_decode_su_pln
  // APT_decode_sbsp_2


- save sur -> DB (with boundary-curves)
  // DB_StoreSur

- get sur out of DB (with boundary-curves)
  - test if filed mesh exists; if yes: read (MSHIG_rdf__())

- get TPS-surface from (any !) DB-surface (hat bounds und suppSur)
  // see TSU_stps_sur

- get 2D-points of boundary-curves

- get tolerances and grid for TPS-surface

- get mesh (tesselate 2D)
  // MSH2D_tess__

- get (missing) 3D-vectors

- save to file (mesh, binary)
  // MSHIG_wrf__
  //  MSH_bsav_fTab     save faceTable to bin. file M#A#.msh
  //  MSH_bload_fTab    load faceTable from bin.file


- display
  // MSHIG_view__ 
  // ../xa/tst_glDrawElements1.c tst_glDrawElements1.mak
  // GL_Disp_ipatch



TESTS:
- test OB
  // TSU_test_OB__ TSU_test_OB_1

- intersect mesh with plane
  // tst_tess_int

*/

  return 0;

}


//================================================================
  int test_SUR_pln () {
//================================================================
// Testmodel eg /mnt/serv1/Devel/cadfiles/gcad/test_sur_cyl_5.gcad
// was tst__


  int      irc, aus_typ[10], ausNr;
  double   aus_tab[10];
  long     dbiSur, dbiInt;
  Memspc   wrkSpcP;
  ObjGX    ox1;

  printf("test_SUR_pln \n");



  // for obj's to store in DB (cpTab und wTab for curves ..)
  UME_init (&wrkSpcP, memspc501, sizeof(memspc501));



//================================================================
// store surface <dbiPln> into DB 
//----------------------------------------------------------------
// planar-surface Circ (test_sur_pln1.gcad):   replacing:
// APT_decode_spl    // Standardflaechen (planar, Conic, Torus
// NEW: store planar-surface as TPS-surface !
// C20=P(-1000 -200 0) P(-900 -100 0)
// C21=P(-1056.703373 -243.018481 0) P(-1011.443215 -269.839314 0)
// A20=C20 C21
    aus_typ[0] = Typ_CI;       aus_tab[0] = 20.;     ausNr = 1;
    aus_typ[1] = Typ_CI;       aus_tab[1] = 21.;     ausNr = 2;
    aus_typ[2] = Typ_CI;       aus_tab[2] = 22.;     ausNr = 3;
    aus_typ[3] = Typ_CI;       aus_tab[3] = 23.;     ausNr = 4;
    // get objGX from atomicObjects
    APT_decode_su_pln (&ox1, ausNr, aus_typ, aus_tab, &wrkSpcP);
    // goto L_start;

/*
//----------------------------------------------------------------
// planar-surface CCV (test_sur_pln1.gcad):   replacing:
// APT_decode_spl    // Standardflaechen (planar, Conic, Torus
// NEW: store planar-surface as TPS-surface !
    // create ox1 = surf-planar
    aus_typ[0] = Typ_CV;       aus_tab[0] = 23.;     ausNr = 1;
    // aus_typ[1] = Typ_CI;       aus_tab[1] = 23.;     ausNr = 2;
    APT_decode_su_pln (&ox1, ausNr, aus_typ, aus_tab, &wrkSpcP);
    dbiPln = 22L;
    // goto L_start;
*/


  //----------------------------------------------------------------
  // store surface ox1 in DB; get DB-index
  L_start:
  dbiSur = 20L;
  DB_StoreSur (&dbiSur, &ox1);   printf(" dbiSur=%ld\n",dbiSur);
    // GR_Disp_dbo (Typ_SUR, dbi, 9, 0);


  //----------------------------------------------------------------
  // test outer-boundary of sur <dbiSur>
  // TSU_test_OB__ (dbiSur);
  // test_SUR_bnd__ (dbiSur);   OK






//================================================================
// create-write | read binary-suface-file,

  dbiInt = 20L; // Typ_PLN

  // create binary-suface-file, write into file
  irc = test_SUR_sur__ (dbiSur, dbiInt);
  if(irc < 0) return irc;


  return 0;

}


//================================================================
  int test_SUR_sur__ (long dbiSur, long dbiInt) {
//================================================================
// create binary-suface-file, write into file
 
  int    irc=0;

  printf("test_SUR_sur__ %ld\n", dbiSur);


  // load surface from db into SUR-surface SUR__/MSH__
  // irc = SUR_tess_dbo__ (dbiSur);     // see INF_OGX_SUR_TPS
  // if(irc < 0) return irc;
  // see TSU_stps_sur
  // see MSHIG_init_sur 


  // save into file
  // SUR_wrf__ (dbiSur);


  // read sur from file
  SUR_rdf__ (dbiSur);


  // display surface in structs SUR__/MSH__
  // SUR_view__ (dbiSur);
  // DL_Redraw ();

  // test intersect surface
  test_SUR_int (dbiInt);


  return 0;

}


//================================================================
  int test_SUR_int (long dbiInt) {
//================================================================

  MemTab(Line) lna = _MEMTAB_NUL;


  printf("test_SUR_int \n");

// TODO: SUR_int_sur

  SUR_int_pln (&lna, dbiInt);

  // TESTBLOCK


  MemTab_free (&lna);


  return 0;

}
 

//================================================================
  int test_SUR_bsp () {
//================================================================
// # loft-Surf (SU_bsp)
// P30=P(447.873692 -825.783636 0)
// P31=P30 Z(300)
// P32=P30 Z(600)
// S30=BSP P(547.913653 -312.679356 0) P(244.976163 -625.714759 0) P(143.996999 -938.750161 0) P(194.486581 -1251.785564 0)
 // R(P31)
// S31=BSP P(180.751815 372.80902 0) P(-80.03844 196.927222 0) P(-158.882006 -51.733251 0) P(-55.778882 -379.237288 0)
 // R(P32)
// S32=BSP P(202.614713 205.099864 0) P(-21.342957 130.447309 0) P(-65.256225 -40.814436 0) P(48.918273 -251.598123 0)
// RZ
// R23=PERP P30 D(0.2 1 0.25)
// #A20=BSP U(S30 S31 S32)

  return 0;

}


//================================================================
  int test_SUR_bnd__ (long dbiSur) {
//================================================================
// test outer-boundary of sur <dbiSur>
// was TSU_test_OB__ (dbiSur);

  int     irc, bTyp, ptNr, iBnd;
  long    bDbi;
  ObjGX   *oSur, *oTab, *oBnd;
  Point   *pta;


  printf("test_SUR_bnd__ %ld\n",dbiSur);


  // get oxSur = complex-obj of surface <dbiSur>
  oSur = DB_GetSur (dbiSur, 1);
  if(oSur->form != Typ_ObjGX) return -1;
  if(oSur->siz < 2) return -1;
    printf(" form=%d siz=%d\n",oSur->form,oSur->siz);
    UTO_dump_s_ (oSur, "ex-DB_GetSur");
    UT3D_stru_dump (Typ_ObjGX, oSur, " oSur");



  // loop tru boundaries of surface
  oTab = oSur->data;
  iBnd = 1;

  L_nxt_bnd:
    // outer-boundary = second subObj of complex-obj oSur
    irc = SUR_dbo_ib_oSur (&bTyp, &bDbi, iBnd, oSur);
    if(irc < 0) return -1;

    // display
    irc = GR_Disp_dbo (bTyp, bDbi, 8, 0);

    ++iBnd;
    if(iBnd < oSur->siz) goto L_nxt_bnd;


  //----------------------------------------------------------------
  DL_Redraw (); // Redraw DispList

  return irc;

}

/*
//================================================================
  int test_SUR_bnd_1 (int typOB, long dbiOB) {
//================================================================
// REPLACED by GR_Disp_dbo
// display DB-objec
// Input:
//   dbTyp, dbi      typ, index od DB-object
// was TSU_test_OB_1

  int     i1, OBform, OBnr, OBrSiz;
  char    *data;
  void    *OBdat;


  printf("------------------------------------ \n");
  printf("test_SUR_bnd_1 typ=%d dbi=%ld\n",typOB,dbiOB);


  // get data for OB-link
  OBform = DB_GetObjDat (&OBdat, &OBnr, typOB, dbiOB);
  if(OBform < 0) return -1;
    printf(" OBform=%d OBnr=%d\n",OBform,OBnr);
    UT3D_nstru_dump (OBform, OBnr, OBdat, "  _OB-dat");


  OBrSiz = UTO_siz_stru (OBform);
    printf(" OBform=%d OBnr=%d OBrSiz=%d\n",OBform,OBnr,OBrSiz);

  // loop tru and display boundary-obj
  data = (char*)OBdat;
  for(i1=0; i1<OBnr; ++i1) {
      UT3D_stru_dump (OBform, (void*)data, " _OB_1-%d",i1);
      // display boundary-obj
      GR_Disp_obj (OBform, (void*)data, 8, 0);
    data += OBrSiz;
  }

  return 0;

}
*/

//================================================================
// SUR - functions -> ../xa/tst_ut_sur1.c
//================================================================


//================================================================
  int UT3D_bp_inpt (int pNr, int *ipa, Point *pa) {
//================================================================
/// \code
/// backplane from n points
/// see UT3D_bp_vcz
/// \endcode

  Point   p1, p2;
  Vector  vc1;

  // box from n points
  UT3D_box_inpt (&p1, &p2, pNr, ipa, pa);

  // vec from box
  UT3D_vc_2pt (&vc1, &p1, &p2);
    // GR_Disp_vc (&vc1, &p1, 2, 1);

  // backplane from vector
  return UT3D_bp_vc_ (&vc1);

}


//==============================================================================
  int UT3D_box_inpt (Point *pmin, Point *pmax, int nump, int *ipa, Point *ptab) {
//==============================================================================
/// \code
/// UT3D_box_pts         bounding box <-- points
/// 
/// Computation of a minimal axis-parallel box which contains all given points.
/// The box is given by the endpoints of its diagonal.
/// If all points ly in a plane parallel x,y-plane, the box will be a rectangle.
/// 
/// IN:
///   int nump    ... number of points
///   Point *ptab ... points
/// OUT:
///   Point *pmin ... endpoint 1 of box diagonal 
///   Point *pmax ... endpoint 2 of box diagonal
/// Returncodes:
///   0 = OK
///  -1 = input error
/// \endcode


  int    i1;
  Point  *ptx;

  //printf("UT3D_box_pts: bounding box <-- points\n");

  if (nump < 1) {
    printf("UT3D_box_pts: input error\n");
    return -1;
  }

  *pmin = ptab[0];
  *pmax = ptab[0];

  for (i1=1; i1<nump; ++i1) {
    ptx = &ptab[ipa[i1]];
    if (ptx->x < pmin->x) pmin->x = ptx->x;
    if (ptx->y < pmin->y) pmin->y = ptx->y;
    if (ptx->z < pmin->z) pmin->z = ptx->z;
    if (ptx->x > pmax->x) pmax->x = ptx->x;
    if (ptx->y > pmax->y) pmax->y = ptx->y;
    if (ptx->z > pmax->z) pmax->z = ptx->z;
  }

  return 0;
}


// EOF
