mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Change to return const references for TriangleMesh return values in SLAPrintObject's methods
This commit is contained in:
		
							parent
							
								
									9996369e2c
								
							
						
					
					
						commit
						3667fc7894
					
				
					 6 changed files with 111 additions and 43 deletions
				
			
		| 
						 | 
				
			
			@ -156,6 +156,7 @@ add_library(libslic3r STATIC
 | 
			
		|||
    TriangleMesh.hpp
 | 
			
		||||
    utils.cpp
 | 
			
		||||
    Utils.hpp
 | 
			
		||||
    MTUtils.hpp
 | 
			
		||||
    SLA/SLABoilerPlate.hpp
 | 
			
		||||
    SLA/SLABasePool.hpp
 | 
			
		||||
    SLA/SLABasePool.cpp
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										63
									
								
								src/libslic3r/MTUtils.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/libslic3r/MTUtils.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,63 @@
 | 
			
		|||
#ifndef MTUTILS_HPP
 | 
			
		||||
#define MTUTILS_HPP
 | 
			
		||||
 | 
			
		||||
#include <atomic>       // for std::atomic_flag
 | 
			
		||||
#include <mutex>        // for std::lock_guard
 | 
			
		||||
#include <functional>   // for std::function
 | 
			
		||||
#include <utility>      // for std::forward
 | 
			
		||||
 | 
			
		||||
namespace Slic3r {
 | 
			
		||||
 | 
			
		||||
// TODO: these classes are untested
 | 
			
		||||
 | 
			
		||||
/// Handy little spin mutex for the cached meshes.
 | 
			
		||||
/// Implements the "Lockable" concept
 | 
			
		||||
class SpinMutex {
 | 
			
		||||
    std::atomic_flag m_flg;
 | 
			
		||||
    static const /*constexpr*/ auto MO_ACQ = std::memory_order_acquire;
 | 
			
		||||
    static const /*constexpr*/ auto MO_REL = std::memory_order_release;
 | 
			
		||||
public:
 | 
			
		||||
    inline SpinMutex() { m_flg.clear(MO_REL); }
 | 
			
		||||
    inline void lock() { while(m_flg.test_and_set(MO_ACQ)); }
 | 
			
		||||
    inline bool try_lock() { return !m_flg.test_and_set(MO_ACQ); }
 | 
			
		||||
    inline void unlock() { m_flg.clear(MO_REL); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// A wrapper class around arbitrary object that needs thread safe caching.
 | 
			
		||||
template<class T> class CachedObject {
 | 
			
		||||
public:
 | 
			
		||||
    // Method type which refreshes the object when it has been invalidated
 | 
			
		||||
    using Setter = std::function<void(T&)>;
 | 
			
		||||
private:
 | 
			
		||||
    T m_obj;            // the object itself
 | 
			
		||||
    bool m_valid;       // invalidation flag
 | 
			
		||||
    SpinMutex m_lck;    // to make the caching thread safe
 | 
			
		||||
 | 
			
		||||
    // the setter will be called just before the object's const value is about
 | 
			
		||||
    // to be retrieved.
 | 
			
		||||
    std::function<void(T&)> m_setter;
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    // Forwarded constructor
 | 
			
		||||
    template<class...Args> inline CachedObject(Setter fn, Args&&...args):
 | 
			
		||||
        m_obj(std::forward<Args>(args)...), m_valid(false), m_setter(fn) {}
 | 
			
		||||
 | 
			
		||||
    // invalidate the value of the object. The object will be refreshed at the
 | 
			
		||||
    // next retrieval (Setter will be called). The data that is used in
 | 
			
		||||
    // the setter function should be guarded as well if it is modified so the
 | 
			
		||||
    // modification has to take place in fn.
 | 
			
		||||
    inline void invalidate(std::function<void()> fn) {
 | 
			
		||||
        std::lock_guard<SpinMutex> lck(m_lck); fn(); m_valid = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Get the const object properly updated.
 | 
			
		||||
    inline const T& get() {
 | 
			
		||||
        std::lock_guard<SpinMutex> lck(m_lck);
 | 
			
		||||
        if(!m_valid) { m_setter(m_obj); m_valid = true; }
 | 
			
		||||
        return m_obj;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // MTUTILS_HPP
 | 
			
		||||
| 
						 | 
				
			
			@ -730,6 +730,9 @@ public:
 | 
			
		|||
            meshcache.merge(mesh(bs.mesh));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // TODO: Is this necessary?
 | 
			
		||||
        meshcache.repair();
 | 
			
		||||
 | 
			
		||||
        BoundingBoxf3&& bb = meshcache.bounding_box();
 | 
			
		||||
        model_height = bb.max(Z) - bb.min(Z);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1616,13 +1619,13 @@ bool SLASupportTree::generate(const PointSet &points,
 | 
			
		|||
    return pc == ABORT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SLASupportTree::merged_mesh(TriangleMesh &outmesh) const
 | 
			
		||||
const TriangleMesh &SLASupportTree::merged_mesh() const
 | 
			
		||||
{
 | 
			
		||||
    outmesh.merge(get().merged_mesh());
 | 
			
		||||
    return get().merged_mesh();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SLASupportTree::merged_mesh_with_pad(TriangleMesh &outmesh) const {
 | 
			
		||||
    merged_mesh(outmesh);
 | 
			
		||||
    outmesh.merge(merged_mesh());
 | 
			
		||||
    outmesh.merge(get_pad());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1658,14 +1661,12 @@ const TriangleMesh &SLASupportTree::add_pad(const SliceLayer& baseplate,
 | 
			
		|||
                                            double max_merge_distance_mm,
 | 
			
		||||
                                            double edge_radius_mm) const
 | 
			
		||||
{
 | 
			
		||||
    TriangleMesh mm;
 | 
			
		||||
    merged_mesh(mm);
 | 
			
		||||
    PoolConfig pcfg;
 | 
			
		||||
    pcfg.min_wall_thickness_mm = min_wall_thickness_mm;
 | 
			
		||||
    pcfg.min_wall_height_mm    = min_wall_height_mm;
 | 
			
		||||
    pcfg.max_merge_distance_mm = max_merge_distance_mm;
 | 
			
		||||
    pcfg.edge_radius_mm        = edge_radius_mm;
 | 
			
		||||
    return m_impl->create_pad(mm, baseplate, pcfg).tmesh;
 | 
			
		||||
    return m_impl->create_pad(merged_mesh(), baseplate, pcfg).tmesh;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const TriangleMesh &SLASupportTree::get_pad() const
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -144,7 +144,7 @@ public:
 | 
			
		|||
 | 
			
		||||
    /// Get the whole mesh united into the output TriangleMesh
 | 
			
		||||
    /// WITHOUT THE PAD
 | 
			
		||||
    void merged_mesh(TriangleMesh& outmesh) const;
 | 
			
		||||
    const TriangleMesh& merged_mesh() const;
 | 
			
		||||
 | 
			
		||||
    void merged_mesh_with_pad(TriangleMesh&) const;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -500,7 +500,10 @@ void SLAPrint::process()
 | 
			
		|||
 | 
			
		||||
SLAPrintObject::SLAPrintObject(SLAPrint *print, ModelObject *model_object):
 | 
			
		||||
    Inherited(print, model_object),
 | 
			
		||||
    m_stepmask(slaposCount, true)
 | 
			
		||||
    m_stepmask(slaposCount, true),
 | 
			
		||||
    m_transformed_rmesh( [this](TriangleMesh& obj){
 | 
			
		||||
            obj = m_model_object->raw_mesh(); obj.transform(m_trafo);
 | 
			
		||||
        })
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -526,28 +529,29 @@ double SLAPrintObject::get_elevation() const {
 | 
			
		|||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//const std::vector<ExPolygons> &SLAPrintObject::get_support_slices() const
 | 
			
		||||
//{
 | 
			
		||||
//    // I don't want to return a copy but the points may not exist, so ...
 | 
			
		||||
//    static const std::vector<ExPolygons> dummy_empty;
 | 
			
		||||
namespace { // dummy empty static containers for return values in some methods
 | 
			
		||||
const std::vector<ExPolygons> EMPTY_SLICES;
 | 
			
		||||
const TriangleMesh EMPTY_MESH;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//    if(!m_supportdata) return dummy_empty;
 | 
			
		||||
//    return m_supportdata->support_slices;
 | 
			
		||||
//}
 | 
			
		||||
const std::vector<ExPolygons> &SLAPrintObject::get_support_slices() const
 | 
			
		||||
{
 | 
			
		||||
    if(!is_step_done(slaposSliceSupports) || !m_supportdata) return EMPTY_SLICES;
 | 
			
		||||
    return m_supportdata->support_slices;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//const std::vector<ExPolygons> &SLAPrintObject::get_model_slices() const
 | 
			
		||||
//{
 | 
			
		||||
//    return m_model_slices;
 | 
			
		||||
//}
 | 
			
		||||
const std::vector<ExPolygons> &SLAPrintObject::get_model_slices() const
 | 
			
		||||
{
 | 
			
		||||
    if(!is_step_done(slaposObjectSlice)) return EMPTY_SLICES;
 | 
			
		||||
    return m_model_slices;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool SLAPrintObject::has_mesh(SLAPrintObjectStep step) const
 | 
			
		||||
{
 | 
			
		||||
    switch (step) {
 | 
			
		||||
    case slaposSupportTree:
 | 
			
		||||
//        return m_supportdata && m_supportdata->support_tree_ptr && ! m_supportdata->support_tree_ptr->get().merged_mesh().empty();
 | 
			
		||||
		return ! this->support_mesh().empty();
 | 
			
		||||
    case slaposBasePool:
 | 
			
		||||
//		return m_supportdata && m_supportdata->support_tree_ptr && ! m_supportdata->support_tree_ptr->get_pad().empty();
 | 
			
		||||
		return ! this->pad_mesh().empty();
 | 
			
		||||
	default:
 | 
			
		||||
        return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -566,22 +570,19 @@ TriangleMesh SLAPrintObject::get_mesh(SLAPrintObjectStep step) const
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TriangleMesh SLAPrintObject::support_mesh() const
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const TriangleMesh& SLAPrintObject::support_mesh() const
 | 
			
		||||
{
 | 
			
		||||
    TriangleMesh trm;
 | 
			
		||||
 | 
			
		||||
    if(m_supportdata && m_supportdata->support_tree_ptr)
 | 
			
		||||
        m_supportdata->support_tree_ptr->merged_mesh(trm);
 | 
			
		||||
        return m_supportdata->support_tree_ptr->merged_mesh();
 | 
			
		||||
 | 
			
		||||
    // TODO: is this necessary?
 | 
			
		||||
    trm.repair();
 | 
			
		||||
 | 
			
		||||
    return trm;
 | 
			
		||||
    return EMPTY_MESH;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TriangleMesh SLAPrintObject::pad_mesh() const
 | 
			
		||||
const TriangleMesh& SLAPrintObject::pad_mesh() const
 | 
			
		||||
{
 | 
			
		||||
    if(!m_supportdata || !m_supportdata->support_tree_ptr) return {};
 | 
			
		||||
    if(!m_supportdata || !m_supportdata->support_tree_ptr) return EMPTY_MESH;
 | 
			
		||||
 | 
			
		||||
    return m_supportdata->support_tree_ptr->get_pad();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -596,11 +597,7 @@ const TriangleMesh &SLAPrintObject::transformed_mesh() const {
 | 
			
		|||
    // or apply an inverse transformation on the support structure after it
 | 
			
		||||
    // has been created.
 | 
			
		||||
 | 
			
		||||
    if(m_trmesh_valid) return m_transformed_rmesh;
 | 
			
		||||
    m_transformed_rmesh = m_model_object->raw_mesh();
 | 
			
		||||
    m_transformed_rmesh.transform(m_trafo);
 | 
			
		||||
    m_trmesh_valid = true;
 | 
			
		||||
    return m_transformed_rmesh;
 | 
			
		||||
    return m_transformed_rmesh.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<Vec3d> SLAPrintObject::transformed_support_points() const
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,12 @@
 | 
			
		|||
#ifndef slic3r_SLAPrint_hpp_
 | 
			
		||||
#define slic3r_SLAPrint_hpp_
 | 
			
		||||
 | 
			
		||||
#include <mutex>
 | 
			
		||||
 | 
			
		||||
#include "PrintBase.hpp"
 | 
			
		||||
#include "PrintExport.hpp"
 | 
			
		||||
#include "Point.hpp"
 | 
			
		||||
#include "MTUtils.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Slic3r {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -53,10 +56,10 @@ public:
 | 
			
		|||
 | 
			
		||||
    // Get a support mesh centered around origin in XY, and with zero rotation around Z applied.
 | 
			
		||||
    // Support mesh is only valid if this->is_step_done(slaposSupportTree) is true.
 | 
			
		||||
    TriangleMesh            support_mesh() const;
 | 
			
		||||
    const TriangleMesh&     support_mesh() const;
 | 
			
		||||
    // Get a pad mesh centered around origin in XY, and with zero rotation around Z applied.
 | 
			
		||||
    // Support mesh is only valid if this->is_step_done(slaposPad) is true.
 | 
			
		||||
    TriangleMesh            pad_mesh() const;
 | 
			
		||||
    const TriangleMesh&     pad_mesh() const;
 | 
			
		||||
 | 
			
		||||
    // This will return the transformed mesh which is cached
 | 
			
		||||
    const TriangleMesh&     transformed_mesh() const;
 | 
			
		||||
| 
						 | 
				
			
			@ -69,8 +72,9 @@ public:
 | 
			
		|||
    // as the pad height also needs to be considered.
 | 
			
		||||
    double get_elevation() const;
 | 
			
		||||
 | 
			
		||||
//    const std::vector<ExPolygons>& get_support_slices() const;
 | 
			
		||||
//    const std::vector<ExPolygons>& get_model_slices() const;
 | 
			
		||||
    // Should be obvious
 | 
			
		||||
    const std::vector<ExPolygons>& get_support_slices() const;
 | 
			
		||||
    const std::vector<ExPolygons>& get_model_slices() const;
 | 
			
		||||
 | 
			
		||||
    // I refuse to grantee copying (Tamas)
 | 
			
		||||
    SLAPrintObject(const SLAPrintObject&) = delete;
 | 
			
		||||
| 
						 | 
				
			
			@ -86,7 +90,10 @@ protected:
 | 
			
		|||
    void                    config_apply(const ConfigBase &other, bool ignore_nonexistent = false) { this->m_config.apply(other, ignore_nonexistent); }
 | 
			
		||||
    void                    config_apply_only(const ConfigBase &other, const t_config_option_keys &keys, bool ignore_nonexistent = false) 
 | 
			
		||||
    	{ this->m_config.apply_only(other, keys, ignore_nonexistent); }
 | 
			
		||||
    void                    set_trafo(const Transform3d& trafo) { m_trafo = trafo; m_trmesh_valid = false; }
 | 
			
		||||
 | 
			
		||||
    void                    set_trafo(const Transform3d& trafo) {
 | 
			
		||||
        m_transformed_rmesh.invalidate([this, &trafo](){ m_trafo = trafo; });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool                    set_instances(const std::vector<Instance> &instances);
 | 
			
		||||
    // Invalidates the step, and its depending steps in SLAPrintObject and SLAPrint.
 | 
			
		||||
| 
						 | 
				
			
			@ -105,8 +112,7 @@ private:
 | 
			
		|||
    std::vector<ExPolygons>                 m_model_slices;
 | 
			
		||||
 | 
			
		||||
    // Caching the transformed (m_trafo) raw mesh of the object
 | 
			
		||||
    mutable TriangleMesh                    m_transformed_rmesh;
 | 
			
		||||
    mutable bool                            m_trmesh_valid = false;
 | 
			
		||||
    mutable CachedObject<TriangleMesh>      m_transformed_rmesh;
 | 
			
		||||
 | 
			
		||||
    class SupportData;
 | 
			
		||||
    std::unique_ptr<SupportData> m_supportdata;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue