cgma
FacetQueryEngine.cpp
Go to the documentation of this file.
00001 //-------------------------------------------------------------------------
00002 // Filename      : FacetQueryEngine.cpp
00003 //
00004 // Purpose       : Implementation of the FacetQueryEngine class.
00005 //                 This class provides facet-based implementations
00006 //                 of various virtual functions in the GeometryQueryEngine
00007 //                 hierarchy.
00008 //
00009 // Special Notes :
00010 //
00011 // Creator       : David R. White
00012 //
00013 // Creation Date : 7/17/00
00014 //
00015 //-------------------------------------------------------------------------
00016 #include "FacetQueryEngine.hpp"
00017 #include "FacetModifyEngine.hpp"
00018 #include "FacetboolInterface.hpp"
00019 #include "TopologyEntity.hpp"
00020 #include "TopologyBridge.hpp"
00021 #include "RefEntity.hpp"
00022 #include "Body.hpp"
00023 #include "Shell.hpp"
00024 #include "Loop.hpp"
00025 #include "Chain.hpp"
00026 #include "CoEdge.hpp"
00027 #include "CoFace.hpp"
00028 #include "RefVolume.hpp"
00029 #include "RefFace.hpp"
00030 #include "RefEdge.hpp"
00031 #include "RefVertex.hpp"
00032 #include "GeometryEntity.hpp"
00033 #include "DLIList.hpp"
00034 #include "CubitBox.hpp"
00035 #include "CubitString.hpp"
00036 #include "FacetPoint.hpp"
00037 #include "FacetCurve.hpp"
00038 #include "FacetCoEdge.hpp"
00039 #include "FacetLoop.hpp"
00040 #include "FacetSurface.hpp"
00041 #include "FacetShell.hpp"
00042 #include "FacetLump.hpp"
00043 #include "FacetBody.hpp"
00044 #include "CubitFacetEdge.hpp"
00045 #include "CubitFacetEdgeData.hpp"
00046 #include "CubitFacet.hpp"
00047 #include "CubitFacetData.hpp"
00048 #include "CubitQuadFacet.hpp"
00049 #include "CubitQuadFacetData.hpp"
00050 #include "CubitPoint.hpp"
00051 #include "GMem.hpp"
00052 #include "FacetEvalTool.hpp"
00053 #include "CurveFacetEvalTool.hpp"
00054 #include "CubitPointData.hpp"
00055 #include "GeometryQueryTool.hpp"
00056 #include "ChollaDebug.hpp"
00057 #include "CubitObserver.hpp"
00058 #include "ChollaEngine.hpp"
00059 #include "ChollaSurface.hpp"
00060 #include "ChollaCurve.hpp"
00061 #include "ChollaPoint.hpp"
00062 #include "Cholla.h"
00063 #include "CubitFileIOWrapper.hpp"
00064 #include "CCubitFile.hpp"
00065 #include "TDFacetBoundaryPoint.hpp"
00066 #include "GfxDebug.hpp"
00067 #include "KDDTree.hpp"
00068 #include "RTree.hpp"
00069 #include "FacetDataUtil.hpp"
00070 #include "GridSearchTree.hpp"
00071 #include <stdio.h>
00072 #include <errno.h>
00073 #include "GeometryModifyTool.hpp"
00074 #include "BodySM.hpp"
00075 #include "AppUtil.hpp"
00076 #include "ProgressTool.hpp"
00077 #include "CubitOctreeGeneratorVolumes.hpp"
00078 #include "GfxDebug.hpp"
00079 
00080 using namespace NCubitFile;
00081 
00082 FacetQueryEngine* FacetQueryEngine::instance_ = NULL;
00083 int FacetQueryEngine::hashPointSize = 0;
00084 DLIList<CubitPoint*> *FacetQueryEngine::hashPointArray = NULL;
00085 
00086 const int FacetQueryEngine::FQE_MAJOR_VERSION = 10;
00087 const int FacetQueryEngine::FQE_MINOR_VERSION = 0;
00088 const int FacetQueryEngine::FQE_SUBMINOR_VERSION = 0;
00089 
00090 struct ContainmentPoint
00091 {
00092   CubitVector *pt_coordinates;
00093   int index;  
00094   CubitBox bounding_box() { return CubitBox( *pt_coordinates); }      
00095 };
00096 
00097 //================================================================================
00098 // Description:
00099 // Author     :
00100 // Date       :
00101 //================================================================================
00102 FacetQueryEngine* FacetQueryEngine::instance()
00103 {
00104   if (instance_ == NULL ) {
00105       instance_ = new FacetQueryEngine;
00106    }
00107   return instance_;
00108 }
00109 
00110 //================================================================================
00111 // Description:  default constructor
00112 // Author     :
00113 // Date       :
00114 //================================================================================
00115 FacetQueryEngine::FacetQueryEngine()
00116 {
00117   GeometryQueryTool::instance()->add_gqe( this );
00118 }
00119 
00120 //================================================================================
00121 // Description:  destructor
00122 // Author     :
00123 // Date       :
00124 //================================================================================
00125 FacetQueryEngine::~FacetQueryEngine()
00126 {
00127   instance_ = NULL;
00128 }
00129 
00130 void FacetQueryEngine::delete_instance()
00131 {
00132   if( NULL != instance_ )
00133   {
00134     delete instance_;
00135     instance_ = NULL;
00136   }
00137 }
00138 
00139 
00140 
00141 //================================================================================
00142 // Description:  can_delete_bodies
00143 // Author     : sjowen
00144 // Date       : 4/25/02
00145 //================================================================================
00146 CubitBoolean FacetQueryEngine::can_delete_bodies(DLIList<Body*>body_list)
00147 {
00148   CubitBoolean delete_ok = CUBIT_TRUE;
00149   int ii;
00150   for (ii=0; ii<body_list.size() && delete_ok; ii++)
00151   {
00152     Body *body_ptr = body_list.get_and_step();
00153     // Extract the BODY from Body
00154     FacetBody* fbody_ptr = CAST_TO(body_ptr->get_body_sm_ptr(), FacetBody);
00155     if (fbody_ptr)
00156     {
00157       delete_ok = fbody_ptr->can_be_deleted(body_list);
00158     }
00159   }
00160   return delete_ok;
00161 }
00162 
00163 int FacetQueryEngine::get_major_version()
00164 {
00165   return FQE_MAJOR_VERSION;
00166 }
00167 
00168 int FacetQueryEngine::get_minor_version()
00169 {
00170   return FQE_MINOR_VERSION;
00171 }
00172 
00173 int FacetQueryEngine::get_subminor_version()
00174 {
00175   return FQE_SUBMINOR_VERSION;
00176 }
00177 
00178 CubitString FacetQueryEngine::get_engine_version_string()
00179 {
00180   CubitString version_string = "Facet Geometry Engine version ";
00181   version_string += CubitString::number(get_major_version());
00182   version_string += CubitString(".");
00183   version_string += CubitString::number(get_minor_version());
00184   version_string += CubitString(".");
00185   version_string += CubitString::number(get_subminor_version());
00186   
00187   return version_string;
00188 }
00189 
00190 //================================================================================
00191 // Description:
00192 // Author     :
00193 // Date       :
00194 //================================================================================
00195 const std::type_info& FacetQueryEngine::entity_type_info() const
00196 {
00197    return typeid(*this);
00198 }
00199 
00200 //================================================================================
00201 // Description:
00202 // Author     :
00203 // Date       :
00204 //================================================================================
00205 TBPoint* FacetQueryEngine::make_Point( GeometryType ,
00206                                         CubitVector const& ) const
00207 {
00208   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00209   return (TBPoint*) NULL;
00210 }
00211 
00212 //================================================================================
00213 // Description:
00214 // Author     :
00215 // Date       :
00216 //================================================================================
00217 Curve* FacetQueryEngine::make_Curve(Curve *) const
00218 {
00219   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00220   return (Curve*) NULL;
00221 }
00222 
00223 //================================================================================
00224 // Description:
00225 // Author     :
00226 // Date       :
00227 //================================================================================
00228 Curve* FacetQueryEngine::make_Curve( TBPoint const* ,
00229                                         TBPoint const* ,
00230                                         RefFace* ,
00231                                         CubitVector * ) const
00232 {
00233   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00234   return (Curve*) NULL;
00235 }
00236 
00237 //================================================================================
00238 // Description:
00239 // Author     :
00240 // Date       :
00241 //================================================================================
00242 Curve* FacetQueryEngine::make_Curve( GeometryType ,
00243                                         TBPoint const* ,
00244                                         TBPoint const* ,
00245                                         DLIList<CubitVector*>& ,
00246                                         RefFace*  ) const
00247 {
00248   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00249   return (Curve*) NULL;
00250 }
00251 
00252 //================================================================================
00253 // Description:
00254 // Author     :
00255 // Date       :
00256 //================================================================================
00257 Curve* FacetQueryEngine::make_Curve( GeometryType ,
00258                                         TBPoint const* ,
00259                                         TBPoint const* ,
00260                                         CubitVector const* ,
00261                                         CubitSense ) const
00262 {
00263   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00264   return (Curve*) NULL;
00265 }
00266 
00267 //================================================================================
00268 // Description:
00269 // Author     :
00270 // Date       :
00271 //================================================================================
00272 Surface* FacetQueryEngine::make_Surface( Surface *,
00273                                             DLIList<Loop*> &,
00274                                             CubitBoolean  ) const
00275 {
00276   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00277   return (Surface*) NULL;
00278 }
00279 
00280 //================================================================================
00281 // Description:
00282 // Author     :
00283 // Date       :
00284 //================================================================================
00285 Surface* FacetQueryEngine::make_Surface( GeometryType ,
00286                                             DLIList<Curve*>& ,
00287                                             DLIList<Loop*> &,
00288                                             Surface *) const
00289 {
00290   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00291   return (Surface*) NULL;
00292 }
00293 
00294 //================================================================================
00295 // Description:
00296 // Author     :
00297 // Date       :
00298 //================================================================================
00299 Lump* FacetQueryEngine::make_Lump( GeometryType ,
00300                                       DLIList<Surface*>&  ) const
00301 {
00302   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00303   return (Lump*) NULL;
00304 }
00305 
00306 //================================================================================
00307 // Description:
00308 // Author     :
00309 // Date       :
00310 //================================================================================
00311 BodySM* FacetQueryEngine::make_BodySM( Surface * ) const
00312 {
00313   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00314   return (BodySM*) NULL;
00315 }
00316 
00317 //================================================================================
00318 // Description:
00319 // Author     :
00320 // Date       :
00321 //================================================================================
00322 BodySM* FacetQueryEngine::make_BodySM( DLIList<Lump*>&  ) const
00323 {
00324   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00325   return (BodySM*) NULL;
00326 }
00327 
00328 //================================================================================
00329 // Description: create a new body by copying
00330 // Author     : sjowen
00331 // Date       : 9/7/01
00332 //================================================================================
00333 Body* FacetQueryEngine::copy_body( Body *body_ptr )
00334 {
00335   BodySM* bodysm_ptr = body_ptr->get_body_sm_ptr();
00336   FacetBody *facet_body_ptr = CAST_TO(bodysm_ptr, FacetBody);
00337   if (!facet_body_ptr)
00338   {
00339     PRINT_ERROR("Attempt to copy mesh-based geometry Body.  This body is not MBG.");
00340     return (Body*)NULL;
00341   }
00342 
00343   TopologyBridge *top_bridge;
00344   GeometryModifyTool::instance()->prepare_for_copy( body_ptr, top_bridge );
00345 
00346   BodySM* osme_body_ptr = (BodySM*)facet_body_ptr->copy();
00347   if (!osme_body_ptr)
00348   {
00349     GeometryModifyTool::instance()->clean_up_from_copy_failure( top_bridge );
00350     PRINT_ERROR("Failed to copy mesh-based geometry Body");
00351     return (Body*)NULL;
00352   }
00353 
00354   TopologyBridge *tb = (TopologyBridge*)osme_body_ptr;
00355   GeometryModifyTool::instance()->finish_copy( tb, bodysm_ptr );
00356 
00357   Body *new_body_ptr = GeometryQueryTool::instance()->make_Body( osme_body_ptr );
00358   return new_body_ptr;
00359 }
00360 
00361 //================================================================================
00362 // Description: reflect body about an axis
00363 // Author     : sjowen
00364 // Date       : 9/7/01
00365 //================================================================================
00366 CubitStatus FacetQueryEngine::reflect( BodySM *bodysm,
00367                                        const CubitVector& axis)
00368 {
00369   FacetBody *fbody = CAST_TO(bodysm, FacetBody);
00370   if (!fbody)
00371   {
00372     PRINT_ERROR("Attempt to reflect mesh-based geometry Body.  This body is not MBG.");
00373     return CUBIT_FAILURE;
00374   }
00375 
00376   fbody->reflect( axis.x(), axis.y(), axis.z() );
00377 
00378   return CUBIT_SUCCESS;
00379 }
00380 
00381 CubitStatus FacetQueryEngine::get_connected_patch(
00382                       DLIList<FacetSurface*>& remaining_surfs,
00383                       DLIList<FacetSurface*>& output_patch )
00384 {
00385   DLIList<FacetSurface*> stack, curve_surfs;
00386   std::set<FacetSurface*> marked;
00387   DLIList<FacetCurve*> curves;
00388   int debug_this = 0;
00389   if(debug_this){
00390     GfxDebug::clear();
00391   }
00392   int i;
00393   for (i = remaining_surfs.size(); i--; )
00394     marked.insert( remaining_surfs.get_and_step() );
00395 
00396   // Choose one surface to start with
00397   FacetSurface* surf = remaining_surfs.pop();
00398   marked.erase( surf );
00399   stack.append( surf );
00400 
00401   // Get all connected surfaces
00402   while( stack.size() )
00403   {
00404     surf = stack.pop();
00405     if(debug_this){
00406       surf->get_eval_tool()->debug_draw_facets(CUBIT_BLUE_INDEX);
00407       GfxDebug::mouse_xforms();
00408     }
00409     output_patch.append( surf );
00410 
00411     surf->get_curves( curves );
00412     while (curves.size())
00413     {
00414       FacetCurve* curve = curves.pop();
00415       curve->get_surfaces( curve_surfs );
00416       if(debug_this && curve_surfs.size() < 2){
00417         PRINT_INFO("Curve is not connected to 2 surfaces.\n");
00418         curve->get_eval_tool()->debug_draw_facet_edges(CUBIT_MAGENTA_INDEX);
00419       }
00420       
00421         
00422       while (curve_surfs.size())
00423       {
00424         FacetSurface* curve_surf = curve_surfs.pop();
00425         if (marked.erase(curve_surf))
00426           stack.append( curve_surf );
00427       }
00428     }
00429   }
00430 
00431   // Remove output surfaces from input list
00432   // At this point, "marked" contains all the surfaces not in "ouput_patch"
00433   remaining_surfs.last();
00434   for (i = remaining_surfs.size(); i--; )
00435     if (marked.find(remaining_surfs.step_and_get()) == marked.end())
00436       remaining_surfs.change_to( 0 );
00437     remaining_surfs.remove_all_with_value( 0 );
00438 
00439   return CUBIT_SUCCESS;
00440 
00441 }
00442 
00443 CubitStatus FacetQueryEngine::get_graphics( BodySM *bodysm, GMem* g_mem,
00444                          std::vector<Surface*> &surface_to_facets_vector,
00445                          std::vector<TopologyBridge*> &vertex_edge_to_point_vector,
00446                          std::vector<std::pair<TopologyBridge*, std::pair<int,int> > > &facet_edges_on_curves,
00447                          unsigned short normal_tolerance, 
00448                          double distance_tolerance, double max_edge_length ) const
00449 {  
00450   FacetBody *facet_body = CAST_TO(bodysm, FacetBody );
00451   if( NULL == facet_body )
00452     return CUBIT_FAILURE;
00453  
00454   DLIList<Surface*> surfaces;
00455   bodysm->surfaces( surfaces );
00456 
00457   //unmark all the points
00458   for( int i=surfaces.size(); i--; )
00459   {
00460     Surface *tmp_surf = surfaces.get_and_step();
00461     FacetSurface *facet_surface = CAST_TO( tmp_surf, FacetSurface );    
00462     
00463     DLIList<CubitPoint*> surface_points;
00464     facet_surface->get_my_points( surface_points );
00465 
00466     for( int k=surface_points.size(); k--; )
00467       surface_points.get_and_step()->marked(0);
00468   }
00469 
00470   DLIList<CubitFacet*> all_facets;
00471   int point_index = 0;
00472   std::vector<CubitPoint*> all_points; 
00473   for( int i=surfaces.size(); i--; )
00474   {
00475     Surface *tmp_surf = surfaces.get_and_step();
00476     FacetSurface *facet_surface = CAST_TO( tmp_surf, FacetSurface );
00477     
00478     DLIList<CubitFacet*> surface_facets;
00479     DLIList<CubitPoint*> surface_points;
00480     facet_surface->get_my_facets(surface_facets, surface_points);
00481 
00482     surface_facets.reset();
00483     all_facets += surface_facets;
00484     
00485     for( int k=surface_points.size(); k--; )
00486     {
00487       CubitPoint *tmp_pt = surface_points.get_and_step();
00488       if( tmp_pt->marked() == 0 )
00489       {
00490         all_points.push_back( tmp_pt );
00491         point_index++;
00492         tmp_pt->marked( point_index );       
00493         vertex_edge_to_point_vector.push_back( tmp_surf );
00494       }      
00495     }
00496  
00497     surface_facets.reset();
00498     for( int k=surface_facets.size(); k--; )    
00499       surface_to_facets_vector.push_back( tmp_surf );
00500   }
00501 
00502   //now stuff them into the g_mem
00503   g_mem->allocate_tri( all_facets.size() );
00504   g_mem->fListCount = all_facets.size() * 4;
00505   g_mem->pointListCount = all_points.size();
00506   
00507   GPoint* pt_itor = g_mem->point_list();
00508   for ( size_t i = 0; i < all_points.size(); i++ )
00509   {
00510     CubitPoint* point = all_points[i];
00511     pt_itor->x = (float)point->x();
00512     pt_itor->y = (float)point->y();
00513     pt_itor->z = (float)point->z();
00514     pt_itor++;    
00515   }
00516 
00517    // Copy facets to Gmem
00518   all_facets.reset();
00519   int* f_itor = g_mem->facet_list();
00520   for ( int i = 0; i < all_facets.size(); i++ )
00521   {
00522     *(f_itor++) = 3;
00523     CubitFacet* facet = all_facets.get_and_step();    
00524     for ( int j = 0; j < 3; j++ )
00525     {
00526       *(f_itor++) = facet->point(j)->marked() - 1;  //go back to zero-based      
00527     }    
00528   }
00529  
00530   //get all the curves
00531   DLIList<Curve*> curves;
00532   bodysm->curves( curves );
00533   for( int i=curves.size(); i--; )
00534   {
00535     Curve *tmp_curve = curves.get_and_step();
00536     FacetCurve *facet_curve = CAST_TO( tmp_curve, FacetCurve );    
00537     
00538     //get all the curves
00539     DLIList<CubitFacetEdge*> curve_facets;
00540     facet_curve->get_facets(curve_facets);
00541     DLIList<CubitPoint*> curve_points;
00542     facet_curve->get_points(curve_points);
00543     curve_points.reset();
00544     curve_facets.reset();
00545 
00546     for( int k=0; k<curve_points.size(); k++ )
00547     {
00548       CubitPoint *tmp_pt = curve_points.get_and_step();
00549       assert( tmp_pt->marked() );     
00550 
00551       if( k == curve_points.size() - 1 )
00552         break;
00553             
00554       int index1 = tmp_pt->marked();
00555       int index2 = curve_points.get()->marked();
00556 
00557       vertex_edge_to_point_vector[index1-1] = tmp_curve;
00558       facet_edges_on_curves.push_back( std::make_pair( tmp_curve, std::make_pair( index1-1, index2-1) ) );
00559     }
00560   }
00561   
00562   //get all the vertices
00563   DLIList<TBPoint*> points;
00564   bodysm->points( points );
00565 
00566   for( int i=points.size(); i--; )
00567   {
00568     TBPoint *tmp_pt = points.get_and_step();
00569     FacetPoint *facet_point = CAST_TO( tmp_pt, FacetPoint );
00570     CubitPoint *cubit_pt = facet_point->get_cubit_point();
00571     assert( cubit_pt->marked() );
00572     vertex_edge_to_point_vector[cubit_pt->marked()-1] = tmp_pt;
00573   }
00574 
00575 
00576   //reset the marks back to zero
00577   for ( unsigned int i = 0; i < all_points.size(); i++ )
00578     all_points[i]->marked(0);
00579 
00580 
00581   return CUBIT_SUCCESS;
00582 }
00583 
00584 //================================================================================
00585 // Description:
00586 // Author     :
00587 // Date       :
00588 //================================================================================
00589 CubitStatus FacetQueryEngine::get_graphics( Surface* surface_ptr,
00590                                                      GMem* gMem,
00591                                                      unsigned short ,
00592                                                      double, double ) const
00593 {
00594   if( !gMem )
00595     return CUBIT_FAILURE;
00596 
00597     //  get the FacetSurface.
00598   int i;
00599   FacetSurface *facet_surf_ptr = CAST_TO(surface_ptr,FacetSurface);
00600   if( ! facet_surf_ptr )
00601     return CUBIT_FAILURE;
00602 
00603     // get the facets for the surface
00604   DLIList<CubitFacet*> surface_facets;
00605   DLIList<CubitPoint*> surface_points;
00606   facet_surf_ptr->get_my_facets(surface_facets, surface_points);
00607 
00608     // set return values, and if GMem is NULL return
00609     // (caller just wanted to know the counts.)
00610   int number_points = surface_points.size();
00611   int number_triangles = surface_facets.size();
00612 
00613 
00614     // Allocate space in GMem
00615   gMem->allocate_tri(number_triangles);
00616   gMem->fListCount = surface_facets.size() * 4;
00617   gMem->pointListCount = number_points;
00618 
00619     // Copy points to GMem
00620   surface_points.reset();
00621   GPoint* pt_itor = gMem->point_list();
00622   for ( i = 0; i < number_points; i++ )
00623   {
00624     CubitPoint* point = surface_points.get_and_step();
00625     pt_itor->x = (float)point->x();
00626     pt_itor->y = (float)point->y();
00627     pt_itor->z = (float)point->z();
00628     point->marked(i);
00629     pt_itor++;
00630   }
00631 
00632     // Copy facets to Gmem
00633   surface_facets.reset();
00634   int* f_itor = gMem->facet_list();
00635   for ( i = 0; i < number_triangles; i++ )
00636   {
00637     *(f_itor++) = 3;
00638     CubitFacet* facet = surface_facets.get_and_step();
00639     for ( int j = 0; j < 3; j++ )
00640       *(f_itor++) = facet->point(j)->marked();
00641   }
00642 
00643     // cleanup
00644   while( surface_points.size() )
00645     surface_points.pop()->marked(0);
00646 
00647   return CUBIT_SUCCESS;
00648 }
00649 
00650 //================================================================================
00651 // Description:
00652 // Author     :
00653 // Date       :
00654 //================================================================================
00655 CubitStatus FacetQueryEngine::get_graphics( Curve* curve_ptr,
00656                                             GMem* gMem,
00657                                             double /*angle_tolerance*/,
00658                                             double /*distance_tolerance*/,
00659                                             double /*max_edge_length*/ ) const
00660 {
00661   //  get the FacetCurve.
00662   FacetCurve *facet_curv_ptr = CAST_TO(curve_ptr,FacetCurve);
00663 
00664   DLIList<CubitFacetEdge*> curve_facets;
00665   facet_curv_ptr->get_facets(curve_facets);
00666   int number_facets = curve_facets.size();
00667   DLIList<CubitPoint*> curve_points;
00668   facet_curv_ptr->get_points(curve_points);
00669   curve_points.reset();
00670   curve_facets.reset();
00671   int num_points = curve_points.size();
00672   GPoint *new_point_list = new GPoint[num_points];
00673   int *new_facet_list = new int [number_facets*3];
00674   int ii;
00675   CubitPoint *cur_pnt;
00676   for ( ii = 0; ii < num_points; ii++ )
00677   {
00678     cur_pnt = curve_points.get();
00679     new_point_list[ii].x = cur_pnt->x();
00680     new_point_list[ii].y = cur_pnt->y();
00681     new_point_list[ii].z = cur_pnt->z();
00682       //mark the point with the index into the point list.
00683       //This is very important to make sure we can index these
00684       //points when we do the facet array.
00685     curve_points.get_and_step()->marked(ii);
00686   }
00687   for ( ii = 0; ii < number_facets; ii++ )
00688   {
00689       //All our facets are segments.  So the first value is 2.
00690     int index_count = 3*ii;
00691     new_facet_list[index_count] = 2;
00692     int jj = index_count + 1;
00693     int ll, kk;
00694     CubitFacetEdge *facet_ptr = curve_facets.get_and_step();
00695     CubitPoint *temp_point;
00696     for ( kk = jj, ll = 0; kk < jj+2; kk++, ll++)
00697     {
00698       temp_point = facet_ptr->point(ll);
00699       int index_to_point = temp_point->marked();
00700       if ( index_to_point < 0 || index_to_point > num_points )
00701       {
00702         PRINT_ERROR("Bad logic in converting edge facets to drawing facets.\n");
00703         delete[] new_point_list;
00704         delete[] new_facet_list;
00705         return CUBIT_FAILURE;
00706       }
00707       new_facet_list[kk] = index_to_point;
00708     }
00709   }
00710   gMem->replace_point_list(new_point_list, num_points, num_points);
00711   gMem->replace_facet_list(new_facet_list, number_facets*3, number_facets*3);
00712   gMem->points_consolidated(CUBIT_TRUE);
00713 
00714   return CUBIT_SUCCESS;
00715 }
00716 
00717 //================================================================================
00718 // Description:
00719 // Author     :
00720 // Date       :
00721 //================================================================================
00722 CubitStatus FacetQueryEngine::get_isoparametric_points(Surface* ,
00723                                                           int &nu, int &nv,
00724                                                           GMem*&) const
00725 {
00726   nu = nv = 0;
00727   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00728   return CUBIT_FAILURE;
00729 }
00730 
00731 CubitStatus FacetQueryEngine::get_u_isoparametric_points(Surface* ,
00732                                                             double, int&,
00733                                                             GMem*&) const
00734 {
00735   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00736   return CUBIT_FAILURE;
00737 }
00738 
00739 CubitStatus FacetQueryEngine::get_v_isoparametric_points(Surface* ,
00740                                                             double, int&,
00741                                                             GMem*&) const
00742 {
00743   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00744   return CUBIT_FAILURE;
00745 }
00746 
00747 //================================================================================
00748 // Description:
00749 // Author     :
00750 // Date       :
00751 //================================================================================
00752 CubitStatus FacetQueryEngine::transform_vec_position( CubitVector const& ,
00753                                                          BodySM *,
00754                                                          CubitVector & ) const
00755 {
00756   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00757   return CUBIT_FAILURE;
00758 }
00759 
00760 //================================================================================
00761 // Description:
00762 // Author     :
00763 // Date       :
00764 //================================================================================
00765 CubitStatus FacetQueryEngine::get_intersections( Curve* , CubitVector& ,
00766                                                  CubitVector&,
00767                                                     DLIList<CubitVector>& ,
00768                                                     CubitBoolean,
00769                                                     CubitBoolean )
00770 {
00771   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00772   return CUBIT_FAILURE;
00773 }
00774 
00775 CubitStatus FacetQueryEngine::get_intersections( Curve* , Curve* ,
00776                                                     DLIList<CubitVector>& ,
00777                                                     CubitBoolean,
00778                                                     CubitBoolean )
00779 {
00780   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00781   return CUBIT_FAILURE;
00782 }
00783 CubitStatus FacetQueryEngine::get_intersections( Curve*,
00784                                                    Curve*,
00785                                                    DLIList<CubitVector>&,
00786                                                    double, CubitBoolean )
00787 {
00788   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00789   return CUBIT_FAILURE;
00790 }
00791 
00792 CubitStatus
00793 FacetQueryEngine::get_intersections( Curve* /*ref_edge*/, Surface* /*ref_face*/,
00794                                         DLIList<CubitVector>& ,
00795                                         CubitBoolean )
00796 {
00797   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00798    return CUBIT_FAILURE;
00799 }
00800 
00801 //================================================================================
00802 // Description: Find extrema position on an entity list
00803 // Author     :
00804 // Date       :
00805 //================================================================================
00806 CubitStatus
00807 FacetQueryEngine::entity_extrema( DLIList<GeometryEntity*> &,
00808                                   const CubitVector *,
00809                                   const CubitVector *,
00810                                   const CubitVector *,
00811                                   CubitVector &,
00812                                   GeometryEntity *& )
00813 {
00814   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00815   return CUBIT_FAILURE;
00816 }
00817 
00818 //================================================================================
00819 // Description: Find distance between two entities and closest positions.
00820 // Author     :
00821 // Date       :
00822 //================================================================================
00823 CubitStatus
00824 FacetQueryEngine::entity_entity_distance( GeometryEntity *,
00825                                           GeometryEntity *,
00826                                           CubitVector &, CubitVector &,
00827                                           double & )
00828 {
00829   PRINT_ERROR("Option not supported for mesh based geometry.\n");
00830   return CUBIT_FAILURE;
00831 }
00832 
00833 //===========================================================================
00834 //Function Name: save_temp_geom_file
00835 //Member Type:  PUBLIC
00836 //Description:  function called for save/restore to save temporary FACET file
00837 //              If file is created, CubitString 'created_file' and
00838 //              'create_file_type' are set
00839 //Author:       Corey Ernst
00840 //Date:         1/18/2003
00841 //===========================================================================
00842 
00843 CubitStatus FacetQueryEngine::save_temp_geom_file( DLIList<TopologyBridge*>& ref_entity_list,
00844                                                    const char *file_name,
00845                                                    const CubitString &cubit_version,
00846                                                    CubitString &created_file,
00847                                                    CubitString &created_file_type)
00848 {
00849   int size_before = ref_entity_list.size();
00850   CubitString temp_filename(file_name);
00851   temp_filename += ".mbg";
00852 
00853   ModelExportOptions export_options;
00854 
00855   if( export_solid_model( ref_entity_list, temp_filename.c_str(), FACET_TYPE,
00856                           cubit_version, export_options ) == CUBIT_FAILURE )
00857   {
00858     PRINT_ERROR( "Error occured while trying to save temporary MESH_BASED_GEOMETRY file\n");
00859     return CUBIT_FAILURE;
00860   }
00861 
00862   int size_after = ref_entity_list.size();
00863 
00864   if( size_before > size_after )
00865   {
00866     created_file +=  temp_filename;
00867     created_file_type += "FACET";
00868   }
00869   return CUBIT_SUCCESS;
00870 }
00871 
00872 //===========================================================================
00873 //Function Name:export_solid_model
00874 //Member Type:  PUBLIC
00875 //Description:  function called for save/restore to save temporary FACET file
00876 //Author:       Corey Ernst
00877 //Date:         1/18/2003
00878 //===========================================================================
00879 
00880 CubitStatus FacetQueryEngine::export_solid_model( DLIList<TopologyBridge*>& ref_entity_list,
00881                                                      const char* file_name,
00882                                                      Model_File_Type file_type,
00883                                                      const CubitString &,
00884                                                      ModelExportOptions & )                                                     
00885 {
00886   if(  file_type != FACET_TYPE )
00887     return CUBIT_SUCCESS;
00888 
00889   DLIList<FacetBody*>    facet_bodies;
00890   DLIList<FacetLump*>    facet_lumps;
00891   DLIList<FacetShell*>   facet_shells;
00892   DLIList<FacetSurface*> facet_surfaces;
00893   DLIList<FacetLoop*>    facet_loops;
00894   DLIList<FacetCoEdge*>  facet_coedges;
00895   DLIList<FacetCurve*>   facet_curves;
00896   DLIList<FacetPoint*>   facet_points;
00897 
00898   DLIList<TopologyBridge*> ref_entities_handled;
00899 
00900   int i;
00901   //Collect all free entities (bodies, curves, vertices )
00902   ref_entity_list.reset();
00903   for(i=ref_entity_list.size(); i>0; i--)
00904   {
00905     TopologyBridge* ref_entity_ptr = ref_entity_list.get();
00906     CubitBoolean handled = CUBIT_TRUE;
00907 
00908     //if it is a Vertex
00909     if( FacetPoint* pt = CAST_TO( ref_entity_ptr, FacetPoint) )
00910       facet_points.append( pt );
00911     //if it is a Curve
00912     else if( FacetCurve* curve = CAST_TO( ref_entity_ptr, FacetCurve) )
00913       facet_curves.append( curve );
00914     /*
00915     //if it is a Surface -- I don't think you can ever have a free surface
00916     //without it being a Body
00917     else if( FacetSurface* surf = CAST_TO( ref_entity_ptr, FacetSurface) )
00918       facet_surfaces.append( surf );
00919    */
00920     //if it is a Body
00921     else if( FacetBody* body = CAST_TO( ref_entity_ptr, FacetBody ) )
00922       facet_bodies.append( body );
00923     else
00924       handled = CUBIT_FALSE;
00925 
00926     if( handled == CUBIT_TRUE )
00927     {
00928       ref_entities_handled.append( ref_entity_ptr );
00929       ref_entity_list.change_to(NULL);
00930     }
00931 
00932     ref_entity_list.step();
00933   }
00934 
00935   ref_entity_list.remove_all_with_value(NULL);
00936 
00937   int free_body_count = facet_bodies.size();
00938   int free_curve_count = facet_curves.size();
00939   int free_point_count = facet_points.size();
00940 
00941   //if nothing to write out...return
00942   if( free_body_count == 0 && free_curve_count == 0 && free_point_count == 0)
00943     return CUBIT_SUCCESS;
00944 
00945   //get file pointer
00946   FILE *file_ptr = fopen( file_name, "wb" );
00947 
00948   //get all child entities from the bodies, curves, & vertices
00949   gather_all_facet_entities( facet_bodies, facet_lumps,
00950                              facet_shells, facet_surfaces,
00951                              facet_loops, facet_coedges,
00952                              facet_curves, facet_points );
00953 
00954   //create a wrapper object for writing
00955   CIOWrapper file_writer( file_ptr );
00956 
00957   // write out file type "MESHED_BASED_GEOMETRY"
00958   file_writer.BeginWriteBlock(0);
00959   file_writer.Write( "MESH_BASED_GEOMETRY", 19 );
00960 
00961   // write out Endian value
00962   UnsignedInt32 endian_value = CCubitFile::mintNativeEndian;
00963   file_writer.Write( &endian_value, 1 );
00964 
00965   // write out version #
00966   UnsignedInt32 version = 1;
00967   file_writer.Write( &version, 1 );
00968 
00969 
00970   //save the facets (geometry info )
00971   CubitStatus status;
00972   status = save_facets( file_ptr, facet_surfaces, facet_curves, facet_points );
00973   if( status == CUBIT_FAILURE ) return CUBIT_FAILURE;
00974 
00975   //write out topology and attributes
00976   status = write_topology( file_ptr,
00977                            facet_bodies, facet_lumps,
00978                            facet_shells, facet_surfaces,
00979                            facet_loops, facet_coedges,
00980                            facet_curves, facet_points );
00981   if( status == CUBIT_FAILURE ) return CUBIT_FAILURE;
00982 
00983   if( free_body_count || free_curve_count || free_point_count )
00984       PRINT_INFO( "\nExported:" );
00985 
00986    int flg = 0;
00987 
00988    if( free_body_count )
00989    {
00990       if( flg )PRINT_INFO( "         " );else flg=1;
00991       if( DEBUG_FLAG( 153 ) )
00992       {
00993         if( free_body_count == 1 )
00994            PRINT_INFO( "%4d Facet Body\n", free_body_count );
00995         else
00996            PRINT_INFO( "%4d Facet Bodies\n", free_body_count );
00997       }
00998       
00999       if( facet_lumps.size() == 1 )
01000          PRINT_INFO( "%4d Facet Volume\n", facet_lumps.size() );
01001       else
01002          PRINT_INFO( "%4d Facet Volumes\n", facet_lumps.size() );
01003    }
01004    if( free_curve_count )
01005    {
01006       if( flg )PRINT_INFO( "         " );else flg=1;
01007       if( free_curve_count == 1 )
01008          PRINT_INFO( "%4d Facet Curve\n", free_curve_count );
01009       else
01010          PRINT_INFO( "%4d Facet Curves\n", free_curve_count );
01011    }
01012    if( free_point_count )
01013    {
01014       if( flg )PRINT_INFO( "         " );else flg=1;
01015       if( free_point_count == 1 )
01016          PRINT_INFO( "%4d Facet Point\n", free_point_count );
01017       else
01018          PRINT_INFO( "%4d Facet Points\n", free_point_count );
01019    }
01020    PRINT_INFO( "\n" );
01021 
01022 
01023 
01024   fclose( file_ptr );
01025 
01026   return CUBIT_SUCCESS;
01027 }
01028 
01029 CubitStatus
01030 FacetQueryEngine::gather_all_facet_entities( DLIList<FacetBody*> &facet_bodies,
01031                                              DLIList<FacetLump*> &facet_lumps,
01032                                              DLIList<FacetShell*> &facet_shells,
01033                                              DLIList<FacetSurface*> &facet_surfaces,
01034                                              DLIList<FacetLoop*> &facet_loops,
01035                                              DLIList<FacetCoEdge*> &facet_coedges,
01036                                              DLIList<FacetCurve*> &facet_curves,
01037                                              DLIList<FacetPoint*> &facet_points )
01038 {
01039   int i;
01040 
01041 
01042   //Collect FacetLumps from FacetBody
01043   for(i=0; i<facet_bodies.size(); i++)
01044   {
01045     FacetBody *facet_body = facet_bodies.get_and_step();
01046     facet_body->get_lumps( facet_lumps );
01047   }
01048 
01049 
01050   //Collect FacetShells from FacetLumps
01051   for(i=0; i<facet_lumps.size(); i++)
01052   {
01053     FacetLump *facet_lump = facet_lumps.get_and_step();
01054     facet_lump->get_shells( facet_shells );
01055   }
01056 
01057 
01058   //Collect FacetSurfaces from FacetShells
01059   for(i=0; i<facet_shells.size(); i++)
01060   {
01061     FacetShell *facet_shell = facet_shells.get_and_step();
01062     facet_shell->get_surfaces( facet_surfaces );
01063   }
01064   facet_surfaces.uniquify_ordered();
01065 
01066 
01067   //Collect FacetLoops from FacetSurfaces
01068   for(i=0; i<facet_surfaces.size(); i++)
01069   {
01070     FacetSurface *facet_surface = facet_surfaces.get_and_step();
01071     facet_surface->get_loops( facet_loops );
01072   }
01073 
01074   //Collect FacetCoEdges from FacetLoops
01075   for(i=0; i<facet_loops.size(); i++)
01076   {
01077     FacetLoop *facet_loop = facet_loops.get_and_step();
01078     facet_loop->get_coedges( facet_coedges );
01079   }
01080 
01081 
01082   //Collect FacetCurves from FacetCoEdges
01083   for( i=0; i<facet_coedges.size(); i++)
01084   {
01085     FacetCoEdge *facet_coedge = facet_coedges.get_and_step();
01086     facet_coedge->get_curves( facet_curves );
01087   }
01088   facet_curves.uniquify_ordered();
01089 
01090 
01091   //Collect FacetPoints from FacetCurves
01092   for( i=0; i<facet_curves.size(); i++)
01093   {
01094     FacetCurve *facet_curve = facet_curves.get_and_step();
01095     facet_curve->get_points( facet_points );
01096   }
01097 
01098   //uniquify lists
01099   facet_points.uniquify_ordered();
01100 
01101 
01102   return CUBIT_SUCCESS;
01103 
01104 }
01105 
01106 
01107 CubitStatus
01108 FacetQueryEngine::write_topology( FILE *file_ptr,
01109                                   DLIList<FacetBody*> &facet_bodies,
01110                                   DLIList<FacetLump*> &facet_lumps,
01111                                   DLIList<FacetShell*> &facet_shells,
01112                                   DLIList<FacetSurface*> &facet_surfaces,
01113                                   DLIList<FacetLoop*> &facet_loops,
01114                                   DLIList<FacetCoEdge*> &facet_coedges,
01115                                   DLIList<FacetCurve*> &facet_curves,
01116                                   DLIList<FacetPoint*> &facet_points )
01117 {
01118 
01119   int i;
01120 
01121   //create a wrapper object for writing
01122   CIOWrapper file_writer( file_ptr );
01123 
01124   //-----------------write FacetPoints--------------
01125   UnsignedInt32 size = facet_points.size();
01126   //write out number of FacetPoints
01127   file_writer.Write( &size, 1 );
01128   facet_points.reset();
01129   for( i=0; i<facet_points.size(); i++)
01130   {
01131     FacetPoint *curr_point = facet_points.get_and_step();
01132     int id = curr_point->get_cubit_point()->id();
01133 
01134     file_writer.Write( reinterpret_cast<UnsignedInt32*>(&id), 1 );
01135     if( curr_point->save_attribs(file_ptr) == CUBIT_FAILURE )
01136       return CUBIT_FAILURE;
01137   }
01138 
01139   //-----------------write FacetCurves--------------
01140   size = facet_curves.size();
01141   //write out number of FacetCurves
01142   file_writer.Write( &size, 1 );
01143   facet_curves.reset();
01144   for( i=0; i<facet_curves.size(); i++)
01145   {
01146     FacetCurve *curr_curve = facet_curves.get_and_step();
01147     TBPoint *s_point, *e_point;
01148     s_point = curr_curve->start_point();
01149     e_point = curr_curve->end_point();
01150 
01151     int data_to_write[4];
01152 
01153     // get start&end points implicit ids
01154     FacetPoint *temp_point = NULL;
01155     temp_point = CAST_TO( s_point, FacetPoint );
01156     if( !temp_point ) assert(0);
01157     int found;
01158     found = facet_points.where_is_item( temp_point );
01159     if( found == -1)
01160       assert(0);
01161     data_to_write[0] = found;
01162 
01163     temp_point = CAST_TO( e_point, FacetPoint );
01164     if( !temp_point ) assert(0);
01165     found = facet_points.where_is_item( temp_point );
01166     if( found == -1)
01167       PRINT_ERROR("Problem saving Facet Curves\n");
01168     data_to_write[1] = found;
01169 
01170     //convert Sense info to integer
01171     if( curr_curve->get_sense() == CUBIT_UNKNOWN )
01172       data_to_write[2] = -1;
01173     else
01174       data_to_write[2] = (curr_curve->get_sense() == CUBIT_REVERSED) ? 1 : 0;
01175 
01176     data_to_write[3] = curr_curve->get_eval_tool()->get_output_id();
01177 
01178     //write the data
01179     file_writer.Write( reinterpret_cast<UnsignedInt32*>(data_to_write), 4 );
01180 
01181     if( curr_curve->save_attribs(file_ptr) == CUBIT_FAILURE )
01182       return CUBIT_FAILURE;
01183   }
01184 
01185   //-----------------write FacetCoedges--------------
01186   size = facet_coedges.size();
01187   // write out number of FacetCurves
01188   file_writer.Write( &size, 1 );
01189   facet_coedges.reset();
01190   for( i=0; i<facet_coedges.size(); i++)
01191   {
01192     FacetCoEdge *curr_coedge = facet_coedges.get_and_step();
01193     Curve *curve_sm;
01194     curve_sm = curr_coedge->curve();
01195 
01196     FacetCurve *temp_curve = NULL;
01197     temp_curve = CAST_TO( curve_sm, FacetCurve );
01198 
01199     int data_to_write[2];
01200 
01201     // get implicit id of this curve
01202     int found;
01203     found = facet_curves.where_is_item( temp_curve );
01204     if( found == -1)
01205       PRINT_ERROR("Problem saving Facet CoEdges\n");
01206     data_to_write[0] = found;
01207 
01208     // convert sense info to integer
01209     if( curr_coedge->get_sense() == CUBIT_UNKNOWN )
01210       data_to_write[1] = -1;
01211     else
01212       data_to_write[1] = (curr_coedge->get_sense() == CUBIT_REVERSED) ? 1 : 0;
01213 
01214     // write out the data
01215     file_writer.Write( reinterpret_cast<UnsignedInt32*>(data_to_write), 2 );
01216 
01217   }
01218 
01219   //-----------------write FacetLoops--------------
01220   size = facet_loops.size();
01221   // write out number of FacetLoops
01222   file_writer.Write( &size, 1 );
01223   facet_loops.reset();
01224   for( i=0; i<facet_loops.size(); i++)
01225   {
01226     FacetLoop *curr_loop = facet_loops.get_and_step();
01227     DLIList<FacetCoEdge*> coedge_list;
01228     curr_loop->get_coedges( coedge_list );
01229 
01230     // get number of coedges in this loop
01231     UnsignedInt32 *data_to_write;
01232     size = coedge_list.size();
01233     data_to_write = new UnsignedInt32[ size + 1 ];
01234     data_to_write[0] = size;
01235 
01236     UnsignedInt32 j;
01237     // get implicit ids of coedges
01238     coedge_list.reset();
01239     for( j=1; j<size+1; j++)
01240     {
01241       FacetCoEdge *temp_coedge = coedge_list.get_and_step();
01242       int found;
01243       found = facet_coedges.where_is_item( temp_coedge );
01244       if( found == -1)
01245         PRINT_ERROR("Problem saving Facet Loops\n");
01246       data_to_write[j] = found;
01247     }
01248 
01249     // write out the data
01250     file_writer.Write( data_to_write, size + 1);
01251     delete [] data_to_write;
01252   }
01253 
01254   //-----------------write FacetSurfaces--------------
01255   size = facet_surfaces.size();
01256   // write out number of FacetSurfaces
01257   file_writer.Write( &size, 1 );
01258   facet_surfaces.reset();
01259   for( i=0; i<facet_surfaces.size(); i++)
01260   {
01261     FacetSurface *curr_surface = facet_surfaces.get_and_step();
01262 
01263     DLIList<FacetLoop*> loop_list;
01264     curr_surface->get_loops( loop_list );
01265 
01266     int num_loops = loop_list.size();
01267     int data_to_write[6];
01268 
01269     // convert sense info to integer
01270     // if( curr_surface->get_relative_surface_sense() == CUBIT_UNKNOWN )
01271 //       data_to_write[0] = -1;
01272 //     else
01273 //       data_to_write[0] = (curr_surface->get_relative_surface_sense() == CUBIT_REVERSED) ? 1 : 0;
01274     data_to_write[0]=0;
01275     // get "useFacets"
01276     data_to_write[1] = 1;
01277 
01278     // get output id of FacetEvalTool
01279     data_to_write[2] = curr_surface->get_eval_tool()->get_output_id();
01280 
01281     // get Shell Sense stuff
01282     CubitSense sense0;
01283     
01284     curr_surface->get_shell_sense( sense0 );
01285     if( sense0 == CUBIT_UNKNOWN )
01286       data_to_write[3] = -1;
01287     else
01288       data_to_write[3] = (sense0 == CUBIT_REVERSED) ? 1 : 0;
01289 
01290 //    if( sense1 == CUBIT_UNKNOWN )
01291       data_to_write[4] = -1;
01292 //    else
01293 //      data_to_write[4] = (sense1 == CUBIT_REVERSED) ? 1 : 0;
01294 
01295     // get number of loops
01296     data_to_write[5] = num_loops;
01297 
01298     file_writer.Write( reinterpret_cast<UnsignedInt32*>(data_to_write), 6 );
01299 
01300     // get implicit ids of loops
01301     if( num_loops > 0 )
01302     {
01303       int *loop_ids = new int[num_loops];
01304       int j;
01305       loop_list.reset();
01306       for( j=0; j<num_loops; j++)
01307       {
01308        FacetLoop *temp_loop = loop_list.get_and_step();
01309        int found;
01310        found = facet_loops.where_is_item( temp_loop );
01311        if( found == -1 )
01312          PRINT_ERROR("Problem saving Facet Surfaces\n");
01313        loop_ids[j] = found;
01314       }
01315 
01316       // write out data
01317       file_writer.Write( reinterpret_cast<UnsignedInt32*>(loop_ids), num_loops );
01318       delete [] loop_ids;
01319     }
01320 
01321     if( curr_surface->save_attribs(file_ptr) == CUBIT_FAILURE )
01322       return CUBIT_FAILURE;
01323   }
01324 
01325   //-----------------write FacetShells--------------
01326   size = facet_shells.size();
01327   // write out number of FacetShells
01328   file_writer.Write( &size, 1 );
01329   facet_shells.reset();
01330   for( i=0; i<facet_shells.size(); i++)
01331   {
01332     FacetShell *curr_shell= facet_shells.get_and_step(); //number of surfaces
01333     DLIList<FacetSurface*> temp_facet_surf_list;
01334     curr_shell->get_surfaces( temp_facet_surf_list );
01335 
01336     // get number of surfaces in this shell
01337     UnsignedInt32 *data_to_write;
01338     int num_surfs = temp_facet_surf_list.size();
01339     data_to_write = new UnsignedInt32[ num_surfs + 1];
01340     data_to_write[0] = num_surfs;
01341 
01342     // get implicit ids of surfaces
01343     int j;
01344     temp_facet_surf_list.reset();
01345     for( j=1; j<num_surfs+1; j++)
01346     {
01347       FacetSurface *temp_facet_surface = temp_facet_surf_list.get_and_step();
01348       int found;
01349       found = facet_surfaces.where_is_item( temp_facet_surface );
01350       if( found == -1 )
01351         PRINT_ERROR("Problem saving Facet Shells\n");
01352       data_to_write[j] = found;
01353     }
01354 
01355     // write the data
01356     file_writer.Write( data_to_write, num_surfs + 1 );
01357     delete [] data_to_write;
01358   }
01359 
01360   //-----------------write FacetLumps--------------
01361   size = facet_lumps.size();
01362   // write out number of FacetLumps
01363   file_writer.Write( &size, 1 );
01364   facet_lumps.reset();
01365   for( i=0; i<facet_lumps.size(); i++)
01366   {
01367     FacetLump *curr_lump = facet_lumps.get_and_step();
01368 
01369     DLIList<FacetShell*> temp_facet_shell_list;
01370     curr_lump->get_shells( temp_facet_shell_list );
01371 
01372     // get number of shells in this lump
01373     UnsignedInt32 *data_to_write;
01374     int num_shells= temp_facet_shell_list.size();
01375     data_to_write = new UnsignedInt32[ num_shells+ 1];
01376     data_to_write[0] = num_shells;
01377 
01378     //get implicit ides of the lumps in this shell
01379     int j;
01380     temp_facet_shell_list.reset();
01381     for( j=1; j<num_shells+1; j++)
01382     {
01383       FacetShell *temp_facet_shell = temp_facet_shell_list.get_and_step();
01384       int found;
01385       found = facet_shells.where_is_item( temp_facet_shell );
01386       if( found == -1 )
01387         PRINT_ERROR("Problem saving Facet Lumps\n");
01388       data_to_write[j] = found;
01389     }
01390 
01391     //write the data
01392     file_writer.Write( data_to_write, num_shells + 1 );
01393     delete [] data_to_write;
01394     if( curr_lump->save_attribs(file_ptr) == CUBIT_FAILURE )
01395       return CUBIT_FAILURE;
01396   }
01397 
01398   //-----------------write FacetBodies--------------
01399   size = facet_bodies.size();
01400   // write out number of FacetBodies
01401   file_writer.Write( &size, 1 );
01402   facet_bodies.reset();
01403   for( i=0; i<facet_bodies.size(); i++)
01404   {
01405     FacetBody *curr_body = facet_bodies.get_and_step();
01406 
01407     DLIList<FacetLump*> temp_facet_lump_list;
01408     curr_body->get_lumps( temp_facet_lump_list );
01409 
01410     // get the number of lumps in this body
01411     UnsignedInt32 *data_to_write;
01412     int num_lumps = temp_facet_lump_list.size();
01413     data_to_write = new UnsignedInt32[ num_lumps + 1];
01414     data_to_write[0] = num_lumps;
01415 
01416     // get the implicit ids of the lumps in this body
01417     int j;
01418     temp_facet_lump_list.reset();
01419     for( j=1; j<num_lumps+1; j++)
01420     {
01421       FacetLump *temp_facet_lump = temp_facet_lump_list.get_and_step();
01422       int found;
01423       found = facet_lumps.where_is_item( temp_facet_lump );
01424       if( found == -1 )
01425         PRINT_ERROR("Problem saving Facet Bodies\n");
01426       data_to_write[j] = found;
01427     }
01428 
01429     // write the data
01430     file_writer.Write( data_to_write, num_lumps + 1 );
01431     delete [] data_to_write;
01432 
01433     // write the transformation matrix of this body
01434     CubitTransformMatrix trans_matrix;
01435     curr_body->get_transforms( trans_matrix );
01436 
01437     UnsignedInt32 num_rows  = trans_matrix.num_rows();
01438     UnsignedInt32 num_cols  = trans_matrix.num_cols();
01439     UnsignedInt32 rows_and_cols[2];
01440     rows_and_cols[0] = num_rows;
01441     rows_and_cols[1] = num_cols;
01442 
01443     file_writer.Write( rows_and_cols, 2 );
01444 
01445     double *trans_matrix_array;
01446     trans_matrix_array = new double[ num_rows*num_cols ];
01447 
01448     //fill up the array row-by-row
01449     unsigned u, k = 0;
01450     for(u=0; u<num_rows; u++)
01451     {
01452       for(k=0; k<num_cols; k++)
01453         trans_matrix_array[(u*num_cols)+k] = trans_matrix.get(u,k);
01454     }
01455 
01456     file_writer.Write( trans_matrix_array, u*k );
01457     delete [] trans_matrix_array;
01458     if( curr_body->save_attribs(file_ptr) == CUBIT_FAILURE )
01459       return CUBIT_FAILURE;
01460   }
01461 
01462   return CUBIT_SUCCESS;
01463 }
01464 
01465 
01466 CubitStatus
01467 FacetQueryEngine::restore_topology( FILE *file_ptr,
01468                                     unsigned int endian,
01469                                     int num_points,
01470                                     CubitPoint **points_array,
01471                                     int num_cfet,
01472                                     CurveFacetEvalTool** cfev_array,
01473                                     int num_fet,
01474                                     FacetEvalTool** fev_array,
01475                                     DLIList<TopologyBridge*> &imported_entities )
01476 {
01477 
01478   //get file pointer
01479   unsigned int size;
01480   unsigned int i, j;
01481   int id, k;
01482 
01483   FacetPoint **facet_points;
01484   FacetCurve **facet_curves;
01485   FacetCoEdge **facet_coedges;
01486   FacetLoop **facet_loops;
01487   FacetSurface **facet_surfaces;
01488   FacetShell **facet_shells;
01489   FacetLump **facet_lumps;
01490   FacetBody **facet_bodies;
01491 
01492   FacetPoint *tmp_point;
01493   FacetCurve *tmp_curve;
01494   FacetCoEdge *tmp_coedge;
01495   FacetLoop *tmp_loop;
01496   FacetSurface *tmp_surf;
01497   FacetShell *tmp_shell;
01498   FacetLump *tmp_lump;
01499   FacetBody*tmp_body;
01500 
01501   int num_facet_points = 0;
01502   int num_facet_curves = 0;
01503   int num_facet_coedges = 0;
01504   int num_facet_loops = 0;
01505   int num_facet_surfaces = 0;
01506   int num_facet_shells = 0;
01507   int num_facet_lumps = 0;
01508   int num_facet_bodies = 0;
01509 
01510   //create a wrapper object for writing
01511   CIOWrapper file_reader( endian, file_ptr );
01512 
01513   //-----------------Read FacetPoints------------------
01514   // Read number of FacetPoints
01515   file_reader.Read( &size, 1 );
01516   // Allocate memory for FacetPoints
01517   facet_points = new FacetPoint*[size];
01518   for(i=0; i<size; i++)
01519   {
01520     file_reader.Read( reinterpret_cast<UnsignedInt32*>(&id), 1 );
01521     if( id >= num_points || id < 0 )
01522     {
01523       delete [] facet_points;
01524       return CUBIT_FAILURE;
01525     }
01526 
01527     tmp_point = new FacetPoint( points_array[ id ] );
01528     if( tmp_point == NULL )
01529       return CUBIT_FAILURE;
01530 
01531     num_facet_points++;
01532     facet_points[i] = tmp_point;
01533     tmp_point->restore_attribs( file_ptr, endian );
01534   }
01535 
01536   //-----------------Read FacetCurves------------------
01537   //Read number of FacetCurves
01538   file_reader.Read( &size, 1 );
01539   // Allocate memory for FacetCurves
01540   facet_curves = new FacetCurve*[size];
01541   for(i=0; i<size; i++)
01542   {
01543     int data[4];
01544     file_reader.Read( reinterpret_cast<UnsignedInt32*>(data), 4 );
01545     if( data[0] >= num_facet_points || data[0] < 0 ||
01546         data[1] >= num_facet_points || data[1] < 0 ||
01547         data[3] >= num_cfet ||  data[3] < 0 )
01548     {
01549       delete [] facet_curves;
01550       return CUBIT_FAILURE;
01551     }
01552 
01553     CubitSense sense;
01554     if (data[2] == -1 )
01555       sense = CUBIT_UNKNOWN;
01556     else
01557       sense = data[2] ? CUBIT_REVERSED : CUBIT_FORWARD;
01558 
01559     tmp_curve = new FacetCurve( cfev_array[ data[3] ], facet_points[ data[0] ],
01560                                 facet_points[ data[1] ], sense );
01561     if( tmp_curve == NULL )
01562       return CUBIT_FAILURE;
01563 
01564     // Add curve to FacetPoints
01565     facet_points[data[0]]->add_curve( tmp_curve );
01566     facet_points[data[1]]->add_curve( tmp_curve );
01567 
01568     num_facet_curves++;
01569     facet_curves[i] = tmp_curve;
01570     tmp_curve->restore_attribs( file_ptr, endian );
01571   }
01572 
01573   //-----------------Read FacetCoEdges------------------
01574   //Read number of FacetCoEdges
01575   file_reader.Read( &size, 1 );
01576   facet_coedges = new FacetCoEdge*[ size ];
01577   for(i=0; i<size; i++)
01578   {
01579     int data[2];
01580     file_reader.Read( reinterpret_cast<unsigned int*>(data), 2 );
01581 
01582     if( data[0] >= num_facet_curves || data[0] < 0 )
01583     {
01584       delete [] facet_coedges;
01585       return CUBIT_FAILURE;
01586     }
01587 
01588     CubitSense sense;
01589     if (data[1] == -1 )
01590       sense = CUBIT_UNKNOWN;
01591     else
01592       sense = data[1] ? CUBIT_REVERSED : CUBIT_FORWARD;
01593 
01594     tmp_coedge =  new FacetCoEdge( facet_curves[ data[0] ], sense );
01595     if( tmp_coedge == NULL )
01596       return CUBIT_FAILURE;
01597 
01598     facet_coedges[i] = tmp_coedge;
01599     num_facet_coedges++;
01600 
01601     // Add FacetCoEdge to FacetCurve
01602     facet_curves[ data[0] ]->add_coedge( tmp_coedge );
01603   }
01604 
01605   //-----------------Read FacetLoops------------------
01606   //Read number of FacetLoops
01607   file_reader.Read( &size, 1 );
01608   DLIList<CoEdgeSM*> temp_coedge_list;
01609   facet_loops = new FacetLoop*[ size ];
01610   for(i=0; i<size; i++)
01611   {
01612     temp_coedge_list.clean_out();
01613 
01614     unsigned int num_coedges = 0;
01615     file_reader.Read( &num_coedges, 1);
01616 
01617     int* coedge_ids = new int[ num_coedges];
01618     file_reader.Read( (unsigned*)coedge_ids, num_coedges );
01619 
01620     for( j=0; j<num_coedges; j++)
01621     {
01622       if( coedge_ids[j] >= num_facet_coedges || coedge_ids[j] < 0 )
01623       {
01624         delete [] facet_loops;
01625         return CUBIT_FAILURE;
01626       }
01627       temp_coedge_list.append( facet_coedges[ coedge_ids[j] ] );
01628     }
01629 
01630     tmp_loop = new FacetLoop( temp_coedge_list );
01631     if( tmp_loop == NULL)
01632       return CUBIT_FAILURE;
01633 
01634     num_facet_loops++;
01635     facet_loops[i] = tmp_loop;
01636 
01637     for( j=0; j<num_coedges; j++)
01638       facet_coedges[ coedge_ids[j] ]->add_loop( tmp_loop );
01639 
01640     delete [] coedge_ids;
01641   }
01642 
01643   //-----------------Read FacetSurfaces------------------
01644   //Read number of FacetSurfaces
01645   file_reader.Read( &size, 1 );
01646   facet_surfaces = new FacetSurface*[size];
01647   DLIList<LoopSM*> temp_loops;
01648   for(i=0; i<size; i++)
01649   {
01650     temp_loops.clean_out();
01651     int data[6];
01652     file_reader.Read( (unsigned int*)data, 6);
01653 
01654     CubitSense sense, sense0;
01655     if (data[0] == -1 )
01656       sense = CUBIT_UNKNOWN;
01657     else
01658       sense = data[0] ? CUBIT_REVERSED : CUBIT_FORWARD;
01659 
01660     CubitBoolean useFacets;
01661     useFacets = data[1] ? CUBIT_TRUE : CUBIT_FALSE;
01662 
01663     // make sure FacetEvalTool ID is in range
01664     if( data[2] >= num_fet || data[2] < 0 )
01665     {
01666       delete [] facet_surfaces;
01667       return CUBIT_FAILURE;
01668     }
01669 
01670     if (data[3] == -1 )
01671       sense0 = CUBIT_UNKNOWN;
01672     else
01673       sense0 = data[3] ? CUBIT_REVERSED : CUBIT_FORWARD;
01674 
01675     int num_loops = data[5];
01676     int* loop_ids = new int[ num_loops ];
01677     file_reader.Read( (unsigned*)loop_ids, num_loops );
01678 
01679     for( k=0; k<num_loops; k++)
01680     {
01681       if( loop_ids[k] >= num_facet_loops ||
01682           loop_ids[k] < 0 )
01683       {
01684         delete [] loop_ids;
01685         return CUBIT_FAILURE;
01686       }
01687       temp_loops.append( facet_loops[ loop_ids[k] ] );
01688     }
01689     tmp_surf = new FacetSurface( fev_array[ data[2] ],
01690                                  sense, sense0,
01691                                  useFacets, temp_loops );
01692     if( tmp_surf == NULL)
01693       return CUBIT_FAILURE;
01694 
01695     facet_surfaces[i] = tmp_surf;
01696     num_facet_surfaces++;
01697 
01698     // Add FacetSurface to FacetLoops
01699     for( k=0; k<num_loops; k++)
01700       facet_loops[ loop_ids[k] ]->add_surface( tmp_surf );
01701 
01702     delete [] loop_ids;
01703     tmp_surf->restore_attribs( file_ptr, endian );
01704   }
01705 
01706   //-----------------Read FacetShells------------------
01707   //Read number of FacetShells
01708   file_reader.Read( &size, 1 );
01709   facet_shells = new FacetShell*[size];
01710   DLIList<Surface*> temp_surfs;
01711   for(i=0; i<size; i++)
01712   {
01713     temp_surfs.clean_out();
01714     unsigned int num_surfs = 0;
01715     file_reader.Read( &num_surfs, 1 );
01716 
01717     int* surface_ids = new int[ num_surfs ];
01718     file_reader.Read( (unsigned*)surface_ids, num_surfs );
01719 
01720     for( j=0; j<num_surfs; j++)
01721     {
01722       if( surface_ids[j] >= num_facet_surfaces ||
01723           surface_ids[j] < 0 )
01724       {
01725         delete [] facet_shells;
01726         return CUBIT_FAILURE;
01727       }
01728 
01729       temp_surfs.append( facet_surfaces[ surface_ids[j] ] );
01730     }
01731 
01732     tmp_shell = new FacetShell( temp_surfs );
01733     facet_shells[i] = tmp_shell;
01734     num_facet_shells++;
01735 
01736     // Add this shell to surfaces
01737     for( j=0; j<num_surfs; j++)
01738       facet_surfaces[ surface_ids[j] ]->add_shell( tmp_shell );
01739 
01740     delete [] surface_ids;
01741   }
01742 
01743   //-----------------Read FacetLumps------------------
01744   //Read number of FacetLumps
01745   file_reader.Read( &size, 1 );
01746   facet_lumps = new FacetLump*[size];
01747   DLIList<ShellSM*> temp_shells;
01748   for(i=0; i<size; i++)
01749   {
01750     temp_shells.clean_out();
01751 
01752     unsigned int num_shells = 0;
01753     file_reader.Read( &num_shells, 1 );
01754 
01755     int* shell_ids = new int[ num_shells ];
01756     file_reader.Read( (unsigned*)shell_ids, num_shells );
01757 
01758     for( j=0; j<num_shells; j++)
01759     {
01760       if( shell_ids[j] >= num_facet_shells )
01761       {
01762         delete [] facet_lumps;
01763         return CUBIT_FAILURE;
01764       }
01765       temp_shells.append( facet_shells[ shell_ids[j] ] );
01766     }
01767 
01768     tmp_lump = new FacetLump( temp_shells );
01769     if( tmp_lump == NULL )
01770       return CUBIT_FAILURE;
01771 
01772     facet_lumps[i] = tmp_lump;
01773     num_facet_lumps++;
01774 
01775     for( j=0; j<num_shells; j++)
01776       facet_shells[ shell_ids[j] ]->add_lump( tmp_lump );
01777 
01778     delete [] shell_ids;
01779     tmp_lump->restore_attribs( file_ptr, endian );
01780   }
01781 
01782   //-----------------Read FacetBodies ------------------
01783   //Read number of FacetBodies
01784   file_reader.Read( &size, 1 );
01785   facet_bodies = new FacetBody*[size];
01786   DLIList<Lump*> temp_lumps;
01787   for(i=0; i<size; i++)
01788   {
01789     temp_lumps.clean_out();
01790 
01791     unsigned int num_lumps= 0;
01792     file_reader.Read( &num_lumps, 1 );
01793 
01794     int* lump_ids = new int[ num_lumps ];
01795     file_reader.Read( (unsigned*)lump_ids, num_lumps );
01796 
01797     for( j=0; j<num_lumps; j++)
01798     {
01799       if( lump_ids[j] >= num_facet_lumps )
01800       {
01801         delete [] facet_bodies;
01802         return CUBIT_FAILURE;
01803       }
01804       temp_lumps.append( facet_lumps[ lump_ids[j] ] );
01805     }
01806 
01807     tmp_body = new FacetBody( temp_lumps );
01808     if( tmp_body == NULL )
01809       return CUBIT_FAILURE;
01810 
01811     facet_bodies[i] = tmp_body;
01812     num_facet_bodies++;
01813 
01814     // Add this FacetBody to FacetLumps
01815     for( j=0; j<num_lumps; j++)
01816       facet_lumps[ lump_ids[j] ]->add_body( tmp_body );
01817 
01818     delete [] lump_ids;
01819 
01820     //read in trans matrix
01821     unsigned int rows_and_cols[2];
01822     file_reader.Read( rows_and_cols, 2 );
01823 
01824     unsigned int num_rows = rows_and_cols[0];
01825     unsigned int num_cols = rows_and_cols[1];
01826 
01827     if( num_rows || num_cols)
01828     {
01829       CubitTransformMatrix trans_matrix;
01830 
01831       double *trans_matrix_array;
01832       trans_matrix_array = new double[ num_rows*num_cols ];
01833       file_reader.Read( trans_matrix_array, num_rows*num_cols );
01834 
01835       unsigned c;
01836       for(j=0; j<num_rows; j++ )
01837       {
01838         for(c=0; c<num_cols; c++)
01839           trans_matrix.add(j,c, trans_matrix_array[(j*num_cols)+c] );
01840       }
01841       tmp_body->set_transforms( trans_matrix );
01842       delete [] trans_matrix_array;
01843     }
01844     tmp_body->restore_attribs( file_ptr, endian );
01845   }
01846 
01847   // Here is where we determine if the entites are free or not
01848   // bodies, all bodies are free
01849   for(k=0; k<num_facet_bodies; k++)
01850     imported_entities.append( facet_bodies[k] );
01851 
01852   // surfaces are free if they are not in a shell
01853   DLIList<FacetShell*> shell_list;
01854   for(k=0; k<num_facet_surfaces; k++)
01855   {
01856     shell_list.clean_out();
01857     facet_surfaces[k]->get_shells( shell_list );
01858     if( shell_list.size() == 0 )
01859       imported_entities.append( facet_surfaces[k] );
01860   }
01861 
01862   // curves are free if they are not associate with a coedge
01863   DLIList<FacetCoEdge*> coedge_list;
01864   for(k=0; k<num_facet_curves; k++)
01865   {
01866     coedge_list.clean_out();
01867     facet_curves[k]->get_coedges( coedge_list );
01868     if( coedge_list.size() == 0 )
01869       imported_entities.append( facet_curves[k] );
01870   }
01871 
01872   // points are free if they are not associate with a curve
01873   DLIList<FacetCurve*> curve_list;
01874   for(k=0; k<num_facet_points; k++)
01875   {
01876     curve_list.clean_out();
01877     facet_points[k]->get_curves( curve_list );
01878     if( curve_list.size() == 0 )
01879       imported_entities.append( facet_points[k] );
01880   }
01881 
01882   // clean up
01883   delete [] facet_points;
01884   delete [] facet_curves;
01885   delete [] facet_coedges;
01886   delete [] facet_loops;
01887   delete [] facet_surfaces;
01888   delete [] facet_shells;
01889   delete [] facet_lumps;
01890   delete [] facet_bodies;
01891 
01892   return CUBIT_SUCCESS;
01893 }
01894 
01895 CubitStatus FacetQueryEngine::import_solid_model( const char* file_name ,
01896                                                   Model_File_Type file_type,
01897                                                   DLIList<TopologyBridge*> &imported_entities,
01898                                                   ModelImportOptions &import_options ) 
01899 {
01900   errno = 0;
01901   FILE *file_ptr = fopen(file_name, "rb");
01902   if (!file_ptr)
01903   {
01904     PRINT_ERROR("Cannot open file: %s (%s)\n", file_name, strerror(errno) );
01905     return CUBIT_FAILURE;
01906   }
01907 
01908   CubitStatus status = import_solid_model(file_ptr, imported_entities );
01909   
01910   fclose(file_ptr);
01911   return status;
01912 }
01913 
01914 CubitStatus FacetQueryEngine::import_solid_model(FILE *file_ptr,
01915                                                  DLIList<TopologyBridge*> &imported_entities )
01916 
01917 {
01918   CubitPoint **points_array = NULL;
01919   CurveFacetEvalTool **cfet_array = NULL;
01920   FacetEvalTool **fet_array = NULL;
01921 
01922   int num_points, num_edges, num_facets;
01923   int num_cfet, num_fet;
01924 
01925   // read in the file type "MESHED_BASED_GEOMETRY"
01926   char fileType[19] = {0};
01927 
01928   if( fread( fileType, 1, 19, file_ptr) != 19 )
01929   {
01930     PRINT_ERROR("Trouble reading in file type for MBG\n");
01931     return CUBIT_FAILURE;
01932   }
01933 
01934   if( strncmp( fileType, "MESH_BASED_GEOMETRY", 19 ) )
01935   {
01936     PRINT_ERROR("Not MESH_BASED_GEOMETRY file type\n");
01937     return CUBIT_FAILURE;
01938   }
01939 
01940   // read in the endian value
01941   NCubitFile::CIOWrapper file_reader(file_ptr, 19, 0);
01942 
01943   // read in version #
01944   UnsignedInt32 version;
01945   file_reader.Read( &version, 1 );
01946 
01947   //Read in points/edges/facets
01948   CubitStatus status;
01949   status = restore_facets( file_ptr, file_reader.get_endian(),
01950                            num_points, num_edges,
01951                            num_facets, points_array, num_cfet,
01952                            num_fet, cfet_array, fet_array );
01953   if( status == CUBIT_FAILURE)
01954   {
01955     PRINT_ERROR("Problems restore facets\n");
01956     return CUBIT_FAILURE;
01957   }
01958 
01959   //Restore Topology
01960   status = restore_topology( file_ptr, file_reader.get_endian(),
01961                              num_points, points_array,
01962                              num_cfet, cfet_array, num_fet,
01963                              fet_array, imported_entities);
01964   if( status == CUBIT_FAILURE)
01965   {
01966     PRINT_ERROR("Problems restore MDB topology\n");
01967     return CUBIT_FAILURE;
01968   }
01969 
01970 
01971   if(cfet_array != NULL)
01972     delete [] cfet_array;
01973   if(fet_array != NULL)
01974     delete [] fet_array;
01975   if(points_array != NULL)
01976     delete [] points_array;
01977 
01978   return CUBIT_SUCCESS;
01979 }
01980 
01981 
01982 //===============================================================================
01983 // Function   : restore_facets
01984 // Member Type: PUBLIC
01985 // Description: restore facets and eval tools onto the list of entities
01986 // Author     : sjowen
01987 // Date       : 1/26/03
01988 //===============================================================================
01989 CubitStatus FacetQueryEngine::restore_facets(
01990   FILE *fp,  // CUB file we are currently reading
01991   unsigned int endian,
01992   int &num_points,
01993   int &num_edges,
01994   int &num_facets,
01995   CubitPoint **&points,
01996   int &num_cfet,
01997   int &num_fet,
01998   CurveFacetEvalTool **&cfet_array,
01999   FacetEvalTool **&fet_array)
02000 {
02001   CubitStatus rv = CUBIT_SUCCESS;
02002 
02003   CubitFacet **facets = NULL;
02004   CubitFacetEdge **edges = NULL;
02005 
02006   // read facets from the file and build arrays of facet entities
02007 
02008   rv = read_facets( fp, endian,
02009                     num_facets, num_edges, num_points,
02010                     facets,     edges,   points );
02011 
02012   // create the CurveFacetEvalTools and FacetEval Tools
02013 
02014   if (rv != CUBIT_FAILURE )
02015   {
02016     rv = restore_eval_tools( fp, endian,
02017                              num_facets, num_edges, num_points,
02018                              facets,     edges,  points,
02019                              num_cfet, num_fet,
02020                              cfet_array, fet_array );
02021   }
02022 
02023   if (facets != NULL)
02024     delete [] facets;
02025   if(edges != NULL)
02026     delete [] edges;
02027   return rv;
02028 
02029 }
02030 
02031 
02032 //===============================================================================
02033 // Function   : read_facets
02034 // Member Type: PUBLIC
02035 // Description: read facets from the file and create facet entities
02036 // Author     : sjowen
02037 // Date       : 1/26/03
02038 //===============================================================================
02039 CubitStatus FacetQueryEngine::read_facets(
02040   FILE *fp,
02041   unsigned int endian,
02042   int &num_facets,
02043   int &num_edges,
02044   int &num_points,
02045   CubitFacet **&facets,
02046   CubitFacetEdge **&edges,
02047   CubitPoint **&points )
02048 {
02049 
02050   NCubitFile::CIOWrapper cio(endian, fp );
02051   int ii;
02052 
02053   // read points
02054   UnsignedInt32 npoints;
02055   double uu,vv,ss;
02056   cio.Read(&npoints, 1);
02057   num_points = (int)npoints;
02058   if (num_points > 0)
02059   {
02060     double* coord_array  = new double [num_points * 3];
02061     double* uvs_array = new double [num_points * 3];
02062     cio.Read(coord_array, npoints*3);
02063     cio.Read(uvs_array, npoints*3);
02064 
02065     // create CubitPoints
02066     CubitPoint *point_ptr;
02067     //CubitVector normal;
02068     points = new CubitPoint * [num_points];
02069     for(ii=0; ii<num_points; ii++)
02070     {
02071       point_ptr = (CubitPoint *) new CubitPointData( coord_array[ii*3],
02072                                                      coord_array[ii*3+1],
02073                                                      coord_array[ii*3+2] );
02074       points[ii] = point_ptr;
02075       uu = uvs_array[ii*3];
02076       vv = uvs_array[ii*3+1];
02077       ss = uvs_array[ii*3+2];
02078       point_ptr->set_uvs(uu, vv, ss);
02079     }
02080 
02081     //Clean up
02082     delete [] coord_array;
02083     delete [] uvs_array;
02084   }
02085 
02086 
02087   //Read in Normals
02088   int nnormals;
02089   cio.Read(reinterpret_cast<UnsignedInt32*>(&nnormals), 1);
02090   if( nnormals > 0 )
02091   {
02092     double* normal_array = new double [nnormals * 3];
02093     int* normal_ids = new int[nnormals * 3];
02094     cio.Read(normal_array, nnormals * 3);
02095     cio.Read(reinterpret_cast<UnsignedInt32*>(normal_ids), nnormals);
02096     CubitVector normal;
02097     for(ii=0; ii<nnormals; ii++)
02098     {
02099       normal.x( normal_array[ii*3] );
02100       normal.y( normal_array[ii*3+1] );
02101       normal.z( normal_array[ii*3+2] );
02102       points[ normal_ids[ii] ]->normal( normal );
02103     }
02104 
02105     //Clean up
02106     delete [] normal_array;
02107     delete [] normal_ids;
02108   }
02109 
02110 
02111   // read edges and edge control points
02112 
02113   UnsignedInt32 nedges;
02114   cio.Read(&nedges, 1);
02115   num_edges = (int)nedges;
02116   if (num_edges > 0)
02117   {
02118     UnsignedInt32 *edge_vert_array = new UnsignedInt32 [nedges*2];
02119     cio.Read(edge_vert_array, nedges*2);
02120     UnsignedInt32 nctrl_pts;
02121     cio.Read(&nctrl_pts, 1);
02122     double *control_points = NULL;
02123     if (nctrl_pts > 0)
02124     {
02125       control_points = new double [nctrl_pts*3];
02126       cio.Read(control_points, nctrl_pts*3);
02127     }
02128 
02129     unsigned id0, id1, ii;
02130     edges = new CubitFacetEdge * [num_edges];
02131     CubitFacetEdge *edge_ptr;
02132     for(ii=0; ii<nedges; ii++)
02133     {
02134       id0 = edge_vert_array[ii*2];
02135       id1 = edge_vert_array[ii*2+1];
02136 
02137       edge_ptr = (CubitFacetEdge *) new CubitFacetEdgeData( points[id0], points[id1] );
02138       edges[ii] = edge_ptr;
02139       if (nctrl_pts > 0)
02140       {
02141         edge_ptr->set_control_points(&control_points[ii*NUM_EDGE_CPTS*3]);
02142       }
02143     }
02144 
02145     //Clean up
02146     delete [] edge_vert_array;
02147     delete [] control_points;
02148     edge_vert_array = NULL;
02149     control_points = NULL;
02150   }
02151 
02152   // read the facets and the facet control points
02153 
02154   UnsignedInt32 nfacets;
02155   cio.Read(&nfacets, 1);
02156   num_facets = (int)nfacets;
02157   if(num_facets > 0)
02158   {
02159     UnsignedInt32 *facet_edge_array = new UnsignedInt32 [nfacets*3];
02160     cio.Read(facet_edge_array, nfacets*3);
02161     int *int_data = new int [nfacets*2];
02162     cio.Read(reinterpret_cast<UnsignedInt32*>(int_data), nfacets*2);
02163 
02164     UnsignedInt32 nctrl_pts;
02165     cio.Read(&nctrl_pts, 1);
02166     double *control_points = NULL;
02167     if (nctrl_pts > 0)
02168     {
02169       control_points = new double [nctrl_pts*3];
02170       cio.Read(control_points, nctrl_pts*3);
02171     }
02172 
02173     unsigned id0, id1, id2, ii;
02174     CubitFacet *facet_ptr;
02175     facets = new CubitFacet * [num_facets];
02176     for (ii=0; ii<nfacets; ii++)
02177     {
02178       id0 = facet_edge_array[ii*3];
02179       id1 = facet_edge_array[ii*3+1];
02180       id2 = facet_edge_array[ii*3+2];
02181       facet_ptr = (CubitFacet *) new CubitFacetData(edges[id0], edges[id1], edges[id2]);
02182       facets[ii] = facet_ptr;
02183       facet_ptr->is_flat( int_data[ii*2] );
02184       facet_ptr->is_backwards( int_data[ii*2+1] );
02185 
02186       if(nctrl_pts > 0)
02187       {
02188         facet_ptr->set_control_points(&control_points[ii*NUM_TRI_CPTS*3]);
02189       }
02190     }
02191 
02192     //Clean up
02193     delete [] facet_edge_array;
02194     delete [] control_points;
02195     delete [] int_data;
02196     facet_edge_array = NULL;
02197     control_points = NULL;
02198     int_data = NULL;
02199   }
02200 
02201   // read the extra info at the surface boundaries
02202 
02203   UnsignedInt32 num_c_zero_points = 0;
02204   cio.Read(&num_c_zero_points, 1);
02205   if (num_c_zero_points > 0)
02206   {
02207     UnsignedInt32 c_zero_int_data_size;
02208 
02209     cio.Read(&c_zero_int_data_size, 1);
02210     if (c_zero_int_data_size <= 0)
02211       return CUBIT_FAILURE;
02212     UnsignedInt32 *c_zero_int32_data = new UnsignedInt32 [c_zero_int_data_size];
02213     cio.Read(c_zero_int32_data, c_zero_int_data_size);
02214     int *c_zero_int_data = new int [c_zero_int_data_size];
02215     unsigned int jj;
02216     for (jj=0; jj<c_zero_int_data_size; jj++)
02217       c_zero_int_data[jj] = (int) c_zero_int32_data[jj];
02218 
02219     UnsignedInt32 c_zero_double_data_size;
02220 
02221     cio.Read(&c_zero_double_data_size, 1);
02222     if (c_zero_double_data_size <= 0) {
02223       delete [] c_zero_int_data;
02224       delete [] c_zero_int32_data;
02225       return CUBIT_FAILURE;
02226     }
02227     double *c_zero_double_data = new double [c_zero_double_data_size];
02228     cio.Read(c_zero_double_data, c_zero_double_data_size);
02229 
02230     // create the facet boundary tool datas and assign to points
02231 
02232     int didx = 0;
02233     int iidx = 0;
02234     UnsignedInt32 zz;
02235     for (zz=0; zz<num_c_zero_points; zz++)
02236     {
02237       if (didx >= (int)c_zero_double_data_size ||
02238           iidx >= (int)c_zero_int_data_size)
02239         return CUBIT_FAILURE;
02240       TDFacetBoundaryPoint::new_facet_boundary_point( points, facets,
02241         iidx, didx, c_zero_int_data, c_zero_double_data );
02242     }
02243 
02244     //Clean up
02245     delete [] c_zero_int_data;
02246     delete [] c_zero_int32_data;
02247     delete [] c_zero_double_data;
02248   }
02249 
02250   return CUBIT_SUCCESS;
02251 }
02252 
02253 
02254 
02255 
02256 //-------------------------------------------------------------------------
02257 // Purpose       : Deletes all solid model entities associated with the
02258 //                 Bodies in the input list.
02259 //
02260 // Special Notes :
02261 //
02262 // Creator       : Steve Owen
02263 //
02264 // Creation Date : 4/23/01
02265 //-------------------------------------------------------------------------
02266 void FacetQueryEngine::delete_solid_model_entities(DLIList<BodySM*>&BodyList) const
02267 {
02268   BodySM* BodyPtr = NULL;
02269   for (int i = 0; i < BodyList.size(); i++ )
02270   {
02271     BodyPtr = BodyList.get_and_step();
02272     this->delete_solid_model_entities(BodyPtr);
02273   }
02274 
02275   return;
02276 }
02277 
02278 //-------------------------------------------------------------------------
02279 // Purpose       : Delete a FacetBody and child entities.
02280 //
02281 // Special Notes :
02282 //
02283 // Creator       : Jason Kraftcheck
02284 //
02285 // Creation Date : 09/29/03
02286 //-------------------------------------------------------------------------
02287 CubitStatus
02288 FacetQueryEngine::delete_solid_model_entities( BodySM* bodysm ) const
02289 {
02290   FacetBody* fbody = dynamic_cast<FacetBody*>(bodysm);
02291   if (!fbody)
02292     return CUBIT_FAILURE;
02293 
02294   DLIList<FacetLump*> lumps;
02295   DLIList<FacetShell*> shells;
02296   DLIList<FacetSurface*> surfaces;
02297 
02298   fbody->get_lumps(lumps);
02299   fbody->disconnect_all_lumps();
02300   delete fbody;
02301 
02302   for (int i = lumps.size(); i--; )
02303   {
02304     FacetLump* lump = lumps.get_and_step();
02305 
02306     shells.clean_out();
02307     lump->get_shells(shells);
02308     lump->disconnect_all_shells();
02309     delete lump;
02310 
02311     for (int j = shells.size(); j--; )
02312     {
02313       FacetShell* shell = shells.get_and_step();
02314 
02315       surfaces.clean_out();
02316       shell->get_surfaces(surfaces);
02317       shell->disconnect_all_surfaces();
02318       delete shell;
02319 
02320       for (int k = surfaces.size(); k--; )
02321       {
02322         FacetSurface* surface = surfaces.get_and_step();
02323         if (!surface->has_parent_shell())
02324           delete_solid_model_entities(surface);
02325       }
02326     }
02327   }
02328 
02329   return CUBIT_SUCCESS;
02330 }
02331 
02332 //-------------------------------------------------------------------------
02333 // Purpose       : Delete a FacetSurface and child entities.
02334 //
02335 // Special Notes :
02336 //
02337 // Creator       : Jason Kraftcheck
02338 //
02339 // Creation Date : 09/29/03
02340 //-------------------------------------------------------------------------
02341 CubitStatus
02342 FacetQueryEngine::delete_solid_model_entities( Surface* surface ) const
02343 {
02344   FacetSurface* fsurf = dynamic_cast<FacetSurface*>(surface);
02345   if (!fsurf || fsurf->has_parent_shell())
02346     return CUBIT_FAILURE;
02347 
02348   DLIList<FacetLoop*> loops;
02349   DLIList<FacetCoEdge*> coedges;
02350 
02351   fsurf->get_loops(loops);
02352   fsurf->disconnect_all_loops();
02353   delete fsurf;
02354 
02355   for (int i = loops.size(); i--; )
02356   {
02357     FacetLoop* loop = loops.get_and_step();
02358 
02359     coedges.clean_out();
02360     loop->get_coedges(coedges);
02361     loop->disconnect_all_coedges();
02362     delete loop;
02363 
02364     for (int j = coedges.size(); j--; )
02365     {
02366       FacetCoEdge* coedge = coedges.get_and_step();
02367       FacetCurve* curve = dynamic_cast<FacetCurve*>(coedge->curve());
02368       if (curve)
02369       {
02370         curve->disconnect_coedge(coedge);
02371         if (!curve->has_parent_coedge())
02372           delete_solid_model_entities(curve);
02373       }
02374 
02375       delete coedge;
02376     }
02377   }
02378 
02379   return CUBIT_SUCCESS;
02380 }
02381 
02382 //-------------------------------------------------------------------------
02383 // Purpose       : Delete a FacetCurve and child entities.
02384 //
02385 // Special Notes :
02386 //
02387 // Creator       : Jason Kraftcheck
02388 //
02389 // Creation Date : 09/29/03
02390 //-------------------------------------------------------------------------
02391 CubitStatus
02392 FacetQueryEngine::delete_solid_model_entities( Curve* curve ) const
02393 {
02394   FacetCurve* fcurve = dynamic_cast<FacetCurve*>(curve);
02395   if (!fcurve || fcurve->has_parent_coedge())
02396     return CUBIT_FAILURE;
02397 
02398   FacetPoint* start = dynamic_cast<FacetPoint*>(fcurve->start_point());
02399   FacetPoint*   end = dynamic_cast<FacetPoint*>(fcurve->end_point()  );
02400 
02401   if (start == end )
02402       end = NULL;
02403 
02404   if (start)
02405   {
02406     start->disconnect_curve(fcurve);
02407     if (!start->has_parent_curve())
02408       delete_solid_model_entities(start);
02409   }
02410 
02411   if (end)
02412   {
02413     end->disconnect_curve(fcurve);
02414     if (!end->has_parent_curve())
02415       delete_solid_model_entities(end);
02416   }
02417 
02418   delete curve;
02419   return CUBIT_SUCCESS;
02420 }
02421 
02422 //-------------------------------------------------------------------------
02423 // Purpose       : Delete a FacetPoint and child entities.
02424 //
02425 // Special Notes :
02426 //
02427 // Creator       : Jason Kraftcheck
02428 //
02429 // Creation Date : 09/29/03
02430 //-------------------------------------------------------------------------
02431 CubitStatus
02432 FacetQueryEngine::delete_solid_model_entities( TBPoint* point ) const
02433 {
02434   FacetPoint* fpoint = dynamic_cast<FacetPoint*>(point);
02435   if (!fpoint || fpoint->has_parent_curve())
02436     return CUBIT_FAILURE;
02437 
02438   delete point;
02439   return CUBIT_SUCCESS;
02440 }
02441 
02442 CubitStatus FacetQueryEngine::fire_ray( CubitVector &origin,
02443                                         CubitVector &direction,
02444                                         DLIList<TopologyBridge*> &at_entity_list,
02445                                         DLIList<double> &ray_params,
02446                                         int max_hits,
02447                                         double ray_radius,
02448                                         DLIList<TopologyBridge*> *hit_entity_list) const
02449 {
02450   
02451   TopologyBridge *bridge_ptr;
02452   int i, j;
02453   bool hit = false;
02454 
02455   DLIList<double> tmp_ray_params;
02456   DLIList<FacetSurface*> at_surface_list;
02457   DLIList<FacetCurve*> at_curve_list;
02458   DLIList<FacetPoint*> at_point_list;
02459 
02460   if( ray_radius == 0.0 )
02461       ray_radius = get_sme_resabs_tolerance();
02462   
02463   at_entity_list.reset();
02464   for (i=0; i<at_entity_list.size(); i++)
02465   {
02466       hit = false;
02467       bridge_ptr = at_entity_list.get_and_step();
02468 
02469       //determine which type of geometry we have. body, lump, face, curve?
02470       if (CAST_TO(bridge_ptr, FacetBody))
02471       {
02472           FacetBody* f_body = CAST_TO(bridge_ptr, FacetBody);
02473           DLIList<Surface*> surface_list;
02474           f_body->surfaces(surface_list);
02475       }
02476       else if (CAST_TO(bridge_ptr, FacetLump))
02477       {
02478           FacetLump* f_lump = CAST_TO(bridge_ptr, FacetLump);
02479           PRINT_INFO("Found FacetLump.\n");
02480           DLIList<FacetSurface*> f_surface_list;
02481           f_lump->get_surfaces(f_surface_list);
02482           at_surface_list.merge_unique(f_surface_list);
02483       }
02484       else if (CAST_TO(bridge_ptr, Surface))
02485       {
02486           FacetSurface* f_surface = CAST_TO(bridge_ptr, FacetSurface);
02487           
02488           DLIList<CubitFacet*> facet_list;
02489           DLIList<CubitPoint*> point_list;
02490           f_surface->get_my_facets(facet_list, point_list);
02491 
02492           //PRINT_INFO("There are %d facets.\n", facet_list.size());
02493 
02494           //RTree<CubitFacet*> rtree(ray_radius);
02495           //for (j=0; j<facet_list.size(); j++)
02496             //  rtree.add(facet_list.get_and_step();
02497           
02498           //DLIList<CubitFacet*> facet_list1;
02499           //CubitBox range_box();
02500           //make range box for the ray
02501           //rtree.find(range_box, facet_list1);
02502 
02503           CubitVector* intersection_pt = new CubitVector();     
02504           double distance;
02505 
02506           for (j=0; j<facet_list.size(); j++)
02507           {
02508               if (hit)
02509                   break;
02510 
02511               CubitFacet* facet = facet_list.get_and_step();
02512 
02513               // Find intersection of ray with triangle
02514               int rv = FacetEvalTool::intersect_ray(origin, direction, facet, intersection_pt, distance);
02515 
02516               switch (rv)
02517               {
02518               case -1:
02519                   //PRINT_INFO("Facet is degenerate (segment or point).\n");
02520                   break;
02521               case 0:
02522                   //PRINT_INFO("Ray does not intersect the facet.\n");
02523                   break;
02524               case 1:
02525                   {
02526                       hit = true;
02527                       if (hit_entity_list)
02528                           hit_entity_list->append(bridge_ptr);
02529                       ray_params.append(distance);
02530                       //PRINT_INFO("Ray intersects facet at %f, %f, %f.\n", intersection_pt->x(), intersection_pt->y(), intersection_pt->z());
02531                     
02532                       continue;
02533                   }
02534               case 2:
02535                   //PRINT_INFO("Ray is in same plane as the facet.\n");
02536                   break;
02537               }
02538           }
02539           if (intersection_pt)
02540               delete intersection_pt;
02541       
02542       }
02543       else if (CAST_TO(bridge_ptr, Curve))
02544       {
02545           FacetCurve* f_curve = CAST_TO(bridge_ptr, FacetCurve);
02546           DLIList<CubitFacetEdge*> facet_edge_list;
02547           f_curve->get_facets(facet_edge_list);
02548 
02549           //PRINT_INFO("There are %d facetedges.\n", facet_edge_list.size());
02550           CubitVector* intersection_pt = new CubitVector();     
02551           double distance;
02552 
02553           for (j=0; j<facet_edge_list.size(); j++)
02554           {
02555               if (hit)
02556                   break;
02557 
02558               CubitFacetEdge* facet_edge = facet_edge_list.get_and_step();
02559 
02560               int rv = FacetEvalTool::intersect_ray(origin, direction, facet_edge, intersection_pt, distance);
02561 
02562               switch (rv)
02563               {
02564               case -1:
02565                   //PRINT_INFO("Facet is degenerate (segment or point).\n");
02566                   break;
02567               case 0:
02568                   //PRINT_INFO("Ray does not intersect the facet edge.\n");
02569                   break;
02570               case 1:
02571                   {
02572                       hit = true;
02573                       if (hit_entity_list)
02574                           hit_entity_list->append(bridge_ptr);
02575                       ray_params.append(distance);
02576                       //PRINT_INFO("Ray intersects facet at %f, %f, %f.\n", intersection_pt->x(), intersection_pt->y(), intersection_pt->z());
02577                     
02578                       continue;
02579                   }
02580               case 2:
02581                   //PRINT_INFO("Ray is parallel to the facet.\n");
02582                   break;
02583               }
02584 
02585           }
02586           if (intersection_pt)
02587               delete intersection_pt;
02588       }
02589       else if (CAST_TO(bridge_ptr, FacetPoint))
02590       {
02591           FacetPoint* f_point = CAST_TO(bridge_ptr, FacetPoint);
02592           at_point_list.append_unique(f_point);
02593       }
02594       else
02595           ;//PRINT_INFO("Cast error in FacetQueryEngine::fire_ray.\n");
02596 
02597   }
02598 
02599   return CUBIT_SUCCESS;
02600 }
02601   //- fire a ray at the specified entities, returning the parameters
02602   //- (distances) along the ray and optionally the entities hit
02603 
02604 
02605 double FacetQueryEngine::get_sme_resabs_tolerance() const
02606 {
02607   return GEOMETRY_RESABS;
02608 }
02609 // Gets solid modeler's resolution absolute tolerance
02610 
02611 double FacetQueryEngine::set_sme_resabs_tolerance( double )
02612 {
02613   PRINT_ERROR("FacetQueryEngine::set_sme_resabs_tolerance not yet implemented.\n");
02614   return CUBIT_FAILURE;
02615 }
02616 
02617 CubitStatus FacetQueryEngine::set_int_option( const char* , int )
02618 {
02619   PRINT_ERROR("FacetQueryEngine::set_int_option not yet implemented.\n");
02620   return CUBIT_FAILURE;
02621 }
02622 
02623 CubitStatus FacetQueryEngine::set_dbl_option( const char* , double )
02624 {
02625   PRINT_ERROR("FacetQueryEngine::set_dbl_option not yet implemented.\n");
02626   return CUBIT_FAILURE;
02627 }
02628 
02629 CubitStatus FacetQueryEngine::set_str_option( const char* , const char* )
02630 {
02631   PRINT_ERROR("FacetQueryEngine::set_str_option not yet implemented.\n");
02632   return CUBIT_FAILURE;
02633 }
02634   //- Set solid modeler options
02635 
02636 //===========================================================================
02637 //Function Name: make_facets
02638 //Member Type:  PUBLIC
02639 //Description:  creates Cubit quad facet entities from the hash points and
02640 //              connectivity
02641 //===========================================================================
02642 CubitStatus FacetQueryEngine::make_facets(
02643   int *conn,        // conectivity array (size = 4 * nfacets)
02644   int nfacets,      // total number of facets (tri+quad)
02645   DLIList<CubitQuadFacet *> &facet_list ) // return the facet list
02646 {
02647   CubitQuadFacet *facet_ptr = NULL;
02648   CubitStatus rv = CUBIT_SUCCESS;
02649   CubitPoint *point0, *point1, *point2, *point3;
02650 
02651   // create the facet array
02652 
02653   for(int ii=0; ii<nfacets; ii++)
02654   {
02655     if (conn[ii*4+2] != conn[ii*4+3])
02656     {
02657       point0 = get_hash_point(conn[ii*4]);
02658       point1 = get_hash_point(conn[ii*4+1]);
02659       point2 = get_hash_point(conn[ii*4+2]);
02660       point3 = get_hash_point(conn[ii*4+3]);
02661 
02662       facet_ptr = new CubitQuadFacetData( point0, point1, point2, point3 );
02663 
02664       if (!facet_ptr)
02665       {
02666         rv = CUBIT_FAILURE;
02667         return rv;
02668       }
02669       facet_list.append( facet_ptr );
02670     }
02671   }
02672   return rv;
02673 }
02674 
02675 //===========================================================================
02676 //Function Name: make_facets
02677 //Member Type:  PUBLIC
02678 //Description:  creates Cubit tri facet entities from the hash points and
02679 //              connectivity
02680 //===========================================================================
02681 CubitStatus FacetQueryEngine::make_facets(
02682   int *conn,        // conectivity array (size = 4 * nfacets)
02683   int nfacets,      // total number of facets (tri+quad)
02684   DLIList<CubitFacet *> &facet_list ) // return the facet list
02685 {
02686   CubitFacet *facet_ptr = NULL;
02687   CubitStatus rv = CUBIT_SUCCESS;
02688   CubitPoint *point0, *point1, *point2;
02689 
02690   // create the facet array
02691 
02692   for(int ii=0; ii<nfacets; ii++)
02693   {
02694     if (conn[ii*4+2] == conn[ii*4+3])
02695     {
02696       point0 = get_hash_point(conn[ii*4]);
02697       point1 = get_hash_point(conn[ii*4+1]);
02698       point2 = get_hash_point(conn[ii*4+2]);
02699       if( (point0 == point1) || (point0 == point2) || (point1 == point2) ){
02700           PRINT_ERROR("Point used more than once in a single facet.  This is not allowed.\n");
02701           return CUBIT_FAILURE;
02702       }
02703       if( !point0 || !point1 || !point2 ){
02704           PRINT_ERROR("Point in facet is undefined.  This is not allowed.\n");
02705           return CUBIT_FAILURE;
02706       }
02707       
02708       facet_ptr = new CubitFacetData( point0, point1, point2 );
02709 
02710       if (!facet_ptr)
02711       {
02712         rv = CUBIT_FAILURE;
02713         return rv;
02714       }
02715       facet_list.append( facet_ptr );
02716     }
02717   }
02718 
02719  return rv;
02720 }
02721 
02722 //===========================================================================
02723 //Function Name: ensure_is_ascii_stl_file
02724 //Member Type:
02725 //Description: returns CUBIT_TRUE in is_ascii if fp is an ascii stl file
02726 //Author: Plamen Stoyanov (USF)
02727 //===========================================================================
02728 CubitStatus FacetQueryEngine::ensure_is_ascii_stl_file(FILE * fp, CubitBoolean &is_ascii)
02729 {
02730 
02731   char line[128]="";
02732 
02733   if (fgets(line, 128, fp)==NULL)
02734   {
02735     return CUBIT_FAILURE;
02736   }
02737   if (fgets(line, 128, fp)==NULL)
02738   {
02739     return CUBIT_FAILURE;
02740   }
02741   if (strlen(line)==127)
02742   {
02743     if (fgets(line, 128, fp)==NULL)
02744     {
02745       return CUBIT_FAILURE;
02746     }
02747   }
02748 
02749 
02750   unsigned int dummy_int=0;
02751 
02752   // One of the functions called by isspace() has an assert that can fail in debug mode if 
02753   // line[dummy_int] is negative so check for it here.
02754   while (line[dummy_int] > -1 && isspace(line[dummy_int]) && dummy_int < strlen(line)) 
02755     dummy_int++;
02756 
02757   if (strlen(line)-dummy_int>5)
02758   {
02759     if (tolower(line[dummy_int++])=='f' &&
02760       tolower(line[dummy_int++])=='a' &&
02761       tolower(line[dummy_int++])=='c' &&
02762       tolower(line[dummy_int++])=='e' &&
02763       tolower(line[dummy_int])=='t')
02764     {
02765       if (fgets(line, 128, fp)==NULL)
02766       {
02767         return CUBIT_FAILURE;
02768       }
02769       dummy_int=0;
02770       while (isspace(line[dummy_int])&& dummy_int<strlen(line))
02771       {
02772         dummy_int++;
02773       }
02774       if (strlen(line)-dummy_int>5)
02775       {
02776         if (tolower(line[dummy_int++])=='o' &&
02777           tolower(line[dummy_int++])=='u' &&
02778           tolower(line[dummy_int++])=='t' &&
02779           tolower(line[dummy_int++])=='e' &&
02780           tolower(line[dummy_int])=='r')
02781         {
02782           if (fgets(line, 128, fp)==NULL)
02783           {
02784             return CUBIT_FAILURE;
02785           }
02786           dummy_int=0;
02787           while (isspace(line[dummy_int])&& dummy_int<strlen(line)) {
02788             dummy_int++;
02789           }
02790           if (strlen(line)-dummy_int>6)
02791           {
02792             if (tolower(line[dummy_int++])=='v' &&
02793               tolower(line[dummy_int++])=='e' &&
02794               tolower(line[dummy_int++])=='r' &&
02795               tolower(line[dummy_int++])=='t' &&
02796               tolower(line[dummy_int++])=='e'   &&
02797               tolower(line[dummy_int])=='x')
02798             {
02799               is_ascii=CUBIT_TRUE;
02800             }
02801           }
02802         }
02803       }
02804     }
02805   }
02806   return CUBIT_SUCCESS;
02807 }
02808 
02809 //===========================================================================
02810 //Function Name: read_facets_stl
02811 //Member Type:
02812 //Description:  read facets from stl file combining vertices within tolerance
02813 //distance
02814 //Author: Plamen Stoyanov (USF)
02815 //===========================================================================
02816 CubitStatus FacetQueryEngine::read_facets_stl_tolerance(
02817                                               DLIList<CubitFacet *> &tfacet_list,
02818                                               DLIList<CubitPoint *> & /*point_list*/,
02819                                               const char * file_name,
02820                                               int &npoints,
02821                                               int &ntri,
02822                                               long& seek_address,
02823                                               double tolerance
02824                                               )
02825 {
02826   
02827   FILE *fp = fopen(file_name, "r");
02828   if (fp == NULL)
02829   {
02830     PRINT_ERROR("Could not open file %s for reading\n", file_name);
02831     seek_address = 0;
02832     return CUBIT_FAILURE;
02833   }
02834 
02835   DLIList <CubitPoint *> file_points;
02836   CubitPoint *current_point;
02837   int points_in_file=0;
02838   int ii;
02839 
02840   CubitBoolean is_ascii=CUBIT_FALSE;
02841   if (!ensure_is_ascii_stl_file(fp, is_ascii))
02842   {
02843     seek_address = 0;
02844     fclose(fp);
02845     return CUBIT_FAILURE;
02846   }
02847 
02848   if (is_ascii==CUBIT_TRUE)
02849   {
02850 
02851     PRINT_INFO("Reading facets...\n");
02852     fclose(fp);
02853     fp = fopen(file_name, "r");
02854     fseek(fp,seek_address,SEEK_SET);
02855     
02856     char line[128], junk[30];
02857     int numverts;
02858     double xx[3], yy[3], zz[3];
02859     int linenumber, num;
02860     bool done, error_found, eof_found;
02861 
02862     linenumber = 0;
02863 
02864     strcpy(line,"");
02865     done = false;
02866     error_found = false;
02867     eof_found = false;
02868     while ( (strstr(line,"endsolid") == 0) && (error_found == false) ) {
02869       numverts = 0;    
02870       while ( numverts < 3 ) {
02871         if ( fgets(line,127,fp) == 0 ) {
02872           linenumber++;
02873           eof_found = true;
02874           break; // EOF
02875         }
02876         linenumber++;        
02877 //      makelowercase(line);
02878         int len, ij;
02879         len = strlen(line);
02880         for ( ij = 0; ij < len; ij++ ) 
02881           line[ij] = tolower(line[ij]);
02882 
02883         if ( strstr(line,"endsolid") != 0 ) {
02884           done = true;
02885           break; // End of part definition
02886         }
02887         if ( strstr(line,"vertex") != 0 ) {
02888           num = sscanf(line,"%s %le %le %le",junk,&xx[numverts],&yy[numverts],&zz[numverts]);
02889           if ( num != 4 ) {
02890             error_found = true;
02891             break; // error in reading vertices
02892           }
02893           numverts += 1;
02894         }
02895       } // end of while ( numverts < 3 )  
02896 
02897       if ( (eof_found == true) || (done == true)  || 
02898            (error_found == true) || (numverts != 3) ) break;
02899 
02900       current_point = (CubitPoint *) new CubitPointData(xx[0],yy[0],zz[0]);
02901       current_point->set_id(points_in_file++);
02902       file_points.append(current_point);
02903       current_point = (CubitPoint *) new CubitPointData(xx[1],yy[1],zz[1]);
02904       current_point->set_id(points_in_file++);
02905       file_points.append(current_point);
02906       current_point = (CubitPoint *) new CubitPointData(xx[2],yy[2],zz[2]);
02907       current_point->set_id(points_in_file++);
02908       file_points.append(current_point);
02909 
02910     }
02911     seek_address = 0;
02912     if ( eof_found == true ) {
02913       PRINT_WARNING("Premature end-of-file on STL file. Body may be incomplete.\n");
02914       fclose(fp);
02915       goto end_read_file_points;
02916     }
02917     if ( error_found == true ) {
02918       PRINT_WARNING("Error found while reading line number %d of file %s. Body may be incomplete.\n",
02919               linenumber,file_name);
02920       fclose(fp);       
02921       goto end_read_file_points;
02922     }
02923     if ( done == false ) {
02924       PRINT_WARNING("Error found while reading line number %d of file %s. Body may be incomplete.\n",
02925               linenumber,file_name); 
02926       fclose(fp);         
02927       goto end_read_file_points;
02928     }  
02929 
02930     if ( (eof_found == false) && (error_found == false) && (done == true) ) {
02931       while ( fgets(line,127,fp) != 0 ) {
02932         if ( (strstr(line,"solid") != 0) && (strstr(line,"endsolid") == 0) ) {
02933           seek_address = ftell(fp);
02934           break;
02935         }
02936       }
02937     }
02938     fclose(fp);
02939     goto end_read_file_points;
02940   }
02941   else
02942   {
02943     fclose(fp);
02944     // file is closed so that it can be opened as binary
02945     fp = fopen(file_name, "rb");
02946     if (fp == NULL)
02947     {
02948       PRINT_ERROR("Could not open file %s for reading\n", file_name);
02949       return CUBIT_FAILURE;
02950     }
02951 
02952     char dummy;
02953         // iterates through the facets of the file
02954     float cur[12];      // an array to hold 48 bytes representing 1AVS facet
02955 
02956     fseek(fp, 80, SEEK_SET);
02957     size_t count = fread(&ntri, 4, 1, fp);
02958     if (count != 1) {
02959       PRINT_ERROR("Trouble reading in number of triangles\n");
02960       return CUBIT_FAILURE;
02961     }
02962 
02963     PRINT_INFO ("Reading facets...\n");
02964     for (ii=0; ii<ntri; ii++) {
02965       // read in 1 facet
02966       if (fread(cur, 4, 12, fp) != 12)
02967       {
02968         PRINT_INFO ("Abnormal file termination %s \n", file_name); break;
02969       }
02970       count = fread(&dummy, 1, 1, fp);
02971       count = fread(&dummy, 1, 1, fp);
02972 
02973         //make point
02974       current_point = (CubitPoint *) new CubitPointData(cur[3],cur[4],cur[5]);
02975       current_point->set_id(points_in_file++);
02976       file_points.append(current_point);
02977       current_point = (CubitPoint *) new CubitPointData(cur[6],cur[7],cur[8]);
02978       current_point->set_id(points_in_file++);
02979       file_points.append(current_point);
02980       current_point = (CubitPoint *) new CubitPointData(cur[9],cur[10],cur[11]);
02981       current_point->set_id(points_in_file++);
02982       file_points.append(current_point);
02983     }
02984   }
02985   fclose(fp);
02986   
02987 // at this point all points from the file are in file_points
02988 end_read_file_points:
02989 
02990   // grid search tree to hold points
02991   GridSearchTree * node_grid = new GridSearchTree (tolerance);
02992 
02993   CubitPoint
02994              *point0,
02995              *point1,
02996              *point2;
02997   CubitFacet
02998              *facet_ptr;
02999   ntri=0;
03000   npoints=0;
03001 
03002   if (file_points.size() % 3 != 0)
03003   {
03004     PRINT_INFO("File Error.");
03005     return CUBIT_FAILURE;
03006   }
03007 
03008   for (ii = file_points.size(); ii>0; ii-=3)
03009   {
03010 
03011     // get three points from the file_points list
03012     // and compare them against the data already in the
03013     // grid search tree; if it contains a point within
03014     // epsilon tolerance this point would replace the
03015     // current point
03016     point0 = node_grid->fix(file_points.get_and_step());
03017     point1 = node_grid->fix(file_points.get_and_step());
03018     point2 = node_grid->fix(file_points.get_and_step());
03019 
03020 
03021     if (point0 && point1 && point2 && point0 != point1 && point1!=point2 && point2!=point0 )
03022     {
03023 
03024       facet_ptr = new CubitFacetData(point0, point1, point2);
03025 
03026       if (facet_ptr)
03027       {
03028         tfacet_list.append(facet_ptr);
03029         ntri++;
03030       }
03031 
03032     }
03033   }
03034 
03035   //delete node_grid;
03036   return CUBIT_SUCCESS;
03037 }
03038 
03039 
03040 //===========================================================================
03041 //Function Name: read_facets_stl
03042 //Member Type:
03043 //Description:  read facets from stl file
03044 //Author: Plamen Stoyanov (USF)
03045 //===========================================================================
03046 
03047 CubitStatus FacetQueryEngine::read_facets_stl(
03048                                               DLIList<CubitFacet *> &tfacet_list,
03049                                               DLIList<CubitPoint *> &point_list,
03050                                               const char * file_name,
03051                                               int &npoints,
03052                                               int &ntri,
03053                                               long& seek_address
03054                                               )
03055 {
03056 
03057   ntri = 0;
03058   npoints = 0;
03059   FILE *fp = fopen(file_name, "r");
03060   if (fp == NULL)
03061   {
03062     PRINT_ERROR("Could not open file %s for reading\n", file_name);
03063     seek_address = 0;
03064     return CUBIT_FAILURE;
03065   }
03066 
03067   typedef std::map< CubitPoint * , int, CubitPointComparator > vMap;
03068 
03069   vMap mm;          // binary search tree to hold the vertices for efficiency
03070   vMap::iterator pos;
03071   bool append_to_facet_list=CUBIT_TRUE;
03072 
03073   CubitBoolean is_ascii=CUBIT_FALSE;
03074 
03075   if (!ensure_is_ascii_stl_file(fp, is_ascii))
03076   {
03077     seek_address = 0;
03078     fclose(fp);
03079     return CUBIT_FAILURE;
03080   }
03081 
03082   if (is_ascii==CUBIT_TRUE)
03083   {
03084     CubitPoint *point0,*point1,*point2;
03085     CubitFacet *facet_ptr = NULL;
03086 
03087     PRINT_INFO("Reading facets...\n");
03088     fclose(fp);
03089     fp = fopen(file_name, "r");
03090     fseek(fp,seek_address,SEEK_SET);
03091     char line[128], junk[30];
03092     int numverts;
03093     double xx[3], yy[3], zz[3];
03094     int linenumber, num;
03095     bool done, error_found, eof_found;
03096 
03097     linenumber = 0;
03098 
03099     strcpy(line,"");
03100     done = false;
03101     error_found = false;
03102     eof_found = false;
03103     while ( (strstr(line,"endsolid") == 0) && (error_found == false) ) {
03104       numverts = 0;    
03105       while ( numverts < 3 ) {
03106         if ( fgets(line,127,fp) == 0 ) {
03107           linenumber++;
03108           eof_found = true;
03109           break; // EOF
03110         }
03111         linenumber++;        
03112 //      makelowercase(line);
03113         int len, ij;
03114         len = strlen(line);
03115         for ( ij = 0; ij < len; ij++ ) 
03116           line[ij] = tolower(line[ij]);
03117 
03118         if ( strstr(line,"endsolid") != 0 ) {
03119           done = true;
03120           break; // End of part definition
03121         }
03122         if ( strstr(line,"vertex") != 0 ) {
03123           num = sscanf(line,"%s %le %le %le",junk,&xx[numverts],&yy[numverts],&zz[numverts]);
03124           if ( num != 4 ) {
03125             error_found = true;
03126             break; // error in reading vertices
03127           }
03128           numverts += 1;
03129         }
03130       } // end of while ( numverts < 3 )  
03131 
03132       if ( (eof_found == true) || (done == true)  || 
03133            (error_found == true) || (numverts != 3) ) break;
03134       point0 = (CubitPoint *) new CubitPointData(xx[0],yy[0],zz[0]);
03135       pos=mm.find(point0);
03136 
03137       if (pos==mm.end())
03138       {
03139         mm.insert ( vMap::value_type(point0, npoints));
03140         point0->set_id( npoints ++ );
03141         //point_list is output of functionAVS
03142         point_list.append(point0);
03143       }
03144       else
03145       {
03146         delete point0;
03147         point0=((*pos).first);
03148       }
03149       point1 = (CubitPoint *) new CubitPointData(xx[1],yy[1],zz[1]);
03150       pos=mm.find(point1);
03151       if (pos==mm.end())
03152       {
03153         mm.insert ( vMap::value_type(point1, npoints));
03154         point1->set_id( npoints ++ );
03155         //point_list is output of function
03156         point_list.append(point1);
03157       }
03158       else
03159       {
03160         delete point1;
03161         point1=((*pos).first);
03162       }
03163       point2 = (CubitPoint *) new CubitPointData(xx[2],yy[2],zz[2]);
03164       pos=mm.find(point2);
03165       if (pos==mm.end())
03166       {
03167         mm.insert ( vMap::value_type(point2, npoints));
03168         point2->set_id( npoints ++ );
03169         //point_list is output of function
03170         point_list.append(point2);
03171       }
03172       else
03173       {
03174         delete point2;
03175         point2=((*pos).first);
03176       }
03177 
03178       if (point0 && point1 && point2 && point0!=point1 && point1!=point2 && point2 !=point0)
03179       {
03180         facet_ptr = new CubitFacetData( point0, point1, point2 );
03181         append_to_facet_list=CUBIT_TRUE;
03182       }
03183       else
03184       {
03185         append_to_facet_list=CUBIT_FALSE;
03186       }
03187     
03188       if (!facet_ptr)
03189       {
03190         seek_address = 0;
03191         fclose(fp);
03192         return CUBIT_FAILURE;
03193       }
03194 
03196       if (append_to_facet_list)
03197       {
03198         tfacet_list.append( facet_ptr );
03199         ntri++;
03200       }
03201       
03202     }
03203     seek_address = 0;
03204     if ( eof_found == true ) {
03205       PRINT_WARNING("Premature end-of-file on STL file. Body may be incomplete.\n");
03206       fclose(fp);
03207       return CUBIT_SUCCESS;
03208     }
03209     if ( error_found == true ) {
03210       PRINT_WARNING("Error found while reading line number %d of file %s. Body may be incomplete.\n",
03211               linenumber,file_name);
03212       fclose(fp);
03213       return CUBIT_SUCCESS;
03214     }
03215     if ( done == false ) {
03216       PRINT_WARNING("Error found while reading line number %d of file %s. Body may be incomplete.\n",
03217               linenumber,file_name); 
03218       fclose(fp); 
03219       return CUBIT_SUCCESS;
03220     }  
03221 
03222     if ( (eof_found == false) && (error_found == false) && (done == true) ) {
03223       while ( fgets(line,127,fp) != 0 ) {
03224         if ( (strstr(line,"solid") != 0) && (strstr(line,"endsolid") == 0) ) {
03225           seek_address = ftell(fp);
03226 //          PRINT_INFO("This STL file is a multipart file.  Only the first part was read.\n");
03227           break;
03228         }
03229       }
03230     }
03231     fclose(fp);
03232       
03233     return CUBIT_SUCCESS;
03234   }
03235   else
03236   {
03237     fclose(fp);
03238     // file is closed so that it can be opened as binary
03239     fp = fopen(file_name, "rb");
03240     if (fp == NULL)
03241     {
03242       PRINT_ERROR("Could not open file %s for reading\n", file_name);
03243       return CUBIT_FAILURE;
03244     }
03245 
03246 
03247     CubitFacet *facet_ptr = NULL;
03248     CubitPoint *point0,
03249               *point1,
03250                 *point2;
03251 
03252     char dummy;
03253     int        ii=0;    // iterates through the facets of the file
03254     float cur[12];      // an array to hold 48 bytes representing 1 facet
03255     npoints=0;          // only tri facets in stl files
03256 
03257     //put file pointer back where you found it
03258     fseek(fp, seek_address+80, SEEK_SET);
03259     size_t count = fread(&ntri, 4, 1, fp);
03260     if (count != 1) {
03261       PRINT_ERROR("Trouble reading in number of triangles\n");
03262       return CUBIT_FAILURE;
03263     }
03264     int distinct_ntri=ntri;
03265 
03266     PRINT_INFO ("Reading facets...\n");
03267     for (ii=0; ii<ntri; ii++) {
03268       // read in 1 facet
03269       if (fread(cur, 4, 12, fp) != 12)
03270       {
03271         PRINT_INFO ("Abnormal file termination %s \n", file_name); break;
03272       }
03273       count = fread(&dummy, 1, 1, fp);
03274       count = fread(&dummy, 1, 1, fp);
03275 
03276         //make point
03277         point0 = (CubitPoint *) new CubitPointData( cur[3], cur[4], cur[5] );
03278 
03279         pos=mm.find(point0);
03280         if (pos==mm.end())
03281         {
03282           mm.insert ( vMap::value_type(point0, npoints));
03283           point0->set_id( npoints ++ );
03284           //point_list is output of function
03285           point_list.append(point0);
03286         }
03287         else
03288         {
03289           delete point0;
03290           point0=((*pos).first);
03291         }
03292 
03293         //make point
03294         point1 = (CubitPoint *) new CubitPointData( cur[6], cur[7], cur[8] );
03295 
03296         pos=mm.find(point1);
03297         if (pos==mm.end())
03298         {
03299           mm.insert ( vMap::value_type(point1, npoints));
03300           point1->set_id( npoints ++ );
03301           //point_list is output of function
03302           point_list.append(point1);
03303         }
03304         else
03305         {
03306           delete point1;
03307           point1=((*pos).first);
03308         }
03309 
03310         //make point
03311         point2 = (CubitPoint *) new CubitPointData( cur[9], cur[10], cur[11] );
03312 
03313         pos=mm.find(point2);
03314         if (pos==mm.end())
03315         {
03316           mm.insert ( vMap::value_type(point2, npoints));
03317           point2->set_id( npoints ++ );
03318           //point_list is output of function
03319           point_list.append(point2);
03320         }
03321         else
03322         {
03323           delete point2;
03324           point2=((*pos).first);
03325         }
03326 
03327         // this is to avoid a facet with all points on same line, which crashes CUBIT
03328         // because of assertion
03329         if (point0 && point1 && point2 && point0!=point1 && point1!=point2 && point2 !=point0)
03330         {
03331           facet_ptr = new CubitFacetData( point0, point1, point2 );
03332           append_to_facet_list=CUBIT_TRUE;
03333         }
03334         else
03335         {
03336           append_to_facet_list=CUBIT_FALSE;
03337         }
03338 
03339         if (!facet_ptr)
03340         {
03341           fclose(fp);
03342           return CUBIT_FAILURE;
03343         }
03344 
03345         if (append_to_facet_list)
03346         {
03347           tfacet_list.append( facet_ptr );
03348         }
03349         else
03350         {
03351           distinct_ntri--;
03352         }
03353     }
03354     ntri=distinct_ntri;
03355 
03356     //reading at or past EOF
03357     long previous_pos = ftell(fp);
03358     fread(&dummy, 1, 1, fp);
03359 
03360     if( feof(fp) )
03361       seek_address = 0;
03362     else    
03363     {
03364       fseek(fp, previous_pos, SEEK_SET);
03365       seek_address = ftell(fp);
03366     }
03367 
03368     fclose(fp);
03369     return CUBIT_SUCCESS;
03370   }
03371 }
03372 
03373 
03374 //===========================================================================
03375 //Function Name: import_facets
03376 //Member Type:  PUBLIC
03377 //Description:  import facets and create geometry
03378 //===========================================================================
03379 CubitStatus FacetQueryEngine::import_facets(
03380   const char *file_name,                // to be read
03381   CubitBoolean use_feature_angle,       // to define where surfaces are broken
03382   double feature_angle,        // angle where surfaces are broken (degrees)
03383   double tolerance,             // for stl files loading
03384   int interp_order,            // Facet representation 1= linear, 4= Bezier
03385   CubitBoolean smooth_non_manifold,  // continutiy accross non-manifold edges
03386   CubitBoolean split_surfaces,   // break facet rep at surface boundaries
03387   CubitBoolean stitch,             // attempt to stitch together facets at the boundary
03388   CubitBoolean improve,      // smooth, swap and collapse to improve quality
03389   DLIList<CubitQuadFacet *> &quad_facet_list,  // return quad facets
03390   DLIList<CubitFacet *> &tri_facet_list,  // return tri facets
03391   DLIList<Surface *> &surface_list,  // return list of surfaces
03392   FacetFileFormat file_format )
03393 {
03394   DLIList <CubitFacet *>tfacet_list;
03395   DLIList <CubitQuadFacet *>qfacet_list;
03396   DLIList <CubitPoint *>point_list;
03397 
03398   ShellSM *shell_ptr;
03399   DLIList<ShellSM*> shell_list;
03400   Lump *lump_ptr;
03401   DLIList<Lump*> lump_list;
03402   BodySM *bodysm_ptr;
03403   Body *body_ptr;
03404   GeometryQueryTool *gti = GeometryQueryTool::instance();
03405   FacetShell* facet_shell;
03406   DLIList<DLIList<CubitFacet *> *> shell_facet_list;
03407   int ishell, ii;
03408   CubitBoolean is_water_tight = CUBIT_TRUE;
03409 
03410   // read the facets from a file
03411 
03412   int *conn = NULL;
03413   int npoints = 0;
03414   int nfacets = 0;
03415   int nquad = 0;
03416   int ntri = 0;
03417 
03418   int prev_vert;
03419   int prev_edge;
03420   int prev_face;
03421   int prev_vol;
03422   int prev_bod;
03423 
03424   long stl_seek_address=0;
03425   bool stl_multiple_parts = true;
03426   
03427   CubitStatus rv;
03428   //  Here we add the capability to read stl files with more than one part.
03429   while ( stl_multiple_parts == true ) {
03430     stl_multiple_parts = false;
03431     prev_vert = gti->num_ref_vertices();
03432     prev_edge = gti->num_ref_edges();
03433     prev_face = gti->num_ref_faces();
03434     prev_vol  = gti->num_ref_volumes();
03435     prev_bod  = gti->num_bodies();
03436     switch (file_format)
03437     {
03438     case STL_FILE:
03439       tfacet_list.clean_out(); // In case there are multiple parts in the stl file
03440       point_list.clean_out();
03441       shell_list.clean_out();
03442       lump_list.clean_out();
03443       shell_facet_list.clean_out();
03444       if (tolerance>0)
03445       {
03446         rv = read_facets_stl_tolerance(tfacet_list, point_list, file_name, npoints, ntri, stl_seek_address, tolerance);
03447       }
03448       else
03449       {
03450         rv = read_facets_stl(tfacet_list, point_list, file_name, npoints, ntri, stl_seek_address);
03451       }
03452       PRINT_INFO("  %d facets read.\n", ntri);
03453       if ( (rv == CUBIT_SUCCESS) && (stl_seek_address) > 0 ) stl_multiple_parts = true;
03454       nfacets = ntri;
03455 
03456       if (rv != CUBIT_SUCCESS)
03457       {
03458         goto end_import_facets;
03459       }
03460       break;
03461 
03462     case CUBIT_FACET_FILE:
03463     case AVS_FILE:
03464       rv = read_facets( file_name, conn, npoints, nquad, ntri, file_format );
03465 
03466       nfacets = ntri + nquad;
03467 
03468       if (rv != CUBIT_SUCCESS)
03469         goto end_import_facets;
03470 
03471       // make cubit facet entities from the points and connectivity
03472 
03473       if (nquad  > 0)
03474         rv = make_facets(conn, nfacets, qfacet_list);
03475       if (ntri > 0)
03476         rv = make_facets(conn, nfacets, tfacet_list);
03477       if (rv != CUBIT_SUCCESS)
03478         goto end_import_facets;
03479       get_all_hash_points(point_list);
03480       delete_hash_points();
03481       break;
03482     case CHOLLA_FILE:
03483       rv = read_cholla_file( file_name, feature_angle, point_list, tfacet_list );
03484       nquad = 0;
03485       ntri = tfacet_list.size();
03486       npoints = point_list.size();
03487       break;
03488     case FROM_FACET_LIST:
03489       tfacet_list = tri_facet_list;
03490       qfacet_list = quad_facet_list;
03491       if (tfacet_list.size() + qfacet_list.size() == 0)
03492       {
03493         PRINT_ERROR("No facets found to build geometry\n");
03494         rv = CUBIT_FAILURE;
03495         goto end_import_facets;
03496       }
03497       break;
03498     default:
03499       assert(0); // unrecognized file format
03500       break;
03501     }
03502 
03503     if (tfacet_list.size() + qfacet_list.size() == 0)
03504     {
03505       PRINT_ERROR("No facets read from file %s.\n", file_name);
03506       rv = CUBIT_FAILURE;
03507       goto end_import_facets;
03508     }
03509     else
03510     {
03511       PRINT_INFO("Building facet-based geometry from %d facets...\n",
03512                   tfacet_list.size() + qfacet_list.size() );
03513     }
03514 
03515 //  if (fix)
03516 //  {
03517 //    rv = check_facets( point_list, tfacet_list );
03518 //  }
03519 
03520     if (0)
03521     {
03522       // Call function to generate an x-y-z file for a CTH/SPH simulation
03523       // the following is an exampl call...
03524       //make_sph( point_list, tfacet_list, 100.0, "fem1-sph100.xyz" );
03525     }
03526 
03527     if (0)
03528     {
03529       // This is an example of using the export_facets function.  Writes
03530       // a facet file of all facets in the list
03531 
03532         //commented out because otherwise it's a compiler warning.
03533 
03534 //     char filename[128];
03535 //     strcpy(filename, "my_test.facets");
03536 //     export_facets(tfacet_list,filename);
03537     }
03538 
03539 
03540     // split the facets into shells if needed
03541 
03542     rv = FacetDataUtil::split_into_shells(tfacet_list, qfacet_list,
03543                                           shell_facet_list, is_water_tight);
03544     if (rv != CUBIT_SUCCESS)
03545     {
03546       PRINT_ERROR("Error processing facets from %s.\n", file_name);
03547       goto end_import_facets;
03548     }
03549 
03550     // if the facets aren't watertight, see if they can be merged
03551 
03552     if (!is_water_tight && stitch)
03553     {
03554       rv = FacetDataUtil::stitch_facets(shell_facet_list,
03555                                         GEOMETRY_RESABS,
03556                                         is_water_tight);
03557       if (rv != CUBIT_SUCCESS)
03558       {
03559         PRINT_WARNING("Couldn't stitch facets.\n");
03560       }
03561     }
03562 
03563     DLIList <CubitFacet *> *facet_list_ptr;
03564     if (improve)
03565     {
03566       for (ishell = 0; ishell < shell_facet_list.size(); ishell++)
03567       {
03568         facet_list_ptr = shell_facet_list.get_and_step();
03569         rv = FacetDataUtil::collapse_short_edges( *facet_list_ptr,  CUBIT_TRUE );
03570         if (rv != CUBIT_SUCCESS)
03571         {
03572           PRINT_WARNING("Couldn't improve facets.\n");
03573         }
03574       }
03575     }
03576     
03577     // check for consistent orientations on the facets for each shell
03578     
03579     for (ishell = 0; ishell < shell_facet_list.size(); ishell++)
03580     {
03581       facet_list_ptr = shell_facet_list.get_and_step();
03582       rv = ChollaEngine::check_all_facet_orientations(*facet_list_ptr,
03583                                                       CUBIT_TRUE);
03584       if (rv != CUBIT_SUCCESS)
03585       {
03586         PRINT_WARNING("Couldn't set consistent orientation for facets.\n");
03587       }
03588       // check to see that we have a positive enclosed volume (note this only works for 
03589       // a single shell.  Will need to do something else for multiple shells
03590       
03591       if (shell_facet_list.size() == 1)
03592       {
03593         double volume = FacetEvalTool::contained_volume(*facet_list_ptr);
03594         if (volume < 0.0)
03595         {
03596           FacetEvalTool::reverse_facets(*facet_list_ptr);
03597         }
03598       }
03599     }
03600 
03601     // create the surface geometry
03602 
03603     if (!use_feature_angle)
03604       feature_angle = -1.0;
03605 
03606     std::vector< std::vector<Surface*> > list_of_shells;
03607 
03608     for (ishell = 0; ishell < shell_facet_list.size(); ishell++)
03609     {
03610       DLIList <Surface *> shell_surfaces;
03611       DLIList <CubitPoint *> mypoint_list;
03612       facet_list_ptr = shell_facet_list.get_and_step();
03613       if(facet_list_ptr == NULL)
03614         rv = CUBIT_FAILURE;
03615       else
03616         rv = FacetModifyEngine::instance()->build_facet_surface( NULL,
03617                                *facet_list_ptr, mypoint_list,
03618                                feature_angle, interp_order,
03619                                smooth_non_manifold,
03620                                split_surfaces, shell_surfaces);
03621       if (rv != CUBIT_SUCCESS || shell_surfaces.size() == 0)
03622       {
03623         PRINT_ERROR("Couldn't build facet based geometry from facets in %s\n", file_name);
03624         rv = CUBIT_FAILURE;
03625         goto end_import_facets;
03626       }
03627 
03628       list_of_shells.push_back( shell_surfaces.as_vector() );
03629     }
03630     
03631     // make a shell out of these surfaces
03632     if( split_surfaces ) //make a shell for each and every surface
03633     {
03634       for( size_t k=0; k<list_of_shells.size(); k++ )
03635       {
03636         std::vector<Surface*> shell_surfaces = list_of_shells[k];
03637 
03638         for( size_t i=0; i<shell_surfaces.size(); i++ )
03639         {
03640           DLIList<Surface*> sheet_body_surfaces;
03641           sheet_body_surfaces.append( shell_surfaces[i] );
03642 
03643           rv = FacetModifyEngine::instance()->make_facet_shell(sheet_body_surfaces, shell_ptr);
03644           if ( shell_ptr == NULL || rv != CUBIT_SUCCESS )
03645           {
03646             PRINT_ERROR("Problems building facet based shell entity.\n");
03647             rv = CUBIT_FAILURE;
03648             goto end_import_facets;
03649           }
03650 
03651           //set the sense
03652           facet_shell = CAST_TO( shell_ptr, FacetShell );
03653           FacetSurface* facet_surf = CAST_TO( sheet_body_surfaces.get(), FacetSurface );
03654           facet_surf->set_shell_sense( facet_shell, CUBIT_FORWARD );          
03655 
03656           surface_list.append( sheet_body_surfaces.get() );
03657 
03658           shell_list.clean_out(); 
03659           shell_list.append( shell_ptr );
03660           rv = FacetModifyEngine::instance()->make_facet_lump(shell_list,lump_ptr);
03661           if ( lump_ptr == NULL || rv != CUBIT_SUCCESS )
03662           {
03663             PRINT_ERROR("Problems building facet based lump entity.\n");
03664             rv = CUBIT_FAILURE;
03665             goto end_import_facets;
03666           }
03667 
03668           lump_list.clean_out();
03669           lump_list.append(lump_ptr);
03670           rv = FacetModifyEngine::instance()->make_facet_body(lump_list,bodysm_ptr);
03671           body_ptr = GeometryQueryTool::instance()->make_Body(bodysm_ptr);
03672 
03673           if ( body_ptr == NULL || rv != CUBIT_SUCCESS )
03674           {
03675             PRINT_ERROR("Problems building facet based body entity.\n");
03676             rv = CUBIT_FAILURE;
03677             goto end_import_facets;
03678           }          
03679         }
03680       }
03681     }
03682     else //make a shell out of all these surfaces
03683     {
03684       for( size_t k=0; k<list_of_shells.size(); k++ )
03685       {
03686         DLIList<Surface*> shell_surfaces( list_of_shells[k] );        
03687 
03688         // make a shell out of these surfaces
03689         rv = FacetModifyEngine::instance()->make_facet_shell(shell_surfaces, shell_ptr);
03690         if ( shell_ptr == NULL || rv != CUBIT_SUCCESS )
03691         {
03692           PRINT_ERROR("Problems building facet based shell entity.\n");
03693           rv = CUBIT_FAILURE;
03694           goto end_import_facets;
03695         }
03696 
03697         //Set the sense for the surfaces (will be cofaces) on this shell.
03698         //Assumption: The sense is always forward when creating geom from facets.
03699         // (This may not be correct -especially with multiple shells in a body)
03700 
03701         facet_shell = CAST_TO( shell_ptr, FacetShell );
03702         for( ii = shell_surfaces.size(); ii > 0; ii-- )
03703         {
03704           Surface* surf = shell_surfaces.get_and_step();
03705           FacetSurface* facet_surf = CAST_TO( surf, FacetSurface );
03706           facet_surf->set_shell_sense( facet_shell, CUBIT_FORWARD );
03707         }
03708 
03709         surface_list += shell_surfaces;
03710         shell_list.append(shell_ptr);    
03711       }
03712 
03713       // make a body out of it
03714       rv = FacetModifyEngine::instance()->make_facet_lump(shell_list,lump_ptr);
03715       if ( lump_ptr == NULL || rv != CUBIT_SUCCESS )
03716       {
03717         PRINT_ERROR("Problems building facet based lump entity.\n");
03718         rv = CUBIT_FAILURE;
03719         goto end_import_facets;
03720       }
03721 
03722       lump_list.append(lump_ptr);
03723       rv = FacetModifyEngine::instance()->make_facet_body(lump_list,bodysm_ptr);
03724       body_ptr = GeometryQueryTool::instance()->make_Body(bodysm_ptr);
03725 
03726       if ( body_ptr == NULL || rv != CUBIT_SUCCESS )
03727       {
03728         PRINT_ERROR("Problems building facet based body entity.\n");
03729         rv = CUBIT_FAILURE;
03730         goto end_import_facets;
03731       }
03732     }
03733 
03734     if(gti->num_bodies() - prev_bod > 1)
03735          PRINT_INFO("Bodies successfully created.\n");
03736     else
03737        PRINT_INFO("Body successfully created.\n");
03738     PRINT_INFO("  Number of new vertices = %d\n", gti->num_ref_vertices() - prev_vert);
03739     PRINT_INFO("  Number of new curves = %d\n", gti->num_ref_edges() - prev_edge);
03740     PRINT_INFO("  Number of new surfaces = %d\n", gti->num_ref_faces() - prev_face);
03741     PRINT_INFO("  Number of new shells = %d\n", shell_facet_list.size());
03742     PRINT_INFO("  Number of new volumes = %d\n", gti->num_ref_volumes() - prev_vol);
03743     PRINT_INFO("  Number of new bodies = %d\n", gti->num_bodies() - prev_bod);
03744 
03745     if (!is_water_tight)
03746     {
03747       PRINT_WARNING("Volume generated does not completely close. 3D meshing (ie. hex/tet) will not be permitted.\n");
03748       PRINT_INFO("Hint: In some cases the \"stitch\" option on the import command may correct the problem.\n");
03749     }
03750   }  // end while ( stl_multiple_parts == true )
03751 
03752 end_import_facets:
03753   if (conn != NULL)
03754     delete [] conn;
03755   for (ii=0; ii<shell_list.size(); ii++)
03756     delete shell_facet_list.get_and_step();
03757 
03758   quad_facet_list = qfacet_list;
03759   tri_facet_list = tfacet_list;
03760   return rv;
03761 }
03762 
03763 
03764 
03765 //===========================================================================
03766 //Function Name: read_facets
03767 //Member Type:  PUBLIC
03768 //Description:  read facets from facet file
03769 //===========================================================================
03770 CubitStatus FacetQueryEngine::read_facets( const char * file_name,
03771                                            int *&conn,
03772                                            int &npoints,
03773                                            int &nquad, int &ntri,
03774                                            FacetFileFormat file_format )
03775 {
03776   // open the file
03777   FILE *fp = fopen(file_name, "r");
03778   if (fp == NULL)
03779   {
03780     PRINT_ERROR("Could not open file %s for reading\n", file_name);
03781     return CUBIT_FAILURE;
03782   }
03783 
03784   PRINT_INFO("Reading facets...\n");
03785 
03786   // read the number of nodes
03787 
03788   int id;
03789   int nfacets = 0;
03790   int iline = 1;
03791   char line[128];
03792   if (fgets(line, 128, fp) == NULL)
03793   {
03794     PRINT_ERROR("Format error in facet file %s on line %d\n", file_name, iline);
03795     fclose( fp );
03796     return CUBIT_FAILURE;
03797   }
03798 
03799   int n;
03800   char type_header[8];
03801   CubitBoolean is_off_file = CUBIT_FALSE;
03802   n = sscanf( line, "%s", type_header );
03803   if( !strcmp( type_header, "OFF" ) || 
03804       !strcmp( type_header, "off" ) )
03805   {
03806     PRINT_INFO( "Reading OFF file...\n" );
03807     iline++;
03808     if (fgets(line, 128, fp) == NULL) {
03809       PRINT_ERROR("Format error in facet file %s on line %d\n", file_name, iline);
03810       fclose( fp );
03811       return CUBIT_FAILURE;
03812     }
03813     is_off_file = CUBIT_TRUE;
03814   }
03815   
03816   n = sscanf(line, "%d %d", &npoints, &nfacets);
03817   if( !is_off_file )
03818   {
03819     if (n < 1 || ( n > 2 && file_format == CUBIT_FACET_FILE ) )
03820     {
03821       PRINT_ERROR("Format error in facet file %s on line %d\n", file_name, iline);
03822       fclose( fp );
03823       return CUBIT_FAILURE;
03824     }
03825   }
03826 
03827   if (npoints <= 0)
03828   {
03829     PRINT_ERROR("Expecting number of nodes in facet file %s on line %d\n", file_name, iline);
03830     fclose( fp );
03831     return CUBIT_FAILURE;
03832   }
03833   if (n==1)
03834   {
03835     nfacets = 0;
03836   }
03837   else if (nfacets <= 0)
03838   {
03839     PRINT_ERROR("Format error in facet file %s on line %d reading number of facets\n", file_name, iline);
03840     fclose( fp );
03841     return CUBIT_FAILURE;
03842   }
03843 
03844   if (init_hash_points( npoints ) == CUBIT_FAILURE)
03845   {
03846     PRINT_ERROR("Can't allocate memory for points in facet file %s on line %d\n", file_name, iline);
03847     fclose( fp );
03848     return CUBIT_FAILURE;
03849   }
03850 
03851   // read the nodes
03852 
03853   int ii;
03854   double xx, yy, zz;
03855   CubitPoint *new_point;
03856   for (ii=0; ii<npoints; ii++)
03857   {
03858     iline++;
03859     if (fgets(line, 128, fp)== NULL)
03860     {
03861       PRINT_ERROR("Format error in facet file %s on line %d\n", file_name, iline);
03862       fclose( fp );
03863       return CUBIT_FAILURE;
03864     }
03865     if( is_off_file )
03866     {
03867       n = sscanf( line, "%lf %lf %lf", &xx, &yy, &zz );
03868       id = ii;
03869       if (n != 3)
03870       {
03871         PRINT_ERROR("Format error in OFF file %s on line %d\n", file_name, iline);
03872         PRINT_INFO("  Expecting 3 doubles, but instead read %d values\n", n);
03873         fclose( fp );
03874         return CUBIT_FAILURE;
03875       }
03876     }
03877     else
03878     {
03879       n = sscanf(line, "%d %lf %lf %lf", &id, &xx, &yy, &zz );
03880       if (n != 4)
03881       {
03882         PRINT_ERROR("Format error in facet file %s on line %d\n", file_name, iline);
03883         PRINT_INFO("  Expecting 1 integer and 3 doubles, but instead read %d values\n", n);
03884         fclose( fp );
03885         return CUBIT_FAILURE;
03886       }
03887     }
03888     
03889     new_point = (CubitPoint *) new CubitPointData( xx, yy, zz );
03890     new_point->set_id( id );
03891     add_hash_point( new_point );
03892   }
03893 
03894     // read the number of facets
03895 
03896   if (nfacets == 0)
03897   {
03898     iline++;
03899     if (fgets(line, 128, fp) == NULL)
03900     {
03901       PRINT_ERROR("Format error in facet file %s on line %d reading number of facets\n", file_name, iline);
03902       fclose( fp );
03903       return CUBIT_FAILURE;
03904     }
03905 
03906     n = sscanf(line, "%d", &nfacets);
03907     if (n != 1)
03908     {
03909       PRINT_ERROR("Format error in facet file %s on line %d reading number of facets\n", file_name, iline);
03910       PRINT_INFO("  Expecting <num facets>\n");
03911       fclose( fp );
03912       return CUBIT_FAILURE;
03913     }
03914     if (nfacets <= 0)
03915     {
03916       PRINT_ERROR("Format error in facet file %s on line %d reading number of facets\n", file_name, iline);
03917       fclose( fp );
03918       return CUBIT_FAILURE;
03919     }
03920   }
03921 
03922   conn = new int [4*nfacets];
03923   if (!conn)
03924   {
03925     PRINT_ERROR("Can't allocate memory for facets in facet file %s on line %d\n", file_name, iline);
03926     fclose( fp );
03927     return CUBIT_FAILURE;
03928   }
03929   ntri = nquad = 0;
03930 
03931   // read the facets
03932 
03933   for (ii=0; ii<nfacets; ii++)
03934   {
03935     iline++;
03936     if (fgets(line, 128, fp) == NULL)
03937     {
03938       PRINT_ERROR("Format error in facet file %s on line %d\n", file_name, iline);
03939       fclose( fp );
03940       return CUBIT_FAILURE;
03941     }
03942 
03943     if( AVS_FILE == file_format )
03944     {
03945       n = sscanf( line, "%d %*d %*s %d %d %d %d", &id, &conn[4*ii],
03946                   &conn[4*ii+1], &conn[4*ii+2], &conn[4*ii+3] );
03947 
03948       if( n < 4 || n > 5 )
03949       {
03950         PRINT_ERROR("Format error in avs file %s on line %d reading facets\n", file_name, iline);
03951         PRINT_INFO("Expecting 6 or 7 values, but instead read %d values\n", n);
03952         fclose( fp );
03953         return CUBIT_FAILURE;
03954       }
03955 
03956         //duplicate the point
03957       if( n == 4 )
03958       {
03959         conn[4*ii+3] = conn[4*ii+2];
03960         ntri++;
03961       }
03962       else
03963       {
03964         nquad++;
03965       }
03966     }
03967     else
03968     {
03969 //       if( is_off_file )
03970 //       {
03971 //         n = sscanf( line, "%d %d %d %d", &id, &conn[4*ii], &conn[4*ii+1],
03972 //                     &conn[4*ii+2], &conn[4*ii+3] );
03973 //         if (n < 4 || n > 5)
03974 //         {
03975 //           PRINT_ERROR("Format error in OFF file %s on line %d reading facets\n", file_name, iline);
03976 //           PRINT_INFO("  Expecting 4 or 5 integers, but instead read %d values\n", n);
03977 //           PRINT_INFO("  For example:  <facet_size> <i0> <i1> <i2> [<i3>]\n");
03978 //           fclose( fp );
03979 //           return CUBIT_FAILURE;
03980 //         } 
03981 
03982 //           // for triangles -- duplicate the point
03983 // //        if( n==3 )
03984 //         if( id==3 )
03985 //         {
03986 //           conn[4*ii+3] = conn[4*ii+2];
03987 //           ntri++;
03988 //         }
03989 //         else
03990 //         {
03991 //           nquad++;
03992 //         }
03993 //       }
03994 //       else
03995 //       {
03996         n = sscanf(line, "%d %d %d %d %d", &id, &conn[4*ii], &conn[4*ii+1],
03997                    &conn[4*ii+2], &conn[4*ii+3] );
03998         
03999         if (n < 4 || n > 5)
04000         {
04001           PRINT_ERROR("Format error in facet file %s on line %d reading facets\n", file_name, iline);
04002           PRINT_INFO("  Expecting 4 or 5 integers, but instead read %d values\n", n);
04003           PRINT_INFO("  For example:  <id> <i0> <i1> <i2> [<i3>]\n");
04004           fclose( fp );
04005           return CUBIT_FAILURE;
04006         }
04007       
04008           // for triangles -- duplicate the point
04009         if (n==4)
04010         {
04011           conn[4*ii+3] = conn[4*ii+2];
04012           ntri++;
04013         }
04014         else
04015         {
04016           nquad++;
04017         }
04018 //       }
04019     }
04020   }
04021 
04022   fclose( fp );
04023   return CUBIT_SUCCESS;
04024 }
04025 
04026 //===========================================================================
04027 //  Function: read_cholla_file
04028 //  Purpose:  import the face mesh from the cholla file
04029 //  Date:     11/28/2002
04030 //  Author:   sjowen
04031 //===========================================================================
04032 CubitStatus FacetQueryEngine::read_cholla_file( const char *file_name,
04033                               double &feature_angle,
04034                               DLIList<CubitPoint *> &point_list,
04035                               DLIList<CubitFacet *> &facet_list )
04036 
04037 {
04038 
04039   double angle = 135.0;
04040   int num_tri = 0;
04041   int num_quad = 0;
04042   int num_edge = 0;
04043   int num_vert = 0;
04044   int* tri_edge = NULL;
04045   int* quad_edge = NULL;
04046   int* edge_vert = NULL;
04047   double* vert = NULL;
04048   double* edge_ctrl_pts = NULL;
04049   double* tri_ctrl_pts = NULL;
04050   double* quad_ctrl_pts = NULL;
04051   int results_included = 0;
04052 
04053   // importMesh and resolveFaceVectors are in Cholla.h
04054 
04055   importMesh(file_name, &results_included, &angle, &num_tri, &num_quad, &num_edge,
04056              &num_vert, &tri_edge, &quad_edge, &edge_vert, &vert,
04057              &edge_ctrl_pts, &tri_ctrl_pts, &quad_ctrl_pts);
04058 
04059   feature_angle = angle;
04060 
04061   // create the points
04062 
04063   CubitPoint **point_array = new CubitPoint * [num_vert];
04064   double x, y, z;
04065   int ii;
04066 
04067   for (ii=0; ii<num_vert; ii++)
04068   {
04069     x = vert[ii*3];
04070     y = vert[ii*3 + 1];
04071     z = vert[ii*3 + 2];
04072     point_array[ii] = (CubitPoint *) new CubitPointData( x, y, z );
04073     point_list.append( point_array[ii] );
04074   }
04075 
04076   // create the edges
04077 
04078   CubitFacetEdge **edge_array = new CubitFacetEdge * [num_edge];
04079   int ip, jp;
04080   for (ii=0; ii<num_edge; ii++)
04081   {
04082     ip = edge_vert[ii*2];
04083     jp = edge_vert[ii*2 + 1];
04084     assert(ip < num_vert && jp < num_vert && ip >= 0 && jp >= 0);
04085     edge_array[ii] = (CubitFacetEdge *) new CubitFacetEdgeData( point_array[ip],
04086                                                                 point_array[jp] );
04087   }
04088 
04089   // create the tri facets
04090 
04091   int begin_face;
04092   int jj, iedge;
04093   CubitFacetEdge *edges[4];
04094   CubitFacet *facet_ptr = NULL;
04095   CubitQuadFacet *qfacet_ptr = NULL;
04096   for (ii=0; ii<num_tri; ii++)
04097   {
04098     begin_face = 3 * ii;
04099     for(jj=0; jj<3; jj++)
04100     {
04101       iedge = tri_edge[begin_face+jj];
04102       edges[jj] = edge_array[iedge];
04103     }
04104     facet_ptr = (CubitFacet *)
04105       new CubitFacetData(edges[0], edges[1], edges[2]);
04106     facet_list.append(facet_ptr);
04107   }
04108 
04109   // create the quad facets
04110 
04111   for (ii=0; ii<num_quad; ii++)
04112   {
04113     begin_face = 4 * ii;
04114     for(jj=0; jj<4; jj++)
04115     {
04116       iedge = quad_edge[begin_face+jj];
04117       edges[jj] = edge_array[iedge];
04118     }
04119     qfacet_ptr = (CubitQuadFacet *)
04120       new CubitQuadFacetData(edges[0], edges[1], edges[2], edges[3]);
04121     facet_list.append(qfacet_ptr->get_tri_facet(0));
04122     facet_list.append(qfacet_ptr->get_tri_facet(1));
04123   }
04124 
04125   // delete the temp arrays
04126 
04127   delete [] point_array;
04128   delete [] edge_array;
04129   delete [] tri_edge;
04130   delete [] quad_edge;
04131   delete [] edge_vert;
04132   delete [] vert;
04133   delete [] edge_ctrl_pts;
04134   delete [] tri_ctrl_pts;
04135   delete [] quad_ctrl_pts;
04136 
04137   return CUBIT_SUCCESS;
04138 }
04139 
04140 
04141 //===========================================================================
04142 //Function Name: is_close
04143 //
04144 //Member Type:  PRIVATE
04145 //Description:  determine if one of the facets in the list is within a
04146 //              certain distance of the point.
04147 //===========================================================================
04148 CubitBoolean
04149 FacetQueryEngine::is_close(CubitVector &this_point,
04150                               DLIList<CubitFacet *>&facet_list,
04151                               CubitFacet *&lastFacet,
04152                               double tol)
04153 {
04154   CubitBoolean isclose = CUBIT_FALSE;
04155   CubitBox bbox;
04156   CubitVector close_point;
04157   CubitFacet *facet;
04158   int ii;
04159 
04160   // set the first facet to be checked as the last one located
04161 
04162   if (lastFacet) {
04163     if (!facet_list.move_to(lastFacet)) {
04164       facet_list.reset();
04165     }
04166   }
04167   else {
04168     facet_list.reset();
04169   }
04170 
04171   CubitBoolean done = CUBIT_FALSE;
04172 
04173   // define a bounding box around the point
04174 
04175   CubitVector ptmin( this_point.x() - tol,
04176                          this_point.y() - tol,
04177                                this_point.z() - tol );
04178     CubitVector ptmax( this_point.x() + tol,
04179                          this_point.y() + tol,
04180                                this_point.z() + tol );
04181 
04182   for ( ii = facet_list.size(); ii > 0 && !done; ii-- ) {
04183       facet = facet_list.get_and_step();
04184 
04185     // Try to trivially reject this facet with a bounding box test
04186 
04187       bbox = facet->bounding_box();
04188       if (ptmax.x() < bbox.minimum().x() ||
04189             ptmin.x() > bbox.maximum().x()) {
04190       continue;
04191     }
04192     if (ptmax.y() < bbox.minimum().y() ||
04193             ptmin.y() > bbox.maximum().y()) {
04194       continue;
04195     }
04196     if (ptmax.z() < bbox.minimum().z() ||
04197             ptmin.z() > bbox.maximum().z()) {
04198       continue;
04199     }
04200 
04201     // Only facets that pass the bounding box test will get past here!
04202 
04203     // Project point to plane of the facet and determine its area coordinates
04204 
04205     CubitVector pt_on_plane;
04206     double dist_to_plane;
04207     FacetEvalTool::project_to_facet_plane( facet, this_point, pt_on_plane, dist_to_plane );
04208 
04209     CubitVector areacoord;
04210     FacetEvalTool::facet_area_coordinate( facet, pt_on_plane, areacoord );
04211 
04212     // If sign of areacoords are all positive then its inside the triangle
04213     // and we are done - go interpolate the point. (use an absolute
04214     // tolerance since the coordinates arenormalized)
04215 
04216     if (areacoord.x() > -GEOMETRY_RESABS &&
04217         areacoord.y() > -GEOMETRY_RESABS &&
04218         areacoord.z() > -GEOMETRY_RESABS) {
04219       FacetEvalTool::eval_facet( facet, areacoord, &close_point, NULL );
04220     }
04221 
04222     // otherwise find the closest vertex or edge to the projected point
04223 
04224     else if (areacoord.x() < GEOMETRY_RESABS) {
04225       if (areacoord.y() < GEOMETRY_RESABS) {
04226         FacetEvalTool::eval_point( facet, 2, close_point );
04227       }
04228       else if(areacoord.z() < GEOMETRY_RESABS) {
04229         FacetEvalTool::eval_point( facet, 1, close_point );
04230       }
04231       else {
04232         FacetEvalTool::eval_edge( facet, 1, 2, pt_on_plane, close_point );
04233       }
04234     }
04235     else if (areacoord.y() < GEOMETRY_RESABS) {
04236       if (areacoord.z() < GEOMETRY_RESABS) {
04237         FacetEvalTool::eval_point( facet, 0, close_point );
04238       }
04239       else {
04240         FacetEvalTool::eval_edge( facet, 2, 0, pt_on_plane, close_point);
04241       }
04242     }
04243     else {
04244       FacetEvalTool::eval_edge( facet, 0, 1, pt_on_plane, close_point );
04245     }
04246 
04247     // keep track of the minimum distance
04248 
04249     double dist = sqrt(FacetEvalToolUtils::sqr(close_point.x() - this_point.x()) +
04250                        FacetEvalToolUtils::sqr(close_point.y() - this_point.y()) +
04251                        FacetEvalToolUtils::sqr(close_point.z() - this_point.z()));
04252     if (dist <= tol) {
04253       done = CUBIT_TRUE;
04254       isclose = CUBIT_TRUE;
04255       lastFacet = facet;
04256     }
04257     }
04258   return isclose;
04259 }
04260 
04261 
04262 
04263 
04264 //=============================================================================
04265 // Function Name: export_facets
04266 // Member Type:  PUBLIC
04267 // Description:  export a list of facets to a facet file for debugging purposes
04268 // Author: sjowen
04269 // Date: 10/29/01
04270 //=============================================================================
04271 CubitStatus FacetQueryEngine::export_facets(DLIList<CubitFacet*> &facet_list,
04272                                                char *filename)
04273 {
04274 
04275   // open the file for writing
04276 
04277   FILE *fp = fopen(filename, "w");
04278   if (!fp)
04279   {
04280     PRINT_ERROR("Couldn't open file %s for writing.\n", filename);
04281     return CUBIT_FAILURE;
04282   }
04283 
04284   // make list of all points
04285 
04286   CubitPoint *point_ptr;
04287   CubitFacet *facet_ptr;
04288   DLIList<CubitPoint*>temp_point_list;
04289   int ii, jj;
04290   for (ii=0; ii<facet_list.size(); ii++)
04291   {
04292     facet_ptr = facet_list.get_and_step();
04293     for(jj=0; jj<3; jj++)
04294     {
04295       point_ptr = facet_ptr->point(jj);
04296       point_ptr->marked(-1);
04297       temp_point_list.append(point_ptr);
04298     }
04299   }
04300 
04301   // assign ids to points and make list unique
04302 
04303   int id = 0;
04304   DLIList<CubitPoint*>point_list;
04305   for (ii=0; ii<temp_point_list.size(); ii++)
04306   {
04307     point_ptr = temp_point_list.get_and_step();
04308     if (point_ptr->marked() == -1)
04309     {
04310       point_ptr->marked(id++);
04311       point_list.append( point_ptr );
04312     }
04313   }
04314 
04315   // write the points
04316 
04317   CubitVector coords;
04318   fprintf(fp, "%d\n", point_list.size());
04319   point_list.reset();
04320   for(ii=0; ii<point_list.size(); ii++)
04321   {
04322     point_ptr = point_list.get_and_step();
04323     coords = point_ptr->coordinates();
04324     fprintf(fp,"%d %f %f %f\n", ii, coords.x(), coords.y(), coords.z());
04325   }
04326 
04327   // write the facets
04328 
04329   int indx[3];
04330   fprintf(fp, "%d\n", facet_list.size());
04331   for (ii=0; ii<facet_list.size(); ii++)
04332   {
04333     facet_ptr = facet_list.get_and_step();
04334     for (jj=0; jj<3; jj++)
04335     {
04336       indx[jj] = facet_ptr->point(jj)->marked();
04337     }
04338     fprintf(fp,"%d %d %d %d\n", ii, indx[0], indx[1], indx[2]);
04339   }
04340 
04341   //- unmark the points
04342 
04343   for (ii=0; ii<point_list.size(); ii++)
04344     point_list.get_and_step()->marked(0);
04345 
04346   fclose(fp);
04347   return CUBIT_SUCCESS;
04348 }
04349 
04350 //=============================================================================
04351 //Function:  init_hash_point (PRIVATE)
04352 //Description: create a hash array of all points.  They are hashed based on the
04353 //             id of the point
04354 //Author: sjowen
04355 //Date: 4/3/01
04356 //=============================================================================
04357 CubitStatus FacetQueryEngine::init_hash_points( int num_points )
04358 {
04359   /* === find the next highest prime number */
04360 
04361   hashPointSize = num_points / 10;
04362   int i;
04363   if (hashPointSize < 13) hashPointSize = 13;
04364   else
04365   {
04366     i=2;
04367     while (i<hashPointSize*0.5 + 1) {
04368       if (hashPointSize % i == 0) {
04369         i=2;
04370         hashPointSize++;
04371       }
04372       else {
04373         i++;
04374       }
04375     }
04376   }
04377   hashPointArray = new DLIList<CubitPoint*>[hashPointSize];
04378 
04379   return CUBIT_SUCCESS;
04380 }
04381 
04382 //=============================================================================
04383 //Function:  add_hash_point (PRIVATE)
04384 //Description: hash the point into the hash table
04385 //Author: sjowen
04386 //Date: 4/3/02
04387 //=============================================================================
04388 CubitStatus FacetQueryEngine::add_hash_point( CubitPoint *point_ptr )
04389 {
04390   int id = point_ptr->id();
04391   int key = get_hash_key( id );
04392   hashPointArray[key].append( point_ptr );
04393   return CUBIT_SUCCESS;
04394 }
04395 
04396 //=============================================================================
04397 //Function:  get_hash_point (PRIVATE)
04398 //Description: retreive the CubitPoint pointer from the id
04399 //Author: sjowen
04400 //Date: 4/3/02
04401 //=============================================================================
04402 CubitPoint *FacetQueryEngine::get_hash_point( int id )
04403 {
04404   int key = get_hash_key( id );
04405   int ii;
04406   int found = 0;
04407   CubitPoint *point_ptr;
04408   for (ii=0; ii<hashPointArray[key].size() && !found; ii++)
04409   {
04410     point_ptr = hashPointArray[key].get_and_step();
04411     if (point_ptr->id() == id)
04412     {
04413       return point_ptr;
04414     }
04415   }
04416   return (CubitPoint*)NULL;
04417 }
04418 
04419 //=============================================================================
04420 //Function:  delete_hash_points (PRIVATE)
04421 //Description: delete the hash points stuff
04422 //Author: sjowen
04423 //Date: 4/3/02
04424 //=============================================================================
04425 void FacetQueryEngine::delete_hash_points( )
04426 {
04427   if (hashPointArray)
04428    delete [] hashPointArray;
04429   hashPointArray = NULL;
04430   hashPointSize = 0;
04431 }
04432 
04433 //=============================================================================
04434 //Function:  get_hash_key (PRIVATE)
04435 //Description:
04436 //Author: sjowen
04437 //Date: 4/3/02
04438 //=============================================================================
04439 int FacetQueryEngine::get_hash_key( int id )
04440 {
04441   int key = id % hashPointSize;
04442   return key;
04443 }
04444 
04445 //===========================================================================
04446 //Function Name: get_all_hash_points
04447 //Member Type:  PUBLIC
04448 //Description:  makes a single list from all points in the hash table
04449 //===========================================================================
04450 CubitStatus FacetQueryEngine::get_all_hash_points(
04451   DLIList<CubitPoint *> &point_list ) // return point list
04452 {
04453   CubitStatus rv = CUBIT_SUCCESS;
04454 
04455   int ii, jj;
04456   CubitPoint *point_ptr;
04457   for(jj=0; jj<hashPointSize; jj++)
04458   {
04459     for (ii=0; ii<hashPointArray[jj].size(); ii++)
04460     {
04461       point_ptr = hashPointArray[jj].get_and_step();
04462       point_list.append(point_ptr);
04463     }
04464   }
04465 
04466   return rv;
04467 }
04468 
04469 //===========================================================================
04470 //Function Name: save_facets
04471 //Member Type:  PUBLIC
04472 //Description:  save the facets from the entities to a Cubit file
04473 //Author:       sjowen
04474 //Date:         1/16/2003
04475 //===========================================================================
04476 CubitStatus FacetQueryEngine::save_facets(
04477   FILE *fp,  // file we are dumping to
04478   DLIList<FacetSurface*> facet_surfaces,
04479   DLIList<FacetCurve*> facet_curves,
04480   DLIList<FacetPoint*> facet_points ) // save facets from these entities
04481 {
04482   CubitStatus rv = CUBIT_SUCCESS;
04483 
04484   DLIList<CubitFacet *> facet_list;
04485   DLIList<CubitFacetEdge *> edge_list;
04486   DLIList<CubitPoint *> point_list;
04487 
04488   // get a unique list of all facets, edges and points
04489   rv = gather_facets(facet_surfaces, facet_curves, facet_points,
04490                      facet_list, edge_list, point_list );
04491 
04492   if (rv != CUBIT_SUCCESS)
04493     return rv;
04494 
04495   // dump the facet entities the file
04496 
04497   rv = dump_facets( fp, facet_list, edge_list, point_list );
04498   if (rv != CUBIT_SUCCESS)
04499     return rv;
04500 
04501   // dump the CurveFacetEvalTools and FacetEval Tools
04502   rv = save_eval_tools( fp, facet_surfaces, facet_curves );
04503 
04504   return rv;
04505 }
04506 
04507 //===========================================================================
04508 //Function Name: save_eval_tools
04509 //Member Type:  PUBLIC
04510 //Description:  go through the RefEntities and save the CurveFacetEvalTools
04511 //              and FacetEvalTools.  These are essentially lists of facets
04512 //              that are owned by the curve or surface
04513 //Authors:      sjowen & cdernst
04514 //Date:         1/21/2003
04515 //===========================================================================
04516 CubitStatus FacetQueryEngine::save_eval_tools(
04517   FILE *fp,        // cubit file we are dumping to
04518   DLIList<FacetSurface*> facet_surfaces,
04519   DLIList<FacetCurve*>  facet_curves )
04520 {
04521 
04522   int ii;
04523   FacetSurface *fsurf_ptr;
04524   FacetCurve *fcurv_ptr;
04525 
04526   //separate out eval tools and set ids
04527   DLIList<CurveFacetEvalTool*> cfe_tools;
04528   DLIList<FacetEvalTool*> fe_tools;
04529   int ft_id = 0;
04530   int cft_id = 0;
04531 
04532   facet_surfaces.reset();
04533   for (ii=facet_surfaces.size(); ii--; )
04534   {
04535     fsurf_ptr = facet_surfaces.get_and_step();
04536     FacetEvalTool *feval_tool = fsurf_ptr->get_eval_tool();
04537     if( feval_tool )
04538     {
04539       feval_tool->set_output_id( ft_id++ );
04540       fe_tools.append( feval_tool );
04541     }
04542   }
04543 
04544   facet_curves.reset();
04545   for (ii=facet_curves.size(); ii--; )
04546   {
04547     fcurv_ptr = facet_curves.get_and_step();
04548     CurveFacetEvalTool *ceval_tool = fcurv_ptr->get_eval_tool();
04549     if( ceval_tool )
04550     {
04551       ceval_tool->set_output_id( cft_id++ );
04552       cfe_tools.append( ceval_tool );
04553     }
04554   }
04555 
04556   //Write out number of FacetEvalTools
04557   int count = fe_tools.size();
04558   NCubitFile::CIOWrapper cio(fp);
04559   cio.Write( reinterpret_cast<UnsignedInt32*>(&count), 1 );
04560 
04561   //Write out each FacetEvalTool
04562   fe_tools.reset();
04563   for( ii=0; ii<fe_tools.size(); ii++)
04564   {
04565     FacetEvalTool *feval_tool = fe_tools.get_and_step();
04566     feval_tool->save( fp );
04567   }
04568 
04569   //Write out number of CurveFacetEvalTools
04570   count = cfe_tools.size();
04571   cio.Write( reinterpret_cast<UnsignedInt32*>(&count), 1 );
04572 
04573   //Write out each CurveFacetEvalTool
04574   cfe_tools.reset();
04575   for( ii=0; ii<cfe_tools.size(); ii++)
04576   {
04577     CurveFacetEvalTool *ceval_tool = cfe_tools.get_and_step();
04578     ceval_tool->save( fp );
04579   }
04580 
04581   return CUBIT_SUCCESS;
04582 }
04583 
04584 //===============================================================================
04585 // Function   : restore_eval_tools
04586 // Member Type: PUBLIC
04587 // Description: restore the curve and surface eval tools
04588 // Author     : sjowen
04589 // Date       : 1/26/03
04590 //===============================================================================
04591 CubitStatus FacetQueryEngine::restore_eval_tools(
04592   FILE *fp,  // CUB file we are currently reading
04593   unsigned int endian,
04594   int num_facets, // list of facet entities already read from the CUB file
04595   int num_edges,  // that we will assign to the eval tools.  Index into
04596   int num_points, // the array is the same as ID
04597   CubitFacet **facets,
04598   CubitFacetEdge **edges,
04599   CubitPoint **points,
04600   int &num_cfet,
04601   int &num_fet,
04602   CurveFacetEvalTool **&cfeval_tools,
04603   FacetEvalTool **&feval_tools)   // return list of curve and surface tools
04604 {
04605   NCubitFile::CIOWrapper cio(endian, fp);
04606 
04607   int ii;
04608   FacetEvalTool *fsurf_ptr;
04609   CurveFacetEvalTool *fcurv_ptr;
04610 
04611   // read the number of facet eval tools
04612   // we are about to read from the CUB file
04613   cio.Read(reinterpret_cast<UnsignedInt32*>(&num_fet), 1);
04614 
04615   feval_tools = new FacetEvalTool *[num_fet];
04616 
04617   // read all the facet surface eval tools
04618 
04619   for (ii=0; ii<num_fet; ii++)
04620   {
04621     /*
04622     // read the topo ID from the CUB file.  This will be stored as the
04623     // FacetEvalTool toolID and serve as the means to associate this
04624     // eval tool with it's topology entity
04625     UnsignedInt32 surf_id = 0;
04626     cio.Read(&surf_id, 1);
04627     int topo_id = (int)surf_id; */
04628 
04629     // read the facet eval tool data and create the tool
04630     fsurf_ptr  = new FacetEvalTool();
04631     fsurf_ptr->restore(fp, endian, num_facets,
04632                        num_edges, num_points,
04633                        facets, edges, points);
04634     if (fsurf_ptr == NULL)
04635     {
04636       PRINT_ERROR("Error restoring mesh-based geometry\n");
04637       return CUBIT_FAILURE;
04638     }
04639     feval_tools[ii] = fsurf_ptr;
04640   }
04641 
04642   // read the number of curves
04643   cio.Read(reinterpret_cast<UnsignedInt32*>(&num_cfet), 1);
04644   cfeval_tools = new CurveFacetEvalTool *[num_cfet];
04645 
04646   // read all the curve facet eval tools.  Same thing as surfaces
04647 
04648   for (ii=0; ii<num_cfet; ii++)
04649   {
04650     // read the facet eval tool data and create the tool
04651     fcurv_ptr = new CurveFacetEvalTool();
04652     fcurv_ptr->restore(fp, endian, num_edges, num_points,
04653                        edges, points, num_fet, feval_tools );
04654     if (fcurv_ptr == NULL)
04655     {
04656       PRINT_ERROR("Error restoring mesh-based geometry\n");
04657       return CUBIT_FAILURE;
04658     }
04659 
04660     cfeval_tools[ii] = fcurv_ptr;
04661   }
04662 
04663   return CUBIT_SUCCESS;
04664 }
04665 
04666 
04667 //===========================================================================
04668 //Function Name: dump_facets
04669 //Member Type:  PUBLIC
04670 //Description:  dump the facets and associated data to the cubit file
04671 //Authors:      sjowen & cdernst
04672 //Date:         1/16/2003
04673 //===========================================================================
04674 CubitStatus FacetQueryEngine::dump_facets(
04675   FILE *fp,                          // file we are dumping to
04676   DLIList<CubitFacet *> &facet_list,  // return unique list of facets
04677   DLIList<CubitFacetEdge *> &edge_list,  // return unique list of edges
04678   DLIList<CubitPoint *> &point_list )  // return unique list of points
04679 {
04680 
04681   NCubitFile::CIOWrapper cio(fp);
04682   typedef NCubitFile::UnsignedInt32 UnsignedInt32;
04683 
04684   // Gather CubitPoint Data
04685   int npoints = point_list.size();
04686   int nnormals = 0;
04687   double* uvs_array = new double [npoints * 3];
04688   double* coord_array  = new double [npoints * 3];
04689   //double* du_array = new double [npoints * 3];
04690   //double* dv_array = new double [npoints * 3];
04691   int c_zero_points = 0;
04692   int c_zero_int_data_size = 0;
04693   int c_zero_double_data_size = 0;
04694   int ii;
04695   DLIList<CubitPoint*> has_td_boundary_point;
04696   DLIList<CubitPoint*> points_with_normal;
04697 
04698   TDFacetBoundaryPoint *td_fbp;
04699   CubitPoint *cp_ptr;
04700   CubitVector coord, *normal;
04701   point_list.reset();
04702   for (ii=0; ii<point_list.size(); ii++)
04703   {
04704     cp_ptr = point_list.get_and_step();
04705 
04706     // write out uVal, vVal, sizeVal
04707     uvs_array[ii*3] = cp_ptr->u();
04708     uvs_array[ii*3+1] = cp_ptr->v();
04709     uvs_array[ii*3+2] = cp_ptr->size();
04710     // coordinates
04711     coord = cp_ptr->coordinates();
04712     coord_array[ii*3]   = coord.x();
04713     coord_array[ii*3+1] = coord.y();
04714     coord_array[ii*3+2] = coord.z();
04715     // surfNormal
04716     if( cp_ptr->normal_ptr() )
04717       points_with_normal.append( cp_ptr );
04718 
04719     /*
04720     // surfU
04721     du = cp_ptr->du();
04722     du_array[ii*3]   = du.x();
04723     du_array[ii*3+1] = du.y();
04724     du_array[ii*3+2] = du.z();
04725     // surfV
04726     dv = cp_ptr->dv();
04727     dv_array[ii*3]   = dv.x();
04728     dv_array[ii*3+1] = dv.y();
04729     dv_array[ii*3+2] = dv.z(); */
04730 
04731     if ((td_fbp = TDFacetBoundaryPoint::get_facet_boundary_point( cp_ptr ))!= NULL)
04732     {
04733       has_td_boundary_point.append( cp_ptr );
04734       c_zero_points++;
04735       td_fbp->get_boundary_point_data_size( c_zero_int_data_size,
04736                                             c_zero_double_data_size );
04737     }
04738   }
04739 
04740   // Normals
04741   nnormals = points_with_normal.size();
04742   double* normal_array = NULL;
04743   int* normal_ids = NULL;
04744   points_with_normal.reset();
04745   if( nnormals > 0 )
04746   {
04747     normal_array = new double [nnormals* 3];
04748     normal_ids = new int[nnormals];
04749     points_with_normal.reset();
04750     for( ii=0; ii<nnormals; ii++)
04751     {
04752       cp_ptr = points_with_normal.get_and_step();
04753       normal_ids[ii] = cp_ptr->id();
04754       normal = cp_ptr->normal_ptr();
04755       normal_array[ii*3]   = normal->x();
04756       normal_array[ii*3+1] = normal->y();
04757       normal_array[ii*3+2] = normal->z();
04758     }
04759   }
04760 
04761   // write arrays  --CubitPoint
04762   cio.Write(reinterpret_cast<UnsignedInt32*>(&npoints), 1);
04763   if( npoints > 0 )
04764   {
04765     cio.Write(coord_array, npoints*3);
04766     cio.Write(uvs_array, npoints*3);
04767   }
04768 
04769   // clean up
04770   delete [] uvs_array;
04771   delete [] coord_array;
04772   uvs_array = NULL;
04773   coord_array = NULL;
04774 
04775   // write normals & ids of points to which normals belong
04776   cio.Write( reinterpret_cast<UnsignedInt32*>(&nnormals), 1 );
04777   if( nnormals > 0 )
04778   {
04779     cio.Write(normal_array, nnormals*3);
04780     cio.Write(reinterpret_cast<UnsignedInt32*>(normal_ids), nnormals);
04781     delete [] normal_array;
04782     delete [] normal_ids;
04783     normal_array = NULL;
04784     normal_ids = NULL;
04785   }
04786 
04787   // Gather CubitFacetEdge Data
04788   int jj, idx;
04789   int nedges = edge_list.size();
04790   int nctrl_pts = nedges * NUM_EDGE_CPTS;
04791   CubitFacetEdge *edge_ptr;
04792   CubitVector *edge_ctrl_pts;
04793   double* control_points = new double [nctrl_pts * 3];
04794   UnsignedInt32* edge_vert_array = new UnsignedInt32 [nedges * 2];
04795   for(ii=0; ii<nedges; ii++)
04796   {
04797     // pointArray[2]
04798     edge_ptr = edge_list.get_and_step();
04799     edge_vert_array[ii*2] = edge_ptr->point(0)->id();
04800     edge_vert_array[ii*2+1] = edge_ptr->point(1)->id();
04801     edge_ctrl_pts = edge_ptr->control_points();
04802 
04803     // controlPoints[3]
04804     if (nctrl_pts > 0)
04805     {
04806       if (!edge_ctrl_pts)
04807       {
04808         nctrl_pts = 0;
04809         continue;
04810       }
04811       for(jj=0; jj<NUM_EDGE_CPTS; jj++)
04812       {
04813         idx = (ii*NUM_EDGE_CPTS+jj)*3;
04814         control_points[idx]   = edge_ctrl_pts[jj].x();
04815         control_points[idx+1] = edge_ctrl_pts[jj].y();
04816         control_points[idx+2] = edge_ctrl_pts[jj].z();
04817       }
04818     }
04819   }
04820 
04821   // write arrays  --CubitFacetEdge
04822   cio.Write(reinterpret_cast<UnsignedInt32*>(&nedges), 1);
04823   if( nedges > 0 )
04824   {
04825     cio.Write(edge_vert_array, nedges*2 );
04826     cio.Write(reinterpret_cast<UnsignedInt32*>(&nctrl_pts), 1);
04827     if (nctrl_pts > 0)
04828       cio.Write(control_points, nctrl_pts*3);
04829   }
04830 
04831   // clean up
04832   delete [] edge_vert_array;
04833   delete [] control_points;
04834   edge_vert_array = NULL;
04835   control_points = NULL;
04836 
04837   // Gather CubitFacet Data
04838   int nfacets = facet_list.size();
04839   nctrl_pts = nfacets * NUM_TRI_CPTS;
04840   CubitFacet *facet_ptr;
04841   CubitVector *facet_ctrl_pts;
04842   control_points = new double [nctrl_pts * 3];
04843   UnsignedInt32* facet_edge_array = new UnsignedInt32 [nfacets * 3];
04844   int *int_data = new int[ nfacets * 2 ];
04845   facet_list.reset();
04846   for (ii=0; ii<nfacets; ii++)
04847   {
04848     facet_ptr = facet_list.get_and_step();
04849 
04850     // is Flat and isBackwards
04851     int_data[ii*2] = facet_ptr->is_flat();
04852     int_data[ii*2+1] = facet_ptr->is_backwards();
04853 
04854     // edgeArray[3]
04855     facet_edge_array[ii*3]   = facet_ptr->edge(0)->id();
04856     facet_edge_array[ii*3+1] = facet_ptr->edge(1)->id();
04857     facet_edge_array[ii*3+2] = facet_ptr->edge(2)->id();
04858     facet_ctrl_pts = facet_ptr->control_points();
04859     if(nctrl_pts > 0)
04860     {
04861       if (!facet_ctrl_pts)
04862       {
04863         nctrl_pts = 0;
04864         continue;
04865       }
04866       for(jj=0; jj<NUM_TRI_CPTS; jj++)
04867       {
04868         idx = (ii*NUM_TRI_CPTS+jj)*3;
04869         control_points[idx]   = facet_ctrl_pts[jj].x();
04870         control_points[idx+1] = facet_ctrl_pts[jj].y();
04871         control_points[idx+2] = facet_ctrl_pts[jj].z();
04872       }
04873     }
04874   }
04875 
04876   // write arrays  --CubitFacet
04877   cio.Write(reinterpret_cast<UnsignedInt32*>(&nfacets), 1);
04878   if( nfacets > 0 )
04879   {
04880     cio.Write(facet_edge_array, nfacets*3);
04881     cio.Write( reinterpret_cast<UnsignedInt32*>(int_data), nfacets*2 );
04882     cio.Write(reinterpret_cast<UnsignedInt32*>(&nctrl_pts), 1);
04883     if (nctrl_pts > 0)
04884       cio.Write(control_points, nctrl_pts*3);
04885   }
04886 
04887   // clean up
04888   delete [] facet_edge_array;
04889   delete [] control_points;
04890   delete [] int_data;
04891   facet_edge_array = NULL;
04892   control_points = NULL;
04893   int_data = NULL;
04894 
04895 
04896   // At points along the boundary (C0 continuity) there may be
04897   // multiple normals.  Write this data too.  First gether it
04898   // into two arrays and then dump.
04899 
04900   cio.Write(reinterpret_cast<UnsignedInt32*>(&c_zero_points), 1);
04901   if (c_zero_points > 0)
04902   {
04903     int *c_zero_int_data = new int [c_zero_int_data_size];
04904     double *c_zero_double_data = new double [c_zero_double_data_size];
04905     point_list.reset();
04906     int iidx = 0;
04907     int didx = 0;
04908     point_list.reset();
04909     for (ii=0; ii<point_list.size(); ii++)
04910     {
04911       cp_ptr = point_list.get_and_step();
04912       td_fbp = TDFacetBoundaryPoint::get_facet_boundary_point( cp_ptr );
04913       if (td_fbp != NULL)
04914       {
04915         td_fbp->get_boundary_point_data( c_zero_int_data,
04916                                          c_zero_double_data,
04917                                          iidx, didx );
04918       }
04919     }
04920 
04921     // dump the int data array
04922 
04923     cio.Write(reinterpret_cast<UnsignedInt32*>(&c_zero_int_data_size), 1);
04924     //convert to UnsignedInt32
04925     UnsignedInt32 *c_zero_int32_data = new UnsignedInt32 [c_zero_int_data_size];
04926     for (ii=0; ii<c_zero_int_data_size; ii++)
04927       c_zero_int32_data[ii] = (UnsignedInt32)c_zero_int_data[ii];
04928     cio.Write(c_zero_int32_data, c_zero_int_data_size);
04929 
04930     // dump the double array
04931 
04932     cio.Write(reinterpret_cast<UnsignedInt32*>(&c_zero_double_data_size), 1);
04933     cio.Write(c_zero_double_data, c_zero_double_data_size);
04934 
04935     // clean up
04936     delete [] c_zero_int_data;
04937     delete [] c_zero_int32_data;
04938     delete [] c_zero_double_data;
04939   }
04940 
04941   return CUBIT_SUCCESS;
04942 }
04943 
04944 //===========================================================================
04945 //Function Name: gather_facets
04946 //Member Type:  PUBLIC
04947 //Description:  get a unique list of facets from the entities
04948 //Author:       sjowen
04949 //Date:         1/16/2003
04950 //===========================================================================
04951 CubitStatus FacetQueryEngine::gather_facets(
04952   DLIList<FacetSurface *> facet_surfaces,
04953   DLIList<FacetCurve *> facet_curves,
04954   DLIList<FacetPoint *> facet_points,
04955   DLIList<CubitFacet *> &facet_list,  // return unique list of facets
04956   DLIList<CubitFacetEdge *> &edge_list,  // return unique list of edges
04957   DLIList<CubitPoint *> &point_list)   // return unique list of points
04958 {
04959   int ii, jj, kk;
04960   FacetSurface *fsurf_ptr;
04961   FacetCurve *fcurv_ptr;
04962   FacetPoint *fpoint_ptr;
04963   DLIList<CubitFacet *>temp_facets;
04964   DLIList<CubitPoint *>temp_points;
04965   DLIList<CubitFacetEdge *>temp_edges;
04966 
04967   CubitFacet *facet_ptr;
04968   CubitFacetEdge *edge_ptr;
04969   CubitPoint *cp_ptr;
04970 
04971   //unmark facets/edges/points on surface
04972   for(ii=facet_surfaces.size(); ii--;)
04973   {
04974     fsurf_ptr = facet_surfaces.get_and_step();
04975     temp_facets.clean_out();
04976     temp_points.clean_out();
04977     fsurf_ptr->get_my_facets(temp_facets, temp_points);
04978     for(jj=0; jj<temp_facets.size(); jj++)
04979     {
04980       facet_ptr = temp_facets.get_and_step();
04981       facet_ptr->marked( 0 );
04982       for (kk=0; kk<3; kk++)
04983       {
04984         edge_ptr = facet_ptr->edge( kk );
04985         edge_ptr->marked( 0 );
04986       }
04987     }
04988     for (jj=0; jj<temp_points.size(); jj++)
04989     {
04990       cp_ptr = temp_points.get_and_step();
04991       cp_ptr->marked( 0 );
04992     }
04993   }
04994 
04995   //unmark facet-edges/points on curves
04996   for(ii=facet_curves.size(); ii--; )
04997   {
04998     fcurv_ptr = facet_curves.get_and_step();
04999     temp_edges.clean_out();
05000     fcurv_ptr->get_facets( temp_edges );
05001     for (jj=0; jj<temp_edges.size(); jj++)
05002     {
05003       edge_ptr = temp_edges.get_and_step();
05004       edge_ptr->marked( 0 );
05005       edge_ptr->point( 0 )->marked( 0 );
05006       edge_ptr->point( 1 )->marked( 0 );
05007     }
05008   }
05009 
05010   //unmark facet-points on points
05011   for(ii=facet_points.size(); ii--; )
05012   {
05013     fpoint_ptr = facet_points.get_and_step();
05014     if (fpoint_ptr != NULL)
05015     {
05016       cp_ptr = fpoint_ptr->get_cubit_point();
05017       cp_ptr->marked( 0 );
05018     }
05019   }
05020 
05021 
05022   // make unique lists
05023   for(ii=facet_surfaces.size(); ii--;)
05024   {
05025     fsurf_ptr = facet_surfaces.get_and_step();
05026     temp_facets.clean_out();
05027     temp_points.clean_out();
05028     fsurf_ptr->get_my_facets(temp_facets, temp_points);
05029     for(jj=0; jj<temp_facets.size(); jj++)
05030     {
05031       facet_ptr = temp_facets.get_and_step();
05032       if (0 == facet_ptr->marked())
05033       {
05034         facet_ptr->marked( 1 );
05035         facet_list.append( facet_ptr );
05036       }
05037       for (kk=0; kk<3; kk++)
05038       {
05039         edge_ptr = facet_ptr->edge( kk );
05040         if (0 == edge_ptr->marked())
05041         {
05042           edge_ptr->marked( 1 );
05043           edge_list.append( edge_ptr );
05044         }
05045       }
05046     }
05047     for (jj=0; jj<temp_points.size(); jj++)
05048     {
05049       cp_ptr = temp_points.get_and_step();
05050       if (0 == cp_ptr->marked())
05051       {
05052         cp_ptr->marked(1);
05053         point_list.append( cp_ptr );
05054       }
05055     }
05056   }
05057 
05058   for(ii=facet_curves.size(); ii--;)
05059   {
05060     fcurv_ptr = facet_curves.get_and_step();
05061     temp_edges.clean_out();
05062     fcurv_ptr->get_facets( temp_edges );
05063     for (jj=0; jj<temp_edges.size(); jj++)
05064     {
05065       edge_ptr = temp_edges.get_and_step();
05066       if (0 == edge_ptr->marked())
05067       {
05068         edge_ptr->marked(1);
05069         edge_list.append( edge_ptr );
05070         for (kk=0; kk<2; kk++)
05071         {
05072           cp_ptr = edge_ptr->point( kk );
05073           if (0 == cp_ptr->marked())
05074           {
05075             cp_ptr->marked(1);
05076             point_list.append(cp_ptr);
05077           }
05078         }
05079       }
05080     }
05081   }
05082 
05083   for(ii=facet_points.size(); ii--;)
05084   {
05085     fpoint_ptr = facet_points.get_and_step();
05086     cp_ptr = fpoint_ptr->get_cubit_point();
05087     if (0 == cp_ptr->marked())
05088     {
05089       cp_ptr->marked( 1 );
05090       point_list.append( cp_ptr );
05091     }
05092   }
05093 
05094   // set the IDs of the facet entities and clear the marks
05095   facet_list.reset();
05096   for (ii=0; ii<facet_list.size(); ii++)
05097   {
05098     facet_ptr = facet_list.get_and_step();
05099     facet_ptr->set_id(ii);
05100     facet_ptr->marked(0);
05101   }
05102   edge_list.reset();
05103   for (ii=0; ii<edge_list.size(); ii++)
05104   {
05105     edge_ptr = edge_list.get_and_step();
05106     edge_ptr->set_id(ii);
05107     edge_ptr->marked(0);
05108   }
05109   for (ii=0; ii<point_list.size(); ii++)
05110   {
05111     cp_ptr = point_list.get_and_step();
05112     cp_ptr->set_id(ii);
05113     cp_ptr->marked(0);
05114   }
05115 
05116   return CUBIT_SUCCESS;
05117 }
05118 
05119 //=============================================================================
05120 //Function:   create_super_facet_bounding_box(PUBLIC)
05121 //Description: Find the bounding box of a list of BodySMs
05122 //Author: jdfowle
05123 //Date: 12/15/03
05124 //=============================================================================
05125 CubitStatus FacetQueryEngine::create_super_facet_bounding_box(
05126                                 DLIList<BodySM*>& body_list,
05127                                 CubitBox& super_box )
05128 {
05129 BodySM *bodySM;
05130 int i;
05131 CubitStatus status = CUBIT_SUCCESS;
05132 
05133   body_list.reset();
05134   for ( i = 0; i < body_list.size(); i++ ) {
05135     bodySM = body_list.get_and_step();  
05136     create_facet_bounding_box(bodySM,super_box);
05137   }
05138 
05139   return status;
05140 }
05141 
05142 //=============================================================================
05143 //Function:   create_facet_bounding_box(PUBLIC)
05144 //Description: Find the bounding box of a BodySM
05145 //Author: jdfowle
05146 //Date: 12/15/03
05147 //=============================================================================
05148 CubitStatus FacetQueryEngine::create_facet_bounding_box(
05149                                 BodySM* bodySM,
05150                                 CubitBox& bbox )
05151 {
05152   FacetBody *fbody_ptr;
05153   int j;
05154   DLIList<FacetSurface*> facet_surf_list;
05155   DLIList<CubitFacet*> facet_list;
05156   DLIList<CubitPoint*> point_list;
05157   FacetSurface *facet_surface;
05158   CubitBox surf_bbox, total_box;
05159   CubitStatus status = CUBIT_FAILURE;
05160 
05161     fbody_ptr = dynamic_cast<FacetBody *>(bodySM);
05162     fbody_ptr->get_surfaces(facet_surf_list);
05163     for ( j = 0; j < facet_surf_list.size(); j++ ) {
05164       facet_surface = facet_surf_list.get_and_step();
05165       facet_list.clean_out();
05166       point_list.clean_out();
05167       facet_surface->get_my_facets(facet_list,point_list);
05168       status = FacetDataUtil::get_bbox_of_points(point_list,surf_bbox);
05169 
05170       if ( j == 0 ) 
05171         total_box = surf_bbox;
05172       else 
05173         total_box |= surf_bbox;
05174     }
05175   bbox = total_box;  
05176 
05177   return status;
05178 }
05179 
05180 const char* fqe_xform_err = "Transform not implemented for facet geometry.\n";
05181 CubitStatus FacetQueryEngine::restore_transform( BodySM* body )
05182 {
05183   FacetBody* facetbod = dynamic_cast<FacetBody*>(body);
05184   return facetbod ? facetbod->restore( ) : CUBIT_FAILURE;
05185 }
05186 CubitStatus FacetQueryEngine::translate( BodySM* body, const CubitVector& d )
05187 {
05188   FacetBody* facetbod = dynamic_cast<FacetBody*>(body);
05189   return facetbod ? facetbod->move( d.x(), d.y(), d.z() ) : CUBIT_FAILURE;
05190 }
05191 CubitStatus FacetQueryEngine::rotate( BodySM* body, const CubitVector& v, double a )
05192 {
05193   FacetBody* facetbod = dynamic_cast<FacetBody*>(body);
05194   return facetbod ? facetbod->rotate( v.x(), v.y(), v.z(), a ) : CUBIT_FAILURE;
05195 }
05196 CubitStatus FacetQueryEngine::scale( BodySM* body, double factor )
05197 {
05198   FacetBody* facetbod = dynamic_cast<FacetBody*>(body);
05199   return facetbod ? facetbod->scale( factor ) : CUBIT_FAILURE;
05200 }
05201 CubitStatus FacetQueryEngine::scale( BodySM* body, const CubitVector& f )
05202 {
05203   FacetBody* facetbod = dynamic_cast<FacetBody*>(body);
05204   return facetbod ? facetbod->scale( f.x(), f.y(), f.z() ) : CUBIT_FAILURE;
05205 }
05206 
05207 CubitStatus FacetQueryEngine::translate( GeometryEntity* , const CubitVector&  )
05208 {
05209   PRINT_ERROR("%s", fqe_xform_err);
05210   return CUBIT_FAILURE;
05211 }
05212 CubitStatus FacetQueryEngine::rotate( GeometryEntity* , const CubitVector& , double  )
05213 {
05214   PRINT_ERROR("%s", fqe_xform_err);
05215   return CUBIT_FAILURE;
05216 }
05217 CubitStatus FacetQueryEngine::scale( GeometryEntity* , double  )
05218 {
05219   PRINT_ERROR("%s", fqe_xform_err);
05220   return CUBIT_FAILURE;
05221 }
05222 CubitStatus FacetQueryEngine::scale( GeometryEntity* , const CubitVector&  )
05223 {
05224   PRINT_ERROR("%s", fqe_xform_err);
05225   return CUBIT_FAILURE;
05226 }
05227 CubitStatus FacetQueryEngine::reflect( GeometryEntity* , const CubitVector&  )
05228 {
05229   PRINT_ERROR("%s", fqe_xform_err);
05230   return CUBIT_FAILURE;
05231 }
05232 
05233 
05234 
05235 
05236 //===============================================================================
05237 // Function   : bodies_overlap
05238 // Member Type: PUBLIC
05239 // Description: determine if facet-based bodies overlap
05240 // Author     : John Fowler
05241 // Date       : 10/02
05242 //===============================================================================
05243 CubitBoolean FacetQueryEngine::bodies_overlap (BodySM * /*body_ptr_1*/,
05244                                                 BodySM * /*body_ptr_2*/ ) const
05245 {
05246   PRINT_ERROR("Currently, Cubit is unable to determine overlap for Facet-based geometry.\n");
05247   return CUBIT_FALSE;
05248     //The following should work, but due to bug 5599, we are not
05249     // using it.  Having this code in the default would cause the
05250     // GeometryPowerTool to rely on Facetbool, which isn't robust
05251     // yet.
05252     /*
05253 FacetboolInterface *fbint;
05254 CubitFacetboolOp op = CUBIT_FB_INTERSECTION;
05255 bool keep_old = true;
05256 CubitStatus status;
05257 BodySM* body_out = 0;
05258 bool intersection_found;
05259 
05260   fbint = new FacetboolInterface;  
05261   status = fbint->dofacetboolean_2bodies(body_ptr_1,body_ptr_2,body_out,
05262                                        keep_old,intersection_found,op);
05263   if ( status == CUBIT_FAILURE ) return CUBIT_FALSE;
05264   else return CUBIT_TRUE;
05265     */
05266 }
05267 
05268 CubitBoolean FacetQueryEngine::volumes_overlap (Lump * /*lump_ptr_1*/,
05269                                                 Lump * /*lump_ptr_2*/ ) const
05270 {
05271   PRINT_ERROR("Currently, Cubit is unable to determine overlap for Facet-based geometry.\n");
05272   return CUBIT_FALSE;
05273 }
05274 
05275 CubitStatus FacetQueryEngine::get_point_containment( DLIList<BodySM*> &bodysm_list,
05276                                      DLIList<CubitVector> &point_list,
05277                                      double tolerance,
05278                                      bool allow_pts_in_multiple_bodies,
05279                                      std::vector< std::pair<BodySM*, std::vector<int> > > &bodysm_to_pt_indices )
05280 {  
05281   //convert all the BodySMs into FacetBodies
05282   DLIList<FacetBody*> body_list;
05283   for( int k=bodysm_list.size(); k--; )
05284   {
05285     BodySM *body_sm = bodysm_list.get_and_step();
05286     FacetBody *facet_body = dynamic_cast<FacetBody*>(body_sm);
05287     if( !facet_body )
05288       return CUBIT_FAILURE;
05289     body_list.append( facet_body );
05290   }
05291   
05292   //stuff all the points into the atree
05293   AbstractTree<ContainmentPoint*> *atree = new RTree<ContainmentPoint*>( tolerance );
05294     
05295   std::vector<ContainmentPoint*> atree_nodes;
05296   int num_points = point_list.size();
05297   for( int i=0; i<num_points; i++ )
05298   {
05299     ContainmentPoint *tmp_pt = new ContainmentPoint();
05300     tmp_pt->pt_coordinates = &(point_list[i]);
05301     tmp_pt->index = i;  
05302     atree->add( tmp_pt );
05303     atree_nodes.push_back( tmp_pt );
05304   }
05305 
05306   int num_bodies = body_list.size();
05307 
05308   if( num_bodies > 10 )
05309   {
05310     char message[128];
05311     sprintf(message, "Point containment routine: %d points %d volumes.", num_points, num_bodies );
05312     AppUtil::instance()->progress_tool()->start(0, num_bodies,
05313       "Progress", message, TRUE, TRUE );
05314   }
05315     
05316   //for each body
05317   //get the points in the bbox of the body
05318   for( int i=0; i<body_list.size(); i++ )
05319   {
05320     FacetBody *facet_body = body_list[i];
05321     CubitBox cubit_box = facet_body->bounding_box();
05322     
05323     double range_ratio = cubit_box.maximum_range() / cubit_box.minimum_range();
05324      
05325     //find the points in the bounding box
05326     DLIList<ContainmentPoint*> close_pts;
05327     atree->find( cubit_box, close_pts );
05328  
05329     std::vector<int> pts_in_body;
05330 
05331   
05332     //if( 0 ) // old ray-shooting
05333     //if( 1 ) // new octree
05334     if( range_ratio < CUTOFF_BBOX_RANGE_RATIO && (close_pts.size() > CUTOFF_NUM_NODES /*pow( pow(2, CUTOFF_OCTREE_DEPTH), 3) */ ) ) // smart
05335       
05336     { 
05337       // build octree
05338       RefEntity* ref_ent = dynamic_cast<RefEntity*>( facet_body->topology_entity() );
05339       DLIList<RefEntity*> ref_entity_list;
05340       ref_entity_list.insert( ref_ent );
05341       CubitOctreeGeneratorVolumes octree_generator( ref_entity_list);
05342       octree_generator.generate_full_octree();
05343       
05344       for( int k=0; k<close_pts.size(); k++ )
05345       {
05346         //ask each point if it is in the body
05347         CubitVector tmp_vec = *(close_pts[k]->pt_coordinates); 
05348         
05349         CubitPointContainment pt_cont;
05350         pt_cont = octree_generator.point_containment( tmp_vec, tolerance );
05351         switch( pt_cont )
05352         {
05353           case CUBIT_PNT_INSIDE:
05354             if( false == allow_pts_in_multiple_bodies )
05355               atree->remove( close_pts[k] );
05356             pts_in_body.push_back( close_pts[k]->index );
05357             //GfxDebug::draw_point(tmp_vec.x(), tmp_vec.y(), tmp_vec.z(), CUBIT_BLUE_INDEX);
05358             //PRINT_INFO(" INSIDE ");
05359             break;
05360             
05361           case CUBIT_PNT_BOUNDARY:
05362             pt_cont = facet_body->point_containment( tmp_vec, tolerance );
05363             if( CUBIT_PNT_INSIDE == pt_cont || CUBIT_PNT_BOUNDARY == pt_cont )
05364             {
05365               if( false == allow_pts_in_multiple_bodies )
05366                 atree->remove( close_pts[k] );
05367               pts_in_body.push_back( close_pts[k]->index );
05368             }
05369             //GfxDebug::draw_point(tmp_vec.x(), tmp_vec.y(), tmp_vec.z(), CUBIT_GREEN_INDEX);
05370             //PRINT_INFO(" BOUNDARY ");
05371             break;
05372           
05373           case CUBIT_PNT_OUTSIDE:
05374             // do nothing
05375             //GfxDebug::draw_point(tmp_vec.x(), tmp_vec.y(), tmp_vec.z(), CUBIT_RED_INDEX);
05376             //PRINT_INFO(" OUTSIDE ");
05377             break;
05378             
05379           default:
05380             break;
05381         }
05382       }
05383     }
05384     else {
05385       for( int k=0; k<close_pts.size(); k++ )
05386       {
05387         //ask each point if it is in the body
05388         CubitVector tmp_vec = *(close_pts[k]->pt_coordinates); 
05389         CubitPointContainment pt_cont = facet_body->point_containment( tmp_vec, tolerance );      
05390         if( CUBIT_PNT_INSIDE == pt_cont || CUBIT_PNT_BOUNDARY == pt_cont )
05391         {        
05392           if( false == allow_pts_in_multiple_bodies )
05393             atree->remove( close_pts[k] );
05394           pts_in_body.push_back( close_pts[k]->index );
05395         }
05396       }
05397     }
05398     
05399     if( num_bodies > 10 )
05400       AppUtil::instance()->progress_tool()->step();
05401 
05402     if(AppUtil::instance()->interrupt()) 
05403     {
05404        if( num_bodies > 10 )
05405          AppUtil::instance()->progress_tool()->end();
05406 
05407       //clean up
05408        while( atree_nodes.size() )
05409        {
05410          delete atree_nodes.back();
05411          atree_nodes.pop_back();
05412        }
05413       delete atree;      
05414       return CUBIT_FAILURE;
05415     }
05416 
05417     bodysm_to_pt_indices.push_back( std::make_pair( bodysm_list[i], pts_in_body ) );
05418   } 
05419 
05420   //cleanup 
05421   while( atree_nodes.size() )
05422   {
05423     delete atree_nodes.back();
05424     atree_nodes.pop_back();
05425   }
05426   delete atree;
05427 
05428   if( num_bodies > 10 )
05429     AppUtil::instance()->progress_tool()->end();
05430 
05431   return CUBIT_SUCCESS;
05432 }
05433 
05434 
05435 //EOF
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines