Ejemplo n.º 1
0
//===========================================================================
shared_ptr<SplineSurface> SurfaceCreators::mergeRationalParts(const SplineSurface& nom_sf,
							      const SplineSurface& den_sf,
							      bool weights_in_first)
//===========================================================================
{
    ASSERT((!nom_sf.rational()) && (!den_sf.rational()));
    ASSERT(den_sf.dimension() == 1);

    int dim = nom_sf.dimension();

    // We first make sure they share spline space.
    vector<shared_ptr<SplineSurface> > sfs;
    sfs.push_back(shared_ptr<SplineSurface>(nom_sf.clone()));
    sfs.push_back(shared_ptr<SplineSurface>(den_sf.clone()));
    double knot_diff_tol = 1e-06;
    GeometryTools::unifySurfaceSplineSpace(sfs, knot_diff_tol);

    vector<double> rcoefs;
    vector<double>::const_iterator iter = sfs[0]->coefs_begin();
    vector<double>::const_iterator riter = sfs[1]->coefs_begin();
    int num_coefs = sfs[0]->numCoefs_u()*sfs[0]->numCoefs_v();
    for (int ki = 0; ki < num_coefs; ++ki) {
	for (int kj = 0; kj < dim; ++kj) {
	    if (weights_in_first) {
		rcoefs.push_back(iter[ki*dim+kj]);
	    } else {
		rcoefs.push_back(iter[ki*dim+kj]*riter[ki]);
	    }
	}
	rcoefs.push_back(riter[ki]);
    }

    shared_ptr<SplineSurface> rat_sf(new SplineSurface
				     (sfs[0]->numCoefs_u(), sfs[0]->numCoefs_v(),
				      sfs[0]->order_u(), sfs[0]->order_v(),
				      sfs[0]->basis_u().begin(), sfs[0]->basis_v().begin(),
				      rcoefs.begin(), dim, true));

    return rat_sf;
}
Ejemplo n.º 2
0
shared_ptr<SplineSurface>
GeometryTools::surfaceSum(const SplineSurface& sf1, double fac1,
                          const SplineSurface& sf2, double fac2, double num_tol)

//********************************************************************
// Addition of two signed SplineSurfaces, i.e. this function can
// also be used for subtraction. The surfaces is assumed to live on
// the same parameter domain, but may have different knot vectors.
//********************************************************************
{
    // Check input
    ALWAYS_ERROR_IF(fabs(sf1.startparam_u() - sf2.startparam_u()) > num_tol ||
                    fabs(sf1.endparam_u() - sf2.endparam_u()) > num_tol ||
                    fabs(sf1.startparam_v() - sf2.startparam_v()) > num_tol ||
                    fabs(sf1.endparam_v() - sf2.endparam_v()) > num_tol,
                    "Inconsistent parameter domain.");

    // For the time being
    if (sf1.rational() || sf2.rational()) {
        THROW("Sum of rational surfaces is not implemented");
    }

    // Make copy of surfaces
    vector<shared_ptr<SplineSurface> > surfaces;
    surfaces.reserve(2);
    shared_ptr<SplineSurface> sf;
// #ifdef _MSC_VER
//     sf = shared_ptr<SplineSurface>(dynamic_cast<SplineSurface*>(sf1.clone()));
// #else
    sf = shared_ptr<SplineSurface>(sf1.clone());
// #endif
    surfaces.push_back(sf);
// #ifdef _MSC_VER
//     sf = shared_ptr<SplineSurface>(dynamic_cast<SplineSurface*>(sf2.clone()));
// #else
    sf = shared_ptr<SplineSurface>(sf2.clone());
// #endif
    surfaces.push_back(sf);

    // Make sure that the surfaces live on the same knot vector
    GeometryTools::unifySurfaceSplineSpace(surfaces, num_tol);

    // Add signed coefficients
    vector<double> coefs;
    int nmb_coefs_u = surfaces[0]->numCoefs_u();
    int nmb_coefs_v = surfaces[0]->numCoefs_v();
    int dim = surfaces[0]->dimension();
    coefs.resize(dim*nmb_coefs_u*nmb_coefs_v);
    int ki;
    std::vector<double>::iterator s1 = surfaces[0]->coefs_begin();
    std::vector<double>::iterator s2 = surfaces[1]->coefs_begin();
    for (ki=0; ki<dim*nmb_coefs_u*nmb_coefs_v; ki++)
        coefs[ki] = fac1*s1[ki] + fac2*s2[ki];

    // Create output curve
    shared_ptr<SplineSurface>
    surfacesum(new SplineSurface(nmb_coefs_u, nmb_coefs_v,
                                 surfaces[0]->order_u(),
                                 surfaces[0]->order_v(),
                                 surfaces[0]->basis_u().begin(),
                                 surfaces[0]->basis_v().begin(),
                                 &coefs[0], dim, false));

    return surfacesum;
}
Ejemplo n.º 3
0
//===========================================================================
shared_ptr<SplineSurface> SurfaceCreators::insertParamDomain(const SplineSurface& sf_1d)
//===========================================================================
{
    shared_ptr<SplineSurface> sf_1d_cp(sf_1d.clone());
    int dim = sf_1d.dimension();
    ASSERT(dim == 1);

    bool rat = sf_1d_cp->rational();
    // The returned object should be linear in the first two directions.
    // We create an additional 1d-sf describing the linear param space.
    vector<double> lin_knots_u(4, sf_1d_cp->startparam_u());
    lin_knots_u[2] = lin_knots_u[3] = sf_1d_cp->endparam_u();
    vector<double> lin_knots_v(4, sf_1d_cp->startparam_v());
    lin_knots_v[2] = lin_knots_v[3] = sf_1d_cp->endparam_v();
    int rdim = (rat) ? dim + 1 : dim;
    vector<double> lin_coefs_u(4, 1.0);
    lin_coefs_u[0] = lin_coefs_u[2] = lin_knots_u[0];
    lin_coefs_u[1] = lin_coefs_u[3] = lin_knots_u[2];
    shared_ptr<SplineSurface> lin_sf_u(new SplineSurface(2, 2, 2, 2,
							 lin_knots_u.begin(), lin_knots_v.begin(),
							 lin_coefs_u.begin(), 1));
    vector<double> lin_coefs_v(4*rdim, 1.0);
    lin_coefs_v[0] = lin_coefs_v[1] = lin_knots_v[0];
    lin_coefs_v[2] = lin_coefs_v[3] = lin_knots_v[2];
    shared_ptr<SplineSurface> lin_sf_v(new SplineSurface(2, 2, 2, 2,
							 lin_knots_u.begin(), lin_knots_v.begin(),
							 lin_coefs_v.begin(), 1));

    if (rat) {
	// We extract the rational part (i.e. the denominator sf) and mult it the linear parts.
	vector<shared_ptr<SplineSurface> > rat_parts = separateRationalParts(*sf_1d_cp);
	lin_sf_u = SurfaceCreators::mult1DSurfaces(*lin_sf_u, *rat_parts[1]);
	lin_sf_v = SurfaceCreators::mult1DSurfaces(*lin_sf_v, *rat_parts[1]);

	// We must then raise the order of sf_1d_cp by 1.
	rat_parts[0]->raiseOrder(1, 1);
	rat_parts[1]->raiseOrder(1, 1);
	sf_1d_cp = mergeRationalParts(*rat_parts[0], *rat_parts[1], false);
    } else {
	int raise_u = sf_1d_cp->order_u() - 2;
	int raise_v = sf_1d_cp->order_v() - 2;
	lin_sf_u->raiseOrder(raise_u, raise_v);
	lin_sf_v->raiseOrder(raise_u, raise_v);
    }

    // If not bezier we must also refine the space.
    int ik1 = sf_1d_cp->order_u();
    int ik2 = sf_1d_cp->order_v();
    int in1 = sf_1d_cp->numCoefs_u();
    int in2 = sf_1d_cp->numCoefs_v();
    if (ik1 < in1 || ik2 < in2)
      {
	vector<double> new_knots_u(sf_1d_cp->basis_u().begin() + ik1,
				   sf_1d_cp->basis_u().begin() + in1);
	vector<double> new_knots_v(sf_1d_cp->basis_v().begin() + ik2,
				   sf_1d_cp->basis_v().begin() + in2);
	lin_sf_u->insertKnot_u(new_knots_u);
	lin_sf_u->insertKnot_v(new_knots_v);
	lin_sf_v->insertKnot_u(new_knots_u);
	lin_sf_v->insertKnot_v(new_knots_v);
      }

    // Finally we create our space sf (i.e. living in a 3-dimensional env).
    vector<double> all_coefs;
    int coefs_size = sf_1d_cp->numCoefs_u()*sf_1d_cp->numCoefs_v();
    for (int ki = 0; ki < coefs_size; ++ki) {
	if (rat) {
	    all_coefs.push_back(lin_sf_u->coefs_begin()[ki*dim]);
	    all_coefs.push_back(lin_sf_v->coefs_begin()[ki*dim]);
	    all_coefs.push_back(sf_1d_cp->rcoefs_begin()[ki*rdim]);
	    all_coefs.push_back(sf_1d_cp->rcoefs_begin()[ki*rdim+1]);
	} else {
	    all_coefs.push_back(lin_sf_u->coefs_begin()[ki*dim]);
	    all_coefs.push_back(lin_sf_v->coefs_begin()[ki*dim]);
	    all_coefs.push_back(sf_1d_cp->coefs_begin()[ki*dim]);
	}
    }
    shared_ptr<SplineSurface> return_sf(new SplineSurface(sf_1d_cp->numCoefs_u(), sf_1d_cp->numCoefs_v(),
							  sf_1d_cp->order_u(), sf_1d_cp->order_v(),
							  sf_1d_cp->basis_u().begin(),
							  sf_1d_cp->basis_v().begin(),
							  all_coefs.begin(), 3, rat));

    return return_sf;
}