cgma
GMem.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines