Week 1
Functions calling procedures in rt_shootray(...)
- Step 1: initialization, resource allocation and data preparation
- Step 2: calling rt_in_rpp(...) to check whether the ray will intersect the bounding box of model, if it does, preparing for ray-tracing and going to next step, or it will report a miss.
- Step 3: determining where the real intersection starts, if back tracing flag is enabled, then calling rt_find_backing_dist(...) to compute the backing distance.
- Step 4: iterating step 5 to step 7 listed below until the ray emerges from the model space again.
- Step 5: calling rt_advance_to_next_cell(...) to move the ray forward along ray direction, during this procedure, traversing the space partitioning tree(like NUBSPT, short for non-uniform binary space partitioning tree) to find next cell(like CUT_BOXNODE defined in NUBSPT) for ray intersection test.
- Step 6: considering all pieces and solids in the cell found in last step to compute intersection segments. For pieces of BoT primitives, it will call rt_bot_piece_shot(...) to record all hits and rt_bot_piece_hitsegs(...) to make segments. Besides, for solids, it will call rt_bot_shot(...) to get the hits and make segments.(Actually, all these functions are called through the function pointers defined in stp->st_meth->ft_***())
[Attentions] In rt_bot_shot(...) (about line 583 in bot.c), at last, it calls rt_bot_shot_float(...) or rt_bot_shot_double(...), actually, these functions are defined by macro in g_bot_include.c.
- Step 7: calling rt_boolweave(...) to weave segments generated in last step into partition list.(Actually, I am a little bit confused about what it really do, since this is not the part that I need to focus on, just put it here until I get around to understand it later.)
- Step 8: defining your a_hit and a_miss function to do some post-processing stuffs regarding to all the hit points, like computing curvature or outputing related information and so on.
- Step 9: returning the result, it's done.
Data structure of rt_bot_internal (about line 758 in geom.h)
There are two internal data structures designed for BoT listed as follows.
- rt_bot_internal(about line 758 in geom.h): it contains some basic data used in BoT, like vertices, faces and normals and so on. Besides, in order to define plate mode BoT, to this end, it defines thickness value array, face mode flag to characterize this property.
- bot_specific(about line 57 in bot.h): it stores almost the same information mentioned in rt_bot_internal.
How to use *thickness* value in BoT when ray-tracing
Actually, the most related utilization of this property is in static int XGLUE(rt_bot_plate_segs_, TRI_TYPE)(...)(about line 382 in g_bot_include.c), this function is used to make segments for each hit, cause we have two types of 'plate mode': RT_BOT_PLATE and RT_BOT_PLATE_NOCOS, so firstly, we compute LOS(Line Of Sight) instead of using thickness value directly. If the mode is RT_BOT_PLATE_NOCOS, it means that the advancing distance of the ray does not consider the oblique angle between ray direction and the normal of hit point. While in RT_BOT_PLATE_NOCOS mode, it will.
Designing data structure for B-rep primitives
After talking with @brlcad, with his suggestion, I summarize all the items we have discussed.
- openNURBS APIs have already provided a variable for attaching additional user defined application specified data. If we only want to store *thickness* value, that should be enough. To be more detailed, in the class definition of ON_Brep(a built-in class in openNURBS for representing B-rep model), there exists a variable, named m_brep_user(about line 3920 in opennurbs_brep.h), available for application based utilization, so it can be used to store additional values for whole brep, like default/global thickness value mentioned by @brlcad. Similarly, for each face, its corresponding data structure is ON_BrepFace, it also contains a variabe called m_face_user for same purpose. So we can exploit this built-in property and assign *thickness* value for brep or even each face in a more convenient way.
- Cause the *thickness* value may tell us everything about the mode(NULL == SOLID, 0 == SURFACE, >0 == PLATE), so at the beginning, we can consider to discard this flag. Besides, for simplicity, we will not consider NOCOS mode at present.
- About how to use face_mode flag, it is still mooted and under discussion.