mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Cut: Preserve Z-rotation, fix upper part mesh position,
perform custom placing instead of arrange()
This commit is contained in:
		
							parent
							
								
									693bee7b79
								
							
						
					
					
						commit
						3b20d03e1d
					
				
					 2 changed files with 62 additions and 32 deletions
				
			
		|  | @ -975,12 +975,6 @@ bool ModelObject::needed_repair() const | ||||||
|     return false; |     return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<class T> static void cut_reset_transform(T *thing) { |  | ||||||
|     const Vec3d offset = thing->get_offset(); |  | ||||||
|     thing->set_transformation(Geometry::Transformation()); |  | ||||||
|     thing->set_offset(offset); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, bool keep_upper, bool keep_lower, bool rotate_lower) | ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, bool keep_upper, bool keep_lower, bool rotate_lower) | ||||||
| { | { | ||||||
|     // Clone the object to duplicate instances, materials etc.
 |     // Clone the object to duplicate instances, materials etc.
 | ||||||
|  | @ -1001,24 +995,25 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, bool keep_upper, b | ||||||
|         lower->input_file = ""; |         lower->input_file = ""; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const auto instance_matrix = instances[instance]->get_matrix(true); |  | ||||||
| 
 |  | ||||||
|     // Because transformations are going to be applied to meshes directly,
 |     // Because transformations are going to be applied to meshes directly,
 | ||||||
|     // we reset transformation of all instances and volumes,
 |     // we reset transformation of all instances and volumes,
 | ||||||
|     // except for translation, which is preserved in the transformation matrix
 |     // except for translation and Z-rotation on instances, which are preserved
 | ||||||
|     // and not applied to the mesh transform.
 |     // in the transformation matrix and not applied to the mesh transform.
 | ||||||
|     // TODO: Do the same for Z-rotation as well?
 |  | ||||||
| 
 | 
 | ||||||
|     if (keep_upper) { |     // const auto instance_matrix = instances[instance]->get_matrix(true);
 | ||||||
|         for (auto *instance : upper->instances) { cut_reset_transform(instance); } |     const auto instance_matrix = Geometry::assemble_transform( | ||||||
|     } |         Vec3d::Zero(),  // don't apply offset
 | ||||||
|     if (keep_lower) { |         instances[instance]->get_rotation().cwiseProduct(Vec3d(1.0, 1.0, 0.0)),   // don't apply Z-rotation
 | ||||||
|         for (auto *instance : lower->instances) { cut_reset_transform(instance); } |         instances[instance]->get_scaling_factor(), | ||||||
|     } |         instances[instance]->get_mirror() | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     // Lower part per-instance bounding boxes
 | ||||||
|  |     std::vector<BoundingBoxf3> lower_bboxes { instances.size() }; | ||||||
| 
 | 
 | ||||||
|     for (ModelVolume *volume : volumes) { |     for (ModelVolume *volume : volumes) { | ||||||
|         if (! volume->is_model_part()) { |         if (! volume->is_model_part()) { | ||||||
|             // don't cut modifiers
 |             // Don't cut modifiers
 | ||||||
|             if (keep_upper) { upper->add_volume(*volume); } |             if (keep_upper) { upper->add_volume(*volume); } | ||||||
|             if (keep_lower) { lower->add_volume(*volume); } |             if (keep_lower) { lower->add_volume(*volume); } | ||||||
|         } else { |         } else { | ||||||
|  | @ -1027,13 +1022,23 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, bool keep_upper, b | ||||||
|             // Transform the mesh by the object transformation matrix
 |             // Transform the mesh by the object transformation matrix
 | ||||||
|             const auto volume_tr = instance_matrix * volume->get_matrix(true); |             const auto volume_tr = instance_matrix * volume->get_matrix(true); | ||||||
|             volume->mesh.transform(volume_tr); |             volume->mesh.transform(volume_tr); | ||||||
|             cut_reset_transform(volume); |  | ||||||
| 
 | 
 | ||||||
|             // Transform z from world to object
 |             // Transform z from world to object
 | ||||||
|             const auto local_z = volume_tr * Vec3d(0.0, 0.0, z); |             const double local_z = (volume_tr * Vec3d(0.0, 0.0, z))(2); | ||||||
| 
 | 
 | ||||||
|  |             // Perform cut
 | ||||||
|             TriangleMeshSlicer tms(&volume->mesh); |             TriangleMeshSlicer tms(&volume->mesh); | ||||||
|             tms.cut(local_z(2), &upper_mesh, &lower_mesh); |             tms.cut(local_z, &upper_mesh, &lower_mesh); | ||||||
|  | 
 | ||||||
|  |             // Move the upper mesh to down to zero in Z
 | ||||||
|  |             if (keep_upper) { | ||||||
|  |                 upper_mesh.translate(0.0, 0.0, -local_z); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // Reset volume transformation except for offset
 | ||||||
|  |             const Vec3d offset = volume->get_offset(); | ||||||
|  |             volume->set_transformation(Geometry::Transformation()); | ||||||
|  |             volume->set_offset(offset); | ||||||
| 
 | 
 | ||||||
|             if (keep_upper) { |             if (keep_upper) { | ||||||
|                 upper_mesh.repair(); |                 upper_mesh.repair(); | ||||||
|  | @ -1055,16 +1060,15 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, bool keep_upper, b | ||||||
|                 vol->name           = volume->name; |                 vol->name           = volume->name; | ||||||
|                 vol->config         = volume->config; |                 vol->config         = volume->config; | ||||||
|                 vol->set_material(volume->material_id(), *volume->material()); |                 vol->set_material(volume->material_id(), *volume->material()); | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     if (keep_lower && rotate_lower) { |                 // Compute the lower part instances' bounding boxes to figure out where to place
 | ||||||
|         for (auto *instance : lower->instances) { |                 // the upper part
 | ||||||
|             Geometry::Transformation tr; |                 if (keep_upper) { | ||||||
|             tr.set_offset(instance->get_offset()); |                     for (size_t i = 0; i < instances.size(); i++) { | ||||||
|             tr.set_rotation({Geometry::deg2rad(180.0), 0.0, 0.0}); |                         lower_bboxes[i].merge(instances[i]->transform_mesh_bounding_box(lower_mesh, true)); | ||||||
|             instance->set_transformation(tr); |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -1073,11 +1077,39 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, bool keep_upper, b | ||||||
|     if (keep_upper && upper->volumes.size() > 0) { |     if (keep_upper && upper->volumes.size() > 0) { | ||||||
|         upper->invalidate_bounding_box(); |         upper->invalidate_bounding_box(); | ||||||
|         upper->center_around_origin(); |         upper->center_around_origin(); | ||||||
|  | 
 | ||||||
|  |         // Reset instance transformation except offset and Z-rotation
 | ||||||
|  |         for (size_t i = 0; i < instances.size(); i++) { | ||||||
|  |             auto &instance = upper->instances[i]; | ||||||
|  |             const Vec3d offset = instance->get_offset(); | ||||||
|  |             const double rot_z = instance->get_rotation()(2); | ||||||
|  |             const Vec3d displace = lower_bboxes[i].size().cwiseProduct(Vec3d(-0.5, -0.5, 0.0)); | ||||||
|  | 
 | ||||||
|  |             instance->set_transformation(Geometry::Transformation()); | ||||||
|  |             instance->set_offset(offset + displace); | ||||||
|  |             instance->set_rotation(Vec3d(0.0, 0.0, rot_z)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         res.push_back(upper); |         res.push_back(upper); | ||||||
|     } |     } | ||||||
|     if (keep_lower && lower->volumes.size() > 0) { |     if (keep_lower && lower->volumes.size() > 0) { | ||||||
|         lower->invalidate_bounding_box(); |         lower->invalidate_bounding_box(); | ||||||
|         lower->center_around_origin(); |         lower->center_around_origin(); | ||||||
|  | 
 | ||||||
|  |         // Reset instance transformation except offset and Z-rotation
 | ||||||
|  |         for (auto *instance : lower->instances) { | ||||||
|  |             const Vec3d offset = instance->get_offset(); | ||||||
|  |             const double rot_z = instance->get_rotation()(2); | ||||||
|  |             instance->set_transformation(Geometry::Transformation()); | ||||||
|  | 
 | ||||||
|  |             if (rotate_lower) { | ||||||
|  |                 instance->set_rotation({Geometry::deg2rad(180.0), 0.0, 0.0}); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             instance->set_offset(offset); | ||||||
|  |             instance->set_rotation(Vec3d(0.0, 0.0, rot_z)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         res.push_back(lower); |         res.push_back(lower); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2483,8 +2483,6 @@ void Plater::cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_uppe | ||||||
| 
 | 
 | ||||||
|     remove(obj_idx); |     remove(obj_idx); | ||||||
|     p->load_model_objects(new_objects); |     p->load_model_objects(new_objects); | ||||||
| 
 |  | ||||||
|     p->arrange(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Plater::export_gcode(fs::path output_path) | void Plater::export_gcode(fs::path output_path) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vojtech Kral
						Vojtech Kral