1 /* dskmi2.f -- translated by f2c (version 19980913).
2    You must link the resulting object file with the libraries:
3 	-lf2c -lm   (in that order)
4 */
5 
6 #include "f2c.h"
7 
8 /* Table of constant values */
9 
10 static integer c_b14 = 16000002;
11 static integer c_b20 = 32000000;
12 
13 /* $Procedure DSKMI2 ( DSK, make spatial index for type 2 segment ) */
dskmi2_(integer * nv,doublereal * vrtces,integer * np,integer * plates,doublereal * finscl,integer * corscl,integer * worksz,integer * voxpsz,integer * voxlsz,logical * makvtl,integer * spxisz,integer * work,doublereal * spaixd,integer * spaixi)14 /* Subroutine */ int dskmi2_(integer *nv, doublereal *vrtces, integer *np,
15 	integer *plates, doublereal *finscl, integer *corscl, integer *worksz,
16 	 integer *voxpsz, integer *voxlsz, logical *makvtl, integer *spxisz,
17 	integer *work, doublereal *spaixd, integer *spaixi)
18 {
19     /* System generated locals */
20     integer spaixi_dim1, i__1, i__2, i__3, i__4, i__5, i__6;
21 
22     /* Builtin functions */
23     integer s_rnge(char *, integer, char *, integer);
24 
25     /* Local variables */
26     extern /* Subroutine */ int zzmkspin_(integer *, integer *, doublereal *,
27 	    doublereal *, integer *, integer *, integer *, integer *, integer
28 	    *, integer *, doublereal *, doublereal *, integer *, integer *,
29 	    integer *, integer *, integer *, doublereal *, integer *);
30     integer i__, j;
31     extern /* Subroutine */ int chkin_(char *, ftnlen), zzvrtplt_(integer *,
32 	    integer *, integer *, integer *, integer *, integer *, integer *,
33 	    integer *, integer *), errdp_(char *, doublereal *, ftnlen);
34     extern logical failed_(void), return_(void);
35     integer nshift, nvxtot, reqsiz, vtlidx, vtpidx, vtxlsz, vxlidx, vxpidx;
36     extern /* Subroutine */ int setmsg_(char *, ftnlen), sigerr_(char *,
37 	    ftnlen), chkout_(char *, ftnlen), errint_(char *, integer *,
38 	    ftnlen);
39 
40 /* $ Abstract */
41 
42 /*     Make spatial index for a DSK type 2 segment. The index is */
43 /*     returned as a pair of arrays, one of type INTEGER and one of type */
44 /*     DOUBLE PRECISION. These arrays are suitable for use with the DSK */
45 /*     type 2 writer DSKW02. */
46 
47 /* $ Disclaimer */
48 
49 /*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
50 /*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
51 /*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
52 /*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
53 /*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
54 /*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
55 /*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
56 /*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
57 /*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
58 /*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */
59 
60 /*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
61 /*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
62 /*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
63 /*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
64 /*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
65 /*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */
66 
67 /*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
68 /*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
69 /*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
70 /*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */
71 
72 /* $ Required_Reading */
73 
74 /*     DAS */
75 /*     DSK */
76 
77 /* $ Keywords */
78 
79 /*     DAS */
80 /*     DSK */
81 /*     FILES */
82 /*     PLATE */
83 /*     TOPOGRAPHY */
84 
85 /* $ Declarations */
86 
87 /*     Include file dskdsc.inc */
88 
89 /*     This include file declares parameters for DSK segment descriptors. */
90 
91 /* -       SPICELIB Version 1.0.0 08-FEB-2017 (NJB) */
92 
93 /*           Updated version info. */
94 
95 /*           22-JAN-2016 (NJB) */
96 
97 /*              Added parameter for data class 2. Changed name of data */
98 /*              class 1 parameter. Corrected data class descriptions. */
99 
100 /*           13-MAY-2010 (NJB) */
101 
102 /*              Descriptor now contains two ID codes, one for the */
103 /*              surface, one for the associated ephemeris object. This */
104 /*              supports association of multiple surfaces with one */
105 /*              ephemeris object without creating file management */
106 /*              issues. */
107 
108 /*              Room was added for coordinate system definition */
109 /*              parameters. */
110 
111 /*               Flag arrays and model ID/component entries were deleted. */
112 
113 /*            11-SEP-2008 (NJB) */
114 
115 
116 /*     DSK segment descriptors are implemented as an array of d.p. */
117 /*     numbers.  Note that each integer descriptor datum occupies one */
118 /*     d.p. value. */
119 
120 
121 
122 
123 /*     Segment descriptor parameters */
124 
125 /*     Each segment descriptor occupies a contiguous */
126 /*     range of DAS d.p. addresses. */
127 
128 /*        The DSK segment descriptor layout is: */
129 
130 /*           +---------------------+ */
131 /*           | Surface ID code     | */
132 /*           +---------------------+ */
133 /*           | Center ID code      | */
134 /*           +---------------------+ */
135 /*           | Data class code     | */
136 /*           +---------------------+ */
137 /*           | Data type           | */
138 /*           +---------------------+ */
139 /*           | Ref frame code      | */
140 /*           +---------------------+ */
141 /*           | Coord sys code      | */
142 /*           +---------------------+ */
143 /*           | Coord sys parameters|  {10 elements} */
144 /*           +---------------------+ */
145 /*           | Min coord 1         | */
146 /*           +---------------------+ */
147 /*           | Max coord 1         | */
148 /*           +---------------------+ */
149 /*           | Min coord 2         | */
150 /*           +---------------------+ */
151 /*           | Max coord 2         | */
152 /*           +---------------------+ */
153 /*           | Min coord 3         | */
154 /*           +---------------------+ */
155 /*           | Max coord 3         | */
156 /*           +---------------------+ */
157 /*           | Start time          | */
158 /*           +---------------------+ */
159 /*           | Stop time           | */
160 /*           +---------------------+ */
161 
162 /*     Parameters defining offsets for segment descriptor elements */
163 /*     follow. */
164 
165 
166 /*     Surface ID code: */
167 
168 
169 /*     Central ephemeris object NAIF ID: */
170 
171 
172 /*     Data class: */
173 
174 /*     The "data class" is a code indicating the category of */
175 /*     data contained in the segment. */
176 
177 
178 /*     Data type: */
179 
180 
181 /*     Frame ID: */
182 
183 
184 /*     Coordinate system code: */
185 
186 
187 /*     Coordinate system parameter start index: */
188 
189 
190 /*     Number of coordinate system parameters: */
191 
192 
193 /*     Ranges for coordinate bounds: */
194 
195 
196 /*     Coverage time bounds: */
197 
198 
199 /*     Descriptor size (24): */
200 
201 
202 /*     Data class values: */
203 
204 /*        Class 1 indicates a surface that can be represented as a */
205 /*                single-valued function of its domain coordinates. */
206 
207 /*                An example is a surface defined by a function that */
208 /*                maps each planetodetic longitude and latitude pair to */
209 /*                a unique altitude. */
210 
211 
212 /*        Class 2 indicates a general surface. Surfaces that */
213 /*                have multiple points for a given pair of domain */
214 /*                coordinates---for example, multiple radii for a given */
215 /*                latitude and longitude---belong to class 2. */
216 
217 
218 
219 /*     Coordinate system values: */
220 
221 /*        The coordinate system code indicates the system to which the */
222 /*        tangential coordinate bounds belong. */
223 
224 /*        Code 1 refers to the planetocentric latitudinal system. */
225 
226 /*        In this system, the first tangential coordinate is longitude */
227 /*        and the second tangential coordinate is latitude. The third */
228 /*        coordinate is radius. */
229 
230 
231 
232 /*        Code 2 refers to the cylindrical system. */
233 
234 /*        In this system, the first tangential coordinate is radius and */
235 /*        the second tangential coordinate is longitude. The third, */
236 /*        orthogonal coordinate is Z. */
237 
238 
239 
240 /*        Code 3 refers to the rectangular system. */
241 
242 /*        In this system, the first tangential coordinate is X and */
243 /*        the second tangential coordinate is Y. The third, */
244 /*        orthogonal coordinate is Z. */
245 
246 
247 
248 /*        Code 4 refers to the planetodetic/geodetic system. */
249 
250 /*        In this system, the first tangential coordinate is longitude */
251 /*        and the second tangential coordinate is planetodetic */
252 /*        latitude. The third, orthogonal coordinate is altitude. */
253 
254 
255 
256 /*     End of include file dskdsc.inc */
257 
258 
259 /*     Include file dsk02.inc */
260 
261 /*     This include file declares parameters for DSK data type 2 */
262 /*     (plate model). */
263 
264 /* -       SPICELIB Version 1.0.0 08-FEB-2017 (NJB) */
265 
266 /*          Updated version info. */
267 
268 /*           22-JAN-2016 (NJB) */
269 
270 /*              Now includes spatial index parameters. */
271 
272 /*           26-MAR-2015 (NJB) */
273 
274 /*              Updated to increase MAXVRT to 16000002. MAXNPV */
275 /*              has been changed to (3/2)*MAXPLT. Set MAXVOX */
276 /*              to 100000000. */
277 
278 /*           13-MAY-2010 (NJB) */
279 
280 /*              Updated to reflect new no-record design. */
281 
282 /*           04-MAY-2010 (NJB) */
283 
284 /*              Updated for new type 2 segment design. Now uses */
285 /*              a local parameter to represent DSK descriptor */
286 /*              size (NB). */
287 
288 /*           13-SEP-2008 (NJB) */
289 
290 /*              Updated to remove albedo information. */
291 /*              Updated to use parameter for DSK descriptor size. */
292 
293 /*           27-DEC-2006 (NJB) */
294 
295 /*              Updated to remove minimum and maximum radius information */
296 /*              from segment layout.  These bounds are now included */
297 /*              in the segment descriptor. */
298 
299 /*           26-OCT-2006 (NJB) */
300 
301 /*              Updated to remove normal, center, longest side, albedo, */
302 /*              and area keyword parameters. */
303 
304 /*           04-AUG-2006 (NJB) */
305 
306 /*              Updated to support coarse voxel grid.  Area data */
307 /*              have now been removed. */
308 
309 /*           10-JUL-2006 (NJB) */
310 
311 
312 /*     Each type 2 DSK segment has integer, d.p., and character */
313 /*     components.  The segment layout in DAS address space is as */
314 /*     follows: */
315 
316 
317 /*        Integer layout: */
318 
319 /*           +-----------------+ */
320 /*           | NV              |  (# of vertices) */
321 /*           +-----------------+ */
322 /*           | NP              |  (# of plates ) */
323 /*           +-----------------+ */
324 /*           | NVXTOT          |  (total number of voxels) */
325 /*           +-----------------+ */
326 /*           | VGREXT          |  (voxel grid extents, 3 integers) */
327 /*           +-----------------+ */
328 /*           | CGRSCL          |  (coarse voxel grid scale, 1 integer) */
329 /*           +-----------------+ */
330 /*           | VOXNPT          |  (size of voxel-plate pointer list) */
331 /*           +-----------------+ */
332 /*           | VOXNPL          |  (size of voxel-plate list) */
333 /*           +-----------------+ */
334 /*           | VTXNPL          |  (size of vertex-plate list) */
335 /*           +-----------------+ */
336 /*           | PLATES          |  (NP 3-tuples of vertex IDs) */
337 /*           +-----------------+ */
338 /*           | VOXPTR          |  (voxel-plate pointer array) */
339 /*           +-----------------+ */
340 /*           | VOXPLT          |  (voxel-plate list) */
341 /*           +-----------------+ */
342 /*           | VTXPTR          |  (vertex-plate pointer array) */
343 /*           +-----------------+ */
344 /*           | VTXPLT          |  (vertex-plate list) */
345 /*           +-----------------+ */
346 /*           | CGRPTR          |  (coarse grid occupancy pointers) */
347 /*           +-----------------+ */
348 
349 
350 
351 /*        D.p. layout: */
352 
353 /*           +-----------------+ */
354 /*           | DSK descriptor  |  DSKDSZ elements */
355 /*           +-----------------+ */
356 /*           | Vertex bounds   |  6 values (min/max for each component) */
357 /*           +-----------------+ */
358 /*           | Voxel origin    |  3 elements */
359 /*           +-----------------+ */
360 /*           | Voxel size      |  1 element */
361 /*           +-----------------+ */
362 /*           | Vertices        |  3*NV elements */
363 /*           +-----------------+ */
364 
365 
366 /*     This local parameter MUST be kept consistent with */
367 /*     the parameter DSKDSZ which is declared in dskdsc.inc. */
368 
369 
370 /*     Integer item keyword parameters used by fetch routines: */
371 
372 
373 /*     Double precision item keyword parameters used by fetch routines: */
374 
375 
376 /*     The parameters below formerly were declared in pltmax.inc. */
377 
378 /*     Limits on plate model capacity: */
379 
380 /*     The maximum number of bodies, vertices and */
381 /*     plates in a plate model or collective thereof are */
382 /*     provided here. */
383 
384 /*     These values can be used to dimension arrays, or to */
385 /*     use as limit checks. */
386 
387 /*     The value of MAXPLT is determined from MAXVRT via */
388 /*     Euler's Formula for simple polyhedra having triangular */
389 /*     faces. */
390 
391 /*     MAXVRT is the maximum number of vertices the triangular */
392 /*            plate model software will support. */
393 
394 
395 /*     MAXPLT is the maximum number of plates that the triangular */
396 /*            plate model software will support. */
397 
398 
399 /*     MAXNPV is the maximum allowed number of vertices, not taking into */
400 /*     account shared vertices. */
401 
402 /*     Note that this value is not sufficient to create a vertex-plate */
403 /*     mapping for a model of maximum plate count. */
404 
405 
406 /*     MAXVOX is the maximum number of voxels. */
407 
408 
409 /*     MAXCGR is the maximum size of the coarse voxel grid. */
410 
411 
412 /*     MAXEDG is the maximum allowed number of vertex or plate */
413 /*     neighbors a vertex may have. */
414 
415 /*     DSK type 2 spatial index parameters */
416 /*     =================================== */
417 
418 /*        DSK type 2 spatial index integer component */
419 /*        ------------------------------------------ */
420 
421 /*           +-----------------+ */
422 /*           | VGREXT          |  (voxel grid extents, 3 integers) */
423 /*           +-----------------+ */
424 /*           | CGRSCL          |  (coarse voxel grid scale, 1 integer) */
425 /*           +-----------------+ */
426 /*           | VOXNPT          |  (size of voxel-plate pointer list) */
427 /*           +-----------------+ */
428 /*           | VOXNPL          |  (size of voxel-plate list) */
429 /*           +-----------------+ */
430 /*           | VTXNPL          |  (size of vertex-plate list) */
431 /*           +-----------------+ */
432 /*           | CGRPTR          |  (coarse grid occupancy pointers) */
433 /*           +-----------------+ */
434 /*           | VOXPTR          |  (voxel-plate pointer array) */
435 /*           +-----------------+ */
436 /*           | VOXPLT          |  (voxel-plate list) */
437 /*           +-----------------+ */
438 /*           | VTXPTR          |  (vertex-plate pointer array) */
439 /*           +-----------------+ */
440 /*           | VTXPLT          |  (vertex-plate list) */
441 /*           +-----------------+ */
442 
443 
444 /*        Index parameters */
445 
446 
447 /*     Grid extent: */
448 
449 
450 /*     Coarse grid scale: */
451 
452 
453 /*     Voxel pointer count: */
454 
455 
456 /*     Voxel-plate list count: */
457 
458 
459 /*     Vertex-plate list count: */
460 
461 
462 /*     Coarse grid pointers: */
463 
464 
465 /*     Size of fixed-size portion of integer component: */
466 
467 
468 /*        DSK type 2 spatial index double precision component */
469 /*        --------------------------------------------------- */
470 
471 /*           +-----------------+ */
472 /*           | Vertex bounds   |  6 values (min/max for each component) */
473 /*           +-----------------+ */
474 /*           | Voxel origin    |  3 elements */
475 /*           +-----------------+ */
476 /*           | Voxel size      |  1 element */
477 /*           +-----------------+ */
478 
479 
480 
481 /*        Index parameters */
482 
483 /*     Vertex bounds: */
484 
485 
486 /*     Voxel grid origin: */
487 
488 
489 /*     Voxel size: */
490 
491 
492 /*     Size of fixed-size portion of double precision component: */
493 
494 
495 /*     The limits below are used to define a suggested maximum */
496 /*     size for the integer component of the spatial index. */
497 
498 
499 /*     Maximum number of entries in voxel-plate pointer array: */
500 
501 
502 /*     Maximum cell size: */
503 
504 
505 /*     Maximum number of entries in voxel-plate list: */
506 
507 
508 /*     Spatial index integer component size: */
509 
510 
511 /*     End of include file dsk02.inc */
512 
513 /* $ Brief_I/O */
514 
515 /*     Variable  I/O  Description */
516 /*     --------  ---  -------------------------------------------------- */
517 /*     IXDFIX     P   Size of fixed-size portion of d.p. index component. */
518 /*     IXIFIX     P   Size of fixed-size portion of integer index */
519 /*                    component. */
520 /*     NV         I   Number of vertices. */
521 /*     VRTCES     I   Vertices. */
522 /*     NP         I   Number of plates. */
523 /*     PLATES     I   Plates. */
524 /*     FINSCL     I   Fine voxel scale. */
525 /*     CORSCL     I   Coarse voxel scale. */
526 /*     WORKSZ     I   Workspace size. */
527 /*     VOXPSZ     I   Voxel-plate pointer array size. */
528 /*     VOXLSZ     I   Voxel-plate list array size. */
529 /*     MAKVTL     I   Vertex-plate list flag. */
530 /*     SPXISZ     I   Spatial index integer component size. */
531 /*     WORK       I   Workspace. */
532 /*     SPAIXD     I   Double precision component of spatial index. */
533 /*     SPAIXI     I   Integer component of spatial index. */
534 
535 /* $ Detailed_Input */
536 
537 /*     NV          is the number of vertices belonging to the input */
538 /*                 set of plates. */
539 
540 
541 /*     VRTCES      is an array of coordinates of the vertices. The Ith */
542 /*                 vertex occupies elements (1:3,I) of this array. */
543 
544 
545 /*     NP          is the number of plates in the input plate set. */
546 
547 
548 /*     PLATES      is an array representing the triangular plates of a */
549 /*                 shape model. The elements of PLATES are vertex */
550 /*                 indices; vertex indices are 1-based. The vertex */
551 /*                 indices of the Ith plate occupy elements (1:3,I) of */
552 /*                 this array. */
553 
554 
555 /*     FINSCL      is the fine voxel scale. This scale determines the */
556 /*                 edge length of the cubical voxels comprising the fine */
557 /*                 voxel grid: the edge length VOXSIZ is approximately */
558 
559 /*                     FINSCL * {average plate extent} */
560 
561 /*                 where the extents of a plate are the respective */
562 /*                 differences between the maximum and minimum */
563 /*                 coordinate values of the plate's vertices. */
564 
565 /*                 The relationship between VOXSIZ and the average plate */
566 /*                 extent is approximate because the VOXSIZ is adjusted */
567 /*                 so that each dimension of the fine voxel grid is an */
568 /*                 integer multiple of the coarse voxel scale. */
569 
570 /*                 See the Particulars section below for further */
571 /*                 information on voxel scales. */
572 
573 
574 /*     CORSCL      is the coarse voxel scale. This integer scale is the */
575 /*                 ratio of the edge length of coarse voxels to */
576 /*                 that of fine voxels. The coarse scale must be */
577 /*                 large enough so that the total number of coarse */
578 /*                 voxels does not exceed MAXCGR (see the Parameters */
579 /*                 section below). */
580 
581 
582 /*     WORKSZ      is the second dimension of the workspace array WORK. */
583 /*                 WORKSZ must be at least as large as the greater of */
584 
585 /*                    - the number of fine voxel-plate associations */
586 
587 /*                      This number is equal to */
588 
589 /*                         NP * {average number of fine voxels */
590 /*                               intersected by each plate} */
591 
592 /*                    - the number of vertex-plate associations, if */
593 /*                      the vertex-plate mapping is constructed. */
594 
595 /*                      This number is equal to */
596 
597 /*                         NV + ( 3 * NP ) */
598 
599 
600 /*     VOXPSZ      is the size of the fine voxel-plate pointer array. */
601 /*                 This array maps fine voxels to lists of plates that */
602 /*                 intersect those voxels. VOXPSZ must be at least as */
603 /*                 large as */
604 
605 /*                          3 */
606 /*                    CORSCL  * {number of non-empty coarse voxels} */
607 
608 
609 /*     VOXLSZ      is the size of the fine voxel-plate list array. This */
610 /*                 array contains, for each non-empty fine voxel, the */
611 /*                 count of plates that intersect that voxel and the */
612 /*                 IDs of those plates. VOXLSZ must be at least as large */
613 /*                 as */
614 
615 /*                         NP * {average number of fine voxels */
616 /*                               intersected by each plate} */
617 
618 /*                     +   {number of non-empty fine voxels} */
619 
620 
621 /*     MAKVTL      is a logical flag that, when set to .TRUE., indicates */
622 /*                 that a  vertex-plate association list is to be */
623 /*                 constructed. */
624 
625 /*                 The amount of workspace that is needed may depend on */
626 /*                 whether a vertex-plate association list is */
627 /*                 constructed. When this list is constructed, the size */
628 /*                 of the integer component of the spatial index is */
629 /*                 increased by the size of the list and the size of a */
630 /*                 vertex-plate pointer array; the total of these sizes */
631 /*                 is */
632 
633 /*                    ( 2 * NV ) + ( 3 * NP ) */
634 
635 
636 /*     SPXISZ      is the declared size of the output array SPAIXI. This */
637 /*                 size must be at least as large as the sum of */
638 
639 /*                    - the fixed-size part of the integer component of */
640 /*                      the index, which includes the coarse voxel grid; */
641 /*                      this value is */
642 
643 /*                         IXIFIX */
644 
645 /*                    - the size VOXPSZ of the voxel-plate pointer array */
646 
647 /*                    - the size VOXLSZ of the voxel-plate association */
648 /*                      list */
649 
650 /*                 plus, if the vertex-plate association list is */
651 /*                 constructed, */
652 
653 /*                    - the size NV of the vertex-plate pointer array */
654 
655 /*                    - the size of the vertex-plate association list; */
656 /*                      this size is */
657 
658 /*                         NV + ( 3 * NP ) */
659 
660 
661 /*     WORK        is the workspace array. The array should be declared */
662 /*                 with dimensions */
663 
664 /*                    (2, WORKSZ) */
665 
666 /*                 See the description of WORKSZ above. */
667 
668 
669 /* $ Detailed_Output */
670 
671 /*     WORK        is the workspace array, modified by the operations */
672 /*                 performed by this routine. */
673 
674 /*     SPAIXD, */
675 /*     SPAIXI      are, respectively, the double precision and integer */
676 /*                 components of the spatial index of the segment. */
677 
678 /*                 SPAIXD must be declared with size at least IXDFIX. */
679 /*                 SPAIXI must be declared with size at least SPXISZ. */
680 
681 /* $ Parameters */
682 
683 /*     IXDFIX      is the size of the double precision component of */
684 /*                 the spatial index. */
685 
686 /*     IXIFIX      is the size of the fixed-size portion of the integer */
687 /*                 component of the spatial index. */
688 
689 /*     See the include file dsk02.inc for declarations of the public DSK */
690 /*     type 2 parameters used by this routine. */
691 
692 /* $ Exceptions */
693 
694 /*     1)  If the fine voxel scale is non-positive, the error */
695 /*         SPICE(BADFINEVOXELSCALE) is signaled. */
696 
697 /*     2)  If the coarse voxel scale is less than 1, the error */
698 /*         SPICE(BADCOARSEVOXSCALE) is signaled. */
699 
700 /*     3)  If NV is less than 3 or greater than MAXVRT, the error */
701 /*         SPICE(BADVERTEXCOUNT) is signaled. */
702 
703 /*     4)  If NP is less than 1 or greater than MAXPLT, the error */
704 /*         SPICE(BADPLATECOUNT) is signaled. */
705 
706 /*     5)  If the workspace size WORKSZ is less than NP+1, the error */
707 /*         SPICE(WORKSPACETOOSMALL) is signaled. This is merely a */
708 /*         sanity check; normally the workspace will need to be */
709 /*         substantially larger than this reference value. See the */
710 /*         description of WORKSZ in the header section Detailed_Input */
711 /*         above. */
712 
713 /*     6)  If the voxel-plate pointer array size VOXPSZ is less than 1, */
714 /*         the error SPICE(PTRARRAYTOOSMALL) is signaled. This is merely */
715 /*         a sanity check; normally this pointer array will need to be */
716 /*         substantially larger than this reference value. See the */
717 /*         description of VOXPSZ in the header section Detailed_Input */
718 /*         above. */
719 
720 /*     7)  If the voxel-plate list array size VOXLSZ is less than NP+1, */
721 /*         the error SPICE(PLATELISTTOOSMALL) is signaled. This is */
722 /*         merely a sanity check; normally this array will need to be */
723 /*         substantially larger than this reference value. See the */
724 /*         description of VOXLSZ in the header section Detailed_Input */
725 /*         above. */
726 
727 /*     8)  If the size SPXISZ of the integer array SPAIXI is too small */
728 /*         to contain its constituent structures, where the sizes */
729 /*         of these structures are derived from the inputs */
730 
731 /*             NV, NP, VOXPSZ, VOXLSZ */
732 
733 /*         the error SPICE(INTINDEXTOOSMALL) will be signaled. */
734 
735 /*     9)  If there is insufficient room to create any of the data */
736 /*         structures contained in the spatial index, the error */
737 /*         will be diagnosed and signaled by a routine in the call */
738 /*         tree of this routine. */
739 
740 /* $ Files */
741 
742 /*     None. */
743 
744 /* $ Particulars */
745 
746 /*     Users planning to create DSK files should consider whether the */
747 /*     SPICE DSK creation utility MKDSK may be suitable for their needs. */
748 
749 /*     This routine supports use of the DSK type 2 segment writer DSKW02 */
750 /*     by creating the "spatial index" arrays required as inputs to that */
751 /*     routine. */
752 
753 /*     A spatial index is a group of data structures that facilitates */
754 /*     rapid high-level computations involving sets of plates. The data */
755 /*     structures created by this routine are aggregated into arrays */
756 /*     of type INTEGER and type DOUBLE PRECISION. */
757 
758 
759 /*     Voxel grids */
760 /*     =========== */
761 
762 /*     A key geometric computation---probably the most important, as it */
763 /*     serves as a foundation for other high-level computations---is */
764 /*     finding the intersection of a ray with the plate set. DSK type 2 */
765 /*     segments use data structures called "voxel grids" as part of */
766 /*     their indexing mechanism. There is a "coarse grid": a box that */
767 /*     completely encloses a DSK type 2 segment's plate set, and which */
768 /*     is composed of identically-sized cubes called "coarse voxels." */
769 /*     Each coarse voxel in composed of smaller cubes called "fine */
770 /*     voxels." When the term "voxel" is used without qualification, it */
771 /*     refers to fine voxels. */
772 
773 /*     Type 2 DSK segments contain data structures that associate plates */
774 /*     with the fine voxels intersected by those plates. These */
775 /*     structures enable the type 2 DSK software to rapidly find plates */
776 /*     in a given region of space. */
777 
778 /*     Voxel scales */
779 /*     ============ */
780 
781 /*     There are two voxel scales: */
782 
783 /*        - The coarse voxel scale is the integer ratio of the */
784 /*          edge length of a coarse voxel to the edge length of */
785 /*          a fine voxel */
786 
787 /*        - The fine voxel scale is the double precision ratio */
788 /*          of the edge length of a fine voxel to the average */
789 /*          extent of the plates in the input plate set. "Extents" */
790 /*          of a plate are the absolute values of the differences */
791 /*          between the respective maximum and minimum X, Y, and Z */
792 /*          coordinates of the plate's vertices. */
793 
794 /*     Voxel scales determine the resolution of the voxel grid. */
795 /*     Voxel scales must be chosen to satisfy size constraints and */
796 /*     provide reasonable plate lookup performance. */
797 
798 /*     The following considerations apply to spatial indexes of */
799 /*     type 2 DSK segments: */
800 
801 /*        1)  The maximum number of coarse voxels is fixed at MAXCGR */
802 /*            (declared in dsk02.inc). */
803 
804 /*        2)  If there are too few fine voxels, the average number of */
805 /*            plates per fine voxel will be very large. This largely */
806 /*            negates the performance improvement afforded by having an */
807 /*            index. Also, the number of plates per voxel may exceed */
808 /*            limits imposed by DSK subroutines that use static arrays. */
809 
810 /*        3)  If there are too many fine voxels, the average number of */
811 /*            voxels intersected by a given plate may be too large for */
812 /*            all the plate-voxel associations to be stored. In */
813 /*            addition, the time needed to examine the plate lists for */
814 /*            each voxel (including the empty ones) may become quite */
815 /*            large, again negating the value of the index. */
816 
817 /*     In many cases, voxel scales yielding optimum performance must be */
818 /*     determined by experiment. However, the following heuristics can */
819 /*     provide reasonable starting values: */
820 
821 /*        Let NP be the number of plates. Let FS be the fine voxel */
822 /*        scale. Then a reasonable value of FS may be */
823 
824 /*                   (0.25D0) */
825 /*           FS =  NP       / 8.D0 */
826 
827 /*        In general, FS should not smaller than 1. */
828 
829 
830 /* $ Examples */
831 
832 
833 /*     The numerical results shown for this example may differ across */
834 /*     platforms. The results depend on the SPICE kernels used as */
835 /*     input, the compiler and supporting libraries, and the machine */
836 /*     specific arithmetic implementation. */
837 
838 /*     1) Create a three-segment DSK file using plate model data for */
839 /*        Phobos. Use latitudinal, rectangular, and planetodetic */
840 /*        coordinates in the respective segments. This is not a */
841 /*        realistic example, but it serves to demonstrate use of */
842 /*        the supported coordinate systems. */
843 
844 /*        For simplicity, use an existing DSK file to provide the */
845 /*        input plate and vertex data. The selected input file has one */
846 /*        segment. */
847 
848 
849 /*     C */
850 /*     C     Example program for DSKW02, DSKMI2, and DSKRB2 */
851 /*     C */
852 /*     C        Create a three-segment DSK file using plate model data */
853 /*     C        for Phobos. Use latitudinal, rectangular, and */
854 /*     C        planetodetic coordinates in the respective segments. */
855 /*     C */
856 /*     C        For simplicity, use an existing DSK file to provide the */
857 /*     C        input plate and vertex data. The selected input file has */
858 /*     C        one segment. */
859 /*     C */
860 /*     C           Version 1.0.0 22-JAN-2016 (NJB) */
861 /*     C */
862 /*           PROGRAM EX1 */
863 /*           IMPLICIT NONE */
864 
865 /*           INCLUDE 'dla.inc' */
866 /*           INCLUDE 'dskdsc.inc' */
867 /*           INCLUDE 'dsk02.inc' */
868 
869 /*     C */
870 /*     C     SPICELIB functions */
871 /*     C */
872 /*           DOUBLE PRECISION      JYEAR */
873 /*           DOUBLE PRECISION      PI */
874 /*     C */
875 /*     C     Local parameters */
876 /*     C */
877 /*           INTEGER               FRNMLN */
878 /*           PARAMETER           ( FRNMLN = 32 ) */
879 
880 /*           INTEGER               NSEG */
881 /*           PARAMETER           ( NSEG   = 3 ) */
882 
883 /*           INTEGER               NAMLEN */
884 /*           PARAMETER           ( NAMLEN = 20 ) */
885 
886 /*           INTEGER               FILSIZ */
887 /*           PARAMETER           ( FILSIZ = 255 ) */
888 
889 /*           INTEGER               LNSIZE */
890 /*           PARAMETER           ( LNSIZE = 80 ) */
891 
892 /*           INTEGER               NCOR */
893 /*           PARAMETER           ( NCOR   = 4 ) */
894 
895 /*     C */
896 /*     C     Local variables */
897 /*     C */
898 /*           CHARACTER*(NAMLEN)    CORNAM ( NCOR ) */
899 /*           CHARACTER*(FILSIZ)    DSK */
900 /*           CHARACTER*(FRNMLN)    FRAME */
901 /*           CHARACTER*(FILSIZ)    INDSK */
902 /*           CHARACTER*(LNSIZE)    LINE */
903 /*     C */
904 /*     C     Note: the values of MAXVRT and MAXPLT declared */
905 /*     C     in dsk02.inc, and the integer spatial index */
906 /*     C     dimension SPAISZ are very large. Smaller buffers */
907 /*     C     can be used for most applications. */
908 /*     C */
909 /*           DOUBLE PRECISION      CORPAR ( NSYPAR ) */
910 /*           DOUBLE PRECISION      F */
911 /*           DOUBLE PRECISION      FINSCL */
912 /*           DOUBLE PRECISION      FIRST */
913 /*           DOUBLE PRECISION      LAST */
914 /*           DOUBLE PRECISION      MNCOR1 */
915 /*           DOUBLE PRECISION      MNCOR2 */
916 /*           DOUBLE PRECISION      MNCOR3 */
917 /*           DOUBLE PRECISION      MXCOR1 */
918 /*           DOUBLE PRECISION      MXCOR2 */
919 /*           DOUBLE PRECISION      MXCOR3 */
920 /*           DOUBLE PRECISION      RE */
921 /*           DOUBLE PRECISION      RP */
922 /*           DOUBLE PRECISION      SPAIXD ( IXDFIX ) */
923 /*           DOUBLE PRECISION      VRTCES ( 3, MAXVRT ) */
924 
925 /*           INTEGER               CENTER */
926 /*           INTEGER               CORSCL */
927 /*           INTEGER               CORSYS */
928 /*           INTEGER               DCLASS */
929 /*           INTEGER               DLADSC ( DLADSZ ) */
930 /*           INTEGER               HANDLE */
931 /*           INTEGER               INHAN */
932 /*           INTEGER               NP */
933 /*           INTEGER               NV */
934 /*           INTEGER               PLATES ( 3, MAXPLT ) */
935 /*           INTEGER               SEGNO */
936 /*           INTEGER               SPAIXI ( SPAISZ ) */
937 /*           INTEGER               SURFID */
938 /*           INTEGER               VOXPSZ */
939 /*           INTEGER               VOXLSZ */
940 /*           INTEGER               WORK   ( 2, MAXCEL ) */
941 /*           INTEGER               WORKSZ */
942 
943 /*           LOGICAL               FOUND */
944 /*     C */
945 /*     C     Saved variables */
946 /*     C */
947 /*     C     Save all large arrays to avoid stack problems. */
948 /*     C */
949 /*           SAVE */
950 /*     C */
951 /*     C     Initial values */
952 /*     C */
953 /*           DATA                  CORNAM / 'radius', */
954 /*          .                               'Z-coordinate', */
955 /*          .                               'Z-coordinate', */
956 /*          .                               'altitude'     / */
957 
958 /*     C */
959 /*     C     Assign names of input and output DSK files. */
960 /*     C */
961 /*           INDSK = 'phobos_3_3.bds' */
962 /*           DSK   = 'phobos_3_3_3seg.bds' */
963 /*     C */
964 /*     C     Open input DSK for read access; find first segment. */
965 /*     C */
966 /*           CALL DASOPR ( INDSK, INHAN ) */
967 /*           CALL DLABFS ( INHAN, DLADSC, FOUND ) */
968 /*     C */
969 /*     C     Fetch vertices and plates from input DSK file. */
970 /*     C */
971 /*           WRITE (*,*) 'Reading input data...' */
972 
973 /*           CALL DSKV02 ( INHAN, DLADSC, 1, MAXVRT, NV, VRTCES ) */
974 /*           CALL DSKP02 ( INHAN, DLADSC, 1, MAXPLT, NP, PLATES ) */
975 
976 /*           WRITE (*,*) 'Done.' */
977 /*     C */
978 /*     C     Set input array sizes required by DSKMI2. */
979 /*     C */
980 /*           VOXPSZ = MAXVXP */
981 /*           VOXLSZ = MXNVLS */
982 /*           WORKSZ = MAXCEL */
983 /*     C */
984 /*     C     Set fine and coarse voxel scales. (These usually */
985 /*     C     need to determined by experimentation.) */
986 /*     C */
987 /*           FINSCL = 5.D0 */
988 /*           CORSCL = 4 */
989 /*     C */
990 /*     C     Open a new DSK file. */
991 /*     C */
992 /*           CALL DSKOPN ( DSK, DSK, 0, HANDLE ) */
993 /*     C */
994 /*     C     Create three segments and add them to the file. */
995 /*     C */
996 /*           DO SEGNO = 1, NSEG */
997 /*     C */
998 /*     C        Create spatial index. */
999 /*     C */
1000 /*              WRITE (*,*) 'Creating segment ', SEGNO */
1001 /*              WRITE (*,*) 'Creating spatial index...' */
1002 
1003 /*              CALL DSKMI2 ( NV,     VRTCES, NP,     PLATES, FINSCL, */
1004 /*          .                 CORSCL, WORKSZ, VOXPSZ, VOXLSZ, .TRUE., */
1005 /*          .                 SPAISZ, WORK,   SPAIXD, SPAIXI          ) */
1006 
1007 /*              WRITE (*,*) 'Done.' */
1008 /*     C */
1009 /*     C        Set up inputs describing segment attributes: */
1010 /*     C */
1011 /*     C        - Central body: Phobos */
1012 /*     C        - Surface ID code: user's choice. */
1013 /*     C          We use the segment number here. */
1014 /*     C        - Data class: general (arbitrary) shape */
1015 /*     C        - Body-fixed reference frame */
1016 /*     C        - Time coverage bounds (TBD) */
1017 /*     C */
1018 /*              CENTER = 401 */
1019 /*              SURFID = SEGNO */
1020 /*              DCLASS = GENCLS */
1021 /*              FRAME  = 'IAU_PHOBOS' */
1022 
1023 /*              FIRST = -50 * JYEAR() */
1024 /*              LAST  =  50 * JYEAR() */
1025 /*     C */
1026 /*     C        Set the coordinate system and coordinate system */
1027 /*     C        bounds based on the segment index. */
1028 /*     C */
1029 /*     C        Zero out the coordinate parameters to start. */
1030 /*     C */
1031 /*              CALL CLEARD ( NSYPAR, CORPAR ) */
1032 
1033 /*              IF ( SEGNO .EQ. 1 ) THEN */
1034 /*     C */
1035 /*     C           Use planetocentric latitudinal coordinates. Set */
1036 /*     C           the longitude and latitude bounds. */
1037 /*     C */
1038 /*                 CORSYS = LATSYS */
1039 
1040 /*                 MNCOR1 = -PI() */
1041 /*                 MXCOR1 =  PI() */
1042 /*                 MNCOR2 = -PI()/2 */
1043 /*                 MXCOR2 =  PI()/2 */
1044 
1045 /*              ELSE IF ( SEGNO .EQ. 2 ) THEN */
1046 /*     C */
1047 /*     C           Use rectangular coordinates. Set the */
1048 /*     C           X and Y bounds. */
1049 /*     C */
1050 /*     C           The bounds shown here were derived from */
1051 /*     C           the plate data. They lie slightly outside */
1052 /*     C           of the range spanned by the plates. */
1053 /*     C */
1054 /*                 CORSYS = RECSYS */
1055 
1056 /*                 MNCOR1 = -1.3D0 */
1057 /*                 MXCOR1 =  1.31D0 */
1058 /*                 MNCOR2 = -1.21D0 */
1059 /*                 MXCOR2 =  1.2D0 */
1060 
1061 /*              ELSE */
1062 /*     C */
1063 /*     C           Set the coordinate system to planetodetic. */
1064 /*     C */
1065 /*                 CORSYS    = PDTSYS */
1066 
1067 /*                 MNCOR1    = -PI() */
1068 /*                 MXCOR1    =  PI() */
1069 /*                 MNCOR2    = -PI()/2 */
1070 /*                 MXCOR2    =  PI()/2 */
1071 /*     C */
1072 /*     C           We'll use equatorial and polar radii from */
1073 /*     C           pck00010.tpc. These normally would be fetched */
1074 /*     C           at run time, but for simplicity, we'll use */
1075 /*     C           hard-coded values. */
1076 
1077 /*                 RE        = 13.0D0 */
1078 /*                 RP        =  9.1D0 */
1079 /*                 F         = ( RE - RP ) / RE */
1080 
1081 /*                 CORPAR(1) = RE */
1082 /*                 CORPAR(2) = F */
1083 
1084 /*              END IF */
1085 /*     C */
1086 /*     C        Compute plate model radius bounds. */
1087 /*     C */
1088 /*              LINE = 'Computing # bounds of plate set...' */
1089 
1090 /*              CALL REPMC ( LINE, '#', CORNAM(CORSYS), LINE ) */
1091 /*              WRITE (*,*) LINE */
1092 
1093 /*              CALL DSKRB2 ( NV,     VRTCES, NP,     PLATES, */
1094 /*          .                 CORSYS, CORPAR, MNCOR3, MXCOR3 ) */
1095 
1096 /*              WRITE (*,*) 'Done.' */
1097 /*     C */
1098 /*     C        Write the segment to the file. */
1099 /*     C */
1100 /*              WRITE (*,*) 'Writing segment...' */
1101 
1102 /*              CALL DSKW02 ( HANDLE, */
1103 /*          .                 CENTER, SURFID, DCLASS, FRAME,  CORSYS, */
1104 /*          .                 CORPAR, MNCOR1, MXCOR1, MNCOR2, MXCOR2, */
1105 /*          .                 MNCOR3, MXCOR3, FIRST,  LAST,   NV, */
1106 /*          .                 VRTCES, NP,     PLATES, SPAIXD, SPAIXI ) */
1107 
1108 /*              WRITE (*,*) 'Done.' */
1109 
1110 /*           END DO */
1111 /*     C */
1112 /*     C     Segregate the data records in the DSK file and */
1113 /*     C     close the file. */
1114 /*     C */
1115 /*           WRITE (*,*) 'Segregating and closing DSK file...' */
1116 
1117 /*           CALL DSKCLS ( HANDLE, .TRUE. ) */
1118 
1119 /*           WRITE (*,*) 'Done.' */
1120 /*           END */
1121 
1122 
1123 
1124 /* $ Restrictions */
1125 
1126 /*     None. */
1127 
1128 /* $ Literature_References */
1129 
1130 /*     None. */
1131 
1132 /* $ Author_and_Institution */
1133 
1134 /*     N.J. Bachman    (JPL) */
1135 
1136 /* $ Version */
1137 
1138 /* -    SPICELIB Version 1.0.0, 13-DEC-2016 (NJB) */
1139 
1140 /*        Updated check on NV. */
1141 
1142 /*        16-MAR-2016 (NJB) */
1143 
1144 /*        Now zeros out the size of the vertex-plate list */
1145 /*        when the list is not created. */
1146 
1147 /*        23-JAN-2016 (NJB) */
1148 
1149 /*           Original version. */
1150 
1151 /* -& */
1152 /* $ Index_Entries */
1153 
1154 /*     make spatial index for type 2 dsk segment */
1155 
1156 /* -& */
1157 
1158 /*     SPICELIB functions */
1159 
1160 
1161 /*     Local parameters */
1162 
1163 
1164 /*     Local variables */
1165 
1166     /* Parameter adjustments */
1167     spaixi_dim1 = *spxisz;
1168 
1169     /* Function Body */
1170     if (return_()) {
1171 	return 0;
1172     }
1173     chkin_("DSKMI2", (ftnlen)6);
1174 
1175 /*     Perform error checks on inputs. */
1176 
1177     if (*finscl <= 0.) {
1178 	setmsg_("Fine voxel scale = #; scale must be positive. Usually scale"
1179 		" should be > 1.0.", (ftnlen)76);
1180 	errdp_("#", finscl, (ftnlen)1);
1181 	sigerr_("SPICE(BADFINEVOXELSCALE)", (ftnlen)24);
1182 	chkout_("DSKMI2", (ftnlen)6);
1183 	return 0;
1184     }
1185     if (*corscl < 1) {
1186 	setmsg_("Coarse voxel scale = #; scale must be >= 1.", (ftnlen)43);
1187 	errint_("#", corscl, (ftnlen)1);
1188 	sigerr_("SPICE(BADCOARSEVOXSCALE)", (ftnlen)24);
1189 	chkout_("DSKMI2", (ftnlen)6);
1190 	return 0;
1191     }
1192     if (*nv < 3 || *nv > 16000002) {
1193 	setmsg_("Vertex count NV = #; count must be in the range 3:#.", (
1194 		ftnlen)52);
1195 	errint_("#", nv, (ftnlen)1);
1196 	errint_("#", &c_b14, (ftnlen)1);
1197 	sigerr_("SPICE(BADVERTEXCOUNT)", (ftnlen)21);
1198 	chkout_("DSKMI2", (ftnlen)6);
1199 	return 0;
1200     }
1201     if (*np < 1 || *np > 32000000) {
1202 	setmsg_("Plate count NP = #; count must be in the range 1:#.", (
1203 		ftnlen)51);
1204 	errint_("#", np, (ftnlen)1);
1205 	errint_("#", &c_b20, (ftnlen)1);
1206 	sigerr_("SPICE(BADPLATECOUNT)", (ftnlen)20);
1207 	chkout_("DSKMI2", (ftnlen)6);
1208 	return 0;
1209     }
1210     if (*worksz < *np + 1) {
1211 	setmsg_("Workspace size = #; size is too small to hold all voxel-pla"
1212 		"te associations. Size should be at least # * (average number"
1213 		" of voxels intersected by each plate).", (ftnlen)157);
1214 	errint_("#", worksz, (ftnlen)1);
1215 	errint_("#", np, (ftnlen)1);
1216 	sigerr_("SPICE(WORKSPACETOOSMALL)", (ftnlen)24);
1217 	chkout_("DSKMI2", (ftnlen)6);
1218 	return 0;
1219     }
1220     if (*voxpsz < 1) {
1221 	setmsg_("Voxel-pointer array size = #; size is too small to hold all"
1222 		" voxel-plate list pointers. Size should be at least # * (num"
1223 		"ber of non-empty coarse voxels).", (ftnlen)151);
1224 	errint_("#", voxpsz, (ftnlen)1);
1225 /* Computing 3rd power */
1226 	i__2 = *corscl;
1227 	i__1 = i__2 * (i__2 * i__2);
1228 	errint_("#", &i__1, (ftnlen)1);
1229 	sigerr_("SPICE(PTRARRAYTOOSMALL)", (ftnlen)23);
1230 	chkout_("DSKMI2", (ftnlen)6);
1231 	return 0;
1232     }
1233     if (*voxlsz < *np + 1) {
1234 	setmsg_("Voxel-plate list array size = #; size is too small to hold "
1235 		"all voxel-plate associations. Size should be at least # * (a"
1236 		"verage number of voxels intersected by each plate).", (ftnlen)
1237 		170);
1238 	errint_("#", voxlsz, (ftnlen)1);
1239 	errint_("#", np, (ftnlen)1);
1240 	sigerr_("SPICE(PLATELISTTOOSMALL)", (ftnlen)24);
1241 	chkout_("DSKMI2", (ftnlen)6);
1242 	return 0;
1243     }
1244 
1245 /*     Check the size of the integer spatial index array. The */
1246 /*     declared size must be large enough to hold: */
1247 
1248 /*        - the fixed-size part of the index, which includes */
1249 /*          the coarse voxel grid */
1250 
1251 /*        - the voxel-plate pointer array */
1252 
1253 /*        - the voxel-plate association list */
1254 
1255 /*     plus, if the vertex-plate association list is constructed, */
1256 
1257 /*        - the vertex-plate pointer array */
1258 
1259 /*        - the vertex-plate association list */
1260 
1261 
1262     reqsiz = *voxpsz + 100007 + *voxlsz;
1263     if (*makvtl) {
1264 
1265 /*        Add on the sizes of the vertex-plate pointer array (NV) */
1266 /*        and the vertex-plate list array (NV + 3*NP). */
1267 
1268 	vtxlsz = *nv + *np * 3;
1269 	reqsiz = reqsiz + *nv + vtxlsz;
1270     } else {
1271 	vtxlsz = 0;
1272     }
1273     if (*spxisz < reqsiz) {
1274 	setmsg_("Integer spatial index size = #; size must be at least #.", (
1275 		ftnlen)56);
1276 	errint_("#", spxisz, (ftnlen)1);
1277 	errint_("#", &reqsiz, (ftnlen)1);
1278 	sigerr_("SPICE(INTINDEXTOOSMALL)", (ftnlen)23);
1279 	chkout_("DSKMI2", (ftnlen)6);
1280 	return 0;
1281     }
1282 
1283 /*     Set known values in spatial index arrays. */
1284 
1285     spaixi[(i__1 = 3) < spaixi_dim1 ? i__1 : s_rnge("spaixi", i__1, "dskmi2_",
1286 	     (ftnlen)898)] = *corscl;
1287 
1288 /*     Prepare indices in the spatial index arrays. */
1289 
1290 /*        VXPIDX is the start index of the voxel pointer array. */
1291 
1292     vxpidx = 100008;
1293 
1294 /*        VXLIDX is the start index of the voxel-plate list. This */
1295 /*        list is offset from the start of the pointer array by */
1296 /*        the input size given for that array. The size is the */
1297 /*        total room available, not the room actually used. */
1298 
1299     vxlidx = vxpidx + *voxpsz;
1300 
1301 /*     Create spatial index for plates. */
1302 
1303     zzmkspin_(np, plates, vrtces, finscl, corscl, voxpsz, worksz, voxlsz,
1304 	    work, &spaixi[(i__1 = 0) < spaixi_dim1 ? i__1 : s_rnge("spaixi",
1305 	    i__1, "dskmi2_", (ftnlen)917)], &spaixd[9], &spaixd[6], &nvxtot, &
1306 	    spaixi[(i__2 = 4) < spaixi_dim1 ? i__2 : s_rnge("spaixi", i__2,
1307 	    "dskmi2_", (ftnlen)917)], &spaixi[(i__3 = vxpidx - 1) <
1308 	    spaixi_dim1 && 0 <= i__3 ? i__3 : s_rnge("spaixi", i__3, "dskmi2_"
1309 	    , (ftnlen)917)], &spaixi[(i__4 = 5) < spaixi_dim1 ? i__4 : s_rnge(
1310 	    "spaixi", i__4, "dskmi2_", (ftnlen)917)], &spaixi[(i__5 = vxlidx
1311 	    - 1) < spaixi_dim1 && 0 <= i__5 ? i__5 : s_rnge("spaixi", i__5,
1312 	    "dskmi2_", (ftnlen)917)], spaixd, &spaixi[(i__6 = 7) <
1313 	    spaixi_dim1 ? i__6 : s_rnge("spaixi", i__6, "dskmi2_", (ftnlen)
1314 	    917)]);
1315     if (failed_()) {
1316 	chkout_("DSKMI2", (ftnlen)6);
1317 	return 0;
1318     }
1319 
1320 /*     At this point the voxel plate list is offset from the */
1321 /*     start of the voxel pointer array by the allocated size */
1322 /*     of the array. We need to shift the plate list so that */
1323 /*     it starts right after the end of the pointer array. */
1324 
1325     nshift = *voxpsz - spaixi[(i__1 = 4) < spaixi_dim1 ? i__1 : s_rnge("spai"
1326 	    "xi", i__1, "dskmi2_", (ftnlen)942)];
1327     i__2 = spaixi[(i__1 = 5) < spaixi_dim1 ? i__1 : s_rnge("spaixi", i__1,
1328 	    "dskmi2_", (ftnlen)944)];
1329     for (i__ = 1; i__ <= i__2; ++i__) {
1330 	j = vxlidx - 1 + i__;
1331 	spaixi[(i__1 = j - nshift - 1) < spaixi_dim1 && 0 <= i__1 ? i__1 :
1332 		s_rnge("spaixi", i__1, "dskmi2_", (ftnlen)948)] = spaixi[(
1333 		i__3 = j - 1) < spaixi_dim1 && 0 <= i__3 ? i__3 : s_rnge(
1334 		"spaixi", i__3, "dskmi2_", (ftnlen)948)];
1335     }
1336 
1337 /*     Update the voxel list start index to reflect the shift. */
1338 
1339     vxlidx -= nshift;
1340 
1341 /*     Create vertex-plate mapping, if requested, as indicated */
1342 /*     by the vertex-plate list size. */
1343 
1344     if (*makvtl) {
1345 
1346 /*           VTPIDX is the start index of the vertex pointer array. */
1347 
1348 	vtpidx = vxlidx + spaixi[(i__2 = 5) < spaixi_dim1 ? i__2 : s_rnge(
1349 		"spaixi", i__2, "dskmi2_", (ftnlen)965)];
1350 
1351 /*           VXLIDX is the start index of the vertex-plate list. The */
1352 /*           list start is offset from the vertex pointer array by */
1353 /*           the size of the array, which is always NV. */
1354 
1355 	vtlidx = vtpidx + *nv;
1356 	zzvrtplt_(nv, np, plates, worksz, &vtxlsz, work, &spaixi[(i__2 =
1357 		vtpidx - 1) < spaixi_dim1 && 0 <= i__2 ? i__2 : s_rnge("spai"
1358 		"xi", i__2, "dskmi2_", (ftnlen)973)], &spaixi[(i__1 = 6) <
1359 		spaixi_dim1 ? i__1 : s_rnge("spaixi", i__1, "dskmi2_", (
1360 		ftnlen)973)], &spaixi[(i__3 = vtlidx - 1) < spaixi_dim1 && 0
1361 		<= i__3 ? i__3 : s_rnge("spaixi", i__3, "dskmi2_", (ftnlen)
1362 		973)]);
1363     } else {
1364 
1365 /*        Zero out the size of the vertex-plate list. */
1366 
1367 	spaixi[(i__2 = 6) < spaixi_dim1 ? i__2 : s_rnge("spaixi", i__2, "dsk"
1368 		"mi2_", (ftnlen)983)] = 0;
1369     }
1370     chkout_("DSKMI2", (ftnlen)6);
1371     return 0;
1372 } /* dskmi2_ */
1373 
1374