cgma
|
00001 #include "GMem.hpp" 00002 #include <cstring> // To define NULL 00003 #include "CubitVector.hpp" 00004 #include "DLIList.hpp" 00005 #include "OctTree.hpp" 00006 #include "CubitTransformMatrix.hpp" 00007 00008 GMem::GMem() 00009 { 00010 ptsSize = 0; 00011 fListSize = 0; 00012 pointListCount = 0; 00013 fListCount = 0; 00014 pointList = NULL; 00015 facetList = NULL; 00016 pointsConsolidated = CUBIT_FALSE; 00017 } 00018 00019 GMem::~GMem() 00020 { 00021 if (pointList) 00022 delete [] pointList; 00023 if (facetList) 00024 delete [] facetList; 00025 } 00026 00027 void GMem::allocate_tri(int num_tri) 00028 { 00029 if (num_tri*3 > ptsSize) 00030 { 00031 if (pointList) 00032 delete [] pointList; 00033 ptsSize = 3 * num_tri; 00034 pointList = new GPoint[ptsSize]; 00035 } 00036 if (num_tri*4 > fListSize) 00037 { 00038 if (facetList) 00039 delete [] facetList; 00040 fListSize = 4 * num_tri; 00041 facetList = new int[fListSize]; 00042 } 00043 } 00044 00045 // Allocates space for a polyline consisting of 00046 // {num_lines} segments. This is num_lines + 1 pointList. 00047 void GMem::allocate_polylines(int num_lines) 00048 { 00049 num_lines++; 00050 if (num_lines > ptsSize) 00051 { 00052 if (pointList) 00053 delete [] pointList; 00054 ptsSize = num_lines; 00055 pointList = new GPoint[ptsSize]; 00056 } 00057 } 00058 00059 // Allocates additional space for a bigger polyline. 00060 // The total number of points will now be 00061 // pointListCount + num_additional_segs. 00062 void GMem::allocate_more_polylines(int num_additional_segs) 00063 { 00064 // Make sure we need to do something 00065 if (num_additional_segs <= 0) 00066 return; 00067 // If there are no points, we need space for one additional point 00068 if (pointListCount == 0) 00069 num_additional_segs++; 00070 // Make sure we need to grow 00071 if (ptsSize >= pointListCount + num_additional_segs) 00072 return; 00073 00074 // Make a big enough array of points 00075 GPoint *new_points = new GPoint[pointListCount + num_additional_segs]; 00076 // Copy the old data to the new array 00077 if (pointList) 00078 { 00079 memcpy (new_points, pointList, pointListCount*sizeof(GPoint)); 00080 delete []pointList; 00081 } 00082 // Store the new array in 'pointList' 00083 pointList = new_points; 00084 ptsSize = pointListCount + num_additional_segs; 00085 } 00086 00087 void GMem::clean_out() 00088 { 00089 pointListCount = 0; 00090 fListCount = 0; 00091 } 00092 00093 00094 void GMem::replace_point_list(GPoint new_point_list[], int num_valid_points, 00095 int array_size) 00096 { 00097 // First, delete the old memory 00098 if (pointList) 00099 delete [] pointList; 00100 // Now replace it with the new 00101 pointList = new_point_list; 00102 // Set the array size 00103 ptsSize = array_size; 00104 // Set the number of valid entries 00105 pointListCount = num_valid_points; 00106 } 00107 00108 void GMem::replace_facet_list(int new_facet_list[], int num_valid_entries, 00109 int array_size) 00110 { 00111 // First, delete the old memory 00112 if (facetList) 00113 delete [] facetList; 00114 // Now replace it with the new 00115 facetList = new_facet_list; 00116 // Set the array size 00117 fListSize = array_size; 00118 // Set the number of valid entries 00119 fListCount = num_valid_entries; 00120 } 00121 00122 // copy constructor 00123 GMem::GMem(const GMem& from) 00124 { 00125 // Set the array pointers to NULL 00126 pointList = NULL; 00127 facetList = NULL; 00128 // Set one equal to the other 00129 *this = from; 00130 } 00131 00132 // Equality operator 00133 GMem& GMem::operator=(const GMem& from) 00134 { 00135 if (this != &from) 00136 { 00137 // Make a copy of the point array 00138 GPoint* temp1 = new GPoint[from.ptsSize]; 00139 memcpy (temp1, from.pointList, from.ptsSize*sizeof(GPoint)); 00140 // Put it in the receiving GMem 00141 replace_point_list(temp1, from.pointListCount, from.ptsSize); 00142 // Make a copy of the facet array 00143 int* temp2 = new int[from.fListSize]; 00144 memcpy (temp2, from.facetList, from.fListSize*sizeof(int)); 00145 // Put it in the receiving GMem 00146 replace_facet_list(temp2, from.fListCount, from.fListSize); 00147 // Set whether it's consolidated 00148 pointsConsolidated = from.pointsConsolidated; 00149 } 00150 return *this; 00151 } 00152 00153 00154 void GMem::consolidate_points( double tolerance ) 00155 { 00156 if ( pointListCount < 1000 ) 00157 consolidate_few_points( tolerance ); 00158 else 00159 consolidate_many_points( tolerance ); 00160 } 00161 00162 void GMem::consolidate_few_points( double tolerance ) 00163 { 00164 const double tolsqr = tolerance * tolerance; 00165 int* index_map = new int[pointListCount]; 00166 00167 // Consolidate the point list. index_map is used 00168 // to maintain a map between the old index of a point 00169 // (the index into index_map) and the new index of a 00170 // point (the value in index_map). 00171 int write = 0, read, comp; 00172 for( read = 0; read < pointListCount; read++ ) 00173 { 00174 const GPoint& pti = pointList[read]; 00175 for( comp = 0; comp < write; comp++ ) 00176 { 00177 const GPoint& ptj = pointList[comp]; 00178 double x = pti.x - ptj.x; 00179 double y = pti.y - ptj.y; 00180 double z = pti.z - ptj.z; 00181 if( (x*x+y*y+z*z) <= tolsqr ) 00182 break; 00183 } 00184 00185 index_map[read] = comp; 00186 if( comp == write ) 00187 { 00188 pointList[comp] = pointList[read]; 00189 write++; 00190 } 00191 } 00192 pointListCount = write; 00193 00194 // Update the facet list using values from index_map. 00195 int *itor = facetList; 00196 const int* end = facetList + fListCount; 00197 while( itor < end ) 00198 for( int count = *(itor++); count--; itor++ ) 00199 *itor = index_map[*itor]; 00200 00201 delete [] index_map; 00202 pointsConsolidated = CUBIT_TRUE; 00203 } 00204 00205 class GPointOctTreeEval { 00206 public: static inline CubitVector coordinates(GPoint* p) 00207 { return CubitVector( p->x, p->y, p->z ); } 00208 }; 00209 00210 void GMem::consolidate_many_points( double tolerance ) 00211 { 00212 const double tolsqr = tolerance * tolerance; 00213 00214 // build OctTree 00215 DLIList<GPoint*> point_list(pointListCount); 00216 GPoint* p_itor = pointList; 00217 GPoint* p_end = p_itor + pointListCount; 00218 while( p_itor < p_end ) 00219 point_list.append( p_itor++ ); 00220 OctTree<GPoint, GPointOctTreeEval> tree( point_list, tolerance ); 00221 point_list.clean_out(); 00222 00223 // Consolidate the point list. index_map is used 00224 // to maintain a map between the old index of a point 00225 // (the index into index_map) and the new index of a 00226 // point (the value in index_map). 00227 int* index_map = new int[pointListCount]; 00228 GPoint* new_array = new GPoint[pointListCount]; 00229 int read, write = 0; 00230 for ( read = 0; read < pointListCount; read++) 00231 { 00232 GPoint* pt = pointList + read; 00233 CubitVector v(pt->x, pt->y, pt->z); 00234 index_map[read] = write; 00235 point_list.clean_out(); 00236 tree.nodes_near( v, point_list ); 00237 while ( point_list.size() ) 00238 { 00239 GPoint* p = point_list.pop(); 00240 int index = p - pointList; 00241 assert( (index >= 0) && (index < pointListCount) ); 00242 CubitVector v2(p->x, p->y, p->z); 00243 if ( (index < read) && ((v - v2).length_squared() < tolsqr) ) 00244 { 00245 index_map[read] = index_map[index]; 00246 break; 00247 } 00248 } 00249 00250 if ( index_map[read] == write ) 00251 { 00252 new_array[write++] = pointList[read]; 00253 } 00254 } 00255 pointListCount = write; 00256 delete [] pointList; 00257 pointList = new_array; 00258 00259 // Update the facet list using values from index_map. 00260 int *itor = facetList; 00261 const int* end = facetList + fListCount; 00262 while( itor < end ) 00263 for( int count = *(itor++); count--; itor++ ) 00264 *itor = index_map[*itor]; 00265 00266 delete [] index_map; 00267 pointsConsolidated = CUBIT_TRUE; 00268 } 00269 00270 void GMem::transform(CubitTransformMatrix &transform) 00271 { 00272 int i=0; 00273 CubitVector temp_point; 00274 for (i=0; i<this->pointListCount; i++) 00275 { 00276 temp_point.set(pointList[i].x, pointList[i].y, pointList[i].z); 00277 temp_point = transform * temp_point; 00278 pointList[i].x = (float)temp_point.x(); 00279 pointList[i].y = (float)temp_point.y(); 00280 pointList[i].z = (float)temp_point.z(); 00281 } 00282 }