1 /* --------------------------------------------------------------------  */
2 /*                          CALCULIX                                     */
3 /*                   - GRAPHICAL INTERFACE -                             */
4 /*                                                                       */
5 /*     A 3-dimensional pre- and post-processor for finite elements       */
6 /*              Copyright (C) 1996 Klaus Wittig                          */
7 /*                                                                       */
8 /*     This program is free software; you can redistribute it and/or     */
9 /*     modify it under the terms of the GNU General Public License as    */
10 /*     published by the Free Software Foundation; version 2 of           */
11 /*     the License.                                                      */
12 /*                                                                       */
13 /*     This program is distributed in the hope that it will be useful,   */
14 /*     but WITHOUT ANY WARRANTY; without even the implied warranty of    */
15 /*     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the      */
16 /*     GNU General Public License for more details.                      */
17 /*                                                                       */
18 /*     You should have received a copy of the GNU General Public License */
19 /*     along with this program; if not, write to the Free Software       */
20 /*     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.         */
21 /* --------------------------------------------------------------------  */
22 
23 
24 /*
25 TO DO:
26 - replace line_ with line_i in qsplitLine() and delete line_() in defineEntity and rename line_i to line_ in all functions.
27 - extend hitUndo()
28 
29 - not finalized:
30       qmshOperator=0;
31 */
32 
33 
34 #define     TEST            0    /* debugging */
35 
36 #include <cgx.h>
37 
38 #define DPICK_BUFFER 10000
39 #define MAX_BUF      100
40 
41 extern int   width_ini, height_ini;            /* Grafik-Fensterbreite/hoehe */
42 extern int   width_menu, height_menu;
43 extern int   w0, w1, activWindow;
44 extern int   width_w0, height_w0;
45 extern int   width_w1, height_w1;
46 extern int   MouseMode;                                   /* status maustasten */
47 extern double dtx, dty, drx, dry, drz, ds;                 /* Verschiebungen */
48 extern GLdouble R[4][4];                                   /* Rotationsmatrix */
49 extern char  surfFlag;                /* zeichne nur Oberflaechenelemente (1), sonst (0)*/
50 extern char  modelEdgeFlag;           /* zeichne mit Modell-Ecken (1), sonst (0)*/
51 extern char  drawMode;                /* protokoliert drawFunktion (drawLoad,Light,Animate,set)*/
52 extern char  frameFlag;               /* mit (1) oder ohne Rahmen um das Grafikfenster */
53 extern char  pickFlag;
54 extern char  graphFlag;
55 extern char  sequenceFlag;                  /* 1: play a sequence of LC */
56 extern char  vectorFlag;
57 extern double dx ,dy;                  /* Mauskoordinaten */
58 extern double centerPnt[3];            /* Rotationszentrum */
59 extern int   centerNode;            /* Nr of center Node, 0:no centernode */
60 extern double     gtol;                                    /* geometry tolerance for merging */
61 extern int     ddiv;
62 extern int   animList;
63 extern int   lcase_animList;
64 extern double   aspectRatio_w1;         /* width_w1/height_w1 */
65 
66 extern Scale     scale[1];
67 extern Summen    anz[1];
68 extern Nodes     *node;
69 extern Elements  *e_enqire;
70 
71 extern Datasets *lcase;
72 extern Faces     *face;
73 extern Texts     *ntext;
74 
75 extern Alias     *alias;
76 extern Sets      *set;
77 extern Shapes    *shape;
78 extern Psets     *pset;
79 extern Points    *point;
80 extern Lines     *line;
81 extern Lcmb      *lcmb;
82 extern Gsur      *surf;
83 extern Gbod      *body;
84 extern Nurbl     *nurbl;
85 extern Nurbs     *nurbs;
86 extern SumGeo    anzGeo[1];
87 extern SumAsci   sumAsci[1];
88 extern double     *colNr;
89 
90 extern char  datin[MAX_LINE_LENGTH];                          /* Input-data-file */
91 
92 /* global variables for picking */
93 extern char pickfunc[MAX_LINE_LENGTH];  /* pickfunc either "qenq" "qadd" "qrem" ..  */
94 char hidefunc[MAX_LINE_LENGTH];         /* hidefunc stores the original commando if a qfunction was started inside another qfunction  */
95 extern char mode[2];                    /* pickmode */
96 char hidemode[2];                       /* hidemode stores the original pickmode */
97 extern GLdouble dx_cur, dy_cur;         /* pick-cursor Area */
98 extern double backgrndcol_rgb[4];
99 extern char    buffer[MAX_LINE_LENGTH];        /* common string-buffer */
100 extern char  printFlag;                     /* printf 1:on 0:off */
101 extern int  cur_entity;                                       /* aktive entity (component) */
102 extern char  v_dim;                         /* 1: scalar plot, 2: a 2D vector plot, 3: a 3D vectorplot, 4: a 3D vectorplot with signed vals */
103 extern int   entity_v[6];                                         /* components of a vector-entity */
104 extern int  cur_lc;
105 extern char  addDispFlag;                    /* 0: original node-coordinates, 1: node-coordinates+displacements */
106 
107 extern double v[4];                                        /* drehkorrekturen fuer centerPkt */
108 extern GLdouble dR[4][4];                                  /* dR= R-Rmem fuer center */
109 extern GLdouble Rmem[4][4];
110 extern double dtx, dty, dtz;
111 
112 int anz_threads=1;
113 int qmshOperator=0;                     /* operator for qdiv in qmsh 0|'*'|'/' */
114 int qbiaFlag=0;                         /* for qmsh, 1:switch from qlin to qbia */
115 int qdisFlag=0;                         /* for qdis */
116 int intersectFlag=0;                    /* for qint, qfill */
117 double qaddTol=-1;                      /* for qadd, angle tolerance for set completition of adjacent faces */
118 double filletRadius=-1;                 /* for qfill */
119 int    shp_pindx=0;                     /* for qshp */
120 
121 
122 static GLint hits;                             /* number of picked items, must be global because of glutKeyboardFunc(defineDiv) */
123 GLuint *selectBuf=NULL;                 /* buffer which holds the picked items, must be global because of glutKeyboardFunc(defineDiv) */
124 extern SpecialSet specialset[1];
125 extern int       setall;                /* setNr of the default set "all" */
126 
127 int     pick_zmin;                      /* kleinster z-wert der gepickten items */
128 int     setNrbuf;                       /* buffer for pick() */
129 int     setNrdiv=-1;                    /* subset of buffer for qmsh(), stores only directly selected lines for defineDiv() */
130 int     qmshbuf;                         /* additional entity buffer for qmsh in pick() */
131 int    *pickdata;                       /* Zwischenspeicher fuer pickdaten */
132 double    pickbuf;                      /* kurzzeitbuffer */
133 int     pick_buffer;                    /* groesse von pickdata */
134 int     qnorCounter=0;                  /* counts number of selected points for qnor() */
135 int     qcutCounter=0;                  /* counts number of selected nodes for qcut() */
136 int     qaliCounter=0;                  /* counts number of selected nodes for qali() */
137 int     xbuf, ybuf;                     /* mauskoordinaten */
138 int     *selem=NULL;                    /* buffer for qflp, points to surfs */
139 int     entitybuf=-1;                   /* saves the index of the last created entity for undo */
140 char    keybuf=0;                       /* saves the type of the last selection */
141 int     set_highl=-1;                   /* set which stores actual entity */
142 int     setNr=-1;                       /* selected set */
143 int     pntNr=-1;                       /* selected point */
144 int     lineNr=-1;                      /* selected line */
145 int     surfNr=-1;                      /* selected surf, surface as a target for the point-projection */
146 int     nurbsNr=-1;                     /* selected Nurbs, used for all touched surfs (s,g) */
147 int     shapeNr=-1;                     /* selected Shape, used for all touched surfs (s,g) */
148 int     bodyNr=-1;                      /* selected body */
149 
150 /* values for movePoint() */
151 int movedp=-1, pntnr=-1, pnt_undo=-1, moveFlag=0;
152 
153 #define MAX_LINES 100
154 int qspl_i, qspl_indx[MAX_LINES]; /* buffer for already splitted lines (qspl) */
155 GLuint GLubuf[2];
156 
157 /* qcut, cut */
158 #define CUTS 20
159 typedef struct {
160   int anz_n;
161   double npre[CUTS][6];
162   int nnew[CUTS];
163 } CutParam;
164 extern Qcut_nodes *qcut_nod;
165 
166 /* the copied node-sets which have to be filled with values from new loaded Datasets */
167 extern CopiedNodeSets copiedNodeSets[1];
168 
169 /* shape buffer */
170 Shapes shapebuf;
171 
172 /* threading */
173 int            glob_cutElement=0;
174 sem_t   sem_cute;
175 extern sem_t   sem_n;
176 
177 
hitAction(GLuint * name,char * type,int x,int y)178 int hitAction( GLuint *name, char *type, int x, int y )
179 {
180   /* name[0]== entity type of picked name   */
181   /* name[1]== picked name(Nr)  */
182   /* type[0] == requested entity type */
183   /* type[1] == often gkey in pick() */
184 
185   char buf[MAX_LINE_LENGTH], printbuf[MAX_LINE_LENGTH];
186   int i,j,k,p,l;
187   int bias_fbd, index;
188   static int p_qnor[3], cpFlag=0, shFlag=0;
189   static double v_qdis[4][3], v_val;
190   double v0[3], v1[3], da,dax,day,daz, r1,r2,rm,lcir, dist;
191   int matchFlag, lin[2]={0,0};
192 
193   /* highlight the entity if its not qdel or qrem ,qtxt */
194   if((compare(pickfunc, "qdel", 4) != 4)&&(compare(pickfunc, "qrem", 4) != 4)&&(compare(pickfunc, "qtxt", 4) != 4))
195   {
196     buf[0]=name[0];
197     buf[1]='\0';
198     seta(set_highl, buf, name[1] );
199   }
200 
201   //printf("type %c %c\n", type[0],type[1]);
202 
203   entitybuf=name[1];
204   keybuf=name[0];
205 
206   if (name[0] == 'e')
207   {
208     printf ("%d t:%d n: ", name[1], e_enqire[name[1]].type);
209     if(e_enqire[name[1]].type==1) k=8;
210     else if(e_enqire[name[1]].type==2) k=6;
211     else if(e_enqire[name[1]].type==3) k=4;
212     else if(e_enqire[name[1]].type==4) k=20;
213     else if(e_enqire[name[1]].type==5) k=15;
214     else if(e_enqire[name[1]].type==6) k=10;
215     else if(e_enqire[name[1]].type==7) k=3;
216     else if(e_enqire[name[1]].type==8) k=6;
217     else if(e_enqire[name[1]].type==9) k=4;
218     else if(e_enqire[name[1]].type==10) k=8;
219     else if(e_enqire[name[1]].type==11) k=2;
220     else if(e_enqire[name[1]].type==12) k=3;
221     else k=0;
222     for (j=0; j<k; j++) printf("%d ",e_enqire[name[1]].nod[j]);
223     printf("\n");
224     if (compare(pickfunc, "qenq", 4) == 4)
225     {
226       sprintf(printbuf, "    in set=");
227       index=2;
228       for(i=1; i<anz->sets; i++)
229         if(!set[i].type)
230         {
231           set[i].index=index++;
232           if((set[i].name!=(char *)NULL)&&(set[i].name[0]!='-')&&( getIndex(&set[i].elem,set[i].anz_e,name[1]) >-1))
233             sprintf(&printbuf[strlen(printbuf)],"%s(%d),",set[i].name,set[i].index);
234         }
235       sprintf(&printbuf[strlen(printbuf)],"\n"); if(strlen(printbuf)>12) printf("%s", printbuf);
236     }
237     else if (compare(pickfunc, "qdel", 4) == 4) seta( setNrbuf, type, name[1]);
238     else if (compare(pickfunc, "qadd", 4) == 4) seta( setNrbuf, type, name[1]);
239     else if (compare(pickfunc, "qmsh", 4) == 4) seta( setNrbuf, type, name[1]);
240     else if (compare(pickfunc, "qrem", 4) == 4) setr( setNrbuf, type, name[1]);
241     else if (compare(pickfunc, "qflp", 4) == 4) flip( type, name[1]);
242   }
243   else if (name[0] == 'f')
244   {
245     printf ("%d e:%d s:%d n= ", name[1], face[name[1]].elem_nr, face[name[1]].nr+1 );
246       if(face[name[1]].type==7) k=3;
247       else if(face[name[1]].type==8) k=6;
248       else if(face[name[1]].type==9) k=4;
249       else if(face[name[1]].type==10) k=8;
250       else if(face[name[1]].type==11) k=2;
251       else if(face[name[1]].type==12) k=3;
252       else k=0;
253       for (j=0; j<k; j++) printf("%d ",face[name[1]].nod[j]);
254       printf("\n");
255     if (compare(pickfunc, "qenq", 4) == 4)
256     {
257       sprintf(printbuf, "    in set=");
258       index=2;
259       for(i=1; i<anz->sets; i++)
260         if(!set[i].type)
261         {
262           set[i].index=index++;
263           if((set[i].name!=(char *)NULL)&&(set[i].name[0]!='-')&&( getIndex(&set[i].face,set[i].anz_f,name[1]) >-1))
264           {
265             sprintf(&printbuf[strlen(printbuf)],"%s(%d)",set[i].name,set[i].index);
266 
267             /* is a contact surface referenced ? */
268             if(set[i].anz_se)
269             {
270               sprintf(&printbuf[strlen(printbuf)],"->[ ");
271               for(j=0; j<set[i].anz_se; j++)
272                 sprintf(&printbuf[strlen(printbuf)],"%s(%d) ",set[set[i].set[j]].name,set[set[i].set[j]].index);
273               sprintf(&printbuf[strlen(printbuf)],"]");
274             }
275             sprintf(&printbuf[strlen(printbuf)],",");
276           }
277         }
278       sprintf(&printbuf[strlen(printbuf)],"\n"); if(strlen(printbuf)>12) printf("%s", printbuf);
279     }
280     else if (compare(pickfunc, "qdel", 4) == 4) seta( setNrbuf, type, name[1]);
281     else if (compare(pickfunc, "qadd", 4) == 4) seta( setNrbuf, type, name[1]);
282     else if (compare(pickfunc, "qrem", 4) == 4) setr( setNrbuf, type, name[1]);
283     else if (compare(pickfunc, "qdis", 4) == 4)
284     {
285       delSet(specialset->impc);
286       setNrbuf=pre_seta( specialset->impc, "i", 0);
287       if(setNrbuf<0) { errMsg(" ERROR: could not create set for qdis\n"); return(0); }
288       seta( setNrbuf, type, name[1]);
289 
290       /* complete the set by all connected faces which do not violate the tolerance */
291       qaddTol=QADDTOL;
292       completeFacesByTolerance(set_highl, setNrbuf, qaddTol);
293     }
294   }
295   else if (name[0] == 'h')
296   {
297     printf ("%s p1=%s p2=%s p3=%s\n", shape[name[1]].name, point[shape[name[1]].p[0]].name, point[shape[name[1]].p[1]].name, point[shape[name[1]].p[2]].name );
298     if (compare(pickfunc, "qenq", 4) == 4)
299     {
300       sprintf(printbuf, "    in set=");
301       index=2;
302       for(i=1; i<anz->sets; i++)
303         if(!set[i].type)
304         {
305           set[i].index=index++;
306           if((set[i].name!=(char *)NULL)&&(set[i].name[0]!='-')&&( getIndex(&set[i].shp,set[i].anz_sh,name[1]) >-1))
307             sprintf(&printbuf[strlen(printbuf)],"%s(%d),",set[i].name,set[i].index);
308         }
309       sprintf(&printbuf[strlen(printbuf)],"\n"); if(strlen(printbuf)>12) printf("%s", printbuf);
310     }
311     else if (compare(pickfunc, "qdel", 4) == 4) seta( setNrbuf, type, name[1]);
312     else if (compare(pickfunc, "qadd", 4) == 4) seta( setNrbuf, type, name[1]);
313     else if (compare(pickfunc, "qrem", 4) == 4) setr( setNrbuf, type, name[1]);
314     else if (compare(pickfunc, "qsur", 4) == 4)
315     {
316       /* if a a default surf is known apply the shape */
317       if(surfNr>-1)
318       {
319         surf[surfNr].sh=name[1];
320         shape_refSurf(surf[surfNr].sh, surfNr);
321 
322 	/* if it was prepared for illumination, change the interior def of the selected surf */
323         if(surf[surfNr].pgn!=NULL)
324 	{
325           free(surf[surfNr].pgn); surf[surfNr].pgn=NULL; surf[surfNr].npgn=0;
326 
327           /* create the interior */
328           repSurf(surfNr,1);
329 	}
330         printf(" Interiour of surf:%s changed to shape:%s\n", surf[surfNr].name, shape[name[1]].name);
331       }
332       else
333       {
334 	printf(" Active Shape:%s\n", shape[name[1]].name);
335         shapeNr=name[1];
336       }
337     }
338     else if (compare(pickfunc, "qshp", 4) == 4)
339     {
340 	printf(" Active Shape:%s\n", shape[name[1]].name);
341         shapeNr=name[1];
342         nurbsNr=-1;
343     }
344   }
345   else if (name[0] == 't')
346   {
347     if(type[1]=='d') ntext[name[1]].node_nr=0;
348     if(type[1]=='p') moveText(name[1], x, y);
349     if(type[1]=='b') { ntext[name[1]].tx= -1; }
350     if(type[1]=='n') { ntext[name[1]].nFlag=!ntext[name[1]].nFlag; }
351     if(type[1]=='v') { ntext[name[1]].vFlag=!ntext[name[1]].vFlag; }
352     if(type[1]=='t') { ntext[name[1]].tFlag=!ntext[name[1]].tFlag; }
353     if(type[1]=='s') { ntext[name[1]].pFlag=!ntext[name[1]].pFlag; }
354     if(type[1]=='f')
355     {
356       ntext[name[1]].fFlag++;
357       if(ntext[name[1]].fFlag>2) ntext[name[1]].fFlag=0;
358     }
359   }
360   else if ((name[0] == 'n')&& (node[name[1]].pflag!=1))
361   {
362     if(!anz->l) printf ("%d xyz= %lf %lf %lf\n", name[1],
363       (node[name[1]].nx* scale->w+scale->x),
364       (node[name[1]].ny* scale->w+scale->y),
365       (node[name[1]].nz* scale->w+scale->z) );
366     else
367     {
368       if(sequenceFlag) rm=lcase[lcase_animList].dat[animList][name[1]];
369       else rm=lcase[cur_lc].dat[cur_entity][name[1]];
370 
371       printf ("%d v= %e ", name[1], rm);
372       /* search linked values (iexist=2) */
373       if(sequenceFlag)
374       {
375         for(i=0; i<lcase[lcase_animList].ncomps; i++)
376           if((i!=animList)&&(lcase[lcase_animList].iexist[i]==2)) printf ("%s:%5.4e ",lcase[lcase_animList].compName[i],lcase[lcase_animList].dat[i][name[1]]);
377       }
378       else
379       {
380         for(i=0; i<lcase[cur_lc].ncomps; i++)
381           if((i!=cur_entity)&&(lcase[cur_lc].iexist[i]==2)) printf ("%s:%5.4e ",lcase[cur_lc].compName[i],lcase[cur_lc].dat[i][name[1]]);
382       }
383 
384       printf (" xyz= %lf %lf %lf ",
385       (node[name[1]].nx* scale->w+scale->x),
386       (node[name[1]].ny* scale->w+scale->y),
387       (node[name[1]].nz* scale->w+scale->z) );
388     }
389 
390     v0[0]=0.;
391     v0[1]=node[name[1]].ny* scale->w+scale->y;
392     v0[2]=node[name[1]].nz* scale->w+scale->z;
393     v1[0]=0.; v1[1]=1.; v1[2]=0.;
394     dax=v_angle(v0,v1);
395     v0[0]=node[name[1]].nx* scale->w+scale->x;
396     v0[1]=0.;
397     v0[2]=node[name[1]].nz* scale->w+scale->z;
398     v1[0]=0.; v1[1]=0.; v1[2]=1.;
399     day=v_angle(v0,v1);
400     v0[0]=node[name[1]].nx* scale->w+scale->x;
401     v0[1]=node[name[1]].ny* scale->w+scale->y;
402     v0[2]=0.;
403     v1[0]=1.; v1[1]=0.; v1[2]=0.;
404     daz=v_angle(v0,v1);
405     v0[0]=node[name[1]].nx* scale->w+scale->x;
406     v0[1]=node[name[1]].ny* scale->w+scale->y;
407     v0[2]=node[name[1]].nz* scale->w+scale->z;
408     printf("axyz= %lf %lf %lf rxyz= %lf %lf %lf\n",
409       dax*180./PI,day*180./PI,daz*180./PI,
410       sqrt(v0[1]*v0[1]+v0[2]*v0[2]),
411       sqrt(v0[0]*v0[0]+v0[2]*v0[2]),
412       sqrt(v0[0]*v0[0]+v0[1]*v0[1]) );
413     if (compare(pickfunc, "qenq", 4) == 4)
414     {
415       sprintf(printbuf, "    in set=");
416       index=2;
417       for(i=1; i<anz->sets; i++)
418         if(!set[i].type)
419         {
420           set[i].index=index++;
421           if((set[i].name!=(char *)NULL)&&(set[i].name[0]!='-')&&( getIndex(&set[i].node,set[i].anz_n,name[1]) >-1))
422           {
423             sprintf(&printbuf[strlen(printbuf)],"%s(%d)",set[i].name,set[i].index);
424 
425             /* is a contact surface referenced ? */
426             if(set[i].anz_se)
427             {
428               sprintf(&printbuf[strlen(printbuf)],"->[ ");
429               for(j=0; j<set[i].anz_se; j++)
430                 sprintf(&printbuf[strlen(printbuf)],"%s(%d) ",set[set[i].set[j]].name,set[set[i].set[j]].index);
431               sprintf(&printbuf[strlen(printbuf)],"]");
432             }
433             sprintf(&printbuf[strlen(printbuf)],",");
434           }
435         }
436       sprintf(&printbuf[strlen(printbuf)],"\n"); if(strlen(printbuf)>12) printf("%s", printbuf);
437     }
438     else if (compare(pickfunc, "qdis", 4) == 4)
439     {
440       if( type[1] == 'h') /* plane */
441       {
442         cpFlag++;
443         v_qdis[cpFlag][0]=node[name[1]].nx* scale->w+scale->x;
444         v_qdis[cpFlag][1]=node[name[1]].ny* scale->w+scale->y;
445         v_qdis[cpFlag][2]=node[name[1]].nz* scale->w+scale->z;
446         if(cpFlag==3) { type[1]=0; cpFlag=0; shFlag++; }
447       }
448 
449       else if( type[1] == 'c') /* set centerpnt */
450       {
451         type[1]=0;
452         cpFlag=1;
453         v_qdis[2][0]=node[name[1]].nx* scale->w+scale->x;
454         v_qdis[2][1]=node[name[1]].ny* scale->w+scale->y;
455         v_qdis[2][2]=node[name[1]].nz* scale->w+scale->z;
456       }
457 
458       else if(qdisFlag>0)
459       {
460         qdisFlag=0;
461 	shFlag=0;
462         v_qdis[1][0]=node[name[1]].nx* scale->w+scale->x;
463         v_qdis[1][1]=node[name[1]].ny* scale->w+scale->y;
464         v_qdis[1][2]=node[name[1]].nz* scale->w+scale->z;
465         if(cpFlag==1)
466         {
467           cpFlag=0;
468           for(i=0; i<3; i++) { v0[i]=v_qdis[0][i]-v_qdis[2][i]; v1[i]=v_qdis[1][i]-v_qdis[2][i]; }
469           da=v_angle(v0,v1);
470           r1=v_betrag(v0);
471           r2=v_betrag(v1);
472           rm=(r1+r2)*.5;
473           lcir=2.*rm*da;
474           printf(" lcir:%lf da:%lf dr:%lf r1:%lf r2:%lf\n", lcir, da*180./PI, r2-r1, r1, r2 );
475         }
476         else
477         {
478           da=v_angle(v_qdis[0],v_qdis[1]);
479           for(i=0; i<3; i++) { v0[i]=v_qdis[0][i]; v1[i]=v_qdis[1][i]; }
480           v0[0]=v1[0]=0.;
481           dax=v_angle(v0,v1);
482           for(i=0; i<3; i++) { v0[i]=v_qdis[0][i]; v1[i]=v_qdis[1][i]; }
483           v0[1]=v1[1]=0.;
484           day=v_angle(v0,v1);
485           for(i=0; i<3; i++) { v0[i]=v_qdis[0][i]; v1[i]=v_qdis[1][i]; }
486           v0[2]=v1[2]=0.;
487           daz=v_angle(v0,v1);
488           for(i=0; i<3; i++) { v0[i]=v_qdis[0][i]; v1[i]=v_qdis[1][i]; }
489           if(!anz->l)
490           {
491 	    dist=sqrt((v_qdis[1][0]-v_qdis[0][0])*(v_qdis[1][0]-v_qdis[0][0])+
492             (v_qdis[1][1]-v_qdis[0][1])*(v_qdis[1][1]-v_qdis[0][1])+
493 		      (v_qdis[1][2]-v_qdis[0][2])*(v_qdis[1][2]-v_qdis[0][2]));
494 	    if(dist>=1e-4)
495 	    {
496             printf("dist:%lf dxyz: %lf %lf %lf da:%lf daxyz: %lf %lf %lf dr:%lf drxyz: %lf %lf %lf\n",
497 		   dist,v_qdis[1][0]-v_qdis[0][0],v_qdis[1][1]-v_qdis[0][1],v_qdis[1][2]-v_qdis[0][2],
498             da*180./PI,dax*180./PI,day*180./PI,daz*180./PI,
499             sqrt(v1[0]*v1[0]+v1[1]*v1[1]+v1[2]*v1[2])-sqrt(v0[0]*v0[0]+v0[1]*v0[1]+v0[2]*v0[2]),
500             sqrt(v1[1]*v1[1]+v1[2]*v1[2])-sqrt(v0[1]*v0[1]+v0[2]*v0[2]),
501             sqrt(v1[0]*v1[0]+v1[2]*v1[2])-sqrt(v0[0]*v0[0]+v0[2]*v0[2]),
502             sqrt(v1[0]*v1[0]+v1[1]*v1[1])-sqrt(v0[0]*v0[0]+v0[1]*v0[1]) );
503 	    }
504 	    else
505 	    {
506               printf("dist:%e dxyz: %e %e %e da:%lf daxyz: %lf %lf %lf dr:%e drxyz: %e %e %e\n",
507 		     dist,v_qdis[1][0]-v_qdis[0][0],v_qdis[1][1]-v_qdis[0][1],v_qdis[1][2]-v_qdis[0][2],
508             da*180./PI,dax*180./PI,day*180./PI,daz*180./PI,
509             sqrt(v1[0]*v1[0]+v1[1]*v1[1]+v1[2]*v1[2])-sqrt(v0[0]*v0[0]+v0[1]*v0[1]+v0[2]*v0[2]),
510             sqrt(v1[1]*v1[1]+v1[2]*v1[2])-sqrt(v0[1]*v0[1]+v0[2]*v0[2]),
511             sqrt(v1[0]*v1[0]+v1[2]*v1[2])-sqrt(v0[0]*v0[0]+v0[2]*v0[2]),
512             sqrt(v1[0]*v1[0]+v1[1]*v1[1])-sqrt(v0[0]*v0[0]+v0[1]*v0[1]) );
513 	    }
514           }
515   	  else
516           {
517             dist=sqrt((v_qdis[1][0]-v_qdis[0][0])*(v_qdis[1][0]-v_qdis[0][0])+
518             (v_qdis[1][1]-v_qdis[0][1])*(v_qdis[1][1]-v_qdis[0][1])+
519 		 (v_qdis[1][2]-v_qdis[0][2])*(v_qdis[1][2]-v_qdis[0][2]));
520 	    if(dist>=1e-4)
521 	    {
522               printf("dist:%lf dv:%lf dxyz: %lf %lf %lf da:%lf daxyz: %lf %lf %lf dr:%lf drxyz: %lf %lf %lf\n",
523 		   dist,lcase[cur_lc].dat[cur_entity][name[1]]-v_val,
524                  v_qdis[1][0]-v_qdis[0][0],v_qdis[1][1]-v_qdis[0][1],v_qdis[1][2]-v_qdis[0][2],
525             da*180./PI,dax*180./PI,day*180./PI,daz*180./PI,
526             sqrt(v1[0]*v1[0]+v1[1]*v1[1]+v1[2]*v1[2])-sqrt(v0[0]*v0[0]+v0[1]*v0[1]+v0[2]*v0[2]),
527             sqrt(v1[1]*v1[1]+v1[2]*v1[2])-sqrt(v0[1]*v0[1]+v0[2]*v0[2]),
528             sqrt(v1[0]*v1[0]+v1[2]*v1[2])-sqrt(v0[0]*v0[0]+v0[2]*v0[2]),
529             sqrt(v1[0]*v1[0]+v1[1]*v1[1])-sqrt(v0[0]*v0[0]+v0[1]*v0[1]) );
530 	    }
531 	    else
532 	    {
533               printf("dist:%e dv:%e dxyz: %e %e %e da:%lf daxyz: %lf %lf %lf dr:%e drxyz: %e %e %e\n",
534 		   dist,lcase[cur_lc].dat[cur_entity][name[1]]-v_val,
535                  v_qdis[1][0]-v_qdis[0][0],v_qdis[1][1]-v_qdis[0][1],v_qdis[1][2]-v_qdis[0][2],
536             da*180./PI,dax*180./PI,day*180./PI,daz*180./PI,
537             sqrt(v1[0]*v1[0]+v1[1]*v1[1]+v1[2]*v1[2])-sqrt(v0[0]*v0[0]+v0[1]*v0[1]+v0[2]*v0[2]),
538             sqrt(v1[1]*v1[1]+v1[2]*v1[2])-sqrt(v0[1]*v0[1]+v0[2]*v0[2]),
539             sqrt(v1[0]*v1[0]+v1[2]*v1[2])-sqrt(v0[0]*v0[0]+v0[2]*v0[2]),
540             sqrt(v1[0]*v1[0]+v1[1]*v1[1])-sqrt(v0[0]*v0[0]+v0[1]*v0[1]) );
541 	    }
542           }
543         }
544       }
545 
546       else
547       {
548 	if(qaddTol>-1) // distance of that node to a set of surfaces or faces
549 	{
550 	  qaddTol=-1;
551 	  sprintf(buffer,"%d",name[1]);
552 	  delSet(specialset->mpc);
553           pre_seta( specialset->mpc, "n", buffer);
554 	  sprintf(buffer,"dist %s %s nor",specialset->mpc,specialset->impc);
555 	  pre_proj(buffer);
556 	  //delSet(specialset->mpc);
557 	  //delSet(specialset->impc);
558 	}
559 	else
560 	{
561           qdisFlag=2; shFlag++;
562           if(anz->l) v_val=lcase[cur_lc].dat[cur_entity][name[1]];
563           v_qdis[0][0]=node[name[1]].nx* scale->w+scale->x;
564           v_qdis[0][1]=node[name[1]].ny* scale->w+scale->y;
565           v_qdis[0][2]=node[name[1]].nz* scale->w+scale->z;
566 	}
567       }
568 
569       if(shFlag==2) // calc the normal dist of v_qdis[0] to the shape v_qdis[1] v_qdis[2] v_qdis[3]
570       {
571         qdisFlag=0;
572 	shFlag=0;
573 	printf("normal dist:%lf\n",normdist(&v_qdis[0][0],&v_qdis[1][0],&v_qdis[2][0],&v_qdis[3][0]));
574       }
575     }
576     else if (compare(pickfunc, "qcnt", 4) == 4)
577     {
578       centerNode=name[1];
579       center( node[name[1]].nx, node[name[1]].ny, node[name[1]].nz);
580       dx_cur=PICK_LENGTH; dy_cur=PICK_LENGTH;
581       glutSetWindow( w1);
582       /* Keyboardfunktion wiederherstellen (von pick())  */
583       pickFlag=0;
584       free(selectBuf); selectBuf=NULL;
585       glutKeyboardFunc ( Keyboard );
586       glutSetWindow( activWindow );
587     }
588     else if (compare(pickfunc, "qdel", 4) == 4) seta( setNrbuf, type, name[1]);
589     else if (compare(pickfunc, "qadd", 4) == 4) seta( setNrbuf, type, name[1]);
590     else if (compare(pickfunc, "qrem", 4) == 4) { if(set[setNrbuf].type) seqr( setNrbuf, type, name[1]); else setr( setNrbuf, type, name[1]); }
591     else if (compare(pickfunc, "qmsh", 4) == 4) entitybuf=createElem(name[1]);
592     else if (compare(pickfunc, "qmov", 4) == 4) moveSet(name, x, y);
593     else if (compare(pickfunc, "qnod", 4) == 4) moveNode(name[1], x, y);
594     else if (compare(pickfunc, "qpnt", 4) == 4) movePoint(name, x, y);
595     else if (compare(pickfunc, "qali", 4) == 4) pre_align( name[1], 0 );
596     else if (compare(pickfunc, "qcut", 4) == 4) pre_cut( name[1], type[1] );
597     else if (compare(pickfunc, "qtxt", 4) == 4) moveText(createText(name[1], -1, 0 ), x, y );
598     else if (compare(pickfunc, "qshp", 4) == 4)
599     {
600       /* create point on node */
601       p= getNewName( buf, "p" );
602       printf(" create point:%s %lf %lf %lf\n", buf, node[name[1]].nx, node[name[1]].ny, node[name[1]].nz );
603       p=pnt( buf, node[name[1]].nx, node[name[1]].ny, node[name[1]].nz, 0 );
604       shapebuf.p[shp_pindx++]=p;
605       printf(" %d pnt picked\n",shp_pindx);
606       if(shp_pindx>6)
607       {
608         shp_pindx=0;
609       }
610     }
611   }
612   else if (name[0] == 'p')
613   {
614     printf ("%s xyz= %lf %lf %lf ", point[name[1]].name,
615       (point[name[1]].px* scale->w+scale->x),
616       (point[name[1]].py* scale->w+scale->y),
617       (point[name[1]].pz* scale->w+scale->z) );
618 
619       v0[0]=0.;
620       v0[1]=point[name[1]].py* scale->w+scale->y;
621       v0[2]=point[name[1]].pz* scale->w+scale->z;
622       v1[0]=0.; v1[1]=1.; v1[2]=0.;
623       dax=v_angle(v0,v1);
624       v0[0]=point[name[1]].px* scale->w+scale->x;
625       v0[1]=0.;
626       v0[2]=point[name[1]].pz* scale->w+scale->z;
627       v1[0]=0.; v1[1]=0.; v1[2]=1.;
628       day=v_angle(v0,v1);
629       v0[0]=point[name[1]].px* scale->w+scale->x;
630       v0[1]=point[name[1]].py* scale->w+scale->y;
631       v0[2]=0.;
632       v1[0]=1.; v1[1]=0.; v1[2]=0.;
633       daz=v_angle(v0,v1);
634       v0[0]=point[name[1]].px* scale->w+scale->x;
635       v0[1]=point[name[1]].py* scale->w+scale->y;
636       v0[2]=point[name[1]].pz* scale->w+scale->z;
637       printf("axyz= %lf %lf %lf rxyz= %lf %lf %lf\n",
638         dax*180./PI,day*180./PI,daz*180./PI,
639         sqrt(v0[1]*v0[1]+v0[2]*v0[2]),
640         sqrt(v0[0]*v0[0]+v0[2]*v0[2]),
641         sqrt(v0[0]*v0[0]+v0[1]*v0[1]) );
642     if (compare(pickfunc, "qenq", 4) == 4)
643     {
644       sprintf(printbuf, "    in set=");
645       index=2;
646       for(i=1; i<anz->sets; i++)
647         if(!set[i].type)
648         {
649           set[i].index=index++;
650           if((set[i].name!=(char *)NULL)&&(set[i].name[0]!='-')&&( getIndex(&set[i].pnt,set[i].anz_p,name[1]) >-1))
651             sprintf(&printbuf[strlen(printbuf)],"%s(%d),", set[i].name,set[i].index);
652         }
653       sprintf(&printbuf[strlen(printbuf)],"\n"); if(strlen(printbuf)>12) printf("%s", printbuf);
654     }
655     else if (compare(pickfunc, "qnor", 4) == 4)
656     {
657       if(qnorCounter==2)
658       {
659         p_qnor[0]=name[1];
660         qnorCounter=0;
661         getNewName(buffer,"l");
662         if((i=normalLine(buffer, p_qnor, pickbuf))<0)
663         { printf("qnor: could not create new line\n"); }
664         else { printf(" create line:%s with new end-point %s\n", buffer, point[i].name ); }
665       }
666       else p_qnor[++qnorCounter]=name[1];
667     }
668     else if (compare(pickfunc, "qdis", 4) == 4)
669     {
670       if( type[1] == 'h') /* plane */
671       {
672         cpFlag++;
673         v_qdis[cpFlag][0]=point[name[1]].px* scale->w+scale->x;
674         v_qdis[cpFlag][1]=point[name[1]].py* scale->w+scale->y;
675         v_qdis[cpFlag][2]=point[name[1]].pz* scale->w+scale->z;
676         if(cpFlag==3) { type[1]=0; cpFlag=0; shFlag++; }
677       }
678 
679       else if( type[1] == 'c') /* set centerpnt */
680       {
681         type[1] =0;
682         cpFlag=1;
683         v_qdis[2][0]=point[name[1]].px* scale->w+scale->x;
684         v_qdis[2][1]=point[name[1]].py* scale->w+scale->y;
685         v_qdis[2][2]=point[name[1]].pz* scale->w+scale->z;
686       }
687 
688       else if(qdisFlag>0)
689       {
690         qdisFlag=0;
691 	shFlag=0;
692         v_qdis[1][0]=point[name[1]].px* scale->w+scale->x;
693         v_qdis[1][1]=point[name[1]].py* scale->w+scale->y;
694         v_qdis[1][2]=point[name[1]].pz* scale->w+scale->z;
695         if(cpFlag==1)
696         {
697           cpFlag=0;
698           for(i=0; i<3; i++) { v0[i]=v_qdis[0][i]-v_qdis[2][i]; v1[i]=v_qdis[1][i]-v_qdis[2][i]; }
699           da=v_angle(v0,v1);
700           r1=v_betrag(v0);
701           r2=v_betrag(v1);
702           rm=(r1+r2)*.5;
703           lcir=2.*rm*da;
704           printf(" lcir:%lf da:%lf dr:%lf r1:%lf r2:%lf\n", lcir, da*180./PI, r2-r1, r1, r2 );
705         }
706         else
707         {
708           da=v_angle(v_qdis[0],v_qdis[1]);
709           for(i=0; i<3; i++) { v0[i]=v_qdis[0][i]; v1[i]=v_qdis[1][i]; }
710           v0[0]=v1[0]=0.;
711           dax=v_angle(v0,v1);
712           for(i=0; i<3; i++) { v0[i]=v_qdis[0][i]; v1[i]=v_qdis[1][i]; }
713           v0[1]=v1[1]=0.;
714           day=v_angle(v0,v1);
715           for(i=0; i<3; i++) { v0[i]=v_qdis[0][i]; v1[i]=v_qdis[1][i]; }
716           v0[2]=v1[2]=0.;
717           daz=v_angle(v0,v1);
718           for(i=0; i<3; i++) { v0[i]=v_qdis[0][i]; v1[i]=v_qdis[1][i]; }
719           printf("dist= %lf dxyz= %lf %lf %lf da= %lf daxyz= %lf %lf %lf dr=%lf drxyz= %lf %lf %lf\n",
720           sqrt((v_qdis[1][0]-v_qdis[0][0])*(v_qdis[1][0]-v_qdis[0][0])+
721           (v_qdis[1][1]-v_qdis[0][1])*(v_qdis[1][1]-v_qdis[0][1])+
722           (v_qdis[1][2]-v_qdis[0][2])*(v_qdis[1][2]-v_qdis[0][2])),
723           v_qdis[1][0]-v_qdis[0][0],v_qdis[1][1]-v_qdis[0][1],v_qdis[1][2]-v_qdis[0][2],
724           da*180./PI, dax*180./PI, day*180./PI, daz*180./PI,
725           sqrt(v1[0]*v1[0]+v1[1]*v1[1]+v1[2]*v1[2])-sqrt(v0[0]*v0[0]+v0[1]*v0[1]+v0[2]*v0[2]),
726           sqrt(v1[1]*v1[1]+v1[2]*v1[2])-sqrt(v0[1]*v0[1]+v0[2]*v0[2]),
727           sqrt(v1[0]*v1[0]+v1[2]*v1[2])-sqrt(v0[0]*v0[0]+v0[2]*v0[2]),
728           sqrt(v1[0]*v1[0]+v1[1]*v1[1])-sqrt(v0[0]*v0[0]+v0[1]*v0[1]) );
729         }
730       }
731 
732       else
733       {
734 	if(qaddTol>-1) // distance of that node to a set of surfaces or faces
735 	{
736 	  qaddTol=-1;
737 	  delSet(specialset->mpc);
738           pre_seta( specialset->mpc, "p", point[name[1]].name);
739 	  sprintf(buffer,"dist %s %s nor",specialset->mpc,specialset->impc);
740 	  pre_proj(buffer);
741 	  //delSet(specialset->mpc);
742 	  //delSet(specialset->impc);
743 	}
744 	else
745 	{
746           qdisFlag=1; shFlag++;
747           v_qdis[0][0]=point[name[1]].px* scale->w+scale->x;
748           v_qdis[0][1]=point[name[1]].py* scale->w+scale->y;
749           v_qdis[0][2]=point[name[1]].pz* scale->w+scale->z;
750         }
751       }
752 
753       if(shFlag==2) // calc the normal dist of v_qdis[0] to the shape v_qdis[1] v_qdis[2] v_qdis[3]
754       {
755         qdisFlag=0;
756 	shFlag=0;
757 	printf("normal dist:%lf\n",normdist(&v_qdis[0][0],&v_qdis[1][0],&v_qdis[2][0],&v_qdis[3][0]));
758       }
759     }
760     else if (compare(pickfunc, "qlin", 4) == 4)
761     {
762       if( type[1] == 'b') entitybuf=createLine( point[name[1]].name, 0 ); /* start line */
763       if( type[1] == 'g') entitybuf=createLine( point[name[1]].name, 1 ); /* end  line */
764       if( type[1] == 'c') entitybuf=createLine( point[name[1]].name, 2 ); /* add centerpnt */
765       if( type[1] == 'm') entitybuf=createLine( point[name[1]].name, 3 ); /* midpnt, create centerpnt */
766       if( type[1] == 't') entitybuf=createLine( point[name[1]].name, 4 ); /* seq, create set */
767       if( type[1] == 'p') entitybuf=createLine( point[name[1]].name, 5 ); /* change length of line (displace) */
768     }
769     else if (compare(pickfunc, "qcnt", 4) == 4)
770     {
771       center( point[name[1]].px, point[name[1]].py, point[name[1]].pz);
772       dx_cur=PICK_LENGTH; dy_cur=PICK_LENGTH;
773       glutSetWindow( w1);
774       /* Keyboardfunktion wiederherstellen (von pick())  */
775       pickFlag=0;
776       free(selectBuf); selectBuf=NULL;
777       glutKeyboardFunc ( Keyboard );
778       glutSetWindow( activWindow );
779     }
780     else if (compare(pickfunc, "qdel", 4) == 4) seta( setNrbuf, type, name[1]);
781     else if (compare(pickfunc, "qadd", 4) == 4) seta( setNrbuf, type, name[1]);
782     else if (compare(pickfunc, "qrem", 4) == 4) { if(set[setNrbuf].type) seqr( setNrbuf, type, name[1]); else setr( setNrbuf, type, name[1]); }
783     else if (compare(pickfunc, "qmov", 4) == 4) moveSet(name, x, y);
784     else if (compare(pickfunc, "qpnt", 4) == 4)
785     {
786       if((surfNr>-1)||(nurbsNr>-1)||(shapeNr>-1))  /* move points to a surface */
787         seta( setNrbuf, type, name[1]);
788       else movePoint(name, x, y);
789     }
790     else if (compare(pickfunc, "qali", 4) == 4) pre_align( name[1], 1 );
791     else if (compare(pickfunc, "qcut", 4) == 4) pre_cut( name[1], type[1] );
792     else if (compare(pickfunc, "qshp", 4) == 4)
793     {
794       shapebuf.p[shp_pindx++]=name[1];
795       printf(" %d pnt picked\n",shp_pindx);
796       if(shp_pindx>6)
797       {
798         shp_pindx=0;
799       }
800     }
801   }
802   else if (name[0] == 'l')
803   {
804     if (line[name[1]].name == (char *)NULL) return(0);
805 
806     if (compare(pickfunc, "qenq", 4) == 4)
807     {
808       if(type[1]=='c')
809       {
810         /* lcmb must be identified and added */
811         for(i=0; i<anzGeo->c; i++)
812         {
813           if( lcmb[i].name != (char *)NULL )
814           {
815             for(j=0; j<lcmb[i].nl; j++) if(lcmb[i].l[j]==name[1])
816             {
817               printf (" lcmb:%s ", lcmb[i].name );
818               for (k=0; k<lcmb[i].nl; k++)
819 	      {
820                 printf (" %1c %s", lcmb[i].o[k], line[lcmb[i].l[k]].name );
821 	      }
822               printf (" \n");
823             }
824           }
825         }
826         return(1);
827       }
828     }
829     else if (compare(pickfunc, "qadd", 4) == 4)
830     {
831       if(type[1]=='c')
832       {
833         /* lcmb must be identified and added */
834         for(i=0; i<anzGeo->c; i++)
835         {
836           if( lcmb[i].name != (char *)NULL )
837           {
838             for(j=0; j<lcmb[i].nl; j++) if(lcmb[i].l[j]==name[1])
839             {
840               printf (" lcmb:%s ", lcmb[i].name );
841               for (k=0; k<lcmb[i].nl; k++)
842 	      {
843                 printf (" %1c %s", lcmb[i].o[k], line[lcmb[i].l[k]].name );
844                 seta( setNrbuf, "l",lcmb[i].l[k] );
845 	      }
846               printf (" \n");
847               seta( setNrbuf, "c", i);
848             }
849           }
850         }
851         return(1);
852       }
853       else  seta( setNrbuf, type, name[1]);
854     }
855     else if (compare(pickfunc, "qdel", 4) == 4)
856     {
857       if(type[1]=='c')
858       {
859         /* lcmb must be identified and added */
860         for(i=0; i<anzGeo->c; i++)
861         {
862           if( lcmb[i].name != (char *)NULL )
863           {
864             for(j=0; j<lcmb[i].nl; j++) if(lcmb[i].l[j]==name[1])
865             {
866               printf (" lcmb:%s ", lcmb[i].name );
867               seta( setNrbuf, "c", i);
868             }
869           }
870         }
871         return(1);
872       }
873       else  seta( setNrbuf, type, name[1]);
874     }
875     else if (compare(pickfunc, "qrem", 4) == 4)
876     {
877       if(type[1]=='c')
878       {
879         /* lcmb must be identified and added */
880         for(i=0; i<anzGeo->c; i++)
881         {
882           if( lcmb[i].name != (char *)NULL )
883           {
884             for(j=0; j<lcmb[i].nl; j++) if(lcmb[i].l[j]==name[1])
885             {
886               printf (" lcmb:%s ", lcmb[i].name );
887               for (k=0; k<lcmb[i].nl; k++)
888 	      {
889                 printf (" %1c %s", lcmb[i].o[k], line[lcmb[i].l[k]].name );
890                 setr( setNrbuf, "l",lcmb[i].l[k] );
891 	      }
892               printf (" \n");
893               setr( setNrbuf, "c", i);
894             }
895           }
896         }
897         return(1);
898       }
899       else setr( setNrbuf, type, name[1]);
900     }
901     else if ((compare(pickfunc, "qbia", 4) == 4)&&(line[name[1]].div>1))
902     {
903       if(type[3]=='c')
904         line[name[1]].bias=1./line[name[1]].bias;
905       else
906       {
907         if(line[name[1]].bias<1.)
908           line[name[1]].bias = 1./pow((double)pickbuf, (1./((double)line[name[1]].div-1.)));
909         else
910           line[name[1]].bias = pow((double)pickbuf, (1./((double)line[name[1]].div-1.)));
911       }
912       repLine(name[1]);
913     }
914     else if (compare(pickfunc, "qdiv", 4) == 4)
915     {
916       if((line[name[1]].bias!=1.)&&(pickbuf>1))
917       {
918         bias_fbd=getBias_fbd(name[1], line);
919         // printf(" bias_fbd:%d\n", bias_fbd);
920 
921         // code from splitBiasDiv()
922         bias_fbd*=10;
923 
924         /* in the fbd-format-definition bias is defined as bias(a)=(elem_length(last)/elem_length(first)) */
925         /* therefore a re-calculation is necessary because in cgx the definition is: */
926         /* bias(b) = (elem_length(n+1)/elem_length(n)) => bias(a)= bias(b)**(div-1) */
927         if(pickbuf>1)
928         {
929           if(bias_fbd<0) line[name[1]].bias= 1./pow(((double)bias_fbd*-.1), (1./((double)pickbuf-1.)));
930           else           line[name[1]].bias= pow(((double)bias_fbd*.1), (1./((double)pickbuf-1.)));
931         }
932         else line[name[1]].bias=1.;
933       }
934       else if(pickbuf==1) line[name[1]].bias=1.;
935       if(pickbuf>0) line[name[1]].div=pickbuf;
936       repLine(name[1]);
937     }
938 
939     bias_fbd=getBias_fbd(name[1], line);
940 
941     if (line[name[1]].typ=='a')
942       printf ("%s p1:%s p2:%s pc:%s div:%d bias:%d bias_el:%lf\n"
943       , line[name[1]].name, point[line[name[1]].p1].name, point[line[name[1]].p2].name
944       , point[line[name[1]].trk].name, line[name[1]].div, bias_fbd, line[name[1]].bias  );
945     else if (line[name[1]].typ=='s')
946       printf ("%s p1:%s p2:%s set:%s div:%d bias:%d bias_el:%lf\n"
947       , line[name[1]].name, point[line[name[1]].p1].name, point[line[name[1]].p2].name
948       , set[line[name[1]].trk].name, line[name[1]].div, bias_fbd, line[name[1]].bias  );
949     else if (line[name[1]].typ==' ')
950       printf ("%s p1:%s p2:%s div:%d bias:%d bias_el:%lf\n"
951       , line[name[1]].name, point[line[name[1]].p1].name, point[line[name[1]].p2].name
952       , line[name[1]].div, bias_fbd, line[name[1]].bias );
953 
954     if (compare(pickfunc, "qenq", 4) == 4)
955     {
956       sprintf(printbuf, "    in set=");
957       index=2;
958       for(i=1; i<anz->sets; i++)
959         if(!set[i].type)
960         {
961           set[i].index=index++;
962           if((set[i].name!=(char *)NULL)&&(set[i].name[0]!='-')&&( getIndex(&set[i].line,set[i].anz_l,name[1]) >-1))
963             sprintf(&printbuf[strlen(printbuf)],"%s(%d),",set[i].name,set[i].index);
964         }
965       sprintf(&printbuf[strlen(printbuf)],"\n"); if(strlen(printbuf)>12) printf("%s", printbuf);
966     }
967     else if (compare(pickfunc, "qmsh", 4) == 4) seta( setNrbuf, type, name[1]);
968     else if (compare(pickfunc, "qint", 4) == 4)
969     {
970       if(intersect( name[1])==0) for (j=0; j<set[setall].anz_l; j++) repLine(set[setall].line[j]);
971     }
972     else if (compare(pickfunc, "qfil", 4) == 4)
973     {
974       if(createFillet( name[1], filletRadius)==0) for (j=0; j<set[setall].anz_l; j++) repLine(set[setall].line[j]);
975     }
976     else if (compare(pickfunc, "qseq", 4) == 4) seta( setNrbuf, type, name[1]);
977     else if ((compare(pickfunc, "qspl", 4) == 4)||((compare(pickfunc, "qlin", 4) == 4)&&(type[1]=='s') ))
978     {
979       for(j=0; j<qspl_i; j++) if(qspl_indx[j]==name[1]) return(0);
980       if (qspl_i<MAX_LINES) qspl_indx[qspl_i]=name[1];
981       else { printf(" ERROR in hitAction(), to much lines picked. Increase MAX_LINES\n"); return(0); }
982       qspl_i++;
983       k= qsplitLine( name[1], x, y );
984       if(k>-1) seta( setNrbuf, "p", k);
985       if(set[setNrbuf].anz_p>1)
986       {
987         sprintf( buffer,"p %s %lf", set[setNrbuf].name, gtol);
988         pre_merge( buffer);
989       }
990     }
991     else if (compare(pickfunc, "qsur", 4) == 4)
992     {
993       if(type[1]=='l') pickstack(name[1]);
994       else strcpy(type, line[name[1]].name);
995     }
996     else if ((compare(pickfunc, "qlin", 4) == 4)&&(type[1]=='e') )
997     {
998       if(entitybuf==name[1]) entitybuf=lineNr;
999       if(entitybuf<0) return(0);
1000       if(entitybuf==name[1]) return(0);
1001 
1002       printf ("try to replace line %s by %s\n", line[name[1]].name, line[entitybuf].name);
1003       if(name[1] !=entitybuf)
1004       {
1005         /* versuche eine linie direkt auszutauschten */
1006         if((line[name[1]].p1==line[entitybuf].p1)&&(line[name[1]].p2==line[entitybuf].p2))
1007 	{
1008           line[entitybuf].div=line[name[1]].div;
1009           /* check lcmbs for the line[i]  */
1010           for (j=0; j<anzGeo->c; j++) if( lcmb[j].name != (char *)NULL )
1011           {
1012             for (k=0; k<lcmb[j].nl; k++)
1013             {
1014               if (lcmb[j].l[k] == name[1])
1015 	      {
1016                 lcmb[j].l[k]=entitybuf;
1017                 printf ("replace %s in lcmb %s by %s\n", line[name[1]].name, lcmb[j].name, line[entitybuf].name);
1018 	      }
1019             }
1020           }
1021           /* check surfs for the line[i]  */
1022           for (j=0; j<anzGeo->s; j++) if( surf[j].name != (char *)NULL )
1023           {
1024             for (k=0; k<surf[j].nl; k++)
1025             {
1026               if ((surf[j].l[k] == name[1])&&(surf[j].typ[k]=='l'))
1027 	      {
1028                 surf[j].l[k]=entitybuf;
1029                 printf ("replace %s in surf %s by %s\n", line[name[1]].name, surf[j].name, line[entitybuf].name);
1030 	      }
1031             }
1032           }
1033           pre_seta( "-delete", "l", line[name[1]].name);
1034           return(1);
1035         }
1036         else if((line[name[1]].p1==line[entitybuf].p2)&&(line[name[1]].p2==line[entitybuf].p1))
1037 	{
1038           line[entitybuf].div=line[name[1]].div;
1039           /* check lcmbs for the line[i]  */
1040           for (j=0; j<anzGeo->c; j++) if( lcmb[j].name != (char *)NULL )
1041           {
1042             for (k=0; k<lcmb[j].nl; k++)
1043             {
1044               if (lcmb[j].l[k] == name[1])
1045               {
1046                 lcmb[j].l[k]=entitybuf;
1047                 printf ("replace %s in lcmb %s by %s\n", line[name[1]].name, lcmb[j].name, line[entitybuf].name);
1048                 if(lcmb[j].o[k]=='+') lcmb[j].o[k]='-';
1049                 else                 lcmb[j].o[k]='+';
1050               }
1051             }
1052           }
1053           /* check surfs for the line[i]  */
1054           for (j=0; j<anzGeo->s; j++) if( surf[j].name != (char *)NULL )
1055           {
1056             for (k=0; k<surf[j].nl; k++)
1057             {
1058               if ((surf[j].l[k] == name[1])&&(surf[j].typ[k]=='l'))
1059               {
1060                 printf ("replace %s in surf %s by %s\n", line[name[1]].name, surf[j].name, line[entitybuf].name);
1061                 surf[j].l[k]=entitybuf;
1062                 if(surf[j].o[k]=='+') surf[j].o[k]='-';
1063                 else                 surf[j].o[k]='+';
1064               }
1065             }
1066           }
1067           pre_seta( "-delete", "l", line[name[1]].name);
1068           return(1);
1069 	}
1070 
1071         /* untersuche alle lcmbs ob line ein Mitglied ist */
1072         for (i=0; i<anzGeo->c; i++) if( lcmb[i].name != (char *)NULL )
1073         {
1074           for (j=0; j<lcmb[i].nl; j++)
1075           {
1076             if( name[1] == lcmb[i].l[j] )
1077             {
1078               /* compare the end-points to find out if the lcmb has the same range */
1079               matchFlag=0;
1080 	      if(lcmb[i].o[0]=='+')
1081               {  if((line[lcmb[i].l[0]].p1==line[entitybuf].p1)||(line[lcmb[i].l[0]].p1==line[entitybuf].p2)) matchFlag=1; }
1082 	      else
1083               {  if((line[lcmb[i].l[0]].p2==line[entitybuf].p1)||(line[lcmb[i].l[0]].p2==line[entitybuf].p2)) matchFlag=1; }
1084 
1085 
1086 	      if(lcmb[i].o[lcmb[i].nl-1]=='-')
1087 	      {if((line[lcmb[i].l[lcmb[i].nl-1]].p1==line[entitybuf].p1)||(line[lcmb[i].l[lcmb[i].nl-1]].p1==line[entitybuf].p2)) matchFlag++; }
1088 	      else
1089 	      { if((line[lcmb[i].l[lcmb[i].nl-1]].p2==line[entitybuf].p1)||(line[lcmb[i].l[lcmb[i].nl-1]].p2==line[entitybuf].p2)) matchFlag++; }
1090 
1091 
1092               /*
1093 	      if(matchFlag) printf("direct match o1:%c lcmblp:%s %s lp:%s %s\n", lcmb[i].o[0], point[line[lcmb[i].l[0]].p1].name,point[line[lcmb[i].l[0]].p2].name,point[line[entitybuf].p1].name,point[line[entitybuf].p2].name);
1094 	      if(matchFlag==2) printf("direct match o2:%c lcmblp:%s %s lp:%s %s\n", lcmb[i].o[lcmb[i].nl-1], point[line[lcmb[i].l[lcmb[i].nl-1]].p1].name,point[line[lcmb[i].l[lcmb[i].nl-1]].p2].name,point[line[entitybuf].p1].name,point[line[entitybuf].p2].name);
1095 	      */
1096 
1097 
1098        	      if(matchFlag==2)
1099 	      {
1100                 line[entitybuf].div=0;
1101                 for(l=0; l<lcmb[i].nl; l++)
1102                 {
1103                   line[entitybuf].div+=line[lcmb[i].l[l]].div;
1104                   pre_seta( "-delete", "l", line[lcmb[i].l[l]].name);
1105   	        }
1106                 repLine(entitybuf);
1107                 printf("complete edge (lcmb:%s) will be deleted and replaced by the new line:%s \n", lcmb[i].name, line[entitybuf].name );
1108                 if ((lcmb[i].o = (char *)realloc( (char *)lcmb[i].o, (1)*sizeof(char)) ) == NULL )
1109                 { printf("\n\n ERROR: realloc failure in qspl, lcmb.o:%s not changed\n\n",lcmb[i].name ); return(0); }
1110                 if ((lcmb[i].l = (int *)realloc( (int *)lcmb[i].l, (1)*sizeof(int)) ) == NULL )
1111                 { printf("\n\n ERROR: realloc failure in qspl, lcmb.l:%s not changed\n\n", lcmb[i].name); return(0); }
1112 
1113                 lcmb[i].o[0]='+';
1114                 lcmb[i].l[0]=entitybuf;
1115                 lcmb[i].nl=1;
1116                 printf ("replace lines in lcmb %s by %s\n", lcmb[i].name, line[entitybuf].name);
1117                 return(1);
1118               }
1119             }
1120           }
1121         }
1122 
1123         /* no exactly matching lcmb was found, go again over all lcmb and replace a line-sequence in a matching lcmb */
1124         for (i=0; i<anzGeo->c; i++) if( lcmb[i].name != (char *)NULL )
1125         {
1126           for (j=0; j<lcmb[i].nl; j++)
1127           {
1128             if( name[1] == lcmb[i].l[j] )
1129             {
1130               /* search the first and the last line which match with the new line */
1131               matchFlag=0;
1132               for (k=0; k<lcmb[i].nl; k++)
1133               {
1134                 if(!matchFlag)
1135 		{
1136 	          if(lcmb[i].o[k]=='+')
1137                   {  if((line[lcmb[i].l[k]].p1==line[entitybuf].p1)||(line[lcmb[i].l[k]].p1==line[entitybuf].p2)) matchFlag++; lin[0]=k;  }
1138 	          else
1139                   {  if((line[lcmb[i].l[k]].p2==line[entitybuf].p1)||(line[lcmb[i].l[k]].p2==line[entitybuf].p2)) matchFlag++; lin[0]=k;  }
1140 		}
1141                 else
1142 		{
1143 	          if(lcmb[i].o[k]=='-')
1144                   { if((line[lcmb[i].l[k]].p1==line[entitybuf].p1)||(line[lcmb[i].l[k]].p1==line[entitybuf].p2)) { matchFlag++; lin[1]=k; } }
1145 	          else
1146 		  { if((line[lcmb[i].l[k]].p2==line[entitybuf].p1)||(line[lcmb[i].l[k]].p2==line[entitybuf].p2)) { matchFlag++; lin[1]=k;  } }
1147 		}
1148 	      }
1149 
1150 	      /*
1151 	      if(matchFlag)
1152                 printf("o1:%c l:%s p:%s %s lp:%s %s\n", lcmb[i].o[lin[0]], line[lcmb[i].l[lin[0]]].name, point[line[lcmb[i].l[lin[0]]].p1].name,point[line[lcmb[i].l[lin[0]]].p2].name,point[line[entitybuf].p1].name,point[line[entitybuf].p2].name);
1153 	      if(matchFlag==2)
1154                 printf("o2:%c l:%s p:%s %s lp:%s %s\n", lcmb[i].o[lin[1]], line[lcmb[i].l[lin[1]]].name, point[line[lcmb[i].l[lin[1]]].p1].name,point[line[lcmb[i].l[lin[1]]].p2].name,point[line[entitybuf].p1].name,point[line[entitybuf].p2].name);
1155 	      */
1156 
1157        	      if(matchFlag==2)
1158 	      {
1159                 line[entitybuf].div=0;
1160                 for(l=lin[0]; l<=lin[1]; l++)
1161                 {
1162                   line[entitybuf].div+=line[lcmb[i].l[l]].div;
1163                   pre_seta( "-delete", "l", line[lcmb[i].l[l]].name);
1164   	        }
1165                 repLine(entitybuf);
1166 
1167                 lcmb[i].l[lin[0]]=entitybuf;
1168                 lcmb[i].o[lin[0]]='+';
1169                 k=lin[0];
1170                 for(l=lin[1]+1; l<lcmb[i].nl; l++)
1171   	        {
1172                   k++;
1173                   lcmb[i].o[k]=lcmb[i].o[l];
1174                   lcmb[i].l[k]=lcmb[i].l[l];
1175                 }
1176                 lcmb[i].nl=k+1;
1177                 printf ("replace lines in lcmb %s by %s\n", lcmb[i].name, line[entitybuf].name);
1178                 return(1);
1179               }
1180             }
1181           }
1182         }
1183       }
1184     }
1185     else if ((compare(pickfunc, "qlin", 4) == 4)&&(type[1]=='x') )
1186     {
1187       printf("Line redefined to be straight\n");
1188       line[name[1]].typ=' ';
1189       line[name[1]].trk=-1;
1190       repLine(name[1]);
1191     }
1192     else if (compare(pickfunc, "qlin", 4) == 4) lineNr=name[1];
1193   }
1194   /*
1195   // lcmbs do not exist as graphical entities and can not be selected so far (TBD)
1196   else if (name[0] == 'c')
1197   {
1198       printf("hallo ch\n");
1199     if (lcmb[name[1]].name == (char *)NULL) return(0);
1200     else if (compare(pickfunc, "qseq", 4) == 4) convertLCMB( name[1] );
1201   }
1202   */
1203   else if (name[0] == 's')
1204   {
1205     if (surf[name[1]].sh<0) printf ("%s %1c BLEND ", surf[name[1]].name, surf[name[1]].ori );
1206     else printf ("%s %1c %s ", surf[name[1]].name, surf[name[1]].ori, shape[surf[name[1]].sh].name );
1207     for (j=0; j<surf[name[1]].nl; j++)
1208     {
1209       if (surf[name[1]].typ[j]=='l')
1210       {
1211         printf (" %1c %s", surf[name[1]].o[j], line[surf[name[1]].l[j]].name );
1212       }
1213       else
1214       {
1215         printf (" %1c %s", surf[name[1]].o[j], lcmb[surf[name[1]].l[j]].name );
1216         for (k=0; k<lcmb[surf[name[1]].l[j]].nl; k++ )
1217         {
1218           printf (" (%c) (%s)", lcmb[surf[name[1]].l[j]].o[k], line[lcmb[surf[name[1]].l[j]].l[k]].name );
1219         }
1220       }
1221     }
1222     if( surf[name[1]].eparm != (char *)NULL )
1223       printf (" etyp:%d attr:%d mshp:%s\n", surf[name[1]].etyp, surf[name[1]].eattr, surf[name[1]].eparm);
1224     else
1225       printf (" etyp:%d attr:%d\n", surf[name[1]].etyp, surf[name[1]].eattr);
1226     if (compare(pickfunc, "qenq", 4) == 4)
1227     {
1228       sprintf(printbuf, "    in set=");
1229       index=2;
1230       for(i=1; i<anz->sets; i++)
1231         if(!set[i].type)
1232         {
1233           set[i].index=index++;
1234           if((set[i].name!=(char *)NULL)&&(set[i].name[0]!='-')&&( getIndex(&set[i].surf,set[i].anz_s,name[1]) >-1))
1235             sprintf(&printbuf[strlen(printbuf)],"%s(%d),",set[i].name,set[i].index);
1236         }
1237       sprintf(&printbuf[strlen(printbuf)],"\n"); if(strlen(printbuf)>12) printf("%s", printbuf);
1238     }
1239     else if (compare(pickfunc, "qdel", 4) == 4) seta( setNrbuf, type, name[1]);
1240     else if (compare(pickfunc, "qadd", 4) == 4) seta( setNrbuf, type, name[1]);
1241     else if (compare(pickfunc, "qmsh", 4) == 4) seta( setNrbuf, type, name[1]);
1242     else if (compare(pickfunc, "qrem", 4) == 4) setr( setNrbuf, type, name[1]);
1243     else if (compare(pickfunc, "qdis", 4) == 4)
1244     {
1245       delSet(specialset->impc);
1246       setNrbuf=pre_seta( specialset->impc, "i", 0);
1247       if(setNrbuf<0) { errMsg(" ERROR: could not create set for qdis\n"); return(0); }
1248       seta( setNrbuf, type, name[1]);
1249       qaddTol=0;  // marker
1250     }
1251     else if (compare(pickfunc, "qsur", 4) == 4)
1252     {
1253       /* change the interior def to BLEND */
1254       if(type[1]=='b')
1255       {
1256         if(surf[name[1]].pgn!=NULL)
1257 	{
1258           surf[name[1]].sh=-1; free(surf[name[1]].pgn); surf[name[1]].pgn=NULL; surf[name[1]].npgn=0;
1259           repSurf(name[1],1);
1260 	}
1261         else
1262         {
1263           surf[name[1]].sh=-1; free(surf[name[1]].pgn); surf[name[1]].pgn=NULL; surf[name[1]].npgn=0;
1264 	}
1265         printf (" interior changed to BLEND\n");
1266       }
1267       else if(type[1]=='h')
1268       {
1269         shapeNr=surf[name[1]].sh;
1270 	if( shapeNr>-1)
1271 	{
1272           //if(shape[surf[name[1]].sh].type==4) nurbsNr=shape[surf[name[1]].sh].p[0];
1273           printf (" default shape set to %s\n",shape[shapeNr].name);
1274 	}
1275         else printf(" surf has no related shape\n");
1276       }
1277       else if(type[1]=='S')
1278       {
1279         shapeNr=surf[name[1]].sh;
1280 	if( shapeNr>-1)
1281 	{
1282           if(shape[surf[name[1]].sh].type==4) nurbsNr=shape[surf[name[1]].sh].p[0];
1283           printf (" default nurbs set to %s (referenced by shape:%s)\n",nurbs[nurbsNr].name, shape[nurbsNr].name);
1284 	}
1285         else printf(" surf has no related nurbs\n");
1286       }
1287       else if(type[1]=='s')
1288       {
1289 	/* if a Nurbs or a shape was chosen change the interior def of the selected surf */
1290         if(nurbsNr>-1)
1291 	{
1292           surf[name[1]].sh=getShapeNr(nurbs[nurbsNr].name);
1293           shape_refSurf(surf[name[1]].sh, name[1]);
1294           if(surf[name[1]].sh>-1)
1295 	  {
1296             if(surf[name[1]].pgn!=NULL)
1297 	    {
1298               free(surf[name[1]].pgn); surf[name[1]].pgn=NULL; surf[name[1]].npgn=0;
1299 
1300               /* create the interior */
1301               repSurf(name[1],1);
1302 	    }
1303             printf (" interior changed to nurbs: %s (referenced by shape:%s)\n",nurbs[nurbsNr].name, shape[surf[name[1]].sh].name );
1304 	  }
1305 	}
1306         else if(shapeNr>-1)
1307 	{
1308           surf[name[1]].sh=shapeNr;
1309           shape_refSurf(surf[name[1]].sh, name[1]);
1310           if(surf[name[1]].pgn!=NULL)
1311 	  {
1312             free(surf[name[1]].pgn); surf[name[1]].pgn=NULL; surf[name[1]].npgn=0;
1313 
1314             /* create the interior */
1315             repSurf(name[1],1);
1316 	  }
1317           printf (" interior changed to shape: %s\n", shape[surf[name[1]].sh].name );
1318 	}
1319         else
1320         {
1321 	  /* define this surf-name as the default name */
1322           printf(" Active surf:%s\n", surf[name[1]].name);
1323           surfNr=name[1];
1324         }
1325       }
1326     }
1327     else if (compare(pickfunc, "qbod", 4) == 4) pickstack(name[1]);
1328     else if (compare(pickfunc, "qshp", 4) == 4)
1329     {
1330       /* if a a default shape or nurbs is known apply to surf */
1331       if((nurbsNr>-1)||(shapeNr>-1))
1332       {
1333         if(nurbsNr>-1) { surf[name[1]].sh=getShapeNr(nurbs[nurbsNr].name); shape_refSurf(surf[name[1]].sh, name[1]); }
1334         if(shapeNr>-1) { surf[name[1]].sh=shapeNr; shape_refSurf(surf[name[1]].sh, name[1]); }
1335 
1336 
1337 	/* if it was prepared for illumination, change the interior def of the selected surf */
1338         if(surf[name[1]].pgn!=NULL)
1339 	{
1340           free(surf[name[1]].pgn); surf[name[1]].pgn=NULL; surf[name[1]].npgn=0;
1341 
1342           /* create the interior */
1343           repSurf(name[1],1);
1344 	}
1345         printf (" interior changed to Shape: %s\n", shape[surf[name[1]].sh].name );
1346       }
1347       else
1348       {
1349         printf (" ERROR: No active shape\n");
1350       }
1351     }
1352     else if (compare(pickfunc, "qflp", 4) == 4) flip( type, name[1]);
1353     else if (compare(pickfunc, "qpnt", 4) == 4)
1354     {
1355       /* mark a surface as a target for the point-projection */
1356       if(surf[name[1]].sh>-1)
1357       {
1358         surfNr=name[1];
1359       }
1360       else
1361       {
1362         errMsg("WARNING: surf:%s is not related to a nurbs, surf can not be used for projection\n", surf[name[1]].name);
1363       }
1364     }
1365   }
1366   else if (name[0] == 'b')
1367   {
1368     printf ("%s %1c", body[name[1]].name, body[name[1]].ori );
1369     for (j=0; j<body[name[1]].ns; j++)
1370       printf (" %1c %s", body[name[1]].o[j], surf[body[name[1]].s[j]].name );
1371     if( body[name[1]].eparm != (char *)NULL )
1372       printf (" etyp:%d attr:%d mshp:%s\n", body[name[1]].etyp, body[name[1]].eattr, body[name[1]].eparm);
1373     else
1374       printf (" etyp:%d attr:%d\n", body[name[1]].etyp, body[name[1]].eattr);
1375     if (compare(pickfunc, "qenq", 4) == 4)
1376     {
1377       sprintf(printbuf, "    in set=");
1378       index=2;
1379       for(i=1; i<anz->sets; i++)
1380         if(!set[i].type)
1381         {
1382           set[i].index=index++;
1383           if((set[i].name!=(char *)NULL)&&(set[i].name[0]!='-')&&( getIndex(&set[i].body,set[i].anz_b,name[1]) >-1))
1384             sprintf(&printbuf[strlen(printbuf)],"%s(%d),",set[i].name,set[i].index);
1385         }
1386       sprintf(&printbuf[strlen(printbuf)],"\n"); if(strlen(printbuf)>12) printf("%s", printbuf);
1387     }
1388     else if (compare(pickfunc, "qdel", 4) == 4) seta( setNrbuf, type, name[1]);
1389     else if (compare(pickfunc, "qadd", 4) == 4) seta( setNrbuf, type, name[1]);
1390     else if (compare(pickfunc, "qrem", 4) == 4) setr( setNrbuf, type, name[1]);
1391     else if (compare(pickfunc, "qbod", 4) == 4) bodyNr=name[1];
1392     else if (compare(pickfunc, "qflp", 4) == 4) flip( type, name[1]);
1393   }
1394   else if (name[0] == 'L')
1395   {
1396     printf ("%s \n", nurbl[name[1]].name);
1397     if (compare(pickfunc, "qenq", 4) == 4)
1398     {
1399       sprintf(printbuf, "    in set=");
1400       index=2;
1401       for(i=1; i<anz->sets; i++)
1402         if(!set[i].type)
1403         {
1404           set[i].index=index++;
1405           if((set[i].name!=(char *)NULL)&&(set[i].name[0]!='-')&&( getIndex(&set[i].nurl,set[i].anz_nurl,name[1]) >-1))
1406             sprintf(&printbuf[strlen(printbuf)],"%s(%d),",set[i].name,set[i].index);
1407         }
1408       sprintf(&printbuf[strlen(printbuf)],"\n"); if(strlen(printbuf)>12) printf("%s", printbuf);
1409     }
1410     else if (compare(pickfunc, "qdel", 4) == 4) seta( setNrbuf, type, name[1]);
1411     else if (compare(pickfunc, "qadd", 4) == 4) seta( setNrbuf, type, name[1]);
1412     else if (compare(pickfunc, "qrem", 4) == 4) setr( setNrbuf, type, name[1]);
1413   }
1414   else if (name[0] == 'S')
1415   {
1416     printf ("%s \n", nurbs[name[1]].name);
1417     if (compare(pickfunc, "qenq", 4) == 4)
1418     {
1419       sprintf(printbuf, "    in set=");
1420       index=2;
1421       for(i=1; i<anz->sets; i++)
1422         if(!set[i].type)
1423         {
1424           set[i].index=index++;
1425           if((set[i].name!=(char *)NULL)&&(set[i].name[0]!='-')&&( getIndex(&set[i].nurs,set[i].anz_nurs,name[1]) >-1))
1426             sprintf(&printbuf[strlen(printbuf)],"%s(%d),",set[i].name,set[i].index);
1427         }
1428       sprintf(&printbuf[strlen(printbuf)],"\n"); if(strlen(printbuf)>12) printf("%s", printbuf);
1429     }
1430     else if (compare(pickfunc, "qdel", 4) == 4) seta( setNrbuf, type, name[1]);
1431     else if (compare(pickfunc, "qadd", 4) == 4) seta( setNrbuf, type, name[1]);
1432     else if (compare(pickfunc, "qrem", 4) == 4) setr( setNrbuf, type, name[1]);
1433     else if (compare(pickfunc, "qpnt", 4) == 4)
1434     {
1435       /* mark a surface as a target for the point-projection */
1436       nurbsNr=name[1];
1437     }
1438     else if (compare(pickfunc, "qshp", 4) == 4)
1439     {
1440 	printf(" Active Nurbs:%s\n", nurbs[name[1]].name);
1441         nurbsNr=name[1];
1442         shapeNr=-1;
1443     }
1444   }
1445   else printf ("\n");
1446   return(1);
1447 }
1448 
1449 
1450 
hitUndo(GLuint * name,char * type,int x,int y)1451 int hitUndo( GLuint *name, char *type, int x, int y )
1452 {
1453   /* name[0]== entity type of picked name   */
1454   /* name[1]== picked name(Nr)  */
1455   /* type[0] == requested entity type */
1456   /* type[1] == often gkey in pick() */
1457 
1458   if (name[0] == 'e')
1459   {
1460     printf (" element: %d \n", name[1]);
1461     /* if (compare(pickfunc, "qdel", 4) == 4) */
1462     if (compare(pickfunc, "qadd", 4) == 4) setr( setNrbuf, type, name[1]);
1463     else if (compare(pickfunc, "qrem", 4) == 4) seta( setNrbuf, type, name[1]);
1464   }
1465   else if (name[0] == 'f')
1466   {
1467     printf (" face: %d \n", name[1]);
1468     /* if (compare(pickfunc, "qdel", 4) == 4) */
1469     if (compare(pickfunc, "qadd", 4) == 4) setr( setNrbuf, type, name[1]);
1470     else if (compare(pickfunc, "qrem", 4) == 4) seta( setNrbuf, type, name[1]);
1471   }
1472   else if (name[0] == 'h')
1473   {
1474     /* if (compare(pickfunc, "qdel", 4) == 4) */
1475     if (compare(pickfunc, "qadd", 4) == 4) setr( setNrbuf, type, name[1]);
1476     else if (compare(pickfunc, "qrem", 4) == 4) seta( setNrbuf, type, name[1]);
1477   }
1478   else if (name[0] == 'n')
1479   {
1480     /* if (compare(pickfunc, "qdel", 4) == 4) */
1481     if (compare(pickfunc, "qadd", 4) == 4) setr( setNrbuf, type, name[1]);
1482     else if (compare(pickfunc, "qrem", 4) == 4) seta( setNrbuf, type, name[1]);
1483   }
1484   else if (name[0] == 'p')
1485   {
1486     /*
1487     if (compare(pickfunc, "qdel", 4) == 4)
1488     */
1489     if (compare(pickfunc, "qadd", 4) == 4) setr( setNrbuf, type, name[1]);
1490     else if (compare(pickfunc, "qrem", 4) == 4) seta( setNrbuf, type, name[1]);
1491   }
1492   else if (name[0] == 'l')
1493   {
1494     /*
1495     if (compare(pickfunc, "qdiv", 4) == 4) { line[name[1]].div=pickbuf; repLine(name[1]); }
1496     if (compare(pickfunc, "qspl", 4) == 4) qsplitLine( name[1], x, y, type[1]);
1497     if (compare(pickfunc, "qdel", 4) == 4) setr( setNrbuf, type, name[1]);
1498     */
1499     if (compare(pickfunc, "qadd", 4) == 4) setr( setNrbuf, type, name[1]);
1500     else if (compare(pickfunc, "qrem", 4) == 4) seta( setNrbuf, type, name[1]);
1501   }
1502   else if (name[0] == 's')
1503   {
1504     if (compare(pickfunc, "qadd", 4) == 4) setr( setNrbuf, type, name[1]);
1505     else if (compare(pickfunc, "qrem", 4) == 4) seta( setNrbuf, type, name[1]);
1506     /*
1507     if (compare(pickfunc, "qdel", 4) == 4)
1508     */
1509   }
1510   else if (name[0] == 'b')
1511   {
1512     /* if (compare(pickfunc, "qdel", 4) == 4) */
1513     if (compare(pickfunc, "qadd", 4) == 4) setr( setNrbuf, type, name[1]);
1514     else if (compare(pickfunc, "qrem", 4) == 4) seta( setNrbuf, type, name[1]);
1515   }
1516   else printf ("\n");
1517   return(1);
1518 }
1519 
1520 
1521 
pickstack(GLuint name)1522 int pickstack( GLuint name )
1523 {
1524   printf (" pickstack: name:%d added\n", name );
1525   pickdata[0]++;
1526   if (pick_buffer<=pickdata[0])
1527   {
1528     pick_buffer=DPICK_BUFFER+pickdata[0];
1529     if((pickdata=(int *)realloc((int *)pickdata,(pick_buffer)*sizeof(int)))==NULL)
1530     { errMsg("\n\nERROR: realloc failure in pickstack\n");
1531     return(-1); }
1532   }
1533   pickdata[pickdata[0]]=name;
1534   return(pickdata[0]);
1535 }
1536 
1537 
1538 
processHits(GLint hits,GLuint * buffer,char * type,char * mode,int x,int y)1539 int processHits( GLint hits, GLuint *buffer, char *type, char *mode, int x, int y )
1540 {
1541   int i;
1542   GLuint   *ptr, key;
1543   GLuint   name[2];
1544   static GLuint ubuffer;
1545   float value;
1546 
1547   pick_zmin=(unsigned int)(pow(2,32)-1);
1548   name[0]=-1;
1549   name[1]=-1;
1550 
1551   key=type[0];
1552   ptr=buffer;
1553   /* ptr pro hit: anz_names, pick_zmin, max_z, name_1, name_n, ... */
1554   if (hits)
1555   {
1556 
1557     // printf (" hits= %d mode %c type %c %c\n", hits,  mode[0], type[0], type[1]);
1558 
1559     if ( mode[0] == 'i')
1560     {
1561       for (i=0; i<hits; i++) /* suche hit mit pick_zmin */
1562       {
1563 
1564         //printf ("hitrecord: %u %u %u type:%c entity:%u %d key:%c\n", *(ptr), *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+4), key);
1565 
1566         ptr+=2;
1567         if(((unsigned int)ptr[0] <= (unsigned int)pick_zmin) &&(ptr[1] == key) )
1568         {
1569           pick_zmin=*ptr; name[0]=ptr[1]; name[1]=*(ptr+2);
1570 
1571           //printf ("pick_zmin:%u typ:%c name:%u key:%c\n", pick_zmin, name[0], name[1], (unsigned int)type[0] );
1572 
1573         }
1574         ptr+=1+*(ptr-2);
1575       }
1576       if (name[0]!=(GLuint)-1)
1577       {
1578         if (type[3]=='u')  hitUndo( name, type, x, y );
1579         else               hitAction( name, type, x, y);
1580       }
1581     }
1582     if ( mode[0] == 'a')
1583     {
1584       for (i=0; i<hits; i++) /* collect all hits */
1585       {
1586 
1587         //printf ("hitrecord: %u %u %u %c %u\n", *(ptr), *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4) );
1588 
1589         ptr+=2;
1590         if ((unsigned int)ptr[1] == (unsigned int)key)
1591         {
1592           pick_zmin=*ptr; name[0]=ptr[1]; name[1]=*(ptr+2);
1593 
1594           //printf ("pick_zmin:%u typ:%1c name:%u key:%1c\n", pick_zmin, name[0], name[1], type[0] );
1595 
1596           if (type[3]=='u')  hitUndo( name, type, x, y );
1597           else               hitAction( name, type, x, y );
1598         }
1599         if (key=='a')
1600         {
1601           if((unsigned int)ptr[0] <= (unsigned int)pick_zmin)
1602           {
1603             pick_zmin=*ptr; name[0]=ptr[1]; name[1]=*(ptr+2);
1604 
1605             //printf ("pick_zmin:%u typ:%c name:%u key:%c\n", pick_zmin, name[0], name[1], (unsigned int)type[0] );
1606 
1607           }
1608         }
1609         ptr+=1+*(ptr-2);
1610       }
1611     }
1612     if ( mode[0] == 'm') /* search max/min values in given range of nodes */
1613     {
1614       if (type[3]=='u')
1615       {
1616         ntext[anz->t-1].node_nr=0;
1617         if (compare(pickfunc, "qdel", 4) == 4) setr( setNrbuf, type, ubuffer);
1618         else if(compare(pickfunc, "qadd", 4) == 4) setr( setNrbuf, type, ubuffer);
1619         else if (compare(pickfunc, "qrem", 4) == 4) seta( setNrbuf, type, ubuffer);
1620         return(1);
1621       }
1622       if (type[1]=='h') value=-MAX_FLOAT; else value=MAX_FLOAT;
1623       name[1]=0;
1624       for (i=0; i<hits; i++) /* collect all hits */
1625       {
1626         ptr+=2;
1627         if ((unsigned int)ptr[1] == (unsigned int)key)
1628         {
1629           name[0]=*(ptr+2); /* buffer, will be redefined as 'n' later */
1630           if (type[1]=='h')
1631 	  {
1632 	    if(sequenceFlag)
1633 	    {
1634               if(value < lcase[lcase_animList].dat[animList][name[0]])
1635 	      {
1636                 name[1]=name[0];
1637                 value=lcase[lcase_animList].dat[animList][name[1]];
1638 	      }
1639 	    }
1640             else
1641 	    {
1642               if(value < lcase[cur_lc].dat[cur_entity][name[0]])
1643 	      {
1644                 name[1]=name[0];
1645                 value=lcase[cur_lc].dat[cur_entity][name[1]];
1646 	      }
1647 	    }
1648  	  }
1649           else
1650 	  {
1651 	    if(sequenceFlag)
1652 	    {
1653               if(value > lcase[lcase_animList].dat[animList][name[0]])
1654 	      {
1655                 name[1]=name[0];
1656                 value=lcase[lcase_animList].dat[animList][name[1]];
1657 	      }
1658 	    }
1659             else
1660 	    {
1661               if(value > lcase[cur_lc].dat[cur_entity][name[0]])
1662 	      {
1663                 name[1]=name[0];
1664                 value=lcase[cur_lc].dat[cur_entity][name[1]];
1665 	      }
1666 	    }
1667 	  }
1668         }
1669         ptr+=1+*(ptr-2);
1670       }
1671 
1672       if(name[1])
1673       {
1674         name[0]='n';
1675         ubuffer=name[1];
1676 
1677         printf ("%d v= %e ", name[1], value);
1678         /* search linked values (iexist=2) */
1679         if(sequenceFlag)
1680         {
1681           for(i=0; i<lcase[lcase_animList].ncomps; i++)
1682             if((i!=animList)&&(lcase[lcase_animList].iexist[i]==2)) printf ("%s:%5.4e ",lcase[lcase_animList].compName[i],lcase[lcase_animList].dat[i][name[1]]);
1683         }
1684         else
1685         {
1686           for(i=0; i<lcase[cur_lc].ncomps; i++)
1687             if((i!=cur_entity)&&(lcase[cur_lc].iexist[i]==2)) printf ("%s:%5.4e ",lcase[cur_lc].compName[i],lcase[cur_lc].dat[i][name[1]]);
1688         }
1689 
1690         printf (" xyz= %lf %lf %lf \n",
1691         (node[name[1]].nx* scale->w+scale->x),
1692         (node[name[1]].ny* scale->w+scale->y),
1693         (node[name[1]].nz* scale->w+scale->z) );
1694         createText(name[1], -1, 0 );
1695         if (compare(pickfunc, "qdel", 4) == 4) seta( setNrbuf, type, name[1]);
1696         else if(compare(pickfunc, "qadd", 4) == 4) seta( setNrbuf, type, name[1]);
1697         else if (compare(pickfunc, "qrem", 4) == 4) setr( setNrbuf, type, name[1]);
1698       }
1699     }
1700   }
1701   else errMsg ("\n");
1702   return(1);
1703 }
1704 
1705 
1706 
defineDiv(unsigned char gkey,int x,int y)1707 void defineDiv( unsigned char gkey, int x, int y )
1708 {
1709   int i,j;
1710   static int ii=0;
1711   static char type[MAX_LINE_LENGTH], buffer[MAX_LINE_LENGTH];
1712 
1713   if (ii)
1714   {
1715     printf("%c",gkey);
1716     ii--;
1717     type[ii]=gkey;
1718   }
1719   else
1720   {
1721     /* 3 digits number? */
1722     if(gkey==' ')
1723     {
1724       printf(" define 3 digits Div: \n");
1725       ii=3;
1726     }
1727 
1728     /* 2 digits number? */
1729     else
1730     {
1731       ii=2;
1732     }
1733     type[ii]='\0';
1734 
1735     /* 2 digits number */
1736     if (ii==2)
1737     {
1738       printf("%c",gkey);
1739       ii--;
1740       type[ii]=gkey;
1741     }
1742   }
1743 
1744   if (!ii)
1745   {
1746     printf("\n");
1747     j=0;
1748     for(i=strlen(type)-1; i>=0; i--) buffer[j++]=type[i];
1749     //buffer[j]='\0';
1750     buffer[j]=0;
1751     i=0;
1752     pickbuf=atof(buffer);
1753     glutKeyboardFunc ( pick );
1754     type[0]='l';
1755     type[1]=' ';
1756     type[2]='\0';
1757     if (compare(pickfunc, "qmsh", 4) == 4)
1758     {
1759       if(setNrdiv==-1) return;
1760       if((!set[setNrbuf].anz_l)&&(!set[setNrbuf].anz_s)) { printf(" WARNING: Nothing selected\n"); return; }
1761       /* delete the mesh */
1762       sprintf(buffer,"me %s", set[setNrbuf].name);
1763       pre_del(buffer);
1764       for(i=0; i<set[setNrbuf].anz_l; i++)
1765       {
1766         printf("del mesh line %s\n",line[set[setNrbuf].line[i]].name);
1767         line[set[setNrbuf].line[i]].nn=0;
1768         line[set[setNrbuf].line[i]].ne=0;
1769       }
1770       for(i=0; i<set[setNrbuf].anz_s; i++)
1771       {
1772         printf("del mesh surf %s\n",surf[set[setNrbuf].surf[i]].name);
1773         surf[set[setNrbuf].surf[i]].nn=0;
1774         surf[set[setNrbuf].surf[i]].ne=0;
1775       }
1776       if(!qbiaFlag)
1777       {
1778         /* change division */
1779         strcpy(pickfunc, "qdiv");
1780         goPicking(xbuf,ybuf,type);
1781         for(i=0; i<set[setNrdiv].anz_l; i++)
1782         { line[set[setNrdiv].line[i]].div=line[entitybuf].div; repLine(set[setNrdiv].line[i]); }
1783       }
1784       else
1785       {
1786         strcpy(pickfunc, "qbia");
1787         goPicking(xbuf,ybuf,type);
1788         for(i=0; i<set[setNrdiv].anz_l; i++)
1789         {
1790           line[set[setNrdiv].line[i]].bias=line[entitybuf].bias;
1791           repLine(set[setNrdiv].line[i]);
1792         }
1793       }
1794       qmshOperator=0;
1795       qbiaFlag=0;
1796       strcpy(pickfunc, "qmsh");
1797       /* mesh again */
1798       if(set[setNrbuf].anz_s)
1799       {
1800         for(i=0; i<set[setNrbuf].anz_s; i++)
1801         {
1802           printf("mesh %s\n",surf[set[setNrbuf].surf[i]].name);
1803         }
1804         completeSet(set[setNrbuf].name, "do");
1805         pre_mesh( set[setNrbuf].name );
1806         sprintf(buffer,"n %s",set[setNrbuf].name);
1807         pre_merge(buffer);
1808       }
1809       delSet("-qmsh");
1810       delSet("-setdiv");
1811       setNrdiv=-1;
1812     }
1813     else goPicking(xbuf,ybuf,type);
1814   }
1815 }
1816 
defineValue(unsigned char gkey,int x,int y)1817 void defineValue( unsigned char gkey, int x, int y )
1818 {
1819   static int i=0;
1820   static char type[MAX_LINE_LENGTH];
1821   type[i]=gkey;
1822   i++;
1823   if (gkey==( char )0xd)
1824   {
1825     i=0;
1826     printf("\n");
1827     pickbuf=atof(type);
1828     glutKeyboardFunc ( pick );
1829     type[0]='p';
1830     type[1]='p';
1831     type[2]='\0';
1832     goPicking(xbuf,ybuf,type);
1833   }
1834   else
1835   {
1836     printf("%c",gkey);
1837     fflush(stdout);
1838   }
1839 }
1840 
1841 
1842 /* fragt Keyboard ab, was im pick-mode zu tun ist  */
1843 /* wenn "q" dann exit  */
pick(unsigned char gkey,int x,int y)1844 void pick( unsigned char gkey, int x, int y )
1845 {
1846   int  i,j,n,k;
1847   char flag;
1848   static int ii={0}, xcur[2], ycur[2], wtogle={0};
1849   static double yw[2], xw[2], dist;
1850   static int anz_lpc[EDGES_PER_SURF], clines[EDGES_PER_SURF][LINES_PER_EDGE], edge[EDGES_PER_SURF], newc[EDGES_PER_SURF];
1851   char ctyp[EDGES_PER_SURF];
1852   static char type[MAX_LINE_LENGTH];
1853   int  icor, nr, shbuf, linbuf;
1854   static int anz_c=0, anz_newc=0;
1855   static char name[MAX_LINE_LENGTH], ori[2], blend[MAX_LINE_LENGTH], cori[EDGES_PER_SURF][2];
1856   static char *lori=NULL;
1857   static char face[SURFS_PER_BODY][MAX_LINE_LENGTH];
1858   static char *alreadyChecked=NULL;
1859   GLuint size_selectBuf;
1860   double dum;
1861 
1862   dum=(double)anz->n+anz->e+anz->f+anz->g+anz->t+anzGeo->p+anzGeo->l+anzGeo->s+anzGeo->b+anzGeo->sh+anzGeo->nurl+anzGeo->nurs+1000;
1863   dum*=10;
1864   if(dum > MAX_INTEGER) size_selectBuf=MAX_INTEGER;
1865   else size_selectBuf=(GLuint)dum;
1866   do{
1867     if( ( selectBuf= (GLuint *)realloc((GLuint *)selectBuf, size_selectBuf * sizeof(GLuint))) == NULL )
1868     {
1869       printf ("WARNING: in Pick() is size_selectBuf: %d to large and is reduced\n", size_selectBuf);
1870       size_selectBuf/=2;
1871     }
1872     if(size_selectBuf<100)
1873     {
1874       errMsg("\n\n ERROR: realloc Failure in pick()\n\n") ;
1875       return;
1876     }
1877   }while(!selectBuf);
1878   glSelectBuffer (size_selectBuf, selectBuf);
1879 
1880 
1881   /* small UNDO capability */
1882   if ( gkey == 'u') /* undo last picking-action */
1883   {
1884 
1885     if (compare(pickfunc, "qcut", 4) == 4) uncut(1);
1886 
1887     else if (compare(pickfunc, "qmov", 4) == 4)
1888     {
1889       GLubuf[1]=-2;
1890       moveSet(GLubuf, x, y);
1891     }
1892     else if (compare(pickfunc, "qnod", 4) == 4)
1893     {
1894       moveNode(-2, x, y);
1895     }
1896     else if (compare(pickfunc, "qmsh", 4) == 4)
1897     {
1898       if(entitybuf>=0) { delElem( 1, &entitybuf); entitybuf=-1; }
1899     }
1900     else if (compare(pickfunc, "qpnt", 4) == 4)
1901     {
1902       if(entitybuf>=0) { delPnt( 1, &entitybuf); entitybuf=-1; }
1903       else
1904       {
1905         GLubuf[1]=-2;
1906         movePoint(GLubuf, x, y);
1907       }
1908     }
1909     else if (compare(pickfunc, "qlin", 4) == 4)
1910     {
1911       if(entitybuf>=0) { delLine( 1, &entitybuf); entitybuf=-1; }
1912     }
1913     else if (compare(pickfunc, "qsur", 4) == 4)
1914     {
1915       if(entitybuf>=0) { delSurf( 1, &entitybuf); entitybuf=-1; }
1916       /* reset counters */
1917       anz_c=0;
1918       for (i=0; i<EDGES_PER_SURF; i++) anz_lpc[i]=0;
1919     }
1920     else if (compare(pickfunc, "qbod", 4) == 4)
1921     {
1922       if(entitybuf>=0) { delBody( 1, &entitybuf); entitybuf=-1; }
1923     }
1924     else if (compare(pickfunc, "qenq", 4) == 4)
1925     {
1926       if(mode[0]=='m') ntext[anz->t-1].node_nr=0;
1927     }
1928     else if ((compare(pickfunc, "qadd", 4) == 4)||(compare(pickfunc, "qrem", 4) == 4))
1929     {
1930       type[3]='u';
1931       processHits( hits, selectBuf, type, mode, x, y );
1932       if (type[0]=='e') updateDispLists();
1933     }
1934     return;
1935   }
1936 
1937   type[0]=gkey;
1938   type[2]='\0';
1939   type[3]='\0';
1940 
1941   /* QUIT: delete and re-open the temporary set which stores highlited entities, or quit */
1942   if (( type[0] == 'q')||( type[0] == 'Q')) /* Exit Pick() */
1943   {
1944     /* if a q-func was started inside another q-func, go back to 1st q-func */
1945     if(hidefunc[0]!=0)
1946     {
1947       printf(" change back to %s\n", hidefunc);
1948       strcpy(pickfunc, hidefunc);
1949       hidefunc[0]=0;
1950       mode[0]=hidemode[0];
1951       mode[1]=hidemode[1];
1952       return;
1953     }
1954     delSet(specialset->highl);
1955     dx_cur=PICK_LENGTH; dy_cur=PICK_LENGTH;
1956     glutSetWindow( w1);
1957     /* glutPassiveMotionFunc ( NULL ); */   /* schaltet mitgehenden Fangrahmen aus */
1958     free(selectBuf); selectBuf=NULL;
1959     glutKeyboardFunc ( Keyboard );    /* Keyboardfunkt wiederherstellen (von pick())  */
1960     glutSetWindow( activWindow );
1961     pickFlag=0;
1962     qbiaFlag=0;
1963     qdisFlag=0;
1964     intersectFlag=0;
1965     anz_c=0;
1966     entitybuf=-1;
1967     pntNr=-1;
1968     lineNr=-1;
1969     surfNr=-1;
1970     nurbsNr=-1;
1971     shapeNr=-1;
1972     bodyNr=-1;
1973     qaddTol=-1;
1974     if (compare(pickfunc, "qsur", 4) == 4)
1975     {
1976       anz_c=0;
1977       for (i=0; i<EDGES_PER_SURF; i++) anz_lpc[i]=0;
1978     }
1979     else if (compare(pickfunc, "qflp", 4) == 4) { free(selem); selem=NULL; }
1980     else if (compare(pickfunc, "qmsh", 4) == 4)
1981     {
1982       delSet("-qmsh");
1983       delSet("-setdiv");
1984       setNrdiv=-1;
1985       /* switch to original nr of thread */
1986       anz->threads=anz_threads;
1987     }
1988 
1989     if(getSetNr(specialset->tmp)>-1) delSet(specialset->tmp);
1990 
1991     pickfunc[0]='\0';
1992     printf (" done\n");
1993     return;
1994   }
1995 
1996   /* create a pset for the selected entity and display it in magenta */
1997   delSet(specialset->highl);
1998 
1999   if ((pset = (Psets *)realloc( (Psets *)pset, (anzGeo->psets+1)*sizeof(Psets)) ) == NULL )
2000   {
2001     printf(" ERROR: realloc failure in plot, pset not installed\n\n");
2002     return;
2003   }
2004   set_highl= pre_seta( specialset->highl, "i", 0 );
2005   pset[anzGeo->psets].nr= set_highl;
2006   pset[anzGeo->psets].type[1]='\0';
2007   pset[anzGeo->psets].width=0;
2008 
2009   if (compare(pickfunc, "qsur", 4) == 4) { if(type[0]=='s') pset[anzGeo->psets].type[0]='s'; else pset[anzGeo->psets].type[0]= 'l'; }
2010   else if (compare(pickfunc, "qlin", 4) == 4) pset[anzGeo->psets].type[0]= 'p';
2011   else pset[anzGeo->psets].type[0]= tolower(gkey);
2012 
2013   if (pset[anzGeo->psets].type[0]=='p'||pset[anzGeo->psets].type[0]=='l'||pset[anzGeo->psets].type[0]=='s'||pset[anzGeo->psets].type[0]=='b') pset[anzGeo->psets].type[1]= 'a';
2014 
2015   pset[anzGeo->psets].col=7;
2016   anzGeo->psets++;
2017   glutPostRedisplay();
2018 
2019   /* Action: Look what should be done */
2020   if ( type[0] == 'r') /*  new pick-area, print x,y */
2021   {
2022     xcur[ii]=x; ycur[ii]=y;
2023     if (ii)
2024     {
2025       ii=0;
2026       dx_cur= xcur[1]-xcur[0];
2027       dx_cur= sqrt( dx_cur*dx_cur );
2028       dy_cur= ycur[1]-ycur[0];
2029       dy_cur= sqrt( dy_cur*dy_cur );
2030       printf (" cursorArea set to dx_cur=%lf dy_cur=%lf\n", dx_cur, dy_cur);
2031     }
2032     else
2033       ii=1;
2034     return;
2035   }
2036   else if ( type[0] == 'w') /* show window koordinates */
2037   {
2038     xw[wtogle]=(double)x/width_w1*scale->w*2.*ds * aspectRatio_w1;
2039     yw[wtogle]=(double)y/width_w1*scale->w*2.*ds * aspectRatio_w1;
2040     if (wtogle)
2041     {
2042       dist=sqrt( (xw[1]-xw[0])*(xw[1]-xw[0]) + (yw[1]-yw[0])*(yw[1]-yw[0]) );
2043       printf (" P2 xw:%lf yw:%lf \n", xw[wtogle], yw[wtogle] );
2044       printf (" distance: %e \n", dist);
2045       wtogle=0;
2046     }
2047     else
2048     {
2049       printf (" P1 xw:%lf yw:%lf \n", xw[wtogle], yw[wtogle]);
2050       wtogle=1;
2051     }
2052     return;
2053   }
2054 
2055 
2056   else if ((compare(pickfunc, "qenq", 4) == 4)||(compare(pickfunc, "qadd", 4) == 4)||
2057            (compare(pickfunc, "qdis", 4) == 4)||
2058            (compare(pickfunc, "qrem", 4) == 4)||(compare(pickfunc, "qdel", 4) == 4))
2059   {
2060     if ( type[0] == 't') /*  change to "qtxt" */
2061     {
2062       printf ("mode:%c\n", 't');
2063       strcpy(hidefunc, pickfunc);
2064       strcpy(pickfunc, "qtxt");
2065       printf(" change to %s\n", pickfunc );
2066       hidemode[0]=mode[0];
2067       hidemode[1]=mode[1];
2068       mode[0]='i';
2069       moveText(anz->t-1, x, y);
2070       return;
2071     }
2072     if ( type[0] == 'a') /*  pick all in range mode */
2073     {
2074       mode[0]='a';
2075       printf ("mode:%s\n", mode);
2076       return;
2077     }
2078     if ( type[0] == 'i') /* individual pick mode */
2079     {
2080       mode[0]='i';
2081       dx_cur=PICK_LENGTH; dy_cur=PICK_LENGTH;
2082       printf ("mode:%s\n", mode);
2083       return;
2084     }
2085     if ( type[0] == 'c')
2086     {
2087       /*  center-point for qdis */
2088       if(compare(pickfunc, "qdis", 4) == 4)
2089       {
2090         type[1]=type[0];
2091         if(qdisFlag!=2) type[0]='p';
2092         else type[0]='n';
2093       }
2094       /*  lcmb in qadd, qdel and qrem */
2095       if((compare(pickfunc, "qenq", 4) == 4)||(compare(pickfunc, "qadd", 4) == 4)||(compare(pickfunc, "qrem", 4) == 4)||(compare(pickfunc, "qdel", 4) == 4))
2096       {
2097         type[1]=type[0];
2098         type[0]='l';
2099       }
2100     }
2101     if ( type[0] == 'g')
2102     {
2103       /*  pick points to define a plane for qdis */
2104       if(compare(pickfunc, "qdis", 4) == 4)
2105       {
2106         type[1]='h';
2107         type[0]='p';
2108       }
2109     }
2110     if ( type[0] == 'm')
2111     {
2112       /*  pick nodes to define a plane for qdis */
2113       if(compare(pickfunc, "qdis", 4) == 4)
2114       {
2115         type[1]='h';
2116         type[0]='n';
2117       }
2118       else
2119       {
2120         /*  search max/min-value at nodes in qenq */
2121         mode[0]='m';
2122         printf ("mode:%s\n", mode);
2123         minus("nt all    \n");
2124         plus("nt all k   \n");
2125         return;
2126       }
2127     }
2128 
2129     if ( mode[0] == 'm')
2130     {
2131       type[1]=type[0];
2132       type[0]='n';
2133     }
2134 
2135     if (compare(pickfunc, "qdel", 4) == 4) {
2136       if((type[0]=='n')||(type[0]=='e')||(type[0]=='p')||(type[0]=='h')||(type[0]=='l')||(type[0]=='s')||(type[0]=='b')
2137         ||(type[0]=='L')||(type[0]=='S'))
2138       {
2139         if(getSetNr(specialset->zap)>-1) delSet( specialset->zap);
2140         setNrbuf=pre_seta(specialset->zap, "i", 0 );
2141         if(setNrbuf<0) { errMsg(" ERROR: could not create set for qdel\n"); return; }
2142         goPicking(x,y,type);
2143         zap(set[setNrbuf].name);
2144       }
2145     }
2146     else goPicking(x,y,type);
2147 
2148     if ((compare(pickfunc, "qadd", 4) == 4)&&(qaddTol>-1))
2149     {
2150       /* complete the set by all connected faces which do not violate the tolerance */
2151       completeFacesByTolerance(set_highl, setNrbuf, qaddTol);
2152     }
2153 
2154     if ((compare(pickfunc, "qadd", 4) == 4)||(compare(pickfunc, "qrem", 4) == 4)||(compare(pickfunc, "qdel", 4) == 4))
2155       if (type[0]=='e') updateDispLists();
2156     type[1]=type[0]=0;
2157   }
2158 
2159   else if ((compare(pickfunc, "qdiv", 4) == 4)||(compare(pickfunc, "qbia", 4) == 4))
2160   {
2161     if ( type[0] == 'a') /*  pick all in range mode */
2162     {
2163       mode[0]='a';
2164       printf ("mode:%s\n", mode);
2165       return;
2166     }
2167     else if ( type[0] == 'i') /* individual pick mode */
2168     {
2169       mode[0]='i';
2170       dx_cur=PICK_LENGTH; dy_cur=PICK_LENGTH;
2171       printf ("mode:%s\n", mode);
2172       return;
2173     }
2174 
2175     else if( type[0] == 'c')
2176     {
2177       if(compare(pickfunc, "qbia", 4) == 4) /* change the bias-direction */
2178       {
2179         type[3]='c';
2180         type[0]='l';
2181       }
2182     }
2183     else if( type[0] == ' ')
2184     {
2185         xbuf=x; ybuf=y;
2186         printf(" define 2 digits Div: \n");
2187         glutKeyboardFunc(defineDiv);
2188         return;
2189     }
2190     else
2191     {
2192       /* look if we have a valid integer > 0, then pick a line */
2193       type[1] = ' ';
2194       icor=atoi(type);
2195       if (( icor <1 )||( icor >9 ))
2196       {
2197         printf(" Key not known\n");
2198         return;
2199       }
2200       type[0]='l';
2201       pickbuf=icor;
2202     }
2203     goPicking(x,y,type);
2204   }
2205 
2206   else if (compare(pickfunc, "qcnt", 4) == 4)
2207   {
2208     if((type[0]=='n')||(type[0]=='p'))
2209       goPicking(x,y,type);
2210   }
2211   else if (compare(pickfunc, "qnor", 4) == 4)
2212   {
2213     if(type[0]=='p')
2214     {
2215       if(qnorCounter>1)
2216       {
2217         xbuf=x; ybuf=y;
2218         printf(" Displacement: \n");
2219         glutKeyboardFunc(defineValue);
2220         return;
2221       }
2222       goPicking(x,y,type);
2223     }
2224   }
2225 
2226   else if (compare(pickfunc, "qsur", 4) == 4)
2227   {
2228     /* create a gsur */
2229     if ( type[0] == 'a') /*  pick all in range mode */
2230     {
2231       mode[0]='a';
2232       printf ("mode:%s\n", mode);
2233       return;
2234     }
2235     if ( type[0] == 'i') /* individual pick mode */
2236     {
2237       mode[0]='i';
2238       dx_cur=PICK_LENGTH; dy_cur=PICK_LENGTH;
2239       printf ("mode:%s\n", mode);
2240       return;
2241     }
2242 
2243     if(type[0]=='b')
2244     {
2245       type[0]='s'; type[1]='b';
2246       goPicking(x,y,type);
2247     }
2248     else if(type[0]=='c') { printf (" default shape, nurbs and surface reseted\n"); nurbsNr=shapeNr=surfNr=-1; }
2249     else if(type[0]=='l') { type[0]='l'; type[1]='l'; goPicking(x,y,type); }
2250     else if(type[0]=='s') { type[0]='s'; type[1]='s'; goPicking(x,y,type); }
2251     else if(type[0]=='h') { type[0]='s'; type[1]='h'; goPicking(x,y,type); }
2252     else if(type[0]=='S') { type[0]='s'; type[1]='S'; goPicking(x,y,type); }
2253     else if(type[0]=='g')
2254     {
2255       strcpy(ori, "+");
2256 
2257       /* if several lines where picked at once, generate a surf for unstructured meshing */
2258       if(pickdata[0])
2259       {
2260         printf ("generate surf ");
2261 
2262         if(pickdata[0]>=EDGES_PER_SURF)
2263 	{
2264           errMsg(" ERROR: more(%d) than %d edges defined, start again\n", pickdata[0], EDGES_PER_SURF);
2265           /* reset counters */
2266           anz_c=0;
2267           pickdata[0]=0;
2268           return;
2269 	}
2270 
2271         /* to avoid multiple lines store them in a temporary set */
2272         linbuf=pre_seta("-qsurl","i",0);
2273         for (i=0; i<pickdata[0]; i++) seta (linbuf,"l",pickdata[i+1]);
2274         anz_c=set[linbuf].anz_l;
2275         for(i=0; i<anz_c; i++)
2276         {
2277           strcpy( cori[i], "+");
2278           edge[i]=set[linbuf].line[i];
2279           ctyp[i]='l';
2280         }
2281         delSet("-qsurl");
2282 
2283         /* try to generate a new surface in any case */
2284         getNewName( name, "s" );
2285         entitybuf= surface_i( name, ori[0], shapeNr, anz_c, &cori[0][0], edge, ctyp );
2286 
2287         if (entitybuf>-1)
2288         {
2289           /* if a surface was pre-selected to be updated delete the new one and continue */
2290           if(surfNr>-1)
2291           {
2292             delSurf( 1, &entitybuf );
2293             /* surfNr will be used as a name for the next generated surface and the original surface will be destroyed. The buffer is then reseted */
2294             strcpy(name,surf[surfNr].name); ori[0]=surf[surfNr].ori; shbuf=surf[surfNr].sh; surfNr=-1;
2295             entitybuf= surface_i( name, ori[0], shbuf, anz_c, &cori[0][0], edge, ctyp );
2296             if (entitybuf>-1) printf (" name: %s elty:%d\n", name, surf[entitybuf].etyp );
2297             else printf(" failed\n");
2298           }
2299           else
2300 	  {
2301             printf (" name: %s elty: tr6u\n", name );
2302 
2303             /* set the element type to tr6u */
2304             surf[entitybuf].etyp=8;
2305             surf[entitybuf].eattr=-1;
2306             if(surfToShape(entitybuf)<0)
2307             {
2308               errMsg("\n WARNING: shape could not be defined. Therefore elty tr6u will not be possible if no shape or nurbs will be assigned manually. Check if all points exist in one common plane.\n\n");
2309 	    }
2310 	  }
2311 	}
2312         else printf(" failed\n");
2313 
2314         /* reset counters */
2315         anz_c=0;
2316         pickdata[0]=0;
2317 
2318         return;
2319       }
2320 
2321       /* look if we have the right amount of edges */
2322       if(anz_c<3)
2323       {
2324           errMsg(" ERROR: less(%d) than %d edges defined, start again\n", anz_c, 3);
2325           /* reset counters */
2326           anz_c=0;
2327           pickdata[0]=0;
2328         return;
2329       }
2330       if( anz_c>=EDGES_PER_SURF-1)
2331       {
2332         errMsg("ERROR: more(%d) than %d edges defined, start again\n", anz_c, EDGES_PER_SURF-1);
2333         anz_c=0;
2334         for (i=0; i<EDGES_PER_SURF; i++)
2335           anz_lpc[i]=0;
2336         return;
2337       }
2338       /* look if all edges are propperly defined */
2339       for (i=0; i<anz_c; i++)
2340       {
2341         if (anz_lpc[i]<1)
2342 	{
2343           printf("ERROR: define edge Nr:%d\n", i+1);
2344           return;
2345         }
2346       }
2347       printf ("generate surf ");
2348       anz_newc=0;
2349       for (i=0; i<anz_c; i++)
2350       {
2351         strcpy( cori[i], "+");
2352         if (anz_lpc[i]==1)                 /* we have a single line */
2353 	{
2354           nr=clines[i][0];
2355           edge[i]=nr;
2356           ctyp[i]='l';
2357         }
2358         else                               /* we need a lcmb */
2359 	{
2360           /* do we already have a suitable lcmb? */
2361           flag=0;
2362           for (j=0; j<anzGeo->c; j++ )
2363 	  {
2364             if((lcmb[j].name != (char *)NULL)&&(lcmb[j].nl==anz_lpc[i]))   /* same amount of lines */
2365 	    {
2366               if (printFlag) printf ("check lcmb:%s \n", lcmb[j].name);
2367 
2368               if((alreadyChecked=(char *)realloc((char *)alreadyChecked,(anz_lpc[i])*sizeof(char)))==NULL)
2369               { printf(" ERROR: realloc failure in pick()\n\n"); return; }
2370 	      for (k=0; k<anz_lpc[i]; k++) alreadyChecked[k]=0; /* reset */
2371               for (n=0; n<lcmb[j].nl; n++)
2372 	      {
2373                 flag=0;
2374                 for (k=0; k<anz_lpc[i]; k++)
2375 		{
2376 		  /*
2377                   printf ("c:%s == l:%s\n", line[lcmb[j].l[n]].name, line[clines[i][k]].name);
2378 		  */
2379                   if ((lcmb[j].l[n]==clines[i][k])&&(alreadyChecked[k]==0))
2380                   {
2381                     flag=1;               /* share that line */
2382                     alreadyChecked[k]=1;
2383                   }
2384 		}
2385                 if (!flag) goto not_equal_lcmb;
2386 	      }
2387 
2388               if (printFlag) printf ("equal\n");
2389 
2390               break;
2391 	    }
2392             else flag=0;
2393             not_equal_lcmb:;
2394 	  }
2395 
2396           if (!flag)  /* no lcmb was found, so create one */
2397 	  {
2398             if((lori=(char *)realloc((char *)lori, (anz_lpc[i])*sizeof(char)) ) == NULL )
2399             { printf(" ERROR: realloc failure in pick()\n\n"); return; }
2400             for (j=0; j<anz_lpc[i]; j++) lori[j]='+';
2401             getNewName( name, "c" );
2402             n=lcmb_i( name, 0, anz_lpc[i], lori, clines[i] );
2403             if(n <0 )
2404             {
2405               errMsg ("ERROR: lcmb in error, start again\n");
2406               anz_c=0;
2407               for (j=0; j<EDGES_PER_SURF; j++) anz_lpc[j]=0;
2408               return;
2409             }
2410             edge[i]=n;
2411             newc[anz_newc++]=n;
2412             ctyp[i]='c';
2413 	  }
2414           else
2415 	  {
2416             if (printFlag) printf ("use existing lcmb:%s nr:%d from %d\n", lcmb[j].name,j,anzGeo->c );
2417             edge[i]=j;
2418             ctyp[i]='c';
2419           }
2420         }
2421       }
2422 
2423       /* try to generate a new surface in any case */
2424       getNewName( name, "s" );
2425       entitybuf= surface_i( name, ori[0], shapeNr, anz_c, &cori[0][0], edge, ctyp );
2426 
2427       if (entitybuf>-1)
2428       {
2429         /* if a surface was pre-selected to be updated delete the new one and continue */
2430         if(surfNr>-1)
2431         {
2432           delSurf( 1, &entitybuf );
2433           /* surfNr will be used as a name for the next generated surface and the original surface will be destroyed. The buffer is then reseted */
2434           strcpy(name,surf[surfNr].name); ori[0]=surf[surfNr].ori; shapeNr=surf[surfNr].sh; surfNr=-1;
2435           entitybuf= surface_i( name, ori[0], shapeNr, anz_c, &cori[0][0], edge, ctyp );
2436           if (entitybuf>-1) printf (" name: %s elty:%d\n", name, surf[entitybuf].etyp );
2437           else  printf(" failed\n");
2438         }
2439         else
2440 	{
2441           if (entitybuf>-1) printf (" name: %s elty:%d\n", name, surf[entitybuf].etyp );
2442           else  printf(" failed\n");
2443         }
2444       }
2445       else
2446       {
2447         /* delete new lcmbs */
2448         if(anz_newc) delLcmb( anz_newc, newc );
2449       }
2450       /* reset counters */
2451       anz_c=0;
2452       for (i=0; i<EDGES_PER_SURF; i++) anz_lpc[i]=0;
2453     }
2454 
2455     /* look if we have a valid integer < 0, then pick a line */
2456     type[1]='\0';
2457     icor=atoi(type)-1;
2458     if (icor>=EDGES_PER_SURF-1)
2459     {
2460       errMsg ("ERROR: Only %d edges per surface possible (not:%s!)\n", EDGES_PER_SURF-1, type);
2461       return;
2462     }
2463     if ( icor>=0 )
2464     {
2465       if( icor>=anz_c) anz_c=icor+1;
2466       type[0]='l';
2467       goPicking(x,y,type);
2468       nr=getLineNr(type);
2469       if ( nr>-1)          /* picking was successfull */
2470       {
2471         printf ("sum_edges:%d actual_edge:%d lines:%d Name:%s index:%d\n",
2472                anz_c, icor+1, anz_lpc[icor], type, clines[icor][anz_lpc[icor]]);
2473 
2474         /* check if this line was already selected */
2475         flag=0;
2476         for (i=0; i<anz_c; i++)
2477           for (k=0; k<anz_lpc[i]; k++)
2478               if (nr==clines[i][k]) { flag=1; break; }
2479         if(!flag)
2480         {
2481           clines[icor][anz_lpc[icor]]=nr;
2482           anz_lpc[icor]++;
2483         }
2484       }
2485       else
2486         errMsg ("WARNING: No line picked, please try again! \n");
2487     }
2488   }
2489 
2490   else if (compare(pickfunc, "qbod", 4) == 4)
2491   {
2492     /* create a gbod */
2493 
2494     if ( type[0] == 'a') /*  pick all in range mode */
2495     {
2496       mode[0]='a';
2497       printf ("mode:%s\n", mode);
2498     }
2499     else if ( type[0] == 'i') /* individual pick mode */
2500     {
2501       mode[0]='i';
2502       dx_cur=PICK_LENGTH; dy_cur=PICK_LENGTH;
2503       printf (" mode:%s\n", mode);
2504     }
2505 
2506     else if ( type[0] == 'b') /* get a body to replace */
2507     {
2508       goPicking(x,y,type);
2509     }
2510     else if(type[0]=='g')
2511     {
2512       if(bodyNr==-1) getNewName( name, "b" );
2513       else { strcpy(name,body[bodyNr].name); bodyNr=-1; }
2514       printf (" generate body:%s\n", name);
2515 
2516       /* look if we have the right amount of faces */
2517       if( anz_c==2)
2518       {
2519         /* try to create the missing surfs */
2520         entitybuf=body_( name, &face[0][0] );
2521       }
2522       else
2523       {
2524         strcpy( blend, "NORM");
2525         for (i=0; i<anz_c; i++) strcpy( &cori[i][0], "+");
2526         entitybuf=gbod( name, blend, anz_c, &cori[0][0], &face[0][0] );
2527       }
2528 
2529       /* reset counters */
2530       anz_c=0;
2531       pickdata[0]=0;
2532       pick_buffer=0;
2533     }
2534 
2535     else if((type[0]=='s')||(type[0]=='S'))
2536     {
2537       goPicking(x,y,type);
2538       if(pickdata[0]>SURFS_PER_BODY)
2539       {
2540         printf(" ERROR: too many surfaces selected:%d. SURFS_PER_BODY in cgx.h must be increased.\n", pickdata[0]);
2541         return;
2542       }
2543       for (i=0; i<pickdata[0]; i++)
2544       {
2545         nr=getSurfNr(surf[pickdata[i+1]].name);
2546         if (nr>-1)
2547         {
2548           strcpy( face[i+anz_c], surf[pickdata[i+1]].name );
2549           printf (" sum:%d face:%d surf:%s \n", i+1+anz_c, pickdata[i+1], face[i+anz_c]);
2550         }
2551         else
2552           printf("pick failed, surf not known\n");
2553       }
2554       anz_c+=i;
2555       pickdata[0]=0;
2556     }
2557   }
2558 
2559   else if (compare(pickfunc, "qlin", 4) == 4)
2560   {
2561     if ( type[0] == 'a') /*  pick all in range mode */
2562     {
2563       mode[0]='a';
2564       printf ("mode:%s\n", mode);
2565       return;
2566     }
2567     if ( type[0] == 'i') /* individual pick mode */
2568     {
2569       mode[0]='i';
2570       dx_cur=PICK_LENGTH; dy_cur=PICK_LENGTH;
2571       printf ("mode:%s\n", mode);
2572       return;
2573     }
2574 
2575     /*  type[0] l:end a line b:start a line c:add centerpoint etc. */
2576     if(type[0]=='l')
2577     {
2578       type[1]=type[0];
2579       goPicking(x,y,type);
2580     }
2581     else if((type[0]=='g')||(type[0]=='b')||(type[0]=='c')||(type[0]=='m')||(type[0]=='t'))
2582     {
2583       type[1]=type[0];
2584       type[0]='p';
2585       goPicking(x,y,type);
2586     }
2587     else if( type[0] == 'p')
2588     {
2589         xbuf=x; ybuf=y;
2590         printf(" Displacement: \n");
2591         glutKeyboardFunc(defineValue);
2592         return;
2593     }
2594     else if(type[0]=='s')
2595     {
2596       qspl_i=0;           /* forget the splitted lines */
2597       if(getSetNr(specialset->tmp)>-1) delSet(specialset->tmp);
2598       setNrbuf=pre_seta(specialset->tmp, "i", 0 );
2599       if(setNrbuf<0) { errMsg(" ERROR: could not create set for qdel\n"); return; }
2600       type[1]=type[0];
2601       type[0]='l';
2602       goPicking(x,y,type);
2603     }
2604     else if(type[0]=='x')
2605     {
2606       type[1]=type[0];
2607       type[0]='l';
2608       goPicking(x,y,type);
2609     }
2610     else if(type[0]=='e')
2611     {
2612       i=mode[0];
2613       mode[0]='a';
2614       type[1]=type[0];
2615       type[0]='l';
2616       goPicking(x,y,type);
2617       mode[0]=i;
2618     }
2619   }
2620 
2621   else if (compare(pickfunc, "qali", 4) == 4)
2622   {
2623     if((type[0]=='n')||(type[0]=='p'))
2624       goPicking(x,y,type);
2625   }
2626 
2627   else if (compare(pickfunc, "qcut", 4) == 4)
2628   {
2629     type[1]=type[0];
2630     if(type[0]=='v')
2631     {
2632       type[0]='n';
2633     }
2634     if((type[0]=='n')||(type[0]=='p'))
2635       goPicking(x,y,type);
2636   }
2637 
2638   /*
2639   used
2640     a,b,c,d,e,f,h,i,1,m,n,(q),s,v.X.*./, ,'0-9H
2641   unused
2642     9,j,k,0,p.r,t,u,w,y,z
2643   */
2644   else if (compare(pickfunc, "qmsh", 4) == 4)
2645   {
2646     if ( type[0] == 'a') /*  pick all in range mode */
2647     {
2648       mode[0]='a';
2649       printf ("mode:%s\n", mode);
2650       return;
2651     }
2652     if ( type[0] == 'i') /* individual pick mode */
2653     {
2654       mode[0]='i';
2655       dx_cur=PICK_LENGTH; dy_cur=PICK_LENGTH;
2656       printf ("mode:%s\n", mode);
2657       return;
2658     }
2659 
2660     if ( type[0] == 'f') /* generate shell element, after node selection with n */
2661     {
2662       createElem(-1);
2663       delSet("-qmsh");
2664       delSet("-setdiv");
2665       setNrdiv=-1;
2666       return;
2667     }
2668     if ( type[0] == 'v') /* generate volume element, after node selection with n */
2669     {
2670       createElem(-2);
2671       delSet("-qmsh");
2672       delSet("-setdiv");
2673       setNrdiv=-1;
2674       return;
2675     }
2676 
2677     if ( type[0] == 'b') /* break (split) the pre-selected surface */
2678     {
2679       if((keybuf!='s')&&(keybuf!='e'))
2680       {
2681         /* switch from qlin to qbia mode */
2682         if(set[qmshbuf].anz_l) qbiaFlag=1;
2683         else printf(" WARNING: The last selected entity must be the surf to split\n");
2684         return;
2685       }
2686       /* delete the mesh */
2687       if((!qmshbuf)||((!set[qmshbuf].anz_l)&&(!set[qmshbuf].anz_s))) { printf(" WARNING: Nothing selected\n"); return; }
2688       sprintf(buffer,"me %s", set[qmshbuf].name);
2689       pre_del(buffer);
2690       for(i=0; i<set[qmshbuf].anz_l; i++)
2691       {
2692         printf("del mesh line %s\n",line[set[qmshbuf].line[i]].name);
2693         line[set[qmshbuf].line[i]].nn=0;
2694         line[set[qmshbuf].line[i]].ne=0;
2695       }
2696       for(i=0; i<set[qmshbuf].anz_s; i++)
2697       {
2698         printf("del mesh surf %s\n",surf[set[qmshbuf].surf[i]].name);
2699         surf[set[qmshbuf].surf[i]].nn=0;
2700         surf[set[qmshbuf].surf[i]].ne=0;
2701       }
2702       /* split the surface */
2703       if(keybuf=='e') entitybuf=set[qmshbuf].surf[0];
2704       printf("break (split) surface %s with line:%s\n", surf[entitybuf].name, line[set[qmshbuf].line[set[qmshbuf].anz_l-1]].name);
2705       i=splitSurf( set[qmshbuf].line[set[qmshbuf].anz_l-1], entitybuf );
2706       if(i<0) { printf(" ERROR:%d: could not split the selected surface\n",i); }
2707       else
2708       {
2709         /* mesh again */
2710         seta(qmshbuf,"s",i);
2711         for(i=0; i<set[qmshbuf].anz_s; i++)
2712         {
2713           printf("mesh %s\n",surf[set[qmshbuf].surf[i]].name);
2714         }
2715         completeSet(set[qmshbuf].name, "do");
2716         pre_mesh( set[qmshbuf].name );
2717         sprintf(buffer,"n %s",set[qmshbuf].name);
2718         pre_merge(buffer);
2719         printf(" %d edges in the model\n", anz->g);
2720       }
2721       delSet("-qmsh");
2722       delSet("-setdiv");
2723       setNrdiv=-1;
2724       return;
2725     }
2726 
2727     /* skip if in qbia mode */
2728     if (( type[0] == 'c')&&(qbiaFlag));
2729     /* combine pre-selected surfaces */
2730     else if ( type[0] == 'c')
2731     {
2732       if((!qmshbuf)||((!set[qmshbuf].anz_l)&&(!set[qmshbuf].anz_s))) { printf(" WARNING: Nothing selected\n"); return; }
2733       sprintf(buffer,"me %s", set[qmshbuf].name);
2734       pre_del(buffer);
2735       for(i=0; i<set[qmshbuf].anz_l; i++)
2736       {
2737         printf("del mesh line %s\n",line[set[qmshbuf].line[i]].name);
2738         line[set[qmshbuf].line[i]].nn=0;
2739         line[set[qmshbuf].line[i]].ne=0;
2740       }
2741       for(i=0; i<set[qmshbuf].anz_s; i++)
2742       {
2743         printf("del mesh surf %s\n",surf[set[qmshbuf].surf[i]].name);
2744         surf[set[qmshbuf].surf[i]].nn=0;
2745         surf[set[qmshbuf].surf[i]].ne=0;
2746       }
2747       /* combine the surfaces */
2748       for(i=0; i<set[qmshbuf].anz_s; i++)
2749       {
2750         printf("combine surfs %s\n", surf[set[qmshbuf].surf[i]].name);
2751       }
2752       i=combineSurfs( qmshbuf );
2753       if(i==-2) printf(" ERROR: could not combine the selected surfaces, they are of type'BLEND' \n");
2754       else if(i<0) printf(" ERROR: could not combine the selected surfaces\n");
2755       else
2756       {
2757         /* mesh again */
2758         seta(qmshbuf,"s",i);
2759         for(i=0; i<set[qmshbuf].anz_s; i++)
2760         {
2761           printf("mesh %s\n",surf[set[qmshbuf].surf[i]].name);
2762         }
2763         completeSet(set[qmshbuf].name, "do");
2764         pre_mesh( set[qmshbuf].name );
2765         sprintf(buffer,"n %s",set[qmshbuf].name);
2766         pre_merge(buffer);
2767         printf(" %d edges in the model\n", anz->g);
2768       }
2769       delSet("-qmsh");
2770       delSet("-setdiv");
2771       setNrdiv=-1;
2772       return;
2773     }
2774 
2775     if ( type[0] == 'm') /* mesh the pre-selected entities (l,s) */
2776     {
2777       if((!qmshbuf)||((!set[qmshbuf].anz_l)&&(!set[qmshbuf].anz_s))) { printf(" WARNING: Nothing selected\n"); return; }
2778       for(i=0; i<set[qmshbuf].anz_s; i++)
2779       {
2780         printf("mesh %s\n",surf[set[qmshbuf].surf[i]].name);
2781       }
2782       completeSet(set[qmshbuf].name, "do");
2783       pre_mesh( set[qmshbuf].name );
2784       sprintf(buffer,"n %s",set[qmshbuf].name);
2785       pre_merge(buffer);
2786         printf(" %d edges in the model\n", anz->g);
2787       delSet("-qmsh");
2788       delSet("-setdiv");
2789       setNrdiv=-1;
2790       return;
2791     }
2792 
2793     if ( type[0] == 'd') /* delete the mesh of the pre-selected entities */
2794     {
2795       if((!qmshbuf)||((!set[qmshbuf].anz_l)&&(!set[qmshbuf].anz_s))) { printf(" WARNING: Nothing selected\n"); return; }
2796       sprintf(buffer,"me %s", set[qmshbuf].name);
2797       pre_del(buffer);
2798       for(i=0; i<set[qmshbuf].anz_l; i++)
2799       {
2800         printf("del mesh line %s\n",line[set[qmshbuf].line[i]].name);
2801         line[set[qmshbuf].line[i]].nn=0;
2802         line[set[qmshbuf].line[i]].ne=0;
2803       }
2804       for(i=0; i<set[qmshbuf].anz_s; i++)
2805       {
2806         printf("del mesh surf %s\n",surf[set[qmshbuf].surf[i]].name);
2807         surf[set[qmshbuf].surf[i]].nn=0;
2808         surf[set[qmshbuf].surf[i]].ne=0;
2809       }
2810       printf(" selection still active!\n");
2811       //delSet("-qmsh");
2812       return;
2813     }
2814 
2815     if( type[0] == 'x') /* change the mesh attribute of the pre-selected surfaces */
2816     {
2817       if((!qmshbuf)||(!set[qmshbuf].anz_s)) { printf(" WARNING: No surfaces selected\n"); return; }
2818       /* change the element attribute */
2819       for ( i=0; i<set[qmshbuf].anz_s; i++)
2820       {
2821         nr=set[qmshbuf].surf[i];
2822         if(surf[nr].etyp==0) surf[nr].etyp=8;
2823         if(surf[nr].eattr==0) surf[nr].eattr=-1; else surf[nr].eattr=0;
2824       }
2825       /* delete the mesh */
2826       sprintf(buffer,"me %s", set[qmshbuf].name);
2827       pre_del(buffer);
2828       for(i=0; i<set[qmshbuf].anz_l; i++)
2829       {
2830         printf("del mesh line %s\n",line[set[qmshbuf].line[i]].name);
2831         line[set[qmshbuf].line[i]].nn=0;
2832         line[set[qmshbuf].line[i]].ne=0;
2833       }
2834       for(i=0; i<set[qmshbuf].anz_s; i++)
2835       {
2836         printf("del mesh surf %s\n",surf[set[qmshbuf].surf[i]].name);
2837         surf[set[qmshbuf].surf[i]].nn=0;
2838         surf[set[qmshbuf].surf[i]].ne=0;
2839       }
2840       /* mesh again */
2841       for(i=0; i<set[qmshbuf].anz_s; i++)
2842       {
2843         printf("mesh %s\n",surf[set[qmshbuf].surf[i]].name);
2844       }
2845       completeSet(set[qmshbuf].name, "do");
2846       pre_mesh( set[qmshbuf].name );
2847       sprintf(buffer,"n %s",set[qmshbuf].name);
2848       pre_merge(buffer);
2849         printf(" %d edges in the model\n", anz->g);
2850       // free qmshbuf
2851       delSet("-qmsh");
2852       delSet("-setdiv");
2853       setNrdiv=-1;
2854       return;
2855     }
2856 
2857     if(( type[0] == 'h')||( type[0] == 't')) /* increase or decrease the mesh-density of the pre-selected surfaces */
2858     {
2859       if((!qmshbuf)||(!set[qmshbuf].anz_s)) { printf(" WARNING: No surfaces selected\n"); return; }
2860       /* change the mesh density attribute */
2861       if ( type[0] == 'h') dist=0.8; else dist=1.2;
2862       for ( i=0; i<set[qmshbuf].anz_s; i++)
2863       {
2864         nr=set[qmshbuf].surf[i];
2865         if(surf[nr].eparm!=(char *)NULL) sprintf(blend,"%.3f", atof(surf[nr].eparm) * dist);
2866         else
2867 	{
2868           sprintf(blend,"%.3f", dist);
2869 	}
2870         if((surf[nr].eparm= (char *)realloc((char *)surf[nr].eparm, (strlen(blend)+1)*sizeof(char))) == NULL )
2871         { printf("ERROR: malloc failed\n\n" ); return; }
2872         strcpy(surf[nr].eparm, blend);
2873       }
2874       /* delete the mesh */
2875       sprintf(buffer,"me %s", set[qmshbuf].name);
2876       pre_del(buffer);
2877       for(i=0; i<set[qmshbuf].anz_l; i++)
2878       {
2879         printf("del mesh line %s\n",line[set[qmshbuf].line[i]].name);
2880         line[set[qmshbuf].line[i]].nn=0;
2881         line[set[qmshbuf].line[i]].ne=0;
2882       }
2883       for(i=0; i<set[qmshbuf].anz_s; i++)
2884       {
2885         printf("del mesh surf %s\n",surf[set[qmshbuf].surf[i]].name);
2886         surf[set[qmshbuf].surf[i]].nn=0;
2887         surf[set[qmshbuf].surf[i]].ne=0;
2888       }
2889       /* mesh again */
2890       for(i=0; i<set[qmshbuf].anz_s; i++)
2891       {
2892         printf("mesh %s\n",surf[set[qmshbuf].surf[i]].name);
2893       }
2894       completeSet(set[qmshbuf].name, "do");
2895       pre_mesh( set[qmshbuf].name );
2896       sprintf(buffer,"n %s",set[qmshbuf].name);
2897       pre_merge(buffer);
2898         printf(" %d edges in the model\n", anz->g);
2899       // free qmshbuf
2900       delSet("-qmsh");
2901       delSet("-setdiv");
2902       setNrdiv=-1;
2903       return;
2904     }
2905 
2906     /* the following keys '*'|'/' must be used before the 'l' key to indicate that 'qdiv' (TBD) should multiply/divide the divisions */
2907     /* they will be reseted by ' '|'<nr' */
2908     if ( type[0] == '*') /* div of later selected lines are multiplied by the typed number */
2909     {
2910       qmshOperator='*';
2911       printf ("mode:%c\n", qmshOperator);
2912       return;
2913     }
2914     else if ( type[0] == '/') /* div of later selected lines are divided by the typed number */
2915     {
2916       qmshOperator='/';
2917       printf ("mode:%c\n", qmshOperator);
2918       return;
2919     }
2920 
2921     if (type[0]=='n')
2922     {
2923       goPicking(x,y,type);
2924     }
2925 
2926     if ((type[0]=='l')||(type[0]=='s')||(type[0]=='e'))
2927     {
2928       if(getSetNr(specialset->tmp)>-1) delSet( specialset->tmp);
2929       setNrbuf=pre_seta(specialset->tmp, "i", 0 );
2930       if(setNrbuf<0) { errMsg(" ERROR: could not create set\n"); return; }
2931       goPicking(x,y,type);
2932       //delSet("-setdiv");
2933       qmshbuf=pre_seta("-qmsh", "i", 0 );
2934       setNrdiv=pre_seta("-setdiv", "i", 0 );
2935 
2936       /* if an element was selected search the related surf and forget the element */
2937       if(type[0]=='e')
2938       {
2939         for ( i=0; i<set[setNrbuf].anz_e; i++)
2940         {
2941           k=-1;
2942           for (j=0; j<anzGeo->s; j++) if( surf[j].name != (char *)NULL )
2943           {
2944             if(ifind(&surf[j].elem, surf[j].ne, set[setNrbuf].elem[i])>-1)
2945             {
2946               k=j;
2947               break;
2948             }
2949           }
2950           if(k>-1)
2951 	  {
2952             printf(" +surf:%s\n",surf[j].name);
2953 	    seta( qmshbuf, "s", j );
2954             free(set[setNrbuf].elem);
2955             set[setNrbuf].elem=(int *)NULL;
2956             set[setNrbuf].anz_e = 0;
2957             break;
2958 	  }
2959 	}
2960       }
2961 
2962       /* search the surfaces for all selected lines and store the directly selected lines if div will be changed later */
2963       /* suche abhaengige lcmbs */
2964       for ( i=0; i<set[setNrbuf].anz_l; i++)
2965       {
2966         printf(" +line:%s\n",line[set[setNrbuf].line[i]].name);
2967         seta(qmshbuf, "l", set[setNrbuf].line[i] );
2968         seta(setNrdiv, "l", set[setNrbuf].line[i] );
2969         for (j=0; j<anzGeo->c; j++)
2970         {
2971           if( lcmb[j].name != (char *)NULL )
2972           for (n=0; n<lcmb[j].nl; n++)
2973           {
2974             if( set[setNrbuf].line[i] == lcmb[j].l[n] )
2975             {
2976               printf(" +lcmb:%s\n",lcmb[j].name);
2977               seta( qmshbuf, "c", j );
2978             }
2979           }
2980         }
2981       }
2982       for ( i=0; i<set[setNrbuf].anz_c; i++)
2983       {
2984         j=set[setNrbuf].lcmb[i];
2985         for (n=0; n<lcmb[j].nl; n++)
2986         {
2987           seta( qmshbuf, "l", lcmb[j].l[n] );
2988           printf(" +line %s\n",line[lcmb[j].l[n]].name);
2989         }
2990         for (j=0; j<anzGeo->s; j++)
2991         {
2992           if( surf[j].name != (char *)NULL )
2993           for (n=0; n<surf[j].nl; n++)
2994           {
2995             if(( set[setNrbuf].lcmb[i] == surf[j].l[n] )&&( surf[j].typ[n] == 'c' ))
2996             {
2997               seta( qmshbuf, "s", j);
2998               printf(" +surf %s\n",surf[j].name);
2999             }
3000           }
3001         }
3002       }
3003       for ( i=0; i<set[setNrbuf].anz_s; i++)
3004       {
3005         printf(" +surf %s\n",surf[set[setNrbuf].surf[i]].name);
3006         seta(qmshbuf, "s", set[setNrbuf].surf[i] );
3007       }
3008 
3009       /* now go over qmshbuf */
3010       for ( i=0; i<set[qmshbuf].anz_c; i++)
3011       {
3012         j=set[qmshbuf].lcmb[i];
3013         for (n=0; n<lcmb[j].nl; n++)
3014         {
3015           seta( qmshbuf, "l", lcmb[j].l[n] );
3016           printf(" +line %s\n",line[lcmb[j].l[n]].name);
3017         }
3018         for (j=0; j<anzGeo->s; j++)
3019         {
3020           if( surf[j].name != (char *)NULL )
3021           for (n=0; n<surf[j].nl; n++)
3022           {
3023             if(( set[qmshbuf].lcmb[i] == surf[j].l[n] )&&( surf[j].typ[n] == 'c' ))
3024             {
3025               seta( qmshbuf, "s", j);
3026               printf(" +surf %s\n",surf[j].name);
3027             }
3028           }
3029         }
3030       }
3031       for ( i=0; i<set[qmshbuf].anz_l; i++)
3032       {
3033         for (j=0; j<anzGeo->s; j++)
3034         {
3035           if( surf[j].name != (char *)NULL )
3036           for (n=0; n<surf[j].nl; n++)
3037           {
3038             if(( set[qmshbuf].line[i] == surf[j].l[n] )&&( surf[j].typ[n] == 'l' ))
3039             {
3040               seta( qmshbuf, "s", j);
3041               printf(" +surf %s\n",surf[j].name);
3042             }
3043           }
3044         }
3045       }
3046       if(getSetNr(specialset->tmp)>-1) delSet( specialset->tmp);
3047       return;
3048     }
3049 
3050     /* include the functionallity from qdiv */
3051     if(((type[0]>=48)&&(type[0]<=57))||(type[0]=='c'))
3052     {
3053       if(keybuf!='l') { printf(" WARNING: No line selected\n"); return; }
3054       if(setNrdiv==-1) return;
3055       /* delete the mesh */
3056       if((!qmshbuf)||((!set[qmshbuf].anz_l)&&(!set[qmshbuf].anz_s))) { printf(" WARNING: Nothing selected\n"); return; }
3057       sprintf(buffer,"me %s", set[qmshbuf].name);
3058       pre_del(buffer);
3059       for(i=0; i<set[qmshbuf].anz_l; i++)
3060       {
3061         printf("del mesh line %s\n",line[set[qmshbuf].line[i]].name);
3062         line[set[qmshbuf].line[i]].nn=0;
3063         line[set[qmshbuf].line[i]].ne=0;
3064       }
3065       for(i=0; i<set[qmshbuf].anz_s; i++)
3066       {
3067         printf("del mesh surf %s\n",surf[set[qmshbuf].surf[i]].name);
3068         surf[set[qmshbuf].surf[i]].nn=0;
3069         surf[set[qmshbuf].surf[i]].ne=0;
3070       }
3071       type[1] ='\0';
3072       icor=atoi(type);
3073       pickbuf=icor;
3074       if((qbiaFlag)&&(type[0]=='c'))
3075       {
3076         /* qbia change direction */
3077         for(i=0; i<set[setNrdiv].anz_l; i++)
3078         {
3079           line[set[setNrdiv].line[i]].bias=1./line[set[setNrdiv].line[i]].bias;
3080           repLine(set[setNrdiv].line[i]);
3081         }
3082       }
3083       else if(!qbiaFlag)
3084       {
3085         /* qdiv change division */
3086         type[0]='l';
3087         strcpy(pickfunc, "qdiv");
3088         goPicking(x,y,type);
3089         for(i=0; i<set[setNrdiv].anz_l; i++)
3090         {
3091           line[set[setNrdiv].line[i]].div=line[entitybuf].div;
3092           repLine(set[setNrdiv].line[i]);
3093         }
3094       }
3095       else
3096       {
3097         /* qbia */
3098         type[0]='l';
3099         strcpy(pickfunc, "qbia");
3100         goPicking(x,y,type);
3101         for(i=0; i<set[setNrdiv].anz_l; i++)
3102         {
3103           line[set[setNrdiv].line[i]].bias=line[entitybuf].bias;
3104           repLine(set[setNrdiv].line[i]);
3105         }
3106       }
3107       qmshOperator=0;
3108       qbiaFlag=0;
3109       strcpy(pickfunc, "qmsh");
3110       /* mesh again */
3111       if(set[qmshbuf].anz_s)
3112       {
3113         for(i=0; i<set[qmshbuf].anz_s; i++)
3114         {
3115           printf("mesh %s\n",surf[set[qmshbuf].surf[i]].name);
3116         }
3117         completeSet(set[qmshbuf].name, "do");
3118         pre_mesh( set[qmshbuf].name );
3119         sprintf(buffer,"n %s",set[qmshbuf].name);
3120         pre_merge(buffer);
3121         printf(" %d edges in the model\n", anz->g);
3122       }
3123       delSet("-qmsh");
3124       delSet("-setdiv");
3125       setNrdiv=-1;
3126       return;
3127     }
3128     else if(( type[0] == ' ')||(type[0]=='c'))
3129     {
3130       if(keybuf!='l') { printf(" WARNING: No line selected\n"); return; }
3131       /* change division, del me and remesh are done in defineDiv()  */
3132       xbuf=x; ybuf=y;
3133       if(!qbiaFlag) printf(" define 2 digits Div: \n");
3134       else  printf(" define 2 digits Bias: \n");
3135       if(setNrdiv>-1) { setNrbuf=qmshbuf; glutKeyboardFunc(defineDiv); }
3136       return;
3137     }
3138   }
3139 
3140   else if (compare(pickfunc, "qmov", 4) == 4)
3141   {
3142     if ( type[0] == 'm') /*  move item */
3143     {
3144       GLubuf[1]=-1;
3145       moveSet(GLubuf, x, y);
3146       entitybuf=-1;      /* if not, undo would delete the last created entity */
3147     }
3148     else if((type[0]=='n')||(type[0]=='p'))
3149     {
3150       goPicking(x,y,type);
3151     }
3152   }
3153 
3154   else if (compare(pickfunc, "qnod", 4) == 4)
3155   {
3156     if ( type[0] == 'm') /*  move item */
3157     {
3158        moveNode(-1, x, y);
3159        entitybuf=-1;      /* if not, undo would delete the last created entity */
3160     }
3161     else if (type[0]=='p')
3162     {
3163       type[1]=type[0];
3164       type[0]='n';
3165       goPicking(x,y,type);
3166     }
3167   }
3168 
3169   else if (compare(pickfunc, "qtxt", 4) == 4)
3170   {
3171     if ( type[0] == 'a') /*  pick all in range mode */
3172     {
3173       mode[0]='a';
3174       printf ("mode:%s\n", mode);
3175       return;
3176     }
3177     if ( type[0] == 'i') /* individual pick mode */
3178     {
3179       mode[0]='i';
3180       dx_cur=PICK_LENGTH; dy_cur=PICK_LENGTH;
3181       printf ("mode:%s\n", mode);
3182       return;
3183     }
3184 
3185     if ( type[0] == 'm') /*  move item */
3186     {
3187        moveText(-1, x, y);
3188        entitybuf=-1;      /* if not, undo would delete the last created entity */
3189     }
3190     else if (type[0]=='p')
3191     {
3192       moveText(-2, x, y);
3193       type[0]='t';
3194       type[1]='p';
3195       goPicking(x,y,type);
3196     }
3197     else if (type[0]=='f')
3198     {
3199       type[0]='t';
3200       type[1]='f';
3201       goPicking(x,y,type);
3202     }
3203     else if (type[0]=='n')
3204     {
3205       type[0]='t';
3206       type[1]='n';
3207       goPicking(x,y,type);
3208     }
3209     else if (type[0]=='v')
3210     {
3211       type[0]='t';
3212       type[1]='v';
3213       goPicking(x,y,type);
3214     }
3215     else if (type[0]=='s')
3216     {
3217       type[0]='t';
3218       type[1]='s';
3219       goPicking(x,y,type);
3220     }
3221     else if (type[0]=='t')
3222     {
3223       type[0]='t';
3224       type[1]='t';
3225       goPicking(x,y,type);
3226     }
3227     else if (type[0]=='b')
3228     {
3229       type[0]='t';
3230       type[1]='b';
3231       goPicking(x,y,type);
3232     }
3233     else if (type[0]=='g')
3234     {
3235       type[0]='n';
3236       type[1]=0;
3237       goPicking(x,y,type);
3238     }
3239     else if (type[0]=='d')
3240     {
3241       type[0]='t';
3242       type[1]='d';
3243       goPicking(x,y,type);
3244     }
3245   }
3246 
3247   else if (compare(pickfunc, "qpnt", 4) == 4)
3248   {
3249     if ( type[0] == 'a') /*  pick all in range mode */
3250     {
3251       mode[0]='a';
3252       printf ("mode:%s\n", mode);
3253       return;
3254     }
3255     if ( type[0] == 'i') /* individual pick mode */
3256     {
3257       mode[0]='i';
3258       dx_cur=PICK_LENGTH; dy_cur=PICK_LENGTH;
3259       printf ("mode:%s\n", mode);
3260       return;
3261     }
3262     if ( type[0] == 'm') /*  move item */
3263     {
3264       surfNr=-1;
3265       GLubuf[1]=-1;
3266       movePoint(GLubuf, x, y);
3267       entitybuf=-1;      /* if not, undo would delete the last created entity */
3268     }
3269     else if ( type[0] == 'g') /* create a new point */
3270     {
3271       surfNr=-1;
3272       entitybuf=createPoint( x, y );
3273     }
3274     else if (type[0]=='n')  /* choose a node as a trgt for point */
3275     {
3276       goPicking(x,y,type);
3277     }
3278     else if (type[0]=='p')  /* choose a point */
3279     {
3280       goPicking(x,y,type);
3281       if(surfNr>-1) /* move points to a surface */
3282       {
3283         GLubuf[1]=-1;
3284         movePoint(GLubuf, x, y);
3285       }
3286       if(nurbsNr>-1) /* move points to a nurbs */
3287       {
3288         GLubuf[1]=-1;
3289         movePoint(GLubuf, x, y);
3290       }
3291     }
3292     else if (type[0]=='s')  /* choose a surface for projection */
3293     {
3294       if(getSetNr(specialset->tmp)>-1) delSet(specialset->tmp);
3295       setNrbuf=pre_seta(specialset->tmp, "i", 0 );
3296       if(setNrbuf<0) { errMsg(" ERROR: could not create set for qpnt\n"); return; }
3297       goPicking(x,y,type);
3298     }
3299     else if (type[0]=='S')  /* choose a Nurbs for projection */
3300     {
3301       if(getSetNr(specialset->tmp)>-1) delSet(specialset->tmp);
3302       setNrbuf=pre_seta(specialset->tmp, "i", 0 );
3303       if(setNrbuf<0) { errMsg(" ERROR: could not create set for qpnt\n"); return; }
3304       goPicking(x,y,type);
3305     }
3306   }
3307 
3308   else if (compare(pickfunc, "qshp", 4) == 4)
3309   {
3310     if ((type[0]=='p')||(type[0]=='n'))
3311     {
3312       goPicking(x,y,type);
3313     }
3314     else if (type[0]=='c') { nurbsNr=shapeNr=surfNr=-1; }
3315     else if ( type[0] == 'g') /* create a new shape */
3316     {
3317       if(shp_pindx==3)
3318       {
3319         shapebuf.type=0;
3320         if(!strlen(shapebuf.name)) getNewName(shapebuf.name,"sh");
3321         printf(" shape:%s %s %s %s generated\n",shapebuf.name, point[shapebuf.p[0]].name, point[shapebuf.p[1]].name, point[shapebuf.p[2]].name);
3322         shapeNr=shape_i(shapebuf.name, 0, shapebuf.p[0], shapebuf.p[1], shapebuf.p[2], 0, 0,0,0);
3323         shapebuf.name[0]=0;
3324       }
3325       else printf(" Not the right number of points for a plane selected:%d (must be 3). Other types can only be created with the command line using shpe.\n",shp_pindx);
3326       shp_pindx=0;
3327     }
3328     else if ( type[0] == 's') /* select a surf and attach a pre-selected shape or nurbs */
3329     {
3330       goPicking(x,y,type);
3331     }
3332     else if (type[0]=='S') /* pre-select a nurbs */
3333     {
3334       type[0]='S';
3335       type[1]='S';
3336       goPicking(x,y,type);
3337     }
3338     else if(type[0]=='h') /* pre-select a shape */
3339     {
3340       type[0]='h';
3341       type[1]='h';
3342       goPicking(x,y,type);
3343     }
3344     else errMsg(" command not known\n");
3345   }
3346 
3347   else if (compare(pickfunc, "qint", 4) == 4)
3348   {
3349     if (type[0]=='l')
3350     {
3351       goPicking(x,y,type);
3352     }
3353     else errMsg(" command not known\n");
3354   }
3355 
3356   else if (compare(pickfunc, "qfil", 4) == 4)
3357   {
3358     if (type[0]=='l')
3359     {
3360       goPicking(x,y,type);
3361     }
3362     else errMsg(" command not known\n");
3363   }
3364 
3365   else if (compare(pickfunc, "qspl", 4) == 4)
3366   {
3367     if ( type[0] == 'a') /*  pick all in range mode */
3368     {
3369       mode[0]='a';
3370       printf ("mode:%s\n", mode);
3371       return;
3372     }
3373     if ( type[0] == 'i') /* individual pick mode */
3374     {
3375       mode[0]='i';
3376       dx_cur=PICK_LENGTH; dy_cur=PICK_LENGTH;
3377       printf ("mode:%s\n", mode);
3378       return;
3379     }
3380     if( type[0] == 's') /*  split lines */
3381     {
3382       qspl_i=0;           /* forget the splitted lines */
3383       if(getSetNr(specialset->tmp)>-1) delSet(specialset->tmp);
3384       setNrbuf=pre_seta(specialset->tmp, "i", 0 );
3385       if(setNrbuf<0) { errMsg(" ERROR: could not create set for qdel\n"); return; }
3386       type[1]=type[0];
3387       type[0]='l';
3388       goPicking(x,y,type);
3389     }
3390     else errMsg(" command not known\n");
3391   }
3392 
3393   else if (compare(pickfunc, "qseq", 4) == 4)
3394   {
3395     if ( type[0] == 'a') /*  pick all in range mode */
3396     {
3397       mode[0]='a';
3398       printf ("mode:%s\n", mode);
3399       return;
3400     }
3401     if ( type[0] == 'i') /* individual pick mode */
3402     {
3403       mode[0]='i';
3404       dx_cur=PICK_LENGTH; dy_cur=PICK_LENGTH;
3405       printf ("mode:%s\n", mode);
3406       return;
3407     }
3408     if ( type[0] == 'l') /* get line */
3409     {
3410       type[1]=type[0];
3411       goPicking(x,y,type);
3412     }
3413     else if ( type[0] == 'g') /* generate spline */
3414     {
3415       //printf (" mode:%c type:%c ,%d, pickbuf:%f\n",mode[0],type[0],type[1], pickbuf);
3416       if(set[setNrbuf].anz_l==0) printf (" ERROR: No line selected\n");
3417       else if((type[1]==' ')||(type[1]==0))
3418       {
3419         for (j=0; j<set[setNrbuf].anz_l; j++ ) convertLine( set[setNrbuf].line[j], (int)pickbuf);
3420       }
3421       else                               /* we need an lcmb */
3422       {
3423         /* do we already have a suitable lcmb? */
3424         flag=0;
3425         for (j=0; j<anzGeo->c; j++ )
3426         {
3427           if((lcmb[j].name != (char *)NULL)&&(lcmb[j].nl==set[setNrbuf].anz_l))   /* same amount of lines */
3428 	  {
3429             if (printFlag) printf ("check lcmb:%s \n", lcmb[j].name);
3430 
3431             if((alreadyChecked=(char *)realloc((char *)alreadyChecked,(set[setNrbuf].anz_l)*sizeof(char)))==NULL)
3432             { printf(" ERROR: realloc failure in pick()\n\n"); return; }
3433 	      for (k=0; k<set[setNrbuf].anz_l; k++) alreadyChecked[k]=0; /* reset */
3434             for (n=0; n<lcmb[j].nl; n++)
3435 	    {
3436               flag=0;
3437               for (k=0; k<set[setNrbuf].anz_l; k++)
3438 	      {
3439 	        /*
3440                 printf ("c:%s == l:%s\n", line[lcmb[j].l[n]].name, line[set[setNrbuf].line[k]].name);
3441                 */
3442                 if ((lcmb[j].l[n]==set[setNrbuf].line[k])&&(alreadyChecked[k]==0))
3443                 {
3444                   flag=1;               /* share that line */
3445                   alreadyChecked[k]=1;
3446                 }
3447 	      }
3448               if (!flag) goto not_equal_lcmb2;
3449 	    }
3450 
3451             if (printFlag) printf ("equal\n");
3452 
3453             break;
3454 	  }
3455           else flag=0;
3456           not_equal_lcmb2:;
3457 	}
3458 
3459         if (!flag)  /* no lcmb was found, so create one */
3460         {
3461           if((lori=(char *)realloc((char *)lori, (set[setNrbuf].anz_l)*sizeof(char)) ) == NULL )
3462           { printf(" ERROR: realloc failure in pick()\n\n"); return; }
3463           for (j=0; j<set[setNrbuf].anz_l; j++) lori[j]='+';
3464           getNewName( name, "c" );
3465           n=lcmb_i( name, 0, set[setNrbuf].anz_l, lori, set[setNrbuf].line );
3466           if(n <0 )
3467           {
3468             errMsg ("ERROR: lcmb in error, start again\n");
3469             anz_c=0;
3470             for (j=0; j<EDGES_PER_SURF; j++) anz_lpc[j]=0;
3471             return;
3472           }
3473           nr=n;
3474         }
3475         else
3476         {
3477           if (printFlag) printf ("use existing lcmb:%s nr:%d from %d\n", lcmb[j].name,j,anzGeo->c );
3478           nr=j;
3479         }
3480         convertLCMB( nr );
3481       }
3482       type[1] = ' ';
3483       set[setNrbuf].anz_l=0;
3484       return;
3485     }
3486     else if( type[0] == ' ')
3487     {
3488         xbuf=x; ybuf=y;
3489         printf(" define 2 digits Div: \n");
3490         glutKeyboardFunc(defineDiv);
3491         return;
3492     }
3493     else
3494     {
3495       /* look if we have a valid integer > 0, then pick a line */
3496       type[1] = ' ';
3497       icor=atoi(type);
3498       if (( icor <1 )||( icor >9 ))
3499       {
3500         printf(" Key not known\n");
3501         return;
3502       }
3503       type[0]='l';
3504       pickbuf=icor;
3505       goPicking(x,y,type);
3506     }
3507   }
3508   else if (compare(pickfunc, "qflp", 4) == 4)
3509   {
3510     if ( type[0] == 'a') /* orient all connected surfs */
3511     {
3512       mode[0]='a';
3513       printf ("mode:%s\n", mode);
3514       return;
3515     }
3516     if ( type[0] == 'i') /* individual pick mode */
3517     {
3518       mode[0]='i';
3519       type[1]='i';
3520       dx_cur=PICK_LENGTH; dy_cur=PICK_LENGTH;
3521       printf ("mode:%s\n", mode);
3522       return;
3523     }
3524     if (( type[0] == 'b')||( type[0] == 's')||( type[0] == 'e')) /* flip surf and elems  or only elem */
3525     {
3526       if(mode[0]=='a')
3527       {
3528 	mode[0]='i'; /* change back to indiv because the surf-connection will identify the others */
3529         type[1]='a';
3530       }
3531       goPicking(x,y,type);
3532     }
3533   }
3534 }
3535 
3536 
3537 
3538 /* look whats drawn in the picking-rectangle  */
goPicking(int x,int y,char * type)3539 void goPicking( int x, int y, char *type )
3540 {
3541   int j;
3542   GLint  viewport[4];
3543 
3544 #if TEST
3545   printf(" in goPicking\n");
3546 #endif
3547 
3548   glutSetWindow( w1);
3549   glGetIntegerv (GL_VIEWPORT, viewport);
3550   /*   glClearColor ( backgrndcol_rgb[0], backgrndcol_rgb[1], backgrndcol_rgb[2], backgrndcol_rgb[3] ); */
3551   /*   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  */
3552 
3553   /*    glRenderMode (GL_SELECT);   */
3554   /*    glInitNames();   */
3555   /*    glPushName (-1);   */
3556   glRenderMode (GL_SELECT);
3557   glInitNames();
3558   glPushName (-1);
3559 
3560   glLoadIdentity();
3561   gluPickMatrix( (GLdouble) x, (GLdouble) (viewport[3]-y), dx_cur,dy_cur, viewport);
3562   moveModel();
3563 
3564   if (drawMode==4)
3565   {
3566     drawSets( PICK );
3567   }
3568   else
3569   {
3570     if(surfFlag==1)
3571     {
3572       if(type[0]=='e')
3573       {
3574         for (j=0; j<anzGeo->psets; j++ )
3575         {
3576           if(pset[j].type[0]=='f') drawFaces_plot( set[pset[j].nr].anz_f, set[pset[j].nr].face, node, colNr, face, 2, 'e', 1, PICK );
3577         }
3578       }
3579       else if(type[0]=='f')
3580       {
3581         for (j=0; j<anzGeo->psets; j++ )
3582         {
3583           if(pset[j].type[0]=='f') drawFaces_plot( set[pset[j].nr].anz_f, set[pset[j].nr].face, node, colNr, face, 2, 0, 1, PICK );
3584         }
3585       }
3586       else if(type[0]=='n')
3587       {
3588         for (j=0; j<anzGeo->psets; j++ )
3589         {
3590           if(pset[j].type[0]=='f') drawFaceNodes_plot( set[pset[j].nr].anz_f, set[pset[j].nr].face, node, face, 2, 0 );
3591         }
3592       }
3593     }
3594     else
3595     {
3596       if(type[0]=='e')
3597       {
3598         for (j=0; j<anzGeo->psets; j++ )
3599         {
3600           if(pset[j].type[0]=='e') drawElements_plot( set[pset[j].nr].anz_e, set[pset[j].nr].elem, node, colNr, e_enqire, 2, 0,1,PICK );
3601         }
3602       }
3603       else if(type[0]=='f')
3604       {
3605         for (j=0; j<anzGeo->psets; j++ )
3606         {
3607           if(pset[j].type[0]=='f') drawFaces_plot( set[pset[j].nr].anz_f, set[pset[j].nr].face, node, colNr, face, 2, 0,1,PICK );
3608         }
3609       }
3610       else if(type[0]=='n')
3611       {
3612         for (j=0; j<anzGeo->psets; j++ )
3613         {
3614           if(pset[j].type[0]=='e') drawElemNodes_plot( set[pset[j].nr].anz_e, set[pset[j].nr].elem, node, e_enqire, 2, 0 );
3615         }
3616       }
3617     }
3618   }
3619   /*     glutSwapBuffers(); */
3620   /*     glFlush(); */
3621   glFlush();
3622   hits = glRenderMode (GL_RENDER);
3623   if (hits<0)
3624   {
3625     errMsg("\nWARNING: Overflow occured, select a smaller region and try again!\n");
3626   }
3627   else
3628   {
3629     processHits( hits, selectBuf, type, mode, x, y );
3630   }
3631 }
3632 
3633 
3634 
qali()3635 void qali()
3636 {
3637   qaliCounter=0;
3638   pickFlag=1;
3639   mode[0]='i';
3640   strcpy( pickfunc, "qali");
3641   glutSetWindow( w1);
3642   glutKeyboardFunc ( pick );
3643   glutSetWindow( activWindow );
3644 }
qcut()3645 void qcut()
3646 {
3647   qcutCounter=0;
3648   pickFlag=1;
3649   mode[0]='i';
3650   strcpy( pickfunc, "qcut");
3651   glutSetWindow( w1);
3652   glutKeyboardFunc ( pick );
3653   glutSetWindow( activWindow );
3654 }
qmsh()3655 void qmsh()
3656 {
3657   if(getSetNr(specialset->tmp)>-1) delSet( specialset->tmp);
3658   setNrbuf=pre_seta(specialset->tmp, "i", 0 );
3659   if(setNrbuf<0) { errMsg(" ERROR: could not create set for qmsh\n"); return; }
3660   pickFlag=1;
3661   mode[0]='i';
3662   strcpy( pickfunc, "qmsh");
3663   qmshbuf=0;
3664   glutSetWindow( w1);
3665   glutKeyboardFunc ( pick );
3666   glutSetWindow( activWindow );
3667   /* switch to one thread */
3668   anz_threads=anz->threads;
3669   anz->threads=1;
3670 }
qmov(char * record)3671 void qmov( char *record)
3672 {
3673   if(strlen(record)) setNr=getSetNr(record);
3674   if(setNr<0) { printf(" ERROR: no valid setname given\n"); return; }
3675   pickFlag=1;
3676   mode[0]='i';
3677   strcpy( pickfunc, "qmov");
3678   glutSetWindow( w1);
3679   glutKeyboardFunc ( pick );
3680   glutSetWindow( activWindow );
3681 }
qnod()3682 void qnod()
3683 {
3684   pickFlag=1;
3685   mode[0]='i';
3686   strcpy( pickfunc, "qnod");
3687   glutSetWindow( w1);
3688   glutKeyboardFunc ( pick );
3689   glutSetWindow( activWindow );
3690 }
qcnt()3691 void qcnt()
3692 {
3693   pickFlag=1;
3694   mode[0]='i';
3695   strcpy( pickfunc, "qcnt");
3696   glutSetWindow( w1);
3697   glutKeyboardFunc ( pick );
3698   glutSetWindow( activWindow );
3699 }
qdis()3700 void qdis()
3701 {
3702   pickFlag=1;
3703   mode[0]='i';
3704   strcpy( pickfunc, "qdis");
3705   glutSetWindow( w1);
3706   glutKeyboardFunc ( pick );
3707   glutSetWindow( activWindow );
3708     generateSetIndexes();
3709 }
qenq()3710 void qenq()
3711 {
3712   pickFlag=1;
3713   mode[0]='i';
3714   strcpy( pickfunc, "qenq");
3715   glutSetWindow( w1);
3716   glutKeyboardFunc ( pick );
3717   glutSetWindow( activWindow );
3718     generateSetIndexes();
3719 }
qflp()3720 void qflp()
3721 {
3722   int i,j;
3723 
3724   pickFlag=1;
3725   mode[0]='i';
3726   strcpy( pickfunc, "qflp");
3727   glutSetWindow( w1);
3728   glutKeyboardFunc ( pick );
3729   glutSetWindow( activWindow );
3730   if ((selem = (int *)malloc( (anz->emax+1)*sizeof(int)) ) == NULL )
3731   { printf("\n\nERROR: malloc failure in qflp\n"); return; }
3732   /* generate selem[elem]= index of surface */
3733   for (i=0; i<=anz->emax; i++) selem[i]=0;
3734   for (i=0; i<anzGeo->s; i++) if( surf[i].name != (char *)NULL )
3735   {
3736     for (j=0; j<surf[i].ne; j++)
3737     {
3738       if((surf[i].elem[j]<=anz->emax)&&(surf[i].elem[j]>=anz->emin))
3739         selem[surf[i].elem[j]]=i;
3740     }
3741   }
3742 }
qbia()3743 void qbia()
3744 {
3745   pickFlag=1;
3746   mode[0]='i';
3747   strcpy( pickfunc, "qbia");
3748   glutSetWindow( w1);
3749   glutKeyboardFunc ( pick );
3750   glutSetWindow( activWindow );
3751 }
qdiv()3752 void qdiv()
3753 {
3754   pickFlag=1;
3755   mode[0]='i';
3756   strcpy( pickfunc, "qdiv");
3757   glutSetWindow( w1);
3758   glutKeyboardFunc ( pick );
3759   glutSetWindow( activWindow );
3760 }
qseq(char * record)3761 void qseq(char *record)
3762 {
3763   char setname[MAX_LINE_LENGTH];
3764   setname[0]=0;
3765   sscanf(record,"%s",setname);
3766   if(strlen(setname))
3767   {
3768     setNrbuf=pre_seta( setname, "i", 0);
3769     set[setNrbuf].type=1;
3770     //set[setNrbuf].anz_p=0;
3771     strcpy( pickfunc, "qadd");
3772   }
3773   else
3774   {
3775     if(getSetNr(specialset->tmp)>-1) delSet(specialset->tmp);
3776     setNrbuf=pre_seta(specialset->tmp, "i", 0 );
3777     if(setNrbuf<0) { errMsg(" ERROR: could not create set for qseq\n"); return; }
3778     strcpy( pickfunc, "qseq");
3779   }
3780   pickFlag=1;
3781   mode[0]='i';
3782   glutSetWindow( w1);
3783   glutKeyboardFunc ( pick );
3784   glutSetWindow( activWindow );
3785 }
qshp(char * record)3786 void qshp( char *record)
3787 {
3788   static char name[MAX_LINE_LENGTH];
3789   name[0]=0;
3790   shapebuf.name=(char *)&name[0];
3791   if(strlen(record)) sscanf(record,"%s",shapebuf.name);
3792   pickFlag=1;
3793   mode[0]='i';
3794   shp_pindx=0;
3795   strcpy( pickfunc, "qshp");
3796   glutSetWindow( w1);
3797   glutKeyboardFunc ( pick );
3798   glutSetWindow( activWindow );
3799 }
qadd(char * record)3800 void qadd( char *record)
3801 {
3802   char setname[MAX_LINE_LENGTH], type[MAX_LINE_LENGTH];
3803   setname[0]=0;
3804   type[0]=0;
3805   sscanf(record,"%s %s",setname,type);
3806   if(!strlen(setname)) { errMsg(" ERROR: could not create set for qadd\n"); return; }
3807   setNrbuf=pre_seta( setname, "i", 0);
3808   if(setNrbuf<0) { errMsg(" ERROR: could not create set for qadd\n"); return; }
3809   if (type[0]=='s') set[setNrbuf].type=1;
3810   if (type[0]=='t') qaddTol=atof(&type[1]);
3811   pickFlag=1;
3812   mode[0]='i';
3813   strcpy( pickfunc, "qadd");
3814   glutSetWindow( w1);
3815   glutKeyboardFunc ( pick );
3816   glutSetWindow( activWindow );
3817 }
qdel(void)3818 void qdel( void )
3819 {
3820   pickFlag=1;
3821   mode[0]='i';
3822   strcpy( pickfunc, "qdel");
3823   glutSetWindow( w1);
3824   glutKeyboardFunc ( pick );
3825   glutSetWindow( activWindow );
3826 }
qrem(char * record)3827 void qrem( char *record)
3828 {
3829   setNrbuf=pre_seta( record, "i", 0);
3830   if(setNrbuf<0) { errMsg(" ERROR: could not create set for qrem\n"); return; }
3831   pickFlag=1;
3832   mode[0]='i';
3833   strcpy( pickfunc, "qrem");
3834   glutSetWindow( w1);
3835   glutKeyboardFunc ( pick );
3836   glutSetWindow( activWindow );
3837 }
qpnt(char * record)3838 void qpnt( char *record)
3839 {
3840   if(strlen(record)) pntNr=getPntNr(record); else pntNr=-1;
3841   pickFlag=1;
3842   mode[0]='i';
3843   movedp=pntnr=pnt_undo=-1;
3844   moveFlag=0;
3845   strcpy( pickfunc, "qpnt");
3846   glutSetWindow( w1);
3847   glutKeyboardFunc ( pick );
3848   glutSetWindow( activWindow );
3849 }
qnor()3850 void qnor()
3851 {
3852   qnorCounter=0;
3853   pickFlag=1;
3854   mode[0]='i';
3855   strcpy( pickfunc, "qnor");
3856   glutSetWindow( w1);
3857   glutKeyboardFunc ( pick );
3858   glutSetWindow( activWindow );
3859 }
qlin(char * record)3860 void qlin( char *record)
3861 {
3862   if(strlen(record)) lineNr=getLineNr(record);
3863   pickFlag=1;
3864   mode[0]='i';
3865   strcpy( pickfunc, "qlin");
3866   glutSetWindow( w1);
3867   glutKeyboardFunc ( pick );
3868   glutSetWindow( activWindow );
3869 }
qsur(char * record)3870 void qsur( char *record)
3871 {
3872   if(strlen(record)) surfNr=getSurfNr(record);
3873   pickFlag=1;
3874   mode[0]='i';
3875   strcpy( pickfunc, "qsur");
3876   glutSetWindow( w1);
3877   glutKeyboardFunc ( pick );
3878   glutSetWindow( activWindow );
3879   if(pickdata==NULL) /* first time call */
3880   {
3881     pick_buffer=DPICK_BUFFER;
3882     if((pickdata=(int *)realloc((int *)pickdata,(pick_buffer)*sizeof(int)))==NULL)
3883     { errMsg("\n\nERROR: realloc failure in pickstack\n");
3884     return; }
3885     pickdata[0]=0;
3886   }
3887 }
qbod(char * record)3888 void qbod( char *record)
3889 {
3890   if(strlen(record)) bodyNr=getBodyNr(record);
3891   pickFlag=1;
3892   mode[0]='i';
3893   strcpy( pickfunc, "qbod");
3894   glutSetWindow( w1);
3895   glutKeyboardFunc ( pick );
3896   glutSetWindow( activWindow );
3897   if(pickdata==NULL) /* first time call */
3898   {
3899     pick_buffer=DPICK_BUFFER;
3900     if((pickdata=(int *)realloc((int *)pickdata,(pick_buffer)*sizeof(int)))==NULL)
3901     { errMsg("\n\nERROR: realloc failure in pickstack\n");
3902     return; }
3903     pickdata[0]=0;
3904   }
3905 }
qspl()3906 void qspl()
3907 {
3908   pickFlag=1;
3909   mode[0]='a';
3910   strcpy( pickfunc, "qspl");
3911   glutSetWindow( w1);
3912   glutKeyboardFunc ( pick );
3913   glutSetWindow( activWindow );
3914 }
qint()3915 void qint()
3916 {
3917   pickFlag=1;
3918   mode[0]='i';
3919   strcpy( pickfunc, "qint");
3920   glutSetWindow( w1);
3921   glutKeyboardFunc ( pick );
3922   glutSetWindow( activWindow );
3923 }
qfil(char * record)3924 void qfil( char *record)
3925 {
3926   if(strlen(record)) filletRadius=atof(record)/scale->w;
3927   if(filletRadius<=0.)
3928   {
3929     printf(" ERROR: No radius was defined:%lf. Start again with a value.\n", filletRadius);
3930     return;
3931   }
3932   pickFlag=1;
3933   pickbuf=-1.;
3934   mode[0]='i';
3935   strcpy( pickfunc, "qfil");
3936   glutSetWindow( w1);
3937   glutKeyboardFunc ( pick );
3938   glutSetWindow( activWindow );
3939 }
qtxt()3940 void qtxt()
3941 {
3942   pickFlag=1;
3943   mode[0]='i';
3944   strcpy( pickfunc, "qtxt");
3945   glutSetWindow( w1);
3946   glutKeyboardFunc ( pick );
3947   glutSetWindow( activWindow );
3948 }
3949 
3950 
3951 
moveText(int t,int x,int y)3952 void moveText(int t, int x, int y)
3953 {
3954   register int i;
3955   static int *txtnr=NULL, sum=0, moveFlag=0;
3956   static int xbuf,ybuf;
3957 
3958   GLint    viewport[4];
3959   GLdouble mvmatrix[16], projmatrix[16];
3960 
3961   static GLdouble wx, wy, wz;  /*  returned window x, y, z coords  */
3962   static int flag;
3963 
3964   //printf("t:%d flag:%d moveFlag:%d sum:%d x,y %d %d xbuf,ybuf:%d %d wxyz:%f %f %f\n", t, flag, moveFlag, sum, x,y, xbuf, ybuf, wx, wy, wz);
3965   glutSetWindow( w1);
3966   if (t>-1)
3967   {
3968     printf(" text at node %d selected\n", ntext[t].node_nr);
3969     if(moveFlag)
3970     {
3971       moveFlag=0;
3972       free(txtnr);
3973       txtnr=NULL;
3974       sum=0;
3975     }
3976     /* mark text as one to be moved later */
3977     if ( (txtnr = (int *)realloc( txtnr, (sum+1) * sizeof(int))) == NULL )
3978       printf("\n\n ERROR: realloc failed\n\n") ;
3979     txtnr[sum++]=t;
3980     xbuf=x;
3981     ybuf=y;
3982   }
3983   else if ((t==-1)&&(sum>0))
3984   {
3985     moveFlag=1;
3986     /* move node to new location */
3987     /* remember that the point was moved, a new stroke of "p" will choose a new text(node) to move */
3988     if(sum==1)
3989     {
3990       ntext[txtnr[0]].tx= (double)x;
3991       ntext[txtnr[0]].ty= (double)y;
3992     }
3993     else
3994     {
3995       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3996       glLoadIdentity();
3997       moveModel();
3998       glGetIntegerv (GL_VIEWPORT, viewport);
3999       glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);
4000       glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
4001 
4002       for(i=0; i<sum; i++)
4003       {
4004 	//printf("i:%d xy:%f %f xbuf:%d %d x: %d %d\n", txtnr[i], ntext[txtnr[i]].tx, ntext[txtnr[i]].ty, xbuf,ybuf,x,y);
4005         if(ntext[txtnr[i]].tx==-1) //still glued to node-pos
4006 	{
4007           flag=gluProject( node[ntext[txtnr[i]].node_nr].nx, node[ntext[txtnr[i]].node_nr].ny, node[ntext[txtnr[i]].node_nr].nz, mvmatrix, projmatrix, viewport,  &wx, &wy, &wz);
4008           if (flag==GL_FALSE) printf("WARNING: Malfunction, please reselect\n");
4009           ntext[txtnr[i]].tx= wx+(double)(x-xbuf);
4010           ntext[txtnr[i]].ty= (viewport[3]-wy)+(double)(y-ybuf);
4011 	  //printf("wxyz:%f %f v:%d %f   %f %f\n",wx, wy, viewport[3], wz, ntext[txtnr[i]].tx, ntext[txtnr[i]].ty);
4012 	}
4013         else
4014 	{
4015           ntext[txtnr[i]].tx+= (double)(x-xbuf);
4016           ntext[txtnr[i]].ty+= (double)(y-ybuf);
4017 	}
4018       }
4019     }
4020     xbuf=x;
4021     ybuf=y;
4022     updateDispLists();
4023   }
4024   else if ((t==-2)&&(sum>0))
4025   {
4026     /* reset, next call with an entity will start fresh */
4027     moveFlag=1;
4028   }
4029 }
4030 
4031 
4032 
moveSet(GLuint * picbuf,int x,int y)4033 void moveSet(GLuint *picbuf, int x, int y)
4034 {
4035   GLint    viewport[4];
4036   GLdouble mvmatrix[16], projmatrix[16];
4037 
4038   static GLdouble wx, wy, wz;  /*  returned window x, y, z coords  */
4039   static GLdouble nx, ny, nz;  /*  new world x, y, z coords  */
4040   static double    nbuf[3];     /*  coordinate-buffer for undo */
4041   static int flag, indx, indxbuf=-1,typ;
4042 
4043 
4044   glutSetWindow( w1);
4045   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
4046   glLoadIdentity();
4047   moveModel();
4048   glGetIntegerv (GL_VIEWPORT, viewport);
4049   glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);
4050   glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
4051 
4052   indx=picbuf[1];
4053   typ=picbuf[0];
4054 
4055   if ((indx<-1)&&(indxbuf==-1))
4056   {
4057     /* undo */
4058     sprintf(buffer,"%s tra %f %f %f",set[setNr].name,-nx,-ny,-nz);
4059     pre_move( buffer );
4060     redraw();
4061     nx=ny=nz=0.;
4062   }
4063   else if((indx!=-1)&&(indxbuf==-1))
4064   {
4065     /* mark node as a reference point and determine screen coordinates */
4066     indxbuf=indx;
4067     nx=ny=nz=0.;
4068     if(typ=='n')
4069     {
4070       nbuf[0]=node[indx].nx;
4071       nbuf[1]=node[indx].ny;
4072       nbuf[2]=node[indx].nz;
4073     }
4074     if(typ=='p')
4075     {
4076       nbuf[0]=point[indx].px;
4077       nbuf[1]=point[indx].py;
4078       nbuf[2]=point[indx].pz;
4079     }
4080     flag=gluProject( nbuf[0],nbuf[1],nbuf[2], mvmatrix, projmatrix,
4081        viewport,  &wx, &wy, &wz);
4082     if (flag==GL_FALSE)
4083       printf("WARNING: Malfunction in moveNode(), please reselect\n");
4084     /* printf (" node:%d x=%lf y=%lf z=%lf \n", n, node[n].nx,node[n].ny,node[n].nz );
4085     printf (" Win coords are %d (%lf, %lf, %lf)\n",  flag,  wx   ,  wy   , wz     ); */
4086   }
4087   else if ((indx==-1)&&(indxbuf>-1))
4088   {
4089     /* move set to new location */
4090 
4091     /* remember that the point was moved, a new stroke of "p" will choose a new point to move */
4092     moveFlag=1;
4093     wx=(GLdouble)x; wy=(GLdouble)(viewport[3]-y);
4094     flag=gluUnProject ( wx, wy, wz, mvmatrix, projmatrix, viewport, &nx, &ny, &nz);
4095     /* printf ("World coords are %d (%lf, %lf, %lf)\n", flag, nx, ny, nz); */
4096     if (flag==GL_TRUE)
4097     {
4098       nx-=nbuf[0];
4099       ny-=nbuf[1];
4100       nz-=nbuf[2];
4101       nx=nx*scale->w;
4102       ny=ny*scale->w;
4103       nz=nz*scale->w;
4104       sprintf(buffer,"%s tra %f %f %f",set[setNr].name,nx,ny,nz);
4105       pre_move( buffer );
4106       redraw();
4107       indxbuf=-1;
4108     }
4109     else
4110       printf("WARNING: Malfunction in moveNode(), please repeat\n");
4111   }
4112   else if ((indx>-1)&&(indxbuf>-1))
4113   {
4114     /* move the set to the actual node n or point p */
4115     if(typ=='n')
4116     {
4117       nx=node[indx].nx-nbuf[0];
4118       ny=node[indx].ny-nbuf[1];
4119       nz=node[indx].nz-nbuf[2];
4120     }
4121     if(typ=='p')
4122     {
4123       nx=point[indx].px-nbuf[0];
4124       ny=point[indx].py-nbuf[1];
4125       nz=point[indx].pz-nbuf[2];
4126     }
4127     nx=nx*scale->w;
4128     ny=ny*scale->w;
4129     nz=nz*scale->w;
4130     sprintf(buffer,"%s tra %f %f %f",set[setNr].name,nx,ny,nz);
4131     printf("%s\n",buffer);
4132     pre_move( buffer );
4133     redraw();
4134     indxbuf=-1;
4135   }
4136 }
4137 
4138 
4139 
moveNode(int n,int x,int y)4140 void moveNode(int n, int x, int y)
4141 {
4142   GLint    viewport[4];
4143   GLdouble mvmatrix[16], projmatrix[16];
4144 
4145   static GLdouble wx, wy, wz;  /*  returned window x, y, z coords  */
4146   static GLdouble nx, ny, nz;  /*  new world x, y, z coords  */
4147   static double    nbuf[3];     /*  coordinate-buffer for undo */
4148   static int flag, nodnr=-1, nod_undo=-1, moveFlag=0;
4149 
4150 
4151   glutSetWindow( w1);
4152   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
4153   glLoadIdentity();
4154   moveModel();
4155   glGetIntegerv (GL_VIEWPORT, viewport);
4156   glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);
4157   glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
4158 
4159   if (((n>-1)&&(nodnr==-1))||((n>-1)&&(moveFlag==1)))
4160   {
4161     /* mark node as one to be moved later and determine screen coordinates */
4162     nodnr=n;
4163     moveFlag=0;
4164     nod_undo=n;
4165     nbuf[0]=node[n].nx;
4166     nbuf[1]=node[n].ny;
4167     nbuf[2]=node[n].nz;
4168 
4169     flag=gluProject( node[n].nx, node[n].ny, node[n].nz, mvmatrix, projmatrix,
4170        viewport,  &wx, &wy, &wz);
4171     if (flag==GL_FALSE)
4172       printf("WARNING: Malfunction in moveNode(), please reselect\n");
4173     /* printf (" node:%d x=%lf y=%lf z=%lf \n", n, node[n].nx,node[n].ny,node[n].nz );
4174     printf (" Win coords are %d (%lf, %lf, %lf)\n",  flag,  wx   ,  wy   , wz     ); */
4175   }
4176   else if ((n==-1)&&(nodnr>-1))
4177   {
4178     /* move node to new location */
4179 
4180     /* remember that the point was moved, a new stroke of "p" will choose a new point to move */
4181     moveFlag=1;
4182     wx=(GLdouble)x; wy=(GLdouble)(viewport[3]-y);
4183     flag=gluUnProject ( wx, wy, wz, mvmatrix, projmatrix, viewport, &nx, &ny, &nz);
4184     /* printf ("World coords are %d (%lf, %lf, %lf)\n", flag, nx, ny, nz); */
4185     if (flag==GL_TRUE)
4186     {
4187       node[nodnr].nx=nx;
4188       node[nodnr].ny=ny;
4189       node[nodnr].nz=nz;
4190       getElemNormalen( e_enqire, node, anz->e );
4191       getFaceNormalen( face, node, anz );
4192       updateDispLists();
4193     }
4194     else
4195       printf("WARNING: Malfunction in moveNode(), please reselect\n");
4196   }
4197   else if ((n>-1)&&(nodnr>-1))
4198   {
4199     /* move the node nodnr to the actual node n */
4200     node[nodnr].nx=node[n].nx;
4201     node[nodnr].ny=node[n].ny;
4202     node[nodnr].nz=node[n].nz;
4203     getElemNormalen( e_enqire, node, anz->e );
4204     getFaceNormalen( face, node, anz );
4205     updateDispLists();
4206     nodnr=-1;
4207   }
4208   else if ((n<-1)&&(nod_undo>-1))
4209   {
4210     /* undo */
4211     node[nod_undo].nx=nbuf[0];
4212     node[nod_undo].ny=nbuf[1];
4213     node[nod_undo].nz=nbuf[2];
4214     getElemNormalen( e_enqire, node, anz->e );
4215     getFaceNormalen( face, node, anz );
4216     updateDispLists();
4217     nodnr=nod_undo=-1;
4218   }
4219 }
4220 
4221 
movePoint(GLuint * picbuf,int x,int y)4222 void movePoint(GLuint *picbuf, int x, int y)
4223 {
4224   int i,j,nr,p,typ;
4225   GLint    viewport[4];
4226   GLdouble mvmatrix[16], projmatrix[16];
4227   char     name[MAX_LINE_LENGTH];
4228 
4229   static GLdouble wx, wy, wz;  /*  returned window x, y, z coords  */
4230   static GLdouble nx, ny, nz;  /*  new world x, y, z coords  */
4231   static double    pbuf[3];     /*  coordinate-buffer for undo */
4232   static int flag;
4233 
4234   glutSetWindow( w1);
4235   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
4236   glLoadIdentity();
4237   moveModel();
4238   glGetIntegerv (GL_VIEWPORT, viewport);
4239   glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);
4240   glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
4241 
4242   p=picbuf[1];
4243   if(p<0) typ=0; else typ=picbuf[0];
4244 
4245   /* undo */
4246   if ((p==-2)&&(pnt_undo>-1))
4247   {
4248     pntnr=pnt_undo;
4249     /* pnt_undo=-1; */
4250     point[pntnr].px=pbuf[0];
4251     point[pntnr].py=pbuf[1];
4252     point[pntnr].pz=pbuf[2];
4253     movedp=pntnr;
4254     pntnr=pnt_undo=-1;
4255   }
4256   else if (surfNr>-1)
4257   {
4258     /* project p to surf */
4259     if(shape[surf[surfNr].sh].type==4)
4260     {
4261       projSetToNurbs(shape[surf[surfNr].sh].p[0],set,setNrbuf,point);
4262       movedp=-1;
4263 
4264       /* correct the shape of the lines */
4265       for (i=0; i<anzGeo->l; i++)
4266       {
4267         repLine(i);
4268       }
4269     }
4270   }
4271   else if (nurbsNr>-1)
4272   {
4273     /* project p to surf */
4274     projSetToNurbs(nurbsNr,set,setNrbuf,point);
4275     movedp=-1;
4276 
4277     /* correct the shape of the lines */
4278     for (i=0; i<anzGeo->l; i++)
4279     {
4280       repLine(i);
4281     }
4282   }
4283   else if ((((p>-1)&&(pntnr==-1))||((p>-1)&&(moveFlag==1)))&&(typ!='n'))
4284   {
4285     /* mark this point as one to be moved later and determine screen coordinates */
4286     pntnr=pnt_undo=p;
4287     moveFlag=0;
4288     movedp=-1;
4289 
4290     pbuf[0]=point[p].px;
4291     pbuf[1]=point[p].py;
4292     pbuf[2]=point[p].pz;
4293 
4294     /* necessary for plotting the moved point */
4295     flag=gluProject( point[p].px, point[p].py, point[p].pz, mvmatrix, projmatrix,
4296        viewport,  &wx, &wy, &wz);
4297     if (flag==GL_FALSE)
4298       printf("WARNING: Malfunction in movePoint(), please reselect\n");
4299 
4300     /* printf (" pnt:%d x=%lf y=%lf z=%lf \n", n, point[p].px, point[p].py, point[p].pz );
4301     printf (" Win coords are %d (%lf, %lf, %lf)\n",  flag,  wx   ,  wy   , wz     ); */
4302   }
4303   else if ((p==-1)&&(pntnr>-1))
4304   {
4305     /* move the point to the window-coordinates */
4306 
4307     /* remember that the point was moved, a new stroke of "p" will choose a new point to move */
4308     moveFlag=1;
4309     wx=(GLdouble)x; wy=(GLdouble)(viewport[3]-y);
4310     flag=gluUnProject ( wx, wy, wz, mvmatrix, projmatrix, viewport, &nx, &ny, &nz);
4311     /* printf ("new World coords are %d (%lf, %lf, %lf)\n", flag, nx, ny, nz); */
4312     if (flag==GL_TRUE)
4313     {
4314       point[pntnr].px=nx;
4315       point[pntnr].py=ny;
4316       point[pntnr].pz=nz;
4317       movedp=pntnr;
4318     }
4319     else
4320       printf("WARNING: Malfunction in movePoint(), please reselect\n");
4321   }
4322   else if (((p>-1)&&(pntnr>-1))&&typ=='p')
4323   {
4324     /* move the point pntnr to the actual point p */
4325 
4326     point[pntnr].px=point[p].px;
4327     point[pntnr].py=point[p].py;
4328     point[pntnr].pz=point[p].pz;
4329     movedp=pntnr;
4330 
4331     /* in case a line exists between the two points then delete this line and merge the two points */
4332     delSet("-movePoint");
4333     i=pre_seta( "-movePoint", "p", point[pntnr].name );
4334     seta(i,"p",p);
4335     completeSet("-movePoint", "up");
4336     pre_del("l0 -movePoint" );
4337     delSet("-movePoint");
4338 
4339     pntnr=-1;
4340   }
4341   else if (((p>-1)&&(pntnr>-1))&&typ=='n')
4342   {
4343     /* move the point pntnr to the actual node p */
4344 
4345     point[pntnr].px=node[p].nx;
4346     point[pntnr].py=node[p].ny;
4347     point[pntnr].pz=node[p].nz;
4348     movedp=pntnr;
4349     pntnr=-1;
4350   }
4351   else if (((p>-1)&&(pntnr==-1))&&typ=='n')
4352   {
4353     /* create a new point at the actual node p */
4354 
4355     getNewName( name, "p" );
4356     if(printFlag) printf (" pnt=%s x=%lf y=%lf z=%lf\n",  name, node[p].nx* scale->w+scale->x, node[p].ny* scale->w+scale->y, node[p].nz* scale->w+scale->z);
4357     if( pnt( name
4358 	       , node[p].nx
4359 	       , node[p].ny
4360 	       , node[p].nz, 0 ) <0) printf("ERROR: point could not be created\n");
4361   }
4362 
4363   if(movedp>-1)
4364   {
4365     /* correct the shape of the connected lines */
4366     for (i=0; i<anzGeo->l; i++)
4367     {
4368       if(line[i].typ=='a')
4369       {
4370         if((line[i].p1==movedp)||(line[i].p2==movedp)||(line[i].trk==movedp)) repLine(i);
4371       }
4372       else if(line[i].typ=='s')
4373       {
4374         for (j=0; j<set[line[i].trk].anz_p; j++)
4375         {
4376           if(set[line[i].trk].pnt[j]==movedp)
4377           {
4378             repLine(i);
4379             break;
4380           }
4381         }
4382       }
4383       else
4384       {
4385         if((line[i].p1==movedp)||(line[i].p2==movedp)) repLine(i);
4386       }
4387     }
4388     /* correct the shape of the connected NURBS */
4389     for (nr=0; nr<anzGeo->nurs; nr++)
4390     {
4391       if( nurbs[nr].name != (char *)NULL )
4392       {
4393         for (i=0; i<nurbs[nr].u_npnt; i++)
4394           for (j=0; j<nurbs[nr].v_npnt; j++)
4395             if (nurbs[nr].ctlpnt[i][j] == movedp) repNurs(nr);
4396       }
4397     }
4398   }
4399 }
4400 
4401 
4402 
createElem(int n)4403 int createElem(int n)
4404 {
4405   static int nodes[26];
4406   static int nr;
4407 
4408   if(n>-1)
4409   {
4410     nodes[nr++]=n;
4411   }
4412   else if(n==-1)
4413   {
4414     printf(" create shell element:%d\n",anz->emax+1 );
4415     if     (nr==3) elem_define(anz,&e_enqire, anz->enext++, 7, nodes, 1, 0 );
4416     else if(nr==4) elem_define(anz,&e_enqire, anz->enext++, 9, nodes, 1, 0 );
4417     else if(nr==6) elem_define(anz,&e_enqire, anz->enext++, 8, nodes, 1, 0 );
4418     else if(nr==8) elem_define(anz,&e_enqire, anz->enext++, 10, nodes, 1, 0 );
4419     else
4420     {
4421       printf(" Warning, wrong number of nodes:%d, no element created, start again\n",nr);
4422       nr=0;
4423       return(-1);
4424     }
4425     nr=0;
4426 
4427     makeSurfaces();
4428     getElemNormalen( e_enqire, node, anz->e );
4429     realloc_colNr();
4430     return(anz->emax);
4431   }
4432   else if(n==-2)
4433   {
4434     printf(" create volume element:%d\n",anz->emax+1);
4435     if     (nr==8)  elem_define(anz,&e_enqire, anz->enext++, 1, nodes, 1, 0 );
4436     else if(nr==20) elem_define(anz,&e_enqire, anz->enext++, 4, nodes, 1, 0 );
4437     else
4438     {
4439       printf(" Warning, wrong number of nodes:%d, no element created, start again\n",nr);
4440       nr=0;
4441       return(-1);
4442     }
4443     nr=0;
4444 
4445     makeSurfaces();
4446     getElemNormalen( e_enqire, node, anz->e );
4447     realloc_colNr();
4448     return(anz->emax);
4449   }
4450   return(-1);
4451 
4452 }
4453 
4454 
4455 
createText(int nodenr,int x,int y)4456 int createText(int nodenr, int x, int y )
4457 {
4458   int i, t=-1;
4459 
4460   for(i=0; i<anz->t; i++)
4461   {
4462     if(ntext[i].node_nr==nodenr)
4463     {
4464       if(ntext[i].text) free(ntext[i].text);
4465       t=i; break;
4466     }
4467   }
4468   if(t==-1) for(i=0; i<anz->t; i++)
4469   {
4470     if(!ntext[i].node_nr) { t=i; break; }
4471   }
4472   if(t==-1)
4473   {
4474     if ((ntext = (Texts *)realloc( (Texts *)ntext, (anz->t+1)*sizeof(Texts)) ) == NULL )
4475     { printf("\n\nERROR: realloc failure in createText\n\n"); return(-1); }
4476     t=anz->t;
4477     ntext[t].tx= -1;
4478     ntext[t].ty= 0;
4479     anz->t++;
4480   }
4481   if(y>-1)
4482   {
4483     ntext[t].tx= (double)x;
4484     ntext[t].ty= (double)y;
4485   }
4486   ntext[t].nFlag= 1;
4487   ntext[t].vFlag= 1;
4488   ntext[t].tFlag= 0;
4489   ntext[t].fFlag= 0;
4490   ntext[t].pFlag= 0;
4491   ntext[t].text=NULL;
4492   ntext[t].node_nr=nodenr;
4493   updateDispLists();
4494   return(t);
4495 }
4496 
4497 
4498 
createPoint(int x,int y)4499 int createPoint( int x, int y )
4500 {
4501   /* new point is located in an area parallel to the screen and running through centerPnt */
4502   char     name[MAX_LINE_LENGTH];
4503   int      nr=-1;
4504   GLint    viewport[4];
4505   GLdouble mvmatrix[16], projmatrix[16];
4506 
4507   static GLdouble wx, wy, wz;  /*  returned world x, y, z coords  */
4508   static GLdouble nx, ny, nz;  /*  new world x, y, z coords  */
4509   static int flag;
4510 
4511   printf("createPoint\n");
4512 
4513   glutSetWindow( w1);
4514   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
4515   glLoadIdentity();
4516   moveModel();
4517   glGetIntegerv (GL_VIEWPORT, viewport);
4518   glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);
4519   glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
4520 
4521   flag=gluProject( centerPnt[0], centerPnt[1], centerPnt[2], mvmatrix, projmatrix,
4522      viewport,  &wx, &wy, &wz);
4523   if (flag==GL_FALSE)
4524     printf("WARNING: Malfunction in createPoint(), please reselect\n");
4525 
4526   wx=(GLdouble)x; wy=(GLdouble)(viewport[3]-y);
4527   //printf (" x,y: %d %d Win coords are %d (%lf, %lf, %lf)\n",x,y,  flag,  wx   ,  wy   , wz     );
4528   flag=gluUnProject ( wx, wy, wz, mvmatrix, projmatrix, viewport, &nx, &ny, &nz);
4529   //printf ("new World coords are %d (%lf, %lf, %lf)\n", flag, nx, ny, nz);
4530   if (flag==GL_TRUE)
4531   {
4532     if(pntNr==-1) getNewName( name, "p" );
4533     else { strcpy(name,point[pntNr].name); pntNr=-1; }
4534     printf(" create point:%s %lf %lf %lf\n", name, nx, ny, nz );
4535     nr  = pnt( name, nx, ny, nz, 0);
4536   }
4537   else
4538     printf("WARNING: Malfunction in createPoint(), please reselect\n");
4539 
4540   updateDispLists();
4541   return(nr);
4542 }
4543 
4544 
4545 /* pnts: 3 points defining a plane, 1st pnt is startpnt of line, l:length of line */
4546 /* return point-index of line-end-point p2 or -1 if failed */
normalLine(char * name,int * pnts,double l)4547 int normalLine(char *name, int *pnts, double l)
4548 {
4549   int i,p1,p2;
4550   double v0[3], v1[3], v2[3];
4551   char buf[MAX_LINE_LENGTH];
4552   double vpnt[3][3];
4553 
4554   if (!l) return(-1);
4555   for(i=0; i<3; i++)
4556   {
4557     //printf("normalLine %d pnt:%s\n", i, point[pnts[i]].name);
4558     vpnt[i][0]=point[pnts[i]].px* scale->w+scale->x;
4559     vpnt[i][1]=point[pnts[i]].py* scale->w+scale->y;
4560     vpnt[i][2]=point[pnts[i]].pz* scale->w+scale->z;
4561   }
4562   p1=pnts[0];
4563 
4564   for(i=0; i<3; i++) { v0[i]=vpnt[1][i]-vpnt[2][i]; v1[i]=vpnt[2][i]-vpnt[0][i]; }
4565   v_prod(v0,v1,v2);
4566   v_norm(v2,v2);
4567   v_scal(&l,v2,v2);
4568   for(i=0; i<3; i++) { v2[i]+=vpnt[0][i]; }
4569 
4570   /* create the normal point */
4571   p2= getNewName( buf, "p" );
4572   p2=pnt( buf, v2[0], v2[1], v2[2], 1 );
4573   if ( p2 >-1 )
4574   {
4575     /* generate line */
4576     if(name) line_i( name, p1, p2, -1, ddiv, 1, 0 );
4577   }
4578   return(p2);
4579 }
4580 
4581 
4582 
moveLineEndPoint(int lineNr,int pntNr,double llength)4583 void moveLineEndPoint(int lineNr, int pntNr, double llength)
4584 {
4585   int p1,p2, flag=0;
4586   double P1[3], P2[3], u, eva[3], va[3], p0p1_2[3];
4587 
4588     p1=line[lineNr].p1;
4589     p2=line[lineNr].p2;
4590 
4591     /* determine which side of the line has to be moved */
4592     if(pntNr==p1) flag=-1;
4593     else if(pntNr==p2) flag=1;
4594     else
4595     {
4596       printf("ERROR: selected point:%s is no line endpoint\n", point[pntNr].name);
4597       return;
4598     }
4599     u=flag*llength;
4600     u/=scale->w;
4601 
4602     /* calc direction */
4603     if(line[lineNr].typ=='s')
4604     {
4605       if(flag==-1) p2=set[line[lineNr].trk].pnt[1];
4606       else  p1=set[line[lineNr].trk].pnt[set[line[lineNr].trk].anz_p-2];
4607     }
4608     P1[0]=point[p1].px;
4609     P1[1]=point[p1].py;
4610     P1[2]=point[p1].pz;
4611     P2[0]=point[p2].px;
4612     P2[1]=point[p2].py;
4613     P2[2]=point[p2].pz;
4614     v_result( P1, P2, p0p1_2);
4615     v_norm(p0p1_2,eva);
4616     v_scal(&u,eva, va);
4617     point[pntNr].px+=va[0];
4618     point[pntNr].py+=va[1];
4619     point[pntNr].pz+=va[2];
4620     printf("moved by dxyz= %lf %lf %lf\n",
4621       (va[0]* scale->w),
4622       (va[1]* scale->w),
4623       (va[2]* scale->w));
4624 }
4625 
4626 
createLine(char * apnt,int flag)4627 int createLine( char *apnt, int flag )
4628 {
4629   int i,j=0, nr=-1;
4630   static int px, p1, p2, pc=-1, pm=-1, ps[1000], seq=1;
4631   double P1[3], P2[3], Pc[3], Pm[3], pbuf[3], u;
4632   char name[MAX_LINE_LENGTH], setname[MAX_LINE_LENGTH];
4633   double pmp1[3], pmp2[3], pmp1_2[3], pmp2_2[3], nm12[3];
4634   double eva[3], evb[3], va[3], vb[3], p0p1_2[3], p0p2_2[3], vr[3];
4635 
4636 
4637   if (flag==0) p1  = getPntNr( apnt );
4638   else if (flag==1)
4639   {
4640     p2  = getPntNr( apnt );
4641     if (p1!=p2)
4642     {
4643       if (pc>-1)
4644       {
4645         P1[0]=point[p1].px;
4646         P1[1]=point[p1].py;
4647         P1[2]=point[p1].pz;
4648         Pc[0]=point[pc].px;
4649         Pc[1]=point[pc].py;
4650         Pc[2]=point[pc].pz;
4651         /* radius berechnen */
4652         v_result(Pc, P1, vr);
4653         printf(" R:%lf\n", v_betrag(vr)*scale->w);
4654 
4655         if(lineNr==-1) getNewName( name, "l" );
4656         else { strcpy(name,line[lineNr].name); lineNr=-1; }
4657         printf(" create line:%s %s %s %s %d\n", name, point[p1].name, point[p2].name, point[pc].name, ddiv );
4658         nr= line_i( name, p1, p2, pc, ddiv, 1, 'a' );
4659         pc=-1;
4660       }
4661       else if (pm>-1)
4662       {
4663         P1[0]=point[p1].px;
4664         P1[1]=point[p1].py;
4665         P1[2]=point[p1].pz;
4666         P2[0]=point[p2].px;
4667         P2[1]=point[p2].py;
4668         P2[2]=point[p2].pz;
4669         Pm[0]=point[pm].px;
4670         Pm[1]=point[pm].py;
4671         Pm[2]=point[pm].pz;
4672 
4673         /* vprod nm12 = pmp1 x pmp2 */
4674         v_result( Pm, P1, pmp1 );
4675         v_result( Pm, P2, pmp2 );
4676         v_prod( pmp1, pmp2, nm12 );
4677 
4678         /* Vector halfway between pm and p1 or p2 */
4679         u=0.5;
4680         v_scal( &u, pmp1, pmp1_2);
4681         v_scal( &u, pmp2, pmp2_2);
4682         v_add( Pm, pmp1_2, p0p1_2);
4683         v_add( Pm, pmp2_2, p0p2_2);
4684 
4685 
4686         /* Vector in direction to PC, vprod va = nm12 x pmp1 and vb =  pmp2 x nm12 */
4687         v_prod( nm12, pmp1, va );
4688         v_prod( pmp2, nm12, vb );
4689         v_norm( va, eva );
4690         v_norm( vb, evb );
4691 
4692         /* determine abs-max-component of nm12 */
4693         u=0.;
4694         for (i=0; i<3; i++) if (nm12[i]*nm12[i]>u) { u=nm12[i]*nm12[i]; j=i; }
4695 
4696         /* calculation of the intersection between eva and evb */
4697         if (j==0)
4698 	{
4699           u=(p0p2_2[1]-p0p1_2[1]-eva[1]*(p0p2_2[2]-p0p1_2[2])/eva[2])
4700            /(eva[1]*evb[2]/eva[2] - evb[1]);
4701         }
4702         else if (j==1)
4703 	{
4704           u=(p0p2_2[0]-p0p1_2[0]-eva[0]*(p0p2_2[2]-p0p1_2[2])/eva[2])
4705            /(eva[0]*evb[2]/eva[2] - evb[0]);
4706         }
4707         else if (j==2)
4708 	{
4709           u=(p0p2_2[0]-p0p1_2[0]-eva[0]*(p0p2_2[1]-p0p1_2[1])/eva[1])
4710            /(eva[0]*evb[1]/eva[1] - evb[0]);
4711         }
4712         else
4713 	{
4714           printf(" ERROR: in createLine, nm12 in error:%d\n", j);
4715           return(-1);
4716         }
4717 
4718         /*  centerpoint Pc = p0p2_2+ evb*u */
4719         v_scal( &u, evb, pbuf );
4720         v_add( pbuf, p0p2_2, Pc );
4721 
4722         /* radius berechnen */
4723         v_result(Pc, P1, vr);
4724         printf(" R:%lf\n", v_betrag(vr)*scale->w);
4725 
4726 	/*
4727         printf( "Pc:%lf %lf %lf\n", Pc[0], Pc[1], Pc[2] );
4728         printf(" P1:%s P2:%s PM:%s\n", point[p1].name, point[p2].name,  point[pm].name);
4729         printf(" u:%lf v:%lf\n", u*scale->w, v*scale->w);
4730         printf("nm12: %lf %lf %lf\n", nm12[0], nm12[1], nm12[2]);
4731         printf("eva: %lf %lf %lf\n", eva[0], eva[1], eva[2]);
4732         printf("evb: %lf %lf %lf\n", evb[0], evb[1], evb[2]);
4733 	*/
4734 
4735 
4736         /* centerpoint anlegen pc */
4737         getNewName( name, "p" );
4738         printf(" create point:%s %lf %lf %lf\n", name, Pc[0], Pc[1], Pc[2] );
4739         pc= pnt( name, Pc[0], Pc[1], Pc[2], 0 );
4740 
4741         /* kreisbogen definieren */
4742         if(lineNr==-1) getNewName( name, "l" );
4743         else { strcpy(name,line[lineNr].name); lineNr=-1; }
4744         printf(" create line:%s %s %s %s %d\n" , name, point[p1].name, point[p2].name, point[pc].name, ddiv  );
4745         nr= line_i( name, p1, p2, pc, ddiv, 1, 'a' );
4746 
4747         pc=-1;
4748         pm=-1;
4749       }
4750       else if (seq>1)
4751       {
4752         getNewName( setname, "se" );
4753         ps[0]=p1;
4754         ps[seq]=p2;
4755         for (i=0; i<=seq; i++)
4756 	{
4757           pre_seta( setname, "ps", point[ps[i]].name);
4758         }
4759         nr=getSetNr( setname);
4760         /* set[nr].type=1; */
4761         if(lineNr==-1) getNewName( name, "l" );
4762         else { strcpy(name,line[lineNr].name); lineNr=-1; }
4763         printf(" create line:%s %s %s %s %d\n"
4764         , name, point[p1].name, point[p2].name, setname, ddiv );
4765         nr= line_i( name, p1, p2, nr, ddiv, 1, 's' );
4766 	seq=1;
4767       }
4768       else
4769       {
4770         if(lineNr==-1) getNewName( name, "l" );
4771         else { strcpy(name,line[lineNr].name); lineNr=-1; }
4772         printf(" create line:%s %s %s %d\n", name, point[p1].name, point[p2].name, ddiv );
4773         nr= line_i( name, p1, p2, 0, ddiv, 1, 0 );
4774       }
4775       p1=p2;
4776       }
4777     else errMsg(" p1==p2, try again\n");
4778     }
4779   else if (flag==2) /* center point defined */
4780   {
4781     pc  = getPntNr( apnt );
4782   }
4783   else if (flag==3) /* mit-point defined, create a centerpoint */
4784   {
4785     pm  = getPntNr( apnt );
4786   }
4787   else if (flag==4) /* seq-point defined, create a set */
4788   {
4789     ps[seq]  = getPntNr( apnt );
4790     if (seq<1000) seq++;
4791   }
4792   else if (flag==5)
4793   {
4794     if(lineNr==-1)
4795     {
4796       printf("ERROR: select line with key l first\n");
4797       return(-1);
4798     }
4799     px  = getPntNr( apnt );
4800     moveLineEndPoint( lineNr, px, pickbuf);
4801     for (i=0; i<anzGeo->l; i++) repLine(i);
4802 
4803     lineNr=-1;
4804   }
4805   return (nr);
4806 }
4807 
4808 
4809 
movePntAlongNurbs(int nurbsNr,int lmaster)4810 void movePntAlongNurbs( int nurbsNr, int lmaster)
4811 {
4812   int i,n;
4813   double vl, pm[3], pmpn[3], pnp1[3], pnp2[3], pnt[5], vnn[3], vns[3], vnc[3], vn[3];
4814   Points pntbuf, pntvn;
4815 
4816   // determine the correction direction
4817 
4818   // get uv coordinates of point
4819   n=set[line[lmaster].trk].pnt[1];
4820   pnt[0]=point[n].px;
4821   pnt[1]=point[n].py;
4822   pnt[2]=point[n].pz;
4823   proj1PntToNurbs( nurbsNr, pnt);
4824   // get the normal of the nurbs at point
4825   evalNurbsWithNormalVector( nurbsNr, 1, &pnt[3], &pnt[4], &pntbuf, &pntvn);
4826   v_norm(&pntvn.px, vnn);
4827   // get the normal of the spline
4828   v_result( &point[n].px,&point[line[lmaster].p1].px,pnp1);
4829   v_result( &point[n].px,&point[line[lmaster].p2].px,pnp2);
4830   v_prod(pnp1,pnp2,vns);
4831   v_norm(vns, vns);
4832   // get the normal on both (correction direction)
4833   v_prod(vnn,vns,vn);
4834   v_norm(vn, vn);
4835   // get the correction direction
4836   v_prod(vnn,vn,vnc);
4837   v_norm(vnc, vn);
4838   // projection of pmpn on that direction gives the correction
4839   v_add(&point[line[lmaster].p1].px, &point[line[lmaster].p2].px, pm);
4840   for(i=0; i<3; i++) pm[i]*=0.5;
4841   v_result( pm,&point[n].px,pmpn);
4842   vl=v_sprod( vn, pmpn)*-1.;
4843   v_scal(&vl,vn,vn);
4844 
4845   v_add(pnt, vn, &point[n].px);
4846 }
4847 
4848 /*
4849 return(new surf)
4850 if error
4851 return
4852 -1: malloc failed
4853 -2: no line or surf selected
4854 -3: has holes
4855 -4: the lines form only one loop, so no 2 surfs can be generated
4856 -5: other error
4857 */
splitSurf(int lmaster,int smaster)4858 int splitSurf( int lmaster, int smaster )
4859 {
4860   int i,j,l,n,s;
4861   int nlines, nls[2];
4862   int snew, sbuf;
4863   char repFlag=0;
4864   static int *ls[2]={NULL,NULL};
4865   static char *os[2]={NULL,NULL};
4866   static char *typs[2]={NULL,NULL};
4867   static int *lines=NULL;
4868   static char *ori=NULL;
4869   static char *typ=NULL;
4870   char name[MAX_LINE_LENGTH];
4871 
4872   double p1p2[3], p1pn[3],vn[3],vl,pnt[5],ubuf,vbuf;
4873 
4874 
4875   if(surf[smaster].nc>1) return(-3);
4876   if(surf[smaster].npgn) repFlag=1;
4877   //printf("line %s surf %s\n", line[lmaster].name, surf[smaster].name);
4878 
4879   /* make sure the master surface is oriented */
4880   orientSurf( smaster );
4881 
4882   /* proj line to surf */
4883   if(surf[smaster].sh>-1)
4884   {
4885     if(( line[lmaster].typ != 's')||(set[line[lmaster].trk].anz_p==3))
4886     {
4887       // 1. make spline with just one point
4888       // loop several times:
4889       // 2. proj to nurbs
4890       // 3. set trk pnt back to node pos
4891       convertLine( lmaster, 1);
4892       if(shape[surf[smaster].sh].type!=4)
4893       {
4894 	sbuf= s= surfToNurs(smaster);
4895         if(s<0) return(-5);
4896       }
4897       else sbuf=shape[surf[smaster].sh].p[0];
4898 
4899       // project the point
4900       ubuf=vbuf=-1.;
4901       for( i=0; i<60; i++)
4902       {
4903         n=set[line[lmaster].trk].pnt[1];
4904 	pnt[0]=point[n].px;
4905 	pnt[1]=point[n].py;
4906 	pnt[2]=point[n].pz;
4907         proj1PntToNurbs(sbuf, pnt);
4908 	if( (abs(pnt[3]-ubuf)/nurbs[sbuf].uknt[nurbs[sbuf].u_nknt-1]) +
4909 	    (abs(pnt[4]-vbuf)/nurbs[sbuf].vknt[nurbs[sbuf].v_nknt-1]) < 1e-6)
4910 	  break;
4911 
4912         repLine(lmaster);
4913         // move pnt back to line mid position
4914         j=(line[lmaster].nip-1)/2;
4915         point[n].px=line[lmaster].ip[j-1]  ;
4916         point[n].py=line[lmaster].ip[j];
4917         point[n].pz=line[lmaster].ip[j+1];
4918 
4919         // if the point is not at the line between line[lmaster].p1 and line[lmaster].p2
4920         // correct the projected point
4921         v_result( &point[line[lmaster].p1].px,&point[line[lmaster].p2].px,p1p2);
4922         v_result( &point[line[lmaster].p1].px,&point[n].px,p1pn);
4923         v_prod( p1p2, p1pn, vn );
4924         vl=v_betrag(vn);
4925         if(vl!=0.)
4926         {
4927 	  pnt[0]=point[n].px;
4928 	  pnt[1]=point[n].py;
4929 	  pnt[2]=point[n].pz;
4930           proj1PntToNurbs(sbuf, pnt);
4931           movePntAlongNurbs( sbuf, lmaster);
4932           repLine(lmaster);
4933           // move pnt back to line mid position
4934           j=(line[lmaster].nip-1)/2;
4935           point[n].px=line[lmaster].ip[j-1]  ;
4936           point[n].py=line[lmaster].ip[j];
4937           point[n].pz=line[lmaster].ip[j+1];
4938         }
4939 	ubuf=pnt[3];
4940 	vbuf=pnt[4];
4941       }
4942       if( ((abs(pnt[3]-ubuf)/nurbs[sbuf].uknt[nurbs[sbuf].u_nknt-1]) >1e-6) &&
4943 	  ((abs(pnt[4]-vbuf)/nurbs[sbuf].vknt[nurbs[sbuf].v_nknt-1]) >1e-6) ) return(-5);
4944 
4945       // 4. make spline with div-1 points
4946       // 2. proj to nurbs
4947       convertLine( lmaster, line[lmaster].div-1);
4948       delPnt( 1, &n );
4949       // proj normal to smaster
4950       if(shape[surf[smaster].sh].type==4) projSetToNurbs(shape[surf[smaster].sh].p[0], set, line[lmaster].trk, point);
4951       else
4952       {
4953         if(s>-1)
4954         {
4955           projSetToNurbs( s, set, line[lmaster].trk, point);
4956           delNurs( 1, &s );
4957         }
4958       }
4959     }
4960     else // line was a spline with more than 3 pnts and trk pnts have to be kept!
4961     {
4962       // proj normal to smaster
4963       if(shape[surf[smaster].sh].type==4) projSetToNurbs(shape[surf[smaster].sh].p[0], set, line[lmaster].trk, point);
4964       else
4965       {
4966         s= surfToNurs(smaster);
4967         if(s>-1)
4968         {
4969           projSetToNurbs( s, set, line[lmaster].trk, point);
4970           delNurs( 1, &s );
4971         }
4972       }
4973     }
4974     repLine(lmaster);
4975   }
4976 
4977   /* copy all lines (also from lcmbs) to an array */
4978   l=0;
4979   for(i=0; i<surf[smaster].nl; i++)
4980   {
4981     if(surf[smaster].typ[i]=='l')
4982     {
4983       if ((lines = (int *)realloc(lines, (l+1)*sizeof(int)) ) == NULL )
4984       { printf("ERROR: malloc failure\n"); return(-1); }
4985       if ((ori = (char *)realloc(ori, (l+1)*sizeof(char)) ) == NULL )
4986       { printf("ERROR: malloc failure\n"); return(-1); }
4987       if ((typ = (char *)realloc(typ, (l+1)*sizeof(char)) ) == NULL )
4988       { printf("ERROR: malloc failure\n"); return(-1); }
4989       typ[l]='l';
4990       ori[l]=surf[smaster].o[i];
4991       //printf("add %s\n", line[surf[smaster].l[i]].name);
4992       lines[l++]=surf[smaster].l[i];
4993     }
4994     else
4995     {
4996       if ((lines = (int *)realloc(lines, (l+lcmb[surf[smaster].l[i]].nl)*sizeof(int)) ) == NULL )
4997         { printf("ERROR: malloc failure\n"); return(-1); }
4998       if ((ori = (char *)realloc(ori, (l+lcmb[surf[smaster].l[i]].nl)*sizeof(char)) ) == NULL )
4999         { printf("ERROR: malloc failure\n"); return(-1); }
5000       if ((typ = (char *)realloc(typ, (l+lcmb[surf[smaster].l[i]].nl)*sizeof(char)) ) == NULL )
5001         { printf("ERROR: malloc failure\n"); return(-1); }
5002 
5003       if(surf[smaster].o[i]=='+')
5004       {
5005         for (n=0; n<lcmb[surf[smaster].l[i]].nl; n++)
5006         {
5007           typ[l]='l';
5008           ori[l]=lcmb[surf[smaster].l[i]].o[n];
5009 	  //printf("add %s\n", line[lcmb[surf[smaster].l[i]].l[n]].name);
5010           lines[l++]=lcmb[surf[smaster].l[i]].l[n];
5011 	}
5012       }
5013       else
5014       {
5015         for (n=lcmb[surf[smaster].l[i]].nl-1; n>=0; n--)
5016         {
5017           typ[l]='l';
5018           if(lcmb[surf[smaster].l[i]].o[n]=='+') ori[l]='-'; else ori[l]='+';
5019 	  //printf("add %s\n", line[lcmb[surf[smaster].l[i]].l[n]].name);
5020           lines[l++]=lcmb[surf[smaster].l[i]].l[n];
5021 	}
5022       }
5023     }
5024   }
5025   nlines=l;
5026 
5027   /* search the line loops starting from the 1st line */
5028   l=0;
5029   s=0;
5030   nls[0]=nls[1]=0;
5031   for(i=0; i<nlines; i++)
5032   {
5033     if ((ls[s] = (int *)realloc(ls[s], (nls[s]+1)*sizeof(int)) ) == NULL )
5034     { printf("ERROR: malloc failure\n"); return(-1); }
5035     if ((os[s] = (char *)realloc(os[s], (nls[s]+1)*sizeof(char)) ) == NULL )
5036     { printf("ERROR: malloc failure\n"); return(-1); }
5037     if ((typs[s] = (char *)realloc(typs[s], (nls[s]+1)*sizeof(char)) ) == NULL )
5038     { printf("ERROR: malloc failure\n"); return(-1); }
5039     ls[s][nls[s]] = lines[i];
5040     os[s][nls[s]] = ori[i];
5041     typs[s][nls[s]] = typ[i];
5042     //    printf("%d found l:%s\n", i, line[ls[s][nls[s]]].name);
5043     nls[s]++;
5044 
5045     /* change the target surface s when a point of lmaster is identical to the end-point of the actual line */
5046     if(ori[i]=='+')
5047     {
5048       if((line[lines[i]].p2==line[lmaster].p1)||(line[lines[i]].p2==line[lmaster].p2))
5049       {
5050         if ((ls[s] = (int *)realloc(ls[s], (nls[s]+1)*sizeof(int)) ) == NULL )
5051         { printf("ERROR: malloc failure\n"); return(-1); }
5052         if ((os[s] = (char *)realloc(os[s], (nls[s]+1)*sizeof(char)) ) == NULL )
5053         { printf("ERROR: malloc failure\n"); return(-1); }
5054         if ((typs[s] = (char *)realloc(typs[s], (nls[s]+1)*sizeof(char)) ) == NULL )
5055         { printf("ERROR: malloc failure\n"); return(-1); }
5056         ls[s][nls[s]] = lmaster;
5057         os[s][nls[s]] = '+';
5058         typs[s][nls[s]] = 'l';
5059         if(line[lines[i]].p2==line[lmaster].p1) os[s][nls[s]] = '+'; else os[s][nls[s]] = '-';
5060         // printf("%d found l:%s\n", i, line[ls[s][nls[s]]].name);
5061         nls[s]++;
5062         s=!s;
5063       }
5064     }
5065     else
5066     {
5067       if((line[lines[i]].p1==line[lmaster].p1)||(line[lines[i]].p1==line[lmaster].p2))
5068       {
5069         if ((ls[s] = (int *)realloc(ls[s], (nls[s]+1)*sizeof(int)) ) == NULL )
5070         { printf("ERROR: malloc failure\n"); return(-1); }
5071         if ((os[s] = (char *)realloc(os[s], (nls[s]+1)*sizeof(char)) ) == NULL )
5072         { printf("ERROR: malloc failure\n"); return(-1); }
5073         if ((typs[s] = (char *)realloc(typs[s], (nls[s]+1)*sizeof(char)) ) == NULL )
5074         { printf("ERROR: malloc failure\n"); return(-1); }
5075         ls[s][nls[s]] = lmaster;
5076         os[s][nls[s]] = '+';
5077         typs[s][nls[s]] = 'l';
5078         if(line[lines[i]].p1==line[lmaster].p1) os[s][nls[s]] = '+'; else os[s][nls[s]] = '-';
5079         // printf("%d found l:%s\n", i, line[ls[s][nls[s]]].name);
5080         nls[s]++;
5081         s=!s;
5082       }
5083     }
5084   }
5085   if(nls[1]<1) return(-4);
5086 
5087   /* redefine selected surf and define new surf */
5088   getNewName( name, "s" );
5089   snew= surface_i( name, surf[smaster].ori, surf[smaster].sh, nls[1], os[1], ls[1], typs[1] );
5090   if(snew<0) return(-5);
5091   surf[snew].etyp=surf[smaster].etyp;
5092   surf[snew].eattr=surf[smaster].eattr;
5093   surface_i( surf[smaster].name, surf[smaster].ori, surf[smaster].sh, nls[0], os[0], ls[0], typs[0] );
5094 
5095   /* add snew to bodies */
5096   for(i=0; i<anzGeo->b; i++) if( body[i].name != (char *)NULL )
5097   {
5098     for(j=0; j<body[i].ns; j++)
5099     {
5100       if(body[i].s[j]==smaster) { n=j; break; }
5101     }
5102     if(j<body[i].ns)
5103     {
5104       /* body must be redefined */
5105       if ((body[i].s = (int *)realloc(body[i].s, (body[i].ns+1)*sizeof(int)) ) == NULL )
5106       { printf("ERROR: malloc failure\n"); return(-1); }
5107       if ((body[i].o = (char *)realloc(body[i].o, (body[i].ns+1)*sizeof(char)) ) == NULL )
5108       { printf("ERROR: malloc failure\n"); return(-1); }
5109       body[i].o[body[i].ns]=body[i].o[n];
5110       body[i].s[body[i].ns]=snew;
5111       body[i].ns++;
5112     }
5113   }
5114 
5115   /* add snew to sets which contain smaster */
5116   for(i=0; i<anz->sets; i++)
5117   {
5118     if(!set[i].type)
5119       if((set[i].name!=(char *)NULL)&&(set[i].name[0]!='-')&&(i!=setall)&&( getIndex(&set[i].surf,set[i].anz_s,smaster) >-1)) seta(i,"s",snew);
5120   }
5121 
5122   if(repFlag)
5123   {
5124     repSurf(smaster,1);
5125     repSurf(snew,1);
5126   }
5127   return(snew);
5128 }
5129 
5130 
5131 /*
5132 return(surf)
5133 if error
5134 return
5135 -1: malloc failed
5136 -2: no 2 surfs selected
5137 -3: the master surf is of type "BLEND"
5138 -4: trim failed
5139 */
combineSurfs(int setNr)5140 int combineSurfs( int setNr )
5141 {
5142   int i,ii,j,jj,l,n,s;
5143   int smaster=-1,sslave, snew, skipFlag;
5144   static int *lines=NULL;
5145   static char *ori=NULL;
5146   static char *typ=NULL;
5147   double lmax=-MAX_FLOAT, Ll=0.;
5148   char name[MAX_LINE_LENGTH];
5149   int  sslaveEvaluated=0;
5150 
5151   /* determine the master surf (the "greater" one) by measure of their line length */
5152   /* it is supposed that the related nurbs (if any) covers also the smaller surf */
5153   /* It was successfull if a trimming attempt of the combined surf verifies that */
5154 
5155   /* for the moment just two surfs can be combined */
5156   if(set[setNr].anz_s!=2) return(-2);
5157 
5158   /* length of the lines of the surfs */
5159   for (s=0; s<set[setNr].anz_s; s++)
5160   {
5161     jj=set[setNr].surf[s];
5162     if( surf[jj].name != (char *)NULL )
5163     Ll=0.;
5164     for (n=0; n<surf[jj].nl; n++)
5165     {
5166       if( surf[jj].typ[n] == 'l' )
5167       {
5168         Ll+=calcLineLength(surf[jj].l[n]);
5169       }
5170       if( surf[jj].typ[n] == 'c' )
5171       {
5172         for(l=0; l<lcmb[surf[jj].l[n]].nl; l++)
5173 	{
5174           Ll+=calcLineLength(lcmb[surf[jj].l[n]].l[l]);
5175 	}
5176       }
5177     }
5178     //printf("surf:%s LENGTH:%lf\n", surf[jj].name, Ll);
5179     if(Ll>lmax) { lmax=Ll; smaster=s; }
5180   }
5181   //printf("msurf:%s LENGTH:%lf sh:%d\n", surf[set[setNr].surf[smaster]].name, lmax, surf[set[setNr].surf[smaster]].sh);
5182 
5183   /* generate a new surface */
5184   /* for the moment just two surfs can be combined */
5185   if(smaster==0) sslave=1; else sslave=0;
5186 
5187   smaster=set[setNr].surf[smaster];
5188   sslave=set[setNr].surf[sslave];
5189 
5190   /* the master surf must not be of type "BLEND" */
5191   if(surf[smaster].sh<0) return(-3);
5192 
5193   l=0;
5194   for(i=0; i<surf[smaster].nl; i++)
5195   {
5196     skipFlag=0;
5197     for(j=0; j<surf[sslave].nl; j++)
5198     {
5199       // might be necessary to regard lcmb cases later
5200       if(surf[smaster].l[i]==surf[sslave].l[j]) skipFlag=1;
5201 
5202       // if i==1: The lines from the second surf have to follow now since orient() must find now the lines from 2nd surf
5203       if((i==1)&&(skipFlag))
5204       {
5205         // code copy from below if(sslaveEvaluated)
5206         for(ii=0; ii<surf[sslave].nl; ii++)
5207         {
5208           skipFlag=0;
5209           for(jj=0; jj<surf[smaster].nl; jj++)
5210           {
5211             if(surf[smaster].l[jj]==surf[sslave].l[ii]) { skipFlag=1; break; }
5212           }
5213           if(!skipFlag)
5214           {
5215             if(surf[sslave].typ[ii]=='l')
5216             {
5217               if ((lines = (int *)realloc(lines, (l+1)*sizeof(int)) ) == NULL )
5218       	      { printf("ERROR: malloc failure\n"); return(-1); }
5219               if ((ori = (char *)realloc(ori, (l+1)*sizeof(char)) ) == NULL )
5220       	      { printf("ERROR: malloc failure\n"); return(-1); }
5221               if ((typ = (char *)realloc(typ, (l+1)*sizeof(char)) ) == NULL )
5222       	      { printf("ERROR: malloc failure\n"); return(-1); }
5223               typ[l]='l';
5224               ori[l]=surf[sslave].o[ii];
5225               lines[l++]=surf[sslave].l[ii];
5226             }
5227             else
5228             {
5229               for (n=0; n<lcmb[surf[sslave].l[ii]].nl; n++)
5230               {
5231                 if ((lines = (int *)realloc(lines, (l+1)*sizeof(int)) ) == NULL )
5232       	        { printf("ERROR: malloc failure\n"); return(-1); }
5233                 if ((ori = (char *)realloc(ori, (l+1)*sizeof(char)) ) == NULL )
5234       	        { printf("ERROR: malloc failure\n"); return(-1); }
5235                 if ((typ = (char *)realloc(typ, (l+1)*sizeof(char)) ) == NULL )
5236       	        { printf("ERROR: malloc failure\n"); return(-1); }
5237                 typ[l]='l';
5238                 ori[l]=lcmb[surf[sslave].l[ii]].o[n];
5239                 if(surf[sslave].o[ii]=='-') { if(ori[l]=='+') ori[l]='-'; else ori[l]='-'; }
5240                 lines[l++]=lcmb[surf[sslave].l[ii]].l[n];
5241               }
5242             }
5243           }
5244         }
5245         skipFlag=sslaveEvaluated=1;
5246         break;
5247       }
5248     }
5249     if(!skipFlag)
5250     {
5251       if(surf[smaster].typ[i]=='l')
5252       {
5253         if ((lines = (int *)realloc(lines, (l+1)*sizeof(int)) ) == NULL )
5254 	{ printf("ERROR: malloc failure\n"); return(-1); }
5255         if ((ori = (char *)realloc(ori, (l+1)*sizeof(char)) ) == NULL )
5256 	{ printf("ERROR: malloc failure\n"); return(-1); }
5257         if ((typ = (char *)realloc(typ, (l+1)*sizeof(char)) ) == NULL )
5258 	{ printf("ERROR: malloc failure\n"); return(-1); }
5259         typ[l]='l';
5260         ori[l]=surf[smaster].o[i];
5261 	//printf("l %d add %s\n", l, line[surf[smaster].l[i]].name);
5262         lines[l++]=surf[smaster].l[i];
5263       }
5264       else
5265       {
5266         for (n=0; n<lcmb[surf[sslave].l[i]].nl; n++)
5267         {
5268           if ((lines = (int *)realloc(lines, (l+1)*sizeof(int)) ) == NULL )
5269 	  { printf("ERROR: malloc failure\n"); return(-1); }
5270           if ((ori = (char *)realloc(ori, (l+1)*sizeof(char)) ) == NULL )
5271 	  { printf("ERROR: malloc failure\n"); return(-1); }
5272           if ((typ = (char *)realloc(typ, (l+1)*sizeof(char)) ) == NULL )
5273 	  { printf("ERROR: malloc failure\n"); return(-1); }
5274           typ[l]='l';
5275           ori[l]=lcmb[surf[smaster].l[i]].o[n];
5276           if(surf[smaster].o[i]=='-') { if(ori[l]=='+') ori[l]='-'; else ori[l]='-'; }
5277 	  //printf("c %d add %s\n",l, line[lcmb[surf[smaster].l[i]].l[n]].name);
5278           lines[l++]=lcmb[surf[smaster].l[i]].l[n];
5279 	}
5280       }
5281     }
5282   }
5283   if(!sslaveEvaluated)
5284   for(i=0; i<surf[sslave].nl; i++)
5285   {
5286     skipFlag=0;
5287     for(j=0; j<surf[smaster].nl; j++)
5288     {
5289       if(surf[smaster].l[j]==surf[sslave].l[i]) skipFlag=1;
5290     }
5291     if(!skipFlag)
5292     {
5293       if(surf[sslave].typ[i]=='l')
5294       {
5295         if ((lines = (int *)realloc(lines, (l+1)*sizeof(int)) ) == NULL )
5296 	{ printf("ERROR: malloc failure\n"); return(-1); }
5297         if ((ori = (char *)realloc(ori, (l+1)*sizeof(char)) ) == NULL )
5298 	{ printf("ERROR: malloc failure\n"); return(-1); }
5299         if ((typ = (char *)realloc(typ, (l+1)*sizeof(char)) ) == NULL )
5300 	{ printf("ERROR: malloc failure\n"); return(-1); }
5301         typ[l]='l';
5302         ori[l]=surf[sslave].o[i];
5303         lines[l++]=surf[sslave].l[i];
5304       }
5305       else
5306       {
5307         for (n=0; n<lcmb[surf[sslave].l[i]].nl; n++)
5308         {
5309           if ((lines = (int *)realloc(lines, (l+1)*sizeof(int)) ) == NULL )
5310 	  { printf("ERROR: malloc failure\n"); return(-1); }
5311           if ((ori = (char *)realloc(ori, (l+1)*sizeof(char)) ) == NULL )
5312 	  { printf("ERROR: malloc failure\n"); return(-1); }
5313           if ((typ = (char *)realloc(typ, (l+1)*sizeof(char)) ) == NULL )
5314 	  { printf("ERROR: malloc failure\n"); return(-1); }
5315           typ[l]='l';
5316           ori[l]=lcmb[surf[sslave].l[i]].o[n];
5317           if(surf[sslave].o[i]=='-') { if(ori[l]=='+') ori[l]='-'; else ori[l]='-'; }
5318           lines[l++]=lcmb[surf[sslave].l[i]].l[n];
5319 	}
5320       }
5321     }
5322   }
5323 
5324   getNewName( name, "s" );
5325   snew= surface_i( name, surf[smaster].ori, surf[smaster].sh, l, ori, lines, typ );
5326   surf[snew].etyp=surf[smaster].etyp;
5327   surf[snew].eattr=surf[smaster].eattr;
5328 
5329   printf(" surfaces combined\n");
5330 
5331   /* update the master surf */
5332   surface_i( surf[smaster].name, surf[smaster].ori, surf[smaster].sh, surf[snew].nl, surf[snew].o, surf[snew].l, surf[snew].typ );
5333   surf[smaster].etyp=surf[snew].etyp;
5334   surf[smaster].eattr=surf[snew].eattr;
5335 
5336   delSurf( 1, &snew );
5337 
5338   /* remove sslave from bodies */
5339   for(i=0; i<anzGeo->b; i++) if( body[i].name != (char *)NULL )
5340   {
5341     for(j=0; j<body[i].ns; j++)
5342     {
5343       if(body[i].s[j]==sslave) break;
5344     }
5345     if(j<body[i].ns)
5346     {
5347       /* body must be redefined */
5348       n=0;
5349       for(j=0; j<body[i].ns; j++)
5350       {
5351         if(body[i].s[j]!=sslave)
5352 	{
5353           body[i].o[n]=body[i].o[j];
5354           body[i].s[n++]=body[i].s[j];
5355 	}
5356       }
5357       body[i].ns--;
5358     }
5359   }
5360   delSurf( 1, &sslave );
5361 
5362   return(smaster);
5363 }
5364 
5365 
5366 /* makes a seqence-line from an lcmb */
convertLCMB(int c)5367 void convertLCMB( int c )
5368 {
5369   int i,j,k,l,n,p, setNr, div=0;
5370   double  bias;
5371   char name[MAX_LINE_LENGTH];
5372 
5373   if(lcmb[c].name==(char *)NULL) return;
5374 
5375   /* define a sequence */
5376   if( getNewName( name, "se" ) == -1 )
5377   {
5378     printf("ERROR: set could not be created\n");
5379     return;
5380   }
5381   if( (setNr=pre_seta( name, "is", 0)) <0 ) return;
5382   bias=1;
5383 
5384   /* create spline points */
5385   /* and define a sequence */
5386   for (i=0; i<lcmb[c].nl; i++)
5387   {
5388     l=lcmb[c].l[i];
5389     repLine(l);
5390     div+=line[l].div;
5391     if(lcmb[c].o[i]=='+')
5392     {
5393       seta( setNr, "p", line[l].p1 );
5394       for (n=3; n<line[l].nip-3; n+=3)
5395       {
5396         if( getNewName( name, "p" ) == -1 )
5397         {
5398           printf("ERROR: point could not be created\n");
5399           return;
5400         }
5401         p=pnt( name, line[l].ip[n], line[l].ip[n+1], line[l].ip[n+2], 0);
5402         if( p<0) printf("ERROR: point could not be created\n");
5403         seta(setNr,"p",p);
5404       }
5405       seta( setNr, "p", line[l].p2 );
5406     }
5407     else
5408     {
5409       seta( setNr, "p", line[l].p2 );
5410       for (n=line[l].nip-6; n>=3; n-=3)
5411       {
5412         if( getNewName( name, "p" ) == -1 )
5413         {
5414           printf("ERROR: point could not be created\n");
5415           return;
5416         }
5417         p=pnt( name, line[l].ip[n], line[l].ip[n+1], line[l].ip[n+2], 0);
5418         if( p<0) printf("ERROR: point could not be created\n");
5419         seta(setNr,"p",p);
5420       }
5421       seta( setNr, "p", line[l].p1 );
5422     }
5423   }
5424 
5425   if( getNewName( name, "l" ) == -1 )
5426   {
5427     printf("ERROR: line could not be created\n");
5428     return;
5429   }
5430   l=line_i( name, lcmb[c].p1, lcmb[c].p2, setNr, div, bias, 's' );
5431 
5432   /* replace the lcmb by the new line in all surfaces */
5433   p=0;
5434   for (i=0; i<anzGeo->s; i++) if( surf[i].name != (char *)NULL )
5435   {
5436     for (j=0; j<surf[i].nl; j++)
5437     {
5438       if(( c == surf[i].l[j] )&&( surf[i].typ[j]=='c' ))
5439       {
5440         p=1;
5441         printf ("realloc surf:%s and replace lcmb:%s with line:%s\n",
5442           surf[i].name, lcmb[c].name, line[l].name );
5443         surf[i].l[j]=l;
5444         surf[i].typ[j]='l';
5445       }
5446     }
5447   }
5448 /* if the lcmb was not part of the surface then replace the single lines by the new line */
5449   if(!p)
5450   {
5451     for (i=0; i<anzGeo->s; i++) if( surf[i].name != (char *)NULL )
5452     {
5453       p=0;
5454       for (j=0; j<surf[i].nl; j++)
5455       {
5456         for (k=0; k<lcmb[c].nl; k++)
5457         {
5458           if(( lcmb[c].l[k] == surf[i].l[j] )&&( surf[i].typ[j]=='l' ))
5459 	  {
5460             if(!p)
5461             {
5462               p=1;
5463               surf[i].l[j]=l;
5464               surf[i].typ[j]='l';
5465             }
5466             else
5467 	    {
5468               /* just remove the line from the surf */
5469               //printf ("remove line:%s \n", line[surf[i].l[j]].name );
5470               for (n=j; n<surf[i].nl-1; n++)
5471               {
5472                 //printf (" replace line:%s with line:%s\n", line[surf[i].l[n]].name, line[surf[i].1[n+1]].name );
5473                 surf[i].l[n]=surf[i].l[n+1];
5474                 surf[i].o[n]=surf[i].o[n+1];
5475                 surf[i].typ[n]=surf[i].typ[n+1];
5476 	      }
5477               surf[i].nl--;
5478               j--;
5479             }
5480           }
5481 	}
5482       }
5483     }
5484   }
5485 
5486   /* replace the lcmb by the new line in all sets */
5487   for (i=1; i<anz->sets; i++)
5488   {
5489     if((set[i].name!=(char *)NULL)&&(set[i].name[0]!='-')&&( getIndex(&set[i].lcmb,set[i].anz_c, c) >-1))
5490       seta( i, "l", l );
5491   }
5492 
5493   delLine( lcmb[c].nl, lcmb[c].l );
5494   delLcmb( 1, &c );
5495   updateDispLists();
5496   return;
5497 }
5498 
5499 
5500 /* makes a seqence-line from an arc or straight line */
convertLine(int l,int div)5501 void convertLine( int l, int div )
5502 {
5503   int k, p, setNr;
5504   double pn[3], bias;
5505   char name[MAX_LINE_LENGTH];
5506 
5507   /* define a sequence */
5508   if( getNewName( name, "se" ) == -1 )
5509   {
5510     printf("ERROR: point could not be created\n");
5511     return;
5512   }
5513   if( (setNr=pre_seta( name, "is", 0)) <0 ) return;
5514   seta( setNr, "p", line[l].p1 );
5515   bias=line[l].bias;
5516   line[l].bias=1.;
5517 
5518   /* create spline points */
5519   /* and define a sequence */
5520   for (k=0; k<div; k++)
5521   {
5522     if (line[l].typ=='a') arcNodes( l, k, div+1, pn );
5523     else if (line[l].typ=='n') nurlNodes( l, k, div+1, pn );
5524     else if (line[l].typ=='s') splineNodes( l, k, div+1, pn );
5525     else straightNodes( l, k, div+1, pn );
5526     if( getNewName( name, "p" ) == -1 )
5527     {
5528       printf("ERROR: point could not be created\n");
5529       return;
5530     }
5531     if(printFlag) printf (" pnt=%s x=%lf y=%lf z=%lf\n",  name, pn[0], pn[1], pn[2]);
5532     p=pnt( name, pn[0], pn[1], pn[2], 0 );
5533     if( p<0) printf("ERROR: point could not be created\n");
5534     seta( setNr, "p", p );
5535   }
5536   seta( setNr, "p", line[l].p2 );
5537   line_i( line[l].name, line[l].p1, line[l].p2, setNr, line[l].div, bias, 's' );
5538   return;
5539 }
5540 
5541 
5542 
5543 
AsplitL_l(double * b,double * eu,double * ev,double * eg)5544 double AsplitL_l( double *b, double *eu, double *ev, double *eg )
5545 /******************************************************************/
5546 /*   Grade (eg) schneidet Ebene (eu,ev) return g                  */
5547 /*   determinante dritter Ordnung                                 */
5548 /*   b= Abstand zwischen den Aufpunkten der Linie und Ebene       */
5549 /*   b=eu*u + ev*v + eg *g  (e: Einheitsvektoren )                */
5550 /******************************************************************/
5551 {
5552   double g, D, Dg, a, c;
5553 
5554   a = eu[0]*ev[1]*eg[2]+ ev[0]*eg[1]*eu[2]+ eg[0]*eu[1]*ev[2];
5555   c = eg[0]*ev[1]*eu[2]+ eu[0]*eg[1]*ev[2]+ ev[0]*eu[1]*eg[2];
5556   D = a-c;
5557 
5558   a = eu[0]*ev[1]* b[2]+ ev[0]* b[1]*eu[2]+  b[0]*eu[1]*ev[2];
5559   c =  b[0]*ev[1]*eu[2]+ eu[0]* b[1]*ev[2]+ ev[0]*eu[1]* b[2];
5560   Dg= a-c;
5561   g = Dg / D;
5562   return (g);
5563 }
5564 
5565 
5566 /* creates the intersection point of two straight lines */
5567 /* not impl:(returns the mismatch in the intersection) */
intersectionPoint(double * l1p1,double * l1p2,double * l2p1,double * l2p2,double * ps)5568 int intersectionPoint( double *l1p1, double *l1p2, double *l2p1, double *l2p2, double *ps)
5569 {
5570   double l1_[3], l2_[3], ln_[3], en[3], eg[3], l2l1_p1[3], l2ps[3], l1ps[3];
5571   double eu[3], ev[3], g;
5572   double ps1[3], ps2[3], dist, dx,dy,dz;
5573 
5574   /* calc the intersection point 2 times */
5575   /* first in the direction of line 1 then in the direction of line 2 */
5576   /* if the difference between the two intersection points is bigger than gtol return(0) else (1) */
5577 
5578   /* ps on vector l2 */
5579     /* berechne den zweiten Einheitsvektor der Schnittebene, ev==Peilstrahl x Linie */
5580     v_result( l2p1, l2p2, l1_ );
5581     v_norm( l1_, eu );
5582     v_result( l1p1, l1p2, l2_ );
5583     v_prod( l1_, l2_, ln_ );
5584     v_norm( ln_, ev );
5585 
5586     /* berechne den Normalenvektor der Schnittebene */
5587     v_prod( eu, ev, en );
5588 
5589     /* berechne den Einheitsvektor der zu splitenden Linie */
5590     v_norm( l2_, eg );
5591 
5592     /* bestimme den Abstand zwischen den Aufpunkten der Linie und Ebene  */
5593     v_result( l1p1, l2p1, l2l1_p1 );
5594 
5595     /* berechne die Konstante g zur berechnung von ps (Schnittpunkt) ps=p0+eg*g  */
5596     g = AsplitL_l( l2l1_p1, eu, ev, eg );
5597 
5598     /* erzeuge den Schnittpunkt */
5599     v_scal( &g, eg, l1ps );
5600     v_add( l1p1, l1ps, ps1 );
5601 
5602   /* ps on vector l2 */
5603     /* berechne den zweiten Einheitsvektor der Schnittebene, ev==Peilstrahl x Linie */
5604     v_result( l1p1, l1p2, l1_ );
5605     v_norm( l1_, eu );
5606     v_result( l2p1, l2p2, l2_ );
5607     v_prod( l1_, l2_, ln_ );
5608     v_norm( ln_, ev );
5609 
5610     /* berechne den Normalenvektor der Schnittebene */
5611     v_prod( eu, ev, en );
5612 
5613     /* berechne den Einheitsvektor der zu splitenden Linie */
5614     v_norm( l2_, eg );
5615 
5616     /* bestimme den Abstand zwischen den Aufpunkten der Linie und Ebene  */
5617     v_result( l2p1, l1p1, l2l1_p1 );
5618 
5619     /* berechne die Konstante g zur berechnung von ps (Schnittpunkt) ps=p0+eg*g  */
5620     g = AsplitL_l( l2l1_p1, eu, ev, eg );
5621 
5622     /* erzeuge den Schnittpunkt */
5623     v_scal( &g, eg, l2ps );
5624     v_add( l2p1, l2ps, ps2 );
5625 
5626     /* calc the distance   */
5627     dx=ps1[0]-ps2[0];
5628     dy=ps1[1]-ps2[1];
5629     dz=ps1[2]-ps2[2];
5630     dist=dx*dx+dy*dy+dz*dz;
5631     //printf("dist:%lf %lf\n", sqrt(dist), sqrt(dist)*scale->w);
5632     if(dist<gtol/scale->w)
5633     {
5634       ps[0]=ps1[0]-dx*.5;
5635       ps[1]=ps1[1]-dy*.5;
5636       ps[2]=ps1[2]-dz*.5;
5637       return(1);
5638     }
5639   return(0);
5640 }
5641 
5642 
5643 /* return 1 or -1 if failed */
createFilletCenterPoint(double filletRadius,double * l1p1,double * l1p2,double * l2p1,double * l2p2,double * p1,double * p2,double * ps)5644 int createFilletCenterPoint( double filletRadius, double *l1p1, double *l1p2, double *l2p1, double *l2p2, double *p1, double *p2, double *ps)
5645 {
5646   double l1[3], l2[3], p1ps[3], p2ps[3];
5647   double eu[3], ev[3], ln[3];
5648   double l1p1b[3], l1p2b[3], l2p1b[3], l2p2b[3];
5649   double b[3],eg[3],g, lg[3];
5650 
5651   /* at first create the intersection if any */
5652   /* then create two new artificial lines running away from the intersection */
5653 
5654   if(intersectionPoint( l1p1, l1p2, l2p1, l2p2, ps) == 0) return(-1);
5655 
5656   /* two parallel lines are created. Offset is the radius. Were this lines intersect is the centerpnt ps */
5657   /* From the ps to the lines are the endpoints of the arc. (p1 p2) */
5658 
5659   v_result(l1p1,l1p2, l1);
5660   v_result(l2p1,l2p2, l2);
5661 
5662   /* determine the radius-vectors */
5663   v_prod( l1, l2, ln );
5664   v_prod( ln, l1, ev );
5665   v_norm( ev, eu );
5666   v_scal( &filletRadius, eu, p1ps );
5667 
5668   v_prod( l2, ln, ev );
5669   v_norm( ev, eu );
5670   v_scal( &filletRadius, eu, p2ps );
5671 
5672   /* new offseted lines which intersect to give ps */
5673   v_add(l1p1, p1ps, l1p1b);
5674   v_add(l1p2, p1ps, l1p2b);
5675   v_add(l2p1, p2ps, l2p1b);
5676   v_add(l2p2, p2ps, l2p2b);
5677 
5678   if(intersectionPoint( l1p1b, l1p2b, l2p1b, l2p2b, ps)==0) return(-1);
5679 
5680   /* create the endpoints of the arc on line l1 and l2 */
5681 
5682   v_norm( ln, ev );
5683 
5684   v_result(l1p1, ps, b);
5685   v_norm(p1ps , eu );
5686   v_norm( l1, eg );
5687   g= AsplitL( b, eu, ev, eg );
5688   v_scal( &g, eg, lg );
5689   v_add(l1p1, lg, p1);
5690 
5691   v_result(l2p1, ps, b);
5692   v_norm(p2ps , eu );
5693   v_norm( l2, eg );
5694   g= AsplitL( b, eu, ev, eg );
5695   v_scal( &g, eg, lg );
5696   v_add(l2p1, lg, p2);
5697 
5698   //for (i=0; i<3; i++) printf("p1:%f p2:%f\n", p1[i], p2[i]);
5699   //v_result(p1ps, ps, p1);
5700   //v_result(p2ps, ps, p2);
5701 
5702   return(1);
5703 }
5704 
5705 
5706 
createFillet(int lin,double filletRadius)5707 int createFillet(int lin, double filletRadius)
5708 {
5709   int i,j,n,p;
5710   static int linbuf[2];
5711   int dirl[2], p1nr, p2nr, psnr, l, l_nr[2], flipflop;
5712   double p1[3], p2[3], pint[2][3], ps[3], p1p2[3], p1ps[3];
5713   double lp1p2[2], lp1ps[2], lp1p2_buf[2], lp1ps_buf[2], dv[4][3], dist, min=MAX_FLOAT;
5714   double lps[2], lbez;
5715   int lp_ptr[2], lp_ptr_buf[2], lflag[2], icase=0, trkNew, trk, divbuffer[2];
5716 
5717   char name[MAX_LINE_LENGTH];
5718 
5719   typedef struct{
5720     int np;
5721     double **pnt;
5722   }Ltmp;
5723   Ltmp ltmp[2];
5724 
5725   if((line[lin].typ==' ')||( line[lin].typ=='s'))
5726   {
5727     if((intersectFlag)&&( lin==linbuf[0]))
5728     {
5729       printf("ERROR: second line:%s not selected because its the same as the first selected.\n", line[lin].name);
5730       return(-1);
5731     }
5732     linbuf[intersectFlag]=lin;
5733   }
5734   else
5735   {
5736     printf("ERROR: line:%s not selected. Only straight lines and splines are supported\n", line[lin].name);
5737     return(-1);
5738   }
5739 
5740   if((intersectFlag)&&( lin==linbuf[0]))
5741   {
5742     printf("ERROR: second line:%s not selected because its the same as the first selected.\n", line[lin].name);
5743     return(-1);
5744   }
5745   linbuf[intersectFlag]=lin;
5746 
5747   if(intersectFlag)
5748   {
5749     /* determine the closest combi of line-end-points determine the orientation of the lines relative to each other */
5750     v_result( &point[line[linbuf[0]].p1].px, &point[line[linbuf[1]].p1].px, dv[0] );
5751     v_result( &point[line[linbuf[0]].p2].px, &point[line[linbuf[1]].p2].px, dv[1] );
5752     v_result( &point[line[linbuf[0]].p1].px, &point[line[linbuf[1]].p2].px, dv[2] );
5753     v_result( &point[line[linbuf[0]].p2].px, &point[line[linbuf[1]].p1].px, dv[3] );
5754     for(i=0; i<4; i++)
5755     {
5756       dist=v_betrag(dv[i]);
5757       if(min>dist) { min=dist; icase=i; }
5758     }
5759     switch(icase)
5760     {
5761       case 0:
5762 	dirl[0]=1;
5763 	dirl[1]=1;
5764 	break;
5765       case 1:
5766 	dirl[0]=2;
5767 	dirl[1]=2;
5768 	break;
5769       case 2:
5770 	dirl[0]=1;
5771 	dirl[1]=2;
5772 	break;
5773       case 3:
5774 	dirl[0]=2;
5775 	dirl[1]=1;
5776 	break;
5777     }
5778 
5779     /* go over all divisions of the lines and determine the split-points */
5780     /* create two arrays ltmp[] of points based on the lines regarding their relative orientation */
5781 
5782     for(i=0; i<2; i++)
5783     {
5784       if(dirl[i]==1)  // line.p1 is startpnt
5785       {
5786         if(line[linbuf[i]].typ==' ')
5787 	{
5788           ltmp[i].np=2;
5789           if ((ltmp[i].pnt = (double **)malloc( (ltmp[i].np)*sizeof(double *)) ) == NULL )
5790           { printf("\n\nERROR: malloc failure\n"); return(-1); }
5791           for(j=0; j<ltmp[i].np; j++)
5792 	  {
5793             if ((ltmp[i].pnt[j] = (double *)malloc( (3)*sizeof(double)) ) == NULL )
5794             { printf("\n\nERROR: malloc failure\n"); return(-1); }
5795 	  }
5796           ltmp[i].pnt[0][0]=point[line[linbuf[i]].p1].px;
5797           ltmp[i].pnt[0][1]=point[line[linbuf[i]].p1].py;
5798           ltmp[i].pnt[0][2]=point[line[linbuf[i]].p1].pz;
5799           ltmp[i].pnt[1][0]=point[line[linbuf[i]].p2].px;
5800           ltmp[i].pnt[1][1]=point[line[linbuf[i]].p2].py;
5801           ltmp[i].pnt[1][2]=point[line[linbuf[i]].p2].pz;
5802 	}
5803 	else
5804 	{
5805           /* temporary increase the division */
5806 	  divbuffer[i]=line[linbuf[i]].div;
5807           line[linbuf[i]].div=98;
5808           repLine(linbuf[i]);
5809 
5810           ltmp[i].np=line[linbuf[i]].nip/3;
5811           if ((ltmp[i].pnt = (double **)malloc( (ltmp[i].np)*sizeof(double *)) ) == NULL )
5812           { printf("\n\nERROR: malloc failure\n"); return(-1); }
5813           for(j=0; j<ltmp[i].np; j++)
5814 	  {
5815             if ((ltmp[i].pnt[j] = (double *)malloc( (3)*sizeof(double)) ) == NULL )
5816             { printf("\n\nERROR: malloc failure\n"); return(-1); }
5817 	  }
5818           p=0;
5819           for(j=0; j<line[linbuf[i]].nip; j+=3)
5820           {
5821             ltmp[i].pnt[p][0]=line[linbuf[i]].ip[j];
5822             ltmp[i].pnt[p][1]=line[linbuf[i]].ip[j+1];
5823             ltmp[i].pnt[p][2]=line[linbuf[i]].ip[j+2];
5824             p++;
5825 	  }
5826 	}
5827       }
5828       else // line.p2 is startpnt
5829       {
5830         if(line[linbuf[i]].typ==' ')
5831 	{
5832           ltmp[i].np=2;
5833           if ((ltmp[i].pnt = (double **)malloc( (ltmp[i].np)*sizeof(double *)) ) == NULL )
5834           { printf("\n\nERROR: malloc failure\n"); return(-1); }
5835           for(j=0; j<ltmp[i].np; j++)
5836 	  {
5837             if ((ltmp[i].pnt[j] = (double *)malloc( (3)*sizeof(double)) ) == NULL )
5838             { printf("\n\nERROR: malloc failure\n"); return(-1); }
5839 	  }
5840           ltmp[i].pnt[0][0]=point[line[linbuf[i]].p2].px;
5841           ltmp[i].pnt[0][1]=point[line[linbuf[i]].p2].py;
5842           ltmp[i].pnt[0][2]=point[line[linbuf[i]].p2].pz;
5843           ltmp[i].pnt[1][0]=point[line[linbuf[i]].p1].px;
5844           ltmp[i].pnt[1][1]=point[line[linbuf[i]].p1].py;
5845           ltmp[i].pnt[1][2]=point[line[linbuf[i]].p1].pz;
5846 	}
5847 	else
5848 	{
5849           /* temporary increase the division */
5850 	  divbuffer[i]=line[linbuf[i]].div;
5851           line[linbuf[i]].div=98;
5852           repLine(linbuf[i]);
5853 
5854           ltmp[i].np=line[linbuf[i]].nip/3;
5855           if ((ltmp[i].pnt = (double **)malloc( (ltmp[i].np)*sizeof(double *)) ) == NULL )
5856           { printf("\n\nERROR: malloc failure\n"); return(-1); }
5857           for(j=0; j<ltmp[i].np; j++)
5858 	  {
5859             if ((ltmp[i].pnt[j] = (double *)malloc( (3)*sizeof(double)) ) == NULL )
5860             { printf("\n\nERROR: malloc failure\n"); return(-1); }
5861 	  }
5862           p=0;
5863           for(j=line[linbuf[i]].nip-3; j>0; j-=3)
5864           {
5865             ltmp[i].pnt[p][0]=line[linbuf[i]].ip[j];
5866             ltmp[i].pnt[p][1]=line[linbuf[i]].ip[j+1];
5867             ltmp[i].pnt[p][2]=line[linbuf[i]].ip[j+2];
5868             p++;
5869 	  }
5870 	}
5871       }
5872     }
5873 
5874     lflag[0]=1;
5875     lflag[1]=1;
5876     /* these pnt-indexes have to be changed due to the results of "searchIntersectionPoints()" */
5877     lp_ptr_buf[0]=lp_ptr[0]=0;
5878     lp_ptr_buf[1]=lp_ptr[1]=0;
5879     flipflop=0;
5880     do
5881     {
5882       if(createFilletCenterPoint( filletRadius, ltmp[0].pnt[lp_ptr[0]], ltmp[0].pnt[lp_ptr[0]+1], ltmp[1].pnt[lp_ptr[1]], ltmp[1].pnt[lp_ptr[1]+1], pint[0],pint[1],ps)==-1)
5883       {
5884         /* failed! free ltmp */
5885         for(i=0; i<2; i++)
5886         {
5887           /* restore the division */
5888           if(line[linbuf[i]].typ!=' ')
5889 	  {
5890             line[linbuf[i]].div=divbuffer[i];
5891             repLine(linbuf[i]);
5892 	  }
5893           for(j=0; j<ltmp[i].np; j++) free(ltmp[i].pnt[j]); free(ltmp[i].pnt);
5894         }
5895         printf(" ERROR: lines %s %s do not intersect based on a tolerance of:%lf\n", line[linbuf[0]].name, line[linbuf[1]].name, gtol);
5896         return(-1);
5897       }
5898 
5899       /* check if the intersection of the lines (p1,p2) is outside of the interval (ie. l1ptr, l1ptr+1) */
5900       for(i=0; i<2; i++)
5901       {
5902         v_result(ltmp[i].pnt[lp_ptr[i]], ltmp[i].pnt[lp_ptr[i]+1], p1p2);
5903         v_result(ltmp[i].pnt[lp_ptr[i]], pint[i], p1ps);
5904         lp1p2[i]=v_betrag(p1p2);
5905         lp1ps[i]=v_betrag(p1ps);
5906         if(v_sprod(p1ps,p1p2)<0.) lp1ps[i]*=-1;
5907 
5908         /* then adjust the interval */
5909 
5910         /* if lp1ps is <0 then decrease lp_ptr[i] */
5911         /* warning gtol might be set to a very high value to enable intersection, so better not use this */
5912         //if((lp1ps[i]<(-gtol/scale->w))&&(lp_ptr[i]>0)) lp_ptr[i]--;
5913         if((lp1ps[i]<(-1e-6))&&(lp_ptr[i]>0)) lp_ptr[i]--;
5914         /* if lp1ps is >lp1p2 then increase lp_ptr[i] */
5915         //else if((lp1ps[i]>(lp1p2[i]+gtol/scale->w))&&(lp_ptr[i]<ltmp[i].np-2)) lp_ptr[i]++;
5916         else if((lp1ps[i]>(lp1p2[i]+1e-6))&&(lp_ptr[i]<ltmp[i].np-2)) lp_ptr[i]++;
5917         /* if lp1ps is <=lp1p2 then break */
5918         else lflag[i]=0;
5919       }
5920       if(printFlag) printf("lflag %d %d\n", lflag[0],lflag[1]);
5921 
5922       /* escape endless loops */
5923       if(flipflop)
5924       {
5925         if((lp_ptr[0]==lp_ptr_buf[0])&&(lp_ptr[1]==lp_ptr_buf[1]))
5926         {
5927           for(i=0; i<2; i++)
5928           {
5929 	    lp_ptr[i]=lp_ptr_buf[i];
5930 	    lp1ps[i]=lp1ps_buf[i];
5931 	    lp1p2[i]=lp1p2_buf[i];
5932 	  }
5933           break;
5934         }
5935         for(i=0; i<2; i++)
5936         {
5937           lp_ptr_buf[i]=lp_ptr[i];
5938 	  lp1ps_buf[i]=lp1ps[i];
5939 	  lp1p2_buf[i]=lp1p2[i];
5940 	}
5941       }
5942       flipflop=!flipflop;
5943     }while( lflag[0] || lflag[1] );
5944 
5945     /* determine the line-length up to the split point, necessary for line-splitting */
5946     for(i=0; i<2; i++)
5947     {
5948       /* check if the split-point is outside */
5949       if(printFlag) printf("check line[%d]:%s of type:%c\n", i,line[linbuf[i]].name, line[linbuf[i]].typ);
5950       if(line[linbuf[i]].typ!='s') continue;
5951 
5952       /* restore the division */
5953       line[linbuf[i]].div=divbuffer[i];
5954       repLine(linbuf[i]);
5955 
5956       if(printFlag) printf("redefine the trkset of line[%d]:%s\n", i,line[linbuf[i]].name);
5957 
5958       /* determine the line-length up to the splitpoint */
5959       lps[i]=0.;
5960       for(j=0; j<lp_ptr[i]; j++)
5961       {
5962         v_result(ltmp[i].pnt[j], ltmp[i].pnt[j+1], p1p2);
5963         lps[i]+=v_betrag(p1p2);
5964       }
5965       lps[i]+=lp1ps[i];
5966 
5967       /* redefine the track-set */
5968       lbez=0.;
5969       getNewName( name, "se" );
5970       trkNew=pre_seta(name,"is",0);
5971       trk=line[linbuf[i]].trk;
5972       if(dirl[i]==1) /* remove the leading points and add the split-point */
5973       {
5974         seta( trkNew, "ps", set[trk].pnt[0] );  // will be redefined later
5975         for (j=0; j<set[trk].anz_p-1; j++)
5976         {
5977           v_result( &point[set[trk].pnt[j]].px, &point[set[trk].pnt[j+1]].px, p1p2 );
5978           lbez+=v_betrag( p1p2 );
5979           if(lbez>lps[i]) seta( trkNew, "ps", set[trk].pnt[j+1] );
5980         }
5981       }
5982       if(dirl[i]==2) /* remove the trailing points and add the split-point */
5983       {
5984         lps[i]=calcLineLength(linbuf[i])/scale->w-lps[i];
5985         seta( trkNew, "ps", set[trk].pnt[0] );
5986         for (j=0; j<set[trk].anz_p-1; j++)
5987         {
5988           v_result( &point[set[trk].pnt[j]].px, &point[set[trk].pnt[j+1]].px, p1p2 );
5989           lbez+=v_betrag( p1p2 );
5990 	  //printf("p %s %s lbez:%f lps[i]:%f\n", point[set[trk].pnt[j]].name,point[set[trk].pnt[j+1]].name, lbez, lps[i]);
5991           if(lbez<lps[i]) seta( trkNew, "ps", set[trk].pnt[j+1] );
5992           else break;
5993         }
5994         seta( trkNew, "ps", set[trk].pnt[set[trk].anz_p-1] );  // will be redefined later
5995       }
5996       line[linbuf[i]].trk=trkNew;
5997       delSet(set[trk].name);
5998     }
5999 
6000     /* free ltmp */
6001     for(i=0; i<2; i++) { for(j=0; j<ltmp[i].np; j++) free(ltmp[i].pnt[j]); free(ltmp[i].pnt); }
6002 
6003     /* create center point */
6004     p1[0]=pint[0][0];
6005     p1[1]=pint[0][1];
6006     p1[2]=pint[0][2];
6007     p2[0]=pint[1][0];
6008     p2[1]=pint[1][1];
6009     p2[2]=pint[1][2];
6010     getNewName( name, "p" );
6011     if(printFlag) printf(" create center point:%s %lf %lf %lf\n", name, ps[0], ps[1], ps[2] );
6012     psnr=pnt( name, ps[0], ps[1], ps[2], 0 );
6013 
6014     /* move one point of line 1 to p1 and one of line 2 to p2 */
6015     /* but if line 1&2 use a common point then replace the point from line 2 with a new point */
6016 
6017     if(dirl[0]==2) /* line points to the intersection */
6018     {
6019       p1nr=line[linbuf[0]].p2;
6020       point[line[linbuf[0]].p2].px=p1[0];
6021       point[line[linbuf[0]].p2].py=p1[1];
6022       point[line[linbuf[0]].p2].pz=p1[2];
6023     }
6024     else
6025     {
6026       p1nr=line[linbuf[0]].p1;
6027       point[line[linbuf[0]].p1].px=p1[0];
6028       point[line[linbuf[0]].p1].py=p1[1];
6029       point[line[linbuf[0]].p1].pz=p1[2];
6030     }
6031     if(dirl[1]==2) /* line points to the intersection */
6032     {
6033       if(p1nr==line[linbuf[1]].p2)
6034       {
6035         n= getNewName( name, "p" );
6036         printf(" create point:%s %lf %lf %lf\n", name, p2[0], p2[1], p2[2] );
6037         p2nr=pnt( name, p2[0], p2[1], p2[2], 0 );
6038         line[linbuf[1]].p2=p2nr;
6039         if(line[linbuf[1]].typ=='s') set[line[linbuf[1]].trk].pnt[set[line[linbuf[1]].trk].anz_p-1]=p2nr;
6040       }
6041       else
6042       {
6043         p2nr=line[linbuf[1]].p2;
6044         point[line[linbuf[1]].p2].px=p2[0];
6045         point[line[linbuf[1]].p2].py=p2[1];
6046         point[line[linbuf[1]].p2].pz=p2[2];
6047       }
6048     }
6049     else
6050     {
6051       if(p1nr==line[linbuf[1]].p1)
6052       {
6053         n= getNewName( name, "p" );
6054         printf(" create point:%s %lf %lf %lf\n", name, p2[0], p2[1], p2[2] );
6055         p2nr=pnt( name, p2[0], p2[1], p2[2], 0 );
6056         line[linbuf[1]].p1=p2nr;
6057         if(line[linbuf[1]].typ=='s') set[line[linbuf[1]].trk].pnt[0]=p2nr;
6058       }
6059       else
6060       {
6061         p2nr=line[linbuf[1]].p1;
6062         point[line[linbuf[1]].p1].px=p2[0];
6063         point[line[linbuf[1]].p1].py=p2[1];
6064         point[line[linbuf[1]].p1].pz=p2[2];
6065       }
6066     }
6067 
6068     /* create the arc */
6069     l= getNewName( name, "l" );
6070     if ( l == -1 )
6071     { printf("copy: could not create new line\n"); return(-1); }
6072     l_nr[1]=line_i( name, p1nr, p2nr, psnr, 0, 1, 'a' );
6073 
6074     /* add the arc to all higher entities which use line 2 */
6075     /* code from qsplitLine() */
6076     l_nr[0]=l=linbuf[1];
6077 
6078     /* untersuche alle lcmbs ob linbuf ein Mitglied ist */
6079     for (i=0; i<anzGeo->c; i++) if( lcmb[i].name != (char *)NULL )
6080     {
6081       for (j=0; j<lcmb[i].nl; j++)
6082       {
6083         if( l == lcmb[i].l[j] )
6084         {
6085           printf (" realloc lcmb:%s and replace line:%s with %s and %s \n",
6086              lcmb[i].name, line[l].name,line[l_nr[0]].name, line[l_nr[1]].name );
6087           if ((lcmb[i].o = (char *)realloc( (char *)lcmb[i].o, (lcmb[i].nl+1)*sizeof(char)) ) == NULL )
6088           { printf("\n\n ERROR: realloc failure in qspl, lcmb.o:%s not changed\n\n",lcmb[i].name ); return(-1); }
6089           if ((lcmb[i].l = (int *)realloc( (int *)lcmb[i].l, (lcmb[i].nl+1)*sizeof(int)) ) == NULL )
6090           { printf("\n\n ERROR: realloc failure in qspl, lcmb.l:%s not changed\n\n", lcmb[i].name); return(-1); }
6091   	  /* umspeichern der linien beginnend bei der letzten bis einschlieslich j */
6092           for (n=lcmb[i].nl; n>j; n--)
6093   	  {
6094             lcmb[i].o[n]=lcmb[i].o[n-1];
6095             lcmb[i].l[n]=lcmb[i].l[n-1];
6096           }
6097           /* Auffuellen der j, j+1 pos. mit l1, l2 mit der Orientierung der gesplitteten linie */
6098           lcmb[i].o[j]=lcmb[i].o[j+1];
6099           lcmb[i].l[j]=l_nr[0];
6100           lcmb[i].o[j+1]=lcmb[i].o[j];
6101           lcmb[i].l[j+1]=l_nr[1];
6102           lcmb[i].nl++;
6103         }
6104       }
6105     }
6106 
6107     /* untersuche alle surfs ob linbuf ein Mitglied ist und ersetze sie durch eine lcmb */
6108     /* kontrolliere ob nicht schon eine geeignete lcmb existiert */
6109     for (i=0; i<anzGeo->s; i++) if( surf[i].name != (char *)NULL )
6110     {
6111       for (j=0; j<surf[i].nl; j++)
6112       {
6113         if(( l == surf[i].l[j] )&&( surf[i].typ[j]=='l' ))
6114         {
6115 
6116           /* do we already have a suitable lcmb? */
6117           for (n=0; n<anzGeo->c; n++ ) if( lcmb[n].name != (char *)NULL )
6118   	  {
6119             if (lcmb[n].nl==2)   /* same amount of lines */
6120   	    {
6121   	    /*
6122               printf ("checke lcmb:%s \n", lcmb[n].name);
6123   	    */
6124               if (((lcmb[n].l[0]==l_nr[0])||(lcmb[n].l[0]==l_nr[1])) && ((lcmb[n].l[1]==l_nr[0])||(lcmb[n].l[1]==l_nr[1])))
6125   	      {
6126   	      /*
6127                 printf ("equal:%s\n",lcmb[n].name);
6128   	      */
6129                 break;
6130   	      }
6131   	    }
6132           }
6133           if (n>=anzGeo->c)  /* no lcmb was found, so create one */
6134           {
6135             /* create lcmb */
6136             if ( getNewName( name, "c" ) == -1 )
6137             { printf("Type c not known, lcmb can not be created\n"); exit(-1); }
6138             lcmb_i( name, (int)0, (int)2, "++", l_nr );
6139             n=getLcmbNr( name );
6140           }
6141           printf ("realloc surf:%s and replace line:%s with lcmb:%s made of %s and %s \n",
6142             surf[i].name, line[l].name, name, line[l_nr[0]].name, line[l_nr[1]].name );
6143           if (n>-1) { surf[i].l[j]=n; surf[i].o[j]='+'; surf[i].typ[j]='c'; }
6144           else { errMsg("lcmb not known, surface could not be changed \n"); return(-1); }
6145         }
6146       }
6147     }
6148     updateDispLists();
6149   }
6150 
6151   intersectFlag=!intersectFlag;
6152   return(intersectFlag);
6153 }
6154 
6155 
intersect(int lin)6156 int intersect(int lin)
6157 {
6158   int i,j,p;
6159   static int linbuf[2];
6160   int dirl[2], p1nr, p2nr, l, flipflop, breakflag=0;
6161   double ps[3], p1p2[3], p1ps[3];
6162   double lp1p2[2], lp1ps[2], lp1p2_buf[2], lp1ps_buf[2], dv[4][3], dist, min=MAX_FLOAT;
6163   double lps[2], lbez=0;
6164   int lp_ptr[2], lp_ptr_buf[2], lflag[2], icase=0, trkNew, trk, divbuffer[2];
6165 
6166   char name[MAX_LINE_LENGTH];
6167 
6168   typedef struct{
6169     int np;
6170     double **pnt;
6171   }Ltmp;
6172   Ltmp ltmp[2];
6173 
6174   if((line[lin].typ==' ')||( line[lin].typ=='s'))
6175   {
6176     if((intersectFlag)&&( lin==linbuf[0]))
6177     {
6178       printf("ERROR: second line:%s not selected because its the same as the first selected.\n", line[lin].name);
6179       return(-1);
6180     }
6181     linbuf[intersectFlag]=lin;
6182   }
6183   else
6184   {
6185     printf("ERROR: line:%s not selected. Only straight lines and splines are supported\n", line[lin].name);
6186     return(-1);
6187   }
6188 
6189   if((intersectFlag)&&( lin==linbuf[0]))
6190   {
6191     printf("ERROR: second line:%s not selected because its the same as the first selected.\n", line[lin].name);
6192     return(-1);
6193   }
6194   linbuf[intersectFlag]=lin;
6195 
6196   if(intersectFlag)
6197   {
6198     /* determine the closest combi of line-end-points determine the orientation of the lines relative to each other */
6199     v_result( &point[line[linbuf[0]].p1].px, &point[line[linbuf[1]].p1].px, dv[0] );
6200     v_result( &point[line[linbuf[0]].p2].px, &point[line[linbuf[1]].p2].px, dv[1] );
6201     v_result( &point[line[linbuf[0]].p1].px, &point[line[linbuf[1]].p2].px, dv[2] );
6202     v_result( &point[line[linbuf[0]].p2].px, &point[line[linbuf[1]].p1].px, dv[3] );
6203     icase=4;
6204     for(i=0; i<4; i++)
6205     {
6206       dist=v_betrag(dv[i]);
6207       if(min>dist) { min=dist; icase=i; }
6208     }
6209     switch(icase)
6210     {
6211       case 0:
6212 	dirl[0]=1;
6213 	dirl[1]=1;
6214 	break;
6215       case 1:
6216 	dirl[0]=2;
6217 	dirl[1]=2;
6218 	break;
6219       case 2:
6220 	dirl[0]=1;
6221 	dirl[1]=2;
6222 	break;
6223       case 3:
6224 	dirl[0]=2;
6225 	dirl[1]=1;
6226 	break;
6227 	printf("ERROR: icase:%d not known, talk to the programmer\n", icase);
6228         return(0);
6229     }
6230 
6231     /* go over all divisions of the lines and determine the split-points */
6232     /* create two arrays ltmp[] of points based on the lines regarding their relative orientation */
6233 
6234     for(i=0; i<2; i++)
6235     {
6236       if(dirl[i]==1)  // line.p1 is startpnt
6237       {
6238         if(line[linbuf[i]].typ==' ')
6239 	{
6240           ltmp[i].np=2;
6241           if ((ltmp[i].pnt = (double **)malloc( (ltmp[i].np)*sizeof(double *)) ) == NULL )
6242           { printf("\n\nERROR: malloc failure\n"); return(-1); }
6243           for(j=0; j<ltmp[i].np; j++)
6244 	  {
6245             if ((ltmp[i].pnt[j] = (double *)malloc( (3)*sizeof(double)) ) == NULL )
6246             { printf("\n\nERROR: malloc failure\n"); return(-1); }
6247 	  }
6248           ltmp[i].pnt[0][0]=point[line[linbuf[i]].p1].px;
6249           ltmp[i].pnt[0][1]=point[line[linbuf[i]].p1].py;
6250           ltmp[i].pnt[0][2]=point[line[linbuf[i]].p1].pz;
6251           ltmp[i].pnt[1][0]=point[line[linbuf[i]].p2].px;
6252           ltmp[i].pnt[1][1]=point[line[linbuf[i]].p2].py;
6253           ltmp[i].pnt[1][2]=point[line[linbuf[i]].p2].pz;
6254 	}
6255 	else
6256 	{
6257           /* temporary increase the division */
6258 	  divbuffer[i]=line[linbuf[i]].div;
6259           line[linbuf[i]].div=98;
6260           repLine(linbuf[i]);
6261 
6262           ltmp[i].np=line[linbuf[i]].nip/3;
6263           if ((ltmp[i].pnt = (double **)malloc( (ltmp[i].np)*sizeof(double *)) ) == NULL )
6264           { printf("\n\nERROR: malloc failure\n"); return(-1); }
6265           for(j=0; j<ltmp[i].np; j++)
6266 	  {
6267             if ((ltmp[i].pnt[j] = (double *)malloc( (3)*sizeof(double)) ) == NULL )
6268             { printf("\n\nERROR: malloc failure\n"); return(-1); }
6269 	  }
6270           p=0;
6271           for(j=0; j<line[linbuf[i]].nip; j+=3)
6272           {
6273             ltmp[i].pnt[p][0]=line[linbuf[i]].ip[j];
6274             ltmp[i].pnt[p][1]=line[linbuf[i]].ip[j+1];
6275             ltmp[i].pnt[p][2]=line[linbuf[i]].ip[j+2];
6276             p++;
6277 	  }
6278 	}
6279       }
6280       else // line.p2 is startpnt
6281       {
6282         if(line[linbuf[i]].typ==' ')
6283 	{
6284           ltmp[i].np=2;
6285           if ((ltmp[i].pnt = (double **)malloc( (ltmp[i].np)*sizeof(double *)) ) == NULL )
6286           { printf("\n\nERROR: malloc failure\n"); return(-1); }
6287           for(j=0; j<ltmp[i].np; j++)
6288 	  {
6289             if ((ltmp[i].pnt[j] = (double *)malloc( (3)*sizeof(double)) ) == NULL )
6290             { printf("\n\nERROR: malloc failure\n"); return(-1); }
6291 	  }
6292           ltmp[i].pnt[0][0]=point[line[linbuf[i]].p2].px;
6293           ltmp[i].pnt[0][1]=point[line[linbuf[i]].p2].py;
6294           ltmp[i].pnt[0][2]=point[line[linbuf[i]].p2].pz;
6295           ltmp[i].pnt[1][0]=point[line[linbuf[i]].p1].px;
6296           ltmp[i].pnt[1][1]=point[line[linbuf[i]].p1].py;
6297           ltmp[i].pnt[1][2]=point[line[linbuf[i]].p1].pz;
6298 	}
6299 	else
6300 	{
6301           /* temporary increase the division */
6302 	  divbuffer[i]=line[linbuf[i]].div;
6303           line[linbuf[i]].div=98;
6304           repLine(linbuf[i]);
6305 
6306           ltmp[i].np=line[linbuf[i]].nip/3;
6307           if ((ltmp[i].pnt = (double **)malloc( (ltmp[i].np)*sizeof(double *)) ) == NULL )
6308           { printf("\n\nERROR: malloc failure\n"); return(-1); }
6309           for(j=0; j<ltmp[i].np; j++)
6310 	  {
6311             if ((ltmp[i].pnt[j] = (double *)malloc( (3)*sizeof(double)) ) == NULL )
6312             { printf("\n\nERROR: malloc failure\n"); return(-1); }
6313 	  }
6314           p=0;
6315           for(j=line[linbuf[i]].nip-3; j>0; j-=3)
6316           {
6317             ltmp[i].pnt[p][0]=line[linbuf[i]].ip[j];
6318             ltmp[i].pnt[p][1]=line[linbuf[i]].ip[j+1];
6319             ltmp[i].pnt[p][2]=line[linbuf[i]].ip[j+2];
6320             p++;
6321 	  }
6322 	}
6323       }
6324     }
6325 
6326     lflag[0]=1;
6327     lflag[1]=1;
6328     /* these pnt-indexes have to be changed due to the results of "searchIntersectionPoints()" */
6329     lp_ptr_buf[0]=lp_ptr[0]=0;
6330     lp_ptr_buf[1]=lp_ptr[1]=0;
6331     flipflop=0;
6332     do
6333     {
6334       if(intersectionPoint( ltmp[0].pnt[lp_ptr[0]], ltmp[0].pnt[lp_ptr[0]+1], ltmp[1].pnt[lp_ptr[1]], ltmp[1].pnt[lp_ptr[1]+1], ps) == 0)
6335       {
6336         /* failed! free ltmp */
6337         for(i=0; i<2; i++)
6338         {
6339           /* restore the division */
6340           if(line[linbuf[i]].typ!=' ')
6341 	  {
6342             line[linbuf[i]].div=divbuffer[i];
6343             repLine(linbuf[i]);
6344 	  }
6345           for(j=0; j<ltmp[i].np; j++) free(ltmp[i].pnt[j]); free(ltmp[i].pnt);
6346         }
6347         printf(" ERROR: lines %s %s do not intersect based on a tolerance of:%lf\n", line[linbuf[0]].name, line[linbuf[1]].name, gtol);
6348         return(-1);
6349       }
6350 
6351       /* check if the intersection of the lines (ps) is outside of the interval (ie. l1ptr, l1ptr+1) */
6352       for(i=0; i<2; i++)
6353       {
6354         v_result(ltmp[i].pnt[lp_ptr[i]], ltmp[i].pnt[lp_ptr[i]+1], p1p2);
6355         v_result(ltmp[i].pnt[lp_ptr[i]], ps, p1ps);
6356         lp1p2[i]=v_betrag(p1p2);
6357         lp1ps[i]=v_betrag(p1ps);
6358         if(v_sprod(p1ps,p1p2)<0.) lp1ps[i]*=-1;
6359 
6360         /* then adjust the interval */
6361 
6362         /* if lp1ps is <0 then decrease lp_ptr[i] */
6363         /* warning gtol might be set to a very high value to enable intersection, so better not use this */
6364         //if((lp1ps[i]<(-gtol/scale->w))&&(lp_ptr[i]>0)) lp_ptr[i]--;
6365         if((lp1ps[i]<(-1e-6))&&(lp_ptr[i]>0)) lp_ptr[i]--;
6366         /* if lp1ps is >lp1p2 then increase lp_ptr[i] */
6367         //else if((lp1ps[i]>(lp1p2[i]+gtol/scale->w))&&(lp_ptr[i]<ltmp[i].np-2)) lp_ptr[i]++;
6368         else if((lp1ps[i]>(lp1p2[i]+1e-6))&&(lp_ptr[i]<ltmp[i].np-2)) lp_ptr[i]++;
6369         /* if lp1ps is <=lp1p2 then break */
6370         else lflag[i]=0;
6371       }
6372       if(printFlag) printf("lflag %d %d\n", lflag[0],lflag[1]);
6373 
6374       /* escape endless loops */
6375       if(flipflop)
6376       {
6377         if((lp_ptr[0]==lp_ptr_buf[0])&&(lp_ptr[1]==lp_ptr_buf[1]))
6378         {
6379           breakflag=1;
6380           for(i=0; i<2; i++)
6381           {
6382 	    lp_ptr[i]=lp_ptr_buf[i];
6383 	    lp1ps[i]=lp1ps_buf[i];
6384 	    lp1p2[i]=lp1p2_buf[i];
6385 	  }
6386           break;
6387         }
6388         for(i=0; i<2; i++)
6389         {
6390           lp_ptr_buf[i]=lp_ptr[i];
6391 	  lp1ps_buf[i]=lp1ps[i];
6392 	  lp1p2_buf[i]=lp1p2[i];
6393 	}
6394       }
6395       flipflop=!flipflop;
6396     }while( lflag[0] || lflag[1] );
6397 
6398     /* determine the line-length up to the split point, necessary for line-splitting */
6399     for(i=0; i<2; i++)
6400     {
6401       /* check if the split-point is outside */
6402       if(printFlag) printf("check line[%d]:%s\n", i,line[linbuf[i]].name);
6403       if(line[linbuf[i]].typ!='s') continue;
6404 
6405       /* restore the division */
6406       line[linbuf[i]].div=divbuffer[i];
6407       repLine(linbuf[i]);
6408 
6409       if(!breakflag) if((lp1ps[i]<=0)||(lp1ps[i]>=lp1p2[i])) continue;
6410 
6411       if(printFlag) printf("redefine the trkset of line[%d]:%s\n", i,line[linbuf[i]].name);
6412 
6413       /* determine the line-length up to the splitpoint */
6414       lps[i]=0.;
6415       for(j=0; j<lp_ptr[i]; j++)
6416       {
6417         v_result(ltmp[i].pnt[j], ltmp[i].pnt[j+1], p1p2);
6418         lps[i]+=v_betrag(p1p2);
6419       }
6420       lps[i]+=lp1ps[i];
6421 
6422 
6423       /* redefine the track-set */
6424       lbez=0.;
6425       getNewName( name, "se" );
6426       trkNew=pre_seta(name,"is",0);
6427       trk=line[linbuf[i]].trk;
6428       if(dirl[i]==1) /* remove the leading points and add the split-point */
6429       {
6430         seta( trkNew, "ps", set[trk].pnt[0] );  // will be redefined later
6431         for (j=0; j<set[trk].anz_p-1; j++)
6432         {
6433           v_result( &point[set[trk].pnt[j]].px, &point[set[trk].pnt[j+1]].px, p1p2 );
6434           lbez+=v_betrag( p1p2 );
6435           if(lbez>lps[i]) seta( trkNew, "ps", set[trk].pnt[j+1] );
6436         }
6437       }
6438       if(dirl[i]==2) /* remove the trailing points and add the split-point */
6439       {
6440         lps[i]=calcLineLength(linbuf[i])/scale->w-lps[i];
6441         seta( trkNew, "ps", set[trk].pnt[0] );
6442         for (j=0; j<set[trk].anz_p-1; j++)
6443         {
6444           v_result( &point[set[trk].pnt[j]].px, &point[set[trk].pnt[j+1]].px, p1p2 );
6445           lbez+=v_betrag( p1p2 );
6446           if(lbez<lps[i]) seta( trkNew, "ps", set[trk].pnt[j+1] );
6447           else break;
6448         }
6449         seta( trkNew, "ps", set[trk].pnt[set[trk].anz_p-1] );  // will be redefined later
6450       }
6451       line[linbuf[i]].trk=trkNew;
6452       delSet(set[trk].name);
6453     }
6454 
6455     /* free ltmp */
6456     for(i=0; i<2; i++) { for(j=0; j<ltmp[i].np; j++) free(ltmp[i].pnt[j]); free(ltmp[i].pnt); }
6457 
6458 
6459     if(dirl[0]==2) /* line points to the intersection */
6460     {
6461       p1nr=line[linbuf[0]].p2;
6462       point[line[linbuf[0]].p2].px=ps[0];
6463       point[line[linbuf[0]].p2].py=ps[1];
6464       point[line[linbuf[0]].p2].pz=ps[2];
6465     }
6466     else
6467     {
6468       p1nr=line[linbuf[0]].p1;
6469       point[line[linbuf[0]].p1].px=ps[0];
6470       point[line[linbuf[0]].p1].py=ps[1];
6471       point[line[linbuf[0]].p1].pz=ps[2];
6472     }
6473     if(dirl[1]==2) /* line points to the intersection */
6474     {
6475         p2nr=line[linbuf[1]].p2;
6476         point[line[linbuf[1]].p2].px=ps[0];
6477         point[line[linbuf[1]].p2].py=ps[1];
6478         point[line[linbuf[1]].p2].pz=ps[2];
6479     }
6480     else
6481     {
6482         p2nr=line[linbuf[1]].p1;
6483         point[line[linbuf[1]].p1].px=ps[0];
6484         point[line[linbuf[1]].p1].py=ps[1];
6485         point[line[linbuf[1]].p1].pz=ps[2];
6486     }
6487 
6488     /* check if a line is running from ps_line1 to ps_line2 and delete this (will have 0 length) */
6489     for (j=0; j<set[setall].anz_l; j++)
6490     {
6491       l=set[setall].line[j];
6492       if( ((line[l].p1==p1nr)||(line[l].p1==p2nr)) && ((line[l].p2==p1nr)||(line[l].p2==p2nr)) )
6493       {
6494         printf(" line:%s was detected between the intersecting lines and is deleted\n", line[l].name);
6495         pre_seta(specialset->zap, "l", line[l].name);
6496         zap(specialset->zap);
6497         //delLine( 1, &l );
6498       }
6499     }
6500     updateDispLists();
6501   }
6502 
6503   intersectFlag=!intersectFlag;
6504   return(intersectFlag);
6505 }
6506 
6507 
6508 
6509 #define DS 10000
6510 #define MIN_SPROD 1.e30
qsplitLine(int l,int x,int y)6511 int qsplitLine( int l, int x, int y )
6512 {
6513   int k;
6514   double p0[3], p1[3], p01[3], pm0[3], pm1[3], pm01[3], pm02[3], p0pm0[3], ps[3], p0ps[3];
6515   double eu[3], ev[3], en[3], eg[3], g;
6516   int   p1_nr, p2_nr, ps_nr, l_nr[2], line_bias;
6517   char name[MAX_LINE_LENGTH], trk[2][MAX_LINE_LENGTH];
6518   double sprod_pk[DS], ek[2][3], pm00[3], pm0k[3];
6519   double pk[2][3], ps_lbez=0;
6520   double min_sprod, sprod_euek;
6521 
6522   double pbuf[3];
6523 
6524   GLint    viewport[4];
6525   GLdouble mvmatrix[16], projmatrix[16];
6526 
6527   static GLdouble wx, wy, wz;  /*  returned world x, y, z coords  */
6528   static GLdouble nx, ny, nz;  /*  new world x, y, z coords  */
6529   static int flag;
6530 
6531 
6532   /* erzeugen von zwei Raumpunkten auf dem Mauspeilstrahl (MausPos.-Z-Richtung) */
6533 
6534   /* first create a temporary point in window-z direction at cursor-x,y pos.  */
6535   glutSetWindow( w1);
6536   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
6537   glLoadIdentity();
6538   moveModel();
6539   glGetIntegerv (GL_VIEWPORT, viewport);
6540   glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);
6541   glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
6542 
6543   flag=gluProject( centerPnt[0], centerPnt[1], centerPnt[2], mvmatrix, projmatrix,
6544      viewport,  &wx, &wy, &wz);
6545   if (flag==GL_FALSE)
6546   {
6547     printf(" ERROR: Malfunction in qsplitLine(), please reselect\n");
6548     return(-1);
6549   }
6550   /* printf (" Win coords are %d (%lf, %lf, %lf)\n",  flag,  wx   ,  wy   , wz     ); */
6551 
6552   wx=(GLdouble)x; wy=(GLdouble)(viewport[3]-y);
6553   flag=gluUnProject ( wx, wy, wz, mvmatrix, projmatrix, viewport, &nx, &ny, &nz);
6554   /* printf ("new World coords are %d (%lf, %lf, %lf)\n", flag, nx, ny, nz); */
6555   if (flag==GL_TRUE)
6556   {
6557     pm0[0]=nx;
6558     pm0[1]=ny;
6559     pm0[2]=nz;
6560   }
6561   else
6562   {
6563     printf(" ERROR: Malfunction in qsplitLine(), please reselect\n");
6564     return(-1);
6565   }
6566 
6567   wz++;
6568   flag=gluUnProject ( wx, wy, wz, mvmatrix, projmatrix, viewport, &nx, &ny, &nz);
6569   /* printf ("new World coords are %d (%lf, %lf, %lf)\n", flag, nx, ny, nz); */
6570   if (flag==GL_TRUE)
6571   {
6572     pm1[0]=nx;
6573     pm1[1]=ny;
6574     pm1[2]=nz;
6575   }
6576   else
6577   {
6578     printf(" ERROR: Malfunction in qsplitLine(), please reselect\n");
6579     return(-1);
6580   }
6581 
6582   /* split the first line (l) */
6583 
6584   /* berechne den ersten Einheitsvektor der Schnittebene, eu==Peilstrahlrichtung */
6585   v_result( pm0, pm1, pm01 );
6586   v_norm( pm01, eu );
6587 
6588   /* bestimme die Koordinaten der Linienendpunkte */
6589   p1_nr= line[l].p1;
6590   p0[0] = point[p1_nr].px;
6591   p0[1] = point[p1_nr].py;
6592   p0[2] = point[p1_nr].pz;
6593   p2_nr= line[l].p2;
6594   p1[0] = point[p2_nr].px;
6595   p1[1] = point[p2_nr].py;
6596   p1[2] = point[p2_nr].pz;
6597   /*
6598   printf("endpnt P1:%s %lf %lf %lf\n", point[line[l].p1].name, p0[0],p0[1],p0[2]);
6599   printf("endpnt P2:%s %lf %lf %lf\n", point[line[l].p2].name, p1[0],p1[1],p1[2]);
6600   */
6601 
6602   /* berechne den schnittpunkt der zu splittenden linie mit der ebene a(eu,ev) */
6603   ps_nr=-1;
6604   if( line[l].typ==' ')
6605   {
6606     /* berechne den zweiten Einheitsvektor der Schnittebene, ev==Peilstrahl x Linie */
6607     v_result( p0, p1, p01 );
6608     v_prod( pm01, p01, pm02 );
6609     v_norm( pm02, ev );
6610 
6611     /* berechne den Normalenvektor der Schnittebene */
6612     v_prod( eu, ev, en );
6613 
6614     /* berechne den Einheitsvektor der zu splitenden Linie */
6615     v_norm( p01, eg );
6616 
6617     /* bestimme den Abstand zwischen den Aufpunkten der Linie und Ebene  */
6618     v_result( p0, pm0, p0pm0 );
6619 
6620     /* berechne die Konstante g zur berechnung von ps (Schnittpunkt) ps=p0+eg*g  */
6621     g = AsplitL_l( p0pm0, eu, ev, eg );
6622 
6623     v_scal( &g, eg, p0ps );
6624     v_add( p0, p0ps, ps );
6625     strcpy(trk[0], " ");
6626     strcpy(trk[1], " ");
6627 
6628     /* erzeuge den Punkt */
6629     getNewName( name, "p" );
6630     printf(" create point:%s %lf %lf %lf\n", name, ps[0], ps[1], ps[2] );
6631     ps_nr  = pnt( name, ps[0], ps[1], ps[2], 0 );
6632   }
6633   else
6634   {
6635     /* Zerlege die linie in DS Teile und bestimme die durchtritte durch die Ebene */
6636     /* ein Durchtritt erfolgt, wenn das vorzeichen des skalarproduckts sich aendert */
6637     /* speichere den linienpunkt vor und hinter dem durchtritt fuer die spaetere */
6638     /* interpolation. Bestimme das dem peilstrahl am naechsten liegende punktepaar */
6639     /* das naechstliegende punktepaar ist das mit dem kleinsten skalarprodukt */
6640 
6641     /* berechne den Einheitsvektor zum 1. kontrollpunkt */
6642     pk[0][0]= p0[0];
6643     pk[0][1]= p0[1];
6644     pk[0][2]= p0[2];
6645     v_result( pm1, pk[0], pm00 );
6646     v_norm( pm00, ek[0] );
6647 
6648     flag=0;
6649     min_sprod=MIN_SPROD;
6650 
6651     /* set the line-bias to 1 for the search of the split-point */
6652     /* reset it after this operation to the original one */
6653     line_bias=line[l].bias;
6654     line[l].bias=1;
6655     for (k=0; k<DS; k++)
6656     {
6657       if (line[l].typ=='a')
6658       {
6659         if(arcNodes( l, k,(int) DS, pbuf )==-1)      { printf("ERROR in spliting\n"); }
6660       }
6661       else if (line[l].typ=='s')
6662       {
6663         if(splineNodes( l, k,(int) DS, pbuf )==-1)   { printf("ERROR in spliting\n"); }
6664       }
6665       pk[1][0]= pbuf[0];
6666       pk[1][1]= pbuf[1];
6667       pk[1][2]= pbuf[2];
6668 
6669 
6670       /* die richtung der schnittebene wird fuer jeden kontrollpunkt neu berechnet */
6671       /* berechne den zweiten Einheitsvektor der Schnittebene */
6672       v_result( pk[0], pk[1], p01 );
6673       v_prod( pm01, p01, pm02 );
6674       v_norm( pm02, ev );
6675 
6676       /* berechne den Normalenvektor der Schnittebene */
6677       v_prod( eu, ev, en );
6678 
6679       /* winkel zum ersten kontrollpunkt */
6680       sprod_pk[0]=v_sprod( en, ek[0]);
6681 
6682       /* berechne den Einheitsvektor zu diesem kontrollpunkt */
6683       v_result( pm1, pk[1], pm0k );
6684       v_norm( pm0k, ek[1] );
6685       sprod_pk[1]=v_sprod( en, ek[1]);
6686 
6687       /* haben wir einen durchstosspunkt? (vorzeichenwechsel von sprod)  */
6688       if( (sprod_pk[0]*sprod_pk[1]) <=0. )
6689       {
6690         flag=1;
6691         /* durchstoss gefunden, ist er der bisher naechstliegende? */
6692         sprod_euek=v_sprod( eu, ek[0])+v_sprod( eu, ek[1]);
6693 	/*
6694         printf("sprod_euek:%lf min_sprod:%lf k:%d DS:%d\n", sprod_euek, min_sprod,k,DS);
6695         printf(" pnt0:%lf %lf %lf sprod_pn:%lf\n", pk[0][0], pk[0][1], pk[0][2], sprod_pk[0]);
6696         printf(" pnt1:%lf %lf %lf sprod_pn:%lf\n", pk[1][0], pk[1][1], pk[1][2], sprod_pk[1]);
6697 	*/
6698 
6699         if( sprod_euek<min_sprod )
6700         {
6701           min_sprod=sprod_euek;
6702           p0[0] =pk[0][0] ;
6703           p0[1] =pk[0][1] ;
6704           p0[2] =pk[0][2] ;
6705           p1[0] =pk[1][0] ;
6706           p1[1] =pk[1][1] ;
6707           p1[2] =pk[1][2] ;
6708           ps_lbez=(double)k/(double)DS;           /* position, bezogene linienlaenge */
6709           /*
6710           printf(" min_sprod:%lf ps_lbez:%lf \n", min_sprod, ps_lbez );
6711           */
6712 	}
6713       }
6714       pk[0][0]=pk[1][0] ;
6715       pk[0][1]=pk[1][1] ;
6716       pk[0][2]=pk[1][2] ;
6717       ek[0][0]=ek[1][0] ;
6718       ek[0][1]=ek[1][1] ;
6719       ek[0][2]=ek[1][2] ;
6720     }
6721     /* reset the line-bias */
6722     line[l].bias=line_bias;
6723 
6724     /* uebernehme einen der durchstoss-punkte als splitpunkt */
6725     if(flag)
6726     {
6727       ps[0]=p0[0];
6728       ps[1]=p0[1];
6729       ps[2]=p0[2];
6730     }
6731     else
6732     {
6733       errMsg(" ERROR: Malfunction in qsplitLine(), please reselect\n");
6734       return(-1);
6735     }
6736 
6737     /* erzeuge den splitpunkt */
6738     getNewName( name, "p" );
6739     printf(" create point:%s %lf %lf %lf\n", name, ps[0], ps[1], ps[2] );
6740     ps_nr  = pnt( name, (double)ps[0], (double)ps[1], (double)ps[2], 0 );
6741   }
6742   if(ps_nr==-1)
6743   {
6744     errMsg(" ERROR: Malfunction in qsplitLine(), please reselect\n");
6745     return(-1);
6746   }
6747 
6748   splitLine(l, l_nr, ps_nr);
6749 
6750   /* loesche basislinie */
6751   delLine( 1, &l );
6752 
6753   updateDispLists();
6754   return(ps_nr);
6755 }
6756 
6757 
6758 
pre_align(int nr,int flag)6759 void pre_align( int nr, int flag )
6760 {
6761   static double p[3][3], p02[3], p01[3], p03[3], p03xz[3];
6762   double  ay, axz;
6763   double  p03_b, p03xz_b, scalar, sig;
6764 
6765   GLint    viewport[4];
6766   GLdouble mvmatrix[16], projmatrix[16];
6767 
6768   static GLdouble wx, wy, wz;  /*  returned world x, y, z coords  */
6769   static int flag2;
6770 
6771   glutSetWindow( w1);
6772   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
6773   glLoadIdentity();
6774   moveModel();
6775   glGetIntegerv (GL_VIEWPORT, viewport);
6776   glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);
6777   glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
6778 
6779   if (flag)
6780   {
6781     flag2=gluProject( point[nr].px, point[nr].py, point[nr].pz, mvmatrix, projmatrix,
6782       viewport,  &wx, &wy, &wz);
6783     if (flag2==GL_FALSE)
6784       printf("WARNING: Malfunction in movePoint(), please reselect\n");
6785   }
6786   else
6787   {
6788     flag2=gluProject( node[nr].nx, node[nr].ny, node[nr].nz, mvmatrix, projmatrix,
6789       viewport,  &wx, &wy, &wz);
6790     if (flag2==GL_FALSE)
6791       printf("WARNING: Malfunction in movePoint(), please reselect\n");
6792   }
6793 
6794   p[qaliCounter][0] = wx;
6795   p[qaliCounter][1] = wy;
6796   p[qaliCounter][2] = -wz*height_w1/ds*2.;
6797   qaliCounter++;
6798 
6799   if (qaliCounter == 1)
6800   {
6801     /* 1. Punkt gewaehlt == neuer Drehpunkt und neue Arbeitsebene */
6802   if (flag==0)
6803         center( node[nr].nx, node[nr].ny, node[nr].nz);
6804   if (flag==1)
6805         center( point[nr].px, point[nr].py, point[nr].pz);
6806   }
6807   if (qaliCounter == 3)
6808   {
6809     qaliCounter=0;
6810     /* 3 Punkte gewaehlt, berechne die Normale auf der Ebene */
6811     v_result( &p[0][0], &p[1][0],  p01);
6812     v_result( &p[0][0], &p[2][0],  p02);
6813     v_prod( p01, p02, p03 );
6814 
6815     /* Richtungsumkehr wenn die z-Komponente der Normalen nach hinten zeigt (-) */
6816     if (p03[2]<0)
6817     {
6818        p03[0]*=-1;
6819        p03[1]*=-1;
6820        p03[2]*=-1;
6821     }
6822     /* return wenn die ebene bereits zu der bildschirmebene paralel ist */
6823     if ((!p03[0])||(!p03[1])) return;
6824 
6825     /* drehe den Ort des Betrachters  */
6826     ay=atan(p03[0]/p03[2]);
6827 
6828     p03xz[0]=p03[0];
6829     p03xz[1]=0.;
6830     p03xz[2]=p03[2];
6831     scalar = v_sprod( p03xz, p03 );
6832     p03xz_b= v_betrag( p03xz );
6833     p03_b  = v_betrag( p03 );
6834     axz =acos( scalar/p03xz_b/p03_b ) * 180./PI;
6835 
6836     /* vorzeichen von der y-Komponente der Normalen wird zum vorzeichen von axz */
6837     scalar= sqrt(p03[1]*p03[1]);
6838     sig = p03[1]/scalar;
6839     axz = axz*sig;
6840 
6841     ay=ay*180./PI;
6842 
6843     rot_r( ay );
6844     rot_u( axz );
6845   }
6846 }
6847 
6848 
6849 
createSplitPoint(double * ns,double * n1,double * n2,double * pn,double * eu,double * ev)6850 double *createSplitPoint( double *ns, double *n1, double *n2, double *pn, double *eu, double *ev )
6851 {
6852   double eg[3], n1n2[3], n1pn[3], n1ns[3];
6853   double g;
6854 
6855   v_result( n1, n2, n1n2 );
6856 
6857   /* berechne den Einheitsvektor der zu splitenden Linie */
6858   v_norm( n1n2, eg );
6859 
6860   /* bestimme den Abstand zwischen den Aufpunkten der Linie und Ebene  */
6861   v_result( n1, pn, n1pn );
6862 
6863   /* berechne die Konstante g zur berechnung von ps (Schnittpunkt) ps=p0+eg*g  */
6864   g = AsplitL_l( n1pn, eu, ev, eg );
6865 
6866   /* pos von ns bezogen auf |n1n2| */
6867   ns[3] = g/v_betrag(n1n2);
6868   if(ns[3]>1.000001) return(NULL);
6869   if(ns[3]<-0.000001) return(NULL);
6870   v_scal( &g, eg, n1ns );
6871   v_add( n1, n1ns, ns );
6872   return(ns);
6873 
6874   /* winkel zw n1ns und n1n2 bestimmen. wenn >0 dann ist ns zwischen n1 und n2 */
6875   //if((double)((int)(g*1000)) < (g-1.)) return(NULL);
6876   //else if((v_sprod(n1ns,n1n2)>=0)&&((int)(g*1000)<=(int)(v_betrag(n1n2)*1000))) return(ns);
6877   //else return(NULL);
6878 }
6879 
6880 
6881 /* calculate values for all Datasets on new nodes */
updLcase(int lc,int setNr)6882 void updLcase(int lc, int setNr)
6883 {
6884   int i,j,k,n, compareChars;
6885   char buffer[2][MAX_LINE_LENGTH];
6886   double s[6], p[3];
6887   if(!anz->l) return;
6888 
6889  next_lc:;
6890 
6891   /* check if the data of the specified lcase (Dataset) are already available */
6892   if (!lcase[lc].loaded)
6893   {
6894     if( pre_readfrdblock(copiedNodeSets , lc, anz, node, lcase )==-1)
6895     {
6896       printf("ERROR in updLcase: Could not read data for Dataset:%d\n", lc+1);
6897       return;
6898     }
6899     calcDatasets( lc, anz, node, lcase );
6900     recompileEntitiesInMenu(lc);
6901   }
6902 
6903   for(i=0; i<lcase[lc].ncomps; i++)
6904   {
6905     if ( (lcase[lc].dat[i] = (float *)realloc(lcase[lc].dat[i], (anz->nmax+1) * sizeof(float))) == NULL )
6906         printf("\n\n ERROR: realloc failure updLcase\n\n" );
6907     for (n=0; n<set[setNr].anz_n; n++)
6908     {
6909       lcase[lc].dat[i][qcut_nod[n].nr] = lcase[lc].dat[i][qcut_nod[n].n1]*(1.-qcut_nod[n].val) + lcase[lc].dat[i][qcut_nod[n].n2]*qcut_nod[n].val;
6910       //printf("val:%lf n0:%lf n1:%lf n2:%lf\n", val, lcase[lc].dat[i][ns], lcase[lc].dat[i][n1], lcase[lc].dat[i][n2]);
6911     }
6912   }
6913 
6914   /* normal stress */
6915   if((lcase[lc].ncomps>=25)&&(lcase[lc].ictype[5]=4)&&(lcase[lc].ictype[6]!=4))
6916   {
6917     for (n=0; n<set[setNr].anz_n; n++)
6918     {
6919         s[0]=lcase[lc].dat[0][qcut_nod[n].nr];
6920         s[1]=lcase[lc].dat[1][qcut_nod[n].nr];
6921         s[2]=lcase[lc].dat[2][qcut_nod[n].nr];
6922         s[3]=lcase[lc].dat[3][qcut_nod[n].nr];
6923         s[4]=lcase[lc].dat[4][qcut_nod[n].nr];
6924         s[5]=lcase[lc].dat[5][qcut_nod[n].nr];
6925         if(v_betrag(node[qcut_nod[n].nr].nv))
6926         {
6927           /* calculate the stress in normal direction */
6928           p[0]=
6929           s[0]*node[qcut_nod[n].nr].nv[0]+
6930           s[3]*node[qcut_nod[n].nr].nv[1]+
6931           s[5]*node[qcut_nod[n].nr].nv[2];
6932           p[1]=
6933           s[3]*node[qcut_nod[n].nr].nv[0]+
6934           s[1]*node[qcut_nod[n].nr].nv[1]+
6935           s[4]*node[qcut_nod[n].nr].nv[2];
6936           p[2]=
6937           s[5]*node[qcut_nod[n].nr].nv[0]+
6938           s[4]*node[qcut_nod[n].nr].nv[1]+
6939           s[2]*node[qcut_nod[n].nr].nv[2];
6940           lcase[lc].dat[24][qcut_nod[n].nr]= v_sprod(node[qcut_nod[n].nr].nv, p);
6941         }
6942       }
6943     }
6944 
6945   /* update related DISP Dataset */
6946   /* if the selected lc is not a disp lc, search a related disp lc */
6947   if(compare(lcase[lc].name, "DISP", 4)!=4)
6948   {
6949     /* since real and imaginary part use different names since ccx_2.9 it is necessary to compare the
6950        names only for the length excluding the last char if its a 'I' */
6951     strcpy(buffer[0],"DISP ");
6952     strcpy(buffer[1],"DISPI");
6953     compareChars=strlen(lcase[lc].name)-1;
6954     for(k=compareChars;k>0; k--) if(lcase[lc].name[k]!=' ') break;
6955     compareChars=k+1;
6956     if(lcase[lc].name[compareChars-1]=='I') j=1; else j=0;;
6957 
6958     if(lc) { for (i=lc-1; i>=0; i--) { if(lcase[i].step_number!=lcase[lc].step_number) break; } i++; }
6959     else i=1;
6960     while((i<anz->l)&&(lcase[i].step_number==lcase[lc].step_number))
6961     {
6962       if((compare(lcase[i].name, buffer[j], 5)==5)&&(lcase[i].ictype[0]!= 12))
6963       {
6964 	//printf("lcase[i].name:%s lcase[lc].name:%s compareChars:%d\n", lcase[i].name,lcase[lc].name,compareChars);
6965         lc=i;
6966         goto next_lc;
6967       }
6968       i++;
6969     }
6970   }
6971 }
6972 
6973 
6974 
cutElement(int elnr,int nset,int eset,double * en,double * pn,double * eu,double * ev,CutParam * cutParam)6975 void cutElement(int elnr, int nset, int eset, double *en, double *pn, double *eu, double *ev, CutParam *cutParam)
6976 {
6977   int j,k,n1,n2,nn1,nn2,anz_n;
6978   int   nvalid[CUTS],nnew[CUTS];
6979   double v02[3], v01[3], ns[4], cg[3];
6980   double local_gtol=1.e-9; /* dist to merge new nodes (might be set to gtol) */
6981   Rsort *rsort=NULL;
6982 
6983   /* mapping of nodeindexes from frd to pre_cut */
6984   int nhe20[]  = {0,8,1,9,2,10,3,11,12,-1,13,-1,14,-1,15,-1,4,16,5,17,6,18,7,19};
6985   int ntet10[] = {0,4,1,5,2,6,7,-1,8,-1,9,-1,3};
6986 
6987   double eg[3], n1n2[3], n1pn[3], n1ns[3];
6988   double g;
6989 
6990   cutParam->anz_n=anz_n=0;  // must always be lower than the 1000 alloc elements
6991 
6992   //printf("e:%d t:%d ptr:%x\n", elnr,e_enqire[elnr].type,cutParam);
6993   if (e_enqire[elnr].type == 1)  /* HEXA8 */
6994   {
6995     for(n1=0; n1<4; n1++)
6996     {
6997       if(n1==3) n2=0;
6998       else n2=n1+1;
6999 
7000       v_result( &node[e_enqire[elnr].nod[n1]].nx, &node[e_enqire[elnr].nod[n2]].nx, n1n2 );
7001       v_result( &node[e_enqire[elnr].nod[n1]].nx, pn, n1pn );
7002       v_norm( n1n2, eg );
7003       g = AsplitL_l( n1pn, eu, ev, eg );
7004       ns[3] = g/v_betrag(n1n2);
7005       if(ns[3]>1.000001) continue;
7006       if(ns[3]<-0.000001) continue;
7007       v_scal( &g, eg, n1ns );
7008       v_add( &node[e_enqire[elnr].nod[n1]].nx, n1ns, ns );
7009       {
7010         cutParam->npre[anz_n][0]=ns[0];
7011         cutParam->npre[anz_n][1]=ns[1];
7012         cutParam->npre[anz_n][2]=ns[2];
7013         cutParam->npre[anz_n][3]=ns[3];
7014         cutParam->npre[anz_n][4]=e_enqire[elnr].nod[n1];
7015         cutParam->npre[anz_n][5]=e_enqire[elnr].nod[n2];
7016         nvalid[anz_n]=1;
7017         anz_n++;
7018       }
7019     }
7020     for(n1=0; n1<4; n1++)
7021     {
7022       n2=n1+4;
7023       v_result( &node[e_enqire[elnr].nod[n1]].nx, &node[e_enqire[elnr].nod[n2]].nx, n1n2 );
7024       v_result( &node[e_enqire[elnr].nod[n1]].nx, pn, n1pn );
7025       v_norm( n1n2, eg );
7026       g = AsplitL_l( n1pn, eu, ev, eg );
7027       ns[3] = g/v_betrag(n1n2);
7028       if(ns[3]>1.000001) continue;
7029       if(ns[3]<-0.000001) continue;
7030       v_scal( &g, eg, n1ns );
7031       v_add( &node[e_enqire[elnr].nod[n1]].nx, n1ns, ns );
7032       {
7033         cutParam->npre[anz_n][0]=ns[0];
7034         cutParam->npre[anz_n][1]=ns[1];
7035         cutParam->npre[anz_n][2]=ns[2];
7036         cutParam->npre[anz_n][3]=ns[3];
7037         cutParam->npre[anz_n][4]=e_enqire[elnr].nod[n1];
7038         cutParam->npre[anz_n][5]=e_enqire[elnr].nod[n2];
7039         nvalid[anz_n]=1;
7040         anz_n++;
7041       }
7042     }
7043     for(n1=4; n1<8; n1++)
7044     {
7045       if(n1==7) n2=4;
7046       else n2=n1+1;
7047       v_result( &node[e_enqire[elnr].nod[n1]].nx, &node[e_enqire[elnr].nod[n2]].nx, n1n2 );
7048       v_result( &node[e_enqire[elnr].nod[n1]].nx, pn, n1pn );
7049       v_norm( n1n2, eg );
7050       g = AsplitL_l( n1pn, eu, ev, eg );
7051       ns[3] = g/v_betrag(n1n2);
7052       if(ns[3]>1.000001) continue;
7053       if(ns[3]<-0.000001) continue;
7054       v_scal( &g, eg, n1ns );
7055       v_add( &node[e_enqire[elnr].nod[n1]].nx, n1ns, ns );
7056       {
7057         cutParam->npre[anz_n][0]=ns[0];
7058         cutParam->npre[anz_n][1]=ns[1];
7059         cutParam->npre[anz_n][2]=ns[2];
7060         cutParam->npre[anz_n][3]=ns[3];
7061         cutParam->npre[anz_n][4]=e_enqire[elnr].nod[n1];
7062         cutParam->npre[anz_n][5]=e_enqire[elnr].nod[n2];
7063         nvalid[anz_n]=1;
7064         anz_n++;
7065       }
7066     }
7067   } /* end he8 */
7068   if (e_enqire[elnr].type == 3)  /* TET4 */
7069   {
7070     for(n1=0; n1<3; n1++)
7071     {
7072       if(n1==2) n2=0;
7073       else n2=n1+1;
7074       v_result( &node[e_enqire[elnr].nod[n1]].nx, &node[e_enqire[elnr].nod[n2]].nx, n1n2 );
7075       v_result( &node[e_enqire[elnr].nod[n1]].nx, pn, n1pn );
7076       v_norm( n1n2, eg );
7077       g = AsplitL_l( n1pn, eu, ev, eg );
7078       ns[3] = g/v_betrag(n1n2);
7079       if(ns[3]>1.000001) continue;
7080       if(ns[3]<-0.000001) continue;
7081       v_scal( &g, eg, n1ns );
7082       v_add( &node[e_enqire[elnr].nod[n1]].nx, n1ns, ns );
7083       {
7084         cutParam->npre[anz_n][0]=ns[0];
7085         cutParam->npre[anz_n][1]=ns[1];
7086         cutParam->npre[anz_n][2]=ns[2];
7087         cutParam->npre[anz_n][3]=ns[3];
7088         cutParam->npre[anz_n][4]=e_enqire[elnr].nod[n1];
7089         cutParam->npre[anz_n][5]=e_enqire[elnr].nod[n2];
7090         nvalid[anz_n]=1;
7091         anz_n++;
7092       }
7093     }
7094     for(n1=0; n1<3; n1++)
7095     {
7096       n2=3;
7097       v_result( &node[e_enqire[elnr].nod[n1]].nx, &node[e_enqire[elnr].nod[n2]].nx, n1n2 );
7098       v_result( &node[e_enqire[elnr].nod[n1]].nx, pn, n1pn );
7099       v_norm( n1n2, eg );
7100       g = AsplitL_l( n1pn, eu, ev, eg );
7101       ns[3] = g/v_betrag(n1n2);
7102       if(ns[3]>1.000001) continue;
7103       if(ns[3]<-0.000001) continue;
7104       v_scal( &g, eg, n1ns );
7105       v_add( &node[e_enqire[elnr].nod[n1]].nx, n1ns, ns );
7106       {
7107         cutParam->npre[anz_n][0]=ns[0];
7108         cutParam->npre[anz_n][1]=ns[1];
7109         cutParam->npre[anz_n][2]=ns[2];
7110         cutParam->npre[anz_n][3]=ns[3];
7111         cutParam->npre[anz_n][4]=e_enqire[elnr].nod[n1];
7112         cutParam->npre[anz_n][5]=e_enqire[elnr].nod[n2];
7113         nvalid[anz_n]=1;
7114         anz_n++;
7115       }
7116     }
7117   } /* end tet4 */
7118 
7119   else if (e_enqire[elnr].type == 4)  /* HEXA20 */
7120   {
7121     for(nn1=0; nn1<8; nn1++)
7122     {
7123       if(nn1==7) nn2=0;
7124       else nn2=nn1+1;
7125       n1=nhe20[nn1];
7126       n2=nhe20[nn2];
7127       v_result( &node[e_enqire[elnr].nod[n1]].nx, &node[e_enqire[elnr].nod[n2]].nx, n1n2 );
7128       v_result( &node[e_enqire[elnr].nod[n1]].nx, pn, n1pn );
7129       v_norm( n1n2, eg );
7130       g = AsplitL_l( n1pn, eu, ev, eg );
7131       ns[3] = g/v_betrag(n1n2);
7132       if(ns[3]>1.000001) continue;
7133       if(ns[3]<-0.000001) continue;
7134       v_scal( &g, eg, n1ns );
7135       v_add( &node[e_enqire[elnr].nod[n1]].nx, n1ns, ns );
7136       {
7137         cutParam->npre[anz_n][0]=ns[0];
7138         cutParam->npre[anz_n][1]=ns[1];
7139         cutParam->npre[anz_n][2]=ns[2];
7140         cutParam->npre[anz_n][3]=ns[3];
7141         cutParam->npre[anz_n][4]=e_enqire[elnr].nod[n1];
7142         cutParam->npre[anz_n][5]=e_enqire[elnr].nod[n2];
7143         nvalid[anz_n]=1;
7144         anz_n++;
7145       }
7146     }
7147     for(nn1=0; nn1<8; nn1+=2)
7148     {
7149       nn2=nn1+8;
7150       n1=nhe20[nn1];
7151       n2=nhe20[nn2];
7152       v_result( &node[e_enqire[elnr].nod[n1]].nx, &node[e_enqire[elnr].nod[n2]].nx, n1n2 );
7153       v_result( &node[e_enqire[elnr].nod[n1]].nx, pn, n1pn );
7154       v_norm( n1n2, eg );
7155       g = AsplitL_l( n1pn, eu, ev, eg );
7156       ns[3] = g/v_betrag(n1n2);
7157       if(ns[3]>1.000001) continue;
7158       if(ns[3]<-0.000001) continue;
7159       v_scal( &g, eg, n1ns );
7160       v_add( &node[e_enqire[elnr].nod[n1]].nx, n1ns, ns );
7161       {
7162         cutParam->npre[anz_n][0]=ns[0];
7163         cutParam->npre[anz_n][1]=ns[1];
7164         cutParam->npre[anz_n][2]=ns[2];
7165         cutParam->npre[anz_n][3]=ns[3];
7166         cutParam->npre[anz_n][4]=e_enqire[elnr].nod[n1];
7167         cutParam->npre[anz_n][5]=e_enqire[elnr].nod[n2];
7168         nvalid[anz_n]=1;
7169         anz_n++;
7170       }
7171     }
7172     for(nn1=16; nn1<24; nn1++)
7173     {
7174       if(nn1==23) nn2=16;
7175       else nn2=nn1+1;
7176       n1=nhe20[nn1];
7177       n2=nhe20[nn2];
7178       v_result( &node[e_enqire[elnr].nod[n1]].nx, &node[e_enqire[elnr].nod[n2]].nx, n1n2 );
7179       v_result( &node[e_enqire[elnr].nod[n1]].nx, pn, n1pn );
7180       v_norm( n1n2, eg );
7181       g = AsplitL_l( n1pn, eu, ev, eg );
7182       ns[3] = g/v_betrag(n1n2);
7183       if(ns[3]>1.000001) continue;
7184       if(ns[3]<-0.000001) continue;
7185       v_scal( &g, eg, n1ns );
7186       v_add( &node[e_enqire[elnr].nod[n1]].nx, n1ns, ns );
7187       {
7188         cutParam->npre[anz_n][0]=ns[0];
7189         cutParam->npre[anz_n][1]=ns[1];
7190         cutParam->npre[anz_n][2]=ns[2];
7191         cutParam->npre[anz_n][3]=ns[3];
7192         cutParam->npre[anz_n][4]=e_enqire[elnr].nod[n1];
7193         cutParam->npre[anz_n][5]=e_enqire[elnr].nod[n2];
7194         nvalid[anz_n]=1;
7195         anz_n++;
7196       }
7197     }
7198     for(nn1=16; nn1<24; nn1+=2)
7199     {
7200       nn2=nn1-8;
7201       n1=nhe20[nn1];
7202       n2=nhe20[nn2];
7203       v_result( &node[e_enqire[elnr].nod[n1]].nx, &node[e_enqire[elnr].nod[n2]].nx, n1n2 );
7204       v_result( &node[e_enqire[elnr].nod[n1]].nx, pn, n1pn );
7205       v_norm( n1n2, eg );
7206       g = AsplitL_l( n1pn, eu, ev, eg );
7207       ns[3] = g/v_betrag(n1n2);
7208       if(ns[3]>1.000001) continue;
7209       if(ns[3]<-0.000001) continue;
7210       v_scal( &g, eg, n1ns );
7211       v_add( &node[e_enqire[elnr].nod[n1]].nx, n1ns, ns );
7212       {
7213         cutParam->npre[anz_n][0]=ns[0];
7214         cutParam->npre[anz_n][1]=ns[1];
7215         cutParam->npre[anz_n][2]=ns[2];
7216         cutParam->npre[anz_n][3]=ns[3];
7217         cutParam->npre[anz_n][4]=e_enqire[elnr].nod[n1];
7218         cutParam->npre[anz_n][5]=e_enqire[elnr].nod[n2];
7219         nvalid[anz_n]=1;
7220         anz_n++;
7221       }
7222     }
7223   } /* end he20 */
7224 
7225   else if (e_enqire[elnr].type == 6)  /* TET10 */
7226   {
7227     for(nn1=0; nn1<6; nn1++)
7228     {
7229       if(nn1==5) nn2=0;
7230       else nn2=nn1+1;
7231       n1=ntet10[nn1];
7232       n2=ntet10[nn2];
7233       v_result( &node[e_enqire[elnr].nod[n1]].nx, &node[e_enqire[elnr].nod[n2]].nx, n1n2 );
7234       v_result( &node[e_enqire[elnr].nod[n1]].nx, pn, n1pn );
7235       v_norm( n1n2, eg );
7236       g = AsplitL_l( n1pn, eu, ev, eg );
7237       ns[3] = g/v_betrag(n1n2);
7238       if(ns[3]>1.000001) continue;
7239       if(ns[3]<-0.000001) continue;
7240       v_scal( &g, eg, n1ns );
7241       v_add( &node[e_enqire[elnr].nod[n1]].nx, n1ns, ns );
7242       {
7243         cutParam->npre[anz_n][0]=ns[0];
7244         cutParam->npre[anz_n][1]=ns[1];
7245         cutParam->npre[anz_n][2]=ns[2];
7246         cutParam->npre[anz_n][3]=ns[3];
7247         cutParam->npre[anz_n][4]=e_enqire[elnr].nod[n1];
7248         cutParam->npre[anz_n][5]=e_enqire[elnr].nod[n2];
7249         nvalid[anz_n]=1;
7250         anz_n++;
7251       }
7252     }
7253     for(nn1=0; nn1<6; nn1+=2)
7254     {
7255       nn2=nn1+6;
7256       n1=ntet10[nn1];
7257       n2=ntet10[nn2];
7258       v_result( &node[e_enqire[elnr].nod[n1]].nx, &node[e_enqire[elnr].nod[n2]].nx, n1n2 );
7259       v_result( &node[e_enqire[elnr].nod[n1]].nx, pn, n1pn );
7260       v_norm( n1n2, eg );
7261       g = AsplitL_l( n1pn, eu, ev, eg );
7262       ns[3] = g/v_betrag(n1n2);
7263       if(ns[3]>1.000001) continue;
7264       if(ns[3]<-0.000001) continue;
7265       v_scal( &g, eg, n1ns );
7266       v_add( &node[e_enqire[elnr].nod[n1]].nx, n1ns, ns );
7267       {
7268         cutParam->npre[anz_n][0]=ns[0];
7269         cutParam->npre[anz_n][1]=ns[1];
7270         cutParam->npre[anz_n][2]=ns[2];
7271         cutParam->npre[anz_n][3]=ns[3];
7272         cutParam->npre[anz_n][4]=e_enqire[elnr].nod[n1];
7273         cutParam->npre[anz_n][5]=e_enqire[elnr].nod[n2];
7274         nvalid[anz_n]=1;
7275         anz_n++;
7276       }
7277     }
7278     for(nn1=6; nn1<12; nn1+=2)
7279     {
7280       nn2=12;
7281       n1=ntet10[nn1];
7282       n2=ntet10[nn2];
7283       v_result( &node[e_enqire[elnr].nod[n1]].nx, &node[e_enqire[elnr].nod[n2]].nx, n1n2 );
7284       v_result( &node[e_enqire[elnr].nod[n1]].nx, pn, n1pn );
7285       v_norm( n1n2, eg );
7286       g = AsplitL_l( n1pn, eu, ev, eg );
7287       ns[3] = g/v_betrag(n1n2);
7288       if(ns[3]>1.000001) continue;
7289       if(ns[3]<-0.000001) continue;
7290       v_scal( &g, eg, n1ns );
7291       v_add( &node[e_enqire[elnr].nod[n1]].nx, n1ns, ns );
7292       {
7293         cutParam->npre[anz_n][0]=ns[0];
7294         cutParam->npre[anz_n][1]=ns[1];
7295         cutParam->npre[anz_n][2]=ns[2];
7296         cutParam->npre[anz_n][3]=ns[3];
7297         cutParam->npre[anz_n][4]=e_enqire[elnr].nod[n1];
7298         cutParam->npre[anz_n][5]=e_enqire[elnr].nod[n2];
7299         nvalid[anz_n]=1;
7300         anz_n++;
7301       }
7302     }
7303   } /* end tet10 */
7304 
7305   if(anz_n>CUTS) { printf(" ERROR in pre_cut (talk to the programmer), increase CUTS at least to %d\n", anz_n); exit(0); }
7306 
7307   if(anz_n>0)
7308   {
7309     /* aussortieren der doppelten nodes */
7310     for(j=0; j<anz_n; j++)
7311     {
7312       if(nvalid[j])
7313       {
7314         /* gehe ueber alle nodes und deaktiviere nahe nodes */
7315         for(k=j; k<anz_n; k++)
7316         {
7317          if(nvalid[k])
7318          {
7319           if(dabs(cutParam->npre[j][0]-cutParam->npre[k][0])>local_gtol) goto nexti;
7320           if(dabs(cutParam->npre[j][1]-cutParam->npre[k][1])>local_gtol) goto nexti;
7321           if(dabs(cutParam->npre[j][2]-cutParam->npre[k][2])>local_gtol) goto nexti;
7322           nvalid[k]=0;
7323           nexti:;
7324          }
7325         }
7326 	//printf("anz_n:%d store index %d\n", cutParam->anz_n, j);
7327         nnew[cutParam->anz_n++]=j;
7328        }
7329     }
7330 
7331     /* sortiere die nodes nach winkel zum ersten node, masterrichtung ist en, center ist cg */
7332     cg[0]=0.;
7333     cg[1]=0.;
7334     cg[2]=0.;
7335     for(j=0; j<cutParam->anz_n; j++)
7336     {
7337       cg[0]+=cutParam->npre[nnew[j]][0];
7338       cg[1]+=cutParam->npre[nnew[j]][1];
7339       cg[2]+=cutParam->npre[nnew[j]][2];
7340     }
7341     cg[0]/=cutParam->anz_n;
7342     cg[1]/=cutParam->anz_n;
7343     cg[2]/=cutParam->anz_n;
7344 
7345     if ( (rsort = (Rsort *)malloc( (cutParam->anz_n+1) * sizeof(Rsort))) == NULL )
7346       printf("ERROR: realloc failed: rsort\n\n" );
7347     v_result( cg, &cutParam->npre[nnew[0]][0],  v01);
7348     rsort[0].r=0.;
7349     rsort[0].i=nnew[0];
7350     k=1;
7351     for(j=1; j<cutParam->anz_n; j++)
7352     {
7353       v_result( cg, &cutParam->npre[nnew[j]][0],  v02);
7354       rsort[k].r=v_angle_ref(v01,v02,en);
7355       rsort[k].i=nnew[j];
7356       k++;
7357     }
7358     qsort( rsort, cutParam->anz_n, sizeof(Rsort), (void *)compareRsort );
7359     k=0;
7360     for(j=0; j<cutParam->anz_n; j++)
7361     {
7362       //printf("anz_n:%d store sorted index %d\n", cutParam->anz_n, rsort[k].i);
7363       cutParam->nnew[j]=rsort[k].i;
7364       k++;
7365     }
7366     free(rsort);
7367   }
7368 }
7369 
7370 
7371 
thread_cutElement(void * vargp)7372 void *thread_cutElement( void *vargp)
7373 {
7374   int elem;
7375   typedef struct {
7376     int thread;
7377     int anz_e;
7378     int nset;
7379     int eset;
7380     double *en;
7381     double *pn;
7382     double *eu;
7383     double *ev;
7384     CutParam *cutParam;
7385   } Threadargs;
7386   Threadargs *param;
7387 
7388   param=(Threadargs *)vargp;
7389   while(1)
7390   {
7391     sem_wait(&sem_cute);
7392     elem=glob_cutElement++;
7393     sem_post(&sem_cute);
7394     if(elem>=param->anz_e) break;
7395     //printf("thread:%d elem:%d\n",param->thread, elem);
7396     //printf("elem:%d ptr:%x\n",e_enqire[elem].nr,&(param->cutParam[e_enqire[elem].nr]));
7397     cutElement(e_enqire[elem].nr, param->nset, param->eset, param->en, param->pn, param->eu, param->ev, &(param->cutParam[e_enqire[elem].nr]));
7398   }
7399   return((void *)1);
7400 }
7401 
7402 
7403 
pre_cut(int nr,int flag)7404 void pre_cut( int nr, int flag )
7405 {
7406   int i,j,e,nn,nset,eset,anz_e,anz_nset,nel[3];
7407   static double p[3][3];
7408   double v02[3], v01[3], en[3], vn[3], pn[3], eu[3], ev[3];
7409   char  addDispFlagLocal=0;
7410   CutParam *cutParam;
7411 
7412   typedef struct {
7413     int thread;
7414     int anz_e;
7415     int nset;
7416     int eset;
7417     double *en;
7418     double *pn;
7419     double *eu;
7420     double *ev;
7421     CutParam *cutParam;
7422   } Threadargs;
7423   Threadargs *targ=NULL;
7424   pthread_t *tid=NULL;
7425   int nlocalThreads;
7426   int threads=NTHREADS_MAX;
7427 
7428   if(anz->l<1)   { printf(" ERROR: no datasets available. This function needs a vector result.\n"); return; }
7429   if(flag=='v')
7430   {
7431     if(lcase[cur_lc].ictype[cur_entity]==2)
7432     {
7433       /* search all necessary entities */
7434       if (lcase[cur_lc].icind1[cur_entity]==1)      { entity_v[0]=cur_entity; entity_v[1]=cur_entity+1; entity_v[2]=cur_entity+2; entity_v[3]=-1; v_dim=3; }
7435       else if (lcase[cur_lc].icind1[cur_entity]==2) { entity_v[0]=cur_entity-1; entity_v[1]=cur_entity; entity_v[2]=cur_entity+1; entity_v[3]=-1; v_dim=3; }
7436       else if (lcase[cur_lc].icind1[cur_entity]==3) { entity_v[0]=cur_entity-2; entity_v[1]=cur_entity-1; entity_v[2]=cur_entity; entity_v[3]=-1; v_dim=3; }
7437       else if (lcase[cur_lc].icind1[cur_entity]==0) { entity_v[0]=cur_entity-3; entity_v[1]=cur_entity-2; entity_v[2]=cur_entity-1; entity_v[3]=cur_entity; v_dim=4; }
7438       else
7439       {
7440         /* vector-components not located before the vector-value */
7441         printf(" ERROR: no vector result was selected\n");
7442         return;
7443       }
7444     }
7445     else
7446     {
7447       printf(" ERROR: no vector result was selected\n");
7448       return;
7449     }
7450   }
7451 
7452   /* neuer Drehpunkt */
7453   if ((flag=='n')||(flag=='v'))
7454   {
7455     center( node[nr].nx, node[nr].ny, node[nr].nz);
7456     p[qcutCounter][0] = node[nr].nx;
7457     p[qcutCounter][1] = node[nr].ny;
7458     p[qcutCounter][2] = node[nr].nz;
7459   }
7460   else if (flag=='p')
7461   {
7462     center( point[nr].px, point[nr].py, point[nr].pz);
7463     p[qcutCounter][0] = point[nr].px;
7464     p[qcutCounter][1] = point[nr].py;
7465     p[qcutCounter][2] = point[nr].pz;
7466   }
7467   qcutCounter++;
7468 
7469   if ((qcutCounter == 3)||(flag=='v'))
7470   {
7471     qcutCounter=0;
7472     pre_view("elem off");
7473 
7474     printf("\nplease wait, new elements in this section will be created\n");
7475 
7476     /* when node coordinates were changed to the deformed ones then switch back before they are copied and then switch again */
7477     if(addDispFlag)
7478     {
7479       addDispToCoordinates(node);
7480       // remember to switch back
7481       addDispFlagLocal=2;
7482     }
7483 
7484     if (flag=='v')
7485     {
7486       /* 1 Node gewaehlt, bestimme die Normale auf der Ebene auf Basis des knotenwertes */
7487       for(i=0; i<3; i++)
7488       {
7489         vn[i]=lcase[cur_lc].dat[entity_v[i]][nr];
7490         //printf("n:%d entity:%d val:%f\n", nr, entity_v[i],vn[i] );
7491       }
7492       v_norm( vn, en );
7493       v02[0]=en[2];
7494       v02[1]=en[0];
7495       v02[2]=en[1];
7496       v_prod( v02, vn, v01 );
7497       pn[0] = node[nr].nx;
7498       pn[1] = node[nr].ny;
7499       pn[2] = node[nr].nz;
7500     }
7501     else
7502     {
7503       /* 3 Punkte gewaehlt, berechne die Normale auf der Ebene */
7504       v_result( &p[0][0], &p[1][0],  v01);
7505       v_result( &p[0][0], &p[2][0],  v02);
7506       v_prod( v01,v02, vn );
7507       v_norm( vn, en );
7508 
7509       /* punkt auf der ebene der nicht mit nodes identisch ist */
7510       for(i=0; i<3; i++) pn[i]=0.;
7511       for(i=0; i<3; i++)
7512       {
7513         pn[0]+= p[i][0];
7514         pn[1]+= p[i][1];
7515         pn[2]+= p[i][2];
7516       }
7517       for(i=0; i<3; i++) pn[i]/=3.;
7518       //center( pn[0], pn[1], pn[2]);
7519 
7520       /* eu ev der ebene ausgehend von pn */
7521       v_result( pn, &p[1][0],  v01);
7522     }
7523 
7524     v_prod( v01, vn, v02 );
7525     v_norm( v01, eu );
7526     v_norm( v02, ev );
7527 
7528     /* open a temp set */
7529     zap("-qcut");
7530     if( (nset=pre_seta( "-qcut", "i", 0)) <0 ) return;
7531 
7532     /* schneide alle elemente mit der ebene */
7533     eset= pre_seta( specialset->etmp, "i", 0 );
7534 
7535     /* daten der geschnittenen elemente */
7536     if ((cutParam=(CutParam *)malloc((anz->emax+1)*sizeof(CutParam)) ) == NULL ) { printf(" ERROR: malloc failure\n\n"); return;}
7537 
7538     if(sem_init(&sem_cute, 0, 1) < 0) printf("Error in:sem_init\n");
7539     if(threads>anz->e) { nlocalThreads=anz->e; }
7540     else nlocalThreads=threads;
7541     //nlocalThreads=1;
7542     if ((tid=(pthread_t *)realloc((pthread_t *)tid, nlocalThreads*sizeof(pthread_t)) ) == NULL ) { printf(" ERROR: malloc failure\n\n"); return;}
7543     if ((targ=(Threadargs *)realloc((Threadargs *)targ, nlocalThreads*sizeof(Threadargs)) ) == NULL ) { printf(" ERROR: malloc failure\n\n"); return;}
7544     glob_cutElement=0;
7545     anz_e=anz->e;
7546     for(i=0; i<nlocalThreads; i++)
7547     {
7548       targ[i].thread=i;
7549       targ[i].anz_e=anz_e;
7550       targ[i].nset=nset;
7551       targ[i].eset=eset;
7552       targ[i].en=en;
7553       targ[i].pn=pn;
7554       targ[i].eu=eu;
7555       targ[i].ev=ev;
7556       targ[i].cutParam=cutParam;
7557       pthread_create(&tid[i],NULL,thread_cutElement,(void *)&targ[i]);
7558     }
7559     for(i=0; i<nlocalThreads; i++)
7560     {
7561       pthread_join(tid[i], NULL);
7562     }
7563     glob_cutElement=0;
7564     free(tid); tid=NULL;
7565     free(targ); targ=NULL;
7566     if(sem_destroy(&sem_cute) < 0) printf("Error in:sem_init\n");
7567 
7568     for(e=1; e<anz_e; e++)
7569     {
7570       i=e_enqire[e].nr;
7571       //printf("e:%d anz_n:%d\n",e_enqire[e].nr, cutParam[i].anz_n);
7572       if(cutParam[i].anz_n>0)
7573       {
7574         /* generiere neue nodes */
7575         for(j=0; j<cutParam[i].anz_n; j++)
7576         {
7577           nn=nod( anz, &node, 0, anz->nnext++, cutParam[i].npre[cutParam[i].nnew[j]][0], cutParam[i].npre[cutParam[i].nnew[j]][1], cutParam[i].npre[cutParam[i].nnew[j]][2], 0 );
7578 	  //printf("j:%d make node:%d from index %d\n",j, node[nn].nr, cutParam[i].nnew[j]);
7579           seta(setall, "n", node[nn].nr);
7580           seta(nset, "n", node[nn].nr);
7581           anz_nset=set[nset].anz_n-1;
7582 
7583           /* store the informations to interpolate node-values for the new nodes */
7584           if ( (qcut_nod = (Qcut_nodes *)realloc(qcut_nod, (anz_nset+1) * sizeof(Qcut_nodes))) == NULL )
7585             printf("\n\n ERROR: realloc failure qcut_nod \n\n" );
7586 	  //printf("qcut_nod:%d nod:%d\n",anz_nset, cutParam[i].nnew[j]);
7587           qcut_nod[anz_nset].nr=node[nn].nr;
7588           qcut_nod[anz_nset].n1=cutParam[i].npre[cutParam[i].nnew[j]][4];
7589           qcut_nod[anz_nset].n2=cutParam[i].npre[cutParam[i].nnew[j]][5];
7590           qcut_nod[anz_nset].val=cutParam[i].npre[cutParam[i].nnew[j]][3];
7591           // re-use of nnew
7592           cutParam[i].nnew[j]=node[nn].nr;
7593         }
7594         /* generiere neue elemente */
7595         for(j=1; j<cutParam[i].anz_n-1; j++)
7596         {
7597           nel[0]=cutParam[i].nnew[0];
7598           nel[1]=cutParam[i].nnew[j];
7599           nel[2]=cutParam[i].nnew[j+1];
7600 	  //printf("j:%d make elem:%d\n",j, anz->enext);
7601           elem_define(anz,&e_enqire, anz->enext++, 7, nel, 0, 0 );
7602           seta(setall, "e", anz->enext-1);
7603           seta(nset, "e", anz->enext-1);
7604           seta(eset, "e", anz->enext-1);
7605         }
7606       }
7607     }
7608     free(cutParam);
7609 
7610     /* update Dataset */
7611     updLcase(cur_lc, nset);
7612 
7613     /* zeige neue elemente */
7614     makeSurfaces();
7615     realloc_colNr();
7616     updateDispLists();
7617 
7618     /* when node coordinates were changed to the deformed ones then switch back  */
7619     if(addDispFlagLocal==2)
7620     {
7621       addDispToCoordinates(node);
7622     }
7623 
7624     if(vectorFlag) pre_view("vector off");
7625     if(anz->l) plot( "ev -qcut" );
7626     else plot( "ei -qcut" );
7627   }
7628 }
7629 
7630 
7631 
flipSurfori(int s)7632 void flipSurfori(int s)
7633 {
7634   int i,j,k,n,setNr=-1;
7635   int nbuf[26];
7636   double *buf;
7637 
7638   /* switch signum of surf */
7639   if (surf[s].ori=='-') surf[s].ori='+';
7640   else                  surf[s].ori='-';
7641   n=0;
7642   while((surf[s].npgn-n)>0)
7643   {
7644     n++; /* jump over the polygon token (ie.GL_POLYGON_TOKEN) */
7645     j=surf[s].pgn[n++];
7646     surf[s].pgn[n]*=-1;
7647     surf[s].pgn[n+1]*=-1;
7648     surf[s].pgn[n+2]*=-1;
7649     n+=3;
7650     if ((buf = (double *)malloc((j*3)*sizeof(double)) ) == NULL )
7651     { printf("\n\nERROR: realloc failure in flip\n\n"); return; }
7652     for(k=0; k<j; k++)
7653     {
7654       buf[j*3-k*3-3]=surf[s].pgn[n];
7655       buf[j*3-k*3-2]=surf[s].pgn[n+1];
7656       buf[j*3-k*3-1]=surf[s].pgn[n+2];
7657       n+=3;
7658     }
7659     n-=3*j;
7660     for(k=0; k<j; k++)
7661     {
7662       surf[s].pgn[n]  =buf[k*3] ;
7663       surf[s].pgn[n+1]=buf[k*3+1];
7664       surf[s].pgn[n+2]=buf[k*3+2];
7665       n+=3;
7666     }
7667     free(buf);
7668   }
7669 
7670   /* switch orient of all embedded elements */
7671   if(surf[s].ne)
7672   {
7673     delSet(specialset->tmp);
7674     setNr=pre_seta(specialset->tmp,"i",0);
7675   }
7676   for (i=0; i<surf[s].ne; i++)
7677   {
7678     if (e_enqire[surf[s].elem[i]].type == 7)
7679     {
7680       nbuf[1]=e_enqire[surf[s].elem[i]].nod[1];
7681       nbuf[2]=e_enqire[surf[s].elem[i]].nod[2];
7682       e_enqire[surf[s].elem[i]].nod[2]=nbuf[1];
7683       e_enqire[surf[s].elem[i]].nod[1]=nbuf[2];
7684       seta(setNr,"e",surf[s].elem[i]);
7685     }
7686     else if (e_enqire[surf[s].elem[i]].type == 8)
7687     {
7688       nbuf[0]=e_enqire[surf[s].elem[i]].nod[0];
7689       nbuf[1]=e_enqire[surf[s].elem[i]].nod[1];
7690       nbuf[4]=e_enqire[surf[s].elem[i]].nod[4];
7691       nbuf[5]=e_enqire[surf[s].elem[i]].nod[5];
7692       e_enqire[surf[s].elem[i]].nod[0]=nbuf[1];
7693       e_enqire[surf[s].elem[i]].nod[1]=nbuf[0];
7694       e_enqire[surf[s].elem[i]].nod[4]=nbuf[5];
7695       e_enqire[surf[s].elem[i]].nod[5]=nbuf[4];
7696       seta(setNr,"e",surf[s].elem[i]);
7697     }
7698     else if (e_enqire[surf[s].elem[i]].type == 9)
7699     {
7700       nbuf[1]=e_enqire[surf[s].elem[i]].nod[1];
7701       nbuf[3]=e_enqire[surf[s].elem[i]].nod[3];
7702       e_enqire[surf[s].elem[i]].nod[3]=nbuf[1];
7703       e_enqire[surf[s].elem[i]].nod[1]=nbuf[3];
7704       seta(setNr,"e",surf[s].elem[i]);
7705     }
7706     else if (e_enqire[surf[s].elem[i]].type == 10)
7707     {
7708       nbuf[1]=e_enqire[surf[s].elem[i]].nod[1];
7709       nbuf[3]=e_enqire[surf[s].elem[i]].nod[3];
7710       nbuf[4]=e_enqire[surf[s].elem[i]].nod[4];
7711       nbuf[5]=e_enqire[surf[s].elem[i]].nod[5];
7712       nbuf[6]=e_enqire[surf[s].elem[i]].nod[6];
7713       nbuf[7]=e_enqire[surf[s].elem[i]].nod[7];
7714       e_enqire[surf[s].elem[i]].nod[3]=nbuf[1];
7715       e_enqire[surf[s].elem[i]].nod[1]=nbuf[3];
7716       e_enqire[surf[s].elem[i]].nod[7]=nbuf[4];
7717       e_enqire[surf[s].elem[i]].nod[6]=nbuf[5];
7718       e_enqire[surf[s].elem[i]].nod[5]=nbuf[6];
7719       e_enqire[surf[s].elem[i]].nod[4]=nbuf[7];
7720       seta(setNr,"e",surf[s].elem[i]);
7721     }
7722     else
7723     {
7724       printf(" ERROR: element type %d not known\n", e_enqire[surf[s].elem[i]].type);
7725     }
7726   }
7727 
7728   if(setNr!=-1)
7729   {
7730     for (i=0; i<anz->f; i++)
7731     {
7732       if(ifind(&set[setNr].elem, set[setNr].anz_e, face[i].elem_nr)>-1)
7733       {
7734         if (face[i].type == 7)
7735         {
7736           nbuf[1]=face[i].nod[1];
7737           nbuf[2]=face[i].nod[2];
7738           face[i].nod[2]=nbuf[1];
7739           face[i].nod[1]=nbuf[2];
7740         }
7741         else if (face[i].type == 8)
7742         {
7743           nbuf[0]=face[i].nod[0];
7744           nbuf[1]=face[i].nod[1];
7745           nbuf[4]=face[i].nod[4];
7746           nbuf[5]=face[i].nod[5];
7747           face[i].nod[0]=nbuf[1];
7748           face[i].nod[1]=nbuf[0];
7749           face[i].nod[4]=nbuf[5];
7750           face[i].nod[5]=nbuf[4];
7751         }
7752         else if (face[i].type == 9)
7753         {
7754           nbuf[1]=face[i].nod[1];
7755           nbuf[3]=face[i].nod[3];
7756           face[i].nod[3]=nbuf[1];
7757           face[i].nod[1]=nbuf[3];
7758         }
7759         else if (face[i].type == 10)
7760         {
7761           nbuf[1]=face[i].nod[1];
7762           nbuf[3]=face[i].nod[3];
7763           nbuf[4]=face[i].nod[4];
7764           nbuf[5]=face[i].nod[5];
7765           nbuf[6]=face[i].nod[6];
7766           nbuf[7]=face[i].nod[7];
7767           face[i].nod[3]=nbuf[1];
7768           face[i].nod[1]=nbuf[3];
7769           face[i].nod[7]=nbuf[4];
7770           face[i].nod[6]=nbuf[5];
7771           face[i].nod[5]=nbuf[6];
7772           face[i].nod[4]=nbuf[7];
7773         }
7774       }
7775     }
7776     delSet(specialset->tmp);
7777   }
7778 }
7779 
7780 
oriAllSurfs(int sur)7781 void oriAllSurfs(int sur)
7782 {
7783   int i,j,n,l,ll,lll,cl,s, prod1, prod2,oriflag,counter=0,surl;
7784   int **ltos, *sori;
7785 
7786   /* go over all surfs.*/
7787   /* check if one neighbour surf is oriented */
7788   /* then orient the surf */
7789 
7790   /* first go over all lines and determine all related surfs (should be 2) */
7791   /* store the surfs in an array which points then to the surf */
7792   /*  this will be set to -1 if the surf is oriented */
7793   /*  if all surfs are oriented this array contains only -1 */
7794 
7795   /* relate all surfs to its lines */
7796   if( (ltos=(int **)malloc((anzGeo->l+1)*sizeof(int *) ) )==NULL)
7797   printf("ERROR malloc failed in oriAllSurfs()\n");
7798   for(i=0; i<anzGeo->l; i++)
7799   {
7800     if( (ltos[i]=(int *)malloc((3)*sizeof(int) ) )==NULL)
7801     printf("ERROR malloc failed in oriAllSurfs()\n");
7802      ltos[i][0]=0; for(j=1;j<3;j++) ltos[i][j]=-1;
7803   }
7804 
7805   for(s=0; s<anzGeo->s; s++)
7806   {
7807     if(surf[s].name!=NULL) for(j=0; j<surf[s].nl; j++)
7808     {
7809       if(surf[s].typ[j]=='l')
7810       {
7811         n=++ltos[surf[s].l[j]][0];
7812         if(n>2)
7813         {
7814           printf("ERROR: to many related surfs(%d) for line:%s\n", n, line[surf[s].l[j]].name);
7815           //printf("No inner surfaces are permitted. Command could not be executed\n");
7816           //return;
7817           //printf("No inner surfaces are permitted. Some surfs can not be oriented\n");
7818           ltos[surf[s].l[j]][2]=-1;
7819         }
7820         else ltos[surf[s].l[j]][n]=s;
7821       }
7822       else
7823       {
7824         cl=surf[s].l[j];
7825         for(l=0; l<lcmb[cl].nl; l++)
7826 	{
7827           n=++ltos[lcmb[cl].l[l]][0];
7828           if(n>2)
7829           {
7830             printf("ERROR: to many related surfs(%d) for line:%s\n", n, line[lcmb[cl].l[l]].name);
7831             //printf("No inner surfaces are permitted. Command could not be executed\n");
7832             //return;
7833             //printf("No inner surfaces are permitted. Some surfs can not be oriented\n");
7834             ltos[lcmb[cl].l[l]][2]=-1;
7835           }
7836           else ltos[lcmb[cl].l[l]][n]=s;
7837 	}
7838       }
7839     }
7840   }
7841 
7842 
7843   for(i=0; i<anzGeo->l; i++) if( line[i].name != (char *)NULL )
7844   {
7845     printf("l:%s ", line[i].name);
7846     if(ltos[i][1]>-1) printf("surf:%s ", surf[ltos[i][1]].name);
7847     if(ltos[i][2]>-1) printf("surf:%s ", surf[ltos[i][2]].name);
7848     printf("\n ");
7849   }
7850 
7851   /* create a link between surfindex and surface-ori */
7852   /* the sori is "0" as long a surf is not oriented */
7853   if( (sori=(int *)malloc((anzGeo->s+1)*sizeof(int) ) )==NULL)
7854     printf("ERROR malloc failed in oriAllSurfs()\n");
7855   for(i=0; i<anzGeo->s; i++) sori[i]=0;
7856 
7857   /* the start-surface is already oriented */
7858   sori[sur]=1;
7859 
7860   /* go over all surfs and look if one has an oriented neighbour */
7861  more:;
7862   oriflag=0;
7863   for(s=0; s<anzGeo->s; s++)
7864   {
7865     /* if the surf is valid and not oriented go over all its lines */
7866     if((surf[s].name!=NULL)&&(sori[s]==0)) for(j=0; j<surf[s].nl; j++)
7867     {
7868       oriflag=1;
7869       if(surf[s].typ[j]=='l')
7870       {
7871         /* check the connected surfs based on the common lines if it is an oriented one */
7872         for(n=1;n<3;n++) if(ltos[surf[s].l[j]][n]>-1) if((ltos[surf[s].l[j]][n]!=s)&&(sori[ltos[surf[s].l[j]][n]]>0))
7873 	{
7874 	  sur=ltos[surf[s].l[j]][n];
7875           surl= surf[s].l[j];
7876           printf("surf:%s line:%s oriented surf:%s\n", surf[s].name, line[surl].name, surf[sur].name);
7877 
7878           /* check if the surf must be inverted */
7879           /* based on the product of orientations of the oriented surf */
7880           /* determine the index of the connected line in sur */
7881           if(surf[sur].ori=='+') prod1=1; else prod1=-1;
7882           for(ll=0; ll<surf[sur].nl; ll++)
7883 	  {
7884             if(surf[sur].typ[ll]=='l')
7885             {
7886 	      if(surl==surf[sur].l[ll])
7887               {
7888                 if(surf[sur].o[ll]=='+') prod1*=1; else prod1*=-1;
7889                 goto found1;
7890               }
7891 	    }
7892 	    else
7893             {
7894               for(lll=0; lll<lcmb[surf[sur].l[ll]].nl; lll++) if(surl==lcmb[surf[sur].l[ll]].l[lll])
7895               {
7896                 if(surf[sur].o[ll]=='+') prod1*=1; else prod1*=-1;
7897                 if(lcmb[surf[sur].l[ll]].o[lll]=='+') prod1*=1; else prod1*=-1;
7898                 goto found1;
7899 	      }
7900 	    }
7901 	  }
7902 	found1:;
7903 
7904           /* product of orientations of the actual surf */
7905           if(surf[s].ori=='+') prod2=1; else prod2=-1;
7906           if(surf[s].o[j]=='+') prod2*=1; else prod2*=-1;
7907 
7908           sori[s]=1;
7909           if(prod2==prod1)
7910 	  {
7911             flipSurfori(s);
7912 	  }
7913           goto new_surf;
7914 	}
7915       }
7916       else
7917       {
7918         cl=surf[s].l[j];
7919         for(l=0; l<lcmb[cl].nl; l++)
7920 	{
7921           /* check the connected surfs based on the common lines if it is an oriented one */
7922           for(n=1;n<3;n++) if(ltos[lcmb[cl].l[l]][n]>-1) if((ltos[lcmb[cl].l[l]][n]!=s)&&(sori[ltos[lcmb[cl].l[l]][n]]>0))
7923 	  {
7924 	    sur=ltos[lcmb[cl].l[l]][n];
7925             printf("surf:%s lcmb:%s line:%s oriented surf:%s\n", surf[s].name, lcmb[cl].name, line[lcmb[cl].l[l]].name, surf[sur].name);
7926             surl= lcmb[cl].l[l];
7927 
7928             /* check if the surf must be inverted */
7929             /* based on the product of orientations of the oriented surf */
7930             /* determine the index of the connected line in sur */
7931             if(surf[sur].ori=='+') prod1=1; else prod1=-1;
7932             for(ll=0; ll<surf[sur].nl; ll++)
7933             {
7934               if(surf[sur].typ[ll]=='l')
7935               {
7936 		if(surl==surf[sur].l[ll])
7937                 {
7938                   if(surf[sur].o[ll]=='+') prod1*=1; else prod1*=-1;
7939                   goto found2;
7940                 }
7941    	      }
7942    	      else
7943               {
7944                 for(lll=0; lll<lcmb[surf[sur].l[ll]].nl; lll++)
7945                 if(surl==lcmb[surf[sur].l[ll]].l[lll])
7946                 {
7947                   if(surf[sur].o[ll]=='+') prod1*=1; else prod1*=-1;
7948                   if(lcmb[surf[sur].l[ll]].o[lll]=='+') prod1*=1; else prod1*=-1;
7949                   goto found2;
7950    	        }
7951    	      }
7952 	    }
7953 	   found2:;
7954 
7955             /* product of orientations of the actual surf */
7956             if(surf[s].ori=='+') prod2=1; else prod2=-1;
7957             if(surf[s].o[j]=='+') prod2*=1; else prod2*=-1;
7958             if(lcmb[cl].o[l]=='+') prod2*=1; else prod2*=-1;
7959 
7960             sori[s]=1;
7961             if(prod2==prod1)
7962 	    {
7963               flipSurfori(s);
7964 	    }
7965             goto new_surf;
7966 	  }
7967 	}
7968       }
7969     }
7970     new_surf:;
7971   }
7972   if(oriflag)
7973   {
7974     counter++;
7975     if(counter<anzGeo->s) goto more;
7976     else printf(" WARNING: too much loops. Some surfs might be still unoriented.\n");
7977   }
7978 }
7979 
7980 
flip(char * type,int e)7981 void flip( char *type, int e)
7982 {
7983   int s=0;
7984   int nbuf[20];
7985 
7986   if (type[0]=='b')
7987   {
7988     /* switch body */
7989     if(body[e].ori=='+') body[e].ori='-'; else body[e].ori='+';
7990   }
7991   else if (type[0]=='s')
7992   {
7993     /* switch surface and elements and embedded faces */
7994     /* identify the surf */
7995     s=e;
7996 
7997     /* check if all connected surfs should be oriented according to the identified one */
7998     if(type[1]=='a')
7999     {
8000       oriAllSurfs(s);
8001     }
8002     else flipSurfori(s);
8003   }
8004   else if ((type[0]=='e')&&(anzGeo->s>0)&&(selem!=NULL))
8005   {
8006     /* warning: selem is allocated in qflp */
8007     /* switch surface and elements and embedded faces */
8008     /* identify the surf */
8009     s=selem[e];
8010 
8011     /* check if all connected surfs should be oriented according to the identified one */
8012     if(type[1]=='a')
8013     {
8014       oriAllSurfs(s);
8015     }
8016     else flipSurfori(s);
8017   }
8018   else if (type[0]=='e')
8019   {
8020     /* switch orient of the single element */
8021       if (e_enqire[e].type == 7)
8022       {
8023         nbuf[1]=e_enqire[e].nod[1];
8024         nbuf[2]=e_enqire[e].nod[2];
8025         e_enqire[e].nod[2]=nbuf[1];
8026         e_enqire[e].nod[1]=nbuf[2];
8027       }
8028       else if (e_enqire[e].type == 8)
8029       {
8030         nbuf[0]=e_enqire[e].nod[0];
8031         nbuf[1]=e_enqire[e].nod[1];
8032         nbuf[4]=e_enqire[e].nod[4];
8033         nbuf[5]=e_enqire[e].nod[5];
8034         e_enqire[e].nod[0]=nbuf[1];
8035         e_enqire[e].nod[1]=nbuf[0];
8036         e_enqire[e].nod[4]=nbuf[5];
8037         e_enqire[e].nod[5]=nbuf[4];
8038       }
8039       else if (e_enqire[e].type == 9)
8040       {
8041         nbuf[1]=e_enqire[e].nod[1];
8042         nbuf[3]=e_enqire[e].nod[3];
8043         e_enqire[e].nod[3]=nbuf[1];
8044         e_enqire[e].nod[1]=nbuf[3];
8045       }
8046       else if (e_enqire[e].type == 10)
8047       {
8048         nbuf[1]=e_enqire[e].nod[1];
8049         nbuf[3]=e_enqire[e].nod[3];
8050         nbuf[4]=e_enqire[e].nod[4];
8051         nbuf[5]=e_enqire[e].nod[5];
8052         nbuf[6]=e_enqire[e].nod[6];
8053         nbuf[7]=e_enqire[e].nod[7];
8054         e_enqire[e].nod[3]=nbuf[1];
8055         e_enqire[e].nod[1]=nbuf[3];
8056         e_enqire[e].nod[7]=nbuf[4];
8057         e_enqire[e].nod[6]=nbuf[5];
8058         e_enqire[e].nod[5]=nbuf[6];
8059         e_enqire[e].nod[4]=nbuf[7];
8060       }
8061       else
8062       {
8063         printf(" ERROR: element type %d not known\n", e_enqire[e].type);
8064       }
8065   }
8066   getFaceNormalen( face, node, anz );
8067   getElemNormalen( e_enqire, node, anz->e );
8068   updateDispLists();
8069 }
8070