ValueFunctionPressure Class Reference

#include <valfunc.h>

Inheritance diagram for ValueFunctionPressure:

ValueFunction ListItem CCObject SimpleCCObject ValueFunctionPressureS List of all members.

Public Member Functions

 ValueFunctionPressure ()
 Constructor Pressure functions store a table of recorded pressure values and return curve-interpolated pressure values on demand.
 ~ValueFunctionPressure ()
 Destructor.
virtual double GetValue (double Position)
 To read the value of this function at a given position.
virtual ValueFunctionClone (void)
 Clone operator. Creates an exact copy of this object.
virtual BOOL IsDifferent (ValueFunction *pOther)
 Comparator. Determines if 2 different ValueFunction objects are considered different.
BOOL AddPressure (float Position, float PressureValue)
 Adds a pressure record to the ValueFunction table.
void NormalisePositions (void)
 Normalises all positions in the table to lie within a 0.0 to 1.0 range, by dividing them by the last element position value. (i.e. it assumes that the last element in the array will have the largest Position value).
virtual CamelotFileRecordWriteFileRecord (INT32 RecordTag, INT32 ExtraBytes, BaseCamelotFilter *pFilter)
 Saves a ValueFunction object to a Xara file. This function will create a new variable-sized record with the given record tag, and will write out whatever data is needed to save this ValueFunction's state to the file.
virtual ValueFunctionID GetUniqueID (void)

Protected Member Functions

virtual ValueFunctionCreateAndReadFileRecord (CXaraFileRecord *pInputRecord)
 Loads a ValueFunction object from a record which was saved into a file using the WriteFileRecord call. This is called by the base class loader routine ReadFileRecord, which finds an appropriate instance of a derived class to call to load the data in question.
BOOL ExpandArray (INT32 NewSize)
 Ensures that the pressure storage array has no fewer than NewSize entries.
virtual ValueFunctionPressureCreateInstance (void)
 Creates a new blank object of the same type as this one. Internal function used in ValueFunctionPressure & ValueFunctionPressureS.

Protected Attributes

VFPressureRecordpArray
INT32 ArraySize
INT32 NextFree

Private Member Functions

 CC_DECLARE_DYNAMIC (ValueFunctionPressure)

Detailed Description

Definition at line 854 of file valfunc.h.


Constructor & Destructor Documentation

ValueFunctionPressure::ValueFunctionPressure  ) 
 

Constructor Pressure functions store a table of recorded pressure values and return curve-interpolated pressure values on demand.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/1/97

Definition at line 2820 of file valfunc.cpp.

02821 {
02822     pArray      = NULL;
02823     ArraySize   = 0;
02824     NextFree    = 0;
02825 }

ValueFunctionPressure::~ValueFunctionPressure  ) 
 

Destructor.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/1/97

Definition at line 2840 of file valfunc.cpp.

02841 {
02842     if (pArray != NULL)
02843         CCFree(pArray);
02844 }


Member Function Documentation

BOOL ValueFunctionPressure::AddPressure float  Position,
float  PressureValue
 

Adds a pressure record to the ValueFunction table.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/1/97
Parameters:
Position - A number representing distance along the path of this point [INPUTS] (Normally this would be between 0.0 and 1.0, but you can temporarily use positions between 0.0 and any positive value and then call NormalisePositions if this is more convenient while building the table)
NOTE: Each added pressure value must be a positive number, and must be greater than the last in order to be recorded. Illegal values will be discarded.

PressureValue - The pressure value to record for this position

Returns:
FALSE if memory was unavailable TRUE if it was happy (even if it discarded the value)

Definition at line 3027 of file valfunc.cpp.

03028 {
03029     ERROR3IF(PressureValue < 0.0 || PressureValue > 1.0, "Illegal pressure value");
03030     ERROR3IF(Position < 0.0, "Illegal (negative) position value");
03031 
03032     // Make sure there's plenty of room for new entries
03033     if (NextFree >= ArraySize && !ExpandArray(ArraySize + 32))
03034         return(FALSE);
03035 
03036     // Only record the value if the position has advanced. Error if the position has
03037     // gone retrograde, but quietly dismiss equal positions.
03038     ERROR3IF(NextFree > 0 && Position < pArray[NextFree-1].Position,
03039                 "AddPressure - pressure values must be ascending");
03040     if (NextFree > 0 && Position <= pArray[NextFree-1].Position)
03041         return(TRUE);
03042 
03043     // And write this entry
03044     pArray[NextFree].Position = Position;
03045     pArray[NextFree].Pressure = PressureValue;
03046     NextFree++;
03047 
03048     return(TRUE);
03049 }

ValueFunctionPressure::CC_DECLARE_DYNAMIC ValueFunctionPressure   )  [private]
 

ValueFunction * ValueFunctionPressure::Clone void   )  [virtual]
 

Clone operator. Creates an exact copy of this object.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/1/97
Returns:
NULL if it failed, else an exact copy of this object

Implements ValueFunction.

Definition at line 2932 of file valfunc.cpp.

02933 {
02934     // Create another object of this type
02935     ValueFunctionPressure *pClone = CreateInstance();
02936 
02937     if (pClone != NULL)
02938     {
02939         // If that worked, make it allocate an array large enough to hold a copy of
02940         // our data, and memcpy the array across.
02941         if (pClone->ExpandArray(NextFree))
02942         {
02943             // We only copy the used array entries so the clone will have no wasted space in it
02944             memcpy(pClone->pArray, pArray, NextFree * sizeof(VFPressureRecord));
02945             pClone->NextFree  = NextFree;
02946             pClone->ArraySize = NextFree;
02947         }
02948     }
02949 
02950     return(pClone);
02951 }

ValueFunction * ValueFunctionPressure::CreateAndReadFileRecord CXaraFileRecord pInputRecord  )  [protected, virtual]
 

Loads a ValueFunction object from a record which was saved into a file using the WriteFileRecord call. This is called by the base class loader routine ReadFileRecord, which finds an appropriate instance of a derived class to call to load the data in question.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/1/97
Parameters:
pInputRecord - The file record to read [INPUTS]
Returns:
NULL if it failed, else a pointer to new ValueFunction object representing whatever was saved in that record.
This method creates a new instance of this particular ValueFunction class and then loads whatever information is necessary from the file to initialise itself properly. The record read-pointer is left pointing at the end of the ValueFunction-saved data so that the caller can continue reading their extra bytes of data after loading the ValueFunction.

See also:
ValueFunctionPressure::WriteFileRecord

Implements ValueFunction.

Definition at line 3242 of file valfunc.cpp.

03243 {
03244     ERROR3IF(pInputRecord == NULL, "Illegal NULL param");
03245 
03246     UINT32 NumEntries = 0;
03247     pInputRecord->ReadUINT32(&NumEntries);
03248 
03249     ValueFunctionPressure *pValFunc = CreateInstance();
03250 
03251     if (pValFunc != NULL && NumEntries > 0)
03252     {
03253         // Make the array big enough to hold all the entries, to save reallocing it as we go,
03254         // and also to save us having to check for failure on each pressure item we add.
03255         if (!pValFunc->ExpandArray(NumEntries))
03256         {
03257             delete pValFunc;
03258             return(NULL);
03259         }
03260 
03261         UINT16 Position;
03262         UINT16 Pressure;
03263 
03264         for (UINT32 i = 0; i < NumEntries; i++)
03265         {
03266             pInputRecord->ReadUINT16(&Position);
03267             pInputRecord->ReadUINT16(&Pressure);
03268             pValFunc->AddPressure(  ((float)Position) / (float) 65535.0,
03269                                     ((float)Pressure) / (float) 65535.0);
03270         }
03271     }
03272 
03273     return(pValFunc);
03274 }

ValueFunctionPressure * ValueFunctionPressure::CreateInstance void   )  [protected, virtual]
 

Creates a new blank object of the same type as this one. Internal function used in ValueFunctionPressure & ValueFunctionPressureS.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/1/97
Returns:
NULL if it failed, else a pointer to new ValueFunctionPressure object of the same type as "this" one. Used to allow derived Pressure classes to use all the base class code, and merely override the GetValue method.
Notes: Called by ValueFunctionPressure::Clone and CreateAndReadFileRecord, as this is the only action in those functions that depends on the type of the class that is being used

Reimplemented in ValueFunctionPressureS.

Definition at line 3298 of file valfunc.cpp.

03299 {   
03300     return(new ValueFunctionPressure);
03301 }

BOOL ValueFunctionPressure::ExpandArray INT32  NewSize  )  [protected]
 

Ensures that the pressure storage array has no fewer than NewSize entries.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/1/97
Parameters:
NewSize - The number of array entries desired. [INPUTS]
Returns:
FALSE if memory was unavailable
Notes: For efficiency, unused array entries are always left uninitialised

Definition at line 3103 of file valfunc.cpp.

03104 {
03105     if (NewSize <= ArraySize)
03106         return(TRUE);           // That was easy!
03107 
03108     VFPressureRecord *pNewArray = NULL;
03109 
03110     if (pArray == NULL)
03111         pNewArray = (VFPressureRecord *) CCMalloc(NewSize * sizeof(VFPressureRecord));
03112     else
03113         pNewArray = (VFPressureRecord *) CCRealloc(pArray, NewSize * sizeof(VFPressureRecord));
03114 
03115     if (pNewArray == NULL)
03116         return(FALSE);
03117 
03118     // We succeeded, so remember the new address & size
03119     pArray = pNewArray;
03120     ArraySize = NewSize;
03121 
03122     return(TRUE);
03123 }

virtual ValueFunctionID ValueFunctionPressure::GetUniqueID void   )  [inline, virtual]
 

Implements ValueFunction.

Reimplemented in ValueFunctionPressureS.

Definition at line 879 of file valfunc.h.

00879 { return(ValueFunctionID_Pressure); };

double ValueFunctionPressure::GetValue double  Position  )  [virtual]
 

To read the value of this function at a given position.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/1/97
Parameters:
Position - A value between 0.0 and 1.0 [INPUTS]
Returns:
A value representing the recorded pressure at the given Position.
Notes: This determines the 2 closest position values for which pressure information was recorded, and interpolates the values by "fitting a curve" through the points.

The "curve" may be improved in future, but is currently a simple linear interpolation.

!!!!TODO: This should cache the last array index it was asked for, and start the search from that index, as we usually ask for values for sequential, close, position values, and this will vastly reduce the searching overhead in most cases. Note that we may step through positions in both positive & negative directions, so it will have to handle this carefully.

Implements ValueFunction.

Reimplemented in ValueFunctionPressureS.

Definition at line 2876 of file valfunc.cpp.

02877 {
02878     // No entries have been recorded!
02879     if (NextFree < 1)
02880         return(0.0);
02881 
02882     // If the position is outside the range in our table, return the closest entry
02883     if (Position <= pArray[0].Position)
02884         return(pArray[0].Pressure);
02885 
02886     if (Position >= pArray[NextFree-1].Position)
02887         return(pArray[NextFree-1].Pressure);
02888 
02889     // Search to find the closest 2 array entries to the position
02890     // We assume the array fills the 0.0 to 1.0 range, so we search from the closest
02891     // "end" of the array to halve the average search time.
02892     INT32 i;
02893     if (Position >= 0.5)
02894     {
02895         i = NextFree;
02896         while (i > 1 && Position < pArray[i-1].Position)
02897             i--;
02898     }
02899     else
02900     {
02901         i = 1;
02902         while (i < NextFree && Position > pArray[i].Position)
02903             i++;
02904     }
02905 
02906     ERROR3IF(i < 1 || i >= NextFree, "I've screwed up the scanning loop code");
02907 
02908     // Otherwise, the position lies between array elements [i-1] and [i], so we
02909     // interpolate between these positions
02910     ERROR3IF((pArray[i].Position - pArray[i-1].Position) <= 0.0, "Pressure array is non-ascending!");
02911     const double MixValue = (Position - pArray[i-1].Position) /
02912                             (pArray[i].Position - pArray[i-1].Position);
02913 
02914     return((MixValue * pArray[i].Pressure) + ((1.0 - MixValue) * pArray[i-1].Pressure));
02915 }

BOOL ValueFunctionPressure::IsDifferent ValueFunction pOther  )  [virtual]
 

Comparator. Determines if 2 different ValueFunction objects are considered different.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/1/97
Parameters:
pOther - Another ValueFunction object to compare this one to [INPUTS]
Returns:
TRUE if the objects are considered different, FALSE if they are considered identical
Notes: Calls the base class to see if they are different classes, and then compares identical classes by checking member vars

Reimplemented from ValueFunction.

Definition at line 2976 of file valfunc.cpp.

02977 {
02978     if (ValueFunction::IsDifferent(pOther))
02979         return(TRUE);
02980     
02981     // Both objects are instances of this class, so compare them more carefully
02982     ValueFunctionPressure *pPressure = (ValueFunctionPressure *)pOther;
02983     if (NextFree != pPressure->NextFree)
02984         return(TRUE);                   // Don't have same number of entries
02985 
02986     // Now compare the entire array
02987     for (INT32 i = 0; i < NextFree; i++)
02988     {
02989         if (pArray[i].Position != pPressure->pArray[i].Position ||
02990             pArray[i].Pressure != pPressure->pArray[i].Pressure)
02991         {
02992             return(TRUE);
02993         }
02994     }
02995 
02996     // Cor. They must be the same!
02997     return(FALSE);
02998 }

void ValueFunctionPressure::NormalisePositions void   ) 
 

Normalises all positions in the table to lie within a 0.0 to 1.0 range, by dividing them by the last element position value. (i.e. it assumes that the last element in the array will have the largest Position value).

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/1/97

Definition at line 3066 of file valfunc.cpp.

03067 {
03068     // If fewer than 1 entries, or no array, then there's nothing to do
03069     if (pArray == NULL || NextFree < 1)
03070         return;
03071 
03072     // Find the maximum value, and baulk if it would cause a divide by zero.
03073     if (pArray[NextFree-1].Position <= 0.0)
03074     {
03075         ERROR3("Max position in table is zero or negative - normalisation failed");
03076         return;
03077     }
03078 
03079     float RMaxPosition = 1.0/pArray[NextFree-1].Position;
03080     for (INT32 i = 0; i < NextFree; i++)
03081         pArray[i].Position *= RMaxPosition;
03082 }

CamelotFileRecord * ValueFunctionPressure::WriteFileRecord INT32  RecordTag,
INT32  ExtraBytes,
BaseCamelotFilter pFilter
[virtual]
 

Saves a ValueFunction object to a Xara file. This function will create a new variable-sized record with the given record tag, and will write out whatever data is needed to save this ValueFunction's state to the file.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/1/97
Parameters:
RecordTag - the tag to write this record under [INPUTS] ExtraBytes - The number of extra bytes of information the caller will write into the record after caling this function (Space for this many extra bytes will be reserved by this function when it creates the new file record) This may be 0 or more bytes. pFilter - The filter to write to
Returns:
NULL if it failed, else a pointer to a record which saves the state of this valueFunction object. Once the caller has written the record, they MUST DELETE it.
"ExtraBytes" bytes will be added to the record size to reserve space at the end of the record for the caller to add their own data. This is to allow ValueFunctions to be saved embedded in other object's record structures (e.g. inside different types of attributes).

All ValueFunction record data has 3 sections, whiich are recorded as follows: 1. ValueFunction header, identifying which type of VF is being saved INT32 ValueFunctionUniqueID (4 bytes) 2. Derived-class-data (0 or more bytes). This particular class adds: UINT32 NumTableEntries + n entries of the form: UNIT16 Position UINT16 Pressure (4 + (NumTableEntries*4) bytes) 3. Caller data. This is written by the caller to the returned record object. This data must be ExtraBytes (0 or more) bytes in length.

The Position & Pressure values are 16-bit unsigned values between 0 & 65535. These represent floating point values between 0.0 & 1.0, i.e. are simply a (UINT16) (Value * 65535.0). I don't bother avoiding rounding errors, as 1/128000th is an insignificant error.

See also:
ValueFunctionPressure::CreateAndReadFileRecord; ValueFunction::CreateAndWriteFileRecord

Implements ValueFunction.

Definition at line 3178 of file valfunc.cpp.

03180 {
03181     ERROR3IF(pFilter == NULL, "Illegal NULL param");
03182     ERROR3IF(ExtraBytes < 0, "Stupid ExtraBytes request in ValueFunction::WriteFileRecord");
03183 
03184     // Calculate how many bytes of information this VF will write. We do not include
03185     // the header info written by the base class or the ExtraInfo desired by the caller -
03186     // the base class adds all that in for us.
03187     const INT32 MyRecordSize = 4 + (4 * NextFree);
03188 
03189     // Create an appropriate record, and write our data to it
03190     CamelotFileRecord *pRec = CreateAndWriteFileRecord(RecordTag, MyRecordSize, ExtraBytes, pFilter);
03191 
03192     if (pRec != NULL)
03193     {
03194         BOOL ok = TRUE;
03195         if (ok)     ok = pRec->WriteUINT32((UINT32) NextFree);
03196 
03197         for (INT32 i = 0; (i < NextFree) && ok; i++)
03198         {
03199             if (ok)     ok = pRec->WriteUINT16((UINT16) (pArray[i].Position * 65535.0));
03200             if (ok)     ok = pRec->WriteUINT16((UINT16) (pArray[i].Pressure * 65535.0));
03201         }
03202 
03203         if (!ok)            // If we failed, clean up & return NULL
03204         {
03205             delete pRec;
03206             pRec = NULL;
03207         }
03208     }
03209 
03210     return(pRec);
03211 }


Member Data Documentation

INT32 ValueFunctionPressure::ArraySize [protected]
 

Definition at line 896 of file valfunc.h.

INT32 ValueFunctionPressure::NextFree [protected]
 

Definition at line 897 of file valfunc.h.

VFPressureRecord* ValueFunctionPressure::pArray [protected]
 

Definition at line 895 of file valfunc.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 04:02:48 2007 for Camelot by  doxygen 1.4.4