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