Пример #1
0
//==========================================================================
void GeometryTools::findDominant(const SplineSurface& surface,
		  Vector3D& dominant_u, Vector3D& dominant_v)
//==========================================================================
{
    int nu = surface.numCoefs_u();
    int nv = surface.numCoefs_v();
    vector<double>::const_iterator start = surface.coefs_begin();
    Vector3D temp;
    // Dominant in u-direction
    dominant_u = Vector3D(0.0, 0.0, 0.0);
    for (int j = 0; j < nv; ++j) {
	for (int dd = 0; dd < 3; ++dd) {
	    temp[dd] = *(start + 3*(nu*j + (nu-1)) + dd)
		- *(start + 3*(nu*j) + dd);
	}
	dominant_u += temp;
    }
    // Dominant in v-direction
    dominant_v = Vector3D(0.0, 0.0, 0.0);
    for (int i = 0; i < nu; ++i) {
	for (int dd = 0; dd < 3; ++dd) {
	    temp[dd] = *(start + 3*(nu*(nv-1) + i) + dd)
		- *(start + 3*i + dd);
	}
	dominant_v += temp;
    }

    return;
}
Пример #2
0
//===========================================================================
vector<shared_ptr<SplineSurface> >
SurfaceCreators::separateRationalParts(const SplineSurface& sf)
//===========================================================================
{
    bool rat = sf.rational();
    ASSERT(rat);

    int dim= sf.dimension();
    int rdim = dim + 1;
    vector<shared_ptr<SplineSurface> > sep_sfs;
    vector<double> coefs(sf.coefs_begin(), sf.coefs_end());
    int nmb1 = sf.numCoefs_u();
    int nmb2 = sf.numCoefs_v();
    vector<double> rcoefs;
    int num_coefs = nmb1*nmb2;
    vector<double>::const_iterator rcoef_iter = sf.rcoefs_begin();
    for (int ki = 0; ki < num_coefs; ++ki) {
	rcoefs.push_back(rcoef_iter[ki*rdim+1]);
	for (int kj = 0; kj < dim; ++kj) {
	    coefs[ki*dim+kj] /= (rcoefs.back());
	}
    }
    sep_sfs.push_back(shared_ptr<SplineSurface>
		      (new SplineSurface(nmb1, nmb2, sf.order_u(), sf.order_v(),
					 sf.basis_u().begin(), sf.basis_v().begin(),
					 coefs.begin(), dim)));
    sep_sfs.push_back(shared_ptr<SplineSurface>
		      (new SplineSurface(nmb1, nmb2, sf.order_u(), sf.order_v(),
					 sf.basis_u().begin(), sf.basis_v().begin(),
					 rcoefs.begin(), 1)));

    return sep_sfs;
}
Пример #3
0
//==========================================================================
void cart_to_bary(const SplineSurface& sf, const BaryCoordSystem3D& bc,
		  SplineSurface& sf_bc)
//==========================================================================
{
    ALWAYS_ERROR_IF(sf.dimension() != 3, "Dimension must be 3.");


    int nu = sf.numCoefs_u();
    int nv = sf.numCoefs_v();
    Vector3D cart;
    Vector4D bary;
    vector<double> new_coefs;
    if (!sf.rational()) {
	new_coefs.resize(4 * nu * nv);
	for (int iv = 0; iv < nv; ++iv) {
	    for (int iu = 0; iu < nu; ++iu) {
		int offset = nu * iv + iu;
		cart = Vector3D(sf.coefs_begin() + 3 * offset);
		bary = bc.cartToBary(cart);
		for (int j = 0; j < 4; ++j) {
		    new_coefs[4*offset + j] = bary[j];
		}
	    }
	}
    } else {
	new_coefs.resize(5 * nu * nv);
	for (int iv = 0; iv < nv; ++iv) {
	    for (int iu = 0; iu < nu; ++iu) {
		int offset = nu * iv + iu;
		cart = Vector3D(sf.coefs_begin() + 3 * offset);
		bary = bc.cartToBary(cart);
		double w = sf.rcoefs_begin()[4*offset + 3];
		for (int j = 0; j < 4; ++j) {
		    new_coefs[5*offset + j] = bary[j] * w;
		}
		new_coefs[5*offset + 4] = w;
	    }
	}
    }
    sf_bc = SplineSurface(nu, nv, sf.order_u(), sf.order_v(),
			  sf.basis_u().begin(), sf.basis_v().begin(),
			  new_coefs.begin(), 4, sf.rational());
    return;	
}
Пример #4
0
int main()
{
    ObjectHeader header;
    SplineSurface surf;
    cin >> header >> surf;

    PointCloud<3> cloud(surf.coefs_begin(),
                        surf.numCoefs_u()*surf.numCoefs_v());
    cloud.writeStandardHeader(cout);
    cout << cloud;
}
Пример #5
0
//==========================================================================
bool GeometryTools::negativeProj(const SplineSurface& surface,
		  const Array<Vector3D, 2>& refvector,
		  const double eps)
//==========================================================================
{
    int num_u = surface.numCoefs_u();
    int num_v = surface.numCoefs_v();
    Vector3D temp;
    int i = 0, j = 0;
    while (i < num_u-1) {
	j = 0;
	while (j < num_v) {
	    temp[0] = *(surface.coefs_begin() + 3*(num_u*j + i+1))
		- *(surface.coefs_begin() + 3*(num_u*j + i));
	    temp[1] = *(surface.coefs_begin() + 3*(num_u*j + i+1) + 1)
		- *(surface.coefs_begin() + 3*(num_u*j + i) + 1);
	    temp[2] = *(surface.coefs_begin() + 3*(num_u*j + i+1) + 2)
		- *(surface.coefs_begin() + 3*(num_u*j + i) + 2);
	    // Positive tolerance means that there must be a small
	    // _nonzero_ negative projection before it is reported as
	    // negative!
	    if (temp * refvector[0] < -eps)
		return true;
	    ++j;
	}
	++i;
    }
    i = 0;
    while (i < num_u) {
	j = 0;
	while (j < num_v-1) {
	    temp[0] = *(surface.coefs_begin() + 3*(num_u*(j+1) + i))
		- *(surface.coefs_begin() + 3*(num_u*j + i));
	    temp[1] = *(surface.coefs_begin() + 3*(num_u*(j+1) + i) + 1)
		- *(surface.coefs_begin() + 3*(num_u*j + i) +1);
	    temp[2] = *(surface.coefs_begin() + 3*(num_u*(j+1) + i) + 2)
		- *(surface.coefs_begin() + 3*(num_u*j + i) + 2);
	    // Positive tolerance means that there must be a small
	    // _nonzero_ negative projection before it is reported as
	    // negative!
	    if (temp * refvector[1] < -eps)
		return true;
	    ++j;
	}
	++i;
    }

    return false;
}
Пример #6
0
//===========================================================================
void SplineUtils::refinedBezierCoefsCubic(SplineSurface& spline_sf,
					  int ind_u_min, int ind_v_min,
					  vector<double>& bez_coefs)
//===========================================================================
{
    assert(!spline_sf.rational());

    if (bez_coefs.size() != 48)
	bez_coefs.resize(48);
    std::fill(bez_coefs.begin(), bez_coefs.end(), 0.0);

    // Values for inpute spline surface.
    int dim = spline_sf.dimension();
    int order_u = spline_sf.order_u();
    int order_v = spline_sf.order_u();
    int num_coefs_u = spline_sf.numCoefs_u();
    int num_coefs_v = spline_sf.numCoefs_v();

    // Checking that input index is within range.
    assert(ind_u_min >= order_u - 1 && ind_u_min < num_coefs_u);
    assert(ind_v_min >= order_v - 1 && ind_v_min < num_coefs_v);

    BsplineBasis& basis_u = spline_sf.basis_u();
    BsplineBasis& basis_v = spline_sf.basis_v();
    double* knot_u = &basis_u.begin()[0];
    double* knot_v = &basis_v.begin()[0];

    // We expect the knot index to refer to the last occurence.
    assert(knot_u[ind_u_min] != knot_u[ind_u_min+1]);
    assert(knot_v[ind_v_min] != knot_v[ind_v_min+1]);

    // We expect knot mult to be 1 or 4.
    int knot_mult_umin = (knot_u[ind_u_min-1] == knot_u[ind_u_min]) ? 4 : 1;
    int knot_mult_umax = (knot_u[ind_u_min+1] == knot_u[ind_u_min+2]) ? 4 : 1;
    int knot_mult_vmin = (knot_v[ind_v_min-1] == knot_v[ind_v_min]) ? 4 : 1;
    int knot_mult_vmax = (knot_v[ind_v_min+1] == knot_v[ind_v_min+2]) ? 4 : 1;

    bool kreg_at_ustart = (knot_mult_umin == 4);
    bool kreg_at_uend = (knot_mult_umax == 4);
    vector<double> transf_mat_u(16, 0.0);
    // if (!kreg_at_ustart && !kreg_at_uend)
    splineToBezierTransfMat(knot_u + ind_u_min - 3,
			    transf_mat_u);

#ifndef NDEBUG
    std::cout << "\ntransf_mat_u=" << std::endl;
    for (size_t kj = 0; kj < 4; ++kj)
    {
	for (size_t ki = 0; ki < 4; ++ki)
	    std::cout << transf_mat_u[kj*4+ki] << " ";
	std::cout << std::endl;
    }
    std::cout << std::endl;
#endif // NDEBUG

    // else
    // 	cubicTransfMat(knot_u + ind_u_min - 3,
    // 		       kreg_at_ustart, kreg_at_uend,
    // 		       transf_mat_u);

    bool kreg_at_vstart = (knot_mult_vmin == 4);
    bool kreg_at_vend = (knot_mult_vmax == 4);
    vector<double> transf_mat_v(16, 0.0);
    // if (!kreg_at_ustart && !kreg_at_uend)
    splineToBezierTransfMat(knot_v + ind_v_min - 3,
			    transf_mat_v);

#ifndef NDEBUG
    std::cout << "\ntransf_mat_v=" << std::endl;
    for (size_t kj = 0; kj < 4; ++kj)
    {
	for (size_t ki = 0; ki < 4; ++ki)
	    std::cout << transf_mat_v[kj*4+ki] << " ";
	std::cout << std::endl;
    }
    std::cout << std::endl;
#endif // NDEBUG

    extractBezierCoefs(&spline_sf.coefs_begin()[0],
		       num_coefs_u, num_coefs_v,
		       ind_u_min, ind_v_min,
		       transf_mat_u, transf_mat_v,
		       bez_coefs);

    return;
}
Пример #7
0
//===========================================================================
shared_ptr<SplineSurface>
SurfaceCreators::mult1DBezierPatches(const SplineSurface& patch1,
				     const SplineSurface& patch2)
//===========================================================================
{
    // @@sbr This should be fixed shortly. Nothing more than separating the
    // spatial and rational components.
    ASSERT(!patch1.rational() && !patch2.rational());

    // We should of course also check the actual knots, but why bother (trusting the user).
    //     ASSERT(basis1_u.numCoefs() == basis2_u.numCoefs() &&
    // 	   basis1_v.numCoefs() == basis2_v.numCoefs() &&
    // 	   basis1_u.order() == basis2_u.order() &&
    // 	   basis1_v.order() == basis2_v.order());
    ASSERT((patch1.dimension() == 1) && (patch2.dimension() == 1));
    // @@sbr Suppose we could allow for differing orders (but equal parameter domain).

    // Ported from SISL routine s6multsfs().
    int order = max(2*(patch1.order_u() - 1) + 1, 2*(patch1.order_v() - 1) + 1);;
    vector<double> pascal((order+1)*(order+2)/2, 0.0); // Binomial coefficients (Pascal's triangle)
    int ki, kj;
    vector<double>::iterator psl1;     /* Pointer used in Pascals triangle */
    vector<double>::iterator psl2;     /* Pointer used in Pascals triangle */
    for(ki = 0, psl2 = pascal.begin(); ki <= order ; ki++, psl1 = psl2, psl2 += ki) {
	psl2[0] = 1.0;

	for(kj = 1; kj < ki; kj++)
	    psl2[kj] = psl1[kj-1] + psl1[kj];

	psl2[ki] = 1.0;
    }

    int order11 = patch1.order_u();
    int order12 = patch1.order_v();
    int order21 = patch2.order_u();
    int order22 = patch2.order_v();

    vector<double>::const_iterator c1 = patch1.coefs_begin();
    vector<double>::const_iterator c2 = patch2.coefs_begin();

    //     vector<double> mult_coefs(patch1.numCoefs_u()*patch1.numCoefs_v()*patch1.dimension(), 0.0);
    int p1,p2,r1,r2;
    int kgrad11 = order11-1;
    int kgrad12 = order12-1;
    int kgrad21 = order21-1;
    int kgrad22 = order22-1;
    int kgrad1  =  kgrad11 + kgrad21; // Degree of mult basis functions in 1st dir.
    int kgrad2  =  kgrad12 + kgrad22;
    int kstop2 = order12+order22-1;
    int kstop1 = order11+order21-1;
    vector<double> mult_coefs(kstop1*kstop2, 0.0);
    vector<double>::const_iterator psl_kgrad11 = pascal.begin()+kgrad11*(kgrad11+1)/2;
    vector<double>::const_iterator psl_kgrad12 = pascal.begin()+kgrad12*(kgrad12+1)/2;
    vector<double>::const_iterator psl_kgrad21 = pascal.begin()+kgrad21*(kgrad21+1)/2;
    vector<double>::const_iterator psl_kgrad22 = pascal.begin()+kgrad22*(kgrad22+1)/2;
    vector<double>::const_iterator psl_kgrad1  = pascal.begin()+kgrad1 *(kgrad1 +1)/2;
    vector<double>::const_iterator psl_kgrad2  = pascal.begin()+kgrad2 *(kgrad2 +1)/2;
    vector<double>::const_iterator qsc1, qsc2;
    double tsum, sumi;
    vector<double>::iterator temp = mult_coefs.begin();
    double tdiv, t2;
    int kstop3, kstop4;

    for (p2 = 0; p2 < kstop2; ++p2)
	for (p1 = 0; p1 <kstop1; p1++, temp++) {
	    tdiv  =  psl_kgrad1[p1]*psl_kgrad2[p2];
	    kstop4  =  min(p2,kgrad12);
	    for (r2 = max(0,p2-kgrad22),tsum = 0.0; r2 <= kstop4; r2++) {
		t2  =  psl_kgrad12[r2]*psl_kgrad22[p2-r2];
		kstop3  =  min(p1,kgrad11);
		for (r1 = max(0,p1-kgrad21),sumi = 0.0,
			 qsc1 = c1+r2*order11,qsc2 = c2+(p2-r2)*order21;
		     r1 <= kstop3; r1++)
		    sumi +=  psl_kgrad11[r1]*psl_kgrad21[p1-r1]*qsc1[r1]*qsc2[p1-r1];
		tsum +=  t2*sumi;
	    }
	    tsum /=  tdiv;
	    *temp  =  tsum;
	}
    //     *order_newsurf1 = kstop1;
    //     *order_newsurf2 = kstop2; 

    // We must add knots to input basises according to new order.
    vector<double> new_knots_u, new_knots_v;
    new_knots_u.insert(new_knots_u.begin(), kstop1, patch1.startparam_u());
    new_knots_u.insert(new_knots_u.end(), kstop1, patch1.endparam_u());
    new_knots_v.insert(new_knots_v.begin(), kstop2, patch1.startparam_v());
    new_knots_v.insert(new_knots_v.end(), kstop2, patch1.endparam_v());

    // Finally we create the spline sf with the multiplied coefs.
    shared_ptr<SplineSurface> mult_sf(new SplineSurface(kstop1, kstop2, kstop1, kstop2,
							       new_knots_u.begin(), new_knots_v.begin(),
							       mult_coefs.begin(), patch1.dimension(),
							       patch1.rational()));
    //     SplineSurface* mult_sf = new SplineSurface(patch1.numCoefs_u(), patch1.numCoefs_v(),
    // 					       patch1.order_u(), patch1.order_v(),
    // 					       patch1.basis_u().begin(), patch1.basis_v().begin(),
    // 					       mult_coefs.begin(), patch1.dimension(),
    // 					       patch1.rational());

    return mult_sf;
}