skin_spl_sur
List of: Classes
Subjects: Construction Geometry, SAT Save and Restore, Skinning and Lofting
Contents: Kernel

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
PDF/KERN/36CLSA.PDF
HTM/DATA/KERN/KERN/36CLSA/0004.HTM