mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer
This commit is contained in:
		
						commit
						b2e7081d31
					
				
					 7 changed files with 61 additions and 66 deletions
				
			
		|  | @ -36,6 +36,10 @@ | |||
| #error "SEEK_SET not defined" | ||||
| #endif | ||||
| 
 | ||||
| #ifndef BOOST_LITTLE_ENDIAN | ||||
| extern void stl_internal_reverse_quads(char *buf, size_t cnt); | ||||
| #endif /* BOOST_LITTLE_ENDIAN */ | ||||
| 
 | ||||
| static FILE* stl_open_count_facets(stl_file *stl, const char *file)  | ||||
| { | ||||
|   	// Open the file in binary mode first.
 | ||||
|  | @ -238,10 +242,6 @@ bool stl_open(stl_file *stl, const char *file) | |||
|   	return result; | ||||
| } | ||||
| 
 | ||||
| #ifndef BOOST_LITTLE_ENDIAN | ||||
| extern void stl_internal_reverse_quads(char *buf, size_t cnt); | ||||
| #endif /* BOOST_LITTLE_ENDIAN */ | ||||
| 
 | ||||
| void stl_allocate(stl_file *stl)  | ||||
| { | ||||
|   	//  Allocate memory for the entire .STL file.
 | ||||
|  |  | |||
|  | @ -753,9 +753,9 @@ void ObjectList::paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& vol | |||
|     } | ||||
| 
 | ||||
|     select_items(items); | ||||
| #ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
 | ||||
| //#ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
 | ||||
|     selection_changed(); | ||||
| #endif //no __WXOSX__ //__WXMSW__
 | ||||
| //#endif //no __WXOSX__ //__WXMSW__
 | ||||
| } | ||||
| 
 | ||||
| void ObjectList::paste_objects_into_list(const std::vector<size_t>& object_idxs) | ||||
|  | @ -773,9 +773,9 @@ void ObjectList::paste_objects_into_list(const std::vector<size_t>& object_idxs) | |||
|     wxGetApp().plater()->changed_objects(object_idxs); | ||||
| 
 | ||||
|     select_items(items); | ||||
| #ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
 | ||||
| //#ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
 | ||||
|     selection_changed(); | ||||
| #endif //no __WXOSX__ //__WXMSW__
 | ||||
| //#endif //no __WXOSX__ //__WXMSW__
 | ||||
| } | ||||
| 
 | ||||
| #ifdef __WXOSX__ | ||||
|  | @ -1722,9 +1722,9 @@ void ObjectList::load_subobject(ModelVolumeType type) | |||
|     if (sel_item) | ||||
|         select_item(sel_item); | ||||
| 
 | ||||
| #ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
 | ||||
| //#ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
 | ||||
|     selection_changed(); | ||||
| #endif //no __WXOSX__ //__WXMSW__
 | ||||
| //#endif //no __WXOSX__ //__WXMSW__
 | ||||
| } | ||||
| 
 | ||||
| void ObjectList::load_part( ModelObject* model_object, | ||||
|  | @ -1860,9 +1860,9 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode | |||
|     const auto object_item = m_objects_model->GetTopParent(GetSelection()); | ||||
|     select_item(m_objects_model->AddVolumeChild(object_item, name, type,  | ||||
|         new_volume->get_mesh_errors_count()>0)); | ||||
| #ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
 | ||||
| //#ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
 | ||||
|     selection_changed(); | ||||
| #endif //no __WXOSX__ //__WXMSW__
 | ||||
| //#endif //no __WXOSX__ //__WXMSW__
 | ||||
| } | ||||
| 
 | ||||
| void ObjectList::load_shape_object(const std::string& type_name) | ||||
|  |  | |||
|  | @ -252,7 +252,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) | |||
|         const sla::SupportPoint& support_point = m_editing_mode ? m_editing_cache[i].support_point : m_normal_cache[i]; | ||||
|         const bool& point_selected = m_editing_mode ? m_editing_cache[i].selected : false; | ||||
| 
 | ||||
|         if (is_point_clipped(support_point.pos.cast<double>())) | ||||
|         if (is_mesh_point_clipped(support_point.pos.cast<double>())) | ||||
|             continue; | ||||
| 
 | ||||
|         // First decide about the color of the point.
 | ||||
|  | @ -335,14 +335,14 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| bool GLGizmoSlaSupports::is_point_clipped(const Vec3d& point) const | ||||
| bool GLGizmoSlaSupports::is_mesh_point_clipped(const Vec3d& point) const | ||||
| { | ||||
|     if (m_clipping_plane_distance == 0.f) | ||||
|         return false; | ||||
| 
 | ||||
|     Vec3d transformed_point = m_model_object->instances.front()->get_transformation().get_matrix() * point; | ||||
|     transformed_point(2) += m_z_shift; | ||||
|     return m_clipping_plane->distance(transformed_point) < 0.; | ||||
|     return m_clipping_plane->is_point_clipped(transformed_point); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -391,27 +391,15 @@ bool GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec | |||
|     trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_z_shift)); | ||||
| 
 | ||||
|     // The raycaster query
 | ||||
|     std::vector<Vec3f> hits; | ||||
|     std::vector<Vec3f> normals; | ||||
|     m_mesh_raycaster->unproject_on_mesh(mouse_pos, trafo.get_matrix(), camera, &hits, &normals); | ||||
| 
 | ||||
|     // We must also take care of the clipping plane (if active)
 | ||||
|     unsigned i = 0; | ||||
|     if (m_clipping_plane_distance != 0.f) { | ||||
|         for (i=0; i<hits.size(); ++i) | ||||
|             if (! is_point_clipped(hits[i].cast<double>())) | ||||
|                 break; | ||||
|     Vec3f hit; | ||||
|     Vec3f normal; | ||||
|     if (m_mesh_raycaster->unproject_on_mesh(mouse_pos, trafo.get_matrix(), camera, hit, normal, m_clipping_plane.get())) { | ||||
|         // Return both the point and the facet normal.
 | ||||
|         pos_and_normal = std::make_pair(hit, normal); | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     if (i==hits.size() || (hits.size()-i) % 2 != 0) { | ||||
|         // All hits are either clipped, or there is an odd number of unclipped
 | ||||
|         // hits - meaning the nearest must be from inside the mesh.
 | ||||
|     else | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     // Calculate and return both the point and the facet normal.
 | ||||
|     pos_and_normal = std::make_pair(hits[i], normals[i]); | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| // Following function is called from GLCanvas3D to inform the gizmo about a mouse/keyboard event.
 | ||||
|  | @ -481,19 +469,15 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous | |||
|             std::vector<Vec3f> points_inside; | ||||
|             std::vector<unsigned int> points_idxs = m_selection_rectangle.stop_dragging(m_parent, points); | ||||
|             for (size_t idx : points_idxs) | ||||
|                 points_inside.push_back((trafo.get_matrix() * points[idx]).cast<float>()); | ||||
|                 points_inside.push_back(points[idx].cast<float>()); | ||||
| 
 | ||||
|             // Only select/deselect points that are actually visible
 | ||||
|             for (size_t idx :  m_mesh_raycaster->get_unobscured_idxs(trafo, m_parent.get_camera(), points_inside, | ||||
|                           [this](const Vec3f& pt) { return is_point_clipped(pt.cast<double>()); })) | ||||
|             for (size_t idx :  m_mesh_raycaster->get_unobscured_idxs(trafo, m_parent.get_camera(), points_inside, m_clipping_plane.get())) | ||||
|             { | ||||
|                 const sla::SupportPoint &support_point = m_editing_cache[points_idxs[idx]].support_point; | ||||
|                 if (! is_point_clipped(support_point.pos.cast<double>())) { | ||||
|                     if (rectangle_status == GLSelectionRectangle::Deselect) | ||||
|                         unselect_point(points_idxs[idx]); | ||||
|                     else | ||||
|                         select_point(points_idxs[idx]); | ||||
|                 } | ||||
|                 if (rectangle_status == GLSelectionRectangle::Deselect) | ||||
|                     unselect_point(points_idxs[idx]); | ||||
|                 else | ||||
|                     select_point(points_idxs[idx]); | ||||
|             } | ||||
|             return true; | ||||
|         } | ||||
|  |  | |||
|  | @ -125,7 +125,7 @@ private: | |||
|     mutable std::unique_ptr<MeshClipper> m_supports_clipper; | ||||
| 
 | ||||
|     std::vector<const ConfigOption*> get_config_options(const std::vector<std::string>& keys) const; | ||||
|     bool is_point_clipped(const Vec3d& point) const; | ||||
|     bool is_mesh_point_clipped(const Vec3d& point) const; | ||||
|     //void find_intersecting_facets(const igl::AABB<Eigen::MatrixXf, 3>* aabb, const Vec3f& normal, double offset, std::vector<unsigned int>& out) const;
 | ||||
| 
 | ||||
|     // Methods that do the model_object and editing cache synchronization,
 | ||||
|  |  | |||
|  | @ -152,8 +152,8 @@ Vec3f MeshRaycaster::AABBWrapper::get_hit_normal(const igl::Hit& hit) const | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& trafo, | ||||
|                                       const Camera& camera, std::vector<Vec3f>* positions, std::vector<Vec3f>* normals) const | ||||
| bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera, | ||||
|                                       Vec3f& position, Vec3f& normal, const ClippingPlane* clipping_plane) const | ||||
| { | ||||
|     const std::array<int, 4>& viewport = camera.get_viewport(); | ||||
|     const Transform3d& model_mat = camera.get_view_matrix(); | ||||
|  | @ -179,25 +179,30 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& | |||
| 
 | ||||
|     std::sort(hits.begin(), hits.end(), [](const igl::Hit& a, const igl::Hit& b) { return a.t < b.t; }); | ||||
| 
 | ||||
|     // Now stuff the points in the provided vector and calculate normals if asked about them:
 | ||||
|     if (positions != nullptr) { | ||||
|         positions->clear(); | ||||
|         if (normals != nullptr) | ||||
|             normals->clear(); | ||||
|         for (const igl::Hit& hit : hits) { | ||||
|             positions->push_back(m_AABB_wrapper->get_hit_pos(hit)); | ||||
|     unsigned i = 0; | ||||
| 
 | ||||
|             if (normals != nullptr) | ||||
|                 normals->push_back(m_AABB_wrapper->get_hit_normal(hit)); | ||||
|     // Remove points that are obscured or cut by the clipping plane
 | ||||
|     if (clipping_plane) { | ||||
|         for (i=0; i<hits.size(); ++i) | ||||
|             if (! clipping_plane->is_point_clipped(trafo * m_AABB_wrapper->get_hit_pos(hits[i]).cast<double>())) | ||||
|                 break; | ||||
| 
 | ||||
|         if (i==hits.size() || (hits.size()-i) % 2 != 0) { | ||||
|             // All hits are either clipped, or there is an odd number of unclipped
 | ||||
|             // hits - meaning the nearest must be from inside the mesh.
 | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // Now stuff the points in the provided vector and calculate normals if asked about them:
 | ||||
|     position = m_AABB_wrapper->get_hit_pos(hits[i]); | ||||
|     normal = m_AABB_wrapper->get_hit_normal(hits[i]); | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| std::vector<unsigned> MeshRaycaster::get_unobscured_idxs(const Geometry::Transformation& trafo, const Camera& camera, const std::vector<Vec3f>& points, | ||||
|                                                        std::function<bool(const Vec3f&)> fn_ignore_hit) const | ||||
|                                                        const ClippingPlane* clipping_plane) const | ||||
| { | ||||
|     std::vector<unsigned> out; | ||||
| 
 | ||||
|  | @ -206,19 +211,24 @@ std::vector<unsigned> MeshRaycaster::get_unobscured_idxs(const Geometry::Transfo | |||
|     Vec3f direction_to_camera_mesh = (instance_matrix_no_translation_no_scaling.inverse().cast<float>() * direction_to_camera).normalized().eval(); | ||||
|     Vec3f scaling = trafo.get_scaling_factor().cast<float>(); | ||||
|     direction_to_camera_mesh = Vec3f(direction_to_camera_mesh(0)*scaling(0), direction_to_camera_mesh(1)*scaling(1), direction_to_camera_mesh(2)*scaling(2)); | ||||
|     const Transform3f inverse_trafo = trafo.get_matrix().inverse().cast<float>(); | ||||
| 
 | ||||
|     for (size_t i=0; i<points.size(); ++i) { | ||||
|         const Vec3f& pt = points[i]; | ||||
|         if (clipping_plane && clipping_plane->is_point_clipped(pt.cast<double>())) | ||||
|             continue; | ||||
| 
 | ||||
|         bool is_obscured = false; | ||||
|         // Cast a ray in the direction of the camera and look for intersection with the mesh:
 | ||||
|         std::vector<igl::Hit> hits; | ||||
|         // Offset the start of the ray to the front of the ball + EPSILON to account for numerical inaccuracies.
 | ||||
|         // Offset the start of the ray by EPSILON to account for numerical inaccuracies.
 | ||||
|         if (m_AABB_wrapper->m_AABB.intersect_ray( | ||||
|                 AABBWrapper::MapMatrixXfUnaligned(m_mesh->its.vertices.front().data(), m_mesh->its.vertices.size(), 3), | ||||
|                 AABBWrapper::MapMatrixXiUnaligned(m_mesh->its.indices.front().data(), m_mesh->its.indices.size(), 3), | ||||
|                 pt + direction_to_camera_mesh * EPSILON, direction_to_camera_mesh, hits)) { | ||||
|                 inverse_trafo * pt + direction_to_camera_mesh * EPSILON, direction_to_camera_mesh, hits)) { | ||||
| 
 | ||||
|             std::sort(hits.begin(), hits.end(), [](const igl::Hit& h1, const igl::Hit& h2) { return h1.t < h2.t; }); | ||||
| 
 | ||||
|             // If the closest hit facet normal points in the same direction as the ray,
 | ||||
|             // we are looking through the mesh and should therefore discard the point:
 | ||||
|             if (m_AABB_wrapper->get_hit_normal(hits.front()).dot(direction_to_camera_mesh) > 0.f) | ||||
|  | @ -227,11 +237,12 @@ std::vector<unsigned> MeshRaycaster::get_unobscured_idxs(const Geometry::Transfo | |||
|             // Eradicate all hits that the caller wants to ignore
 | ||||
|             for (unsigned j=0; j<hits.size(); ++j) { | ||||
|                 const igl::Hit& hit = hits[j]; | ||||
|                 if (fn_ignore_hit(m_AABB_wrapper->get_hit_pos(hit))) { | ||||
|                 if (clipping_plane && clipping_plane->is_point_clipped(trafo.get_matrix() * m_AABB_wrapper->get_hit_pos(hit).cast<double>())) { | ||||
|                     hits.erase(hits.begin()+j); | ||||
|                     --j; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             // FIXME: the intersection could in theory be behind the camera, but as of now we only have camera direction.
 | ||||
|             // Also, the threshold is in mesh coordinates, not in actual dimensions.
 | ||||
|             if (! hits.empty()) | ||||
|  |  | |||
|  | @ -50,6 +50,7 @@ public: | |||
|         return (-get_normal().dot(pt) + m_data[3]); | ||||
|     } | ||||
| 
 | ||||
|     bool is_point_clipped(const Vec3d& point) const { return distance(point) < 0.; } | ||||
|     void set_normal(const Vec3d& normal) { for (size_t i=0; i<3; ++i) m_data[i] = normal(i); } | ||||
|     void set_offset(double offset) { m_data[3] = offset; } | ||||
|     Vec3d get_normal() const { return Vec3d(m_data[0], m_data[1], m_data[2]); } | ||||
|  | @ -98,10 +99,10 @@ public: | |||
|     void set_camera(const Camera& camera); | ||||
| 
 | ||||
|     bool unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera, | ||||
|                            std::vector<Vec3f>* positions = nullptr, std::vector<Vec3f>* normals = nullptr) const; | ||||
|                            Vec3f& position, Vec3f& normal, const ClippingPlane* clipping_plane = nullptr) const; | ||||
| 
 | ||||
|     std::vector<unsigned> get_unobscured_idxs(const Geometry::Transformation& trafo, const Camera& camera, | ||||
|                                               const std::vector<Vec3f>& points, std::function<bool(const Vec3f&)> fn_ignore_hit) const; | ||||
|                                               const std::vector<Vec3f>& points, const ClippingPlane* clipping_plane = nullptr) const; | ||||
| 
 | ||||
|     Vec3f get_closest_point(const Vec3f& point, Vec3f* normal = nullptr) const; | ||||
| 
 | ||||
|  |  | |||
|  | @ -4288,11 +4288,10 @@ void Plater::increase_instances(size_t num) | |||
| 
 | ||||
|     sidebar().obj_list()->increase_object_instances(obj_idx, was_one_instance ? num + 1 : num); | ||||
| 
 | ||||
|     if (p->get_config("autocenter") == "1") { | ||||
|     if (p->get_config("autocenter") == "1") | ||||
|         p->arrange(); | ||||
|     } else { | ||||
|         p->update(); | ||||
|     } | ||||
| 
 | ||||
|     p->update(); | ||||
| 
 | ||||
|     p->get_selection().add_instance(obj_idx, (int)model_object->instances.size() - 1); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 YuSanka
						YuSanka