/* --------------------------------------------------------------------  */
/*                          CALCULIX                                     */
/*                   - GRAPHICAL INTERFACE -                             */
/*                                                                       */
/*     A 3-dimensional pre- and post-processor for finite elements       */
/*              Copyright (C) 1996 Klaus Wittig                          */
/*                                                                       */
/*     This program is free software; you can redistribute it and/or     */
/*     modify it under the terms of the GNU General Public License as    */
/*     published by the Free Software Foundation; version 2 of           */
/*     the License.                                                      */
/*                                                                       */
/*     This program 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 General Public License for more details.                      */
/*                                                                       */
/*     You should have received a copy of the GNU General Public License */
/*     along with this program; if not, write to the Free Software       */
/*     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.         */
/* --------------------------------------------------------------------  */

/* TO DO
MESHOPT_ANGLE is not working good enough. after the optimization elem-edges might cross. all element edges must be regarded in future.
*/

#include <cgx.h>
#include <sys/dir.h>
#include <xwd.h>


#define TEST 0

/* choose the optimization-steps for the mesher */
#define MESHOPT_LENGTH 1
#define MESHOPT_ANGLE  0

extern GLfloat entity_r[SET_COLS];                     /* predefined colors of entities */
extern GLfloat entity_g[SET_COLS];                     /* predefined colors of entities */
extern GLfloat entity_b[SET_COLS];                     /* predefined colors of entities */
extern unsigned char  datin[MAX_LINE_LENGTH];         /* Input-data-file */
extern unsigned char  buffer[MAX_LINE_LENGTH];
extern int   offset, maxIndex;                        /* offset+steps-1 = maxIndex */
extern int   basCol[3];                     /* color indexes due to basic colormap */
extern int   width_ini, height_ini; /* Grafig-Fensterbreite/hoehe */
extern int   width_menu, height_menu;
extern int   w0, w1, w_index, w_rgb, activWindow;
extern int   width_w0, height_w0;
extern int   width_w1, height_w1;
extern int   MouseMode;                                   /* status maustasten */
extern double dtx, dty, dtz, drx, dry, drz, ds;                 /* Verschiebungen */
extern double vmem[4];                                     /* kor. bis auswahl eines neuen drehpkts */
extern double anim_faktor;                            /* Scalierung der Amplitude */
extern unsigned char  drawMode;               /* protokoliert drawFunktion (Load=1,Light=2,Animate=3,preprocessor=4, vector=5)*/
extern   double lmodel_twoside[1];
extern GLint   gl_max_eval_order;                         /* max order of NURBS */
extern GLdouble R[4][4];                                   /* Rotationsmatrix */
extern unsigned char  surfFlag;                /* zeichne nur Oberflaechenelemente (1), sonst (0)*/
extern unsigned char  modelEdgeFlag;                /* zeichne mit Modell-Ecken (1), sonst (0)*/
extern unsigned char  elemEdgeFlag;                 /* zeichne mit Surface Ecken (1), sonst (0)*/
extern unsigned char  frameFlag;                   /* mit (1) oder ohne Rahmen um das Grafikfenster */
extern unsigned char  filenamFlag;                   /* mit (1) oder ohne filename im Menufenster */
extern unsigned char  textFlag;                   /* mit (1) oder ohne text im Menufenster */
extern unsigned char  printFlag;                     /* printf 1:on 0:off */
extern unsigned char  cullFlag;                     /* (1) enable Culling */
extern unsigned char  frameFlag;               /* mit (1) oder ohne Rahmen um das Grafigfenster */
extern unsigned char  scalaFlag;                 /* mit (1) oder ohne scala und wertetexte */ 
extern unsigned char  addDispFlag;                    /* 0: original node-coordinates, 1: node-coordinates+displacements */
extern double dx ,dy;                                      /* Mauskoordinaten */
extern int   steps;                          /* Schrittweite der Farbscala */
extern double gtol;
extern int     ddiv;
extern double     dbias;
extern unsigned char  picture_text[MAX_LINE_LENGTH], datin[MAX_LINE_LENGTH];
extern double v_scale;                                    /* scaling-factor for the vectors in the vector-plot */
extern unsigned char  psviewer[MAX_LINE_LENGTH];

extern unsigned char  delPntFlag;                    /* 1: deleted points exists */
extern unsigned char  delLineFlag;                   /* 1: deleted lines exists */
extern unsigned char  delLcmbFlag;                   /* 1: deleted lcmbs exists */
extern unsigned char  delSurfFlag;                   /* 1: deleted surfs exists */
extern unsigned char  delBodyFlag;                   /* 1: deleted bodys exists */
extern unsigned char  delNursFlag;
extern unsigned char  delSetFlag;                  /* 1: deleted sets exists */
extern unsigned char  movieFlag;                     /* >0: save sequence of gif pictures */
extern unsigned char  stopFlag;                      /* stop/start animation */

extern int     num_olc;          /* nr-of-original-loadcases (lc from input-file) */
extern int     elemMat[99];      /*  Material Numbers, Number of Materials stored in elemMat[0]  */

/* for rgb mode */
extern Colours   *colRgb;

/* for index mode */
extern int       *colNr;

extern Scale     scale[1];
extern double     *value_n;
extern Elements  *e_enqire;     /* elem-array by elem-number instead of elem[index]... */
extern Summen    anz[1];
extern Edges     *edge;
extern Nodes     *node;
extern Nodes     *n_anim;
extern Datasets *lcase;
extern Faces     *face;
extern NodeBlocks *nBlock;
extern BGpicture *bgpicture;

extern Meshp meshp;

extern Alias     *alias;
extern Sets      *set;
extern Materials *material; 
extern Psets     *pset;
extern Points    *point;
extern Lines     *line;
extern Lcmb      *lcmb;
extern Gsur      *surf;
extern Gbod      *body;
extern Nurbl     *nurbl;
extern Nurbs     *nurbs;
extern Materials *material; 
extern Amplitudes *amplitude; 
extern SumGeo    anzGeo[1];
extern SumAsci   sumAsci[1];

extern int     num_onodmax;          /* max-node-nr-of-original-nodes (nodes from input-file) */
extern int       num_onod;          /* nr-of-original-nodes (nodes from input-file) */
extern int       num_olc;

/* nr of hardcopies */
extern int psNr, tgaNr, gifNr, pngNr;

/* additional entities */
extern OpenSets   openSets[1];
extern SpecialSet specialset[1];

Lchar     lchar[1]={{'0','0','P','L','C','A','B','Q','N','S'}};      /* first letter in the entity names */




/* returns node-Index if known, or -(Index+10) of a unused node or if none is unused -1  */
int getNodNr(Summen *anz, Nodes *node, int nodnr )
{
  int pfree;

  if(nodnr>anz->nmax) return(-1);
  if(node[nodnr].indx>anz->n) return(-1);

  if( node[node[nodnr].indx].nr == nodnr )
  {
    /* unused node ?  */
    if( node[nodnr].pflag == 2) return(pfree=-node[nodnr].indx-10);
    else return(node[nodnr].indx);
  }
  return(-1);
}



/* returns alias-Index if known, or if not -1  */
int getAliasNr(unsigned char *name)
{
  static int i, n, length, pfree, sum;

  if(!anzGeo->alias) return(-1);

  i=length=sum=0; 
  pfree=-1;

  while(name[length]!=(unsigned char)NULL) { sum+=name[length++]*(++i); }

  if(sum<=sumAsci->max_suma)
  {
   for (i=0; i<sumAsci->anza[sum]; i++)
   {
    if(( alias[sumAsci->aindx[sum][i]].name != (unsigned char *)NULL ) && (strlen(alias[sumAsci->aindx[sum][i]].name) == length))
    { 
      n=length-1;
      while(alias[sumAsci->aindx[sum][i]].name[n]==name[n])
      {
        if(!n--)
        {
          return(sumAsci->aindx[sum][i]);
	}
      }
      /*
      printf(" name:%s nam:%s indx:%d\n"
      , name, alias[sumAsci->pindx[sum][i]].name, sumAsci->aindx[sum][i]);
      */
    }
   }
  }
  else
  {
    if(printFlag) printf(" WARNING alias:%s not found in hash-table\n", name);
     for (i=0; i<anzGeo->alias; i++) if( alias[i].name != (unsigned char *)NULL )
      if((compare( alias[i].name, name, length)==length) && (sword( alias[i].name, buffer)==length))
        return(i);
  }
  return(pfree);
}


/* returns pnt-Index if known, or -(Index+10) of a deleted pnt or if none is deleted -1  */
int getPntNr(unsigned char *name)
{
  static int i, n, length, pfree, sum;

  if(!anzGeo->p) return(-1);

  i=length=sum=0; 
  pfree=-1;

  while(name[length]!=(unsigned char)NULL) { sum+=name[length++]*(++i); }
  
  /* printf ("in getPntNr name:|%s| sum:%d anzp:%d\n", name, sum, sumAsci->max_sump); */
  
  if(sum<=sumAsci->max_sump)
  {
   for (i=0; i<sumAsci->anzp[sum]; i++)
   {
    if(( point[sumAsci->pindx[sum][i]].name != (unsigned char *)NULL ) && (strlen(point[sumAsci->pindx[sum][i]].name) == length))
    { 
      n=length-1;
      while(point[sumAsci->pindx[sum][i]].name[n]==name[n])
      {
        if(!n--)
        {
          return(sumAsci->pindx[sum][i]);
	}
      }
      /*
      printf(" name:%s nam:%s indx:%d\n"
      , name, point[sumAsci->pindx[sum][i]].name, sumAsci->pindx[sum][i]);
      */
    }
   }
  }
  else 
  {
    if(printFlag) printf(" WARNING point:%s not found in hash-table\n", name);
    for (i=0; i<anzGeo->p; i++) if( point[i].name != (unsigned char *)NULL )
      if((compare( point[i].name, name, length)==length) && (sword( point[i].name, buffer)==length))
        return(i);
  }

  /* if not found  look for free cells */
  if (delPntFlag)
  for (i=0; i<anzGeo->p; i++)
  {
    /* do we have a "deleted" point for use?  */
    if( point[i].name == (unsigned char *)NULL ) 
    {
      pfree=-i-10;
      return(pfree);
    }
  }
  delPntFlag=0; /* only if "deleted" was no more found */
  return(pfree);
}


/* returns line-Index if known, or -(Index+10) of a deleted line or if none is deleted -1  */
int getLineNr(unsigned char *name)
{
  static int  i, n, length, pfree, sum;

  if(!anzGeo->l) return(-1);

  i=length=sum=0;
  pfree=-1;

  while(name[length]!=(unsigned char)NULL) { sum+=name[length++]*(++i); }
  /*
  printf ("in getLineNr anzl[%d]: %d\n", sum, sumAsci->anzl[sum]);
  */
  if(sum<=sumAsci->max_suml)
  {
   for (i=0; i<sumAsci->anzl[sum]; i++)
   {
    if(( line[sumAsci->lindx[sum][i]].name != (unsigned char *)NULL ) && (strlen(line[sumAsci->lindx[sum][i]].name) == length))
    { 
      n=length-1;
      while(line[sumAsci->lindx[sum][i]].name[n]==name[n])
      {
        if(!n--)
        {
          return(sumAsci->lindx[sum][i]);
	}
      }
      /*
      printf(" name:%s nam:%s indx:%d\n"
      , name, line[sumAsci->lindx[sum][i]].name, sumAsci->lindx[sum][i]);
      */
    }   
   } 
  }
  else
  {
    if(printFlag) printf(" WARNING line:%s not found in hash-table\n", name);
    for (i=0; i<anzGeo->l; i++)
    {
      if( line[i].name != (unsigned char *)NULL )
      {
        if((compare( line[i].name, name, length)==length) && (sword( line[i].name, buffer)==length))
          return(i);
      }
    }
  }

  /* if not found look for free cells */
  if (delLineFlag)
  for (i=0; i<anzGeo->l; i++)
  {
    /* do we have a "deleted" line for use?  */
    if( line[i].name == (unsigned char *)NULL ) 
    {
      pfree=-i-10;
      return(pfree);
    }
  } 
  delLineFlag=0;
  return(pfree);
}


/* returns line-Index if known, or -(Index+10) of a deleted line or if none is deleted -1  */
int getLcmbNr(unsigned char *name)
{
  static int  i, n, length, pfree, sum;

  if(!anzGeo->c) return(-1);

  i=length=sum=0;
  pfree=-1;

  while(name[length]!=(unsigned char)NULL) { sum+=name[length++]*(++i); }
  
  /* printf ("in getLcmbNr sum:%d max_sumc:%d anzGeo->c:%d\n", sum, sumAsci->max_sumc, anzGeo->c); */
  
  if(sum<=sumAsci->max_sumc)
  {
   /* printf ("in getLcmbNr anzc[%d]:%d \n", sum, sumAsci->anzc[sum]); */
   for (i=0; i<sumAsci->anzc[sum]; i++)
   {
    if(( lcmb[sumAsci->cindx[sum][i]].name != (unsigned char *)NULL ) && (strlen(lcmb[sumAsci->cindx[sum][i]].name) == length))
    { 
      n=length-1;
      while(lcmb[sumAsci->cindx[sum][i]].name[n]==name[n])
      {
        if(!n--)
        {
          return(sumAsci->cindx[sum][i]);
	}
      }
      /*
      printf(" name:%s nam:%s indx:%d\n"
      , name, lcmb[sumAsci->cindx[sum][i]].name, sumAsci->cindx[sum][i]);
      */
    }
   }    
  }
  else 
  {
    if(printFlag) printf(" WARNING lcmb:%s not found in hash-table\n", name);
    for (i=0; i<anzGeo->c; i++) if( lcmb[i].name != (unsigned char *)NULL )
      if((compare( lcmb[i].name, name, length)==length) && (sword( lcmb[i].name, buffer)==length))
        return(i);
  }

  /* if not found look for free cells */
  if (delLcmbFlag)
  for (i=0; i<anzGeo->c; i++)
  {
    /* do we have a "deleted" lcmb for use?  */
    if( lcmb[i].name == (unsigned char *)NULL ) 
    {
      pfree=-i-10;
      return(pfree);
    }
  }
  delLcmbFlag=0;
  return(pfree);
}


/* returns surf-Index if known, or -(Index+10) of a deleted surf or if none is deleted -1  */
int getSurfNr(unsigned char *name)
{
  static int  i, n, length, pfree, sum;

  if(!anzGeo->s) return(-1);

  i=length=sum=0;
  pfree=-1;

  while(name[length]!=(unsigned char)NULL) { sum+=name[length++]*(++i); }
  /*
  printf ("in getSurfNr anzs[%d]: %d\n", sum, sumAsci->anzs[sum]);
  */
  if(sum<=sumAsci->max_sums)
  {
   for (i=0; i<sumAsci->anzs[sum]; i++)
   {
    if(( surf[sumAsci->sindx[sum][i]].name != (unsigned char *)NULL ) && (strlen(surf[sumAsci->sindx[sum][i]].name) == length))
    { 
      n=length-1;
      while(surf[sumAsci->sindx[sum][i]].name[n]==name[n])
      {
        if(!n--)
        {
          return(sumAsci->sindx[sum][i]);
	}
      }
      /*
      printf(" name:%s nam:%s indx:%d\n"
      , name, surf[sumAsci->sindx[sum][i]].name, sumAsci->sindx[sum][i]);
      */
    }
   } 
  }
  else
  {
    if(printFlag) printf(" WARNING surf:%s not found in hash-table\n", name);
    for (i=0; i<anzGeo->s; i++) if( surf[i].name != (unsigned char *)NULL )
    {
      if((compare( surf[i].name, name, length)==length) && (sword( surf[i].name, buffer)==length)) return(i);
    }
  }

  /* if not found look for free cells */
  if (delSurfFlag)
  for (i=0; i<anzGeo->s; i++)
  {
    /* do we have a "deleted" surf for use?  */
    if( surf[i].name == (unsigned char *)NULL ) 
    {
      pfree=-i-10;
      return(pfree);
    }
  }
  delSurfFlag=0;
  return(pfree);
}

/* returns body-Index if known, or -(Index+10) of a deleted body or if none is deleted -1  */
int getBodyNr(unsigned char *name)
{
  static int  i, n, length, pfree, sum;

  if(!anzGeo->b) return(-1);

  i=length=sum=0;
  pfree=-1;

  while(name[length]!=(unsigned char)NULL) { sum+=name[length++]*(++i); }
  /*
  printf ("in getBodyNr anzb[%d]: %d\n", sum, sumAsci->anzb[sum]);
  */
  if(sum<=sumAsci->max_sumb)
  {
   for (i=0; i<sumAsci->anzb[sum]; i++)
   {
    if(( body[sumAsci->bindx[sum][i]].name != (unsigned char *)NULL ) && (strlen(body[sumAsci->bindx[sum][i]].name) == length))
    { 
      n=length-1;
      while(body[sumAsci->bindx[sum][i]].name[n]==name[n])
      {
        if(!n--)
        {
          return(sumAsci->bindx[sum][i]);
	}
      }
      /*
      printf(" name:%s nam:%s indx:%d\n"
      , name, body[sumAsci->bindx[sum][i]].name, sumAsci->bindx[sum][i]);
      */
    }
   }   
  }
  else 
  {
    if(printFlag) printf(" WARNING body:%s not found in hash-table\n", name);
    for (i=0; i<anzGeo->b; i++) if( body[i].name != (unsigned char *)NULL )
      if((compare( body[i].name, name, length)==length) && (sword( body[i].name, buffer)==length))
        return(i);
  }

  /* if not found check all and look for free cells */
  /* check all is not active, should not be necessary */
  if (delBodyFlag)
  for (i=0; i<anzGeo->b; i++)
  {
    /* do we have a "deleted" body for use?  */
    if( body[i].name == (unsigned char *)NULL ) 
    {
      pfree=-i-10;
      return(pfree);
    }
  }
  delBodyFlag=0;
  return(pfree);
}


/* returns Nurs-Index if known, or -(Index+10) of a deleted body or if none is deleted -1  */
int getNursNr(unsigned char *name)
{
  static int  i, n, length, pfree, sum;

  if(!anzGeo->nurs) return(-1);
  if(compareStrings(name, "BLEND")>0) return(-1);

  i=length=sum=0;
  pfree=-1;

  while(name[length]!=(unsigned char)NULL) {  sum+=name[length++]*(++i); }
  
  if(sum<=sumAsci->max_sumS)
  {
   for (i=0; i<sumAsci->anzS[sum]; i++)
   {
    if(( nurbs[sumAsci->Sindx[sum][i]].name != (unsigned char *)NULL ) && (strlen(nurbs[sumAsci->Sindx[sum][i]].name) == length))
    { 
      n=length-1;
      while(nurbs[sumAsci->Sindx[sum][i]].name[n]==name[n])
      {
        if(!n--)
        {
          return(sumAsci->Sindx[sum][i]);
	}
      }
      /*
      printf(" name:%s nam:%s indx:%d\n"
      , name, nurbs[sumAsci->Sindx[sum][i]].name, sumAsci->Sindx[sum][i]);
      */
    }
   }
  }
  else 
  {
    if(printFlag) printf(" WARNING NURS:%s not found in hash-table\n", name);
    for (i=0; i<anzGeo->nurs; i++) if( nurbs[i].name != (unsigned char *)NULL )
      if((compare( nurbs[i].name, name, length)==length) && (sword( nurbs[i].name, buffer)==length))
        return(i);
  }

  /* if not found check all and look for free cells */
  /* check all is not active, should not be necessary */
  if (delNursFlag)
  for (i=0; i<anzGeo->nurs; i++)
  {
    /* do we have a "deleted" nurbs for use?  */
    if( nurbs[i].name == (unsigned char *)NULL ) 
    {
      pfree=-i-10;
      return(pfree);
    }
  }
  delNursFlag=0;
  return(pfree);
}

/* returns nurl-Index if known, or -(Index+10) of a deleted nurl or if none is deleted -1  */
int getNurlNr(unsigned char *name)
{
  static int i, length, pfree;

  if(!anzGeo->nurl) return(-1);

  i=0;
  pfree=-1;
  length=sword( name, buffer );
  for (i=0; i<anzGeo->nurl; i++)
  {
    if( ( compare( nurbl[i].name, name, length)==length) && ( sword( nurbl[i].name, buffer)==length) )
      return(i);
    if( nurbl[i].name == (unsigned char *)NULL )
      pfree=-i-10;
  }
  return(pfree);
}



/* returns set-Index if known, or -(Index+10) of a deleted set or if none is deleted -1  */
int getSetNr(unsigned char *name)
{
  static int  i, n, length, pfree, sum;

  if(!anzGeo->sets) return(-1);

  i=length=sum=0;
  pfree=-1;

  while((name[length]!=(unsigned char)NULL)&&(length<MAX_LINE_LENGTH)) { sum+=name[length++]*(++i); }
  
  if(sum<=sumAsci->max_sumse)
  {
   for (i=0; i<sumAsci->anzse[sum]; i++)
   {
    if(( set[sumAsci->seindx[sum][i]].name != (unsigned char *)NULL ) && (strlen(set[sumAsci->seindx[sum][i]].name) == length))
    { 
      n=length-1;
      while(set[sumAsci->seindx[sum][i]].name[n]==name[n])
      {
        if(!n--)
        {
          return(sumAsci->seindx[sum][i]);
	}
      }
      /*
      printf(" name:%s nam:%s indx:%d\n"
      , name, set[sumAsci->seindx[sum][i]].name, sumAsci->seindx[sum][i]);
      */
    }
   }    
  }
  else
  {
    if(printFlag) printf(" WARNING set:%s not found in hash-table\n", name);
    for (i=0; i<anzGeo->sets; i++)
    {
      if (set[i].name!= (unsigned char *)NULL)
        if ((compare( set[i].name, name, length)==length) && (sword( set[i].name, buffer)==length))
          return(i);
    }
  }

  /* set not found, check if the name could be an set-index */
  if (atoi(name)>0)
  {
    /* the user has specified the set-index */
    n=atoi(name);
    if(n<=anzGeo->sets)
    {
      for (i=0; i<anzGeo->sets; i++) if(set[i].index==n)
      {
        printf (" index %s points to %s\n", name, set[i].name);
        return (i);
      }
    }
  }

  /* if not found check all and look for free cells */
  /* check all is not active, should not be necessary */
  if (delSetFlag)
  for (i=0; i<anzGeo->sets; i++)
  {
    /* do we have a "deleted" set for use?  */
    if( set[i].name == (unsigned char *)NULL ) 
    {
      pfree=-i-10;
      return(pfree);
    }
  }
  delSetFlag=0;
  return(pfree);
}




/* search an element in an sorted integer-array */
/* return -1 if not found or index if found */
int getIndex(int **ipnt, int n, int x0 )
{
  int i=0,ii,m,n1,n2;
  int *x;

  x=*ipnt;
  /* if x0 is lower than the first elem */
  if((n==0)||(x0<x[0])) return(-1);

  /* if x0 is higher than the last elem */
  else if(x0>x[n-1]) return(-1);

  else
  {
    /* search the intersection */
    n1=0;                              
    n2=n;                            
    for(ii=0; ii<n; ii++)
    {                     
      m=(n2+n1)/2;                      
      if(x0>= x[m] ) n1=m;              
      if(x0 < x[m] ) n2=m;              
      if((n2-n1) == 1) break;           
    }                                 
    i=n1;
#if TEST
    printf("i:%d x:%d x0:%d x++:%d\n", i,x[i],x0,x[i+1]); 
#endif

    if (x0!=x[i])
    {
      /* element not found */
      return(-1);
    }
  }

#if TEST
  for(ii=0; ii<n; ii++)
  {
    printf("i:%d x:%d \n", ii,x[ii]); 
  }
#endif
 
#if TEST
  printf("b:%d\n", *ipnt); 
#endif
  return(n);
}



void delSet( unsigned char *setname)
{
  int i, j;
  int   setNr;

  setNr=getSetNr(setname);

  if (setNr<0)
  {
    if(printFlag) printf (" delSet: set:%s does not exist\n", setname);
    return;
  }
  /* suche abhaengige entities */
  if( set[setNr].type )
  {
    /* durchsuche alle linien   */
    for(i=0; i<anzGeo->l; i++)
    {
      if ((setNr==line[i].trk)&&(line[i].typ=='s')&&( line[i].name != (unsigned char *)NULL))
      {
        printf (" ERROR: trk removed, Line will be straight\n");
        line[i].trk=-1;
        line[i].typ=' ';
      }
    }
  }
  /* durchsuche alle uebrigen sets und entferne den set  */
  for(i=0; i<anzGeo->sets; i++)
  {
    for(j=0; j<set[i].anz_se; j++)
      if (setNr==set[i].set[j])
      {
        setr( i, "se", setNr);
      }
  }
  /* durchsuche alle psets und entferne den set   */
  j=0; for(i=0; i<anzGeo->psets; i++)
  {
    if (setNr!=pset[i].nr)  { pset[j].nr=pset[i].nr; j++; }
  }
  anzGeo->psets=j;

  /* der set wird wieder frei gegeben */
  delSetFlag=1;
    set[setNr].flag = 'c';
    set[setNr].type = 0;
    set[setNr].anz_n = 0;
    set[setNr].anz_e = 0;
    set[setNr].anz_f = 0;
    set[setNr].anz_p = 0;
    set[setNr].anz_l = 0;
    set[setNr].anz_c = 0;
    set[setNr].anz_s = 0;
    set[setNr].anz_b = 0;
    set[setNr].anz_nurl = 0;
    set[setNr].anz_nurs = 0;
    set[setNr].anz_se = 0;
    free(set[setNr].name);
    free(set[setNr].node);
    free(set[setNr].elem);
    free(set[setNr].face);
    free(set[setNr].pnt);
    free(set[setNr].line);
    free(set[setNr].lcmb);
    free(set[setNr].surf);
    free(set[setNr].body);
    free(set[setNr].nurl);
    free(set[setNr].nurs);
    free(set[setNr].set);
    set[setNr].name=(unsigned char *)NULL;
    set[setNr].node=(int *)NULL;
    set[setNr].elem=(int *)NULL;
    set[setNr].face=(int *)NULL;
    set[setNr].pnt= (int *)NULL;
    set[setNr].line=(int *)NULL;
    set[setNr].lcmb=(int *)NULL;
    set[setNr].surf=(int *)NULL;
    set[setNr].body=(int *)NULL;
    set[setNr].nurl=(int *)NULL;
    set[setNr].nurs=(int *)NULL;
    set[setNr].set=(int *)NULL;
    set[setNr].material = -1;
}

/*------------------------------------------------------------------*/
/* einen set als offen markieren                                    */
/*------------------------------------------------------------------*/

int seto( unsigned char *setname )
{
  int   i,setNr, sum=0;

  operateAlias( setname, "se" );

  setNr=getSetNr(setname);

  if (strlen(setname)<=0)
  {
    /* list all open sets */
    for (i=0; i<anzGeo->sets; i++)
    {
      if( set[i].name != (unsigned char *)NULL )
      {
        if ((!set[i].type)&&(set[i].flag=='o'))
          printf ("%s stat:%c n:%d e:%d f:%d p:%d l:%d s:%d b:%d L:%d S:%d se:%d\n", set[i].name, set[i].flag, set[i].anz_n, set[i].anz_e, set[i].anz_f, set[i].anz_p, set[i].anz_l, set[i].anz_s, set[i].anz_b, set[i].anz_nurl, set[i].anz_nurs, set[i].anz_se);
      }
    }
    return(-1);
  }

  if (setNr==-1)       /* open a new set */
  {
    if ((set = (Sets *)realloc( (Sets *)set, (anzGeo->sets+1)*sizeof(Sets)) ) == NULL )
    {
      printf(" ERROR: realloc failure in seto, set:%s not installed\n\n", setname);
      return(-1);
    }
    setNr= anzGeo->sets;
    anzGeo->sets++;

    i=strlen(setname);
    if((set[setNr].name= (unsigned char *)malloc((i+1)*sizeof(unsigned char))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    strcpy( set[setNr].name, setname);
    sum=hashSet( sumAsci, setname, setNr );
    if(printFlag) printf (" create and open set:%s\n", set[setNr].name);
    set[setNr].flag='o';
    set[setNr].type=0;
    set[setNr].etyp=0;
    if((set[setNr].node= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].elem= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].face= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].pnt= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].line= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].lcmb= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].surf= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].body= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].nurl= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].nurs= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].set= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    set[setNr].index = -1;
    set[setNr].material = -1;
    set[setNr].anz_n = 0;
    set[setNr].anz_e = 0;
    set[setNr].anz_f = 0;
    set[setNr].anz_p = 0;
    set[setNr].anz_l = 0;
    set[setNr].anz_c = 0;
    set[setNr].anz_s = 0;
    set[setNr].anz_b = 0;
    set[setNr].anz_nurl = 0;
    set[setNr].anz_nurs = 0;
    set[setNr].anz_se = 0;
  }
  else if (setNr<-1)    /* replace a deleted set */
  {
    setNr=-(setNr+10);
    i=strlen(setname);
    if((set[setNr].name= (unsigned char *)malloc((i+1)*sizeof(unsigned char))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    strcpy( set[setNr].name, setname);
    sum=hashSet( sumAsci, setname, setNr );
    set[setNr].flag='o';
    set[setNr].type=0;
    if(printFlag) printf (" open set:%s\n", set[setNr].name);
  }
  else
  {
    if (set[setNr].flag=='o')
    {
      printf (" set:%s is already open\n", set[setNr].name);
      return(setNr);
    }
    else
    {
      if(printFlag) printf (" open set:%s\n", set[setNr].name);
      set[setNr].flag='o';
    }
  }

  /* add the set to openSets */
  openSets->nr++;
  if( (openSets->set = (int *)realloc( (int *)openSets->set, openSets->nr*sizeof(int))) == NULL )
  { printf(" ERROR: realloc failed in seto\n\n"); return(-1); }
  openSets->set[ openSets->nr-1 ] = setNr;
  if(printFlag) printf("seto: openSets->nr:%d openSets->set:%d set:%s\n", openSets->nr, openSets->set[openSets->nr-1],set[setNr].name);
  return(setNr);
}


/*------------------------------------------------------------------*/
/* einen set schliessen                                             */
/*------------------------------------------------------------------*/

void setc( unsigned char *setname )
{
  int   setNr, i, n, flag=0;
  static int *puf=NULL;

  operateAlias( setname, "se" );
  if (strlen(setname)>0) setNr=getSetNr(setname);
  else if(openSets->nr>0) setNr=openSets->set[openSets->nr-1];
  else { printf("no open set\n"); return; }

  if (setNr<0)
  {
    printf (" setc: set:%s does not exist\n", setname);
    return;
  }
  else
  {
    if (set[setNr].flag=='c')
    {
      printf (" set:%s is already closed\n", set[setNr].name);
    }
    else
    {
      if(printFlag) printf (" close set:%s\n", set[setNr].name);
      set[setNr].flag='c';

      /* remove the set from openSets */
      /* puffer allocieren  */
      if ( (puf = (int *)malloc( (openSets->nr+1)*sizeof(int))) == NULL )
      printf(" ERROR: malloc failed in setc\n\n");

      n=0;
      for ( i=0; i<openSets->nr; i++)
      {
        if ( openSets->set[i]!=setNr )
        {
          puf[n] = openSets->set[i];
          n++;
        }
        else
          flag=1;
      }
 
      if (flag)
      {
        openSets->nr--;
        if ((openSets->set = (int *)realloc( (int *)openSets->set, (openSets->nr+1)*sizeof(int)) ) == NULL)
        { printf(" ERROR: realloc failed in setc\n\n"); free(puf); return; }

        for ( i=0; i<openSets->nr; i++)
        {
          openSets->set[i] = puf[i];
        }
      }
      free(puf);
      if(printFlag) printf("setc: openSets->nr:%d openSets->set:%d set:%s\n", openSets->nr, setNr, set[setNr].name); 
    }
  }
}


/*------------------------------------------------------------------*/
/* entity einem Set zuordnen                                        */
/*------------------------------------------------------------------*/


int hashSet( SumAsci *sumAsci, unsigned char *name, int nr)
{
  int i=0,j=0, n;
  int sum=0; 

  while(name[i]!=(unsigned char)NULL) { sum+=name[i]*(++j); i++; }

  /* check if sum is higher as the allocated value */
  /* if not look for a free entry */
  if(sum>sumAsci->max_sumse)
  {
    if ((sumAsci->anzse=(int *)realloc( (int *)sumAsci->anzse, (sum+1)*sizeof(int)) ) == NULL )
    { printf("\n\nERROR: realloc failure in hashSet(), set:%s not included\n\n", name); return(-1); }
    if ((sumAsci->seindx=(int **)realloc( (int **)sumAsci->seindx, (sum+1)*sizeof(int *)) ) == NULL )
    { printf("\n\nERROR: realloc failure in hashSet(), set:%s not included\n\n", name); return(-1); }
    for(i=sumAsci->max_sumse+1; i<=sum; i++) { sumAsci->anzse[i]=0; sumAsci->seindx[i]=NULL; }
    sumAsci->max_sumse=sum;
  }
  else
  {
    if (delSetFlag)
    for (i=0; i<sumAsci->anzse[sum]; i++) 
    {
      n=sumAsci->seindx[sum][i];
      if( set[n].name == (unsigned char *)NULL )
      {
        /* already existing space to fill */
        sumAsci->seindx[sum][i]=nr;
        return(sum);
      }
    }
  }

  /* alloc of a new entry in the hash table */
  if ((sumAsci->seindx[sum] =(int *)realloc( (int *)sumAsci->seindx[sum], (sumAsci->anzse[sum]+1)*sizeof(int)) ) == NULL )
  { printf("\n\nERROR: realloc failure in hashSet(), set:%s not included\n\n", name); return(-1); }

  sumAsci->seindx[sum][sumAsci->anzse[sum]] = nr;
  sumAsci->anzse[sum]++;
  return(sum);
}



int pre_seta( unsigned char *string, unsigned char *type, unsigned char *name)
{
  int i, setNr;
  int sum=0, n=0;
  int number;
  unsigned char setname[MAX_LINE_LENGTH]; /* string is not changeable. Therefore a new unsigned char is necessary */

  /* remove blanks and other illegal chars*/
  for(i=0;i<strlen(string); i++) if(string[i]>(unsigned char)0x20) { setname[n]=string[i]; n++; }

  setname[n]=(unsigned char)NULL;

  operateAlias( setname, "se" );
  setNr=getSetNr(setname);

  number=0;

  if (setNr==-1)
  {
    if ((set = (Sets *)realloc( (Sets *)set, (anzGeo->sets+2)*sizeof(Sets)) ) == NULL )
    {
      printf(" ERROR: realloc failure in seta, set:%s not installed\n\n", setname);
      return(-1);
    }
    setNr= anzGeo->sets;
    anzGeo->sets++;

    i=strlen(setname);
    if((set[setNr].name= (unsigned char *)malloc((i+1)*sizeof(unsigned char))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    strcpy( set[setNr].name, setname);
    sum=hashSet( sumAsci, setname, setNr );
    if(printFlag) printf (" create set:%s\n", set[setNr].name);
    set[setNr].flag='c';
    if ( type[1] == 's' ) set[setNr].type=1;
    else                  set[setNr].type=0;
    set[setNr].etyp=0;
    if((set[setNr].node= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].elem= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].face= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].pnt= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].line= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].lcmb= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].surf= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].body= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].nurl= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].nurs= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].set= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    set[setNr].index = -1;
    set[setNr].material = -1;
    set[setNr].anz_n = 0;
    set[setNr].anz_e = 0;
    set[setNr].anz_f = 0;
    set[setNr].anz_p = 0;
    set[setNr].anz_l = 0;
    set[setNr].anz_c = 0;
    set[setNr].anz_s = 0;
    set[setNr].anz_b = 0;
    set[setNr].anz_nurl = 0;
    set[setNr].anz_nurs = 0;
    set[setNr].anz_se = 0;
  }
  else if (setNr<-1)    /* replace a deleted set */
  {
    setNr=-(setNr+10);
    i=strlen(setname);
    if((set[setNr].name= (unsigned char *)malloc((i+1)*sizeof(unsigned char))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    strcpy( set[setNr].name, setname);
    if ( type[1] == 's' ) set[setNr].type=1;
    else                  set[setNr].type=0;
    sum=hashSet( sumAsci, setname, setNr );
    if((set[setNr].node= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].elem= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].face= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].pnt= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].line= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].lcmb= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].surf= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].body= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].nurl= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].nurs= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
    if((set[setNr].set= (int *)malloc(sizeof(int))) == NULL )
    { printf("ERROR: malloc failed in seta()\n\n" ); return(-1); }
  }

  /* determine the index of the entity */
  if (( type[0] == 's' )&&( type[1] == 'e' ))  number=getSetNr(name);
  else if ( type[0] == 'n' )                   number=atoi(name);
  else if ( type[0] == 'e' )                   number=atoi(name);
  else if ( type[0] == 'f' )                   number=atoi(name);
  else if ( type[0] == 'p' )                   number=getPntNr(name);
  else if ( type[0] == 'l' )                   number=getLineNr(name);
  else if ( type[0] == 'c' )                   number=getLcmbNr(name);
  else if ( type[0] == 's' )                   number=getSurfNr(name);
  else if ( type[0] == 'b' )                   number=getBodyNr(name);
  else if ( type[0] == 'L' )                   number=getNurlNr(name);
  else if ( type[0] == 'S' )                   number=getNursNr(name);
  else if ( type[0] == 'i' ) 
  {
    if(printFlag) printf (" set initialized\n");
    return(setNr);
  }
  else
  {
    errMsg ("ERROR: in seta type:%s not recognized\n", type);
    return(-1);
  }

  /* add to the set */
  if( seta(setNr, type, number)<0 )
    return(-1);
  else
    return(setNr);
}



int seta( int setNr, unsigned char *type, int number)
{
  int n,k;
  if( set[setNr].name == (unsigned char *)NULL )
  {
    errMsg(" ERROR: setNr:%d is undefined\n", setNr);
    return(-1);
  }

  /* check if item is known and if its already member of the set */
  if (( type[0] == 's' )&&( type[1] == 'e' ))
  {
    if (number<0)
    { if(printFlag) printf(" set:%d does not exist\n", number ); return(-1); }
    set[setNr].anz_se= iinsert(&set[setNr].set, set[setNr].anz_se, number);
  }
  else if ( type[0] == 'n' )
  {
    if ((number<anz->nmin)|| (number>anz->nmax))
    { if(printFlag) printf(" node:%d does not exist, min:%d max:%d\n", number, anz->nmin, anz->nmax); return(-1); }
    set[setNr].anz_n= iinsert(&set[setNr].node, set[setNr].anz_n, number);
  }
  else if ( type[0] == 'e' )
  {
    if ((number<anz->emin)|| (number>anz->emax))
    { if(printFlag) printf(" elem:%d does not exist, min:%d max:%d\n", number, anz->emin, anz->emax ); return(-1); }
    set[setNr].anz_e=iinsert(&set[setNr].elem, set[setNr].anz_e, number);
  }
  else if ( type[0] == 'f' )
  {
    set[setNr].anz_f=iinsert(&set[setNr].face, set[setNr].anz_f, number);
  }
  else if ( type[0] == 'p' )
  {
    if (number<0)
    { if(printFlag) printf(" pntNr:%d does not exist\n", number ); return(-1); }

    if(set[setNr].type==1) /* seqa */
    {
      if (number<0)
      { if(printFlag) printf(" pntNr:%d does not exist\n", number ); return(-1); }
      for (n=0; n<set[setNr].anz_p; n++)
      {
        if( set[setNr].pnt[n] == number )
        { if(printFlag) printf(" pnt already stored\n"); return(-1); }
      }
      set[setNr].anz_p++;
      if( (set[setNr].pnt = (int *)realloc( (int *)set[setNr].pnt, set[setNr].anz_p*sizeof(int))) == NULL )
      { printf(" ERROR: realloc failed in set[%d]:%s\n\n", setNr, set[setNr].name); return(-1); }
      else
      {
        if(printFlag) printf(" set[%d]:%s reallocated and pnt %s added\n"
            , setNr, set[setNr].name, point[number].name );
      }
      set[setNr].pnt[ (set[setNr].anz_p-1) ] = number;
    }
    else
      set[setNr].anz_p=iinsert(&set[setNr].pnt, set[setNr].anz_p, number);

    if (point[number].nn>0)
    {
      for (k=0; k<point[number].nn; k++)
      {
        set[setNr].anz_n=iinsert(&set[setNr].node, set[setNr].anz_n, point[number].nod[k] );
      }
    }
  }
  else if ( type[0] == 'l' )
  {
    if (number<0)
    { if(printFlag) printf(" lineNr:%d does not exist\n", number ); return(-1); }
    set[setNr].anz_l= iinsert(&set[setNr].line, set[setNr].anz_l, number);
    if( line[number].nn >0 )
    {
      for (k=0; k<line[number].nn; k++)
      {
        set[setNr].anz_n= iinsert(&set[setNr].node, set[setNr].anz_n, line[number].nod[k] );
      }
    }
    if (line[number].ne>0)
    {
      for (k=0; k<line[number].ne; k++)
      {
        set[setNr].anz_e=iinsert(&set[setNr].elem, set[setNr].anz_e, line[number].elem[k] );
      }
    }
  }
  else if ( type[0] == 'c' )
  {
    if (number<0)
    { if(printFlag) printf(" lcmbNr:%d does not exist\n", number ); return(-1); }
    set[setNr].anz_c= iinsert(&set[setNr].lcmb, set[setNr].anz_c, number);
  }
  else if ( type[0] == 's' )
  {
    if (number<0)
    { if(printFlag) printf(" surfNr:%d does not exist\n", number ); return(-1); }
    set[setNr].anz_s= iinsert(&set[setNr].surf, set[setNr].anz_s, number);
    if (surf[number].nn>0)
    {
      for (k=0; k<surf[number].nn; k++)
      {
        set[setNr].anz_n= iinsert(&set[setNr].node, set[setNr].anz_n, surf[number].nod[k] );
      }
    }
    if (surf[number].ne>0)
    {
      for (k=0; k<surf[number].ne; k++)
      {
        set[setNr].anz_e=iinsert(&set[setNr].elem, set[setNr].anz_e, surf[number].elem[k] );
      }
    }
  }
  else if ( type[0] == 'b' )
  { 
    if (number<0)
    { if(printFlag) printf(" bodyNr:%d does not exist\n", number ); return(-1); }
    set[setNr].anz_b= iinsert(&set[setNr].body, set[setNr].anz_b, number);

    if (body[number].nn>0)
    {
      for (k=0; k<body[number].nn; k++)
      {
        set[setNr].anz_n= iinsert(&set[setNr].node, set[setNr].anz_n,body[number].nod[k] );
      }
    }
    if (body[number].ne>0)
    {
      for (k=0; k<body[number].ne; k++)
      {
        set[setNr].anz_e=iinsert(&set[setNr].elem, set[setNr].anz_e,body[number].elem[k] );
      }
    }
  }
  else if ( type[0] == 'L' )
  {
    if (number<0)
    { if(printFlag) printf(" NurlNr:%d does not exist\n", number ); return(-1); }
    set[setNr].anz_nurl= iinsert(&set[setNr].nurl, set[setNr].anz_nurl, number);
  }
  else if ( type[0] == 'S' )
  {
    if (number<0)
    { if(printFlag) printf(" NursNr:%d does not exist\n", number ); return(-1); }
    set[setNr].anz_nurs= iinsert(&set[setNr].nurs, set[setNr].anz_nurs, number);
  }
  else
  {
    errMsg ("WARNING: in seta type:%s not recognized\n", type);
    return(-1);
  }
  return(1);
}


int setr( int setNr, unsigned char *type, int number)
{
  register int i,j;

  if( set[setNr].name == (unsigned char *)NULL )
  {
    errMsg(" ERROR: setNr:%d is undefined\n", setNr);
    return(-1);
  }

  if (( type[0] == 's' )&&( type[1] == 'e' ))
  {
    /* set remove  */
    i=iremove(&set[setNr].set, set[setNr].anz_se, number);
    if(i<set[setNr].anz_se)
    {
      set[setNr].anz_se=i;
    }
    else { if(printFlag) printf(" set:%s not in set:%s\n", set[number].name, set[setNr].name); }
  }
  else if (type[0]=='n')
  {
    /* node remove  */
    i=iremove(&set[setNr].node, set[setNr].anz_n, number);
    if(i<set[setNr].anz_n)
    {
      set[setNr].anz_n=i;
    }
    else { if(printFlag) printf(" node:%d not in set:%s\n", number, set[setNr].name); }
  }
  else if (type[0]=='e')
  {
    /* element remove  */
    i=iremove(&set[setNr].elem, set[setNr].anz_e, number);
    if(i<set[setNr].anz_e)
    {
      set[setNr].anz_e=i;
    }
    else { if(printFlag) printf(" element:%d not in set:%s\n", number, set[setNr].name); }
  }
  else if (type[0]=='f')
  {
    /* element remove  */
    i=iremove(&set[setNr].face, set[setNr].anz_f, number);
    if(i<set[setNr].anz_f)
    {
      set[setNr].anz_f=i;
    }
    else { if(printFlag) printf(" face:%d not in set:%s\n", number, set[setNr].name); }
  }
  else if (type[0]=='p')
  {
    /* point remove  */
    i=iremove(&set[setNr].pnt, set[setNr].anz_p, number);
    if(i<set[setNr].anz_p)
    {
      set[setNr].anz_p=i;

      /* remove also embedded nodes */
      for (j=0; j<point[number].nn; j++)
      {
        set[setNr].anz_n=iremove(&set[setNr].node, set[setNr].anz_n, point[number].nod[j]);
      }        
    }
    else { if(printFlag) printf(" pnt:%s not in set:%s\n", point[number].name, set[setNr].name); }
  }
  else if (type[0]=='l')
  {
    /* line remove  */
    i=iremove(&set[setNr].line, set[setNr].anz_l, number);
    if(i<set[setNr].anz_l)
    {
      set[setNr].anz_l=i;

      /* remove also embedded nodes */
      for (j=0; j<line[number].nn; j++)
      {
        set[setNr].anz_n=iremove(&set[setNr].node, set[setNr].anz_n, line[number].nod[j]);
      }        

      /* remove also embedded elements */
      for (j=0; j<line[number].ne; j++)
      {
        set[setNr].anz_e=iremove(&set[setNr].elem, set[setNr].anz_e, line[number].elem[j]);
      }        
    }
    else { if(printFlag) printf(" line:%s not in set:%s\n", line[number].name, set[setNr].name); }
  }
  else if (type[0]=='c')
  {
    /* lcmb remove  */
    i=iremove(&set[setNr].lcmb, set[setNr].anz_c, number);
    if(i<set[setNr].anz_c)
    {
      set[setNr].anz_c=i;
    }
    else{  if(printFlag) printf(" lcmb:%s not in set:%s\n", lcmb[number].name, set[setNr].name); }
  }
  else if (type[0]=='s')
  {
    /* surface remove  */
    i=iremove(&set[setNr].surf, set[setNr].anz_s, number);
    if(i<set[setNr].anz_s)
    {
      set[setNr].anz_s=i;

      /* remove also embedded nodes */
      for (j=0; j<surf[number].nn; j++)
      {
        set[setNr].anz_n=iremove(&set[setNr].node, set[setNr].anz_n, surf[number].nod[j]);
      }        

      /* remove also embedded elements */
      for (j=0; j<surf[number].ne; j++)
      {
        set[setNr].anz_e=iremove(&set[setNr].elem, set[setNr].anz_e, surf[number].elem[j]);
      }        
    }
    else{  if(printFlag) printf(" surf:%s not in set:%s\n", surf[number].name, set[setNr].name); }
  }
  else if (type[0]=='b')
  {
    /* body remove  */
    i=iremove(&set[setNr].body, set[setNr].anz_b, number);
    if(i<set[setNr].anz_b)
    {
      set[setNr].anz_b=i;

      /* remove also embedded nodes */
      for (j=0; j<body[number].nn; j++)
      {
        set[setNr].anz_n=iremove(&set[setNr].node, set[setNr].anz_n, body[number].nod[j]);
      }        

      /* remove also embedded elements */
      for (j=0; j<body[number].ne; j++)
      {
        set[setNr].anz_e=iremove(&set[setNr].elem, set[setNr].anz_e, body[number].elem[j]);
      }        
    }
    else{ if(printFlag) printf(" body:%s not in set:%s\n", body[number].name, set[setNr].name); }
  }
  else if (type[0]=='L')
  {
    /* nurl remove  */
    i=iremove(&set[setNr].nurl, set[setNr].anz_nurl, number);
    if(i<set[setNr].anz_nurl)
    {
      set[setNr].anz_nurl=i;
    }
    else{ if(printFlag) printf(" nurl:%s not in set:%s\n", nurbl[number].name, set[setNr].name); }
  }
  else if (type[0]=='S')
  {
    /* nurs remove  */
    i=iremove(&set[setNr].nurs, set[setNr].anz_nurs, number);
    if(i<set[setNr].anz_nurs)
    {
      set[setNr].anz_nurs=i;
    }
    else{ if(printFlag) printf(" nurs:%s not in set:%s\n", nurbs[number].name, set[setNr].name); }
  }
  else
  {
    errMsg ("WARNING: in setr type:%s not recognized\n", type );
    return(-1);
  }
  return(1);
}


/*  seqr works only for sequences (set[].type==1) with points */
/*  must be used for seqences if points are to be deleted */ 
void seqr( int setNr, int number)
{
  register int i, n;
  static int *puf=NULL;
  int flag=0;

  if( set[setNr].name == (unsigned char *)NULL )
  {
    errMsg(" ERROR: setNr:%d is undefined\n", setNr);
    return;
  }

  if ( set[setNr].type!=1)
  {
    errMsg(" FATAL ERROR: in seqr, set:%s is not a sequence\n", set[setNr].name );
  }
  else
  {
    /* puffer allocieren  */
    if ( (puf = (int *)malloc( (set[setNr].anz_p+1)*sizeof(int))) == NULL )
      printf(" ERROR: malloc failed in setr\n\n");

    n=0;
    for ( i=0; i<set[setNr].anz_p; i++)
    {
      if (set[setNr].pnt[i] != number)
      {
        puf[n] = set[setNr].pnt[i];
        n++;
      }
      else
        flag=1;
    }

    if (flag)
    {
      set[setNr].anz_p--;
      /* if the set is empty, delete the set */
      if (set[setNr].anz_p <1) 
      {
        /* suche abhaengige linien, redefine if necessary */
        for (i=0; i<anzGeo->l; i++)
        {
          if(( line[i].typ == 's' )&&( setNr == line[i].trk ))
          {
            line[i].typ = ' ';
          }
        }
        delSet(set[setNr].name); free(puf); return;
      }
      if ((set[setNr].pnt = (int *)realloc( (int *)set[setNr].pnt,(set[setNr].anz_p+1)*sizeof(int)) ) == NULL)
      { printf(" ERROR: realloc failed in set[%d]:%s\n\n", setNr, set[setNr].name); free(puf); return; }
      else if(printFlag)
        printf (" set[%d]:%s reallocated and pnt %s removed\n", setNr, set[setNr].name, point[number].name );

      for ( i=0; i<set[setNr].anz_p; i++)
      {
        set[setNr].pnt[i] = puf[i];
      }
    }
    else if(printFlag) printf(" pnt:%s not in set:%s\n", point[number].name, set[setNr].name);
    free(puf);
  }
}


double calcLineLength(int l)
{
  int n;
  double p1[3], p2[3], p1p2[3], lp1p2, lmax=0.;

  p1[0]=line[l].ip[0]*scale->w+scale->x;
  p1[1]=line[l].ip[1]*scale->w+scale->y;
  p1[2]=line[l].ip[2]*scale->w+scale->z;
  for (n=3; n<line[l].nip; n+=3)
  {
    p2[0]=line[l].ip[n]*scale->w+scale->x;
    p2[1]=line[l].ip[n+1]*scale->w+scale->y;
    p2[2]=line[l].ip[n+2]*scale->w+scale->z;
    v_result( p1, p2, p1p2 );
    lp1p2=v_betrag( p1p2 );
    lmax+=lp1p2;

    p1[0]=p2[0];
    p1[1]=p2[1];
    p1[2]=p2[2];
  }
  return(lmax);
}


double pre_length(unsigned char *setname)
{
  int   i;
  int   setNr,l;
  double L=0, Ll=0;

  setNr=getSetNr(setname);
  if (setNr<0)
  {
    printf (" ERROR: set:%s does not exist\n", setname);
    return(-1);
  }

  for(i=0; i<set[setNr].anz_l; i++)
  {
    l=set[setNr].line[i];
    Ll=calcLineLength(l);
    L+=Ll;
  }
  printf("LENGTH:%lf\n", L);
  return(L);
}


double pre_area(unsigned char *setname)
{
  int   i,j;
  int   nr, setNr;
  double A=0., Ae, p[3][3], pcg[3], Ix, Iy, Ixy;
  double xcg=0., ycg=0., zcg=0.;

  setNr=getSetNr(setname);
  if (setNr<0)
  {
    printf (" ERROR: set:%s does not exist\n", setname);
    return(-1);
  }

  for(i=0; i<set[setNr].anz_e; i++)
  {
    nr=set[setNr].elem[i];
    if((e_enqire[nr].type==7)||(e_enqire[nr].type==8))
    {
      for(j=0; j<3; j++)
      {
        p[j][0]=node[e_enqire[nr].nod[j]].nx*scale->w+scale->x;
        p[j][1]=node[e_enqire[nr].nod[j]].ny*scale->w+scale->y;
        p[j][2]=node[e_enqire[nr].nod[j]].nz*scale->w+scale->z;
      }
      getGeoDataTria( p[0], p[1], p[2], &Ix, &Iy, &Ixy, &Ae, pcg);
    }
    else
    {
      printf("ERROR: type:%d of elem:%d not known. Interrupt\n",e_enqire[nr].type,nr); 
      return(-1.);
    }
    /*
       Berechnung globaler Größen:
    */
    A+=Ae;
    xcg+=pcg[0]*Ae;
    ycg+=pcg[1]*Ae;
    zcg+=pcg[2]*Ae;
  }
  printf("AREA:%lf  CENTER OF GRAVITY: %lf %lf %lf\n", A,xcg/A,ycg/A,zcg/A);
  return(A);
}






double pre_volu(unsigned char *setname)
{
  int   i,j;
  int   nr, setNr, massFlag=1, volFlag=1, elFlag=0;
  int   istat[3]={0,0,0};
  double vol=0., mass=0., vole, masse, x[20],y[20],z[20];
  double xcg=0., ycg=0., zcg=0., xcge, ycge, zcge;

  setNr=getSetNr(setname);
  if (setNr<0)
  {
    printf (" ERROR: set:%s does not exist\n", setname);
    return(-1);
  }

  for(i=0; i<set[setNr].anz_e; i++)
  {
    nr=set[setNr].elem[i];
    if((e_enqire[nr].type==1)||(e_enqire[nr].type==4))
    {
      for(j=0; j<8; j++)
      {
        x[j]=node[e_enqire[nr].nod[j]].nx*scale->w+scale->x;
        y[j]=node[e_enqire[nr].nod[j]].ny*scale->w+scale->y;
        z[j]=node[e_enqire[nr].nod[j]].nz*scale->w+scale->z;
      }
      hexaeder_(&nr, istat, x,y,z, &vole, &xcge, &ycge, &zcge );
    }
    else if((e_enqire[nr].type==3)||(e_enqire[nr].type==6))
    {
      for(j=0; j<4; j++)
      {
        x[j]=node[e_enqire[nr].nod[j]].nx*scale->w+scale->x;
        y[j]=node[e_enqire[nr].nod[j]].ny*scale->w+scale->y;
        z[j]=node[e_enqire[nr].nod[j]].nz*scale->w+scale->z;
      }
      tetraeder_(&nr, istat, x,y,z, &vole, &xcge, &ycge, &zcge );
    }
    else
    {
      printf("ERROR: type:%d of elem:%d not known. Interrupt\n",e_enqire[nr].type,nr); 
      return(-1.);
    }

    /*
       Berechnung globaler Größen:
    */

    /* get material properties */
    masse=-1.;
    elFlag=-1;
    for(j=0; j<anzGeo->sets; j++)
    {
      if((set[j].name!=(unsigned char *)NULL) && (!set[j].type) && (set[j].name[0]!='-') && (set[j].material>-1)) 
      {
        if(( getIndex(&set[j].elem,set[j].anz_e,nr) >-1) && (material[set[j].material].rho>-1.))
        {
          if(elFlag!=-1)
          {
            printf("ERROR: found material-definition for elem:%d in set:%s and %s\n", nr, set[j].name,set[elFlag].name );  
            break;
          }
          elFlag=j;
          volFlag=0;
          masse= vole * material[set[j].material].rho;
          mass+= masse;
        }
      }
    }
    if (masse<0)
    {
      massFlag=0;
      masse=vole;
    }
              
    vol+=vole;
    xcg+=xcge*masse;
    ycg+=ycge*masse;
    zcg+=zcge*masse;
  }
  if (massFlag)     printf("VOLUME:%lf  MASS:%e CENTER OF GRAVITY: %lf %lf %lf\n", vol,mass,xcg/mass,ycg/mass,zcg/mass);
  else if (volFlag) printf("VOLUME:%lf CENTER OF GRAVITY: %lf %lf %lf\n", vol,xcg/vol,ycg/vol,zcg/vol);
  else              printf("VOLUME:%lf\n", vol);
  return(vol);
}


void pre_contact( unsigned char *record)
{
  int i,j;
  int length, setNr, sum_c, c1, c2, mpcset[2];
  unsigned char setname[MAX_LINE_LENGTH], action[MAX_LINE_LENGTH];
  double tol=0.;


  length=sscanf(record, "%s %lf %s", setname, &tol, action);
  if(length<3) strcpy(action,"null");

  setNr=getSetNr(setname);
  if (setNr<0)
  {
    printf (" ERROR: set:%s does not exist\n", setname);
    return;
  }

  if (set[setNr].anz_f<2)
  {
    printf("ERROR: set:%s contains less than 2 faces. Contact between two faces not possible. Consider a <comp %s do> command.\n",set[setNr].name, set[setNr].name);
    return;
  }
  printf("Contact between faces of set:%s with tol:%lf\nwait for <ready>\n", set[setNr].name, tol);
  printf(" REMARK: Contact will only be detected if all nodes of adjacent element-faces are as close as the specified tolerance.\n");
  printf("         It will not be detected if only single nodes are within tolerance.\n");

  /*----- search the contact faces and write the eqations --------*/

  /* subdivide the faces into single unconnected sets of faces */
  /* return if not at least 2 indep meshes exist */
  sum_c=getMeshSections(setNr, face, node);
  if(sum_c < 2) 
  {
    printf("ERROR: Found only %d separate meshes. Contact not possible\n", sum_c);
    return;
  }
  printf(" found %d separate meshes\n", sum_c);

  /* ------- node-koordinaten berechnen und am ende wieder scalieren ------ */

  descalNodes ( anz->n, node, scale );

  /* search face-pairs of unconnected sets of faces */
  /* deside which side is the dep side */
  /* remove all dep-nodes which are not inside the ind-faces */


  for(i=1; i<sum_c; i++)
  {
    sprintf( setname, "%s%d", specialset->cf,i); 
    c1=getSetNr(setname);
    for(j=i; j<sum_c; j++)
    {
      sprintf( setname, "%s%d", specialset->cf,j+1); 
      c2=getSetNr(setname);

      if ((getFacePair( anz, c1, c2, e_enqire, face, node, tol, mpcset)==1)&&(action[0]=='e'))
      {
        /* write equations */
        /* write only dep-nodes which are not already used (1) */
        areampc(mpcset[0], mpcset[1], "abq", "123", "c", 1);
      }
    }
  }

  scalNodes ( anz->n, node, scale );
  printf("ready\n");
}



void pre_del( unsigned char *record)
{
  int  length, n, e, k, i, j, setNr, nf=0;
  unsigned char type[MAX_LINE_LENGTH], datum[MAX_PARAM_PER_RECORD][MAX_LINE_LENGTH];

  length= sword( record, type );
  for (i=0; i<MAX_PARAM_PER_RECORD; i++)
  {
    n =  sword( &record[length], datum[i] );
    if (n<1) break;
    length= length+n+1;
    operateAlias( datum[i], type );
    if(printFlag) printf ("nr:%d type:'%s' datum:'%s'\n", n, type, datum[i] );
  }

  if (compare(type, "se", 2) == 2 )
  {
    for (n=0; n<i; n++)
      delSet(datum[n]);
  }
  else if (compare(type, "pic", 3) == 3 )
  {
    bgpicture=0;
  }
  else if(compare(type, "mesh", 2) == 2 )
  {
    if(anz->n<1) return;
    if((i>0)&&(strlen(datum[i-1])>0)) 
    { 
      setNr=getSetNr(datum[i-1]);
      if(setNr<0)
      {
        printf(" ERROR: set |%s| does not exist\n",set[setNr].name);
        return;
      }
    }
    else setNr=0;
    if(printFlag) printf ("delete mesh defined in set:%s\n", set[setNr].name);
 
    if(setNr==0)
    {
      for (j=0; j<anzGeo->sets; j++ )
      {
        set[j].anz_n = 0;
        set[j].anz_e = 0;
        set[j].anz_f = 0;
      }
      for (j=0; j<anzGeo->psets; j++ )
      {
        set[pset[j].nr].anz_n=0;
        set[pset[j].nr].anz_e=0;
        set[pset[j].nr].anz_f=0;
      }
      for (j=0; j<anz->e; j++)
      {
        /* free space for the normal-vectors */
        if(e_enqire[e_enqire[j].nr].side!=NULL)
        {
          if (e_enqire[e_enqire[j].nr].type == 1)       nf=6;  /* HEXA8 */
          else if (e_enqire[e_enqire[j].nr].type == 2)  nf=6;  /* PENTA6 */
          else if (e_enqire[e_enqire[j].nr].type == 3)  nf=4;  /* TET4 */
          else if (e_enqire[e_enqire[j].nr].type == 4)  nf=48; /* HEXA20 */
          else if (e_enqire[e_enqire[j].nr].type == 5)  nf=48; /* PENTA15 */
          else if (e_enqire[e_enqire[j].nr].type == 6)  nf=16; /* TET10 */
          else if (e_enqire[e_enqire[j].nr].type == 7)  nf=1;  /* TRI3  */
          else if (e_enqire[e_enqire[j].nr].type == 8)  nf=4; /* TRI6  */
          else if (e_enqire[e_enqire[j].nr].type == 9)  nf=2; /* QUAD4 */
          else if (e_enqire[e_enqire[j].nr].type == 10) nf=8; /* QUAD8 */
          else if (e_enqire[e_enqire[j].nr].type == 11) nf=1; /* BEAM */
          else if (e_enqire[e_enqire[j].nr].type == 12) nf=1; /* BEAM3 */
          for(k=0; k<nf; k++) free(e_enqire[e_enqire[j].nr].side[k]);
          free(e_enqire[e_enqire[j].nr].side);
          e_enqire[e_enqire[j].nr].side=NULL;
        }
      }
      for (j=0; j<anz->f; j++)
      {
        if(face[j].side!=NULL)
        {
          if (face[j].type == 7)       nf=1;  /* TRI3  */
          else if (face[j].type == 8)  nf=4; /* TRI6  */
          else if (face[j].type == 9)  nf=2; /* QUAD4 */
          else if (face[j].type == 10) nf=8; /* QUAD8 */
          else if (face[j].type == 11) nf=1; /* BEAM */
          else if (face[j].type == 12) nf=1; /* BEAM3 */
          for(k=0; k<nf; k++) free(face[j].side[k]);
          free(face[j].side);
          face[j].side=NULL;
        }
      }
      anz->n=0;
      anz->e=0;
      anz->g=0;
      anz->f=0;
      anz->l=0;
      anz->nmax=0;
      anz->nmin=0;
      anz->emax=0;
      anz->emin=0;
      for (j=0; j<anzGeo->p; j++)
      { free(point[j].nod);
        point[j].nod=NULL; 
        point[j].nn=-1; }
      for (j=0; j<anzGeo->l; j++)
      { free(line[j].nod); free(line[j].elem);
        line[j].nod=NULL; line[j].elem=NULL; 
        line[j].nn=-1; line[j].ne=-1; }
      for (j=0; j<anzGeo->s; j++)
      { surf[j].nn=-1; free(surf[j].nod); surf[j].nod=NULL;
        surf[j].ne=-1; free(surf[j].elem); surf[j].elem=NULL; }
      for (j=0; j<anzGeo->b; j++)
      { body[j].nn=-1; free(body[j].nod); body[j].nod=NULL;
        body[j].ne=-1; free(body[j].elem); body[j].elem=NULL; }
      num_onod=0;
      num_olc=0;
      updateDispLists();
    }
    else
    {
      j=pre_seta( specialset->zap, "i", 0 );
      n=set[j].anz_n;
      e=set[j].anz_e;
      set[j].anz_n+=set[setNr].anz_n;
      set[j].anz_e+=set[setNr].anz_e;
      if((set[j].node=(int *)realloc((int *)set[j].node, (set[j].anz_n+1)*sizeof(int)))==NULL)
      { printf("\nERROR: realloc failure in pre_del()\n\n"); return; }
      if((set[j].elem=(int *)realloc((int *)set[j].elem, (set[j].anz_e+1)*sizeof(int)))==NULL)
      { printf("\nERROR: realloc failure in pre_del()\n\n"); return; }
      for (k=0; k<n; k++) set[j].elem[e++]=set[setNr].node[k];
      for (k=0; k<e; k++) set[j].node[n++]=set[setNr].elem[k];
      qsort( set[j].node, set[j].anz_n, sizeof(int), (void *)compareInt );
      qsort( set[j].elem, set[j].anz_e, sizeof(int), (void *)compareInt );
      if( zap(specialset->zap)==-1)
         printf (" ERROR in ZAP: set:%s does not exist\n",specialset->zap );
    }
  }
  else if (((compare(type, "n", 1) == 1 )||
      (compare(type, "e", 1) == 1 )||
      (compare(type, "p", 1) == 1 )||
      (compare(type, "l", 1) == 1 )||
      (compare(type, "c", 1) == 1 )||
      (compare(type, "s", 1) == 1 )||
      (compare(type, "b", 1) == 1 )||
      (compare(type, "S", 1) == 1 ))&&(strlen(type)==1)) 
  {
    pre_seta( specialset->zap, type, datum[n] );
    if( zap(specialset->zap)==-1)
          printf (" ERROR in ZAP: set:%s does not exist\n",specialset->zap );
  }
  else printf(" ERROR: type %s not known\n", type);
}


void pre_bia( unsigned char *record)
{
  int  length, j=0, nr, setNr;
  unsigned char setname[MAX_LINE_LENGTH], type[MAX_LINE_LENGTH];
  double factor=1., value=1.;
  double bias,div;
  int bias_fbd;     /* bias * 10 to gain one decimal digit (bias 10 == 100) */

  length= sscanf( record, "%s%s%lf%lf", setname, type, &factor, &value );

  if ((type[0]=='M')||(type[0]=='m')||(type[0]=='D')||(type[0]=='d') )
  {
    if ((type[0]=='D')||(type[0]=='d') ) factor=1./factor;
    operateAlias( setname, "se" );
    nr=getSetNr( setname );
    if(nr<0)
    {
      errMsg(" ERROR: %s is undefined\n", setname );
      return;
    }
    for (j=0; j<set[nr].anz_l; j++)
    {
      div=line[set[nr].line[j]].div;
      bias=line[set[nr].line[j]].bias;
      if(bias<1.)
      {
        bias_fbd= (pow(1./bias,(div-1.))*-10.)-.5;
        bias_fbd*=factor;
        if(bias_fbd>-10) line[set[nr].line[j]].bias=1.;
        else line[set[nr].line[j]].bias= 1./pow(((double)bias_fbd*-0.1), (1./((double)div-1.)));
      }
      else if(bias>1.)
      {
        bias_fbd= (pow(bias,(div-1.))*10)+.5;
        bias_fbd*=factor;
        if(bias_fbd<10) line[set[nr].line[j]].bias=1.;
        else line[set[nr].line[j]].bias=pow(((double)bias_fbd*0.1), (1./((double)div-1.)));
      }
    }
  }
  else if((type[0]>='1')&&(type[0]<='9'))
  {
    operateAlias( setname, "l" );
    nr=getLineNr( setname );

    operateAlias( setname, "se" );
    setNr=getSetNr( setname );

    /* its a line */
    if(nr>-1)
    {
      div=line[nr].div;
      bias=atof( &type[0])*factor;
      if(div>1)
      {
        if(bias<0) bias= 1./pow((bias*-1), (1./((double)div-1.)));
        else       bias=pow(bias, (1./((double)div-1.)));
      }
      else bias=1.;
      line[nr].bias=bias;
      rep(nr);
    }
    /* its a set */
    else if(setNr>-1)
    {
      for (j=0; j<set[setNr].anz_l; j++)
      {
        div=line[set[setNr].line[j]].div;
        if(div>1)
        {
          bias=atof(type)*factor;
          if(bias<0) bias= 1./pow((bias*-1), (1./((double)div-1.)));
          else       bias=pow(bias, (1./((double)div-1.)));
        }
        else bias=1.;
	printf("bias:%f factor:%f\n", bias,factor);
        line[set[setNr].line[j]].bias=bias;
      }
      for (j=0; j<set[setNr].anz_l; j++) rep(set[setNr].line[j]);
    }
    else
    {
      errMsg(" ERROR: %s is undefined\n", setname );
      return;
    }
  }
  else
  {
    errMsg(" ERROR: command:|%s| not recognized\n", record );
  }
  return;
}


void pre_div( unsigned char *record)
{
  int  length,j=0, nr, setNr;
  unsigned char setname[MAX_LINE_LENGTH], type[MAX_LINE_LENGTH];
  double factor=1., value=1., bias=1.;
  int bias_fbd,div;

  length= sscanf( record, "%s%s%lf%lf", setname, type, &factor, &value );

  if((length==1)&&(atoi(setname)>0))
  {
    sprintf(type,"DDIV %s",setname);
    pre_proc(type);
  }
  else if ((length>2)||(compare(type, "auto", 4) == 4 ))
  {
    /* its a set */
    operateAlias( setname, "se" );
    nr=getSetNr( setname );
    if(nr<0)
    {
      errMsg(" ERROR: %s is undefined\n", setname );
      return;
    }
    if ((type[0]=='A')||(type[0]=='a') )
    {
      if(length==2) { value=GTOL_COS_A; factor=gtol*GTOL_NODE_DIST/scale->w; }
      else if(length==3) { value=GTOL_COS_A; factor/=scale->w; }
      else  { value=cos(value*PI/180.); factor/=scale->w; }
      for (j=0; j<set[nr].anz_l; j++)
      {
        calcLineDiv(line, set[nr].line[j], point, value, factor, factor*ELEM_LENGTH_RATIO  ); 
      }
    }
    else if ((type[0]=='M')||(type[0]=='m') )
    {
      for (j=0; j<set[nr].anz_l; j++)
      {
        if((line[set[nr].line[j]].bias!=1.)&&(line[set[nr].line[j]].div>1))
	{
          if(line[set[nr].line[j]].bias<1.)
	  {
            bias_fbd= (int)((pow(1./line[set[nr].line[j]].bias,(line[set[nr].line[j]].div-1.))*-10.) -0.5) * value;
	  }
          else
	  {
            bias_fbd= (int)((pow(line[set[nr].line[j]].bias,(line[set[nr].line[j]].div-1.))*10.) +0.5) * value;
	  }
          line[set[nr].line[j]].div*=factor;
          if(bias_fbd*bias_fbd<10.) line[set[nr].line[j]].bias=1.;
          else
          {
            if(bias_fbd<0) line[set[nr].line[j]].bias= 1./pow((bias_fbd*-.1), (1./((double)line[set[nr].line[j]].div-1.)));
            else       line[set[nr].line[j]].bias=pow((bias_fbd*.1), (1./((double)line[set[nr].line[j]].div-1.)));
          }
        }
        else line[set[nr].line[j]].div*=factor;
      }
    }
    else if ((type[0]=='D')||(type[0]=='d') )
    {
      for (j=0; j<set[nr].anz_l; j++)
      {
        if((line[set[nr].line[j]].bias!=1.)&&(line[set[nr].line[j]].div>1))
	{
          if(line[set[nr].line[j]].bias<1.)
	  {
            bias_fbd= (int)((pow(1./line[set[nr].line[j]].bias,(line[set[nr].line[j]].div-1.))*-10.) -0.5) / value;
	  }
          else
	  {
            bias_fbd= (int)((pow(line[set[nr].line[j]].bias,(line[set[nr].line[j]].div-1.))*10.) +0.5) / value;
	  }
          line[set[nr].line[j]].div/=factor;
          if(bias_fbd*bias_fbd<10.) line[set[nr].line[j]].bias=1.;
          else
          {
            if(bias_fbd<0) line[set[nr].line[j]].bias= 1./pow((bias_fbd*-.1), (1./((double)line[set[nr].line[j]].div-1.)));
            else       line[set[nr].line[j]].bias=pow((bias_fbd*.1), (1./((double)line[set[nr].line[j]].div-1.)));
          }
        }
        else line[set[nr].line[j]].div/=factor;
        if(line[set[nr].line[j]].div<1) line[set[nr].line[j]].div=1;
      }
    }
    else if (length==2)
    {
      div=atoi(type);
      splitBiasDiv(&div, &bias);
      line[set[nr].line[j]].div=div;
      line[set[nr].line[j]].bias=bias;
    }
    else printf(" ERROR: type %s not known\n", type);
  
    for (j=0; j<set[nr].anz_l; j++) rep(set[nr].line[j]);
  }
  else if((length==2)&&(type[0]>='1')&&(type[0]<='9'))
  {
    operateAlias( setname, "l" );
    nr=getLineNr( setname );

    operateAlias( setname, "se" );
    setNr=getSetNr( setname );

    /* its a line */
    if(nr>-1)
    {
      div=atoi(type);
      splitBiasDiv(&div, &bias);

      line[nr].div=div;
      line[nr].bias=bias;
      rep(nr);
    }
    /* its a set */
    else if(setNr>-1)
    {
      div=atoi(type);
      splitBiasDiv(&div, &bias);
      for (j=0; j<set[setNr].anz_l; j++)
      {
        line[set[setNr].line[j]].div=div;
        line[set[setNr].line[j]].bias=bias;
      }
      for (j=0; j<set[setNr].anz_l; j++) rep(set[setNr].line[j]);
    }
    else
    {
      errMsg(" ERROR: %s is undefined\n", setname );
      return;
    }
  }
  else
  {
    errMsg(" ERROR: command:|%s| not recognized\n", record );
  }
  return;
}


void pre_move( unsigned char *record)
{
  int  length, i,k,p, setNr, nr;
  unsigned char setname[MAX_LINE_LENGTH];
  Nodes *bufn;


  length = sword( record, setname );

  operateAlias( setname, "se" );
  setNr=getSetNr( setname );
  if (setNr<0)
  {
    errMsg(" ERROR: Set (%s) is undefined\n", setname );
    return;
  }
  nr=setNr;

  if (set[nr].anz_p>set[nr].anz_n) i=set[nr].anz_p;
  else                             i=set[nr].anz_n;

  if ( (bufn = (Nodes *)malloc( (i+1) * sizeof(Nodes))) == NULL )
  {  printf("\n\n ERROR: malloc failed in pre_move(): i=%d\n\n", i) ; return; }


  if(set[nr].anz_p>0)
  {
    for (i=0; i<set[nr].anz_p; i++)
    {
      p=set[nr].pnt[i];
      if (p==-1)
      {
        errMsg(" ERROR: Point-nr:%d is undefined\n", set[nr].pnt[i] );
        return;
      }
      bufn[i].nx=point[p].px*scale->w+scale->x;
      bufn[i].ny=point[p].py*scale->w+scale->y;
      bufn[i].nz=point[p].pz*scale->w+scale->z;
    }
    if(transform( &record[length], set[nr].anz_p, bufn )<0) return;

    for (i=0; i<set[nr].anz_p; i++)
    {
      p=set[nr].pnt[i];
      point[p].px= (bufn[i].nx-scale->x)/scale->w;
      point[p].py= (bufn[i].ny-scale->y)/scale->w;
      point[p].pz= (bufn[i].nz-scale->z)/scale->w;
    }
    /*  recalculate the line-shapes    */
    for (i=0; i<anzGeo->l; i++) rep(i);
  }
  if(set[nr].anz_n>0)
  {
    for (i=0; i<set[nr].anz_n; i++)
    {
      bufn[i].nx=node[set[nr].node[i]].nx* scale->w+scale->x;
      bufn[i].ny=node[set[nr].node[i]].ny* scale->w+scale->y;
      bufn[i].nz=node[set[nr].node[i]].nz* scale->w+scale->z;
    }
    if (transform( &record[length], set[nr].anz_n, bufn )<0) return;
    for (i=0; i<set[nr].anz_n; i++)
    {
      node[set[nr].node[i]].nx= (bufn[i].nx-scale->x)/scale->w;
      node[set[nr].node[i]].ny= (bufn[i].ny-scale->y)/scale->w;
      node[set[nr].node[i]].nz= (bufn[i].nz-scale->z)/scale->w;
    }
  }

  /* the additional nodes for the HE20 (then HE26) elements need a new pos. too  */
  adjustNodes();

  /* dependent higher entities need new label-positions, achived with orient */
  /* create a set with the dependent higher entities to be oriented  */

  /* add all points to special set _ORI  */
  if(set[nr].anz_p>0)
  {
    if( (i=pre_seta( specialset->ori, "i", 0 )) <0 ) return;
    for (k=0; k<set[nr].anz_p; k++)
    {
      p=set[nr].pnt[k];
      seta( i, "p", p );
    }
    completeSet( specialset->ori, "up");
    orientSet( specialset->ori );
    /* clear special set  */
    delSet(specialset->ori);
  }
  free (bufn);
}


void free_proj(double *nx, double *nrad, int *nmissed)
{
  free (nx);
  free (nrad);
  free (nmissed);
  delSet(specialset->dep );
  delSet(specialset->ind );
}



void pre_proc( unsigned char *record)
{
  int  length, i;
  unsigned char action[MAX_LINE_LENGTH], param[MAX_LINE_LENGTH];

  length = sscanf( record,"%s %s", action, param);

  for(i=0; i<strlen(action); i++) action[i]=toupper(action[i]);
  if (compareStrings(action, "DDIV")>0)
  {
    ddiv=atoi(param);
    splitBiasDiv(&ddiv, &dbias);
  }
}


/* l linie, l_nr two new lines, ps_nr split-point */
int splitLine(int l, int *l_nr, int ps_nr, double ps_lbez)
{
  int  i,k, setNr;
  int  setNr0, setNr1;
  unsigned char name[MAX_LINE_LENGTH], trk[2][MAX_LINE_LENGTH];

  int p1_nr, p2_nr;
  unsigned char linbuf[MAX_LINE_LENGTH];
  double lbez, div;
  double p0[3], p1[3], p01[3];

  static double *pset_dl=NULL;

  double ltot,l1;
  int    div1,div2;


  /*  erzeuge den trk der neuen linien */
  if (line[l].typ=='a')
  {
    strcpy( trk[0], point[line[l].trk].name );
    strcpy( trk[1], point[line[l].trk].name );
  }
  else if (line[l].typ=='s')
  {
    /* suche alle punkte des trk die vor dem schnittpunkt liegen und ordne sie einem */
    /* neuen set zu und loesche sie aus dem bestehenden trk */
  
    /* erzeuge zwei neue sets fuer die stuetzpunkte der zwei neuen linien */
    getNewName( trk[0], "se" );
    setNr0=pre_seta( trk[0], "is", 0);
  
    getNewName( trk[1], "se" );
    setNr1=pre_seta( trk[1], "is", 0);
  
    /* determine the length of the spline, accumulate all dists between points */
    /* look if the sequence is ordered in the same way as the line */
    setNr=line[l].trk;
    lbez=0.;
   
    if ( ( pset_dl= (double *)realloc( (double *)pset_dl, (set[setNr].anz_p+1) * sizeof(double))) == NULL )
      printf("ERROR: realloc failed: splitLine\n\n" ); 
    pset_dl[0]=pset_dl[set[setNr].anz_p-1]=0.;
    if( line[l].p1==set[setNr].pnt[0] )
    {
      p0[0]=point[set[setNr].pnt[0]].px;
      p0[1]=point[set[setNr].pnt[0]].py;
      p0[2]=point[set[setNr].pnt[0]].pz;   
      for (i=1; i<set[setNr].anz_p; i++)
      {
        p1[0]=point[set[setNr].pnt[i]].px;
        p1[1]=point[set[setNr].pnt[i]].py;
        p1[2]=point[set[setNr].pnt[i]].pz;
        v_result( p0, p1, p01  );
        p0[0]=p1[0];
        p0[1]=p1[1];
        p0[2]=p1[2];
        lbez+=v_betrag( p01  );
        pset_dl[i]=lbez;
      }
    }
    else
    {
      p0[0]=point[set[setNr].pnt[set[setNr].anz_p-1]].px;
      p0[1]=point[set[setNr].pnt[set[setNr].anz_p-1]].py;
      p0[2]=point[set[setNr].pnt[set[setNr].anz_p-1]].pz;   
      for (i=1; i<set[setNr].anz_p; i++)
      {
        p1[0]=point[set[setNr].pnt[set[setNr].anz_p-1-i]].px;
        p1[1]=point[set[setNr].pnt[set[setNr].anz_p-1-i]].py;
        p1[2]=point[set[setNr].pnt[set[setNr].anz_p-1-i]].pz;
        v_result( p0, p1, p01  );
        p0[0]=p1[0];
        p0[1]=p1[1];
        p0[2]=p1[2];
        lbez+=v_betrag( p01  );
        pset_dl[set[setNr].anz_p-1-i]=lbez;
      }
    }
    ps_lbez*=lbez;
  
    k=0;
    if( line[l].p1==set[setNr].pnt[0] )
    {
      for (i=0; i<set[setNr].anz_p; i++)
      { 
        /* printf("+ dl:%lf ls:%lf p:%s\n", pset_dl[i], ps_lbez, point[set[setNr].pnt[i]].name); */
        if(pset_dl[i]<ps_lbez) seta( setNr0, "ps", set[setNr].pnt[i] );
        else
        {
          if(!k){
        /* printf(" change\n"); */
            seta( setNr0, "ps", ps_nr ); 
            seta( setNr1, "ps", ps_nr ); k++; } 
          seta( setNr1, "ps", set[setNr].pnt[i] );
        }
      }
    }
    else
    {
      for (i=set[setNr].anz_p-1; i>=0; i--)
      { 
        /* printf("- dl:%lf ls:%lf p:%s\n", pset_dl[i], ps_lbez, point[set[setNr].pnt[i]].name); */
        if(pset_dl[i]<ps_lbez) seta( setNr0, "ps", set[setNr].pnt[i] );
        else
        {
          if(!k){
        /* printf(" change\n"); */
            seta( setNr0, "ps", ps_nr ); 
            seta( setNr1, "ps", ps_nr ); k++; } 
          seta( setNr1, "ps", set[setNr].pnt[i] );
        }
      }
    }
  }
  else
  {
    strcpy(trk[0], " ");
    strcpy(trk[1], " ");
  }

  /* sichere den liniennamen bevor der pointer durch realloc in line_ geaendert wird  */
  strcpy( linbuf, line[l].name);
  
  /* erzeuge zwei neue linien  */
  p1_nr = line[l].p1;
  p2_nr = line[l].p2;

  div=1;
  getNewName( name, "l" );
  printf(" create line:%s %s %s %s %lf\n", name, point[p1_nr].name, point[ps_nr].name, trk[0], div );
  line_( name, point[p1_nr].name, point[ps_nr].name, trk[0], div, 1 );
  l_nr[0]=getLineNr(name);
  getNewName( name, "l" );
  printf(" create line:%s %s %s %s %lf\n", name, point[ps_nr].name, point[p2_nr].name, trk[1], div );
  line_( name, point[ps_nr].name, point[p2_nr].name, trk[1], div, 1 );
  l_nr[1]=getLineNr(name);

  /* calc new div */
  if (line[l].div>1)
  {
    ltot=calcLineLength(l);
    l1=calcLineLength(l_nr[0]);
    div1=line[l].div/ltot*l1;
    div2=line[l].div-div1;
     printf("1 ltot:%lf l1:%lf ldiv:%d div1:%d div2:%d\n", ltot,l1,line[l].div,div1,div2); 

    if(div1<1) { div1=1; div2=line[l].div-div1; }
    if(div2<1) { div2=1; div1=line[l].div-div2; }
    line[l_nr[0]].div=div1;
    line[l_nr[1]].div=div2;
     printf("2 ltot:%lf l1:%lf ldiv:%d div1:%d div2:%d\n", ltot,l1,line[l].div,div1,div2); 
    rep(l_nr[0]);
    rep(l_nr[1]);
  }
  return(1);
}


#define MAX_CLOSE_TRI 10

void pre_split( unsigned char *record)
{
  int  length, e,i,j=0,k,n,p,ll,l,ss,s, setNr, trgtNr, mode;
  unsigned char setname[MAX_LINE_LENGTH], targetname[MAX_LINE_LENGTH], name[MAX_LINE_LENGTH];
  double pl[2][3],ps[3][3], pc[3], psplt[10][3], vproj[3], offset=0., dist=0., dist2=0., lp0p1, lps, ltot;
  double pt1[3], pt2[3], pt3[3], vs[3];
  double cg_edge[3][3];

  int p1_nr, p2_nr, ps_nr, l_nr[2], sum_psplt;

  Rsort *rsort=NULL;
  typedef struct {
    double p1[3];
    double p2[3];
    double p3[3];
    double cg[3];
  } Tri;
  Tri *tri=NULL;
  int sum_tri;
  float dx,dy,dz;

  int   setdep, setind;



  length = sscanf( record,"%s %s", setname, targetname );

  operateAlias( setname, "se" );
  setNr=getSetNr( setname );
  if (setNr<0)
  {
    errMsg(" ERROR: Set (%s) is undefined\n", setname );
    return;
  }

  operateAlias( targetname, "se" );
  trgtNr=getSetNr( targetname );
  if (trgtNr<0)
  {
    errMsg(" ERROR: Set (%s) is undefined\n", targetname );
    return;
  }

  delSet(specialset->dep );
  delSet(specialset->ind );

  /* cycle through all entities of setNr and add them to the special set  */
  /* cyrcle through all bodys and add  */
  if( (setdep=pre_seta( specialset->dep, "i", 0 )) <0 ) return;
  for (i=0; i<set[setNr].anz_b; i++)
  {
    seta( setdep, "b", set[setNr].body[i] );
  }
  /* cyrcle through all surfs and add  */
  for (i=0; i<set[setNr].anz_s; i++)
  {
    seta( setdep, "s", set[setNr].surf[i] );
  }
  /* cyrcle through all lcmbs and add  */
  for (i=0; i<set[setNr].anz_c; i++)
  {
    seta( setdep, "c", set[setNr].lcmb[i] );
  }
  /* cyrcle through all lines and add  */
  for (i=0; i<set[setNr].anz_l; i++)
  {
    seta( setdep, "l", set[setNr].line[i] );
  }
  for (i=0; i<set[setNr].anz_p; i++)
  {
    seta( setdep, "p", set[setNr].pnt[i] );
  }
  /* second cycle through all entities and add lower ones  to the special set  */
  completeSet( specialset->dep, "do") ;


  /* cycle through all entities of targetNr and add them to the special set  */
  /* cyrcle through all bodies and add  */
  if( (setind=pre_seta( specialset->ind, "i", 0 )) <0 ) return;
  for (i=0; i<set[trgtNr].anz_b; i++)
  {
    seta( setind, "b", set[trgtNr].body[i] );
  }
  /* cyrcle through all surfs and add  */
  for (i=0; i<set[trgtNr].anz_s; i++)
  {
    seta( setind, "s", set[trgtNr].surf[i] );
  }
  /* cyrcle through all lcmbs and add  */
  for (i=0; i<set[trgtNr].anz_c; i++)
  {
    seta( setind, "c", set[trgtNr].lcmb[i] );
  }
  /* cyrcle through all lines and add  */
  for (i=0; i<set[trgtNr].anz_l; i++)
  {
    seta( setind, "l", set[trgtNr].line[i] );
  }
  /* cyrcle through all lines and add  */
  for (i=0; i<set[trgtNr].anz_p; i++)
  {
    seta( setind, "p", set[trgtNr].pnt[i] );
  }
  /* second cycle through all entities and add lower ones to the special set  */
  completeSet( specialset->ind, "do") ;

  setNr=setdep;
  trgtNr=setind;


  /* target needs surfs */
  if( set[trgtNr].anz_s == 0) 
  {
    errMsg(" ERROR: Set (%s) does not have lines, surfaces or a triangle-mesh\n", targetname );
    return;
  }

  /* fill all unfilled surfaces */
  for (j=0; j<set[trgtNr].anz_s; j++)
  {
    // if(surf[set[trgtNr].surf[j]].sh>-1) untrimNurs(surf[set[trgtNr].surf[j]].sh);
    if(surf[set[trgtNr].surf[j]].npgn <= 0) repSurf(set[trgtNr].surf[j]);
  }
  for (j=0; j<set[setNr].anz_s; j++)
  {
    // if(surf[set[setNr].surf[j]].sh>-1) untrimNurs(surf[set[setNr].surf[j]].sh);
    if(surf[set[setNr].surf[j]].npgn <= 0) repSurf(set[setNr].surf[j]);
  }


  /* 1) split all lines */

  /* go over all splitting-surfs */
  for (ss=0; ss<set[trgtNr].anz_s; ss++)
  {
    s=set[trgtNr].surf[ss];
    /* go over all splitting-tri */
    n=0;
    while((surf[s].npgn-n))
    {
      /* requires that only triangles are used for the interiour description of the surface */
      /* this is regarded by the adjustFeedBack() routine */
      n+=5; /* jump over the leading bytes */
      pt1[0]=surf[s].pgn[n++]*scale->w+scale->x;
      pt1[1]=surf[s].pgn[n++]*scale->w+scale->y;
      pt1[2]=surf[s].pgn[n++]*scale->w+scale->z;
      pt2[0]=surf[s].pgn[n++]*scale->w+scale->x;
      pt2[1]=surf[s].pgn[n++]*scale->w+scale->y;
      pt2[2]=surf[s].pgn[n++]*scale->w+scale->z;
      pt3[0]=surf[s].pgn[n++]*scale->w+scale->x;
      pt3[1]=surf[s].pgn[n++]*scale->w+scale->y;
      pt3[2]=surf[s].pgn[n++]*scale->w+scale->z;

      /* go over all lines and calculate the split-point */
      for (ll=0; ll<set[setNr].anz_l; ll++)
      {
        l=set[setNr].line[ll];
        /* printf("check line:%s\n", line[l].name); */

        /* store the line-dots in an array of points */
        /* the original coordinates are used  */
        lps=0.;
        ltot=calcLineLength(l);
        pl[0][0]=line[l].ip[0]*scale->w+scale->x;
        pl[0][1]=line[l].ip[1]*scale->w+scale->y;
        pl[0][2]=line[l].ip[2]*scale->w+scale->z;
        for (p=3; p<line[l].nip; p+=3)
        {
          pl[1][0]=line[l].ip[p]*scale->w+scale->x;
          pl[1][1]=line[l].ip[p+1]*scale->w+scale->y;
          pl[1][2]=line[l].ip[p+2]*scale->w+scale->z;
    
          /* The embedded triangles of the surfaces are used as a target */
          /* determine the position where the vector vproj between two line-dots meets the triangles */
          /* and determine if the position is inside the triangle */
          vproj[0]=pl[1][0]-pl[0][0];
          vproj[1]=pl[1][1]-pl[0][1];
          vproj[2]=pl[1][2]-pl[0][2];
          lp0p1=v_betrag( vproj );
          /*
          printf("pl: %lf %lf %lf\n",pl[0][0],pl[0][1],pl[0][2]);
          printf("v: %lf %lf %lf\n",vproj[0],vproj[1],vproj[2]);
          printf("pt1: %lf %lf %lf\n",pt1[0],pt1[1],pt1[2] );
          printf("pt2: %lf %lf %lf\n",pt2[0],pt2[1],pt2[2] );
          printf("pt3: %lf %lf %lf\n",pt3[0],pt3[1],pt3[2] );
          */
          dist=v_distA(  pt1, pt2, pt3, pl[0], vproj);
          dist2=v_distA(  pt1, pt2, pt3, pl[1], vproj);

          /* create a point only if the vector goes through the tri and if the sign of dist has changed (scip the first line-vector (p==3))*/
	  /* printf("nip:%d dist2:%lf dist:%lf p:%d \n",line[l].nip, dist2, dist, p); */
          if (( dist != -1.e10 ) && ( dist2 != -1.e10 ) && (dist2*dist < 0.))
          {
            /* split-point */
            v_norm( vproj, pc );
            vs[0]=pc[0]*(dist+offset);
            vs[1]=pc[1]*(dist+offset);
            vs[2]=pc[2]*(dist+offset);
            psplt[0][0]=pl[0][0]+vs[0];
            psplt[0][1]=pl[0][1]+vs[1];
            psplt[0][2]=pl[0][2]+vs[2];
            lp0p1=v_betrag( vs );
            lps+=lp0p1;

            /* split line only if its end-points are more than gtol away */
            mode=0;
            dx=psplt[0][0]-(point[line[l].p1].px*scale->w+scale->x);
            dy=psplt[0][1]-(point[line[l].p1].py*scale->w+scale->y);
            dz=psplt[0][2]-(point[line[l].p1].pz*scale->w+scale->z);
            if(sqrt(dx*dx+dy*dy+dz*dz)<gtol) mode=1;
	    /* printf("d1:%lf gtol:%lf\n", sqrt(dx*dx+dy*dy+dz*dz),gtol); */
            if(!mode)
	    {
              printf("a create point:%s %lf %lf %lf\n", name, psplt[0][0], psplt[0][1], psplt[0][2] );
              dx=psplt[0][0]-(point[line[l].p2].px*scale->w+scale->x);
              dy=psplt[0][1]-(point[line[l].p2].py*scale->w+scale->y);
              dz=psplt[0][2]-(point[line[l].p2].pz*scale->w+scale->z);
              if(sqrt(dx*dx+dy*dy+dz*dz)<gtol) mode=1;
	      /* printf("d2:%lf gtol:%lf\n", sqrt(dx*dx+dy*dy+dz*dz),gtol); */
	    }
            if(!mode)
	    {
              getNewName( name, "p" );
              printf(" create point:%s %lf %lf %lf\n", name, psplt[0][0], psplt[0][1], psplt[0][2] );
              ps_nr  = pnt( name, psplt[0][0], psplt[0][1], psplt[0][2], 1 );
  
              /* create two new lines l_nr */
              splitLine(l, l_nr, ps_nr, lps/ltot);
              seta(setNr, "l", l_nr[0]);
              seta(setNr, "l", l_nr[1]);
  
              /* untersuche alle lcmbs ob linbuf ein Mitglied ist */
              for (i=0; i<anzGeo->c; i++)
              {
                for (j=0; j<lcmb[i].nl; j++)
                {
                  if( l == lcmb[i].l[j] )
                  {
                     printf (" realloc lcmb:%s and replace line:%s with %s and %s \n",
                       lcmb[i].name, line[l].name,line[l_nr[0]].name, line[l_nr[1]].name );
                    if ((lcmb[i].o = (unsigned char *)realloc( (unsigned char *)lcmb[i].o, (lcmb[i].nl+1)*sizeof(unsigned char)) ) == NULL )
                    { printf("\n\n ERROR: realloc failure in qspl, lcmb.o:%s not changed\n\n",lcmb[i].name ); return; }
                    if ((lcmb[i].l = (int *)realloc( (int *)lcmb[i].l, (lcmb[i].nl+1)*sizeof(int)) ) == NULL )
                    { printf("\n\n ERROR: realloc failure in qspl, lcmb.l:%s not changed\n\n", lcmb[i].name); return; }
  
                    /* umspeichern der linien beginnend bei der letzten bis einschlieslich j */
                    for (k=lcmb[i].nl; k>j; k--)
            	    {
                      lcmb[i].o[k]=lcmb[i].o[k-1];
                      lcmb[i].l[k]=lcmb[i].l[k-1];
                    }
  
                    /* Auffuellen der j, j+1 pos. mit l1, l2 mit der Orientierung der gesplitteten linie */
                    lcmb[i].o[j]=lcmb[i].o[j+1];
                    lcmb[i].l[j]=l_nr[0];
                    lcmb[i].o[j+1]=lcmb[i].o[j];
                    lcmb[i].l[j+1]=l_nr[1];
                    lcmb[i].nl++;
                  }
                }
              }

              /* untersuche alle surfs ob linbuf ein Mitglied ist und ersetze sie durch eine lcmb */
              /* kontrolliere ob nicht schon eine geeignete lcmb existiert */
              for (i=0; i<anzGeo->s; i++)
              {
                for (j=0; j<surf[i].nl; j++)
                {
                  if(( l == surf[i].l[j] )&&( surf[i].typ[j]=='l' ))
                  {
                    /* do we already have a suitable lcmb? */
                    for (k=0; k<anzGeo->c; k++ )
            	    {
                      if (lcmb[k].nl==2)   /* same amount of lines */
            	      {
            	        /*
                        printf ("check lcmb:%s \n", lcmb[k].name);
            	        */
                        if (((lcmb[k].l[0]==l_nr[0])||(lcmb[k].l[0]==l_nr[1])) && ((lcmb[k].l[1]==l_nr[0])||(lcmb[k].l[1]==l_nr[1])))
            	        {
            	          /*
                          printf ("equal:%s\n",lcmb[k].name);
            	          */
                          break;
            	        }
            	      }
                    }
                    if (k>=anzGeo->c)  /* no lcmb was found, so create one */
                    {
                      /* create lcmb */
                      getNewName( name, "c" );
                      lcmb_i( name, (int)0, (int)2, "++", l_nr );
                      k=getLcmbNr( name );
                    }
                    printf ("realloc surf:%s and replace line:%s with lcmb:%s made of %s and %s \n",
                      surf[i].name, line[l].name, name, line[l_nr[0]].name, line[l_nr[1]].name );
                    if (k>-1) { surf[i].l[j]=k; surf[i].o[j]='+'; surf[i].typ[j]='c'; }
                    else { errMsg("lcmb not known, surface could not be changed \n"); return; }
                  }
                }
              }
              /* delete basic-line */
              delLine( 1, &l );
              /* decrease ll because nr-of-lines in line-set "setNr" is reduced by line "l", next line is now on pos of "l" */ 
              ll--;

	    }
          }
          lps+=lp0p1;
          pl[0][0]=pl[1][0];
          pl[0][1]=pl[1][1];
          pl[0][2]=pl[1][2];
        }
      }
    }
  }


  /* 2) split all surfaces */

  /* generate an array of all splitting triangles tri*/
  /* go over all splitting-surfs */
  sum_tri=0;
  for (ss=0; ss<set[trgtNr].anz_s; ss++)
  {
    s=set[trgtNr].surf[ss];

    /* create an array of sorted tri which might split the surfaces */
    /* go over all tri */
    n=0;
    while((surf[s].npgn-n))
    {
      /* alloc a new tri */
      if ( (tri = (Tri *)realloc( (Tri *)tri, (sum_tri+2) * sizeof(Tri))) == NULL )
      {
        errMsg("\nERROR: realloc failed in pre_split() \n\n");
      }

      /* requires that only triangles are used for the interiour description of the surface */
      /* this is regarded by the adjustFeedBack() routine */
      n+=5; /* jump over the leading bytes */
      tri[sum_tri].p1[0]=surf[s].pgn[n++]*scale->w+scale->x;
      tri[sum_tri].p1[1]=surf[s].pgn[n++]*scale->w+scale->y;
      tri[sum_tri].p1[2]=surf[s].pgn[n++]*scale->w+scale->z;
      tri[sum_tri].p2[0]=surf[s].pgn[n++]*scale->w+scale->x;
      tri[sum_tri].p2[1]=surf[s].pgn[n++]*scale->w+scale->y;
      tri[sum_tri].p2[2]=surf[s].pgn[n++]*scale->w+scale->z;
      tri[sum_tri].p3[0]=surf[s].pgn[n++]*scale->w+scale->x;
      tri[sum_tri].p3[1]=surf[s].pgn[n++]*scale->w+scale->y;
      tri[sum_tri].p3[2]=surf[s].pgn[n++]*scale->w+scale->z;

      /* "cg" of tri       */
      tri[sum_tri].cg[0]=(tri[sum_tri].p1[0]+tri[sum_tri].p2[0]+tri[sum_tri].p3[0])*.333;
      tri[sum_tri].cg[1]=(tri[sum_tri].p1[1]+tri[sum_tri].p2[1]+tri[sum_tri].p3[1])*.333;
      tri[sum_tri].cg[2]=(tri[sum_tri].p1[2]+tri[sum_tri].p2[2]+tri[sum_tri].p3[2])*.333;

      sum_tri++;
    }
  }

  /* go over all surfs which should be splitted (opposite to the lines-procedere) */
  /* and create the split-points */
  for (ss=0; ss<set[setNr].anz_s; ss++)
  {
    s=set[setNr].surf[ss];
    /* go over all tri */
    n=0;
    while((surf[s].npgn-n))
    {
      /* requires that only triangles are used for the interiour description of the surface */
      /* this is regarded by the adjustFeedBack() routine */
      n+=5; /* jump over the leading bytes */
      ps[0][0]=surf[s].pgn[n++]*scale->w+scale->x;
      ps[0][1]=surf[s].pgn[n++]*scale->w+scale->y;
      ps[0][2]=surf[s].pgn[n++]*scale->w+scale->z;
      ps[1][0]=surf[s].pgn[n++]*scale->w+scale->x;
      ps[1][1]=surf[s].pgn[n++]*scale->w+scale->y;
      ps[1][2]=surf[s].pgn[n++]*scale->w+scale->z;
      ps[2][0]=surf[s].pgn[n++]*scale->w+scale->x;
      ps[2][1]=surf[s].pgn[n++]*scale->w+scale->y;
      ps[2][2]=surf[s].pgn[n++]*scale->w+scale->z;

      /* "cg" of tri-edges */
      cg_edge[0][0]=(ps[0][0]+ps[1][0])*.5;
      cg_edge[0][1]=(ps[0][1]+ps[1][1])*.5;
      cg_edge[0][2]=(ps[0][2]+ps[1][2])*.5;

      cg_edge[1][0]=(ps[1][0]+ps[2][0])*.5;
      cg_edge[1][1]=(ps[1][1]+ps[2][1])*.5;
      cg_edge[1][2]=(ps[1][2]+ps[2][2])*.5;

      cg_edge[2][0]=(ps[2][0]+ps[0][0])*.5;
      cg_edge[2][1]=(ps[2][1]+ps[0][1])*.5;
      cg_edge[2][2]=(ps[2][2]+ps[0][2])*.5;

      /* go over all edges and determine the split-point */
      sum_psplt=0;
      for(e=0; e<3; e++)
      {
        /* find the closest splitting-tri */
        /* distance between line-cg and tri-cg */
        if ( (rsort = (Rsort *)realloc((Rsort *)rsort, (sum_tri+1) * sizeof(Rsort))) == NULL )
          printf("ERROR: realloc failed: Rsort\n\n" );
        for(i=0; i<sum_tri; i++)
        {
          dx=tri[i].cg[0]-cg_edge[e][0];
          dy=tri[i].cg[1]-cg_edge[e][1];
          dz=tri[i].cg[2]-cg_edge[e][2];
          rsort[i].r=dx*dx+dy*dy+dz*dz;
          rsort[i].i=i;
        }
        qsort( rsort, sum_tri, sizeof(Rsort), (void *)compareRsort );
#if TEST
        for (i=0; i<sum_tri; i++)
          printf("%d n:%d r:%lf\n", i, rsort[i].i, rsort[i].r); 
#endif
  
        /* check the closest tri for a split-point */
        if(MAX_CLOSE_TRI < sum_tri) k=MAX_CLOSE_TRI ; else k=sum_tri;
        for(i=0; i<k; i++)
        {
          /* The embedded triangles of the surfaces are used as a target */
          /* determine the position where the vector vproj between two line-dots meets the triangles */
          /* and determine if the position is inside the triangle */
          if(e==0)      { p2_nr=1; p1_nr=0; }
          else if(e==1) { p2_nr=2; p1_nr=1; }
          else          { p2_nr=0; p1_nr=2; }
          vproj[0]=ps[p2_nr][0]-ps[p1_nr][0];
          vproj[1]=ps[p2_nr][1]-ps[p1_nr][1];
          vproj[2]=ps[p2_nr][2]-ps[p1_nr][2];
          dist=v_distA(  tri[rsort[i].i].p1, tri[rsort[i].i].p2, tri[rsort[i].i].p3, ps[p1_nr], vproj);
          dist2=v_distA( tri[rsort[i].i].p1, tri[rsort[i].i].p2, tri[rsort[i].i].p3, ps[p2_nr], vproj);
  
          /* create a point only if the vector goes through the tri and if the sign of dist has changed (scip the first line-vector (p==3))*/
          //printf("tri:%d dist2:%lf dist:%lf p:%d \n",rsort[i].i, dist2, dist);
          if (( dist != -1.e10 ) && ( dist2 != -1.e10 ) && (dist2*dist < 0.))
          {
            /* split-point */
            v_norm( vproj, pc );
            psplt[sum_psplt][0]=ps[p1_nr][0]+pc[0]*(dist+offset);
            psplt[sum_psplt][1]=ps[p1_nr][1]+pc[1]*(dist+offset);
            psplt[sum_psplt][2]=ps[p1_nr][2]+pc[2]*(dist+offset);
            sum_psplt++;
            break;
	  }
    	}
      }

      /* create split-point inside the surface-tri */
      if(sum_psplt==2)
      {
        pc[0]=(psplt[0][0]+psplt[1][0])*.5;
        pc[1]=(psplt[0][1]+psplt[1][1])*.5;
        pc[2]=(psplt[0][2]+psplt[1][2])*.5;
        getNewName( name, "p" );
        printf(" create point:%s %lf %lf %lf\n", name, pc[0], pc[1], pc[2] );
        ps_nr  = pnt( name, pc[0], pc[1], pc[2], 1 );
      }
    }
  }

  /* split-points are created, create a new line */
  /* tbd */

  /* lines are created, create new surfaces */
  /* tbd */
  free(tri);
  free(rsort);
  delSet(specialset->dep);
  delSet(specialset->ind);
}


void fixMidsideNodes( unsigned char *setname, unsigned char *parameter)
{
  int i,n,f,k,n1,n2,nm;
  int nodseq_he20[]={0,8,1,1,9,2,2,10,3,3,11,0, 4,16,5,5,17,6,6,18,7,7,19,4, 0,12,4,1,13,5,2,14,6,3,15,7};
  int nodseq_pe15[]={0,6,1,1,7,2,2,10,0, 3,12,4,4,13,5,5,14,0, 0,9,3,1,8,4,2,11,5};
  int nodseq_te10[]={0,4,1,1,5,2,2,6,0, 0,7,3,1,8,3,2,9,3};

  int   setNr, mode=0, *facenod=NULL,ipuf=0;

  setNr=getSetNr(setname);

  if (setNr<0)
  {
    if(printFlag) printf (" delSet: set:%s does not exist\n", setname);
    return;
  }

  if(compare(parameter,"lin",2)==2)
  {
    mode=1;
    if( (facenod=(int *)calloc( (anz->nmax+1),sizeof(int) ) )==NULL)
    { printf(" ERROR: realloc failure in fixMidsideNodes\n\n" ); return; }
    for (f=0; f<anz->f; f++)
    {
      if (face[f].type == 7) ipuf = 3;  /* TRI3 */
      else if (face[f].type== 8) ipuf = 6;  /* TRI6  */
      else if (face[f].type == 9) ipuf = 4;  /* QU4 */
      else if (face[f].type == 10) ipuf = 8;  /* QU4 */
      else ipuf=0;

      for( i=0; i<ipuf; i++)
      {
        facenod[face[f].nod[i]]=1;
      }
    }
  }
  for(k=0; k<set[setNr].anz_e; k++)
  {
    /* go over the dep elem and corr midside nodes */
    for (k=0; k<set[setNr].anz_e; k++)
    {
      if      (e_enqire[set[setNr].elem[k]].type == 4)
      {
        for (n=0; n<12; n++)
        {
          n1=e_enqire[set[setNr].elem[k]].nod[nodseq_he20[n*3]];
          nm=e_enqire[set[setNr].elem[k]].nod[nodseq_he20[n*3+1]];
          n2=e_enqire[set[setNr].elem[k]].nod[nodseq_he20[n*3+2]];
          if((mode)&&(facenod[nm]==1)) adjustMidsideNode( &node[n1].nx, &node[n2].nx, &node[nm].nx, 0);
          else adjustMidsideNode( &node[n1].nx, &node[n2].nx, &node[nm].nx, mode);
        }
      }
      else if (e_enqire[set[setNr].elem[k]].type == 5)
      {
        for (n=0; n<9; n++)
        {
          n1=e_enqire[set[setNr].elem[k]].nod[nodseq_pe15[n*3]];
          nm=e_enqire[set[setNr].elem[k]].nod[nodseq_pe15[n*3+1]];
          n2=e_enqire[set[setNr].elem[k]].nod[nodseq_pe15[n*3+2]];
          if((mode)&&(facenod[nm]==1)) adjustMidsideNode( &node[n1].nx, &node[n2].nx, &node[nm].nx, 0); 
          adjustMidsideNode( &node[n1].nx, &node[n2].nx, &node[nm].nx, mode);
        }
      }
      else if (e_enqire[set[setNr].elem[k]].type == 6)
      {
        for (n=0; n<6; n++)
        {
          n1=e_enqire[set[setNr].elem[k]].nod[nodseq_te10[n*3]];
          nm=e_enqire[set[setNr].elem[k]].nod[nodseq_te10[n*3+1]];
          n2=e_enqire[set[setNr].elem[k]].nod[nodseq_te10[n*3+2]];
          if((mode)&&(facenod[nm]==1)) adjustMidsideNode( &node[n1].nx, &node[n2].nx, &node[nm].nx, 0); 
          adjustMidsideNode( &node[n1].nx, &node[n2].nx, &node[nm].nx, mode);
        }
      }
    }
  }
  free(facenod);
}


void pre_proj( unsigned char *record)
{
#define INTPOLMODE  0 /* linear */
#define CLOSE_TRIS 100

  int  length, i,j=0,n,e,p,s,ss, setNr, trgtNr, setNrbuf, setNoProj, mode, csys[3], surfFlag=0, normFlag=0;
  int anz_n=0;
  unsigned char setname[MAX_LINE_LENGTH], targetname[MAX_LINE_LENGTH], action[MAX_LINE_LENGTH], name[MAX_LINE_LENGTH];
  unsigned char axis;
  double pr[3], pc[3], nr[3], pa1[3], pa2[3], pa3[3], ps1[3], ps2[3], vproj[3],v1[3],v2[3], offset=0., dist, mindist=0;
  int  minj=0, close_tris=0;
  double pt1[3], pt2[3], pt3[3], rp, rs1, rs2, rmax, rmin;
  double *nx=NULL;
  double *nrad=NULL;
  int  *nmissed=NULL;

  unsigned char pkt1[MAX_LINE_LENGTH], pkt2[MAX_LINE_LENGTH];
  int   pnr1, pnr2, setdep, setind;
  double x, y, z, dx,dy,dz, l, h, q, l_offs, h_offs, q_offs;
  double p1[3], p2[3], p1p2[3];
  double el[3], eh[3], eq[3];   /* xyz koordinaten der lhq vektoren */
  double ex[3], ey[3], ez[3];   /* lhq koordinaten der xyz vektoren */

  Rsort *rsort=NULL;
  typedef struct {
    double p1[3];
    double p2[3];
    double p3[3];
    double cg[3];
    int fnr;
  } Tri;
  Tri *tri=NULL;
  int sum_tri=0;

  Points    *pproj=NULL;
  int sum_pproj;

  length = sscanf( record,"%s %s %s", setname, targetname, action );
  operateAlias( setname, "se" );
  setNr=getSetNr( setname );
  if (setNr<0)
  {
    errMsg(" ERROR: Set (%s) is undefined\n", setname );
    return;
  }

  operateAlias( targetname, "se" );
  trgtNr=getSetNr( targetname );
  if (trgtNr<0)
  {
    errMsg(" ERROR: Set (%s) is undefined\n", targetname );
    return;
  }

  delSet(specialset->dep );
  delSet(specialset->ind );

  /* cycle through all entities of setNr and add them to the special set  */
  /* cyrcle through all bodys and add  */
  if( (setdep=pre_seta( specialset->dep, "i", 0 )) <0 ) return;
  for (i=0; i<set[setNr].anz_n; i++)
  {
    seta( setdep, "n", set[setNr].node[i] );
  }
  /* add all related elements for a later midside-node-correction */
  completeSet( specialset->dep, "up") ;

  for (i=0; i<set[setNr].anz_b; i++)
  {
    seta( setdep, "b", set[setNr].body[i] );
  }
  /* cyrcle through all surfs and add  */
  for (i=0; i<set[setNr].anz_s; i++)
  {
    seta( setdep, "s", set[setNr].surf[i] );
  }
  /* cyrcle through all lcmbs and add  */
  for (i=0; i<set[setNr].anz_c; i++)
  {
    seta( setdep, "c", set[setNr].lcmb[i] );
  }
  /* cyrcle through all lines and add  */
  for (i=0; i<set[setNr].anz_l; i++)
  {
    seta( setdep, "l", set[setNr].line[i] );
  }
  for (i=0; i<set[setNr].anz_p; i++)
  {
    seta( setdep, "p", set[setNr].pnt[i] );
  }
  /* second cycle through all entities and add lower ones  to the special set  */
  // completeSet( specialset->dep, "do") ;


  /* cycle through all entities of targetNr and add them to the special set  */
  /* cyrcle through all bodies and add  */
  if( (setind=pre_seta( specialset->ind, "i", 0 )) <0 ) return;
  for (i=0; i<set[trgtNr].anz_s; i++)
  {
    seta( setind, "s", set[trgtNr].surf[i] );
  }
  for (i=0; i<set[trgtNr].anz_l; i++)
  {
    seta( setind, "l", set[trgtNr].line[i] );
  }
  for (i=0; i<set[trgtNr].anz_f; i++)
  {
    seta( setind, "f", set[trgtNr].face[i] );
  }

  if (set[setNr].anz_n==0) set[setdep].anz_n=set[setNr].anz_n;
  setNr=setdep;
  trgtNr=setind;


  /* generate an array of all points or nodes to be projected */
  /* the original coordinates must be used for radial projection to get the correct axis */
  sum_pproj=0;
  for (i=0; i<set[setNr].anz_p; i++)
  {
    p=set[setNr].pnt[i];
    if (p<0)
    {
      errMsg(" ERROR: Point-nr:%d is undefined\n", set[setNr].pnt[i] );
      goto nextpoint;
    }
    if ( (pproj = (Points *)realloc( (Points *)pproj, (sum_pproj+2) * sizeof(Points))) == NULL )
    {
      errMsg("\nERROR: realloc failed in pre_proj() \n\n");
    }
    pproj[sum_pproj].nn=p;
    pproj[sum_pproj].name=point[p].name;
    pproj[sum_pproj].px=point[p].px*scale->w+scale->x;
    pproj[sum_pproj].py=point[p].py*scale->w+scale->y;
    pproj[sum_pproj].pz=point[p].pz*scale->w+scale->z;
    sum_pproj++;
  }
  for (i=0; i<set[setNr].anz_n; i++)
  {
    n=set[setNr].node[i];
    if ( (pproj = (Points *)realloc( (Points *)pproj, (sum_pproj+2) * sizeof(Points))) == NULL )
    {
      errMsg("\nERROR: realloc failed in pre_proj() \n\n");
    }
    pproj[sum_pproj].nn=-n;
    sprintf(name,"%d",n);
    if((pproj[sum_pproj].name= (unsigned char *)malloc((strlen(name)+1)*sizeof(unsigned char))) == NULL )
    { printf("ERROR: malloc failed\n\n" ); return; }
    strcpy(pproj[sum_pproj].name,name);
    pproj[sum_pproj].px=node[n].nx*scale->w+scale->x;
    pproj[sum_pproj].py=node[n].ny*scale->w+scale->y;
    pproj[sum_pproj].pz=node[n].nz*scale->w+scale->z;
    sum_pproj++;
  }

  /* fill all unfilled surfaces */
  anz_n=0;
  for (j=0; j<set[trgtNr].anz_s; j++)
  {
    orientSet( set[trgtNr].name );
    if(surf[set[trgtNr].surf[j]].sh>-1) { repNurs(surf[set[trgtNr].surf[j]].sh); untrimNurs(surf[set[trgtNr].surf[j]].sh); }
    repSurf(set[trgtNr].surf[j]);
    anz_n+=surf[set[trgtNr].surf[j]].npgn/8;
  }

  /* generate an array of all target-triangles tri*/
  /* go over all surfs */
  sum_tri=0;
  for (ss=0; ss<set[trgtNr].anz_s; ss++)
  {
    s=set[trgtNr].surf[ss];

    /* go over all tri */
    n=0;
    while((surf[s].npgn-n))
    {
      /* alloc a new tri */
      if ( (tri = (Tri *)realloc( (Tri *)tri, (sum_tri+2) * sizeof(Tri))) == NULL )
      {
        errMsg("\nERROR: realloc failed in pre_proj() \n\n");
      }

      /* requires that only triangles are used for the interiour description of the surface */
      /* this is regarded by the adjustFeedBack() routine */
      n+=5; /* jump over the leading bytes */
      tri[sum_tri].p1[0]=surf[s].pgn[n++]*scale->w+scale->x;
      tri[sum_tri].p1[1]=surf[s].pgn[n++]*scale->w+scale->y;
      tri[sum_tri].p1[2]=surf[s].pgn[n++]*scale->w+scale->z;
      tri[sum_tri].p2[0]=surf[s].pgn[n++]*scale->w+scale->x;
      tri[sum_tri].p2[1]=surf[s].pgn[n++]*scale->w+scale->y;
      tri[sum_tri].p2[2]=surf[s].pgn[n++]*scale->w+scale->z;
      tri[sum_tri].p3[0]=surf[s].pgn[n++]*scale->w+scale->x;
      tri[sum_tri].p3[1]=surf[s].pgn[n++]*scale->w+scale->y;
      tri[sum_tri].p3[2]=surf[s].pgn[n++]*scale->w+scale->z;
      tri[sum_tri].fnr= -1;
      sum_tri++;
    }
  }
  for (ss=0; ss<set[trgtNr].anz_f; ss++)
  {
    i=set[trgtNr].face[ss];

    if (face[i].type == 7)  /* TRI3  */
    {
      if ( (tri = (Tri *)realloc( (Tri *)tri, (sum_tri+2) * sizeof(Tri))) == NULL )
        errMsg("\nERROR: realloc failed in pre_proj() \n\n");
      tri[sum_tri].p1[0]=node[face[i].nod[0]].nx*scale->w+scale->x;
      tri[sum_tri].p1[1]=node[face[i].nod[0]].ny*scale->w+scale->y;
      tri[sum_tri].p1[2]=node[face[i].nod[0]].nz*scale->w+scale->z;
      tri[sum_tri].p2[0]=node[face[i].nod[1]].nx*scale->w+scale->x;
      tri[sum_tri].p2[1]=node[face[i].nod[1]].ny*scale->w+scale->y;
      tri[sum_tri].p2[2]=node[face[i].nod[1]].nz*scale->w+scale->z;
      tri[sum_tri].p3[0]=node[face[i].nod[2]].nx*scale->w+scale->x;
      tri[sum_tri].p3[1]=node[face[i].nod[2]].ny*scale->w+scale->y;
      tri[sum_tri].p3[2]=node[face[i].nod[2]].nz*scale->w+scale->z;
      tri[sum_tri].fnr= i;
      sum_tri++;
    }
    else if (face[i].type == 8)  /* TRI6  */
    {
      if ( (tri = (Tri *)realloc( (Tri *)tri, (sum_tri+6) * sizeof(Tri))) == NULL )
        errMsg("\nERROR: realloc failed in pre_proj() \n\n");
      tri[sum_tri].p1[0]=node[face[i].nod[0]].nx*scale->w+scale->x;
      tri[sum_tri].p1[1]=node[face[i].nod[0]].ny*scale->w+scale->y;
      tri[sum_tri].p1[2]=node[face[i].nod[0]].nz*scale->w+scale->z;
      tri[sum_tri].p2[0]=node[face[i].nod[3]].nx*scale->w+scale->x;
      tri[sum_tri].p2[1]=node[face[i].nod[3]].ny*scale->w+scale->y;
      tri[sum_tri].p2[2]=node[face[i].nod[3]].nz*scale->w+scale->z;
      tri[sum_tri].p3[0]=node[face[i].nod[5]].nx*scale->w+scale->x;
      tri[sum_tri].p3[1]=node[face[i].nod[5]].ny*scale->w+scale->y;
      tri[sum_tri].p3[2]=node[face[i].nod[5]].nz*scale->w+scale->z;
      sum_tri++;
      tri[sum_tri].p1[0]=node[face[i].nod[2]].nx*scale->w+scale->x;
      tri[sum_tri].p1[1]=node[face[i].nod[2]].ny*scale->w+scale->y;
      tri[sum_tri].p1[2]=node[face[i].nod[2]].nz*scale->w+scale->z;
      tri[sum_tri].p2[0]=node[face[i].nod[5]].nx*scale->w+scale->x;
      tri[sum_tri].p2[1]=node[face[i].nod[5]].ny*scale->w+scale->y;
      tri[sum_tri].p2[2]=node[face[i].nod[5]].nz*scale->w+scale->z;
      tri[sum_tri].p3[0]=node[face[i].nod[4]].nx*scale->w+scale->x;
      tri[sum_tri].p3[1]=node[face[i].nod[4]].ny*scale->w+scale->y;
      tri[sum_tri].p3[2]=node[face[i].nod[4]].nz*scale->w+scale->z;
      sum_tri++;
      tri[sum_tri].p1[0]=node[face[i].nod[4]].nx*scale->w+scale->x;
      tri[sum_tri].p1[1]=node[face[i].nod[4]].ny*scale->w+scale->y;
      tri[sum_tri].p1[2]=node[face[i].nod[4]].nz*scale->w+scale->z;
      tri[sum_tri].p2[0]=node[face[i].nod[5]].nx*scale->w+scale->x;
      tri[sum_tri].p2[1]=node[face[i].nod[5]].ny*scale->w+scale->y;
      tri[sum_tri].p2[2]=node[face[i].nod[5]].nz*scale->w+scale->z;
      tri[sum_tri].p3[0]=node[face[i].nod[3]].nx*scale->w+scale->x;
      tri[sum_tri].p3[1]=node[face[i].nod[3]].ny*scale->w+scale->y;
      tri[sum_tri].p3[2]=node[face[i].nod[3]].nz*scale->w+scale->z;
      sum_tri++;
      tri[sum_tri].p1[0]=node[face[i].nod[3]].nx*scale->w+scale->x;
      tri[sum_tri].p1[1]=node[face[i].nod[3]].ny*scale->w+scale->y;
      tri[sum_tri].p1[2]=node[face[i].nod[3]].nz*scale->w+scale->z;
      tri[sum_tri].p2[0]=node[face[i].nod[1]].nx*scale->w+scale->x;
      tri[sum_tri].p2[1]=node[face[i].nod[1]].ny*scale->w+scale->y;
      tri[sum_tri].p2[2]=node[face[i].nod[1]].nz*scale->w+scale->z;
      tri[sum_tri].p3[0]=node[face[i].nod[4]].nx*scale->w+scale->x;
      tri[sum_tri].p3[1]=node[face[i].nod[4]].ny*scale->w+scale->y;
      tri[sum_tri].p3[2]=node[face[i].nod[4]].nz*scale->w+scale->z;
      sum_tri++;
    }
    else if (face[i].type == 9)  /* QUAD4 */
    {
      if ( (tri = (Tri *)realloc( (Tri *)tri, (sum_tri+4) * sizeof(Tri))) == NULL )
        errMsg("\nERROR: realloc failed in pre_proj() \n\n");
      tri[sum_tri].p1[0]=node[face[i].nod[0]].nx*scale->w+scale->x;
      tri[sum_tri].p1[1]=node[face[i].nod[0]].ny*scale->w+scale->y;
      tri[sum_tri].p1[2]=node[face[i].nod[0]].nz*scale->w+scale->z;
      tri[sum_tri].p2[0]=node[face[i].nod[1]].nx*scale->w+scale->x;
      tri[sum_tri].p2[1]=node[face[i].nod[1]].ny*scale->w+scale->y;
      tri[sum_tri].p2[2]=node[face[i].nod[1]].nz*scale->w+scale->z;
      tri[sum_tri].p3[0]=node[face[i].nod[3]].nx*scale->w+scale->x;
      tri[sum_tri].p3[1]=node[face[i].nod[3]].ny*scale->w+scale->y;
      tri[sum_tri].p3[2]=node[face[i].nod[3]].nz*scale->w+scale->z;
      tri[sum_tri].fnr= i;
      sum_tri++;
      tri[sum_tri].p1[0]=node[face[i].nod[3]].nx*scale->w+scale->x;
      tri[sum_tri].p1[1]=node[face[i].nod[3]].ny*scale->w+scale->y;
      tri[sum_tri].p1[2]=node[face[i].nod[3]].nz*scale->w+scale->z;
      tri[sum_tri].p2[0]=node[face[i].nod[1]].nx*scale->w+scale->x;
      tri[sum_tri].p2[1]=node[face[i].nod[1]].ny*scale->w+scale->y;
      tri[sum_tri].p2[2]=node[face[i].nod[1]].nz*scale->w+scale->z;
      tri[sum_tri].p3[0]=node[face[i].nod[2]].nx*scale->w+scale->x;
      tri[sum_tri].p3[1]=node[face[i].nod[2]].ny*scale->w+scale->y;
      tri[sum_tri].p3[2]=node[face[i].nod[2]].nz*scale->w+scale->z;
      tri[sum_tri].fnr= i;
      sum_tri++;
    }
    else if (face[i].type == 10) /* QUAD8 */
    {
      if ( (tri = (Tri *)realloc( (Tri *)tri, (sum_tri+8) * sizeof(Tri))) == NULL )
        errMsg("\nERROR: realloc failed in pre_proj() \n\n");
      tri[sum_tri].p1[0]=node[face[i].nod[8]].nx*scale->w+scale->x;
      tri[sum_tri].p1[1]=node[face[i].nod[8]].ny*scale->w+scale->y;
      tri[sum_tri].p1[2]=node[face[i].nod[8]].nz*scale->w+scale->z;
      tri[sum_tri].p2[0]=node[face[i].nod[0]].nx*scale->w+scale->x;
      tri[sum_tri].p2[1]=node[face[i].nod[0]].ny*scale->w+scale->y;
      tri[sum_tri].p2[2]=node[face[i].nod[0]].nz*scale->w+scale->z;
      tri[sum_tri].p3[0]=node[face[i].nod[4]].nx*scale->w+scale->x;
      tri[sum_tri].p3[1]=node[face[i].nod[4]].ny*scale->w+scale->y;
      tri[sum_tri].p3[2]=node[face[i].nod[4]].nz*scale->w+scale->z;
      sum_tri++;
      tri[sum_tri].p1[0]=node[face[i].nod[8]].nx*scale->w+scale->x;
      tri[sum_tri].p1[1]=node[face[i].nod[8]].ny*scale->w+scale->y;
      tri[sum_tri].p1[2]=node[face[i].nod[8]].nz*scale->w+scale->z;
      tri[sum_tri].p2[0]=node[face[i].nod[4]].nx*scale->w+scale->x;
      tri[sum_tri].p2[1]=node[face[i].nod[4]].ny*scale->w+scale->y;
      tri[sum_tri].p2[2]=node[face[i].nod[4]].nz*scale->w+scale->z;
      tri[sum_tri].p3[0]=node[face[i].nod[1]].nx*scale->w+scale->x;
      tri[sum_tri].p3[1]=node[face[i].nod[1]].ny*scale->w+scale->y;
      tri[sum_tri].p3[2]=node[face[i].nod[1]].nz*scale->w+scale->z;
      sum_tri++;
      tri[sum_tri].p1[0]=node[face[i].nod[8]].nx*scale->w+scale->x;
      tri[sum_tri].p1[1]=node[face[i].nod[8]].ny*scale->w+scale->y;
      tri[sum_tri].p1[2]=node[face[i].nod[8]].nz*scale->w+scale->z;
      tri[sum_tri].p2[0]=node[face[i].nod[1]].nx*scale->w+scale->x;
      tri[sum_tri].p2[1]=node[face[i].nod[1]].ny*scale->w+scale->y;
      tri[sum_tri].p2[2]=node[face[i].nod[1]].nz*scale->w+scale->z;
      tri[sum_tri].p3[0]=node[face[i].nod[5]].nx*scale->w+scale->x;
      tri[sum_tri].p3[1]=node[face[i].nod[5]].ny*scale->w+scale->y;
      tri[sum_tri].p3[2]=node[face[i].nod[5]].nz*scale->w+scale->z;
      sum_tri++;
      tri[sum_tri].p1[0]=node[face[i].nod[8]].nx*scale->w+scale->x;
      tri[sum_tri].p1[1]=node[face[i].nod[8]].ny*scale->w+scale->y;
      tri[sum_tri].p1[2]=node[face[i].nod[8]].nz*scale->w+scale->z;
      tri[sum_tri].p2[0]=node[face[i].nod[5]].nx*scale->w+scale->x;
      tri[sum_tri].p2[1]=node[face[i].nod[5]].ny*scale->w+scale->y;
      tri[sum_tri].p2[2]=node[face[i].nod[5]].nz*scale->w+scale->z;
      tri[sum_tri].p3[0]=node[face[i].nod[2]].nx*scale->w+scale->x;
      tri[sum_tri].p3[1]=node[face[i].nod[2]].ny*scale->w+scale->y;
      tri[sum_tri].p3[2]=node[face[i].nod[2]].nz*scale->w+scale->z;
      sum_tri++;
      tri[sum_tri].p1[0]=node[face[i].nod[8]].nx*scale->w+scale->x;
      tri[sum_tri].p1[1]=node[face[i].nod[8]].ny*scale->w+scale->y;
      tri[sum_tri].p1[2]=node[face[i].nod[8]].nz*scale->w+scale->z;
      tri[sum_tri].p2[0]=node[face[i].nod[2]].nx*scale->w+scale->x;
      tri[sum_tri].p2[1]=node[face[i].nod[2]].ny*scale->w+scale->y;
      tri[sum_tri].p2[2]=node[face[i].nod[2]].nz*scale->w+scale->z;
      tri[sum_tri].p3[0]=node[face[i].nod[6]].nx*scale->w+scale->x;
      tri[sum_tri].p3[1]=node[face[i].nod[6]].ny*scale->w+scale->y;
      tri[sum_tri].p3[2]=node[face[i].nod[6]].nz*scale->w+scale->z;
      sum_tri++;
      tri[sum_tri].p1[0]=node[face[i].nod[8]].nx*scale->w+scale->x;
      tri[sum_tri].p1[1]=node[face[i].nod[8]].ny*scale->w+scale->y;
      tri[sum_tri].p1[2]=node[face[i].nod[8]].nz*scale->w+scale->z;
      tri[sum_tri].p2[0]=node[face[i].nod[6]].nx*scale->w+scale->x;
      tri[sum_tri].p2[1]=node[face[i].nod[6]].ny*scale->w+scale->y;
      tri[sum_tri].p2[2]=node[face[i].nod[6]].nz*scale->w+scale->z;
      tri[sum_tri].p3[0]=node[face[i].nod[3]].nx*scale->w+scale->x;
      tri[sum_tri].p3[1]=node[face[i].nod[3]].ny*scale->w+scale->y;
      tri[sum_tri].p3[2]=node[face[i].nod[3]].nz*scale->w+scale->z;
      sum_tri++;
      tri[sum_tri].p1[0]=node[face[i].nod[8]].nx*scale->w+scale->x;
      tri[sum_tri].p1[1]=node[face[i].nod[8]].ny*scale->w+scale->y;
      tri[sum_tri].p1[2]=node[face[i].nod[8]].nz*scale->w+scale->z;
      tri[sum_tri].p2[0]=node[face[i].nod[3]].nx*scale->w+scale->x;
      tri[sum_tri].p2[1]=node[face[i].nod[3]].ny*scale->w+scale->y;
      tri[sum_tri].p2[2]=node[face[i].nod[3]].nz*scale->w+scale->z;
      tri[sum_tri].p3[0]=node[face[i].nod[7]].nx*scale->w+scale->x;
      tri[sum_tri].p3[1]=node[face[i].nod[7]].ny*scale->w+scale->y;
      tri[sum_tri].p3[2]=node[face[i].nod[7]].nz*scale->w+scale->z;
      sum_tri++;
      tri[sum_tri].p1[0]=node[face[i].nod[8]].nx*scale->w+scale->x;
      tri[sum_tri].p1[1]=node[face[i].nod[8]].ny*scale->w+scale->y;
      tri[sum_tri].p1[2]=node[face[i].nod[8]].nz*scale->w+scale->z;
      tri[sum_tri].p2[0]=node[face[i].nod[7]].nx*scale->w+scale->x;
      tri[sum_tri].p2[1]=node[face[i].nod[7]].ny*scale->w+scale->y;
      tri[sum_tri].p2[2]=node[face[i].nod[7]].nz*scale->w+scale->z;
      tri[sum_tri].p3[0]=node[face[i].nod[0]].nx*scale->w+scale->x;
      tri[sum_tri].p3[1]=node[face[i].nod[0]].ny*scale->w+scale->y;
      tri[sum_tri].p3[2]=node[face[i].nod[0]].nz*scale->w+scale->z;
      sum_tri++;
    }
  }
  if (sum_tri>CLOSE_TRIS) close_tris=CLOSE_TRIS; else close_tris=sum_tri;

  for(j=0; j<sum_tri; j++)
  {
    /* "cg" of tri       */
    tri[j].cg[0]=(tri[j].p1[0]+tri[j].p2[0]+tri[j].p3[0])/3;
    tri[j].cg[1]=(tri[j].p1[1]+tri[j].p2[1]+tri[j].p3[1])/3;
    tri[j].cg[2]=(tri[j].p1[2]+tri[j].p2[2]+tri[j].p3[2])/3;
  }

  /* project the nodes and points */
  if(getSetNr(specialset->noprj)>-1) delSet(specialset->noprj);
  if( (setNoProj=pre_seta( specialset->noprj, "i", 0 )) <0 ) return;
  if( compare( action, "rad", 3) == 3)
  {
    length = sscanf( record,"%*s %*s %*s %c %lf", &axis, &offset );
    if(length==1) offset=0.;

    /* target needs lines or surfs */
    if( set[trgtNr].anz_s == 0) 
    {
      if( set[trgtNr].anz_l > 0)
      {
        surfFlag=0;
      }
      else
      {
        errMsg(" ERROR: Set (%s) does not have lines, surfaces or a triangle-mesh\n", targetname );
        return;
      }
    }
    else 
    {
      surfFlag=1;
    }

    for (i=0; i<sum_pproj; i++)
    {
      /* the original coordinates must be used for radial projection to get the correct axis */
      pr[0]=pproj[i].px;
      pr[1]=pproj[i].py;
      pr[2]=pproj[i].pz;

      /* move the point to the line of nodes or to the surface */
      if( surfFlag)
      {
        /* The embedded triangles of the surfaces are used as a target for the projection */
        /* determine the position where the radial-ray through the point meets the triangles */
        /* and determine if the position is inside the triangle */

        if( axis=='x')
        {
          vproj[0]=0.;
          vproj[1]=pr[1];
          vproj[2]=pr[2];
	}
        if( axis=='y')
        {
          vproj[0]=pr[0];
          vproj[1]=0.;
          vproj[2]=pr[2];
	}
        if( axis=='z')
        {
          vproj[0]=pr[0];
          vproj[1]=pr[1];
          vproj[2]=0.;
	}

        /* find the closest tri */
        /* distance between point and tri-cg */
        if ( (rsort = (Rsort *)realloc((Rsort *)rsort, (sum_tri+1) * sizeof(Rsort))) == NULL )
          printf("ERROR: realloc failed: Rsort\n\n" );
        for(j=0; j<sum_tri; j++)
        {
          dx=tri[j].cg[0]-pr[0];
          dy=tri[j].cg[1]-pr[1];
          dz=tri[j].cg[2]-pr[2];
          rsort[j].r=dx*dx+dy*dy+dz*dz;
          rsort[j].i=j;
        }
        qsort( rsort, sum_tri, sizeof(Rsort), (void *)compareRsort );
#if TEST
        for (j=0; j<close_tris; j++)
          printf("%d f:%d n:%d r:%lf\n", j, tri[rsort[j].i].fnr, rsort[j].i, rsort[j].r); 
#endif

        /* check the closest tri for a split-point */
        minj=-1;mindist=MAXVALUE;
        for(j=0; j<close_tris; j++)
        {
          dist=v_distA(  tri[rsort[j].i].p1, tri[rsort[j].i].p2, tri[rsort[j].i].p3, pr, vproj);
          if(( dist != -1.e10 )&&(abs(dist)<abs(mindist)))
          {
            // printf(" found enclosing tri3:%d for point:%s, distance:%lf\n", tri[rsort[j].i].fnr, pproj[i].name, dist); 
            mindist=dist;
            minj=j;
          }
        }
        // printf(" minj:%d\n",minj);
        if( minj!=-1 )
        {
          j=minj;
          dist=v_distA(  tri[rsort[j].i].p1, tri[rsort[j].i].p2, tri[rsort[j].i].p3, pr, vproj);
          printf(" found enclosing tri3[%d] for point:%s, distance:%lf\n", j, pproj[i].name, dist); 
          /* berechne den Gradeneinheitsvektor en */
          v_norm( vproj, pc );
          pr[0]+=pc[0]*(dist+offset);
          pr[1]+=pc[1]*(dist+offset);
          pr[2]+=pc[2]*(dist+offset);
          goto foundTri3rad;
        }
        if(pproj[i].nn>-1) { printf("WARNING: no enclosing element for point:%s found\n", pproj[i].name ); pre_seta(specialset->noprj, "p",pproj[i].name ); } 
        else               { printf("WARNING: no enclosing element for node:%s found\n", pproj[i].name );  pre_seta(specialset->noprj, "n",pproj[i].name ); }
        goto nextpoint;
       foundTri3rad:;
      }
      else
      {
        /* Internal points of the target-lines are used as a target for the projection */

        /* count the internal points */
        for (j=0; j<set[trgtNr].anz_l; j++)
        {
          anz_n+=line[set[trgtNr].line[j]].nip;
	}
	anz_n/=3;

        if ( (nx = (double *)malloc( (anz_n+1) * sizeof(double))) == NULL )
        {  errMsg("\n\n ERROR: malloc failed in pre_proj()\n") ; free_proj(nx, nrad, nmissed); return; }
        if ( (nrad = (double *)malloc( (anz_n+1) * sizeof(double))) == NULL )
        {  errMsg("\n\n ERROR: malloc failed in pre_proj()\n") ; free_proj(nx, nrad, nmissed); return; }

        if( axis=='x') j=0;
        else if( axis=='y') j=1;
        else if( axis=='z') j=2;
        if( v_rec2cyl( pr, j, csys, pc) <0) goto nextpoint;

        /* move the point to the target-line */
        e=0;
        for (j=0; j<set[trgtNr].anz_l; j++)
        {
          for (n=0; n<line[set[trgtNr].line[j]].nip; n+=3)
          {
            nr[0]=line[set[trgtNr].line[j]].ip[n]*scale->w+scale->x;
            nr[1]=line[set[trgtNr].line[j]].ip[n+1]*scale->w+scale->y;
            nr[2]=line[set[trgtNr].line[j]].ip[n+2]*scale->w+scale->z;
            nx[e]=nr[csys[0]];
            nrad[e++]=sqrt(nr[csys[1]]*nr[csys[1]]+nr[csys[2]]*nr[csys[2]]);
          }
        }
        mode=INTPOLMODE; 
        pc[0]=intpol2( nx, nrad, e, pc[2], &mode )+offset;
        
        pr[csys[1]]=cos(pc[1])*pc[0];
        pr[csys[2]]=sin(pc[1])*pc[0];
      }
  
      /* redefine the point */
      pproj[i].px= pr[0];
      pproj[i].py= pr[1];
      pproj[i].pz= pr[2];
    nextpoint:;
    }
  }
  else if( compare( action, "rot", 3) == 3)
  {
    length = sscanf( record, "%*s%*s%*s%s%s%lf", pkt1, pkt2, &offset );
    if(length<3) offset=0.;
    else if(length<2) 
    {
      errMsg(" ERROR: not enough parameter specified\n");
      return;
    }
    pnr1=getPntNr( pkt1 );
    pnr2=getPntNr( pkt2 );
    if (pnr1==-1)
    {
      errMsg(" Point:%s is undefined\n", pkt1 );
      return;
    }
    if (pnr2==-1)
    {
      errMsg(" Point:%s is undefined\n", pkt2 );
      return;
    }

    /* The embedded triangles is the surfaces are used as a target for the projection */

    p1[0] = point[pnr1].px;
    p1[1] = point[pnr1].py;
    p1[2] = point[pnr1].pz;

    p2[0] = point[pnr2].px;
    p2[1] = point[pnr2].py;
    p2[2] = point[pnr2].pz;

    /* berechnung der Einheitsvektoren des Verdreh-Koordinatensystems */
    /* Exneu = p1p2/|p1p2| ist der Einheitsvektor in xneu richtung    */
    /* Eyneu = p1p2 X p1ph / |p1p2 X p1ph|     in yneu                */
    /* Ezneu = Exneu X Eyneu                   in zneu                */

    v_result( p1, p2, p1p2 );
    v_norm  ( p1p2, el );

    /* erzeuge eh, eq durch zyklische vertauschung */
    eq[0]=eh[1]=el[2];
    eq[1]=eh[2]=el[0];
    eq[2]=eh[0]=el[1];

    /* berechnung der lhq-koordinaten der xyz einheitsvektoren durch zykl.vertausch.  */
    ex[0]=el[0];
    ex[1]=eh[0];
    ex[2]=eq[0];

    ey[0]=el[1];
    ey[1]=eh[1];
    ey[2]=eq[1];

    ez[0]=el[2];
    ez[1]=eh[2];
    ez[2]=eq[2];

    /* Berechnung der lhq-koordinaten des Startpunktes der Drehachse (pnr1 ist der 0-Punkt des lhq systems) */
    x=point[pnr1].px*scale->w+scale->x;
    y=point[pnr1].py*scale->w+scale->y;
    z=point[pnr1].pz*scale->w+scale->z;
    
    l_offs=ex[0]*x+ey[0]*y+ez[0]*z;
    h_offs=ex[1]*x+ey[1]*y+ez[1]*z;
    q_offs=ex[2]*x+ey[2]*y+ez[2]*z;
    /*
    printf("el:%lf %lf %lf eh:%lf %lf %lf eq:%lf %lf %lf\n", el[0],el[1],el[2], eh[0],eh[1],eh[2], eq[0],eq[1],eq[2]);
    printf("ex:%lf %lf %lf ey:%lf %lf %lf ez:%lf %lf %lf\n", ex[0],ex[1],ex[2], ey[0],ey[1],ey[2], ez[0],ez[1],ez[2]);
    printf("xyz p1:%lf %lf %lf\n", x,y,z);
    printf("lhq p1:%lf %lf %lf\n", l_offs, h_offs, q_offs);
    */

    /* Berechnung der lhq-koordinaten aller zu drehenden punkte */
    for (i=0; i<sum_pproj; i++)
    {
      p=set[setNr].pnt[i];
      if (p==-1)
      {
        errMsg(" ERROR: Point-nr:%d is undefined\n", set[setNr].pnt[i] );
        goto nextpointrot;
      }

      x=pproj[i].px;
      y=pproj[i].py;
      z=pproj[i].pz;

      l=( ex[0]*x+ey[0]*y+ez[0]*z ) - l_offs ;   /* l (drehachse) */
      h=( ex[1]*x+ey[1]*y+ez[1]*z ) - h_offs ;   /* h */
      q=( ex[2]*x+ey[2]*y+ez[2]*z ) - q_offs ;   /* q */

      /* define a cutting plane pa by 3 points ( pa1,pa2,pa3) in the lhq system */
      pa1[0]=l;
      pa1[1]=0.;
      pa1[2]=0.;
      pa2[0]=l;
      pa2[1]=1.;
      pa2[2]=0.;
      pa3[0]=l;
      pa3[1]=0.;
      pa3[2]=1.;

      /* cycle through all target-surfaces and determine the triangle which fits and move the point */
      /* find the closest tri */
      /* distance between point and tri-cg */
      if ( (rsort = (Rsort *)realloc((Rsort *)rsort, (sum_tri+1) * sizeof(Rsort))) == NULL )
        printf("ERROR: realloc failed: Rsort\n\n" );
      for(j=0; j<sum_tri; j++)
      {
        dx=tri[j].cg[0]-x;
        dy=tri[j].cg[1]-y;
        dz=tri[j].cg[2]-z;
        rsort[j].r=dx*dx+dy*dy+dz*dz;
        rsort[j].i=j;
      }
      qsort( rsort, sum_tri, sizeof(Rsort), (void *)compareRsort );
#if TEST
      for (j=0; j<sum_tri; j++)
        printf("%d n:%d r:%lf\n", j, rsort[j].i, rsort[j].r); 
#endif

      /* check the closest tri for a split-point */
      for(j=0; j<sum_tri; j++)
      {
        x=tri[rsort[j].i].p1[0];
        y=tri[rsort[j].i].p1[1];
        z=tri[rsort[j].i].p1[2];
        pt1[0]=( ex[0]*x+ey[0]*y+ez[0]*z ) - l_offs ;    /* l */
        pt1[1]=( ex[1]*x+ey[1]*y+ez[1]*z ) - h_offs ;    /* h */
        pt1[2]=( ex[2]*x+ey[2]*y+ez[2]*z ) - q_offs ;    /* q */

        x=tri[rsort[j].i].p2[0];
        y=tri[rsort[j].i].p2[1];
        z=tri[rsort[j].i].p2[2];
        pt2[0]=( ex[0]*x+ey[0]*y+ez[0]*z ) - l_offs ;    /* l */
        pt2[1]=( ex[1]*x+ey[1]*y+ez[1]*z ) - h_offs ;    /* h */
        pt2[2]=( ex[2]*x+ey[2]*y+ez[2]*z ) - q_offs ;    /* q */

        x=tri[rsort[j].i].p3[0];
        y=tri[rsort[j].i].p3[1];
        z=tri[rsort[j].i].p3[2];
        pt3[0]=( ex[0]*x+ey[0]*y+ez[0]*z ) - l_offs ;    /* l */
        pt3[1]=( ex[1]*x+ey[1]*y+ez[1]*z ) - h_offs ;    /* h */
        pt3[2]=( ex[2]*x+ey[2]*y+ez[2]*z ) - q_offs ;    /* q */

        if( AsplitA( pa1, pa2, pa3, pt1, pt2, pt3, ps1, ps2) >0 )
        {
          /* check if the projected point is on that element */
          /* this is the case if r(ps) is between r(ps1) and r(ps2) */
          rp=sqrt(h*h+q*q);
          rs1=sqrt(ps1[1]*ps1[1]+ps1[2]*ps1[2]);
          rs2=sqrt(ps2[1]*ps2[1]+ps2[2]*ps2[2]);
          rmin=smin(rs1,rs2); 
          rmax=smax(rs1,rs2);
          /*
	    printf("rp:%lf %lf %lf\n",rp,rmin,rmax);
	    printf("p: %lf %lf %lf\n",pa1[0],pa1[1],pa1[2]);
	    printf("p: %lf %lf %lf\n",pa2[0],pa2[1],pa2[2]);
	    printf("p: %lf %lf %lf\n",pa3[0],pa3[1],pa3[2]);
	    printf("p1: %lf %lf %lf\n",pt1[0],pt1[1],pt1[2] );
	    printf("p2: %lf %lf %lf\n",pt2[0],pt2[1],pt2[2] );
	    printf("p3: %lf %lf %lf\n",pt3[0],pt3[1],pt3[2] );
          */
          if((rp>=rmin)&&(rp<=rmax))
          {
            printf(" found enclosing tri3 for point:%s\n", pproj[i].name);
            /* new h and q values  */
            h=ps1[1]+((rp-rs1)/(rs2-rs1)*(ps2[1]-ps1[1]));
            q=ps1[2]+((rp-rs1)/(rs2-rs1)*(ps2[2]-ps1[2]));
            goto foundTri3rot;
          }
	}
      }
      if(pproj[i].nn>-1) { printf("WARNING: no enclosing element for point:%s found\n", pproj[i].name ); pre_seta(specialset->noprj, "p",pproj[i].name ); } 
      else               { printf("WARNING: no enclosing element for node:%s found\n", pproj[i].name );  pre_seta(specialset->noprj, "n",pproj[i].name ); }
      goto nextpointrot;
     foundTri3rot:;
      
      l+= l_offs;
      h+= h_offs;
      q+= q_offs;
      
      x=el[0]*l+eh[0]*h+eq[0]*q;
      y=el[1]*l+eh[1]*h+eq[1]*q;
      z=el[2]*l+eh[2]*h+eq[2]*q;
  
      /* redefine the point */
      pproj[i].px=  x;
      pproj[i].py=  y;
      pproj[i].pz=  z;
     nextpointrot:;
    }
  }
  else if(( compare( action, "tra", 3) == 3)||( compare( action, "nor", 3) == 3))
  {
    offset=0.;
    if( compare( action, "tra", 3) == 3)
      length = sscanf( record,"%*s %*s %*s %lf %lf %lf %lf", &vproj[0], &vproj[1], &vproj[2], &offset );
    else
    {
      length = sscanf( record,"%*s %*s %*s %lf", &offset );
      normFlag=1;
    }


    /* The embedded triangles are the surfaces which are used as a target for the projection */
    
    for (i=0; i<sum_pproj; i++)
    {
      pr[0]=pproj[i].px;
      pr[1]=pproj[i].py;
      pr[2]=pproj[i].pz;

      /* find the closest tri */
      /* distance between point and tri-cg */
      if ( (rsort = (Rsort *)realloc((Rsort *)rsort, (sum_tri+1) * sizeof(Rsort))) == NULL )
        printf("ERROR: realloc failed: Rsort\n\n" );
      for(j=0; j<sum_tri; j++)
      {
        dx=tri[j].cg[0]-pr[0];
        dy=tri[j].cg[1]-pr[1];
        dz=tri[j].cg[2]-pr[2];
        rsort[j].r=dx*dx+dy*dy+dz*dz;
        rsort[j].i=j;
      }
      qsort( rsort, sum_tri, sizeof(Rsort), (void *)compareRsort );
#if TEST
      for (j=0; j<close_tris; j++)
        printf("%d f:%d  n:%d r:%lf\n", j, tri[rsort[j].i].fnr, rsort[j].i, rsort[j].r); 
#endif

      /* check the closest tri for a split-point */
      minj=-1;mindist=MAXVALUE;
      for(j=0; j<close_tris; j++)
      {
        if(normFlag)
	{
          v_result( tri[rsort[j].i].p1, tri[rsort[j].i].p2, v1);
          v_result( tri[rsort[j].i].p1, tri[rsort[j].i].p3, v2);
          v_prod( v1, v2, vproj );
	}
        // printf(" tri3:%d r:%f for point:%s\n", tri[rsort[j].i].fnr, rsort[j].r, pproj[i].name); 
        dist=v_distA(  tri[rsort[j].i].p1, tri[rsort[j].i].p2, tri[rsort[j].i].p3, pr, vproj);
        if(( dist != -1.e10 )&&(abs(dist)<abs(mindist)))
        {
          // printf(" found enclosing tri3:%d for point:%s, distance:%lf\n", tri[rsort[j].i].fnr, pproj[i].name, dist); 
          mindist=dist;
          minj=j;
	}
      }
      // printf(" minj:%d\n",minj);
      if( minj!=-1 )
      {
        j=minj;
        if(normFlag)
	{
          v_result( tri[rsort[j].i].p1, tri[rsort[j].i].p2, v1);
          v_result( tri[rsort[j].i].p1, tri[rsort[j].i].p3, v2);
          v_prod( v1, v2, vproj );
	}
        dist=v_distA(  tri[rsort[j].i].p1, tri[rsort[j].i].p2, tri[rsort[j].i].p3, pr, vproj);
        printf(" found enclosing tri3[%d] for point:%s, distance:%lf\n", j, pproj[i].name, dist); 
        /* berechne den Gradeneinheitsvektor en */
        v_norm( vproj, pc );
        pr[0]+=pc[0]*(dist+offset);
        pr[1]+=pc[1]*(dist+offset);
        pr[2]+=pc[2]*(dist+offset);
        goto foundTri3tra;
      }
      if(pproj[i].nn>-1) { printf("WARNING: no enclosing element for point:%s found\n", pproj[i].name ); pre_seta(specialset->noprj, "p",pproj[i].name ); } 
      else               { printf("WARNING: no enclosing element for node:%s found\n", pproj[i].name );  pre_seta(specialset->noprj, "n",pproj[i].name ); }
    foundTri3tra:;
      /* redefine the point */
      pproj[i].px= pr[0];
      pproj[i].py= pr[1];
      pproj[i].pz= pr[2];
    }
  }
  /* has to be included in the above block. If a nurbs is in trgtNr which is not referenced by a surf in trgtNr then proj to it */
  else if( compare( action, "_nor", 3) == 3)
  {
    /* project normal onto a nurbs-surface */
    if(getSetNr(specialset->zap)>-1) delSet(specialset->zap);
    setNrbuf=pre_seta(specialset->zap, "i", 0 );
    if(setNrbuf<0) { errMsg(" ERROR: could not create set for qdel\n"); return; } 
    for (i=0; i<sum_pproj; i++) seta(setNrbuf,"p", i);
    for (i=0; i<set[trgtNr].anz_nurs; i++)
    {
      projPntsToNurbs( nurbs, set[trgtNr].nurs[i], set, setNrbuf, pproj);
    }
    if(getSetNr(specialset->zap)>-1) delSet(specialset->zap);
  }
  else
  {
    errMsg(" ERROR: transformation:%s not known\n", action);
    return;
  }

  /* map the results to the original entities */
  for (i=0; i<sum_pproj; i++)
  {
    if(pproj[i].nn>-1)
    {
      p=pproj[i].nn;
      point[p].px=(pproj[i].px-scale->x)/scale->w;
      point[p].py=(pproj[i].py-scale->y)/scale->w;
      point[p].pz=(pproj[i].pz-scale->z)/scale->w;
    }
    else
    {
      n=-pproj[i].nn;
      node[n].nx=(pproj[i].px-scale->x)/scale->w;
      node[n].ny=(pproj[i].py-scale->y)/scale->w;
      node[n].nz=(pproj[i].pz-scale->z)/scale->w;
    }
  }
  free(pproj);
  free(tri);
  free(rsort);

  if(getSetNr(specialset->noprj)>-1) printf("WARNING: check set:%s for failed entities\n", specialset->noprj);

  /* dependent higher entities need new label-positions, achived with orient */
  /* create a set with the dependent higher entities to be oriented  */

  /* add all points to special set _ORI  */
  if(set[setNr].anz_p>0)
  { 
    j=pre_seta( specialset->ori, "i", 0 );
    for (i=0; i<set[setNr].anz_p; i++)
    {
      p=set[setNr].pnt[i];
      seta( j, "p", p );
    }
    completeSet( specialset->ori, "up");
    orientSet( specialset->ori );
    delSet(specialset->ori);
  }

  /* recalculate the line-shapes */
  for (i=0; i<anzGeo->l; i++) rep(i);

  /* recalculate the dependent surfaces */
  for (j=0; j<set[setNr].anz_s; j++)
  {
    if(surf[set[setNr].surf[j]].sh>-1)
    {
      untrimNurs(surf[set[setNr].surf[j]].sh);
      repNurs(surf[set[setNr].surf[j]].sh);
    }
    repSurf(set[setNr].surf[j]);
  }

  /* fix midside-node positions */
  fixMidsideNodes(set[setNr].name, "");

  free_proj(nx, nrad, nmissed);
}


/*------------------------------------------------------------------*/
/* setinhalt schreiben                                              */
/*------------------------------------------------------------------*/

int prnt(unsigned char *record)
{
  int   setNr, nr, p, l, nc,nl;
  int i,j,k,n, index;
  int length, bias_fbd;
  unsigned char name[MAX_LINE_LENGTH], typ[MAX_LINE_LENGTH];

  length=sscanf(record,"%s%s",typ,name);


  if ((compare( typ, "amp", 3) == 3) ||(compare( typ, "AMP", 3) == 3))
  {
    if (length==1)
    {
      /* list all existing amplitudes */
      for (i=0; i<anzGeo->amps; i++)
      {
        if( amplitude[i].name != (unsigned char *)NULL )
        {
          printf ("%s xy-pairs:%d\n", amplitude[i].name, amplitude[i].n);
        }
      }
      return(1);
    }
    else
    {
      setNr=getAmplitudeNr(name,1);
      if (setNr<0)
      {
        printf (" prnt: amplitude:'%s' does not exist\n", name);
        return (-1);
      }
    }
    printf ("i      x:            y:\n");
    for (i=0; i<amplitude[setNr].n; i++)
    {
      printf (" %8d %12e %12e\n", i+1, amplitude[setNr].x[i],amplitude[setNr].y[i]);
    }
  }

  if ((compare( typ, "mat", 3) == 3) ||(compare( typ, "MAT", 3) == 3))
  {
    if (length==1)
    {
      /* list all existing amplitudes */
      for (i=0; i<anzGeo->mats; i++)
      {
        if( material[i].name != (unsigned char *)NULL )
        {
          printf ("%s elastic:%d expansion:%d conductivity:%d specific heat:%d \n", material[i].name, material[i].nela, material[i].nexp, material[i].ncon, material[i].nsph);
        }
      }
      return(1);
    }
    else
    {
      setNr=getMatNr(name,1);
      if (setNr<0)
      {
        printf (" prnt: material:'%s' does not exist\n", name);
        return (-1);
      }
    }
    printf ("density:%e\n", material[setNr].rho);
    printf ("\ni      elastic:      nue:      temperature:\n");
    for (i=0; i<material[setNr].nela; i++)
    {
      printf (" %8d %12e %12e %12e\n", i+1, material[setNr].ela[i],material[setNr].nue[i],material[setNr].tela[i]);
    }
    printf ("\ni      expansion:      temperature:\n");
    for (i=0; i<material[setNr].nexp; i++)
    {
      printf (" %8d %12e %12e\n", i+1, material[setNr].exp[i],material[setNr].texp[i]);
    }
    printf ("\ni      conductivity:      temperature:\n");
    for (i=0; i<material[setNr].ncon; i++)
    {
      printf (" %8d %12e %12e\n", i+1, material[setNr].con[i],material[setNr].tcon[i]);
    }
    printf ("\ni      sp. heat:      temperature:\n");
    for (i=0; i<material[setNr].nsph; i++)
    {
      printf (" %8d %12e %12e\n", i+1, material[setNr].sph[i],material[setNr].tsph[i]);
    }
  }

  if ((compare( typ, "se", 2) == 2) ||(compare( typ, "SE", 2) == 2))
  {
    if (length==1)
    {
      /* list all existing sets */
      index=1;
      for (i=0; i<anzGeo->sets; i++)
      {
        if( set[i].name != (unsigned char *)NULL )
        {
          if (!set[i].type)
          {
            set[i].index=index++;
            printf ("%-5d %s stat:%c n:%d e:%d f:%d p:%d l:%d s:%d b:%d L:%d S:%d se:%d\n", set[i].index, set[i].name, set[i].flag, set[i].anz_n, set[i].anz_e, set[i].anz_f, set[i].anz_p, set[i].anz_l, set[i].anz_s, set[i].anz_b, set[i].anz_nurl, set[i].anz_nurs, set[i].anz_se);
          }
        }
      }
      return(1);
    }
    else
    {
      setNr=getSetNr(name);
      if (setNr<0)
      {
        printf (" prnt: set:'%s' does not exist\n", name);
        return (-1);
      }
    }
    printf (" node:    value:       x:            y:           z:\n");
    for (i=0; i<set[setNr].anz_n; i++)
    {
      printf (" %8d %12f %12f %12f %12f\n",  set[setNr].node[i], value_n[set[setNr].node[i]],
        (node[set[setNr].node[i]].nx* scale->w+scale->x),
        (node[set[setNr].node[i]].ny* scale->w+scale->y),
        (node[set[setNr].node[i]].nz* scale->w+scale->z) );
    }
    for (i=0; i<set[setNr].anz_e; i++)
    {
      printf (" elem:%d ", set[setNr].elem[i]);
      nr=set[setNr].elem[i];
      if     (e_enqire[nr].type==1) k=8;
      else if(e_enqire[nr].type==2) k=6;
      else if(e_enqire[nr].type==3) k=4;
      else if(e_enqire[nr].type==4) k=20;
      else if(e_enqire[nr].type==5) k=15;
      else if(e_enqire[nr].type==6) k=10;
      else if(e_enqire[nr].type==7) k=3;
      else if(e_enqire[nr].type==8) k=6;
      else if(e_enqire[nr].type==9) k=4;
      else if(e_enqire[nr].type==10) k=8;
      else if(e_enqire[nr].type==11) k=2;
      else if(e_enqire[nr].type==12) k=3;
      else k=0;
      for (n=0; n<k; n++) printf("%d ",e_enqire[nr].nod[n]);
      printf("\n"); 
    }
    for (i=0; i<set[setNr].anz_f; i++)
    {
      nr=set[setNr].face[i];
      printf (" face:%d elem:%d side:%d nodes:",  nr, face[nr].elem_nr, face[nr].nr);
      if(face[nr].type==7) k=3;
      else if(face[nr].type==8) k=6;
      else if(face[nr].type==9) k=4;
      else if(face[nr].type==10) k=8;
      else k=0;
      for (n=0; n<k; n++) printf("%d ",face[nr].nod[n]);
      printf("\n"); 
    }
    for (i=0; i<set[setNr].anz_p; i++)
    {
      p=set[setNr].pnt[i];
      if( point[p].name != (unsigned char *)NULL ) 
        printf (" pnt:'%s' x:%lf y:%lf z:%lf\n", point[p].name,
        (point[p].px* scale->w+scale->x),
        (point[p].py* scale->w+scale->y),
        (point[p].pz* scale->w+scale->z) );
    }
    for (i=0; i<set[setNr].anz_l; i++)
    {
      l=set[setNr].line[i];
      if( line[l].name != (unsigned char *)NULL ) 
      {
        bias_fbd=getBias_fbd(l, line);

        if( line[l].typ=='a' )  /* arc-line */
        {
          printf (" line:'%s' p1:'%s' p2:'%s' pc:'%s' div:%d bias:%d bias_el:%lf etyp:%d attr:%d\n"
          , line[l].name, point[line[l].p1].name,
          point[line[l].p2].name, point[line[l].trk].name, line[l].div, bias_fbd, line[l].bias, line[l].etyp, line[l].eattr);
        }
        else if( line[l].typ=='s' )  /* seq-line */
        {
          printf (" line:%s p1:%s p2:%s set:%s div:%d bias:%d bias_el:%lf etyp:%d attr:%d\n"
          , line[l].name, point[line[l].p1].name,
          point[line[l].p2].name, set[line[l].trk].name, line[l].div, bias_fbd, line[l].bias, line[l].etyp, line[l].eattr);
        }
        else  /* its a straight line   */
        {
          printf (" line:%s p1:%s p2:%s  div:%d bias:%d bias_el:%lf etyp:%d attr:%d\n"
          , line[l].name, point[line[l].p1].name,
          point[line[l].p2].name, line[l].div, bias_fbd, line[l].bias, line[l].etyp, line[l].eattr);
        }
      }
    }
    for (i=0; i<set[setNr].anz_c; i++)
    {
      p=set[setNr].lcmb[i];
      if( lcmb[p].name != (unsigned char *)NULL ) 
      {
        printf (" lcmb:%s ", lcmb[p].name );
        for (j=0; j<lcmb[p].nl; j++)
          printf (" %1c %s", lcmb[p].o[j], line[lcmb[p].l[j]].name );
        printf (" \n");
      }
    }
    for (i=0; i<set[setNr].anz_s; i++)
    {
      p=set[setNr].surf[i];
      if( surf[p].name != (unsigned char *)NULL ) 
      {
        if (surf[p].sh<0) printf (" surf:%s %1c BLEND ", surf[p].name, surf[p].ori );
        else printf (" surf:%s %1c %s ", surf[p].name, surf[p].ori, nurbs[surf[p].sh].name );
        for (j=0; j<surf[p].nl; j++)
        {
          nl=surf[p].l[j];
          if (surf[p].typ[j]=='l')
          {
            printf (" %1c %s", surf[p].o[j], line[nl].name );
          }
          else
          {
            printf (" %1c %s", surf[p].o[j], lcmb[nl].name );
            for (k=0; k<lcmb[nl].nl; k++ )
            {
              nc=lcmb[nl].l[k];
              printf (" (%c) (%s)", lcmb[nl].o[k], line[nc].name );
            }
          }
        }
        printf (" etyp:%d attr:%d\n", surf[p].etyp, surf[p].eattr);
      }
    }
    for (i=0; i<set[setNr].anz_b; i++)
    {
      p=set[setNr].body[i];
      if( body[p].name != (unsigned char *)NULL ) 
      {
        printf (" body:%s %1c", body[p].name, body[p].ori );
        for (j=0; j<body[p].ns; j++)
          printf (" %1c %s", body[p].o[j], surf[body[p].s[j]].name );
          printf (" etyp:%d attr:%d\n", body[p].etyp, body[p].eattr);
      }
    }
    for (i=0; i<set[setNr].anz_nurl; i++)
    {
      nr=set[setNr].nurl[i];
      if( nurbl[nr].name != (unsigned char *)NULL ) 
      {
        printf (" nurl:%s\n", nurbl[nr].name );
        printf (" coefficients: exp:%d pnts:%d nods:%d End:%d\n", nurbl[nr].u_exp, nurbl[nr].u_npnt, nurbl[nr].u_nknt, nurbl[nr].endFlag);
        for (k=0; k<nurbl[nr].u_nknt; k++) printf("u-node[%d] = %lf\n", k+1, nurbl[nr].uknt[k]);
        for (k=0; k<nurbl[nr].u_npnt; k++)
        {
          printf("cpnt[%d]:%s x=%lf y=%lf z=%lf w=%lf\n", k+1, point[nurbl[nr].ctlpnt[k]].name, point[nurbl[nr].ctlpnt[k]].px,
          point[nurbl[nr].ctlpnt[k]].py, point[nurbl[nr].ctlpnt[k]].pz, nurbl[nr].weight[k]);
        }
      }
    }
    for (i=0; i<set[setNr].anz_nurs; i++)
    {
      nr=set[setNr].nurs[i];
     if( nurbs[nr].name != (unsigned char *)NULL ) 
     {
      printf (" nurs:%s\n", nurbs[nr].name );

      printf (" coefficients: u_exp:%d v_exp:%d u_npnt:%d v_npnt:%d u_nnod:%d v_nnod:%d End:%d\n", nurbs[nr].u_exp, nurbs[nr].v_exp,
        nurbs[nr].u_npnt, nurbs[nr].v_npnt, nurbs[nr].u_nknt, nurbs[nr].v_nknt, nurbs[nr].endFlag);
      for (k=0; k<nurbs[nr].u_nknt; k++) printf("u-node[%d] = %lf\n", k+1, nurbs[nr].uknt[k]);
      for (k=0; k<nurbs[nr].v_nknt; k++) printf("v-node[%d] = %lf\n", k+1, nurbs[nr].vknt[k]);
      for (k=0; k<nurbs[nr].u_npnt; k++)
      {
        for (j=0; j<nurbs[nr].v_npnt; j++)
        {
          printf("cpnt[%d][%d]:%s x=%lf y=%lf z=%lf w=%lf \n", k+1, j+1, point[nurbs[nr].ctlpnt[k][j]].name, point[nurbs[nr].ctlpnt[k][j]].px,
          point[nurbs[nr].ctlpnt[k][j]].py, point[nurbs[nr].ctlpnt[k][j]].pz, nurbs[nr].weight[k][j]);
        }
      }
     }
    }
    for (i=0; i<set[setNr].anz_se; i++)
    {
      p=set[setNr].set[i];
      if( set[p].name != (unsigned char *)NULL ) 
      {
        printf (" set:%s ", set[p].name );
        printf (" \n");
      }
    }
    printf (" %d nodes, %d elements, %d faces, %d Points, %d Lines, %d Lcmb, %d Surfs, %d Bodys, %d Nurl, %d Nurs, %d sets stored\n", set[setNr].anz_n, set[setNr].anz_e, set[setNr].anz_f, set[setNr].anz_p, set[setNr].anz_l, set[setNr].anz_c, set[setNr].anz_s, set[setNr].anz_b, set[setNr].anz_nurl, set[setNr].anz_nurs, set[setNr].anz_se );
  }
  else if ((compare( typ, "sq", 2) == 2) ||(compare( typ, "SQ", 2) == 2))
  {
    if (length==1)
    {
      /* list all existing sequential sets */
      for (i=0; i<anzGeo->sets; i++)
      {
        if( set[i].name != (unsigned char *)NULL )
        {
          if (set[i].type)
            printf ("%s type:SEQ stat:%c p:%d\n", set[i].name, set[i].flag, set[i].anz_p);
        }
      }
      return(1);
    }
    else
    {
      setNr=getSetNr(name);
      if (setNr<0)
      {
        printf (" prnt: set:%s does not exist\n", name);
        return (-1);
      }
    }
    for (i=0; i<set[setNr].anz_p; i++)
    {
      p=set[setNr].pnt[i];
      if( point[p].name != (unsigned char *)NULL ) 
        printf (" pnt:%s x:%lf y:%lf z:%lf\n", point[p].name,
        (point[p].px* scale->w+scale->x),
        (point[p].py* scale->w+scale->y),
        (point[p].pz* scale->w+scale->z) );
    }
  }
  else if ((typ[0]=='n')||(typ[0]=='N'))
  {
    nr=atoi(name);
    printf (" node:%d v:%lf x:%lf y:%lf z:%lf\n", nr, value_n[nr],
        (node[nr].nx* scale->w+scale->x),
        (node[nr].ny* scale->w+scale->y),
        (node[nr].nz* scale->w+scale->z) );
  }
  else if ((typ[0]=='e')||(typ[0]=='E'))
  {
    nr=atoi(name);
    printf (" elem:%d ",  nr);
    if     (e_enqire[nr].type==1) k=8;
    else if(e_enqire[nr].type==2) k=6;
    else if(e_enqire[nr].type==3) k=4;
    else if(e_enqire[nr].type==4) k=20;
    else if(e_enqire[nr].type==5) k=15;
    else if(e_enqire[nr].type==6) k=10;
    else if(e_enqire[nr].type==7) k=3;
    else if(e_enqire[nr].type==8) k=6;
    else if(e_enqire[nr].type==9) k=4;
    else if(e_enqire[nr].type==10) k=8;
    else if(e_enqire[nr].type==11) k=2;
    else if(e_enqire[nr].type==12) k=3;
    else k=0;
    for (n=0; n<k; n++) printf("%d ",e_enqire[nr].nod[n]);
    printf("\n"); 
  }
  else if ((typ[0]=='f')||(typ[0]=='F'))
  {
    nr=atoi(name);
    printf (" face:%d elem:%d side:%d nodes:",  nr, face[nr].elem_nr, face[nr].nr);
      if(face[nr].type==7) k=3;
      else if(face[nr].type==8) k=6;
      else if(face[nr].type==9) k=4;
      else if(face[nr].type==10) k=8;
      else k=0;
      for (n=0; n<k; n++) printf("%d ",face[nr].nod[n]);
      printf("\n"); 
  }
  else if ((typ[0]=='p')||(typ[0]=='P'))
  {
    p=getPntNr(name);
    if (p<0)
    {
      printf (" prnt: point:%s does not exist\n", name);
      return (-1);
    }
    if( point[p].name != (unsigned char *)NULL ) 
      printf (" pnt:%s x:%lf y:%lf z:%lf\n", point[p].name,
      (point[p].px* scale->w+scale->x),
      (point[p].py* scale->w+scale->y),
      (point[p].pz* scale->w+scale->z) );
  }
  else if ((typ[0]=='l')||(typ[0]=='L'))
  {
    l=getLineNr(name);
    if (l<0)
    {
      printf (" prnt: line:%s does not exist\n", name);
      return (-1);
    }
    if( line[l].name != (unsigned char *)NULL ) 
    {
      bias_fbd=getBias_fbd(l, line);

      if( line[l].typ=='a' )  /* arc-line */
      {
        printf (" line:%s p1:%s p2:%s pc:%s div:%d bias:%d bias_el:%lf\n"
        , line[l].name, point[line[l].p1].name,
        point[line[l].p2].name, point[line[l].trk].name, line[l].div, bias_fbd, line[l].bias);
      }
      else if( line[l].typ=='s' )  /* seq-line */
      {
        printf (" line:%s p1:%s p2:%s set:%s div:%d bias:%d bias_el:%lf\n"
        , line[l].name, point[line[l].p1].name,
        point[line[l].p2].name, set[line[l].trk].name, line[l].div, bias_fbd, line[l].bias);
      }
      else  /* its a straight line   */
      {
        printf (" line:%s p1:%s p2:%s div:%d bias:%d bias_el:%lf\n"
        , line[l].name, point[line[l].p1].name,
        point[line[l].p2].name, line[l].div, bias_fbd, line[l].bias);
      }
    }
  }
  else if ((typ[0]=='c')||(typ[0]=='C'))
  {
    l=getLcmbNr(name);
    if (l<0)
    {
      printf (" prnt: lcmb:%s does not exist\n", name);
      return (-1);
    }  
    if( lcmb[l].name != (unsigned char *)NULL ) 
    {
      printf (" lcmb:%s ", lcmb[l].name );
      for (j=0; j<lcmb[l].nl; j++)
        printf (" %1c %s", lcmb[l].o[j], line[lcmb[l].l[j]].name );
      printf (" \n");
    }
  }
  else if ((typ[0]=='s')||(typ[0]=='S'))
  {
    p=getSurfNr(name);
    if (p<0)
    {
      printf (" prnt: surf:%s does not exist\n", name);
      return (-1);
    }  
    if( surf[p].name != (unsigned char *)NULL ) 
    {
      if (surf[p].sh<0) printf (" surf:%s %1c BLEND ", surf[p].name, surf[p].ori );
      else printf (" surf:%s %1c %s ", surf[p].name, surf[p].ori, nurbs[surf[p].sh].name );
      for (j=0; j<surf[p].nl; j++)
      {
        nl=surf[p].l[j];
        if (surf[p].typ[j]=='l')
        {
          printf (" %1c %s", surf[p].o[j], line[nl].name );
        }
        else
        {
          printf (" %1c %s", surf[p].o[j], lcmb[nl].name );
          for (k=0; k<lcmb[nl].nl; k++ )
          {
            nc=lcmb[nl].l[k];
            printf (" (%c) (%s)", lcmb[nl].o[k], line[nc].name );
          }
        }
      }
      printf (" \n");
    }
  }
  else if ((typ[0]=='b')||(typ[0]=='B'))
  {
    p=getBodyNr(name);
    if (p<0)
    {
      printf (" prnt: body:%s does not exist\n", name);
      return (-1);
    }  
    if( body[p].name != (unsigned char *)NULL ) 
    {
      printf (" body:%s %1c", body[p].name, body[p].ori );
      for (j=0; j<body[p].ns; j++)
        printf (" %1c %s", body[p].o[j], surf[body[p].s[j]].name );
      printf (" \n");
    }
  }
  return(1);
}

/*------------------------------------------------------------------*/
/* set und setinhalt loeschen                                       */
/*------------------------------------------------------------------*/

int zap(unsigned char *record)
{
  int i,j;
  int length, setNr;
  unsigned char setname[MAX_LINE_LENGTH];

  length=sword( record, setname );
  operateAlias( setname, "se" );
  setNr=getSetNr(setname);

  if (setNr<0) return (-1);

  /* enthaelt der set etwas? */
  if((set[setNr].anz_n==0)&&
     (set[setNr].anz_e==0)&& 
     (set[setNr].anz_p==0)&& 
     (set[setNr].anz_l==0)&& 
     (set[setNr].anz_c==0)&& 
     (set[setNr].anz_s==0)&& 
     (set[setNr].anz_b==0)&& 
     (set[setNr].anz_nurl==0)&& 
     (set[setNr].anz_nurs==0)&& 
     (set[setNr].anz_se=0)) return(-1); 

  /* suche abhaengige linien, redefine if necessary */
  for ( i=0; i<set[setNr].anz_p; i++)
  {
    for (j=0; j<anzGeo->l; j++)
    {
      if(( set[setNr].pnt[i] == line[j].trk )&&( line[j].typ == 'a' ))
      {
        line[j].typ = ' ';
      }
    }
  }

  /* vor dem loeschen muessen noch die abhaengigen direkt uebergeordneten Groessen dazugeladen werden  */
  printf(" complete set\n");
  completeSet( setname, "up");
  printf(" set complete\n");


  if (set[setNr].anz_e>0)
  {
    qsort( set[setNr].elem, set[setNr].anz_e, sizeof(int), (void *)compareInt );
    delElem( set[setNr].anz_e, set[setNr].elem );
    printf(" elements deleted\n");
  }
  if (set[setNr].anz_n>0)
  {
    delNod( set[setNr].anz_n, set[setNr].node );
    printf(" nodes deleted\n");
  }
  if (set[setNr].anz_nurs>0)
  {
    delNurs( set[setNr].anz_nurs, set[setNr].nurs );
    printf(" nurs deleted\n");
  }
  if (set[setNr].anz_b>0)
  {
    delBody( set[setNr].anz_b, set[setNr].body );
    printf(" bodys deleted\n");
  }
  if (set[setNr].anz_s>0)
  {
    delSurf( set[setNr].anz_s, set[setNr].surf );
    printf(" surfs deleted\n");
  }
  if (set[setNr].anz_l>0)
  {
    delLine( set[setNr].anz_l, set[setNr].line );
    printf(" lines deleted\n");
  }
  if (set[setNr].anz_c>0)
  {
    delLcmb( set[setNr].anz_c, set[setNr].lcmb );
    printf(" lcmbs deleted\n");
  }
  if (set[setNr].anz_p>0)
  {
    delPnt( set[setNr].anz_p, set[setNr].pnt );
    printf(" points deleted\n");
  }

  /* delete the set itself */
  delSet(setname);

  return(1);
}



void mata( int *elemMat, int mat, int setNr )
{
  register int  i, j;
  int           *ielem=NULL;

  /* mark the elements of the set for easy identification */
  if( (ielem=(int *)malloc((anz->emax+1)*sizeof(int) ) )==NULL) 
  { printf(" ERROR: malloc failure\n"); return; }
  if (setNr==-1)
    for (i=0; i<=anz->emax; i++) ielem[i]=1;
  else
  {
    for (i=0; i<=anz->emax; i++) ielem[i]=0;
    for (i=0; i<set[setNr].anz_e; i++) ielem[set[setNr].elem[i]]=1;
  }

  /* exists this mat? */
  for (i=1; i<=elemMat[0]; i++) if (elemMat[i]==mat) break;
  if(i>elemMat[0])
  {
    elemMat[0] = i;
    elemMat[i] = mat;
  }
  
  for (j=0; j<anz->e; j++)
  {
    if (ielem[e_enqire[j].nr])
      e_enqire[e_enqire[j].nr].mat= elemMat[i];
  }
  free(ielem); ielem=NULL;
}


unsigned char getLetter(int i)
{
  if(i>9) return(i-10+65);
  else return(i+48);
}


int getFamName( int n, unsigned char *c )
{
  int i, j;
  double f;

  j=n/46656;
  n=n%46656;

  /* change decimal (0->46655) into a string of 3 char (000 -> ZZZ) */
  f=n/1296.;
  i=f;
  c[0]=getLetter(i);
  f=(f-i)*36.;
  i=f;
  c[1]=getLetter(i);
  i=(f-i)*36.;
  c[2]=getLetter(i);
  c[3]=(unsigned char)NULL;
  return(j);
}

int getNewName( unsigned char *name, unsigned char *type )
{
  static int p, l, c, s, b, L, S, se;
  int i,nr,nr2=0;
  unsigned char string[MAX_LINE_LENGTH];

  /* not implemented yet 
  if(fillSpaceFlag) p=l=c=s=b=S=se=0;
  */

    do
    {
      if (type[0]=='p')
      {
        p++;
        i=getFamName(p, string);
        if(lchar->p+i>90)  sprintf(name, "%c%-d", lchar->p, p );
        else sprintf(name, "%c%s", lchar->p+i, string );
        nr=getPntNr(name);
      }
      else if (compare( type, "se", 2) == 2 )
      {
        se++;
        i=getFamName(se, string);
        if(lchar->se+i>90)  sprintf(name, "%c%-d", lchar->se,se);
        else sprintf(name, "%c%s", lchar->se+i, string );
        nr=getSetNr(name);
      }
      else if (type[0]=='l')
      {
        l++;
        i=getFamName(l, string);
        if(lchar->l+i>90)  sprintf(name, "%c%-d", lchar->l, l );
        else sprintf(name, "%c%s", lchar->l+i, string );
        nr=getLineNr(name);
        if(nr<0) nr2=getLcmbNr(name); if(nr2>0) nr=0; /* check if a lcmb has this name, not use it */
      }
      else if (type[0]=='c')
      {
        c++;
        i=getFamName(c, string);
        if(lchar->c+i>90)  sprintf(name, "%c%-d", lchar->c, c );
        else sprintf(name, "%c%s", lchar->c+i, string );
        nr=getLcmbNr(name);
        if(nr<0) nr2=getLineNr(name); if(nr2>0) nr=0; /* check if a line has this name, not use it */
      }
      else if (type[0]=='s')
      {
        s++;
        i=getFamName(s, string);
        if(lchar->s+i>90)  sprintf(name, "%c%-d", lchar->s, s );
        else sprintf(name, "%c%s", lchar->s+i, string );
        nr=getSurfNr(name);
      }
      else if (type[0]=='b')
      {
        b++;
        i=getFamName(b, string);
        if(lchar->b+i>90)  sprintf(name, "%c%-d", lchar->b, b );
        else sprintf(name, "%c%s", lchar->b+i, string );
        nr=getBodyNr(name);
      }
      else if (type[0]=='L')
      {
        L++;
        i=getFamName(L, string);
        if(lchar->L+i>90)  sprintf(name, "%c%-d", lchar->L, L );
        else sprintf(name, "%c%s", lchar->L+i, string );
        nr=getNurlNr(name);
      }
      else if (type[0]=='S')
      {
        S++;
        i=getFamName(S, string);
        if(lchar->S+i>90)  sprintf(name, "%c%-d", lchar->S, S );
        else sprintf(name, "%c%s", lchar->S+i, string );
        nr=getNursNr(name);
      }
      else
        return(-1);
    }while(nr>-1);   /* new entity */

  return(1);
}

int readlist(unsigned char *datin, unsigned char *type)
{
  FILE *handle;

  int length, i, j, n, dotpos, column, setNr;
  unsigned char string[MAX_LINE_LENGTH], face[MAX_LINE_LENGTH], format[MAX_LINE_LENGTH];
  int nr;

  handle = fopen (datin, "r");
  if (handle==NULL)
  {
    printf (" ERROR: The input file \"%s\" could not be opened.\n\n", datin);
    return(-1);
  }
  else  printf ("\n%s opened",datin);

  length = 1;
  printf ("\n reading file\n");

  i=n=0;
  dotpos = strlen (datin);
  for (j=0; j<dotpos; j++) if (datin[j]=='/') n=j+1;
  for (j=n; j<dotpos; j++)
  {
    if (datin[j]=='.')
    {
       break;
    }
    else datin[i]=datin[j];
    i++;
  }
  datin[i]= (unsigned char)NULL;

  /* initialize the set */
  if( (setNr=pre_seta( datin, "i", 0)) <0 ) return(-1);
 
  /* get the column */
  if(strlen(type)>1) column=atoi(&type[1])-1;
  else column=0;

  if((type[0]=='E')||(type[0]=='e'))
  {
    for (i=0; i<column; i++) sprintf(&format[i*4], "%%*s ");
    sprintf(&format[i*4], "%%d, %%s");
    while (length > -1)
    {
      length = frecord( handle, string);
      if( string[length]== (unsigned char)EOF)  break;
      n=sscanf(string, format, &nr, face );
      printf("rec:%d e:%d face:%s\n",n,nr,face);
      if(n)
      {
        printf (" seta %s e %d\n", datin, nr );
        seta( setNr, "e", nr );
        if(n==2) /* element face is provided */
	{
          if(e_enqire[nr].type==1)
          {
	    if(face[1]=='1')
            {
              seta( setNr, "n", e_enqire[nr].nod[0] );
              seta( setNr, "n", e_enqire[nr].nod[1] );
              seta( setNr, "n", e_enqire[nr].nod[2] );
              seta( setNr, "n", e_enqire[nr].nod[3] );
	    }
	    else if(face[1]=='2')
            {
              seta( setNr, "n", e_enqire[nr].nod[4] );
              seta( setNr, "n", e_enqire[nr].nod[5] );
              seta( setNr, "n", e_enqire[nr].nod[5] );
              seta( setNr, "n", e_enqire[nr].nod[7] );
	    }
	    else if(face[1]=='3')
            {
              seta( setNr, "n", e_enqire[nr].nod[0] );
              seta( setNr, "n", e_enqire[nr].nod[1] );
              seta( setNr, "n", e_enqire[nr].nod[5] );
              seta( setNr, "n", e_enqire[nr].nod[4] );
	    }
	    else if(face[1]=='4')
            {
              seta( setNr, "n", e_enqire[nr].nod[1] );
              seta( setNr, "n", e_enqire[nr].nod[2] );
              seta( setNr, "n", e_enqire[nr].nod[6] );
              seta( setNr, "n", e_enqire[nr].nod[5] );
	    }
	    else if(face[1]=='5')
            {
              seta( setNr, "n", e_enqire[nr].nod[2] );
              seta( setNr, "n", e_enqire[nr].nod[3] );
              seta( setNr, "n", e_enqire[nr].nod[7] );
              seta( setNr, "n", e_enqire[nr].nod[6] );
	    }
	    else if(face[1]=='6')
            {
              seta( setNr, "n", e_enqire[nr].nod[3] );
              seta( setNr, "n", e_enqire[nr].nod[0] );
              seta( setNr, "n", e_enqire[nr].nod[4] );
              seta( setNr, "n", e_enqire[nr].nod[7] );
	    }
            else printf(" side:%s not supported\n", face);
	  }
          else if(e_enqire[nr].type==6)
          {
	    if(face[1]=='1')
            {
              seta( setNr, "n", e_enqire[nr].nod[0] );
              seta( setNr, "n", e_enqire[nr].nod[1] );
              seta( setNr, "n", e_enqire[nr].nod[2] );
              seta( setNr, "n", e_enqire[nr].nod[4] );
              seta( setNr, "n", e_enqire[nr].nod[5] );
              seta( setNr, "n", e_enqire[nr].nod[6] );
	    }
	    else if(face[1]=='2')
            {
              seta( setNr, "n", e_enqire[nr].nod[0] );
              seta( setNr, "n", e_enqire[nr].nod[1] );
              seta( setNr, "n", e_enqire[nr].nod[3] );
              seta( setNr, "n", e_enqire[nr].nod[4] );
              seta( setNr, "n", e_enqire[nr].nod[8] );
              seta( setNr, "n", e_enqire[nr].nod[7] );
	    }
	    else if(face[1]=='3')
            {
              seta( setNr, "n", e_enqire[nr].nod[1] );
              seta( setNr, "n", e_enqire[nr].nod[2] );
              seta( setNr, "n", e_enqire[nr].nod[3] );
              seta( setNr, "n", e_enqire[nr].nod[5] );
              seta( setNr, "n", e_enqire[nr].nod[9] );
              seta( setNr, "n", e_enqire[nr].nod[8] );
	    }
	    else if(face[1]=='4')
            {
              seta( setNr, "n", e_enqire[nr].nod[2] );
              seta( setNr, "n", e_enqire[nr].nod[0] );
              seta( setNr, "n", e_enqire[nr].nod[3] );
              seta( setNr, "n", e_enqire[nr].nod[6] );
              seta( setNr, "n", e_enqire[nr].nod[7] );
              seta( setNr, "n", e_enqire[nr].nod[9] );
	    }
            else printf(" side:%s not supported\n", face);
	  }
          else printf(" element type:%d not supported\n", e_enqire[nr].type);
	}
      }
    }
  }
  else if((type[0]=='N')||(type[0]=='n'))
  {
    for (i=0; i<column; i++) sprintf(&format[i*4], "%%*s ");
    sprintf(&format[i*4], "%%d");
    while (length > -1)
    {
      length = frecord( handle, string);
      if( string[length]== (unsigned char)EOF)  break;
      n=sscanf((const char *)string, (const char *)format, &nr );
      printf("rec:%d n:%d\n",n,nr);
      if(n)
      {
        printf (" seta %s n %d\n", datin, nr );
        seta( setNr, "n", nr );
      }
    }
  }
  else printf (" ERROR: type %s not known\n", type );
  fclose(handle);
  return(1);
}


void pre_movie(unsigned char *string)
{
  int i,j,k, length;
  static int delay=10;
  double val1, val2;
  unsigned char type[MAX_LINE_LENGTH], name[MAX_LINE_LENGTH], movie[MAX_LINE_LENGTH];


  length=sscanf(string, "%s %lf %lf %s", type, &val1, &val2, movie );

  if (compareStrings(type, "delay")>0) { if(length==2) delay=100.*val1; else delay=10.; }
  if (compareStrings(type, "start")>0) { movieFlag=1; stopFlag=0; }
  if (compareStrings(type, "stop")>0)
  {
    printf("movie stopped, make movie with 'movie make <nr> <nr> [movie]'\n");
    printf("optionally define the delay-time between pictures with:'movie delay <sec>' before 'movi make'\n");
    printf("optionally reset the counter and delete the single frames with 'movi clean'\n");
    printf("you might use the program 'realplay' to play the movie.gif file\n");
    movieFlag=0;
    sprintf( buffer, "rm -f  hcpy_0.tga %s", DEV_NULL2);
    system (buffer);
  }
  if (compareStrings(type, "clean")>0)
  {
    sprintf( buffer, "rm -f _*.gif %s", DEV_NULL2);
    system (buffer);
    gifNr=1;
  }
  if (compareStrings(type, "make")>0)
  {
    if(length==1) {  val2=gifNr-1, val1=1; length=3; }  
    else if(length==2) {  val2=val1, val1=1; length=3; }  

    if(length>2)
    {
      if(length==4)
      {
        printf("make movie from %s and pic:%d to %d, wait for ready\n", movie, (int)val1,(int)val2);
        sprintf( buffer, "cp %s movie.gif %s", movie, DEV_NULL2);
        system (buffer);
      }
      else
      {
        printf("make movie from pic:%d to %d, wait for ready\n", (int)val1,(int)val2);
        movie[0]=0;
        system (buffer);
      }
        
      /* generate movie from single gif files */
      j=k=0;
      for(i=(int)val1; i<=(int)val2; i++)
      { 
        sprintf(&name[j*10], "_%d.gif     ",i); j++;
        if(j==9)
        {
  	j=0;
          sprintf( buffer, "convert -delay %d %s __%d.gif %s", delay, name, k++,DEV_NULL2);
          system (buffer);
        }
      }
      if(j)
      {
        sprintf( buffer, "convert -delay %d %s __%d.gif %s", delay, name, k++,DEV_NULL2);
        system (buffer);
      }
  
      /* assemble all movies */
      j=0;
      for(i=0; i<k; i++)
      { 
        sprintf(&name[j*12], "__%d.gif     ",i); j++;
        if(j==9)
        {
  	  j=0;
          if (i==9) sprintf( buffer, "convert -delay %d %s %s movie.gif %s", delay, movie, name,DEV_NULL2);
          else sprintf( buffer, "convert -delay %d movie.gif %s movie.gif %s", delay, name,DEV_NULL2);
          system (buffer);
        }
      }
      if(j)
      {
        if (k<9) sprintf( buffer, "convert -delay %d %s %s movie.gif %s", delay, movie, name,DEV_NULL2);
        else sprintf( buffer, "convert -delay %d movie.gif %s movie.gif %s", delay, name,DEV_NULL2);
        system (buffer);
      }
      sprintf( buffer, "rm __*.gif %s", DEV_NULL2);
      system (buffer);
      printf("ready\n");
    }
    else
    {
      printf(" ERROR: make movie with 'movie make <nr> <nr> [movie]'\n");
    }
  }
}


/*------------------------------------------------------------------*/
/* Daten im fbd-format einlesen                                     */
/*------------------------------------------------------------------*/
int commandoInterpreter( unsigned char *type, unsigned char *string, int na, int nb, FILE *handle1, int addFlag, int *gtolFlag )
{
  int   i,j,k,l,ibuf; 
  int nr;

  unsigned char  setname[MAX_LINE_LENGTH];
  unsigned char  xbuf[MAX_LINE_LENGTH], format[MAX_LINE_LENGTH];
  unsigned char  name[MAX_LINE_LENGTH], comm[MAX_LINE_LENGTH], posn[MAX_LINE_LENGTH], entity[MAX_LINE_LENGTH];
  static unsigned char  **seq=NULL;
  unsigned char  **buf;
  unsigned char  dat[MAX_PARAM_PER_RECORD][MAX_LINE_LENGTH];
  int       anz_seq, posn_length, length, setNr;
  double    pscal, x,y,dx,dy, wx[2], wy[2];

  static int *picnr=NULL;
  int pics;
  DIR *dirp;
  struct direct *dp;

  /* initialized based on valgrind report */
  setname[0]=name[0]=posn[0]=comm[0]=entity[0]=xbuf[0]=format[0]=0;
  for(j=0;j<MAX_PARAM_PER_RECORD; j++) dat[j][0]=0;

  for(j=0;j<strlen(type); j++) type[j]=toupper(type[j]);
  for(j=0;j<strlen(string); j++) if(string[j]=='\n') string[j]=0;

  if (compareStrings(type, "AREA")>0)
  {
    pre_area(&string[na+1]);
  }
  else if (compareStrings(type, "ASGN")>0)
  {
    sscanf(&string[na+1], "%s %s", entity, name);
    if(( entity[0]=='s')&&( entity[1]=='e')) lchar->se=name[0];
    else if( compareStrings(entity, "alpha")>0) meshp.alpha=atof(name);
    else if( compareStrings(entity, "beta")>0) meshp.beta=atof(name);
    else if( compareStrings(entity, "nadapt")>0) meshp.nadapt=atoi(name);
    else if( entity[0]=='n') anz->nmax=atoi(name)-1;
    else if( entity[0]=='e') anz->emax=atoi(name)-1;
    else if( entity[0]=='p') lchar->p=name[0];
    else if( entity[0]=='l') lchar->l=name[0];
    else if( entity[0]=='c') lchar->c=name[0];
    else if( entity[0]=='s') lchar->s=name[0];
    else if( entity[0]=='b') lchar->b=name[0];
    else if( entity[0]=='L') lchar->L=name[0];
    else if( entity[0]=='S') lchar->S=name[0];
    else errMsg(" %s not recognized\n", entity);
  }
  else if (compareStrings(type, "BIA")>0)
  {
    pre_bia(&string[na+1]);
  }
  else if (compareStrings(type, "BODY")>0)
  {
    pre_body(&string[na+1]);
  }
  else if (compareStrings(type, "CALL")>0)
  {
    userFunction(&string[na+1], anz, &node, &e_enqire, &lcase, &face, &set);
    createDatasetEntries();
  }
  else if (compareStrings(type, "COPY")>0)
  {
    pre_copy(&string[na+1]);
  }
  else if (compareStrings(type, "COMP")>0)
  {
    if ( sscanf(&string[na+1], "%s%s", name, xbuf) < 2) 
    { printf(" ERROR in formulation\n"); return(0); }
    completeSet( name, xbuf) ;
  }
  else if (compareStrings(type, "GLUE")>0)
  {
    pre_contact(&string[na+1]);
  }
  else if (compareStrings(type, "CORRAD")>0)
  {
    length=sscanf(string, "%*s %s %lf",name,&x); 
    if (length==1) x=0.;
    operateAlias( name, "se" );
    setNr=getSetNr(name);
    if (setNr<0)
    {
      printf (" corrad: set:%s does not exist\n", name);
      return(0);
    }
    corrad( setNr, x);
  }
  else if (compareStrings(type, "DEL")>0)
  {
    pre_del(&string[na+1]);
  }
  else if (compareStrings(type, "DIV")>0)
  {
    pre_div(&string[na+1]);
  }
  else if (compareStrings(type, "ELEM")>0)
  {
    pre_elem(&string[na+1]);
  }
  else if (compareStrings(type, "ELTY")>0)
  {
    pre_elty(&string[na+1]);
  }
  else if ( compareStrings(type, "EXIT")>0 )
  {
    strcpy(setname,datin);
    for (i=strlen(datin); i>=0; i--)
    {
      if(datin[i]=='.')break;
    }
    setname[i]=(unsigned char)NULL;
#ifdef WIN32
    sprintf (buffer, "move /y %s %s.fbb", datin, setname );
#else
    sprintf (buffer, "mv %s %s.fbb", datin, setname );
#endif
    if(compare(&datin[i+1],"fbd",3)==3) system (buffer);
    pre_write(" all fbd ");
    if( compareStrings( setname, "all")<3)
    {
#ifdef WIN32
      sprintf (buffer, "move /y all.fbd %s.fbd", setname );
#else
      sprintf (buffer, "mv all.fbd %s.fbd", setname );
#endif
      system (buffer);
    }     
    exit(0);
  }
  else if (compareStrings(type, "FRAME")>0)
  {
    descalNodes( anz->n, node, scale);
    descalPoints( anzGeo->p, point, scale);
    descalSurfs( anzGeo->s, surf, scale);
    getScaleValues( anz->n, anzGeo->p, point, node, scale);
    scalPoints ( anzGeo->p, point, scale );
    scalNodes ( anz->n, node, scale );
    scalSurfs( anzGeo->s, surf, scale);
    dtx=0.; dty=0.; dtz=0.; ds=0.5;
    for (i=0; i<4; i++) vmem[i]=0; /* reset all kompensations (center()) */
    /* recalculate the line-shapes */
    for (i=0; i<anzGeo->l; i++) rep(i);
    for (i=0; i<anzGeo->nurl; i++) repNurl(i);
    for (i=0; i<anzGeo->nurs; i++) repNurs(i);
    redraw(); glutPostRedisplay();
  }
  else if (compareStrings(type, "GBOD")>0)
  {
    pre_gbod(&string[na+1], addFlag);
  }
  else if (compareStrings(type, "GONLY")>0)
  {
    if (( compareStrings(&string[na+1], "of")>0)
        ||( compareStrings(&string[na+1], "OF")>0) )
    { 
      frameFlag=1;
      filenamFlag=1;
      textFlag=1;
      scalaFlag=1; 
    }
    else
    { 
      frameFlag=0;
      filenamFlag=0;
      textFlag=0;
      scalaFlag=0;
    }
    redraw();
  }
  else if (compareStrings(type, "GRAPH")>0)
  {
    graph(&string[na+1]);
  }
  else if (compareStrings(type, "GRPA")>0)
  {
    printf("ERROR: Not longer supported.\n");
  }
  else if (compareStrings(type, "GROUPS")>0)
  {
    printf("ERROR: Not longer supported.\n");
  }
  else if (compareStrings(type, "GROUP")>0)
  {
    printf("ERROR: Not longer supported.\n");
  }
  else if (compareStrings(type, "GSUR")>0)
  {
      pre_gsur(&string[na+1], addFlag);
  }
  else if (compareStrings(type, "GTOL")>0)
  {
    if(gtolFlag>(int *)NULL) *gtolFlag=1;
    x=gtol;
    length=sscanf(string, "%*s %lf",&gtol); 
    if (length==1) printf ("gtol set to:%lf\n", gtol);
    else { gtol=x;  printf ("gtol set to:%lf\n", gtol); }
  }
  else if (compareStrings(type, "HCPY")>0)
  {
    format[0]=0;
    sscanf(string,"%*s %s %s", name, format);
    if     (compareStrings(name, "ps")>0)  createHardcopy(1);
    else if(compareStrings(name, "tga")>0) createHardcopy(2);
    else if(compareStrings(name, "gif")>0) createHardcopy(4);
    else if(compareStrings(name, "png")>0) createHardcopy(5);
    else if(compareStrings(name, "clean")>0)
    {
      sprintf( buffer, "rm -f hcpy_*.ps %s", DEV_NULL2);
      system (buffer);
      psNr=1;
    }
    else if(compareStrings(name, "make")>0)
    {
      /* open the actual dir and get the available hcpy files */
      pics=0;
      dirp = opendir(".");
      if (dirp != NULL) while ((dp = readdir(dirp)) != NULL)
      {
        /* search for hcpy_xx.ps files  */
        if( (compare(dp->d_name, "hcpy", 4) == 4) && ( dp->d_name[strlen(dp->d_name)-2]=='p') && ( dp->d_name[strlen(dp->d_name)-1]=='s') )
        {
          printf(" found %s \n", dp->d_name);
          /* get the pic-nr */
          i=0; while(dp->d_name[i]!='_') i++; i++;
          j=0; while(dp->d_name[i]!='.') { posn[j]=dp->d_name[i]; j++; i++;}
          if ( (picnr = (int *)realloc( (int *)picnr, (pics+2) * sizeof(int))) == NULL )
          {  printf("\n\n ERROR: realloc failed, hcpy\n\n"); }
          picnr[pics]=atoi(posn); pics++;
        }
      }
      closedir(dirp);
      qsort( picnr, pics, sizeof(int), (void *)compareInt );

      nr=0; /* page-nr */
      ibuf=0; /* pic-nr */
      do
      {
        sprintf( buffer, "gs -dNOPAUSE -dBATCH -sDEVICE=pswrite -sOutputFile=tmp.ps ");
        for(j=0; j<6; j++) /* 6 pics per page */
	{
          if(ibuf==pics) break;
          sprintf( &buffer[strlen(buffer)], " hcpy_%d.ps", picnr[ibuf++]);
	}
        system (buffer);
        printf("%s\n",buffer);
        if ( compareStrings(format, "ls")>0)
        {
          pscal=0.45;
          x=13.; dx=9.;
          y=1.;  dy=9.;
          /* sscanf(string,"%*s %*s %*s %lf %lf %lf %lf %lf", &x, &y, &dx, &dy, &pscal); */
          sprintf( buffer, "pstops '6:0L@%lf(%lfcm,%lfcm)+3L@%lf(%lfcm,%lfcm)+1L@%lf(%lfcm,%lfcm)+4L@%lf(%lfcm,%lfcm)+2L@%lf(%lfcm,%lfcm)+5L@%lf(%lfcm,%lfcm)' tmp.ps tmp_%d.ps", pscal, x,y, pscal, x+dx,y, pscal, x,y+dy, pscal, x+dx,y+dy, pscal, x,y+2.*dy, pscal, x+dx,y+2.*dy, nr);
        }
        else
        {
          pscal=0.45;
          x=2.; dx=9.;
          y=0.; dy=9.;
          /* sscanf(string,"%*s %*s %*s %lf %lf %lf %lf %lf", &x, &y, &dx, &dy, &pscal); */
          sprintf( buffer, "pstops '6:4@%lf(%lfcm,%lfcm)+5@%lf(%lfcm,%lfcm)+2@%lf(%lfcm,%lfcm)+3@%lf(%lfcm,%lfcm)+0@%lf(%lfcm,%lfcm)+1@%lf(%lfcm,%lfcm)' tmp.ps tmp_%d.ps", pscal, x,y, pscal, x+dx,y, pscal, x,y+dy, pscal, x+dx,y+dy, pscal, x,y+2.*dy, pscal, x+dx,y+2.*dy, nr);
        }
        system (buffer);
        printf("%s\n",buffer);
        sprintf( buffer, "gs -dNOPAUSE -dBATCH -sDEVICE=pswrite -sOutputFile=cgx_%d.ps tmp_%d.ps", nr, nr);
        system (buffer);
        printf("%s\n",buffer);
        sprintf( buffer, "rm -f tmp*.ps %s",DEV_NULL);
        system (buffer);
        nr++;
      }while(j==6);
      sprintf( buffer, "gs -dNOPAUSE -dBATCH -sDEVICE=pswrite -sOutputFile=cgx.ps ");
      for(j=0; j<nr; j++)
      {
        sprintf( &buffer[strlen(buffer)], " cgx_%d.ps", j);
      }
      system (buffer);
      printf("%s\n",buffer);
      sprintf( buffer, "rm -f cgx_*.ps %s",DEV_NULL);
      system (buffer);
      if ( compareStrings(format, "ls")>0)
        sprintf(buffer, "%s -landscape cgx.ps &", psviewer);
      else
        sprintf(buffer, "%s cgx.ps &", psviewer);
      system (buffer);
      printf("ready\n");
    }
    else if(compareStrings(&string[na+1], "clean")>0)
    {
      sprintf( buffer, "rm -f hcpy_* %s",DEV_NULL);
      system (buffer);
      psNr=tgaNr=gifNr=pngNr=1;
    }           
    else createHardcopy(2);
  }
  else if (compareStrings(type, "LCMB")>0)
  {
    pre_lcmb(&string[na+1], addFlag);
  }
  else if (compareStrings(type, "LC")>0)
  {
    selectData( &string[na+1] );
  }
  else if (compareStrings(type, "LENGTH")>0)
  {
    pre_length(&string[na+1]);
  }
  else if (compareStrings(type, "LINE")>0)
  {
    pre_line(&string[na+1], addFlag);
  }
  else if (compareStrings(type, "MATA")>0)
  {
    length = sscanf(&string[na+1], "%d %s", &nr, name);
    if(length<2) { printf(" wrong syntax\n"); return(0); }
    operateAlias( name, "se" );
    setNr=getSetNr(name);
    if (setNr<0)
    {
      printf (" ERROR in mata: set:%s does not exist\n", name);
      return(0);
    }
    mata( elemMat, nr, setNr);
  }
  else if (compareStrings(type, "MATS")>0)
  {
    for (i=1; i<=elemMat[0]; i++) printf ("matNr:%d\n", elemMat[i]); 
    for (i=0; i<anz->e; i++)
    {
      sprintf(name,"%d", e_enqire[i].nr);
      sprintf(buffer, "+mat%d", e_enqire[e_enqire[i].nr].mat );
      pre_seta( buffer, "e", name );
      sprintf(buffer, "+grp%d", e_enqire[e_enqire[i].nr].group );
      pre_seta( buffer, "e", name  );
    }
  }
  else if (compareStrings(type, "MAX")>0)
  {
    sscanf( string, "%*s %lf",&scale->bmax);
    redraw(); glutPostRedisplay();
  }
  else if (compareStrings(type, "MERG")>0)
  {
    pre_merge( &string[na+1] );
  }
  else if (compareStrings(type, "MESH")>0)
  {
    pre_mesh( &string[na+1] );
  }
  else if (compareStrings(type, "MIDS")>0)
  {
    sscanf( string, "%*s %s %s", setname, comm);
    fixMidsideNodes( setname, comm );
  }
  else if (compareStrings(type, "MINUS")>0)
  {
    minus(&string[na+1] );
  }
  else if (compareStrings(type, "MIN")>0)
  {
    sscanf( string, "%*s %lf",&scale->bmin);
    redraw(); glutPostRedisplay();
  }
  else if (compareStrings(type, "MOVE")>0)
  {
    pre_move( &string[na+1] );
  }
  else if (compareStrings(type, "MOVI")>0)
  {
    pre_movie( &string[na+1] );
  }
  else if ( compareStrings(type, "MSG")>0 )
  {
    sscanf( string, "%*s%s", buffer );
    if ( compareStrings(buffer, "on")>0) printFlag=1; 
    else if ( compareStrings(buffer, "off")>0) printFlag=0;
    else printf(" %s not recognized (use on/off)\n", buffer);
  }
  else if (compareStrings(type, "NODE")>0)
  {
      pre_nod(&string[na+1]);
  }
  else if (compareStrings(type, "NURL")>0)
  {
    nurl( &string[na+1], addFlag );
  }
  else if (compareStrings(type, "NURS")>0)
  {
    length = sscanf( string, "%*s%s%s%s", name, comm, buffer  );

    /* check if a set of blended surfaces should make nurbs. The surfaces use then this nurbs */ 
    if((length==2) && ( name[0] == '!' ))
    {
      setNr=getSetNr(comm);
      if(setNr<0)
      {
        printf("ERROR: Set:[%s] in command:|%s| does not exist\n",comm,string);
        return(0);
      }
      /* try to create suitable nurbs */
      ibuf=set[setNr].anz_s;
      for ( i=0; i<ibuf; i++)
      {
        nr = set[setNr].surf[i];
        if (surf[nr].sh==-1)
        {
          k=createBlendedNurbs(nr, &point, line, lcmb, surf, &nurbs );
          if(k>-1)
	  {
            surf[nr].sh=k;
            repNurs(surf[nr].sh);
            seta( getSetNr("all"), "S", surf[nr].sh );
            for (j=0; j<anzGeo->sets; j++)
            {
              if(( set[j].name != (unsigned char *)NULL)&&( set[j].flag=='o')) seta( j, "S", surf[nr].sh );
            }
	  }
	}
      }
    }
    else nurs( &string[na+1], addFlag);
  }
  else if (compareStrings(type, "ORI")>0)
  {
    orientSet( &string[na+1] );
  }
  else if (compareStrings(type, "PLOT")>0)
  {
    plot( &string[na+1] );
  }
  else if (compareStrings(type, "PLUS")>0)
  {
    plus( &string[na+1] );
  }
  else if (compareStrings(type, "PNT")>0)
  {
    pre_pnt( &string[na+1], addFlag );
  }
  else if (compareStrings(type, "PROJ")>0)
  {
    pre_proj( &string[na+1] );
  }
  else if (compareStrings(type, "PROC")>0)
  {
    pre_proc( &string[na+1] );
  }
  else if (compareStrings(type, "PRNT")>0) prnt(&string[na+1]);
  else if (compareStrings(type, "QUIT")>0) exit(0);
  else if (compareStrings(type, "READ")>0)
  {
    pre_read(&string[na+1]); 
  }
  else if (compareStrings(type, "REP")>0)
  {
    nr=getSetNr(&string[na+1]);
    if(nr<0)
    {
      printf("ERROR: Set:[%s] in command:|%s| does not exist\n",&string[na+1],string);
      return(0);
    } 
    orientSet( &string[na+1] );
    delSet(specialset->bsur);
    if( compareStrings(&string[na+1],"all")>0)
    {
      for (i=0; i<anzGeo->l; i++) rep(i);
      for (i=0; i<anzGeo->nurl; i++) repNurl(i);
      for (i=0; i<anzGeo->nurs; i++) repNurs(i);
      /* delete the data-structures for trimming of the nurbs */
      for (i=0; i<anzGeo->nurs; i++) untrimNurs(i);
      /* recalculate the nurbs-trimming-points (after repNurs) */
      /* set "all" to avoid substitute surfs */
      j=getSetNr("all");
      if(j>=0) for (i=0; i<set[j].anz_s; i++) repSurf(set[j].surf[i]);
    }
    else
    {
      for (i=0; i<set[nr].anz_l; i++) rep(set[nr].line[i]);
      for (i=0; i<set[nr].anz_nurl; i++) repNurl(set[nr].nurl[i]);
      for (i=0; i<set[nr].anz_nurs; i++) repNurs(set[nr].nurs[i]);
      for (i=0; i<set[nr].anz_nurs; i++) untrimNurs(set[nr].nurs[i]);
      for (i=0; i<set[nr].anz_s; i++) repSurf(set[nr].surf[i]);
    }
    i=getSetNr(specialset->bsur);
    if(i>-1) if(set[i].anz_s)
      printf("WARNING: %d surfaces could not be filled, see set:%s\n", set[i].anz_s,specialset->bsur);
  }
  else if (compareStrings(type, "RNAM")>0)
  {
    sscanf(string, "%*s %s%s", name, xbuf );
    setNr=getSetNr(xbuf);
    if (setNr>-1)
    {
      printf ("ERROR: set:%s exist already\n", xbuf);
      return(-1);
    }

    setNr=getSetNr(name);
    if (setNr<0)
    {
      printf ("ERROR: set:%s does not exist\n", name);
    }
    else
    {
      printf(" rename %s", set[setNr].name ); 
      strcpy(set[setNr].name, xbuf );
      hashSet( sumAsci,set[setNr].name, setNr );
      printf(" to %s \n ", set[setNr].name ); 
    }
  }
  else if (compareStrings(type, "ROT")>0)
  {
    pre_rot( &string[na+1] );
  }
  else if ( compareStrings(type, "SAVE")>0 )
  {
    strcpy(setname,datin);
    for (i=strlen(datin); i>=0; i--)
    {
      if(datin[i]=='.')break;
    }
    setname[i]=(unsigned char)NULL;
#ifdef WIN32
    sprintf (buffer, "move /y %s %s.fbb", datin, setname );
#else
    sprintf (buffer, "mv %s %s.fbb", datin, setname );
#endif
    if(compare(&datin[i+1],"fbd",3)==3) system (buffer);
    pre_write(" all fbd ");
    if( compareStrings( setname, "all")<1 )
    {
#ifdef WIN32
      sprintf (buffer, "move /y all.fbd %s.fbd", setname );
#else
      sprintf (buffer, "mv all.fbd %s.fbd", setname );
#endif
      system (buffer);
    }     
  }
  else if ( compareStrings(type, "SCAL")>0 )
  {
    entity[0]=0; x=0.;
    length=sscanf(&string[na+1],"%s %lf", entity, &x);
    /* vector length */
    if(entity[0]=='v')
    {
      if(x!=0.)  v_scale*=x;
      else v_scale=1.;
      updateDispLists();
    }
    else if(entity[0]=='d') 
    {
      if(x!=0.) anim_faktor*=x;
      else  anim_faktor=1.;
      if(addDispFlag==1)
      { 
        node=addDispToCoordinates(node);
        node=addDispToCoordinates(node);
      }  
      redraw();
    }
    else if(entity[0]=='s') 
    {
      scale->bmin*=x; scale->bmax*=x;
      redraw(); glutPostRedisplay();
    }
    else printf("type:%s not known, factor:%lf\n", entity, x);
  }
  else if (compareStrings(type, "SEND")>0)
  {
    pre_write( &string[na+1] );
  }
  else if (compareStrings(type, "SEQA")>0)
  {
    /* if the name is in use and no valid data are spec. then the seq will be overwritten */
    /* if the name is in use and valid data are spec. then the command is ignored */

    /* for the moment the commands AFTE and BEFO are wrong interpreted */

    /* determine the commands */
    na= sscanf( string, "%*s %s%s%s%s ", name, dat[0],dat[1],dat[2]);
    /* search for valid commands */
    if((dat[0][0]=='A')||(dat[0][0]=='a'))
    {
      if (addFlag) { for(j=strlen(name); j>=0; j--) name[j+1]=name[j]; name[0]='%'; }
      operateAlias( name, "se" );
      if( na < 4) return(0);
      strcpy(comm,"AFTE"); 
      if (addFlag) { for(j=strlen(dat[1]); j>=0; j--) dat[1][j+1]=dat[1][j]; dat[1][0]='%'; }
      operateAlias( dat[1], "p" );
      strcpy(posn,dat[1]); 
      strcpy(entity,dat[2]);
      strcpy(format
      , "%*s%*s%*s%*s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"); 
    }
    else if((dat[0][0]=='B')||(dat[0][0]=='b'))
    {
      if (addFlag) { for(j=strlen(name); j>=0; j--) name[j+1]=name[j]; name[0]='%'; }
      operateAlias( name, "se" );
      if( na < 4) return(0);
      strcpy(comm,"BEFO"); 
      if (addFlag) { for(j=strlen(dat[1]); j>=0; j--) dat[1][j+1]=dat[1][j]; dat[1][0]='%'; }
      operateAlias( dat[1], "p" );
      strcpy(posn,dat[1]); 
      strcpy(entity,dat[2]);
      strcpy(format
      , "%*s%*s%*s%*s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"); 
    }
    else if ((dat[0][0]=='E')||(dat[0][0]=='e'))
    {
      if (addFlag) { for(j=strlen(name); j>=0; j--) name[j+1]=name[j]; name[0]='%'; }
      operateAlias( name, "se" );
      if( na < 3) return(0);
      strcpy(comm,"END"); 
      strcpy(entity,dat[1]); 
      strcpy(format
      , "%*s%*s%*s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"); 
    }
    else
    {
      if (addFlag) { for(j=strlen(name); j>=0; j--) name[j+1]=name[j]; name[0]='!'; }
      operateAlias( name, "se" );
      if( na < 3) return(0);
      strcpy(comm,"NEW"); 
      strcpy(entity,dat[0]); 
      strcpy(format
      , "%*s%*s%*s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"); 
    }

    j=anz_seq=0;
  newline:;
    na =   sscanf( string,format
              , dat[0],dat[1],dat[2],dat[3],dat[4],dat[5], dat[6],dat[7],dat[8],dat[9]
              , dat[10],dat[11],dat[12],dat[13],dat[14],dat[15], dat[16],dat[17],dat[18],dat[19]);
    anz_seq+=na;
    if( (seq = (unsigned char **)realloc((unsigned char **)seq, (anz_seq)*sizeof(unsigned char *))) == NULL )
    { printf(" ERROR: realloc failure in interpreter()\n\n"); return(-1); }
    for (i=anz_seq-na; i<anz_seq; i++)
    {
      if( (seq[i]= (unsigned char *)malloc( MAX_LINE_LENGTH*sizeof(unsigned char))) == NULL )
      { printf(" ERROR: malloc failure in interpreter()\n\n"); return(-1); }
    }

    /* look if the command-line continues */
    for (i=0; i<na; i++)
    {
      /* printf("dat:%d |%s|\n",i, dat[i]); */
      if(dat[i][0]=='=')
      {
        length = frecord( handle1, string);
        strcpy(format
        , "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"); 
        goto newline;
      }
      if (addFlag) { for(l=strlen(dat[i]); l>=0; l--) dat[i][l+1]=dat[i][l]; dat[i][0]='%'; }
      operateAlias( dat[i], "p" );
      strcpy(seq[j], dat[i]);
      j++;
    }

    if((entity[0]=='N')||entity[0]=='n') type[0]='n';
    else if((entity[0]=='E')||entity[0]=='e') type[0]='e';
    else if((entity[0]=='P')||entity[0]=='p') type[0]='p';
    else if((entity[0]=='L')||entity[0]=='l') type[0]='l';
    else if((entity[0]=='S')||entity[0]=='s') type[0]='s';
    else if((entity[0]=='B')||entity[0]=='b') type[0]='b';
    else 
    {
      errMsg(" ERROR in SEQA: entity:%s not known\n", entity );
      return(0);
    }
    /* mark the set as a sequence-set */
    type[1]='s';

    posn_length=strlen( posn );
    if(comm[0]=='A')
    {
      /* the set exists */
      setNr=getSetNr( name );
      if (setNr<0)
      {
        printf (" ERROR: set:%s does not exist\n", name);
        return(0);
      }

      if((buf=(unsigned char **)malloc((set[setNr].anz_p+anz_seq)*sizeof(unsigned char *)))==NULL)
      { printf(" ERROR: realloc failure in interpreter()\n\n"); return(-1); }
      for (i=0; i<(set[setNr].anz_p+anz_seq); i++)
      {
        if( (buf[i]= (unsigned char *)malloc( MAX_LINE_LENGTH*sizeof(unsigned char))) == NULL )
        { printf(" ERROR: realloc failure in interpreter()\n\n"); return(-1); }
      }

      j=0;
      if( type[0]=='p') for (i=0; i<set[setNr].anz_p; i++)
      {
        strcpy( buf[j], point[set[setNr].pnt[i]].name); j++;
        length=strlen( point[set[setNr].pnt[i]].name );
        if(( compareStrings( point[set[setNr].pnt[i]].name, posn)>0)
          &&( posn_length==length))
        {
          for (k=0; k<anz_seq; k++) strcpy( buf[j], seq[k]); j++;
        }
      }     
      set[setNr].anz_p = 0;
      for (i=0; i<j; i++)
      {
        pre_seta( name, type, buf[i]);
      }

      for (i=0; i<(set[setNr].anz_p+anz_seq); i++) free(buf[i]); free(buf);
    }
    else if(comm[0]=='B')
    {
      /* the set exists */
      setNr=getSetNr( name );
      if (setNr<0)
      {
        printf (" ERROR: set:%s does not exist\n", name);
        return(0);
      }

      if((buf=(unsigned char **)malloc((set[setNr].anz_p+anz_seq)*sizeof(unsigned char *)))==NULL)
      { printf(" ERROR: realloc failure in interpreter()\n\n"); return(-1); }
      for (i=0; i<(set[setNr].anz_p+anz_seq); i++)
      {
        if( (buf[i]= (unsigned char *)malloc( MAX_LINE_LENGTH*sizeof(unsigned char))) == NULL )
        { printf(" ERROR: realloc failure in interpreter()\n\n"); return(-1); }
      }

      j=0;
      if( type[0]=='p') for (i=0; i<set[setNr].anz_p; i++)
      {
        length=strlen( point[set[setNr].pnt[i]].name );
        if(( compareStrings( point[set[setNr].pnt[i]].name, posn)>0)
          &&( posn_length==length))
        {
          for (k=0; k<anz_seq; k++) strcpy( buf[j], seq[k]); j++;
        }
        strcpy( buf[j], point[set[setNr].pnt[i]].name); j++;
      }     
      set[setNr].anz_p = 0;
      for (i=0; i<j; i++)
      {
        pre_seta( name, type, buf[i]);
      }

      for (i=0; i<(set[setNr].anz_p+anz_seq); i++) free(buf[i]); free(buf);
    }
    else if(comm[0]=='E')
    {
      for (i=0; i<anz_seq; i++)
      {
        pre_seta( name, type, seq[i]);
      }
    }
    else if(comm[0]=='N')
    {
      delSet(name);
      for (i=0; i<anz_seq; i++)
      {
        pre_seta( name, type, seq[i]);
      }
    }

    for (i=0; i<anz_seq; i++) free(seq[i]);
  }
  else if (compareStrings(type, "SETA")>0)
  {
    na =   sscanf( string, "%*s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
               name, type, dat[0],dat[1],dat[2],dat[3],dat[4],dat[5], dat[6],dat[7],dat[8],dat[9],
               dat[10],dat[11],dat[12],dat[13],dat[14],dat[15], dat[16],dat[17],dat[18],dat[19]);

    /* check if the setname matches a seqential-set (sq). if yes do not add entities */
    l=getSetNr(name);
    if (l>-1)
    {
      if(set[l].type==1)
      {
        printf("ERROR: setname:%s in use by a sequence. Set can not be created.\n", name);
        return(0);
      }
    }

    /* Single letters (except 'se') determine the type of the following entities in cgx. */
    /* In FAM no indication of the type is given. So if the name of the entity */
    /* consists only of a lingle letter (or 'se'), it will be ignored. */ 
    if (((type[0]=='n')&&(type[1]=='\0'))||
        ((type[0]=='e')&&(type[1]=='\0'))||
        ((type[0]=='f')&&(type[1]=='\0'))||
        ((type[0]=='p')&&(type[1]=='\0'))||
        ((type[0]=='l')&&(type[1]=='\0'))||
        ((type[0]=='c')&&(type[1]=='\0'))||
        ((type[0]=='s')&&(type[1]=='\0'))||
        ((type[0]=='s')&&(type[1]=='e'))||
        ((type[0]=='L')&&(type[1]=='\0'))||
        ((type[0]=='S')&&(type[1]=='\0'))||
        ((type[0]=='b')&&(type[1]=='\0')) )
    {
      /* look if a sequence is defined */
      if((dat[1][0]=='-')&&(dat[1][1]=='\0'))
      {
        if((type[0]!='n')&&(type[0]!='e')) 
        {
          printf("ERROR: sequence only possible for nodes and elements. Set %s can not be created.\n", name);
          return(0);
        }
        for(i=atoi(dat[0]); i<=atoi(dat[2]); i+=atoi(dat[3]) )
        {
          sprintf(buffer,"%d",i);
          pre_seta( name, type, buffer);
        }
      }
      else
      {
        for (i=0; i<na-2; i++)
        {
          if (addFlag) { for(l=strlen(dat[i]); l>=0; l--) dat[i][l+1]=dat[i][l]; dat[i][0]='%'; }
          operateAlias( dat[i], type );
          pre_seta( name, type, dat[i]);
        }
      }

      if((type[0]=='s')&&(type[1]=='e'))
      {
        completeSet( name, "do");
      }
    }
    else
    {
      /* items of unknown type, determine each type */
      if (addFlag) { for(l=strlen(type); l>=0; l--) type[l+1]=type[l]; type[0]='%'; }
      ibuf=0;
      operateAlias( type, "b" ); if (getBodyNr(type) >-1)  {  pre_seta( name, "b", type); goto next_seta;  } 
      operateAlias( type, "s" ); if (getSurfNr(type) >-1)  {  pre_seta( name, "s", type); goto  next_seta;  } 
      operateAlias( type, "c" ); if (getLcmbNr(type) >-1)  {  pre_seta( name, "c", type); goto  next_seta;  } 
      operateAlias( type, "l" ); if (getLineNr(type) >-1)  {  pre_seta( name, "l", type); goto  next_seta;  } 
      operateAlias( type, "p" ); if (getPntNr(type) >-1)   {  pre_seta( name, "p", type); goto  next_seta;  } 
      operateAlias( type, "se" ); if (getSetNr(type) >-1)   {  pre_seta( name, "se", type); ibuf=1; goto  next_seta;  } 
      next_seta:;

      for (i=0; i<na-2; i++)
      {
        if (addFlag) { for(l=strlen(dat[i]); l>=0; l--) dat[i][l+1]=dat[i][l]; dat[i][0]='%'; }
        operateAlias( dat[i], "b" ); if (getBodyNr(dat[i]) >-1)  { pre_seta( name, "b",dat[i] ); goto next_dat;  } 
        operateAlias( dat[i], "s" ); if (getSurfNr(dat[i]) >-1)  { pre_seta( name, "s",dat[i] ); goto  next_dat;  } 
        operateAlias( dat[i], "c" ); if (getLcmbNr(dat[i]) >-1)  { pre_seta( name, "c",dat[i] ); goto  next_dat;  } 
        operateAlias( dat[i], "l" ); if (getLineNr(dat[i]) >-1)  { pre_seta( name, "l",dat[i] ); goto  next_dat;  }
        operateAlias( dat[i], "p" ); if (getPntNr(dat[i]) >-1)   { pre_seta( name, "p",dat[i] ); goto  next_dat;  } 
        operateAlias( dat[i], "se" ); if (getSetNr(dat[i]) >-1)   {  pre_seta( name, "se",dat[i]); ibuf=1; goto  next_dat;  } 
      next_dat:;
      }
      if(ibuf)
      {
        completeSet( name, "do");
      }
    }
  }
  else if (compareStrings(type, "SETC")>0)
  {
    for(i=0; i<MAX_LINE_LENGTH; i++) name[i]=0;
    length=sscanf( string, "%*s%s", name);
    setc(name);
  }
  else if (compareStrings(type, "SETO")>0)
  {
    name[0]=(unsigned char)NULL;
    length=sscanf( string, "%*s%s", name);
    seto(name);
  }
  else if (compareStrings(type, "SETR")>0)
  {
    na =   sscanf( string, "%*s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
               name, type, dat[0],dat[1],dat[2],dat[3],dat[4],dat[5], dat[6],dat[7],dat[8],dat[9],
               dat[10],dat[11],dat[12],dat[13],dat[14],dat[15], dat[16],dat[17],dat[18],dat[19]);

    operateAlias( name, "se" );
    setNr=getSetNr( name );
    if (setNr<0)
    {
      errMsg(" ERROR: Set (%s) is undefined\n", name );
      return(0);
    }
    /* only lowercase letters are possible as type, */
    /* otherwhise a conflict with fam occurs */
    if ((type[0]=='n')||
        (type[0]=='e')||
        (type[0]=='f')||
        (type[0]=='p')||
        (type[0]=='l')||
        (type[0]=='c')||
        (type[0]=='s')||
        (type[0]=='b') )
    {
      for (i=0; i<na-2; i++)
      {
        operateAlias( dat[i], type );
        if ((type[0]=='s')&&(type[1]=='e'))
        {
          nr=getSetNr(dat[i]);
          if(nr>-1)
          {
            /* remove the contents of nr from setNr */
            for (j=0; j<set[nr].anz_n; j++) setr( setNr, "n", set[nr].node[j] );
            for (j=0; j<set[nr].anz_e; j++) setr( setNr, "e", set[nr].elem[j] );
            for (j=0; j<set[nr].anz_f; j++) setr( setNr, "f", set[nr].face[j] );
            for (j=0; j<set[nr].anz_p; j++) setr( setNr, "p", set[nr].pnt[j] );
            for (j=0; j<set[nr].anz_l; j++) setr( setNr, "l", set[nr].line[j] );
            for (j=0; j<set[nr].anz_c; j++) setr( setNr, "c", set[nr].lcmb[j] );
            for (j=0; j<set[nr].anz_s; j++) setr( setNr, "s", set[nr].surf[j] );
            for (j=0; j<set[nr].anz_b; j++) setr( setNr, "b", set[nr].body[j] );
          }
        }
        else if (type[0]=='n') nr=atoi(dat[i]);
        else if (type[0]=='e') nr=atoi(dat[i]);
        else if (type[0]=='f') nr=atoi(dat[i]);
        else if (type[0]=='p') nr=getPntNr(dat[i]);
        else if (type[0]=='l') nr=getLineNr(dat[i]);
        else if (type[0]=='c') nr=getLcmbNr(dat[i]);
        else if (type[0]=='s') nr=getSurfNr(dat[i]);
        else if (type[0]=='b') nr=getBodyNr(dat[i]);
        setr( setNr, type, nr);
      }
    }
    else
    {
      /* items of unknown type, determine each type */
      if (getBodyNr(type) >-1)
      { operateAlias( type, "b" ); setr( setNr, "b", getBodyNr(type)); } 
      if (getSurfNr(type) >-1)
      { operateAlias( type, "s" ); setr( setNr, "s", getSurfNr(type)); } 
      if (getLcmbNr(type) >-1)
      { operateAlias( type, "c" ); setr( setNr, "c", getLcmbNr(type)); } 
      if (getLineNr(type) >-1)
      { operateAlias( type, "l" ); setr( setNr, "l", getLineNr(type)); } 
      if (getPntNr(type) >-1)
      { operateAlias( type, "p" ); setr( setNr, "p", getPntNr(type)); } 
      for (i=0; i<na-2; i++)
      {
        if (getBodyNr(dat[i]) >-1)
        { operateAlias( dat[i], "b" ); setr( setNr, "b", getBodyNr(dat[i]) ); } 
        if (getSurfNr(dat[i]) >-1)
        { operateAlias( dat[i], "s" ); setr( setNr, "s", getSurfNr(dat[i]) ); } 
        if (getLcmbNr(dat[i]) >-1)
        { operateAlias( dat[i], "c" ); setr( setNr, "c", getLcmbNr(dat[i]) ); } 
        if (getLineNr(dat[i]) >-1)
        { operateAlias( dat[i], "l" ); setr( setNr, "l", getLineNr(dat[i]) ); }
        if (getPntNr(dat[i]) >-1)
        { operateAlias( dat[i], "p" ); setr( setNr, "p", getPntNr(dat[i]) ); } 
      }
    }
  }
  else if (compareStrings(type, "SPLIT")>0)
  {
    pre_split( &string[na+1] );
  }
  else if (compareStrings(type, "SURF")>0)
  {
    pre_surf(&string[na+1]);
  }
  else if (compareStrings(type, "SWEP")>0)
  {
    pre_swep(&string[na+1]);
  }
  else if (compareStrings(type, "STEPS")>0)
  {
    steps= atoi( &string[na+1]  );
#if INX_MODE
    calcOffset();
    maxIndex= offset+steps-1;
#endif
    redraw(); glutPostRedisplay();
  }
  else if (compareStrings(type, "TEXT")>0)
  {
    stos( &string[na], 1, strlen(&string[na]), picture_text);
  }
  else if (compareStrings(type, "TRA")>0)
  {
    length=sscanf( string, "%*s %s %lf", posn, &dx);
    printf("dtx:%f dty:%f dx:%f\n", dtx, dty, dx);
    if(posn[0]=='u') dty+= (dx*2);
    if(posn[0]=='d') dty-= (dx*2);
    if(posn[0]=='l') dtx-= (dx*2);
    if(posn[0]=='r') dtx+= (dx*2);
    glutPostRedisplay();
    updateDispLists();
  }
  else if (compareStrings(type, "VOLU")>0)
  {
    pre_volu(&string[na+1]);
  }
  else if (compareStrings(type, "ZAP")>0)
  {
    if( zap(&string[na+1])==-1)
      printf (" ERROR in ZAP: set:%s does not exist\n",&string[na+1] );
  }
  else if (compareStrings(type, "ZOOM")>0)
  {
    length=sscanf( string, "%*s %lf %lf %lf %lf", &wx[0], &wy[0], &wx[1], &wy[1]);
    if (length==4)
    {
      wx[0]*=2.;
      wx[1]*=2.;
      wy[0]*=2.;
      wy[1]*=2.;

      wx[0]+=-1.;
      wx[1]+=-1.;
      wy[0]+=-1.;
      wy[1]+=-1.;
    }
    else
    {
      dx=1./wx[0];
      wx[0]=wy[0]=-dx;
      wx[1]=wy[1]=dx;
    }
    zoom(wx[0], wy[0], wx[1], wy[1]);
  }
  else if ((type[0]== '!')||(type[0]== '#')||(type[0]== '$'))
  {
    printf(" %s\n", string );
  }
  else
  {
    printf(" key:%s from string %s not known\n", type, string);
  }
  return(1);
}


void readfbd( unsigned char *datin, int addFlag )
{
  FILE      *handle1;
  int       result=0, length, i, na, gtolFlag=0;
  unsigned char type[MAX_LINE_LENGTH];
  unsigned char string[MAX_LINE_LENGTH];
  double max[3], min[3];

  handle1 = fopen (datin, "r");
  if (handle1==NULL)
  {
    printf (" ERROR: The input file \"%s\" could not be opened.\n\n", datin);
    return;
  }
  else  printf ("\n%s opened",datin);

  printf ("\n reading file\n");
  while (result > -1)
  {
    length = frecord( handle1, string);
    type[0]=0;
    na=0; while(string[na]==' ') na++;
    na+= sword( string, type);
    if( string[length]== (unsigned char)EOF)  break;
    /* printf ("\n record:%s", &string[0]); */
    result=commandoInterpreter( type, string, na, length, handle1, addFlag, &gtolFlag );
  }
  fclose( handle1);

  if(!gtolFlag)
  {
    /* calculate the geometric tolerance based on all line-end-points */
    for(i=0; i<3; i++)
    {
      max[i]=-MAXVALUE;
      min[i]= MAXVALUE;
    }
    for(i=0; i<anzGeo->l; i++) if(line[i].name!=(unsigned char *)NULL)
    {
      if(point[line[i].p1].px > max[0]) max[0]=point[line[i].p1].px;
      if(point[line[i].p2].px > max[0]) max[0]=point[line[i].p2].px;
      if(point[line[i].p1].py > max[1]) max[1]=point[line[i].p1].py;
      if(point[line[i].p2].py > max[1]) max[1]=point[line[i].p2].py;
      if(point[line[i].p1].pz > max[2]) max[2]=point[line[i].p1].pz;
      if(point[line[i].p2].pz > max[2]) max[2]=point[line[i].p2].pz;
  
      if(point[line[i].p1].px < min[0]) min[0]=point[line[i].p1].px;
      if(point[line[i].p2].px < min[0]) min[0]=point[line[i].p2].px;
      if(point[line[i].p1].py < min[1]) min[1]=point[line[i].p1].py;
      if(point[line[i].p2].py < min[1]) min[1]=point[line[i].p2].py;
      if(point[line[i].p1].pz < min[2]) min[2]=point[line[i].p1].pz;
      if(point[line[i].p2].pz < min[2]) min[2]=point[line[i].p2].pz;
    }
    gtol=0.;
    for(i=0; i<3; i++)
    {
      max[i]-=min[i];
      if(max[i]>gtol) gtol=max[i];
    }
    gtol=GTOL*gtol*scale->w;
    printf("\ngtol set to:%e\n\n", gtol);
  }

  /* delete the entities in specialSet->zap */
  zap(specialset->zap);

  descalNodes ( anz->n, node, scale );
  descalPoints( anzGeo->p, point, scale);
  descalSurfs( anzGeo->s, surf, scale);
  getScaleValues( anz->n, anzGeo->p, point, node, scale);
  scalNodes ( anz->n, node, scale );
  scalPoints ( anzGeo->p, point, scale );
  scalSurfs( anzGeo->s, surf, scale);

  /* recalculate the line-shapes */
  for (i=0; i<anzGeo->l; i++) rep(i);
  /* recalculate the nurbl-controll-points */
  for (i=0; i<anzGeo->nurl; i++) repNurl(i);
  /* recalculate the nurbs-controll-points */
  for (i=0; i<anzGeo->nurs; i++) repNurs(i);
  /* correct the orientation of all entities */
  orientSet( "all" );

  /* das neue netz muss noch zur beleuchteten ansicht aufbereitet werden  */
  num_olc       = anz->l;
  makeSurfaces();
  allocUtilityData();

  printf (" done \n\n");
}


/*------------------------------------------------------------------*/
/* Daten im frd-format einlesen                                     */
/*------------------------------------------------------------------*/
void readfrdfile( unsigned char *datin, unsigned char *setname )
{
  register int i, setNr=-1;
  unsigned char  datum[MAX_LINE_LENGTH];
  Summen    anzr[1];
  Nodes     *noder=NULL;
  Elements  *elemr=NULL;
  Datasets  *lcaser=NULL;


  if(printFlag) printf (" read %s in set:%s\n", datin, setname );
  readfrd( datin, anzr, &noder, &elemr, &lcaser);
  if(printFlag) printf (" Nodes:%d Elements:%d Datasets:%d \n\n", anzr->n, anzr->e, anzr->l);


  if(anzr->n>0)
  {
    for (i=0; i<anzr->n; i++)
    {
      if ((noder[i].nr <= anz->nmax)&&(noder[i].nr >= anz->nmin))
      {
        if(setNr<0) { sprintf (datum, "%d", noder[i].nr); setNr=pre_seta( setname, "n", datum ); }
        else seta( setNr, "n", noder[i].nr );
      }
      else printf (" node %d is outside range of known nodes\n", noder[i].nr);
    }
  }
  if(anzr->e>0)
  {
    for (i=0; i<anzr->e; i++)
    {
      if ((elemr[i].nr <= anz->emax)&&(elemr[i].nr >= anz->emin))
      {
        if(setNr<0) { sprintf (datum, "%d", elemr[i].nr); pre_seta( setname, "e", datum ); }
        else seta( setNr, "e", elemr[i].nr );
      }
    else printf (" element %d is outside range of known elements\n", elemr[i].nr);
    }
  }
  free(elemr);
  free(noder);
  free(lcaser);
}

long swap_long(char *ptr)
{
  long buf,buf2;
  char *pbuf, *pbuf2;

  pbuf=&buf;
  pbuf2=&buf2;

  *pbuf2=*(ptr);  pbuf2++;
  *pbuf2=*(ptr+1);  pbuf2++;
  *pbuf2=*(ptr+2);  pbuf2++;
  *pbuf2=*(ptr+3); 

  *pbuf=*(ptr+3);  pbuf++;
  *pbuf=*(ptr+2);  pbuf++;
  *pbuf=*(ptr+1);  pbuf++;
  *pbuf=*(ptr);

  // printf("in:%u out:%u\n", buf2, buf);
  return(buf);
}


#define BYTES 100000000
BGpicture *readxwd( unsigned char * datin)
{
  int i, j, k, n, fp, offset;
  int bytes_per_line, bits_per_pixel;
  XWDFileHeader *xwdheader;

  static char buf[BYTES];
  static char buf2[BYTES];
  static BGpicture bgpicture;

  char aux;

  fp = open ( datin, O_RDONLY);
  if( read( fp, buf, BYTES)<1)
  {
    printf("ERROR: File:%s could not be opened\n", datin) ;
    return(0);
  }
  xwdheader=&buf[0];

  /* swap from big-endian to little-endian */
  printf("header: %d or swaped: %d\n", xwdheader->header_size, swap_long(&xwdheader->header_size));
  if ((xwdheader->header_size>300)||(xwdheader->header_size<100))
  {
    offset=swap_long(&xwdheader->header_size)+swap_long(&xwdheader->ncolors)*sz_XWDColor;
    bytes_per_line=swap_long(&xwdheader->bytes_per_line);
    bgpicture.width=(GLsizei)swap_long(&xwdheader->window_width);
    bgpicture.height=(GLsizei)swap_long(&xwdheader->window_height);
    bits_per_pixel=(int)swap_long(&xwdheader->bits_per_pixel);

    /*
        printf(" XWD_FILE_VERSION above 	      :%d \n", swap_long(&xwdheader->file_version ));        
        printf(" ZPixmap or XYPixmap 		      :%d \n", swap_long(&xwdheader->pixmap_format ));       
        printf(" Pixmap depth 			      :%d \n", swap_long(&xwdheader->pixmap_depth ));        
        printf(" Pixmap width 	       		       :%d\n", swap_long(&xwdheader->pixmap_width ));        
        printf(" Pixmap height 		      	      :%d \n", swap_long(&xwdheader->pixmap_height ));       
        printf(" Bitmap x offset, normally 0   	      :%d\n", swap_long(&xwdheader->xoffset ));             
        printf(" of image data: MSBFirst, LSBFirs     :%d \n", swap_long(&xwdheader->byte_order ));          
        printf(" bitmap_unit			      :%d \n", swap_long(&xwdheader->bitmap_unit ));
        printf(" bitmaps only: MSBFirst, LSBFirst     :%d\n", swap_long(&xwdheader->bitmap_bit_order ));    
        printf(" bitmap_pad			      :%d \n", swap_long(&xwdheader->bitmap_pad ));
        printf(" Bits per pixel 		      :%d \n", swap_long(&xwdheader->bits_per_pixel ));      
        printf(" bytes_per_line			      :%d \n", swap_long(&xwdheader->bytes_per_line ));
        printf(" Class of colormap 		      :%d \n", swap_long(&xwdheader->visual_class ));        
        printf(" Z red mask			      :%d \n", swap_long(&xwdheader->red_mask ));            
        printf(" Z green mask			      :%d \n", swap_long(&xwdheader->green_mask ));          
        printf(" Z blue mask 			      :%d \n", swap_long(&xwdheader->blue_mask ));           
        printf(" Log2 of distinct color values	      :%d \n", swap_long(&xwdheader->bits_per_rgb ));        
        printf(" Number of entries in colormap; not used? :%d  \n", swap_long(&xwdheader->colormap_entries ));    
        printf(" Number of XWDColor structures	       :%d\n", swap_long(&xwdheader->ncolors ));             
        printf(" Window width			      :%d \n", swap_long(&xwdheader->window_width ));        
        printf(" Window height			      :%d \n", swap_long(&xwdheader->window_height ));       
        printf(" Window upper left X coordinate	      :%d \n", swap_long(&xwdheader->window_x ));            
        printf(" Window upper left Y coordinate	      :%d \n", swap_long(&xwdheader->window_y ));            
        printf(" Window border width                  :%d \n", swap_long(&xwdheader->window_bdrwidth ));     
    */
  }
  else
  {
    offset=xwdheader->header_size + xwdheader->ncolors*sz_XWDColor;
    bytes_per_line=xwdheader->bytes_per_line;
    bgpicture.width=(GLsizei)xwdheader->window_width;
    bgpicture.height=(GLsizei)xwdheader->window_height;
    bits_per_pixel=(int)xwdheader->bits_per_pixel;

    printf("ncolors:%d\n", xwdheader->ncolors);
  }

  bgpicture.name=&buf[100];
  printf("windowName:%s\n", bgpicture.name);
  if(bits_per_pixel==32) { bgpicture.format=GL_RGBA;  bgpicture.type=GL_UNSIGNED_BYTE; }
  if(bits_per_pixel==24) { bgpicture.format=GL_RGB;   bgpicture.type=GL_UNSIGNED_BYTE; }
  if(bits_per_pixel==8)  { bgpicture.format=GL_RGBA;  bgpicture.type=GL_UNSIGNED_BYTE; }
  if(bits_per_pixel==1)  { bgpicture.format=GL_COLOR_INDEX;  bgpicture.type=GL_BITMAP; }


  /* inverse the lines (last is first) */
  n=0;
  for(j=0; j<bgpicture.height; j++)
  {
    for(i=0; i<bytes_per_line; i++)
    {
      buf2[n]=buf[offset-1+ (bytes_per_line*(bgpicture.height-j-1)) +i +1];
      if(bits_per_pixel==8)
      {
        for (k=1; k<4; k++) buf2[n+k]=buf2[n];
        n+=3;
      }
      n++;
    }
  }
  /* convert the image data from RGBA to BGRA if 32bit picture */
  if (bits_per_pixel == 32) for (i=0; i < bgpicture.width * bgpicture.height * bits_per_pixel/8 ; i+= bits_per_pixel/8)
  {
      aux = buf2[i];
      buf2[i] = buf2[i+2];
      buf2[i+2] = aux;
  }

  bgpicture.pixels=&buf2[0];
  printf("pixel-offset:%d\n", offset);
  printf("bits_per_pixel:%d\n", bits_per_pixel);
  printf("bytes_per_line:%d\n", bytes_per_line);
  printf("window_width:%d\n", bgpicture.width);
  printf("window_height:%d\n", bgpicture.height);
  printf("window-pixels:%d\n", bgpicture.pixels);

  return(&bgpicture);
}

BGpicture *_readxwd(void)
{
   int i, j, c;
   static GLubyte checkImage[64][64][3];
   static BGpicture bgpicture;
   static char name[100];

   for (i = 0; i < 64; i++) {
      for (j = 0; j < 64; j++) {
         c = ((((i&0x8)==0)^((j&0x8))==0))*255;
         checkImage[i][j][0] = (GLubyte) c/(i+1);
         checkImage[i][j][1] = (GLubyte) c/(j+1);
         checkImage[i][j][2] = (GLubyte) c;
      }
   }
  strcpy(name,"CheckImage");

  bgpicture.name=&name[0];
  bgpicture.width=64;
  bgpicture.height=64;
  bgpicture.format=GL_RGB;
  bgpicture.type=GL_UNSIGNED_BYTE;
  bgpicture.pixels=&checkImage;

  return(&bgpicture);
}


void pre_read( unsigned char *record )
{
  unsigned char      datin[MAX_LINE_LENGTH];
  unsigned char      param1[MAX_LINE_LENGTH];
  unsigned char      param2[MAX_LINE_LENGTH];
  unsigned char      ext[MAX_LINE_LENGTH];
  int       i,j,n,n1,n2,l,sets, length;
  Summen    apre[1];
  Nodes     *npre=NULL;
  Elements  *epre=NULL;
  Datasets  *lpre=NULL;
  int *sumface=NULL, **iface=NULL;
  int ***facebuf=NULL;
  int anz_nmax, anz_emax;
  int anz_nmin, anz_emin;

  length = sscanf( record, "%s %s %s", datin, param1, param2 );
  if(length==1) strcpy(param1,"read"); 

  /* the filetype is determined by its extension except fbd */
  /* frd: frd-format, nodes, element-numbers will be stored in a set, but are not re-defined */
  /* inp: abaqus format, nodes, elements, sets */

  /* determine the extension */
  for(i=strlen(datin); i>=0; i--) if(datin[i]=='.') break;
  for(j=++i; j<strlen(datin); j++) ext[j-i]=datin[j]; ext[j-i]=0;

  if (compare( ext, "frd", 3)== 3)
  { readfrdfile(datin,param1); if(length==1) printf("\n entities stored in set:%s\n",param1); }  
  else if(param1[0]=='-')
  { readlist( datin, &param1[1] ); }
  else if(compare( ext, "xwd", 3)== 3)
  { bgpicture=readxwd( datin); }
  else if((compare( ext, "edg", 3)== 3)||(compare( param1, "edg", 3)== 3)) 
  {
    apre->n=0;
    apre->e=0;
    apre->f=0;
    apre->g=0;
    apre->emax=0;  apre->emin=MAXVALUE;
    apre->nmax=0;  apre->nmin=MAXVALUE;
    apre->l=0;
    readEdges( datin, apre, &npre, &epre );
    printf("add nodes:%d maxnr:%d\n",apre->n, apre->nmax);  

    /* modify node and element numbers if param2 == add */
    if((param2[0]=='A')||(param2[0]=='a'))
    {
      renumberfrd( anz->emax+1, anz->nmax+1, apre, &npre, &epre, &lpre );
    }

    /* create the nodes and elements or overwrite old ones */
    for(i=0; i<apre->n; i++)  nod( anz, &node, 1, npre[i].nr, npre[npre[i].nr].nx, npre[npre[i].nr].ny, npre[npre[i].nr].nz, 1 );
    for(i=0; i<apre->e; i++) elem_define( epre[i].nr, epre[i].type, epre[i].nod, 1, 0 );
    printf("elements:%d maxnr:%d\n",anz->e, anz->emax);  

    free(npre);
    free(epre);

    /* new scaling for drawing */
    descalNodes ( anz->n, node, scale );
    descalPoints( anzGeo->p, point, scale);
    descalSurfs( anzGeo->s, surf, scale);
    getScaleValues( anz->n, anzGeo->p, point, node, scale);
    scalNodes ( anz->n, node, scale );
    scalPoints ( anzGeo->p, point, scale );
    scalSurfs( anzGeo->s, surf, scale);

    /* from here code from pre_mesh() */
    /* das neue netz muss noch zur beleuchteten ansicht aufbereitet werden  */
    makeSurfaces();
    allocUtilityData();
        
    updateDispLists(); 
  }
  else if((compare( ext, "inp", 3)== 3)||(compare( param1, "inp", 3)== 3)) 
  {
    /* free the additional midside-nodes for higher order elements */
    anz->nmax= num_onodmax;
    anz->n= num_onod;

    apre->n=0;
    apre->e=0;
    apre->f=0;
    apre->g=0;
    apre->emax=0;  apre->emin=MAXVALUE;
    apre->nmax=0;  apre->nmin=MAXVALUE;
    apre->l=0;

    /* The seta command for nodes and elements will only work if anz->nmax etc are set temporarily to values */
    /* covering the numbers in the inp file */
    anz_nmax= anz->nmax ;  
    anz_nmin= anz->nmin ;  
    anz_emax= anz->emax ;  
    anz_emin= anz->emin ;  
    anz->nmax=MAXVALUE;
    anz->nmin=1;
    anz->emax=MAXVALUE;
    anz->emin=1;

    if( readccx( datin, apre, &npre, &epre, &lpre, &facebuf) == -1) return;

    /* modify node and element numbers if param2 == add */
    if((param2[0]=='A')||(param2[0]=='a'))
    {
      renumberfrd( anz->emax+1, anz->nmax+1, apre, &npre, &epre, &lpre );
    }

    anz->nmax=anz_nmax ;
    anz->nmin=anz_nmin ;
    anz->emax=anz_emax ;
    anz->emin=anz_emin ;

    /* create the nodes and elements or overwrite old ones */
    for(i=0; i<apre->n; i++) 
    {
      nod( anz, &node, 1, npre[i].nr, npre[npre[i].nr].nx, npre[npre[i].nr].ny, npre[npre[i].nr].nz, 1 );
    }

    /* new number of original nodes */
    num_onodmax = anz->nmax;
    num_onod = anz->n;

    /* new scaling for drawing */
    descalNodes ( anz->n, node, scale );
    descalPoints( anzGeo->p, point, scale);
    descalSurfs( anzGeo->s, surf, scale);
    getScaleValues( anz->n, anzGeo->p, point, node, scale);
    scalNodes ( anz->n, node, scale );
    scalPoints ( anzGeo->p, point, scale );
    scalSurfs( anzGeo->s, surf, scale);
    

    for(i=0; i<apre->e; i++)
    {
      elem_define( epre[i].nr, epre[i].type, epre[i].nod, 1, 0 );
    }

    /* new midnodes */
    for(i=0; i<anz->e; i++)
    {
      if(e_enqire[e_enqire[i].nr].type==4)
      {
        /* if(e_enqire[e_enqire[i].nr].nod[20]==0) !additional nodes are free'd */
	{
          for (n=0; n<3; n++)  /* create new nodes in center of areas */
          {
            nod( anz, &node, 0, anz->nmax+1, 0., 0., 0., 0 ); 
            node[anz->nmax].pflag=1;
        
            node[anz->nmax].nx = -1./4.* (
              node[e_enqire[e_enqire[i].nr].nod[0+n]].nx+node[e_enqire[e_enqire[i].nr].nod[1+n]].nx    +
              node[e_enqire[e_enqire[i].nr].nod[5+n]].nx+node[e_enqire[e_enqire[i].nr].nod[4+n]].nx )  + 1./2.*(
              node[e_enqire[e_enqire[i].nr].nod[8+n]].nx+node[e_enqire[e_enqire[i].nr].nod[13+n]].nx   +
              node[e_enqire[e_enqire[i].nr].nod[16+n]].nx+node[e_enqire[e_enqire[i].nr].nod[12+n]].nx) ;
        
            node[anz->nmax].ny = -1./4.* (
              node[e_enqire[e_enqire[i].nr].nod[0+n]].ny+node[e_enqire[e_enqire[i].nr].nod[1+n]].ny    +
              node[e_enqire[e_enqire[i].nr].nod[5+n]].ny+node[e_enqire[e_enqire[i].nr].nod[4+n]].ny )  + 1./2.*(
              node[e_enqire[e_enqire[i].nr].nod[8+n]].ny+node[e_enqire[e_enqire[i].nr].nod[13+n]].ny   +
              node[e_enqire[e_enqire[i].nr].nod[16+n]].ny+node[e_enqire[e_enqire[i].nr].nod[12+n]].ny) ;
        
            node[anz->nmax].nz = -1./4.* (
              node[e_enqire[e_enqire[i].nr].nod[0+n]].nz+node[e_enqire[e_enqire[i].nr].nod[1+n]].nz    +
              node[e_enqire[e_enqire[i].nr].nod[5+n]].nz+node[e_enqire[e_enqire[i].nr].nod[4+n]].nz )  + 1./2.*(
              node[e_enqire[e_enqire[i].nr].nod[8+n]].nz+node[e_enqire[e_enqire[i].nr].nod[13+n]].nz   +
              node[e_enqire[e_enqire[i].nr].nod[16+n]].nz+node[e_enqire[e_enqire[i].nr].nod[12+n]].nz) ;
        
            e_enqire[e_enqire[i].nr].nod[n+20]=anz->nmax;
          }
        
          /* create  new node in center of area4 */
        
            nod( anz, &node, 0, anz->nmax+1, 0., 0., 0., 0 ); 
            node[anz->nmax].pflag=1;
        
            node[anz->nmax].nx = -1./4.* (
              node[e_enqire[e_enqire[i].nr].nod[3]].nx+node[e_enqire[e_enqire[i].nr].nod[0]].nx    +
              node[e_enqire[e_enqire[i].nr].nod[4]].nx+node[e_enqire[e_enqire[i].nr].nod[7]].nx )  + 1./2.*(
              node[e_enqire[e_enqire[i].nr].nod[11]].nx+node[e_enqire[e_enqire[i].nr].nod[12]].nx   +
              node[e_enqire[e_enqire[i].nr].nod[19]].nx+node[e_enqire[e_enqire[i].nr].nod[15]].nx) ;
        
            node[anz->nmax].ny = -1./4.* (
              node[e_enqire[e_enqire[i].nr].nod[3]].ny+node[e_enqire[e_enqire[i].nr].nod[0]].ny    +
              node[e_enqire[e_enqire[i].nr].nod[4]].ny+node[e_enqire[e_enqire[i].nr].nod[7]].ny )  + 1./2.*(
              node[e_enqire[e_enqire[i].nr].nod[11]].ny+node[e_enqire[e_enqire[i].nr].nod[12]].ny   +
              node[e_enqire[e_enqire[i].nr].nod[19]].ny+node[e_enqire[e_enqire[i].nr].nod[15]].ny) ;
        
            node[anz->nmax].nz = -1./4.* (
              node[e_enqire[e_enqire[i].nr].nod[3]].nz+node[e_enqire[e_enqire[i].nr].nod[0]].nz    +
              node[e_enqire[e_enqire[i].nr].nod[4]].nz+node[e_enqire[e_enqire[i].nr].nod[7]].nz )  + 1./2.*(
              node[e_enqire[e_enqire[i].nr].nod[11]].nz+node[e_enqire[e_enqire[i].nr].nod[12]].nz   +
              node[e_enqire[e_enqire[i].nr].nod[19]].nz+node[e_enqire[e_enqire[i].nr].nod[15]].nz) ;
        
            e_enqire[e_enqire[i].nr].nod[23]=anz->nmax;
        
          for (n=0; n<2; n++)  /* create last 2 new nodes in center of areas */
          {
            nod( anz, &node, 0, anz->nmax+1, 0., 0., 0., 0 ); 
            node[anz->nmax].pflag=1;
        
            n1=n*4;
            n2=n*8;
            node[anz->nmax].nx = -1./4.* (
              node[e_enqire[e_enqire[i].nr].nod[0+n1]].nx+node[e_enqire[e_enqire[i].nr].nod[1+n1]].nx    +
              node[e_enqire[e_enqire[i].nr].nod[2+n1]].nx+node[e_enqire[e_enqire[i].nr].nod[3+n1]].nx )  + 1./2.*(
              node[e_enqire[e_enqire[i].nr].nod[8+n2]].nx+node[e_enqire[e_enqire[i].nr].nod[9+n2]].nx   +
              node[e_enqire[e_enqire[i].nr].nod[10+n2]].nx+node[e_enqire[e_enqire[i].nr].nod[11+n2]].nx) ;
        
            node[anz->nmax].ny = -1./4.* (
              node[e_enqire[e_enqire[i].nr].nod[0+n1]].ny+node[e_enqire[e_enqire[i].nr].nod[1+n1]].ny    +
              node[e_enqire[e_enqire[i].nr].nod[2+n1]].ny+node[e_enqire[e_enqire[i].nr].nod[3+n1]].ny )  + 1./2.*(
              node[e_enqire[e_enqire[i].nr].nod[8+n2]].ny+node[e_enqire[e_enqire[i].nr].nod[9+n2]].ny   +
              node[e_enqire[e_enqire[i].nr].nod[10+n2]].ny+node[e_enqire[e_enqire[i].nr].nod[11+n2]].ny) ;
        
            node[anz->nmax].nz = -1./4.* (
              node[e_enqire[e_enqire[i].nr].nod[0+n1]].nz+node[e_enqire[e_enqire[i].nr].nod[1+n1]].nz    +
              node[e_enqire[e_enqire[i].nr].nod[2+n1]].nz+node[e_enqire[e_enqire[i].nr].nod[3+n1]].nz )  + 1./2.*(
              node[e_enqire[e_enqire[i].nr].nod[8+n2]].nz+node[e_enqire[e_enqire[i].nr].nod[9+n2]].nz   +
              node[e_enqire[e_enqire[i].nr].nod[10+n2]].nz+node[e_enqire[e_enqire[i].nr].nod[11+n2]].nz) ;
        
            e_enqire[e_enqire[i].nr].nod[n+24]=anz->nmax;
          }
        }
      }
      else if(e_enqire[e_enqire[i].nr].type==5)
      {
        /* if(e_enqire[e_enqire[i].nr].nod[16]==0) !additional nodes are free'd */
	{
          for (n=0; n<2; n++)  /* create new nodes in center of areas */
          {
            nod( anz, &node, 0, anz->nmax+1, 0., 0., 0., 0 ); 
            node[anz->nmax].pflag=1;
        
            node[anz->nmax].nx = -1./4.* (
            node[e_enqire[e_enqire[i].nr].nod[0+n]].nx+node[e_enqire[e_enqire[i].nr].nod[1+n]].nx    +
            node[e_enqire[e_enqire[i].nr].nod[4+n]].nx+node[e_enqire[e_enqire[i].nr].nod[3+n]].nx )  + 1./2.*(
            node[e_enqire[e_enqire[i].nr].nod[6+n]].nx+node[e_enqire[e_enqire[i].nr].nod[10+n]].nx   +
            node[e_enqire[e_enqire[i].nr].nod[12+n]].nx+node[e_enqire[e_enqire[i].nr].nod[ 9+n]].nx) ;
    
          node[anz->nmax].ny = -1./4.* (
            node[e_enqire[e_enqire[i].nr].nod[0+n]].ny+node[e_enqire[e_enqire[i].nr].nod[1+n]].ny    +
            node[e_enqire[e_enqire[i].nr].nod[4+n]].ny+node[e_enqire[e_enqire[i].nr].nod[3+n]].ny )  + 1./2.*(
            node[e_enqire[e_enqire[i].nr].nod[6+n]].ny+node[e_enqire[e_enqire[i].nr].nod[10+n]].ny   +
            node[e_enqire[e_enqire[i].nr].nod[12+n]].ny+node[e_enqire[e_enqire[i].nr].nod[ 9+n]].ny) ;
    
          node[anz->nmax].nz = -1./4.* (
            node[e_enqire[e_enqire[i].nr].nod[0+n]].nz+node[e_enqire[e_enqire[i].nr].nod[1+n]].nz    +
            node[e_enqire[e_enqire[i].nr].nod[4+n]].nz+node[e_enqire[e_enqire[i].nr].nod[3+n]].nz )  + 1./2.*(
            node[e_enqire[e_enqire[i].nr].nod[6+n]].nz+node[e_enqire[e_enqire[i].nr].nod[10+n]].nz   +
            node[e_enqire[e_enqire[i].nr].nod[12+n]].nz+node[e_enqire[e_enqire[i].nr].nod[ 9+n]].nz) ;
    
          e_enqire[e_enqire[i].nr].nod[n+15]=anz->nmax;
          }
          nod( anz, &node, 0, anz->nmax+1, 0., 0., 0., 0 ); 
          node[anz->nmax].pflag=1;
    
          node[anz->nmax].nx = -1./4.* (
            node[e_enqire[e_enqire[i].nr].nod[2]].nx+node[e_enqire[e_enqire[i].nr].nod[0]].nx    +
            node[e_enqire[e_enqire[i].nr].nod[3]].nx+node[e_enqire[e_enqire[i].nr].nod[5]].nx )  + 1./2.*(
            node[e_enqire[e_enqire[i].nr].nod[ 8]].nx+node[e_enqire[e_enqire[i].nr].nod[ 9]].nx   +
            node[e_enqire[e_enqire[i].nr].nod[14]].nx+node[e_enqire[e_enqire[i].nr].nod[11]].nx) ;
    
          node[anz->nmax].ny = -1./4.* (
            node[e_enqire[e_enqire[i].nr].nod[2]].ny+node[e_enqire[e_enqire[i].nr].nod[0]].ny    +
            node[e_enqire[e_enqire[i].nr].nod[3]].ny+node[e_enqire[e_enqire[i].nr].nod[5]].ny )  + 1./2.*(
            node[e_enqire[e_enqire[i].nr].nod[ 8]].ny+node[e_enqire[e_enqire[i].nr].nod[ 9]].ny   +
            node[e_enqire[e_enqire[i].nr].nod[14]].ny+node[e_enqire[e_enqire[i].nr].nod[11]].ny) ;
    
          node[anz->nmax].nz = -1./4.* (
            node[e_enqire[e_enqire[i].nr].nod[2]].nz+node[e_enqire[e_enqire[i].nr].nod[0]].nz    +
            node[e_enqire[e_enqire[i].nr].nod[3]].nz+node[e_enqire[e_enqire[i].nr].nod[5]].nz )  + 1./2.*(
            node[e_enqire[e_enqire[i].nr].nod[ 8]].nz+node[e_enqire[e_enqire[i].nr].nod[ 9]].nz   +
            node[e_enqire[e_enqire[i].nr].nod[14]].nz+node[e_enqire[e_enqire[i].nr].nod[11]].nz) ;
    
          e_enqire[e_enqire[i].nr].nod[17]=anz->nmax;
          nod( anz, &node, 0, anz->nmax+1, 0., 0., 0., 0 ); 
          node[anz->nmax].pflag=1;
    
          node[anz->nmax].nx = -1./4.* (
            node[e_enqire[e_enqire[i].nr].nod[0]].nx+node[e_enqire[e_enqire[i].nr].nod[2]].nx    +
            node[e_enqire[e_enqire[i].nr].nod[1]].nx+node[e_enqire[e_enqire[i].nr].nod[0]].nx )  + 1./2.*(
            node[e_enqire[e_enqire[i].nr].nod[ 8]].nx+node[e_enqire[e_enqire[i].nr].nod[ 7]].nx   +
            node[e_enqire[e_enqire[i].nr].nod[ 6]].nx+node[e_enqire[e_enqire[i].nr].nod[ 0]].nx) ;
    
          node[anz->nmax].ny = -1./4.* (
            node[e_enqire[e_enqire[i].nr].nod[0]].ny+node[e_enqire[e_enqire[i].nr].nod[2]].ny    +
            node[e_enqire[e_enqire[i].nr].nod[1]].ny+node[e_enqire[e_enqire[i].nr].nod[0]].ny )  + 1./2.*(
            node[e_enqire[e_enqire[i].nr].nod[ 8]].ny+node[e_enqire[e_enqire[i].nr].nod[ 7]].ny   +
            node[e_enqire[e_enqire[i].nr].nod[ 6]].ny+node[e_enqire[e_enqire[i].nr].nod[ 0]].ny) ;
    
          node[anz->nmax].nz = -1./4.* (
            node[e_enqire[e_enqire[i].nr].nod[0]].nz+node[e_enqire[e_enqire[i].nr].nod[2]].nz    +
            node[e_enqire[e_enqire[i].nr].nod[1]].nz+node[e_enqire[e_enqire[i].nr].nod[0]].nz )  + 1./2.*(
            node[e_enqire[e_enqire[i].nr].nod[ 8]].nz+node[e_enqire[e_enqire[i].nr].nod[ 7]].nz   +
            node[e_enqire[e_enqire[i].nr].nod[ 6]].nz+node[e_enqire[e_enqire[i].nr].nod[ 0]].nz) ;
    
          e_enqire[e_enqire[i].nr].nod[18]=anz->nmax;
          nod( anz, &node, 0, anz->nmax+1, 0., 0., 0., 0 ); 
          node[anz->nmax].pflag=1;
    
          node[anz->nmax].nx = -1./4.* (
            node[e_enqire[e_enqire[i].nr].nod[3]].nx+node[e_enqire[e_enqire[i].nr].nod[4]].nx    +
            node[e_enqire[e_enqire[i].nr].nod[5]].nx+node[e_enqire[e_enqire[i].nr].nod[3]].nx )  + 1./2.*(
            node[e_enqire[e_enqire[i].nr].nod[12]].nx+node[e_enqire[e_enqire[i].nr].nod[13]].nx   +
            node[e_enqire[e_enqire[i].nr].nod[14]].nx+node[e_enqire[e_enqire[i].nr].nod[ 3]].nx) ;
    
          node[anz->nmax].ny = -1./4.* (
            node[e_enqire[e_enqire[i].nr].nod[3]].ny+node[e_enqire[e_enqire[i].nr].nod[4]].ny    +
            node[e_enqire[e_enqire[i].nr].nod[5]].ny+node[e_enqire[e_enqire[i].nr].nod[3]].ny )  + 1./2.*(
            node[e_enqire[e_enqire[i].nr].nod[12]].ny+node[e_enqire[e_enqire[i].nr].nod[13]].ny   +
            node[e_enqire[e_enqire[i].nr].nod[14]].ny+node[e_enqire[e_enqire[i].nr].nod[ 3]].ny) ;
    
          node[anz->nmax].nz = -1./4.* (
            node[e_enqire[e_enqire[i].nr].nod[3]].nz+node[e_enqire[e_enqire[i].nr].nod[4]].nz    +
            node[e_enqire[e_enqire[i].nr].nod[5]].nz+node[e_enqire[e_enqire[i].nr].nod[3]].nz )  + 1./2.*(
            node[e_enqire[e_enqire[i].nr].nod[12]].nz+node[e_enqire[e_enqire[i].nr].nod[13]].nz   +
            node[e_enqire[e_enqire[i].nr].nod[14]].nz+node[e_enqire[e_enqire[i].nr].nod[ 3]].nz) ;
    
          e_enqire[e_enqire[i].nr].nod[19]=anz->nmax;
        }
      }
      else if (e_enqire[e_enqire[i].nr].type== 10)
      {
        /* if(e_enqire[e_enqire[i].nr].nod[8]==0) !additional nodes are free'd */
	{
          /* calculate the midside node */
          nod( anz, &node, 0, anz->nmax+1, 0., 0., 0., 0 ); 
          node[anz->nmax].pflag=1;

          node[anz->nmax].nx = -1./4.* (
          node[e_enqire[e_enqire[i].nr].nod[0]].nx+node[e_enqire[e_enqire[i].nr].nod[1]].nx  +
          node[e_enqire[e_enqire[i].nr].nod[3]].nx+node[e_enqire[e_enqire[i].nr].nod[2]].nx )+ 1./2.*(
          node[e_enqire[e_enqire[i].nr].nod[4]].nx+node[e_enqire[e_enqire[i].nr].nod[6]].nx  +
          node[e_enqire[e_enqire[i].nr].nod[7]].nx+node[e_enqire[e_enqire[i].nr].nod[5]].nx) ;

          node[anz->nmax].ny = -1./4.* (
          node[e_enqire[e_enqire[i].nr].nod[0]].ny+node[e_enqire[e_enqire[i].nr].nod[1]].ny  +
          node[e_enqire[e_enqire[i].nr].nod[3]].ny+node[e_enqire[e_enqire[i].nr].nod[2]].ny )+ 1./2.*(
          node[e_enqire[e_enqire[i].nr].nod[4]].ny+node[e_enqire[e_enqire[i].nr].nod[6]].ny  +
          node[e_enqire[e_enqire[i].nr].nod[7]].ny+node[e_enqire[e_enqire[i].nr].nod[5]].ny) ;

          node[anz->nmax].nz = -1./4.* (
          node[e_enqire[e_enqire[i].nr].nod[0]].nz+node[e_enqire[e_enqire[i].nr].nod[1]].nz  +
          node[e_enqire[e_enqire[i].nr].nod[3]].nz+node[e_enqire[e_enqire[i].nr].nod[2]].nz )+ 1./2.*(
          node[e_enqire[e_enqire[i].nr].nod[4]].nz+node[e_enqire[e_enqire[i].nr].nod[6]].nz  +
          node[e_enqire[e_enqire[i].nr].nod[7]].nz+node[e_enqire[e_enqire[i].nr].nod[5]].nz) ;
          e_enqire[e_enqire[i].nr].nod[8]=anz->nmax;   
        }
      }
    } 


    /* add the new datasets */
    if((param2[0]=='A')||(param2[0]=='a'))
    {
      /* add the nodes to the existing datasets */
      /* extend the datasets */
      for(l=0; l<anz->l; l++)
      {
        for(i=0; i<lcase[l].ncomps; i++)
        {
          if ( (lcase[l].dat[i] = (float *)realloc((float *)lcase[l].dat[i], (anz->nmax+1) * sizeof(float))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );	               
        }

        /* fill the datasets */
        if((l<apre->l)&&(lcase[l].ncomps==lpre[l].ncomps))
        {
          for(n=apre->nmin; n<=apre->nmax; n++)
          {
            for(i=0; i<lcase[l].ncomps; i++)
            {
              lcase[l].dat[i][n]=  lpre[l].dat[i][n];
              if (lcase[l].dat[i][n] >  lcase[l].max[i])
              {  lcase[l].max[i]=lcase[l].dat[i][n]; lcase[l].nmax[i]=n; }
              if (lcase[l].dat[i][n] <  lcase[l].min[i])
              {  lcase[l].min[i]=lcase[l].dat[i][n]; lcase[l].nmin[i]=n; }
            }     
          }     
        }
      }
    }
    else
    {
      /* add the new datasets to the existing datasets */

      printf("additional Datasets:%d\n",apre->l);  
      if( ( lcase=(Datasets *)realloc((Datasets *)lcase,(anz->l+apre->l+1)*sizeof(Datasets))  )==NULL)
        printf("\n\n ERROR: realloc failed\n\n") ;
      for(l=0; l<apre->l; l++) lcase[anz->l+l]=lpre[l];
      anz->l+=apre->l;
    }
    if(activWindow!=-1) createDatasetEntries();

    free(npre); npre=NULL;
    free(epre); epre=NULL;
    free(lpre); lpre=NULL;

    /* from here code from pre_mesh() */
    /* das neue netz muss noch zur beleuchteten ansicht aufbereitet werden  */
    makeSurfaces();
    allocUtilityData();
    
    /* reference the faces by the nodes for fast identification */
    if( (iface=(int **)malloc((anz->nmax+1)*sizeof(int *) ) )==NULL) 
    { printf(" ERROR: malloc failure\n"); return; }
    for (j=0; j<=anz->nmax; j++)
    {
      if( (iface[j]=(int *)malloc((int)1*sizeof(int) ) )==NULL) 
      { printf(" ERROR: malloc failure\n"); return; }
      iface[j][0]=0;
    }
    if( (sumface=(int *)malloc( (anz->f+1)*sizeof(int) ) )==NULL) 
    { printf(" ERROR: malloc failure\n"); return; }
    for (i=0; i<anz->f; i++)
    { 
      if (face[i].type == 7) n = 3;  /* TRI3  */
      else if (face[i].type == 8) n = 6;  /* TRI6  */
      else if (face[i].type == 9) n = 4;  /* QUAD4 */
      else if (face[i].type == 10) n = 8; /* QUAD8 */
      else n=0;
      for (j=0; j<n; j++)
      {
        /* store for each node the amount and index of all affected faces */
        iface[face[i].nod[j]][0]++;
        if( (iface[face[i].nod[j]]=(int *)realloc((int *)iface[face[i].nod[j]], (int)(iface[face[i].nod[j]][0]+2)*sizeof(int) ) )==NULL) 
        { printf(" ERROR: realloc failure\n"); return; }
        iface[face[i].nod[j]][iface[face[i].nod[j]][0]]=i;
      }
    }
    for (sets=0; sets<anzGeo->sets; sets++)
    {
      if ( sets==getSetNr(specialset->mesh)||( set[sets].type==1)||(sets==getSetNr(specialset->nomesh))) goto nextSet1;
      {
        if(set[sets].anz_n>0)
        { 
          for (i=0; i<anz->f; i++) sumface[i]=0;
          for (i=0; i<set[sets].anz_n; i++)
          {
            /* goto all set-nodes and mark all affected faces */
            if(iface[set[sets].node[i]][0]>0)
    	  {
              for(j=1; j<=iface[set[sets].node[i]][0]; j++)
              {
                /* all affected faces are marked */
    	      sumface[iface[set[sets].node[i]][j]]++;
    	    }
    	  }
          }
          /* now go through all faces and look how often it was marked */
          for (i=0; i<anz->f; i++)
          {
            if (face[i].type == 7) n = 3;  /* TRI3  */
            else if (face[i].type == 8) n = 6;  /* TRI6  */
            else if (face[i].type == 9) n = 4;  /* QUAD4 */
            else if (face[i].type == 10) n = 8; /* QUAD8 */
            else n=0;
            if(sumface[i]==n) seta( sets, "f", i );
          }
        }
      }
    nextSet1:;
    }
    for (j=0; j<=anz->nmax; j++) free(iface[j]);
    free(iface); 
    free(sumface); 
    
    
    /* add the faces of elements to the sets */
    if(printFlag) printf(" include faces in sets\n");
    /* reference the faces by the elements for easy identification */
    if( (iface=(int **)malloc((anz->emax+1)*sizeof(int *) ) )==NULL) 
    { printf(" ERROR: malloc failure\n"); return; }
    for (j=0; j<=anz->emax; j++)
    {
      if( (iface[j]=(int *)malloc((int)7*sizeof(int) ) )==NULL) 
      { printf(" ERROR: malloc failure\n"); return; }
      iface[j][0]=0;
    }
    for (i=0; i<anz->f; i++)
    {
      iface[face[i].elem_nr][0]++;
      iface[face[i].elem_nr][iface[face[i].elem_nr][0]]=i;
    }
    for (sets=0; sets<anzGeo->sets; sets++)
    {
      if ( sets==getSetNr(specialset->mesh)||( set[sets].type==1) ) goto nextSet2;
      {
        if(set[sets].anz_e>0)
        { 
          for (i=0; i<set[sets].anz_e; i++)
            if(iface[set[sets].elem[i]][0]>0)
              for(j=1; j<=iface[set[sets].elem[i]][0]; j++)
              { seta( sets, "f", iface[set[sets].elem[i]][j] ); }
        }
      }
    nextSet2:;
    }
    for (j=0; j<=anz->emax; j++) free(iface[j]); free(iface); 
    
    updateDispLists(); 
    /* end code from pre_mesh() */

    /* recalculate the line-shapes */
    for (i=0; i<anzGeo->l; i++) rep(i);
    /* recalculate the nurbl-controll-points */
    for (i=0; i<anzGeo->nurl; i++) repNurl(i);
    /* recalculate the nurbs-controll-points */
    for (i=0; i<anzGeo->nurs; i++) repNurs(i);
  }
  else if ((length==1)||(compare( param1, "rep", 3)== 3))
  { readfbd( datin, 0 ); updateDispLists(); }
  else if (compare( param1, "add", 3)== 3)
  { readfbd( datin, 1 ); updateDispLists(); } 
  else printf("ERROR, no matching file-type found\n");
  printf (" ready\n");
}



/* define the element-typ in the struct of the lines, surfs, bodies */
void pre_elty( unsigned char *record )
{
  int i, length, setNr;
  unsigned char      setname[MAX_LINE_LENGTH], etype[MAX_LINE_LENGTH], eattr[MAX_LINE_LENGTH];

  setname[0]=etype[0]=(unsigned char)NULL;
  length= sscanf( record, "%s%s", setname, etype);
  if(compareStrings(setname, "ALL")==3) strcpy(setname,"all");

  if(length<1)
  {
    /* show all sets which have an element type assigned */
    for (setNr=0; setNr<anzGeo->sets; setNr++)
    {
      if(set[setNr].etyp!=0)
      {
        if (set[setNr].etyp < 0) strcpy( etype, "unknown type ");
        if (set[setNr].etyp == 1)  strcpy( etype, "he8");
        if (set[setNr].etyp == 2)  strcpy( etype, "pe6"); 
        if (set[setNr].etyp == 3)  strcpy( etype, "te4"); 
        if (set[setNr].etyp == 4)  strcpy( etype, "he20"); 
        if (set[setNr].etyp == 5)  strcpy( etype, "pe15");
        if (set[setNr].etyp == 6)  strcpy( etype, "te10"); 
        if (set[setNr].etyp == 7)  strcpy( etype, "tr3"); 
        if (set[setNr].etyp == 8)  strcpy( etype, "tr6"); 
        if (set[setNr].etyp == 9)  strcpy( etype, "qu4"); 
        if (set[setNr].etyp == 10) strcpy( etype, "qu8"); 
        if (set[setNr].etyp == 11) strcpy( etype, "be2"); 
        if (set[setNr].etyp == 12) strcpy( etype, "be3");
        if (set[setNr].etyp > 12) strcpy( etype, "unknown type ");
        if (set[setNr].eattr < -2) strcpy( eattr, " unknown attr");
        if (set[setNr].eattr == -2) strcpy( eattr, " glu mesh");
        if (set[setNr].eattr == -1) strcpy( eattr, " unstructured");
        if (set[setNr].eattr == 0) strcpy( eattr, " ");
        if (set[setNr].eattr == 1) strcpy( eattr, "r");
        if (set[setNr].eattr == 2) strcpy( eattr, "i");
        if (set[setNr].eattr > 2) strcpy( eattr, " unknown attr");
        printf("set:%s element-type: %s%s\n", set[setNr].name, etype, eattr);
      }
    }
  }
  else if(length==1)
  {
    setNr=getSetNr(setname);
    if (setNr<0)
    {
      printf (" ERROR in pre_elty: set:%s does not exist\n", setname);
      return;
    }

    /* delete all element definitions if the setname is "all" */
    if(compareStrings(setname, "all")>0)
    {
      for (setNr=0; setNr<anzGeo->sets; setNr++)
      {
        set[setNr].etyp=0;
        set[setNr].eattr=0;
        for (i=0; i<set[setNr].anz_b; i++)
        {
          body[set[setNr].body[i]].eattr=set[setNr].eattr ;
          body[set[setNr].body[i]].etyp=set[setNr].etyp ;
        }
        for (i=0; i<set[setNr].anz_s; i++)
        {
          surf[set[setNr].surf[i]].eattr=set[setNr].eattr ;
          surf[set[setNr].surf[i]].etyp=set[setNr].etyp ;
        }
        for (i=0; i<set[setNr].anz_l; i++)
        {
          line[set[setNr].line[i]].eattr=set[setNr].eattr ;
          line[set[setNr].line[i]].etyp=set[setNr].etyp ;
        }
      }
    }
    /* delete only the element-def of this set */
    else
    {
      set[setNr].etyp=0;
      set[setNr].eattr=0;
      for (i=0; i<set[setNr].anz_b; i++)
      {
        body[set[setNr].body[i]].eattr=set[setNr].eattr ;
        body[set[setNr].body[i]].etyp=set[setNr].etyp ;
      }
      for (i=0; i<set[setNr].anz_s; i++)
      {
        surf[set[setNr].surf[i]].eattr=set[setNr].eattr ;
        surf[set[setNr].surf[i]].etyp=set[setNr].etyp ;
      }
      for (i=0; i<set[setNr].anz_l; i++)
      {
        line[set[setNr].line[i]].eattr=set[setNr].eattr ;
        line[set[setNr].line[i]].etyp=set[setNr].etyp ;
      }
    }
  }
  else
  {
    setNr=getSetNr(setname);
    if (setNr<0)
    {
      printf (" ERROR in pre_elty: set:%s does not exist\n", setname);
      return;
    }

    for(i=0;i<strlen(etype); i++) etype[i]=toupper(etype[i]);
    if( compare( etype, "BE2", 3) == 3)
    {
      set[setNr].etyp=11; set[setNr].eattr=0;
    }
    else if(compare( etype, "BE3", 3) == 3)
    {
      set[setNr].etyp=12; set[setNr].eattr=0;
    }
    else if(compare( etype, "TR3", 3) == 3)
    {
        if(strlen(etype)==3) { set[setNr].etyp=7; set[setNr].eattr=0; }
      else if(etype[3]=='U') { set[setNr].etyp=7; set[setNr].eattr=-1; }
      else if(etype[3]=='G') { set[setNr].etyp=7; set[setNr].eattr=-2; }
      else printf("ERROR: type %s not known\n", etype);
    }
    else if(compare( etype, "TR6", 3) == 3)
    {
      set[setNr].etyp=8; set[setNr].eattr=0;
    }
    else if(compare( etype, "QU4", 3) == 3)
    {
      set[setNr].etyp=9; set[setNr].eattr=0;
    }
    else if(compare( etype, "QU8", 3) == 3)
    {
      set[setNr].etyp=10; set[setNr].eattr=0;
    }
    else if(compare( etype, "HE8", 3) == 3)
    {
      if(strlen(etype)==3)   { set[setNr].etyp=1; set[setNr].eattr=0; }
      else if(etype[3]=='R') { set[setNr].etyp=1; set[setNr].eattr=1; }
      else if(etype[3]=='I') { set[setNr].etyp=1; set[setNr].eattr=2; }
      else printf("ERROR: type %s not known\n", etype);
    }
    else if(compare( etype, "HE20", 4) == 4)
    {
      if(strlen(etype)==4)   { set[setNr].etyp=4; set[setNr].eattr=0; }
      else if(etype[4]=='R') { set[setNr].etyp=4; set[setNr].eattr=1; }
      else printf("ERROR: type %s not known\n", etype);
    }
    else 
    {
      printf("ERROR: element-type:%s not known (choose either be2,be3,tr3,tr6,qu4,qu8,he8,he20)\n",etype);
      return;
    }
    
    /* assign the element-type to the appropriate entities */ 
    /* assign the attribute */
    /* get the basis formulation of the etyp */
    if((set[setNr].etyp==1)||(set[setNr].etyp==4))
    {
      for (i=0; i<set[setNr].anz_b; i++)
      {
        body[set[setNr].body[i]].eattr=set[setNr].eattr ;
        body[set[setNr].body[i]].etyp=set[setNr].etyp ;
      }
    }
    if((set[setNr].etyp>=7)&&(set[setNr].etyp<=10))
    {
      for (i=0; i<set[setNr].anz_s; i++)
      {
        surf[set[setNr].surf[i]].eattr=set[setNr].eattr ;
        surf[set[setNr].surf[i]].etyp=set[setNr].etyp ;
      }
    }
    if((set[setNr].etyp>=11)&&(set[setNr].etyp<=12))
    {
      for (i=0; i<set[setNr].anz_l; i++)
      {
        line[set[setNr].line[i]].eattr=set[setNr].eattr ;
        line[set[setNr].line[i]].etyp=set[setNr].etyp ;
      }
    }
  }
}

void pre_mesh( unsigned char *record )
/* store the entities to be meshed in a special set and add lower entities, then mesh   */
{
  int c,l,s,i,j,k,n,se,setall;
  unsigned char setname[MAX_LINE_LENGTH], code[4][MAX_LINE_LENGTH];
  int       length, setNr, sets, meshoptFlag_length=MESHOPT_LENGTH, meshoptFlag_angle=MESHOPT_ANGLE, blockFlag=0, lonlyFlag=0, projFlag=1;
  int *openSets=NULL, **iface=NULL, *sumface=NULL;

  length = sscanf( record,"%s %s %s %s %s", setname,code[0],code[1],code[2],code[3] );

  for(i=0; i<length-1; i++)
  {
    if(compare(code[i],"nolength",4)==4)  meshoptFlag_length=0;
    else if(compare(code[i],"noangle",4)==4)  meshoptFlag_angle=0;
    else if(compare(code[i],"length",4)==4)  meshoptFlag_length=1;
    else if(compare(code[i],"angle",4)==4)  meshoptFlag_angle=1;
    else if(compare(code[i],"block",3)==3) blockFlag=1;
    else if(compare(code[i],"fast",3)==3) projFlag=0;
    else if(compare(code[i],"lonly",3)==3) lonlyFlag=1;
  }

  operateAlias( setname, "se" );
  setNr=getSetNr(setname);
  if (setNr<0)
  {
    printf (" ERROR in pre_mesh: set:%s does not exist\n", setname);
    return;
  }
  else
    if(printFlag) printf (" set[%d]:%s %s will be meshed\n", setNr, setname, set[setNr].name);

  printf (" please wait for 'ready'\n");

  /* cycle through all entities and add them to the special set  */
  if( (se=pre_seta( specialset->mesh, "i", 0)) <0 ) return;
  if(!setNr) /* its the set "all" */
  {
    for (i=0; i<anzGeo->p; i++) if( point[i].name != (unsigned char *)NULL ) seta( se, "p", i );
    for (i=0; i<anzGeo->l; i++) if( line[i].name != (unsigned char *)NULL ) seta( se, "l", i );
    for (i=0; i<anzGeo->s; i++) if( surf[i].name != (unsigned char *)NULL ) seta( se, "s", i );
    for (i=0; i<anzGeo->b; i++) if( body[i].name != (unsigned char *)NULL ) seta( se, "b", i );
  }
  else 
  {
    for (i=0; i<set[setNr].anz_b; i++) seta( se, "b", set[setNr].body[i] );
    for (i=0; i<set[setNr].anz_s; i++) seta( se, "s", set[setNr].surf[i] );
    for (i=0; i<set[setNr].anz_c; i++) seta( se, "c", set[setNr].lcmb[i] );
    for (i=0; i<set[setNr].anz_l; i++) seta( se, "l", set[setNr].line[i] );
    /* second cycle through all entities and add lower ones  to the special set  */
    /* completeSet( specialset->mesh, "do") ; */

    /* cyrcle through all bodys and add all surfs */
    for (i=0; i<set[se].anz_b; i++)
    {
      c= set[se].body[i];
      for (j=0; j<body[c].ns; j++)
      {
        l=body[c].s[j];
        seta( se, "s", l );
      }
    }
    /* cyrcle through all surfs and add all lines, lcmbs and nurbs */
    for (i=0; i<set[se].anz_s; i++)
    {
      s= set[se].surf[i];
      if(surf[s].sh>-1) seta( se, "S", surf[s].sh );
      for (j=0; j<surf[s].nl; j++)
      {
        l=surf[s].l[j];
        if (surf[s].typ[j]=='l')
        {
          seta( se, "l", l );
        }
        else
        {
          seta( se, "c", l );
        }
      }
    }
    /* cyrcle through all lcmbs and add all lines */
    for (i=0; i<set[se].anz_c; i++)
    {
      c= set[se].lcmb[i];
      for (j=0; j<lcmb[c].nl; j++)
      {
        l=lcmb[c].l[j];
        seta( se, "l", l );
      }
    }
    /* cyrcle through all lines and add all points, trks */
    for (i=0; i<set[se].anz_l; i++)
    {
      l= set[se].line[i];
      seta( se, "p", line[l].p1 );
      seta( se, "p", line[l].p2 );
      if (line[l].typ=='a') seta( se, "p", line[l].trk );
      if (line[l].typ=='s') seta( se, "se", line[l].trk );
    }
    /* cyrcle through all nurbs and add all points */
    for (i=0; i<set[se].anz_nurs; i++)
    {
      s= set[se].nurs[i];
      for (j=0; j<nurbs[s].u_npnt; j++)
        for (k=0; k<nurbs[s].v_npnt; k++)
          seta( se, "p", nurbs[s].ctlpnt[j][k] );
    }
  }
  
  /* mesh will not automaticaly be deleted because initial mesh should be possible */
  /*
  pre_del( "mesh" );
  */
  orientSet( specialset->mesh );

  /* close all open sets, exept set[].name=='all' */
  /* necessary, if 5 or 7 sided bodies exist, otherwhise temporary geom will be assigned */
  setall=getSetNr("all");
  j=1;
  for(i=0; i<anzGeo->sets; i++)
  {
    if((set[i].flag=='o')&&(i!=setall))
    {
      if ( (openSets = (int *)realloc( (int *)openSets,(j+1) * sizeof(int))) == NULL )
         printf("\n\n ERROR: realloc failed in pre_mesh() openSets\n\n") ;
      openSets[j]=i;
      set[i].flag='c';
      j++;
    }
  }
  meshSet( specialset->mesh, blockFlag, lonlyFlag, projFlag, meshoptFlag_length, meshoptFlag_angle); 
  /* improve bad tr3 elements */
  improveBadTr3(specialset->mesh);

  /* mark the closed sets as open again */
  for(i=1; i<j; i++) set[openSets[i]].flag='o';
  free(openSets);

  /* das neue netz muss noch zur beleuchteten ansicht aufbereitet werden  */
  num_olc       = anz->l;
  makeSurfaces();

  if(printFlag) printf(" correct bad elements\n");
  if (calcBadElements("all")>0)
  {
    fixMidsideNodes( specialset->njby, "lin");
  }

  allocUtilityData();


  /* reference the faces by the nodes for fast identification */
  if( (iface=(int **)malloc((anz->nmax+1)*sizeof(int *) ) )==NULL) 
  { printf(" ERROR: malloc failure\n"); return; }
  for (j=0; j<=anz->nmax; j++)
  {
    if( (iface[j]=(int *)malloc((int)1*sizeof(int) ) )==NULL) 
    { printf(" ERROR: malloc failure\n"); return; }
    iface[j][0]=0;
  }
  if( (sumface=(int *)malloc( (anz->f+1)*sizeof(int) ) )==NULL) 
  { printf(" ERROR: malloc failure\n"); return; }
  for (i=0; i<anz->f; i++)
  { 
    if (face[i].type == 7) n = 3;  /* TRI3  */
    else if (face[i].type == 8) n = 6;  /* TRI6  */
    else if (face[i].type == 9) n = 4;  /* QUAD4 */
    else if (face[i].type == 10) n = 8; /* QUAD8 */
    else n=0;
    for (j=0; j<n; j++)
    {
      /* store for each node the amount and index of all affected faces */
      iface[face[i].nod[j]][0]++;
      if( (iface[face[i].nod[j]]=(int *)realloc((int *)iface[face[i].nod[j]], (int)(iface[face[i].nod[j]][0]+2)*sizeof(int) ) )==NULL) 
      { printf(" ERROR: realloc failure\n"); return; }
      iface[face[i].nod[j]][iface[face[i].nod[j]][0]]=i;
    }
  }
  for (sets=0; sets<anzGeo->sets; sets++)
  {
    if ( sets==getSetNr(specialset->mesh)||( set[sets].type==1)||(sets==getSetNr(specialset->nomesh))) goto nextSet1;
    {
      if(set[sets].anz_n>0)
      { 
        for (i=0; i<anz->f; i++) sumface[i]=0;
        for (i=0; i<set[sets].anz_n; i++)
        {
          /* goto all set-nodes and mark all affected faces */
          if(iface[set[sets].node[i]][0]>0)
	  {
            for(j=1; j<=iface[set[sets].node[i]][0]; j++)
            {
              /* all affected faces are marked */
	      sumface[iface[set[sets].node[i]][j]]++;
	    }
	  }
        }
        /* now go through all faces and look how often it was marked */
        for (i=0; i<anz->f; i++)
        {
          if (face[i].type == 7) n = 3;  /* TRI3  */
          else if (face[i].type == 8) n = 6;  /* TRI6  */
          else if (face[i].type == 9) n = 4;  /* QUAD4 */
          else if (face[i].type == 10) n = 8; /* QUAD8 */
          else n=0;
          if(sumface[i]==n) seta( sets, "f", i );
        }
      }
    }
  nextSet1:;
  }
  for (j=0; j<=anz->nmax; j++) free(iface[j]);
  free(iface); 
  free(sumface); 


  /* add the faces of elements to the sets */
  if(printFlag) printf(" include faces in sets\n");
  /* reference the faces by the elements for easy identification */
  if( (iface=(int **)malloc((anz->emax+1)*sizeof(int *) ) )==NULL) 
  { printf(" ERROR: malloc failure\n"); return; }
  for (j=0; j<=anz->emax; j++)
  {
    if( (iface[j]=(int *)malloc((int)7*sizeof(int) ) )==NULL) 
    { printf(" ERROR: malloc failure\n"); return; }
    iface[j][0]=0;
  }
  for (i=0; i<anz->f; i++)
  {
    iface[face[i].elem_nr][0]++;
    iface[face[i].elem_nr][iface[face[i].elem_nr][0]]=i;
  }
  n=getSetNr(specialset->mesh);
  for (sets=0; sets<anzGeo->sets; sets++)
  {
    if ( sets==n||( set[sets].type==1) ) goto nextSet2;
    {
      if(set[sets].anz_e>0)
      { 
        for (i=0; i<set[sets].anz_e; i++)
        {
          if(iface[set[sets].elem[i]][0]>0)
          {
            for(j=1; j<=iface[set[sets].elem[i]][0]; j++)
            {
              seta( sets, "f", iface[set[sets].elem[i]][j] );
            }
          }
        }
      }
    }
  nextSet2:;
  }
  for (j=0; j<=anz->emax; j++) free(iface[j]); free(iface); 

  if(printFlag) printf(" updateDispLists\n");
  updateDispLists(); 

  /* clear special set  */
  delSet(specialset->mesh ); 
  printf (" ready\n");
}


int completeSet( unsigned char *setname, unsigned char *type )
{
  int       anz_n, setNr, i, j, k, n, p, l, c, s, ipuf;
  int       *nbody=NULL, *nsurf=NULL, *nline=NULL, *npoint=NULL, **iface=NULL, *sumface=NULL ;

  operateAlias( setname, "se" );
  setNr=getSetNr(setname);
  if (setNr<0)
  {
    printf (" ERROR in completeSet: set:%s does not exist\n", setname);
    return(-1);
  }

  if (toupper(type[0])=='U') /* up  */
  {
    if (set[setNr].anz_n>0)
    {
      /* suche abhaengige elemente */
      for ( i=0; i<anz->e; i++)
      {
        ipuf=0;
        if (e_enqire[e_enqire[i].nr].type == 1) ipuf = 8;       /* HEXA8 */
        else if (e_enqire[e_enqire[i].nr].type == 2) ipuf = 6;  /* PENTA6 */
        else if (e_enqire[e_enqire[i].nr].type == 3) ipuf = 4;  /* TET4 */
        else if (e_enqire[e_enqire[i].nr].type == 4) ipuf = 20; /* HEXA20 */
        else if (e_enqire[e_enqire[i].nr].type == 5) ipuf = 15; /* PENTA15 */
        else if (e_enqire[e_enqire[i].nr].type == 6) ipuf = 10; /* TET10 */
        else if (e_enqire[e_enqire[i].nr].type == 7) ipuf = 3;  /* TRI3  */
        else if (e_enqire[e_enqire[i].nr].type == 8) ipuf = 6;  /* TRI6  */
        else if (e_enqire[e_enqire[i].nr].type == 9) ipuf = 4;  /* QUAD4 */
        else if (e_enqire[e_enqire[i].nr].type == 10) ipuf = 8; /* QUAD8 */
        else if (e_enqire[e_enqire[i].nr].type == 11) ipuf = 2; /* BEAM */
        else if (e_enqire[e_enqire[i].nr].type == 12) ipuf = 3; /* BEAM3 */
        if (ipuf!=0)
        {
          anz_n=0;
          for (j=0; j<ipuf; j++)
          {
            if(ifind(&set[setNr].node, set[setNr].anz_n, e_enqire[e_enqire[i].nr].nod[j])>-1)
            {
              anz_n++;
              if((set[setNr].elem=(int *)realloc((int *)set[setNr].elem, (set[setNr].anz_e+1)*sizeof(int)))==NULL)
              printf(" ERROR: malloc failed\n\n");
              set[setNr].elem[set[setNr].anz_e]=e_enqire[i].nr;
              set[setNr].anz_e++;
              break;
            }
          }
        }
      }
      qsort( set[setNr].elem, set[setNr].anz_e, sizeof(int), (void *)compareInt );
    }
    if (set[setNr].anz_p>0)
    {
      /* suche abhaengige linien */
      for ( i=0; i<set[setNr].anz_p; i++)
      {
        for (j=0; j<anzGeo->l; j++)
        {
          if( line[j].name != (unsigned char *)NULL )
          if(( set[setNr].pnt[i] == line[j].p1 )||( set[setNr].pnt[i] == line[j].p2 ))
          {
            seta( setNr, "l", j );
          }
        }
      }
    }
    if (set[setNr].anz_l>0)
    {
      /* suche abhaengige lcmbs */
      for ( i=0; i<set[setNr].anz_l; i++)
      {
        for (j=0; j<anzGeo->c; j++)
        {
          if( lcmb[j].name != (unsigned char *)NULL )
          for (n=0; n<lcmb[j].nl; n++)
          {
            if( set[setNr].line[i] == lcmb[j].l[n] )
            {
              seta( setNr, "c", j );
            }
          }
        }
      }
      /* suche abhaengige surfs */
      for ( i=0; i<set[setNr].anz_l; i++)
      {
        for (j=0; j<anzGeo->s; j++)
        {
          if( surf[j].name != (unsigned char *)NULL )
          for (n=0; n<surf[j].nl; n++)
          {
            if(( set[setNr].line[i] == surf[j].l[n] )&&( surf[j].typ[n] == 'l' ))
            {
              seta( setNr, "s", j);
            }
          }
        }
      }
    }
    if (set[setNr].anz_c>0)
    {
      /* suche abhaengige surfaces */
      for ( i=0; i<set[setNr].anz_c; i++)
      {
        for (j=0; j<anzGeo->s; j++)
        {
          if( surf[j].name != (unsigned char *)NULL )
          for (n=0; n<surf[j].nl; n++)
          {
            if(( set[setNr].lcmb[i] == surf[j].l[n] )&&( surf[j].typ[n] == 'c' ))
            {
              seta( setNr, "s", j );
            }
          }
        }
      }
    }
    if (set[setNr].anz_s>0)
    {
      /* suche abhaengige bodys */
      for ( i=0; i<set[setNr].anz_s; i++)
      {
        for (j=0; j<anzGeo->b; j++)
        {
          if( body[j].name != (unsigned char *)NULL )
          for (n=0; n<body[j].ns; n++)
          {
            if ( set[setNr].surf[i] == body[j].s[n] )
            {
              seta( setNr, "b", j);
            }
          }
        }
      }
    }
    if (set[setNr].anz_nurs>0)
    {
      /* suche abhaengige surfaces */
      for ( i=0; i<set[setNr].anz_nurs; i++)
      {
        for (j=0; j<anzGeo->s; j++)
        {
          if( surf[j].name != (unsigned char *)NULL )
          {
            if ( set[setNr].nurs[i] == surf[j].sh )
            {
              seta( setNr, "s", j);
            }
          }
        }
      }
    }
  }

  else if (toupper(type[0])=='D') /* down */
  {
    /* cycle through all nodes and add all fully described faces */
    /* regard also the nodes from the freshly included entities */
    if(set[setNr].anz_n)
    {
      /* reference the faces by the nodes for easy identification */
      if( (iface=(int **)malloc((anz->nmax+1)*sizeof(int *) ) )==NULL) 
      { printf(" ERROR: malloc failure\n"); return(-1); }
      for (j=0; j<=anz->nmax; j++)
      {
        if( (iface[j]=(int *)malloc((int)1*sizeof(int) ) )==NULL) 
        { printf(" ERROR: malloc failure\n"); return(-1); }
        iface[j][0]=0;
      }
      if( (sumface=(int *)malloc( (anz->f+1)*sizeof(int) ) )==NULL) 
      { printf(" ERROR: malloc failure\n"); goto mfail_comp; }
      for (i=0; i<anz->f; i++)
      {
        sumface[i]=0;
        if (face[i].type == 7) n = 3;  /* TRI3  */
        else if (face[i].type == 8) n = 6;  /* TRI6  */
        else if (face[i].type == 9) n = 4;  /* QUAD4 */
        else if (face[i].type == 10) n = 8; /* QUAD8 */
        else n=0;
        for (j=0; j<n; j++)
        {
          /* store for each node the amount and index of all affected faces */
          iface[face[i].nod[j]][0]++;
          if( (iface[face[i].nod[j]]=(int *)realloc((int *)iface[face[i].nod[j]], (int)(iface[face[i].nod[j]][0]+2)*sizeof(int) ) )==NULL) 
          { printf(" ERROR: realloc failure\n"); return(-1); }
          iface[face[i].nod[j]][iface[face[i].nod[j]][0]]=i;
	}
      }
      for (i=0; i<set[setNr].anz_n; i++)
      {
        /* goto all set-nodes and mark all affected faces */
        if(iface[set[setNr].node[i]][0]>0)
	{
          for(j=1; j<=iface[set[setNr].node[i]][0]; j++)
          {
            /* all affected faces are marked */
	    sumface[iface[set[setNr].node[i]][j]]++;
	  }
	}
      }
      /* now go through all faces and look how often it was marked */
      for (i=0; i<anz->f; i++)
      {
        if (face[i].type == 7) n = 3;  /* TRI3  */
        else if (face[i].type == 8) n = 6;  /* TRI6  */
        else if (face[i].type == 9) n = 4;  /* QUAD4 */
        else if (face[i].type == 10) n = 8; /* QUAD8 */
        else n=0;
        if(sumface[i]==n) seta( setNr, "f", i );
      }
      for (j=0; j<=anz->nmax; j++) free(iface[j]);
      free(iface); 
      free(sumface); 
    }

    /* cyrcle through all nodes and add all geometric entities */
    if(set[setNr].anz_n)
    {
      /* mark the related geometry */
      if( (nbody=(int *)malloc( (anz->nmax+1)*sizeof(int) ) )==NULL) 
      { printf(" ERROR: malloc failure\n"); goto mfail_comp; }
      if( (nsurf=(int *)malloc( (anz->nmax+1)*sizeof(int) ) )==NULL) 
      { printf(" ERROR: malloc failure\n"); goto mfail_comp; }
      if( (nline=(int *)malloc( (anz->nmax+1)*sizeof(int) ) )==NULL) 
      { printf(" ERROR: malloc failure\n"); goto mfail_comp; }
      if( (npoint=(int *)malloc( (anz->nmax+1)*sizeof(int) ) )==NULL) 
      { printf(" ERROR: malloc failure\n"); goto mfail_comp; }
      for (i=0; i<=anz->nmax; i++)
      {
        nbody[i]=nsurf[i]=nline[i]=npoint[i]=-1;
      }

      for (i=0; i<anzGeo->b; i++)
      {
        for (j=0; j<body[i].nn; j++){ nbody[body[i].nod[j]]=i; }
      }
      for (i=0; i<anzGeo->s; i++)
      {
        for (j=0; j<surf[i].nn; j++){ nsurf[surf[i].nod[j]]=i; }
      }
      for (i=0; i<anzGeo->l; i++)
      {
        for (j=0; j<line[i].nn; j++){ nline[line[i].nod[j]]=i; }
      }
      for (i=0; i<anzGeo->p; i++)
      {
        for (j=0; j<point[i].nn; j++){ npoint[point[i].nod[j]]=i; }
      }
      for (i=0; i<set[setNr].anz_n; i++)
      {
        /* check if the node is relevant */
        if(nbody[set[setNr].node[i]]>-1) seta( setNr, "b", nbody[set[setNr].node[i]]);
        if(nsurf[set[setNr].node[i]]>-1) seta( setNr, "s", nsurf[set[setNr].node[i]]);
        if(nline[set[setNr].node[i]]>-1) seta( setNr, "l", nline[set[setNr].node[i]]);
        if(npoint[set[setNr].node[i]]>-1) seta( setNr, "p", npoint[set[setNr].node[i]]);
      }

      mfail_comp:;
      free(nbody);
      free(nsurf);
      free(nline);
      free(npoint);
    }
    /* cyrcle through all faces and add all nodes */
    /* nodes have to be completed before because otherwhise all geometry with there nodes would be included */
    for (i=0; i<set[setNr].anz_f; i++)
    {
      if (face[set[setNr].face[i]].type == 7) n = 3;  /* TRI3  */
      else if (face[set[setNr].face[i]].type == 8) n = 6;  /* TRI6  */
      else if (face[set[setNr].face[i]].type == 9) n = 4;  /* QUAD4 */
      else if (face[set[setNr].face[i]].type == 10) n = 8; /* QUAD8 */
      else n=0;
      for (j=0; j<n; j++)
      {
        seta( setNr, "n", face[set[setNr].face[i]].nod[j] );
      }
    }
    /* circle through all elements and add all nodes and faces */
    /* nodes have to be completed before because otherwhise all geometry with there nodes would be included */
    for (i=0; i<set[setNr].anz_e; i++)
    {
      if (e_enqire[set[setNr].elem[i]].type == 1) n = 8;       /* HEXA8 */
      else if (e_enqire[set[setNr].elem[i]].type == 2) n = 6;  /* PENTA6 */
      else if (e_enqire[set[setNr].elem[i]].type == 3) n = 4;  /* TET4 */
      else if (e_enqire[set[setNr].elem[i]].type == 4) n = 20; /* HEXA20 */
      else if (e_enqire[set[setNr].elem[i]].type == 5) n = 15; /* PENTA15 */
      else if (e_enqire[set[setNr].elem[i]].type == 6) n = 10; /* TET10 */
      else if (e_enqire[set[setNr].elem[i]].type == 7) n = 3;  /* TRI3  */
      else if (e_enqire[set[setNr].elem[i]].type == 8) n = 6;  /* TRI6  */
      else if (e_enqire[set[setNr].elem[i]].type == 9) n = 4;  /* QUAD4 */
      else if (e_enqire[set[setNr].elem[i]].type == 10) n = 8; /* QUAD8 */
      else if (e_enqire[set[setNr].elem[i]].type == 11) n = 2; /* BEAM2 */
      else if (e_enqire[set[setNr].elem[i]].type == 12) n = 3; /* BEAM3 */
      else n=0;
      for (j=0; j<n; j++)
      {
        seta( setNr, "n", e_enqire[set[setNr].elem[i]].nod[j] );
      }
    }

    /* add the element-faces to the set */
    /* reference the faces by the elements for easy identification */
    if( (iface=(int **)malloc((anz->emax+1)*sizeof(int *) ) )==NULL) 
    { printf(" ERROR: malloc failure\n"); return(-1); }
    for (j=0; j<=anz->emax; j++)
    {
      if( (iface[j]=(int *)malloc((int)7*sizeof(int) ) )==NULL) 
      { printf(" ERROR: malloc failure\n"); return(-1); }
      iface[j][0]=0;
    }
    for (j=0; j<anz->f; j++)
    {
      iface[face[j].elem_nr][0]++;
      if(iface[face[j].elem_nr][0]>6)
      {
        printf("ERROR1 in elem:%d face:%d n:%d\n",face[j].elem_nr,j,iface[face[j].elem_nr][0]);
        return(-1);
      } 
      iface[face[j].elem_nr][iface[face[j].elem_nr][0]]=j;
    }
    for (j=0; j<set[setNr].anz_e; j++)
    {
      if(set[setNr].elem[j]>anz->emax)
        printf("ERROR2 e:%d emax:%d\n", set[setNr].elem[j], anz->emax);
      if(iface[set[setNr].elem[j]][0]>0)
      {
        if(iface[set[setNr].elem[j]][0]>6)
        {
          printf("ERROR3 in elem:%d face:%d n:%d\n",set[setNr].elem[j],j,iface[set[setNr].elem[j]][0]);
          return(-1);
        } 
        for(n=1; n<=iface[set[setNr].elem[j]][0]; n++)
        {  seta( setNr, "f", iface[set[setNr].elem[j]][n] ); }
      }
    }
    for (j=0; j<=anz->emax; j++) free(iface[j]);
    free(iface); 

    /* cyrcle through all bodys and add all surfs */
    for (i=0; i<set[setNr].anz_b; i++)
    {
      c= set[setNr].body[i];
      for (j=0; j<body[c].ns; j++)
      {
        l=body[c].s[j];
        seta( setNr, "s", l );
      }
    }
    /* cyrcle through all surfs and add all lines, lcmbs and nurbs */
    for (i=0; i<set[setNr].anz_s; i++)
    {
      s= set[setNr].surf[i];
      if(surf[s].sh>-1) seta( setNr, "S", surf[s].sh );
      for (j=0; j<surf[s].nl; j++)
      {
        l=surf[s].l[j];
        if (surf[s].typ[j]=='l')
        {
          seta( setNr, "l", l );
        }
        else
        {
          seta( setNr, "c", l );
        }
      }
    }
    /* cyrcle through all lcmbs and add all lines */
    for (i=0; i<set[setNr].anz_c; i++)
    {
      c= set[setNr].lcmb[i];
      for (j=0; j<lcmb[c].nl; j++)
      {
        l=lcmb[c].l[j];
        seta( setNr, "l", l );
      }
    }
    /* cyrcle through all lines and add all points, trks */
    for (i=0; i<set[setNr].anz_l; i++)
    {
      l= set[setNr].line[i];
      seta( setNr, "p", line[l].p1 );
      seta( setNr, "p", line[l].p2 );
      if (line[l].typ=='a') seta( setNr, "p", line[l].trk );
      if (line[l].typ=='s') seta( setNr, "se", line[l].trk );
    }
    /* cyrcle through all nurbs and add all points */
    for (i=0; i<set[setNr].anz_nurs; i++)
    {
      s= set[setNr].nurs[i];
      for (j=0; j<nurbs[s].u_npnt; j++)
        for (k=0; k<nurbs[s].v_npnt; k++)
          seta( setNr, "p", nurbs[s].ctlpnt[j][k] );
    }
    /* cyrcle through all sets and add all entities */
    for (i=0; i<set[setNr].anz_se; i++)
    {
      s= set[setNr].set[i];
      for (j=0; j<set[s].anz_n; j++)
      {
        p=set[s].node[j];
        seta( setNr, "n", p );
      }
      for (j=0; j<set[s].anz_f; j++)
      {
        p=set[s].face[j];
        seta( setNr, "f", p );
      }
      for (j=0; j<set[s].anz_e; j++)
      {
        p=set[s].elem[j];
        seta( setNr, "e", p );
      }
      for (j=0; j<set[s].anz_p; j++)
      {
        p=set[s].pnt[j];
        seta( setNr, "p", p );
      }
      for (j=0; j<set[s].anz_l; j++)
      {
        p=set[s].line[j];
        seta( setNr, "l", p );
      }
      for (j=0; j<set[s].anz_c; j++)
      {
        p=set[s].lcmb[j];
        seta( setNr, "c", p );
      }
      for (j=0; j<set[s].anz_s; j++)
      {
        p=set[s].surf[j];
        seta( setNr, "s", p );
      }
      for (j=0; j<set[s].anz_b; j++)
      {
        p=set[s].body[j];
        seta( setNr, "b", p );
      }
    }

    /* remove the appended sets */
    while(set[setNr].anz_se>0)
    {
      s= set[setNr].set[0];
      setr( setNr, "se", s);
    }

  }

  else if (toupper(type[0])=='F') /* faces */
  {
    /* cyrcle through all nodes and add all fully described faces */
    if(set[setNr].anz_n)
    {
      /* reference the faces by the nodes for easy identification */
      if( (iface=(int **)malloc((anz->nmax+1)*sizeof(int *) ) )==NULL) 
      { printf(" ERROR: malloc failure\n"); return(-1); }
      for (j=0; j<=anz->nmax; j++)
      {
        if( (iface[j]=(int *)malloc((int)1*sizeof(int) ) )==NULL) 
        { printf(" ERROR: malloc failure\n"); return(-1); }
        iface[j][0]=0;
      }
      if( (sumface=(int *)malloc( (anz->f+1)*sizeof(int) ) )==NULL) 
      { printf(" ERROR: malloc failure\n"); goto mfail_comp; }
      for (i=0; i<anz->f; i++)
      {
        sumface[i]=0;
        if (face[i].type == 7) n = 3;  /* TRI3  */
        else if (face[i].type == 8) n = 6;  /* TRI6  */
        else if (face[i].type == 9) n = 4;  /* QUAD4 */
        else if (face[i].type == 10) n = 8; /* QUAD8 */
        else n=0;
        for (j=0; j<n; j++)
        {
          /* store for each node the amount and index of all affected faces */
          iface[face[i].nod[j]][0]++;
          if( (iface[face[i].nod[j]]=(int *)realloc((int *)iface[face[i].nod[j]], (int)(iface[face[i].nod[j]][0]+2)*sizeof(int) ) )==NULL) 
          { printf(" ERROR: realloc failure\n"); return(-1); }
          iface[face[i].nod[j]][iface[face[i].nod[j]][0]]=i;
	}
      }
      for (i=0; i<set[setNr].anz_n; i++)
      {
        /* goto all set-nodes and mark all affected faces */
        if(iface[set[setNr].node[i]][0]>0)
	{
          for(j=1; j<=iface[set[setNr].node[i]][0]; j++)
          {
            /* all affected faces are marked */
	    sumface[iface[set[setNr].node[i]][j]]++;
	  }
	}
      }
      /* now go through all faces and look how often it was marked */
      for (i=0; i<anz->f; i++)
      {
        if (face[i].type == 7) n = 3;  /* TRI3  */
        else if (face[i].type == 8) n = 6;  /* TRI6  */
        else if (face[i].type == 9) n = 4;  /* QUAD4 */
        else if (face[i].type == 10) n = 8; /* QUAD8 */
        else n=0;
        if(sumface[i]==n) seta( setNr, "f", i );
      }
      for (j=0; j<=anz->nmax; j++) free(iface[j]);
      free(iface); 
      free(sumface); 
    }
  }

  else if (toupper(type[0])=='E') /* edges */
  {
    /* cyrcle through all bodys and add all surfs */
    for (i=0; i<set[setNr].anz_b; i++)
    {
      c= set[setNr].body[i];
      for (j=0; j<body[c].ns; j++)
      {
        l=body[c].s[j];
        seta( setNr, "s", l );
      }
    }
    /* cyrcle through all surfs and add all lines, lcmbs  */
    for (i=0; i<set[setNr].anz_s; i++)
    {
      s= set[setNr].surf[i];
      for (j=0; j<surf[s].nl; j++)
      {
        l=surf[s].l[j];
        if (surf[s].typ[j]=='l')
        {
          seta( setNr, "l", l );
        }
        else
        {
          seta( setNr, "c", l );
        }
      }
    }
    /* cyrcle through all lcmbs and add all lines */
    for (i=0; i<set[setNr].anz_c; i++)
    {
      c= set[setNr].lcmb[i];
      for (j=0; j<lcmb[c].nl; j++)
      {
        l=lcmb[c].l[j];
        seta( setNr, "l", l );
      }
    }
    /* cyrcle through all lines and add all corner-points */
    for (i=0; i<set[setNr].anz_l; i++)
    {
      l= set[setNr].line[i];
      seta( setNr, "p", line[l].p1 );
      seta( setNr, "p", line[l].p2 );
    }
  }
  else printf(" Command not recognized, use up down or edges\n");
  return(setNr);
}



/* send the interiour of the surfaces in stl format (not used ) */

int sendTriangles(  unsigned char *setname )
{
  int i,j,k,n,s, setNr, tris=0;
  FILE *handle;

  operateAlias( setname, "se" );
  setNr=getSetNr(setname);
  if (setNr<0)
  {
    printf (" ERROR in completeSet: set:%s does not exist\n", setname);
    return(-1);
  }

  sprintf(buffer, "%s.stl", setname);
  handle = fopen (buffer, "w");
  if (handle==NULL)
  {
    printf (" ERROR: The input file \"%s\" could not be opened.\n\n", datin);
    return(-1);
  }
  else  printf ("\n%s opened\n",buffer);

  /* write the interiour of the surface */
  fprintf( handle, "solid\n");
  for (i=0; i<set[setNr].anz_s; i++)
  {
    s= set[setNr].surf[i];

    n=0;
    while((surf[s].npgn-n))
    {
      n++;
      j=surf[s].pgn[n++];
      fprintf( handle, "  facet normal %e %e %e\n",surf[s].pgn[n],surf[s].pgn[n+1],surf[s].pgn[n+2]); n+=3;
      fprintf( handle, "    outer loop\n");
      for(k=0; k<j; k++)
      {
        fprintf( handle, "      vertex %e %e %e\n",
          surf[s].pgn[n]*scale->w+scale->x,
          surf[s].pgn[n+1]*scale->w+scale->y,
          surf[s].pgn[n+2]*scale->w+scale->z); n+=3;
      }
      tris++;
      fprintf( handle, "    endloop\n");
      fprintf( handle, "  endfacet\n");
    }
  }
  fprintf( handle, "endsolid\n");
  printf("wrote %d triangles\n", tris);
  fclose(handle);
  return(1);
}



int write2stl(unsigned char *datout, Summen *anz, Nodes *node, Elements *elem, Datasets *lcase )
{
  int i,k,elems=0;
  double v1[3], v2[3], v3[3];
  FILE *handle;

  handle = fopen (datout, "w");
  if (handle==NULL)
  {
    printf (" ERROR: The input file \"%s\" could not be opened.\n\n", datout);
    return(-1);
  }
  else  printf ("\n%s opened\n", datout);

  /* write the elements if they are tr3 */
  fprintf( handle, "solid\n");
  for (i=0; i<anz->e; i++)
  {
    if (elem[i].type == 7)
    {
      v_result( &node[elem[i].nod[0]].nx, &node[elem[i].nod[1]].nx, v1);
      v_result( &node[elem[i].nod[1]].nx, &node[elem[i].nod[2]].nx, v2);
      v_prod( v1, v2, v3 );
      v_norm( v3, v1 );
      fprintf( handle, "  facet normal %e %e %e\n",v1[0],v1[1],v1[2]);
      fprintf( handle, "    outer loop\n");
      for(k=0; k<3; k++)
      {
        fprintf( handle, "      vertex %e %e %e\n",
        node[elem[i].nod[k]].nx,
        node[elem[i].nod[k]].ny,
        node[elem[i].nod[k]].nz);
      }
      fprintf( handle, "    endloop\n");
      fprintf( handle, "  endfacet\n");
      elems++;
    }
  }
  fprintf( handle, "endsolid\n");
  printf("wrote %d triangles\n", elems);
  fclose(handle);
  return(1);
}



int write2netgenEdges(unsigned char *datout, Summen *anz, Nodes *node, Elements *elem, Datasets *lcase )
{
  int i,elems=0;
  FILE *handle;

  handle = fopen (datout, "w");
  if (handle==NULL)
  {
    printf (" ERROR: The input file \"%s\" could not be opened.\n\n", datout);
    return(-1);
  }
  else  printf ("\n%s opened\n", datout);

  /* write the elements if they are be2 */
  for (i=0; i<anz->e; i++) if (elem[i].type == 11) elems++;
  fprintf( handle, "%d\n",elems);

  for (i=0; i<anz->e; i++)
  {
    if (elem[i].type == 11)
    {
      fprintf( handle, "2 %e %e %e %e %e %e\n",
        node[elem[i].nod[0]].nx,
        node[elem[i].nod[0]].ny,
        node[elem[i].nod[0]].nz,
        node[elem[i].nod[1]].nx,
        node[elem[i].nod[1]].ny,
        node[elem[i].nod[1]].nz);
    }
  }
  printf("wrote %d edges\n", elems);
  fclose(handle);
  return(1);
}



void pre_write( unsigned char *record )
{
  unsigned char  setname[MAX_LINE_LENGTH], format[MAX_LINE_LENGTH], type[MAX_LINE_LENGTH], **dat;
  int          length, anz_l, setNr, i,j,l=0,s,v,n,b;
  unsigned char typ,  **val, buffer[MAX_LINE_LENGTH];
  double        f[3]={0.,0.,0.};
  int bset;
  int bouNr;
  Dunsbou *dunsbou=NULL;
  int *linebuf=NULL, *lcmbbuf=NULL, *surfbuf=NULL;

  if(( val=(unsigned char **)malloc( 4*sizeof(unsigned char *)) )==NULL)
  { printf(" ERROR: malloc failure\n\n" ); return; }
  for(i=0; i<4; i++)
  {
    if(( val[i]=(unsigned char *)malloc( MAX_LINE_LENGTH*sizeof(unsigned char)) )==NULL)
    { printf(" ERROR: malloc failure\n\n" ); return; }
    val[i][0]=0;
  }

  /* clean the buffers */
  for(i=0; i<MAX_LINE_LENGTH; i++) setname[i]=format[i]=type[i]=(unsigned char)NULL;
  for(i=0; i<MAX_LINE_LENGTH; i++) for(j=0; j<4; j++) val[j][i]=(unsigned char)NULL;

  length = sscanf(record, "%s%s%s%s%s%s%s", setname, format, type, val[0], val[1], val[2], val[3]);
  if (length<2) { printf(" ERROR: format missing!\n"); return; }

  operateAlias( setname, "se" );
  printf (" please wait for 'ready'\n");

  if (compare( format, "fbd", 3)== 3)
  {
    if(getSetNr(specialset->zap)>-1)
    {
      errMsg("ERROR: special set:%s is not empty. Please delete the set before\n", specialset->zap);
      return;
    }
    if (length>2)
    {
      if (compare( type, "c", 1)== 1)
      {
      completeSet( setname, "do" );
      }
    }
    descalPoints( anzGeo->p, point, scale);
    writefbd( setname, anzGeo, point, line, lcmb, surf, body, nurbs, set );
    scalPoints( anzGeo->p, point, scale);
  }
  else if (compare( format, "frd", 3)== 3)
  {
    if (length>2)
    {
      if (compare( type, "sur", 3)== 3)
        sendSurfNormalen( setname, format, anz, node, e_enqire, lcase, scale );
      else if (compare( type, "c", 1)== 1)
      {
        anz_l=anz->l;
        anz->l=num_olc;
        senddata( setname, format, anz, node, e_enqire, lcase, scale, 1, 0);
        anz->l=anz_l;
      }
      else if (compare( type, "lc", 2)== 2)
      {
        strcpy(val[1], val[0]);
        strcpy(val[0], type);
        senddata( setname, format, anz, node, e_enqire, lcase, scale, 1, val);
      }
      else
      {
        errMsg(" ERROR:  %s in format %s not yet supported\n", type, format );
        return;
      }
    }
    else
    {
      anz_l=anz->l;
      anz->l=num_olc;
      senddata( setname, format, anz, node, e_enqire, lcase, scale, 0, 0);
      anz->l=anz_l;
    }
  }
  else if (compare( format, "abq", 3)== 3)
  {
    if (length>2)
    {
      if (compare( type, "pres", 3)== 3)
        sendPressure( setname, format, anz, node, e_enqire, val[0], val[1] );
      else if (compare( type, "film", 3)== 3)
        sendFilm( setname, format, anz, node, e_enqire, val[0], val[1], val[2], val[3] );
      else if (compare( type, "radiate", 3)== 3)
        sendRadiate( setname, format, anz, node, e_enqire, val[0], val[1], val[2], val[3] );
      else if (compare( type, "dflux", 3)== 3)
        sendDflux( setname, format, anz, node, e_enqire, val[0], val[1] );
      else if (compare( type, "force", 3)== 3)
      { length = sscanf(record, "%*s%*s%*s%lf%lf%lf", &f[0],&f[1],&f[2]);
        sendForce( setname, format, anz, node, e_enqire, f ); }
      else if (compare( type, "spc", 3)== 3)
        sendSPC( setname, format, anz, node, e_enqire, val[0], val[1] );
      else if (compare( type, "cflux", 3)== 3)
        sendCflux( setname, format, anz, node, e_enqire, "t", val[0] );
      else if (compare( type, "slide", 3)== 3)
        sendSliders( setname, format, anz, node, e_enqire, val[0]  );
      else if (compare( type, "names", 3)== 3)
        sendNames( setname, format, anz, node, e_enqire );
      else if (compare( type, "sur", 3)== 3)
        sendSurfaces( setname, format, anz, node, e_enqire );
      else if (compare( type, "mpc", 3)== 3)
      { length = sscanf(record, "%*s%*s%*s%*s%lf%lf%lf", &f[0],&f[1],&f[2]);
        sendMpc( setname, format, anz, node, e_enqire, val[0], f ); }
      else if (compare( type, "lc", 2)== 2)
      {
        strcpy(val[1], val[0]);
        strcpy(val[0], type);
        anz_l=anz->l;
        anz->l=num_olc;
        senddata( setname, format, anz, node, e_enqire, lcase, scale, 0, val);
        anz->l=anz_l;
      }
      else if (compare( type, "tmf", 2)== 2)
      {
        anz_l=anz->l;
        anz->l=num_olc;
        strcpy(val[0], type);
        senddata( setname, format, anz, node, e_enqire, lcase, scale, 0, val);
        anz->l=anz_l;
      }
      else if (compare( type, "crp", 2)== 2)
      {
        anz_l=anz->l;
        anz->l=num_olc;
        strcpy(val[3], val[2]); /* write-frequency */
        strcpy(val[2], val[1]); /* reference-speed */
        strcpy(val[1], val[0]); /* time-factor */
        strcpy(val[0], type);
        senddata( setname, format, anz, node, e_enqire, lcase, scale, 0, val);
        anz->l=anz_l;
      }
      else if (compare( type, "sta", 2)== 2)
      {
        anz_l=anz->l;
        anz->l=num_olc;
        strcpy(val[2], val[0]); /* reference-speed */
        strcpy(val[0], type);
        senddata( setname, format, anz, node, e_enqire, lcase, scale, 0, val);
        anz->l=anz_l;
      }
      else if (compare( type, "c", 1)== strlen(type))
      {
        anz_l=anz->l;
        anz->l=num_olc;
        senddata( setname, format, anz, node, e_enqire, lcase, scale, 1, 0);
        anz->l=anz_l;
      }
      else
      {
        errMsg(" ERROR:  %s in format %s not yet supported\n", type, format );
        return;
      }
    }
    else
    {
      anz_l=anz->l;
      anz->l=num_olc;
      senddata( setname, format, anz, node, e_enqire, lcase, scale, 0, 0);
      anz->l=anz_l;
    }
  }
  /* changes from Paul CARRICO */
  else if (compare( format, "aster", 3)== 3)
  {
    if (length>2)
    {
      if (compare( type, "names", 3)== 3)
        sendNames( setname, format, anz, node, e_enqire );
      else if (compare( type, "c", 1)== 1)
      {
        anz_l=anz->l;
        anz->l=num_olc;
        senddata( setname, format, anz, node, e_enqire, lcase, scale, 1, 0);
        anz->l=anz_l;
      }
      else
      {
        errMsg(" ERROR:  %s in format %s not yet supported\n", type, format );
        return;
      }
    }
    else
    {
      anz_l=anz->l;
      anz->l=num_olc;
      senddata( setname, format, anz, node, e_enqire, lcase, scale, 0, 0);
      anz->l=anz_l;
    }
  }
  /* changes from Paul CARRICO */
  else if (compare( format, "sam", 3)== 3)
  {
    if (length>2)
    {
      if (compare( type, "names", 3)== 3)
        sendNames( setname, format, anz, node, e_enqire );
      else if (compare( type, "c", 1)== 1)
      {
        anz_l=anz->l;
        anz->l=num_olc;
        senddata( setname, format, anz, node, e_enqire, lcase, scale, 1, 0);
        anz->l=anz_l;
      }
      else
      {
        printf(" ERROR:  %s in format %s not yet supported\a\n", type, format );
        return;
      }
    }
    else
    {
      anz_l=anz->l;
      anz->l=num_olc;
      senddata( setname, format, anz, node, e_enqire, lcase, scale, 0, 0);
      anz->l=anz_l;
    }
  }
  else if (compare( format, "adh", 3)== 3)
  {
    if (length>2)
    {
      if (compare( type, "spc", 3)== 3)
        sendSPC( setname, format, anz, node, e_enqire, val[0], val[1] );
      else
      {
        errMsg(" ERROR:  %s in format %s not yet supported\n", type, format );
        return;
      }
    }
    else
    {
      anz_l=anz->l;
      anz->l=num_olc;
      senddata( setname, format, anz, node, e_enqire, lcase, scale, 0, 0);
      anz->l=anz_l;
    }
  }
  else if (compare( format, "ans", 3)== 3)
  {
    if (length>2)
    {
      if (compare( type, "pres", 4)== 4)
        sendPressure( setname, format, anz, node, e_enqire, val[0], val[1] );
      else if (compare( type, "for", 3)== 3)
      { length = sscanf(record, "%*s%*s%*s%lf%lf%lf", &f[0],&f[1],&f[2]);
        sendForce( setname, format, anz, node, e_enqire, f ); }
      else if (compare( type, "spc", 3)== 3)
        sendSPC( setname, format, anz, node, e_enqire, val[0], val[1] );
      else if (compare( type, "slide", 4)== 4)
        sendSliders( setname, format, anz, node, e_enqire, val[0]  );
      else if (compare( type, "names", 4)== 4)
        sendNames( setname, format, anz, node, e_enqire );
      else if (compare( type, "c", 1)== 1)
      {
        anz_l=anz->l;
        anz->l=num_olc;
        senddata( setname, format, anz, node, e_enqire, lcase, scale, 1, 0);
        anz->l=anz_l;
      }
      else
      {
        errMsg(" ERROR:  %s in format %s not yet supported\n", type, format );
        return;
      }
    }
    else
    {
      anz_l=anz->l;
      anz->l=num_olc;
      senddata( setname, format, anz, node, e_enqire, lcase, scale, 0, 0);
      anz->l=anz_l;
    }
  }
  else if (compare( format, "nas", 3)== 3)
  {
    if (length>2)
    {
      if (compare( type, "pres", 4)== 4)
        sendPressure( setname, format, anz, node, e_enqire, val[0], val[1] );
      else if (compare( type, "for", 3)== 3)
      { length = sscanf(record, "%*s%*s%*s%lf%lf%lf", &f[0],&f[1],&f[2]);
        sendForce( setname, format, anz, node, e_enqire, f ); }
      else if (compare( type, "spc", 3)== 3)
        sendSPC( setname, format, anz, node, e_enqire, val[0], val[1] );
      else if (compare( type, "c", 1)== 1)
      {
        anz_l=anz->l;
        anz->l=num_olc;
        senddata( setname, format, anz, node, e_enqire, lcase, scale, 1, 0);
        anz->l=anz_l;
      }
      else
      {
        errMsg(" ERROR:  %s in format %s not yet supported\n", type, format );
        return;
      }
    }
    else
    {
      anz_l=anz->l;
      anz->l=num_olc;
      senddata( setname, format, anz, node, e_enqire, lcase, scale, 0, 0);
      anz->l=anz_l;
    }
  }
  else if (compare( format, "tcg", 3)== 3)
  {
    if (length>2)
    {
      if (compare( type, "pres", 4)== 4)
        sendPressure( setname, format, anz, node, e_enqire, val[0], val[1] );
      else if (compare( type, "for", 3)== 3)
      { length = sscanf(record, "%*s%*s%*s%lf%lf%lf", &f[0],&f[1],&f[2]);
        sendForce( setname, format, anz, node, e_enqire, f ); }
      else if (compare( type, "spc", 3)== 3)
        sendSPC( setname, format, anz, node, e_enqire, val[0], val[1] );
      else if (compare( type, "c", 1)== 1)
      {
        anz_l=anz->l;
        anz->l=num_olc;
        senddata( setname, format, anz, node, e_enqire, lcase, scale, 1, 0);
        anz->l=anz_l;
      }
      else
      {
        errMsg(" ERROR:  %s in format %s not yet supported\n", type, format );
        return;
      }
    }
    else
    {
      anz_l=anz->l;
      anz->l=num_olc;
      senddata( setname, format, anz, node, e_enqire, lcase, scale, 0, 0);
      anz->l=anz_l;
    }
  }
  else if (compare( format, "duns", 3)== 3)
  {
    if (compare( type, "names", 3)== 3) sendNames( setname, format, anz, node, e_enqire );
    else
    {
      length= strsplt( record, ' ', &dat);

      /* initialize the bctype with "0" */
      for( b=0; b<anz->b; b++)
      {
        if(nBlock[b].dim==2)
        {
          s=nBlock[b].geo;
          for(j=0; j<surf[s].nl; j++) nBlock[b].bctype[j][0]=0;
        }
        if(nBlock[b].dim==3)
        {
          s=nBlock[b].geo;
          for(j=0; j<body[s].ns; j++) nBlock[b].bctype[j][0]=0;
        }
      }

      /* add the grid-blocks to the type of boundary */
      bouNr=-1;
      n=2; while(n<length)
      {
        /* search the corresponding blocks */
        bset=getSetNr(dat[n+1]);
        if(bset<0)
        {
          printf("boundary set:%s does not exist\n", dat[n+1]);
          return;
        }
        bouNr++;
        if((dunsbou=(Dunsbou *)realloc((Dunsbou *)dunsbou, (bouNr+1)*sizeof(Dunsbou)) )==NULL)
        { printf(" ERROR: realloc failure, dunsbou:%d could not be allocated\n\n", bouNr ); return; }
        strcpy(dunsbou[bouNr].name,set[bset].name);
        dunsbou[bouNr].surf=NULL;
        dunsbou[bouNr].surfs=0;

        /* add the lcmb to the set */
        for(i=0; i<set[bset].anz_l; i++)
        {
          for(j=0; j<anzGeo->c; j++)
          {
            for(l=0; l<lcmb[j].nl; l++)
            {
              if(lcmb[j].l[l]==set[bset].line[i]) seta(bset, "c", j);
            }
          }
        }
  
        if(( linebuf=(int *)realloc((int *)linebuf, (anzGeo->l+2)*sizeof(int)) )==NULL)
        { printf(" ERROR: realloc failure\n\n" ); return; }
        if(( lcmbbuf=(int *)realloc((int *)lcmbbuf, (anzGeo->c+2)*sizeof(int)) )==NULL)
        { printf(" ERROR: realloc failure\n\n" ); return; }
        if(( surfbuf=(int *)realloc((int *)surfbuf, (anzGeo->s+2)*sizeof(int)) )==NULL)
        { printf(" ERROR: realloc failure\n\n" ); return; }
        for(i=0; i<set[bset].anz_l; i++)        linebuf[set[bset].line[i]]=-1;
        for(i=0; i<set[bset].anz_c; i++)        lcmbbuf[set[bset].lcmb[i]]=-1;
        for(i=0; i<set[bset].anz_s; i++)        surfbuf[set[bset].surf[i]]=-1;

        /* look if a member of the set is used by a block */
        for( b=0; b<anz->b; b++)
        {
          if(nBlock[b].dim==2)
          {
            s=nBlock[b].geo;
            for(i=0; i<set[bset].anz_l; i++)
            {
              for(j=0; j<surf[s].nl; j++)
              {
                if(nBlock[b].map[j][0]==-1)
                {
                  l=surf[s].l[nBlock[b].bcface[j]];
                  typ=surf[s].typ[nBlock[b].bcface[j]];
                }
                else typ=-1;
                if(typ=='l')
                {
                  if(l==set[bset].line[i])
                  {
                    linebuf[l]=nBlock[b].neighbor[j];
                    break;
                  }
                }
              }
            }
            for(i=0; i<set[bset].anz_c; i++)
            {
              for(j=0; j<surf[s].nl; j++)
              {
                if(nBlock[b].map[j][0]==-1)
                {
                  typ=surf[s].typ[nBlock[b].bcface[j]];
                  l=surf[s].l[nBlock[b].bcface[j]];
                }
                else typ=-1;
                if(typ=='c')
                {
                  if(l==set[bset].lcmb[i])
                  {
                    lcmbbuf[l]=nBlock[b].neighbor[j];
                    break;
                  }
                }
              }
            }
          }
          if(nBlock[b].dim==3)
	  {
            v=nBlock[b].geo;
            for(i=0; i<set[bset].anz_s; i++)
            {
              for(j=0; j<body[v].ns; j++)
              {
                if(nBlock[b].map[j][0]==-1) s=body[v].s[nBlock[b].bcface[j]];
                else s=-1;
                if(s==set[bset].surf[i])
                {
            printf("body:%s bsurf:%s surf:%s\n", body[v].name, surf[body[v].s[nBlock[b].bcface[j]]].name, surf[set[bset].surf[i]].name);
                  surfbuf[s]=nBlock[b].neighbor[j];
                  break;
                }
              }
            }
	  }
        }

        /* store the identified entities in dunsbou */
        for(i=0; i<set[bset].anz_l; i++)
        {
          if(linebuf[set[bset].line[i]]>0)
	  {
            if((dunsbou[bouNr].surf=(int *)realloc((int *)dunsbou[bouNr].surf, (dunsbou[bouNr].surfs+2)*sizeof(int)) )==NULL)
            { printf(" ERROR: realloc failure, dunsbou:%d surface could not be allocated\n\n", bouNr ); return; }
            printf("set:%s bou:%s bouNr:%d store line[%d] %s in %s nr:%d\n",set[bset].name, dat[n],bouNr,dunsbou[bouNr].surfs, line[set[bset].line[i]].name, dat[n],linebuf[set[bset].line[i]]);
            dunsbou[bouNr].surf[dunsbou[bouNr].surfs] = linebuf[set[bset].line[i]];
            strcpy(dunsbou[bouNr].bctype, dat[n]);
            dunsbou[bouNr].surfs++;
	  }
	}
        for(i=0; i<set[bset].anz_c; i++)
        {
          if(lcmbbuf[set[bset].lcmb[i]]>0)
	  {
            if((dunsbou[bouNr].surf=(int *)realloc((int *)dunsbou[bouNr].surf, (dunsbou[bouNr].surfs+2)*sizeof(int)) )==NULL)
            { printf(" ERROR: realloc failure, dunsbou:%d surface could not be allocated\n\n", bouNr ); return; }
            printf("set:%s bou:%s bouNr:%d store lcmb[%d] %s in %s nr:%d\n",set[bset].name, dat[n],bouNr,dunsbou[bouNr].surfs, lcmb[set[bset].lcmb[i]].name, dat[n],lcmbbuf[set[bset].lcmb[i]]);
            dunsbou[bouNr].surf[dunsbou[bouNr].surfs] = lcmbbuf[set[bset].lcmb[i]];
            strcpy(dunsbou[bouNr].bctype, dat[n]);
            dunsbou[bouNr].surfs++;
	  }
	}
        for(i=0; i<set[bset].anz_s; i++)
        {
          if(surfbuf[set[bset].surf[i]]>0)
	  {
            if((dunsbou[bouNr].surf=(int *)realloc((int *)dunsbou[bouNr].surf, (dunsbou[bouNr].surfs+2)*sizeof(int)) )==NULL)
            { printf(" ERROR: realloc failure, dunsbou:%d surface could not be allocated\n\n", bouNr ); return; }
            printf("set:%s bou:%s bouNr:%d store surf[%d] %s in %s nr:%d\n",set[bset].name, dat[n],bouNr,dunsbou[bouNr].surfs, surf[set[bset].surf[i]].name, dat[n],surfbuf[set[bset].surf[i]]);
            dunsbou[bouNr].surf[dunsbou[bouNr].surfs] = surfbuf[set[bset].surf[i]];
            strcpy(dunsbou[bouNr].bctype, dat[n]);
            dunsbou[bouNr].surfs++;
	  }
	}

        n+=2;
      }
      bouNr++;

      descalNodes ( anz->n, node, scale);
      write2duns( setname, anz, node, e_enqire, lcase, nBlock, bouNr, dunsbou );
      scalNodes ( anz->n, node, scale);

      for(i=0; i<bouNr; i++) free(dunsbou[i].surf); free(dunsbou);
      free(linebuf);
      free(lcmbbuf);
      free(surfbuf);
    }
  }
  else if (compare( format, "foam", 3)== 3)
  {
    length= strsplt( record, ' ', &dat);
    descalNodes ( anz->n, node, scale);
    write2foam( setname, length-2, &dat[2], anz, node, face, e_enqire, set );
    scalNodes ( anz->n, node, scale);

    /* free dat */
    for(i=0; i<length; i++) free(dat[i]); free(dat);
  }
  else if (compare( format, "isaac", 3)== 3)
  {
    length= strsplt( record, ' ', &dat);

    for( b=0; b<anz->b; b++)
    {
      if(nBlock[b].dim==2)
      {
        s=nBlock[b].geo;
        for(j=0; j<surf[s].nl; j++) strcpy(nBlock[b].bctype[j], "not defined");
      }
      if(nBlock[b].dim==3)
      {
        s=nBlock[b].geo;
        for(j=0; j<body[s].ns; j++) strcpy(nBlock[b].bctype[j], "not defined");
      }
    }
    /* add the type of boundary to the grid-blocks */
    n=2; while(n<length)
    {
      /* search the corresponding blocks */
      bset=getSetNr(dat[n+1]);
      if(bset<0)
      {
        printf("boundary set:%s does not exist\n", dat[n]);
        return;
      }

      if(nBlock[b].dim==2)
      {
       /* add the lcmb to the set */
       for(i=0; i<set[bset].anz_l; i++)
       {
        for(j=0; j<anzGeo->c; j++)
        {
          for(l=0; l<lcmb[j].nl; l++)
	  {
	    printf("add lcmb:%s to set %s\n", lcmb[j].name, set[bset].name);
            if(lcmb[j].l[l]==set[bset].line[i]) seta(bset, "c", j);
	  }
	}
       }
      }

      /* look if a member of the set is used by a block */
      for( b=0; b<anz->b; b++)
      {
        if(nBlock[b].dim==2)
        {
          s=nBlock[b].geo;
          for(i=0; i<set[bset].anz_l; i++)
          {
            for(j=0; j<surf[s].nl; j++)
            {
              l=surf[s].l[nBlock[b].bcface[j]];
              typ=surf[s].typ[nBlock[b].bcface[j]];
              if(typ=='l')
              {
                if(l==set[bset].line[i])
                {
                  printf(" store line %s in set:%s\n",line[l].name ,dat[n]);
                  strcpy(nBlock[b].bctype[j], dat[n]);
                }
              }
            }
          }
          for(i=0; i<set[bset].anz_c; i++)
          {
            for(j=0; j<surf[s].nl; j++)
            {
              l=surf[s].l[nBlock[b].bcface[j]];
              typ=surf[s].typ[nBlock[b].bcface[j]];
              if(typ=='c')
              {
                if(l==set[bset].lcmb[i])
                {
                  printf(" store lcmb %s in set:%s \n",lcmb[l].name, dat[n]);
                  strcpy(nBlock[b].bctype[j], dat[n]);
                }
              }
            }
          }
        }
        if(nBlock[b].dim==3)
        {
          s=nBlock[b].geo;
          for(i=0; i<set[bset].anz_s; i++)
          {
            for(j=0; j<body[s].ns; j++)
            {
              l=body[s].s[nBlock[b].bcface[j]];
              if(l==set[bset].surf[i])
              {
                printf(" store surf %s in set:%s\n", surf[l].name, dat[n]);
                strcpy(nBlock[b].bctype[j], dat[n]);
              }
            }
          }
        }
      }
      n+=2;
    }

    for( b=0; b<anz->b; b++)
    {
      if(nBlock[b].dim==2)
      {
        s=nBlock[b].geo;
        for(j=0; j<surf[s].nl; j++)
        {
          if((surf[s].typ[nBlock[b].bcface[j]]=='l')&&(nBlock[b].bctype[j][0]==0))
          {
            printf(" WARNING: free surface:%s are not defined as boundary:%s in block: %d\n",line[surf[s].l[nBlock[b].bcface[j]]].name,nBlock[b].bctype[j], b);
          } 
          if((surf[s].typ[nBlock[b].bcface[j]]=='c')&&(nBlock[b].bctype[j][0]==0))
          {
            printf(" WARNING: free surface:%s are not defined as boundary:%s in block: %d\n",lcmb[surf[s].l[nBlock[b].bcface[j]]].name,nBlock[b].bctype[j], b);
          } 
	}
      }
      if(nBlock[b].dim==3)
      {
        s=nBlock[b].geo;
        for(j=0; j<body[s].ns; j++)
        {
          if(nBlock[b].bctype[j][0]==0)
          {
            printf(" WARNING: free surface:%s are not defined as boundary:%s in block: %d\n",surf[body[s].s[nBlock[b].bcface[j]]].name,nBlock[b].bctype[j], b);
          } 
	}
      }
    }

    descalNodes ( anz->n, node, scale);   
    write2isaac( setname, anz, node, e_enqire, lcase, nBlock );
    scalNodes ( anz->n, node, scale);
  }
  else if (compare( format, "stl", 3)== 3)
  {
    /* sendTriangles( setname ); */
    anz_l=anz->l;
    anz->l=num_olc;
    senddata( setname, format, anz, node, e_enqire, lcase, scale, 0, 0);
    anz->l=anz_l;
  }
  else
  {
    /* assume 'format' is  a second set for the mpc's */
    setNr=getSetNr(setname);
    if (setNr<0)
    {
      printf (" ERROR: set:%s does not exist\n", setname);
      return;
    }
    i=getSetNr(format);
    if (i>-1)
    {
       length = sscanf(record, "%*s%*s%s%s%s%s", format, type, val[0], buffer);
       if (compare(type, "cycmpc", 6)==6) cycmpc(setNr, i, format, val[0], buffer);
       else if (compare(type, "areampc", 7)==7) areampc(setNr, i, format, val[0], buffer, 0);
       else if (compare(type, "gap", 3)==3) gap(record);
       else
       { 
         errMsg(" ERROR: mpc type %s not yet supported, available are cycmpc or areampc\n", type );
         return;
       }
       /* the additional nodes for the HE20 (then HE26) elements need a new pos.  */
       adjustNodes();
    }
    else errMsg(" ERROR: format:%s not yet supported, or set:%s does not exist\n", format, format );
  }
  printf (" ready\n");
}



/*------------------------------------------------------------------*/
/* Daten im frd, abaqus oder nastran format rausschreiben           */
/*------------------------------------------------------------------*/

void senddata( unsigned char *setname, unsigned char *format, Summen *anz, Nodes *node, Elements *e_enqire, Datasets *lcase , Scale *scale, int compFlag, unsigned char **val)
{
  int   setNr;
  int  length, i, j, ipuf;
  unsigned char prognam[MAX_LINE_LENGTH];
  Summen    anz2[1];
  Nodes     *node2;
  Elements  *elem2;
  static int   *isort=NULL;
  extern int compareInt();


  if ( (compare( format, "frd", 3) == 3)||
       (compare( format, "nas", 3) == 3)||
       (compare( format, "tcg", 3) == 3)||
       (compare( format, "abq", 3) == 3)||
       (compare( format, "ans", 3) == 3)||
       (compare( format, "ast", 3) == 3)||
       (compare( format, "sam", 3) == 3)||
       (compare( format, "stl", 3) == 3) );
  else
  {
    printf (" ERROR: format not recognized:%s\n\n", format);
    return;
  }

  setNr=getSetNr(setname);

  if (setNr<0)
  {
    printf (" ERROR in senddata, set:%s does not exist\n", setname);
    return;
  }

  descalNodes ( anz->n, node, scale);

  if ( (node2 = (Nodes *)malloc( (anz->nmax+1) * sizeof(Nodes))) == NULL )
    { printf(" ERROR: malloc failed in senddata\n\n") ; return; }
  if ( (elem2 = (Elements *)malloc( (anz->emax+1) * sizeof(Elements))) == NULL )
    { printf(" ERROR: malloc failed in senddata\n\n") ; return; }

  anz2->emax=0;
  anz2->emin=MAXVALUE;

  if ( (isort = (int *)realloc( isort, (set[setNr].anz_e+1) * sizeof(int))) == NULL )
    printf("ERROR: realloc failed: isort\n\n" ); 
  for( i=0; i<set[setNr].anz_e; i++) isort[i]=set[setNr].elem[i];
  qsort( isort, set[setNr].anz_e, sizeof(int), (void *)compareInt );

  for (i=0; i<set[setNr].anz_e; i++)
  {
    elem2[i].nr      = isort[i];
    elem2[i].type    = e_enqire[isort[i]].type;
    elem2[i].group   = e_enqire[isort[i]].group;
    elem2[i].mat     = e_enqire[isort[i]].mat;
    elem2[i].attr     = e_enqire[isort[i]].attr;
    
    if (anz2->emax<elem2[i].nr ) anz2->emax = elem2[i].nr;
    if (anz2->emin>elem2[i].nr ) anz2->emin = elem2[i].nr;
    ipuf=0;
    if (elem2[i].type == 1) ipuf = 8;  /* HEXA8 */
    if (elem2[i].type == 2) ipuf = 6;  /* PENTA6 */
    if (elem2[i].type == 3) ipuf = 4;  /* TET4 */
    if (elem2[i].type == 4) ipuf = 20; /* HEX20 */
    if (elem2[i].type == 5) ipuf = 15; /* PENTA15 */
    if (elem2[i].type == 6) ipuf = 10; /* TET10 */
    if (elem2[i].type == 7) ipuf = 3;  /* TRI3  */
    if (elem2[i].type == 8) ipuf = 6;  /* TRI6  */
    if (elem2[i].type == 9) ipuf = 4;  /* QUAD4 */
    if (elem2[i].type == 10) ipuf = 8; /* QUAD8 */
    if (elem2[i].type == 11) ipuf = 2; /* BEAM */
    if (elem2[i].type == 12) ipuf = 3; /* BEAM3 */
    if (ipuf==0)
    {
      if(printFlag) printf (" elem(%d) not a known type (%d)\n", elem2[i].nr, elem2[i].type);
    }
    else
    {
     if (compFlag)
     {
      for (j=0; j<ipuf; j++)
      {
        elem2[i].nod[j]=e_enqire[elem2[i].nr].nod[j];
        seta( setNr, "n", elem2[i].nod[j] );
      }
     }
     else
     {
      for (j=0; j<ipuf; j++)
      {
        elem2[i].nod[j]=e_enqire[elem2[i].nr].nod[j];
      }
     }
    }
  }


  /* nodes must follow the elements (seta n above!) */
  /* sort the nodenumbers */

  anz2->nmax = 0;
  anz2->nmin = MAXVALUE;

  if ( (isort = (int *)realloc( isort, (set[setNr].anz_n+1) * sizeof(int))) == NULL )
    printf("ERROR: realloc failed: isort\n\n" ); 
  for( i=0; i<set[setNr].anz_n; i++) isort[i]=set[setNr].node[i];
  qsort( isort, set[setNr].anz_n, sizeof(int), (void *)compareInt  );

  for (i=0; i<set[setNr].anz_n; i++)
  {
    node2[i].nr = isort[i];
    node2[isort[i]].nx = node[isort[i]].nx;
    node2[isort[i]].ny = node[isort[i]].ny;
    node2[isort[i]].nz = node[isort[i]].nz;
    if (anz2->nmax<node2[i].nr) anz2->nmax = node2[i].nr;
    if (anz2->nmin>node2[i].nr) anz2->nmin = node2[i].nr;
  }

  strcpy( anz2->model, setname);
  strcpy ( prognam, setname);
  anz2->n = set[setNr].anz_n;
  anz2->e = set[setNr].anz_e;
  for (i=0; i<13; i++)
    anz2->etype[i] = anz->etype[i];
  anz2->l = anz->l;
  anz2->u = anz->u;
  anz2->p = anz->p;
  anz2->uheader = anz->uheader;
  anz2->pheader = anz->pheader;

  if(printFlag) printf (" write file \n");

  length= strlen ( setname );
  if (compare( format, "frd", 3) == 3)
  {
    strcpy (&prognam[length], ".frd");
    write2frd( prognam, anz2, node2, elem2, lcase); 
  }
  else if (compare( format, "nas", 3) == 3)
  {
    write2nas( prognam, anz2, node2, elem2, lcase);
  }
  else if (compare( format, "abq", 3) == 3)
  {
    write2aba( prognam, anz2, node2, elem2, lcase, val);
  }
  else if (compare( format, "ans", 3) == 3)
  {
    write2ansys( prognam, anz2, node2, elem2, lcase);
  }
  else if (compare( format, "ast", 3) == 3)
  {
    write2aster( prognam, anz2, node2, elem2, lcase);
  }
  else if (compare( format, "sam", 3) == 3)
  {
    write2samcef( prognam, anz2, node2, elem2, lcase);
  }
  else if (compare( format, "tcg", 3) == 3)
  {
    write2tochnog( prognam, anz2, node2, elem2, lcase);
  }
  else if (compare( format, "stl", 3) == 3)
  {
    strcpy (&prognam[length], ".stl");
    write2stl( prognam, anz2, node2, elem2, lcase);
    strcpy (&prognam[length], ".ned");
    write2netgenEdges( prognam, anz2, node2, elem2, lcase);
  }
  else
      printf (" ERROR: Format not recognized");

  free(node2);
  free(elem2);
  scalNodes ( anz->n, node, scale );
}



void setLightAndMaterial_rgb(int col)
{
  GLfloat mat_shininess[1]; /* 0->128 Blankheit */
  GLfloat mat_specular[4]; /* ungerichtete reflektion*/
  GLfloat mat_diffuse[4];  /* gerichtete reflektion*/

  if(col<0) /* define standard grey */
  {
    mat_shininess[0]= 128.;
    mat_specular[0]=MAT_SPEC;
    mat_specular[1]=MAT_SPEC;
    mat_specular[2]=MAT_SPEC;
    mat_specular[3]=1.0;          

    mat_diffuse[0]=MAT_DIFF;
    mat_diffuse[1]=MAT_DIFF;
    mat_diffuse[2]=MAT_DIFF;
    mat_diffuse[3]=1.0;          
  }
  else
  {
    mat_shininess[0]= 128.;
    mat_specular[0]=MAT_SPEC;
    mat_specular[1]=MAT_SPEC;
    mat_specular[2]=MAT_SPEC;
    mat_specular[3]=1.0;          

    mat_diffuse[0]=entity_r[col];
    mat_diffuse[1]=entity_g[col];
    mat_diffuse[2]=entity_b[col];
    mat_diffuse[3]=1.0;          
  }

  /* Reflexionseigenschaften des Materials aufbringen */
  glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,   mat_diffuse);
  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,  mat_specular);
}



void drawSets(int mode)
{
  int  j;

  for (j=0; j<anzGeo->psets; j++ )
  {
    if (pset[j].type[0]=='n')
    {
      drawNodes_plot( set[pset[j].nr].anz_n, set[pset[j].nr].node, node, pset[j].col, pset[j].type[1] );
    }
    if (pset[j].type[0]=='e')
    {
      if(mode) drawElemNodes_plot( set[pset[j].nr].anz_e, set[pset[j].nr].elem, node, e_enqire, 2, 0 );
      if(elemEdgeFlag) drawElem_edge( set[pset[j].nr].anz_e, set[pset[j].nr].elem, node, e_enqire, basCol[0], pset[j].type[1] );
#if INX_MODE
      if (pset[j].col==-1)
        drawElements_plot( set[pset[j].nr].anz_e, set[pset[j].nr].elem, node, e_enqire, pset[j].col, pset[j].type[1], mode );
      else
        drawElements_plot( set[pset[j].nr].anz_e, set[pset[j].nr].elem, node, e_enqire, pset[j].col, pset[j].type[1], PICK );
#endif
#if TEX_MODE
      setLightAndMaterial_rgb(pset[j].col);
      drawElements_plot( set[pset[j].nr].anz_e, set[pset[j].nr].elem, node, e_enqire, pset[j].col, pset[j].type[1], mode );
#endif
    }
    if (pset[j].type[0]=='f')
    {
      if(mode) drawFaceNodes_plot( set[pset[j].nr].anz_f, set[pset[j].nr].face, node, face, 2, 0 );
      if(elemEdgeFlag) drawFaces_edge( set[pset[j].nr].anz_f, set[pset[j].nr].face, node, face, basCol[0], pset[j].type[1] );
#if INX_MODE
      if (pset[j].col==-1)
        drawFaces_plot( set[pset[j].nr].anz_f, set[pset[j].nr].face, node, face, pset[j].col, pset[j].type[1], mode );
      else
        drawFaces_plot( set[pset[j].nr].anz_f, set[pset[j].nr].face, node, face, pset[j].col, pset[j].type[1], PICK );
#endif
#if TEX_MODE
      setLightAndMaterial_rgb(pset[j].col);
      drawFaces_plot( set[pset[j].nr].anz_f, set[pset[j].nr].face, node, face, pset[j].col, pset[j].type[1], mode );
#endif
    }
    if (pset[j].type[0]=='p')
    {
      drawPoints_plot( set[pset[j].nr].anz_p, set[pset[j].nr].pnt, point, pset[j].col, pset[j].type[1] );
    }
    if (pset[j].type[0]=='l')
    {
      drawLines_plot( set[pset[j].nr].anz_l, set[pset[j].nr].line, line, point, pset[j].col, pset[j].type[1] );
    }
    if (pset[j].type[0]=='s')
    {
      drawSurfs_plot( set[pset[j].nr].anz_s, set[pset[j].nr].surf, surf, lcmb, line, point, pset[j].col, pset[j].type[1] );
    }
    if (pset[j].type[0]=='b')
    {
      drawBodys_plot( set[pset[j].nr].anz_b, set[pset[j].nr].body, body, surf, lcmb, line, point, pset[j].col, pset[j].type[1] );
    }
    if (pset[j].type[0]=='L')
    {
      drawNurl_plot( set[pset[j].nr].anz_nurl, set[pset[j].nr].nurl, pset[j].col, pset[j].type[1], mode );
    }
    if (pset[j].type[0]=='S')
    {
      drawNurs_plot( set[pset[j].nr].anz_nurs, set[pset[j].nr].nurs, pset[j].col, pset[j].type[1], mode );
    }
  }
}

