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 TODO:
25 - oriTetBody must be improved. The body might be inside-out for shapes like
26   a disk rim were the CG is not inside the body
27 */
28 
29 #include <cgx.h>
30 
31 #define TEST 0
32 
33 extern Points    *point;
34 extern Lines     *line;
35 extern Lcmb      *lcmb;
36 extern Gsur      *surf;
37 extern Gbod      *body;
38 extern Nurbs     *nurbs;
39 extern SumGeo    anzGeo[1];
40 
41 
42 /* Set Management */
43 extern Sets      *set;
44 extern Scale     scale[1];
45 extern SpecialSet specialset[1];
46 extern char  printFlag;                     /* printf on/off */
47 
48 
49 
angleSurfBody(double * v0,double * v1,double * v2,double * scg,double * bcg)50 double angleSurfBody( double *v0, double *v1, double *v2, double *scg, double *bcg )
51 {
52   double vsb[3], vsb_[3];
53   double v01[3], v02[3], vn[3], vn_[3];
54   double fi;
55 
56    /* vektor surf-body */
57     v_result( scg, bcg, vsb );
58     v_norm(  vsb, vsb_ );
59     /* normale auf surf */
60     v_result( v0, v1, v01 );
61     v_result( v0, v2, v02 );
62     v_prod( v01, v02, vn );
63     v_norm( vn, vn_ );
64     /* winkel zwischen den Vektoren */
65     fi=v_sprod( vsb_, vn_ );
66     return(fi);
67 }
68 
69 
70 /* lcmb rueckgabe von 1. linie bis n.linie orientiert (linie*ori zeigt in richtung letzte linie) */
orientLcmb(int nr)71 int orientLcmb( int nr )
72 {
73   int i,j;
74   int     flag1, flag2, pnt=0, err=0, lcount=0;
75   int     *sortLines=NULL;
76   char    *sortOri=NULL;
77 
78   if(printFlag) printf (" orient lcmb:%s ", lcmb[nr].name);
79 
80   /* loesche alle linien orientierungen */
81   for (i=0; i<lcmb[nr].nl; i++)
82   {
83     lcmb[nr].o[i]=0;
84   }
85 
86   if((sortOri = (char *)realloc((char *)sortOri, (lcmb[nr].nl)*sizeof(char)) ) == NULL )
87   { printf(" ERROR: realloc failure in orientLcmb()\n\n"); return(-1); }
88   if((sortLines=(int *)realloc((int *)sortLines, (lcmb[nr].nl)*sizeof(int) ) )==NULL)
89   { printf(" ERROR: realloc failure in orientLcmb()\n\n"); return(-1); }
90 
91   /* suche die erste linie (suche einen punkt der nur mit einer linie verbunden ist) */
92   /* und orientiere diese */
93   for (i=0; i<lcmb[nr].nl; i++)
94   {
95     flag1=flag2=0;
96     for (j=0; j<lcmb[nr].nl; j++)
97     {
98       if (i!=j)
99       {
100         if ( line[lcmb[nr].l[i]].p1 == line[lcmb[nr].l[j]].p1 ) flag1=1;
101         if ( line[lcmb[nr].l[i]].p1 == line[lcmb[nr].l[j]].p2 ) flag1=1;
102         if ( line[lcmb[nr].l[i]].p2 == line[lcmb[nr].l[j]].p1 ) flag2=1;
103         if ( line[lcmb[nr].l[i]].p2 == line[lcmb[nr].l[j]].p2 ) flag2=1;
104       }
105     }
106     if (!flag1)
107     {
108       /* p1 ist frei, linie ist + orientiert */
109       lcmb[nr].o[i]='+';
110       pnt=line[lcmb[nr].l[i]].p2;
111       break;
112     }
113     if (!flag2)
114     {
115       /* p2 ist frei, linie ist - orientiert */
116       lcmb[nr].o[i]='-';
117       pnt=line[lcmb[nr].l[i]].p1;
118       break;
119     }
120   }
121   if (i==lcmb[nr].nl)
122   {
123     errMsg(" ERROR: lcmb %s are a closed loop, no orientation possible\n", lcmb[nr].name);
124     for (j=0; j<lcmb[nr].nl; j++) printf(" %s", line[lcmb[nr].l[j]].name);
125     printf("\n");
126     err=-i;
127   }
128   else
129   {
130     sortLines[lcount]=lcmb[nr].l[i];      /* merke dir die reihenfolge in der die linien kommen */
131     sortOri[lcount]=  lcmb[nr].o[i];      /* merke dir die dazugehoerigen orientationen */
132     lcount++;
133   }
134 
135   for (i=1; i<lcmb[nr].nl; i++)  /* ori die restlichen linien */
136   {
137     for (j=0; j<lcmb[nr].nl; j++) /* suche die anschliessende durch vergleich */
138     {
139       if (!lcmb[nr].o[j])              /* wenn ori noch == 0 */
140       {
141         /*
142         printf ("pnt:%s \n", point[pnt].name);
143         */
144         if ( line[lcmb[nr].l[j]].p1 == pnt )
145         {  pnt=line[lcmb[nr].l[j]].p2; lcmb[nr].o[j]='+';
146            sortLines[lcount]=lcmb[nr].l[j]; sortOri[lcount]=lcmb[nr].o[j]; lcount++; break; }
147         if ( line[lcmb[nr].l[j]].p2 == pnt )
148         {  pnt=line[lcmb[nr].l[j]].p1; lcmb[nr].o[j]='-';
149            sortLines[lcount]=lcmb[nr].l[j]; sortOri[lcount]=lcmb[nr].o[j]; lcount++; break; }
150       }
151     }
152   }
153 
154   /* check for unoriented lines */
155   for (i=0; i<lcmb[nr].nl; i++)
156   {
157     if (!lcmb[nr].o[i])
158     {
159       err--;
160       errMsg(" ERROR: l:%s in lcmb:%s  not chained and therefore not oriented.\n", line[lcmb[nr].l[i]].name, lcmb[nr].name );
161       /* unverbundene linien werden am ende angehaengt */
162       sortLines[lcount]=lcmb[nr].l[i];  sortOri[lcount]='+'; lcount++;
163     }
164   }
165   if (lcount!=lcmb[nr].nl) errMsg(" ERROR: lcount:%d != %d lines in lcmb:%s\n",
166      lcount,  lcmb[nr].nl, lcmb[nr].name );
167 
168   /* rearange lines */
169   for (i=0; i<lcmb[nr].nl; i++)
170   {
171     lcmb[nr].o[i]=sortOri[i];
172     lcmb[nr].l[i]=sortLines[i];
173     if(printFlag) printf ("%1c %s ", lcmb[nr].o[i], line[lcmb[nr].l[i]].name );
174   }
175   if(printFlag) printf ("\n");
176 
177   /* determine the end-points */
178   if (lcmb[nr].o[0]=='+')           lcmb[nr].p1=line[lcmb[nr].l[0]].p1;
179   else                              lcmb[nr].p1=line[lcmb[nr].l[0]].p2;
180   if (lcmb[nr].o[lcmb[nr].nl-1]=='+') lcmb[nr].p2=line[lcmb[nr].l[lcmb[nr].nl-1]].p2;
181   else                              lcmb[nr].p2=line[lcmb[nr].l[lcmb[nr].nl-1]].p1;
182 
183   /*
184   printf("l0:%s p1:%s p2:%s   l2:%s p1:%s p2:%s \n", line[lcmb[nr].l[0]].name,
185     point[line[lcmb[nr].l[0]].p1].name, point[line[lcmb[nr].l[0]].p2].name,
186     line[lcmb[nr].l[lcmb[nr].nl-1]].name, point[line[lcmb[nr].l[lcmb[nr].nl-1]].p1].name,
187     point[line[lcmb[nr].l[lcmb[nr].nl-1]].p2].name);
188   printf ("p1:%s p2:%s\n", point[lcmb[nr].p1].name, point[lcmb[nr].p2].name );
189   */
190 
191   free(sortLines);
192   free(sortOri);
193   return(err);
194 }
195 
196 
197 /* surf rueckgabe von 1. linie bis n.linie orientiert. linie*ori zeigt in richtung letzte linie. */
198 /* Die finale orientierung von surfaces mit inneren loops geschieht in repSurf(), */
199 /* danach muessen die betroffenen bodies final orientiert werden */
200 /* vorher ist ein tet-volumen netz nicht erzeugbar */
orientSurf(int nr)201 int orientSurf( int nr )
202 {
203   int i,j=0, n=0;
204   int     flag1, flag2, err=0, lcount=0;
205   int     p1,p2, pnt=0, sl, cl, l0;
206   int     line0_p1, line0_p2;
207   int     *sortLines=NULL;
208   int     *cp=NULL;
209   char    *sortOri=NULL, *tmpOri=NULL, *sortTyp=NULL;
210 
211 
212   if(printFlag) printf (" orient surf:%s ", surf[nr].name);
213 
214   if((sortOri = (char *)realloc((char *)sortOri, (surf[nr].nl)*sizeof(char)) ) == NULL )
215   { printf(" ERROR: realloc failure in orientSurf()\n\n"); return(-1); }
216   if((sortTyp = (char *)realloc((char *)sortTyp, (surf[nr].nl)*sizeof(char)) ) == NULL )
217   { printf(" ERROR: realloc failure in orientSurf()\n\n"); return(-1); }
218   if((sortLines=(int *)realloc((int *)sortLines, (surf[nr].nl)*sizeof(int) ) )==NULL)
219   { printf(" ERROR: realloc failure in orientSurf()\n\n"); return(-1); }
220   if((cp=(int *)realloc((int *)cp, (surf[nr].nl)*sizeof(int) ) )==NULL)
221   { printf(" ERROR: realloc failure in orientSurf()\n\n"); return(-1); }
222   if((tmpOri = (char *)realloc((char *)tmpOri, (surf[nr].nl)*sizeof(char)) ) == NULL )
223   { printf(" ERROR: realloc failure in orientSurf()\n\n"); return(-1); }
224 
225   /* loesche alle linien orientierungen */
226   for (i=0; i<surf[nr].nl; i++)
227   {
228     tmpOri[i]=surf[nr].o[i];
229     surf[nr].o[i]=0;
230   }
231   surf[nr].nc= 0;
232 
233 
234   /* Definiere die Linienzuege (curves) zb: Auessere Umrandung, innere Loecher */
235   /* die einzelnen Linenzuege werden zum NURBS-Trimming benutzt. Zumstrukturierten Vernetzen sind */
236   /* nur Surfaces mit einem Linienzug geeignet */
237   do
238   {
239 #if TEST
240     printf("curve starts with n:%d lcount:%d \n",n,lcount);
241 #endif
242     /* suche den punkt einer linie die mit der ersten linie verbunden ist */
243     /* und orientiere die erste linie */
244     if (surf[nr].typ[n]=='c')
245     {
246       sl=surf[nr].l[n];
247       cl=lcmb[sl].nl-1;
248         /* erste linie der lcmb enthaelt den 1.p fuer den vergl. */
249         /* letzte linie der lcmb enthaelt den 2.p fuer den vergl. */
250         if(lcmb[sl].o[0]=='+')  line0_p1=line[lcmb[sl].l[0]].p1;
251         else                    line0_p1=line[lcmb[sl].l[0]].p2;
252         if(lcmb[sl].o[cl]=='+') line0_p2=line[lcmb[sl].l[cl]].p2;
253         else                    line0_p2=line[lcmb[sl].l[cl]].p1;
254     }
255     else
256     {
257       l0=surf[nr].l[n];
258       line0_p1=line[l0].p1;
259       line0_p2=line[l0].p2;
260     }
261 
262 #if TEST
263     for (i=0; i<surf[nr].nl; i++)
264     {
265       if (surf[nr].typ[i]=='c')
266         printf("%1c %1c %s\n",surf[nr].typ[i], surf[nr].o[i], lcmb[surf[nr].l[i]].name);
267       else if (surf[nr].typ[i]=='l')
268         printf("%1c %1c %s\n", surf[nr].typ[i], surf[nr].o[i], line[surf[nr].l[i]].name);
269       else printf("unknown line\n");
270     }
271 #endif
272 
273     /* lcmb muessen sortiert vorliegen */
274     /* gehe durch alle Linien und suche die zweite Linie */
275     flag1=flag2=0;
276     for (i=n+1; i<surf[nr].nl; i++)
277     {
278       if (surf[nr].typ[i]=='c')
279       {
280         sl=surf[nr].l[i];
281         cl=lcmb[sl].nl-1;
282         /* erste linie der lcmb enthaelt den 1.p fuer den vergl. */
283         /* letzte linie der lcmb enthaelt den 2.p fuer den vergl. */
284         if(lcmb[sl].o[0]=='+')  p1=line[lcmb[sl].l[0]].p1;
285         else                    p1=line[lcmb[sl].l[0]].p2;
286         if(lcmb[sl].o[cl]=='+') p2=line[lcmb[sl].l[cl]].p2;
287         else                    p2=line[lcmb[sl].l[cl]].p1;
288 #if TEST
289     printf ("%1c lc1:%s %1c lc2:%s \n", lcmb[sl].o[0], line[lcmb[sl].l[0]].name,
290                                         lcmb[sl].o[cl], line[lcmb[sl].l[cl]].name);
291     printf (" p1:%s p2:%s \n", point[p1].name, point[p2].name);
292 #endif
293       }
294       else
295       {
296         p1=line[surf[nr].l[i]].p1;
297         p2=line[surf[nr].l[i]].p2;
298 #if TEST
299     printf ("l:%s  \n", line[surf[nr].l[i]].name );
300 #endif
301       }
302 
303       if(tmpOri[n]=='+')
304       {
305         if      ( line0_p2 == p2 ) flag2=2;
306         else if ( line0_p2 == p1 ) flag2=1;
307         else if ( line0_p1 == p2 ) flag1=2;
308         else if ( line0_p1 == p1 ) flag1=1;
309       }
310       else
311       {
312         if      ( line0_p1 == p2 ) flag1=2;
313         else if ( line0_p1 == p1 ) flag1=1;
314         else if ( line0_p2 == p2 ) flag2=2;
315         else if ( line0_p2 == p1 ) flag2=1;
316       }
317 
318       if (flag1==1)
319       {
320           surf[nr].o[n]='-';
321           surf[nr].o[i]='+';
322           pnt=p2;
323           break;
324       }
325       else if (flag1==2)
326       {
327           surf[nr].o[n]='-';
328           surf[nr].o[i]='-';
329           pnt=p1;
330           break;
331       }
332       else if (flag2==1)
333       {
334           surf[nr].o[n]='+';
335           surf[nr].o[i]='+';
336           pnt=p2;
337           break;
338       }
339       else if (flag2==2)
340       {
341           surf[nr].o[n]='+';
342           surf[nr].o[i]='-';
343           pnt=p1;
344           break;
345       }
346       else pnt=0;
347     }
348 
349     if (i==surf[nr].nl)
350     {
351       errMsg("WARNING: surf not closed, no orientation possible\n");
352       for (i=0; i<surf[nr].nl; i++)
353       {
354         surf[nr].o[i]='+';
355       }
356       goto orientSurfError;
357     }
358     else
359     {
360       sortLines[lcount]=surf[nr].l[n];      /* merke dir die reihenfolge in der die linien kommen */
361       sortOri[lcount]=  surf[nr].o[n];      /* merke dir die dazugehoerigen orientationen */
362       sortTyp[lcount]=  surf[nr].typ[n];
363       lcount++;
364       sortLines[lcount]=surf[nr].l[i];      /* merke dir die reihenfolge in der die linien kommen */
365       sortOri[lcount]=  surf[nr].o[i];      /* merke dir die dazugehoerigen orientationen */
366       sortTyp[lcount]=  surf[nr].typ[i];
367       lcount++;
368     }
369 
370 #if TEST
371    printf ("Curve:%d Start-line:%s ori:%c 2line:%s ori:%c \n",surf[nr].nc,line[surf[nr].l[n]].name, surf[nr].o[n], line[surf[nr].l[i]].name, surf[nr].o[i] );
372 #endif
373     for (i=n+1; i<surf[nr].nl; i++)  /* ori die restlichen linien */
374     {
375       for (j=0; j<surf[nr].nl; j++) /* suche die anschliessende durch vergleich */
376       {
377         if (!surf[nr].o[j])              /* wenn ori noch == 0 */
378         {
379 #if TEST
380           printf ("pnt:%s nr:%d j:%d\n", point[pnt].name, nr,j);
381 #endif
382           if (surf[nr].typ[j]=='c')
383           {
384             sl=surf[nr].l[j];
385             cl=lcmb[sl].nl-1;
386             if(lcmb[sl].o[0]=='+')     p1=line[lcmb[sl].l[0]].p1;
387             else                       p1=line[lcmb[sl].l[0]].p2;
388             if(lcmb[sl].o[cl]=='+')   p2=line[lcmb[sl].l[cl]].p2;
389             else                      p2=line[lcmb[sl].l[cl]].p1;
390 #if TEST
391    printf ("lcmb:%s pnt:%d p1:%d p2:%d\n", lcmb[surf[nr].l[j]].name, pnt, p1, p2 );
392 #endif
393           }
394           else
395           {
396             p1=line[surf[nr].l[j]].p1;
397             p2=line[surf[nr].l[j]].p2;
398 #if TEST
399    printf ("i:%d j:%d line:%s ori:%c pnt:%d p1:%d p2:%d\n", i,j,line[surf[nr].l[j]].name, surf[nr].o[j], pnt, p1, p2 );
400 #endif
401           }
402 
403           if ( p1 == pnt )
404           {  pnt=p2; surf[nr].o[j]='+';
405 #if TEST
406    printf ("i:%d j:%d line:%s pnt:%d p1:%d p2:%d\n", i,j,line[surf[nr].l[j]].name, pnt, p1, p2 );
407 #endif
408              sortLines[lcount]=surf[nr].l[j]; sortOri[lcount]=surf[nr].o[j];
409              sortTyp[lcount]=surf[nr].typ[j]; lcount++; }
410           else if ( p2 ==  pnt )
411           {  pnt=p1; surf[nr].o[j]='-';
412 #if TEST
413    printf ("i:%d j:%d line:%s pnt:%d p1:%d p2:%d\n", i,j,line[surf[nr].l[j]].name, pnt, p1, p2 );
414 #endif
415              sortLines[lcount]=surf[nr].l[j]; sortOri[lcount]=surf[nr].o[j];
416              sortTyp[lcount]=surf[nr].typ[j]; lcount++; }
417         }
418       }
419     }
420 
421     /* check if the curve is closed and store the first line-index of the surf */
422     if(sortTyp[n]=='l')
423     {
424       if((pnt==line[sortLines[n]].p1)||(pnt==line[sortLines[n]].p2))
425       {
426         /* start-index of the curve */
427         if((surf[nr].c=(int *)realloc((int *)surf[nr].c, (surf[nr].nc+1)*sizeof(int)) )==NULL)
428         { printf(" ERROR: realloc failure in orient surf:%s can not be oriented\n", surf[nr].name); exit(-1); }
429         surf[nr].c[surf[nr].nc]=lcount-n;
430         surf[nr].nc++;
431       }
432     }
433     else if(sortTyp[n]=='c')
434     {
435       if((pnt==lcmb[sortLines[n]].p1)||(pnt==lcmb[sortLines[n]].p2))
436       {
437         /* start-index of the curve */
438         if((surf[nr].c=(int *)realloc((int *)surf[nr].c, (surf[nr].nc+1)*sizeof(int)) )==NULL)
439         { printf(" ERROR: realloc failure in orient surf:%s can not be oriented\n", surf[nr].name); exit(-1); }
440         surf[nr].c[surf[nr].nc]=lcount-n;
441         surf[nr].nc++;
442       }
443     }
444     else
445     {
446       printf("WARNING in ori: Surf:%s has an unclosed curve\n", surf[nr].name);
447       printf("typ:%c pnt:%s line[sortLines[n]].p1:%s line[sortLines[n]].p2:%s\n", sortTyp[n], point[pnt].name, point[line[sortLines[n]].p1].name, point[line[sortLines[n]].p2].name);
448       goto finish_ori;
449     }
450 
451     /* check for unoriented lines */
452     err=0;
453     for (n=0; n<surf[nr].nl; n++)
454     {
455       if (!surf[nr].o[n])
456       {
457         err--;
458         break;
459       }
460     }
461   }while(err<0);
462 
463 
464   finish_ori:;
465   /* check of the loop was closed */
466   if(surf[nr].nc==0)
467   {
468     errMsg(" WARNING: surf:%s not chained and therefore not oriented.\n", surf[nr].name );
469     err--;
470   }
471 
472   /* check for unoriented lines */
473   for (i=0; i<surf[nr].nl; i++)
474   {
475     if (!surf[nr].o[i])
476     {
477       err--;
478       if (surf[nr].typ[i]=='l')
479         errMsg(" ERROR: l:%s in surf:%s not chained and therefore not oriented.\n", line[surf[nr].l[i]].name, surf[nr].name );
480       else
481         errMsg(" ERROR: c:%s in surf:%s not chained and therefore not oriented.\n", lcmb[surf[nr].l[i]].name, surf[nr].name );
482       /* unverbundene linien werden am ende  angehaengt */
483       sortLines[lcount]=surf[nr].l[i];  sortOri[lcount]='+'; sortTyp[lcount]=surf[nr].typ[i]; lcount++;
484     }
485   }
486   if (lcount!=surf[nr].nl) errMsg(" ERROR: lcount:%d != %d lines in surf:%s\n",
487      lcount,  surf[nr].nl, surf[nr].name );
488 
489   /* re-arange lines */
490   for (i=0; i<surf[nr].nl; i++)
491   {
492     surf[nr].typ[i]=sortTyp[i];
493     surf[nr].o[i]=sortOri[i];
494     surf[nr].l[i]=sortLines[i];
495     if ((surf[nr].typ[i]=='l')&&(printFlag)) printf("%1c %s ", surf[nr].o[i], line[surf[nr].l[i]].name );
496     else if(printFlag) printf ("%1c %s ", surf[nr].o[i], lcmb[surf[nr].l[i]].name );
497   }
498   if(printFlag) printf ("\n");
499 
500   /* suche die Eckknoten der surface */
501   /* beruecksichtige dabei die orientierung der linien oder lcmbs */
502   /* so das die punktefolge der linienfolge entspricht */
503   /* aus den eckknoten wird der Schwerpunkt (CG) bestimmt */
504 
505   /* suche den ersten punkt der ersten linie oder lcmb der surf */
506   sl=surf[nr].l[0];
507   if (surf[nr].typ[0]=='c')
508   {
509     cl=lcmb[sl].nl-1;
510     if (surf[nr].o[0]=='-')
511     {
512       if(lcmb[sl].o[cl]=='+') cp[0]=line[lcmb[sl].l[cl]].p2;
513       else                    cp[0]=line[lcmb[sl].l[cl]].p1;
514     }
515     else
516     {
517       if(lcmb[sl].o[0]=='+')  cp[0]=line[lcmb[sl].l[0]].p1;
518       else                    cp[0]=line[lcmb[sl].l[0]].p2;
519     }
520   }
521   else if (surf[nr].typ[0]=='l')
522   {
523     if (surf[nr].o[0]=='-')
524     {
525       cp[0]=line[surf[nr].l[0]].p2;
526     }
527     else
528     {
529       cp[0]=line[surf[nr].l[0]].p1;
530     }
531   }
532   else { errMsg (" ERROR in orientSurf, surf.typ:%1c not known\n", surf[nr].typ[j]); exit(-1);}
533 
534   /* suche den anfangspunkt aller weiteren linien oder lcmbs der surf */
535   for (j=1; j<surf[nr].nl; j++)
536   {
537     sl=surf[nr].l[j];
538     if (surf[nr].typ[j]=='c')
539     {
540       cl=lcmb[sl].nl-1;
541       if (surf[nr].o[j]=='-')
542       {
543         if(lcmb[sl].o[cl]=='+') cp[j]=line[lcmb[sl].l[cl]].p2;
544         else                    cp[j]=line[lcmb[sl].l[cl]].p1;
545       }
546       else
547       {
548         if(lcmb[sl].o[0]=='+')  cp[j]=line[lcmb[sl].l[0]].p1;
549         else                    cp[j]=line[lcmb[sl].l[0]].p2;
550       }
551     }
552     else if (surf[nr].typ[j]=='l')
553     {
554       if (surf[nr].o[j]=='-')
555       {
556         cp[j]=line[surf[nr].l[j]].p2;
557       }
558       else
559       {
560         cp[j]=line[surf[nr].l[j]].p1;
561       }
562     }
563     else { errMsg (" ERROR in orientSurf, surf.typ:%1c not known\n", surf[nr].typ[j]); exit(-1);}
564   }
565 
566   /* berechnung des CG, koordinaten werden descaliert gespeichert */
567   /* sonst muesste bei jeder aenderung von scale orientSet() ablaufen */
568   surf[nr].cx=surf[nr].cy=surf[nr].cz=0.;
569   surf[nr].cp=cp;
570   for (i=0; i<surf[nr].nl; i++)
571   {
572     surf[nr].cx+=(point[cp[i]].px* scale->w+scale->x)/surf[nr].nl;
573     surf[nr].cy+=(point[cp[i]].py* scale->w+scale->y)/surf[nr].nl;
574     surf[nr].cz+=(point[cp[i]].pz* scale->w+scale->z)/surf[nr].nl;
575   }
576   free(sortLines);
577   free(cp);
578   free(sortOri);
579   free(tmpOri);
580   free(sortTyp);
581   return(err);
582  orientSurfError:;
583   free(sortLines);
584   free(cp);
585   free(sortOri);
586   free(tmpOri);
587   free(sortTyp);
588   return(-1);
589 }
590 
591 
592 /* ordnet die Flaechen eines Bodies endsprechend der Topologiedefinition */
593 /* in: */
594 /*   nr                                   body-index */
595 /*   cp[SURFS_PER_BODY][EDGES_PER_SURF];  corner points der surfs */
596 /* out:   */
597 /*   return 1 if successfull or -1 if not */
ori7SidedBody(int nr,int ** cp)598 int ori7SidedBody( int nr, int **cp )
599 {
600   int i,j,k;
601   int s, p0=0, p1=0, sl=0, cl, cl1, p0_s4;
602   int surfIndex[7];           /* index einer surf, Topologieabh. gespeichert */
603   int body_ns[7];             /* speichert die pos innerhalb der body definition */
604   char  surfOri[7];    /* orientierung  */
605   double scg[3], bcg[3];
606   double v0[3], v1[3], v2[3];
607   double fi;
608 
609   /* 7surfs: surf-order im surf-kreuz: 0 m, 1 g, 2 lo, 3 l, 4 u, 5 r, 6 ro */
610   /* startsurf ist 0, 4 haengt an v01, 5 an v12, 6 an v23, 2 an v34, 3 an v40, 1 bleibt uebrig */
611   /* v01 ist der Vektor von cp[][0] nach cp[][1]  */
612 
613   /* zuerst wird die orientierung der ersten surf willkuerlich auf + gesetzt. */
614   /* alle anderen werden relativ zur ersten orientiert. wenn die reihenfolge dann feststeht */
615   /* erfolgt eine berechnung der orientierungen der surfs, so das die meisten aus dem body zeigen. */
616   /* dazu wird der winkel zwischen surf-normalenvektor und surfCG-bodyCG-Vektor berechnet */
617 
618   /* suche eine geeignete bez.surf (0), diese muss 5 seiten haben */
619   for (i=0; i<body[nr].ns; i++)
620   {
621     if (surf[body[nr].s[i]].nl==5)
622     {
623       sl=i;            /* nr der bezugs surface im body-raum (0-6) */
624       goto sfound;
625     }
626   }
627   sfound:;
628 
629   k=0;
630 #if TEST
631       errMsg (" in orientBody, side %d sl:%d ori always:1 surf:%s \n",
632       k, sl, surf[body[nr].s[sl]].name);
633 #endif
634   s=body[nr].s[sl];
635   surfIndex[k]=s;
636   body_ns[k]=sl;
637   surfOri[k]=1;
638 
639 
640   k=6;  /* laufende nr der zu bestimmenden surf */
641   for (i=0; i<body[nr].ns; i++)
642   {
643     s=body[nr].s[i];
644     p0=p1=-1;
645     if(i!=sl)
646     {
647       for (j=0; j<surf[s].nl; j++)
648       {
649         if( cp[i][j]==cp[sl][2] ) p0=j;
650         if( cp[i][j]==cp[sl][3] ) p1=j;
651       }
652       if ((p0>-1)&&(p1>-1)) break;
653     }
654   }
655   if (i>=body[nr].ns)
656   { errMsg (" ERROR in orientBody, side %d from body:%s could not be located \n",
657       k, body[nr].name); return(-1);
658   }
659 #if TEST
660       errMsg (" in orientBody, side %d  surf:%s \n",
661       k, surf[s].name);
662 #endif
663   surfIndex[k]=s;
664   body_ns[k]=i;
665   /* surfori relativ zur surf0 */
666   if((p0==3)&&(p1==0)) p1=4;
667   else if((p1==3)&&(p0==0)) p0=4;
668   if(p0<p1) surfOri[k]=0 ;
669   else      surfOri[k]=1 ;
670 
671 
672   k=2;  /* laufende nr der zu bestimmenden surf */
673   for (i=0; i<body[nr].ns; i++)
674   {
675     s=body[nr].s[i];
676     p0=p1=-1;
677     if(i!=sl)
678     {
679       for (j=0; j<surf[s].nl; j++)
680       {
681         if( cp[i][j]==cp[sl][3] ) p0=j;
682         if( cp[i][j]==cp[sl][4] ) p1=j;
683       }
684       if ((p0>-1)&&(p1>-1)) break;
685     }
686   }
687   if (i>=body[nr].ns)
688   { errMsg (" ERROR in orientBody, side %d from body:%s could not be located \n",
689       k, body[nr].name); return(-1);
690   }
691 #if TEST
692       errMsg (" in orientBody, side %d  surf:%s \n",
693       k, surf[s].name);
694 #endif
695   surfIndex[k]=s;
696   body_ns[k]=i;
697   /* surfori relativ zur surf0 */
698   if((p0==3)&&(p1==0)) p1=4;
699   else if((p1==3)&&(p0==0)) p0=4;
700   if(p0<p1) surfOri[k]=0 ;
701   else      surfOri[k]=1 ;
702 
703 
704   k=3;  /* laufende nr der zu bestimmenden surf */
705   for (i=0; i<body[nr].ns; i++)
706   {
707     if(i!=sl)
708     {
709       s=body[nr].s[i];
710       p0=p1=-1;
711       for (j=0; j<surf[s].nl; j++)
712       {
713         if( cp[i][j]==cp[sl][4] ) p0=j;
714         if( cp[i][j]==cp[sl][0] ) p1=j;
715       }
716       if ((p0>-1)&&(p1>-1)) break;
717     }
718   }
719   if (i>=body[nr].ns)
720   { errMsg (" ERROR in orientBody, side %d from body:%s could not be located \n",
721       k, body[nr].name); return(-1);
722   }
723 #if TEST
724       errMsg (" in orientBody, side %d  surf:%s \n",
725       k, surf[s].name);
726 #endif
727   surfIndex[k]=s;
728   body_ns[k]=i;
729   if((p0==3)&&(p1==0)) p1=4;
730   else if((p1==3)&&(p0==0)) p0=4;
731   if(p0<p1) surfOri[k]=0 ;
732   else      surfOri[k]=1 ;
733 
734 
735   k=5;  /* laufende nr der zu bestimmenden surf */
736   for (i=0; i<body[nr].ns; i++)
737   {
738     s=body[nr].s[i];
739     p0=p1=-1;
740     if(i!=sl)
741     {
742       for (j=0; j<surf[s].nl; j++)
743       {
744         if( cp[i][j]==cp[sl][1] ) p0=j;
745         if( cp[i][j]==cp[sl][2] ) p1=j;
746       }
747       if ((p0>-1)&&(p1>-1)) break;
748     }
749   }
750   if (i>=body[nr].ns)
751   { errMsg (" ERROR in orientBody, side %d from body:%s could not be located \n",
752       k, body[nr].name); return(-1);
753   }
754 #if TEST
755       errMsg (" in orientBody, side %d  surf:%s \n",
756       k, surf[s].name);
757 #endif
758   surfIndex[k]=s;
759   body_ns[k]=i;
760   if((p0==3)&&(p1==0)) p1=4;
761   else if((p1==3)&&(p0==0)) p0=4;
762   if(p0<p1) surfOri[k]=0 ;
763   else      surfOri[k]=1 ;
764 
765 
766   k=4;  /* laufende nr der zu bestimmenden surf    */
767   for (i=0; i<body[nr].ns; i++)
768   {
769     s=body[nr].s[i];
770     p0=p1=-1;
771     if(i!=sl)
772     {
773       for (j=0; j<surf[s].nl; j++)
774       {
775         if( cp[i][j]==cp[sl][0] ) p0=j;
776         if( cp[i][j]==cp[sl][1] ) p1=j;
777       }
778       if ((p0>-1)&&(p1>-1)) break;
779     }
780   }
781   if (i>=body[nr].ns)
782   { errMsg (" ERROR in orientBody, side %d from body:%s could not be located \n",
783       k, body[nr].name); return(-1);
784   }
785 #if TEST
786       errMsg (" in orientBody, side %d  surf:%s \n",
787       k, surf[s].name);
788 #endif
789   p0_s4=p0;
790   surfIndex[k]=s;
791   body_ns[k]=i;
792   if((p0==3)&&(p1==0)) p1=4;
793   else if((p1==3)&&(p0==0)) p0=4;
794   if(p0<p1) surfOri[k]=0 ;
795   else      surfOri[k]=1 ;
796 
797 
798   k=1;  /* laufende nr der zu bestimmenden surf                            */
799   surfIndex[k]=-1;
800   /* suche die noch nicht zugewiesene surf */
801   for (i=0; i<body[nr].ns; i++)
802   {
803     cl=0;
804     s=body[nr].s[i];
805     for (j=0; j<body[nr].ns; j++) { if(surfIndex[j]==s) cl=1; }
806     if(!cl) break;
807   }
808 #if TEST
809       errMsg (" in orientBody, side %d  surf:%s \n",
810       k, surf[s].name);
811 #endif
812   surfIndex[k]=s;
813   body_ns[k]=i;
814 
815   /* bestimme die orientierung mit hilfe der seite nr.4 */
816   /* wenn der drehsinn der surf mit surf 4 uebereinstimmt wird die ori von 4 uebernommen */
817   /* dafuer muessen die anschlusspunkte gefunden werden. p0 und p1 sind von surf 4 bekannt, */
818   /* die gegenueberliegenden werden gesucht */
819   if (surfOri[4]==surfOri[0])
820   {
821     cl=p0_s4+1;
822     if (cl>=surf[surfIndex[4]].nl) cl=0;
823     cl1=cl+1;
824     if (cl1>=surf[surfIndex[4]].nl) cl1=0;
825   }
826   else
827   {
828     cl=p0_s4+2;
829     if (cl>=surf[surfIndex[4]].nl) cl-=surf[surfIndex[4]].nl;
830     cl1=cl+1;
831     if (cl1>=surf[surfIndex[4]].nl) cl1-=surf[surfIndex[4]].nl;
832   }
833 
834   /* suche die anschlusspunkte zu surf 1 */
835   p0=p1=-1;
836   for (j=0; j<surf[s].nl; j++)
837   {
838     if( cp[i][j]==cp[body_ns[4]][cl] ) p0=j;
839     if( cp[i][j]==cp[body_ns[4]][cl1] ) p1=j;
840   }
841   if((p0==4)&&(p1==0)) p1=5;
842   else if((p1==4)&&(p0==0)) p0=5;
843   /* wenn die surf die gleiche drehrichtung hat wie surf4: */
844   if (p0>p1) surfOri[1]=surfOri[4];
845   else if(surfOri[4]==1) surfOri[1]=0;
846   else surfOri[1]=1;
847 
848 
849   /* die orientierungen aller surfs werden nun mit hilfe des schwerpunktes des bodies ueberprueft */
850   /* wenn die mehrzahl der surfnormalen aus dem body zeigt, ist alles ok, sonst invertieren */
851   bcg[0]=(body[nr].cx-scale->x)/scale->w;
852   bcg[1]=(body[nr].cy-scale->y)/scale->w;
853   bcg[2]=(body[nr].cz-scale->z)/scale->w;
854   cl=0;
855   for (i=0; i<body[nr].ns; i++)
856   {
857     s = surfIndex[i];
858     sl= body_ns[i];
859     /*
860     scg[0]=surf[s].cx;
861     scg[1]=surf[s].cy;
862     scg[2]=surf[s].cz;
863     bcg[0]=body[nr].cx;
864     bcg[1]=body[nr].cy;
865     bcg[2]=body[nr].cz;
866     */
867     scg[0]=(surf[s].cx-scale->x)/scale->w;
868     scg[1]=(surf[s].cy-scale->y)/scale->w;
869     scg[2]=(surf[s].cz-scale->z)/scale->w;
870     v0[0]=point[cp[sl][0]].px;
871     v0[1]=point[cp[sl][0]].py;
872     v0[2]=point[cp[sl][0]].pz;
873     v1[0]=point[cp[sl][1]].px;
874     v1[1]=point[cp[sl][1]].py;
875     v1[2]=point[cp[sl][1]].pz;
876     v2[0]=point[cp[sl][2]].px;
877     v2[1]=point[cp[sl][2]].py;
878     v2[2]=point[cp[sl][2]].pz;
879     fi=angleSurfBody( v0, v1, v2, scg, bcg );
880     if(surfOri[i])
881     {
882       if(fi>0.) cl-- ;
883       else      cl++ ;
884     }
885     else
886     {
887       if(fi>0.) cl++ ;
888       else      cl-- ;
889     }
890   }
891 
892   /* wenn cl<0: vertauschen von surf3 mit surf5  */
893   /* und vertauschen von surf2 mit surf6 und invertieren aller surfOri  */
894   if(cl<0)
895   {
896     cl1=surfOri[3];
897     surfOri[3]=surfOri[5];
898     surfOri[5]=cl1;
899     cl1=surfIndex[3];
900     surfIndex[3]=surfIndex[5];
901     surfIndex[5]=cl1;
902 
903     cl1=surfOri[2];
904     surfOri[2]=surfOri[6];
905     surfOri[6]=cl1;
906     cl1=surfIndex[2];
907     surfIndex[2]=surfIndex[6];
908     surfIndex[6]=cl1;
909   }
910 
911   /* define the body-structure */
912   for (i=0; i<body[nr].ns; i++)
913   {
914     body[nr].s[i]=surfIndex[i];
915     if((cl>0)&&(surfOri[i])) body[nr].o[i]='+';
916     else if((cl<0)&&(surfOri[i])) body[nr].o[i]='-';
917     else if((cl>0)&&(!surfOri[i])) body[nr].o[i]='-';
918     else if((cl<0)&&(!surfOri[i])) body[nr].o[i]='+';
919     if(printFlag) printf (" %1c %s", body[nr].o[i], surf[ body[nr].s[i] ].name );
920   }
921   if(printFlag) printf("\n");
922   return(1);
923 }
924 
925 
926 /* ordnet die Flaechen eines Bodies endsprechend der Topologiedefinition */
927 /* in: */
928 /*   nr                                   body-index */
929 /*   cp[SURFS_PER_BODY][EDGES_PER_SURF];  corner points der surfs */
930 /* out:   */
931 /*   return 1 if successfull or -1 if not */
ori6SidedBody(int nr,int ** cp)932 int ori6SidedBody( int nr, int **cp )
933 {
934   int i,j,k,n;
935   int s, p0=0, p1=0, sl=0, cl, cl1, ipuf, p0_s4;
936   int surfIndex[6];           /* index einer surf, Topologieabh. gespeichert */
937   int body_ns[6];             /* speichert die pos innerhalb der body definition */
938   char  surfOri[6];    /* orientierung  */
939   int   p_colapse[6];
940   double scg[3], bcg[3];
941   double v0[3], v1[3], v2[3];
942   double fi;
943 
944   /* 6surfs: surf-order im surf-kreuz: 0 m, 1 g, 2 o, 3 l, 4 u, 5 r */
945   /* startsurf ist 0, 4 haengt an v01, 5 an v12, 2 an v23, 3 an v30 , 1 bleibt uebrig */
946   /* v01 ist der Vektor von cp[][0] nach cp[][1]  */
947 
948   /* ACHTUNG: in meshSet() wird die Reihenfolge der Body-Corner-Points (bcp) anders definiert */
949   /* dort gilt bcp 0-3 werden durch die Mastersurf (0) festgelegt (orientabhaengig)  */
950   /*
951     if ( body[b_indx].o[0]=='+')
952     {
953       bcp[0]=scp[0][3];
954       bcp[1]=scp[0][2];
955       bcp[2]=scp[0][1];
956       bcp[3]=scp[0][0];
957     }
958     else if (body[b_indx].o[0]=='-')
959     {
960       bcp[0]=scp[0][2];
961       bcp[1]=scp[0][3];
962       bcp[2]=scp[0][0];
963       bcp[3]=scp[0][1];
964       }
965   */
966 
967   /* zuerst wird die orientierung der ersten surf willkuerlich auf + gesetzt. */
968   /* alle anderen werden relativ zur ersten orientiert. wenn die reihenfolge dann feststeht */
969   /* erfolgt eine berechnung der orientierungen der surfs, so das die meisten aus dem body zeigen. */
970   /* dazu wird der winkel zwischen surf-normalenvektor und surfCG-bodyCG-Vektor berechnet */
971 
972   /* suche eine geeignete bez.surf (0), fuer einen gewoehnl. brick ist jede Recht */
973   /* fuer ein brick mit kollabierter seite darf die bez.surf keinen eckpunkt der kol-*/
974   /* labierten surf enthalten. */
975 
976   /* suche punkte an den kollabierten seiten */
977   n=0;
978   for (i=0; i<body[nr].ns; i++)
979   {
980     if (surf[body[nr].s[i]].nl<4) return(-1);
981     if (cp[i][0]==cp[i][1]) {  p_colapse[n]=cp[i][0]; n++; }
982     if (cp[i][1]==cp[i][2]) {  p_colapse[n]=cp[i][1]; n++; }
983     if (cp[i][2]==cp[i][3]) {  p_colapse[n]=cp[i][2]; n++; }
984     if (cp[i][3]==cp[i][0]) {  p_colapse[n]=cp[i][3]; n++; }
985   }
986 
987   /* suche die seite die keine punkte kollabierter seiten enthaelt */
988   for (i=0; i<body[nr].ns; i++)
989   {
990     ipuf=1;
991     for (j=0; j<surf[body[nr].s[i]].nl; j++)
992     {
993       for (k=0; k<n; k++)
994       {
995         if (cp[i][j]==p_colapse[k]) ipuf=0;
996       }
997     }
998     if (ipuf)
999     {
1000       sl=i;            /* nr der bezugs surface im body-raum (0-5) */
1001       goto sfound;
1002     }
1003   }
1004   sfound:;
1005 
1006   k=0;
1007 #if TEST
1008       errMsg (" in orientBody, side %d sl:%d ori always:1 surf:%s \n",
1009       k, sl, surf[body[nr].s[sl]].name);
1010 #endif
1011   s=body[nr].s[sl];
1012   surfIndex[k]=s;
1013   body_ns[k]=sl;
1014   surfOri[k]=1;
1015 
1016 
1017   k=2;  /* laufende nr der zu bestimmenden surf */
1018   for (i=0; i<body[nr].ns; i++)
1019   {
1020     s=body[nr].s[i];
1021     p0=p1=-1;
1022     if(i!=sl)
1023     {
1024       for (j=0; j<surf[s].nl; j++)
1025       {
1026         if( cp[i][j]==cp[sl][2] ) p0=j;
1027         if( cp[i][j]==cp[sl][3] ) p1=j;
1028       }
1029       if ((p0>-1)&&(p1>-1)) break;
1030     }
1031   }
1032   if (i>=body[nr].ns)
1033   { errMsg (" ERROR in orientBody, side %d from body:%s could not be located \n",
1034       k, body[nr].name); return(-1);
1035   }
1036 #if TEST
1037       printf (" in orientBody, side:%d surf:%s p0:%d p1:%d %s %s",
1038       k, surf[s].name,p0,p1, point[cp[i][p0]].name, point[cp[i][p1]].name );
1039 #endif
1040   surfIndex[k]=s;
1041   body_ns[k]=i;
1042   /* surfori relativ zur surf0 */
1043   if((p0==3)&&(p1==0)) p1=4;
1044   else if((p1==3)&&(p0==0)) p0=4;
1045   if(p0<p1) surfOri[k]=0 ;
1046   else      surfOri[k]=1 ;
1047 #if TEST
1048       printf (" %d\n", surfOri[k] );
1049 #endif
1050 
1051 
1052   k=3;  /* laufende nr der zu bestimmenden surf */
1053   for (i=0; i<body[nr].ns; i++)
1054   {
1055     if(i!=sl)
1056     {
1057       s=body[nr].s[i];
1058       p0=p1=-1;
1059       for (j=0; j<surf[s].nl; j++)
1060       {
1061         if( cp[i][j]==cp[sl][3] ) p0=j;
1062         if( cp[i][j]==cp[sl][0] ) p1=j;
1063       }
1064       if ((p0>-1)&&(p1>-1)) break;
1065     }
1066   }
1067   if (i>=body[nr].ns)
1068   { errMsg (" ERROR in orientBody, side %d from body:%s could not be located \n",
1069       k, body[nr].name); return(-1);
1070   }
1071 #if TEST
1072       printf (" in orientBody, side:%d surf:%s p0:%d p1:%d %s %s",
1073       k, surf[s].name,p0,p1, point[cp[i][p0]].name, point[cp[i][p1]].name );
1074 #endif
1075   surfIndex[k]=s;
1076   body_ns[k]=i;
1077   if((p0==3)&&(p1==0)) p1=4;
1078   else if((p1==3)&&(p0==0)) p0=4;
1079   if(p0<p1) surfOri[k]=0 ;
1080   else      surfOri[k]=1 ;
1081 #if TEST
1082       printf (" %d\n", surfOri[k] );
1083 #endif
1084 
1085 
1086   k=5;  /* laufende nr der zu bestimmenden surf */
1087   for (i=0; i<body[nr].ns; i++)
1088   {
1089     s=body[nr].s[i];
1090     p0=p1=-1;
1091     if(i!=sl)
1092     {
1093       for (j=0; j<surf[s].nl; j++)
1094       {
1095         if( cp[i][j]==cp[sl][1] ) p0=j;
1096         if( cp[i][j]==cp[sl][2] ) p1=j;
1097       }
1098       if ((p0>-1)&&(p1>-1)) break;
1099     }
1100   }
1101   if (i>=body[nr].ns)
1102   { errMsg (" ERROR in orientBody, side %d from body:%s could not be located \n",
1103       k, body[nr].name); return(-1);
1104   }
1105 #if TEST
1106       printf (" in orientBody, side:%d surf:%s p0:%d p1:%d %s %s",
1107       k, surf[s].name,p0,p1, point[cp[i][p0]].name, point[cp[i][p1]].name );
1108 #endif
1109   surfIndex[k]=s;
1110   body_ns[k]=i;
1111   if((p0==3)&&(p1==0)) p1=4;
1112   else if((p1==3)&&(p0==0)) p0=4;
1113   if(p0<p1) surfOri[k]=0 ;
1114   else      surfOri[k]=1 ;
1115 #if TEST
1116       printf (" %d\n", surfOri[k] );
1117 #endif
1118 
1119 
1120   k=4;  /* laufende nr der zu bestimmenden surf    */
1121   for (i=0; i<body[nr].ns; i++)
1122   {
1123     s=body[nr].s[i];
1124     p0=p1=-1;
1125     if(i!=sl)
1126     {
1127       for (j=0; j<surf[s].nl; j++)
1128       {
1129         if( cp[i][j]==cp[sl][0] ) p0=j;
1130         if( cp[i][j]==cp[sl][1] ) p1=j;
1131       }
1132       if ((p0>-1)&&(p1>-1)) break;
1133     }
1134   }
1135   if (i>=body[nr].ns)
1136   { errMsg (" ERROR in orientBody, side %d from body:%s could not be located \n",
1137       k, body[nr].name); return(-1);
1138   }
1139 #if TEST
1140       printf (" in orientBody, side:%d surf:%s p0:%d p1:%d %s %s",
1141       k, surf[s].name,p0,p1, point[cp[i][p0]].name, point[cp[i][p1]].name );
1142 #endif
1143   surfIndex[k]=s;
1144   body_ns[k]=i;
1145   p0_s4=p0;
1146   if((p0==3)&&(p1==0)) p1=4;
1147   else if((p1==3)&&(p0==0)) p0=4;
1148   if(p0<p1) surfOri[k]=0 ;
1149   else      surfOri[k]=1 ;
1150 #if TEST
1151       printf (" %d\n", surfOri[k] );
1152 #endif
1153 
1154 
1155   k=1;  /* laufende nr der zu bestimmenden surf                            */
1156   surfIndex[k]=-1;
1157   /* suche die noch nicht zugewiesene surf */
1158   for (i=0; i<body[nr].ns; i++)
1159   {
1160     cl=0;
1161     s=body[nr].s[i];
1162     for (j=0; j<body[nr].ns; j++) { if(surfIndex[j]==s) cl=1; }
1163     if(!cl) break;
1164   }
1165   if (i>=body[nr].ns)
1166   { errMsg (" ERROR in orientBody, side %d from body:%s could not be located \n",
1167       k, body[nr].name); return(-1);
1168   }
1169   surfIndex[k]=s;
1170   body_ns[k]=i;
1171 
1172   /* bestimme die orientierung mit hilfe der seite nr.4 */
1173   /* wenn der drehsinn der surf mit surf 4 uebereinstimmt wird die ori von 4 uebernommen */
1174   /* dafuer muessen die anschlusspunkte gefunden werden. p0 und p1 sind von surf 4 bekannt, */
1175   /* die gegenueberliegenden werden gesucht */
1176   if (surfOri[4]==surfOri[0])
1177   {
1178     cl=p0_s4+1;
1179     if (cl>=surf[surfIndex[4]].nl) cl=0;
1180     cl1=cl+1;
1181     if (cl1>=surf[surfIndex[4]].nl) cl1=0;
1182   }
1183   else
1184   {
1185     cl=p0_s4+2;
1186     if (cl>=surf[surfIndex[4]].nl) cl-=surf[surfIndex[4]].nl;
1187     cl1=cl+1;
1188     if (cl1>=surf[surfIndex[4]].nl) cl1-=surf[surfIndex[4]].nl;
1189   }
1190 
1191   /* suche die anschlusspunkte zu surf 1 */
1192   p0=p1=-1;
1193   for (j=0; j<surf[s].nl; j++)
1194   {
1195     if( cp[i][j]==cp[body_ns[4]][cl] ) p0=j;
1196     if( cp[i][j]==cp[body_ns[4]][cl1] ) p1=j;
1197   }
1198 #if TEST
1199       printf (" in orientBody, side:%d surf:%s p0:%d p1:%d %s %s",
1200       k, surf[s].name,p0,p1, point[cp[i][p0]].name, point[cp[i][p1]].name );
1201 #endif
1202   if((p0==3)&&(p1==0)) p1=4;
1203   else if((p1==3)&&(p0==0)) p0=4;
1204   /* wenn die surf die gleiche drehrichtung hat wie surf4: */
1205   if (p0>p1) surfOri[1]=surfOri[4];
1206   else if(surfOri[4]==1) surfOri[1]=0;
1207   else surfOri[1]=1;
1208 #if TEST
1209       printf (" %d\n", surfOri[k] );
1210 #endif
1211 
1212   /* die orientierungen aller surfs werden nun mit hilfe des schwerpunktes des bodies ueberprueft */
1213   /* wenn die mehrzahl der surfnormalen aus dem body zeigt, ist alles ok, sonst invertieren */
1214   bcg[0]=(body[nr].cx-scale->x)/scale->w;
1215   bcg[1]=(body[nr].cy-scale->y)/scale->w;
1216   bcg[2]=(body[nr].cz-scale->z)/scale->w;
1217   cl=0;
1218   for (i=0; i<body[nr].ns; i++)
1219   {
1220     s = surfIndex[i];
1221     sl= body_ns[i];
1222     /*
1223     scg[0]=surf[s].cx;
1224     scg[1]=surf[s].cy;
1225     scg[2]=surf[s].cz;
1226     bcg[0]=body[nr].cx;
1227     bcg[1]=body[nr].cy;
1228     bcg[2]=body[nr].cz;
1229     */
1230     scg[0]=(surf[s].cx-scale->x)/scale->w;
1231     scg[1]=(surf[s].cy-scale->y)/scale->w;
1232     scg[2]=(surf[s].cz-scale->z)/scale->w;
1233     v0[0]=point[cp[sl][0]].px;
1234     v0[1]=point[cp[sl][0]].py;
1235     v0[2]=point[cp[sl][0]].pz;
1236     v1[0]=point[cp[sl][1]].px;
1237     v1[1]=point[cp[sl][1]].py;
1238     v1[2]=point[cp[sl][1]].pz;
1239     v2[0]=point[cp[sl][2]].px;
1240     v2[1]=point[cp[sl][2]].py;
1241     v2[2]=point[cp[sl][2]].pz;
1242     fi=angleSurfBody( v0, v1, v2, scg, bcg );
1243     /* plus zweitem winkel da eine seite concav sein koennte */
1244     v0[0]=point[cp[sl][1]].px;
1245     v0[1]=point[cp[sl][1]].py;
1246     v0[2]=point[cp[sl][1]].pz;
1247     v1[0]=point[cp[sl][2]].px;
1248     v1[1]=point[cp[sl][2]].py;
1249     v1[2]=point[cp[sl][2]].pz;
1250     v2[0]=point[cp[sl][3]].px;
1251     v2[1]=point[cp[sl][3]].py;
1252     v2[2]=point[cp[sl][3]].pz;
1253     fi+=angleSurfBody( v0, v1, v2, scg, bcg );
1254     /* plus zweitem winkel da eine seite concav sein koennte */
1255     v0[0]=point[cp[sl][2]].px;
1256     v0[1]=point[cp[sl][2]].py;
1257     v0[2]=point[cp[sl][2]].pz;
1258     v1[0]=point[cp[sl][3]].px;
1259     v1[1]=point[cp[sl][3]].py;
1260     v1[2]=point[cp[sl][3]].pz;
1261     v2[0]=point[cp[sl][0]].px;
1262     v2[1]=point[cp[sl][0]].py;
1263     v2[2]=point[cp[sl][0]].pz;
1264     fi+=angleSurfBody( v0, v1, v2, scg, bcg );
1265     /* plus zweitem winkel da eine seite concav sein koennte */
1266     v0[0]=point[cp[sl][3]].px;
1267     v0[1]=point[cp[sl][3]].py;
1268     v0[2]=point[cp[sl][3]].pz;
1269     v1[0]=point[cp[sl][0]].px;
1270     v1[1]=point[cp[sl][0]].py;
1271     v1[2]=point[cp[sl][0]].pz;
1272     v2[0]=point[cp[sl][1]].px;
1273     v2[1]=point[cp[sl][1]].py;
1274     v2[2]=point[cp[sl][1]].pz;
1275     fi+=angleSurfBody( v0, v1, v2, scg, bcg );
1276     if(surfOri[i])
1277     {
1278       if(fi>0.) cl-- ;
1279       else      cl++ ;
1280     }
1281     else
1282     {
1283       if(fi>0.) cl++ ;
1284       else      cl-- ;
1285     }
1286 #if TEST
1287     printf(" ori:%d cl:%d fi:%lf\n",surfOri[i],cl,fi);
1288 #endif
1289   }
1290 
1291 
1292   /* wenn cl<0: vertauschen von surf3 mit surf5 und invertieren aller surfOri  */
1293   if(cl<0)
1294   {
1295     cl1=surfOri[3];
1296     surfOri[3]=surfOri[5];
1297     surfOri[5]=cl1;
1298     cl1=surfIndex[3];
1299     surfIndex[3]=surfIndex[5];
1300     surfIndex[5]=cl1;
1301   }
1302 
1303   /* define the body-structure */
1304   for (i=0; i<body[nr].ns; i++)
1305   {
1306     body[nr].s[i]=surfIndex[i];
1307     if((cl>=0)&&(surfOri[i])) body[nr].o[i]='+';
1308     else if((cl<0)&&(surfOri[i])) body[nr].o[i]='-';
1309     else if((cl>=0)&&(!surfOri[i])) body[nr].o[i]='-';
1310     else if((cl<0)&&(!surfOri[i])) body[nr].o[i]='+';
1311     /* if(surf[ body[nr].s[i] ].name[3]=='4') body[nr].o[i]='-'; */
1312     if(printFlag) printf (" %1c %s", body[nr].o[i], surf[ body[nr].s[i] ].name );
1313   }
1314   if(printFlag) printf("\n");
1315   return(1);
1316 }
1317 
1318 
1319 /* ordnet die Flaechen eines Bodies endsprechend der Topologiedefinition */
1320 /* in: */
1321 /*   nr                                   body-index */
1322 /*   cp[SURFS_PER_BODY][EDGES_PER_SURF];  corner points der surfs */
1323 /* out:   */
1324 /*   return 1 if successfull or -1 if not */
ori5SidedBody(int nr,int ** cp)1325 int ori5SidedBody( int nr, int **cp )
1326 {
1327   int i,j,k;
1328   int   s, p0=0, p1=0, sl=0, cl, cl1, p0_s4;
1329   int   surfIndex[5];           /* index einer surf, Topologieabh. gespeichert */
1330   int   body_ns[5];             /* speichert die pos innerhalb der body definition */
1331   char  surfOri[5];    /* orientierung  */
1332   double scg[3], bcg[3];
1333   double v0[3], v1[3], v2[3];
1334   double fi;
1335 
1336   /* surfs: surf-order im surf-kreuz: 0 m, 1 g, 2 r, 3 l, 4 u */
1337   /* startsurf ist 0, 4 haengt an v01, 2 an v12, 3 an v20 , 1 bleibt uebrig */
1338   /* v01 ist der Vektor von cp[][0] nach cp[][1]  */
1339 
1340   /* zuerst wird die orientierung der ersten surf willkuerlich auf + gesetzt. */
1341   /* alle anderen werden relativ zur ersten orientiert. wenn die reihenfolge dann feststeht */
1342   /* erfolgt eine berechnung der orientierungen der surfs, so das die meisten aus dem body zeigen. */
1343   /* dazu wird der winkel zwischen surf-normalenvektor und surfCG-bodyCG-Vektor berechnet */
1344 
1345   /* suche eine geeignete bez.surf (0), es muss eine 3-seitige sein. */
1346   for (i=0; i<body[nr].ns; i++)
1347   {
1348     if (surf[body[nr].s[i]].nl==3)
1349     {
1350       sl=i;            /* nr der bezugs surface im body-raum (0-4) */
1351       goto sfound;
1352     }
1353   }
1354   sfound:;
1355 
1356   k=0;
1357 #if TEST
1358       errMsg (" in orientBody, side %d sl:%d ori always:1 surf:%s \n",
1359       k, sl, surf[body[nr].s[sl]].name);
1360 #endif
1361   s=body[nr].s[sl];
1362   surfIndex[k]=s;
1363   body_ns[k]=sl;
1364   surfOri[k]=1;
1365 
1366 
1367   k=2;  /* laufende nr der zu bestimmenden surf */
1368   for (i=0; i<body[nr].ns; i++)
1369   {
1370     s=body[nr].s[i];
1371     p0=p1=-1;
1372     if(i!=sl)
1373     {
1374       for (j=0; j<surf[s].nl; j++)
1375       {
1376         if( cp[i][j]==cp[sl][1] ) p0=j;
1377         if( cp[i][j]==cp[sl][2] ) p1=j;
1378       }
1379       if ((p0>-1)&&(p1>-1)) break;
1380     }
1381   }
1382   if (i>=body[nr].ns)
1383   { errMsg (" ERROR in orientBody, side %d from body:%s could not be located \n",
1384       k, body[nr].name); return(-1);
1385   }
1386 #if TEST
1387       errMsg (" in orientBody, side %d  surf:%s \n",
1388       k, surf[s].name);
1389 #endif
1390   surfIndex[k]=s;
1391   body_ns[k]=i;
1392   /* surfori relativ zur surf0 */
1393   if((p0==3)&&(p1==0)) p1=4;
1394   else if((p1==3)&&(p0==0)) p0=4;
1395   if(p0<p1) surfOri[k]=0 ;
1396   else      surfOri[k]=1 ;
1397 
1398 
1399   k=3;  /* laufende nr der zu bestimmenden surf */
1400   for (i=0; i<body[nr].ns; i++)
1401   {
1402     if(i!=sl)
1403     {
1404       s=body[nr].s[i];
1405       p0=p1=-1;
1406       for (j=0; j<surf[s].nl; j++)
1407       {
1408         if( cp[i][j]==cp[sl][2] ) p0=j;
1409         if( cp[i][j]==cp[sl][0] ) p1=j;
1410       }
1411       if ((p0>-1)&&(p1>-1)) break;
1412     }
1413   }
1414   if (i>=body[nr].ns)
1415   { errMsg (" ERROR in orientBody, side %d from body:%s could not be located \n",
1416       k, body[nr].name); return(-1);
1417   }
1418 #if TEST
1419       errMsg (" in orientBody, side %d  surf:%s \n",
1420       k, surf[s].name);
1421 #endif
1422   surfIndex[k]=s;
1423   body_ns[k]=i;
1424   if((p0==3)&&(p1==0)) p1=4;
1425   else if((p1==3)&&(p0==0)) p0=4;
1426   if(p0<p1) surfOri[k]=0 ;
1427   else      surfOri[k]=1 ;
1428 
1429 
1430   k=4;  /* laufende nr der zu bestimmenden surf    */
1431   for (i=0; i<body[nr].ns; i++)
1432   {
1433     s=body[nr].s[i];
1434     p0=p1=-1;
1435     if(i!=sl)
1436     {
1437       for (j=0; j<surf[s].nl; j++)
1438       {
1439         if( cp[i][j]==cp[sl][0] ) p0=j;
1440         if( cp[i][j]==cp[sl][1] ) p1=j;
1441       }
1442       if ((p0>-1)&&(p1>-1)) break;
1443     }
1444   }
1445   if (i>=body[nr].ns)
1446   { errMsg (" ERROR in orientBody, side %d from body:%s could not be located \n",
1447       k, body[nr].name); return(-1);
1448   }
1449 #if TEST
1450       errMsg (" in orientBody, side %d  surf:%s \n",
1451       k, surf[s].name);
1452 #endif
1453   surfIndex[k]=s;
1454   body_ns[k]=i;
1455   p0_s4=p0;
1456   if((p0==3)&&(p1==0)) p1=4;
1457   else if((p1==3)&&(p0==0)) p0=4;
1458   if(p0<p1) surfOri[k]=0 ;
1459   else      surfOri[k]=1 ;
1460 
1461 
1462   k=1;  /* laufende nr der zu bestimmenden surf                            */
1463   surfIndex[k]=-1;
1464   /* suche die noch nicht zugewiesene surf */
1465   for (i=0; i<body[nr].ns; i++)
1466   {
1467     cl=0;
1468     s=body[nr].s[i];
1469     for (j=0; j<body[nr].ns; j++) { if(surfIndex[j]==s) cl=1; }
1470     if(!cl) break;
1471   }
1472 #if TEST
1473       errMsg (" in orientBody, side %d  surf:%s \n",
1474       k, surf[s].name);
1475 #endif
1476   surfIndex[k]=s;
1477   body_ns[k]=i;
1478 
1479   /* bestimme die orientierung mit hilfe der seite nr.4 */
1480   /* wenn der drehsinn der surf mit surf 4 uebereinstimmt wird die ori von 4 uebernommen */
1481   /* dafuer muessen die anschlusspunkte gefunden werden. p0 und p1 sind von surf 4 bekannt, */
1482   /* die gegenueberliegenden werden gesucht */
1483   if (surfOri[4]==surfOri[0])
1484   {
1485     cl=p0_s4+1;
1486     if (cl>=surf[surfIndex[4]].nl) cl=0;
1487     cl1=cl+1;
1488     if (cl1>=surf[surfIndex[4]].nl) cl1=0;
1489   }
1490   else
1491   {
1492     cl=p0_s4+2;
1493     if (cl>=surf[surfIndex[4]].nl) cl-=surf[surfIndex[4]].nl;
1494     cl1=cl+1;
1495     if (cl1>=surf[surfIndex[4]].nl) cl1-=surf[surfIndex[4]].nl;
1496   }
1497 
1498   /* suche die anschlusspunkte zu surf 1 */
1499   p0=p1=-1;
1500   for (j=0; j<surf[s].nl; j++)
1501   {
1502     if( cp[i][j]==cp[body_ns[4]][cl] ) p0=j;
1503     if( cp[i][j]==cp[body_ns[4]][cl1] ) p1=j;
1504   }
1505   if((p0==3)&&(p1==0)) p1=4;
1506   else if((p1==3)&&(p0==0)) p0=4;
1507   /* wenn die surf die gleiche drehrichtung hat wie surf4: */
1508   if (p0>p1) surfOri[1]=surfOri[4];
1509   else if(surfOri[4]==1) surfOri[1]=0;
1510   else surfOri[1]=1;
1511 
1512 
1513   /* die orientierungen aller surfs werden nun mit hilfe des schwerpunktes des bodies ueberprueft */
1514   /* wenn die mehrzahl der surfnormalen aus dem body zeigt, ist alles ok, sonst invertieren */
1515   bcg[0]=(body[nr].cx-scale->x)/scale->w;
1516   bcg[1]=(body[nr].cy-scale->y)/scale->w;
1517   bcg[2]=(body[nr].cz-scale->z)/scale->w;
1518   cl=0;
1519   for (i=0; i<body[nr].ns; i++)
1520   {
1521     s = surfIndex[i];
1522     sl= body_ns[i];
1523     /*
1524     scg[0]=surf[s].cx;
1525     scg[1]=surf[s].cy;
1526     scg[2]=surf[s].cz;
1527     bcg[0]=body[nr].cx;
1528     bcg[1]=body[nr].cy;
1529     bcg[2]=body[nr].cz;
1530     */
1531     scg[0]=(surf[s].cx-scale->x)/scale->w;
1532     scg[1]=(surf[s].cy-scale->y)/scale->w;
1533     scg[2]=(surf[s].cz-scale->z)/scale->w;
1534     v0[0]=point[cp[sl][0]].px;
1535     v0[1]=point[cp[sl][0]].py;
1536     v0[2]=point[cp[sl][0]].pz;
1537     v1[0]=point[cp[sl][1]].px;
1538     v1[1]=point[cp[sl][1]].py;
1539     v1[2]=point[cp[sl][1]].pz;
1540     v2[0]=point[cp[sl][2]].px;
1541     v2[1]=point[cp[sl][2]].py;
1542     v2[2]=point[cp[sl][2]].pz;
1543     fi=angleSurfBody( v0, v1, v2, scg, bcg );
1544     if(surfOri[i])
1545     {
1546       if(fi>0.) cl-- ;
1547       else      cl++ ;
1548     }
1549     else
1550     {
1551       if(fi>0.) cl++ ;
1552       else      cl-- ;
1553     }
1554   }
1555 
1556   /* wenn cl<0: vertauschen von surf3 mit surf2 und invertieren aller surfOri  */
1557   if(cl<0)
1558   {
1559     cl1=surfOri[3];
1560     surfOri[3]=surfOri[2];
1561     surfOri[2]=cl1;
1562     cl1=surfIndex[3];
1563     surfIndex[3]=surfIndex[2];
1564     surfIndex[2]=cl1;
1565   }
1566 
1567   /* define the body-structure */
1568   for (i=0; i<body[nr].ns; i++)
1569   {
1570     body[nr].s[i]=surfIndex[i];
1571     if((cl>0)&&(surfOri[i])) body[nr].o[i]='+';
1572     else if((cl<0)&&(surfOri[i])) body[nr].o[i]='-';
1573     else if((cl>0)&&(!surfOri[i])) body[nr].o[i]='-';
1574     else if((cl<0)&&(!surfOri[i])) body[nr].o[i]='+';
1575     if(printFlag) printf (" %1c %s", body[nr].o[i], surf[ body[nr].s[i] ].name );
1576   }
1577   if(printFlag) printf("\n");
1578   return(1);
1579 }
1580 
1581 
1582 /* based on oriAllSurfs() */
oriTetBody(int nr,int ** cp)1583 int oriTetBody( int nr, int **cp )
1584 {
1585   int i,j,k,n,l,ll,lll,cl,s,sb, prod1, prod2,oriflag,counter=0,surl,sur, sl=0, p1,p2;
1586   int **ltos, *sori=NULL;
1587   int *surfOriBuffer=NULL;
1588   double scg[3], bcg[3];
1589   double v0[3], v1[3], v2[3];
1590   double fi, dist;
1591   int dist_count=0;
1592   double *max_dist=NULL;
1593   int *i_ind=NULL;
1594 
1595   /* go over all surfs of that body*/
1596   /* check if one neighbour surf is oriented */
1597   /* then orient the surf */
1598 
1599   /* first go over all lines and determine all related surfs (should be 2) */
1600   /* store the surfs in an array which points then to the surf */
1601   /*  this will be set to -1 if the surf is oriented */
1602   /*  if all surfs are oriented this array contains only -1 */
1603   /* relate all surfs to its lines */
1604   if( (ltos=(int **)malloc((anzGeo->l+1)*sizeof(int *) ) )==NULL)
1605   printf("ERROR malloc failed in oriAllSurfs()\n");
1606   for(i=0; i<anzGeo->l; i++)
1607   {
1608     if( (ltos[i]=(int *)malloc((3)*sizeof(int) ) )==NULL)
1609     printf("ERROR malloc failed in oriAllSurfs()\n");
1610      ltos[i][0]=0; for(j=1;j<3;j++) ltos[i][j]=-1;
1611   }
1612 
1613   if( (surfOriBuffer=(int *)malloc((body[nr].ns)*sizeof(int) ) )==NULL)
1614   printf("ERROR malloc failed in oriAllSurfs()\n");
1615 
1616   for(sb=0; sb<body[nr].ns; sb++)
1617   {
1618     body[nr].o[sb]='+';
1619     s=body[nr].s[sb];
1620     surfOriBuffer[sb]=surf[s].ori;
1621     if(surf[s].name!=NULL) for(j=0; j<surf[s].nl; j++)
1622     {
1623       if(surf[s].typ[j]=='l')
1624       {
1625         n=++ltos[surf[s].l[j]][0];
1626         if(n>2)
1627         {
1628           printf("ERROR: to many related surfs(%d) for line:%s\n", n, line[surf[s].l[j]].name);
1629           printf("No inner surfaces are permitted. Command could not be executed\n");
1630           goto orientTetBodyError;
1631         }
1632         ltos[surf[s].l[j]][n]=s;
1633       }
1634       else
1635       {
1636         cl=surf[s].l[j];
1637         for(l=0; l<lcmb[cl].nl; l++)
1638 	{
1639           n=++ltos[lcmb[cl].l[l]][0];
1640           if(n>2)
1641           {
1642             printf("ERROR: to many related surfs(%d) for line:%s\n", n, line[lcmb[cl].l[l]].name);
1643             printf("No inner surfaces are permitted. Command could not be executed\n");
1644             goto orientTetBodyError;
1645           }
1646           ltos[lcmb[cl].l[l]][n]=s;
1647 	}
1648       }
1649     }
1650   }
1651   /*
1652   for(i=0; i<anzGeo->l; i++) if(ltos[i][0])
1653   {
1654     printf("l:%s ", line[i].name);
1655     if(ltos[i][1]>-1) printf("surf:%s ", surf[ltos[i][1]].name);
1656     if(ltos[i][2]>-1) printf("surf:%s ", surf[ltos[i][2]].name);
1657     printf("\n ");
1658   }
1659   */
1660 
1661   /* create a link between surf-index and surface */
1662   /* the surf-index is "-" as long a surf is not oriented */
1663   if( (sori=(int *)malloc((anzGeo->s+1)*sizeof(int) ) )==NULL)
1664     printf("ERROR malloc failed in oriAllSurfs()\n");
1665   for(i=0; i<anzGeo->s; i++) sori[i]=0;
1666 
1667   /* assume the start-surface is already correct oriented (will be checked later) */
1668   sur=body[nr].s[0];
1669   sori[sur]=1;
1670 
1671   /* go over all surfs and look if one has an oriented neighbour */
1672  more:;
1673   oriflag=0;
1674   for(sb=1; sb<body[nr].ns; sb++)
1675   {
1676     s=body[nr].s[sb];
1677 
1678     /* if the surf is valid and not oriented go over all its lines */
1679     if((surf[s].name!=NULL)&&(sori[s]==0)) for(j=0; j<surf[s].nl; j++)
1680     {
1681       oriflag=1;
1682       if(surf[s].typ[j]=='l')
1683       {
1684         /* check the connected surfs based on the common lines if it is an oriented one */
1685         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))
1686 	{
1687 	  sur=ltos[surf[s].l[j]][n];
1688           surl= surf[s].l[j];
1689           //printf("surf:%s line:%s oriented surf:%s\n", surf[s].name, line[surl].name, surf[sur].name);
1690 
1691           /* check if the surf must be inverted */
1692           /* based on the product of orientations of the oriented surf */
1693           /* determine the index of the connected line in sur */
1694           if(surf[sur].ori=='+') prod1=1; else prod1=-1;
1695           for(ll=0; ll<surf[sur].nl; ll++)
1696 	  {
1697             if(surf[sur].typ[ll]=='l')
1698             {
1699 	      if(surl==surf[sur].l[ll])
1700               {
1701                 if(surf[sur].o[ll]=='+') prod1*=1; else prod1*=-1;
1702                 goto found1;
1703               }
1704 	    }
1705 	    else
1706             {
1707               for(lll=0; lll<lcmb[surf[sur].l[ll]].nl; lll++) if(surl==lcmb[surf[sur].l[ll]].l[lll])
1708               {
1709                 if(surf[sur].o[ll]=='+') prod1*=1; else prod1*=-1;
1710                 if(lcmb[surf[sur].l[ll]].o[lll]=='+') prod1*=1; else prod1*=-1;
1711                 goto found1;
1712 	      }
1713 	    }
1714 	  }
1715 	found1:;
1716 
1717           /* product of orientations of the actual surf */
1718           if(surf[s].ori=='+') prod2=1; else prod2=-1;
1719           if(surf[s].o[j]=='+') prod2*=1; else prod2*=-1;
1720 
1721           sori[s]=1;
1722           if(prod2==prod1)
1723 	  {
1724             if (surf[s].ori=='-') surf[s].ori='+';
1725             else                  surf[s].ori='-';
1726             body[nr].o[sb]='-';
1727 	  }
1728           goto new_surf;
1729 	}
1730       }
1731       else
1732       {
1733         cl=surf[s].l[j];
1734         for(l=0; l<lcmb[cl].nl; l++)
1735 	{
1736           /* check the connected surfs based on the common lines if it is an oriented one */
1737           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))
1738 	  {
1739 	    sur=ltos[lcmb[cl].l[l]][n];
1740             //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);
1741             surl= lcmb[cl].l[l];
1742 
1743             /* check if the surf must be inverted */
1744             /* based on the product of orientations of the oriented surf */
1745             /* determine the index of the connected line in sur */
1746             if(surf[sur].ori=='+') prod1=1; else prod1=-1;
1747             for(ll=0; ll<surf[sur].nl; ll++)
1748             {
1749               if(surf[sur].typ[ll]=='l')
1750               {
1751 		if(surl==surf[sur].l[ll])
1752                 {
1753                   if(surf[sur].o[ll]=='+') prod1*=1; else prod1*=-1;
1754                   goto found2;
1755                 }
1756    	      }
1757    	      else
1758               {
1759                 for(lll=0; lll<lcmb[surf[sur].l[ll]].nl; lll++)
1760                 if(surl==lcmb[surf[sur].l[ll]].l[lll])
1761                 {
1762                   if(surf[sur].o[ll]=='+') prod1*=1; else prod1*=-1;
1763                   if(lcmb[surf[sur].l[ll]].o[lll]=='+') prod1*=1; else prod1*=-1;
1764                   goto found2;
1765    	        }
1766    	      }
1767 	    }
1768 	   found2:;
1769 
1770             /* product of orientations of the actual surf */
1771             if(surf[s].ori=='+') prod2=1; else prod2=-1;
1772             if(surf[s].o[j]=='+') prod2*=1; else prod2*=-1;
1773             if(lcmb[cl].o[l]=='+') prod2*=1; else prod2*=-1;
1774 
1775             sori[s]=1;
1776             if(prod2==prod1)
1777 	    {
1778               if (surf[s].ori=='-') surf[s].ori='+';
1779               else                  surf[s].ori='-';
1780               body[nr].o[sb]='-';
1781 	    }
1782             goto new_surf;
1783 	  }
1784 	}
1785       }
1786     }
1787     new_surf:;
1788   }
1789   if(oriflag)
1790   {
1791     counter++;
1792     if(counter<body[nr].ns) goto more;
1793     else { printf(" WARNING: too much loops. Some surfs might be still unoriented.\n"); goto orientTetBodyError; }
1794   }
1795 
1796   /* die orientierungen aller surfs werden nun mit hilfe des schwerpunktes des bodies ueberprueft */
1797   bcg[0]=(body[nr].cx-scale->x)/scale->w;
1798   bcg[1]=(body[nr].cy-scale->y)/scale->w;
1799   bcg[2]=(body[nr].cz-scale->z)/scale->w;
1800 
1801   /* suche den vom CG entferntesten Punkt und die daran h�ngenden surfaces */
1802   if( (i_ind=(int *)realloc((int *)i_ind, (1)*sizeof(int) ) )==NULL)
1803     printf("ERROR malloc failed in oriTetBody()\n");
1804   if( (max_dist=(double *)realloc((double *)max_dist, (1)*sizeof(double) ) )==NULL)
1805     printf("ERROR malloc failed in oriTetBody()\n");
1806   max_dist[0]=-1.;
1807   for (i=0; i<body[nr].ns; i++)
1808   {
1809     s = body[nr].s[i];
1810     surf[s].ori=surfOriBuffer[i];
1811     for (j=0; j<surf[s].nl; j++)
1812     {
1813       v0[0]=point[cp[i][j]].px;
1814       v0[1]=point[cp[i][j]].py;
1815       v0[2]=point[cp[i][j]].pz;
1816       for(k=0; k<3; k++) v1[k]=v0[k]-bcg[k];
1817       dist=v_betrag(v1);
1818       if(dist>max_dist[0]) { max_dist[0]=dist; i_ind[0]=i; dist_count=1; }
1819       else if(dist==max_dist[0])
1820       {
1821         if( (i_ind=(int *)realloc((int *)i_ind, (dist_count+1)*sizeof(int) ) )==NULL)
1822           printf("ERROR malloc failed in oriTetBody()\n");
1823        if( (max_dist=(double *)realloc((double *)max_dist, (dist_count+1)*sizeof(double) ) )==NULL)
1824          printf("ERROR malloc failed in oriTetBody()\n");
1825         max_dist[dist_count]=dist; i_ind[dist_count]=i; dist_count++;
1826       }
1827     }
1828   }
1829 
1830   /* wenn die mehrzahl der surfnormalen aus dem body zeigt, ist alles ok, sonst invertieren */
1831   cl=0;
1832   //for (i=0; i<body[nr].ns; i++)
1833   for (i=0; i<dist_count; i++)
1834   {
1835     //s = body[nr].s[i];
1836     s = body[nr].s[i_ind[i]];
1837    if(surf[s].nl<3) continue;
1838      //sl= i;
1839     sl= i_ind[i];
1840     //printf("dist_count:%d s:%s\n", dist_count, surf[s].name);
1841     if(surf[s].nc==0) { p2=surf[s].nl-1; p1=p2/2; }
1842     else { p2=surf[s].c[0]-1; p1=p2/2; }
1843     scg[0]=(surf[s].cx-scale->x)/scale->w;
1844     scg[1]=(surf[s].cy-scale->y)/scale->w;
1845     scg[2]=(surf[s].cz-scale->z)/scale->w;
1846     v0[0]=point[cp[sl][0]].px;
1847     v0[1]=point[cp[sl][0]].py;
1848     v0[2]=point[cp[sl][0]].pz;
1849     v1[0]=point[cp[sl][p1]].px;
1850     v1[1]=point[cp[sl][p1]].py;
1851     v1[2]=point[cp[sl][p1]].pz;
1852     v2[0]=point[cp[sl][p2]].px;
1853     v2[1]=point[cp[sl][p2]].py;
1854     v2[2]=point[cp[sl][p2]].pz;
1855     fi=angleSurfBody( v0, v1, v2, scg, bcg );
1856     //printf("cl:%d scg[0]:%f bcg[0]:%f v0[0]:%f v1[0]:%f v2[0]:%f fi %f, %s b:%c s:%c\n", cl,scg[0], bcg[0], v0[0], v1[0], v2[0], fi, surf[s].name, body[nr].o[i_ind[i]], surf[s].ori);
1857     if(body[nr].o[i_ind[i]]=='-') fi*=-1;
1858     if(surf[s].ori=='-') fi*=-1;
1859     if(fi>0.) cl++ ;
1860     else      cl-- ;
1861     //printf("cl:%d scg[0]:%f bcg[0]:%f v0[0]:%f v1[0]:%f v2[0]:%f fi %f\n", cl,scg[0], bcg[0], v0[0], v1[0], v2[0], fi);
1862   }
1863   free(surfOriBuffer);
1864 
1865   /* wenn cl>0: invertieren aller surfOri  */
1866   if(cl>0)
1867   {
1868     for(sb=0; sb<body[nr].ns; sb++)
1869     {
1870       if(body[nr].o[sb]=='-') body[nr].o[sb]='+';
1871       else body[nr].o[sb]='-';
1872     }
1873   }
1874 
1875   /* define the body-structure */
1876   for (i=0; i<body[nr].ns; i++)
1877   {
1878     if(printFlag) printf (" %1c %s", body[nr].o[i], surf[ body[nr].s[i] ].name );
1879   }
1880   if(printFlag) printf("\n");
1881 
1882   for(i=0; i<anzGeo->l; i++) free(ltos[i]);
1883   free(ltos);
1884   free(sori);
1885   free(max_dist);
1886   free(i_ind);
1887   return(1);
1888  orientTetBodyError:;
1889   for(i=0; i<anzGeo->l; i++) free(ltos[i]);
1890   free(ltos);
1891   free(sori);
1892   free(max_dist);
1893   free(i_ind);
1894   return(-1);
1895 }
1896 
1897 
1898 
orientBody(int nr)1899 int orientBody( int nr )
1900 {
1901   int i,j=0,n;
1902   int   s, sl, cl, err=0;
1903   int   **cp;                  /* corner points of the surfs */
1904 
1905   if( (cp=(int **)malloc( (body[nr].ns)*sizeof(int *) ) )==NULL)
1906   { printf(" ERROR: malloc failure in orientBody()\n"); return(-1); }
1907   for(i=0; i<body[nr].ns; i++)
1908   {
1909     if( (cp[i]=(int *)malloc(surf[body[nr].s[i]].nl*sizeof(int) ) )==NULL)
1910     { printf(" ERROR: malloc failure in orientBody()\n"); return(-1); }
1911   }
1912 
1913   if(printFlag) printf (" orient body:%s \n", body[nr].name);
1914 
1915   /* suche die Eckknoten der surfaces */
1916   /* beruecksichtige dabei die orientierung der linien oder lcmbs */
1917   /* so das die punktefolge der linienfolge entspricht */
1918   for (i=0; i<body[nr].ns; i++)
1919   {
1920     s=body[nr].s[i];
1921 
1922     /* suche den ersten punkt der ersten linie oder lcmb der surf */
1923     if(surf[s].nl<1)
1924     { printf(" ERROR: failure in orientBody()\n"); return(-1); }
1925     sl=surf[s].l[0];
1926     if (surf[s].typ[0]=='c')
1927     {
1928       cl=lcmb[sl].nl-1;
1929       if (surf[s].o[0]=='-')
1930       {
1931         if(lcmb[sl].o[cl]=='+') cp[i][0]=line[lcmb[sl].l[cl]].p2;
1932         else                    cp[i][0]=line[lcmb[sl].l[cl]].p1;
1933       }
1934       else
1935       {
1936         if(lcmb[sl].o[0]=='+')  cp[i][0]=line[lcmb[sl].l[0]].p1;
1937         else                    cp[i][0]=line[lcmb[sl].l[0]].p2;
1938       }
1939     }
1940     else if (surf[s].typ[0]=='l')
1941     {
1942       if (surf[s].o[0]=='-')
1943       {
1944         cp[i][0]=line[surf[s].l[0]].p2;
1945       }
1946       else
1947       {
1948         cp[i][0]=line[surf[s].l[0]].p1;
1949       }
1950     }
1951     else { errMsg (" ERROR in orientBody, surf.typ:%1c not known\n", surf[s].typ[j]); exit(-1);}
1952 
1953     /* suche den anfangspunkt aller weiteren linien oder lcmbs der surf */
1954     for (j=1; j<surf[s].nl; j++)
1955     {
1956       sl=surf[s].l[j];
1957       if (surf[s].typ[j]=='c')
1958       {
1959         cl=lcmb[sl].nl-1;
1960         if (surf[s].o[j]=='-')
1961         {
1962           if(lcmb[sl].o[cl]=='+') cp[i][j]=line[lcmb[sl].l[cl]].p2;
1963           else                    cp[i][j]=line[lcmb[sl].l[cl]].p1;
1964         }
1965         else
1966         {
1967           if(lcmb[sl].o[0]=='+')  cp[i][j]=line[lcmb[sl].l[0]].p1;
1968           else                    cp[i][j]=line[lcmb[sl].l[0]].p2;
1969         }
1970       }
1971       else if (surf[s].typ[j]=='l')
1972       {
1973         if (surf[s].o[j]=='-')
1974         {
1975           cp[i][j]=line[surf[s].l[j]].p2;
1976         }
1977         else
1978         {
1979           cp[i][j]=line[surf[s].l[j]].p1;
1980         }
1981       }
1982       else { errMsg (" ERROR in orientBody, surf.typ:%1c not known\n", surf[s].typ[j]); exit(-1);}
1983     }
1984     /*
1985     printf ("\n");
1986     printf ("s:%s ",  surf[s].name );
1987     for (j=0; j<surf[s].nl; j++)
1988     {
1989         printf (" i:%d j:%d cp %d\n", i,j, cp[i][j]);
1990         printf("%s\n", point[cp[i][j]].name);
1991     }
1992     printf ("\n");
1993     */
1994   }
1995   /* berechnung des CG, koordinaten werden descaliert gespeichert */
1996   /* sonst muesste bei jeder aenderung von scale orientSet() ablaufen */
1997   n=0;
1998   body[nr].cx=body[nr].cy=body[nr].cz=0.;
1999   for (i=0; i<body[nr].ns; i++)
2000   {
2001     s=body[nr].s[i];
2002     for (j=0; j<surf[s].nl; j++)
2003     {
2004       body[nr].cx+=point[cp[i][j]].px* scale->w+scale->x;
2005       body[nr].cy+=point[cp[i][j]].py* scale->w+scale->y;
2006       body[nr].cz+=point[cp[i][j]].pz* scale->w+scale->z;
2007       n++;
2008     }
2009   }
2010   body[nr].cx/=n;
2011   body[nr].cy/=n;
2012   body[nr].cz/=n;
2013 
2014   /* die Eckknoten aller Surfaces sind sortiert, sortiere und orientiere die surfaces */
2015   /* entsprechend den Anforderungen des Meshers */
2016 
2017   if (body[nr].ns==6)
2018   { if(ori6SidedBody( nr, cp )==-1) err=-2;}
2019   else if (body[nr].ns==5)
2020   { if(ori5SidedBody( nr, cp )==-1) err=-3;}
2021   else if (body[nr].ns==7)
2022   { if(ori7SidedBody( nr, cp )==-1) err=-4;}
2023   else if ((body[nr].etyp==3)||(body[nr].etyp==6))
2024   { if(oriTetBody( nr, cp )==-1) err=-1;}
2025   else err=0;
2026 
2027 
2028   for(i=0; i<body[nr].ns; i++) free(cp[i]);
2029   free(cp);
2030   return(err);
2031 }
2032 
2033 
orientSet(char * record)2034 void orientSet( char *record)
2035 {
2036   int   setNr, flag;
2037   int i,j=0;
2038   char setname[MAX_LINE_LENGTH];
2039 
2040   sword( record, setname );
2041   operateAlias( setname, "se" );
2042   setNr=getSetNr(setname);
2043 
2044   if (setNr<0)
2045   {
2046     printf (" ERROR: set:%s does not exist\n", setname);
2047     return;
2048   }
2049 
2050   delSet(specialset->uori);
2051 
2052   for (i=0; i<set[setNr].anz_c; i++)
2053   {
2054    if(lcmb[set[setNr].lcmb[i]].name !=(char *)NULL)
2055    {
2056     if(printFlag) printf (" orient lcmb:%s from setname:%s \n", lcmb[set[setNr].lcmb[i]].name, set[setNr].name);
2057     flag=orientLcmb( set[setNr].lcmb[i] );
2058     if (flag<0)
2059     {
2060       errMsg(" ERROR: Orientation of lcmb:%s failed\n", lcmb[set[setNr].lcmb[i]].name);
2061       pre_seta( specialset->uori, "c", lcmb[set[setNr].lcmb[i]].name );
2062       j++;
2063     }
2064    }
2065   }
2066   for (i=0; i<set[setNr].anz_s; i++)
2067   {
2068    if(surf[set[setNr].surf[i]].name !=(char *)NULL)
2069    {
2070     if(printFlag) printf (" orient surf:%s from setname:%s \n", surf[set[setNr].surf[i]].name, set[setNr].name);
2071     flag=orientSurf( set[setNr].surf[i] );
2072     if (flag<0)
2073     {
2074       surf[set[setNr].surf[i]].o[0]=0;
2075       errMsg(" ERROR: Orientation of surf:%s failed\n", surf[set[setNr].surf[i]].name);
2076       pre_seta( specialset->uori, "s", surf[set[setNr].surf[i]].name );
2077       j++;
2078     }
2079    }
2080   }
2081   for (i=0; i<set[setNr].anz_b; i++)
2082   {
2083    if(body[set[setNr].body[i]].name !=(char *)NULL)
2084    {
2085     if(printFlag) printf (" orient body:%s from setname:%s \n", body[set[setNr].body[i]].name, set[setNr].name);
2086     flag=orientBody( set[setNr].body[i] );
2087     if (flag<0)
2088     {
2089       errMsg(" ERROR: Orientation of body:%s failed\n", body[set[setNr].body[i]].name);
2090       pre_seta( specialset->uori, "b", body[set[setNr].body[i]].name );
2091       j++;
2092     }
2093    }
2094   }
2095   if( j>0) printf("WARNING: %d entities are unoriented, check set:%s\n", j, specialset->uori);
2096 }
2097 
2098 
2099