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
9 #include <dxconfig.h>
10 #include <dx/dx.h>
11
12
13 #include <stdio.h>
14 #include <math.h>
15 #include <string.h>
16 #include "trisRI2DClass.h"
17
18 #define WALK_LENGTH 5
19
20 #define FALSE 0
21 #define TRUE 1
22
23 static Error _dxfInitializeTask(Pointer);
24 static Error _dxfInitialize(TrisRI2DInterpolator);
25 static int _dxftriangular_coords(float *, float *,
26 float *, float *, TriCoord *, float);
27 static int _dxfCleanup(TrisRI2DInterpolator);
28 static int _dxftriExit(int, TriCoord *, int *);
29 static int _dxfTrisWalk(TrisRI2DInterpolator, float *, int, TriCoord *);
30 static int _dxfTrisSearch(TrisRI2DInterpolator, float *, int, TriCoord *, int);
31
32 int
_dxfRecognizeTrisRI2D(Field field)33 _dxfRecognizeTrisRI2D(Field field)
34 {
35 Array array;
36 Type t;
37 Category c;
38
39 CHECK(field, CLASS_FIELD);
40
41 ELT_TYPECHECK(field, "triangles");
42
43 array = (Array)DXGetComponentValue(field, "positions");
44 if (!array)
45 {
46 DXSetError(ERROR_MISSING_DATA, "#10240", "positions");
47 return 0;
48 }
49
50 DXGetArrayInfo(array, NULL, &t, &c, NULL, NULL);
51
52 if (c != CATEGORY_REAL)
53 {
54 DXSetError(ERROR_DATA_INVALID, "#11150", "connections");
55 return 0;
56 }
57
58 array = (Array)DXGetComponentValue(field, "connections");
59 if (!array)
60 {
61 DXSetError(ERROR_MISSING_DATA, "#10240", "connections");
62 return 0;
63 }
64
65 DXGetArrayInfo(array, NULL, &t, &c, NULL, NULL);
66
67 if (t != TYPE_INT || c != CATEGORY_REAL)
68 {
69 DXSetError(ERROR_DATA_INVALID, "#11450");
70 return 0;
71 }
72
73 return 1;
74 }
75
76 TrisRI2DInterpolator
_dxfNewTrisRI2DInterpolator(Field field,enum interp_init initType,double fuzz,Matrix * m)77 _dxfNewTrisRI2DInterpolator(Field field,
78 enum interp_init initType, double fuzz, Matrix *m)
79 {
80 return (TrisRI2DInterpolator)_dxf_NewTrisRI2DInterpolator(field,
81 initType, fuzz, m, &_dxdtrisri2dinterpolator_class);
82 }
83
84 TrisRI2DInterpolator
_dxf_NewTrisRI2DInterpolator(Field field,enum interp_init initType,float fuzz,Matrix * m,struct trisri2dinterpolator_class * class)85 _dxf_NewTrisRI2DInterpolator(Field field,
86 enum interp_init initType, float fuzz, Matrix *m,
87 struct trisri2dinterpolator_class *class)
88 {
89 TrisRI2DInterpolator ti;
90 float *mm, *MM;
91
92 ti = (TrisRI2DInterpolator)_dxf_NewFieldInterpolator(field, fuzz, m,
93 (struct fieldinterpolator_class *)class);
94
95 if (! ti)
96 return NULL;
97
98 mm = ((Interpolator)ti)->min;
99 MM = ((Interpolator)ti)->max;
100
101 if (((MM[0] - mm[0]) * (MM[1] - mm[1])) == 0.0)
102 {
103 DXDelete((Object)ti);
104 return NULL;
105 }
106
107
108 ti->pArray = NULL;
109 ti->pHandle = NULL;
110 ti->dArray = NULL;
111 ti->dHandle = NULL;
112 ti->tArray = NULL;
113 ti->nArray = NULL;
114 ti->grid = NULL;
115
116 ti->hint = -1;
117
118 if (initType == INTERP_INIT_PARALLEL)
119 {
120 if (! DXAddTask(_dxfInitializeTask, (Pointer)&ti, sizeof(ti), 1.0))
121 {
122 DXDelete((Object)ti);
123 return NULL;
124 }
125
126 }
127 else if (initType == INTERP_INIT_IMMEDIATE)
128 {
129 if (! _dxfInitialize(ti))
130 {
131 DXDelete((Object)ti);
132 return NULL;
133 }
134 }
135
136 return ti;
137 }
138
139 static Error
_dxfInitializeTask(Pointer p)140 _dxfInitializeTask(Pointer p)
141 {
142 return _dxfInitialize(*(TrisRI2DInterpolator *)p);
143 }
144
145 static Error
_dxfInitialize(TrisRI2DInterpolator ti)146 _dxfInitialize(TrisRI2DInterpolator ti)
147 {
148 Field field;
149 Type dataType;
150 Category dataCategory;
151 int i;
152 int *tri;
153 float len, area;
154
155 ti->fieldInterpolator.initialized = 1;
156
157 field = (Field)((Interpolator)ti)->dataObject;
158
159 /*
160 * De-reference data
161 */
162 ti->dArray = (Array)DXGetComponentValue(field, "data");
163 if (!ti->dArray)
164 {
165 DXSetError(ERROR_MISSING_DATA, "#10240", "data");
166 return ERROR;
167 }
168 DXReference((Object)ti->dArray);
169
170 DXGetArrayInfo(ti->dArray, NULL, &((Interpolator)ti)->type,
171 &((Interpolator)ti)->category,
172 &((Interpolator)ti)->rank, ((Interpolator)ti)->shape);
173
174 ti->dHandle = DXCreateArrayHandle(ti->dArray);
175 if (! ti->dHandle)
176 return ERROR;
177
178
179 /*
180 * Get the grid.
181 */
182 ti->pArray = (Array)DXGetComponentValue(field, "positions");
183 if (!ti->pArray)
184 {
185 DXSetError(ERROR_MISSING_DATA, "#10240", "positions");
186 return ERROR;
187 }
188 DXReference((Object)ti->pArray);
189
190 ti->pHandle = DXCreateArrayHandle(ti->pArray);
191 if (! ti->pHandle)
192 return ERROR;
193
194 /*
195 * Get the triangles.
196 */
197 ti->tArray = (Array)DXGetComponentValue(field, "connections");
198 if (!ti->tArray)
199 {
200 DXSetError(ERROR_MISSING_DATA, "#10240", "connections");
201 return ERROR;
202 }
203 DXReference((Object)ti->tArray);
204
205 DXGetArrayInfo(ti->tArray, &ti->nTriangles, NULL, NULL, NULL, NULL);
206
207 /*
208 * get info about data values
209 */
210 DXGetArrayInfo(ti->dArray, NULL, &dataType, &dataCategory, NULL, NULL);
211
212 /*
213 * Don't worry about maintaining shape of input; just determine how
214 * many values to interpolate.
215 */
216 ti->nElements = DXGetItemSize(ti->dArray) / DXTypeSize(dataType);
217
218 if (ti->fieldInterpolator.localized)
219 ti->triangles = (Triangle *)DXGetArrayDataLocal(ti->tArray);
220 else
221 ti->triangles = (Triangle *)DXGetArrayData(ti->tArray);
222
223 if (! ti->triangles)
224 return ERROR;
225
226 /*
227 * Get the neighbors
228 */
229 ti->nArray =
230 DXNeighbors((Field)(ti->fieldInterpolator.interpolator.dataObject));
231 if (! ti->nArray)
232 return ERROR;
233
234 DXReference((Object)ti->nArray);
235
236 if (ti->fieldInterpolator.localized)
237 ti->neighbors = (Triangle *)DXGetArrayDataLocal(ti->nArray);
238 else
239 ti->neighbors = (Triangle *)DXGetArrayData(ti->nArray);
240
241 if (! ti->neighbors)
242 return ERROR;
243
244 if (ti->nTriangles)
245 {
246 area = (((Interpolator)ti)->max[0] - ((Interpolator)ti)->min[0]) *
247 (((Interpolator)ti)->max[1] - ((Interpolator)ti)->min[1]);
248
249 area /= ti->nTriangles;
250
251 len = sqrt(area);
252
253 ti->fieldInterpolator.fuzz *= len;
254 }
255
256 /*
257 * Create the search grid
258 */
259 ti->grid = _dxfMakeSearchGrid(((Interpolator)ti)->max,
260 ((Interpolator)ti)->min, ti->nTriangles, 2);
261 if (! ti->grid)
262 return ERROR;
263
264 tri = (int *)ti->triangles;
265
266 for (i = 0; i < ti->nTriangles; i++)
267 {
268 float *points[3], pbuf[6];
269 register int j;
270
271 for (j = 0; j < 3; j++)
272 points[j] = (float *)
273 DXGetArrayEntry(ti->pHandle, *tri++, (Pointer)(pbuf+2*j));
274
275 _dxfAddItemToSearchGrid(ti->grid, points, 3, i);
276 }
277
278 return OK;
279 }
280
281 Error
_dxfTrisRI2DInterpolator_Delete(TrisRI2DInterpolator ti)282 _dxfTrisRI2DInterpolator_Delete(TrisRI2DInterpolator ti)
283 {
284 _dxfCleanup(ti);
285 return _dxfFieldInterpolator_Delete((FieldInterpolator) ti);
286 }
287
288 int
_dxfTrisRI2DInterpolator_PrimitiveInterpolate(TrisRI2DInterpolator ti,int * n,float ** points,Pointer * values,int fuzzFlag)289 _dxfTrisRI2DInterpolator_PrimitiveInterpolate(TrisRI2DInterpolator ti,
290 int *n, float **points, Pointer *values, int fuzzFlag)
291 {
292 int primNum;
293 TriCoord triCoord;
294 Triangle *tri;
295 int i;
296 int found;
297 Pointer v;
298 float *p;
299 int dep;
300 int itemSize;
301 InvalidComponentHandle icH = ((FieldInterpolator)ti)->invCon;
302 char *dbuf = NULL;
303 Matrix *xform;
304
305 if (! ti->fieldInterpolator.initialized)
306 {
307 if (! _dxfInitialize(ti))
308 {
309 _dxfCleanup(ti);
310 return ERROR;
311 }
312
313 ti->fieldInterpolator.initialized = 1;
314 }
315
316 dep = ti->fieldInterpolator.data_dependency;
317 itemSize = DXGetItemSize(ti->dArray);
318
319 dbuf = (char *)DXAllocate(3*itemSize);
320 if (! dbuf)
321 return ERROR;
322
323 if (((FieldInterpolator)ti)->xflag)
324 xform = &(((FieldInterpolator)ti)->xform);
325 else
326 xform = NULL;
327
328 v = *values;
329 p = (float *)*points;
330
331 /*
332 * For each point in the input, attempt to interpolate the point.
333 * When a point cannot be interpolated, quit.
334 */
335 while(*n != 0)
336 {
337 float xpt[2];
338 float *pPtr;
339
340 if (xform)
341 {
342 xpt[0] = p[0]*xform->A[0][0] +
343 p[1]*xform->A[1][0] +
344 xform->b[0];
345
346 xpt[1] = p[0]*xform->A[0][1] +
347 p[1]*xform->A[1][1] +
348 xform->b[1];
349 pPtr = xpt;
350 }
351 else
352 pPtr = p;
353
354
355 found = -1;
356
357 /*
358 * Check the hint first, if one exists...
359 */
360 if (ti->hint != -1)
361 found = _dxfTrisWalk(ti, pPtr, ti->hint, &triCoord);
362
363 /*
364 * If it wasn't found, try the search grid
365 */
366 if (found == -1)
367 {
368 _dxfInitGetSearchGrid(ti->grid, (float *)pPtr);
369 while((primNum = _dxfGetNextSearchGrid(ti->grid)) != -1 && found == -1)
370 found = _dxfTrisSearch(ti,
371 pPtr, primNum, &triCoord, fuzzFlag);
372 }
373
374 if (found == -1 || (icH && DXIsElementInvalid(icH, found)))
375 break;
376
377 ti->hint = found;
378
379 #define INTERPOLATE(type, round) \
380 { \
381 type *d0, *d1, *d2, *r; \
382 \
383 tri = ti->triangles + found; \
384 r = (type *)v; \
385 \
386 d0 = (type *)DXGetArrayEntry(ti->dHandle, tri->p, \
387 (Pointer)dbuf); \
388 d1 = (type *)DXGetArrayEntry(ti->dHandle, tri->q, \
389 (Pointer)(dbuf+itemSize)); \
390 d2 = (type *)DXGetArrayEntry(ti->dHandle, tri->r, \
391 (Pointer)(dbuf+2*itemSize)); \
392 for (i = 0; i < ti->nElements; i++) \
393 *r++ = (*d0++ * triCoord.p) + \
394 (*d1++ * triCoord.q) + \
395 (*d2++ * triCoord.r) + round; \
396 \
397 v = (Pointer)r; \
398 }
399
400 if (((FieldInterpolator)ti)->cstData)
401 {
402 memcpy(v, ((FieldInterpolator)ti)->cstData, itemSize);
403 v = (Pointer)(((char *)v) + itemSize);
404 }
405 else if (dep == DATA_POSITIONS_DEPENDENT)
406 {
407 Type dataType;
408
409 if ((dataType = ((Interpolator)ti)->type) == TYPE_FLOAT)
410 {
411 INTERPOLATE(float, 0.0);
412 }
413 else if (dataType == TYPE_DOUBLE)
414 {
415 INTERPOLATE(double, 0.0);
416 }
417 else if (dataType == TYPE_INT)
418 {
419 INTERPOLATE(int, 0.5);
420 }
421 else if (dataType == TYPE_SHORT)
422 {
423 INTERPOLATE(short, 0.5);
424 }
425 else if (dataType == TYPE_USHORT)
426 {
427 INTERPOLATE(ushort, 0.5);
428 }
429 else if (dataType == TYPE_UINT)
430 {
431 INTERPOLATE(uint, 0.5);
432 }
433 else if (dataType == TYPE_BYTE)
434 {
435 INTERPOLATE(byte, 0.5);
436 }
437 else if (dataType == TYPE_UBYTE)
438 {
439 INTERPOLATE(ubyte, 0.5);
440 }
441 else
442 {
443 INTERPOLATE(unsigned char, 0.5);
444 }
445 }
446 else
447 {
448 memcpy(v, DXGetArrayEntry(ti->dHandle,
449 found, dbuf), itemSize);
450 v = (Pointer)(((char *)v) + itemSize);
451 }
452
453
454 /*
455 * Only use fuzz on first point
456 */
457 fuzzFlag = FUZZ_OFF;
458
459 p += 2;
460 *n -= 1;
461 }
462
463 *values = v;
464 *points = (float *)p;
465
466 return OK;
467 }
468
469 static int
_dxfCleanup(TrisRI2DInterpolator ti)470 _dxfCleanup(TrisRI2DInterpolator ti)
471 {
472 if (ti->fieldInterpolator.localized)
473 {
474 if (ti->neighbors)
475 DXFreeArrayDataLocal(ti->nArray, (Pointer)ti->neighbors);
476 if (ti->triangles)
477 DXFreeArrayDataLocal(ti->tArray, (Pointer)ti->triangles);
478 }
479
480 ti->neighbors = NULL;
481 ti->triangles = NULL;
482
483 if (ti->pHandle)
484 {
485 DXFreeArrayHandle(ti->pHandle);
486 ti->pHandle = NULL;
487 }
488
489 if (ti->dHandle)
490 {
491 DXFreeArrayHandle(ti->dHandle);
492 ti->dHandle = NULL;
493 }
494
495 if (ti->dArray)
496 {
497 DXDelete((Object)ti->dArray);
498 ti->dArray = NULL;
499 }
500
501 if (ti->pArray)
502 {
503 DXDelete((Object)ti->pArray);
504 ti->pArray = NULL;
505 }
506
507 if (ti->nArray)
508 {
509 DXDelete((Object)ti->nArray);
510 ti->nArray = NULL;
511 }
512
513 if (ti->tArray)
514 {
515 DXDelete((Object)ti->tArray);
516 ti->tArray = NULL;
517 }
518
519 if (ti->grid)
520 {
521 _dxfFreeSearchGrid(ti->grid);
522 ti->grid = NULL;
523 }
524
525 return OK;
526 }
527
528 #define ON_EDGE(q, r, s) \
529 (((q) == 0.0) && ((((r) <= 0.0) && ((s) <= 0.0)) || (((r) >= 0.0) && ((s) >= 0.0))))
530
_dxftriangular_coords(float * pt,float * p0,float * p1,float * p2,TriCoord * b,float fuzz)531 static int _dxftriangular_coords (float *pt, float *p0,
532 float *p1, float *p2, TriCoord *b, float fuzz)
533 {
534 double a, a0, a1, a2;
535 double x, x0, x1, x2;
536 double y, y0, y1, y2;
537
538 x = pt[0]; y = pt[1];
539 x0 = p0[0]; y0 = p0[1];
540 x1 = p1[0]; y1 = p1[1];
541 x2 = p2[0]; y2 = p2[1];
542
543 a = (x0*y1 + x1*y2 + x2*y0 - y0*x1 - y1*x2 - y2*x0) / 2.0;
544
545 a0 = (x *y1 + x1*y2 + x2*y - y *x1 - y1*x2 - y2*x ) / 2.0;
546 a1 = (x0*y + x *y2 + x2*y0 - y0*x - y *x2 - y2*x0) / 2.0;
547 a2 = (x0*y1 + x1*y + x *y0 - y0*x1 - y1*x - y *x0) / 2.0;
548
549 b->p = a0 / a;
550 b->q = a1 / a;
551 b->r = a2 / a;
552
553 if (ON_EDGE(a0, a1, a2) || ON_EDGE(a1, a2, a0) || ON_EDGE(a2, a0, a1))
554 return 0;
555
556 if ((b->p >= 0.0 && b->q >= 0.0 && b->r >= 0.0) ||
557 (b->p <= 0.0 && b->q <= 0.0 && b->r <= 0.0))
558 {
559 return 0;
560 }
561 else if ((b->p >= -fuzz && b->q >= -fuzz && b->r >= -fuzz) ||
562 (b->p <= fuzz && b->q <= fuzz && b->r <= fuzz))
563 {
564 if (a > 0)
565 return 2;
566 else
567 return -2;
568 }
569 else if (a > 0)
570 {
571 return 1;
572 }
573 else
574 {
575 return -1;
576 }
577 }
578
579 static int
_dxftriExit(int side,TriCoord * be,int * face)580 _dxftriExit(int side, TriCoord *be, int *face)
581 {
582 float best; /* best choice so far */
583 int f;
584
585 best = 0;
586 f = -1;
587
588 if (side < 0)
589 {
590 if (be->p > best)
591 {
592 best = be->p;
593 f = 0;
594 }
595 if (be->q > best)
596 {
597 best = be->q;
598 f = 1;
599 }
600 if (be->r > best)
601 {
602 best = be->r;
603 f = 2;
604 }
605 }
606 else
607 {
608 if (be->p < best)
609 {
610 best = be->p;
611 f = 0;
612 }
613
614 if (be->q < best)
615 {
616 best = be->q;
617 f = 1;
618 }
619 if (be->r < best)
620 {
621 best = be->r;
622 f = 2;
623 }
624 }
625
626 if (f == -1)
627 return 0;
628
629 *face = f;
630 return 1;
631 }
632
633 static int
_dxfTrisSearch(TrisRI2DInterpolator ti,float * point,int triIndex,TriCoord * triCoord,int fuzzFlag)634 _dxfTrisSearch(TrisRI2DInterpolator ti, float *point,
635 int triIndex, TriCoord *triCoord, int fuzzFlag)
636 {
637 int face;
638 float *p0, *p1, *p2;
639 int side;
640 Triangle *tri;
641 float pbuf[6];
642
643 while (triIndex != -1)
644 {
645 tri = ti->triangles + triIndex;
646
647 p0 = (float *)DXGetArrayEntry(ti->pHandle,
648 tri->p, (Pointer)(pbuf));
649 p1 = (float *)DXGetArrayEntry(ti->pHandle,
650 tri->q, (Pointer)(pbuf+2));
651 p2 = (float *)DXGetArrayEntry(ti->pHandle,
652 tri->r, (Pointer)(pbuf+4));
653
654 side = _dxftriangular_coords(point, p0, p1, p2, triCoord,
655 ti->fieldInterpolator.fuzz);
656
657 if (side == 0)
658 {
659 return triIndex;
660 }
661
662 else if (fuzzFlag == FUZZ_ON && (side == 2 || side == -2))
663 {
664 if (!_dxftriExit(side, triCoord, &face))
665 {
666 return triIndex;
667 }
668 }
669
670 if (!_dxftriExit(side, triCoord, &face))
671 {
672 return -1;
673 }
674
675 triIndex = ((int *)(ti->neighbors))[(triIndex*3) + face];
676 };
677
678
679 return -1;
680 }
681
682 static int
_dxfTrisWalk(TrisRI2DInterpolator ti,float * point,int triIndex,TriCoord * triCoord)683 _dxfTrisWalk(TrisRI2DInterpolator ti, float *point,
684 int triIndex, TriCoord *triCoord)
685 {
686 int face;
687 float *p0, *p1, *p2;
688 int side;
689 Triangle *tri;
690 float pbuf[6];
691
692 while (triIndex != -1)
693 {
694 tri = ti->triangles + triIndex;
695
696 p0 = (float *)DXGetArrayEntry(ti->pHandle,
697 tri->p, (Pointer)(pbuf));
698 p1 = (float *)DXGetArrayEntry(ti->pHandle,
699 tri->q, (Pointer)(pbuf+2));
700 p2 = (float *)DXGetArrayEntry(ti->pHandle,
701 tri->r, (Pointer)(pbuf+4));
702
703 side = _dxftriangular_coords(point, p0, p1, p2, triCoord,
704 ti->fieldInterpolator.fuzz);
705
706 if (side == 0)
707 return triIndex;
708
709 if (!_dxftriExit(side, triCoord, &face))
710 return -1;
711
712 triIndex = ((int *)(ti->neighbors))[(triIndex*3) + face];
713 };
714
715 return -1;
716 }
717
718 Object
_dxfTrisRI2DInterpolator_Copy(TrisRI2DInterpolator old,enum _dxd_copy copy)719 _dxfTrisRI2DInterpolator_Copy(TrisRI2DInterpolator old, enum _dxd_copy copy)
720 {
721 TrisRI2DInterpolator new;
722
723 new = (TrisRI2DInterpolator)
724 _dxf_NewObject((struct object_class *)&_dxdtrisri2dinterpolator_class);
725
726 if (!(_dxf_CopyTrisRI2DInterpolator(new, old, copy)))
727 {
728 DXDelete((Object)new);
729 return NULL;
730 }
731 else
732 return (Object)new;
733 }
734
735 TrisRI2DInterpolator
_dxf_CopyTrisRI2DInterpolator(TrisRI2DInterpolator new,TrisRI2DInterpolator old,enum _dxd_copy copy)736 _dxf_CopyTrisRI2DInterpolator(TrisRI2DInterpolator new,
737 TrisRI2DInterpolator old, enum _dxd_copy copy)
738 {
739
740 if (! _dxf_CopyFieldInterpolator((FieldInterpolator)new,
741 (FieldInterpolator)old, copy))
742 return NULL;
743
744 new->nPoints = old->nPoints;
745 new->nTriangles = old->nTriangles;
746 new->nElements = old->nElements;
747 new->hint = old->hint;
748
749 if (new->fieldInterpolator.initialized)
750 {
751 new->pArray = (Array)DXReference((Object)old->pArray);
752 new->tArray = (Array)DXReference((Object)old->tArray);
753 new->dArray = (Array)DXReference((Object)old->dArray);
754 new->nArray = (Array)DXReference((Object)old->nArray);
755
756 if (new->fieldInterpolator.localized)
757 {
758 new->triangles = (Triangle *)DXGetArrayDataLocal(new->tArray);
759 new->neighbors = (Triangle *)DXGetArrayDataLocal(new->nArray);
760 }
761 else
762 {
763 new->triangles = (Triangle *)DXGetArrayData(new->tArray);
764 new->neighbors = (Triangle *)DXGetArrayData(new->nArray);
765 }
766
767 new->pHandle = DXCreateArrayHandle(new->pArray);
768 new->dHandle = DXCreateArrayHandle(new->dArray);
769 if (! new->pHandle || ! new->dHandle)
770 return NULL;
771
772 new->grid = _dxfCopySearchGrid(old->grid);
773 if (! new->grid)
774 return NULL;
775 }
776 else
777 {
778 new->pArray = NULL;
779 new->tArray = NULL;
780 new->dArray = NULL;
781 new->nArray = NULL;
782 new->pHandle = NULL;
783 new->triangles = NULL;
784 new->dHandle = NULL;
785 new->grid = NULL;
786 }
787
788 if (DXGetError())
789 return NULL;
790
791 return new;
792 }
793
794 Interpolator
_dxfTrisRI2DInterpolator_LocalizeInterpolator(TrisRI2DInterpolator ti)795 _dxfTrisRI2DInterpolator_LocalizeInterpolator(TrisRI2DInterpolator ti)
796 {
797 if (ti->fieldInterpolator.localized)
798 return (Interpolator)ti;
799
800 ti->fieldInterpolator.localized = 1;
801
802 if (ti->fieldInterpolator.initialized)
803 {
804 ti->triangles = (Triangle *)DXGetArrayDataLocal(ti->tArray);
805 ti->neighbors = (Triangle *)DXGetArrayDataLocal(ti->nArray);
806 }
807
808 if (DXGetError())
809 return NULL;
810 else
811 return (Interpolator)ti;
812 }
813