Richard, Several comments. I know this is a learning experience, so I'll try to explain things but please ask if there are any questions.
First off, there shouldn't be a global in rt's main.c. Also, adding boolean type definitions really isn't necessary or desirable. It adds a layer of abstraction and generally doesn't add any value, even with regards to readability. The language has defined behavior for value truthfulness. It just raises questions to devs reading the code where they now have to ask what that symbol is and what its value is. On top of that, those names (bool, true, false) are reserved C++ words and already even provided by stdbool for C (although c99, which isn't yet fair game to require). They're best removed. Just use zero and one. You should use 'set' vars instead of the -y option since the opt.c arguments are intended to apply to most all of the ray-trace applications. The ray-trace front-end interface (RTUI) provides a command interface that are what is used for options that don't apply to all ray-tracers. The -y option you added only applies to rtedge, so it doesn't really belong there. The raytracers that have application-specific options define those in their view file (see view_parse in src/rt/viewedge.c for an example of how rtedge accomplishes this). The end result is something like "rtedge -c "set cpa=1". Another note with regards to the comments.. overkill and in odd locations where you're commenting on variables being incremented. Instead of big comment blocks where the variables are incremented that describe what those variables are and what they are used for, those comments should be up where the variable is declared. There's of course no need to say that you're incrementing a variable since that's exactly what the next line is doing via the ++ operator. It just makes it harder to actually follow the logic when there are 5x as much comments as code with the comments heavily mixed throughout. Finally, don't forget to update the manual page documentation too for the new option (and can again see rtedge's manpage for how to document your set variable). Otherwise, it looks like it does compute and optionally centers now -- pretty cool progress! Cheers! Sean On Mar 30, 2009, at 4:34 PM, [email protected] wrote: > Revision: 34121 > http://brlcad.svn.sourceforge.net/brlcad/?rev=34121&view=rev > Author: r_weiss > Date: 2009-03-30 20:34:25 +0000 (Mon, 30 Mar 2009) > > Log Message: > ----------- > updates to rtarea adding center computations > > Modified Paths: > -------------- > brlcad/trunk/src/rt/main.c > brlcad/trunk/src/rt/opt.c > brlcad/trunk/src/rt/viewarea.c > > Modified: brlcad/trunk/src/rt/main.c > =================================================================== > --- brlcad/trunk/src/rt/main.c 2009-03-30 16:46:31 UTC (rev 34120) > +++ brlcad/trunk/src/rt/main.c 2009-03-30 20:34:25 UTC (rev 34121) > @@ -49,7 +49,16 @@ > #include "rtprivate.h" > #include "brlcad_version.h" > > +/* boolean type definition */ > +typedef int bool; > +#define false (0) > +#define true (1) > > +/* rt global boolean to indicate if rtarea should compute > + * centers. this is set in opt.c > + */ > +bool rtarea_compute_centers=false; > + > extern const char title[]; > extern const char usage[]; > > @@ -186,6 +195,7 @@ > (void)fputs(usage, stderr); > return 1; > } > + > /* Identify the versions of the libraries we are using. */ > if (rt_verbosity & VERBOSE_LIBVERSIONS) { > (void)fprintf(stderr, "%s%s%s%s\n", > > Modified: brlcad/trunk/src/rt/opt.c > =================================================================== > --- brlcad/trunk/src/rt/opt.c 2009-03-30 16:46:31 UTC (rev 34120) > +++ brlcad/trunk/src/rt/opt.c 2009-03-30 20:34:25 UTC (rev 34121) > @@ -44,6 +44,16 @@ > int height = 0; /* # of lines in Y */ > > > +/* boolean type definition */ > +typedef int bool; > +#define false (0) > +#define true (1) > + > + > +/* boolean to enable/disable rtarea center computations */ > +extern bool rtarea_compute_centers; > + > + > /***** Variables shared with viewing model *** */ > int doubles_out = 0; /* u_char or double .pix output file */ > double azimuth = 0.0, elevation = 0.0; > @@ -167,7 +177,7 @@ > > > #define GETOPT_STR \ > - ".:,:@:a:b:c:d:e:f:g:h:ij:k:l:n:o:p:q:rs:tu:v:w:x:A:BC:D:E:F:G:H:IJ: > K:MN:O:P:Q:RST:U:V:WX:!:+:" > + ".:,:@:a:b:c:d:e:f:g:h:ij:k:l:n:o:p:q:rs:tu:v:w:x:yA:BC:D:E:F:G:H:IJ > :K:MN:O:P:Q:RST:U:V:WX:!:+:" > > while ( (c=bu_getopt( argc, argv, GETOPT_STR )) != EOF ) { > switch ( c ) { > @@ -568,6 +578,10 @@ > case 'd': > rpt_dist = atoi( bu_optarg ); > break; > + case 'y': > + /* enable rtarea center computations */ > + rtarea_compute_centers = true; > + break; > case '+': > { > register char *cp = bu_optarg; > > Modified: brlcad/trunk/src/rt/viewarea.c > =================================================================== > --- brlcad/trunk/src/rt/viewarea.c 2009-03-30 16:46:31 UTC (rev 34120) > +++ brlcad/trunk/src/rt/viewarea.c 2009-03-30 20:34:25 UTC (rev 34121) > @@ -39,6 +39,10 @@ > #include "plot3.h" > #include "rtprivate.h" > > +/* boolean type definition */ > +typedef int bool; > +#define false (0) > +#define true (1) > > extern int npsw; /* number of worker PSWs to run */ > > @@ -51,7 +55,15 @@ > static long hit_count=0; > static fastf_t cell_area=0.0; > > +/* holds total exposed values */ > +static unsigned long int exposed_hit_sum=0; > +static fastf_t exposed_hit_x_sum=0.0; > +static fastf_t exposed_hit_y_sum=0.0; > +static fastf_t exposed_hit_z_sum=0.0; > > +/* boolean to enable/disable center computations */ > +extern bool rtarea_compute_centers; /* from opt.c */ > + > /* Viewing module specific "set" variables */ > struct bu_structparse view_parse[] = { > {"", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL } > @@ -72,21 +84,37 @@ > -U # Set use_air boolean to # (default=1)\n\ > -u units Set the display units (default=mm)\n\ > -x # Set librt debug flags\n\ > + -y Enable center computations\n\ > "; > > +struct point_list { > + struct point_list * next; > + point_t pt_cell; > +}; > > struct area { > - struct area *assembly; /* pointer to a linked list of > assemblies */ > - long hits; /* presented hits count */ > - long exposures; /* exposed hits count */ > - int seen; /* book-keeping for exposure */ > - int depth; /* assembly depth */ > - const char *name; /* assembly name */ > + struct bu_list l; /**< @brief > magic # and doubly linked list */ > + struct area * assembly; /* pointer > to a bu_list of assemblies */ > + long hits; /* > presented hits count */ > + long exposures; /* exposed > hits count */ > + int seen; /* book- > keeping for exposure */ > + int depth; /* assembly > depth */ > + const char * name; /* assembly > name */ > + struct point_list * hit_points; /* list of > points that define the presented area */ > + struct point_list * exp_points; /* list of > points that define the exposed area */ > + int num_hit_points; /* number > of points present in hit_points */ > + int num_exp_points; /* number > of points present in exp_points */ > + fastf_t group_exposed_hit_x_sum; /* running > x total of exposed hit points on group */ > + fastf_t group_exposed_hit_y_sum; /* running > y total of exposed hit points on group */ > + fastf_t group_exposed_hit_z_sum; /* running > z total of exposed hit points on group */ > + fastf_t group_presented_hit_x_sum; /* running > x total of presented hit points on group */ > + fastf_t group_presented_hit_y_sum; /* running > y total of presented hit points on group */ > + fastf_t group_presented_hit_z_sum; /* running > z total of presented hit points on group */ > }; > > struct area_list { > - struct area *cell; > - struct area_list *next; > + struct area * cell; > + struct area_list * next; > }; > > typedef enum area_type { > @@ -97,8 +125,8 @@ > > int rayhit(struct application *ap, struct partition *PartHeadp, > struct seg *segHeadp); > int raymiss(register struct application *ap); > +int area_center(struct point_list *ptlist, int number, point_t > *center); > > - > /* > * V I E W _ I N I T > */ > @@ -136,19 +164,69 @@ > /* initial empty parent assembly */ > struct area *assembly; > > + /* cell_width and cell_height are global variables */ > cell_area = cell_width * cell_height; > > - assembly = (struct area *)bu_calloc(1, sizeof(struct area), > "view_2init assembly allocation"); > + /* create first parent-area record */ > + BU_GETSTRUCT(assembly, area); > > - /* allocate the initial areas and point them all to the same > (empty) starting assembly list */ > + /* initialize linked-list pointers for first parent-area > record */ > + BU_LIST_INIT(&(assembly->l)); > + > + /* initialize first parent-area record */ > + assembly->assembly = (struct area *) NULL; > + assembly->hits = 0; > + assembly->exposures = 0; > + assembly->seen = 0; > + assembly->depth = 0; > + assembly->name = (char *) NULL; > + assembly->hit_points = (struct point_list *) NULL; > + assembly->exp_points = (struct point_list *) NULL; > + assembly->num_hit_points = 0; > + assembly->num_exp_points = 0; > + assembly->group_exposed_hit_x_sum = 0.0; > + assembly->group_exposed_hit_y_sum = 0.0; > + assembly->group_exposed_hit_z_sum = 0.0; > + assembly->group_presented_hit_x_sum = 0.0; > + assembly->group_presented_hit_y_sum = 0.0; > + assembly->group_presented_hit_z_sum = 0.0; > + > bu_semaphore_acquire( RT_SEM_RESULTS ); > + > + /* traverse the regions linked-list, create and assign an > empty area record > + * to each region record. > + */ > for ( BU_LIST_FOR( rp, region, &(rtip->HeadRegion) ) ) { > struct area *cell; > - /* allocate memory first time through */ > - cell = (struct area *)bu_calloc(1, sizeof(struct area), > "view_2init area allocation"); > + > + /* create region-area record */ > + BU_GETSTRUCT(cell, area); > + > + /* initialize linked-list pointers for region-area record */ > + BU_LIST_INIT(&(cell->l)); > + > + /* initialize region-area record */ > cell->assembly = assembly; > + cell->hits = 0; > + cell->exposures = 0; > + cell->seen = 0; > + cell->depth = 0; > + cell->name = (char *) NULL; > + cell->hit_points = (struct point_list *) NULL; > + cell->exp_points = (struct point_list *) NULL; > + cell->num_hit_points = 0; > + cell->num_exp_points = 0; > + cell->group_exposed_hit_x_sum = 0.0; > + cell->group_exposed_hit_y_sum = 0.0; > + cell->group_exposed_hit_z_sum = 0.0; > + cell->group_presented_hit_x_sum = 0.0; > + cell->group_presented_hit_y_sum = 0.0; > + cell->group_presented_hit_z_sum = 0.0; > + > + /* place new region-area record into current region record */ > rp->reg_udata = (genptr_t)cell; > } > + > bu_semaphore_release( RT_SEM_RESULTS ); > > return; > @@ -184,15 +262,23 @@ > * used for regions. > */ > static void > -increment_assembly_counter(register struct area *cell, const char > *path, area_type_t type) > +increment_assembly_counter(register struct area *cell, const char > *path, area_type_t type, point_t *hit_point) > { > - int l; > - char *buffer; > - int depth; > + int l = 0; > + char *buffer = (char *) NULL; > + int depth = 0; > + bool parent_found=false; > + register struct area *assembly_head_ptr = cell->assembly; > + register struct area *area_record_ptr = (struct area *) NULL; > > - if (!cell || !path) { > + if (!cell) { > + bu_log("ERROR: Function 'increment_assembly_counter' > received a NULL pointer to an 'area' structure. Function aborted.\n"); > return; > } > + if (!path) { > + bu_log("ERROR: Function 'increment_assembly_counter' > received a NULL pointer to a region path. Function aborted.\n"); > + return; > + } > > l = strlen(path); > buffer = bu_calloc(l+1, sizeof(char), > "increment_assembly_counter buffer allocation"); > @@ -207,75 +293,149 @@ > } > buffer[l-1] = '\0'; > > - /* get the region names, one at a time */ > - depth = 0; > + /* traverse region path name, character-by-character to > + * extract and process each parent name of the current region. > + */ > while (l > 0) { > + /* when the current character in the path name is forward- > slash, this > + * indicates the characters to the right of the forward- > slash are the next > + * parent in the path, use this name. when done find next > name up the > + * path until the path is empty. > + */ > if (buffer[l-1] == '/') { > - register struct area *cellp; > + parent_found=false; > > - /* scan the assembly list */ > - cellp = cell->assembly; > - while (cellp->name) { > - if ( (strcmp(cellp->name, &buffer[l])==0) ) { > + /* traverse the assembly linked-list */ > + for (BU_LIST_FOR(area_record_ptr, area, & > (assembly_head_ptr->l))) { > + /* if the 'name' of the current parent/group of the > + * current region matches the current 'name' in > the area > + * structure, then within the current linked-list > area > + * structure, increment number of exposures & hits > and > + * increment seen, then exit for-loop. > + */ > + if ( (strcmp(area_record_ptr->name, &buffer[l])==0) ) { > if (type == EXPOSED_AREA) { > - if (!cellp->seen) { > - cellp->exposures++; > - cellp->seen++; > - if (depth > cellp->depth) { > - cellp->depth = depth; > + if (!area_record_ptr->seen) { > + area_record_ptr->exposures++; > + area_record_ptr->seen++; > + area_record_ptr->hits++; > + > + /* total x,y,z for exposed & presented > hits */ > + if (rtarea_compute_centers) { > + area_record_ptr- > >group_exposed_hit_x_sum += (fastf_t)((*hit_point)[X]); > + area_record_ptr- > >group_exposed_hit_y_sum += (fastf_t)((*hit_point)[Y]); > + area_record_ptr- > >group_exposed_hit_z_sum += (fastf_t)((*hit_point)[Z]); > + area_record_ptr- > >group_presented_hit_x_sum += (fastf_t)((*hit_point)[X]); > + area_record_ptr- > >group_presented_hit_y_sum += (fastf_t)((*hit_point)[Y]); > + area_record_ptr- > >group_presented_hit_z_sum += (fastf_t)((*hit_point)[Z]); > + } > + > + if (depth > area_record_ptr->depth) { > + area_record_ptr->depth = depth; > } > } > } > if (type == PRESENTED_AREA) { > - cellp->hits++; > - cellp->seen++; > - if (depth > cellp->depth) { > - cellp->depth = depth; > + if (!area_record_ptr->seen) { > + area_record_ptr->hits++; > + area_record_ptr->seen++; > + > + /* total x,y,z for presented hits */ > + if (rtarea_compute_centers) { > + area_record_ptr- > >group_presented_hit_x_sum += (fastf_t)((*hit_point)[X]); > + area_record_ptr- > >group_presented_hit_y_sum += (fastf_t)((*hit_point)[Y]); > + area_record_ptr- > >group_presented_hit_z_sum += (fastf_t)((*hit_point)[Z]); > + } > + > + if (depth > area_record_ptr->depth) { > + area_record_ptr->depth = depth; > + } > } > } > + parent_found=true; > break; > } > - cellp = cellp->assembly; > - } > + } > > - /* insert a new assembly? */ > - if (!cellp->name) { > + /* if a parent of the current region does not already exist > in the > + * assembly linked-list then create, populate, insert > new area record > + * into the assembly linked-list. > + */ > + if (!parent_found) { > char *name; > int len; > > - /* sanity check */ > - if (cellp->assembly) { > - bu_log("Inconsistent assembly list detected\n"); > - break; > - } > + /* create new area record */ > + BU_GETSTRUCT(area_record_ptr, area); > > + /* initialize new parent-area record (i.e. > assembly-area record) */ > + area_record_ptr->assembly = (struct area *) NULL; > + area_record_ptr->hits = 0; > + area_record_ptr->exposures = 0; > + area_record_ptr->seen = 0; > + area_record_ptr->depth = 0; > + area_record_ptr->name = (char *) NULL; > + area_record_ptr->hit_points = (struct point_list > *) NULL; > + area_record_ptr->exp_points = (struct point_list > *) NULL; > + area_record_ptr->num_hit_points = 0; > + area_record_ptr->num_exp_points = 0; > + area_record_ptr->group_exposed_hit_x_sum = 0.0; > + area_record_ptr->group_exposed_hit_y_sum = 0.0; > + area_record_ptr->group_exposed_hit_z_sum = 0.0; > + area_record_ptr->group_presented_hit_x_sum = 0.0; > + area_record_ptr->group_presented_hit_y_sum = 0.0; > + area_record_ptr->group_presented_hit_z_sum = 0.0; > + > + /* allocate string to contain the object/parent/ > group name, copy the > + * name to the new string, assign the string to > the parent-area record. > + */ > len = strlen(&buffer[l])+1; > name = (char *)bu_malloc(len, "increment_assembly_counter > assembly name allocation"); > bu_strlcpy(name, &buffer[l], len); > - cellp->name = name; > + > + /* populate parent-area record */ > + area_record_ptr->name = name; > + > if (type == EXPOSED_AREA) { > - cellp->exposures++; > + area_record_ptr->exposures++; > + area_record_ptr->hits++; > + /* total x,y,z for exposed & presented hits */ > + if (rtarea_compute_centers) { > + area_record_ptr->group_exposed_hit_x_sum > += (fastf_t)((*hit_point)[X]); > + area_record_ptr->group_exposed_hit_y_sum > += (fastf_t)((*hit_point)[Y]); > + area_record_ptr->group_exposed_hit_z_sum > += (fastf_t)((*hit_point)[Z]); > + area_record_ptr->group_presented_hit_x_sum > += (fastf_t)((*hit_point)[X]); > + area_record_ptr->group_presented_hit_y_sum > += (fastf_t)((*hit_point)[Y]); > + area_record_ptr->group_presented_hit_z_sum > += (fastf_t)((*hit_point)[Z]); > + } > } > if (type == PRESENTED_AREA) { > - cellp->hits++; > + area_record_ptr->hits++; > + /* total x,y,z for presented hits */ > + if (rtarea_compute_centers) { > + area_record_ptr->group_presented_hit_x_sum > += (fastf_t)((*hit_point)[X]); > + area_record_ptr->group_presented_hit_y_sum > += (fastf_t)((*hit_point)[Y]); > + area_record_ptr->group_presented_hit_z_sum > += (fastf_t)((*hit_point)[Z]); > + } > } > - cellp->seen++; > - if (depth > cellp->depth) { > - cellp->depth = depth; > + > + /* always mark the current parent as seen since > this is a new > + * parent-area record and it is being processed now. > + */ > + area_record_ptr->seen++; > + > + if (depth > area_record_ptr->depth) { > + area_record_ptr->depth = depth; > } > - > - /* allocate space for the next assembly */ > - cellp->assembly = (struct area *)bu_calloc(1, sizeof(struct > area), "increment_assembly_counter assembly allocation"); > + /* attach new area record to assembly linked-list */ > + BU_LIST_PUSH(&(assembly_head_ptr->l), & > (area_record_ptr->l)); > } > - > buffer[l-1] = '\0'; > depth++; > } > l--; > } > - > bu_free(buffer, "increment_assembly_counter buffer free"); > - > return; > } > > @@ -287,12 +447,20 @@ > int > rayhit(struct application *ap, struct partition *PartHeadp, struct > seg *segHeadp) > { > + struct point_list * temp_point_list; /* to contain > exposed points */ > + struct point_list * temp_presented_point_list; /* to contain > presented points */ > register struct region *rp; > struct rt_i *rtip = ap->a_rt_i; > register struct partition *pp = PartHeadp->pt_forw; > register struct area *cell; > register int l; > + struct area *cellp; > > +/* exposed hit sums */ > + extern unsigned long int exposed_hit_sum; > + extern fastf_t exposed_hit_x_sum; > + extern fastf_t exposed_hit_y_sum; > + extern fastf_t exposed_hit_z_sum; > > if ( pp == PartHeadp ) > return(0); /* nothing was actually hit?? */ > @@ -302,34 +470,141 @@ > > hit_count++; > > - /* clear the list of visited regions */ > + /* traverse all regions in the model, clear seen in the 'area' > record > + * associated with each region. > + */ > for ( BU_LIST_FOR( rp, region, &(rtip->HeadRegion) ) ) { > - struct area *cellp; > cell = (struct area *)rp->reg_udata; > cell->seen = 0; > + } > > - for (cellp = cell->assembly; cellp; cellp = cellp->assembly) { > - cellp->seen = 0; > - } > + /* clear seen for all 'area' records associated with groups */ > + rp = BU_LIST_FIRST(region, &(rtip->HeadRegion)); > + cell = (struct area *)rp->reg_udata; > + for ( BU_LIST_FOR(cellp, area, &(cell->assembly->l) ) ) { > + cellp->seen = 0; > } > > - /* get the exposed areas (i.e. first hits) */ > - for (pp = PartHeadp->pt_forw; pp != PartHeadp; pp = pp- > >pt_forw) { > + /* get the exposed areas (i.e. first hits), traverse linked- > list of > + * partition records. > + */ > + for ( BU_LIST_FOR( pp, partition, (struct bu_list *) > PartHeadp ) ) { > struct region *reg = pp->pt_regionp; > + > + /* obtain the pointer to the area record associated with > the current > + * region being processed. > + */ > cell = (struct area *)reg->reg_udata; > > - /* ignore air */ > + /* ignore air. if the current region is of type 'air' skip > this region > + * and continue with the next region hit by the ray. > + */ > if (reg->reg_aircode) { > continue; > } > > - /* have not visited this region yet, so increment the count */ > - if (!cell->seen) { > + /* only process this hit if the region has not already > been hit by this > + * ray. this allows only exposed regions to be processed. > (i.e. 1st hit) > + */ > + if (!cell->seen) { /* for exposed areas */ > + if (rtarea_compute_centers) { > + > + /* create a new 'exposed' point_list record */ > + temp_point_list = (struct point_list *) bu_malloc > (sizeof(struct point_list), "Point list allocation"); > + > + /* create a new 'presented' point_list record */ > + temp_presented_point_list = (struct point_list *) > bu_malloc(sizeof(struct point_list), "Presented Point list > allocation"); > + > + /* initialize new 'exposed' point_list record */ > + temp_point_list->next = (struct point_list *) NULL; > + (temp_point_list->pt_cell)[X] = 0.0; > + (temp_point_list->pt_cell)[Y] = 0.0; > + (temp_point_list->pt_cell)[Z] = 0.0; > + > + /* initialize new 'presented' point_list record */ > + temp_presented_point_list->next = (struct > point_list *) NULL; > + (temp_presented_point_list->pt_cell)[X] = 0.0; > + (temp_presented_point_list->pt_cell)[Y] = 0.0; > + (temp_presented_point_list->pt_cell)[Z] = 0.0; > + > + /* compute hit_point and store in pt_inhit record > within the > + * current partition record > + */ > + VJOIN1(pp->pt_inhit->hit_point, ap->a_ray.r_pt, pp- > >pt_inhit->hit_dist, ap->a_ray.r_dir); > + > + /* place hit_point in new 'exposed' point_list > record */ > + (temp_point_list->pt_cell)[X] = (pp->pt_inhit- > >hit_point)[X]; > + (temp_point_list->pt_cell)[Y] = (pp->pt_inhit- > >hit_point)[Y]; > + (temp_point_list->pt_cell)[Z] = (pp->pt_inhit- > >hit_point)[Z]; > + > + /* place hit_point in new 'presented' point_list > record */ > + (temp_presented_point_list->pt_cell)[X] = (pp- > >pt_inhit->hit_point)[X]; > + (temp_presented_point_list->pt_cell)[Y] = (pp- > >pt_inhit->hit_point)[Y]; > + (temp_presented_point_list->pt_cell)[Z] = (pp- > >pt_inhit->hit_point)[Z]; > + > + /* for computing exposed area center, count hits > and sum x,y,z > + * values of hits on exposed regions > + */ > + exposed_hit_sum++; > + exposed_hit_x_sum = exposed_hit_x_sum + (fastf_t) > ((pp->pt_inhit->hit_point)[X]); > + exposed_hit_y_sum = exposed_hit_y_sum + (fastf_t) > ((pp->pt_inhit->hit_point)[Y]); > + exposed_hit_z_sum = exposed_hit_z_sum + (fastf_t) > ((pp->pt_inhit->hit_point)[Z]); > + > + /* if current area record contains no point_list > linked-list then > + * place the new and first point_list record in > the area record. > + * if the current area record already has a > point_list record > + * linked-list, then add the new point_list record > to the head of > + * the linked-list. > + */ > + if (!cell->exp_points) { > + cell->exp_points = temp_point_list; > + } else { > + temp_point_list->next = cell->exp_points; > + cell->exp_points = temp_point_list; > + } > + > + /* if current area record contains no 'presented' > point_list linked-list > + * then place the new and first point_list record > in the area record. > + * if the current area record already has a > point_list record > + * linked-list, then add the new point_list record > to the head of > + * the linked-list. > + */ > + if (!cell->hit_points) { > + cell->hit_points = temp_presented_point_list; > + } else { > + temp_presented_point_list->next = cell- > >hit_points; > + cell->hit_points = temp_presented_point_list; > + } > + > + /* for the current area record, increment > num_exp_points which > + * maintains a count of the number of records > within the point_list > + * linked-list and also the total of exposed hits > on the current > + * region. > + */ > + cell->num_exp_points++; > + > + /* for the current area record, increment > num_hit_points which > + * maintains a count of the number of records > within the > + * 'presented' point_list linked-list and also the > total of > + * presented hits on the current region. > + */ > + cell->num_hit_points++; > + } > + > + /* for the current area structure, increment exposures > and seen */ > cell->exposures++; > cell->seen++; > > + /* increment 'presented hits' for current region since > all hits on a > + * region are 'presented hits' even those that are a > first-hit on a ray. > + */ > + cell->hits++; > + > + /* if the current area record does not contain the > region name that > + * it represents then extract the region name from the > object path > + * then assign the name within the area record. > + */ > if (!cell->name) { > - /* get the region name */ > int l = strlen(reg->reg_name); > while (l > 0) { > if (reg->reg_name[l-1] == '/') { > @@ -341,15 +616,15 @@ > } > > /* record the parent assemblies */ > - increment_assembly_counter(cell, reg->reg_name, EXPOSED_AREA); > + increment_assembly_counter(cell, reg->reg_name, EXPOSED_AREA, > &(pp->pt_inhit->hit_point)); > } > > /* halt after first non-air */ > break; > - } > + } /* end of for-loop to 'get the exposed areas (i.e. first > hits)' */ > > /* get the presented areas */ > - for (pp = PartHeadp->pt_forw; pp != PartHeadp; pp = pp- > >pt_forw) { > + for ( BU_LIST_FOR( pp, partition, (struct bu_list *) > PartHeadp ) ) { > struct region *reg = pp->pt_regionp; > cell = (struct area *)reg->reg_udata; > > @@ -358,22 +633,62 @@ > continue; > } > > - cell->hits++; > + /* makes sure that a region already processed is not > processed again */ > + if (!cell->seen) { > > - if (!cell->name) { > - /* get the region name */ > - int l = strlen(reg->reg_name); > - while (l > 0) { > - if (reg->reg_name[l-1] == '/') { > - break; > - } > - l--; > + /* marks the current region being processed as > 'seen'='yes' so that > + * additional hits of this region by this ray are not > processed. > + */ > + cell->seen++; > + > + /* increments the presented hits on the current region > because all > + * hits on a region are considered part of presented > area of that region. > + * > + * do not increment exposed hits here because all > exposed hit on all > + * regions have already been processed in the previous > loop used to > + * process the first hit of the current ray. > + */ > + cell->hits++; > + > + /* enable/disable center point processing */ > + if (rtarea_compute_centers) { > + cell->num_hit_points++; > + > + /* allocate memory for point_list structure */ > + temp_point_list = (struct point_list *) bu_malloc(sizeof > (struct point_list), "Point list allocation"); > + > + /* compute hit point */ > + VJOIN1(pp->pt_inhit->hit_point, ap->a_ray.r_pt, pp- > >pt_inhit->hit_dist, ap->a_ray.r_dir); > + > + /* record the points in the area */ > + (temp_point_list->pt_cell)[X] = (pp->pt_inhit->hit_point) > [X]; > + (temp_point_list->pt_cell)[Y] = (pp->pt_inhit->hit_point) > [Y]; > + (temp_point_list->pt_cell)[Z] = (pp->pt_inhit->hit_point) > [Z]; > + temp_point_list->next = (struct point_list *) NULL; > + > + if (!cell->hit_points) { > + cell->hit_points = temp_point_list; > + } else { > + temp_point_list->next = cell->hit_points; > + cell->hit_points = temp_point_list; > + } > + } > + > + if (!cell->name) { > + /* get the region name */ > + int l = strlen(reg->reg_name); > + while (l > 0) { > + if (reg->reg_name[l-1] == '/') { > + break; > + } > + l--; > + } > + cell->name = ®->reg_name[l]; > } > - cell->name = ®->reg_name[l]; > - } > > - /* record the parent assemblies */ > - increment_assembly_counter(cell, reg->reg_name, PRESENTED_AREA); > + /* record the parent assemblies */ > + increment_assembly_counter(cell, reg->reg_name, > PRESENTED_AREA, &(pp->pt_inhit->hit_point)); > + } > } > bu_semaphore_release( RT_SEM_RESULTS ); > > @@ -465,8 +780,9 @@ > } > > cell = listp->cell; > + > if (type == PRESENTED_AREA) { > - bu_log("Region %s\t(%ld hits)\t= %18.4lf square %s\t(%.4lf > square %s)\n", > + bu_log("Region %s\t(%ld hits)\t= %18.4lf square %s\t(%.4lf > square %s)", > cell->name, > cell->hits, > cell_area * (fastf_t)cell->hits / (units*units), > @@ -474,10 +790,15 @@ > cell_area * (fastf_t)cell->hits / (factor*factor), > bu_units_string(factor) > ); > - fflush(stdout); fflush(stderr); > + if (rtarea_compute_centers) { > + point_t temp; > + if (area_center((cell->hit_points), (cell- > >num_hit_points), &temp)) { > + bu_log("\tcenter at (%.4lf, %.4lf, %.4lf)", > temp[X], temp[Y], temp[Z]); > + } > + } > } > if (type == EXPOSED_AREA) { > - bu_log("Region %s\t(%ld hits)\t= %18.4lf square %s\t(%.4lf > square %s)\n", > + bu_log("Region %s\t(%ld hits)\t= %18.4lf square %s\t(%.4lf > square %s)", > cell->name, > cell->exposures, > cell_area * (fastf_t)cell->exposures / (units*units), > @@ -485,8 +806,17 @@ > cell_area * (fastf_t)cell->exposures / (factor*factor), > bu_units_string(factor) > ); > - fflush(stdout); fflush(stderr); > + if (rtarea_compute_centers) { > + point_t temp; > + if (area_center((cell->exp_points), (cell- > >num_exp_points), &temp)) { > + bu_log("\tcenter at (%.4lf, %.4lf, %.4lf)", > temp[X], temp[Y], temp[Z]); > + } > + } > } > + > + bu_log("\n"); > + fflush(stdout); fflush(stderr); > + > listp = listp->next; > bu_free(prev, "print_area_list area list node free"); > } > @@ -520,12 +850,13 @@ > /* insertion sort based on depth and case */ > rp = BU_LIST_FIRST(region, &(rtip->HeadRegion)); > cell = (struct area *)rp->reg_udata; > - for (cellp = cell->assembly; cellp; cellp = cellp->assembly) { > + > + for (BU_LIST_FOR(cellp, area, &(cell->assembly->l))) { > int counted_items; > listp = listHead; > > if (type == PRESENTED_AREA) { > - counted_items = cellp->hits; > + counted_items = cellp->hits; > } > if (type == EXPOSED_AREA) { > counted_items = cellp->exposures; > @@ -588,9 +919,9 @@ > bu_log("--"); > } > } > - > + > if (type == PRESENTED_AREA) { > - bu_log("Assembly %s\t(%ld hits)\t= %18.4lf square %s\t(%.4lf > square %s)\n", > + bu_log("Assembly %s\t(%ld hits)\t= %18.4lf square %s\t(%.4lf > square %s)", > cell->name, > cell->hits, > cell_area * (fastf_t)cell->hits / (units*units), > @@ -598,10 +929,18 @@ > cell_area * (fastf_t)cell->hits / (factor*factor), > bu_units_string(factor) > ); > - fflush(stdout); fflush(stderr); > + if (rtarea_compute_centers) { > + if (cell->hits) { > + bu_log("\tcenter at (%.4lf, %.4lf, %.4lf)", > + cell->group_presented_hit_x_sum / (fastf_t) > cell->hits, > + cell->group_presented_hit_y_sum / (fastf_t) > cell->hits, > + cell->group_presented_hit_z_sum / (fastf_t) > cell->hits > + ); > + } > + } > } > if (type == EXPOSED_AREA) { > - bu_log("Assembly %s\t(%ld hits)\t= %18.4lf square %s\t(%.4lf > square %s)\n", > + bu_log("Assembly %s\t(%ld hits)\t= %18.4lf square %s\t(%.4lf > square %s)", > cell->name, > cell->exposures, > cell_area * (fastf_t)cell->exposures / (units*units), > @@ -609,9 +948,19 @@ > cell_area * (fastf_t)cell->exposures / (factor*factor), > bu_units_string(factor) > ); > - fflush(stdout); fflush(stderr); > + if (rtarea_compute_centers) { > + if (cell->exposures) { > + bu_log("\tcenter at (%.4lf, %.4lf, %.4lf)", > + cell->group_exposed_hit_x_sum / (fastf_t)cell- > >exposures, > + cell->group_exposed_hit_y_sum / (fastf_t)cell- > >exposures, > + cell->group_exposed_hit_z_sum / (fastf_t)cell- > >exposures > + ); > + } > + } > } > > + bu_log("\n"); > + fflush(stdout); fflush(stderr); > listp = listp->next; > bu_free(prev, "print_area_list area list node free"); > } > @@ -662,7 +1011,8 @@ > /* find the maximum assembly depth */ > rp = BU_LIST_FIRST(region, &(rtip->HeadRegion)); > cell = (struct area *)rp->reg_udata; > - for (cellp = cell->assembly; cellp; cellp = cellp->assembly) { > + > + for (BU_LIST_FOR(cellp, area, &(cell->assembly->l))) { > if (cellp->depth > max_depth) { > max_depth = cellp->depth; > } > @@ -688,6 +1038,15 @@ > total_area / (factor*factor), > bu_units_string(factor) > ); > + /* output of center of exposed area */ > + if (rtarea_compute_centers) { > + bu_log("Center of Exposed Area (%lu hits) = (%.4lf, %. > 4lf, %.4lf)\n", > + exposed_hit_sum, > + exposed_hit_x_sum / (fastf_t)exposed_hit_sum, > + exposed_hit_y_sum / (fastf_t)exposed_hit_sum, > + exposed_hit_z_sum / (fastf_t)exposed_hit_sum > + ); > + } > bu_log("Number of Presented Regions: %8d\n", > presented_region_count); > bu_log("Number of Presented Assemblies: %8d\n", > presented_assembly_count); > bu_log("Number of Exposed Regions: %8d\n", > exposed_region_count); > @@ -702,32 +1061,72 @@ > /* free the assembly areas */ > cell = (struct area *)rp->reg_udata; > if (cell) { > - struct area *next_cell; > - cell = cell->assembly; > - while (cell) { > - next_cell = cell->assembly; > - if (cell->name) { > - bu_free((char *)cell->name, "view_end assembly name free"); > + struct area *cellp; > + while (BU_LIST_WHILE(cellp, area, &(cell->assembly->l))) { > + if (cellp->name) { > + bu_free((char *)cellp->name, "view_end assembly name free"); > } > - bu_free(cell, "view_end assembly free"); > - cell = next_cell; > - } > + if (rtarea_compute_centers) { > + if (cellp->exp_points) { > + struct point_list * point, * next_point; > + point = cellp->exp_points; > + while (point) { > + /*next_point = BU_LIST_NEXT(point_list, & > (point->l));*/ > + next_point = point->next; > + bu_free(point, "exposed point_list free"); > + point = next_point; > + } > + } > + if (cellp->hit_points) { > + struct point_list * point, * next_point; > + point = cellp->hit_points; > + while (point) { > + /*next_point = BU_LIST_NEXT(point_list, & > (point->l));*/ > + next_point = point->next; > + bu_free(point, "presented point_list free"); > + point = next_point; > + } > + } > + } > + BU_LIST_DEQUEUE(&(cellp->l)); > + bu_free(cellp, "free assembly-area entry"); > + } > + bu_free(cell->assembly, "free assembly list head"); > } > > /* free the region areas */ > for ( BU_LIST_FOR( rp, region, &(rtip->HeadRegion) ) ) { > cell = (struct area *)rp->reg_udata; > - > if (cell) { > + if (rtarea_compute_centers) { > + if (cell->exp_points) { > + struct point_list * point, * next_point; > + point = cell->exp_points; > + while (point) { > + /*next_point = BU_LIST_NEXT(point_list, & > (point->l));*/ > + next_point = point->next; > + bu_free(point, "exposed point_list free"); > + point = next_point; > + } > + } > + if (cell->hit_points) { > + struct point_list * point, * next_point; > + point = cell->hit_points; > + while (point) { > + /*next_point = BU_LIST_NEXT(point_list, & > (point->l));*/ > + next_point = point->next; > + bu_free(point, "presented point_list free"); > + point = next_point; > + } > + } > + } > bu_free(cell, "view_end area free"); > cell = (genptr_t)NULL; > - rp->reg_name = (genptr_t)NULL; > } > } > > /* flush for good measure */ > fflush(stdout); fflush(stderr); > - > return; > } > > @@ -736,6 +1135,42 @@ > void application_init () {} > > /* > + * A R E A _ C E N T E R > + * > + * This function receives a pointer to a point_list > + * structure, the number of points to calculate, and > + * the point address of where to record the information. > + */ > + > +int > +area_center(struct point_list * ptlist, int number, point_t *center) > +{ > + struct point_list *point_it; > + point_t temp_point; > + > + if (!ptlist) { > + return 0; > + } > + temp_point[X] = 0; > + temp_point[Y] = 0; > + temp_point[Z] = 0; > + > + point_it = ptlist; > + while (point_it) { > + temp_point[X] += point_it->pt_cell[X]; > + temp_point[Y] += point_it->pt_cell[Y]; > + temp_point[Z] += point_it->pt_cell[Z]; > + point_it = point_it->next; > + } > + > + (*center)[X] = temp_point[X] / number; > + (*center)[Y] = temp_point[Y] / number; > + (*center)[Z] = temp_point[Z] / number; > + > + return 1; > +} > + > +/* > * Local Variables: > * mode: C > * tab-width: 8 > > > This was sent by the SourceForge.net collaborative development > platform, the world's largest Open Source development site. > > ---------------------------------------------------------------------- > -------- > _______________________________________________ > BRL-CAD Source Commits mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/brlcad-commits ------------------------------------------------------------------------------ _______________________________________________ BRL-CAD Developer mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/brlcad-devel
