#152manual seam placement tool, inspired from @dartrax pull request

Currently it only use the center of sphere, using the nearest z for each layer.
This commit is contained in:
supermerill 2020-08-19 12:31:07 +02:00
parent 8438de487b
commit a1acd5b167
11 changed files with 192 additions and 36 deletions

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.0"
id="Layer_1"
x="0px"
y="0px"
viewBox="0 0 16 16"
enable-background="new 0 0 16 16"
xml:space="preserve"
sodipodi:docname="add_seam.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata
id="metadata12"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs10"><linearGradient
id="linearGradient4549-6-6"
inkscape:collect="always"><stop
id="stop4568"
offset="0"
style="stop-color:#ed6b21;stop-opacity:1;" /><stop
id="stop4570"
offset="1"
style="stop-color:#808080;stop-opacity:1" /></linearGradient><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4549-6-6"
id="linearGradient4551"
x1="0.95844549"
y1="2.2075603"
x2="15.084078"
y2="2.2075603"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1,0,0,1,16.042524,0)" /></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1001"
id="namedview8"
showgrid="false"
inkscape:zoom="22.627417"
inkscape:cx="14.547048"
inkscape:cy="-0.37641358"
inkscape:window-x="-9"
inkscape:window-y="-9"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1" />
<path
style="fill:none;fill-opacity:1;stroke:#ed6b21;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="M 14.584078,1.5485052 V 14.453204 H 8.883029 v -1.370019"
id="path4526"
inkscape:connector-curvature="0" /><path
style="fill:#000000;fill-opacity:0;stroke:#808080;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="M 1.4805051,1.5636706 V 14.468368 h 5.701048 v -1.370019"
id="path4526-6"
inkscape:connector-curvature="0" /><path
style="fill:none;stroke:url(#linearGradient4551);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="M 14.584116,3.3604663 14.562019,1.5636706 1.4584455,1.5485056 v 1.8119611"
id="path4543"
inkscape:connector-curvature="0" /></svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -3120,7 +3120,7 @@ void GCode::split_at_seam_pos(ExtrusionLoop &loop, std::unique_ptr<EdgeGrid::Gri
Point last_pos = this->last_pos();
if (m_config.spiral_vase) {
loop.split_at(last_pos, false);
} else if (seam_position == spNearest || seam_position == spAligned || seam_position == spRear || seam_position == spHidden) {
} else if (seam_position == spNearest || seam_position == spAligned || seam_position == spRear || seam_position == spHidden || seam_position == spCustom) {
Polygon polygon = loop.polygon();
const coordf_t nozzle_dmr = EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, loop.paths.front().width);
const coord_t nozzle_r = coord_t(scale_(0.5 * nozzle_dmr) + 0.5);
@ -3128,6 +3128,33 @@ void GCode::split_at_seam_pos(ExtrusionLoop &loop, std::unique_ptr<EdgeGrid::Gri
// Retrieve the last start position for this object.
float last_pos_weight = 1.f;
if (seam_position == spCustom) {
// Seam is aligned to be nearest to the position of a "lambda-seam"-named modifier in this or any preceding layer
last_pos = m_layer->object()->bounding_box().center();
// Look for all lambda-seam-modifiers below current z, choose the highest one
ModelVolume *v_lambda_seam = nullptr;
Vec3d lambda_pos;
for (ModelVolume *v : m_layer->object()->model_object()->volumes)
if (v->is_seam_position()) {
Vec3d test_lambda_pos = m_layer->object()->model_object()->instances.front()->transform_vector(v->get_offset());
//use this one if the first or nearer (in z)
if (v_lambda_seam == nullptr || std::abs(m_layer->print_z - test_lambda_pos.z()) < std::abs(m_layer->print_z - lambda_pos.z())) {
v_lambda_seam = v;
lambda_pos = m_layer->object()->model_object()->instances.front()->transform_vector(v_lambda_seam->get_offset());
}
}
if (v_lambda_seam != nullptr) {
lambda_pos = m_layer->object()->model_object()->instances.front()->transform_vector(v_lambda_seam->get_offset(), true);
// Found, get the center point and apply rotation and scaling of Model instance. Continues to spAligned if not found or Weight set to Zero.
last_pos = Point::new_scale(lambda_pos.x(), lambda_pos.y());
// Weight is set by user and stored in the radius of the sphere
double weight_temp = (m_layer->object()->model_object()->instances.front()->transform_bounding_box(v_lambda_seam->mesh().bounding_box(), true).size().x() / 2.0);
last_pos_weight = std::max(0.0, std::round(100 * (weight_temp - 0.5)));
if (last_pos_weight <= 0.0)
seam_position = spHidden;
}
}
if (seam_position == spAligned) {
// Seam is aligned to the seam at the preceding layer.
if (m_layer != NULL && m_seam_position.count(m_layer->object()) > 0) {
@ -3202,7 +3229,9 @@ void GCode::split_at_seam_pos(ExtrusionLoop &loop, std::unique_ptr<EdgeGrid::Gri
std::min(lengths[i] - lengths[last_pos_proj_idx], lengths.back() - lengths[i] + lengths[last_pos_proj_idx]);
penalty -= last_pos_weight * bspline_kernel(dist_to_last_pos_proj / dist_max);
}
penalties[i] = std::max(0.f, penalty);
// Allow negative penalties to overcome penalty for overhangs when in Custom mode
penalties[i] = (seam_position == spCustom) ? penalty : std::max(0.f, penalty);
}
// Penalty for overhangs.
@ -3232,7 +3261,7 @@ void GCode::split_at_seam_pos(ExtrusionLoop &loop, std::unique_ptr<EdgeGrid::Gri
size_t idx_min = std::min_element(penalties.begin(), penalties.end()) - penalties.begin();
// if (seam_position == spAligned)
// For all (aligned, nearest, rear) seams:
// For all (aligned, nearest, rear, hidden, custom) seams:
{
// Very likely the weight of idx_min is very close to the weight of last_pos_proj_idx.
// In that case use last_pos_proj_idx instead.

View File

@ -1622,6 +1622,8 @@ ModelVolumeType ModelVolume::type_from_string(const std::string &s)
return ModelVolumeType::SUPPORT_ENFORCER;
if (s == "SupportBlocker")
return ModelVolumeType::SUPPORT_BLOCKER;
if (s == "SeamPosition")
return ModelVolumeType::SEAM_POSITION;
assert(s == "0");
// Default value if invalud type string received.
return ModelVolumeType::MODEL_PART;
@ -1634,6 +1636,7 @@ std::string ModelVolume::type_to_string(const ModelVolumeType t)
case ModelVolumeType::PARAMETER_MODIFIER: return "ParameterModifier";
case ModelVolumeType::SUPPORT_ENFORCER: return "SupportEnforcer";
case ModelVolumeType::SUPPORT_BLOCKER: return "SupportBlocker";
case ModelVolumeType::SEAM_POSITION: return "SeamPosition";
default:
assert(false);
return "ModelPart";

View File

@ -389,6 +389,7 @@ enum class ModelVolumeType : int {
PARAMETER_MODIFIER,
SUPPORT_ENFORCER,
SUPPORT_BLOCKER,
SEAM_POSITION,
};
// An object STL, or a modifier volume, over which a different set of parameters shall be applied.
@ -429,7 +430,8 @@ public:
bool is_modifier() const { return m_type == ModelVolumeType::PARAMETER_MODIFIER; }
bool is_support_enforcer() const { return m_type == ModelVolumeType::SUPPORT_ENFORCER; }
bool is_support_blocker() const { return m_type == ModelVolumeType::SUPPORT_BLOCKER; }
bool is_support_modifier() const { return m_type == ModelVolumeType::SUPPORT_BLOCKER || m_type == ModelVolumeType::SUPPORT_ENFORCER; }
bool is_support_modifier() const { return m_type == ModelVolumeType::SUPPORT_BLOCKER || m_type == ModelVolumeType::SUPPORT_ENFORCER; }
bool is_seam_position() const { return m_type == ModelVolumeType::SEAM_POSITION; }
t_model_material_id material_id() const { return m_material_id; }
void set_material_id(t_model_material_id material_id);
ModelMaterial* material() const;

View File

@ -397,7 +397,7 @@ double Print::max_allowed_layer_height() const
// Add or remove support modifier ModelVolumes from model_object_dst to match the ModelVolumes of model_object_new
// in the exact order and with the same IDs.
// It is expected, that the model_object_dst already contains the non-support volumes of model_object_new in the correct order.
void Print::model_volume_list_update_supports(ModelObject &model_object_dst, const ModelObject &model_object_new)
void Print::model_volume_list_update_supports_seams(ModelObject &model_object_dst, const ModelObject &model_object_new)
{
typedef std::pair<const ModelVolume*, bool> ModelVolumeWithStatus;
std::vector<ModelVolumeWithStatus> old_volumes;
@ -420,7 +420,7 @@ void Print::model_volume_list_update_supports(ModelObject &model_object_dst, con
// For support modifiers, the type may have been switched from blocker to enforcer and vice versa.
assert((model_volume_dst->is_support_modifier() && model_volume_src->is_support_modifier()) || model_volume_dst->type() == model_volume_src->type());
model_object_dst.volumes.emplace_back(model_volume_dst);
if (model_volume_dst->is_support_modifier()) {
if (model_volume_dst->is_support_modifier() || model_volume_dst->is_seam_position()) {
// For support modifiers, the type may have been switched from blocker to enforcer and vice versa.
model_volume_dst->set_type(model_volume_src->type());
model_volume_dst->set_transformation(model_volume_src->get_transformation());
@ -428,7 +428,7 @@ void Print::model_volume_list_update_supports(ModelObject &model_object_dst, con
assert(model_volume_dst->get_matrix().isApprox(model_volume_src->get_matrix()));
} else {
// The volume was not found in the old list. Create a new copy.
assert(model_volume_src->is_support_modifier());
assert(model_volume_src->is_support_modifier() || model_volume_dst->is_seam_position());
model_object_dst.volumes.emplace_back(new ModelVolume(*model_volume_src));
model_object_dst.volumes.back()->set_model_object(&model_object_dst);
}
@ -895,7 +895,8 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
bool modifiers_differ = model_volume_list_changed(model_object, model_object_new, ModelVolumeType::PARAMETER_MODIFIER);
bool support_blockers_differ = model_volume_list_changed(model_object, model_object_new, ModelVolumeType::SUPPORT_BLOCKER);
bool support_enforcers_differ = model_volume_list_changed(model_object, model_object_new, ModelVolumeType::SUPPORT_ENFORCER);
if (model_parts_differ || modifiers_differ ||
bool seam_position_differ = model_volume_list_changed(model_object, model_object_new, ModelVolumeType::SEAM_POSITION);
if (model_parts_differ || modifiers_differ ||
model_object.origin_translation != model_object_new.origin_translation ||
model_object.layer_height_profile != model_object_new.layer_height_profile ||
! layer_height_ranges_equal(model_object.layer_config_ranges, model_object_new.layer_config_ranges, model_object_new.layer_height_profile.empty())) {
@ -916,7 +917,15 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
for (auto it = range.first; it != range.second; ++ it)
update_apply_status(it->print_object->invalidate_step(posSupportMaterial));
// Copy just the support volumes.
model_volume_list_update_supports(model_object, model_object_new);
model_volume_list_update_supports_seams(model_object, model_object_new);
}else if (seam_position_differ) {
// First stop background processing before shuffling or deleting the ModelVolumes in the ModelObject's list.
this->call_cancel_callback();
update_apply_status(false);
// Invalidate just the gcode step.
invalidate_step(psGCodeExport);
// Copy just the seam volumes.
model_volume_list_update_supports_seams(model_object, model_object_new);
}
if (! model_parts_differ && ! modifiers_differ) {
// Synchronize Object's config.
@ -1051,11 +1060,9 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
for (PrintRegion *region : m_regions)
region->m_refcnt = 0;
for (PrintObject *print_object : m_objects) {
int idx_region = 0;
for (const auto &volumes : print_object->region_volumes) {
if (! volumes.empty())
++ m_regions[idx_region]->m_refcnt;
++ idx_region;
for (int idx_region = 0; idx_region < print_object->region_volumes.size(); ++idx_region) {
if (!print_object->region_volumes[idx_region].empty())
++ m_regions[idx_region]->m_refcnt;
}
}

View File

@ -488,7 +488,7 @@ private:
void _make_wipe_tower();
// Declared here to have access to Model / ModelObject / ModelInstance
static void model_volume_list_update_supports(ModelObject &model_object_dst, const ModelObject &model_object_src);
static void model_volume_list_update_supports_seams(ModelObject &model_object_dst, const ModelObject &model_object_src);
PrintConfig m_config;
PrintObjectConfig m_default_object_config;

View File

@ -2551,18 +2551,25 @@ void PrintConfigDef::init_fff_params()
def = this->add("seam_position", coEnum);
def->label = L("Seam position");
def->category = OptionCategory::perimeter;
def->tooltip = L("Position of perimeters starting points.");
def->tooltip = L("Position of perimeters starting points."
"\n --- When using Custom ---"
"\nYou have to create one or more seam sphere in the context menu of the object."
" Note that the custom setting is automatically added to the object when creating a seam object,"
" so you shouldn't have to set it in the global config."
" The center of the seam sphere is used to position the seam. If you set multiple spheres, the nearest in z is chosen for a given layer.");
def->enum_keys_map = &ConfigOptionEnum<SeamPosition>::get_enum_values();
def->enum_values.push_back("random");
def->enum_values.push_back("near");
def->enum_values.push_back("aligned");
def->enum_values.push_back("rear");
def->enum_values.push_back("hidden");
def->enum_values.push_back("custom");
def->enum_labels.push_back(L("Random"));
def->enum_labels.push_back(L("Nearest"));
def->enum_labels.push_back(L("Aligned"));
def->enum_labels.push_back(L("Rear"));
def->enum_labels.push_back(L("Corners"));
def->enum_labels.push_back(L("Custom"));
def->mode = comSimple;
def->set_default_value(new ConfigOptionEnum<SeamPosition>(spHidden));

View File

@ -67,7 +67,7 @@ enum SupportMaterialPattern {
};
enum SeamPosition {
spRandom, spNearest, spAligned, spRear, spHidden
spRandom, spNearest, spAligned, spRear, spHidden, spCustom
};
enum SLAMaterial {
@ -207,6 +207,7 @@ template<> inline const t_config_enum_values& ConfigOptionEnum<SeamPosition>::ge
keys_map["aligned"] = spAligned;
keys_map["rear"] = spRear;
keys_map["hidden"] = spHidden;
keys_map["custom"] = spCustom;
}
return keys_map;
}

View File

@ -288,8 +288,8 @@ void GLVolume::set_color_from_model_volume(const ModelVolume *model_volume)
{
if (model_volume->is_modifier()) {
color[0] = 0.2f;
color[1] = 1.0f;
color[2] = 0.2f;
color[1] = 0.2f;
color[2] = 1.0f;
}
else if (model_volume->is_support_blocker()) {
color[0] = 1.0f;
@ -298,6 +298,11 @@ void GLVolume::set_color_from_model_volume(const ModelVolume *model_volume)
}
else if (model_volume->is_support_enforcer()) {
color[0] = 0.2f;
color[1] = 1.0f;
color[2] = 0.2f;
}
else if (model_volume->is_seam_position()) {
color[0] = 0.9f;
color[1] = 0.2f;
color[2] = 1.0f;
}

View File

@ -51,7 +51,8 @@ static std::vector<std::pair<std::string, std::string>> ADD_VOLUME_MENU_ITEMS =
{L("Add part"), "add_part" }, // ~ModelVolumeType::MODEL_PART
{L("Add modifier"), "add_modifier"}, // ~ModelVolumeType::PARAMETER_MODIFIER
{L("Add support enforcer"), "support_enforcer"}, // ~ModelVolumeType::SUPPORT_ENFORCER
{L("Add support blocker"), "support_blocker"} // ~ModelVolumeType::SUPPORT_BLOCKER
{L("Add support blocker"), "support_blocker"}, // ~ModelVolumeType::SUPPORT_BLOCKER
{L("Add seam position"), "add_seam"} // ~ModelVolumeType::SEAM_POSITION
};
static PrinterTechnology printer_technology()
@ -577,13 +578,15 @@ void ObjectList::init_icons()
m_bmp_solidmesh = ScalableBitmap(this, ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::MODEL_PART) ].second);
m_bmp_modifiermesh = ScalableBitmap(this, ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::PARAMETER_MODIFIER)].second);
m_bmp_support_enforcer = ScalableBitmap(this, ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_ENFORCER) ].second);
m_bmp_support_blocker = ScalableBitmap(this, ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_BLOCKER) ].second);
m_bmp_support_blocker = ScalableBitmap(this, ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_BLOCKER) ].second);
m_bmp_seam_position = ScalableBitmap(this, ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SEAM_POSITION) ].second);
m_bmp_vector.reserve(4); // bitmaps for different types of parts
m_bmp_vector.push_back(&m_bmp_solidmesh.bmp());
m_bmp_vector.push_back(&m_bmp_modifiermesh.bmp());
m_bmp_vector.push_back(&m_bmp_support_enforcer.bmp());
m_bmp_vector.push_back(&m_bmp_support_blocker.bmp());
m_bmp_vector.push_back(&m_bmp_solidmesh.bmp());
m_bmp_vector.push_back(&m_bmp_modifiermesh.bmp());
m_bmp_vector.push_back(&m_bmp_support_enforcer.bmp());
m_bmp_vector.push_back(&m_bmp_support_blocker.bmp());
m_bmp_vector.push_back(&m_bmp_seam_position.bmp());
// Set volumes default bitmaps for the model
@ -605,7 +608,8 @@ void ObjectList::msw_rescale_icons()
for (ScalableBitmap* bitmap : { &m_bmp_solidmesh, // Add part
&m_bmp_modifiermesh, // Add modifier
&m_bmp_support_enforcer, // Add support enforcer
&m_bmp_support_blocker }) // Add support blocker
&m_bmp_support_blocker, // Add support blocker
&m_bmp_seam_position }) // Add seam position
{
bitmap->msw_rescale();
m_bmp_vector.push_back(& bitmap->bmp());
@ -1442,12 +1446,15 @@ wxMenu* ObjectList::append_submenu_add_generic(wxMenu* menu, const ModelVolumeTy
sub_menu->AppendSeparator();
}
for (auto& item : { L("Box"), L("Cylinder"), L("Sphere"), L("Slab") })
std::vector<std::string> items = { "Box", "Cylinder", "Sphere", "Slab" };
if(type == ModelVolumeType::SEAM_POSITION) items = { "Sphere" };
for (std::string& item : items)
{
if (type == ModelVolumeType::INVALID && strncmp(item, "Slab", 4) == 0)
if (type == ModelVolumeType::INVALID && item == "Slab")
continue;
append_menu_item(sub_menu, wxID_ANY, _(item), "",
[this, type, item](wxCommandEvent&) { load_generic_subobject(item, type); }, "", menu);
append_menu_item(sub_menu, wxID_ANY, _(L(item)), "",
[this, type, item](wxCommandEvent&) { load_generic_subobject(L(item), type); }, "", menu);
}
return sub_menu;
@ -1481,6 +1488,10 @@ void ObjectList::append_menu_items_add_volume(wxMenu* menu)
[this](wxCommandEvent&) { load_generic_subobject(L("Box"), ModelVolumeType::SUPPORT_BLOCKER); },
ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_BLOCKER)].second, nullptr,
[this]() { return is_instance_or_object_selected(); }, parent);
append_menu_item(menu, wxID_ANY, _(ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SEAM_POSITION)].first), "",
[this](wxCommandEvent&) { load_generic_subobject(L("Sphere"), ModelVolumeType::SEAM_POSITION); },
ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SEAM_POSITION)].second, nullptr,
[this]() { return is_instance_or_object_selected(); }, parent);
return;
}
@ -1488,10 +1499,16 @@ void ObjectList::append_menu_items_add_volume(wxMenu* menu)
for (size_t type = (mode == comExpert || wxGetApp().app_config->get("objects_always_expert") == "1" ? 0 : 1) ; type < ADD_VOLUME_MENU_ITEMS.size(); type++)
{
auto& item = ADD_VOLUME_MENU_ITEMS[type];
wxMenu* sub_menu = append_submenu_add_generic(menu, ModelVolumeType(type));
append_submenu(menu, sub_menu, wxID_ANY, _(item.first), "", item.second,
[this]() { return is_instance_or_object_selected(); }, parent);
if (type == int(ModelVolumeType::SEAM_POSITION)) {
append_menu_item(menu, wxID_ANY, _(item.first), "",
[this](wxCommandEvent&) { load_generic_subobject(L("Sphere"), ModelVolumeType::SEAM_POSITION); },
item.second, nullptr,
[this]() { return is_instance_or_object_selected(); }, parent);
} else {
wxMenu* sub_menu = append_submenu_add_generic(menu, ModelVolumeType(type));
append_submenu(menu, sub_menu, wxID_ANY, _(item.first), "", item.second,
[this]() { return is_instance_or_object_selected(); }, parent);
}
}
}
@ -1969,7 +1986,7 @@ static TriangleMesh create_mesh(const std::string& type_name, const BoundingBoxf
else if (type_name == "Cylinder")
// Centered around 0, sitting on the print bed.
// The cylinder has the same volume as the box above.
mesh = make_cylinder(0.564 * side, side);
mesh = make_cylinder(0.564 * side, bb.size().z()>0 ? bb.size().z() : side);
else if (type_name == "Sphere")
// Centered around 0, half the sphere below the print bed, half above.
// The sphere has the same volume as the box above.
@ -2011,6 +2028,9 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
// Bounding box of the selected instance in world coordinate system including the translation, without modifiers.
BoundingBoxf3 instance_bb = model_object.instance_bounding_box(instance_idx);
if(type == ModelVolumeType::SEAM_POSITION)
model_object.config.set_key_value("seam_position", new ConfigOptionEnum<SeamPosition>(spCustom));
TriangleMesh mesh = create_mesh(type_name, instance_bb);
// Mesh will be centered when loading.
@ -2033,7 +2053,11 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
new_volume->set_offset(v->get_instance_transformation().get_matrix(true).inverse() * offset);
}
const wxString name = _(L("Generic")) + "-" + _(type_name);
std::string base_name = "Generic";
if (type == ModelVolumeType::SEAM_POSITION) base_name = "Seam";
if (type == ModelVolumeType::SUPPORT_ENFORCER) base_name = "Support";
if (type == ModelVolumeType::SUPPORT_BLOCKER) base_name = "Blocker";
const wxString name = _(L(base_name)) + "-" + _(type_name);
new_volume->name = into_u8(name);
// set a default extruder value, since user can't add it manually
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
@ -2049,6 +2073,8 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
//#ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
selection_changed();
//#endif //no __WXOSX__ //__WXMSW__
if (type == ModelVolumeType::SEAM_POSITION)
this->update_after_undo_redo();
}
void ObjectList::load_shape_object(const std::string& type_name)

View File

@ -127,6 +127,7 @@ private:
ScalableBitmap m_bmp_solidmesh;
ScalableBitmap m_bmp_support_enforcer;
ScalableBitmap m_bmp_support_blocker;
ScalableBitmap m_bmp_seam_position;
ScalableBitmap m_bmp_manifold_warning;
ScalableBitmap m_bmp_cog;