cgma
FacetGeometryCreator.cpp
Go to the documentation of this file.
00001 //- Class:       FacetGeometryCreator
00002 //- Description: Creates the topology for a given geometry described by facets.
00003 //- Owner:       Steven J. Owen
00004 //- Checked by:
00005 //- Version:
00006 #include "CubitDefines.h"
00007 #include "FacetGeometryCreator.hpp"
00008 #include "FacetQueryEngine.hpp"
00009 #include "DLIList.hpp"
00010 #include "TDGeomFacet.hpp"
00011 #include "CastTo.hpp"
00012 #include "FacetSkinTool.hpp"
00013 #include "FacetSurfaceMesh.hpp"
00014 #include "FacetCurveMesh.hpp"
00015 #include "FacetPointMesh.hpp"
00016 #include "Body.hpp"
00017 #include "Lump.hpp"
00018 #include "ShellSM.hpp"
00019 #include "Surface.hpp"
00020 #include "Curve.hpp"
00021 #include "GeometryQueryTool.hpp"
00022 #include "GeometryModifyTool.hpp"
00023 #include "PointSM.hpp"
00024 #include "FacetShell.hpp"
00025 #include "FacetSurface.hpp"
00026 #include "CubitFacet.hpp"
00027 #include "CubitFacetEdge.hpp"
00028 #include "CubitPoint.hpp"
00029 #include "FacetEntity.hpp"
00030 #include "FacetEvalTool.hpp"
00031 #include "ChollaDebug.hpp"
00032 #include "CurveSM.hpp"
00033 #include "TDFacetBoundaryEdge.hpp"
00034 #include "TDFacetBoundaryPoint.hpp"
00035 
00036 
00037 //============================================================================
00038 //Function:  FacetGeometryCreator (PUBLIC) (constructor)
00039 //============================================================================
00040 FacetGeometryCreator::FacetGeometryCreator()
00041 {
00042   hashCurveArray = NULL;
00043   hashCurveSize = 0;
00044   hashPointArray = NULL;
00045   hashPointSize = 0;
00046 }
00047 
00048 //============================================================================
00049 //Function:  FacetGeometryCreator (PUBLIC) (constructor)
00050 //============================================================================
00051 FacetGeometryCreator::FacetGeometryCreator(DLIList<FacetEntity*> &face_list,
00052                                            DLIList<FacetEntity*> &edge_list,
00053                                            DLIList<FacetEntity*> &point_list )
00054 {
00055   faceList = face_list;
00056   edgeList = edge_list;
00057   pointList = point_list;
00058   set_up_tool_datas();
00059   hashCurveArray = NULL;
00060   hashCurveSize = 0;
00061   hashPointArray = NULL;
00062   hashPointSize = 0;
00063 }
00064 
00065 //============================================================================
00066 //Function:  set_up_tool_datas
00067 //============================================================================
00068 void FacetGeometryCreator::set_up_tool_datas( )
00069 {
00070   int ii;
00071   FacetEntity *fe_ptr;
00072   for (ii=0; ii<faceList.size(); ii++)
00073   {
00074     fe_ptr = faceList.get_and_step();
00075     TDGeomFacet::add_geom_facet( fe_ptr, -1 );
00076   }
00077   for (ii=0; ii<pointList.size(); ii++)
00078   {
00079     fe_ptr = pointList.get_and_step();
00080     TDGeomFacet::add_geom_facet( fe_ptr, -1 );
00081   }
00082 }
00083 
00084 //============================================================================
00085 //Function:  delete_tool_datas
00086 //============================================================================
00087 void FacetGeometryCreator::delete_tool_datas( )
00088 {
00089   int ii;
00090   FacetEntity *fe_ptr;
00091   for (ii=0; ii<faceList.size(); ii++)
00092   {
00093     fe_ptr = faceList.get_and_step();
00094     fe_ptr->delete_TD( &TDGeomFacet::is_geom_facet );
00095   }
00096   for (ii=0; ii<edgeList.size(); ii++)
00097   {
00098     fe_ptr = edgeList.get_and_step();
00099     fe_ptr->delete_TD( &TDGeomFacet::is_geom_facet );
00100   }
00101   for (ii=0; ii<pointList.size(); ii++)
00102   {
00103     fe_ptr = pointList.get_and_step();
00104     fe_ptr->delete_TD( &TDGeomFacet::is_geom_facet );
00105   }
00106 }
00107 
00108 //==================================================================================
00109 //Function:  ~FacetGeometryCreator (PUBLIC) (destructor)
00110 //==================================================================================
00111 FacetGeometryCreator::~FacetGeometryCreator()
00112 {
00113   delete_tool_datas();
00114   int ii;
00115     //clean up any data remaining.
00116   for (ii = facetPointList.size(); ii > 0; ii-- )
00117     delete facetPointList.remove();
00118   for (ii = facetCurveList.size(); ii > 0; ii-- )
00119     delete facetCurveList.remove();
00120   for (ii = facetSurfaceList.size(); ii > 0; ii-- )
00121     delete facetSurfaceList.remove();
00122   
00123 }
00124 
00125 //=============================================================================
00126 //Function:  create_volume_boundaries (PRIVATE)
00127 //Description: creates the surfaces based on the sideset and element block
00128 //             information
00129 //Author: sjowen
00130 //Date: 10/17/00
00131 //=============================================================================
00132 CubitStatus FacetGeometryCreator::create_volume_boundaries( 
00133   DLIList<FacetSurfaceMesh*> &facet_surface_sheets,  // output global list of surfaces
00134   CubitBoolean use_feature_angle,   // define surfaces based on feature angle
00135   double min_dot,      // minimum dot product between face normals
00136   CubitBoolean split_surfaces )  // create new FacetEntities to split surfaces at
00137                                  // at features.  Otherwise - don't mess with the
00138                                  // FacetEntities. (creates TDs instead)
00139 {
00140   CubitStatus rv = CUBIT_SUCCESS;
00141 
00142   // Split these surfaces so that there is only one set of continuous
00143   // faces per surface 
00144 
00145   int ii;
00146   int num_surfaces = facet_surface_sheets.size();
00147   facet_surface_sheets.reset();
00148   for ( ii = num_surfaces; ii > 0; ii-- )
00149   {
00150 
00151     FacetSurfaceMesh *fsm_ptr = facet_surface_sheets.get_and_step();
00152     
00153     // make a list of feature edges
00154     
00155     DLIList<CubitFacetEdge *> feature_edge_list;
00156     if (use_feature_angle)
00157     {
00158       rv = fsm_ptr->feature_angle( min_dot, feature_edge_list );
00159     }
00160     else
00161     {
00162       rv = fsm_ptr->non_manifold_edges( feature_edge_list );
00163     }
00164     if (rv != CUBIT_SUCCESS)
00165       return rv;
00166 
00167      // crack the surface at the feature edges.  create new edges and
00168      // points so the facet representation is discontinuous.
00169 
00170     rv = FacetQueryEngine::make_features( feature_edge_list, split_surfaces );
00171     if (rv != CUBIT_SUCCESS)
00172        return rv;
00173 
00174     // split up the surface
00175 
00176     rv = fsm_ptr->split_surface( facet_surface_sheets );
00177     if (rv != CUBIT_SUCCESS)
00178        return rv;
00179   }
00180 
00181   // Clean up any edges that do not form complete loops as a result of 
00182   // feature angle.  For this implementation we will allow features to exist
00183   // within the surface without defining a complete loop. -- so the next
00184   // piece of code is never executed.
00185 
00186   CubitBoolean use_complete_loops_only = CUBIT_FALSE;
00187   if (use_feature_angle && use_complete_loops_only)
00188   {
00189     for ( ii = facet_surface_sheets.size(); ii > 0; ii-- )
00190     {
00191       FacetSurfaceMesh *fsm_ptr = facet_surface_sheets.get_and_step();
00192       fsm_ptr->clean_features();
00193     }
00194   }
00195 
00196   // Now that we've broken everything into surfaces, update the surface IDs
00197   // on the boundary facet tool data
00198 
00199   if (!split_surfaces)
00200   {
00201     for ( ii = facet_surface_sheets.size(); ii > 0; ii-- )
00202     {
00203       FacetSurfaceMesh *fsm_ptr = facet_surface_sheets.get_and_step();
00204       fsm_ptr->update_boundary_tool_data();
00205     }
00206   }
00207   return rv;
00208 }
00209 
00210 
00211 //=============================================================================
00212 //Function:  create_surface_boundaries (PRIVATE)
00213 //Description: creates the curves based on the facet surface information
00214 //Author: sjowen
00215 //Date: 12/3/00
00216 //=============================================================================
00217 CubitStatus FacetGeometryCreator::create_surface_boundaries(
00218   DLIList<FacetSurfaceMesh*> &facet_surface_list, // global list of surfaces
00219   DLIList<FacetCurveMesh*> &facet_curve_list,     // output global list of curves
00220   CubitBoolean use_feature_angle,
00221   double min_dot )
00222 {
00223   CubitStatus stat = CUBIT_SUCCESS;
00224 
00225     // determine the boundaries for each surface.  One curve per surface
00226 
00227   int ii;
00228   for ( ii = facet_surface_list.size(); ii > 0; ii-- )
00229   {
00230     FacetSurfaceMesh *fsm_ptr = facet_surface_list.get_and_step();
00231     DLIList<FacetCurveMesh*> fcurve_list;
00232     fsm_ptr->get_curves( fcurve_list );
00233     if (fcurve_list.size() == 0)
00234     {
00235       DLIList<FacetEntity*> facet_list;
00236       fsm_ptr->get_facets(facet_list);
00237       FacetSkinTool f_skin_tool;
00238       stat = f_skin_tool.skin_2d(facet_list, fsm_ptr);
00239       if ( stat != CUBIT_SUCCESS )
00240         return stat;
00241     }
00242   }
00243 
00244   // create a hash list of curves - to speed up classification
00245 
00246   stat = init_hash_curves();
00247   if (stat != CUBIT_SUCCESS)
00248   {
00249     delete_hash_curves();
00250     return stat;
00251   }
00252 
00253   // loop through each of the edges on the surfaces
00254   // Determine which curve it is a part of.
00255   // Create a new FacetCurveMesh for each curve
00256   // Curves are created wherever there is a unique set of associated
00257   // surfaces 
00258 
00259   int jj, kk;
00260   for ( ii = facet_surface_list.size(); ii > 0; ii-- )
00261   {
00262 
00263     FacetSurfaceMesh *fsm_ptr = facet_surface_list.get_and_step();
00264     DLIList<FacetCurveMesh*> fcurve_list;
00265     fsm_ptr->get_curves( fcurve_list );
00266 
00267     // curently there should only be one curve list per surface
00268 
00269     for (jj=fcurve_list.size(); jj>0; jj--)
00270     {
00271       FacetCurveMesh *fcm_ptr = fcurve_list.get_and_step();
00272       DLIList<FacetEntity*> facet_list =  fcm_ptr->get_facets();
00273       FacetEntity *edge_ptr;
00274       for ( kk = 0; kk < facet_list.size(); kk++)
00275       {
00276         edge_ptr = facet_list.get_and_step();
00277         stat = classify_edge( edge_ptr, facet_curve_list, fsm_ptr );
00278         if (stat != CUBIT_SUCCESS) 
00279           return stat;
00280       }
00281 
00282       // delete this FacetCurveMesh - it should have been replaced by one
00283       // or more curves bounding this surface
00284 
00285       fsm_ptr->remove_curve( fcm_ptr );
00286     }
00287   }
00288   delete_hash_curves();
00289 
00290   // Split these curves so that there is only one string of continuous
00291   // edges per curve (it will also order the edges and set the start
00292   // and end nodes for each curve) 
00293 
00294   int num_curves = facet_curve_list.size();
00295 
00296   facet_curve_list.reset();
00297   for ( ii = num_curves; ii > 0 && stat == CUBIT_SUCCESS; ii-- )
00298   {
00299     FacetCurveMesh *fcm_ptr = facet_curve_list.get();
00300 
00301     // if necessary mark nodes that will serve as feature breaks (vertices 
00302     // will be generatedat them)
00303 
00304     if (use_feature_angle)
00305     {
00306       stat = fcm_ptr->feature_angle( min_dot );
00307       if (stat != CUBIT_SUCCESS)
00308          return stat;
00309     }
00310 
00311     // split the curve based on various criteria
00312 
00313     stat = fcm_ptr->split_curve( facet_curve_list );
00314 
00315     // delete this curve (new curves were created in split_curve)
00316 
00317     delete fcm_ptr;
00318     facet_curve_list.change_to(NULL);
00319     facet_curve_list.step();
00320   }
00321   facet_curve_list.remove_all_with_value(NULL);
00322 
00323   // update the point->curve associativity
00324 
00325   for (ii=0; ii<facet_curve_list.size(); ii++)
00326   {
00327     FacetCurveMesh *fcm_ptr = facet_curve_list.get_and_step();
00328     CubitPoint *start_ptr, *end_ptr;
00329     fcm_ptr->get_ends( start_ptr, end_ptr );
00330     TDGeomFacet *td = TDGeomFacet::get_geom_facet( start_ptr );
00331     td->add_facet_curve( fcm_ptr );
00332     td = TDGeomFacet::get_geom_facet( end_ptr );
00333     td->add_facet_curve( fcm_ptr );
00334   }
00335 
00336   return stat;
00337 }
00338 
00339 //=============================================================================
00340 //Function:  init_hash_curves (PRIVATE)
00341 //Description: create a hash array of all curves.  They are hashed based on the
00342 //             smallest id of any surface attached to the curve 
00343 //Author: sjowen
00344 //Date: 3/7/01
00345 //=============================================================================
00346 CubitStatus FacetGeometryCreator::init_hash_curves( )
00347 {
00348   /* === find the next highest prime number */
00349 
00350   int num_surfs = facetSurfaceList.size();
00351   int i;
00352   hashCurveSize = num_surfs;
00353   if (num_surfs < 30) hashCurveSize = 31;
00354   else 
00355   {
00356     i=2;
00357     while (i<hashCurveSize*0.5 + 1) {
00358       if (hashCurveSize % i == 0) {
00359         i=2;
00360         hashCurveSize++;
00361       }
00362       else {
00363         i++;
00364       }
00365     }
00366   }
00367   hashCurveArray = new DLIList<FacetCurveMesh*>[hashCurveSize];
00368 
00369   int key = 0;
00370   FacetCurveMesh *fcm_ptr;
00371   DLIList<FacetSurfaceMesh*> *fsm_list_ptr; 
00372   for (i=0; i<facetCurveList.size(); i++)
00373   {
00374     fcm_ptr = facetCurveList.get_and_step();
00375     fsm_list_ptr = fcm_ptr->get_surface_list_ptr();
00376     key = get_curve_hash_key( fsm_list_ptr );
00377     hashCurveArray[key].append( fcm_ptr );   
00378   }
00379   return CUBIT_SUCCESS;
00380 }
00381 
00382 //=============================================================================
00383 //Function:  delete_hash_curves (PRIVATE)
00384 //Description: delete the hash curve stuff
00385 //Author: sjowen
00386 //Date: 3/7/01
00387 //=============================================================================
00388 void FacetGeometryCreator::delete_hash_curves( )
00389 {
00390   if (hashCurveArray)
00391    delete [] hashCurveArray;
00392   hashCurveArray = NULL;
00393   hashCurveSize = 0;
00394 }
00395 
00396 //=============================================================================
00397 //Function:  get_curve_hash_key (PRIVATE)
00398 //Description: 
00399 //Author: sjowen
00400 //Date: 3/7/01
00401 //=============================================================================
00402 int FacetGeometryCreator::get_curve_hash_key(
00403   DLIList<FacetSurfaceMesh*> *fsm_list_ptr )
00404 {
00405   int key, j;
00406   FacetSurfaceMesh *fsm_ptr;
00407   if (fsm_list_ptr->size() == 0)
00408   {
00409     key = 0;
00410   }
00411   else
00412   {
00413     key = INT_MAX;
00414     for (j=0; j<fsm_list_ptr->size(); j++)
00415     {
00416       fsm_ptr = fsm_list_ptr->get_and_step();
00417       if (fsm_ptr->get_id() < key)
00418         key = fsm_ptr->get_id();
00419     }
00420   }
00421   key = key % hashCurveSize;
00422   return key;
00423 }
00424 
00425 
00426 //=============================================================================
00427 //Function:  classify_edge (PRIVATE)
00428 //Description: sorts a edge into its correct curve based on its associated
00429 //             surfaces and sidesets/nodesets.  Creates a new block curve if 
00430 //             necessary.
00431 //Author: sjowen
00432 //Date: 12/3/00
00433 //=============================================================================
00434 CubitStatus FacetGeometryCreator::classify_edge(
00435   FacetEntity *edge_ptr,       // the edge we are classifying
00436   DLIList<FacetCurveMesh*> &facet_curve_list,  // add to one of these
00437   FacetSurfaceMesh *facet_surf_mesh_ptr )   // the current surface
00438 {
00439   CubitStatus rv = CUBIT_SUCCESS;
00440 
00441   // see if we have already classified this edge (from another surface)
00442 
00443   TDGeomFacet *td_gm_edge = TDGeomFacet::get_geom_facet(edge_ptr);
00444   if (td_gm_edge->get_hit_flag() != 0)
00445     return rv;
00446   td_gm_edge->set_hit_flag(1);
00447 
00448   // get the surfaces adjacent to this edge
00449 
00450   DLIList<FacetSurfaceMesh*> this_fsurf_list;
00451   td_gm_edge->get_facet_surfs( this_fsurf_list );
00452   int this_num_adj = this_fsurf_list.size();
00453 
00454   // see if the surfaces defined on this face match any 
00455   // of the existing block curves
00456 
00457   DLIList<FacetSurfaceMesh*> *fsurf_list_ptr;
00458   FacetCurveMesh *fcm_ptr = NULL;
00459   int found = 0;
00460   int key = get_curve_hash_key( &this_fsurf_list );
00461   int ii;
00462   for (ii=0; ii<hashCurveArray[key].size() && !found; ii++)
00463   {
00464     fcm_ptr = hashCurveArray[key].get();
00465     // the first one checked should be the same as the last one checked (don't
00466     // use get_and_step here)  This should speed things up
00467 
00468     // check if surfaces are the same
00469 
00470     fsurf_list_ptr = fcm_ptr->get_surface_list_ptr( );
00471     int num_adj = fsurf_list_ptr->size();
00472     if (num_adj == this_num_adj)
00473     {
00474       found = 1;
00475       int jj, kk;
00476       for (jj=fsurf_list_ptr->size(); jj>0 && found; jj--)
00477       {
00478         int same_surf = 0;
00479         FacetSurfaceMesh *fsm_ptr = fsurf_list_ptr->get_and_step();
00480         for(kk=this_fsurf_list.size(); kk>0 && !same_surf; kk--)
00481         {
00482           FacetSurfaceMesh *this_fsm_ptr = this_fsurf_list.get_and_step();
00483           if (this_fsm_ptr == fsm_ptr)
00484           {
00485             same_surf = 1;
00486           }
00487         }
00488         if (!same_surf)
00489           found = 0;
00490       }
00491     }
00492     if (!found)
00493       hashCurveArray[key].step();
00494   }
00495 
00496   // if the unique set of surfaces that this edge is associated 
00497   // with was found to already exist for a facet curve -- add the
00498   // edge to the block curve
00499 
00500   if (found)
00501   {
00502 
00503     // add the edge to the block curve mesh (make sure it is only added once)
00504 
00505     int was_added = fcm_ptr->add_facet_unique( edge_ptr );
00506 
00507     // add the curve to the surface (if needed)
00508 
00509     facet_surf_mesh_ptr->add_curve_unique( fcm_ptr );
00510 
00511     // add the curve to the edge
00512   
00513     td_gm_edge->add_facet_curve( fcm_ptr );
00514   }
00515 
00516   // if the unique set of surfaces that this edge is associated
00517   // with is not found, then create a new facet curve and add the edge to it
00518 
00519   else
00520   {
00521 
00522     // create it and update surface and nodeset info
00523 
00524     int block_id = td_gm_edge->get_block_id();
00525     FacetCurveMesh *new_fcm_ptr = new FacetCurveMesh( block_id ); 
00526     for (int mm=0; mm<this_num_adj; mm++)
00527     {
00528       new_fcm_ptr->add_surface( this_fsurf_list.get_and_step() );
00529     }
00530 
00531     // add the edge
00532 
00533     new_fcm_ptr->add_facet( edge_ptr );
00534 
00535     // update the surface with this new curve
00536 
00537     facet_surf_mesh_ptr->add_curve( new_fcm_ptr );
00538 
00539     // add the new curve to the global list
00540 
00541     facet_curve_list.append( new_fcm_ptr ); 
00542 
00543     // add the curve to the edge
00544   
00545     td_gm_edge->add_facet_curve( new_fcm_ptr );
00546 
00547     // add the new curve to the hash table
00548 
00549     hashCurveArray[key].append( new_fcm_ptr );
00550   }
00551   return rv;
00552 }
00553 
00554 //=============================================================================
00555 //Function:  create_curve_boundaries (PRIVATE)
00556 //Description: creates the points based on the nodeset and curve information
00557 //Author: sjowen
00558 //Date: 12/6/00
00559 //=============================================================================
00560 CubitStatus FacetGeometryCreator::create_curve_boundaries(
00561   DLIList<FacetCurveMesh*> &facet_curve_list,   // global list of curves
00562   DLIList<FacetPointMesh*> &facet_point_list )  // output global list of points
00563 {
00564 
00565   CubitStatus stat = CUBIT_SUCCESS;
00566 
00567   // hash the points for speed
00568 
00569   stat = init_hash_points();
00570   if (stat != CUBIT_SUCCESS)
00571   {
00572     delete_hash_points();
00573     return stat;
00574   }
00575 
00576   // loop through each of the end nodes on the curves
00577   // Determine which point it is a part of.
00578   // Create a new FacetPointMesh for each point
00579 
00580   int ii, kk;
00581   for ( ii = facet_curve_list.size(); ii > 0; ii-- )
00582   {
00583     FacetCurveMesh *fcm_ptr = facet_curve_list.get_and_step();
00584     CubitPoint *point_ptr[2];
00585     fcm_ptr->get_ends( point_ptr[0], point_ptr[1] );
00586     for ( kk = 0; kk < 2; kk++)
00587     {
00588       stat = classify_point( point_ptr[kk], facet_point_list, fcm_ptr );
00589       if (stat != CUBIT_SUCCESS)
00590       {
00591         delete_hash_points();
00592         return stat;
00593       }
00594     }
00595   }
00596   delete_hash_points();
00597   return stat;
00598 }
00599 
00600 //=============================================================================
00601 //Function:  classify_node (PRIVATE)
00602 //Description: sorts a node into its correct point based on its associated
00603 //             curve.  Creates a new block point if necessary
00604 //Author: sjowen
00605 //Date: 12/6/00
00606 //=============================================================================
00607 CubitStatus FacetGeometryCreator::classify_point(
00608   CubitPoint *point_ptr,                     // the node to classify
00609   DLIList<FacetPointMesh*> &facet_point_list,   // global list of points
00610   FacetCurveMesh *fcm_ptr )                 // curve that the end point is on
00611 {
00612   int ii;
00613   int found = 0;
00614   TDGeomFacet *td_node = TDGeomFacet::get_geom_facet( point_ptr );
00615   FacetPointMesh *fpm_ptr;
00616   DLIList<FacetCurveMesh*> fcm_list;
00617   td_node->get_facet_curves(fcm_list);
00618   int key = get_point_hash_key( &fcm_list );
00619   for (ii = 0; ii < hashPointArray[key].size() && !found; ii++)
00620   {
00621     fpm_ptr = hashPointArray[key].get();
00622     FacetEntity *this_point_ptr = fpm_ptr->get_facets();
00623     if (this_point_ptr == point_ptr)
00624     {
00625       found = 1;
00626     }
00627     else
00628     {
00629       hashPointArray[key].step();
00630     }
00631   } 
00632 
00633   if (found)
00634   {
00635     fpm_ptr->add_curve( fcm_ptr );
00636     fcm_ptr->add_point( fpm_ptr );
00637   }
00638   else
00639   {
00640     FacetPointMesh *new_fpm_ptr = new FacetPointMesh(); 
00641     new_fpm_ptr->add_facet( point_ptr );
00642     new_fpm_ptr->add_curve( fcm_ptr );
00643     fcm_ptr->add_point( new_fpm_ptr );
00644     facet_point_list.append( new_fpm_ptr );
00645     hashPointArray[key].append( new_fpm_ptr );
00646   }
00647   return CUBIT_SUCCESS;
00648 }
00649 
00650 //=============================================================================
00651 //Function:  init_hash_points (PRIVATE)
00652 //Description: create a hash array of all points.  They are hashed based on the
00653 //             smallest id of any curve attached to the curve 
00654 //Author: sjowen
00655 //Date: 3/7/01
00656 //=============================================================================
00657 CubitStatus FacetGeometryCreator::init_hash_points( )
00658 {
00659   /* === find the next highest prime number */
00660 
00661   int num_curves = facetCurveList.size();
00662   int i;
00663   hashPointSize = num_curves;
00664   if (num_curves < 30) hashPointSize = 31;
00665   else 
00666   {
00667     i=2;
00668     while (i<hashPointSize*0.5 + 1) {
00669       if (hashPointSize % i == 0) {
00670         i=2;
00671         hashPointSize++;
00672       }
00673       else {
00674         i++;
00675       }
00676     }
00677   }
00678   hashPointArray = new DLIList<FacetPointMesh*>[hashPointSize];
00679 
00680   int key = 0;
00681   FacetPointMesh *fpm_ptr;
00682   DLIList<FacetCurveMesh*> *fcm_list_ptr; 
00683   for (i=0; i<facetPointList.size(); i++)
00684   {
00685     fpm_ptr = facetPointList.get_and_step();
00686     fcm_list_ptr = fpm_ptr->get_curve_list_ptr();
00687     key = get_point_hash_key( fcm_list_ptr );
00688     hashPointArray[key].append( fpm_ptr );   
00689   }
00690   return CUBIT_SUCCESS;
00691 }
00692 
00693 //=============================================================================
00694 //Function:  delete_hash_points (PRIVATE)
00695 //Description: delete the hash point stuff
00696 //Author: sjowen
00697 //Date: 3/7/01
00698 //=============================================================================
00699 void FacetGeometryCreator::delete_hash_points( )
00700 {
00701   if (hashPointArray)
00702    delete [] hashPointArray;
00703   hashPointArray = NULL;
00704   hashPointSize = 0;
00705 }
00706 
00707 //=============================================================================
00708 //Function:  get_point_hash_key (PRIVATE)
00709 //Description: 
00710 //Author: sjowen
00711 //Date: 3/7/01
00712 //=============================================================================
00713 int FacetGeometryCreator::get_point_hash_key(
00714   DLIList<FacetCurveMesh*> *fcm_list_ptr )
00715 {
00716   int key, j;
00717   FacetCurveMesh *fcm_ptr;
00718   if (fcm_list_ptr->size() == 0)
00719   {
00720     key = 0;
00721   }
00722   else
00723   {
00724     key = INT_MAX;
00725     for (j=0; j<fcm_list_ptr->size(); j++)
00726     {
00727       fcm_ptr = fcm_list_ptr->get_and_step();
00728       if (fcm_ptr->get_id() < key)
00729         key = fcm_ptr->get_id();
00730     }
00731   }
00732   key = key % hashPointSize;
00733   return key;
00734 }
00735 
00736 
00737 //===============================================================================
00738 //Function:  build_geometry (PRIVATE)
00739 //Description:  build the CUBIT geometry based on the Facet entity class lists
00740 //===============================================================================
00741 CubitStatus FacetGeometryCreator::build_geometry(
00742   DLIList<FacetSurfaceMesh*> &facet_surface_list,
00743   DLIList<FacetCurveMesh*> &facet_curve_list,
00744   DLIList<FacetPointMesh*> &facet_point_list,
00745   int interp_order,
00746   CubitBoolean use_feature_angle,
00747   double min_dot,
00748   CubitBoolean smooth_non_manifold,
00749   CubitBoolean split_surfaces )
00750 {
00751   CubitStatus stat = CUBIT_SUCCESS;
00752 
00753   stat = build_point_geometry( facet_point_list );
00754   
00755   if (stat == CUBIT_SUCCESS)
00756     stat = build_curve_geometry( facet_curve_list );
00757 
00758   if (stat == CUBIT_SUCCESS)
00759     stat = build_surface_geometry( facet_surface_list,
00760                                    interp_order, min_dot );
00761   if (stat == CUBIT_SUCCESS)
00762     if (interp_order == 4)
00763       stat = clean_geometry( smooth_non_manifold, split_surfaces,
00764                            use_feature_angle, min_dot, facet_curve_list );
00765   return stat;
00766 }
00767 
00768 //===============================================================================
00769 //Function:  build_point_geometry (PRIVATE)
00770 //Description:  From the facet point list, create geometric points for each
00771 //===============================================================================
00772 CubitStatus FacetGeometryCreator::build_point_geometry(
00773   DLIList<FacetPointMesh*> &facet_point_list )
00774 {
00775   CubitStatus stat = CUBIT_SUCCESS;
00776   int kk;
00777   for ( kk = facet_point_list.size(); kk > 0; kk-- )
00778   {
00779     FacetPointMesh *fpm_ptr = facet_point_list.get_and_step();
00780     Point *point_ptr = fpm_ptr->get_geometric_point();
00781     if (point_ptr == NULL)
00782     {
00783       FacetEntity *facet_ptr = fpm_ptr->get_facets();
00784       CubitPoint *cp_ptr = CAST_TO( facet_ptr, CubitPoint );
00785       PointSM *point = NULL;
00786       stat = GeometryModifyTool::instance()->make_facet_point( cp_ptr, point );
00787       if ( point == NULL || stat != CUBIT_SUCCESS )
00788       {
00789         PRINT_ERROR("Problems building mesh based points.\n");
00790         return stat;
00791       }
00792       point_ptr = (Point *)point;
00793       fpm_ptr->assign_geometric_point(point_ptr);
00794     }
00795   }
00796   return stat;
00797 }
00798 
00799 //===============================================================================
00800 //Function:  build_curve_geometry (PRIVATE)
00801 //Description:  From the facet curve list, create geometric curves for each
00802 //===============================================================================
00803 CubitStatus FacetGeometryCreator::build_curve_geometry(
00804   DLIList<FacetCurveMesh*> &facet_curve_list )
00805 {
00806   CubitStatus stat = CUBIT_SUCCESS;
00807   int kk;
00808   for ( kk = facet_curve_list.size(); kk > 0; kk-- )
00809   {
00810     FacetCurveMesh *fcm_ptr = facet_curve_list.get_and_step();
00811     Curve *curv_ptr = fcm_ptr->get_geometric_curve();
00812     if (curv_ptr == NULL)
00813     {
00814       DLIList<FacetPointMesh*> fpoint_list = fcm_ptr->get_points( );
00815       FacetPointMesh *fpm0_ptr = fpoint_list.get_and_step();
00816       FacetPointMesh *fpm1_ptr = fpoint_list.get_and_step();
00817       CubitPoint *start_point, *end_point;
00818       fcm_ptr->get_ends( start_point, end_point );
00819       if (fpm0_ptr->get_facets() != start_point)
00820       {
00821         FacetPointMesh *temp_ptr;
00822         temp_ptr = fpm0_ptr;
00823         fpm0_ptr = fpm1_ptr;
00824         fpm1_ptr = temp_ptr;
00825       }
00826       PointSM *start_ptr = (PointSM *) fpm0_ptr->get_geometric_point();
00827       PointSM *end_ptr = (PointSM *) fpm1_ptr->get_geometric_point();
00828       
00829       // if this is a curve without a parent surface then handle it 
00830       // differently.  (Curves with parents use the surface to evaluate to
00831       // With only a curve, it must evaluate to the curve)
00832       
00833       DLIList<FacetSurfaceMesh*> fsm_list = fcm_ptr->get_surfaces();
00834       if (fsm_list.size() == 0)
00835       {
00836         DLIList<FacetEntity*> facet_list;
00837         DLIList<CubitPoint*> point_list;  // needs to be filled in
00838         facet_list = fcm_ptr->get_facets();
00839         DLIList<CubitFacetEdge*> edge_list;
00840         CAST_LIST( facet_list, edge_list, CubitFacetEdge );
00841         if (stat != CUBIT_SUCCESS)
00842           return stat;
00843         stat = FacetQueryEngine::instance()->make_facet_curve( start_ptr, end_ptr,
00844                                                                   edge_list, point_list,
00845                                                                   curv_ptr );
00846         if (stat == CUBIT_SUCCESS)
00847         {
00848           CurveSM *curvsm_ptr = CAST_TO( curv_ptr, CurveSM );
00849           GeometryQueryTool::instance()->make_free_RefEdge( curvsm_ptr );
00850         }
00851       }
00852       else
00853       {
00854         stat = FacetQueryEngine::instance()->make_facet_curve( start_ptr, end_ptr,
00855                                                                   curv_ptr );
00856         if ( curv_ptr == NULL || stat != CUBIT_SUCCESS )
00857         {
00858           PRINT_ERROR("Problems building mesh based curves.\n");
00859           return stat;
00860         }
00861       }
00862       fcm_ptr->assign_geometric_curve(curv_ptr);
00863     }
00864   }
00865   return stat;
00866 }
00867 
00868 //===============================================================================
00869 //Function:  build_loop_geometry (PRIVATE)
00870 //Description:  From the block curve list of a surface, create geometric loops 
00871 //===============================================================================
00872 CubitStatus FacetGeometryCreator::build_loop_geometry(
00873   DLIList<FacetCurveMesh*> &facet_curve_list,   // curves on a surface
00874   FacetSurfaceMesh *fsm_ptr,                    // the surface
00875   DLIList<LoopSM*> &loop_list,                  // append to this loop list
00876   int &ncurves )                                // number of curves used
00877 {
00878 
00879   // find the first unused curve on the list.  Use that as the starting curve
00880   // in the loop
00881 
00882   ncurves = 0;
00883   CubitStatus stat = CUBIT_SUCCESS;
00884   int ii, jj;
00885   int found = 0;
00886   FacetCurveMesh *fcm_ptr = NULL;
00887   for(ii=0; ii<facet_curve_list.size() && !found; ii++)
00888   {
00889     fcm_ptr = facet_curve_list.get_and_step();
00890     if (fcm_ptr->get_flag() == 0)
00891       found = 1;
00892   }
00893   if (!found)
00894     return CUBIT_FAILURE;  // all the curves have already been used in this surface
00895 
00896   // get the first mesh edge on the first curve. use it to determine the 
00897   // orientation of the curve with respect to the surface
00898 
00899   DLIList<FacetEntity*> facet_list = fcm_ptr->get_facets();
00900   FacetEntity *facet_ptr = facet_list.get();
00901   CubitFacetEdge *edge_ptr = CAST_TO( facet_ptr, CubitFacetEdge );
00902   if (!edge_ptr)
00903     return CUBIT_FAILURE; // facet edges are not on the list ????
00904 
00905   // get the adjacent face on this surface
00906 
00907   DLIList<FacetEntity*> adj_face_list;
00908   FacetEntity *face_ptr = NULL;
00909   edge_ptr->get_parents( adj_face_list );
00910   found = 0;
00911   for ( jj = 0; jj < adj_face_list.size() && !found; jj++ )
00912   {
00913     face_ptr = adj_face_list.get_and_step();
00914     TDGeomFacet *td_gm_face = TDGeomFacet::get_geom_facet(face_ptr); 
00915     DLIList<FacetSurfaceMesh*> fsurf_list;
00916     td_gm_face->get_facet_surfs( fsurf_list );
00917     FacetSurfaceMesh *face_fsm_ptr = fsurf_list.get();
00918     if(face_fsm_ptr == fsm_ptr)
00919     {
00920       found = 1;
00921     }
00922   }
00923   if (!found)
00924     return CUBIT_FAILURE;  // didn't find an adj face on the surface ???
00925     
00926   // determine orientation of nodes on this mesh face
00927 
00928   CubitPoint *start_ptr, *end_ptr;
00929   fcm_ptr->get_ends( start_ptr, end_ptr );
00930   end_ptr = edge_ptr->other_point( start_ptr );
00931   if (end_ptr == NULL)
00932     return CUBIT_FAILURE;  // the edge list may not be ordered correctly??
00933   CubitPoint *points[3];
00934   CubitFacet *tri_ptr = CAST_TO( face_ptr, CubitFacet );
00935   tri_ptr->points( points[0], points[1], points[2] );
00936 
00937   found = 0;
00938   CubitSense orientation;
00939   for ( jj = 0; jj < 3 && !found; jj++ )
00940   {
00941     if (points[jj] == start_ptr)
00942     {
00943       int next_jj = (jj + 1)%3;
00944       int prev_jj = (jj + 2)%3;
00945       if(points[next_jj] == end_ptr)
00946       {
00947         found = 1;
00948         orientation = CUBIT_FORWARD;
00949       }
00950       else if(points[prev_jj] == end_ptr)
00951       {
00952         found = 1;
00953         orientation = CUBIT_REVERSED;
00954       }
00955     } 
00956   } 
00957   if (!found)
00958     return CUBIT_FAILURE;  // couldn't determine the orientation
00959   fcm_ptr->get_ends( start_ptr, end_ptr );
00960 
00961   // create a new coedge
00962 
00963   CoEdgeSM *coedge_ptr = NULL;
00964   Curve *curv_ptr = fcm_ptr->get_geometric_curve();
00965   stat = GeometryModifyTool::instance()->make_facet_coedge( (CurveSM*)curv_ptr, orientation,
00966                                                       coedge_ptr );
00967   if ( coedge_ptr == NULL || stat != CUBIT_SUCCESS )
00968   {
00969     PRINT_ERROR("Problems building mesh based coedges.\n");
00970     return stat;
00971   }
00972 
00973   // start a list of coedges for this loop
00974 
00975   DLIList<CoEdgeSM*> coedge_list;
00976   coedge_list.append( coedge_ptr );
00977   fcm_ptr->set_flag(1);
00978   FacetCurveMesh *last_fcm_ptr = fcm_ptr;
00979 
00980   // loop through and determine the rest of the coedges based on the
00981   // orientation of the first curve in the loop
00982    
00983   fcm_ptr->get_ends( start_ptr, end_ptr );
00984   FacetEntity *n0_ptr, *n1_ptr;
00985   if (orientation == CUBIT_FORWARD)
00986   {
00987     n0_ptr = start_ptr;
00988     n1_ptr = end_ptr;
00989   }
00990   else
00991   {
00992     n1_ptr = start_ptr;
00993     n0_ptr = end_ptr;
00994   }
00995 
00996   while (n0_ptr != n1_ptr)
00997   {
00998 
00999     // find the next curve in the loop
01000 
01001     int ntimes = 0;
01002     found = 0;
01003     while(!found)
01004     {
01005       for ( jj = 0; jj < facet_curve_list.size() && !found; jj++)
01006       {
01007         fcm_ptr = facet_curve_list.get_and_step();
01008         if (last_fcm_ptr != fcm_ptr && (fcm_ptr->get_flag() == 0 || ntimes > 0))
01009         {
01010           fcm_ptr->get_ends( start_ptr, end_ptr );
01011           if (start_ptr == n1_ptr)
01012           {
01013             found = 1;
01014             orientation = CUBIT_FORWARD;
01015             n1_ptr = end_ptr;
01016           }
01017           else if (end_ptr == n1_ptr)
01018           {
01019             found = 1;
01020             orientation = CUBIT_REVERSED;
01021             n1_ptr = start_ptr;
01022           }
01023         }
01024       }
01025       if (!found)
01026       {
01027 
01028         // in this special case - we have gone through the whole list without
01029         // finding the next curve on the loop.  In the first pass we have assumed
01030         // that each curve is only used once.  This may not be the case.  Go
01031         // back and see of we can find a curve that has already been used that
01032         // will work.  If we fail the second time through, then we fail!
01033 
01034         ntimes++;
01035         if (ntimes > 1)
01036           // return CUBIT_FAILURE;  // didn't find the next curve in the loop
01037           // DEBUG ONLY -- THIS NEEDS TO BE FIXED
01038           goto create_loop;
01039       }
01040     }
01041 
01042     // create a new coedge
01043 
01044     coedge_ptr = NULL;
01045     curv_ptr = fcm_ptr->get_geometric_curve();
01046     stat = GeometryModifyTool::instance()->make_facet_coedge( (CurveSM*)curv_ptr, orientation,
01047                                                          coedge_ptr );
01048     if ( coedge_ptr == NULL || stat != CUBIT_SUCCESS )
01049     {
01050       PRINT_ERROR("Problems building mesh based coedges.\n");
01051       return stat;
01052     }
01053     coedge_list.append( coedge_ptr );
01054     if (coedge_list.size() > 2*facet_curve_list.size())
01055       return CUBIT_FAILURE;  // more curves in the loop than their are curves ????
01056     fcm_ptr->set_flag(1);
01057     last_fcm_ptr = fcm_ptr;
01058   } 
01059 
01060   // create the loop
01061 
01062 create_loop:
01063   LoopSM *loop_ptr = NULL;
01064   stat = GeometryModifyTool::instance()->make_facet_loop( coedge_list, loop_ptr );
01065   if ( coedge_ptr == NULL || stat != CUBIT_SUCCESS )
01066   {
01067     PRINT_ERROR("Problems building mesh based loops.\n");
01068     return stat;
01069   }
01070   loop_list.append( loop_ptr );
01071   ncurves = coedge_list.size();
01072       
01073   return stat;
01074 }
01075 
01076 //===============================================================================
01077 //Function:  build_surface_geometry (PRIVATE)
01078 //Description:  From the facet surface list, create geometric surface,
01079 //              loops and coedges for each surface in the list
01080 //===============================================================================
01081 CubitStatus FacetGeometryCreator::build_surface_geometry(
01082   DLIList<FacetSurfaceMesh*> &facet_surface_list,
01083   int interp_order,
01084   double min_dot )
01085 {
01086   CubitStatus stat = CUBIT_SUCCESS;
01087   int ii, kk;
01088 
01089   // make sure the facet flags have been reset
01090 
01091   FacetCurveMesh *fcm_ptr;
01092   for ( kk = facet_surface_list.size(); kk > 0; kk-- )
01093   {
01094     FacetSurfaceMesh *fsm_ptr = facet_surface_list.get_and_step();
01095     fsm_ptr->reset_facet_flags();
01096   }
01097 
01098   // now loop through surfaces and create them
01099 
01100   int mydebug = 0;
01101   for ( kk = facet_surface_list.size(); kk > 0; kk-- )
01102   {
01103     int num_curves = 0;
01104     FacetSurfaceMesh *fsm_ptr = facet_surface_list.get_and_step();
01105 
01106     DLIList<FacetCurveMesh*> fcurve_list;
01107     fsm_ptr->get_curves( fcurve_list );
01108 
01109     // init flags for curves on this surface
01110 
01111     for (ii=0; ii< fcurve_list.size(); ii++)
01112     {
01113       fcm_ptr = fcurve_list.get_and_step();
01114       fcm_ptr->set_flag(0);
01115       if (mydebug)
01116       {
01117         fcm_ptr->draw();
01118       }
01119     }
01120 
01121     // generate loops - keep going until we have used all the curves in the list
01122 
01123     DLIList<LoopSM*> loop_list;
01124     while (num_curves < fcurve_list.size())
01125     {
01126       int ncurves = 0;
01127       stat = build_loop_geometry( fcurve_list, fsm_ptr, loop_list, ncurves );
01128       if (stat != CUBIT_SUCCESS)
01129       {
01130         PRINT_ERROR("Can't build geometric loop from facets\n");
01131         return stat;
01132       }
01133       num_curves += ncurves;
01134     }
01135 
01136     // create the surface
01137 
01138     Surface *surf_ptr = fsm_ptr->get_geometric_surface();
01139     if (surf_ptr == NULL)
01140     {
01141       DLIList<FacetEntity*> facet_entity_list;
01142       DLIList<CubitPoint*> point_list;
01143       fsm_ptr->get_points(point_list);
01144       fsm_ptr->get_facets(facet_entity_list);
01145       DLIList<CubitFacet*> facet_list;
01146       CAST_LIST( facet_entity_list, facet_list, CubitFacet );
01147       stat = GeometryModifyTool::instance()->make_facet_surface(facet_list,
01148                                                                 point_list,
01149                                                                 loop_list,
01150                                                                 interp_order,
01151                                                                 min_dot,
01152                                                                 surf_ptr);
01153       if ( surf_ptr == NULL || stat != CUBIT_SUCCESS )
01154       {
01155         PRINT_ERROR("Problems building mesh based surfaces.\n");
01156         return stat;
01157       }
01158       fsm_ptr->assign_geometric_surface(surf_ptr);
01159     }
01160   }
01161   return stat;
01162 }
01163 
01164 //===============================================================================
01165 //Function:  clean_geometry (PRIVATE)
01166 //Description:  fix the edge control points and the normals so they are conforming
01167 //              (or non-conforming) accross curves
01168 //===============================================================================
01169 CubitStatus FacetGeometryCreator::clean_geometry( 
01170   CubitBoolean smooth_non_manifold,
01171   CubitBoolean split_surfaces,
01172   CubitBoolean use_feature_angle,
01173   double mindot,
01174   DLIList <FacetCurveMesh *> &facet_curve_list )
01175 {
01176   int iedge;
01177   FacetCurveMesh *fcm_ptr;
01178   FacetEntity *fedge_ptr;
01179   CubitFacetEdge *edge_ptr;
01180   DLIList <FacetEntity *> facet_list; 
01181   DLIList<CubitFacetEdge *> feature_edge_list;
01182   int icurve;
01183   for (icurve=0; icurve<facet_curve_list.size(); icurve++)
01184   {
01185     fcm_ptr = facet_curve_list.get_and_step();
01186     facet_list.clean_out();
01187     facet_list = fcm_ptr->get_facets( );
01188     for (iedge=0; iedge<facet_list.size(); iedge++)
01189     {
01190       fedge_ptr = facet_list.get_and_step();
01191       edge_ptr = CAST_TO( fedge_ptr, CubitFacetEdge );
01192       feature_edge_list.append( edge_ptr );
01193     }
01194   }
01195 
01196   return FacetQueryEngine::instance()->fix_geometry( smooth_non_manifold,
01197                                                         split_surfaces, 
01198                                                         use_feature_angle, 
01199                                                         mindot, feature_edge_list );
01200 }
01201 
01202 //===============================================================================
01203 //Function:  print_me (PRIVATE)
01204 //Description: debug
01205 //===============================================================================
01206 void FacetGeometryCreator::print_me()
01207 {
01208   FILE *fp = fopen( "fbg.out", "w" );
01209   int ii, jj, kk;
01210   for (ii=0; ii<facetSurfaceList.size(); ii++)
01211   {
01212     FacetSurfaceMesh *fsm_ptr = facetSurfaceList.get_and_step();
01213     fprintf( fp, "*********** Surface %d ***************\n", fsm_ptr->get_id());
01214     DLIList<FacetCurveMesh *> fcm_list;
01215     fsm_ptr->get_curves( fcm_list );
01216     for (jj=0; jj<fcm_list.size(); jj++)
01217     {
01218       FacetCurveMesh *fcm_ptr = fcm_list.get_and_step();
01219       fprintf(fp, "   Curve %d\n", fcm_ptr->get_id() );
01220       DLIList<FacetPointMesh *> fpm_list = fcm_ptr->get_points();
01221       for (kk=0; kk<fpm_list.size(); kk++)
01222       {
01223         FacetPointMesh *fpm_ptr = fpm_list.get_and_step();
01224         FacetEntity *facet_point = fpm_ptr->get_facets();
01225         if (facet_point)
01226         {
01227           CubitPoint *point_ptr = CAST_TO(facet_point, CubitPoint);
01228           CubitVector pt = point_ptr->coordinates();
01229           fprintf(fp, "      (%d) x = %8.4lf y = %8.4lf z = %8.4lf\n",
01230                   fpm_ptr->get_id(), pt.x(), pt.y(), pt.z());
01231         }
01232       }
01233     }
01234   }
01235   fclose(fp);
01236 }
01237 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines