1 /***********************************************************************/
2 /* Open Visualization Data Explorer                                    */
3 /* (C) Copyright IBM Corp. 1989,1999                                   */
4 /* ALL RIGHTS RESERVED                                                 */
5 /* This code licensed under the                                        */
6 /*    "IBM PUBLIC LICENSE - Open Visualization Data Explorer"          */
7 /***********************************************************************/
8 /* RPos, normals out,back faces regular, regular growth, leaks ?*/
9 
10 #include <dxconfig.h>
11 
12 
13 /*
14  * $Header: /src/master/dx/src/exec/dxmods/showboundary.c,v 1.8 2003/07/11 05:50:36 davidt Exp $
15  */
16 
17 #include <string.h>
18 #include <stdio.h>
19 #include <dx/dx.h>
20 #include "showboundary.h"
21 #include "_helper_jea.h"
22 #include "_isosurface.h"
23 
24 #define    DEFAULT_BOUND_COLOR          DXRGB ( 0.5, 0.7, 1.0 )
25 #define    PROPRIETARY_COMPONENT_NAME   "overall offsets"
26 
27 typedef struct bounds *bounds_ptr;
28 
29 typedef struct bounds
30 {
31     int  i_min, j_min, k_min;
32     int  i_max, j_max, k_max;
33     int  set;
34 }
35 bounds_rec;
36 
37 struct
38 {
39     int  have_connects;
40     int  have_nondegen;
41 }
42 global = {0, 0};
43 
44 
45 /*
46  * The following functions reside herein.
47  */
48 
49 static Field          partition_neighbors  ( Field );
50 static CompositeField irregular_neighbors  ( CompositeField );
51 static int            is_irregular_c_field ( CompositeField );
52 static Object         c_field_neighbors    ( Object );
53 static Field          show_boundary        ( Field, char *, int );
54 static Object         set_aux_offsets      ( Object, bounds_ptr, Array );
55 static Object       traverse_flatten_cf_mg ( Object );
56 
57 
58 #define I_input  in[0]
59 #define I_option in[1]
60 #define O_output out[0]
61 
m_ShowBoundary(Object * in,Object * out)62 int m_ShowBoundary ( Object *in, Object *out )
63 {
64     Object  Xtra_output = NULL;
65     int     option;
66 
67     O_output = NULL;
68 
69     if ( I_input == NULL )
70         DXErrorGoto2
71             ( ERROR_MISSING_DATA,
72               "#10000", /* %s must be specified */ "Object" )
73 #if 0
74     /*
75      * Perform this check here because DXCopy ( Array ) does nothing and
76      * DXDelete () of that leads to deleted too often...
77      */
78                 /* XXX - test After copy by uniqueness WRT I_input */
79     else if ( ( DXGetObjectClass ( I_input ) == CLASS_ARRAY  ) ||
80               ( DXGetObjectClass ( I_input ) == CLASS_STRING )   )
81         DXErrorGoto2
82             ( ERROR_BAD_CLASS,
83               "#10190",  /* %s must be a field or a group */
84               "'input'" );
85 #endif
86 
87     if ( I_option == NULL )
88         option = 0;
89     else
90         if ( !DXExtractInteger ( I_option, &option )
91              ||
92              ( option < 0 ) || ( option > 1 ) )
93             DXErrorGoto2
94                 ( ERROR_BAD_PARAMETER,
95                   "#10070", /* %s must be either 0 or 1 */
96                   "'option' parameter" );
97 
98     global.have_connects = 0;
99     global.have_nondegen = 0;
100 
101     if ( ( ERROR == ( O_output = DXCopy ( I_input, COPY_STRUCTURE ) ) )
102 
103          ||
104          /*
105           * Set irregular netghbors pass:
106           *   c_field_neighbors
107           *       c_field_neighbors (recursive)
108           *       is_irregular_c_field
109           *       irregular_neighbors
110           *           partition_neighbors
111           *               partition_neighbors (recursive)
112           */
113          ( ERROR == ( O_output = c_field_neighbors ( O_output ) ) )
114 
115          ||
116          /*
117           * Set regular offsets pass:
118           *   set_aux_offsets
119           *       set_aux_offsets (recursive)
120           */
121          !set_aux_offsets ( O_output, NULL, NULL )
122 
123          ||
124          ( ERROR == ( Xtra_output = DXProcessParts
125                                         ( O_output,
126                                           show_boundary,
127                                           (Pointer) &option,
128                                           sizeof(int),
129                                           1 /* copy     */,
130                                           0 /* preserve */ ) ) ) )
131         goto error;
132 
133 
134     DXDelete ( O_output );   O_output = Xtra_output;   Xtra_output = NULL;
135 
136 
137     if ( ERROR == ( Xtra_output = traverse_flatten_cf_mg ( O_output ) ) )
138         /* XXX - flatten CF:MG:F->MG:F to MG:CF:F */
139         goto error;
140 
141     /* XXX - very wrong looking */
142     if ( Xtra_output == O_output ) Xtra_output = NULL;
143     else
144     {
145         DXDelete ( O_output );   O_output = Xtra_output;   Xtra_output = NULL;
146     }
147 
148     if (ERROR == DXCopyAttributes(O_output, I_input))
149 	goto error;
150 
151     if ( ( global.have_connects == 1 ) && ( global.have_nondegen == 0 ) )
152          DXWarning
153              ( "#11836" /* all connections are degenerate */ );
154 
155     return OK;
156 
157     error:
158         if ( ( Xtra_output != NULL     ) &&
159              ( Xtra_output != I_input  ) &&
160              ( Xtra_output != O_output )   )
161             DXDelete ( Xtra_output );
162 
163         if ( ( O_output != NULL    ) &&
164              ( O_output != I_input )   )
165             DXDelete ( O_output );
166 
167         Xtra_output = NULL;
168         O_output    = NULL;
169 
170         DXASSERT ( DXGetError() != ERROR_NONE );
171         return ERROR;
172 }
173 
174 
175 
176 #if 0
177 /* m_Slab: There were problems with colors, etc. dep connections */
178 static
179 Field call_slab ( Field field, int d, int n, int t )
180 {
181     Object  slab_inputs  [5];
182     Object  slab_outputs [2];
183     int i;
184 
185     for(i=0;i<5;)  slab_inputs [i++] = NULL;
186     for(i=0;i<2;)  slab_outputs[i++] = NULL;
187 
188     DXASSERTGOTO ( ERROR      != field        );
189     DXASSERTGOTO ( ERROR_NONE == DXGetError() );
190 
191     if ( ( ERROR == ( slab_inputs[0] = (Object) field ) )
192          ||
193          ( ERROR == ( slab_inputs[1]
194                           = (Object) DXNewArray
195                                          ( TYPE_INT, CATEGORY_REAL, 0 ) ) ) ||
196          ( ERROR == ( slab_inputs[2]
197                           = (Object) DXNewArray
198                                          ( TYPE_INT, CATEGORY_REAL, 0 ) ) ) ||
199          ( ERROR == ( slab_inputs[3]
200                           = (Object) DXNewArray
201                                          ( TYPE_INT, CATEGORY_REAL, 0 ) ) )
202          ||
203          !DXAddArrayData ( (Array) slab_inputs[1], 0, 1, (Pointer) &d ) ||
204          !DXAddArrayData ( (Array) slab_inputs[2], 0, 1, (Pointer) &n ) ||
205          !DXAddArrayData ( (Array) slab_inputs[3], 0, 1, (Pointer) &t )
206          ||
207          !m_Slab ( slab_inputs, slab_outputs )
208          ||
209          ( ERROR == slab_outputs[0] ) || ( ERROR_NONE != DXGetError() ) )
210         goto error;
211 
212     for (i=1;i<5;slab_inputs[i++]=NULL)  DXDelete ( slab_inputs[i] );
213 
214     return slab_outputs[0];
215 
216     error:
217         for (i=1;i<5;slab_inputs [i++]=NULL)  DXDelete ( slab_inputs [i] );
218         for (i=0;i<2;slab_outputs[i++]=NULL)  DXDelete ( slab_outputs[i] );
219 
220         DXASSERT ( DXGetError() != ERROR_NONE );
221         return ERROR;
222 }
223 #endif
224 
225 
226 
227 static
set_aux_offsets(Object input,bounds_ptr read,Array write)228 Object set_aux_offsets ( Object input, bounds_ptr read, Array write )
229 {
230     int         i;
231     Object      child;
232     bounds_rec  bounds;
233     Array       conn;
234     int         dimens;
235     Array       aux_array = NULL;
236 
237     /*
238      * actions given arguments:
239      *     ( i,,  ):  traverse until composite field
240      *     ( i,r, ):  read and accumulate subordinates
241      *     ( i,,w ):  write totals to subordinates
242      */
243 
244     DXASSERTGOTO ( input != NULL );
245 
246     if ( ( read == NULL ) && ( write == NULL ) ) /*--------------------------*/
247     {
248         switch ( DXGetObjectClass ( input ) )
249         {
250             case CLASS_FIELD:
251                 break;
252 
253             case CLASS_XFORM:
254                 if ( !DXGetXformInfo  ( (Xform)input, &child, NULL ) ||
255                      !set_aux_offsets ( child, NULL, NULL ) )
256                     goto error;
257                 break;
258 
259             case CLASS_SCREEN:
260                 if ( !DXGetScreenInfo ( (Screen)input, &child, NULL, NULL ) ||
261                      !set_aux_offsets ( child, NULL, NULL ) )
262                     goto error;
263                 break;
264 
265             case CLASS_CLIPPED:
266                 if ( !DXGetClippedInfo ( (Clipped)input, &child, NULL ) ||
267                      !set_aux_offsets  ( child, NULL, NULL ) )
268                     goto error;
269                 break;
270 
271             case CLASS_GROUP:
272                 switch ( DXGetGroupClass ( (Group) input ) )
273                 {
274                     case CLASS_COMPOSITEFIELD:
275                         /* Read, then Write */
276 
277                         bounds.i_min = bounds.j_min = bounds.k_min = 0;
278                         bounds.i_max = bounds.j_max = bounds.k_max = 0;
279                         bounds.set   = 0;
280 
281                         for ( i = 0; (child=DXGetEnumeratedMember
282                                           ( (Group) input, i, NULL ));
283                               i++ )
284                             if ( !set_aux_offsets ( child, &bounds, NULL ) )
285                                 goto error;
286 
287                         if ( bounds.set == 1 )
288                         {
289                             if ( ERROR == ( aux_array = DXNewArray
290                                                            ( TYPE_INT,
291                                                              CATEGORY_REAL, 0 ))
292                                  ||
293                                  !DXAddArrayData
294                                     ( aux_array, 0, 6, (Pointer) &bounds.i_min )
295                                  ||
296                                  /* XXX */
297                                  !DXReference ( (Object) aux_array ) )
298                                 goto error;
299 
300                             for ( i = 0; (child=DXGetEnumeratedMember
301                                               ( (Group) input, i, NULL ));
302                                   i++ )
303                                 if ( !set_aux_offsets
304                                           ( child, NULL, aux_array ) )
305                                     goto error;
306                         }
307                         break;
308 
309                     default:
310                         for ( i = 0; ( child=DXGetEnumeratedMember
311                                           ( (Group) input, i, NULL ));
312                               i++ )
313                             if ( !set_aux_offsets ( child, NULL, NULL ) )
314                                 goto error;
315                 }
316                 break;
317 
318             default:
319                 DXErrorGoto2 ( ERROR_BAD_CLASS, "#10190", "'input'" );
320         }
321     }
322     else if ( read != NULL ) /*----------------------------------------------*/
323     {
324         DXASSERTGOTO ( write == NULL );
325 
326         switch ( DXGetObjectClass ( input ) )
327         {
328             case CLASS_FIELD:
329                 if ( DXEmptyField ( (Field) input ) )
330                    return input;
331 
332                 if ( ERROR == ( conn = (Array) DXGetComponentValue
333                                                    ( (Field) input,
334                                                      "connections" ) ) )
335                     DXErrorGoto2
336                         ( ERROR_DATA_INVALID, "#10240", "\"connections\"" );
337 
338                 if ( !DXQueryGridConnections ( conn, &dimens, NULL ) )
339                     return input;
340 
341                 if ( ( dimens < 1 ) || ( dimens > 3 ) )
342                     DXErrorGoto
343                         ( ERROR_NOT_IMPLEMENTED,
344                           "regular grid connections must be 1, 2, or 3D" );
345 
346                 if ( !DXQueryGridConnections ( conn, &dimens, &bounds.i_max ) )
347                     goto error;
348 
349                 switch ( dimens )
350                 {
351                     /* the max is n-1 if the min is 0 */
352 
353                     case 3:  bounds.k_max--;
354                     case 2:  bounds.j_max--;
355                     case 1:  bounds.i_max--;
356                 }
357 
358                 if ( !DXGetMeshOffsets ( (MeshArray) conn, &bounds.i_min ) )
359                 {
360                     if ( DXGetError() != ERROR_NONE ) goto error;
361                     bounds.i_min = 0;
362                     bounds.j_min = 0;
363                     bounds.k_min = 0;
364                 }
365 
366                 switch ( dimens )
367                 {
368                     case 1:  bounds.j_max = bounds.j_min = 0;
369                     case 2:  bounds.k_max = bounds.k_min = 0;
370                 }
371 
372                 bounds.i_max += bounds.i_min;
373                 bounds.j_max += bounds.j_min;
374                 bounds.k_max += bounds.k_min;
375 
376                 if ( read->i_min > bounds.i_min ) read->i_min = bounds.i_min;
377                 if ( read->j_min > bounds.j_min ) read->j_min = bounds.j_min;
378                 if ( read->k_min > bounds.k_min ) read->k_min = bounds.k_min;
379 
380                 if ( read->i_max < bounds.i_max ) read->i_max = bounds.i_max;
381                 if ( read->j_max < bounds.j_max ) read->j_max = bounds.j_max;
382                 if ( read->k_max < bounds.k_max ) read->k_max = bounds.k_max;
383 
384                 read->set = 1;
385 
386                 break;
387 
388             default:
389                 DXErrorGoto2 ( ERROR_BAD_CLASS, "#10190", "'input'" );
390         }
391     }
392     else if ( write != NULL ) /*---------------------------------------------*/
393     {
394         DXASSERTGOTO ( read == NULL );
395 
396         switch ( DXGetObjectClass ( input ) )
397         {
398             case CLASS_FIELD:
399                 if ( DXEmptyField ( (Field) input ) )
400                    return input;
401 
402                 if ( ERROR == ( conn = (Array) DXGetComponentValue
403                                                    ( (Field) input,
404                                                      "connections" ) ) )
405                     DXErrorGoto2
406                         ( ERROR_DATA_INVALID, "#10240", "\"connections\"" );
407 
408                 if ( !DXQueryGridConnections ( conn, &dimens, NULL ) )
409                     return input;
410 
411                 if ( !DXSetComponentValue
412                           ( (Field)  input,
413                             PROPRIETARY_COMPONENT_NAME,
414                             (Object) write ) )
415                     goto error;
416 
417                 break;
418 
419             default:
420                 DXErrorGoto2 ( ERROR_BAD_CLASS, "#10190", "'input'" );
421         }
422     }
423 
424     DXDelete ( (Object) aux_array );
425 
426     return input;
427 
428     error:
429         DXDelete ( (Object) aux_array );
430 
431         DXASSERT ( DXGetError() != ERROR_NONE );
432         return ERROR;
433 }
434 
435 
436 
437 static
c_field_neighbors(Object object)438 Object c_field_neighbors ( Object object )
439 {
440     Object child;
441     int    i;
442 
443     switch ( DXGetObjectClass ( object ) )
444     {
445         case CLASS_FIELD:
446             break;
447 
448         case CLASS_XFORM:
449             if ( !DXGetXformInfo    ( (Xform)object, &child, NULL ) ||
450                  !c_field_neighbors ( child ) )
451                 goto error;
452             break;
453 
454         case CLASS_SCREEN:
455             if ( !DXGetScreenInfo   ( (Screen)object, &child, NULL, NULL ) ||
456                  !c_field_neighbors ( child ) )
457                 goto error;
458             break;
459 
460         case CLASS_CLIPPED:
461             if ( !DXGetClippedInfo  ( (Clipped)object, &child, NULL ) ||
462                  !c_field_neighbors ( child ) )
463                 goto error;
464             break;
465 
466         case CLASS_GROUP:
467             switch ( DXGetGroupClass ( (Group)object ) )
468             {
469                 case CLASS_COMPOSITEFIELD:
470                     if ( is_irregular_c_field ( (CompositeField) object ) )
471                         if ( !irregular_neighbors ( (CompositeField) object ) )
472                             goto error;
473                     break;
474 
475                 default:
476                     for ( i = 0;
477                           ( NULL != ( child = DXGetEnumeratedMember
478                                                   ( (Group)object, i, NULL )) );
479                           i++ )
480                         if ( !c_field_neighbors ( child ) )
481                             goto error;
482             }
483             break;
484 
485         default:
486             DXErrorGoto2 ( ERROR_BAD_CLASS, "#10190", "'input'" );
487     }
488 
489     return object;
490 
491     error:
492         DXASSERT ( DXGetError() != ERROR_NONE );
493         return ERROR;
494 }
495 
496 
497 
498 static
irregular_neighbors(CompositeField cfield)499 CompositeField irregular_neighbors ( CompositeField cfield )
500 {
501     Object  child;
502     int     i;
503 
504     DXASSERTGOTO ( DXGetObjectClass ( (Object) cfield ) == CLASS_GROUP );
505     DXASSERTGOTO( DXGetGroupClass  ( (Group) cfield ) == CLASS_COMPOSITEFIELD );
506 
507     if ( !DXGrow ( (Object)cfield, 1, NULL, NULL ) )
508         goto error;
509 
510     for ( i = 0;
511           ( NULL != ( child = DXGetEnumeratedMember
512                                    ( (Group)cfield, i, NULL ) ) );
513           i++ )
514         if ( !partition_neighbors ( (Field)child ) )
515             goto error;
516 
517     if ( !DXShrink ( (Object)cfield ) )
518         goto error;
519 
520     return cfield;
521 
522     error:
523         DXASSERT ( DXGetError() != ERROR_NONE );
524         return ERROR;
525 }
526 
527 
528 
529 static
partition_neighbors(Field object)530 Field partition_neighbors ( Field object )
531 {
532     Array  neighbors;
533     int    i, nRefs, nNbrs, origConnections;
534     int    *refs;
535 
536     DXASSERTGOTO ( DXGetObjectClass ( (Object) object ) == CLASS_FIELD );
537 
538     /* XXX - a traverser had been here */
539 
540     if ( DXEmptyField ( object ) )
541         return object;
542 
543     /* 1D fail consideration. */
544 
545     if ( ( ERROR == ( neighbors = DXNeighbors ( object ) ) ) )
546         return ( DXGetError == ERROR_NONE ) ? object : ERROR;
547 
548     if ( ! DXQueryOriginalSizes ( object, NULL, &origConnections )
549          ||
550          ! DXGetArrayInfo ( neighbors, NULL, NULL, NULL, NULL, &nNbrs )
551          ||
552          ( ERROR == ( refs = DXGetArrayData ( neighbors ) ) ) )
553         goto error;
554 
555     /* XXX - who says that it is right to modify neighbors ? */
556 
557     nRefs = origConnections * nNbrs;
558 
559     for ( i = 0;  i < nRefs;  i++, refs++ )
560         if ( *refs >= origConnections )
561             *refs = -2;
562 
563     return object;
564 
565     error:
566         DXASSERT ( DXGetError() != ERROR_NONE );
567         return ERROR;
568 }
569 
570 
571 
572 static
is_irregular_c_field(CompositeField object)573 int is_irregular_c_field ( CompositeField object )
574 {
575     Field  field;
576     int    i;
577     Array  connections;
578     int    any_regular   = 0;
579     int    any_irregular = 0;
580 
581     DXASSERT ( DXGetObjectClass ( (Object) object ) == CLASS_GROUP );
582     DXASSERT ( DXGetGroupClass  ( (Group)  object ) == CLASS_COMPOSITEFIELD );
583 
584     for ( i = 0;
585           ( NULL != ( field = DXGetPart ( (Object)object, i ) ) );
586           i++ )
587         if ( !DXEmptyField ( field )
588              &&
589              ( NULL != ( connections
590                              = (Array)DXGetComponentValue
591                                           ( field, "connections" ) ) ) )
592         {
593             if ( DXQueryGridConnections ( connections, NULL, NULL ) )
594                 any_regular   = 1;
595             else
596                 any_irregular = 1;
597         }
598 
599     /*
600      * XXX
601      * this routine should be 3-state: Empty, Regular, Irregular
602      */
603     if ( any_irregular || !any_regular )
604         return 1;
605     else
606         return 0;
607 }
608 
609 
610 
611 static
flatten_cf_mg(Object in,MultiGrid out,int * position)612 Object flatten_cf_mg ( Object in, MultiGrid out, int *position )
613 {
614     Object child;
615     int    i;
616 
617     /* XXX - Make MG:CF:F based on orientation of planes */
618 
619     DXASSERTGOTO ( in && out && position );
620 
621     switch ( DXGetObjectClass ( in ) )
622     {
623         case CLASS_FIELD:
624             if ( !DXSetEnumeratedMember ( (Group)out, *position, in ) )
625                 goto error;
626 
627             (*position)++;
628             break;
629 
630         case CLASS_GROUP:
631             for ( i     = 0;
632                   NULL != ( child = DXGetEnumeratedMember
633                                         ( (Group)in, i, NULL ) );
634                   i++ )
635                 if ( !flatten_cf_mg ( child, out, position ) )
636                     goto error;
637             break;
638 
639         default:
640             DXErrorGoto
641                 ( ERROR_DATA_INVALID, "Illegal member in Composite Field" );
642     }
643 
644     return (Object) out;
645 
646     error:
647         DXASSERT ( DXGetError() != ERROR_NONE );
648         return ERROR;
649 }
650 
651 
652 
653 static
traverse_flatten_cf_mg(Object object)654 Object traverse_flatten_cf_mg ( Object object )
655 {
656     MultiGrid  flattened = NULL;
657     int        position  = 0;
658     int        i;
659     Object     child, new_child;
660 
661     switch ( DXGetObjectClass ( object ) )
662     {
663         case CLASS_XFORM:
664             if ( !DXGetXformInfo ( (Xform)object, &child, NULL ) ||
665                  ( ERROR == ( new_child = traverse_flatten_cf_mg ( child ) ) ) )
666                 goto error;
667             else if ( ( new_child != child ) &&
668                       !DXSetXformObject ( (Xform)object, new_child ) )
669                 goto error;
670             break;
671 
672         case CLASS_SCREEN:
673             if ( !DXGetScreenInfo   ( (Screen)object, &child, NULL, NULL )  ||
674                  ( ERROR == ( new_child = traverse_flatten_cf_mg ( child ) ) ) )
675                 goto error;
676             else if ( ( new_child != child ) &&
677                       !DXSetScreenObject ( (Screen)object, new_child ) )
678                 goto error;
679             break;
680 
681         case CLASS_CLIPPED:
682             if ( !DXGetClippedInfo    ( (Clipped)object, &child, NULL )     ||
683                  ( ERROR == ( new_child = traverse_flatten_cf_mg ( child ) ) ) )
684                 goto error;
685             else if ( ( new_child != child ) &&
686                       !DXSetClippedObjects ( (Clipped)object, new_child, NULL ))
687                 goto error;
688             break;
689 
690         case CLASS_GROUP:
691 
692             switch ( DXGetGroupClass ( (Group)object ) )
693             {
694                 /* we are looking for CF:MG:F's */
695                 case CLASS_COMPOSITEFIELD:
696                     for ( i     = 0;
697                           NULL != ( child = DXGetEnumeratedMember
698                                                 ( (Group)object, i, NULL ) );
699                           i++ )
700                         if ( ( CLASS_GROUP     == DXGetObjectClass ( child ) )&&
701                              ( CLASS_MULTIGRID == DXGetGroupClass
702                                                       ( (Group) child ) ) )
703                         {
704                             position = 0;
705 
706                             if ( ( ERROR == ( flattened = DXNewMultiGrid () ) )
707                                  ||
708                                 !flatten_cf_mg ( object, flattened, &position ))
709                                 goto error;
710 
711                             /*
712                              * Delete unnecessary unless top group,
713                              * for that see m_Showboundary().
714                              */
715                             return (Object) flattened;
716                             break;
717                         }
718                         /* else fall through */
719 
720                 default:
721                     for ( i     = 0;
722                           NULL != ( child = DXGetEnumeratedMember
723                                                 ( (Group)object, i, NULL ) );
724                           i++ )
725                         if ( ERROR == ( new_child = traverse_flatten_cf_mg
726                                                         ( child ) ) )
727                             goto error;
728                         else if ( ( new_child != child ) &&
729                                   !DXSetEnumeratedMember
730                                        ( (Group)object, i, new_child ) )
731                             goto error;
732 
733             }
734             break;
735 
736         case CLASS_FIELD:
737         default:
738             return object;
739     }
740 
741     return object;
742 
743     error:
744 #if 0
745         DXDelete ( (Object) );
746 #endif
747         DXASSERT ( DXGetError() != ERROR_NONE );
748         return ERROR;
749 }
750 
751 
752 
753 static
make_normals(Field field,int nP,int flip)754 Field make_normals ( Field field, int nP, int flip )
755 {
756     field_info  input_info;
757     array_info  p_info, c_info, n_info = NULL;
758     Array       array;
759 
760     Point         *pp;
761     Vector        n, *np;
762     Quadrilateral q, *qp;
763     Triangle         *tp;
764     float         length;
765     int           i, j;
766     PointId       t;
767 
768 #if 0
769 DXMessage ( "    make_normals: given flip = %d", flip );
770 #endif
771 
772     if ( ( flip == 0 ) || DXEmptyField ( field ) )
773         return field;
774 
775     if ( ( ERROR == ( array = DXNewArray ( TYPE_FLOAT, CATEGORY_REAL, 1, 3 ) ) )
776          ||
777          !DXAllocateArray ( array, nP )          ||
778          !DXAddArrayData  ( array, 0, nP, NULL ) ||
779          !DXTrim          ( array )
780          ||
781          !DXSetComponentValue ( field, "normals", (Object) array ) )
782         goto error;
783 
784     array = NULL;
785 
786     if ( !DXSetComponentAttribute
787              ( field, "normals", "dep", (Object)DXNewString ( "positions" ) )
788          ||
789          ( ERROR == ( input_info = _dxf_InMemory ( field ) ) )
790          ||
791          !_dxf_SetIterator ( input_info->std_comps[(int)CONNECTIONS] ) ||
792          !_dxf_SetIterator ( input_info->std_comps[(int)POSITIONS]   )  )
793         goto error;
794 
795     p_info = (array_info) &(input_info->std_comps[(int)POSITIONS]->array);
796     c_info = (array_info) &(input_info->std_comps[(int)CONNECTIONS]->array);
797     n_info = (array_info) &(input_info->std_comps[(int)NORMALS]->array);
798 
799     if ( !memset ( (char*)n_info->data, 0, (n_info->items*n_info->itemsize) ) )
800         DXErrorGoto2
801             ( ERROR_UNEXPECTED,
802               "#11800", /* C standard library call, %s, returns error */
803               "memset()" );
804 
805     np = (Point*)n_info->data;
806     pp = (Point*)p_info->data;
807 
808     switch ( input_info->std_comps[(int)CONNECTIONS]->element_type )
809     {
810         case TRIANGLES:
811             for ( i=0, tp=(Triangle*)c_info->data; i<c_info->items; i++, tp++ )
812             {
813                 if ( flip == -1 )
814                 { t = tp->p; tp->p = tp->q; tp->q = t; }
815 
816                 n = DXCross ( DXSub ( pp[tp->p], pp[tp->q] ),
817                               DXSub ( pp[tp->p], pp[tp->r] ) );
818 
819                 /* potential non-cuteness! */
820                 for ( j=0; j<9; j++ )
821                     ( (float*) & np [ ( (int*) tp ) [j/3] ] ) [j%3]
822                         += ((float*)&n)[j%3];
823             }
824             break;
825 
826         case QUADRILATERALS:
827             if ( c_info->class == CLASS_MESHARRAY ) flip = 1;
828 
829             for ( i=0; i<c_info->items; i++ )
830             {
831                 if ( flip == -1 )
832                 {
833                     qp = &(((Quadrilateral*)c_info->data)[i]);
834 
835                     t = qp->p; qp->p = qp->q; qp->q = t;
836                     t = qp->r; qp->r = qp->s; qp->s = t;
837                 }
838                 else
839                 {
840                     qp = &q;
841 
842                     if ( !c_info->get_item ( i, c_info, &q ) ) goto error;
843                 }
844 
845                 n = DXCross ( DXSub ( pp[qp->p], pp[qp->r] ),
846                               DXSub ( pp[qp->p], pp[qp->q] ) );
847 
848                 /* potential non-cuteness! */
849                 for ( j=0; j<12; j++ )
850                     ( (float*) & np [ ( (int*) qp ) [j/3] ] ) [j%3]
851                         += ((float*)&n)[j%3];
852             }
853             break;
854          default:
855 	    break;
856     }
857 
858 
859     for ( i=0, np=(Vector*)n_info->data; i<n_info->items; i++, np++ )
860     {
861         if ( ( length = DXLength ( *np ) ) != 0.0 )
862 #if 0
863         if ( ( length = -DXLength ( *np ) ) != 0.0 )
864 #endif
865         {
866             np->x /= length;
867             np->y /= length;
868             np->z /= length;
869         }
870     }
871 
872     if ( !_dxf_FreeInMemory ( input_info ) )
873         goto error;
874 
875     return field;
876 
877     error:
878         DXASSERT ( DXGetError() != ERROR_NONE );
879         return ERROR;
880 }
881 
882 
_dxf_resample_array(component_info comp,int dep_ref,int Nin,int Nout,int * push,int * pull)883 Array _dxf_resample_array
884           ( component_info comp,
885             int dep_ref,   /* 1=dep,2=ref., how comp relates to push/pull */
886             int Nin,       /* number of input items                */
887             int Nout,      /* number of output items               */
888             int *push,     /* array of (from[i:Nin] = to) indices  */
889             int *pull      /* array of (to[i:Nout] = from) indices */
890           )
891 {
892     Array   array = NULL;
893     Array   array2= NULL;
894     Pointer data  = NULL;
895     int     i, j, k;
896 
897     if ( CLASS_CONSTANTARRAY == ((array_info)&comp->array)->class )
898     {
899         /* XXX - if the data is ref, change the value, even if constant */
900 
901         if ( ERROR == ( array
902                  = (Array)DXNewConstantArrayV
903                               ( Nout,
904                                 DXGetConstantArrayData
905                                     ( ((array_info)&comp->array)->array ),
906                                 ((array_info)&comp->array)->type,
907                                 ((array_info)&comp->array)->category,
908                                 ((array_info)&comp->array)->rank,
909                                 ((array_info)&comp->array)->shape ) ) )
910             goto error;
911     }
912     else /* not CONSTANTARRAY */
913     {
914         if ( !_dxf_SetIterator ( comp )
915              ||
916              ( ERROR == ( array = DXNewArrayV
917                                      ( ((array_info)&comp->array)->type,
918                                        ((array_info)&comp->array)->category,
919                                        ((array_info)&comp->array)->rank,
920                                        ((array_info)&comp->array)->shape ) ) )
921              ||
922              !DXAllocateArray ( array, Nout )          ||
923              !DXAddArrayData  ( array, 0, Nout, NULL ) ||
924              !DXTrim          ( array )
925              ||
926              ( ERROR == ( data = DXGetArrayData ( array ) ) ) )
927             goto error;
928 
929         if ( 1 == dep_ref ) /* DEP */
930         {
931             DXASSERTGOTO ( Nin == ((array_info)&comp->array)->items );
932 
933             if ( NULL != push )
934             {
935                 /*
936                  * For each input item
937                  *     if it maps to output then
938                  *         save in output array given push value
939                  */
940                 for ( i=0; i<Nin; i++ )
941                     if ( ( push[i] > -1 )
942                          &&
943                          !((array_info)&comp->array)->get_item
944                              ( i, (array_info)&comp->array,
945                                &((char*)data)
946                                 [push[i]*((array_info)&comp->array)->itemsize]))
947                         goto error;
948             }
949             else /* NULL != pull */
950             {
951                 DXASSERTGOTO ( NULL != pull );
952 
953                 /*
954                  * For each output item
955                  *     retrieve from input given pull array value
956                  *     save in output
957                  */
958                 for ( i=0; i<Nout; i++ )
959                     if ( !((array_info)&comp->array)->get_item
960                              ( pull[i],
961                                (array_info)&comp->array,
962                                &((char*)data)
963                                     [i*((array_info)&comp->array)->itemsize]))
964                         goto error;
965             }
966         }
967         else /* REF */
968         {
969             int  ref;
970             int  nout = 0;
971 
972             if ( ( 0 != strcmp ( comp->name, "invalid connections" ) ) &&
973                  ( 0 != strcmp ( comp->name, "invalid positions"   ) )   )
974                 goto error;
975 
976           DXASSERTGOTO( 2             == dep_ref );
977           DXASSERTGOTO( TYPE_INT      == ((array_info)&comp->array)->type     );
978           DXASSERTGOTO( CATEGORY_REAL == ((array_info)&comp->array)->category );
979           DXASSERTGOTO( sizeof(int)   == ((array_info)&comp->array)->itemsize );
980 
981             for ( i=0; i<Nout; i++ ) ((int*)data)[i] = -1;
982 
983             if ( NULL != push )
984             {
985                 /*
986                  * For each input item
987                  *     If it has a valid reference and is to be pushed to output
988                  *         save in output
989                  */
990                 for ( i=0; i<((array_info)&comp->array)->items; i++ )
991                 {
992                     if ( !((array_info)&comp->array)->get_item
993                              ( i, (array_info)&comp->array, ((char*)&ref) ) )
994                         goto error;
995 
996                     if ( ( ref > -1 ) && ( push[ref] > -1 ) )
997                         ((int*)data)[nout++] = push[ref];
998                 }
999             }
1000             else /* NULL != pull */
1001             {
1002                 DXASSERTGOTO ( NULL != pull );
1003 
1004                 /*
1005                  * For each input item
1006                  *     If it has a valid reference
1007                  *         For each item in pull array
1008                  *             If the pull array item matches the reference
1009                  *             it can be moved, so
1010                  *                 If reference is not already in output
1011                  *                     save in output
1012                  */
1013                 for ( i=0; i<((array_info)&comp->array)->items; i++ )
1014                 {
1015                     if ( !((array_info)&comp->array)->get_item
1016                              ( i, (array_info)&comp->array, ((char*)&ref) ) )
1017                         goto error;
1018 
1019                     if ( ref > -1 )
1020                         for ( j=0; j<Nout; j++ )
1021                             if ( pull[j] == ref )
1022                             {
1023                                 for(k=0; (k<nout)&&(((int*)data)[k]!=j); k++);
1024 
1025                                 if ( k == nout )
1026                                     ((int*)data)[nout++] = j;
1027                             }
1028                 }
1029             }
1030 
1031             if ( ( ERROR == ( array2 = DXNewArrayV
1032                                          ( ((array_info)&comp->array)->type,
1033                                            ((array_info)&comp->array)->category,
1034                                            ((array_info)&comp->array)->rank,
1035                                            ((array_info)&comp->array)->shape )))
1036                  ||
1037                  !DXAllocateArray ( array2, nout )          ||
1038                  !DXAddArrayData  ( array2, 0, nout, data ) ||
1039                  !DXTrim          ( array2 ) )
1040                 goto error;
1041 
1042             DXDelete ( (Object) array );
1043 
1044             array  = array2;
1045             array2 = NULL;
1046         }
1047     }
1048 
1049     return array;
1050 
1051     error:
1052         DXDelete ( (Object) array );  array = NULL;
1053         DXDelete ( (Object) array2);  array2= NULL;
1054 
1055         DXASSERT ( DXGetError() != ERROR_NONE );
1056         return ERROR;
1057 }
1058 
1059 
1060 
1061 static
jea_slab(field_info input_info,int d,int n)1062 Field jea_slab
1063           ( field_info input_info,
1064             int  d,
1065             int  n )
1066 {
1067     int  nC_out, nP_in, nP_out;
1068 
1069     Field           out_field;
1070     Array           array     = NULL;
1071     array_info      c_info    = NULL;
1072     component_info  comp;
1073     Pointer         data      = NULL;
1074     int             *pull     = NULL;
1075 
1076     int flip = 0;
1077 
1078     array_info  t0, t1, t2=NULL;
1079     int         I,  II, OO,  i, j, k;
1080     int         n1;
1081 
1082     int    rev = (( d == 0 ) && ( n == 0 )) ||
1083                  (( d == 1 ) && ( n != 0 )) ||
1084                  (( d == 2 ) && ( n == 0 ));
1085 
1086  /*
1087   * Note:  if irregular data or invalidity culling, this call not made.
1088   */
1089 
1090 #if 0
1091 DXMessage ( "jea_slab d=%d, n=%d", d, n );
1092 DXPrint   ( (Object)input_info->field, "rd", "connections", 0);
1093 #endif
1094 
1095 
1096     c_info = (array_info) &(input_info->std_comps[(int)CONNECTIONS]->array);
1097     nP_in  = ((array_info) &(input_info->std_comps[(int)POSITIONS]->array))
1098                  ->items;
1099 
1100     if ( ERROR == ( out_field
1101                  = (Field) DXCopy ( (Object)input_info->field, COPY_HEADER ) ) )
1102         goto error;
1103 
1104     switch ( input_info->std_comps[(int)CONNECTIONS]->element_type )
1105     {
1106         case QUADRILATERALS:
1107             t0 = (array_info) &(((struct _array_allocator *)
1108                                     ((mesh_array_info)c_info)->terms)[0]);
1109             t1 = (array_info) &(((struct _array_allocator *)
1110                                     ((mesh_array_info)c_info)->terms)[1]);
1111 
1112             if ( ERROR == ( array = DXMakeGridConnections
1113                                         ( 1,
1114                                           ( (d!=0) ? t0->items+1 :
1115                                                      t1->items+1 ) ) ) )
1116                 goto error;
1117 
1118             nC_out = ((d!=0)? t0->items: t1->items );
1119             nP_out = nC_out + 1;
1120 
1121             break;
1122 
1123         case CUBES:
1124             t0 = (array_info) &(((struct _array_allocator *)
1125                                     ((mesh_array_info)c_info)->terms)[0]);
1126             t1 = (array_info) &(((struct _array_allocator *)
1127                                     ((mesh_array_info)c_info)->terms)[1]);
1128             t2 = (array_info) &(((struct _array_allocator *)
1129                                     ((mesh_array_info)c_info)->terms)[2]);
1130 
1131             if ( ERROR == ( array = DXMakeGridConnections
1132                                         ( 2,
1133                                           ( (d!=0)? t0->items+1: t1->items+1 ),
1134                                           ( (d!=2)? t2->items+1: t1->items+1 ) )
1135                           ) )
1136                 goto error;
1137 
1138             nC_out = ((d!=0)? t0->items: t1->items ) *
1139                      ((d!=2)? t2->items: t1->items );
1140 
1141             nP_out = ( ((d!=0)? t0->items: t1->items ) + 1 ) *
1142                      ( ((d!=2)? t2->items: t1->items ) + 1 );
1143 
1144             if ( ERROR == ( flip = _dxf_get_flip
1145                                        ( input_info,
1146                                          &global.have_connects,
1147                                          &global.have_nondegen ) ) )
1148                 goto error;
1149 
1150 #if 0
1151             DXMessage ( "jea_slab: get flip = %d", flip );
1152 #endif
1153             break;
1154 
1155         default:
1156             DXErrorGoto2
1157                 ( ERROR_DATA_INVALID,
1158                   "#11380", /* %s is an invalid connections type */
1159                   input_info->std_comps[(int)CONNECTIONS]->name );
1160     }
1161 
1162     if ( !DXSetComponentValue ( out_field, "connections", (Object) array ) )
1163         goto error;
1164 
1165     array = NULL;
1166 
1167     if ( !DXSetComponentAttribute
1168              ( out_field, "connections", "element type",
1169                (Object)DXNewString
1170                            (
1171               ( CUBES == input_info->std_comps[(int)CONNECTIONS]->element_type )
1172                         ? "quads" : "lines" ) ) )
1173         goto error;
1174 
1175 
1176     /*
1177      * For each component in input:
1178      *     Determine if copied unchanged, already handled,
1179      *     discarded, or remapped.
1180      */
1181     for ( I=0, comp=input_info->comp_list;
1182           I<input_info->comp_count;
1183           I++, comp++ )
1184     {
1185         array = NULL;
1186 
1187 #if 0
1188 DXMessage ( "---------------------------------------------------------------" );
1189 DXMessage ( "The name of the dog is %s", comp->name );
1190 DXPrint   ( (Object)((array_info)&comp->array)->array, "rd", 0);
1191 #endif
1192 
1193         if ( 0 == strcmp ( comp->name, "color map" ) ||
1194 	     0 == strcmp ( comp->name, "opacity map" ) )
1195         {
1196             array = ((array_info)&comp->array)->array;
1197         }
1198         else if ( ( 0 == strncmp ( comp->name, "original", 8 ) ) ||
1199                   ( 0 == strcmp  ( comp->name, "normals"     ) )   )
1200         {
1201             array = NULL;
1202         }
1203         else if ( ( NULL  != comp->std_attribs[(int)DEP]        ) &&
1204                   ( ERROR != comp->std_attribs[(int)DEP]->value )   )
1205         {
1206             if (0 == strcmp ( comp->std_attribs[(int)DEP]->value, "positions" ))
1207             {
1208                 if ( CLASS_CONSTANTARRAY == ((array_info)&comp->array)->class )
1209                 {
1210                     if ( ERROR == ( array
1211                              = (Array)DXNewConstantArrayV
1212                                    ( nP_out,
1213                                      DXGetConstantArrayData
1214                                          ( ((array_info)&comp->array)->array ),
1215                                      ((array_info)&comp->array)->type,
1216                                      ((array_info)&comp->array)->category,
1217                                      ((array_info)&comp->array)->rank,
1218                                      ((array_info)&comp->array)->shape ) ) )
1219                         goto error;
1220                 }
1221                 else
1222                 {
1223                     if ( !_dxf_SetIterator ( comp )
1224                          ||
1225                          ( ERROR == ( array
1226                                = DXNewArrayV
1227                                      ( ((array_info)&comp->array)->type,
1228                                        ((array_info)&comp->array)->category,
1229                                        ((array_info)&comp->array)->rank,
1230                                        ((array_info)&comp->array)->shape ) ) )
1231                          ||
1232                          !DXAllocateArray ( array, nP_out )          ||
1233                          !DXAddArrayData  ( array, 0, nP_out, NULL ) ||
1234                          !DXTrim          ( array )
1235                          ||
1236                          ( ERROR == ( data = DXGetArrayData ( array ) ) ) )
1237                         goto error;
1238 
1239                     switch ( input_info->std_comps[(int)CONNECTIONS]
1240                               ->element_type )
1241                     {
1242                         case QUADRILATERALS:
1243                             for ( i = (d==0)? n : 0;
1244                                   (d==0)? (i==n) : (i<(t0->items+1));
1245                                   i++ )
1246                             for ( j = (d==1)? n : 0;
1247                                   (d==1)? (j==n) : (j<(t1->items+1));
1248                                   j++ )
1249                             {
1250                                 /* 2D ( rev ) */
1251                                 II = ( i * (t1->items+1) ) + j;
1252                                 OO = (d==0)? j : i;
1253 
1254                                 if ( !((array_info)&comp->array)->get_item
1255                                           ( II, (array_info)&comp->array,
1256                                             &((char*)data)
1257                                      [OO*((array_info)&comp->array)->itemsize]))
1258                                     goto error;
1259                             }
1260                             break;
1261 
1262                         case CUBES:
1263                             for ( i = (d==0)? n : 0;
1264                                   (d==0)? (i==n) : (i<(t0->items+1));
1265                                   i++ )
1266                             for ( j = (d==1)? n : 0;
1267                                   (d==1)? (j==n) : (j<(t1->items+1));
1268                                   j++ )
1269                             for ( k = (d==2)? n : 0;
1270                                   (d==2)? (k==n) : (k<(t2->items+1));
1271                                   k++ )
1272                             {
1273                                 if ( rev )
1274                                 {
1275                                     if ( d == 2 )
1276                                         II = ((((t0->items-i)*(t1->items+1))+j)
1277                                              *(t2->items+1))+k;
1278                                     else
1279                                         II = (((i*(t1->items+1))+j)
1280                                              *(t2->items+1)) + t2->items-k;
1281                                 }
1282                                 else
1283                                 II = (((i*(t1->items+1))+j)*(t2->items+1))+k;
1284 
1285                                 OO = (d==0)? ( ( j * (t2->items+1) ) + k ) :
1286                                      (d==1)? ( ( i * (t2->items+1) ) + k ) :
1287                                              ( ( i * (t1->items+1) ) + j );
1288 
1289                                 if ( !((array_info)&comp->array)->get_item
1290                                           ( II, (array_info)&comp->array,
1291                                             &((char*)data)
1292                                      [OO*((array_info)&comp->array)->itemsize]))
1293                                     goto error;
1294                             }
1295                             break;
1296 		         default:
1297 			    break;
1298                     }
1299                 }
1300             }
1301             else if ( ( 0 == strcmp ( comp->std_attribs[(int)DEP]->value,
1302                                       "connections" ) ) &&
1303                       ( 0 != strcmp ( comp->name, "connections" ) ) )
1304             {
1305                 if ( CLASS_CONSTANTARRAY == ((array_info)&comp->array)->class )
1306                 {
1307                     if ( ERROR == ( array
1308                              = (Array)DXNewConstantArrayV
1309                                    ( nC_out,
1310                                      DXGetConstantArrayData
1311                                          ( ((array_info)&comp->array)->array ),
1312                                      ((array_info)&comp->array)->type,
1313                                      ((array_info)&comp->array)->category,
1314                                      ((array_info)&comp->array)->rank,
1315                                      ((array_info)&comp->array)->shape ) ) )
1316                         goto error;
1317                 }
1318                 else
1319                 {
1320                     if ( !_dxf_SetIterator ( comp )
1321                          ||
1322                          ( ERROR == ( array
1323                                = DXNewArrayV
1324                                      ( ((array_info)&comp->array)->type,
1325                                        ((array_info)&comp->array)->category,
1326                                        ((array_info)&comp->array)->rank,
1327                                        ((array_info)&comp->array)->shape ) ) )
1328                          ||
1329                          !DXAllocateArray ( array, nC_out )          ||
1330                          !DXAddArrayData  ( array, 0, nC_out, NULL ) ||
1331                          !DXTrim          ( array )
1332                          ||
1333                          ( ERROR == ( data = DXGetArrayData ( array ) ) ) )
1334                         goto error;
1335 
1336                     n1 = (n==0)? 0 : n-1;  /* max connections = max p - 1 */
1337 
1338                     switch ( input_info->std_comps[(int)CONNECTIONS]
1339                              ->element_type )
1340                     {
1341                         case QUADRILATERALS:
1342                             for ( i = (d==0)? n1 : 0;
1343                                   (d==0)? (i==n1) : (i<t0->items);
1344                                   i++ )
1345                             for ( j = (d==1)? n1 : 0;
1346                                   (d==1)? (j==n1) : (j<t1->items);
1347                                   j++ )
1348                             {
1349                                 /* 2D ( rev ) */
1350                                 II = ( i * t1->items ) + j;
1351                                 OO = (d==0)? j : i;
1352 
1353                                 if ( !((array_info)&comp->array)->get_item
1354                                           ( II, (array_info)&comp->array,
1355                                             &((char*)data)
1356                                      [OO*((array_info)&comp->array)->itemsize]))
1357                                     goto error;
1358                             }
1359                             break;
1360 
1361                         case CUBES:
1362                             for ( i = (d==0)? n1 : 0;
1363                                   (d==0)? (i==n1) : (i<t0->items);
1364                                   i++ )
1365                             for ( j = (d==1)? n1 : 0;
1366                                   (d==1)? (j==n1) : (j<t1->items);
1367                                   j++ )
1368                             for ( k = (d==2)? n1 : 0;
1369                                   (d==2)? (k==n1) : (k<t2->items);
1370                                   k++ )
1371                             {
1372                                 if ( rev )
1373                                 {
1374                                     if ( d == 2 )
1375                                         II = (((((t0->items-1)-i)*t1->items)+j)
1376                                              *t2->items) + k;
1377                                     else
1378                                         II = (((i*t1->items)+j)
1379                                              *t2->items) + (t2->items-1)-k;
1380                                 }
1381                                 else
1382                                II = ((( i * t1->items ) + j ) * t2->items ) + k;
1383 
1384                                 OO = (d==0)? ( ( j * t2->items ) + k ) :
1385                                      (d==1)? ( ( i * t2->items ) + k ) :
1386                                              ( ( i * t1->items ) + j );
1387 
1388                                 if ( !((array_info)&comp->array)->get_item
1389                                           ( II, (array_info)&comp->array,
1390                                             &((char*)data)
1391                                      [OO*((array_info)&comp->array)->itemsize]))
1392                                     goto error;
1393                             }
1394                             break;
1395 		         default:
1396 			    break;
1397                     }
1398                 }
1399             }
1400         }
1401         else if ( ( NULL  != comp->std_attribs[(int)REF]        ) &&
1402                   ( ERROR != comp->std_attribs[(int)REF]->value ) &&
1403                   ( ( 0 == strcmp ( comp->name, "invalid connections" ) ) ||
1404                     ( 0 == strcmp ( comp->name, "invalid positions"   ) ) ))
1405         {
1406             /*
1407              * Time/space tradeoff:
1408              *   push (see _dxf_resample_array) is simpler, pull is smaller
1409              */
1410             if ( 0 == strcmp ( comp->std_attribs[(int)REF]->value, "positions"))
1411             {
1412                 if ( ERROR == ( pull = (int*) DXAllocate (nP_out*sizeof(int))) )
1413                     goto error;
1414 
1415                 switch ( input_info->std_comps[(int)CONNECTIONS]->element_type )
1416                 {
1417                     case QUADRILATERALS:
1418                         for ( i = (d==0)? n : 0;
1419                               (d==0)? (i==n) : (i<(t0->items+1));
1420                               i++ )
1421                         for ( j = (d==1)? n : 0;
1422                               (d==1)? (j==n) : (j<(t1->items+1));
1423                               j++ )
1424                         {
1425                             /* 2D ( rev ) */
1426                             II = ( i * (t1->items+1) ) + j;
1427                             OO = (d==0)? j : i;
1428 
1429                             pull[OO] = II;
1430                         }
1431                         break;
1432 
1433                     case CUBES:
1434                         for ( i = (d==0)? n : 0;
1435                               (d==0)? (i==n) : (i<(t0->items+1));
1436                               i++ )
1437                         for ( j = (d==1)? n : 0;
1438                               (d==1)? (j==n) : (j<(t1->items+1));
1439                               j++ )
1440                         for ( k = (d==2)? n : 0;
1441                               (d==2)? (k==n) : (k<(t2->items+1));
1442                               k++ )
1443                         {
1444                             if ( rev )
1445                             {
1446                                 if ( d == 2 )
1447                                     II = ((((t0->items-i)*(t1->items+1))+j)
1448                                          *(t2->items+1)) + k;
1449                                 else
1450                                     II = (((i*(t1->items+1))+j)
1451                                          *(t2->items+1)) + t2->items-k;
1452                             }
1453                             else
1454                             II = (((i*(t1->items+1))+j)*(t2->items+1))+k;
1455 
1456                             OO = (d==0)? ( ( j * (t2->items+1) ) + k ) :
1457                                  (d==1)? ( ( i * (t2->items+1) ) + k ) :
1458                                          ( ( i * (t1->items+1) ) + j );
1459 
1460                             pull[OO] = II;
1461                         }
1462                         break;
1463 		    default:
1464 		        break;
1465                 }
1466 
1467                 if ( ERROR == ( array = _dxf_resample_array
1468                                             ( comp, 2 /* REF */,
1469                                               nP_in, nP_out,
1470                                               NULL, pull ) ) )
1471                     goto error;
1472 
1473                 DXFree ( (Pointer) pull );  pull = NULL;
1474 
1475             }
1476             else if ( 0 == strcmp ( comp->std_attribs[(int)REF]->value,
1477                                     "connections" ) )
1478             {
1479                 if ( ERROR == ( pull = (int*) DXAllocate (nC_out*sizeof(int))) )
1480                     goto error;
1481 
1482                 n1 = (n==0)? 0 : n-1;  /* max connections = max p - 1 */
1483 
1484                 switch ( input_info->std_comps[(int)CONNECTIONS]->element_type )
1485                 {
1486                     case QUADRILATERALS:
1487                         for ( i = (d==0)? n1 : 0;
1488                               (d==0)? (i==n1) : (i<t0->items);
1489                               i++ )
1490                         for ( j = (d==1)? n1 : 0;
1491                               (d==1)? (j==n1) : (j<t1->items);
1492                               j++ )
1493                         {
1494                             /* 2D ( rev ) */
1495                             II = ( i * t1->items ) + j;
1496                             OO = (d==0)? j : i;
1497 
1498                             pull[OO] = II;
1499                         }
1500                         break;
1501 
1502                     case CUBES:
1503                         for ( i = (d==0)? n1 : 0;
1504                               (d==0)? (i==n1) : (i<t0->items);
1505                               i++ )
1506                         for ( j = (d==1)? n1 : 0;
1507                               (d==1)? (j==n1) : (j<t1->items);
1508                               j++ )
1509                         for ( k = (d==2)? n1 : 0;
1510                               (d==2)? (k==n1) : (k<t2->items);
1511                               k++ )
1512                         {
1513                             if ( rev )
1514                             {
1515                                 if ( d == 2 )
1516                                     II = (((((t0->items-1)-i)*t1->items)+j)
1517                                          * t2->items ) + k;
1518                                 else
1519                                     II = (((i*t1->items)+j)
1520                                          * t2->items ) + (t2->items-1)-k;
1521                             }
1522                             else
1523                            II = ((( i * t1->items ) + j ) * t2->items ) + k;
1524 
1525                             OO = (d==0)? ( ( j * t2->items ) + k ) :
1526                                  (d==1)? ( ( i * t2->items ) + k ) :
1527                                          ( ( i * t1->items ) + j );
1528 
1529                             pull[OO] = II;
1530                         }
1531                         break;
1532 		     default:
1533 		        break;
1534                 }
1535 
1536                 if ( ERROR == ( array = _dxf_resample_array
1537                                             ( comp, 2 /* REF */,
1538                                               c_info->items, nC_out,
1539                                               NULL, pull ) ) )
1540                     goto error;
1541 
1542                 DXFree ( (Pointer) pull );  pull = NULL;
1543             }
1544         }
1545 
1546         if ( 0 != strcmp ( comp->name, "connections" ) )
1547             if ( !DXSetComponentValue ( out_field, comp->name, (Object)array ) )
1548                 goto error;
1549 
1550     }
1551 
1552     /* XXX - remove "der"'s ! (This gets the follow-on der's as well) */
1553     if ( !DXChangedComponentValues ( out_field, "positions"   ) ||
1554          !DXChangedComponentValues ( out_field, "connections" )  )
1555         goto error;
1556 
1557     if ( input_info->std_comps[(int)CONNECTIONS]->element_type == CUBES )
1558         if ( !make_normals ( out_field, nP_out, flip ) )
1559             goto error;
1560 
1561     if ( !_dxf_SetDefaultColor ( out_field, DEFAULT_BOUND_COLOR ) )
1562         goto error;
1563 
1564     return out_field;
1565 
1566     error:
1567         DXASSERT ( DXGetError() != ERROR_NONE );
1568         return ERROR;
1569 }
1570 
1571 
1572 
1573 static
regular_boundary(field_info input_info)1574 MultiGrid regular_boundary ( field_info input_info )
1575 {
1576     component_info  proprietary = NULL;
1577     bounds_ptr      bptr        = NULL;
1578     MultiGrid       output      = NULL;
1579     Field           field       = NULL;
1580     array_info      c_info      = NULL;
1581     int             nfields     = 0;
1582     array_info      t0, t1, t2;
1583 
1584 
1585     if ( ( ERROR == ( output = DXNewMultiGrid() ) ) )
1586         goto error;
1587 
1588     if ( ( ERROR == ( proprietary = _dxf_FindCompInfo
1589                                         ( input_info,
1590                                           PROPRIETARY_COMPONENT_NAME ) ) )
1591          &&
1592          ( DXGetError() != ERROR_NONE ) )
1593         goto error;
1594 
1595     bptr = ( NULL == proprietary )?
1596                NULL : ((array_info)&(proprietary->array))->data;
1597 
1598     c_info = (array_info) &(input_info->std_comps[(int)CONNECTIONS]->array);
1599 
1600     /* XXX - growth */
1601 
1602 #if 0
1603     if ( bptr == NULL )
1604         DXMessage ( "offsets: NULL" );
1605     else
1606         DXMessage ( "offsets: %d, %d, %d, %d, %d, %d",
1607                     bptr->i_min, bptr->j_min, bptr->k_min,
1608                     bptr->i_max, bptr->j_max, bptr->k_max );
1609 #endif
1610 
1611 #define PUT_FACE(DN,IJK_MINMAX,VALUE) \
1612     if((bptr==NULL)||\
1613        (((VALUE)+((mesh_array_info)c_info)->offsets[DN])==bptr->IJK_MINMAX)) \
1614       if((ERROR==(field=jea_slab(input_info,DN,(VALUE))))|| \
1615         !DXSetEnumeratedMember((Group)output,nfields++,(Object)field))goto error
1616 
1617     switch ( input_info->std_comps[(int)CONNECTIONS]->element_type )
1618     {
1619         case QUADRILATERALS:
1620             DXDATAASSERTGOTO ( ((mesh_array_info)c_info)->n == 2 );
1621 
1622             t0 = (array_info) &(((struct _array_allocator *)
1623                                     ((mesh_array_info)c_info)->terms)[0]);
1624             t1 = (array_info) &(((struct _array_allocator *)
1625                                     ((mesh_array_info)c_info)->terms)[1]);
1626 
1627             PUT_FACE ( 0, i_min, 0 );
1628             PUT_FACE ( 1, j_min, 0 );
1629             PUT_FACE ( 0, i_max, t0->items );
1630             PUT_FACE ( 1, j_max, t1->items );
1631             break;
1632 
1633         case CUBES:
1634             DXDATAASSERTGOTO ( ((mesh_array_info)c_info)->n == 3 );
1635 
1636             t0 = (array_info) &(((struct _array_allocator *)
1637                                     ((mesh_array_info)c_info)->terms)[0]);
1638             t1 = (array_info) &(((struct _array_allocator *)
1639                                     ((mesh_array_info)c_info)->terms)[1]);
1640             t2 = (array_info) &(((struct _array_allocator *)
1641                                     ((mesh_array_info)c_info)->terms)[2]);
1642 
1643             PUT_FACE ( 0, i_min, 0 );
1644             PUT_FACE ( 1, j_min, 0 );
1645             PUT_FACE ( 2, k_min, 0 );
1646             PUT_FACE ( 0, i_max, t0->items );
1647             PUT_FACE ( 1, j_max, t1->items );
1648             PUT_FACE ( 2, k_max, t2->items );
1649             break;
1650 
1651         default:
1652             DXErrorGoto
1653                 ( ERROR_DATA_INVALID,
1654                   "Bad \"connections\" element type" );
1655     }
1656 #undef PUT_FACE
1657 
1658     DXDelete ( (Object) input_info->field );
1659     /* gets PROPRIETARY_COMPONENT_NAME */
1660 
1661     if ( nfields == 0 ) { DXDelete ( (Object) output );  output = NULL; }
1662 
1663     return output;
1664 
1665     error:
1666         DXASSERT ( DXGetError() != ERROR_NONE );
1667         return ERROR;
1668 }
1669 
1670 
1671 
1672 static
irregular_boundary(field_info input_info,InvalidComponentHandle i_handle)1673 Field irregular_boundary
1674          ( field_info input_info, InvalidComponentHandle i_handle )
1675 {
1676     array_info      c_info, n_info;
1677     component_info  proprietary = NULL;
1678     component_info  comp;
1679 
1680     int  i, j, k,   n, t;
1681     int  nP_in,  nC_out, nP_out;
1682 
1683     Array    array         = NULL;
1684     Pointer  data          = NULL;
1685     int      *o_conn_index = NULL;
1686     int      *i_posi_index = NULL;
1687     int      outshape;
1688 
1689     bounds_ptr bptr        = NULL;
1690     neighbor6  neighb;
1691     Cube       conn;
1692 
1693     int flip=0;
1694 
1695     Error (*get_neighbor)() = NULL;
1696 
1697     /* duplicated out of _helper_jea.h */
1698 
1699                        /* XXX - we don't have or know line neighb's */
1700     int  quad_to_line  [4][2] = { { 0, 1 }, { 3, 2 }, { 2, 0 }, { 1, 3 } };
1701     int  tri_to_line   [3][2] = { { 1, 2 }, { 2, 0 }, { 0, 1 } };
1702     int  cube_to_quad  [6][4]
1703              = { { 1, 0, 3, 2 }, { 4, 5, 6, 7 }, { 0, 1, 4, 5 },
1704                  { 2, 6, 3, 7 }, { 0, 4, 2, 6 }, { 1, 3, 5, 7 } };
1705     int  tetra_to_tri  [4][3]
1706              = { { 1, 3, 2 }, { 0, 2, 3 }, { 0, 3, 1 }, { 0, 1, 2 } };
1707 
1708     c_info = (array_info) &(input_info->std_comps[(int)CONNECTIONS]->array);
1709     nP_in  = ((array_info) &(input_info->std_comps[(int)POSITIONS]->array))
1710                  ->items;
1711 
1712     switch ( input_info->std_comps[(int)CONNECTIONS]->element_type )
1713     {
1714         case TETRAHEDRA:
1715         case CUBES:
1716             if ( ERROR == ( flip = _dxf_get_flip
1717                                        ( input_info,
1718                                          &global.have_connects,
1719                                          &global.have_nondegen ) ) )
1720                 goto error;
1721 #if 0
1722             DXMessage ( "irregular_boundary: get flip = %d", flip );
1723 #endif
1724             break;
1725 	 default:
1726 	    break;
1727     }
1728 
1729     if ( input_info->std_comps[(int)NEIGHBORS] != NULL )
1730         n_info = (array_info) &(input_info->std_comps[(int)NEIGHBORS]->array);
1731     else if ( ( CLASS_MESHARRAY == c_info->class )
1732               &&
1733               ( TTRUE == ((mesh_array_info)c_info)->grid ) )
1734     {
1735         n_info = NULL;
1736 
1737         if ( ( ERROR == ( proprietary = _dxf_FindCompInfo
1738                                             ( input_info,
1739                                               PROPRIETARY_COMPONENT_NAME ) ) )
1740              &&
1741              ( DXGetError() != ERROR_NONE ) )
1742             goto error;
1743 
1744         bptr = (proprietary==NULL)?
1745                    NULL : ((array_info)&(proprietary->array))->data;
1746 
1747         switch ( input_info->std_comps[(int)CONNECTIONS]->element_type )
1748         {
1749           case QUADRILATERALS: get_neighbor = _dxf_get_neighb_grid_QUADS; break;
1750           case CUBES:          get_neighbor = _dxf_get_neighb_grid_CUBES; break;
1751 	  default: break;
1752         }
1753     }
1754     else
1755         DXErrorGoto3
1756             ( ERROR_UNEXPECTED,
1757               "#10250", /*%s is missing %s component*/
1758               "'input' parameter",
1759               "\"neighbors\"" );
1760 
1761 
1762     /*
1763      * COUNT:  find total output connections, using variable in nC_out.
1764      *     N_NEIGHB - Number of neighbors in a connection.
1765      */
1766 #define COUNT( N_NEIGHB ) \
1767     if ( i_handle == NULL ) \
1768         for ( i=0; i<c_info->items; i++ ) \
1769             for ( j=0; j<N_NEIGHB; j++ ) \
1770             { \
1771                 if ( -1 == ( (int*) n_info->data ) [i*N_NEIGHB+j] ) \
1772                     nC_out ++; \
1773             } \
1774     else if ( n_info != NULL ) \
1775         for ( i=0; i<c_info->items; i++ ) \
1776         { \
1777             if ( !DXIsElementInvalid ( i_handle, i ) ) \
1778                 for ( j=0; j<N_NEIGHB; j++) \
1779                     if ( ( -1 == ( n = \
1780                                  ((int *) n_info->data) [i*N_NEIGHB+j] ) ) \
1781                          || ( ( n > -1 ) && \
1782                          DXIsElementInvalid ( i_handle, n ) ) ) \
1783                         nC_out ++; \
1784         } \
1785     else \
1786         for ( i=0; i<c_info->items; i++ ) \
1787             if ( !DXIsElementInvalid ( i_handle, i ) ) { \
1788                 if ( !get_neighbor ( i, c_info, bptr, &neighb ) ) \
1789                     goto error;\
1790                 else \
1791                     for ( j=0; j<N_NEIGHB; j++ ) \
1792                         if ( ( -1 == ( n = ((int*)&neighb)[j] ) ) \
1793                              || ( ( n > -1 ) && \
1794                              DXIsElementInvalid ( i_handle, n ) ) ) \
1795                             nC_out ++; \
1796 	    }
1797 
1798 
1799 
1800     nC_out = 0;
1801     switch ( input_info->std_comps[(int)CONNECTIONS]->element_type )
1802     {
1803         case TRIANGLES:      outshape = 2;  COUNT ( 3 ); break;
1804         case QUADRILATERALS: outshape = 2;  COUNT ( 4 ); break;
1805         case TETRAHEDRA:     outshape = 3;  COUNT ( 4 ); break;
1806         case CUBES:          outshape = 4;  COUNT ( 6 ); break;
1807         default:
1808             DXErrorGoto2
1809                 ( ERROR_DATA_INVALID,
1810                   "#11380", /* %s is an invalid connections type */
1811                   input_info->std_comps[(int)CONNECTIONS]->name );
1812     }
1813 #undef  COUNT
1814 
1815     if ( nC_out == 0 )
1816         return _dxf_MakeFieldEmpty ( input_info->field );
1817 
1818     else
1819         if ( ( ERROR == ( i_posi_index = (int *) DXAllocate
1820                                                      ( nP_in * sizeof(int) )) )
1821              ||
1822              ( ERROR == ( o_conn_index = (int *) DXAllocate
1823                                                      ( nC_out * sizeof(int) )) )
1824              ||
1825              ( ERROR == ( array = DXNewArray ( TYPE_INT, CATEGORY_REAL,
1826                                                1, outshape ) ) )
1827              ||
1828              !DXAllocateArray ( array, nC_out )          ||
1829              !DXAddArrayData  ( array, 0, nC_out, NULL ) ||
1830              !DXTrim          ( array )
1831              ||
1832              ( ERROR == ( data = DXGetArrayData ( array ) ) )
1833              ||
1834              !DXSetComponentValue
1835                   ( input_info->field, "connections", (Object) array ) )
1836             goto error;
1837 
1838     array = NULL;
1839 
1840     if ( !DXSetComponentAttribute
1841              ( input_info->field, "connections", "element type",
1842                (Object)DXNewString
1843                            ( ( outshape == 1 ) ? "points"    :
1844                              ( outshape == 2 ) ? "lines"     :
1845                              ( outshape == 3 ) ? "triangles" :
1846                              ( outshape == 4 ) ? "quads"     :
1847                                                  "ERROR" ) ) )
1848         goto error;
1849 
1850     for ( i=0; i<nP_in; i++ ) i_posi_index [ i ] = -1;
1851 
1852 #if 0
1853 DXMessage( "ci[%d][%d] = %d  -->>  co[%d][%d] = %d",
1854 i,IN_TO_OUT[j][k],((int *) c_info->data)[i*N_CONN+IN_TO_OUT[j][k]],
1855 nC_out,k,((int *) data) [nC_out*N_CONN_OUT+k] );
1856 #endif
1857 
1858     /*
1859      * CONVERT:
1860      *     N_NEIGHB   - Number of neighbors in a connection.
1861      *     N_CONN     - Number of indices in an input connection.
1862      *     N_CONN_OUT - Number of indices in an output connection.
1863      *     IN_TO_OUT  - mapping of a neighbor to a conn. spanning that face.
1864      */
1865 #define CONVERT(N_NEIGHB,N_CONN,N_CONN_OUT,IN_TO_OUT) \
1866     if ( i_handle == NULL ) { \
1867         for ( i=0; i<c_info->items; i++ ) \
1868             for ( j=0; j<N_NEIGHB; j++ ) \
1869             { \
1870                 if ( -1 == ((int *) n_info->data) [i*N_NEIGHB+j] ) \
1871                 { \
1872                     for ( k=0; k<N_CONN_OUT; k++ ) \
1873                     { \
1874                         t = ( (int*) c_info->data ) \
1875                                 [i*N_CONN+IN_TO_OUT[j][k]]; \
1876                         \
1877                         if ( i_posi_index[t] == -1 ) \
1878                             i_posi_index[t] = nP_out++; \
1879                         \
1880                         ((int *) data) [nC_out*N_CONN_OUT+k] \
1881                             = i_posi_index[t]; \
1882                     } \
1883                     o_conn_index [ nC_out++ ] = i; \
1884                 } \
1885             } \
1886     } else if ( n_info != NULL ) { \
1887         for ( i=0; i<c_info->items; i++ ) \
1888         { \
1889             if ( !DXIsElementInvalid ( i_handle, i ) ) \
1890                 for ( j=0; j<N_NEIGHB; j++ ) \
1891                 { \
1892                     if ( ( -1 == ( n = \
1893                                  ( (int*) n_info->data) [i*N_NEIGHB+j] ) ) \
1894                          || ( ( n > -1 ) && \
1895                          DXIsElementInvalid ( i_handle, n ) ) ) \
1896                     { \
1897                         for ( k=0; k<N_CONN_OUT; k++ ) \
1898                         { \
1899                             t = ( (int*) c_info->data ) \
1900                                     [i*N_CONN+IN_TO_OUT[j][k]]; \
1901                             \
1902                             if ( i_posi_index[t] == -1 ) \
1903                                 i_posi_index[t] = nP_out++; \
1904                             \
1905                             ( (int*) data ) [nC_out*N_CONN_OUT+k] \
1906                                 = i_posi_index[t]; \
1907                         } \
1908                         o_conn_index [ nC_out++ ] = i; \
1909                     } \
1910                 } \
1911         } \
1912     } else { \
1913         for ( i=0; i<c_info->items; i++ ) \
1914             if ( !DXIsElementInvalid ( i_handle, i ) ) { \
1915                 if ( !get_neighbor ( i, c_info, bptr, &neighb ) ) \
1916                     goto error; \
1917                 else \
1918                     for ( j=0; j<N_NEIGHB; j++ ) \
1919                         if ( ( -1 == ( n = ((int*)&neighb) [j] ) ) \
1920                              || ( ( n > -1 ) && \
1921                              DXIsElementInvalid ( i_handle, n ) ) ) \
1922                         { \
1923                             if ( !c_info->get_item ( i, c_info, &conn ) ) \
1924                                 goto error; \
1925                             else \
1926                                 for ( k=0; k<N_CONN_OUT; k++ ) \
1927                                 { \
1928                                     t = ((int*)&conn) [IN_TO_OUT[j][k]]; \
1929                                     \
1930                                     if ( i_posi_index[t] == -1 ) \
1931                                         i_posi_index[t] = nP_out++; \
1932                                     \
1933                                     ( (int*) data ) [nC_out*N_CONN_OUT+k] \
1934                                         = i_posi_index[t]; \
1935                                 } \
1936                                 o_conn_index [ nC_out++ ] = i; \
1937                         } \
1938 	    } \
1939      }
1940 
1941 
1942     nC_out = 0;
1943     nP_out = 0;
1944     switch ( input_info->std_comps[(int)CONNECTIONS]->element_type )
1945     {
1946         case TRIANGLES:      CONVERT ( 3, 3, 2,   tri_to_line  );  break;
1947         case QUADRILATERALS: CONVERT ( 4, 4, 2,  quad_to_line  );  break;
1948         case TETRAHEDRA:     CONVERT ( 4, 4, 3, tetra_to_tri   );  break;
1949         case CUBES:          CONVERT ( 6, 8, 4,  cube_to_quad  );  break;
1950         default: break;
1951     }
1952 #undef  CONVERT
1953 
1954 
1955     /*
1956      * For each component in input:
1957      *     Determine if copied unchanged, already handled,
1958      *     discarded, or remapped.
1959      */
1960     for ( i=0, comp=input_info->comp_list;
1961           i<input_info->comp_count;
1962           i++, comp++ )
1963     {
1964         array = NULL;
1965 
1966 #if 0
1967 DXMessage ( "---------------------------------------------------------------" );
1968 DXMessage ( "The name of the dog is %s", comp->name );
1969 #endif
1970 
1971         if ( 0 == strcmp ( comp->name, "color map" ) ||
1972 	     0 == strcmp ( comp->name, "opacity map" ) )
1973         {
1974             array = ((array_info)&comp->array)->array;
1975         }
1976         else if ( ( 0 == strncmp ( comp->name, "original", 8 ) ) ||
1977                   ( 0 == strcmp  ( comp->name, "normals"     ) )   )
1978         {
1979             array = NULL;
1980         }
1981         else if ( ( NULL  != comp->std_attribs[(int)DEP]        ) &&
1982                   ( ERROR != comp->std_attribs[(int)DEP]->value )   )
1983         {
1984             if (0 == strcmp ( comp->std_attribs[(int)DEP]->value, "positions" ))
1985             {
1986                 if ( ERROR == ( array = _dxf_resample_array
1987                                             ( comp, 1 /* DEP */, nP_in, nP_out,
1988                                               i_posi_index, NULL ) ) )
1989                     goto error;
1990             }
1991             else if ( ( 0 == strcmp ( comp->std_attribs[(int)DEP]->value,
1992                                       "connections" ) ) &&
1993                       ( 0 != strcmp ( comp->name, "connections" ) ) )
1994             {
1995                 if ( ERROR == ( array = _dxf_resample_array
1996                                             ( comp, 1 /* DEP */,
1997                                               c_info->items, nC_out,
1998                                               NULL, o_conn_index ) ) )
1999                     goto error;
2000             }
2001         }
2002         else if ( ( NULL  != comp->std_attribs[(int)REF]        ) &&
2003                   ( ERROR != comp->std_attribs[(int)REF]->value ) &&
2004                   ( NULL  == i_handle ) &&
2005                   ( ( 0 == strcmp ( comp->name, "invalid connections" ) ) ||
2006                     ( 0 == strcmp ( comp->name, "invalid positions"   ) )   ) )
2007         {
2008             if (0 == strcmp ( comp->std_attribs[(int)REF]->value, "positions" ))
2009             {
2010                 if ( ERROR == ( array = _dxf_resample_array
2011                                             ( comp, 2 /* REF */, nP_in, nP_out,
2012                                               i_posi_index, NULL ) ) )
2013                     goto error;
2014             }
2015             else if (0 == strcmp ( comp->std_attribs[(int)REF]->value,
2016                                    "connections" ) )
2017             {
2018                 if ( ERROR == ( array = _dxf_resample_array
2019                                             ( comp, 2 /* REF */,
2020                                               c_info->items, nC_out,
2021                                               NULL, o_conn_index ) ) )
2022                     goto error;
2023             }
2024         }
2025 
2026         if ( 0 != strcmp ( comp->name, "connections" ) )
2027             if ( !DXSetComponentValue
2028                       ( input_info->field, comp->name, (Object)array ) )
2029                 goto error;
2030     }
2031 
2032     DXFree ( (Pointer) i_posi_index );  i_posi_index = NULL;
2033     DXFree ( (Pointer) o_conn_index );  o_conn_index = NULL;
2034 
2035     /* XXX - remove "der"'s ! (This gets the follow-on der's as well) */
2036     if ( !DXChangedComponentValues ( input_info->field, "positions"   ) ||
2037          !DXChangedComponentValues ( input_info->field, "connections" )  )
2038         goto error;
2039 
2040     switch ( input_info->std_comps[(int)CONNECTIONS]->element_type )
2041     {
2042         case TETRAHEDRA:
2043         case CUBES:
2044             if ( !make_normals ( input_info->field, nP_out, flip ) )
2045                 goto error;
2046             break;
2047     	default:
2048 	    break;
2049     }
2050 
2051     if ( !_dxf_SetDefaultColor ( input_info->field, DEFAULT_BOUND_COLOR ) )
2052         goto error;
2053 
2054     return input_info->field;
2055 
2056     error:
2057         DXFree ( (Pointer) i_posi_index );  i_posi_index = NULL;
2058         DXFree ( (Pointer) o_conn_index );  o_conn_index = NULL;
2059 
2060         DXASSERT ( DXGetError() != ERROR_NONE );
2061         return ERROR;
2062 }
2063 
2064 
2065 static
show_boundary(Field input,char * arg,int args)2066 Field show_boundary ( Field input, char *arg, int args )
2067 {
2068     field_info  input_info     = NULL;
2069     array_info  c_info = NULL;
2070     int         option;
2071     Object      output;
2072 
2073     InvalidComponentHandle  i_handle  = NULL;
2074 
2075     DXASSERTGOTO ( input != ERROR );
2076     DXASSERTGOTO ( DXGetObjectClass ( (Object)input ) == CLASS_FIELD );
2077     DXASSERTGOTO ( ( arg != ERROR ) && ( args == sizeof(int) ) );
2078 
2079     option = *((int *)arg);
2080 
2081     if ( ( ERROR == ( output = DXCopy ( (Object)input, COPY_HEADER ) ) )
2082          ||
2083          !DXInvalidateConnections ( (Object)output ) )
2084         goto error;
2085 
2086     if ( DXEmptyField ( (Field) output ) )
2087        return (Field) output;
2088 
2089     if ( !DXExists    ( output, "neighbors" ) &&
2090          !DXNeighbors ( (Field)output       ) &&
2091          ( DXGetError() != ERROR_NONE ) )
2092         goto error;
2093 
2094     if ( ( ERROR == ( input_info = _dxf_InMemory ( (Field)output ) ) ) )
2095         goto error;
2096 
2097     if ( input_info->std_comps[(int)POSITIONS] == NULL )
2098         DXErrorGoto3
2099             ( ERROR_DATA_INVALID,
2100               "#10250", /*%s is missing %s component*/
2101               "'input' parameter",
2102               "\"positions\"" );
2103 
2104     if ( input_info->std_comps[(int)CONNECTIONS] == NULL )
2105         DXErrorGoto3
2106             ( ERROR_DATA_INVALID,
2107               "#10250", /*%s is missing %s component*/
2108               "'input' parameter",
2109               "\"connections\"" );
2110 
2111     if ( LINES == input_info->std_comps[(int)CONNECTIONS]->element_type )
2112         DXErrorGoto2
2113             ( ERROR_DATA_INVALID,
2114               "#10340", /* %s must be 2D or 3D */
2115               "\"connections\"" );
2116 
2117     /*p_info = (array_info) &(input_info->std_comps[(int)POSITIONS]->array);*/
2118     c_info = (array_info) &(input_info->std_comps[(int)CONNECTIONS]->array);
2119 
2120     if ( !_dxf_SetIterator ( input_info->std_comps[(int)CONNECTIONS] ) )
2121         goto error;
2122 
2123     if ( ( option == 1 )
2124          &&
2125          ( NULL == input_info->std_comps[(int)INVALID_CONNECTIONS] ) )
2126         option = 0;
2127 
2128     if ( ( option == 1 )
2129          &&
2130          ( ERROR == ( i_handle = DXCreateInvalidComponentHandle
2131                                      ( (Object)input_info->field,
2132                                        NULL, "connections" ) ) ) )
2133         goto error;
2134 
2135     if ( ( CLASS_MESHARRAY == c_info->class )
2136          &&
2137          ( TTRUE == ((mesh_array_info)c_info)->grid )
2138          &&
2139          ( 0 == option ) )
2140     {
2141         if ( ( ERROR == ( output = (Object) regular_boundary ( input_info ) ) )
2142              &&
2143              ( DXGetError() != ERROR_NONE ) )
2144             goto error;
2145     }
2146     else
2147     {
2148         if ( ( ERROR == ( output = (Object) irregular_boundary
2149                                               ( input_info, i_handle ) ) )
2150              &&
2151              ( DXGetError() != ERROR_NONE ) )
2152             goto error;
2153     }
2154 
2155     DXFreeInvalidComponentHandle ( i_handle );  i_handle = NULL;
2156 
2157     if ( !_dxf_FreeInMemory ( input_info ) ) goto error;   input_info = NULL;
2158 
2159     return (Field) output;
2160 
2161     error:
2162         DXDelete          ( output );       output     = NULL;
2163         _dxf_FreeInMemory ( input_info );   input_info = NULL;
2164 
2165         DXASSERT ( DXGetError() != ERROR_NONE );
2166         return ERROR;
2167 }
2168