// ************************************************************************ // // Copyright (c) 1995-2002 Juniper Networks, Inc. All rights reserved. // // Permission is hereby granted, without written agreement and without // license or royalty fees, to use, copy, modify, and distribute this // software and its documentation for any purpose, provided that the // above copyright notice and the following three paragraphs appear in // all copies of this software. // // IN NO EVENT SHALL JUNIPER NETWORKS, INC. BE LIABLE TO ANY PARTY FOR // DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF // JUNIPER NETWORKS, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH // DAMAGE. // // JUNIPER NETWORKS, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES, // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND // NON-INFRINGEMENT. // // THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND JUNIPER // NETWORKS, INC. HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, // UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // // ************************************************************************ #ifndef _BPLANE_H #define _BPLANE_H /* * bplane.h -- * * This file defines the interface between the bplane * module and the rest of max. * * BUGS * ==== * * NOTE nested enums are currently broken do to dynamic binning. * * OVERVIEW OF BPLANES * =================== * * BPlanes ('Binned' Planes) are a data-structure for storing, sorting, * and accessing two dimensional geometric objects. * * BPlanes are an alternative to Planes, i.e. corner-stitched tile planes, * defined in the tile module. * * Differences between Planes and BPlanes: * -------------------------------------- * * 1. BPlanes are more memory efficient. * Three pointers (+ a modest amount of binning overhead) * replaces approximately 8 pointers (4/tile, approx. 1 space * tile for each data tile). * * 2. BPlanes use a 'next' procedure for enumeration, instead of * function call-backs. This allows client code to be simpler * and more readable, partcularly with regard to passing state info. * In addition gprof results are easier to interpet, since * there is not confusion about which client procedures belong to * a given "loop". * * 3. Planes fundamentally assume objects don't overlap, while BPlanes * make no such assumption. This makes BPlanes more generally useful. * In particular they are a natural choice for instance uses, * labels, and non-manhattan polygons (sorted on bounding boxes). * * 4. Planes are optimized for merging (merging recangles * into maximal horizontal strips) and neighbor access * (finding nearest elements to current element). BPlanes are less * efficient for these operations. * * 5. Planes generally cannot be safely modified during an enumeration, * but BPlanes can. This makes operations such as delete, copy, and * move simpler in BPlanes. * * Interface * --------- * * 1. The structure of elements to be stored in BPlanes must be as * follows: * * typedef struct foo * { * struct void *foo_bpLinks[BP_NUM_LINKS]; * Rect foo_rect; * * } Foo * * 2. It is the clients responsiblity to alloc/free elements. * * 3. The client must set foo_rect before adding the element * to a BPlane. foo_rect must be canonical: not inverted. * * 4. The BPlane module does not access or modify any client fields. * * 5. The client may access/modify client fields at any time. * * 6. As long as an element belongs to a BPlane (i.e. has been * added via BPAdd() and not removed via BPDelete()): * * a. The client should not reference/modify the foo_bpLinks[] fields. * b. The client may reference but should not modify the foo_rect * field. * c. The client should not call BPAdd() for the element * (an element can only belong to one BPlane at at time). * d. The client should not free the element! * * 7. The client may assume tht BP_NUM_LINKS is at least one, and * may use foo_bpLinks[0], for his own purposes as long as an * element does not belong to a bplane. * * 8. Concurrent (nested) enumerations of a bplane are permitted. * * 9. Elements may not be added to a bplane during active enumeration(s) * on that bplane. * * 10. An element may be deleted from a bplane at any time, including * during active enumeration(s) of that bplane. After an element * has been deleted from a bplane, it will not be enumerated * (i.e. returned by BPEnumNext() on that bplane). * * Example * ------- * * Here is a procedure that takes an array of id'ed rectangles and an * area as input, and prints the ids of all rectangles impinging on the * area. * * typedef struct rid * { * struct rid *rid_bpLinks[BP_NUM_LINKS]; * Rect rid_rect; * char *rid_id; * } RId; * * void findRects(RId data[], // ided rects * int n, // number of rects in data * Rect *area) // area to search * { * int i; * BPEnum bpe; * BPlane *bp; * RId *rid; * * bp = BPNew(); * for(i=0;irid_id); * } * BPEnumTerm(&bpe); * */ /* offset of a structure member (used to gen offsets for ihash stuff) */ #if _MSC_VER /* Microsoft compile complains about size of (void*), so must use (char*) */ /* Could use (char*) in UNIX version too. */ #define OFFSET(structure,member) \ ( ((char *) &(((structure *) 0))->member) - ((char *) 0) ) #else #define OFFSET(structure,member) \ ( ((void *) &(((structure *) 0))->member) - ((void *) 0) ) #endif /* data-structures opaque to clients */ #include "bplane/bpOpaque.h" /* create a new BPlane */ extern BPlane *BPNew(void); /* free storate assoicated with a BPlane * (The BPlane must be empty.) */ extern void BPFree(BPlane *bp); /* add an element to a BPlane */ extern void BPAdd(BPlane *bp, void *element); /* remove an element from a BPlane */ extern void BPDelete(BPlane *bp, void *element); /* begin an enumeration */ extern void BPEnumInit(BPEnum *bpe, /* this procedure initializes this * client supplied 'handle' for the * enumeration. */ BPlane *bp, /* bplane to search */ Rect *area, /* area to search */ int match, /* see below */ char *id); /* for debugging */ /* match values */ /* enum all elements in the bplane (area arg must be null) */ #define BPE_ALL 0 /* element need only touch area */ #define BPE_TOUCH 1 /* some part of element must be inside (not just on boundary of) area */ #define BPE_OVERLAP 2 /* elements rect must be identical to area */ #define BPE_EQUAL 3 /* return next element in enumeration (returns NULL if none) */ #include "bplane/bpEnum.h" /* inlined extern void *BPEnumNext(BPEnum *bpe); */ /* terminate enumeration * * (unterminated enumerations can cause great inefficiency since * all active enumerations for a bplane must be considered whenever * an element is added or deleted.) */ extern void BPEnumTerm(BPEnum *bpe); /* get current bounding box of BPlane */ extern Rect BPBBox(BPlane *bp); /* compute number of bytes used by BPlane * (does not count memory of the elements themselves) */ extern unsigned int BPStatMemory(BPlane *bp); /* tabulate statistics on a bplane */ extern unsigned int BPStat(BPlane *bp, int *totCount, /* ret total number of elements */ int *inBox, /* ret num of elements in inBox */ int *totBins, /* ret tot num of bins */ int *emptyBins, /* ret num of empty bins */ int *binArraysp, /* ret num of bin arrays */ int *maxEffp, /* ret max effective list length */ int *maxBinCount, /* ret max count for regular bin */ int *totUnbinned, /* ret tot num of e's not binned */ int *maxDepth); /* ret max bin array depth */ #endif /* _BPLANE_H */