@@ -1318,12 +1318,204 @@ void cntr_del(Csite *site)
13181318 site = NULL ;
13191319}
13201320
1321+ #define MOVETO 1
1322+ #define LINETO 2
13211323
1322- /* Build a list of XY 2-D arrays, shape (N,2), to which a list of K arrays
1323- is concatenated. */
1324+ int reorder (double * xpp , double * ypp , short * kpp ,
1325+ double * xy , unsigned char * c , int npts )
1326+ {
1327+ int * i0 ;
1328+ int * i1 ;
1329+ int * subp = NULL ; /* initialized to suppress warning */
1330+ int isp , nsp ;
1331+ int iseg , nsegs ;
1332+ int isegplus ;
1333+ int i ;
1334+ int k ;
1335+ int started ;
1336+ int maxnsegs = npts /2 + 1 ;
1337+
1338+ /* allocate maximum possible size--gross overkill */
1339+ i0 = malloc (maxnsegs * sizeof (int ));
1340+ i1 = malloc (maxnsegs * sizeof (int ));
1341+
1342+ /* Find the segments. */
1343+ iseg = 0 ;
1344+ started = 0 ;
1345+ for (i = 0 ; i < npts ; i ++ )
1346+ {
1347+ if (started )
1348+ {
1349+ if ((kpp [i ] >= kind_slit_up ) || (i == npts - 1 ))
1350+ {
1351+ i1 [iseg ] = i ;
1352+ started = 0 ;
1353+ iseg ++ ;
1354+ if (iseg == maxnsegs )
1355+ {
1356+ k = -1 ;
1357+ goto ending ;
1358+ }
1359+ }
1360+ }
1361+ else if ((kpp [i ] < kind_slit_up ) && (i < npts - 1 ))
1362+ {
1363+ i0 [iseg ] = i ;
1364+ started = 1 ;
1365+ }
1366+ }
1367+
1368+ nsegs = iseg ;
1369+
1370+
1371+ /* Find the subpaths as sets of connected segments. */
1372+
1373+ subp = malloc (nsegs * sizeof (int ));
1374+ for (i = 0 ; i < nsegs ; i ++ ) subp [i ] = -1 ;
1375+
1376+ nsp = 0 ;
1377+ for (iseg = 0 ; iseg < nsegs ; iseg ++ )
1378+ {
1379+ /* For each segment, if it is not closed, look ahead for
1380+ the next connected segment.
1381+ */
1382+ double xend , yend ;
1383+ xend = xpp [i1 [iseg ]];
1384+ yend = ypp [i1 [iseg ]];
1385+ if (subp [iseg ] >= 0 ) continue ;
1386+ subp [iseg ] = nsp ;
1387+ nsp ++ ;
1388+ if (iseg == nsegs - 1 ) continue ;
1389+ for (isegplus = iseg + 1 ; isegplus < nsegs ; isegplus ++ )
1390+ {
1391+ if (subp [isegplus ] >= 0 ) continue ;
1392+
1393+ if (xend == xpp [i0 [isegplus ]] && yend == ypp [i0 [isegplus ]])
1394+ {
1395+ subp [isegplus ] = subp [iseg ];
1396+ xend = xpp [i1 [isegplus ]];
1397+ yend = ypp [i1 [isegplus ]];
1398+ }
1399+
1400+ }
1401+ }
1402+
1403+ /* Generate the verts and codes from the subpaths. */
1404+ k = 0 ;
1405+ for (isp = 0 ; isp < nsp ; isp ++ )
1406+ {
1407+ int first = 1 ;
1408+ for (iseg = 0 ; iseg < nsegs ; iseg ++ )
1409+ {
1410+ int istart , iend ;
1411+ if (subp [iseg ] != isp ) continue ;
1412+ iend = i1 [iseg ];
1413+ if (first )
1414+ {
1415+ istart = i0 [iseg ];
1416+ }
1417+ else
1418+ {
1419+ istart = i0 [iseg ]+ 1 ; /* skip duplicate */
1420+ }
1421+ for (i = istart ; i <=iend ; i ++ )
1422+ {
1423+ xy [2 * k ] = xpp [i ];
1424+ xy [2 * k + 1 ] = ypp [i ];
1425+ if (first ) c [k ] = MOVETO ;
1426+ else c [k ] = LINETO ;
1427+ first = 0 ;
1428+ k ++ ;
1429+ if (k > npts ) /* should never happen */
1430+ {
1431+ k = -1 ;
1432+ goto ending ;
1433+ }
1434+ }
1435+ }
1436+ }
1437+
1438+ ending :
1439+ free (i0 );
1440+ free (i1 );
1441+ free (subp );
1442+
1443+ return k ;
1444+ }
1445+
1446+ /* Build a list of XY 2-D arrays, shape (N,2), to which a list of path
1447+ code arrays is concatenated.
1448+ */
13241449static PyObject *
13251450build_cntr_list_v2 (long * np , double * xp , double * yp , short * kp ,
13261451 int nparts , long ntotal )
1452+ {
1453+ PyObject * all_contours ;
1454+ PyArrayObject * xyv ;
1455+ PyArrayObject * kv ;
1456+ npy_intp dims [2 ];
1457+ npy_intp kdims [1 ];
1458+ int i ;
1459+ long k ;
1460+
1461+ PyArray_Dims newshape ;
1462+
1463+ all_contours = PyList_New (nparts * 2 );
1464+
1465+ for (i = 0 , k = 0 ; i < nparts ; k += np [i ], i ++ )
1466+ {
1467+ double * xpp = xp + k ;
1468+ double * ypp = yp + k ;
1469+ short * kpp = kp + k ;
1470+ int n ;
1471+
1472+
1473+ dims [0 ] = np [i ];
1474+ dims [1 ] = 2 ;
1475+ kdims [0 ] = np [i ];
1476+ xyv = (PyArrayObject * ) PyArray_SimpleNew (2 , dims , PyArray_DOUBLE );
1477+ if (xyv == NULL ) goto error ;
1478+ kv = (PyArrayObject * ) PyArray_SimpleNew (1 , kdims , PyArray_UBYTE );
1479+ if (kv == NULL ) goto error ;
1480+
1481+ n = reorder (xpp , ypp , kpp ,
1482+ (double * ) xyv -> data ,
1483+ (unsigned char * ) kv -> data ,
1484+ np [i ]);
1485+ if (n == -1 ) goto error ;
1486+ newshape .len = 2 ;
1487+ dims [0 ] = n ;
1488+ newshape .ptr = dims ;
1489+ if (PyArray_Resize (xyv , & newshape , 1 , NPY_CORDER ) == NULL ) goto error ;
1490+
1491+ newshape .len = 1 ; /* ptr, dims can stay the same */
1492+ if (PyArray_Resize (kv , & newshape , 1 , NPY_CORDER ) == NULL ) goto error ;
1493+
1494+
1495+ if (PyList_SetItem (all_contours , i , (PyObject * )xyv )) goto error ;
1496+ if (PyList_SetItem (all_contours , nparts + i ,
1497+ (PyObject * )kv )) goto error ;
1498+ }
1499+ return all_contours ;
1500+
1501+ error :
1502+ Py_XDECREF (xyv );
1503+ Py_XDECREF (kv );
1504+ Py_XDECREF (all_contours );
1505+ return NULL ;
1506+ }
1507+
1508+ #if 0 /* preprocess this out when we are not using it. */
1509+ /* Build a list of XY 2-D arrays, shape (N,2), to which a list of K arrays
1510+ is concatenated.
1511+ This is kept in the code in case we need to switch back to it,
1512+ or in case we need it for investigating the infamous internal
1513+ masked region bug.
1514+ */
1515+
1516+ static PyObject *
1517+ __build_cntr_list_v2 (long * np , double * xp , double * yp , short * kp ,
1518+ int nparts , long ntotal )
13271519{
13281520 PyObject * all_contours ;
13291521 PyArrayObject * xyv ;
@@ -1364,6 +1556,7 @@ build_cntr_list_v2(long *np, double *xp, double *yp, short *kp,
13641556 return NULL ;
13651557}
13661558
1559+ #endif /* preprocessing out the old version for now */
13671560
13681561
13691562/* cntr_trace is called once per contour level or level pair.
0 commit comments