Пример #1
0
bool
Model::_arrange(const Pointfs &sizes, coordf_t dist, const BoundingBoxf* bb, Pointfs &out) const
{
    // we supply unscaled data to arrange()
    bool result = Slic3r::Geometry::arrange(
        sizes.size(),               // number of parts
        BoundingBoxf(sizes).max,    // width and height of a single cell
        dist,                       // distance between cells
        bb,                         // bounding box of the area to fill
        out                         // output positions
    );
    
    if (!result && bb != NULL) {
        // Try to arrange again ignoring bb
        result = Slic3r::Geometry::arrange(
            sizes.size(),               // number of parts
            BoundingBoxf(sizes).max,    // width and height of a single cell
            dist,                       // distance between cells
            NULL,                         // bounding box of the area to fill
            out                         // output positions
        );
    }
    
    return result;
}
Пример #2
0
/*  arrange objects preserving their instance count
    but altering their instance positions */
bool
Model::arrange_objects(coordf_t dist, const BoundingBoxf* bb)
{
    // get the (transformed) size of each instance so that we take
    // into account their different transformations when packing
    Pointfs instance_sizes;
    for (ModelObjectPtrs::const_iterator o = this->objects.begin(); o != this->objects.end(); ++o) {
        for (size_t i = 0; i < (*o)->instances.size(); ++i) {
            instance_sizes.push_back((*o)->instance_bounding_box(i).size());
        }
    }
    
    Pointfs positions;
    if (! this->_arrange(instance_sizes, dist, bb, positions))
        return false;
    
    for (ModelObjectPtrs::const_iterator o = this->objects.begin(); o != this->objects.end(); ++o) {
        for (ModelInstancePtrs::const_iterator i = (*o)->instances.begin(); i != (*o)->instances.end(); ++i) {
            (*i)->offset = positions.back();
            positions.pop_back();
        }
        (*o)->invalidate_bounding_box();
    }
    return true;
}
Пример #3
0
/*  duplicate the entire model preserving instance relative positions */
void
Model::duplicate(size_t copies_num, coordf_t dist, const BoundingBoxf* bb)
{
    Pointfs model_sizes(copies_num-1, this->bounding_box().size());
    Pointfs positions = this->_arrange(model_sizes, dist, bb);
    
    // note that this will leave the object count unaltered
    
    for (ModelObjectPtrs::const_iterator o = this->objects.begin(); o != this->objects.end(); ++o) {
        // make a copy of the pointers in order to avoid recursion when appending their copies
        ModelInstancePtrs instances = (*o)->instances;
        for (ModelInstancePtrs::const_iterator i = instances.begin(); i != instances.end(); ++i) {
            for (Pointfs::const_iterator pos = positions.begin(); pos != positions.end(); ++pos) {
                ModelInstance* instance = (*o)->add_instance(**i);
                instance->offset.translate(*pos);
            }
        }
        (*o)->invalidate_bounding_box();
    }
}
Пример #4
0
Pointfs
Model::_arrange(const Pointfs &sizes, coordf_t dist, const BoundingBoxf* bb) const
{
    // we supply unscaled data to arrange()
    return Slic3r::Geometry::arrange(
        sizes.size(),               // number of parts
        BoundingBoxf(sizes).max,    // width and height of a single cell
        dist,                       // distance between cells
        bb                          // bounding box of the area to fill
    );
}
Пример #5
0
// Follow an Archimedean spiral, in polar coordinates: r=a+b\theta
Pointfs FillArchimedeanChords::_generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y)
{
    // Radius to achieve.
    coordf_t rmax = std::sqrt(coordf_t(max_x)*coordf_t(max_x)+coordf_t(max_y)*coordf_t(max_y)) * std::sqrt(2.) + 1.5;
    // Now unwind the spiral.
    coordf_t a = 1.;
    coordf_t b = 1./(2.*M_PI);
    coordf_t theta = 0.;
    coordf_t r = 1;
    Pointfs out;
    //FIXME Vojtech: If used as a solid infill, there is a gap left at the center.
    out.push_back(Pointf(0, 0));
    out.push_back(Pointf(1, 0));
    while (r < rmax) {
        theta += 1. / r;
        r = a + b * theta;
        out.push_back(Pointf(r * cos(theta), r * sin(theta)));
    }
    return out;
}
Пример #6
0
Pointfs FillHilbertCurve::_generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y)
{
    // Minimum power of two square to fit the domain.
    size_t sz = 2;
    size_t pw = 1;
    {
        size_t sz0 = std::max(max_x + 1 - min_x, max_y + 1 - min_y);
        while (sz < sz0) {
            sz = sz << 1;
            ++ pw;
        }
    }

    size_t sz2 = sz * sz;
    Pointfs line;
    line.reserve(sz2);
    for (size_t i = 0; i < sz2; ++ i) {
        Point p = hilbert_n_to_xy(i);
        line.push_back(Pointf(p.x + min_x, p.y + min_y));
    }
    return line;
}
Пример #7
0
Pointfs FillOctagramSpiral::_generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y)
{
    // Radius to achieve.
    coordf_t rmax = std::sqrt(coordf_t(max_x)*coordf_t(max_x)+coordf_t(max_y)*coordf_t(max_y)) * std::sqrt(2.) + 1.5;
    // Now unwind the spiral.
    coordf_t r = 0;
    coordf_t r_inc = sqrt(2.);
    Pointfs out;
    out.push_back(Pointf(0, 0));
    while (r < rmax) {
        r += r_inc;
        coordf_t rx = r / sqrt(2.);
        coordf_t r2 = r + rx;
        out.push_back(Pointf( r,  0.));
        out.push_back(Pointf( r2, rx));
        out.push_back(Pointf( rx, rx));
        out.push_back(Pointf( rx, r2));
        out.push_back(Pointf(0.,  r));
        out.push_back(Pointf(-rx, r2));
        out.push_back(Pointf(-rx, rx));
        out.push_back(Pointf(-r2, rx));
        out.push_back(Pointf(-r,  0.));
        out.push_back(Pointf(-r2, -rx));
        out.push_back(Pointf(-rx, -rx));
        out.push_back(Pointf(-rx, -r2));
        out.push_back(Pointf(0., -r));
        out.push_back(Pointf( rx, -r2));
        out.push_back(Pointf( rx, -rx));
        out.push_back(Pointf( r2+r_inc, -rx));
    }
    return out;
}