commit | author | age
|
d7639a
|
1 |
#include<stdlib.h> |
SP |
2 |
#include<stdio.h> |
|
3 |
#include "general.h" |
|
4 |
#include "triangle.h" |
|
5 |
#include<math.h> |
|
6 |
|
bb77ca
|
7 |
/** @brief Prepares the list for triangles. |
SP |
8 |
* |
|
9 |
* Create empty list for holding the information on triangles. Triangles are |
|
10 |
* added later on with triangle_add(). |
|
11 |
* Returns pointer to the tlist datastructure it has created. This pointer must |
|
12 |
* be assigned to some variable or it will be lost. |
|
13 |
* |
|
14 |
* |
|
15 |
* Example of usage: |
|
16 |
* ts_triangle_list *tlist; |
|
17 |
* tlist=triangle_data_free(); |
|
18 |
* |
|
19 |
* Initalized data structure for holding the information on triangles. |
|
20 |
* |
|
21 |
*/ |
a2a676
|
22 |
ts_triangle_list *init_triangle_list(){ |
SP |
23 |
ts_triangle_list *tlist=(ts_triangle_list *)malloc(sizeof(ts_triangle_list)); |
d7639a
|
24 |
tlist->n = 0; |
a2a676
|
25 |
tlist->tria=NULL; |
SP |
26 |
return tlist; |
d7639a
|
27 |
} |
SP |
28 |
|
bb77ca
|
29 |
/** @brief Add the triangle to the triangle list and create necessary data |
SP |
30 |
* structures. |
|
31 |
* |
|
32 |
* Add the triangle ts_triangle with ts_triangle_data to the ts_triangle_list. |
|
33 |
* The triangle list is resized, the ts_triangle is allocated and |
|
34 |
* ts_triangle_data is allocated and zeroed. The function receives 4 arguments: |
|
35 |
* ts_triangle_list *tlist as list of triangles and 3 ts_vertex *vtx as |
|
36 |
* vertices that are used to form a triangle. Returns a pointer to newly |
|
37 |
* created triangle. This pointer doesn't need assigning, since it is |
|
38 |
* referenced by triangle list. |
|
39 |
* |
|
40 |
* WARNING: Function can be accelerated a bit by removing the NULL checks. |
|
41 |
* However the time gained by removal doesn't justify the time spent by |
|
42 |
* debugging stupid NULL pointers. |
|
43 |
* |
|
44 |
* Example of usage: |
|
45 |
* triangle_add(tlist, vlist->vtx[1], vlist->vtx[2], vlist->vtx[3]); |
|
46 |
* |
|
47 |
* Creates a triangle with given vertices and puts it into the list. |
|
48 |
* |
|
49 |
*/ |
a2a676
|
50 |
ts_triangle *triangle_add(ts_triangle_list *tlist, ts_vertex *vtx1, ts_vertex *vtx2, ts_vertex *vtx3){ |
SP |
51 |
if(vtx1==NULL || vtx2==NULL || vtx3==NULL){ |
|
52 |
return NULL; |
|
53 |
} |
d7639a
|
54 |
tlist->n++; |
a2a676
|
55 |
tlist->tria=(ts_triangle **)realloc(tlist->tria,tlist->n*sizeof(ts_triangle *)); |
SP |
56 |
if(tlist->tria==NULL) fatal("Cannot reallocate memory for additional ts_triangle.",5); |
|
57 |
|
|
58 |
tlist->tria[tlist->n-1]=(ts_triangle *)calloc(1,sizeof(ts_triangle)); |
|
59 |
if(tlist->tria[tlist->n-1]==NULL) fatal("Cannot reallocate memory for additional ts_triangle.",5); |
41a035
|
60 |
// tlist->tria[tlist->n-1]->data=(ts_triangle_data *)calloc(1,sizeof(ts_triangle_data)); |
a2a676
|
61 |
|
d7639a
|
62 |
//NOW insert vertices! |
a2a676
|
63 |
tlist->tria[tlist->n - 1]->idx=tlist->n-1; |
41a035
|
64 |
tlist->tria[tlist->n - 1]->vertex[0]=vtx1; |
SP |
65 |
tlist->tria[tlist->n - 1]->vertex[1]=vtx2; |
|
66 |
tlist->tria[tlist->n - 1]->vertex[2]=vtx3; |
a2a676
|
67 |
return tlist->tria[tlist->n-1]; |
d7639a
|
68 |
} |
SP |
69 |
|
bb77ca
|
70 |
/** @brief Add the neigbour to triangles. |
SP |
71 |
* |
|
72 |
* Add the neigbour to the list of neighbouring triangles. The |
|
73 |
* neighbouring triangles are those, who share two vertices. Function resizes |
|
74 |
* the list and adds the pointer to neighbour. It receives two arguments of |
dac2e5
|
75 |
* ts_triangle type. It then adds second triangle to the list of first |
SP |
76 |
* triangle, but not the opposite. Upon |
bb77ca
|
77 |
* success it returns TS_SUCCESS, upon detecting NULL pointers |
SP |
78 |
* returns TS_FAIL and it FATALY ends when the data structure |
|
79 |
* cannot be resized. |
|
80 |
* |
|
81 |
* |
|
82 |
* WARNING: Function can be accelerated a bit by removing the NULL checks. |
|
83 |
* However the time gained by removal doesn't justify the time spent by |
|
84 |
* debugging stupid NULL pointers. |
|
85 |
* |
|
86 |
* Example of usage: |
|
87 |
* triangle_remove_neighbour(tlist->tria[3], tlist->tria[4]); |
|
88 |
* |
|
89 |
* Triangles 3 and 4 are not neighbours anymore. |
|
90 |
* |
|
91 |
*/ |
d7639a
|
92 |
|
SP |
93 |
ts_bool triangle_add_neighbour(ts_triangle *tria, ts_triangle *ntria){ |
a2a676
|
94 |
if(tria==NULL || ntria==NULL) return TS_FAIL; |
SP |
95 |
/*TODO: check if the neighbour already exists! Now there is no such check |
|
96 |
* because of the performance issue. */ |
41a035
|
97 |
tria->neigh_no++; |
SP |
98 |
tria->neigh=realloc(tria->neigh,tria->neigh_no*sizeof(ts_triangle *)); |
|
99 |
if(tria->neigh == NULL) |
d7639a
|
100 |
fatal("Reallocation of memory failed during insertion of triangle neighbour in triangle_add_neighbour",3); |
41a035
|
101 |
tria->neigh[tria->neigh_no-1]=ntria; |
3131dc
|
102 |
|
SP |
103 |
|
a2a676
|
104 |
/* we repeat the procedure for the neighbour */ |
3131dc
|
105 |
/* ntria->data->neigh_no++; |
a2a676
|
106 |
ntria->data->neigh=realloc(ntria->data->neigh,ntria->data->neigh_no*sizeof(ts_triangle *)); |
SP |
107 |
if(ntria->data->neigh == NULL) |
|
108 |
fatal("Reallocation of memory failed during insertion of triangle neighbour in triangle_add_neighbour",3); |
|
109 |
ntria->data->neigh[ntria->data->neigh_no-1]=tria; |
3131dc
|
110 |
*/ |
d7639a
|
111 |
return TS_SUCCESS; |
SP |
112 |
} |
|
113 |
|
bb77ca
|
114 |
/** @brief Remove the neigbours from triangle. |
SP |
115 |
* |
|
116 |
* Removes the neigbour from the list of neighbouring triangles. The |
|
117 |
* neighbouring triangles are those, who share two vertices. Function resizes |
|
118 |
* the list and deletes the pointer to neighbour. It receives two arguments of |
|
119 |
* ts_triangle type. It then removes eachother form eachother's list. Upon |
|
120 |
* success it returns TS_SUCCESS, upon failure to find the triangle in the |
|
121 |
* neighbour list returns TS_FAIL and it FATALY ends when the datastructure |
|
122 |
* cannot be resized. |
|
123 |
* |
|
124 |
* WARNING: The function doesn't check whether the pointer is NULL or invalid. It is the |
|
125 |
* job of programmer to make sure the pointer is valid. |
|
126 |
* |
|
127 |
* WARNING: Function is slow. Do not use it often! |
|
128 |
* |
|
129 |
* Example of usage: |
|
130 |
* triangle_remove_neighbour(tlist->tria[3], tlist->tria[4]); |
|
131 |
* |
|
132 |
* Triangles 3 and 4 are not neighbours anymore. |
|
133 |
* |
|
134 |
*/ |
d7639a
|
135 |
ts_bool triangle_remove_neighbour(ts_triangle *tria, ts_triangle *ntria){ |
a2a676
|
136 |
ts_uint i,j=0; |
SP |
137 |
if(tria==NULL || ntria==NULL) return TS_FAIL; |
|
138 |
|
41a035
|
139 |
for(i=0;i<tria->neigh_no;i++){ |
SP |
140 |
if(tria->neigh[i]!=ntria){ |
|
141 |
tria->neigh[j]=tria->neigh[i]; |
d7639a
|
142 |
j++; |
SP |
143 |
} |
|
144 |
} |
a2a676
|
145 |
if(j==i) { |
SP |
146 |
return TS_FAIL; |
|
147 |
//fatal("In triangle_remove_neighbour: Specified neighbour does not exist for given triangle",3); |
|
148 |
} |
41a035
|
149 |
tria->neigh_no--; |
SP |
150 |
tria->neigh=(ts_triangle **)realloc(tria->neigh,tria->neigh_no*sizeof(ts_triangle *)); |
|
151 |
if(tria->neigh == NULL){ |
a2a676
|
152 |
fatal("Reallocation of memory failed during removal of vertex neighbour in triangle_remove_neighbour",100); |
SP |
153 |
} |
|
154 |
/* we repeat the procedure for neighbour */ |
41a035
|
155 |
for(i=0;i<ntria->neigh_no;i++){ |
SP |
156 |
if(ntria->neigh[i]!=tria){ |
|
157 |
ntria->neigh[j]=ntria->neigh[i]; |
a2a676
|
158 |
j++; |
SP |
159 |
} |
|
160 |
} |
|
161 |
if(j==i) { |
|
162 |
return TS_FAIL; |
|
163 |
//fatal("In triangle_remove_neighbour: Specified neighbour does not exist for given triangle",3); |
|
164 |
} |
41a035
|
165 |
ntria->neigh_no--; |
SP |
166 |
ntria->neigh=(ts_triangle **)realloc(ntria->neigh,ntria->neigh_no*sizeof(ts_triangle *)); |
|
167 |
if(ntria->neigh == NULL){ |
a2a676
|
168 |
fatal("Reallocation of memory failed during removal of vertex neighbour in triangle_remove_neighbour",100); |
SP |
169 |
} |
d7639a
|
170 |
return TS_SUCCESS; |
SP |
171 |
} |
|
172 |
|
bb77ca
|
173 |
|
SP |
174 |
/** @brief Calculates normal vector of the triangle. |
|
175 |
|
|
176 |
* |
|
177 |
* Calculate normal vector of the triangle (xnorm, ynorm and znorm) and stores |
|
178 |
* information in underlying ts_triangle_data data_structure. |
|
179 |
* |
|
180 |
* Function receives one argument of type ts_triangle. It should be corectly |
|
181 |
* initialized with underlying data structure of type ts_triangle_data. the |
|
182 |
* result is stored in triangle->data->xnorm, triangle->data->ynorm, |
|
183 |
* triangle->data->znorm. Returns TS_SUCCESS on completion. |
|
184 |
* |
|
185 |
* NOTE: Function uses math.h library. pow function implementation is selected |
|
186 |
* accordind to the setting in genreal.h |
|
187 |
* |
|
188 |
* Example of usage: |
|
189 |
* triangle_normal_vector(tlist->tria[3]); |
|
190 |
* |
|
191 |
* Computes normals and stores information into tlist->tria[3]->xnorm, |
|
192 |
* tlist->tria[3]->ynorm, tlist->tria[3]->znorm. |
|
193 |
* |
|
194 |
*/ |
d7639a
|
195 |
ts_bool triangle_normal_vector(ts_triangle *tria){ |
SP |
196 |
ts_double x21,x31,y21,y31,z21,z31,xden; |
8f6a69
|
197 |
x21=tria->vertex[1]->x - tria->vertex[0]->x; |
SP |
198 |
x31=tria->vertex[2]->x - tria->vertex[0]->x; |
|
199 |
y21=tria->vertex[1]->y - tria->vertex[0]->y; |
|
200 |
y31=tria->vertex[2]->y - tria->vertex[0]->y; |
|
201 |
z21=tria->vertex[1]->z - tria->vertex[0]->z; |
|
202 |
z31=tria->vertex[2]->z - tria->vertex[0]->z; |
d7639a
|
203 |
|
41a035
|
204 |
tria->xnorm=y21*z31 - z21*y31; |
SP |
205 |
tria->ynorm=z21*x31 - x21*z31; |
|
206 |
tria->znorm=x21*y31 - y21*x31; |
|
207 |
xden=tria->xnorm*tria->xnorm + |
|
208 |
tria->ynorm*tria->ynorm + |
|
209 |
tria->znorm*tria->znorm; |
d7639a
|
210 |
#ifdef TS_DOUBLE_DOUBLE |
SP |
211 |
xden=sqrt(xden); |
|
212 |
#endif |
|
213 |
#ifdef TS_DOUBLE_FLOAT |
|
214 |
xden=sqrtf(xden); |
|
215 |
#endif |
|
216 |
#ifdef TS_DOUBLE_LONGDOUBLE |
|
217 |
xden=sqrtl(xden); |
|
218 |
#endif |
41a035
|
219 |
tria->xnorm=tria->xnorm/xden; |
SP |
220 |
tria->ynorm=tria->ynorm/xden; |
|
221 |
tria->znorm=tria->znorm/xden; |
d7639a
|
222 |
return TS_SUCCESS; |
SP |
223 |
} |
|
224 |
|
|
225 |
|
bb77ca
|
226 |
|
SP |
227 |
|
|
228 |
|
d7639a
|
229 |
|
bb77ca
|
230 |
/** @brief Frees the memory allocated for data structure of triangle list |
SP |
231 |
* (ts_triangle_list) |
|
232 |
* |
|
233 |
* Function frees the memory of ts_triangle_list previously allocated. It |
|
234 |
* accepts one argument, the address of data structure. It destroys all |
|
235 |
* ts_triangle's in the list with underlying data (by calling |
|
236 |
* triangle_data_free()), and the list itself. |
|
237 |
* |
|
238 |
* Should be used eveytime the deletion of triangle list (created by |
|
239 |
* init_triangle_list() and altered by add_triangle() or remove_triangle()) is desired. |
|
240 |
* |
|
241 |
* WARNING: The function doesn't check whether the pointer is NULL or invalid. It is the |
|
242 |
* job of programmer to make sure the pointer is valid. |
|
243 |
* |
|
244 |
* WARNING: Careful when destroying triangle lists. There could be pointers to |
|
245 |
* that information remaining in structures like vertex_data. This pointers |
|
246 |
* will be rendered invalid by this operation and should not be used anymore. |
|
247 |
* |
|
248 |
* Example of usage: |
|
249 |
* triangle_list_free(tlist); |
|
250 |
* |
|
251 |
* Clears all the information on triangles. |
|
252 |
* |
|
253 |
*/ |
d7639a
|
254 |
ts_bool triangle_list_free(ts_triangle_list *tlist){ |
a2a676
|
255 |
ts_uint i; |
d7639a
|
256 |
for(i=0;i<tlist->n;i++){ |
41a035
|
257 |
if(tlist->tria[i]->neigh!=NULL) free(tlist->tria[i]->neigh); |
a2a676
|
258 |
free(tlist->tria[i]); |
d7639a
|
259 |
} |
a2a676
|
260 |
free(tlist->tria); |
SP |
261 |
free(tlist); |
d7639a
|
262 |
return TS_SUCCESS; |
SP |
263 |
} |
|
264 |
|