Purpose:
|
Defines a skin surface between a list of curves.
|
|
Derivation:
|
skin_spl_sur : spl_sur : subtrans_object : subtype_object : ACIS_OBJECT : -
|
|
SAT Identifier:
|
"skinsur"
|
|
Filename:
|
kern/kernel/sg_husk/skin/skin_spl.hxx
|
|
Description:
|
This class defines a skin surface between a list of curves.
|
|
|
Surface Parameterization
|
|
|
The surface parameterization is the
u-direction corresponds to the parameterization of the curves to be skinned and the
v-direction corresponds to the cubic Bezier between the skin-curves.
|
|
|
The input to this surface class are the curves to be skinned (all the curves are reparameterized to lie in [0.0 - 1.0] range), optional tangents (the magnitude of the curves' tangents have to match on the ends) in
u-direction, and the optional surfaces on which the curves lie. If surfaces containing the curves are provided, these determine the tangent directions in
v.
|
|
|
Evaluation Process
|
|
|
The evaluation process is a three-step process, as described below.
|
|
|
Step 1
|
|
|
If any matching tangent magnitudes are given, the section curves (curves to be skinned) are reparameterized as follows: parameter t is the parameter on the original curve. Parameter
u on the skin surface is determined such that the
u-partial at each end of the skin surface is equal to the matching tangent magnitude.
|
|
|
t = f(u) =
|
ts*H0(u) + m0*H1(u) + m1*H2(u) +
|
|
|
|
|
te*H3(u)
|
|
|
In the above expression,
Hn are the
cubic Hermite polynomials and
ts and
te are the start and end parameter values of the original curves to be skinned, which here are 0 and 1, respectively.
|
|
|
So,
ds/du on the ends are:
|
|
|
dc/du = dc/dt * dt/du
|
|
|
where the
dt/du values on the ends are
m0 and
m1.
|
|
|
So by choosing the values
m0 and
m1 such that the dc/du on the left surface is equal to
dc/du on the right surface (provided that the curves are G1), a C1 continuous surface is achieved even when skinning G1 continuous curves.
|
|
|
Step 2
|
|
|
The tangent directions for the
v are determined by fitting a circle through the points corresponding to the same
u-value on the adjacent section curves to the left and right. The scheme followed is similar to the way Bessel tangents are computed. If there are only two section curves, the circle radius is chosen to be infinity. If the surfaces are given for any section, the tangent direction in
v when on that curve is obtained by the cross product of surface normal and the section curve tangent at that point. The direction also has an optional scalar value that can be applied. The surface is called a loft surface when such a surface is provided.
|
|
|
Step 3
|
|
|
Now the skin/loft surface is defined using cubic Hermite interpolants between sections that join each other C1 continuously. To evaluate the surface
s(u,v) at a particular
v-parameter, the first step is to find the segment to which this parameter corresponds. Then a local parameter
vi is computed, which ranges from 0 to 1. The section curves
ci and
ci+1, and the
v-tangents
ti and
ti+1 are also obtained. The surface is defined as:
|
|
|
s(u,v) =
|
ci(u)*H0(vi) + ti*H1(vi) + ti+1*H2(vi) +
|
|
|
|
|
ci+1*H3(vi)
|
|
|
The parametric derivatives of this surface are obtained by differentiating the above equation algebraically.
|
|
References:
|
KERN
|
pcurve, surface
|
|
BASE
|
SPAvector
|
|
LAW
|
law
|
|
Data:
|
protected VOID_LIST curves;
|
|
The list of curves to be skinned.
|
|
|
protected VOID_LIST path_curves;
|
|
Array of curves used to define the path for skinning.
|
|
|
protected int no_path_crv;
|
|
Value specifies how many path curves are in entity list.
|
|
|
protected law **laws;
|
|
Array of laws used to define how skinning is performed.
|
|
|
protected double *deriv_cache;
|
|
Section mapping information.
|
|
|
protected double *matching_derivs;
|
|
Section mapping information.
|
|
|
protected double *tan_factors;
|
|
An array of factors applied to the cross boundary tangents.
|
|
|
protected double *v_knots;
|
|
An array of reals indicating the knot values at each section that is being interpolated.
|
|
|
protected int no_crv;
|
|
The number of curves to be skinned.
|
|
|
protected pcurve **pcurves;
|
|
Pcurves corresponding to the curves and surfaces are stored.
|
|
|
protected logical arc_length_param;
|
|
Flag for using arc-length parameterization. When set, arc-length parameterization is used. When clear, arc-wise parameterization is used.
|
|
|
protected logical perpendicular_option;
|
|
Flag for the loft direction. When set, it is perpendicular to the curve; when clear, it is in the curve direction.
|
|
|
protected logical skin_2p1_surface;
|
|
Flag to indicate this is an old skin surface.
|
|
|
protected surface **surfaces;
|
|
An array of pointers to the surface. The curves that are skinned lie on these surfaces and the surfaces are used to obtain cross boundary tangents. If this is
NULL, the cross boundary tangents are calculated on the fly.
|
|
|
protected skin_data *surface_data;
|
|
Data cache for computing the optimal tangent factors for the skin surface.
|
|
|
protected SPAvector *tangents;
|
|
An array of cross-boundary tangents. If these are
NULL, the tangents at each point are calculated on the fly.
|
|
Constructor:
|
protected: skin_spl_sur::skin_spl_sur
();
|
|
|
C++ allocation constructor requests memory for this object but does not populate it.
|
|
|
|
|
|
|
public: skin_spl_sur::skin_spl_sur
(
|
|
|
const skin_spl_sur&
|
// surface to copy
|
|
|
);
|
|
|
C++ copy constructor requests memory for this object and populates it with the data from the object supplied as an argument.
|
|
|
|
|
Destructor:
|
protected: virtual skin_spl_sur::~skin_spl_sur
();
|
|
|
C++ destructor, deleting a
skin_spl_sur.
|
|
|
|
Methods:
|
public: int skin_spl_sur::accurate_derivs
(
|
|
|
SPApar_box const&
|
|
// area for deriv
|
|
|
|
= * (SPApar_box* ) NULL_REF
|
|
|
) const;
|
|
|
Calculates the derivatives within the given parameter box.
|
|
|
|
|
|
|
public: void skin_spl_sur::add_path_data
(
|
|
|
int no_curves,
|
// number of curves in
|
|
|
|
|
// path
|
|
|
curve** curves
|
// curve paths to add
|
|
|
);
|
|
|
Adds the path data to the
skin_spl_sur object.
|
|
|
|
|
|
|
protected: virtual void
|
|
skin_spl_sur::calculate_disc_info ();
|
|
|
Calculates the discontinuity information from the defining curves.
|
|
|
|
|
|
|
protected: virtual subtrans_object*
|
|
|
skin_spl_sur::copy () const;
|
|
|
Constructs a duplicate
skin_spl_sur in free storage of this object, with a zero use count.
|
|
|
|
|
|
|
protected: void
|
|
|
skin_spl_sur::curve_add_discontinuities ();
|
|
|
Calculates discontinuity information from the generating curves and adds it to the skin surface.
|
|
|
|
|
|
|
protected: virtual void skin_spl_sur::debug
(
|
|
|
char const*,
|
// leader string
|
|
|
logical,
|
// brief output OK?
|
|
|
FILE*
|
// output pointer
|
|
|
) const;
|
|
|
Prints out a class-specific identifying line to standard output or to the specified file.
|
|
|
|
|
|
|
protected: void skin_spl_sur::debug_data
(
|
|
|
char const*,
|
// leader string
|
|
|
logical,
|
// brief output ok?
|
|
|
FILE*
|
// output pointer
|
|
|
) const;
|
|
|
Prints out the details. The
debug_data derived class can call its parent's version first, to put out the common data. If the derived class has no additional data it need not define its own version of
debug_data and may use its parent's instead. A string argument provides the introduction to each displayed line after the first, and a logical sets brief output (normally removing detailed subsidiary curve and surface definitions).
|
|
|
|
|
|
|
public: virtual spl_sur* skin_spl_sur::deep_copy
(
|
|
|
pointer_map* pm
|
// list of items within
|
|
|
|
= NULL
|
// the entity that are
|
|
|
|
|
// already deep copied
|
|
|
) const;
|
|
|
Creates a copy of an item that does not share any data with the original. Allocates new storage for all member data and any pointers. Returns a pointer to the copied item.
|
|
|
In a
deep copy, all the information about the copied item is self-contained in a new memory block. By comparison, a
shallow copy stores only the first instance of the item in memory, and increments the reference count for each copy.
|
|
|
The
pointer_map keeps a list of all pointers in the original object that have already been deep copied. For example, a
deep_copy of a complex model results in self contained data, but identical sub-parts within the model are allowed to share a single set of data.
|
|
|
|
|
|
|
public: double
|
|
|
skin_spl_sur::estimate_min_rad_curv ();
|
|
|
This function estimates the minimum radius of curvature of the skin surface for a given set of tangent factor values.
|
|
|
|
|
|
|
public: void skin_spl_sur::estimate_tanfacs_scale
(
|
|
|
SPAinterval& tan_range
|
|
// range to use
|
|
|
);
|
|
|
Estimates the scaling factor range by which the tangent factors controlling the skin surface should be scaled so as to get the surface with as large a radius of curvature as possible.
|
|
|
|
|
|
|
protected: virtual void skin_spl_sur::eval
(
|
|
|
SPApar_pos const& uv,
|
// param space location
|
|
|
SPAposition& pos,
|
// returned point
|
|
|
SPAvector* dpos,
|
// first derivatives
|
|
|
SPAvector* ddpos
|
// second derivatives
|
|
|
) const;
|
|
|
Finds the position and the first and second derivatives of the surface at a specified point.
dpos is of length 2,
ddpos is of length 3. Upon return,
dpos contains
xu and
xv.
ddpos contains
xuu,
xuv,
xvv.
|
|
|
|
|
|
|
protected: virtual int skin_spl_sur::evaluate
(
|
|
|
SPApar_pos const&,
|
|
|
// parameter on
|
|
|
|
|
|
|
// surface point
|
|
|
SPAposition&,
|
|
|
// for deriv
|
|
|
SPAvector**
|
|
|
// first
|
|
|
|
= NULL,
|
|
|
// derivative
|
|
|
int
|
|
|
// second
|
|
|
|
= 0,
|
|
|
// derivative
|
|
|
evaluate_surface_quadrant
|
|
// quadrant of
|
|
|
|
= evaluate_surface_unknown
|
// discontinuity
|
|
|
|
|
|
|
// to evaluate
|
|
|
) const;
|
|
|
The evaluate function calculates derivatives, of any order up to the number requested, and stores them in vectors provided by the user. It returns the number it was able to calculate; this will be equal to the number requested in all but the most exceptional circumstances. A certain number will be evaluated directly and (more or less) accurately; higher derivatives will be automatically calculated by finite differencing; the accuracy of these decreases with the order of the derivative, as the cost increases.
|
|
|
|
|
|
|
protected: void skin_spl_sur::eval_2p1_skin
(
|
|
|
SPApar_pos const& uv,
|
// param space location
|
|
|
SPAposition& pos,
|
// returned point
|
|
|
SPAvector* dpos,
|
// first derivatives
|
|
|
SPAvector* ddpos
|
// second derivatives
|
|
|
) const;
|
|
|
Finds the position and first and second derivatives of the
ACIS 2.1 skin surface at a given point.
|
|
|
|
|
|
|
protected: void skin_spl_sur::eval_skin
(
|
|
|
SPApar_pos const& uv,
|
// parameter on surface
|
|
|
SPAposition& pos,
|
// point for deriv
|
|
|
SPAvector* dpos,
|
// first deriv. array of
|
|
|
|
|
// length 2 in order
|
|
|
|
|
// xu, xv
|
|
|
SPAvector* ddpos,
|
// second deriv. array of
|
|
|
|
|
// length 3 in order
|
|
|
|
|
// xuu, xuv, xvv
|
|
|
SPAvector* dddpos,
|
// third deriv. array of
|
|
|
|
|
// length
|
|
|
evaluate_surface_quadrant
|
// which quadrant to
|
|
|
|
quadrant
|
|
// evaluate
|
|
|
) const;
|
|
|
Finds the position and first and second derivatives of the skin surface at the given parameter position value.
|
|
|
|
|
|
|
public: void skin_spl_sur::get_curves
(
|
|
|
int& no_crv,
|
// number of curves
|
|
|
curve** *curves
|
// output array pointer
|
|
|
) const;
|
|
|
Returns the surface curves.
|
|
|
|
|
|
|
public: void skin_spl_sur::get_laws
(
|
|
|
int& no_laws,
|
// number of laws
|
|
|
law**& laws
|
// list of laws pointer
|
|
|
) const;
|
|
|
Returns a list of laws used by the
skin_spl_sur. The use count of the laws is incremented by one.
|
|
|
|
|
|
|
public: void skin_spl_sur::get_surfaces
(
|
|
|
int& no_surfaces,
|
// number of surfaces
|
|
|
surface**& surf_arr
|
// surface array pointer
|
|
|
) const;
|
|
|
Returns the surfaces. The array of surfaces need to be deleted by the calling routine.
|
|
|
|
|
|
|
|
public: void skin_spl_sur::get_tanfacs
(
|
|
|
double* tangents
|
// tangent factors
|
|
|
);
|
|
|
Get the tangent factors to determine optimal values for them.
|
|
|
|
|
|
|
public: void skin_spl_sur::get_v_knots
(
|
|
|
double u,
|
// u parameter
|
|
|
int& out_no_knots,
|
// number of knots
|
|
|
double** out_vknots
|
// output array pointer
|
|
|
) const;
|
|
|
Returns the v_knot sequence for a given parameter value.
|
|
|
|
|
|
|
public: static int skin_spl_sur::id
();
|
|
|
Returns the ID for the
skin_spl_sur list.
|
|
|
|
|
|
|
protected: void skin_spl_sur::initialize
();
|
|
|
Initializes the member data for this class.
|
|
|
|
|
|
|
protected: virtual void skin_spl_sur::make_approx
(
|
|
|
double fit,
|
|
// fit tolerance
|
|
|
const spline& spl
|
|
// pointer to output
|
|
|
|
= * (spline*) NULL_REF,
|
// approximation
|
|
|
logical force
|
|
// flag for forcing
|
|
|
|
= FALSE
|
|
|
) const;
|
|
|
Makes or remakes an approximation of the
skin_spl_sur, within the given tolerance.
|
|
|
|
|
|
|
public: static spl_sur*
|
|
|
skin_spl_sur::make_skin_spl_sur (
|
|
|
logical,
|
// arc-length option
|
|
|
int,
|
// number of curves
|
|
|
curve**,
|
// array of curves
|
|
|
double*,
|
// array of knot values
|
|
|
double*,
|
// array of left tangents
|
|
|
double*,
|
// array of rt tangents
|
|
|
SPAvector*
|
// array of tangent dirs.
|
|
|
|
= (SPAvector* ) NULL,
|
|
|
closed_forms
|
// Flag for periodicity
|
|
|
|
= OPEN,
|
// of surface in u
|
|
|
closed_forms
|
// Flag for periodicity
|
|
|
|
= OPEN
|
// of surface in v
|
|
|
);
|
|
|
Constructs a skin surface from the given section curves and the optional matching tangents.
|
|
|
|
|
|
|
public: static spl_sur*
|
|
|
skin_spl_sur::make_skin_spl_sur (
|
|
|
logical,
|
// arc-length flag
|
|
|
logical,
|
// perpendicular flag
|
|
|
int,
|
// # section curves
|
|
|
curve**,
|
// array of curves
|
|
|
double*,
|
// array of knot values
|
|
|
double*,
|
// array of left tangents
|
|
|
double*,
|
// right tangents array
|
|
|
surface**,
|
// array of surfaces
|
|
|
double*,
|
// cr-bnd tangents array
|
|
|
law**,
|
// array of laws
|
|
|
closed_forms
|
// Flag for periodicity
|
|
|
|
= OPEN,
|
// of surface in u
|
|
|
closed_forms
|
// Flag for periodicity
|
|
|
|
= OPEN
|
// of surface in v
|
|
|
);
|
|
|
Constructs a loft surface from the given section curves and the corresponding surfaces on which the sections lie and the optional tangent factors that should be applied to cross-boundary tangents. The surfaces are passed in are owned by the
skin_surface, so the user should pass in a copy. All arrays are the size of
int, the number of sections.
|
|
|
|
|
|
|
protected: virtual void skin_spl_sur::operator*=
(
|
|
|
SPAtransf const&
|
// transformation
|
|
|
);
|
|
|
Transforms this surface by the specified transform.
|
|
|
|
|
|
|
protected: logical skin_spl_sur::operator==
(
|
|
|
subtype_object const&
|
// object sub-type
|
|
|
) const;
|
|
|
Tests for equality. This does not guarantee to find all effectively equal surfaces, but it does guarantee that different surfaces are correctly identified as different.
|
|
|
|
|
|
|
protected: virtual SPApar_pos skin_spl_sur::param
(
|
|
|
SPAposition const&,
|
// given point
|
|
|
SPApar_pos const&
|
// guess value
|
|
|
|
= * (SPApar_pos* ) NULL_REF
|
|
|
) const;
|
|
|
Finds the parameter values of a point on a 3D B-spline surface, iterating from the given parameter values, if supplied.
|
|
|
|
|
|
|
protected: void skin_spl_sur::restore_data
();
|
|
|
Restore the data for a
skin_spl_sur from a save file.
|
|
|
if (restore_version_number >= ARCWISE_SKIN_VERSION )
|
|
read_logical
|
// skin_2p1_surface, "FALSE" or "TRUE"
|
|
read_logical
|
// arc length parameter, "ISO" or "ARC"
|
|
read_logical
|
// perpendicular option, "SKIN" or "PERPENDICULAR"
|
|
read_int
|
// number of curves
|
|
for( int i = 0; i < no_crv; i ++ ) {
|
// for each curve
|
|
read_real
|
// tangent length at start of curve or -1
|
|
read_real
|
// tangent length at end of curve or -1
|
|
read_real
|
// matching tangent length at start of curve or -1
|
|
read_real
|
// matching tangent length at end of curve or -1
|
|
read_real
|
// v knots
|
|
restore_curve
|
// restore the underlying curve
|
|
read_vector
|
// tangent vector
|
|
restore_surface
|
// underlying surface
|
|
read_real
|
// tangent factor
|
|
if (restore_version_number >= LOFT_LAW_VERSION )
|
|
|
restore_law
|
// restore law definition if available
|
|
if (restore_version_number >= LOFT_PCURVE_VERSION )
|
|
|
restore_pcurve
|
// restore pcurve definition if available
|
|
if (restore_version_number >= LOFT_LAW_VERSION ) {
|
|
|
read_int
|
// number of path curves
|
|
for(int i = 0; i < no_path_crv; i ++ ) // for each path curve
|
|
|
restore_curve
|
// restore path curve to be skinned or lofted
|
|
spl_sur::restore_common_data
|
Restore the rest of the surface
|
|
|
|
|
|
|
public: virtual void skin_spl_sur::save
() const;
|
|
|
Saves the
skin_spl_sur as an approximation if there is a need to approximate.
|
|
|
|
|
|
|
public: virtual void
|
|
|
skin_spl_sur::save_data () const;
|
|
|
Saves the information for
skin_spl_sur to the save file.
|
|
|
|
|
|
|
|
public: void skin_spl_sur::set_tanfacs
(
|
|
|
double* tangents,
|
// tangent factors
|
|
|
logical remake_approx
|
// remake enabled
|
|
|
|
= TRUE
|
// or not
|
|
|
);
|
|
|
Set the tangent factors and get them for purposes of determining optimal values for them.
|
|
|
|
|
|
|
protected: virtual void skin_spl_sur::shift_u
(
|
|
|
double
|
// shift value
|
|
|
);
|
|
|
Adjusts the spline surface to have a parameter range increased by the shift value, which may be negative. This method is only used to move portions of a periodic surface by integral multiples of the period.
|
|
|
|
|
|
|
protected: virtual void skin_spl_sur::shift_v
(
|
|
|
double
|
// shift value
|
|
|
);
|
|
|
Adjusts the spline surface to have a parameter range increased by the shift value, which may be negative. This method is only used to move portions of a periodic surface by integral multiples of the period.
|
|
|
|
|
|
|
protected: virtual void skin_spl_sur::split_u
(
|
|
|
double,
|
// u-parameter value
|
|
|
spl_sur* [ 2 ]
|
// two spline surfaces
|
|
|
);
|
|
|
Divides a surface into two pieces at the
u-parameter value.
|
|
|
|
|
|
|
protected: virtual void skin_spl_sur::split_v
(
|
|
|
double,
|
// v-parameter value
|
|
|
spl_sur* [ 2 ]
|
// two spline surfaces
|
|
|
);
|
|
|
Divides a surface into two pieces at the specified
v-parameter value.
|
|
|
|
|
|
|
public: virtual int skin_spl_sur::type
() const;
|
|
|
Returns the type of
skin_spl_sur.
|
|
|
|
|
|
|
public: virtual char const*
|
|
|
skin_spl_sur::type_name () const;
|
|
|
Returns the string of the given spline surface type, which is "skinsur" for a
skin_spl_surf.
|
|
Internal Use:
|
arclength_index_end, arclength_index_general, arclength_index_start, calculate_arcwise_data, calculate_iso_data, compute_bernstein_polynomials, deep_copy_elements_skin, full_size, remap_and_eval, sg_calculate_surface_normal_dervs, sg_recalculate_vknots_and_dervs
|
|
|
|
|
Related Fncs:
|
restore_skin_spl_sur
|