Skip to content

Commit f377d97

Browse files
cyrushCyrus Harrison
authored and
Cyrus Harrison
committed
1 parent c2c68c8 commit f377d97

17 files changed

+5098
-0
lines changed

LICENSE.txt

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
** SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
2+
** Copyright (C) [dates of first publication] Silicon Graphics, Inc.
3+
** All Rights Reserved.
4+
**
5+
** Permission is hereby granted, free of charge, to any person obtaining a copy
6+
** of this software and associated documentation files (the "Software"), to deal
7+
** in the Software without restriction, including without limitation the rights
8+
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9+
** of the Software, and to permit persons to whom the Software is furnished to do so,
10+
** subject to the following conditions:
11+
**
12+
** The above copyright notice including the dates of first publication and either this
13+
** permission notice or a reference to http://oss.sgi.com/projects/FreeB/ shall be
14+
** included in all copies or substantial portions of the Software.
15+
**
16+
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
17+
** INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
18+
** PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL SILICON GRAPHICS, INC.
19+
** BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20+
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21+
** OR OTHER DEALINGS IN THE SOFTWARE.
22+
**
23+
** Except as contained in this notice, the name of Silicon Graphics, Inc. shall not
24+
** be used in advertising or otherwise to promote the sale, use or other dealings in
25+
** this Software without prior written authorization from Silicon Graphics, Inc.

mononen.readme.txt

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
Libtess2 version 1.0
3+
4+
5+
This is refactored version of the original libtess which comes with the GLU reference implementation. The code is good quality polygon tesselator and triangulator. The original code comes with rather horrible interface and its' performance suffers from lots of small memory allocations. The main point of the refactoring has been the interface and memory allocation scheme.
6+
7+
Simple bucketed memory allocator (see Graphics Gems III for reference) was added which speeds up the code by order of magnitude (tests showed 15 to 50 times improvement depending on data). The API allows the user to pass his own allocator to the library. It is possible to configure the library so that the library runs on predefined chunk of memory.
8+
9+
The API was changed to loosely resemble the OpenGL vertex array API. The processed data can be accessed via getter functions. The code is able to output contours, polygons and connected polygons. The output of the tesselator can be also used as input for new run. I.e. the user may first want to calculate an union all the input contours and the triangulate them.
10+
11+
The code is released under SGI FREE SOFTWARE LICENSE B Version 2.0.
12+
13+
14+
15+
Mikko Mononen
16+

src/bucketalloc.c

+191
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
/*
2+
** SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3+
** Copyright (C) [dates of first publication] Silicon Graphics, Inc.
4+
** All Rights Reserved.
5+
**
6+
** Permission is hereby granted, free of charge, to any person obtaining a copy
7+
** of this software and associated documentation files (the "Software"), to deal
8+
** in the Software without restriction, including without limitation the rights
9+
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10+
** of the Software, and to permit persons to whom the Software is furnished to do so,
11+
** subject to the following conditions:
12+
**
13+
** The above copyright notice including the dates of first publication and either this
14+
** permission notice or a reference to http://oss.sgi.com/projects/FreeB/ shall be
15+
** included in all copies or substantial portions of the Software.
16+
**
17+
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18+
** INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
19+
** PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL SILICON GRAPHICS, INC.
20+
** BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21+
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
22+
** OR OTHER DEALINGS IN THE SOFTWARE.
23+
**
24+
** Except as contained in this notice, the name of Silicon Graphics, Inc. shall not
25+
** be used in advertising or otherwise to promote the sale, use or other dealings in
26+
** this Software without prior written authorization from Silicon Graphics, Inc.
27+
*/
28+
/*
29+
** Author: Mikko Mononen, July 2009.
30+
*/
31+
32+
#include <stdio.h>
33+
#include <stdlib.h>
34+
#include "tesselator.h"
35+
36+
//#define CHECK_BOUNDS
37+
38+
typedef struct BucketAlloc BucketAlloc;
39+
typedef struct Bucket Bucket;
40+
41+
struct Bucket
42+
{
43+
Bucket *next;
44+
};
45+
46+
struct BucketAlloc
47+
{
48+
void *freelist;
49+
Bucket *buckets;
50+
unsigned int itemSize;
51+
unsigned int bucketSize;
52+
const char *name;
53+
TESSalloc* alloc;
54+
};
55+
56+
static int CreateBucket( struct BucketAlloc* ba )
57+
{
58+
size_t size;
59+
Bucket* bucket;
60+
void* freelist;
61+
unsigned char* head;
62+
unsigned char* it;
63+
64+
// Allocate memory for the bucket
65+
size = sizeof(Bucket) + ba->itemSize * ba->bucketSize;
66+
bucket = (Bucket*)ba->alloc->memalloc( ba->alloc->userData, size );
67+
if ( !bucket )
68+
return 0;
69+
bucket->next = 0;
70+
71+
// Add the bucket into the list of buckets.
72+
bucket->next = ba->buckets;
73+
ba->buckets = bucket;
74+
75+
// Add new items to the free list.
76+
freelist = ba->freelist;
77+
head = (unsigned char*)bucket + sizeof(Bucket);
78+
it = head + ba->itemSize * ba->bucketSize;
79+
do
80+
{
81+
it -= ba->itemSize;
82+
// Store pointer to next free item.
83+
*((void**)it) = freelist;
84+
// Pointer to next location containing a free item.
85+
freelist = (void*)it;
86+
}
87+
while ( it != head );
88+
// Update pointer to next location containing a free item.
89+
ba->freelist = (void*)it;
90+
91+
return 1;
92+
}
93+
94+
static void *NextFreeItem( struct BucketAlloc *ba )
95+
{
96+
return *(void**)ba->freelist;
97+
}
98+
99+
struct BucketAlloc* createBucketAlloc( TESSalloc* alloc, const char* name,
100+
unsigned int itemSize, unsigned int bucketSize )
101+
{
102+
BucketAlloc* ba = (BucketAlloc*)alloc->memalloc( alloc->userData, sizeof(BucketAlloc) );
103+
104+
ba->alloc = alloc;
105+
ba->name = name;
106+
ba->itemSize = itemSize;
107+
if ( ba->itemSize < sizeof(void*) )
108+
ba->itemSize = sizeof(void*);
109+
ba->bucketSize = bucketSize;
110+
ba->freelist = 0;
111+
ba->buckets = 0;
112+
113+
if ( !CreateBucket( ba ) )
114+
{
115+
alloc->memfree( alloc->userData, ba );
116+
return 0;
117+
}
118+
119+
return ba;
120+
}
121+
122+
void* bucketAlloc( struct BucketAlloc *ba )
123+
{
124+
void *it;
125+
126+
// If running out of memory, allocate new bucket and update the freelist.
127+
if ( !ba->freelist || !NextFreeItem( ba ) )
128+
{
129+
if ( !CreateBucket( ba ) )
130+
return 0;
131+
}
132+
133+
// Pop item from in front of the free list.
134+
it = ba->freelist;
135+
ba->freelist = NextFreeItem( ba );
136+
137+
return it;
138+
}
139+
140+
void bucketFree( struct BucketAlloc *ba, void *ptr )
141+
{
142+
#ifdef CHECK_BOUNDS
143+
int inBounds = 0;
144+
Bucket *bucket;
145+
146+
// Check that the pointer is allocated with this allocator.
147+
bucket = ba->buckets;
148+
while ( bucket )
149+
{
150+
void *bucketMin = (void*)((unsigned char*)bucket + sizeof(Bucket));
151+
void *bucketMax = (void*)((unsigned char*)bucket + sizeof(Bucket) + ba->itemSize * ba->bucketSize);
152+
if ( ptr >= bucketMin && ptr < bucketMax )
153+
{
154+
inBounds = 1;
155+
break;
156+
}
157+
bucket = bucket->next;
158+
}
159+
160+
if ( inBounds )
161+
{
162+
// Add the node in front of the free list.
163+
*(void**)ptr = ba->freelist;
164+
ba->freelist = ptr;
165+
}
166+
else
167+
{
168+
printf("ERROR! pointer 0x%p does not belong to allocator '%s'\n", ba->name);
169+
}
170+
#else
171+
// Add the node in front of the free list.
172+
*(void**)ptr = ba->freelist;
173+
ba->freelist = ptr;
174+
#endif
175+
}
176+
177+
void deleteBucketAlloc( struct BucketAlloc *ba )
178+
{
179+
TESSalloc* alloc = ba->alloc;
180+
Bucket *bucket = ba->buckets;
181+
Bucket *next;
182+
while ( bucket )
183+
{
184+
next = bucket->next;
185+
alloc->memfree( alloc->userData, bucket );
186+
bucket = next;
187+
}
188+
ba->freelist = 0;
189+
ba->buckets = 0;
190+
alloc->memfree( alloc->userData, ba );
191+
}

src/bucketalloc.h

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
** SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3+
** Copyright (C) [dates of first publication] Silicon Graphics, Inc.
4+
** All Rights Reserved.
5+
**
6+
** Permission is hereby granted, free of charge, to any person obtaining a copy
7+
** of this software and associated documentation files (the "Software"), to deal
8+
** in the Software without restriction, including without limitation the rights
9+
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10+
** of the Software, and to permit persons to whom the Software is furnished to do so,
11+
** subject to the following conditions:
12+
**
13+
** The above copyright notice including the dates of first publication and either this
14+
** permission notice or a reference to http://oss.sgi.com/projects/FreeB/ shall be
15+
** included in all copies or substantial portions of the Software.
16+
**
17+
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18+
** INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
19+
** PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL SILICON GRAPHICS, INC.
20+
** BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21+
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
22+
** OR OTHER DEALINGS IN THE SOFTWARE.
23+
**
24+
** Except as contained in this notice, the name of Silicon Graphics, Inc. shall not
25+
** be used in advertising or otherwise to promote the sale, use or other dealings in
26+
** this Software without prior written authorization from Silicon Graphics, Inc.
27+
*/
28+
/*
29+
** Author: Mikko Mononen, July 2009.
30+
*/
31+
32+
#ifndef MEMALLOC_H
33+
#define MEMALLOC_H
34+
35+
#ifdef __cplusplus
36+
extern "C" {
37+
#endif
38+
39+
#include "tesselator.h"
40+
41+
struct BucketAlloc *createBucketAlloc( TESSalloc* alloc, const char *name,
42+
unsigned int itemSize, unsigned int bucketSize );
43+
void *bucketAlloc( struct BucketAlloc *ba);
44+
void bucketFree( struct BucketAlloc *ba, void *ptr );
45+
void deleteBucketAlloc( struct BucketAlloc *ba );
46+
47+
#ifdef __cplusplus
48+
};
49+
#endif
50+
51+
#endif

src/dict.c

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
** SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3+
** Copyright (C) [dates of first publication] Silicon Graphics, Inc.
4+
** All Rights Reserved.
5+
**
6+
** Permission is hereby granted, free of charge, to any person obtaining a copy
7+
** of this software and associated documentation files (the "Software"), to deal
8+
** in the Software without restriction, including without limitation the rights
9+
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10+
** of the Software, and to permit persons to whom the Software is furnished to do so,
11+
** subject to the following conditions:
12+
**
13+
** The above copyright notice including the dates of first publication and either this
14+
** permission notice or a reference to http://oss.sgi.com/projects/FreeB/ shall be
15+
** included in all copies or substantial portions of the Software.
16+
**
17+
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18+
** INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
19+
** PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL SILICON GRAPHICS, INC.
20+
** BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21+
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
22+
** OR OTHER DEALINGS IN THE SOFTWARE.
23+
**
24+
** Except as contained in this notice, the name of Silicon Graphics, Inc. shall not
25+
** be used in advertising or otherwise to promote the sale, use or other dealings in
26+
** this Software without prior written authorization from Silicon Graphics, Inc.
27+
*/
28+
/*
29+
** Author: Eric Veach, July 1994.
30+
*/
31+
32+
#include <stddef.h>
33+
#include "tesselator.h"
34+
#include "bucketalloc.h"
35+
#include "dict.h"
36+
37+
/* really tessDictListNewDict */
38+
Dict *dictNewDict( TESSalloc* alloc, void *frame, int (*leq)(void *frame, DictKey key1, DictKey key2) )
39+
{
40+
Dict *dict = (Dict *)alloc->memalloc( alloc->userData, sizeof( Dict ));
41+
DictNode *head;
42+
43+
if (dict == NULL) return NULL;
44+
45+
head = &dict->head;
46+
47+
head->key = NULL;
48+
head->next = head;
49+
head->prev = head;
50+
51+
dict->frame = frame;
52+
dict->leq = leq;
53+
54+
if (alloc->dictNodeBucketSize < 16)
55+
alloc->dictNodeBucketSize = 16;
56+
if (alloc->dictNodeBucketSize > 4096)
57+
alloc->dictNodeBucketSize = 4096;
58+
dict->nodePool = createBucketAlloc( alloc, "Dict", sizeof(DictNode), alloc->dictNodeBucketSize );
59+
60+
return dict;
61+
}
62+
63+
/* really tessDictListDeleteDict */
64+
void dictDeleteDict( TESSalloc* alloc, Dict *dict )
65+
{
66+
deleteBucketAlloc( dict->nodePool );
67+
alloc->memfree( alloc->userData, dict );
68+
}
69+
70+
/* really tessDictListInsertBefore */
71+
DictNode *dictInsertBefore( Dict *dict, DictNode *node, DictKey key )
72+
{
73+
DictNode *newNode;
74+
75+
do {
76+
node = node->prev;
77+
} while( node->key != NULL && ! (*dict->leq)(dict->frame, node->key, key));
78+
79+
newNode = (DictNode *)bucketAlloc( dict->nodePool );
80+
if (newNode == NULL) return NULL;
81+
82+
newNode->key = key;
83+
newNode->next = node->next;
84+
node->next->prev = newNode;
85+
newNode->prev = node;
86+
node->next = newNode;
87+
88+
return newNode;
89+
}
90+
91+
/* really tessDictListDelete */
92+
void dictDelete( Dict *dict, DictNode *node ) /*ARGSUSED*/
93+
{
94+
node->next->prev = node->prev;
95+
node->prev->next = node->next;
96+
bucketFree( dict->nodePool, node );
97+
}
98+
99+
/* really tessDictListSearch */
100+
DictNode *dictSearch( Dict *dict, DictKey key )
101+
{
102+
DictNode *node = &dict->head;
103+
104+
do {
105+
node = node->next;
106+
} while( node->key != NULL && ! (*dict->leq)(dict->frame, key, node->key));
107+
108+
return node;
109+
}

0 commit comments

Comments
 (0)