Logo Search packages:      
Sourcecode: varkon version File versions  Download package

dbsurf.c

/**********************************************************************
*
*    dbsurf.c
*    ========
*
*
*    This file includes the following public functions:
*
*    DBinsert_surface();     Inserts a surface entity (no patch data)
*    DBread_surface();       Reads a surface entity (no patch data)
*    DBupdate_surface();     Updates a surface entity (no patch data)
*    DBdelete_surface();     Deletes a surface entity (no patch data)
*
*    DBread_patches();       Reads all patches
*    DBread_one_patch();     Reads one patch
*   *DBcreate_patches();     Allocates memory for patch data
*    DBcreate_NURBS();       Allocates memory for NURBS data
*    DBfree_patches();       Free's allocated patch memory
*
*    DBadd_srep_curves();    Writes wireframe representation
*    DBread_srep_curves();   Reads wireframe representation
*    DBdelete_srep_curves(); Deletes wireframe representation
*    DBfree_srep_curves();   Free's mem allocated for wireframe representation
*
*    DBadd_srep_NURBS();     Writes NURBS representation
*    DBread_srep_NURBS();    Reads NURBS representation
*    DBdelete_srep_NURBS();  Deletes NURBS representation
*    DBfree_srep_NURBS();    Free's memory allocated for NURBS representation
*
*    This file is part of the VARKON Database Library.
*    URL:  http://www.varkon.com
*
*    This library is free software; you can redistribute it and/or
*    modify it under the terms of the GNU Library General Public
*    License as published by the Free Software Foundation; either
*    version 2 of the License, or (at your option) any later version.
*
*    This library is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*    Library General Public License for more details.
*
*    You should have received a copy of the GNU Library General Public
*    License along with this library; if not, write to the Free
*    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*    (C)Microform AB 1984-1998, Johan Kjellander, johan@microform.se
*
***********************************************************************/

#include <string.h>
#include "../include/DB.h"
#include "../include/DBintern.h"

static DBptr    wrgseg (short nseg, GMSEG *segdat);
static GMSEG   *rdgseg(short nseg, DBptr la);
static DBstatus dlgseg(short nseg,DBptr la);
static DBstatus gmwrnp(GMPATNU *np, DBptr *pla);
static DBstatus gmrdnp(GMPATNU *np);
static DBstatus gmrlnp(DBptr la);

/*!******************************************************/

        DBstatus DBinsert_surface(
        GMSUR   *surpek,
        GMPAT   *ptpat,
        DBId    *idpek,
        DBptr   *lapek)

/*      Huvudrutin för lagring av yta.
 *
 *      In: surpek => Pekare till en surf-structure.
 *          ptpat  => Pekare till topologipatchnätet.
 *          idpek  => Pekare till identitet-structure.
 *          lapek  => Pekare till DBptr-variabel.
 *
 *      Ut: *la    => Logisk adress till surf-post.
 *
 *      FV:  Returnerar status från inpost().
 *
 *      Felkoder: GM1043 = Kan ej allokera minne för patchtabell
 *
 *      (C)microform ab 3/11/92 J. Kjellander
 *
 *      22/2/93    RATSUR och LFTSUR, J.Kjellander
 *      31/1/94    Grafiska segment, J.Kjellander
 *      14/3/94    Nya GMPAT, J.Kjellander
 *      15/3/95    v3mall(), J.Kjellander
 *      1996-01-29 CON_PAT, J.Kjellander
 *      1996-07-04 Polynompatchar, J.Kjellander
 *      1997-03-05 GMPOSTV1, J.Kjellander
 *      1997-11-05 GMPATNU, J.Kjellander
 *
 ******************************************************!*/

  {
    DBptr   *tabpek,*ptab,tabla,la;
    DBint    nu,nv,i,j,tabsiz;
    GMPAT   *patpek,*spek;

/*
***Allokera minne för patch-tabellen.
*/
    nu = surpek->nu_su;
    nv = surpek->nv_su;
    tabsiz = nu*nv*sizeof(DBptr);
    if ( (tabpek=(DBptr *)v3mall(tabsiz,"DBinsert_surface")) == NULL )
      return(erpush("GM1043",""));
    ptab = tabpek;
/*
***Gå igenom de primära patcharna. Lagra eventuella geometriska
***patchar och därefter den primära patchen själv.
*/
    patpek = ptpat;

    for ( i=0; i<nu; ++i )
      {
      for ( j=0; j<nv; ++j )
        {
        switch ( patpek->styp_pat )
          {
/*
***Den primära patchen pekar direkt på en geometrisk patch.
***Lagra den geometriska patchen och notera dess GM-adress i den
***primära patchen.
*/
          case CUB_PAT:
          wrdat1(patpek->spek_c,&la,sizeof(GMPATC));
          patpek->spek_gm = la;
          wrdat1((char *)patpek,ptab,sizeof(GMPAT));
          break;

          case RAT_PAT:
          wrdat1(patpek->spek_c,&la,sizeof(GMPATR));
          patpek->spek_gm = la;
          wrdat1((char *)patpek,ptab,sizeof(GMPAT));
          break;

          case LFT_PAT:
          wrdat2(patpek->spek_c,&la,sizeof(GMPATL));
          patpek->spek_gm = la;
          wrdat1((char *)patpek,ptab,sizeof(GMPAT));
          break;

          case FAC_PAT:
          wrdat1(patpek->spek_c,&la,sizeof(GMPATF));
          patpek->spek_gm = la;
          wrdat1((char *)patpek,ptab,sizeof(GMPAT));
          break;

          case PRO_PAT:
          wrdat2(patpek->spek_c,&la,sizeof(GMPATP));
          patpek->spek_gm = la;
          wrdat1((char *)patpek,ptab,sizeof(GMPAT));
          break;

          case CON_PAT:
          wrdat1(patpek->spek_c,&la,sizeof(GMPATN));
          patpek->spek_gm = la;
          wrdat1((char *)patpek,ptab,sizeof(GMPAT));
          break;

          case P3_PAT:
          wrdat1(patpek->spek_c,&la,sizeof(GMPATP3));
          patpek->spek_gm = la;
          wrdat1((char *)patpek,ptab,sizeof(GMPAT));
          break;

          case P5_PAT:
          wrdat1(patpek->spek_c,&la,sizeof(GMPATP5));
          patpek->spek_gm = la;
          wrdat1((char *)patpek,ptab,sizeof(GMPAT));
          break;

          case P7_PAT:
          wrdat2(patpek->spek_c,&la,sizeof(GMPATP7));
          patpek->spek_gm = la;
          wrdat1((char *)patpek,ptab,sizeof(GMPAT));
          break;

          case P9_PAT:
          wrdat2(patpek->spek_c,&la,sizeof(GMPATP9));
          patpek->spek_gm = la;
          wrdat1((char *)patpek,ptab,sizeof(GMPAT));
          break;

          case P21_PAT:
          wrdat2(patpek->spek_c,&la,sizeof(GMPATP21));
          patpek->spek_gm = la;
          wrdat1((char *)patpek,ptab,sizeof(GMPAT));
          break;

          case NURB_PAT:
          gmwrnp((GMPATNU *)patpek->spek_c,&la);
          patpek->spek_gm = la;
          wrdat1((char *)patpek,ptab,sizeof(GMPAT));
          break;
/*
***Den primära patchen pekar på en NULL-patch. Ingenting
***lagras.
*/
          case NUL_PAT:
         *ptab = DBNULL;
          break;
/*
***Den primära patchen pekar på en annan primär (GMPAT) patch.
***Lagra inte denna men notera dess patchadress.
*/
          case TOP_PAT:
          spek = (GMPAT *) patpek->spek_c;
          patpek->su_pat = spek->iu_pat;
          patpek->sv_pat = spek->iv_pat;
          wrdat1((char *)patpek,ptab,sizeof(GMPAT));
          break;
          }
/*
***Nästa patch.
*/
        ++ptab;
        ++patpek;
        }
      }
/*
***Lagra patch-tabellen.
*/
    if ( tabsiz <= PAGSIZ ) wrdat1((char *)tabpek,&tabla,tabsiz);
    else                    wrdat2((char *)tabpek,&tabla,tabsiz);
    surpek->ptab_su = tabla;
    v3free(tabpek,"DBinsert_surface");
/*
***Ännu finns det ingen grafisk representation. Varken grafiska
***segment eller B-Splineyta.
*/
    for ( i=0; i< 6; ++i )
      {
      surpek->ngseg_su[i] = 0;
      surpek->pgseg_su[i] = DBNULL;
      }

    surpek->uorder_su = surpek->vorder_su = 0;
    surpek->nku_su = surpek->nkv_su = 0;
    surpek->pkvu_su = surpek->pkvv_su = surpek->pcpts_su = DBNULL;
/*
***Typ-specifika data.
*/
    surpek->hed_su.type = SURTYP;
    surpek->hed_su.vers = GMPOSTV1;
/*
***Lagra själva surf-posten. 
*/
    return(inpost((GMUNON *)surpek,idpek,lapek,sizeof(GMSUR)));
  }

/********************************************************/
/*!******************************************************/

        DBstatus DBread_surface(
        GMSUR  *surpek,
        DBptr   la)

/*      Huvudrutin för läsning av en yta.
 *
 *      In: surpek => Pekare till en GMSUR-structure.
 *          la     => Ytans adress i GM.
 *
 *      Ut: *surpek => Surf-post.
 *
 *      FV: Inget.
 *
 *      (C)microform ab 21/11/92 J. Kjellander
 *
 *      1997-03-05 GMPOSTV1, J.Kjellander
 *
 ******************************************************!*/

  {
    GMRECH *hedpek;

    hedpek = (GMRECH *)gmgadr(la);

    switch ( GMVERS(hedpek) )
      {
      case GMPOSTV1:
      V3MOME(hedpek,surpek,sizeof(GMSUR));
      break;
/*
***GMSUR0 har ingen B-spline approximation.
*/ 
      default:
      V3MOME(hedpek,surpek,sizeof(GMSUR0));
      surpek->uorder_su = surpek->vorder_su = 0;
      surpek->nku_su = surpek->nkv_su = 0;
      surpek->pkvu_su = surpek->pkvv_su = surpek->pcpts_su = DBNULL;
      break;
      }

    return(0);
  }

/********************************************************/
/*!******************************************************/

        DBstatus DBupdate_surface(
        GMSUR  *surpek,
        DBptr   la)

/*      Uppdaterar (skriver över) en yt-post.
 *
 *      In: surpek => Pekare till en GMSUR-structure.
 *          la     => Ytans adress i GM.
 *
 *      Ut: Inget.
 *
 *      FV: Inget.
 *
 *      (C)microform ab 21/11/92 J. Kjellander
 *
 *      1997-03-05 GMPOSTV1, J.Kjellander
 *
 ******************************************************!*/

  {
    GMRECH *hedpek;

    hedpek = (GMRECH *)gmgadr(la);

    switch ( GMVERS(hedpek) )
      {
      case GMPOSTV1:
      updata( (char *)surpek, la, sizeof(GMSUR));
      break;
 
      default:
      updata( (char *)surpek, la, sizeof(GMSUR0));
      break;
      }

    return(0);
  }

/********************************************************/
/*!******************************************************/

        DBstatus DBdelete_surface(DBptr la)

/*      Stryker en yt-post med patch-data och deallokerar
 *      allokerat minne.
 *
 *      In: la => Ytan:s GM-adress.
 *
 *      Ut: Inget.
 *
 *      FV:  0  => Ok.
 *
 *      (C)microform ab 26/11/92 J. Kjellander
 *
 *      22/2/93    RATSUR och LFTSUR, J. Kjellander
 *      21/3/94    Nya GMPAT, J. Kjellander
 *      1996-01-29 CON_PAT, J. Kjellander
 *      1996-07-04 Polynompatchar, J.Kjellander
 *      1997-03-05 GMPOSTV1, J.Kjellander
 *      1997-05-28 DBread_one_patch(NULL), J.Kjellander
 *      1997-05-28 DBdelete_srep_NURBS(), J.Kjellander
 *      1997-11-05 GMPATNU, J.Kjellander
 *
 ******************************************************!*/

  {
    DBptr  *tabpek,*ptab,tabla;
    DBint   nu,nv,i,j,tabsiz;
    GMSUR   sur;
    GMPAT   toppat;

/*
***Läs själva yt-posten.
*/
    DBread_surface(&sur,la);
/*
***Stryk eventuella grafiska segment.
*/
    DBdelete_srep_curves(&sur);
/*
***Stryk ev. nurbs-representation.
*/
    DBdelete_srep_NURBS(&sur);
/*
***Stryk själva yt-posten.
*/
    switch ( sur.hed_su.vers )
      {
      case GMPOSTV1:
      rldat1(la,sizeof(GMSUR));
      break;
 
      default:
      rldat1(la,sizeof(GMSUR0));
      break;
      }
/*
***Allokera minne för patch-tabellen.
*/
    nu     = sur.nu_su;
    nv     = sur.nv_su;
    tabsiz = nu*nv*sizeof(DBptr);

    if ( (tabpek=(DBptr *)v3mall(tabsiz,"DBdelete_surface")) == NULL )
      return(erpush("GM1043",""));
    ptab = tabpek;
/*
***Läs tabellen och stryk den ur GM.
*/
    tabla = sur.ptab_su;

    if ( tabsiz <= PAGSIZ )
      {
      rddat1((char *)tabpek,tabla,tabsiz);
      rldat1(tabla,tabsiz);
      }
    else
      {
      rddat2((char *)tabpek,tabla,tabsiz);
      rldat2(tabla,tabsiz);
      }
/*
***Stryk patcharna ?
*/
    for ( i=0; i<nu; ++i )
      {
      for ( j=0; j<nv; ++j )
        {
/*
***Först den primära patchen. NUL_PAT behöver inte strykas.
*/
        if ( *ptab != DBNULL )
          {
          rddat1((char *)&toppat,*ptab,sizeof(GMPAT));
          rldat1(*ptab,sizeof(GMPAT));
/*
***Sen den sekundära patchen.
*/
          switch ( toppat.styp_pat )
            {
/*
***Om den sekundära patchen är geometrisk stryker vi den.
*/
            case CUB_PAT:
            rldat1(toppat.spek_gm,sizeof(GMPATC));
            break;

            case RAT_PAT:
            rldat1(toppat.spek_gm,sizeof(GMPATR));
            break;

            case LFT_PAT:
            rldat2(toppat.spek_gm,sizeof(GMPATL));
            break;

            case FAC_PAT:
            rldat1(toppat.spek_gm,sizeof(GMPATF));
            break;

            case PRO_PAT:
            rldat2(toppat.spek_gm,sizeof(GMPATP));
            break;

            case CON_PAT:
            rldat1(toppat.spek_gm,sizeof(GMPATN));
            break;

            case P3_PAT:
            rldat1(toppat.spek_gm,sizeof(GMPATP3));
            break;

            case P5_PAT:
            rldat1(toppat.spek_gm,sizeof(GMPATP5));
            break;

            case P7_PAT:
            rldat2(toppat.spek_gm,sizeof(GMPATP7));
            break;

            case P9_PAT:
            rldat2(toppat.spek_gm,sizeof(GMPATP9));
            break;

            case P21_PAT:
            rldat2(toppat.spek_gm,sizeof(GMPATP21));
            break;

            case NURB_PAT:
            gmrlnp(toppat.spek_gm);
            rldat1(toppat.spek_gm,sizeof(GMPATNU));
            break;
            }
          }
/*
***Nästa (primära) patch.
*/
        ++ptab;
        }
      }
/*
***För säkerhets skull nollställer vi också DBread_one_patch():s
***cache så att en ny yta vars patchtabell råkar hamna
***på samma plats som den nu borttagna ytans säkert läses
***från disk vid nästa anrop till DBread_one_patch().
*/
    DBread_one_patch(NULL,NULL,0,0);
/*
***Lämna tillbaks C-minne för patchtabellen.
*/
    v3free(tabpek,"DBdelete_surface");
/*
***Slut.
*/
    return(0);
  }

/********************************************************/
/*!******************************************************/

 static DBstatus gmwrnp(
        GMPATNU *np,
        DBptr   *pla)

/*      Lagrar nurbspatch.
 *
 *      In: np  => Pekare till en GMPATNU-structure.
 *          pla => Pekare till utdata.
 *
 *      Ut: *pla = GM-pekare.
 *
 *      FV: Inget.
 *
 *      (C)microform ab 1997-11-05 J. Kjellander
 *
 ******************************************************!*/

  {
    DBint size;

/*
***Lagra först knutvektorerna.
*/
    size = np->nk_u*sizeof(DBfloat);
    if ( size <= PAGSIZ ) wrdat1((char *)np->kvec_u,&(np->pku),size);
    else                  wrdat2((char *)np->kvec_u,&(np->pku),size);

    size = np->nk_v*sizeof(DBfloat);
    if ( size <= PAGSIZ ) wrdat1((char *)np->kvec_v,&(np->pkv),size);
    else                  wrdat2((char *)np->kvec_v,&(np->pkv),size);
/*
***Och sen styrpolygonen.
*/
    size = (np->nk_u - np->order_u) *
           (np->nk_v - np->order_v) * sizeof(DBHvector);
    if ( size <= PAGSIZ ) wrdat1((char *)np->cpts,&(np->pcpts),size);
    else                  wrdat2((char *)np->cpts,&(np->pcpts),size);
/*
***Och slutligen själva patch-posten.
*/
    wrdat1((char *)np,pla,sizeof(GMPATNU));

    return(0);
  }

/********************************************************/
/*!******************************************************/

 static DBstatus gmrdnp(GMPATNU *np)

/*      Läser nurbspatch.
 *
 *      In: np  => Pekare till en delvis ifylld 
 *                 GMPATNU-structure.
 *
 *      Ut: *np = GMPATNU med C-pekare till NURBS-data.
 *
 *      FV: Inget.
 *
 *      (C)microform ab 1997-11-05 J. Kjellander
 *
 ******************************************************!*/

  {
    DBstatus status;
    DBint    size;

/*
***Allokera minne för NURBS-data.
*/
    if ( (status=DBcreate_NURBS(np)) < 0 ) return(status);
/*
***Läs knutvektorerna.
*/
    size = np->nk_u*sizeof(DBfloat);
    if ( size <= PAGSIZ ) rddat1((char *)np->kvec_u,np->pku,size);
    else                  rddat2((char *)np->kvec_u,np->pku,size);

    size = np->nk_v*sizeof(DBfloat);
    if ( size <= PAGSIZ ) rddat1((char *)np->kvec_v,np->pkv,size);
    else                  rddat2((char *)np->kvec_v,np->pkv,size);
/*
***Och sen styrpolygonen.
*/
    size = (np->nk_u - np->order_u) *
           (np->nk_v - np->order_v) * sizeof(DBHvector);
    if ( size <= PAGSIZ ) rddat1((char *)np->cpts,np->pcpts,size);
    else                  rddat2((char *)np->cpts,np->pcpts,size);

    return(0);
  }

/********************************************************/
/*!******************************************************/

 static DBstatus gmrlnp(DBptr la)

/*      Stryker nurbsdata.
 *
 *      In: la => Pekare till GMPATNU-post.
 *
 *      Ut: Inget.
 *
 *      FV: Inget.
 *
 *      (C)microform ab 1997-11-05 J. Kjellander
 *
 ******************************************************!*/

  {
    DBint   size;
    GMPATNU np;

/*
***Läs posten.
*/
    rddat1((char *)&np,la,sizeof(GMPATNU));
/*
***Stryk knutvektorerna.
*/
    size = np.nk_u*sizeof(DBfloat);
    if ( size <= PAGSIZ ) rldat1(np.pku,size);
    else                  rldat2(np.pku,size);

    size = np.nk_v*sizeof(DBfloat);
    if ( size <= PAGSIZ ) rldat1(np.pkv,size);
    else                  rldat2(np.pkv,size);
/*
***Och sen styrpolygonen.
*/
    size = (np.nk_u - np.order_u) *
           (np.nk_v - np.order_v) * sizeof(DBHvector);
    if ( size <= PAGSIZ ) rldat1(np.pcpts,size);
    else                  rldat2(np.pcpts,size);

    return(0);
  }

/********************************************************/
/*!******************************************************/

        DBstatus DBread_patches(
        GMSUR  *surpek,
        GMPAT **pptpat)

/*      Läser patch-data för alla patchar i ytan.
 *      Allokerar minne för patcharna.
 *
 *      In: surpek => Pekare till yt-post.
 *          pptpat => Pekare till en patch-pekare.
 *
 *      Ut: *pptpat = Pekare till patchdata.
 *
 *      FV: Inget.
 *
 *      Felkoder: GM1043 = malloc-fel patchtabell
 *                GM1033 = malloc-fel primära patchar
 *                GM1063 = malloc-fel sekundär patch
 *
 *      (C)microform ab 20/11/92 J. Kjellander
 *
 *      22/2/93    RATSUR och LFTSUR, J. Kjellander
 *      14/3/94    Nya GMPAT, J. Kjellander
 *      1996-01-29 CON_PAT, J. Kjellander
 *      1996-07-04 Bug, PRO_PAT, J.Kjellander
 *      1996-07-04 Polynompatchar, J.Kjellander
 *      1997-11-05 GMPATNU, J.Kjellander
 *
 ******************************************************!*/

  {
    DBptr *tabpek,*ptab,tabla;
    DBint  nu,nv,i,j,tabsiz;
    GMPAT *patpek;

/*
***Allokera minne för patch-tabellen.
*/
    nu = surpek->nu_su;
    nv = surpek->nv_su;
    tabsiz = nu*nv*sizeof(DBptr);
    if ( (tabpek=(DBptr *)v3mall(tabsiz,"DBread_patches")) == NULL )
      return(erpush("GM1043",""));
    ptab = tabpek;
/*
***Läs patch-tabellen.
*/
    tabla = surpek->ptab_su;
    if ( tabsiz <= PAGSIZ ) rddat1((char *)tabpek,tabla,tabsiz);
    else                    rddat2((char *)tabpek,tabla,tabsiz);
/*
***Allokera minne för primära patchar.
*/
    if ( (*pptpat=(GMPAT *)DBcreate_patches(TOP_PAT,nu*nv)) == NULL )
      return(erpush("GM1033",""));
    patpek = *pptpat;
/*
***Läs patcharna.
*/
    for ( i=0; i<nu; ++i )
      {
      for ( j=0; j<nv; ++j )
        {
/*
***Först den primära patchen. NUL_PAT behöver inte ens läsas
***utan skapas här.
*/
        if ( *ptab == DBNULL )
          {
          patpek->styp_pat = NUL_PAT;
          patpek->spek_c   = NULL;
          patpek->iu_pat   = (short) (i + 1);
          patpek->iv_pat   = (short) (j + 1);
          }
        else rddat1((char *)patpek,*ptab,sizeof(GMPAT));
/*
***Sen den sekundära patchen.
*/
        switch ( patpek->styp_pat )
          {
/*
***Om den sekundära patchen är geometrisk allokerar vi minne
***för den nu och läser in den.
*/
          case CUB_PAT:
          if ( (patpek->spek_c=DBcreate_patches(CUB_PAT,1)) == NULL )
            return(erpush("GM1063",""));
          rddat1(patpek->spek_c,patpek->spek_gm,sizeof(GMPATC));
          break;

          case RAT_PAT:
          if ( (patpek->spek_c=DBcreate_patches(RAT_PAT,1)) == NULL )
            return(erpush("GM1063",""));
          rddat1(patpek->spek_c,patpek->spek_gm,sizeof(GMPATR));
          break;

          case LFT_PAT:
          if ( (patpek->spek_c=DBcreate_patches(LFT_PAT,1)) == NULL )
            return(erpush("GM1063",""));
          rddat2(patpek->spek_c,patpek->spek_gm,sizeof(GMPATL));
          break;

          case FAC_PAT:
          if ( (patpek->spek_c=DBcreate_patches(FAC_PAT,1)) == NULL )
            return(erpush("GM1063",""));
          rddat1(patpek->spek_c,patpek->spek_gm,sizeof(GMPATF));
          break;

          case PRO_PAT:
          if ( (patpek->spek_c=DBcreate_patches(PRO_PAT,1)) == NULL )
            return(erpush("GM1063",""));
          rddat2(patpek->spek_c,patpek->spek_gm,sizeof(GMPATP));
          break;

          case CON_PAT:
          if ( (patpek->spek_c=DBcreate_patches(CON_PAT,1)) == NULL )
            return(erpush("GM1063",""));
          rddat1(patpek->spek_c,patpek->spek_gm,sizeof(GMPATN));
          break;

          case P3_PAT:
          if ( (patpek->spek_c=DBcreate_patches(P3_PAT,1)) == NULL )
            return(erpush("GM1063",""));
          rddat1(patpek->spek_c,patpek->spek_gm,sizeof(GMPATP3));
          break;

          case P5_PAT:
          if ( (patpek->spek_c=DBcreate_patches(P5_PAT,1)) == NULL )
            return(erpush("GM1063",""));
          rddat1(patpek->spek_c,patpek->spek_gm,sizeof(GMPATP5));
          break;

          case P7_PAT:
          if ( (patpek->spek_c=DBcreate_patches(P7_PAT,1)) == NULL )
            return(erpush("GM1063",""));
          rddat2(patpek->spek_c,patpek->spek_gm,sizeof(GMPATP7));
          break;

          case P9_PAT:
          if ( (patpek->spek_c=DBcreate_patches(P9_PAT,1)) == NULL )
            return(erpush("GM1063",""));
          rddat2(patpek->spek_c,patpek->spek_gm,sizeof(GMPATP9));
          break;

          case P21_PAT:
          if ( (patpek->spek_c=DBcreate_patches(P21_PAT,1)) == NULL )
            return(erpush("GM1063",""));
          rddat2(patpek->spek_c,patpek->spek_gm,sizeof(GMPATP21));
          break;

          case NURB_PAT:
          if ( (patpek->spek_c=DBcreate_patches(NURB_PAT,1)) == NULL )
            return(erpush("GM1053",""));
          rddat1(patpek->spek_c,patpek->spek_gm,sizeof(GMPATNU));
          if ( gmrdnp((GMPATNU *)patpek->spek_c) < 0 )
            return(erpush("GM1063",""));
          break;
/*
***Om den sekundära patchen är en topologisk patch beräknar
***vi dess C-adress utan att allokera eller läsa något.
*/
          case TOP_PAT:
          patpek->spek_c = (char *) (*pptpat +
                           (patpek->su_pat-1)*nv + patpek->sv_pat - 1);
          break;
          }
/*
***Nästa (primära) patch.
*/
        ++ptab;
        ++patpek;
        }
      }
/*
***Slut.
*/
    v3free(tabpek,"DBread_patches");

    return(0);
  }

/********************************************************/
/*!******************************************************/

        DBstatus DBread_one_patch(
        GMSUR  *surpek,
        GMPAT  *patpek,
        short   iu,
        short   iv)

/*      Läser patch-data för en enstaka patch. Lagrar
 *      sist lästa patchtabell i cache för snabb åtkomst
 *      vid upprepade acesser.
 *
 *      Vill man tömma cachen anropar man med surpek = NULL.
 *
 *      In: surpek => Pekare till yt-post eller NULL.
 *          patpek => Pekare till en patch-pekare.
 *          iu     => Patchnummer i U-riktn. 1 = Första
 *          iv     => Patchnummer i V-riktn. 1 = Första
 *
 *      Ut: *patpek = Pekare till patchdata.
 *
 *      Felkoder: GM1073 = Felaktig typ av patch
 *
 *      (C)microform ab 7/9/93 J. Kjellander
 *
 *      1/3/95     surpek = NULL, J. Kjellander
 *      17/3/95    Reentrans, J. Kjellander
 *      1996-01-29 CON_PAT, J. Kjellander
 *      1996-07-04 Polynompatchar, J.Kjellander
 *      1997-11-05 GMPATNU, J.Kjellander
 *
 ******************************************************!*/

  {
#ifdef V3_X11
extern bool wpintr();
#endif

    DBptr  *tabpek,*ptab,tabla,patla;
    DBint   nu,nv,tabsiz;
    char   *geopat;

static DBptr  otabla = DBNULL;
static DBptr  tab[500];

/*
***Om surpek == NULL handlar det bara om att tömma cachen.
*/
   if ( surpek == NULL )
     {
     otabla = DBNULL;
     return(0);
     }
/*
***På prov lägger vi in ett anrop till vänta-systemet här.
*/
#ifdef V3_X11
    wpintr();
#endif
/*
***Hur många patchar har ytan och var finns patchtabellen ?
*/
    nu     = surpek->nu_su;
    nv     = surpek->nv_su;
    tabla  = surpek->ptab_su;
/*
***Om patchtabellen finns i cachen är allt ok. Om inte
***läs in den. Om större än 500 patchar, allokera dynamisk
***area istället.
*/
    tabsiz = nu*nv*sizeof(DBptr);

    if      ( tabla == otabla )
      {
      ptab  = tab + (iu-1)*nv + iv-1;
      patla = *ptab;
      }
    else if ( nu*nv < 500 )
      { 
      if ( tabsiz <= PAGSIZ ) rddat1((char *)tab,tabla,tabsiz);
      else                    rddat2((char *)tab,tabla,tabsiz);
      ptab   = tab + (iu-1)*nv + iv-1;
      patla  = *ptab;
      otabla = tabla;
      }
    else
      {
      if ( (tabpek=(DBptr *)v3mall(tabsiz,"DBread_one_patch")) == NULL )
        return(erpush("GM1043",""));
      if ( tabsiz <= PAGSIZ ) rddat1((char *)tabpek,tabla,tabsiz);
      else                    rddat2((char *)tabpek,tabla,tabsiz);
      ptab  = tabpek + (iu-1)*nv + iv-1;
      patla = *ptab;
      v3free((char *)tabpek,"DBread_one_patch");
      }
/*
***Innan topologiska patchen läses från GM noterar vi dess
***C-pekare till geometrisk patch eftersom denna kommer att
***skrivas över. Sen läser vi och sen återställer vi rätt adress.
*/
    geopat = patpek->spek_c;
    rddat1((char *)patpek,patla,sizeof(GMPAT));
    patpek->spek_c = geopat;
/*
***Nu kan vi läsa även den geometriska patchen.
*/
    switch ( patpek->styp_pat )
      {
      case CUB_PAT:
      rddat1(patpek->spek_c,patpek->spek_gm,sizeof(GMPATC));
      break;

      case RAT_PAT:
      rddat1(patpek->spek_c,patpek->spek_gm,sizeof(GMPATR));
      break;

      case LFT_PAT:
      rddat2(patpek->spek_c,patpek->spek_gm,sizeof(GMPATL));
      break;

      case FAC_PAT:
      rddat1(patpek->spek_c,patpek->spek_gm,sizeof(GMPATF));
      break;

      case PRO_PAT:
      rddat2(patpek->spek_c,patpek->spek_gm,sizeof(GMPATP));
      break;

      case CON_PAT:
      rddat1(patpek->spek_c,patpek->spek_gm,sizeof(GMPATN));
      break;

      case P3_PAT:
      rddat1(patpek->spek_c,patpek->spek_gm,sizeof(GMPATP3));
      break;

      case P5_PAT:
      rddat1(patpek->spek_c,patpek->spek_gm,sizeof(GMPATP5));
      break;

      case P7_PAT:
      rddat2(patpek->spek_c,patpek->spek_gm,sizeof(GMPATP7));
      break;

      case P9_PAT:
      rddat2(patpek->spek_c,patpek->spek_gm,sizeof(GMPATP9));
      break;

      case P21_PAT:
      rddat2(patpek->spek_c,patpek->spek_gm,sizeof(GMPATP21));
      break;

      case TOP_PAT:
      rddat1(patpek->spek_c,patpek->spek_gm,sizeof(GMPAT));
      break;

      default:
      return(erpush("GM1073",""));
      }
    return(0);
  }

/********************************************************/
/*!******************************************************/

        char *DBcreate_patches(
        DBint typ,
        DBint antal)

/*      Allokerar plats i primärminne för patch-data.
 *
 *      In: typ   = Typ av patch.
 *          antal = Antal patchar totalt nu*nv.
 *
 *      Ut: Inget.
 *
 *      FV:   NULL = Kan ej allokera minne.
 *          > NULL = C-adress till ledig minnesarea.
 *
 *      (C)microform ab 20/11/92 J. Kjellander
 *
 *      17/3/94    GMPAT, J. Kjellander
 *      1996-01-29 GMPATN, J. Kjellander
 *      1996-07-04 Polynompatchar, J.Kjellander
 *      1997-05-05 GMPATNU, J.Kjellander
 *
 ******************************************************!*/

  {
    char *ptr;
    DBint nbytes;

/*
***Vilken typ av patchar är det ?
*/
    switch ( typ )
      {
      case CUB_PAT:  nbytes = antal*sizeof(GMPATC);   break;
      case RAT_PAT:  nbytes = antal*sizeof(GMPATR);   break;
      case LFT_PAT:  nbytes = antal*sizeof(GMPATL);   break;
      case FAC_PAT:  nbytes = antal*sizeof(GMPATF);   break;
      case PRO_PAT:  nbytes = antal*sizeof(GMPATP);   break;
      case CON_PAT:  nbytes = antal*sizeof(GMPATN);   break;
      case P3_PAT:   nbytes = antal*sizeof(GMPATP3);  break;
      case P5_PAT:   nbytes = antal*sizeof(GMPATP5);  break;
      case P7_PAT:   nbytes = antal*sizeof(GMPATP7);  break;
      case P9_PAT:   nbytes = antal*sizeof(GMPATP9);  break;
      case P21_PAT:  nbytes = antal*sizeof(GMPATP21); break;
      case NURB_PAT: nbytes = antal*sizeof(GMPATNU);  break;
      case TOP_PAT:  nbytes = antal*sizeof(GMPAT);    break;
      default: return(NULL);
      }
/*
***Allokera minne.
*/
    if ( (ptr=v3mall(nbytes,"DBcreate_patches")) == NULL ) return(NULL);
/*
***Slut.
*/
    return(ptr);
  }

/********************************************************/
/*!******************************************************/

        DBstatus DBcreate_NURBS(GMPATNU *patpek)

/*      Allokerar minne för NURBS-data i en GMPATNU.
 *
 *      In: patpek => Pekare till delvis ifylld GMPATNU.
 *
 *      Ut: Inget.
 *
 *      FV:  0 = Ok.
 *          -2 = Kan ej allokera.
 *
 *      (C)microform ab 1997-05-05 J. Kjellander
 *
 ******************************************************!*/

  {
   unsigned size;

/*
***Allokera minne för knutpunkter.
*/
   size = patpek->nk_u*sizeof(DBfloat);
   if ( (patpek->kvec_u=(DBfloat *)v3mall(size,"DBcreate_NURBS")) == NULL )
     return(-2);
  
   size = patpek->nk_v*sizeof(DBfloat);
   if ( (patpek->kvec_v=(DBfloat *)v3mall(size,"DBcreate_NURBS")) == NULL )
     return(-2);
/*
***Samma för kontrollpunkter.
*/
   size = (patpek->nk_u - patpek->order_u) *
          (patpek->nk_v - patpek->order_v) *  sizeof(DBHvector);

   if ( (patpek->cpts=(DBHvector *)v3mall(size,"DBcreate_NURBS")) == NULL )
     return(-2);

    return(0);
  }

/********************************************************/
/*!******************************************************/

        DBstatus DBfree_patches(
        GMSUR *surpek,
        GMPAT *patpek)

/*      Återlämnar C-minne allokerat för patchar.
 *
 *      In: surpek => Pekare till yta.
 *          patpek => Pekare till patchar.
 *
 *      Ut: Inget.
 *
 *      FV: 0 = Ok.
 *
 *      (C)microform ab 20/11/92 J. Kjellander
 *
 *      21/3/94    Nya GMPAT, J. Kjellandert
 *      1996-01-29 GMPATN, J. Kjellander
 *      1996-07-04 Polynompatchar, J.Kjellander
 *      1997-05-05 GMPATNU, J.Kjellander
 *
 ******************************************************!*/

  {
    DBint    i,j;
    GMPAT   *ppat;
    GMPATNU *nurbpat;

/*
***Initiering.
*/
    ppat = patpek;
/*
***Deallokera minne för alla geometriska patchar..
***C-rutinen free() är en void och man kan inte få
***reda på om det gick bra eller inte.
*/
    for ( i=0; i<surpek->nu_su; ++i )
      {
      for ( j=0; j<surpek->nv_su; ++j )
        {
        switch ( ppat->styp_pat )
          {
          case CUB_PAT:
          case RAT_PAT:
          case LFT_PAT:
          case FAC_PAT:
          case PRO_PAT:
          case CON_PAT:
          case P3_PAT:
          case P5_PAT:
          case P7_PAT:
          case P9_PAT:
          case P21_PAT:
          v3free(ppat->spek_c,"DBfree_patches");
          break;

          case NURB_PAT:
          nurbpat = (GMPATNU *)ppat->spek_c;
          v3free((char *)nurbpat->kvec_u,"DBfree_patches");
          v3free((char *)nurbpat->kvec_v,"DBfree_patches");
          v3free((char *)nurbpat->cpts,"DBfree_patches");
          v3free((char *)nurbpat,"DBfree_patches");
          break;
          }
        ++ppat;
        }
      }
/*
***Deallokera minne för dom topologiska patcharna.
*/
    v3free((char *)patpek,"DBfree_patches");

    return(0);
  }

/********************************************************/
/*!******************************************************/

        DBstatus DBadd_srep_curves(
        GMSUR  *surpek,
        GMSEG  *sptarr[])

/*      Lagrar en ytas grafiska segment.
 *
 *      In: surpek => Pekare till en GMSUR-structure.
 *          sptarr => Pekare till segment.
 *
 *      Ut: Inget.
 *
 *      FV: Inget.
 *
 *      (C)microform ab 21/11/92 J. Kjellander
 *
 ******************************************************!*/

  {

    if ( surpek->ngseg_su[0] > 0 )
      surpek->pgseg_su[0] = wrgseg(surpek->ngseg_su[0],sptarr[0]);
    else surpek->pgseg_su[0] = DBNULL;

    if ( surpek->ngseg_su[1] > 0 )
      surpek->pgseg_su[1] = wrgseg(surpek->ngseg_su[1],sptarr[1]);
    else surpek->pgseg_su[1] = DBNULL;

    if ( surpek->ngseg_su[2] > 0 )
      surpek->pgseg_su[2] = wrgseg(surpek->ngseg_su[2],sptarr[2]);
    else surpek->pgseg_su[2] = DBNULL;

    if ( surpek->ngseg_su[3] > 0 )
      surpek->pgseg_su[3] = wrgseg(surpek->ngseg_su[3],sptarr[3]);
    else surpek->pgseg_su[3] = DBNULL;

    if ( surpek->ngseg_su[4] > 0 )
      surpek->pgseg_su[4] = wrgseg(surpek->ngseg_su[4],sptarr[4]);
    else surpek->pgseg_su[4] = DBNULL;

    if ( surpek->ngseg_su[5] > 0 )
      surpek->pgseg_su[5] = wrgseg(surpek->ngseg_su[5],sptarr[5]);
    else surpek->pgseg_su[5] = DBNULL;

    return(0);
  }

/********************************************************/
/*!******************************************************/

        DBstatus DBread_srep_curves(
        GMSUR  *surpek,
        GMSEG  *sptarr[])

/*      Läser en ytas grafiska segment.
 *
 *      In: surpek => Pekare till en GMSUR-structure.
 *          sptarr => Pekare till utdata.
 *
 *      Ut: *sptarrÄÅ => Pekare till segment.
 *
 *      FV: Inget.
 *
 *      (C)microform ab 21/11/92 J. Kjellander
 *
 ******************************************************!*/

  {
/*
***Läs segmentdata för de 6 "kurvorna" och returnera C-pekare.
*/
    if ( surpek->pgseg_su[0] > 0 )
      sptarr[0] = rdgseg(surpek->ngseg_su[0],surpek->pgseg_su[0]);
    else
      sptarr[0] = NULL;

    if ( surpek->pgseg_su[1] > 0 )
      sptarr[1] = rdgseg(surpek->ngseg_su[1],surpek->pgseg_su[1]);
    else
      sptarr[1] = NULL;

    if ( surpek->pgseg_su[2] > 0 )
      sptarr[2] = rdgseg(surpek->ngseg_su[2],surpek->pgseg_su[2]);
    else
      sptarr[2] = NULL;

    if ( surpek->pgseg_su[3] > 0 )
      sptarr[3] = rdgseg(surpek->ngseg_su[3],surpek->pgseg_su[3]);
    else
      sptarr[3] = NULL;

    if ( surpek->pgseg_su[4] > 0 )
      sptarr[4] = rdgseg(surpek->ngseg_su[4],surpek->pgseg_su[4]);
    else
      sptarr[4] = NULL;

    if ( surpek->pgseg_su[5] > 0 )
      sptarr[5] = rdgseg(surpek->ngseg_su[5],surpek->pgseg_su[5]);
    else
      sptarr[5] = NULL;

    return(0);
  }

/********************************************************/
/*!******************************************************/

        DBstatus DBdelete_srep_curves(GMSUR  *surpek)

/*      Suddar en ytas grafiska segment.
 *
 *      In: surpek => Pekare till en GMSUR-structure.
 *
 *      Ut: Inget.
 *
 *      FV: 0
 *
 *      (C)microform ab 14/3/94 J. Kjellander
 *
 ******************************************************!*/

  {
/*
***Läs segmentdata för de 6 "kurvorna" och returnera C-pekare.
*/
    if ( surpek->pgseg_su[0] > 0 )
      dlgseg(surpek->ngseg_su[0],surpek->pgseg_su[0]);

    if ( surpek->pgseg_su[1] > 0 )
      dlgseg(surpek->ngseg_su[1],surpek->pgseg_su[1]);

    if ( surpek->pgseg_su[2] > 0 )
      dlgseg(surpek->ngseg_su[2],surpek->pgseg_su[2]);

    if ( surpek->pgseg_su[3] > 0 )
      dlgseg(surpek->ngseg_su[3],surpek->pgseg_su[3]);

    if ( surpek->pgseg_su[4] > 0 )
      dlgseg(surpek->ngseg_su[4],surpek->pgseg_su[4]);

    if ( surpek->pgseg_su[5] > 0 )
      dlgseg(surpek->ngseg_su[5],surpek->pgseg_su[5]);

    return(0);
  }

/********************************************************/
/*!******************************************************/

        DBstatus DBfree_srep_curves(GMSEG *sptarr[])

/*      Återlämnar minne för grafiska segment.
 *
 *      In: sptarr = 6 GMSEG-pekare.
 *
 *      Ut: Inget.
 *
 *      FV: 0 = Ok.
 *
 *      (C)microform ab 31/1/94 J. Kjellander
 *
 ******************************************************!*/

  {
    if ( sptarr[0] != NULL ) v3free((char *)sptarr[0],"DBfree_srep_curves");
    if ( sptarr[1] != NULL ) v3free((char *)sptarr[1],"DBfree_srep_curves");
    if ( sptarr[2] != NULL ) v3free((char *)sptarr[2],"DBfree_srep_curves");
    if ( sptarr[3] != NULL ) v3free((char *)sptarr[3],"DBfree_srep_curves");
    if ( sptarr[4] != NULL ) v3free((char *)sptarr[4],"DBfree_srep_curves");
    if ( sptarr[5] != NULL ) v3free((char *)sptarr[5],"DBfree_srep_curves");

    return(0);
  }

/********************************************************/
/*!******************************************************/

        DBstatus DBadd_srep_NURBS(
        GMSUR   *surpek,
        GLfloat *kvu,
        GLfloat *kvv,
        GLfloat *cpts)

/*      Lagrar en ytas B-splineapproximation.
 *
 *      In: kvu,kvv => Nodvektorerna
 *          cpts    => Kontrollpunkterna.
 *
 *      Ut: Inget.
 *
 *      FV: Inget.
 *
 *      (C)microform ab 1997-03-05 J. Kjellander
 *
 ******************************************************!*/

  {
   DBint size;

/*
***Kolla att data finns att lagra.
*/
   if ( surpek->nku_su     == 0  ||
        surpek->nkv_su     == 0  ||
        surpek->uorder_su  == 0  ||
        surpek->vorder_su  == 0 )
     {
     surpek->pkvu_su  = DBNULL;
     surpek->pkvv_su  = DBNULL;
     surpek->pcpts_su = DBNULL;
     return(-2);
     }
/*
***Lagra nodvektorerna.
*/
   size = surpek->nku_su*sizeof(GLfloat);
   if ( size < PAGSIZ ) wrdat1((char *)kvu,&surpek->pkvu_su,size);
   else                 wrdat2((char *)kvu,&surpek->pkvu_su,size);

   size = surpek->nkv_su*sizeof(GLfloat);
   if ( size < PAGSIZ ) wrdat1((char *)kvv,&surpek->pkvv_su,size);
   else                 wrdat2((char *)kvv,&surpek->pkvv_su,size);
/*
***Lagra kontrollpunkterna.
*/
   size = (surpek->nku_su - surpek->uorder_su) *
          (surpek->nkv_su - surpek->vorder_su) * 3 * sizeof(GLfloat);

   if ( size < PAGSIZ ) wrdat1((char *)cpts,&surpek->pcpts_su,size);
   else                 wrdat2((char *)cpts,&surpek->pcpts_su,size);

   return(0);
  }

/********************************************************/
/*!******************************************************/

        DBstatus  DBread_srep_NURBS(
        GMSUR    *surpek,
        GLfloat **kvu,
        GLfloat **kvv,
        GLfloat **cpts)

/*      Läser en ytas B-splineapproximation. C-minne
 *      allokeras och pekare returneras.
 *
 *      In: surpek => Pekare till en GMSUR-structure.
 *          kvu    => Nodvektor U
 *          kvv    => Nodvektor V
 *          cpts   => Kontrollpunkter
 *
 *      Ut: *kvu  => Pekare till U-noder
 *          *kvv  => Pekare till V-noder
 *          *cpts => Pekare till Kontrollpunkter
 *
 *      FV: Inget.
 *
 *      (C)microform ab 1997-03-05 J. Kjellander
 *
 ******************************************************!*/

  {
   unsigned size;

/*
***Kolla att data finns att läsa.
*/
   if ( surpek->nku_su     == 0  ||
        surpek->nkv_su     == 0  ||
        surpek->uorder_su  == 0  ||
        surpek->vorder_su  == 0  ||
        surpek->pkvu_su    == DBNULL  ||
        surpek->pkvv_su    == DBNULL  ||
        surpek->pcpts_su   == DBNULL ) return(-2);
/*
***Allokera minne för noder och läs.
*/
   size = surpek->nku_su*sizeof(GLfloat);
   if ( (*kvu=(GLfloat *)v3mall(size,"DBread_srep_NURBS")) == NULL ) return(-2);
   if ( size < PAGSIZ ) rddat1((char *)*kvu,surpek->pkvu_su,size);
   else                 rddat2((char *)*kvu,surpek->pkvu_su,size);
  
   size = surpek->nkv_su*sizeof(GLfloat);
   if ( (*kvv=(GLfloat *)v3mall(size,"DBread_srep_NURBS")) == NULL ) return(-2);
   if ( size < PAGSIZ ) rddat1((char *)*kvv,surpek->pkvv_su,size);
   else                 rddat2((char *)*kvv,surpek->pkvv_su,size);
/*
***Samma för kontrollpunkter.
*/
   size = (surpek->nku_su - surpek->uorder_su) *
          (surpek->nkv_su - surpek->vorder_su) * 3 * sizeof(GLfloat);

   if ( (*cpts=(GLfloat *)v3mall(size,"DBread_srep_NURBS")) == NULL ) return(-2);

   if ( size < PAGSIZ ) rddat1((char *)*cpts,surpek->pcpts_su,size);
   else                 rddat2((char *)*cpts,surpek->pcpts_su,size);

   return(0);
  }

/********************************************************/
/*!******************************************************/

        DBstatus DBdelete_srep_NURBS(GMSUR *surpek)

/*      Suddar en ytas B-splineapproximation.
 *
 *      In: surpek => Pekare till en GMSUR-structure.
 *
 *      Ut: Inget.
 *
 *      FV: 0
 *
 *      (C)microform ab 1997-03-05 J. Kjellander
 *
 ******************************************************!*/

  {
   DBint size;

/*
***Kolla att data finns att sudda.
*/
   if ( surpek->nku_su     == 0  ||
        surpek->nkv_su     == 0  ||
        surpek->uorder_su  == 0  ||
        surpek->vorder_su  == 0  ||
        surpek->pkvu_su    == DBNULL  ||
        surpek->pkvv_su    == DBNULL  ||
        surpek->pcpts_su   == DBNULL ) return(-2);
/*
***Sudda nodvektorerna.
*/
   size = surpek->nku_su*sizeof(GLfloat);
   if ( size < PAGSIZ ) rldat1(surpek->pkvu_su,size);
   else                 rldat2(surpek->pkvu_su,size);

   size = surpek->nkv_su*sizeof(GLfloat);
   if ( size < PAGSIZ ) rldat1(surpek->pkvv_su,size);
   else                 rldat2(surpek->pkvv_su,size);
/*
***Och kontrollpunkterna.
*/
   size = (surpek->nku_su - surpek->uorder_su) *
          (surpek->nkv_su - surpek->vorder_su) * 3 * sizeof(GLfloat);

   if ( size < PAGSIZ ) rldat1(surpek->pcpts_su,size);
   else                 rldat2(surpek->pcpts_su,size);

    return(0);
  }

/********************************************************/
/*!******************************************************/

        DBstatus DBfree_srep_NURBS(
        GLfloat *kvu,
        GLfloat *kvv,
        GLfloat *cpts)

/*      Återlämnar minne för B-splineapproximation.
 *
 *      In: kvu,kvv = Minne för nodvektorer.
 *          cpts    = Minne för kontrollpunkter.
 *
 *      Ut: Inget.
 *
 *      FV: 0 = Ok.
 *
 *      (C)microform ab 1997-03-05 J. Kjellander
 *
 ******************************************************!*/

  {
    if ( kvu != NULL ) v3free((char *)kvu,"DBfree_srep_NURBS");
    if ( kvv != NULL ) v3free((char *)kvv,"DBfree_srep_NURBS");
    if ( cpts != NULL ) v3free((char *)cpts,"DBfree_srep_NURBS");

    return(0);
  }

/********************************************************/
/*!******************************************************/

        static DBptr wrgseg(
        short  nseg,
        GMSEG  segdat[])

/*      Lagrar nseg stycken GMSEG och returnerar GM-adress.
 *
 *      In: segdat => Pekare till segment.
 *          nseg   => Antal segment.
 *
 *      Ut: Inget.
 *
 *      FV:  > 0 => GM-adress.
 *           = 0 => Kan ej lagra.
 *
 *      (C)microform ab 31/1/94 J. Kjellander
 *
 *      15/3/95 Bugfix, J. Kjellander
 *
 ******************************************************!*/

  {
    DBint  i;
    DBptr  la;

/*
***Lagra segmenten och länka ihop dom.
*/
    la = 0;

    for ( i=nseg; i > 0; --i)
      {
      (segdat+i-1)->nxt_seg = la;
      if ( wrdat1((char *)&segdat[i-1],&la,sizeof(GMSEG)) < 0 ) return(0);
      }

  return(la);
  }

/********************************************************/
/*!******************************************************/

        static GMSEG *rdgseg(
        short  nseg,
        DBptr  la)

/*      Läser nseg stycken GMSEG och returnerar C-adress.
 *
 *      In: nseg   => Antal segment.
 *          la     => Segmentens GM-adress.
 *
 *      Ut: Inget.
 *
 *      FV:  > 0 => Giltig C-adress.
 *           = 0 => Fel från DBcreate_segments(), dvs. malloc().
 *
 *      (C)microform ab 31/1/94 J. Kjellander
 *
 ******************************************************!*/

  {
    DBint  i;
    DBptr  la_seg;
    GMSEG *segpek,*ptr_seg;

/*
***Allokera minne.
*/
    if ( (segpek=DBcreate_segments((DBint)nseg)) == NULL ) return(NULL);
/*
***Läs segment.
*/
    la_seg  = la;
    ptr_seg = segpek;

    for ( i=0; i < nseg; ++i)
      {
      rddat1((char *)ptr_seg,la_seg,sizeof(GMSEG));
      la_seg = ptr_seg->nxt_seg;
      ++ptr_seg;
      }

    return(segpek);
  }

/********************************************************/
/*!******************************************************/

        static DBstatus dlgseg(
        short  nseg,
        DBptr  la)

/*      Dödar nseg stycken GMSEG vid la.
 *
 *      In: nseg   => Antal segment.
 *          la     => Segmentens GM-adress.
 *
 *      Ut: Inget.
 *
 *      FV:  0
 *
 *      (C)microform ab 14/3/94 J. Kjellander
 *
 ******************************************************!*/

  {
    DBint i;
    DBptr la_seg;
    GMSEG seg;

    la_seg = la;

    for ( i=0; i<nseg; ++i)
      {
      rddat1((char *)&seg,la_seg,sizeof(GMSEG));
      rldat1(la_seg,sizeof(GMSEG));
      la_seg = seg.nxt_seg;
      }

    return(0);
  }

/********************************************************/

Generated by  Doxygen 1.6.0   Back to index