Branch data Line data Source code
1 : : #include "GMem.hpp"
2 : : #include <cstring> // To define NULL
3 : : #include "CubitVector.hpp"
4 : : #include "DLIList.hpp"
5 : : #include "OctTree.hpp"
6 : : #include "CubitTransformMatrix.hpp"
7 : :
8 : 1219 : GMem::GMem()
9 : : {
10 : 1219 : ptsSize = 0;
11 : 1219 : fListSize = 0;
12 : 1219 : pointListCount = 0;
13 : 1219 : fListCount = 0;
14 : 1219 : pointList = NULL;
15 : 1219 : facetList = NULL;
16 : 1219 : pointsConsolidated = CUBIT_FALSE;
17 : 1219 : }
18 : :
19 : 1219 : GMem::~GMem()
20 : : {
21 [ + + ]: 1219 : if (pointList)
22 [ + - ]: 1120 : delete [] pointList;
23 [ + + ]: 1219 : if (facetList)
24 [ + - ]: 468 : delete [] facetList;
25 : 1219 : }
26 : :
27 : 0 : void GMem::allocate_tri(int num_tri)
28 : : {
29 [ # # ]: 0 : if (num_tri*3 > ptsSize)
30 : : {
31 [ # # ]: 0 : if (pointList)
32 [ # # ]: 0 : delete [] pointList;
33 : 0 : ptsSize = 3 * num_tri;
34 [ # # ]: 0 : pointList = new GPoint[ptsSize];
35 : : }
36 [ # # ]: 0 : if (num_tri*4 > fListSize)
37 : : {
38 [ # # ]: 0 : if (facetList)
39 [ # # ]: 0 : delete [] facetList;
40 : 0 : fListSize = 4 * num_tri;
41 [ # # ]: 0 : facetList = new int[fListSize];
42 : : }
43 : 0 : }
44 : :
45 : : // Allocates space for a polyline consisting of
46 : : // {num_lines} segments. This is num_lines + 1 pointList.
47 : 0 : void GMem::allocate_polylines(int num_lines)
48 : : {
49 : 0 : num_lines++;
50 [ # # ]: 0 : if (num_lines > ptsSize)
51 : : {
52 [ # # ]: 0 : if (pointList)
53 [ # # ]: 0 : delete [] pointList;
54 : 0 : ptsSize = num_lines;
55 [ # # ]: 0 : pointList = new GPoint[ptsSize];
56 : : }
57 : 0 : }
58 : :
59 : : // Allocates additional space for a bigger polyline.
60 : : // The total number of points will now be
61 : : // pointListCount + num_additional_segs.
62 : 0 : void GMem::allocate_more_polylines(int num_additional_segs)
63 : : {
64 : : // Make sure we need to do something
65 [ # # ]: 0 : if (num_additional_segs <= 0)
66 : 0 : return;
67 : : // If there are no points, we need space for one additional point
68 [ # # ]: 0 : if (pointListCount == 0)
69 : 0 : num_additional_segs++;
70 : : // Make sure we need to grow
71 [ # # ]: 0 : if (ptsSize >= pointListCount + num_additional_segs)
72 : 0 : return;
73 : :
74 : : // Make a big enough array of points
75 [ # # ]: 0 : GPoint *new_points = new GPoint[pointListCount + num_additional_segs];
76 : : // Copy the old data to the new array
77 [ # # ]: 0 : if (pointList)
78 : : {
79 : 0 : memcpy (new_points, pointList, pointListCount*sizeof(GPoint));
80 [ # # ]: 0 : delete []pointList;
81 : : }
82 : : // Store the new array in 'pointList'
83 : 0 : pointList = new_points;
84 : 0 : ptsSize = pointListCount + num_additional_segs;
85 : : }
86 : :
87 : 8040 : void GMem::clean_out()
88 : : {
89 : 8040 : pointListCount = 0;
90 : 8040 : fListCount = 0;
91 : 8040 : }
92 : :
93 : :
94 : 8907 : void GMem::replace_point_list(GPoint new_point_list[], int num_valid_points,
95 : : int array_size)
96 : : {
97 : : // First, delete the old memory
98 [ + + ]: 8907 : if (pointList)
99 [ + - ]: 7787 : delete [] pointList;
100 : : // Now replace it with the new
101 : 8907 : pointList = new_point_list;
102 : : // Set the array size
103 : 8907 : ptsSize = array_size;
104 : : // Set the number of valid entries
105 : 8907 : pointListCount = num_valid_points;
106 : 8907 : }
107 : :
108 : 2943 : void GMem::replace_facet_list(int new_facet_list[], int num_valid_entries,
109 : : int array_size)
110 : : {
111 : : // First, delete the old memory
112 [ + + ]: 2943 : if (facetList)
113 [ + - ]: 2475 : delete [] facetList;
114 : : // Now replace it with the new
115 : 2943 : facetList = new_facet_list;
116 : : // Set the array size
117 : 2943 : fListSize = array_size;
118 : : // Set the number of valid entries
119 : 2943 : fListCount = num_valid_entries;
120 : 2943 : }
121 : :
122 : : // copy constructor
123 : 0 : GMem::GMem(const GMem& from)
124 : : {
125 : : // Set the array pointers to NULL
126 : 0 : pointList = NULL;
127 : 0 : facetList = NULL;
128 : : // Set one equal to the other
129 : 0 : *this = from;
130 : 0 : }
131 : :
132 : : // Equality operator
133 : 0 : GMem& GMem::operator=(const GMem& from)
134 : : {
135 [ # # ]: 0 : if (this != &from)
136 : : {
137 : : // Make a copy of the point array
138 [ # # ]: 0 : GPoint* temp1 = new GPoint[from.ptsSize];
139 : 0 : memcpy (temp1, from.pointList, from.ptsSize*sizeof(GPoint));
140 : : // Put it in the receiving GMem
141 : 0 : replace_point_list(temp1, from.pointListCount, from.ptsSize);
142 : : // Make a copy of the facet array
143 [ # # ]: 0 : int* temp2 = new int[from.fListSize];
144 : 0 : memcpy (temp2, from.facetList, from.fListSize*sizeof(int));
145 : : // Put it in the receiving GMem
146 : 0 : replace_facet_list(temp2, from.fListCount, from.fListSize);
147 : : // Set whether it's consolidated
148 : 0 : pointsConsolidated = from.pointsConsolidated;
149 : : }
150 : 0 : return *this;
151 : : }
152 : :
153 : :
154 : 0 : void GMem::consolidate_points( double tolerance )
155 : : {
156 [ # # ]: 0 : if ( pointListCount < 1000 )
157 : 0 : consolidate_few_points( tolerance );
158 : : else
159 : 0 : consolidate_many_points( tolerance );
160 : 0 : }
161 : :
162 : 0 : void GMem::consolidate_few_points( double tolerance )
163 : : {
164 : 0 : const double tolsqr = tolerance * tolerance;
165 [ # # ]: 0 : int* index_map = new int[pointListCount];
166 : :
167 : : // Consolidate the point list. index_map is used
168 : : // to maintain a map between the old index of a point
169 : : // (the index into index_map) and the new index of a
170 : : // point (the value in index_map).
171 : 0 : int write = 0, read, comp;
172 [ # # ]: 0 : for( read = 0; read < pointListCount; read++ )
173 : : {
174 : 0 : const GPoint& pti = pointList[read];
175 [ # # ]: 0 : for( comp = 0; comp < write; comp++ )
176 : : {
177 : 0 : const GPoint& ptj = pointList[comp];
178 : 0 : double x = pti.x - ptj.x;
179 : 0 : double y = pti.y - ptj.y;
180 : 0 : double z = pti.z - ptj.z;
181 [ # # ]: 0 : if( (x*x+y*y+z*z) <= tolsqr )
182 : 0 : break;
183 : : }
184 : :
185 : 0 : index_map[read] = comp;
186 [ # # ]: 0 : if( comp == write )
187 : : {
188 : 0 : pointList[comp] = pointList[read];
189 : 0 : write++;
190 : : }
191 : : }
192 : 0 : pointListCount = write;
193 : :
194 : : // Update the facet list using values from index_map.
195 : 0 : int *itor = facetList;
196 : 0 : const int* end = facetList + fListCount;
197 [ # # ]: 0 : while( itor < end )
198 [ # # ]: 0 : for( int count = *(itor++); count--; itor++ )
199 : 0 : *itor = index_map[*itor];
200 : :
201 [ # # ]: 0 : delete [] index_map;
202 : 0 : pointsConsolidated = CUBIT_TRUE;
203 : 0 : }
204 : :
205 : : class GPointOctTreeEval {
206 : 0 : public: static inline CubitVector coordinates(GPoint* p)
207 : 0 : { return CubitVector( p->x, p->y, p->z ); }
208 : : };
209 : :
210 : 0 : void GMem::consolidate_many_points( double tolerance )
211 : : {
212 : 0 : const double tolsqr = tolerance * tolerance;
213 : :
214 : : // build OctTree
215 [ # # ]: 0 : DLIList<GPoint*> point_list(pointListCount);
216 : 0 : GPoint* p_itor = pointList;
217 : 0 : GPoint* p_end = p_itor + pointListCount;
218 [ # # ]: 0 : while( p_itor < p_end )
219 [ # # ]: 0 : point_list.append( p_itor++ );
220 [ # # ][ # # ]: 0 : OctTree<GPoint, GPointOctTreeEval> tree( point_list, tolerance );
221 [ # # ]: 0 : point_list.clean_out();
222 : :
223 : : // Consolidate the point list. index_map is used
224 : : // to maintain a map between the old index of a point
225 : : // (the index into index_map) and the new index of a
226 : : // point (the value in index_map).
227 [ # # ][ # # ]: 0 : int* index_map = new int[pointListCount];
228 [ # # ][ # # ]: 0 : GPoint* new_array = new GPoint[pointListCount];
229 : 0 : int read, write = 0;
230 [ # # ]: 0 : for ( read = 0; read < pointListCount; read++)
231 : : {
232 : 0 : GPoint* pt = pointList + read;
233 [ # # ]: 0 : CubitVector v(pt->x, pt->y, pt->z);
234 : 0 : index_map[read] = write;
235 [ # # ]: 0 : point_list.clean_out();
236 [ # # ]: 0 : tree.nodes_near( v, point_list );
237 [ # # ][ # # ]: 0 : while ( point_list.size() )
238 : : {
239 [ # # ]: 0 : GPoint* p = point_list.pop();
240 : 0 : int index = p - pointList;
241 [ # # ][ # # ]: 0 : assert( (index >= 0) && (index < pointListCount) );
242 [ # # ]: 0 : CubitVector v2(p->x, p->y, p->z);
243 [ # # ][ # # ]: 0 : if ( (index < read) && ((v - v2).length_squared() < tolsqr) )
[ # # ][ # # ]
[ # # ]
[ # # # # ]
244 : : {
245 : 0 : index_map[read] = index_map[index];
246 : 0 : break;
247 : : }
248 : : }
249 : :
250 [ # # ]: 0 : if ( index_map[read] == write )
251 : : {
252 : 0 : new_array[write++] = pointList[read];
253 : : }
254 : : }
255 : 0 : pointListCount = write;
256 [ # # ]: 0 : delete [] pointList;
257 : 0 : pointList = new_array;
258 : :
259 : : // Update the facet list using values from index_map.
260 : 0 : int *itor = facetList;
261 : 0 : const int* end = facetList + fListCount;
262 [ # # ]: 0 : while( itor < end )
263 [ # # ]: 0 : for( int count = *(itor++); count--; itor++ )
264 : 0 : *itor = index_map[*itor];
265 : :
266 [ # # ]: 0 : delete [] index_map;
267 [ # # ]: 0 : pointsConsolidated = CUBIT_TRUE;
268 : 0 : }
269 : :
270 : 0 : void GMem::transform(CubitTransformMatrix &transform)
271 : : {
272 : 0 : int i=0;
273 [ # # ]: 0 : CubitVector temp_point;
274 [ # # ]: 0 : for (i=0; i<this->pointListCount; i++)
275 : : {
276 [ # # ]: 0 : temp_point.set(pointList[i].x, pointList[i].y, pointList[i].z);
277 [ # # ][ # # ]: 0 : temp_point = transform * temp_point;
278 [ # # ]: 0 : pointList[i].x = (float)temp_point.x();
279 [ # # ]: 0 : pointList[i].y = (float)temp_point.y();
280 [ # # ]: 0 : pointList[i].z = (float)temp_point.z();
281 : : }
282 : 0 : }
|