Fixed DnD function for volumes inside the object in respect to the volume type

This commit is contained in:
YuSanka 2021-05-26 15:36:02 +02:00
parent 980ca195f5
commit b7769856d1
7 changed files with 106 additions and 28 deletions

View file

@ -156,8 +156,8 @@ const std::vector<std::pair<std::string, std::string>> MenuFactory::ADD_VOLUME_M
{L("Add part"), "add_part" }, // ~ModelVolumeType::MODEL_PART
{L("Add negative volume"), "add_negative" }, // ~ModelVolumeType::NEGATIVE_VOLUME
{L("Add modifier"), "add_modifier"}, // ~ModelVolumeType::PARAMETER_MODIFIER
{L("Add support blocker"), "support_blocker"}, // ~ModelVolumeType::SUPPORT_BLOCKER
{L("Add support enforcer"), "support_enforcer"}, // ~ModelVolumeType::SUPPORT_ENFORCER
{L("Add support blocker"), "support_blocker"} // ~ModelVolumeType::SUPPORT_BLOCKER
};
static Plater* plater()

View file

@ -1135,8 +1135,44 @@ bool ObjectList::can_drop(const wxDataViewItem& item) const
return false;
// move volumes inside one object only
if (m_dragged_data.type() & itVolume)
return m_dragged_data.obj_idx() == m_objects_model->GetObjectIdByItem(item);
if (m_dragged_data.type() & itVolume) {
if (m_dragged_data.obj_idx() != m_objects_model->GetObjectIdByItem(item))
return false;
wxDataViewItem dragged_item = m_objects_model->GetItemByVolumeId(m_dragged_data.obj_idx(), m_dragged_data.sub_obj_idx());
if (!dragged_item)
return false;
ModelVolumeType item_v_type = m_objects_model->GetVolumeType(item);
ModelVolumeType dragged_item_v_type = m_objects_model->GetVolumeType(dragged_item);
if (dragged_item_v_type == item_v_type && dragged_item_v_type != ModelVolumeType::MODEL_PART)
return true;
if (wxGetApp().app_config->get("order_volumes") == "1" || // we can't reorder volumes outside of types
item_v_type >= ModelVolumeType::SUPPORT_BLOCKER) // support blockers/enforcers can't change its place
return false;
bool only_one_solid_part = true;
auto& volumes = (*m_objects)[m_dragged_data.obj_idx()]->volumes;
for (size_t cnt, id = cnt = 0; id < volumes.size() && cnt < 2; id ++)
if (volumes[id]->type() == ModelVolumeType::MODEL_PART) {
if (++cnt > 1)
only_one_solid_part = false;
}
if (dragged_item_v_type == ModelVolumeType::MODEL_PART) {
if (only_one_solid_part)
return false;
return (m_objects_model->GetVolumeIdByItem(item) == 0 ||
(m_dragged_data.sub_obj_idx()==0 && volumes[1]->type() == ModelVolumeType::MODEL_PART) ||
(m_dragged_data.sub_obj_idx()!=0 && volumes[0]->type() == ModelVolumeType::MODEL_PART));
}
if ((dragged_item_v_type == ModelVolumeType::NEGATIVE_VOLUME || dragged_item_v_type == ModelVolumeType::PARAMETER_MODIFIER)) {
if (only_one_solid_part)
return false;
return m_objects_model->GetVolumeIdByItem(item) != 0;
}
return false;
}
return true;
}
@ -1375,8 +1411,7 @@ void ObjectList::load_part( ModelObject* model_object,
}
for (auto volume : object->volumes) {
volume->translate(delta);
auto new_volume = model_object->add_volume(*volume);
new_volume->set_type(type);
auto new_volume = model_object->add_volume(*volume, type);
new_volume->name = boost::filesystem::path(input_file).filename().string();
volumes_info.push_back(std::make_pair(from_u8(new_volume->name), new_volume->get_mesh_errors_count()>0));
@ -1446,8 +1481,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
TriangleMesh mesh = create_mesh(type_name, instance_bb);
// Mesh will be centered when loading.
ModelVolume *new_volume = model_object.add_volume(std::move(mesh));
new_volume->set_type(type);
ModelVolume *new_volume = model_object.add_volume(std::move(mesh), type);
if (instance_idx != -1)
{

View file

@ -329,7 +329,25 @@ wxDataViewItem ObjectDataViewModel::AddVolumeChild( const wxDataViewItem &parent
if (insert_position >= 0) insert_position++;
}
const auto node = new ObjectDataViewModelNode(root, name, GetVolumeIcon(volume_type, has_errors), extruder_str, root->m_volumes_cnt);
size_t new_volume_id = root->m_volumes_cnt;
// find insert_position in respect to the volume type
for (int pos = (insert_position < 0 ? (int)root->GetChildCount() : insert_position) - 1; pos >= 0; pos--) {
ObjectDataViewModelNode* node = root->GetNthChild(pos);
if (volume_type >= node->m_volume_type) {
insert_position = pos + 1;
new_volume_id = (size_t)(node->GetIdx()) + 1;
for (int new_pos = pos + 1; new_pos < (int)root->GetChildCount(); new_pos++) {
ObjectDataViewModelNode* new_node = root->GetNthChild(new_pos);
if (new_node->GetType() != itVolume)
break;
new_node->SetIdx(new_node->GetIdx() + 1);
}
break;
}
}
const auto node = new ObjectDataViewModelNode(root, name, GetVolumeIcon(volume_type, has_errors), extruder_str, new_volume_id);
insert_position < 0 ? root->Append(node) : root->Insert(node, insert_position);
// if part with errors is added, but object wasn't marked, then mark it

View file

@ -312,6 +312,14 @@ void PreferencesDialog::build()
option = Option(def, "color_mapinulation_panel");
m_optgroup_gui->append_single_option_line(option);
def.label = L("Order object volumes by types");
def.type = coBool;
def.tooltip = L("If enabled, volumes will be always ordered inside the object. Correct order is Model Part, Negative Volume, Modifier, Support Blocker and Support Enforcer. "
"If disabled, you can reorder Model Parts, Negative Volumes and Modifiers. But one of the model parts have to be on the first place.");
def.set_default_value(new ConfigOptionBool{ app_config->get("order_volumes") == "1" });
option = Option(def, "order_volumes");
m_optgroup_gui->append_single_option_line(option);
def.label = L("Use custom size for toolbar icons");
def.type = coBool;
def.tooltip = L("If enabled, you can change size of toolbar icons manually.");