

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>                         // for ...


#include "../ut/ut_geo.h"              // Point ...
#include "../ut/ut_ox_base.h"          // OGX_SET_INDEX

#include "../xa/xa_mem.h"              // memspc51, mem_cbuf1



//=============================================================================
  int APT_decode_sbsp_2 (ObjGX *ox1,int aus_anz,int aus_typ[],double aus_tab[],                            Memspc *tbuf1, Memspc *tbuf2, Memspc *tbuf3) {
//=============================================================================
// create Loft Surface, B-Spline-Surface, from curves along surface
// BSP U(Curves) [deg]
// aus_typ[0] = Typ_cmdNCsub; aus_tab[1] = = T_BSP0
// aus_typ[1] = Typ_Group;    aus_tab[1] = nr_of_curves
// 
// tbuf1 memspc501
// tbuf2 memspc201 temp
// tbuf3 mem_cbuf1
// wrkSeg memspc102


  int      irc, i1, i2, typ, iu1, deg1, cv1Nr;
  long     dbi, sDbi, bDbi;
  CurvBSpl **cv1tab, **cv2tab;
  SurBSpl  *su1;
  ObjGX    *oxTab;



  printf("================================================ \n");
  printf("APT_decode_sbsp_2: %d\n",aus_anz);
  for(i1=0; i1<aus_anz; ++i1) {
    printf(" %d typ=%d tab=%f\n",i1,aus_typ[i1],aus_tab[i1]);
  }


  //================================================================
  // Surfcae from 2-n Querschnittskurven: SkinnedSurface; exact.
  // exact: es werden die Knotentabellen aller curves exact gleich gemacht
  //   (sehr hoher Rechenaufwand)
  // max 19 curves.

  cv1Nr = aus_tab[1];
  if(cv1Nr > 19) goto Err_2;
  if(cv1Nr < 1) goto Par_err;
  iu1 = 2;
  i1 = iu1 + cv1Nr;

  if(i1 > aus_anz) {
    deg1 = aus_tab[i1];
    ++i1;
  } else {
    deg1 = 0;
  }

  // we have  <cv1Nr> curves starting at aus_*[iu1]
    // TESTBLOCK
    for(i1=0; i1<cv1Nr; ++i1)
    printf(" G1[%d] typ=%d ind=%d\n",i1,aus_typ[i1+iu1],(int)aus_tab[i1+iu1]);
    // END TESTBLOCK


  //----------------------------------------------------------------
  // reserve space for output-surf su1 in tbuf1
  su1 = UME_reserve (tbuf1, sizeof(SurBSpl));
  if(su1 == NULL) return -1;


  // reserve space for cv1tab inside tbuf1
  // cv1tab = tbuf1->next;
  cv1tab = UME_reserve (tbuf1, cv1Nr * sizeof(void*));   //CurvBSpl));
  if(cv1tab == NULL) return -1;


  // put 1. group of curves > cv1tab
  for(i1=0; i1<cv1Nr; ++i1) {
    i2 = iu1 + i1;
    typ = aus_typ[i2];
    dbi = aus_tab[i2];
      // printf(" G1[%d] typ=%d dbi=%d\n",i1,typ,dbi);
    // add lfig(LN/CI/CV) (typ,dbi) as cbsp to cv1tab
    irc = UT3D_cbsp_dbo (&cv1tab[i1], tbuf1, typ, dbi, tbuf3);
    if(irc < 0) return irc;
      // UT3D_stru_dump (Typ_CVBSP, cv1tab[i1], "U1[%d]",i1);
  }

  // orient B-SplCurves cv1tab (same direction)
  i1 = UT3D_ncvbsp_orient (cv1Nr, cv1tab, tbuf1);
  if(i1 < 0) return -1;


  // create bspl-surf from 2-n across-curves
  irc = UT3D_sbsp_ncv (su1, tbuf1,
                  cv1Nr, cv1tab, deg1,
                  tbuf2, tbuf3);
  if(irc < 0) return irc;



    // TESTBLOCK
    UT3D_stru_dump (Typ_SURBSP, su1, "" );
    printf(" - APT_decode_sbsp irc=%d\n",irc);
    // END TESTBLOCK


  // store surf in DB
  sDbi = DB_StoreSurBsp (-1L, su1);
  if(!sDbi) goto Err_DB;



//================================================================
  //----------------------------------------------------------------
  // create outer-boundary
  // see GL_sSym_sbsp UT3D_cv_sbspout
  //
  //  V1    x-----3------x                     // U along X; V along Y
  //        |            |
  //        4            2
  //        |            |
  //  V0    x-----1------x   
  //        U0           U1
  //
  //----------------------------------------------------------------
{
  // was UT3D_cv_sbspout   see also GL_sSym_spl
  int       i1, cvNr;
  CurvBSpl  cvTab[4];
  CurvCCV   ccvTab[4];


  //----------------------------------------------------------------
  // get cvTab[0] = 1.boundaryCurve   U (U0-U1 / V0)
  UT3D_bsp_sbspU (&cvTab[0], 0, su1);
    // GR_Disp_CvBSp (&cvTab[0], 9);
    // UT3D_stru_dump (Typ_CVBSP, &cvTab[0], " bndCv0 ");


  //----------------------------------------------------------------
  // get cvTab[1] = 2.boundaryCurve V-aussen (U0 / V0-V1)
  // cpTab und wTab of curves -> tbuf1
  i1 = su1->ptUNr-1;
  i1 = UT3D_bsp_sbspV (&cvTab[1], i1, su1, tbuf1);
    // GR_Disp_CvBSp (&cvTab[1], 9);
    // UT3D_stru_dump (Typ_CVBSP, &cvTab[1], " bndCv1 ");


  //----------------------------------------------------------------
  // cvTab[2] = randKurve U-aussen (U1 / V0-V1) REVERSE
  i1 = su1->ptVNr-1;
  UT3D_bsp_sbspU (&cvTab[2], i1, su1);
    // GR_Disp_CvBSp (&cvTab[2], 9);
    // UT3D_stru_dump (Typ_CVBSP, &cvTab[2], " bndCv2 ");

  //----------------------------------------------------------------
  // cvTab[3] = randKurve V0 (U0-U1 / V0) REVERSE
  // cpTab und wTab of curves -> tbuf1
  i1 = UT3D_bsp_sbspV (&cvTab[3], 0, su1, tbuf1);
    // GR_Disp_CvBSp (&cvTab[3], 9);
    // UT3D_stru_dump (Typ_CVBSP, &cvTab[3], " bndCv3 ");


  //----------------------------------------------------------------
  // create CCV from <cvNr> DB-obj's

  // loop tru <cvNr>
  cvNr = 4;

  for(i1=0; i1<cvNr; ++i1) {

    // store CurvBSpl in DB
    dbi = DB_StoreCvBsp (-1L, &cvTab[i1]);
    if(!dbi) goto Err_DB;

    // create PRCV for bin.obj
    PRCV_set_obj_dbi (Typ_CVBSP, &cvTab[i1], 1, Typ_CV, dbi);

    // create trimmed-curve from CurvBSpl
    CVTRM__dbo (&ccvTab[i1], Typ_CV, dbi);

    // reverse curve 3 and 4; .dir
    if(i1 > 1) UTO_stru_inv (Typ_CVTRM, &ccvTab[i1]);
      UT3D_stru_dump (Typ_CVTRM, &ccvTab[i1], " ex-CVTRM__dbo %d",i1);

  }


  // store CCV from ccvTab in DB
  bDbi = DB_StoreCvCCV (-1L, ccvTab, cvNr);
    printf(" dbi-ccv=%ld\n",bDbi);


    // TESTBLOCK
    // PRCV_test_get (Typ_CV, bDbi);
    // END TESTBLOCK

}


//================================================================
  // get space for 2 ox-records
  oxTab = UME_reserve (tbuf1, sizeof(ObjGX) * 2);
  if(oxTab == NULL) return -1;

  // 1. record = supporting sbsp-surface
  OGX_SET_INDEX (&oxTab[0], Typ_SURBSP, sDbi);

  // add outer-boundary as second ox-record 
  OGX_SET_INDEX (&oxTab[1], Typ_CVTRM, bDbi);


  //----------------------------------------------------------------
  ox1->typ   = Typ_SURBSP;
  ox1->form  = Typ_ObjGX;
  ox1->siz   = 2;
  ox1->data  = oxTab;


    // TESTBLOCK
    UTO_dump_s_ (ox1, "ex-APT_decode_sbsp");
    // GR_Disp_dbo (Typ_CV, bDbi, 9, 0);
    // END TESTBLOCK

  // return irc;
  return 0;


  //================= Fehler =============================
  Par_err:
    TX_Error("BsplSurfDefinition: ParameterError ****");
    goto Error;

  Err_DB:
    TX_Error("BsplSurfDefinition: DB-Error ****");
    goto Error;

  Err_2:
    TX_Error("BsplSurf: max 19 curves ****");


  Error:
  return -1;

}


//=============================================================================
  int APT_decode_su_pln (ObjGX *ox1,int aus_anz,int aus_typ[],double aus_tab[],                            Memspc *wrkSpc) {
//=============================================================================
// create ox1 = planar TPS-surface from outer & inner boundaries
// REPLACING APT_decode_su_pln
// Input:
//   aus_x[0]    outer-boundary; 1-n = inner-boundaries
//   aus_x[1-n]  inner-boundaries
// Output:
//   ox1         see INF_OGX_SUR_PLN
//
// was APT_decode_spl see APT_decode_fsub

  int     i1, i2;
  ObjGX   *oxTab;


  printf("APT_decode_su_pln %d\n",aus_anz);
    for(i1=0; i1<aus_anz; ++i1) {
    printf(" %d %d %f\n",i1,aus_typ[i1],aus_tab[i1]);
  }


  //----------------------------------------------------------------
  // get space for surTPS
  oxTab = UME_reserve (wrkSpc, sizeof(ObjGX) * (aus_anz + 1));
  if(oxTab == NULL) return -1;


  // which type of support-surface ?

  // oxTab[0] = supporting-surface
  //   supporting-surface planar: undef. (compute from outer-boundary)
  // OGX_SET_OBJ (&oxTab[0], Typ_modUndef, Typ_modUndef, 1, NULL);
  OGX_SET_OBJ (&oxTab[0], Typ_SURPLN, Typ_modUndef, 1, NULL);

  // oxTab[1] = outer boundary followed by inner-boundaries
  for(i1=0; i1<aus_anz; ++i1) {
    OGX_SET_INDEX (&oxTab[i1 + 1], aus_typ[i1], (long) aus_tab[i1]);
  }


  ox1->typ    = Typ_SURTPS;
  ox1->form   = Typ_ObjGX;
  ox1->siz    = aus_anz + 1;
  ox1->data   = oxTab;


    // TESTBLOCK
    UTO_dump_s_ (ox1, "ex-APT_decode_su_pln");
    // END TESTBLOCK

  return 0;

}

// EOF
