[brlcad-commits] SF.net SVN: brlcad: [31456] brlcad/trunk
Open Source Solid Modeling CAD
Brought to you by:
brlcad
From: <joh...@us...> - 2008-06-18 14:02:19
|
Revision: 31456 http://brlcad.svn.sourceforge.net/brlcad/?rev=31456&view=rev Author: johnranderson Date: 2008-06-18 07:02:26 -0700 (Wed, 18 Jun 2008) Log Message: ----------- Since MUVES3 was not using the asynchronous capabilities, simplified this library to eliminate pthreads, queues, and most of the locking. These changes were also suggested by Ron and Erik. Modified Paths: -------------- brlcad/trunk/include/RtServerImpl.h brlcad/trunk/include/rtserver.h brlcad/trunk/src/librtserver/rtserver.c brlcad/trunk/src/librtserver/rtserverTest.c Modified: brlcad/trunk/include/RtServerImpl.h =================================================================== --- brlcad/trunk/include/RtServerImpl.h 2008-06-18 12:43:45 UTC (rev 31455) +++ brlcad/trunk/include/RtServerImpl.h 2008-06-18 14:02:26 UTC (rev 31456) @@ -1,85 +1,77 @@ /* DO NOT EDIT THIS FILE - it is machine generated */ -/* Header for class mil_army_arl_services_RtService */ +/* Header for class mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper */ -#ifndef _Included_mil_army_arl_services_RtService -#define _Included_mil_army_arl_services_RtService - -__BEGIN_DECLS - -#undef mil_army_arl_services_RtService_minimumVersion -#define mil_army_arl_services_RtService_minimumVersion 14.1 +#ifndef _Included_mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper +#define _Included_mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper +#ifdef __cplusplus +extern "C" { +#endif +#undef mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper_minimumVersion +#define mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper_minimumVersion 14.1 /* - * Class: mil_army_arl_services_RtService + * Class: mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper * Method: rtsInit * Signature: ([Ljava/lang/String;)I */ -JNIEXPORT jint JNICALL Java_mil_army_arl_services_RtService_rtsInit -(JNIEnv *, jobject, jobjectArray); +JNIEXPORT jint JNICALL Java_mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper_rtsInit + (JNIEnv *, jobject, jobjectArray); /* - * Class: mil_army_arl_services_RtService + * Class: mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper * Method: getDbTitle * Signature: ()Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_mil_army_arl_services_RtService_getDbTitle -(JNIEnv *, jobject); +JNIEXPORT jstring JNICALL Java_mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper_getDbTitle + (JNIEnv *, jobject); /* - * Class: mil_army_arl_services_RtService + * Class: mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper * Method: getLibraryVersion * Signature: ()Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_mil_army_arl_services_RtService_getLibraryVersion -(JNIEnv *, jclass); +JNIEXPORT jstring JNICALL Java_mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper_getLibraryVersion + (JNIEnv *, jclass); /* - * Class: mil_army_arl_services_RtService + * Class: mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper * Method: openSession * Signature: ()I */ -JNIEXPORT jint JNICALL Java_mil_army_arl_services_RtService_openSession -(JNIEnv *, jobject); +JNIEXPORT jint JNICALL Java_mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper_openSession + (JNIEnv *, jobject); /* - * Class: mil_army_arl_services_RtService + * Class: mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper * Method: closeSession * Signature: (I)V */ -JNIEXPORT void JNICALL Java_mil_army_arl_services_RtService_closeSession -(JNIEnv *, jobject, jint); +JNIEXPORT void JNICALL Java_mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper_closeSession + (JNIEnv *, jobject, jint); /* - * Class: mil_army_arl_services_RtService - * Method: shutdownNative - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_mil_army_arl_services_RtService_shutdownNative -(JNIEnv *, jobject); - -/* - * Class: mil_army_arl_services_RtService + * Class: mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper * Method: shootRay - * Signature: (Lmil/army/arl/muves/math/Point;Lmil/army/arl/muves/math/Vector3;I)Lmil/army/arl/muves/rtserver/RayResult; + * Signature: (Lmil/army/arl/math/Point;Lmil/army/arl/math/Vector3;I)[B */ -JNIEXPORT jobject JNICALL Java_mil_army_arl_services_RtService_shootRay -(JNIEnv *, jobject, jobject, jobject, jint); +JNIEXPORT jbyteArray JNICALL Java_mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper_shootRay + (JNIEnv *, jobject, jobject, jobject, jint); /* - * Class: mil_army_arl_services_RtService + * Class: mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper * Method: shootArray - * Signature: (Lmil/army/arl/muves/math/Point;Lmil/army/arl/muves/math/Vector3;Lmil/army/arl/muves/math/Vector3;Lmil/army/arl/muves/math/Vector3;IIII)[Lmil/army/arl/muves/rtserver/RayResult; + * Signature: (Lmil/army/arl/math/Point;Lmil/army/arl/math/Vector3;Lmil/army/arl/math/Vector3;Lmil/army/arl/math/Vector3;IIII)[B */ -JNIEXPORT jobjectArray JNICALL Java_mil_army_arl_services_RtService_shootArray -(JNIEnv *, jobject, jobject, jobject, jobject, jobject, jint, jint, jint, jint); +JNIEXPORT jbyteArray JNICALL Java_mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper_shootArray + (JNIEnv *, jobject, jobject, jobject, jobject, jobject, jint, jint, jint, jint); /* - * Class: mil_army_arl_services_RtService + * Class: mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper * Method: getItemTree - * Signature: (I)Lmil/army/arl/muves/rtserver/ItemTree; + * Signature: (I)Lmil/army/arl/geometryservice/datatypes/ItemTree; */ -JNIEXPORT jobject JNICALL Java_mil_army_arl_services_RtService_getItemTree -(JNIEnv *, jobject, jint); +JNIEXPORT jobject JNICALL Java_mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper_getItemTree + (JNIEnv *, jobject, jint); /* * Class: mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper @@ -91,6 +83,14 @@ /* * Class: mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper + * Method: getBoundingBox + * Signature: (I)Lmil/army/arl/math/BoundingBox; + */ +JNIEXPORT jobject JNICALL Java_mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper_getBoundingBox + (JNIEnv *, jobject, jint); + +/* + * Class: mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper * Method: shootList * Signature: ([Lmil/army/arl/math/Ray;II)[B */ @@ -98,23 +98,14 @@ (JNIEnv *, jobject, jobjectArray, jint, jint); /* - * Class: mil_army_arl_services_RtService - * Method: getBoundingBox - * Signature: (I)Lmil/army/arl/muves/math/BoundingBox; + * Class: mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper + * Method: shutdownNative + * Signature: ()V */ -JNIEXPORT jobject JNICALL Java_mil_army_arl_services_RtService_getBoundingBox -(JNIEnv *, jobject, jint); +JNIEXPORT void JNICALL Java_mil_army_arl_brlcadservice_impl_BrlcadJNIWrapper_shutdownNative + (JNIEnv *, jobject); -__END_DECLS - +#ifdef __cplusplus +} #endif - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ +#endif Modified: brlcad/trunk/include/rtserver.h =================================================================== --- brlcad/trunk/include/rtserver.h 2008-06-18 12:43:45 UTC (rev 31455) +++ brlcad/trunk/include/rtserver.h 2008-06-18 14:02:26 UTC (rev 31456) @@ -25,31 +25,9 @@ * * @author: John R. Anderson * - * In order to use the rtserver, the BRL-CAD model must include an opaque binary object named "rtserver_data" - * This object must contain ASCII data consisting of lines of the form: - * assembly_name1 { object1 object2 object3 ...} key1 value1 key2 value2 ... - * Where assembly names are names of assemblies to be used for raytracing or articulation and - * the list of objects for each assembly specifies the BRL-CAD objects in that assembly. The - * assembly names do not need to be names of objects that already exist in the BRL-CAD model. - * At least one assembly named "rtserver_tops" must exist (this will be used for raytracing when - * no articulation is to be done. Each assembly must appear on its own line and must have at least - * one object in its list of objects. If the assembly name has embedded spaces, it must be surrounded - * by "{" and "}". Each line is a series of key/value pairs with the first key being the assembly name. - * optional keys are: - * key_pt - value is the center of rotation for this assembly - * xrotate - values are the rotation limits (max min initial) about the x-axis (degrees). Default is no rotation allowed - * yrotate - values are the rotation limits (max min initial) about the y-axis (degrees). Default is no rotation allowed - * zrotate - values are the rotation limits (max min initial) about the z-axis (degrees). Default is no rotation allowed - * xtranslate - values are the limits (max min) of translation along the x-axis (mm). Default is no translation allowed. - * ytranslate - values are the limits (max min) of translation along the y-axis (mm). Default is no translation allowed. - * ztranslate - values are the limits (max min) of translation along the z-axis (mm). Default is no translation allowed. - * children - values are other assemblies that are rigidly attached to this assembly (The children will move - * with their parent). - * - * An empty value for the translation keys implies unlimited translation is allowed. - * */ +/* Attempt to handle different sizes of the TCL ClientData on differing acjitectures */ #if SIZEOF_VOID_P == SIZEOF_INT typedef int CLIENTDATA_INT; #elif SIZEOF_VOID_P == SIZEOF_LONG @@ -60,88 +38,22 @@ #define CLIENTDATA_INT "ERROR: could not determine size of void*"; #endif -struct rtserver_job { - struct bu_list l; /* for linking */ - int exit_flag; /* flag, non-zero means the running thread should exit */ - int sessionid; /* index into sessions (rts_geometry array) */ - int rtjob_id; /* identifying number, assigned by the rt server */ - int maxHits; /* Max number of hits to consider along each ray (zero means take all of them) */ - int useByteArray; /* flag, non-zero means create byte array version of the results */ - struct bu_ptbl rtjob_rays; /* list of pointers to rays to be fired */ -}; -struct ray_hit { - struct bu_list l; - struct region *regp; /* pointer to containing region */ - int comp_id; /* index into component list */ - fastf_t hit_dist; /* distance along ray to hit point */ - fastf_t los; /* line of sight distance through this component */ - vect_t enter_normal; /* normal vector at entrance hit */ - vect_t exit_normal; /* normal vector at exit hit */ -}; - -struct ray_result { - struct bu_list l; - struct xray the_ray; /* the originating ray */ - struct ray_hit hitHead; /* the list of components hit along this ray */ - struct bu_vlb *vlb; /* pointer to the byte array in the owning rtserver_result */ -}; - -struct rtserver_result { - struct bu_list l; /* for linked list */ - int got_some_hits; /* flag 0-> no hits in results */ - struct rtserver_job *the_job; /* the originating job */ - struct ray_result resultHead; /* the list of results, one for each ray */ - struct bu_vlb *vlb; /* variable length byte array to contain the byte array - * return for Java (null if rtserver_job->useByteArray == 0) */ -}; - -struct rtserver_rti { - struct rt_i *rtrti_rtip; /* pointer to an rti structure */ - char *rtrti_name; /* name of this "assembly" (bu_malloc'd storage) */ - int rtrti_num_trees; /* number of trees in this rti structure */ - char **rtrti_trees; /* array of pointers to tree-top names trees[num_trees] (bu_malloc'd storage) */ - matp_t rtrti_xform; /* transformation matrix from global coords to this rt instance (NULL -> identity) */ - matp_t rtrti_inv_xform; /* inverse of above xform (NULL -> identity) */ - Tcl_HashTable *rtrti_region_names; /* A Tcl hash table containing region names as keys and index numbers as values. - * The indices are used to reference region names in the Java return byte array - * rather than using the full name. */ - int region_count; /* number of entries in above hash table */ -}; - -struct rtserver_geometry { - int rts_number_of_rtis; /* number of rtserver_rti structures */ - struct rtserver_rti **rts_rtis; /* array of pointers to rtserver_rti - structures rts_rtis[rts_number_of_rtis] (bu_malloc'd storage ) */ - point_t rts_mdl_min; /* min corner of model bounding RPP */ - point_t rts_mdl_max; /* max corner of model bounding RPP */ - double rts_radius; /* radius of model bounding sphere */ - Tcl_HashTable *rts_comp_names; /* A Tcl hash table containing ident numbers as keys - and component names as values */ -}; - -/* MACRO to add a ray to a job */ -#define RTS_ADD_RAY_TO_JOB( _ajob, _aray ) bu_ptbl_ins( &(_ajob)->rtjob_rays, (long *)(_aray) ) - -extern int get_max_working_threads(); - -extern struct rtserver_job *rts_get_rtserver_job(); - -extern struct rtserver_result *rts_get_any_waiting_result( int sessionid ); - -extern struct rtserver_result *rts_submit_job_and_wait( struct rtserver_job *ajob ); - -extern struct rtserver_result *rts_submit_job_to_queue_and_wait( struct rtserver_job *ajob, int queue_count ); - -extern struct xray *rts_get_xray(); - +extern void getApplication(struct application **ap); +extern void freeApplication(struct application *ap); extern void get_model_extents( int sessionid, point_t min, point_t max ); - -extern void rts_free_rtserver_job( struct rtserver_job *job ); - -extern void rts_free_xray( struct xray *ray ); - extern void rts_set_verbosity( int v ); +extern int rts_hit(struct application *ap, struct partition *partHeadp, struct seg *segs); +extern int rts_miss(struct application *ap); +extern void getApplication(struct application **ap); +extern void freeApplication(struct application *ap); +extern void rts_set_verbosity( int v ); +extern void rts_close_session( int sessionid ); +extern int rts_open_session(); +extern int rts_load_geometry( char *filename, int num_trees, char **objects ); +extern void printHits(struct bu_vlb *vlb); +extern void get_model_extents( int sessionid, point_t min, point_t max ); +extern void rts_shootray( struct application *ap ); /** @} */ /* Modified: brlcad/trunk/src/librtserver/rtserver.c =================================================================== --- brlcad/trunk/src/librtserver/rtserver.c 2008-06-18 12:43:45 UTC (rev 31455) +++ brlcad/trunk/src/librtserver/rtserver.c 2008-06-18 14:02:26 UTC (rev 31456) @@ -42,99 +42,90 @@ #elif defined(HAVE_JNI_H) # include <jni.h> #else -# error ERROR: jni.h could not be found +# include "ERROR: jni.h could not be found" #endif #include "RtServerImpl.h" -#if TESTING -#include <sys/time.h> -#include <time.h> -#endif +/* private structures not used outside this file */ +struct rtserver_rti { + struct rt_i *rtrti_rtip; /* pointer to an rti structure */ + char *rtrti_name; /* name of this "assembly" (bu_malloc'd storage) */ + int rtrti_num_trees; /* number of trees in this rti structure */ + char **rtrti_trees; /* array of pointers to tree-top names trees[num_trees] (bu_malloc'd storage) */ + matp_t rtrti_xform; /* transformation matrix from global coords to this rt instance (NULL -> identity) */ + matp_t rtrti_inv_xform; /* inverse of above xform (NULL -> identity) */ + Tcl_HashTable *rtrti_region_names; /* A Tcl hash table containing region names as keys and index numbers as values. + * The indices are used to reference region names in the Java return byte array + * rather than using the full name. */ + int region_count; /* number of entries in above hash table */ +}; +struct rtserver_geometry { + int rts_number_of_rtis; /* number of rtserver_rti structures */ + struct rtserver_rti **rts_rtis; /* array of pointers to rtserver_rti + structures rts_rtis[rts_number_of_rtis] (bu_malloc'd storage ) */ + point_t rts_mdl_min; /* min corner of model bounding RPP */ + point_t rts_mdl_max; /* max corner of model bounding RPP */ + double rts_radius; /* radius of model bounding sphere */ + Tcl_HashTable *rts_comp_names; /* A Tcl hash table containing ident numbers as keys + and component names as values */ +}; -/* number of cpus (only used for call to rt_prep_parallel) */ -static int ncpus=1; +static struct bu_ptbl apps; /* dynamic table of application structures, each incoming connection gets its own private struct */ -/* verbosity flag */ -static int verbose=0; +static int app_count = 0; /* number of application structures created so far */ -/* number of threads */ -static int num_threads=0; +static struct rt_i *myrtip = NULL; /* rt_i pointer for the geometry */ -/* the threads */ -static pthread_t *threads=NULL; +/* mutex to protect the list of application structures */ +static pthread_mutex_t apps_mutex = PTHREAD_MUTEX_INITIALIZER; -/* Job ID numbers */ -static int jobIds=0; +#define GET_APPLICATION(_p) { \ + pthread_mutex_lock( &apps_mutex ); \ + if ( BU_PTBL_LEN(&apps) ) { \ + _p = (struct application *)BU_PTBL_GET( &apps, BU_PTBL_LEN( &apps )-1 );\ + bu_ptbl_trunc( &apps, BU_PTBL_LEN( &apps )-1 );\ + pthread_mutex_unlock( &apps_mutex ); \ + bu_vlb_reset(_p->a_uptr); \ + } else { \ + int app_no = app_count++; \ + pthread_mutex_unlock( &apps_mutex ); \ + _p = (struct application *)bu_malloc( sizeof(struct application), "apps"); \ + RT_APPLICATION_INIT(_p); \ + _p->a_rt_i = myrtip; \ + _p->a_uptr = (struct bu_vlb *)bu_calloc( sizeof(struct bu_vlb), 1, "bu_vlb"); \ + bu_vlb_init(_p->a_uptr); \ + _p->a_resource = (struct resource *)bu_calloc( sizeof(struct resource), 1, "resource"); \ + rt_init_resource( _p->a_resource, app_no, _p->a_rt_i ); \ + _p->a_hit = rts_hit; \ + _p->a_miss = rts_miss; \ + _p->a_logoverlap = rt_silent_logoverlap; \ + } \ +} -/* mutex to protect the jobIds */ -static pthread_mutex_t jobid_mutex = PTHREAD_MUTEX_INITIALIZER; +#define FINISH_APPLICATION(_p) { \ + pthread_mutex_lock( &apps_mutex ); \ + bu_ptbl_ins( &apps, (long *)(_p) ); \ + pthread_mutex_unlock( &apps_mutex ); \ + _p = (struct application *)NULL; \ +} -/* mutex to protect the resources */ -static pthread_mutex_t resource_mutex = PTHREAD_MUTEX_INITIALIZER; -/* mutex to protect session opening and closing */ -static pthread_mutex_t session_mutex = PTHREAD_MUTEX_INITIALIZER; +/* the title of this BRL-CAD database */ +static char *title=NULL; -/* mutexes to protect the input and output queues */ -static pthread_mutex_t *output_queue_mutex=NULL; +/* use air flag (0 -> ignore air regions) */ +static int use_air=0; -/* input queues condition and mutex */ -static pthread_mutex_t input_queue_ready_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t input_queue_ready = PTHREAD_COND_INITIALIZER; +/* verbosity flag */ +static int verbose=0; -/* output queues condition and mutex */ -static pthread_mutex_t output_queue_ready_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t output_queue_ready = PTHREAD_COND_INITIALIZER; - -/* the queues */ -static struct rtserver_job *input_queue=NULL; -static struct rtserver_result *output_queue=NULL; -static int num_queues=0; - -/* resources for librtserver */ -struct rts_resources { - struct bu_list rtserver_results; - struct bu_list ray_results; - struct bu_list ray_hits; - struct bu_list rtserver_jobs; - struct bu_ptbl xrays; -}; - -static int rtserver_results_count=0; -static int ray_results_count=0; -static int ray_hits_count=0; -static int rtserver_jobs_count=0; -static int xrays_count=0; - -static struct rts_resources rts_resource; - -/* From here down should be combined into a single structure to - * allow more than one RtServer in the same JAVA VM. - * The sessionId would then be a packed number containing two - * indices, one for the usual sessionID and the other is an index - * into these new structures - */ - /* total number of MUVES component names */ static CLIENTDATA_INT comp_count=0; -/* use air flag (0 -> ignore air regions) */ -static int use_air=0; - -/* attribute name for MUVES components */ -/* static char *muves_comp="MUVES_Comp"; */ - /* array of MUVES component names */ static char **names; -/* hash tables for MUVES components */ -static int hash_table_exists=0; -static Tcl_HashTable name_tbl; /* all the MUVES component names (key is the MUVES component name, - value = MUVES id number */ -static Tcl_HashTable ident_tbl; /* all the non-air regions (key = ident, value = MUVES id number) */ -static Tcl_HashTable air_tbl; /* all the air regions (key = aircode, value = MUVES id number) */ - /* the geometry */ static struct rtserver_geometry **rts_geometry=NULL; /* array of rtserver_geometry structures * indexed by session id @@ -143,329 +134,146 @@ */ static int num_geometries=0; /* the length of the rts_geometry array */ static int used_session_0=0; /* flag indicating if initial session has been used */ -static int needs_initialization=1; /* flag indicating if init has already been done */ -/* the title of this BRL-CAD database */ -static char *title=NULL; +/* hash tables for MUVES components */ +static int hash_table_exists=0; +static Tcl_HashTable name_tbl; /* all the MUVES component names (key is the MUVES component name, + value = MUVES id number */ +#if 0 +static Tcl_HashTable ident_tbl; /* all the non-air regions (key = ident, value = MUVES id number) */ +static Tcl_HashTable air_tbl; /* all the air regions (key = aircode, value = MUVES id number) */ +#endif +/* wrapper for the GET_APPLICATION macro */ void -fillItemTree( jobject parent_node, - struct db_i *dbip, - JNIEnv *env, - char *name, - jclass itemTree_class, - jmethodID itemTree_constructor_id, - jmethodID itemTree_addcomponent_id, - jmethodID itemTree_setMuvesName_id, - jmethodID itemTree_setMaterialName_id, - jmethodID itemTree_setIdentNumber_id, - jmethodID itemTree_setLos_id, - jmethodID itemTree_setUseCount_id ); - -#define GEOMETRIES_BLOCK_SIZE 5 /* the number of slots to allocate at one time */ - -/* MACROS for getting and releasing resources */ -#define RTS_GET_XRAY( _p ) \ - pthread_mutex_lock( &resource_mutex ); \ - if ( BU_PTBL_LEN( &rts_resource.xrays ) ) { \ - _p = (struct xray *)BU_PTBL_GET( &rts_resource.xrays, BU_PTBL_LEN( &rts_resource.xrays )-1 );\ - bu_ptbl_trunc( &rts_resource.xrays, BU_PTBL_LEN( &rts_resource.xrays )-1 );\ - pthread_mutex_unlock( &resource_mutex ); \ - memset((_p), 0, sizeof( struct xray )); \ - } else { \ - xrays_count++; \ - pthread_mutex_unlock( &resource_mutex ); \ - _p = (struct xray *)bu_calloc( 1, sizeof( struct xray ), "xray" ); \ - } \ - (_p)->magic = RT_RAY_MAGIC; - -#define RTS_FREE_XRAY( _p ) \ - pthread_mutex_lock( &resource_mutex ); \ - bu_ptbl_ins( &rts_resource.xrays, (long *)(_p) ); \ - pthread_mutex_unlock( &resource_mutex ); \ - _p = (struct xray *)NULL; - -#define RTS_GET_RTSERVER_JOB( _p ) \ - pthread_mutex_lock( &resource_mutex ); \ - if ( BU_LIST_NON_EMPTY( &rts_resource.rtserver_jobs ) ) { \ - _p = BU_LIST_FIRST( rtserver_job, &rts_resource.rtserver_jobs ); \ - BU_LIST_DEQUEUE( &(_p)->l ); \ - pthread_mutex_unlock( &resource_mutex ); \ - memset((_p), 0, sizeof( struct rtserver_job )); \ - } else { \ - rtserver_jobs_count++; \ - pthread_mutex_unlock( &resource_mutex ); \ - _p = (struct rtserver_job *)bu_calloc( 1, sizeof( struct rtserver_job ), "rtserver_job" ); \ - } \ - BU_LIST_INIT( &(_p)->l ); \ - bu_ptbl_init( &(_p)->rtjob_rays, 128, "rtjob_rays list" ); - -#define RTS_FREE_RTSERVER_JOB( _p ) \ - { \ - int _i; \ - if ( (_p)->l.forw != NULL && BU_LIST_NON_EMPTY( &((_p)->l) ) ) { \ - BU_LIST_DEQUEUE( &((_p)->l) ); \ - } \ - for ( _i=0; _i<BU_PTBL_LEN( &(_p)->rtjob_rays); _i++ ) { \ - struct xray *_xray; \ - _xray = (struct xray *)BU_PTBL_GET( &(_p)->rtjob_rays, _i ); \ - RTS_FREE_XRAY( _xray ); \ - } \ - bu_ptbl_free( &(_p)->rtjob_rays ); \ - pthread_mutex_lock( &resource_mutex ); \ - BU_LIST_INSERT( &rts_resource.rtserver_jobs, &((_p)->l) ); \ - pthread_mutex_unlock( &resource_mutex ); \ - _p = (struct rtserver_job *)NULL; \ - } - -#define RTS_GET_RAY_HIT( _p ) \ - pthread_mutex_lock( &resource_mutex ); \ - if ( BU_LIST_NON_EMPTY( &rts_resource.ray_hits ) ) { \ - _p = BU_LIST_FIRST( ray_hit, &rts_resource.ray_hits ); \ - BU_LIST_DEQUEUE( &(_p)->l ); \ - pthread_mutex_unlock( &resource_mutex ); \ - memset((_p), 0, sizeof( struct ray_hit )); \ - BU_LIST_INIT( &(_p)->l ); \ - } else { \ - ray_hits_count++; \ - pthread_mutex_unlock( &resource_mutex ); \ - _p = (struct ray_hit *)bu_calloc( 1, sizeof( struct ray_hit ), "ray_hit" ); \ - BU_LIST_INIT( &(_p)->l );\ - } - -#define RTS_FREE_RAY_HIT( _p ) \ - if ( (_p)->l.forw != NULL && BU_LIST_NON_EMPTY( &(_p)->l ) ) {\ - BU_LIST_DEQUEUE( &(_p)->l ); \ - } \ - pthread_mutex_lock( &resource_mutex ); \ - BU_LIST_APPEND( &rts_resource.ray_hits, &(_p)->l ); \ - pthread_mutex_unlock( &resource_mutex ); \ - _p = (struct ray_hit *)NULL; - -#define RTS_FREE_RAY_RESULT( _p ) \ - { \ - struct ray_hit *_rhp; \ - while ( BU_LIST_WHILE( _rhp, ray_hit, &(_p)->hitHead.l ) ) { \ - RTS_FREE_RAY_HIT( _rhp ); \ - } \ - if ( (_p)->l.forw != NULL && BU_LIST_NON_EMPTY( &((_p)->l) ) ) {\ - BU_LIST_DEQUEUE( &((_p)->l) ); \ - } \ - pthread_mutex_lock( &resource_mutex ); \ - BU_LIST_INSERT( &rts_resource.ray_results, &((_p)->l) ); \ - pthread_mutex_unlock( &resource_mutex ); \ - _p = (struct ray_result *)NULL; \ - } - -#define RTS_GET_RAY_RESULT( _p ) \ - pthread_mutex_lock( &resource_mutex ); \ - if ( BU_LIST_NON_EMPTY( &rts_resource.ray_results ) ) { \ - _p = BU_LIST_FIRST( ray_result, &rts_resource.ray_results ); \ - BU_LIST_DEQUEUE( &(_p)->l ); \ - pthread_mutex_unlock( &resource_mutex ); \ - memset((_p), 0, sizeof( struct ray_result )); \ - } else { \ - ray_results_count++; \ - pthread_mutex_unlock( &resource_mutex ); \ - _p = (struct ray_result *)bu_calloc( 1, sizeof( struct ray_result ), "ray_result" ); \ - } \ - BU_LIST_INIT( &((_p)->l) );\ - BU_LIST_INIT( &(_p)->hitHead.l ); - - -#define RTS_GET_RTSERVER_RESULT( _p ) \ - pthread_mutex_lock( &resource_mutex ); \ - if ( BU_LIST_NON_EMPTY( &rts_resource.rtserver_results ) ) { \ - _p = BU_LIST_FIRST( rtserver_result, &rts_resource.rtserver_results ); \ - BU_LIST_DEQUEUE( &(_p)->l ); \ - pthread_mutex_unlock( &resource_mutex ); \ - memset((_p), 0, sizeof( struct rtserver_result )); \ - } else { \ - rtserver_results_count++; \ - pthread_mutex_unlock( &resource_mutex ); \ - _p = (struct rtserver_result *)bu_calloc( 1, sizeof( struct rtserver_result ), "rtserver_result" ); \ - } \ - BU_LIST_INIT( &(_p)->l ); \ - BU_LIST_INIT( &(_p)->resultHead.l ); - -#define RTS_FREE_RTSERVER_RESULT( _p ) \ - { \ - struct ray_result *_rrp; \ - while ( BU_LIST_WHILE( _rrp, ray_result, &(_p)->resultHead.l ) ) { \ - RTS_FREE_RAY_RESULT( _rrp ); \ - } \ - if ( (_p)->the_job ) { \ - RTS_FREE_RTSERVER_JOB( (_p)->the_job ); \ - (_p)->the_job = NULL; \ - } \ - if ( (_p)->l.forw != NULL && BU_LIST_NON_EMPTY( &((_p)->l) ) ) { \ - BU_LIST_DEQUEUE( &((_p)->l) ); \ - } \ - if(_p->vlb != NULL) { \ - bu_vlb_free(_p->vlb); \ - bu_free(_p->vlb, "bu_vlb"); \ - _p->vlb = NULL; \ - } \ - pthread_mutex_lock( &resource_mutex ); \ - BU_LIST_INSERT( &rts_resource.rtserver_results, &((_p)->l) ); \ - pthread_mutex_unlock( &resource_mutex ); \ - } - - -int -get_unique_jobid() +getApplication(struct application **ap) { - int aJobId; - - pthread_mutex_lock( &jobid_mutex ); - aJobId = ++jobIds; - if ( aJobId < 0 ) { - jobIds = 0; - aJobId = ++jobIds; - } - pthread_mutex_unlock( &jobid_mutex ); - - return aJobId; + GET_APPLICATION((*ap)); } - -struct rtserver_job * -rts_get_rtserver_job() +/* wrapper for the FINISH_APPLICATION macro */ +void +freeApplication(struct application *ap) { - struct rtserver_job *ajob; - - RTS_GET_RTSERVER_JOB( ajob ); - - return ajob; + FINISH_APPLICATION(ap); } -struct xray * -rts_get_xray() -{ - struct xray *aray; - - RTS_GET_XRAY( aray ); - - return aray; -} - +/* Routine to create a hash table of all the MUVES component names that appear in this BRL-CAD model + * + * MUVES components are identified by an attribute named "MUVES_Comp", and its value is the MUVES + * component name. Ray trace results will employ indices into this list rather than using the name strings + * themselves. Note that index 0 will be used to indicate an object with no MUVES name. + */ void -rts_free_rtserver_result( struct rtserver_result *result ) +get_muves_components() { - RTS_FREE_RTSERVER_RESULT( result ); -} + Tcl_HashEntry *name_entry, *ident_entry, *air_entry; + Tcl_HashSearch search; + int i, j; + int sessionid; -/* count the number of members in a bu_list structure */ -int -count_list_members( struct bu_list *listhead ) -{ - int count=0; - struct bu_list *l; - for ( BU_LIST_FOR( l, bu_list, listhead ) ) { - count++; + /* make sure we have some geometry */ + if ( !rts_geometry ) { + return; } - return( count ); -} + for ( sessionid=0; sessionid<num_geometries; sessionid++ ) { + if ( rts_geometry[sessionid] ) { + break; + } + } + if ( !rts_geometry[sessionid] ) { + return; + } -/* initialize the librtserver resources */ -void -rts_resource_init() -{ - pthread_mutex_lock( &resource_mutex ); \ - BU_LIST_INIT( &rts_resource.rtserver_results ); - BU_LIST_INIT( &rts_resource.ray_results ); - BU_LIST_INIT( &rts_resource.ray_hits ); - BU_LIST_INIT( &rts_resource.rtserver_jobs ); - bu_ptbl_init( &rts_resource.xrays, 128, "xrays" ); - pthread_mutex_unlock( &resource_mutex ); \ - } + /* initialize the hash tables */ + Tcl_InitHashTable( &name_tbl, TCL_STRING_KEYS ); /* MUVES Component name to index table */ +#if 0 + Tcl_InitHashTable( &ident_tbl, TCL_ONE_WORD_KEYS ); /* ident to MUVES_Component index table */ + Tcl_InitHashTable( &air_tbl, TCL_ONE_WORD_KEYS ); /* aircode to MUVES_Componnet index table */ +#endif + hash_table_exists = 1; + /* visit each rt_i */ + for ( i=0; i<rts_geometry[sessionid]->rts_number_of_rtis; i++ ) { + struct rtserver_rti *rts_rtip=rts_geometry[sessionid]->rts_rtis[i]; + struct rt_i *rtip=rts_rtip->rtrti_rtip; -/* print a summary of librt resources */ -void -rts_pr_resource_summary() -{ - fprintf( stderr, "Resource Summary:\n" ); + /* visit each region in this rt_i */ + for ( j=0; j<rtip->nregions; j++ ) { + struct region *rp=rtip->Regions[j]; + struct bu_mro *attrs=rp->attr_values[0]; + int new; + CLIENTDATA_INT index=0; + CLIENTDATA_INT code; - pthread_mutex_lock( &resource_mutex ); \ - fprintf( stderr, "\t %d rtserver_job structures\n", - count_list_members( &rts_resource.rtserver_jobs ) ); - fprintf( stderr, "\t %d rtserver_result structures\n", - count_list_members( &rts_resource.rtserver_results ) ); - fprintf( stderr, "\t %d ray_result structures\n", - count_list_members( &rts_resource.ray_results ) ); - fprintf( stderr, "\t %d ray_hit structures\n", - count_list_members( &rts_resource.ray_hits ) ); - fprintf( stderr, "\t %d xray structures\n", - BU_PTBL_LEN( &rts_resource.xrays ) ); - pthread_mutex_unlock( &resource_mutex ); \ - } + if ( !rp || BU_MRO_STRLEN(attrs) < 1 ) { + /* not a region, or does not have a MUVES_Component attribute */ + continue; + } + /* create an entry for this MUVES_Component name */ + name_entry = Tcl_CreateHashEntry( &name_tbl, BU_MRO_GETSTRING( attrs ), &new ); + if ( verbose ) { + fprintf( stderr, "region %s, name = %s\n", + rp->reg_name, BU_MRO_GETSTRING( attrs ) ); + } + /* set value to next index */ + if ( new ) { + comp_count++; + Tcl_SetHashValue( name_entry, (ClientData)comp_count ); + index = comp_count; + } else { + index = (CLIENTDATA_INT)Tcl_GetHashValue( name_entry ); + } +#if 0 + if ( rp->reg_aircode > 0 ) { + /* this is an air region, create an air table entry */ + code = rp->reg_aircode; + air_entry = Tcl_CreateHashEntry( &air_tbl, (ClientData)code, &new ); + if ( new ) { + Tcl_SetHashValue( air_entry, (ClientData)index ); + } + } else { + /* this is a solid region, create an ident table entry */ + code = rp->reg_regionid; + ident_entry = Tcl_CreateHashEntry( &ident_tbl, (ClientData)code, &new ); + if ( new ) { + Tcl_SetHashValue( ident_entry, (ClientData)index ); + } + } +#endif + } + } -/* create a new copy of the rtserver_geometry (typically for a new session) - * based on an existing session (usually zero) - */ -void -copy_geometry( int dest, int src ) -{ - int i, j; + /* create an array of MUVES_Component names. + * this can be returned to a client + */ + comp_count++; + names = (char **)bu_calloc( comp_count + 1, sizeof( char *), "MUVES names" ); + names[0] = bu_strdup( "No MUVES Name" ); + name_entry = Tcl_FirstHashEntry( &name_tbl, &search ); + while ( name_entry ) { + char *name; + CLIENTDATA_INT index; - /* allocate some memory */ - rts_geometry[dest] = (struct rtserver_geometry *)bu_calloc( 1, - sizeof( struct rtserver_geometry ), - "rts_geometry[]" ); + name = Tcl_GetHashKey( &name_tbl, name_entry ); + index = (CLIENTDATA_INT)Tcl_GetHashValue( name_entry ); + names[index] = bu_strdup( name ); - /* allocate memory for the rtserver_rti structures */ - rts_geometry[dest]->rts_number_of_rtis = - rts_geometry[src]->rts_number_of_rtis; - rts_geometry[dest]->rts_rtis = - (struct rtserver_rti **)bu_calloc( rts_geometry[dest]->rts_number_of_rtis, - sizeof( struct rtserver_rti *), - "rtserver_rti *" ); - /* initialize our overall bounding box */ - VSETALL( rts_geometry[dest]->rts_mdl_min, MAX_FASTF ); - VREVERSE( rts_geometry[dest]->rts_mdl_max, rts_geometry[dest]->rts_mdl_min ); - - /* fill out each rtsserver_rti structure */ - for ( i=0; i < rts_geometry[dest]->rts_number_of_rtis; i++ ) { - struct rt_i *rtip; - - /* the allocation call initializes the xform pointers to NULL */ - rts_geometry[dest]->rts_rtis[i] = (struct rtserver_rti *)bu_calloc( 1, - sizeof( struct rtserver_rti ), - "rtserver_rti" ); - - /* copy the rt_i pointer (the same ones are used by all the sessions */ - rtip = rts_geometry[src]->rts_rtis[i]->rtrti_rtip; - rts_geometry[dest]->rts_rtis[i]->rtrti_rtip = rtip; - if ( rts_geometry[src]->rts_rtis[i]->rtrti_name ) { - rts_geometry[dest]->rts_rtis[i]->rtrti_name = - bu_strdup( rts_geometry[src]->rts_rtis[i]->rtrti_name ); - } - rts_geometry[dest]->rts_rtis[i]->rtrti_num_trees = - rts_geometry[src]->rts_rtis[i]->rtrti_num_trees; - rts_geometry[dest]->rts_rtis[i]->rtrti_trees = - (char **) bu_calloc( rts_geometry[dest]->rts_rtis[i]->rtrti_num_trees, - sizeof( char *), - "rtrti_trees" ); - for ( j=0; j<rts_geometry[dest]->rts_rtis[i]->rtrti_num_trees; j++ ) { - rts_geometry[dest]->rts_rtis[i]->rtrti_trees[j] = - bu_strdup( rts_geometry[src]->rts_rtis[i]->rtrti_trees[j] ); - } - - /* update our overall bounding box */ - VMINMAX( rts_geometry[dest]->rts_mdl_min, rts_geometry[dest]->rts_mdl_max, rtip->mdl_min ); - VMINMAX( rts_geometry[dest]->rts_mdl_min, rts_geometry[dest]->rts_mdl_max, rtip->mdl_max ); + name_entry = Tcl_NextHashEntry( &search ); } +} - - /* hash table of component names is shared */ - rts_geometry[dest]->rts_comp_names = - rts_geometry[src]->rts_comp_names; +/* set the verbosity level for this library (currently, only zero or non-zero is supported */ +void rts_set_verbosity( int v ) +{ + verbose = v; } + +/* check if the specified rt_i pointer is the last use of this rt_i */ int isLastUseOfRti( struct rt_i *rtip, int sessionid ) { @@ -542,154 +350,37 @@ } } -/* routine to initialize anything that needs initializing */ +/* routine to close a session + * session id 0 is just marked as closed, but not freed + * any other session is deleted + */ void -rts_init() +rts_close_session( int sessionid ) { - if ( !needs_initialization ) { - return; - } - /* Things like bu_malloc() must have these initialized for use with parallel processing */ - bu_semaphore_init( RT_SEM_LAST ); + /* does nothing for now */ +} - output_queue_mutex = NULL; - input_queue = NULL; - output_queue = NULL; - num_queues = 0; - threads = NULL; - num_threads = 0; - /* initialize the rtserver resources (cached structures) */ - rts_resource_init(); - - needs_initialization = 0; -} - -/* routine to create a new sesion id +/* routine to create a new session id * - * Uses sessionid 0 if no sessions have been requesdted yet - * Otherwise, make a copy of the session + * Uses sessionid 0 for everyone so far */ int rts_open_session() { - int i; - - pthread_mutex_lock( &session_mutex ); /* make sure we have some geometry */ if ( num_geometries == 0 || rts_geometry[0] == NULL ) { fprintf( stderr, "rtServer: ERROR: no geometry loaded!!\n" ); - pthread_mutex_unlock( &session_mutex ); return -1; } /* for now, just return the same session to everyone */ used_session_0 = 1; - pthread_mutex_unlock( &session_mutex ); return 0; - -#if 0 - /* Better session management is needed. When a session is opened it needs to be - * to be associated with an analysis and a run. subsequent open session requests - * should then return the appropriate session bases on a passed in analysis id and run number - */ - - /* if the initial session is not yet used, just return it */ - if ( !used_session_0 ) { - used_session_0 = 1; - pthread_mutex_unlock( &session_mutex ); - return 0; - } - - /* create a new session by making a new copy of session #0 */ - /* look for an empty slot */ - for ( i=1; i<num_geometries; i++ ) { - if ( !rts_geometry[i] ) { - break; - } - } - - if ( i >= num_geometries ) { - /* need more slots */ - num_geometries += GEOMETRIES_BLOCK_SIZE; - rts_geometry = (struct rtserver_geometry **)bu_realloc( rts_geometry, - num_geometries * sizeof( struct rtserver_geometry **), - "realloc rtserver_geometry" ); - } - - /* copy into slot #i from session 0 */ - copy_geometry( i, 0 ); - - pthread_mutex_unlock( &session_mutex ); - - return( i ); -#endif } - -/* routine to set all the xforms to NULL for the given session id */ -void -reset_xforms( int sessionid ) -{ - int i; - - for ( i=0; i<rts_geometry[sessionid]->rts_number_of_rtis; i++ ) { - struct rtserver_rti *rts_rtip = rts_geometry[sessionid]->rts_rtis[i]; - - if ( rts_rtip->rtrti_xform ) { - bu_free( (char *)rts_rtip->rtrti_xform, "xform" ); - rts_rtip->rtrti_xform = NULL; - } - if ( rts_rtip->rtrti_inv_xform ) { - bu_free( (char *)rts_rtip->rtrti_inv_xform, "inv_xform" ); - rts_rtip->rtrti_inv_xform = NULL; - } - } -} - - -/* routine to close a session - * session id 0 is just marked as closed, but not freed - * any other session is deleted - */ -void -rts_close_session( int sessionid ) -{ - int i, j; - - pthread_mutex_lock( &session_mutex ); - if ( sessionid == 0 ) { - /* never eliminate sessionid 0 */ - used_session_0 = 0; - - /* reset any xforms */ - reset_xforms( sessionid ); - - pthread_mutex_unlock( &session_mutex ); - return; - } - if ( sessionid >= num_geometries ) { - /* no such session */ - pthread_mutex_unlock( &session_mutex ); - return; - } - if ( !rts_geometry[sessionid] ) { - /* this session has already been closed (or never opened) */ - pthread_mutex_unlock( &session_mutex ); - return; - } - - /* free the xforms */ - reset_xforms( sessionid ); - - rts_clean( sessionid ); - - pthread_mutex_unlock( &session_mutex ); -} - - /* routine to load geometry from a BRL-CAD model * * Uses "rtserver_data" object in the BRL-CAD model to find object names (see rtserver.h) @@ -701,16 +392,14 @@ * negative number - we have a problem */ int -rts_load_geometry( char *filename, int use_articulation, int num_objs, char **objects, int thread_count ) +rts_load_geometry( char *filename, int num_trees, char **objects ) { struct rt_i *rtip; struct db_i *dbip; - Tcl_Interp *interp; - Tcl_Obj *rtserver_data; int i, j; - int sessionid; + int sessionid=0; const char *attrs[] = {(const char *)"muves_comp", (const char *)NULL }; - + /* clean up any prior geometry data */ if ( rts_geometry ) { struct db_i *dbip; @@ -725,11 +414,15 @@ bu_free( (char *)rts_geometry, "rts_geometry" ); rts_geometry = NULL; } + + bu_ptbl_init( &apps, 8, "application structure list" ); if ( hash_table_exists ) { Tcl_DeleteHashTable( &name_tbl ); +#if 0 Tcl_DeleteHashTable( &ident_tbl); Tcl_DeleteHashTable( &air_tbl ); +#endif hash_table_exists = 0; } @@ -748,6 +441,7 @@ bu_log( "rt_dirbuild() failed for file %s\n", filename ); return -1; } + myrtip = rtip; /* grab the DB instance pointer (just for convenience) */ dbip = rtip->rti_dbip; @@ -757,180 +451,41 @@ /* set the use air flags */ rtip->useair = use_air; + - if ( use_articulation && objects ) { - fprintf( stderr, "Cannot use articulation when specifiying object names on the comand line for rtserver\n" ); - return -2; - } else if ( objects ) { - int num_trees; + /* load the specified objects */ + /* malloc some memory for the rtserver geometry structure (bu_calloc zeros the memory) */ + rts_geometry[sessionid] = (struct rtserver_geometry *)bu_calloc( 1, + sizeof( struct rtserver_geometry ), + "rtserver geometry" ); - /* load the specified objects */ - /* malloc some memory for the rtserver geometry structure (bu_calloc zeros the memory) */ - rts_geometry[sessionid] = (struct rtserver_geometry *)bu_calloc( 1, - sizeof( struct rtserver_geometry ), - "rtserver geometry" ); - - /* just one RT instance */ - rts_geometry[sessionid]->rts_number_of_rtis = 1; - rts_geometry[sessionid]->rts_rtis = (struct rtserver_rti **)bu_malloc( sizeof( struct rtserver_rti *), - "rtserver_rti" ); - rts_geometry[sessionid]->rts_rtis[0] = (struct rtserver_rti *)bu_calloc( 1, - sizeof( struct rtserver_rti ), - "rtserver_rti" ); - rts_geometry[sessionid]->rts_rtis[0]->rtrti_rtip = rtip; - num_trees = num_objs; - rts_geometry[sessionid]->rts_rtis[0]->rtrti_num_trees = num_trees; - if ( verbose ) { - fprintf( stderr, "num_trees = %d\n", num_trees ); - } - - /* malloc some memory for pointers to the object names */ - if ( num_trees > 0 ) { - rts_geometry[sessionid]->rts_rtis[0]->rtrti_trees = (char **)bu_calloc( num_trees, - sizeof( char *), - "rtrti_trees" ); - - for ( i=0; i<num_trees; i++ ) { - rts_geometry[sessionid]->rts_rtis[0]->rtrti_trees[i] = bu_strdup( objects[i] ); - } - } - } else if ( use_articulation ) { - /* XXX get articulation data */ - } else { - /* user just wants a single RT instance, with no articulation */ - struct directory *dp; - struct rt_db_internal intern; - struct rt_binunif_internal *bip; - int index1, index2; - int id; - int data_len; - - /* find the "rtserver_data" binary object */ - dp = db_lookup( dbip, "rtserver_data", LOOKUP_QUIET ); - if ( dp == DIR_NULL ) { - /* not found, cannot continue */ - return -2; - } - - /* fetch the "rtserver_data" object */ - if ( (id=rt_db_get_internal( &intern, dp, dbip, NULL, &rt_uniresource )) != ID_BINUNIF ) { - /* either we did not get the object, or it is not a binary object */ - return -3; - } - - /* malloc some memory for the rtserver geometry structure (bu_calloc zeros the memory) */ - rts_geometry[sessionid] = (struct rtserver_geometry *)bu_calloc( 1, - sizeof( struct rtserver_geometry ), - "rtserver geometry" ); - - /* just one RT instance */ - rts_geometry[sessionid]->rts_number_of_rtis = 1; - rts_geometry[sessionid]->rts_rtis = (struct rtserver_rti **)bu_malloc( sizeof( struct rtserver_rti *), - "rtserver_rti" ); - rts_geometry[sessionid]->rts_rtis[0] = (struct rtserver_rti *)bu_calloc( 1, - sizeof( struct rtserver_rti ), - "rtserver_rti" ); - rts_geometry[sessionid]->rts_rtis[0]->rtrti_rtip = rtip; - - /* use Tcl to interpret the rtserver_data */ - interp = Tcl_CreateInterp(); - - /* get the internal form of the binary object from the above fetch */ - bip = (struct rt_binunif_internal *)intern.idb_ptr; - - /* make a list object to hold the rtserver data, one line per list element */ - rtserver_data = Tcl_NewObj(); - index1 = 0; - index2 = index1; - - /* step through the rtserver_data buffer, appending each line as an element */ - while ( index2 < bip->count ) { - Tcl_Obj *tmp; - int length; - - /* find end of line */ - while ( index2 < bip->count && - bip->u.int8[index2] != '\n' && - bip->u.int8[index2] != '\0' ) { - index2++; - } - length = index2 - index1; - if ( length > 0 ) { - /* make a new object and append it to the list */ - tmp = Tcl_NewStringObj( &bip->u.int8[index1], index2 - index1 ); - Tcl_ListObjAppendElement( interp, rtserver_data, tmp ); - } - index2++; - index1 = index2; - } - - /* free the binary object */ - rt_db_free_internal( &intern, &rt_uniresource ); - - /* get the number of lines in the final object */ - Tcl_ListObjLength( interp, rtserver_data, &data_len ); - - /* look for top level object (check each line in the list) */ - for ( i=0; i<data_len; i++ ) { - Tcl_Obj *aline; - Tcl_Obj *key; - int found=0; - - /* get the next line from the list */ - Tcl_ListObjIndex( interp, rtserver_data, i, &aline ); - - /* get the first element from this line */ - Tcl_ListObjIndex( interp, aline, 0, &key ); - - /* is this the "rtserver_tops" key?? */ - if ( !strcmp( "rtserver_tops", Tcl_GetStringFromObj( key, NULL ) ) ) { - /* found top level object */ - Tcl_Obj *value; - int num_trees=0; - - /* get the value for this key (the next list element) */ - Tcl_ListObjIndex( interp, aline, 1, &value ); - - /* how long is the valu list (number of top level object) */ - Tcl_ListObjLength( interp, value, &num_trees ); - - /* save this number in the rts_geometry structure */ - rts_geometry[sessionid]->rts_rtis[0]->rtrti_num_trees = num_trees; - if ( verbose ) { - fprintf( stderr, "num_trees = %d\n", num_trees ); - } - - if ( num_trees > 0 ) { - /* malloc some memory for pointers to the object names */ - rts_geometry[sessionid]->rts_rtis[0]->rtrti_trees = (char **)bu_calloc( num_trees, - sizeof( char *), - "rtrti_trees" ); - - /* get the names of the top-level BRL-CAD objects */ - for ( j=0; j < num_trees; j++ ) { - Tcl_Obj *tree; - - Tcl_ListObjIndex( interp, value, j, &tree ); - - /* copy the names */ - rts_geometry[sessionid]->rts_rtis[0]->rtrti_trees[j] = - bu_strdup( Tcl_GetString( tree ) ); - if ( verbose ) { - fprintf( stderr, "\t%s\n", rts_geometry[sessionid]->rts_rtis[0]->rtrti_trees[j] ); - } - } - } - found = 1; - break; - } - if ( found ) { - break; - } - } - Tcl_DeleteInterp( interp ); + /* just one RT instance */ + rts_geometry[sessionid]->rts_number_of_rtis = 1; + rts_geometry[sessionid]->rts_rtis = (struct rtserver_rti **)bu_malloc( sizeof( struct rtserver_rti *), + "rtserver_rti" ); + rts_geometry[sessionid]->rts_rtis[0] = (struct rtserver_rti *)bu_calloc( 1, + sizeof( struct rtserver_rti ), + "rtserver_rti" ); + rts_geometry[sessionid]->rts_rtis[0]->rtrti_rtip = rtip; + rts_geometry[sessionid]->rts_rtis[0]->rtrti_num_trees = num_trees; + if ( verbose ) { + fprintf( stderr, "num_trees = %d\n", num_trees ); } + /* malloc some memory for the rtserver geometry structure (bu_calloc zeros the memory) */ + rts_geometry[sessionid] = (struct rtserver_geometry *)bu_calloc( 1, + sizeof( struct rtserver_geometry ), + "rtserver geometry" ); + /* just one RT instance */ + rts_geometry[sessionid]->rts_number_of_rtis = 1; + rts_geometry[sessionid]->rts_rtis = (struct rtserver_rti **)bu_malloc( sizeof( struct rtserver_rti *), + "rtserver_rti" ); + rts_geometry[sessionid]->rts_rtis[0] = (struct rtserver_rti *)bu_calloc( 1, + sizeof( struct rtserver_rti ), + "rtserver_rti" ); + rts_geometry[sessionid]->rts_rtis[0]->rtrti_rtip = rtip; + /* initialize our overall bounding box */ VSETALL( rts_geometry[sessionid]->rts_mdl_min, MAX_FASTF ); VREVERSE( rts_geometry[sessionid]->rts_mdl_max, rts_geometry[sessionid]->rts_mdl_min ); @@ -944,15 +499,12 @@ /* cache the rtserver_rti pointer and its associated rt instance pointer */ rts_rtip = rts_geometry[sessionid]->rts_rtis[i]; rtip = rts_rtip->rtrti_rtip; + rts_rtip->rtrti_num_trees = num_trees; + rts_rtip->rtrti_trees = (char**)bu_calloc(rts_rtip->rtrti_num_trees, sizeof(char *), "rtrti_trees"); - /* create resource structures for each thread */ - for ( j=0; j<thread_count; j++ ) { - struct resource *resp; - - resp = (struct resource *)bu_calloc( 1, sizeof( struct resource ), "resource" ); - rt_init_resource( resp, j, rtip ); - } - + for ( j=0; j<rts_rtip->rtrti_num_trees; j++ ) { + rts_rtip->rtrti_trees[j] = bu_strdupm(objects[j], "rtrti_tree"); + } /* get the BRL-CAD objects for this rt instance */ if ( verbose ) { fprintf( stderr, "Getting trees:\n" ); @@ -961,7 +513,7 @@ } } if ( rt_gettrees_and_attrs( rtip, attrs, rts_rtip->rtrti_num_trees, - (const char **)rts_rtip->rtrti_trees, ncpus ) ) { + (const char **)rts_rtip->rtrti_trees, 1 ) ) { fprintf( stderr, "Failed to get BRL-CAD objects:\n" ); for ( j=0; j<rts_rtip->rtrti_num_trees; j++ ) { fprintf( stderr, "\t%s\n", rts_rtip->rtrti_trees[j] ); @@ -970,7 +522,7 @@ } /* prep the geometry for raytracing */ - rt_prep_parallel( rtip, ncpus ); + rt_prep_parallel( rtip, 1 ); /* create the hash table of region names */ rts_rtip->rtrti_region_names = (Tcl_HashTable *)bu_calloc(1, sizeof(Tcl_HashTable), "region names hash table"); @@ -979,10 +531,14 @@ int newPtr = 0; Tcl_HashEntry *entry = Tcl_CreateHashEntry(rts_rtip->rtrti_region_names, rtip->Regions[regno]->reg_name, &newPtr); if( !newPtr ) { - bu_log( "Already have an entry for region %s\n", rtip->Regions[regno]->reg_name); + if( verbose ) { + bu_log( "Already have an entry for region %s\n", rtip->Regions[regno]->reg_name); + } continue; } - bu_log( "Setting hash table for key %s to %d\n", rtip->Regions[regno]->reg_name, regno); + if( verbose ) { + bu_log( "Setting hash table for key %s to %d\n", rtip->Regions[regno]->reg_name, regno); + } Tcl_SetHashValue(entry, (ClientData)regno ); } rts_rtip->region_count = rtip->nregions; @@ -998,25 +554,22 @@ V3ARGS( rts_geometry[sessionid]->rts_mdl_max ) ); } - return sessionid; } - /* ray missed routine for rt_shootray() */ int rts_miss( struct application *ap ) { - struct ray_result *ray_res; - int numPartitions; + struct bu_vlb *vlb; + int numPartitions = 0; /* get the results pointer from the application structure */ - ray_res = (struct ray_result *)ap->a_uptr; - if(ray_res->vlb != NULL) { + vlb = (struct bu_vlb *)ap->a_uptr; + if(vlb != NULL) { unsigned char buffer[SIZEOF_NETWORK_LONG]; - numPartitions = 0; bu_plong(buffer, numPartitions); - bu_vlb_write(ray_res->vlb, buffer, SIZEOF_NETWORK_LONG); + bu_vlb_write(vlb, buffer, SIZEOF_NETWORK_LONG); } if ( verbose ) { fprintf( stderr, "Missed!!!\n" ); @@ -1033,56 +586,52 @@ { int sessionid = ap->a_user; struct partition *pp; - struct ray_result *ray_res; + struct bu_vlb *vlb; + vect_t reverse_ray_dir; int numPartitions; + unsigned char buffer[SIZEOF_NETWORK_DOUBLE*3]; if ( verbose ) { fprintf( stderr, "Got a hit!!!\n" ); } /* get the results pointer from the application structure */ - ray_res = (struct ray_result *)ap->a_uptr; - - /* save a copy of the fired ray */ - ray_res->the_ray = ap->a_ray; + vlb = (struct bu_vlb *)ap->a_uptr; - if(ray_res->vlb != NULL) { - unsigned char buffer[SIZEOF_NETWORK_LONG]; - /* count the number of partitions */ - numPartitions = 0; - for ( BU_LIST_FOR( pp, partition, (struct bu_list *)partHeadp ) ) { - numPartitions++; - }; - bu_plong(buffer, numPartitions); - bu_vlb_write(ray_res->vlb, buffer, SIZEOF_NETWORK_LONG); - } - + /* count the number of partitions */ + numPartitions = 0; + for ( BU_LIST_FOR( pp, partition, (struct bu_list *)partHeadp ) ) { + numPartitions++; + }; /* write the number of partitiions to the byte array */ + bu_plong(buffer, numPartitions); + bu_vlb_write(vlb, buffer, SIZEOF_NETWORK_LONG); + + VREVERSE(reverse_ray_dir, ap->a_ray.r_dir); - /* build a list of hits */ + /* write hits to the bu_vlb structure */ for ( BU_LIST_FOR( pp, partition, (struct bu_list *)partHeadp ) ) { - struct ray_hit *ahit; struct region *rp; + vect_t enterNormal; + vect_t exitNormal; Tcl_HashEntry *entry; CLIENTDATA_INT code; + double los; + double inObl, outObl; + double dot; + int regionIndex; - /* get one hit structure */ - RTS_GET_RAY_HIT( ahit ); - /* fill in the data for this hit */ - ahit->hit_dist = pp->pt_inhit->hit_dist; - ahit->los = pp->pt_outhit->hit_dist - pp->pt_inhit->hit_dist; - RT_HIT_NORMAL( ahit->enter_normal, pp->pt_inhit, + los = pp->pt_outhit->hit_dist - pp->pt_inhit->hit_dist; + RT_HIT_NORMAL( enterNormal, pp->pt_inhit, pp->pt_inseg->seg_stp, 0, pp->pt_inflip ); - RT_HIT_NORMAL( ahit->exit_normal, pp->pt_outhit, + RT_HIT_NORMAL( exitNormal, pp->pt_outhit, pp->pt_outseg->seg_stp, 0, pp->pt_outflip ); rp = pp->pt_regionp; - /* stash a pointer to the region structure (used by JAVA code to get region name) */ - ahit->regp = rp; - /* find has table entry, if we have a table (to get MUVES_Component index) */ +/* if ( hash_table_exists ) { if ( rp->reg_aircode ) { code = rp->reg_aircode; @@ -1094,86 +643,67 @@ } else { entry = NULL; } - - /* assign comp_id based on hash table results */ - if ( entry == NULL ) { - ahit->comp_id = 0; - } else { - ahit->comp_id = (CLIENTDATA_INT)Tcl_GetHashValue( entry ); - } - - if(ray_res->vlb != NULL) { - unsigned char buffer[SIZEOF_NETWORK_DOUBLE*3]; - vect_t reverse_ray_dir; - double inObl, outObl; - double dot; - int regionIndex; +*/ - /* write partition info to the byte array */ - /* start with entrance point */ - htond(buffer, (unsigned char *)pp->pt_inhit->hit_point, 3); - bu_vlb_write(ray_res->vlb, buffer, SIZEOF_NETWORK_DOUBLE*3); - /* next exit point */ - htond(buffer, (unsigned char *)pp->pt_outhit->hit_point, 3); - bu_vlb_write(ray_res->vlb, buffer, SIZEOF_NETWORK_DOUBLE*3); - /* next entrance surface normal vector */ - htond(buffer, (unsigned char *)ahit->enter_normal, 3); - bu_vlb_write(ray_res->vlb, buffer, SIZEOF_NETWORK_DOUBLE*3); - /* next entrance surface normal vector */ - htond(buffer, (unsigned char *)ahit->exit_normal, 3); - bu_vlb_write(ray_res->vlb, buffer, SIZEOF_NETWORK_DOUBLE*3); + /* write partition info to the byte array */ + /* start with entrance point */ + htond(buffer, (unsigned char *)pp->pt_inhit->hit_point, 3); + bu_vlb_write(vlb, buffer, SIZEOF_NETWORK_DOUBLE*3); + /* next exit point */ + htond(buffer, (unsigned char *)pp->pt_outhit->hit_point, 3); + bu_vlb_write(vlb, buffer, SIZEOF_NETWORK_DOUBLE*3); + /* next entrance surface normal vector */ + htond(buffer, (unsigned char *)enterNormal, 3); + bu_vlb_write(vlb, buffer, SIZEOF_NETWORK_DOUBLE*3); + /* next entrance surface normal vector */ + htond(buffer, (unsigned char *)exitNormal, 3); + bu_vlb_write(vlb, buffer, SIZEOF_NETWORK_DOUBLE*3); - VREVERSE(reverse_ray_dir, ray_res->the_ray.r_dir); - - /* calculate the entrance and exit obliquities */ - dot = VDOT( reverse_ray_dir, ahit->enter_normal ); - if( dot < -1.0 ) { - dot = -1.0; - } else if( dot > 1.0 ) { - dot = 1.0; - } - inObl = acos(dot); - if ( inObl < 0.0 ) { - inObl = -inObl; - } - if ( inObl > M_PI_2 ) { - inObl = M_PI_2; - } + /* calculate the entrance and exit obliquities */ + dot = VDOT( reverse_ray_dir, enterNormal ); + if( dot < -1.0 ) { + dot = -1.0; + } else if( dot > 1.0 ) { + dot = 1.0; + } + inObl = acos(dot); + if ( inObl < 0.0 ) { + inObl = -inObl; + } + if ( inObl > M_PI_2 ) { + inObl = M_PI_2; + } - dot = VDOT( ray_res->the_ray.r_dir, ahit->exit_normal ); - if( dot < -1.0 ) { - dot = -1.0; - } else if( dot > 1.0 ) { - dot = 1.0; - } - outObl = acos(dot); - if ( outObl < 0.0 ) { - outObl = -outObl; - } - if ( outObl > M_PI_2 ) { - outObl = M_PI_2; - } - - /* write obliquities to the buffer */ - htond( buffer, (unsigned char *)&inObl, 1 ); - htond( &buffer[SIZEOF_NETWORK_DOUBLE], (unsigned char *)&outObl, 1); - bu_vlb_write(ray_res->vlb, buffer, SIZEOF_NETWORK_DOUBLE*2); - - /* get the region index from the hash table */ - entry = Tcl_FindHashEntry( rts_geometry[sessionid]->rts_rtis[0]->rtrti_region_names, (ClientData)rp->reg_name ); - regionIndex = (CLIENTDATA_INT)Tcl_GetHashValue( entry ); - - /* write region index to buffer */ - bu_plong(buffer, regionIndex); - bu_vlb_write(ray_res->vlb, buffer, SIZEOF_NETWORK_LONG); - } else { - /* add this to our list of hits */ - BU_LIST_INSERT( &ray_res->hitHead.l, &ahit->l ); + dot = VDOT( ap->a_ray.r_dir, exitNormal ); + if( dot < -1.0 ) { + dot = -1.0; + } else if( dot > 1.0 ) { + dot = 1.0; } + outObl = acos(dot); + if ( outObl < 0.0 ) { + outObl = -outObl; + } + if ( outObl > M_PI_2 ) { + outObl = M_PI_2; + } + /* write obliquities to the buffer */ + htond( buffer, (unsigned char *)&inObl, 1 ); + htond( &buffer[SIZEOF_NETWORK_DOUBLE], (unsigned char *)&outObl, 1); + bu_vlb_write(vlb, buffer, SIZEOF_NETWORK_DOUBLE*2); + + /* get the region index from the hash table */ + entry = Tcl_FindHashEntry( rts_geometry[sessionid]-... [truncated message content] |