cgma
iGeom_CGMA.cc
Go to the documentation of this file.
00001 
00023 #include "InitCGMA.hpp"
00024 #include "GMem.hpp"
00025 #include <iostream>
00026 #include <limits>
00027 #include <math.h>
00028 #include "GeometryQueryTool.hpp"
00029 #include "CubitCompat.hpp"
00030 #include "CCubitFile.hpp"
00031 
00032 #include "cgm/CGMConfig.h"
00033 
00034 
00035 #ifdef ITAPS_SHIM
00036 # include "iGeom_private.h"
00037 # include "iGeom_binding.h"
00038 # include "CGM_iGeom.h"
00039 # define ITAPS_API static
00040 #else
00041 # include "iGeom.h"
00042 # define ITAPS_API
00043 #endif
00044 
00045 const bool debug = false;
00046 
00047 #define RETURN(a) do {CGM_iGeom_setLastError((*err = a)); return; } while(false)
00048 #define ERROR(a, b) do {CGM_iGeom_setLastError((*err = a), b); return; } while(false)
00049 
00050 #define ARRAY_IN(b) \
00051   b, b ## _size  
00052 
00053 #define ARRAY_INOUT(b) \
00054   b, b ## _allocated, b ## _size  
00055 
00056 // Check the array size, and allocate the array if necessary.
00057 // Free the array upon leaving scope unless KEEP_ARRAY
00058 // is invoked.
00059 #define ALLOC_CHECK_ARRAY(array, this_size) \
00060   iGeomArrayManager array ## _manager ( reinterpret_cast<void**>(array), *(array ## _allocated), *(array ## _size), this_size, sizeof(**array), err ); \
00061   if (iBase_SUCCESS != *err) return
00062 
00063 #define KEEP_ARRAY(array) \
00064   array ## _manager .keep_array()
00065 
00066 // Check the array size, and allocate the array if necessary.
00067 // Do NOT free the array upon leaving scope.
00068 #define ALLOC_CHECK_ARRAY_NOFAIL(array, this_size) \
00069   ALLOC_CHECK_ARRAY(array, this_size); KEEP_ARRAY(array)
00070 
00071 #define TAG_HANDLE(handle) reinterpret_cast<long>(handle)
00072 
00073 #define ENTITY_HANDLE(handle) reinterpret_cast<RefEntity*>(handle)
00074 #define SET_HANDLE(handle) reinterpret_cast<RefGroup*>(handle)
00075 
00076 #define ENTITY_HANDLE_ARRAY(array) reinterpret_cast<RefEntity**>(array)
00077 #define SET_HANDLE_ARRAY(array) reinterpret_cast<RefGroup**>(array)
00078 
00079 #define ENTITY_HANDLE_CONST_ARRAY(array) reinterpret_cast<RefEntity* const*>(array)
00080 #define SET_HANDLE_CONST_ARRAY(array) reinterpret_cast<RefGroup* const*>(array)
00081 
00082 #define ENTITY_HANDLE_ARRAY_PTR(array) reinterpret_cast<RefEntity***>(array)
00083 #define SET_HANDLE_ARRAY_PTR(array) reinterpret_cast<RefGroup***>(array)
00084 
00085 #define CAST_TO_VOID(ptr) reinterpret_cast<void*>(ptr)
00086 #define TAG_HANDLE_ARRAY_INOUT(a) reinterpret_cast<long**>(a), a ## _allocated, a ## _size
00087 
00088 #define TM reinterpret_cast<CGMTagManager*>(instance)
00089 
00090 const double RAD_TO_DEG = 180.0 / acos(-1.0);
00091 const double DEG_TO_RAD = 1.0 / RAD_TO_DEG;
00092 
00093 #include "CATag.hpp"
00094 #include "CGMAIterator.hpp"
00095 #include "iGeomError.h"
00096 
00097 #include "RefEntityFactory.hpp"
00098 #include "BasicTopologyEntity.hpp"
00099 #include "RefGroup.hpp"
00100 #include "Body.hpp"
00101 #include "RefVertex.hpp"
00102 #include "RefEdge.hpp"
00103 #include "RefFace.hpp"
00104 #include "RefVolume.hpp"
00105 #include "CubitVector.hpp"
00106 
00107 #ifdef USE_MPI
00108 #include "CGMReadParallel.hpp"
00109 #endif
00110 
00111 #include "CGMApp.hpp"
00112 #include "GeometryModifyTool.hpp"
00113 #include "Surface.hpp"
00114 #include "BasicTopologyEntity.hpp"
00115 #include "CubitFile.hpp"
00116 #include "CubitDefines.h"
00117 #include "MergeTool.hpp"
00118 #include "GeometryDefines.h"
00119 
00120 #define gqt GeometryQueryTool::instance()
00121 #define gmt GeometryModifyTool::instance()
00122 
00123 const char *iGeom_entity_type_names[] = {"vertex", "curve", "surface", "body"};
00124 const char *cgm_type_names[] = {"vertex", "curve", "surface", "volume", "body"};
00125 
00126 // Implement RAII pattern for allocated arrays
00127 class iGeomArrayManager
00128 {
00129   void** arrayPtr;
00130 
00131 public:
00132 
00133 
00134   iGeomArrayManager( void** array_ptr,
00135                      int& array_allocated_space,
00136                      int& array_size,
00137                      int count,
00138                      int val_size,
00139                      int* err ) : arrayPtr(0)
00140   {
00141     if (!*array_ptr) {
00142       *array_ptr = malloc(val_size * count);
00143       array_allocated_space = array_size = count;
00144       if (!*array_ptr) {
00145         ERROR(iBase_MEMORY_ALLOCATION_FAILED, "Couldn't allocate array.");
00146       }
00147       arrayPtr = array_ptr;
00148     }
00149     else {
00150       array_size = count;
00151       if (array_allocated_space < count) {
00152         ERROR(iBase_BAD_ARRAY_DIMENSION, 
00153           "Allocated array not large enough to hold returned contents.");
00154       }
00155     }
00156     RETURN(iBase_SUCCESS);
00157   }
00158   
00159   ~iGeomArrayManager() 
00160   {
00161     if (arrayPtr) {
00162       free(*arrayPtr);
00163       *arrayPtr = 0;
00164     }
00165   }
00166   
00167   void keep_array()
00168     { arrayPtr = 0; }
00169 };
00170 
00171 
00172 // declare private-type functions here, so they aren't visible outside
00173 // this implementation file
00174 
00175 /* Helper functions 
00176  * Declare these outside the 'extern "C"' block because they are not
00177  * extern.
00178  */
00179 static void
00180 iGeom_get_adjacent_entities( const RefEntity *from, 
00181                              const int to_dim,
00182                              DLIList<RefEntity*> &adj_ents,
00183                              int* err);
00184 
00185 static void tokenize( const std::string& str, 
00186                       std::vector<std::string>& tokens );
00187 
00188 // Expect option of the form "NAME=VALUE".
00189 // If NAME portion matches, pass back VALUE and return true.
00190 // Otherwise, leave 'value' unchanged and return false.
00191 static bool match_option( const std::string& opt,
00192                           const char* name,
00193                           std::string& value );
00194                           
00195 static void
00196 iGeom_load_cub_geometry(const char *name, int* err) ;
00197 
00198 static iBase_ErrorType 
00199 process_attribs(iGeom_Instance instance, DLIList<RefEntity*> &ref_list) ;
00200 
00201 static void
00202 iGeom_get_adjacent_entities( const RefEntity *from, 
00203                              const int to_dim,
00204                              DLIList<RefEntity*> &adj_ents,
00205                              int* err ) ;
00206 /* Common implementation for both single-entity and array functions. */
00207 static CubitStatus iGeom_closest_point( RefEntity* this_entity,
00208                                         const CubitVector& near,
00209                                         CubitVector& on );
00210 
00211 static CubitStatus iGeom_closest_point_trimmed( RefEntity* this_entity,
00212                                         const CubitVector& near,
00213                                         CubitVector& on );
00214 
00215 static CubitStatus
00216 iGeom_closest_point_and_normal( RefEntity* this_entity, 
00217                                 const CubitVector& near,
00218                                 CubitVector& on,
00219                                 CubitVector& normal );
00220 static CubitStatus
00221 iGeom_bounding_box( RefEntity* entity, CubitVector& minc, CubitVector& maxc );
00222 
00224 /*
00225 static inline void box_min_max( double dir,
00226                                 double min,
00227                                 double max,
00228                                 double pt,
00229                                 double& tmin,
00230                                 double& tmax );
00231 */
00232 /*
00233 static bool
00234 iBase_intersect_ray_box( const CubitBox& box,
00235                          const CubitVector& point,
00236                          const CubitVector& direction );
00237 */
00238 
00239 static CubitStatus
00240 iGeom_fire_ray( const CubitVector& point,
00241                 const CubitVector& direction,
00242                 DLIList<RefEntity*>& entities,
00243                 DLIList<double>& ray_params );
00244 
00245 static RefEntity*
00246 iGeom_get_point_containment( const CubitVector& pt );
00247 
00248 static int iGeom_get_nonmanifold_sense( const BasicTopologyEntity* child,
00249                                         const BasicTopologyEntity* parent,
00250                                         int* err );
00251 
00252 static
00253 int iGeom_edge_vertex_sense( const RefEdge* cedge,
00254                              const RefVertex* vtx1,
00255                              const RefVertex* vtx2,
00256                              int* err );
00257 
00258 static int iGeom_is_parametric( RefEntity* entity );
00259 
00260 static iBase_ErrorType
00261 iGeom_get_vtx_to_u(RefVertex* vertex, RefEdge* edge, double& u);
00262 
00263 static iBase_ErrorType
00264 iGeom_get_vtx_to_uv(RefVertex* vertex, RefFace* face, double& u, double& uv);
00265 
00266 
00267 static CubitStatus
00268 iGeom_normal_from_uv( RefFace* face, double u, double v, CubitVector& normal );
00269 
00270 static CubitStatus iGeom_is_periodic( RefEntity* entity, int& u, int& v );
00271 
00272 static bool iGeom_is_face_degenerate( RefFace* face );
00273 
00274 static
00275 int count_ibase_type( int ibase_type, 
00276                       const DLIList<CubitEntity*>& list, 
00277                       int* err );
00278 
00279 static 
00280 void copy_ibase_type( int ibase_type, 
00281                       const DLIList<CubitEntity*>& list,
00282                       iBase_EntityHandle** entity_handles,
00283                       int* entity_handles_alloc,
00284                       int* entity_handles_size,
00285                       int* err );
00286 
00287 static 
00288 void append_ibase_type( int ibase_type, 
00289                         const DLIList<CubitEntity*>& source_list,
00290                         DLIList<RefEntity*>& target_list,
00291                         int* err );
00292 static 
00293 void append_all_ibase_type( int ibase_type, 
00294                             DLIList<RefEntity*>& target_list,
00295                             int* err );
00296 
00297 /*
00298 static
00299 CubitStatus iGeom_get_graphics(RefFace* face, 
00300                                DLIList<CubitVector*>& point_list,
00301                                DLIList<int>& facet_list,
00302                                double normal_tolerance = 15.0,
00303                                double distance_tolerance = 0.0,
00304                                double longest_edge = 0.0) ;
00305 
00306 static
00307 CubitStatus iGeom_get_graphics(RefEdge* edge,
00308                                DLIList<CubitVector*>& point_list,
00309                                DLIList<int>& facet_list,
00310                                double angle_tolerance = 0.0,
00311                                double distance_tolerance=0.0 ) ;
00312 
00313 static CubitStatus iGeom_get_graphics(RefFace* face,
00314                                DLIList<CubitVector*>& point_list,
00315                                DLIList<int>& facet_list,
00316                                double normal_tolerance, 
00317                                double distance_tolerance,
00318                                double longest_edge)
00319 {
00320   CubitStatus status = CUBIT_SUCCESS;
00321   GMem facets;
00322   face->get_graphics(facets, normal_tolerance, distance_tolerance, longest_edge);
00323   int num_points = 0, num_facets = 0;
00324   num_points = facets.point_list_size();
00325   num_facets = facets.facet_list_size();
00326   GPoint* points = facets.point_list();
00327   int*  facet_array = facets.facet_list();
00328   for(int i = 0; i < num_points; i++)
00329   {
00330     CubitVector point(points[i].x, points[i].y, points[i].z);
00331     point_list.append(&point);
00332   }
00333   for(int i = 0; i < num_facets; i++)
00334     facet_list.append(facet_array[i]);
00335   return status;
00336 }
00337 
00338 static CubitStatus iGeom_get_graphics(RefEdge* edge,
00339                                DLIList<CubitVector*>& point_list,
00340                                DLIList<int>& facet_list,
00341                                double angle_tolerance,
00342                                double distance_tolerance )
00343 {
00344   CubitStatus status = CUBIT_SUCCESS;
00345   GMem facets;
00346   edge->get_graphics(facets, angle_tolerance, distance_tolerance);
00347   int num_points = 0, num_facets = 0;
00348   num_points = facets.point_list_size();
00349   num_facets = facets.facet_list_size();
00350   GPoint* points = facets.point_list();
00351   int*  facet_array = facets.facet_list();
00352   for(int i = 0; i < num_points; i++)
00353   {
00354     CubitVector point(points[i].x, points[i].y, points[i].z);
00355     point_list.append(&point);
00356   }
00357   for(int i = 0; i < num_facets; i++)
00358     facet_list.append(facet_array[i]);
00359   return status;
00360 }
00361 */
00362 
00363 static CubitStatus init_cgm( const std::string& engine )
00364 {
00365   CubitStatus status = CUBIT_SUCCESS;
00366   if (engine.empty())
00367     status = InitCGMA::initialize_cgma();
00368   else
00369     status = InitCGMA::initialize_cgma( engine.c_str() );
00370  
00371 // sometimes can't have following, depending on CGM version
00372   // CGMApp::instance()->attrib_manager()->silent_flag(true);
00373 
00374   CGMApp::instance()->attrib_manager()->auto_flag(true);
00375   
00376   return status;
00377 }
00378 
00379 extern "C" {
00380 
00381 #ifdef ITAPS_SHIM
00382 static struct iGeom_vtable CGM_iGeom_vtable = {
00383   iGeom_getDescription,
00384   iGeom_getErrorType,
00385   iGeom_dtor,
00386   iGeom_load,
00387   iGeom_save,
00388   iGeom_getRootSet,
00389   iGeom_getBoundBox,
00390   iGeom_getEntities,
00391   iGeom_getNumOfType,
00392   iGeom_getEntType,
00393   iGeom_getArrType,
00394   iGeom_getEntAdj,
00395   iGeom_getArrAdj,
00396   iGeom_getEnt2ndAdj,
00397   iGeom_getArr2ndAdj,
00398   iGeom_isEntAdj,
00399   iGeom_isArrAdj,
00400   iGeom_getTopoLevel,
00401   iGeom_getEntClosestPt,
00402   iGeom_getEntClosestPtTrimmed,
00403   iGeom_getArrClosestPt,
00404   iGeom_getEntNrmlXYZ,
00405   iGeom_getArrNrmlXYZ,
00406   iGeom_getEntNrmlPlXYZ,
00407   iGeom_getArrNrmlPlXYZ,
00408   iGeom_getEntTgntXYZ,
00409   iGeom_getArrTgntXYZ,
00410   iGeom_getFcCvtrXYZ,
00411   iGeom_getEgCvtrXYZ,
00412   iGeom_getEntArrCvtrXYZ,
00413   iGeom_getEgEvalXYZ,
00414   iGeom_getFcEvalXYZ,
00415   iGeom_getArrEgEvalXYZ,
00416   iGeom_getArrFcEvalXYZ,
00417   iGeom_getEntBoundBox,
00418   iGeom_getArrBoundBox,
00419   iGeom_getVtxCoord,
00420   iGeom_getVtxArrCoords,
00421   iGeom_getPntRayIntsct,
00422   iGeom_getPntArrRayIntsct,
00423   iGeom_getPntClsf,
00424   iGeom_getPntArrClsf,
00425   iGeom_getEntNrmlSense,
00426   iGeom_getArrNrmlSense,
00427   iGeom_getEgFcSense,
00428   iGeom_getEgFcArrSense,
00429   iGeom_getEgVtxSense,
00430   iGeom_getEgVtxArrSense,
00431   iGeom_measure,
00432   iGeom_getFaceType,
00433   iGeom_getParametric,
00434   iGeom_isEntParametric,
00435   iGeom_isArrParametric,
00436   iGeom_getEntUVtoXYZ,
00437   iGeom_getArrUVtoXYZ,
00438   iGeom_getEntUtoXYZ,
00439   iGeom_getArrUtoXYZ,
00440   iGeom_getEntXYZtoUV,
00441   iGeom_getEntXYZtoU,
00442   iGeom_getArrXYZtoUV,
00443   iGeom_getArrXYZtoU,
00444   iGeom_getEntXYZtoUVHint,
00445   iGeom_getArrXYZtoUVHint,
00446   iGeom_getEntUVRange,
00447   iGeom_getEntURange,
00448   iGeom_getArrUVRange,
00449   iGeom_getArrURange,
00450   iGeom_getEntUtoUV,
00451   iGeom_getVtxToUV,
00452   iGeom_getVtxToU,
00453   iGeom_getArrUtoUV,
00454   iGeom_getVtxArrToUV,
00455   iGeom_getVtxArrToU,
00456   iGeom_getEntNrmlUV,
00457   iGeom_getArrNrmlUV,
00458   iGeom_getEntTgntU,
00459   iGeom_getArrTgntU,
00460   iGeom_getEnt1stDrvt,
00461   iGeom_getArr1stDrvt,
00462   iGeom_getEnt2ndDrvt,
00463   iGeom_getArr2ndDrvt,
00464   iGeom_getFcCvtrUV,
00465   iGeom_getFcArrCvtrUV,
00466   iGeom_isEntPeriodic,
00467   iGeom_isArrPeriodic,
00468   iGeom_isFcDegenerate,
00469   iGeom_isFcArrDegenerate,
00470   iGeom_getTolerance,
00471   iGeom_getEntTolerance,
00472   iGeom_getArrTolerance,
00473   iGeom_initEntIter,
00474   iGeom_initEntArrIter,
00475   iGeom_getNextEntIter,
00476   iGeom_getNextEntArrIter,
00477   iGeom_resetEntIter,
00478   iGeom_resetEntArrIter,
00479   iGeom_endEntIter,
00480   iGeom_endEntArrIter,
00481   iGeom_copyEnt,
00482   iGeom_sweepEntAboutAxis,
00483   iGeom_deleteAll,
00484   iGeom_deleteEnt,
00485   iGeom_createSphere,
00486   iGeom_createPrism,
00487   iGeom_createBrick,
00488   iGeom_createCylinder,
00489   iGeom_createCone,
00490   iGeom_createTorus,
00491   iGeom_moveEnt,
00492   iGeom_rotateEnt,
00493   iGeom_reflectEnt,
00494   iGeom_scaleEnt,
00495   iGeom_uniteEnts,
00496   iGeom_subtractEnts,
00497   iGeom_intersectEnts,
00498   iGeom_sectionEnt,
00499   iGeom_imprintEnts,
00500   iGeom_mergeEnts,
00501   iGeom_createEntSet,
00502   iGeom_destroyEntSet,
00503   iGeom_isList,
00504   iGeom_getNumEntSets,
00505   iGeom_getEntSets,
00506   iGeom_addEntToSet,
00507   iGeom_rmvEntFromSet,
00508   iGeom_addEntArrToSet,
00509   iGeom_rmvEntArrFromSet,
00510   iGeom_addEntSet,
00511   iGeom_rmvEntSet,
00512   iGeom_isEntContained,
00513   iGeom_isEntArrContained,
00514   iGeom_isEntSetContained,
00515   iGeom_addPrntChld,
00516   iGeom_rmvPrntChld,
00517   iGeom_isChildOf,
00518   iGeom_getNumChld,
00519   iGeom_getNumPrnt,
00520   iGeom_getChldn,
00521   iGeom_getPrnts,
00522   iGeom_createTag,
00523   iGeom_destroyTag,
00524   iGeom_getTagName,
00525   iGeom_getTagSizeValues,
00526   iGeom_getTagSizeBytes,
00527   iGeom_getTagHandle,
00528   iGeom_getTagType,
00529   iGeom_setEntSetData,
00530   iGeom_setEntSetIntData,
00531   iGeom_setEntSetDblData,
00532   iGeom_setEntSetEHData,
00533   iGeom_setEntSetESHData,
00534   iGeom_getEntSetData,
00535   iGeom_getEntSetIntData,
00536   iGeom_getEntSetDblData,
00537   iGeom_getEntSetEHData,
00538   iGeom_getEntSetESHData,
00539   iGeom_getAllEntSetTags,
00540   iGeom_rmvEntSetTag,
00541   iGeom_getArrData,
00542   iGeom_getIntArrData,
00543   iGeom_getDblArrData,
00544   iGeom_getEHArrData,
00545   iGeom_getESHArrData,
00546   iGeom_setArrData,
00547   iGeom_setIntArrData,
00548   iGeom_setDblArrData,
00549   iGeom_setEHArrData,
00550   iGeom_setESHArrData,
00551   iGeom_rmvArrTag,
00552   iGeom_getData,
00553   iGeom_getIntData,
00554   iGeom_getDblData,
00555   iGeom_getEHData,
00556   iGeom_getESHData,
00557   iGeom_setData,
00558   iGeom_setIntData,
00559   iGeom_setDblData,
00560   iGeom_setEHData,
00561   iGeom_setESHData,
00562   iGeom_getAllTags,
00563   iGeom_rmvTag,
00564   iGeom_subtract,
00565   iGeom_intersect,
00566   iGeom_unite,
00567   iGeom_getFacets
00568 };
00569 
00570 void CGM_iGeom_register()
00571 {
00572   iGeom_register("cgm", iGeom_newGeom);
00573 }
00574 #endif
00575 
00576 
00577 ITAPS_API void
00578 iGeom_getErrorType( iGeom_Instance geom,
00579                     int *error_type )
00580 {
00581   *error_type = CGM_iGeom_getLastErrorType();
00582 }
00583 
00584 ITAPS_API void
00585 iGeom_getDescription( iGeom_Instance geom,
00586                       char* description_buffer,
00587                       int description_buffer_length )
00588 {
00589   CGM_iGeom_getLastErrorDesc(description_buffer, description_buffer_length);
00590 }
00591 
00592 ITAPS_API void
00593 iGeom_newGeom( const char* options,
00594                iGeom_Instance* instance_out,
00595                int* err,
00596                const int options_size ) 
00597 {
00598     // scan options for default engine option
00599   std::string engine;
00600   if (options && options_size) {
00601     std::string tmp(options, options_size);
00602     char f[] = ";engine="; f[0]=tmp[0]; // correct delimiter
00603     size_t p = tmp.find( f );
00604     if (p != std::string::npos) { // if we found engine option
00605       p += strlen(f); // advance to value (past '=')
00606       size_t e = tmp.find( tmp[0], p ); // find end delimiter
00607       if (e == std::string::npos) // if no end delim, then must be last option
00608         engine = tmp.substr( p, std::string::npos );
00609       else
00610         engine = tmp.substr( p, e-p );
00611     }
00612   }
00613   
00614     // initialize static var with result so that call happens only once
00615   static const CubitStatus status = init_cgm( engine );
00616     // but check the result for every call
00617   if (CUBIT_SUCCESS != status)
00618     RETURN (iBase_FAILURE);
00619 
00620     // return the tagmanager as the instance
00621 #ifdef ITAPS_SHIM
00622   CGMTagManager::instance().vtable = &CGM_iGeom_vtable;
00623 #endif
00624   *instance_out = reinterpret_cast<iGeom_Instance>(&CGMTagManager::instance());
00625   RETURN(iBase_SUCCESS);
00626 }
00627 
00628 
00629 ITAPS_API void
00630 iGeom_dtor( iGeom_Instance instance,
00631             int* err ) 
00632 {
00633   if (NULL == TM) 
00634     ERROR(iBase_INVALID_ARGUMENT, "NUll Instance");
00635   
00636     // delete TM;
00637   
00638     // shut down CGM
00639   CGMApp::instance()->shutdown();
00640 
00641   RETURN(iBase_SUCCESS);
00642 }
00643   
00644 // user defined non-static methods:
00653 ITAPS_API void
00654 iGeom_load( iGeom_Instance instance,
00655             /*in*/ const char *name,
00656             /*in*/ const char *options,
00657             int* err,
00658             int name_len,
00659             int options_size )
00660 {
00661   // pre-get all entities, so we can filter them out later; use cubit list
00662   // 'cuz we need to get both volumes and bodies
00663   DLIList<RefEntity*> ref_list, tmp_ref_list;
00664   for (int dim = 0; dim < 5; dim++) {
00665     // Using a temporary since GeometryQueryTool::ref_entity_list cleans out
00666     // the list before appending to it
00667     gqt->ref_entity_list(cgm_type_names[dim], tmp_ref_list, false);
00668     ref_list += tmp_ref_list;
00669   }
00670 
00671    // make sure we have a null-terminated string for file name
00672   std::string file_name( name, name_len );
00673   name = file_name.c_str();
00674 
00675   // check if work in parallel
00676   bool parallel = false;
00677   std::string parallel_opt;
00678   std::vector<std::string> opts;
00679   std::string tmp_options(options, options_size);
00680   tmp_options.insert(0, ";");
00681   tokenize(tmp_options, opts );
00682   for (std::vector<std::string>::iterator i = opts.begin(); i != opts.end(); ++i)
00683   {
00684     if (match_option( *i, "PARALLEL", parallel_opt )) parallel = true;
00685   }
00686   
00687   // parallel
00688   if (parallel) {
00689 #ifdef USE_MPI
00690     CGMParallelComm* p_comm = new CGMParallelComm();
00691     CGMReadParallel* p_reader = new CGMReadParallel(GeometryQueryTool::instance(), p_comm);
00692     CubitStatus status = p_reader->load_file(name, options);
00693     if (CUBIT_SUCCESS != status) {
00694       ERROR(iBase_FAILURE, "Trouble loading geometry file in parallel.");
00695     }
00696 #endif
00697   }
00698   else {
00699     CubitStatus status = CUBIT_SUCCESS;
00700     
00701 
00702       std::string file_type;
00703       if (strstr(name, ".brep") != NULL ||
00704       strstr(name, ".BREP") != NULL ||
00705       strstr(name, ".occ") != NULL ||
00706       strstr(name, ".OCC") != NULL)
00707     file_type = "OCC";
00708       else if (strstr(name, ".stp") != NULL ||
00709            strstr(name, ".STP") != NULL ||
00710            strstr(name, ".step") != NULL ||
00711            strstr(name, ".STEP") != NULL)
00712     file_type = "STEP";
00713       else if (strstr(name, ".igs") != NULL ||
00714            strstr(name, ".IGS") != NULL ||
00715            strstr(name, ".iges") != NULL ||
00716            strstr(name, ".IGES") != NULL)
00717     file_type = "IGES";
00718       
00719 
00720       status = CubitCompat_import_solid_model(name, file_type.c_str());
00721 
00722       if (CUBIT_SUCCESS != status) {
00723     ERROR(iBase_FILE_NOT_FOUND, "Trouble loading geometry file.");
00724 
00725     }
00726   }
00727 
00728   DLIList<RefEntity*> ref_list_2;
00729   for (int dim = 0; dim < 5; dim++) {
00730     // Using a temporary since GeometryQueryTool::ref_entity_list cleans out
00731     // the list before appending to it
00732     gqt->ref_entity_list(cgm_type_names[dim], tmp_ref_list, false);
00733     ref_list_2 += tmp_ref_list;
00734   }
00735 
00736   ref_list_2 -= ref_list;
00737   
00738     // now process uncaught/unregistered attributes
00739   iBase_ErrorType result = process_attribs(instance, ref_list_2);
00740 
00741   RETURN(result);
00742 }
00743 
00744 // user defined non-static methods:
00753 ITAPS_API void
00754 iGeom_save( iGeom_Instance instance,
00755             /*in*/ const char *name,
00756             /*in*/ const char* options,
00757             int* err,
00758             int name_len,
00759             int options_len )
00760 {
00761     // make sure strings are null terminated
00762   std::string name_buf(name, name_len);
00763   name = name_buf.c_str();
00764   
00765     // parse options
00766   std::string file_type;
00767   std::vector<std::string> opts;
00768   tokenize( std::string(options, options_len), opts );
00769   for (std::vector<std::string>::iterator i = opts.begin(); i != opts.end(); ++i)
00770   {
00771     if (!match_option( *i, "TYPE", file_type )) //
00772       ERROR( iBase_INVALID_ARGUMENT, i->c_str() );
00773   }
00774 
00775     // if no type, check file type for known extensions
00776   if (file_type.empty()) {
00777     size_t name_len = name_buf.length();
00778     if (name_buf.find(".igs") < name_len ||
00779         name_buf.find(".IGS") < name_len ||
00780         name_buf.find(".iges") < name_len ||
00781         name_buf.find(".IGES") < name_len)
00782       file_type = "IGES";
00783     else if (name_buf.find(".stp") < name_len ||
00784              name_buf.find(".STP") < name_len ||
00785              name_buf.find(".step") < name_len ||
00786              name_buf.find(".STEP") < name_len)
00787       file_type = "STEP";
00788     else if (name_buf.find(".occ") < name_len ||
00789              name_buf.find(".brep") < name_len ||
00790              name_buf.find(".OCC") < name_len ||
00791              name_buf.find(".BREP") < name_len)
00792       file_type = "OCC";
00793     else
00794       ERROR(iBase_FAILURE, "Unknown geometry file extension and no file type.");
00795   }
00796   
00801   const char* logfile_name = NULL;
00802   if( file_type == "IGES" ){
00803     logfile_name = "igeom_iges_export.log";
00804   }
00805   else if( file_type == "STEP" ){
00806     logfile_name = "igeom_step_export.log";
00807   }
00808 
00809     // process options (none right now...)
00810   DLIList<RefEntity*> bodies;
00811   int num_ents_exported;
00812   CubitString cubit_version(" (iGeom)");
00813   CubitStatus status = CubitCompat_export_solid_model(bodies, name, file_type.c_str(),
00814                                                num_ents_exported, cubit_version, logfile_name );
00815   if (CUBIT_SUCCESS != status) 
00816     ERROR(iBase_FAILURE, "Trouble saving geometry file.");
00817 
00818   RETURN(iBase_SUCCESS);
00819 }
00820 
00821 ITAPS_API void
00822 iGeom_getRootSet( iGeom_Instance,
00823                   iBase_EntitySetHandle* root,
00824                   int* err )
00825 {
00826   *root = NULL;
00827   RETURN(iBase_SUCCESS);
00828 }
00829 
00830 
00831 ITAPS_API void
00832 iGeom_getBoundBox( iGeom_Instance,
00833                    double* min_x,
00834                    double* min_y,
00835                    double* min_z,
00836                    double* max_x,
00837                    double* max_y,
00838                    double* max_z,
00839                    int* err ) 
00840 {
00841   CubitBox box = GeometryQueryTool::instance()->model_bounding_box();
00842   *min_x = box.min_x();
00843   *min_y = box.min_y();
00844   *min_z = box.min_z();
00845   *max_x = box.max_x();
00846   *max_y = box.max_y();
00847   *max_z = box.max_z();
00848   RETURN(iBase_SUCCESS);
00849 }
00850 
00851 
00858 ITAPS_API void
00859 iGeom_initEntIter( iGeom_Instance instance,
00860                    iBase_EntitySetHandle entity_set_handle,
00861                    const int dimension,
00862                    iBase_EntityIterator *iterator,
00863                    int* err )
00864 {
00865   iGeom_initEntArrIter( instance, entity_set_handle, dimension, 1, 
00866                         reinterpret_cast<iBase_EntityArrIterator*>(iterator), 
00867                         err );
00868 }
00869 
00870 ITAPS_API void
00871 iGeom_initEntArrIter( iGeom_Instance instance,
00872                       /*in*/ iBase_EntitySetHandle entity_set_handle,
00873                       /*in*/ int type,
00874                       /*in*/ int requested_array_size,
00875                       /*out*/ iBase_EntityArrIterator* entArr_iterator,
00876                       int* err )
00877 {
00878   DLIList<RefEntity*> entities;
00879   if (RefGroup* group = reinterpret_cast<RefGroup*>(entity_set_handle)) {
00880     DLIList<CubitEntity*> centities;
00881     group->get_child_entities( centities );
00882     append_ibase_type( type, centities, entities, err );
00883   }
00884   else {
00885     append_all_ibase_type( type, entities, err );
00886   }
00887   
00888   if (*err == iBase_SUCCESS) {
00889     CGMAIterator* iter = new CGMAIterator(entities, requested_array_size);
00890     *entArr_iterator = reinterpret_cast<iBase_EntityArrIterator>(iter);
00891   }
00892 }
00893 
00894 
00895 
00903 ITAPS_API void
00904 iGeom_getNextEntIter( iGeom_Instance instance,
00905                       /*in*/ iBase_EntityIterator gentity_iterator,
00906                       /*out*/ iBase_EntityHandle *gentity_handle,
00907                       int* has_data,
00908                       int* err )
00909 {
00910   CGMAIterator* iterator = reinterpret_cast<CGMAIterator*>(gentity_iterator);
00911   RefEntity** out_handle = reinterpret_cast<RefEntity**>(gentity_handle);
00912   *has_data = !iterator->at_end();
00913   if (*has_data) {
00914     int count = 1;
00915     iterator->next( out_handle, count );
00916   }
00917   RETURN(iBase_SUCCESS);
00918 }
00919 
00920 
00921 ITAPS_API void
00922 iGeom_getNextEntArrIter( iGeom_Instance instance,
00923                          /*in*/ iBase_EntityArrIterator entArr_iterator,
00924                          /*inout*/ iBase_EntityHandle **entity_handles,
00925                          int *entity_handles_allocated,
00926                          int *entity_handles_size,
00927                          int* has_data,
00928                          int* err )
00929 {
00930   CGMAIterator* iterator = reinterpret_cast<CGMAIterator*>(entArr_iterator);
00931   *has_data = !iterator->at_end();
00932   if (has_data) {
00933     ALLOC_CHECK_ARRAY_NOFAIL(entity_handles, iterator->size());
00934     iterator->next( (RefEntity**)*entity_handles, *entity_handles_size );
00935   }
00936   RETURN(iBase_SUCCESS);
00937 }
00938 
00939 
00944 ITAPS_API void
00945 iGeom_resetEntIter( iGeom_Instance instance,
00946                     /*in*/ iBase_EntityIterator gentity_iterator,
00947                     int* err )
00948 {
00949   CGMAIterator* iterator = reinterpret_cast<CGMAIterator*>(gentity_iterator);
00950   iterator->reset();
00951   RETURN(iBase_SUCCESS);
00952 }
00953 
00954 ITAPS_API void
00955 iGeom_resetEntArrIter( iGeom_Instance instance,
00956                        /*in*/ iBase_EntityArrIterator gentity_iterator,
00957                        int* err )
00958 {
00959   CGMAIterator* iterator = reinterpret_cast<CGMAIterator*>(gentity_iterator);
00960   iterator->reset();
00961   RETURN(iBase_SUCCESS);
00962 }
00963 
00968 ITAPS_API void
00969 iGeom_endEntIter( iGeom_Instance instance,
00970                   /*in*/ iBase_EntityIterator gentity_iterator,
00971                   int* err )
00972 {
00973   CGMAIterator* iterator = reinterpret_cast<CGMAIterator*>(gentity_iterator);
00974   delete iterator;
00975   RETURN(iBase_SUCCESS);
00976 }
00977 
00978 ITAPS_API void
00979 iGeom_endEntArrIter( iGeom_Instance instance,
00980                      /*in*/ iBase_EntityArrIterator gentity_iterator,
00981                      int* err )
00982 {
00983   CGMAIterator* iterator = reinterpret_cast<CGMAIterator*>(gentity_iterator);
00984   delete iterator;
00985   RETURN(iBase_SUCCESS);
00986 }
00987 
00992 ITAPS_API void
00993 iGeom_isChildOf( iGeom_Instance instance,
00994                  /*in*/ iBase_EntitySetHandle parent_entity_set,
00995                  /*in*/ iBase_EntitySetHandle child_entity_set,
00996                  int* is_child,
00997                  int* err )
00998 {
00999   std::vector<RefGroup*> *par1, *ch1, *par2, *ch2;
01000   TM->pc_list(const_cast<RefGroup*>(SET_HANDLE(parent_entity_set)), par1, ch1, false);
01001   if (NULL == ch1 || ch1->empty()) {
01002     *is_child = false;
01003     RETURN (iBase_SUCCESS);
01004   }
01005   TM->pc_list(const_cast<RefGroup*>(SET_HANDLE(child_entity_set)), par2, ch2, false);
01006   if (NULL == par2 || par2->empty()) {
01007     *is_child = false;
01008     RETURN (iBase_SUCCESS);
01009   }
01010   
01011   const RefGroup *group1 = SET_HANDLE(parent_entity_set);
01012   const RefGroup *group2 = SET_HANDLE(child_entity_set);
01013   if ((std::find(ch1->begin(), ch1->end(), group2) != ch1->end())
01014       || (std::find(par2->begin(), par2->end(), group1) != par2->end()))
01015     *is_child = true;
01016   
01017   else *is_child = false;
01018   RETURN(iBase_SUCCESS);
01019 }
01020 
01025 ITAPS_API void
01026 iGeom_getChldn( iGeom_Instance instance,
01027                 /*in*/ iBase_EntitySetHandle from_entity_set,
01028                 /*in*/ const int num_hops,
01029                 /*inout*/ iBase_EntitySetHandle** entity_set_handles,
01030                 int* entity_set_handles_allocated,
01031                 int* entity_set_handles_size,
01032                 int* err )
01033 {
01034   std::vector<RefGroup*> group_ptrs;
01035   const RefGroup *this_grp = SET_HANDLE(from_entity_set);
01036   TM->get_pc_groups(const_cast<RefGroup*>(this_grp), 1, num_hops, group_ptrs);
01037   ALLOC_CHECK_ARRAY_NOFAIL(entity_set_handles, group_ptrs.size());
01038 
01039   iBase_EntitySetHandle* ent_arr = reinterpret_cast<iBase_EntitySetHandle*>(&group_ptrs[0]);
01040   std::copy( ent_arr, ent_arr + group_ptrs.size(), *entity_set_handles);
01041   
01042   RETURN(iBase_SUCCESS);
01043 }
01044 
01049 ITAPS_API void
01050 iGeom_getPrnts( iGeom_Instance instance,
01051                 /*in*/ iBase_EntitySetHandle from_entity_set,
01052                 /*in*/ const int num_hops,
01053                 /*inout*/ iBase_EntitySetHandle **entity_set_handles,
01054                 int *entity_set_handles_allocated,
01055                 int *entity_set_handles_size,
01056                 int* err )
01057 {
01058   std::vector<RefGroup*> group_ptrs;
01059   const RefGroup *this_grp = SET_HANDLE(from_entity_set);
01060   TM->get_pc_groups(const_cast<RefGroup*>(this_grp), 0, num_hops, group_ptrs);
01061   ALLOC_CHECK_ARRAY_NOFAIL(entity_set_handles, group_ptrs.size());
01062 
01063   iBase_EntitySetHandle* ent_arr = reinterpret_cast<iBase_EntitySetHandle*>(&group_ptrs[0]);
01064   std::copy( ent_arr, ent_arr + group_ptrs.size(), *entity_set_handles);
01065   RETURN(iBase_SUCCESS);
01066 }
01067 
01072 ITAPS_API void
01073 iGeom_getNumChld( iGeom_Instance instance,
01074                   /*in*/ iBase_EntitySetHandle entity_set,
01075                   /*in*/ const int num_hops,
01076                   int* num_child, 
01077                   int* err )
01078 {
01079     // HJK: num_hops has to be handled
01080   if (0 < num_hops) {
01081     ERROR(iBase_NOT_SUPPORTED, "Num_hops argument not yet supported.");
01082   }
01083 
01084   std::vector<RefGroup*> *my_children = TM->pc_list(const_cast<RefGroup*>(SET_HANDLE(entity_set)), 1, false);
01085   *num_child = my_children == NULL ? 0 : my_children->size();
01086   RETURN (iBase_SUCCESS);
01087 }
01088 
01093 ITAPS_API void
01094 iGeom_getNumPrnt( iGeom_Instance instance,
01095                   /*in*/ iBase_EntitySetHandle entity_set,
01096                   /*in*/ const int num_hops,
01097                   int* num_parent,
01098                   int* err )
01099 {
01100     // HJK: num_hops has to be handled
01101   if (0 < num_hops) {
01102     ERROR(iBase_NOT_SUPPORTED, "Num_hops argument not yet supported.");
01103   }
01104 
01105   std::vector<RefGroup*> *my_parents = TM->pc_list(const_cast<RefGroup*>(SET_HANDLE(entity_set)), 0, false);
01106   *num_parent = my_parents == NULL ? 0 : my_parents->size();
01107   RETURN (iBase_SUCCESS);
01108 }
01109 
01113 ITAPS_API void
01114 iGeom_addPrntChld( iGeom_Instance instance,
01115                    /*inout*/ iBase_EntitySetHandle parent_entity_set,
01116                    /*inout*/ iBase_EntitySetHandle child_entity_set,
01117                    int* err )
01118 {
01119   std::vector<RefGroup*> *my_parents = 
01120     TM->pc_list(SET_HANDLE(child_entity_set), 0, true);
01121   std::vector<RefGroup*> *my_children = 
01122     TM->pc_list(SET_HANDLE(parent_entity_set), 1, true);
01123   RefGroup *par_group = SET_HANDLE(parent_entity_set);
01124   RefGroup *child_group = SET_HANDLE(child_entity_set);
01125   my_parents->push_back(par_group);
01126   my_children->push_back(child_group);
01127   RETURN(iBase_SUCCESS);
01128 }
01129 
01133 ITAPS_API void
01134 iGeom_rmvPrntChld( iGeom_Instance instance,
01135                    /*inout*/ iBase_EntitySetHandle parent_entity_set,
01136                    /*inout*/ iBase_EntitySetHandle child_entity_set,
01137                    int* err )
01138 {
01139   RefGroup *parent = reinterpret_cast<RefGroup *>(parent_entity_set);
01140   RefGroup *child = reinterpret_cast<RefGroup *>(child_entity_set);
01141   std::vector<RefGroup*> *children = TM->pc_list(parent, 1, false),
01142     *parents = TM->pc_list(child, 0, false);
01143   if (NULL == children || NULL == parents) {
01144     RETURN(iBase_INVALID_ARGUMENT);
01145   }
01146   
01147   children->erase(std::remove(children->begin(), children->end(), child), children->end());
01148   parents->erase(std::remove(parents->begin(), parents->end(), parent), parents->end());
01149   RETURN(iBase_SUCCESS);
01150 }
01151 
01158 ITAPS_API void
01159 iGeom_getEntities( iGeom_Instance instance,
01160                    /*in*/ iBase_EntitySetHandle set_handle,
01161                    /*in*/ int gentity_type,
01162                    /*out*/ iBase_EntityHandle **gentity_handles,
01163                    int *gentity_handles_allocated,
01164                    int *gentity_handles_size,
01165                    int* err )
01166 {
01167   if (RefGroup *this_set = SET_HANDLE(set_handle)) {
01168     static DLIList<CubitEntity*> centities;
01169     centities.clean_out();
01170     this_set->get_child_entities(centities);
01171     copy_ibase_type( gentity_type, centities, 
01172                      gentity_handles,
01173                      gentity_handles_allocated,
01174                      gentity_handles_size,
01175                      err );
01176   }
01177   else {
01178     static DLIList<RefEntity*> dim_entities;
01179     dim_entities.clean_out();
01180     append_all_ibase_type( gentity_type, dim_entities, err );
01181     if (iBase_SUCCESS != *err)
01182       return;
01183     
01184     ALLOC_CHECK_ARRAY_NOFAIL(gentity_handles, dim_entities.size());
01185     dim_entities.copy_to((RefEntity**)*gentity_handles);
01186     RETURN(iBase_SUCCESS);
01187   }  
01188 }
01189 
01197 ITAPS_API void
01198 iGeom_getNumOfType( iGeom_Instance instance,
01199                     /*in*/ iBase_EntitySetHandle set_handle,
01200                     /*in*/ int gentity_type,
01201                     int* count,
01202                     int* err )
01203 {
01204   const RefGroup *this_set = SET_HANDLE(set_handle);
01205   if (0 == this_set) {
01206     switch (gentity_type) {
01207       case iBase_ALL_TYPES:
01208         *count  = GeometryQueryTool::instance()->num_bodies();
01209         *count += GeometryQueryTool::instance()->num_ref_faces();
01210         *count += GeometryQueryTool::instance()->num_ref_edges();
01211         *count += GeometryQueryTool::instance()->num_ref_vertices();
01212         break;
01213       case iBase_REGION:
01214         *count = GeometryQueryTool::instance()->num_bodies();
01215         break;
01216       case iBase_FACE:
01217         *count = GeometryQueryTool::instance()->num_ref_faces();
01218         break;
01219       case iBase_EDGE:
01220         *count = GeometryQueryTool::instance()->num_ref_edges();
01221         break;
01222       case iBase_VERTEX:
01223         *count = GeometryQueryTool::instance()->num_ref_vertices();
01224         break;
01225       default:
01226         RETURN(iBase_BAD_TYPE_AND_TOPO);
01227         break;
01228     }
01229     RETURN (iBase_SUCCESS);
01230   }
01231   else {
01232     static DLIList<CubitEntity*> centities;
01233     centities.clean_out();
01234     const_cast<RefGroup*>(this_set)->get_child_entities(centities);
01235     *count = count_ibase_type( gentity_type, centities, err );
01236   }
01237 }
01238 
01239 ITAPS_API void
01240 iGeom_getEntType( iGeom_Instance instance, 
01241                   iBase_EntityHandle handle,
01242                   int* gtype,
01243                   int* err )
01244 {
01245   RefEntity* entity = reinterpret_cast<RefEntity*>(handle);
01246   if (dynamic_cast<Body*>(entity))
01247     *gtype = iBase_REGION;
01248   else
01249     *gtype = static_cast<int>(entity->dimension());
01250   RETURN(iBase_SUCCESS);
01251 }
01252 
01257 ITAPS_API void
01258 iGeom_getArrType( iGeom_Instance instance,
01259                   /*in*/ iBase_EntityHandle const *gentity_handles,
01260                   int gentity_handles_size,
01261                   /*inout*/ int **gtype,
01262                   int *gtype_allocated,
01263                   int *gtype_size, 
01264                   int* err )
01265 {
01266     // go through each entity and look up its dimension
01267   ALLOC_CHECK_ARRAY_NOFAIL(gtype, gentity_handles_size);
01268 
01269   const RefEntity **tmp_handles = (const RefEntity**)(gentity_handles);
01270   
01271   for (int i = 0; i < gentity_handles_size; i++) {
01272     if (dynamic_cast<const Body*>(tmp_handles[i]))
01273       (*gtype)[i] = iBase_REGION;
01274     else
01275       (*gtype)[i] = tmp_handles[i]->dimension();
01276   }
01277 
01278   RETURN(iBase_SUCCESS);
01279 }
01280 
01287 ITAPS_API void
01288 iGeom_getEntAdj( iGeom_Instance instance,
01289                  /*in*/ iBase_EntityHandle gentity_handle,
01290                  /*in*/int to_dimension,
01291                  /*inout*/ iBase_EntityHandle **adj_gentities,
01292                  int *adj_gentities_allocated,
01293                  int *adj_gentities_size,
01294                  int* err )
01295 {
01296   const RefEntity *tmp_hndl = ENTITY_HANDLE(gentity_handle);
01297 
01298   if (tmp_hndl->dimension() == to_dimension) {
01299     ERROR(iBase_INVALID_ARGUMENT, "Can't get adjacencies to entities of same dimension.");
01300   }
01301 
01302   static DLIList<RefEntity*> tmp_ents;
01303   iGeom_get_adjacent_entities(tmp_hndl, to_dimension, tmp_ents, err);
01304   if (iBase_SUCCESS != *err) return;
01305 
01306   ALLOC_CHECK_ARRAY_NOFAIL(adj_gentities, tmp_ents.size());
01307   tmp_ents.copy_to((RefEntity**)*adj_gentities);
01308   RETURN(iBase_SUCCESS);
01309 }
01310 
01311 ITAPS_API void
01312 iGeom_getArrAdj( iGeom_Instance instance,
01313                  /*in*/ iBase_EntityHandle const *entity_handles,
01314                  const int entity_handles_size,
01315                  /*in*/ int requested_entity_type,
01316                  /*inout*/ iBase_EntityHandle **adj_entity_handles,
01317                  int *adj_entity_handles_allocated,
01318                  int *adj_entity_handles_size,
01319                  /*inout*/ int **offset,
01320                  int *offset_allocated,
01321                  int *offset_size,
01322                  int* err )
01323 {
01324   ALLOC_CHECK_ARRAY(offset, entity_handles_size+1);
01325   DLIList<RefEntity*> temp_list, total_list;
01326   for (int i = 0; i < entity_handles_size; ++i) {
01327     (*offset)[i] = total_list.size();
01328     temp_list.clean_out();
01329     iGeom_get_adjacent_entities( (RefEntity*)(entity_handles[i]), requested_entity_type, temp_list, err );
01330     if (iBase_SUCCESS != *err) return;
01331     total_list += temp_list;
01332   }
01333   (*offset)[entity_handles_size] = total_list.size();
01334 
01335   ALLOC_CHECK_ARRAY_NOFAIL(adj_entity_handles, total_list.size());
01336   total_list.copy_to((RefEntity**)*adj_entity_handles);
01337   KEEP_ARRAY(offset);
01338   RETURN(iBase_SUCCESS);
01339 }
01340   
01353 ITAPS_API void
01354 iGeom_getEnt2ndAdj( iGeom_Instance instance,
01355                     /*in*/ iBase_EntityHandle gentity_handle,
01356                     /*in*/ int bridge_dimension,
01357                     /*in*/ int to_dimension,
01358                     /*out*/ iBase_EntityHandle **adjacent_gentities,
01359                     int *adjacent_gentities_allocated,
01360                     int *adjacent_gentities_size,
01361                     int* err )
01362 {
01363     // for better or worse, go to cgm as quickly as possible, to avoid working with
01364     // sidl arrays
01365   const RefEntity *gentity = ENTITY_HANDLE(gentity_handle);
01366   DLIList<RefEntity*> to_ents, bridge_ents, tmp_ents;
01367 
01368   iGeom_get_adjacent_entities(gentity, bridge_dimension, bridge_ents, err);
01369   if (iBase_SUCCESS != *err) return;
01370   
01371   for (int i = bridge_ents.size(); i > 0; i--) {
01372     iGeom_get_adjacent_entities(bridge_ents.get_and_step(), to_dimension, tmp_ents, err);
01373     if (iBase_SUCCESS != *err) return;
01374 
01375     to_ents += tmp_ents;
01376     tmp_ents.clean_out();
01377   }
01378 
01379   to_ents.uniquify_unordered();
01380 
01381   ALLOC_CHECK_ARRAY_NOFAIL(adjacent_gentities, to_ents.size());
01382   to_ents.copy_to((RefEntity**)*adjacent_gentities);
01383 
01384   RETURN(iBase_SUCCESS);
01385 }
01386 
01387 ITAPS_API void
01388 iGeom_getArr2ndAdj( iGeom_Instance instance,
01389                     /*in*/ iBase_EntityHandle const *entity_handles,
01390                     int entity_handles_size,
01391                     /*in*/ int order_adjacent_key,
01392                     /*in*/ int requested_entity_type,
01393                     /*inout*/ iBase_EntityHandle **adj_entity_handles,
01394                     int *adj_entity_handles_allocated,
01395                     int *adj_entity_handles_size,
01396                     /*inout*/ int **offset,
01397                     int *offset_allocated,
01398                     int *offset_size,
01399                     int *err )
01400 {
01401   ALLOC_CHECK_ARRAY(offset, entity_handles_size+1);
01402   DLIList<RefEntity*> bridge_list, temp_list, entity_list, total_list;
01403    
01404   for (int i = 0; i < entity_handles_size; ++i) {
01405     bridge_list.clean_out();
01406     entity_list.clean_out();
01407     iGeom_get_adjacent_entities( (RefEntity*)(entity_handles[i]), order_adjacent_key, bridge_list, err );
01408     if (iBase_SUCCESS != *err) return;
01409     bridge_list.reset();
01410     for (int j = bridge_list.size(); j > 0; --j) {
01411       temp_list.clean_out();
01412       iGeom_get_adjacent_entities( bridge_list.get_and_step(), requested_entity_type, temp_list, err );
01413       if (iBase_SUCCESS != *err) return;
01414       entity_list += temp_list;
01415     }
01416     entity_list.uniquify_unordered();
01417     (*offset)[i] = total_list.size();
01418     total_list += entity_list;
01419   }
01420   (*offset)[entity_handles_size] = total_list.size();
01421 
01422   ALLOC_CHECK_ARRAY_NOFAIL(adj_entity_handles, total_list.size());
01423   total_list.copy_to((RefEntity**)*adj_entity_handles);
01424   KEEP_ARRAY(offset);
01425   RETURN(iBase_SUCCESS);
01426 }
01427 
01434 ITAPS_API void
01435 iGeom_isEntAdj( iGeom_Instance instance,
01436                 /*in*/ iBase_EntityHandle gentity_handle1,
01437                 /*in*/ iBase_EntityHandle gentity_handle2,
01438                 /*out*/ int *are_adjacent,
01439                 int* err )
01440 {
01441   const TopologyEntity *ent1 = dynamic_cast<const TopologyEntity*>(ENTITY_HANDLE(gentity_handle1));
01442   const TopologyEntity *ent2 = dynamic_cast<const TopologyEntity*>(ENTITY_HANDLE(gentity_handle2));
01443   if (ent1 != NULL && ent2 != NULL)
01444     *are_adjacent = const_cast<TopologyEntity*>(ent1)->is_directly_related(const_cast<TopologyEntity*>(ent2));
01445   else *are_adjacent = false;
01446   RETURN(iBase_SUCCESS);
01447 }
01448 
01449 ITAPS_API void
01450 iGeom_isArrAdj( iGeom_Instance instance,
01451                 /*in*/ iBase_EntityHandle const *entity_handles_1,
01452                 int entity_handles_1_size,
01453                 /*in*/ iBase_EntityHandle const *entity_handles_2,
01454                 int entity_handles_2_size,
01455                 /*inout*/ int **is_adjacent_info,
01456                 int *is_adjacent_info_allocated,
01457                 int *is_adjacent_info_size,
01458                 int* err )
01459 {
01460   RefEntity **list_1_iter = (RefEntity**)entity_handles_1, 
01461     **list_2_iter = (RefEntity**)entity_handles_2;
01462   size_t list_1_step, list_2_step;
01463   int count;
01464     // If either list contains only 1 entry, compare that entry with
01465     // every entry in the other list.
01466   if (entity_handles_1_size == entity_handles_2_size) {
01467     list_1_step = list_2_step = 1;
01468     count = entity_handles_1_size;
01469   }
01470   else if (entity_handles_1_size == 1) {
01471     list_1_step = 0;
01472     list_2_step = 1;
01473     count = entity_handles_2_size;
01474   }
01475   else if (entity_handles_2_size == 1) {
01476     list_1_step = 1;
01477     list_2_step = 0;
01478     count = entity_handles_1_size;
01479   }
01480   else {
01481     RETURN(iBase_INVALID_ENTITY_COUNT);
01482   }
01483   
01484   ALLOC_CHECK_ARRAY_NOFAIL(is_adjacent_info, count);
01485   for (int i = 0; i < count; ++i)
01486   {
01487     TopologyEntity* ent1 = dynamic_cast<TopologyEntity*>(*list_1_iter);
01488     TopologyEntity* ent2 = dynamic_cast<TopologyEntity*>(*list_2_iter);
01489     (*is_adjacent_info)[i] = ent1->is_directly_related(ent2);
01490     list_1_iter += list_1_step;
01491     list_2_iter += list_2_step;
01492   }
01493   RETURN(iBase_SUCCESS);
01494 }
01495 
01496 ITAPS_API void
01497 iGeom_getTopoLevel( iGeom_Instance instance,
01498                     /*out*/ int* level,
01499                     int* err )
01500 {
01501   *level = 2; // 0->basic entities only, 1->manifold, 2->non-manifold
01502   RETURN(iBase_SUCCESS);
01503 }
01504 
01515 ITAPS_API void
01516 iGeom_createTag( iGeom_Instance instance,
01517                  /*in*/ const char *tag_name,
01518                  /*in*/ int tag_size,
01519                  /*in*/ int tag_type,
01520                  /*out*/ iBase_TagHandle *tag_handle,
01521                  int* err,
01522                  int tag_name_len )
01523 {
01524   long new_tag;
01525   int this_size = tag_size;
01526   switch (tag_type) {
01527     case iBase_INTEGER:
01528       this_size *= sizeof(int);
01529       break;
01530     case iBase_DOUBLE:
01531       this_size *= sizeof(double);
01532       break;
01533     case iBase_ENTITY_HANDLE:
01534       this_size *= sizeof(iBase_EntityHandle);
01535       break;
01536     case iBase_ENTITY_SET_HANDLE:
01537       this_size *= sizeof(iBase_EntitySetHandle);
01538       break;
01539     case iBase_BYTES:
01540       break;
01541   }
01542   
01543     // make sure string is null terminated
01544   std::string name_buf( tag_name, tag_name_len );
01545   tag_name = name_buf.c_str();
01546   
01547   iBase_ErrorType retval = TM->createTag(tag_name, this_size, tag_type, NULL, &new_tag);
01548   *tag_handle = (iBase_TagHandle) new_tag;
01549   RETURN(retval);
01550 }
01551 
01564 ITAPS_API void
01565 iGeom_destroyTag( iGeom_Instance instance,
01566                   /*in*/ iBase_TagHandle tag_handle,
01567                   /*in*/ int forced,
01568                   int* err )
01569 {
01570   iBase_ErrorType retval = TM->destroyTag(TAG_HANDLE(tag_handle), forced);
01571   RETURN(retval);
01572 }
01573 
01577 ITAPS_API void
01578 iGeom_getTagName( iGeom_Instance instance,
01579                   /*in*/ iBase_TagHandle tag_handle,
01580                   char* name,
01581                   int* err,
01582                   int name_len )
01583 {
01584   const char* name_ptr = TM->getTagName(TAG_HANDLE(tag_handle));
01585   int len = strlen(name_ptr) + 1;
01586   if (len > name_len)
01587     len = name_len;
01588   memcpy( name, name_ptr, len );
01589   RETURN(iBase_SUCCESS);
01590 }
01591 
01595 ITAPS_API void
01596 iGeom_getTagSizeValues( iGeom_Instance instance,
01597                         /*in*/ iBase_TagHandle tag_handle,
01598                         int* tag_size,
01599                         int* err )
01600 {
01601   *tag_size = TM->getTagSize(TAG_HANDLE(tag_handle));
01602   int type;
01603   iGeom_getTagType( instance, tag_handle, &type, err );
01604   if (iBase_SUCCESS != *err) return;
01605   
01606   switch (type) {
01607     case iBase_INTEGER:
01608       *tag_size /= sizeof(int);
01609       break;
01610     case iBase_DOUBLE:
01611       *tag_size /= sizeof(double);
01612       break;
01613     case iBase_ENTITY_HANDLE:
01614     case iBase_ENTITY_SET_HANDLE:
01615       *tag_size /= sizeof(iBase_EntityHandle);
01616       break;
01617     case iBase_BYTES:
01618       break;
01619   }
01620   RETURN(iBase_SUCCESS);
01621 }
01622 
01626 ITAPS_API void
01627 iGeom_getTagSizeBytes( iGeom_Instance instance,
01628                        /*in*/ iBase_TagHandle tag_handle,
01629                        int* tag_size,
01630                        int* err )
01631 {
01632   *tag_size = TM->getTagSize(TAG_HANDLE(tag_handle));
01633   RETURN(iBase_SUCCESS);
01634 }
01635 
01636 ITAPS_API void
01637 iGeom_getTagType( iGeom_Instance instance,
01638                   /*in*/ iBase_TagHandle tag_handle,
01639                   int* type,
01640                   int* err )
01641 {
01642   *type = TM->getTagType(TAG_HANDLE(tag_handle));
01643   RETURN(iBase_SUCCESS);
01644 }
01645 
01649 ITAPS_API void
01650 iGeom_getTagHandle( iGeom_Instance instance,
01651                     /*in*/ const char *tag_name,
01652                     iBase_TagHandle* tag_handle,
01653                     int* err,
01654                     int tag_name_len )
01655 {
01656     // make sure string is null-terminated
01657   std::string tag_name_buf( tag_name, tag_name_len );
01658   tag_name = tag_name_buf.c_str();
01659   *tag_handle = reinterpret_cast<iBase_TagHandle>(static_cast<size_t>(TM->getTagHandle( tag_name )));
01660 
01661     // XXX: this seems really wrong...
01662   iGeom_getErrorType(instance, err);
01663 }
01664 
01665 ITAPS_API void
01666 iGeom_rmvArrTag( iGeom_Instance instance,
01667                  const iBase_EntityHandle *entity_handles,
01668                  int entity_handles_size,
01669                  iBase_TagHandle tag_handle,
01670                  int* err )
01671 {
01672   RefEntity *const *tmp_entity_handles = reinterpret_cast<RefEntity*const *>(entity_handles);  
01673   iBase_ErrorType retval = TM->rmvArrTag(tmp_entity_handles, entity_handles_size, TAG_HANDLE(tag_handle));
01674   RETURN(retval);
01675 }
01676 
01683 ITAPS_API void
01684 iGeom_rmvTag( iGeom_Instance instance,
01685               /*in*/ iBase_EntityHandle entity_handle,
01686               /*in*/ iBase_TagHandle tag_handle,
01687               int* err )
01688 {
01689   RefEntity *tmp_entity = ENTITY_HANDLE(entity_handle);
01690   iBase_ErrorType retval = TM->rmvArrTag(&tmp_entity, 1, TAG_HANDLE(tag_handle));
01691   RETURN(retval);
01692 }
01693 
01697 ITAPS_API void
01698 iGeom_getAllTags( iGeom_Instance instance,
01699                   /*in*/ iBase_EntityHandle entity_handle,
01700                   /*inout*/ iBase_TagHandle **tag_handles,
01701                   int *tag_handles_allocated,
01702                   int *tag_handles_size,
01703                   int* err )
01704 {
01705   iBase_ErrorType retval = TM->getAllTags(SET_HANDLE(entity_handle), 
01706                                           TAG_HANDLE_ARRAY_INOUT(tag_handles));
01707   RETURN(retval);
01708 }
01709 
01710 ITAPS_API void
01711 iGeom_getArrData( iGeom_Instance instance,
01712                   /*in*/ iBase_EntityHandle const *entity_handles,
01713                   int entity_handles_size,
01714                   /*in*/ iBase_TagHandle tag_handle,
01715                   /*inout*/ void **tag_value_tmp,
01716                   int *tag_value_allocated,
01717                   int *tag_value_size,
01718                   int* err )
01719 {
01720   char **tag_value = reinterpret_cast<char**>(tag_value_tmp);
01721   iBase_ErrorType retval = TM->getArrData(reinterpret_cast<RefEntity*const*>(entity_handles),
01722                                           entity_handles_size,
01723                                           TAG_HANDLE(tag_handle), 
01724                                           ARRAY_INOUT(tag_value));
01725   RETURN(retval);
01726 }
01727 
01728 
01729 ITAPS_API void
01730 iGeom_getIntArrData( iGeom_Instance instance,
01731                      /*in*/ iBase_EntityHandle const *entity_handles,
01732                      int entity_handles_size,
01733                      /*in*/ iBase_TagHandle tag_handle,
01734                      /*inout*/ int **tag_value,
01735                      int *tag_value_allocated,
01736                      int *tag_value_size,
01737                      int* err )
01738 {
01739   int tag_value_allocated_tmp = *tag_value_allocated * sizeof(int);
01740   int tag_value_size_tmp = *tag_value_size * sizeof(int);
01741   iGeom_getArrData(instance, entity_handles, 
01742                    entity_handles_size, tag_handle,
01743                    reinterpret_cast<void**>(tag_value),
01744                    &tag_value_allocated_tmp, 
01745                    &tag_value_size_tmp,
01746                    err);
01747   *tag_value_allocated = tag_value_allocated_tmp / sizeof(int);
01748   *tag_value_size = tag_value_size_tmp / sizeof(int);
01749 }
01750 
01751 
01752 ITAPS_API void
01753 iGeom_getDblArrData( iGeom_Instance instance,
01754                      /*in*/ iBase_EntityHandle const *entity_handles,
01755                      int entity_handles_size,
01756                      /*in*/ iBase_TagHandle tag_handle,
01757                      /*inout*/ double **tag_value,
01758                      int *tag_value_allocated,
01759                      int *tag_value_size,
01760                      int* err )
01761 {
01762   int tag_value_allocated_tmp = *tag_value_allocated * sizeof(double);
01763   int tag_value_size_tmp = *tag_value_size * sizeof(double);
01764   iGeom_getArrData(instance, entity_handles, 
01765                    entity_handles_size, tag_handle,
01766                    reinterpret_cast<void**>(tag_value),
01767                    &tag_value_allocated_tmp, 
01768                    &tag_value_size_tmp,
01769                    err);
01770   *tag_value_allocated = tag_value_allocated_tmp / sizeof(double);
01771   *tag_value_size = tag_value_size_tmp / sizeof(double);
01772 }
01773 
01774 ITAPS_API void
01775 iGeom_getEHArrData( iGeom_Instance instance,
01776                     /*in*/ iBase_EntityHandle const *entity_handles,
01777                     int entity_handles_size,
01778                     /*in*/ iBase_TagHandle tag_handle,
01779                     /*inout*/ iBase_EntityHandle **tag_value,
01780                     int *tag_value_allocated,
01781                     int *tag_value_size,
01782                     int* err )
01783 {
01784   int tag_value_allocated_tmp = *tag_value_allocated * sizeof(iBase_EntityHandle);
01785   int tag_value_size_tmp = *tag_value_size * sizeof(iBase_EntityHandle);
01786   iGeom_getArrData(instance, entity_handles, 
01787                    entity_handles_size, tag_handle,
01788                    reinterpret_cast<void**>(tag_value),
01789                    &tag_value_allocated_tmp, 
01790                    &tag_value_size_tmp,
01791                    err);
01792   *tag_value_allocated = tag_value_allocated_tmp / sizeof(iBase_EntityHandle);
01793   *tag_value_size = tag_value_size_tmp / sizeof(iBase_EntityHandle);
01794 }
01795 
01796 ITAPS_API void
01797 iGeom_getESHArrData( iGeom_Instance instance,
01798                      /*in*/ iBase_EntityHandle const *entity_handles,
01799                      int entity_handles_size,
01800                      /*in*/ iBase_TagHandle tag_handle,
01801                      /*inout*/ iBase_EntitySetHandle **tag_value,
01802                      int *tag_value_allocated,
01803                      int *tag_value_size,
01804                      int* err )
01805 {
01806   int tag_value_allocated_tmp = *tag_value_allocated * sizeof(iBase_EntitySetHandle);
01807   int tag_value_size_tmp = *tag_value_size * sizeof(iBase_EntitySetHandle);
01808   iGeom_getArrData(instance, entity_handles,
01809                    entity_handles_size, tag_handle,
01810                    reinterpret_cast<void**>(tag_value),
01811                    &tag_value_allocated_tmp,
01812                    &tag_value_size_tmp,
01813                    err);
01814   *tag_value_allocated = tag_value_allocated_tmp / sizeof(iBase_EntitySetHandle);
01815   *tag_value_size = tag_value_size_tmp / sizeof(iBase_EntitySetHandle);
01816 }
01817 
01818 ITAPS_API void
01819 iGeom_setArrData( iGeom_Instance instance,
01820                   const iBase_EntityHandle *entity_handles,
01821                   int entity_handles_size,
01822                   /*in*/ iBase_TagHandle tag_handle,
01823                   /*in*/ const void *tag_value_tmp,
01824                   const int tag_value_size,
01825                   int* err )
01826 {
01827   const char *tag_value = reinterpret_cast<const char*>(tag_value_tmp);
01828   iBase_ErrorType retval = TM->setArrData(ENTITY_HANDLE_CONST_ARRAY(entity_handles),
01829                                           entity_handles_size,
01830                                           TAG_HANDLE(tag_handle), 
01831                                           ARRAY_IN(tag_value));
01832   RETURN(retval);
01833 }
01834 
01835 ITAPS_API void
01836 iGeom_setIntArrData( iGeom_Instance instance,
01837                      const iBase_EntityHandle *entity_handles,
01838                      int entity_handles_size,
01839                      iBase_TagHandle tag_handle,
01840                      const int *tag_value,
01841                      int tag_value_size,
01842                      int* err )
01843 {
01844   iGeom_setArrData(instance, entity_handles, 
01845                    entity_handles_size, tag_handle, 
01846                    tag_value, sizeof(int)*tag_value_size, err);
01847 }
01848 
01849 ITAPS_API void
01850 iGeom_setDblArrData( iGeom_Instance instance,
01851                      const iBase_EntityHandle *entity_handles,
01852                      int entity_handles_size,
01853                      iBase_TagHandle tag_handle,
01854                      const double *tag_value,
01855                      int tag_value_size,
01856                      int* err )
01857 {
01858   iGeom_setArrData(instance, entity_handles, 
01859                    entity_handles_size, tag_handle, 
01860                    tag_value, sizeof(double)*tag_value_size, err);
01861 }
01862 
01863 ITAPS_API void
01864 iGeom_setEHArrData( iGeom_Instance instance,
01865                     const iBase_EntityHandle *entity_handles,
01866                     int entity_handles_size,
01867                     iBase_TagHandle tag_handle,
01868                     iBase_EntityHandle const *tag_values,
01869                     int tag_values_size,
01870                     int* err )
01871 {
01872   iGeom_setArrData(instance, entity_handles, 
01873                    entity_handles_size, tag_handle, 
01874                    tag_values, sizeof(iBase_EntityHandle)*tag_values_size,
01875                    err);
01876 }
01877 
01878 ITAPS_API void
01879 iGeom_setESHArrData( iGeom_Instance instance,
01880                      const iBase_EntityHandle *entity_handles,
01881                      int entity_handles_size,
01882                      iBase_TagHandle tag_handle,
01883                      iBase_EntitySetHandle const *tag_values,
01884                      int tag_values_size,
01885                      int* err )
01886 {
01887   iGeom_setArrData(instance, entity_handles,
01888                    entity_handles_size, tag_handle,
01889                    tag_values, sizeof(iBase_EntitySetHandle)*tag_values_size,
01890                    err);
01891 }
01892 
01897 ITAPS_API void
01898 iGeom_getData( iGeom_Instance instance,
01899                /*in*/ iBase_EntityHandle entity_handle,
01900                /*in*/ iBase_TagHandle tag_handle,
01901                /*inout*/ void **tag_value_tmp,
01902                int *tag_value_allocated,
01903                int *tag_value_size,
01904                int* err )
01905 {
01906   char **tag_value = reinterpret_cast<char **>(tag_value_tmp);
01907   RefEntity *tmp_entity = ENTITY_HANDLE(entity_handle);
01908   iBase_ErrorType retval = TM->getArrData(&tmp_entity, 1, TAG_HANDLE(tag_handle), 
01909                                           ARRAY_INOUT(tag_value));
01910   RETURN(retval);
01911 }
01912 
01913 ITAPS_API void
01914 iGeom_getIntData( iGeom_Instance instance,
01915                   iBase_EntityHandle entity_handle,
01916                   iBase_TagHandle tag_handle,
01917                   int* data_out,
01918                   int* err ) 
01919 {
01920   void *val_ptr = data_out;
01921   int val_size = sizeof(int);
01922   iGeom_getArrData(instance, &entity_handle, 1, 
01923                    tag_handle, &val_ptr, &val_size, &val_size, err);
01924 }
01925 
01926 ITAPS_API void
01927 iGeom_getDblData( iGeom_Instance instance,
01928                   iBase_EntityHandle entity_handle,
01929                   iBase_TagHandle tag_handle,
01930                   double* data_out,
01931                   int* err ) 
01932 {
01933   void *val_ptr = data_out;
01934   int val_size = sizeof(double);
01935   iGeom_getArrData(instance, &entity_handle, 1, 
01936                    tag_handle, &val_ptr, &val_size, &val_size, err);
01937 }
01938 
01939 ITAPS_API void
01940 iGeom_getEHData( iGeom_Instance instance,
01941                  iBase_EntityHandle entity_handle,
01942                  iBase_TagHandle tag_handle,
01943                  iBase_EntityHandle* data_out,
01944                  int* err ) 
01945 {
01946   void *val_ptr = data_out;
01947   int val_size = sizeof(iBase_EntityHandle);
01948   iGeom_getArrData(instance, &entity_handle, 1, 
01949                    tag_handle, &val_ptr, &val_size, &val_size, err);
01950 }
01951 
01952 ITAPS_API void
01953 iGeom_getESHData( iGeom_Instance instance,
01954                   iBase_EntityHandle entity_handle,
01955                   iBase_TagHandle tag_handle,
01956                   iBase_EntitySetHandle* data_out,
01957                   int* err )
01958 {
01959   void *val_ptr = data_out;
01960   int val_size = sizeof(iBase_EntitySetHandle);
01961   iGeom_getArrData(instance, &entity_handle, 1,
01962                    tag_handle, &val_ptr, &val_size, &val_size, err);
01963 }
01964 
01969 ITAPS_API void
01970 iGeom_setData( iGeom_Instance instance,
01971                /*in*/ iBase_EntityHandle entity_handle,
01972                /*in*/ iBase_TagHandle tag_handle,
01973                /*in*/ const void *tag_value_tmp,
01974                int tag_value_size,
01975                int* err )
01976 {
01977   const char *tag_value = reinterpret_cast<const char *>(tag_value_tmp);
01978   RefEntity *tmp_entity = ENTITY_HANDLE(entity_handle);
01979   iBase_ErrorType retval = TM->setArrData(&tmp_entity, 1, 
01980                                           TAG_HANDLE(tag_handle), 
01981                                           ARRAY_IN(tag_value));
01982   RETURN(retval);
01983 }
01984 
01985 ITAPS_API void
01986 iGeom_setIntData( iGeom_Instance instance,
01987                   /*in*/ iBase_EntityHandle entity_handle,
01988                   /*in*/ iBase_TagHandle tag_handle,
01989                   /*in*/ int tag_value,
01990                   int* err ) 
01991 {
01992   iGeom_setArrData(instance, &entity_handle, 1, 
01993                    tag_handle, &tag_value, sizeof(int), err);
01994 }
01995 
01996 ITAPS_API void
01997 iGeom_setDblData( iGeom_Instance instance,
01998                   /*in*/ iBase_EntityHandle entity_handle,
01999                   /*in*/ iBase_TagHandle tag_handle,
02000                   /*in*/ double tag_value,
02001                   int* err ) 
02002 {
02003   iGeom_setArrData(instance, &entity_handle, 1, 
02004                    tag_handle, &tag_value, sizeof(double), err);
02005 }
02006 
02007 ITAPS_API void
02008 iGeom_setEHData( iGeom_Instance instance,
02009                  /*in*/ iBase_EntityHandle entity_handle,
02010                  /*in*/ iBase_TagHandle tag_handle,
02011                  /*in*/ iBase_EntityHandle tag_value,
02012                  int* err ) 
02013 {
02014   iGeom_setArrData(instance, &entity_handle, 1, 
02015                    tag_handle, &tag_value, sizeof(iBase_EntityHandle), err);
02016 }
02017 
02018 ITAPS_API void
02019 iGeom_setESHData( iGeom_Instance instance,
02020                   /*in*/ iBase_EntityHandle entity_handle,
02021                   /*in*/ iBase_TagHandle tag_handle,
02022                   /*in*/ iBase_EntitySetHandle tag_value,
02023                   int* err )
02024 {
02025   iGeom_setArrData(instance, &entity_handle, 1,
02026                    tag_handle, &tag_value, sizeof(iBase_EntitySetHandle), err);
02027 }
02028 
02034 ITAPS_API void
02035 iGeom_rmvEntSetTag( iGeom_Instance instance,
02036                     /*in*/ iBase_EntitySetHandle entity_set,
02037                     /*in*/ iBase_TagHandle tag_handle,
02038                     int* err )
02039 {
02040     // have to go through RefEntity* so that RefEntity** gets set right
02041   RefEntity *tmp_entity = SET_HANDLE(entity_set);
02042   iBase_ErrorType retval = TM->rmvArrTag(&tmp_entity, 1, TAG_HANDLE(tag_handle));
02043   RETURN(retval);
02044 }
02045 
02049 ITAPS_API void
02050 iGeom_getAllEntSetTags( iGeom_Instance instance,
02051                         /*in*/ iBase_EntitySetHandle entity_set,
02052                         /*inout*/ iBase_TagHandle **tag_handles,
02053                         int *tag_handles_allocated,
02054                         int *tag_handles_size,
02055                         int* err )
02056 {
02057     // have to go through RefEntity* so that RefEntity** gets set right
02058   const RefEntity *tmp_entity = SET_HANDLE(entity_set);
02059   iBase_ErrorType retval = TM->getAllTags(tmp_entity,TAG_HANDLE_ARRAY_INOUT(tag_handles));
02060   RETURN(retval);
02061 }
02062 
02069 ITAPS_API void
02070 iGeom_getEntSetData( iGeom_Instance instance,
02071                      /*in*/ iBase_EntitySetHandle entity_set,
02072                      /*in*/ iBase_TagHandle tag_handle,
02073                      /*inout*/ void **tag_value_tmp,
02074                      int *tag_value_allocated,
02075                      int *tag_value_size,
02076                      int* err )
02077 {
02078   char **tag_value = reinterpret_cast<char **>(tag_value_tmp);
02079     // have to go through RefEntity* so that RefEntity** gets set right
02080   RefEntity *tmp_entity = SET_HANDLE(entity_set);
02081   iBase_ErrorType retval = TM->getArrData(&tmp_entity, 1, TAG_HANDLE(tag_handle), 
02082                                           ARRAY_INOUT(tag_value));
02083   RETURN(retval);
02084 }
02085 
02086 ITAPS_API void
02087 iGeom_getEntSetIntData( iGeom_Instance instance,
02088                         /*in*/ iBase_EntitySetHandle entity_set,
02089                         /*in*/ iBase_TagHandle tag_handle,
02090                         int* tag_ptr,
02091                         int* err ) 
02092 {
02093   int tag_size = sizeof(int);
02094   void* data_ptr = tag_ptr;
02095   iGeom_getEntSetData(instance, entity_set, tag_handle, &data_ptr, 
02096                       &tag_size, &tag_size, err);
02097 }
02098 
02099 ITAPS_API void
02100 iGeom_getEntSetDblData( iGeom_Instance instance,
02101                         /*in*/ iBase_EntitySetHandle entity_set,
02102                         /*in*/ iBase_TagHandle tag_handle,
02103                         double* tag_ptr,
02104                         int* err ) 
02105 {
02106   int tag_size = sizeof(double);
02107   void* data_ptr = tag_ptr;
02108   iGeom_getEntSetData(instance, entity_set, tag_handle, &data_ptr, 
02109                       &tag_size, &tag_size, err);
02110 }
02111 
02112 ITAPS_API void
02113 iGeom_getEntSetEHData( iGeom_Instance instance,
02114                        /*in*/ iBase_EntitySetHandle entity_set,
02115                        /*in*/ iBase_TagHandle tag_handle,
02116                        iBase_EntityHandle* tag_ptr,
02117                        int* err ) 
02118 {
02119   int tag_size = sizeof(iBase_EntityHandle);
02120   void* data_ptr = tag_ptr;
02121   iGeom_getEntSetData(instance, entity_set, tag_handle, &data_ptr, 
02122                       &tag_size, &tag_size, err);
02123 }
02124 
02125 ITAPS_API void
02126 iGeom_getEntSetESHData( iGeom_Instance instance,
02127                         /*in*/ iBase_EntitySetHandle entity_set,
02128                         /*in*/ iBase_TagHandle tag_handle,
02129                         iBase_EntitySetHandle* tag_ptr,
02130                         int* err )
02131 {
02132   int tag_size = sizeof(iBase_EntitySetHandle);
02133   void* data_ptr = tag_ptr;
02134   iGeom_getEntSetData(instance, entity_set, tag_handle, &data_ptr,
02135                       &tag_size, &tag_size, err);
02136 }
02137 
02142 ITAPS_API void
02143 iGeom_setEntSetData( iGeom_Instance instance,
02144                      /*in*/ iBase_EntitySetHandle entity_set,
02145                      /*in*/ iBase_TagHandle tag_handle,
02146                      /*in*/ const void *tag_value_tmp,
02147                      int tag_value_size,
02148                      int* err )
02149 {
02150   const char *tag_value = reinterpret_cast<const char *>(tag_value_tmp);
02151     // have to go through RefEntity* so that RefEntity** gets set right
02152   RefEntity *tmp_entity = SET_HANDLE(entity_set);
02153   iBase_ErrorType retval = TM->setArrData(&tmp_entity, 1, TAG_HANDLE(tag_handle), 
02154                                           ARRAY_IN(tag_value));
02155   RETURN(retval);
02156 }
02157 
02158 ITAPS_API void
02159 iGeom_setEntSetIntData( iGeom_Instance instance,
02160                         /*in*/ iBase_EntitySetHandle entity_set,
02161                         /*in*/ iBase_TagHandle tag_handle,
02162                         /*in*/ int tag_value,
02163                         int* err )
02164 {
02165   iGeom_setEntSetData(instance, entity_set, tag_handle, 
02166                       &tag_value, sizeof(int), err);
02167 }
02168 
02169 ITAPS_API void
02170 iGeom_setEntSetDblData( iGeom_Instance instance,
02171                         /*in*/ iBase_EntitySetHandle entity_set,
02172                         /*in*/ iBase_TagHandle tag_handle,
02173                         /*in*/ double tag_value,
02174                         int* err )
02175 {
02176   iGeom_setEntSetData(instance, entity_set, tag_handle, 
02177                       &tag_value, sizeof(double), err);
02178 }
02179 
02180 ITAPS_API void
02181 iGeom_setEntSetEHData( iGeom_Instance instance,
02182                        /*in*/ iBase_EntitySetHandle entity_set,
02183                        /*in*/ iBase_TagHandle tag_handle,
02184                        /*in*/ iBase_EntityHandle tag_value,
02185                        int* err )
02186 {
02187   iGeom_setEntSetData(instance, entity_set, tag_handle, 
02188                       &tag_value,
02189                       sizeof(iBase_EntityHandle), err);
02190 }
02191 
02192 ITAPS_API void
02193 iGeom_setEntSetESHData( iGeom_Instance instance,
02194                         /*in*/ iBase_EntitySetHandle entity_set,
02195                         /*in*/ iBase_TagHandle tag_handle,
02196                         /*in*/ iBase_EntitySetHandle tag_value,
02197                         int* err )
02198 {
02199   iGeom_setEntSetData(instance, entity_set, tag_handle,
02200                       &tag_value, sizeof(iBase_EntitySetHandle), err);
02201 }
02202 
02203 ITAPS_API void
02204 iGeom_getEntClosestPt( iGeom_Instance instance,
02205                        /*in*/ iBase_EntityHandle entity_handle,
02206                        /*in*/ double near_x,
02207                        /*in*/ double near_y,
02208                        /*in*/ double near_z,
02209                        /*out*/ double* on_x,
02210                        /*out*/ double* on_y, 
02211                        /*out*/ double* on_z,
02212                        int* err )
02213 {
02214   RefEntity* entity = (RefEntity*)entity_handle;
02215   CubitVector on, near(near_x, near_y, near_z);
02216   CubitStatus status = iGeom_closest_point( entity, near, on );
02217   if (status == CUBIT_FAILURE) {
02218     ERROR(iBase_FAILURE, "Problems getting closest point for some entity.");
02219   }
02220   on.get_xyz( *on_x, *on_y, *on_z );
02221   RETURN(iBase_SUCCESS);
02222 }
02223 
02224 ITAPS_API void
02225 iGeom_getEntClosestPtTrimmed( iGeom_Instance instance,
02226                               iBase_EntityHandle entity_handle,
02227                               double near_x,
02228                               double near_y,
02229                               double near_z,
02230                               double* on_x,
02231                               double* on_y,
02232                               double* on_z,
02233                               int* err )
02234 {
02235   RefEntity* entity = (RefEntity*)entity_handle;
02236   CubitVector on, near(near_x, near_y, near_z);
02237   CubitStatus status = iGeom_closest_point_trimmed( entity, near, on );
02238   if (status == CUBIT_FAILURE) {
02239     ERROR(iBase_FAILURE, "Problems getting closest point for some entity.");
02240   }
02241   on.get_xyz( *on_x, *on_y, *on_z );
02242   RETURN(iBase_SUCCESS);
02243 }
02244  
02253 ITAPS_API void
02254 iGeom_getArrClosestPt( iGeom_Instance instance,
02255                        /*in*/ iBase_EntityHandle const *gentity_handles,
02256                        int gentity_handles_size,
02257                        /*in*/ int storage_order,
02258                        /*in*/ const double *near_coordinates,
02259                        int near_coordinates_size,
02260                        /*out*/ double **on_coordinates,
02261                        int *on_coordinates_allocated,
02262                        int *on_coordinates_size,
02263                        int* err )
02264 {
02265     /* set up iteration according to storage order.
02266        allow either gentity_handles or near_coordinates to contain
02267        only one value, where that single value is applied for every
02268        entry in the other list.
02269     */
02270   size_t near_step, on_step = 1, ent_step;
02271   int count;
02272   if (3*gentity_handles_size == near_coordinates_size) {
02273     near_step = ent_step = 1;
02274     count = gentity_handles_size;
02275   }
02276   else if (near_coordinates_size == 3) {
02277     near_step = 0;
02278     ent_step = 1;
02279     count = gentity_handles_size;
02280   }
02281   else if (gentity_handles_size == 1) {
02282     near_step = 1;
02283     ent_step = 0;
02284     count = near_coordinates_size / 3;
02285   }
02286   else {
02287     ERROR( iBase_INVALID_ENTITY_COUNT, "Mismatched array sizes" );
02288   }
02289   ALLOC_CHECK_ARRAY( on_coordinates, 3*count );
02290   
02291   const double *near_x, *near_y, *near_z;
02292   double *on_x, *on_y, *on_z;
02293   if (storage_order == iBase_BLOCKED) {
02294     near_x = near_coordinates;
02295     near_y = near_x + near_coordinates_size/3;
02296     near_z = near_y + near_coordinates_size/3;
02297     on_x = *on_coordinates;
02298     on_y = on_x + count;
02299     on_z = on_y + count;
02300     on_step = 1;
02301   }
02302   else {
02303     storage_order = iBase_INTERLEAVED; /* set if unspecified */
02304     near_x = near_coordinates;
02305     near_y = near_x+1;
02306     near_z = near_x+2;
02307     on_x = *on_coordinates;
02308     on_y = on_x+1;
02309     on_z = on_x+2;
02310     near_step *= 3;
02311     on_step = 3;
02312   }
02313   
02314   RefEntity** ent_iter = (RefEntity**)(gentity_handles);
02315   CubitStatus final_result = CUBIT_SUCCESS;
02316   for (int i = 0; i < count; ++i) {
02317     CubitVector on, near( *near_x, *near_y, *near_z );
02318     CubitStatus status = iGeom_closest_point( *ent_iter, near, on );
02319     if (status != CUBIT_SUCCESS)
02320       final_result = status;
02321     on.get_xyz( *on_x, *on_y, *on_z );
02322     
02323     ent_iter += ent_step;
02324     near_x += near_step;
02325     near_y += near_step;
02326     near_z += near_step;
02327     on_x += on_step;
02328     on_y += on_step;
02329     on_z += on_step;
02330   }
02331   
02332   if (final_result == CUBIT_FAILURE) {
02333     ERROR(iBase_FAILURE, "Problems getting closest point for some entity.");
02334   }
02335 
02336   KEEP_ARRAY(on_coordinates);
02337   RETURN(iBase_SUCCESS);
02338 }
02339 
02340 
02341 ITAPS_API void
02342 iGeom_getEntNrmlPlXYZ( iGeom_Instance instance,
02343                        /*in*/ iBase_EntityHandle entity_handle,
02344                        /*in*/ double x,
02345                        /*in*/ double y,
02346                        /*in*/ double z,
02347                        /*out*/ double* pt_x,
02348                        /*out*/ double* pt_y, 
02349                        /*out*/ double* pt_z,
02350                        /*out*/ double* nmrl_i,
02351                        /*out*/ double* nmrl_j, 
02352                        /*out*/ double* nmrl_k,
02353                        int* err )
02354 {
02355   RefEntity* entity = (RefEntity*)entity_handle;
02356   CubitVector pt, nmrl, near(x, y, z);
02357   CubitStatus status = iGeom_closest_point_and_normal( entity, near, pt, nmrl );
02358   if (status == CUBIT_FAILURE) {
02359     ERROR(iBase_FAILURE, "Problems getting closest point for some entity.");
02360   }
02361   pt.get_xyz( *pt_x, *pt_y, *pt_z );
02362   nmrl.get_xyz( *nmrl_i, *nmrl_j, *nmrl_k );
02363   RETURN(iBase_SUCCESS);
02364 }
02365 
02375 ITAPS_API void
02376 iGeom_getArrNrmlPlXYZ( iGeom_Instance instance,
02377                        /*in*/ iBase_EntityHandle const *gentity_handles,
02378                        const int gentity_handles_size,
02379                        /*in*/ int storage_order,
02380                        /*in*/ const double *near_coordinates,
02381                        const int near_coordinates_size,
02382                        /*out*/ double **on_coordinates,
02383                        int *on_coordinates_allocated,
02384                        int *on_coordinates_size,
02385                        /*out*/ double **normals,
02386                        int *normals_allocated,
02387                        int *normals_size,
02388                        int* err )
02389 {
02390     /* set up iteration according to storage order.
02391        allow either gentity_handles or near_coordinates to contain
02392        only one value, where that single value is applied for every
02393        entry in the other list.
02394     */
02395   size_t near_step, on_step = 1, ent_step;
02396   int count;
02397   if (3*gentity_handles_size == near_coordinates_size) {
02398     near_step = ent_step = 1;
02399     count = gentity_handles_size;
02400   }
02401   else if (near_coordinates_size == 3) {
02402     near_step = 0;
02403     ent_step = 1;
02404     count = gentity_handles_size;
02405   }
02406   else if (gentity_handles_size == 1) {
02407     near_step = 1;
02408     ent_step = 0;
02409     count = near_coordinates_size / 3;
02410   }
02411   else {
02412     ERROR( iBase_INVALID_ENTITY_COUNT, "Mismatched array sizes" );
02413   }
02414   ALLOC_CHECK_ARRAY( on_coordinates, 3*count );
02415   ALLOC_CHECK_ARRAY( normals, 3*count );
02416   
02417   const double *near_x, *near_y, *near_z;
02418   double *on_x, *on_y, *on_z;
02419   double *norm_x, *norm_y, *norm_z;
02420   if (storage_order == iBase_BLOCKED) {
02421     near_x = near_coordinates;
02422     near_y = near_x + near_coordinates_size/3;
02423     near_z = near_y + near_coordinates_size/3;
02424     on_x = *on_coordinates;
02425     on_y = on_x + count;
02426     on_z = on_y + count;
02427     norm_x = *normals;
02428     norm_y = norm_x + count;
02429     norm_z = norm_y + count;
02430     on_step = 1;
02431   }
02432   else {
02433     storage_order = iBase_INTERLEAVED; /* set if unspecified */
02434     near_x = near_coordinates;
02435     near_y = near_x+1;
02436     near_z = near_x+2;
02437     on_x = *on_coordinates;
02438     on_y = on_x+1;
02439     on_z = on_x+2;
02440     norm_x = *normals;
02441     norm_y = norm_x+1;
02442     norm_z = norm_x+2;
02443     near_step *= 3;
02444     on_step = 3;
02445   }
02446   
02447   RefEntity** ent_iter = (RefEntity**)(gentity_handles);
02448   CubitStatus final_result = CUBIT_SUCCESS;
02449   for (int i = 0; i < count; ++i) {
02450     CubitVector on, norm, near( *near_x, *near_y, *near_z );
02451     CubitStatus status = iGeom_closest_point_and_normal( *ent_iter, near, on, norm );
02452     if (status != CUBIT_SUCCESS)
02453       final_result = status;
02454     on.get_xyz( *on_x, *on_y, *on_z );
02455     norm.get_xyz( *norm_x, *norm_y, *norm_z );
02456     
02457     ent_iter += ent_step;
02458     near_x += near_step;
02459     near_y += near_step;
02460     near_z += near_step;
02461     on_x += on_step;
02462     on_y += on_step;
02463     on_z += on_step;
02464     norm_x += on_step;
02465     norm_y += on_step;
02466     norm_z += on_step;
02467   }
02468   
02469   if (final_result == CUBIT_FAILURE) {
02470     ERROR(iBase_FAILURE, "Problems getting closest point for some entity.");
02471   }
02472 
02473   KEEP_ARRAY(on_coordinates);
02474   KEEP_ARRAY(normals);
02475   RETURN(iBase_SUCCESS);
02476 }
02477 
02478 ITAPS_API void
02479 iGeom_getEntNrmlXYZ( iGeom_Instance instance,
02480                      /*in*/ iBase_EntityHandle entity_handle,
02481                      /*in*/ double near_x,
02482                      /*in*/ double near_y,
02483                      /*in*/ double near_z,
02484                      /*out*/ double* nmrl_i,
02485                      /*out*/ double* nmrl_j, 
02486                      /*out*/ double* nmrl_k,
02487                      int* err )
02488 {
02489   RefEntity* entity = (RefEntity*)entity_handle;
02490   RefFace* face = dynamic_cast<RefFace*>(entity);
02491   if (NULL == face) {
02492     ERROR(iBase_INVALID_ENTITY_TYPE, "Entities passed into gentityNormal must be faces.");
02493   }
02494   
02495   CubitVector normal, near( near_x, near_y, near_z );
02496   normal = face->normal_at( near );
02497   normal.get_xyz( *nmrl_i, *nmrl_j, *nmrl_k );
02498   RETURN(iBase_SUCCESS);
02499 } 
02500 
02509 ITAPS_API void
02510 iGeom_getArrNrmlXYZ( iGeom_Instance instance,
02511                      /*in*/ iBase_EntityHandle const *gentity_handles,
02512                      int gentity_handles_size,
02513                      int storage_order,
02514                      /*in*/ const double *coordinates,
02515                      int coordinates_size,
02516                      /*out*/ double **normals,
02517                      int *normals_allocated,
02518                      int *normals_size,
02519                      int* err )
02520 {
02521     /* set up iteration according to storage order.
02522        allow either gentity_handles or near_coordinates to contain
02523        only one value, where that single value is applied for every
02524        entry in the other list.
02525     */
02526   size_t coord_step, norm_step = 1, ent_step;
02527   int count;
02528   if (3*gentity_handles_size == coordinates_size) {
02529     coord_step = ent_step = 1;
02530     count = gentity_handles_size;
02531   }
02532   else if (coordinates_size == 3) {
02533     coord_step = 0;
02534     ent_step = 1;
02535     count = gentity_handles_size;
02536   }
02537   else if (gentity_handles_size == 1) {
02538     coord_step = 1;
02539     ent_step = 0;
02540     count = coordinates_size / 3;
02541   }
02542   else {
02543     ERROR( iBase_INVALID_ENTITY_COUNT, "Mismatched array sizes" );
02544   }
02545 
02546     // check or pre-allocate the coordinate arrays
02547   ALLOC_CHECK_ARRAY( normals, 3*count );
02548   
02549   const double *coord_x, *coord_y, *coord_z;
02550   double *norm_x, *norm_y, *norm_z;
02551   if (storage_order == iBase_BLOCKED) {
02552     coord_x = coordinates;
02553     coord_y = coord_x + coordinates_size/3;
02554     coord_z = coord_y + coordinates_size/3;
02555     norm_x = *normals;
02556     norm_y = norm_x + count;
02557     norm_z = norm_y + count;
02558     norm_step = 1;
02559   }
02560   else {
02561     storage_order = iBase_INTERLEAVED; /* set if unspecified */
02562     coord_x = coordinates;
02563     coord_y = coord_x+1;
02564     coord_z = coord_x+2;
02565     norm_x = *normals;
02566     norm_y = norm_x+1;
02567     norm_z = norm_x+2;
02568     coord_step *= 3;
02569     norm_step = 3;
02570   }
02571   
02572   RefEntity** entities = (RefEntity**)(gentity_handles);
02573   for (int i = 0; i < count; ++i)
02574   {
02575     RefFace* face = dynamic_cast<RefFace*>(*entities);
02576     if (NULL == face) {
02577       ERROR(iBase_INVALID_ENTITY_TYPE, "Entities passed into gentityNormal must be faces.");
02578     }
02579     else {
02580       CubitVector normal, coords( *coord_x, *coord_y, *coord_z );
02581       normal = face->normal_at( coords );
02582       normal.get_xyz( *norm_x, *norm_y, *norm_z );
02583     }
02584     entities += ent_step;
02585     coord_x += coord_step;
02586     coord_y += coord_step;
02587     coord_z += coord_step;
02588     norm_x += norm_step;
02589     norm_y += norm_step;
02590     norm_z += norm_step;
02591   }
02592 
02593   KEEP_ARRAY(normals);
02594   RETURN(iBase_SUCCESS);
02595 }
02596 
02597 
02598 ITAPS_API void
02599 iGeom_getEntTgntXYZ( iGeom_Instance instance,
02600                      /*in*/ iBase_EntityHandle entity_handle,
02601                      /*in*/ double x,
02602                      /*in*/ double y,
02603                      /*in*/ double z,
02604                      /*out*/ double* tgnt_i,
02605                      /*out*/ double* tgnt_j, 
02606                      /*out*/ double* tgnt_k,
02607                      int* err )
02608 {
02609   RefEntity* entity = (RefEntity*)entity_handle;
02610   RefEdge* edge = dynamic_cast<RefEdge*>(entity);
02611   if (NULL == edge) {
02612     ERROR(iBase_INVALID_ENTITY_TYPE, "Entities passed into gentityTangent must be edges.");
02613   }
02614   
02615   CubitVector tangent, near( x, y, x );
02616   edge->tangent( near, tangent );
02617   tangent.get_xyz( *tgnt_i, *tgnt_j, *tgnt_k );
02618   RETURN(iBase_SUCCESS);
02619 } 
02620 
02629 ITAPS_API void
02630 iGeom_getArrTgntXYZ( iGeom_Instance instance,
02631                      /*in*/ iBase_EntityHandle const *gentity_handles,
02632                      int gentity_handles_size,
02633                      /*in*/ int storage_order,
02634                      /*in*/ const double *coordinates,
02635                      int coordinates_size,
02636                      /*out*/ double **tangents,
02637                      int *tangents_allocated,
02638                      int *tangents_size,
02639                      int* err )
02640 {
02641     /* set up iteration according to storage order.
02642        allow either gentity_handles or near_coordinates to contain
02643        only one value, where that single value is applied for every
02644        entry in the other list.
02645     */
02646   size_t coord_step, tan_step = 1, ent_step;
02647   int count;
02648   if (3*gentity_handles_size == coordinates_size) {
02649     coord_step = ent_step = 1;
02650     count = gentity_handles_size;
02651   }
02652   else if (coordinates_size == 3) {
02653     coord_step = 0;
02654     ent_step = 1;
02655     count = gentity_handles_size;
02656   }
02657   else if (gentity_handles_size == 1) {
02658     coord_step = 1;
02659     ent_step = 0;
02660     count = coordinates_size / 3;
02661   }
02662   else {
02663     ERROR( iBase_INVALID_ENTITY_COUNT, "Mismatched array sizes" );
02664   }
02665 
02666     // check or pre-allocate the coordinate arrays
02667   ALLOC_CHECK_ARRAY( tangents, 3*count );
02668   
02669   const double *coord_x, *coord_y, *coord_z;
02670   double *tan_x, *tan_y, *tan_z;
02671   if (storage_order == iBase_BLOCKED) {
02672     coord_x = coordinates;
02673     coord_y = coord_x + coordinates_size/3;
02674     coord_z = coord_y + coordinates_size/3;
02675     tan_x = *tangents;
02676     tan_y = tan_x + count;
02677     tan_z = tan_y + count;
02678     tan_step = 1;
02679   }
02680   else {
02681     storage_order = iBase_INTERLEAVED; /* set if unspecified */
02682     coord_x = coordinates;
02683     coord_y = coord_x+1;
02684     coord_z = coord_x+2;
02685     tan_x = *tangents;
02686     tan_y = tan_x+1;
02687     tan_z = tan_x+2;
02688     coord_step *= 3;
02689     tan_step = 3;
02690   }
02691   
02692   RefEntity** entities = (RefEntity**)(gentity_handles);
02693   for (int i = 0; i < count; ++i)
02694   {
02695     RefEdge* edge = dynamic_cast<RefEdge*>(*entities);
02696     if (NULL == edge) {
02697       ERROR(iBase_INVALID_ENTITY_TYPE, "Entities passed into gentityTangent must be edges.");
02698     }
02699     else {
02700       CubitVector tangent, coords( *coord_x, *coord_y, *coord_z );
02701       edge->tangent( coords, tangent );
02702       tangent.get_xyz( *tan_x, *tan_y, *tan_z );
02703     }
02704     
02705     entities += ent_step;
02706     coord_x += coord_step;
02707     coord_y += coord_step;
02708     coord_z += coord_step;
02709     tan_x += tan_step;
02710     tan_y += tan_step;
02711     tan_z += tan_step;
02712   }
02713 
02714   KEEP_ARRAY(tangents);
02715   RETURN(iBase_SUCCESS);
02716 }
02717 
02718 
02719 ITAPS_API void
02720 iGeom_getFcCvtrXYZ( iGeom_Instance instance,
02721                     /*in*/ iBase_EntityHandle face_handle,
02722                     /*in*/ double x,
02723                     /*in*/ double y,
02724                     /*in*/ double z,
02725                     /*out*/ double* cvtr1_i,
02726                     /*out*/ double* cvtr1_j,
02727                     /*out*/ double* cvtr1_k,
02728                     /*out*/ double* cvtr2_i,
02729                     /*out*/ double* cvtr2_j,
02730                     /*out*/ double* cvtr2_k,
02731                     int* err )
02732 {
02733   RefEntity* entity = (RefEntity*)face_handle;
02734   RefFace* face = dynamic_cast<RefFace*>(entity);
02735   if (!face)
02736     RETURN(iBase_INVALID_ENTITY_TYPE);
02737   
02738   Surface* surf = face->get_surface_ptr();
02739   CubitVector loc(x,y,z), curv1, curv2;
02740   CubitStatus status = surf->closest_point( loc, 0, 0, &curv1, &curv2 );
02741   if (surf->bridge_sense() == CUBIT_REVERSED) {
02742     curv1 = -curv1;
02743     curv2 = -curv2;
02744   }
02745   curv1.get_xyz( *cvtr1_i, *cvtr1_j, *cvtr1_k );
02746   curv2.get_xyz( *cvtr2_i, *cvtr2_j, *cvtr2_k );
02747   RETURN( (status == CUBIT_SUCCESS ? iBase_SUCCESS : iBase_FAILURE) );
02748 }
02749 
02750 ITAPS_API void
02751 iGeom_getEgCvtrXYZ( iGeom_Instance instance,
02752                     /*in*/ iBase_EntityHandle edge_handle,
02753                     /*in*/ double x,
02754                     /*in*/ double y,
02755                     /*in*/ double z,
02756                     /*out*/ double* cvtr_i,
02757                     /*out*/ double* cvtr_j,
02758                     /*out*/ double* cvtr_k,
02759                     int* err )
02760 {
02761   RefEntity* entity = (RefEntity*)edge_handle;
02762   RefEdge* edge = dynamic_cast<RefEdge*>(entity);
02763   if (!edge)
02764     RETURN(iBase_INVALID_ENTITY_TYPE);
02765   
02766   CubitVector loc(x,y,z), junk, curv;
02767   CubitStatus status = edge->closest_point( loc, junk, 0, &curv );
02768   curv.get_xyz( *cvtr_i, *cvtr_j, *cvtr_k );
02769   RETURN( (status == CUBIT_SUCCESS ? iBase_SUCCESS : iBase_FAILURE) );
02770 }
02771 
02772 ITAPS_API void
02773 iGeom_getEntArrCvtrXYZ( iGeom_Instance instance,
02774                         /*in*/ const iBase_EntityHandle *entity_handles,
02775                         int entity_handles_size,
02776                         /*in*/ int storage_order,
02777                         /*in*/ const double *coordinates,
02778                         int coordinates_size,
02779                         /*inout*/ double **cvtr_1,
02780                         int *cvtr_1_allocated,
02781                         int *cvtr_1_size,
02782                         /*inout*/ double **cvtr_2,
02783                         int *cvtr_2_allocated,
02784                         int *cvtr_2_size,
02785                         int* err )
02786 {
02787   RefEntity** entities = (RefEntity**)(entity_handles);
02788   
02789     /* set up iteration according to storage order.
02790        allow either gentity_handles or near_coordinates to contain
02791        only one value, where that single value is applied for every
02792        entry in the other list.
02793     */
02794   size_t coord_step, cvtr_step = 1, ent_step;
02795   int count;
02796   if (3*entity_handles_size == coordinates_size) {
02797     coord_step = ent_step = 1;
02798     count = entity_handles_size;
02799   }
02800   else if (coordinates_size == 3) {
02801     coord_step = 0;
02802     ent_step = 1;
02803     count = entity_handles_size;
02804   }
02805   else if (entity_handles_size == 1) {
02806     coord_step = 1;
02807     ent_step = 0;
02808     count = coordinates_size / 3;
02809   }
02810   else {
02811     ERROR( iBase_INVALID_ENTITY_COUNT, "Mismatched array sizes" );
02812   }
02813   
02814     /* check if input list contains any surfaces. */
02815   bool have_surfs = false;
02816   for (int s = 0; s < entity_handles_size; ++s)
02817     if (dynamic_cast<RefFace*>(entities[s])) {
02818       have_surfs = true;
02819       break;
02820     }
02821 
02822     // check or pre-allocate the coordinate arrays
02823   ALLOC_CHECK_ARRAY( cvtr_1, 3*count );
02824   ALLOC_CHECK_ARRAY( cvtr_2, have_surfs ? 3*count : 0 );
02825   
02826   const double *coord_x, *coord_y, *coord_z;
02827   double *c1x, *c1y, *c1z, *c2x, *c2y, *c2z;
02828   if (storage_order == iBase_BLOCKED) {
02829     coord_x = coordinates;
02830     coord_y = coord_x + coordinates_size/3;
02831     coord_z = coord_y + coordinates_size/3;
02832     c1x = *cvtr_1;
02833     c1y = c1x + count;
02834     c1z = c1y + count;
02835     c2x = *cvtr_2;
02836     c2y = c2x + count;
02837     c2z = c2y + count;
02838     cvtr_step = 1;
02839   }
02840   else {
02841     storage_order = iBase_INTERLEAVED; /* set if unspecified */
02842     coord_x = coordinates;
02843     coord_y = coord_x+1;
02844     coord_z = coord_x+2;
02845     c1x = *cvtr_1;
02846     c1y = c1x+1;
02847     c1z = c1x+2;
02848     c2x = *cvtr_2;
02849     c2y = c2x+1;
02850     c2z = c2x+2;
02851     coord_step *= 3;
02852     cvtr_step = 3;
02853   }
02854   
02855   RefFace *face;
02856   RefEdge *edge;
02857   CubitStatus result = CUBIT_SUCCESS;
02858   for (int i = 0; i < count; ++i) {
02859     CubitStatus status;
02860     const CubitVector coords( *coord_x, *coord_y, *coord_z );
02861     if ((face = dynamic_cast<RefFace*>(*entities))) {
02862       Surface* surf = face->get_surface_ptr();
02863       CubitVector curv1, curv2;
02864       status = surf->closest_point( coords, 0, 0, &curv1, &curv2 );
02865       curv1.get_xyz( *c1x, *c1y, *c1z );
02866       curv2.get_xyz( *c2x, *c2y, *c2z );
02867     }
02868     else if ((edge = dynamic_cast<RefEdge*>(*entities))) {
02869       CubitVector junk, curv;
02870       status = edge->closest_point( coords, junk, 0, &curv );
02871       curv.get_xyz( *c1x, *c1y, *c1z );
02872     }
02873     else {
02874       status = CUBIT_FAILURE;
02875     }
02876 
02877     if (CUBIT_SUCCESS != status)
02878       result = status;
02879     
02880     entities += ent_step;
02881     coord_x += coord_step;
02882     coord_y += coord_step;
02883     coord_z += coord_step;
02884     c1x += cvtr_step;
02885     c1y += cvtr_step;
02886     c1z += cvtr_step;
02887     c2x += cvtr_step;
02888     c2y += cvtr_step;
02889     c2z += cvtr_step;
02890   }
02891   
02892   if (result == CUBIT_FAILURE)
02893     RETURN(iBase_FAILURE);
02894   
02895   KEEP_ARRAY( cvtr_1 );
02896   KEEP_ARRAY( cvtr_2 );
02897   RETURN( iBase_SUCCESS );
02898 }
02899 
02900 
02901 ITAPS_API void
02902 iGeom_getEgEvalXYZ( iGeom_Instance instance,
02903                     /*in*/ iBase_EntityHandle edge_handle,
02904                     /*in*/ double x,
02905                     /*in*/ double y,
02906                     /*in*/ double z,
02907                     /*out*/ double* on_x,
02908                     /*out*/ double* on_y,
02909                     /*out*/ double* on_z,
02910                     /*out*/ double* tan_i,
02911                     /*out*/ double* tan_j,
02912                     /*out*/ double* tan_k,
02913                     /*out*/ double* cvtr_i,
02914                     /*out*/ double* cvtr_j,
02915                     /*out*/ double* cvtr_k,
02916                     int* err )
02917 {
02918   RefEntity* entity = (RefEntity*)edge_handle;
02919   RefEdge* edge = dynamic_cast<RefEdge*>(entity);
02920   if (!edge)
02921     RETURN(iBase_INVALID_ENTITY_TYPE);
02922   
02923   CubitVector loc(x,y,z), on, tan, curv;
02924   CubitStatus status = edge->closest_point( loc, on, &tan, &curv );
02925   on.get_xyz( *on_x, *on_y, *on_z );
02926   tan.get_xyz( *tan_i, *tan_j, *tan_k );
02927   curv.get_xyz( *cvtr_i, *cvtr_j, *cvtr_k );
02928   RETURN( (status == CUBIT_SUCCESS ? iBase_SUCCESS : iBase_FAILURE) );
02929 }
02930 
02931 ITAPS_API void
02932 iGeom_getFcEvalXYZ( iGeom_Instance instance,
02933                     /*in*/ iBase_EntityHandle face_handle,
02934                     /*in*/ double x,
02935                     /*in*/ double y,
02936                     /*in*/ double z,
02937                     /*out*/ double* on_x,
02938                     /*out*/ double* on_y,
02939                     /*out*/ double* on_z,
02940                     /*out*/ double* norm_i,
02941                     /*out*/ double* norm_j,
02942                     /*out*/ double* norm_k,
02943                     /*out*/ double* cvtr1_i,
02944                     /*out*/ double* cvtr1_j,
02945                     /*out*/ double* cvtr1_k,
02946                     /*out*/ double* cvtr2_i,
02947                     /*out*/ double* cvtr2_j,
02948                     /*out*/ double* cvtr2_k,
02949                     int* err )
02950 {
02951   RefEntity* entity = (RefEntity*)face_handle;
02952   RefFace* face = dynamic_cast<RefFace*>(entity);
02953   if (!face)
02954     RETURN(iBase_INVALID_ENTITY_TYPE);
02955   
02956   Surface* surf = face->get_surface_ptr();
02957   CubitVector loc(x,y,z), on, norm, curv1, curv2;
02958 #ifdef CGM_HAVE_FACET_ENGINE_ONLY
02959   CubitStatus status = surf->closest_point( loc, &on, &norm);
02960 #else
02961   CubitStatus status = surf->closest_point( loc, &on, &norm, &curv1, &curv2 );
02962 #endif
02963 
02964   if (surf->bridge_sense() == CUBIT_REVERSED) {
02965     norm = -norm;
02966     curv1 = -curv1;
02967     curv2 = -curv2;
02968   }
02969   on.get_xyz( *on_x, *on_y, *on_z );
02970   norm.get_xyz( *norm_i, *norm_j, *norm_k );
02971   curv1.get_xyz( *cvtr1_i, *cvtr1_j, *cvtr1_k );
02972   curv2.get_xyz( *cvtr2_i, *cvtr2_j, *cvtr2_k );
02973   RETURN( (status == CUBIT_SUCCESS ? iBase_SUCCESS : iBase_FAILURE) );
02974 }
02975                        
02976 ITAPS_API void
02977 iGeom_getArrEgEvalXYZ( iGeom_Instance instance,
02978                        /*in*/ const iBase_EntityHandle *edge_handles,
02979                        int edge_handles_size,
02980                        /*in*/ int storage_order,
02981                        /*in*/ const double *coordinates,
02982                        int coordinates_size,
02983                        /*inout*/ double **on_coords,
02984                        int *on_coords_allocated,
02985                        int *on_coords_size,
02986                        /*inout*/ double **tangents,
02987                        int *tangents_allocated,
02988                        int *tangents_size,
02989                        /*inout*/ double **curvatures,
02990                        int *curvatures_allocated,
02991                        int *curvatures_size,
02992                        int* err )
02993 {
02994     /* set up iteration according to storage order.
02995        allow either gentity_handles or near_coordinates to contain
02996        only one value, where that single value is applied for every
02997        entry in the other list.
02998     */
02999   size_t coord_step, on_step = 1, ent_step;
03000   int count;
03001   if (3*edge_handles_size == coordinates_size) {
03002     coord_step = ent_step = 1;
03003     count = edge_handles_size;
03004   }
03005   else if (coordinates_size == 3) {
03006     coord_step = 0;
03007     ent_step = 1;
03008     count = edge_handles_size;
03009   }
03010   else if (edge_handles_size == 1) {
03011     coord_step = 1;
03012     ent_step = 0;
03013     count = coordinates_size / 3;
03014   }
03015   else {
03016     ERROR( iBase_INVALID_ENTITY_COUNT, "Mismatched array sizes" );
03017   }
03018 
03019     // check or pre-allocate the coordinate arrays
03020   ALLOC_CHECK_ARRAY( on_coords, 3*count );
03021   ALLOC_CHECK_ARRAY( tangents, 3*count );
03022   ALLOC_CHECK_ARRAY( curvatures, 3*count );
03023   
03024   const double *coord_x, *coord_y, *coord_z;
03025   double *on_x, *on_y, *on_z;
03026   double *tan_x, *tan_y, *tan_z;
03027   double *curv_x, *curv_y, *curv_z;
03028   if (storage_order == iBase_BLOCKED) {
03029     coord_x = coordinates;
03030     coord_y = coord_x + coordinates_size/3;
03031     coord_z = coord_y + coordinates_size/3;
03032     on_x = *on_coords;
03033     on_y = on_x + count;
03034     on_z = on_y + count;
03035     tan_x = *tangents;
03036     tan_y = tan_x + count;
03037     tan_z = tan_y + count;
03038     curv_x = *curvatures;
03039     curv_y = curv_x + count;
03040     curv_z = curv_y + count;
03041     on_step = 1;
03042   }
03043   else {
03044     storage_order = iBase_INTERLEAVED; /* set if unspecified */
03045     coord_x = coordinates;
03046     coord_y = coord_x+1;
03047     coord_z = coord_x+2;
03048     on_x = *on_coords;
03049     on_y = on_x + 1;
03050     on_z = on_x + 2;
03051     tan_x = *tangents;
03052     tan_y = tan_x+1;
03053     tan_z = tan_x+2;
03054     curv_x = *curvatures;
03055     curv_y = curv_x + 1;
03056     curv_z = curv_x + 2;
03057     coord_step *= 3;
03058     on_step = 3;
03059   }
03060   
03061   RefEntity** ent_iter = (RefEntity**)edge_handles;
03062   iBase_ErrorType result = iBase_SUCCESS;
03063   for (int i = 0; i < count; ++i) {
03064     RefEdge* edge = dynamic_cast<RefEdge*>(*ent_iter);
03065     if (!edge) {
03066       ERROR(iBase_INVALID_ENTITY_TYPE, "Non-edge input handle.");
03067     }
03068     else {
03069       const CubitVector coords( *coord_x, *coord_y, *coord_z );
03070       CubitVector on, tan, curv;
03071       CubitStatus s = edge->closest_point( coords, on, &tan, &curv );
03072       if (s == CUBIT_FAILURE)
03073         result = iBase_FAILURE;
03074       on.get_xyz( *on_x, *on_y, *on_z );
03075       tan.get_xyz( *tan_x, *tan_y, *tan_z );
03076       curv.get_xyz( *curv_x, *curv_y, *curv_z );
03077     }
03078     
03079     ent_iter += ent_step;
03080     coord_x += coord_step;
03081     coord_y += coord_step;
03082     coord_z += coord_step;
03083     on_x += on_step;
03084     on_y += on_step;
03085     on_z += on_step;
03086     tan_x += on_step;
03087     tan_y += on_step;
03088     tan_z += on_step;
03089     curv_x += on_step;
03090     curv_y += on_step;
03091     curv_z += on_step;
03092   }
03093   
03094   KEEP_ARRAY( on_coords );
03095   KEEP_ARRAY( tangents );
03096   KEEP_ARRAY( curvatures );
03097   RETURN(result);
03098 }
03099                        
03100 ITAPS_API void
03101 iGeom_getArrFcEvalXYZ( iGeom_Instance instance,
03102                        /*in*/ const iBase_EntityHandle *face_handles,
03103                        int face_handles_size,
03104                        /*in*/ int storage_order,
03105                        /*in*/ const double *coordinates,
03106                        int coordinates_size,
03107                        /*inout*/ double **on_coords,
03108                        int *on_coords_allocated,
03109                        int *on_coords_size,
03110                        /*inout*/ double **normals,
03111                        int *normals_allocated,
03112                        int *normals_size,
03113                        /*inout*/ double **curvatures_1,
03114                        int *curvatures_1_allocated,
03115                        int *curvatures_1_size,
03116                        /*inout*/ double **curvatures_2,
03117                        int *curvatures_2_allocated,
03118                        int *curvatures_2_size,
03119                        int* err )
03120 {
03121     /* set up iteration according to storage order.
03122        allow either gentity_handles or near_coordinates to contain
03123        only one value, where that single value is applied for every
03124        entry in the other list.
03125     */
03126   size_t coord_step, on_step = 1, ent_step;
03127   int count;
03128   if (3*face_handles_size == coordinates_size) {
03129     coord_step = ent_step = 1;
03130     count = face_handles_size;
03131   }
03132   else if (coordinates_size == 3) {
03133     coord_step = 0;
03134     ent_step = 1;
03135     count = face_handles_size;
03136   }
03137   else if (face_handles_size == 1) {
03138     coord_step = 1;
03139     ent_step = 0;
03140     count = coordinates_size / 3;
03141   }
03142   else {
03143     ERROR( iBase_INVALID_ENTITY_COUNT, "Mismatched array sizes" );
03144   }
03145 
03146     // check or pre-allocate the coordinate arrays
03147   ALLOC_CHECK_ARRAY( on_coords, 3*count );
03148   ALLOC_CHECK_ARRAY( normals, 3*count );
03149   ALLOC_CHECK_ARRAY( curvatures_1, 3*count );
03150   ALLOC_CHECK_ARRAY( curvatures_2, 3*count );
03151   
03152   const double *coord_x, *coord_y, *coord_z;
03153   double *on_x, *on_y, *on_z;
03154   double *norm_x, *norm_y, *norm_z;
03155   double *curv1_x, *curv1_y, *curv1_z;
03156   double *curv2_x, *curv2_y, *curv2_z;
03157   if (storage_order == iBase_BLOCKED) {
03158     coord_x = coordinates;
03159     coord_y = coord_x + coordinates_size/3;
03160     coord_z = coord_y + coordinates_size/3;
03161     on_x = *on_coords;
03162     on_y = on_x + count;
03163     on_z = on_y + count;
03164     norm_x = *normals;
03165     norm_y = norm_x + count;
03166     norm_z = norm_y + count;
03167     curv1_x = *curvatures_1;
03168     curv1_y = curv1_x + count;
03169     curv1_z = curv1_y + count;
03170     curv2_x = *curvatures_2;
03171     curv2_y = curv2_x + count;
03172     curv2_z = curv2_y + count;
03173     on_step = 1;
03174   }
03175   else {
03176     storage_order = iBase_INTERLEAVED; /* set if unspecified */
03177     coord_x = coordinates;
03178     coord_y = coord_x+1;
03179     coord_z = coord_x+2;
03180     on_x = *on_coords;
03181     on_y = on_x + 1;
03182     on_z = on_x + 2;
03183     norm_x = *normals;
03184     norm_y = norm_x+1;
03185     norm_z = norm_x+2;
03186     curv1_x = *curvatures_1;
03187     curv1_y = curv1_x + 1;
03188     curv1_z = curv1_x + 2;
03189     curv2_x = *curvatures_2;
03190     curv2_y = curv2_x + 1;
03191     curv2_z = curv2_x + 2;
03192     coord_step *= 3;
03193     on_step = 3;
03194   }
03195   
03196   RefEntity** ent_iter = (RefEntity**)face_handles;
03197   iBase_ErrorType result = iBase_SUCCESS;
03198   for (int i = 0; i < count; ++i) {
03199     RefFace* face = dynamic_cast<RefFace*>(*ent_iter);
03200     if (!face) {
03201       ERROR(iBase_INVALID_ENTITY_TYPE, "Non-face input handle.");
03202       result = iBase_INVALID_ENTITY_TYPE;
03203     }
03204     else {
03205       const CubitVector coords( *coord_x, *coord_y, *coord_z );
03206       CubitVector on, norm, curv1, curv2;
03207       Surface* surf = face->get_surface_ptr();
03208 #ifdef CGM_HAVE_FACET_ENGINE_ONLY
03209       CubitStatus s = surf->closest_point( coords, &on, &norm);
03210 #else
03211       CubitStatus s = surf->closest_point( coords, &on, &norm, &curv1, &curv2 );
03212 #endif
03213       if (s == CUBIT_FAILURE)
03214         result = iBase_FAILURE;
03215       on.get_xyz( *on_x, *on_y, *on_z );
03216       norm.get_xyz( *norm_x, *norm_y, *norm_z );
03217       curv1.get_xyz( *curv1_x, *curv1_y, *curv1_z );
03218       curv2.get_xyz( *curv2_x, *curv2_y, *curv2_z );
03219     }
03220     
03221     ent_iter += ent_step;
03222     coord_x += coord_step;
03223     coord_y += coord_step;
03224     coord_z += coord_step;
03225     on_x += on_step;
03226     on_y += on_step;
03227     on_z += on_step;
03228     norm_x += on_step;
03229     norm_y += on_step;
03230     norm_z += on_step;
03231     curv1_x += on_step;
03232     curv1_y += on_step;
03233     curv1_z += on_step;
03234     curv2_x += on_step;
03235     curv2_y += on_step;
03236     curv2_z += on_step;
03237   }
03238   
03239   KEEP_ARRAY( on_coords );
03240   KEEP_ARRAY( normals );
03241   KEEP_ARRAY( curvatures_1 );
03242   KEEP_ARRAY( curvatures_2 );
03243   RETURN(result);
03244 }
03245 
03253 ITAPS_API void
03254 iGeom_measure( iGeom_Instance instance,
03255                /*in*/ const iBase_EntityHandle *gentity_handles,
03256                int gentity_handles_size,
03257                /*out*/ double **measures,
03258                int *measures_allocated,
03259                int *measures_size,
03260                int* err )
03261 {
03262   RefEntity **handle_array = (RefEntity**)(gentity_handles);
03263 
03264     // check or pre-allocate the measure arrays
03265   ALLOC_CHECK_ARRAY_NOFAIL(measures, gentity_handles_size);
03266   for (int i = 0; i < gentity_handles_size; i++)
03267     (*measures)[i] = handle_array[i]->measure();
03268   
03269   RETURN(iBase_SUCCESS);
03270 }
03271 
03272 ITAPS_API void
03273 iGeom_getEntBoundBox( iGeom_Instance instance,
03274                       /*in*/ iBase_EntityHandle entity_handle,
03275                       /*out*/ double* min_x,
03276                       /*out*/ double* min_y,
03277                       /*out*/ double* min_z,
03278                       /*out*/ double* max_x,
03279                       /*out*/ double* max_y,
03280                       /*out*/ double* max_z,
03281                       int* err )
03282 {
03283   RefEntity* entity = (RefEntity*)entity_handle;
03284   CubitVector minc, maxc;
03285   CubitStatus status = iGeom_bounding_box( entity, minc, maxc );
03286   minc.get_xyz( *min_x, *min_y, *min_z );
03287   maxc.get_xyz( *max_x, *max_y, *max_z );
03288   RETURN( (status == CUBIT_SUCCESS ? iBase_SUCCESS : iBase_FAILURE) );
03289 }
03290 
03296 ITAPS_API void
03297 iGeom_getFaceType( iGeom_Instance instance,
03298                    /*in*/ iBase_EntityHandle gentity_handle,
03299                    /*out*/ char *face_type,
03300                    int* err,
03301                    int *face_type_length )
03302 {
03303   static const char *surf_types[] = {"cone", "plane", "sphere", "spline", 
03304                                      "torus", "best_fit", "facet", "undefined"};
03305   
03306   RefEntity *this_ent = ENTITY_HANDLE(gentity_handle);
03307   RefFace *this_face = dynamic_cast<RefFace*>(this_ent);
03308   if (!this_face)
03309     RETURN(iBase_INVALID_ENTITY_TYPE);
03310   GeometryType this_type = this_face->get_surface_ptr()->geometry_type();
03311   if (this_type < CONE_SURFACE_TYPE || this_type > UNDEFINED_SURFACE_TYPE) {
03312     RETURN(iBase_FAILURE);
03313   }
03314   
03315   const char* result = surf_types[this_type - CONE_SURFACE_TYPE];
03316   const int len = strlen(result);
03317   if (len < *face_type_length) {
03318     strcpy(face_type, result);
03319     *face_type_length = len;
03320   }
03321   else {
03322     strncpy(face_type, result, *face_type_length-1);
03323     face_type[*face_type_length] = '\0';
03324   }
03325 
03326   RETURN(iBase_SUCCESS);
03327 }
03328 
03336 ITAPS_API void
03337 iGeom_getArrBoundBox( iGeom_Instance instance,
03338                       /*in*/ const iBase_EntityHandle *gentity_handles,
03339                       int gentity_handles_size,
03340                       /*in*/ int storage_order,
03341                       /*out*/ double **min_corner,
03342                       int *min_corner_allocated,
03343                       int *min_corner_size,
03344                       /*out*/ double **max_corner,
03345                       int *max_corner_allocated,
03346                       int *max_corner_size,
03347                       int* err )
03348 {
03349     // check or pre-allocate the coordinate arrays
03350   ALLOC_CHECK_ARRAY(min_corner, 3*gentity_handles_size);
03351   ALLOC_CHECK_ARRAY(max_corner, 3*gentity_handles_size);
03352   
03353   size_t step, init;
03354   if (storage_order == iBase_BLOCKED) {
03355     step = 1;
03356     init = gentity_handles_size;
03357   }
03358   else {
03359     step = 3;
03360     init = 1;
03361   }
03362   double *min_x, *min_y, *min_z, *max_x, *max_y, *max_z;
03363   min_x = *min_corner;
03364   max_x = *max_corner;
03365   min_y = min_x + init;
03366   max_y = max_x + init;
03367   min_z = min_y + init;
03368   max_z = max_y + init;
03369   
03370   iBase_ErrorType result = iBase_SUCCESS;
03371   RefEntity** entities = (RefEntity**)gentity_handles;
03372   for (int i = 0; i < gentity_handles_size; ++i)
03373   {
03374     CubitVector min_c, max_c;
03375     CubitStatus s = iGeom_bounding_box( entities[i], min_c, max_c );
03376     if (s != CUBIT_SUCCESS)
03377       result = iBase_FAILURE;
03378     min_c.get_xyz( *min_x, *min_y, *min_z );
03379     max_c.get_xyz( *max_x, *max_y, *max_z );
03380     
03381     min_x += step;
03382     max_x += step;
03383     min_y += step;
03384     max_y += step;
03385     min_z += step;
03386     max_z += step;
03387   }
03388 
03389   KEEP_ARRAY(min_corner);
03390   KEEP_ARRAY(max_corner);
03391   RETURN(result);
03392 }
03393 
03394 ITAPS_API void
03395 iGeom_getVtxCoord( iGeom_Instance instance,
03396                    /*in*/ iBase_EntityHandle vertex_handle,
03397                    /*out*/ double* x,
03398                    /*out*/ double* y,
03399                    /*out*/ double* z,
03400                    int* err )
03401 {
03402   RefEntity* entity = (RefEntity*)vertex_handle;
03403   RefVertex* vertex = dynamic_cast<RefVertex*>(entity);
03404   if (!vertex) {
03405     ERROR(iBase_INVALID_ENTITY_TYPE, "Entity not a vertex");
03406   }
03407   vertex->coordinates().get_xyz(*x, *y, *z);
03408   RETURN(iBase_SUCCESS);
03409 }
03410 
03417 ITAPS_API void
03418 iGeom_getVtxArrCoords( iGeom_Instance instance,
03419                        /*in*/ const iBase_EntityHandle *gentity_handles,
03420                        int gentity_handles_size,
03421                        /*in*/ int storage_order,
03422                        /*out*/ double **coordinates,
03423                        int *coordinates_allocated,
03424                        int *coordinates_size,
03425                        int* err )
03426 {
03427   const RefEntity **handle_array = (const RefEntity**)(gentity_handles);
03428 
03429     // check or pre-allocate the coordinate arrays
03430   ALLOC_CHECK_ARRAY(coordinates, 3*gentity_handles_size);
03431   
03432   CubitVector dumvec;
03433   const RefVertex *this_vertex;
03434 
03435   double *x, *y, *z;
03436   size_t step;
03437   if (storage_order == iBase_BLOCKED) {
03438     x = *coordinates;
03439     y = x + gentity_handles_size;
03440     z = y + gentity_handles_size;
03441     step = 1;
03442   }
03443   else {
03444     x = *coordinates;
03445     y = x + 1;
03446     z = x + 2;
03447     step = 3;
03448   }
03449 
03450   for (int i = 0; i < gentity_handles_size; i++) {
03451     this_vertex = dynamic_cast<const RefVertex*>(handle_array[i]);
03452     if (NULL == this_vertex) {
03453       ERROR(iBase_INVALID_ENTITY_TYPE, "Entities passed into getGvertexCoordinates must be vertices.");
03454     }
03455     else {
03456       dumvec = this_vertex->coordinates();
03457       dumvec.get_xyz(*x,*y,*z);
03458       x += step;
03459       y += step;
03460       z += step;
03461     }
03462   }
03463 
03464   KEEP_ARRAY(coordinates);
03465   RETURN(iBase_SUCCESS);
03466 }
03467 
03468 ITAPS_API void
03469 iGeom_getPntRayIntsct( iGeom_Instance instance,
03470                        /*in*/ double x,
03471                        /*in*/ double y,
03472                        /*in*/ double z,
03473                        /*in*/ double dx,
03474                        /*in*/ double dy,
03475                        /*in*/ double dz,
03476                        /*inout*/ iBase_EntityHandle **intersect_entity_handles,
03477                        int *intersect_entity_handles_allocated,
03478                        int *intersect_entity_handles_size,
03479                        /*in*/ int storage_order,
03480                        /*inout*/ double **intersect_coords,
03481                        int *intersect_coords_allocated,
03482                        int *intersect_coords_size,
03483                        /*inout*/ double **param_coords,
03484                        int *param_coords_allocated,
03485                        int *param_coords_size,
03486                        int* err )
03487 {
03488   DLIList<double> ray_params;
03489   DLIList<RefEntity*> entities;
03490   CubitVector point(x,y,z), dir(dx,dy,dz);
03491   CubitStatus status = iGeom_fire_ray( point, dir, entities, ray_params );
03492   if (status != CUBIT_SUCCESS)
03493     RETURN(iBase_FAILURE);
03494   
03495   ALLOC_CHECK_ARRAY_NOFAIL( intersect_entity_handles, entities.size() );
03496   ALLOC_CHECK_ARRAY_NOFAIL( intersect_coords, 3*ray_params.size() );
03497   ALLOC_CHECK_ARRAY_NOFAIL( param_coords, ray_params.size() );
03498   
03499   size_t init, step;
03500   if (storage_order == iBase_BLOCKED) {
03501     init = ray_params.size();
03502     step = 1;
03503   }
03504   else {
03505     init = 1;
03506     step = 3;
03507   }
03508   
03509   double *x_iter = *intersect_coords;
03510   double *y_iter = x_iter + init;
03511   double *z_iter = y_iter + init;
03512   for (size_t i = ray_params.size(); i > 0; --i) {
03513     double t = ray_params.get_and_step();
03514     CubitVector pos = t * dir + point;
03515     pos.get_xyz( *x_iter, *y_iter, *z_iter );
03516     x_iter += step;
03517     y_iter += step;
03518     z_iter += step;
03519   }
03520   ray_params.copy_to( *param_coords );
03521   entities.copy_to( (RefEntity**)*intersect_entity_handles );
03522          
03523   RETURN(iBase_SUCCESS);  
03524 }
03525 
03526 ITAPS_API void
03527 iGeom_getPntArrRayIntsct( iGeom_Instance instance,
03528                           /*in*/ int storage_order,
03529                           /*in*/ const double *points,
03530                           int points_size,
03531                           /*in*/ const double *directions,
03532                           int directions_size,
03533                           /*inout*/ iBase_EntityHandle **intersect_entity_handles,
03534                           int *intersect_entity_handles_allocated,
03535                           int *intersect_entity_handles_size,
03536                           /*inout*/ int **offset,
03537                           int *offset_allocated,
03538                           int *offset_size,
03539                           /*inout*/ double **intersect_coords,
03540                           int *intersect_coords_allocated,
03541                           int *intersect_coords_size,
03542                           /*inout*/ double **param_coords,
03543                           int *param_coords_allocated,
03544                           int *param_coords_size,
03545                           int* err )
03546 {
03547   if (points_size != directions_size || points_size % 3) {
03548     ERROR(iBase_INVALID_ARGUMENT, "Mismatched or invalid input array size");
03549   }
03550   
03551   const int count = points_size / 3;
03552   ALLOC_CHECK_ARRAY( offset, count );
03553   
03554   const double *px, *py, *pz, *dx, *dy, *dz;
03555   size_t init, step;
03556   if (storage_order == iBase_BLOCKED) {
03557     init = count;
03558     step = 1;
03559   }
03560   else {
03561     storage_order = iBase_INTERLEAVED;
03562     init = 1;
03563     step = 3;
03564   }
03565   px = points;
03566   py = px + init;
03567   pz = py + init;
03568   dx = directions;
03569   dy = dx + init;
03570   dz = dy + init;
03571   
03572   DLIList<RefEntity*> entities, tmp_entities;
03573   DLIList<double> params, tmp_params;
03574   std::vector<CubitVector> coords;
03575   for (int i = 0; i < count; ++i)
03576   {
03577     tmp_entities.clean_out();
03578     tmp_params.clean_out();
03579     (*offset)[i] = params.size();
03580     const CubitVector point(*px, *py, *pz), dir(*dx, *dy, *dz);
03581     CubitStatus s = iGeom_fire_ray( point, dir, tmp_entities, tmp_params );
03582     if (CUBIT_SUCCESS != s) {
03583       RETURN(iBase_FAILURE);
03584     }
03585 
03586     entities += tmp_entities;
03587     params += tmp_params;
03588     tmp_params.reset();
03589     for (int j = tmp_params.size(); j > 0; --j) 
03590       coords.push_back( tmp_params.get_and_step() * dir + point );
03591     
03592     px += step;
03593     py += step;
03594     pz += step;
03595     dx += step;
03596     dy += step;
03597     dz += step;
03598   }
03599   
03600   ALLOC_CHECK_ARRAY_NOFAIL( intersect_entity_handles, entities.size() );
03601   ALLOC_CHECK_ARRAY_NOFAIL( intersect_coords, coords.size() );
03602   ALLOC_CHECK_ARRAY_NOFAIL( param_coords, params.size() );
03603   entities.copy_to( (RefEntity**)*intersect_entity_handles );
03604   params.copy_to( *param_coords );
03605   
03606   double *x = *intersect_coords;
03607   double *y = x + init;
03608   double *z = y + init;
03609   for (std::vector<CubitVector>::const_iterator k = coords.begin(); k != coords.end(); ++k)
03610   {
03611     k->get_xyz( *x, *y, *z );
03612     x += step;
03613     y += step;
03614     z += step;
03615   }
03616   
03617   KEEP_ARRAY(offset);
03618   RETURN(iBase_SUCCESS);
03619 }
03620 
03621 ITAPS_API void
03622 iGeom_getPntClsf( iGeom_Instance instance,
03623                   /*in*/ double x,
03624                   /*in*/ double y,
03625                   /*in*/ double z,
03626                   /*out*/ iBase_EntityHandle* entity_handle,
03627                   int* err )
03628 {
03629   RefEntity** ptr = (RefEntity**)entity_handle;
03630   const CubitVector pt(x,y,z);
03631   *ptr = iGeom_get_point_containment( pt );
03632   RETURN( *ptr ? iBase_SUCCESS : iBase_FAILURE );
03633 }
03634 
03635 ITAPS_API void
03636 iGeom_getPntArrClsf( iGeom_Instance instance,
03637                      /*in*/ int storage_order,
03638                      /*in*/ const double *coords,
03639                      int coords_size,
03640                      /*inout*/ iBase_EntityHandle **entity_handles,
03641                      int *entity_handles_allocated,
03642                      int *entity_handles_size,
03643                      int* err )
03644 {
03645   size_t init, step;
03646   int count = coords_size / 3;
03647   if (storage_order == iBase_BLOCKED) {
03648     init = count;
03649     step = 1;
03650   }
03651   else {
03652     storage_order = iBase_INTERLEAVED;
03653     init = 1;
03654     step = 3;
03655   }
03656   const double *x = coords;
03657   const double *y = x + init;
03658   const double *z = y + init;
03659   
03660   ALLOC_CHECK_ARRAY( entity_handles, count );
03661   
03662   RefEntity** array = (RefEntity**)*entity_handles;
03663   for (int i = 0; i < count; ++i)
03664   {
03665     const CubitVector pt( *x, *y, *z );
03666     array[i] = iGeom_get_point_containment( pt );
03667     if (!array[i]) {
03668       RETURN(iBase_FAILURE);
03669     }
03670     x += step;
03671     y += step;
03672     z += step;
03673   }
03674   
03675   KEEP_ARRAY(entity_handles);
03676   RETURN(iBase_SUCCESS);
03677 }
03678 
03686 ITAPS_API void
03687 iGeom_getEntNrmlSense( iGeom_Instance instance,
03688                        /*in*/ iBase_EntityHandle gface,
03689                        /*in*/ iBase_EntityHandle gregion,
03690                        int* rel_sense,
03691                        int* err )
03692 {
03693   const RefFace *face_ent = dynamic_cast<const RefFace*>(ENTITY_HANDLE(gface));
03694   if (NULL == face_ent) {
03695     ERROR(iBase_INVALID_ENTITY_TYPE, "1st argument to getEntNrmlSense must be a face.");
03696   }
03697 
03698   // XXX: workaround; remove this when we switch iBase_REGIONs to RefVolume
03699   const RefVolume *volume_ent;
03700   Body *body_ent = dynamic_cast<Body*>(ENTITY_HANDLE(gregion));
03701   if (NULL != body_ent) {
03702     DLIList<RefEntity*> children;
03703     body_ent->get_child_ref_entities(children);
03704     if (children.size() != 1) {
03705       ERROR(iBase_FAILURE, "Can only support bodies with one volume");
03706     }
03707     volume_ent = dynamic_cast<const RefVolume*>(children[0]);
03708   }
03709   else {
03710     volume_ent = dynamic_cast<const RefVolume*>(ENTITY_HANDLE(gregion));
03711   }
03712 
03713   if (NULL == volume_ent) {
03714     ERROR(iBase_INVALID_ENTITY_TYPE, "2nd argument to getEntNrmlSense must be a region.");
03715   }
03716 
03717   *rel_sense = iGeom_get_nonmanifold_sense( face_ent, volume_ent, err );
03718 }
03719 
03720 ITAPS_API void
03721 iGeom_getArrNrmlSense( iGeom_Instance instance,
03722                        /*in*/ iBase_EntityHandle const *faces,
03723                        int faces_size,
03724                        /*in*/ iBase_EntityHandle const *regions,
03725                        int regions_size,
03726                        /*inout*/ int **senses,
03727                        int *senses_allocated,
03728                        int *senses_size,
03729                        int* err )
03730 {
03731   size_t faces_step, regions_step;
03732   int count;
03733   if (faces_size == regions_size) {
03734     faces_step = regions_step = 1;
03735     count = faces_size;
03736   }
03737   else if (faces_size == 1) {
03738     faces_step = 0;
03739     regions_step = 1;
03740     count = regions_size;
03741   }
03742   else if (regions_size == 1) {
03743     faces_step = 1;
03744     regions_step = 0;
03745     count = faces_size;
03746   }
03747   else {
03748     ERROR( iBase_INVALID_ENTITY_COUNT, "Mismatched input array sizes" );
03749     RETURN (iBase_INVALID_ENTITY_COUNT);
03750   }
03751   
03752   RefEntity** face_iter = (RefEntity**)faces;
03753   RefEntity** region_iter = (RefEntity**)regions;
03754   ALLOC_CHECK_ARRAY( senses, count );
03755   for (int i = 0; i < count; ++i) {
03756     RefFace *face_ent = dynamic_cast<RefFace*>(*face_iter);
03757     if (NULL == face_ent) {
03758       ERROR(iBase_INVALID_ENTITY_TYPE, "1st argument to getArrNrmlSense must be a face.");
03759     }
03760 
03761     // XXX: workaround; remove this when we switch iBase_REGIONs to RefVolume
03762     const RefVolume *volume_ent;
03763     Body *body_ent = dynamic_cast<Body*>(*region_iter);
03764     if (NULL != body_ent) {
03765       DLIList<RefEntity*> children;
03766       body_ent->get_child_ref_entities(children);
03767       if (children.size() != 1) {
03768         ERROR(iBase_FAILURE, "Can only support bodies with one volume");
03769       }
03770       volume_ent = dynamic_cast<const RefVolume*>(children[0]);
03771     }
03772     else {
03773       volume_ent = dynamic_cast<const RefVolume*>(*region_iter);
03774     }
03775 
03776     if (NULL == volume_ent) {
03777       ERROR(iBase_INVALID_ENTITY_TYPE, "2nd argument to getArrNrmlSense must be a region.");
03778     }
03779 
03780     (*senses)[i] = iGeom_get_nonmanifold_sense( face_ent, volume_ent, err );
03781     if (iBase_SUCCESS != *err)
03782       return;
03783 
03784     face_iter += faces_step;
03785     region_iter += regions_step;
03786   }
03787   
03788   KEEP_ARRAY(senses);
03789   RETURN(iBase_SUCCESS);
03790 }
03791 
03792 
03793 
03801 ITAPS_API void
03802 iGeom_getEgFcSense( iGeom_Instance instance,
03803                     /*in*/ iBase_EntityHandle gedge,
03804                     /*in*/ iBase_EntityHandle gface,
03805                     int* rel_sense,
03806                     int* err )
03807 {
03808   const RefEdge *edge_ent = dynamic_cast<const RefEdge*>(ENTITY_HANDLE(gedge));
03809   if (NULL == edge_ent) {
03810     ERROR(iBase_INVALID_ENTITY_TYPE, "1st argument to getGtangentSense must be an edge.");
03811   }
03812   const RefFace *face_ent = dynamic_cast<const RefFace*>(ENTITY_HANDLE(gface));
03813   if (NULL == face_ent) {
03814     ERROR(iBase_INVALID_ENTITY_TYPE, "2nd argument to getGtangentSense must be a face.");
03815   }
03816   *rel_sense = iGeom_get_nonmanifold_sense( edge_ent, face_ent, err );
03817   RETURN(iBase_SUCCESS);
03818 }
03819 
03820 ITAPS_API void
03821 iGeom_getEgFcArrSense( iGeom_Instance instance,
03822                        /*in*/ iBase_EntityHandle const *edges,
03823                        int edges_size,
03824                        /*in*/ iBase_EntityHandle const *faces,
03825                        int faces_size,
03826                        /*inout*/ int **senses,
03827                        int *senses_allocated,
03828                        int *senses_size,
03829                        int* err )
03830 {
03831   size_t faces_step, edges_step;
03832   int count;
03833   if (faces_size == edges_size) {
03834     faces_step = edges_step = 1;
03835     count = faces_size;
03836   }
03837   else if (faces_size == 1) {
03838     faces_step = 0;
03839     edges_step = 1;
03840     count = edges_size;
03841   }
03842   else if (edges_size == 1) {
03843     faces_step = 1;
03844     edges_step = 0;
03845     count = faces_size;
03846   }
03847   else {
03848     ERROR( iBase_INVALID_ENTITY_COUNT, "Mismatched input array sizes" );
03849   }
03850   
03851   RefEntity** face_iter = (RefEntity**)faces;
03852   RefEntity** edge_iter = (RefEntity**)edges;
03853   ALLOC_CHECK_ARRAY( senses, count );
03854   for (int i = 0; i < count; ++i) {
03855     RefEdge *edge_ent = dynamic_cast<RefEdge*>(*edge_iter);
03856     if (NULL == edge_ent) {
03857       ERROR(iBase_INVALID_ENTITY_TYPE, "1st argument to getGnormalSense must be a face.");
03858     }
03859     RefFace *face_ent = dynamic_cast<RefFace*>(*face_iter);
03860     if (NULL == face_ent) {
03861       ERROR(iBase_INVALID_ENTITY_TYPE, "2nd argument to getGnormalSense must be a region.");
03862     }
03863     (*senses)[i] = iGeom_get_nonmanifold_sense( edge_ent, face_ent, err );
03864     if (iBase_SUCCESS != *err)
03865       return;
03866 
03867     face_iter += faces_step;
03868     edge_iter += edges_step;
03869   }
03870   
03871   KEEP_ARRAY(senses);
03872   RETURN(iBase_SUCCESS);
03873 }
03874 
03885 ITAPS_API void
03886 iGeom_getEgVtxSense( iGeom_Instance instance,
03887                      /*in*/ iBase_EntityHandle gedge,
03888                      /*in*/ iBase_EntityHandle gvertex1,
03889                      /*in*/ iBase_EntityHandle gvertex2,
03890                      int* rel_sense,
03891                      int* err )
03892 {
03893   const RefEdge *this_edge = dynamic_cast<const RefEdge*>(ENTITY_HANDLE(gedge));
03894   const RefVertex *vertex1 = dynamic_cast<const RefVertex*>(ENTITY_HANDLE(gvertex1));
03895   const RefVertex *vertex2 = dynamic_cast<const RefVertex*>(ENTITY_HANDLE(gvertex2));
03896   if (NULL == this_edge || NULL == vertex1 || NULL == vertex2) {
03897     ERROR(iBase_INVALID_ENTITY_TYPE, "Bad entity argument to getGvertexTangentSense.");
03898   }
03899   *rel_sense = iGeom_edge_vertex_sense( this_edge, vertex1, vertex2, err );
03900   RETURN(iBase_SUCCESS);
03901 }
03902 
03903 ITAPS_API void
03904 iGeom_getEgVtxArrSense( iGeom_Instance instance,
03905                         /*in*/ iBase_EntityHandle const *edges ,
03906                         int edges_size,
03907                         /*in*/ iBase_EntityHandle const *start_vertices ,
03908                         int start_vertices_size,
03909                         /*in*/ iBase_EntityHandle const *end_vertices ,
03910                         int end_vertices_size,
03911                         /*inout*/  int **senses ,
03912                         int *senses_allocated,
03913                         int *senses_size,
03914                         int* err )
03915 {
03916   int count;
03917   size_t edge_step, start_step, end_step;
03918   edge_step = edges_size > 1;
03919   start_step = start_vertices_size > 1;
03920   end_step = end_vertices_size > 1;
03921   count = edges_size;
03922   if (count != 1) {
03923     if (start_vertices_size != 1 && start_vertices_size != count) {
03924       ERROR( iBase_INVALID_ENTITY_COUNT, "Mismatched input array sizes" );
03925     }
03926   }
03927   else
03928     count = start_vertices_size;
03929   if (count != 1) {
03930     if (end_vertices_size != 1 && end_vertices_size != count) {
03931       ERROR( iBase_INVALID_ENTITY_COUNT, "Mismatched input array sizes" );
03932     }
03933   }
03934   else
03935     count = end_vertices_size;
03936     
03937   ALLOC_CHECK_ARRAY( senses, count );
03938   
03939   RefEntity** edge_iter = (RefEntity**)edges;
03940   RefEntity** start_iter = (RefEntity**)start_vertices;
03941   RefEntity** end_iter = (RefEntity**)end_vertices;
03942   for (int i = 0; i < count; ++i) {
03943     RefEdge* edge = dynamic_cast<RefEdge*>(*edge_iter);
03944     RefVertex* vtx1 = dynamic_cast<RefVertex*>(*start_iter);
03945     RefVertex* vtx2 = dynamic_cast<RefVertex*>(*end_iter);
03946     if (!edge || !vtx1 || !vtx2) {
03947       ERROR(iBase_INVALID_ENTITY_TYPE, "Bad entity argument to getGvertexTangentSense.");
03948     }
03949     
03950     (*senses)[i] = iGeom_edge_vertex_sense( edge, vtx1, vtx2, err );
03951     if (iBase_SUCCESS != *err)
03952       return;
03953     edge_iter += edge_step;
03954     start_iter += start_step;
03955     end_iter += end_step;
03956   }
03957   
03958   KEEP_ARRAY(senses);
03959   RETURN(iBase_SUCCESS);
03960 }
03961   
03962   
03963     
03964       
03965 
03972 ITAPS_API void
03973 iGeom_getNumEntSets( iGeom_Instance instance,
03974                      /*in*/ iBase_EntitySetHandle entity_set,
03975                      /*in*/ int num_hops,
03976                      int* num_ent_sets,
03977                      int* err )
03978 {
03979     // HJK: num_hops has to be handled
03980   if (0 < num_hops) {
03981     ERROR(iBase_NOT_SUPPORTED, "Num_hops argument not yet supported.");
03982   }
03983   
03984   const RefGroup *this_set = SET_HANDLE(entity_set);
03985   if (NULL == this_set)
03986     *num_ent_sets = RefEntityFactory::instance()->num_ref_groups();
03987   else {
03988     DLIList<RefEntity*> tmp_ents;
03989     DLIList<RefGroup*> groups;
03990     const_cast<RefGroup*>(this_set)->get_child_ref_entities(tmp_ents);
03991     CAST_LIST(tmp_ents, groups, RefGroup);
03992     *num_ent_sets = groups.size();
03993   }
03994 
03995   RETURN(iBase_SUCCESS);
03996 }
03997 
04005 ITAPS_API void
04006 iGeom_getEntSets( iGeom_Instance instance,
04007                   /*in*/ iBase_EntitySetHandle entity_set,
04008                   /*in*/ int num_hops,
04009                   /*inout*/ iBase_EntitySetHandle **contained_entity_set_handles,
04010                   int *contained_entity_set_handles_allocated,
04011                   int *contained_entity_set_handles_size,
04012                   int *err )
04013 {
04014   if (0 < num_hops) {
04015     ERROR(iBase_NOT_SUPPORTED, "Num_hops argument not yet supported.");
04016   }
04017 
04018   const RefGroup *this_set = SET_HANDLE(entity_set);
04019   DLIList<RefEntity*> tmp_ents;
04020   DLIList<RefGroup*> groups;
04021   if (NULL == this_set)
04022     RefEntityFactory::instance()->ref_groups(groups);
04023   else {
04024     const_cast<RefGroup*>(this_set)->get_child_ref_entities(tmp_ents);
04025     CAST_LIST(tmp_ents, groups, RefGroup);
04026   }
04027   
04028   ALLOC_CHECK_ARRAY_NOFAIL(contained_entity_set_handles, groups.size());
04029 
04030   groups.copy_to(*SET_HANDLE_ARRAY_PTR(contained_entity_set_handles));
04031   
04032   RETURN(iBase_SUCCESS);
04033 }
04034 
04048 ITAPS_API void
04049 iGeom_createEntSet( iGeom_Instance instance,
04050                     /*in*/ int isList,
04051                     /*out*/ iBase_EntitySetHandle *entity_set,
04052                     int* err )
04053 {
04054   RefGroup* grp = RefEntityFactory::instance()->construct_RefGroup();
04055   *entity_set = reinterpret_cast<iBase_EntitySetHandle>(grp);
04056     // need to set a tag denoting multiset or not...
04057   if (*entity_set == NULL) {
04058     RETURN(iBase_FAILURE);
04059   }
04060   
04061   else {
04062     RETURN(iBase_SUCCESS);
04063   }
04064 }
04065 
04071 ITAPS_API void
04072 iGeom_destroyEntSet( iGeom_Instance instance,
04073                      /*in*/ iBase_EntitySetHandle entity_set,
04074                      int* err )
04075 {
04076   if (NULL == entity_set) {
04077     ERROR(iBase_INVALID_ARGUMENT, "Can't destroy interface set.");
04078   }
04079       
04080   CubitStatus result = RefGroup::delete_group(SET_HANDLE(entity_set));
04081   if (CUBIT_SUCCESS == result) {
04082     RETURN(iBase_SUCCESS);
04083   }
04084   
04085   else {
04086     RETURN(iBase_FAILURE);
04087   }
04088   
04089 }
04090 
04091 ITAPS_API void
04092 iGeom_isList( iGeom_Instance instance,
04093               /*in*/ iBase_EntitySetHandle entity_set,
04094               int* result,
04095               int* err )
04096 {
04097   *result = true;
04098   RETURN (iBase_SUCCESS);
04099 }
04100 
04110 ITAPS_API void
04111 iGeom_addEntSet( iGeom_Instance instance,
04112                  /*in*/ iBase_EntitySetHandle entity_set_to_add,
04113                  /*inout*/ iBase_EntitySetHandle entity_set_handle,
04114                  int* err )
04115 {
04116   iGeom_addEntToSet(instance, reinterpret_cast<iBase_EntityHandle>(entity_set_to_add), entity_set_handle, err);
04117 }
04118 
04127 ITAPS_API void
04128 iGeom_rmvEntSet( iGeom_Instance instance,
04129                  /*in*/ iBase_EntitySetHandle entity_set_to_remove,
04130                  /*inout*/ iBase_EntitySetHandle entity_set_handle,
04131                  int* err )
04132 {
04133   iGeom_rmvEntFromSet(instance, reinterpret_cast<iBase_EntityHandle>(entity_set_to_remove), entity_set_handle, err);
04134 }
04135 
04145 ITAPS_API void
04146 iGeom_addEntToSet( iGeom_Instance instance,
04147                    /*in*/ iBase_EntityHandle entity_to_add,
04148                    /*inout*/ iBase_EntitySetHandle entity_set_handle,
04149                    int* err )
04150 {
04151   if (NULL == entity_to_add) RETURN(iBase_INVALID_ARGUMENT);
04152   
04153   CubitStatus status = SET_HANDLE(entity_set_handle)->
04154     add_ref_entity(const_cast<RefEntity*>(ENTITY_HANDLE(entity_to_add)));
04155   
04156   if (CUBIT_SUCCESS != status) {
04157     ERROR(iBase_FAILURE, "Problem adding entity to another set.");
04158   }
04159 
04160   RETURN(iBase_SUCCESS);
04161 }
04162 
04171 ITAPS_API void
04172 iGeom_rmvEntFromSet( iGeom_Instance instance,
04173                      /*in*/ iBase_EntityHandle entity_to_remove,
04174                      /*inout*/ iBase_EntitySetHandle entity_set_handle,
04175                      int* err )
04176 {
04177   if (NULL == entity_set_handle) RETURN(iBase_INVALID_ARGUMENT);
04178   
04179   CubitStatus status = SET_HANDLE(entity_set_handle)->
04180     remove_ref_entity(const_cast<RefEntity*>(ENTITY_HANDLE(entity_to_remove)));
04181   if (CUBIT_SUCCESS != status) {
04182     ERROR(iBase_FAILURE, "Problem removing entity from a set.");
04183   }
04184   
04185   RETURN(iBase_SUCCESS);
04186 }
04187 
04188 ITAPS_API void
04189 iGeom_isEntContained( iGeom_Instance instance,
04190                       /*in*/ iBase_EntitySetHandle containing_entity_set,
04191                       /*in*/ iBase_EntityHandle contained_entity,
04192                       int* is_contained,
04193                       int* err )
04194 {
04195     // everything is contained in root set
04196   if (NULL == containing_entity_set && NULL != contained_entity) {
04197     *is_contained = true;
04198     RETURN( iBase_SUCCESS );
04199   }
04200 
04201   DLIList<RefGroup*> containing_groups;
04202   RefEntity *contained_entity_temp = const_cast<RefEntity*>(ENTITY_HANDLE(contained_entity));
04203   RefGroup::get_groups_within(contained_entity_temp, containing_groups, CUBIT_FALSE);
04204   *is_contained = containing_groups.size() > 0 &&
04205       containing_groups.move_to(const_cast<RefGroup*>(SET_HANDLE(containing_entity_set))) ;
04206 
04207   RETURN(iBase_SUCCESS);
04208 }
04209 
04210 ITAPS_API void
04211 iGeom_isEntArrContained( iGeom_Instance instance,
04212                          /*in*/ iBase_EntitySetHandle containing_set,
04213                          /*in*/ const iBase_EntityHandle* entity_handles,
04214                          /*in*/ int num_entity_handles,
04215                          /*inout*/ int** is_contained,
04216                          /*inout*/ int* is_contained_allocated,
04217                          /*out*/ int* is_contained_size,
04218                          /*out*/ int* err )
04219 {
04220     // go through each entity and look up its dimension
04221   ALLOC_CHECK_ARRAY(is_contained, num_entity_handles);
04222 
04223   for (int i = 0; i < num_entity_handles; ++i) {
04224     iGeom_isEntContained( instance, containing_set, entity_handles[i], (*is_contained)+i, err );
04225     if (iBase_SUCCESS != *err)
04226       return;
04227   }
04228 
04229   KEEP_ARRAY(is_contained);
04230   RETURN(iBase_SUCCESS);
04231 }
04232 
04233 ITAPS_API void
04234 iGeom_isEntSetContained( iGeom_Instance instance,
04235                          /*in*/ iBase_EntitySetHandle containing_entity_set,
04236                          /*in*/ iBase_EntitySetHandle contained_entity_set,
04237                          int* is_contained,
04238                          int* err )
04239 {
04240   iGeom_isEntContained( instance, containing_entity_set, 
04241                         reinterpret_cast<iBase_EntityHandle>(contained_entity_set),
04242                         is_contained, err);
04243 }
04244 
04253 ITAPS_API void
04254 iGeom_addEntArrToSet( iGeom_Instance instance,
04255                       /*in*/ iBase_EntityHandle const* entity_handles,
04256                       int entity_handles_size,
04257                       /*inout*/ iBase_EntitySetHandle entity_set,
04258                       int* err )
04259 {
04260   if (NULL == entity_set) RETURN(iBase_INVALID_ARGUMENT);
04261 
04262   RefGroup *this_set = SET_HANDLE(entity_set);
04263   RefEntity **ent_array = (RefEntity**)(entity_handles);
04264   CubitStatus status = CUBIT_SUCCESS, tmp_status;
04265   for (int i = 0; i < entity_handles_size; i++) {
04266     tmp_status = this_set->add_ref_entity(ent_array[i]);
04267     if (CUBIT_SUCCESS != tmp_status) status = tmp_status;
04268   }
04269 
04270   if (CUBIT_SUCCESS != status) {
04271     ERROR(iBase_FAILURE, "Problem adding entities to a set.");
04272   }
04273   
04274   RETURN(iBase_SUCCESS);
04275 }
04276 
04282 ITAPS_API void
04283 iGeom_rmvEntArrFromSet( iGeom_Instance instance,
04284                         /*in*/ iBase_EntityHandle const* entity_handles,
04285                         int entity_handles_size,
04286                         /*inout*/ iBase_EntitySetHandle entity_set,
04287                         int* err )
04288 {
04289   if (NULL == entity_set) RETURN(iBase_INVALID_ARGUMENT);
04290 
04291   RefGroup *this_set = SET_HANDLE(entity_set);
04292   RefEntity **ent_array = (RefEntity**)(entity_handles);
04293   CubitStatus status = CUBIT_SUCCESS, tmp_status;
04294   for (int i = 0; i < entity_handles_size; i++) {
04295     tmp_status = this_set->remove_ref_entity(ent_array[i]);
04296     if (CUBIT_SUCCESS != tmp_status) status = tmp_status;
04297   }
04298 
04299   if (CUBIT_SUCCESS != status) {
04300     ERROR(iBase_FAILURE, "Problem removing entities from a set.");
04301   }
04302   
04303   RETURN(iBase_SUCCESS);
04304 }
04305 
04313 ITAPS_API void
04314 iGeom_getTolerance( iGeom_Instance instance,
04315                     /*out*/ int* type,
04316                     /*out*/ double* tolerance,
04317                     int* err )
04318 {
04319   *type = 1;
04320   *tolerance = gqt->get_sme_resabs_tolerance();
04321   RETURN(iBase_SUCCESS);
04322 }
04323 
04324 ITAPS_API void
04325 iGeom_getEntTolerance( iGeom_Instance instance,
04326                        /*in*/ iBase_EntityHandle entity_handle,
04327                        double* tolerance,
04328                        int* err )
04329 {
04330   *tolerance = gqt->get_sme_resabs_tolerance();
04331   RETURN(iBase_SUCCESS);
04332 }
04333 
04342 ITAPS_API void
04343 iGeom_getArrTolerance( iGeom_Instance instance,
04344                        /*in*/ iBase_EntityHandle const *gentity_handles,
04345                        const int gentity_handles_size,
04346                        /*out*/ double **tolerances,
04347                        int *tolerances_allocated,
04348                        int *tolerances_size,
04349                        int* err )
04350 {
04351   ALLOC_CHECK_ARRAY_NOFAIL(tolerances, gentity_handles_size);
04352   double dum_abs_tol = gqt->get_sme_resabs_tolerance();
04353   for (int i = 0; i < gentity_handles_size; i++) {
04354     (*tolerances)[i] = dum_abs_tol;
04355   }
04356   RETURN(iBase_SUCCESS);
04357 }
04358 
04359 ITAPS_API void
04360 iGeom_getParametric( iGeom_Instance instance,
04361                      int* is_parametric,
04362                      int* err )
04363 {
04364   *is_parametric = true;
04365   RETURN(iBase_SUCCESS);
04366 }
04367 
04374 ITAPS_API void
04375 iGeom_isEntParametric( iGeom_Instance instance,
04376                        /*in*/ iBase_EntityHandle gentity_handle,
04377                        int* is_parametric,
04378                        int* err )
04379 {
04380   *is_parametric = iGeom_is_parametric( (RefEntity*)gentity_handle );
04381   RETURN (iBase_SUCCESS);
04382 }
04383 
04384 ITAPS_API void
04385 iGeom_isArrParametric( iGeom_Instance instance,
04386                        iBase_EntityHandle const *entity_handles,
04387                        int entity_handles_size,
04388                        int **is_parametric,
04389                        int *is_parametric_allocated,
04390                        int *is_parametric_size,
04391                        int* err )
04392 {
04393   ALLOC_CHECK_ARRAY_NOFAIL( is_parametric, entity_handles_size );
04394   RefEntity** const ent_array = (RefEntity**)entity_handles;
04395   for (int i = 0; i < entity_handles_size; ++i)
04396     (*is_parametric)[i] = iGeom_is_parametric( ent_array[i] );
04397   RETURN(iBase_SUCCESS);
04398 }
04399 
04400 ITAPS_API void
04401 iGeom_getEntUVtoXYZ( iGeom_Instance instance,
04402                      /*in*/ iBase_EntityHandle entity_handle,
04403                      /*in*/ double u,
04404                      /*in*/ double v,
04405                      /*out*/ double* x,
04406                      /*out*/ double* y,
04407                      /*out*/ double* z,
04408                      int* err )
04409 {
04410   RefEntity* entity = (RefEntity*)entity_handle;
04411   RefFace* face = dynamic_cast<RefFace*>(entity);
04412   if (!face) {
04413     ERROR(iBase_INVALID_ENTITY_TYPE, "Expected face for UV method.");
04414   }
04415   
04416   CubitVector xyz = face->position_from_u_v( u, v );
04417   xyz.get_xyz( *x, *y, *z );
04418   RETURN(iBase_SUCCESS);
04419 }
04420 
04429 ITAPS_API void
04430 iGeom_getArrUVtoXYZ( iGeom_Instance instance,
04431                      /*in*/ iBase_EntityHandle const *gentity_handles,
04432                      int gentity_handles_size,
04433                      /*in*/ int storage_order,
04434                      /*in*/ const double *uv,
04435                      int uv_size,
04436                      /*out*/ double **coordinates,
04437                      int *coordinates_allocated,
04438                      int *coordinates_size,
04439                      int* err )
04440 {
04441   size_t ent_step, coord_step, uv_step;
04442   int count;
04443   if (2*gentity_handles_size == uv_size) {
04444     ent_step = uv_step = 1;
04445     count = gentity_handles_size;
04446   }
04447   else if (uv_size == 2) {
04448     ent_step = 1;
04449     uv_step = 0;
04450     count = gentity_handles_size;
04451   }
04452   else if (gentity_handles_size == 1) {
04453     ent_step = 0;
04454     uv_step = 1;
04455     count = uv_size/2;
04456   }
04457   else {
04458     ERROR(iBase_INVALID_ENTITY_COUNT, "Mismatched input array sizes.");
04459   }
04460 
04461   ALLOC_CHECK_ARRAY( coordinates, 3*count );
04462     
04463   const double *u, *v;
04464   double *x, *y, *z;
04465   u = uv;
04466   x = *coordinates;
04467   if (storage_order == iBase_BLOCKED) {
04468     v = u + (uv_step ? count : 1);
04469     y = x + count;
04470     z = y + count;
04471     coord_step = 1;
04472   } 
04473   else {
04474     storage_order = iBase_INTERLEAVED;
04475     v = u + 1;
04476     y = x + 1;
04477     z = x + 2;
04478     coord_step = 3;
04479     uv_step *= 2;
04480   }
04481   
04482   RefEntity** ent = (RefEntity**)gentity_handles;
04483   for (int i = 0; i < count; ++i) {
04484     RefFace* face = dynamic_cast<RefFace*>(*ent);
04485     if (!face) {
04486       ERROR(iBase_INVALID_ENTITY_TYPE, "Expected face for UV method.");
04487     }
04488     
04489     CubitVector xyz = face->position_from_u_v( *u, *v );
04490     xyz.get_xyz( *x, *y, *z );
04491     
04492     ent += ent_step;
04493     u += uv_step;
04494     v += uv_step;
04495     x += coord_step;
04496     y += coord_step;
04497     z += coord_step;
04498   }
04499   
04500   KEEP_ARRAY(coordinates);
04501   RETURN(iBase_SUCCESS);
04502 }
04503 
04504 ITAPS_API void
04505 iGeom_getEntUtoXYZ( iGeom_Instance instance,
04506                     /*in*/ iBase_EntityHandle entity_handle,
04507                     /*in*/ double u,
04508                     /*out*/ double* x,
04509                     /*out*/ double* y,
04510                     /*out*/ double* z,
04511                     int* err )
04512 {
04513   RefEntity* entity = (RefEntity*)entity_handle;
04514   RefEdge* edge = dynamic_cast<RefEdge*>(entity);
04515   if (!edge) {
04516     ERROR(iBase_INVALID_ENTITY_TYPE, "Expected edge for 1-param method.");
04517   }
04518   
04519   CubitVector xyz;
04520   CubitStatus s = edge->position_from_u( u, xyz );
04521   xyz.get_xyz( *x, *y, *z );
04522   RETURN( (s == CUBIT_SUCCESS ? iBase_SUCCESS : iBase_FAILURE) );
04523 }
04524 
04525 ITAPS_API void
04526 iGeom_getArrUtoXYZ( iGeom_Instance instance,
04527                     /*in*/ iBase_EntityHandle const *gentity_handles,
04528                     int gentity_handles_size,
04529                     /*in*/ const double *u,
04530                     int u_size,
04531                     /*in*/ int storage_order,
04532                     /*out*/ double **coordinates,
04533                     int *coordinates_allocated,
04534                     int *coordinates_size,
04535                     int* err )
04536 {
04537   int count;
04538   size_t ent_step, coord_step, u_step;
04539   if (gentity_handles_size == u_size) {
04540     ent_step = u_step = 1;
04541     count = gentity_handles_size;
04542   }
04543   else if (u_size == 1) {
04544     ent_step = 1;
04545     u_step = 0;
04546     count = gentity_handles_size;
04547   }
04548   else if (gentity_handles_size == 1) {
04549     ent_step = 0;
04550     u_step = 1;
04551     count = u_size;
04552   }
04553   else {
04554     ERROR(iBase_INVALID_ENTITY_COUNT, "Mismatched input array sizes.");
04555   }
04556     
04557   ALLOC_CHECK_ARRAY( coordinates, 3*count );
04558   
04559   const double *u_iter;
04560   double *x, *y, *z;
04561   u_iter = u;
04562   x = *coordinates;
04563   if (storage_order == iBase_BLOCKED) {
04564     y = x + count;
04565     z = y + count;
04566     coord_step = 1;
04567   } 
04568   else {
04569     y = x + 1;
04570     z = x + 2;
04571     coord_step = 3;
04572   }
04573   
04574   iBase_ErrorType result = iBase_SUCCESS;
04575   RefEntity** ent = (RefEntity**)gentity_handles;
04576   for (int i = 0; i < count; ++i) {
04577     RefEdge* edge = dynamic_cast<RefEdge*>(*ent);
04578     if (!edge) {
04579       ERROR(iBase_INVALID_ENTITY_TYPE, "Expected edge for 1-param method.");
04580     }
04581     
04582     CubitVector xyz;
04583     CubitStatus s = edge->position_from_u( *u_iter, xyz );
04584     if (CUBIT_SUCCESS != s)
04585       result = iBase_FAILURE;
04586     xyz.get_xyz( *x, *y, *z );
04587     
04588     ent += ent_step;
04589     u_iter += u_step;
04590     x += coord_step;
04591     y += coord_step;
04592     z += coord_step;
04593   }
04594   
04595   KEEP_ARRAY(coordinates);
04596   RETURN(result);
04597 }
04598 
04599 ITAPS_API void
04600 iGeom_getEntXYZtoUV( iGeom_Instance instance,
04601                      /*in*/ iBase_EntityHandle entity_handle,
04602                      /*in*/ double x,
04603                      /*in*/ double y,
04604                      /*in*/ double z,
04605                      /*out*/ double* u,
04606                      /*out*/ double* v,
04607                      int* err )
04608 {
04609   RefEntity* entity = (RefEntity*)entity_handle;
04610   RefFace* face = dynamic_cast<RefFace*>(entity);
04611   if (!face) {
04612     ERROR(iBase_INVALID_ENTITY_TYPE, "Expected face for UV method.");
04613   }
04614   
04615   const CubitVector xyz( x, y, z );
04616   CubitStatus s = face->u_v_from_position( xyz, *u, *v );
04617   RETURN( (s == CUBIT_SUCCESS ? iBase_SUCCESS : iBase_FAILURE) );
04618 }
04619 
04620 
04629 ITAPS_API void
04630 iGeom_getArrXYZtoUV( iGeom_Instance instance,
04631                      /*in*/ iBase_EntityHandle const *gentity_handles,
04632                      int gentity_handles_size,
04633                      /*in*/ int storage_order,
04634                      /*in*/ const double *coordinates,
04635                      int coordinates_size,
04636                      /*out*/ double **uv,
04637                      int *uv_allocated,
04638                      int *uv_size,
04639                      int* err )
04640 {
04641   int count;
04642   size_t ent_step, coord_step, uv_step;
04643   if (3*gentity_handles_size == coordinates_size) {
04644     ent_step = coord_step = 1;
04645     count = gentity_handles_size;
04646   }
04647   else if (coordinates_size == 3) {
04648     ent_step = 1;
04649     coord_step = 0;
04650     count = gentity_handles_size;
04651   }
04652   else if (gentity_handles_size == 1) {
04653     ent_step = 0;
04654     coord_step = 1;
04655     count = coordinates_size/3;
04656   }
04657   else {
04658     ERROR(iBase_INVALID_ENTITY_COUNT, "Mismatched input array sizes.");
04659   }
04660 
04661   ALLOC_CHECK_ARRAY( uv, 2*count );
04662 
04663   double *u, *v;
04664   const double *x, *y, *z;
04665   u = *uv;
04666   x = coordinates;
04667   if (storage_order == iBase_BLOCKED) {
04668     v = u + count;
04669     y = x + (coord_step ? count : 1);
04670     z = y + (coord_step ? count : 1);
04671     uv_step = 1;
04672   } 
04673   else {
04674     storage_order = iBase_INTERLEAVED;
04675     v = u + 1;
04676     y = x + 1;
04677     z = x + 2;
04678     coord_step *= 3;
04679     uv_step = 2;
04680   }
04681   
04682   RefEntity** ent = (RefEntity**)gentity_handles;
04683   for (int i = 0; i < count; ++i) {
04684     RefFace* face = dynamic_cast<RefFace*>(*ent);
04685     if (!face) {
04686       ERROR(iBase_INVALID_ENTITY_TYPE, "Expected face for UV method.");
04687     }
04688     
04689     CubitVector xyz( *x, *y, *z );
04690     CubitStatus s = face->u_v_from_position( xyz, *u, *v );
04691     if (CUBIT_SUCCESS != s)
04692       RETURN(iBase_FAILURE);
04693     
04694     ent += ent_step;
04695     u += uv_step;
04696     v += uv_step;
04697     x += coord_step;
04698     y += coord_step;
04699     z += coord_step;
04700   }
04701   
04702   KEEP_ARRAY(uv);
04703   RETURN(iBase_SUCCESS);
04704 }
04705 
04706 
04707 ITAPS_API void
04708 iGeom_getEntXYZtoU( iGeom_Instance instance,
04709                     /*in*/ iBase_EntityHandle entity_handle,
04710                     /*in*/ double x,
04711                     /*in*/ double y,
04712                     /*in*/ double z,
04713                     /*out*/ double* u,
04714                     int* err )
04715 {
04716   RefEntity* entity = (RefEntity*)entity_handle;
04717   RefEdge* edge = dynamic_cast<RefEdge*>(entity);
04718   if (!edge) {
04719     ERROR(iBase_INVALID_ENTITY_TYPE, "Expected edge for 1-param method.");
04720   }
04721   
04722   const CubitVector xyz( x, y, z );
04723   *u = edge->u_from_position( xyz );
04724   RETURN(iBase_SUCCESS);
04725 }
04726 
04727 
04728 ITAPS_API void
04729 iGeom_getArrXYZtoU( iGeom_Instance instance,
04730                     /*in*/ iBase_EntityHandle const *gentity_handles,
04731                     int gentity_handles_size,
04732                     /*in*/ int storage_order,
04733                     /*in*/ const double *coordinates,
04734                     int coordinates_size,
04735                     /*out*/ double **u,
04736                     int *u_allocated,
04737                     int *u_size,
04738                     int* err )
04739 {
04740   int count;
04741   size_t ent_step, coord_step;
04742   if (3*gentity_handles_size == coordinates_size) {
04743     ent_step = coord_step = 1;
04744     count = gentity_handles_size;
04745   }
04746   else if (coordinates_size == 3) {
04747     ent_step = 1;
04748     coord_step = 0;
04749     count = gentity_handles_size;
04750   }
04751   else if (gentity_handles_size == 1) {
04752     ent_step = 0;
04753     coord_step = 1;
04754     count = coordinates_size/3;
04755   }
04756   else {
04757     ERROR(iBase_INVALID_ENTITY_COUNT, "Mismatched input array sizes.");
04758   }
04759     
04760   const double *x, *y, *z;
04761   x = coordinates;
04762   if (storage_order == iBase_BLOCKED) {
04763     y = x + (coord_step ? count : 1);
04764     z = y + (coord_step ? count : 1);
04765   } 
04766   else {
04767     storage_order = iBase_INTERLEAVED;
04768     y = x + 1;
04769     z = x + 2;
04770     coord_step *= 3;
04771   }
04772   
04773   ALLOC_CHECK_ARRAY( u, count );
04774   
04775   RefEntity** ent = (RefEntity**)gentity_handles;
04776   for (int i = 0; i < count; ++i) {
04777     RefEdge* edge = dynamic_cast<RefEdge*>(*ent);
04778     if (!edge) {
04779       ERROR(iBase_INVALID_ENTITY_TYPE, "Expected edge for 1-param method.");
04780     }
04781     
04782     CubitVector xyz( *x, *y, *z );
04783     (*u)[i] = edge->u_from_position( xyz );
04784     
04785     ent += ent_step;
04786     x += coord_step;
04787     y += coord_step;
04788     z += coord_step;
04789   }
04790   
04791   KEEP_ARRAY(u);
04792   RETURN(iBase_SUCCESS);
04793 }
04794 
04795 ITAPS_API void
04796 iGeom_getEntXYZtoUVHint( iGeom_Instance instance,
04797                          /*in*/ iBase_EntityHandle entity_handle,
04798                          /*in*/ double x,
04799                          /*in*/ double y,
04800                          /*in*/ double z,
04801                          /*inout*/ double* u,
04802                          /*inout*/ double* v,
04803                          int* err )
04804 {
04805   RefEntity* entity = (RefEntity*)entity_handle;
04806   RefFace* face = dynamic_cast<RefFace*>(entity);
04807   if (!face) {
04808     ERROR(iBase_INVALID_ENTITY_TYPE, "Expected face for UV method.");
04809   }
04810   
04811   CubitVector xyz( x, y, z );
04812   face->move_to_surface( xyz, u, v );
04813   RETURN(iBase_SUCCESS);
04814 }
04815 
04816 
04825 ITAPS_API void
04826 iGeom_getArrXYZtoUVHint( iGeom_Instance instance,
04827                          /*in*/ iBase_EntityHandle const *gentity_handles,
04828                          int gentity_handles_size,
04829                          /*in*/ int storage_order,
04830                          /*in*/ const double *coordinates,
04831                          int coordinates_size,
04832                          /*inout*/ double **uv,
04833                          int *uv_allocated,
04834                          int *uv_size,
04835                          int* err )
04836 {
04837   int count;
04838   size_t ent_step, coord_step, uv_step;
04839   if (3*gentity_handles_size == coordinates_size) {
04840     ent_step = coord_step = 1;
04841     count = gentity_handles_size;
04842   }
04843   else if (coordinates_size == 3) {
04844     ent_step = 1;
04845     coord_step = 0;
04846     count = gentity_handles_size;
04847   }
04848   else if (gentity_handles_size == 1) {
04849     ent_step = 0;
04850     coord_step = 1;
04851     count = coordinates_size/3;
04852   }
04853   else {
04854     ERROR(iBase_INVALID_ENTITY_COUNT, "Mismatched input array sizes.");
04855   }
04856     
04857   double *u, *v;
04858   const double *x, *y, *z;
04859   u = *uv;
04860   x = coordinates;
04861   if (storage_order == iBase_BLOCKED) {
04862     v = u + count;
04863     y = x + (coord_step ? count : 1);
04864     z = y + (coord_step ? count : 1);
04865     uv_step = 1;
04866   } 
04867   else {
04868     storage_order = iBase_INTERLEAVED;
04869     v = u + 1;
04870     y = x + 1;
04871     z = x + 2;
04872     coord_step *= 3;
04873     uv_step = 2;
04874   }
04875   
04876   ALLOC_CHECK_ARRAY( uv, 2*count );
04877   
04878   RefEntity** ent = (RefEntity**)gentity_handles;
04879   for (int i = 0; i < count; ++i) {
04880     RefFace* face = dynamic_cast<RefFace*>(*ent);
04881     if (!face) {
04882       ERROR(iBase_INVALID_ENTITY_TYPE, "Expected face for UV method.");
04883     }
04884     
04885     CubitVector xyz( *x, *y, *z );
04886     face->move_to_surface( xyz, u, v );
04887     
04888     ent += ent_step;
04889     u += uv_step;
04890     v += uv_step;
04891     x += coord_step;
04892     y += coord_step;
04893     z += coord_step;
04894   }
04895   
04896   KEEP_ARRAY(uv);
04897   RETURN(iBase_SUCCESS);
04898 }
04899 
04900 ITAPS_API void
04901 iGeom_getEntUVRange( iGeom_Instance instance,
04902                      /*in*/ iBase_EntityHandle entity_handle,
04903                      /*out*/ double *u_min,
04904                      /*out*/ double *v_min,
04905                      /*out*/ double *u_max,
04906                      /*out*/ double *v_max,
04907                      int* err )
04908 {
04909   RefEntity* entity = (RefEntity*)entity_handle;
04910   RefFace* face = dynamic_cast<RefFace*>(entity);
04911   if (!face) {
04912     ERROR(iBase_INVALID_ENTITY_TYPE, "Expected face for UV method.");
04913   }
04914   
04915   CubitBoolean r1 = face->get_param_range_U(*u_min, *u_max);
04916   CubitBoolean r2 = face->get_param_range_V(*v_min, *v_max);
04917   RETURN( ((r1 && r2) ? iBase_SUCCESS : iBase_FAILURE) );
04918 }
04919 
04920 ITAPS_API void
04921 iGeom_getEntURange( iGeom_Instance instance,
04922                     /*in*/ iBase_EntityHandle entity_handle,
04923                     /*out*/ double *u_min,
04924                     /*out*/ double *u_max,
04925                     int* err )
04926 {
04927   RefEntity* entity = (RefEntity*)entity_handle;
04928   RefEdge* edge = dynamic_cast<RefEdge*>(entity);
04929   if (!edge) {
04930     ERROR(iBase_INVALID_ENTITY_TYPE, "Expected edge for 1-param method.");
04931   }
04932   
04933   CubitBoolean r1 = edge->get_param_range(*u_min, *u_max);
04934   RETURN( (r1 ? iBase_SUCCESS : iBase_FAILURE) );
04935 }
04936     
04937 
04944 ITAPS_API void
04945 iGeom_getArrUVRange( iGeom_Instance instance,
04946                      /*in*/ iBase_EntityHandle const *gentity_handles,
04947                      int gentity_handles_size,
04948                      /*in*/ int storage_order,
04949                      /*out*/ double **uv_min,
04950                      int *uv_min_allocated,
04951                      int *uv_min_size,
04952                      /*out*/ double **uv_max,
04953                      int *uv_max_allocated,
04954                      int *uv_max_size,
04955                      int* err )
04956 {
04957   ALLOC_CHECK_ARRAY(uv_min, 2*gentity_handles_size);
04958   ALLOC_CHECK_ARRAY(uv_max, 2*gentity_handles_size);
04959   
04960   size_t init, step;
04961   if (storage_order == iBase_BLOCKED) {
04962     init = gentity_handles_size;
04963     step = 1;
04964   }
04965   else {
04966     init = 1;
04967     step = 2;
04968   }
04969   
04970   double *u_min = *uv_min;
04971   double *v_min = u_min + init;
04972   double *u_max = *uv_max;
04973   double *v_max = u_max + init;
04974   
04975   RefEntity** entities = (RefEntity**)gentity_handles;
04976   for (int i = 0; i < gentity_handles_size; ++i) {
04977     RefFace* face = dynamic_cast<RefFace*>(entities[i]);
04978     if (!face) {
04979       ERROR(iBase_INVALID_ENTITY_TYPE, "Expected face for UV method.");
04980     }
04981     
04982     CubitBoolean r1 = face->get_param_range_U(*u_min, *u_max);
04983     CubitBoolean r2 = face->get_param_range_V(*v_min, *v_max);
04984     if (!(r1 && r2)) {
04985       RETURN(iBase_FAILURE);
04986     }
04987     
04988     u_min += step;
04989     v_min += step;
04990     u_max += step;
04991     v_max += step;
04992   }
04993   
04994   KEEP_ARRAY(uv_min);
04995   KEEP_ARRAY(uv_max);
04996   RETURN(iBase_SUCCESS);
04997 }
04998 
04999 ITAPS_API void
05000 iGeom_getArrURange( iGeom_Instance instance,
05001                     /*in*/ iBase_EntityHandle const *gentity_handles,
05002                     const int gentity_handles_size,
05003                     /*out*/ double **u_min,
05004                     int *u_min_allocated,
05005                     int *u_min_size,
05006                     /*out*/ double **u_max,
05007                     int *u_max_allocated,
05008                     int *u_max_size,
05009                     int* err )
05010 {
05011   ALLOC_CHECK_ARRAY(u_min, gentity_handles_size);
05012   ALLOC_CHECK_ARRAY(u_max, gentity_handles_size);
05013   
05014   RefEntity** entities = (RefEntity**)gentity_handles;
05015   for (int i = 0; i < gentity_handles_size; ++i) {
05016     RefEdge* edge = dynamic_cast<RefEdge*>(entities[i]);
05017     if (!edge) {
05018       ERROR(iBase_INVALID_ENTITY_TYPE, "Expected edge for 1-param method.");
05019     }
05020     
05021     CubitBoolean r1 = edge->get_param_range((*u_min)[i], (*u_max)[i]);
05022     if (!r1) {
05023       RETURN(iBase_FAILURE);
05024     }
05025   }
05026   
05027   KEEP_ARRAY(u_min);
05028   KEEP_ARRAY(u_max);
05029   RETURN(iBase_SUCCESS);
05030 }
05031 
05032 ITAPS_API void
05033 iGeom_getEntUtoUV( iGeom_Instance instance,
05034                    /*in*/ iBase_EntityHandle edge_handle,
05035                    /*in*/ iBase_EntityHandle face_handle,
05036                    /*in*/ double in_u,
05037                    /*out*/ double* u,
05038                    /*out*/ double* v,
05039                    int* err )
05040 {
05041   RefEdge* edge = dynamic_cast<RefEdge*>((RefEntity*)edge_handle);
05042   RefFace* face = dynamic_cast<RefFace*>((RefEntity*)face_handle);
05043   if (!edge || !face) {
05044     RETURN(iBase_INVALID_ENTITY_TYPE);
05045   }
05046   
05047   CubitVector xyz;
05048   CubitStatus s;
05049   s = edge->position_from_u( in_u, xyz );
05050   if (s != CUBIT_SUCCESS)
05051     RETURN(iBase_FAILURE);
05052 
05053   s = face->u_v_from_position( xyz, *u, *v );
05054   RETURN( (s == CUBIT_SUCCESS ? iBase_SUCCESS : iBase_FAILURE) );
05055 }
05056 
05057 static bool
05058 iGeom_check_array_size(int size1, int size2)
05059 {
05060     return size1 == 1 || size2 == 1 || size1 == size2;        
05061 }
05062 
05063 ITAPS_API void
05064 iGeom_getArrUtoUV( iGeom_Instance instance,
05065                    /*in*/ iBase_EntityHandle const *edge_handles,
05066                    int edge_handles_size,
05067                    /*in*/ iBase_EntityHandle const *face_handles,
05068                    int face_handles_size,
05069                    /*in*/ const double *in_u,
05070                    int in_u_size,
05071                    /*in*/ int storage_order,
05072                    /*inout*/ double **uv,
05073                    int *uv_allocated,
05074                    int *uv_size,
05075                    int* err )
05076 {
05077   int count;
05078   size_t edge_step, face_step, coord_step, in_u_step;
05079 
05080   if (!(iGeom_check_array_size(edge_handles_size, face_handles_size) &&
05081         iGeom_check_array_size(edge_handles_size, in_u_size) &&
05082         iGeom_check_array_size(face_handles_size, in_u_size))) {
05083     ERROR(iBase_INVALID_ENTITY_COUNT, "Mismatched input array sizes.");
05084   }
05085 
05086   edge_step = (edge_handles_size == 1) ? 0:1;
05087   face_step = (face_handles_size == 1) ? 0:1;
05088   in_u_step = (in_u_size == 1) ? 0:1;
05089 
05090   count = std::max(edge_handles_size, std::max(face_handles_size, in_u_size));
05091 
05092   ALLOC_CHECK_ARRAY( uv, 2*count );
05093   
05094   const double *in_u_iter;
05095   double *u, *v;
05096   in_u_iter = in_u;
05097   u = *uv;
05098   if (storage_order == iBase_BLOCKED) {
05099     v = u + count;
05100     coord_step = 1;
05101   } 
05102   else {
05103     v = u + 1;
05104     coord_step = 2;
05105   }
05106   
05107   RefEntity** edge_ent = (RefEntity**)edge_handles;
05108   RefEntity** face_ent = (RefEntity**)face_handles;
05109   for (int i = 0; i < count; ++i) {
05110     RefEdge* edge = dynamic_cast<RefEdge*>(*edge_ent);
05111     RefFace* face = dynamic_cast<RefFace*>(*face_ent);
05112     if (!edge || !face) {
05113       RETURN(iBase_INVALID_ENTITY_TYPE);
05114     }
05115     
05116     CubitVector xyz;
05117     CubitStatus s;
05118     s = edge->position_from_u( *in_u_iter, xyz );
05119     if (CUBIT_SUCCESS != s)
05120       RETURN(iBase_FAILURE);
05121     s = face->u_v_from_position( xyz, *u, *v );
05122     if (CUBIT_SUCCESS != s)
05123       RETURN(iBase_FAILURE);
05124 
05125     edge_ent += edge_step;
05126     face_ent += face_step;
05127     in_u_iter += in_u_step;
05128     u += coord_step;
05129     v += coord_step;
05130   }
05131   
05132   KEEP_ARRAY(uv);
05133   RETURN(iBase_SUCCESS);
05134 }
05135 
05136 ITAPS_API void
05137 iGeom_getVtxToUV( iGeom_Instance instance,
05138                   /*in*/ iBase_EntityHandle vertex_handle,
05139                   /*in*/ iBase_EntityHandle face_handle,
05140                   /*out*/ double* u,
05141                   /*out*/ double* v,
05142                   int* err )
05143 {
05144   RefVertex* vtx = dynamic_cast<RefVertex*>((RefEntity*)vertex_handle);
05145   RefFace* face = dynamic_cast<RefFace*>((RefEntity*)face_handle);
05146   if (!vtx || !face) {
05147     RETURN(iBase_INVALID_ENTITY_TYPE);
05148   }
05149 
05150   iBase_ErrorType result = iGeom_get_vtx_to_uv( vtx, face, *u, *v );
05151   RETURN(result);
05152 }  
05153 
05154 ITAPS_API void
05155 iGeom_getVtxArrToUV( iGeom_Instance instance,
05156                      /*in*/ iBase_EntityHandle const *vertex_handles,
05157                      int vertex_handles_size,
05158                      /*in*/ iBase_EntityHandle const *face_handles,
05159                      int face_handles_size,
05160                      /*in*/ int storage_order,
05161                      /*inout*/ double **uv,
05162                      int *uv_allocated,
05163                      int *uv_size,
05164                      int* err )
05165 {
05166   int count;
05167   size_t vtx_step, face_step, uv_step;
05168   if (vertex_handles_size == face_handles_size) {
05169     count = vertex_handles_size;
05170     vtx_step = face_step = 1;
05171   }
05172   else if (face_handles_size == 1) {
05173     count = vertex_handles_size;
05174     vtx_step = 1;
05175     face_step = 0;
05176   }
05177   else if (vertex_handles_size == 1) {
05178     count = face_handles_size;
05179     vtx_step = 0;
05180     face_step = 1;
05181   }
05182   else {
05183     ERROR(iBase_INVALID_ENTITY_COUNT, "Mismatched input array sizes.");
05184   }
05185   
05186   ALLOC_CHECK_ARRAY( uv, 2*count );
05187 
05188   double *u, *v;
05189   u = *uv;
05190   if (storage_order == iBase_BLOCKED) {
05191     v = u + count;
05192     uv_step = 1;
05193   } 
05194   else {
05195     storage_order = iBase_INTERLEAVED;
05196     v = u + 1;
05197     uv_step = 2;
05198   }
05199   
05200   RefEntity** vtx_iter = (RefEntity**)vertex_handles;
05201   RefEntity** face_iter = (RefEntity**)face_handles;
05202   for (int i = 0; i < count; ++i) {
05203     RefVertex* vtx = dynamic_cast<RefVertex*>(*vtx_iter);
05204     RefFace* face = dynamic_cast<RefFace*>(*face_iter);
05205     if (!vtx || !face) {
05206       RETURN(iBase_INVALID_ENTITY_TYPE);
05207     }
05208     
05209     iBase_ErrorType rval = iGeom_get_vtx_to_uv( vtx, face, *u, *v );
05210     if (iBase_SUCCESS != rval) {
05211       RETURN(rval);
05212     }
05213 
05214     vtx_iter += vtx_step;
05215     face_iter += face_step;
05216     u += uv_step;
05217     v += uv_step;
05218   }
05219   KEEP_ARRAY(uv);
05220   RETURN(iBase_SUCCESS);
05221 }
05222 
05223 ITAPS_API void
05224 iGeom_getVtxToU( iGeom_Instance instance,
05225                  /*in*/ iBase_EntityHandle vertex_handle,
05226                  /*in*/ iBase_EntityHandle edge_handle,
05227                  /*out*/ double* u,
05228                  int* err )
05229 {
05230   RefVertex* vtx = dynamic_cast<RefVertex*>((RefEntity*)vertex_handle);
05231   RefEdge* edge = dynamic_cast<RefEdge*>((RefEntity*)edge_handle);
05232   if (!vtx || !edge) {
05233     RETURN(iBase_INVALID_ENTITY_TYPE);
05234   }
05235   
05236   iBase_ErrorType result = iGeom_get_vtx_to_u( vtx, edge, *u );
05237   RETURN(result);
05238 }
05239 
05240 ITAPS_API void
05241 iGeom_getVtxArrToU( iGeom_Instance instance,
05242                     /*in*/ iBase_EntityHandle const *vertex_handles ,
05243                     int vertex_handles_size,
05244                     /*in*/ iBase_EntityHandle const *edge_handles ,
05245                     int edge_handles_size,
05246                     /*inout*/  double **u ,
05247                     int *u_allocated,
05248                     int *u_size,
05249                     int* err )
05250 {
05251   int count;
05252   size_t vtx_step, edge_step;
05253   if (vertex_handles_size == edge_handles_size) {
05254     count = vertex_handles_size;
05255     vtx_step = edge_step = 1;
05256   }
05257   else if (edge_handles_size == 1) {
05258     count = vertex_handles_size;
05259     vtx_step = 1;
05260     edge_step = 0;
05261   }
05262   else if (vertex_handles_size == 1) {
05263     count = edge_handles_size;
05264     vtx_step = 0;
05265     edge_step = 1;
05266   }
05267   else {
05268     ERROR(iBase_INVALID_ENTITY_COUNT, "Mismatched input array sizes.");
05269   }
05270   
05271   ALLOC_CHECK_ARRAY( u, count );
05272   
05273   RefEntity** vtx_iter = (RefEntity**)vertex_handles;
05274   RefEntity** edge_iter = (RefEntity**)edge_handles;
05275   for (int i = 0; i < count; ++i) {
05276     RefVertex* vtx = dynamic_cast<RefVertex*>(*vtx_iter);
05277     RefEdge* edge = dynamic_cast<RefEdge*>(*edge_iter);
05278     if (!vtx || !edge) {
05279       RETURN(iBase_INVALID_ENTITY_TYPE);
05280     }
05281     
05282     iBase_ErrorType rval = iGeom_get_vtx_to_u( vtx, edge, (*u)[i] );
05283     if (iBase_SUCCESS != rval) {
05284       RETURN(rval);
05285     }
05286     
05287     vtx_iter += vtx_step;
05288     edge_iter += edge_step;
05289   }
05290   KEEP_ARRAY(u);
05291   RETURN(iBase_SUCCESS);
05292 }
05293 
05294 ITAPS_API void
05295 iGeom_getEntNrmlUV( iGeom_Instance instance,
05296                     /*in*/ iBase_EntityHandle entity_handle,
05297                     /*in*/ double u,
05298                     /*in*/ double v,
05299                     /*out*/ double* nrml_i,
05300                     /*out*/ double* nrml_j,
05301                     /*out*/ double* nrml_k,
05302                     int* err )
05303 {
05304   RefFace* face = dynamic_cast<RefFace*>((RefEntity*)entity_handle);
05305   if (!face) {
05306     RETURN (iBase_INVALID_ENTITY_TYPE);
05307   }
05308   
05309   CubitVector normal;
05310   CubitStatus s = iGeom_normal_from_uv( face, u, v, normal );
05311   normal.get_xyz( *nrml_i, *nrml_j, *nrml_k );
05312   RETURN ((s == CUBIT_SUCCESS ? iBase_SUCCESS : iBase_FAILURE));
05313 }
05314 
05323 ITAPS_API void
05324 iGeom_getArrNrmlUV( iGeom_Instance instance,
05325                     /*in*/ iBase_EntityHandle const *gface_handles,
05326                     int gface_handles_size,
05327                     /*in*/ int storage_order,
05328                     /*in*/ const double *parameters,
05329                     int parameters_size,
05330                     /*out*/ double **normals,
05331                     int *normals_allocated,
05332                     int *normals_size,
05333                     int* err )
05334 {
05335   int count;
05336   size_t face_step, param_step, norm_step;
05337   if (2*gface_handles_size == parameters_size) {
05338     count = gface_handles_size;
05339     face_step = param_step = 1;
05340   }
05341   else if (parameters_size == 2) {
05342     count = gface_handles_size;
05343     face_step = 1;
05344     param_step = 0;
05345   }
05346   else if (gface_handles_size == 1) {
05347     count = parameters_size/2;
05348     face_step = 0;
05349     param_step = 1;
05350   }
05351   else {
05352     ERROR(iBase_INVALID_ENTITY_COUNT, "Mismatched input array sizes.");
05353   }
05354   
05355     // check or pre-allocate the coordinate arrays
05356   ALLOC_CHECK_ARRAY( normals, 3*count );
05357 
05358   const double *u, *v;
05359   double *x, *y, *z;
05360   u = parameters;
05361   x = *normals;
05362   if (storage_order == iBase_BLOCKED) {
05363     v = u + (param_step ? count : 1);
05364     y = x + count;
05365     z = y + count;
05366     norm_step = 1;
05367   }
05368   else {
05369     storage_order = iBase_INTERLEAVED;
05370     v = u + 1;
05371     y = x + 1;
05372     z = x + 2;
05373     norm_step = 3;
05374     param_step *= 2;
05375   }
05376   
05377   RefEntity** face_iter = (RefEntity**)gface_handles;
05378   for (int i = 0; i < count; ++i) {
05379     RefFace* face = dynamic_cast<RefFace*>(*face_iter);
05380     if (!face) { RETURN (iBase_INVALID_ENTITY_TYPE); }
05381     
05382     CubitVector normal;
05383     CubitStatus s = iGeom_normal_from_uv( face, *u, *v, normal );
05384     normal.get_xyz( *x, *y, *z );
05385     if (CUBIT_SUCCESS != s) {
05386       RETURN(iBase_FAILURE);
05387     }
05388     
05389     face_iter += face_step;
05390     x += norm_step;
05391     y += norm_step;
05392     z += norm_step;
05393     u += param_step;
05394     v += param_step;
05395   }
05396   
05397   KEEP_ARRAY(normals);
05398   RETURN(iBase_SUCCESS);
05399 }
05400 
05401 
05402 ITAPS_API void
05403 iGeom_getEntTgntU( iGeom_Instance instance,
05404                    /*in*/ iBase_EntityHandle entity_handle,
05405                    /*in*/ double param_coord,
05406                    /*out*/ double* tngt_i,
05407                    /*out*/ double* tngt_j,
05408                    /*out*/ double* tngt_k,
05409                    int* err )
05410 {
05411   double x, y, z;
05412   iGeom_getEntUtoXYZ( instance, entity_handle, param_coord, &x, &y, &z, err );
05413   if (iBase_SUCCESS == *err)
05414     iGeom_getEntTgntXYZ( instance, entity_handle, x, y, z, tngt_i, tngt_j, tngt_k, err );
05415 }
05416 
05425 ITAPS_API void
05426 iGeom_getArrTgntU( iGeom_Instance instance,
05427                    /*in*/ iBase_EntityHandle const *gedge_handles,
05428                    int gedge_handles_size,
05429                    /*in*/ int storage_order,
05430                    /*in*/ const double *parameters,
05431                    int parameters_size,
05432                    /*out*/ double **tangents,
05433                    int *tangents_allocated,
05434                    int *tangents_size,
05435                    int* err )
05436 {
05437   iGeom_getArrUtoXYZ(instance, ARRAY_IN(gedge_handles),
05438                      ARRAY_IN(parameters), storage_order, 
05439                      ARRAY_INOUT(tangents), err); 
05440   if (iBase_SUCCESS == *err)
05441     iGeom_getArrTgntXYZ(instance, ARRAY_IN(gedge_handles), storage_order,
05442                         *tangents, *tangents_size, ARRAY_INOUT(tangents), err);
05443 }
05444 
05445 ITAPS_API void
05446 iGeom_getEnt1stDrvt( iGeom_Instance instance,
05447                      /*in*/ iBase_EntityHandle entity_handle,
05448                      /*in*/ double u,
05449                      /*in*/ double v,
05450                      /*inout*/  double **dvrt_u ,
05451                      int *dvrt_u_allocated,
05452                      int *dvrt_u_size,
05453                      /*inout*/  double **dvrt_v ,
05454                      int *dvrt_v_allocated,
05455                      int *dvrt_v_size,
05456                      int* err )
05457 {
05458   RefFace* face = dynamic_cast<RefFace*>((RefEntity*)entity_handle);
05459   if (!face) { 
05460     ERROR( iBase_INVALID_ENTITY_TYPE, "Derivatives only for faces." );
05461   }
05462   
05463   CubitVector du, dv;
05464   CubitStatus s = face->get_surface_ptr()->uv_derivitives( u, v, du, dv );
05465   if (CUBIT_SUCCESS != s) {
05466     RETURN(iBase_FAILURE);
05467   }
05468   
05469   ALLOC_CHECK_ARRAY_NOFAIL( dvrt_u, 3 );
05470   ALLOC_CHECK_ARRAY_NOFAIL( dvrt_v, 3 );
05471   du.get_xyz( *dvrt_u );
05472   dv.get_xyz( *dvrt_v );
05473   RETURN (iBase_SUCCESS);
05474 }
05475 
05476 ITAPS_API void
05477 iGeom_getArr1stDrvt( iGeom_Instance instance,
05478                      /*in*/ iBase_EntityHandle const *entity_handles ,
05479                      int entity_handles_size,
05480                      /*in*/ int storage_order,
05481                      /*in*/ const  double *uv ,
05482                      int uv_size,
05483                      /*inout*/  double **drvt_u ,
05484                      int *drvt_u_allocated,
05485                      int *drvt_u_size,
05486                      /*inout*/  int **u_offset ,
05487                      int *u_offset_allocated,
05488                      int *u_offset_size,  
05489                      /*inout*/  double **drvt_v ,
05490                      int *drvt_v_allocated,
05491                      int *drvt_v_size,
05492                      /*inout*/  int **v_offset ,
05493                      int *v_offset_allocated,
05494                      int *v_offset_size,
05495                      int* err )
05496 {
05497   if (2*entity_handles_size != uv_size) {
05498     ERROR(iBase_INVALID_ENTITY_COUNT, "Mismatched input array sizes.");
05499     RETURN(iBase_INVALID_ENTITY_COUNT);
05500   }
05501   
05502   ALLOC_CHECK_ARRAY( drvt_u, 3*entity_handles_size );
05503   ALLOC_CHECK_ARRAY( drvt_v, 3*entity_handles_size );
05504   ALLOC_CHECK_ARRAY( u_offset, entity_handles_size+1 );
05505   ALLOC_CHECK_ARRAY( v_offset, entity_handles_size+1 );
05506   
05507   size_t u_step, du_step, init;
05508   if (storage_order == iBase_BLOCKED) {
05509     u_step = du_step = 1;
05510     init = entity_handles_size;
05511   }
05512   else {
05513     storage_order = iBase_INTERLEAVED;
05514     u_step = 2;
05515     du_step = 3;
05516     init = 1;
05517   }
05518   
05519   const double *u = uv;
05520   const double *v = u + init;
05521   double *du_x = *drvt_u;
05522   double *du_y = du_x + init;
05523   double *du_z = du_y + init;
05524   double *dv_x = *drvt_v;
05525   double *dv_y = dv_x + init;
05526   double *dv_z = dv_y + init;
05527   
05528   int off = 0;
05529   RefEntity** entities = (RefEntity**)entity_handles;
05530   for (int i = 0; i < entity_handles_size; ++i) {
05531     RefFace* face = dynamic_cast<RefFace*>(entities[i]);
05532     if (!face) { 
05533       ERROR( iBase_INVALID_ENTITY_TYPE, "Derivatives only for faces." );
05534     }
05535     
05536     CubitVector du, dv;
05537     CubitStatus s = face->get_surface_ptr()->uv_derivitives( *u, *v, du, dv );
05538     if (s != CUBIT_SUCCESS) { RETURN(iBase_FAILURE); }
05539     du.get_xyz( *du_x, *du_y, *du_z );
05540     dv.get_xyz( *dv_x, *dv_y, *dv_z );
05541   
05542     u += u_step;
05543     v += u_step;
05544     du_x += du_step;
05545     du_y += du_step;
05546     du_z += du_step;
05547     dv_x += du_step;
05548     dv_y += du_step;
05549     dv_z += du_step;
05550 
05551     (*u_offset)[i] = off;
05552     (*v_offset)[i] = off;
05553     off += du_step;
05554   }
05555   (*u_offset)[entity_handles_size] = off;
05556   (*v_offset)[entity_handles_size] = off; 
05557 
05558   KEEP_ARRAY( drvt_u );
05559   KEEP_ARRAY( drvt_v );
05560   KEEP_ARRAY( u_offset );
05561   KEEP_ARRAY( v_offset );
05562   RETURN(iBase_SUCCESS);
05563 }
05564 
05565 ITAPS_API void
05566 iGeom_getEnt2ndDrvt( iGeom_Instance instance,
05567                      /*in*/ iBase_EntityHandle entity_handle,
05568                      /*in*/ double u,
05569                      /*in*/ double v,
05570                      /*inout*/  double **dvrt_uu ,
05571                      int *dvrt_uu_allocated,
05572                      int *dvrt_uu_size,
05573                      /*inout*/  double **dvrt_uv ,
05574                      int *dvrt_uv_allocated,
05575                      int *dvrt_uv_size,
05576                      /*inout*/  double **dvrt_vv ,
05577                      int *dvrt_vv_allocated,
05578                      int *dvrt_vv_size,
05579                      int* err )
05580 {
05581   RETURN(iBase_NOT_SUPPORTED);
05582 }
05583 
05584 ITAPS_API void
05585 iGeom_getArr2ndDrvt( iGeom_Instance instance,
05586                      /*in*/ iBase_EntityHandle const *entity_handles ,
05587                      int entity_handles_size,
05588                      /*in*/ int storage_order,
05589                      /*in*/ const  double *uv ,
05590                      int uv_size,
05591                      /*inout*/  double **drvt_uu ,
05592                      int *drvt_uu_allocated,
05593                      int *drvt_uu_size,
05594                      /*inout*/  int **uu_offset ,
05595                      int *uu_offset_allocated,
05596                      int *uu_offset_size,  
05597                      /*inout*/  double **drvt_uv ,
05598                      int *drvt_uv_allocated,
05599                      int *drvt_uv_size,
05600                      /*inout*/  int **uv_offset ,
05601                      int *uv_offset_allocated,
05602                      int *uv_offset_size,  
05603                      /*inout*/  double **drvt_vv ,
05604                      int *drvt_vv_allocated,
05605                      int *drvt_vv_size,
05606                      /*inout*/  int **vv_offset ,
05607                      int *vv_offset_allocated,
05608                      int *vv_offset_size,
05609                      int* err )
05610 {
05611   RETURN(iBase_NOT_SUPPORTED);
05612 }
05613 
05614 ITAPS_API void
05615 iGeom_getFcCvtrUV( iGeom_Instance instance,
05616                    /*in*/ iBase_EntityHandle entity_handle,
05617                    /*in*/ double u,
05618                    /*in*/ double v,
05619                    /*out*/ double* cvtr1_i,
05620                    /*out*/ double* cvtr1_j,
05621                    /*out*/ double* cvtr1_k,
05622                    /*out*/ double* cvtr2_i,
05623                    /*out*/ double* cvtr2_j,
05624                    /*out*/ double* cvtr2_k,
05625                    int* err )
05626 {
05627   double x, y, z;
05628   iGeom_getEntUVtoXYZ(instance, entity_handle, u, v, &x, &y, &z, err );
05629   if (*err == iBase_SUCCESS)
05630     iGeom_getFcCvtrXYZ(instance, entity_handle, x, y, z, 
05631                        cvtr1_i, cvtr1_j, cvtr1_k,
05632                        cvtr2_i, cvtr2_j, cvtr2_k,
05633                        err );
05634 }
05635 
05636 
05637 ITAPS_API void
05638 iGeom_getFcArrCvtrUV( iGeom_Instance instance,
05639                       /*in*/ const  iBase_EntityHandle *face_handles ,
05640                       int face_handles_size,
05641                       /*in*/ int storage_order,
05642                       /*in*/ const  double *uv ,
05643                       int uv_size,
05644                       /*inout*/  double **cvtr_1 ,
05645                       int *cvtr_1_allocated,
05646                       int *cvtr_1_size,
05647                       /*inout*/  double **cvtr_2 ,
05648                       int *cvtr_2_allocated,
05649                       int *cvtr_2_size,
05650                       int* err )
05651 {
05652   iGeom_getArrUVtoXYZ(instance, ARRAY_IN(face_handles), storage_order, 
05653                       ARRAY_IN(uv), ARRAY_INOUT(cvtr_1), err);
05654   if (*err == iBase_SUCCESS)
05655     iGeom_getEntArrCvtrXYZ(instance, ARRAY_IN(face_handles), storage_order,
05656                            *cvtr_1, *cvtr_1_size, 
05657                            ARRAY_INOUT(cvtr_1), ARRAY_INOUT(cvtr_2), err);
05658 }
05659 
05660 ITAPS_API void
05661 iGeom_isEntPeriodic( iGeom_Instance instance, 
05662                      /*in*/ iBase_EntityHandle entity_handle,
05663                      /*out*/ int* in_u,
05664                      /*out*/ int* in_v,
05665                      int* err )
05666 {
05667   CubitStatus s = iGeom_is_periodic( (RefEntity*)entity_handle, *in_u, *in_v );
05668   RETURN( (s == CUBIT_SUCCESS ? iBase_SUCCESS : iBase_FAILURE) );
05669 }
05670 
05671 ITAPS_API void
05672 iGeom_isArrPeriodic( iGeom_Instance instance,
05673                      /*in*/ iBase_EntityHandle const *entity_handles ,
05674                      const int entity_handles_size,
05675                      /*inout*/  int **in_uv ,
05676                      int *in_uv_allocated,
05677                      int *in_uv_size,
05678                      int* err )
05679 {
05680   ALLOC_CHECK_ARRAY( in_uv, 2*entity_handles_size );
05681   RefEntity** ents = (RefEntity**)entity_handles;
05682   for (int i = 0; i < entity_handles_size; ++i) {
05683     CubitStatus s = iGeom_is_periodic( ents[i], (*in_uv)[2*i], (*in_uv)[2*i+1] );
05684     if (s != CUBIT_SUCCESS) {
05685       RETURN(iBase_FAILURE);
05686     }
05687   }
05688   KEEP_ARRAY(in_uv);
05689   RETURN(iBase_SUCCESS);
05690 }
05691 
05692 ITAPS_API void
05693 iGeom_isFcDegenerate( iGeom_Instance instance,
05694                       /*in*/ iBase_EntityHandle entity_handle,
05695                       int* is_degenerate,
05696                       int* err )
05697 {
05698   RefFace* face = dynamic_cast<RefFace*>((RefEntity*)entity_handle);
05699   if (!face) { RETURN (iBase_INVALID_ENTITY_TYPE); }
05700   *is_degenerate = iGeom_is_face_degenerate(face);
05701   RETURN (iBase_SUCCESS);
05702 }
05703 
05704 ITAPS_API void
05705 iGeom_isFcArrDegenerate( iGeom_Instance instance,
05706                          /*in*/ iBase_EntityHandle const *face_handles ,
05707                          const int face_handles_size,
05708                          /*inout*/  int **degenerate ,
05709                          int *degenerate_allocated,
05710                          int *degenerate_size,
05711                          int* err )
05712 {
05713   ALLOC_CHECK_ARRAY( degenerate, face_handles_size );
05714   RefEntity** faces = (RefEntity**)face_handles;
05715   for (int i = 0; i < face_handles_size; ++i) {
05716     RefFace* face = dynamic_cast<RefFace*>(faces[i]);
05717     if (!face) { RETURN (iBase_INVALID_ENTITY_TYPE); }
05718     (*degenerate)[i] = iGeom_is_face_degenerate( face );
05719   }
05720   KEEP_ARRAY(degenerate);
05721   RETURN(iBase_SUCCESS);
05722 }
05723                
05724 
05734 ITAPS_API void
05735 iGeom_subtract( iGeom_Instance instance,
05736                 /*in*/ iBase_EntitySetHandle entity_set_1,
05737                 /*in*/ iBase_EntitySetHandle entity_set_2,
05738                 /*out*/ iBase_EntitySetHandle *result_entity_set,
05739                 int* err )
05740 {
05741   const RefGroup *set1 = SET_HANDLE(entity_set_1);
05742   const RefGroup *set2 = SET_HANDLE(entity_set_2);
05743   RefGroup *set3 = SET_HANDLE(*result_entity_set);
05744   if (NULL == set3) {
05745     set3 = RefEntityFactory::instance()->construct_RefGroup();
05746     *result_entity_set = reinterpret_cast<iBase_EntitySetHandle>(set3);
05747   }
05748     
05749   const_cast<RefGroup*>(set1)->subtract(const_cast<RefGroup*>(set2), set3);
05750   RETURN(iBase_SUCCESS);
05751 }
05752 
05758 ITAPS_API void
05759 iGeom_intersect( iGeom_Instance instance,
05760                  /*in*/ iBase_EntitySetHandle entity_set_1,
05761                  /*in*/ iBase_EntitySetHandle entity_set_2,
05762                  /*out*/ iBase_EntitySetHandle *result_entity_set,
05763                  int* err )
05764 {
05765   const RefGroup *set1 = SET_HANDLE(entity_set_1);
05766   const RefGroup *set2 = SET_HANDLE(entity_set_2);
05767   RefGroup *set3 = SET_HANDLE(*result_entity_set);
05768   if (NULL == set3) {
05769     set3 = RefEntityFactory::instance()->construct_RefGroup();
05770     *result_entity_set = reinterpret_cast<iBase_EntitySetHandle>(set3);
05771   }
05772 
05773   const_cast<RefGroup*>(set1)->intersect(const_cast<RefGroup*>(set2), set3);
05774   RETURN(iBase_SUCCESS);
05775 }
05776 
05782 ITAPS_API void
05783 iGeom_unite( iGeom_Instance instance,
05784              /*in*/ iBase_EntitySetHandle entity_set_1,
05785              /*in*/ iBase_EntitySetHandle entity_set_2,
05786              /*out*/ iBase_EntitySetHandle *result_entity_set,
05787              int* err )
05788 {
05789   const RefGroup *set1 = SET_HANDLE(entity_set_1);
05790   const RefGroup *set2 = SET_HANDLE(entity_set_2);
05791   RefGroup *set3 = SET_HANDLE(*result_entity_set);
05792   if (NULL == set3) {
05793     set3 = RefEntityFactory::instance()->construct_RefGroup();
05794     *result_entity_set = reinterpret_cast<iBase_EntitySetHandle>(set3);
05795   }
05796 
05797   const_cast<RefGroup*>(set1)->unite(const_cast<RefGroup*>(set2), set3);
05798   RETURN(iBase_SUCCESS);
05799 }
05800 
05801 ITAPS_API void
05802 iGeom_copyEnt( iGeom_Instance instance,
05803                /*in*/ iBase_EntityHandle geom_entity,
05804                /*out*/ iBase_EntityHandle *geom_entity2,
05805                int* err )
05806 {
05807   Body *this_body = dynamic_cast<Body*>(ENTITY_HANDLE(geom_entity));
05808   RefVolume *this_vol = dynamic_cast<RefVolume*>(ENTITY_HANDLE(geom_entity));
05809   if (NULL != this_vol || NULL != this_body) {
05810       // need to get the associated body, since cgm only supports copying bodies,
05811       // not volumes
05812     if (NULL == this_body) {
05813       this_body = this_vol->get_body_ptr();
05814       if (NULL == this_body) {
05815         ERROR(iBase_FAILURE, "Can't get body from volume.");
05816       }
05817     }
05818 
05819     RefEntity *temp_entity = gmt->copy_body(this_body);
05820     *geom_entity2 = reinterpret_cast<iBase_EntityHandle>(temp_entity);
05821   }
05822   else {
05823     RefEntity *this_ent = ENTITY_HANDLE(geom_entity);
05824     RefEntity *temp_entity = gmt->copy_refentity(this_ent);
05825     *geom_entity2 = reinterpret_cast<iBase_EntityHandle>(temp_entity);
05826   }
05827 
05828   if (NULL == *geom_entity2) {
05829     ERROR(iBase_FAILURE, "NULL returned from CGM copy.");
05830   }
05831   
05832   RETURN(iBase_SUCCESS);
05833 }
05834       
05835 ITAPS_API void
05836 iGeom_sweepEntAboutAxis( iGeom_Instance instance,
05837                          /*in*/ iBase_EntityHandle geom_entity,
05838                          /*in*/ const double angle,
05839                          /*in*/ const double axis_normal_x,
05840                          /*in*/ const double axis_normal_y,
05841                          /*in*/ const double axis_normal_z,
05842                          /*out*/ iBase_EntityHandle *geom_entity2,
05843                          int* err )
05844 {
05845   DLIList<RefEntity*> ents;
05846   RefEntity *this_ent = ENTITY_HANDLE(geom_entity);
05847   if (NULL == this_ent) {
05848     ERROR(iBase_FAILURE, "Can't get ref entity from specified entity.");
05849   }
05850   else if (this_ent->dimension() > 2) {
05851     ERROR(iBase_INVALID_ENTITY_TYPE, "Can't sweep 3-d entities.");
05852   }
05853 
05854   RefEntity *new_ent = gmt->copy_refentity(this_ent);
05855   ents.append(new_ent);
05856   
05857   CubitVector origin(0.0, 0.0, 0.0);
05858   CubitVector direction(axis_normal_x, axis_normal_y, axis_normal_z);
05859 
05860   double radian_angle = angle * DEG_TO_RAD;
05861   
05862   DLIList<Body*> new_bodies;
05863   CubitStatus result = gmt->sweep_rotational(ents, origin, direction,
05864                                              radian_angle, new_bodies,
05865                                              CUBIT_FALSE, CUBIT_FALSE);
05866   if (CUBIT_FAILURE == result) {
05867       // destroy entity we copied before
05868     gqt->delete_RefEntity(new_ent);
05869     ERROR(iBase_FAILURE, "Sweep returned failure.");
05870   }
05871   
05872   else {
05873       // HACK to get last entity created, because cgm doesn't return
05874       // body created by sweep
05875     RefEntity *new_body = new_bodies.get();
05876     *geom_entity2 = reinterpret_cast<iBase_EntityHandle>(new_body);
05877 
05878       // now we know it's succeeded, delete original body
05879     Body *this_body = dynamic_cast<TopologyEntity*>(this_ent)->body();
05880     if (NULL != this_body)
05881       gqt->delete_RefEntity(this_body);
05882     else
05883       gqt->delete_RefEntity(this_ent);
05884   }
05885 
05886 
05887   if (NULL == *geom_entity2) {
05888     RETURN(iBase_FAILURE);
05889   }
05890   
05891   RETURN(iBase_SUCCESS);
05892 }
05893 
05894 ITAPS_API void
05895 iGeom_deleteAll( iGeom_Instance,
05896                  int* err )
05897 {
05898   GeometryQueryTool::instance()->delete_geometry();
05899   *err = iBase_SUCCESS;
05900 }
05901 
05902 
05903 ITAPS_API void
05904 iGeom_deleteEnt( iGeom_Instance instance,
05905                  /*in*/ iBase_EntityHandle geom_entity,
05906                  int* err )
05907 {
05908   RefEntity *this_ent = ENTITY_HANDLE(geom_entity);
05909 
05910     // special case: if this is a volume, delete the body instead
05911   CubitStatus result;
05912   RefVolume *this_vol = CAST_TO(this_ent, RefVolume);
05913   if (NULL != this_vol)
05914     result = gqt->delete_Body(this_vol->body());
05915   else    
05916     result = gqt->delete_RefEntity(this_ent);
05917 
05918   if (CUBIT_FAILURE == result) {
05919     ERROR(iBase_FAILURE, "Problems deleting entity.");
05920   }
05921 
05922     // check to see if this was last thing deleted; if so, reset ids
05923   RefEntityFactory *rfi = RefEntityFactory::instance();
05924   if (rfi->num_bodies() == 0 && 
05925       rfi->num_ref_volumes() == 0 &&
05926       rfi->num_ref_faces() == 0 &&
05927       rfi->num_ref_edges() == 0 &&
05928       rfi->num_ref_vertices() == 0)
05929     rfi->reset_ids();
05930   
05931   RETURN(iBase_SUCCESS);
05932 }
05933 
05934 ITAPS_API void
05935 iGeom_createSphere( iGeom_Instance instance,
05936                     double radius,
05937                     iBase_EntityHandle *geom_entity,
05938                     int* err )
05939 {
05940   if (radius <= 0.0) {
05941     ERROR(iBase_INVALID_ARGUMENT, "Sphere radius must be must be positive.");
05942   }
05943   
05944   RefEntity* tmp_body = gmt->sphere( radius );
05945   *geom_entity = reinterpret_cast<iBase_EntityHandle>(tmp_body);
05946   RETURN ((tmp_body ? iBase_SUCCESS : iBase_FAILURE));
05947 }
05948 
05949 
05950 ITAPS_API void
05951 iGeom_createPrism( iGeom_Instance instance,
05952                    /*in*/ double height,
05953                    /*in*/ int n_sides,
05954                    /*in*/ double major_rad,
05955                    /*in*/ double minor_rad,
05956                    /*out*/ iBase_EntityHandle *geom_entity,
05957                    int* err )
05958 {
05959   if ( 0.0>=height ) {
05960     ERROR(iBase_INVALID_ARGUMENT, "Prism height must be positive.");
05961   } else if ( 3>n_sides ) {
05962     ERROR(iBase_INVALID_ARGUMENT, "Prism must have at least three sides.");
05963   }
05964   
05965   RefEntity* tmp_body = gmt->prism( height, n_sides, major_rad, minor_rad );
05966   *geom_entity = reinterpret_cast<iBase_EntityHandle>(tmp_body);
05967   RETURN ((tmp_body ? iBase_SUCCESS :iBase_FAILURE));
05968 }
05969 
05970 
05971 ITAPS_API void
05972 iGeom_createBrick( iGeom_Instance instance,
05973                    /*in*/ double x,
05974                    /*in*/ double y,
05975                    /*in*/ double z,
05976                    /*out*/ iBase_EntityHandle *geom_entity,
05977                    int* err )
05978 {
05979   double tmp_x = x;
05980   double tmp_y = y;
05981   double tmp_z = z;
05982   
05983   if (0.0 == y && 0.0 == z) {
05984     tmp_y = x;
05985     tmp_z = x;
05986   }
05987   
05988   if (0.0 >= tmp_x || 0.0 >= tmp_y || 0.0 >= tmp_z) {
05989     ERROR(iBase_INVALID_ARGUMENT, "Dimensions must be >= 0, or y & z must both be zero.");
05990   }
05991     
05992   RefEntity *temp_body = gmt->brick(tmp_x, tmp_y, tmp_z);
05993   *geom_entity = reinterpret_cast<iBase_EntityHandle>(temp_body);
05994 
05995   if (NULL == *geom_entity) {
05996     RETURN(iBase_FAILURE);
05997   }
05998 
05999   RETURN(iBase_SUCCESS);
06000 }
06001           
06002 ITAPS_API void
06003 iGeom_createCylinder( iGeom_Instance instance,
06004                       /*in*/ double height,
06005                       /*in*/ double major_rad,
06006                       /*in*/ double minor_rad,
06007                       /*out*/ iBase_EntityHandle *geom_entity,
06008                       int* err )
06009 {
06010   double tmp_minor = (0.0 == minor_rad ? major_rad : minor_rad);
06011   RefEntity *temp_body = 
06012     gmt->cylinder(height, major_rad, tmp_minor, major_rad);
06013   *geom_entity = reinterpret_cast<iBase_EntityHandle>(temp_body);
06014 
06015 
06016   if (NULL == *geom_entity) {
06017     RETURN(iBase_FAILURE);
06018   }
06019 
06020   RETURN(iBase_SUCCESS);
06021 }
06022       
06023 ITAPS_API void
06024 iGeom_createCone( iGeom_Instance instance,
06025                   /*in*/ double height,
06026                   /*in*/ double major_rad_base,
06027                   /*in*/ double minor_rad_base,
06028                   /*in*/ double rad_top,
06029                   /*out*/ iBase_EntityHandle *geom_entity,
06030                   int* err )
06031 {
06032   double tmp_minor = (0.0 == minor_rad_base ? major_rad_base : minor_rad_base);
06033   RefEntity *temp_body = 
06034     gmt->cylinder(height, major_rad_base, tmp_minor, rad_top);
06035   *geom_entity = reinterpret_cast<iBase_EntityHandle>(temp_body);
06036 
06037 
06038   if (NULL == *geom_entity) {
06039     RETURN(iBase_FAILURE);
06040   }
06041 
06042   RETURN(iBase_SUCCESS);
06043 }
06044     
06045 ITAPS_API void
06046 iGeom_createTorus( iGeom_Instance instance,
06047                    /*in*/ double major_rad,
06048                    /*in*/ double minor_rad,
06049                    /*out*/ iBase_EntityHandle *geom_entity,
06050                    int* err )
06051 {
06052   if (minor_rad >= major_rad) {
06053     ERROR(iBase_INVALID_ARGUMENT, "Major radius must be greater than minor radius for tori.");
06054   }
06055   
06056   RefEntity *temp_body = gmt->torus(major_rad, minor_rad);
06057   *geom_entity = reinterpret_cast<iBase_EntityHandle>(temp_body);
06058    
06059   if (NULL == *geom_entity) {
06060     RETURN(iBase_FAILURE);
06061   }
06062 
06063   RETURN(iBase_SUCCESS);
06064 }
06065 
06066 ITAPS_API void
06067 iGeom_moveEnt( iGeom_Instance instance,
06068                /*inout*/ iBase_EntityHandle geom_entity,
06069                /*in*/ double x,
06070                /*in*/ double y,
06071                /*in*/ double z,
06072                int* err )
06073 {
06074   CubitVector vec(x, y, z);
06075   Body *this_bod = dynamic_cast<Body*>(ENTITY_HANDLE(geom_entity));
06076   DLIList<Body*> bods;
06077   bods.append(this_bod);
06078   CubitStatus result;
06079   if (NULL != this_bod) {
06080     result = gqt->translate(bods, vec);
06081     if (CUBIT_SUCCESS != result) {
06082       ERROR(iBase_FAILURE, "Failed to move body.");
06083       RETURN(iBase_FAILURE);
06084     }
06085     
06086     RETURN(iBase_SUCCESS);
06087   }
06088   
06089   BasicTopologyEntity *this_bte = dynamic_cast<BasicTopologyEntity*>(ENTITY_HANDLE(geom_entity));
06090   if (NULL != this_bte) {
06091       // non-body move; check to see if there are any siblings to this entity in the
06092       // same body; if so, we can't move it; if not, get the body and move that; if
06093       // there is no body, it's a free entity and we can move it anyway
06094     Body *this_body = this_bte->body();
06095     if (NULL == this_body) {
06096       DLIList<BasicTopologyEntity*> btes;
06097       btes.append(this_bte);
06098       result = gqt->translate(btes, vec);
06099       if (CUBIT_SUCCESS != result) {
06100         ERROR(iBase_FAILURE, "Failed to move entity.");
06101       }
06102     }
06103     else {
06104       int num_sibs = -1;
06105       switch (this_bte->dimension()) {
06106         case 0: num_sibs = this_body->num_ref_vertices(); break;
06107         case 1: num_sibs = this_body->num_ref_edges(); break;
06108         case 2: num_sibs = this_body->num_ref_faces(); break;
06109       }
06110       if (num_sibs == 1) {
06111           // ok to move the body instead
06112         result = gqt->translate(bods, vec);
06113         if (CUBIT_SUCCESS != result) {
06114           ERROR(iBase_FAILURE, "Failed to move body even only one entity of that"
06115                              " dimension in the body.");
06116         }
06117       }
06118       else {
06119         ERROR(iBase_FAILURE, "Too many siblings for an entity to move it.");
06120       }
06121     }
06122 
06123     RETURN(iBase_SUCCESS);
06124   }
06125   
06126   ERROR(iBase_INVALID_ENTITY_TYPE, "Wrong type of entity specified for move.");
06127 }
06128       
06129 ITAPS_API void
06130 iGeom_rotateEnt( iGeom_Instance instance,
06131                  /*inout*/ iBase_EntityHandle geom_entity,
06132                  /*in*/ double angle,
06133                  /*in*/ double axis_normal_x,
06134                  /*in*/ double axis_normal_y,
06135                  /*in*/ double axis_normal_z,
06136                  int* err )
06137 {
06138   CubitVector this_axis(axis_normal_x, axis_normal_y, axis_normal_z);
06139   Body *this_bod = dynamic_cast<Body*>(ENTITY_HANDLE(geom_entity));
06140   DLIList<Body*> bods;
06141   bods.append(this_bod);
06142   CubitStatus result;
06143   if (NULL != this_bod) {
06144     result = gqt->rotate(bods, this_axis, angle);
06145     if (CUBIT_SUCCESS != result) {
06146       ERROR(iBase_FAILURE, "Failed to rotate body.");
06147     }
06148     
06149     RETURN(iBase_SUCCESS);
06150   }
06151   
06152   BasicTopologyEntity *this_bte = dynamic_cast<BasicTopologyEntity*>(ENTITY_HANDLE(geom_entity));
06153   if (NULL != this_bte) {
06154     DLIList<BasicTopologyEntity*> btes;
06155     btes.append(this_bte);
06156     result = gqt->rotate(btes, this_axis, angle);
06157     if (CUBIT_SUCCESS != result) {
06158       ERROR(iBase_FAILURE, "Failed to rotate entity.");
06159     }
06160     
06161     RETURN(iBase_SUCCESS);
06162   }
06163   
06164   ERROR(iBase_INVALID_ENTITY_TYPE, "Wrong type of entity specified for move.");
06165 }
06166 
06167 ITAPS_API void
06168 iGeom_reflectEnt( iGeom_Instance instance,
06169                   /*inout*/ iBase_EntityHandle geom_entity,
06170                   /*in*/ double point_x,
06171                   /*in*/ double point_y,
06172                   /*in*/ double point_z,
06173                   /*in*/ double plane_normal_x,
06174                   /*in*/ double plane_normal_y,
06175                   /*in*/ double plane_normal_z,
06176                   int* err )
06177 {
06178   CubitVector this_plane(plane_normal_x, plane_normal_y, plane_normal_z);
06179   CubitVector point(point_x, point_y, point_z);
06180   Body *this_bod = dynamic_cast<Body*>(ENTITY_HANDLE(geom_entity));
06181   DLIList<Body*> bods;
06182   bods.append(this_bod);
06183   CubitStatus result;
06184   if (NULL != this_bod) {
06185     result = gqt->reflect(bods, point , this_plane);
06186     if (CUBIT_SUCCESS != result) {
06187       ERROR(iBase_FAILURE, "Failed to reflect body.");
06188     }
06189     
06190     RETURN(iBase_SUCCESS);
06191   }
06192   
06193   BasicTopologyEntity *this_bte = dynamic_cast<BasicTopologyEntity*>(ENTITY_HANDLE(geom_entity));
06194   if (NULL != this_bte) {
06195     DLIList<BasicTopologyEntity*> btes;
06196     btes.append(this_bte);
06197     result = gqt->reflect(btes, point, this_plane);
06198     if (CUBIT_SUCCESS != result) {
06199       ERROR(iBase_FAILURE, "Failed to reflect entity.");
06200     }
06201     
06202     RETURN(iBase_SUCCESS);
06203   }
06204   
06205   ERROR(iBase_INVALID_ENTITY_TYPE, "Wrong type of entity specified for reflect.");
06206 }
06207 
06208 ITAPS_API void
06209 iGeom_scaleEnt( iGeom_Instance instance,
06210                 /*inout*/ iBase_EntityHandle geom_entity,
06211                 /*in*/ double point_x,
06212                 /*in*/ double point_y,
06213                 /*in*/ double point_z,
06214                 /*in*/ double scale_x,
06215                 /*in*/ double scale_y,
06216                 /*in*/ double scale_z,
06217                 int* err )
06218 {
06219   CubitVector factor(scale_x, scale_y, scale_z);
06220   CubitVector point(point_x, point_y, point_z);
06221   Body *this_bod = dynamic_cast<Body*>(ENTITY_HANDLE(geom_entity));
06222   CubitStatus result;
06223   if (NULL != this_bod) {
06224     result = gqt->scale(this_bod, point, factor);
06225     if (CUBIT_SUCCESS != result) {
06226       ERROR(iBase_FAILURE, "Failed to scale body.");
06227     }
06228     
06229     RETURN(iBase_SUCCESS);
06230   }
06231   
06232   BasicTopologyEntity *this_bte = dynamic_cast<BasicTopologyEntity*>(ENTITY_HANDLE(geom_entity));
06233     // non-body move; check to see if there are any siblings to this entity in the
06234     // same body; if so, we can't move it; if not, get the body and move that; if
06235     // there is no body, it's a free entity and we can move it anyway
06236   Body *this_body = this_bte->body();
06237   if (NULL == this_body && NULL != this_bte) {
06238     result = gqt->scale(this_bte, point, factor);
06239     if (CUBIT_SUCCESS != result) {
06240       ERROR(iBase_FAILURE, "Failed to scale entity.");
06241     }
06242   }
06243   else if (NULL != this_body && NULL != this_bte) {
06244     int num_sibs = -1;
06245     switch (this_bte->dimension()) {
06246       case 0: num_sibs = this_body->num_ref_vertices(); break;
06247       case 1: num_sibs = this_body->num_ref_edges(); break;
06248       case 2: num_sibs = this_body->num_ref_faces(); break;
06249           // for TSTT, always scale volumes
06250       case 3: num_sibs = 1; break;
06251     }
06252     if (num_sibs == 1) {
06253         // ok to scale the body instead
06254       result = gqt->scale(this_body, point, factor);
06255       if (CUBIT_SUCCESS != result) {
06256         ERROR(iBase_FAILURE, "Failed to scale body even only one entity of that"
06257                            " dimension in the body.");
06258       }
06259     }
06260     else {
06261       ERROR(iBase_FAILURE, "Too many siblings for an entity to scale it.");
06262     }
06263   }
06264 
06265   RETURN(iBase_SUCCESS);
06266 }
06267 
06268 ITAPS_API void
06269 iGeom_uniteEnts( iGeom_Instance instance,
06270                  /*in*/ iBase_EntityHandle const* geom_entities,
06271                  int geom_entities_size,
06272                  /*out*/ iBase_EntityHandle *geom_entity,
06273                  int* err )
06274 {
06275   DLIList<Body*> bods, orig_bods;
06276   RefEntity* const* handle_array = ENTITY_HANDLE_CONST_ARRAY(geom_entities);
06277   for (int i = 0; i < geom_entities_size; i++) {
06278     Body *this_body = dynamic_cast<Body*>(handle_array[i]);
06279     if (NULL != this_body) {
06280       Body *new_body = gmt->copy_body(this_body);
06281       if (NULL != new_body) {
06282         bods.append(this_body);
06283         orig_bods.append(new_body);
06284       }
06285     }
06286   }
06287   if (bods.size() < geom_entities_size) {
06288     ERROR(iBase_INVALID_ARGUMENT, "Not all entities input were regions.");
06289     for (int i = bods.size(); i > 0; i--)
06290       gqt->delete_RefEntity(bods.get_and_step());
06291     
06292     RETURN(iBase_SUCCESS);
06293   }
06294   
06295   DLIList<Body*> new_bods;
06296   CubitStatus result = gmt->unite(bods, new_bods, false);
06297   if (CUBIT_SUCCESS != result || 1 != new_bods.size()) {
06298     ERROR(iBase_FAILURE, "Unite failed.");
06299   }
06300     
06301   else {
06302     *geom_entity = reinterpret_cast<iBase_EntityHandle>(dynamic_cast<RefEntity*>(new_bods.get()));
06303     for (int i = orig_bods.size(); i > 0; i--)
06304       gqt->delete_RefEntity(orig_bods.get_and_step());
06305   }
06306 
06307   RETURN(iBase_SUCCESS);
06308 }
06309 
06310 ITAPS_API void
06311 iGeom_subtractEnts( iGeom_Instance instance,
06312                     /*in*/ iBase_EntityHandle blank,
06313                     /*in*/ iBase_EntityHandle tool,
06314                     /*out*/ iBase_EntityHandle *geom_entity,
06315                     int* err )
06316 {
06317   Body *this_blank = dynamic_cast<Body*>(ENTITY_HANDLE(blank));
06318   Body *blank_copy = gmt->copy_body(this_blank);
06319   if (NULL == blank_copy) {
06320     ERROR(iBase_FAILURE, "Trouble copying blank.");
06321   }
06322   Body *this_tool = dynamic_cast<Body*>(ENTITY_HANDLE(tool));
06323   Body *tool_copy = gmt->copy_body(this_tool);
06324   if (NULL == tool_copy) {
06325     ERROR(iBase_FAILURE, "Trouble copying tool.");
06326     gqt->delete_RefEntity(blank_copy);
06327     RETURN(iBase_FAILURE);
06328   }
06329 
06330   DLIList<Body*> blank_list, new_body_list;
06331   blank_list.append(blank_copy);
06332   
06333   RefEntity *new_body = NULL;
06334   CubitStatus result = gmt->subtract(tool_copy, blank_list, new_body_list);
06335   if (CUBIT_SUCCESS != result || 0 == new_body_list.size()) {
06336     ERROR(iBase_FAILURE, "Subtract failed.");
06337   }
06338   else {
06339     new_body = new_body_list.get();
06340     *geom_entity = reinterpret_cast<iBase_EntityHandle>(new_body);
06341     gqt->delete_RefEntity(this_blank);
06342     gqt->delete_RefEntity(this_tool);
06343   }
06344 
06345   RETURN(iBase_SUCCESS);
06346 }
06347 
06348 ITAPS_API void
06349 iGeom_intersectEnts( iGeom_Instance instance,
06350                      /*in*/ iBase_EntityHandle ent1,
06351                      /*in*/ iBase_EntityHandle ent2,
06352                      /*out*/ iBase_EntityHandle *geom_entity,
06353                      int* err )
06354 {
06355   Body *this_ent1 = dynamic_cast<Body*>(ENTITY_HANDLE(ent1));
06356   Body *ent1_copy = gmt->copy_body(this_ent1);
06357   if (NULL == ent1_copy) {
06358     ERROR(iBase_FAILURE, "Trouble copying blank.");
06359   }
06360   Body *this_ent2 = dynamic_cast<Body*>(ENTITY_HANDLE(ent2));
06361   Body *ent2_copy = gmt->copy_body(this_ent2);
06362   if (NULL == ent2_copy) {
06363     ERROR(iBase_FAILURE, "Trouble copying tool.");
06364     gqt->delete_RefEntity(ent1_copy);
06365     RETURN(iBase_FAILURE);
06366   }
06367 
06368   DLIList<Body*> ent1_list, new_body_list;
06369   ent1_list.append(ent1_copy);
06370   
06371   RefEntity *new_body = NULL;
06372   CubitStatus result = gmt->intersect(ent2_copy, ent1_list, new_body_list);
06373   if (CUBIT_SUCCESS != result || 0 == new_body_list.size()) {
06374     ERROR(iBase_FAILURE, "Intersect failed.");
06375   }
06376   else {
06377     new_body = new_body_list.get();
06378     *geom_entity = reinterpret_cast<iBase_EntityHandle>(new_body);
06379     gqt->delete_RefEntity(this_ent2);
06380     gqt->delete_RefEntity(this_ent1);
06381   }
06382 
06383   RETURN(iBase_SUCCESS);
06384 }
06385 
06386 ITAPS_API void
06387 iGeom_sectionEnt( iGeom_Instance instance,
06388                   /*inout*/ iBase_EntityHandle geom_entity,
06389                   /*in*/ double plane_normal_x,
06390                   /*in*/ double plane_normal_y,
06391                   /*in*/ double plane_normal_z,
06392                   /*in*/ double offset,
06393                   /*in*/ int reverse,
06394                   /*out*/ iBase_EntityHandle *geom_entity2,
06395                   int* err )
06396 {
06397   Body *this_body = dynamic_cast<Body*>(ENTITY_HANDLE(geom_entity));
06398   if (NULL == this_body) {
06399     RefVolume *this_vol = dynamic_cast<RefVolume*>(ENTITY_HANDLE(geom_entity));
06400     if (NULL != this_vol)
06401       this_body = this_vol->get_body_ptr();
06402   }
06403   if (NULL == this_body) {
06404     ERROR(iBase_INVALID_ARGUMENT, "Can only section bodies.");
06405   }
06406 
06407   CubitVector normal(plane_normal_x, plane_normal_y, plane_normal_z);
06408   if (normal.length_squared() == 0.0) {
06409     ERROR(iBase_INVALID_ARGUMENT, "Zero-length vector input.");
06410   }
06411   
06412   CubitVector point1 = normal * CubitVector(1.0, 0.0, 0.0);
06413   if (point1.length_squared() == 0.0)
06414     point1 = normal * CubitVector(0.0, 1.0, 0.0);
06415     
06416   CubitVector point2 = normal * point1;
06417   CubitVector point3(0.0, 0.0, 0.0);
06418 
06419   if (0.0 != offset) {
06420     normal.normalize();
06421     normal *= offset;
06422     point1 += normal;
06423     point2 += normal;
06424     point3 += normal;
06425   }
06426 
06427   
06428   DLIList<Body*> blank_list, new_body_list;
06429   blank_list.append(gmt->copy_body(this_body));
06430   CubitStatus result = gmt->section(blank_list, point1, point2, point3,
06431                                     new_body_list, !reverse,
06432                                     false);
06433   if (CUBIT_SUCCESS != result || 0 == new_body_list.size()) {
06434     gqt->delete_RefEntity(blank_list.get());
06435     ERROR(iBase_FAILURE, "Section failed.");
06436   }
06437     
06438   else {
06439       // need to assign it to a RE* first so the void cast gets done right
06440     RefEntity *new_body = new_body_list.get();
06441     *geom_entity2 = reinterpret_cast<iBase_EntityHandle>(new_body);
06442       // also, delete the original body, now that the section worked
06443     gqt->delete_RefEntity(this_body);
06444   }
06445 
06446   RETURN(iBase_SUCCESS);
06447 }
06448 
06449 ITAPS_API void
06450 iGeom_imprintEnts( iGeom_Instance instance,
06451                    /*in*/ iBase_EntityHandle const* gentity_handles,
06452                    int gentity_handles_size,
06453                    int* err )
06454 {
06455   if (gentity_handles_size < 1) // GMT::imprint segfaults if passed an empty list
06456     RETURN(iBase_SUCCESS);
06457 
06458   DLIList<Body*> bods;
06459   DLIList<RefVolume*> vols, temp_vols;
06460   RefEntity* const* handle_array = ENTITY_HANDLE_CONST_ARRAY(gentity_handles);
06461   CubitStatus status = CUBIT_SUCCESS;
06462   for (int i = 0; i < gentity_handles_size; i++) {
06463     Body *temp_bod = dynamic_cast<Body*>(handle_array[i]);
06464     if (NULL != temp_bod) {
06465       bods.append_unique(temp_bod);
06466       continue;
06467     }
06468     
06469     RefVolume *temp_vol = dynamic_cast<RefVolume*>(handle_array[i]);
06470     if (NULL != temp_vol) {
06471       TopologyEntity *topo_ent = dynamic_cast<TopologyEntity*>(handle_array[i]);
06472       if (NULL == topo_ent) {
06473         status = CUBIT_FAILURE;
06474         continue;
06475       }
06476       temp_bod = topo_ent->body();
06477       if (NULL == temp_bod) {
06478         status = CUBIT_FAILURE;
06479         continue;
06480       }
06481       bods.append_unique(temp_bod);
06482       continue;
06483     }
06484 
06485       // if we've gotten here, it's an error
06486     status = CUBIT_FAILURE;
06487   }
06488   
06489   if (CUBIT_SUCCESS != status) RETURN(iBase_FAILURE);
06490 
06491   DLIList<Body*> temp_bods;
06492   status = GeometryModifyTool::instance()->imprint(bods, temp_bods, false);
06493   
06494   RETURN(iBase_SUCCESS);
06495 }
06496   
06497 ITAPS_API void
06498 iGeom_mergeEnts( iGeom_Instance instance,
06499                  /*in*/ iBase_EntityHandle const* gentity_handles,
06500                  int gentity_handles_size,
06501                  double tolerance,
06502                  int* err )
06503 {
06504   double old_factor = GeometryQueryTool::instance()->get_geometry_factor();
06505   if (tolerance != old_factor) 
06506     GeometryQueryTool::instance()->set_geometry_factor(tolerance*1.0e6);
06507   else old_factor = 0.0;
06508   
06509   DLIList<Body*> bods;
06510   DLIList<RefVolume*> vols, temp_vols;
06511   DLIList<RefFace*> faces;
06512   DLIList<RefEdge*> edges;
06513   DLIList<RefVertex*> verts;
06514   RefEntity* const* handle_array = ENTITY_HANDLE_CONST_ARRAY(gentity_handles);
06515   for (int i = 0; i < gentity_handles_size; i++) {
06516     TopologyEntity *topo_ent = dynamic_cast<TopologyEntity*>(handle_array[i]);
06517     if (NULL == topo_ent) continue;
06518     Body *temp_bod;
06519     RefVolume *temp_vol;
06520     RefFace *temp_face;
06521     RefEdge *temp_edge;
06522     RefVertex *temp_vert;
06523     switch (handle_array[i]->dimension()) {
06524       case -1:
06525           // it should be a body
06526         temp_bod = dynamic_cast<Body*>(handle_array[i]);
06527         if (NULL == temp_bod) RETURN(iBase_FAILURE);
06528         temp_vols.clean_out();
06529         topo_ent->ref_volumes(temp_vols);
06530         vols += temp_vols;
06531         break;
06532       case 0:
06533         temp_vert = dynamic_cast<RefVertex*>(handle_array[i]);
06534         if (NULL == temp_vert) RETURN(iBase_FAILURE);
06535         verts.append(temp_vert);
06536         break;
06537       case 1:
06538         temp_edge = dynamic_cast<RefEdge*>(handle_array[i]);
06539         if (NULL == temp_edge) RETURN(iBase_FAILURE);
06540         edges.append(temp_edge);
06541         break;
06542       case 2:
06543         temp_face = dynamic_cast<RefFace*>(handle_array[i]);
06544         if (NULL == temp_face) RETURN(iBase_FAILURE);
06545         faces.append(temp_face);
06546         break;
06547       case 3:
06548         temp_vol = dynamic_cast<RefVolume*>(handle_array[i]);
06549         if (NULL == temp_vol) RETURN(iBase_FAILURE);
06550         vols.append(temp_vol);
06551         break;
06552     }
06553   }
06554   
06555   CubitStatus status = CUBIT_SUCCESS, temp_status;
06556     
06557   if (verts.size() != 0) {
06558     temp_status = MergeTool::instance()->merge_refvertices(verts, false);
06559     if (CUBIT_SUCCESS != temp_status) status = temp_status;
06560   }
06561     
06562   if (edges.size() != 0) {
06563     temp_status = MergeTool::instance()->merge_refedges(edges, true, false);
06564     if (CUBIT_SUCCESS != temp_status) status = temp_status;
06565   }
06566     
06567   if (faces.size() != 0) {
06568     temp_status = MergeTool::instance()->merge_reffaces(faces, false);
06569     if (CUBIT_SUCCESS != temp_status) status = temp_status;
06570   }
06571     
06572   if (vols.size() != 0) {
06573     temp_status = MergeTool::instance()->merge_volumes(vols, false);
06574     if (CUBIT_SUCCESS != temp_status) status = temp_status;
06575   }
06576     
06577   if (bods.size() != 0) {
06578     temp_status = MergeTool::instance()->merge_bodies(bods);
06579     if (CUBIT_SUCCESS != temp_status) status = temp_status;
06580   }
06581 
06582   if (0 != old_factor)
06583     GeometryQueryTool::instance()->set_geometry_factor(old_factor);
06584     
06585   if (CUBIT_SUCCESS != status) {
06586     RETURN(iBase_FAILURE);
06587   }
06588   
06589   else {
06590     RETURN(iBase_SUCCESS);
06591   }
06592 }
06593 
06594 ITAPS_API void
06595 iGeom_isPositionOn( iGeom_Instance instance,
06596                     iBase_EntityHandle entity,
06597                     double x,
06598                     double y,
06599                     double z,
06600                     int* IsOn )
06601 {
06602   CubitVector position(x,y,z);
06603   RefVertex* ref_v = dynamic_cast<RefVertex*>(ENTITY_HANDLE(entity));
06604   if(ref_v)
06605   {
06606     CubitVector v_loc = ref_v->coordinates();
06607     CubitBoolean test = v_loc.about_equal(position);
06608     if (test == CUBIT_TRUE)
06609       *IsOn = 1;
06610     else
06611       *IsOn = 0;
06612     return;
06613   }
06614 
06615   CubitPointContainment pc = CUBIT_PNT_UNKNOWN;
06616   RefFace *ref_face = dynamic_cast<RefFace*>(ENTITY_HANDLE(entity));
06617   if(ref_face)
06618     pc = ref_face->point_containment(position);
06619 
06620   RefEdge *ref_edge = dynamic_cast<RefEdge*>(ENTITY_HANDLE(entity));
06621   if(ref_edge)
06622     pc = ref_edge->point_containment(position);
06623 
06624   Body *body = dynamic_cast<Body*>(ENTITY_HANDLE(entity));
06625   if(body)
06626     pc = body->point_containment(position);
06627 
06628   if (pc == CUBIT_PNT_INSIDE || pc == CUBIT_PNT_BOUNDARY)
06629     *IsOn = 1;
06630 
06631   else
06632     *IsOn = 0;
06633   return;
06634 }
06635 
06636 } // extern "C"
06637 
06638 /********************* HELPER FUNCTION IMPLEMENTATIONS ***************************/
06639 
06640 static void tokenize( const std::string& str, 
06641                       std::vector<std::string>& tokens )
06642 {
06643   char delim =  str[0];
06644   std::string::size_type last = str.find_first_not_of( delim, 1 );
06645   std::string::size_type pos  = str.find_first_of( delim, last );
06646   while (std::string::npos != pos && std::string::npos != last) {
06647     tokens.push_back( str.substr( last, pos - last ) );
06648     last = str.find_first_not_of( delim, pos );
06649     pos  = str.find_first_of( delim, last ); 
06650   }
06651 }
06652 
06653 // Expect option of the form "NAME=VALUE".
06654 // If NAME portion matches, pass back VALUE and return true.
06655 // Otherwise, leave 'value' unchanged and return false.
06656 static bool match_option( const std::string& opt,
06657                           const char* name,
06658                           std::string& value )
06659 {
06660   std::string::size_type len = strlen( name );
06661   if (opt[len] != '=')
06662     return false;
06663   if (opt.compare( 0, len, name, len ))
06664     return false;
06665   value = opt.substr( len + 1 );
06666   return true;
06667 }
06668 
06669 
06670 static void
06671 iGeom_get_adjacent_entities( const RefEntity *from, 
06672                              const int to_dim,
06673                              DLIList<RefEntity*> &adj_ents,
06674                              int* err ) 
06675 {
06676   TopologyEntity *topo_ent = const_cast<TopologyEntity*>(dynamic_cast<const TopologyEntity*>(from));
06677   if (NULL == topo_ent) {
06678     ERROR(iBase_INVALID_ARGUMENT, "Bad entity input.");
06679   }
06680   
06681   adj_ents.clean_out();
06682   static DLIList<RefVertex*> tmp_verts;
06683   static DLIList<RefEdge*> tmp_edges;
06684   static DLIList<RefFace*> tmp_faces;
06685   static DLIList<Body*> tmp_bodies;
06686   
06687   switch (to_dim) {
06688     case 0:
06689       tmp_verts.clean_out();
06690       topo_ent->ref_vertices(tmp_verts);
06691       CAST_LIST_TO_PARENT(tmp_verts, adj_ents);
06692       break;
06693     case 1:
06694       tmp_edges.clean_out();
06695       topo_ent->ref_edges(tmp_edges);
06696       CAST_LIST_TO_PARENT(tmp_edges, adj_ents);
06697       break;
06698     case 2:
06699       tmp_faces.clean_out();
06700       topo_ent->ref_faces(tmp_faces);
06701       CAST_LIST_TO_PARENT(tmp_faces, adj_ents);
06702       break;
06703     case 3:
06704       tmp_bodies.clean_out();
06705       topo_ent->bodies(tmp_bodies);
06706       CAST_LIST_TO_PARENT(tmp_bodies, adj_ents);
06707       break;
06708     default:
06709       ERROR(iBase_INVALID_ARGUMENT, "Bad input dimension getting adjacent entities.");
06710   }
06711   
06712   RETURN(iBase_SUCCESS);
06713 }
06714 
06715 /* Common implementation for both single-entity and array functions. */
06716 static CubitStatus iGeom_closest_point( RefEntity* this_entity,
06717                                         const CubitVector& near,
06718                                         CubitVector& on )
06719 {
06720   RefEdge *this_edge;
06721   RefFace *this_face;
06722   Surface *this_surf;
06723   CubitStatus status;
06724  
06725   switch (this_entity->dimension()) {
06726     case 0:
06727       on = dynamic_cast<RefVertex*>(this_entity)->coordinates();
06728       status = CUBIT_SUCCESS;
06729       break;
06730     case 1:
06731       this_edge = dynamic_cast<RefEdge*>(this_entity);
06732       if (NULL == this_edge) return CUBIT_FAILURE;
06733 
06734       status = this_edge->closest_point(near, on);
06735 
06736       if (debug) {
06737         std::cout << "Edge " << this_edge->id() << " closest point to (" 
06738                   << near.x() << ", " << near.y() << ", " << near.z() 
06739                   << ") is "
06740                   << on.x() << ", " << on.y() << ", " << on.z() 
06741                   << ")" << std::endl;
06742       }
06743       break;
06744     case 2:
06745       this_face = dynamic_cast<RefFace*>(this_entity);
06746       if (NULL == this_face) return CUBIT_FAILURE;
06747       this_surf = this_face->get_surface_ptr();
06748       if (NULL == this_surf) return CUBIT_FAILURE;
06749       status = this_surf->closest_point( near, &on );
06750       break;
06751     default:
06752         // just copy over the coordinates
06753       on = near;
06754       status = CUBIT_SUCCESS;
06755       break;
06756   }
06757   
06758   return status;
06759 }
06760 
06761 static CubitStatus iGeom_closest_point_trimmed( RefEntity* this_entity,
06762                                                 const CubitVector& near,
06763                                                 CubitVector& on )
06764 {
06765   RefEdge *this_edge;
06766   RefFace *this_face;
06767   Surface *this_surf;
06768   CubitStatus status;
06769 
06770   switch (this_entity->dimension()) {
06771     case 0:
06772       on = dynamic_cast<RefVertex*>(this_entity)->coordinates();
06773       status = CUBIT_SUCCESS;
06774       break;
06775     case 1:
06776       this_edge = dynamic_cast<RefEdge*>(this_entity);
06777       if (NULL == this_edge) return CUBIT_FAILURE;
06778 
06779       status = this_edge->closest_point(near, on);
06780 
06781       if (debug) {
06782         std::cout << "Edge " << this_edge->id() << " closest point to ("
06783                   << near.x() << ", " << near.y() << ", " << near.z()
06784                   << ") is "
06785                   << on.x() << ", " << on.y() << ", " << on.z()
06786                   << ")" << std::endl;
06787       }
06788       break;
06789     case 2:
06790       this_face = dynamic_cast<RefFace*>(this_entity);
06791       if (NULL == this_face) return CUBIT_FAILURE;
06792       this_surf = this_face->get_surface_ptr();
06793       if (NULL == this_surf) return CUBIT_FAILURE;
06794       this_surf->closest_point_trimmed( near, on );
06795       status = CUBIT_SUCCESS;
06796       break;
06797     default:
06798         // just copy over the coordinates
06799       on = near;
06800       status = CUBIT_SUCCESS;
06801       break;
06802   }
06803 
06804   return status;
06805 }
06806 
06807 static CubitStatus
06808 iGeom_closest_point_and_normal( RefEntity* this_entity, 
06809                                 const CubitVector& near,
06810                                 CubitVector& on,
06811                                 CubitVector& normal )
06812 {
06813   RefEdge* this_edge;
06814   RefFace* this_face;
06815   Surface* this_surf;
06816   CubitStatus status;
06817   switch (this_entity->dimension()) {
06818     case 0:
06819       on = dynamic_cast<RefVertex*>(this_entity)->coordinates();
06820       normal.set( 0, 0, 0 );
06821       status = CUBIT_SUCCESS;
06822       break;
06823     case 1:
06824       this_edge = dynamic_cast<RefEdge*>(this_entity);
06825       if (NULL == this_edge) return CUBIT_FAILURE;
06826       
06827       status = this_edge->closest_point( near, on );
06828       if (debug) {
06829         std::cout << "Edge " << this_edge->id() << " closest point to (" 
06830                   << near.x() << ", " << near.y() << ", " << near.z() 
06831                   << ") is "
06832                   << on.x() << ", " << on.y() << ", " << on.x()
06833                   << ")" << std::endl;
06834       }
06835       break;
06836     case 2:
06837       this_face = dynamic_cast<RefFace*>(this_entity);
06838       if (NULL == this_face) return CUBIT_FAILURE;
06839       this_surf = this_face->get_surface_ptr();
06840       if (NULL == this_surf) return CUBIT_FAILURE;
06841       status = this_surf->closest_point( near, &on, &normal );
06842       if (this_surf->bridge_sense() == CUBIT_REVERSED)
06843         normal = -normal;
06844       break;
06845     default:
06846         // just copy over the coordinates
06847       on = near;
06848       normal.set( 0, 0, 0 );
06849       status = CUBIT_SUCCESS;
06850       break;
06851   }
06852   
06853   return status;
06854 }
06855 
06856 static CubitStatus
06857 iGeom_bounding_box( RefEntity* entity, CubitVector& minc, CubitVector& maxc )
06858 {
06859   CubitBox box;
06860   if (BasicTopologyEntity* bte = dynamic_cast<BasicTopologyEntity*>(entity))
06861     box = bte->bounding_box();
06862   else if(Body* body = dynamic_cast<Body*>(entity))
06863     box = body->bounding_box();
06864   else {
06865     CGM_iGeom_setLastError(iBase_INVALID_ENTITY_HANDLE, "Entities passed into gentityBoundingBox must be vertex, edge, face, or region."); 
06866     return CUBIT_FAILURE;
06867   }
06868   
06869   minc = box.minimum();
06870   maxc = box.maximum();
06871   return CUBIT_SUCCESS;
06872 }
06873 
06876 /*
06877 static inline void box_min_max( double dir,
06878                                 double min,
06879                                 double max,
06880                                 double pt,
06881                                 double& tmin,
06882                                 double& tmax )
06883 {
06884   if (dir == 0) {
06885     tmin = std::numeric_limits<double>::min();
06886     tmax = std::numeric_limits<double>::max();
06887   }
06888   else if (dir > 0.0) {
06889     tmin = (min - pt) / dir;
06890     tmax = (max - pt) / dir;
06891   }
06892   else {
06893     tmin = (max - pt) / dir;
06894     tmax = (min - pt) / dir;
06895   }
06896 }
06897 */
06898 
06899 /*
06900 static bool
06901 iBase_intersect_ray_box( const CubitBox& box,
06902                          const CubitVector& point,
06903                          const CubitVector& direction )
06904 {
06905   double txmin, txmax, tymin, tymax, tzmin, tzmax;
06906   box_min_max( direction.x(), box.minimum().x(), box.maximum().x(), point.x(), txmin, txmax );
06907   box_min_max( direction.y(), box.minimum().y(), box.maximum().y(), point.y(), tymin, tymax );
06908   if (txmin > tymax || tymin > txmax)
06909     return false;
06910   
06911   if (tymin > txmin)
06912     txmin = tymin;
06913   if (tymax < txmax)
06914     txmax = tymax;
06915   
06916   box_min_max( direction.z(), box.minimum().z(), box.maximum().z(), point.z(), tzmin, tzmax );
06917   if (txmin > txmax || tzmin > txmax)
06918     return false;
06919   
06920   return true;
06921 }
06922 */
06923 
06924 static CubitStatus
06925 iGeom_fire_ray( const CubitVector& point,
06926                 const CubitVector& direction,
06927                 DLIList<RefEntity*>& entities,
06928                 DLIList<double>& ray_params )
06929 {
06930   const double EPSILON = 0.0;
06931   CubitStatus s;
06932   CubitVector nc_point(point), nc_direction(direction);
06933   
06934     // get all free entities in model
06935   DLIList<RefEntity*> target_entities;
06936   s = GeometryQueryTool::instance()->get_free_ref_entities( target_entities );
06937   if (CUBIT_SUCCESS != s) return s;
06938   DLIList<Body*> bodies;
06939   GeometryQueryTool::instance()->bodies( bodies );
06940   CAST_LIST_TO_PARENT( bodies, target_entities );
06941     
06942     // do ray fire at list of free entities
06943   return GeometryQueryTool::instance()->
06944     fire_ray( nc_point, nc_direction, target_entities, ray_params, 0, EPSILON, &entities );
06945 }
06946 
06947 static RefEntity* point_classification( const CubitVector& pt, RefVertex* vtx )
06948 {
06949   return (pt - vtx->coordinates()).length_squared() > GEOMETRY_RESABS*GEOMETRY_RESABS ? 0 : vtx;
06950 }
06951 
06952 static RefEntity* point_classification( const CubitVector& pt, RefEdge* edge )
06953 {
06954   CubitVector closest;
06955   edge->closest_point_trimmed( pt, closest );
06956   if ((pt - closest).length_squared() > GEOMETRY_RESABS*GEOMETRY_RESABS)
06957     return 0;
06958   
06959   if (RefEntity* vtx = point_classification( pt, edge->start_vertex() ))
06960     return vtx;
06961   else if (RefEntity* vtx = point_classification( pt, edge->end_vertex() ))
06962     return vtx;
06963   else
06964     return edge;
06965 }
06966 
06967 static RefEntity* point_classification( const CubitVector& pt, RefFace* face )
06968 {
06969   CubitBox extents = face->bounding_box();
06970   if (extents.distance_squared(pt) > GEOMETRY_RESABS*GEOMETRY_RESABS)
06971     return 0;
06972   
06973   CubitVector closest;
06974   face->find_closest_point_trimmed( pt, closest );
06975   if ((pt - closest).length_squared() > GEOMETRY_RESABS*GEOMETRY_RESABS)
06976     return 0;
06977   
06978   DLIList<RefEdge*> edges;
06979   face->ref_edges( edges );
06980   edges.last();
06981   for (int i = 0; i < edges.size(); ++i)
06982     if (RefEntity* ent = point_classification( pt, edges.step_and_get() ))
06983       return ent;
06984   
06985   return face;
06986 }
06987 
06988 static RefEntity* point_classification( const CubitVector& pt, Body* body )
06989 {
06990   CubitVector nonconst_pt(pt);
06991   CubitPointContainment pc = body->point_containment( nonconst_pt );
06992   if (CUBIT_PNT_INSIDE == pc) 
06993     return body;
06994   else if (CUBIT_PNT_BOUNDARY != pc)
06995     return 0;
06996   
06997     // If we're here, then we're on the boundary.  
06998     // Find which boundary entity we're on.
06999   DLIList<RefFace*> faces;
07000   body->ref_faces( faces );
07001   faces.last();
07002   for (int i = 0; i < faces.size(); ++i)
07003     if (RefEntity* ent = point_classification( pt, faces.step_and_get() ))
07004       return ent;
07005   
07006     // We don't appear to be on any face.  Is the tolerance for
07007     // Body::point_classification something other than GEOMETRY_RESABS??
07008   return body;
07009 }
07010 
07011 
07012 
07013 static RefEntity*
07014 iGeom_get_point_containment( const CubitVector& pt )
07015 {
07016   DLIList<RefEntity*> ents;
07017   gqt->get_free_ref_entities( ents );
07018   
07019   ents.reset();
07020   for (int i = 0; i < ents.size(); ++i)
07021     if (RefVertex* vtx = dynamic_cast<RefVertex*>(ents.get_and_step()))
07022       if (RefEntity* ent = point_classification( pt, vtx ))
07023         return ent;
07024   for (int i = 0; i < ents.size(); ++i)
07025     if (RefEdge* edge = dynamic_cast<RefEdge*>(ents.get_and_step()))
07026       if (RefEntity* ent = point_classification( pt, edge ))
07027         return ent;
07028   for (int i = 0; i < ents.size(); ++i)
07029     if (RefFace* face = dynamic_cast<RefFace*>(ents.get_and_step()))
07030       if (RefEntity* ent = point_classification( pt, face ))
07031         return ent;
07032         
07033   DLIList<Body*> bodies;
07034   gqt->bodies( bodies );
07035   bodies.reset();
07036   for (int i = 0; i < bodies.size(); ++i)
07037    if (RefEntity* ent = point_classification( pt, bodies.get_and_step() ))
07038      return ent;
07039   
07040   return 0;
07041 }
07042 
07043 static int iGeom_get_nonmanifold_sense( const BasicTopologyEntity* child,
07044                                         const BasicTopologyEntity* parent,
07045                                         int* err )
07046 {
07047   DLIList<SenseEntity*> se_list(1);
07048   const_cast<BasicTopologyEntity*>(child)
07049     ->get_sense_entities( se_list, const_cast<BasicTopologyEntity*>(parent) );
07050   if (se_list.size() == 0) {
07051     CGM_iGeom_setLastError((*err = iBase_INVALID_ENTITY_HANDLE), "Relative senes of unrelated entities"); 
07052     return 2;
07053   }
07054   se_list.reset();
07055   CubitSense sense = se_list.get_and_step()->get_sense();
07056   for (int i = se_list.size() - 1; i > 0; --i)
07057     if (se_list.get_and_step()->get_sense() != sense) {
07058       *err = iBase_SUCCESS;
07059       return 0;
07060     }
07061   *err = iBase_SUCCESS;
07062   return sense == CUBIT_FORWARD ? 1 : -1;
07063 }
07064 
07065 static
07066 int iGeom_edge_vertex_sense( const RefEdge* cedge,
07067                              const RefVertex* vtx1,
07068                              const RefVertex* vtx2,
07069                              int* err )
07070 {
07071   RefEdge* edge = const_cast<RefEdge*>(cedge);
07072   if (edge->start_vertex() == vtx1 && edge->end_vertex() == vtx2) 
07073     return vtx1 == vtx2 ? 0 : 1;
07074   else if (edge->start_vertex() == vtx2 && edge->end_vertex() == vtx1)
07075     return -1;
07076   CGM_iGeom_setLastError((*err = iBase_INVALID_ENTITY_HANDLE), "Relative senes of unrelated entities"); 
07077   return 2;
07078 }
07079 
07080 static int iGeom_is_parametric( RefEntity* entity )
07081 {
07082   if (RefFace* face = dynamic_cast<RefFace*>(entity))
07083     return face->is_parametric();
07084   else if (dynamic_cast<RefEdge*>(entity))
07085     return true;
07086   else
07087     return false;
07088 }
07089 
07090 static iBase_ErrorType
07091 iGeom_get_vtx_to_u(RefVertex* vertex,
07092                    RefEdge* edge,
07093                    double& u)
07094 {
07095   if (edge->start_vertex() == vertex)
07096     u = edge->start_param();
07097   else if (edge->end_vertex() == vertex)
07098     u = edge->end_param();
07099   else
07100     return iBase_INVALID_ARGUMENT;
07101   return iBase_SUCCESS;
07102 }
07103 
07104 static iBase_ErrorType
07105 iGeom_get_vtx_to_uv(RefVertex* vertex, RefFace* face, double& u, double& v)
07106 {
07107   DLIList<RefVertex*> pts;
07108   TopologyEntity *topo_ent = dynamic_cast<TopologyEntity*>(face);
07109   topo_ent->ref_vertices(pts);
07110 
07111   pts.reset();
07112   for(int i=0; i<pts.size(); i++) {
07113     if (pts.get_and_step() == vertex) {
07114       face->u_v_from_position( vertex->coordinates(), u, v );         
07115       return iBase_SUCCESS;
07116     }
07117   }
07118   return iBase_INVALID_ARGUMENT;
07119 }
07120 
07121 static CubitStatus
07122 iGeom_normal_from_uv( RefFace* face, double u, double v, CubitVector& normal )
07123 {
07124   
07125   CubitVector coords = face->position_from_u_v( u, v );
07126   Surface* surf_ptr = face->get_surface_ptr();
07127   CubitStatus rval = surf_ptr->closest_point_uv_guess( coords, u, v, 0, &normal );
07128   if (surf_ptr->bridge_sense() == CUBIT_REVERSED)
07129     normal = -normal;
07130   return rval;
07131 }
07132 
07133 static CubitStatus
07134 iGeom_is_periodic( RefEntity* entity, int& u, int& v )
07135 {
07136   if (RefEdge* edge = dynamic_cast<RefEdge*>(entity)) {
07137     u = edge->is_periodic();
07138     v = CUBIT_FALSE;
07139   }
07140   else if (RefFace* face = dynamic_cast<RefFace*>(entity)) {
07141     double period;
07142     u = face->is_periodic_in_U(period);
07143     v = face->is_periodic_in_V(period);
07144   }
07145   else {
07146     u = v = CUBIT_FALSE;
07147   }
07148   
07149   return CUBIT_SUCCESS;
07150 }
07151 
07152 static bool
07153 iGeom_is_face_degenerate( RefFace* face )
07154 {
07155   double param = 0;
07156   CubitBoolean b1 = face->is_singular_in_U(param);
07157   CubitBoolean b2 = face->is_singular_in_V(param);
07158   return b1 || b2;
07159 }
07160 
07161 static iBase_ErrorType 
07162 process_attribs(iGeom_Instance instance, DLIList<RefEntity*> &ref_list) 
07163 {
07164     // go through all entities, checking for remaining simple attribs
07165   DLIList<CubitSimpleAttrib> csa_list;
07166   iBase_ErrorType result = iBase_SUCCESS;
07167 
07168   for (int i = ref_list.size(); i > 0; i--) {
07169     csa_list.clean_out();
07170 
07171       // get all the csa's still on this entity
07172     RefEntity *this_ent = ref_list.get_and_step();
07173     TopologyEntity *topo_ent = dynamic_cast<TopologyEntity*>(this_ent);
07174     topo_ent->bridge_manager()->topology_bridge()->get_simple_attribute(csa_list);
07175 
07176     for (int j = csa_list.size(); j > 0; j--) {
07177         // see if there's a tag for this csa already
07178       CubitSimpleAttrib csa = csa_list.get_and_step();
07179       const char *tag_name = csa.character_type().c_str();
07180       long tag = TM->getTagHandle(tag_name);
07181       if (tag < 0) continue;
07182       else if (0 == tag) {
07183           // don't have a tag handle for this yet - make one
07184         result = TM->create_csa_tag(tag_name, &tag);
07185         if (iBase_SUCCESS != result || 0 == tag) return iBase_FAILURE;
07186       }
07187         
07188         // now set the tag
07189       iBase_ErrorType tmp_result = TM->set_csa_tag(this_ent, tag, &csa);
07190       if (iBase_SUCCESS != tmp_result) result = tmp_result;
07191     }
07192   }
07193 
07194   return iBase_SUCCESS;
07195 }
07196 
07197 
07198 template <typename T> static inline 
07199 int count_type( const DLIList<CubitEntity*>& list )
07200 {
07201   int count = 0, size = list.size();
07202   for (int i = 0; i < size; ++i)
07203     if (dynamic_cast<T*>(list[i]))
07204       ++count;
07205   return count;
07206 }
07207 
07208 static inline
07209 int count_ibase_type( int ibase_type, const DLIList<CubitEntity*>& list, int* err )
07210 {
07211   *err = iBase_SUCCESS;
07212   switch (ibase_type) {
07213     case iBase_ALL_TYPES: return list.size() - count_type<RefGroup>(list);
07214     case iBase_REGION:    return count_type<Body>(list);
07215     case iBase_FACE:      return count_type<RefFace>(list);
07216     case iBase_EDGE:      return count_type<RefEdge>(list);
07217     case iBase_VERTEX:    return count_type<RefVertex>(list);
07218     default:
07219       *err = iBase_INVALID_ENTITY_TYPE;
07220       CGM_iGeom_setLastError( *err );
07221       return -1;
07222   }
07223 }
07224 
07225 template <typename TARGET_TYPE, typename LIST_TYPE> static inline 
07226 void append_type( const DLIList<CubitEntity*>& source_list,
07227                   DLIList<LIST_TYPE*>& target_list )
07228 {
07229   int size = source_list.size();
07230   for (int i = 0; i < size; ++i) 
07231     if (TARGET_TYPE* ent = dynamic_cast<TARGET_TYPE*>(source_list[i]))
07232       target_list.append(ent);
07233 }
07234 
07235 template <typename SKIP_TYPE, typename LIST_TYPE> static inline 
07236 void append_not_type( const DLIList<CubitEntity*>& source_list,
07237                       DLIList<LIST_TYPE*>& target_list )
07238 {
07239   int size = source_list.size();
07240   for (int i = 0; i < size; ++i) 
07241     if (!dynamic_cast<SKIP_TYPE*>(source_list[i]))
07242       if (RefEntity* ent = dynamic_cast<LIST_TYPE*>(source_list[i]))
07243         target_list.append(ent);
07244 }
07245 
07246 // Returns count of entities appended.
07247 template <typename TARGET_TYPE> static inline 
07248 int append_type( const DLIList<CubitEntity*>& source_list,
07249                  iBase_EntityHandle* array, int array_size )
07250 {
07251   RefEntity* re_ptr;
07252   int len = source_list.size();
07253   int count = 0;
07254   for (int i = 0; i < len; ++i) {
07255     if (TARGET_TYPE* ent = dynamic_cast<TARGET_TYPE*>(source_list[i])) {
07256       if (count < array_size)
07257         array[count] = reinterpret_cast<iBase_EntityHandle>(re_ptr = ent);
07258       ++count;
07259     }
07260   }
07261   return count;
07262 }
07263 
07264 template <typename SKIP_TYPE> static inline 
07265 int append_not_type( const DLIList<CubitEntity*>& source_list,
07266                      iBase_EntityHandle* array, int array_size )
07267 {
07268   int len = source_list.size();
07269   int count = 0;
07270   for (int i = 0; i < len; ++i) {
07271     if (!dynamic_cast<SKIP_TYPE*>(source_list[i])) {
07272       if (count == array_size) 
07273         return -1;
07274       else if (RefEntity* ent = dynamic_cast<RefEntity*>(source_list[i]))
07275         array[count++] = reinterpret_cast<iBase_EntityHandle>(ent);
07276     }
07277   }
07278   return count;
07279 }
07280 
07281 static 
07282 void copy_ibase_type( int ibase_type, 
07283                       const DLIList<CubitEntity*>& list,
07284                       iBase_EntityHandle** entity_handles,
07285                       int* entity_handles_alloc,
07286                       int* entity_handles_size,
07287                       int* err )
07288 {
07289   int count;
07290   if (*entity_handles_alloc == 0) {
07291     count = count_ibase_type( ibase_type, list, err );
07292     if (count < 0)
07293       return;
07294     *entity_handles = (iBase_EntityHandle*)malloc( count * sizeof(iBase_EntityHandle) );
07295     if (!*entity_handles) 
07296       RETURN(iBase_MEMORY_ALLOCATION_FAILED);
07297     *entity_handles_alloc = count;
07298   }
07299   
07300   switch (ibase_type) {
07301     case iBase_ALL_TYPES:
07302       count = append_not_type<RefGroup>(list,*entity_handles, *entity_handles_alloc);
07303       break;
07304     case iBase_REGION:
07305       count = append_type<Body>(list,*entity_handles, *entity_handles_alloc);
07306       break;
07307     case iBase_FACE:
07308       count = append_type<RefFace>(list,*entity_handles, *entity_handles_alloc);
07309       break;
07310     case iBase_EDGE:
07311       count = append_type<RefEdge>(list,*entity_handles, *entity_handles_alloc);
07312       break;
07313     case iBase_VERTEX:
07314       count = append_type<RefVertex>(list,*entity_handles, *entity_handles_alloc);
07315       break;
07316     default:
07317       RETURN(iBase_INVALID_ENTITY_TYPE);
07318       break;
07319   }
07320   
07321   *entity_handles_size = count;
07322   if (count > *entity_handles_alloc)
07323     RETURN(iBase_BAD_ARRAY_DIMENSION);
07324   
07325   RETURN(iBase_SUCCESS);
07326 }
07327 
07328 static 
07329 void append_ibase_type( int ibase_type, 
07330                         const DLIList<CubitEntity*>& source_list,
07331                         DLIList<RefEntity*>& target_list,
07332                         int* err )
07333 {
07334   switch (ibase_type) {
07335     case iBase_ALL_TYPES:
07336       append_not_type<RefGroup>(source_list, target_list);
07337       break;
07338     case iBase_REGION:
07339       append_type<Body>(source_list, target_list);
07340       break;
07341     case iBase_FACE:
07342       append_type<RefFace>(source_list, target_list);
07343       break;
07344     case iBase_EDGE:
07345       append_type<RefEdge>(source_list, target_list);
07346       break;
07347     case iBase_VERTEX:
07348       append_type<RefVertex>(source_list, target_list);
07349       break;
07350     default:
07351       RETURN(iBase_INVALID_ENTITY_TYPE);
07352       break;
07353   }
07354   
07355   RETURN(iBase_SUCCESS);
07356 }
07357 
07358 static 
07359 void append_all_ibase_type( int ibase_type, 
07360                             DLIList<RefEntity*>& target_list,
07361                             int* err )
07362 {
07363   RefEntityFactory *const ref = RefEntityFactory::instance();
07364   if (ibase_type == iBase_ALL_TYPES) {
07365     for (int i = 0; i < 4; ++i) {
07366       DLIList<RefEntity*> tmp;
07367       ref->ref_entity_list( iGeom_entity_type_names[i], tmp );
07368       target_list += tmp;
07369     }
07370   }
07371   else if (abs(ibase_type) < iBase_ALL_TYPES) {
07372     ref->ref_entity_list( iGeom_entity_type_names[ibase_type], target_list );
07373   }
07374   else {
07375     RETURN(iBase_INVALID_ENTITY_TYPE);
07376   }
07377   
07378   RETURN(iBase_SUCCESS);
07379 }
07380 
07381 void iGeom_getFacets(iGeom_Instance instance,
07382                      iBase_EntityHandle entity,
07383                      double dist_tolerance,
07384                      double **points, int *points_allocated, int *points_size,
07385                      int **facets, int *facets_allocated, int *facets_size,
07386                      int *err)
07387 {
07388   GMem gMem;
07389   CubitStatus resl = CUBIT_SUCCESS;
07390   RefFace *ref_face = dynamic_cast<RefFace*>(ENTITY_HANDLE(entity));
07391   if(ref_face)
07392     resl = ref_face->get_graphics(gMem, 15, dist_tolerance);
07393 
07394   RefEdge *ref_edge = dynamic_cast<RefEdge*>(ENTITY_HANDLE(entity));
07395   if(ref_edge)
07396     resl = ref_edge->get_graphics(gMem, 15, dist_tolerance);
07397 
07398   if(resl == CUBIT_FAILURE)
07399       ERROR(iBase_FAILURE, "Can't get facets for this entity.");
07400 
07401   if(ref_face || ref_edge)
07402   {
07403     int p_count = gMem.point_list_size(); 
07404     int f_count = gMem.facet_list_size();
07405     if(p_count)
07406     {
07407       ALLOC_CHECK_ARRAY_NOFAIL(points, p_count * 3);
07408       GPoint* gpoints = gMem.point_list();
07409       double *x, *y, *z;
07410       x = *points;
07411       y = x + 1;
07412       z = x + 2;
07413       size_t step = 3;
07414       for(int i = 0; i < p_count; i++)
07415       {
07416         GPoint pt = gpoints[i];       
07417         *x = pt.x;
07418         *y = pt.y;
07419         *z = pt.z;
07420         x += step;
07421         y += step;
07422         z += step; 
07423       } 
07424     }
07425     if(f_count)
07426     {
07427       //return all the triangles. Current gMem gives 4*triangle facets which
07428       //includes a '3' for each facet set to indicate there are 3 nodes on 
07429       //the tessilation. Here trying to ignore the '3'.
07430       ALLOC_CHECK_ARRAY_NOFAIL(facets, f_count*3/4);
07431       int *connectivity;
07432       connectivity = *facets;
07433       int* list = gMem.facet_list();
07434       for (int i = 0; i < f_count/4; i++)
07435       {
07436          *connectivity = list[i*4 + 1];
07437          *(connectivity + 1) = list[i*4 + 2];
07438          *(connectivity + 2) = list[i*4 + 3];
07439          connectivity += 3;
07440       }
07441     } 
07442     RETURN(iBase_SUCCESS); 
07443   }
07444   else
07445     RETURN(iBase_INVALID_ENTITY_TYPE);
07446 }
07447 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines