Fixed DnD function for volumes inside the object in respect to the volume type
This commit is contained in:
parent
980ca195f5
commit
b7769856d1
@ -126,6 +126,9 @@ void AppConfig::set_defaults()
|
|||||||
|
|
||||||
if (get("color_mapinulation_panel").empty())
|
if (get("color_mapinulation_panel").empty())
|
||||||
set("color_mapinulation_panel", "0");
|
set("color_mapinulation_panel", "0");
|
||||||
|
|
||||||
|
if (get("order_volumes").empty())
|
||||||
|
set("order_volumes", "1");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -652,19 +652,34 @@ ModelVolume* ModelObject::add_volume(const TriangleMesh &mesh)
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelVolume* ModelObject::add_volume(TriangleMesh &&mesh)
|
static void add_v_to_volumes(ModelVolumePtrs* volumes, ModelVolume* v)
|
||||||
{
|
{
|
||||||
ModelVolume* v = new ModelVolume(this, std::move(mesh));
|
if (volumes->empty() || v->type() >= volumes->back()->type())
|
||||||
this->volumes.push_back(v);
|
volumes->push_back(v);
|
||||||
|
else {
|
||||||
|
for (int pos = volumes->size() - 1; pos >= 0; pos--)
|
||||||
|
if (v->type() >= (*volumes)[pos]->type()) {
|
||||||
|
volumes->insert(volumes->begin() + pos + 1, v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelVolume* ModelObject::add_volume(TriangleMesh &&mesh, ModelVolumeType type /*= ModelVolumeType::MODEL_PART*/)
|
||||||
|
{
|
||||||
|
ModelVolume* v = new ModelVolume(this, std::move(mesh), type);
|
||||||
|
add_v_to_volumes(&(this->volumes), v);
|
||||||
v->center_geometry_after_creation();
|
v->center_geometry_after_creation();
|
||||||
this->invalidate_bounding_box();
|
this->invalidate_bounding_box();
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelVolume* ModelObject::add_volume(const ModelVolume &other)
|
ModelVolume* ModelObject::add_volume(const ModelVolume &other, ModelVolumeType type /*= ModelVolumeType::MODEL_PART*/)
|
||||||
{
|
{
|
||||||
ModelVolume* v = new ModelVolume(this, other);
|
ModelVolume* v = new ModelVolume(this, other);
|
||||||
this->volumes.push_back(v);
|
if (v->type() != type)
|
||||||
|
v->set_type(type);
|
||||||
|
add_v_to_volumes(&(this->volumes), v);
|
||||||
// The volume should already be centered at this point of time when copying shared pointers of the triangle mesh and convex hull.
|
// The volume should already be centered at this point of time when copying shared pointers of the triangle mesh and convex hull.
|
||||||
// v->center_geometry_after_creation();
|
// v->center_geometry_after_creation();
|
||||||
// this->invalidate_bounding_box();
|
// this->invalidate_bounding_box();
|
||||||
|
@ -216,6 +216,16 @@ private:
|
|||||||
friend class ModelObject;
|
friend class ModelObject;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Declared outside of ModelVolume, so it could be forward declared.
|
||||||
|
enum class ModelVolumeType : int {
|
||||||
|
INVALID = -1,
|
||||||
|
MODEL_PART = 0,
|
||||||
|
NEGATIVE_VOLUME,
|
||||||
|
PARAMETER_MODIFIER,
|
||||||
|
SUPPORT_BLOCKER,
|
||||||
|
SUPPORT_ENFORCER,
|
||||||
|
};
|
||||||
|
|
||||||
// A printable object, possibly having multiple print volumes (each with its own set of parameters and materials),
|
// A printable object, possibly having multiple print volumes (each with its own set of parameters and materials),
|
||||||
// and possibly having multiple modifier volumes, each modifier volume with its set of parameters and materials.
|
// and possibly having multiple modifier volumes, each modifier volume with its set of parameters and materials.
|
||||||
// Each ModelObject may be instantiated mutliple times, each instance having different placement on the print bed,
|
// Each ModelObject may be instantiated mutliple times, each instance having different placement on the print bed,
|
||||||
@ -262,8 +272,8 @@ public:
|
|||||||
const Model* get_model() const { return m_model; }
|
const Model* get_model() const { return m_model; }
|
||||||
|
|
||||||
ModelVolume* add_volume(const TriangleMesh &mesh);
|
ModelVolume* add_volume(const TriangleMesh &mesh);
|
||||||
ModelVolume* add_volume(TriangleMesh &&mesh);
|
ModelVolume* add_volume(TriangleMesh &&mesh, ModelVolumeType type = ModelVolumeType::MODEL_PART);
|
||||||
ModelVolume* add_volume(const ModelVolume &volume);
|
ModelVolume* add_volume(const ModelVolume &volume, ModelVolumeType type = ModelVolumeType::MODEL_PART);
|
||||||
ModelVolume* add_volume(const ModelVolume &volume, TriangleMesh &&mesh);
|
ModelVolume* add_volume(const ModelVolume &volume, TriangleMesh &&mesh);
|
||||||
void delete_volume(size_t idx);
|
void delete_volume(size_t idx);
|
||||||
void clear_volumes();
|
void clear_volumes();
|
||||||
@ -482,16 +492,6 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Declared outside of ModelVolume, so it could be forward declared.
|
|
||||||
enum class ModelVolumeType : int {
|
|
||||||
INVALID = -1,
|
|
||||||
MODEL_PART = 0,
|
|
||||||
NEGATIVE_VOLUME,
|
|
||||||
PARAMETER_MODIFIER,
|
|
||||||
SUPPORT_BLOCKER,
|
|
||||||
SUPPORT_ENFORCER,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class EnforcerBlockerType : int8_t {
|
enum class EnforcerBlockerType : int8_t {
|
||||||
// Maximum is 3. The value is serialized in TriangleSelector into 2 bits!
|
// Maximum is 3. The value is serialized in TriangleSelector into 2 bits!
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
@ -717,7 +717,7 @@ private:
|
|||||||
// 1 -> is splittable
|
// 1 -> is splittable
|
||||||
mutable int m_is_splittable{ -1 };
|
mutable int m_is_splittable{ -1 };
|
||||||
|
|
||||||
ModelVolume(ModelObject *object, const TriangleMesh &mesh) : m_mesh(new TriangleMesh(mesh)), m_type(ModelVolumeType::MODEL_PART), object(object)
|
ModelVolume(ModelObject *object, const TriangleMesh &mesh, ModelVolumeType type = ModelVolumeType::MODEL_PART) : m_mesh(new TriangleMesh(mesh)), m_type(type), object(object)
|
||||||
{
|
{
|
||||||
assert(this->id().valid());
|
assert(this->id().valid());
|
||||||
assert(this->config.id().valid());
|
assert(this->config.id().valid());
|
||||||
@ -731,8 +731,8 @@ private:
|
|||||||
if (mesh.stl.stats.number_of_facets > 1)
|
if (mesh.stl.stats.number_of_facets > 1)
|
||||||
calculate_convex_hull();
|
calculate_convex_hull();
|
||||||
}
|
}
|
||||||
ModelVolume(ModelObject *object, TriangleMesh &&mesh, TriangleMesh &&convex_hull) :
|
ModelVolume(ModelObject *object, TriangleMesh &&mesh, TriangleMesh &&convex_hull, ModelVolumeType type = ModelVolumeType::MODEL_PART) :
|
||||||
m_mesh(new TriangleMesh(std::move(mesh))), m_convex_hull(new TriangleMesh(std::move(convex_hull))), m_type(ModelVolumeType::MODEL_PART), object(object) {
|
m_mesh(new TriangleMesh(std::move(mesh))), m_convex_hull(new TriangleMesh(std::move(convex_hull))), m_type(type), object(object) {
|
||||||
assert(this->id().valid());
|
assert(this->id().valid());
|
||||||
assert(this->config.id().valid());
|
assert(this->config.id().valid());
|
||||||
assert(this->supported_facets.id().valid());
|
assert(this->supported_facets.id().valid());
|
||||||
|
@ -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 part"), "add_part" }, // ~ModelVolumeType::MODEL_PART
|
||||||
{L("Add negative volume"), "add_negative" }, // ~ModelVolumeType::NEGATIVE_VOLUME
|
{L("Add negative volume"), "add_negative" }, // ~ModelVolumeType::NEGATIVE_VOLUME
|
||||||
{L("Add modifier"), "add_modifier"}, // ~ModelVolumeType::PARAMETER_MODIFIER
|
{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 enforcer"), "support_enforcer"}, // ~ModelVolumeType::SUPPORT_ENFORCER
|
||||||
{L("Add support blocker"), "support_blocker"} // ~ModelVolumeType::SUPPORT_BLOCKER
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static Plater* plater()
|
static Plater* plater()
|
||||||
|
@ -1135,8 +1135,44 @@ bool ObjectList::can_drop(const wxDataViewItem& item) const
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// move volumes inside one object only
|
// move volumes inside one object only
|
||||||
if (m_dragged_data.type() & itVolume)
|
if (m_dragged_data.type() & itVolume) {
|
||||||
return m_dragged_data.obj_idx() == m_objects_model->GetObjectIdByItem(item);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1375,8 +1411,7 @@ void ObjectList::load_part( ModelObject* model_object,
|
|||||||
}
|
}
|
||||||
for (auto volume : object->volumes) {
|
for (auto volume : object->volumes) {
|
||||||
volume->translate(delta);
|
volume->translate(delta);
|
||||||
auto new_volume = model_object->add_volume(*volume);
|
auto new_volume = model_object->add_volume(*volume, type);
|
||||||
new_volume->set_type(type);
|
|
||||||
new_volume->name = boost::filesystem::path(input_file).filename().string();
|
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));
|
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);
|
TriangleMesh mesh = create_mesh(type_name, instance_bb);
|
||||||
|
|
||||||
// Mesh will be centered when loading.
|
// Mesh will be centered when loading.
|
||||||
ModelVolume *new_volume = model_object.add_volume(std::move(mesh));
|
ModelVolume *new_volume = model_object.add_volume(std::move(mesh), type);
|
||||||
new_volume->set_type(type);
|
|
||||||
|
|
||||||
if (instance_idx != -1)
|
if (instance_idx != -1)
|
||||||
{
|
{
|
||||||
|
@ -329,7 +329,25 @@ wxDataViewItem ObjectDataViewModel::AddVolumeChild( const wxDataViewItem &parent
|
|||||||
if (insert_position >= 0) insert_position++;
|
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);
|
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
|
// if part with errors is added, but object wasn't marked, then mark it
|
||||||
|
@ -312,6 +312,14 @@ void PreferencesDialog::build()
|
|||||||
option = Option(def, "color_mapinulation_panel");
|
option = Option(def, "color_mapinulation_panel");
|
||||||
m_optgroup_gui->append_single_option_line(option);
|
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.label = L("Use custom size for toolbar icons");
|
||||||
def.type = coBool;
|
def.type = coBool;
|
||||||
def.tooltip = L("If enabled, you can change size of toolbar icons manually.");
|
def.tooltip = L("If enabled, you can change size of toolbar icons manually.");
|
||||||
|
Loading…
Reference in New Issue
Block a user