Ejemplo n.º 1
0
std::vector< bool > SliceDataStorage::getExtrudersUsed()
{

    std::vector<bool> ret;
    ret.resize(meshgroup->getExtruderCount(), false);

    ret[getSettingAsIndex("adhesion_extruder_nr")] = true; 
    { // process brim/skirt
        for (int extr_nr = 0; extr_nr < meshgroup->getExtruderCount(); extr_nr++)
        {
            if (skirt[extr_nr].size() > 0)
            {
                ret[extr_nr] = true;
                continue;
            }
        }
    }

    // TODO: ooze shield, draft shield ..?

    // support
    // support is presupposed to be present...
    ret[getSettingAsIndex("support_extruder_nr_layer_0")] = true;
    ret[getSettingAsIndex("support_extruder_nr")] = true;
    ret[getSettingAsIndex("support_roof_extruder_nr")] = true;

    // all meshes are presupposed to actually have content
    for (SliceMeshStorage& mesh : meshes)
    {
        ret[mesh.getSettingAsIndex("extruder_nr")] = true;
    }
    return ret;
}
Ejemplo n.º 2
0
std::vector<bool> SliceDataStorage::getExtrudersUsed(int layer_nr)
{
    std::vector<bool> ret;
    ret.resize(meshgroup->getExtruderCount(), false);
    if (layer_nr < 0)
    {
        ret[getSettingAsIndex("adhesion_extruder_nr")] = true; // raft
    }
    else 
    {
        if (layer_nr == 0)
        { // process brim/skirt
            for (int extr_nr = 0; extr_nr < meshgroup->getExtruderCount(); extr_nr++)
            {
                if (skirt[extr_nr].size() > 0)
                {
                    ret[extr_nr] = true;
                    continue;
                }
            }
        }

        // TODO: ooze shield, draft shield

        // support
        if (support.supportLayers[layer_nr].supportAreas.size() > 0)
        {
            if (layer_nr == 0)
            {
                ret[getSettingAsIndex("support_extruder_nr_layer_0")] = true;
            }
            else 
            {
                ret[getSettingAsIndex("support_extruder_nr")] = true;
            }
        }
        if (support.supportLayers[layer_nr].roofs.size() > 0)
        {
            ret[getSettingAsIndex("support_roof_extruder_nr")] = true;
        }

        for (SliceMeshStorage& mesh : meshes)
        {
            SliceLayer& layer = mesh.layers[layer_nr];
            int extr_nr = mesh.getSettingAsIndex("extruder_nr");
            if (layer.parts.size() > 0)
            {
                ret[extr_nr] = true;
            }
        }
    }
    return ret;
}
Ejemplo n.º 3
0
SliceDataStorage::SliceDataStorage(MeshGroup* meshgroup) : SettingsMessenger(meshgroup),
    meshgroup(meshgroup != nullptr ? meshgroup : new MeshGroup(FffProcessor::getInstance())), //If no mesh group is provided, we roll our own.
    retraction_config_per_extruder(initializeRetractionConfigs()),
    travel_config_per_extruder(initializeTravelConfigs()),
    skirt_config(initializeSkirtConfigs()),
    raft_base_config(&retraction_config_per_extruder[getSettingAsIndex("adhesion_extruder_nr")], PrintFeatureType::Support),
    raft_interface_config(&retraction_config_per_extruder[getSettingAsIndex("adhesion_extruder_nr")], PrintFeatureType::Support),
    raft_surface_config(&retraction_config_per_extruder[getSettingAsIndex("adhesion_extruder_nr")], PrintFeatureType::Support),
    support_config(&retraction_config_per_extruder[getSettingAsIndex("support_infill_extruder_nr")], PrintFeatureType::Support),
    support_roof_config(&retraction_config_per_extruder[getSettingAsIndex("support_roof_extruder_nr")], PrintFeatureType::Skin),
    max_object_height_second_to_last_extruder(-1)
{
}
Ejemplo n.º 4
0
std::vector<bool> SliceDataStorage::getExtrudersUsed() const
{

    std::vector<bool> ret;
    ret.resize(meshgroup->getExtruderCount(), false);

    if (getSettingAsPlatformAdhesion("adhesion_type") != EPlatformAdhesion::NONE)
    {
        ret[getSettingAsIndex("adhesion_extruder_nr")] = true;
        { // process brim/skirt
            for (int extr_nr = 0; extr_nr < meshgroup->getExtruderCount(); extr_nr++)
            {
                if (skirt_brim[extr_nr].size() > 0)
                {
                    ret[extr_nr] = true;
                    continue;
                }
            }
        }
    }

    // TODO: ooze shield, draft shield ..?

    // support
    // support is presupposed to be present...
    ret[getSettingAsIndex("support_extruder_nr_layer_0")] = true;
    ret[getSettingAsIndex("support_infill_extruder_nr")] = true;
    ret[getSettingAsIndex("support_interface_extruder_nr")] = true;

    // all meshes are presupposed to actually have content
    for (const SliceMeshStorage& mesh : meshes)
    {
        if (!mesh.getSettingBoolean("anti_overhang_mesh")
            && !mesh.getSettingBoolean("support_mesh")
        )
        {
            ret[mesh.getSettingAsIndex("extruder_nr")] = true;
        }
    }
    return ret;
}
Ejemplo n.º 5
0
void FffPolygonGenerator::processWipeTower(SliceDataStorage& storage, unsigned int totalLayers)
{
    
    
    // TODO: move this code into its own function?
    { // compute storage.max_object_height_second_to_last_extruder, which is used to determine the highest point in the wipe tower
        
        int max_object_height_per_extruder[MAX_EXTRUDERS];
        { // compute max_object_height_per_extruder
            memset(max_object_height_per_extruder, -1, sizeof(max_object_height_per_extruder));
            for (SliceMeshStorage& mesh : storage.meshes)
            {
                max_object_height_per_extruder[mesh.settings->getSettingAsIndex("extruder_nr")] = 
                    std::max(   max_object_height_per_extruder[mesh.settings->getSettingAsIndex("extruder_nr")]
                            ,   mesh.layer_nr_max_filled_layer  ); 
            }
            int support_extruder_nr = getSettingAsIndex("support_extruder_nr");
            max_object_height_per_extruder[support_extruder_nr] = 
            std::max(   max_object_height_per_extruder[support_extruder_nr]
                    ,   storage.support.layer_nr_max_filled_layer  ); 
        }
        { // // compute max_object_height_second_to_last_extruder
            int extruder_max_object_height = 0;
            for (unsigned int extruder_nr = 1; extruder_nr < MAX_EXTRUDERS; extruder_nr++)
            {
                if (max_object_height_per_extruder[extruder_nr] > max_object_height_per_extruder[extruder_max_object_height])
                {
                    extruder_max_object_height = extruder_nr;
                }
            }
            int extruder_second_max_object_height = -1;
            for (int extruder_nr = 0; extruder_nr < MAX_EXTRUDERS; extruder_nr++)
            {
                if (extruder_nr == extruder_max_object_height) { continue; }
                if (max_object_height_per_extruder[extruder_nr] > max_object_height_per_extruder[extruder_second_max_object_height])
                {
                    extruder_second_max_object_height = extruder_nr;
                }
            }
            if (extruder_second_max_object_height < 0)
            {
                storage.max_object_height_second_to_last_extruder = -1;
            }
            else 
            {
                storage.max_object_height_second_to_last_extruder = max_object_height_per_extruder[extruder_second_max_object_height];
            }
        }
    }
       
        
    if (storage.max_object_height_second_to_last_extruder >= 0 && getSettingInMicrons("wipe_tower_distance") > 0 && getSettingInMicrons("wipe_tower_size") > 0)
    {
        PolygonRef p = storage.wipeTower.newPoly();
        int tower_size = getSettingInMicrons("wipe_tower_size");
        int tower_distance = getSettingInMicrons("wipe_tower_distance");
        p.add(Point(storage.model_min.x - tower_distance, storage.model_max.y + tower_distance));
        p.add(Point(storage.model_min.x - tower_distance, storage.model_max.y + tower_distance + tower_size));
        p.add(Point(storage.model_min.x - tower_distance - tower_size, storage.model_max.y + tower_distance + tower_size));
        p.add(Point(storage.model_min.x - tower_distance - tower_size, storage.model_max.y + tower_distance));

        storage.wipePoint = Point(storage.model_min.x - tower_distance - tower_size / 2, storage.model_max.y + tower_distance + tower_size / 2);
    }
}
Ejemplo n.º 6
0
bool FffPolygonGenerator::sliceModel(MeshGroup* meshgroup, TimeKeeper& timeKeeper, SliceDataStorage& storage) /// slices the model
{
    Progress::messageProgressStage(Progress::Stage::SLICING, &timeKeeper);
    
    storage.model_min = meshgroup->min();
    storage.model_max = meshgroup->max();
    storage.model_size = storage.model_max - storage.model_min;

    log("Slicing model...\n");
    int initial_layer_thickness = getSettingInMicrons("layer_height_0");
    if(initial_layer_thickness <= 0) //Initial layer height of 0 is not allowed. Negative layer height is nonsense.
    {
        logError("Initial layer height %i is disallowed.",initial_layer_thickness);
        return false;
    }
    int layer_thickness = getSettingInMicrons("layer_height");
    if(layer_thickness <= 0) //Layer height of 0 is not allowed. Negative layer height is nonsense.
    {
        logError("Layer height %i is disallowed.",layer_thickness);
        return false;
    }
    int initial_slice_z = initial_layer_thickness - layer_thickness / 2;
    int layer_count = (storage.model_max.z - initial_slice_z) / layer_thickness + 1;
    if(layer_count <= 0) //Model is shallower than layer_height_0, so not even the first layer is sliced. Return an empty model then.
    {
        return true; //This is NOT an error state!
    }

    std::vector<Slicer*> slicerList;
    for(unsigned int mesh_idx = 0; mesh_idx < meshgroup->meshes.size(); mesh_idx++)
    {
        Mesh& mesh = meshgroup->meshes[mesh_idx];
        Slicer* slicer = new Slicer(&mesh, initial_slice_z, layer_thickness, layer_count, mesh.getSettingBoolean("meshfix_keep_open_polygons"), mesh.getSettingBoolean("meshfix_extensive_stitching"));
        slicerList.push_back(slicer);
        /*
        for(SlicerLayer& layer : slicer->layers)
        {
            //Reporting the outline here slows down the engine quite a bit, so only do so when debugging.
            sendPolygons("outline", layer_nr, layer.z, layer.polygonList);
            sendPolygons("openoutline", layer_nr, layer.openPolygonList);
        }
        */
        Progress::messageProgress(Progress::Stage::SLICING, mesh_idx + 1, meshgroup->meshes.size());
    }
    
    log("Layer count: %i\n", layer_count);

    meshgroup->clear();///Clear the mesh face and vertex data, it is no longer needed after this point, and it saves a lot of memory.

    Progress::messageProgressStage(Progress::Stage::PARTS, &timeKeeper);
    //carveMultipleVolumes(storage.meshes);
    generateMultipleVolumesOverlap(slicerList);
    // TODO!!! dont generate multi volume overlap with infill meshes!
    
    storage.meshes.reserve(slicerList.size()); // causes there to be no resize in meshes so that the pointers in sliceMeshStorage._config to retraction_config don't get invalidated.
    for(unsigned int meshIdx=0; meshIdx < slicerList.size(); meshIdx++)
    {
        storage.meshes.emplace_back(&meshgroup->meshes[meshIdx]); // new mesh in storage had settings from the Mesh
        SliceMeshStorage& meshStorage = storage.meshes.back();
        Mesh& mesh = storage.meshgroup->meshes[meshIdx];
        
        
        createLayerParts(meshStorage, slicerList[meshIdx], mesh.getSettingBoolean("meshfix_union_all"), mesh.getSettingBoolean("meshfix_union_all_remove_holes"));
        delete slicerList[meshIdx];

        bool has_raft = meshStorage.getSettingAsPlatformAdhesion("adhesion_type") == EPlatformAdhesion::RAFT;
        //Add the raft offset to each layer.
        for(unsigned int layer_nr=0; layer_nr<meshStorage.layers.size(); layer_nr++)
        {
            SliceLayer& layer = meshStorage.layers[layer_nr];
            meshStorage.layers[layer_nr].printZ += 
                getSettingInMicrons("layer_height_0")
                - initial_slice_z;
            if (has_raft)
            {
                ExtruderTrain* train = storage.meshgroup->getExtruderTrain(getSettingAsIndex("adhesion_extruder_nr"));
                layer.printZ += 
                    train->getSettingInMicrons("raft_base_thickness") 
                    + train->getSettingInMicrons("raft_interface_thickness") 
                    + train->getSettingAsCount("raft_surface_layers") * getSettingInMicrons("raft_surface_thickness")
                    + train->getSettingInMicrons("raft_airgap")
                    - train->getSettingInMicrons("layer_0_z_overlap"); // shift all layers (except 0) down
                if (layer_nr == 0)
                {
                    layer.printZ += train->getSettingInMicrons("layer_0_z_overlap"); // undo shifting down of first layer
                }
            }
    
 
            if (layer.parts.size() > 0 || (mesh.getSettingAsSurfaceMode("magic_mesh_surface_mode") != ESurfaceMode::NORMAL && layer.openPolyLines.size() > 0) )
            {
                meshStorage.layer_nr_max_filled_layer = layer_nr; // last set by the highest non-empty layer
            } 
                
            if (CommandSocket::isInstantiated())
            {
                CommandSocket::getInstance()->sendLayerInfo(layer_nr, layer.printZ, layer_nr == 0? getSettingInMicrons("layer_height_0") : getSettingInMicrons("layer_height"));
            }
        }
        
        Progress::messageProgress(Progress::Stage::PARTS, meshIdx + 1, slicerList.size());
    }
    return true;
}
Ejemplo n.º 7
0
std::vector<bool> SliceDataStorage::getExtrudersUsed(int layer_nr) const
{

    std::vector<bool> ret;
    ret.resize(meshgroup->getExtruderCount(), false);

    bool include_adhesion = true;
    bool include_helper_parts = true;
    bool include_models = true;
    if (layer_nr < 0)
    {
        include_models = false;
        if (layer_nr < -Raft::getFillerLayerCount(*this))
        {
            include_helper_parts = false;
        }
        else
        {
            layer_nr = 0; // because the helper parts are copied from the initial layer in the filler layer
            include_adhesion = false;
        }
    }
    else if (layer_nr > 0 || getSettingAsPlatformAdhesion("adhesion_type") == EPlatformAdhesion::RAFT)
    { // only include adhesion only for layers where platform adhesion actually occurs
        // i.e. layers < 0 are for raft, layer 0 is for brim/skirt
        include_adhesion = false;
    }
    if (include_adhesion)
    {
        ret[getSettingAsIndex("adhesion_extruder_nr")] = true;
        { // process brim/skirt
            for (int extr_nr = 0; extr_nr < meshgroup->getExtruderCount(); extr_nr++)
            {
                if (skirt_brim[extr_nr].size() > 0)
                {
                    ret[extr_nr] = true;
                    continue;
                }
            }
        }
    }

    // TODO: ooze shield, draft shield ..?

    if (include_helper_parts)
    {
        // support
        if (layer_nr < int(support.supportLayers.size()))
        {
            const SupportLayer& support_layer = support.supportLayers[layer_nr];
            if (layer_nr == 0)
            {
                if (support_layer.supportAreas.size() > 0)
                {
                    ret[getSettingAsIndex("support_extruder_nr_layer_0")] = true;
                }
            }
            else
            {
                if (support_layer.supportAreas.size() > 0)
                {
                    ret[getSettingAsIndex("support_infill_extruder_nr")] = true;
                }
            }
            if (support_layer.skin.size() > 0)
            {
                ret[getSettingAsIndex("support_interface_extruder_nr")] = true;
            }
        }
    }

    if (include_models)
    {
        for (const SliceMeshStorage& mesh : meshes)
        {
            if (layer_nr >= int(mesh.layers.size()))
            {
                continue;
            }
            const SliceLayer& layer = mesh.layers[layer_nr];
            if (layer.parts.size() > 0)
            {
                ret[mesh.getSettingAsIndex("extruder_nr")] = true;
            }
        }
    }
    return ret;
}
Ejemplo n.º 8
0
void MeshGroup::finalize()
{
    extruder_count = getSettingAsCount("machine_extruder_count");

    for (int extruder_nr = 0; extruder_nr < extruder_count; extruder_nr++)
    {
        createExtruderTrain(extruder_nr); // create it if it didn't exist yet

        if (getSettingAsIndex("adhesion_extruder_nr") == extruder_nr && getSettingAsPlatformAdhesion("adhesion_type") != EPlatformAdhesion::NONE)
        {
            getExtruderTrain(extruder_nr)->setIsUsed(true);
            continue;
        }

        for (const Mesh& mesh : meshes)
        {
            if (mesh.getSettingBoolean("support_enable")
                && (
                    getSettingAsIndex("support_infill_extruder_nr") == extruder_nr
                    || getSettingAsIndex("support_extruder_nr_layer_0") == extruder_nr
                    || (getSettingBoolean("support_interface_enable") && getSettingAsIndex("support_interface_extruder_nr") == extruder_nr)
                    )
                )
            {
                getExtruderTrain(extruder_nr)->setIsUsed(true);
                break;
            }
        }
    }

    for (const Mesh& mesh : meshes)
    {
        if (!mesh.getSettingBoolean("anti_overhang_mesh")
            && !mesh.getSettingBoolean("support_mesh")
        )
        {
            getExtruderTrain(mesh.getSettingAsIndex("extruder_nr"))->setIsUsed(true);
        }
    }

    //If the machine settings have been supplied, offset the given position vertices to the center of vertices (0,0,0) is at the bed center.
    Point3 meshgroup_offset(0, 0, 0);
    if (!getSettingBoolean("machine_center_is_zero"))
    {
        meshgroup_offset.x = getSettingInMicrons("machine_width") / 2;
        meshgroup_offset.y = getSettingInMicrons("machine_depth") / 2;
    }
    
    // If a mesh position was given, put the mesh at this position in 3D space. 
    for(Mesh& mesh : meshes)
    {
        Point3 mesh_offset(mesh.getSettingInMicrons("mesh_position_x"), mesh.getSettingInMicrons("mesh_position_y"), mesh.getSettingInMicrons("mesh_position_z"));
        if (mesh.getSettingBoolean("center_object"))
        {
            Point3 object_min = mesh.min();
            Point3 object_max = mesh.max();
            Point3 object_size = object_max - object_min;
            mesh_offset += Point3(-object_min.x - object_size.x / 2, -object_min.y - object_size.y / 2, -object_min.z);
        }
        mesh.offset(mesh_offset + meshgroup_offset);
    }
}