Commit 730a9724 authored by Pierre Kraemer's avatar Pierre Kraemer

Grosse mise à jour des Approximator / Selector + update plugin Radiance

parent 6ddae940
......@@ -70,8 +70,8 @@ int main(int argc, char **argv)
std::cout << " NB Faces "<< Algo::Topo::getNbOrbits<FACE>(myMap) << std::endl;
std::cout << " NB Vertices "<< nbVertices << std::endl;
std::vector<VertexAttribute<typename PFP::VEC3, MAP> *> attr;
attr.push_back(&position);
std::vector<VertexAttribute<typename PFP::VEC3, MAP> > attr;
attr.push_back(position);
Algo::Surface::Decimation::decimate<PFP>(myMap, Algo::Surface::Decimation::S_QEM, Algo::Surface::Decimation::A_QEM, attr, nbVertices * 0.05) ;
VertexAttribute<PFP::VEC3, MAP> normal = myMap.addAttribute<PFP::VEC3,VERTEX,MAP>( "normal") ;
......
......@@ -52,8 +52,8 @@ int main(int argc, char **argv)
Algo::Surface::Modelisation::LoopSubdivision<PFP>(myMap, position) ;
unsigned int nbVertices = Algo::Topo::getNbOrbits<VERTEX>(myMap) ;
std::vector<VertexAttribute<typename PFP::VEC3, MAP> *> attr;
attr.push_back(&position);
std::vector<VertexAttribute<typename PFP::VEC3, MAP> > attr;
attr.push_back(position);
Algo::Surface::Decimation::decimate<PFP>(myMap, Algo::Surface::Decimation::S_QEM, Algo::Surface::Decimation::A_QEM, attr, nbVertices * 0.1) ;
Algo::Surface::Modelisation::LoopSubdivision<PFP>(myMap, position) ;
......
......@@ -14,6 +14,19 @@
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
......@@ -21,6 +34,13 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Normal :</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="combo_positionVBO">
<property name="sizePolicy">
......@@ -36,13 +56,6 @@
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Normal :</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="combo_normalVBO">
<property name="sizePolicy">
......@@ -58,18 +71,12 @@
</item>
</widget>
</item>
<item row="2" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
<item row="2" column="0" colspan="2">
<widget class="QPushButton" name="button_decimate">
<property name="text">
<string>Decimate</string>
</property>
</spacer>
</widget>
</item>
</layout>
</widget>
......
#ifndef SPHERICALFUNCTIONINTEGRATORCARTESIAN_H
#define SPHERICALFUNCTIONINTEGRATORCARTESIAN_H
#include "sphere_lebedev_rule.h"
typedef double (*CartesianFunction)(double x, double y, double z, void* userData); // Prototype for the function to be evaluated
typedef bool (*CartesianDomain)(double x, double y, double z, void* userData); // Prototype for the domain definition (true: inside, false: outside)
class SphericalFunctionIntegratorCartesian
{
public:
SphericalFunctionIntegratorCartesian();
~SphericalFunctionIntegratorCartesian();
static const unsigned int maxRuleId = 65; // Span of rule id (inclusive)
static inline bool RuleAvailable(unsigned int ruleId); // States that the quadrature rule is available
static inline unsigned int RuleOrder(unsigned int ruleId); // Number of points used in the quadrature
static inline unsigned int RulePrecision(unsigned int ruleId); // Max degree of exactly integrated polynomial
void Init(unsigned int ruleId); // Rule to use for subsequent integration - allocates quadrature samples and weights
void Release(); // Release cached informations
/*
* Integrates a function over a user-specified domain of the full 2D-sphere
*
* outIntegral: resulting value
* outArea: area of the integration domain, as specified by the dom function
* f: function to integrate
* userDataFunction: user callback value passed to f during evaluation
* dom: Implicit domain definition (true when inside, false outside)
* userDataDomain: user callback value passed to dom during evaluation
*
*/
void Compute(double* outIntegral, double* outArea, CartesianFunction f, void* userDataFunction, CartesianDomain dom, void* userDataDomain) const;
protected:
unsigned int rId;
unsigned int rOrder;
double* quadValues; // [x_i] then [y_i], then [z_i], then [w_i] values
};
bool SphericalFunctionIntegratorCartesian::RuleAvailable(unsigned int ruleId)
{
return available_table(ruleId) == 1;
}
unsigned int SphericalFunctionIntegratorCartesian::RuleOrder(unsigned int ruleId)
{
return order_table(ruleId);
}
unsigned int SphericalFunctionIntegratorCartesian::RulePrecision(unsigned int ruleId)
{
return precision_table(ruleId);
}
#endif
#ifndef _HALFEDGESELECTOR_RADIANCE_H_
#define _HALFEDGESELECTOR_RADIANCE_H_
#include "Algo/Decimation/selector.h"
#include "Algo/Decimation/approximator.h"
#include "Utils/qem.h"
#include "Utils/sphericalHarmonics.h"
#include "SphericalFunctionIntegratorCartesian.h"
namespace CGoGN
{
namespace SCHNApps
{
template <typename PFP>
class HalfEdgeSelector_Radiance : public Algo::Surface::Decimation::Selector<PFP>
{
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::REAL REAL ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename Utils::SphericalHarmonics<REAL, VEC3> SH;
private:
VertexAttribute<VEC3, MAP>& m_position;
VertexAttribute<VEC3, MAP>& m_normal;
VertexAttribute<SH, MAP>& m_radiance;
Algo::Surface::Decimation::Approximator<PFP, VEC3, DART>& m_positionApproximator;
Algo::Surface::Decimation::Approximator<PFP, VEC3, DART>& m_normalApproximator;
Algo::Surface::Decimation::Approximator<PFP, SH, DART>& m_radianceApproximator;
typedef struct
{
typename std::multimap<float, Dart>::iterator it;
bool valid;
static std::string CGoGNnameOfType() { return "LightfieldGradHalfEdgeInfo"; }
} LightfieldHalfEdgeInfo;
typedef NoTypeNameAttribute<LightfieldHalfEdgeInfo> HalfEdgeInfo;
DartAttribute<HalfEdgeInfo, PFP2::MAP> halfEdgeInfo;
VertexAttribute<Utils::Quadric<PFP2::REAL>, PFP2::MAP> m_quadric;
VertexAttribute<PFP2::VEC3, PFP2::MAP> m_avgColor;
unsigned int m_nb_coefs;
SphericalFunctionIntegratorCartesian m_integrator;
double* m_n;
double* m_workspace;
std::multimap<float, Dart> halfEdges;
typename std::multimap<float, Dart>::iterator cur;
void initHalfEdgeInfo(Dart d);
void updateHalfEdgeInfo(Dart d);
void computeHalfEdgeInfo(Dart d, HalfEdgeInfo& einfo);
void recomputeQuadric(const Dart d);
/*
PFP2::VEC3 computeGradientLFerror(const Dart& v0, const Dart& v1) const;
PFP2::VEC3 computeDirDerivativeLFerror(const Dart& v0, const Dart& v1);
PFP2::VEC3 computeSquaredLightfieldDifferenceNumerical(const Dart& d1, const Dart& d2, const PFP2::VEC3& N) const;
PFP2::VEC3 computeSquaredLightfieldDifferenceAnalytical(const Dart& d1, const Dart& d2) const;
PFP2::VEC3 computeGradient(const PFP2::VEC3& P0, const PFP2::VEC3& Pi, const PFP2::VEC3& Pj, const Dart& v0, const Dart& v1, const Dart& vi, const Dart& vj, unsigned int channel) const;
PFP2::VEC3 integrateDscalGrad(const PFP2::VEC3& d, const unsigned int& K, const PFP2::VEC3& N, const PFP2::VEC3& ei, const PFP2::VEC3& ej,
const PFP2::VEC3* coefs1, const PFP2::VEC3& T1, const PFP2::VEC3& B1, const PFP2::VEC3& N1, const PFP2::VEC3& avg1,
const PFP2::VEC3* coefsi, const PFP2::VEC3& Ti, const PFP2::VEC3& Bi, const PFP2::VEC3& Ni, const PFP2::VEC3& avgi,
const PFP2::VEC3* coefsj, const PFP2::VEC3& Tj, const PFP2::VEC3& Bj, const PFP2::VEC3& Nj, const PFP2::VEC3& avgj) const;
PFP2::VEC3 integrateDlf(const PFP2::VEC3& d, const unsigned int& K, const PFP2::VEC3& N, const PFP2::VEC3& ei, const PFP2::VEC3& ej,
const std::vector<PFP2::VEC3*> coefs0, const PFP2::VEC3& T0, const PFP2::VEC3& B0, const PFP2::VEC3& N0, const PFP2::VEC3& avg0,
const std::vector<PFP2::VEC3*> coefs1, const PFP2::VEC3& T1, const PFP2::VEC3& B1, const PFP2::VEC3& N1, const PFP2::VEC3& avg1,
const std::vector<PFP2::VEC3*> coefsi, const PFP2::VEC3& Ti, const PFP2::VEC3& Bi, const PFP2::VEC3& Ni, const PFP2::VEC3& avgi,
const std::vector<PFP2::VEC3*> coefsj, const PFP2::VEC3& Tj, const PFP2::VEC3& Bj, const PFP2::VEC3& Nj, const PFP2::VEC3& avgj) const;
PFP2::REAL computeIntegral(const double *avgi, const PFP2::VEC3& ti, const PFP2::VEC3& bi, const PFP2::VEC3& ni, unsigned int nbCoefs, const std::vector<double>& coefs) const;
static double dispScalGrad (double x, double y, double z, void* data);
static double dlf (double x, double y, double z, void* data);
static double evalF(double* N, double* avg, unsigned int nb, bool isSH, double* T, double* B, double* coefs, double& x, double& y, double& z);
static void cart2spherical(double u, double v, double& theta, double& phi);
static double SquaredDifferenceOfCartesianFunctions (double x, double y, double z, void* data);
static bool isInDomain(double x, double y, double z, void *data);
static double CartesianFunction (double x, double y, double z, void* data);
*/
public:
HalfEdgeSelector_Radiance(
MAP& m,
VertexAttribute<VEC3, MAP>& pos,
VertexAttribute<VEC3, MAP>& norm,
VertexAttribute<SH, MAP>& rad,
Algo::Surface::Decimation::Approximator<PFP, VEC3, DART>& posApprox,
Algo::Surface::Decimation::Approximator<PFP, VEC3, DART>& normApprox,
Algo::Surface::Decimation::Approximator<PFP, SH, DART>& radApprox
) :
Algo::Surface::Decimation::Selector<PFP2>(m),
m_position(pos),
m_normal(norm),
m_radiance(rad),
m_positionApproximator(posApprox),
m_normalApproximator(normApprox),
m_radianceApproximator(radApprox),
m_nb_coefs(0),
m_n(NULL),
m_workspace(NULL)
{
halfEdgeInfo = m.template checkAttribute<HalfEdgeInfo, DART, PFP2::MAP>("halfEdgeInfo");
m_quadric = m.template checkAttribute<Utils::Quadric<PFP2::REAL>, VERTEX, PFP2::MAP>("QEMquadric");
m_avgColor = m.template checkAttribute<PFP2::VEC3, VERTEX, PFP2::MAP>("avgColor");
m_n = new double[3];
}
~HalfEdgeSelector_Radiance()
{
this->m_map.removeAttribute(halfEdgeInfo);
this->m_map.removeAttribute(m_quadric);
this->m_map.removeAttribute(m_avgColor);
m_integrator.Release();
delete[] m_n;
delete[] m_workspace;
}
Algo::Surface::Decimation::SelectorType getType() { return Algo::Surface::Decimation::S_OTHER; }
bool init();
bool nextEdge(Dart& d) const;
void updateBeforeCollapse(Dart d);
void updateAfterCollapse(Dart d2, Dart);
void updateWithoutCollapse() { }
void getEdgeErrors(EdgeAttribute<PFP2::REAL, PFP2::MAP> *errors) const
{
assert(errors != NULL || !"HalfEdgeSelector_Radiance::getEdgeErrors requires non null vertexattribute argument") ;
if (!errors->isValid())
std::cerr << "HalfEdgeSelector_Radiance::getEdgeErrors requires valid edgeattribute argument" << std::endl ;
assert(halfEdgeInfo.isValid());
TraversorE<PFP2::MAP> travE(this->m_map);
for(Dart d = travE.begin() ; d != travE.end() ; d = travE.next())
{
Dart dd = this->m_map.phi2(d);
if (halfEdgeInfo[d].valid)
{
(*errors)[d] = halfEdgeInfo[d].it->first;
}
if (halfEdgeInfo[dd].valid && halfEdgeInfo[dd].it->first < (*errors)[d])
{
(*errors)[d] = halfEdgeInfo[dd].it->first;
}
if (!(halfEdgeInfo[d].valid || halfEdgeInfo[dd].valid))
(*errors)[d] = -1;
}
}
};
} // namespace SCHNApps
} // namespace CGoGN
#include "halfEdgeSelectorRadiance.hpp"
#endif // _HALFEDGESELECTOR_RADIANCE_H_
#ifndef _MESHTABLESURFACE_RADIANCE_H_
#define _MESHTABLESURFACE_RADIANCE_H_
#include "Algo/Import/import.h"
#include "Algo/Import/import2tables.h"
namespace CGoGN
{
namespace SCHNApps
{
class MeshTablesSurface_Radiance : public CGoGN::Algo::Surface::Import::MeshTablesSurface<PFP2>
{
public:
MeshTablesSurface_Radiance(MAP& m) : MeshTablesSurface<PFP2>(m)
{}
/**
* @brief importPLY
* @param filename: the ply file to be imported. This file is supposed to have a three position, three normal and at least three radiance scalars per vertex.
* @return succeeded
*/
template <typename SH_TYPE>
bool importPLY(const std::string& filename);
private:
/**
* \brief reads the list of vertices in a radiance PLY file. The function is template of the type of arithmetic (float, double) used in the file to be read
* \param fp IN: the file pointer descriptor
* \param binary IN: binary mode for reading fp
* \param nbVertices IN: the number of vertices to read
* \param nbProps IN: the number of properties according to the header
* \param positions IN/OUT: the positions container
* \param normals IN/OUT: the normals container
* \param radiances IN/OUT: the radiances container
* \param verticesID IN/OUT: the vector of vertex IDs
* \return number of vertices readVerticesPLY
*/
template <typename REAL, typename SH_TYPE>
unsigned int readVerticesPLY(
std::ifstream& fp, bool binary,
const unsigned int& nbVertices, const unsigned int& nbProps, const unsigned int& propSize,
VertexAttribute<PFP2::VEC3, PFP2::MAP>& positions,
VertexAttribute<PFP2::VEC3, PFP2::MAP>& normals,
VertexAttribute<SH_TYPE, PFP2::MAP>& radiances,
std::vector<unsigned int>& verticesID
);
};
} // namespace SCHNApps
} // namespace CGoGN
#include "meshTableSurfaceRadiance.hpp"
#endif
namespace CGoGN
{
namespace SCHNApps
{
template <typename SH_TYPE>
bool MeshTablesSurface_Radiance::importPLY(const std::string& filename)
{
// Open file
std::ifstream fp(filename, std::ios::in | std::ios::binary) ;
if (!fp.good())
{
CGoGNerr << "Unable to open file " << filename << CGoGNendl ;
return false ;
}
// Read quantities : #vertices, #faces, #properties, degree of polynomials
std::string tag ;
fp >> tag;
if (tag != std::string("ply")) // verify file type
{
CGoGNerr << filename << " is not a ply file !" << CGoGNout ;
return false ;
}
do // go to "format"
{
fp >> tag ;
} while (tag != std::string("format")) ;
fp >> tag ;
bool binary = (tag != "ascii") ;
do // go to #vertices
{
fp >> tag ;
} while (tag != std::string("vertex")) ;
unsigned int nbVertices ;
fp >> nbVertices ; // Read #vertices
bool position = false ;
bool normal = false ;
bool radiance = false ;
unsigned int propSize = 0 ; // for binary read
unsigned int nbProps = 0 ; // # properties
unsigned int nbCoefs = 0 ; // # coefficients
do // go to #faces and count #properties
{
fp >> tag ;
if (tag == std::string("property"))
{
++nbProps ;
}
else if (tag == std::string("int8") || tag == std::string("uint8"))
{
if (propSize < 2)
{
propSize = 1 ;
std::cerr << "only float32 of float64 is yet handled" << std::endl ;
assert(!"only float32 or float64 is yet handled") ;
}
else
{
std::cerr << "only float32 of float64 is yet handled" << std::endl ;
assert(!"only float32 or float64 is yet handled") ;
}
}
else if (tag == std::string("int16") || tag == std::string("uint16"))
{
if (propSize == 0 || propSize == 2)
{
propSize = 2 ;
std::cerr << "only float32 of float64 is yet handled" << std::endl ;
assert(!"only float32 or float64 is yet handled") ;
}
else
{
std::cerr << "only float32 of float64 is yet handled" << std::endl ;
assert(!"only float32 or float64 is yet handled") ;
}
}
else if (tag == std::string("int32") || tag == std::string("float32") || tag == std::string("uint32"))
{
if (propSize == 0 || propSize == 4)
{
propSize = 4 ;
}
else
{
std::cerr << "only float32 of float64 is yet handled" << std::endl ;
assert(!"only float32 or float64 is yet handled") ;
}
}
else if (tag == std::string("int64") || tag == std::string("float64"))
{
if (propSize == 0 || propSize == 8)
{
propSize = 8 ;
}
else
{
std::cerr << "only float32 of float64 is yet handled" << std::endl ;
assert(!"only float32 or float64 is yet handled") ;
}
}
else if (tag == std::string("x") || tag == std::string("y") || tag == std::string("z"))
position = true ;
else if (tag == std::string("nx") || tag == std::string("ny") || tag == std::string("nz"))
normal = true ;
else if (tag.substr(0,6) == std::string("SHcoef"))
{
radiance = true ;
++nbCoefs ;
}
} while (tag != std::string("face")) ;
assert((nbCoefs % 3) == 0 || !"Import only supports RGB SphericalHarmonics (i.e. Tcoef==VEC3)") ;
nbCoefs /= 3 ;
SH_TYPE::set_nb_coefs(nbCoefs) ;
fp >> this->m_nbFaces ; // Read #vertices
do // go to end of header
{
fp >> tag ;
} while (tag != std::string("end_header")) ;
if (binary)
{
char* endline = new char[1] ;
fp.read(endline, sizeof(char)) ;
if (*endline == '\r') // for windows
fp.read(endline, sizeof(char)) ;
assert(*endline == '\n') ;
delete[] endline ;
}
// Define containers
assert((position && normal && radiance) || !"Import: position, normal and radiance attributs should be provided") ;
if (!(position && normal && radiance))
return false ;
VertexAttribute<VEC3, MAP> positions = this->m_map.template checkAttribute<VEC3, VERTEX, MAP>("position") ;
VertexAttribute<VEC3, MAP> normals = this->m_map.template checkAttribute<VEC3, VERTEX, MAP>("normal") ;
VertexAttribute<SH_TYPE, MAP> radiances = this->m_map.template checkAttribute<SH_TYPE, VERTEX, MAP>("radiance") ;
// Read vertices
std::vector<unsigned int> verticesID ;
if (propSize == 4)
{
this->m_nbVertices = readVerticesPLY<float, SH_TYPE>(fp, binary, nbVertices, nbProps, propSize, positions, normals, radiances, verticesID) ;
}
else if (propSize == 8)
{
this->m_nbVertices = readVerticesPLY<double, SH_TYPE>(fp, binary, nbVertices, nbProps, propSize, positions, normals, radiances, verticesID) ;
}
// Read faces index
this->m_nbEdges.reserve(this->m_nbFaces) ;
this->m_emb.reserve(3 * this->m_nbFaces) ;
for (unsigned int i = 0 ; i < this->m_nbFaces ; ++i)
{
// read the indices of vertices for current face
unsigned int nbEdgesForFace ;
if (binary)
{
unsigned char tmp ;
fp.read((char*)&(tmp), sizeof(unsigned char)) ;
nbEdgesForFace = tmp ;
}
else
fp >> nbEdgesForFace ;
this->m_nbEdges.push_back(nbEdgesForFace);
unsigned int vertexID ;
if (binary)
{
for (unsigned int j=0 ; j < nbEdgesForFace ; ++j)
{
fp.read((char*)&vertexID, sizeof(unsigned int)) ;
this->m_emb.push_back(verticesID[vertexID]);
}
}
else
{
for (unsigned int j=0 ; j < nbEdgesForFace ; ++j)
{
fp >> vertexID ;
this->m_emb.push_back(verticesID[vertexID]);
}
}
}
// Close file
fp.close() ;
return true ;
}
template <typename REAL, typename SH_TYPE>
unsigned int MeshTablesSurface_Radiance::readVerticesPLY(
std::ifstream& fp, bool binary,
const unsigned int& nbVertices, const unsigned int& nbProps, const unsigned int& propSize,
VertexAttribute<PFP2::VEC3, PFP2::MAP>& positions,
VertexAttribute<PFP2::VEC3, PFP2::MAP>& normals,
VertexAttribute<SH_TYPE, PFP2::MAP>& radiances,
std::vector<unsigned int>& verticesID
)
{
verticesID.reserve(nbVertices) ;
REAL* properties = new REAL[nbProps] ;
AttributeContainer& container = this->m_map.template getAttributeContainer<VERTEX>() ;
for (unsigned int i = 0 ; i < nbVertices ; ++i) // Read and store properties for current vertex
{
unsigned int id = container.insertLine() ;
verticesID.push_back(id) ;
if (binary)
{
fp.read((char*)properties,nbProps * propSize) ;
}
else
{
for (unsigned int j = 0 ; j < nbProps ; ++j) // get all properties
fp >> properties[j] ;
}
positions[id] = VEC3(properties[0],properties[1],properties[2]) ; // position
normals[id] = VEC3(properties[3],properties[4],properties[5]) ; // normal
int coefno = 6 ;
for (int l = 0 ; l <= SH_TYPE::get_resolution() ; ++l) // radiance
for (int m = -l ; m <= l ; ++m)
{
radiances[id].get_coef(l,m) = VEC3(properties[coefno],properties[coefno+1],properties[coefno+2]) ;
coefno += 3 ;
}
}
this->m_nbVertices = verticesID.size() ;
delete[] properties ;
return verticesID.size() ;
}
} // namespace SCHNApps
} // namespace CGoGN
int available_table ( int rule );
int gen_oh ( int code, double a, double b, double v, double *x,
double *y, double *z, double *w );
void ld_by_order ( int order, double *x, double *y, double *z, double *w );
void ld0006 ( double *x, double *y, double *z, double *w );
void ld0014 ( double *x, double *y, double *z, double *w );
void ld0026 ( double *x, double *y, double *z, double *w );
void ld0038 ( double *x, double *y, double *z, double *w );
void ld0050 ( double *x, double *y, double *z, double *w );
void ld0074 ( double *x, double *y, double *z, double *w );
void ld0086 ( double *x, double *y, double *z, double *w );
void ld0110 ( double *x, double *y, double *z, double *w );
void ld0146 ( double *x, double *y, double *z, double *w );
void ld0170 ( double *x, double *y, double *z, double *w );
void ld0194 ( double *x, double *y, double *z, double *w );
void ld0230 ( double *x, double *y, double *z, double *w );
void ld0266 ( double *x, double *y, double *z, double *w );
void ld0302 ( double *x, double *y, double *z, double *w );
void ld0350 ( double *x, double *y, double *z, double *w );
void ld0434 ( double *x, double *y, double *z, double *w );
void ld0590 ( double *x, double *y, double *z, double *w );
void ld0770 ( double *x, double *y, double *z, double *w );
void ld0974 ( double *x, double *y, double *z, double *w );
void ld1202 ( double *x, double *y, double *z, double *w );
void ld1454 ( double *x, double *y, double *z, double *w );
void ld1730 ( double *x, double *y, double *z, double *w );
void ld2030 ( double *x, double *y, double *z, double *w );
void ld2354 ( double *x, double *y, double *z, double *w );
void ld2702 ( double *x, double *y, double *z, double *w );
void ld3074 ( double *x, double *y, double *z, double *w );
void ld3470 ( double *x, double *y, double *z, double *w );
void ld3890 ( double *x, double *y, double *z, double *w );
void ld4334 ( double *x, double *y, double *z, double *w );
void ld4802 ( double *x, double *y, double *z, double *w );