/* --------------------------------------------------------------------  */
/*                          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.         */
/* --------------------------------------------------------------------  */

/* todo:
- arcs of 180 deg have to be splitted
- mark already used geometric entities (line, circle..)
- b_spline, line have to regard trimming
 */


#include <cgx.h>

#define  INI_PARAM_LENGTH 10 


extern double gtol;
extern Scale     scale[1];
extern Summen    anz[1];

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 Nodes     *node;

extern int       num_onod;          /* nr-of-original-nodes (nodes from input-file) */
extern int       num_olc;
extern SpecialSet specialset[1];
extern int     ddiv;


typedef struct {
  unsigned char name[MAX_LINE_LENGTH];
  unsigned char class_name[MAX_LINE_LENGTH];
  unsigned char **param;
  int nr;
} Step_Object;

int max_indx;



int get_param_in_string( unsigned char *string, unsigned char ***args)
{
  int i=0,j,nr=0,k;
  int parenthesis;
  unsigned char **param;

  param=*args;


  if((param=(unsigned char **)realloc((unsigned char **)param, (1)*sizeof(unsigned char *)))==NULL)
    printf("ERROR: in get_param_in_string\n");
  if((param[0]= (unsigned char *)malloc( INI_PARAM_LENGTH*sizeof(unsigned char))) == NULL )
    printf("ERROR: in get_param_in_string\n");

  /* scip first parenthesis, count open and closed parenthesis, if all closed stop param at next ',' */
  i++; j=0; parenthesis=0; nr=0;
  while(i<strlen(string))
  {
    if(string[i]=='(') parenthesis++;
    if(string[i]==')') parenthesis--;

    /* break if the first open '(' is closed */
    if(parenthesis==-1)
    {
      /* terminate the string */
      param[nr][j]=0;
      nr++; i++; j=0;
      break;
    }

    if((parenthesis==0)&&(string[i]==',')) 
    {
	/* terminate the string */
      param[nr][j]=0;
      nr++; i++; j=0;

      /* alloc the next param */
      if((param=(unsigned char **)realloc((unsigned char **)param, (nr+1)*sizeof(unsigned char *)))==NULL)
        printf("ERROR: in get_param_in_string\n");
      if((param[nr]= (unsigned char *)malloc( INI_PARAM_LENGTH*sizeof(unsigned char))) == NULL )
        printf("ERROR: in get_param_in_string\n");
    }
    else
    {
      /* add char */
      k=strlen(param[nr])+2;
      if(k>INI_PARAM_LENGTH)
        if((param[nr]= (unsigned char *)realloc((unsigned char *)param[nr], (k)*sizeof(unsigned char)))==NULL)
          printf("ERROR: in get_param_in_string\n");
      param[nr][j++]=string[i++];
    }
  }
  /* read until last ')' */

  *args=param;
  return(nr);
}



void parse_step_record(unsigned char *string, Step_Object **ptr_step_object)
{
  int i=0,j=0;
  int indx;
  Step_Object *step_object;

  step_object= *ptr_step_object;

  /* erase all blanks */
  for(i=0; i<strlen(string); i++) { if(string[i]!=' ') string[j++]=string[i]; }
  string[j]=0;

  //printf("string:%s\n", string);

  /* if 1st char # then 1st arg will be the index (and name) of the command and the second arg is the class of the command */
  if(string[0]=='#') 
  {
    /* index in the step_object array */
    indx=atoi(&string[1]);
    if(indx > max_indx) max_indx=indx;



    /* add a new member to ptr_step_object */
    if((step_object = (Step_Object *)realloc( (Step_Object *)step_object, (max_indx+1) * sizeof(Step_Object))) == NULL )
      printf("ERROR: in parse_step_record\n");

    i=0; j=0;
    while(i<strlen(string))
    {
      if(string[i]!='=') step_object[indx].name[j++]=string[i++];
      else break;
    }
    step_object[indx].name[j]=0;

    i++; j=0;
    while(i<strlen(string))
    {
      if(string[i]!='(') step_object[indx].class_name[j++]=string[i++];
      else break;
    }
    step_object[indx].class_name[j]=0;

    i++;
    step_object[indx].nr=get_param_in_string(&string[i], &step_object[indx].param);
  }

  *ptr_step_object = step_object;
}



void make_point(Step_Object *step_object)
{
  unsigned char buffer[MAX_LINE_LENGTH];
  double px,py,pz;

  /* make pnt based on name and point coordinates */
  sscanf(step_object->param[1],"(%lf,%lf,%lf",&px,&py,&pz);
  sprintf( buffer, "%s %lf %lf %lf",step_object->name,px,py,pz);
  pre_pnt( buffer, 0 );

  /* look if a label (setname) was specified */
  if (step_object->param[0][1]!='\'')
  {
    strcpy(buffer,step_object->param[0]);
    buffer[0]='S'; buffer[(int)strlen(buffer)-1]=(unsigned char)NULL;
    pre_seta( buffer, "p", step_object->name);
  }
}



void make_line(Step_Object *step_object, int indx_trim)
{
  unsigned char buffer[MAX_LINE_LENGTH];
  int indx_l, indx_p1, indx_v, indx_dir;
  double vl,p1[3],p2[3],dir[3],vec[3];


  indx_l=atoi(&step_object[indx_trim].param[1][1]);

  /* line needs point, second point, generated out of direction and vector */
  indx_p1=atoi(&step_object[indx_l].param[1][1]);
  indx_v=atoi(&step_object[indx_l].param[2][1]);

  /* indx of dir based on vector */
  indx_dir=atoi(&step_object[indx_v].param[1][1]);

  /* length of vector */
  vl=atof(step_object[indx_v].param[2]);

  /* make pnt based on name and direction coordinates and vector length*/
  sscanf(step_object[indx_dir].param[1],"(%lf,%lf,%lf",&dir[0],&dir[1],&dir[2]);
  v_scal(&vl,dir,vec);
  sscanf(step_object[indx_p1].param[1],"(%lf,%lf,%lf",&p1[0],&p1[1],&p1[2]);
  v_add(p1,vec,p2);

  sprintf( buffer, "%s %lf %lf %lf",step_object[indx_v].name,p2[0],p2[1],p2[2]);
  pre_pnt( buffer, 0 );

  /* make line */
  sprintf( buffer, "%s %s %s",step_object[indx_l].name,step_object[indx_p1].name,step_object[indx_v].name);
  pre_line( buffer, 0 );

  /* look if a label (setname) was specified */
  if (step_object[indx_l].param[0][1]!='\'')
  {
    strcpy(buffer,step_object[indx_l].param[0]);
    buffer[0]='S'; buffer[strlen(buffer)-1]=(unsigned char)NULL;
    pre_seta( buffer, "l", step_object[indx_l].name);
  }
}



void make_circle(Step_Object *step_object, int indx_trim)
{
  int       i, lnr, lnr_new[2];
  unsigned char buffer[MAX_LINE_LENGTH], pmid_name[MAX_LINE_LENGTH];
  int indx_l, indx_pc, indx_ax, indx_dir1, indx_dir2;
  double Rl,pc[3],p1[3],p2[3],dir1[3],dir2[3], parm1, parm2,fi1,fi2,fi_mid;
  double pmid[3],pbuf[3],vbuf[3];

  indx_l=atoi(&step_object[indx_trim].param[1][1]);


  /* circle uses AXIS2_PLACEMENT_3D which specifies cener_p(CARTESIAN_POINT), rot-axis(DIRECTION), start-dir(DIRECTION) and the 2angles by TRIMMED_CURVE */
  parm1=atof(&step_object[indx_trim].param[2][17]);
  parm2=atof(&step_object[indx_trim].param[3][17]);

  /* get cp and dirs from AXIS2_PLACEMENT_3D */
  indx_ax=atoi(&step_object[indx_l].param[1][1]);
  indx_pc=atoi(&step_object[indx_ax].param[1][1]);
  indx_dir1=atoi(&step_object[indx_ax].param[2][1]);
  indx_dir2=atoi(&step_object[indx_ax].param[3][1]);

  /* Radius Rl */
  Rl=atof(step_object[indx_l].param[2]);
  sscanf(step_object[indx_pc].param[1],"(%lf,%lf,%lf",&pc[0],&pc[1],&pc[2]);

  /* make pnt pbuf based on direction coordinates and Radius */
  sscanf(step_object[indx_dir1].param[1],"(%lf,%lf,%lf",&dir1[0],&dir1[1],&dir1[2]);
  sscanf(step_object[indx_dir2].param[1],"(%lf,%lf,%lf",&dir2[0],&dir2[1],&dir2[2]);

  /* calc pnts */
  v_scal(&Rl,dir2,vbuf);
  v_add(pc,vbuf,pbuf);

  /* rotate pbuf by angle1 and make p1 */
  if(parm1!=0.)
  {
    fi1=(parm1)*PI/180.;
    v_rot(fi1,pc,dir1,pbuf,p1);
  }
  else { for(i=0; i<3; i++) p1[i]=pbuf[i]; }
  sprintf( buffer, "%s %lf %lf %lf",step_object[indx_dir1].name,p1[0],p1[1],p1[2]);
  pre_pnt( buffer, 0 );

  /* rotate pbuf by angle1 and make p2 */
  if(parm2!=0.)
  {
    fi2=(parm2)*PI/180.;
    v_rot(fi2,pc,dir1,pbuf,p2);
  }
  else { for(i=0; i<3; i++) p2[i]=pbuf[i]; }
  sprintf( buffer, "%s %lf %lf %lf",step_object[indx_dir2].name,p2[0],p2[1],p2[2]);
  pre_pnt( buffer, 0 );

  /* make line */
  sprintf( buffer, "%s %s %s %s",step_object[indx_l].name,step_object[indx_dir1].name,step_object[indx_dir2].name,step_object[indx_pc].name);
  pre_line( buffer, 0 );

  if (parm2<parm1) parm2+=360.;
  if(fabs(parm2-parm1)>=180.)
  {
    printf("fi:fabs(parm1-parm2):%f:%f:%f deg:%s\n",parm1, parm2, fabs(parm2-parm1),step_object[indx_l].name);
    /* if an arc has 180 or more degrees create 2 lines and create a lcmb with the step-line-name */

    /* rotate pbuf by angle and make pmid */
    fi_mid=(parm1+(parm2-parm1)/2.)*PI/180.;
    v_rot(fi_mid,pc,dir1,pbuf,pmid);

    getNewName( pmid_name, "p" );
    i=pnt( pmid_name, pmid[0], pmid[1], pmid[2], 1 );
    lnr=getLineNr( step_object[indx_l].name );
    splitLine(lnr, &lnr_new, i, 0.5);
    /* automatic calculated div is wrong because it does not work for arcs of 180deg */
    line[lnr_new[0]].div=line[lnr_new[1]].div=ddiv;

    /* create lcmb with the basis line name */
    sprintf( buffer, "%s + %s + %s",step_object[indx_l].name,line[lnr_new[0]].name,line[lnr_new[1]].name);
    pre_lcmb( buffer, 0 );

    /* del basis line */
    delLine( 1, &lnr );    
  }
}



void make_ellipse(Step_Object *step_object, int indx_trim)
{
  /* assumption: dir2 is in direction of Rl1 (big axis) */
  /* r(fi) of the ellipse is determined by interpolating between ra and rb as a function of fi (0-360 deg) */

  int       i;
  unsigned char buffer[MAX_LINE_LENGTH];
  int indx_l, indx_pc, indx_ax, indx_dir1, indx_dir2;
  double Rl1,Rl2,pc[3],p1[3],p2[3],dir1[3],dir2[3], parm1, parm2,fi1,fi2;
  double pbuf[3],vbuf[3],fac;
  double pbufa[3];
  double pbufb[3];
  double pa[3],pb[3],vba[3];

  int mode=1;
  int el_n=5;
  double el_fi[]={0.,90.,180.,270.,360};
  double el_fac[]={1.,0.,1.,0.,1.};

  indx_l=atoi(&step_object[indx_trim].param[1][1]);


  /* circle uses AXIS2_PLACEMENT_3D which specifies cener_p(CARTESIAN_POINT), rot-axis(DIRECTION), start-dir(DIRECTION) and the 2angles by TRIMMED_CURVE */
  parm1=atof(&step_object[indx_trim].param[2][17]);
  parm2=atof(&step_object[indx_trim].param[3][17]);

  /* get cp and dirs from AXIS2_PLACEMENT_3D */
  indx_ax=atoi(&step_object[indx_l].param[1][1]);
  indx_pc=atoi(&step_object[indx_ax].param[1][1]);
  indx_dir1=atoi(&step_object[indx_ax].param[2][1]);
  indx_dir2=atoi(&step_object[indx_ax].param[3][1]);

  /* Radius Rl */
  Rl1=atof(step_object[indx_l].param[2]);
  Rl2=atof(step_object[indx_l].param[3]);
  sscanf(step_object[indx_pc].param[1],"(%lf,%lf,%lf",&pc[0],&pc[1],&pc[2]);

  /* make pnt pbuf based on direction coordinates and Radius */
  sscanf(step_object[indx_dir1].param[1],"(%lf,%lf,%lf",&dir1[0],&dir1[1],&dir1[2]);
  sscanf(step_object[indx_dir2].param[1],"(%lf,%lf,%lf",&dir2[0],&dir2[1],&dir2[2]);

  /* calc pnts */
  v_scal(&Rl1,dir2,vbuf);
  v_add(pc,vbuf,pbufa);

  v_scal(&Rl2,dir2,vbuf);
  v_add(pc,vbuf,pbufb);

  /* rotate pbuf by angle1 and make pa */
  if(parm1!=0.)
  {
    fi1=(parm1)*PI/180.;
    v_rot(fi1,pc,dir1,pbufa,pa);
  }
  else { for(i=0; i<3; i++) pa[i]=pbuf[i]; }

  /* rotate pbuf by angle1 and make pb */
  if(parm1!=0.)
  {
    fi1=(parm1)*PI/180.;
    v_rot(fi1,pc,dir1,pbufb,pb);
  }
  else { for(i=0; i<3; i++) pb[i]=pbuf[i]; }

  v_result(pb,pa,vba);

  /* interpolate p1 between pa and pb, this has to be replaced by a more accurate method */
  fac = intpol3( el_fi, el_fac, el_n, parm1, &mode );
  v_scal(&fac,vba,vbuf);
  v_add(pb,vbuf,p1);

  sprintf( buffer, "%s %lf %lf %lf",step_object[indx_dir1].name,p1[0],p1[1],p1[2]);
  pre_pnt( buffer, 0 );

  /* rotate pbuf by angle2 and make pa */
  if(parm2!=0.)
  {
    fi2=(parm2)*PI/180.;
    v_rot(fi2,pc,dir1,pbufa,pa);
  }
  else { for(i=0; i<3; i++) pa[i]=pbuf[i]; }

  /* rotate pbuf by angle2 and make pb */
  if(parm2!=0.)
  {
    fi2=(parm2)*PI/180.;
    v_rot(fi2,pc,dir1,pbufb,pb);
  }
  else { for(i=0; i<3; i++) pb[i]=pbuf[i]; }

  v_result(pb,pa,vba);

  /* interpolate p2 between pa and pb, this has to be replaced by a more accurate method */
  fac = intpol3( el_fi, el_fac, el_n, parm2, &mode );
  v_scal(&fac,vba,vbuf);
  v_add(pb,vbuf,p2);

  sprintf( buffer, "%s %lf %lf %lf",step_object[indx_dir2].name,p2[0],p2[1],p2[2]);
  pre_pnt( buffer, 0 );

  /* make line */
  sprintf( buffer, "%s %s %s %s",step_object[indx_l].name,step_object[indx_dir1].name,step_object[indx_dir2].name,step_object[indx_pc].name);
  pre_line( buffer, 0 );
}


void make_trimmed_curve(Step_Object *step_object, int indx_trim)
{
  unsigned char buffer[MAX_LINE_LENGTH];
  int indx_l;

  indx_l=atoi(&step_object[indx_trim].param[1][1]);

  if (compareStrings(step_object[indx_l].class_name, "CIRCLE")>0)   make_circle(step_object, indx_trim);
  else if (compareStrings(step_object[indx_l].class_name, "ELLIPSE")>0)   make_ellipse(step_object, indx_trim);
  else if(compareStrings(step_object[indx_l].class_name, "LINE")>0) make_line(step_object, indx_trim);
  else
    printf("not known trimmed_curve-type:%s for index_trim:%d\n",step_object[indx_l].class_name, indx_trim);


  /* look if a label (setname) was specified */
  if (step_object[indx_trim].param[0][1]!='\'')
  {
    strcpy(buffer,step_object[indx_trim].param[0]);
    buffer[0]='S'; buffer[strlen(buffer)-1]=(unsigned char)NULL;
    pre_seta( buffer, "l", step_object[indx_trim].name);
  }
}


void make_b_spline_curve_with_knots(Step_Object *step_object, int indx)
{
  int       i,j,k;
  unsigned char buffer[MAX_LINE_LENGTH], **args=NULL;
  int deg, npnt=0, nknt=0, div=99, *cpnt=NULL, *knt_i=NULL, nknt_t=0;
  double *knt_v=NULL;

  /* determine degree */
  deg=atoi(step_object[indx].param[1]);

  /* determine controll-points */
  npnt=get_param_in_string(step_object[indx].param[2], &args);

  /* get the controll-points from args */
  if((cpnt = (int *)malloc( (npnt+1) * sizeof(int))) == NULL )
    printf("ERROR: in make_b_spline_curve_with_knots\n");
  for (i=0; i<npnt; i++) cpnt[i]=atoi(&args[i][1]);

  /* determine knots */
  nknt=get_param_in_string(step_object[indx].param[6], &args);

  /* get the knt-indx from args */
  if((knt_i = (int *)malloc( (nknt+1) * sizeof(int))) == NULL )
    printf("ERROR: in make_b_spline_curve_with_knots\n");
  for (i=0; i<nknt; i++) knt_i[i]=atoi(&args[i][0]);

  /* get knot-values */
  nknt=get_param_in_string(step_object[indx].param[7], &args);

  /* get the knt-values from args */
  if((knt_v = (double *)malloc( (nknt+1) * sizeof(double))) == NULL )
    printf("ERROR: in make_b_spline_curve_with_knots\n");
  for (i=0; i<nknt; i++) knt_v[i]=atof(args[i]);

  /* total nr-of-nkots= sum( knt_i) */
  for(i=0; i<nknt; i++) nknt_t+=knt_i[i];

  sprintf(buffer,"%s DEFINE FULL #%d #%d %d %d %d %d\n"
  , step_object[indx].name, cpnt[0], cpnt[npnt-1], deg, npnt, nknt_t, div);
  nurl( buffer, 0 );

  for (i=0; i<npnt; i++)
  {
    sprintf(buffer,"%s CONTROL %d #%d 1.\n"
    , step_object[indx].name, i+1, cpnt[i]);
    nurl( buffer, 0 );
  }

  k=1;
  for (i=0; i<nknt; i++)
  {
    for(j=0; j<knt_i[i]; j++)
    {
      sprintf(buffer,"%s KNOT %d %lf\n"
      , step_object[indx].name, k++, knt_v[i] );
      nurl( buffer, 0 );
    }
  }

  sprintf(buffer,"%s END\n", step_object[indx].name);
  nurl( buffer, 0 );
}



void readstep( unsigned char *datin, int addFlag )
{
  FILE      *handle1;
  int       length, i,j, terminated=0, eof=0, gtolFlag=0;
  unsigned char *string=NULL;
  unsigned char string1[MAX_LINE_LENGTH];
  double max[3], min[3];

  Step_Object *step_object=NULL;

  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 (1)
  {
    do {
      length=frecord( handle1, string1);
      if (string1[length] == (unsigned char)EOF) eof=1;

      /* a step-record is terminated by a ';'. If it can not be found then read the next record an add it */
      for (i=strlen(string1); i>=0; i--) if(string1[i]==';') terminated=1;
      if (!terminated) string1[length]=0;

      if(string==NULL)
      {
        if((string=(unsigned char *)malloc((strlen(string1)+2)*sizeof(unsigned char)))==NULL)
          printf("ERROR: in readstep\n");
        string[0]=0;
        strcpy(string,string1);
      }
      else
      {
        if((string=(unsigned char *)realloc((unsigned char *)string, (strlen(string)+strlen(string1)+2)*sizeof(unsigned char)))==NULL)
           printf("ERROR: in readstep\n");
        strcpy(&string[strlen(string)],string1);
      }
      if(eof) terminated=1;
    }while(!terminated);

    terminated=0;

    /* parse record, get class and parameters */
    if(string[0]) parse_step_record(string, &step_object);
    string[0]=0;
    if (eof) break;
  }
  printf ("\n finished file\n");

  /* check objects */
  /*
  for(j=1; j<max_indx; j++)
  {
    printf("%s %s",step_object[j].name,step_object[j].class_name);
    for (i=0; i<step_object[j].nr; i++) printf(" %s",step_object[j].param[i]);
    printf("\n");
  }
  */

  /* generate cgx-objects from step_objects */
  for(j=1; j<max_indx; j++) if (compareStrings(step_object[j].class_name, "CARTESIAN_POINT")>0) make_point(&step_object[j]);
  for(j=1; j<max_indx; j++) if (compareStrings(step_object[j].class_name, "TRIMMED_CURVE")>0) make_trimmed_curve(step_object, j);
  for(j=1; j<max_indx; j++) if (compareStrings(step_object[j].class_name, "B_SPLINE_CURVE_WITH_KNOTS")>0) make_b_spline_curve_with_knots(step_object, j);


  /* scal the work-space */
  if(!gtolFlag)
  {
    for(i=0; i<3; i++)
    {
      max[i]=-MAXVALUE;
      min[i]= MAXVALUE;
    }
    /* calculate the geometric tolerance based on all points */
    for(i=0; i<anzGeo->p; i++) if(point[i].name!=(unsigned char *)NULL)
    {
      if(point[i].px > max[0]) max[0]=point[i].px;
      if(point[i].py > max[1]) max[1]=point[i].py;
      if(point[i].pz > max[2]) max[2]=point[i].pz;
      if(point[i].px < min[0]) min[0]=point[i].px;
      if(point[i].py < min[1]) min[1]=point[i].py;
      if(point[i].pz < min[2]) min[2]=point[i].pz;
    }
    /* calculate the geometric tolerance based on all line-end-points */
    /*
    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");
}

