HImCuttingGeometry

Functions

HImCuttingGeometry

~HImCuttingGeometry

void

CreateCuttingGeometry

void

CreateCuttingGeometry

void

SetSmallestFeature

float

GetSmallestFeature

void

SetTolerance

float

GetTolerance

void

RegisterCallbacks

Detailed Description

class HImCuttingGeometry

This class implements capping polygons. Capping planes help extend the illusion to the user that he is dealing with actual solids, as opposed to what they really are — boundary representations.

Capping planes are implemented in MVO via the HImCuttingGeometry class. They work by setting an I.M. callback on cutting lines, then collecting those into closed loops from which capping polygons represented as shell faces can be derived. The HImCuttingGeometry class can be used to create polylines, faces or both.

Computation of capping polygons is an operation on solid bodies, so there needs to be some notion of what geometry should be considered as part of the same solid. The normal modes of operation (decided, as described below, with an argument to the CreateCuttingGeometry function) are to consider each shell to be a separate solid or take everything in a segment to collectively represent a solid. In the latter mode, under certain circumstances as described below, entire segment trees can be considered as one.

The main function where all of the magic happens is CreateCuttingGeometry(). This function has four arguments: a) source_key, b) target_key, c) cutting_type, defaulted to HIM_CUTTING_GEOMETRY_TYPE_POLYLINES, and d) body_level, defaulted to HIM_CUTTING_GEOMETRY_SHELL_BODY.

This class is intended to be used to recalculate geometry only when needed, as opposed to once on every update. To that end, we suggest that the user create a dedicated segment for all of the temporary geometry, and keep a flag that is marked “dirty” whenever geometry, or cutting planes move. Note that camera movements don’t require recalculation. In that segment, Set_Heuristics(“no polygon handedness”) as well as Set_Heuristics(“concave faces”) should be used.

With the HIM_CUTTING_GEOMETRY_SHELL_BODY body_level, a particular user index set to a non-zero value has a special meaning. If the user index defined by H_SOLID_BODY_MAGIC (see htools.h in MVO) is set to something other than zero, everything in and underneath the segment with that index will be considered as part of the same solid body, and merged together. In case you’re curious, H_SOLID_BODY_MAGIC is defined as ((‘b’<<24) | (‘o’<<16) | (‘d’<<8) | (‘y’)), which works out to be 0x626f6479. So Set_User_Index( H_SOLID_BODY_MAGIC, 1 ) will cause everything underneath the currently open segment to get merged together as part of the same solid body.

Merging line pieces is asymptotically an O(n^2) operation, and the triangulation can also be quite expensive. Once they are in place, however the cutting geometry is drawn just as fast as if it had been part of the original model until something happens that triggers a recalculation. Segregating solids as much as possible by using the appropriate setting of the body_level argument of CreateCuttingGeometry will help with performance by keeping the “n” in the O(n^2) small.

Proper segregation helps in another way as well: colors. One solid body corresponds to at most one shell face for the capping polygon. The color that will be set on that shell face is the net face color from the segment in which the body was started. Inappropriate use of the H_SOLID_BODY_MAGIC user index at too high a segment can cause color settings from below to be missed, and consequently an inappropriate color applied to the capping polygon.

Under circumstances where only lines are needed, and it is known that the cutting lines will be quickly invalidated, there are two approaches that may perform better. The first is to use HIM_CUTTING_GEOMETRY_TYPE_LINES as the cutting type, which will save the effort of doing any merging. The second possibility is to bypass the HImCuttingGeometry class entirely, with Set_Visibility( “cut lines=on” ). Keep in mind, though, that those approaches are only for when it is known that the cutting lines will be quickly invalidated (since otherwise the upfront computational cost will pay off in future updates).

Numerical problems can create sets of lines that form “loops” with self-intersections. Triangulating such loops is a difficult problem, for which our current approach is not guaranteed to solve perfectly. As a consequence, there will, on occasion, be very thin slivers missing from the capping polygon. To help mitigate such numerical problems, two functions are provided to control the tolerances of a) the smallest feature that is to be considered valid; and b) the allowable distance between endpoints for a “closed” loop to be considered closed.

Public Functions

HImCuttingGeometry()

Constructs an HImCuttingGeometry object.

~HImCuttingGeometry()
void CreateCuttingGeometry(HC_KEY source_key, HC_KEY target_key, int cutting_type = HIM_CUTTING_GEOMETRY_TYPE_POLYLINES, int body_level = HIM_CUTTING_GEOMETRY_SEGMENT_BODY)

This method is the compute routine that uses HOOPS IM information during the process.

Parameters
  • source_key – The key to the root of the segment tree in which we want to find cutting geometry.

  • target_key – The key of the segment that is to contain the cutting geometry after completion.

  • cutting_type – Pass a HIMCG_Cutting_Type which is a bitmask of geometry types (HIM_CUTTING_GEOMETRY_TYPE_POLYLINES or HIM_CUTTING_GEOMETRY_TYPE_FACES) to be used for cutting geometry. HIM_CUTTING_GEOMETRY_TYPE_LINES=0 is a special value that indicates that lines should not be merged into polylines (and certainly not from there into faces). This saves on initial computation but is slightly slower. During draw time, the default is HIM_CUTTING_GEOMETRY_TYPE_POLYLINES.

  • body_level – This parameter determines what geometry should be considered to be part of the same solid body. Pass a HIMCG_Body_Type which can be either HIM_CUTTING_GEOMETRY_SEGMENT_BODY or HIM_CUTTING_GEOMETRY_SHELL_BODY. In the latter case, if there is a nonzero user index set at H_SOLID_BODY_MAGIC (e.g. with HC_Set_User_Index(H_SOLID_BODY_MAGIC,1) ), everything in and under that segment will be merged together.

void CreateCuttingGeometry(HC_KEY source_key, HC_KEY target_key, bool honor_modelling_matrices)

This method is the compute routine that uses a callback and newer 3dgs functionality.

Parameters
  • source_key – The key to the root of the segment tree in which we want to find cutting geometry.

  • target_key – The key of the segment that is to contain the cutting geometry after completion.

  • honor_modelling_matrices – Pass true to allow local transforms be applied to the cutting geometry or false not.

inline void SetSmallestFeature(float smallest_feature)

This feature has been deprecated. This method sets the smallest feature not culled away to avoid numerical problems.

Parameters

smallest_feature – Pass a float value defining the smallest feature. The default value is 0.001 * camera width.

inline float GetSmallestFeature()

This feature has been deprecated.

Returns

The smallest feature not culled away to avoid numerical problems.

inline void SetTolerance(float tolerance)

This method sets the distance between two points that may be considered a match for the purposes of assembling polylines and testing for closed loops.

Parameters

tolerance – Pass a float value that defines the range between two points for matching purposes. The default value is 0.1 * camera width.

inline float GetTolerance()
Returns

The largest distance between two points that may be considered a match for the purposes of assembling polylines and testing for closed loops.

Public Static Functions

static void RegisterCallbacks()

This method gives HOOPS pointers to the functions we are planning to have available. This function should be called just once, at the beginning of execution.