# Trimming, Subsetting, and Extending Geometry

Trimming and subsetting reduce the usable region of a curve or surface; extending enlarges it. Trimming a curve or surface divides it into multiple pieces and discards the unwanted pieces. Trimming permanently alters the underlying definition of the geometry. Subsetting does not alter the underlying definition. Subsetting merely specifies that a portion of a curve or surface is to be used by modeling algorithms, rather than the entire curve or surface. The reduced range of the curve or surface is commonly referred to as the subsetted range or subset range. Extending is the opposite of trimming. It enlarges the portion of a curve or surface that is defined. Unsubsetting (or unlimiting) is the opposite of subsetting. It removes the subset range associated with a curve or surface.

The figures below illustrate the effects of trimming, subsetting, and extending. The first figure, A Face on a Surface, depicts a face and its underlying surface. The second figure, A Face on a Trimmed Surface, depicts the same face on a surface that has been trimmed to the parameter range of the face. The third figure, A Face on a Subsetted Surface, depicts the same face on a surface that has been subsetted to the parameter range of the face. Notice that the full surface definition still exists, but algorithms use only the portion of the surface within the subset range. The fourth figure, A Face on an Extended Surface, depicts the same face on the trimmed surface that has been extended to a parameter range 60% larger than the original surface. In this particular case, the B-spline surface was naturally extended to the range of the original surface and then linearly extended to the desired range.

 A Face on a Surface A Face on a Trimmed Surface A Face on a Subsetted Surface A Face on an Extended Surface

Trimming, subsetting, extending, and unsubsetting geometry are considered low level operations that are typically part of a larger operation. Higher level operations that could potentially reduce or enlarge the used portion of a curve or surface (such as a Boolean or Local Operation) may perform trimming, subsetting, extending, or unsubsetting as a part of the operation. These low level operations do not have an API level interface. They must be accessed through Direct Interface functions. They are not intended for the casual user. Failure to maintain the proper relations among the ranges of EDGEs, COEDGEs, FACEs, curves, parameter space curves, and surfaces will corrupt the model.

## Trimming

As a result of a modeling operation a portion of a curve or surface may no longer be needed to support model topology, so the modeling operation may elect to reduce the range of the curve or surface. One way to reduce the range of a curve or surface is to reduce the range of its underlying definition. This is referred to as trimming or splitting the geometry. Because trimming reduces the underlying definition of a curve or surface, it can reduce the amount of memory or disk space associated with a curve or surface. Curve splitting is performed by the curve::split member function. straights, ellipses, and helixs cannot be split: only intcurves can be split. Similarly, analytic surfaces cannot be split: only splines can be split. spline splitting is performed by spline::split_u and spline::split_v. (To be more precise, only some flavors of splines can be split. "Exact" B-spline surfaces can be split and some procedural surfaces can be split. If a particular spline cannot be split, it is recommended that it be subsetted instead.)

A slightly higher level, Direct Interface function for trimming the surface underlying a face to the range needed to support the face is void trim_face(FACE *this_face, char const * subset_option = NULL). This function may either trim or subset the surface, or elect to do neither. The "trim versus subset" behavior is controlled by the subset_option argument or the subsetting global option, as described below in Subsetting Option. (Passing the subset_option argument allows one to override the subsetting option.) Although this function may attempt to split various surface types, only splines are splittable. (All surface types are subsettable.) The default behavior of this function (that is, the default value of the subsetting option) is to subset splines, rather than trim them.

A similar Direct Interface function for trimming the curves and pcurves underlying an edge to the range needed by the edge is void trim_edge(EDGE *this_edge). This function attempts to subset curves and trim pcurves. trim_edge and trim_face are used by higher level modeling functions to provide a consistent interface to trimming and subsetting of geometry.

There are API level functions to split an EDGE or FACE and possibly the geometry underlying them. These are api_split_curve and api_split_face. These functions are the preferred interface for application developers who need to reduce the extents of an edge or face.

## Subsetting

Subsetting reduces the extents of a curve or surface without altering the underlying definition. Unlike trimming, subsetting cannot reduce the amount of memory or disk space used by geometry, but by reducing the extents of the curve or surface it provides the same efficiency advantages as trimming. In fact, subsetting can provide efficiency advantages over trimming. For example, merging two subsetted surfaces that have the same underlying definition is simply a matter of combining their subset ranges; whereas, merging the same two surfaces if they had been trimmed would be much more computationally difficult. Comparisons and operations on subsetted geometry with the same underlying definitions is much more efficient, and accurate, than the same operations on trimmed geometry. For this reason, subsetting is generally preferred over trimming.

Class methods are used to subset a curve or surface, change its subset range, or revert to the original (unsubsetted) curve or surface definition.

### Subsetting (and Unsubsetting) Curves

Listed below are the most commonly used curve member functions to subset, unsubset, and querying about the subsetting of a curve.

To subset a curve in place:

`void curve::limit (const SPAinterval & range)`

To construct a subsetted copy of a curve:

`curve * curve::subset (const SPAinterval &range) const`

To remove subsetting from a curve:

`void curve::unlimit ()`

To determine if a curve has been subsetted:

`logical curve::subsetted () const`

To determine the range of a subsetted curve:

`SPAinterval curve::param_range (const SPAbox &region=*(SPAbox *) NULL_REF) const`

Note: curve::param_range returns the parameter range of a curve. If the curve has been subsetted, it is the subsetted range. If the curve has not been subsetted, it is the unsubsetted range.

Subsetting a curve can change its form. A periodic curve can become closed or open. (If a periodic curve is subsetted to a range with a length of one period, it will become closed. If the range is less than one period, it will become open.) A closed curve can become open. An open curve will remain open, even if it is subsetted. It will not change form.

### Subsetting (and Unsubsetting) Surfaces

The most commonly used member functions to subset, unsubset, and query about the subsetting of a surface are listed below.

To subset a surface in place:

```void surface::limit (const SPApar_box & box)
void surface::limit_u (const SPAinterval & u_range)
void surface::limit_v (const SPAinterval & v_range)```

To construct a subsetted copy of a surface:

```surface * surface::subset (const SPApar_box &box) const
surface * surface::subset_u (const SPAinterval &range) const
surface * surface::subset_v (const SPAinterval &range) const```

To remove subsetting from a surface:

```void surface::unlimit ()
void surface::unlimit_u ()
void surface::unlimit_v ()```

To determine if a surface has been subsetted:

```logical surface::subsetted () const
logical surface::subsetted_u () const
logical surface::subsetted_v () const```

To determine the range of a subsetted surface:

```SPApar_box surface::param_range (const SPAbox &region=*(SPAbox *) NULL_REF) const
SPAinterval surface::param_range_u (const SPAbox &region=*(SPAbox *) NULL_REF) const
SPAinterval surface::param_range_v (const SPAbox &region=*(SPAbox *) NULL_REF) const```

Note: surface::param_range, surface::param_range_u, and surface::param_range_v return the principal parameter range of a surface. If the surface has been subsetted, it is the subsetted range. If the surface has not been subsetted, it is the unsubsetted range.

To obtain the subset range of a surface:

```SPApar_box surface::subset_box() const
SPAinterval surface::subset_u_interval() const
SPAinterval surface::subset_v_interval() const```

Note: surface::subset_box, surface::subset_u_interval, and surface::subset_v_interval return the subset range of a surface. If the surface has not been subsetted, its range is infinite. The primary purpose of these functions is to obtain the subset range before unlimiting the surface, allow the subset range to be subsequently reapplied.

Subsetting a surface can change its form. A periodic surface can become closed or open. (If a periodic surface is subsetted to a range with a length of one period, it will become closed. If the range is less than one period, it will become open.) A closed surface can become open. An open surface will remain open, even if it is subsetted. It will not change form.

### Subsetting Option

The option subsetting allows the application developer to control of "trimming versus subsetting" during trim_face, which is used by high level API functions to trim or subset the surfaces underlying faces. The subsetting of curves is not controlled by an option. There are four valid values of this option. The default value of this option is "spline".

Option Value Meaning
"all" subset both splines and tori, ignore all others
"spline" subset splines only, ignore all other types
"torus" subset tori only, trim splines, ignore all others
"none" do not subset any surface type, trim splines

### Isoparameter Curves on Subsetted Surfaces

If a surface is subsetted, it does not span the entire range of the underlying, defining surface. Isoparameter curves on such a subsetted surface should not span the entire defining surface either. The methods to generate isoparameter curves on surfaces take this reduced range into consideration.

### Parameter Values on Subsetted Geometry

If an intcurve is closed, there are two valid parameter values for a position on the seam of the curve. If the curve is subsetted such that one of the ends is not in the subset range, then there is only one valid parameter value. The intcurve method param returns the corrected parameter value when the intcurve has been subsetted in this manner.

This philosophy also holds for spline surfaces. If a spline surface is closed, two sets of parameter values correspond to the seam. (If a seam edge exists, the two sets of parameter values can be observed in the pcurves associated with the coedges of the seam edge.) If the surface is subsetted such that one of the sets of parameter values is not in the subset range, then only one valid set of parameter values corresponding to the seam edge and the inverse evaluation functions of the spline class take this into account.

## Extending

Many functions within ACIS require the enlargement of curves and surfaces. For example, the Blending end capping algorithm and Local Operations must extend curves and surfaces to successfully complete their operations. Generally this is done by extending the natural definition of the entity and extending any supporting curves or surfaces as necessary. For example, the extension of an offset intersection curve defining the spine of a blend is done by extending the two surfaces that define the curve and intersecting them. Typically B-spline curves and surfaces are extended by adding a tangential straight line or a tangential ruled surface, respectively. B-spline curves and surfaces extended in this manner are examples of geometry that is only C1 continuous. It is also possible to create natural extensions to B-spline curves and surfaces.

### Extending Curves

Straight and elliptical curves have a default parameter range that cannot be extended. They can only be unsubsetted. intcurves and helixes however, can be extended using the global function, extend_curve. The example below demonstrates how this function could be used to extend the parameter range of an intcurve by 2 percent. By default, a smaller extension will be returned if the requested extension is improper. Clients should check the returned achieved parameter interval to confirm if it is adequate for the work flow.

```curve & cur = some_intcurve;
SPAinterval old_range = cur.param_range();
double old_range_length = old_range.length()
double delta = 0.01 * old_range_length;
SPAinterval requested_range = enlarge_interval(old_range, delta);
SPAinterval achieved_range = extend_curve(cur, requested_range);
// code to check if achieved_range is adequate for work flow```

Note: Curve extensions should be minimal, because curve extensions can have unexpected behavior. For instance, extending a curve can create regions of very high curvature or cause the curve to self-intersect.

Note: The change to the curve in the example above would not be recorded by the history mechanism. To have this operation recorded by the history mechanism, you would need to construct a new INTCURVE and, most likely, change the CURVE underlying an EDGE, or construct a new EDGE using the new INTCURVE.

Note: The Scheme extension for extending an edge, edge:extend, demonstrates the use of extend_curve.

Natural extensions to B-spline curves can be created using the Spline Interface function bs3_curve_natural_ext. It is, however, preferable to use higher level Direct Interface or API functions. For instance, to construct a new EDGE that is an extended copy of an existing EDGE, you can use EDGE *extend_edge(EDGE *edge, double new_start_param, double new_end_param).

### Extending Surfaces

Analytic surfaces have a default parameter range that cannot be extended. They can only be unsubsetted. spline surfaces can, however, be extended using the global function, extend_surface. The example below demonstrates how this function could be used to extend the v-parameter range of a spline surface by 2 percent. By default, a smaller extension will be returned if the requested extension is improper. Clients should check the returned achieved parameter box to confirm if it is adequate for the work flow.

```surface & surf = some_spline;
SPApar_box surf_box = surf.param_range();
SPAinterval requested_u_range = surf_box.u_range();
SPAinterval old_v_range = surf_box.v_range();
double old_v_range_length = old_v_range.length()
double delta = 0.01 * old_v_range_length;
SPAinterval requested_v_range = enlarge_interval(old_v_range, delta);
SPApar_box achieved_par_box = extend_surface(surf, SPApar_box(requested_u_range, requested_v_range));
// code to check if achieved_par_box is adequate for work flow```

Note: Surface extensions should be minimal, because surface extensions can have unexpected behavior. For instance, extending a surface can create regions of very high curvature or cause the surface to self-intersect.

Note: The change to the surface in the example above would not be recorded by the history mechanism. To have this operation recorded by the history mechanism, you would need to construct a new SPLINE surface and, most likely, change the SURFACE underlying a FACE, or construct a new FACE using the new SPLINE.

Note: The Scheme extension for extending a face, face:extend, demonstrates the use of extend_surface. The surface depicted in A Face on an Extended Surface was created using face:extend on the surface depicted in A Face on a Trimmed Surface.

Natural extensions to B-spline surfaces can be created using the Spline Interface function bs3_surface_natural_ext. Generally speaking, it is preferable to use higher level, API functions that operate on a FACE or set of FACEs, such as those available in Local Operations, rather than Direct Interface functions such as extend_surface.